From bc9d55f738db72d35b6dfdf9dad7bf2d82204665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Fri, 23 Aug 2019 15:13:01 +0200 Subject: [PATCH 001/275] grandpa: observer doesn't send catch up messages (#3460) * grandpa: don't send catch up requests when running GRANDPA observer * grandpa: fix tests * grandpa: add tests for catch up requests --- .../src/communication/gossip.rs | 124 +++++++++++++++++- .../finality-grandpa/src/communication/mod.rs | 12 +- .../src/communication/tests.rs | 1 + core/finality-grandpa/src/lib.rs | 1 + core/finality-grandpa/src/observer.rs | 4 +- core/finality-grandpa/src/tests.rs | 1 + 6 files changed, 133 insertions(+), 10 deletions(-) diff --git a/core/finality-grandpa/src/communication/gossip.rs b/core/finality-grandpa/src/communication/gossip.rs index 5fd09620e9..e0db1f0ba2 100644 --- a/core/finality-grandpa/src/communication/gossip.rs +++ b/core/finality-grandpa/src/communication/gossip.rs @@ -503,12 +503,13 @@ struct Inner { config: crate::Config, next_rebroadcast: Instant, pending_catch_up: PendingCatchUp, + catch_up_enabled: bool, } type MaybeMessage = Option<(Vec, NeighborPacket>)>; impl Inner { - fn new(config: crate::Config) -> Self { + fn new(config: crate::Config, catch_up_enabled: bool) -> Self { Inner { local_view: None, peers: Peers::default(), @@ -516,6 +517,7 @@ impl Inner { next_rebroadcast: Instant::now() + REBROADCAST_AFTER, authorities: Vec::new(), pending_catch_up: PendingCatchUp::None, + catch_up_enabled, config, } } @@ -804,6 +806,10 @@ impl Inner { } fn try_catch_up(&mut self, who: &PeerId) -> (Option>, Option) { + if !self.catch_up_enabled { + return (None, None); + } + let mut catch_up = None; let mut report = None; @@ -917,13 +923,17 @@ pub(super) struct GossipValidator { } impl GossipValidator { - /// Create a new gossip-validator. This initialized the current set to 0. - pub(super) fn new(config: crate::Config, set_state: environment::SharedVoterSetState) - -> (GossipValidator, ReportStream) - { + /// Create a new gossip-validator. The current set is initialized to 0. If + /// `catch_up_enabled` is set to false then the validator will not issue any + /// catch up requests (useful e.g. when running just the GRANDPA observer). + pub(super) fn new( + config: crate::Config, + set_state: environment::SharedVoterSetState, + catch_up_enabled: bool, + ) -> (GossipValidator, ReportStream) { let (tx, rx) = mpsc::unbounded(); let val = GossipValidator { - inner: parking_lot::RwLock::new(Inner::new(config)), + inner: parking_lot::RwLock::new(Inner::new(config, catch_up_enabled)), set_state, report_sender: tx, }; @@ -1408,6 +1418,7 @@ mod tests { let (val, _) = GossipValidator::::new( config(), voter_set_state(), + true, ); let set_id = 1; @@ -1443,6 +1454,7 @@ mod tests { let (val, _) = GossipValidator::::new( config(), voter_set_state(), + true, ); let set_id = 1; let auth = AuthorityId::from_slice(&[1u8; 32]); @@ -1487,6 +1499,7 @@ mod tests { let (val, _) = GossipValidator::::new( config(), voter_set_state(), + true, ); let set_id = 1; @@ -1555,6 +1568,7 @@ mod tests { let (val, _) = GossipValidator::::new( config(), set_state.clone(), + true, ); let set_id = 1; @@ -1609,6 +1623,7 @@ mod tests { let (val, _) = GossipValidator::::new( config(), set_state.clone(), + true, ); // the validator starts at set id 2 @@ -1682,4 +1697,101 @@ mod tests { false, ); } + + #[test] + fn issues_catch_up_request_on_neighbor_packet_import() { + let (val, _) = GossipValidator::::new( + config(), + voter_set_state(), + true, + ); + + // the validator starts at set id 1. + val.note_set(SetId(1), Vec::new(), |_, _| {}); + + // add the peer making the request to the validator, + // otherwise it is discarded. + let peer = PeerId::random(); + val.inner.write().peers.new_peer(peer.clone()); + + let import_neighbor_message = |set_id, round| { + let (_, _, catch_up_request, _) = val.inner.write().import_neighbor_message( + &peer, + NeighborPacket { + round: Round(round), + set_id: SetId(set_id), + commit_finalized_height: 42, + }, + ); + + catch_up_request + }; + + // importing a neighbor message from a peer in the same set in a later + // round should lead to a catch up request for the previous round. + match import_neighbor_message(1, 42) { + Some(GossipMessage::CatchUpRequest(request)) => { + assert_eq!(request.set_id, SetId(1)); + assert_eq!(request.round, Round(41)); + }, + _ => panic!("expected catch up message"), + } + + // we note that we're at round 41. + val.note_round(Round(41), |_, _| {}); + + // if we import a neighbor message within CATCH_UP_THRESHOLD then we + // won't request a catch up. + match import_neighbor_message(1, 42) { + None => {}, + _ => panic!("expected no catch up message"), + } + + // or if the peer is on a lower round. + match import_neighbor_message(1, 40) { + None => {}, + _ => panic!("expected no catch up message"), + } + + // we also don't request a catch up if the peer is in a different set. + match import_neighbor_message(2, 42) { + None => {}, + _ => panic!("expected no catch up message"), + } + } + + #[test] + fn doesnt_send_catch_up_requests_when_disabled() { + // we create a gossip validator with catch up requests disabled. + let (val, _) = GossipValidator::::new( + config(), + voter_set_state(), + false, + ); + + // the validator starts at set id 1. + val.note_set(SetId(1), Vec::new(), |_, _| {}); + + // add the peer making the request to the validator, + // otherwise it is discarded. + let peer = PeerId::random(); + val.inner.write().peers.new_peer(peer.clone()); + + // importing a neighbor message from a peer in the same set in a later + // round should lead to a catch up request but since they're disabled + // we should get `None`. + let (_, _, catch_up_request, _) = val.inner.write().import_neighbor_message( + &peer, + NeighborPacket { + round: Round(42), + set_id: SetId(1), + commit_finalized_height: 50, + }, + ); + + match catch_up_request { + None => {}, + _ => panic!("expected no catch up message"), + } + } } diff --git a/core/finality-grandpa/src/communication/mod.rs b/core/finality-grandpa/src/communication/mod.rs index 2aa2618535..a4b149fac4 100644 --- a/core/finality-grandpa/src/communication/mod.rs +++ b/core/finality-grandpa/src/communication/mod.rs @@ -236,19 +236,25 @@ pub(crate) struct NetworkBridge> { impl> NetworkBridge { /// Create a new NetworkBridge to the given NetworkService. Returns the service /// handle and a future that must be polled to completion to finish startup. - /// If a voter set state is given it registers previous round votes with the - /// gossip service. + /// On creation it will register previous rounds' votes with the gossip + /// service taken from the VoterSetState. pub(crate) fn new( service: N, config: crate::Config, set_state: crate::environment::SharedVoterSetState, on_exit: impl Future + Clone + Send + 'static, + catch_up_enabled: bool, ) -> ( Self, impl futures::Future + Send + 'static, ) { - let (validator, report_stream) = GossipValidator::new(config, set_state.clone()); + let (validator, report_stream) = GossipValidator::new( + config, + set_state.clone(), + catch_up_enabled, + ); + let validator = Arc::new(validator); service.register_validator(validator.clone()); diff --git a/core/finality-grandpa/src/communication/tests.rs b/core/finality-grandpa/src/communication/tests.rs index de5a084039..3ec3bc8dd4 100644 --- a/core/finality-grandpa/src/communication/tests.rs +++ b/core/finality-grandpa/src/communication/tests.rs @@ -182,6 +182,7 @@ fn make_test_network() -> ( config(), voter_set_state(), Exit, + true, ); ( diff --git a/core/finality-grandpa/src/lib.rs b/core/finality-grandpa/src/lib.rs index 428fa1aeb8..f6c11dd634 100644 --- a/core/finality-grandpa/src/lib.rs +++ b/core/finality-grandpa/src/lib.rs @@ -524,6 +524,7 @@ pub fn run_grandpa_voter, N, RA, SC, X>( config.clone(), persistent_data.set_state.clone(), on_exit.clone(), + true, ); register_finality_tracker_inherent_data_provider(client.clone(), &inherent_data_providers)?; diff --git a/core/finality-grandpa/src/observer.rs b/core/finality-grandpa/src/observer.rs index bce292262e..8a2d539f49 100644 --- a/core/finality-grandpa/src/observer.rs +++ b/core/finality-grandpa/src/observer.rs @@ -175,8 +175,10 @@ pub fn run_grandpa_observer, N, RA, SC>( network, config.clone(), persistent_data.set_state.clone(), - on_exit.clone() + on_exit.clone(), + false, ); + let observer_work = ObserverWork::new( client, network, diff --git a/core/finality-grandpa/src/tests.rs b/core/finality-grandpa/src/tests.rs index f634fd114a..c82982e20d 100644 --- a/core/finality-grandpa/src/tests.rs +++ b/core/finality-grandpa/src/tests.rs @@ -1215,6 +1215,7 @@ fn voter_persists_its_votes() { config.clone(), set_state, Exit, + true, ); runtime.block_on(routing_work).unwrap(); -- GitLab From 549a160daf9721a35c0187fc60ae71c9d7f8b0d1 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Sat, 24 Aug 2019 06:51:40 +0200 Subject: [PATCH 002/275] Fix linkemap swap (#3468) * fix linkedmap swap * version bump --- node/runtime/src/lib.rs | 2 +- srml/support/procedural/src/storage/impls.rs | 36 ++++++++++++++++++++ srml/support/src/lib.rs | 29 ++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index e80d5fa83a..01dff2b7ae 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -81,7 +81,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 149, - impl_version: 149, + impl_version: 150, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/support/procedural/src/storage/impls.rs b/srml/support/procedural/src/storage/impls.rs index dd93663673..d5f73f5d39 100644 --- a/srml/support/procedural/src/storage/impls.rs +++ b/srml/support/procedural/src/storage/impls.rs @@ -666,6 +666,42 @@ impl<'a, I: Iterator> Impls<'a, I> { #mutate_impl; ret } + + // Swap must be overriden not to break links. + fn swap>( + key1: &#kty, + key2: &#kty, + storage: &mut S, + ) { + use self::#inner_module::Utils; + + let final_key1 = &*#as_map::key_for(key1); + let final_key2 = &*#as_map::key_for(key2); + let full_value_1 = Self::read_with_linkage(storage, final_key1); + let full_value_2 = Self::read_with_linkage(storage, final_key2); + + match (full_value_1, full_value_2) { + // Just keep linkage in order and only swap values. + (Some((value1, linkage1)), Some((value2, linkage2))) => { + storage.put(final_key1, &(value2, linkage1)); + storage.put(final_key2, &(value1, linkage2)); + } + // Remove key and insert the new one. + (Some((value, linkage)), None) => { + #as_map::remove(key1, storage); + let linkage = Self::new_head_linkage(storage, key2); + storage.put(final_key2, &(value, linkage)); + } + // Remove key and insert the new one. + (None, Some((value, linkage))) => { + #as_map::remove(key2, storage); + let linkage = Self::new_head_linkage(storage, key1); + storage.put(final_key1, &(value, linkage)); + } + // No-op. + (None, None) => (), + } + } } impl<#impl_trait> #scrate::storage::hashed::generator::EnumerableStorageMap<#kty, #typ> diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index 5623cab70f..16e3ca5de9 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -342,6 +342,35 @@ mod tests { }); } + #[test] + fn linked_map_swap_works() { + with_externalities(&mut new_test_ext(), || { + OptionLinkedMap::insert(0, 0); + OptionLinkedMap::insert(1, 1); + OptionLinkedMap::insert(2, 2); + OptionLinkedMap::insert(3, 3); + + let collect = || OptionLinkedMap::enumerate().collect::>(); + assert_eq!(collect(), vec![(3, 3), (2, 2), (1, 1), (0, 0)]); + + // Two existing + OptionLinkedMap::swap(1, 2); + assert_eq!(collect(), vec![(3, 3), (2, 1), (1, 2), (0, 0)]); + + // Back to normal + OptionLinkedMap::swap(2, 1); + assert_eq!(collect(), vec![(3, 3), (2, 2), (1, 1), (0, 0)]); + + // Left existing + OptionLinkedMap::swap(2, 5); + assert_eq!(collect(), vec![(5, 2), (3, 3), (1, 1), (0, 0)]); + + // Right existing + OptionLinkedMap::swap(5, 2); + assert_eq!(collect(), vec![(2, 2), (3, 3), (1, 1), (0, 0)]); + }); + } + #[test] fn linked_map_basic_insert_remove_should_work() { with_externalities(&mut new_test_ext(), || { -- GitLab From 005a16eae7933a67b7e631e894e522773a8dfadc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Sat, 24 Aug 2019 06:52:22 +0200 Subject: [PATCH 003/275] Pluralise newHead (#3463) --- core/rpc/src/chain/mod.rs | 16 ++++++++-------- core/rpc/src/chain/tests.rs | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/rpc/src/chain/mod.rs b/core/rpc/src/chain/mod.rs index 9b8192e660..cb0235e13b 100644 --- a/core/rpc/src/chain/mod.rs +++ b/core/rpc/src/chain/mod.rs @@ -67,19 +67,19 @@ pub trait ChainApi { #[pubsub( subscription = "chain_newHead", subscribe, - name = "chain_subscribeNewHead", - alias("subscribe_newHead") + name = "chain_subscribeNewHeads", + alias("subscribe_newHead", "chain_subscribeNewHead") )] - fn subscribe_new_head(&self, metadata: Self::Metadata, subscriber: Subscriber
); + fn subscribe_new_heads(&self, metadata: Self::Metadata, subscriber: Subscriber
); /// Unsubscribe from new head subscription. #[pubsub( subscription = "chain_newHead", unsubscribe, - name = "chain_unsubscribeNewHead", - alias("unsubscribe_newHead") + name = "chain_unsubscribeNewHeads", + alias("unsubscribe_newHead", "chain_unsubscribeNewHead") )] - fn unsubscribe_new_head(&self, metadata: Option, id: SubscriptionId) -> RpcResult; + fn unsubscribe_new_heads(&self, metadata: Option, id: SubscriptionId) -> RpcResult; /// New head subscription #[pubsub( @@ -199,7 +199,7 @@ impl ChainApi, Block::Hash, Block::Header, Sig Ok(self.client.info().chain.finalized_hash) } - fn subscribe_new_head(&self, _metadata: Self::Metadata, subscriber: Subscriber) { + fn subscribe_new_heads(&self, _metadata: Self::Metadata, subscriber: Subscriber) { self.subscribe_headers( subscriber, || self.block_hash(None.into()), @@ -210,7 +210,7 @@ impl ChainApi, Block::Hash, Block::Header, Sig ) } - fn unsubscribe_new_head(&self, _metadata: Option, id: SubscriptionId) -> RpcResult { + fn unsubscribe_new_heads(&self, _metadata: Option, id: SubscriptionId) -> RpcResult { Ok(self.subscriptions.cancel(id)) } diff --git a/core/rpc/src/chain/tests.rs b/core/rpc/src/chain/tests.rs index e6fa4d94e5..36157df71d 100644 --- a/core/rpc/src/chain/tests.rs +++ b/core/rpc/src/chain/tests.rs @@ -202,7 +202,7 @@ fn should_notify_about_latest_block() { subscriptions: Subscriptions::new(Arc::new(remote)), }; - api.subscribe_new_head(Default::default(), subscriber); + api.subscribe_new_heads(Default::default(), subscriber); // assert id assigned assert_eq!(core.block_on(id), Ok(Ok(SubscriptionId::Number(1)))); -- GitLab From ac9836da175f4e3203f234bdc4d02d4a94d581cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Sat, 24 Aug 2019 06:54:14 +0200 Subject: [PATCH 004/275] Implement HTTP request in offchain workers (#3461) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Implement HTTP request in offchain workers * Bump impl_version * Don't compile offchain workers for WASM anymore * Initialize HttpConnector as a fallback. * Apply review suggestions 😳 --- .gitlab-ci.yml | 3 +- Cargo.lock | 21 + core/offchain/Cargo.toml | 8 + core/offchain/src/api.rs | 91 ++- core/offchain/src/api/http.rs | 990 +++++++++++++++++++++++++++++ core/offchain/src/api/timestamp.rs | 60 ++ core/offchain/src/testing.rs | 2 +- core/primitives/src/offchain.rs | 85 ++- core/sr-io/src/offchain/http.rs | 6 +- core/sr-io/without_std.rs | 2 +- 10 files changed, 1194 insertions(+), 74 deletions(-) create mode 100644 core/offchain/src/api/http.rs create mode 100644 core/offchain/src/api/timestamp.rs diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7889b52afa..872f916f4c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -202,7 +202,6 @@ check-web-wasm: - time cargo web build -p substrate-keystore - time cargo web build -p substrate-executor - time cargo web build -p substrate-network - - time cargo web build -p substrate-offchain - time cargo web build -p substrate-panic-handler - time cargo web build -p substrate-peerset - time cargo web build -p substrate-primitives @@ -336,7 +335,7 @@ check_warnings: - docker push $CONTAINER_IMAGE:$VERSION - docker push $CONTAINER_IMAGE:latest -publish-docker-substrate: +publish-docker-substrate: stage: publish <<: *publish-docker-release # collect VERSION artifact here to pass it on to kubernetes diff --git a/Cargo.lock b/Cargo.lock index f69b2f4063..2967d167da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1322,6 +1322,18 @@ dependencies = [ "want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hyper-tls" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "idna" version = "0.1.5" @@ -4866,11 +4878,18 @@ dependencies = [ name = "substrate-offchain" version = "2.0.0" dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", "substrate-client-db 2.0.0", @@ -4880,6 +4899,7 @@ dependencies = [ "substrate-primitives 2.0.0", "substrate-test-runtime-client 2.0.0", "substrate-transaction-pool 2.0.0", + "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6366,6 +6386,7 @@ dependencies = [ "checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" "checksum hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273" "checksum hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)" = "7cb44cbce9d8ee4fb36e4c0ad7b794ac44ebaad924b9c8291a63215bb44c2c8f" +"checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" "checksum impl-codec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "78c441b3d2b5e24b407161e76d482b7bbd29b5da357707839ac40d95152f031f" "checksum impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5158079de9d4158e0ce1de3ae0bd7be03904efc40b3d7dd8b8c301cbf6b52b56" diff --git a/core/offchain/Cargo.toml b/core/offchain/Cargo.toml index 4c8891eb6b..691fdea91c 100644 --- a/core/offchain/Cargo.toml +++ b/core/offchain/Cargo.toml @@ -7,13 +7,20 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] +bytes = "0.4" client = { package = "substrate-client", path = "../../core/client" } +fnv = "1.0" +futures01 = { package = "futures", version = "0.1" } futures-preview = "=0.3.0-alpha.17" +futures-timer = "0.2.1" +hyper = "0.12.33" +hyper-tls = "0.3.2" log = "0.4" offchain-primitives = { package = "substrate-offchain-primitives", path = "./primitives" } codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } parking_lot = "0.9.0" primitives = { package = "substrate-primitives", path = "../../core/primitives" } +rand = "0.7" sr-primitives = { path = "../../core/sr-primitives" } transaction_pool = { package = "substrate-transaction-pool", path = "../../core/transaction-pool" } network = { package = "substrate-network", path = "../../core/network" } @@ -23,6 +30,7 @@ keystore = { package = "substrate-keystore", path = "../keystore" } env_logger = "0.6" client-db = { package = "substrate-client-db", path = "../../core/client/db/", default-features = true } test-client = { package = "substrate-test-runtime-client", path = "../../core/test-runtime/client" } +tokio = "0.1" [features] default = [] diff --git a/core/offchain/src/api.rs b/core/offchain/src/api.rs index 225e7c3f72..0057dfd273 100644 --- a/core/offchain/src/api.rs +++ b/core/offchain/src/api.rs @@ -17,13 +17,12 @@ use std::{ str::FromStr, sync::Arc, - convert::{TryFrom, TryInto}, - time::{SystemTime, Duration}, + convert::TryFrom, thread::sleep, }; use client::backend::OffchainStorage; -use futures::{StreamExt as _, Future, future, channel::mpsc}; +use futures::{StreamExt as _, Future, FutureExt as _, future, channel::mpsc}; use log::{info, debug, warn, error}; use network::{PeerId, Multiaddr, NetworkStateInfo}; use codec::{Encode, Decode}; @@ -34,6 +33,9 @@ use primitives::offchain::{ use sr_primitives::{generic::BlockId, traits::{self, Extrinsic}}; use transaction_pool::txpool::{Pool, ChainApi}; +mod http; +mod timestamp; + /// A message between the offchain extension and the processing thread. enum ExtMessage { SubmitExtrinsic(Vec), @@ -49,6 +51,8 @@ pub(crate) struct Api { _at: BlockId, /// Is this node a potential validator? is_validator: bool, + /// Everything HTTP-related is handled by a different struct. + http: http::HttpApi, } fn unavailable_yet(name: &str) -> R { @@ -89,29 +93,11 @@ where } fn timestamp(&mut self) -> Timestamp { - let now = SystemTime::now(); - let epoch_duration = now.duration_since(SystemTime::UNIX_EPOCH); - match epoch_duration { - Err(_) => { - // Current time is earlier than UNIX_EPOCH. - Timestamp::from_unix_millis(0) - }, - Ok(d) => { - let duration = d.as_millis(); - // Assuming overflow won't happen for a few hundred years. - Timestamp::from_unix_millis(duration.try_into() - .expect("epoch milliseconds won't overflow u64 for hundreds of years; qed")) - } - } + timestamp::now() } fn sleep_until(&mut self, deadline: Timestamp) { - // Get current timestamp. - let now = self.timestamp(); - // Calculate the diff with the deadline. - let diff = deadline.diff(&now); - // Call thread::sleep for the diff duration. - sleep(Duration::from_millis(diff.millis())); + sleep(timestamp::timestamp_from_now(deadline)); } fn random_seed(&mut self) -> [u8; 32] { @@ -149,58 +135,53 @@ where fn http_request_start( &mut self, - _method: &str, - _uri: &str, + method: &str, + uri: &str, _meta: &[u8] ) -> Result { - unavailable_yet::<()>("http_request_start"); - Err(()) + self.http.request_start(method, uri) } fn http_request_add_header( &mut self, - _request_id: HttpRequestId, - _name: &str, - _value: &str + request_id: HttpRequestId, + name: &str, + value: &str ) -> Result<(), ()> { - unavailable_yet::<()>("http_request_add_header"); - Err(()) + self.http.request_add_header(request_id, name, value) } fn http_request_write_body( &mut self, - _request_id: HttpRequestId, - _chunk: &[u8], - _deadline: Option + request_id: HttpRequestId, + chunk: &[u8], + deadline: Option ) -> Result<(), HttpError> { - unavailable_yet::<()>("http_request_write_body"); - Err(HttpError::IoError) + self.http.request_write_body(request_id, chunk, deadline) } fn http_response_wait( &mut self, ids: &[HttpRequestId], - _deadline: Option + deadline: Option ) -> Vec { - unavailable_yet::<()>("http_response_wait"); - ids.iter().map(|_| HttpRequestStatus::Unknown).collect() + self.http.response_wait(ids, deadline) } fn http_response_headers( &mut self, - _request_id: HttpRequestId + request_id: HttpRequestId ) -> Vec<(Vec, Vec)> { - unavailable_yet("http_response_headers") + self.http.response_headers(request_id) } fn http_response_read_body( &mut self, - _request_id: HttpRequestId, - _buffer: &mut [u8], - _deadline: Option + request_id: HttpRequestId, + buffer: &mut [u8], + deadline: Option ) -> Result { - unavailable_yet::<()>("http_response_read_body"); - Err(HttpError::IoError) + self.http.response_read_body(request_id, buffer, deadline) } } @@ -276,6 +257,8 @@ pub(crate) struct AsyncApi { receiver: Option>, transaction_pool: Arc>, at: BlockId, + /// Everything HTTP-related is handled by a different struct. + http: Option, } impl AsyncApi { @@ -289,18 +272,22 @@ impl AsyncApi { ) -> (Api, AsyncApi) { let (sender, rx) = mpsc::unbounded(); + let (http_api, http_worker) = http::http(); + let api = Api { sender, db, network_state, _at: at, is_validator, + http: http_api, }; let async_api = AsyncApi { receiver: Some(rx), transaction_pool, at, + http: Some(http_worker), }; (api, async_api) @@ -309,13 +296,17 @@ impl AsyncApi { /// Run a processing task for the API pub fn process(mut self) -> impl Future { let receiver = self.receiver.take().expect("Take invoked only once."); + let http = self.http.take().expect("Take invoked only once."); - receiver.for_each(move |msg| { + let extrinsics = receiver.for_each(move |msg| { match msg { ExtMessage::SubmitExtrinsic(ext) => self.submit_extrinsic(ext), } future::ready(()) - }) + }); + + future::join(extrinsics, http) + .map(|((), ())| ()) } fn submit_extrinsic(&mut self, ext: Vec) { @@ -340,7 +331,7 @@ impl AsyncApi { #[cfg(test)] mod tests { use super::*; - use std::convert::TryFrom; + use std::{convert::{TryFrom, TryInto}, time::SystemTime}; use sr_primitives::traits::Zero; use client_db::offchain::LocalStorage; use network::PeerId; diff --git a/core/offchain/src/api/http.rs b/core/offchain/src/api/http.rs new file mode 100644 index 0000000000..287e3f99be --- /dev/null +++ b/core/offchain/src/api/http.rs @@ -0,0 +1,990 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! This module is composed of two structs: [`HttpApi`] and [`HttpWorker`]. Calling the [`http`] +//! function returns a pair of [`HttpApi`] and [`HttpWorker`] that share some state. +//! +//! The [`HttpApi`] is (indirectly) passed to the runtime when calling an offchain worker, while +//! the [`HttpWorker`] must be processed in the background. The [`HttpApi`] mimicks the API of the +//! HTTP-related methods available to offchain workers. +//! +//! The reason for this design is driven by the fact that HTTP requests should continue running +//! (i.e.: the socket should continue being processed) in the background even if the runtime isn't +//! actively calling any function. + +use crate::api::timestamp; +use bytes::Buf as _; +use fnv::FnvHashMap; +use futures::{prelude::*, channel::mpsc, compat::Compat01As03}; +use log::{warn, error}; +use primitives::offchain::{HttpRequestId, Timestamp, HttpRequestStatus, HttpError}; +use std::{fmt, io::Read as _, mem, pin::Pin, task::Context, task::Poll}; + +/// Creates a pair of [`HttpApi`] and [`HttpWorker`]. +pub fn http() -> (HttpApi, HttpWorker) { + let (to_worker, from_api) = mpsc::unbounded(); + let (to_api, from_worker) = mpsc::unbounded(); + + let api = HttpApi { + to_worker, + from_worker: from_worker.fuse(), + // We start with a random ID for the first HTTP request, to prevent mischievous people from + // writing runtime code with hardcoded IDs. + next_id: HttpRequestId(rand::random::() % 2000), + requests: FnvHashMap::default(), + }; + + let engine = HttpWorker { + to_api, + from_api, + // TODO: don't unwrap; we should fall back to the HttpConnector if we fail to create the + // Https one; there doesn't seem to be any built-in way to do this + http_client: HyperClient::new(), + requests: Vec::new(), + }; + + (api, engine) +} + +/// Provides HTTP capabilities. +/// +/// Since this struct is a helper for offchain workers, its API is mimicking the API provided +/// to offchain workers. +pub struct HttpApi { + /// Used to sends messages to the worker. + to_worker: mpsc::UnboundedSender, + /// Used to receive messages from the worker. + /// We use a `Fuse` in order to have an extra protection against panicking. + from_worker: stream::Fuse>, + /// Id to assign to the next HTTP request that is started. + next_id: HttpRequestId, + /// List of HTTP requests in preparation or in progress. + requests: FnvHashMap, +} + +/// One active request within `HttpApi`. +enum HttpApiRequest { + /// The request object is being constructed locally and not started yet. + NotDispatched(hyper::Request, hyper::body::Sender), + /// The request has been dispatched and we're in the process of sending out the body (if the + /// field is `Some`) or waiting for a response (if the field is `None`). + Dispatched(Option), + /// Received a response. + Response(HttpApiRequestRp), + /// A request has been dispatched then produced an error. + Fail(hyper::Error), +} + +/// A request within `HttpApi` that has received a response. +struct HttpApiRequestRp { + /// We might still be writing the request's body when the response comes. + /// This field allows to continue writing that body. + sending_body: Option, + /// Status code of the response. + status_code: hyper::StatusCode, + /// Headers of the response. + headers: hyper::HeaderMap, + /// Body of the response, as a channel of `Chunk` objects. + /// While the code is designed to drop the `Receiver` once it ends, we wrap it within a + /// `Fuse` in order to be extra precautious about panics. + body: stream::Fuse>>, + /// Chunk that has been extracted from the channel and that is currently being read. + /// Reading data from the response should read from this field in priority. + current_read_chunk: Option>, +} + +impl HttpApi { + /// Mimicks the corresponding method in the offchain API. + pub fn request_start( + &mut self, + method: &str, + uri: &str + ) -> Result { + // Start by building the prototype of the request. + // We do this first so that we don't touch anything in `self` if building the prototype + // fails. + let (body_sender, body) = hyper::Body::channel(); + let mut request = hyper::Request::new(body); + *request.method_mut() = hyper::Method::from_bytes(method.as_bytes()).map_err(|_| ())?; + *request.uri_mut() = hyper::Uri::from_shared(From::from(uri)).map_err(|_| ())?; + + let new_id = self.next_id; + debug_assert!(!self.requests.contains_key(&new_id)); + match self.next_id.0.checked_add(1) { + Some(new_id) => self.next_id.0 = new_id, + None => { + error!("Overflow in offchain worker HTTP request ID assignment"); + return Err(()); + } + }; + self.requests.insert(new_id, HttpApiRequest::NotDispatched(request, body_sender)); + + Ok(new_id) + } + + /// Mimicks the corresponding method in the offchain API. + pub fn request_add_header( + &mut self, + request_id: HttpRequestId, + name: &str, + value: &str + ) -> Result<(), ()> { + let request = match self.requests.get_mut(&request_id) { + Some(&mut HttpApiRequest::NotDispatched(ref mut rq, _)) => rq, + _ => return Err(()) + }; + + let name = hyper::header::HeaderName::from_bytes(name.as_bytes()).map_err(|_| ())?; + let value = hyper::header::HeaderValue::from_str(value).map_err(|_| ())?; + // Note that we're always appending headers and never replacing old values. + // We assume here that the user knows what they're doing. + request.headers_mut().append(name, value); + Ok(()) + } + + /// Mimicks the corresponding method in the offchain API. + pub fn request_write_body( + &mut self, + request_id: HttpRequestId, + chunk: &[u8], + deadline: Option + ) -> Result<(), HttpError> { + // Extract the request from the list. + // Don't forget to add it back if necessary when returning. + let mut request = match self.requests.remove(&request_id) { + None => return Err(HttpError::Invalid), + Some(r) => r, + }; + + let mut deadline = timestamp::deadline_to_future(deadline); + // Closure that writes data to a sender, taking the deadline into account. + // If `IoError` is returned, don't forget to destroy the request. + let mut poll_sender = move |sender: &mut hyper::body::Sender| -> Result<(), HttpError> { + let mut when_ready = future::maybe_done(Compat01As03::new( + futures01::future::poll_fn(|| sender.poll_ready()) + )); + futures::executor::block_on(future::select(&mut when_ready, &mut deadline)); + match when_ready { + future::MaybeDone::Done(Ok(())) => {} + future::MaybeDone::Done(Err(_)) => return Err(HttpError::IoError), + future::MaybeDone::Future(_) | + future::MaybeDone::Gone => { + debug_assert!(if let future::MaybeDone::Done(_) = deadline { true } else { false }); + return Err(HttpError::DeadlineReached) + } + }; + + match sender.send_data(hyper::Chunk::from(chunk.to_owned())) { + Ok(()) => Ok(()), + Err(_chunk) => { + error!("HTTP sender refused data despite being ready"); + Err(HttpError::IoError) + }, + } + }; + + loop { + request = match request { + HttpApiRequest::NotDispatched(request, sender) => { + // If the request is not dispatched yet, dispatch it and loop again. + let _ = self.to_worker.unbounded_send(ApiToWorker::Dispatch { + id: request_id, + request + }); + HttpApiRequest::Dispatched(Some(sender)) + } + + HttpApiRequest::Dispatched(Some(mut sender)) => + if !chunk.is_empty() { + match poll_sender(&mut sender) { + Err(HttpError::IoError) => return Err(HttpError::IoError), + other => { + self.requests.insert( + request_id, + HttpApiRequest::Dispatched(Some(sender)) + ); + return other + } + } + } else { + // Dropping the sender to finish writing. + self.requests.insert(request_id, HttpApiRequest::Dispatched(None)); + return Ok(()) + } + + HttpApiRequest::Response(mut response @ HttpApiRequestRp { sending_body: Some(_), .. }) => + if !chunk.is_empty() { + match poll_sender(response.sending_body.as_mut() + .expect("Can only enter this match branch if Some; qed")) { + Err(HttpError::IoError) => return Err(HttpError::IoError), + other => { + self.requests.insert(request_id, HttpApiRequest::Response(response)); + return other + } + } + + } else { + // Dropping the sender to finish writing. + self.requests.insert(request_id, HttpApiRequest::Response(HttpApiRequestRp { + sending_body: None, + ..response + })); + return Ok(()) + } + + HttpApiRequest::Fail(_) => + // If the request has already failed, return without putting back the request + // in the list. + return Err(HttpError::IoError), + + v @ HttpApiRequest::Dispatched(None) | + v @ HttpApiRequest::Response(HttpApiRequestRp { sending_body: None, .. }) => { + // We have already finished sending this body. + self.requests.insert(request_id, v); + return Err(HttpError::Invalid) + } + } + } + } + + /// Mimicks the corresponding method in the offchain API. + pub fn response_wait( + &mut self, + ids: &[HttpRequestId], + deadline: Option + ) -> Vec { + // First of all, dispatch all the non-dispatched requests and drop all senders so that the + // user can't write anymore data. + for id in ids { + match self.requests.get_mut(id) { + Some(HttpApiRequest::NotDispatched(_, _)) => {} + Some(HttpApiRequest::Dispatched(sending_body)) | + Some(HttpApiRequest::Response(HttpApiRequestRp { sending_body, .. })) => { + let _ = sending_body.take(); + continue + } + _ => continue + }; + + let (request, _sender) = match self.requests.remove(id) { + Some(HttpApiRequest::NotDispatched(rq, s)) => (rq, s), + _ => unreachable!("we checked for NotDispatched above; qed") + }; + + let _ = self.to_worker.unbounded_send(ApiToWorker::Dispatch { + id: *id, + request + }); + + // We also destroy the sender in order to forbid writing more data. + self.requests.insert(*id, HttpApiRequest::Dispatched(None)); + } + + let mut deadline = timestamp::deadline_to_future(deadline); + + loop { + // Within that loop, first try to see if we have all the elements for a response. + { + let mut output = Vec::with_capacity(ids.len()); + let mut must_wait_more = false; + for id in ids { + output.push(match self.requests.get_mut(id) { + None => HttpRequestStatus::Invalid, + Some(HttpApiRequest::NotDispatched(_, _)) => + unreachable!("we replaced all the NotDispatched with Dispatched earlier; qed"), + Some(HttpApiRequest::Dispatched(_)) => { + must_wait_more = true; + HttpRequestStatus::DeadlineReached + }, + Some(HttpApiRequest::Fail(_)) => HttpRequestStatus::IoError, + Some(HttpApiRequest::Response(HttpApiRequestRp { status_code, .. })) => + HttpRequestStatus::Finished(status_code.as_u16()), + }); + } + debug_assert_eq!(output.len(), ids.len()); + + // Are we ready to call `return`? + let is_done = if let future::MaybeDone::Done(_) = deadline { + true + } else if !must_wait_more { + true + } else { + false + }; + + if is_done { + // Requests in "fail" mode are purged before returning. + debug_assert_eq!(output.len(), ids.len()); + for n in (0..ids.len()).rev() { + if let HttpRequestStatus::IoError = output[n] { + self.requests.remove(&ids[n]); + } + } + return output + } + } + + // Grab next message, or call `continue` if deadline is reached. + let next_message = { + let mut next_msg = future::maybe_done(self.from_worker.next()); + futures::executor::block_on(future::select(&mut next_msg, &mut deadline)); + if let future::MaybeDone::Done(msg) = next_msg { + msg + } else { + debug_assert!(if let future::MaybeDone::Done(_) = deadline { true } else { false }); + continue + } + }; + + // Update internal state based on received message. + match next_message { + Some(WorkerToApi::Response { id, status_code, headers, body }) => + match self.requests.remove(&id) { + Some(HttpApiRequest::Dispatched(sending_body)) => { + self.requests.insert(id, HttpApiRequest::Response(HttpApiRequestRp { + sending_body, + status_code, + headers, + body: body.fuse(), + current_read_chunk: None, + })); + } + None => {} // can happen if we detected an IO error when sending the body + _ => error!("State mismatch between the API and worker"), + } + + Some(WorkerToApi::Fail { id, error }) => + match self.requests.remove(&id) { + Some(HttpApiRequest::Dispatched(_)) => { + self.requests.insert(id, HttpApiRequest::Fail(error)); + } + None => {} // can happen if we detected an IO error when sending the body + _ => error!("State mismatch between the API and worker"), + } + + None => { + error!("Worker has crashed"); + return ids.iter().map(|_| HttpRequestStatus::IoError).collect() + } + } + + } + } + + /// Mimicks the corresponding method in the offchain API. + pub fn response_headers( + &mut self, + request_id: HttpRequestId + ) -> Vec<(Vec, Vec)> { + // Do an implicit non-blocking wait on the request. + let _ = self.response_wait(&[request_id], Some(timestamp::now())); + + let headers = match self.requests.get(&request_id) { + Some(HttpApiRequest::Response(HttpApiRequestRp { headers, .. })) => headers, + _ => return Vec::new() + }; + + headers + .iter() + .map(|(name, value)| (name.as_str().as_bytes().to_owned(), value.as_bytes().to_owned())) + .collect() + } + + /// Mimicks the corresponding method in the offchain API. + pub fn response_read_body( + &mut self, + request_id: HttpRequestId, + buffer: &mut [u8], + deadline: Option + ) -> Result { + // Do an implicit non-blocking wait on the request. + let _ = self.response_wait(&[request_id], deadline); + + // Remove the request from the list and handle situations where the request is invalid or + // in the wrong state. + let mut response = match self.requests.remove(&request_id) { + Some(HttpApiRequest::Response(r)) => r, + // Because we called `response_wait` above, we know that the deadline has been reached + // and we still haven't received a response. + Some(HttpApiRequest::Dispatched(_)) => return Err(HttpError::DeadlineReached), + // The request has failed. + Some(HttpApiRequest::Fail { .. }) => + return Err(HttpError::IoError), + // Request hasn't been dispatched yet; reading the body is invalid. + Some(rq) => { + self.requests.insert(request_id, rq); + return Err(HttpError::Invalid) + } + None => return Err(HttpError::Invalid) + }; + + // Convert the deadline into a `Future` that resolves when the deadline is reached. + let mut deadline = future::maybe_done(match deadline { + Some(deadline) => future::Either::Left( + futures_timer::Delay::new(timestamp::timestamp_from_now(deadline)) + ), + None => future::Either::Right(future::pending()) + }); + + loop { + // First read from `current_read_chunk`. + if let Some(mut current_read_chunk) = response.current_read_chunk.take() { + match current_read_chunk.read(buffer) { + Ok(0) => {} + Ok(n) => { + self.requests.insert(request_id, HttpApiRequest::Response(HttpApiRequestRp { + current_read_chunk: Some(current_read_chunk), + .. response + })); + return Ok(n) + }, + Err(err) => { + // This code should never be reached unless there's a logic error somewhere. + error!("Failed to read from current read chunk: {:?}", err); + return Err(HttpError::IoError) + } + } + } + + // If we reach here, that means the `current_read_chunk` is empty and needs to be + // filled with a new chunk from `body`. We block on either the next body or the + // deadline. + let mut next_body = future::maybe_done(response.body.next()); + futures::executor::block_on(future::select(&mut next_body, &mut deadline)); + + if let future::MaybeDone::Done(next_body) = next_body { + match next_body { + Some(Ok(chunk)) => response.current_read_chunk = Some(chunk.reader()), + Some(Err(_)) => return Err(HttpError::IoError), + None => return Ok(0), // eof + } + } + + if let future::MaybeDone::Done(_) = deadline { + self.requests.insert(request_id, HttpApiRequest::Response(response)); + return Err(HttpError::DeadlineReached) + } + } + } +} + +impl fmt::Debug for HttpApi { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_list() + .entries(self.requests.iter()) + .finish() + } +} + +impl fmt::Debug for HttpApiRequest { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + HttpApiRequest::NotDispatched(_, _) => + f.debug_tuple("HttpApiRequest::NotDispatched").finish(), + HttpApiRequest::Dispatched(_) => + f.debug_tuple("HttpApiRequest::Dispatched").finish(), + HttpApiRequest::Response(HttpApiRequestRp { status_code, headers, .. }) => + f.debug_tuple("HttpApiRequest::Response").field(status_code).field(headers).finish(), + HttpApiRequest::Fail(err) => + f.debug_tuple("HttpApiRequest::Fail").field(err).finish(), + } + } +} + +/// Message send from the API to the worker. +enum ApiToWorker { + /// Dispatches a new HTTP request. + Dispatch { + /// ID to send back when the response comes back. + id: HttpRequestId, + /// Request to start executing. + request: hyper::Request, + } +} + +/// Message send from the API to the worker. +enum WorkerToApi { + /// A request has succeeded. + Response { + /// The ID that was passed to the worker. + id: HttpRequestId, + /// Status code of the response. + status_code: hyper::StatusCode, + /// Headers of the response. + headers: hyper::HeaderMap, + /// Body of the response, as a channel of `Chunk` objects. + /// We send the body back through a channel instead of returning the hyper `Body` object + /// because we don't want the `HttpApi` to have to drive the reading. + /// Instead, reading an item from the channel will notify the worker task, which will push + /// the next item. + body: mpsc::Receiver>, + }, + /// A request has failed because of an error. + Fail { + /// The ID that was passed to the worker. + id: HttpRequestId, + /// Error that happened. + error: hyper::Error, + }, +} + +enum HyperClient { + Http(hyper::Client), + Https(hyper::Client, hyper::Body>), +} + +impl HyperClient { + /// Creates new hyper client. + /// + /// By default we will try to initialize the `HttpsConnector`, + /// if that's not possible we'll fall back to `HttpConnector`. + pub fn new() -> Self { + match hyper_tls::HttpsConnector::new(1) { + Ok(tls) => HyperClient::Https(hyper::Client::builder().build(tls)), + Err(e) => { + warn!("Unable to initialize TLS client. Falling back to HTTP-only: {:?}", e); + HyperClient::Http(hyper::Client::new()) + }, + } + } +} + +/// Must be continuously polled for the [`HttpApi`] to properly work. +pub struct HttpWorker { + /// Used to sends messages to the `HttpApi`. + to_api: mpsc::UnboundedSender, + /// Used to receive messages from the `HttpApi`. + from_api: mpsc::UnboundedReceiver, + /// The engine that runs HTTP requests. + http_client: HyperClient, + /// HTTP requests that are being worked on by the engine. + requests: Vec<(HttpRequestId, HttpWorkerRequest)>, +} + +/// HTTP request being processed by the worker. +enum HttpWorkerRequest { + /// Request has been dispatched and is waiting for a response. + Dispatched(Compat01As03), + /// Reading the body of the response and sending it to the channel. + ReadBody { + /// Body to read `Chunk`s from. + body: Compat01As03, + /// Where to send the chunks. + tx: mpsc::Sender>, + }, +} + +impl Future for HttpWorker { + type Output = (); + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { + // Reminder: this is continuously run in the background. + + // We use a `me` variable because the compiler isn't smart enough to allow borrowing + // multiple fields at once through a `Deref`. + let me = &mut *self; + + // We remove each element from `requests` one by one and add them back only if necessary. + for n in (0..me.requests.len()).rev() { + let (id, request) = me.requests.swap_remove(n); + match request { + HttpWorkerRequest::Dispatched(mut future) => { + // Check for an HTTP response from the Internet. + let mut response = match Future::poll(Pin::new(&mut future), cx) { + Poll::Pending => { + me.requests.push((id, HttpWorkerRequest::Dispatched(future))); + continue + }, + Poll::Ready(Ok(response)) => response, + Poll::Ready(Err(err)) => { + let _ = me.to_api.unbounded_send(WorkerToApi::Fail { + id, + error: err, + }); + continue; // don't insert the request back + } + }; + + // We received a response! Decompose it into its parts. + let status_code = response.status(); + let headers = mem::replace(response.headers_mut(), hyper::HeaderMap::new()); + let body = Compat01As03::new(response.into_body()); + + let (body_tx, body_rx) = mpsc::channel(3); + let _ = me.to_api.unbounded_send(WorkerToApi::Response { + id, + status_code, + headers, + body: body_rx, + }); + + me.requests.push((id, HttpWorkerRequest::ReadBody { body, tx: body_tx })); + cx.waker().wake_by_ref(); // wake up in order to poll the new future + continue + } + + HttpWorkerRequest::ReadBody { mut body, mut tx } => { + // Before reading from the HTTP response, check that `tx` is ready to accept + // a new chunk. + match tx.poll_ready(cx) { + Poll::Ready(Ok(())) => {} + Poll::Ready(Err(_)) => continue, // don't insert the request back + Poll::Pending => { + me.requests.push((id, HttpWorkerRequest::ReadBody { body, tx })); + continue + } + } + + match Stream::poll_next(Pin::new(&mut body), cx) { + Poll::Ready(Some(Ok(chunk))) => { + let _ = tx.start_send(Ok(chunk)); + me.requests.push((id, HttpWorkerRequest::ReadBody { body, tx })); + cx.waker().wake_by_ref(); // notify in order to poll again + } + Poll::Ready(Some(Err(err))) => { + let _ = tx.start_send(Err(err)); + // don't insert the request back + }, + Poll::Ready(None) => {} // EOF; don't insert the request back + Poll::Pending => { + me.requests.push((id, HttpWorkerRequest::ReadBody { body, tx })); + }, + } + } + } + } + + // Check for messages coming from the [`HttpApi`]. + match Stream::poll_next(Pin::new(&mut me.from_api), cx) { + Poll::Pending => {}, + Poll::Ready(None) => return Poll::Ready(()), // stops the worker + Poll::Ready(Some(ApiToWorker::Dispatch { id, request })) => { + let future = Compat01As03::new(match me.http_client { + HyperClient::Http(ref mut c) => c.request(request), + HyperClient::Https(ref mut c) => c.request(request), + }); + debug_assert!(me.requests.iter().all(|(i, _)| *i != id)); + me.requests.push((id, HttpWorkerRequest::Dispatched(future))); + cx.waker().wake_by_ref(); // reschedule the task to poll the request + } + } + + Poll::Pending + } +} + +impl fmt::Debug for HttpWorker { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_list() + .entries(self.requests.iter()) + .finish() + } +} + +impl fmt::Debug for HttpWorkerRequest { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + HttpWorkerRequest::Dispatched(_) => + f.debug_tuple("HttpWorkerRequest::Dispatched").finish(), + HttpWorkerRequest::ReadBody { .. } => + f.debug_tuple("HttpWorkerRequest::Response").finish(), + } + } +} + +#[cfg(test)] +mod tests { + use crate::api::timestamp; + use super::http; + use futures::prelude::*; + use futures01::Future as _; + use primitives::offchain::{HttpError, HttpRequestId, HttpRequestStatus, Duration}; + + // Returns an `HttpApi` whose worker is ran in the background, and a `SocketAddr` to an HTTP + // server that runs in the background as well. + macro_rules! build_api_server { + () => {{ + let (api, worker) = http(); + // Note: we have to use tokio because hyper still uses old futures. + std::thread::spawn(move || { + tokio::run(futures::compat::Compat::new(worker.map(|()| Ok::<(), ()>(())))) + }); + let (addr_tx, addr_rx) = std::sync::mpsc::channel(); + std::thread::spawn(move || { + let server = hyper::Server::bind(&"127.0.0.1:0".parse().unwrap()) + .serve(|| { + hyper::service::service_fn_ok(move |_: hyper::Request| { + hyper::Response::new(hyper::Body::from("Hello World!")) + }) + }); + let _ = addr_tx.send(server.local_addr()); + hyper::rt::run(server.map_err(|e| panic!("{:?}", e))); + }); + (api, addr_rx.recv().unwrap()) + }}; + } + + #[test] + fn basic_localhost() { + let deadline = timestamp::now().add(Duration::from_millis(10_000)); + + // Performs an HTTP query to a background HTTP server. + + let (mut api, addr) = build_api_server!(); + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.request_write_body(id, &[], Some(deadline)).unwrap(); + + match api.response_wait(&[id], Some(deadline))[0] { + HttpRequestStatus::Finished(200) => {}, + v => panic!("Connecting to localhost failed: {:?}", v) + } + + let headers = api.response_headers(id); + assert!(headers.iter().any(|(h, _)| h.eq_ignore_ascii_case(b"Date"))); + + let mut buf = vec![0; 2048]; + let n = api.response_read_body(id, &mut buf, Some(deadline)).unwrap(); + assert_eq!(&buf[..n], b"Hello World!"); + } + + #[test] + fn request_start_invalid_call() { + let (mut api, addr) = build_api_server!(); + + match api.request_start("\0", &format!("http://{}", addr)) { + Err(()) => {} + Ok(_) => panic!() + }; + + match api.request_start("GET", "http://\0localhost") { + Err(()) => {} + Ok(_) => panic!() + }; + } + + #[test] + fn request_add_header_invalid_call() { + let (mut api, addr) = build_api_server!(); + + match api.request_add_header(HttpRequestId(0xdead), "Foo", "bar") { + Err(()) => {} + Ok(_) => panic!() + }; + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + match api.request_add_header(id, "\0", "bar") { + Err(()) => {} + Ok(_) => panic!() + }; + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + match api.request_add_header(id, "Foo", "\0") { + Err(()) => {} + Ok(_) => panic!() + }; + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.request_add_header(id, "Foo", "Bar").unwrap(); + api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); + match api.request_add_header(id, "Foo2", "Bar") { + Err(()) => {} + Ok(_) => panic!() + }; + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.response_headers(id); + match api.request_add_header(id, "Foo2", "Bar") { + Err(()) => {} + Ok(_) => panic!() + }; + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.response_read_body(id, &mut [], None).unwrap(); + match api.request_add_header(id, "Foo2", "Bar") { + Err(()) => {} + Ok(_) => panic!() + }; + } + + #[test] + fn request_write_body_invalid_call() { + let (mut api, addr) = build_api_server!(); + + match api.request_write_body(HttpRequestId(0xdead), &[1, 2, 3], None) { + Err(HttpError::Invalid) => {} + _ => panic!() + }; + + match api.request_write_body(HttpRequestId(0xdead), &[], None) { + Err(HttpError::Invalid) => {} + _ => panic!() + }; + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); + api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); + api.request_write_body(id, &[], None).unwrap(); + match api.request_write_body(id, &[], None) { + Err(HttpError::Invalid) => {} + _ => panic!() + }; + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); + api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); + api.request_write_body(id, &[], None).unwrap(); + match api.request_write_body(id, &[1, 2, 3, 4], None) { + Err(HttpError::Invalid) => {} + _ => panic!() + }; + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); + api.response_wait(&[id], None); + match api.request_write_body(id, &[], None) { + Err(HttpError::Invalid) => {} + _ => panic!() + }; + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); + api.response_wait(&[id], None); + match api.request_write_body(id, &[1, 2, 3, 4], None) { + Err(HttpError::Invalid) => {} + _ => panic!() + }; + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.response_headers(id); + match api.request_write_body(id, &[1, 2, 3, 4], None) { + Err(HttpError::Invalid) => {} + _ => panic!() + }; + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.response_headers(id); + match api.request_write_body(id, &[], None) { + Err(HttpError::Invalid) => {} + _ => panic!() + }; + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.response_read_body(id, &mut [], None).unwrap(); + match api.request_write_body(id, &[1, 2, 3, 4], None) { + Err(HttpError::Invalid) => {} + _ => panic!() + }; + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.response_read_body(id, &mut [], None).unwrap(); + match api.request_write_body(id, &[], None) { + Err(HttpError::Invalid) => {} + _ => panic!() + }; + } + + #[test] + fn response_headers_invalid_call() { + let (mut api, addr) = build_api_server!(); + assert!(api.response_headers(HttpRequestId(0xdead)).is_empty()); + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + assert!(api.response_headers(id).is_empty()); + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.request_write_body(id, &[], None).unwrap(); + while api.response_headers(id).is_empty() { + std::thread::sleep(std::time::Duration::from_millis(100)); + } + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.response_wait(&[id], None); + assert!(!api.response_headers(id).is_empty()); + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + let mut buf = [0; 128]; + while api.response_read_body(id, &mut buf, None).unwrap() != 0 {} + assert!(api.response_headers(id).is_empty()); + } + + #[test] + fn response_header_invalid_call() { + let (mut api, addr) = build_api_server!(); + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + assert!(api.response_headers(id).is_empty()); + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.request_add_header(id, "Foo", "Bar").unwrap(); + assert!(api.response_headers(id).is_empty()); + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + api.request_add_header(id, "Foo", "Bar").unwrap(); + api.request_write_body(id, &[], None).unwrap(); + // Note: this test actually sends out the request, and is supposed to test a situation + // where we haven't received any response yet. This test can theoretically fail if the + // HTTP response comes back faster than the kernel schedules our thread, but that is highly + // unlikely. + assert!(api.response_headers(id).is_empty()); + } + + #[test] + fn response_read_body_invalid_call() { + let (mut api, addr) = build_api_server!(); + let mut buf = [0; 512]; + + match api.response_read_body(HttpRequestId(0xdead), &mut buf, None) { + Err(HttpError::Invalid) => {} + _ => panic!() + } + + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + while api.response_read_body(id, &mut buf, None).unwrap() != 0 {} + match api.response_read_body(id, &mut buf, None) { + Err(HttpError::Invalid) => {} + _ => panic!() + } + } + + #[test] + fn fuzzing() { + // Uses the API in random ways to try to trigger panicks. + // Doesn't test some paths, such as waiting for multiple requests. Also doesn't test what + // happens if the server force-closes our socket. + + let (mut api, addr) = build_api_server!(); + + for _ in 0..50 { + let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + + for _ in 0..250 { + match rand::random::() % 6 { + 0 => { let _ = api.request_add_header(id, "Foo", "Bar"); } + 1 => { let _ = api.request_write_body(id, &[1, 2, 3, 4], None); } + 2 => { let _ = api.request_write_body(id, &[], None); } + 3 => { let _ = api.response_wait(&[id], None); } + 4 => { let _ = api.response_headers(id); } + 5 => { + let mut buf = [0; 512]; + let _ = api.response_read_body(id, &mut buf, None); + } + 6 ..= 255 => unreachable!() + } + } + } + } +} diff --git a/core/offchain/src/api/timestamp.rs b/core/offchain/src/api/timestamp.rs new file mode 100644 index 0000000000..f106ac7273 --- /dev/null +++ b/core/offchain/src/api/timestamp.rs @@ -0,0 +1,60 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Helper methods dedicated to timestamps. + +use primitives::offchain::Timestamp; +use std::convert::TryInto; +use std::time::{SystemTime, Duration}; + +/// Returns the current time as a `Timestamp`. +pub fn now() -> Timestamp { + let now = SystemTime::now(); + let epoch_duration = now.duration_since(SystemTime::UNIX_EPOCH); + match epoch_duration { + Err(_) => { + // Current time is earlier than UNIX_EPOCH. + Timestamp::from_unix_millis(0) + }, + Ok(d) => { + let duration = d.as_millis(); + // Assuming overflow won't happen for a few hundred years. + Timestamp::from_unix_millis(duration.try_into() + .expect("epoch milliseconds won't overflow u64 for hundreds of years; qed")) + } + } +} + +/// Returns how a `Timestamp` compares to "now". +/// +/// In other words, returns `timestamp - now()`. +pub fn timestamp_from_now(timestamp: Timestamp) -> Duration { + Duration::from_millis(timestamp.diff(&now()).millis()) +} + +/// Converts the deadline into a `Future` that resolves when the deadline is reached. +pub fn deadline_to_future( + deadline: Option, +) -> futures::future::MaybeDone { + use futures::future; + + future::maybe_done(match deadline { + Some(deadline) => future::Either::Left( + futures_timer::Delay::new(timestamp_from_now(deadline)) + ), + None => future::Either::Right(future::pending()) + }) +} diff --git a/core/offchain/src/testing.rs b/core/offchain/src/testing.rs index cdf2878c13..8724ca7546 100644 --- a/core/offchain/src/testing.rs +++ b/core/offchain/src/testing.rs @@ -248,7 +248,7 @@ impl offchain::Externalities for TestOffchainExt { ids.iter().map(|id| match state.requests.get(id) { Some(req) if req.response.is_empty() => RequestStatus::DeadlineReached, - None => RequestStatus::Unknown, + None => RequestStatus::Invalid, _ => RequestStatus::Finished(200), }).collect() } diff --git a/core/primitives/src/offchain.rs b/core/primitives/src/offchain.rs index 52dbf5fbee..8aa097cec0 100644 --- a/core/primitives/src/offchain.rs +++ b/core/primitives/src/offchain.rs @@ -61,7 +61,7 @@ impl From for u32 { /// Opaque type for offchain http requests. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "std", derive(Debug))] +#[cfg_attr(feature = "std", derive(Debug, Hash))] pub struct HttpRequestId(pub u16); impl From for u32 { @@ -79,6 +79,8 @@ pub enum HttpError { DeadlineReached = 1, /// There was an IO Error while processing the request. IoError = 2, + /// The ID of the request is invalid in this context. + Invalid = 3, } impl TryFrom for HttpError { @@ -88,6 +90,7 @@ impl TryFrom for HttpError { match error { e if e == HttpError::DeadlineReached as u8 as u32 => Ok(HttpError::DeadlineReached), e if e == HttpError::IoError as u8 as u32 => Ok(HttpError::IoError), + e if e == HttpError::Invalid as u8 as u32 => Ok(HttpError::Invalid), _ => Err(()) } } @@ -105,18 +108,17 @@ impl From for u32 { pub enum HttpRequestStatus { /// Deadline was reached while we waited for this request to finish. /// - /// Note the deadline is controlled by the calling part, it not necessarily means - /// that the request has timed out. + /// Note the deadline is controlled by the calling part, it not necessarily + /// means that the request has timed out. DeadlineReached, - /// Request timed out. + /// An error has occured during the request, for example a timeout or the + /// remote has closed our socket. /// - /// This means that the request couldn't be completed by the host environment - /// within a reasonable time (according to the host), has now been terminated - /// and is considered finished. - /// To retry the request you need to construct it again. - Timeout, - /// Request status of this ID is not known. - Unknown, + /// The request is now considered destroyed. To retry the request you need + /// to construct it again. + IoError, + /// The passed ID is invalid in this context. + Invalid, /// The request has finished with given status code. Finished(u16), } @@ -124,9 +126,9 @@ pub enum HttpRequestStatus { impl From for u32 { fn from(status: HttpRequestStatus) -> Self { match status { - HttpRequestStatus::Unknown => 0, + HttpRequestStatus::Invalid => 0, HttpRequestStatus::DeadlineReached => 10, - HttpRequestStatus::Timeout => 20, + HttpRequestStatus::IoError => 20, HttpRequestStatus::Finished(code) => u32::from(code), } } @@ -137,9 +139,9 @@ impl TryFrom for HttpRequestStatus { fn try_from(status: u32) -> Result { match status { - 0 => Ok(HttpRequestStatus::Unknown), + 0 => Ok(HttpRequestStatus::Invalid), 10 => Ok(HttpRequestStatus::DeadlineReached), - 20 => Ok(HttpRequestStatus::Timeout), + 20 => Ok(HttpRequestStatus::IoError), 100..=999 => u16::try_from(status).map(HttpRequestStatus::Finished).map_err(|_| ()), _ => Err(()), } @@ -291,6 +293,11 @@ pub trait Externalities { /// /// Meta is a future-reserved field containing additional, parity-scale-codec encoded parameters. /// Returns the id of newly started request. + /// + /// Returns an error if: + /// - No new request identifier could be allocated. + /// - The method or URI contain invalid characters. + /// fn http_request_start( &mut self, method: &str, @@ -299,6 +306,18 @@ pub trait Externalities { ) -> Result; /// Append header to the request. + /// + /// Calling this function multiple times with the same header name continues appending new + /// headers. In other words, headers are never replaced. + /// + /// Returns an error if: + /// - The request identifier is invalid. + /// - You have called `http_request_write_body` on that request. + /// - The name or value contain invalid characters. + /// + /// An error doesn't poison the request, and you can continue as if the call had never been + /// made. + /// fn http_request_add_header( &mut self, request_id: HttpRequestId, @@ -308,10 +327,19 @@ pub trait Externalities { /// Write a chunk of request body. /// - /// Writing an empty chunks finalises the request. + /// Calling this function with a non-empty slice may or may not start the + /// HTTP request. Calling this function with an empty chunks finalizes the + /// request and always starts it. It is no longer valid to write more data + /// afterwards. /// Passing `None` as deadline blocks forever. /// - /// Returns an error in case deadline is reached or the chunk couldn't be written. + /// Returns an error if: + /// - The request identifier is invalid. + /// - `http_response_wait` has already been called on this request. + /// - The deadline is reached. + /// - An I/O error has happened, for example the remote has closed our + /// request. The request is then considered invalid. + /// fn http_request_write_body( &mut self, request_id: HttpRequestId, @@ -325,6 +353,9 @@ pub trait Externalities { /// Note that if deadline is not provided the method will block indefinitely, /// otherwise unready responses will produce `DeadlineReached` status. /// + /// If a response returns an `IoError`, it is then considered destroyed. + /// Its id is then invalid. + /// /// Passing `None` as deadline blocks forever. fn http_response_wait( &mut self, @@ -335,6 +366,12 @@ pub trait Externalities { /// Read all response headers. /// /// Returns a vector of pairs `(HeaderKey, HeaderValue)`. + /// + /// Dispatches the request if it hasn't been done yet. It is no longer + /// valid to modify the headers or write data to the request. + /// + /// Returns an empty list if the identifier is unknown/invalid, hasn't + /// received a response, or has finished. fn http_response_headers( &mut self, request_id: HttpRequestId @@ -342,9 +379,23 @@ pub trait Externalities { /// Read a chunk of body response to given buffer. /// + /// Dispatches the request if it hasn't been done yet. It is no longer + /// valid to modify the headers or write data to the request. + /// /// Returns the number of bytes written or an error in case a deadline /// is reached or server closed the connection. /// Passing `None` as a deadline blocks forever. + /// + /// If `Ok(0)` or `Err(IoError)` is returned, the request is considered + /// destroyed. Doing another read or getting the response's headers, for + /// example, is then invalid. + /// + /// Returns an error if: + /// - The request identifier is invalid. + /// - The deadline is reached. + /// - An I/O error has happened, for example the remote has closed our + /// request. The request is then considered invalid. + /// fn http_response_read_body( &mut self, request_id: HttpRequestId, diff --git a/core/sr-io/src/offchain/http.rs b/core/sr-io/src/offchain/http.rs index 6685dd023f..7aab309f13 100644 --- a/core/sr-io/src/offchain/http.rs +++ b/core/sr-io/src/offchain/http.rs @@ -224,7 +224,7 @@ pub enum Error { /// Deadline has been reached. DeadlineReached, /// Request had timed out. - Timeout, + IoError, /// Unknown error has been ecountered. Unknown, } @@ -283,8 +283,8 @@ impl PendingRequest { .zip(requests.into_iter()) .map(|(status, req)| match status { RequestStatus::DeadlineReached => Err(req), - RequestStatus::Timeout => Ok(Err(Error::Timeout)), - RequestStatus::Unknown => Ok(Err(Error::Unknown)), + RequestStatus::IoError => Ok(Err(Error::IoError)), + RequestStatus::Invalid => Ok(Err(Error::Unknown)), RequestStatus::Finished(code) => Ok(Ok(Response::new(req.id, code))), }) .collect() diff --git a/core/sr-io/without_std.rs b/core/sr-io/without_std.rs index 954eccc9cf..c5f2ac483f 100644 --- a/core/sr-io/without_std.rs +++ b/core/sr-io/without_std.rs @@ -1163,7 +1163,7 @@ impl OffchainApi for () { statuses .into_iter() - .map(|status| status.try_into().unwrap_or(offchain::HttpRequestStatus::Unknown)) + .map(|status| status.try_into().unwrap_or(offchain::HttpRequestStatus::Invalid)) .collect() } -- GitLab From 57c37149eeeffe5db35c64cf288df1c371416997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sat, 24 Aug 2019 11:53:44 +0200 Subject: [PATCH 005/275] Show the available key management RPC calls in README (#3474) * Show the available key management RPC calls in README * minor fixes --- README.adoc | 34 +++++++++++++++++++++++++++++++++- core/cli/src/params.rs | 6 +++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/README.adoc b/README.adoc index aaab6df3cc..6afa1cf4e1 100644 --- a/README.adoc +++ b/README.adoc @@ -160,7 +160,7 @@ It won't do much until you start producing blocks though, so to do that you'll n [source, shell] ---- -substrate --chain ~/mychain.json --validator --key ... +substrate --chain ~/mychain.json --validator ---- You can distribute `mychain.json` so that everyone can synchronize and (depending on your authorities list) validate on your chain. @@ -378,6 +378,38 @@ git checkout -b v1.0 origin/v1.0 You can then follow the same steps for building and running as described above in <>. +== Key management + +Keys in Substrate are stored in the keystore in the file system. To store keys into this keystore, +you need to use one of the two provided RPC calls. If your keys are encrypted or should be encrypted +by the keystore, you need to provide the key using one of the cli arguments `--password`, +`--password-interactive` or `--password-filename`. + +=== Recommended RPC call + +For most users who want to run a validator node, the `author_rotateKeys` RPC call is sufficient. +The RPC call will generate `N` Session keys for you and return their public keys. `N` is the number +of session keys configured in the runtime. The output of the RPC call can be used as input for the +`session::set_keys` transaction. + +``` +curl -H 'Content-Type: application/json' --data '{ "jsonrpc":"2.0", "method":"author_rotateKeys", "id":1 }' localhost:9933 +``` + +=== Advanced RPC call + +If the Session keys need to match a fixed seed, they can be set individually key by key. The RPC call +expects the key seed and the key type. The key types supported by default in Substrate are listed +https://github.com/paritytech/substrate/blob/master/core/primitives/src/crypto.rs#L767[here], but the +user can declare any key type. + +``` +curl -H 'Content-Type: application/json' --data '{ "jsonrpc":"2.0", "method":"author_insertKey", "params":["KEY_TYPE", "SEED"],"id":1 }' localhost:9933 +``` + +`KEY_TYPE` - needs to be replaced with the 4-character key type identifier. +`SEEED` - is the seed of the key. + == Documentation === Viewing documentation for Substrate packages diff --git a/core/cli/src/params.rs b/core/cli/src/params.rs index 72adc552b9..0f58527287 100644 --- a/core/cli/src/params.rs +++ b/core/cli/src/params.rs @@ -441,7 +441,11 @@ lazy_static::lazy_static! { /// The Cli values for all test accounts. static ref TEST_ACCOUNTS_CLI_VALUES: Vec = { keyring::Sr25519Keyring::iter().map(|a| { - let help = format!("Shortcut for `--key //{} --name {}`.", a, a); + let help = format!( + "Shortcut for `--name {} --validator` with session keys for `{}` added to keystore.", + a, + a, + ); let conflicts_with = keyring::Sr25519Keyring::iter() .filter(|b| a != *b) .map(|b| b.to_string().to_lowercase()) -- GitLab From 86a0fc25e3aaeee273b6b3706f2aef99df72a21e Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Sat, 24 Aug 2019 17:17:01 +0200 Subject: [PATCH 006/275] GRANDPA links set IDs to sessions. (#3472) * introduce some type aliases for round and set-id * overhaul session "changed" flag and document better * do_initialize in BABE when getting new session * grandpa module tracks set IDs * update runtime versions * doc comment -> comment * Include docs fixes from Gav Co-Authored-By: Gavin Wood * some more review changes * fix srml-grandpa compilation --- core/finality-grandpa/primitives/src/lib.rs | 6 + core/finality-grandpa/src/aux_schema.rs | 20 ++-- .../finality-grandpa/src/communication/mod.rs | 36 +++--- core/finality-grandpa/src/environment.rs | 50 +++++---- core/finality-grandpa/src/lib.rs | 8 +- core/finality-grandpa/src/light_import.rs | 4 +- node/runtime/src/lib.rs | 2 +- srml/babe/src/lib.rs | 2 + srml/grandpa/src/lib.rs | 64 +++++++---- srml/session/src/lib.rs | 103 +++++++++++++----- srml/session/src/mock.rs | 29 +++-- srml/staking/src/lib.rs | 4 + 12 files changed, 214 insertions(+), 114 deletions(-) diff --git a/core/finality-grandpa/primitives/src/lib.rs b/core/finality-grandpa/primitives/src/lib.rs index b92444e262..1f103a548d 100644 --- a/core/finality-grandpa/primitives/src/lib.rs +++ b/core/finality-grandpa/primitives/src/lib.rs @@ -52,6 +52,12 @@ pub type AuthorityWeight = u64; /// The index of an authority. pub type AuthorityIndex = u64; +/// The identifier of a GRANDPA set. +pub type SetId = u64; + +/// The round indicator. +pub type RoundNumber = u64; + /// A scheduled change of authority set. #[cfg_attr(feature = "std", derive(Debug, Serialize))] #[derive(Clone, Eq, PartialEq, Encode, Decode)] diff --git a/core/finality-grandpa/src/aux_schema.rs b/core/finality-grandpa/src/aux_schema.rs index 78c1741d51..599604c1d3 100644 --- a/core/finality-grandpa/src/aux_schema.rs +++ b/core/finality-grandpa/src/aux_schema.rs @@ -26,7 +26,7 @@ use grandpa::round::State as RoundState; use sr_primitives::traits::{Block as BlockT, NumberFor}; use log::{info, warn}; use substrate_telemetry::{telemetry, CONSENSUS_INFO}; -use fg_primitives::AuthorityId; +use fg_primitives::{AuthorityId, AuthorityWeight, SetId, RoundNumber}; use crate::authorities::{AuthoritySet, SharedAuthoritySet, PendingChange, DelayKind}; use crate::consensus_changes::{SharedConsensusChanges, ConsensusChanges}; @@ -47,16 +47,16 @@ const CURRENT_VERSION: u32 = 2; #[cfg_attr(test, derive(PartialEq))] pub enum V1VoterSetState { /// The voter set state, currently paused. - Paused(u64, RoundState), + Paused(RoundNumber, RoundState), /// The voter set state, currently live. - Live(u64, RoundState), + Live(RoundNumber, RoundState), } -type V0VoterSetState = (u64, RoundState); +type V0VoterSetState = (RoundNumber, RoundState); #[derive(Debug, Clone, Encode, Decode, PartialEq)] struct V0PendingChange { - next_authorities: Vec<(AuthorityId, u64)>, + next_authorities: Vec<(AuthorityId, AuthorityWeight)>, delay: N, canon_height: N, canon_hash: H, @@ -64,8 +64,8 @@ struct V0PendingChange { #[derive(Debug, Clone, Encode, Decode, PartialEq)] struct V0AuthoritySet { - current_authorities: Vec<(AuthorityId, u64)>, - set_id: u64, + current_authorities: Vec<(AuthorityId, AuthorityWeight)>, + set_id: SetId, pending_changes: Vec>, } @@ -267,7 +267,7 @@ pub(crate) fn load_persistent( -> ClientResult> where B: AuxStore, - G: FnOnce() -> ClientResult>, + G: FnOnce() -> ClientResult>, { let version: Option = load_decode(backend, VERSION_KEY)?; let consensus_changes = load_decode(backend, CONSENSUS_CHANGES_KEY)? @@ -448,7 +448,7 @@ mod test { let authorities = vec![(AuthorityId::default(), 100)]; let set_id = 3; - let round_number: u64 = 42; + let round_number: RoundNumber = 42; let round_state = RoundState:: { prevote_ghost: Some((H256::random(), 32)), finalized: None, @@ -536,7 +536,7 @@ mod test { let authorities = vec![(AuthorityId::default(), 100)]; let set_id = 3; - let round_number: u64 = 42; + let round_number: RoundNumber = 42; let round_state = RoundState:: { prevote_ghost: Some((H256::random(), 32)), finalized: None, diff --git a/core/finality-grandpa/src/communication/mod.rs b/core/finality-grandpa/src/communication/mod.rs index a4b149fac4..732c14c1a9 100644 --- a/core/finality-grandpa/src/communication/mod.rs +++ b/core/finality-grandpa/src/communication/mod.rs @@ -50,7 +50,9 @@ use crate::environment::HasVoted; use gossip::{ GossipMessage, FullCatchUpMessage, FullCommitMessage, VoteOrPrecommitMessage, GossipValidator }; -use fg_primitives::{AuthorityPair, AuthorityId, AuthoritySignature}; +use fg_primitives::{ + AuthorityPair, AuthorityId, AuthoritySignature, SetId as SetIdNumber, RoundNumber, +}; pub mod gossip; mod periodic; @@ -129,12 +131,12 @@ pub trait Network: Clone + Send + 'static { } /// Create a unique topic for a round and set-id combo. -pub(crate) fn round_topic(round: u64, set_id: u64) -> B::Hash { +pub(crate) fn round_topic(round: RoundNumber, set_id: SetIdNumber) -> B::Hash { <::Hashing as HashT>::hash(format!("{}-{}", set_id, round).as_bytes()) } /// Create a unique topic for global messages on a set ID. -pub(crate) fn global_topic(set_id: u64) -> B::Hash { +pub(crate) fn global_topic(set_id: SetIdNumber) -> B::Hash { <::Hashing as HashT>::hash(format!("{}-GLOBAL", set_id).as_bytes()) } @@ -618,25 +620,25 @@ impl> Clone for NetworkBridge { } } -fn localized_payload(round: u64, set_id: u64, message: &E) -> Vec { +fn localized_payload(round: RoundNumber, set_id: SetIdNumber, message: &E) -> Vec { (message, round, set_id).encode() } -/// Type-safe wrapper around u64 when indicating that it's a round number. +/// Type-safe wrapper around a round number. #[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Encode, Decode)] -pub struct Round(pub u64); +pub struct Round(pub RoundNumber); -/// Type-safe wrapper around u64 when indicating that it's a set ID. +/// Type-safe wrapper around a set ID. #[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Encode, Decode)] -pub struct SetId(pub u64); +pub struct SetId(pub SetIdNumber); // check a message. pub(crate) fn check_message_sig( message: &Message, id: &AuthorityId, signature: &AuthoritySignature, - round: u64, - set_id: u64, + round: RoundNumber, + set_id: SetIdNumber, ) -> Result<(), ()> { let as_public = id.clone(); let encoded_raw = localized_payload(round, set_id, message); @@ -656,8 +658,8 @@ pub(crate) fn check_message_sig( /// `ed25519` and `BLS` signatures (which we might use in the future), care must /// be taken when switching to different key types. struct OutgoingMessages> { - round: u64, - set_id: u64, + round: RoundNumber, + set_id: SetIdNumber, locals: Option<(AuthorityPair, AuthorityId)>, sender: mpsc::UnboundedSender>, network: N, @@ -851,8 +853,8 @@ fn check_catch_up( fn check_signatures<'a, B, I>( messages: I, - round: u64, - set_id: u64, + round: RoundNumber, + set_id: SetIdNumber, mut signatures_checked: usize, ) -> Result where B: BlockT, @@ -919,7 +921,7 @@ impl> CommitsOut { /// Create a new commit output stream. pub(crate) fn new( network: N, - set_id: u64, + set_id: SetIdNumber, is_voter: bool, gossip_validator: Arc>, ) -> Self { @@ -933,10 +935,10 @@ impl> CommitsOut { } impl> Sink for CommitsOut { - type SinkItem = (u64, Commit); + type SinkItem = (RoundNumber, Commit); type SinkError = Error; - fn start_send(&mut self, input: (u64, Commit)) -> StartSend { + fn start_send(&mut self, input: (RoundNumber, Commit)) -> StartSend { if !self.is_voter { return Ok(AsyncSink::Ready); } diff --git a/core/finality-grandpa/src/environment.rs b/core/finality-grandpa/src/environment.rs index b20e8ab5df..c0474cb036 100644 --- a/core/finality-grandpa/src/environment.rs +++ b/core/finality-grandpa/src/environment.rs @@ -51,7 +51,7 @@ use crate::authorities::{AuthoritySet, SharedAuthoritySet}; use crate::consensus_changes::SharedConsensusChanges; use crate::justification::GrandpaJustification; use crate::until_imported::UntilVoteTargetImported; -use fg_primitives::{AuthorityId, AuthoritySignature}; +use fg_primitives::{AuthorityId, AuthoritySignature, SetId, RoundNumber}; type HistoricalVotes = grandpa::HistoricalVotes< ::Hash, @@ -65,7 +65,7 @@ type HistoricalVotes = grandpa::HistoricalVotes< #[derive(Debug, Clone, Decode, Encode, PartialEq)] pub struct CompletedRound { /// The round number. - pub number: u64, + pub number: RoundNumber, /// The round state (prevote ghost, estimate, finalized, etc.) pub state: RoundState>, /// The target block base used for voting in the round. @@ -80,7 +80,7 @@ pub struct CompletedRound { #[derive(Debug, Clone, PartialEq)] pub struct CompletedRounds { rounds: Vec>, - set_id: u64, + set_id: SetId, voters: Vec, } @@ -100,7 +100,7 @@ impl codec::EncodeLike for CompletedRounds {} impl Decode for CompletedRounds { fn decode(value: &mut I) -> Result { - <(Vec>, u64, Vec)>::decode(value) + <(Vec>, SetId, Vec)>::decode(value) .map(|(rounds, set_id, voters)| CompletedRounds { rounds: rounds.into(), set_id, @@ -113,7 +113,7 @@ impl CompletedRounds { /// Create a new completed rounds tracker with NUM_LAST_COMPLETED_ROUNDS capacity. pub(crate) fn new( genesis: CompletedRound, - set_id: u64, + set_id: SetId, voters: &AuthoritySet>, ) -> CompletedRounds @@ -126,7 +126,7 @@ impl CompletedRounds { } /// Get the set-id and voter set of the completed rounds. - pub fn set_info(&self) -> (u64, &[AuthorityId]) { + pub fn set_info(&self) -> (SetId, &[AuthorityId]) { (self.set_id, &self.voters[..]) } @@ -162,7 +162,7 @@ impl CompletedRounds { /// A map with voter status information for currently live rounds, /// which votes have we cast and what are they. -pub type CurrentRounds = BTreeMap>; +pub type CurrentRounds = BTreeMap>; /// The state of the current voter set, whether it is currently active or not /// and information related to the previously completed rounds. Current round @@ -190,7 +190,7 @@ impl VoterSetState { /// the given genesis state and the given authorities. Round 1 is added as a /// current round (with state `HasVoted::No`). pub(crate) fn live( - set_id: u64, + set_id: SetId, authority_set: &AuthoritySet>, genesis_state: (Block::Hash, NumberFor), ) -> VoterSetState { @@ -237,7 +237,7 @@ impl VoterSetState { /// Returns the voter set state validating that it includes the given round /// in current rounds and that the voter isn't paused. - pub fn with_current_round(&self, round: u64) + pub fn with_current_round(&self, round: RoundNumber) -> Result<(&CompletedRounds, &CurrentRounds), Error> { if let VoterSetState::Live { completed_rounds, current_rounds } = self { @@ -344,7 +344,7 @@ impl SharedVoterSetState { } /// Return vote status information for the current round. - pub(crate) fn has_voted(&self, round: u64) -> HasVoted { + pub(crate) fn has_voted(&self, round: RoundNumber) -> HasVoted { match &*self.inner.read() { VoterSetState::Live { current_rounds, .. } => { current_rounds.get(&round).and_then(|has_voted| match has_voted { @@ -375,7 +375,7 @@ pub(crate) struct Environment, RA, SC> { pub(crate) authority_set: SharedAuthoritySet>, pub(crate) consensus_changes: SharedConsensusChanges>, pub(crate) network: crate::communication::NetworkBridge, - pub(crate) set_id: u64, + pub(crate) set_id: SetId, pub(crate) voter_set_state: SharedVoterSetState, } @@ -554,7 +554,7 @@ where fn round_data( &self, - round: u64 + round: RoundNumber, ) -> voter::RoundData { let now = Instant::now(); let prevote_timer = Delay::new(now + self.config.gossip_duration * 2); @@ -601,7 +601,7 @@ where } } - fn proposed(&self, round: u64, propose: PrimaryPropose) -> Result<(), Self::Error> { + fn proposed(&self, round: RoundNumber, propose: PrimaryPropose) -> Result<(), Self::Error> { let local_id = crate::is_voter(&self.voters, &self.config.keystore); let local_id = match local_id { @@ -641,7 +641,7 @@ where Ok(()) } - fn prevoted(&self, round: u64, prevote: Prevote) -> Result<(), Self::Error> { + fn prevoted(&self, round: RoundNumber, prevote: Prevote) -> Result<(), Self::Error> { let local_id = crate::is_voter(&self.voters, &self.config.keystore); let local_id = match local_id { @@ -683,7 +683,7 @@ where Ok(()) } - fn precommitted(&self, round: u64, precommit: Precommit) -> Result<(), Self::Error> { + fn precommitted(&self, round: RoundNumber, precommit: Precommit) -> Result<(), Self::Error> { let local_id = crate::is_voter(&self.voters, &self.config.keystore); let local_id = match local_id { @@ -737,7 +737,7 @@ where fn completed( &self, - round: u64, + round: RoundNumber, state: RoundState>, base: (Block::Hash, NumberFor), historical_votes: &HistoricalVotes, @@ -794,7 +794,13 @@ where Ok(()) } - fn finalize_block(&self, hash: Block::Hash, number: NumberFor, round: u64, commit: Commit) -> Result<(), Self::Error> { + fn finalize_block( + &self, + hash: Block::Hash, + number: NumberFor, + round: RoundNumber, + commit: Commit, + ) -> Result<(), Self::Error> { finalize_block( &*self.inner, &self.authority_set, @@ -818,7 +824,7 @@ where fn prevote_equivocation( &self, - _round: u64, + _round: RoundNumber, equivocation: ::grandpa::Equivocation, Self::Signature> ) { warn!(target: "afg", "Detected prevote equivocation in the finality worker: {:?}", equivocation); @@ -827,7 +833,7 @@ where fn precommit_equivocation( &self, - _round: u64, + _round: RoundNumber, equivocation: Equivocation, Self::Signature> ) { warn!(target: "afg", "Detected precommit equivocation in the finality worker: {:?}", equivocation); @@ -837,11 +843,11 @@ where pub(crate) enum JustificationOrCommit { Justification(GrandpaJustification), - Commit((u64, Commit)), + Commit((RoundNumber, Commit)), } -impl From<(u64, Commit)> for JustificationOrCommit { - fn from(commit: (u64, Commit)) -> JustificationOrCommit { +impl From<(RoundNumber, Commit)> for JustificationOrCommit { + fn from(commit: (RoundNumber, Commit)) -> JustificationOrCommit { JustificationOrCommit::Commit(commit) } } diff --git a/core/finality-grandpa/src/lib.rs b/core/finality-grandpa/src/lib.rs index f6c11dd634..b79b120e35 100644 --- a/core/finality-grandpa/src/lib.rs +++ b/core/finality-grandpa/src/lib.rs @@ -108,7 +108,7 @@ use import::GrandpaBlockImport; use until_imported::UntilGlobalMessageBlocksImported; use communication::NetworkBridge; use service::TelemetryOnConnect; -use fg_primitives::AuthoritySignature; +use fg_primitives::{AuthoritySignature, SetId, AuthorityWeight}; // Re-export these two because it's just so damn convenient. pub use fg_primitives::{AuthorityId, ScheduledChange}; @@ -267,8 +267,8 @@ impl, RA> BlockStatus for Arc { pub(crate) canon_number: N, pub(crate) canon_hash: H, - pub(crate) set_id: u64, - pub(crate) authorities: Vec<(AuthorityId, u64)>, + pub(crate) set_id: SetId, + pub(crate) authorities: Vec<(AuthorityId, AuthorityWeight)>, } /// Commands issued to the voter. @@ -399,7 +399,7 @@ where } fn global_communication, B, E, N, RA>( - set_id: u64, + set_id: SetId, voters: &Arc>, client: &Arc>, network: &NetworkBridge, diff --git a/core/finality-grandpa/src/light_import.rs b/core/finality-grandpa/src/light_import.rs index dbdabe9629..4d5381f1cc 100644 --- a/core/finality-grandpa/src/light_import.rs +++ b/core/finality-grandpa/src/light_import.rs @@ -36,7 +36,7 @@ use sr_primitives::Justification; use sr_primitives::traits::{ NumberFor, Block as BlockT, Header as HeaderT, ProvideRuntimeApi, DigestFor, }; -use fg_primitives::{GrandpaApi, AuthorityId}; +use fg_primitives::{self, GrandpaApi, AuthorityId}; use sr_primitives::generic::BlockId; use primitives::{H256, Blake2Hasher}; @@ -192,7 +192,7 @@ impl LightAuthoritySet { /// Get a genesis set with given authorities. pub fn genesis(initial: Vec<(AuthorityId, u64)>) -> Self { LightAuthoritySet { - set_id: 0, + set_id: fg_primitives::SetId::default(), authorities: initial, } } diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 01dff2b7ae..c8496fa3b1 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -80,7 +80,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 149, + spec_version: 150, impl_version: 150, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/babe/src/lib.rs b/srml/babe/src/lib.rs index b58fb26b5a..0f439d489e 100644 --- a/srml/babe/src/lib.rs +++ b/srml/babe/src/lib.rs @@ -445,6 +445,8 @@ impl session::OneSessionHandler for Module { fn on_new_session<'a, I: 'a>(_changed: bool, validators: I, queued_validators: I) where I: Iterator { + Self::do_initialize(); + // Update epoch index let epoch_index = EpochIndex::get() .checked_add(1) diff --git a/srml/grandpa/src/lib.rs b/srml/grandpa/src/lib.rs index d64939ae0a..5fc354eab9 100644 --- a/srml/grandpa/src/lib.rs +++ b/srml/grandpa/src/lib.rs @@ -33,7 +33,8 @@ pub use substrate_finality_grandpa_primitives as fg_primitives; use rstd::prelude::*; use codec::{self as codec, Encode, Decode, Error}; use srml_support::{ - decl_event, decl_storage, decl_module, dispatch::Result, storage::StorageValue + decl_event, decl_storage, decl_module, dispatch::Result, + storage::StorageValue, storage::StorageMap, }; use sr_primitives::{ generic::{DigestItem, OpaqueDigestItemId}, traits::Zero, @@ -43,7 +44,7 @@ use sr_staking_primitives::{ SessionIndex, offence::{Offence, Kind}, }; -use fg_primitives::{ScheduledChange, ConsensusLog, GRANDPA_ENGINE_ID}; +use fg_primitives::{GRANDPA_ENGINE_ID, ScheduledChange, ConsensusLog, SetId, RoundNumber}; pub use fg_primitives::{AuthorityId, AuthorityWeight}; use system::{ensure_signed, DigestOf}; @@ -65,7 +66,7 @@ pub struct OldStoredPendingChange { /// The delay in blocks until it will be applied. pub delay: N, /// The next authority set. - pub next_authorities: Vec<(AuthorityId, u64)>, + pub next_authorities: Vec<(AuthorityId, AuthorityWeight)>, } /// A stored pending change. @@ -76,7 +77,7 @@ pub struct StoredPendingChange { /// The delay in blocks until it will be applied. pub delay: N, /// The next authority set. - pub next_authorities: Vec<(AuthorityId, u64)>, + pub next_authorities: Vec<(AuthorityId, AuthorityWeight)>, /// If defined it means the change was forced and the given block number /// indicates the median last finalized block when the change was signaled. pub forced: Option, @@ -127,7 +128,7 @@ pub enum StoredState { decl_event!( pub enum Event { /// New authority set has been applied. - NewAuthorities(Vec<(AuthorityId, u64)>), + NewAuthorities(Vec<(AuthorityId, AuthorityWeight)>), /// Current authority set has been paused. Paused, /// Current authority set has been resumed. @@ -151,6 +152,13 @@ decl_storage! { /// `true` if we are currently stalled. Stalled get(stalled): Option<(T::BlockNumber, T::BlockNumber)>; + + /// The number of changes (both in terms of keys and underlying economic responsibilities) + /// in the "set" of Grandpa validators from genesis. + CurrentSetId get(current_set_id) build(|_| fg_primitives::SetId::default()): SetId; + + /// A mapping from grandpa set ID to the index of the *most recent* session for which its members were responsible. + SetIdSession get(session_for_set): map SetId => Option; } add_extra_genesis { config(authorities): Vec<(AuthorityId, AuthorityWeight)>; @@ -243,7 +251,7 @@ decl_module! { impl Module { /// Get the current set of authorities, along with their respective weights. - pub fn grandpa_authorities() -> Vec<(AuthorityId, u64)> { + pub fn grandpa_authorities() -> Vec<(AuthorityId, AuthorityWeight)> { Authorities::get() } @@ -292,7 +300,7 @@ impl Module { /// No change should be signaled while any change is pending. Returns /// an error if a change is already pending. pub fn schedule_change( - next_authorities: Vec<(AuthorityId, u64)>, + next_authorities: Vec<(AuthorityId, AuthorityWeight)>, in_blocks: T::BlockNumber, forced: Option, ) -> Result { @@ -337,29 +345,34 @@ impl Module { } impl Module { + /// Attempt to extract a GRANDPA log from a generic digest. pub fn grandpa_log(digest: &DigestOf) -> Option> { let id = OpaqueDigestItemId::Consensus(&GRANDPA_ENGINE_ID); digest.convert_first(|l| l.try_to::>(id)) } + /// Attempt to extract a pending set-change signal from a digest. pub fn pending_change(digest: &DigestOf) -> Option> { Self::grandpa_log(digest).and_then(|signal| signal.try_into_change()) } + /// Attempt to extract a forced set-change signal from a digest. pub fn forced_change(digest: &DigestOf) -> Option<(T::BlockNumber, ScheduledChange)> { Self::grandpa_log(digest).and_then(|signal| signal.try_into_forced_change()) } + /// Attempt to extract a pause signal from a digest. pub fn pending_pause(digest: &DigestOf) -> Option { Self::grandpa_log(digest).and_then(|signal| signal.try_into_pause()) } + /// Attempt to extract a resume signal from a digest. pub fn pending_resume(digest: &DigestOf) -> Option { @@ -367,7 +380,9 @@ impl Module { } } -impl session::OneSessionHandler for Module { +impl session::OneSessionHandler for Module + where T: session::Trait +{ type Key = AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) @@ -380,18 +395,27 @@ impl session::OneSessionHandler for Module { fn on_new_session<'a, I: 'a>(changed: bool, validators: I, _queued_validators: I) where I: Iterator { - // instant changes - if changed { + // Always issue a change if `session` says that the validators have changed. + // Even if their session keys are the same as before, the underyling economic + // identities have changed. + let current_set_id = if changed { let next_authorities = validators.map(|(_, k)| (k, 1)).collect::>(); - let last_authorities = >::grandpa_authorities(); - if next_authorities != last_authorities { - if let Some((further_wait, median)) = >::take() { - let _ = Self::schedule_change(next_authorities, further_wait, Some(median)); - } else { - let _ = Self::schedule_change(next_authorities, Zero::zero(), None); - } + if let Some((further_wait, median)) = >::take() { + let _ = Self::schedule_change(next_authorities, further_wait, Some(median)); + } else { + let _ = Self::schedule_change(next_authorities, Zero::zero(), None); } - } + CurrentSetId::mutate(|s| { *s += 1; *s }) + } else { + // nothing's changed, neither economic conditions nor session keys. update the pointer + // of the current set. + Self::current_set_id() + }; + + // if we didn't issue a change, we update the mapping to note that the current + // set corresponds to the latest equivalent session (i.e. now). + let session_index = >::current_index(); + SetIdSession::insert(current_set_id, &session_index); } fn on_disabled(i: usize) { @@ -412,8 +436,8 @@ impl finality_tracker::OnFinalizationStalled for Modul #[derive(Copy, Clone, PartialOrd, Ord, Eq, PartialEq, Encode, Decode)] struct GrandpaTimeSlot { // The order of these matters for `derive(Ord)`. - set_id: u64, - round: u64, + set_id: SetId, + round: RoundNumber, } // TODO [slashing]: Integrate this. diff --git a/srml/session/src/lib.rs b/srml/session/src/lib.rs index f8e13d529b..6a09591e01 100644 --- a/srml/session/src/lib.rs +++ b/srml/session/src/lib.rs @@ -170,6 +170,12 @@ impl< pub trait OnSessionEnding { /// Handle the fact that the session is ending, and optionally provide the new validator set. /// + /// Even if the validator-set is the same as before, if any underlying economic + /// conditions have changed (i.e. stake-weights), the new validator set must be returned. + /// This is necessary for consensus engines making use of the session module to + /// issue a validator-set change so misbehavior can be provably associated with the new + /// economic conditions as opposed to the old. + /// /// `ending_index` is the index of the currently ending session. /// The returned validator set, if any, will not be applied until `will_apply_at`. /// `will_apply_at` is guaranteed to be at least `ending_index + 1`, since session indices don't @@ -192,7 +198,11 @@ pub trait SessionHandler { /// should provide the same validator set. fn on_genesis_session(validators: &[(ValidatorId, Ks)]); - /// Session set has changed; act appropriately. + /// Session set has changed; act appropriately. Note that this can be called + /// before initialization of your module. + /// + /// `changed` is true whenever any of the session keys or underlying economic + /// identities or weightings behind those keys has changed. fn on_new_session( changed: bool, validators: &[(ValidatorId, Ks)], @@ -217,11 +227,19 @@ pub trait OneSessionHandler { fn on_genesis_session<'a, I: 'a>(validators: I) where I: Iterator, ValidatorId: 'a; - /// Session set has changed; act appropriately. + /// Session set has changed; act appropriately. Note that this can be called + /// before initialization of your module. + /// + /// `changed` is true when at least one of the session keys + /// or the underlying economic identities/distribution behind one the + /// session keys has changed, false otherwise. + /// + /// The `validators` are the validators of the incoming session, and `queued_validators` + /// will follow. fn on_new_session<'a, I: 'a>( - _changed: bool, - _validators: I, - _queued_validators: I + changed: bool, + validators: I, + queued_validators: I, ) where I: Iterator, ValidatorId: 'a; @@ -341,10 +359,8 @@ decl_storage! { /// Current index of the session. CurrentIndex get(current_index): SessionIndex; - /// True if anything has changed in this session. - Changed: bool; - - /// Queued keys changed. + /// True if the underlying economic identities or weighting behind the validators + /// has changed in the queued validator set. QueuedChanged: bool; /// The queued keys for the next session. When the next session begins, these keys @@ -443,13 +459,10 @@ decl_module! { Self::do_set_keys(&who, keys)?; - // Something changed. - Changed::put(true); - Ok(()) } - /// Called when a block is finalized. Will rotate session if it is the last + /// Called when a block is initialized. Will rotate session if it is the last /// block of the current session. fn on_initialize(n: T::BlockNumber) { if T::ShouldEndSession::should_end_session(n) { @@ -467,7 +480,6 @@ impl Module { let session_index = CurrentIndex::get(); let changed = QueuedChanged::get(); - let mut next_changed = Changed::take(); // Get queued session keys and validators. let session_keys = >::get(); @@ -479,12 +491,16 @@ impl Module { let applied_at = session_index + 2; // Get next validator set. - let maybe_validators = T::OnSessionEnding::on_session_ending(session_index, applied_at); - let next_validators = if let Some(validators) = maybe_validators { - next_changed = true; - validators + let maybe_next_validators = T::OnSessionEnding::on_session_ending(session_index, applied_at); + let (next_validators, next_identities_changed) + = if let Some(validators) = maybe_next_validators + { + // NOTE: as per the documentation on `OnSessionEnding`, we consider + // the validator set as having changed even if the validators are the + // same as before, as underlying economic conditions may have changed. + (validators, true) } else { - >::get() + (>::get(), false) }; // Increment session index. @@ -492,9 +508,34 @@ impl Module { CurrentIndex::put(session_index); // Queue next session keys. - let queued_amalgamated = next_validators.into_iter() - .map(|a| { let k = Self::load_keys(&a).unwrap_or_default(); (a, k) }) - .collect::>(); + let (queued_amalgamated, next_changed) = { + // until we are certain there has been a change, iterate the prior + // validators along with the current and check for changes + let mut changed = next_identities_changed; + + let mut now_session_keys = session_keys.iter(); + let mut check_next_changed = |keys: &T::Keys| { + if changed { return } + // since a new validator set always leads to `changed` starting + // as true, we can ensure that `now_session_keys` and `next_validators` + // have the same length. this function is called once per iteration. + if let Some(&(_, ref old_keys)) = now_session_keys.next() { + if old_keys != keys { + changed = true; + return + } + } + }; + let queued_amalgamated = next_validators.into_iter() + .map(|a| { + let k = Self::load_keys(&a).unwrap_or_default(); + check_next_changed(&k); + (a, k) + }) + .collect::>(); + + (queued_amalgamated, changed) + }; >::put(queued_amalgamated.clone()); QueuedChanged::put(next_changed); @@ -503,13 +544,16 @@ impl Module { Self::deposit_event(Event::NewSession(session_index)); // Tell everyone about the new session keys. - T::SessionHandler::on_new_session::(changed, &session_keys, &queued_amalgamated); + T::SessionHandler::on_new_session::( + changed, + &session_keys, + &queued_amalgamated, + ); } /// Disable the validator of index `i`. pub fn disable_index(i: usize) { T::SessionHandler::on_disabled(i); - Changed::put(true); } /// Disable the validator identified by `c`. (If using with the staking module, this would be @@ -554,8 +598,6 @@ impl Module { let key_data = old_keys.get_raw(id); Self::clear_key_owner(id, key_data); } - - Changed::put(true); } } @@ -668,8 +710,6 @@ mod tests { Session::on_free_balance_zero(&1); assert_eq!(Session::load_keys(&1), None); assert_eq!(Session::key_owner(id, UintAuthorityId(1).get_raw(id)), None); - - assert!(Changed::get()); }) } @@ -816,9 +856,16 @@ mod tests { initialize_block(6); assert!(!session_changed()); + // changing the keys of a validator leads to change. + assert_ok!(Session::set_keys(Origin::signed(69), UintAuthorityId(69).into(), vec![])); force_new_session(); initialize_block(7); assert!(session_changed()); + + // while changing the keys of a non-validator does not. + force_new_session(); + initialize_block(7); + assert!(!session_changed()); }); } diff --git a/srml/session/src/mock.rs b/srml/session/src/mock.rs index c5608e1a54..13fcb54754 100644 --- a/srml/session/src/mock.rs +++ b/srml/session/src/mock.rs @@ -44,6 +44,7 @@ impl_outer_origin! { } thread_local! { + pub static VALIDATORS: RefCell> = RefCell::new(vec![1, 2, 3]); pub static NEXT_VALIDATORS: RefCell> = RefCell::new(vec![1, 2, 3]); pub static AUTHORITIES: RefCell> = RefCell::new(vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]); @@ -51,6 +52,7 @@ thread_local! { pub static SESSION_LENGTH: RefCell = RefCell::new(2); pub static SESSION_CHANGED: RefCell = RefCell::new(false); pub static TEST_SESSION_CHANGED: RefCell = RefCell::new(false); + pub static DISABLED: RefCell = RefCell::new(false); } pub struct TestShouldEndSession; @@ -76,14 +78,24 @@ impl SessionHandler for TestSessionHandler { .collect() ); } - fn on_disabled(_validator_index: usize) {} + fn on_disabled(_validator_index: usize) { + DISABLED.with(|l| *l.borrow_mut() = true) + } } pub struct TestOnSessionEnding; impl OnSessionEnding for TestOnSessionEnding { fn on_session_ending(_: SessionIndex, _: SessionIndex) -> Option> { if !TEST_SESSION_CHANGED.with(|l| *l.borrow()) { - Some(NEXT_VALIDATORS.with(|l| l.borrow().clone())) + VALIDATORS.with(|v| { + let mut v = v.borrow_mut(); + *v = NEXT_VALIDATORS.with(|l| l.borrow().clone()); + Some(v.clone()) + }) + } else if DISABLED.with(|l| std::mem::replace(&mut *l.borrow_mut(), false)) { + // If there was a disabled validator, underlying conditions have changed + // so we return `Some`. + Some(VALIDATORS.with(|v| v.borrow().clone())) } else { None } @@ -92,16 +104,13 @@ impl OnSessionEnding for TestOnSessionEnding { #[cfg(feature = "historical")] impl crate::historical::OnSessionEnding for TestOnSessionEnding { - fn on_session_ending(_: SessionIndex, _: SessionIndex) + fn on_session_ending(ending_index: SessionIndex, will_apply_at: SessionIndex) -> Option<(Vec, Vec<(u64, u64)>)> { - if !TEST_SESSION_CHANGED.with(|l| *l.borrow()) { - let last_validators = Session::validators(); - let last_identifications = last_validators.into_iter().map(|v| (v, v)).collect(); - Some((NEXT_VALIDATORS.with(|l| l.borrow().clone()), last_identifications)) - } else { - None - } + let pair_with_ids = |vals: &[u64]| vals.iter().map(|&v| (v, v)).collect::>(); + >::on_session_ending(ending_index, will_apply_at) + .map(|vals| (pair_with_ids(&vals), vals)) + .map(|(ids, vals)| (vals, ids)) } } diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index e7bb42c64d..9386035e44 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -1355,6 +1355,10 @@ impl Module { // Set the new validator set in sessions. >::put(&elected_stashes); + // In order to keep the property required by `n_session_ending` + // that we must return the new validator set even if it's the same as the old, + // as long as any underlying economic conditions have changed, we don't attempt + // to do any optimization where we compare against the prior set. (slot_stake, Some(elected_stashes)) } else { // There were not enough candidates for even our minimal level of functionality. -- GitLab From d2cc68e97d9818c3d7872c7f6991e2c419e77738 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Sat, 24 Aug 2019 17:41:45 +0200 Subject: [PATCH 007/275] improve error msg on wrong closure signature (#3467) --- .../procedural/src/storage/transformation.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index d378907cb1..eb479a2664 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -35,7 +35,7 @@ use syn::{ }, parse_macro_input, }; -use quote::quote; +use quote::{quote, quote_spanned}; use super::*; @@ -417,7 +417,16 @@ fn decl_store_extra_genesis( } assimilate_require_generic |= ext::expr_contains_ident(&expr.content, traitinstance); let content = &expr.content; - scall = quote!( ( #content ) ); + scall = quote_spanned! { expr.span() => + let scall: fn( + &mut ( + #scrate::sr_primitives::StorageOverlay, + #scrate::sr_primitives::ChildrenStorageOverlay + ), + &Self + ) = #content; + scall + }; has_scall = true; }, } -- GitLab From 7ab9efff56f7ed613615319afa0ccc5bf2c3877c Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Sat, 24 Aug 2019 18:42:57 +0300 Subject: [PATCH 008/275] fix digest in check_execution_proof (#3469) --- core/client/src/light/call_executor.rs | 21 ++++++++------------- core/test-runtime/src/system.rs | 12 ++++++++++++ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/core/client/src/light/call_executor.rs b/core/client/src/light/call_executor.rs index 2367aaf806..746f36069d 100644 --- a/core/client/src/light/call_executor.rs +++ b/core/client/src/light/call_executor.rs @@ -471,7 +471,7 @@ pub fn check_execution_proof( Default::default(), Default::default(), request.header.hash(), - request.header.digest().clone(), + Default::default(), ); execution_proof_check_on_trie_backend::( &trie_backend, @@ -498,7 +498,7 @@ pub fn check_execution_proof( #[cfg(test)] mod tests { use consensus::BlockOrigin; - use test_client::{self, runtime::Header, ClientExt, TestClient}; + use test_client::{self, runtime::{Header, Digest}, ClientExt, TestClient}; use executor::NativeExecutor; use crate::backend::{Backend, NewBlockState}; use crate::in_mem::Backend as InMemBackend; @@ -509,8 +509,7 @@ mod tests { fn execution_proof_is_generated_and_checked() { fn execute(remote_client: &TestClient, at: u64, method: &'static str) -> (Vec, Vec) { let remote_block_id = BlockId::Number(at); - let remote_root = remote_client.state_at(&remote_block_id) - .unwrap().storage_root(::std::iter::empty()).0; + let remote_header = remote_client.header(&remote_block_id).unwrap().unwrap(); // 'fetch' execution proof from remote node let (remote_result, remote_execution_proof) = remote_client.execution_proof( @@ -523,13 +522,7 @@ mod tests { let local_executor = NativeExecutor::::new(None); let local_result = check_execution_proof(&local_executor, &RemoteCallRequest { block: test_client::runtime::Hash::default(), - header: test_client::runtime::Header { - state_root: remote_root.into(), - parent_hash: Default::default(), - number: at, - extrinsics_root: Default::default(), - digest: Default::default(), - }, + header: remote_header, method: method.into(), call_data: vec![], retry_count: None, @@ -540,10 +533,12 @@ mod tests { // prepare remote client let remote_client = test_client::new(); - for _ in 1..3 { + for i in 1u32..3u32 { + let mut digest = Digest::default(); + digest.push(sr_primitives::generic::DigestItem::Other::(i.to_le_bytes().to_vec())); remote_client.import_justified( BlockOrigin::Own, - remote_client.new_block(Default::default()).unwrap().bake().unwrap(), + remote_client.new_block(digest).unwrap().bake().unwrap(), Default::default(), ).unwrap(); } diff --git a/core/test-runtime/src/system.rs b/core/test-runtime/src/system.rs index f3c890cf79..63f9c0050b 100644 --- a/core/test-runtime/src/system.rs +++ b/core/test-runtime/src/system.rs @@ -62,6 +62,12 @@ pub fn initialize_block(header: &Header) { ::put(&header.parent_hash); ::put(header.digest()); storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &0u32); + + // try to read something that depends on current header digest + // so that it'll be included in execution proof + if let Some(generic::DigestItem::Other(v)) = header.digest().logs().iter().next() { + let _: Option = storage::unhashed::get(&v); + } } pub fn get_block_number() -> Option { @@ -104,6 +110,12 @@ fn execute_block_with_state_root_handler( assert!(txs_root == header.extrinsics_root, "Transaction trie root must be valid."); } + // try to read something that depends on current header digest + // so that it'll be included in execution proof + if let Some(generic::DigestItem::Other(v)) = header.digest().logs().iter().next() { + let _: Option = storage::unhashed::get(&v); + } + // execute transactions block.extrinsics.iter().enumerate().for_each(|(i, e)| { storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &(i as u32)); -- GitLab From a6cbed65ab40e481597b00227ad10d5d41e422b1 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Sat, 24 Aug 2019 18:00:26 +0200 Subject: [PATCH 009/275] Clean runtime constants (#3459) * Remove bogus constants. * Bump. --- node/runtime/src/lib.rs | 7 +++---- srml/balances/src/lib.rs | 6 ------ srml/democracy/src/lib.rs | 7 ------- srml/elections/src/lib.rs | 10 ---------- srml/staking/src/lib.rs | 3 --- srml/treasury/src/lib.rs | 5 ----- 6 files changed, 3 insertions(+), 35 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index c8496fa3b1..d6014addaa 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -48,7 +48,6 @@ use version::NativeVersion; use primitives::OpaqueMetadata; use grandpa::{AuthorityId as GrandpaId, AuthorityWeight as GrandpaWeight}; use im_online::{AuthorityId as ImOnlineId}; -use finality_tracker::{DEFAULT_REPORT_LATENCY, DEFAULT_WINDOW_SIZE}; #[cfg(any(feature = "std", test))] pub use sr_primitives::BuildStorage; @@ -81,7 +80,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 150, - impl_version: 150, + impl_version: 151, apis: RUNTIME_API_VERSIONS, }; @@ -414,8 +413,8 @@ impl grandpa::Trait for Runtime { } parameter_types! { - pub const WindowSize: BlockNumber = DEFAULT_WINDOW_SIZE.into(); - pub const ReportLatency: BlockNumber = DEFAULT_REPORT_LATENCY.into(); + pub const WindowSize: BlockNumber = 101; + pub const ReportLatency: BlockNumber = 1000; } impl finality_tracker::Trait for Runtime { diff --git a/srml/balances/src/lib.rs b/srml/balances/src/lib.rs index d3961e53c9..e450ca6403 100644 --- a/srml/balances/src/lib.rs +++ b/srml/balances/src/lib.rs @@ -181,12 +181,6 @@ mod tests; pub use self::imbalances::{PositiveImbalance, NegativeImbalance}; -pub const DEFAULT_EXISTENTIAL_DEPOSIT: u32 = 0; -pub const DEFAULT_TRANSFER_FEE: u32 = 0; -pub const DEFAULT_CREATION_FEE: u32 = 0; -pub const DEFAULT_TRANSACTION_BASE_FEE: u32 = 0; -pub const DEFAULT_TRANSACTION_BYTE_FEE: u32 = 0; - pub trait Subtrait: system::Trait { /// The balance of an account. type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index cfac7fdfbc..d4cfedc37b 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -174,13 +174,6 @@ impl Decode for Vote { type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -pub const DEFAULT_ENACTMENT_PERIOD: u32 = 0; -pub const DEFAULT_LAUNCH_PERIOD: u32 = 0; -pub const DEFAULT_VOTING_PERIOD: u32 = 0; -pub const DEFAULT_MINIMUM_DEPOSIT: u32 = 0; -pub const DEFAULT_EMERGENCY_VOTING_PERIOD: u32 = 0; -pub const DEFAULT_COOLOFF_PERIOD: u32 = 0; - pub trait Trait: system::Trait + Sized { type Proposal: Parameter + Dispatchable; type Event: From> + Into<::Event>; diff --git a/srml/elections/src/lib.rs b/srml/elections/src/lib.rs index a82b3fab7e..f615fdee38 100644 --- a/srml/elections/src/lib.rs +++ b/srml/elections/src/lib.rs @@ -138,18 +138,8 @@ pub type VoteIndex = u32; // all three must be in sync. type ApprovalFlag = u32; -pub const APPROVAL_FLAG_MASK: ApprovalFlag = 0x8000_0000; pub const APPROVAL_FLAG_LEN: usize = 32; -pub const DEFAULT_CANDIDACY_BOND: u32 = 9; -pub const DEFAULT_VOTING_BOND: u32 = 0; -pub const DEFAULT_VOTING_FEE: u32 = 0; -pub const DEFAULT_PRESENT_SLASH_PER_VOTER: u32 = 1; -pub const DEFAULT_CARRY_COUNT: u32 = 2; -pub const DEFAULT_INACTIVE_GRACE_PERIOD: u32 = 1; -pub const DEFAULT_VOTING_PERIOD: u32 = 1000; -pub const DEFAULT_DECAY_RATIO: u32 = 24; - pub trait Trait: system::Trait { type Event: From> + Into<::Event>; diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index 9386035e44..a4d1ed88ab 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -465,9 +465,6 @@ type ExpoMap = BTreeMap< Exposure<::AccountId, BalanceOf> >; -pub const DEFAULT_SESSIONS_PER_ERA: u32 = 3; -pub const DEFAULT_BONDING_DURATION: u32 = 1; - /// Means for interacting with a specialized version of the `session` trait. /// /// This is needed because `Staking` sets the `ValidatorIdOf` of the `session::Trait` diff --git a/srml/treasury/src/lib.rs b/srml/treasury/src/lib.rs index 12ef4fc14e..1e709b74a6 100644 --- a/srml/treasury/src/lib.rs +++ b/srml/treasury/src/lib.rs @@ -89,11 +89,6 @@ type NegativeImbalanceOf = <::Currency as Currency< + ReservableCurrency; -- GitLab From 3e975b30f4d162ac0b42b075ddc41ac537db4774 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Sat, 24 Aug 2019 20:12:29 +0200 Subject: [PATCH 010/275] Allow root to force transfers (#3475) * Allow root to force transfers * Bump version * Avoid changing pre-existing encodings --- node/runtime/src/lib.rs | 2 +- srml/balances/src/lib.rs | 17 ++++++++++++++++- srml/balances/src/tests.rs | 15 +++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index d6014addaa..d1b9abd4cf 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -79,7 +79,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 150, + spec_version: 151, impl_version: 151, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/balances/src/lib.rs b/srml/balances/src/lib.rs index e450ca6403..0c83897045 100644 --- a/srml/balances/src/lib.rs +++ b/srml/balances/src/lib.rs @@ -462,7 +462,7 @@ decl_module! { /// - Independent of the arguments. /// - Contains a limited number of reads and writes. /// # - #[weight = SimpleDispatchInfo::FixedOperational(500_000)] + #[weight = SimpleDispatchInfo::FixedOperational(50_000)] fn set_balance( origin, who: ::Source, @@ -488,6 +488,21 @@ decl_module! { } Self::set_reserved_balance(&who, new_reserved); } + + /// Exactly as `transfer`, except the origin must be root and the source account may be + /// specified. + #[weight = SimpleDispatchInfo::FixedNormal(1_000_000)] + pub fn force_transfer( + origin, + source: ::Source, + dest: ::Source, + #[compact] value: T::Balance + ) { + ensure_root(origin)?; + let source = T::Lookup::lookup(source)?; + let dest = T::Lookup::lookup(dest)?; + >::transfer(&source, &dest, value)?; + } } } diff --git a/srml/balances/src/tests.rs b/srml/balances/src/tests.rs index 338513d40d..1af3ce6ba0 100644 --- a/srml/balances/src/tests.rs +++ b/srml/balances/src/tests.rs @@ -26,6 +26,7 @@ use srml_support::{ traits::{LockableCurrency, LockIdentifier, WithdrawReason, WithdrawReasons, Currency, ReservableCurrency} }; +use system::RawOrigin; const ID_1: LockIdentifier = *b"1 "; const ID_2: LockIdentifier = *b"2 "; @@ -352,6 +353,20 @@ fn balance_transfer_works() { }); } +#[test] +fn force_transfer_works() { + with_externalities(&mut ExtBuilder::default().build(), || { + let _ = Balances::deposit_creating(&1, 111); + assert_noop!( + Balances::force_transfer(Some(2).into(), 1, 2, 69), + "bad origin: expected to be a root origin" + ); + assert_ok!(Balances::force_transfer(RawOrigin::Root.into(), 1, 2, 69)); + assert_eq!(Balances::total_balance(&1), 42); + assert_eq!(Balances::total_balance(&2), 69); + }); +} + #[test] fn reserving_balance_should_work() { with_externalities(&mut ExtBuilder::default().build(), || { -- GitLab From 337a0b22aaa42e4210d59091d4d95ad75dbb02f3 Mon Sep 17 00:00:00 2001 From: Xiliang Chen Date: Sun, 25 Aug 2019 22:57:31 +1200 Subject: [PATCH 011/275] add Copy to Moment type (#3476) * add Copy to Moment type * bump version * add Copy to support::Traits::Time::Moment and removed few clones --- node/runtime/src/lib.rs | 2 +- srml/aura/src/lib.rs | 4 ++-- srml/democracy/src/lib.rs | 4 ++-- srml/staking/src/lib.rs | 2 +- srml/support/src/traits.rs | 2 +- srml/timestamp/src/lib.rs | 8 ++++---- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index d1b9abd4cf..0c5cdefd96 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -80,7 +80,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 151, - impl_version: 151, + impl_version: 152, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/aura/src/lib.rs b/srml/aura/src/lib.rs index e02a2e1f0a..4df832912a 100644 --- a/srml/aura/src/lib.rs +++ b/srml/aura/src/lib.rs @@ -258,7 +258,7 @@ impl Module { fn on_timestamp_set(now: T::Moment, slot_duration: T::Moment) { let last = Self::last(); - ::LastTimestamp::put(now.clone()); + ::LastTimestamp::put(now); if last.is_zero() { return; @@ -266,7 +266,7 @@ impl Module { assert!(!slot_duration.is_zero(), "Aura slot duration cannot be zero."); - let last_slot = last / slot_duration.clone(); + let last_slot = last / slot_duration; let cur_slot = now / slot_duration; assert!(last_slot < cur_slot, "Only one block may be authored per slot."); diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index d4cfedc37b..f1265438f2 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -946,12 +946,12 @@ impl Module { if (now % T::LaunchPeriod::get()).is_zero() { // Errors come from the queue being empty. we don't really care about that, and even if // we did, there is nothing we can do here. - let _ = Self::launch_next(now.clone()); + let _ = Self::launch_next(now); } // tally up votes for any expiring referenda. for (index, info) in Self::maturing_referenda_at(now).into_iter() { - Self::bake_referendum(now.clone(), index, info)?; + Self::bake_referendum(now, index, info)?; } for (proposal, index) in >::take(now).into_iter().filter_map(|x| x) { diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index a4d1ed88ab..2e46d6b2b4 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -1179,7 +1179,7 @@ impl Module { let rewards = CurrentEraRewards::take(); let now = T::Time::now(); let previous_era_start = >::mutate(|v| { - rstd::mem::replace(v, now.clone()) + rstd::mem::replace(v, now) }); let era_duration = now - previous_era_start; if !era_duration.is_zero() { diff --git a/srml/support/src/traits.rs b/srml/support/src/traits.rs index cca9fd2b10..37262cdfcb 100644 --- a/srml/support/src/traits.rs +++ b/srml/support/src/traits.rs @@ -620,7 +620,7 @@ bitmask! { } pub trait Time { - type Moment: SimpleArithmetic + Codec + Clone + Default; + type Moment: SimpleArithmetic + Codec + Clone + Default + Copy; fn now() -> Self::Moment; } diff --git a/srml/timestamp/src/lib.rs b/srml/timestamp/src/lib.rs index 78a741aff4..1b03b5b9af 100644 --- a/srml/timestamp/src/lib.rs +++ b/srml/timestamp/src/lib.rs @@ -195,9 +195,9 @@ macro_rules! impl_timestamp_set { ); ( $($t:ident)* ) => { - impl),*> OnTimestampSet for ($($t,)*) { + impl),*> OnTimestampSet for ($($t,)*) { fn on_timestamp_set(moment: Moment) { - $($t::on_timestamp_set(moment.clone());)* + $($t::on_timestamp_set(moment);)* } } } @@ -209,7 +209,7 @@ for_each_tuple!(impl_timestamp_set); pub trait Trait: system::Trait { /// Type used for expressing timestamp. type Moment: Parameter + Default + SimpleArithmetic - + Scale; + + Scale + Copy; /// Something which can be notified when the timestamp is set. Set this to `()` if not needed. type OnTimestampSet: OnTimestampSet; @@ -246,7 +246,7 @@ decl_module! { Self::now().is_zero() || now >= Self::now() + T::MinimumPeriod::get(), "Timestamp must increment by at least between sequential blocks" ); - ::Now::put(now.clone()); + ::Now::put(now); ::DidUpdate::put(true); >::on_timestamp_set(now); -- GitLab From f5e71926975a798b6655107625bd5fa2a8d495a2 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 26 Aug 2019 08:37:42 +0100 Subject: [PATCH 012/275] Custom deserialize impl for ApisVec (#3471) --- core/rpc/src/state/tests.rs | 10 +++++--- core/sr-version/src/lib.rs | 50 +++++++++++++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/core/rpc/src/state/tests.rs b/core/rpc/src/state/tests.rs index 6b4ddc9b92..0bb6d40e24 100644 --- a/core/rpc/src/state/tests.rs +++ b/core/rpc/src/state/tests.rs @@ -262,10 +262,12 @@ fn should_return_runtime_version() { [\"0xc6e9a76309f39b09\",1],[\"0xdd718d5cc53262d4\",1],[\"0xcbca25e39f142387\",1],\ [\"0xf78b278be53f454c\",1],[\"0xab3c0572291feb8b\",1]]}"; - assert_eq!( - serde_json::to_string(&api.runtime_version(None.into()).unwrap()).unwrap(), - result, - ); + let runtime_version = api.runtime_version(None.into()).unwrap(); + let serialized = serde_json::to_string(&runtime_version).unwrap(); + assert_eq!(serialized, result); + + let deserialized: RuntimeVersion = serde_json::from_str(result).unwrap(); + assert_eq!(deserialized, runtime_version); } #[test] diff --git a/core/sr-version/src/lib.rs b/core/sr-version/src/lib.rs index 731c5b63c7..f787d8dd7e 100644 --- a/core/sr-version/src/lib.rs +++ b/core/sr-version/src/lib.rs @@ -96,7 +96,13 @@ pub struct RuntimeVersion { pub impl_version: u32, /// List of supported API "features" along with their versions. - #[cfg_attr(feature = "std", serde(serialize_with = "apis_serialize::serialize"))] + #[cfg_attr( + feature = "std", + serde( + serialize_with = "apis_serialize::serialize", + deserialize_with = "apis_serialize::deserialize", + ) + )] pub apis: ApisVec, } @@ -163,7 +169,7 @@ impl NativeVersion { mod apis_serialize { use super::*; use impl_serde::serialize as bytes; - use serde::{Serializer, ser::SerializeTuple}; + use serde::{Serializer, de, ser::SerializeTuple}; #[derive(Serialize)] struct ApiId<'a>( @@ -187,4 +193,44 @@ mod apis_serialize { { bytes::serialize(*apis, ser) } + + #[derive(Deserialize)] + struct ApiIdOwned( + #[serde(deserialize_with="deserialize_bytes")] + super::ApiId, + u32, + ); + + pub fn deserialize<'de, D>(deserializer: D) -> Result where + D: de::Deserializer<'de>, + { + struct Visitor; + impl<'de> de::Visitor<'de> for Visitor { + type Value = ApisVec; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a sequence of api id and version tuples") + } + + fn visit_seq(self, mut visitor: V) -> Result where + V: de::SeqAccess<'de>, + { + let mut apis = Vec::new(); + while let Some(value) = visitor.next_element::()? { + apis.push((value.0, value.1)); + } + Ok(apis.into()) + } + } + deserializer.deserialize_seq(Visitor) + } + + pub fn deserialize_bytes<'de, D>(d: D) -> Result where + D: de::Deserializer<'de> + { + let bytes = bytes::deserialize_check_len(d, bytes::ExpectedLen::Exact(8))?; + let mut arr = [0; 8]; + arr.copy_from_slice(&bytes); + Ok(arr) + } } -- GitLab From c63ee7ad8fef5aba30930e56b82e282e2f14d1d5 Mon Sep 17 00:00:00 2001 From: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Date: Mon, 26 Aug 2019 10:56:00 +0200 Subject: [PATCH 013/275] fix typos in readme (#3481) --- README.adoc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.adoc b/README.adoc index 6afa1cf4e1..91c473c347 100644 --- a/README.adoc +++ b/README.adoc @@ -133,7 +133,7 @@ First let's get a template chainspec that you can edit. We'll use the "staging" substrate build-spec --chain=staging > ~/chainspec.json ---- -Now, edit `~/chainspec.json` in your editor. There are a lot of individual fields for each module, and one very large one which contains the Webassembly code blob for this chain. The easiest field to edit is the block `period`. Change it to 10 (seconds): +Now, edit `~/chainspec.json` in your editor. There are a lot of individual fields for each module, and one very large one which contains the WebAssembly code blob for this chain. The easiest field to edit is the block `period`. Change it to 10 (seconds): [source, json] ---- @@ -281,9 +281,9 @@ cargo run \-- --dev Detailed logs may be shown by running the node with the following environment variables set: `RUST_LOG=debug RUST_BACKTRACE=1 cargo run \-- --dev`. -If you want to see the multi-node consensus algorithm in action locally, then you can create a local testnet with two validator nodes for Alice and Bob, who are the initial authorities of the genesis chain specification that have been endowed with a testnet DOTs. We'll give each node a name and expose them so they are listed on link:https://telemetry.polkadot.io/#/Local%20Testnet[Telemetry] . You'll need two terminals windows open. +If you want to see the multi-node consensus algorithm in action locally, then you can create a local testnet with two validator nodes for Alice and Bob, who are the initial authorities of the genesis chain specification that have been endowed with a testnet DOTs. We'll give each node a name and expose them so they are listed on link:https://telemetry.polkadot.io/#/Local%20Testnet[Telemetry]. You'll need two terminal windows open. -We'll start Alice's substrate node first on default TCP port 30333 with her chain database stored locally at `/tmp/alice`. The Bootnode ID of her node is `QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR`, which is generated from the `--node-key` value that we specify below: +We'll start Alice's Substrate node first on default TCP port 30333 with her chain database stored locally at `/tmp/alice`. The Bootnode ID of her node is `QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR`, which is generated from the `--node-key` value that we specify below: [source, shell] cargo run --release \-- \ @@ -294,7 +294,7 @@ cargo run --release \-- \ --telemetry-url ws://telemetry.polkadot.io:1024 \ --validator -In the second terminal, we'll run the following to start Bob's substrate node on a different TCP port of 30334, and with his chain database stored locally at `/tmp/bob`. We'll specify a value for the `--bootnodes` option that will connect his node to Alice's Bootnode ID on TCP port 30333: +In the second terminal, we'll run the following to start Bob's Substrate node on a different TCP port of 30334, and with his chain database stored locally at `/tmp/bob`. We'll specify a value for the `--bootnodes` option that will connect his node to Alice's Bootnode ID on TCP port 30333: [source, shell] cargo run --release \-- \ @@ -408,7 +408,7 @@ curl -H 'Content-Type: application/json' --data '{ "jsonrpc":"2.0", "method":"au ``` `KEY_TYPE` - needs to be replaced with the 4-character key type identifier. -`SEEED` - is the seed of the key. +`SEED` - is the seed of the key. == Documentation -- GitLab From 2d2f08f8d1b0d9f67da3729447d163d96a6f4f39 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 26 Aug 2019 21:30:09 +0300 Subject: [PATCH 014/275] init cache on restart (#3486) --- core/client/db/src/cache/mod.rs | 4 ++-- core/client/db/src/light.rs | 41 +++++++++++++++++++++------------ 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/core/client/db/src/cache/mod.rs b/core/client/db/src/cache/mod.rs index 68245a54ee..f53eb54ca0 100644 --- a/core/client/db/src/cache/mod.rs +++ b/core/client/db/src/cache/mod.rs @@ -299,8 +299,8 @@ impl BlockchainCache for DbCacheSync { key: &CacheKeyId, at: &BlockId, ) -> Option<((NumberFor, Block::Hash), Option<(NumberFor, Block::Hash)>, Vec)> { - let cache = self.0.read(); - let storage = cache.cache_at.get(key)?.storage(); + let mut cache = self.0.write(); + let storage = cache.get_cache(*key).storage(); let db = storage.db(); let columns = storage.columns(); let at = match *at { diff --git a/core/client/db/src/light.rs b/core/client/db/src/light.rs index 2ee2c2ec54..86408a155d 100644 --- a/core/client/db/src/light.rs +++ b/core/client/db/src/light.rs @@ -1030,26 +1030,37 @@ pub(crate) mod tests { #[test] fn cache_can_be_initialized_after_genesis_inserted() { - let db = LightStorage::::new_test(); + let (genesis_hash, storage) = { + let db = LightStorage::::new_test(); + + // before cache is initialized => None + assert_eq!(db.cache().get_at(b"test", &BlockId::Number(0)), None); + + // insert genesis block (no value for cache is provided) + let mut genesis_hash = None; + insert_block(&db, HashMap::new(), || { + let header = default_header(&Default::default(), 0); + genesis_hash = Some(header.hash()); + header + }); - // before cache is initialized => None - assert_eq!(db.cache().get_at(b"test", &BlockId::Number(0)), None); + // after genesis is inserted => None + assert_eq!(db.cache().get_at(b"test", &BlockId::Number(0)), None); - // insert genesis block (no value for cache is provided) - let mut genesis_hash = None; - insert_block(&db, HashMap::new(), || { - let header = default_header(&Default::default(), 0); - genesis_hash = Some(header.hash()); - header - }); + // initialize cache + db.cache().initialize(b"test", vec![42]).unwrap(); - // after genesis is inserted => None - assert_eq!(db.cache().get_at(b"test", &BlockId::Number(0)), None); + // after genesis is inserted + cache is initialized => Some + assert_eq!( + db.cache().get_at(b"test", &BlockId::Number(0)), + Some(((0, genesis_hash.unwrap()), None, vec![42])), + ); - // initialize cache - db.cache().initialize(b"test", vec![42]).unwrap(); + (genesis_hash, db.db) + }; - // after genesis is inserted + cache is initialized => Some + // restart && check that after restart value is read from the cache + let db = LightStorage::::from_kvdb(storage as Arc<_>).expect("failed to create test-db"); assert_eq!( db.cache().get_at(b"test", &BlockId::Number(0)), Some(((0, genesis_hash.unwrap()), None, vec![42])), -- GitLab From 036df49173e8ce539553092d6a0f4aa276905c4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 27 Aug 2019 07:43:10 +0200 Subject: [PATCH 015/275] Make `node-template-release` create a workspace (#3484) --- scripts/node-template-release/src/main.rs | 59 ++++++++++++++++++++--- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/scripts/node-template-release/src/main.rs b/scripts/node-template-release/src/main.rs index 4036104f60..e1db5af649 100644 --- a/scripts/node-template-release/src/main.rs +++ b/scripts/node-template-release/src/main.rs @@ -117,8 +117,15 @@ fn replace_path_dependencies_with_git(cargo_toml_path: &Path, commit_id: &str, c cargo_toml.insert("dependencies".into(), dependencies.into()); } -/// Add `profile.release` = `panic = unwind` to the given `Cargo.toml` -fn cargo_toml_add_profile_release(cargo_toml: &mut CargoToml) { +/// Update the top level (workspace) `Cargo.toml` file. +/// +/// - Adds `profile.release` = `panic = unwind` +/// - Adds `workspace` definition +fn update_top_level_cargo_toml( + cargo_toml: &mut CargoToml, + workspace_members: Vec<&PathBuf>, + node_template_path: &Path, +) { let mut panic_unwind = toml::value::Table::new(); panic_unwind.insert("panic".into(), "unwind".into()); @@ -126,6 +133,24 @@ fn cargo_toml_add_profile_release(cargo_toml: &mut CargoToml) { profile.insert("release".into(), panic_unwind.into()); cargo_toml.insert("profile".into(), profile.into()); + + let members = workspace_members.iter() + .map(|p| + p.strip_prefix(node_template_path) + .expect("Workspace member is a child of the node template path!") + .parent() + // We get the `Cargo.toml` paths as workspace members, but for the `members` field + // we just need the path. + .expect("The given path ends with `Cargo.toml` as file name!") + .display() + .to_string() + ) + .collect::>(); + + let mut members_section = toml::value::Table::new(); + members_section.insert("members".into(), members.into()); + + cargo_toml.insert("workspace".into(), members_section.into()); } fn write_cargo_toml(path: &Path, cargo_toml: CargoToml) { @@ -137,10 +162,24 @@ fn write_cargo_toml(path: &Path, cargo_toml: CargoToml) { /// Build and test the generated node-template fn build_and_test(path: &Path, cargo_tomls: &[PathBuf]) { // Build node - assert!(Command::new("cargo").args(&["build", "--all"]).current_dir(path).status().expect("Compiles node").success()); + assert!( + Command::new("cargo") + .args(&["build", "--all"]) + .current_dir(path) + .status() + .expect("Compiles node") + .success() + ); // Test node - assert!(Command::new("cargo").args(&["test", "--all"]).current_dir(path).status().expect("Tests node").success()); + assert!( + Command::new("cargo") + .args(&["test", "--all"]) + .current_dir(path) + .status() + .expect("Tests node") + .success() + ); // Remove all `target` directories for toml in cargo_tomls { @@ -174,14 +213,20 @@ fn main() { let cargo_tomls = find_cargo_tomls(build_dir.path().to_owned()); let commit_id = get_git_commit_id(&options.node_template); + let top_level_cargo_toml_path = node_template_path.join("Cargo.toml"); cargo_tomls.iter().for_each(|t| { let mut cargo_toml = parse_cargo_toml(&t); replace_path_dependencies_with_git(&t, &commit_id, &mut cargo_toml); - // If this is the top-level `Cargo.toml`, add `profile.release` - if &node_template_path.join("Cargo.toml") == t { - cargo_toml_add_profile_release(&mut cargo_toml); + // Check if this is the top level `Cargo.toml`, as this requires some special treatments. + if top_level_cargo_toml_path == *t { + // All workspace member `Cargo.toml` file paths. + let workspace_members = cargo_tomls.iter() + .filter(|p| **p != top_level_cargo_toml_path) + .collect(); + + update_top_level_cargo_toml(&mut cargo_toml, workspace_members, &node_template_path); } write_cargo_toml(&t, cargo_toml); -- GitLab From 3f6cbc851883a7e7638e81ea43cf2bfc5e2a3736 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 27 Aug 2019 10:07:30 +0200 Subject: [PATCH 016/275] Introduce capabilities filtering for off-chain runtime calls. (#3454) * Introduce capabilities filtering for calls. * Bump impl version. * Allow RichOffchainCall to only read offchain db. * Fix code. * Panic on invalid calls. * Merge execution contexts and expose capabilities. * Fix repr * Re-enable keystore for offchain calls. --- Cargo.lock | 1 + core/client/src/client.rs | 18 +- core/offchain/src/lib.rs | 4 +- core/primitives/Cargo.toml | 2 + core/primitives/src/lib.rs | 20 +- core/primitives/src/offchain.rs | 195 ++++++++++++++++++++ core/sr-api-macros/src/decl_runtime_apis.rs | 4 +- node/runtime/src/lib.rs | 2 +- 8 files changed, 224 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2967d167da..6a2260b3b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4946,6 +4946,7 @@ dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/core/client/src/client.rs b/core/client/src/client.rs index c6234dc8d1..a57584575c 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -27,8 +27,9 @@ use codec::{Encode, Decode}; use hash_db::{Hasher, Prefix}; use primitives::{ Blake2Hasher, H256, ChangesTrieConfiguration, convert_hash, - NeverNativeValue, ExecutionContext, - storage::{StorageKey, StorageData, well_known_keys}, NativeOrEncoded + NeverNativeValue, ExecutionContext, NativeOrEncoded, + storage::{StorageKey, StorageData, well_known_keys}, + offchain, }; use substrate_telemetry::{telemetry, SUBSTRATE_INFO}; use sr_primitives::{ @@ -1471,8 +1472,6 @@ impl CallRuntimeAt for Client where context: ExecutionContext, recorder: &Option>>>, ) -> error::Result> { - let enable_keystore = context.enable_keystore(); - let manager = match context { ExecutionContext::BlockConstruction => self.execution_strategies.block_construction.get_manager(), @@ -1480,16 +1479,17 @@ impl CallRuntimeAt for Client where self.execution_strategies.syncing.get_manager(), ExecutionContext::Importing => self.execution_strategies.importing.get_manager(), - ExecutionContext::OffchainWorker(_) => + ExecutionContext::OffchainCall(Some((_, capabilities))) if capabilities.has_all() => self.execution_strategies.offchain_worker.get_manager(), - ExecutionContext::Other => + ExecutionContext::OffchainCall(_) => self.execution_strategies.other.get_manager(), }; + let capabilities = context.capabilities(); let mut offchain_extensions = match context { - ExecutionContext::OffchainWorker(ext) => Some(ext), + ExecutionContext::OffchainCall(ext) => ext.map(|x| x.0), _ => None, - }; + }.map(|ext| offchain::LimitedExternalities::new(capabilities, ext)); self.executor.contextual_call::<_, _, fn(_,_) -> _,_,_>( || core_api.initialize_block(at, &self.prepare_environment_block(at)?), @@ -1502,7 +1502,7 @@ impl CallRuntimeAt for Client where native_call, offchain_extensions.as_mut(), recorder, - enable_keystore, + capabilities.has(offchain::Capability::Keystore), ) } diff --git a/core/offchain/src/lib.rs b/core/offchain/src/lib.rs index b38b202c62..9b785ec8ba 100644 --- a/core/offchain/src/lib.rs +++ b/core/offchain/src/lib.rs @@ -43,7 +43,7 @@ use client::runtime_api::ApiExt; use futures::future::Future; use log::{debug, warn}; use network::NetworkStateInfo; -use primitives::ExecutionContext; +use primitives::{offchain, ExecutionContext}; use sr_primitives::{generic::BlockId, traits::{self, ProvideRuntimeApi}}; use transaction_pool::txpool::{Pool, ChainApi}; @@ -122,7 +122,7 @@ impl OffchainWorkers< debug!("Running offchain workers at {:?}", at); let run = runtime.offchain_worker_with_context( &at, - ExecutionContext::OffchainWorker(api), + ExecutionContext::OffchainCall(Some((api, offchain::Capabilities::all()))), number, ); if let Err(e) = run { diff --git a/core/primitives/Cargo.toml b/core/primitives/Cargo.toml index b9bb141ad7..f05907e3f2 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -13,6 +13,7 @@ twox-hash = { version = "1.2.0", optional = true } byteorder = { version = "1.3.1", default-features = false } primitive-types = { version = "0.5.0", default-features = false, features = ["codec"] } impl-serde = { version = "0.1", optional = true } +log = { version = "0.4", optional = true } wasmi = { version = "0.5.0", optional = true } hash-db = { version = "0.15.2", default-features = false } hash256-std-hasher = { version = "0.15.2", default-features = false } @@ -48,6 +49,7 @@ bench = false [features] default = ["std"] std = [ + "log", "wasmi", "lazy_static", "parking_lot", diff --git a/core/primitives/src/lib.rs b/core/primitives/src/lib.rs index 21e7c87808..5c918e4964 100644 --- a/core/primitives/src/lib.rs +++ b/core/primitives/src/lib.rs @@ -88,19 +88,23 @@ pub enum ExecutionContext { Syncing, /// Context used for block construction. BlockConstruction, - /// Offchain worker context. - OffchainWorker(Box), - /// Context used for other calls. - Other, + /// Context used for offchain calls. + /// + /// This allows passing offchain extension and customizing available capabilities. + OffchainCall(Option<(Box, offchain::Capabilities)>), } impl ExecutionContext { - /// Returns if the keystore should be enabled for the current context. - pub fn enable_keystore(&self) -> bool { + /// Returns the capabilities of particular context. + pub fn capabilities(&self) -> offchain::Capabilities { use ExecutionContext::*; + match self { - Importing | Syncing | BlockConstruction => false, - OffchainWorker(_) | Other => true, + Importing | Syncing | BlockConstruction => + offchain::Capabilities::none(), + // Enable keystore by default for offchain calls. CC @bkchr + OffchainCall(None) => [offchain::Capability::Keystore][..].into(), + OffchainCall(Some((_, capabilities))) => *capabilities, } } } diff --git a/core/primitives/src/offchain.rs b/core/primitives/src/offchain.rs index 8aa097cec0..6f024c5c02 100644 --- a/core/primitives/src/offchain.rs +++ b/core/primitives/src/offchain.rs @@ -232,6 +232,70 @@ impl Timestamp { } } +/// Execution context extra capabilities. +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[repr(u8)] +pub enum Capability { + /// Access to transaction pool. + TransactionPool = 1, + /// External http calls. + Http = 2, + /// Keystore access. + Keystore = 4, + /// Randomness source. + Randomness = 8, + /// Access to opaque network state. + NetworkState = 16, + /// Access to offchain worker DB (read only). + OffchainWorkerDbRead = 32, + /// Access to offchain worker DB (writes). + OffchainWorkerDbWrite = 64, +} + +/// A set of capabilities +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub struct Capabilities(u8); + +impl Capabilities { + /// Return an object representing an empty set of capabilities. + pub fn none() -> Self { + Self(0) + } + + /// Return an object representing all capabilities enabled. + pub fn all() -> Self { + Self(u8::max_value()) + } + + /// Return capabilities for rich offchain calls. + /// + /// Those calls should be allowed to sign and submit transactions + /// and access offchain workers database (but read only!). + pub fn rich_offchain_call() -> Self { + [ + Capability::TransactionPool, + Capability::Keystore, + Capability::OffchainWorkerDbRead, + ][..].into() + } + + /// Check if particular capability is enabled. + pub fn has(&self, capability: Capability) -> bool { + self.0 & capability as u8 != 0 + } + + /// Check if this capability object represents all capabilities. + pub fn has_all(&self) -> bool { + self == &Capabilities::all() + } +} + +impl<'a> From<&'a [Capability]> for Capabilities { + fn from(list: &'a [Capability]) -> Self { + Capabilities(list.iter().fold(0_u8, |a, b| a | *b as u8)) + } +} + /// An extended externalities for offchain workers. pub trait Externalities { /// Returns if the local node is a potential validator. @@ -481,6 +545,123 @@ impl Externalities for Box { (&mut **self).http_response_read_body(request_id, buffer, deadline) } } +/// An `OffchainExternalities` implementation with limited capabilities. +pub struct LimitedExternalities { + capabilities: Capabilities, + externalities: T, +} + +impl LimitedExternalities { + /// Create new externalities limited to given `capabilities`. + pub fn new(capabilities: Capabilities, externalities: T) -> Self { + Self { + capabilities, + externalities, + } + } + + /// Check if given capability is allowed. + /// + /// Panics in case it is not. + fn check(&self, capability: Capability, name: &'static str) { + if !self.capabilities.has(capability) { + panic!("Accessing a forbidden API: {}. No: {:?} capability.", name, capability); + } + } +} + +impl Externalities for LimitedExternalities { + fn is_validator(&self) -> bool { + self.check(Capability::Keystore, "is_validator"); + self.externalities.is_validator() + } + + fn submit_transaction(&mut self, ex: Vec) -> Result<(), ()> { + self.check(Capability::TransactionPool, "submit_transaction"); + self.externalities.submit_transaction(ex) + } + + fn network_state(&self) -> Result { + self.check(Capability::NetworkState, "network_state"); + self.externalities.network_state() + } + + fn timestamp(&mut self) -> Timestamp { + self.check(Capability::Http, "timestamp"); + self.externalities.timestamp() + } + + fn sleep_until(&mut self, deadline: Timestamp) { + self.check(Capability::Http, "sleep_until"); + self.externalities.sleep_until(deadline) + } + + fn random_seed(&mut self) -> [u8; 32] { + self.check(Capability::Randomness, "random_seed"); + self.externalities.random_seed() + } + + fn local_storage_set(&mut self, kind: StorageKind, key: &[u8], value: &[u8]) { + self.check(Capability::OffchainWorkerDbWrite, "local_storage_set"); + self.externalities.local_storage_set(kind, key, value) + } + + fn local_storage_compare_and_set( + &mut self, + kind: StorageKind, + key: &[u8], + old_value: Option<&[u8]>, + new_value: &[u8], + ) -> bool { + self.check(Capability::OffchainWorkerDbWrite, "local_storage_compare_and_set"); + self.externalities.local_storage_compare_and_set(kind, key, old_value, new_value) + } + + fn local_storage_get(&mut self, kind: StorageKind, key: &[u8]) -> Option> { + self.check(Capability::OffchainWorkerDbRead, "local_storage_get"); + self.externalities.local_storage_get(kind, key) + } + + fn http_request_start(&mut self, method: &str, uri: &str, meta: &[u8]) -> Result { + self.check(Capability::Http, "http_request_start"); + self.externalities.http_request_start(method, uri, meta) + } + + fn http_request_add_header(&mut self, request_id: HttpRequestId, name: &str, value: &str) -> Result<(), ()> { + self.check(Capability::Http, "http_request_add_header"); + self.externalities.http_request_add_header(request_id, name, value) + } + + fn http_request_write_body( + &mut self, + request_id: HttpRequestId, + chunk: &[u8], + deadline: Option + ) -> Result<(), HttpError> { + self.check(Capability::Http, "http_request_write_body"); + self.externalities.http_request_write_body(request_id, chunk, deadline) + } + + fn http_response_wait(&mut self, ids: &[HttpRequestId], deadline: Option) -> Vec { + self.check(Capability::Http, "http_response_wait"); + self.externalities.http_response_wait(ids, deadline) + } + + fn http_response_headers(&mut self, request_id: HttpRequestId) -> Vec<(Vec, Vec)> { + self.check(Capability::Http, "http_response_headers"); + self.externalities.http_response_headers(request_id) + } + + fn http_response_read_body( + &mut self, + request_id: HttpRequestId, + buffer: &mut [u8], + deadline: Option + ) -> Result { + self.check(Capability::Http, "http_response_read_body"); + self.externalities.http_response_read_body(request_id, buffer, deadline) + } +} #[cfg(test)] @@ -494,4 +675,18 @@ mod tests { assert_eq!(t.sub(Duration::from_millis(10)), Timestamp(0)); assert_eq!(t.diff(&Timestamp(3)), Duration(2)); } + + #[test] + fn capabilities() { + let none = Capabilities::none(); + let all = Capabilities::all(); + let some = Capabilities::from(&[Capability::Keystore, Capability::Randomness][..]); + + assert!(!none.has(Capability::Keystore)); + assert!(all.has(Capability::Keystore)); + assert!(some.has(Capability::Keystore)); + assert!(!none.has(Capability::TransactionPool)); + assert!(all.has(Capability::TransactionPool)); + assert!(!some.has(Capability::TransactionPool)); + } } diff --git a/core/sr-api-macros/src/decl_runtime_apis.rs b/core/sr-api-macros/src/decl_runtime_apis.rs index 27f102740b..0e69c2b76d 100644 --- a/core/sr-api-macros/src/decl_runtime_apis.rs +++ b/core/sr-api-macros/src/decl_runtime_apis.rs @@ -552,9 +552,9 @@ impl<'a> ToClientSideDecl<'a> { fn fold_trait_item_method(&mut self, method: TraitItemMethod) -> (TraitItemMethod, Option, TraitItemMethod) { let crate_ = self.crate_; - let context_other = quote!( #crate_::runtime_api::ExecutionContext::Other ); + let context = quote!( #crate_::runtime_api::ExecutionContext::OffchainCall(None) ); let fn_impl = self.create_method_runtime_api_impl(method.clone()); - let fn_decl = self.create_method_decl(method.clone(), context_other); + let fn_decl = self.create_method_decl(method.clone(), context); let fn_decl_ctx = self.create_method_decl_with_context(method); (fn_decl, fn_impl, fn_decl_ctx) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 0c5cdefd96..33088260b7 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -80,7 +80,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 151, - impl_version: 152, + impl_version: 153, apis: RUNTIME_API_VERSIONS, }; -- GitLab From a0a74b5fd03e8d9d490121ee3a03fd707ce39d14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 27 Aug 2019 10:59:33 +0200 Subject: [PATCH 017/275] Improve `insert_key` error message on unsupported key type (#3490) --- core/rpc/src/author/error.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/core/rpc/src/author/error.rs b/core/rpc/src/author/error.rs index 2fcc8c780d..1ce707f0bb 100644 --- a/core/rpc/src/author/error.rs +++ b/core/rpc/src/author/error.rs @@ -83,6 +83,8 @@ const POOL_TOO_LOW_PRIORITY: i64 = POOL_INVALID_TX + 4; const POOL_CYCLE_DETECTED: i64 = POOL_INVALID_TX + 5; /// The transaction was not included to the pool because of the limits. const POOL_IMMEDIATELY_DROPPED: i64 = POOL_INVALID_TX + 6; +/// The key type crypto is not known. +const UNSUPPORTED_KEY_TYPE: i64 = POOL_INVALID_TX + 7; impl From for rpc::Error { fn from(e: Error) -> Self { @@ -134,6 +136,14 @@ impl From for rpc::Error { message: "Immediately Dropped" .into(), data: Some("The transaction couldn't enter the pool because of the limit".into()), }, + Error::UnsupportedKeyType => rpc::Error { + code: rpc::ErrorCode::ServerError(UNSUPPORTED_KEY_TYPE), + message: "Unknown key type crypto" .into(), + data: Some( + "The crypto for the given key type is unknown, please add the public key to the \ + request to insert the key successfully.".into() + ), + }, e => errors::internal(e), } } -- GitLab From d14e727bdd97396fafeb4b3f86d9629aa9fd5b4d Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 27 Aug 2019 11:18:41 +0200 Subject: [PATCH 018/275] Service factory refactor (#3382) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Move Service::new to a macro * Move function calls to macros * Extract offchain_workers and start_rpc in separate function In follow-up commits, we want to be able to directly call maintain_transaction_pool, offchain_workers, and start_rpc, without having to implement the Components trait. This commit is a preliminary step: we extract the code to freestanding functions. * Introduce an AbstractService trait * Introduce NewService as an implementation detail of Service * Implement traits on NewService instead Instead of implementing AbstractService, Future, and Executor on Service, we implement them on NewService instead. The implementations of AbstractService, Future, and Executor on Service still exist, but they just wrap to the respective implementations for NewService. * Move components creation back to macro invocation Instead of having multiple $build_ parameters passed to the macro, let's group them all into one. This change is necessary for the follow-up commits, because we are going to call new_impl! only after all the components have already been built. * Add a $block parameter to new_impl This makes it possible to be explicit as what the generic parameter of the NewServiceis, without relying on type inference. * Introduce the ServiceBuilder struct Introduces a new builder-like ServiceBuilder struct that creates a NewService. * Macro-ify import_blocks, export_blocks and revert_chain Similar to the introduction of new_impl!, we extract the actual code into a macro, letting us get rid of the Components and Factory traits * Add export_blocks, import_blocks and revert_chain methods on ServiceBuilder Can be used as a replacement for the chain_ops::* methods * Add run_with_builder Instead of just run, adds run_with_builder to ParseAndPrepareExport/Import/Revert. This lets you run these operations with a ServiceBuilder instead of a ServiceFactory. * Transition node and node-template to ServiceBuilder * Transition transaction-factory to the new service factory This is technically a breaking change, but the transaction-factory crate is only ever used from within substrate-node, which this commit updates as well. * Remove old service factory * Adjust the AbstractService trait to be more usable We slightly change the trait bounds in order to make all the methods usable. * Make substrate-service-test compile * Fix the node-cli tests * Remove the old API * Remove the components module * Fix indentation on chain_ops * Line widths * Fix bad line widths commit * Line widths again 🤦 * Fix the sync test * Apply suggestions from code review Co-Authored-By: Gavin Wood * Address some concerns * Remove TelemetryOnConnect * Remove informant::start * Update jsonrpc * Rename factory to builder * Line widths 😩 --- Cargo.lock | 118 ++- core/cli/src/informant.rs | 14 +- core/cli/src/lib.rs | 93 +- core/finality-grandpa/Cargo.toml | 5 - core/finality-grandpa/src/lib.rs | 9 +- .../src/service_integration.rs | 49 -- core/rpc-servers/Cargo.toml | 8 +- core/rpc/Cargo.toml | 8 +- core/service/src/builder.rs | 809 ++++++++++++++++++ core/service/src/chain_ops.rs | 165 ++-- core/service/src/chain_spec.rs | 2 +- core/service/src/components.rs | 808 ----------------- core/service/src/lib.rs | 595 +++++-------- core/service/test/src/lib.rs | 240 +++--- node-template/src/cli.rs | 31 +- node-template/src/main.rs | 1 + node-template/src/service.rs | 413 ++++----- node/cli/Cargo.toml | 2 +- node/cli/src/chain_spec.rs | 8 +- node/cli/src/lib.rs | 39 +- node/cli/src/service.rs | 654 +++++++------- node/rpc-client/Cargo.toml | 2 +- node/rpc/Cargo.toml | 8 +- .../transaction-factory/src/complex_mode.rs | 25 +- test-utils/transaction-factory/src/lib.rs | 66 +- .../transaction-factory/src/simple_modes.rs | 25 +- 26 files changed, 1947 insertions(+), 2250 deletions(-) delete mode 100644 core/finality-grandpa/src/service_integration.rs create mode 100644 core/service/src/builder.rs delete mode 100644 core/service/src/components.rs diff --git a/Cargo.lock b/Cargo.lock index 6a2260b3b4..7bddc07d24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1344,6 +1344,16 @@ dependencies = [ "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "idna" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "impl-codec" version = "0.4.0" @@ -1421,24 +1431,25 @@ dependencies = [ [[package]] name = "jsonrpc-client-transports" -version = "13.0.0" +version = "13.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "websocket 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-core" -version = "13.0.0" +version = "13.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1450,15 +1461,15 @@ dependencies = [ [[package]] name = "jsonrpc-core-client" -version = "13.0.0" +version = "13.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-client-transports 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-client-transports 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-derive" -version = "13.0.0" +version = "13.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1469,12 +1480,12 @@ dependencies = [ [[package]] name = "jsonrpc-http-server" -version = "13.0.0" +version = "13.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1483,10 +1494,10 @@ dependencies = [ [[package]] name = "jsonrpc-pubsub" -version = "13.0.0" +version = "13.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1494,12 +1505,12 @@ dependencies = [ [[package]] name = "jsonrpc-server-utils" -version = "13.0.0" +version = "13.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1510,15 +1521,15 @@ dependencies = [ [[package]] name = "jsonrpc-ws-server" -version = "13.0.0" +version = "13.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "ws 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ws 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2298,7 +2309,7 @@ dependencies = [ "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "node-executor 2.0.0", "node-primitives 2.0.0", @@ -2388,10 +2399,10 @@ name = "node-rpc" version = "2.0.0" dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", "node-runtime 2.0.0", @@ -2412,7 +2423,7 @@ dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", "substrate-rpc 2.0.0", @@ -2934,6 +2945,11 @@ name = "percent-encoding" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "pin-utils" version = "0.1.0-alpha.4" @@ -4769,7 +4785,6 @@ dependencies = [ "substrate-keystore 2.0.0", "substrate-network 2.0.0", "substrate-primitives 2.0.0", - "substrate-service 2.0.0", "substrate-telemetry 2.0.0", "substrate-test-runtime-client 2.0.0", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4975,10 +4990,10 @@ dependencies = [ "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5004,10 +5019,10 @@ dependencies = [ name = "substrate-rpc-servers" version = "2.0.0" dependencies = [ - "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-http-server 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-ws-server 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-http-server 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-ws-server 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -5746,7 +5761,7 @@ name = "twox-hash" version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5845,6 +5860,16 @@ dependencies = [ "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "url" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "utf8-ranges" version = "1.0.3" @@ -6157,7 +6182,7 @@ dependencies = [ [[package]] name = "ws" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6169,7 +6194,7 @@ dependencies = [ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6389,6 +6414,7 @@ dependencies = [ "checksum hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)" = "7cb44cbce9d8ee4fb36e4c0ad7b794ac44ebaad924b9c8291a63215bb44c2c8f" "checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" "checksum impl-codec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "78c441b3d2b5e24b407161e76d482b7bbd29b5da357707839ac40d95152f031f" "checksum impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5158079de9d4158e0ce1de3ae0bd7be03904efc40b3d7dd8b8c301cbf6b52b56" "checksum impl-serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d26be4b97d738552ea423f76c4f681012ff06c3fa36fa968656b3679f60b4a1" @@ -6400,14 +6426,14 @@ dependencies = [ "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum js-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)" = "da3ea71161651a4cd97d999b2da139109c537b15ab33abc8ae4ead38deac8a03" -"checksum jsonrpc-client-transports 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0bb6fd4acf48d1f17eb7b0e27ab7043c16f063ad0aa7020ec92a431648286c2f" -"checksum jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34d379861584fe4e3678f6ae9ee60b41726df2989578c1dc0f90190dfc92dbe0" -"checksum jsonrpc-core-client 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6b0a3dc76953d88cdb47f5fe4ae21abcabc8d7edf4951ebce42db5c722d6698" -"checksum jsonrpc-derive 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9e2d4475549bc0126690788ed5107573c8917f97db5298f0043fb73d46fc498" -"checksum jsonrpc-http-server 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad55e8dd67c2c5b16436738b0baf319a6b353feba7401dbc1508a0bd8bd451f" -"checksum jsonrpc-pubsub 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "583f5930821dbc043236fe5d672d496ead7ff83d21351146598386c66fe8722a" -"checksum jsonrpc-server-utils 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "04f18ca34046c249751fe90428e77e9570beaa03b33a108e74418a586063d07d" -"checksum jsonrpc-ws-server 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aee1265de937bd53ad0fc95ff5817314922ce009fa99a04a09fdf449b140ddf6" +"checksum jsonrpc-client-transports 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "39577db48b004cffb4c5b8e5c9b993c177c52599ecbee88711e815acf65144db" +"checksum jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd42951eb35079520ee29b7efbac654d85821b397ef88c8151600ef7e2d00217" +"checksum jsonrpc-core-client 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f047c10738edee7c3c6acf5241a0ce33df32ef9230c1a7fb03e4a77ee72c992f" +"checksum jsonrpc-derive 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29f9149f785deaae92a4c834a9a1a83a4313b8cfedccf15362cd4cf039a64501" +"checksum jsonrpc-http-server 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4edd28922653d79e4f6c0f5d0a1034a4edbc5f9cf6cad8ec85e2a685713e3708" +"checksum jsonrpc-pubsub 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2c08b444cc0ed70263798834343d0ac875e664257df8079160f23ac1ea79446" +"checksum jsonrpc-server-utils 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44561bfdd31401bad790527f1e951dde144f2341ddc3e1b859d32945e1a34eff" +"checksum jsonrpc-ws-server 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d230ff76a8e4a3fb068aab6ba23d0c4e7d6e3b41bca524daa33988b04b065265" "checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" "checksum keccak-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3468207deea1359a0e921591ae9b4c928733d94eb9d6a2eeda994cfd59f42cf8" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" @@ -6512,6 +6538,7 @@ dependencies = [ "checksum pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" +"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" "checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" "checksum pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c1d2cfa5a714db3b5f24f0915e74fcdf91d09d496ba61329705dda7774d2af" "checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" @@ -6666,6 +6693,7 @@ dependencies = [ "checksum unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2c64cdf40b4a9645534a943668681bcb219faf51874d4b65d2e0abda1b10a2ab" "checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" +"checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" "checksum utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d50aa7650df78abf942826607c62468ce18d9019673d4a2ebe1865dbb96ffde" "checksum vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "33dd455d0f96e90a75803cfeb7f948768c08d70a6de9a8d2362461935698bf95" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" @@ -6700,7 +6728,7 @@ dependencies = [ "checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" -"checksum ws 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ec91ea61b83ce033c43c06c52ddc7532f465c0153281610d44c58b74083aee1a" +"checksum ws 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a6f5bb86663ff4d1639408410f50bf6050367a8525d644d49a6894cd618a631" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ee1585dc1484373cbc1cee7aafda26634665cf449436fd6e24bfd1fad230538" "checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" diff --git a/core/cli/src/informant.rs b/core/cli/src/informant.rs index b5a2f03d79..52a5f67c26 100644 --- a/core/cli/src/informant.rs +++ b/core/cli/src/informant.rs @@ -21,22 +21,12 @@ use futures::{Future, Stream}; use futures03::{StreamExt as _, TryStreamExt as _}; use log::{info, warn}; use sr_primitives::{generic::BlockId, traits::Header}; -use service::{Service, Components}; -use tokio::runtime::TaskExecutor; +use service::AbstractService; mod display; -/// Spawn informant on the event loop -#[deprecated(note = "Please use informant::build instead, and then create the task manually")] -pub fn start(service: &Service, exit: ::exit_future::Exit, handle: TaskExecutor) where - C: Components, -{ - handle.spawn(exit.until(build(service)).map(|_| ())); -} - /// Creates an informant in the form of a `Future` that must be polled regularly. -pub fn build(service: &Service) -> impl Future -where C: Components { +pub fn build(service: &impl AbstractService) -> impl Future { let client = service.client(); let mut display = display::InformantDisplay::new(); diff --git a/core/cli/src/lib.rs b/core/cli/src/lib.rs index ef52904131..6e9955ca1a 100644 --- a/core/cli/src/lib.rs +++ b/core/cli/src/lib.rs @@ -29,8 +29,8 @@ pub mod informant; use client::ExecutionStrategies; use service::{ config::Configuration, - ServiceFactory, FactoryFullConfiguration, RuntimeGenesis, - FactoryGenesis, PruningMode, ChainSpec, + ServiceBuilderExport, ServiceBuilderImport, ServiceBuilderRevert, + RuntimeGenesis, PruningMode, ChainSpec, }; use network::{ self, multiaddr::Protocol, @@ -317,13 +317,17 @@ pub struct ParseAndPrepareExport<'a> { impl<'a> ParseAndPrepareExport<'a> { /// Runs the command and exports from the chain. - pub fn run( + pub fn run_with_builder( self, + builder: F, spec_factory: S, exit: E, ) -> error::Result<()> - where S: FnOnce(&str) -> Result>>, String>, - F: ServiceFactory, + where S: FnOnce(&str) -> Result>, String>, + F: FnOnce(Configuration) -> Result, + B: ServiceBuilderExport, + C: Default, + G: RuntimeGenesis, E: IntoExit { let config = create_config_with_db_path(spec_factory, &self.params.shared_params, self.version)?; @@ -338,9 +342,8 @@ impl<'a> ParseAndPrepareExport<'a> { None => Box::new(stdout()), }; - service::chain_ops::export_blocks::( - config, exit.into_exit(), file, from.into(), to.map(Into::into), json - ).map_err(Into::into) + builder(config)?.export_blocks(exit.into_exit(), file, from.into(), to.map(Into::into), json)?; + Ok(()) } } @@ -352,13 +355,17 @@ pub struct ParseAndPrepareImport<'a> { impl<'a> ParseAndPrepareImport<'a> { /// Runs the command and imports to the chain. - pub fn run( + pub fn run_with_builder( self, + builder: F, spec_factory: S, exit: E, ) -> error::Result<()> - where S: FnOnce(&str) -> Result>>, String>, - F: ServiceFactory, + where S: FnOnce(&str) -> Result>, String>, + F: FnOnce(Configuration) -> Result, + B: ServiceBuilderImport, + C: Default, + G: RuntimeGenesis, E: IntoExit { let mut config = create_config_with_db_path(spec_factory, &self.params.shared_params, self.version)?; @@ -377,7 +384,7 @@ impl<'a> ParseAndPrepareImport<'a> { }, }; - let fut = service::chain_ops::import_blocks::(config, exit.into_exit(), file)?; + let fut = builder(config)?.import_blocks(exit.into_exit(), file)?; tokio::run(fut); Ok(()) } @@ -440,67 +447,23 @@ pub struct ParseAndPrepareRevert<'a> { impl<'a> ParseAndPrepareRevert<'a> { /// Runs the command and reverts the chain. - pub fn run( + pub fn run_with_builder( self, + builder: F, spec_factory: S ) -> error::Result<()> - where S: FnOnce(&str) -> Result>>, String>, - F: ServiceFactory { + where S: FnOnce(&str) -> Result>, String>, + F: FnOnce(Configuration) -> Result, + B: ServiceBuilderRevert, + C: Default, + G: RuntimeGenesis { let config = create_config_with_db_path(spec_factory, &self.params.shared_params, self.version)?; let blocks = self.params.num; - Ok(service::chain_ops::revert_chain::(config, blocks.into())?) + builder(config)?.revert_chain(blocks.into())?; + Ok(()) } } -/// Parse command line interface arguments and executes the desired command. -/// -/// # Return value -/// -/// A result that indicates if any error occurred. -/// If no error occurred and a custom subcommand was found, the subcommand is returned. -/// The user needs to handle this subcommand on its own. -/// -/// # Remarks -/// -/// `CC` is a custom subcommand. This needs to be an `enum`! If no custom subcommand is required, -/// `NoCustom` can be used as type here. -/// `RP` are custom parameters for the run command. This needs to be a `struct`! The custom -/// parameters are visible to the user as if they were normal run command parameters. If no custom -/// parameters are required, `NoCustom` can be used as type here. -#[deprecated( - note = "Use parse_and_prepare instead; see the source code of parse_and_execute for how to transition" -)] -pub fn parse_and_execute<'a, F, CC, RP, S, RS, E, I, T>( - spec_factory: S, - version: &VersionInfo, - impl_name: &'static str, - args: I, - exit: E, - run_service: RS, -) -> error::Result> -where - F: ServiceFactory, - S: FnOnce(&str) -> Result>>, String>, - CC: StructOpt + Clone + GetLogFilter, - RP: StructOpt + Clone + AugmentClap, - E: IntoExit, - RS: FnOnce(E, RunCmd, RP, FactoryFullConfiguration) -> Result<(), String>, - I: IntoIterator, - T: Into + Clone, -{ - match parse_and_prepare::(version, impl_name, args) { - ParseAndPrepare::Run(cmd) => cmd.run(spec_factory, exit, run_service), - ParseAndPrepare::BuildSpec(cmd) => cmd.run(spec_factory), - ParseAndPrepare::ExportBlocks(cmd) => cmd.run::(spec_factory, exit), - ParseAndPrepare::ImportBlocks(cmd) => cmd.run::(spec_factory, exit), - ParseAndPrepare::PurgeChain(cmd) => cmd.run(spec_factory), - ParseAndPrepare::RevertChain(cmd) => cmd.run::(spec_factory), - ParseAndPrepare::CustomCommand(cmd) => return Ok(Some(cmd)) - }?; - - Ok(None) -} - /// Create a `NodeKeyConfig` from the given `NodeKeyParams` in the context /// of an optional network config storage directory. fn node_key_config

(params: NodeKeyParams, net_config_dir: &Option

) diff --git a/core/finality-grandpa/Cargo.toml b/core/finality-grandpa/Cargo.toml index 22237c5a0b..393ee45db5 100644 --- a/core/finality-grandpa/Cargo.toml +++ b/core/finality-grandpa/Cargo.toml @@ -23,7 +23,6 @@ serde_json = "1.0" client = { package = "substrate-client", path = "../client" } inherents = { package = "substrate-inherents", path = "../../core/inherents" } network = { package = "substrate-network", path = "../network" } -service = { package = "substrate-service", path = "../service", optional = true } srml-finality-tracker = { path = "../../srml/finality-tracker" } fg_primitives = { package = "substrate-finality-grandpa-primitives", path = "primitives" } grandpa = { package = "finality-grandpa", version = "0.9.0", features = ["derive-codec"] } @@ -37,7 +36,3 @@ babe_primitives = { package = "substrate-consensus-babe-primitives", path = "../ env_logger = "0.6" tokio = "0.1.17" tempfile = "3.1" - -[features] -default = ["service-integration"] -service-integration = ["service"] diff --git a/core/finality-grandpa/src/lib.rs b/core/finality-grandpa/src/lib.rs index b79b120e35..d6f4d76847 100644 --- a/core/finality-grandpa/src/lib.rs +++ b/core/finality-grandpa/src/lib.rs @@ -93,10 +93,6 @@ mod light_import; mod observer; mod until_imported; -#[cfg(feature="service-integration")] -mod service_integration; -#[cfg(feature="service-integration")] -pub use service_integration::{LinkHalfForService, BlockImportForService, BlockImportForLightService}; pub use communication::Network; pub use finality_proof::FinalityProofProvider; pub use light_import::light_block_import; @@ -107,7 +103,6 @@ use environment::{Environment, VoterSetState}; use import::GrandpaBlockImport; use until_imported::UntilGlobalMessageBlocksImported; use communication::NetworkBridge; -use service::TelemetryOnConnect; use fg_primitives::{AuthoritySignature, SetId, AuthorityWeight}; // Re-export these two because it's just so damn convenient. @@ -484,7 +479,7 @@ pub struct GrandpaParams, N, RA, SC, X> { /// Handle to a future that will resolve on exit. pub on_exit: X, /// If supplied, can be used to hook on telemetry connection established events. - pub telemetry_on_connect: Option, + pub telemetry_on_connect: Option>, } /// Run a GRANDPA voter as a task. Provide configuration and a link to a @@ -531,7 +526,7 @@ pub fn run_grandpa_voter, N, RA, SC, X>( let telemetry_task = if let Some(telemetry_on_connect) = telemetry_on_connect { let authorities = persistent_data.authority_set.clone(); - let events = telemetry_on_connect.telemetry_connection_sinks + let events = telemetry_on_connect .for_each(move |_| { telemetry!(CONSENSUS_INFO; "afg.authority_set"; "authority_set_id" => ?authorities.set_id(), diff --git a/core/finality-grandpa/src/service_integration.rs b/core/finality-grandpa/src/service_integration.rs deleted file mode 100644 index 9f19b92041..0000000000 --- a/core/finality-grandpa/src/service_integration.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2018-2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -/// Integrate grandpa finality with substrate service - -use client; -use service::{FullBackend, FullExecutor, LightBackend, LightExecutor, ServiceFactory}; - -pub type BlockImportForService = crate::GrandpaBlockImport< - FullBackend, - FullExecutor, - ::Block, - ::RuntimeApi, - client::Client< - FullBackend, - FullExecutor, - ::Block, - ::RuntimeApi - >, - ::SelectChain, ->; - -pub type LinkHalfForService = crate::LinkHalf< - FullBackend, - FullExecutor, - ::Block, - ::RuntimeApi, - ::SelectChain ->; - -pub type BlockImportForLightService = crate::light_import::GrandpaLightBlockImport< - LightBackend, - LightExecutor, - ::Block, - ::RuntimeApi, ->; diff --git a/core/rpc-servers/Cargo.toml b/core/rpc-servers/Cargo.toml index 54a4b68eab..d4befd52e9 100644 --- a/core/rpc-servers/Cargo.toml +++ b/core/rpc-servers/Cargo.toml @@ -5,12 +5,12 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -jsonrpc-core = "13.0.0" -pubsub = { package = "jsonrpc-pubsub", version = "13.0.0" } +jsonrpc-core = "13.1.0" +pubsub = { package = "jsonrpc-pubsub", version = "13.1.0" } log = "0.4" serde = "1.0" sr-primitives = { path = "../sr-primitives" } [target.'cfg(not(target_os = "unknown"))'.dependencies] -http = { package = "jsonrpc-http-server", version = "13.0.0" } -ws = { package = "jsonrpc-ws-server", version = "13.0.0" } +http = { package = "jsonrpc-http-server", version = "13.1.0" } +ws = { package = "jsonrpc-ws-server", version = "13.1.0" } diff --git a/core/rpc/Cargo.toml b/core/rpc/Cargo.toml index 0a9cf108c9..f35408c7b3 100644 --- a/core/rpc/Cargo.toml +++ b/core/rpc/Cargo.toml @@ -8,10 +8,10 @@ edition = "2018" derive_more = "0.14.0" futures = "0.1" futures03 = { package = "futures-preview", version = "0.3.0-alpha.17", features = ["compat"] } -jsonrpc-core = "13.0.0" -jsonrpc-core-client = "13.0.0" -jsonrpc-pubsub = "13.0.0" -jsonrpc-derive = "13.0.0" +jsonrpc-core = "13.1.0" +jsonrpc-core-client = "13.1.0" +jsonrpc-pubsub = "13.1.0" +jsonrpc-derive = "13.1.0" log = "0.4" parking_lot = "0.9.0" codec = { package = "parity-scale-codec", version = "1.0.0" } diff --git a/core/service/src/builder.rs b/core/service/src/builder.rs new file mode 100644 index 0000000000..3b079e549d --- /dev/null +++ b/core/service/src/builder.rs @@ -0,0 +1,809 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use crate::{NewService, NetworkStatus, NetworkState, error::{self, Error}, DEFAULT_PROTOCOL_ID}; +use crate::{SpawnTaskHandle, start_rpc_servers, build_network_future, TransactionPoolAdapter}; +use crate::TaskExecutor; +use crate::config::Configuration; +use client::{BlockchainEvents, Client, runtime_api}; +use codec::{Decode, Encode, IoReader}; +use consensus_common::import_queue::ImportQueue; +use futures::{prelude::*, sync::mpsc}; +use futures03::{FutureExt as _, compat::Compat, StreamExt as _, TryStreamExt as _}; +use keystore::{Store as Keystore, KeyStorePtr}; +use log::{info, warn}; +use network::{FinalityProofProvider, OnDemand, NetworkService, NetworkStateInfo}; +use network::{config::BoxFinalityProofRequestBuilder, specialization::NetworkSpecialization}; +use parking_lot::{Mutex, RwLock}; +use primitives::{Blake2Hasher, H256, Hasher}; +use rpc::{self, system::SystemInfo}; +use sr_primitives::{BuildStorage, generic::BlockId}; +use sr_primitives::traits::{Block as BlockT, ProvideRuntimeApi, NumberFor, One, Zero, Header, SaturatedConversion}; +use substrate_executor::{NativeExecutor, NativeExecutionDispatch}; +use serde::{Serialize, de::DeserializeOwned}; +use std::{io::{Read, Write, Seek}, marker::PhantomData, sync::Arc, sync::atomic::AtomicBool}; +use sysinfo::{get_current_pid, ProcessExt, System, SystemExt}; +use tel::{telemetry, SUBSTRATE_INFO}; +use transaction_pool::txpool::{self, ChainApi, Pool as TransactionPool}; + +/// Aggregator for the components required to build a service. +/// +/// # Usage +/// +/// Call [`ServiceBuilder::new_full`] or [`ServiceBuilder::new_light`], then call the various +/// `with_` methods to add the required components that you built yourself: +/// +/// - [`with_select_chain`](ServiceBuilder::with_select_chain) +/// - [`with_import_queue`](ServiceBuilder::with_import_queue) +/// - [`with_network_protocol`](ServiceBuilder::with_network_protocol) +/// - [`with_finality_proof_provider`](ServiceBuilder::with_finality_proof_provider) +/// - [`with_transaction_pool`](ServiceBuilder::with_transaction_pool) +/// +/// After this is done, call [`build`](ServiceBuilder::build) to construct the service. +/// +/// The order in which the `with_*` methods are called doesn't matter, as the correct binding of +/// generics is done when you call `build`. +/// +pub struct ServiceBuilder { + config: Configuration, + client: Arc, + keystore: Arc>, + fetcher: Option, + select_chain: Option, + import_queue: TImpQu, + finality_proof_request_builder: Option, + finality_proof_provider: Option, + network_protocol: TNetP, + transaction_pool: Arc, + rpc_extensions: TRpc, + marker: PhantomData<(TBl, TRtApi)>, +} + +impl ServiceBuilder<(), (), TCfg, TGen, (), (), (), (), (), (), (), (), ()> +where TGen: Serialize + DeserializeOwned + BuildStorage { + /// Start the service builder with a configuration. + pub fn new_full, TRtApi, TExecDisp: NativeExecutionDispatch>( + config: Configuration + ) -> Result, + client::LocalCallExecutor, NativeExecutor>, + TBl, + TRtApi + >, + Arc>, + (), + (), + BoxFinalityProofRequestBuilder, + (), + (), + (), + () + >, Error> { + let keystore = Keystore::open(config.keystore_path.clone(), config.keystore_password.clone())?; + + let db_settings = client_db::DatabaseSettings { + cache_size: None, + state_cache_size: config.state_cache_size, + state_cache_child_ratio: + config.state_cache_child_ratio.map(|v| (v, 100)), + path: config.database_path.clone(), + pruning: config.pruning.clone(), + }; + + let executor = NativeExecutor::::new(config.default_heap_pages); + + let client = Arc::new(client_db::new_client( + db_settings, + executor, + &config.chain_spec, + config.execution_strategies.clone(), + Some(keystore.clone()), + )?); + + Ok(ServiceBuilder { + config, + client, + keystore, + fetcher: None, + select_chain: None, + import_queue: (), + finality_proof_request_builder: None, + finality_proof_provider: None, + network_protocol: (), + transaction_pool: Arc::new(()), + rpc_extensions: Default::default(), + marker: PhantomData, + }) + } + + /// Start the service builder with a configuration. + pub fn new_light, TRtApi, TExecDisp: NativeExecutionDispatch + 'static>( + config: Configuration + ) -> Result, network::OnDemand, Blake2Hasher>, + client::light::call_executor::RemoteOrLocalCallExecutor< + TBl, + client::light::backend::Backend< + client_db::light::LightStorage, + network::OnDemand, + Blake2Hasher + >, + client::light::call_executor::RemoteCallExecutor< + client::light::blockchain::Blockchain< + client_db::light::LightStorage, + network::OnDemand + >, + network::OnDemand, + >, + client::LocalCallExecutor< + client::light::backend::Backend< + client_db::light::LightStorage, + network::OnDemand, + Blake2Hasher + >, + NativeExecutor + > + >, + TBl, + TRtApi + >, + Arc>, + (), + (), + BoxFinalityProofRequestBuilder, + (), + (), + (), + () + >, Error> { + let keystore = Keystore::open(config.keystore_path.clone(), config.keystore_password.clone())?; + + let db_settings = client_db::DatabaseSettings { + cache_size: config.database_cache_size.map(|u| u as usize), + state_cache_size: config.state_cache_size, + state_cache_child_ratio: + config.state_cache_child_ratio.map(|v| (v, 100)), + path: config.database_path.clone(), + pruning: config.pruning.clone(), + }; + + let executor = NativeExecutor::::new(config.default_heap_pages); + + let db_storage = client_db::light::LightStorage::new(db_settings)?; + let light_blockchain = client::light::new_light_blockchain(db_storage); + let fetch_checker = Arc::new(client::light::new_fetch_checker(light_blockchain.clone(), executor.clone())); + let fetcher = Arc::new(network::OnDemand::new(fetch_checker)); + let client_backend = client::light::new_light_backend(light_blockchain, fetcher.clone()); + let client = client::light::new_light(client_backend, fetcher.clone(), &config.chain_spec, executor)?; + + Ok(ServiceBuilder { + config, + client: Arc::new(client), + keystore, + fetcher: Some(fetcher), + select_chain: None, + import_queue: (), + finality_proof_request_builder: None, + finality_proof_provider: None, + network_protocol: (), + transaction_pool: Arc::new(()), + rpc_extensions: Default::default(), + marker: PhantomData, + }) + } +} + +impl + ServiceBuilder { + + /// Returns a reference to the client that was stored in this builder. + pub fn client(&self) -> &Arc { + &self.client + } + + /// Returns a reference to the select-chain that was stored in this builder. + pub fn select_chain(&self) -> Option<&TSc> { + self.select_chain.as_ref() + } + + /// Defines which head-of-chain strategy to use. + pub fn with_opt_select_chain( + mut self, + select_chain_builder: impl FnOnce(&mut Configuration, Arc) -> Result, Error> + ) -> Result, Error> { + let select_chain = select_chain_builder(&mut self.config, self.client.clone())?; + + Ok(ServiceBuilder { + config: self.config, + client: self.client, + keystore: self.keystore, + fetcher: self.fetcher, + select_chain, + import_queue: self.import_queue, + finality_proof_request_builder: self.finality_proof_request_builder, + finality_proof_provider: self.finality_proof_provider, + network_protocol: self.network_protocol, + transaction_pool: self.transaction_pool, + rpc_extensions: self.rpc_extensions, + marker: self.marker, + }) + } + + /// Defines which head-of-chain strategy to use. + pub fn with_select_chain( + self, + builder: impl FnOnce(&mut Configuration, Arc) -> Result + ) -> Result, Error> { + self.with_opt_select_chain(|cfg, cl| builder(cfg, cl).map(Option::Some)) + } + + /// Defines which import queue to use. + pub fn with_import_queue( + mut self, + builder: impl FnOnce(&mut Configuration, Arc, Option, Arc) + -> Result + ) -> Result, Error> + where TSc: Clone { + let import_queue = builder( + &mut self.config, + self.client.clone(), + self.select_chain.clone(), + self.transaction_pool.clone() + )?; + + Ok(ServiceBuilder { + config: self.config, + client: self.client, + keystore: self.keystore, + fetcher: self.fetcher, + select_chain: self.select_chain, + import_queue, + finality_proof_request_builder: self.finality_proof_request_builder, + finality_proof_provider: self.finality_proof_provider, + network_protocol: self.network_protocol, + transaction_pool: self.transaction_pool, + rpc_extensions: self.rpc_extensions, + marker: self.marker, + }) + } + + /// Defines which network specialization protocol to use. + pub fn with_network_protocol( + self, + network_protocol_builder: impl FnOnce(&Configuration) -> Result + ) -> Result, Error> { + let network_protocol = network_protocol_builder(&self.config)?; + + Ok(ServiceBuilder { + config: self.config, + client: self.client, + keystore: self.keystore, + fetcher: self.fetcher, + select_chain: self.select_chain, + import_queue: self.import_queue, + finality_proof_request_builder: self.finality_proof_request_builder, + finality_proof_provider: self.finality_proof_provider, + network_protocol, + transaction_pool: self.transaction_pool, + rpc_extensions: self.rpc_extensions, + marker: self.marker, + }) + } + + /// Defines which strategy to use for providing finality proofs. + pub fn with_opt_finality_proof_provider( + self, + builder: impl FnOnce(Arc) -> Result>>, Error> + ) -> Result>, + TNetP, + TExPool, + TRpc + >, Error> { + let finality_proof_provider = builder(self.client.clone())?; + + Ok(ServiceBuilder { + config: self.config, + client: self.client, + keystore: self.keystore, + fetcher: self.fetcher, + select_chain: self.select_chain, + import_queue: self.import_queue, + finality_proof_request_builder: self.finality_proof_request_builder, + finality_proof_provider, + network_protocol: self.network_protocol, + transaction_pool: self.transaction_pool, + rpc_extensions: self.rpc_extensions, + marker: self.marker, + }) + } + + /// Defines which strategy to use for providing finality proofs. + pub fn with_finality_proof_provider( + self, + build: impl FnOnce(Arc) -> Result>, Error> + ) -> Result>, + TNetP, + TExPool, + TRpc + >, Error> { + self.with_opt_finality_proof_provider(|client| build(client).map(Option::Some)) + } + + /// Defines which import queue to use. + pub fn with_import_queue_and_opt_fprb( + mut self, + builder: impl FnOnce(&mut Configuration, Arc, Option, Arc) + -> Result<(UImpQu, Option), Error> + ) -> Result, Error> + where TSc: Clone { + let (import_queue, fprb) = builder( + &mut self.config, + self.client.clone(), + self.select_chain.clone(), + self.transaction_pool.clone() + )?; + + Ok(ServiceBuilder { + config: self.config, + client: self.client, + keystore: self.keystore, + fetcher: self.fetcher, + select_chain: self.select_chain, + import_queue, + finality_proof_request_builder: fprb, + finality_proof_provider: self.finality_proof_provider, + network_protocol: self.network_protocol, + transaction_pool: self.transaction_pool, + rpc_extensions: self.rpc_extensions, + marker: self.marker, + }) + } + + /// Defines which import queue to use. + pub fn with_import_queue_and_fprb( + self, + builder: impl FnOnce(&mut Configuration, Arc, Option, Arc) + -> Result<(UImpQu, UFprb), Error> + ) -> Result, Error> + where TSc: Clone { + self.with_import_queue_and_opt_fprb(|cfg, cl, sc, tx| builder(cfg, cl, sc, tx).map(|(q, f)| (q, Some(f)))) + } + + /// Defines which transaction pool to use. + pub fn with_transaction_pool( + self, + transaction_pool_builder: impl FnOnce(transaction_pool::txpool::Options, Arc) -> Result + ) -> Result, Error> { + let transaction_pool = transaction_pool_builder(self.config.transaction_pool.clone(), self.client.clone())?; + + Ok(ServiceBuilder { + config: self.config, + client: self.client, + keystore: self.keystore, + fetcher: self.fetcher, + select_chain: self.select_chain, + import_queue: self.import_queue, + finality_proof_request_builder: self.finality_proof_request_builder, + finality_proof_provider: self.finality_proof_provider, + network_protocol: self.network_protocol, + transaction_pool: Arc::new(transaction_pool), + rpc_extensions: self.rpc_extensions, + marker: self.marker, + }) + } + + /// Defines the RPC extensions to use. + pub fn with_rpc_extensions( + self, + rpc_ext_builder: impl FnOnce(Arc, Arc) -> URpc + ) -> Result, Error> { + let rpc_extensions = rpc_ext_builder(self.client.clone(), self.transaction_pool.clone()); + + Ok(ServiceBuilder { + config: self.config, + client: self.client, + keystore: self.keystore, + fetcher: self.fetcher, + select_chain: self.select_chain, + import_queue: self.import_queue, + finality_proof_request_builder: self.finality_proof_request_builder, + finality_proof_provider: self.finality_proof_provider, + network_protocol: self.network_protocol, + transaction_pool: self.transaction_pool, + rpc_extensions, + marker: self.marker, + }) + } +} + +/// Implemented on `ServiceBuilder`. Allows importing blocks once you have given all the required +/// components to the builder. +pub trait ServiceBuilderImport { + /// Starts the process of importing blocks. + fn import_blocks( + self, + exit: impl Future + Send + 'static, + input: impl Read + Seek, + ) -> Result + Send>, Error>; +} + +/// Implemented on `ServiceBuilder`. Allows exporting blocks once you have given all the required +/// components to the builder. +pub trait ServiceBuilderExport { + /// Type of block of the builder. + type Block: BlockT; + + /// Performs the blocks export. + fn export_blocks( + &self, + exit: impl Future + Send + 'static, + output: impl Write, + from: NumberFor, + to: Option>, + json: bool + ) -> Result<(), Error>; +} + +/// Implemented on `ServiceBuilder`. Allows reverting the chain once you have given all the +/// required components to the builder. +pub trait ServiceBuilderRevert { + /// Type of block of the builder. + type Block: BlockT; + + /// Performs a revert of `blocks` bocks. + fn revert_chain( + &self, + blocks: NumberFor + ) -> Result<(), Error>; +} + +impl + ServiceBuilderImport for ServiceBuilder, + TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc> +where + TBl: BlockT::Out>, + TBackend: 'static + client::backend::Backend + Send, + TExec: 'static + client::CallExecutor + Send + Sync + Clone, + TImpQu: 'static + ImportQueue, + TRtApi: 'static + Send + Sync, +{ + fn import_blocks( + self, + exit: impl Future + Send + 'static, + input: impl Read + Seek, + ) -> Result + Send>, Error> { + let client = self.client; + let mut queue = self.import_queue; + import_blocks!(TBl, client, queue, exit, input) + .map(|f| Box::new(f) as Box<_>) + } +} + +impl + ServiceBuilderExport for ServiceBuilder, + TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc> +where + TBl: BlockT::Out>, + TBackend: 'static + client::backend::Backend + Send, + TExec: 'static + client::CallExecutor + Send + Sync + Clone +{ + type Block = TBl; + + fn export_blocks( + &self, + exit: impl Future + Send + 'static, + mut output: impl Write, + from: NumberFor, + to: Option>, + json: bool + ) -> Result<(), Error> { + let client = &self.client; + export_blocks!(client, exit, output, from, to, json) + } +} + +impl + ServiceBuilderRevert for ServiceBuilder, + TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc> +where + TBl: BlockT::Out>, + TBackend: 'static + client::backend::Backend + Send, + TExec: 'static + client::CallExecutor + Send + Sync + Clone +{ + type Block = TBl; + + fn revert_chain( + &self, + blocks: NumberFor + ) -> Result<(), Error> { + let client = &self.client; + revert_chain!(client, blocks) + } +} + +impl +ServiceBuilder< + TBl, + TRtApi, + TCfg, + TGen, + Client, + Arc>, + TSc, + TImpQu, + BoxFinalityProofRequestBuilder, + Arc>, + TNetP, + TransactionPool, + TRpc +> where + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: + runtime_api::Metadata + + offchain::OffchainWorkerApi + + runtime_api::TaggedTransactionQueue + + session::SessionKeys, + TBl: BlockT::Out>, + TRtApi: 'static + Send + Sync, + TCfg: Default, + TGen: Serialize + DeserializeOwned + BuildStorage, + TBackend: 'static + client::backend::Backend + Send, + TExec: 'static + client::CallExecutor + Send + Sync + Clone, + TSc: Clone, + TImpQu: 'static + ImportQueue, + TNetP: NetworkSpecialization, + TExPoolApi: 'static + ChainApi::Hash>, + TRpc: rpc::RpcExtension + Clone, +{ + /// Builds the service. + pub fn build(self) -> Result, + TBl, + Client, + TSc, + NetworkStatus, + NetworkService::Hash>, + TransactionPool, + offchain::OffchainWorkers< + Client, + TBackend::OffchainStorage, + TBl + >, + >, Error> { + let mut config = self.config; + session::generate_initial_session_keys( + self.client.clone(), + config.dev_key_seed.clone().map(|s| vec![s]).unwrap_or_default() + )?; + let ( + client, + fetcher, + keystore, + select_chain, + import_queue, + finality_proof_request_builder, + finality_proof_provider, + network_protocol, + transaction_pool, + rpc_extensions + ) = ( + self.client, + self.fetcher, + self.keystore, + self.select_chain, + self.import_queue, + self.finality_proof_request_builder, + self.finality_proof_provider, + self.network_protocol, + self.transaction_pool, + self.rpc_extensions + ); + + new_impl!( + TBl, + config, + move |_| -> Result<_, Error> { + Ok(( + client, + fetcher, + keystore, + select_chain, + import_queue, + finality_proof_request_builder, + finality_proof_provider, + network_protocol, + transaction_pool, + rpc_extensions + )) + }, + |h, c, tx| maintain_transaction_pool(h, c, tx), + |n, o, p, ns, v| offchain_workers(n, o, p, ns, v), + |c, ssb, si, te, tp, ext, ks| start_rpc(c, ssb, si, te, tp, ext, ks), + ) + } +} + +pub(crate) fn start_rpc( + client: Arc>, + system_send_back: futures03::channel::mpsc::UnboundedSender>, + rpc_system_info: SystemInfo, + task_executor: TaskExecutor, + transaction_pool: Arc>, + rpc_extensions: impl rpc::RpcExtension, + keystore: KeyStorePtr, +) -> rpc_servers::RpcHandler +where + Block: BlockT::Out>, + Backend: client::backend::Backend + 'static, + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: + runtime_api::Metadata + session::SessionKeys, + Api: Send + Sync + 'static, + Executor: client::CallExecutor + Send + Sync + Clone + 'static, + PoolApi: txpool::ChainApi + 'static { + use rpc::{chain, state, author, system}; + let subscriptions = rpc::Subscriptions::new(task_executor.clone()); + let chain = chain::Chain::new(client.clone(), subscriptions.clone()); + let state = state::State::new(client.clone(), subscriptions.clone()); + let author = rpc::author::Author::new( + client, + transaction_pool, + subscriptions, + keystore, + ); + let system = system::System::new(rpc_system_info, system_send_back); + + rpc_servers::rpc_handler(( + state::StateApi::to_delegate(state), + chain::ChainApi::to_delegate(chain), + author::AuthorApi::to_delegate(author), + system::SystemApi::to_delegate(system), + rpc_extensions, + )) +} + +pub(crate) fn maintain_transaction_pool( + id: &BlockId, + client: &Client, + transaction_pool: &TransactionPool, +) -> error::Result<()> where + Block: BlockT::Out>, + Backend: client::backend::Backend, + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: runtime_api::TaggedTransactionQueue, + Executor: client::CallExecutor, + PoolApi: txpool::ChainApi, +{ + // Avoid calling into runtime if there is nothing to prune from the pool anyway. + if transaction_pool.status().is_empty() { + return Ok(()) + } + + if let Some(block) = client.block(id)? { + let parent_id = BlockId::hash(*block.block.header().parent_hash()); + let extrinsics = block.block.extrinsics(); + transaction_pool.prune(id, &parent_id, extrinsics).map_err(|e| format!("{:?}", e))?; + } + + Ok(()) +} + +pub(crate) fn offchain_workers( + number: &NumberFor, + offchain: &offchain::OffchainWorkers< + Client, + >::OffchainStorage, + Block + >, + pool: &Arc>, + network_state: &Arc, + is_validator: bool, +) -> error::Result + Send>> +where + Block: BlockT::Out>, + Backend: client::backend::Backend + 'static, + Api: 'static, + >::OffchainStorage: 'static, + Client: ProvideRuntimeApi + Send + Sync, + as ProvideRuntimeApi>::Api: offchain::OffchainWorkerApi, + Executor: client::CallExecutor + 'static, + PoolApi: txpool::ChainApi + 'static, +{ + let future = offchain.on_block_imported(number, pool, network_state.clone(), is_validator) + .map(|()| Ok(())); + Ok(Box::new(Compat::new(future))) +} + +#[cfg(test)] +mod tests { + use super::*; + use consensus_common::{BlockOrigin, SelectChain}; + use substrate_test_runtime_client::{prelude::*, runtime::Transfer}; + + #[test] + fn should_remove_transactions_from_the_pool() { + let (client, longest_chain) = TestClientBuilder::new().build_with_longest_chain(); + let client = Arc::new(client); + let pool = TransactionPool::new(Default::default(), ::transaction_pool::ChainApi::new(client.clone())); + let transaction = Transfer { + amount: 5, + nonce: 0, + from: AccountKeyring::Alice.into(), + to: Default::default(), + }.into_signed_tx(); + let best = longest_chain.best_chain().unwrap(); + + // store the transaction in the pool + pool.submit_one(&BlockId::hash(best.hash()), transaction.clone()).unwrap(); + + // import the block + let mut builder = client.new_block(Default::default()).unwrap(); + builder.push(transaction.clone()).unwrap(); + let block = builder.bake().unwrap(); + let id = BlockId::hash(block.header().hash()); + client.import(BlockOrigin::Own, block).unwrap(); + + // fire notification - this should clean up the queue + assert_eq!(pool.status().ready, 1); + maintain_transaction_pool( + &id, + &client, + &pool, + ).unwrap(); + + // then + assert_eq!(pool.status().ready, 0); + assert_eq!(pool.status().future, 0); + } +} diff --git a/core/service/src/chain_ops.rs b/core/service/src/chain_ops.rs index c801b81186..3a3677798b 100644 --- a/core/service/src/chain_ops.rs +++ b/core/service/src/chain_ops.rs @@ -16,44 +16,19 @@ //! Chain utilities. -use std::{self, io::{Read, Write, Seek}}; -use futures::prelude::*; -use futures03::TryFutureExt as _; -use log::{info, warn}; - -use sr_primitives::generic::{SignedBlock, BlockId}; -use sr_primitives::traits::{SaturatedConversion, Zero, One, Block, Header, NumberFor}; -use consensus_common::import_queue::{ImportQueue, IncomingBlock, Link, BlockImportError, BlockImportResult}; -use network::message; - -use consensus_common::BlockOrigin; -use crate::components::{self, Components, ServiceFactory, FactoryFullConfiguration, FactoryBlockNumber, RuntimeGenesis}; -use crate::new_client; -use codec::{Decode, Encode, IoReader}; +use crate::RuntimeGenesis; use crate::error; use crate::chain_spec::ChainSpec; -/// Export a range of blocks to a binary stream. -pub fn export_blocks( - config: FactoryFullConfiguration, - exit: E, - mut output: W, - from: FactoryBlockNumber, - to: Option>, - json: bool -) -> error::Result<()> - where - F: ServiceFactory, - E: Future + Send + 'static, - W: Write, -{ - let client = new_client::(&config)?; - let mut block = from; +#[macro_export] +macro_rules! export_blocks { +($client:ident, $exit:ident, $output:ident, $from:ident, $to:ident, $json:ident) => {{ + let mut block = $from; - let last = match to { + let last = match $to { Some(v) if v.is_zero() => One::one(), Some(v) => v, - None => client.info().chain.best_number, + None => $client.info().chain.best_number, }; if last < block { @@ -62,28 +37,28 @@ pub fn export_blocks( let (exit_send, exit_recv) = std::sync::mpsc::channel(); ::std::thread::spawn(move || { - let _ = exit.wait(); + let _ = $exit.wait(); let _ = exit_send.send(()); }); info!("Exporting blocks from #{} to #{}", block, last); - if !json { + if !$json { let last_: u64 = last.saturated_into::(); let block_: u64 = block.saturated_into::(); let len: u64 = last_ - block_ + 1; - output.write(&len.encode())?; + $output.write(&len.encode())?; } loop { if exit_recv.try_recv().is_ok() { break; } - match client.block(&BlockId::number(block))? { + match $client.block(&BlockId::number(block))? { Some(block) => { - if json { - serde_json::to_writer(&mut output, &block) + if $json { + serde_json::to_writer(&mut $output, &block) .map_err(|e| format!("Error writing JSON: {}", e))?; } else { - output.write(&block.encode())?; + $output.write(&block.encode())?; } }, None => break, @@ -97,66 +72,59 @@ pub fn export_blocks( block += One::one(); } Ok(()) +}} } -struct WaitLink { - imported_blocks: u64, - has_error: bool, -} +#[macro_export] +macro_rules! import_blocks { +($block:ty, $client:ident, $queue:ident, $exit:ident, $input:ident) => {{ + use consensus_common::import_queue::{IncomingBlock, Link, BlockImportError, BlockImportResult}; + use consensus_common::BlockOrigin; + use network::message; + use sr_primitives::generic::SignedBlock; + use sr_primitives::traits::Block; + use futures03::TryFutureExt as _; + + struct WaitLink { + imported_blocks: u64, + has_error: bool, + } -impl WaitLink { - fn new() -> WaitLink { - WaitLink { - imported_blocks: 0, - has_error: false, + impl WaitLink { + fn new() -> WaitLink { + WaitLink { + imported_blocks: 0, + has_error: false, + } } } -} -impl Link for WaitLink { - fn blocks_processed( - &mut self, - imported: usize, - _count: usize, - results: Vec<(Result>, BlockImportError>, B::Hash)> - ) { - self.imported_blocks += imported as u64; - - for result in results { - if let (Err(err), hash) = result { - warn!("There was an error importing block with hash {:?}: {:?}", hash, err); - self.has_error = true; - break; + impl Link for WaitLink { + fn blocks_processed( + &mut self, + imported: usize, + _count: usize, + results: Vec<(Result>, BlockImportError>, B::Hash)> + ) { + self.imported_blocks += imported as u64; + + for result in results { + if let (Err(err), hash) = result { + warn!("There was an error importing block with hash {:?}: {:?}", hash, err); + self.has_error = true; + break; + } } } } -} - -/// Returns a future that import blocks from a binary stream. -pub fn import_blocks( - mut config: FactoryFullConfiguration, - exit: E, - input: R -) -> error::Result> - where F: ServiceFactory, E: Future + Send + 'static, R: Read + Seek, -{ - let client = new_client::(&config)?; - // FIXME #1134 this shouldn't need a mutable config. - let select_chain = components::FullComponents::::build_select_chain(&mut config, client.clone())?; - let (mut queue, _) = components::FullComponents::::build_import_queue( - &mut config, - client.clone(), - select_chain, - None, - )?; let (exit_send, exit_recv) = std::sync::mpsc::channel(); ::std::thread::spawn(move || { - let _ = exit.wait(); + let _ = $exit.wait(); let _ = exit_send.send(()); }); - let mut io_reader_input = IoReader(input); + let mut io_reader_input = IoReader($input); let count: u64 = Decode::decode(&mut io_reader_input) .map_err(|e| format!("Error reading file: {}", e))?; info!("Importing {} blocks", count); @@ -165,11 +133,11 @@ pub fn import_blocks( if exit_recv.try_recv().is_ok() { break; } - match SignedBlock::::decode(&mut io_reader_input) { + match SignedBlock::<$block>::decode(&mut io_reader_input) { Ok(signed) => { let (header, extrinsics) = signed.block.deconstruct(); let hash = header.hash(); - let block = message::BlockData:: { + let block = message::BlockData::<$block> { hash, justification: signed.justification, header: Some(header), @@ -178,8 +146,8 @@ pub fn import_blocks( message_queue: None }; // import queue handles verification and importing it into the client - queue.import_blocks(BlockOrigin::File, vec![ - IncomingBlock:: { + $queue.import_blocks(BlockOrigin::File, vec![ + IncomingBlock::<$block> { hash: block.hash, header: block.header, body: block.body, @@ -208,7 +176,7 @@ pub fn import_blocks( let blocks_before = link.imported_blocks; let _ = futures03::future::poll_fn(|cx| { - queue.poll_actions(cx, &mut link); + $queue.poll_actions(cx, &mut link); std::task::Poll::Pending::> }).compat().poll(); if link.has_error { @@ -226,24 +194,20 @@ pub fn import_blocks( ); } if link.imported_blocks >= count { - info!("Imported {} blocks. Best: #{}", block_count, client.info().chain.best_number); + info!("Imported {} blocks. Best: #{}", block_count, $client.info().chain.best_number); Ok(Async::Ready(())) } else { Ok(Async::NotReady) } })) +}} } -/// Revert the chain. -pub fn revert_chain( - config: FactoryFullConfiguration, - blocks: FactoryBlockNumber -) -> error::Result<()> - where F: ServiceFactory, -{ - let client = new_client::(&config)?; - let reverted = client.revert(blocks)?; - let info = client.info().chain; +#[macro_export] +macro_rules! revert_chain { +($client:ident, $blocks:ident) => {{ + let reverted = $client.revert($blocks)?; + let info = $client.info().chain; if reverted.is_zero() { info!("There aren't any non-finalized blocks to revert."); @@ -251,6 +215,7 @@ pub fn revert_chain( info!("Reverted {} blocks. Best: #{} ({})", reverted, info.best_number, info.best_hash); } Ok(()) +}} } /// Build a chain spec json diff --git a/core/service/src/chain_spec.rs b/core/service/src/chain_spec.rs index 1683876c3f..8b35b0bac9 100644 --- a/core/service/src/chain_spec.rs +++ b/core/service/src/chain_spec.rs @@ -24,7 +24,7 @@ use serde::{Serialize, Deserialize}; use primitives::storage::{StorageKey, StorageData}; use sr_primitives::{BuildStorage, StorageOverlay, ChildrenStorageOverlay}; use serde_json as json; -use crate::components::RuntimeGenesis; +use crate::RuntimeGenesis; use network::Multiaddr; use tel::TelemetryEndpoints; diff --git a/core/service/src/components.rs b/core/service/src/components.rs deleted file mode 100644 index a9aa2129f2..0000000000 --- a/core/service/src/components.rs +++ /dev/null @@ -1,808 +0,0 @@ -// Copyright 2017-2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Substrate service components. - -use std::{sync::Arc, ops::Deref, ops::DerefMut}; -use serde::{Serialize, de::DeserializeOwned}; -use crate::chain_spec::ChainSpec; -use keystore::KeyStorePtr; -use client_db; -use client::{self, Client, runtime_api}; -use crate::{error, Service}; -use consensus_common::{import_queue::ImportQueue, SelectChain}; -use network::{ - self, OnDemand, FinalityProofProvider, NetworkStateInfo, config::BoxFinalityProofRequestBuilder -}; -use substrate_executor::{NativeExecutor, NativeExecutionDispatch}; -use transaction_pool::txpool::{self, Options as TransactionPoolOptions, Pool as TransactionPool}; -use sr_primitives::{ - BuildStorage, traits::{Block as BlockT, Header as HeaderT, ProvideRuntimeApi}, generic::BlockId -}; -use crate::config::Configuration; -use primitives::{Blake2Hasher, H256, traits::BareCryptoStorePtr}; -use rpc::{self, system::SystemInfo}; -use futures::{prelude::*, future::Executor}; -use futures03::{FutureExt as _, channel::mpsc, compat::Compat}; - -// Type aliases. -// These exist mainly to avoid typing `::Foo` all over the code. - -/// Network service type for `Components`. -pub type NetworkService = network::NetworkService< - ComponentBlock, - <::Factory as ServiceFactory>::NetworkProtocol, - ComponentExHash ->; - -/// Code executor type for a factory. -pub type CodeExecutor = NativeExecutor<::RuntimeDispatch>; - -/// Full client backend type for a factory. -pub type FullBackend = client_db::Backend<::Block>; - -/// Full client executor type for a factory. -pub type FullExecutor = client::LocalCallExecutor< - client_db::Backend<::Block>, - CodeExecutor, ->; - -/// Light client backend type for a factory. -pub type LightBackend = client::light::backend::Backend< - client_db::light::LightStorage<::Block>, - network::OnDemand<::Block>, - Blake2Hasher, ->; - -/// Light client executor type for a factory. -pub type LightExecutor = client::light::call_executor::RemoteOrLocalCallExecutor< - ::Block, - client::light::backend::Backend< - client_db::light::LightStorage<::Block>, - network::OnDemand<::Block>, - Blake2Hasher - >, - client::light::call_executor::RemoteCallExecutor< - client::light::blockchain::Blockchain< - client_db::light::LightStorage<::Block>, - network::OnDemand<::Block> - >, - network::OnDemand<::Block>, - >, - client::LocalCallExecutor< - client::light::backend::Backend< - client_db::light::LightStorage<::Block>, - network::OnDemand<::Block>, - Blake2Hasher - >, - CodeExecutor - > ->; - -/// Full client type for a factory. -pub type FullClient = Client, FullExecutor, ::Block, ::RuntimeApi>; - -/// Light client type for a factory. -pub type LightClient = Client, LightExecutor, ::Block, ::RuntimeApi>; - -/// `ChainSpec` specialization for a factory. -pub type FactoryChainSpec = ChainSpec<::Genesis>; - -/// `Genesis` specialization for a factory. -pub type FactoryGenesis = ::Genesis; - -/// `Block` type for a factory. -pub type FactoryBlock = ::Block; - -/// `Extrinsic` type for a factory. -pub type FactoryExtrinsic = <::Block as BlockT>::Extrinsic; - -/// `Number` type for a factory. -pub type FactoryBlockNumber = < as BlockT>::Header as HeaderT>::Number; - -/// Full `Configuration` type for a factory. -pub type FactoryFullConfiguration = Configuration<::Configuration, FactoryGenesis>; - -/// Client type for `Components`. -pub type ComponentClient = Client< - ::Backend, - ::Executor, - FactoryBlock<::Factory>, - ::RuntimeApi, ->; - -/// A offchain workers storage backend type. -pub type ComponentOffchainStorage = < - ::Backend as client::backend::Backend, Blake2Hasher> ->::OffchainStorage; - -/// Block type for `Components` -pub type ComponentBlock = <::Factory as ServiceFactory>::Block; - -/// Extrinsic hash type for `Components` -pub type ComponentExHash = <::TransactionPoolApi as txpool::ChainApi>::Hash; - -/// Extrinsic type. -pub type ComponentExtrinsic = as BlockT>::Extrinsic; - -/// Extrinsic pool API type for `Components`. -pub type PoolApi = ::TransactionPoolApi; - -/// A set of traits for the runtime genesis config. -pub trait RuntimeGenesis: Serialize + DeserializeOwned + BuildStorage {} -impl RuntimeGenesis for T {} - -/// A transport-agnostic handler of the RPC queries. -pub type RpcHandler = rpc_servers::RpcHandler; - -/// Something that can create and store initial session keys from given seeds. -pub trait InitialSessionKeys { - /// Generate the initial session keys for the given seeds and store them in - /// an internal keystore. - fn generate_initial_session_keys( - client: Arc>, - seeds: Vec, - ) -> error::Result<()>; -} - -impl InitialSessionKeys for C where - ComponentClient: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: session::SessionKeys>, -{ - fn generate_initial_session_keys( - client: Arc>, - seeds: Vec, - ) -> error::Result<()> { - session::generate_initial_session_keys(client, seeds).map_err(Into::into) - } -} - -/// Something that can start the RPC service. -pub trait StartRpc { - fn start_rpc( - client: Arc>, - system_send_back: mpsc::UnboundedSender>>, - system_info: SystemInfo, - task_executor: TaskExecutor, - transaction_pool: Arc>, - rpc_extensions: impl rpc::RpcExtension, - keystore: KeyStorePtr, - ) -> RpcHandler; -} - -impl StartRpc for C where - ComponentClient: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: - runtime_api::Metadata> + session::SessionKeys>, -{ - fn start_rpc( - client: Arc>, - system_send_back: mpsc::UnboundedSender>>, - rpc_system_info: SystemInfo, - task_executor: TaskExecutor, - transaction_pool: Arc>, - rpc_extensions: impl rpc::RpcExtension, - keystore: KeyStorePtr, - ) -> RpcHandler { - use rpc::{chain, state, author, system}; - let subscriptions = rpc::Subscriptions::new(task_executor.clone()); - let chain = chain::Chain::new(client.clone(), subscriptions.clone()); - let state = state::State::new(client.clone(), subscriptions.clone()); - let author = rpc::author::Author::new( - client, - transaction_pool, - subscriptions, - keystore, - ); - let system = system::System::new(rpc_system_info, system_send_back); - - rpc_servers::rpc_handler(( - state::StateApi::to_delegate(state), - chain::ChainApi::to_delegate(chain), - author::AuthorApi::to_delegate(author), - system::SystemApi::to_delegate(system), - rpc_extensions, - )) - } -} - -/// Something that can maintain transaction pool on every imported block. -pub trait MaintainTransactionPool { - fn maintain_transaction_pool( - id: &BlockId>, - client: &ComponentClient, - transaction_pool: &TransactionPool, - ) -> error::Result<()>; -} - -fn maintain_transaction_pool( - id: &BlockId, - client: &Client, - transaction_pool: &TransactionPool, -) -> error::Result<()> where - Block: BlockT::Out>, - Backend: client::backend::Backend, - Client: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: runtime_api::TaggedTransactionQueue, - Executor: client::CallExecutor, - PoolApi: txpool::ChainApi, -{ - // Avoid calling into runtime if there is nothing to prune from the pool anyway. - if transaction_pool.status().is_empty() { - return Ok(()) - } - - if let Some(block) = client.block(id)? { - let parent_id = BlockId::hash(*block.block.header().parent_hash()); - let extrinsics = block.block.extrinsics(); - transaction_pool.prune(id, &parent_id, extrinsics).map_err(|e| format!("{:?}", e))?; - } - - Ok(()) -} - -impl MaintainTransactionPool for C where - ComponentClient: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: runtime_api::TaggedTransactionQueue>, -{ - fn maintain_transaction_pool( - id: &BlockId>, - client: &ComponentClient, - transaction_pool: &TransactionPool, - ) -> error::Result<()> { - maintain_transaction_pool(id, client, transaction_pool) - } -} - -pub trait OffchainWorker { - fn offchain_workers( - number: &FactoryBlockNumber, - offchain: &offchain::OffchainWorkers< - ComponentClient, - ComponentOffchainStorage, - ComponentBlock - >, - pool: &Arc>, - network_state: &Arc, - is_validator: bool, - ) -> error::Result + Send>>; -} - -impl OffchainWorker for C where - ComponentClient: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: offchain::OffchainWorkerApi>, -{ - fn offchain_workers( - number: &FactoryBlockNumber, - offchain: &offchain::OffchainWorkers< - ComponentClient, - ComponentOffchainStorage, - ComponentBlock - >, - pool: &Arc>, - network_state: &Arc, - is_validator: bool, - ) -> error::Result + Send>> { - let future = offchain.on_block_imported(number, pool, network_state.clone(), is_validator) - .map(|()| Ok(())); - Ok(Box::new(Compat::new(future))) - } -} - -/// The super trait that combines all required traits a `Service` needs to implement. -pub trait ServiceTrait: - Deref> - + Send - + 'static - + StartRpc - + MaintainTransactionPool - + OffchainWorker - + InitialSessionKeys -{} -impl ServiceTrait for T where - T: Deref> - + Send - + 'static - + StartRpc - + MaintainTransactionPool - + OffchainWorker - + InitialSessionKeys -{} - -/// Alias for a an implementation of `futures::future::Executor`. -pub type TaskExecutor = Arc + Send>> + Send + Sync>; - -/// A collection of types and methods to build a service on top of the substrate service. -pub trait ServiceFactory: 'static + Sized { - /// Block type. - type Block: BlockT; - /// The type that implements the runtime API. - type RuntimeApi: Send + Sync; - /// Network protocol extensions. - type NetworkProtocol: network::specialization::NetworkSpecialization; - /// Chain runtime. - type RuntimeDispatch: NativeExecutionDispatch + Send + Sync + 'static; - /// Extrinsic pool backend type for the full client. - type FullTransactionPoolApi: txpool::ChainApi::Hash, Block = Self::Block> + Send + 'static; - /// Extrinsic pool backend type for the light client. - type LightTransactionPoolApi: txpool::ChainApi::Hash, Block = Self::Block> + 'static; - /// Genesis configuration for the runtime. - type Genesis: RuntimeGenesis; - /// Other configuration for service members. - type Configuration: Default; - /// RPC initialisation. - type RpcExtensions: rpc::RpcExtension; - /// Extended full service type. - type FullService: ServiceTrait>; - /// Extended light service type. - type LightService: ServiceTrait>; - /// ImportQueue for full client - type FullImportQueue: ImportQueue + 'static; - /// ImportQueue for light clients - type LightImportQueue: ImportQueue + 'static; - /// The Fork Choice Strategy for the chain - type SelectChain: SelectChain + 'static; - - //TODO: replace these with a constructor trait. that TransactionPool implements. (#1242) - /// Extrinsic pool constructor for the full client. - fn build_full_transaction_pool(config: TransactionPoolOptions, client: Arc>) - -> Result, error::Error>; - /// Extrinsic pool constructor for the light client. - fn build_light_transaction_pool(config: TransactionPoolOptions, client: Arc>) - -> Result, error::Error>; - - /// Build network protocol. - fn build_network_protocol(config: &FactoryFullConfiguration) - -> Result; - - /// Build finality proof provider for serving network requests on full node. - fn build_finality_proof_provider( - client: Arc> - ) -> Result>>, error::Error>; - - /// Build the Fork Choice algorithm for full client - fn build_select_chain( - config: &mut FactoryFullConfiguration, - client: Arc>, - ) -> Result; - - /// Build full service. - fn new_full(config: FactoryFullConfiguration) - -> Result; - /// Build light service. - fn new_light(config: FactoryFullConfiguration) - -> Result; - - /// ImportQueue for a full client - fn build_full_import_queue( - config: &mut FactoryFullConfiguration, - _client: Arc>, - _select_chain: Self::SelectChain, - _transaction_pool: Option>>, - ) -> Result { - if let Some(name) = config.chain_spec.consensus_engine() { - match name { - _ => Err(format!("Chain Specification defines unknown consensus engine '{}'", name).into()) - } - - } else { - Err("Chain Specification doesn't contain any consensus_engine name".into()) - } - } - - /// ImportQueue for a light client - fn build_light_import_queue( - config: &mut FactoryFullConfiguration, - _client: Arc> - ) -> Result<(Self::LightImportQueue, BoxFinalityProofRequestBuilder), error::Error> { - if let Some(name) = config.chain_spec.consensus_engine() { - match name { - _ => Err(format!("Chain Specification defines unknown consensus engine '{}'", name).into()) - } - - } else { - Err("Chain Specification doesn't contain any consensus_engine name".into()) - } - } - - /// Create custom RPC method handlers for full node. - fn build_full_rpc_extensions( - client: Arc>, - transaction_pool: Arc>, - ) -> Self::RpcExtensions; - - /// Create custom RPC method handlers for light node. - fn build_light_rpc_extensions( - client: Arc>, - transaction_pool: Arc>, - ) -> Self::RpcExtensions; -} - -/// A collection of types and function to generalize over full / light client type. -pub trait Components: Sized + 'static { - /// Associated service factory. - type Factory: ServiceFactory; - /// Client backend. - type Backend: 'static + client::backend::Backend, Blake2Hasher>; - /// Client executor. - type Executor: 'static + client::CallExecutor, Blake2Hasher> + Send + Sync + Clone; - /// The type that implements the runtime API. - type RuntimeApi: Send + Sync; - /// The type that can start all runtime-dependent services. - type RuntimeServices: ServiceTrait; - /// The type that can extend the RPC methods. - type RpcExtensions: rpc::RpcExtension; - // TODO: Traitify transaction pool and allow people to implement their own. (#1242) - /// Extrinsic pool type. - type TransactionPoolApi: 'static + txpool::ChainApi< - Hash = as BlockT>::Hash, - Block = FactoryBlock - >; - /// Our Import Queue - type ImportQueue: ImportQueue> + 'static; - /// The Fork Choice Strategy for the chain - type SelectChain: SelectChain>; - - /// Create client. - fn build_client( - config: &FactoryFullConfiguration, - executor: CodeExecutor, - keystore: Option, - ) -> Result< - ( - Arc>, - Option>>> - ), - error::Error - >; - - /// Create extrinsic pool. - fn build_transaction_pool(config: TransactionPoolOptions, client: Arc>) - -> Result, error::Error>; - - /// Build the queue that imports blocks from the network, and optionally a way for the network - /// to build requests for proofs of finality. - fn build_import_queue( - config: &mut FactoryFullConfiguration, - client: Arc>, - select_chain: Option, - _transaction_pool: Option>>, - ) -> Result<(Self::ImportQueue, Option>>), error::Error>; - - /// Finality proof provider for serving network requests. - fn build_finality_proof_provider( - client: Arc> - ) -> Result::Block>>>, error::Error>; - - /// Build fork choice selector - fn build_select_chain( - config: &mut FactoryFullConfiguration, - client: Arc> - ) -> Result, error::Error>; - - /// Build RPC extensions - fn build_rpc_extensions( - client: Arc>, - transaction_pool: Arc>, - ) -> Self::RpcExtensions; -} - -/// A struct that implement `Components` for the full client. -pub struct FullComponents { - service: Service>, -} - -impl FullComponents { - /// Create new `FullComponents` - pub fn new( - config: FactoryFullConfiguration - ) -> Result { - Ok( - Self { - service: Service::new(config)?, - } - ) - } -} - -impl Deref for FullComponents { - type Target = Service; - - fn deref(&self) -> &Self::Target { - &self.service - } -} - -impl DerefMut for FullComponents { - fn deref_mut(&mut self) -> &mut Service { - &mut self.service - } -} - -impl Future for FullComponents { - type Item = (); - type Error = super::Error; - - fn poll(&mut self) -> Poll { - self.service.poll() - } -} - -impl Executor + Send>> -for FullComponents { - fn execute( - &self, - future: Box + Send> - ) -> Result<(), futures::future::ExecuteError + Send>>> { - self.service.execute(future) - } -} - -impl Components for FullComponents { - type Factory = Factory; - type Executor = FullExecutor; - type Backend = FullBackend; - type TransactionPoolApi = ::FullTransactionPoolApi; - type ImportQueue = Factory::FullImportQueue; - type RuntimeApi = Factory::RuntimeApi; - type RuntimeServices = Factory::FullService; - type RpcExtensions = Factory::RpcExtensions; - type SelectChain = Factory::SelectChain; - - fn build_client( - config: &FactoryFullConfiguration, - executor: CodeExecutor, - keystore: Option, - ) -> Result< - (Arc>, Option>>>), - error::Error, - > - { - let db_settings = client_db::DatabaseSettings { - cache_size: config.database_cache_size.map(|u| u as usize), - state_cache_size: config.state_cache_size, - state_cache_child_ratio: - config.state_cache_child_ratio.map(|v| (v, 100)), - path: config.database_path.clone(), - pruning: config.pruning.clone(), - }; - - Ok(( - Arc::new( - client_db::new_client( - db_settings, - executor, - &config.chain_spec, - config.execution_strategies.clone(), - keystore, - )? - ), - None, - )) - } - - fn build_transaction_pool( - config: TransactionPoolOptions, - client: Arc> - ) -> Result, error::Error> { - Factory::build_full_transaction_pool(config, client) - } - - fn build_import_queue( - config: &mut FactoryFullConfiguration, - client: Arc>, - select_chain: Option, - transaction_pool: Option>>, - ) -> Result<(Self::ImportQueue, Option>>), error::Error> { - let select_chain = select_chain - .ok_or(error::Error::SelectChainRequired)?; - Factory::build_full_import_queue(config, client, select_chain, transaction_pool) - .map(|queue| (queue, None)) - } - - fn build_select_chain( - config: &mut FactoryFullConfiguration, - client: Arc> - ) -> Result, error::Error> { - Self::Factory::build_select_chain(config, client).map(Some) - } - - fn build_finality_proof_provider( - client: Arc> - ) -> Result::Block>>>, error::Error> { - Factory::build_finality_proof_provider(client) - } - - fn build_rpc_extensions( - client: Arc>, - transaction_pool: Arc>, - ) -> Self::RpcExtensions { - Factory::build_full_rpc_extensions(client, transaction_pool) - } -} - -/// A struct that implement `Components` for the light client. -pub struct LightComponents { - service: Service>, -} - -impl LightComponents { - /// Create new `LightComponents` - pub fn new( - config: FactoryFullConfiguration, - ) -> Result { - Ok( - Self { - service: Service::new(config)?, - } - ) - } -} - -impl Deref for LightComponents { - type Target = Service; - - fn deref(&self) -> &Self::Target { - &self.service - } -} - -impl DerefMut for LightComponents { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.service - } -} - -impl Future for LightComponents { - type Item = (); - type Error = super::Error; - - fn poll(&mut self) -> Poll { - self.service.poll() - } -} - -impl Executor + Send>> -for LightComponents { - fn execute( - &self, - future: Box + Send> - ) -> Result<(), futures::future::ExecuteError + Send>>> { - self.service.execute(future) - } -} - -impl Components for LightComponents { - type Factory = Factory; - type Executor = LightExecutor; - type Backend = LightBackend; - type TransactionPoolApi = ::LightTransactionPoolApi; - type ImportQueue = ::LightImportQueue; - type RuntimeApi = Factory::RuntimeApi; - type RuntimeServices = Factory::LightService; - type RpcExtensions = Factory::RpcExtensions; - type SelectChain = Factory::SelectChain; - - fn build_client( - config: &FactoryFullConfiguration, - executor: CodeExecutor, - _: Option, - ) - -> Result< - ( - Arc>, - Option>>> - ), error::Error> - { - let db_settings = client_db::DatabaseSettings { - cache_size: None, - state_cache_size: config.state_cache_size, - state_cache_child_ratio: - config.state_cache_child_ratio.map(|v| (v, 100)), - path: config.database_path.clone(), - pruning: config.pruning.clone(), - }; - - let db_storage = client_db::light::LightStorage::new(db_settings)?; - let light_blockchain = client::light::new_light_blockchain(db_storage); - let fetch_checker = Arc::new( - client::light::new_fetch_checker(light_blockchain.clone(), executor.clone()) - ); - let fetcher = Arc::new(network::OnDemand::new(fetch_checker)); - let client_backend = client::light::new_light_backend(light_blockchain, fetcher.clone()); - let client = client::light::new_light(client_backend, fetcher.clone(), &config.chain_spec, executor)?; - Ok((Arc::new(client), Some(fetcher))) - } - - fn build_transaction_pool(config: TransactionPoolOptions, client: Arc>) - -> Result, error::Error> - { - Factory::build_light_transaction_pool(config, client) - } - - fn build_import_queue( - config: &mut FactoryFullConfiguration, - client: Arc>, - _select_chain: Option, - _transaction_pool: Option>>, - ) -> Result<(Self::ImportQueue, Option>>), error::Error> { - Factory::build_light_import_queue(config, client) - .map(|(queue, builder)| (queue, Some(builder))) - } - - fn build_finality_proof_provider( - _client: Arc> - ) -> Result::Block>>>, error::Error> { - Ok(None) - } - - fn build_select_chain( - _config: &mut FactoryFullConfiguration, - _client: Arc> - ) -> Result, error::Error> { - Ok(None) - } - - fn build_rpc_extensions( - client: Arc>, - transaction_pool: Arc>, - ) -> Self::RpcExtensions { - Factory::build_light_rpc_extensions(client, transaction_pool) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use consensus_common::BlockOrigin; - use substrate_test_runtime_client::{prelude::*, runtime::Transfer}; - - #[test] - fn should_remove_transactions_from_the_pool() { - let (client, longest_chain) = TestClientBuilder::new().build_with_longest_chain(); - let client = Arc::new(client); - let pool = TransactionPool::new(Default::default(), ::transaction_pool::ChainApi::new(client.clone())); - let transaction = Transfer { - amount: 5, - nonce: 0, - from: AccountKeyring::Alice.into(), - to: Default::default(), - }.into_signed_tx(); - let best = longest_chain.best_chain().unwrap(); - - // store the transaction in the pool - pool.submit_one(&BlockId::hash(best.hash()), transaction.clone()).unwrap(); - - // import the block - let mut builder = client.new_block(Default::default()).unwrap(); - builder.push(transaction.clone()).unwrap(); - let block = builder.bake().unwrap(); - let id = BlockId::hash(block.header().hash()); - client.import(BlockOrigin::Own, block).unwrap(); - - // fire notification - this should clean up the queue - assert_eq!(pool.status().ready, 1); - maintain_transaction_pool( - &id, - &client, - &pool, - ).unwrap(); - - // then - assert_eq!(pool.status().ready, 0); - assert_eq!(pool.status().future, 0); - } -} diff --git a/core/service/src/lib.rs b/core/service/src/lib.rs index 33a42e87fe..363ad9cfda 100644 --- a/core/service/src/lib.rs +++ b/core/service/src/lib.rs @@ -19,51 +19,43 @@ #![warn(missing_docs)] -mod components; mod chain_spec; pub mod config; +#[macro_use] pub mod chain_ops; pub mod error; use std::io; +use std::marker::PhantomData; use std::net::SocketAddr; use std::collections::HashMap; use std::sync::atomic::{AtomicBool, Ordering}; use std::time::{Duration, Instant}; +use serde::{Serialize, de::DeserializeOwned}; use futures::sync::mpsc; use parking_lot::Mutex; -use client::{BlockchainEvents, backend::Backend, runtime_api::BlockT}; +use client::{runtime_api::BlockT, Client}; use exit_future::Signal; use futures::prelude::*; use futures03::stream::{StreamExt as _, TryStreamExt as _}; -use keystore::Store as Keystore; -use network::{NetworkState, NetworkStateInfo}; -use log::{log, info, warn, debug, error, Level}; +use network::{NetworkService, NetworkState, specialization::NetworkSpecialization}; +use log::{log, warn, debug, error, Level}; use codec::{Encode, Decode}; +use primitives::{Blake2Hasher, H256}; +use sr_primitives::BuildStorage; use sr_primitives::generic::BlockId; -use sr_primitives::traits::{Header, NumberFor, SaturatedConversion}; -use substrate_executor::NativeExecutor; -use sysinfo::{get_current_pid, ProcessExt, System, SystemExt}; -use tel::{telemetry, SUBSTRATE_INFO}; +use sr_primitives::traits::NumberFor; pub use self::error::Error; +pub use self::builder::{ServiceBuilder, ServiceBuilderExport, ServiceBuilderImport, ServiceBuilderRevert}; pub use config::{Configuration, Roles, PruningMode}; pub use chain_spec::{ChainSpec, Properties}; pub use transaction_pool::txpool::{ self, Pool as TransactionPool, Options as TransactionPoolOptions, ChainApi, IntoPoolError }; pub use client::FinalityNotifications; - -pub use components::{ - ServiceFactory, FullBackend, FullExecutor, LightBackend, - LightExecutor, Components, PoolApi, ComponentClient, ComponentOffchainStorage, - ComponentBlock, FullClient, LightClient, FullComponents, LightComponents, - CodeExecutor, NetworkService, FactoryChainSpec, FactoryBlock, - FactoryFullConfiguration, RuntimeGenesis, FactoryGenesis, - ComponentExHash, ComponentExtrinsic, FactoryExtrinsic, InitialSessionKeys, -}; -use components::{StartRpc, MaintainTransactionPool, OffchainWorker}; +pub use rpc::Metadata as RpcMetadata; #[doc(hidden)] pub use std::{ops::Deref, result::Result, sync::Arc}; #[doc(hidden)] @@ -74,15 +66,15 @@ pub use futures::future::Executor; const DEFAULT_PROTOCOL_ID: &str = "sup"; /// Substrate service. -pub struct Service { - client: Arc>, - select_chain: Option, - network: Arc>, +pub struct NewService { + client: Arc, + select_chain: Option, + network: Arc, /// Sinks to propagate network status updates. network_status_sinks: Arc>, NetworkState + TNetStatus, NetworkState )>>>>, - transaction_pool: Arc>, + transaction_pool: Arc, /// A future that resolves when the service has exited, this is useful to /// make sure any internally spawned futures stop when the service does. exit: exit_future::Exit, @@ -100,31 +92,22 @@ pub struct Service { /// The elements must then be polled manually. to_poll: Vec + Send>>, /// Configuration of this Service - config: FactoryFullConfiguration, - rpc_handlers: components::RpcHandler, + config: TCfg, + rpc_handlers: rpc_servers::RpcHandler, _rpc: Box, _telemetry: Option, _telemetry_on_connect_sinks: Arc>>>, - _offchain_workers: Option, - ComponentOffchainStorage, - ComponentBlock> - >>, + _offchain_workers: Option>, keystore: keystore::KeyStorePtr, + marker: PhantomData, } -/// Creates bare client without any networking. -pub fn new_client( - config: &FactoryFullConfiguration, -) -> Result>>, error::Error> { - let executor = NativeExecutor::new(config.default_heap_pages); - - components::FullComponents::::build_client( - config, - executor, - None, - ).map(|r| r.0) -} +/// A set of traits for the runtime genesis config. +pub trait RuntimeGenesis: Serialize + DeserializeOwned + BuildStorage {} +impl RuntimeGenesis for T {} + +/// Alias for a an implementation of `futures::future::Executor`. +pub type TaskExecutor = Arc + Send>> + Send + Sync>; /// An handle for spawning tasks in the service. #[derive(Clone)] @@ -146,59 +129,38 @@ impl Executor + Send>> for SpawnTaskHandle } } -/// Stream of events for connection established to a telemetry server. -pub type TelemetryOnConnectNotifications = mpsc::UnboundedReceiver<()>; - -/// Used to hook on telemetry connection established events. -pub struct TelemetryOnConnect { - /// Event stream. - pub telemetry_connection_sinks: TelemetryOnConnectNotifications, -} - -impl Service { - /// Creates a new service. - pub fn new( - mut config: FactoryFullConfiguration, - ) -> Result { +macro_rules! new_impl { + ( + $block:ty, + $config:ident, + $build_components:expr, + $maintain_transaction_pool:expr, + $offchain_workers:expr, + $start_rpc:expr, + ) => {{ let (signal, exit) = exit_future::signal(); // List of asynchronous tasks to spawn. We collect them, then spawn them all at once. let (to_spawn_tx, to_spawn_rx) = mpsc::unbounded:: + Send>>(); - // Create client - let executor = NativeExecutor::new(config.default_heap_pages); - - let keystore = Keystore::open(config.keystore_path.clone(), config.keystore_password.clone())?; - - let (client, on_demand) = Components::build_client(&config, executor, Some(keystore.clone()))?; - let select_chain = Components::build_select_chain(&mut config, client.clone())?; - - let transaction_pool = Arc::new( - Components::build_transaction_pool(config.transaction_pool.clone(), client.clone())? - ); - let transaction_pool_adapter = Arc::new(TransactionPoolAdapter { - imports_external_transactions: !config.roles.is_light(), - pool: transaction_pool.clone(), - client: client.clone(), - }); - - let (import_queue, finality_proof_request_builder) = Components::build_import_queue( - &mut config, - client.clone(), - select_chain.clone(), - Some(transaction_pool.clone()), - )?; + // Create all the components. + let ( + client, + on_demand, + keystore, + select_chain, + import_queue, + finality_proof_request_builder, + finality_proof_provider, + network_protocol, + transaction_pool, + rpc_extensions + ) = $build_components(&mut $config)?; let import_queue = Box::new(import_queue); - let finality_proof_provider = Components::build_finality_proof_provider(client.clone())?; let chain_info = client.info().chain; - Components::RuntimeServices::generate_initial_session_keys( - client.clone(), - config.dev_key_seed.clone().map(|s| vec![s]).unwrap_or_default(), - )?; - - let version = config.full_version(); + let version = $config.full_version(); info!("Highest known block at #{}", chain_info.best_number); telemetry!( SUBSTRATE_INFO; @@ -207,10 +169,14 @@ impl Service { "best" => ?chain_info.best_hash ); - let network_protocol = ::build_network_protocol(&config)?; + let transaction_pool_adapter = Arc::new(TransactionPoolAdapter { + imports_external_transactions: !$config.roles.is_light(), + pool: transaction_pool.clone(), + client: client.clone(), + }); let protocol_id = { - let protocol_id_full = match config.chain_spec.protocol_id() { + let protocol_id_full = match $config.chain_spec.protocol_id() { Some(pid) => pid, None => { warn!("Using default protocol ID {:?} because none is configured in the \ @@ -223,8 +189,8 @@ impl Service { }; let network_params = network::config::Params { - roles: config.roles, - network_config: config.network.clone(), + roles: $config.roles, + network_config: $config.network.clone(), chain: client.clone(), finality_proof_provider, finality_proof_request_builder, @@ -242,7 +208,7 @@ impl Service { #[allow(deprecated)] let offchain_storage = client.backend().offchain_storage(); - let offchain_workers = match (config.offchain_worker, offchain_storage) { + let offchain_workers = match ($config.offchain_worker, offchain_storage) { (true, Some(db)) => { Some(Arc::new(offchain::OffchainWorkers::new(client.clone(), db))) }, @@ -260,23 +226,25 @@ impl Service { let offchain = offchain_workers.as_ref().map(Arc::downgrade); let to_spawn_tx_ = to_spawn_tx.clone(); let network_state_info: Arc = network.clone(); - let is_validator = config.roles.is_authority(); + let is_validator = $config.roles.is_authority(); let events = client.import_notification_stream() .map(|v| Ok::<_, ()>(v)).compat() .for_each(move |notification| { let number = *notification.header.number(); + let txpool = txpool.upgrade(); - if let (Some(txpool), Some(client)) = (txpool.upgrade(), wclient.upgrade()) { - Components::RuntimeServices::maintain_transaction_pool( + if let (Some(txpool), Some(client)) = (txpool.as_ref(), wclient.upgrade()) { + $maintain_transaction_pool( &BlockId::hash(notification.hash), &*client, &*txpool, ).map_err(|e| warn!("Pool error processing new block: {:?}", e))?; } - if let (Some(txpool), Some(offchain)) = (txpool.upgrade(), offchain.as_ref().and_then(|o| o.upgrade())) { - let future = Components::RuntimeServices::offchain_workers( + let offchain = offchain.as_ref().and_then(|o| o.upgrade()); + if let (Some(txpool), Some(offchain)) = (txpool, offchain) { + let future = $offchain_workers( &number, &offchain, &txpool, @@ -321,7 +289,7 @@ impl Service { let client_ = client.clone(); let mut sys = System::new(); let self_pid = get_current_pid().ok(); - let (netstat_tx, netstat_rx) = mpsc::unbounded::<(NetworkStatus>, NetworkState)>(); + let (netstat_tx, netstat_rx) = mpsc::unbounded::<(NetworkStatus<_>, NetworkState)>(); network_status_sinks.lock().push(netstat_tx); let tel_task = netstat_rx.for_each(move |(net_status, network_state)| { let info = client_.info(); @@ -374,23 +342,23 @@ impl Service { let (system_rpc_tx, system_rpc_rx) = futures03::channel::mpsc::unbounded(); let gen_handler = || { let system_info = rpc::system::SystemInfo { - chain_name: config.chain_spec.name().into(), - impl_name: config.impl_name.into(), - impl_version: config.impl_version.into(), - properties: config.chain_spec.properties(), + chain_name: $config.chain_spec.name().into(), + impl_name: $config.impl_name.into(), + impl_version: $config.impl_version.into(), + properties: $config.chain_spec.properties(), }; - Components::RuntimeServices::start_rpc( + $start_rpc( client.clone(), system_rpc_tx.clone(), system_info.clone(), Arc::new(SpawnTaskHandle { sender: to_spawn_tx.clone() }), transaction_pool.clone(), - Components::build_rpc_extensions(client.clone(), transaction_pool.clone()), + rpc_extensions.clone(), keystore.clone(), ) }; let rpc_handlers = gen_handler(); - let rpc = start_rpc_servers(&config, gen_handler)?; + let rpc = start_rpc_servers(&$config, gen_handler)?; let _ = to_spawn_tx.unbounded_send(Box::new(build_network_future( network_mut, @@ -406,17 +374,17 @@ impl Service { let telemetry_connection_sinks: Arc>>> = Default::default(); // Telemetry - let telemetry = config.telemetry_endpoints.clone().map(|endpoints| { - let is_authority = config.roles.is_authority(); + let telemetry = $config.telemetry_endpoints.clone().map(|endpoints| { + let is_authority = $config.roles.is_authority(); let network_id = network.local_peer_id().to_base58(); - let name = config.name.clone(); - let impl_name = config.impl_name.to_owned(); + let name = $config.name.clone(); + let impl_name = $config.impl_name.to_owned(); let version = version.clone(); - let chain_name = config.chain_spec.name().to_owned(); + let chain_name = $config.chain_spec.name().to_owned(); let telemetry_connection_sinks_ = telemetry_connection_sinks.clone(); let telemetry = tel::init_telemetry(tel::TelemetryConfig { endpoints, - wasm_external_transport: config.telemetry_external_transport.take(), + wasm_external_transport: $config.telemetry_external_transport.take(), }); let future = telemetry.clone() .map(|ev| Ok::<_, ()>(ev)) @@ -446,7 +414,7 @@ impl Service { telemetry }); - Ok(Service { + Ok(NewService { client, network, network_status_sinks, @@ -458,56 +426,145 @@ impl Service { to_spawn_tx, to_spawn_rx, to_poll: Vec::new(), - config, + $config, rpc_handlers, _rpc: rpc, _telemetry: telemetry, _offchain_workers: offchain_workers, _telemetry_on_connect_sinks: telemetry_connection_sinks.clone(), keystore, + marker: PhantomData::<$block>, }) - } + }} +} + +mod builder; + +/// Abstraction over a Substrate service. +pub trait AbstractService: 'static + Future + + Executor + Send>> + Send { + /// Type of block of this chain. + type Block: BlockT; + /// Backend storage for the client. + type Backend: 'static + client::backend::Backend; + /// How to execute calls towards the runtime. + type CallExecutor: 'static + client::CallExecutor + Send + Sync + Clone; + /// API that the runtime provides. + type RuntimeApi: Send + Sync; + /// Configuration struct of the service. + type Config; + /// Chain selection algorithm. + type SelectChain; + /// API of the transaction pool. + type TransactionPoolApi: ChainApi; + /// Network specialization. + type NetworkSpecialization: NetworkSpecialization; + + /// Get event stream for telemetry connection established events. + fn telemetry_on_connect_stream(&self) -> mpsc::UnboundedReceiver<()>; + + /// Returns the configuration passed on construction. + fn config(&self) -> &Self::Config; + + /// Returns the configuration passed on construction. + fn config_mut(&mut self) -> &mut Self::Config; + + /// return a shared instance of Telemetry (if enabled) + fn telemetry(&self) -> Option; + + /// Spawns a task in the background that runs the future passed as parameter. + fn spawn_task(&self, task: impl Future + Send + 'static); + + /// Spawns a task in the background that runs the future passed as + /// parameter. The given task is considered essential, i.e. if it errors we + /// trigger a service exit. + fn spawn_essential_task(&self, task: impl Future + Send + 'static); + + /// Returns a handle for spawning tasks. + fn spawn_task_handle(&self) -> SpawnTaskHandle; + + /// Returns the keystore that stores keys. + fn keystore(&self) -> keystore::KeyStorePtr; + + /// Starts an RPC query. + /// + /// The query is passed as a string and must be a JSON text similar to what an HTTP client + /// would for example send. + /// + /// Returns a `Future` that contains the optional response. + /// + /// If the request subscribes you to events, the `Sender` in the `RpcSession` object is used to + /// send back spontaneous events. + fn rpc_query(&self, mem: &RpcSession, request: &str) -> Box, Error = ()> + Send>; + + /// Get shared client instance. + fn client(&self) -> Arc>; + + /// Get clone of select chain. + fn select_chain(&self) -> Option; + + /// Get shared network instance. + fn network(&self) -> Arc>; - /// Returns a reference to the config passed at initialization. - pub fn config(&self) -> &FactoryFullConfiguration { + /// Returns a receiver that periodically receives a status of the network. + fn network_status(&self) -> mpsc::UnboundedReceiver<(NetworkStatus, NetworkState)>; + + /// Get shared transaction pool instance. + fn transaction_pool(&self) -> Arc>; + + /// Get a handle to a future that will resolve on exit. + fn on_exit(&self) -> ::exit_future::Exit; +} + +impl AbstractService for + NewService, TSc, NetworkStatus, + NetworkService, TransactionPool, TOc> +where TCfg: 'static + Send, + TBl: BlockT, + TBackend: 'static + client::backend::Backend, + TExec: 'static + client::CallExecutor + Send + Sync + Clone, + TRtApi: 'static + Send + Sync, + TSc: 'static + Clone + Send, + TExPoolApi: 'static + ChainApi, + TOc: 'static + Send + Sync, + TNetSpec: NetworkSpecialization, +{ + type Block = TBl; + type Backend = TBackend; + type CallExecutor = TExec; + type RuntimeApi = TRtApi; + type Config = TCfg; + type SelectChain = TSc; + type TransactionPoolApi = TExPoolApi; + type NetworkSpecialization = TNetSpec; + + fn config(&self) -> &Self::Config { &self.config } - /// Returns a reference to the config passed at initialization. - /// - /// > **Note**: This method is currently necessary because we extract some elements from the - /// > configuration at the end of the service initialization. It is intended to be - /// > removed. - pub fn config_mut(&mut self) -> &mut FactoryFullConfiguration { + fn config_mut(&mut self) -> &mut Self::Config { &mut self.config } - /// Get event stream for telemetry connection established events. - pub fn telemetry_on_connect_stream(&self) -> TelemetryOnConnectNotifications { + fn telemetry_on_connect_stream(&self) -> mpsc::UnboundedReceiver<()> { let (sink, stream) = mpsc::unbounded(); self._telemetry_on_connect_sinks.lock().push(sink); stream } - /// Return a shared instance of Telemetry (if enabled) - pub fn telemetry(&self) -> Option { + fn telemetry(&self) -> Option { self._telemetry.as_ref().map(|t| t.clone()) } - /// Returns the keystore instance. - pub fn keystore(&self) -> keystore::KeyStorePtr { + fn keystore(&self) -> keystore::KeyStorePtr { self.keystore.clone() } - /// Spawns a task in the background that runs the future passed as parameter. - pub fn spawn_task(&self, task: impl Future + Send + 'static) { + fn spawn_task(&self, task: impl Future + Send + 'static) { let _ = self.to_spawn_tx.unbounded_send(Box::new(task)); } - /// Spawns a task in the background that runs the future passed as - /// parameter. The given task is considered essential, i.e. if it errors we - /// trigger a service exit. - pub fn spawn_essential_task(&self, task: impl Future + Send + 'static) { + fn spawn_essential_task(&self, task: impl Future + Send + 'static) { let essential_failed = self.essential_failed.clone(); let essential_task = Box::new(task.map_err(move |_| { error!("Essential task failed. Shutting down service."); @@ -517,62 +574,45 @@ impl Service { let _ = self.to_spawn_tx.unbounded_send(essential_task); } - /// Returns a handle for spawning tasks. - pub fn spawn_task_handle(&self) -> SpawnTaskHandle { + fn spawn_task_handle(&self) -> SpawnTaskHandle { SpawnTaskHandle { sender: self.to_spawn_tx.clone(), } } - /// Starts an RPC query. - /// - /// The query is passed as a string and must be a JSON text similar to what an HTTP client - /// would for example send. - /// - /// Returns a `Future` that contains the optional response. - /// - /// If the request subscribes you to events, the `Sender` in the `RpcSession` object is used to - /// send back spontaneous events. - pub fn rpc_query(&self, mem: &RpcSession, request: &str) - -> impl Future, Error = ()> - { - self.rpc_handlers.handle_request(request, mem.metadata.clone()) + fn rpc_query(&self, mem: &RpcSession, request: &str) -> Box, Error = ()> + Send> { + Box::new(self.rpc_handlers.handle_request(request, mem.metadata.clone())) } - /// Get shared client instance. - pub fn client(&self) -> Arc> { + fn client(&self) -> Arc> { self.client.clone() } - /// Get clone of select chain. - pub fn select_chain(&self) -> Option<::SelectChain> { + fn select_chain(&self) -> Option { self.select_chain.clone() } - /// Get shared network instance. - pub fn network(&self) -> Arc> { + fn network(&self) -> Arc> { self.network.clone() } - /// Returns a receiver that periodically receives a status of the network. - pub fn network_status(&self) -> mpsc::UnboundedReceiver<(NetworkStatus>, NetworkState)> { + fn network_status(&self) -> mpsc::UnboundedReceiver<(NetworkStatus, NetworkState)> { let (sink, stream) = mpsc::unbounded(); self.network_status_sinks.lock().push(sink); stream } - /// Get shared transaction pool instance. - pub fn transaction_pool(&self) -> Arc> { + fn transaction_pool(&self) -> Arc> { self.transaction_pool.clone() } - /// Get a handle to a future that will resolve on exit. - pub fn on_exit(&self) -> ::exit_future::Exit { + fn on_exit(&self) -> ::exit_future::Exit { self.exit.clone() } } -impl Future for Service where Components: components::Components { +impl Future for +NewService { type Item = (); type Error = Error; @@ -603,9 +643,8 @@ impl Future for Service where Components: components::Co } } -impl Executor + Send>> - for Service where Components: components::Components -{ +impl Executor + Send>> for +NewService { fn execute( &self, future: Box + Send> @@ -746,7 +785,8 @@ pub struct NetworkStatus { pub average_upload_per_sec: u64, } -impl Drop for Service where Components: components::Components { +impl Drop for +NewService { fn drop(&mut self) { debug!(target: "service", "Substrate service shutdown"); if let Some(signal) = self.signal.take() { @@ -757,7 +797,7 @@ impl Drop for Service where Components: components::Comp /// Starts RPC servers that run in their own thread, and returns an opaque object that keeps them alive. #[cfg(not(target_os = "unknown"))] -fn start_rpc_servers components::RpcHandler>( +fn start_rpc_servers rpc_servers::RpcHandler>( config: &Configuration, mut gen_handler: H ) -> Result, error::Error> { @@ -906,225 +946,6 @@ where } } -/// Constructs a service factory with the given name that implements the `ServiceFactory` trait. -/// The required parameters are required to be given in the exact order. Some parameters are followed -/// by `{}` blocks. These blocks are required and used to initialize the given parameter. -/// In these block it is required to write a closure that takes the same number of arguments, -/// the corresponding function in the `ServiceFactory` trait provides. -/// -/// # Example -/// -/// ``` -/// # use substrate_service::{ -/// # construct_service_factory, Service, FullBackend, FullExecutor, LightBackend, LightExecutor, -/// # FullComponents, LightComponents, FactoryFullConfiguration, FullClient -/// # }; -/// # use transaction_pool::{self, txpool::{Pool as TransactionPool}}; -/// # use network::{config::DummyFinalityProofRequestBuilder, construct_simple_protocol}; -/// # use client::{self, LongestChain}; -/// # use consensus_common::import_queue::{BasicQueue, Verifier}; -/// # use consensus_common::{BlockOrigin, BlockImportParams, well_known_cache_keys::Id as CacheKeyId}; -/// # use node_runtime::{GenesisConfig, RuntimeApi}; -/// # use std::sync::Arc; -/// # use node_primitives::Block; -/// # use babe_primitives::AuthorityPair as BabePair; -/// # use grandpa_primitives::AuthorityPair as GrandpaPair; -/// # use sr_primitives::Justification; -/// # use sr_primitives::traits::Block as BlockT; -/// # use grandpa; -/// # construct_simple_protocol! { -/// # pub struct NodeProtocol where Block = Block { } -/// # } -/// # struct MyVerifier; -/// # impl Verifier for MyVerifier { -/// # fn verify( -/// # &mut self, -/// # origin: BlockOrigin, -/// # header: B::Header, -/// # justification: Option, -/// # body: Option>, -/// # ) -> Result<(BlockImportParams, Option)>>), String> { -/// # unimplemented!(); -/// # } -/// # } -/// type FullChainApi = transaction_pool::ChainApi< -/// client::Client, FullExecutor, Block, RuntimeApi>, Block>; -/// type LightChainApi = transaction_pool::ChainApi< -/// client::Client, LightExecutor, Block, RuntimeApi>, Block>; -/// -/// construct_service_factory! { -/// struct Factory { -/// // Declare the block type -/// Block = Block, -/// RuntimeApi = RuntimeApi, -/// // Declare the network protocol and give an initializer. -/// NetworkProtocol = NodeProtocol { |config| Ok(NodeProtocol::new()) }, -/// RuntimeDispatch = node_executor::Executor, -/// FullTransactionPoolApi = FullChainApi -/// { |config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) }, -/// LightTransactionPoolApi = LightChainApi -/// { |config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) }, -/// Genesis = GenesisConfig, -/// Configuration = (), -/// FullService = FullComponents -/// { |config| >::new(config) }, -/// // Setup as Consensus Authority (if the role and key are given) -/// AuthoritySetup = { -/// |service: Self::FullService| { -/// Ok(service) -/// }}, -/// LightService = LightComponents -/// { |config| >::new(config) }, -/// FullImportQueue = BasicQueue -/// { |_, client, _, _| Ok(BasicQueue::new(MyVerifier, Box::new(client), None, None)) }, -/// LightImportQueue = BasicQueue -/// { |_, client| { -/// let fprb = Box::new(DummyFinalityProofRequestBuilder::default()) as Box<_>; -/// Ok((BasicQueue::new(MyVerifier, Box::new(client), None, None), fprb)) -/// }}, -/// SelectChain = LongestChain, Self::Block> -/// { |config: &FactoryFullConfiguration, client: Arc>| { -/// #[allow(deprecated)] -/// Ok(LongestChain::new(client.backend().clone())) -/// }}, -/// FinalityProofProvider = { |client: Arc>| { -/// Ok(Some(Arc::new(grandpa::FinalityProofProvider::new(client.clone(), client)) as _)) -/// }}, -/// RpcExtensions = (), -/// } -/// } -/// ``` -#[macro_export] -macro_rules! construct_service_factory { - ( - $(#[$attr:meta])* - struct $name:ident { - Block = $block:ty, - RuntimeApi = $runtime_api:ty, - NetworkProtocol = $protocol:ty { $( $protocol_init:tt )* }, - RuntimeDispatch = $dispatch:ty, - FullTransactionPoolApi = $full_transaction:ty { $( $full_transaction_init:tt )* }, - LightTransactionPoolApi = $light_transaction:ty { $( $light_transaction_init:tt )* }, - Genesis = $genesis:ty, - Configuration = $config:ty, - FullService = $full_service:ty { $( $full_service_init:tt )* }, - AuthoritySetup = { $( $authority_setup:tt )* }, - LightService = $light_service:ty { $( $light_service_init:tt )* }, - FullImportQueue = $full_import_queue:ty - { $( $full_import_queue_init:tt )* }, - LightImportQueue = $light_import_queue:ty - { $( $light_import_queue_init:tt )* }, - SelectChain = $select_chain:ty - { $( $select_chain_init:tt )* }, - FinalityProofProvider = { $( $finality_proof_provider_init:tt )* }, - RpcExtensions = $rpc_extensions_ty:ty - $( { $( $rpc_extensions:tt )* } )?, - } - ) => { - $( #[$attr] )* - pub struct $name {} - - #[allow(unused_variables)] - impl $crate::ServiceFactory for $name { - type Block = $block; - type RuntimeApi = $runtime_api; - type NetworkProtocol = $protocol; - type RuntimeDispatch = $dispatch; - type FullTransactionPoolApi = $full_transaction; - type LightTransactionPoolApi = $light_transaction; - type Genesis = $genesis; - type Configuration = $config; - type FullService = $full_service; - type LightService = $light_service; - type FullImportQueue = $full_import_queue; - type LightImportQueue = $light_import_queue; - type SelectChain = $select_chain; - type RpcExtensions = $rpc_extensions_ty; - - fn build_full_transaction_pool( - config: $crate::TransactionPoolOptions, - client: $crate::Arc<$crate::FullClient> - ) -> $crate::Result<$crate::TransactionPool, $crate::Error> - { - ( $( $full_transaction_init )* ) (config, client) - } - - fn build_light_transaction_pool( - config: $crate::TransactionPoolOptions, - client: $crate::Arc<$crate::LightClient> - ) -> $crate::Result<$crate::TransactionPool, $crate::Error> - { - ( $( $light_transaction_init )* ) (config, client) - } - - fn build_network_protocol(config: &$crate::FactoryFullConfiguration) - -> $crate::Result - { - ( $( $protocol_init )* ) (config) - } - - fn build_select_chain( - config: &mut $crate::FactoryFullConfiguration, - client: Arc<$crate::FullClient> - ) -> $crate::Result { - ( $( $select_chain_init )* ) (config, client) - } - - fn build_full_import_queue( - config: &mut $crate::FactoryFullConfiguration, - client: $crate::Arc<$crate::FullClient>, - select_chain: Self::SelectChain, - transaction_pool: Option>>, - ) -> $crate::Result { - ( $( $full_import_queue_init )* ) (config, client, select_chain, transaction_pool) - } - - fn build_light_import_queue( - config: &mut FactoryFullConfiguration, - client: Arc<$crate::LightClient>, - ) -> Result<(Self::LightImportQueue, $crate::BoxFinalityProofRequestBuilder<$block>), $crate::Error> { - ( $( $light_import_queue_init )* ) (config, client) - } - - fn build_finality_proof_provider( - client: Arc<$crate::FullClient> - ) -> Result>>, $crate::Error> { - ( $( $finality_proof_provider_init )* ) (client) - } - - fn new_light( - config: $crate::FactoryFullConfiguration - ) -> $crate::Result - { - ( $( $light_service_init )* ) (config) - } - - fn new_full( - config: $crate::FactoryFullConfiguration - ) -> Result - { - ( $( $full_service_init )* ) (config).and_then(|service| { - ($( $authority_setup )*)(service) - }) - } - - fn build_full_rpc_extensions( - client: Arc<$crate::FullClient>, - transaction_pool: Arc<$crate::TransactionPool>, - ) -> Self::RpcExtensions { - $( ( $( $rpc_extensions )* ) (client, transaction_pool) )? - } - - fn build_light_rpc_extensions( - client: Arc<$crate::LightClient>, - transaction_pool: Arc<$crate::TransactionPool>, - ) -> Self::RpcExtensions { - $( ( $( $rpc_extensions )* ) (client, transaction_pool) )? - } - } - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/core/service/test/src/lib.rs b/core/service/test/src/lib.rs index c2895c5329..870f287bff 100644 --- a/core/service/test/src/lib.rs +++ b/core/service/test/src/lib.rs @@ -27,32 +27,31 @@ use tempdir::TempDir; use tokio::{runtime::Runtime, prelude::FutureExt}; use tokio::timer::Interval; use service::{ - ServiceFactory, + AbstractService, + ChainSpec, Configuration, - FactoryFullConfiguration, - FactoryChainSpec, Roles, - FactoryExtrinsic, + Error, }; use network::{multiaddr, Multiaddr}; use network::config::{NetworkConfiguration, TransportConfig, NodeKeyConfig, Secret, NonReservedPeerMode}; -use sr_primitives::generic::BlockId; +use sr_primitives::{generic::BlockId, traits::Block as BlockT}; use consensus::{BlockImportParams, BlockImport}; /// Maximum duration of single wait call. const MAX_WAIT_TIME: Duration = Duration::from_secs(60 * 3); -struct TestNet { +struct TestNet { runtime: Runtime, - authority_nodes: Vec<(usize, SyncService, Multiaddr)>, - full_nodes: Vec<(usize, SyncService, Multiaddr)>, - light_nodes: Vec<(usize, SyncService, Multiaddr)>, - chain_spec: FactoryChainSpec, + authority_nodes: Vec<(usize, SyncService, U, Multiaddr)>, + full_nodes: Vec<(usize, SyncService, U, Multiaddr)>, + light_nodes: Vec<(usize, SyncService, Multiaddr)>, + chain_spec: ChainSpec, base_port: u16, nodes: usize, } -/// Wraps around an `Arc>` and implements `Future`. +/// Wraps around an `Arc` and implements `Future`. pub struct SyncService(Arc>); impl SyncService { @@ -82,22 +81,24 @@ impl> Future for SyncService { } } -impl TestNet { +impl TestNet +where F: Send + 'static, L: Send +'static, U: Clone + Send + 'static +{ pub fn run_until_all_full( &mut self, full_predicate: FP, light_predicate: LP, ) where - FP: Send + Fn(usize, &SyncService) -> bool + 'static, - LP: Send + Fn(usize, &SyncService) -> bool + 'static, + FP: Send + Fn(usize, &SyncService) -> bool + 'static, + LP: Send + Fn(usize, &SyncService) -> bool + 'static, { let full_nodes = self.full_nodes.clone(); let light_nodes = self.light_nodes.clone(); let interval = Interval::new_interval(Duration::from_millis(100)) .map_err(|_| ()) .for_each(move |_| { - let full_ready = full_nodes.iter().all(|&(ref id, ref service, _)| + let full_ready = full_nodes.iter().all(|&(ref id, ref service, _, _)| full_predicate(*id, service) ); @@ -125,14 +126,14 @@ impl TestNet { } } -fn node_config ( +fn node_config ( index: usize, - spec: &FactoryChainSpec, + spec: &ChainSpec, role: Roles, key_seed: Option, base_port: u16, root: &TempDir, -) -> FactoryFullConfiguration +) -> Configuration<(), G> { let root = root.path().join(format!("node-{}", index)); @@ -194,18 +195,18 @@ fn node_config ( } } -impl TestNet where - F::FullService: Future, - F::LightService: Future, +impl TestNet where + F: AbstractService, + L: AbstractService, { fn new( temp: &TempDir, - spec: FactoryChainSpec, - full: usize, - light: usize, - authorities: Vec, + spec: ChainSpec, + full: impl Iterator) -> Result<(F, U), Error>>, + light: impl Iterator) -> Result>, + authorities: impl Iterator) -> Result<(F, U), Error>)>, base_port: u16 - ) -> TestNet { + ) -> TestNet { let _ = env_logger::try_init(); fdlimit::raise_fd_limit(); let runtime = Runtime::new().expect("Error creating tokio runtime"); @@ -222,79 +223,89 @@ impl TestNet where net } - fn insert_nodes(&mut self, temp: &TempDir, full: usize, light: usize, authorities: Vec) { - let mut nodes = self.nodes; - let base_port = self.base_port; - let spec = &self.chain_spec; + fn insert_nodes( + &mut self, + temp: &TempDir, + full: impl Iterator) -> Result<(F, U), Error>>, + light: impl Iterator) -> Result>, + authorities: impl Iterator) -> Result<(F, U), Error>)> + ) { let executor = self.runtime.executor(); - self.authority_nodes.extend(authorities.iter().enumerate().map(|(index, key)| { - let node_config = node_config::( - index, - &spec, + + for (key, authority) in authorities { + let node_config = node_config( + self.nodes, + &self.chain_spec, Roles::AUTHORITY, - Some(key.clone()), - base_port, + Some(key), + self.base_port, &temp, ); let addr = node_config.network.listen_addresses.iter().next().unwrap().clone(); - let service = SyncService::from(F::new_full(node_config).expect("Error creating test node service")); + let (service, user_data) = authority(node_config).expect("Error creating test node service"); + let service = SyncService::from(service); executor.spawn(service.clone().map_err(|_| ())); let addr = addr.with(multiaddr::Protocol::P2p(service.get().network().local_peer_id().into())); - ((index + nodes), service, addr) - })); - nodes += authorities.len(); + self.authority_nodes.push((self.nodes, service, user_data, addr)); + self.nodes += 1; + } - self.full_nodes.extend((nodes..nodes + full).map(|index| { - let node_config = node_config::(index, &spec, Roles::FULL, None, base_port, &temp); + for full in full { + let node_config = node_config(self.nodes, &self.chain_spec, Roles::FULL, None, self.base_port, &temp); let addr = node_config.network.listen_addresses.iter().next().unwrap().clone(); - let service = SyncService::from(F::new_full(node_config).expect("Error creating test node service")); + let (service, user_data) = full(node_config).expect("Error creating test node service"); + let service = SyncService::from(service); executor.spawn(service.clone().map_err(|_| ())); let addr = addr.with(multiaddr::Protocol::P2p(service.get().network().local_peer_id().into())); - (index, service, addr) - })); - nodes += full; + self.full_nodes.push((self.nodes, service, user_data, addr)); + self.nodes += 1; + } - self.light_nodes.extend((nodes..nodes + light).map(|index| { - let node_config = node_config::(index, &spec, Roles::LIGHT, None, base_port, &temp); + for light in light { + let node_config = node_config(self.nodes, &self.chain_spec, Roles::LIGHT, None, self.base_port, &temp); let addr = node_config.network.listen_addresses.iter().next().unwrap().clone(); - let service = SyncService::from(F::new_light(node_config).expect("Error creating test node service")); + let service = SyncService::from(light(node_config).expect("Error creating test node service")); executor.spawn(service.clone().map_err(|_| ())); let addr = addr.with(multiaddr::Protocol::P2p(service.get().network().local_peer_id().into())); - (index, service, addr) - })); - nodes += light; - - self.nodes = nodes; + self.light_nodes.push((self.nodes, service, addr)); + self.nodes += 1; + } } } -pub fn connectivity(spec: FactoryChainSpec) where - F::FullService: Future, - F::LightService: Future, +pub fn connectivity(spec: ChainSpec, full_builder: Fb, light_builder: Lb) where + Fb: Fn(Configuration<(), G>) -> Result, + F: AbstractService, + Lb: Fn(Configuration<(), G>) -> Result, + L: AbstractService, { const NUM_FULL_NODES: usize = 5; const NUM_LIGHT_NODES: usize = 5; { let temp = TempDir::new("substrate-connectivity-test").expect("Error creating test dir"); let runtime = { - let mut network = TestNet::::new( + let mut network = TestNet::new( &temp, spec.clone(), - NUM_FULL_NODES, - NUM_LIGHT_NODES, - vec![], + (0..NUM_FULL_NODES).map(|_| { |cfg| full_builder(cfg).map(|s| (s, ())) }), + (0..NUM_LIGHT_NODES).map(|_| { |cfg| light_builder(cfg) }), + // Note: this iterator is empty but we can't just use `iter::empty()`, otherwise + // the type of the closure cannot be inferred. + (0..0).map(|_| (String::new(), { |cfg| full_builder(cfg).map(|s| (s, ())) })), 30400, ); info!("Checking star topology"); - let first_address = network.full_nodes[0].2.clone(); - for (_, service, _) in network.full_nodes.iter().skip(1) { - service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); + let first_address = network.full_nodes[0].3.clone(); + for (_, service, _, _) in network.full_nodes.iter().skip(1) { + service.get().network().add_reserved_peer(first_address.to_string()) + .expect("Error adding reserved peer"); } for (_, service, _) in network.light_nodes.iter() { - service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); + service.get().network().add_reserved_peer(first_address.to_string()) + .expect("Error adding reserved peer"); } network.run_until_all_full( |_index, service| service.get().network().num_connected() == NUM_FULL_NODES - 1 @@ -311,27 +322,31 @@ pub fn connectivity(spec: FactoryChainSpec) where { let temp = TempDir::new("substrate-connectivity-test").expect("Error creating test dir"); { - let mut network = TestNet::::new( + let mut network = TestNet::new( &temp, spec, - NUM_FULL_NODES, - NUM_LIGHT_NODES, - vec![], + (0..NUM_FULL_NODES).map(|_| { |cfg| full_builder(cfg).map(|s| (s, ())) }), + (0..NUM_LIGHT_NODES).map(|_| { |cfg| light_builder(cfg) }), + // Note: this iterator is empty but we can't just use `iter::empty()`, otherwise + // the type of the closure cannot be inferred. + (0..0).map(|_| (String::new(), { |cfg| full_builder(cfg).map(|s| (s, ())) })), 30400, ); info!("Checking linked topology"); - let mut address = network.full_nodes[0].2.clone(); + let mut address = network.full_nodes[0].3.clone(); let max_nodes = std::cmp::max(NUM_FULL_NODES, NUM_LIGHT_NODES); for i in 0..max_nodes { if i != 0 { - if let Some((_, service, node_id)) = network.full_nodes.get(i) { - service.get().network().add_reserved_peer(address.to_string()).expect("Error adding reserved peer"); + if let Some((_, service, _, node_id)) = network.full_nodes.get(i) { + service.get().network().add_reserved_peer(address.to_string()) + .expect("Error adding reserved peer"); address = node_id.clone(); } } if let Some((_, service, node_id)) = network.light_nodes.get(i) { - service.get().network().add_reserved_peer(address.to_string()).expect("Error adding reserved peer"); + service.get().network().add_reserved_peer(address.to_string()) + .expect("Error adding reserved peer"); address = node_id.clone(); } } @@ -345,42 +360,53 @@ pub fn connectivity(spec: FactoryChainSpec) where } } -pub fn sync(spec: FactoryChainSpec, mut block_factory: B, mut extrinsic_factory: E) where - F: ServiceFactory, - F::FullService: Future, - F::LightService: Future, - B: FnMut(&SyncService) -> BlockImportParams, - E: FnMut(&SyncService) -> FactoryExtrinsic, +pub fn sync( + spec: ChainSpec, + full_builder: Fb, + light_builder: Lb, + mut block_factory: B, + mut extrinsic_factory: E +) where + Fb: Fn(Configuration<(), G>) -> Result<(F, U), Error>, + F: AbstractService, + Lb: Fn(Configuration<(), G>) -> Result, + L: AbstractService, + B: FnMut(&F, &U) -> BlockImportParams, + E: FnMut(&F, &U) -> ::Extrinsic, + U: Clone + Send + 'static, { const NUM_FULL_NODES: usize = 10; // FIXME: BABE light client support is currently not working. const NUM_LIGHT_NODES: usize = 10; const NUM_BLOCKS: usize = 512; let temp = TempDir::new("substrate-sync-test").expect("Error creating test dir"); - let mut network = TestNet::::new( + let mut network = TestNet::new( &temp, spec.clone(), - NUM_FULL_NODES, - NUM_LIGHT_NODES, - vec![], + (0..NUM_FULL_NODES).map(|_| { |cfg| full_builder(cfg) }), + (0..NUM_LIGHT_NODES).map(|_| { |cfg| light_builder(cfg) }), + // Note: this iterator is empty but we can't just use `iter::empty()`, otherwise + // the type of the closure cannot be inferred. + (0..0).map(|_| (String::new(), { |cfg| full_builder(cfg) })), 30500, ); info!("Checking block sync"); let first_address = { let first_service = &network.full_nodes[0].1; + let first_user_data = &network.full_nodes[0].2; let mut client = first_service.get().client(); for i in 0 .. NUM_BLOCKS { if i % 128 == 0 { info!("Generating #{}", i); } - let import_data = block_factory(&first_service); + let import_data = block_factory(&first_service.get(), first_user_data); client.import_block(import_data, HashMap::new()).expect("Error importing test block"); } - network.full_nodes[0].2.clone() + network.full_nodes[0].3.clone() }; info!("Running sync"); - for (_, service, _) in network.full_nodes.iter().skip(1) { + for (_, service, _, _) in network.full_nodes.iter().skip(1) { service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); } for (_, service, _) in network.light_nodes.iter() { @@ -395,8 +421,9 @@ pub fn sync(spec: FactoryChainSpec, mut block_factory: B, mut extrin info!("Checking extrinsic propagation"); let first_service = network.full_nodes[0].1.clone(); + let first_user_data = &network.full_nodes[0].2; let best_block = BlockId::number(first_service.get().client().info().chain.best_number); - let extrinsic = extrinsic_factory(&first_service); + let extrinsic = extrinsic_factory(&first_service.get(), first_user_data); first_service.get().transaction_pool().submit_one(&best_block, extrinsic).unwrap(); network.run_until_all_full( |_index, service| service.get().transaction_pool().ready().count() == 1, @@ -404,33 +431,39 @@ pub fn sync(spec: FactoryChainSpec, mut block_factory: B, mut extrin ); } -pub fn consensus(spec: FactoryChainSpec, authorities: Vec) where - F: ServiceFactory, - F::FullService: Future, - F::LightService: Future, +pub fn consensus( + spec: ChainSpec, + full_builder: Fb, + light_builder: Lb, + authorities: impl IntoIterator +) where + Fb: Fn(Configuration<(), G>) -> Result, + F: AbstractService, + Lb: Fn(Configuration<(), G>) -> Result, + L: AbstractService, { const NUM_FULL_NODES: usize = 10; const NUM_LIGHT_NODES: usize = 10; const NUM_BLOCKS: usize = 10; // 10 * 2 sec block production time = ~20 seconds let temp = TempDir::new("substrate-conensus-test").expect("Error creating test dir"); - let mut network = TestNet::::new( + let mut network = TestNet::new( &temp, spec.clone(), - NUM_FULL_NODES / 2, - NUM_LIGHT_NODES / 2, - authorities, + (0..NUM_FULL_NODES / 2).map(|_| { |cfg| full_builder(cfg).map(|s| (s, ())) }), + (0..NUM_LIGHT_NODES / 2).map(|_| { |cfg| light_builder(cfg) }), + authorities.into_iter().map(|key| (key, { |cfg| full_builder(cfg).map(|s| (s, ())) })), 30600, ); info!("Checking consensus"); - let first_address = network.authority_nodes[0].2.clone(); - for (_, service, _) in network.full_nodes.iter() { + let first_address = network.authority_nodes[0].3.clone(); + for (_, service, _, _) in network.full_nodes.iter() { service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); } for (_, service, _) in network.light_nodes.iter() { service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); } - for (_, service, _) in network.authority_nodes.iter().skip(1) { + for (_, service, _, _) in network.authority_nodes.iter().skip(1) { service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); } network.run_until_all_full( @@ -441,8 +474,15 @@ pub fn consensus(spec: FactoryChainSpec, authorities: Vec) where ); info!("Adding more peers"); - network.insert_nodes(&temp, NUM_FULL_NODES / 2, NUM_LIGHT_NODES / 2, vec![]); - for (_, service, _) in network.full_nodes.iter() { + network.insert_nodes( + &temp, + (0..NUM_FULL_NODES / 2).map(|_| { |cfg| full_builder(cfg).map(|s| (s, ())) }), + (0..NUM_LIGHT_NODES / 2).map(|_| { |cfg| light_builder(cfg) }), + // Note: this iterator is empty but we can't just use `iter::empty()`, otherwise + // the type of the closure cannot be inferred. + (0..0).map(|_| (String::new(), { |cfg| full_builder(cfg).map(|s| (s, ())) })), + ); + for (_, service, _, _) in network.full_nodes.iter() { service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); } for (_, service, _) in network.light_nodes.iter() { diff --git a/node-template/src/cli.rs b/node-template/src/cli.rs index 4d672491c1..f6edbb2cc3 100644 --- a/node-template/src/cli.rs +++ b/node-template/src/cli.rs @@ -4,9 +4,8 @@ use std::cell::RefCell; use tokio::runtime::Runtime; pub use substrate_cli::{VersionInfo, IntoExit, error}; use substrate_cli::{informant, parse_and_prepare, ParseAndPrepare, NoCustom}; -use substrate_service::{ServiceFactory, Roles as ServiceRoles}; +use substrate_service::{AbstractService, Roles as ServiceRoles}; use crate::chain_spec; -use std::ops::Deref; use log::info; /// Parse command line arguments into service configuration. @@ -16,7 +15,8 @@ pub fn run(args: I, exit: E, version: VersionInfo) -> error::Result<()> E: IntoExit, { match parse_and_prepare::(&version, "substrate-node", args) { - ParseAndPrepare::Run(cmd) => cmd.run(load_spec, exit, |exit, _cli_args, _custom_args, config| { + ParseAndPrepare::Run(cmd) => cmd.run::<(), _, _, _, _>(load_spec, exit, + |exit, _cli_args, _custom_args, config| { info!("{}", version.name); info!(" version {}", config.full_version()); info!(" by {}, 2017, 2018", version.author); @@ -27,21 +27,24 @@ pub fn run(args: I, exit: E, version: VersionInfo) -> error::Result<()> match config.roles { ServiceRoles::LIGHT => run_until_exit( runtime, - service::Factory::new_light(config).map_err(|e| format!("{:?}", e))?, + service::new_light(config).map_err(|e| format!("{:?}", e))?, exit ), _ => run_until_exit( runtime, - service::Factory::new_full(config).map_err(|e| format!("{:?}", e))?, + service::new_full(config).map_err(|e| format!("{:?}", e))?, exit ), }.map_err(|e| format!("{:?}", e)) }), ParseAndPrepare::BuildSpec(cmd) => cmd.run(load_spec), - ParseAndPrepare::ExportBlocks(cmd) => cmd.run::(load_spec, exit), - ParseAndPrepare::ImportBlocks(cmd) => cmd.run::(load_spec, exit), + ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder::<(), _, _, _, _, _>(|config| + Ok(new_full_start!(config).0), load_spec, exit), + ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder::<(), _, _, _, _, _>(|config| + Ok(new_full_start!(config).0), load_spec, exit), ParseAndPrepare::PurgeChain(cmd) => cmd.run(load_spec), - ParseAndPrepare::RevertChain(cmd) => cmd.run::(load_spec), + ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder::<(), _, _, _, _>(|config| + Ok(new_full_start!(config).0), load_spec), ParseAndPrepare::CustomCommand(_) => Ok(()) }?; @@ -55,14 +58,13 @@ fn load_spec(id: &str) -> Result, String> { }) } -fn run_until_exit( +fn run_until_exit( mut runtime: Runtime, service: T, e: E, -) -> error::Result<()> where - T: Deref>, - T: Future + Send + 'static, - C: substrate_service::Components, +) -> error::Result<()> +where + T: AbstractService, E: IntoExit, { let (exit_send, exit) = exit_future::signal(); @@ -99,7 +101,8 @@ impl IntoExit for Exit { let exit_send_cell = RefCell::new(Some(exit_send)); ctrlc::set_handler(move || { - if let Some(exit_send) = exit_send_cell.try_borrow_mut().expect("signal handler not reentrant; qed").take() { + let exit_send = exit_send_cell.try_borrow_mut().expect("signal handler not reentrant; qed").take(); + if let Some(exit_send) = exit_send { exit_send.send(()).expect("Error sending exit notification"); } }).expect("Error setting Ctrl-C handler"); diff --git a/node-template/src/main.rs b/node-template/src/main.rs index 18e9638833..024efcc7db 100644 --- a/node-template/src/main.rs +++ b/node-template/src/main.rs @@ -4,6 +4,7 @@ #![warn(unused_extern_crates)] mod chain_spec; +#[macro_use] mod service; mod cli; diff --git a/node-template/src/service.rs b/node-template/src/service.rs index 2baa0c7631..07c0aa26cf 100644 --- a/node-template/src/service.rs +++ b/node-template/src/service.rs @@ -1,24 +1,17 @@ -#![warn(unused_extern_crates)] - //! Service and ServiceFactory implementation. Specialized wrapper over substrate service. use std::sync::Arc; use std::time::Duration; -use substrate_client::{self as client, LongestChain}; -use babe::{import_queue, start_babe, BabeImportQueue, Config}; +use substrate_client::LongestChain; +use babe::{import_queue, start_babe, Config}; use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; use futures::prelude::*; use node_template_runtime::{self, GenesisConfig, opaque::Block, RuntimeApi, WASM_BINARY}; -use substrate_service::{ - FactoryFullConfiguration, LightComponents, FullComponents, FullBackend, - FullClient, LightClient, LightBackend, FullExecutor, LightExecutor, - error::{Error as ServiceError}, -}; +use substrate_service::{error::{Error as ServiceError}, AbstractService, Configuration, ServiceBuilder}; use transaction_pool::{self, txpool::{Pool as TransactionPool}}; use inherents::InherentDataProviders; use network::construct_simple_protocol; use substrate_executor::native_executor_instance; -use substrate_service::{ServiceFactory, construct_service_factory, TelemetryOnConnect}; pub use substrate_executor::NativeExecutor; // Our native executor instance. @@ -34,235 +27,205 @@ construct_simple_protocol! { pub struct NodeProtocol where Block = Block { } } -type BabeBlockImportForService = babe::BabeBlockImport< - FullBackend, - FullExecutor, - ::Block, - grandpa::BlockImportForService, - ::RuntimeApi, - client::Client< - FullBackend, - FullExecutor, - ::Block, - ::RuntimeApi - >, ->; - -pub struct NodeConfig { - /// GRANDPA and BABE connection to import block. - // FIXME #1134 rather than putting this on the config, let's have an actual intermediate setup state - pub import_setup: Option<( - BabeBlockImportForService, - grandpa::LinkHalfForService, - babe::BabeLink, - )>, - /// Tasks that were created by previous setup steps and should be spawned. - pub tasks_to_spawn: Option + Send>>>, - inherent_data_providers: InherentDataProviders, -} - -impl Default for NodeConfig where F: ServiceFactory { - fn default() -> NodeConfig { - NodeConfig { - import_setup: None, - inherent_data_providers: InherentDataProviders::new(), - tasks_to_spawn: None, - } - } -} - -construct_service_factory! { - struct Factory { - Block = Block, - RuntimeApi = RuntimeApi, - NetworkProtocol = NodeProtocol { |config| Ok(NodeProtocol::new()) }, - RuntimeDispatch = Executor, - FullTransactionPoolApi = - transaction_pool::ChainApi< - client::Client, FullExecutor, Block, RuntimeApi>, - Block - > { - |config, client| - Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) - }, - LightTransactionPoolApi = - transaction_pool::ChainApi< - client::Client, LightExecutor, Block, RuntimeApi>, - Block - > { - |config, client| - Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) - }, - Genesis = GenesisConfig, - Configuration = NodeConfig, - FullService = FullComponents { - |config: FactoryFullConfiguration| FullComponents::::new(config) - }, - AuthoritySetup = { - |mut service: Self::FullService| { - let (block_import, link_half, babe_link) = - service.config_mut().custom.import_setup.take() - .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); - - // spawn any futures that were created in the previous setup steps - if let Some(tasks) = service.config_mut().custom.tasks_to_spawn.take() { - for task in tasks { - service.spawn_task( - task.select(service.on_exit()) - .map(|_| ()) - .map_err(|_| ()) - ); - } - } - - if service.config().roles.is_authority() { - let proposer = basic_authorship::ProposerFactory { - client: service.client(), - transaction_pool: service.transaction_pool(), - }; - - let client = service.client(); - let select_chain = service.select_chain() - .ok_or(ServiceError::SelectChainRequired)?; - - let babe_config = babe::BabeParams { - config: Config::get_or_compute(&*client)?, - keystore: service.keystore(), - client, - select_chain, - block_import, - env: proposer, - sync_oracle: service.network(), - inherent_data_providers: service.config() - .custom.inherent_data_providers.clone(), - force_authoring: service.config().force_authoring, - time_source: babe_link, - }; - - let babe = start_babe(babe_config)?; - let select = babe.select(service.on_exit()).then(|_| Ok(())); - - // the BABE authoring task is considered infallible, i.e. if it - // fails we take down the service with it. - service.spawn_essential_task(select); - } - - let config = grandpa::Config { - // FIXME #1578 make this available through chainspec - gossip_duration: Duration::from_millis(333), - justification_period: 4096, - name: Some(service.config().name.clone()), - keystore: Some(service.keystore()), - }; - - match (service.config().roles.is_authority(), service.config().disable_grandpa) { - (false, false) => { - // start the lightweight GRANDPA observer - service.spawn_task(Box::new(grandpa::run_grandpa_observer( - config, - link_half, - service.network(), - service.on_exit(), - )?)); - }, - (true, false) => { - // start the full GRANDPA voter - let telemetry_on_connect = TelemetryOnConnect { - telemetry_connection_sinks: service.telemetry_on_connect_stream(), - }; - let grandpa_config = grandpa::GrandpaParams { - config: config, - link: link_half, - network: service.network(), - inherent_data_providers: - service.config().custom.inherent_data_providers.clone(), - on_exit: service.on_exit(), - telemetry_on_connect: Some(telemetry_on_connect), - }; - - // the GRANDPA voter task is considered infallible, i.e. - // if it fails we take down the service with it. - service.spawn_essential_task(grandpa::run_grandpa_voter(grandpa_config)?); - }, - (_, true) => { - grandpa::setup_disabled_grandpa( - service.client(), - &service.config().custom.inherent_data_providers, - service.network(), - )?; - }, - } - - Ok(service) - } - }, - LightService = LightComponents - { |config| >::new(config) }, - FullImportQueue = BabeImportQueue { - | - config: &mut FactoryFullConfiguration, - client: Arc>, - select_chain: Self::SelectChain, - transaction_pool: Option>>, - | { +/// Starts a `ServiceBuilder` for a full service. +/// +/// Use this macro if you don't actually need the full service, but just the builder in order to +/// be able to perform chain operations. +macro_rules! new_full_start { + ($config:expr) => {{ + let mut import_setup = None; + let inherent_data_providers = inherents::InherentDataProviders::new(); + let mut tasks_to_spawn = None; + + let builder = substrate_service::ServiceBuilder::new_full::< + node_template_runtime::opaque::Block, node_template_runtime::RuntimeApi, crate::service::Executor + >($config)? + .with_select_chain(|_config, client| { + #[allow(deprecated)] + Ok(substrate_client::LongestChain::new(client.backend().clone())) + })? + .with_transaction_pool(|config, client| + Ok(transaction_pool::txpool::Pool::new(config, transaction_pool::ChainApi::new(client))) + )? + .with_import_queue(|_config, client, mut select_chain, transaction_pool| { + let select_chain = select_chain.take() + .ok_or_else(|| substrate_service::Error::SelectChainRequired)?; let (block_import, link_half) = - grandpa::block_import::<_, _, _, RuntimeApi, FullClient, _>( + grandpa::block_import::<_, _, _, node_template_runtime::RuntimeApi, _, _>( client.clone(), client.clone(), select_chain )?; let justification_import = block_import.clone(); - let (import_queue, babe_link, babe_block_import, pruning_task) = import_queue( - Config::get_or_compute(&*client)?, + + let (import_queue, babe_link, babe_block_import, pruning_task) = babe::import_queue( + babe::Config::get_or_compute(&*client)?, block_import, Some(Box::new(justification_import)), None, client.clone(), client, - config.custom.inherent_data_providers.clone(), - transaction_pool, + inherent_data_providers.clone(), + Some(transaction_pool) )?; - config.custom.import_setup = Some((babe_block_import.clone(), link_half, babe_link)); - config.custom.tasks_to_spawn = Some(vec![Box::new(pruning_task)]); + + import_setup = Some((babe_block_import.clone(), link_half, babe_link)); + tasks_to_spawn = Some(vec![Box::new(pruning_task)]); + Ok(import_queue) - } - }, - LightImportQueue = BabeImportQueue - { |config: &FactoryFullConfiguration, client: Arc>| { - #[allow(deprecated)] - let fetch_checker = client.backend().blockchain().fetcher() - .upgrade() - .map(|fetcher| fetcher.checker().clone()) - .ok_or_else(|| "Trying to start light import queue without active fetch checker")?; - let block_import = grandpa::light_block_import::<_, _, _, RuntimeApi, LightClient>( - client.clone(), Arc::new(fetch_checker), client.clone() - )?; + })?; + + (builder, import_setup, inherent_data_providers, tasks_to_spawn) + }} +} - let finality_proof_import = block_import.clone(); - let finality_proof_request_builder = - finality_proof_import.create_finality_proof_request_builder(); +/// Builds a new service for a full client. +pub fn new_full(config: Configuration) + -> Result +{ + + let (builder, mut import_setup, inherent_data_providers, mut tasks_to_spawn) = new_full_start!(config); + + let service = builder.with_network_protocol(|_| Ok(NodeProtocol::new()))? + .with_finality_proof_provider(|client| + Ok(Arc::new(GrandpaFinalityProofProvider::new(client.clone(), client)) as _) + )? + .build()?; + + let (block_import, link_half, babe_link) = + import_setup.take() + .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); + + // spawn any futures that were created in the previous setup steps + if let Some(tasks) = tasks_to_spawn.take() { + for task in tasks { + service.spawn_task( + task.select(service.on_exit()) + .map(|_| ()) + .map_err(|_| ()) + ); + } + } - // FIXME: pruning task isn't started since light client doesn't do `AuthoritySetup`. - let (import_queue, ..) = import_queue::<_, _, _, _, _, _, TransactionPool>( - Config::get_or_compute(&*client)?, - block_import, - None, - Some(Box::new(finality_proof_import)), - client.clone(), - client, - config.custom.inherent_data_providers.clone(), - None, - )?; + if service.config().roles.is_authority() { + let proposer = basic_authorship::ProposerFactory { + client: service.client(), + transaction_pool: service.transaction_pool(), + }; + + let client = service.client(); + let select_chain = service.select_chain() + .ok_or(ServiceError::SelectChainRequired)?; + + let babe_config = babe::BabeParams { + config: Config::get_or_compute(&*client)?, + keystore: service.keystore(), + client, + select_chain, + block_import, + env: proposer, + sync_oracle: service.network(), + inherent_data_providers: inherent_data_providers.clone(), + force_authoring: service.config().force_authoring, + time_source: babe_link, + }; + + let babe = start_babe(babe_config)?; + let select = babe.select(service.on_exit()).then(|_| Ok(())); + + // the BABE authoring task is considered infallible, i.e. if it + // fails we take down the service with it. + service.spawn_essential_task(select); + } - Ok((import_queue, finality_proof_request_builder)) - }}, - SelectChain = LongestChain, Self::Block> - { |config: &FactoryFullConfiguration, client: Arc>| { - #[allow(deprecated)] - Ok(LongestChain::new(client.backend().clone())) - } + let config = grandpa::Config { + // FIXME #1578 make this available through chainspec + gossip_duration: Duration::from_millis(333), + justification_period: 4096, + name: Some(service.config().name.clone()), + keystore: Some(service.keystore()), + }; + + match (service.config().roles.is_authority(), service.config().disable_grandpa) { + (false, false) => { + // start the lightweight GRANDPA observer + service.spawn_task(Box::new(grandpa::run_grandpa_observer( + config, + link_half, + service.network(), + service.on_exit(), + )?)); + }, + (true, false) => { + // start the full GRANDPA voter + let grandpa_config = grandpa::GrandpaParams { + config: config, + link: link_half, + network: service.network(), + inherent_data_providers: inherent_data_providers.clone(), + on_exit: service.on_exit(), + telemetry_on_connect: Some(service.telemetry_on_connect_stream()), + }; + + // the GRANDPA voter task is considered infallible, i.e. + // if it fails we take down the service with it. + service.spawn_essential_task(grandpa::run_grandpa_voter(grandpa_config)?); + }, + (_, true) => { + grandpa::setup_disabled_grandpa( + service.client(), + &inherent_data_providers, + service.network(), + )?; }, - FinalityProofProvider = { |client: Arc>| { - Ok(Some(Arc::new(GrandpaFinalityProofProvider::new(client.clone(), client)) as _)) - }}, - RpcExtensions = (), } + + Ok(service) +} + +/// Builds a new service for a light client. +pub fn new_light(config: Configuration) + -> Result +{ + let inherent_data_providers = InherentDataProviders::new(); + + ServiceBuilder::new_light::(config)? + .with_select_chain(|_config, client| { + #[allow(deprecated)] + Ok(LongestChain::new(client.backend().clone())) + })? + .with_transaction_pool(|config, client| + Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) + )? + .with_import_queue_and_fprb(|_config, client, _select_chain, transaction_pool| { + #[allow(deprecated)] + let fetch_checker = client.backend().blockchain().fetcher() + .upgrade() + .map(|fetcher| fetcher.checker().clone()) + .ok_or_else(|| "Trying to start light import queue without active fetch checker")?; + let block_import = grandpa::light_block_import::<_, _, _, RuntimeApi, _>( + client.clone(), Arc::new(fetch_checker), client.clone() + )?; + + let finality_proof_import = block_import.clone(); + let finality_proof_request_builder = + finality_proof_import.create_finality_proof_request_builder(); + + // FIXME: pruning task isn't started since light client doesn't do `AuthoritySetup`. + let (import_queue, ..) = import_queue( + Config::get_or_compute(&*client)?, + block_import, + None, + Some(Box::new(finality_proof_import)), + client.clone(), + client, + inherent_data_providers.clone(), + Some(transaction_pool) + )?; + + Ok((import_queue, finality_proof_request_builder)) + })? + .with_network_protocol(|_| Ok(NodeProtocol::new()))? + .with_finality_proof_provider(|client| + Ok(Arc::new(GrandpaFinalityProofProvider::new(client.clone(), client)) as _) + )? + .build() } diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index 7b4ebb0c5f..1f35f7b86b 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -11,7 +11,7 @@ log = "0.4" tokio = "0.1.7" futures = "0.1" exit-future = "0.1" -jsonrpc-core = "13.0.0" +jsonrpc-core = "13.1.0" cli = { package = "substrate-cli", path = "../../core/cli" } codec = { package = "parity-scale-codec", version = "1.0.0" } sr-io = { path = "../../core/sr-io" } diff --git a/node/cli/src/chain_spec.rs b/node/cli/src/chain_spec.rs index fca4c78b89..f83958eef4 100644 --- a/node/cli/src/chain_spec.rs +++ b/node/cli/src/chain_spec.rs @@ -350,8 +350,8 @@ pub fn local_testnet_config() -> ChainSpec { #[cfg(test)] pub(crate) mod tests { use super::*; + use crate::service::{new_full, new_light}; use service_test; - use crate::service::Factory; fn local_testnet_genesis_instant_single() -> GenesisConfig { testnet_genesis( @@ -395,6 +395,10 @@ pub(crate) mod tests { #[test] #[ignore] fn test_connectivity() { - service_test::connectivity::(integration_test_config_with_two_authorities()); + service_test::connectivity( + integration_test_config_with_two_authorities(), + |config| new_full(config), + |config| new_light(config), + ); } } diff --git a/node/cli/src/lib.rs b/node/cli/src/lib.rs index 4e3cfa7f01..b7679be176 100644 --- a/node/cli/src/lib.rs +++ b/node/cli/src/lib.rs @@ -21,14 +21,14 @@ pub use cli::error; pub mod chain_spec; +#[macro_use] mod service; mod factory_impl; use tokio::prelude::Future; use tokio::runtime::{Builder as RuntimeBuilder, Runtime}; pub use cli::{VersionInfo, IntoExit, NoCustom, SharedParams, ExecutionStrategyParam}; -use substrate_service::{ServiceFactory, Roles as ServiceRoles}; -use std::ops::Deref; +use substrate_service::{AbstractService, Roles as ServiceRoles}; use log::info; use structopt::{StructOpt, clap::App}; use cli::{AugmentClap, GetLogFilter, parse_and_prepare, ParseAndPrepare}; @@ -159,7 +159,8 @@ pub fn run(args: I, exit: E, version: cli::VersionInfo) -> error::Resul E: IntoExit, { match parse_and_prepare::(&version, "substrate-node", args) { - ParseAndPrepare::Run(cmd) => cmd.run(load_spec, exit, |exit, _cli_args, _custom_args, config| { + ParseAndPrepare::Run(cmd) => cmd.run::<(), _, _, _, _>(load_spec, exit, + |exit, _cli_args, _custom_args, config| { info!("{}", version.name); info!(" version {}", config.full_version()); info!(" by Parity Technologies, 2017-2019"); @@ -171,23 +172,26 @@ pub fn run(args: I, exit: E, version: cli::VersionInfo) -> error::Resul match config.roles { ServiceRoles::LIGHT => run_until_exit( runtime, - service::Factory::new_light(config).map_err(|e| format!("{:?}", e))?, + service::new_light(config).map_err(|e| format!("{:?}", e))?, exit ), _ => run_until_exit( runtime, - service::Factory::new_full(config).map_err(|e| format!("{:?}", e))?, + service::new_full(config).map_err(|e| format!("{:?}", e))?, exit ), }.map_err(|e| format!("{:?}", e)) }), ParseAndPrepare::BuildSpec(cmd) => cmd.run(load_spec), - ParseAndPrepare::ExportBlocks(cmd) => cmd.run::(load_spec, exit), - ParseAndPrepare::ImportBlocks(cmd) => cmd.run::(load_spec, exit), + ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder::<(), _, _, _, _, _>(|config| + Ok(new_full_start!(config).0), load_spec, exit), + ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder::<(), _, _, _, _, _>(|config| + Ok(new_full_start!(config).0), load_spec, exit), ParseAndPrepare::PurgeChain(cmd) => cmd.run(load_spec), - ParseAndPrepare::RevertChain(cmd) => cmd.run::(load_spec), + ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder::<(), _, _, _, _>(|config| + Ok(new_full_start!(config).0), load_spec), ParseAndPrepare::CustomCommand(CustomSubcommands::Factory(cli_args)) => { - let mut config = cli::create_config_with_db_path( + let mut config = cli::create_config_with_db_path::<(), _, _>( load_spec, &cli_args.shared_params, &version, @@ -209,9 +213,13 @@ pub fn run(args: I, exit: E, version: cli::VersionInfo) -> error::Resul cli_args.num, cli_args.rounds, ); - transaction_factory::factory::>( + + let service_builder = new_full_start!(config).0; + transaction_factory::factory::, _, _, _, _, _>( factory_state, - config, + service_builder.client(), + service_builder.select_chain() + .expect("The select_chain is always initialized by new_full_start!; QED") ).map_err(|e| format!("Error in transaction factory: {}", e))?; Ok(()) @@ -219,14 +227,13 @@ pub fn run(args: I, exit: E, version: cli::VersionInfo) -> error::Resul } } -fn run_until_exit( +fn run_until_exit( mut runtime: Runtime, service: T, e: E, -) -> error::Result<()> where - T: Deref>, - T: Future + Send + 'static, - C: substrate_service::Components, +) -> error::Result<()> +where + T: AbstractService, E: IntoExit, { let (exit_send, exit) = exit_future::signal(); diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index 7022d12d69..c47e764c42 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -16,271 +16,240 @@ #![warn(unused_extern_crates)] -//! Service and ServiceFactory implementation. Specialized wrapper over substrate service. +//! Service implementation. Specialized wrapper over substrate service. use std::sync::Arc; -use std::time::Duration; -use babe::{import_queue, start_babe, BabeImportQueue, Config}; +use babe::{import_queue, Config}; use client::{self, LongestChain}; use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; use node_executor; -use futures::prelude::*; use node_primitives::Block; use node_runtime::{GenesisConfig, RuntimeApi}; use substrate_service::{ - FactoryFullConfiguration, LightComponents, FullComponents, FullBackend, - FullClient, LightClient, LightBackend, FullExecutor, LightExecutor, - error::{Error as ServiceError}, + AbstractService, ServiceBuilder, config::Configuration, error::{Error as ServiceError}, }; use transaction_pool::{self, txpool::{Pool as TransactionPool}}; use inherents::InherentDataProviders; use network::construct_simple_protocol; -use substrate_service::construct_service_factory; -use substrate_service::TelemetryOnConnect; construct_simple_protocol! { /// Demo protocol attachment for substrate. pub struct NodeProtocol where Block = Block { } } -type BabeBlockImportForService = babe::BabeBlockImport< - FullBackend, - FullExecutor, - ::Block, - grandpa::BlockImportForService, - ::RuntimeApi, - client::Client< - FullBackend, - FullExecutor, - ::Block, - ::RuntimeApi - >, ->; - -/// Node specific configuration -pub struct NodeConfig { - /// GRANDPA and BABE connection to import block. - // FIXME #1134 rather than putting this on the config, let's have an actual intermediate setup state - pub import_setup: Option<( - BabeBlockImportForService, - grandpa::LinkHalfForService, - babe::BabeLink, - )>, - /// Tasks that were created by previous setup steps and should be spawned. - pub tasks_to_spawn: Option + Send>>>, - inherent_data_providers: InherentDataProviders, -} - -impl Default for NodeConfig where F: substrate_service::ServiceFactory { - fn default() -> NodeConfig { - NodeConfig { - import_setup: None, - inherent_data_providers: InherentDataProviders::new(), - tasks_to_spawn: None, - } - } -} - -construct_service_factory! { - struct Factory { - Block = Block, - RuntimeApi = RuntimeApi, - NetworkProtocol = NodeProtocol { |config| Ok(NodeProtocol::new()) }, - RuntimeDispatch = node_executor::Executor, - FullTransactionPoolApi = - transaction_pool::ChainApi< - client::Client, FullExecutor, Block, RuntimeApi>, - Block - > { - |config, client| - Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) - }, - LightTransactionPoolApi = - transaction_pool::ChainApi< - client::Client, LightExecutor, Block, RuntimeApi>, - Block - > { - |config, client| - Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) - }, - Genesis = GenesisConfig, - Configuration = NodeConfig, - FullService = FullComponents { - |config: FactoryFullConfiguration| FullComponents::::new(config) - }, - AuthoritySetup = { - |mut service: Self::FullService| { - let (block_import, link_half, babe_link) = - service.config_mut().custom.import_setup.take() - .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); - - // spawn any futures that were created in the previous setup steps - if let Some(tasks) = service.config_mut().custom.tasks_to_spawn.take() { - for task in tasks { - service.spawn_task( - task.select(service.on_exit()) - .map(|_| ()) - .map_err(|_| ()) - ); - } - } - - if service.config().roles.is_authority() { - let proposer = substrate_basic_authorship::ProposerFactory { - client: service.client(), - transaction_pool: service.transaction_pool(), - }; - - let client = service.client(); - let select_chain = service.select_chain() - .ok_or(ServiceError::SelectChainRequired)?; - - let babe_config = babe::BabeParams { - config: Config::get_or_compute(&*client)?, - keystore: service.keystore(), - client, - select_chain, - block_import, - env: proposer, - sync_oracle: service.network(), - inherent_data_providers: service.config() - .custom.inherent_data_providers.clone(), - force_authoring: service.config().force_authoring, - time_source: babe_link, - }; - - let babe = start_babe(babe_config)?; - let select = babe.select(service.on_exit()).then(|_| Ok(())); - - // the BABE authoring task is considered infallible, i.e. if it - // fails we take down the service with it. - service.spawn_essential_task(select); - } - - let config = grandpa::Config { - // FIXME #1578 make this available through chainspec - gossip_duration: Duration::from_millis(333), - justification_period: 4096, - name: Some(service.config().name.clone()), - keystore: Some(service.keystore()), - }; - - match (service.config().roles.is_authority(), service.config().disable_grandpa) { - (false, false) => { - // start the lightweight GRANDPA observer - service.spawn_task(Box::new(grandpa::run_grandpa_observer( - config, - link_half, - service.network(), - service.on_exit(), - )?)); - }, - (true, false) => { - // start the full GRANDPA voter - let telemetry_on_connect = TelemetryOnConnect { - telemetry_connection_sinks: service.telemetry_on_connect_stream(), - }; - let grandpa_config = grandpa::GrandpaParams { - config: config, - link: link_half, - network: service.network(), - inherent_data_providers: - service.config().custom.inherent_data_providers.clone(), - on_exit: service.on_exit(), - telemetry_on_connect: Some(telemetry_on_connect), - }; - - // the GRANDPA voter task is considered infallible, i.e. - // if it fails we take down the service with it. - service.spawn_essential_task(grandpa::run_grandpa_voter(grandpa_config)?); - }, - (_, true) => { - grandpa::setup_disabled_grandpa( - service.client(), - &service.config().custom.inherent_data_providers, - service.network(), - )?; - }, - } - - Ok(service) - } - }, - LightService = LightComponents - { |config| >::new(config) }, - FullImportQueue = BabeImportQueue - { - | - config: &mut FactoryFullConfiguration, - client: Arc>, - select_chain: Self::SelectChain, - transaction_pool: Option>>, - | - { +/// Starts a `ServiceBuilder` for a full service. +/// +/// Use this macro if you don't actually need the full service, but just the builder in order to +/// be able to perform chain operations. +macro_rules! new_full_start { + ($config:expr) => {{ + let mut import_setup = None; + let inherent_data_providers = inherents::InherentDataProviders::new(); + let mut tasks_to_spawn = None; + + let builder = substrate_service::ServiceBuilder::new_full::< + node_primitives::Block, node_runtime::RuntimeApi, node_executor::Executor + >($config)? + .with_select_chain(|_config, client| { + #[allow(deprecated)] + Ok(client::LongestChain::new(client.backend().clone())) + })? + .with_transaction_pool(|config, client| + Ok(transaction_pool::txpool::Pool::new(config, transaction_pool::ChainApi::new(client))) + )? + .with_import_queue(|_config, client, mut select_chain, transaction_pool| { + let select_chain = select_chain.take() + .ok_or_else(|| substrate_service::Error::SelectChainRequired)?; let (block_import, link_half) = - grandpa::block_import::<_, _, _, RuntimeApi, FullClient, _>( + grandpa::block_import::<_, _, _, node_runtime::RuntimeApi, _, _>( client.clone(), client.clone(), select_chain )?; let justification_import = block_import.clone(); - let (import_queue, babe_link, babe_block_import, pruning_task) = import_queue( - Config::get_or_compute(&*client)?, + let (import_queue, babe_link, babe_block_import, pruning_task) = babe::import_queue( + babe::Config::get_or_compute(&*client)?, block_import, Some(Box::new(justification_import)), None, client.clone(), client, - config.custom.inherent_data_providers.clone(), - transaction_pool, + inherent_data_providers.clone(), + Some(transaction_pool) )?; - config.custom.import_setup = Some((babe_block_import.clone(), link_half, babe_link)); - config.custom.tasks_to_spawn = Some(vec![Box::new(pruning_task)]); + import_setup = Some((babe_block_import.clone(), link_half, babe_link)); + tasks_to_spawn = Some(vec![Box::new(pruning_task)]); Ok(import_queue) - }}, - LightImportQueue = BabeImportQueue - { |config: &FactoryFullConfiguration, client: Arc>| { - #[allow(deprecated)] - let fetch_checker = client.backend().blockchain().fetcher() - .upgrade() - .map(|fetcher| fetcher.checker().clone()) - .ok_or_else(|| "Trying to start light import queue without active fetch checker")?; - let block_import = grandpa::light_block_import::<_, _, _, RuntimeApi, LightClient>( - client.clone(), Arc::new(fetch_checker), client.clone() - )?; + })? + .with_rpc_extensions(|client, pool| { + use node_rpc::accounts::{Accounts, AccountsApi}; + + let mut io = jsonrpc_core::IoHandler::::default(); + io.extend_with( + AccountsApi::to_delegate(Accounts::new(client, pool)) + ); + io + })?; + + (builder, import_setup, inherent_data_providers, tasks_to_spawn) + }} +} - let finality_proof_import = block_import.clone(); - let finality_proof_request_builder = - finality_proof_import.create_finality_proof_request_builder(); +/// Creates a full service from the configuration. +/// +/// We need to use a macro because the test suit doesn't work with an opaque service. It expects +/// concrete types instead. +macro_rules! new_full { + ($config:expr) => {{ + use futures::Future; + + let (builder, mut import_setup, inherent_data_providers, mut tasks_to_spawn) = new_full_start!($config); + + let service = builder.with_network_protocol(|_| Ok(crate::service::NodeProtocol::new()))? + .with_finality_proof_provider(|client| + Ok(Arc::new(grandpa::FinalityProofProvider::new(client.clone(), client)) as _) + )? + .build()?; + + let (block_import, link_half, babe_link) = import_setup.take() + .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); + + // spawn any futures that were created in the previous setup steps + if let Some(tasks) = tasks_to_spawn.take() { + for task in tasks { + service.spawn_task( + task.select(service.on_exit()) + .map(|_| ()) + .map_err(|_| ()) + ); + } + } - // FIXME: pruning task isn't started since light client doesn't do `AuthoritySetup`. - let (import_queue, ..) = import_queue::<_, _, _, _, _, _, TransactionPool>( - Config::get_or_compute(&*client)?, - block_import, - None, - Some(Box::new(finality_proof_import)), - client.clone(), - client, - config.custom.inherent_data_providers.clone(), - None, + if service.config().roles.is_authority() { + let proposer = substrate_basic_authorship::ProposerFactory { + client: service.client(), + transaction_pool: service.transaction_pool(), + }; + + let client = service.client(); + let select_chain = service.select_chain() + .ok_or(substrate_service::Error::SelectChainRequired)?; + + let babe_config = babe::BabeParams { + config: babe::Config::get_or_compute(&*client)?, + keystore: service.keystore(), + client, + select_chain, + block_import, + env: proposer, + sync_oracle: service.network(), + inherent_data_providers: inherent_data_providers.clone(), + force_authoring: service.config().force_authoring, + time_source: babe_link, + }; + + let babe = babe::start_babe(babe_config)?; + let select = babe.select(service.on_exit()).then(|_| Ok(())); + service.spawn_task(Box::new(select)); + } + + let config = grandpa::Config { + // FIXME #1578 make this available through chainspec + gossip_duration: std::time::Duration::from_millis(333), + justification_period: 4096, + name: Some(service.config().name.clone()), + keystore: Some(service.keystore()), + }; + + match (service.config().roles.is_authority(), service.config().disable_grandpa) { + (false, false) => { + // start the lightweight GRANDPA observer + service.spawn_task(Box::new(grandpa::run_grandpa_observer( + config, + link_half, + service.network(), + service.on_exit(), + )?)); + }, + (true, false) => { + // start the full GRANDPA voter + let grandpa_config = grandpa::GrandpaParams { + config: config, + link: link_half, + network: service.network(), + inherent_data_providers: inherent_data_providers.clone(), + on_exit: service.on_exit(), + telemetry_on_connect: Some(service.telemetry_on_connect_stream()), + }; + service.spawn_task(Box::new(grandpa::run_grandpa_voter(grandpa_config)?)); + }, + (_, true) => { + grandpa::setup_disabled_grandpa( + service.client(), + &inherent_data_providers, + service.network(), )?; + }, + } - Ok((import_queue, finality_proof_request_builder)) - }}, - SelectChain = LongestChain, Self::Block> - { |config: &FactoryFullConfiguration, client: Arc>| { - #[allow(deprecated)] - Ok(LongestChain::new(client.backend().clone())) - } - }, - FinalityProofProvider = { |client: Arc>| { - Ok(Some(Arc::new(GrandpaFinalityProofProvider::new(client.clone(), client)) as _)) - }}, + Ok((service, inherent_data_providers)) + }} +} - RpcExtensions = jsonrpc_core::IoHandler - { |client, pool| { +/// Builds a new service for a full client. +pub fn new_full(config: Configuration) +-> Result { + new_full!(config).map(|(service, _)| service) +} + +/// Builds a new service for a light client. +pub fn new_light(config: Configuration) +-> Result { + let inherent_data_providers = InherentDataProviders::new(); + + ServiceBuilder::new_light::(config)? + .with_select_chain(|_config, client| { + #[allow(deprecated)] + Ok(LongestChain::new(client.backend().clone())) + })? + .with_transaction_pool(|config, client| + Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) + )? + .with_import_queue_and_fprb(|_config, client, _select_chain, transaction_pool| { + #[allow(deprecated)] + let fetch_checker = client.backend().blockchain().fetcher() + .upgrade() + .map(|fetcher| fetcher.checker().clone()) + .ok_or_else(|| "Trying to start light import queue without active fetch checker")?; + let block_import = grandpa::light_block_import::<_, _, _, RuntimeApi, _>( + client.clone(), Arc::new(fetch_checker), client.clone() + )?; + + let finality_proof_import = block_import.clone(); + let finality_proof_request_builder = + finality_proof_import.create_finality_proof_request_builder(); + + // FIXME: pruning task isn't started since light client doesn't do `AuthoritySetup`. + let (import_queue, ..) = import_queue( + Config::get_or_compute(&*client)?, + block_import, + None, + Some(Box::new(finality_proof_import)), + client.clone(), + client, + inherent_data_providers.clone(), + Some(transaction_pool) + )?; + + Ok((import_queue, finality_proof_request_builder)) + })? + .with_network_protocol(|_| Ok(NodeProtocol::new()))? + .with_finality_proof_provider(|client| + Ok(Arc::new(GrandpaFinalityProofProvider::new(client.clone(), client)) as _) + )? + .with_rpc_extensions(|client, pool| { use node_rpc::accounts::{Accounts, AccountsApi}; let mut io = jsonrpc_core::IoHandler::default(); @@ -288,11 +257,10 @@ construct_service_factory! { AccountsApi::to_delegate(Accounts::new(client, pool)) ); io - }}, - } + })? + .build() } - #[cfg(test)] mod tests { use std::sync::Arc; @@ -312,9 +280,8 @@ mod tests { use timestamp; use finality_tracker; use keyring::AccountKeyring; - use substrate_service::ServiceFactory; - use service_test::SyncService; - use crate::service::Factory; + use substrate_service::AbstractService; + use crate::service::{new_full, new_light}; #[cfg(feature = "rhd")] fn test_sync() { @@ -369,8 +336,10 @@ mod tests { let v: Vec = Decode::decode(&mut xt.as_slice()).unwrap(); OpaqueExtrinsic(v) }; - service_test::sync::( + service_test::sync( chain_spec::integration_test_config(), + |config| new_full(config), + |config| new_light(config), block_factory, extrinsic_factory, ); @@ -387,130 +356,127 @@ mod tests { let chain_spec = crate::chain_spec::tests::integration_test_config_with_single_authority(); + // For the block factory let mut slot_num = 1u64; - let block_factory = |service: &SyncService<::FullService>| { - let service = service.get(); - let mut inherent_data = service - .config() - .custom - .inherent_data_providers - .create_inherent_data() - .expect("Creates inherent data."); - inherent_data.replace_data(finality_tracker::INHERENT_IDENTIFIER, &1u64); - - let parent_id = BlockId::number(service.client().info().chain.best_number); - let parent_header = service.client().header(&parent_id).unwrap().unwrap(); - let mut proposer_factory = substrate_basic_authorship::ProposerFactory { - client: service.client(), - transaction_pool: service.transaction_pool(), - }; - - let mut digest = Digest::::default(); - - // even though there's only one authority some slots might be empty, - // so we must keep trying the next slots until we can claim one. - let babe_pre_digest = loop { - inherent_data.replace_data(timestamp::INHERENT_IDENTIFIER, &(slot_num * SLOT_DURATION)); - if let Some(babe_pre_digest) = babe::test_helpers::claim_slot( - slot_num, - &parent_header, - &*service.client(), - (278, 1000), - &keystore, - ) { - break babe_pre_digest; - } - - slot_num += 1; - }; - - digest.push(::babe_pre_digest(babe_pre_digest)); - - let mut proposer = proposer_factory.init(&parent_header).unwrap(); - let new_block = futures03::executor::block_on(proposer.propose( - inherent_data, - digest, - std::time::Duration::from_secs(1), - )).expect("Error making test block"); - - let (new_header, new_body) = new_block.deconstruct(); - let pre_hash = new_header.hash(); - // sign the pre-sealed hash of the block and then - // add it to a digest item. - let to_sign = pre_hash.encode(); - let signature = alice.sign(&to_sign[..]); - let item = ::babe_seal( - signature.into(), - ); - slot_num += 1; - - BlockImportParams { - origin: BlockOrigin::File, - header: new_header, - justification: None, - post_digests: vec![item], - body: Some(new_body), - finalized: true, - auxiliary: Vec::new(), - fork_choice: ForkChoiceStrategy::LongestChain, - } - }; + // For the extrinsics factory let bob = Arc::new(AccountKeyring::Bob.pair()); let charlie = Arc::new(AccountKeyring::Charlie.pair()); - let mut index = 0; - let extrinsic_factory = |service: &SyncService<::FullService>| { - let amount = 5 * CENTS; - let to = AddressPublic::from_raw(bob.public().0); - let from = AddressPublic::from_raw(charlie.public().0); - let genesis_hash = service.get().client().block_hash(0).unwrap().unwrap(); - let best_block_id = BlockId::number(service.get().client().info().chain.best_number); - let version = service.get().client().runtime_version_at(&best_block_id).unwrap().spec_version; - let signer = charlie.clone(); - - let function = Call::Balances(BalancesCall::transfer(to.into(), amount)); - - let check_version = system::CheckVersion::new(); - let check_genesis = system::CheckGenesis::new(); - let check_era = system::CheckEra::from(Era::Immortal); - let check_nonce = system::CheckNonce::from(index); - let check_weight = system::CheckWeight::new(); - let take_fees = balances::TakeFees::from(0); - let extra = (check_version, check_genesis, check_era, check_nonce, check_weight, take_fees); - - let raw_payload = (function, extra.clone(), version, genesis_hash, genesis_hash); - let signature = raw_payload.using_encoded(|payload| if payload.len() > 256 { - signer.sign(&blake2_256(payload)[..]) - } else { - signer.sign(payload) - }); - let xt = UncheckedExtrinsic::new_signed( - raw_payload.0, - from.into(), - signature.into(), - extra, - ).encode(); - let v: Vec = Decode::decode(&mut xt.as_slice()).unwrap(); - index += 1; - OpaqueExtrinsic(v) - }; - - service_test::sync::( + service_test::sync( chain_spec, - block_factory, - extrinsic_factory, + |config| new_full!(config), + |config| new_light(config), + |service, inherent_data_providers| { + let mut inherent_data = inherent_data_providers + .create_inherent_data() + .expect("Creates inherent data."); + inherent_data.replace_data(finality_tracker::INHERENT_IDENTIFIER, &1u64); + + let parent_id = BlockId::number(service.client().info().chain.best_number); + let parent_header = service.client().header(&parent_id).unwrap().unwrap(); + let mut proposer_factory = substrate_basic_authorship::ProposerFactory { + client: service.client(), + transaction_pool: service.transaction_pool(), + }; + + let mut digest = Digest::::default(); + + // even though there's only one authority some slots might be empty, + // so we must keep trying the next slots until we can claim one. + let babe_pre_digest = loop { + inherent_data.replace_data(timestamp::INHERENT_IDENTIFIER, &(slot_num * SLOT_DURATION)); + if let Some(babe_pre_digest) = babe::test_helpers::claim_slot( + slot_num, + &parent_header, + &*service.client(), + (278, 1000), + &keystore, + ) { + break babe_pre_digest; + } + + slot_num += 1; + }; + + digest.push(::babe_pre_digest(babe_pre_digest)); + + let mut proposer = proposer_factory.init(&parent_header).unwrap(); + let new_block = futures03::executor::block_on(proposer.propose( + inherent_data, + digest, + std::time::Duration::from_secs(1), + )).expect("Error making test block"); + + let (new_header, new_body) = new_block.deconstruct(); + let pre_hash = new_header.hash(); + // sign the pre-sealed hash of the block and then + // add it to a digest item. + let to_sign = pre_hash.encode(); + let signature = alice.sign(&to_sign[..]); + let item = ::babe_seal( + signature.into(), + ); + slot_num += 1; + + BlockImportParams { + origin: BlockOrigin::File, + header: new_header, + justification: None, + post_digests: vec![item], + body: Some(new_body), + finalized: true, + auxiliary: Vec::new(), + fork_choice: ForkChoiceStrategy::LongestChain, + } + }, + |service, _| { + let amount = 5 * CENTS; + let to = AddressPublic::from_raw(bob.public().0); + let from = AddressPublic::from_raw(charlie.public().0); + let genesis_hash = service.client().block_hash(0).unwrap().unwrap(); + let best_block_id = BlockId::number(service.client().info().chain.best_number); + let version = service.client().runtime_version_at(&best_block_id).unwrap().spec_version; + let signer = charlie.clone(); + + let function = Call::Balances(BalancesCall::transfer(to.into(), amount)); + + let check_version = system::CheckVersion::new(); + let check_genesis = system::CheckGenesis::new(); + let check_era = system::CheckEra::from(Era::Immortal); + let check_nonce = system::CheckNonce::from(index); + let check_weight = system::CheckWeight::new(); + let take_fees = balances::TakeFees::from(0); + let extra = (check_version, check_genesis, check_era, check_nonce, check_weight, take_fees); + + let raw_payload = (function, extra.clone(), version, genesis_hash, genesis_hash); + let signature = raw_payload.using_encoded(|payload| if payload.len() > 256 { + signer.sign(&blake2_256(payload)[..]) + } else { + signer.sign(payload) + }); + let xt = UncheckedExtrinsic::new_signed( + raw_payload.0, + from.into(), + signature.into(), + extra, + ).encode(); + let v: Vec = Decode::decode(&mut xt.as_slice()).unwrap(); + + index += 1; + OpaqueExtrinsic(v) + }, ); } #[test] #[ignore] fn test_consensus() { - use super::Factory; - - service_test::consensus::( + service_test::consensus( crate::chain_spec::tests::integration_test_config_with_two_authorities(), + |config| new_full(config), + |config| new_light(config), vec![ "//Alice".into(), "//Bob".into(), diff --git a/node/rpc-client/Cargo.toml b/node/rpc-client/Cargo.toml index bc492bc003..b98df224df 100644 --- a/node/rpc-client/Cargo.toml +++ b/node/rpc-client/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" env_logger = "0.6" futures = "0.1.26" hyper = "0.12" -jsonrpc-core-client = { version = "13.0.0", features = ["http", "ws"] } +jsonrpc-core-client = { version = "13.1.0", features = ["http", "ws"] } log = "0.4" node-primitives = { path = "../primitives" } substrate-rpc = { path = "../../core/rpc", version = "2.0.0" } diff --git a/node/rpc/Cargo.toml b/node/rpc/Cargo.toml index 6042380c83..55371daad6 100644 --- a/node/rpc/Cargo.toml +++ b/node/rpc/Cargo.toml @@ -6,10 +6,10 @@ edition = "2018" [dependencies] client = { package = "substrate-client", path = "../../core/client" } -jsonrpc-core = "13.0.0" -jsonrpc-core-client = "13.0.0" -jsonrpc-derive = "13.0.0" -jsonrpc-pubsub = "13.0.0" +jsonrpc-core = "13.1.0" +jsonrpc-core-client = "13.1.0" +jsonrpc-derive = "13.1.0" +jsonrpc-pubsub = "13.1.0" keyring = { package = "substrate-keyring", path = "../../core/keyring" } log = "0.4" node-primitives = { path = "../primitives" } diff --git a/test-utils/transaction-factory/src/complex_mode.rs b/test-utils/transaction-factory/src/complex_mode.rs index 85b12248d8..ed76a66b09 100644 --- a/test-utils/transaction-factory/src/complex_mode.rs +++ b/test-utils/transaction-factory/src/complex_mode.rs @@ -41,29 +41,30 @@ use std::sync::Arc; use log::info; +use client::Client; use client::block_builder::api::BlockBuilder; use client::runtime_api::ConstructRuntimeApi; +use primitives::{Blake2Hasher, Hasher}; use sr_primitives::generic::BlockId; use sr_primitives::traits::{Block as BlockT, ProvideRuntimeApi, One, Zero}; -use substrate_service::{ - FactoryBlock, FullClient, ServiceFactory, ComponentClient, FullComponents -}; use crate::{RuntimeAdapter, create_block}; -pub fn next( +pub fn next( factory_state: &mut RA, - client: &Arc>>, + client: &Arc>, version: u32, genesis_hash: ::Hash, prior_block_hash: ::Hash, - prior_block_id: BlockId, -) -> Option<::Block> + prior_block_id: BlockId, +) -> Option where - F: ServiceFactory, - F::RuntimeApi: ConstructRuntimeApi, FullClient>, - FullClient: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: BlockBuilder>, + Block: BlockT::Out>, + Exec: client::CallExecutor + Send + Sync + Clone, + Backend: client::backend::Backend + Send, + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: BlockBuilder, + RtApi: ConstructRuntimeApi> + Send + Sync, RA: RuntimeAdapter, { let total = factory_state.start_number() + factory_state.num() * factory_state.rounds(); @@ -102,7 +103,7 @@ where let inherents = client.runtime_api().inherent_extrinsics(&prior_block_id, inherents) .expect("Failed to create inherent extrinsics"); - let block = create_block::(&client, transfer, inherents); + let block = create_block::(&client, transfer, inherents); info!( "Created block {} with hash {}. Transferring {} from {} to {}.", factory_state.block_no() + RA::Number::one(), diff --git a/test-utils/transaction-factory/src/lib.rs b/test-utils/transaction-factory/src/lib.rs index 16bb08a2b4..5d63f906a7 100644 --- a/test-utils/transaction-factory/src/lib.rs +++ b/test-utils/transaction-factory/src/lib.rs @@ -26,22 +26,19 @@ use std::fmt::Display; use log::info; -use client::block_builder::api::BlockBuilder; -use client::runtime_api::ConstructRuntimeApi; +use client::{Client, block_builder::api::BlockBuilder, runtime_api::ConstructRuntimeApi}; use consensus_common::{ BlockOrigin, BlockImportParams, InherentData, ForkChoiceStrategy, SelectChain }; use consensus_common::block_import::BlockImport; use codec::{Decode, Encode}; +use primitives::{Blake2Hasher, Hasher}; use sr_primitives::generic::BlockId; use sr_primitives::traits::{ Block as BlockT, Header as HeaderT, ProvideRuntimeApi, SimpleArithmetic, One, Zero, }; -use substrate_service::{ - FactoryBlock, FactoryFullConfiguration, FullClient, new_client, - ServiceFactory, ComponentClient, FullComponents}; pub use crate::modes::Mode; pub mod modes; @@ -95,15 +92,19 @@ pub trait RuntimeAdapter { /// Manufactures transactions. The exact amount depends on /// `mode`, `num` and `rounds`. -pub fn factory( +pub fn factory( mut factory_state: RA, - mut config: FactoryFullConfiguration, + client: &Arc>, + select_chain: &Sc, ) -> cli::error::Result<()> where - F: ServiceFactory, - F::RuntimeApi: ConstructRuntimeApi, FullClient>, - FullClient: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: BlockBuilder>, + Block: BlockT::Out>, + Exec: client::CallExecutor + Send + Sync + Clone, + Backend: client::backend::Backend + Send, + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: BlockBuilder, + RtApi: ConstructRuntimeApi> + Send + Sync, + Sc: SelectChain, RA: RuntimeAdapter, <::Block as BlockT>::Hash: From, { @@ -112,20 +113,16 @@ where return Err(cli::error::Error::Input(msg)); } - let client = new_client::(&config)?; - - let select_chain = F::build_select_chain(&mut config, client.clone())?; - - let best_header: Result<::Header, cli::error::Error> = + let best_header: Result<::Header, cli::error::Error> = select_chain.best_chain().map_err(|e| format!("{:?}", e).into()); let mut best_hash = best_header?.hash(); - let best_block_id = BlockId::::hash(best_hash); + let best_block_id = BlockId::::hash(best_hash); let version = client.runtime_version_at(&best_block_id)?.spec_version; let genesis_hash = client.block_hash(Zero::zero())? .expect("Genesis block always exists; qed").into(); while let Some(block) = match factory_state.mode() { - Mode::MasterToNToM => complex_mode::next::( + Mode::MasterToNToM => complex_mode::next::( &mut factory_state, &client, version, @@ -133,7 +130,7 @@ where best_hash.into(), best_block_id, ), - _ => simple_modes::next::( + _ => simple_modes::next::( &mut factory_state, &client, version, @@ -143,7 +140,7 @@ where ), } { best_hash = block.header().hash(); - import_block::(&client, block); + import_block(&client, block); info!("Imported block at {}", factory_state.block_no()); } @@ -152,16 +149,18 @@ where } /// Create a baked block from a transfer extrinsic and timestamp inherent. -pub fn create_block( - client: &Arc>>, +pub fn create_block( + client: &Arc>, transfer: ::Extrinsic, - inherent_extrinsics: Vec<::Extrinsic>, -) -> ::Block + inherent_extrinsics: Vec<::Extrinsic>, +) -> Block where - F: ServiceFactory, - FullClient: ProvideRuntimeApi, - F::RuntimeApi: ConstructRuntimeApi, FullClient>, - as ProvideRuntimeApi>::Api: BlockBuilder>, + Block: BlockT::Out>, + Exec: client::CallExecutor + Send + Sync + Clone, + Backend: client::backend::Backend + Send, + Client: ProvideRuntimeApi, + RtApi: ConstructRuntimeApi> + Send + Sync, + as ProvideRuntimeApi>::Api: BlockBuilder, RA: RuntimeAdapter, { let mut block = client.new_block(Default::default()).expect("Failed to create new block"); @@ -177,10 +176,13 @@ where block.bake().expect("Failed to bake block") } -fn import_block( - client: &Arc>>, - block: ::Block -) -> () where F: ServiceFactory +fn import_block( + client: &Arc>, + block: Block +) -> () where + Block: BlockT::Out>, + Exec: client::CallExecutor + Send + Sync + Clone, + Backend: client::backend::Backend + Send, { let import = BlockImportParams { origin: BlockOrigin::File, diff --git a/test-utils/transaction-factory/src/simple_modes.rs b/test-utils/transaction-factory/src/simple_modes.rs index ec4f484fa9..bcbb912006 100644 --- a/test-utils/transaction-factory/src/simple_modes.rs +++ b/test-utils/transaction-factory/src/simple_modes.rs @@ -36,29 +36,30 @@ use std::sync::Arc; use log::info; +use client::Client; use client::block_builder::api::BlockBuilder; use client::runtime_api::ConstructRuntimeApi; +use primitives::{Blake2Hasher, Hasher}; use sr_primitives::traits::{Block as BlockT, ProvideRuntimeApi, One}; use sr_primitives::generic::BlockId; -use substrate_service::{ - FactoryBlock, FullClient, ServiceFactory, ComponentClient, FullComponents -}; use crate::{Mode, RuntimeAdapter, create_block}; -pub fn next( +pub fn next( factory_state: &mut RA, - client: &Arc>>, + client: &Arc>, version: u32, genesis_hash: ::Hash, prior_block_hash: ::Hash, - prior_block_id: BlockId, -) -> Option<::Block> + prior_block_id: BlockId, +) -> Option where - F: ServiceFactory, - F::RuntimeApi: ConstructRuntimeApi, FullClient>, - FullClient: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: BlockBuilder>, + Block: BlockT::Out>, + Exec: client::CallExecutor + Send + Sync + Clone, + Backend: client::backend::Backend + Send, + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: BlockBuilder, + RtApi: ConstructRuntimeApi> + Send + Sync, RA: RuntimeAdapter, { if factory_state.block_no() >= factory_state.num() { @@ -93,7 +94,7 @@ where let inherents = client.runtime_api().inherent_extrinsics(&prior_block_id, inherents) .expect("Failed to create inherent extrinsics"); - let block = create_block::(&client, transfer, inherents); + let block = create_block::(&client, transfer, inherents); factory_state.set_block_no(factory_state.block_no() + RA::Number::one()); -- GitLab From 223770a8abc645ff87b50e4226d236aeb48067d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 27 Aug 2019 11:57:35 +0200 Subject: [PATCH 019/275] Make sure that `on_before_session_ending` is called (#3487) * Make sure that `on_before_session_ending` is called * Move the call above the validtor set being set * Bump spec_version --- node/runtime/src/lib.rs | 4 ++-- srml/session/src/lib.rs | 29 +++++++++++++++++++++++++++++ srml/session/src/mock.rs | 14 ++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 33088260b7..e121967511 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -79,8 +79,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 151, - impl_version: 153, + spec_version: 152, + impl_version: 152, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/session/src/lib.rs b/srml/session/src/lib.rs index 6a09591e01..c474962c65 100644 --- a/srml/session/src/lib.rs +++ b/srml/session/src/lib.rs @@ -481,6 +481,9 @@ impl Module { let changed = QueuedChanged::get(); + // Inform the session handlers that a session is going to end. + T::SessionHandler::on_before_session_ending(); + // Get queued session keys and validators. let session_keys = >::get(); let validators = session_keys.iter() @@ -663,6 +666,7 @@ mod tests { use mock::{ NEXT_VALIDATORS, SESSION_CHANGED, TEST_SESSION_CHANGED, authorities, force_new_session, set_next_validators, set_session_length, session_changed, Test, Origin, System, Session, + reset_before_session_end_called, before_session_end_called, }; fn new_test_ext() -> runtime_io::TestExternalities { @@ -715,6 +719,8 @@ mod tests { #[test] fn authorities_should_track_validators() { + reset_before_session_end_called(); + with_externalities(&mut new_test_ext(), || { set_next_validators(vec![1, 2]); force_new_session(); @@ -725,6 +731,8 @@ mod tests { ]); assert_eq!(Session::validators(), vec![1, 2, 3]); assert_eq!(authorities(), vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]); + assert!(before_session_end_called()); + reset_before_session_end_called(); force_new_session(); initialize_block(2); @@ -734,6 +742,8 @@ mod tests { ]); assert_eq!(Session::validators(), vec![1, 2]); assert_eq!(authorities(), vec![UintAuthorityId(1), UintAuthorityId(2)]); + assert!(before_session_end_called()); + reset_before_session_end_called(); set_next_validators(vec![1, 2, 4]); assert_ok!(Session::set_keys(Origin::signed(4), UintAuthorityId(4).into(), vec![])); @@ -746,6 +756,7 @@ mod tests { ]); assert_eq!(Session::validators(), vec![1, 2]); assert_eq!(authorities(), vec![UintAuthorityId(1), UintAuthorityId(2)]); + assert!(before_session_end_called()); force_new_session(); initialize_block(4); @@ -827,45 +838,63 @@ mod tests { #[test] fn session_changed_flag_works() { + reset_before_session_end_called(); + with_externalities(&mut new_test_ext(), || { TEST_SESSION_CHANGED.with(|l| *l.borrow_mut() = true); force_new_session(); initialize_block(1); assert!(!session_changed()); + assert!(before_session_end_called()); + reset_before_session_end_called(); force_new_session(); initialize_block(2); assert!(!session_changed()); + assert!(before_session_end_called()); + reset_before_session_end_called(); Session::disable_index(0); force_new_session(); initialize_block(3); assert!(!session_changed()); + assert!(before_session_end_called()); + reset_before_session_end_called(); force_new_session(); initialize_block(4); assert!(session_changed()); + assert!(before_session_end_called()); + reset_before_session_end_called(); force_new_session(); initialize_block(5); assert!(!session_changed()); + assert!(before_session_end_called()); + reset_before_session_end_called(); assert_ok!(Session::set_keys(Origin::signed(2), UintAuthorityId(5).into(), vec![])); force_new_session(); initialize_block(6); assert!(!session_changed()); + assert!(before_session_end_called()); + reset_before_session_end_called(); // changing the keys of a validator leads to change. assert_ok!(Session::set_keys(Origin::signed(69), UintAuthorityId(69).into(), vec![])); force_new_session(); initialize_block(7); assert!(session_changed()); + assert!(before_session_end_called()); + reset_before_session_end_called(); // while changing the keys of a non-validator does not. force_new_session(); initialize_block(7); assert!(!session_changed()); + assert!(before_session_end_called()); + reset_before_session_end_called(); }); } diff --git a/srml/session/src/mock.rs b/srml/session/src/mock.rs index 13fcb54754..445076be65 100644 --- a/srml/session/src/mock.rs +++ b/srml/session/src/mock.rs @@ -53,6 +53,8 @@ thread_local! { pub static SESSION_CHANGED: RefCell = RefCell::new(false); pub static TEST_SESSION_CHANGED: RefCell = RefCell::new(false); pub static DISABLED: RefCell = RefCell::new(false); + // Stores if `on_before_session_end` was called + pub static BEFORE_SESSION_END_CALLED: RefCell = RefCell::new(false); } pub struct TestShouldEndSession; @@ -81,6 +83,9 @@ impl SessionHandler for TestSessionHandler { fn on_disabled(_validator_index: usize) { DISABLED.with(|l| *l.borrow_mut() = true) } + fn on_before_session_ending() { + BEFORE_SESSION_END_CALLED.with(|b| *b.borrow_mut() = true); + } } pub struct TestOnSessionEnding; @@ -134,8 +139,17 @@ pub fn set_next_validators(next: Vec) { NEXT_VALIDATORS.with(|v| *v.borrow_mut() = next); } +pub fn before_session_end_called() -> bool { + BEFORE_SESSION_END_CALLED.with(|b| *b.borrow()) +} + +pub fn reset_before_session_end_called() { + BEFORE_SESSION_END_CALLED.with(|b| *b.borrow_mut() = false); +} + #[derive(Clone, Eq, PartialEq)] pub struct Test; + parameter_types! { pub const BlockHashCount: u64 = 250; pub const MaximumBlockWeight: u32 = 1024; -- GitLab From ca7f4c9273cff541407c2f3a24cf2077c5ffe1c3 Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Tue, 27 Aug 2019 14:07:43 +0200 Subject: [PATCH 020/275] Fixed uncle pruning (#3491) * Fixed uncle pruning * Version bump --- node/runtime/src/lib.rs | 4 +-- srml/authorship/src/lib.rs | 55 ++++++++++++++++++++------------------ 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index e121967511..a487a4a89e 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -79,8 +79,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 152, - impl_version: 152, + spec_version: 153, + impl_version: 153, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/authorship/src/lib.rs b/srml/authorship/src/lib.rs index 424223a2c9..c71c26df02 100644 --- a/srml/authorship/src/lib.rs +++ b/srml/authorship/src/lib.rs @@ -27,7 +27,7 @@ use srml_support::traits::{FindAuthor, VerifySeal, Get}; use srml_support::dispatch::Result as DispatchResult; use codec::{Encode, Decode}; use system::ensure_none; -use sr_primitives::traits::{SimpleArithmetic, Header as HeaderT, One, Zero}; +use sr_primitives::traits::{Header as HeaderT, One, Zero}; use sr_primitives::weights::SimpleDispatchInfo; use inherents::{ RuntimeString, InherentIdentifier, ProvideInherent, @@ -236,29 +236,14 @@ decl_storage! { } } -fn prune_old_uncles( - minimum_height: BlockNumber, - uncles: &mut Vec> -) where BlockNumber: SimpleArithmetic { - let prune_entries = uncles.iter().take_while(|item| match item { - UncleEntryItem::Uncle(_, _) => true, - UncleEntryItem::InclusionHeight(height) => height < &minimum_height, - }); - let prune_index = prune_entries.count(); - - let _ = uncles.drain(..prune_index); -} - decl_module! { pub struct Module for enum Call where origin: T::Origin { fn on_initialize(now: T::BlockNumber) { let uncle_generations = T::UncleGenerations::get(); - let mut uncles = ::Uncles::get(); - // prune uncles that are older than the allowed number of generations. if uncle_generations <= now { let minimum_height = now - uncle_generations; - prune_old_uncles(minimum_height, &mut uncles) + Self::prune_old_uncles(minimum_height) } ::DidSetUncles::put(false); @@ -387,6 +372,18 @@ impl Module { // check uncle validity. T::FilterUncle::filter_uncle(&uncle, accumulator) } + + fn prune_old_uncles(minimum_height: T::BlockNumber) { + let mut uncles = ::Uncles::get(); + let prune_entries = uncles.iter().take_while(|item| match item { + UncleEntryItem::Uncle(_, _) => true, + UncleEntryItem::InclusionHeight(height) => height < &minimum_height, + }); + let prune_index = prune_entries.count(); + + let _ = uncles.drain(..prune_index); + ::Uncles::put(uncles); + } } impl ProvideInherent for Module { @@ -569,15 +566,21 @@ mod tests { #[test] fn prune_old_uncles_works() { use UncleEntryItem::*; - let mut uncles = vec![ - InclusionHeight(1u32), Uncle((), Some(())), Uncle((), None), Uncle((), None), - InclusionHeight(2u32), Uncle((), None), - InclusionHeight(3u32), Uncle((), None), - ]; - - prune_old_uncles(3, &mut uncles); - - assert_eq!(uncles, vec![InclusionHeight(3), Uncle((), None)]); + with_externalities(&mut new_test_ext(), || { + let hash = Default::default(); + let author = Default::default(); + let uncles = vec![ + InclusionHeight(1u64), Uncle(hash, Some(author)), Uncle(hash, None), Uncle(hash, None), + InclusionHeight(2u64), Uncle(hash, None), + InclusionHeight(3u64), Uncle(hash, None), + ]; + + ::Uncles::put(uncles); + Authorship::prune_old_uncles(3); + + let uncles = ::Uncles::get(); + assert_eq!(uncles, vec![InclusionHeight(3u64), Uncle(hash, None)]); + }) } #[test] -- GitLab From 46b63afe5f593f1035bcc0d84e4619826c12881a Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 27 Aug 2019 15:07:26 +0200 Subject: [PATCH 021/275] Minor tweak to requirements of AbstractService (#3493) --- core/service/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/service/src/lib.rs b/core/service/src/lib.rs index 363ad9cfda..1362e86c21 100644 --- a/core/service/src/lib.rs +++ b/core/service/src/lib.rs @@ -454,7 +454,7 @@ pub trait AbstractService: 'static + Future + /// Configuration struct of the service. type Config; /// Chain selection algorithm. - type SelectChain; + type SelectChain: consensus_common::SelectChain; /// API of the transaction pool. type TransactionPoolApi: ChainApi; /// Network specialization. @@ -524,7 +524,7 @@ where TCfg: 'static + Send, TBackend: 'static + client::backend::Backend, TExec: 'static + client::CallExecutor + Send + Sync + Clone, TRtApi: 'static + Send + Sync, - TSc: 'static + Clone + Send, + TSc: consensus_common::SelectChain + 'static + Clone + Send, TExPoolApi: 'static + ChainApi, TOc: 'static + Send + Sync, TNetSpec: NetworkSpecialization, -- GitLab From 4ba93c0e94956f8621ae6d5103e57dfcc98947ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 27 Aug 2019 17:01:06 +0200 Subject: [PATCH 022/275] Bump `multistream-select` to fix flaky tests (#3495) --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7bddc07d24..18f18b63d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1675,7 +1675,7 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "multistream-select 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "multistream-select 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2243,7 +2243,7 @@ dependencies = [ [[package]] name = "multistream-select" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6492,7 +6492,7 @@ dependencies = [ "checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -"checksum multistream-select 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51a032ec01abdbe99a1165cd3e518bdd4bd7ca509a59ae9adf186d240399b90c" +"checksum multistream-select 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e8f3cb4c93f2d79811fc11fa01faab99d8b7b8cbe024b602c27434ff2b08a59d" "checksum names 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef320dab323286b50fb5cdda23f61c796a72a89998ab565ca32525c5c556f2da" "checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" -- GitLab From 7aa47cee7010022ba73e5bba04c6455ee12d1cc9 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Tue, 27 Aug 2019 19:39:05 +0200 Subject: [PATCH 023/275] Use optimized append and len storage methods in SRML. (#3071) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * expose len from codec to storage. * refactor runtime with len and append. * Undo example. * Remove imports. * Bump codec. * Optionify. * Make decode_len counscious. * Refactor. * Update srml/support/src/storage/hashed/generator.rs Co-Authored-By: Bastian Köcher * Update srml/support/src/storage/hashed/generator.rs Co-Authored-By: Bastian Köcher * Update srml/support/src/storage/hashed/generator.rs Co-Authored-By: Bastian Köcher * Update srml/support/src/storage/hashed/generator.rs Co-Authored-By: Bastian Köcher * Fix merge. * fix some docs. * Add NoDefault trait. * Bump. * Final nits. * Update srml/support/src/traits.rs * new approach toward len. * re-create lock file. * Fix build errors and Option handling. * More test fix * Use default for append as well. * Fix runtime. * Add support for linked_map * More tweaks from review. * Fix style * Change api for none-values * Bump. --- Cargo.lock | 191 ++++++++---------- node/runtime/src/lib.rs | 2 +- srml/democracy/src/lib.rs | 19 +- srml/elections/src/lib.rs | 30 +-- srml/support/Cargo.toml | 2 +- srml/support/procedural/src/storage/impls.rs | 54 ++++- .../procedural/src/storage/transformation.rs | 21 +- srml/support/src/lib.rs | 3 +- srml/support/src/storage/hashed/generator.rs | 133 ++++++++++-- srml/support/src/storage/mod.rs | 134 +++++++++++- srml/support/src/storage/storage_items.rs | 135 ++++++++++++- srml/support/src/traits.rs | 22 ++ srml/system/src/lib.rs | 2 +- 13 files changed, 571 insertions(+), 177 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 18f18b63d1..f3fc76d630 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -211,11 +211,6 @@ name = "bitmask" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "bitvec" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "bitvec" version = "0.14.0" @@ -865,7 +860,7 @@ dependencies = [ "hashmap_core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -917,7 +912,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "fork-tree" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1359,7 +1354,7 @@ name = "impl-codec" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2315,7 +2310,7 @@ dependencies = [ "node-primitives 2.0.0", "node-rpc 2.0.0", "node-runtime 2.0.0", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -2359,7 +2354,7 @@ dependencies = [ "node-primitives 2.0.0", "node-runtime 2.0.0", "node-testing 2.0.0", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "srml-balances 2.0.0", @@ -2384,7 +2379,7 @@ dependencies = [ name = "node-primitives" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -2407,7 +2402,7 @@ dependencies = [ "node-primitives 2.0.0", "node-runtime 2.0.0", "node-testing 2.0.0", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", @@ -2435,7 +2430,7 @@ version = "2.0.0" dependencies = [ "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2485,7 +2480,7 @@ dependencies = [ "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "node-template-runtime 2.0.0", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "substrate-basic-authorship 2.0.0", @@ -2510,7 +2505,7 @@ dependencies = [ name = "node-template-runtime" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -2541,7 +2536,7 @@ dependencies = [ "node-executor 2.0.0", "node-primitives 2.0.0", "node-runtime 2.0.0", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "srml-balances 2.0.0", @@ -2707,16 +2702,6 @@ name = "parity-bytes" version = "0.1.0" source = "git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d#b0317f649ab2c665b7987b8475878fc4d2e1f81d" -[[package]] -name = "parity-codec" -version = "4.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "bitvec 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "parity-multiaddr" version = "0.5.0" @@ -2750,7 +2735,7 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2758,7 +2743,6 @@ dependencies = [ "byte-slice-cast 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec-derive 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", - "vecarray 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3316,7 +3300,7 @@ dependencies = [ "error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3708,7 +3692,7 @@ version = "2.0.0" dependencies = [ "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3730,7 +3714,7 @@ dependencies = [ "environmental 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", "substrate-offchain 2.0.0", @@ -3747,7 +3731,7 @@ dependencies = [ "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "primitive-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3764,7 +3748,7 @@ name = "sr-sandbox" version = "2.0.0" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", "substrate-primitives 2.0.0", @@ -3776,7 +3760,7 @@ dependencies = [ name = "sr-staking-primitives" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", ] @@ -3793,7 +3777,7 @@ name = "sr-version" version = "2.0.0" dependencies = [ "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -3803,7 +3787,7 @@ dependencies = [ name = "srml-assets" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -3818,7 +3802,7 @@ name = "srml-aura" version = "2.0.0" dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -3838,7 +3822,7 @@ dependencies = [ name = "srml-authority-discovery" version = "0.1.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -3855,7 +3839,7 @@ dependencies = [ name = "srml-authorship" version = "0.1.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -3871,7 +3855,7 @@ version = "2.0.0" dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -3891,7 +3875,7 @@ dependencies = [ name = "srml-balances" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -3908,7 +3892,7 @@ name = "srml-collective" version = "2.0.0" dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -3927,7 +3911,7 @@ dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", "pwasm-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3948,7 +3932,7 @@ dependencies = [ name = "srml-democracy" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -3965,7 +3949,7 @@ name = "srml-elections" version = "2.0.0" dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -3981,7 +3965,7 @@ dependencies = [ name = "srml-example" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -3997,7 +3981,7 @@ name = "srml-executive" version = "2.0.0" dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4013,7 +3997,7 @@ dependencies = [ name = "srml-finality-tracker" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4028,7 +4012,7 @@ dependencies = [ name = "srml-generic-asset" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4042,7 +4026,7 @@ dependencies = [ name = "srml-grandpa" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4060,7 +4044,7 @@ dependencies = [ name = "srml-im-online" version = "0.1.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4077,7 +4061,7 @@ dependencies = [ name = "srml-indices" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4094,7 +4078,7 @@ dependencies = [ name = "srml-membership" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4108,7 +4092,7 @@ dependencies = [ name = "srml-metadata" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", "substrate-primitives 2.0.0", @@ -4118,7 +4102,7 @@ dependencies = [ name = "srml-offences" version = "1.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4134,7 +4118,7 @@ dependencies = [ name = "srml-scored-pool" version = "1.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4150,7 +4134,7 @@ name = "srml-session" version = "2.0.0" dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4169,7 +4153,7 @@ dependencies = [ name = "srml-staking" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4191,7 +4175,7 @@ dependencies = [ name = "srml-sudo" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4208,7 +4192,7 @@ version = "2.0.0" dependencies = [ "bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4257,7 +4241,7 @@ dependencies = [ name = "srml-support-test" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4272,7 +4256,7 @@ name = "srml-system" version = "2.0.0" dependencies = [ "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4287,7 +4271,7 @@ dependencies = [ name = "srml-timestamp" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4302,7 +4286,7 @@ dependencies = [ name = "srml-treasury" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4394,7 +4378,7 @@ dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", "node-runtime 2.0.0", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -4419,7 +4403,7 @@ dependencies = [ name = "substrate-application-crypto" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4432,7 +4416,7 @@ dependencies = [ name = "substrate-authority-discovery-primitives" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", "substrate-client 2.0.0", @@ -4444,7 +4428,7 @@ version = "2.0.0" dependencies = [ "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", "substrate-consensus-common 2.0.0", @@ -4514,7 +4498,7 @@ dependencies = [ "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", "kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-api-macros 2.0.0", "sr-primitives 2.0.0", @@ -4543,7 +4527,7 @@ dependencies = [ "kvdb-rocksdb 0.1.4 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", @@ -4566,7 +4550,7 @@ dependencies = [ "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", "futures-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4595,7 +4579,7 @@ dependencies = [ name = "substrate-consensus-aura-primitives" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", "substrate-application-crypto 2.0.0", @@ -4616,7 +4600,7 @@ dependencies = [ "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "schnorrkel 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4648,7 +4632,7 @@ dependencies = [ name = "substrate-consensus-babe-primitives" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "schnorrkel 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4666,7 +4650,7 @@ dependencies = [ "futures-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4684,7 +4668,7 @@ dependencies = [ "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rhododendron 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4707,7 +4691,7 @@ dependencies = [ "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", "futures-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", @@ -4742,7 +4726,7 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4770,7 +4754,7 @@ dependencies = [ "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4797,7 +4781,7 @@ dependencies = [ name = "substrate-finality-grandpa-primitives" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4809,7 +4793,7 @@ dependencies = [ name = "substrate-inherents" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4861,7 +4845,7 @@ dependencies = [ "linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "quickcheck 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4902,7 +4886,7 @@ dependencies = [ "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -4963,7 +4947,7 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "primitive-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4995,7 +4979,7 @@ dependencies = [ "jsonrpc-derive 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-pubsub 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5061,7 +5045,7 @@ dependencies = [ "node-primitives 2.0.0", "node-runtime 2.0.0", "parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5126,7 +5110,7 @@ version = "2.0.0" dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-primitives 2.0.0", ] @@ -5139,7 +5123,7 @@ dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-panic-handler 2.0.0", "substrate-primitives 2.0.0", @@ -5175,7 +5159,7 @@ version = "2.0.0" dependencies = [ "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", "substrate-client-db 2.0.0", @@ -5193,7 +5177,7 @@ dependencies = [ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -5225,7 +5209,7 @@ dependencies = [ name = "substrate-test-runtime-client" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-primitives 2.0.0", "substrate-test-client 2.0.0", @@ -5241,7 +5225,7 @@ dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -5255,7 +5239,7 @@ version = "2.0.0" dependencies = [ "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", @@ -5274,7 +5258,7 @@ dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", "substrate-primitives 2.0.0", "trie-bench 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5675,7 +5659,7 @@ name = "transaction-factory" version = "0.0.1" dependencies = [ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-cli 2.0.0", "substrate-client 2.0.0", @@ -5693,7 +5677,7 @@ dependencies = [ "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "trie-standardmap 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5885,16 +5869,6 @@ name = "vec_map" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "vecarray" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "parity-codec 4.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", - "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "vergen" version = "3.0.4" @@ -6287,7 +6261,6 @@ dependencies = [ "checksum bindgen 0.47.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df683a55b54b41d5ea8ebfaebb5aa7e6b84e3f3006a78f010dadc9ca88469260" "checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" "checksum bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5da9b3d9f6f585199287a473f4f8dfab6566cf827d15c00c219f53c645687ead" -"checksum bitvec 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b67491e1cc6f37da6c4415cd743cb8d2e2c65388acc91ca3094a054cbf3cbd0c" "checksum bitvec 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9633b74910e1870f50f5af189b08487195cdb83c0e27a71d6f64d5e09dd0538b" "checksum blake2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91721a6330935673395a0607df4d49a9cb90ae12d259f1b3e0a3f6e1d486872e" "checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" @@ -6515,10 +6488,9 @@ dependencies = [ "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" "checksum parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" -"checksum parity-codec 4.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2900f06356edf90de66a2922db622b36178dca71e85625eae58d0d9cc6cff2ac" "checksum parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "045b3c7af871285146300da35b1932bb6e4639b66c7c98e85d06a32cbc4e8fa7" "checksum parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df3a17dc27848fd99e4f87eb0f8c9baba6ede0a6d555400c850ca45254ef4ce3" -"checksum parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "00fd14ff806ad82cea9a8f909bb116443d92efda7c9acd4502690af64741ad81" +"checksum parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "65582b5c02128a4b0fa60fb3e070216e9c84be3e4a8f1b74bc37e15a25e58daf" "checksum parity-scale-codec-derive 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a81f3cd93ed368a8e41c4e79538e99ca6e8f536096de23e3a0bc3e782093ce28" "checksum parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" "checksum parity-util-mem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2005637ccf93dbb60c85081ccaaf3f945f573da48dcc79f27f9646caa3ec1dc" @@ -6697,7 +6669,6 @@ dependencies = [ "checksum utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d50aa7650df78abf942826607c62468ce18d9019673d4a2ebe1865dbb96ffde" "checksum vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "33dd455d0f96e90a75803cfeb7f948768c08d70a6de9a8d2362461935698bf95" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" -"checksum vecarray 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d4d68a73b7d7d950c6558b6009e9fba229fb67562bda9fd02198f614f4ecf83f" "checksum vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6aba5e34f93dc7051dfad05b98a18e9156f27e7b431fe1d2398cb6061c0a1dba" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index a487a4a89e..5260a3ef43 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -80,7 +80,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 153, - impl_version: 153, + impl_version: 154, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index f1265438f2..4853d192c4 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -24,11 +24,11 @@ use sr_primitives::traits::{Zero, Bounded, CheckedMul, CheckedDiv, EnsureOrigin, use sr_primitives::weights::SimpleDispatchInfo; use codec::{Encode, Decode, Input, Output, Error}; use srml_support::{ - decl_module, decl_storage, decl_event, ensure, - StorageValue, StorageMap, Parameter, Dispatchable, EnumerableStorageMap, + decl_module, decl_storage, decl_event, ensure, AppendableStorageMap, StorageValue, StorageMap, + Parameter, Dispatchable, EnumerableStorageMap, traits::{ - Currency, ReservableCurrency, LockableCurrency, WithdrawReason, LockIdentifier, - OnFreeBalanceZero, Get + Currency, ReservableCurrency, LockableCurrency, WithdrawReason, LockIdentifier, Get, + OnFreeBalanceZero } }; use srml_support::dispatch::Result; @@ -377,9 +377,8 @@ decl_module! { PublicPropCount::put(index + 1); >::insert(index, (value, vec![who.clone()])); - let mut props = Self::public_props(); - props.push((index, (*proposal).clone(), who)); - >::put(props); + let new_prop = (index, (*proposal).clone(), who); + >::append_or_put([new_prop].into_iter()); Self::deposit_event(RawEvent::Proposed(index, value)); } @@ -788,7 +787,7 @@ impl Module { fn do_vote(who: T::AccountId, ref_index: ReferendumIndex, vote: Vote) -> Result { ensure!(Self::is_active_referendum(ref_index), "vote given for invalid referendum."); if !>::exists(&(ref_index, who.clone())) { - >::mutate(ref_index, |voters| voters.push(who.clone())); + >::append_or_insert(ref_index, [who.clone()].into_iter()); } >::insert(&(ref_index, who), vote); Ok(()) @@ -926,9 +925,9 @@ impl Module { if info.delay.is_zero() { Self::enact_proposal(info.proposal, index); } else { - >::mutate( + >::append_or_insert( now + info.delay, - |q| q.push(Some((info.proposal, index))) + [Some((info.proposal, index))].into_iter() ); } } else { diff --git a/srml/elections/src/lib.rs b/srml/elections/src/lib.rs index f615fdee38..9c49b9055b 100644 --- a/srml/elections/src/lib.rs +++ b/srml/elections/src/lib.rs @@ -28,7 +28,7 @@ use sr_primitives::traits::{Zero, One, StaticLookup, Bounded, Saturating}; use sr_primitives::weights::SimpleDispatchInfo; use runtime_io::print; use srml_support::{ - StorageValue, StorageMap, + StorageValue, StorageMap, AppendableStorageMap, DecodeLengthStorageMap, dispatch::Result, decl_storage, decl_event, ensure, decl_module, traits::{ Currency, ExistenceRequirement, Get, LockableCurrency, LockIdentifier, @@ -714,15 +714,15 @@ impl Module { /// /// The voter index must be provided as explained in [`voter_at`] function. fn do_set_approvals(who: T::AccountId, votes: Vec, index: VoteIndex, hint: SetIndex) -> Result { - let candidates = Self::candidates(); + let candidates_len = ::Candidates::decode_len().unwrap_or(0_usize); ensure!(!Self::presentation_active(), "no approval changes during presentation period"); ensure!(index == Self::vote_index(), "incorrect vote index"); - ensure!(!candidates.is_empty(), "amount of candidates to receive approval votes should be non-zero"); + ensure!(!candidates_len.is_zero(), "amount of candidates to receive approval votes should be non-zero"); // Prevent a vote from voters that provide a list of votes that exceeds the candidates length // since otherwise an attacker may be able to submit a very long list of `votes` that far exceeds // the amount of candidates and waste more computation than a reasonable voting bond would cover. - ensure!(candidates.len() >= votes.len(), "amount of candidate votes cannot exceed amount of candidates"); + ensure!(candidates_len >= votes.len(), "amount of candidate votes cannot exceed amount of candidates"); // Amount to be locked up. let mut locked_balance = T::Currency::total_balance(&who); @@ -755,10 +755,10 @@ impl Module { CellStatus::Head | CellStatus::Occupied => { // Either occupied or out-of-range. let next = Self::next_nonfull_voter_set(); - let mut set = Self::voters(next); + let set_len = >::decode_len(next).unwrap_or(0_usize); // Caused a new set to be created. Pay for it. // This is the last potential error. Writes will begin afterwards. - if set.is_empty() { + if set_len == 0 { let imbalance = T::Currency::withdraw( &who, T::VotingFee::get(), @@ -769,8 +769,10 @@ impl Module { // NOTE: this is safe since the `withdraw()` will check this. locked_balance -= T::VotingFee::get(); } - Self::checked_push_voter(&mut set, who.clone(), next); - >::insert(next, set); + if set_len + 1 == VOTER_SET_SIZE { + NextVoterSet::put(next + 1); + } + >::append_or_insert(next, [Some(who.clone())].into_iter()) } } @@ -908,18 +910,6 @@ impl Module { Ok(()) } - fn checked_push_voter(set: &mut Vec>, who: T::AccountId, index: u32) { - let len = set.len(); - - // Defensive only: this should never happen. Don't push since it will break more things. - if len == VOTER_SET_SIZE { return; } - - set.push(Some(who)); - if len + 1 == VOTER_SET_SIZE { - NextVoterSet::put(index + 1); - } - } - /// Get the set and vector index of a global voter index. /// /// Note that this function does not take holes into account. diff --git a/srml/support/Cargo.toml b/srml/support/Cargo.toml index 2befc11b19..cf8c90993a 100644 --- a/srml/support/Cargo.toml +++ b/srml/support/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] serde = { version = "1.0", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.0.5", default-features = false, features = ["derive"] } srml-metadata = { path = "../metadata", default-features = false } sr-std = { path = "../../core/sr-std", default-features = false } runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } diff --git a/srml/support/procedural/src/storage/impls.rs b/srml/support/procedural/src/storage/impls.rs index d5f73f5d39..d67bc5a116 100644 --- a/srml/support/procedural/src/storage/impls.rs +++ b/srml/support/procedural/src/storage/impls.rs @@ -43,6 +43,8 @@ pub(crate) struct Impls<'a, I: Iterator> { pub instance_opts: &'a InstanceOpts, pub type_infos: DeclStorageTypeInfos<'a>, pub fielddefault: TokenStream2, + pub default_delegator_ident: syn::Ident, + pub default_delegator_return: TokenStream2, pub prefix: String, pub cratename: &'a syn::Ident, pub name: &'a syn::Ident, @@ -60,6 +62,8 @@ impl<'a, I: Iterator> Impls<'a, I> { instance_opts, type_infos, fielddefault, + default_delegator_ident, + default_delegator_return, prefix, name, attrs, @@ -116,6 +120,17 @@ impl<'a, I: Iterator> Impls<'a, I> { // generator for value quote! { + #visibility struct #default_delegator_ident<#struct_trait>( + #scrate::rstd::marker::PhantomData<(#trait_and_instance)> + ) #where_clause; + impl<#impl_trait> #scrate::traits::StorageDefault<#typ> + for #default_delegator_ident<#trait_and_instance> #where_clause + { + fn default() -> Option<#typ> { + #default_delegator_return + } + } + #( #[ #attrs ] )* #visibility struct #name<#struct_trait>( #scrate::rstd::marker::PhantomData<(#trait_and_instance)> @@ -125,6 +140,7 @@ impl<'a, I: Iterator> Impls<'a, I> { for #name<#trait_and_instance> #where_clause { type Query = #value_type; + type Default = #default_delegator_ident<#trait_and_instance>; /// Get the storage key. fn key() -> &'static [u8] { @@ -168,6 +184,8 @@ impl<'a, I: Iterator> Impls<'a, I> { instance_opts, type_infos, fielddefault, + default_delegator_ident, + default_delegator_return, prefix, name, attrs, @@ -230,6 +248,17 @@ impl<'a, I: Iterator> Impls<'a, I> { // generator for map quote!{ + #visibility struct #default_delegator_ident<#struct_trait>( + #scrate::rstd::marker::PhantomData<(#trait_and_instance)> + ) #where_clause; + impl<#impl_trait> #scrate::traits::StorageDefault<#typ> + for #default_delegator_ident<#trait_and_instance> #where_clause + { + fn default() -> Option<#typ> { + #default_delegator_return + } + } + #( #[ #attrs ] )* #visibility struct #name<#struct_trait>( #scrate::rstd::marker::PhantomData<(#trait_and_instance)> @@ -239,8 +268,8 @@ impl<'a, I: Iterator> Impls<'a, I> { for #name<#trait_and_instance> #where_clause { type Query = #value_type; - type Hasher = #scrate::#hasher; + type Default = #default_delegator_ident<#trait_and_instance>; /// Get the prefix key in storage. fn prefix() -> &'static [u8] { @@ -283,6 +312,10 @@ impl<'a, I: Iterator> Impls<'a, I> { impl<#impl_trait> #scrate::storage::hashed::generator::AppendableStorageMap<#kty, #typ> for #name<#trait_and_instance> #where_clause {} + + impl<#impl_trait> #scrate::storage::hashed::generator::DecodeLengthStorageMap<#kty, #typ> + for #name<#trait_and_instance> #where_clause + {} } } @@ -295,6 +328,8 @@ impl<'a, I: Iterator> Impls<'a, I> { instance_opts, type_infos, fielddefault, + default_delegator_ident, + default_delegator_return, prefix, name, attrs, @@ -567,12 +602,23 @@ impl<'a, I: Iterator> Impls<'a, I> { #structure + #visibility struct #default_delegator_ident<#struct_trait>( + #scrate::rstd::marker::PhantomData<(#trait_and_instance)> + ) #where_clause; + impl<#impl_trait> #scrate::traits::StorageDefault<#typ> + for #default_delegator_ident<#trait_and_instance> #where_clause + { + fn default() -> Option<#typ> { + #default_delegator_return + } + } + impl<#impl_trait> #scrate::storage::hashed::generator::StorageMap<#kty, #typ> for #name<#trait_and_instance> #where_clause { type Query = #value_type; - type Hasher = #scrate::#hasher; + type Default = #default_delegator_ident<#trait_and_instance>; /// Get the prefix key in storage. fn prefix() -> &'static [u8] { @@ -730,6 +776,10 @@ impl<'a, I: Iterator> Impls<'a, I> { }) } } + + impl<#impl_trait> #scrate::storage::hashed::generator::DecodeLengthStorageMap<#kty, #typ> + for #name<#trait_and_instance> #where_clause + {} } } diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index eb479a2664..039bf8c8f6 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -762,10 +762,26 @@ fn decl_storage_items( } = sline; let type_infos = get_type_infos(storage_type); + let fielddefault = default_value.inner + .as_ref() + .map(|d| &d.expr) + .map(|d| quote!( #d )) + .unwrap_or_else(|| quote!{ Default::default() }); let kind = type_infos.kind.clone(); // Propagate doc attributes. let attrs = attrs.inner.iter().filter_map(|a| a.parse_meta().ok()).filter(|m| m.name() == "doc"); + // create default value delegator + let default_delegator_ident = Ident::new( + &format!("{}{}", name.to_string(), "DefaultDelegator"), + proc_macro2::Span::call_site(), + ); + let default_delegator_return = if !type_infos.is_option { + quote! { Some(#fielddefault) } + } else { + quote! { #fielddefault } + }; + let i = impls::Impls { scrate, visibility, @@ -774,8 +790,9 @@ fn decl_storage_items( traittype, instance_opts, type_infos, - fielddefault: default_value.inner.as_ref().map(|d| &d.expr).map(|d| quote!( #d )) - .unwrap_or_else(|| quote!{ Default::default() }), + fielddefault, + default_delegator_ident, + default_delegator_return, prefix: build_prefix(cratename, name), name, attrs, diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index 16e3ca5de9..9ebd848fca 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -62,7 +62,8 @@ mod double_map; pub mod traits; pub use self::storage::{ - StorageValue, StorageMap, EnumerableStorageMap, StorageDoubleMap, AppendableStorageMap + StorageValue, StorageMap, EnumerableStorageMap, StorageDoubleMap, AppendableStorageMap, + DecodeLengthStorageMap, }; pub use self::hashable::Hashable; pub use self::dispatch::{Parameter, Dispatchable, Callable, IsSubType}; diff --git a/srml/support/src/storage/hashed/generator.rs b/srml/support/src/storage/hashed/generator.rs index f8b8fb5483..27b459e3ff 100644 --- a/srml/support/src/storage/hashed/generator.rs +++ b/srml/support/src/storage/hashed/generator.rs @@ -14,12 +14,14 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Abstract storage to use on HashedStorage trait +//! Abstract storage to use on HashedStorage trait. Please refer to the +//! [top level docs](../../index.html) for more detailed documentation about storage traits and functions. use crate::codec::{self, Encode}; -use crate::rstd::prelude::{Vec, Box}; +use crate::rstd::{prelude::{Vec, Box}, iter::FromIterator}; #[cfg(feature = "std")] use crate::storage::unhashed::generator::UnhashedStorage; +use crate::traits::{StorageDefault, Len}; use runtime_io::{twox_64, twox_128, blake2_128, twox_256, blake2_256}; pub trait StorageHasher: 'static { @@ -164,6 +166,9 @@ impl HashedStorage for sr_primitives::StorageOverlay { pub trait StorageValue { /// The type that get/take returns. type Query; + /// Something that can provide the default value of this storage type. + type Default: StorageDefault; + /// Get the storage key. fn key() -> &'static [u8]; @@ -202,24 +207,75 @@ pub trait StorageValue { /// Append the given items to the value in the storage. /// /// `T` is required to implement `codec::EncodeAppend`. - fn append, I: codec::Encode>( - items: &[I], storage: &mut S - ) -> Result<(), &'static str> where T: codec::EncodeAppend { + fn append<'a, S, I, R>( + items: R, + storage: &mut S, + ) -> Result<(), &'static str> where + S: HashedStorage, + I: 'a + codec::Encode, + T: codec::EncodeAppend, + R: IntoIterator, + R::IntoIter: ExactSizeIterator, + { let new_val = ::append( - storage.get_raw(Self::key()).unwrap_or_default(), + // if the key exists, directly append to it. + storage.get_raw(Self::key()).unwrap_or_else(|| { + // otherwise, try and read a proper __provided__ default. + Self::Default::default().map(|v| v.encode()) + // or just use the Rust's `default()` value. + .unwrap_or_default() + }), items, ).map_err(|_| "Could not append given item")?; storage.put_raw(Self::key(), &new_val); Ok(()) } + + /// Safely append the given items to the value in the storage. If a codec error occurs, then the + /// old (presumably corrupt) value is replaced with the given `items`. + /// + /// `T` is required to implement `codec::EncodeAppend`. + fn append_or_put<'a, S, I, R>( + items: R, + storage: &mut S, + ) where + S: HashedStorage, + I: 'a + codec::Encode + Clone, + T: codec::EncodeAppend + FromIterator, + R: IntoIterator + Clone, + R::IntoIter: ExactSizeIterator, + { + Self::append(items.clone(), storage) + .unwrap_or_else(|_| Self::put(&items.into_iter().cloned().collect(), storage)); + } + + /// Read the length of the value in a fast way, without decoding the entire value. + /// + /// `T` is required to implement `Codec::DecodeLength`. + /// + /// Note that `0` is returned as the default value if no encoded value exists at the given key. + /// Therefore, this function cannot be used as a sign of _existence_. use the `::exists()` + /// function for this purpose. + fn decode_len>(storage: &mut S) -> Result + where T: codec::DecodeLength, T: Len + { + // attempt to get the length directly. + if let Some(k) = storage.get_raw(Self::key()) { + ::len(&k).map_err(|e| e.what()) + } else { + Ok(Self::Default::default().map(|v| v.len()).unwrap_or(0)) + } + } } /// A strongly-typed map in storage. pub trait StorageMap { /// The type that get/take returns. type Query; - + /// Hasher type type Hasher: StorageHasher; + /// Something that can provide the default value of this storage type. + type Default: StorageDefault; /// Get the prefix key in storage. fn prefix() -> &'static [u8]; @@ -295,16 +351,69 @@ pub trait EnumerableStorageMap: StorageMap: StorageMap { /// Append the given items to the value in the storage. /// - /// `T` is required to implement `codec::EncodeAppend`. - fn append, I: codec::Encode>( - key : &K, items: &[I], storage: &mut S - ) -> Result<(), &'static str> where V: codec::EncodeAppend { + /// `V` is required to implement `codec::EncodeAppend`. + fn append<'a, S, I, R>( + key : &K, + items: R, + storage: &mut S, + ) -> Result<(), &'static str> where + S: HashedStorage, + I: 'a + codec::Encode, + V: codec::EncodeAppend, + R: IntoIterator + Clone, + R::IntoIter: ExactSizeIterator, + { let k = Self::key_for(key); let new_val = ::append( - storage.get_raw(&k[..]).unwrap_or_default(), + storage.get_raw(&k[..]).unwrap_or_else(|| { + // otherwise, try and read a proper __provided__ default. + Self::Default::default().map(|v| v.encode()) + // or just use the default value. + .unwrap_or_default() + }), items, ).map_err(|_| "Could not append given item")?; storage.put_raw(&k[..], &new_val); Ok(()) } + + /// Safely append the given items to the value in the storage. If a codec error occurs, then the + /// old (presumably corrupt) value is replaced with the given `items`. + /// + /// `T` is required to implement `codec::EncodeAppend`. + fn append_or_insert<'a, S, I, R>( + key : &K, + items: R, + storage: &mut S, + ) where + S: HashedStorage, + I: 'a + codec::Encode + Clone, + V: codec::EncodeAppend + crate::rstd::iter::FromIterator, + R: IntoIterator + Clone, + R::IntoIter: ExactSizeIterator, + { + Self::append(key, items.clone(), storage) + .unwrap_or_else(|_| Self::insert(key, &items.into_iter().cloned().collect(), storage)); + } +} + +/// A storage map with a decodable length. +pub trait DecodeLengthStorageMap: StorageMap { + /// Read the length of the value in a fast way, without decoding the entire value. + /// + /// `T` is required to implement `Codec::DecodeLength`. + /// + /// Note that `0` is returned as the default value if no encoded value exists at the given key. + /// Therefore, this function cannot be used as a sign of _existence_. use the `::exists()` + /// function for this purpose. + fn decode_len>(key: &K, storage: &mut S) -> Result + where V: codec::DecodeLength, V: Len + { + let k = Self::key_for(key); + if let Some(v) = storage.get_raw(&k[..]) { + ::len(&v).map_err(|e| e.what()) + } else { + Ok(Self::Default::default().map(|v| v.len()).unwrap_or(0)) + } + } } diff --git a/srml/support/src/storage/mod.rs b/srml/support/src/storage/mod.rs index 385fad42eb..aa3faee878 100644 --- a/srml/support/src/storage/mod.rs +++ b/srml/support/src/storage/mod.rs @@ -17,10 +17,11 @@ //! Stuff to do with the runtime's storage. use crate::rstd::prelude::*; -use crate::rstd::borrow::Borrow; +use crate::rstd::{borrow::Borrow, iter::FromIterator}; use codec::{Codec, Encode, Decode, KeyedVec, EncodeAppend}; use hashed::generator::{HashedStorage, StorageHasher}; use unhashed::generator::UnhashedStorage; +use crate::traits::{StorageDefault, Len}; #[macro_use] pub mod storage_items; @@ -107,6 +108,8 @@ impl UnhashedStorage for RuntimeStorage { pub trait StorageValue { /// The type that get/take return. type Query; + /// Something that can provide the default value of this storage type. + type Default: StorageDefault; /// Get the storage key. fn key() -> &'static [u8]; @@ -136,12 +139,39 @@ pub trait StorageValue { /// Append the given item to the value in the storage. /// /// `T` is required to implement `codec::EncodeAppend`. - fn append(items: &[I]) -> Result<(), &'static str> - where T: EncodeAppend; + fn append<'a, I, R>(items: R) -> Result<(), &'static str> where + I: 'a + Encode, + T: EncodeAppend, + R: IntoIterator, + R::IntoIter: ExactSizeIterator; + + /// Append the given items to the value in the storage. + /// + /// `T` is required to implement `Codec::EncodeAppend`. + /// + /// Upon any failure, it replaces `items` as the new value (assuming that the previous stored + /// data is simply corrupt and no longer usable). + /// + /// ### WARNING + /// + /// use with care; if your use-case is not _exactly_ as what this function is doing, + /// you should use append and sensibly handle failure within the runtime code if it happens. + fn append_or_put<'a, I, R>(items: R) where + I: 'a + Encode + Clone, + T: EncodeAppend + FromIterator, + R: IntoIterator + Clone, + R::IntoIter: ExactSizeIterator; + + /// Read the length of the value in a fast way, without decoding the entire value. + /// + /// `T` is required to implement `Codec::DecodeLength`. + fn decode_len() -> Result + where T: codec::DecodeLength, T: Len; } impl StorageValue for U where U: hashed::generator::StorageValue { type Query = U::Query; + type Default = U::Default; fn key() -> &'static [u8] { >::key() @@ -167,17 +197,35 @@ impl StorageValue for U where U: hashed::generator::StorageValue fn take() -> Self::Query { U::take(&mut RuntimeStorage) } - fn append(items: &[I]) -> Result<(), &'static str> - where T: EncodeAppend + fn append<'a, I, R>(items: R) -> Result<(), &'static str> where + I: 'a + Encode, + T: EncodeAppend, + R: IntoIterator, + R::IntoIter: ExactSizeIterator, { U::append(items, &mut RuntimeStorage) } + fn append_or_put<'a, I, R>(items: R) where + I: 'a + Encode + Clone, + T: EncodeAppend + FromIterator, + R: IntoIterator + Clone, + R::IntoIter: ExactSizeIterator, + { + U::append_or_put(items, &mut RuntimeStorage) + } + fn decode_len() -> Result + where T: codec::DecodeLength, T: Len + { + U::decode_len(&mut RuntimeStorage) + } } /// A strongly-typed map in storage. pub trait StorageMap { /// The type that get/take return. type Query; + /// Something that can provide the default value of this storage type. + type Default: StorageDefault; /// Get the prefix key in storage. fn prefix() -> &'static [u8]; @@ -213,6 +261,7 @@ pub trait StorageMap { impl StorageMap for U where U: hashed::generator::StorageMap { type Query = U::Query; + type Default = U::Default; fn prefix() -> &'static [u8] { >::prefix() @@ -260,18 +309,85 @@ pub trait AppendableStorageMap: StorageMap { /// Append the given item to the value in the storage. /// /// `T` is required to implement `codec::EncodeAppend`. - fn append, I: Encode>(key: KeyArg, items: &[I]) -> Result<(), &'static str> - where V: EncodeAppend; + fn append<'a, KeyArg, I, R>( + key: KeyArg, + items: R, + ) -> Result<(), &'static str> where + KeyArg: Borrow, + I: 'a + codec::Encode, + V: EncodeAppend, + R: IntoIterator + Clone, + R::IntoIter: ExactSizeIterator; + + /// Append the given items to the value in the storage. + /// + /// `T` is required to implement `codec::EncodeAppend`. + /// + /// Upon any failure, it replaces `items` as the new value (assuming that the previous stored + /// data is simply corrupt and no longer usable). + /// + /// WARNING: use with care; if your use-case is not _exactly_ as what this function is doing, + /// you should use append and sensibly handle failure within the runtime code if it happens. + fn append_or_insert<'a, KeyArg, I, R>( + key: KeyArg, + items: R, + ) where + KeyArg: Borrow, + I: 'a + codec::Encode + Clone, + V: codec::EncodeAppend + FromIterator, + R: IntoIterator + Clone, + R::IntoIter: ExactSizeIterator; } impl AppendableStorageMap for U where U: hashed::generator::AppendableStorageMap { - fn append, I: Encode>(key: KeyArg, items: &[I]) -> Result<(), &'static str> - where V: EncodeAppend + fn append<'a, KeyArg, I, R>( + key: KeyArg, + items: R, + ) -> Result<(), &'static str> where + KeyArg: Borrow, + I: 'a + codec::Encode, + V: EncodeAppend, + R: IntoIterator + Clone, + R::IntoIter: ExactSizeIterator, { U::append(key.borrow(), items, &mut RuntimeStorage) } + + fn append_or_insert<'a, KeyArg, I, R>( + key: KeyArg, + items: R, + ) where + KeyArg: Borrow, + I: 'a + codec::Encode + Clone, + V: codec::EncodeAppend + FromIterator, + R: IntoIterator + Clone, + R::IntoIter: ExactSizeIterator, + { + U::append_or_insert(key.borrow(), items, &mut RuntimeStorage) + } +} + +/// A storage map with a decodable length. +pub trait DecodeLengthStorageMap: StorageMap { + /// Read the length of the value in a fast way, without decoding the entire value. + /// + /// `T` is required to implement `Codec::DecodeLength`. + /// + /// Has the same logic as [`StorageValue`](trait.StorageValue.html). + fn decode_len>(key: KeyArg) -> Result + where V: codec::DecodeLength, V: Len; +} + +impl DecodeLengthStorageMap for U + where U: hashed::generator::DecodeLengthStorageMap +{ + fn decode_len>(key: KeyArg) -> Result + where V: codec::DecodeLength, V: Len + { + U::decode_len(key.borrow(), &mut RuntimeStorage) + } } /// A storage map that can be enumerated. diff --git a/srml/support/src/storage/storage_items.rs b/srml/support/src/storage/storage_items.rs index 06cb8fc55b..a2a5c3229f 100644 --- a/srml/support/src/storage/storage_items.rs +++ b/srml/support/src/storage/storage_items.rs @@ -172,6 +172,7 @@ macro_rules! __storage_items_internal { impl $crate::storage::hashed::generator::StorageValue<$ty> for $name { type Query = $gettype; + type Default = (); /// Get the storage key. fn key() -> &'static [u8] { @@ -221,8 +222,8 @@ macro_rules! __storage_items_internal { impl $crate::storage::hashed::generator::StorageMap<$kty, $ty> for $name { type Query = $gettype; - type Hasher = $crate::Blake2_256; + type Default = (); /// Get the prefix key in storage. fn prefix() -> &'static [u8] { @@ -795,18 +796,41 @@ mod test3 { #[cfg(test)] #[allow(dead_code)] -mod test_map_vec_append { +mod test_append_and_len { + use crate::storage::{AppendableStorageMap, DecodeLengthStorageMap, StorageMap, StorageValue}; + use runtime_io::{with_externalities, TestExternalities}; + use codec::{Encode, Decode}; + pub trait Trait { type Origin; type BlockNumber; } + decl_module! { pub struct Module for enum Call where origin: T::Origin {} } + + #[derive(PartialEq, Eq, Clone, Encode, Decode)] + struct NoDef(u32); + crate::decl_storage! { trait Store for Module as Test { + NoDefault: Option; + JustVec: Vec; + JustVecWithDefault: Vec = vec![6, 9]; + OptionVec: Option>; + OptionVecWithDefault: Option> = Some(vec![6, 9]); + MapVec: map u32 => Vec; + MapVecWithDefault: map u32 => Vec = vec![6, 9]; + OptionMapVec: map u32 => Option>; + OptionMapVecWithDefault: map u32 => Option> = Some(vec![6, 9]); + + LinkedMapVec: linked_map u32 => Vec; + LinkedMapVecWithDefault: linked_map u32 => Vec = vec![6, 9]; + OptionLinkedMapVec: linked_map u32 => Option>; + OptionLinkedMapVecWithDefault: linked_map u32 => Option> = Some(vec![6, 9]); } } @@ -817,21 +841,116 @@ mod test_map_vec_append { type BlockNumber = u32; } + #[test] + fn default_for_option() { + with_externalities(&mut TestExternalities::default(), || { + assert_eq!(OptionVecWithDefault::get(), Some(vec![6, 9])); + assert_eq!(OptionVec::get(), None); + assert_eq!(JustVec::get(), vec![]); + }); + } + #[test] fn append_works() { - use crate::storage::{AppendableStorageMap, StorageMap, StorageValue}; - use runtime_io::{with_externalities, TestExternalities}; + with_externalities(&mut TestExternalities::default(), || { + let _ = MapVec::append(1, [1, 2, 3].iter()); + let _ = MapVec::append(1, [4, 5].iter()); + assert_eq!(MapVec::get(1), vec![1, 2, 3, 4, 5]); + + let _ = JustVec::append([1, 2, 3].iter()); + let _ = JustVec::append([4, 5].iter()); + assert_eq!(JustVec::get(), vec![1, 2, 3, 4, 5]); + }); + } + + #[test] + fn append_works_for_default() { + with_externalities(&mut TestExternalities::default(), || { + assert_eq!(JustVecWithDefault::get(), vec![6, 9]); + let _ = JustVecWithDefault::append([1].iter()); + assert_eq!(JustVecWithDefault::get(), vec![6, 9, 1]); + + assert_eq!(MapVecWithDefault::get(0), vec![6, 9]); + let _ = MapVecWithDefault::append(0, [1].iter()); + assert_eq!(MapVecWithDefault::get(0), vec![6, 9, 1]); + + assert_eq!(OptionVec::get(), None); + let _ = OptionVec::append([1].iter()); + assert_eq!(OptionVec::get(), Some(vec![1])); + }); + } + #[test] + fn append_or_put_works() { with_externalities(&mut TestExternalities::default(), || { - let _ = MapVec::append(1, &[1, 2, 3]); - let _ = MapVec::append(1, &[4, 5]); + let _ = MapVec::append_or_insert(1, [1, 2, 3].iter()); + let _ = MapVec::append_or_insert(1, [4, 5].iter()); assert_eq!(MapVec::get(1), vec![1, 2, 3, 4, 5]); - let _ = JustVec::append(&[1, 2, 3]); - let _ = JustVec::append(&[4, 5]); + let _ = JustVec::append_or_put([1, 2, 3].iter()); + let _ = JustVec::append_or_put([4, 5].iter()); assert_eq!(JustVec::get(), vec![1, 2, 3, 4, 5]); }); } + + #[test] + fn len_works() { + with_externalities(&mut TestExternalities::default(), || { + JustVec::put(&vec![1, 2, 3, 4]); + OptionVec::put(&vec![1, 2, 3, 4, 5]); + MapVec::insert(1, &vec![1, 2, 3, 4, 5, 6]); + LinkedMapVec::insert(2, &vec![1, 2, 3]); + + assert_eq!(JustVec::decode_len().unwrap(), 4); + assert_eq!(OptionVec::decode_len().unwrap(), 5); + assert_eq!(MapVec::decode_len(1).unwrap(), 6); + assert_eq!(LinkedMapVec::decode_len(2).unwrap(), 3); + }); + } + + #[test] + fn len_works_for_default() { + with_externalities(&mut TestExternalities::default(), || { + // vec + assert_eq!(JustVec::get(), vec![]); + assert_eq!(JustVec::decode_len(), Ok(0)); + + assert_eq!(JustVecWithDefault::get(), vec![6, 9]); + assert_eq!(JustVecWithDefault::decode_len(), Ok(2)); + + assert_eq!(OptionVec::get(), None); + assert_eq!(OptionVec::decode_len(), Ok(0)); + + assert_eq!(OptionVecWithDefault::get(), Some(vec![6, 9])); + assert_eq!(OptionVecWithDefault::decode_len(), Ok(2)); + + // map + assert_eq!(MapVec::get(0), vec![]); + assert_eq!(MapVec::decode_len(0), Ok(0)); + + assert_eq!(MapVecWithDefault::get(0), vec![6, 9]); + assert_eq!(MapVecWithDefault::decode_len(0), Ok(2)); + + assert_eq!(OptionMapVec::get(0), None); + assert_eq!(OptionMapVec::decode_len(0), Ok(0)); + + assert_eq!(OptionMapVecWithDefault::get(0), Some(vec![6, 9])); + assert_eq!(OptionMapVecWithDefault::decode_len(0), Ok(2)); + + // linked map + assert_eq!(LinkedMapVec::get(0), vec![]); + assert_eq!(LinkedMapVec::decode_len(0), Ok(0)); + + assert_eq!(LinkedMapVecWithDefault::get(0), vec![6, 9]); + assert_eq!(LinkedMapVecWithDefault::decode_len(0), Ok(2)); + + assert_eq!(OptionLinkedMapVec::get(0), None); + assert_eq!(OptionLinkedMapVec::decode_len(0), Ok(0)); + + assert_eq!(OptionLinkedMapVecWithDefault::get(0), Some(vec![6, 9])); + assert_eq!(OptionLinkedMapVecWithDefault::decode_len(0), Ok(2)); + }); + } } diff --git a/srml/support/src/traits.rs b/srml/support/src/traits.rs index 37262cdfcb..a5e52f5f66 100644 --- a/srml/support/src/traits.rs +++ b/srml/support/src/traits.rs @@ -26,6 +26,28 @@ use crate::sr_primitives::ConsensusEngineId; use super::for_each_tuple; +/// A trait that can return the default value of a storage item. This must only ever be implemented +/// for a special delegator struct for each storage item +pub trait StorageDefault: Sized { + /// Return the default value of type `V`. `None`, if `V` does not have a proper default value. + fn default() -> Option; +} + +// FIXME #1466 This is needed for `storage_items!`. Should be removed once it is deprecated. +impl StorageDefault for () { fn default() -> Option { Some(Default::default()) } } + +/// Anything that can have a `::len()` method. +pub trait Len { + /// Return the length of data type. + fn len(&self) -> usize; +} + +impl Len for T where ::IntoIter: ExactSizeIterator { + fn len(&self) -> usize { + self.clone().into_iter().len() + } +} + /// A trait for querying a single fixed value from a type. pub trait Get { /// Return a constant value. diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index d0b36ae14d..2343af8bec 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -578,7 +578,7 @@ impl Module { // We perform early return if we've reached the maximum capacity of the event list, // so `Events` seems to be corrupted. Also, this has happened after the start of execution // (since the event list is cleared at the block initialization). - if >::append(&[event]).is_err() { + if >::append([event].into_iter()).is_err() { // The most sensible thing to do here is to just ignore this event and wait until the // new block. return; -- GitLab From 3e257e011c98eef2671b9732af47fd2645b49f06 Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Tue, 27 Aug 2019 22:20:47 +0200 Subject: [PATCH 024/275] Eradicate native_equivalent (#3494) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add ability to supply extra storage in test-client * Don't use native_equivalent in tests. * Get rid of native_equivalent * Try to make fields private * Apply Basti's suggestions Co-Authored-By: Bastian Köcher --- Cargo.lock | 1 - core/client/src/genesis.rs | 6 ++- core/executor/src/native_executor.rs | 15 ++----- core/rpc/Cargo.toml | 1 - core/rpc/src/state/tests.rs | 16 +++++--- core/test-runtime/client/src/lib.rs | 58 ++++++++++++++++++---------- core/test-runtime/src/genesismap.rs | 16 ++++++-- node-template/src/service.rs | 5 +-- node/executor/src/lib.rs | 3 +- 9 files changed, 70 insertions(+), 51 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f3fc76d630..375d03fa47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4988,7 +4988,6 @@ dependencies = [ "sr-primitives 2.0.0", "sr-version 2.0.0", "substrate-client 2.0.0", - "substrate-executor 2.0.0", "substrate-keystore 2.0.0", "substrate-network 2.0.0", "substrate-primitives 2.0.0", diff --git a/core/client/src/genesis.rs b/core/client/src/genesis.rs index 3ac93f4f57..4791a34d17 100644 --- a/core/client/src/genesis.rs +++ b/core/client/src/genesis.rs @@ -54,8 +54,7 @@ mod tests { native_executor_instance!( Executor, test_client::runtime::api::dispatch, - test_client::runtime::native_version, - test_client::runtime::WASM_BINARY + test_client::runtime::native_version ); fn executor() -> executor::NativeExecutor { @@ -153,6 +152,7 @@ mod tests { vec![AccountKeyring::One.into(), AccountKeyring::Two.into()], 1000, None, + vec![], ).genesis_map(); let genesis_hash = insert_genesis_block(&mut storage); @@ -181,6 +181,7 @@ mod tests { vec![AccountKeyring::One.into(), AccountKeyring::Two.into()], 1000, None, + vec![], ).genesis_map(); let genesis_hash = insert_genesis_block(&mut storage); @@ -209,6 +210,7 @@ mod tests { vec![AccountKeyring::One.into(), AccountKeyring::Two.into()], 68, None, + vec![], ).genesis_map(); let genesis_hash = insert_genesis_block(&mut storage); diff --git a/core/executor/src/native_executor.rs b/core/executor/src/native_executor.rs index 937e003353..1ebf7f3146 100644 --- a/core/executor/src/native_executor.rs +++ b/core/executor/src/native_executor.rs @@ -49,9 +49,6 @@ pub fn with_native_environment(ext: &mut dyn Externalities, /// Delegate for dispatching a CodeExecutor call to native code. pub trait NativeExecutionDispatch: Send + Sync { - /// Get the wasm code that the native dispatch will be equivalent to. - fn native_equivalent() -> &'static [u8]; - /// Dispatch a method and input data to be executed natively. fn dispatch(ext: &mut dyn Externalities, method: &str, data: &[u8]) -> Result>; @@ -211,19 +208,13 @@ impl CodeExecutor for NativeExecutor { + ( $pub:vis $name:ident, $dispatcher:path, $version:path $(,)?) => { /// A unit struct which implements `NativeExecutionDispatch` feeding in the hard-coded runtime. $pub struct $name; - $crate::native_executor_instance!(IMPL $name, $dispatcher, $version, $code); + $crate::native_executor_instance!(IMPL $name, $dispatcher, $version); }; - (IMPL $name:ident, $dispatcher:path, $version:path, $code:expr) => { + (IMPL $name:ident, $dispatcher:path, $version:path) => { impl $crate::NativeExecutionDispatch for $name { - fn native_equivalent() -> &'static [u8] { - // WARNING!!! This assumes that the runtime was built *before* the main project. Until we - // get a proper build script, this must be strictly adhered to or things will go wrong. - $code - } - fn dispatch( ext: &mut $crate::Externalities<$crate::Blake2Hasher>, method: &str, diff --git a/core/rpc/Cargo.toml b/core/rpc/Cargo.toml index f35408c7b3..234761708e 100644 --- a/core/rpc/Cargo.toml +++ b/core/rpc/Cargo.toml @@ -18,7 +18,6 @@ codec = { package = "parity-scale-codec", version = "1.0.0" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" client = { package = "substrate-client", path = "../client" } -substrate-executor = { path = "../executor" } network = { package = "substrate-network", path = "../network" } primitives = { package = "substrate-primitives", path = "../primitives" } session = { package = "substrate-session", path = "../session" } diff --git a/core/rpc/src/state/tests.rs b/core/rpc/src/state/tests.rs index 0bb6d40e24..07e009d179 100644 --- a/core/rpc/src/state/tests.rs +++ b/core/rpc/src/state/tests.rs @@ -25,20 +25,24 @@ use test_client::{ consensus::BlockOrigin, runtime, }; -use substrate_executor::NativeExecutionDispatch; #[test] fn should_return_storage() { + const KEY: &[u8] = b":mock"; + const VALUE: &[u8] = b"hello world"; + let core = tokio::runtime::Runtime::new().unwrap(); - let client = Arc::new(test_client::new()); + let client = TestClientBuilder::new() + .add_extra_storage(KEY.to_vec(), VALUE.to_vec()) + .build(); let genesis_hash = client.genesis_hash(); - let client = State::new(client, Subscriptions::new(Arc::new(core.executor()))); - let key = StorageKey(b":code".to_vec()); + let client = State::new(Arc::new(client), Subscriptions::new(Arc::new(core.executor()))); + let key = StorageKey(KEY.to_vec()); assert_eq!( client.storage(key.clone(), Some(genesis_hash).into()) .map(|x| x.map(|x| x.0.len())).unwrap().unwrap() as usize, - LocalExecutor::native_equivalent().len(), + VALUE.len(), ); assert_matches!( client.storage_hash(key.clone(), Some(genesis_hash).into()).map(|x| x.is_some()), @@ -46,7 +50,7 @@ fn should_return_storage() { ); assert_eq!( client.storage_size(key.clone(), None).unwrap().unwrap() as usize, - LocalExecutor::native_equivalent().len(), + VALUE.len(), ); } diff --git a/core/test-runtime/client/src/lib.rs b/core/test-runtime/client/src/lib.rs index f1cbb6fd8c..ad5badf8bf 100644 --- a/core/test-runtime/client/src/lib.rs +++ b/core/test-runtime/client/src/lib.rs @@ -51,8 +51,7 @@ mod local_executor { native_executor_instance!( pub LocalExecutor, runtime::api::dispatch, - runtime::native_version, - runtime::WASM_BINARY + runtime::native_version ); } @@ -97,12 +96,34 @@ pub type LightExecutor = client::light::call_executor::RemoteOrLocalCallExecutor pub struct GenesisParameters { support_changes_trie: bool, heap_pages_override: Option, + extra_storage: Vec<(Vec, Vec)>, +} + +impl GenesisParameters { + fn genesis_config(&self) -> GenesisConfig { + GenesisConfig::new( + self.support_changes_trie, + vec![ + sr25519::Public::from(Sr25519Keyring::Alice).into(), + sr25519::Public::from(Sr25519Keyring::Bob).into(), + sr25519::Public::from(Sr25519Keyring::Charlie).into(), + ], + vec![ + AccountKeyring::Alice.into(), + AccountKeyring::Bob.into(), + AccountKeyring::Charlie.into(), + ], + 1000, + self.heap_pages_override, + self.extra_storage.clone(), + ) + } } impl generic_test_client::GenesisInit for GenesisParameters { fn genesis_storage(&self) -> (StorageOverlay, ChildrenStorageOverlay) { use codec::Encode; - let mut storage = genesis_config(self.support_changes_trie, self.heap_pages_override).genesis_map(); + let mut storage = self.genesis_config().genesis_map(); let child_roots = storage.1.iter().map(|(sk, child_map)| { let state_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( @@ -157,6 +178,13 @@ pub trait TestClientBuilderExt: Sized { /// Override the default value for Wasm heap pages. fn set_heap_pages(self, heap_pages: u64) -> Self; + /// Add an extra value into the genesis storage. + /// + /// # Panics + /// + /// Panics if the key is empty. + fn add_extra_storage>, V: Into>>(self, key: K, value: V) -> Self; + /// Build the test client. fn build(self) -> Client { self.build_with_longest_chain().0 @@ -182,28 +210,18 @@ impl TestClientBuilderExt for TestClientBuilder< self } + fn add_extra_storage>, V: Into>>(mut self, key: K, value: V) -> Self { + let key = key.into(); + assert!(!key.is_empty()); + self.genesis_init_mut().extra_storage.push((key, value.into())); + self + } + fn build_with_longest_chain(self) -> (Client, client::LongestChain) { self.build_with_native_executor(None) } } -fn genesis_config(support_changes_trie: bool, heap_pages_override: Option) -> GenesisConfig { - GenesisConfig::new( - support_changes_trie, - vec![ - sr25519::Public::from(Sr25519Keyring::Alice).into(), - sr25519::Public::from(Sr25519Keyring::Bob).into(), - sr25519::Public::from(Sr25519Keyring::Charlie).into(), - ], vec![ - AccountKeyring::Alice.into(), - AccountKeyring::Bob.into(), - AccountKeyring::Charlie.into(), - ], - 1000, - heap_pages_override, - ) -} - /// Creates new client instance used for tests. pub fn new() -> Client { TestClientBuilder::new().build() diff --git a/core/test-runtime/src/genesismap.rs b/core/test-runtime/src/genesismap.rs index 7686ed08bc..c2dd49156d 100644 --- a/core/test-runtime/src/genesismap.rs +++ b/core/test-runtime/src/genesismap.rs @@ -25,10 +25,12 @@ use sr_primitives::traits::{Block as BlockT, Hash as HashT, Header as HeaderT}; /// Configuration of a general Substrate test genesis block. pub struct GenesisConfig { - pub changes_trie_config: Option, - pub authorities: Vec, - pub balances: Vec<(AccountId, u64)>, - pub heap_pages_override: Option, + changes_trie_config: Option, + authorities: Vec, + balances: Vec<(AccountId, u64)>, + heap_pages_override: Option, + /// Additional storage key pairs that will be added to the genesis map. + extra_storage: Vec<(Vec, Vec)>, } impl GenesisConfig { @@ -38,6 +40,7 @@ impl GenesisConfig { endowed_accounts: Vec, balance: u64, heap_pages_override: Option, + extra_storage: Vec<(Vec, Vec)>, ) -> Self { GenesisConfig { changes_trie_config: match support_changes_trie { @@ -47,6 +50,7 @@ impl GenesisConfig { authorities: authorities.clone(), balances: endowed_accounts.into_iter().map(|a| (a, balance)).collect(), heap_pages_override, + extra_storage, } } @@ -70,6 +74,10 @@ impl GenesisConfig { map.insert(well_known_keys::CHANGES_TRIE_CONFIG.to_vec(), changes_trie_config.encode()); } map.insert(twox_128(&b"sys:auth"[..])[..].to_vec(), self.authorities.encode()); + // Finally, add the extra storage entries. + for (key, value) in self.extra_storage.iter().cloned() { + map.insert(key, value); + } (map, Default::default()) } } diff --git a/node-template/src/service.rs b/node-template/src/service.rs index 07c0aa26cf..7bb4cc8d52 100644 --- a/node-template/src/service.rs +++ b/node-template/src/service.rs @@ -18,8 +18,7 @@ pub use substrate_executor::NativeExecutor; native_executor_instance!( pub Executor, node_template_runtime::api::dispatch, - node_template_runtime::native_version, - WASM_BINARY + node_template_runtime::native_version ); construct_simple_protocol! { @@ -72,7 +71,7 @@ macro_rules! new_full_start { Ok(import_queue) })?; - + (builder, import_setup, inherent_data_providers, tasks_to_spawn) }} } diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index 874c5a1b6d..eba744f62a 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -30,8 +30,7 @@ use substrate_executor::native_executor_instance; native_executor_instance!( pub Executor, node_runtime::api::dispatch, - node_runtime::native_version, - node_runtime::WASM_BINARY + node_runtime::native_version ); #[cfg(test)] -- GitLab From e3f57ff9c86866a040e2c1f5dbe0b994b103e5cd Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 28 Aug 2019 11:35:51 +0200 Subject: [PATCH 025/275] Some tweaks to offchain HTTP workers (#3488) --- core/offchain/src/api/http.rs | 62 ++++++++++++++++++------------ core/offchain/src/api/timestamp.rs | 2 + 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/core/offchain/src/api/http.rs b/core/offchain/src/api/http.rs index 287e3f99be..9ea666862c 100644 --- a/core/offchain/src/api/http.rs +++ b/core/offchain/src/api/http.rs @@ -84,7 +84,9 @@ enum HttpApiRequest { Dispatched(Option), /// Received a response. Response(HttpApiRequestRp), - /// A request has been dispatched then produced an error. + /// A request has been dispatched but the worker notified us of an error. We report this + /// failure to the user as an `IoError` and remove the request from the list as soon as + /// possible. Fail(hyper::Error), } @@ -100,6 +102,9 @@ struct HttpApiRequestRp { /// Body of the response, as a channel of `Chunk` objects. /// While the code is designed to drop the `Receiver` once it ends, we wrap it within a /// `Fuse` in order to be extra precautious about panics. + /// Elements extracted from the channel are first put into `current_read_chunk`. + /// If the channel produces an error, then that is translated into an `IoError` and the request + /// is removed from the list. body: stream::Fuse>>, /// Chunk that has been extracted from the channel and that is currently being read. /// Reading data from the response should read from this field in priority. @@ -170,8 +175,9 @@ impl HttpApi { }; let mut deadline = timestamp::deadline_to_future(deadline); - // Closure that writes data to a sender, taking the deadline into account. - // If `IoError` is returned, don't forget to destroy the request. + // Closure that writes data to a sender, taking the deadline into account. Can return `Ok` + // (if the body has been written), or `DeadlineReached`, or `IoError`. + // If `IoError` is returned, don't forget to remove the request from the list. let mut poll_sender = move |sender: &mut hyper::body::Sender| -> Result<(), HttpError> { let mut when_ready = future::maybe_done(Compat01As03::new( futures01::future::poll_fn(|| sender.poll_ready()) @@ -220,7 +226,8 @@ impl HttpApi { } } } else { - // Dropping the sender to finish writing. + // Writing an empty body is a hint that we should stop writing. Dropping + // the sender. self.requests.insert(request_id, HttpApiRequest::Dispatched(None)); return Ok(()) } @@ -237,7 +244,8 @@ impl HttpApi { } } else { - // Dropping the sender to finish writing. + // Writing an empty body is a hint that we should stop writing. Dropping + // the sender. self.requests.insert(request_id, HttpApiRequest::Response(HttpApiRequestRp { sending_body: None, ..response @@ -297,6 +305,7 @@ impl HttpApi { loop { // Within that loop, first try to see if we have all the elements for a response. + // This includes the situation where the deadline is reached. { let mut output = Vec::with_capacity(ids.len()); let mut must_wait_more = false; @@ -337,7 +346,8 @@ impl HttpApi { } } - // Grab next message, or call `continue` if deadline is reached. + // Grab next message from the worker. We call `continue` if deadline is reached so that + // we loop back and `return`. let next_message = { let mut next_msg = future::maybe_done(self.from_worker.next()); futures::executor::block_on(future::select(&mut next_msg, &mut deadline)); @@ -410,7 +420,7 @@ impl HttpApi { buffer: &mut [u8], deadline: Option ) -> Result { - // Do an implicit non-blocking wait on the request. + // Do an implicit wait on the request. let _ = self.response_wait(&[request_id], deadline); // Remove the request from the list and handle situations where the request is invalid or @@ -419,12 +429,15 @@ impl HttpApi { Some(HttpApiRequest::Response(r)) => r, // Because we called `response_wait` above, we know that the deadline has been reached // and we still haven't received a response. - Some(HttpApiRequest::Dispatched(_)) => return Err(HttpError::DeadlineReached), + Some(rq @ HttpApiRequest::Dispatched(_)) => { + self.requests.insert(request_id, rq); + return Err(HttpError::DeadlineReached) + }, // The request has failed. Some(HttpApiRequest::Fail { .. }) => return Err(HttpError::IoError), // Request hasn't been dispatched yet; reading the body is invalid. - Some(rq) => { + Some(rq @ HttpApiRequest::NotDispatched(_, _)) => { self.requests.insert(request_id, rq); return Err(HttpError::Invalid) } @@ -432,12 +445,7 @@ impl HttpApi { }; // Convert the deadline into a `Future` that resolves when the deadline is reached. - let mut deadline = future::maybe_done(match deadline { - Some(deadline) => future::Either::Left( - futures_timer::Delay::new(timestamp::timestamp_from_now(deadline)) - ), - None => future::Either::Right(future::pending()) - }); + let mut deadline = timestamp::deadline_to_future(deadline); loop { // First read from `current_read_chunk`. @@ -530,9 +538,11 @@ enum WorkerToApi { /// because we don't want the `HttpApi` to have to drive the reading. /// Instead, reading an item from the channel will notify the worker task, which will push /// the next item. + /// Can also be used to send an error, in case an error happend on the HTTP socket. After + /// an error is sent, the channel will close. body: mpsc::Receiver>, }, - /// A request has failed because of an error. + /// A request has failed because of an error. The request is then no longer valid. Fail { /// The ID that was passed to the worker. id: HttpRequestId, @@ -541,16 +551,19 @@ enum WorkerToApi { }, } +/// Wraps around a `hyper::Client` with either TLS enabled or disabled. enum HyperClient { - Http(hyper::Client), + /// Everything is ok and HTTPS is available. Https(hyper::Client, hyper::Body>), + /// We failed to initialize HTTPS and therefore only allow HTTP. + Http(hyper::Client), } impl HyperClient { /// Creates new hyper client. /// /// By default we will try to initialize the `HttpsConnector`, - /// if that's not possible we'll fall back to `HttpConnector`. + /// If that's not possible we'll fall back to `HttpConnector`. pub fn new() -> Self { match hyper_tls::HttpsConnector::new(1) { Ok(tls) => HyperClient::Https(hyper::Client::builder().build(tls)), @@ -576,13 +589,13 @@ pub struct HttpWorker { /// HTTP request being processed by the worker. enum HttpWorkerRequest { - /// Request has been dispatched and is waiting for a response. + /// Request has been dispatched and is waiting for a response from the Internet. Dispatched(Compat01As03), - /// Reading the body of the response and sending it to the channel. + /// Progressively reading the body of the response and sending it to the channel. ReadBody { - /// Body to read `Chunk`s from. + /// Body to read `Chunk`s from. Only used if the channel is ready to accept data. body: Compat01As03, - /// Where to send the chunks. + /// Channel to the [`HttpApi`] where we send the chunks to. tx: mpsc::Sender>, }, } @@ -632,7 +645,7 @@ impl Future for HttpWorker { }); me.requests.push((id, HttpWorkerRequest::ReadBody { body, tx: body_tx })); - cx.waker().wake_by_ref(); // wake up in order to poll the new future + cx.waker().wake_by_ref(); // reschedule in order to poll the new future continue } @@ -648,11 +661,12 @@ impl Future for HttpWorker { } } + // `tx` is ready. Read a chunk from the socket and send it to the channel. match Stream::poll_next(Pin::new(&mut body), cx) { Poll::Ready(Some(Ok(chunk))) => { let _ = tx.start_send(Ok(chunk)); me.requests.push((id, HttpWorkerRequest::ReadBody { body, tx })); - cx.waker().wake_by_ref(); // notify in order to poll again + cx.waker().wake_by_ref(); // reschedule in order to continue reading } Poll::Ready(Some(Err(err))) => { let _ = tx.start_send(Err(err)); diff --git a/core/offchain/src/api/timestamp.rs b/core/offchain/src/api/timestamp.rs index f106ac7273..445c7f3878 100644 --- a/core/offchain/src/api/timestamp.rs +++ b/core/offchain/src/api/timestamp.rs @@ -46,6 +46,8 @@ pub fn timestamp_from_now(timestamp: Timestamp) -> Duration { } /// Converts the deadline into a `Future` that resolves when the deadline is reached. +/// +/// If `None`, returns a never-ending `Future`. pub fn deadline_to_future( deadline: Option, ) -> futures::future::MaybeDone { -- GitLab From ae9f8d04dcf39ded1e0f3ddb6477cd02c37f8621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Wed, 28 Aug 2019 13:46:52 +0100 Subject: [PATCH 026/275] im-online: use generic crypto (#3500) * im-online: support using ed25519 and sr25519 crypto * app-crypto: add trait bounds to RuntimePublic::Signature * im-online: add missing type annotations * authority-discovery: depend on im-online module and use its crypto * node: set i'm online crypto to sr25519 * node: bump spec_version * rpc: don't generate i'm online pubkey in insert_key method * im-online: fix docs * im-online: move app crypto packages * aura: move app crypto packages --- Cargo.lock | 1 + core/application-crypto/src/traits.rs | 5 +- core/consensus/aura/primitives/src/lib.rs | 32 ++++---- core/rpc/src/author/mod.rs | 2 +- node/cli/src/chain_spec.rs | 2 +- node/runtime/src/lib.rs | 19 ++--- srml/authority-discovery/Cargo.toml | 3 + srml/authority-discovery/src/lib.rs | 99 ++++++++++++++--------- srml/im-online/src/lib.rs | 95 +++++++++++++--------- 9 files changed, 156 insertions(+), 102 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 375d03fa47..b1936f4177 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3826,6 +3826,7 @@ dependencies = [ "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", + "sr-staking-primitives 2.0.0", "sr-std 2.0.0", "srml-im-online 0.1.0", "srml-session 2.0.0", diff --git a/core/application-crypto/src/traits.rs b/core/application-crypto/src/traits.rs index d7f1eafe35..323c9c3e54 100644 --- a/core/application-crypto/src/traits.rs +++ b/core/application-crypto/src/traits.rs @@ -17,6 +17,7 @@ use primitives::crypto::{KeyTypeId, CryptoType, IsWrappedBy, Public}; #[cfg(feature = "std")] use primitives::crypto::Pair; +use codec::Codec; /// An application-specific key. pub trait AppKey: 'static + Send + Sync + Sized + CryptoType + Clone { @@ -72,7 +73,7 @@ pub trait AppSignature: AppKey + Eq + PartialEq + MaybeDebugHash { /// A runtime interface for a public key. pub trait RuntimePublic: Sized { /// The signature that will be generated when signing with the corresponding private key. - type Signature; + type Signature: Codec + MaybeDebugHash + Eq + PartialEq + Clone; /// Returns all public keys for the given key type in the keystore. fn all(key_type: KeyTypeId) -> crate::Vec; @@ -97,7 +98,7 @@ pub trait RuntimePublic: Sized { /// A runtime interface for an application's public key. pub trait RuntimeAppPublic: Sized { /// The signature that will be generated when signing with the corresponding private key. - type Signature; + type Signature: Codec + MaybeDebugHash + Eq + PartialEq + Clone; /// Returns all public keys for this application in the keystore. fn all() -> crate::Vec; diff --git a/core/consensus/aura/primitives/src/lib.rs b/core/consensus/aura/primitives/src/lib.rs index 84671e5ae6..e4620fcdbf 100644 --- a/core/consensus/aura/primitives/src/lib.rs +++ b/core/consensus/aura/primitives/src/lib.rs @@ -23,38 +23,38 @@ use substrate_client::decl_runtime_apis; use rstd::vec::Vec; use sr_primitives::ConsensusEngineId; -mod app_sr25519 { - use app_crypto::{app_crypto, key_types::AURA, sr25519}; - app_crypto!(sr25519, AURA); -} - pub mod sr25519 { + mod app_sr25519 { + use app_crypto::{app_crypto, key_types::AURA, sr25519}; + app_crypto!(sr25519, AURA); + } + /// An Aura authority keypair using S/R 25519 as its crypto. #[cfg(feature = "std")] - pub type AuthorityPair = super::app_sr25519::Pair; + pub type AuthorityPair = app_sr25519::Pair; /// An Aura authority signature using S/R 25519 as its crypto. - pub type AuthoritySignature = super::app_sr25519::Signature; + pub type AuthoritySignature = app_sr25519::Signature; /// An Aura authority identifier using S/R 25519 as its crypto. - pub type AuthorityId = super::app_sr25519::Public; -} - -mod app_ed25519 { - use app_crypto::{app_crypto, key_types::AURA, ed25519}; - app_crypto!(ed25519, AURA); + pub type AuthorityId = app_sr25519::Public; } pub mod ed25519 { + mod app_ed25519 { + use app_crypto::{app_crypto, key_types::AURA, ed25519}; + app_crypto!(ed25519, AURA); + } + /// An Aura authority keypair using Ed25519 as its crypto. #[cfg(feature = "std")] - pub type AuthorityPair = super::app_ed25519::Pair; + pub type AuthorityPair = app_ed25519::Pair; /// An Aura authority signature using Ed25519 as its crypto. - pub type AuthoritySignature = super::app_ed25519::Signature; + pub type AuthoritySignature = app_ed25519::Signature; /// An Aura authority identifier using Ed25519 as its crypto. - pub type AuthorityId = super::app_ed25519::Public; + pub type AuthorityId = app_ed25519::Public; } /// The `ConsensusEngineId` of AuRa. diff --git a/core/rpc/src/author/mod.rs b/core/rpc/src/author/mod.rs index 6e2d7aa92a..0290a534ea 100644 --- a/core/rpc/src/author/mod.rs +++ b/core/rpc/src/author/mod.rs @@ -162,7 +162,7 @@ impl AuthorApi, BlockHash

> for Author whe Some(public) => public.0, None => { let maybe_public = match key_type { - key_types::BABE | key_types::IM_ONLINE | key_types::SR25519 => + key_types::BABE | key_types::SR25519 => sr25519::Pair::from_string(&suri, maybe_password) .map(|pair| pair.public().to_raw_vec()), key_types::GRANDPA | key_types::ED25519 => diff --git a/node/cli/src/chain_spec.rs b/node/cli/src/chain_spec.rs index f83958eef4..00bcb25776 100644 --- a/node/cli/src/chain_spec.rs +++ b/node/cli/src/chain_spec.rs @@ -30,7 +30,7 @@ use hex_literal::hex; use substrate_telemetry::TelemetryEndpoints; use grandpa_primitives::{AuthorityId as GrandpaId}; use babe_primitives::{AuthorityId as BabeId}; -use im_online::AuthorityId as ImOnlineId; +use im_online::sr25519::{AuthorityId as ImOnlineId}; use sr_primitives::Perbill; const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 5260a3ef43..d23e3bb457 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -47,7 +47,7 @@ use elections::VoteIndex; use version::NativeVersion; use primitives::OpaqueMetadata; use grandpa::{AuthorityId as GrandpaId, AuthorityWeight as GrandpaWeight}; -use im_online::{AuthorityId as ImOnlineId}; +use im_online::sr25519::{AuthorityId as ImOnlineId}; #[cfg(any(feature = "std", test))] pub use sr_primitives::BuildStorage; @@ -79,7 +79,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 153, + spec_version: 154, impl_version: 154, apis: RUNTIME_API_VERSIONS, }; @@ -393,6 +393,7 @@ impl sudo::Trait for Runtime { } impl im_online::Trait for Runtime { + type AuthorityId = ImOnlineId; type Call = Call; type Event = Event; type UncheckedExtrinsic = UncheckedExtrinsic; @@ -447,8 +448,8 @@ construct_runtime!( Treasury: treasury::{Module, Call, Storage, Event}, Contracts: contracts, Sudo: sudo, - ImOnline: im_online::{Module, Call, Storage, Event, ValidateUnsigned, Config}, - AuthorityDiscovery: authority_discovery::{Module, Call, Config}, + ImOnline: im_online::{Module, Call, Storage, Event, ValidateUnsigned, Config}, + AuthorityDiscovery: authority_discovery::{Module, Call, Config}, Offences: offences::{Module, Call, Storage, Event}, } ); @@ -578,19 +579,19 @@ impl_runtime_apis! { } } - impl authority_discovery_primitives::AuthorityDiscoveryApi for Runtime { - fn authority_id() -> Option { + impl authority_discovery_primitives::AuthorityDiscoveryApi for Runtime { + fn authority_id() -> Option { AuthorityDiscovery::authority_id() } - fn authorities() -> Vec { + fn authorities() -> Vec { AuthorityDiscovery::authorities() } - fn sign(payload: Vec, authority_id: im_online::AuthorityId) -> Option> { + fn sign(payload: Vec, authority_id: ImOnlineId) -> Option> { AuthorityDiscovery::sign(payload, authority_id) } - fn verify(payload: Vec, signature: Vec, public_key: im_online::AuthorityId) -> bool { + fn verify(payload: Vec, signature: Vec, public_key: ImOnlineId) -> bool { AuthorityDiscovery::verify(payload, signature, public_key) } } diff --git a/srml/authority-discovery/Cargo.toml b/srml/authority-discovery/Cargo.toml index 5d52bdb246..f4c2d4e2b0 100644 --- a/srml/authority-discovery/Cargo.toml +++ b/srml/authority-discovery/Cargo.toml @@ -17,6 +17,9 @@ srml-support = { path = "../support", default-features = false } sr-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } +[dev-dependencies] +sr-staking-primitives = { path = "../../core/sr-staking-primitives", default-features = false } + [features] default = ["std"] std = [ diff --git a/srml/authority-discovery/src/lib.rs b/srml/authority-discovery/src/lib.rs index 00912aeffe..ffcb6672c8 100644 --- a/srml/authority-discovery/src/lib.rs +++ b/srml/authority-discovery/src/lib.rs @@ -33,18 +33,20 @@ use codec::{Decode, Encode}; use rstd::prelude::*; use srml_support::{decl_module, decl_storage, StorageValue}; -pub trait Trait: system::Trait + session::Trait {} +pub trait Trait: system::Trait + session::Trait + im_online::Trait {} + +type AuthorityIdFor = ::AuthorityId; decl_storage! { trait Store for Module as AuthorityDiscovery { /// The current set of keys that may issue a heartbeat. - Keys get(keys): Vec; + Keys get(keys): Vec>; } add_extra_genesis { - config(keys): Vec; + config(keys): Vec>; build(| storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &GenesisConfig + config: &GenesisConfig, | { sr_io::with_storage( storage, @@ -64,10 +66,10 @@ impl Module { /// set, otherwise this function returns None. The restriction might be /// softened in the future in case a consumer needs to learn own authority /// identifier. - pub fn authority_id() -> Option { - let authorities = Keys::get(); + pub fn authority_id() -> Option> { + let authorities = Keys::::get(); - let local_keys = im_online::AuthorityId::all(); + let local_keys = >::all(); authorities.into_iter().find_map(|authority| { if local_keys.contains(&authority) { @@ -79,12 +81,12 @@ impl Module { } /// Retrieve authority identifiers of the current authority set. - pub fn authorities() -> Vec { - Keys::get() + pub fn authorities() -> Vec> { + Keys::::get() } /// Sign the given payload with the private key corresponding to the given authority id. - pub fn sign(payload: Vec, authority_id: im_online::AuthorityId) -> Option> { + pub fn sign(payload: Vec, authority_id: AuthorityIdFor) -> Option> { authority_id.sign(&payload).map(|s| s.encode()) } @@ -93,27 +95,27 @@ impl Module { pub fn verify( payload: Vec, signature: Vec, - authority_id: im_online::AuthorityId, + authority_id: AuthorityIdFor, ) -> bool { - im_online::AuthoritySignature::decode(&mut &signature[..]) + as RuntimeAppPublic>::Signature::decode(&mut &signature[..]) .map(|s| authority_id.verify(&payload, &s)) .unwrap_or(false) } - fn initialize_keys(keys: &[im_online::AuthorityId]) { + fn initialize_keys(keys: &[AuthorityIdFor]) { if !keys.is_empty() { - assert!(Keys::get().is_empty(), "Keys are already initialized!"); - Keys::put_ref(keys); + assert!(Keys::::get().is_empty(), "Keys are already initialized!"); + Keys::::put_ref(keys); } } } impl session::OneSessionHandler for Module { - type Key = im_online::AuthorityId; + type Key = AuthorityIdFor; fn on_genesis_session<'a, I: 'a>(validators: I) where - I: Iterator, + I: Iterator, { let keys = validators.map(|x| x.1).collect::>(); Self::initialize_keys(&keys); @@ -121,10 +123,10 @@ impl session::OneSessionHandler for Module { fn on_new_session<'a, I: 'a>(_changed: bool, _validators: I, next_validators: I) where - I: Iterator, + I: Iterator, { // Remember who the authorities are for the new session. - Keys::put(next_validators.map(|x| x.1).collect::>()); + Keys::::put(next_validators.map(|x| x.1).collect::>()); } fn on_disabled(_i: usize) { @@ -139,9 +141,11 @@ mod tests { use primitives::testing::KeyStore; use primitives::{crypto::key_types, sr25519, traits::BareCryptoStore, H256}; use sr_io::{with_externalities, TestExternalities}; + use sr_primitives::generic::UncheckedExtrinsic; use sr_primitives::testing::{Header, UintAuthorityId}; use sr_primitives::traits::{ConvertInto, IdentityLookup, OpaqueKeys}; use sr_primitives::Perbill; + use sr_staking_primitives::CurrentElectedSet; use srml_support::{impl_outer_origin, parameter_types}; type AuthorityDiscovery = Module; @@ -151,12 +155,21 @@ mod tests { pub struct Test; impl Trait for Test {} + type AuthorityId = im_online::sr25519::AuthorityId; + + pub struct DummyCurrentElectedSet(std::marker::PhantomData); + impl CurrentElectedSet for DummyCurrentElectedSet { + fn current_elected_set() -> Vec { + vec![] + } + } + pub struct TestOnSessionEnding; - impl session::OnSessionEnding for TestOnSessionEnding { + impl session::OnSessionEnding for TestOnSessionEnding { fn on_session_ending( _: SessionIndex, _: SessionIndex, - ) -> Option> { + ) -> Option> { None } } @@ -167,11 +180,25 @@ mod tests { type ShouldEndSession = session::PeriodicSessions; type SessionHandler = TestSessionHandler; type Event = (); - type ValidatorId = im_online::AuthorityId; + type ValidatorId = AuthorityId; type ValidatorIdOf = ConvertInto; type SelectInitialValidators = (); } + impl session::historical::Trait for Test { + type FullIdentification = (); + type FullIdentificationOf = (); + } + + impl im_online::Trait for Test { + type AuthorityId = AuthorityId; + type Call = im_online::Call; + type Event = (); + type UncheckedExtrinsic = UncheckedExtrinsic<(), im_online::Call, (), ()>; + type ReportUnresponsiveness = (); + type CurrentElectedSet = DummyCurrentElectedSet; + } + pub type BlockNumber = u64; parameter_types! { @@ -191,7 +218,7 @@ mod tests { type Call = (); type Hash = H256; type Hashing = ::sr_primitives::traits::BlakeTwo256; - type AccountId = im_online::AuthorityId; + type AccountId = AuthorityId; type Lookup = IdentityLookup; type Header = Header; type WeightMultiplierUpdate = (); @@ -208,17 +235,17 @@ mod tests { } pub struct TestSessionHandler; - impl session::SessionHandler for TestSessionHandler { + impl session::SessionHandler for TestSessionHandler { fn on_new_session( _changed: bool, - _validators: &[(im_online::AuthorityId, Ks)], - _queued_validators: &[(im_online::AuthorityId, Ks)], + _validators: &[(AuthorityId, Ks)], + _queued_validators: &[(AuthorityId, Ks)], ) { } fn on_disabled(_validator_index: usize) {} - fn on_genesis_session(_validators: &[(im_online::AuthorityId, Ks)]) {} + fn on_genesis_session(_validators: &[(AuthorityId, Ks)]) {} } #[test] @@ -236,17 +263,17 @@ mod tests { .sr25519_public_keys(key_types::IM_ONLINE) .pop() .unwrap(); - let authority_id = im_online::AuthorityId::from(public_key); + let authority_id = AuthorityId::from(public_key); // Build genesis. let mut t = system::GenesisConfig::default() .build_storage::() .unwrap(); - GenesisConfig { + GenesisConfig:: { keys: vec![authority_id.clone()], } - .assimilate_storage::(&mut t) + .assimilate_storage(&mut t) .unwrap(); // Create externalities. @@ -279,11 +306,11 @@ mod tests { let keys = vec![(); 5] .iter() .map(|_x| sr25519::Pair::generate_with_phrase(None).0.public()) - .map(im_online::AuthorityId::from) + .map(AuthorityId::from) .collect(); - GenesisConfig { keys: keys } - .assimilate_storage::(&mut t) + GenesisConfig:: { keys: keys } + .assimilate_storage(&mut t) .unwrap(); // Create externalities. @@ -310,17 +337,17 @@ mod tests { .sr25519_public_keys(key_types::IM_ONLINE) .pop() .unwrap(); - let authority_id = im_online::AuthorityId::from(public_key); + let authority_id = AuthorityId::from(public_key); // Build genesis. let mut t = system::GenesisConfig::default() .build_storage::() .unwrap(); - GenesisConfig { + GenesisConfig:: { keys: vec![authority_id.clone()], } - .assimilate_storage::(&mut t) + .assimilate_storage(&mut t) .unwrap(); // Create externalities. diff --git a/srml/im-online/src/lib.rs b/srml/im-online/src/lib.rs index 760ab79eb9..06a350655b 100644 --- a/srml/im-online/src/lib.rs +++ b/srml/im-online/src/lib.rs @@ -67,7 +67,7 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -use app_crypto::RuntimeAppPublic; +use app_crypto::{AppPublic, RuntimeAppPublic}; use codec::{Encode, Decode}; use primitives::offchain::{OpaqueNetworkState, StorageKind}; use rstd::prelude::*; @@ -75,7 +75,7 @@ use session::historical::IdentificationTuple; use sr_io::Printable; use sr_primitives::{ Perbill, ApplyError, - traits::{Extrinsic as ExtrinsicT, Convert}, + traits::{Convert, Extrinsic as ExtrinsicT, Member}, transaction_validity::{TransactionValidity, TransactionLongevity, ValidTransaction}, }; use sr_staking_primitives::{ @@ -83,28 +83,44 @@ use sr_staking_primitives::{ offence::{ReportOffence, Offence, Kind}, }; use srml_support::{ - StorageValue, decl_module, decl_event, decl_storage, StorageDoubleMap, print, ensure + decl_module, decl_event, decl_storage, print, ensure, + Parameter, StorageValue, StorageDoubleMap, }; use system::ensure_none; -mod app { - pub use app_crypto::sr25519 as crypto; - use app_crypto::{app_crypto, key_types::IM_ONLINE, sr25519}; +pub mod sr25519 { + mod app_sr25519 { + use app_crypto::{app_crypto, key_types::IM_ONLINE, sr25519}; + app_crypto!(sr25519, IM_ONLINE); + } + + /// An i'm online keypair using sr25519 as its crypto. + #[cfg(feature = "std")] + pub type AuthorityPair = app_sr25519::Pair; - app_crypto!(sr25519, IM_ONLINE); + /// An i'm online signature using sr25519 as its crypto. + pub type AuthoritySignature = app_sr25519::Signature; + + /// An i'm online identifier using sr25519 as its crypto. + pub type AuthorityId = app_sr25519::Public; } -/// A Babe authority keypair. Necessarily equivalent to the schnorrkel public key used in -/// the main Babe module. If that ever changes, then this must, too. -#[cfg(feature = "std")] -pub type AuthorityPair = app::Pair; +pub mod ed25519 { + mod app_ed25519 { + use app_crypto::{app_crypto, key_types::IM_ONLINE, ed25519}; + app_crypto!(ed25519, IM_ONLINE); + } + + /// An i'm online keypair using ed25519 as its crypto. + #[cfg(feature = "std")] + pub type AuthorityPair = app_ed25519::Pair; -/// A Babe authority signature. -pub type AuthoritySignature = app::Signature; + /// An i'm online signature using ed25519 as its crypto. + pub type AuthoritySignature = app_ed25519::Signature; -/// A Babe authority identifier. Necessarily equivalent to the schnorrkel public key used in -/// the main Babe module. If that ever changes, then this must, too. -pub type AuthorityId = app::Public; + /// An i'm online identifier using ed25519 as its crypto. + pub type AuthorityId = app_ed25519::Public; +} // The local storage database key under which the worker progress status // is tracked. @@ -158,10 +174,13 @@ pub struct Heartbeat } pub trait Trait: system::Trait + session::historical::Trait { + /// The identifier type for an authority. + type AuthorityId: Member + Parameter + AppPublic + RuntimeAppPublic + Default; + /// The overarching event type. - type Event: From + Into<::Event>; + type Event: From> + Into<::Event>; - /// The function call. + /// A dispatchable call type. type Call: From>; /// A extrinsic right from the external world. This is unchecked and so @@ -181,7 +200,9 @@ pub trait Trait: system::Trait + session::historical::Trait { } decl_event!( - pub enum Event { + pub enum Event where + ::AuthorityId, + { /// A new heartbeat was received from `AuthorityId` HeartbeatReceived(AuthorityId), } @@ -193,7 +214,7 @@ decl_storage! { GossipAt get(gossip_at): T::BlockNumber; /// The current set of keys that may issue a heartbeat. - Keys get(keys): Vec; + Keys get(keys): Vec; /// For each session index we keep a mapping of `AuthorityId` /// to `offchain::OpaqueNetworkState`. @@ -201,10 +222,10 @@ decl_storage! { blake2_256(AuthIndex) => Vec; } add_extra_genesis { - config(keys): Vec; + config(keys): Vec; build(| storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &GenesisConfig + config: &GenesisConfig | { sr_io::with_storage( storage, @@ -217,12 +238,12 @@ decl_storage! { decl_module! { pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; fn heartbeat( origin, heartbeat: Heartbeat, - signature: AuthoritySignature + signature: ::Signature ) { ensure_none(origin)?; @@ -232,7 +253,7 @@ decl_module! { ¤t_session, &heartbeat.authority_index ); - let keys = Keys::get(); + let keys = Keys::::get(); let public = keys.get(heartbeat.authority_index as usize); if let (true, Some(public)) = (!exists, public) { let signature_valid = heartbeat.using_encoded(|encoded_heartbeat| { @@ -240,7 +261,7 @@ decl_module! { }); ensure!(signature_valid, "Invalid heartbeat signature."); - Self::deposit_event(Event::HeartbeatReceived(public.clone())); + Self::deposit_event(Event::::HeartbeatReceived(public.clone())); let network_state = heartbeat.network_state.encode(); ::insert( @@ -297,8 +318,8 @@ impl Module { fn do_gossip_at(block_number: T::BlockNumber) -> Result<(), OffchainErr> { // we run only when a local authority key is configured - let authorities = Keys::get(); - let mut local_keys = app::Public::all(); + let authorities = Keys::::get(); + let mut local_keys = T::AuthorityId::all(); local_keys.sort(); for (authority_index, key) in authorities.into_iter() @@ -389,27 +410,27 @@ impl Module { } } - fn initialize_keys(keys: &[AuthorityId]) { + fn initialize_keys(keys: &[T::AuthorityId]) { if !keys.is_empty() { - assert!(Keys::get().is_empty(), "Keys are already initialized!"); - Keys::put_ref(keys); + assert!(Keys::::get().is_empty(), "Keys are already initialized!"); + Keys::::put_ref(keys); } } } impl session::OneSessionHandler for Module { - type Key = AuthorityId; + type Key = T::AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) - where I: Iterator + where I: Iterator { let keys = validators.map(|x| x.1).collect::>(); Self::initialize_keys(&keys); } fn on_new_session<'a, I: 'a>(_changed: bool, validators: I, _queued_validators: I) - where I: Iterator + where I: Iterator { // Reset heartbeats ::remove_prefix(&>::current_index()); @@ -418,7 +439,7 @@ impl session::OneSessionHandler for Module { >::put(>::block_number()); // Remember who the authorities are for the new session. - Keys::put(validators.map(|x| x.1).collect::>()); + Keys::::put(validators.map(|x| x.1).collect::>()); } fn on_before_session_ending() { @@ -426,7 +447,7 @@ impl session::OneSessionHandler for Module { let current_session = >::current_index(); - let keys = Keys::get(); + let keys = Keys::::get(); let current_elected = T::CurrentElectedSet::current_elected_set(); // The invariant is that these two are of the same length. @@ -481,7 +502,7 @@ impl srml_support::unsigned::ValidateUnsigned for Module { } // verify that the incoming (unverified) pubkey is actually an authority id - let keys = Keys::get(); + let keys = Keys::::get(); let authority_id = match keys.get(heartbeat.authority_index as usize) { Some(id) => id, None => return TransactionValidity::Invalid(ApplyError::BadSignature as i8), -- GitLab From b05b3c9629e8efad424e2f68e6e4f7bddfe9af9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Wed, 28 Aug 2019 14:37:23 +0100 Subject: [PATCH 027/275] grandpa: only send catch-up requests to authorities (#3499) * grandpa: only send catch-up requests to authorities * grandpa: fix gossip tests * grandpa: test sending catch-up requests only to authorities * grandpa: fix catch-up test * grandpa: apply suggestions from code review --- .../src/communication/gossip.rs | 83 +++++++++++++++---- .../src/communication/tests.rs | 4 +- 2 files changed, 71 insertions(+), 16 deletions(-) diff --git a/core/finality-grandpa/src/communication/gossip.rs b/core/finality-grandpa/src/communication/gossip.rs index e0db1f0ba2..831be7ad14 100644 --- a/core/finality-grandpa/src/communication/gossip.rs +++ b/core/finality-grandpa/src/communication/gossip.rs @@ -386,12 +386,14 @@ impl Misbehavior { struct PeerInfo { view: View, + roles: Roles, } impl PeerInfo { - fn new() -> Self { + fn new(roles: Roles) -> Self { PeerInfo { view: View::default(), + roles, } } } @@ -408,8 +410,8 @@ impl Default for Peers { } impl Peers { - fn new_peer(&mut self, who: PeerId) { - self.inner.insert(who, PeerInfo::new()); + fn new_peer(&mut self, who: PeerId, roles: Roles) { + self.inner.insert(who, PeerInfo::new(roles)); } fn peer_disconnected(&mut self, who: &PeerId) { @@ -815,9 +817,12 @@ impl Inner { // if the peer is on the same set and ahead of us by a margin bigger // than `CATCH_UP_THRESHOLD` then we should ask it for a catch up - // message. + // message. we only send catch-up requests to authorities, observers + // won't be able to reply since they don't follow the full GRANDPA + // protocol and therefore might not have the vote data available. if let (Some(peer), Some(local_view)) = (self.peers.peer(who), &self.local_view) { - if peer.view.set_id == local_view.set_id && + if peer.roles.is_authority() && + peer.view.set_id == local_view.set_id && peer.view.round.0.saturating_sub(CATCH_UP_THRESHOLD) > local_view.round.0 { // send catch up request if allowed @@ -1033,10 +1038,10 @@ impl GossipValidator { } impl network_gossip::Validator for GossipValidator { - fn new_peer(&self, context: &mut dyn ValidatorContext, who: &PeerId, _roles: Roles) { + fn new_peer(&self, context: &mut dyn ValidatorContext, who: &PeerId, roles: Roles) { let packet = { let mut inner = self.inner.write(); - inner.peers.new_peer(who.clone()); + inner.peers.new_peer(who.clone(), roles); inner.local_view.as_ref().map(|v| { NeighborPacket { @@ -1324,7 +1329,7 @@ mod tests { assert!(res.unwrap().is_none()); // connect & disconnect. - peers.new_peer(id.clone()); + peers.new_peer(id.clone(), Roles::AUTHORITY); peers.peer_disconnected(&id); let res = peers.update_peer_state(&id, update.clone()); @@ -1360,7 +1365,7 @@ mod tests { let mut peers = Peers::default(); let id = PeerId::random(); - peers.new_peer(id.clone()); + peers.new_peer(id.clone(), Roles::AUTHORITY); let mut check_update = move |update: NeighborPacket<_>| { let view = peers.update_peer_state(&id, update.clone()).unwrap().unwrap(); @@ -1380,7 +1385,7 @@ mod tests { let mut peers = Peers::default(); let id = PeerId::random(); - peers.new_peer(id.clone()); + peers.new_peer(id.clone(), Roles::AUTHORITY); peers.update_peer_state(&id, NeighborPacket { round: Round(10), @@ -1581,7 +1586,7 @@ mod tests { // add the peer making the request to the validator, // otherwise it is discarded let mut inner = val.inner.write(); - inner.peers.new_peer(peer.clone()); + inner.peers.new_peer(peer.clone(), Roles::AUTHORITY); let res = inner.handle_catch_up_request( &peer, @@ -1632,7 +1637,7 @@ mod tests { // add the peer making the request to the validator, // otherwise it is discarded let peer = PeerId::random(); - val.inner.write().peers.new_peer(peer.clone()); + val.inner.write().peers.new_peer(peer.clone(), Roles::AUTHORITY); let send_request = |set_id, round| { let mut inner = val.inner.write(); @@ -1712,7 +1717,7 @@ mod tests { // add the peer making the request to the validator, // otherwise it is discarded. let peer = PeerId::random(); - val.inner.write().peers.new_peer(peer.clone()); + val.inner.write().peers.new_peer(peer.clone(), Roles::AUTHORITY); let import_neighbor_message = |set_id, round| { let (_, _, catch_up_request, _) = val.inner.write().import_neighbor_message( @@ -1775,7 +1780,7 @@ mod tests { // add the peer making the request to the validator, // otherwise it is discarded. let peer = PeerId::random(); - val.inner.write().peers.new_peer(peer.clone()); + val.inner.write().peers.new_peer(peer.clone(), Roles::AUTHORITY); // importing a neighbor message from a peer in the same set in a later // round should lead to a catch up request but since they're disabled @@ -1794,4 +1799,54 @@ mod tests { _ => panic!("expected no catch up message"), } } + + #[test] + fn doesnt_send_catch_up_requests_to_non_authorities() { + let (val, _) = GossipValidator::::new( + config(), + voter_set_state(), + true, + ); + + // the validator starts at set id 1. + val.note_set(SetId(1), Vec::new(), |_, _| {}); + + // add the peers making the requests to the validator, + // otherwise it is discarded. + let peer_authority = PeerId::random(); + let peer_full = PeerId::random(); + + val.inner.write().peers.new_peer(peer_authority.clone(), Roles::AUTHORITY); + val.inner.write().peers.new_peer(peer_full.clone(), Roles::FULL); + + let import_neighbor_message = |peer| { + let (_, _, catch_up_request, _) = val.inner.write().import_neighbor_message( + &peer, + NeighborPacket { + round: Round(42), + set_id: SetId(1), + commit_finalized_height: 50, + }, + ); + + catch_up_request + }; + + // importing a neighbor message from a peer in the same set in a later + // round should lead to a catch up request but since the node is not an + // authority we should get `None`. + if import_neighbor_message(peer_full).is_some() { + panic!("expected no catch up message"); + } + + // importing the same neighbor message from a peer who is an authority + // should lead to a catch up request. + match import_neighbor_message(peer_authority) { + Some(GossipMessage::CatchUpRequest(request)) => { + assert_eq!(request.set_id, SetId(1)); + assert_eq!(request.round, Round(41)); + }, + _ => panic!("expected catch up message"), + } + } } diff --git a/core/finality-grandpa/src/communication/tests.rs b/core/finality-grandpa/src/communication/tests.rs index 3ec3bc8dd4..b537c29dca 100644 --- a/core/finality-grandpa/src/communication/tests.rs +++ b/core/finality-grandpa/src/communication/tests.rs @@ -448,8 +448,8 @@ fn peer_with_higher_view_leads_to_catch_up_request() { let (tester, mut net) = make_test_network(); let test = tester .and_then(move |tester| { - // register a peer. - tester.gossip_validator.new_peer(&mut NoopContext, &id, network::config::Roles::FULL); + // register a peer with authority role. + tester.gossip_validator.new_peer(&mut NoopContext, &id, network::config::Roles::AUTHORITY); Ok((tester, id)) }) .and_then(move |(tester, id)| { -- GitLab From f1b181dce26d5f21b60431d6e65d6b1758d91c7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Wed, 28 Aug 2019 17:10:19 +0100 Subject: [PATCH 028/275] node: spawn babe epoch pruning in light client (#3505) * node: use plain vec for tasks_to_spawn * node: spawn background tasks in light client setup --- node/cli/src/service.rs | 43 +++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index c47e764c42..40f287445f 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -46,7 +46,7 @@ macro_rules! new_full_start { ($config:expr) => {{ let mut import_setup = None; let inherent_data_providers = inherents::InherentDataProviders::new(); - let mut tasks_to_spawn = None; + let mut tasks_to_spawn = Vec::new(); let builder = substrate_service::ServiceBuilder::new_full::< node_primitives::Block, node_runtime::RuntimeApi, node_executor::Executor @@ -79,7 +79,7 @@ macro_rules! new_full_start { )?; import_setup = Some((babe_block_import.clone(), link_half, babe_link)); - tasks_to_spawn = Some(vec![Box::new(pruning_task)]); + tasks_to_spawn.push(Box::new(pruning_task)); Ok(import_queue) })? @@ -92,7 +92,7 @@ macro_rules! new_full_start { ); io })?; - + (builder, import_setup, inherent_data_providers, tasks_to_spawn) }} } @@ -117,14 +117,12 @@ macro_rules! new_full { .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); // spawn any futures that were created in the previous setup steps - if let Some(tasks) = tasks_to_spawn.take() { - for task in tasks { - service.spawn_task( - task.select(service.on_exit()) - .map(|_| ()) - .map_err(|_| ()) - ); - } + for task in tasks_to_spawn.drain(..) { + service.spawn_task( + task.select(service.on_exit()) + .map(|_| ()) + .map_err(|_| ()) + ); } if service.config().roles.is_authority() { @@ -207,9 +205,12 @@ pub fn new_full(config: Configuration(config: Configuration) -> Result { + use futures::Future; + let inherent_data_providers = InherentDataProviders::new(); + let mut tasks_to_spawn = Vec::new(); - ServiceBuilder::new_light::(config)? + let service = ServiceBuilder::new_light::(config)? .with_select_chain(|_config, client| { #[allow(deprecated)] Ok(LongestChain::new(client.backend().clone())) @@ -231,8 +232,7 @@ pub fn new_light(config: Configuration(config: Configuration(config: Configuration Date: Wed, 28 Aug 2019 18:03:54 +0100 Subject: [PATCH 029/275] node: update flaming fir (#3508) * node: reduce block time to 3s and add primary probability constant * node: update flaming fir chain spec * node: fix integration test --- node/cli/res/flaming-fir.json | 138 +++++++++++++++++----------------- node/cli/src/service.rs | 4 +- node/runtime/src/constants.rs | 12 ++- node/runtime/src/lib.rs | 2 +- 4 files changed, 82 insertions(+), 74 deletions(-) diff --git a/node/cli/res/flaming-fir.json b/node/cli/res/flaming-fir.json index e135901ac1..2d4486f018 100644 --- a/node/cli/res/flaming-fir.json +++ b/node/cli/res/flaming-fir.json @@ -23,86 +23,86 @@ "genesis": { "raw": [ { + "0xb2029f8665aac509629f2d28cea790a3": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26633919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f437800299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d655633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde787932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d129becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993326e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106", + "0x9c16fd03b96712dc0751bb0d63bc05aa": "0x00e1f505", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b657973be035f25cd43adc80f1dcf505f5ffd158d1592ab3719f354a256a4c3b7571934": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", + "0x4e62513de81454ce76df887573f7f98b101eb4585b1485a222b7db599f4e93e2": "0x047374616b696e67200000c16ff28623000000000000000000ffffffff0e", "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797346c8960f8387b17441ee2be48a0896e48d3580e922c6e1cd8f53a621370c1e49": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", - "0x579ab55d37b1220812be3c3df29d4858": "0x00000000", - "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b657973711590f60a214f6f06502eb29dd14f55aa04e72e2fa12c098ba4fa5a00c57fa9": "0x7932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b657973dc4036f96ca26a30da6d8637ca1431896c1069bf172c419e98dc08109e7b23b5": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b6579730a299be621974fd19374a88f1dddd8442b21db25d2c923907dda6af815b657fe": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", - "0x3a636f6465": "0x0061736d010000000194022460027f7f0060017f0060027f7f017f60037f7f7f0060037f7f7f017f60057f7f7f7f7f0060047f7f7f7f0060017f017e60057f7f7f7f7f017f60067f7f7f7f7f7f0060047f7f7f7f017f6000017f60077f7f7f7f7f7f7f017f60017f017f60067f7f7f7f7f7f017f60087f7f7f7f7f7f7f7f017f60000060077f7f7e7e7f7f7f0060087f7f7f7f7f7e7e7f0060057f7f7f7e7e0060047f7f7e7e0060077f7f7f7e7e7f7f0060037f7e7e0060057f7f7e7e7f0060077f7e7e7f7f7f7f0060067f7f7e7e7f7f0060077f7e7e7e7e7e7e0060047f7e7e7e0060037e7f7f017f60027f7f017e60047f7f7f7f017e60067f7f7f7e7e7f0060037f7e7f0060047f7e7e7f0060057f7e7e7e7e0060067f7e7e7e7e7f00029b082703656e760e6578745f626c616b65325f323536000303656e761f6578745f6765745f616c6c6f63617465645f6368696c645f73746f72616765000803656e76176578745f636c6561725f6368696c645f73746f72616765000603656e760c6578745f74776f785f313238000303656e760f6578745f7365745f73746f72616765000603656e76146578745f6765745f73746f726167655f696e746f000803656e76116578745f636c6561725f73746f72616765000003656e76166578745f6b696c6c5f6368696c645f73746f72616765000003656e76196578745f6765745f616c6c6f63617465645f73746f72616765000403656e760e6578745f7072696e745f75746638000003656e76166578745f6368696c645f73746f726167655f726f6f74000403656e76156578745f7365745f6368696c645f73746f72616765000903656e76126578745f737232353531395f766572696679000a03656e760d6578745f7072696e745f686578000003656e76106578745f69735f76616c696461746f72000b03656e76156578745f6c6f63616c5f73746f726167655f676574000a03656e76216578745f6c6f63616c5f73746f726167655f636f6d706172655f616e645f736574000c03656e76176578745f737232353531395f7075626c69635f6b657973000203656e76116578745f6e6574776f726b5f7374617465000d03656e76106578745f737232353531395f7369676e000803656e76166578745f7375626d69745f7472616e73616374696f6e000203656e76156578745f6c6f63616c5f73746f726167655f736574000503656e76146578745f656432353531395f67656e6572617465000603656e76146578745f737232353531395f67656e6572617465000603656e76106578745f636c6561725f707265666978000003656e76166578745f73616e64626f785f6d656d6f72795f6e6577000203656e761b6578745f73616e64626f785f6d656d6f72795f74656172646f776e000103656e76176578745f73616e64626f785f696e7374616e7469617465000e03656e76126578745f73616e64626f785f696e766f6b65000f03656e761d6578745f73616e64626f785f696e7374616e63655f74656172646f776e000103656e76236578745f626c616b65325f3235365f656e756d6572617465645f747269655f726f6f74000603656e76106578745f73746f726167655f726f6f74000103656e76186578745f73746f726167655f6368616e6765735f726f6f74000403656e76126578745f656432353531395f766572696679000a03656e76166578745f73616e64626f785f6d656d6f72795f676574000a03656e76166578745f73616e64626f785f6d656d6f72795f736574000a03656e760b6578745f74776f785f3634000303656e760a6578745f6d616c6c6f63000d03656e76086578745f66726565000103da04d80400000d040100100101000010000d000000030001000000000000000003000000000000000303110202120309060100131401011506000000050000020600000000020200000214031403010316000100000000170000030010000300030018000101010100160114030019141416010000010003000203020101000100001a1b01010100000000000003000204021c0e0000000000000a030300010100000003010000000001010000010000000000000000030205030000060000000000030003050302030000010000030503030600060000000001000003000000000000010101010101010101010101010100030001000300030106060303030310030101001d1d000100000610011d1d0300001d1d001d001d1d031d03031d1d1d1d1d1d000000001d1d030101010001010001000300100001000003010100100606060606060606060606060606060606060606060606061e0000000d0d00000005010000010104000100000000000101010001010100001000000000010100030001010100000100000000000000000010100600000002000d030001030303010100000100000000000000000000000000000000001a1f010100000101000000000000010000140000010300050001010000000001000000000000000a0003030503200000020000030305000300020400030000020006020302020001000306060303020505030303030602040101020204020202080302030203030000020302020202010202020200010202020100010d01040d040202070a0602020d02020202020601010402020402020202020202040404042121222222230407017001de01de0105030100120619037f01418080c0000b7f0041f099c6000b7f0041f099c6000b07dd0416066d656d6f72790200195f5f696e6469726563745f66756e6374696f6e5f7461626c6501000a5f5f646174615f656e6403010b5f5f686561705f6261736503020c436f72655f76657273696f6e00a80212436f72655f657865637574655f626c6f636b00a90215436f72655f696e697469616c697a655f626c6f636b00b102114d657461646174615f6d6574616461746100b2021c426c6f636b4275696c6465725f6170706c795f65787472696e73696300b6021b426c6f636b4275696c6465725f66696e616c697a655f626c6f636b00b70220426c6f636b4275696c6465725f696e686572656e745f65787472696e7369637300b9021c426c6f636b4275696c6465725f636865636b5f696e686572656e747300bb0218426c6f636b4275696c6465725f72616e646f6d5f7365656400bc022b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6e00be02214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b657200c102214772616e6470614170695f6772616e6470615f70656e64696e675f6368616e676500c202204772616e6470614170695f6772616e6470615f666f726365645f6368616e676500c3021e4772616e6470614170695f6772616e6470615f617574686f72697469657300c40214426162654170695f737461727475705f6461746100c5020d426162654170695f65706f636800c60218436f6e73656e7375734170695f617574686f72697469657300cb022153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b65797300cc0209bb03010041010bdd019804e302e402e502e602e702e802e902ea02eb02ec02ed02ee02ef02f002f102f202f302f402f502f602f702f802f902fa02fb02e604da0168696c9e0189049b049d049e049204c204a704af04b404e304bb04bd04d004d104cf04df04e004d002e801e901eb01ea01e701ec0159f201f301f4014ef10155d4028b01f703d601cc03cd03e203a101a203ce01a401a301ad01ac01aa01db02b201b104b401c401c301cf01f403d701d501d401d301d201d101d103e404e504a703a6038602aa03a0019f01a201930392039403e002df028c0387028a01890188028d01e003df038902e703d302d2028a02d502f303f2038b02f803970396038c029803cd01cc018d02d001890388038e02c101c201cf02ce028f02a801a7019002a901c403c3039102c703a103a0039202a502a6029302a702f204d102d602dd02dc02de02f4049503a903a803c603c503d303d203d003cf03ce03cb03ca03c903c803e603e503e403e303e103e803ed03d803eb03ee03f603f503fc03fb03fa03f903b204b604c604b304c404b804c504c704cb04c904ca04cc04cd04ce04d904da04db04dc04e904ea04eb04ec04ed04ee04ef04f104f004f3040afec83ad8049a1002187f017e230041f0006b2202240002400240024020012802042203200128020022046b41e100490d0003402001200441206a3602002001280208220341186a280200210520032802102106200241d0006a41186a22034200370300200241d0006a41106a22074200370300200241d0006a41086a220842003703002002420037035020044120200241d0006a1000200241106a41186a22092003290300370300200241106a41106a220a2007290300370300200241106a41086a220b2008290300370300200220022903503703102002410036025020062005200241106a4120200241d0006a100121060240024020022802502205417f470d002002200c36020c2002200d3602082002200e3602040c010b2001280208220f2802182110200f280210210f2003420037030020074200370300200842003703002002420037035020044120200241d0006a1000200241306a41186a2003290300370300200241306a41106a2007290300370300200241306a41086a200829030037030020022002290350370330200f2010200241306a412010022002200536020c20022005360208200220063602042006210e2005210d2005210c2004450d00200241046a21010c030b20012001280200220441206a3602002001280208220541186a2802002106200528021021052003420037030020074200370300200842003703002002420037035020044120200241d0006a100020092003290300370300200a2007290300370300200b2008290300370300200220022903503703102002410036025020052006200241106a4120200241d0006a100121060240024020022802502205417f470d002002201136020c20022012360208200220133602040c010b2001280208220f2802182110200f280210210f2003420037030020074200370300200842003703002002420037035020044120200241d0006a1000200241306a41186a2003290300370300200241306a41106a2007290300370300200241306a41086a200829030037030020022002290350370330200f2010200241306a412010022002200536020c20022005360208200220063602042006211320052112200521112004450d00200241046a21010c030b20012001280200220441206a3602002001280208220541186a2802002106200528021021052003420037030020074200370300200842003703002002420037035020044120200241d0006a100020092003290300370300200a2007290300370300200b2008290300370300200220022903503703102002410036025020052006200241106a4120200241d0006a100121060240024020022802502205417f470d002002201436020c20022015360208200220163602040c010b2001280208220f2802182110200f280210210f2003420037030020074200370300200842003703002002420037035020044120200241d0006a1000200241306a41186a2003290300370300200241306a41106a2007290300370300200241306a41086a200829030037030020022002290350370330200f2010200241306a412010022002200536020c20022005360208200220063602042006211620052115200521142004450d00200241046a21010c030b20012001280200220441206a3602002001280208220541186a2802002106200528021021052003420037030020074200370300200842003703002002420037035020044120200241d0006a100020092003290300370300200a2007290300370300200b2008290300370300200220022903503703102002410036025020052006200241106a4120200241d0006a1001210a0240024020022802502209417f470d002002201736020c20022018360208200220193602040c010b2001280208220b2802182105200b280210210b2003420037030020074200370300200842003703002002420037035020044120200241d0006a1000200241306a41186a2003290300370300200241306a41106a2007290300370300200241306a41086a200829030037030020022002290350370330200b2005200241306a412010022002200936020c200220093602082002200a360204200a211920092118200921172004450d00200241046a21010c030b20012802042203200128020022046b41e0004b0d000b0b024020042003460d0003402001200441206a3602002001280208220341186a280200210a20032802102103200241d0006a41186a22074200370300200241d0006a41106a22084200370300200241d0006a41086a220942003703002002420037035020044120200241d0006a1000200241106a41186a2007290300370300200241106a41106a2008290300370300200241106a41086a200929030037030020022002290350370310200241003602502003200a200241106a4120200241d0006a1001210a0240024020022802502203417f470d002002200b36020c20022005360208200220063602040c010b2001280208220b2802182105200b280210210b2007420037030020084200370300200942003703002002420037035020044120200241d0006a1000200241306a41186a2007290300370300200241306a41106a2008290300370300200241306a41086a200929030037030020022002290350370330200b2005200241306a412010022002200336020c200220033602082002200a360204200a2106200321052003210b2004450d00200241046a21010c030b200128020022042001280204470d000b0b200041003602000c010b200241d0006a41086a200141086a280200220336020020022001290200221a370350200020043602002000201a3702042000410c6a20033602000b200241f0006a24000b830202077f017e0240024002400240200041046a2802002202200041086a28020022036b2001410c6a2802002204200141086a28020022056b220641b0016d2207490d00200028020021020c010b200320076a22082003490d0220024101742203200820082003491b2203ad42b0017e2209422088a70d022009a722084100480d020240024020020d002008102921020c010b2000280200200241b0016c2008102a21020b2002450d0120002002360200200041046a2003360200200041086a28020021030b2002200341b0016c6a2005200610f6041a200141086a2004360200200041086a2200200028020020076a3602002001102b0f0b20084108102c000b102d000b0700200010d5040b0b0020002001200210d7040b950201057f230041e0026b22012400024020002802082202200028020c460d00200141b0016a4101722103200141d8016a210403402000200241b0016a36020820022d00002105200141b0016a200241016a41af0110f6041a20054103460d01200141016a200141b0016a41af0110f6041a200120053a00b0012003200141016a41af0110f6041a02400240200541014b0d000240024020050e020001000b024020012802b801450d0020012802b401102e0b20012d00c0014105490d0220012802e801450d0220012802e401102e0c020b2004102f0c010b200128029802450d00200128029402102e0b20002802082202200028020c470d000b0b02402000280204450d002000280200102e0b200141e0026a24000b0e0041f8e6c500412210d30400000b0a0041bce8c5001058000b0700200010d6040b9a0b01057f0240024020002d0000220141114b0d0002400240024002400240024002400240024002400240024020010e12000d0d010d0d020304050607080d090d0a0b000b0240200041086a280200220141054b0d0002400240024020010e06101000100102100b200041106a280200450d0f2000410c6a280200102e0f0b200041106a280200450d0e2000410c6a280200102e0f0b0240200041146a2802002202450d002000410c6a2802002101200241186c210203400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141186a2101200241686a22020d000b0b200041106a280200450d0d200028020c102e0f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c210203400240200141046a280200450d002001280200102e0b2001410c6a2101200241746a22020d000b0b200041106a280200450d0c200028020c102e0f0b02402000410c6a2802002201450d00200041046a2802002203200141f0006c6a2104034002402003410c6a2802002202450d0020032802042101200241246c210203400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012002415c6a22020d000b0b200341f0006a21010240200341086a280200450d002003280204102e0b2001210320012004470d000b0b200041086a280200450d0b2000280204102e0f0b0240200041086a2d00002201410d4b0d0020014106470d0b200041106a280200450d0b2000410c6a280200102e0f0b200041106a280200450d0a2000410c6a280200102e0f0b200041086a280200450d09200041046a280200102e0f0b200041086a2d0000417f6a220141074b0d08024002400240024020010e08000c0c0c0c010203000b2000410c6a2201280200102f2001280200102e0f0b2000410c6a2201280200102f2001280200102e0f0b2000410c6a2201280200102f2001280200102e0f0b2000410c6a2201280200102f2001280200102e0f0b200041046a2d0000417f6a220141024b0d0702400240024020010e03000102000b2000410c6a280200450d09200041086a280200102e0f0b200041086a2201280200102f2001280200102e0f0b2000410c6a2201280200102f2001280200102e0f0b200041046a2d0000417f6a220141024b0d0602400240024020010e03000102000b2000410c6a280200450d08200041086a280200102e0f0b200041086a2201280200102f2001280200102e0f0b2000410c6a2201280200102f2001280200102e0f0b200041086a280200417f6a220141014b0d050240024020010e020001000b200041106a280200450d062000410c6a280200102e0f0b200041106a280200450d052000410c6a280200102e0f0b200041046a2d00004104490d042000410c6a280200450d04200041086a280200102e0f0b200041086a280200450d03200041046a280200102e0f0b200041086a2d0000417e6a220141024b0d0202400240024020010e03000102000b200041106a280200450d042000410c6a280200102e0c040b200041346a280200450d03200041306a280200102e0f0b200041306a280200450d022000412c6a280200102e0f0b200041046a2802004101470d01200041086a2201280200102f2001280200102e0f0b02402000410c6a280200450d00200041086a280200102e0b02402000411c6a2802002202450d00200041146a28020021012002410c6c210203400240200141046a280200450d002001280200102e0b2001410c6a2101200241746a22020d000b0b200041186a280200450d002000280214102e0f0b0baf04010a7f230041d0006b220224002002200110310240024002400240024020022802000d00200128020422034160712204417f4c0d022002280204210502400240200341057622060d00410121070c010b200410292207450d040b02402005450d00410021080340200241003a00482008220941016a21082001280204417f6a21034100210402400240024003402003417f460d01200241286a20046a2001280200220a2d00003a0000200120033602042001200a41016a3602002002200441016a220a3a00482003417f6a2103200a2104200a4120470d000b200241086a41186a2204200241286a41186a290300370300200241086a41106a220a200241286a41106a290300370300200241086a41086a220b200241286a41086a2903003703002002200229032837030820062009470d02024020094101742203200820082003491b220641ffffff3f712006470d002006410574220341004e0d020b102d000b0240200441ff0171450d00200241003a00480b200041003602002006450d052007102e0c050b0240024020090d002003102921070c010b200720094105742003102a21070b2007450d070b200720094105746a22032002290308370000200341186a2004290300370000200341106a200a290300370000200341086a200b29030037000020082005470d000b0b2000200636020420002007360200200041086a20053602000c010b200041003602000b200241d0006a24000f0b1032000b20044101102c000b20034101102c000bcf0201067f0240024020012802042202450d00200128020022032d0000210420012002417f6a2205360204410121062001200341016a3602000240200441037122074103460d0002400240024020070e03000102000b20044102762107410021060c040b41012106024020050d000c040b20032d0001210520012002417e6a3602042001200341026a3602002005410874200472220141ffff0371418002490d03200141fcff03714102762107410021060c030b20054103490d01200341036a2d0000210620032f0001210720012002417c6a3602042001200341046a3602002007200641107472410874200472220141027621072001418080044921060c020b0240200441034d0d000c020b20054104490d012003280001210720012002417b6a3602042001200341056a36020020074180808080044921060c010b410121060b20002007360204200020063602000b0500102d000b960301097f230041106b2202240002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002006450d0020042d0001210720012003417e6a22063602042001200441026a3602002006450d0020042d0002210820012003417d6a22063602042001200441036a3602002006450d0020042d0003210620012003417c6a3602042001200441046a360200200241086a2001103120022802080d022001280204200228020c2204490d022004417f4c0d0302400240024020040d004101210341010d010c050b200410342203450d0120012802042004490d0320032001280200200410f60421092001280204220a2004490d062001200a20046b3602042001200128020020046a3602002009450d040b20002004360208200020033602042000410c6a2004360200200020074108742005722008411074722006411874723602000c060b20044101102c000b200041003602040c040b2003102e0b200041003602040c020b1032000b2004200a1035000b200241106a24000b0700200010d8040b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420237020c200241b4efc500360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41c4efc500106a000b970201057f0240024002400240200041086a28020022022001490d0020012002200220014b1b21030c010b02400240200041046a280200220320026b200120026b2204490d0020002802002105200221030c010b200220046a22052002490d0320034101742206200520052006491b22064100480d030240024020030d002006102921050c010b200028020020032006102a21050b2005450d0220002005360200200041046a2006360200200041086a28020021030b200520036a21060240024020044102490d00200641002002417f73220220016a10f5041a2005200320016a20026a22036a21060c010b2004450d010b200641003a0000200341016a21030b200041086a20033602000f0b20064101102c000b102d000b9203010a7f200041086a220228020021034100210420024100360200024002402003450d004100210541002106410021044100210702400340024002402004450d00200741057421080340200720034f0d062001200028020022096b2008460d02200920086a220a2001412010f804450d020240200620076a220b20034f0d00200920056a20086a2209200a290000370000200941186a200a41186a290000370000200941106a200a41106a290000370000200941086a200a41086a290000370000200841206a2108200741016a22072003490d010c050b0b419481c000200b20031038000b200028020020074105746a21080340200720034f0d0520012008460d0120082001412010f804450d01200841206a2108200741016a22072003490d000b410021040c030b200541606a21052006417f6a2106200441016a2104200741016a22072003490d000b0b2004450d00200320074d0d00200028020020074105746a220820044105746b2008200320076b41057410f7041a0b2002200320046b3602000f0b41b880c000200720031038000b6c01017f230041306b2203240020032002360204200320013602002003411c6a41023602002003412c6a41013602002003420237020c200341b8ecc500360208200341013602242003200341206a360218200320033602282003200341046a360220200341086a2000106a000ba30a03027f017e1b7f230041f0006b22022400024020012802082203ad42f0007e2204422088a70d002004a72205417f4c0d002001280200210602400240024020050d00410421070c010b200510292207450d010b02400240024020030d00410021080c010b2006200341f0006c6a2109410021082007210a0340200241c0006a41086a220b200641186a290000370300200241c0006a41106a220c200641206a290000370300200241c0006a41186a220d200641286a290000370300200241206a41086a220e200641386a29000037030020062900102104200241206a41106a220f200641c0006a290000370300200241206a41186a2210200641c8006a290000370300200241186a2211200641e8006a290000370300200241106a2212200641e0006a290000370300200241086a2213200641d8006a290000370300200220043703402002200629003037032020022006290050370300200628020c2214ad42247e2204422088a70d042004a72201417f4c0d0420062802002115200628020421160240024020010d00410421170c010b200110292217450d030b0240024020140d00410021180c010b201441246c2119410021054100211803400240024002400240024002400240201620056a22012d00000e050001020304000b2002200141146a2900003703602002200141196a290000370065200141056a2f0000200141076a2d000041107472211a200141106a280000211b2001410c6a280000211c200141086a280000211d200141016a280000211e4100211f0c050b200141106a280200221c417f4c0d0b200141016a280000211e4101211f201c450d03200141086a28020021010240201c1029221d450d00201d2001201c10f6041a201c211b0c050b201c4101102c000b200141106a280200221c417f4c0d0a200141016a280000211e4102211f201c450d02200141086a28020021010240201c1029221d450d00201d2001201c10f6041a201c211b0c040b201c4101102c000b200141106a280200221c417f4c0d09200141016a280000211e4103211f201c450d01200141086a28020021010240201c1029221d450d00201d2001201c10f6041a201c211b0c030b201c4101102c000b2001410c6a280200221d417f4c0d08024002400240201d0d00410121010c010b200141046a280200211c201d10292201450d012001201c201d10f6041a0b2001410876211a2001411874211e4104211f201d211c0c020b201d4101102c000b4100211c4101211d4100211b0b201720056a2201201f3a0000200141076a201a4110763a0000200141056a201a3b0000200141106a201b3600002001410c6a201c360000200141086a201d360000200141016a201e360000200141146a20022903603702002001411c6a200241e0006a41086a290300370200201841016a21182019200541246a2205470d000b0b200a2017360204200a410c6a2018360200200a41086a2014360200200a2002290340370210200a41186a200b290300370200200a2015360200200a2002290320370230200a41206a200c290300370200200a41286a200d290300370200200a41386a200e290300370200200a41c0006a200f290300370200200a41c8006a2010290300370200200a41e8006a2011290300370200200a41e0006a2012290300370200200a41d8006a2013290300370200200a2002290300370250200841016a2108200a41f0006a210a200641f0006a22062009470d000b0b200020083602082000200336020420002007360200200241f0006a24000f0b20014104102c000b20054104102c000b1032000b900201077f024020002802082201200028020c460d0003402000200141306a36020820012d00284102460d01200141246a2802002102200141206a2802002103200141146a2802002104200128021c2105200128021021060240200141186a2802002201450d002001410c6c21072006210103400240200141046a280200450d002001280200102e0b2001410c6a2101200741746a22070d000b0b02402004450d002006102e0b02402002450d002002410c6c21072005210103400240200141046a280200450d002001280200102e0b2001410c6a2101200741746a22070d000b0b02402003450d002005102e0b20002802082201200028020c470d000b0b02402000280204450d002000280200102e0b0be60403087f017e017f230041f0016b22022400200241086a2001103102400240024002400240024020022802080d00200128020441f0006e220341f0006c2204417f4c0d02200228020c21050240024020040d00410421060c010b200410292206450d040b024002402005450d00410021074100210841002109034020024180016a2001103c200228028401450d02200941016a2104200241106a20024180016a41f00010f6041a024020092003470d002007200420042007491b2203ad42f0007e220a422088a70d09200aa7220b4100480d090240024020090d00200b102921060c010b20062008200b102a21060b2006450d080b200620086a200241106a41f00010f6041a200741026a2107200841f0006a21082004210920052004470d000b0b2000200336020420002006360200200041086a20053602000c020b2000410036020002402009450d00200620086a210120062107034002402007410c6a2802002209450d0020072802042104200941246c210903400240024020042d0000220841034b0d0002400240024020080e0404000102040b2004410c6a280200450d03200441086a280200102e0c030b2004410c6a280200450d02200441086a280200102e0c020b2004410c6a280200450d01200441086a280200102e0c010b200441086a280200450d00200441046a280200102e0b200441246a21042009415c6a22090d000b0b200741f0006a21040240200741086a280200450d002007280204102e0b2004210720012004470d000b0b2003450d012006102e0c010b200041003602000b200241f0016a24000f0b1032000b20044104102c000b200b4104102c000b102d000b9f0a03077f037e057f230041d0026b2202240041002103200241003a00c8022001280204417f6a210402400240024003402004417f460d01200241a8026a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00c8022004417f6a21042005210320054120470d000b200241e8006a41086a200241a8026a41086a290300370300200241e8006a41106a200241a8026a41106a290300370300200241e8006a41186a200241a8026a41186a290300370300200220022903a8023703682002200110312002280200450d01200041003602040c020b0240200341ff0171450d00200241003a00c8020b200041003602040c010b2002280204210641002104200241003a00c80220012802042107417f21030240034020072004460d01200241a8026a20046a200128020022082d00003a00002001200720036a3602042001200841016a3602002002200441016a22053a00c8022003417f6a21032005210420054120470d000b200241a8016a41086a200241a8026a41086a2903002209370300200241a8016a41106a200241a8026a41106a290300220a370300200241a8016a41186a200241a8026a41186a290300220b37030020024188016a41086a200937030020024188016a41106a200a37030020024188016a41186a200b370300200220022903a80222093703a801200220093703880141002104200241003a00c802200720056b210c200720036a210303400240200c2004470d000240200441ff0171450d00200241003a00c8020b200041003602040c030b200241a8026a20046a200820046a220541016a2d00003a0000200120033602042001200541026a3602002002200441016a22053a00c8022003417f6a21032005210420054120470d000b200241e8016a41086a200241a8026a41086a2903002209370300200241e8016a41106a200241a8026a41106a290300220a370300200241e8016a41186a200241a8026a41186a290300220b370300200241c8016a41086a22042009370300200241c8016a41106a2203200a370300200241c8016a41186a2205200b370300200220022903a80222093703e801200220093703c801200241a8026a2001103f024020022802a8022201450d00200241c8006a41086a2208200241e8006a41086a290300370300200241c8006a41106a2207200241e8006a41106a290300370300200241c8006a41186a220c200241e8006a41186a290300370300200241286a41086a220d20024188016a41086a290300370300200241286a41106a220e20024188016a41106a290300370300200241286a41186a220f20024188016a41186a29030037030020022002290368370348200220022903880137032820022902ac022109200241086a41186a22102005290300370300200241086a41106a22052003290300370300200241086a41086a22032004290300370300200220022903c801370308200020093702082000200136020420002006360200200041106a2002290348370200200041186a2008290300370200200041206a2007290300370200200041286a200c290300370200200041306a2002290328370200200041386a200d290300370200200041c0006a200e290300370200200041c8006a200f290300370200200041e8006a2010290300370200200041e0006a2005290300370200200041d8006a2003290300370200200041d0006a20022903083702000c020b200041003602040c010b0240200441ff0171450d00200241003a00c8020b200041003602040b200241d0026a24000bfb1002147f037e230041c0026b22022400200241086a200110310240024020022802080d000240200128020441c4006e220341c4006c2204417f4c0d00200228020c210502400240024020040d00410421060c010b200410292206450d010b024002402005450d0020024198026a410772210741002108034002400240024002400240024020012802042209450d002001280200220a2d0000210420012009417f6a220b3602042001200a41016a360200200441014b0d000240024020040e020001000b200b41034d0d01200a280001210c20012009417b6a3602042001200a41056a360200200241d4016a41026a200241d8016a41026a2d00003a0000200241b8016a41086a200241f8016a41086a290200370300200241b8016a41106a200241f8016a41106a290200370300200241b8016a41186a200241f8016a41186a2d00003a000020024198016a41086a20024198026a41086a29010037030020024198016a41106a20024198026a41106a29010037030020024198016a41186a20024198026a41186a290100370300200220022f00d8013b01d401200220022902f8013703b801200220022901980237039801200220022f01f4013b0196014100210d0c030b4100210e200241003a00b8022009417e6a210d03400240200b200e2204470d000240200441ff0171450d00200241003a00b8020b4102210d0c040b20024198026a20046a200a20046a220e41016a2d00003a00002001200d3602042001200e41026a3602002002200441016a220e3a00b802200d417f6a210d200e4120470d000b200241f4016a41026a220f20022d009a023a0000200241d8016a41086a2210200741086a290000370300200241d8016a41106a2211200741106a290000370300200241d8016a41186a2212200741186a2d00003a0000200220022f0198023b01f401200220072900003703d801200b200e460d01200228009b022113200a200e6a220a41016a2d0000210b2001200d3602042001200a41026a360200200b41014b0d014100211402400240200b0e020100010b4100210d200241003a00b802200e20096b41026a210b200920046b417c6a210403400240200b200d6a0d00200d41ff0171450d04200241003a00b8020c040b20024198026a200d6a200a200d6a220e41026a2d00003a0000200120043602042001200e41036a3602002002200d41016a220e3a00b8022004417f6a2104200e210d200e4120470d000b200241f8016a41186a20024198026a41186a290300370300200241f8016a41106a20024198026a41106a290300370300200241f8016a41086a20024198026a41086a29030037030020022002290398023703f801410121140b20024198016a41186a200241f8016a41186a29030037030020024198016a41106a200241f8016a41106a29030037030020024198016a41086a200241f8016a41086a290300370300200241d4016a41026a200f2d00003a0000200241b8016a41086a2010290300370300200241b8016a41106a2011290300370300200241b8016a41186a20122d00003a0000200220022903f80137039801200220022f01f4013b01d401200220022903d8013703b8014101210d201421152013210c0c020b20024192016a41026a200241d4016a41026a2d00003a0000200241f8006a41086a200241b8016a41086a290300370300200241f8006a41106a200241b8016a41106a290300370300200241f8006a41186a200241b8016a41186a2d00003a0000200241d8006a41086a20024198016a41086a290300370300200241d8006a41106a20024198016a41106a290300370300200241d8006a41186a20024198016a41186a290300370300200220022f01d4013b019201200220022903b8013703782002200229039801370358200220022f0196013b01560c020b4102210d0b20024192016a41026a2204200241d4016a41026a2d00003a0000200241f8006a41086a220a200241b8016a41086a290300370300200241f8006a41106a220b200241b8016a41106a290300370300200241f8006a41186a2209200241b8016a41186a2d00003a0000200241d8006a41086a220f20024198016a41086a290300370300200241d8006a41106a221020024198016a41106a290300370300200241d8006a41186a221120024198016a41186a290300370300200220022f01d4013b019201200220022903b8013703782002200229039801370358200220022f0196013b0156200d4102460d00200841016a210e200241d2006a41026a221220042d00003a0000200241386a41086a2213200a290300370300200241386a41106a220a200b290300370300200241386a41186a220b20092d00003a0000200241186a41086a2209200f290300370300200241186a41106a220f2010290300370300200241186a41186a22102011290300370300200220022f0192013b01522002200229037837033820022002290358370318200220022f01563b011620032008470d02024020084101742204200e200e2004491b2203ad42c4007e2216422088a70d002016a7220441004e0d020b102d000b200041003602002003450d082006102e0c080b0240024020080d002004102921060c010b2006200841c4006c2004102a21060b2006450d030b2006200841c4006c6a2204200d3a00002004200c360004200441036a20122d00003a0000200420022f01523b0001200b2d0000210d200a29030021162013290300211720022903382118200420153a002120042018370008200441106a2017370000200441186a2016370000200441206a200d3a00002004413a6a2010290300370000200441326a200f2903003700002004412a6a200929030037000020042002290318370022200420022f01163b0042200e2108200e2005470d000b0b2000200336020420002006360200200041086a20053602000c040b20044104102c000b20044104102c000b1032000b200041003602000b200241c0026a24000bb906020c7f047e230041b0016b2202240020022001103102400240024002400240024020022802000d00200128020441286e220341286c2204417f4c0d02200228020421050240024020040d00410821060c010b200410292206450d040b02402005450d00410021070340200241003a00a8012007220841016a210720012802042109417f210a4100210402400240024002400240034020092004460d0120024188016a20046a2001280200220b2d00003a000020012009200a6a3602042001200b41016a3602002002200441016a220c3a00a801200a417f6a210a200c2104200c4120470d000b200241e8006a41186a220420024188016a41186a290300370300200241e8006a41106a220a20024188016a41106a290300370300200241e8006a41086a220d20024188016a41086a29030037030020022002290388013703682009200c6b220c41074d0d01200b290001210e2001200b41096a3602002001200c41786a360204200241286a41086a200d290300220f370300200241286a41106a200a2903002210370300200241286a41186a20042903002211370300200241086a41086a220a200f370300200241086a41106a220c2010370300200241086a41186a2209201137030020022002290368220f3703282002200f37030820032008470d0420084101742204200720072004491b2203ad42287e220f422088a70d0c200fa722044100480d0c20080d022004102921060c030b200441ff0171450d00200241003a00a8010b200241286a41186a200241c8006a41186a290300370300200241286a41106a200241c8006a41106a290300370300200241286a41086a200241c8006a41086a29030037030020022002290348370328200041003602002003450d062006102e0c060b2006200841286c2004102a21060b2006450d070b2006200841286c6a22042002290308370300200a290300210f200c2903002110200929030021112004200e370320200441186a2011370300200441106a2010370300200441086a200f37030020072005470d000b0b2000200336020420002006360200200041086a20053602000c010b200041003602000b200241b0016a24000f0b1032000b20044108102c000b20044108102c000b102d000b990a02137f017e230041e0006b22022400200241086a200110310240024020022802080d000240200128020441246e220341246c2204417f4c0d00200228020c210502400240024020040d00410421060c010b200410292206450d010b02400240024020050d00410021040c010b2002412d6a2107200241cb006a220841056a21094100210a4100210b0340024002402001280204220c450d002001280200220d2d000021042001200c417f6a220e3602042001200d41016a360200200441064b0d00024002400240024002400240024020040e0700070107030402000b20022001103120022802000d0620012802042002280204220c490d06200c417f4c0d0c024002400240200c0d004101210441010d010c090b200c10342204450d012001280204200c490d0620042001280200200c10f604210f2001280204220d200c490d072001200d200c6b36020420012001280200200c6a360200200f450d080b200241206a41086a200241386a41086a290200370300200220022902383703202004410876210f4104210d200c210e201041ffffff0771200441187472221021110c080b200c4101102c000b41002104200241003a0058200c417e6a210c03400240200e2004470d00200441ff0171450d07200241003a00580c070b200241386a20046a200d20046a220f41016a2d00003a00002001200c3602042001200f41026a3602002002200441016a220f3a0058200c417f6a210c200f2104200f4120470d000b2002200829000037032020022009290000370025200228004721122002280043210e200228003f210c2002280238211120022f013c210420022d003e210f200741026a200241356a41026a2d00003a0000200720022f00353b00002004200f41107472210f4100210d0c060b200241386a20011033200228023c220c450d04200228024421122002280240210e200228023821114101210d0c050b200241386a20011033200228023c220c450d03200228024421122002280240210e200228023821114102210d0c040b200241386a20011033200228023c220c450d02200228024421122002280240210e200228023821114103210d0c030b2004102e0c010b200c200d1035000b200041003602000240200b450d002006210403400240024020042d0000220141034b0d0002400240024020010e0404000102040b2004410c6a280200450d03200441086a280200102e0c030b2004410c6a280200450d02200441086a280200102e0c020b2004410c6a280200450d01200441086a280200102e0c010b200441086a280200450d00200441046a280200102e0b200441246a2104200a415c6a220a0d000b0b2003450d072006102e0c070b200241106a41086a2213200241206a41086a290300370300200220022903203703100240200b2003470d0002400240200341016a22042003490d0020034101742214200420042014491b2204ad42247e2215422088a70d002015a7221441004e0d010b102d000b0240024020030d002014102921060c010b2006200341246c2014102a21060b2006450d03200421030b2006200b41246c6a220420123600102004200e36000c2004200c3600082004200f3b0005200420113600012004200d3a0000200441076a200f4110763a0000200420022903103700142004411c6a2013290300370000200a41246a210a200b41016a2204210b20042005470d000b0b2000200336020420002006360200200041086a20043602000c040b20144104102c000b20044104102c000b1032000b200041003602000b200241e0006a24000bc902010a7f230041106b22022400200241086a200110310240024020022802080d00024020012802042203417f4c0d00200228020c210402400240024020030d00410121050c010b200310292205450d010b02402004450d004100210641002107034002400240024020012802042208450d00200741016a21092001280200220a2d0000210b20012008417f6a3602042001200a41016a36020020072003460d010c020b200041003602002003450d072005102e0c070b02402006200920092006491b22034100480d000240024020070d002003102921050c010b200520072003102a21050b20050d0120034101102c000b102d000b200520076a200b3a0000200641026a21062009210720042009470d000b0b2000200336020420002005360200200041086a20043602000c030b20034101102c000b1032000b200041003602000b200241106a24000bf602010b7f230041106b22022400200241086a200110310240024002400240024020022802080d0020012802042203417c712204417f4c0d02200228020c210502400240200341027622060d00410421070c010b200410292207450d040b02402005450d0041002108410021094100210403400240024002402001280204220a4104490d00200441016a21032001280200220b280000210c2001200a417c6a3602042001200b41046a36020020042006470d0202402008200320032008491b220641ffffffff03712006470d002006410274220a41004e0d020b102d000b200041003602002006450d052007102e0c050b0240024020040d00200a102921070c010b20072009200a102a21070b2007450d070b200720096a200c360200200841026a2108200941046a21092003210420052003470d000b0b2000200636020420002007360200200041086a20053602000c010b200041003602000b200241106a24000f0b1032000b20044104102c000b200a4104102c000bd408040c7f017e057f037e23004180016b22022400024002400240200141086a220328020022042001410c6a2802002205460d002001280210220628020021072006280208220841014b210903402003200441206a220a360200200241e0006a41186a200441186a290000370300200241e0006a41106a200441106a290000370300200241e0006a41086a200441086a29000037030020022004290000370360410021040240024020090d0020080e020401040b2008210b0340200b410176220c20046a220d20042007200d4105746a200241e0006a412010f8044101481b2104200b200c6b220b41014b0d000b0b200720044105746a200241e0006a412010f8040d02200a2104200a2005470d000b200521040b2000410036020820004201370200024020042005460d00200141086a200520046b41606a41607120046a41206a3602000b2001280204450d012001280200102e0c010b200241c0006a41086a2204200241e0006a41086a290300370300200241c0006a41106a220b200241e0006a41106a290300370300200241c0006a41186a220c200241e0006a41186a29030037030020022002290360220e3703002002200e370340024041201029220f450d00200f2002290340370000200f41186a200c290300370000200f41106a200b290300370000200f41086a2004290300370000200128020421102001280200211102400240200a2005470d0041012112410121130c010b41012112410121130340200628020821032006280200210702400340200241e0006a41186a2208200a41186a290000370300200241e0006a41106a2209200a41106a290000370300200241e0006a41086a2201200a41086a2900003703002002200a290000370360200a41206a210a4100210402400240200341014b0d0020030e020301030b2003210b0340200b410176220c20046a220d20042007200d4105746a200241e0006a412010f8044101481b2104200b200c6b220b41014b0d000b0b200720044105746a200241e0006a412010f8040d01200a2005470d000c030b0b200241c0006a41086a2001290300220e370300200241c0006a41106a20092903002214370300200241c0006a41186a20082903002215370300200220022903602216370340200241186a220b2015370300200241106a220c2014370300200241086a220d200e37030020022016370300024020132012470d000240201241016a22042012490d0020124101742207200420042007491b221341ffffff3f712013470d00201341057422044100480d000240024020120d0020041029210f0c010b200f20124105742004102a210f0b200f0d0120044101102c000b102d000b200f20124105746a22042002290300370000200441186a200b290300370000200441106a200c290300370000200441086a200d290300370000201241016a2112200a2005470d000b0b02402010450d002011102e0b20002012360208200020133602042000200f3602000c010b41204101102c000b20024180016a24000bed0704067f017e0a7f027e230041f0006b22032400200341206a2001200228020c22041100000240024020032802200d002000410036020820004208370200200120022802001101002002280204450d012001102e0c010b200341c8006a41106a200341206a41106a290300370300200341c8006a41086a200341206a41086a290300370300200341c8006a41186a200341206a41186a290300370300200341c8006a41206a200341206a41206a280200360200200341086a200341d4006a290200370300200341106a200341dc006a290200370300200341186a200341e4006a290200370300200320032903203703482003200329024c370300200341c8006a2001200228021022051100000240024002400240417f2003280248220641016a220720072006491b2208ad42287e2209422088a70d002009a72206417f4c0d000240024020060d004108210a4108210b0c010b20061029220a450d02200a210b0b200a2003290300370300200a41186a200341186a220c290300370300200a41106a200341106a220d290300370300200a41086a200341086a290300370300200b4201370320200341206a200120041100000240024020032802200d004101210e0c010b200341c8006a410472210641c800210f4101210e0340200341c8006a41206a200341206a41206a280200360200200341c8006a41186a2210200341206a41186a290300370300200341c8006a41106a2211200341206a41106a290300370300200341c8006a41086a2212200341206a41086a29030037030020032003290320370348200341086a2207200641086a290200370300200d200641106a290200370300200c200641186a290200370300200320062902003703002010200c2903003703002011200d29030037030020122007290300370300200320032903003703480240200e2008470d00200341206a200120051100002008417f2003280220220741016a221320132007491b6a22072008490d0620084101742213200720072013491b2213ad42287e2209422088a70d062009a722074100480d060240024020080d0020071029210a0c010b200a200841286c2007102a210a0b200a450d05200a210b201321080b200b200f6a221341606a2207200329034837030020122903002109201129030021142010290300211520134201370300200741186a2015370300200741106a2014370300200741086a2009370300200341206a20012004110000200f41286a210f200e41016a210e20032802200d000b0b2001200228020011010002402002280204450d002001102e0b2000200e360208200020083602042000200b3602000c040b1032000b20064108102c000b20074108102c000b102d000b200341f0006a24000bd80705077f037e087f017e017f23004180016b22022400024002400240200141086a220328020022042001410c6a2802002205460d0020012802102106200241f4006a2107034020032004220841206a2204360200200841086a2903002109200841106a290300210a2008290300210b200241e0006a41186a200841186a290300370300200241e0006a41106a200a370300200241e0006a41086a20093703002002200b3703600240200aa720062802004d0d002001280214220c2007460d002007290000200c290000520d030b20052004470d000b200521040b2000410036020820004208370200024020042005460d00200141086a200520046b41606a41607120046a41206a3602000b2001280204450d012001280200102e0c010b200241086a2204200241e0006a41086a290300370300200241106a2203200241e0006a41106a290300370300200241186a2207200241e0006a41186a29030037030020022002290360220a3703202002200a37030002400240024041201029220d450d00200d2002290300370300200d41186a2007290300370300200d41106a2003290300370300200d41086a20042903003703002001280204210e2001280200210f4101211002400240200541606a2008470d00410121110c010b0240200c200241f4006a2207470d00410121110c010b200841206a2112200541606a2113410121104101211103402012210802400340200241e0006a41186a2204200841186a290300370300200241e0006a41106a2203200841106a290300220a370300200241e0006a41086a2201200841086a290300370300200220082903003703600240200aa720062802004d0d002007290000200c290000520d020b2005200841206a2208470d000c030b0b200241206a41086a2001290300220a370300200241206a41106a20032903002209370300200241206a41186a2004290300220b3703002002200229036022143703202004200b370300200320093703002001200a37030020022014370360024020112010470d00201041016a22112010490d0520104101742212201120112012491b221141ffffff3f712011470d05201141057422124100480d050240024020100d0020121029210d0c010b200d20104105742012102a210d0b200d450d040b200841206a2112200d20104105746a22152002290360370300201541186a2004290300370300201541106a2003290300370300201541086a2001290300370300201041016a211020132008470d000b0b0240200e450d00200f102e0b20002010360208200020113602042000200d3602000c030b41204108102c000b20124108102c000b102d000b20024180016a24000ba41601067f230041106b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e050003010204000b2002410036020820024201370300410110292203450d05200242818080801037020420022003360200200341023a0000200141016a200210460c040b2002410036020820024201370300410110292203450d05200242818080801037020420022003360200200341043a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1a20034101742205200420042005491b22054100480d1a0240024020030d002005102921040c010b200228020020032005102a21040b2004450d0720022005360204200220043602000b2002200341016a360208200420036a20012d00013a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1a20034101742205200420042005491b22054100480d1a0240024020030d002005102921040c010b200228020020032005102a21040b2004450d0820022005360204200220043602000b2002200341016a360208200420036a20012d00023a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1a20034101742205200420042005491b22054100480d1a0240024020030d002005102921040c010b200228020020032005102a21040b2004450d0920022005360204200220043602000b2002200341016a360208200420036a20012d00033a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1a20034101742205200420042005491b22054100480d1a0240024020030d002005102921040c010b200228020020032005102a21040b2004450d0a20022005360204200220043602000b2002200341016a360208200420036a20012d00043a000020012802082105200141106a2802002201200210470240024020022802042204200228020822036b2001490d00200228020021040c010b200320016a22062003490d1a20044101742207200620062007491b22064100480d1a0240024020040d002006102921040c010b200228020020042006102a21040b2004450d0b20022006360204200220043602000b2002200320016a360208200420036a2005200110f6041a0c030b2002410036020820024201370300410110292203450d0a200242818080801037020420022003360200200341053a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1920034101742205200420042005491b22054100480d190240024020030d002005102921040c010b200228020020032005102a21040b2004450d0c20022005360204200220043602000b2002200341016a360208200420036a20012d00013a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1920034101742205200420042005491b22054100480d190240024020030d002005102921040c010b200228020020032005102a21040b2004450d0d20022005360204200220043602000b2002200341016a360208200420036a20012d00023a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1920034101742205200420042005491b22054100480d190240024020030d002005102921040c010b200228020020032005102a21040b2004450d0e20022005360204200220043602000b2002200341016a360208200420036a20012d00033a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1920034101742205200420042005491b22054100480d190240024020030d002005102921040c010b200228020020032005102a21040b2004450d0f20022005360204200220043602000b2002200341016a360208200420036a20012d00043a000020012802082105200141106a2802002201200210470240024020022802042204200228020822036b2001490d00200228020021040c010b200320016a22062003490d1920044101742207200620062007491b22064100480d190240024020040d002006102921040c010b200228020020042006102a21040b2004450d1020022006360204200220043602000b2002200320016a360208200420036a2005200110f6041a0c020b2002410036020820024201370300410110292203450d0f200242818080801037020420022003360200200341063a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1820034101742205200420042005491b22054100480d180240024020030d002005102921040c010b200228020020032005102a21040b2004450d1120022005360204200220043602000b2002200341016a360208200420036a20012d00013a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1820034101742205200420042005491b22054100480d180240024020030d002005102921040c010b200228020020032005102a21040b2004450d1220022005360204200220043602000b2002200341016a360208200420036a20012d00023a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1820034101742205200420042005491b22054100480d180240024020030d002005102921040c010b200228020020032005102a21040b2004450d1320022005360204200220043602000b2002200341016a360208200420036a20012d00033a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1820034101742205200420042005491b22054100480d180240024020030d002005102921040c010b200228020020032005102a21040b2004450d1420022005360204200220043602000b2002200341016a360208200420036a20012d00043a000020012802082105200141106a2802002201200210470240024020022802042204200228020822036b2001490d00200228020021040c010b200320016a22062003490d1820044101742207200620062007491b22064100480d180240024020040d002006102921040c010b200228020020042006102a21040b2004450d1520022006360204200220043602000b2002200320016a360208200420036a2005200110f6041a0c010b2002410036020820024201370300410110292203450d14200242818080801037020420022003360200200341003a0000200141046a28020021052001410c6a2802002201200210470240024020022802042204200228020822036b2001490d00200228020021040c010b200320016a22062003490d1720044101742207200620062007491b22064100480d170240024020040d002006102921040c010b200228020020042006102a21040b2004450d1620022006360204200220043602000b2002200320016a360208200420036a2005200110f6041a0b200020022201290200370200200041086a200141086a280200360200200241106a24000f0b41014101102c000b41014101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20064101102c000b41014101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20064101102c000b41014101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20064101102c000b41014101102c000b20064101102c000b102d000bb50501037f02400240024002400240024002400240410110292202450d00200220002d00003a0000200241014102102a2202450d01200220002d00013a0001200241024104102a2202450d02200220002d00023a0002200220002d00033a0003200241044108102a2202450d03200220002d00043a0004200220002d00053a0005200220002d00063a0006200220002d00073a0007200241084110102a2202450d04200220002d00083a0008200220002d00093a0009200220002d000a3a000a200220002d000b3a000b200220002d000c3a000c200220002d000d3a000d200220002d000e3a000e200220002d000f3a000f200241104120102a2202450d05200220002d00103a0010200220002d00113a0011200220002d00123a0012200220002d00133a0013200220002d00143a0014200220002d00153a0015200220002d00163a0016200220002d00173a0017200220002d00183a0018200220002d00193a0019200220002d001a3a001a200220002d001b3a001b200220002d001c3a001c200220002d001d3a001d200220002d001e3a001e200220002d001f3a001f02400240200141046a2802002203200141086a28020022006b4120490d00200128020021030c010b200041206a22042000490d0820034101742200200420042000491b22004100480d080240024020030d002000102921030c010b200128020020032000102a21030b2003450d0720012003360200200141046a2000360200200141086a28020021000b200141086a200041206a360200200320006a220041186a200241186a290000370000200041106a200241106a290000370000200041086a200241086a290000370000200020022900003700002002102e0f0b41014101102c000b41024101102c000b41044101102c000b41084101102c000b41104101102c000b41204101102c000b20004101102c000b102d000b920701037f0240024002400240024002402000413f4b0d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0620024101742204200320032004491b22044100480d060240024020020d002004102921030c010b200128020020022004102a21030b2003450d0220012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20004102743a00000f0b200041808001490d032000418080808004490d020c010b20044101102c000b0240024002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0520024101742204200320032004491b22044100480d050240024020020d002004102921030c010b200128020020022004102a21030b2003450d0120012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a000002400240200141046a2802002203200428020022026b4104490d00200128020021030c010b200241046a22042002490d0520034101742202200420042002491b22024100480d050240024020030d002002102921030c010b200128020020032002102a21030b2003450d0220012003360200200141046a2002360200200141086a28020021020b200141086a200241046a360200200320026a20003600000f0b20044101102c000b20024101102c000b024002400240200141046a2802002203200141086a28020022026b4104490d00200128020021030c010b200241046a22042002490d0320034101742202200420042002491b22024100480d030240024020030d002002102921030c010b200128020020032002102a21030b2003450d0120012003360200200141046a2002360200200141086a28020021020b200141086a200241046a360200200320026a20004102744102723600000f0b20024101102c000b024002400240200141046a2802002203200141086a28020022026b4102490d00200128020021030c010b200241026a22042002490d0220034101742202200420042002491b22024100480d020240024020030d002002102921030c010b200128020020032002102a21030b2003450d0120012003360200200141046a2002360200200141086a28020021020b200141086a200241026a360200200320026a20004102744101723b00000f0b20024101102c000b102d000bf40601067f230041f0006b21020240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a2206360204410121072001200441016a360200200541f001490d0a200541847e6a220541034b0d0420050e0401020803010b200041023a00000f0b20064102490d0320042f0001210520012003417d6a3602042001200441036a360200200541ef014b0d04200041023a00000f0b20064104490d042004280001210520012003417b6a3602042001200441056a36020041012107200541ffff034b0d07200041023a00000f0b41002105200241003a00682003417f6a21062003417e6a210302400340024020062005470d000240200541ff0171450d00200241003a00680b410121010c020b200241c8006a20056a200420056a220741016a2d00003a0000200120033602042001200741026a3602002002200541016a22073a00682003417f6a21032007210520074120470d000b200241c6006a20022d004a3a0000200241306a200241d7006a290000370300200241386a200241df006a290000370300200241c0006a200241e7006a2d00003a0000200220022f01483b01442002200229004f370328200228004b2105410021010b200241246a41026a2203200241c4006a41026a2d00003a0000200241086a41086a2207200241286a41086a290300370300200241086a41106a2204200241286a41106a290300370300200241086a41186a2206200241286a41186a2d00003a0000200220022f01443b0124200220022903283703082001450d05200041023a00000f0b200041023a00000f0b200041023a00000f0b410121070c030b200041023a00000f0b0240200641044f0d00200041023a00000f0b200041023a000020012003417b6a3602042001200441056a3602000f0b200241286a41026a20032d00003a0000200241c8006a41086a2007290300370300200241c8006a41106a2004290300370300200241c8006a41186a20062d00003a0000200220022f01243b012820022002290308370348410021070b200020073a0000200020022f01283b0001200041046a2005360200200041086a2002290348370200200041036a2002412a6a2d00003a0000200041106a200241c8006a41086a290300370200200041186a200241c8006a41106a290300370200200041206a200241c8006a41186a2802003602000bb20801037f0240024002400240024002400240024020002d00004101460d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0820024101742204200320032004491b22044100480d080240024020020d002004102921030c010b200128020020022004102a21030b2003450d0220012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41ff013a0000200041016a2001104a0f0b0240024002400240200041046a280200220241ffff034b0d00200241ef014b0d03200141046a280200200141086a2802002200460d01200128020021030c020b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d0a20004101742204200320032004491b22044100480d0a0240024020000d002004102921030c010b200128020020002004102a21030b2003450d0520012003360200200141046a2004360200200141086a28020021000b200141086a2204200041016a360200200320006a41fd013a000002400240200141046a2802002203200428020022006b4104490d00200128020021030c010b200041046a22042000490d0a20034101742200200420042000491b22004100480d0a0240024020030d002000102921030c010b200128020020032000102a21030b2003450d0620012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20023600000f0b200041016a22032000490d0820004101742204200320032004491b22044100480d080240024020000d002004102921030c010b200128020020002004102a21030b2003450d0520012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a20023a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d0720004101742204200320032004491b22044100480d070240024020000d002004102921030c010b200128020020002004102a21030b2003450d0520012003360200200141046a2004360200200141086a28020021000b200141086a2204200041016a360200200320006a41fc013a000002400240200141046a2802002203200428020022006b4102490d00200128020021030c010b200041026a22042000490d0720034101742200200420042000491b22004100480d070240024020030d002000102921030c010b200128020020032000102a21030b2003450d0620012003360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200320006a20023b00000f0b20044101102c000b20044101102c000b20004101102c000b20044101102c000b20044101102c000b20004101102c000b102d000b952801057f02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2202280200200141086a22032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00003a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00013a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00023a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00033a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00043a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00053a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00063a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00073a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00083a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00093a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000e3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1020012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000f3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00103a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00113a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00123a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00133a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00143a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00153a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00163a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00173a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00183a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00193a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001e3a000002400240200228020020032802002202460d00200128020021040c010b200241016a22042002490d2120024101742205200420042005491b22054100480d210240024020020d002005102921040c010b200128020020022005102a21040b2004450d2020012004360200200141046a2005360200200141086a28020021020b2003200241016a360200200420026a20002d001f3a00000f0b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20054101102c000b102d000b9b0502067f027e230041c0006b220324002003200236020820032001280200220236020020032002200128020841246c22016a22043602042003200341086a36020c024002400240200141ed00490d00200341286a410472210103402003200241246a360200200341286a2003410c6a2002104c200341106a41086a2204200141086a2205290200370300200341106a41106a2206200141106a220728020036020020032001290200370310200341106a2108200328022822024105470d0220032003280200220241246a360200200341286a2003410c6a2002104c200420052902003703002006200728020036020020032001290200370310200328022822024105470d0220032003280200220241246a360200200341286a2003410c6a2002104c200420052902003703002006200728020036020020032001290200370310200328022822024105470d0220032003280200220241246a360200200341286a2003410c6a2002104c200420052902003703002006200728020036020020032001290200370310200328022822024105470d0220032802042204200328020022026b41ec004b0d000b0b024020022004460d00200341286a410472210103402003200241246a360200200341286a2003410c6a2002104c200341106a41086a200141086a290200370300200341106a41106a200141106a280200360200200320012902003703100240200328022822024105460d00200341106a21080c030b200328020022022003280204470d000b0b200041053602000c010b200341286a41106a200841106a2802002201360200200341286a41086a200841086a290200220937030020032008290200220a370328200020023602002000200a3702042000410c6a2009370200200041146a20013602000b200341c0006a24000bea0602047f037e230041206b2203240020012802002802002201280204210420012802002101024002400240024002400240024002400240024002400240024020022d00000e050001020304000b200241016a21024100210520010e0406040507060b200241086a210641012105200241016a210220010e0405030406050b200241086a2106200241016a21024102210520010e0404020305040b200241086a2106200241016a21024103210520010e0403010204030b41042105200241046a210220010e0402000103020b20054102470d0520022004470d03200621020c040b20054103470d04024020022004470d00200621020c040b200228000021012006210220012004280000460d030c040b20054101470d03024020022004470d00200621020c030b200228000021012006210220012004280000460d020c030b20054104470d020c010b200228000021012006210220012004280000470d010b2002280200210120032002280208220236020c200320013602082002450d0020012d0000210520032002417f6a220436020c2003200141016a3602082005417f6a220541044b0d000240024002400240024002400240024020050e050001020304000b200341106a200341086a103e20032802102205450d0720032902142107200328020c22024104490d0620032802082201350000210820032002417c6a36020c2003200141046a360208410021060c050b20044104490d062001280001210520032002417b6a36020c2003200141056a360208200341106a200341086a103e20032802102202450d06200328021421010240200328020c220441044f0d002001450d072002102e0c070b200341186a350200210820032802082206350000210920032004417c6a36020c2003200641046a3602082001ad4220862002ad84210720082009422086842108410121060c040b20044108490d05200129000121072003200241776a36020c2003200141096a360208410221060c030b20044104490d042001280001210520032002417b6a36020c2003200141056a360208410321060c010b4104210620044104490d032001280001210520032002417b6a36020c2003200141056a3602080b0b2000200536020420002006360200200041106a2008370300200041086a20073703000c020b2007a7450d002005102e0b200041053602000b200341206a24000b942004027f027e087f037e230041a00d6b22072400024002400240200128022c200128023c22082802b801460d002004420020042903082209200841c0006a2903007d220a200a20095622081b3703082008450d01200041c083c00036020420004101360200200041086a412a3602002000410c6a2006290200370200200041146a200641086a2802003602000c020b200041f682c00036020420004101360200200041086a41243602002000410c6a2006290200370200200041146a200641086a2802003602000c010b200741086a41186a200141e4006a290000370300200741086a41106a200141dc006a290000370300200741086a41086a200141d4006a2900003703002007200129004c3703082006280208210b20062802002108200741a0026a41186a220c4200370300200741a0026a41106a220d4200370300200741a0026a41086a220e4200370300200742003703a0022008200b200741a0026a1000200741c00a6a41186a200c290300370300200741c00a6a41106a200d290300370300200741c00a6a41086a200e290300370300200720072903a0023703c00a024002400240024002400240024002400240412010292208450d0020082005290000370000200841186a200541186a290000370000200841106a200541106a290000370000200841086a200541086a2900003700002008412041c000102a2208450d01200820072903c00a370020200841386a200741c00a6a41186a290300370000200841306a200741c00a6a41106a290300370000200841286a200741c00a6a41086a290300370000200841c000418001102a2208450d0220082007290308370040200841d8006a200741086a41186a290300370000200841d0006a200741086a41106a290300370000200841c8006a200741086a41086a290300370000200741a0026a41186a220c4200370300200741a0026a41106a220d4200370300200741a0026a41086a220e4200370300200742003703a002200841e000200741a0026a1000200741286a41186a220f200c290300370300200741286a41106a220c200d290300370300200741286a41086a220d200e290300370300200720072903a0023703282008102e200629020021092007419c016a200d290300370200200741a4016a200c290300370200200741ac016a200f290300370200200741c8006a41386a4100360200200741c8006a41286a419c83c000360200200741ec006a200141146a2210360200200741e4006a4200370200200741c8006a41186a221141e08dc0003602002007200729032837029401200742083703782007410036025c200741003602502007200128024436028c012007200129023c370284012007200128022c41016a3602742001290300210a20072001280248360290012007200a370348200741b8016a41186a200541186a290000370300200741b8016a41106a200541106a290000370300200741b8016a41086a200541086a2900003703002007410136025c200720052900003703b8012010200741286a104e21062007200728025c417f6a220836025c024020060d0020080d042007417f36025c20074180026a41186a200741286a41186a29030037030020074180026a41106a200741286a41106a29030037030020074180026a41086a200741286a41086a2903003703002007200729032837038002024002402007280260220e41e08dc000460d002007280264210f0c010b4100210f200741c00a6a410041e00210f5041a200741a0026a410041a00810f5041a41880b1029220e450d06200e41003b0106200e4100360200200e41086a200741c00a6a41e00210f6041a200e41e8026a200741a0026a41a00810f6041a200741003602642007200e3602600b024002400340200e41086a2108200e2f0106221241057421064100210c0240024003402006450d0120074180026a2008412010f804220d450d02200641606a2106200c41016a210c200841206a2108200d417f4a0d000b200c417f6a21120b200f450d02200f417f6a210f200e20124102746a41880b6a280200210e0c010b0b200e200c41e0006c6a41e8026a21060c010b200741e0016a41186a20074180026a41186a290300220a370300200741e0016a41106a20074180026a41106a2903002213370300200741e0016a41086a20074180026a41086a2903002214370300200720072903800222153703e001200741dc0a6a2014370200200741e40a6a2013370200200741ec0a6a200a3702002007200741e8006a3602d00a200720123602cc0a200720113602c80a2007200e3602c40a200741003602c00a200720153702d40a200741d4026a4200370200200741003a00dc02200742003703a002200741e08dc0003602d002200742003703b802200741c00a6a200741a0026a104f21060b200641013a003c200641286a427f370300200641206a427f3703002006413d6a20072903b801370000200641d5006a200741d0016a290300370000200641cd006a200741c8016a290300370000200641c5006a200741c0016a290300370000200642013703182007200728025c41016a36025c200720044101200741086a200741286a20022003200741c8006a10502007280200220e0d06200741a0026a2005200728028c012802001051024020072802a0024101470d00200741a8026a280200210520072802a402210e0c090b20074180026a41186a220c200741a0026a410472220641186a2802002208360200200741c00a6a41106a200641086a290200370300200741c00a6a41186a220d200641106a290200370300200741e00a6a2008360200200741063602c40a200741b1a4c5003602c00a200720062902003703c80a20072802880121062007200741c8006a3602b8022007290348210a2007280290012108200741c8026a200741086a41086a220f290300370300200741d0026a200741086a41106a2212290300370300200741d8026a200741086a41186a2211290300370300200720033703a802200720023703a002200720083602bc022007200a3703b002200720072903083703c0022007200b3602e801200720093703e00120074180026a2006200741c00a6a200741a0026a200741e0016a200410522007418c026a290200210920074180026a41086a22062802002105200728028402210e02402007280280024101470d0020074180026a41146a280200210b200d280200450d09200741c00a6a41146a280200102e0c090b2006200f29030037030020074180026a41106a2012290300370300200c2011290300370300200741e0016a41086a200741286a41086a290300370300200741e0016a41106a200741286a41106a290300370300200741e0016a41186a200741286a41186a2903003703002007200729030837038002200720072903283703e00102402007280280012206200728027c460d00200728027821080c0a0b0240200641016a22082006490d002006410174220c20082008200c491b220cad42b0017e2202422088a70d002002a7220d4100480d000240024020060d00200d102921080c010b2007280278200641b0016c200d102a21080b2008450d082007200c36027c2007200836027820072802800121060c0a0b102d000b41c8dac100210e412a21050c070b41204101102c000b41c0004101102c000b4180014101102c000b41aed9c1004110200741a0026a41c0d9c1001053000b41880b4108102c000b200728020421050c010b200d4108102c000b024020072802502206450d00200741d4006a280200450d002006102e0b200728026821012007280260210602400240200728026422080d002006210c0c010b2008210d2006210c0340200c2802880b210c200d417f6a220d0d000b0340200620062f01064102746a41880b6a28020021062008417f6a22080d000b0b200741bc026a20062f010636020041002108200741b8026a4100360200200741b4026a2006360200200720013602c002200741003602b002200742003703a8022007200c3602a402200741003602a002200741a0026a105402402007280280012206450d002007280278210d200641b0016c2101034002400240200d20086a22062d0000220c41014b0d0002400240200c0e020001000b0240200641086a280200450d00200641046a280200102e0b200641106a2d00004105490d02200641386a280200450d02200641346a280200102e0c020b200641286a102f0c010b200641e8006a280200450d00200641e4006a280200102e0b2001200841b0016a2208470d000b0b0240200728027c450d002007280278102e0b2000200e36020420004101360200200041146a200b3602002000410c6a2009370200200041086a20053602000c010b2008200641b0016c6a220641003a0000200620072f00dd013b0001200641013a00102006410036000c200642013700042006200729038002370011200620072903e001370031200641036a200741df016a2d00003a0000200641196a20074180026a41086a290300370000200641216a20074180026a41106a290300370000200641296a20074180026a41186a290300370000200641396a200741e0016a41086a290300370000200641c1006a200741e0016a41106a290300370000200641c9006a200741e0016a41186a290300370000200641e0006a200741c7016a290000370000200641d9006a200741b8016a41086a290000370000200620072900b801370051200641e8006a200741a0026a41c80010f6041a200720072802800141016a2208360280010240200741c00a6a41186a280200450d00200741d40a6a280200102e20072802800121080b200728027c210b20072802782104200728026821122007280264210d2007280260210602402007280250220c450d00200741d4006a280200450d00200c102e0b0240024020094280808080f01f8350450d00200720123602a8022007200d3602a402200720063602a0022010200741a0026a105520072004200841b0016c6a3602ac02200720043602a8022007200b3602a402200720043602a002200141306a200741a0026a10280c010b02402008450d00200841b0016c210f41002108034002400240200420086a220c2d0000220141014b0d000240024020010e020001000b0240200c41086a280200450d00200c41046a280200102e0b200c41106a2d00004105490d02200c41386a280200450d02200c41346a280200102e0c020b200c41286a102f0c010b200c41e8006a280200450d00200c41e4006a280200102e0b200f200841b0016a2208470d000b0b0240200b450d002004102e0b02400240200d0d00200621080c010b200d210c20062108034020082802880b2108200c417f6a220c0d000b0340200620062f01064102746a41880b6a2802002106200d417f6a220d0d000b0b200741bc026a20062f0106360200200741b8026a4100360200200741b4026a2006360200200720123602c002200741003602b002200742003703a802200720083602a402200741003602a002200741a0026a10540b20002007290328370004200041003602002000412c6a2009370200200041286a2005360200200041246a200e3602002000411c6a200741c0006a290300370000200041146a200741386a2903003700002000410c6a200741306a2903003700000b200741a00d6a24000b940201097f230041106b220224000240200028020041016a220341004c0d0020002003360200200041046a2104200041086a28020021050240024003402004280200220641086a210720062f01062208410574210441002109024003402004450d0120012007412010f804220a450d03200441606a2104200941016a2109200741206a2107200a417f4a0d000b2009417f6a21080b02402005450d002005417f6a2105200620084102746a41880b6a21040c010b0b20002802102001200041146a2802002802181102002104200028020021030c010b2006200941e0006c6a41a4036a2d000041014621040b20002003417f6a360200200241106a240020040f0b41e3d7c1004118200241086a41fcd7c1001053000b8f1901187f230041d0116b2202240020002802102203200328020041016a360200200028020c21042000280208210520002802042103200241206a41186a22062000412c6a290000370300200241206a41106a2207200041246a290000370300200241206a41086a22082000411c6a29000037030020022000290014370320200241a0026a200141e00010f6041a024002400240024020032f01062201410b490d00200241b0036a410041e00210f5041a20024198066a410041a00810f5041a0240024041880b10292209450d00200941003b010620094100360200200941086a200241b0036a41e00210f6042101200941e8026a20024198066a41a00810f6042106200220032f00c8013b01ac032002200341ca016a2d00003a00ae03200220032900db01370398032002200341e0016a29000037009d03200341cb016a280000210a200341cf016a280000210b200341d3016a280000210c200341d7016a280000210d20024198066a200341a8076a41e00010f6041a2001200341e8016a20032f010641796a220041057410f6042101200620034188086a200041e0006c10f6042106200341063b0106200920003b0106200220022f01ac033b019403200220022d00ae033a0096032002200229039803370380032002200229009d0337008503200241b0036a20024198066a41e00010f6041a0240024020044107490d00200441057420016a41c07e6a2001200441796a22074105746a2201200041ffff037120076b41057410f7041a200141186a200241206a41186a290300370000200141106a200241206a41106a290300370000200141086a200241206a41086a29030037000020012002290320370000200441e0006c20066a220041c07b6a200041e07a6a220e200941066a22002f010020076b41e0006c10f7041a200e200241a0026a41e00010f6041a0c010b200341086a20044105746a220141206a2001200341066a22002f010020046b41057410f7041a200141186a200241206a41186a290300370000200141106a200241206a41106a290300370000200141086a200241206a41086a29030037000020012002290320370000200341e8026a200441e0006c6a220e41e0006a200e20002f010020046b41e0006c10f7041a200e200241a0026a41e00010f6041a0b20024188026a41026a220420022d0096033a0000200020002f010041016a3b0100200220022f0194033b01880220022002290380033703800120022002290085033700850120024190016a200241b0036a41e00010f6041a2002411c6a41026a220f20042d00003a0000200220022f0188023b011c2002200229038001370308200220022900850137000d200241206a20024190016a41e00010f6041a20032802002206450d0320032f0104211020024198066a410272211103402002419c026a41026a2212200f2d00003a0000200220022f011c3b019c0220022002290308370388022002200229000d37008d02200241a0026a200241206a41e00010f6041a201041ffff0371210702400240024020062f01062203410b490d002011410041b20b10f5041a41b80b10292201450d0520014100360200200141046a20024198066a41b40b10f6041a200220062f00c8013b01ac032002200641ca016a2d00003a00ae03200220062900db01370398032002200641e0016a29000037009d03200641cb016a2800002113200641cf016a2800002114200641d3016a2800002115200641d7016a280000211620024198066a200641a8076a41e00010f6041a200141086a200641e8016a20062f0106220041796a220341057410f6042117200141e8026a20064188086a200341e0006c10f6042118200141880b6a200641a40b6a2000417a6a220841027410f6042119200641063b0106200120033b010602402008450d00410021032019210003402000280200220420033b010420042001360200200041046a21002008200341016a2203470d000b0b200241b0036a20024198066a41e00010f6041a200220022d00ae0322033a009603200220022f01ac0322003b0194032002200229009d033700850320022002290398033703800320024194066a41026a220820033a0000200220003b01940620022002290380033703800120022002290085033700850120024198066a200241b0036a41e00010f6041a201041ffff037122004107490d0120172007417a6a22044105746a2017200741796a22034105746a220020012f010620036b41057410f7041a200041186a200229008d023700002000200d36000f2000200c36000b2000200b3600072000200a360003200041026a20122d00003a0000200020022f019c023b00002000200229038802370013200741e0006c20186a220041c07b6a200041e07a6a220020012f010620036b41e0006c10f7041a2000200241a0026a41e00010f6041a200120012f010641016a22003b01062007410274220a20196a416c6a201920044102746a2210200041ffff0371220720046b41027410f7041a2010200936020020072004490d022001200a6a41f00a6a2100034020002802002204200341016a22033b010420042001360200200041046a210020032007490d000c030b0b200641086a2200200741016a22044105746a200020074105746a2200200320076b220141057410f7041a2000200d36000f2000200c36000b2000200b3600072000200a360003200041026a2002419c026a41026a2d00003a0000200020022f019c023b00002000200229038802370013200041186a200229008d023700002006200741e0006c6a220041c8036a200041e8026a2200200141e0006c10f7041a2000200241a0026a41e00010f6041a2006200341016a22033b01062007410274200641880b6a22006a41086a200020044102746a2200200341ffff037120046b41027410f7041a20002009360200201041ffff037120062f010622034f0d07200920043b010420092006360200200420034f0d072003417f6a210120062004417f6a22034102746a41900b6a2100034020002802002204200341026a3b010420042006360200200041046a21002001200341016a2203470d000c080b0b200641086a2203200741016a22044105746a200320074105746a220320062f0106221020076b221941057410f7041a2003200d36000f2003200c36000b2003200b3600072003200a360003200341026a20122d00003a0000200320022f019c023b00002003200229038802370013200341186a200229008d02370000200641e8026a200741e0006c6a220341e0006a2003201941e0006c10f7041a2003200241a0026a41e00010f6041a2006201041016a22033b010620074102742219200641880b6a22106a41086a201020044102746a2210200341ffff037120046b41027410f7041a20102009360200200020062f010622044f0d00200620196a418c0b6a2103034020032802002200200741016a22073b010420002006360200200341046a210320042007470d000b0b20024184026a41026a220320082d00003a0000200220022f0194063b01840220022002290380013703f00120022002290085013700f50120024190016a20024198066a41e00010f6041a200f20032d00003a0000200220022f0184023b011c200220022903f001370308200220022900f50137000d200241206a20024190016a41e00010f6041a0240200628020022030d002013210a2016210d2015210c2014210b200121090c050b20062f010421102013210a2016210d2015210c2014210b20032106200121090c000b0b41880b4108102c000b41b80b4108102c000b200320044105746a220041286a200041086a2210200120046b41057410f7041a200041206a2006290300370000200041186a2007290300370000200041106a2008290300370000201020022903203700002003200441e0006c6a220041c8036a200041e8026a220e20032f010620046b41e0006c10f7041a200e200241a0026a41e00010f6041a200320032f010641016a3b01060c010b20024198066a410272410041b20b10f5041a41b80b10292203450d0120034100360200200341046a20024198066a41b40b10f6041a2003200528020022003602880b200520033602002005200528020441016a360204200041003b010420002003360200200320032f010622044105746a220041086a20022f011c3b00002000410a6a2002411c6a41026a2d00003a0000200041176a200d360000200041136a200c3600002000410f6a200b3600002000410b6a200a3600002000411b6a2002290308370000200041206a200229000d3700002003200441e0006c6a41e8026a200241206a41e00010f6041a200341880b6a200441016a22004102746a2009360200200320003b0106200920003b0104200920033602000b200241d0116a2400200e0f0b41b80b4108102c000b9f0d020b7f067e230041d0016b22082400024002400240024002400240200728021441016a220941004c0d00200741146a210a200720093602142007411c6a280200210b200741186a220c210d024002400340200d280200220e41086a210f200e2f01062210410574210d41002111024002400340200d450d012004200f412010f8042212450d02200d41606a210d201141016a2111200f41206a210f2012417f4a0d000b2011417f6a21100b200b450d02200b417f6a210b200e20104102746a41880b6a210d0c010b0b200e201141e0006c6a220d41e8026a280200450d00200d41f8026a2903002113200d41f0026a29030021140c010b200841286a200741246a2802002004200741286a28020028021c110300200841306a290300211320072802142109200829032821140b20072009417f6a360214200141186a2903002115200728023c210d20012903102116024002400240024041004101410220142013842217501b20021b0e03010200010b200d41a8016a210d0c020b200d4188016a210d0c010b200d4198016a210d0b20162015844200510d01200841186a200d290300200d41086a2903002016201510fc0420014200200129030822152008290318427f200841186a41086a290300501b7d22162016201556220d1b3703080240200d450d0041ea83c000210d4122210f0c060b200a28020041016a220141004c0d0220072001360214200728021c210b024002400340200c280200220e41086a210f200e2f01062210410574210d41002111024002400340200d450d012003200f412010f8042212450d02200d41606a210d201141016a2111200f41206a210f2012417f4a0d000b2011417f6a21100b200b450d02200b417f6a210b200e20104102746a41880b6a210c0c010b0b200e201141e0006c6a220d41e8026a280200450d00200d41f8026a2903002115200d41f0026a29030021160c010b200841086a200741246a2802002003200741286a28020028021c110300200841106a290300211520072802142101200829030821160b200a2001417f6a3602000240201620057d2218201656201520067d2016200554ad7d221620155620162015511b4101470d004191b5c000210d411d210f0c060b024020174200520d00200728023c220d290378200556200d4180016a290300221520065620152006511b450d0041d6b5c000210d411f210f0c060b20082003410220182016105602402008280200220d450d002008280204210f0c060b0240201420057c2217201454220d201320067c200dad7c221520135420152013511b450d0041e4b4c000210d412d210f0c060b4100210d024020032004470d000c060b024020032004412010f8040d000c060b200a2003201820161057200a2004201720151057200841a8016a41086a200341086a290000370300200841a8016a41106a200341106a290000370300200841a8016a41186a200341186a29000037030020084188016a41086a200441086a29000037030020084188016a41106a200441106a29000037030020084188016a41186a200441186a290000370300200820032900003703a801200820042900003703880102400240200741386a280200220f200741346a280200460d00200728023021110c010b200f41016a220d200f490d05200f4101742211200d200d2011491b220dad42b0017e2215422088a70d052015a722124100480d0502400240200f0d002012102921110c010b2007280230200f41b0016c2012102a21110b2011450d0420072011360230200741346a200d3602002007280238210f0b4100210d2011200f41b0016c6a220f41003a0000200f20082f00cd013b0001200f4200370008200f4101360004200f20082903a801370011200f200829038801370031200f41036a200841cf016a2d00003a0000200f41106a41003a0000200f41196a200841a8016a41086a290300370000200f41216a200841a8016a41106a290300370000200f41296a200841a8016a41186a290300370000200f41c9006a20084188016a41186a290300370000200f41c1006a20084188016a41106a290300370000200f41396a20084188016a41086a290300370000200f2005370358200f41e0006a2006370300200f41d4006a20084181016a41036a280000360000200f200828008101360051200f41e8006a200841386a41c80010f6041a2007200728023841016a3602380c050b41e3d7c1004118200841386a41fcd7c1001053000b41c8a5c3001058000b41e3d7c1004118200841386a41fcd7c1001053000b20124108102c000b102d000b2000200f3602042000200d360200200841d0016a24000bd61001107f230041a0016b2203240002400240024002400240024002400240024002400240411410292204450d00200441106a41002800aca543360000200441086a41002900a4a5433700002004410029009ca54337000020034294808080c00237027c200320043602782001200341f8006a1046200328027c2105200328028001210420032802782106200341f8006a41186a22074200370300200341f8006a41106a22084200370300200341f8006a41086a220942003703002003420037037820062004200341f8006a1000200341d8006a41186a2007290300370300200341d8006a41106a2008290300370300200341d8006a41086a20092903003703002003200329037837035820034100360278200341d8006a4120200341f8006a1008210a2003280278220b417f460d03200a450d032003200b36027c2003200a360278200341286a200341f8006a103120032802280d02200328022c2107200341206a200341f8006a103120032802200d0220032802242109200341186a200341f8006a103120032802180d02200328027c2204450d02200328021c210c20032004417f6a36027c20032003280278220441016a36027820042d0000220441014b0d02410021080240024020040e020100010b410121080b200341106a200341f8006a103120032802100d02200328027c220d20032802142204490d022004417f4c0d050240024020040d004101210e0c010b20041034220e450d02200e2003280278220f200410f6041a2003200d20046b36027c2003200f20046a3602780b200e450d02200341d4006a41026a220d200341386a41026a2d00003a0000200320032f00383b01540240200b450d00200a102e0b200341f8006a41026a200d2d00003a0000200320032f01543b01780c040b41144101102c000b20044101102c000b41eff0c2004133200341386a4184f4c2001053000b410221080b02402005450d002006102e0b0240024020084102470d004101210641f2dac1002107411121090c010b200341d8006a41026a200341f8006a41026a2d00003a0000200320032f01783b0158410021060b200341346a41026a200341d8006a41026a2d00003a0000200320032f01583b013402402006450d002000200736020420004101360200200041086a20093602000c060b200341d4006a41026a220a200341346a41026a2d00003a0000200320032f01343b015402400240200228025820074b0d00200421050c010b411510292208450d02410021072008410d6a4100290094a543370000200841086a410029008fa54337000020084100290087a54337000020034295808080d00237027c200320083602782001200341f8006a1046200328027c2105200328028001210620032802782108200341f8006a41186a22094200370300200341f8006a41106a220b4200370300200341f8006a41086a220c42003703002003420037037820082006200341f8006a1000200341d8006a41186a2009290300370300200341d8006a41106a200b290300370300200341d8006a41086a200c2903003703002003200329037837035820034100360278200341d8006a4120200341f8006a10082109024002402003280278220b417f470d00410021070c010b024020090d000c010b2003200b36027c20032009360278200341086a200341f8006a103102400240024020032802080d00200328027c220c200328020c2206490d002006417f4c0d050240024020060d00410121070c010b200610342207450d0220072003280278220d200610f6041a2003200c20066b36027c2003200d20066a3602780b20070d020b41eff0c2004133200341386a4184f4c2001053000b20064101102c000b200b450d002009102e0b02402005450d002008102e0b024020070d0020004183dbc10036020420004101360200200041086a411a3602000c060b2007410020071b210d200341f8006a20072006200210f701024020032802784101470d002000200329027c370204200041013602002006450d06200d102e0c060b02402004450d00200e102e0b200341d6006a20034197016a2d00003a0000200320032f0095013b015420034190016a2802002204417f4c0d0120034194016a2d000021082003418c016a280200210520034188016a280200210e20034184016a280200210c20034180016a2802002109200328027c21074101210202402004450d00200410292202450d042002200e200410f6041a0b200341386a41146a2004360200200341386a41106a20043602002003200c3602402003200936023c20032007360238200320023602442003200841ff01714101463a005041141029220b450d04200b41106a41002800aca543360000200b41086a41002900a4a543370000200b410029009ca54337000020034294808080c00237027c2003200b3602782001200341f8006a1046200328027c210b200328028001210f20032802782101200341f8006a41186a22104200370300200341f8006a41106a22114200370300200341f8006a41086a22124200370300200342003703782001200f200341f8006a1000200341d8006a41186a2010290300370300200341d8006a41106a2011290300370300200341d8006a41086a2012290300370300200320032903783703582003412036027c2003200341d8006a360278200341386a200341f8006a10f8010240200b450d002001102e0b02402004450d002002102e0b2006450d00200d102e0b20002007360204200020032f01543b001d200041003602002000411c6a20083a0000200041186a2004360200200041146a2005360200200041106a200e3602002000410c6a200c360200200041086a20093602002000411f6a200a2d00003a00000c050b1032000b41154101102c000b20044101102c000b41144101102c000b2004450d00200e102e0b200341a0016a24000beb3002097f017e230041c0006b22062400024002402002410c6a280200200241106a28020010192207417f460d00410c102922080d01410c4104102c000b10e202000b200820073602082008428180808010370200024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002404101450d002008410141016a3602004101417e460d0020084101410272360200410410292209450d01200920083602002008280208210a41031029220b450d02200b41026a41002d008cc5453a0000200b41002f008ac5453b000041061029220c450d03200c41046a41002f008b9a433b0000200c41002800879a43360000412010292207450d042007200a36021c2007410136021820074286808080e0003702102007200c36020c20074283808080303702042007200b36020020082008280200417f6a220b3602000240200b0d002008280208101a20082008280204417f6a220b360204200b0d002008102e0b41031029220b450d05200b41026a41002d008cc5453a0000200b41002f008ac5453b000041031029220c450d06200c41026a41002d008fc5453a0000200c41002f008dc5453b00002007412041c000102a2207450d072007410236023c2007410036023820074283808080303702302007200c36022c20074283808080303702242007200b36022041031029220b450d08200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410f1029220c450d09200c41076a41002900c39c45370000200c41002900bc9c45370000200741c000418001102a2207450d0a2007410336025c200741003602582007428f808080f0013702502007200c36024c20074283808080303702442007200b36024041031029220b450d0b200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410f1029220c450d0c200c41076a41002900d29c45370000200c41002900cb9c453700002007410436027c200741003602782007428f808080f0013702702007200c36026c20074283808080303702642007200b36026041031029220b450d0d200b41026a41002d008cc5453a0000200b41002f008ac5453b000041081029220c450d0e200c42e5f0d1fbb5ac98b6ec003700002007418001418002102a2207450d0f2007410536029c012007410036029801200742888080808001370290012007200c36028c012007428380808030370284012007200b3602800141031029220b450d10200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410a1029220c450d11200c41086a41002f00ea9c453b0000200c41002900e29c45370000200741063602bc01200741003602b8012007428a808080a0013702b0012007200c3602ac0120074283808080303702a4012007200b3602a00141031029220b450d12200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410a1029220c450d13200c41086a41002f00f49c453b0000200c41002900ec9c45370000200741073602dc01200741003602d8012007428a808080a0013702d0012007200c3602cc0120074283808080303702c4012007200b3602c00141031029220b450d14200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410a1029220c450d15200c41086a41002f00fe9c453b0000200c41002900f69c45370000200741083602fc01200741003602f8012007428a808080a0013702f0012007200c3602ec0120074283808080303702e4012007200b3602e00141031029220b450d16200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410b1029220c450d17200c41076a41002800879d45360000200c41002900809d453700002007418002418004102a2207450d182007410936029c0220074100360298022007428b808080b001370290022007200c36028c022007428380808030370284022007200b3602800241031029220b450d19200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410d1029220c450d1a200c41056a41002900909d45370000200c410029008b9d453700002007410a3602bc02200741003602b8022007428d808080d0013702b0022007200c3602ac0220074283808080303702a4022007200b3602a00241031029220b450d1b200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410c1029220c450d1c200c41086a41002800a09d45360000200c41002900989d453700002007410b3602dc02200741003602d8022007428c808080c0013702d0022007200c3602cc0220074283808080303702c4022007200b3602c00241031029220b450d1d200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410b1029220c450d1e200c41076a41002800ab9d45360000200c41002900a49d453700002007410c3602fc02200741003602f8022007428b808080b0013702f0022007200c3602ec0220074283808080303702e4022007200b3602e00241031029220c450d1f200c41026a41002d008cc5453a0000200c41002f008ac5453b000041151029220b450d20200b410d6a41002900bc9d45370000200b41086a41002900b79d45370000200b41002900af9d453700002007410d36029c03200741003602980320074295808080d002370290032007200b36028c032007428380808030370284032007200c3602800341031029220b450d21200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410a1029220c450d22200c41086a41002f00cc9d453b0000200c41002900c49d453700002007410e3602bc03200741003602b8032007428a808080a0013702b0032007200c3602ac0320074283808080303702a4032007200b3602a00341031029220b450d23200b41026a41002d008cc5453a0000200b41002f008ac5453b000041071029220c450d24200c41036a41002800d19d45360000200c41002800ce9d453600002007410f3602dc03200741003602d80320074287808080f0003702d0032007200c3602cc0320074283808080303702c4032007200b3602c00341031029220c450d25200c41026a41002d008cc5453a0000200c41002f008ac5453b000041111029220b450d26200b41106a41002d00e59d453a0000200b41086a41002900dd9d45370000200b41002900d59d45370000200741103602fc03200741003602f8032007429180808090023702f0032007200b3602ec0320074283808080303702e4032007200c3602e00341031029220b450d27200b41026a41002d008cc5453a0000200b41002f008ac5453b0000410e1029220c450d28200c41066a41002900ec9d45370000200c41002900e69d453700002007418004418008102a220a450d29200a411136029c04200a410036029804200a428e808080e00137029004200a200c36028c04200a42838080803037028404200a200b36028004410310292207450d2a200741026a41002d008cc5453a0000200741002f008ac5453b000041101029220b450d2b200b41086a41002900fc9d45370000200b41002900f49d45370000200a41123602bc04200a41003602b804200a429080808080023702b004200a200b3602ac04200a4283808080303702a404200a20073602a004410310292207450d2c200741026a41002d008cc5453a0000200741002f008ac5453b000041101029220b450d2d200b41086a410029008c9e45370000200b41002900849e45370000200a41133602dc04200a41003602d804200a429080808080023702d004200a200b3602cc04200a4283808080303702c404200a20073602c00441031029220b450d2e200b41026a41002d008cc5453a0000200b41002f008ac5453b0000411110292207450d2f200741106a41002d00a49e453a0000200741086a410029009c9e45370000200741002900949e45370000200a41143602fc04200a41003602f804200a429180808090023702f004200a20073602ec04200a4283808080303702e404200a200b3602e00441031029220b450d30200b41026a41002d008cc5453a0000200b41002f008ac5453b0000411110292207450d31200741106a41002d00b59e453a0000200741086a41002900ad9e45370000200741002900a59e45370000200a411536029c05200a410036029805200a4291808080900237029005200a200736028c05200a42838080803037028405200a200b3602800541031029220b450d32200b41026a41002d008cc5453a0000200b41002f008ac5453b0000411610292207450d332007410e6a41002900c49e45370000200741086a41002900be9e45370000200741002900b69e45370000200a41163602bc05200a41003602b805200a4296808080e0023702b005200a20073602ac05200a4283808080303702a405200a200b3602a00541031029220b450d34200b41026a41002d008cc5453a0000200b41002f008ac5453b0000411210292207450d35200741106a41002f00dc9e453b0000200741086a41002900d49e45370000200741002900cc9e45370000200a41173602dc05200a41003602d805200a4292808080a0023702d005200a20073602cc05200a4283808080303702c405200a200b3602c005410310292207450d36200741026a41002d008cc5453a0000200741002f008ac5453b0000410b1029220b450d37200b41076a41002800e59e45360000200b41002900de9e45370000200a41183602fc05200a41003602f805200a428b808080b0013702f005200a200b3602ec05200a4283808080303702e405200a20073602e005410310292207450d38200741026a41002d008cc5453a0000200741002f008ac5453b000041101029220b450d39200b41086a41002900f19e45370000200b41002900e99e45370000200a411936029c06200a410036029806200a4290808080800237029006200a200b36028c06200a42838080803037028406200a2007360280062006410c6a200441086a280200360200200620033602002006410036021c20062005360218200620083602142006200429020037020420062001280200360210200241146a280200210d2002411c6a280200210e20064100360238200642013703304119200641306a1047410021030340200a20036a220b2802002104200b41086a2802002207200641306a1047024002402006280234220c200628023822086b2007490d002006280230210c0c010b200820076a22012008490d41200c4101742205200120012005491b22014100480d4102400240200c0d0020011029210c0c010b2006280230200c2001102a210c0b200c450d3c200620013602342006200c3602300b2006200820076a360238200c20086a2004200710f6041a200b410c6a2802002105200b41146a280200220c200641306a10470240024020062802342208200628023822016b200c490d00200628023021070c010b2001200c6a22072001490d4120084101742204200720072004491b22044100480d410240024020080d002004102921070c010b200628023020082004102a21070b2007450d3d2006200436023420062007360230200421080b20062001200c6a2204360238200720016a2005200c10f6041a02400240200b41186a2802004101460d000240024020082004460d002008210c0c010b200841016a220c2008490d4320084101742201200c200c2001491b220c4100480d430240024020080d00200c102921070c010b20072008200c102a21070b2007450d402006200c360234200620073602300b2006200441016a2208360238200720046a41013a00002006200b411c6a280200220b360228200641286a21040c010b0240024020082004460d002008210c0c010b200841016a220c2008490d4220084101742201200c200c2001491b220c4100480d420240024020080d00200c102921070c010b20072008200c102a21070b2007450d402006200c360234200620073602300b2006200441016a2208360238200720046a41023a00002006200b411c6a280200220b360228200641286a21040b0240200c20086b41034b0d00200841046a220b2008490d41200c4101742201200b200b2001491b220b4100480d4102400240200c0d00200b102921070c010b2007200c200b102a21070b2007450d402006200b360234200620073602302004280200210b0b2006200841046a360238200720086a200b360000200341206a220341a006470d000b200628023421070240411a200d200e2006280230220420062802382006101b220b41036a220841024b0d004100210c0240024020080e03000201000b4102210c0b41012101024020070d000c450b2004102e0c440b410410292208450d402009280200220c28020041016a220141014d0d00200c20013602002008200c36020002402007450d002004102e0b200228020421042002280200210120064100360238200642013703304100200641306a104720062802382103200628023421022006280230210c410a10342207450d410240024002400240200b20012004200c20032007410a2006101c41036a220441034b0d004101210120040e0402000001020b4198a4c2001058000b2006410936022c410121012006200741016a36022820072d0000220441014b0d01410421030240024020040e020100010b200641306a200641286a10fc02200628023022034104460d02200628023421050b410021010b2007102e2002450d43200c102e0c430b2007102e024020020d000c430b200c102e0c420b00000b41044104102c000b41034101102c000b41064101102c000b41204104102c000b41034101102c000b41034101102c000b41c0004104102c000b41034101102c000b410f4101102c000b4180014104102c000b41034101102c000b410f4101102c000b41034101102c000b41084101102c000b4180024104102c000b41034101102c000b410a4101102c000b41034101102c000b410a4101102c000b41034101102c000b410a4101102c000b41034101102c000b410b4101102c000b4180044104102c000b41034101102c000b410d4101102c000b41034101102c000b410c4101102c000b41034101102c000b410b4101102c000b41034101102c000b41154101102c000b41034101102c000b410a4101102c000b41034101102c000b41074101102c000b41034101102c000b41114101102c000b41034101102c000b410e4101102c000b4180084104102c000b41034101102c000b41104101102c000b41034101102c000b41104101102c000b41034101102c000b41114101102c000b41034101102c000b41114101102c000b41034101102c000b41164101102c000b41034101102c000b41124101102c000b41034101102c000b410b4101102c000b41034101102c000b41104101102c000b20014101102c000b20044101102c000b200c4101102c000b200c4101102c000b200b4101102c000b102d000b41044104102c000b410a4101102c000b200b101d200828020022072007280200417f6a3602000240200828020022072802000d002007280208101a200828020022072007280204417f6a360204200828020022072802040d002007102e0b2008102e4102210c0b200641086a2802002108200628021421072006280204210b024002400240024002400240024002400240200628021c22040d002006410c6a290200210f20010d04200341044b0d0320030e050203030301020b2000200436020420004100360200200041106a41003a0000200041086a200641206a29030037020002402008450d00200b102e0b20072007280200417f6a220836020020080d072007280208101a20072007280204417f6a22083602042008450d060c070b2000200b3602044100210b200041106a41003a00002000410c6a4100360200200041086a20083602000c040b2000200b360204200041106a20053a00002000410c6a200f3e0200200041086a20083602004100210b0c030b200041badfc300360204200041146a200f3e0200200041106a20083602002000410c6a200b360200200041086a41113602000c010b0240200c450d00200041dbdfc300360204200041146a200f3e0200200041106a20083602002000410c6a200b360200200041086a41103602000c010b200041cbdfc300360204200041146a200f3e0200200041106a20083602002000410c6a200b360200200041086a41103602000b4101210b0b2000200b36020020072007280200417f6a220836020020080d012007280208101a20072007280204417f6a220836020420080d010b2007102e0b4100210803400240200a20086a220741046a280200450d002007280200102e0b0240200741106a280200450d002007410c6a280200102e0b200841206a220841a006470d000b200a102e200928020022072007280200417f6a3602000240200928020022072802000d002007280208101a200928020022072007280204417f6a360204200928020022072802040d002007102e0b2009102e200641c0006a24000b810101017f230041c0006b220424002004200136020c2004200036020820042003360214200420023602102004412c6a41023602002004413c6a411b3602002004420237021c2004418098c6003602182004411c3602342004200441306a3602282004200441106a3602382004200441086a360230200441186a419498c600106a000bca0201067f230041b0016b22012400200141086a200010ed01024020012903284202510d000340200128026021022001280258210302400240200128025c22040d00200321050c010b2004210620032105034020052802ec0321052006417f6a22060d000b0340200320032f01064102746a41ec036a28020021032004417f6a22040d000b0b200120023602a801200141003602a001200141003602980120014200370390012001200536028c0120014100360288012001200336029c01200120032f01063602a40120014188016a10ee01200141086a200010ed0120012903284202520d000b0b02402000280204220341e08dc000460d00200328020021042003102e2004450d00200428020021052004102e2005450d00024020052802002203450d0003402005102e2003210520032802002204210320040d000b0b2005102e0b200141b0016a24000b911208057f017e107f047e017f017e0a7f047e230041800d6b22022400024020002802000d002000417f360200200128020821032001280200210402400240200128020422050d00200421010c010b2005210620042101034020012802880b21012006417f6a22060d000b0340200420042f01064102746a41880b6a28020021042005417f6a22050d000b0b200241246a20042f0106360200200241086a41186a4100360200200241086a41146a20043602002002200336022820024100360218200242003703102002200136020c2002410036020820024180026a200241086a10ed01024020022903a00222074202510d00200041046a21082000410c6a2109200241dd026a210a200241bd026a210b200241a00a6a41146a210c200241a00a6a41206a210d20024180026a4104722101200241fd026a210e200241c8026a210f200241b0026a211020024180026a41286a21110340200241d0006a41086a220420024180026a41086a2212290300370300200241d0006a41106a220520024180026a41106a2213290300370300200241d0006a41186a220320024180026a41186a2214290300370300200241306a41086a2215200a41086a290000370300200241306a41106a2216200a41106a290000370300200241306a41186a2217200a41186a29000037030020022002290380023703502002200a290000370330200f29030021182010290300211920022903c002211a20022903a802211b20022d00dc02211c20022903b802211d20022802d002210620022802d402211e20022802d802211f2002412c6a41026a200e41026a2d000022203a00002002200e2f000022213b012c200241f8006a41086a22222015290300370300200241f8006a41106a22232016290300370300200241f8006a41186a22242017290300370300200241f4006a41026a222520203a000020022002290330370378200220213b017420024198016a41186a2221200329030037030020024198016a41106a2226200529030037030020024198016a41086a222720042903003703002002200229035037039801024002400240024002402008280200221541e08dc000460d00200028020821170c010b200241a00a6a410041e00210f5041a20024180026a410041a00810f5041a41880b10292215450d0141002117201541003b010620154100360200201541086a200241a00a6a41e00210f6041a201541e8026a20024180026a41a00810f6041a20004100360208200020153602040b034020152f01062220410574211641002104410021050240034020162004460d0120024198016a201520046a41086a412010f8042203450d04200441206a2104200541016a21052003417f4a0d000b2005417f6a21200b02402017450d002017417f6a2117201520204102746a41880b6a28020021150c010b0b200241d0016a41186a20212903002228370300200241d0016a41106a20262903002229370300200241d0016a41086a2027290300222a3703002002200229039801222b3703d001200c202b370200200c41086a202a370200200c41106a2029370200200c41186a2028370200200220093602b00a200220203602ac0a200220083602a80a200220153602a40a200241003602a00a20112018370300201320193703002002201a3703a0022002201b370388022002201c3a00bc022002201f3602b8022002201e3602b402200220063602b0022002201d370398022002200737038002200b2002290378370000200b41086a2022290300370000200b41106a2023290300370000200b41186a2024290300370000200a20022f01743b0000200a41026a20252d00003a0000200241a00a6a20024180026a104f1a0c020b41880b4108102c000b2015200541e0006c6a221741f0026a22042004290300201b20075022041b370300201741f8026a22052005290300201920041b370300201741e8026a22052005290300200720041b370300200241a00a6a41186a22032024290300370300200241a00a6a41106a22152023290300370300200241a00a6a41086a22162022290300370300200220022903783703a00a201741a4036a22052d000021202014201741bd036a22222900003703002013201741b5036a22232900003703002012201741ad036a22132900003703002002201741a5036a2224290000370380022027200241a00a6a20024180026a201c41ff0171410146221c1b220441086a2900003703002026200441106a2900003703002021200441186a2900003703002002200429000037039801200541012020201c1b3a0000202420022903980137000020132027290300370000202320262903003700002022202129030037000020174188036a2204201a2004290300201da722041b37030020174190036a22052018200529030020041b37030020174180036a2205201d200529030020041b37030002400240201e0d00200621040c010b201e210520062104034020042802ec0321042005417f6a22050d000b0340200620062f01064102746a41ec036a2802002106201e417f6a221e0d000b0b20062f010621052002201f3602b801200220053602b401200241003602b001200220063602ac01200241003602a801200242003703a0012002200436029c01200241003602980120024180026a20024198016a10ef0102402002280280024101470d0020174198036a211e0340200241a00a6a41286a200141286a280200360200200d200141206a2902003703002003200141186a22042902003703002015200141106a22052902003703002016200141086a2206290200370300200220012902003703a00a200241d0016a41186a2004290000370300200241d0016a41106a2005290000370300200241d0016a41086a2006290000370300200220012900003703d001200241f0016a41086a200d41086a2802003602002002200d2902003703f001200241c0016a201e200241d0016a200241f0016a10f501024020022802c001450d0020022802c4012204450d0020022802c801450d002004102e0b20024180026a20024198016a10ef012002280280024101460d000b0b20024198016a10ee010b20024180026a200241086a10ed0120022903a00222074202520d000b0b200241086a10542000200028020041016a360200200241800d6a24000f0b41aed9c100411020024180026a41c0d9c1001053000b8a0303027f017e037f230041c0006b22052400024002400240200241ff0171417e6a220641024b0d000240024020060e03000201000b200541106a2001107b2005290310200358200541186a290300220720045820072004511b0d010c020b200541206a2001107b2005290320200356200541286a290300220720045620072004511b0d010b200541306a2001107c0240200528023822010d0002402005280234450d002005280230102e0b410021010c020b200541086a41b0f3c200410d107d200528020c410020052802081b210820014105742106200528023421092005280230220a2101024002400240034002402008200141106a2802004f0d002001290300200358200141086a290300220720045820072004511b0d002001411c6a2d000020027141ff0171200241ff0171460d020b200141206a2101200641606a22060d000b4100210120090d010c020b41b88bc00021012009450d010b200a102e0b413121060c010b41928bc0002101412621060b2000200636020420002001360200200541c0006a24000b890602087f047e230041d00b6b220424000240024020002802000d002000417f360200200441286a41186a200141186a290000370300200441286a41106a200141106a290000370300200441286a41086a200141086a29000037030020042001290000370328024002402000280204220541e08dc000460d00200041086a28020021060c010b41002106200441f0086a410041e00210f5041a200441d0006a410041a00810f5041a41880b10292205450d02200541003b010620054100360200200541086a200441f0086a41e00210f6041a200541e8026a200441d0006a41a00810f6041a200041086a4100360200200020053602040b200041046a210702400240034020052f010622084105742109410021014100210a0240034020092001460d01200441286a200520016a41086a412010f804220b450d03200141206a2101200a41016a210a200b417f4a0d000b200a417f6a21080b02402006450d002006417f6a2106200520084102746a41880b6a28020021050c010b0b200441086a41186a200441286a41186a290300220c370300200441086a41106a200441286a41106a290300220d370300200441086a41086a200441286a41086a290300220e37030020042004290328220f3703082004418c096a200e37020020044194096a200d3702002004419c096a200c37020020042000410c6a36028009200420083602fc08200420073602f808200420053602f408200441003602f0082004200f3702840920044184016a42003702002004418c016a41003a0000200441e08dc000360280012004420037036820044200370350200441f0086a200441d0006a104f21010c010b200441e8006a4200370300200441e4006a41e08dc000360200200441003602702004410036026020044200370358200441e08dc000360254200441003602502005200a41e0006c6a41e8026a2101200441d0006a10ee010b200141106a200337030020012002370308200142013703002000200028020041016a360200200441d00b6a24000f0b41aed9c1004110200441d0006a41c0d9c1001053000b41880b4108102c000b6802017f037e230041306b22012400200029020821022000290210210320002902002104200141146a4100360200200141c8ecc50036021020014201370204200120043703182001200141186a36020020012003370328200120023703202001200141206a106a000bc40101057f230041306b220124002000410c6a28020021022000280204210302400240200041086a28020022040d00200321000c010b2004210520032100034020002802880b21002005417f6a22050d000b0340200320032f01064102746a41880b6a28020021032004417f6a22040d000b0b200141246a20032f0106360200200141206a41003602002001411c6a20033602002001200236022820014100360218200142003703102001200036020c20014100360208200141086a1054200141306a24000bf61c03027f027e087f23004180046b2207240020072004370310200720033703082007200536021c02400240024002400240200128022c200128023c22082802b801460d002005420020052903082209200841386a2903007d220a200a20095622081b37030820080d01200741d8006a200241004101105b200741fc006a280200210b200741f8006a280200210c20072d0060220841037122054103460d0220050e03030203030b2000418c84c00036020420004101360200200041086a41293602002000410c6a2006290200370200200041146a200641086a2802003602000c030b200041b584c00036020420004101360200200041086a41233602002000410c6a2006290200370200200041146a200641086a2802003602000c020b200041d884c00036020420004101360200200041086a41193602002000410c6a2006290200370200200041146a200641086a28020036020020080d01200b450d01200c102e0c010b20074180016a2802002105200741386a200141e4006a290000370300200741306a200141dc006a290000370300200741206a41086a200141d4006a2900003703002007200129004c3703204100210d024002400240024002400240200841024b0d00024020080e03000102000b2005417f4c0d020240024020050d004101210d0c010b20051029220d450d04200d200c200510f6041a0b200b450d00200c102e0b200741086a41086a2903002104200729030821030b20074190016a4100360200200741d8006a41286a419c83c000360200200741fc006a200141146a220e360200200741f4006a4200370200200741d8006a41186a41e08dc000360200200741d8006a41106a2005360200200741d8006a410c6a2005360200200741ac016a200241086a290000370200200741b4016a200241106a290000370200200741bc016a200241186a29000037020020074208370388012007410036026c2007200d360260200720022900003702a4012007200128024436029c012007200129023c370294012007200128022c41016a3602840120012903002109200720012802483602a0012007200937035820074198026a200741206a41086a290300370300200741f8016a41286a200741206a41106a290300370300200741a8026a200741206a41186a290300370300200741f8016a41146a200641086a28020036020020072002360280022007200729032037039002200720062902003702840220072007411c6a3602fc012007200741086a3602f801200741f8016a41186a210f200741f8016a410c6a2110024002400240024002400240200320048450450d00410021110c010b2007200728021c4100200f200220032004200741d8006a1050200728020022060d01200728026c211120072802800221020b201141016a220641004c0d062007200636026c200741f0006a2106200741f4006a280200210c024002400240024003402006280200220b41086a2105200b2f010622124105742106410021080240024003402006450d0120022005412010f804220d450d02200641606a2106200841016a2108200541206a2105200d417f4a0d000b2008417f6a21120b200c450d02200c417f6a210c200b20124102746a41880b6a21060c010b0b200741a8036a2205200b200841e0006c6a220641ad036a290000370300200741b0036a2208200641b5036a290000370300200741b8036a220d200641bd036a2900003703002007200641a5036a2900003703a003200641a4036a2d00004101470d00200741b9026a2005290300370000200741c1026a2008290300370000200741c9026a200d290300370000200741013a00b002200720072903a0033700b1022007201136026c0c010b200741b0026a200728027c20022007280280012802101103002007200728026c417f6a36026c20072d00b0024101470d010b200741d8026a41186a200741c9026a290000370300200741d8026a41106a200741c1026a290000370300200741d8026a41086a200741b9026a290000370300200720072900b1023703d802200741a0036a200741d8026a200728029c012802001051024020072802a0034101470d0020072902a4032103200741ec016a2010290200370200200741f4016a201041086a280200360200200720033702e401200741013602e001200741e0016a41047221060c040b200741e0036a41186a2205200741a0036a410472220641186a2802002208360200200741f8026a41106a200641086a290200370300200741f8026a41186a220d200641106a29020037030020074198036a2008360200200741043602fc02200741ada4c5003602f802200720062902003703800320072802980121062005200f41186a2900002203370300200741e0036a41106a200f41106a2900002204370300200741e0036a41086a2205200f41086a2900002209370300200741c8036a2009370300200741d0036a2004370300200741d8036a20033703002007200f29000022033703e003200720033703c00320072802f801220841086a29030021032007200741d8006a3602b803200829030021042007290358210920072802a0012108200720033703a803200720043703a003200720083602bc03200720093703b0032005201041086a280200360200200720102902003703e003200741e0016a2006200741f8026a200741a0036a200741e0036a20072802fc0128020010520240200d280200450d002007418c036a280200102e0b200741d8016a200741ec016a280200360200200741ce016a200741f3016a2d00003a0000200720072902e4013703d001200720072f00f1013b01cc01200741f0016a2d0000210520072802e0014101470d01200741f4016a28020021060c040b200741e0016a41086a420037030041002105200741e0016a41106a220841003a000020074280808080103703e001200741e0016a41047221060240200741f8016a41106a280200450d00200728028402102e20082d000021050b200741d0016a41086a200641086a280200360200200741ce016a200741f3016a2d00003a0000200720072f00f1013b01cc01200720062902003703d0010b200741c8006a41086a2202200741d0016a41086a280200360200200741c4006a41026a2212200741cc016a41026a2d00003a0000200720072903d001370348200720072f01cc013b01442007280290012108200728028c01210c200728028801210b200728027821102007280274210d2007280270210602402007280260220f450d002007280264450d00200f102e0b200741a0036a41086a2002280200360200200741f8016a41026a20122d00003a0000200720072903483703a003200720072f01443b01f801200541ff0171450d03200020072903a003370204200020072f01f8013b0011200041106a20053a00002000410c6a200741a0036a41086a280200360200200041136a200741fa016a2d00003a000002402008450d00200841b0016c210141002105034002400240200b20056a22082d0000220241014b0d000240024020020e020001000b0240200841086a280200450d00200841046a280200102e0b200841106a2d00004105490d02200841386a280200450d02200841346a280200102e0c020b200841286a102f0c010b200841e8006a280200450d00200841e4006a280200102e0b2001200541b0016a2205470d000b0b0240200c450d00200b102e0b02400240200d0d00200621050c010b200d210820062105034020052802880b21052008417f6a22080d000b0340200620062f01064102746a41880b6a2802002106200d417f6a220d0d000b0b200741f4006a20062f0106360200200741f0006a4100360200200741ec006a20063602002007201036027820074100360268200742003703602007200536025c20074100360258200741d8006a10540c070b200741e0016a41086a2007280204360200200741ec016a2010290200370200200741f4016a201041086a280200360200200720063602e401200741013602e001200741e0016a41047221060b200741d0016a41086a200641086a280200360200200741ce016a2006410f6a2d00003a0000200720062902003703d001200720062f000d3b01cc01200741f0016a2d00002105200741f4016a28020021060b200020072903d001370204200020072f01cc013b001120004101360200200041106a20053a0000200041146a20063602002000410c6a200741d8016a280200360200200041136a200741ce016a2d00003a0000024020072802602206450d002007280264450d002006102e0b200741d8006a41186a28020021062007280278210d02400240200728027422050d00200621080c010b2005210020062108034020082802880b21082000417f6a22000d000b0340200620062f01064102746a41880b6a28020021062005417f6a22050d000b0b200741bc036a20062f010636020041002105200741a0036a41186a4100360200200741b4036a20063602002007200d3602c003200741003602b003200742003703a803200720083602a403200741003602a003200741a0036a105402402007280290012206450d002007280288012100200641b0016c210d034002400240200020056a22062d0000220841014b0d000240024020080e020001000b0240200641086a280200450d00200641046a280200102e0b200641106a2d00004105490d02200641386a280200450d02200641346a280200102e0c020b200641286a102f0c010b200641e8006a280200450d00200641e4006a280200102e0b200d200541b0016a2205470d000b0b200728028c01450d05200728028801102e0c050b200720103602602007200d36025c20072006360258200e200741d8006a10552007200b200841b0016c6a3602642007200b3602602007200c36025c2007200b360258200141306a200741d8006a10282000410c6a200741a8036a280200360200200020072903a003370204200041106a41003a0000200020072f01f8013b0011200041136a200741fa016a2d00003a00000c030b1032000b20054101102c000b41e3d7c1004118200741f8026a41fcd7c1001053000b200041003602000b20074180046a24000bef1704057f027e0b7f077e23004180036b22042400200441e0006a200110af010240024020042d00602205417f6a41ff017141024f0d00200041003a0000200041086a200441e0006a41d80010f6041a0c010b200441b8016a41086a2206200441e0006a413c6a290200370300200441b8016a41106a2207200441e0006a41c4006a290200370300200441b8016a41186a2208200441e0006a41cc006a2902003703002004200441e0006a41346a2902003703b801200441e0006a41106a2903002109200441e0006a41086a290300210a200441e0006a41306a280200210b200441e0006a412c6a280200210c200441e0006a41246a280200210d200441e0006a41206a280200210e200441fc006a280200210f200441e0006a41186a2802002110200441e0006a41d4006a2802002111200441e0006a41286a2802002112200441d8006a41b0f3c200410d107d0240024002400240024002400240024002400240024041004100200428025c410020042802581b221320026b2202200220134b1b220220126b2214201420024b1b2215450d00411410292202450d02200241002900d88c40370000200241106a41002800e88c40360000200241086a41002900e08c4037000020044294808080c0023702fc01200420023602f8012001200441f8016a104a20042802fc012102200441c0006a20042802f8012206200428028002106e200441c0006a41106a2903004200200428024022141b21162004290348420020141b211702402002450d002006102e0b200441306a2017201642e807420010fc044200200dad2218200429033022197d221a201a2018564200200441306a41086a2903002018201954ad7c7d22184200522018501b22021b22194200201820021b221884500d0302400240024002402017429080e983b1de165441002016501b0d00200441186a201942028620184202862019423e88842015ad420010fb04200441286a2001410842002017201742f0ff96fccea1697c2218200a200a201856200920162018201754ad7c427f7c22185620092018511b22021b22192004290318221a2019201a542018200920021b2219200441186a41086a29030022185420192018511b22021b221b7d221c201c20175620162019201820021b22197d2017201b54ad7d221720165620172016511b22141b4200201720141b105620042802280d010240024020020d002003450d010b200441f8016a2001201b20194108107a20042802f8014101460d0a200441f8016a41106a2903002119200441f8016a41086a2214290300211720144200370300200442003703f80141c28cc0004116200441f8016a1003200441d0026a41086a22072014290300370300200420042903f8013703d0022004200441d0026a109701200441106a29030021162004290308211b2004280200210620144200370300200442003703f80141c28cc0004116200441f8016a100320072014290300370300200420042903f8013703d002200442002016420020061b221620197d201b420020061b2219201754ad7d221b201920177d2217201956201b201656201b2016511b22141b3703800220044200201720141b3703f801200441d0026a4110200441f8016a411010040b20020d0120030d03200041003a0008200041023a0000200041186a2009370000200041106a200a370000200041386a200b360000200041346a200c360000200041306a20123600002000412c6a200d360000200041286a200e360000200041246a200f360000200041206a20103600002000413c6a20042903b801370000200041c4006a200441c0016a290300370000200041cc006a200441b8016a41106a290300370000200041d4006a200441b8016a41186a290300370000200041dc006a2011360000200541037122004103460d0520000e030f05050f0b411710292202450d07200241002900b0a5433700002002410f6a41002900bfa543370000200241086a41002900b8a54337000020044297808080f0023702fc01200420023602f8012001200441f8016a104a20042802fc012102200428028002211220042802f8012101200441f8016a41186a220d4200370300200441f8016a41106a22034200370300200441f8016a41086a22134200370300200442003703f80120012012200441f8016a1000200441d0026a41186a200d290300370300200441d0026a41106a2003290300370300200441d0026a41086a2013290300370300200420042903f8013703d002200441d0026a4120100602402002450d002001102e0b2010200e1007200041023a0008200041013a00000c010b200441003602f8012010200e200441f8016a100a211420042802f8012213417f460d08200441d0026a41186a200441b8016a41186a290300370300200441d0026a41106a200441b8016a41106a290300370300200441d0026a41086a200441b8016a41086a290300370300200420042903b8013703d002200441003602f802200442013703f00220142013200441f0026a10b0010240024020042802f402220320042802f802220d6b4120490d00200d41206a211220042802f00221020c010b200d41206a2212200d490d0b20034101742202201220122002491b220b4100480d0b0240024020030d00200b102921020c010b20042802f0022003200b102a21020b2002450d0a2004200b3602f402200420023602f002200b21030b200420123602f8022002200d6a220d20042903d002370000200d41086a200441d0026a41086a290300370000200d41106a200441d0026a41106a290300370000200d41186a200441d0026a41186a290300370000200441f8016a41186a220d4200370300200441f8016a41106a220b4200370300200441f8016a41086a220c4200370300200442003703f80120022012200441f8016a1000200441d8016a41186a2212200d290300370300200441d8016a41106a220d200b290300370300200441d8016a41086a220b200c290300370300200420042903f8013703d80102402003450d002002102e0b20044191026a201229030037000020044189026a200d29030037000020044181026a200b290300370000200420042903d8013700f901200441013a00f8012001200441f8016a10b1012010200e1007200041013a0000200041086a200441f8016a41d80010f6041a2013450d002014102e0b200f450d0a2010102e0c0a0b200441a8026a200b360200200441a4026a200c360200200441a0026a20133602002004419c026a200d36020020044198026a200e36020020044194026a200f360200200441f8016a41186a2010360200200441ac026a20042903b801370200200441b4026a200441b8016a41086a290300370200200441bc026a200441b8016a41106a290300370200200441c4026a200441b8016a41186a290300370200200441f8016a41106a200920187d200a201a54ad7d370300200441003a00f8012004200a201a7d370380022001200441f8016a10b101200041023a0000200041086a200441f8016a41d80010f6041a0c090b200041003a0008200041003a0000200041186a2009370000200041106a200a370000200041386a200b360000200041346a200c360000200041306a20123600002000412c6a200d360000200041286a200e360000200041246a200f360000200041206a20103600002000413c6a20042903b801370000200041c4006a2006290300370000200041cc006a2007290300370000200041d4006a2008290300370000200041dc006a20113600000c080b200f450d090c080b41144101102c000b200041003a0008200041003a0000200041186a2009370000200041106a200a370000200041386a200b360000200041346a200c360000200041306a20123600002000412c6a200d360000200041286a200e360000200041246a200f360000200041206a20103600002000413c6a20042903b801370000200041c4006a200441c0016a290300370000200041cc006a200441b8016a41106a290300370000200041d4006a200441b8016a41186a290300370000200041dc006a20113600000c050b41174101102c000b200420042902fc013703d00241fbecc00041fe00200441d0026a41fcedc0001053000b41c0e6c5004138109b01000b200b4101102c000b102d000b0240200541037122004103460d0020000e03020000020b200f450d010b2010102e0b20044180036a24000bde0d03047f017e027f230041106b2202240020024100360208200242013703000240024002400240024002400240024002400240024002400240024002402001280200220341044b0d000240024002400240024020030e050001020304000b410110292203450d05200242818080801037020420022003360200200341013a0000200128020421042001410c6a28020022032002104702402003450d002004200341286c6a2105034020042002104a200441206a29030021060240024020022802042207200228020822036b4108490d00200228020021070c010b200341086a22082003490d1520074101742203200820082003491b22034100480d150240024020070d002003102921070c010b200228020020072003102a21070b2007450d092002200336020420022007360200200228020821030b2002200341086a360208200720036a20063700002005200441286a2204470d000b0b200141106a28020021070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d1320044101742203200820082003491b22034100480d130240024020040d002003102921040c010b200228020020042003102a21040b2004450d082002200336020420022004360200200228020821030b2002200341046a360208200420036a20073600000c040b410110292203450d07200242818080801037020420022003360200200341023a0000200128020421070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d1220044101742205200820082005491b22084100480d120240024020040d002008102921040c010b200228020020042008102a21040b2004450d0920022008360204200220043602000b2002200341046a360208200420036a200736000020012802082104200141106a28020022032002104702402003450d002004200341286c6a2105034020042002104a200441206a29030021060240024020022802042207200228020822036b4108490d00200228020021070c010b200341086a22082003490d1420074101742203200820082003491b22034100480d140240024020070d002003102921070c010b200228020020072003102a21070b2007450d0c2002200336020420022007360200200228020821030b2002200341086a360208200720036a20063700002005200441286a2204470d000b0b200141146a28020021070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d1220044101742203200820082003491b22034100480d120240024020040d002003102921040c010b200228020020042003102a21040b2004450d0b2002200336020420022004360200200228020821030b2002200341046a360208200420036a20073600000c030b410110292203450d0a200242818080801037020420022003360200200341033a0000200141086a29030021060240024020022802042207200228020822036b4108490d00200341086a2104200228020021070c010b200341086a22042003490d1120074101742208200420042008491b22084100480d110240024020070d002008102921070c010b200228020020072008102a21070b2007450d0c20022008360204200220073602000b20022004360208200720036a20063700000c020b410110292203450d0b200242818080801037020420022003360200200341043a0000200128020421070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d1020044101742201200820082001491b22084100480d100240024020040d002008102921040c010b200228020020042008102a21040b2004450d0d20022008360204200220043602000b2002200341046a360208200420036a20073600000c010b410110292203450d0c200242818080801037020420022003360200200341053a0000200128020421080240024020022802042207200228020822036b4104490d00200341046a2104200228020021070c010b200341046a22042003490d0f20074101742201200420042001491b22014100480d0f0240024020070d002001102921070c010b200228020020072001102a21070b2007450d0e20022001360204200220073602000b20022004360208200720036a20083600000b20002002290300370200200041086a200241086a280200360200200241106a24000f0b41014101102c000b20034101102c000b20034101102c000b41014101102c000b20084101102c000b20034101102c000b20034101102c000b41014101102c000b20084101102c000b41014101102c000b20084101102c000b41014101102c000b20014101102c000b102d000bb01405167f017e017f027e037f230041206b220224000240024020014115490d0002402001410176220341ffffff3f712003470d0020034105742204417f4c0d0041012105024002402004450d00200410292205450d010b200041606a2106200041a07f6a210741042108410021094100210a2001210b034002400240200b220c417f6a220d0d004101210e4100210b0c010b0240024002400240024002402000200d4105746a200c410574220f20006a41406a412010f8044100480d004102200c6b210d2007200f6a21044101210e03400240200d200e6a4101470d004100210b200c210e0c080b200e41016a210e200441206a2004412010f8042110200441606a21042010417f4a0d000b200c200e6b210d0c010b2007200f6a2104024003400240200d4101470d004100210d0c020b200d417f6a210d200441206a2004412010f8042110200441606a210420104100480d000b0b200c200d490d01200c20014b0d03200c200d6b220e4101762211450d002006200f6a21042000200d4105746a21100340200241186a220f201041186a2212290000370300200241106a2213201041106a2214290000370300200241086a2215201041086a221629000037030020022010290000370300200441086a22172900002118200441106a2219290000211a200441186a220b290000211b201020042900003700002012201b3700002014201a37000020162018370000200b200f290300370000201920132903003700002017201529030037000020042002290300370000200441606a2104201041206a21102011417f6a22110d000b0b0240200d0d00200d210b0c050b0240200e41094d0d00200d210b0c050b200c20014b0d01200c200d6b21112000200d4105746a210f0340200c200d417f6a220b490d040240200c200b6b220e4102490d002000200d4105746a22042000200b4105746a220d412010f804417f4a0d00200d2900002118200d2004290000370000200241186a2215200d41186a2210290000370300200241106a2216200d41106a2212290000370300200241086a2217200d41086a22132900003703002013200441086a2900003700002012200441106a2900003700002010200441186a29000037000020022018370300410121140240200e4103490d00200d41c0006a2002412010f804417f4a0d0041022110200f210402400340200441186a200441386a290000370000200441106a200441306a290000370000200441086a200441286a2900003700002004200441206a221229000037000020112010460d01200441c0006a21132010211420122104201041016a211020132002412010f804417f4a0d020c000b0b201021140b200d20144105746a22042002290300370000200441186a2015290300370000200441106a2016290300370000200441086a20172903003700000b200b450d05200f41606a210f201141016a2111200b210d200e410a4f0d050c000b0b200d200c1035000b200c200d417f6a220b490d010b200c2001105e000b200b200c1035000b0240024002402009200a470d0002400240200941016a22042009490d0020094101742210200420042010491b220441ffffffff01712004470d002004410374221041004e0d010b102d000b0240024020090d002010102921080c010b200820094103742010102a21080b2008450d01200421090b2008200a4103746a2204200e3602042004200b360200200a41016a2215210a20154102490d0103400240024002400240200820152213417f6a22154103746a2204280200450d00201341037420086a221141746a280200220e200428020422104d0d004102210a201341024d0d0620082013417d6a22044103746a280204220d2010200e6a4d0d014103210a201341034d0d06201141646a280200200d200e6a4d0d012013210a0c060b20134103490d012004280204211020082013417d6a22044103746a280204210d0b200d2010490d010b2013417e6a21040b0240024002400240024002402013200441016a221c4d0d00201320044d0d01200820044103746a2216280204221d20162802006a22042008201c4103746a22172802002219490d02200420014b0d03201641046a211e200020194105746a22122017280204221441057422106a210e2004410574210d200420196b220a20146b220420144f0d042005200e2004410574221010f604220f20106a21110240024020144101480d00200441014e0d010b200e2104200f21100c060b2006200d6a210d200e21040340200d200441606a220e201141606a220a200a200e412010f804410048220c1b2210290000370000200d41186a201041186a290000370000200d41106a201041106a290000370000200d41086a201041086a2900003700002011200a200c1b211102402012200e2004200c1b2204490d00200f21100c070b200d41606a210d200f2110200f2011490d000c060b0b41f484c000201c20131038000b41f484c000200420131038000b201920041035000b20042001105e000b20052012201010f604220f20106a21110240024020144101480d00200a20144a0d010b20122104200f21100c010b2000200d6a210c200f21102012210403402004200e2010200e2010412010f804410048220a1b220d290000370000200441186a200d41186a290000370000200441106a200d41106a290000370000200441086a200d41086a2900003700002010201041206a200a1b2110200441206a2104200e41206a200e200a1b220e200c4f0d01201120104b0d000b0b20042010201120106b41607110f6041a201e201d20146a360200201620193602002017201741086a201c417f7320136a41037410f7041a2015210a201541014d0d020c000b0b20104104102c000b200b0d000b02402009450d002008102e0b2003450d032005102e0c030b20044101102c000b1032000b20014102490d002001417f6a2110200141057420006a41206a210c410121110340024002400240024020102204417f6a221020014b0d00200120106b220d4102490d03200020044105746a2204200020104105746a220a412010f804417f4a0d03200a2900002118200a2004290000370000200241186a2212200a41186a220e290000370300200241106a2213200a41106a220f290000370300200241086a2214200a41086a22082900003703002008200441086a290000370000200f200441106a290000370000200e200441186a2900003700002002201837030041012104200d4103490d02200a41c0006a2002412010f804417f4a0d024100210f200c21040340200441406a220d200441606a220e290000370000200d41186a200e41186a290000370000200d41106a200e41106a290000370000200d41086a200e41086a2900003700002011200f220d460d02200d417f6a210f20042002412010f804210e200441206a2104200e417f4a0d020c000b0b201020011035000b4102200d6b21040b200a20044105746a22042002290300370000200441186a2012290300370000200441106a2013290300370000200441086a20142903003700000b200c41606a210c2011417f6a211120100d000b0b200241206a24000b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420237020c200241d4eec500360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41e4eec500106a000bdd2003167f037e067f230041c0026b220524000240024020014115490d004101210641012107024002400240034020012108200021092006200771210a024002400240024002400240034002400240024002402004450d00024020064101710d002000200110602004417f6a21040b2001410276220b41036c210c200b410174210d4100210e024020014132490d00200b200b417f6a220e2000200b4105746a2000200e4105746a412010f804220f41004822101b2211200b41016a2212200e200b20101b220b200020124105746a2000200b4105746a412010f80441004822121b220b2000200b4105746a200020114105746a412010f80422114100481b210b200d200d417f6a220e2000200d4105746a2000200e4105746a412010f804221341004822141b2215200d4101722216200e200d20141b220d200020164105746a2000200d4105746a412010f80422144100481b220d2000200d4105746a200020154105746a412010f80422154100481b210d200c200c417f6a220e2000200c4105746a2000200e4105746a412010f804221641004822171b2218200c41016a2219200e200c20171b220c200020194105746a2000200c4105746a412010f804220e4100481b220c2000200c4105746a200020184105746a412010f80422174100481b210c4102410120101b200f411f7620121b2011411f766a2013411f766a2014411f766a2015411f766a2016411f766a200e411f766a2017411f766a210e0b2000200d4105746a2000200b4105746a412010f8042210411f76200e6a2000200c4105746a2000200b200d201041004822101b220f4105746a412010f8042211411f766a210e2000200c200f20114100481b220c4105746a2000200d200b20101b221a4105746a412010f804417f4c0d01200c211a0c020b2000200110610c0f0b200e41016a220e410c490d0002402001410176220c450d00200020014105746a41606a210b2000210d0340200541206a41186a220e200d41186a2210290000370300200541206a41106a220f200d41106a2211290000370300200541206a41086a2212200d41086a22132900003703002005200d290000370320200b41086a2214290000211b200b41106a2215290000211c200b41186a2216290000211d200d200b2900003700002010201d3700002011201c3700002013201b3700002016200e2903003700002015200f29030037000020142012290300370000200b2005290320370000200b41606a210b200d41206a210d200c417f6a220c0d000b0b2001201a417f736a211a4101210b0c010b200e45210b0b0240200a417f73200b45724101710d002000200110620d0d0b2003450d02201a20014f0d01024020032000201a4105746a220b412010f80441004e0d0020002109200121080c040b200541206a41186a2213200041186a220f290000370300200541206a41106a2214200041106a2211290000370300200541206a41086a2215200041086a221229000037030020052000290000370320200b41086a220d290000211b200b41106a220c290000211c200b41186a220e290000211d2000200b290000370000200f201d3700002011201c3700002012201b370000200e2013290300370000200c2014290300370000200d2015290300370000200b2005290320370000200541c0016a41186a2218200f290000370300200541c0016a41106a22192011290000370300200541c0016a41086a221a2012290000370300200520002900003703c001200041606a2116200041206a21174100210d2001210c03400240200d200c417f6a220e4f0d002017200d4105746a210b0340200541c0016a200b412010f804417f4c0d01200b41206a210b200e200d41016a220d470d000b200e210d0b2016200c4105746a210b02400340200d200c417f6a220c4f0d01200541c0016a200b412010f804210e200b41606a2210210b200e4100480d000b20132017200d4105746a220b41186a220e2900003703002014200b41106a221e2900003703002015200b41086a22072900003703002005200b290000370320201041286a221f290000211b201041306a2220290000211c201041386a2221290000211d200b201041206a2210290000370000200e201d370000201e201c3700002007201b3700002021201329030037000020202014290300370000201f201529030037000020102005290320370000200d41016a210d0c010b0b200020052903c001370000200f2018290300370000201120192903003700002012201a29030037000002402001200d41016a220b490d002000200b4105746a21002001200b6b220141154f0d010c0c0b0b200b20011035000b419086c000201a20011038000b2008450d010b201a20084f0d01200541206a41186a2217200941186a221f290000370300200541206a41106a2218200941106a2220290000370300200541206a41086a2219200941086a2221290000370300200520092900003703202009201a4105746a220b41086a220d290000211b200b41106a220c290000211c200b41186a220e290000211d2009200b290000370000201f201d3700002020201c3700002021201b370000200e2017290300370000200c2018290300370000200d2019290300370000200b2005290320370000200541186a2206201f290000370300200541106a220a2020290000370300200541086a2222202129000037030020052009290000370300200941206a21014100211e2008417f6a220e450d022001210b0340200b2005412010f80441004e0d03200b41206a210b200e201e41016a221e470d000b200e211e0c020b41d885c000410041001038000b41e885c000201a20081038000b200920084105746a210d200e210c02400340200d2100200c220b201e4d22070d01200b417f6a210c200041606a220d2005412010f804417f4a0d000b0b0240200b201e490d00200e200b490d02418001211541002110410021134100210e4100211241800121162001201e4105746a2223210103400240200020016b220b419fc0004b221a0d00200b410576220b41807f6a200b20132010492012200e49220d72220c1b210b0240200c450d002016200b200d1b2116200b2015200d1b21150c010b200b200b41017622166b21150b02402012200e470d00024020160d00200541c0006a220e21120c010b4100210b200541c0006a2212210e2001210d0340200e200b3a0000200e200d2005412010f804417f73411f766a210e200d41206a210d2016200b41016a220b470d000b0b024020132010470d00024020150d00200541c0016a221021130c010b200041606a210b4100210d200541c0016a2213211003402010200d3a00002010200b2005412010f804411f766a2110200b41606a210b2015200d41016a220d470d000b0b0240201020136b220b200e20126b220d200d200b4b1b2214450d002017200120122d00004105746a220b41186a2900003703002018200b41106a2900003703002019200b41086a2900003703002005200b290000370320200120122d00004105746a220b200020132d0000417f734105746a220d290000370000200b41186a200d41186a290000370000200b41106a200d41106a290000370000200b41086a200d41086a290000370000024020144101460d004100210b034020002013200b6a220f2d0000417f734105746a220d20012012200b6a41016a22112d00004105746a220c290000370000200d41186a200c41186a290000370000200d41106a200c41106a290000370000200d41086a200c41086a290000370000200120112d00004105746a220d2000200f41016a2d0000417f734105746a220c290000370000200d41186a200c41186a290000370000200d41106a200c41106a290000370000200d41086a200c41086a290000370000200b41026a210d200b41016a220c210b200d2014490d000b2013200c6a21132012200c6a21120b200020132d0000417f734105746a220b2005290320370000200b41186a2017290300370000200b41106a2018290300370000200b41086a2019290300370000201341016a2113201241016a21120b200020154105746b200020132010461b2100200120164105746a20012012200e461b2101201a0d000b024002402012200e4f0d002000210b034020172001200e417f6a220e2d00004105746a220d41186a220c2900003703002018200d41106a22102900003703002019200d41086a22002900003703002005200d290000370320200b41606a220b41086a220f290000211b200b41106a2211290000211c200b41186a2213290000211d200d200b290000370000200c201d3700002010201c3700002000201b3700002013201729030037000020112018290300370000200f2019290300370000200b20052903203700002012200e490d000c020b0b2001210b201320104f0d0003402010417f6a22102d0000210d2017200b41186a220c2900003703002018200b41106a220e2900003703002019200b41086a22012900003703002005200b2900003703202000200d417f734105746a220d41086a220f290000211b200d41106a2211290000211c200d41186a2212290000211d200b200d290000370000200c201d370000200e201c3700002001201b3700002012201729030037000020112018290300370000200f2019290300370000200d2005290320370000200b41206a210b20132010490d000b0b20092005290300370000201f20062903003700002020200a290300370000202120222903003700002008200b20236b410576201e6a22014d0d032017201f290000370300201820202900003703002019202129000037030020052009290000370320200920014105746a220b41086a220d290000211b200b41106a220c290000211c200b41186a220e290000211d2009200b290000370000201f201d3700002020201c3700002021201b370000200e2017290300370000200c2018290300370000200d2019290300370000200b2005290320370000200820016b220d450d04200d20012001200d4b1b210c2008410376210e200b41206a2100024002402001200d417f6a220d490d002000200d2002200b2004105f200921000c010b20092001200220032004105f200b2103200d21010b200c200e4f2106200141154f0d010c050b0b201e200b1035000b200b200e105e000b41e885c000200120081038000b41f885c0001058000b20014102490d00200041606a21104101210c0340200c410574210b200c417f6a210d200c41016a210c02402000200b6a220b2000200d4105746a220e412010f804417f4a0d00200541c0016a41186a220f200b41186a2211290000370300200541c0016a41106a2212200b41106a2213290000370300200541c0016a41086a2214200b41086a22152900003703002005200b2900003703c001200b200e2900003700002015200e41086a2900003700002013200e41106a2900003700002011200e41186a2900003700004100210e0240200d450d002010210b03400240200541c0016a200b412010f8044100480d00200d210e0c020b200b41206a200b290000370000200b41386a200b41186a290000370000200b41306a200b41106a290000370000200b41286a200b41086a290000370000200b41606a210b200d417f6a220d0d000b0b2000200e4105746a220b20052903c001370000200b41186a200f290300370000200b41106a2012290300370000200b41086a20142903003700000b201041206a2110200c2001470d000b0b200541c0026a24000beb050a067f017e017f017e017f017e017f017e017f017e230041206b2202240002400240024020014108490d00200141017641feffffff07712203417f6a220420014f0d022001410d74200173220541117620057322054105742005732206417f2001417f6a677622077122054100200120052001491b6b220520014f0d01200020044105746a22042900002108200020054105746a220541086a2209290000210a200541106a220b290000210c200541186a220d290000210e20042005290000370000200441186a220f2900002110200f200e370000200441106a220f290000210e200f200c370000200441086a2204290000210c2004200a370000200d2010370000200b200e3700002009200c37000020052008370000024020032001490d00200321040c030b2006410d7420067322054111762005732205410574200573220620077122054100200120052001491b6b220520014f0d01200020034105746a22042900002108200020054105746a220541086a2209290000210a200541106a220b290000210c200541186a220d290000210e20042005290000370000200441186a220f2900002110200f200e370000200441106a220f290000210e200f200c370000200441086a2204290000210c2004200a370000200d2010370000200b200e3700002009200c370000200520083700002003410172220420014f0d022006410d742006732205411176200573220541057420057320077122054100200120052001491b6b220520014f0d01200020044105746a22012900002108200020054105746a220041086a2205290000210a200041106a2204290000210c200041186a2203290000210e20012000290000370000200141186a220629000021102006200e370000200141106a2206290000210e2006200c370000200141086a2201290000210c2001200a370000200320103700002004200e3700002005200c370000200020083700000b200241206a24000f0b41e885c000200520011038000b41d885c000200420011038000be90609067f017e017f017e017f027e017f017e027f230041206b22022400024020014101762203450d0003402003417f6a2203210402400240024003402004410174220541017221060240200541026a220520014f0d00200620014f0d0220052006200020064105746a200020054105746a412010f8044100481b21060b200620014f0d03200420014f0d02200020044105746a2204200020064105746a2205412010f804417f4a0d03200541086a22072900002108200541106a2209290000210a200541186a220b290000210c2004290000210d20042005290000370000200441186a220e290000210f200e200c370000200441106a220e290000210c200e200a370000200441086a2204290000210a20042008370000200b200f3700002009200c3700002007200a3700002005200d370000200621040c000b0b41d887c000200620011038000b41e887c000200420011038000b20030d000b0b0240024020014102490d002001210703402007417f6a220720014f0d02200241186a2209200041186a2204290000370300200241106a220b200041106a2205290000370300200241086a220e200041086a2203290000370300200020074105746a220641086a2900002108200641106a290000210a200641186a290000210c2000290000210d200020062900003700002004200c3700002005200a370000200320083700002002200d37030041002105024002400240034020062002290300370000200641186a2009290300370000200641106a200b290300370000200641086a200e2903003700002005410174220641017221040240200641026a220620074f0d00200420074f0d0220062004200020044105746a200020064105746a412010f8044100481b21040b200420074f0d03200520074f0d02200020054105746a2205200020044105746a2206412010f804417f4a0d032009200541186a2203290000370300200b200541106a2210290000370300200e200541086a2211290000370300200641086a2900002108200641106a290000210a200641186a290000210c2005290000210d200520062900003700002003200c3700002010200a370000201120083700002002200d370300200421050c000b0b41d887c000200420071038000b41e887c000200520071038000b200741014b0d000b0b200241206a24000f0b41e885c000200720011038000bdb08030a7f017e0a7f230041c0006b22022400200041a07f6a21032001417f6a2104200141324921054101210641002107024003400240024020062001490d00410021080c010b41012108200020064105746a2209200941606a412010f8044100480d0003404101210a20042006460d03200641016a2106200941206a220a2009412010f8042108200a21092008417f4a0d000b200620014921080b2006200146210a20050d0120062001460d0102400240024002402006417f6a220920014f0d002008450d0120002006410574220b6a220a290000210c200a200020094105746a22092900003700002009200c370000200a41086a220d290000210c200d200941086a220e290000370000200e200c370000200a41106a220f290000210c200f200941106a22102900003700002010200c370000200a41186a2211290000210c2011200941186a22122900003700002012200c37000020064102490d03200920002006417e6a22084105746a2213412010f804417f4a0d032009290000210c20092013290000370000200241206a41186a22142012290000370300200241206a41106a22152010290000370300200241206a41086a2216200e290000370300200e201341086a2900003700002010201341106a2900003700002012201341186a2900003700002002200c3703204100210e2008450d022003200b6a210903400240200241206a2009412010f8044100480d002008210e0c040b200941206a2009290000370000200941386a200941186a290000370000200941306a200941106a290000370000200941286a200941086a290000370000200941606a21092008417f6a22080d000c030b0b41d885c000200920011038000b41e885c000200620011038000b2000200e4105746a22092002290320370000200941186a2014290300370000200941106a2015290300370000200941086a20162903003700000b200741016a21070240200120066b22104102490d00200a41206a2209200a412010f804417f4a0d00200a290000210c200a2009290000370000200241206a41186a22122011290000370300200241206a41106a2213200f290000370300200241206a41086a220b200d290000370300200d200941086a290000370000200f200941106a2900003700002011200941186a2900003700002002200c3703204101210d024020104103490d00200a41c0006a200241206a412010f804417f4a0d00410321084102210e0340200a200e4105746a220941606a220d2009290000370000200d41186a200941186a290000370000200d41106a200941106a290000370000200d41086a200941086a290000370000024020082010490d00200e210d0c020b20084105742109200e210d2008210e200841016a2108200a20096a200241206a412010f8044100480d000b0b200a200d4105746a22092002290320370000200941186a2012290300370000200941106a2013290300370000200941086a200b2903003700000b20074105470d000b4100210a0b200241c0006a2400200a0bd92003167f037e067f230041c0026b220424000240024020014115490d0041012105410121060240024002400340200121072000210820052006712109024002400240024002400240034002400240024002402003450d00024020054101710d002000200110602003417f6a21030b2001410276220a41036c210b200a410174210c4100210d024020014132490d00200a200a417f6a220d2000200a4105746a2000200d4105746a412010f804220e410048220f1b2210200a41016a2211200d200a200f1b220a200020114105746a2000200a4105746a412010f80441004822111b220a2000200a4105746a200020104105746a412010f80422104100481b210a200c200c417f6a220d2000200c4105746a2000200d4105746a412010f804221241004822131b2214200c4101722215200d200c20131b220c200020154105746a2000200c4105746a412010f80422134100481b220c2000200c4105746a200020144105746a412010f80422144100481b210c200b200b417f6a220d2000200b4105746a2000200d4105746a412010f804221541004822161b2217200b41016a2218200d200b20161b220b200020184105746a2000200b4105746a412010f804220d4100481b220b2000200b4105746a200020174105746a412010f80422164100481b210b41024101200f1b200e411f7620111b2010411f766a2012411f766a2013411f766a2014411f766a2015411f766a200d411f766a2016411f766a210d0b2000200c4105746a2000200a4105746a412010f804220f411f76200d6a2000200b4105746a2000200a200c200f410048220f1b220e4105746a412010f8042210411f766a210d2000200b200e20104100481b220b4105746a2000200c200a200f1b22194105746a412010f804417f4c0d01200b21190c020b2000200110610c0f0b200d41016a220d410c490d0002402001410176220b450d00200020014105746a41606a210a2000210c0340200441206a41186a220d200c41186a220f290000370300200441206a41106a220e200c41106a2210290000370300200441206a41086a2211200c41086a22122900003703002004200c290000370320200a41086a2213290000211a200a41106a2214290000211b200a41186a2215290000211c200c200a290000370000200f201c3700002010201b3700002012201a3700002015200d2903003700002014200e29030037000020132011290300370000200a2004290320370000200a41606a210a200c41206a210c200b417f6a220b0d000b0b20012019417f736a21194101210a0c010b200d45210a0b02402009417f73200a45724101710d002000200110620d0d0b2002450d02201920014f0d0102402002200020194105746a220a412010f80441004e0d0020002108200121070c040b200441206a41186a2212200041186a220e290000370300200441206a41106a2213200041106a2210290000370300200441206a41086a2214200041086a221129000037030020042000290000370320200a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2000200a290000370000200e201c3700002010201b3700002011201a370000200d2012290300370000200b2013290300370000200c2014290300370000200a2004290320370000200441c0016a41186a2217200e290000370300200441c0016a41106a22182010290000370300200441c0016a41086a22192011290000370300200420002900003703c001200041606a2115200041206a21164100210c2001210b03400240200c200b417f6a220d4f0d002016200c4105746a210a0340200441c0016a200a412010f804417f4c0d01200a41206a210a200d200c41016a220c470d000b200d210c0b2015200b4105746a210a02400340200c200b417f6a220b4f0d01200441c0016a200a412010f804210d200a41606a220f210a200d4100480d000b20122016200c4105746a220a41186a220d2900003703002013200a41106a221d2900003703002014200a41086a22062900003703002004200a290000370320200f41286a221e290000211a200f41306a221f290000211b200f41386a2220290000211c200a200f41206a220f290000370000200d201c370000201d201b3700002006201a37000020202012290300370000201f2013290300370000201e2014290300370000200f2004290320370000200c41016a210c0c010b0b200020042903c001370000200e2017290300370000201020182903003700002011201929030037000002402001200c41016a220a490d002000200a4105746a21002001200a6b220141154f0d010c0c0b0b200a20011035000b419086c000201920011038000b2007450d010b201920074f0d01200441206a41186a2216200841186a221e290000370300200441206a41106a2217200841106a221f290000370300200441206a41086a2218200841086a222029000037030020042008290000370320200820194105746a220a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2008200a290000370000201e201c370000201f201b3700002020201a370000200d2016290300370000200b2017290300370000200c2018290300370000200a2004290320370000200441186a2205201e290000370300200441106a2209201f290000370300200441086a2221202029000037030020042008290000370300200841206a21014100211d2007417f6a220d450d022001210a0340200a2004412010f80441004e0d03200a41206a210a200d201d41016a221d470d000b200d211d0c020b41d885c000410041001038000b41e885c000201920071038000b200820074105746a210c200d210b02400340200c2100200b220a201d4d22060d01200a417f6a210b200041606a220c2004412010f804417f4a0d000b0b0240200a201d490d00200d200a490d0241800121144100210f410021124100210d4100211141800121152001201d4105746a2222210103400240200020016b220a419fc0004b22190d00200a410576220a41807f6a200a2012200f492011200d49220c72220b1b210a0240200b450d002015200a200c1b2115200a2014200c1b21140c010b200a200a41017622156b21140b02402011200d470d00024020150d00200441c0006a220d21110c010b4100210a200441c0006a2211210d2001210c0340200d200a3a0000200d200c2004412010f804417f73411f766a210d200c41206a210c2015200a41016a220a470d000b0b02402012200f470d00024020140d00200441c0016a220f21120c010b200041606a210a4100210c200441c0016a2212210f0340200f200c3a0000200f200a2004412010f804411f766a210f200a41606a210a2014200c41016a220c470d000b0b0240200f20126b220a200d20116b220c200c200a4b1b2213450d002016200120112d00004105746a220a41186a2900003703002017200a41106a2900003703002018200a41086a2900003703002004200a290000370320200120112d00004105746a220a200020122d0000417f734105746a220c290000370000200a41186a200c41186a290000370000200a41106a200c41106a290000370000200a41086a200c41086a290000370000024020134101460d004100210a034020002012200a6a220e2d0000417f734105746a220c20012011200a6a41016a22102d00004105746a220b290000370000200c41186a200b41186a290000370000200c41106a200b41106a290000370000200c41086a200b41086a290000370000200120102d00004105746a220c2000200e41016a2d0000417f734105746a220b290000370000200c41186a200b41186a290000370000200c41106a200b41106a290000370000200c41086a200b41086a290000370000200a41026a210c200a41016a220b210a200c2013490d000b2012200b6a21122011200b6a21110b200020122d0000417f734105746a220a2004290320370000200a41186a2016290300370000200a41106a2017290300370000200a41086a2018290300370000201241016a2112201141016a21110b200020144105746b20002012200f461b2100200120154105746a20012011200d461b210120190d000b024002402011200d4f0d002000210a034020162001200d417f6a220d2d00004105746a220c41186a220b2900003703002017200c41106a220f2900003703002018200c41086a22002900003703002004200c290000370320200a41606a220a41086a220e290000211a200a41106a2210290000211b200a41186a2212290000211c200c200a290000370000200b201c370000200f201b3700002000201a3700002012201629030037000020102017290300370000200e2018290300370000200a20042903203700002011200d490d000c020b0b2001210a2012200f4f0d000340200f417f6a220f2d0000210c2016200a41186a220b2900003703002017200a41106a220d2900003703002018200a41086a22012900003703002004200a2900003703202000200c417f734105746a220c41086a220e290000211a200c41106a2210290000211b200c41186a2211290000211c200a200c290000370000200b201c370000200d201b3700002001201a3700002011201629030037000020102017290300370000200e2018290300370000200c2004290320370000200a41206a210a2012200f490d000b0b20082004290300370000201e2005290300370000201f2009290300370000202020212903003700002007200a20226b410576201d6a22014d0d032016201e2900003703002017201f2900003703002018202029000037030020042008290000370320200820014105746a220a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2008200a290000370000201e201c370000201f201b3700002020201a370000200d2016290300370000200b2017290300370000200c2018290300370000200a2004290320370000200720016b220c450d04200c20012001200c4b1b210b2007410376210d200a41206a2100024002402001200c417f6a220c490d002000200c200a20031063200821000c010b20082001200220031063200a2102200c21010b200b200d4f2105200141154f0d010c050b0b201d200a1035000b200a200d105e000b41e885c000200120071038000b41f885c0001058000b20014102490d00200041606a210f4101210b0340200b410574210a200b417f6a210c200b41016a210b02402000200a6a220a2000200c4105746a220d412010f804417f4a0d00200441c0016a41186a220e200a41186a2210290000370300200441c0016a41106a2211200a41106a2212290000370300200441c0016a41086a2213200a41086a22142900003703002004200a2900003703c001200a200d2900003700002014200d41086a2900003700002012200d41106a2900003700002010200d41186a2900003700004100210d0240200c450d00200f210a03400240200441c0016a200a412010f8044100480d00200c210d0c020b200a41206a200a290000370000200a41386a200a41186a290000370000200a41306a200a41106a290000370000200a41286a200a41086a290000370000200a41606a210a200c417f6a220c0d000b0b2000200d4105746a220a20042903c001370000200a41186a200e290300370000200a41106a2011290300370000200a41086a20132903003700000b200f41206a210f200b2001470d000b0b200441c0026a24000bb50404057f017e017f017e0240024020012802042202450d00200128020022032d0000210420012002417f6a22053602042001200341016a3602000240200441037122064103460d00024002400240024020060e03000102000b2004410276ad21070c020b41012106024020050d000c050b20032d0001210520012002417e6a3602042001200341026a3602002005410874200472220141ffff0371418002490d04200141fcff0371410276ad21070c010b410121060240200541034f0d000c040b200341036a2d0000210520032f0001210820012002417c6a3602042001200341046a3602002008200541107472410874200472220141808004490d032001410276ad21070b410021060c020b02402004410276220841044b0d000240024020080e050002020201000b20054104490d022003350001210720012002417b6a3602042001200341056a36020020074280808080045421060c030b20054108490d01200329000121072001200241776a3602042001200341096a3602002007428080808080808080015421060c020b200841046a220541084b0d002002417e6a2102200341026a2103410021044200210741012106034002402002417f470d000c030b2003417f6a310000210920012002360204200120033602002002417f6a2102200341016a210320092004410374413871ad862007842107200441016a220441ff01712005490d000b2007427f412820084103746b413871ad885821060c010b410121060b2000200737030820002006ad3703000bde0506067f017e017f017e017f017e230041206b220224000240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200024002400240200541037122074103460d0002400240024020070e03000102000b2005410276ad21080c040b410121072006450d0220042d0001210620012003417e6a3602042001200441026a3602002006410874200572220141ffff0371418002490d02200141fcff0371410276ad21080c030b4101210720064103490d01200441036a2d0000210620042f0001210920012003417c6a3602042001200441046a3602002009200641107472410874200572220141808004490d012001410276ad21080c020b024020054102762209410c4b0d0002400240024020090e0d00030303010303030303030302000b20064104490d052004350001210820012003417b6a3602042001200441056a36020020084280808080045421074200210a0c060b20064108490d04200429000121082001200341776a3602042001200441096a3602002008428080808080808080015421074200210a0c050b20064110490d03200441096a290000210a2004290001210820012003416f6a3602042001200441116a360200200a428080808080808080015421070c040b200941046a220641104b0d022003417e6a2103200441026a21044100210541012107200241186a210b420021084200210a03402003417f460d01200241106a2004417f6a3100004200200541037441f8007110f90420012003360204200120043602002003417f6a2103200441016a2104200b290300200a84210a20022903102008842108200541016a220541ff01712006490d000b2002427f427f41e80020094103746b41f8007110fa042008200229030058200a200241086a290300220c58200a200c511b21070c030b0c020b4200210a410021070c010b410121070b20002008370308200041106a200a37030020002007ad370300200241206a24000b9e0701037f02400240024002400240024020002802002202413f4b0d0002400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d0620004101742204200320032004491b22044100480d060240024020000d002004102921030c010b200128020020002004102a21030b2003450d0220012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a20024102743a00000f0b200241808001490d032002418080808004490d020c010b20044101102c000b0240024002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0520024101742204200320032004491b22044100480d050240024020020d002004102921030c010b200128020020022004102a21030b2003450d0120012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a00002000280200210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d0520024101742200200420042000491b22004100480d050240024020020d002000102921020c010b200128020020022000102a21020b2002450d0220012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b20044101102c000b20004101102c000b024002400240200141046a2802002203200141086a28020022006b4104490d00200128020021030c010b200041046a22042000490d0320034101742200200420042000491b22004100480d030240024020030d002000102921030c010b200128020020032000102a21030b2003450d0120012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20024102744102723600000f0b20004101102c000b024002400240200141046a2802002203200141086a28020022006b4102490d00200128020021030c010b200041026a22042000490d0220034101742200200420042000491b22004100480d020240024020030d002000102921030c010b200128020020032000102a21030b2003450d0120012003360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200320006a20024102744101723b00000f0b20004101102c000b102d000bbd0903017f017e057f230041e0006b220224000240024002400240024002400240024002400240024020002903002203423f560d0002400240200141046a280200200141086a2802002200460d00200128020021040c010b200041016a22042000490d0b20004101742205200420042005491b22054100480d0b0240024020000d002005102921040c010b200128020020002005102a21040b2004450d0220012004360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200420006a2003a74102743a00000c080b200342808001540d062003428080808004540d054108200379a741037622056b4104490d0402400240200141046a280200200141086a2802002204460d00200128020021060c010b200441016a22072004490d0a20044101742206200720072006491b22074100480d0a0240024020040d002007102921060c010b200128020020042007102a21060b2006450d0220012006360200200141046a2007360200200141086a28020021040b200141086a2207200441016a360200200620046a411320054102746b3a0000200220002903002203370308200541786a2104200141046a2106034002400240200628020020072802002200460d00200128020021050c010b200041016a22052000490d0b20004101742208200520052008491b22084100480d0b0240024020000d002008102921050c010b200128020020002008102a21050b2005450d042001200536020020062008360200200728020021000b2007200041016a360200200520006a2003a73a000020034208882103200441016a22002004492105200021042005450d000b20022003370308200350450d030c070b20054101102c000b20074101102c000b20084101102c000b200241286a41146a411d360200200241346a411e360200200241106a41146a41033602002002200241086a360240200241e08dc000360244200241c8006a41146a4100360200200242033702142002419ce7c5003602102002411e36022c200241c8ecc5003602582002420137024c200241e88dc0003602482002200241286a3602202002200241c8006a3602382002200241c4006a3602302002200241c0006a360228200241106a41f08dc000106a000b41c48dc0001058000b024002400240200141046a2802002204200141086a28020022006b4104490d00200128020021040c010b200041046a22052000490d0520044101742200200520052000491b22004100480d050240024020040d002000102921040c010b200128020020042000102a21040b2004450d0120012004360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200420006a2003a74102744102723600000c020b20004101102c000b02400240200141046a2802002204200141086a28020022006b4102490d00200128020021040c010b200041026a22052000490d0320044101742200200520052000491b22004100480d030240024020040d002000102921040c010b200128020020042000102a21040b2004450d0220012004360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200420006a2003a74102744101723b00000b200241e0006a24000f0b20004101102c000b102d000b6501027f230041206b220224002001411c6a280200210320012802182101200241086a41106a200041106a290200370300200241086a41086a200041086a2902003703002002200029020037030820012003200241086a10b5042100200241206a240020000bc20202027f017e23004180016b220224002000280200210002400240024002400240200128020022034110710d002000290300210420034120710d0120044101200110b50121000c020b20002903002104410021000340200220006a41ff006a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000c010b410021000340200220006a41ff006a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000b20024180016a240020000f0b20034180011035000b20034180011035000b4b02017f017e230041206b2202240020012902002103200241146a20012902083702002002200337020c20022000360208200241c8ecc500360204200241c8ecc500360200200210d204000b910a03017f027e057f230041e0006b2202240002400240024002400240024002400240024002400240200028020022002903002203423f56200041086a290300220442005220045022051b0d0002400240200141046a280200200141086a2802002200460d00200128020021050c010b200041016a22052000490d0b20004101742206200520052006491b22064100480d0b0240024020000d002006102921050c010b200128020020002006102a21050b2005450d0220012005360200200141046a2006360200200141086a28020021000b200141086a200041016a360200200520006a2003a74102743a00000c080b20034280800154410020051b0d06200342808080800454410020051b0d05411020047920037942c0007c20044200521ba741037622066b4104490d0402400240200141046a280200200141086a2802002205460d00200128020021070c010b200541016a22082005490d0a20054101742207200820082007491b22084100480d0a0240024020050d002008102921070c010b200128020020052008102a21070b2007450d0220012007360200200141046a2008360200200141086a28020021050b200141086a2208200541016a360200200720056a413320064102746b3a0000200029030021032002200041086a290300220437030820022003370300200641706a2105200141046a2107034002400240200728020020082802002200460d00200128020021060c010b200041016a22062000490d0b20004101742209200620062009491b22094100480d0b0240024020000d002009102921060c010b200128020020002009102a21060b2006450d042001200636020020072009360200200828020021000b2008200041016a360200200620006a2003a73a00002003420888200442388684210320044208882104200541016a22002005492106200021052006450d000b2002200337030020022004370308200320048450450d030c070b20064101102c000b20084101102c000b20094101102c000b200241286a41146a411d360200200241346a411f360200200241106a41146a410336020020022002360240200241908fc000360244200241c8006a41146a4100360200200242033702142002419ce7c5003602102002411f36022c200241c8ecc5003602582002420137024c200241e88dc0003602482002200241286a3602202002200241c8006a3602382002200241c4006a3602302002200241c0006a360228200241106a41a08fc000106a000b41f48ec0001058000b024002400240200141046a2802002205200141086a28020022006b4104490d00200128020021050c010b200041046a22062000490d0520054101742200200620062000491b22004100480d050240024020050d002000102921050c010b200128020020052000102a21050b2005450d0120012005360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200520006a2003a74102744102723600000c020b20004101102c000b02400240200141046a2802002205200141086a28020022006b4102490d00200128020021050c010b200041026a22062000490d0320054101742200200620062000491b22004100480d030240024020050d002000102921050c010b200128020020052000102a21050b2005450d0220012005360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200520006a2003a74102744101723b00000b200241e0006a24000f0b20004101102c000b102d000b840605027f027e017f027e027f230041a0016b220224002000280200210002400240024002400240024002400240200128020022034110710d00200041086a29030021042000290300210520034120710d0220054290ce005441002004501b450d012005a72103412721000c060b200041086a2903002105200029030021044180012100024003402000450d01200241206a20006a417f6a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a210020044204882005423c8684220420054204882205844200520d000b0b20004181014f0d022001410141f8efc5004102200241206a20006a41800120006b10b60121000c060b41272100200241186a21060340200241106a200520044290ce00420010fc042002200229031022072006290300220842f0b17f427f10fb04200241206a20006a2203417c6a200520022903007ca7220941ffff037141e4006e220a410174418aedc5006a2f00003b00002003417e6a200a419c7f6c20096a41ffff0371410174418aedc5006a2f00003b0000200542ffc1d72f56210320044200522109200450210a2000417c6a2100200721052008210420032009200a1b0d000c040b0b4180012100024003402000450d01200241206a20006a417f6a2005a7410f712203413072200341376a2003410a491b3a00002000417f6a210020054204882004423c8684220520044204882204844200520d000b0b20004181014f0d012001410141f8efc5004102200241206a20006a41800120006b10b60121000c040b20004180011035000b20004180011035000b2007a721030b02400240200341e3004a0d00200321090c010b200241206a2000417e6a22006a2003200341ffff037141e4006e2209419c7f6c6a41ffff0371410174418aedc5006a2f00003b00000b024002402009410a480d00200241206a2000417e6a22006a2009410174418aedc5006a2f00003b00000c010b200241206a2000417f6a22006a200941306a3a00000b2001410141c8ecc5004100200241206a20006a412720006b10b60121000b200241a0016a240020000bd20302047f037e230041e0006b2204240002400240411410292205450d00200541002900d88c40370000200541106a41002800e88c40360000200541086a41002900e08c4037000020044294808080c002370234200420053602302001200441306a104a20042802342105200441186a200428023022062004280238106e200441186a41106a2903004200200428021822071b21082004290320420020071b210902402005450d002006102e0b200441306a2001200920027c2202200820037c2002200954ad7c106f200441306a41106a290300210920042903382102024020042903304200520d00200221030c020b200441c28cc00041161070200441106a29030021082004290308210a2004280200210542002103200441306a41086a220142003703002004420037033041c28cc0004116200441306a1003200441d0006a41086a200129030037030020042004290330370350200442002008420020051b220820097d200a420020051b2209200254ad7d220a200920027d2202200956200a200856200a2008511b22051b37033820044200200220051b370330200441d0006a4110200441306a41101004420021090c010b41144101102c000b2000200337030020002009370308200441e0006a24000b880204017f017e037f027e230041c0006b2203240042002104200341206a41186a22054200370300200341206a41106a22064200370300200341206a41086a220742003703002003420037032020012002200341206a1000200341186a2005290300370300200341106a2006290300370300200341086a2007290300370300200320032903203703002003410036022020034120200341206a1008210102400240024020032802202202417f470d000c010b20024110490d01200141086a2900002108200129000021092001102e420121040b2000200937030820002004370300200041106a2008370300200341c0006a24000f0b41eff0c2004133200341206a4184f4c2001053000b9e0603047f037e047f230041b0016b2204240002400240411410292205450d00200541002900d88c40370000200541106a41002800e88c40360000200541086a41002900e08c4037000020044294808080c002370224200420053602202001200441206a104a20042802242106200441086a200428022022072004280228106e200441086a41106a2903002108200428020821052004290310210902402006450d002007102e0b2008420020051b210a2009420020051b2108024002400240200242ffffe883b1de1656200342005220035022051b0d002008200a84500d010b4101210602402002428080e983b1de1654410020051b0d00411410292205450d0441002106200541002900d88c40370000200541106a41002800e88c40360000200541086a41002900e08c4037000020044294808080c002370224200420053602202001200441206a104a200428022421072004280228210b20042802202105200441206a41186a220c4200370300200441206a41106a220d4200370300200441206a41086a220e4200370300200442003703202005200b200441206a100020044190016a41186a200c29030037030020044190016a41106a200d29030037030020044190016a41086a200e290300370300200420042903203703900120044190016a412041c8ecc500410041001005210b02402007450d002005102e0b200b417f470d0020011071200441d8006a2003370300200441d0006a200237030041002106200441206a41086a41003a0000200441296a2001290000370000200441316a200141086a290000370000200441396a200141106a290000370000200441c1006a200141186a290000370000200441023a002041c8ecc5004100200441206a10720b2001200220031073200041106a200a20037d2008200254ad7d2003200a7d2002200854ad7d2008200256200a200356200a2003511b22051b3703002000200820027d200220087d20051b370308200020063a001820002005ad3703000c010b20004200370300200041013a0018200041106a4200370300200041086a42003703000b200441b0016a24000f0b41144101102c000b41144101102c000bce0104017f017e017f027e230041206b2203240042002104200341106a41086a220542003703002003420037031020012002200341106a1003200341086a2005290300370300200320032903103703002003410036021020034110200341106a1008210102400240024020032802102202417f470d000c010b20024110490d01200141086a2900002106200129000021072001102e420121040b2000200737030820002004370300200041106a2006370300200341206a24000f0b41eff0c2004133200341106a4184f4c2001053000ba20a03067f037e047f230041a0016b22012400200141186a4197cac2004113107d20012802182102200128021c21030240024002400240024002400240410110292204450d00200420002d00003a0000200441014102102a2204450d01200420002d00013a0001200441024104102a2204450d02200420002d00023a0002200420002d00033a0003200441044108102a2204450d03200420002d00043a0004200420002d00053a0005200420002d00063a0006200420002d00073a0007200441084110102a2204450d04200420002d00083a0008200420002d00093a0009200420002d000a3a000a200420002d000b3a000b200420002d000c3a000c200420002d000d3a000d200420002d000e3a000e200420002d000f3a000f200441104120102a2204450d05200420002d00103a0010200420002d00113a0011200420002d00123a0012200420002d00133a0013200420002d00143a0014200420002d00153a0015200420002d00163a0016200420002d00173a0017200420002d00183a0018200420002d00193a0019200420002d001a3a001a200420002d001b3a001b200420002d001c3a001c200420002d001d3a001d200420002d001e3a001e200420002d001f3a001f20042d0000210520042d000121062004102e20014190016a2005200641087472410676220610bb0102402005413f7122042001280298014f0d00200141086a20012802900120044105746a22041084012001290308200141086a41086a290300844200520d00200041086a2900002107200041106a2900002108200041186a290000210920042000290000370000200441186a2009370000200441106a2008370000200441086a2007370000200141206a41086a20014190016a41086a28020036020020012001290390013703202006200141206a1091030c070b2003410020021b21040240200128029401450d00200128029001102e0b200141206a200410bb01024020012802282205413f4d0d000340200441016a210402402001280224450d002001280220102e0b200141206a200410bb0120012802282205413f4b0d000b0b2001280220210620012802242103200141206a41186a220a200041186a290000370300200141206a41106a220b200041106a290000370300200141206a41086a220c200041086a29000037030020012000290000370320200541016a2102024020032005470d00024020054101742203200220022003491b2203410574220d4100480d000240024020050d00200d102921060c010b20062005410574200d102a21060b20060d01200d4101102c000b102d000b200520044106746a210d200620054105746a22052001290320370000200541186a200a290300370000200541106a200b290300370000200541086a200c2903003700000240200241c000470d00200141206a41086a22054200370300200142003703204197cac2004113200141206a100320014190016a41086a200529030037030020012001290320370390012001200441016a36022020014190016a4110200141206a410410040b2001200236022820012003360224200120063602202004200141206a109103200141206a41086a2000290000370300200141206a41106a200041086a290000370300200141206a41186a200041106a290000370300200141c0006a200041186a2900003703002001200d360224200141013a002041c8ecc5004100200141206a10720c060b41014101102c000b41024101102c000b41044101102c000b41084101102c000b41104101102c000b41204101102c000b200141a0016a24000b982203097f047e017f230041b0036b22032400200341003602a00141dff0c2004110200341a0016a100821040240024020032802a0012205417f460d002004450d00024020054104490d00200428000021062004102e410021070c020b41eff0c2004133200341a8036a4184f4c2001053000b410121070b200141057421084101210941002104410021050240024002400240024002400240024002402001450d0020084100480d05200810292209450d012001410574220a41606a410576210b410021040340200341b8026a41186a200020046a220541186a290000220c370300200341b8026a41106a200541106a290000220d370300200341b8026a41086a200541086a290000220e37030020032005290000220f3703b802200920046a220541186a200c370000200541106a200d370000200541086a200e3700002005200f370000200a200441206a2204470d000b200b41016a2105200121040b2003418c016a20063602002003200736028801200341186a200241f00010f6041a20034198016a200536020020034194016a20043602002003200936029001200341106a4197e5c5004111107d0240024002400240024002402003280214410020032802101b220641016a22052006490d00200341b8026a41086a22044200370300200342003703b8024197e5c5004111200341b8026a100320034180036a41086a22092004290300370300200320032903b80237038003200320053602a00120034180036a4110200341a0016a41041004200341a0016a200341186a41880110f6041a20044200370300200342003703b80241c4f5c200410d200341b8026a100320092004290300370300200320032903b80237038003200341003602b80220034180036a4110200341b8026a100821050240024020032802b8022204417f460d0020050d010b200341003602b002200342013703a8020c080b200320043602b002200320043602ac02200320053602a8022004450d07200341b8026a2005200410a303024020032802b8024101460d0020032802bc02210a0240200341c4026a2802002204200341c0026a2802002205460d0020032802b002200420056b6a22094188016a2202417f4c0d0d0240024020020d00410121070c010b200210292207450d040b200320023602dc02200320073602d802200320093602e0022003200341d8026a3602b802200a200341b8026a2004109d0120092004490d0420032802e002220a2009490d0520032802b002220a2005490d0620032802d802210220032802a80221072003200920046b2209360298032003200a20056b220a36029c032009200a470d07200220046a200720056a200910f6041a200341a0016a200341d8026a10a40320032802e002210520032802dc02210920032802d802210420032802ac02450d0b20032802a802102e0c0b0b2003200341a8026a3602b802200a200341b8026a2005109d01200341a0016a200341a8026a10a4030c090b20032802ac02450d0c20032802a802102e0c0c0b200341186a10a5030c0c0b20024101102c000b200420091035000b2009200a105e000b2005200a1035000b20034180036a41146a411d3602002003418c036a4120360200200341e8026a41146a4103360200200320034198036a3602a00320032003419c036a3602a403200341b8026a41146a4100360200200342033702ec022003419ce7c5003602e8022003412036028403200341c8ecc5003602c802200342013702bc02200341f0e7c5003602b802200320034180036a3602f8022003200341b8026a360290032003200341a4036a360288032003200341a0036a36028003200341e8026a41ace8c500106a000b20084101102c000b4101200341a8026a1047200341a0016a200341a8026a10a4030b20032802b002210520032802ac02210920032802a80221040b2004450d02200341b8026a41086a220a4200370300200342003703b80241c4f5c200410d200341b8026a100320034180036a41086a200a290300370300200320032903b8023703800320034180036a411020042005100402402009450d002004102e0b200341a0016a10a503200341086a41b0f3c200410d107d2001450d03200020086a2110200328020c410020032802081b210b0240024002400340200320063602ac022003200b3602a802024002400240024002400240024002400240024002400240024002400240024002400240024002400240411210292204450d00200441106a41002f00e1f5423b0000200441086a41002900d9f542370000200441002900d1f542370000200341b8026a41186a22094200370300200341b8026a41106a220a4200370300200341b8026a41086a22014200370300200342003703b80220044112200341b8026a1000200341a0016a41186a22082009290300370300200341a0016a41106a2202200a290300370300200341a0016a41086a22072001290300370300200320032903b8023703a001412010292205450d01200520032903a001370000200541186a2008290300370000200541106a2002290300370000200541086a20072903003700002004102e410110292204450d02200420002d00003a0000200441014102102a2204450d032004200041016a2d00003a0001200441024104102a2204450d042004200041026a2d00003a00022004200041036a2d00003a0003200441044108102a2204450d052004200041046a2d00003a00042004200041056a2d00003a00052004200041066a2d00003a00062004200041076a2d00003a0007200441084110102a2204450d062004200041086a2d00003a00082004200041096a2d00003a000920042000410a6a2d00003a000a20042000410b6a2d00003a000b20042000410c6a2d00003a000c20042000410d6a2d00003a000d20042000410e6a2d00003a000e20042000410f6a2d00003a000f200441104120102a2204450d072004200041106a2d00003a00102004200041116a2d00003a00112004200041126a2d00003a00122004200041136a2d00003a00132004200041146a2d00003a00142004200041156a2d00003a00152004200041166a2d00003a00162004200041176a2d00003a00172004200041186a2d00003a00182004200041196a2d00003a001920042000411a6a2d00003a001a20042000411b6a2d00003a001b20042000411c6a2d00003a001c20042000411d6a2d00003a001d20042000411e6a2d00003a001e20042000411f6a2d00003a001f20094200370300200a420037030020014200370300200342003703b80220044120200341b8026a1000200820092903003703002002200a29030037030020072001290300370300200320032903b8023703a0012005412041c000102a2205450d08200520032903a001370020200541386a2008290300370000200541306a2002290300370000200541286a20072903003700002004102e200341003602a001200541c000200341a0016a10082109024020032802a0012204417f470d00200341003602e002200342013703d8020c130b200320043602e002200320043602dc02200320093602d8022004450d12200341a0016a2009200410a303024020032802a0014101460d0020032802a4012101024020032802ac01220420032802a8012209460d0020032802e002200420096b6a220a41086a2208417f4c0d1c0240024020080d00410121020c010b200810292202450d0c0b200320083602ec02200320023602e8022003200a3602f0022003200341e8026a3602a0012001200341a0016a2004109d01200a2004490d0c20032802f0022201200a490d0d20032802e00222012009490d0e20032802e802210820032802d80221022003200a20046b220a360298032003200120096b220136029c03200a2001470d0f200820046a200220096a200a10f6041a20032802a802210a0240024020032802ec02220920032802f00222046b4104490d0020032802e80221090c010b200441046a22012004490d1c20094101742204200120012004491b22044100480d1c0240024020090d002004102921090c010b20032802e80220092004102a21090b2009450d11200320043602ec02200320093602e80220032802f00221040b2003200441046a3602f002200920046a200a36000020032802ac02210a0240024020032802ec02220920032802f00222046b4104490d0020032802e80221090c010b200441046a22012004490d1c20094101742204200120012004491b22044100480d1c0240024020090d002004102921090c010b20032802e80220092004102a21090b2009450d12200320043602ec02200320093602e80220032802f00221040b2003200441046a3602f002200920046a200a36000020032802f002210920032802ec02210a20032802e802210420032802dc02450d1620032802d802102e0c160b2003200341d8026a3602a0012001200341a0016a2009109d0120032802a802210a0240024020032802dc02220920032802e00222046b4104490d0020032802d80221090c010b200441046a22012004490d1b20094101742204200120012004491b22044100480d1b0240024020090d002004102921090c010b20032802d80220092004102a21090b2009450d12200320043602dc02200320093602d80220032802e00221040b2003200441046a3602e002200920046a200a36000020032802ac02210a0240024020032802dc02220920032802e00222046b4104490d0020032802d80221090c010b200441046a22012004490d1b20094101742204200120012004491b22044100480d1b0240024020090d002004102921090c010b20032802d80220092004102a21090b2009450d13200320043602dc02200320093602d80220032802e00221040b2003200441046a3602e002200920046a200a3600000c140b20032802dc02450d1620032802d802102e0c160b41124101102c000b41204101102c000b41014101102c000b41024101102c000b41044101102c000b41084101102c000b41104101102c000b41204101102c000b41c0004101102c000b20084101102c000b2004200a1035000b200a2001105e000b200920011035000b20034180036a41146a411d3602002003418c036a4120360200200341b8026a41146a4103360200200320034198036a3602a00320032003419c036a3602a403200341a0016a41146a4100360200200342033702bc022003419ce7c5003602b8022003412036028403200341c8ecc5003602b001200342013702a401200341f0e7c5003602a001200320034180036a3602c8022003200341a0016a360290032003200341a4036a360288032003200341a0036a36028003200341b8026a41ace8c500106a000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b4101200341d8026a104720032802a802210a0240024020032802dc02220920032802e00222046b4104490d0020032802d80221090c010b200441046a22012004490d0720094101742204200120012004491b22044100480d070240024020090d002004102921090c010b20032802d80220092004102a21090b2009450d05200320043602dc02200320093602d80220032802e00221040b2003200441046a3602e002200920046a200a36000020032802ac02210a0240024020032802dc02220920032802e00222046b4104490d0020032802d80221090c010b200441046a22012004490d0720094101742204200120012004491b22044100480d070240024020090d002004102921090c010b20032802d80220092004102a21090b2009450d06200320043602dc02200320093602d80220032802e00221040b2003200441046a3602e002200920046a200a3600000b20032802e002210920032802dc02210a20032802d80221040b2004450d01200541c0002004200910040240200a450d002004102e0b2005102e200041206a22002010470d000c070b0b2005102e0c050b20044101102c000b20044101102c000b102d000b1032000b200341a0016a10a5030b200341b0036a24000bfb1403087f027e027f230041f0036b22032400024002400240024002400240024002400240024002400240411410292204450d00200441002900d88c40370000200441106a41002800e88c40360000200441086a41002900e08c4037000020034294808080c00237024c200320043602482000200341c8006a104a200328024c21052003280250210620032802482104200341c8006a41186a22074200370300200341c8006a41106a22084200370300200341c8006a41086a220942003703002003420037034820042006200341c8006a100020034188036a41186a200729030037030020034188036a41106a200829030037030020034188036a41086a20092903003703002003200329034837038803200320023703502003200137034820034188036a4120200341c8006a4110100402402005450d002004102e0b200142ffffe883b1de165620024200522002501b0d09411410292204450d01200441002900d88c40370000200441106a41002800e88c40360000200441086a41002900e08c4037000020034294808080c00237024c200320043602482000200341c8006a104a200328024c21052003280250210620032802482104200341c8006a41186a22074200370300200341c8006a41106a22084200370300200341c8006a41086a220942003703002003420037034820042006200341c8006a100020034188036a41186a200729030037030020034188036a41106a200829030037030020034188036a41086a20092903003703002003200329034837038803200341306a20034188036a1074200341306a41106a2903002101200329033821022003280230210a02402005450d002004102e0b410e10292204450d02200441002900848d40370000200441066a410029008a8d403700002003428e808080e00137024c200320043602482000200341c8006a104a200328024c21052003280250210620032802482104200341c8006a41186a22074200370300200341c8006a41106a22084200370300200341c8006a41086a220942003703002003420037034820042006200341c8006a100020034188036a41186a200729030037030020034188036a41106a200829030037030020034188036a41086a2009290300370300200320032903483703880320034188036a4120100602402005450d002004102e0b02402002200184500d00200a450d00200341186a41c28cc00041161070200341186a41106a290300210b2003290320210c20032802182104200341c8016a41086a22054200370300200342003703c80141c28cc0004116200341c8016a100320034188036a41086a2005290300370300200320032903c8013703880320034200200b420020041b220b20017d200c420020041b2201200254ad7d220c200120027d2202200156200c200b56200c200b511b22041b37035020034200200220041b37034820034188036a4110200341c8006a411010040b20001075411710292204450d03200441002900b0a5433700002004410f6a41002900bfa543370000200441086a41002900b8a54337000020034297808080f00237024c200320043602482000200341c8006a104a200328024c21072003280250210620032802482105200341c8006a41186a22044200370300200341c8006a41106a22084200370300200341c8006a41086a220942003703002003420037034820052006200341c8006a100020034188036a41186a200429030037030020034188036a41106a200829030037030020034188036a41086a20092903003703002003200329034837038803200341c8006a20034188036a1076024020032d004822064102460d0020034188036a412010060b200341e8006a280200210a200341e4006a28020021092004280200210802402007450d002005102e0b0240024002400240200641037122044103460d0020040e03010003010b20060d0220090d010c020b2008200a10072009450d010b2008102e0b200341b8016a2000107720032802b801210420032802c00121052003410036024820042005200341c8006a1008210720032802482206417f460d07200320063602ec03200320073602e803200341c8006a200341e8036a107820032d00484101460d0420034188036a200341c8006a41017241e00010f6041a02402006450d002007102e0b200341a8026a20034188036a41e00010f6041a200420051006200341c8016a200341a8026a41e00010f6041a20034188036a200341c8016a41e00010f6041a024020032802bc01450d002004102e0b200341c8006a20034188036a41e00010f6041a200341c8006a41206a210920034188016a210d200341c8006a210a4120417f4a210e4104210641e7e485f306210503402009210702400240200541e2c289ab06460d00200a2107200541e7e485f306460d000240200541e9dabdf306460d00410121084100210441c8ecc50021070c020b200d21070b200e450d07024041200d0041012108410021040c010b412010292208450d08412021040b20082007200410f6042107200320043602b402200320043602b002200320073602ac02200320053602a802200341c8016a200341a8026a107920032802c801220520032802d0011006024020032802cc01450d002005102e0b02402004450d002007102e0b02402006410c460d002006418cd8c1006a2800002105200641046a21060c010b0b200341013a00b801200341c8016a41086a22044200370300200342003703c80141ccdfc500410f200341c8016a1003200341a8026a41086a2004290300370300200320032903c8013703a802200341a8026a4110200341b8016a410110040c080b41144101102c000b41144101102c000b410e4101102c000b41174101102c000b41eff0c200413320034188036a4184f4c2001053000b1032000b41204101102c000b200341c8016a200341a8026a41e00010f6041a20032802bc01450d002004102e0b411810292204450d01200441002900ec8c40370000200441106a41002900fc8c40370000200441086a41002900f48c4037000020034298808080800337024c200320043602482000200341c8006a104a200328024c21042003200328024822062003280250106e200341106a2903002102200329030821012003280200210502402004450d002006102e0b02402001200284500d0020050d010b411310292204450d02200441002900eff3423700002004410f6a41002800fef342360000200441086a41002900f7f34237000020034293808080b00237024c200320043602482000200341c8006a104a200328024c21062003280250210720032802482105200341c8006a41186a22084200370300200341c8006a41106a22094200370300200341c8006a41086a220442003703002003420037034820052007200341c8006a100020034188036a41186a200829030037030020034188036a41106a200929030037030020034188036a41086a2004290300370300200320032903483703880320034188036a4120100602402006450d002005102e0b200441013a0000200341d1006a2000290000370000200341d9006a200041086a290000370000200341e1006a200041106a290000370000200341e9006a200041186a290000370000200341023a004841c8ecc5004100200341c8006a10720b200341f0036a24000f0b41184101102c000b41134101102c000b980102037f037e230041106b220224002002410036020420014120200241046a1008210302400240024020022802042204417f470d00420021050c010b20044110490d01200341086a2900002106200329000021072003102e200141201006420121050b2000200537030020002007370308200041106a2006370300200241106a24000f0b41eff0c2004133200241086a4184f4c2001053000bc60901077f23004190016b220124000240024002400240410e10292202450d00200241002900d9e743370000200241066a41002900dfe7433700002001428e808080e00137026c200120023602682000200141e8006a104a200128026c21032001280270210420012802682102200141e8006a41186a22054200370300200141e8006a41106a22064200370300200141e8006a41086a220742003703002001420037036820022004200141e8006a1000200141c8006a41186a2005290300370300200141c8006a41106a2006290300370300200141c8006a41086a200729030037030020012001290368370348200141e8006a200141c8006a412010dc010240024020012d00684101470d00200141c8006a41201006200141086a41186a20014181016a290000370300200141086a41106a200141f9006a290000370300200141086a41086a200141f1006a2900003703002001200129006937030802402003450d002002102e0b200141286a41186a200141086a41186a290300370300200141286a41106a200141086a41106a290300370300200141286a41086a200141086a41086a29030037030020012001290308370328410e10292202450d03200241002900b1e843370000200241066a41002900b7e8433700002001428e808080e00137026c20012002360268200141286a200141e8006a104a200128026c21032001280270210420012802682102200141e8006a41186a22054200370300200141e8006a41106a22064200370300200141e8006a41086a220742003703002001420037036820022004200141e8006a1000200141c8006a41186a2005290300370300200141c8006a41106a2006290300370300200141c8006a41086a200729030037030020012001290368370348200141c8006a412010062003450d012002102e0c010b2003450d002002102e0b410d10292202450d02200241002900bfe843370000200241056a41002900c4e8433700002001428d808080d00137026c200120023602682000200141e8006a104a200128026c21032001280270210420012802682102200141e8006a41186a22054200370300200141e8006a41106a22064200370300200141e8006a41086a220742003703002001420037036820022004200141e8006a1000200141c8006a41186a2005290300370300200141c8006a41106a2006290300370300200141c8006a41086a200729030037030020012001290368370348200141c8006a4120100602402003450d002002102e0b411210292202450d03200241002900cce843370000200241106a41002f00dce8433b0000200241086a41002900d4e84337000020014292808080a00237026c200120023602682000200141e8006a104a200128026c21032001280270210420012802682102200141e8006a41186a22054200370300200141e8006a41106a22064200370300200141e8006a41086a220742003703002001420037036820022004200141e8006a1000200141c8006a41186a2005290300370300200141c8006a41106a2006290300370300200141c8006a41086a200729030037030020012001290368370348200141c8006a4120100602402003450d002002102e0b200010db03200010dc0320014190016a24000f0b410e4101102c000b410e4101102c000b410d4101102c000b41124101102c000bd60a050a7f027e037f027e017f230041e0006b220224002002410036023820014120200241386a1008210302400240024002400240024002400240024020022802382204417f460d0020030d010b200041023a00000c010b20022004360214200220033602102004450d0520032d0000210120022004417f6a3602142002200341016a360210200141014b0d0502400240024020010e020001000b200241086a200241106a103120022802080d072002280214200228020c2205490d072005417f4c0d030240024020050d004101210641010d010c090b200510342206450d09200620022802102201200510f6042104200228021422072005490d052002200720056b3602142002200120056a3602102004450d080b200228021422084104490d0520022802102209280000210a20022008417c6a220b3602142002200941046a36021041002101200241003a0058417b210703400240200b2001470d000240200141ff0171450d00200241003a00580b20050d080c090b200241386a20016a200920016a220441046a2d00003a00002002200820076a3602142002200441056a3602102002200141016a22043a00582007417f6a21072004210120044120470d000b2002200228003b36003320022002280238360230200220022802303602282002200228003336002b0240024002400240200820046b2207417c6a4110490d00200241c7006a290000210c200229003f210d200228004f210b2002280053210e20022d0057210f2002200920046a220141146a220936021020022007416c6a221036021420104104490d002001410c6a2900002111200141046a2900002112200928000021092002200741686a3602142002200141186a2210360210200841686a2004460d0320102d000021102002200741676a22133602142002200141196a360210201041014b0d034100210420100e020201020b20050d090c0a0b20134104490d01200141196a28000021082002200741636a36021420022001411d6a360210410121040b2002200228002b3600232002200228022836022020022002280220360230200220022800233600332002200228001936023820022002411c6a28000036003b41002101200521070c020b2005450d070c060b41002101200241003a00582004417f6a21082004417e6a21040340024020082001470d00200141ff0171450d08200241003a00580c080b200241386a20016a200320016a220741016a2d00003a00002002200741026a3602102002200141016a22073a0058200220043602142004417f6a21042007210120074120470d000b2002200228003b360033200220022802383602302002200228003336002b20022002280230360228200220022802283602202002200228002b360023200241c7006a2900002111200229003f2112200228004f21062002280053210720022d005721052002200228002336003b2002200228022036023820022002411c6a28000036003320022002280019360230410121010b200020013a000020002002280238360001200041106a2011370300200041086a2012370300200041c3006a200c3700002000413b6a200d370000200041046a200228003b360000200041306a20083602002000412c6a2004360200200041286a2009360200200041246a200a360200200041206a20053602002000411c6a2007360200200041186a2006360200200041346a2002280230360200200041376a2002280033360000200041d3006a200f3a0000200041cf006a200e360000200041cb006a200b3600002003102e0b200241e0006a24000f0b1032000b200520071035000b2005450d010b2006102e0b41eff0c2004133200241286a4184f4c2001053000b20054101102c000bde0801067f230041c0006b220224000240024002400240024002400240024002400240411010292203450d00200341086a41002900b0f541370000200341002900a8f54137000020024290808080800237020420022003360200410d20021047024002400240024020022802042204200228020822056b410d490d002005410d6a2106200228020021030c010b2005410d6a22062005490d0120044101742203200620062003491b22074100480d010240024020040d002007102921030c010b200228020020042007102a21030b2003450d042002200736020420022003360200200721040b20022006360208200320056a220541002900e1f441370000200541056a41002900e6f441370000200241206a2003200610d70220022802282206417f4c0d04200228022021050240024020060d00410121070c010b200610292207450d0620072005200610f6041a0b02402004450d002003102e0b02402002280224450d002005102e0b410110292203450d06200320012d00003a0000200341014102102a2203450d07200320012d00013a0001200341024104102a2203450d08200320012d00023a0002200320012d00033a0003200341044108102a2203450d09200320012d00043a0004200320012d00053a0005200320012d00063a0006200320012d00073a0007200341084110102a2203450d0a200320012d00083a0008200320012d00093a0009200320012d000a3a000a200320012d000b3a000b200320012d000c3a000c200320012d000d3a000d200320012d000e3a000e200320012d000f3a000f200341104120102a2203450d0b200320012d00103a0010200320012d00113a0011200320012d00123a0012200320012d00133a0013200320012d00143a0014200320012d00153a0015200320012d00163a0016200320012d00173a0017200320012d00183a0018200320012d00193a0019200320012d001a3a001a200320012d001b3a001b200320012d001c3a001c200320012d001d3a001d200320012d001e3a001e200320012d001f3a001f200241206a41186a22014200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034120200241206a1000200241186a2001290300370300200241106a2004290300370300200241086a200529030037030020022002290320370300200641206a22012006490d0020064101742204200120012004491b22054100480d000240024020060d002005102921040c010b200720062005102a21040b20040d0120054101102c000b102d000b200420066a22062002290300370000200641186a200241186a290300370000200641106a200241106a290300370000200641086a200241086a2903003700002003102e200020013602082000200536020420002004360200200241c0006a24000f0b41104101102c000b20074101102c000b1032000b20064101102c000b41014101102c000b41024101102c000b41044101102c000b41084101102c000b41104101102c000b41204101102c000b8b0701077f23004190026b2202240041002103200241003a002820012802042104417f210502400240034020042003460d01200241086a20036a200128020022062d00003a00002001200420056a3602042001200641016a3602002002200341016a22073a00282005417f6a21052007210320074120470d000b200241e8006a41086a200241086a41086a290300370300200241e8006a41106a200241086a41106a290300370300200241e8006a41186a200241086a41186a2903003703002002200229030837036841002103200241003a0028200420076b2108200420056a21050340024020082003470d000240200341ff0171450d00200241003a00280b200041013a00000c030b200241086a20036a200620036a220741016a2d00003a0000200120053602042001200741026a3602002002200341016a22073a00282005417f6a21052007210320074120470d000b20024188016a41086a200241086a41086a29030037030020024188016a41106a200241086a41106a29030037030020024188016a41186a200241086a41186a290300370300200220022903083703880141002103200241003a008802200620076a2106034002402005417f470d000240200341ff0171450d00200241003a0088020b200041013a00000c030b200241e8016a20036a200620036a220741016a2d00003a0000200120053602042001200741026a3602002002200341016a22073a0088022005417f6a21052007210320074120470d000b200241a8016a41086a2201200241e8016a41086a290300370300200241a8016a41106a2203200241e8016a41106a290300370300200241a8016a41186a2205200241e8016a41186a290300370300200241086a41086a200241e8006a41086a290300370300200241086a41106a200241e8006a41106a290300370300200241086a41186a200241e8006a41186a290300370300200220022903e8013703a80120022002290368370308200241c0006a20024188016a41186a290300370300200241386a20024188016a41106a290300370300200241306a20024188016a41086a2903003703002002200229038801370328200241e0006a2005290300370300200241d8006a2003290300370300200241d0006a2001290300370300200220022903a801370348200041016a200241086a41e00010f6041a200041003a00000c010b0240200341ff0171450d00200241003a00280b200041013a00000b20024190026a24000ba60a01097f230041c0006b220224000240024002400240024002400240024002400240411010292203450d00200341086a41002900b19342370000200341002900a9934237000020024290808080800237020420022003360200410d20021047024002400240024020022802042204200228020822056b410d490d002005410d6a2106200228020021030c010b2005410d6a22062005490d0120044101742203200620062003491b22074100480d010240024020040d002007102921030c010b200228020020042007102a21030b2003450d042002200736020420022003360200200721040b20022006360208200320056a220541002900e1f441370000200541056a41002900e6f441370000200241206a2003200610d70220022802282206417f4c0d04200228022021050240024020060d00410121080c010b200610292208450d0620082005200610f6041a0b02402004450d002003102e0b02402002280224450d002005102e0b2001410c6a28020041046a2204417f4c0d04024002402004450d00200410292203450d0820024100360228200220043602240c010b200241003602282002200436022420024101360220410110292203450d08200241013602240b2002200336022020024101360228200320012d00003a00000240200228022422044101470d0041000d014102410241024102491b22044100480d01200341012004102a2203450d0920022004360224200220033602200b20024102360228200320012d00013a00010240024020044102460d00200421050c010b200441016a22052004490d0120044101742207200520052007491b22054100480d010240024020040d002005102921030c010b200320042005102a21030b2003450d0a20022005360224200220033602200b20024103360228200341026a20012d00023a0000024020054103470d00200541016a22042005490d0120054101742207200420042007491b22044100480d010240024020050d002004102921030c010b200320052004102a21030b2003450d0b20022004360224200220033602200b20024104360228200341036a20012d00033a000020012802042107200128020c2201200241206a10470240024020022802242205200228022822046b2001490d00200228022021030c010b200420016a22032004490d0120054101742209200320032009491b22094100480d010240024020050d002009102921030c010b200228022020052009102a21030b2003450d0c2002200936022420022003360220200921050b200320046a2007200110f6041a200241206a41186a22074200370300200241206a41106a22094200370300200241206a41086a220a4200370300200242003703202003200420016a200241206a1000200241186a2007290300370300200241106a2009290300370300200241086a200a29030037030020022002290320370300200641206a22012006490d0020064101742204200120012004491b22074100480d000240024020060d002007102921040c010b200820062007102a21040b20040d0120074101102c000b102d000b200420066a22062002290300370000200641186a200241186a290300370000200641106a200241106a290300370000200641086a200241086a29030037000002402005450d002003102e0b200020013602082000200736020420002004360200200241c0006a24000f0b41104101102c000b20074101102c000b1032000b20064101102c000b20044101102c000b41014101102c000b20044101102c000b20054101102c000b20044101102c000b20094101102c000b8d0302047f037e230041306b2205240002400240411410292206450d00200641002900d88c40370000200641106a41002800e88c40360000200641086a41002900e08c4037000020054294808080c002370224200520063602202001200541206a104a20052802242106200541086a200528022022072005280228106e200541086a41106a2903004200200528020822081b21092005290310420020081b210a02402006450d002007102e0b410121060240200a20027d220b200a56200920037d200a200254ad7d220a200956200a2009511b4101470d002000418b8cc000360204200041086a411d3602000c020b024002400240200b428080e983b1de16544100200a501b0d00200520012004200b200a105620052802002206450d022005280204210120002006360204200041086a20013602000c010b200041a88cc000360204200041086a411a3602000b410121060c020b2001200b200a1073200041106a2003370300200041086a2002370300410021060c010b41144101102c000b20002006360200200541306a24000bd40602087f087e23004190016b220224000240024002400240411010292203450d0041002104200341002900b08f40370000200341086a41002900b88f40370000200242908080808002370274200220033602702001200241f0006a104a200228027421052002280278210320022802702106200241f0006a41186a22074200370300200241f0006a41106a22084200370300200241f0006a41086a220942003703002002420037037020062003200241f0006a1000200241d0006a41186a2007290300370300200241d0006a41106a2008290300370300200241d0006a41086a20092903003703002002200229037037035020024100360270200241d0006a4120200241f0006a1008210320022802702207417f460d022003450d0220074110490d0120074170714110460d012007417c714120460d01200341086a290000210a2003290000210b200341186a290000210c2003290010210d200328002021072003102e410121040c030b41104101102c000b41eff0c2004133200241f0006a4184f4c2001053000b0b02402005450d002006102e0b4200210e4200210f024002402004450d00411410292203450d01200341002900d88c40370000200341106a41002800e88c40360000200341086a41002900e08c4037000020024294808080c002370274200220033602702001200241f0006a104a20022802742106200241386a200228027022012002280278106e200241386a41106a290300210e42002110200228023821032002290340211102402006450d002001102e0b200e420020031b210f2011420020031b2111200241306a41b0f3c200410d107d200241106a200c420041002002280234410020022802301b220320076b2206200620034b1bad220e420010fb04200241206a200e4200200d420010fb04200242004200200d420010fb044200210e02402002290308200229031884420052200241206a41086a290300220c200229030020022903107c7c220d200c54720d00200a200d20022903202210200b54200d200a54200d200a511b22031b200d7d200b201020031b220d201054ad7d210e200d20107d21100b200e200f2011201056200f200e56200f200e511b22031b210f2010201120031b210e0b2000200e3703002000200f37030820024190016a24000f0b41144101102c000ba907030d7f037e037f230041e0006b22022400024002400240024002400240410e10292203450d00200341002900848d40370000200341066a410029008a8d403700002002428e808080e001370244200220033602402001200241c0006a104a200228024421042002280248210320022802402105200241c0006a41186a22014200370300200241c0006a41106a22064200370300200241c0006a41086a220742003703002002420037034020052003200241c0006a1000200241086a41186a2001290300370300200241086a41106a2006290300370300200241086a41086a20072903003703002002200229034037030820024100360240200241086a4120200241c0006a100821080240024020022802402209417f460d002002200936022c200220083602282002200241286a103120022802000d07200228022c22034160712201417f4c0d032002280204210a024002402003410576220b0d004108210c0c010b20011029220c450d050b0240200a450d004100210d4100210e410021070340200241c0006a200241286a107e0240024020022d00404101460d00200228022c22014110490d002002290041210f20022002280228220341106a3602282002200141706a220636022c20064104490d00200341086a29000021102003290000211120022001416c6a220636022c2002200341146a36022820060d010b200b450d0a200c102e0c0a0b200741016a210620032800102112200241366a41026a2002413d6a41026a2d000022133a0000200241326a41026a221420133a000020022001416b6a36022c2002200341156a360228200220022f003d22013b0136200220013b013220032d0014210102402007200b470d00200d20062006200d491b220b41ffffff3f71200b470d09200b41057422034100480d090240024020070d0020031029210c0c010b200c200e2003102a210c0b200c450d080b200c200e6a2203411c6a20013a00002003201037030820032011370300200341146a200f370200200341106a20123602002003411d6a20022f01323b00002003411f6a20142d00003a0000200d41026a210d200e41206a210e20062107200a2006470d000b0b200c450d07200aad422086200bad84210f02402009450d002008102e0b2000200f3702042000200c3602000c010b20004100360208200042083702000b02402004450d002005102e0b200241e0006a24000f0b410e4101102c000b1032000b20014108102c000b20034108102c000b102d000b41eff0c2004133200241c0006a4184f4c2001053000bbd0101027f230041206b22032400200341106a41086a220442003703002003420037031020012002200341106a1003200341086a200429030037030020032003290310370300410021022003410036021020034110200341106a1008210102400240024020032802102204417f470d000c010b024020010d000c010b20044104490d01200128000021042001102e410121020b2000200436020420002002360200200341206a24000f0b41eff0c2004133200341106a4184f4c2001053000bf00204027f017e017f077e0240024020012802042202450d0020012802002203310000210420012002417f6a22053602042001200341016a3602002005450d012003310001210620012002417e6a22053602042001200341026a3602002005450d012003310002210720012002417d6a22053602042001200341036a3602002005450d012003310003210820012002417c6a22053602042001200341046a3602002005450d012003310004210920012002417b6a22053602042001200341056a3602002005450d012003310005210a20012002417a6a22053602042001200341066a3602002005450d012003310006210b2001200241796a22053602042001200341076a3602002005450d01200041003a00002003310007210c2001200241786a3602042001200341086a3602002000200c423886200b42308684200a422886842009422086842008421886842007421086842006420886842004843700010f0b200041013a00000f0b200041013a00000b971d05047f017e057f017e037f23004190056b2200240020004198036a41086a22014200370300200042003703980341c8dec500411020004198036a1003200041a0026a41086a200129030037030020002000290398033703a0022000410036029004200041a0026a411020004190046a10082101024002400240024002400240024002400240024002402000280290042202417f460d002001450d002002450d0120012d000021022001102e20024102460d0020024101710d030b200041013a00900420004198036a41086a22014200370300200042003703980341c8dec500411020004198036a1003200041a0026a41086a2202200129030037030020002000290398033703a002200041a0026a411020004190046a4101100420014200370300200042003703980341d2f3c200410d20004198036a10032002200129030037030020002000290398033703a0022000410036029004200041a0026a411020004190046a1008210102402000280290042202417f460d002001450d002000200236029c03200020013602980320004190046a20004198036a103f02402000280290042203450d00200029029404210402402002450d002001102e0b2004422088a721052004a721060c030b41eff0c200413320004188056a4184f4c2001053000b4104210341002105410021060c010b41eff0c200413320004188056a4184f4c2001053000b2003200541246c22026a210720032101024002400240200241ed00490d0020004190046a41017221082003210103400240024020012d00004101460d00200041a8016a200041a0026a41f70010f6041a0c010b200141016a2800002102200141086a28020021092000200141106a28020036028c01200020093602880102400240200241c28289aa04460d00410221020c010b20004190046a20004188016a108001024020002d00900422024102470d00410221020c010b20004198036a200841f70010f6041a200041a0026a20004198036a41f70010f6041a0b200041a8016a200041a0026a41f70010f6041a20024102460d00200041a8016a21010c030b02400240200141246a2d00004101460d00200041a8016a200041a0026a41f70010f6041a0c010b200141256a28000021022001412c6a28020021092000200141346a28020036028c01200020093602880102400240200241c28289aa04460d00410221020c010b20004190046a20004188016a108001024020002d00900422024102470d00410221020c010b20004198036a200841f70010f6041a200041a0026a20004198036a41f70010f6041a0b200041a8016a200041a0026a41f70010f6041a20024102460d00200041a8016a21010c030b02400240200141c8006a2d00004101460d00200041a8016a200041a0026a41f70010f6041a0c010b200141c9006a2800002102200141d0006a28020021092000200141d8006a28020036028c01200020093602880102400240200241c28289aa04460d00410221020c010b20004190046a20004188016a108001024020002d00900422024102470d00410221020c010b20004198036a200841f70010f6041a200041a0026a20004198036a41f70010f6041a0b200041a8016a200041a0026a41f70010f6041a20024102460d00200041a8016a21010c030b02400240200141ec006a2d00004101460d00200041a8016a200041a0026a41f70010f6041a0c010b200141ed006a2800002102200141f4006a28020021092000200141fc006a28020036028c01200020093602880102400240200241c28289aa04460d00410221020c010b20004190046a20004188016a108001024020002d00900422024102470d00410221020c010b20004198036a200841f70010f6041a200041a0026a20004198036a41f70010f6041a0b200041a8016a200041a0026a41f70010f6041a20024102460d00200041a8016a21010c030b200720014190016a22016b41ec004b0d000b0b024020012007460d002003200541246c6a210720004190046a410172210803400240024020012d00004101460d00200041a8016a200041a0026a41f70010f6041a0c010b200141016a2800002102200141086a28020021092000200141106a28020036028c01200020093602880102400240200241c28289aa04460d00410221020c010b20004190046a20004188016a108001024020002d00900422024102470d00410221020c010b20004198036a200841f70010f6041a200041a0026a20004198036a41f70010f6041a0b200041a8016a200041a0026a41f70010f6041a20024102460d00200041a8016a21010c030b2007200141246a2201470d000b0b02402005450d00200541246c21022003210103400240024020012d0000220741034b0d0002400240024020070e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012002415c6a22020d000b0b20060d010c020b200020012900003703782000200141076a29000037007f200129000f2104200041206a200141176a41d80010f6041a200129006f210a20002000290378370388012000200029007f37008f0120004190046a200041206a41d80010f6041a200041106a41a9ddc5004113108101024002402000290318500d0020002802100d010b20004198036a41086a22014200370300200042003703980341a9ddc500411320004198036a1003200041a0026a41086a200129030037030020002000290398033703a00220002004200a20024101461b37039803200041a0026a411020004198036a410810040b20004198036a41086a22014200370300200042003703980341bcddc500411020004198036a1003200041a0026a41086a200129030037030020002000290398033703a00220002004200a20024101461b37039803200041a0026a411020004198036a41081004024020020d0020004198016a41086a20004190046a41086a2d00003a000020002000290388013703a8012000200029008f013700af01200020002903900437039801200041086a41a1dec5004111107d20002802082107200028020c2109411610292201450d032001410e6a41002900c0de45370000200141086a41002900bade45370000200141002900b2de4537000020014116412c102a2202450d0420022009410020071b220836001620004198036a41186a2207420037030020004198036a41106a2209420037030020004198036a41086a2201420037030020004200370398032002411a20004198036a1000200041a0026a41186a2007290300370300200041a0026a41106a2009290300370300200041a0026a41086a200129030037030020002000290398033703a00220004198036a200041a0026a108201200128020021092000280298032101200028029c0321072002102e2007410020011b21072001410120011b2102024002402009410020011b2201418002490d00412010292201450d07200120002903a8013700002001200437000f2001200029039801370017200141076a20002900af013700002001411f6a20004198016a41086a2d00003a0000411610292209450d082009410e6a41002900c0de45370000200941086a41002900bade45370000200941002900b2de4537000020094116412c102a2209450d092009200841016a220b36001620004198036a41186a220c420037030020004198036a41106a220d420037030020004198036a41086a2208420037030020004200370398032009411a20004198036a1000200041a0026a41186a200c290300370300200041a0026a41106a200d290300370300200041a0026a41086a220c200829030037030020002000290398033703a00220004198036a20014101108301200041a0026a4120200028029803220d20002802a00310040240200028029c03450d00200d102e0b2009102e2001102e20084200370300200042003703980341a1dec500411120004198036a1003200c200829030037030020002000290398033703a0022000200b36029803200041a0026a411020004198036a410410040c010b200041a0026a41086a220b20004198016a41086a2d00003a0000200020002903a80137039803200020002900af0137009f0320002000290398013703a002200141016a2109024020072001470d00024020014101742207200920092007491b2207410574220c4100480d000240024020010d00200c102921020c010b20022001410574200c102a21020b20020d01200c4101102c000b102d000b200220014105746a2201200029039803370000200029009f03210a2001200437000f200141076a200a370000200120002903a0023700172001411f6a200b2d00003a0000411610292201450d092001410e6a41002900c0de45370000200141086a41002900bade45370000200141002900b2de4537000020014116412c102a2201450d0a2001200836001620004198036a41186a2208420037030020004198036a41106a220b420037030020004198036a41086a220c420037030020004200370398032001411a20004198036a1000200041a0026a41186a2008290300370300200041a0026a41106a200b290300370300200041a0026a41086a200c29030037030020002000290398033703a00220004198036a20022009108301200041a0026a4120200028029803220920002802a00310040240200028029c03450d002009102e0b2001102e0b2007450d002002102e0b02402005450d00200541246c21022003210103400240024020012d0000220741034b0d0002400240024020070e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012002415c6a22020d000b0b2006450d010b2003102e0b20004190056a24000f0b41164101102c000b412c4101102c000b41204101102c000b41164101102c000b412c4101102c000b41164101102c000b412c4101102c000bb30a03067f017e067f230041f0016b2202240002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200200541014b0d0420050e020102010b200041023a00000c070b20064104490d012004280001210720012003417b6a22053602042001200441056a36020020054108490d05200429000521082001200341736a220536020420012004410d6a36020020054104490d04200428000d210920012003416f6a3602042001200441116a36020041002105200241003a00b001411120036b210a2003416e6a210603400240200a20056a0d000240200541ff0171450d00200241003a00b0010b200041023a00000c080b20024190016a20056a200420056a220b41116a2d00003a0000200120063602042001200b41126a3602002002200541016a220b3a00b0012006417f6a2106200b2105200b4120470d000b200241f0006a41186a20024190016a41186a290300370300200241f0006a41106a20024190016a41106a290300370300200241f0006a41086a20024190016a41086a290300370300200220022903900137037041002105200241003a00d0012004200b6a210a200b20036b41116a210303400240200320056a0d000240200541ff0171450d00200241003a00d0010b200041023a00000c080b20024190016a20056a200a20056a220441116a2d00003a0000200120063602042001200441126a3602002002200541016a22043a00d0012006417f6a210620042105200441c000470d000b200241106a41386a220120024190016a41386a290300370300200241106a41306a220420024190016a41306a290300370300200241106a41286a220520024190016a41286a290300370300200241106a41206a220320024190016a41206a290300370300200241106a41186a220620024190016a41186a290300370300200241106a41106a220b20024190016a41106a290300370300200241106a41086a220a20024190016a41086a290300370300200241d0006a41086a220c200241f0006a41086a290300370300200241d0006a41106a220d200241f0006a41106a290300370300200241d0006a41186a220e200241f0006a41186a290300370300200220022903900137031020022002290370370350200041003a000020002002290350370001200041096a200c290300370000200041116a200d290300370000200041196a200e290300370000200041216a2002290310370000200041296a200a290300370000200041316a200b290300370000200041396a2006290300370000200041c1006a2003290300370000200041c9006a2005290300370000200041d1006a2004290300370000200041d9006a2001290300370000200041e3006a2002410f6a2d00003a0000200041e1006a20022f000d3b0000200041f0006a2008370300200041e8006a2009360200200041e4006a20073602000c060b20064104490d022004280001210620012003417b6a22053602042001200441056a36020020054108490d02200429000521082001200341736a220536020420012004410d6a36020020054104490d02200428000d210520012003416f6a3602042001200441116a360200200041013a0000200020022f00103b0001200041106a2008370300200041086a2005360200200041046a2006360200200041036a200241126a2d00003a0000200041186a20024190016a41e00010f6041a0c050b200041023a00000c040b200041023a00000c030b200041023a00000c020b200041023a00000c010b200041023a00000b200241f0016a24000bc30104017f017e017f017e230041206b2203240042002104200341106a41086a220542003703002003420037031020012002200341106a1003200341086a2005290300370300200320032903103703002003410036021020034110200341106a1008210102400240024020032802102202417f470d000c010b024020010d000c010b20024108490d01200129000021062001102e420121040b2000200637030820002004370300200341206a24000f0b41eff0c2004133200341106a4184f4c2001053000b8505010e7f230041e0006b220224002002410036023820014120200241386a1008210302400240024002400240024020022802382204417f470d00200041003602000c010b2002200436021420022003360210200241086a200241106a103120022802080d04200228021422054160712201417f4c0d01200228020c210602400240200541057622070d00410121080c010b200110292208450d030b02402006450d004100210903402005210a200241003a00582009220b41016a2109410021010240024002400340200a2001460d01200241386a20016a2002280210220c2d00003a00002002200c41016a3602102002200141016a220c3a0058200c2101200c4120470d000b200241186a41186a220d200241386a41186a290300370300200241186a41106a220e200241386a41106a290300370300200241186a41086a220f200241386a41086a290300370300200220022903383703182007200b470d020240200b4101742201200920092001491b220741ffffff3f712007470d002007410574220141004e0d020b102d000b200241003602140240200141ff0171450d00200241003a00580b2007450d082008102e0c080b02400240200b0d002001102921080c010b2008200b4105742001102a21080b2008450d060b200a200c6b21052008200b4105746a22012002290318370000200141186a200d290300370000200141106a200e290300370000200141086a200f29030037000020092006470d000b2002200a200c6b3602140b2008450d042000200736020420002008360200200041086a20063602002004450d002003102e0b200241e0006a24000f0b1032000b20014101102c000b20014101102c000b41eff0c2004133200241386a4184f4c2001053000ba72601047f230041106b22032400200341003602082003420137030020022003104702400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402002450d00200120024105746a2104034002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0320032006360204200320053602000b2003200241016a360208200520026a20012d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0420032006360204200320053602000b2003200241016a360208200520026a200141016a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0520032006360204200320053602000b2003200241016a360208200520026a200141026a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0620032006360204200320053602000b2003200241016a360208200520026a200141036a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0720032006360204200320053602000b2003200241016a360208200520026a200141046a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0820032006360204200320053602000b2003200241016a360208200520026a200141056a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0920032006360204200320053602000b2003200241016a360208200520026a200141066a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0a20032006360204200320053602000b2003200241016a360208200520026a200141076a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0b20032006360204200320053602000b2003200241016a360208200520026a200141086a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0c20032006360204200320053602000b2003200241016a360208200520026a200141096a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0d20032006360204200320053602000b2003200241016a360208200520026a2001410a6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0e20032006360204200320053602000b2003200241016a360208200520026a2001410b6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d0f20032006360204200320053602000b2003200241016a360208200520026a2001410c6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1020032006360204200320053602000b2003200241016a360208200520026a2001410d6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1120032006360204200320053602000b2003200241016a360208200520026a2001410e6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1220032006360204200320053602000b2003200241016a360208200520026a2001410f6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1320032006360204200320053602000b2003200241016a360208200520026a200141106a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1420032006360204200320053602000b2003200241016a360208200520026a200141116a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1520032006360204200320053602000b2003200241016a360208200520026a200141126a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1620032006360204200320053602000b2003200241016a360208200520026a200141136a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1720032006360204200320053602000b2003200241016a360208200520026a200141146a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1820032006360204200320053602000b2003200241016a360208200520026a200141156a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1920032006360204200320053602000b2003200241016a360208200520026a200141166a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1a20032006360204200320053602000b2003200241016a360208200520026a200141176a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1b20032006360204200320053602000b2003200241016a360208200520026a200141186a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1c20032006360204200320053602000b2003200241016a360208200520026a200141196a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1d20032006360204200320053602000b2003200241016a360208200520026a2001411a6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1e20032006360204200320053602000b2003200241016a360208200520026a2001411b6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d1f20032006360204200320053602000b2003200241016a360208200520026a2001411c6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d2020032006360204200320053602000b2003200241016a360208200520026a2001411d6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d2120032006360204200320053602000b2003200241016a360208200520026a2001411e6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006102921050c010b200328020020022006102a21050b2005450d2220032006360204200320053602000b2003200241016a360208200520026a2001411f6a2d00003a0000200141206a22012004470d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b102d000b820304037f017e017f037e230041c0006b2202240002400240411410292203450d00200341002900d88c40370000200341106a41002800e88c40360000200341086a41002900e08c4037000020024294808080c002370234200220033602302001200241306a104a20022802342103200241186a200228023022042002280238106e200241186a41106a2903002105200228021821062002290320210702402003450d002004102e0b411810292203450d012005420020061b21082007420020061b2107200341002900ec8c40370000200341106a41002900fc8c40370000200341086a41002900f48c40370000200242988080808003370234200220033602302001200241306a104a200228023421032002200228023022062002280238106e200241106a2903004200200228020022011b21092002290308420020011b210502402003450d002006102e0b2000200520077c22073703002000200920087c2007200554ad7c370308200241c0006a24000f0b41144101102c000b41184101102c000b8e0e06017f037e017f017e017f067e230041f0016b220724004200210842002109024020050d00200741a0016a2006ad42004280c8afa025420010fb04200741a8016a29030020072903a001220a4280a094a58d1d7c2208200a54ad7c21090b200741d0016a41086a22054200370300200742003703d00141e8e4c500411b200741d0016a1003200741b0016a41086a220b2005290300370300200720072903d0013703b00120074190016a200741b0016a1086012007280290012105200729039801210a2007418094ebdc033602b4012007200a420020051b220a200a423f87220c7c200c85220c200c428094ebdc037f220c4280ec94a37c7e7ca722053602b00120074180016a417f2004418094ebdc032004418094ebdc03491b2204417f417f2004ad200ca7417f200c428080808010541bad7e220ca7200c422088a71b2206200741b0016a2005418094ebdc034b4102746a28020022052004418094ebdc036e220d6c2005ad2004200d4180ec94a37c6c6aad7e428094ebdc0380a76a6a220520052006491b22056a220620062004491b4100200420056b2205200520044b1b200a4200551bad420042e807420010fb0441012104200741b0016a2003427f20082007290380017c220a20017c220c200c200a542205200920074180016a41086a2903007c200a200854ad7c220820027c2005ad7c220a200854200a2008511b22051b220e427f200a20051b220f4101107a0240024020072802b0014101470d00200041003a00010c010b200741b0016a41106a290300210a200741386a200b290300220242004204420010fb04200741286a420042002002420010fb04200741c8006a2007290338200741386a41086a2903002208200a42028620072903287c7c220c4205420010fc0420072903302109200741c8006a41086a290300210120072903482110200741b0016a108701200741f0006a200741b0016a42b3e6cc99b3e6cc99332010200a200a42ffffffffffffffff3f8352200942005272200c2008547222041b22082002200820025442b3e6cc99b3e6cc9933200120041b220c200a54200c200a511b22041b2208200c200a20041b220c106d200741f0006a41086a290300211020072903702109200741d8006a41c28cc00041161070200820097d200920087d20092008582010200c582010200c5122041b22051b2111200c20107d2008200954ad7d2010200c7d2009200854ad7d20051b2112200a200c7d2002200854ad7d2101200220087d210a200741d8006a41106a2903004200200728025822051b21022007290360420020051b21130240024020092008562010200c5620041b0d00200741e0016a41086a22044200370300200742003703e00141c28cc0004116200741e0016a1003200741d0016a41086a2004290300370300200720072903e0013703d00120074200200220127d2013201154ad7d2208201320117d220c201356200820025620082002511b22041b3703e80120074200200c20041b3703e001200741e0016a21040c010b200741e0016a41086a22044200370300200742003703e00141c28cc0004116200741e0016a1003200741d0016a41086a2004290300370300200720072903e0013703d0012007427f200220127c201320117c220c2013542204ad7c22082004200820025420082002511b22041b3703e8012007427f200c20041b3703e001200741e0016a21040b200741d0016a4110200441101004200741b0016a108801200741186a200741b0016a200a2001106d200741186a41086a290300210c20072903182108200741c28cc00041161070200a20087d2008200a7d2008200a58200c200158200c20015122041b22051b21102001200c7d200a200854ad7d200c20017d2008200a54ad7d20051b2113200741106a2903004200200728020022051b21092007290308420020051b2102024002402008200a56200c20015620041b0d00200741e0016a41086a22044200370300200742003703e00141c28cc0004116200741e0016a1003200741d0016a41086a2004290300370300200720072903e0013703d00120074200200920137d2002201054ad7d2208200220107d220a200256200820095620082009511b22041b3703e80120074200200a20041b3703e001200741e0016a21040c010b200741e0016a41086a22044200370300200742003703e00141c28cc0004116200741e0016a1003200741d0016a41086a2004290300370300200720072903e0013703d0012007427f200920137c200220107c220a2002542204ad7c22082004200820095420082009511b22041b3703e8012007427f200a20041b3703e001200741e0016a21040b200741d0016a4110200441101004200041306a41013a0000200041286a4200370300200041206a4280808080c000370300200041186a4204370300200041106a427f370300200041086a200e427f200f501b370300410021040b200020043a0000200741f0016a24000b820102027f027e230041106b220224002002410036020420014110200241046a100821010240024020022802042203417f460d002001450d00024020034108490d00200129000021042001102e420121050c020b41eff0c2004133200241086a4184f4c2001053000b420021050b2000200437030820002005370300200241106a24000bbf0301077f230041d0006b22012400024002400240024002400240410110292202450d00200241ed003a0000200241014102102a2202450d01200241ef003a0001200241024104102a2202450d02200241e4d8013b0002200241044108102a2202450d03200241f0f2bda107360004200241084110102a2203450d04200341f2e6c9cb07360008200141003a0048410c210220032104410021050340200141003a0008200141086a20042002410047220610f6041a024020020d00200141003a00080b20022006490d06200141286a20056a20012d00083a00002001200541016a22073a0048200220066b2102200420066a21042007210520074120470d000b200141086a41186a2202200141286a41186a290300370300200141086a41106a2206200141286a41106a290300370300200141086a41086a2204200141286a41086a290300370300200120012903283703082003102e200041186a2002290300370000200041106a2006290300370000200041086a200429030037000020002001290308370000200141d0006a24000f0b41014101102c000b41024101102c000b41044101102c000b41084101102c000b41104101102c000b200620021035000bee0b03047f017e057f230041c0016b22012400200141306a41086a220242003703002001420037033041eef4c1004111200141306a1003200141206a41086a200229030037030020012001290330370320200141c0006a200141206a411010dc010240024020012d00404101470d0020002001290041370000200041186a200141d9006a290000370000200041106a200141c0006a41116a290000370000200041086a200141c9006a2900003700000c010b200242003703002001420037033041d2f3c200410d200141306a1003200141c0006a41086a20022903003703002001200129033037034020014100360200200141c0006a411020011008210202400240024020012802002203417f460d002002450d0020012003360234200120023602302001200141306a103f20012802002204450d02200129020421052003450d012002102e0c010b41042104420021050b20042005422088a7220641246c6a210720042102024002400240034002400240200720026b41ed00490d0003400240200222032d00004101470d00200341246a2108200341106a2109200341086a210a200341016a21020c030b0240200341246a2d00004101470d00200341c8006a2108200341346a21092003412c6a210a200341256a21020c030b0240200341c8006a2d00004101470d00200341ec006a2108200341d8006a2109200341d0006a210a200341c9006a21020c030b0240200341ec006a2d00004101470d0020034190016a2108200341fc006a2109200341f4006a210a200341ed006a21020c030b200720034190016a22026b41ec004b0d000b20034190016a21020b20022007460d020240034020022d00004101460d012007200241246a2202460d040c000b0b200241246a2108200241106a2109200241086a210a200241016a21020b20022800002102200a280200210320012009280200360204200120033602000240200241c28289aa04460d00200821020c010b0b200141c0006a200110800120012d004022024102460d00200141a4016a28020021092001280244210a200141306a41086a220342003703002001420037033041fff4c1004112200141306a1003200141206a41086a20032903003703002001200129033037032020014100360240200141206a4110200141c0006a1008210720012802402203417f460d002001200336020420012007360200200141c0006a2001103020012802402208450d02200a200920024101711b2102200141c8006a28020021092001280244210a02402003450d002007102e0b0240200920024d0d00200141186a2203200820024105746a220241186a290000370300200141106a2207200241106a290000370300200141086a2209200241086a290000370300200120022900003703000240200a450d002008102e0b200141c0006a41186a22022003290300370300200141c0006a41106a22032007290300370300200141c0006a41086a2207200929030037030020012001290300370340200141306a41086a220942003703002001420037033041eef4c1004111200141306a1003200141206a41086a200929030037030020012001290330370320200141103602342001200141206a360230200141c0006a200141306a109a02200041186a2002290300370000200041106a2003290300370000200041086a2007290300370000200020012903403700000c020b200a450d002008102e0b20004200370000200041186a4200370000200041106a4200370000200041086a42003700000b02402006450d00200641246c21032004210203400240024020022d0000220741034b0d0002400240024020070e0404000102040b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022003415c6a22030d000b0b2005a7450d022004102e0c020b41eff0c2004133200141b8016a4184f4c2001053000b41eff0c2004133200141b8016a4184f4c2001053000b200141c0016a24000b1300200041023602042000418c90c0003602000b3400200041d8e9c10036020420004100360200200041146a4105360200200041106a41ac9fc000360200200041086a42083702000b3701017f02404110102922020d0041104101102c000b2002420037000820024200370000200042908080808002370204200020023602000bdb0a02077f027e230041e0016b220324000240024002400240411810292204450d00200441002900ec8c40370000200441106a41002900fc8c40370000200441086a41002900f48c40370000200342988080808003370254200320043602502000200341d0006a104a200328025421052003280258210620032802502104200341c0016a41186a22074200370300200341c0016a41106a22084200370300200341c0016a41086a22094200370300200342003703c00120042006200341c0016a1000200341d0006a41186a2007290300370300200341d0006a41106a2008290300370300200341d0006a41086a2009290300370300200320032903c001370350200320023703c801200320013703c001200341d0006a4120200341c0016a4110100402402005450d002004102e0b0240200142ffffe883b1de165620024200522002501b0d00411810292204450d02200441002900ec8c40370000200441106a41002900fc8c40370000200441086a41002900f48c40370000200342988080808003370254200320043602502000200341d0006a104a200328025421052003280258210620032802502104200341c0016a41186a22074200370300200341c0016a41106a22084200370300200341c0016a41086a22094200370300200342003703c00120042006200341c0016a1000200341d0006a41186a2007290300370300200341d0006a41106a2008290300370300200341d0006a41086a2009290300370300200320032903c001370350200341386a200341d0006a1074200341386a41106a2903002101200329034021022003280238210602402005450d002004102e0b02402002200184500d002006450d00200341206a41c28cc00041161070200341206a41106a290300210a2003290328210b20032802202104200341d0006a41086a220542003703002003420037035041c28cc0004116200341d0006a1003200341c0016a41086a2005290300370300200320032903503703c00120034200200a420020041b220a20017d200b420020041b2201200254ad7d220b200120027d2202200156200b200a56200b200a511b22041b37035820034200200220041b370350200341c0016a4110200341d0006a411010040b411410292204450d03200441002900d88c40370000200441106a41002800e88c40360000200441086a41002900e08c4037000020034294808080c002370254200320043602502000200341d0006a104a20032802542104200341086a200328025022062003280258106e200341086a41106a2903002102200329031021012003280208210502402004450d002006102e0b02402001200284500d0020050d010b411310292204450d04200441002900eff3423700002004410f6a41002800fef342360000200441086a41002900f7f34237000020034293808080b002370254200320043602502000200341d0006a104a200328025421052003280258210620032802502104200341c0016a41186a22074200370300200341c0016a41106a22084200370300200341c0016a41086a22094200370300200342003703c00120042006200341c0016a1000200341d0006a41186a2007290300370300200341d0006a41106a2008290300370300200341d0006a41086a22062009290300370300200320032903c001370350200341d0006a4120100602402005450d002004102e0b200641013a0000200341d9006a2000290000370000200341e1006a200041086a290000370000200341e9006a200041106a290000370000200341f1006a200041186a290000370000200341023a005041c8ecc5004100200341d0006a10720b200341e0016a24000f0b41184101102c000b41184101102c000b41144101102c000b41134101102c000b130020004105360204200041c8b0c0003602000baf0202057f037e230041c0006b22042400200441206a20011084010240024002402004290320200441206a41086a29030084500d00411410292205450d0241002106200541002900d88c40370000200541106a41002800e88c40360000200541086a41002900e08c4037000020044294808080c002370234200420053602302001200441306a104a20042802342105200441086a200428023022072004280238106e200441086a41106a2903004200200428020822081b21092004290310420020081b210a02402005450d002007102e0b2001200a20027c220b200920037c200b200a54ad7c1073200041106a2003370300200041086a20023703000c010b200041e98bc000360204200041086a4122360200410121060b20002006360200200441c0006a24000f0b41144101102c000b851507037f017e067f037e017f027e0a7f230041e0006b22032400200341b0f3c200410d107d2003280204210420032802002105200341186a427f3703002003412c6a41023a0000200341206a2002360200200341246a20002900003702002003427f3703104201210620034201370308200341c0006a2001107c41002107200328024021082003280244210902400240024002402003280248220a450d002004410020051b210502400240200341d4006a220b2000460d00200341dd006a210c200a410574210442012106200821020340200241086a290300210d200241106a290300210e2002290300210f200341c0006a41186a200241186a290300370300200341c0006a41106a200e370300200341c0006a41086a200d3703002003200f37034002400240200b2900002000290000510d002003280250221020054d0d012003413c6a41026a200c41026a2d00003a00002003200c2f00003b013c200241206a2102200341c8006a290300210e2003290340210f20032d005c21070c060b2003290308210d4200210620034200370308200d4201520d00200341086a41106a2903002111200341086a41086a2903002112200241206a2102200341086a41186a290300a7210b0c030b200241206a2102200441606a22040d000c030b0b200a4105742104200341086a41106a2903002111200341086a41086a2903002112200341086a41186a280200210b200329030821062008210202400340200241086a290300210d200241106a290300210e2002290300210f200341c0006a41186a200241186a290300370300200341c0006a41106a200e370300200341c0006a41086a200d3703002003200f3703402003420037030820064201510d01200241206a2102420021064100210b4200211242002111200441606a22040d000c030b0b200241206a21020b200341c8006a290300220620112003290340220d201256200620115620062011511b22041b210e200d201220041b210f20032802502204200b2004200b4b1b211020032d005c2003412c6a2d0000722107420021060c010b024020090d00410021104108210b410821020c020b2008102e4108210b41002110410821020c010b2003290254210d200341306a41026a22042003413c6a41026a2d00003a0000200320032f013c3b01300240024002400240024041201029220b450d00200b200f370300200b20073a001c200b200d370214200b2010360210200b20032f01303b001d200b200e370308200b411f6a20042d00003a000041012107024020022008200a4105746a2204470d00410121100c050b200341d4006a22102000460d01200341dd006a210c0340200341c0006a41186a200241186a290300370300200341c0006a41106a200241106a290300370300200341c0006a41086a200241086a290300370300200320022903003703400240024020102900002000290000510d002003280250220a20054d0d012003413c6a41026a200c41026a2d00003a00002003200c2f00003b013c200241206a2102200341c8006a290300210d2003290340210e20032d005c21130c060b2003290308210d4200210620034200370308200d4201520d00200341086a41106a290300210d200341086a41086a2903002106200241206a2102200341086a41186a290300a721100c040b2004200241206a2202470d000b410121100c040b41204108102c000b20032903084201512107200341086a41106a290300210d200341086a41086a2903002106200341086a41186a280200211002400340200341c0006a41186a200241186a290300370300200341c0006a41106a200241106a290300370300200341c0006a41086a200241086a290300370300200320022903003703402003420037030820074101710d0142002106410021074200210d410021102004200241206a2202470d000b41012107410121100c030b200241206a21020b200341c8006a290300220e200d2003290340220f200656200e200d56200e200d511b22071b210d200f200620071b210e200328025022072010200720104b1b210a20032d005c2003412c6a2d0000722113420021060b2003290254210f200341346a41026a22142003413c6a41026a22152d00003a0000200320032f013c3b0134200341dd006a2116200341d4006a210c200341086a41106a2117200341086a41086a2118200341086a41186a21192003412c6a211a41012107410121100340200341c0006a41026a221b20142d00003a0000200320032f01343b01400240024002400240024020102007470d00200741016a22102007490d082007410174221c20102010201c491b221041ffffff3f712010470d082010410574221c4100480d080240024020070d00201c1029210b0c010b200b2007410574201c102a210b0b200b450d010b200b20074105746a221c20133a001c201c200d370308201c200e370300201c200f370214201c200a360210201c20032f01403b001d201c411f6a201b2d00003a0000200741016a210720022004460d050240200c2000470d002017290300210d2018290300210e2019280200210a200329030821060340200341c0006a41186a200241186a290300370300200341c0006a41106a200241106a290300370300200341c0006a41086a200241086a290300370300200320022903003703402003420037030820064201510d03420021064100210a4200210e4200210d2004200241206a2202470d000c070b0b0340200341c0006a41186a200241186a290300370300200341c0006a41106a200241106a290300370300200341c0006a41086a221c200241086a2903003703002003200229030037034002400240200c2900002000290000510d002003280250220a20054d0d012015201641026a2d00003a0000200320162f00003b013c200241206a2102201c290300210d2003290340210e20032d005c21130c060b2003290308210d4200210620034200370308200d4201520d002017290300210d2018290300210e200241206a21022019290300a7210a0c040b2004200241206a2202470d000c060b0b201c4108102c000b200241206a21020b200341c0006a41086a2903002206200d2003290340220f200e562006200d562006200d511b221c1b210d200f200e201c1b210e2003280250221c200a201c200a4b1b210a20032d005c201a2d0000722113420021060b2003290254210f201420152d00003a0000200320032f013c3b01340c000b0b02402009450d002008102e0b200b21020b0240024020064201520d00200341c0006a41186a200341106a220041186a290300370300200341c0006a41106a200041106a290300370300200341c0006a41086a200041086a29030037030020032000290300370340024020102007470d00200741016a22022007490d0320074101742200200220022000491b221041ffffff3f712010470d03201041057422004100480d030240024020070d002000102921020c010b200b20074105742000102a21020b2002450d020b200220074105746a22002003290340370300200041186a200341c0006a41186a290300370300200041106a200341c0006a41106a290300370300200041086a200341c0006a41086a290300370300200741016a21070b2003200736024820032010360244200320023602402001200341c0006a109001200341e0006a24000f0b20004108102c000b102d000bcd1003097f027e027f230041c0006b220224000240024002400240024002400240024002400240024002400240410e10292203450d00200341002900848d40370000200341066a410029008a8d403700002002428e808080e001370224200220033602202000200241206a104a200228022421042002280228210320022802202105200241206a41186a22004200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020052003200241206a1000200241186a2000290300370300200241106a2006290300370300200241086a200729030037030020022002290320370300200128020021082001280208210320024100360228200242013703202003200241206a104702402003450d00200341057421094100210a034002400240200228022420022802282203460d00200228022021000c010b200341016a22002003490d0f20034101742206200020002006491b22064100480d0f0240024020030d002006102921000c010b200228022020032006102a21000b2000450d042002200636022420022000360220200228022821030b2002200341016a360228200020036a2008200a6a220341146a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007102921060c010b200228022020002007102a21060b2006450d052002200736022420022006360220200228022821000b2002200041016a360228200620006a200341156a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007102921060c010b200228022020002007102a21060b2006450d062002200736022420022006360220200228022821000b2002200041016a360228200620006a200341166a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007102921060c010b200228022020002007102a21060b2006450d072002200736022420022006360220200228022821000b2002200041016a360228200620006a200341176a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007102921060c010b200228022020002007102a21060b2006450d082002200736022420022006360220200228022821000b2002200041016a360228200620006a200341186a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007102921060c010b200228022020002007102a21060b2006450d092002200736022420022006360220200228022821000b2002200041016a360228200620006a200341196a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007102921060c010b200228022020002007102a21060b2006450d0a2002200736022420022006360220200228022821000b2002200041016a360228200620006a2003411a6a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007102921060c010b200228022020002007102a21060b2006450d0b2002200736022420022006360220200228022821000b2002200041016a360228200620006a2003411b6a2d00003a0000200341086a290300210b2003290300210c0240024020022802242207200228022822066b4110490d00200228022021000c010b200641106a22002006490d0f20074101742206200020002006491b220d4100480d0f0240024020070d00200d102921000c010b20022802202007200d102a21000b2000450d0c2002200d3602242002200036022020022802282106200d21070b200020066a220d200b370008200d200c3700002002200641106a2206360228200341106a280200210d0240200720066b41034b0d00200641046a220e2006490d0f20074101742206200e200e2006491b22064100480d0f0240024020070d002006102921000c010b200020072006102a21000b2000450d0d2002200636022420022000360220200228022821060b2002200641046a360228200020066a200d36000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007102921060c010b200228022020002007102a21060b2006450d0e2002200736022420022006360220200228022821000b2002200041016a360228200620006a2003411c6a2d00003a00002009200a41206a220a470d000b0b2002280224210320024120200228022022002002280228100402402003450d002000102e0b02402004450d002005102e0b0240200141046a280200450d002008102e0b200241c0006a24000f0b410e4101102c000b20064101102c000b20074101102c000b20074101102c000b20074101102c000b20074101102c000b20074101102c000b20074101102c000b20074101102c000b200d4101102c000b20064101102c000b20074101102c000b102d000bcc0c05037f017e057f0a7e017f230041d0006b22062400200641b0f3c200410d107d2006280204210720062802002108200641186a20033703002006412c6a20053a0000200641206a2004360200200641246a2000290000370200200620023703104201210920064201370308200641306a2001107c4100210a2006280230210b2006280234210c024002400240024002400240024002402006280238220d450d002007410020081b21080240200641c4006a220e2000460d00200d41057421052006290308220921022006290310220f2110200629031822112112200641086a41186a29030022132114200b210402400340200441086a2903002103200441106a290300211520042903002116200641306a41186a200441186a290300370300200641306a41106a22072015370300200641306a41086a200337030020062016370330024002400240200e2900002000290000510d00200628024020084b0d0120022103420021020c020b42002109200629032821174200210f4200211142002113420021032010211520122116201421180c010b2007290300211820062903382116200629033021152006290348211720022103420121020b20024201510d01200441206a210420032102200541606a22050d000b200641206a2013370300200620093703082006200f370310200620113703180c020b200641206a2014370300200620033703082006201037031020062012370318200441206a21040c030b200d4105742105200b41206a2104200641206a2903002118200641086a41206a2903002117200629031821162006290310211520062903082102034020024201510d02200441206a210442002102200541606a22050d000b42002109200642003703080b0240200c0d004100210d41082119410821040c030b200b102e410821194100210d410821040c020b42002103200642003703080b412010292219450d04201920173703182019201537030020192016370308201941106a2018370300024002402004200b200d4105746a2205470d004101210a4101210d0c010b200641c4006a210e200321024101210a4101210d034002400240200e2000460d00200221150340200641306a41186a200441186a290300370300200641306a41106a2207200441106a290300370300200641306a41086a200441086a29030037030020062004290300370330024002400240200e2900002000290000510d00200628024020084b0d0120152102420021150c020b420021032006420037030820062903282116420021022010211820122117201421090c010b2007290300210920062903382117200629033021182006290348211620152102420121150b024020154201510d00200221152005200441206a2204470d010c050b0b200441206a21040c010b20062903282116024003402006420037030820024201510d01420021022005200441206a2204470d000b420021030c030b200441206a210442002103420021022010211820122117201421090b0240200d200a470d00200a41016a2207200a490d06200a410174220d20072007200d491b220d41ffffff3f71200d470d06200d41057422074100480d0602400240200a0d002007102921190c010b2019200a4105742007102a21190b2019450d040b2019200a4105746a2207201737030820072018370300200741106a2009370300200741186a2016370300200a41016a210a20042005470d000b0b0240200c450d00200b102e0b20032109201921040b024020094201520d00200641306a41186a200641106a220041186a290300370300200641306a41106a200041106a290300370300200641306a41086a200041086a290300370300200620002903003703300240200d200a470d00200a41016a2204200a490d04200a4101742200200420042000491b220d41ffffff3f71200d470d04200d41057422004100480d0402400240200a0d002000102921040c010b2019200a4105742000102a21040b2004450d030b2004200a4105746a22002006290330370300200041186a200641306a41186a290300370300200041106a200641306a41106a290300370300200041086a200641306a41086a290300370300200a41016a210a0b2006200a3602382006200d360234200620043602302001200641306a109001200641d0006a24000f0b20074108102c000b20004108102c000b102d000b41204108102c000bfb0102047f027e230041306b220424000240411810292205450d00200541002900ec8c40370000200541106a41002900fc8c40370000200541086a41002900f48c40370000200442988080808003370224200420053602202001200441206a104a20042802242105200441086a200428022022062004280228106e200441086a41106a2903004200200428020822071b21082004290310420020071b210902402005450d002006102e0b20012009200220092009200256200820035620082003511b22051b22027d20082003200820051b22037d2009200254ad7d108c012000200337030820002002370300200441306a24000f0b41184101102c000bee0304047f027e017f027e230041d0006b220424000240024002400240411410292205450d00200541002900d88c40370000200541106a41002800e88c40360000200541086a41002900e08c4037000020044294808080c002370244200420053602402001200441c0006a104a20042802442105200441286a200428024022062004280248106e200441286a41106a2903004200200428022822071b21082004290330420020071b210902402005450d002006102e0b024020092002542205200820035420082003511b450d0041e1b3c0002105411521010c040b200441206a20014104200920027d2209200820037d2005ad7d22081056200428022022050d02411810292207450d0141002105200741002900ec8c40370000200741106a41002900fc8c40370000200741086a41002900f48c40370000200442988080808003370244200420073602402001200441c0006a104a20042802442107200441086a2004280240220a2004280248106e200441086a41106a2903004200200428020822061b210b2004290310420020061b210c02402007450d00200a102e0b2001200c20027c2202200b20037c2002200c54ad7c108c0120012009200810730c030b41144101102c000b41184101102c000b200428022421010b2000200136020420002005360200200441d0006a24000bb00304037f017e017f047e230041c0006b2203240002400240411810292204450d00200441002900ec8c40370000200441106a41002900fc8c40370000200441086a41002900f48c40370000200342988080808003370234200320043602302000200341306a104a20032802342104200341186a200328023022052003280238106e200341186a41106a2903002106200328021821072003290320210802402004450d002005102e0b411410292204450d0120022006420020071b22062008420020071b2208200156200620025620062002511b22071b21092001200820071b2102200441002900d88c40370000200441106a41002800e88c40360000200441086a41002900e08c4037000020034294808080c002370234200320043602302000200341306a104a200328023421042003200328023022052003280238106e200341106a2903004200200328020022071b210a2003290308420020071b210102402004450d002005102e0b2000200120027c220b200a20097c200b200154ad7c10732000200820027d200620097d2008200254ad7d108c01200341c0006a24000f0b41184101102c000b41144101102c000bbd4e06057f027e0c7f027e027f047e230041d0046b22012400200141b8036a41086a22024200370300200142003703b80341eea0c5004111200141b8036a1003200141d8036a41086a2002290300370300200120012903b8033703d803200141d8036a4110100602400240024002400240024002400240024002400240024002400240200041c0f000700d00200141d8036a1087010240024002400240411410292203450d00200341002900d88c40370000200341106a41002800e88c40360000200341086a41002900e08c4037000020014294808080c0023702f401200120033602f001200141d8036a200141f0016a104a20012802f4012103200141b0016a20012802f001220420012802f801106e200141b0016a41106a290300420020012802b00122051b210620012903b801420020051b210702402003450d002004102e0b200120073703c801200120063703d001200141f0036a2006370300200141d8036a41106a2007370300200141d8036a41086a41013a00002001410b3a00d80341c8ecc5004100200141d8036a1072200141003a00df01200142003703e801200142003703e001200141d8026a41086a22034200370300200142003703d80241ae98c5004112200141d8026a1003200141b8036a41086a2003290300370300200120012903d8023703b803200141003602d803200141b8036a4110200141d8036a1008210320012802d8032204417f460d012003450d01200120043602f401200120033602f001200141d8036a200141f0016a1041024020012802d8032205450d00200141e0036a280200210820012802dc03210902402004450d002003102e0b4100210a2005410420051b210b200545210c2008410020051b2205450d04200141e1036a210d20014198036a210e200141d8026a41206a210f200141f0016a41086a211020014190046a2111410021124100210a4100210302400240024003400240024002400240200a450d00200b20034102746a2104200b200320126a4102746a21080340200320054f0d02200141f0016a2004280200221310960120012903f0014201520d04200141d8026a201041e00010f6041a20012903c801221420012903d802221554200141c8016a41086a2903002206200141d8026a41086a29030022075420062007511b450d03200141013a00df010240201220036a221320054f0d0020082004280200360200200441046a2104200841046a2108200341016a22032005490d010c070b0b419481c000201320051038000b200b20034102746a21040340200320054f0d01200141f0016a2004280200221310960120012903f0014201520d03200141d8026a201041e00010f6041a20012903c801221420012903d80222155a200141c8016a41086a2903002206200141d8026a41086a29030022075a20062007511b0d02200441046a2104200141013a00df01200341016a22032005490d000c0b0b0b41b880c000200320051038000b2001201420157d3703c8012001200620077d2014201554ad7d3703d001411210292204450d03200441106a41002f00ffda403b0000200441086a41002900f7da40370000200441002900efda40370000200441124124102a2204450d0420042013360012200141d8036a41186a22084200370300200141d8036a41106a22164200370300200141d8036a41086a22174200370300200142003703d80320044116200141d8036a1000200141b8036a41186a2008290300370300200141b8036a41106a2016290300370300200141b8036a41086a2017290300370300200120012903d8033703b803200141b8036a412010062004102e200f20012903e802200141d8026a41186a290300109401200141a0016a200e20012903d802200141d8026a41086a2204290300106d200141e0016a41086a2208427f20082903002206200141a0016a41086a2903007c20012903e001220720012903a0017c22142007542208ad7c22072008200720065420072006511b22081b3703002001427f201420081b3703e00120012903d802210620112004290300370300200d200e290000370000200d41086a200e41086a290000370000200d41106a200e41106a290000370000200d41186a200e41186a2900003700002001200637038804200141023a00e0032001410b3a00d803200120133602840441c8ecc5004100200141d8036a10720b2012417f6a2112200a41016a210a200341016a22032005490d000b0b200a450d06200520034d0d06200b20034102746a2204200a4102746b2004200520036b41027410f7041a0c060b41124101102c000b41244101102c000b41eff0c2004133200141c8046a4184f4c2001053000b41144101102c000b4101210c410021054104210b0b4100210a0b200141d8026a41086a22034200370300200142003703d80241ae98c5004112200141d8026a1003200141b8036a41086a2003290300370300200120012903d8023703b803200141003602e003200142013703d8032005200a6b2203200141d8036a10470240024020030d0020012802e003210520012802dc03211320012802d80321040c010b2005410274200a4102746b210a20012802dc03211320012802e0032103410021080340200b20086a280200211002400240201320036b4104490d00200341046a210520012802d80321040c010b200341046a22052003490d0e20134101742204200520052004491b22124100480d0e0240024020130d002012102921040c010b20012802d80320132012102a21040b2004450d04200120123602dc03200120043602d803201221130b200120053602e003200420036a201036000020052103200a200841046a2208470d000b0b200141b8036a411020042005100402402013450d002004102e0b0240200c200945720d00200b102e0b024020012d00df010d00200141f8006a20012903c8012206200141c8016a41086a2203290300220742c0843d420010fc04200141e8006a20012903782214200141f8006a41086a290300221542c0fb42427f10fb04200141d8006a2014201542a0c21e420010fb04200320072007200141d8006a41086a29030020012903582215200620012903687c42018842ffffffff0f837c2214201554ad7c22152014200656201520075620152007511b22051b22157d20062006201420051b220754ad7d3703002001200620077d3703c801200141d8026a41086a22034200370300200142003703d80241c28cc0004116200141d8026a1003200141b8036a41086a22042003290300370300200120012903d8023703b80320014188016a200141b8036a10970120014188016a41106a29030021142001290390012106200128028801210520034200370300200142003703d80241c28cc0004116200141d8026a100320042003290300370300200120012903d8023703b80320012006420020051b22063703d80320012014420020051b22143703e003200141b8036a4110200141d8036a41101004200141e0016a41086a2203427f2003290300221820142015200620077d200656201420157d2006200754ad7d221920145620192014511b22031b7c20012903e00122142006200720031b7c22192014542203ad7c22062003200620185420062018511b22031b3703002001427f201920031b3703e001200141f0036a2015370300200141d8036a41106a2007370300200141d8036a41086a41033a00002001410b3a00d80341c8ecc5004100200141d8036a10720b200141d8036a108701200141f0016a200141d8036a20012903e0012206200141e0016a41086a29030022074102107a0240024020012802f0010d00200141f0016a41106a290300211520012903f8012114200141286a41c28cc00041161070200720157d2006201454ad7d201520077d2014200654ad7d20142006582015200758201520075122031b22051b211a200620147d201420067d20051b211b200141286a41106a2903004200200128022822051b21182001290330420020051b2119024002402014200656201520075620031b0d00200141d8026a41086a22034200370300200142003703d80241c28cc0004116200141d8026a1003200141b8036a41086a2003290300370300200120012903d8023703b8032001427f2018201a7c2019201b7c22072019542203ad7c22062003200620185420062018511b22031b3703e0022001427f200720031b3703d802200141d8026a21030c010b200141d8026a41086a22034200370300200142003703d80241c28cc0004116200141d8026a1003200141b8036a41086a2003290300370300200120012903d8023703b803200142002018201a7d2019201b54ad7d22062019201b7d2207201956200620185620062018511b22031b3703e00220014200200720031b3703d802200141d8026a21030b200141b8036a41102003411010040c010b41b1ecc00041ca001009200141d8026a41086a22034200370300200142003703d80241c28cc0004116200141d8026a1003200141b8036a41086a22042003290300370300200120012903d8023703b803200141c0006a200141b8036a109701200141c0006a41106a2903002114200129034821152001280240210520034200370300200142003703d80241c28cc0004116200141d8026a100320042003290300370300200120012903d8023703b8032001427f2014420020051b221420077c2015420020051b220720067c22152007542203ad7c22062003200620145420062014511b22031b3703f8012001427f201520031b3703f001200141b8036a4110200141f0016a411010040b20012903c8012106200141f0036a200141c8016a41086a290300370300200141e8036a2006370300200141d8036a41086a41043a00002001410b3a00d80341c8ecc5004100200141d8036a10720b20024200370300200142003703b80341ba8ec200411d200141b8036a1003200141d8026a41086a2002290300370300200120012903b8033703d802200141003602d803200141d8026a4110200141d8036a10082103024020012802d8032205417f460d002003450d00200120033602f001200120053602f40120054104490d062001200341046a3602f00120012005417c6a22043602f40120044104490d06200328000021132001200541786a3602f4012001200341086a3602f0012003280004210b200141d8036a200141f0016a103e20012802d8032212450d0620012902dc032118410021080240024020012802f40122050d000c010b20012005417f6a22103602f401200120012802f001220441016a3602f001024020042d00004101460d000c010b20104104490d0020012005417b6a3602f4012001200441056a3602f0012004280001210a410121080b2003102e2018422088a72110024020132000470d00024020080d002010ad42287e2206422088a70d042006a72203417f4c0d040240024020030d004108210a0c010b20031029220a450d060b4100210402402010450d00201041286c210841002104200a2103201221050340200541086a2903002106200541106a2903002107200541186a290300211420052903002115200341206a200541206a290300370300200341186a2014370300200341106a2007370300200341086a200637030020032015370300200341286a2103200441016a2104200541286a2105200841586a22080d000b0b20014180026a200b360200200141f0016a410c6a2004360200200141f0016a41086a20103602002001200a3602f401200141003602f001200141d8036a200141f0016a105c200141e3026a200141d8036a41086a280200360000200120012903d8033700db02200141d8036a410c6a200141df026a290000370000200141c6a4b9da043600d903200141023a00d803200120012900d8023700dd03200141d8036a1098012010450d01200a102e0c010b2010ad42287e2206422088a70d032006a72203417f4c0d030240024020030d00410821020c010b200310292202450d060b0240024020100d00410021040c010b201041286c21084100210420022103201221050340200541086a2903002106200541106a2903002107200541186a290300211420052903002115200341206a200541206a290300370300200341186a2014370300200341106a2007370300200341086a200637030020032015370300200341286a2103200441016a2104200541286a2105200841586a22080d000b0b20014184026a200b36020020014180026a2004360200200141f0016a410c6a2010360200200141f0016a41086a20023602002001200a3602f401200141013602f001200141d8036a200141f0016a105c200141e3026a200141d8036a41086a280200360000200120012903d8033700db02200141d8036a410c6a200141df026a290000370000200141c6a4b9da043600d903200141023a00d803200120012900d8023700dd03200141d8036a1098012010450d002002102e0b2018a7210a0240200b20136a2000470d00200141b8036a41086a22034200370300200142003703b80341dadcc500411b200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d802200141003602e003200142013703d8032010200141d8036a104702402010450d002012201041286c6a21132012210503402005200141d8036a104a200541206a29030021060240024020012802dc03220420012802e00322036b4108490d0020012802d80321040c010b200341086a22082003490d0f20044101742203200820082003491b22034100480d0f0240024020040d002003102921040c010b20012802d80320042003102a21040b2004450d09200120033602dc03200120043602d80320012802e00321030b2001200341086a3602e003200420036a20063700002013200541286a2205470d000b0b20012802dc032103200141d8026a411020012802d803220520012802e003100402402003450d002005102e0b200141d8036a41106a2010360200200141e4036a200a360200200141d8036a41086a2012360200200141003602dc032001410a3a00d80341c8ecc5004100200141d8036a1072200141b8036a41086a22034200370300200142003703b80341ba8ec200411d200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d802200141d8026a411010060c010b200a450d002012102e0b200141b8036a41086a22034200370300200142003703b80341d78ec2004115200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d802200141003602d803200141d8026a4110200141d8036a1008210320012802d8032205417f460d092003450d092005450d0820032d0000220441034b0d080240024020040e0401090100010b2005417f6a41074b0d070c090b2003102e0c090b20124101102c000b1032000b20034108102c000b20034108102c000b20034101102c000b41eff0c2004133200141c8046a4184f4c2001053000b20032800052104200328000121052003102e024020052000470d00200141043602f001200120043602f401200141d8036a200141f0016a105c200141e3026a200141e0036a280200360000200120012903d8033700db02200141e4036a200141df026a290000370000200141c6a4b9da043600d903200141023a00d803200120012900d8023700dd03200141d8036a1098010b200420056a2000470d02200141003602f001200141b8036a41086a22034200370300200142003703b80341d78ec2004115200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d802200141d8036a200141f0016a109901200141d8026a411020012802d803220320012802e0031004024020012802dc03450d002003102e0b200141023602dc032001410a3a00d80341c8ecc5004100200141d8036a10720c020b2005417f6a4108490d0020032800052104200328000121052003102e024020052000470d00200141033602f001200120043602f401200141d8036a200141f0016a105c200141e3026a200141e0036a280200360000200120012903d8033700db02200141e4036a200141df026a290000370000200141c6a4b9da043600d903200141023a00d803200120012900d8023700dd03200141d8036a1098010b200420056a2000470d01200141023602f001200141b8036a41086a22034200370300200142003703b80341d78ec2004115200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d802200141d8036a200141f0016a109901200141d8026a411020012802d803220320012802e0031004024020012802dc03450d002003102e0b200141013602dc032001410a3a00d80341c8ecc5004100200141d8036a10720c010b41eff0c2004133200141c8046a4184f4c2001053000b200141b8036a41086a22034200370300200142003703b80341fbd8c0004110200141b8036a1003200141d8026a41086a22052003290300370300200120012903b8033703d802200141206a200141d8026a4110109a01200128022421022001280220211320034200370300200142003703b80341f5dcc5004115200141b8036a100320052003290300370300200120012903b8033703d802200141003602d803200141d8026a4110200141d8036a10082103024002400240024002400240024002400240024020012802d8032205417f460d002003450d002005450d0820032d000021052003102e20054102460d0020054101710d010b410410292205450d0120054100360200200141b8036a41086a22034200370300200142003703b803418bd9c0004115200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d802200141003602e003200142013703d8034101200141d8036a1047200528020021100240024020012802dc03220820012802e00322046b4104490d0020012802d80321030c010b200441046a22032004490d0a20084101742212200320032012491b22124100480d0a0240024020080d002012102921030c010b20012802d80320082012102a21030b2003450d03200120123602dc03200120033602d803201221080b2001200441046a22123602e003200320046a2010360000200141d8026a411020032012100402402008450d002003102e0b2005102e410410292205450d0320054100360200200141b8036a41086a22034200370300200142003703b803418ceec0004116200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d802200141003602e003200142013703d8034101200141d8036a1047200528020021100240024020012802dc03220820012802e00322046b4104490d0020012802d80321030c010b200441046a22032004490d0a20084101742212200320032012491b22124100480d0a0240024020080d002012102921030c010b20012802d80320082012102a21030b2003450d05200120123602dc03200120033602d803201221080b2001200441046a22123602e003200320046a2010360000200141d8026a411020032012100402402008450d002003102e0b2005102e200141b8036a41086a22034200370300200142003703b80341a2eec0004110200141b8036a1003200141d8026a41086a22052003290300370300200120012903b8033703d802200141003602d803200141d8026a4110200141d8036a41041004200141013a00d80320034200370300200142003703b80341f5dcc5004115200141b8036a100320052003290300370300200120012903b8033703d802200141d8026a4110200141d8036a410110040b200141b8036a41086a22034200370300200142003703b803418bd9c0004115200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d802200141003602d803200141d8026a4110200141d8036a1008210320012802d8032205417f460d052003450d05200120053602f401200120033602f001200141d8036a200141f0016a104120012802d8032209450d04200141e0036a280200210020012802dc03210d2005450d072003102e0c070b41044104102c000b20124101102c000b41044104102c000b20124101102c000b41eff0c2004133200141c8046a4184f4c2001053000b41042109410021004100210d0c010b41eff0c2004133200141c8046a4184f4c2001053000b200141b8036a41086a22034200370300200142003703b803418ceec0004116200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d8024100210c200141003602d803200141d8026a4110200141d8036a100821030240024020012802d8032204417f460d002003450d00200120043602f401200120033602f001200141d8036a200141f0016a1041024020012802d803220c450d00200141e0036a280200210520012802dc0321112004450d022003102e0c020b41eff0c2004133200141c8046a4184f4c2001053000b0b02400240024002400240024020130d002000417f6a220320004b0d01200320004f0d01200920034102746a2203450d01200328020021020b200041002000419c7f6a22032003200041016a4b1b220f490d0120054100200c1b2112200c4104200c1b21102000200f6b210e200f450d042009200f4102746a210a2009210b0340200b280200211302400240024002400240201241014b0d004100210320120e020201020b4100210320122105034020032005410176220420036a22082013201020084102746a280200491b2103200520046b220541014b0d000b0b2013201020034102746a22052802002204460d022003201320044b6a21030c010b410021030b200120033602d80341d8eec000412e200141d8036a4188efc0001053000b201220034d0d032005200541046a2003417f7320126a41027410f7041a2012417f6a2112200b41046a220b200a460d040c000b0b41b2eec0004126109b01000b418cc6c5001058000b418080c0001058000b200e450d002009200a200e41027410f7041a0b41002103024002400240201241014b0d0020120e020201020b20122105034020032005410176220420036a22082002201020084102746a280200491b2103200520046b220541014b0d000b0b2002201020034102746a2802002205460d002003200220054b6a21030b02400240024002400240024002400240024020122003490d00201220114100200c1b2205460d01200521110c020b41c0c6c5001058000b200541016a22042005490d0720054101742208200420042008491b221141ffffffff03712011470d07201141027422044100480d070240024020050d002004102921100c010b201020054102742004102a21100b2010450d010b201020034102746a220541046a2005201220036b41027410f7041a2005200236020002400240200d200e460d00200d21160c010b200d41016a2203200d490d07200d4101742205200320032005491b221641ffffffff03712016470d07201641027422034100480d0702400240200d0d002003102921090c010b2009200d4102742003102a21090b2009450d020b2009200e4102746a20023602000240201241016a220c0d004198efc0001058000b200c200c41017622034d0d02201020034102746a280200210d0240200c4101710d00200c2003417f6a22034d0d04201020034102746a280200200d6a410176210d0b200141b8036a41086a22034200370300200142003703b803418bd9c0004115200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d802200141003602e003200142013703d803200e41016a220e200141d8036a104702400240200e0d0020012802e003210b20012802dc03211320012802d80321050c010b2000410274200f4102746b41046a210a410020012802e00322036b210420012802dc0321132009210803402008280200210202400240201320046a4104490d0020012802d80321050c010b200341046a22052003490d092013410174220b20052005200b491b220b4100480d090240024020130d00200b102921050c010b20012802d8032013200b102a21050b2005450d072001200b3602dc03200120053602d803200b21130b200841046a21082001200341046a220b3602e003200520036a20023600002004417c6a2104200b2103200a417c6a220a0d000b0b200141d8026a41102005200b100402402013450d002005102e0b02402016450d002009102e0b200141b8036a41086a22034200370300200142003703b803418ceec0004116200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d802200142013703d803200141003602e003200c200141d8036a1047201241027441046a2112410020012802e00322036b210420012802dc0321132010210803402008280200210a02400240201320046a4104490d0020012802d80321050c010b200341046a22052003490d082013410174220b20052005200b491b220b4100480d080240024020130d00200b102921050c010b20012802d8032013200b102a21050b2005450d072001200b3602dc03200120053602d803200b21130b200841046a21082001200341046a220b3602e003200520036a200a3600002004417c6a2104200b21032012417c6a22120d000b200141d8026a41102005200b100402402013450d002005102e0b02402011450d002010102e0b200141b8036a41086a22034200370300200142003703b80341a2eec0004110200141b8036a1003200141d8026a41086a2003290300370300200120012903b8033703d8022001200d3602d803200141d8026a4110200141d8036a410410040240200e41e500470d00200141186a41b0f3c200410d107d200d419a086a200128021c410020012802181b4b0d00200141b8036a41086a22054200370300200142003703b8034191f5c1004117200141b8036a1003200141d8026a41086a2005290300370300200120012903b8033703d802410810292205450d082005200d360004200541e400360000200141d8026a41102005410810042005102e0b20034200370300200142003703b80341e7e7c3004117200141b8036a1003200141d8036a41086a2003290300370300200120012903b8033703d8030240200141d8036a411041c8ecc500410041001005417f470d00200141086a41c5c1c200410d1081012001290310210620012802082103200141b8036a41086a22054200370300200142003703b80341e7e7c3004117200141b8036a1003200141d8036a41086a2005290300370300200120012903b8033703d80320012006420020031b3703f001200141d8036a4110200141f0016a410810040b200141b8036a41086a22034200370300200142003703b80341eef4c1004111200141b8036a1003200141d8036a41086a22052003290300370300200120012903b8033703d803200141d8036a4110100620034200370300200142003703b80341d49bc5004117200141b8036a100320052003290300370300200120012903b8033703d803200141d8036a4110100641cde2c5004113109c01220341ff01714102460d082003410171450d08200141b8036a41086a22034200370300200142003703b80341c8dec5004110200141b8036a1003200141d8036a41086a2003290300370300200120012903b8033703d803200141d8036a41101006200141d0046a24000f0b20044104102c000b20034104102c000b41b0efc0002003200c1038000b41b0efc0002003200c1038000b200b4101102c000b200b4101102c000b102d000b41084101102c000b41ccb7c2001058000ba70201047f23004190016b2202240002400240411210292203450d00200341106a41002f00ffda403b0000200341086a41002900f7da40370000200341002900efda40370000200341124124102a2203450d0120032001360012200241086a41186a22014200370300200241086a41106a22044200370300200241086a41086a220542003703002002420037030820034116200241086a1000200241f0006a41186a2001290300370300200241f0006a41106a2004290300370300200241f0006a41086a200529030037030020022002290308370370200241086a200241f0006a10ae010240024020022903084201510d00200042003703000c010b2000200241086a41e80010f6041a0b2003102e20024190016a24000f0b41124101102c000b41244101102c000b920102027f037e230041106b220224002002410036020420014110200241046a1008210102400240024020022802042203417f470d00420021040c010b20034110490d01200141086a2900002105200129000021062001102e420121040b2000200637030820002004370300200041106a2005370300200241106a24000f0b41eff0c2004133200241086a4184f4c2001053000bd20805047f017e047f027e047f230041d0006b22012400200141106a41086a220242003703002001420037031041d2f3c200410d200141106a1003200141086a2002290300370300200120012903103703002001410036021020014110200141106a1008210202400240024002400240024020012802102203417f460d002002450d002001200336023c20012002360238200141106a200141386a103f20012802102204450d022001290214210502402003450d002002102e0b2005422088a721062005a721030c010b410421044100210642002105410021030b200141106a41206a2207200041206a280200360200200141106a41186a2208200041186a290200370300200141106a41106a2209200041106a290200370300200141106a41086a2202200041086a29020037030020012000290200370310024020062003470d00024020062005a7470d00200641016a22002006490d0520064101742203200020002003491bad220a42247e220b422088a70d05200ba722004100480d050240024020060d002000102921040c010b2004200641246c2000102a21040b2004450d03200542808080807083200a8421050b2005422088a721060b2004200641246c22036a22002001290310370200200041206a2007280200360200200041186a2008290300370200200041106a2009290300370200200041086a2002290300370200200242003703002001420037031041d2f3c200410d200141106a1003200141086a2002290300370300200120012903103703002001410036024020014201370338200641016a220c200141386a104702400240200c20064f0d0020012802402102200128023c2109200128023821030c010b200341246a210d200128023c210920012802402100200421070340200141106a200710452001280210210e02400240200920006b20012802182208490d00200020086a2102200128023821030c010b200020086a22022000490d0620094101742203200220022003491b220f4100480d060240024020090d00200f102921030c010b20012802382009200f102a21030b2003450d052001200f36023c20012003360238200f21090b20012002360240200320006a200e200810f6041a02402001280214450d00200e102e0b200741246a210720022100200d415c6a220d0d000b0b2001411020032002100402402009450d002003102e0b0240200c450d00200641246c41246a21022004210003400240024020002d0000220341034b0d0002400240024020030e0404000102040b2000410c6a280200450d03200041086a280200102e0c030b2000410c6a280200450d02200041086a280200102e0c020b2000410c6a280200450d01200041086a280200102e0c010b200041086a280200450d00200041046a280200102e0b200041246a21002002415c6a22020d000b0b02402005a7450d002004102e0b200141d0006a24000f0b41eff0c2004133200141c8006a4184f4c2001053000b20004104102c000b200f4101102c000b102d000bd60201037f0240024002400240024002400240024002400240024002400240024020012802000e0400010203000b41012102410110292201450d05200141003a0000410121030c040b410110292202450d05200241013a000020012802042103200241014105102a2202450d062002200336000120012802082104410a210320024105410a102a2201450d07200120043600050c020b41012102410110292201450d07200141023a0000410121030c020b410110292202450d07200241033a000020012802042103200241014105102a2202450d082002200336000120012802082104410a210320024105410a102a2201450d09200120043600050b410921020b2000200236020820002003360204200020013602000f0b41014101102c000b41014101102c000b41054101102c000b410a4101102c000b41014101102c000b41014101102c000b41054101102c000b410a4101102c000b8b0101047f230041106b22032400410021042003410036020420012002200341046a1008210502400240024020032802042206417f470d000c010b024020050d000c010b20064104490d01200528000021062005102e200120021006410121040b2000200436020020002006360204200341106a24000f0b41eff0c2004133200341086a4184f4c2001053000b5e01017f230041306b220224002002200136020c20022000360208200241246a410136020020024201370214200241e897c6003602102002411c36022c2002200241286a3602202002200241086a360228200241106a41f097c600106a000ba80101027f230041206b22022400200241106a41086a220342003703002002420037031020002001200241106a1003200241086a2003290300370300200220022903103703002002410036021020024110200241106a1008210002400240024020022802102201417f470d00410221010c010b2001450d0120002d000021012000102e2002411010060b200241206a240020010f0b41eff0c2004133200241106a4184f4c2001053000b9e0301027f230041e0006b22032400200341003a0005024002402000413f4b0d0041012104200341013a0005200320004102743a00000c010b02400240200041808001490d0020004180808080044f0d0141042104200341043a0005200320004102744102723602000c020b41022104200341023a0005200320004102744101723b01000c010b41052104200341053a0005200341033a0000200320003600010b024002402001280200220028020822012002490d0020002802002100200320023602082003200436020c20042002470d0120002003200210f6041a200341e0006a24000f0b20022001105e000b200341286a41146a411d360200200341346a4120360200200341106a41146a41033602002003200341086a36024020032003410c6a360244200341c8006a41146a4100360200200342033702142003419ce7c5003602102003412036022c200341c8ecc5003602582003420137024c200341f0e7c5003602482003200341286a3602202003200341c8006a3602382003200341c4006a3602302003200341c0006a360228200341106a41ace8c500106a000bb90201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d002000280200210420034120710d012004ad4101200110b50121000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000b20024180016a240020000f0b20044180011035000b20044180011035000b130020004101360204200041f8b5c0003602000b3400200041d4e9c10036020420004100360200200041146a410b360200200041106a41bcb8c000360200200041086a42043702000b3001017f02404102102922020d0041024101102c000b20024181023b00002000428280808020370204200020023602000b130020004102360204200041c0cfc0003602000b3101017f02404108102922020d0041084101102c000b20004288808080800137020420002002360200200242f02e3700000b3101017f02404108102922020d0041084101102c000b20004288808080800137020420002002360200200242e4003700000bdc0805037f037e027f017e017f23004180016b220724002004a7210802400240024002400240024020014201510d0041012109024020084101460d00427f200320067c200220057c220a2002542208ad7c220b2008200b200354200b2003511b22081b210b427f200a20081b210a4200210c4100210d0c040b2002200556200320065620032006511b450d01200320067d2002200554ad7d210b200220057d210a4200210c0c020b4101210d024020084101470d00427f200320067c200220057c22012002542208ad7c22022008200220035420022003511b22081b210b427f200120081b210a410021094201210c0c040b200741306a20042005200642012002200310a501200741c0006a290300210b2007290338210a2007290330210c0c040b200620037d2005200254ad7d210b200520027d210a4201210c0b410021094101210d0b2001500d00200741f0006a41086a220842003703002007420037037041c28cc0004116200741f0006a1003200741e0006a41086a220e200829030037030020072007290370370360200741c8006a200741e0006a109701200741c8006a41106a29030021012007290350210f20072802482110200842003703002007420037037041c28cc0004116200741f0006a1003200e200829030037030020072007290370370360200742002001420020101b220120037d200f420020101b2203200254ad7d220f200320027d2202200356200f200156200f2001511b22081b37037820074200200220081b370370200741e0006a4110200741f0006a411010040b02402004500d002009450d01200741f0006a41086a220842003703002007420037037041c28cc0004116200741f0006a1003200741e0006a41086a220d200829030037030020072007290370370360200741186a200741e0006a109701200741186a41106a29030021032007290320210220072802182109200842003703002007420037037041c28cc0004116200741f0006a1003200d200829030037030020072007290370370360200742002003420020091b220320067d2002420020091b2202200554ad7d2204200220057d2205200256200420035620042003511b22081b37037820074200200520081b370370200741e0006a4110200741f0006a411010040c010b200d450d00200741f0006a41086a220842003703002007420037037041c28cc0004116200741f0006a1003200741e0006a41086a220d2008290300370300200720072903703703602007200741e0006a109701200741106a29030021032007290308210220072802002109200842003703002007420037037041c28cc0004116200741f0006a1003200d2008290300370300200720072903703703602007427f2003420020091b220320067c2002420020091b220220057c22052002542208ad7c22022008200220035420022003511b22081b3703782007427f200520081b370370200741e0006a4110200741f0006a411010040b2000200a3703082000200c370300200041106a200b37030020074180016a24000bf20403037f027e017f230041d0006b220424004101210502402001a722064101470d002000427f2000290300220720027c220820082007542205200041086a2209290300220720037c2005ad7c220820075420082007511b22051b3703002009427f200820051b370300410021050b0240024020014201560d00024020060e020200020b2005450d01200441c0006a41086a220042003703002004420037034041c28cc0004116200441c0006a1003200441306a41086a2206200029030037030020042004290340370330200441186a200441306a109701200441186a41106a29030021012004290320210720042802182105200042003703002004420037034041c28cc0004116200441c0006a100320062000290300370300200420042903403703302004427f2001420020051b220120037c2007420020051b220320027c22072003542200ad7c22022000200220015420022001511b22001b3703482004427f200720001b370340200441306a4110200441c0006a411010040c010b200441c0006a41086a220042003703002004420037034041c28cc0004116200441c0006a1003200441306a41086a22062000290300370300200420042903403703302004200441306a109701200441106a29030021012004290308210720042802002105200042003703002004420037034041c28cc0004116200441c0006a100320062000290300370300200420042903403703302004427f2001420020051b220120037c2007420020051b220320027c22072003542200ad7c22022000200220015420022001511b22001b3703482004427f200720001b370340200441306a4110200441c0006a411010040b200441d0006a24000b130020004103360204200041e0dbc0003602000b3400200041abeac10036020420004100360200200041146a4103360200200041106a41c8e2c000360200200041086a42083702000b130020004104360204200041e0e6c0003602000b0b00200041a0c21e10ab010b3001017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200220013600000b3201017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241c0f0003600000b0b00200041d0860310ab010bee0704077f027e047f027e230041d0016b22022400200241003602a80120014120200241a8016a10082103024002400240024020022802a8012204417f460d0020030d010b200042003703000c010b41002101200241003a00c801200441706a21050340024020042001470d00200141ff0171450d03200241003a00c8010c030b200241a8016a20016a200320016a2d00003a00002002200141016a22063a00c8012005417f6a21052006210120064120470d000b200241c8006a41086a200241a8016a41086a290300370300200241c8006a41106a200241a8016a41106a290300370300200241c8006a41186a200241a8016a41186a290300370300200220022903a801370348200420066b22074110490d01200320066a22082900002109200841086a290000210a41002101200241003a00c801200741706a21070340024020072001470d00200141ff0171450d03200241003a00c8010c030b200241a8016a20016a200820016a41106a2d00003a00002002200141016a22063a00c8012006210120064120470d000b200241e8006a41086a220b200241a8016a41086a2201290300370300200241e8006a41106a220c200241a8016a41106a2207290300370300200241e8006a41186a220d200241a8016a41186a220e290300370300200220022903a801370368200520066b410f4d0d012001200241c8006a41086a2903003703002007200241c8006a41106a290300370300200e200241c8006a41186a29030037030020024188016a41086a2205200b29030037030020024188016a41106a220b200c29030037030020024188016a41186a220c200d290300370300200220022903483703a8012002200229036837038801200820066a220641186a290000210f200641106a2900002110200241286a41086a2001290300370300200241286a41106a2007290300370300200241286a41186a200e290300370300200241086a41086a2005290300370300200241086a41106a200b290300370300200241086a41186a200c290300370300200220022903a801370328200220022903880137030802402004450d002003102e0b20002009370308200041206a200f370300200041186a2010370300200041106a200a370300200041286a2002290328370300200041c8006a2002290308370300200041306a200241286a41086a290300370300200041386a200241286a41106a290300370300200041c0006a200241286a41186a290300370300200041d0006a200241086a41086a290300370300200041d8006a200241086a41106a290300370300200041e0006a200241086a41186a290300370300200042013703000b200241d0016a24000f0b41eff0c2004133200241e8006a4184f4c2001053000bc10201067f23004180016b220224000240411710292203450d00200341002900b0a5433700002003410f6a41002900bfa543370000200341086a41002900b8a54337000020024297808080f00237020c200220033602082001200241086a104a200228020c21012002280210210420022802082103200241086a41186a22054200370300200241086a41106a22064200370300200241086a41086a220742003703002002420037030820032004200241086a1000200241e0006a41186a2005290300370300200241e0006a41106a2006290300370300200241e0006a41086a200729030037030020022002290308370360200241086a200241e0006a10760240024020022d00084102470d00200041023a00000c010b2000200241086a41d80010f6041a0b02402001450d002003102e0b20024180016a24000f0b41174101102c000bbc0301057f230041106b2203240002400240024002400240200141046a2204417f4c0d000240024020040d00410121050c010b200410292205450d020b2003410036020820032004360204200320053602002001200310470240024020032802042206200328020822056b2001490d00200328020021040c010b200520016a22042005490d0520064101742207200420042007491b22074100480d050240024020060d002007102921040c010b200328020020062007102a21040b2004450d032003200736020420032004360200200721060b200420056a2000200110f6041a02400240200241046a2802002207200241086a28020022006b200520016a2201490d00200228020021050c010b200020016a22052000490d0520074101742200200520052000491b22004100480d050240024020070d002000102921050c010b200228020020072000102a21050b2005450d0420022005360200200241046a2000360200200241086a28020021000b200241086a200020016a360200200520006a2004200110f6041a02402006450d002004102e0b200341106a24000f0b1032000b20044101102c000b20074101102c000b20004101102c000b102d000b990201067f230041c0006b220224000240411710292203450d00200341002900b0a5433700002003410f6a41002900bfa543370000200341086a41002900b8a54337000020024297808080f002370224200220033602202000200241206a104a200228022421002002280228210420022802202103200241206a41186a22054200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020032004200241206a1000200241186a2005290300370300200241106a2006290300370300200241086a20072903003703002002200229032037030020024120360224200220023602202001200241206a10d50302402000450d002003102e0b200241c0006a24000f0b41174101102c000b110020002802002000280204200110b3010bbe0f020d7f017e230041206b220324004101210402400240200228021841222002411c6a2802002802101102000d000240024020010d00410021050c010b200020016a21062000210741002105410021080240034020072109200741016a210a02400240024020072c0000220b417f4a0d0002400240200a2006470d004100210c200621070c010b20072d0001413f71210c200741026a220a21070b200b411f7121040240200b41ff0171220b41df014b0d00200c200441067472210b0c020b0240024020072006470d004100210d2006210e0c010b20072d0000413f71210d200741016a220a210e0b200d200c41067472210c0240200b41f0014f0d00200c2004410c7472210b0c020b02400240200e2006470d004100210b200a21070c010b200e41016a2107200e2d0000413f71210b0b200c4106742004411274418080f0007172200b72220b418080c400470d020c040b200b41ff0171210b0b200a21070b4102210a024002400240024002400240200b41776a220c411e4d0d00200b41dc00470d010c020b41f400210e02400240200c0e1f05010202000202020202020202020202020202020202020202030202020203050b41f200210e0c040b41ee00210e0c030b02400240200b10e1040d0002400240200b41808004490d00024002400240200b418080084f0d00200b4180fe0371410876210f41f183c600210c410021040340200c41026a210d2004200c2d0001220a6a210e0240200c2d0000220c200f460d00200c200f4b0d06200e2104200d210c200d41b784c600470d010c060b200e2004490d02200e41a6014b0d03200441b784c6006a210c02400340200a450d01200a417f6a210a200c2d00002104200c41016a210c2004200b41ff0171470d000c080b0b200e2104200d210c200d41b784c600470d000c050b0b200b41ef83384b0d04200b41e28b746a41e28d2c490d04200b419fa8746a419f18490d04200b41dee2746a410e490d04200b41feffff0071419ef00a460d04200b41a9b2756a4129490d04200b41cb91756a410a4b0d090c040b2004200e1035000b200e41a601105e000b200b4180fe0371410876210f41c0fec500210c41002104024002400340200c41026a210d2004200c2d0001220a6a210e0240200c2d0000220c200f460d00200c200f4b0d03200e2104200d210c200d4192ffc500470d010c030b0240200e2004490d00200e41a5024b0d0220044192ffc5006a210c02400340200a450d01200a417f6a210a200c2d00002104200c41016a210c2004200b41ff0171470d000c070b0b200e2104200d210c200d4192ffc500470d010c030b0b2004200e1035000b200e41a502105e000b200b41ffff0371210441b781c600210a4101210e02400340200a41016a210d02400240200a2d0000220c411874411875220f4100480d00200d210a0c010b200d41f183c600460d02200f41ff0071410874200a2d000172210c200a41026a210a0b02402004200c6b22044100480d00200e410173210e200a41f183c600470d010b0b200e410171450d020c070b41d8f0c5001058000b200b41ffff0371210441dd85c600210a4101210e0340200a41016a210d02400240200a2d0000220c411874411875220f4100480d00200d210a0c010b200d41f588c600460d03200f41ff0071410874200a2d000172210c200a41026a210a0b02402004200c6b22044100480d00200e410173210e200a41f588c600470d010b0b200e4101710d050b200b41017267410276410773ad4280808080d0008421104103210a0c020b41d8f0c5001058000b0b200b210e0b2003200136020420032000360200200320053602082003200836020c0240024020082005490d0002402005450d0020052001460d00200520014f0d01200020056a2c000041bf7f4c0d010b02402008450d0020082001460d00200820014f0d01200020086a2c000041bf7f4c0d010b2002280218200020056a200820056b200228021c28020c110400450d01410121040c060b20032003410c6a3602182003200341086a36021420032003360210200341106a10e804000b0340200a210c4101210441dc0021054101210a024002400240024002400240200c0e0402010500020b02400240024002402010422088a741ff01710e06050302010006050b201042ffffffff8f60834280808080308421104103210a41f50021050c070b201042ffffffff8f60834280808080208421104103210a41fb0021050c060b200e2010a7220c410274411c7176410f71220a413072200a41d7006a200a410a491b21050240200c450d002010427f7c42ffffffff0f832010428080808070838421100c050b201042ffffffff8f60834280808080108421100c040b201042ffffffff8f608321104103210a41fd0021050c040b4100210a200e21050c030b4101210a0240200b418001490d004102210a200b418010490d0041034104200b41808004491b210a0b200a20086a21050c040b201042ffffffff8f60834280808080c0008421100b4103210a0b20022802182005200228021c2802101102000d050c000b0b200820096b20076a210820062007470d000b0b2005450d0020052001460d00200520014f0d02200020056a2c000041bf7f4c0d020b410121042002280218200020056a200120056b200228021c28020c1104000d0020022802184122200228021c28021011020021040b200341206a240020040f0b200020012005200110de04000bb20201037f23004180016b2202240002400240024002400240200128020022034110710d002000280200210420034120710d012004ad4101200110b50121000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000b20024180016a240020000f0b20044180011035000b20044180011035000bd50203027f017e037f230041306b22032400412721040240024020004290ce005a0d00200021050c010b412721040340200341096a20046a2206417c6a200020004290ce0080220542f0b17f7e7ca7220741ffff037141e4006e2208410174418aedc5006a2f00003b00002006417e6a2008419c7f6c20076a41ffff0371410174418aedc5006a2f00003b00002004417c6a2104200042ffc1d72f5621062005210020060d000b0b02402005a7220641e3004c0d00200341096a2004417e6a22046a2005a7220741ffff037141e4006e2206419c7f6c20076a41ffff0371410174418aedc5006a2f00003b00000b024002402006410a480d00200341096a2004417e6a22046a2006410174418aedc5006a2f00003b00000c010b200341096a2004417f6a22046a200641306a3a00000b2002200141c8ecc5004100200341096a20046a412720046b10b6012104200341306a240020040be40501057f024002402001450d00412b418080c4002000280200220641017122011b2107200120056a21080c010b200541016a210820002802002106412d21070b0240024020064104710d00410021020c010b4100210902402003450d002003210a200221010340200920012d000041c00171418001466a2109200141016a2101200a417f6a220a0d000b0b200820036a20096b21080b410121010240024020002802084101460d00200020072002200310dd040d012000280218200420052000411c6a28020028020c1104000f0b02402000410c6a280200220920084b0d00200020072002200310dd040d012000280218200420052000411c6a28020028020c1104000f0b0240024020064108710d00200920086b210941002101024002400240410120002d0030220a200a4103461b0e0402000100020b20092101410021090c010b20094101762101200941016a41017621090b200141016a210103402001417f6a2201450d0220002802182000280204200028021c280210110200450d000b41010f0b41012101200041013a003020004130360204200020072002200310dd040d01200920086b210941002101024002400240410120002d0030220a200a4103461b0e0402000100020b20092101410021090c010b20094101762101200941016a41017621090b200141016a2101024003402001417f6a2201450d0120002802182000280204200028021c280210110200450d000b41010f0b2000280204210a41012101200028021820042005200028021c28020c1104000d01200941016a2109200028021c210320002802182100034002402009417f6a22090d0041000f0b410121012000200a2003280210110200450d000c020b0b2000280204210a41012101200020072002200310dd040d00200028021820042005200028021c28020c1104000d00200941016a2109200028021c210320002802182100034002402009417f6a22090d0041000f0b410121012000200a2003280210110200450d000b0b20010b930c04047f017e097f067e23004180066b22022400200241286a2001103102400240024002400240024020022802280d0020012802042203450d01200128020022042d0000210520012003417f6a3602042001200441016a36020002400240200541ff00714103470d0020054118744118754100480d01420221060c060b200042033703680c060b20024198046a2001104820022d0098044102460d02200241f0036a41206a20024198046a41206a280200360200200241f0036a41186a20024198046a41186a290300370300200241f0036a41106a20024198046a41106a290300370300200241f0036a41086a20024198046a41086a29030037030020022002290398043703f00341002103200241003a00c00220012802042107417f2105024002400240034020072003460d0120024180026a20036a200128020022082d00003a00002001200720056a3602042001200841016a3602002002200341016a22043a00c0022005417f6a210520042103200441c000470d000b200241c0056a41386a220320024180026a41386a290300370300200241c0056a41306a220920024180026a41306a290300370300200241c0056a41286a220a20024180026a41286a290300370300200241c0056a41206a220b20024180026a41206a290300370300200241c0056a41186a220c20024180026a41186a290300370300200241c0056a41106a220d20024180026a41106a290300370300200241c0056a41086a220e20024180026a41086a29030037030020022002290380023703c005200441ff017141c000490d0520024180056a41386a220f200329030037030020024180056a41306a2009290300220637030020024180056a41286a200a290300221037030020024180056a41206a200b290300221137030020024180056a41186a200c290300221237030020024180056a41106a200d290300221337030020024180056a41086a200e2903002214370300200220022903c005221537038005200241c0046a41306a2006370300200241c0046a41286a2010370300200241c0046a41206a2011370300200241c0046a41186a2012370300200241c0046a41106a2013370300200241c0046a41086a2014370300200241c0046a41386a200f290300370300200220153703c00420072004460d05200831000121112001200720056a3602042001200841026a360200201150450d01420021060c020b200341ff0171450d04200241003a00c0020c040b2007417f6a2004460d03200831000221122001200841036a3602002001200720046b417e6a36020442022011420f838622104204540d034201210620124208862011844204882010420c882211420120114201561b7e221120105a0d030b200241206a2001103120022802200d0220022802242103200241086a200110652002290308a70d02200241086a41106a290300211320022903102112200241e8026a41206a200241f0036a41206a280200360200200241e8026a41186a200241f0036a41186a290300370300200241e8026a41106a200241f0036a41106a290300370300200241e8026a41086a200241f0036a41086a29030037030020024194036a200241c0046a41086a2903003702002002419c036a200241c0046a41106a290300370200200241a4036a200241c0046a41186a290300370200200241ac036a200241c0046a41206a290300370200200241b4036a200241e8046a290300370200200241bc036a200241f0046a290300370200200241c4036a200241f8046a290300370200200220022903f0033703e802200220022903c00437028c0320024180026a200241e8026a41e80010f6041a0c030b200042033703680c040b200042033703680c030b420221060b20024198016a20024180026a41e80010f6041a024020064202520d00200042033703680c020b200241306a20024198016a41e80010f6041a0b200241e8026a200110b801024020022d00e8024113460d002000200241306a41e80010f60422014190016a201337030020014188016a201237030020014180016a2003360200200141f8006a2011370300200120103703702001200637036820014198016a200241e8026a41880110f6041a0c010b200042033703680b20024180066a24000bb18a0107087f017e067f057e017f027e017f230041e0096b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200200541124b0d14200141046a210720050e130102030405060708090a0b0c0d0e0f10111213010b200041133a00000c440b02402006450d0020042d0001210620012003417e6a22083602042001200441026a360200200641054b0d004101210902400240024002400240024020060e06490001020304490b200241086a2001103120022802080d052001280204200228020c2204490d052004417f4c0d1d02400240024020040d00410121050c010b200410342205450d0120072802002004490d0620052001280200200410f6041a200128020422032004490d202001200320046b3602042001200128020020046a3602000b2005450d062004ad220a422086200a84210a410221090c490b20044101102c000b20084108490d042004290002210a2001200341766a36020420012004410a6a360200410321090c470b200241106a2001103120022802100d03200128020420022802142204490d032004417f4c0d1b02400240024020040d00410121050c010b200410342205450d0120072802002004490d0420052001280200200410f6041a200128020422032004490d1f2001200320046b3602042001200128020020046a3602000b2005450d042004ad220a422086200a84210a410421090c470b20044101102c000b200241286a2001103120022802280d02200728020041186e220b41186c2204417f4c0d1a200228022c210c0240024020040d00410421050c010b200410292205450d1e0b0240200c450d004100210d41002106410021080340200241206a2001103102400240024020022802200d00200128020420022802242204490d002004417f4c0d1f02400240024020040d004101210e0c010b20041034220e450d3820072802002004490d01200e2001280200200410f6041a200128020422032004490d252001200320046b3602042001200128020020046a3602000b200241186a20011031024020022802180d002001280204200228021c2203490d002003417f4c0d21024002400240024020030d004101210f0c010b20031034220f450d0120072802002003490d02200f2001280200200310f6041a200128020422092003490d292001200920036b3602042001200128020020036a3602000b200841016a21092008200b470d06200d20092009200d491b220bad42187e220a422088a70d4d200aa7221041004e0d050c4d0b20034101102c000b200f102e0b2004450d010b200e102e0b02402008450d002005210103400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141186a2101200641686a22060d000b0b200b0d050c060b0240024020080d002010102921050c010b200520062010102a21050b2005450d230b200520066a2208200e360200200841146a2003ad220a3e02002008410c6a200a422086200fad84370200200841046a2004ad220a422086200a84370200200d41026a210d200641186a210620092108200c2009470d000b0b2005450d02200cad422086200bad84210a410521090c450b200241386a2001103120022802380d012007280200410c6e220e410c6c2204417f4c0d19200228023c210f0240024020040d00410421050c010b200410292205450d210b024002400240200f450d004100210841002103410021090340200241306a2001103120022802300d03200128020420022802342204490d032004417f4c0d1d0240024020040d004101210d0c010b20041034220d450d3620072802002004490d03200d2001280200200410f6041a200128020422062004490d262001200620046b3602042001200128020020046a3602000b200941016a210602402009200e470d002008200620062008491b220ead420c7e220a422088a70d48200aa7220b4100480d480240024020090d00200b102921050c010b20052003200b102a21050b2005450d270b200520036a2209200d360200200941086a2004360200200941046a2004360200200841026a21082003410c6a210320062109200f2006470d000b0b2005450d03200fad422086200ead84210a410621090c460b200d102e0b02402009450d002005210103400240200141046a280200450d002001280200102e0b2001410c6a2101200341746a22030d000b0b200e450d010b2005102e0b200041133a00000c430b2006450d2020042d0001210520012003417e6a22063602042001200441026a36020020050d202006450d2020042d0002210520012003417d6a22073602042001200441036a360200200541014b0d20410221060240024020050e020100010b2007450d2120042d0003210620012003417c6a3602042001200441046a3602000b200020063a0001200041013a0000200041026a200241d8086a41860110f6041a0c420b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241c0006a200110642002290340a70d002002290348210a200041023a0000200020022800d007360001200041086a200a370300200041046a200241d3076a280000360000200041106a200241d8086a41f80010f6041a0c420b200041133a00000c410b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241d0076a2001103b20022802d00722010d110b200041133a00000c400b02402006450d0020012003417e6a3602042001200441026a3602000b200041133a00000c3f0b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541014b0d0002400240024020050e020001000b200241d0076a2001104820022d00d0074102460d02200241b8056a41086a2209200241ec076a2902003703002002200241e4076a2902003703b805200241d0076a41106a2802002104200241dc076a2802002103200241d0076a41086a280200210520022802d407210620022802d0072107200241d0006a200110652002290350a70d02200241d0006a41106a290300210a20022903582111200241e0066a41086a2009290300370300200220022903b8053703e006410121010c010b200241d0076a2001104820022d00d0074102460d01200241b8056a41086a200241ec076a2902003703002002200241e4076a2902003703b805200241d0076a41106a2802002104200241dc076a2802002103200241d0076a41086a280200210520022802d407210620022802d007210720024180016a20011065200229038001a70d0120024180016a41106a290300210a2002290388012111200241e8006a200110652002290368a70d01200241e8006a41106a290300211220022903702113200241e0066a41086a200241b8056a41086a290300370300200220022903b8053703e006410221010b20024198066a41086a200241e0066a41086a2903002214370300200220022903e006221537039806200041c8006a2012370000200041c0006a2013370000200041386a200a370000200041306a2011370000200041053a0000200020022800b807360001200041046a200241bb076a2800003600002000411c6a2004360000200041186a2003360000200041146a2005360000200041106a20063600002000410c6a2007360000200041086a2001360000200041206a2015370000200041286a2014370000200041d0006a20022903d808370300200041d8006a200241d8086a41086a290300370300200041e0006a200241d8086a41106a290300370300200041e8006a200241d8086a41186a290300370300200041f0006a200241d8086a41206a290300370300200041f8006a200241d8086a41286a29030037030020004180016a200241d8086a41306a2903003703000c3f0b200041133a00000c3e0b2006450d3a20042d0001210520012003417e6a220b3602042001200441026a3602002005410d4b0d3a4104210f024002400240024002400240024002400240024002400240024020050e0e00010246030405060708090a0b0c000b200241d0076a2001104820022d00d0074102460d46200241bc056a200241ec076a2d00003a00002002200241e8076a2802003602b8052002200241ee076a2f01003b01d804200241dc076a2902002111200241e4076a2802002108200241ed076a2d0000210d200241f0076a280200210e20022902d407210a20022802d007210620024198016a20011065200229039801a70d4620072802002204450d46200241a8016a290300211220022903a0012113200128020022032d0000210920012004417f6a3602044101210f2001200341016a360200200941024b0d46200241c4076a41046a200241b8056a41046a2d00003a0000200220022802b8053602c407200220022f01d8043b01d006200220022f0198063b01d8060c450b200241b0016a2001106520022903b001a70d45200241c0016a290300211120022903b801210a200241c4076a41046a20024188076a41046a2d00003a0000200220022f01d0073b01d80620022002280288073602c407200220022f0186073b01d0064102210f0c430b200241c8016a2001106520022903c801a70d44200241d8016a290300211120022903d001210a200241c4076a41046a20024190076a41046a2d00003a0000200220022f01d0073b01d80620022002280290073602c407200220022f018e073b01d0064103210f0c420b200241f8016a2001103120022802f8010d4320022802fc012108200241e0016a2001106520022903e001a70d43200241f0016a290300211120022903e801210a200241c4076a41046a200241d0076a41046a2d00003a0000200220022f01b8053b01d806200220022802d0073602c407200220022f01d8043b01d0064105210f0c410b20024180026a200110312002280280020d42200728020041246e221041246c2204417f4c0d1920022802840221160240024020040d00410421060c010b200410292206450d250b02402016450d00200241d0076a41017221034100210941002107410021040340200241d0076a20011048200241b8056a41086a2208200341086a290000370300200241b8056a41106a220d200341106a290000370300200241b8056a41186a220e200341186a290000370300200220032900003703b805200220022f01f2073b01b807024020022d00d007220f4102470d002010450d452006102e0c450b200441016a210520022d00f107210b200241d8046a41186a220c200e290300370300200241d8046a41106a220e200d290300370300200241d8046a41086a220d2008290300370300200220022903b8053703d804200220022f01b8073b01a007024020042010470d002009200520052009491b2210ad42247e220a422088a70d46200aa722084100480d460240024020040d002008102921060c010b200620072008102a21060b2006450d280b200620076a2204200f3a0000200c290300210a200e2903002111200d290300211320022903d8042112200441216a200b3a0000200441016a2012370000200441096a2013370000200441116a2011370000200441196a200a370000200441226a20022f01a0073b0000200941026a2109200741246a21072005210420162005470d000b0b2006450d422016ad4220862010ad84210a200241c4076a41046a20024198066a41046a2d00003a0000200220022f0198073b01d80620022002280298063602c407200220022f0190073b01d006420021114106210f0c400b4107210f0c3f0b200b450d4020042d0002210920012003417d6a3602042001200441036a360200200941034f0d40200241c4076a41046a200241d0076a41046a2d00003a0000200220022f01b8053b01d806200220022801d0073602c407200220022f01d8043b01d0064108210f0c3f0b200241d0076a2001104820022d00d0074102460d3f200241a0076a41046a200241ec076a2d000022013a0000200241c4076a41046a20013a00002002200241e8076a28020022013602a0072002200241ee076a2f010022043b018807200220022f0190073b01d806200220013602c407200241dc076a2902002111200241e4076a2802002108200241ed076a2d0000210d200241f0076a280200210e20022902d407210a20022802d0072106200220043b01d0064109210f0c3d0b20024188026a200110312002280288020d3e200228028c022106200241c4076a41046a200241d0076a41046a2d00003a0000200220022f01b8053b01d806200220022802d0073602c407200220022f01d8043b01d006410a210f0c3c0b410b210f0c3b0b410c210f0c3a0b20024190026a200110312002280290020d3b2002280294022106200241c4076a41046a200241b8076a41046a2d00003a0000200220022f01d8043b01d806200220022802b8073602c407200220022f0198073b01d006410d210f0c390b200241d0076a2001103020022802d0072206450d3a200241c4076a41046a200241b8056a41046a2d00003a0000200220022f0188073b01d806200220022802b8053602c407200220022f01d8043b01d00620022902d407210a42002111410e210f0c380b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241d8086a2001107820022d00d8084101460d00200241d0076a200241d8086a41017241e00010f6041a20024198026a200110312002280298020d002001280204200228029c022204490d002004417f4c0d11024002400240024020040d004101210341010d010c040b200410342203450d0120072802002004490d0220032001280200200410f6042105200128020422062004490d212001200620046b3602042001200128020020046a3602002005450d030b200241b8056a200241d0076a41e00010f6041a200241d8046a200241b8056a41e00010f6041a200041073a0000200020022f0098063b0001200041036a2002419a066a2d00003a00002000410c6a2004360000200041086a2004360000200041046a2003360000200041106a200241d8046a41e00010f6041a20004180016a200241e0066a41106a290300370300200041f8006a200241e0066a41086a290300370300200041f0006a20022903e0063703000c3f0b20044101102c000b2003102e0b200041133a00000c3c0b200241b8056a200110f90120022d00b8054112470d0c200041133a00000c3b0b200241b8056a200110fa0120022d00b8054105470d0c200041133a00000c3a0b200241b8056a200110fa0120022d00b8054105470d0c200041133a00000c390b2006450d3220042d0001210520012003417e6a3602042001200441026a360200200541094b0d32024002400240024002400240024002400240024020050e0a00010203040506070809000b200241b8056a2001104020022802b8052204450d3b200241c0056a280200210520022802bc052103200241a0026a20011031024020022802a002450d002003450d3c0c3b0b0240200728020022094104490d0020022802a402210620012802002208280000210720012009417c6a3602042001200841046a360200200241e0066a41086a200241d0076a41086a290300370300200220022903d0073703e006410121010c3a0b20030d3a0c3b0b200241b8056a2001104020022802b8052204450d3a200241c0056a280200210520022802bc052103200241a8026a20011031024020022802a802450d0020030d3a0c3b0b0240200728020022094104490d0020022802ac02210620012802002208280000210720012009417c6a3602042001200841046a360200200241e0066a41086a200241d0076a41086a290300370300200220022903d0073703e006410221010c390b20030d390c3a0b200241c0026a2001103120022802c0020d3920022802c4022104200241d0076a2001104820022d00d0074102460d39200241b8056a41086a200241e8076a2903003703002002200241e0076a2903003703b805200241dc076a2802002107200241d0076a41086a2802002106200241f0076a280200210920022802d407210520022802d0072103200241b8026a2001103120022802b8020d3920022802bc022108200241b0026a2001103120022802b0020d3920022802b4022101200241e0066a41086a200241b8056a41086a290300370300200220022903b8053703e0062001ad210a42002111410321010c370b200241c8026a2001103120022802c8020d3820022802cc022104200241e0066a41086a200241d0076a41086a290300370300200220022903d0073703e006410421010c360b200241d0026a2001103120022802d0020d3720022802d4022104200241e0066a41086a200241d0076a41086a290300370300200220022903d0073703e006410521010c350b200241d0076a2001104820022d00d0074102460d36200241b8056a41086a200241ec076a2902003703002002200241e4076a2902003703b805200241d0076a41106a2802002107200241dc076a2802002106200241d0076a41086a280200210520022802d407210320022802d0072104200241e0026a2001106520022903e002a70d36200241e0026a41106a290300211120022903e802210a200241d8026a2001103120022802d8020d3620022802dc022109200241e0066a41086a200241b8056a41086a290300370300200220022903b8053703e006410621010c340b200241f8026a2001103120022802f8020d3520022802fc022104200241e0066a41086a200241d0076a41086a290300370300200220022903d0073703e006410721010c330b200241d0076a2001104820022d00d0074102460d3441082101200241e0066a41086a200241ec076a2902003703002002200241e4076a2902003703e006200241e0076a2802002107200241dc076a2802002106200241d0076a41086a280200210520022802d407210320022802d00721040c320b20024180036a200110312002280280030d332002280284032104200241e0066a41086a200241d0076a41086a290300370300200220022903d0073703e006410921010c310b20024188036a200110312002280288030d32200228028c032104200241e0066a41086a200241d0076a41086a290300370300200220022903d0073703e006410a21010c300b2006450d2e20042d0001210520012003417e6a3602042001200441026a360200200541034b0d2e0240024002400240024020050e0400010203000b41002105200241003a00f0072003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d34200241003a00f0070c340b200241d0076a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00f0072003417f6a21032006210520064120470d000b2002418c076a200241d0076a41086a2d00003a0000200220022802d4072201360288072002419e076a20022d008a073a0000200220022f01da0722033b018607200220022802d007220836029807200220013b019c07200241d0076a41186a290300210a20022903e007211120022802dc07210420022f008b072101200220022d00d9073a00ba05200220013b01b805200220043600bd05200220033b00bb05200241c9056a200a370000200220113700c105200220022f0099073b01d006200228009b07210120022903b8052113200241e0066a41186a200241d8046a41186a290000370300200241e0066a41106a200241d8046a41106a290000370300200241e0066a41086a200241d8046a41086a290000370300200220022900d8043703e006200220022f01a0073b01c4062004411876210d410121040c030b41002105200241003a00f0072003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d33200241003a00f0070c330b200241d0076a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00f0072003417f6a21032006210520064120470d000b2002418c076a200241d0076a41086a2d00003a0000200220022802d407220136028807200241b2076a20022d008a073a0000200220022f01da0722033b018607200220022802d00722083602ac07200220013b01b007200241d0076a41186a290300210a20022903e007211120022802dc07210420022f008b072101200220022d00d9073a00a207200220013b01a007200220043600a507200220033b00a307200220022f00ad073b01d00620022800af07210120022903a0072113200241e0066a41186a200241b8056a41186a290000370300200241e0066a41106a200241b8056a41106a290000370300200241e0066a41086a200241b8056a41086a290000370300200220022900b8053703e006200220022f01b8073b01c4062004411876210d410221040c020b41002105200241003a00f007410220036b21092003417d6a210603400240200920056a0d00200541ff0171450d32200241003a00f0070c320b200241d0076a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a00f0072006417f6a21062007210520074120470d000b2002418c076a200241d8076a2d00003a0000200220022802d407220536028807200241ca076a20022d008a073a0000200220022f01da0722093b018607200220022802d00722083602c407200220053b01c807200241d0076a41186a290300210a20022903e007211120022802dc07210d20022f008b072105200220022d00d9073a00ba07200220053b01b8072002200d3600bd07200220093b00bb0741002105200241003a00f007200420076a2109200d411876210d200720036b41026a210303400240200320056a0d00200541ff0171450d32200241003a00f0070c320b200241d0076a20056a200920056a220441026a2d00003a0000200120063602042001200441036a3602002002200541016a22043a00f0072006417f6a21062004210520044120470d000b2002418c076a200241d0076a41086a2d00003a0000200220022802d407220136028807200241a6076a20022d008a073a0000200220022f01da0722043b018607200220022802d0073602a007200220013b01a407200241d0076a41186a290300211320022903e007211220022802dc07210120022f008b072103200220022d00d9073a00ba05200220033b01b805200220013600bd05200220043b00bb05200241c9056a2013370000200220123700c105200220022f00c50722043b01b60720022903b807211320022800c7072101200220043b01d006200220022800a3073600e306200220022802a0073602e006200241ff066a200241b8056a41186a2d00003a0000200241f7066a200241c8056a290300370000200241ef066a200241b8056a41086a290300370000200220022903b8053700e706200220022f01d8043b01c406410321040c010b200241b8056a2001103020022802b8052201450d2f200241e0066a41086a200241d0076a41086a290000370300200241e0066a41106a200241d0076a41106a290000370300200241e0066a41186a200241d0076a41186a290000370300200220022f0188073b01d006200220022900d0073703e006200220022f01d8043b01c40620022902bc052113410421040b20024198066a41086a2203200241e0066a41086a29030037030020024198066a41106a2205200241e0066a41106a29030037030020024198066a41186a2206200241e0066a41186a290300370300200220022f01d0063b01bc06200220022903e00637039806200220022f01c4063b01ce072000410c3a0000200020022f00d8063b0001200041036a200241da066a2d00003a0000200041056a20083a0000200041046a20043a00002000411d6a200a370000200041156a2011370000200041146a200d3a00002000410c6a2013370000200041086a2001360000200041066a20022f01bc063b0000200041256a2002290398063700002000412d6a2003290300370000200041356a20052903003700002000413d6a2006290300370000200041c6006a20022f01ce073b000020004180016a20024190096a290300370300200041f8006a20024188096a290300370300200041f0006a20024180096a290300370300200041e8006a200241f8086a290300370300200041e0006a200241d8086a41186a290300370300200041d8006a200241d8086a41106a290300370300200041d0006a200241d8086a41086a290300370300200041c8006a20022903d8083703000c370b024002402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d0020024190036a20011031200228029003450d010b200041133a00000c370b20022802940321012000410d3a0000200020022f00d0073b0001200041046a2001360200200041036a200241d2076a2d00003a0000200041086a200241d8086a41800110f6041a0c360b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d0020024198036a200110312002280298030d002001280204200228029c032204490d002004417f4c0d0a024002400240024020040d00410121030c010b200410342203450d0120072802002004490d0220032001280200200410f6041a200128020422052004490d1b2001200520046b3602042001200128020020046a3602000b2003450d022000410e3a0000200020022f00d0073b0001200041086a2004ad220a422086200a84370000200041046a2003360000200041036a200241d2076a2d00003a0000200041106a200241d8086a41f80010f6041a0c380b20044101102c000b2003102e0b200041133a00000c350b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541024b0d0002400240024020050e03000102000b200241a0036a2001106520022903a003a70d02200241b0036a290300210a20022903a8032111200241d0076a2001104820022d00d0074102460d02200241b8056a41086a200241ec076a2902003703002002200241e4076a2902003703b805200241e0076a2802002101200241dc076a2802002104200241d0076a41086a280200210320022802d407210520022802d0072106410121070c2d0b200241b8036a2001103120022802b8030d0120022802bc032106200241b8056a41086a200241d0076a41086a290300370300200220022903d0073703b805410221070c2c0b200241c0036a2001103120022802c0030d0020022802c4032106200241b8056a41086a200241d0076a41086a290300370300200220022903d0073703b805410321070c2b0b200041133a00000c340b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541044b0d0002400240024002400240024020050e050001020304000b200241d8086a200110fb0120022d00c8094102460d05200241d8066a41046a200241f0086a2d00003a0000200241d8076a20024188096a290300370300200241e0076a20024190096a290300370300200220022802ec083602d806200220022f01f2083b01d60620022002290380093703d00720022802e808210520022903e008210a20022903d808211120022d00f108210420022802f408210320022903f8082113200241d0066a41046a200241b8096a2d00003a0000200220022802b4093602d006200220022f01ba093b01ce06200220022f01b8053b01de06200241a8096a2903002114200241c8096a290300211520022903a009211720022802b009210d200229039809211220022d00b909210120022802bc09210620022903c0092118410121070c2e0b200241d0036a2001106420022903d003a70d0420022903d803210a200241c8036a2001103120022802c8030d04200128020420022802cc032204490d042004417f4c0d0c02400240024020040d00410121090c010b200410342209450d0120072802002004490d0520092001280200200410f6041a200128020422032004490d1d2001200320046b3602042001200128020020046a3602000b2009450d052004ad22114220862011842111200241d8066a41046a200241b8056a41046a2d00003a0000200241d0076a41086a200241d8086a41086a290300370300200241d0076a41106a200241d8086a41106a290300370300200241d0066a41046a200241e0066a41046a2d00003a0000200220022f0198073b01de06200220022802b8053602d806200220022f01b8073b01d606200220022903d8083703d007200220022802e0063602d006200220022f01a0073b01ce06410221070c2e0b20044101102c000b200241d8086a2001104820022d00d8084102460d03200241bc056a200241f4086a2d00003a00002002200241f0086a2802003602b8052002200241f6086a2f01003b01e006200241e4086a290200210a200241ec086a2802002105200241f5086a2d00002104200241f8086a280200210320022902dc08211120022802d8082109200241f8036a2001106520022903f803a70d0320024188046a29030021132002290380042114200241e8036a2001106420022903e803a70d0320022903f0032112200241e0036a2001103120022802e0030d03200128020420022802e4032206490d032006417f4c0d0b024002400240024020060d004101210841010d010c070b200610342208450d0120072802002006490d0220082001280200200610f60421072001280204220d2006490d1e2001200d20066b3602042001200128020020066a3602002007450d060b200241a0076a41046a200241b8056a41046a2d000022013a0000200241e0076a2013370300200241d8066a41046a20013a0000200241d0066a41046a200241b8076a41046a2d00003a0000200220022802b80522013602a007200220022f01e00622073b018807200220143703d807200220022f0190073b01de06200220013602d806200220073b01d606200220022802b8073602d006200220063602d007200220022f0198073b01ce062006ad4220862008ad842113410321070c2e0b20064101102c000b2008102e0c030b200241a8046a2001106520022903a804a70d02200241b8046a290300211220022903b004211420024198046a20011064200229039804a70d0220022903a004211541002103200241003a00f8082007280200417f6a21040240024002400240024003402004417f460d01200241d8086a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00f8082004417f6a21042005210320054120470d000b200241a8076a200241e7086a2d00003a0000200220022800db083600c707200220022802d8083602c407200220022900df083703a007200220022802c4073602ac07200220022800c7073600af07200241f0086a290300211720022903e808211820024190046a200110312002280290040d0720012802042002280294042204490d072004417f4c0d0f20040d01410121030c020b200341ff0171450d06200241003a00f8080c060b200410342203450d0120072802002004490d0220032001280200200410f6041a200128020422052004490d1e2001200520046b3602042001200128020020046a3602000b2003450d042004ad220a422086200a842113200220183700c105200241c9056a2017370000200241b8056a41086a2201200241a0076a41086a2d00003a0000200220022802ac07220836029807200220022800af0736009b07200220022903a00722113703b805200220022f0099073b01de062001290300210a41042107200228009b072109200241d8066a41046a200241d0056a2d00003a0000200220022802cc053602d806200220022f0188073b01d606200220123703d807200220143703d007200220153703e007200241d0066a41046a200241e0066a41046a2d00003a0000200220022802e0063602d006200220022f0190073b01ce062018423888201742088684a721050c2d0b20044101102c000b2003102e0c020b41002105200241003a00f8082003417e6a21092003417d6a21060340024020092005470d00200541ff0171450d03200241003a00f8080c030b200241d8086a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a00f8082006417f6a21062007210520074120470d000b200220022802d80822083602c407200220022800db083600c707200220022f00c5073b01b6072003417e6a2007460d01200241f0086a2903002112200241e7086a2d0000210e20022903e808211420022900df08211120022800c7072109200420076a220d41026a2d00002105200120063602042001200d41036a360200200541014b0d01410021040240024020050e020100010b41002104200241003a00f808200720036b41036a2106200320076b417c6a210303400240200620046a0d00200441ff0171450d04200241003a00f8080c040b200241d8086a20046a200d20046a220541036a2d00003a0000200120033602042001200541046a3602002002200441016a22053a00f8082003417f6a21032005210420054120470d000b2002418c076a2201200241e0086a2d00003a0000200220022802dc0836028807200220022f01e20822043b018607200220022802d8083602b807200241f0086a290300211720022903e808211520022802e408210320022d00e1082105200220022f0188073b01bc07200220012d00003a00e206200220022f018a073b01e006200220053a00e306200220033601e606200220043b01e4064101210420022903e00621130b200220143700c105200241c9056a2012370000200220022f01b8073b01d606200220022f01e8063b01d007200220083a00a007200220093600a307200220022f01b60722013b00a1072002200e3a00c005200220113703b805200220013b01de0620022801ba07210320022903c005210a200241d8066a41046a200241d0056a2d00003a0000200220022802cc053602d806200241da076a2017370100200220153701d207200241e6076a200241ac076a41046a2f01003b0100200220022801ac073601e207200241d0066a41046a20024198076a41046a2d00003a000020022002280198073602d006200220022f01ce073b01ce062014423888201242088684a72105410521070c2a0b2009102e0b200041133a00000c330b2006450d2620042d0001210520012003417e6a3602042001200441026a360200200541014b0d2602400240024020050e020001000b200241d0076a200110b80120022d00d0074113470d010c280b200241d8086a200110484102210120022d00d8084102460d27200241e0066a41086a200241f4086a2902003703002002200241ec086a2902003703e006200241e8086a2802002103200241e4086a2802002105200241d8086a41086a280200210620022802dc08210720022802d80821040c260b200241d8086a200241d0076a41880110f6041a41880110292204450d182004200241d8086a41880110f6041a200241e0066a41086a200241d8046a41086a290200370300200220022902d8043703e006410121010c250b2006450d2320042d0001210520012003417e6a22063602042001200441026a36020020050d2320064104490d232004280002210b20012003417a6a3602042001200441066a360200200241d0046a2001103120022802d0040d23200128020420022802d4042205490d232005417f4c0d050240024020050d004101210c41010d010c250b20051034220c450d1f20072802002005490d23200c2001280200200510f6042104200128020422032005490d192001200320056b3602042001200128020020056a3602002004450d240b200241c8046a2001103120022802c8040d212007280200410c6e220f410c6c2204417f4c0d0520022802cc0421100240024020040d004104210e0c010b20041029220e450d1a0b0240024002400240024002402010450d004100210841002103410021090340200241c0046a2001103120022802c0040d03200128020420022802c4042204490d032004417f4c0d0c0240024020040d004101210d0c010b20041034220d450d2720072802002004490d03200d2001280200200410f6041a200128020422062004490d222001200620046b3602042001200128020020046a3602000b200941016a210602402009200f470d002008200620062008491b220fad420c7e220a422088a70d37200aa722164100480d370240024020090d0020161029210e0c010b200e20032016102a210e0b200e450d230b200e20036a2209200d360200200941046a2004ad220a422086200a84370200200841026a21082003410c6a21032006210920102006470d000b0b200e450d26200c450d28200728020022034104490d0220012802002207280000210820012003417c6a22043602042001200741046a36020020044104490d032007280004210d2001200341786a22093602042001200741086a36020041002104200241003a009809200341776a2103034020092004460d05200241d8086a20046a200720046a220641086a2d00003a0000200120033602042001200641096a3602002002200441016a22063a0098092003417f6a210320062104200641c000470d000b200241d0076a41386a2201200241d8086a41386a290300370300200241d0076a41306a2204200241d8086a41306a290300370300200241d0076a41286a2203200241d8086a41286a290300370300200241d0076a41206a2207200241d8086a41206a290300370300200241d0076a41186a2209200241d8086a41186a290300370300200241d0076a41106a2216200241d8086a41106a290300370300200241d0076a41086a2219200241d8086a41086a290300370300200220022903d8083703d007200641ff017141c000490d25200241b8056a41386a22062001290300370300200241b8056a41306a2004290300220a370300200241b8056a41286a20032903002211370300200241b8056a41206a20072903002213370300200241b8056a41186a20092903002212370300200241b8056a41106a20162903002214370300200241b8056a41086a20192903002215370300200220022903d00722173703b805200241d8046a41306a2201200a370300200241d8046a41286a22042011370300200241d8046a41206a22032013370300200241d8046a41186a22072012370300200241d8046a41106a22092014370300200241d8046a41086a22162015370300200241d8046a41386a22192006290300370300200220173703d804200041123a0000200041246a200d360000200041206a20083600002000411c6a2010360000200041186a200f360000200041146a200e360000200041106a20053600002000410c6a2005360000200041086a200c360000200041046a200b360000200020022f0098063b0001200041036a2002419a066a2d00003a0000200041286a20022903d804370000200041306a2016290300370000200041386a2009290300370000200041c0006a2007290300370000200041c8006a2003290300370000200041d0006a2004290300370000200041d8006a2001290300370000200041e0006a201929030037000020004180016a200241e0066a41186a290300370300200041f8006a200241e0066a41106a290300370300200041f0006a200241e0066a41086a290300370300200041e8006a20022903e0063703000c360b200d102e0b02402009450d00200e210103400240200141046a280200450d002001280200102e0b2001410c6a2101200341746a22030d000b0b200f450d24200e102e0c240b02402005450d00200c102e0b02402010450d002010410c6c2104200e210103400240200141046a280200450d002001280200102e0b2001410c6a2101200441746a22040d000b0b200f450d25200e102e0c250b02402005450d00200c102e0b02402010450d002010410c6c2104200e210103400240200141046a280200450d002001280200102e0b2001410c6a2101200441746a22040d000b0b200f450d24200e102e0c240b200441ff0171450d20200241003a0098090c200b200041133a00000c300b20022902d407210a200041033a0000200020022f00b8053b0001200041086a200a370000200041046a2001360000200041036a200241ba056a2d00003a0000200041106a200241d8086a41f80010f6041a0c2f0b200241d8046a41286a200241b8056a41286a290300220a370300200241d8046a41206a200241b8056a41206a2903002211370300200241df076a200241b8056a41086a290300370000200241e7076a200241b8056a41106a290300370000200241ef076a200241b8056a41186a290300370000200241f7076a2011370000200241ff076a2201200a370000200220022903b8053700d707200041083a0000200041096a200241d0076a41086a290000370000200041116a200241d0076a41106a290000370000200041196a200241d0076a41186a290000370000200041216a200241d0076a41206a290000370000200041296a200241d0076a41286a290000370000200020022900d007370001200041306a2001290000370000200041386a200241d8086a41d00010f6041a0c2e0b200241d8046a41206a200241b8056a41206a290300220a370300200241db076a200241b8056a41086a290300370000200241e3076a200241b8056a41106a290300370000200241eb076a200241b8056a41186a290300370000200241f3076a200a370000200220022903b8053700d307200041093a0000200020022900d007370001200041096a200241d0076a41086a290000370000200041116a200241d0076a41106a290000370000200041196a200241d0076a41186a290000370000200041216a200241d0076a41206a290000370000200041286a200241f7076a2800003600002000412c6a200241d8086a41dc0010f6041a0c2d0b200241d8046a41206a200241b8056a41206a290300220a370300200241db076a200241b8056a41086a290300370000200241e3076a200241b8056a41106a290300370000200241eb076a200241b8056a41186a290300370000200241f3076a200a370000200220022903b8053700d3072000410a3a0000200020022900d007370001200041096a200241d0076a41086a290000370000200041116a200241d0076a41106a290000370000200041196a200241d0076a41186a290000370000200041216a200241d0076a41206a290000370000200041286a200241f7076a2800003600002000412c6a200241d8086a41dc0010f6041a0c2c0b1032000b200420031035000b200420031035000b20044104102c000b200420031035000b200320091035000b20104104102c000b20044104102c000b200420061035000b200b4104102c000b200041133a00000c210b20044104102c000b20084104102c000b200420061035000b200420051035000b200420031035000b2006200d1035000b200420051035000b4188014108102c000b200520031035000b20044104102c000b200420061035000b20164104102c000b20044101102c000b20044101102c000b20054101102c000b20044101102c000b02402005450d00200c102e0b02402010450d002010410c6c2104200e210103400240200141046a280200450d002001280200102e0b2001410c6a2101200441746a22040d000b0b200f450d02200e102e0c020b2005450d010b200c102e0b200041133a00000c0d0b20024198066a41086a200241e0066a41086a290300220a370300200220022903e006221137039806200041113a0000200020022f00b8073b0001200041036a200241ba076a2d00003a0000200041186a2003360000200041146a2005360000200041106a20063600002000410c6a2007360000200041086a2004360000200041046a20013600002000411c6a2011370000200041246a200a3700002000412c6a200241b8056a41dc0010f6041a0c0c0b200041133a00000c0b0b200241c4066a41046a220e200241d8066a41046a2d00003a0000200241d8046a41086a220f200241d0076a41086a290300370300200241d8046a41106a220b200241d0076a41106a290300370300200241bc066a41046a220c200241d0066a41046a2d00003a0000200220022f01de063b01cc06200220022802d8063602c406200220022f01d6063b01c206200220022903d0073703d804200220022802d0063602bc06200220022f01ce063b01ba06200041103a00002000200228009806360001200041046a2002419b066a280000360000200041096a20083a0000200041086a20073a0000200041206a2005360000200041186a200a370000200041106a20113700002000410c6a20093600002000410a6a20022f01cc063b0000200041296a20043a0000200041246a20022802c406360000200041286a200e2d00003a000020022f01c2062104200041306a20133700002000412c6a20033600002000412a6a20043b0000200041c8006a200b290300370000200041c0006a200f290300370000200041386a20022903d804370000200041e0006a2014370000200041d8006a2017370000200041e8006a200d360000200041d0006a2012370000200041f0006a200c2d00003a0000200041ec006a20022802bc06360000200041f1006a20013a000020022f01ba06210120004180016a2015370000200041f8006a2018370000200041f4006a2006360000200041f2006a20013b00000c0a0b200241e0066a41086a200241b8056a41086a2903002213370300200220022903b80522123703e006200041386a200a370000200041306a20113700002000410f3a00002000200228009806360001200041046a2002419b066a2800003600002000411c6a2001360000200041186a2004360000200041146a2003360000200041106a20053600002000410c6a2006360000200041086a2007360000200041206a2012370000200041286a2013370000200041c0006a200241d8086a41c80010f6041a0c090b200041133a00000c080b20024198066a41086a200241e0066a41086a2903002213370300200220022903e006221237039806200041c0006a2011370000200041386a200a3700002000410b3a0000200020022800b807360001200041046a200241bb076a2800003600002000411c6a2007360000200041186a2006360000200041146a2005360000200041106a20033600002000410c6a2004360000200041086a2001360000200041206a2012370000200041286a2013370000200041346a2008360000200041306a2009360000200041c8006a20022903d808370300200041d0006a200241d8086a41086a290300370300200041d8006a200241d8086a41106a290300370300200041e0006a200241d8086a41186a290300370300200041e8006a200241d8086a41206a290300370300200041f0006a200241d8086a41286a290300370300200041f8006a200241d8086a41306a29030037030020004180016a200241d8086a41386a2903003703000c070b2004102e0b200041133a00000c050b0b200241ac076a41046a2201200241c4076a41046a2d00003a0000200220022f01d80622043b01c406200220022802c4073602ac07200220022f01d0063b01bc06200041186a2011370000200041106a200a370000200041063a0000200020022800e006360001200041046a200241e3066a280000360000200041096a20093a0000200041086a200f3a0000200041206a20083600002000410c6a20063600002000410a6a20043b0000200041296a200d3a0000200041246a20022802ac07360000200041286a20012d00003a000020022f01bc062101200041386a2012370000200041306a20133700002000412c6a200e3600002000412a6a20013b0000200041c0006a200241d8086a41c80010f6041a0c030b200041133a00000c020b102d000b200041003a0000200020022800d007360001200041106a200a3700002000410c6a2005360000200041086a2009360000200041046a200241d3076a280000360000200041186a200241d8086a41f00010f6041a0b200241e0096a24000b901e07017f027e037f017e037f017e087f230041c0066b22022400420221030240024002400240024002400240200129036822044202520d00200241106a20014198016a41880110f6041a0c010b200241fc016a41026a200141036a2d00003a0000200241e0016a41086a200141146a290200370300200241e0016a410d6a200141196a290000370000200220012f00013b01fc012002200129020c3703e00120012d000021052001280204210620012802082107200241b8026a200141dc006a290000370300200241b0026a200141d4006a290000370300200241a8026a200141cc006a290000370300200241a0026a200141c4006a29000037030020024180026a41186a2001413c6a29000037030020024180026a41106a200141346a29000037030020024180026a41086a2001412c6a2900003703002002200129002437038002200241c0026a41086a20014188016a290300370300200241c0026a41106a20014190016a290300370300200220014180016a2903003703c002200141f8006a29030021032001290370210841002109200241c8036a410010ba01200241c0056a410d6a220a200241c8036a41186a290000370000200241c0056a41086a220b200241db036a290000370300200241f8056a41026a20022d00ca033a0000200241e0056a41086a200b290300370300200241e0056a410d6a200a290000370000200220022f01c8033b01f805200220022900d303220c3703c0052002200c3703e00520022800cb03210d20022800cf03210e200241086a41b0f3c200410d107d02400240024002400240024020044201520d0020084200510d01200228020c410020022802081b210a417f2109200aad220c20032003200c541b220c200c20037d2008827d220c42ffffffff0f560d00200ca721090b41101029220a450d01200a41086a41002900e7f342370000200a41002900dff342370000200a41104120102a220a450d02200a2009360010200241a0066a41186a220f4200370300200241a0066a41106a220b4200370300200241a0066a41086a22104200370300200242003703a006200a4114200241a0066a100020024180066a41186a200f29030037030020024180066a41106a200b29030037030020024180066a41086a2010290300370300200220022903a0063703800620024180066a412041c8ecc500410041001005210f200a102e02400240200f417f470d004101210a411f210941edf4c200210f0c010b200241c8036a200910ba0120024182066a20022d00ca033a0000200241a8066a200241db036a290000370300200241ad066a200241c8036a41186a290000370000200220022f01c8033b018006200220022900d3033703a00620022800cb03210f20022800cf0321094100210a0b200241fc056a41026a221020024180066a41026a2d00003a0000200241c8036a41086a2211200241a0066a41086a2212290300370300200241c8036a41106a200b290300370300200220022f0180063b01fc05200220022903a0063703c80302400240200a450d004101210a2009210e200f210d0c010b200241c4036a41026a200241f8056a41026a2d00003a00002012200241e0056a41086a290300370300200241a0066a410d6a200241e0056a410d6a290000370000200241b7066a20102d00003a000020024180066a410d6a200241c8036a410d6a29000037000020024180066a41086a2011290300370300200220022f01f8053b01c403200220022903e0053703a006200220022f01fc053b00b506200220022903c803370380064100210a0b200241c0036a41026a220b200241c4036a41026a2d00003a0000200241a8036a41086a2210200241a0066a41086a2211290300370300200241a8036a41106a2212200241a0066a41106a29030037030020024190036a41086a221320024180066a41086a29030037030020024190036a410d6a221420024180066a410d6a290000370000200220022f01c4033b01c003200220022903a0063703a8032002200229038006370390030240200a450d002000200d36020420004101360200200041086a200e36020020014198016a102f0c0b0b2002418c036a41026a220a200b2d00003a0000200241f0026a41086a220b2010290300370300200241f0026a41106a22102012290300370300200241d8026a41086a22122013290300370300200241d8026a410d6a22132014290000370000200220022f01c0033b018c03200220022903a8033703f00220022002290390033703d802200241c8036a20014198016a41880110f6041a200241c8036a4198016a2003370300200241d8046a200837030020024187056a200e36000020024183056a200d360000200241e8046a220d20022903c002370300200241f0046a200241c0026a41086a290300370300200241f8046a200241c0026a41106a29030037030020024182056a200a2d00003a00002002418b056a20022903f00237000020024193056a200b2903003700002002419b056a2010290300370000200220043703d004200220022f018c033b018005200241a7056a2009360000200241a3056a200f360000200241ab056a20022903d802370000200241b3056a2012290300370000200241b8056a201329000037000020024190036a41026a200241fc016a41026a2d00003a0000200220022f01fc013b0190032011200241e0016a41086a290300370300200241a0066a410d6a200241e0016a410d6a290000370000200220022903e0013703a0060240200541ff01714101460d00200241fc056a41026a20024190036a41026a2d00003a0000200241a8036a41086a200241a0066a41086a290300370300200241a8036a410d6a200241a0066a410d6a290000370000200220022f0190033b01fc05200220022903a0063703a8030c040b200241e0056a200641067610bb0120022802e005210a0240024020022802e8052006413f7122014b0d00410021010c010b200241fc056a41026a200a20014105746a220141026a2d00003a0000200241b0036a200141136a290000370300200241b5036a200141186a290000370000200220012f00003b01fc052002200129000b3703a8032001280007210720012800032106410121010b024020022802e405450d00200a102e0b20010d034101210141ccc4c2002106411521070c040b41b8e5c5001058000b41104101102c000b41204101102c000b200241e0056a41026a200241fc056a41026a2d00003a0000200241a0066a41086a200241a8036a41086a290300370300200241a0066a410d6a200241a8036a410d6a290000370000200220022f01fc053b01e005200220022903a8033703a006410021010b200241f8056a41026a220a200241e0056a41026a2d00003a000020024180066a41086a2209200241a0066a41086a29030037030020024180066a41106a200241a0066a41106a290300370300200220022f01e0053b01f805200220022903a0063703800602402001450d002000200636020420004101360200200041086a2007360200200241c8036a102f0c060b200241d3056a2009290300370000200241d8056a2002418d066a290000370000200220022f01f8053b01c005200220073600c705200220063600c30520022002290380063700cb052002200a2d00003a00c205200241003602a806200242013703a006200241c8036a200241a0066a10bc010240024020022903d0044201510d000240024020022802a40620022802a8062201460d0020022802a006210a0c010b200141016a220a2001490d0620014101742209200a200a2009491b22094100480d060240024020010d0020091029210a0c010b20022802a00620012009102a210a0b200a450d04200220093602a4062002200a3602a00620022802a80621010b2002200141016a3602a806200a20016a41003a00000c010b20022903e00420022903d8042204420c882203420120034201561b8021030240024020022802a406220a20022802a80622016b4102490d0020022802a006210a0c010b200141026a22092001490d05200a4101742201200920092001491b22014100480d0502400240200a0d0020011029210a0c010b20022802a006200a2001102a210a0b200a450d04200220013602a4062002200a3602a00620022802a80621010b2002200141026a3602a806200a20016a2003a741047420047aa7417f6a22014101200141014b1b2201410f2001410f491b723b00000b200d200241a0066a10662002200241f0046a3602800620024180066a200241a0066a106b20024180056a200241a0066a1046200241a0056a200241a0066a104620022802a406210a20022802a00621010240024020022802a80622094180024b0d0020024180026a20012009200241c0056a10bd0121090c010b200241a0066a41186a220b4200370300200241a0066a41106a220d4200370300200241a0066a41086a220e4200370300200242003703a00620012009200241a0066a100020024180066a41186a200b29030037030020024180066a41106a200d29030037030020024180066a41086a200e290300370300200220022903a0063703800620024180026a20024180066a4120200241c0056a10bd0121090b0240200a450d002001102e0b2009450d04200241c0016a41186a200241c0056a41186a290300370300200241c0016a41106a200241c0056a41106a290300370300200241c0016a41086a200241c0056a41086a29030037030020024198016a41086a200241e0046a29030037030020024198016a41106a200241e8046a29030037030020024198016a41186a200241f0046a290300370300200241b8016a200241f8046a290300370300200220022903c0053703c0012002200241d8046a2903003703980120022903d0042103200241106a200241c8036a41880110f6041a0b200041086a20022903c001370300200041286a2003370300200041306a200229039801370300200041206a200241c0016a41186a290300370300200041186a200241c0016a41106a290300370300200041106a200241c0016a41086a290300370300200041386a20024198016a41086a290300370300200041c0006a20024198016a41106a290300370300200041c8006a20024198016a41186a290300370300200041d0006a20024198016a41206a290300370300200041d8006a200241106a41880110f6041a20004100360200200241c0066a24000f0b20094101102c000b20014101102c000b102d000b200041949dc20036020420004101360200200041086a411a360200200241c8036a102f0b200241c0066a24000be00201047f230041d0006b2202240002400240411010292203450d00200341086a41002900e7f342370000200341002900dff342370000200341104120102a2203450d0120032001360010200241086a41186a22014200370300200241086a41106a22044200370300200241086a41086a220542003703002002420037030820034114200241086a1000200241306a41186a2001290300370300200241306a41106a2004290300370300200241306a41086a200529030037030020022002290308370330200241086a200241306a412010dc010240024020022d00084101460d0020004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b20002002290009370000200041186a200241216a290000370000200041106a200241196a290000370000200041086a200241116a2900003700000b2003102e200241d0006a24000f0b41104101102c000b41204101102c000bec0202047f017e230041d0006b22022400024002400240410f10292203450d00200341076a410029008fc24237000020034100290088c2423700002003410f411e102a2203450d012003200136000f200241286a41186a22014200370300200241286a41106a22044200370300200241286a41086a220542003703002002420037032820034113200241286a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903283703002002410036022820024120200241286a100821040240024020022802282201417f460d002002200136022420022004360220200241286a200241206a103020022802282205450d04200229022c210602402001450d002004102e0b20002006370204200020053602000c010b20004100360208200042013702000b2003102e200241d0006a24000f0b410f4101102c000b411e4101102c000b41eff0c2004133200241c8006a4184f4c2001053000bfe8c0203057f017e077f230041206b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002d0000220341124b0d00024002400240024002400240024002400240024002400240024002400240024002400240024020030e13000102030405060708090a0b0c0d0e0f101112000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5f20034101742205200420042005491b22054100480d5f0240024020030d002005102921040c010b200128020020032005102a21040b2004450d1420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002000280208417f6a220341054b0d1202400240024002400240024020030e06000102030405000b200241003a001c02400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d6420034101742204200020002004491b22044100480d640240024020030d002004102921000c010b200128020020032004102a21000b2000450d1a20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c170b200241013a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6320034101742205200420042005491b22054100480d630240024020030d002005102921040c010b200128020020032005102a21040b2004450d1a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200028020c2106200041146a28020022032001104702400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d6320044101742200200520052000491b22004100480d630240024020040d002000102921040c010b200128020020042000102a21040b2004450d1b20012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a2006200310f6041a0c160b200241023a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6220034101742205200420042005491b22054100480d620240024020030d002005102921040c010b200128020020032005102a21040b2004450d1b20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a00002000290310210702400240200141046a2802002200200528020022036b4108490d00200128020021000c010b200341086a22042003490d6220004101742203200420042003491b22034100480d620240024020000d002003102921000c010b200128020020002003102a21000b2000450d1c20012000360200200141046a2003360200200141086a28020021030b200141086a200341086a360200200020036a20073700000c150b200241033a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6120034101742205200420042005491b22054100480d610240024020030d002005102921040c010b200128020020032005102a21040b2004450d1c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a0000200028020c2106200041146a28020022032001104702400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d6120044101742200200520052000491b22004100480d610240024020040d002000102921040c010b200128020020042000102a21040b2004450d1d20012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a2006200310f6041a0c140b200141086a2802002103200241043a001c024002402003200141046a280200460d00200128020021050c010b200341016a22042003490d6020034101742205200420042005491b22044100480d600240024020030d002004102921050c010b200128020020032004102a21050b2005450d1d20012005360200200141046a2004360200200141086a28020021030b200141086a2204200341016a360200200520036a41043a0000200028020c2103200041146a2802002200200110472000450d132003200041186c6a2108200141046a2106034020032802002109200341086a280200220020011047024002402006280200220a200428020022056b2000490d002001280200210a0c010b200520006a220b2005490d61200a4101742205200b200b2005491b22054100480d6102400240200a0d0020051029210a0c010b2001280200200a2005102a210a0b200a450d1f2001200a36020020062005360200200428020021050b2004200520006a360200200a20056a2009200010f6041a2003410c6a2802002109200341146a280200220020011047024002402006280200220a200428020022056b2000490d002001280200210a0c010b200520006a220b2005490d61200a4101742205200b200b2005491b22054100480d6102400240200a0d0020051029210a0c010b2001280200200a2005102a210a0b200a450d202001200a36020020062005360200200428020021050b2004200520006a360200200a20056a2009200010f6041a200341186a22032008470d000c140b0b200241053a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5f20034101742205200420042005491b22054100480d5f0240024020030d002005102921040c010b200128020020032005102a21040b2004450d1f20012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41053a0000200028020c2104200041146a2802002203200110472003450d1220042003410c6c6a2108200141046a210903402004280200210a200441086a2802002203200110470240024020092802002205200628020022006b2003490d00200128020021050c010b200020036a220b2000490d6020054101742200200b200b2000491b22004100480d600240024020050d002000102921050c010b200128020020052000102a21050b2005450d212001200536020020092000360200200628020021000b2006200020036a360200200520006a200a200310f6041a2004410c6a22042008470d000c130b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5e20034101742205200420042005491b22054100480d5e0240024020030d002005102921040c010b200128020020032005102a21040b2004450d2020012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5e20034101742205200420042005491b22054100480d5e0240024020030d002005102921040c010b200128020020032005102a21040b2004450d2120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200141046a280200210420052802002103024020002d00014102470d000240024020042003460d00200128020021000c010b200341016a22002003490d5f20034101742204200020002004491b22044100480d5f0240024020030d002004102921000c010b200128020020032004102a21000b2000450d2320012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c120b0240024020042003460d00200128020021040c010b200341016a22042003490d5e20034101742205200420042005491b22054100480d5e0240024020030d002005102921040c010b200128020020032005102a21040b2004450d2320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5e20034101742205200420042005491b22054100480d5e0240024020030d002005102921040c010b200128020020032005102a21040b2004450d2420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00013a00000c110b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5d20034101742205200420042005491b22054100480d5d0240024020030d002005102921040c010b200128020020032005102a21040b2004450d2420012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5d20034101742205200420042005491b22054100480d5d0240024020030d002005102921040c010b200128020020032005102a21040b2004450d2520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041086a200110670c100b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5c20034101742205200420042005491b22054100480d5c0240024020030d002005102921040c010b200128020020032005102a21040b2004450d2520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5c20034101742205200420042005491b22054100480d5c0240024020030d002005102921040c010b200128020020032005102a21040b2004450d2620012004360200200141046a2005360200200141086a28020021030b200141086a220a200341016a360200200420036a41003a00002000280204210c2000410c6a2802002203200110472003450d0f200c200341f0006c6a210d200141046a210b0340200c41106a20011046200c20011066200c41306a20011046200c41d0006a20011046200c2802042104200c28020c22032001104702402003450d00200341246c21090340200241086a200410452002280208210602400240200b2802002205200a28020022036b20022802102200490d00200128020021050c010b200320006a22082003490d5f20054101742203200820082003491b22034100480d5f0240024020050d002003102921050c010b200128020020052003102a21050b2005450d2a20012005360200200b2003360200200a28020021030b200a200320006a360200200520036a2006200010f6041a0240200228020c450d002006102e0b200441246a21042009415c6a22090d000b0b200c41f0006a220c200d470d000c100b0b02400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d5b20034101742204200020002004491b22044100480d5b0240024020030d002004102921000c010b200128020020032004102a21000b2000450d2720012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41043a0000200110fc010c0e0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5a20034101742205200420042005491b22054100480d5a0240024020030d002005102921040c010b200128020020032005102a21040b2004450d2720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a00002000280208417f6a220341014b0d0d02400240024020030e020001000b200241003a001c02400240200141046a280200200141086a2802002203460d00200128020021050c010b200341016a22042003490d5c20034101742205200420042005491b22044100480d5c0240024020030d002004102921050c010b200128020020032004102a21050b2005450d2a20012005360200200141046a2004360200200141086a28020021030b200041306a2104200141086a200341016a360200200520036a41003a00002000410c6a20011049200241186a21030c010b200241013a001c02400240200141046a280200200141086a2802002203460d00200128020021050c010b200341016a22042003490d5b20034101742205200420042005491b22044100480d5b0240024020030d002004102921050c010b200128020020032004102a21050b2005450d2a20012005360200200141046a2004360200200141086a28020021030b200041c0006a2104200141086a200341016a360200200520036a41013a00002000410c6a200110492002200041306a36021c2002411c6a2001106b200241086a21030b2003200436020020032001106b0c0d0b02400240200141046a2206280200200141086a22042802002203460d00200128020021050c010b200341016a22052003490d592003410174220a20052005200a491b220a4100480d590240024020030d00200a102921050c010b20012802002003200a102a21050b2005450d2920012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a41063a000020002d0008417f6a2203410d4b0d0c0240024002400240024002400240024002400240024002400240024020030e0e000102030405060708090a0b0c0d000b200241003a001c02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d662003410174220a20052005200a491b220a4100480d660240024020030d00200a102921050c010b20012802002003200a102a21050b2005450d3720012005360200200141046a200a360200200141086a28020021030b200141086a200341016a360200200520036a41003a00002000410c6a200110492002200041306a360208200241086a2001106b20002d0009220341024b0d1902400240024020030e03000102000b200241003a001c02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d6820034101742205200020002005491b22054100480d680240024020030d002005102921000c010b200128020020032005102a21000b2000450d3a20012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41003a00000c1b0b200241013a001c02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d6720034101742205200020002005491b22054100480d670240024020030d002005102921000c010b200128020020032005102a21000b2000450d3a20012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41013a00000c1a0b200241023a001c02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d6620034101742205200020002005491b22054100480d660240024020030d002005102921000c010b200128020020032005102a21000b2000450d3a20012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41023a00000c190b200241013a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6520034101742205200420042005491b22054100480d650240024020030d002005102921040c010b200128020020032005102a21040b2004450d3a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002002200041106a360208200241086a2001106b0c180b200241023a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6420034101742205200420042005491b22054100480d640240024020030d002005102921040c010b200128020020032005102a21040b2004450d3a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002002200041106a360208200241086a2001106b0c170b200241033a001c02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d6320034101742205200020002005491b22054100480d630240024020030d002005102921000c010b200128020020032005102a21000b2000450d3a20012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41033a00000c160b200241043a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6220034101742205200420042005491b22054100480d620240024020030d002005102921040c010b200128020020032005102a21040b2004450d3a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41043a0000200041206a200110662002200041106a360208200241086a2001106b0c150b200241053a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6120034101742205200420042005491b22054100480d610240024020030d002005102921040c010b200128020020032005102a21040b2004450d3a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a0000200028020c2103200041146a2802002200200110472000450d14200041246c21000340200320011049200341246a21032000415c6a22000d000c150b0b200241063a001c02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d6020034101742205200020002005491b22054100480d600240024020030d002005102921000c010b200128020020032005102a21000b2000450d3a20012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41063a00000c130b200241073a001c02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5f2003410174220a20052005200a491b220a4100480d5f0240024020030d00200a102921050c010b20012802002003200a102a21050b2005450d3a20012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a41073a000020002d0009220341024b0d1202400240024020030e03000102000b200241003a001c02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d6120034101742205200020002005491b22054100480d610240024020030d002005102921000c010b200128020020032005102a21000b2000450d3d20012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41003a00000c140b200241013a001c02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d6020034101742205200020002005491b22054100480d600240024020030d002005102921000c010b200128020020032005102a21000b2000450d3d20012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41013a00000c130b200241023a001c02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5f20034101742205200020002005491b22054100480d5f0240024020030d002005102921000c010b200128020020032005102a21000b2000450d3d20012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41023a00000c120b200241083a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5e20034101742205200420042005491b22054100480d5e0240024020030d002005102921040c010b200128020020032005102a21040b2004450d3d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41083a00002000410c6a200110490c110b200241093a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5d20034101742205200420042005491b22054100480d5d0240024020030d002005102921040c010b200128020020032005102a21040b2004450d3d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a00002000410c6a200110660c100b2002410a3a001c02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5c20034101742205200020002005491b22054100480d5c0240024020030d002005102921000c010b200128020020032005102a21000b2000450d3d20012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a410a3a00000c0f0b2002410b3a001c02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5b20034101742205200020002005491b22054100480d5b0240024020030d002005102921000c010b200128020020032005102a21000b2000450d3d20012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a410b3a00000c0e0b2002410c3a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5a20034101742205200420042005491b22054100480d5a0240024020030d002005102921040c010b200128020020032005102a21040b2004450d3d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410c3a00002000410c6a200110660c0d0b2002410d3a001c02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5920034101742205200420042005491b22054100480d590240024020030d002005102921040c010b200128020020032005102a21040b2004450d3d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410d3a0000200028020c2103200041146a2802002200200110472000450d0c20004105742100034020032001104a200341206a2103200041606a22000d000c0d0b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5820034101742205200420042005491b22054100480d580240024020030d002005102921040c010b200128020020032005102a21040b2004450d3d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41073a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5820034101742205200420042005491b22054100480d580240024020030d002005102921040c010b200128020020032005102a21040b2004450d3e20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041106a2001104a200041306a2001104a200041d0006a2001104a200028020421062000410c6a28020022032001104702400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d5820044101742200200520052000491b22004100480d580240024020040d002000102921040c010b200128020020042000102a21040b2004450d3f20012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a2006200310f6041a0c0b0b02400240200141046a2206280200200141086a22042802002203460d00200128020021050c010b200341016a22052003490d572003410174220a20052005200a491b220a4100480d570240024020030d00200a102921050c010b20012802002003200a102a21050b2005450d3f20012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a41083a000020002d0008417f6a220341104b0d0a0240024002400240024002400240024002400240024002400240024002400240024020030e11000102030405060708090a0b0c0d0e0f10000b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6720034101742205200420042005491b22054100480d670240024020030d002005102921040c010b200128020020032005102a21040b2004450d5020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200028020c200110bc012002200041106a360208200241086a2001106b0c1a0b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6620034101742205200420042005491b22054100480d660240024020030d002005102921040c010b200128020020032005102a21040b2004450d5020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000410c6a200110660c190b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d6520034101742206200520052006491b22064100480d650240024020030d002006102921050c010b200128020020032006102a21050b2005450d5020012005360200200141046a2006360200200141086a28020021030b200141086a2206200341016a360200200520036a41023a00002000410c6a20011066200041096a2d000021052000410a6a2d0000210a02400240200141046a28020020062802002203460d00200128020021000c010b200341016a22002003490d6520034101742206200020002006491b22064100480d650240024020030d002006102921000c010b200128020020032006102a21000b2000450d5120012000360200200141046a2006360200200141086a28020021030b2004200341016a360200200020036a2005410047410774200a723a00000c180b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d6420034101742206200520052006491b22064100480d640240024020030d002006102921050c010b200128020020032006102a21050b2005450d5120012005360200200141046a2006360200200141086a28020021030b200141086a2206200341016a360200200520036a41033a00002000410c6a20011066200041096a2d000021052000410a6a2d0000210a02400240200141046a28020020062802002203460d00200128020021000c010b200341016a22002003490d6420034101742206200020002006491b22064100480d640240024020030d002006102921000c010b200128020020032006102a21000b2000450d5220012000360200200141046a2006360200200141086a28020021030b2004200341016a360200200020036a2005410047410774200a723a00000c170b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d632003410174220a20052005200a491b220a4100480d630240024020030d00200a102921050c010b20012802002003200a102a21050b2005450d5220012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a41043a0000200028020c21050240024020062802002200200428020022036b4104490d00200128020021000c010b200341046a22062003490d6320004101742203200620062003491b22034100480d630240024020000d002003102921000c010b200128020020002003102a21000b2000450d5320012000360200200141046a2003360200200141086a28020021030b2004200341046a360200200020036a20053600000c160b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6220034101742205200420042005491b22054100480d620240024020030d002005102921040c010b200128020020032005102a21040b2004450d5320012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a0000200028020c200110bc010c150b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6120034101742205200420042005491b22054100480d610240024020030d002005102921040c010b200128020020032005102a21040b2004450d5320012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a0000200028020c200110bc010c140b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6020034101742205200420042005491b22054100480d600240024020030d002005102921040c010b200128020020032005102a21040b2004450d5320012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a0000200028020c200110bc010c130b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5f2003410174220a20052005200a491b220a4100480d5f0240024020030d00200a102921050c010b20012802002003200a102a21050b2005450d5320012005360200200141046a200a360200200141086a28020021030b200141086a220a200341016a360200200520036a41083a0000200041096a20011046200028022c210902400240200141046a2802002205200a28020022036b4104490d00200128020021050c010b200341046a220a2003490d5f20054101742203200a200a2003491b22034100480d5f0240024020050d002003102921050c010b200128020020052003102a21050b2005450d5420012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a2009360000200028023021050240024020062802002200200428020022036b4104490d00200128020021000c010b200341046a22062003490d5f20004101742203200620062003491b22034100480d5f0240024020000d002003102921000c010b200128020020002003102a21000b2000450d5520012000360200200141046a2003360200200141086a28020021030b2004200341046a360200200020036a20053600000c120b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5e20034101742205200420042005491b22054100480d5e0240024020030d002005102921040c010b200128020020032005102a21040b2004450d5520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a0000200041096a200110460c110b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5d20034101742205200420042005491b22054100480d5d0240024020030d002005102921040c010b200128020020032005102a21040b2004450d5520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410a3a00002000410c6a200110660c100b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5c20034101742205200420042005491b22054100480d5c0240024020030d002005102921040c010b200128020020032005102a21040b2004450d5520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410b3a00002000410c6a20011066200041106a20011066200041146a200110660c0f0b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5b20034101742205200420042005491b22054100480d5b0240024020030d002005102921040c010b200128020020032005102a21040b2004450d5520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410c3a0000200041096a2001104a0c0e0b02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5a20034101742205200020002005491b22054100480d5a0240024020030d002005102921000c010b200128020020032005102a21000b2000450d5520012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a410d3a00000c0d0b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5920034101742205200420042005491b22054100480d590240024020030d002005102921040c010b200128020020032005102a21040b2004450d5520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410e3a0000200041096a2001104a0c0c0b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d582003410174220a20052005200a491b220a4100480d580240024020030d00200a102921050c010b20012802002003200a102a21050b2005450d5520012005360200200141046a200a360200200141086a28020021030b200141086a200341016a360200200520036a410f3a0000200041096a2001104a20002d0029220341064b0d0b0240024002400240024002400240024020030e0700010203040506000b410021000c060b410121000c050b410221000c040b410321000c030b410421000c020b410521000c010b410621000b200220003a001c02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5820034101742206200520052006491b22064100480d580240024020030d002006102921050c010b200128020020032006102a21050b2005450d5620012005360200200141046a2006360200200141086a28020021030b2004200341016a360200200520036a20003a00000c0b0b02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5720034101742205200020002005491b22054100480d570240024020030d002005102921000c010b200128020020032005102a21000b2000450d5620012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41103a00000c0a0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da10120034101742205200420042005491b22054100480da1010240024020030d002005102921040c010b200128020020032005102a21040b2004450d5720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a0000200041046a200110fd010c090b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da00120034101742205200420042005491b22054100480da0010240024020030d002005102921040c010b200128020020032005102a21040b2004450d5720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410a3a0000200041046a200110fd010c080b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9f0120034101742205200420042005491b22054100480d9f010240024020030d002005102921040c010b200128020020032005102a21040b2004450d5720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410b3a00002000280208417f6a220341094b0d07024002400240024002400240024002400240024020030e0a00010203040506070809000b200241003a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da80120034101742205200420042005491b22054100480da8010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6120012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41003a0000200028020c2104200041146a280200220a200110470240200a450d00200141046a2109034002400240200928020020062802002203460d00200128020021050c010b200341016a22052003490daa012003410174220b20052005200b491b220b4100480daa010240024020030d00200b102921050c010b20012802002003200b102a21050b2005450d64200120053602002009200b360200200628020021030b2006200341016a360200200520036a20042d00003a0000200441016a2104200a417f6a220a0d000b0b200041186a20011066200028021c210402400240200141046a2802002200200628020022036b4104490d00200128020021000c010b200341046a22052003490da80120004101742203200520052003491b22034100480da8010240024020000d002003102921000c010b200128020020002003102a21000b2000450d6320012000360200200141046a2003360200200141086a28020021030b200141086a200341046a360200200020036a20043600000c100b200241013a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da70120034101742205200420042005491b22054100480da7010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6320012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41013a0000200028020c2104200041146a280200220a200110470240200a450d00200141046a2109034002400240200928020020062802002203460d00200128020021050c010b200341016a22052003490da9012003410174220b20052005200b491b220b4100480da9010240024020030d00200b102921050c010b20012802002003200b102a21050b2005450d66200120053602002009200b360200200628020021030b2006200341016a360200200520036a20042d00003a0000200441016a2104200a417f6a220a0d000b0b200041186a20011066200028021c210402400240200141046a2802002200200628020022036b4104490d00200128020021000c010b200341046a22052003490da70120004101742203200520052003491b22034100480da7010240024020000d002003102921000c010b200128020020002003102a21000b2000450d6520012000360200200141046a2003360200200141086a28020021030b200141086a200341046a360200200020036a20043600000c0f0b200241023a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da60120034101742205200420042005491b22054100480da6010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002000410c6a20011066200041106a20011049200041346a20011066200041386a200110660c0e0b200241033a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da50120034101742205200420042005491b22054100480da5010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a00002000410c6a200110660c0d0b200141086a2802002103200241043a001c024002402003200141046a280200460d00200128020021040c010b200341016a22042003490da40120034101742205200420042005491b22054100480da4010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41043a00002000410c6a200110660c0c0b200241053a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da30120034101742205200420042005491b22054100480da3010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a00002000410c6a200110492002200041386a360208200241086a2001106b200041306a200110660c0b0b200241063a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da20120034101742205200420042005491b22054100480da2010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a00002000410c6a200110660c0a0b200241073a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da10120034101742205200420042005491b22054100480da1010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a00002000410c6a200110490c090b200141046a2802002104200241083a001c024002402004200141086a2802002203460d00200128020021040c010b200341016a22042003490da00120034101742205200420042005491b22054100480da0010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41083a00002000410c6a200110660c080b200241093a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9f0120034101742205200420042005491b22054100480d9f010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a00002000410c6a200110660c070b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9e0120034101742205200420042005491b22054100480d9e010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410c3a000020002d0004417f6a220341034b0d06024002400240024020030e0400010203000b200241003a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da10120034101742205200420042005491b22054100480da1010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041056a2001104a0c090b200241013a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da00120034101742205200420042005491b22054100480da0010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041056a2001104a0c080b200241023a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9f0120034101742205200420042005491b22054100480d9f010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a0000200041056a2001104a200041256a2001104a0c070b200241033a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9e0120034101742205200420042005491b22054100480d9e010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a000020002802082103200041106a2802002200200110472000450d0620004105742100034020032001104a200341206a2103200041606a22000d000c070b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9d0120034101742205200420042005491b22054100480d9d010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410d3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d9d0120034101742205200420042005491b22054100480d9d010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041046a200110660c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9c0120034101742205200420042005491b22054100480d9c010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410e3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d9c0120034101742205200420042005491b22054100480d9c010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6b20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200028020421062000410c6a28020022032001104702400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d9c0120044101742200200520052000491b22004100480d9c010240024020040d002000102921040c010b200128020020042000102a21040b2004450d6c20012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a2006200310f6041a0c040b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9b0120034101742205200420042005491b22054100480d9b010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410f3a00002000280208417f6a220341024b0d0302400240024020030e03000102000b200241003a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9d0120034101742205200420042005491b22054100480d9d010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002002200041306a360208200241086a2001106b2000410c6a200110490c050b200241013a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9c0120034101742205200420042005491b22054100480d9c010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000410c6a200110660c040b200241023a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9b0120034101742205200420042005491b22054100480d9b010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002000410c6a200110660c030b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9a0120034101742205200420042005491b22054100480d9a010240024020030d002005102921040c010b200128020020032005102a21040b2004450d6f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41103a000020002d0008417f6a220341044b0d020240024002400240024020030e050001020304000b200241003a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9e0120034101742205200420042005491b22054100480d9e010240024020030d002005102921040c010b200128020020032005102a21040b2004450d7420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041106a200110fe010c060b200241013a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9d0120034101742205200420042005491b22054100480d9d010240024020030d002005102921040c010b200128020020032005102a21040b2004450d7420012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200041186a20011067200028020c2106200041146a28020022032001104702400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d9d0120044101742200200520052000491b22004100480d9d010240024020040d002000102921040c010b200128020020042000102a21040b2004450d7520012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a2006200310f6041a0c050b200241023a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9c0120034101742205200420042005491b22054100480d9c010240024020030d002005102921040c010b200128020020032005102a21040b2004450d7520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a00002000410c6a200110492002200041c0006a360208200241086a2001106b200041d0006a2001106720002802302106200041386a28020022032001104702400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d9c0120044101742200200520052000491b22004100480d9c010240024020040d002000102921040c010b200128020020042000102a21040b2004450d7620012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a2006200310f6041a0c040b200241033a001c02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9b0120034101742205200420042005491b22054100480d9b010240024020030d002005102921040c010b200128020020032005102a21040b2004450d7620012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a00002002200041386a360208200241086a2001106b200041c8006a20011067200041096a20011046200028022c2106200041346a28020022032001104702400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d9b0120044101742200200520052000491b22004100480d9b010240024020040d002000102921040c010b200128020020042000102a21040b2004450d7720012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a2006200310f6041a0c030b200141086a2802002103200241043a001c024002402003200141046a280200460d00200128020021040c010b200341016a22042003490d9a0120034101742205200420042005491b22054100480d9a010240024020030d002005102921040c010b200128020020032005102a21040b2004450d7720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a0000200041096a2001104a024020002d00294101460d00200241003a001c02400240200141046a28020020052802002203460d00200128020021000c010b200341016a22002003490d9b0120034101742204200020002004491b22044100480d9b010240024020030d002004102921000c010b200128020020032004102a21000b2000450d7920012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c030b200241013a001c02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d9a0120034101742205200420042005491b22054100480d9a010240024020030d002005102921040c010b200128020020032005102a21040b2004450d7920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000412a6a2001104a0c020b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d990120034101742205200420042005491b22054100480d99010240024020030d002005102921040c010b200128020020032005102a21040b2004450d7920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41113a00002000280204417f6a220341014b0d010240024020030e020001000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9a0120034101742205200420042005491b22054100480d9a010240024020030d002005102921040c010b200128020020032005102a21040b2004450d7b20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002000280208200110bc010c020b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d990120034101742205200420042005491b22054100480d99010240024020030d002005102921040c010b200128020020032005102a21040b2004450d7b20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041086a200110490c010b02400240200141046a220a280200200141086a22032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d7b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a41123a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d7c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a41003a00002000280204210602400240200a2802002205200328020022046b4104490d00200128020021050c010b200441046a22092004490d980120054101742204200920092004491b22044100480d98010240024020050d002004102921050c010b200128020020052004102a21050b2005450d7d20012005360200200141046a2004360200200141086a28020021040b200141086a2209200441046a360200200520046a2006360000200041086a280200210b200041106a28020022042001104702400240200141046a2802002206200928020022056b2004490d00200128020021060c010b200520046a22092005490d980120064101742205200920092005491b22054100480d98010240024020060d002005102921060c010b200128020020062005102a21060b2006450d7e20012006360200200141046a2005360200200141086a28020021050b200141086a2208200520046a360200200620056a200b200410f6041a200041146a28020021062000411c6a28020022042001104702402004450d0020062004410c6c6a210e200141046a210c03402006280200210b200641086a28020022042001104702400240200c2802002209200828020022056b2004490d00200128020021090c010b200520046a220d2005490d9a0120094101742205200d200d2005491b22054100480d9a010240024020090d002005102921090c010b200128020020092005102a21090b2009450d810120012009360200200c2005360200200828020021050b2003200520046a360200200920056a200b200410f6041a2006410c6a2206200e470d000b0b200041206a280200210602400240200a2802002205200328020022046b4104490d00200128020021050c010b200441046a22092004490d980120054101742204200920092004491b22044100480d98010240024020050d002004102921050c010b200128020020052004102a21050b2005450d800120012005360200200141046a2004360200200141086a28020021040b2003200441046a360200200520046a2006360000200041246a280200210602400240200a2802002205200328020022046b4104490d00200128020021050c010b200441046a22092004490d980120054101742204200920092004491b22044100480d98010240024020050d002004102921050c010b200128020020052004102a21050b2005450d810120012005360200200141046a2004360200200141086a28020021040b2003200441046a360200200520046a200636000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d820120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00283a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d830120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00293a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d840120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d002a3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d850120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d002b3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d860120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d002c3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d870120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d002d3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d880120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d002e3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d890120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d002f3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d8a0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00303a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d8b0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00313a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d8c0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00323a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d8d0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00333a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d8e0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00343a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d8f0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00353a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d900120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00363a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d910120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00373a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d920120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00383a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d930120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00393a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d940120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d003a3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d950120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d003b3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d960120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d003c3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d980120044101742206200520052006491b22064100480d98010240024020040d002006102921050c010b200128020020042006102a21050b2005450d970120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d003d3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450d990120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d003e3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450d9a0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d003f3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450d9b0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00403a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450d9c0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00413a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450d9d0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00423a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450d9e0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00433a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450d9f0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00443a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450da00120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00453a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450da10120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00463a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450da20120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00473a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450da30120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00483a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450da40120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00493a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450da50120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d004a3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450da60120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d004b3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450da70120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d004c3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450da80120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d004d3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450da90120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d004e3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450daa0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d004f3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dab0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00503a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dac0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00513a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dad0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00523a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dae0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00533a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450daf0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00543a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450db00120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00553a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450db10120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00563a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450db20120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00573a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450db30120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00583a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450db40120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00593a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450db50120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d005a3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450db60120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d005b3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450db70120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d005c3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450db80120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d005d3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450db90120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d005e3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dba0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d005f3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dbb0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00603a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dbc0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00613a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dbd0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00623a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dbe0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00633a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dbf0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00643a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dc00120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00653a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dc10120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00663a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc30120044101742206200520052006491b22064100480dc3010240024020040d002006102921050c010b200128020020042006102a21050b2005450dc20120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00673a00000b200241206a24000f0b20054101102c000b20044101102c000b20054101102c000b20004101102c000b20054101102c000b20034101102c000b20054101102c000b20004101102c000b20044101102c000b20054101102c000b20054101102c000b20054101102c000b20004101102c000b20054101102c000b20054101102c000b20044101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20034101102c000b20044101102c000b20054101102c000b20044101102c000b20044101102c000b200a4101102c000b200a4101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b200a4101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20004101102c000b200a4101102c000b20054101102c000b20054101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b200a4101102c000b20034101102c000b20054101102c000b20054101102c000b20054101102c000b200a4101102c000b20034101102c000b20034101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b200a4101102c000b20064101102c000b20054101102c000b102d000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b200b4101102c000b20034101102c000b20054101102c000b200b4101102c000b20034101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20004101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20004101102c000b20054101102c000b20004101102c000b20054101102c000b20004101102c000b20054101102c000b20044101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20064101102c000b20064101102c000b20044101102c000b20054101102c000b20054101102c000b20044101102c000b20044101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b102d000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b102d000b8305010f7f230041a0026b22042400200441c0016a41386a2205200041386a2206290000370300200441c0016a41306a2207200041306a2208290000370300200441c0016a41286a2209200041286a220a290000370300200441c0016a41206a220b200041206a220c290000370300200441c0016a41186a220d200041186a220e290000370300200441c0016a41106a220f200041106a2210290000370300200441c0016a41086a2211200041086a2212290000370300200420002900003703c0010240024020012002200441c0016a2003100c0d00410121000c010b20052006290000370300200720082900003703002009200a290000370300200b200c290000370300200d200e290000370300200f20102900003703002011201229000037030020044188026a2205200341086a29000037030020044190026a2206200341106a29000037030020044198026a2207200341186a290000370300200420002900003703c00120042003290000370380022004200441c0016a41e00010f604220041c0016a200041e00010f6041a200041e0006a41386a200041386a290000370300200041e0006a41306a200041306a290000370300200041e0006a41286a200041286a290000370300200041e0006a41206a200041206a290000370300200041e0006a41186a200041186a290000370300200041e0006a41106a200041106a290000370300200041e0006a41086a200041086a29000037030020002000290000370360200041a0016a41186a2007290300370300200041a0016a41106a2006290300370300200041a0016a41086a200529030037030020002000290380023703a00120012002200041e0006a200041a0016a10214521000b200441a0026a240020000bda0401057f230041106b220324002003410036020820034201370300200220031047024002400240024002402002450d0020024190016c2104034020032802042105200328020821020240024020012d00004113470d000240024020052002460d00200328020021050c010b200241016a22052002490d0820024101742206200520052006491b22064100480d080240024020020d002006102921050c010b200328020020022006102a21050b2005450d052003200636020420032005360200200328020821020b2003200241016a360208200520026a41003a00000c010b0240024020052002460d00200328020021050c010b200241016a22052002490d0720024101742206200520052006491b22064100480d070240024020020d002006102921050c010b200328020020022006102a21050b2005450d052003200636020420032005360200200328020821020b2003200241016a360208200520026a41013a00002001200310bc0120014188016a28020021060240024020032802042205200328020822026b4104490d00200328020021050c010b200241046a22072002490d0720054101742202200720072002491b22024100480d070240024020050d002002102921050c010b200328020020052002102a21050b2005450d062003200236020420032005360200200328020821020b2003200241046a360208200520026a20063600000b20014190016a2101200441f07e6a22040d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b20064101102c000b20064101102c000b20024101102c000b102d000bc50301047f230041106b22032400200341003602082003420137030020012003104702400240024002402001450d00200141216c210403400240024020002d00004101460d0002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d0720014101742206200520052006491b22064100480d070240024020010d002006102921050c010b200328020020012006102a21050b2005450d052003200636020420032005360200200328020821010b2003200141016a360208200520016a41003a00000c010b02400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d0620014101742206200520052006491b22064100480d060240024020010d002006102921050c010b200328020020012006102a21050b2005450d052003200636020420032005360200200328020821010b2003200141016a360208200520016a41013a0000200041016a2003104a0b200041216a21002004415f6a22040d000b0b2003280204210020022802002002280204200328020022012003280208100402402000450d002001102e0b200341106a24000f0b20064101102c000b20064101102c000b102d000b6801037f024041094101200128020022024101461b220310292204450d000240024020020d00200441003a0000410121010c010b200441013a000020042001290204370001410921010b2000200136020820002003360204200020043602000f0b20034101102c000b130020004101360204200041ccf0c0003602000b13002000410236020420004184f2c0003602000b3101017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241e8073600000b3101017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241e5003600000bbd0201067f230041c0006b220224000240411610292203450d00200341002900d7f8403700002003410e6a41002900e5f840370000200341086a41002900dff84037000020024296808080e002370224200220033602202001200241206a104a200228022421042002280228210520022802202103200241206a41186a22064200370300200241206a41106a22074200370300200241206a41086a220142003703002002420037032020032005200241206a1000200241186a2006290300370300200241106a2007290300370300200241086a200129030037030020022002290320370300200241206a2002412010c6010240024020022802204101460d00200041003602000c010b20002002290320370200200041086a20012802003602000b02402004450d002003102e0b200241c0006a24000f0b41164101102c000ba50101027f230041206b22032400410021042003410036021420012002200341146a100821010240024020032802142202417f460d002001450d002003410036020c20024104490d0120012800002104200341003602102002417c714104460d01200128000421022001102e200041086a200236020020002004360204410121040b20002004360200200341206a24000f0b41eff0c2004133200341186a4184f4c2001053000bed02030a7f017e017f230041206b220124002001410010c801200141106a410110c80102400240024020012802182202450d004102210320012802042104200128020821050340200128021421062001280210210702400240200420056b200241216c220841216d2209490d00200520096a2109200128020021020c010b200520096a22092005490d0420044101742202200920092002491b220aad42217e220b422088a70d04200ba7220c4100480d040240024020040d00200c102921020c010b2001280200200441216c200c102a21020b2002450d0320012002360200200a21040b2002200541216c6a2007200810f6041a02402006450d002007102e0b200141106a200310c801200341016a210320092105200128021822020d000b20012004360204200120093602080b02402001280214450d002001280210102e0b20002001290300370200200041086a200141086a280200360200200141206a24000f0b200c4101102c000b102d000bc908030c7f037e027f230041e0016b22022400024002400240024002400240410e10292203450d00200341066a41002900f6fa40370000200341002900f0fa403700002003410e411c102a2204450d012004200136000e200241306a41186a22034200370300200241306a41106a22014200370300200241306a41086a220542003703002002420037033020044112200241306a1000200241106a41186a2003290300370300200241106a41106a2001290300370300200241106a41086a200529030037030020022002290330370310200241003602b801200241106a4120200241b8016a100821060240024020022802b8012207417f460d002002200736025420022006360250200241086a200241d0006a103120022802080d072002280254220541216e220841216c2203417f4c0d04200228020c21090240024020030d004101210a0c010b20031029220a450d060b02402009450d004100210b03402005450d0820022005417f6a220536025420022002280250220c41016a360250200c2d0000220341014b0d084100210d0240024020030e020100010b41002103200241003a00d8010340024020052003470d0020024100360254200341ff0171450d0b200241003a00d8010c0b0b200241b8016a20036a200c20036a220141016a2d00003a00002002200141026a3602502002200341016a22013a00d8012001210320014120470d000b200241306a41106a200241b8016a41106a290300220e37030020024198016a41086a200241b8016a41086a29030037030020024198016a41106a200e37030020024198016a41186a200241b8016a41186a2903003703002002200520016b2205360254200220022903b801370398014101210d0b200b41016a2101200241f8006a41186a20024198016a41186a290300220e370300200241f8006a41106a20024198016a41106a290300220f370300200241f8006a41086a20024198016a41086a2903002210370300200241d8006a41086a220c2010370300200241d8006a41106a2211200f370300200241d8006a41186a2212200e3703002002200229039801220e3703782002200e37035802402008200b470d000240200b4101742203200120012003491b2208ad42217e220e422088a70d00200ea722034100480d0002400240200b0d0020031029210a0c010b200a200b41216c2003102a210a0b200a0d0120034101102c000b102d000b200a200b41216c6a2203200d3a000020032002290358370001200341096a200c290300370000200341116a2011290300370000200341196a20122903003700002001210b20012009470d000b0b200a450d072009ad4220862008ad84210e02402007450d002006102e0b2000200e3702042000200a3602000c010b20004100360208200042013702000b2004102e200241e0016a24000f0b410e4101102c000b411c4101102c000b1032000b20034101102c000b2008450d00200a102e0b41eff0c2004133200241b8016a4184f4c2001053000bc00402067f017e230041d0006b220224000240024002400240411310292203450d00200341002900ddfa403700002003410f6a41002800ecfa40360000200341086a41002900e5fa4037000020024293808080b002370224200220033602202001200241206a104a200128022021040240024020022802242201200228022822036b4104490d00200228022021010c010b200341046a22052003490d0320014101742203200520052003491b22034100480d030240024020010d002003102921010c010b200228022020012003102a21010b2001450d022002200336022420022001360220200228022821030b2002200341046a360228200120036a2004360000200228022421052002280228210120022802202103200241206a41186a22044200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020032001200241206a1000200241186a2004290300370300200241106a2006290300370300200241086a2007290300370300200220022903203703002002410036022020024120200241206a100821040240024020022802202201417f460d002002200136024420022004360240200241206a200241c0006a104120022802202206450d052002290224210802402001450d002004102e0b20002008370204200020063602000c010b20004100360208200042043702000b02402005450d002003102e0b200241d0006a24000f0b41134101102c000b20034101102c000b102d000b41eff0c2004133200241c8006a4184f4c2001053000bef0302067f047e230041c0006b220224000240024002400240411310292203450d0020034100290086fa403700002003410f6a4100280095fa40360000200341086a410029008efa4037000020024293808080b002370224200220033602202001200241206a104a200228022421042002280228210320022802202105200241206a41186a22014200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020052003200241206a1000200241186a2001290300370300200241106a2006290300370300200241086a2007290300370300200220022903203703002002410036022020024120200241206a1008210320022802202201417f460d022003450d0220014104490d012001417c714104460d01200141786a4110490d01200141686a4110490d012003280000210620032800042107200341106a290000210820032900082109200341206a290000210a2003290018210b02402001450d002003102e0b20002009370308200041206a200a370300200041186a200b370300200041106a20083703002000412c6a2007360200200041286a2006360200420121080c030b41134101102c000b41eff0c2004133200241206a4184f4c2001053000b420021080b2000200837030002402004450d002005102e0b200241c0006a24000bd30102027f027e200028022021020240024002400240410410292203450d002003200236000020002802242102200341044108102a2203450d0120032002360004200041086a290300210420002903002105200341084118102a2203450d0220032005370008200341106a2004370000200041186a290300210420002903102105200341184130102a2200450d0320002005370018200041206a2004370000200128020020012802042000412810042000102e0f0b41044101102c000b41084101102c000b41184101102c000b41304101102c000b13002000410a360204200041c8fbc0003602000b3400200041e0e9c10036020420004100360200200041146a4110360200200041106a41d0a1c100360200200041086a42073702000b3001017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241003600000b2201017f230041106b22022400200241003602002000200210c001200241106a24000b13002000410a360204200041a0bdc1003602000b3101017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241c0003600000b3201017f02404104102922020d0041044101102c000b20004284808080c0003702042000200236020020024180e1013600000b3001017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241013600000b3001017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241063600000b3d01017f02404110102922020d0041104101102c000b200242003700082002428080d287e2bc2d370000200042908080808002370204200020023602000b3d01017f02404110102922020d0041104101102c000b200242003700082002428080e983b1de16370000200042908080808002370204200020023602000b3e01017f02404110102922020d0041104101102c000b2002420037000820024280809aa6eaafe301370000200042908080808002370204200020023602000be50901047f230041206b220224000240024002400240024002400240024002400240024002400240024002402001280200417f6a220341094b0d0020030e0a0102030405060708090a010b4190cec1001058000b2001410c6a2802002203417f4c0d0a200128020421044101210502402003450d00200310292205450d0c0b20052004200310f60421052000410c6a2003360200200041086a20033602002000200536020420004101360200200041106a20012902103703000c090b2001410c6a2802002203417f4c0d09200128020421050240024020030d00410121040c010b200310292204450d0c0b20042005200310f60421052000410c6a2003360200200041086a20033602002000200536020420004102360200200041106a20012902103703000c080b200128020421054101210302400240200141086a22042d00004101460d002002411e6a200441036a2d00003a0000200241086a200141186a290200370300200241106a200141206a290200370300200241186a200141286a2d00003a0000200220042f00013b011c2002200141106a2902003703002001410c6a2802002104410021030c010b2001410c6a28020021040b20002005360204200020022f011c3b0009200041086a20033a00002000410c6a2004360200200041106a20022903003702002000412c6a200129022c3702002000410b6a2002411e6a2d00003a0000200041186a200241086a290300370200200041206a200241106a290300370200200041286a200241186a280200360200200041033602000c070b20004104360200200020012802043602040c060b20004105360200200020012802043602040c050b410121030240024020012d00044101460d002002411e6a200141046a220341036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290200370300200141086a2802002105410021030c010b200141086a28020021050b200020033a0004200020022f011c3b0005200041306a2001290330370300200041086a20053602002000410c6a2002290300370200200041386a200141386a290300370300200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602002001280228210120004106360200200041286a20013602000c040b20004107360200200020012802043602040c030b410121030240024020012d00044101460d002002411e6a200141046a220341036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290200370300200141086a2802002101410021030c010b200141086a28020021010b200020033a0004200020022f011c3b000520004108360200200041086a20013602002000410c6a2002290300370200200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c020b20004109360200200020012802043602040c010b2000410a360200200020012802043602040b200241206a24000f0b1032000b20034101102c000b20034101102c000ba2a10106197f017e037f017e087f0b7e230041f0046b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e0b000102030405060708090a000b20034184036a4101360200200342013702f402200341cc91c5003602f0022003411c3602c404200341c491c5003602c0042003200341c0046a36028003200341f0026a41eccec100106a000b200141086a2802002104200128020421050240024020022d00000d004101210620022d00014101460d010b41b5f0c2002107412a210841002109410121062004450d282005102e0c280b200241196a2d00002107200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021182001410c6a2802002119200141146a280200211a200141106a280200211b20032002411a6a29010037038803200320073a008703200320083a008603200320093b0184032003200a3a0083032003200b3a0082032003200c3b0180032003200d3a00ff022003200e3a00fe022003200f3b01fc02200320103a00fb02200320173a00f202200320183b01f002200320132012410874201141187472723600f702200320162015410874722014411874723600f302200320193602c804200320043602c404200320053602c0042003200341f0026a200341c0046a201b201a10db012003280204210820032802002107410021090c270b200141086a2802002104200128020421050240024020022d00000d0020022d00014101460d010b41b5f0c2002107412a21080c260b2001410c6a2802002118200141146a2802002119200141106a280200211a200241196a2d00002107200241186a2d00002108200241166a2f01002106200241156a2d00002109200241146a2d0000210a200241126a2f0100210b200241116a2d0000210c200241106a2d0000210d2002410e6a2f0100210e2002410d6a2d0000210f2002410c6a2d000021102002410a6a2f01002111200241096a2d00002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f0100211720032002411a6a2901003703b004200320073a00af04200320083a00ae04200320063b01ac04200320093a00ab042003200a3a00aa042003200b3b01a8042003200c3a00a7042003200d3a00a6042003200e3b01a4042003200f3a00a304200320163a009a04200320173b0198042003201220114108742010411874727236009f042003201520144108747220134118747236009b04410d10292202450d0841002107200241002900fcce41370000200241056a4100290081cf413700002003428d808080d0013702f402200320023602f00220034198046a200341f0026a104a20032802f402210620032802f802210920032802f0022102200341f0026a41186a220a4200370300200341f0026a41106a22084200370300200341f0026a41086a220b4200370300200342003703f00220022009200341f0026a1000200341c0046a41186a200a290300370300200341c0046a41106a2008290300370300200341c0046a41086a200b290300370300200320032903f0023703c004200341f0026a200341c0046a412010dc010240024020032d00f0024101460d000c010b20034189036a290000211c20034188036a2d0000210a20034187036a2d0000210b20034185036a2f0000210c20034184036a2d0000210d20034183036a2d0000210e20034181036a2f0000210f20082d00002110200341ff026a2d00002111200341fd026a2f00002112200341fc026a2d00002113200341f8026a280200211520032802f402211420032d00f302210820032f00f1022109410121070b02402006450d002002102e0b024020070d0041c992c5002107410b21080c260b2003201c370388032003200a3a0087032003200b3a0086032003200c3b0184032003200d3a0083032003200e3a0082032003200f3b018003200320103a00ff02200320113a00fe02200320123b01fc02200320133a00fb02200320153600f702200320143600f302200320083a00f202200320093b01f002200320183602c804200320043602c404200320053602c004200341086a200341f0026a200341c0046a201a201910db01200328020c21082003280208210741012109410021060c260b200141216a290000211c200141206a2d0000210a2001411d6a2f0000210b2001411c6a2d0000210c200141196a2f0000210d200141186a2d0000210e200141156a2f0000210f200141146a2d00002110200141106a28020021112001410c6a2802002105200141086a2d00002117200141306a280200211d2001412c6a280200211e20012d001f211220012d001b211320012d0017211420012d000b211520012f000921162001280204211f2002411a6a2901002120200241196a2d00002118200241186a2d00002119200241166a2f0100211a200241156a2d0000211b200241146a2d00002121200241126a2f01002122200241116a2d00002123200241106a2d000021242002410e6a2f010021252002410d6a2d00002126200241046a2d00002127200241026a2f01002128412a210841b5f0c20021070240024020022d0000450d004101210641002109410021040c010b41012106410021094100210420022d00014101470d002002410c6a2d000021092002410a6a2f01002104200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d0000411874722107410021060b200441ffff0371410874200941187472200841ff017172210820060d23200320203703d802200320183a00d702200320193a00d6022003201a3b01d4022003201b3a00d302200320213a00d202200320223b01d002200320233a00cf02200320243a00ce02200320253b01cc02200320263a00cb02200320083600c702200320073600c302200320273a00c202200320283b01c0020240201741ff01714101470d00200341f0026a200541067610bb0120032802f00221070240024020032802f8022005413f7122024b0d00410021020c010b200720024105746a2202290018211c20022d0017210a20022d0016211220022f0014210b20022d0013210c20022d0012211320022f0010210d20022d000f210e20022d000e211420022f000c210f20022d000b2110200228000721112002280003210520022d0002211520022f00002116410121020b024020032802f402450d002007102e0b2002450d230b2003201c370388042003200a3a008704200320123a0086042003200b3b0184042003200c3a008304200320133a0082042003200d3b0180042003200e3a00ff03200320143a00fe032003200f3b01fc03200320103a00fb03200320113600f703200320053600f303200320153a00f203200320163b01f003200341e0036a41086a22024200370300200342003703e00341fcf8c0004114200341e0036a1003200341e0026a41086a2002290300370300200320032903e0033703e0020240200341e0026a411041c8ecc500410041001005417f460d004189cfc1002107412621080c240b200341f0026a200341c0026a10ca01024020032903f0024201510d0041afcfc1002107411821080c240b200341f0026a200341f0036a10ca01024020032903f0024201510d004192d0c1002107412c21080c240b20034198036a280200210c20034180016a41bfd9c5004111107d41ddcfc10021074116210820032802840141002003280280011b201d470d230240200c41016a201d490d0041f3cfc1002107411f21080c240b200341f0026a201f41067610c80141002107201f413f71220220032802f8024f0d1920032802f002200241216c6a22022d00004101470d1920022f00012106200241196a290000211c200241186a2d00002109200241176a2d00002104200241156a2f00002105200241146a2d0000210a200241136a2d0000210b200241116a2f0000210d200241106a2d0000210e2002410f6a2d0000210f2002410d6a2f000021102002410c6a2d00002111200241086a2800002113200241046a2800002112200241036a2d00002102410121070c1a0b41b5f0c2002107412a210820022d00000d2220022d00014101470d2220012802042116200241196a2d00002107200241186a2d00002108200241166a2f01002106200241156a2d00002109200241146a2d00002104200241126a2f01002105200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002114200241026a2f0100211520032002411a6a2901003703b004200320073a00af04200320083a00ae04200320063b01ac04200320093a00ab04200320043a00aa04200320053b01a8042003200a3a00a7042003200b3a00a6042003200c3b01a4042003200d3a00a304200320143a009a04200320153b01980420032010200f41087472200e4118747236009f042003201320124108747220114118747236009b04200341e0036a41086a22024200370300200342003703e00341fcf8c0004114200341e0036a1003200341e0026a41086a2002290300370300200320032903e0033703e0020240200341e0026a411041c8ecc500410041001005417f460d0041a5d1c1002107411e21080c230b411310292202450d0720024100290086fa403700002002410f6a4100280095fa40360000200241086a410029008efa4037000020034293808080b0023702f402200320023602f00220034198046a200341f0026a104a20032802f402210720032802f802210620032802f002210241182108200341f0026a41186a22094200370300200341f0026a41106a22044200370300200341f0026a41086a22054200370300200342003703f00220022006200341f0026a1000200341c0046a41186a2009290300370300200341c0046a41106a2004290300370300200341c0046a41086a2005290300370300200320032903f0023703c004200341c0046a412041c8ecc500410041001005210602402007450d002002102e0b02402006417f470d0041c3d1c10021070c230b200341c0046a201641067610c801410021072016413f71220220032802c8044f0d1620032802c004200241216c6a22022d00004101470d1620022f00012106200241196a290000211c200241186a2d00002109200241176a2d00002104200241156a2f00002105200241146a2d0000210a200241136a2d0000210b200241116a2f0000210c200241106a2d0000210d2002410f6a2d0000210e2002410d6a2f0000210f2002410c6a2d00002110200241086a2800002112200241046a2800002111200241036a2d00002102410121070c170b200128020421052002411a6a290100211c200241196a2d0000210a200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d00002113200241046a2d00002114200241026a2f0100211541b5f0c2002107412a21080240024020022d0000450d004101210641002109410021040c010b41012106410021094100210420022d00014101470d002002410c6a2d000021042002410a6a2f01002109200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d0000411874722107410021060b200941ffff0371410874200841ff017172200441187472210820060d212003201c3703b0042003200a3a00af042003200b3a00ae042003200c3b01ac042003200d3a00ab042003200e3a00aa042003200f3b01a804200320103a00a704200320113a00a604200320123b01a404200320133a00a3042003200836009f042003200736009b04200320143a009a04200320153b019804411610292202450d07200241002900d7f8403700002002410e6a41002900e5f840370000200241086a41002900dff84037000020034296808080e0023702f402200320023602f00220034198046a200341f0026a104a20032802f402210720032802f802210820032802f0022102200341f0026a41186a22064200370300200341f0026a41106a22094200370300200341f0026a41086a22044200370300200342003703f00220022008200341f0026a1000200341c0046a41186a2006290300370300200341c0046a41106a2009290300370300200341c0046a41086a2004290300370300200320032903f0023703c004200341c0046a412041c8ecc500410041001005210802402007450d002002102e0b02402008417f460d0041dbd1c1002107411e21080c220b200341a0016a41f6d9c5004116107d20032802a401210820032802a0012104200341e0036a41086a22024200370300200342003703e00341f4f9c0004112200341e0036a1003200341e0026a41086a2002290300370300200320032903e0033703e002200341003602f002200341e0026a4110200341f0026a1008210720032802f002220a417f460d092007450d092003200a3602c404200320073602c004200341f0026a200341c0046a103020032802f0022206450d08200341f8026a280200210220032802f4022109200a450d0f2007102e0c0f0b200141386a290300211c200141306a29030021202001411d6a29000021292001411c6a2d00002116200141196a2f00002117200141186a2d00002118200141156a2f00002119200141146a2d0000211a200141116a2f0000211b200141106a2d000021212001410c6a2802002122200141086a2802002105200141286a280200211d20012d001b212320012d0017212420012d0013212520012d0007212620012f0005212720012d000421282002411a6a290100212a200241196a2d0000210a200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d00002113200241046a2d00002114200241026a2f0100211541b5f0c2002107412a21080240024020022d0000450d004101210641002109410021040c010b41012106410021094100210420022d00014101470d002002410c6a2d000021042002410a6a2f01002109200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d0000411874722107410021060b200941ffff0371410874200841ff017172200441187472210820060d202003202a370388042003200a3a0087042003200b3a0086042003200c3b0184042003200d3a0083042003200e3a0082042003200f3b018004200320103a00ff03200320113a00fe03200320123b01fc03200320133a00fb03200320083600f703200320073600f303200320143a00f203200320153b01f00302402020201c8450450d0041ebd2c100210741d00021080c210b0240202841ff01714101470d00200341f0026a200541067610bb0120032802f00221070240024020032802f8022005413f7122024b0d00410021020c010b200720024105746a2202290018212920022d0017211620022d0016212320022f0014211720022d0013211820022d0012212420022f0010211920022d000f211a20022d000e212520022f000c211b20022d000b2121200228000721222002280003210520022d0002212620022f00002127410121020b024020032802f402450d002007102e0b2002450d200b200320293703b004200320163a00af04200320233a00ae04200320173b01ac04200320183a00ab04200320243a00aa04200320193b01a8042003201a3a00a704200320253a00a6042003201b3b01a404200320213a00a3042003202236009f042003200536009b04200320263a009a04200320273b01980441112108200341a8026a41bfd9c5004111107d41dad2c100210720032802ac02410020032802a8021b201d470d20200341e0036a41086a22024200370300200342003703e00341fcf8c0004114200341e0036a1003200341e0026a41086a2002290300370300200320032903e0033703e002200341f0026a200341e0026a10dd01024020032802f802220a0d0041add2c1002107412d21080c210b20032902fc02212b200341a0026a41e4d9c5004112107d20034190026a20032802a402410020032802a0021bad42004280a094a58d1d420010fb04411410292202450d0920034190026a41086a290300212a200329039002212c200241002900d88c40370000200241106a41002800e88c40360000200241086a41002900e08c4037000020034294808080c0023702f402200320023602f002200341f0036a200341f0026a104a20032802f4022102200341f8016a20032802f002220820032802f802106e200341f8016a41106a290300420020032802f80122071b2129200329038002420020071b212d02402002450d002008102e0b202d202c542029202a542029202a511b450d0c41ecd3c1002107412e21080c0d0b4101210620022d000120022d0000720d0a20012802042102200341e0036a41086a22074200370300200342003703e00341abd9c5004114200341e0036a1003200341e0026a41086a2007290300370300200320032903e0033703e002200320023602f002200341e0026a4110200341f0026a410410040c0e0b024020022d000120022d000072450d00418df0c2002107412821080c1f0b200141086a2802002107024020012d00044101460d00200141106a2d00002108200141146a2d00002106200141186a2d000021092001411c6a2d0000210420012f0005210220012d00072105200128020c210a20012f0011210b20012d0013210c20012f0015210d20012d0017210e20012f0019210f20012d001b2110200129001d211c0c090b200341f0026a200741067610bb0120032802f00221110240024020032802f8022007413f7122024b0d00410021120c010b201120024105746a2202290018211c20022d0017210420022d0016211020022f0014210f20022d0013210920022d0012210e20022f0010210d20022d000f210620022d000e210c20022f000c210b20022d000b21082002280007210a2002280003210720022d0002210520022f00002102410121120b024020032802f402450d002011102e0b2012450d1d0c080b4101210620022d000120022d0000720d0820012802042102200341e0036a41086a22074200370300200342003703e00341b4f9c000411c200341e0036a1003200341e0026a41086a2007290300370300200320032903e0033703e002200320023602f002200341e0026a4110200341f0026a410410040c0c0b4101210620022d000120022d0000720d0720012802042102200341e0036a41086a22074200370300200342003703e00341a0f9c0004114200341e0036a1003200341e0026a41086a2007290300370300200320032903e0033703e002200320023602f002200341e0026a4110200341f0026a410410040c0b0b410d4101102c000b41134101102c000b41164101102c000b41eff0c2004133200341e8046a4184f4c2001053000b4100210941012106410021020c050b41144101102c000b2003201c3703d802200320043a00d702200320103a00d6022003200f3b01d402200320093a00d3022003200e3a00d2022003200d3b01d002200320063a00cf022003200c3a00ce022003200b3b01cc02200320083a00cb022003200a3600c702200320073600c302200320053a00c202200320023b01c002200341e0036a41086a22024200370300200342003703e00341edf8c000410f200341e0036a1003200341e0026a41086a2002290300370300200320032903e0033703e002200341f0026a200341e0026a10de014100210720032802f402410020032802f00222021b210d4104210b2002410420021b21080240024002400240024002400240200341f0026a41086a2206280200410020021b2205450d002008200541246c22096a21040340200341f0026a41206a200820076a220241206a280200360200200341f0026a41186a200241186a290200370300200341f0026a41106a200241106a2902003703002006200241086a290200370300200320022902003703f002200341f0026a200341c0026a412010f8040d022009200741246a2207470d000b0b410021050240200d0d004100210c0c020b2008102e4104210b4100210c0c010b20034198046a41086a200341f0026a41086a290300221c370300200341f0036a41086a2206201c370300200341f0036a41106a2209200341f0026a41106a290300370300200341f0036a41186a220a200341f0026a41186a290300370300200341f0036a41206a220c200341f0026a41206a280200360200200320032903f002221c370398042003201c3703f00341241029220b450d01200b20032903f003370200200b41206a200c280200360200200b41186a200a290300370200200b41106a2009290300370200200b41086a200629030037020002400240200541246c415c6a2007470d00410121054101210c0c010b200241246a210f2004415c6a2110410121054101210c0340200f210202400340200341f0026a41206a2207200241206a280200360200200341f0026a41186a2206200241186a290200370300200341f0026a41106a2209200241106a290200370300200341f0026a41086a220a200241086a290200370300200320022902003703f002200341f0026a200341c0026a412010f8040d012004200241246a2202470d000c030b0b200341c0046a41206a2007280200220e36020020034198046a41086a200a290300221c37030020034198046a41106a2009290300222037030020034198046a41186a2006290300222a37030020034198046a41206a200e360200200320032903f0022229370398042007200e3602002006202a37030020092020370300200a201c370300200320293703f0020240200c2005470d00200541016a220c2005490d162005410174220e200c200c200e491b220cad42247e221c422088a70d16201ca7220e4100480d160240024020050d00200e1029210b0c010b200b200541246c200e102a210b0b200b450d050b200241246a210f200b200541246c6a220e20032903f002370200200e41206a2007280200360200200e41186a2006290300370200200e41106a2009290300370200200e41086a200a290300370200200541016a210520102002470d000b0b200d450d002008102e0b200341e0036a41086a22024200370300200342003703e00341edf8c000410f200341e0036a1003200341e0026a41086a2002290300370300200320032903e0033703e002200341003602f802200342013703f0022005200341f0026a104702402005450d00200b200541246c6a2104200b210703402007200341f0026a104a200741206a28020021060240024020032802f402220820032802f80222026b4104490d0020032802f00221080c010b200241046a22092002490d1520084101742202200920092002491b22024100480d150240024020080d002002102921080c010b20032802f00220082002102a21080b2008450d05200320023602f402200320083602f00220032802f80221020b2003200241046a3602f802200820026a20063600002004200741246a2207470d000b0b20032802f4022102200341e0026a411020032802f002220720032802f802100402402002450d002007102e0b410021080240200541246c22020d0041012109410021040c040b200241246d220441ffffff3f712004470d12200441057422024100480d122002102922090d0320024101102c000b41244104102c000b200e4104102c000b20024101102c000b02402005450d00200541246c21064100210820092102200b21070340200741086a290000211c200741106a29000021202007290000212a200241186a200741186a290000370000200241106a2020370000200241086a201c3700002002202a370000200841016a2108200241206a2102200741246a21072006415c6a22060d000b0b0240200c450d00200b102e0b200341f0026a41186a200341c0026a41186a290300370300200341f0026a41106a200341c0026a41106a290300370300200341f0026a41086a200341c0026a41086a290300370300200320032903c0023703f0024100210720092008200341e8046a410041202008676b105f41012106200341f0026a41012009200810df012004450d102009102e0c100b418df0c200210741282108410121090c160b200341e0036a41086a22024200370300200342003703e00341d0f9c0004113200341e0036a1003200341e0026a41086a2002290300370300200320032903e0033703e002200341f0026a200341e0026a10e001024020032802f002220c0d0041bbd3c1002107413121080c010b0240024002400240200341f0026a41086a2802002213450d0020032802f402211041bdd4c100210741232108200c290300202054200c41086a2903002229201c542029201c511b0d010c020b4190f9c000410041001038000b200341e0036a41086a22024200370300200342003703e00341edf8c000410f200341e0036a1003200341e0026a41086a2002290300370300200320032903e0033703e002200341f0026a200341e0026a10de010240024020032802f00222040d00410421044100210b410021050c010b200341f8026a280200210520032802f402210b0b2004200541246c6a210920042102410021070240024003400240200920026b41ec004b0d0020092002460d032004200541246c6a2109034020034198046a2002460d032007200220034198046a412010f80422064100476a21072006450d032009200241246a2202470d000c040b0b200220034198046a460d012007200220034198046a412010f80422064100476a21072006450d01200241246a220620034198046a460d012007200620034198046a412010f80422064100476a21072006450d01200241c8006a220620034198046a460d012007200620034198046a412010f80422064100476a21072006450d01200241ec006a220620034198046a460d0120024190016a21022007200620034198046a412010f80422064100476a210720060d000b0b2007202b422088a7490d0041e0d4c100210741362108200b450d012004102e0c010b0240200b450d002004102e0b200341b0026a10c701200341f0026a20034198046a10c50120032802f0024101460d01024020032802b402450d0020032802b002102e0b419ad4c10021070b2010450d01200c102e0c010b20032802b00221260240024002400240024002400240024020032802b80222020d004200212e4200212f0c010b20032802f4022106200241216c2107202641016a2102200341f8026a2802002208410876210941012008411f7174210d20084105764107712204417f73210e20034190036a21054200212e4200212f034002402002417f6a2d00004101470d00200341f0026a200210ca0120032903f0024201520d002003280298032006490d0020052903002130200341f0026a41106a2903002131200329038803213220032903f8022133200341f0016a41bfd9c5004111107d200341c0046a41186a200241186a290000370300200341c0046a41106a200241106a290000370300200341c0046a41086a200241086a290000370300200320022900003703c004200320093602e004200341c0026a200341c0046a10c901420021294200212d0240200420032802c80222084f0d002008200e6a220b20084f0d04203020317c203220337c2229203254ad7c420020032802c002200b4102746a280200200d7122081b212d2029420020081b21290b024020032802c402450d0020032802c002102e0b202d202f7c2029202e7c222e202954ad7c212f0b200241216a21022007415f6a22070d000b0b200c201341306c6a2119200c210202400240024002400240024003400240201920026b4190014b0d00024020022019460d00034041012108200241106a220220034198046a460d04200220034198046a412010f804450d04200241206a22022019470d000b0b41002108202e202085202f201c858450450d0220034198046a41186a290300212a200341a8046a2903002129200341a0046a290300212c200329039804212d200c201c370308200c2020370300200c202d370310200c41186a202c370300200c41206a2029370300200c41286a202a37030020134115490d092013410176221ead42307e221c422088a70d19201ca72202417f4c0d1920020d03410821254108210b0c040b41012108200241106a220720034198046a460d01200720034198046a412010f804450d01200241c0006a220720034198046a460d01200720034198046a412010f804450d01200241f0006a220720034198046a460d01200720034198046a412010f804450d01200241a0016a220720034198046a460d01200241c0016a2102200720034198046a412010f8040d000b0b411410292202450d04200241002900d88c40370000200241106a41002800e88c40360000200241086a41002900e08c4037000020034294808080c0023702f402200320023602f002200341f0036a200341f0026a104a20032802f4022102200341d8016a20032802f002220620032802f802106e200341d8016a41106a290300420020032802d80122071b211c20032903e001420020071b212002402002450d002006102e0b200341f0036a2020202c20202020202c56201c202a56201c202a511b22021b22297d201c202a201c20021b222e7d2020202954ad7d10730240202c20297d222f202a202e7d202c202954ad7d222d84500d00411810292202450d04200241002900ec8c40370000200241106a41002900fc8c40370000200241086a41002900f48c403700002003429880808080033702f402200320023602f002200341f0036a200341f0026a104a20032802f4022102200341c0016a20032802f002220620032802f802106e200341c0016a41106a290300420020032802c00122071b211c20032903c801420020071b212002402002450d002006102e0b200341f0036a2020202f20202020202f56201c202d56201c202d511b22021b222a7d201c202d201c20021b222c7d2020202a54ad7d108c01202c202e7c202a20297c222c202a54ad7c212a0b200341e0036a41086a22024200370300200342003703e00341c28cc0004116200341e0036a1003200341e0026a41086a22062002290300370300200320032903e0033703e002200341a8016a200341e0026a109701200341a8016a41106a290300211c20032903b001212020032802a801210720024200370300200342003703e00341c28cc0004116200341e0036a100320062002290300370300200320032903e0033703e00220034200201c420020071b221c202a7d2020420020071b2220202c54ad7d222a2020202c7d2229202056202a201c56202a201c511b22021b3703f80220034200202920021b3703f002200341e0026a4110200341f0026a411010044196d5c10041acd5c10020081b21074116410f20081b2108410121020c080b200210292225450d012025210b0b200c41506a2128200c41306a211f200c41f07e6a211d41042111410021274100210520132117034020172104410021174101210902402004417f6a2208450d00024002400240024002400240200c200841306c6a2202290300200441306c220e200c6a41a07f6a2207290300222054200241086a290300222a200741086a290300221c54202a201c511b0d002004417e6a210d201d200e6a2102410021174100210703400240200d2007470d00200421090c080b2020200229030022295a2108201c200241086a290300222a512106201c202a5a2109200241506a2102200741016a210720292120202a211c2008200920061b0d000b200741016a21092007417f7320046a21080c010b201d200e6a210202400340024020084101470d00410021080c020b202020022903002229542107201c200241086a290300222a512106201c202a542109200241506a21022008417f6a210820292120202a211c2007200920061b0d000b0b20042008490d01200420134b0d03200420086b22094101762206450d002028200e6a2102200c200841306c6a21070340200341f0026a41286a220d200741286a220e290300370300200341f0026a41206a220f200741206a2212290300370300200341f0026a41186a2214200741186a2215290300370300200341f0026a41106a2216200741106a2217290300370300200341f0026a41086a2218200741086a221a290300370300200320072903003703f002200241086a221b290300211c200241106a22212903002120200241186a2222290300212a200241206a22232903002129200241286a2224290300212c20072002290300370300200e202c370300201220293703002015202a37030020172020370300201a201c3703002024200d2903003703002023200f2903003703002022201429030037030020212016290300370300201b2018290300370300200220032903f002370300200741306a2107200241506a21022006417f6a22060d000b0b024020080d00200821170c050b0240200941094d0d00200821170c050b200420134b0d01200420086b2106201f200841306c6a210d034020042008417f6a2217490d040240200420176b22094102490d00200c200841306c6a2202290300200c201741306c6a2208290300222a5a200241086a22072903002220200841086a220e290300221c5a2020201c511b0d00200341f0026a41186a2212200841286a220f290300370300200341f0026a41106a2214200841206a2215290300370300200341f0026a41086a2216200841186a2218290300370300200320082903103703f00220082002290300370300200e2007290300370300200841106a200241106a2903003703002018200241186a2903003703002015200241206a290300370300200f200241286a29030037030041012107024020094103490d002008290360202a5a200841e8006a2903002220201c5a2020201c511b0d004102210e200d210f0340200f220241506a22072002290300370300200741286a200241286a290300370300200741206a200241206a290300370300200741186a200241186a290300370300200741106a200241106a290300370300200741086a200241086a2903003703002006200e2207460d01200741016a210e200241306a220f290300202a5a200241386a2903002220201c5a2020201c511b450d000b0b2002202a3703002002201c3703082008200741306c6a220241286a2012290300370300200241206a2014290300370300200241186a2016290300370300200220032903f0023703100b2017450d05200d41506a210d200641016a2106201721082009410a4f0d050c000b0b200820041035000b20042008417f6a2217490d010b20042013105e000b201720041035000b02400240024020272005470d00202741016a22022027490d1920274101742207200220022007491b220241ffffffff01712002470d19200241037422074100480d190240024020270d002007102921110c010b201120274103742007102a21110b2011450d01200221270b201120054103746a2202200936020420022017360200200541016a2212210520124102490d010340024002400240024020112012220e417f6a22124103746a2202280200450d00200e41037420116a220941746a2802002206200228020422074d0d0041022105200e41024d0d062011200e417d6a22024103746a2802042208200720066a4d0d0141032105200e41034d0d06200941646a280200200820066a4d0d01200e21050c060b200e4103490d01200228020421072011200e417d6a22024103746a28020421080b20082007490d010b200e417e6a21020b024002400240024002400240200e200241016a22184d0d00200e20024d0d01201120024103746a2214280204221a20142802006a2202201120184103746a22152802002216490d02200220134b0d03201441046a211b200c201641306c6a220d2015280204220f41306c22076a2106200241306c2108200220166b2204200f6b2202200f4f0d0420252006200241306c220710f6041a200b20076a210902400240200f4101480d00200241014e0d010b20062102200b21070c060b202820086a21082006210203402008200241506a2206200941506a22042004290300200629030054200441086a290300221c200641086a290300222054201c2020511b22051b2207290300370300200841086a200741086a290300370300200841106a200741106a290300370300200841186a200741186a290300370300200841206a200741206a290300370300200841286a200741286a2903003703002009200420051b21090240200d2006200220051b2202490d00200b21070c070b200841506a2108200b2107200b2009490d000c060b0b41f484c0002018200e1038000b41f484c0002002200e1038000b201620021035000b20022013105e000b2025200d200710f6041a200b20076a210902400240200f4101480d002004200f4a0d010b200d2102200b21070c010b200c20086a2105200b2107200d210203402002200620072006290300200729030054200641086a290300221c200741086a290300222054201c2020511b22041b2208290300370300200241086a200841086a290300370300200241106a200841106a290300370300200241186a200841186a290300370300200241206a200841206a290300370300200241286a200841286a2903003703002007200741306a20041b2107200241306a2102200641306a200620041b220620054f0d01200920074b0d000b0b20022007200920076b220820084130706b10f6041a201b201a200f6a360200201420163602002015201541086a2018417f73200e6a41037410f7041a20122105201241014d0d020c000b0b20074104102c000b20170d000b02402027450d002011102e0b201e450d052025102e0c050b20024108102c000b41184101102c000b41144101102c000b4190f9c000200b20081038000b20134102490d002013417f6a2108200c201341306c6a21044101210603400240024002400240201320082202417f6a2208490d00201320086b22074102490d03200c200241306c6a2202290300200c200841306c6a2209290300222a5a200241086a22052903002220200941086a220b290300221c5a2020201c511b0d03200341f0026a41186a220d200941286a220e290300370300200341f0026a41106a220f200941206a2211290300370300200341f0026a41086a2212200941186a2214290300370300200320092903103703f00220092002290300370300200b2005290300370300200941106a200241106a2903003703002014200241186a2903003703002011200241206a290300370300200e200241286a2903003703004101210520074103490d022009290360202a5a200941e8006a2903002220201c5a2020201c511b0d02410021052004210703402007220241506a22072002290300370300200741286a200241286a290300370300200741206a200241206a290300370300200741186a200241186a290300370300200741106a200241106a290300370300200741086a200241086a29030037030020062005220b460d02200b417f6a2105200241306a2207290300202a5a200241386a2903002220201c5a2020201c511b0d020c000b0b200820131035000b4102200b6b21050b2002202a3703002002201c3703082009200541306c6a220241286a200d290300370300200241206a200f290300370300200241186a2012290300370300200220032903f0023703100b200441506a21042006417f6a210620080d000b0b200341e0036a41086a22024200370300200342003703e00341d0f9c0004113200341e0036a1003200341e0026a41086a2002290300370300200320032903e0033703e002200341003602f802200342013703f0022013200341f0026a1047200c21020340200241086a290300211c200229030021200240024020032802f402220820032802f80222076b4110490d0020032802f00221080c010b200741106a22062007490d1120084101742207200620062007491b22074100480d110240024020080d002007102921080c010b20032802f00220082007102a21080b2008450d03200320073602f402200320083602f00220032802f80221070b200820076a2208201c370008200820203700002003200741106a3602f802200241106a200341f0026a104a200241306a22022019470d000b20032802f4022102200341e0026a411020032802f002220720032802f802100402402002450d002007102e0b02402010450d00200c102e0b41002102410021070b024020032802b402450d002026102e0b024020020d00202ba7450d160c020b02402010450d00200c102e0b202ba7450d150c010b20074101102c000b200a102e0c130b202ba7450d12200a102e0c120b02400240024002402008410020041b22042005470d0020022005460d010b41f9d1c100210741162108200220054d0d0120034188036a420037030020034180036a4200370300200341f8026a4200370300200342003703f002200620054105746a220a200341f0026a460d00200a200341f0026a412010f8040d010b20034198016a20034198046a4280809aa6eaafe3014200109301200328029801450d01418fd2c1002107411e21080b2009450d122006102e0c120b20034190016a41bfd9c5004111107d200328029001210a200328029401210b411610292207450d01200741002900d7f8403700002007410e6a41002900e5f840370000200741086a41002900dff84037000020034296808080e0023702f402200320073602f00220034198046a200341f0026a104a20032802f402210c20032802f802210720032802f0022108200341f0026a41186a220d4200370300200341f0026a41106a220e4200370300200341f0026a41086a220f4200370300200342003703f00220082007200341f0026a1000200341c0046a41186a200d290300370300200341c0046a41106a200e290300370300200341c0046a41086a200f290300370300200320032903f0023703c004410810292207450d02200720053600042007200b4100200a1b360000200341c0046a41202007410810042007102e0240200c450d002008102e0b0240024020022005460d00200341f0026a41186a220820034198046a41186a290300370300200341f0026a41106a220a20034198046a41106a290300370300200341f0026a41086a220b20034198046a41086a29030037030020032003290398043703f002200220054d0d05200620054105746a220720032903f002370000200741186a2008290300370000200741106a200a290300370000200741086a200b2903003700000c010b200341f0026a41186a220720034198046a41186a290300370300200341f0026a41106a220820034198046a41106a290300370300200341f0026a41086a220a20034198046a41086a29030037030020032003290398043703f002024020092005470d00200541016a22022005490d0c20054101742209200220022009491b220941ffffff3f712009470d0c200941057422024100480d0c0240024020050d002002102921060c010b200620054105742002102a21060b2006450d060b200620054105746a220220032903f002370000200241186a2007290300370000200241106a2008290300370000200241086a200a290300370000200541016a21020b200341e0036a41086a22074200370300200342003703e00341f4f9c0004112200341e0036a1003200341e0026a41086a2007290300370300200320032903e0033703e002200341003602f802200342013703f0022002200341f0026a104702402002450d00200241057421072006210203402002200341f0026a104a200241206a2102200741606a22070d000b0b20032802f4022102200341e0026a411020032802f002220720032802f802100402402002450d002007102e0b02402009450d002006102e0b200341e0036a41086a22024200370300200342003703e00341f6d9c5004116200341e0036a1003200341e0026a41086a2002290300370300200320032903e0033703e002410121062003200441016a3602f002200341e0026a4110200341f0026a410410040b410021070c0b0b41164101102c000b41084101102c000b41e4f9c000200520021038000b20024101102c000b0b024020032802c404450d0020032802c004102e0b024020070d00418dd1c10021070c0b0b2003201c37038803200320093a008703200320043a008603200320053b0184032003200a3a0083032003200b3a0082032003200c3b0180032003200d3a00ff022003200e3a00fe022003200f3b01fc02200320103a00fb02200320123600f702200320113600f302200320023a00f202200320063b01f0020240200341f0026a20034198046a412010f8040d0020034198046a201610e10120034198046a428080e983b1de164200109401200342f0f2bda9c6add9b1f4003703c00220034188016a41b0f3c200410d107d410021072003200328028c0141002003280288011b3602e003200341c0046a20034198046a107c20032802c404210820032802c004210220032802c8042106200341d4046a200341c0026a3602002003200220064105746a3602cc04200320023602c804200320083602c404200320023602c0042003200341e0036a3602d004200341f0036a200341c0046a1044200341c0046a41086a200341f0036a41086a280200360200200320032903f0033703c00420034198046a200341c0046a1090010c0b0b41f4d0c1002107411921080c0a0b0b024020032802f402450d0020032802f002102e0b024020070d0041c7cfc10021070c090b2003201c3703b004200320093a00af04200320043a00ae04200320053b01ac042003200a3a00ab042003200b3a00aa042003200d3b01a8042003200e3a00a7042003200f3a00a604200320103b01a404200320113a00a3042003201336009f042003201236009b04200320023a009a04200320063b019804200341f0026a201e41067610c8014100210702400240201e413f71220220032802f8024f0d0020032802f002200241216c6a22022d00004101470d0020022f00012108200241196a290000211c200241186a2d00002106200241176a2d00002109200241156a2f00002104200241146a2d00002105200241136a2d0000210a200241116a2f0000210b200241106a2d0000210d2002410f6a2d0000210e2002410d6a2f0000210f2002410c6a2d00002110200241086a2800002112200241046a2800002111200241036a2d00002102410121070c010b0b024020032802f402450d0020032802f002102e0b024020070d0041e0d0c1002107411421080c090b2003201c3703d804200320063a00d704200320093a00d604200320043b01d404200320053a00d3042003200a3a00d2042003200b3b01d0042003200d3a00cf042003200e3a00ce042003200f3b01cc04200320103a00cb04200320123600c704200320113600c304200320023a00c204200320083b01c004024020034198046a200341c0026a412010f804450d0041bed0c1002107411221080c090b0240200341c0046a200341f0036a412010f804450d0041d0d0c1002107411021080c090b200341f0026a41186a2213200341f0036a41186a2214290300370300200341f0026a41106a2215200341f0036a41106a2216290300370300200341f0026a41086a2217200341f0036a41086a2218290300370300200320032903f0033703f002410021022003410036029003200341e0036a200341f0026a10c9010240024020032802e80322050d004101210e4100210f0c010b4100210d4100210f4101210e4100211103402005417f4c0d0220032802e403211220032802e00321100240024020051029220a450d00024002400240200541027422020d00410021040c010b201020026a210b410021042010210903402009280200210702400240024002400240412010292202450d00200941046a210920022007411f763a001f200220074101713a000020022007411e764101713a001e20022007411d764101713a001d20022007411c764101713a001c20022007411b764101713a001b20022007411a764101713a001a200220074119764101713a0019200220074118764101713a0018200220074117764101713a0017200220074116764101713a0016200220074115764101713a0015200220074114764101713a0014200220074113764101713a0013200220074112764101713a0012200220074111764101713a0011200220074110764101713a001020022007410f764101713a000f20022007410e764101713a000e20022007410d764101713a000d20022007410c764101713a000c20022007410b764101713a000b20022007410a764101713a000a200220074109764101713a0009200220074108764101713a00082002200741ff017122074107763a0007200220074106764101713a0006200220074105764101713a0005200220074104764101713a0004200220074103764101713a0003200220074102764101713a0002200220074101764101713a00014100210702400340200741206a220841034d0d010240200220076a2208411f6a2d0000450d002007411f6a21060c060b2008411e6a2d00000d042008411d6a2d00000d032007417c6a21072008411c6a2d0000450d000b200741206a21060c040b03402008450d05200220086a21072008417f6a220621082007417f6a2d0000450d000c040b0b41204101102c000b2007411d6a21060c010b2007411e6a21060b200641016a22082006490d000240200520046b2008412020084120491b22074f0d00200420076a22072004490d0a20054101742206200720072006491b22074100480d0a0240024020050d0020071029210a0c010b200a20052007102a210a0b200a450d04200721050b200a20046a2106410021070240034020074120460d01200620076a200220076a2d00004101713a00002008200741016a2207470d000b0b200420076a21040b2002102e2009200b470d000b0b02402012450d002010102e0b0240200f200d6b2004490d00200d20046a21020c030b200d20046a2202200d490d06200f4101742207200220022007491b22074100480d0602400240200f0d0020071029210e0c010b200e200f2007102a210e0b0240200e450d002007210f0c030b20074101102c000b20074101102c000b20054101102c000b200e200d6a200a200410f6041a02402005450d00200a102e0b201320142903003703002015201629030037030020172018290300370300200320032903f0033703f0022003201141016a221136029003200341e0036a200341f0026a10c9012002210d20032802e80322050d000b0b024020032802e403450d0020032802e003102e0b200341e0036a41086a22074200370300200342003703e00341f4f9c0004112200341e0036a1003200341e0026a41086a2007290300370300200320032903e0033703e002200341003602f002200341e0026a4110200341f0026a10082107024020032802f0022208417f460d002007450d00200320083602e403200320073602e003200341f0026a200341e0036a1030024020032802f002220a450d00200341f8026a280200210620032802f402210b02402008450d002007102e0b200641ffffff3f7121070c040b41eff0c2004133200341e8046a4184f4c2001053000b4101210a410021074100210b0c020b1032000b102d000b0240024020072002200220074b1b2208450d004100210720034188036a210620034180036a2109200341f8026a2104200a210203400240200e20076a2d0000450d00200642003703002009420037030020044200370300200342003703f002200341f0026a2002460d002002200341f0026a412010f804450d00200341f0026a200210c5014101210520032802f0024101470d0020032802f402200c4d0d030b200241206a2102200741016a22072008490d000b0b410021050b0240200b450d00200a102e0b0240200f450d00200e102e0b200341c0026a200341f0036a20051b2207201f201e20051b10e101200342f0f2bda9c6add9b1f4003703b002200341f8006a41b0f3c200410d107d2003200328027c410020032802781b3602e002200341f0026a2007107c20032802f402210820032802f002210220032802f802210620034184036a200341b0026a3602002003200220064105746a3602fc02200320023602f802200320083602f402200320023602f0022003200341e0026a36028003200341e0036a200341f0026a1044200341f0026a41086a200341e0036a41086a2202280200360200200320032903e0033703f0022007200341f0026a109001024002402005450d00200341286a200341c0026a428080e983b1de164200109201200341286a41086a290300212a2003290328211c20024200370300200342003703e00341c28cc0004116200341e0036a1003200341e0026a41086a22082002290300370300200320032903e0033703e002200341106a200341e0026a109701200341106a41106a2903002120200329031821292003280210210720024200370300200342003703e00341c28cc0004116200341e0036a100320082002290300370300200320032903e0033703e002200342002020420020071b2220202a7d2029420020071b222a201c54ad7d2229202a201c7d221c202a56202920205620292020511b22021b3703f80220034200201c20021b3703f002200341e0026a4110200341f0026a41101004200341013a00f402200341083a00f002200341f0026a4105722102200341f0026a21080c010b200341e8006a200341c0026a1084012003290368200341e8006a41086a29030084500d04411810292202450d02200241002900ec8c40370000200241106a41002900fc8c40370000200241086a41002900f48c403700002003429880808080033702f402200320023602f002200341f0036a200341f0026a104a20032802f4022102200341d0006a20032802f002220820032802f802106e200341d0006a41106a290300211c200328025021072003290358212002402002450d002008102e0b411410292202450d03201c420020071b222a42002020420020071b221c428080e983b1de16544100202a501b22071b2129201c428080e983b1de1620071b2120200241002900d88c40370000200241106a41002800e88c40360000200241086a41002900e08c4037000020034294808080c0023702f402200320023602f002200341c0026a200341f0026a104a20032802f4022102200341386a20032802f002220820032802f802106e200341386a41106a2903004200200328023822071b212b2003290340420020071b212c02402002450d002008102e0b200341c0026a202c20207c222d202b20297c202d202c54ad7c1073200341f0036a201c20207d202a20297d201c202054ad7d108c0120034185036a200341f0036a41106a2903003700002003418d036a20034188046a290300370000200341083a00f002200341fd026a200341f0036a41086a290300370000200341003a00f402200320032903f0033700f50220034195036a2102200341f0026a21080b200220032903c002370000200241186a200341c0026a41186a290300370000200241106a200341c0026a41106a290300370000200241086a200341c0026a41086a2903003700004100210741c8ecc500410020081072410121060b410121090c060b41184101102c000b41144101102c000b41e98bc0002107412221080c010b41ccc4c2002107411521080b41012106410121090c010b41012109410021062004450d002005102e0b02402001280200417f6a220241014b0d000240024020020e020001000b2009450d01200141086a280200450d012001280204102e0c010b2006450d00200141086a280200450d002001280204102e0b2000200836020420002007360200200341f0046a24000b11002001200028020020002802041093040beb2405087f047e037f027e077f230041a0026b2205240020054180026a41086a22064200370300200542003703800241f4f9c000411220054180026a100320054198016a41086a2006290300370300200520052903800237039801410021062005410036026820054198016a4110200541e8006a100821070240024020052802682208417f460d002007450d0020052008360284022005200736028002200541e8006a20054180026a1030024020052802682206450d00200541f0006a2802002109200528026c210a2008450d022007102e0c020b41eff0c2004133200541d0016a4184f4c2001053000b0b20054180026a41086a2208420037030020054200370380024114210741fcf8c000411420054180026a100320054198016a41086a2008290300370300200520052903800237039801200a410020061b210b2006410120061b210c02400240024020054198016a411041c8ecc500410041001005417f460d0041bbd5c100210a412e21070c010b200541e0006a41bfd9c5004111107d41e9d5c100210a2005280264410020052802601b2003470d0002402009410020061b22060d0041fdd5c100210a41c10021070c010b02402006200241086a28020022084f0d0041bed6c100210a413c21070c010b200541d0006a2001108401200541d0006a41086a290300210d2005290350210e200541e8006a200110ca0102400240024002400240024002400240024002400240024020052903684201510d00411410292206450d03200641002900d88c40370000200641106a41002800e88c40360000200641086a41002900e08c4037000020054294808080c002370284022005200636028002200120054180026a104a2005280284022106200541386a2005280280022207200528028802106e200541386a41106a290300210f200529034021102005280238210902402006450d002007102e0b419ed7c100210a413421072010428180e983b1de16544100200f501b0d0c2009450d0c20054180026a2004410676220a10c8014100210602402005280288022004413f7122074d0d0041014102200528028002200741216c6a2d00001b21060b0240200528028402450d00200528028002102e0b20064102490d0120054198016a200a10c80120054180026a41186a2204200141186a29000037030020054180026a41106a2211200141106a29000037030020054180026a41086a2212200141086a290000370300200520012900003703800220052802a001221320074d0d042005280298012209200741216c6a220641013a00002006200529038002370001200641096a2012290300370000200641116a2011290300370000200641196a2004290300370000410e10292206450d05200641066a41002900f6fa40370000200641002900f0fa403700002006410e411c102a2206450d062006200a36000e20054180026a41186a2207420037030020054180026a41106a220a420037030020054180026a41086a2204420037030020054200370380022006411220054180026a1000200541e0016a41186a2007290300370300200541e0016a41106a200a290300370300200541e0016a41086a200429030037030020052005290380023703e00120054120360284022005200541e0016a360280022009201320054180026a10bf012006102e200528029c01450d022009102e0c020b200541f8006a29030021102005290370210f200541e0016a200441067610c801410021062004413f71220720052802e8014f0d0720052802e001200741216c6a220a2d00004101470d07200541d2016a200a41036a2d00003a0000200541b8016a41086a200a41146a290000370300200541c5016a200a41196a2900003700002005200a2f00013b01d0012005200a410c6a2900003703b801200a41086a2800002107200a41046a280000210a410121060c080b200541306a41d0d9c5004114107d200541b8016a2005280234410020052802301b220a10c801024020052802c00122060d0020054180026a2001428080d287e2bc2d42004108107a02402005280280024101470d002005280288022107200528028402210a20052802bc01450d0c20052802b801102e0c0c0b20054180026a41106a2903002114200529038802210f20054180026a41086a22074200370300200542003703800241c28cc000411620054180026a100320054198016a41086a22042007290300370300200520052903800237039801200541186a20054198016a109701200541186a41106a2903002110200529032021152005280218210920074200370300200542003703800241c28cc000411620054180026a100320042007290300370300200520052903800237039801200542002010420020091b221020147d2015420020091b2214200f54ad7d22152014200f7d220f201456201520105620152010511b22071b3703880220054200200f20071b3703800220054198016a411020054180026a41101004200d200e428080aef89dc3527c220f200e54ad7c427f7c210d200f210e0b200541e0016a41186a2207200141186a290000370300200541e0016a41106a2209200141106a290000370300200541e0016a41086a2204200141086a290000370300200520012900003703e0010240200641c000460d0020054180026a41186a200729030037030020054180026a41106a200929030037030020054180026a41086a2004290300370300200520052903e001370380020240024020052802bc012006460d0020052802b80121070c010b200641016a22072006490d0b20064101742209200720072009491b2209ad42217e220f422088a70d0b200fa722044100480d0b0240024020060d002004102921070c010b20052802b801200641216c2004102a21070b2007450d07200520093602bc01200520073602b8010b2007200641216c6a220741013a00002007200529038002370001200741096a20054180026a41086a2209290300370000200741116a20054180026a41106a290300370000200741196a20054198026a2903003700002005200641016a3602c0012006413f470d0020094200370300200542003703800241d0d9c500411420054180026a100320054198016a41086a20092903003703002005200529038002370398012005200a41016a3602800220054198016a411020054180026a410410040b20054180026a41086a200541b8016a41086a280200360200200520052903b80137038002200a20054180026a10e2010b4200210f200541106a2001428080e983b1de16420010930102402005280210220a450d00200528021421070c0a0b200541086a41e4d9c5004112107d20052802082106200528020c210720054180026a41086a220a4200370300200542003703800241e4d9c500411220054180026a100320054198016a41086a200a2903003703002005200529038002370398012005200741016a410120061b3602800220054198016a411020054180026a41041004420021100c070b41144101102c000b41e4f9c000200720131038000b410e4101102c000b411c4101102c000b20044101102c000b0b024020052802e401450d0020052802e001102e0b0240024020060d00410121064113210741fad6c100210a0c010b200541b4016a41026a200541d0016a41026a2d00003a0000200541e0016a41086a200541b8016a41086a290300370300200541e0016a410d6a200541b8016a410d6a290000370000200520052f01d0013b01b401200520052903b8013703e001410021060b200541b0016a41026a2209200541b4016a41026a2d00003a000020054198016a41086a2204200541e0016a41086a29030037030020054198016a41106a200541e0016a41106a290300370300200520052f01b4013b01b001200520052903e0013703980120060d0220054193026a200429030037000020054198026a200541a5016a290000370000200520052f01b0013b01800220052007360087022005200a36008302200520052903980137008b02200520092d00003a00820220054180026a2001460d0020054180026a2001412010f804450d00418dd7c100210a411121070c020b200542f0f2bda9c6add9b1f4003703d801200541d8016a2001200e200d417f410e109101200541e8006a41186a200d3703002005200e370378200520103703702005200f3703682005200336028c012005200336028801024002400240411310292206450d0020064100290086fa403700002006410f6a4100280095fa40360000200641086a410029008efa4037000020054293808080b002370284022005200636028002200120054180026a104a2005280284022107200528028802210a200528028002210620054180026a41186a2203420037030020054180026a41106a2209420037030020054180026a41086a2204420037030020054200370380022006200a20054180026a1000200541e0016a41186a2003290300370300200541e0016a41106a2009290300370300200541e0016a41086a200429030037030020052005290380023703e00120054120360284022005200541e0016a36028002200541e8006a20054180026a10cb0102402007450d002006102e0b200228020421042002280200210a024002400240200841057622160d0041042117410421180c010b2016410274220610292217450d01201721180b2008450d020240024020160d00410410292217450d0141012116201721180b201841003602002008417f6a21034101211341002107410021060240034002400240024002400240024002400240201320074d0d00201820074102746a22022002280200200a20066a2d00002006411f71746a360200024020032006460d00200641016a2206411f710d0820162013470d07201641016a22022016490d1020164101742209200220022009491b220241ffffffff03712002470d102002410274220941004e0d060c100b02402004450d00200a102e0b410021190340200541e8006a41186a200141186a290000370300200541e8006a41106a200141106a290000370300200541e8006a41086a200141086a2900003703002005201936028801200520012900003703682013410820134108491b221a410274221110292206450d0220062018201110f6042112411310292206450d03200641002900ddfa403700002006410f6a41002800ecfa40360000200641086a41002900e5fa4037000020054293808080b002370284022005200636028002200541e8006a20054180026a104a200528028801210202400240200528028402220720052802880222066b4104490d0020052802800221070c010b200641046a220a2006490d1120074101742206200a200a2006491b22064100480d110240024020070d002006102921070c010b20052802800220072006102a21070b2007450d052005200636028402200520073602800220052802880221060b2013201a6b2113201820116a21182005200641046a36028802200720066a2002360000200528028402211b2005280288022106200528028002211c20054180026a41186a2207420037030020054180026a41106a2202420037030020054180026a41086a220a42003703002005420037038002201c200620054180026a1000200541e0016a41186a2007290300370300200541e0016a41106a2002290300370300200541e0016a41086a200a29030037030020052005290380023703e0014100210620054100360288022005420137038002201a20054180026a1047410020052802880222036b210220052802840221080340200320066a210a201220066a280200210902400240200820026a4104490d0020052802800221070c010b200a41046a2207200a490d1220084101742204200720072004491b22044100480d120240024020080d002004102921070c010b20052802800220082004102a21070b2007450d0720052004360284022005200736028002200421080b2005200a41046a36028802200720036a20066a20093600002002417c6a21022011200641046a2206470d000b200541e0016a41202007200320066a100402402008450d002007102e0b0240201b450d00201c102e0b0240201a450d002012102e0b201941016a211920130d000b2016450d0e2017102e0c0e0b41e4f9c000200720131038000b20114104102c000b41134101102c000b20064101102c000b20044101102c000b0240024020160d002009102921170c010b201720164102742009102a21170b2017450d0320172118200221160b201820134102746a4100360200200741016a2107201341016a21130b200820064b0d000b4190f9c000200620081038000b20094104102c000b41044104102c000b20064104102c000b41134101102c000b2004450d00200a102e0b4100210a0240200b450d00200c102e0b0c020b102d000b0240200b450d00200c102e0b200241046a280200450d002002280200102e0b200020073602042000200a360200200541a0026a24000bcb0201047f230041d0006b220324002003410036022820012002200341286a1008210402400240024020032802282205417f460d0020040d010b200041003a00000c010b41002101200341003a00480340024020052001470d000240200141ff0171450d00200341003a00480b41eff0c2004133200341286a4184f4c2001053000b200341286a20016a200420016a2d00003a00002003200141016a22023a00482002210120024120470d000b200341086a41186a2201200341286a41186a290300370300200341086a41106a2202200341286a41106a290300370300200341086a41086a2206200341286a41086a2903003703002003200329032837030802402005450d002004102e0b20002003290308370001200041013a0000200041196a2001290300370000200041116a2002290300370000200041096a20062903003700000b200341d0006a24000bef0101047f230041206b220224002002410036021020014110200241106a10082101024002400240024020022802102203417f460d0020010d010b200041003602080c010b200220013602082002200336020c20034104490d012002200141046a36020820022003417c6a220436020c20044104490d01200128000021042002200341786a36020c2002200141086a36020820012800042103200241106a200241086a103020022802102205450d012000200229021437020c2000200536020820002003360204200020043602002001102e0b200241206a24000f0b41eff0c2004133200241106a4184f4c2001053000bfa05020e7f037e23004180016b220224002002410036025820014110200241d8006a1008210302400240024002400240024020022802582204417f470d00200041003602000c010b2002200436021420022003360210200241086a200241106a103120022802080d042002280214220541246e220641246c2201417f4c0d01200228020c21070240024020010d00410421080c010b200110292208450d030b02402007450d00410021090340200241003a00782009220a41016a2109410021010240024002400240034020052001460d01200241d8006a20016a2002280210220b2d00003a00002002200b41016a3602102002200141016a220c3a0078200c2101200c4120470d000b200241386a41086a220d200241d8006a41086a290300370300200241386a41106a220e200241d8006a41106a290300370300200241386a41186a220f200241d8006a41186a2903003703002002200229035837033820022005200c6b220136021420014104490d01200241186a41086a220c200d290300370300200241186a41106a220d200e290300370300200241186a41186a220e200f290300370300200220022903383703182002200b41056a36021020022001417c6a2205360214200b280001210b2006200a470d030240200a4101742201200920092001491b2206ad42247e2210422088a70d002010a7220141004e0d030b102d000b20024100360214200141ff0171450d00200241003a00780b2006450d082008102e0c080b02400240200a0d002001102921080c010b2008200a41246c2001102a21080b2008450d060b2008200a41246c6a22012002290318370200200c2903002110200d2903002111200e29030021122001200b360220200141186a2012370200200141106a2011370200200141086a201037020020092007470d000b0b2008450d042000200636020420002008360200200041086a20073602002004450d002003102e0b20024180016a24000f0b1032000b20014104102c000b20014104102c000b41eff0c2004133200241d8006a4184f4c2001053000bae0f030b7f077e057f230022042105200441c0016b41607122042400024002400240024002400240200141ffffff3f712001470d0020014105742206417f4c0d000240024020060d00410121070c010b200610292207450d020b410021084100210602402001450d0020014105742109416020006b210a2007210620002108034020062008290000370000200641186a200841186a290000370000200641106a200841106a290000370000200641086a200841086a290000370000200641206a2106200841206a2108200941606a22090d000b200020014105746a200a6a41057641016a2106200121080b20042006360218200420083602142004200736021020072006200441206a410041202006676b105f200441a0016a41086a22064200370300200442003703a00141a9c9c200411d200441a0016a100320044180016a41086a2006290300370300200420042903a00137038001200441003602a00120044180016a4110200441a0016a100821080240024020042802a0012206417f460d002004200636024420042008360240200441a0016a200441c0006a103020042802a001220b450d04200441a8016a280200210920042802a401210c2006450d012008102e0c010b4101210b410021094100210c0b2009410574220a450d05200441a0016a411472210d200441a0016a410872210e200b21060340200641086a290000210f200641106a290000211020062900002111200441206a41186a200641186a290000370300200441206a41106a2010370300200441206a41086a200f37030020042011370320200441c0006a200441206a108d03200441003602a80120042903582111200420042903b801221237035820042903502113200420042903b001221437035020042903402115200420042903a0013703402004290348210f200420042903a80122103703482014422088a721002010422088a721012012a721072010a721080240200fa72209450d00200420153703a0012004200f3703a801200420133703b001200420113703b801200420092013a74105746a36028c0120042009360288012004200f422088a73602840120042009360280012004200441106a36029001200441f0006a20044180016a1042200e41086a200441f0006a41086a2216280200360200200e200429037037020020042013422088a722092011422088a74105746a36028c01200420093602880120042011a73602840120042009360280012004200441106a36029001200441f0006a20044180016a1042200d41086a2016280200360200200d200429037037020020042903a801210f20042903a001211320042903b801211020042903b001211102402008450d0002402001450d002008102e0b2007450d002000102e0b200420133703402004200f370348200f422088a72101200420113703502011422088a7210020042010370358200fa721082010a721070b0240024020080d00411a10292208450d06200841186a41002f00dec9423b0000200841106a41002900d6c942370000200841086a41002900cec942370000200841002900c6c9423700002004429a808080a0033702a401200420083602a001200441206a200441a0016a104620042802a401210920042802a801210120042802a0012108200441a0016a41186a22074200370300200441a0016a41106a22004200370300200441a0016a41086a22164200370300200442003703a00120082001200441a0016a100020044180016a41186a200729030037030020044180016a41106a200029030037030020044180016a41086a2016290300370300200420042903a0013703800120044180016a412010062009450d012008102e0c010b411a10292209450d06200941186a41002f00dec9423b0000200941106a41002900d6c942370000200941086a41002900cec942370000200941002900c6c9423700002004429a808080a0033702a401200420093602a001200441206a200441a0016a104620042802a401211620042802a801211720042802a0012109200441a0016a41186a22184200370300200441a0016a41106a22194200370300200441a0016a41086a221a4200370300200442003703a00120092017200441a0016a100020044180016a41186a201829030037030020044180016a41106a201929030037030020044180016a41086a201a290300370300200420042903a00137038001200441203602a401200420044180016a3602a001200441c0006a200441a0016a108e0302402016450d002009102e0b02402001450d002008102e0b2007450d002000102e0b200641206a2106200a41606a220a0d000c060b0b1032000b20064101102c000b41eff0c2004133200441206a4184f4c2001053000b411a4101102c000b411a4101102c000b0240200c450d00200b102e0b200441003602a801200442013703a0012003200441a0016a104702402003450d002003410574210603402002200441a0016a104a200241206a2102200641606a22060d000b0b20042802a401210820042802a801210920042802a0012106200441a0016a41086a22024200370300200442003703a00141edc1c200411b200441a0016a100320044180016a41086a2002290300370300200420042903a0013703800120044180016a411020062009100402402008450d002006102e0b02402004280214450d002004280210102e0b200524000bd505040a7f027e057f017e230041e0006b220224002002410036023820014110200241386a1008210302400240024002400240024002400240024020022802382204417f470d00200041003602000c010b2002200436021420022003360210200241086a200241106a103120022802080d072002280214220541306e220641306c2201417f4c0d01200228020c21070240024020010d00410821080c010b200110292208450d030b02402007450d004100210903402005220a4110490d05200941016a210b20022002280210220541106a360210200541086a290000210c2005290000210d41002101200241003a0058200a41706a210e03400240200e2001470d0020024100360214200141ff0171450d0a200241003a00580c0a0b200241386a20016a200520016a220f41106a2d00003a00002002200f41116a3602102002200141016a220f3a0058200f2101200f4120470d000b200241186a41186a2210200241386a41186a290300370300200241186a41106a2211200241386a41106a290300370300200241186a41086a2212200241386a41086a29030037030020022002290338370318024020062009470d0020094101742201200b200b2001491b2206ad42307e2213422088a70d082013a722014100480d080240024020090d002001102921080c010b2008200941306c2001102a21080b2008450d070b200e200f6b21052008200941306c6a2201200c3703082001200d37030020012002290318370310200141186a2012290300370300200141206a2011290300370300200141286a2010290300370300200b2109200b2007470d000b2002200a200f6b41706a3602140b2008450d072000200636020420002008360200200041086a20073602002004450d002003102e0b200241e0006a24000f0b1032000b20014108102c000b2002200a3602140c020b20014108102c000b102d000b2006450d002008102e0b41eff0c2004133200241386a4184f4c2001053000be009010d7f23004190016b22022400200241086a2001410676220310c80102400240024002400240200228021022042001413f7122014d0d002002280208200141216c6a220141003a000020012002290028370001200141096a200241286a41086a2205290000370000200141116a200241286a41106a2206290000370000200141196a200241286a41186a22072900003700002005200241086a41086a280200360200200220022903083703282003200241286a10e201200241e4d9c5004112107d2002280200210120022802042103200542003703002002420037032841e4d9c5004112200241286a1003200241f0006a41086a220820052903003703002002200229032837037020022003417f6a417f20011b360228200241f0006a4110200241286a410410042007200041186a22092900003703002006200041106a220a2900003703002005200041086a220b2900003703002002410036024820022000290000370328200241186a200241286a10c90102402002280220450d00410121030340200720092900003703002006200a2900003703002005200b2900003703002002200029000037032820022003417f6a360248411310292201450d03200141002900ddfa403700002001410f6a41002800ecfa40360000200141086a41002900e5fa4037000020024293808080b00237027420022001360270200241286a200241f0006a104a2002280248210c0240024020022802742204200228027822016b4104490d00200228027021040c010b200141046a220d2001490d0620044101742201200d200d2001491b22014100480d060240024020040d002001102921040c010b200228027020042001102a21040b2004450d052002200136027420022004360270200228027821010b2002200141046a360278200420016a200c360000200228027421042002280278210c20022802702101200241f0006a41186a220d4200370300200241f0006a41106a220e420037030020084200370300200242003703702001200c200241f0006a1000200241d0006a41186a200d290300370300200241d0006a41106a200e290300370300200241d0006a41086a200829030037030020022002290370370350200241d0006a4120100602402004450d002001102e0b0240200228021c450d002002280218102e0b200720092900003703002006200a2900003703002005200b2900003703002002200029000037032820022003360248200341016a2103200241186a200241286a10c90120022802200d000b0b0240200228021c450d002002280218102e0b411310292201450d0420014100290086fa403700002001410f6a4100280095fa40360000200141086a410029008efa4037000020024293808080b00237022c200220013602282000200241286a104a200228022c21032002280230210420022802282101200241f0006a41186a22004200370300200241f0006a41106a22054200370300200241f0006a41086a220642003703002002420037037020012004200241f0006a1000200241d0006a41186a2000290300370300200241d0006a41106a2005290300370300200241d0006a41086a200629030037030020022002290370370350200241d0006a4120100602402003450d002001102e0b20024190016a24000f0b41e4f9c000200120041038000b41134101102c000b20014101102c000b102d000b41134101102c000b8b0201047f230041c0006b2202240002400240410e10292203450d00200341066a41002900f6fa40370000200341002900f0fa403700002003410e411c102a2203450d012003200036000e200241206a41186a22004200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034112200241206a1000200241186a2000290300370300200241106a2004290300370300200241086a2005290300370300200220022903203703002002412036022420022002360220200128020022002001280208200241206a10bf012003102e0240200141046a280200450d002000102e0b200241c0006a24000f0b410e4101102c000b411c4101102c000ba108010a7f230041a0016b2202240041002103024020012802102204450d0020012802082205200128020c460d00200128021421062001200541246a3602082002413c6a41026a2207200541036a2d00003a0000200241206a41086a2208200541146a290000370300200241206a410d6a2209200541196a290000370000200220052f00013b013c20022005410c6a29000037032020052d0000220a4102460d00200541086a280000210b200541046a280000210520012004417f6a360210200241026a20072d00003a0000200241e0006a41086a2008290300370300200241e0006a410d6a2009290000370000200220022f013c3b010020022002290320370360024002400240200a4101460d002002419c016a41026a200241026a2d00003a000020024180016a41086a200241e0006a41086a29030037030020024180016a410d6a200241e0006a410d6a290000370000200220022f01003b019c0120022002290360370380010c010b200241c0006a200541067610bb01200228024021040240024020022802482005413f7122014b0d00410021010c010b2002419c016a41026a200420014105746a220141026a2d00003a000020024188016a200141136a2900003703002002418d016a200141186a290000370000200220012f00003b019c012002200129000b370380012001280007210b20012800032105410121010b02402002280244450d002004102e0b20010d00410121014115210b41ccc4c20021050c010b200241fc006a41026a2002419c016a41026a2d00003a0000200241e0006a41086a20024180016a41086a290300370300200241e0006a410d6a20024180016a410d6a290000370000200220022f019c013b017c2002200229038001370360410021010b200241dc006a41026a2204200241fc006a41026a2d00003a0000200241c0006a41086a2207200241e0006a41086a290300370300200241c0006a41106a200241e0006a41106a290300370300200220022f017c3b015c200220022903603703400240024020010d002002419c016a41026a20042d00003a000020024180016a41086a200729030037030020024180016a410d6a200241c0006a410d6a290000370000200220022f015c3b019c012002200229034037038001410121010c010b2006200b36020420062005360200410021010b2002411c6a41026a22042002419c016a41026a2d00003a0000200241086a220720024180016a41086a2903003703002002410d6a220820024180016a410d6a290000370000200220022f019c013b011c20022002290380013703002001450d00200020022f011c3b0001200041086a200b360000200041046a20053600002000410c6a2002290300370000200041036a20042d00003a0000200041146a2007290300370000200041196a2008290000370000410121030b200020033a0000200241a0016a24000ba70605057f017e067f017e027f23004190026b22022400200241086a200110310240024002400240024020022802080d00200228020c210320024200370214200241e08dc00036021002402003450d00200241b0016a4102722104200241106a41086a2105410021060340200241286a2001107e02400240024020022d00284101460d002002290029210720022001103120022802000d00200128020420022802042208490d002008417f4c0d07024002400240024020080d00410121090c010b200810342209450d0120012802042008490d0220092001280200200810f6041a2001280204220a2008490d0b2001200a20086b3602042001200128020020086a3602000b200220073703202002280210220b41e08dc000460d032002280214210c0c040b20084101102c000b2009102e0b200228021821082002280214210a2002280210210d20004100360200200d200a200810e5010c050b2004410041da0010f5041a200241286a410041840110f5041a41e4011029220b450d074100210c200b4100360200200b41046a200241b0016a41dc0010f6041a200b41e0006a200241286a41840110f6041a200241003602142002200b3602100b200641016a21062008ad220e422086200e84210e024002400340200b41086a210a200b2f0106220f41037421084100210d024003402008450d01200241206a200a410810f8042210450d03200841786a2108200d41016a210d200a41086a210a2010417f4a0d000b200d417f6a210f0b0240200c450d00200c417f6a210c200b200f4102746a41e4016a280200210b0c010b0b2002200737023c200220053602382002200f3602342002200b36022c200241003602282002200241106a3602302002200e3702b401200220093602b001200241286a200241b0016a10e6010c010b200b200d410c6c6a220841e4006a220a280200210d200a200e370200200841e0006a220a2802002108200a20093602002008450d00200d450d002008102e0b20062003470d000b0b20022903102107200041086a2002280218360200200020073702000c010b200041003602000b20024190026a24000f0b1032000b2008200a1035000b41e4014104102c000bd90303027f017e027f02402001450d00034020002802e40121002001417f6a22010d000b0b02402002450d004100210341002101034002400240200120002f01064f0d0020002001410c6c6a220441e4006a2902002105200441e0006a2802002104200141016a21010c010b02400240200028020022010d002003ad210541002106410021010c010b20003301044220862003ad842105410121060b2000102e2005a72103024002402005422088a7220720012f01064f0d00200121040c010b034002400240200128020022040d002003ad2105410021040c010b200641016a210620013301044220862003ad8421050b2001102e2005a72103200421012005422088a7220720042f01064f0d000b0b200741027420046a41e8016a280200210020042007410c6c6a220141e4006a2902002105200141e0006a280200210402402006417f6a2201450d00034020002802e40121002001417f6a22010d000b0b410021010b2004450d012002417f6a210202402005a7450d002004102e0b20020d000b0b0240200041e08dc000460d00200028020021012000102e2001450d00200128020021042001102e2004450d00024020042802002201450d0003402004102e2001210420012802002200210120000d000b0b2004102e0b0be71207027f017e057f027e017f017e0a7f230041b0036b2202240020002802102203200328020041016a36020020002902142104200028020c2103200028020821052000280200210620002802042100200241f0016a41086a2207200141086a280200360200200220012902003703f001024002400240024020002f01062201410b490d00200241d0026a410272410041da0010f5041a200241386a410041840110f5041a0240024041e40110292208450d0020084100360200200841046a200241d0026a41dc0010f6041a200841e0006a200241386a41840110f6042107200241386a41086a2209200041b0016a280200360200200220002902a8013703382000413c6a330000210a2000413e6a310000210b20002d003f210c2000350038210d200841086a200041c0006a20002f010641796a220141037410f604210e2007200041b4016a2001410c6c10f6042107200041063b0106200820013b0106200241d0026a41086a2009280200360200200220022903383703d002200d200a200b4210868442208684210a0240024020034107490d002003410374200e6a41506a200e200341796a22094103746a220e200141ffff037120096b41037410f7041a200e20043700002003410c6c20076a220341b87f6a200341ac7f6a2203200841066a22012f010020096b410c6c10f7041a200341086a200241f0016a41086a280200360200200320022903f0013702000c010b200041086a20034103746a220741086a2007200041066a22012f010020036b41037410f7041a20072004370000200041e0006a2003410c6c6a2207410c6a200720012f010020036b410c6c10f7041a200741086a200241f0016a41086a280200360200200720022903f0013702000b200120012f010041016a3b0100200241286a41086a220f200241d0026a41086a22102802002203360200200241086a221120033602002002200c3a0017200220022903d00222043703282002200a3e02102002200a4230883c00162002200a4220883d011420022004370300200229031021042000280200220c450d0320002f01042112200241d0026a410272211303402002200641016a22063602202002200c360224200f201128020036020020022002290300370328201241ffff03712109024002400240200c2f01062200410b490d002013410041da0010f5041a200241f0016a200241d0026a41dc0010f6041a200241386a410041b40110f5041a41940210292207450d0520074100360200200741046a200241f0016a41dc0010f6041a200741e0006a200241386a41b40110f6042103200c41386a290000210a200241386a41086a2214200c41b0016a2802003602002002200c41a8016a290200370338200741086a200c41c0006a200c2f0106220141796a220041037410f60421152003200c41b4016a2000410c6c10f6042116200741e4016a200c4180026a2001417a6a220e41027410f6042117200c41063b0106200720003b01060240200e450d00410021002017210303402003280200220120003b010420012007360200200341046a2103200e200041016a2200470d000b0b20102014280200220036020020022002290338220b3703d002201420003602002002200b370338201241ffff037122034107490d0120152009417a6a22034103746a2015200941796a22004103746a220120072f010620006b41037410f7041a200120043700002009410c6c20166a220141b87f6a200141ac7f6a220120072f0106220e20006b410c6c10f7041a200141086a200f280200360200200120022903283702002007200e41016a22013b01062009410274221220176a416c6a201720034102746a220e200141ffff0371220920036b41027410f7041a200e200836020020092003490d02200720126a41cc016a2103034020032802002201200041016a22003b010420012007360200200341046a210320002009490d000c030b0b200c41086a2201200941016a22034103746a200120094103746a2201200020096b220741037410f7041a20012004370000200c2009410c6c6a220141ec006a200141e0006a220e2007410c6c10f7041a200141e8006a200241286a41086a280200360200200e2002290328370200200c200041016a22003b01062009410274200c41e4016a22016a41086a200120034102746a2201200041ffff0371220720036b41027410f7041a20012008360200201241ffff037120074f0d07200c2003417f6a22004102746a41e8016a2103034020032802002201200041016a22003b01042001200c360200200341046a210320002007490d000c080b0b200c41086a2200200941016a220e4103746a200020094103746a2200200c2f0106220120096b221241037410f7041a20002004370000200c41e0006a2009410c6c6a2200410c6a20002012410c6c10f7041a200041086a200f28020036020020002002290328370200200c200141016a22003b010620094102742217200c41e4016a22016a41086a2001200e4102746a2212200041ffff03712201200e6b41027410f7041a20122008360200200320014f0d00200c20176a41e8016a2100034020002802002203200941016a22093b01042003200c360200200041046a210020012009470d000b0b200241106a41086a2014280200220036020020112000360200200220022903382204370310200220043703000240200c28020022000d0020072108200a21040c050b200c2f010421122000210c200a2104200721080c000b0b41e4014104102c000b4194024104102c000b200020034103746a220941106a200941086a2209200120036b41037410f7041a2009200437000020002003410c6c6a220141ec006a200141e0006a220920002f010620036b410c6c10f7041a200141e8006a2007280200360200200920022903f001370200200020002f010641016a3b01060c010b200241d0026a410272410041da0010f5041a200241f0016a200241d0026a41dc0010f6041a200241386a410041b40110f5041a41940210292200450d0120004100360200200041046a200241f0016a41dc0010f6041a200041e0006a200241386a41b40110f60421012000200528020022033602e401200520003602002005200528020441016a360204200341003b010420032000360200200120002f01062203410c6c6a22012002290300370200200020034103746a41086a2004370000200141086a200241086a280200360200200041e4016a200341016a22034102746a2008360200200020033b0106200820033b0104200820003602000b200241b0036a24000f0b4194024104102c000bc70102037f027e230041306b220324000240411410292204450d00200441002900d88c40370000200441106a41002800e88c40360000200441086a41002900e08c4037000020034294808080c002370224200320043602202002200341206a104a20032802242104200341086a200328022022052003280228106e200341086a41106a2903004200200328020822021b21062003290310420020021b210702402004450d002005102e0b2000200737030020002006370308200341306a24000f0b41144101102c000bef0101057f230041c0006b220524000240024020030d00200041003602000c010b2003280208210620032802002103200541206a41186a22074200370300200541206a41106a22084200370300200541206a41086a220942003703002005420037032020044120200541206a1000200541186a2007290300370300200541106a2008290300370300200541086a200929030037030020052005290320370300200541003602202003200620054120200541206a10012104024020052802202203417f460d002000200336020420002004360200200041086a20033602000c010b200041003602000b200541c0006a24000baf0201027f23004190016b220324002003200210af010240024020032d000022024102470d00200041003a00000c010b200341e0006a200341286a290300370300200341e8006a200341306a290300370300200341d8006a41186a200341386a290300370300200341d8006a41206a200341c0006a290300370300200341d8006a41286a200341c8006a290300370300200341d8006a41306a200341d0006a2802003602002003200341206a29030037035802402002450d00200041003a00000c010b2003411c6a2802002102200341186a28020021042000200329026c370001200041013a0000200041196a20034184016a290200370000200041116a200341fc006a290200370000200041096a200341d8006a411c6a2902003700002002450d002004102e0b20034190016a24000b970201067f230041c0006b220224000240411710292203450d00200341002900b0a5433700002003410f6a41002900bfa543370000200341086a41002900b8a54337000020024297808080f002370224200220033602202001200241206a104a200228022421012002280228210420022802202103200241206a41186a22054200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020032004200241206a1000200241186a2005290300370300200241106a2006290300370300200241086a2007290300370300200220022903203703002002412041c8ecc500410041001005210402402001450d002003102e0b200241c0006a24002004417f470f0b41174101102c000b870102017f037e230041e0006b22032400200341086a200210af010240024020032d000822024102470d00420021040c010b2002410173ad2104200341186a2903002105200341106a290300210620020d00200341246a280200450d00200341206a280200102e0b2000200637030820002004370300200041106a2005370300200341e0006a24000bb6220a057f047e0c7f047e027f027e037f027e0b7f017e23004190056b22022400200128020821032001280200210402400240200128020422050d00200421010c010b2005210620042101034020012802880b21012006417f6a22060d000b0340200420042f01064102746a41880b6a28020021042005417f6a22050d000b0b2002418c016a20042f0106360200200241f0006a41186a410036020020024184016a20043602002002200336029001200241003602800142002107200242003703782002200136027420024100360270200241d8016a200241f0006a10ed010240024020022903f80122084202520d00420021094200210a0c010b2002418c026a210b200241d8016a412c6a210c200241d8016a410472210d200241d8016a41086a2103200241b8036a412c6a210e200241b5026a210f200241a0026a211020024188026a21114187a5c30041ffa4c3006b20024188046a6b20024188046a41206a6a410f6a211242002107420021094200210a0340200241b8016a41086a22052003290300370300200241b8016a41106a2206200241d8016a41106a2204290300370300200241b8016a41186a2213200241d8016a41186a220129030037030020024198016a41086a2214200f41086a29000037030020024198016a41106a2215200f41106a29000037030020024198016a41186a2216200f41186a290000370300200220022903d8013703b8012002200f2900003703980120102903002117201129030021182002290398022119200229038002211a20022d00b402211b20022802b002211c20022903a802211d200229039002211e200241d8026a41186a221f2013290300370300200241d8026a41106a22202006290300370300200241d8026a41086a22062005290300370300200220022903b8013703d802200241f8026a41186a22052016290300370300200241f8026a41106a22132015290300370300200241f8026a41086a2216201429030037030020022002290398013703f802024002400240024002400240024002400240024002400240024020084201520d00200241d8016a200241d8026a201a2018106f20022d00f0012114200241d8006a200a2007200920022903d80120022903e001200429030010a501200241d8006a41106a2903002109200229036021072002290358210a20140d010b0240201b41ff017122154101460d00201e4201510d00201c450d090b200241d8016a200241d8026a10af010240024020022d00d8012214417f6a221b41014b0d000240201b0e020002000b20140d0220022802f401450d0220022802f001102e0c020b20024198036a41086a2214200b41086a29020037030020024198036a41106a221b200b41106a29020037030020024198036a41186a2221200b41186a2902003703002002200b290200370398032004290300212220022903e00121232002280288022124200228028002212520022802fc01212620022802f801212720022802f401212820022802f001212920022802ac02212a0240200228028402222b4102470d0020150d030c020b2027417f4c0d050240024020270d00410121060c010b202710292206450d0520062029202710f6041a0b200e200229039803370200200e41086a2014290300370200200e41106a201b290300370200200e41186a2021290300370200200220233703b803200220243602e003200220253602d803200220263602d403200220273602d003200220273602cc03200220063602c803200220223703c0032002202b410146222c3602dc032027212d2027211b2025212e202321182022212f202621140c030b024020140d0020022802f401450d0020022802f001102e0b4102212b20150d010b201da7210402400240201d422088a722050d00200421010c010b2005210620042101034020012802ec0321012006417f6a22060d000b0340200420042f01064102746a41ec036a28020021042005417f6a22050d000b0b2002201c3602f801200241003602f001200241003602e801200242003703e001200220013602dc01200241003602d801200220043602ec01200220042f01063602f401200241d8016a10ee010c0a0b200241c8006a4197a1c5004117108101200228024821142002290350210820034200370300200242003703d8014197a1c5004117200241d8016a100320024188046a41086a221b2003290300370300200220022903d801370388042002200842017c420120141b22083703d80120024188046a4110200241d8016a41081004412010292214450d05201420022903d802370000201441186a201f290300370000201441106a2020290300370000201441086a20062903003700002014412041c000102a2214450d0420142008370020200142003703002004420037030020034200370300200242003703d80120144128200241d8016a100020024188046a41186a200129030037030020024188046a41106a2004290300370300201b2003290300370300200220022903d80137038804413710292206450d03200642bac6a1cbc68dd9aff300370000200642f4dec98bf6ac999de400370008200641e5cc85ab073600102006413a3a0016200641ece8013b00142006200229038804370017200620022f0190043b001f2006200228019204360021200620022f0196043b0025200620022d0098043a0027200620022d0099043a0028200620022d009a043a0029200620022d009b043a002a200620022d009c043a002b200620022d009d043a002c200620022d009e043a002d200620022d009f043a002e200620022d00a0043a002f200620022d00a1043a0030200620022d00a2043a0031200620022d00a3043a0032200620022d00a4043a0033200620022d00a5043a0034200620022d00a6043a0035200620022d00a7043a00362014102e200241c0006a41b0f3c200410d107d2002280244211b2002280240211f200e20022903f80237000041082114200e41086a200241f8026a41086a290300370000200e41106a2013290300370000200e41186a2005290300370000427f21182002427f3703c0032002427f3703b803200241083602d403200220123602d0034137212d200241373602cc03200220063602c8034100212c200241003602dc032002201b4100201f1b222e3602d8032012211b427f212f0b0240201e4201520d00200220193703b803200220173703c003201921182017212f0b02402015450d00200e20022903f802370000200e41186a2005290300370000200e41106a2013290300370000200e41086a20162903003700000b0240201c450d00200241386a41b0f3c200410d107d4101212c200241013602dc032002200228023c410020022802381b3602e0030b201da7210502400240201d422088a722150d00200521130c010b2015211620052113034020132802ec0321132016417f6a22160d000b0340200520052f01064102746a41ec036a28020021052015417f6a22150d000b0b20052f010621152002201c3602a804200220153602a404200241003602a0042002200536029c04200241003602980420024200370390042002201336028c042002410036028804200241d8016a20024188046a10ef0120022802d8014101470d070340200241b0046a41186a200d41186a290200221d370300200241b0046a41106a200d41106a2902002208370300200241b0046a41086a200d41086a290200221e3703002002200d290200221a3703b00420022802fc01210520022802800221202002280284022113200241d0046a41186a201d370300200241d0046a41106a2008370300200241d0046a41086a201e3703002002201a3703d004200142003703002004420037030020034200370300200242003703d801200241d0046a4120200241d8016a1000200241f0046a41186a22162001290300370300200241f0046a41106a221c2004290300370300200241f0046a41086a221f2003290300370300200220022903d8013703f004200241003602d8012006201b200241f0046a4120200241d8016a10012121024020022802d8012215417f460d00201420156b21142015450d002021102e0b024002402005450d00200142003703002004420037030020034200370300200242003703d801200241d0046a4120200241d8016a100020162001290300370300201c2004290300370300201f2003290300370300200220022903d8013703f0042006201b200241f0046a412020052013100b201420136a21142020450d012005102e0c010b200142003703002004420037030020034200370300200242003703d801200241d0046a4120200241d8016a100020162001290300370300201c2004290300370300201f2003290300370300200220022903d8013703f0042006201b200241f0046a412010020b200241d8016a20024188046a10ef0120022802d8014101470d070c000b0b20274101102c000b1032000b41374101102c000b41c0004101102c000b41204101102c000b201da7210402400240201d422088a722050d00200421010c010b2005210620042101034020012802ec0321012006417f6a22060d000b0340200420042f01064102746a41ec036a28020021042005417f6a22050d000b0b200241003602f801200241003602f001200241003602e801200242003703e001200220013602dc01200241003602d801200220043602ec01200220042f01063602f401200241d8016a10ee010c020b200220143602d4030b20024188046a10ee0120024188046a41186a220420024198036a41186a29030037030020024188046a41106a220120024198036a41106a29030037030020024188046a41086a220520024198036a41086a29030037030020022002290398033703880402400240202b4102460d00200c200229038804370200200c41086a2005290300370200200c41106a2001290300370200200c41186a2004290300370200200220233703d80120022024360280022002202b3602fc01200220253602f801200220263602f401200220283602ec01200220293602e8012002202a3602a402200220223703e001200220273602f0014101210402402027201b470d000240024020292006460d0020292006202710f8040d0220262014470d020c010b20262014470d010b200c200e412010f8040d0020232018852022202f858450450d002025202e470d00202b202c470d00202b410146202420022802e003477121040b02402028450d002029102e0b20044102460d002004450d010b2003200241b8036a41d00010f6041a200241003a00d801200241d8026a200241d8016a10f0010c010b202d450d002006102e0b200241d8016a200241f0006a10ed0120022903f80122084202520d000b0b200241f0006a105402400240200a500d00200241d8016a41086a22044200370300200242003703d80141c28cc0004116200241d8016a1003200241b8036a41086a22052004290300370300200220022903d8013703b803200241206a200241b8036a109701200241306a290300211d200229032821082002280220210120044200370300200242003703d80141c28cc0004116200241d8016a100320052004290300370300200220022903d8013703b80320024200201d420020011b221d20097d2008420020011b2208200754ad7d221e200820077d221a200856201e201d56201e201d511b22041b3703e00120024200201a20041b3703d801200241d8016a2104200241b8036a21010c010b02402007200984500d004198d8c1001058000b200241d8016a41086a22044200370300200242003703d80141c28cc0004116200241d8016a1003200241b8036a41086a22052004290300370300200220022903d8013703b803200241086a200241b8036a109701200241186a290300211d200229031021082002280208210120044200370300200242003703d80141c28cc0004116200241d8016a100320052004290300370300200220022903d8013703b8032002201d420020011b3703e00120022008420020011b3703d801200241d8016a2104200241b8036a21010b2001411020044110100420024190056a24000bf90503087f017e017f23004180026b2202240002400240024020012802202203450d0020012003417f6a36022020012802082104200128020c2203200128020422052f01064f0d01200241186a2206200520034105746a220741206a290000370300200241106a2208200741186a290000370300200241086a2209200741106a2900003703002002200741086a290000370300200241206a2005200341e0006c6a41e8026a41e00010f6041a2001200341016a36020c200120043602082001200536020420024180016a41186a200629030037030020024180016a41106a200829030037030020024180016a41086a2009290300370300200220022903003703800120024180016a41206a200241206a41e00010f6041a200020024180016a41800110f6041a0c020b200042023703200c010b2001280200210702400240200528020022030d002004ad210a410021030c010b200741016a210720053301044220862004ad84210a0b2005102e200aa7210402400240200a422088a7220620032f01064f0d00200321050c010b034002400240200328020022050d002004ad210a410021050c010b200741016a210720033301044220862004ad84210a0b2003102e200aa7210420052103200a422088a7220620052f01064f0d000b0b200241186a2208200520064105746a220341206a290000370300200241106a2209200341186a290000370300200241086a220b200341106a2900003703002002200341086a290000370300200241206a2005200641e0006c6a41e8026a41e00010f6041a200641027420056a418c0b6a280200210302402007417f6a2205450d00034020032802880b21032005417f6a22050d000b0b2001410036020c20012004360208200120033602042001410036020020024180016a41186a200829030037030020024180016a41106a200929030037030020024180016a41086a200b290300370300200220022903003703800120024180016a41206a200241206a41e00010f6041a200020024180016a41800110f6041a0b20024180026a24000bb00101037f230041306b220124002001200010ef01024020012802004101470d000340024020012802242202450d002001280228450d002002102e0b2001200010ef0120012802004101460d000b0b02402000280204220241e08dc000460d00200228020021032002102e2003450d00200328020021002003102e2000450d00024020002802002202450d0003402000102e2002210020022802002203210220030d000b0b2000102e0b200141306a24000bdd0605057f047e017f017e047f23004190016b2202240002400240024020012802202203450d0020012003417f6a36022020012802082104200128020c2203200128020422052f01064f0d01200241e0006a41186a200520034105746a220641206a2900002207370300200241e0006a41106a200641186a2900002208370300200241e0006a41086a200641106a29000022093703002002200641086a290000220a370360200241306a41086a20052003410c6c6a220641f0026a280200220b360200200641e8026a290200210c2001200341016a36020c20012004360208200120053602042002200c3703302000200a3702042000410c6a2009370200200041146a20083702002000411c6a2007370200200041246a200c3702002000412c6a200b360200200041013602000c020b200041003602000c010b2001280200210602400240200528020022030d002004ad210c410021030c010b200641016a210620053301044220862004ad84210c0b2005102e200ca7210402400240200c422088a7220b20032f01064f0d00200321050c010b034002400240200328020022050d002004ad210c410021050c010b200641016a210620033301044220862004ad84210c0b2003102e200ca7210420052103200c422088a7220b20052f01064f0d000b0b200241306a41186a220d2005200b4105746a220341206a290000370300200241306a41106a220e200341186a290000370300200241306a41086a220f200341106a2900003703002002200341086a290000370330200241d0006a41086a22102005200b410c6c6a220341f0026a2802003602002002200341e8026a290200370350200b41027420056a41f0036a280200210302402006417f6a2205450d00034020032802ec0321032005417f6a22050d000b0b2001410036020c200120043602082001200336020420014100360200200241e0006a41186a200d290300220c370300200241e0006a41106a200e2903002207370300200241e0006a41086a200f290300220837030020024188016a201028020022033602002000200229033022093702042000410c6a2008370200200041146a20073702002000411c6a200c370200200041246a2002290350220c3702002000412c6a2003360200200220093703602002200c37038001200041013602000b20024190016a24000bb80201067f230041c0006b220224000240411710292203450d00200341002900b0a5433700002003410f6a41002900bfa543370000200341086a41002900b8a54337000020024297808080f002370224200220033602202000200241206a104a200228022421002002280228210420022802202103200241206a41186a22054200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020032004200241206a1000200241186a2005290300370300200241106a2006290300370300200241086a20072903003703002002200229032037030020024120360224200220023602202001200241206a10d50302402000450d002003102e0b024020012d00000d002001411c6a280200450d00200141186a280200102e0b200241c0006a24000f0b41174101102c000bcc0202097f027e230041206b220324000240200128020041016a220441004c0d0020012004360200200141046a2105200141086a28020021060240024003402005280200220741086a210820072f0106220941057421054100210a0240024003402005450d0120022008412010f804220b450d02200541606a2105200a41016a210a200841206a2108200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200720094102746a41880b6a21050c010b0b2007200a41e0006c6a220541e8026a280200450d00200541f8026a290300210c200541f0026a290300210d0c010b200341086a20012802102002200141146a28020028021c110300200341106a290300210c200128020021042003290308210d0b20012004417f6a3602002000200c3703082000200d370300200341206a24000f0b41e3d7c1004118200341186a41fcd7c1001053000b9f0501097f230041206b22052400024002400240200128020041016a220641004c0d0020012006360200200141086a2802002107200141046a220821060340200628020022092f0106220a410574210b410021064100210c0240024002400340200b2006460d0102402002200920066a41086a412010f804220d0d00410021060c030b200641206a2106200c41016a210c200d417f4a0d000b200c417f6a210a0b20070d014101210641002107200a210c0b200541186a200c360200200541146a2008360200200541086a41086a20093602002005200736020c2005200636020820060d032009200c41e0006c6a2206419c036a280200210720064198036a2208210602400340200628020022092f0106220a410574210b410021064100210c02400240024002400340200b2006460d0102402004200920066a41086a412010f804220d0d00410021060c030b200641206a2106200c41016a210c200d417f4a0d000b200c417f6a210a0b20070d014101210641002107200a210c0b200541186a200c360200200541086a410c6a2008360200200541106a20093602002005200736020c2005200636020820060d0702400240200941e8026a2206200c410c6c6a280200220d0d004100210c0c010b2006200c410c6c6a2802082206417f4c0d02024020060d004101210c0c010b20061029220c450d04200c200d200610f6041a0b200020063602042000200c360200200041086a20063602000c080b2007417f6a21072009200a4102746a41ec036a21060c010b0b1032000b20064101102c000b2007417f6a21072009200a4102746a41880b6a21060c000b0b41e3d7c1004118200541086a41fcd7c1001053000b20002001280210200220032004200141146a28020028020c1105000b20012001280200417f6a360200200541206a24000b930301097f230041206b220324000240200128020041016a220441004c0d0020012004360200200141046a2105200141086a280200210602400240024003402005280200220741086a210820072f0106220941057421054100210a0240024003402005450d0120022008412010f804220b450d02200541606a2105200a41016a210a200841206a2108200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200720094102746a41880b6a21050c010b0b200341086a22082007200a41e0006c6a220541ad036a290000370300200341106a220a200541b5036a290000370300200341186a220b200541bd036a2900003703002003200541a5036a290000370300200541a4036a2d00004101460d010b200020012802102002200141146a280200280210110300200128020021040c010b200041013a000020002003290300370001200041096a2008290300370000200041116a200a290300370000200041196a200b2903003700000b20012004417f6a360200200341206a24000f0b41e3d7c1004118200341fcd7c1001053000bdd0202097f037e230041206b220324000240200128020041016a220441004c0d0020012004360200200141046a2105200141086a28020021060240024003402005280200220741086a210820072f0106220941057421054100210a0240024003402005450d0120022008412010f804220b450d02200541606a2105200a41016a210a200841206a2108200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200720094102746a41880b6a21050c010b0b2007200a41e0006c6a22054180036a290300220ca7450d0020054190036a290300210d20054188036a290300210e0c010b200320012802102002200141146a280200280214110300200341106a290300210d200128020021042003290308210e2003290300210c0b20012004417f6a360200200041106a200d3703002000200e3703082000200c370300200341206a24000f0b41e3d7c1004118200341186a41fcd7c1001053000bc31e03087f037e127f23004180076b22042400200441e0006a41186a200241186a290000370300200441e0006a41106a200241106a290000370300200441e0006a41086a200241086a290000370300200420022900003703600240024002400240024002400240024002402001280200220541e08dc000460d00200128020421060c010b41002106200441e8026a410041e00210f5041a200441c0016a410041840110f5041a41ec0310292205450d01200541003b010620054100360200200541086a200441e8026a41e00210f6041a200541e8026a200441c0016a41840110f6041a20014100360204200120053602000b02400340200541086a2107200541066a210820052f0106220941057421024100210a0240024003402002450d01200441e0006a2007412010f804220b450d02200241606a2102200a41016a210a200741206a2107200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200520094102746a41ec036a28020021050c010b0b200441e8026a41086a22022005200a410c6c6a220741f0026a220a2802003602002004200741e8026a22072902003703e80220072003290200370200200a200341086a280200360200200441c0016a41086a20022802002202360200200420042903e802220c3703c0012000410c6a20023602002000200c370204200041013602000c060b200441086a41186a220b200441e0006a41186a2202290300370300200441086a41106a200441e0006a41106a2207290300220c370300200441086a41086a200441e0006a41086a220a290300220d37030020042004290360220e3703082001200128020841016a3602082007200c370300200a200d3703002002200b2903003703002004200e370360200441d8026a41086a2206200341086a280200360200200420032902003703d802024020082f01002203410b490d00200441e8026a410041e00210f5041a200441c0016a410041840110f5041a41ec031029220f450d02200f41003b0106200f4100360200200f41086a200441e8026a41e00210f6042107200f41e8026a200441c0016a41840110f604210a200441e8026a41086a220b200541b8036a280200360200200420052900db013703a8012004200541e0016a2900003700ad01200420052902b0033703e802200420052f00c8013b01bc012004200541ca016a2d00003a00be01200541cb016a2800002110200541cf016a2800002111200541d3016a2800002112200541d7016a28000021132007200541e8016a20052f010641796a220241057410f6042107200a200541bc036a2002410c6c10f604210a200541063b0106200f20023b0106200420042f01bc013b01a401200420042d00be013a00a601200420042903a8013703c001200420042900ad013700c501200441286a41086a200b280200360200200420042903e8023703280240024020094107490d00200941057420076a41c07e6a2007200941796a220b4105746a2207200241ffff0371200b6b41057410f7041a200741186a200441e0006a41186a290300370000200741106a200441e0006a41106a290300370000200741086a200441e0006a41086a290300370000200720042903603700002009410c6c200a6a220241b87f6a200241ac7f6a2202200f41066a22082f0100200b6b410c6c10f7041a200241086a200441d8026a41086a280200360200200220042903d8023702000c010b200541086a20094105746a220241206a200220082f010020096b41057410f7041a200241186a200441e0006a41186a290300370000200241106a200441e0006a41106a290300370000200241086a200441e0006a41086a29030037000020022004290360370000200541e8026a2009410c6c6a2202410c6a200220082f010020096b410c6c10f7041a200241086a200441d8026a41086a280200360200200220042903d8023702000b200820082f010041016a3b010020044198016a41026a220220042d00a6013a0000200441c8026a41086a2214200441286a41086a280200360200200420042f01a4013b019801200420042903c001370350200420042900c501370055200420042903283703c8022004413c6a41026a221520022d00003a0000200420042f0198013b013c2004200429005537002d20042004290350370328200441c0006a41086a22162014280200360200200420042903c80237034020052802002206450d0420052f01042103200441e8026a4102722117034020044194016a41026a221820152d00003a0000200420042f013c3b019401200420042903283703602004200429002d37006520044198016a41086a221920162802003602002004200429034037039801200341ffff0371210502400240024020062f01062202410b490d002017410041960410f5041a419c041029220b450d07200b4100360200200b41046a200441e8026a41980410f6041a200420062f00c8013b01bc012004200641ca016a2d00003a00be012004200641db016a2900003703a8012004200641e0016a2900003700ad01200641cb016a280000211a200641cf016a280000211b200641d3016a280000211c200641d7016a280000211d200441e8026a41086a221e200641b8036a2802003602002004200641b0036a2902003703e802200b41086a200641e8016a20062f0106220741796a220241057410f604211f200b41e8026a200641bc036a2002410c6c10f6042120200b41ec036a20064188046a2007417a6a220941027410f6042108200641063b0106200b20023b010602402009450d00410021022008210703402007280200220a20023b0104200a200b360200200741046a21072009200241016a2202470d000b0b200441d8026a41086a2202201e280200360200200420042d00be0122073a00a601200420042f01bc01220a3b01a401200420042903a8013703c001200420042900ad013700c501200420042903e8023703d802200441c4026a41026a220920073a00002004200a3b01c402200420042903c0013703e802200420042900c5013700ed0220142002280200360200200420042903d8023703c802200341ffff037122074107490d01201f2005417a6a220a4105746a201f200541796a22024105746a2207200b2f010620026b41057410f7041a200741186a20042900653700002007201336000f2007201236000b2007201136000720072010360003200741026a20182d00003a0000200720042f0194013b0000200720042903603700132005410c6c20206a220741b87f6a200741ac7f6a2207200b2f0106220320026b410c6c10f7041a200741086a20192802003602002007200429039801370200200b200341016a22073b01062005410274221020086a416c6a2008200a4102746a2203200741ffff03712205200a6b41027410f7041a2003200f3602002005200a490d02200b20106a41d4036a210703402007280200220a200241016a22023b0104200a200b360200200741046a210720022005490d000c030b0b200641086a2207200541016a220a4105746a200720054105746a2207200220056b41057410f7041a200741186a20042900653700002007201336000f2007201236000b2007201136000720072010360003200741026a20044194016a41026a2d00003a0000200720042f0194013b00002007200429036037001320062005410c6c6a220241f4026a200241e8026a220720062f0106220b20056b410c6c10f7041a200241f0026a20044198016a41086a28020036020020072004290398013702002006200b41016a22023b01062005410274200641ec036a22076a41086a2007200a4102746a2207200241ffff0371220b200a6b41027410f7041a2007200f360200200341ffff0371200b4f0d082006200a417f6a22024102746a41f0036a210703402007280200220a200241016a22023b0104200a2006360200200741046a21072002200b490d000c090b0b200641086a2202200541016a22034105746a200220054105746a220220062f010620056b41057410f7041a200241186a20042900653700002002201336000f2002201236000b2002201136000720022010360003200241026a20182d00003a0000200220042f0194013b000020022004290360370013200641e8026a2005410c6c6a2202410c6a200220062f0106220a20056b410c6c10f7041a200241086a201928020036020020022004290398013702002006200a41016a22023b010620054102742210200641ec036a220a6a41086a200a20034102746a2208200241ffff0371220a20036b41027410f7041a2008200f3602002007200a4f0d00200620106a41f0036a2102034020022802002207200541016a22053b010420072006360200200241046a2102200a2005470d000b0b20044190016a41026a220220092d00003a000020044180016a41086a22072014280200360200200420042f01c402220a3b019001200420042903e802370350200420042900ed02370055200420042903c80237038001201520022d00003a00002004200a3b013c2004200429005537002d200420042903503703282016200728020036020020042004290380013703400240200628020022020d00201a2110201d2113201c2112201b2111200b210f0c060b20062f01042103201a2110201d2113201c2112201b211120022106200b210f0c000b0b200520094105746a220b41286a200b41086a2201200320096b41057410f7041a200b41206a2002290300370000200b41186a2007290300370000200b41106a200a2903003700002001200429036037000020052009410c6c6a220241f4026a200241e8026a220720052f010620096b410c6c10f7041a200241f0026a2006280200360200200720042903d802370200200520052f010641016a3b01060c040b41ec034104102c000b41ec034104102c000b419c044104102c000b200441e8026a410272410041960410f5041a419c0410292202450d0220024100360200200241046a200441e8026a41980410f6041a2002200128020022073602ec03200120023602002001200128020441016a360204200741003b010420072002360200200220022f0106220a4105746a220741086a20042f013c3b00002007410a6a2004413c6a41026a2d00003a0000200741176a2013360000200741136a20123600002007410f6a20113600002007410b6a20103600002007411b6a2004290328370000200741206a200429002d3700002002200a410c6c6a220741f0026a200441c0006a41086a280200360200200741e8026a2004290340370200200241ec036a200a41016a22074102746a200f360200200220073b0106200f20073b0104200f20023602000b200041003602000b20044180076a24000f0b419c044104102c000bd40201057f230041c0006b22022400024002400240411b10292203450d00200341176a41002800a7d945360000200341106a41002900a0d945370000200341086a4100290098d94537000020034100290090d9453700002003411b4136102a2204450d012004200136001b200241206a41186a22034200370300200241206a41106a22014200370300200241206a41086a22054200370300200242003703202004411f200241206a1000200241186a22062003290300370300200241106a2001290300370300200241086a200529030037030020022002290320370300412010292203450d0220032002290300370000200042a0808080800437020420002003360200200341186a2006290300370000200341106a200241106a290300370000200341086a200241086a2903003700002004102e200241c0006a24000f0b411b4101102c000b41364101102c000b41204101102c000bad6d04147f027e0d7f027e230041c0046b22042400200441b0036a20012002200310b603200441b0036a41086a280200210520042802b40321060240024020042802b0034101470d002000200636020420004101360200200041086a20053602000c010b200441c4036a2802002207412c6c2108200441c8036a2802002109200441c0036a280200210a200441bc036a280200210b4100210c4100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004102470d000b200441d8006a200b200d6a41586a10b7032004280258210c200428025c21010b4100210e20014100200c1b210f2007412c6c2108200c41c8ecc500200c1b21104100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004108470d000b200441d0006a200b200d6a41586a10b7032004280250210e200428025421010b4100211120014100200e1b21122007412c6c2108200e41c8ecc500200e1b210c4100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004104470d000b200441c8006a200b200d6a41586a10b70320042802482111200428024c21010b4100210e2001410020111b21132007412c6c2108201141c8ecc50020111b21114100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004103470d000b200441c0006a200b200d6a41586a10b7032004280240210e200428024421010b41002102024020014100200e1b2201450d00200141286c2108200e41c8ecc500200e1b41186a2101410021020340200220012d0000456a2102200141286a2101200841586a22080d000b0b0240024020120d00411e2101200041b7a4c5003602040c010b200c201241146c6a2112410021144100211502400240034041d5a4c500210841382101200c41086a280200417c6a220e41024b0d01200c280200210d024002400240200e0e03000401000b41012115200d41ada4c500460d01200d28000041e3c2b1e306460d010c030b41012114200d41b1a4c500460d00200d41b1a4c500410610f8040d020b0240200c410c6a280200450d0041132101200041d3a5c5003602040c040b0240200c41106a280200220120026b220d20014d0d00412a2101200041e6a5c5003602040c040b41ada5c5002108412621012013200d4d0d012011200d4102746a220d450d01418da5c500210841202101200f200d280200220d4d0d012010200d4104746a220d450d014190a6c5002108411f2101200d2802080d01200d2d000d220d41077141044b0d010240200d0e050002020200000b200c41146a220c2012470d000b20142015714101710d01411c411e201441017122021b2101200041afa6c50041b7a4c50020021b3602040c020b200020083602040c010b2007412c6c2108410021010240034020082001460d01200b20016a21022001412c6a220d210120022d00004106470d000b200441386a200b200d6a41586a10b703200428023c450d00200041fba1c500360204411f21010c010b2007412c6c21082003280268210c410021010240034020082001460d01200b20016a21022001412c6a220d210120022d00004105470d000b200441306a200b200d6a41586a220110b7030240200428023441014d0d00411821012000419aa2c5003602040c020b200441286a200110b703200428022c450d0020042802282201450d002001280200200c4d0d0041222101200041b2a2c5003602040c010b2007412c6c2108410021010240034020082001460d01200b20016a21022001412c6a220d210120022d00004107470d000b200441206a200b200d6a41586a10b7032004280220220120042802244104746a2108034020012008460d012001450d012001410c6a2102200141106a210120022d0000410271450d000b41322101200041bea3c5003602040c010b2007412c6c2108410021010240034020082001460d01200b20016a21022001412c6a220d210120022d0000410b470d000b200b200d6a220141606a2802002202450d00200141586a280200220d200241186c6a210c0340200d220241186a210d2002280208410374210120022802002102024003402001450d01200141786a210120022d00042108200241086a21022008410271450d000b413121012000418da3c5003602040c030b200d200c470d000b0b2007412c6c2108410021010240034020082001460d01200b20016a21022001412c6a220d210120022d00004102470d000b200441186a200b200d6a41586a10b703200428021c2201450d002004280218220220014104746a211103402002450d01200241106a210e200420022d000d22083a00b0032002280200220120022802086a210c410021024100200441b0036a20084104461b210d024003400240024002400240200241ff01710e03000102000b2001200c460d014100210220012108200141016a21010c020b2001200c460d034101210220012108200141016a21010c010b200d450d0241022102200d21084100210d0b20082d0000410271450d000b41392101200041d4a2c5003602040c030b200e2102200e2011470d000b0b2007412c6c21084100210c4100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004102470d000b200441106a200b200d6a41586a10b7032004280210210c200428021421010b4100210e20014100200c1b21102007412c6c2108200c41c8ecc500200c1b21124100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004103470d000b200441086a200b200d6a41586a10b7032004280208210e200428020c21010b200e41c8ecc500200e1b220220014100200e1b41286c6a210d4100211302400240024003400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402002200d460d00412d210141ca9bc300210820022802084103470d1402402002280200220c418ac5c500460d00200c418ac5c500410310f8040d150b200241286a21114115210c41c39ac300210e4114210141b69bc300210802400240024020022d00180e040017011e000b4136210c418d9ac300210e2010200228021c22014d0d1d201220014104746a220f450d1d2002280214210c200228020c210220092d00700d01200c410b470d014138210141fe9ac3002108200241de9ec500460d16200241de9ec500410b10f804450d160c190b412f210141969cc300210820022802144106470d150240200228020c220c41879ac300460d00200c41879ac300410610f8040d160b02402013450d00411f2101200041f79bc3003602040c1e0b2002411c6a2113201121020c190b4126210141d89ac3002108200c417d6a220c41134b0d140240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200c0e14003030300e043006330b0a110113101a30300c18000b2002418dc5c500460d2f2002418dc5c500410310f804450d2f418dc5c5002002410310f8040d2f41011029220e450d1c200e41003a00000240200f2d000c41e000470d00200f2802084101470d00200f280200211441002102034020024101460d03200e20026a2108201420026a210c200241016a2102200c2d000020082d0000460d000b0b200e102e200041d89ac3003602040c370b200241bc9cc500460d0141bc9cc5002002410f10f804450d010240200241cb9cc500460d0041cb9cc5002002410f10f8040d2f0b410110292214450d1d201441003a0000200f2d000c41e000470d30200f2802084101470d30200f280200211541002102034020024101460d04201420026a210c201520026a210e200241016a2102200e2d0000200c2d0000460d000c310b0b200f2d000d2101200e102e2011210220014104460d310c330b41041029220e450d1a200e41003600000240200f2d000c41e000470d00200f2802084104470d00200f280200211441002102034020024104460d28200e20026a2108201420026a210c200241016a2102200c2d000020082d0000460d000b0b200e102e200041d89ac3003602040c340b0240200241da9cc500460d00200229000042e5f0d1fbb5ac98b6ec00520d2c0b410710292214450d1b20144100360003201441013a0002201441003b0000200f2d000c41e000470d2c200f2802084107470d2c200f280200211541002102034020024107460d03201420026a210c201520026a210e200241016a2102200e2d0000200c2d0000460d000c2d0b0b200f2d000d220c4104460d2c2014102e20112102200c41fb0171450d2e0c2a0b200241e29cc500460d0141e29cc5002002410a10f804450d01200241ec9cc500460d0241ec9cc5002002410a10f804450d020240200241f69cc500460d0041f69cc5002002410a10f8040d070b4126210c41d89ac300210e200f2d000c41e000470d30200f2802080d3020112102200f2d000d4104460d2d0c300b200f2d000d220c4104460d292014102e20112102200c41fb0171450d2c0c280b410710292214450d1820144100360003201441013a0002201441003b00000240200f2d000c41e000470d00200f2802084107470d00200f2802002115410021020340024020024107470d00200f2d000d220c4104460d022014102e20112102200c41fb0171450d2e0c2a0b201420026a210c201520026a210e200241016a2102200e2d0000200c2d0000460d000b0b2014102e200041d89ac3003602040c2f0b41021029220e450d18200e41003b00000240200f2d000c41e000470d00200f2802084102470d00200f280200211441002102034020024102460d23200e20026a2108201420026a210c200241016a2102200c2d000020082d0000460d000b0b200e102e200041d89ac3003602040c2e0b02402002418b9dc500460d00418b9dc5002002410d10f8040d260b4126210c41d89ac300210e200f2d000c41e000470d2c200f2802080d2c20112102200f2d000d4104460d290c2c0b0240200241989dc500460d0041989dc5002002410c10f8040d250b4126210c41d89ac300210e200f2d000c41e000470d2b200f2802080d2b20112102200f2d000d4104460d280c2b0b0240200241af9dc500460d0041af9dc5002002411510f8040d240b4126210c41d89ac300210e200f2d000c41e000470d2a200f2802080d2a20112102200f2d000d4104460d270c2a0b0240200241c49dc500460d0041c49dc5002002410a10f8040d230b41021029220e450d15200e41003b00000240200f2d000c41e000470d00200f2802084102470d00200f280200211441002102034020024102460d03200e20026a2108201420026a210c200241016a2102200c2d000020082d0000460d000b0b200e102e200041d89ac3003602040c2a0b0240200241ce9dc500460d0041ce9dc5002002410710f8040d220b4126210c41d89ac300210e200f2d000c41e000470d28200f2802080d2820112102200f2d000d4104460d250c280b200f2d000d2101200e102e2011210220014104460d240c260b200241d59dc500460d0141d59dc5002002411110f804450d01200241949ec500460d0641949ec5002002411110f804450d060240200241a59ec500460d0041a59ec5002002411110f8040d200b41041029220e450d17200e41003600000240200f2d000c41e000470d00200f2802084104470d00200f280200211441002102034020024104460d0a200e20026a2108201420026a210c200241016a2102200c2d000020082d0000460d000b0b200e102e200041d89ac3003602040c270b0240200241e69dc500460d0041e69dc5002002410e10f8040d1f0b41081029220e450d13200e42003700000240200f2d000c41e000470d00200f2802084108470d00200f280200211441002102034020024108460d04200e20026a2108201420026a210c200241016a2102200c2d000020082d0000460d000b0b200e102e200041d89ac3003602040c260b41021029220e450d11200e41003b00000240200f2d000c41e000470d00200f2802084102470d00200f280200211441002102034020024102460d1b200e20026a2108201420026a210c200241016a2102200c2d000020082d0000460d000b0b200e102e200041d89ac3003602040c250b200241f49dc500460d0141f49dc5002002411010f804450d01200241849ec500460d0241849ec5002002411010f804450d020240200241e99ec500460d0041e99ec5002002411010f8040d1d0b4126210c41d89ac300210e200f2d000c41e000470d23200f2802080d2320112102200f2d000d4104460d200c230b200f2d000d2101200e102e2011210220014104460d1f0c210b4126210c41d89ac300210e200f2d000c41e000470d21200f2802080d21200f2d000d22014104460d2120112102200141fb0171450d1e0c1f0b41031029220e450d0f200e41003a0002200e41003b00000240200f2d000c41e000470d00200f2802084103470d00200f280200211441002102034020024103460d18200e20026a2108201420026a210c200241016a2102200c2d000020082d0000460d000b0b200e102e200041d89ac3003602040c210b41021029220e450d0f200e41003b00000240200f2d000c41e000470d00200f2802084102470d00200f280200211441002102034020024102460d18200e20026a2108201420026a210c200241016a2102200c2d000020082d0000460d000b0b200e102e200041d89ac3003602040c200b0240200241b69ec500460d0041b69ec5002002411610f8040d180b410210292214450d10201441003b00000240200f2d000c41e000470d00200f2802084102470d00200f280200211541002102034020024102460d04201420026a210c201520026a210e200241016a2102200e2d0000200c2d0000460d000b0b2014102e0c170b200f2d000d2101200e102e2011210220014104460d1a0c1c0b0240200241cc9ec500460d0041cc9ec5002002411210f8040d160b4126210c41d89ac300210e200f2d000c41e000470d1c200f2802080d1c20112102200f2d000d4104460d190c1c0b200f2d000d21012014102e2011210220014104460d180c1a0b024020130d0041002116410021170c130b024020132802040d00200041c59cc300360204413221010c1c0b024020132802002216201341086a28020022174d0d00200041f79cc30036020441c90021010c1c0b201720032802644d0d12200041c09dc30036020441c10021010c1b0b41014101102c000b41044101102c000b41014101102c000b41074101102c000b41074101102c000b41024101102c000b41024101102c000b41024101102c000b41084101102c000b41034101102c000b41024101102c000b41044101102c000b41024101102c000b200f2d000d2101200e102e2011210220014104460d090c0b0b200f2d000d2101200e102e2011210220014104460d080c0a0b200f2d000d2101200e102e2011210220014104460d070c090b200f2d000d2101200e102e2011210220014104460d060c080b200f2d000d2101200e102e2011210220014104460d050c070b20092903082118200441b8036a22024200370300200441e08dc0003602b4032009290310211920042018a7417f2018428080808010541b3602c00320042019a7417f2019428080808010541b3602b003200441b0036a4104722201410d10b8032001410c10b8032001410710b8032001410f10b803200441b0036a410c6a220128020021132002280200211120042802c003211a20042802b403210c20042802b003211b200441c0036a220820073602002001200a3602002004200b3602b803200420053602b403200420063602b003200441e0006a200441b0036a10b903024002400240410110292201450d00200141003a0000200420042f01b003220d3b01a002200841e0083b01002002428180808010370300200420013602b403200441013602b0032004200d3b01c203200441e0006a200441b0036a10ba03210b0240410310292202450d00200241026a41002d008cc5453a0000200241002f008ac5453b00000240410310292208450d00200841026a41002d008fc5453a0000200841002f008dc5453b000002400240024002400240024002400240200441f4006a280200220d200441e0006a41106a2802002201470d00200141016a220d2001490d0120014101742207200d200d2007491b220dad42287e2218422088a70d012018a722074100480d010240024020010d002007102921010c010b200428026c200141286c2007102a21010b2001450d072004200d3602702004200136026c2004280274210d0b200428026c200d41286c6a220141003a00182001200836020c2001428380808030370204200120023602002001411c6a200b360200200141106a4283808080303702002004200428027441016a360274200441b0036a200441e0006a418c0110f6041a200441f0016a200441b0036a10bb03200441f0016a41106a2802002210412c6c210120042802f801220741586a210202400340410021082001450d01200141546a2101200241286a210d2002412c6a220b2102200d2d00004103470d000b200b41086a2802002201450d00200141286c2102200b28020041186a2101410021080340200820012d0000456a2108200141286a2101200241586a22020d000b0b2010412c6c2101200741586a21022008417f6a210d02400340410021082001450d01200141546a2101200241286a210b2002412c6a220e2102200b2d00004103470d000b200e41086a2802002201450d00200141286c2102200e28020041186a2101410021080340200820012d0000456a2108200141286a2101200241586a22020d000b0b2010412c6c2101200741606a2102024003404100210e024020010d00410021010c020b200141546a2101200241206a210b2002412c6a220f2102200b2d00004104470d000b200f28020021010b02400240024002402010450d00200120086a211c20072010412c6c6a211d4100211e4100210f0340024020072d000041786a220141034b0d00024002400240024020010e0403010200030b200728020c2201450d032007280204220b200141186c6a211f0340200f21200240200b22212802144104742202450d00202128020c21010340024020012d0000410b470d00200141046a2208280200220b200d490d002008200b41016a3602000b200141106a2101200241706a22020d000b0b02400240024002400240024002400240024002400240410810292201450d002001428080808010370200410410292222450d012021410c6a21082022410036020020212802142223450d0241002102410121062023210b41012110410121124101210f024003402002200b4f0d01200241016a210a02400240024002400240024002400240200828020020024104746a2d0000220b417e6a220241044b0d0020020e050101010302010b200b10bc032124200c210b201121250340200b410c6a210e200b41086a2126200b2f010621054100210202400240034020052002460d01202620026a2114200e41086a210e200241016a210202404100417f410120142d00002214202441ff017122154b1b20142015461b41016a0e03000301000b0b2002417f6a21050b024020250d00201b210b0c070b2025417f6a2125200b20054102746a41ec006a280200210b0c010b0b201b210b200e2802000e0404100304040b200b10bc032124200c210b2011212502400340200b410c6a210e200b41086a2126200b2f010621054100210202400240034020052002460d01202620026a2114200e41086a210e200241016a210202404100417f410120142d00002214202441ff017122154b1b20142015461b41016a0e03000301000b0b2002417f6a21050b024020250d00201b210b0c030b2025417f6a2125200b20054102746a41ec006a280200210b0c010b0b201b210b0240200e2802000e0401110001010b200e41046a280200210b0b200f417f6a2202200f4f0d0f2002200f4b0d0f2010202220024102746a28020022024d0d0f200120024103746a220e2802042202200b6a220b2002490d0f200e200b3602040240024020062010460d00200621050c010b200641016a22022006490d1e2006410174220b20022002200b491b220541ffffffff01712005470d1e200541037422024100480d1e0240024020060d002002102921010c010b200120064103742002102a21010b2001450d0c0b200120104103746a220241013602042002200a360200024002402012200f460d00201221140c010b201241016a22022012490d1e2012410174220b20022002200b491b221441ffffffff03712014470d1e201441027422024100480d1e0240024020120d002002102921220c010b202220124102742002102a21220b2022450d0d0b201041016a21022022200f4102746a2010360200200f41016a210f0c050b200f450d0e200f417f6a210f0c030b200f450d0d0240024020062010460d00200621050c010b200641016a22022006490d1c2006410174220b20022002200b491b220541ffffffff01712005470d1c200541037422024100480d1c0240024020060d002002102921010c010b200120064103742002102a21010b2001450d0c0b200120104103746a220241013602042002200a360200024002402012200f417f6a220b460d00201221140c010b20124101742202200f200f2002491b221441ffffffff03712014470d1c201441027422024100480d1c0240024020120d002002102921220c010b202220124102742002102a21220b2022450d0d0b201041016a21022022200b4102746a20103602000c030b200e41046a280200210b0b200f417f6a2202200f4f0d0b2002200f4b0d0b2010202220024102746a28020022024d0d0b200120024103746a220e2802042202200b6a220b2002490d0b200e200b3602040b2006210520102102201221140b200a2023460d0a2021280214210b200521062002211020142112200a21020c000b0b4190c5c5002002200b1038000b41084104102c000b41044104102c000b200141086a210e41012114410121050c060b20024104102c000b20024104102c000b20024104102c000b20024104102c000b02402006450d002001102e0b4101211e024020120d002020210f0c080b2022102e2020210f0c070b2002450d01200120024103746a210e0b2001210f410121020340200129020021182004412d3a00b003200420184220883e02b403200820022018a76a220b417f6a200441b0036a10bd032004410b3a00b0032004200d3602b4032008200b200441b0036a10bd03200241026a2102200e200141086a2201470d000b200f21010b02402005450d002001102e0b02402014450d002022102e0b202141186a210b02400240201a450d0020212802142202450d00202128020c210120024104742102410021080340024020012d0000412c470d002001410b3a0000200141046a201c360200200841016a21080b200141106a2101200241706a22020d000b4101210f20080d010b2020210f0b200b201f470d000c040b0b20072802042201200d490d022007200141016a3602040c020b200728020c2201450d012007280204220b2001411c6c6a210e0340200b2201411c6a210b024020012802182202450d0020012802102101200241027421020340024020012802002208200d490d002001200841016a3602000b200141046a21012002417c6a22020d000b0b200b200e460d020c000b0b200728020c2201450d00200141146c2102200728020441106a2101034002402001417c6a2802000d0020012802002208200d490d002001200841016a3602000b200141146a21012002416c6a22020d000b0b2007412c6a2207201d470d000b201e4101710d02200f4101710d01200428028002210e20042802f80121070b200441fc016a280200210620042802f401210f20042802f0012110410021050c020b200441b0036a41106a200441f0016a41106a280200360200200441b0036a41086a200441f0016a41086a290300370300200420042903f0013703b003200441a0026a200441b0036a10b903411010292202450d07200241063a0000410110292201450d06200141003a000041011029220b450d05200b20012d00003a00002001102e411010292208450d04200841063a000041f00010292201450d03200141063a00602001412c3b01502001200d3602442001410b3a0040200141d8003a00302001201a3602242001412d3a0020200141003602142001410f3a0010200141003602042001410f3a0000024020082d00004109470d00200828020841ffffffff0371450d002008280204102e0b2008102e024020022d00004109470d00200228020841ffffffff0371450d002002280204102e0b2002102e200441d4036a4287808080f000370200200441d0036a2001360200200441cc036a4100360200200441b0036a410c6a4281808080800c370200200441b8036a4101360200200441003602dc03200442043702c4032004200b3602b403200441013602b003200441a0026a200441b0036a10be03200441b0036a200441a0026a418c0110f6041a20044188026a200441b0036a10bb0320044188026a410c6a280200210620044198026a280200210e2004280288022110200428028c02210f2004280290022107410021050c010b200441fc016a280200210620042802f80121070240200428028002220e450d00200e412c6c2102200721010340200110bf032001412c6a2101200241546a22020d000b0b41012105411a210f41f0a3c500211002402006450d002007102e0b0b02402011450d000340200c28026c210c2011417f6a22110d000b0b4100210841002101024003402013450d01024002402001200c2f01064f0d00200c20014103746a41146a2902002118200141016a21010c010b02400240200c28020022010d002008ad21184100210d410021010c010b200c3301044220862008ad8421184101210d0b200c102e2018a72108024002402018422088a7220b20012f01064f0d00200121020c010b034002400240200128020022020d002008ad2118410021020c010b200d41016a210d20013301044220862008ad8421180b2001102e2018a72108200221012018422088a7220b20022f01064f0d000b0b200b41027420026a41f0006a280200210c2002200b4103746a41146a29020021180240200d417f6a2201450d000340200c28026c210c2001417f6a22010d000b0b410021010b2013417f6a21132018a74103470d000b0b0240200c41e08dc000460d00200c2802002101200c102e2001450d00200128020021022001102e2002450d00024020022802002201450d0003402002102e2001210220012802002208210120080d000b0b2002102e0b02402005450d002000201036020420004101360200200041086a200f3602000c160b200441a0026a41106a200e360200200441a0026a410c6a2006360200200420073602a8022004200f3602a402200420103602a002200441b0036a200441a0026a200928026010c003024020042802b0034101470d000240200441b0036a41086a280200450d0020042802b403102e0b2000418aa4c50036020420004101360200200041086a41233602000c160b200441c4036a2802002102200441b0036a41106a2802002105200441b0036a410c6a2802002110200441b8036a280200210d20042802b4032108200328025821062004410036029002200442013703880202400240410410292201450d002004410436028c022004200428029002220b41046a3602900220042001360288022001200b6a200836000002400240200428028c02220820042802900222016b4104490d0020042802880221080c010b200141046a220b2001490d0320084101742201200b200b2001491b22014100480d030240024020080d002001102921080c010b20042802880220082001102a21080b2008450d022004200136028c02200420083602880220042802900221010b2004200141046a36029002200820016a200d36000020102002412c6c22016a210d024020020d00201021010c0e0b200141546a2103200441b0036a4101722102200441b0036a41276a210b200441b0036a41206a210c200441b0036a41186a2107200441b0036a41106a210e200441b0036a41086a211120102101034020012d00002108200b200141286a280000360000200c200141216a2900003703002007200141196a290000370300200e200141116a2900003703002011200141096a2900003703002004200141016a2900003703b00302402008410f470d002001412c6a21010c0f0b200441a0026a41276a2213200b280000360000200441a0026a41206a220f200c290300370300200441a0026a41186a20072903002218370300200441a0026a41106a200e2903002219370300200441a0026a41086a20112903002227370300200420042903b00322283703a00220022028370000200241086a2027370000200241106a2019370000200241186a2018370000200241206a200f290300370000200241276a2013280000360000200420083a00b003200441e0006a200441b0036a20044188026a10c10320042d00602208411a470d0d200341546a21032001412c6a2201200d470d000b200d21010c0d0b41044101102c000b20014101102c000b102d000b41f0004108102c000b41104108102c000b41014101102c000b41014101102c000b41104108102c000b20074104102c000b41034101102c000b41034101102c000b41014101102c000b200428026421122004280268210602402003450d002001412c6a2101200441b0036a4101722102200441b0036a41276a210c200441b0036a41206a2107200441b0036a41186a210e200441b0036a41106a2111200441b0036a41086a2103034020012d0000210b200c200141286a2800003600002007200141216a290000370300200e200141196a2900003703002011200141116a2900003703002003200141096a2900003703002004200141016a2900003703b003200b410f460d01200441a0026a41276a2213200c280000360000200441a0026a41206a220f2007290300370300200441a0026a41186a200e2903002218370300200441a0026a41106a20112903002219370300200441a0026a41086a20032903002227370300200420042903b00322283703a00220022028370000200241086a2027370000200241106a2019370000200241186a2018370000200241206a200f290300370000200241276a20132800003600002004200b3a00b003200441b0036a10bf032001412c6a2201200d470d000b0b02402005450d002010102e0b0240200428028c02450d00200428028802102e0b024020084105470d002006450d002012102e0b200041cba6c50036020420004101360200200041086a41253602000c0a0b02402001200d460d00200441b0036a4101722102200441b0036a41276a210b200441b0036a41206a210c200441b0036a41186a2107200441b0036a41106a210e200441b0036a41086a2111034020012d00002108200b200141286a280000360000200c200141216a2900003703002007200141196a290000370300200e200141116a2900003703002011200141096a2900003703002004200141016a2900003703b0032008410f460d01200441a0026a41276a2203200b280000360000200441a0026a41206a2213200c290300370300200441a0026a41186a20072903002218370300200441a0026a41106a200e2903002219370300200441a0026a41086a20112903002227370300200420042903b00322283703a00220022028370000200241086a2027370000200241106a2019370000200241186a2018370000200241206a2013290300370000200241276a2003280000360000200420083a00b003200441b0036a10bf032001412c6a2201200d470d000b0b02402005450d002010102e0b2004280288022101200429028c0221182000411c6a41003a0000200041146a2018370200200041106a20013602002000410c6a2017360200200041086a2016360200200020063602042000411d6a20042f00f0013b0000200041003602002000411f6a200441f2016a2d00003a00000c090b200020083602040c070b2014102e200041d89ac3003602040c060b2014102e200041d89ac3003602040c050b02400240200241809dc500460d0041809dc5002002410b10f8040d010b4126210c41d89ac300210e200f2d000c41e000470d04200f2802080d0420112102200f2d000d4104460d010c040b02400240200241a49dc500460d0041a49dc5002002410b10f8040d010b4126210c41d89ac300210e200f2d000c41e000470d04200f2802080d0420112102200f2d000d4104460d010c040b0240200241de9ec500460d0041de9ec5002002410b10f8040d020b0240024041021029220c450d00200c41003b00000240200f2d000c41e000470d00200f2802084102470d00200f280200210e41002101034020014102460d03200c20016a2102200e20016a2108200141016a210120082d000020022d0000460d000b0b200c102e0c030b41024101102c000b200f2d000d2101200c102e2011210220014104460d000c020b0b41262101200041d89ac3003602040c020b4126210c41d89ac300210e0b200c21012000200e3602040b20004101360200200041086a200136020002402007450d00200b2007412c6c6a2107200b210c0340200c220d412c6a210c02400240200d2d00002201410d4b0d00024002400240024002400240024002400240024002400240024020010e0e0001020304050607080e090a0b0c000b200d41086a280200450d0d200d41046a280200102e0c0d0b0240200d41086a280200450d00200d41046a280200102e0b200d41146a280200450d0c200d41106a280200102e0c0c0b0240200d410c6a2802002202450d00200d41046a28020021012002410474210203400240200141046a280200450d002001280200102e0b200141106a2101200241706a22020d000b0b200d41086a280200450d0b200d280204102e0c0b0b0240200d410c6a2802002202450d00200d41046a2802002101200241286c210203400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141286a2101200241586a22020d000b0b200d41086a280200450d0a200d280204102e0c0a0b200d41086a280200450d09200d41046a280200102e0c090b200d41086a280200450d08200d41046a280200102e0c080b200d41086a280200450d07200d41046a280200102e0c070b0240200d410c6a2802002201450d00200d41046a280200220820014104746a21000340024020082802082202450d0020082802002101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200241706a22020d000b0b200841106a21010240200841046a280200450d002008280200102e0b2001210820012000470d000b0b200d41086a280200450d06200d280204102e0c060b0240200d410c6a2802002202450d00200d41046a2802002101200241146c210203400240200141046a280200450d002001280200102e0b200141146a21012002416c6a22020d000b0b200d41086a280200450d05200d280204102e0c050b0240200d410c6a2802002201450d00200d41046a28020022082001411c6c6a2100034002402008410c6a2802002202450d0020082802042101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200241706a22020d000b0b0240200841086a280200450d002008280204102e0b2008411c6a21010240200841146a280200450d002008280210102e0b2001210820012000470d000b0b200d41086a280200450d04200d280204102e0c040b0240200d410c6a2802002201450d00200d41046a2802002208200141186c6a210003400240200841046a280200450d002008280200102e0b0240200841146a2802002202450d00200828020c2101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200241706a22020d000b0b200841186a21010240200841106a280200450d00200828020c102e0b2001210820012000470d000b0b200d41086a280200450d03200d280204102e0c030b0240200d410c6a2802002201450d00200d41046a28020022082001411c6c6a2100034002402008410c6a2802002202450d0020082802042101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200241706a22020d000b0b0240200841086a280200450d002008280204102e0b2008411c6a21010240200841146a280200450d002008280210102e0b2001210820012000470d000b0b200d41086a280200450d02200d280204102e0c020b0240200d41046a2d0000220141024b0d0002400240024020010e03000102000b200d410c6a280200450d04200d41086a280200102e0c040b0240200d41146a2802002202450d00200d410c6a28020021012002410c6c21020340024020012802002208450d00200141046a280200450d002008102e0b2001410c6a2101200241746a22020d000b0b200d41106a280200450d03200d28020c102e0c030b0240200d41146a2802002201450d00200d410c6a280200220e20014104746a21110340200e220041106a210e024020002802042201450d0002402000410c6a2802002202450d002002410c6c21020340024020012802002208450d00200141046a280200450d002008102e0b2001410c6a2101200241746a22020d000b0b200041086a280200450d002000280204102e0b200e2011470d000b0b200d41106a280200450d02200d28020c102e0c020b200d410c6a280200450d01200d41086a280200102e0c010b0240200d41086a280200450d00200d41046a280200102e0b0240200d41146a2802002201450d00200d41186a280200450d002001102e0b200d41246a280200450d00200d41206a280200102e0b200c2007470d000b0b200a450d00200b102e0b200441c0046a24000b9e0301067f230041106b220224002002410036020820024201370300200020021066200041046a20021066200041086a2002106620002d0018210302400240024002400240200228020420022802082204460d00200228020021050c010b200441016a22052004490d0320044101742206200520052006491b22064100480d030240024020040d002006102921050c010b200228020020042006102a21050b2005450d0120022006360204200220053602000b2002200441016a360208200520046a20033a0000200028020c2106200041146a2802002204200210470240024020022802042203200228020822056b2004490d00200228020021000c010b200520046a22002005490d0320034101742207200020002007491b22074100480d030240024020030d002007102921000c010b200228020020032007102a21000b2000450d022002200736020420022000360200200721030b200020056a2006200410f6041a200128020020012802042000200520046a100402402003450d002000102e0b200241106a24000f0b20064101102c000b20074101102c000b102d000b9c2104057f027e027f027e230041c0036b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200200541104b0d1220050e110102030405060708090a0b0c0d0e0f1011010b200041123a00000c170b200241b0016a200110b8010240024020022d00b0014113460d00200241b8026a200241b0016a41880110f6041a418801102922040d014188014108102c000b200041123a00000c170b2004200241b8026a41880110f6042104200241086a2001106502402002290308a7450d00200041123a00002004102f2004102e0c170b200241086a41106a290300210720022903102108200041013a0000200020022f0090013b0001200041086a2008370300200041046a2004360200200041186a2002290358370300200041106a2007370300200041036a20024192016a2d00003a0000200041206a200241d8006a41086a290300370300200041286a200241d8006a41106a2903003703000c160b200241206a2001103102402002280220450d00200041123a00000c160b20022802242101200041023a0000200020022f00b0013b0001200041046a2001360200200041086a20022903b802370300200041036a200241b0016a41026a2d00003a0000200041106a200241b8026a41086a290300370300200041186a200241b8026a41106a290300370300200041206a200241b8026a41186a290300370300200041286a200241b8026a41206a2903003703000c150b200241286a2001103120022802280d1320012802042204450d13200228022c2106200128020022032d0000210520012004417f6a3602042001200341016a360200200541ff0071220141064b0d13200041033a0000200041046a2006360200200041026a20013a0000200020054107763a0001200041086a20022903b802370300200041106a200241b8026a41086a290300370300200041186a200241b8026a41106a290300370300200041206a200241b8026a41186a290300370300200041286a200241b8026a41206a2903003703000c140b200241306a2001103120022802300d1120012802042204450d1120022802342106200128020022032d0000210520012004417f6a3602042001200341016a360200200541ff0071220141064b0d11200041043a0000200041046a2006360200200041026a20013a0000200020054107763a0001200041086a20022903b802370300200041106a200241b8026a41086a290300370300200041186a200241b8026a41106a290300370300200041206a200241b8026a41186a290300370300200041286a200241b8026a41206a2903003703000c130b0240200641034b0d00200041123a00000c130b2004280001210520012003417b6a3602042001200441056a360200200041053a0000200020022f00b0013b0001200041046a2005360200200041086a20022903b802370300200041036a200241b2016a2d00003a0000200041106a200241b8026a41086a290300370300200041186a200241b8026a41106a290300370300200041206a200241b8026a41186a290300370300200041286a200241b8026a41206a2903003703000c120b200241b0016a200110b8010240024020022d00b0014113460d00200241b8026a200241b0016a41880110f6041a418801102922010d014188014108102c000b200041123a00000c120b2001200241b8026a41880110f6042101200041063a0000200020022f0090013b0001200041036a20024192016a2d00003a0000200041046a2001360200200041086a2002290358370300200041106a200241d8006a41086a290300370300200041186a200241d8006a41106a290300370300200041206a200241d8006a41186a290300370300200041286a200241d8006a41206a2903003703000c110b200241b0016a200110b8010240024020022d00b0014113460d00200241b8026a200241b0016a41880110f6041a418801102922010d014188014108102c000b200041123a00000c110b2001200241b8026a41880110f6042101200041073a0000200020022f0090013b0001200041036a20024192016a2d00003a0000200041046a2001360200200041086a2002290358370300200041106a200241d8006a41086a290300370300200041186a200241d8006a41106a290300370300200041206a200241d8006a41186a290300370300200041286a200241d8006a41206a2903003703000c100b200241b0016a200110b8010240024020022d00b0014113460d00200241b8026a200241b0016a41880110f6041a418801102922010d014188014108102c000b200041123a00000c100b2001200241b8026a41880110f6042101200041083a0000200020022f0090013b0001200041036a20024192016a2d00003a0000200041046a2001360200200041086a2002290358370300200041106a200241d8006a41086a290300370300200041186a200241d8006a41106a290300370300200041206a200241d8006a41186a290300370300200041286a200241d8006a41206a2903003703000c0f0b41002105200241003a00d8022003417f6a2109417e21060340024020092005470d00200541ff0171450d0d200241003a00d8020c0d0b200241b8026a20056a200420056a220a41016a2d00003a00002001200320066a3602042001200a41026a3602002002200541016a220a3a00d8022006417f6a2106200a2105200a4120470d000b200241d8006a41086a200241b8026a41086a290300370300200241d8006a41106a200241b8026a41106a290300370300200241d8006a41186a200241b8026a41186a290300370300200220022903b802370358200a417f7320036a4104490d0b2004200a6a220441016a280000210620012003200a6b2203417b6a22053602042001200441056a220a36020020054104490d0b20024190016a41086a200241d8006a41086a290300220737030020024190016a41106a200241d8006a41106a290300220837030020024190016a41186a200241d8006a41186a290300220b370300200a28000021052001200341776a3602042001200441096a36020020022002290358220c37039001200041093a00002000200c370001200041096a2007370000200041116a2008370000200041196a200b370000200041286a2005360200200041246a2006360200200041216a20022f0082013b0000200041236a20024184016a2d00003a00000c0e0b41002105200241003a00d8022003417f6a210a2003417e6a210303400240200a2005470d000240200541ff0171450d00200241003a00d8020b200041123a00000c0f0b200241b8026a20056a200420056a220641016a2d00003a0000200120033602042001200641026a3602002002200541016a22063a00d8022003417f6a21032006210520064120470d000b200241d8006a41086a200241b8026a41086a2903002207370300200241d8006a41106a200241b8026a41106a2903002208370300200241d8006a41186a200241b8026a41186a290300220b370300200220022903b802220c3703582000410a3a00002000200c370001200041096a2007370000200041116a2008370000200041196a200b370000200041216a200229009001370000200041286a20024197016a2900003700000c0d0b200241386a2001103102402002280238450d00200041123a00000c0d0b200228023c21012000410b3a0000200020022f00b0013b0001200041046a2001360200200041086a20022903b802370300200041036a200241b2016a2d00003a0000200041106a200241b8026a41086a290300370300200041186a200241b8026a41106a290300370300200041206a200241b8026a41186a290300370300200041286a200241b8026a41206a2903003703000c0c0b200241d0006a2001103120022802500d0720022802542104200241c8006a2001103120022802480d07200228024c2105200241c0006a2001103120022802400d07200228024421012000410c3a0000200020022f00b0013b00012000410c6a2001360200200041086a2005360200200041046a2004360200200041106a20022903b802370300200041036a200241b2016a2d00003a0000200041186a200241b8026a41086a290300370300200041206a200241b8026a41106a290300370300200041286a200241b8026a41186a2903003703000c0b0b41002105200241003a00d8022003417f6a210a2003417e6a210303400240200a2005470d000240200541ff0171450d00200241003a00d8020b200041123a00000c0c0b200241b8026a20056a200420056a220641016a2d00003a0000200120033602042001200641026a3602002002200541016a22063a00d8022003417f6a21032006210520064120470d000b200241d8006a41086a200241b8026a41086a2903002207370300200241d8006a41106a200241b8026a41106a2903002208370300200241d8006a41186a200241b8026a41186a290300220b370300200220022903b802220c3703582000410d3a00002000200c370001200041096a2007370000200041116a2008370000200041196a200b370000200041216a200229009001370000200041286a20024197016a2900003700000c0a0b2000410e3a00000c090b41002105200241003a00d8022003417f6a210a2003417e6a210303400240200a2005470d000240200541ff0171450d00200241003a00d8020b200041123a00000c0a0b200241b8026a20056a200420056a220641016a2d00003a0000200120033602042001200641026a3602002002200541016a22063a00d8022003417f6a21032006210520064120470d000b200241d8006a41086a200241b8026a41086a2903002207370300200241d8006a41106a200241b8026a41106a2903002208370300200241d8006a41186a200241b8026a41186a290300220b370300200220022903b802220c3703582000410f3a00002000200c370001200041096a2007370000200041116a2008370000200041196a200b370000200041216a200229009001370000200041286a20024197016a2900003700000c080b41002105200241003a00d8022003417f6a21092003417e6a21060340024020092005470d00200541ff0171450d04200241003a00d8020c040b200241b8026a20056a200420056a220a41016a2d00003a0000200120063602042001200a41026a3602002002200541016a220a3a00d8022006417f6a2106200a2105200a4120470d000b200241d8006a41086a200241b8026a41086a290300370300200241d8006a41106a200241b8026a41106a290300370300200241d8006a41186a200241b8026a41186a290300370300200220022903b8023703582003417f6a200a460d022004200a6a220541016a2d00002104200120063602042001200541026a360200200441064b0d0220024190016a41186a200241d8006a41186a290300220737030020024190016a41106a200241d8006a41106a290300220837030020024190016a41086a200241d8006a41086a290300220b37030020022002290358220c37039001200041103a00002000200c370001200041096a200b370000200041116a2008370000200041196a2007370000200041216a20043a0000200041226a200229018201370100200041286a20024182016a41066a2901003701000c070b200041113a00000c060b200041123a00000c050b200041123a00000c040b200041123a00000c030b200041123a00000c020b200041123a00000c010b200041123a00000b200241c0036a24000b800902067f047e230041d0026b220224000240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a3602042001200441016a360200200541034b0d0820050e0401020304010b200041053a00000c0c0b200241206a2001103020022802200d03200041053a00000c0b0b200241c0006a200110b80120022d00404113470d03200041053a00000c0a0b2002200110312002280200450d030c080b41002105200241003a00e8012003417f6a21062003417e6a21030340024020062005470d00200541ff0171450d08200241003a00e8010c080b200241c8016a20056a200420056a220741016a2d00003a0000200120033602042001200741026a3602002002200541016a22073a00e8012003417f6a21032007210520074120470d000b200241c0006a41186a200241c8016a41186a290300370300200241c0006a41106a200241c8016a41106a290300370300200241c0006a41086a200241c8016a41086a290300370300200220022903c801370340200241086a2001103120022802080d0620012802042205450d06200228020c2103200128020022072d0000210420012005417f6a3602042001200741016a360200200241206a41086a200241c0006a41086a2903002208370300200241206a41106a200241c0006a41106a2903002209370300200241206a41186a200241c0006a41186a290300220a37030020022002290340220b370320200041043a00002000200b370001200041096a2008370000200041116a2009370000200041196a200a370000200041246a2003360200200041216a20043a00000c080b200241cb006a200241206a41086a28020036000020022002290320370043200041013a000020002002290040370001200041086a200241c7006a290000370000200041106a20022902c801370200200041186a200241c8016a41086a290200370200200041206a200241c8016a41106a2902003702000c070b200241c8016a200241c0006a41880110f6041a41880110292205450d022005200241c8016a41880110f6042105200041023a0000200020022f00103b0001200041036a200241106a41026a2d00003a0000200041046a2005360200200041086a2002290220370200200041106a200241206a41086a290200370200200041186a200241206a41106a290200370200200041206a200241206a41186a2902003702000c060b20022802042105200241c0006a200110b80120022d00404113460d04200241c8016a200241c0006a41880110f6041a41880110292201450d022001200241c8016a41880110f6042101200041033a0000200020022f00103b0001200041036a200241126a2d00003a0000200041086a2001360200200041046a20053602002000410c6a2002290220370200200041146a200241206a41086a2902003702002000411c6a200241306a290200370200200041246a200241386a2802003602000c050b200041053a00000c040b4188014108102c000b4188014108102c000b200041053a00000c010b200041053a00000b200241d0026a24000bd50603057f0b7e057f230041106b21020240200128020422034104490d0020012802002204280000210520012003417c6a22063602042001200441046a36020020064108490d00200429000421072001200341746a220636020420012004410c6a36020020064108490d00200429000c210820012003416c6a22063602042001200441146a36020020064108490d00200429001421092001200341646a220636020420012004411c6a36020020064108490d00200429001c210a20012003415c6a22063602042001200441246a36020020064108490d002004290024210b2001200341546a220636020420012004412c6a36020020064108490d00200429002c210c20012003414c6a22063602042001200441346a36020020064108490d002004290034210d2001200341446a220636020420012004413c6a36020020064108490d00200429003c210e2001200341bc7f6a22063602042001200441c4006a36020020064108490d002004290044210f2001200341b47f6a22063602042001200441cc006a36020020064108490d00200429004c21102001200341ac7f6a22063602042001200441d4006a36020020064108490d00200429005421112001200341a47f6a22063602042001200441dc006a36020020064104490d00200428005c21122001200341a07f6a22063602042001200441e0006a36020020064104490d002004280060211320012003419c7f6a22063602042001200441e4006a36020020064104490d00200428006421142001200341987f6a22063602042001200441e8006a36020020064104490d00200428006821152001200341947f6a22063602042001200441ec006a22043602002006450d0020042d000021162001200341937f6a22063602042001200441016a36020020064104490d00200020163a00702000201536026820002014360264200020133602602000201236025c2000200536025820002011370350200020103703482000200f3703402000200e3703382000200d3703302000200c3703282000200b3703202000200a3703182000200937031020002008370308200020073703002004280001210620012003418f7f6a3602042001200441056a3602002000200636026c200041f4006a2002410c6a280000360000200020022800093600710f0b200041023a00700bfb0101077f230041106b220124002001410036020820014201370300200110fc0120012802042102200128020021030240024002400240200041046a2802002204200041086a28020022056b20012802082206490d00200028020021040c010b200520066a22072005490d0220044101742205200720072005491b22054100480d020240024020040d002005102921040c010b200028020020042005102a21040b2004450d0120002004360200200041046a2005360200200041086a28020021050b200041086a200520066a360200200420056a2003200610f6041a02402002450d002003102e0b200141106a24000f0b20054101102c000b102d000bdf0701037f024002400240024002400240024020002d0000417f6a220241034b0d00024002400240024020020e0400010203000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0a20024101742204200320032004491b22044100480d0a0240024020020d002004102921030c010b200128020020022004102a21030b2003450d0520012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41003a0000200028020421022000410c6a2802002200200110472000450d0320004105742100034020022001104a200241206a2102200041606a22000d000c040b0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0920024101742204200320032004491b22044100480d090240024020020d002004102921030c010b200128020020022004102a21030b2003450d0520012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a00002000280204200110bc010f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0820024101742204200320032004491b22044100480d080240024020020d002004102921030c010b200128020020022004102a21030b2003450d0520012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41023a0000200041046a200110662000280208200110bc010f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0720024101742204200320032004491b22044100480d070240024020020d002004102921030c010b200128020020022004102a21030b2003450d0520012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a0000200041016a20011046200041246a2001106602400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d0720024101742204200320032004491b22044100480d070240024020020d002004102921030c010b200128020020022004102a21030b2003450d0620012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20002d00213a00000b0f0b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b102d000bf71802047f017e20002802582102024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2802002203200141086a28020022046b4104490d00200128020021030c010b200441046a22052004490d1320034101742204200520052004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0120012003360200200141046a2004360200200141086a28020021040b200141086a2205200441046a360200200320046a20023600002000290300210602400240200141046a2802002203200528020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0220012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290308210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0320012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290310210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0420012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290318210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0520012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290320210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0620012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290328210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0720012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290330210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0820012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290338210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0920012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290340210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0a20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290348210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0b20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290350210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0c20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a2006370000200028025c210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0d20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a20053600002000280260210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0e20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a20053600002000280264210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d0f20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a20053600002000280268210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004102921030c010b200128020020032004102a21030b2003450d1020012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a200536000002400240200141046a28020020022802002204460d00200128020021030c010b200441016a22032004490d1320044101742202200320032002491b22024100480d130240024020040d002002102921030c010b200128020020042002102a21030b2003450d1120012003360200200141046a2002360200200141086a28020021040b200141086a2202200441016a360200200320046a20002d00703a0000200028026c210302400240200141046a2802002204200228020022006b4104490d00200128020021040c010b200041046a22022000490d1320044101742200200220022000491b22004100480d130240024020040d002000102921040c010b200128020020042000102a21040b2004450d1220012004360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200420006a20033600000f0b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20024101102c000b20004101102c000b102d000bb70201057f230041106b2203240020034100360208200342013703002001200310470240024002402001450d00200141b0016c2104034020004188016a28020021050240024020032802042206200328020822016b4104490d00200328020021060c010b200141046a22072001490d0420064101742201200720072001491b22014100480d040240024020060d002001102921060c010b200328020020062001102a21060b2006450d032003200136020420032006360200200328020821010b2003200141046a360208200620016a20053600002000200310bc012000418c016a2003104a200041b0016a2100200441d07e6a22040d000b0b2003280204210020022802002002280204200328020022012003280208100402402000450d002001102e0b200341106a24000f0b20014101102c000b102d000b8d0403057f017e077f02400240024002402001410c6a2802002202417f4c0d00200128020021030240024020020d00410121040c010b20012802042105200210292204450d0220042005200210f6041a0b200141186a2802002206ad420c7e2207422088a70d002007a72205417f4c0d00200128021021080240024020050d00410421090c010b200510292209450d030b0240024020060d004100210a0c010b20082006410c6c6a210b4100210a2009210c0340200841086a2802002205417f4c0d022008280200210d0240024020050d004101210e0c010b20051029220e450d060b200e200d200510f604210d200c41086a2005360200200c41046a2005360200200c200d360200200c410c6a210c200a41016a210a2008410c6a2208200b470d000b0b20002004360204200020033602002000200129021c37021c200041186a200a360200200041146a2006360200200041106a20093602002000410c6a2002360200200041086a2002360200200020012902243702242000412c6a2001412c6a290200370200200041346a200141346a2902003702002000413c6a2001413c6a290200370200200041c4006a200141c4006a290200370200200041cc006a200141cc006a290200370200200041d4006a200141d4006a290200370200200041dc006a200141dc006a2902003702000f0b1032000b20024101102c000b20054104102c000b20054101102c000bb90804087f067e017f047e230041e0026b22022400200241386a2001280200200128020428020c1100000240024020022903384201520d0020024198026a4101722103200241386a41086a2104200241ab016a21050340200241a8016a41186a2206200441186a290000370300200241a8016a41106a2207200441106a290000370300200241a8016a41086a2208200441086a290000370300200220042900003703a80120024198026a200241a8016a108202024002400240024020022d0098024101460d00200241003602e8010c010b200241c0026a41186a200341186a290000370300200241c0026a41106a200341106a290000370300200241c0026a41086a200341086a290000370300200220032900003703c002200241c8016a200241c0026a10830220022802e80122090d010b4200210a4200210b0c010b200241c8016a41186a290300210b20022903d801210a20022802ec01450d002009102e0b20024198026a41086a2008290300220c37030020024198026a41106a2007290300220d37030020024198026a41186a2006290300220e370300200220022903a801220f37039802200241c8016a41086a2207200c370300200241c8016a41106a2209200d370300200241c8016a41186a2210200e3703002002200f3703c801200241c0026a41086a22064200370300200242003703c00241c28cc0004116200241c0026a100320082006290300370300200220022903c0023703a801200241206a200241a8016a109701200241106a2002290328200241206a41106a290300427f420010fc042002200a200b20022903104200200228022022081b220c4201200c420156200241106a41086a290300420020081b220c420052200c501b22081b200c420020081b10fc04024002402002290300220c50450d00410221080c010b200241c0026a41186a2010290300370300200241c0026a41106a200929030037030020062007290300370300200220022903c8013703c002200220022800a8013602a001200220052800003600a3014200211141002108200c2112200a2113200b21140b20024180016a41086a200629030037030020024180016a41106a200241c0026a41106a29030037030020024180016a41186a200241c0026a41186a290300370300200220022903c00237038001200220022802a001360278200220022800a30136007b024020084102460d002000201237031020004200370308200042003703002000200229038001370320200020083a004020002002280278360041200041186a2011370300200041d0006a2014370300200041c8006a2013370300200041c4006a200228007b360000200041286a20024188016a290300370300200041306a20024190016a290300370300200041386a20024180016a41186a2903003703000c030b200241386a2001280200200128020428020c11000020022903384201510d000b0b200041023a00400b200241e0026a24000be70201067f230041d0006b220224000240410e10292203450d00200341002900d9e743370000200341066a41002900dfe7433700002002428e808080e00137020c200220033602082001200241086a104a200228020c21042002280210210520022802082103200241086a41186a22014200370300200241086a41106a22064200370300200241086a41086a220742003703002002420037030820032005200241086a1000200241306a41186a2001290300370300200241306a41106a2006290300370300200241306a41086a200729030037030020022002290308370330200241086a200241306a412010dc010240024020022d00084101460d00200041003a00000c010b20002002290308370000200041206a200241086a41206a2d00003a0000200041186a2001290300370000200041106a2006290300370000200041086a20072903003700000b02402004450d002003102e0b200241d0006a24000f0b410e4101102c000b9b0201067f230041f0006b220224000240410e10292203450d00200341002900b1e843370000200341066a41002900b7e8433700002002428e808080e0013702042002200336020020012002104a200228020421012002280208210420022802002103200241186a22054200370300200241106a22064200370300200241086a22074200370300200242003703002003200420021000200241d0006a41186a2005290300370300200241d0006a41106a2006290300370300200241d0006a41086a2007290300370300200220022903003703502002200241d0006a10ae030240024020022802200d00200041003602200c010b2000200241d00010f6041a0b02402001450d002003102e0b200241f0006a24000f0b410e4101102c000b91880103037f027e037f024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002d00002202410e4b0d0002400240024002400240024002400240024002400240024002400240024020020e0f000102030405060708090a0b0c0d0e000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5b20024101742204200320032004491b22044100480d5b0240024020020d002004102921030c010b200128020020022004102a21030b2003450d1020012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a0000200141046a280200210320042802002102024020002d00014101460d000240024020032002460d00200128020021000c010b200241016a22002002490d5c20024101742203200020002003491b22034100480d5c0240024020020d002003102921000c010b200128020020022003102a21000b2000450d1220012000360200200141046a2003360200200141086a28020021020b200141086a200241016a360200200020026a41003a00000f0b0240024020032002460d00200128020021000c010b200241016a22002002490d5b20024101742203200020002003491b22034100480d5b0240024020020d002003102921000c010b200128020020022003102a21000b2000450d1220012000360200200141046a2003360200200141086a28020021020b200141086a200241016a360200200020026a41013a00000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5a20024101742204200320032004491b22044100480d5a0240024020020d002004102921030c010b200128020020022004102a21030b2003450d1220012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41013a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d5a20024101742204200320032004491b22044100480d5a0240024020020d002004102921030c010b200128020020022004102a21030b2003450d1320012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a0000200041086a2001104a2000280204210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d5a20024101742200200420042000491b22004100480d5a0240024020020d002000102921020c010b200128020020022000102a21020b2002450d1420012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5920024101742204200320032004491b22044100480d590240024020020d002004102921030c010b200128020020022004102a21030b2003450d1420012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41023a000020002d0008220241024b0d0c02400240024020020e03000102000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5b20024101742204200320032004491b22044100480d5b0240024020020d002004102921030c010b200128020020022004102a21030b2003450d1720012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a0000200041096a2001104a200041386a29030021052000290330210602400240200141046a2802002202200428020022006b4110490d00200128020021020c010b200041106a22032000490d5b20024101742200200320032000491b22004100480d5b0240024020020d002000102921020c010b200128020020022000102a21020b2002450d1820012002360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200220006a22012005370008200120063700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5a20024101742204200320032004491b22044100480d5a0240024020020d002004102921030c010b200128020020022004102a21030b2003450d1820012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a0000200041096a2001104a0f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5920024101742204200320032004491b22044100480d590240024020020d002004102921030c010b200128020020022004102a21030b2003450d1820012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41023a0000200041096a2001104a200041296a2001104a200041d8006a29030021052000290350210602400240200141046a2802002203200428020022026b4110490d00200128020021030c010b200241106a22042002490d5920034101742202200420042002491b22024100480d590240024020030d002002102921030c010b200128020020032002102a21030b2003450d1920012003360200200141046a2002360200200141086a28020021020b200141086a2204200241106a360200200320026a2202200537000820022006370000200041e8006a29030021052000290360210602400240200141046a2802002202200428020022006b4110490d00200128020021020c010b200041106a22032000490d5920024101742200200320032000491b22004100480d590240024020020d002000102921020c010b200128020020022000102a21020b2002450d1a20012002360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200220006a22012005370008200120063700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5820024101742204200320032004491b22044100480d580240024020020d002004102921030c010b200128020020022004102a21030b2003450d1a20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41033a000020002d0008220241024b0d0b02400240024020020e03000102000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5a20024101742204200320032004491b22044100480d5a0240024020020d002004102921030c010b200128020020022004102a21030b2003450d1d20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a0000200041186a29030021052000290310210602400240200141046a2802002202200428020022006b4110490d00200128020021020c010b200041106a22032000490d5a20024101742200200320032000491b22004100480d5a0240024020020d002000102921020c010b200128020020022000102a21020b2002450d1e20012002360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200220006a22012005370008200120063700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5920024101742204200320032004491b22044100480d590240024020020d002004102921030c010b200128020020022004102a21030b2003450d1e20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41013a0000200041096a2001104a200028022c210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d5920024101742200200420042000491b22004100480d590240024020020d002000102921020c010b200128020020022000102a21020b2002450d1f20012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5820024101742204200320032004491b22044100480d580240024020020d002004102921030c010b200128020020022004102a21030b2003450d1f20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41023a0000200041096a2001104a200041386a29030021052000290330210602400240200141046a2802002202200428020022006b4110490d00200128020021020c010b200041106a22032000490d5820024101742200200320032000491b22004100480d580240024020020d002000102921020c010b200128020020022000102a21020b2002450d2020012002360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200220006a22012005370008200120063700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5720024101742204200320032004491b22044100480d570240024020020d002004102921030c010b200128020020022004102a21030b2003450d2020012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41043a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d5720024101742204200320032004491b22044100480d570240024020020d002004102921030c010b200128020020022004102a21030b2003450d2120012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a00002000280204210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d5720024101742200200420042000491b22004100480d570240024020020d002000102921020c010b200128020020022000102a21020b2002450d2220012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a2207280200200141086a22032802002202460d00200128020021040c010b200241016a22042002490d5620024101742208200420042008491b22084100480d560240024020020d002008102921040c010b200128020020022008102a21040b2004450d2220012004360200200141046a2008360200200141086a28020021020b2003200241016a360200200420026a41053a000020002d00082202410a4b0d090240024002400240024002400240024002400240024020020e0b000102030405060708090a000b02400240200728020020032802002202460d00200128020021040c010b200241016a22042002490d6020024101742208200420042008491b22084100480d600240024020020d002008102921040c010b200128020020022008102a21040b2004450d2d20012004360200200141046a2008360200200141086a28020021020b2003200241016a360200200420026a41003a0000200028020c21080240024020072802002204200328020022026b4104490d00200128020021040c010b200241046a22092002490d6020044101742202200920092002491b22024100480d600240024020040d002002102921040c010b200128020020042002102a21040b2004450d2e20012004360200200141046a2002360200200141086a28020021020b2003200241046a360200200420026a2008360000200041186a2903002105200029031021060240024020072802002202200328020022006b4110490d00200128020021020c010b200041106a22042000490d6020024101742200200420042000491b22004100480d600240024020020d002000102921020c010b200128020020022000102a21020b2002450d2f20012002360200200141046a2000360200200141086a28020021000b2003200041106a360200200220006a22012005370008200120063700000f0b02400240200728020020032802002202460d00200128020021040c010b200241016a22042002490d5f20024101742208200420042008491b22084100480d5f0240024020020d002008102921040c010b200128020020022008102a21040b2004450d2f20012004360200200141046a2008360200200141086a28020021020b2003200241016a360200200420026a41013a0000200028020c21080240024020072802002204200328020022026b4104490d00200128020021040c010b200241046a22092002490d5f20044101742202200920092002491b22024100480d5f0240024020040d002002102921040c010b200128020020042002102a21040b2004450d3020012004360200200141046a2002360200200141086a28020021020b2003200241046a360200200420026a2008360000200041286a2903002105200029032021060240024020072802002204200328020022026b4110490d00200128020021030c010b200241106a22032002490d5f20044101742202200320032002491b22024100480d5f0240024020040d002002102921030c010b200128020020042002102a21030b2003450d3120012003360200200141046a2002360200200141086a28020021020b200141086a200241106a360200200320026a220220053700082002200637000020002802102102200041186a2802002200200110472000450d1220004105742100034020022001104a200241206a2102200041606a22000d000c130b0b02400240200728020020032802002200460d00200128020021020c010b200041016a22022000490d5e20004101742204200220022004491b22044100480d5e0240024020000d002004102921020c010b200128020020002004102a21020b2002450d3120012002360200200141046a2004360200200141086a28020021000b2003200041016a360200200220006a41023a00000f0b02400240200728020020032802002202460d00200128020021040c010b200241016a22042002490d5d20024101742208200420042008491b22084100480d5d0240024020020d002008102921040c010b200128020020022008102a21040b2004450d3120012004360200200141046a2008360200200141086a28020021020b2003200241016a360200200420026a41033a0000200028020c21080240024020072802002204200328020022026b4104490d00200128020021040c010b200241046a22092002490d5d20044101742202200920092002491b22024100480d5d0240024020040d002002102921040c010b200128020020042002102a21040b2004450d3220012004360200200141046a2002360200200141086a28020021020b2003200241046a360200200420026a200836000020002d0009220041024b0d1002400240024020000e03000102000b02400240200728020020032802002200460d00200128020021020c010b200041016a22022000490d5f20004101742204200220022004491b22044100480d5f0240024020000d002004102921020c010b200128020020002004102a21020b2002450d3520012002360200200141046a2004360200200141086a28020021000b2003200041016a360200200220006a41003a00000f0b02400240200728020020032802002200460d00200128020021020c010b200041016a22022000490d5e20004101742204200220022004491b22044100480d5e0240024020000d002004102921020c010b200128020020002004102a21020b2002450d3520012002360200200141046a2004360200200141086a28020021000b2003200041016a360200200220006a41013a00000f0b02400240200728020020032802002200460d00200128020021020c010b200041016a22022000490d5d20004101742204200220022004491b22044100480d5d0240024020000d002004102921020c010b200128020020002004102a21020b2002450d3520012002360200200141046a2004360200200141086a28020021000b2003200041016a360200200220006a41023a00000f0b02400240200728020020032802002202460d00200128020021040c010b200241016a22042002490d5c20024101742208200420042008491b22084100480d5c0240024020020d002008102921040c010b200128020020022008102a21040b2004450d3520012004360200200141046a2008360200200141086a28020021020b2003200241016a360200200420026a41043a0000200028020c21040240024020072802002202200328020022006b4104490d00200128020021020c010b200041046a22072000490d5c20024101742200200720072000491b22004100480d5c0240024020020d002000102921020c010b200128020020022000102a21020b2002450d3620012002360200200141046a2000360200200141086a28020021000b2003200041046a360200200220006a20043600000f0b02400240200728020020032802002202460d00200128020021040c010b200241016a22042002490d5b20024101742208200420042008491b22084100480d5b0240024020020d002008102921040c010b200128020020022008102a21040b2004450d3620012004360200200141046a2008360200200141086a28020021020b2003200241016a360200200420026a41053a0000200028020c21040240024020072802002202200328020022006b4104490d00200128020021020c010b200041046a22072000490d5b20024101742200200720072000491b22004100480d5b0240024020020d002000102921020c010b200128020020022000102a21020b2002450d3720012002360200200141046a2000360200200141086a28020021000b2003200041046a360200200220006a20043600000f0b02400240200728020020032802002202460d00200128020021040c010b200241016a22042002490d5a20024101742208200420042008491b22084100480d5a0240024020020d002008102921040c010b200128020020022008102a21040b2004450d3720012004360200200141046a2008360200200141086a28020021020b2003200241016a360200200420026a41063a0000200028020c21040240024020072802002202200328020022006b4104490d00200128020021020c010b200041046a22072000490d5a20024101742200200720072000491b22004100480d5a0240024020020d002000102921020c010b200128020020022000102a21020b2002450d3820012002360200200141046a2000360200200141086a28020021000b2003200041046a360200200220006a20043600000f0b02400240200728020020032802002202460d00200128020021040c010b200241016a22042002490d5920024101742208200420042008491b22084100480d590240024020020d002008102921040c010b200128020020022008102a21040b2004450d3820012004360200200141046a2008360200200141086a28020021020b2003200241016a360200200420026a41073a0000200028020c21080240024020072802002204200328020022026b4104490d00200128020021040c010b200241046a22092002490d5920044101742202200920092002491b22024100480d590240024020040d002002102921040c010b200128020020042002102a21040b2004450d3920012004360200200141046a2002360200200141086a28020021020b2003200241046a360200200420026a200836000002400240200728020020032802002202460d00200128020021040c010b200241016a22042002490d5920024101742207200420042007491b22074100480d590240024020020d002007102921040c010b200128020020022007102a21040b2004450d3a20012004360200200141046a2007360200200141086a28020021020b2003200241016a360200200420026a20002d00093a00000f0b02400240200728020020032802002202460d00200128020021030c010b200241016a22032002490d5820024101742204200320032004491b22044100480d580240024020020d002004102921030c010b200128020020022004102a21030b2003450d3a20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41083a0000200041096a2001104a200041296a2001104a0f0b02400240200728020020032802002202460d00200128020021030c010b200241016a22032002490d5720024101742204200320032004491b22044100480d570240024020020d002004102921030c010b200128020020022004102a21030b2003450d3a20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41093a0000200041096a2001104a0f0b02400240200728020020032802002202460d00200128020021040c010b200241016a22042002490d5620024101742207200420042007491b22074100480d560240024020020d002007102921040c010b200128020020022007102a21040b2004450d3a20012004360200200141046a2007360200200141086a28020021020b200141086a2207200241016a360200200420026a410a3a0000200041096a2001104a200041296a20011046200028024c210402400240200141046a2802002202200728020022006b4104490d00200128020021020c010b200041046a22072000490d5620024101742200200720072000491b22004100480d560240024020020d002000102921020c010b200128020020022000102a21020b2002450d3b20012002360200200141046a2000360200200141086a28020021000b2003200041046a360200200220006a20043600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5520024101742204200320032004491b22044100480d550240024020020d002004102921030c010b200128020020022004102a21030b2003450d3b20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41063a0000200041046a20011085020f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5420024101742204200320032004491b22044100480d540240024020020d002004102921030c010b200128020020022004102a21030b2003450d3b20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41073a0000200041046a20011085020f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5320024101742204200320032004491b22044100480d530240024020020d002004102921030c010b200128020020022004102a21030b2003450d3b20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41083a0000024002400240024020002d00040e0400010203000b02400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d5620024101742204200320032004491b22044100480d560240024020020d002004102921030c010b200128020020022004102a21030b2003450d3f20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41003a0000200041056a2001104a200041256a2001104a0f0b02400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d5520024101742204200320032004491b22044100480d550240024020020d002004102921030c010b200128020020022004102a21030b2003450d3f20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a0000200041056a2001104a0f0b02400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d5420024101742204200320032004491b22044100480d540240024020020d002004102921030c010b200128020020022004102a21030b2003450d3f20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41023a00002000280208210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d5420024101742200200420042000491b22004100480d540240024020020d002000102921020c010b200128020020022000102a21020b2002450d4020012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d5320024101742204200320032004491b22044100480d530240024020020d002004102921030c010b200128020020022004102a21030b2003450d4020012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41033a000020002802082102200041106a28020022032001104702402003450d0020034105742103034020022001104a200241206a2102200341606a22030d000b0b200028021421022000411c6a2802002200200110472000450d0620004105742100034020022001104a200241206a2102200041606a22000d000c070b0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5220024101742204200320032004491b22044100480d520240024020020d002004102921030c010b200128020020022004102a21030b2003450d4020012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41093a000020002d0001220041044b0d050240024002400240024020000e050001020304000b02400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d5620004101742203200220022003491b22034100480d560240024020000d002003102921020c010b200128020020002003102a21020b2002450d4520012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41003a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d5520004101742203200220022003491b22034100480d550240024020000d002003102921020c010b200128020020002003102a21020b2002450d4520012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41013a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d5420004101742203200220022003491b22034100480d540240024020000d002003102921020c010b200128020020002003102a21020b2002450d4520012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41023a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d5320004101742203200220022003491b22034100480d530240024020000d002003102921020c010b200128020020002003102a21020b2002450d4520012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41033a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d5220004101742203200220022003491b22034100480d520240024020000d002003102921020c010b200128020020002003102a21020b2002450d4520012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41043a00000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5120024101742204200320032004491b22044100480d510240024020020d002004102921030c010b200128020020022004102a21030b2003450d4520012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a410a3a00002000280204220241024b0d0402400240024020020e03000102000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5320024101742204200320032004491b22044100480d530240024020020d002004102921030c010b200128020020022004102a21030b2003450d4820012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a000020002802082102200041106a2802002200200110472000450d062002200041286c6a2109200141046a2107034020022001104a200241206a29030021050240024020072802002203200428020022006b4108490d00200128020021030c010b200041086a22082000490d5420034101742200200820082000491b22004100480d540240024020030d002000102921030c010b200128020020032000102a21030b2003450d4a2001200336020020072000360200200428020021000b2004200041086a360200200320006a20053700002009200241286a2202470d000c070b0b02400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d5220004101742203200220022003491b22034100480d520240024020000d002003102921020c010b200128020020002003102a21020b2002450d4920012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41013a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d5120004101742203200220022003491b22034100480d510240024020000d002003102921020c010b200128020020002003102a21020b2002450d4920012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41023a00000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5020024101742204200320032004491b22044100480d500240024020020d002004102921030c010b200128020020022004102a21030b2003450d4920012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a410b3a000020002d0008220241044b0d030240024002400240024020020e050001020304000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5420024101742204200320032004491b22044100480d540240024020020d002004102921030c010b200128020020022004102a21030b2003450d4e20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a0000200028020c210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d5420024101742200200420042000491b22004100480d540240024020020d002000102921020c010b200128020020022000102a21020b2002450d4f20012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5320024101742204200320032004491b22044100480d530240024020020d002004102921030c010b200128020020022004102a21030b2003450d4f20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41013a0000200041186a29030021052000290310210602400240200141046a2802002202200428020022006b4110490d00200128020021020c010b200041106a22032000490d5320024101742200200320032000491b22004100480d530240024020020d002000102921020c010b200128020020022000102a21020b2002450d5020012002360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200220006a22012005370008200120063700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d5220024101742204200320032004491b22044100480d520240024020020d002004102921030c010b200128020020022004102a21030b2003450d5020012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41023a0000200028022c210702400240200141046a2802002203200428020022026b4104490d00200128020021030c010b200241046a22042002490d5220034101742202200420042002491b22024100480d520240024020030d002002102921030c010b200128020020032002102a21030b2003450d5120012003360200200141046a2002360200200141086a28020021020b200141086a2204200241046a360200200320026a2007360000200041386a29030021052000290330210602400240200141046a2802002203200428020022026b4110490d00200128020021030c010b200241106a22042002490d6920034101742202200420042002491b22024100480d690240024020030d002002102921030c010b200128020020032002102a21030b2003450d5320012003360200200141046a2002360200200141086a28020021020b200141086a200241106a360200200320026a2202200537000820022006370000200041096a2001104a0f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6820024101742204200320032004491b22044100480d680240024020020d002004102921030c010b200128020020022004102a21030b2003450d5320012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a0000200041186a29030021052000290310210602400240200141046a2802002202200428020022006b4110490d00200128020021020c010b200041106a22032000490d6820024101742200200320032000491b22004100480d680240024020020d002000102921020c010b200128020020022000102a21020b2002450d5420012002360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200220006a22012005370008200120063700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6720024101742204200320032004491b22044100480d670240024020020d002004102921030c010b200128020020022004102a21030b2003450d5420012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41043a0000200041186a29030021052000290310210602400240200141046a2802002202200428020022006b4110490d00200128020021020c010b200041106a22032000490d6720024101742200200320032000491b22004100480d670240024020020d002000102921020c010b200128020020022000102a21020b2002450d5520012002360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200220006a22012005370008200120063700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6620024101742204200320032004491b22044100480d660240024020020d002004102921030c010b200128020020022004102a21030b2003450d5520012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a410c3a000020002d0008220241054b0d0202400240024002400240024020020e06000102030405000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6b20024101742204200320032004491b22044100480d6b0240024020020d002004102921030c010b200128020020022004102a21030b2003450d5b20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a0000200041096a2001104a200041296a2001104a200041d8006a29030021052000290350210602400240200141046a2802002202200428020022006b4110490d00200128020021020c010b200041106a22032000490d6b20024101742200200320032000491b22004100480d6b0240024020020d002000102921020c010b200128020020022000102a21020b2002450d5c20012002360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200220006a22012005370008200120063700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6a20024101742204200320032004491b22044100480d6a0240024020020d002004102921030c010b200128020020022004102a21030b2003450d5c20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a0000200041096a2001104a200041296a2001104a0f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6920024101742204200320032004491b22044100480d690240024020020d002004102921030c010b200128020020022004102a21030b2003450d5c20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41023a0000200041096a200110460f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6820024101742204200320032004491b22044100480d680240024020020d002004102921030c010b200128020020022004102a21030b2003450d5c20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a0000200028020c210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d6820024101742200200420042000491b22004100480d680240024020020d002000102921020c010b200128020020022000102a21020b2002450d5d20012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6720024101742204200320032004491b22044100480d670240024020020d002004102921030c010b200128020020022004102a21030b2003450d5d20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41043a0000200041096a2001104a02400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d6720024101742204200320032004491b22044100480d670240024020020d002004102921030c010b200128020020022004102a21030b2003450d5e20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20002d00293a00000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6620024101742204200320032004491b22044100480d660240024020020d002004102921030c010b200128020020022004102a21030b2003450d5e20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41053a0000200041096a2001104a200028022c2107200041346a28020022002001104702400240200141046a2802002203200428020022026b2000490d00200128020021030c010b200220006a22042002490d6620034101742202200420042002491b22024100480d660240024020030d002002102921030c010b200128020020032002102a21030b2003450d5f20012003360200200141046a2002360200200141086a28020021020b200141086a200220006a360200200320026a2007200010f6041a0f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6520024101742204200320032004491b22044100480d650240024020020d002004102921030c010b200128020020022004102a21030b2003450d5f20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a410d3a0000200041026a2103200141046a280200210720042802002102024020002d00014101460d000240024020072002460d00200128020021000c010b200241016a22002002490d6620024101742204200020002004491b22044100480d660240024020020d002004102921000c010b200128020020022004102a21000b2000450d6120012000360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200020026a41003a000002400240200141046a28020020042802002200460d00200128020021020c010b200041016a22022000490d6620004101742204200220022004491b22044100480d660240024020000d002004102921020c010b200128020020002004102a21020b2002450d6220012002360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200220006a20032d00003a00000f0b0240024020072002460d00200128020021000c010b200241016a22002002490d6520024101742204200020002004491b22044100480d650240024020020d002004102921000c010b200128020020022004102a21000b2000450d6220012000360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200020026a41013a000020032001104a0f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d6420024101742204200320032004491b22044100480d640240024020020d002004102921030c010b200128020020022004102a21030b2003450d6220012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a410e3a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d6420024101742204200320032004491b22044100480d640240024020020d002004102921030c010b200128020020022004102a21030b2003450d6320012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41003a0000200041016a2001104a0b0f0b20044101102c000b20034101102c000b20034101102c000b20044101102c000b20044101102c000b20004101102c000b20044101102c000b20044101102c000b20004101102c000b20044101102c000b20044101102c000b20024101102c000b20004101102c000b20044101102c000b20044101102c000b20004101102c000b20044101102c000b20004101102c000b20044101102c000b20004101102c000b20044101102c000b20044101102c000b20004101102c000b20084101102c000b20084101102c000b20024101102c000b20004101102c000b20084101102c000b20024101102c000b20024101102c000b20044101102c000b20084101102c000b20024101102c000b20044101102c000b20044101102c000b20044101102c000b20084101102c000b20004101102c000b20084101102c000b20004101102c000b20084101102c000b20004101102c000b20084101102c000b20024101102c000b20074101102c000b20044101102c000b20044101102c000b20074101102c000b20004101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20004101102c000b20044101102c000b20044101102c000b20034101102c000b20034101102c000b20034101102c000b20034101102c000b20034101102c000b20044101102c000b20044101102c000b20004101102c000b20034101102c000b20034101102c000b20044101102c000b20044101102c000b20004101102c000b20044101102c000b20004101102c000b20044101102c000b20024101102c000b102d000b20024101102c000b20044101102c000b20004101102c000b20044101102c000b20004101102c000b20044101102c000b20044101102c000b20004101102c000b20044101102c000b20044101102c000b20044101102c000b20004101102c000b20044101102c000b20044101102c000b20044101102c000b20024101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b102d000ba41201047f02400240024002400240024002400240024002400240024002400240024020002d0000220241054b0d0002400240024002400240024020020e06000102030405000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d1420024101742204200320032004491b22044100480d140240024020020d002004102921030c010b200128020020022004102a21030b2003450d0720012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a0000200041016a2001104a2000280244210502400240200141046a2802002203200428020022026b4104490d00200128020021030c010b200241046a22042002490d1420034101742202200420042002491b22024100480d140240024020030d002002102921030c010b200128020020032002102a21030b2003450d0820012003360200200141046a2002360200200141086a28020021020b200141086a2204200241046a360200200320026a2005360000200041216a200110462000280248210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d1420024101742200200420042000491b22004100480d140240024020020d002000102921020c010b200128020020022000102a21020b2002450d0920012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d1320024101742204200320032004491b22044100480d130240024020020d002004102921030c010b200128020020022004102a21030b2003450d0920012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41013a0000200041016a2001104a200041216a2001104602400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1320024101742204200320032004491b22044100480d130240024020020d002004102921030c010b200128020020022004102a21030b2003450d0a20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00413a00002000280244210502400240200141046a2802002203200428020022026b4104490d00200128020021030c010b200241046a22042002490d1320034101742202200420042002491b22024100480d130240024020030d002002102921030c010b200128020020032002102a21030b2003450d0b20012003360200200141046a2002360200200141086a28020021020b200141086a2204200241046a360200200320026a20053600002000280248210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d1320024101742200200420042000491b22004100480d130240024020020d002000102921020c010b200128020020022000102a21020b2002450d0c20012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d1220024101742204200320032004491b22044100480d120240024020020d002004102921030c010b200128020020022004102a21030b2003450d0c20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41023a0000200041016a200110460f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d1120024101742204200320032004491b22044100480d110240024020020d002004102921030c010b200128020020022004102a21030b2003450d0c20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41033a0000200041016a200110460f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d1020024101742204200320032004491b22044100480d100240024020020d002004102921030c010b200128020020022004102a21030b2003450d0c20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41043a0000200041016a2001104602400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1020024101742204200320032004491b22044100480d100240024020020d002004102921030c010b200128020020022004102a21030b2003450d0d20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20002d00213a00000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0f20024101742204200320032004491b22044100480d0f0240024020020d002004102921030c010b200128020020022004102a21030b2003450d0d20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41053a0000200041016a2001104602400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d0f20024101742204200320032004491b22044100480d0f0240024020020d002004102921030c010b200128020020022004102a21030b2003450d0e20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20002d00213a00000b0f0b20044101102c000b20024101102c000b20004101102c000b20044101102c000b20044101102c000b20024101102c000b20004101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b102d000b130020004102360204200041e0e2c5003602000b130020004101360204200041c8b5c2003602000b130020004103360204200041dc88c0003602000b130020004103360204200041d0e3c3003602000b130020004101360204200041f0dfc5003602000b13002000410b36020420004188c2c4003602000b13002000410636020420004184bac2003602000b13002000410436020420004194f5c0003602000b130020004105360204200041b09dc2003602000b1300200041033602042000418cdac5003602000b130020004105360204200041e0d4c0003602000b130020004106360204200041b49ec3003602000b130020004102360204200041b0c5c2003602000b130020004101360204200041f8d7c5003602000bcb0501027f4190ce002102410121030240024002400240024002400240024002400240024002400240024002400240024020012d00000e13001010100e010203040506090b0e0e0c0e0d0e000b417f2102200141086a280200417f6a220141054b0d0d4101210320010e060f0d090709090f0b41002103200141086a280200417f6a220141014b0d0d41c0843d2102024020010e020f000f0b4101210341a0c21e21020c0e0b41002103200141086a2d0000417f6a2201410d4b0d0c41a0c21e210202400240024020010e0e101000000101101001020a0a0a0a100b4180b51821020c0f0b41b0e32d21020c0e0b41f093092102410121030c0d0b4100210341f0930921020c0c0b41002103200141086a2d0000417f6a220141104b0d0a41c096b10221020240024002400240024020010e11101000000110101002020a0a0303030404100b41c09a0c21020c0f0b41a0c21e2102410121030c0e0b41c09a0c21020c0d0b41a08d0621020c0c0b41a0c21e21020c0b0b200141046a2d0000417f6a220141034b0d0841a08d0621024101210320010e040a0a01020a0b200141046a2d0000417f6a220141034b0d0741a08d0621024101210320010e0409090001090b41c096b1022102410121030c080b41c09a0c2102410121030c070b41002103200141086a280200417f6a220141094b0d0541a0cb980121020240024020010e0a08080800080102020202080b41d0a5cc0021020c070b4180ade20421020c060b4190ce002102410121030c050b41d086034190ce00200141046a2d0000411d7441808080807e6a411d75417f4a1b2102410021030c040b41002103200141086a280200417f6a220141024b0d0241a0c21e2102024020010e03040000040b41a08d062102410121030c030b41012103200141046a280200417f6a220141014b0d0041c0843d210220010e020200020b410021030b4190ce0021020b200020033a0004200020023602000bbff10108017f017e0f7f027e057f027e0b7f047e230041f0096b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e1300010203251e1d1c1b1a19180f0d0a09080706000b200141106a29030021042001410c6a280200210520022d0001210620022d000021020240024002400240024002400240024002400240200141086a28020022070e0700010203040607000b200341fc086a4101360200200342013702ec08200341cc91c5003602e8082003411c3602a407200341c491c5003602a0072003200341a0076a3602f808200341e8086a41949ec300106a000b41002108418df0c2004100200220067241ff01711b21094128210a4101210b0c380b2004a7210702400240200241ff01710d004101210b200641ff01714101460d010b41b5f0c2002109412a210a4101210b410021082007450d380c370b20070d020c330b4128210a4101210b0240200220067241ff0171450d00418df0c2002109410021080c370b410810292202450d0a2002200437000041a49ec300410a2002410810042002102e4100210841012106410121074101210c4101210d4101210e4101210f41012110410121110c100b2004a721070240200220067241ff0171450d00418df0c20021094128210a4101210b4100210820070d350c360b41ae9ec300410520052004422088a710044101210b2007450d310b2005102e0c300b2004422088a721092004a7210a0240200220067241ff0171450d0002402009450d00200941186c21082005210203400240200241046a280200450d002002280200102e0b0240200241106a280200450d002002410c6a280200102e0b200241186a2102200841686a22080d000b0b418df0c20021094101211241002113200a0d020c2f0b0240200941186c2202450d00200520026a21082005210203402002280200200241086a2802002002410c6a280200200241146a2802001004200241186a22022008470d000b0b02402009450d00200941186c21082005210203400240200241046a280200450d002002280200102e0b0240200241106a280200450d002002410c6a280200102e0b200241186a2102200841686a22080d000b0b41012112200a450d2d2005102e0c2d0b2004422088a721092004a7210a200220067241ff0171450d0102402009450d002009410c6c21082005210203400240200241046a280200450d002002280200102e0b2002410c6a2102200841746a22080d000b0b418df0c20021094100211241012113200a450d2d0b2005102e0c2c0b02402009410c6c2202450d00200520026a21082005210203402002280200200241086a28020010062002410c6a22022008470d000b0b02402009450d002009410c6c21082005210203400240200241046a280200450d002002280200102e0b2002410c6a2102200841746a22080d000b0b41012113200a450d292005102e0c290b418df0c20021094128210a4101210820022d000120022d0000720d0c024020012d0001220241ff01714102470d0041dfddc5004120109c011a410021094101210b0c300b41012108200320024101713a00e808200341c0066a41086a22024200370300200342003703c00641dfddc5004120200341c0066a100320034188086a41086a2002290300370300200320032903c0063703880820034188086a4110200341e8086a41011004410021094101210b0c2f0b41e9efc20021094124210a4101210820022d00000d0b20022d000141ff01714102470d0b200141086a2903002104200341c0066a41086a22024200370300200342003703c00641cde2c5004113200341c0066a100320034188086a41086a2002290300370300200320032903c0063703880820034188086a411041c8ecc500410041001005417f470d01200341186a41c5c1c200410d108101024002402003290320500d002003280218450d00200341086a41c5c1c200410d108101200329031042b8177c42b81720032802081b2004560d010b200341c0066a41086a22024200370300200342003703c00641c5c1c200410d200341c0066a100320034188086a41086a22062002290300370300200320032903c00637038808200320043703e80820034188086a4110200341e8086a4108100441012108200341013a00e80820024200370300200342003703c00641cde2c5004113200341c0066a100320062002290300370300200320032903c0063703880820034188086a4110200341e8086a41011004410021094101210b0c2f0b419cb9c2001058000b2001410c6a2802002108200141086a2802002105200141046a280200211041e9efc20021094124210a20022d00000d2520022d000141ff01714102470d25200341c0066a41086a22024200370300200342003703c00641d49bc5004117200341c0066a100320034188086a41086a2002290300370300200320032903c00637038808200341003602e80820034188086a4110200341e8086a10082102024002400240024020032802e8082206417f460d002002450d002006450d0120022d000021062002102e20064102460d002006410171450d0041e09ac2002109411c210a0c290b200341013a00e808200341c0066a41086a22024200370300200342003703c00641d49bc5004117200341c0066a100320034188086a41086a22062002290300370300200320032903c0063703880820034188086a4110200341e8086a41011004200341306a41b0f3c200410d107d200328023421072003280230210920024200370300200342003703c006419893c2004111200341c0066a100320062002290300370300200320032903c00637038808200341003602e80820034188086a4110200341e8086a100821020240024020032802e8082206417f460d002002450d00200320063602f403200320023602f003200341e8086a200341f0036a103d20032802e808220c450d0420032902ec0821042006450d012002102e0c010b4104210c420021040b02402004a72004422088a72202470d00200241016a22062002490d102002410174220a20062006200a491bad221442c4007e2215422088a70d102015a722064100480d100240024020020d0020061029210c0c010b200c200241c4006c2006102a210c0b200c450d0220044280808080708320148421040b200c200241c4006c6a220241003a000020022007410020091b360204200220032f01ec033b0001200241036a200341ec036a41026a2d00003a0000200220032902e808370208200241106a200341e8086a41086a2216290200370200200241186a200341e8086a41106a2217290200370200200241206a200341e8086a41186a290200370200200241286a200341e8086a41206a290200370200200241306a200341e8086a41286a290200370200200241386a200341e8086a41306a290200370200200241c0006a200341e8086a41386a28020036020020044280808080107c21042010200841f0006c6a210d024020080d00201021070c270b20034188086a417f6a210e200341bb066a2113200341ff066a2112200341c3076a210b200341a0076a41186a211820102107024003402007280204210220072802002108200341e8086a200741086a41e80010f6041a200741f0006a21072002450d28200341f0036a200341e8086a41e80010f6041a200320023602ec08200320083602e8082016200341f0036a41e80010f6041a200341286a41b0f3c200410d107d20032802282108200328022c210620034188086a200341e8086a10960202400240024020032802e80822020d0041929bc20021094110210a0c010b024020022006410020081b22084d0d00411a210a41a29bc20021090c010b200341a0076a2002417f6a10ba010240200341a0076a2017412010f804450d004119210a41bc9bc20021090c010b024020032802e808220941002008417b6a2202200220084b1b4f0d004126210a41d59bc20021090c010b200c210202400240200c2004422088a7220f41c4006c22116a2206200c6b41cd01490d00200c21020340024020022d00004101470d00200241016a2108200e2002460d03200820034188086a412010f804450d030b0240200241c4006a2d00004101470d00200241c5006a2108200b2002460d03200820034188086a412010f804450d030b024020024188016a2d00004101470d0020024189016a210820122002460d03200820034188086a412010f804450d030b0240200241cc016a2d00004101470d00200241cd016a210820132002460d03200820034188086a412010f804450d030b200620024190026a22026b41cc014b0d000b0b024020022006460d000340024020022d00004101470d00200241016a2108200e2002460d03200820034188086a412010f804450d030b2006200241c4006a2202470d000b0b410021080b200341a0076a200910ba01200341a0076a20034188086a412010f8042102200341c0056a41086a2206200341c0066a41086a290300370300200341c0056a41106a200341c0066a41106a290300370300200320032903c0063703c00541fc9ac20021094116210a20080d2920020d010c290b200341c0056a41086a200341c0066a41086a290300370300200341c0056a41106a200341c0066a41106a290300370300200320032903c0063703c0050c280b200341a0066a410e6a2209200341c0056a410e6a290100370100200341a0066a41086a220a2006290300370300200320032903c0053703a00620034188086a200341e8086a10960220184200370300200341a0076a41106a22064200370300200341a0076a41086a22084200370300200342003703a007024041c80010292202450d00200341f8046a1088012002410236022020024101360244200241186a200341f8046a41186a290300370200200241106a200341f8046a41106a290300370200200241086a200341f8046a41086a290300370200200220032903f804370200200220032903a0073700242002412c6a2008290300370000200241346a20062903003700002002413c6a2018290300370000200320023602c00620034282808080203702c406200341c0066a109702200341d8046a41086a220620034188086a41086a290300370300200341d8046a41106a221920034188086a41106a290300370300200341d8046a41186a221a20034188086a41186a2903003703002008200a290300370300200341a0076a410e6a220a200929010037010020032003290388083703d804200320032903a0063703a00702402004a7200f470d00200f41016a2202200f490d13200f4101742209200220022009491bad221442c4007e2215422088a70d132015a722024100480d1302400240200f0d0020021029210c0c010b200c20112002102a210c0b200c450d0320044280808080708320148421040b200c20116a220241013a00002006290300211420192903002115201a290300211b20032903d804211c20024116360028200241fc9ac200360024200241003a0021200241196a201b370000200241116a2015370000200241096a20143700002002201c3700012002413a6a200a290100370000200241346a2008290300370000200220032903a00737002c024020032802f4082208450d0020032802ec082102200841246c210803400240024020022d0000220641034b0d0002400240024020060e0404000102040b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022008415c6a22080d000b0b024020032802f008450d0020032802ec08102e0b20044280808080107c21042007200d470d010c2a0b0b41c8004104102c000b20024104102c000b41eff0c200413320034198056a4184f4c2001053000b20064104102c000b41eff0c200413320034198056a4184f4c2001053000b41d4b8c2001058000b41084101102c000b200341f0036a200141046a220841e40010f6041a4124210a200141246a280200210b200141206a28020021192001411c6a280200210f200141186a2802002111200141146a2802002110200141106a28020021052001410c6a2802002118200141086a280200211a20082802002108200341d8076a200341cc046a290200370300200341d0076a200341c4046a290200370300200341c8076a200341bc046a290200370300200341a0076a41206a200341b4046a290200370300200341a0076a41186a200341ac046a290200370300200341a0076a41106a200341a4046a290200370300200341a0076a41086a2003419c046a29020037030020032003290294043703a00741e9efc20021090240024020022d00000d0020022d000141ff01714102470d00200341c0036a41b8dfc5004114107d41c9dbc1002109411b210a20032802c403410020032802c0031b2019470d0020034188086a201910f6012003200b3602c006200341f8046a41186a22024200370300200341f8046a41106a22064200370300200341f8046a41086a22074200370300200342003703f804200341c0066a4104200341f8046a1000200341e8086a41186a2002290300370300200341e8086a41106a2006290300370300200341e8086a41086a2007290300370300200320032903f8043703e8080240024002400240024002400240024002400240200328028c08220720032802900822066b4120490d00200641206a210920032802880821020c010b200641206a22092006490d1420074101742202200920092002491b220c4100480d140240024020070d00200c102921020c010b2003280288082007200c102a21020b2002450d012003200c36028c082003200236028808200c21070b200220066a220620032903e808370000200641186a200341e8086a41186a290300370000200641106a200341e8086a41106a290300370000200641086a200341e8086a41086a2206290300370000410021132002200941c8ecc500410041001005210902402007450d002002102e0b200341c0066a41086a22024200370300200342003703c0064183d9c500410d200341c0066a100320062002290300370300200320032903c0063703e80820034188086a200341e8086a1098020240024020032802880822120d0041012112410021020c010b20034190086a2802002102200328028c0821130b2009417f470d062012200b4105746a41002002200b4b1b2216450d06200341003602f008200342013703e808410410292202450d0120034284808080c0003702ec08200320023602e808200220083600002005200341e8086a10470240024020032802ec08220820032802f00822026b2005490d0020032802e80821080c010b200220056a22062002490d1420084101742207200620062007491b22064100480d140240024020080d002006102921080c010b20032802e80820082006102a21080b2008450d03200320063602ec08200320083602e8080b2003200220056a3602f008200820026a201a200510f6041a200f200341e8086a10472010200f410c6c6a210e200f450d032010210803402008280200210c200841086a2802002202200341e8086a10470240024020032802ec08220720032802f00822066b2002490d0020032802e80821090c010b200620026a22092006490d152007410174220d20092009200d491b220d4100480d150240024020070d00200d102921090c010b20032802e8082007200d102a21090b2009450d062003200d3602ec08200320093602e808200d21070b2003200620026a220d3602f008200920066a200c200210f6041a2008410c6a2208200e470d000c060b0b200c4101102c000b41044101102c000b20064101102c000b20032802ec08210720032802f008210d0c010b200d4101102c000b024002400240024002400240024002402007200d6b4104490d00200d41046a210820032802e80821020c010b200d41046a2208200d490d1420074101742202200820082002491b22064100480d140240024020070d002006102921020c010b20032802e80820072006102a21020b2002450d01200320063602ec08200320023602e808200621070b200320083602f0082002200d6a201936000002400240200720086b41034d0d00200721060c010b200841046a22062008490d1420074101742209200620062009491b22064100480d140240024020070d002006102921020c010b200220072006102a21020b2002450d02200320063602ec08200320023602e8080b200220086a200b3600002002200841046a200341a0076a2016100c210802402006450d002002102e0b024020080d00200341f1086a201641086a290000370000200341f9086a201641106a29000037000020034181096a201641186a2900003700002003410e3a00e808200320162900003700e90841c8ecc5004100200341e8086a1072200341003602f008200342013703e8082005200341e8086a10470240024020032802ec08220820032802f00822026b2005490d0020032802e80821080c010b200220056a22062002490d1520084101742207200620062007491b22064100480d150240024020080d002006102921080c010b20032802e80820082006102a21080b2008450d04200320063602ec08200320083602e8080b2003200220056a3602f008200820026a201a200510f6041a200f200341e8086a1047200f450d042010210803402008280200210a200841086a2802002202200341e8086a10470240024020032802ec08220920032802f00822066b2002490d0020032802e80821070c010b200620026a22072006490d162009410174220c20072007200c491b220c4100480d160240024020090d00200c102921070c010b20032802e8082009200c102a21070b2007450d072003200c3602ec08200320073602e808200c21090b2003200620026a220c3602f008200720066a200a200210f6041a2008410c6a2208200e470d000c070b0b41e4dbc10021092013450d082012102e0c080b20064101102c000b20064101102c000b20064101102c000b20032802f008210c20032802ec08210920032802e80821070c010b200c4101102c000b20034188086a201910f6012003200b3602c006200341f8046a41186a22024200370300200341f8046a41106a22084200370300200341f8046a41086a22064200370300200342003703f804200341c0066a4104200341f8046a1000200341e8086a41186a2002290300370300200341e8086a41106a2008290300370300200341e8086a41086a2006290300370300200320032903f8043703e80802400240200328028c08220a20032802900822086b4120490d0020032802880821020c010b200841206a22022008490d0e200a4101742206200220022006491b22064100480d0e02400240200a0d002006102921020c010b200328028808200a2006102a21020b2002450d022003200636028c0820032002360288082006210a0b200220086a220620032903e808370000200641186a200341e8086a41186a290300370000200641106a200341e8086a41106a290300370000200641086a200341e8086a41086a2903003700002003200841206a3602ec08200320023602e8082007200c200341e8086a1099020240200a450d002002102e0b2009450d002007102e0b02402013450d002012102e0b02402018450d00201a102e0b0240200f450d00200f410c6c21082010210203400240200241046a280200450d002002280200102e0b2002410c6a2102200841746a22080d000b0b4100210902402011450d002010102e0b0c020b20064101102c000b02402018450d00201a102e0b0240200f450d00200f410c6c21082010210203400240200241046a280200450d002002280200102e0b2002410c6a2102200841746a22080d000b0b2011450d002010102e0b4100211a410121084101210b41012106410121074101210c4101210d4101210e4101210f410121104101211141012118410121190c340b2002411a6a2901002104200241196a2d00002107200241186a2d0000210c200241166a2f0100210d200241156a2d0000210e200241146a2d0000210f200241126a2f01002110200241116a2d00002111200241106a2d000021182002410e6a2f010021192002410d6a2d0000211a2002410c6a2d0000210b2002410a6a2f01002105200241096a2d00002112200241086a2d00002113200241066a2f01002116200241056a2d00002117200241046a2d0000211d200241026a2f0100211e200141086a280200210620022d0001210820022d00002102024002400240024002400240200141046a2802000e03000102000b200341e8086a41146a4101360200200342013702ec08200341cc91c5003602e8082003411c3602a407200341c491c5003602a0072003200341a0076a3602f808200341e8086a41c8e6c200106a000b41b5f0c2002109412a210a200241ff01710d02200841ff01714101470d02200320043703b807200320073a00b7072003200c3a00b6072003200d3b01b4072003200e3a00b3072003200f3a00b207200320103b01b007200320113a00af07200320183a00ae07200320193b01ac072003201a3a00ab072003201d3a00a2072003201e3b01a00720032005410874200b411874722012723600a707200320164108742017722013411874723600a307200341c0066a41086a22024200370300200342003703c00641fae6c2004108200341c0066a100320034188086a41086a2002290300370300200320032903c00637038808200341e8086a20034188086a411010dc010240024020032d00e8084101460d00200341f0036a41186a4200370300200341f0036a41106a4200370300200341f0036a41086a4200370300200342003703f0030c010b200341f0036a41186a20034181096a290000370300200341f0036a41106a200341f9086a290000370300200341f0036a41086a200341f1086a290000370300200320032900e9083703f0030b0240200341a0076a200341f0036a412010f804450d0041d8e6c20021094122210a0c030b200341e8086a200641880110f6041a41002119200341003b01f003200341b8036a200341e8086a200341f0036a1095024101210841012102024020032802b8032207450d00200720032802bc031009410021020b200320023a00ea082003410d3b01e80841c8ecc5004100200341e8086a10722006102e0c010b02400240200241ff01710d00200841ff01714101460d010b41b5f0c2002109412a210a0c030b200141216a2900002114200141206a2d000021092001411f6a2d0000210a2001411d6a2f0000211f2001411c6a2d000021202001411b6a2d00002121200141196a2f00002122200141186a2d00002123200141176a2d00002124200141156a2f00002125200141146a2d00002126200141106a28020021272001410c6a2802002108200320043703b807200320073a00b7072003200c3a00b6072003200d3b01b4072003200e3a00b3072003200f3a00b207200320103b01b007200320113a00af07200320183a00ae07200320193b01ac072003201a3a00ab072003201d3a00a2072003201e3b01a00720032005410874201272200b411874723600a707200320164108742017722013411874723600a307200341c0066a41086a22024200370300200342003703c00641fae6c2004108200341c0066a100320034188086a41086a2002290300370300200320032903c00637038808200341e8086a20034188086a411010dc010240024020032d00e8084101460d00200341f0036a41186a4200370300200341f0036a41106a4200370300200341f0036a41086a4200370300200342003703f0030c010b200341f0036a41186a20034181096a290000370300200341f0036a41106a200341f9086a290000370300200341f0036a41086a200341f1086a290000370300200320032900e9083703f0030b0240200341a0076a200341f0036a412010f804450d004182e7c20021094131210a0c030b02400240200641ff01714101460d0020064118762107200641087621020c010b200341e8086a200841067610bb0120032802e80821060240024020032802f0082008413f7122024b0d004100210c0c010b200620024105746a2202290018211420022d0017210920022d0016210a20022f0014211f20022d0013212020022d0012212120022f0010212220022d000f212320022d000e212420022f000c212520022d000b2126200228000721272002280003210820022d0002210720022f000021024101210c0b024020032802ec08450d002006102e0b200c0d0041ccc4c20021094115210a0c030b200341c0066a41086a22064200370300200342003703c00641fae6c2004108200341c0066a100320034188086a41086a2006290300370300200320032903c00637038808200341e8086a20034188086a411010dc010240024020032d00e8084101460d0020034190056a4200370300200341f8046a41106a4200370300200341f8046a41086a4200370300200342003703f8040c010b20034190056a20034181096a290000370300200341f8046a41106a200341f9086a290000370300200341f8046a41086a200341f1086a290000370300200320032900e9083703f8040b200341d8046a41086a200341f8046a41086a2903002204370300200341d8046a41106a200341f8046a41106a2903002215370300200341d8046a41186a200341f8046a41186a290300221b370300200320032903f804221c3703d804200341f2086a2004370100200341fa086a201537010020034182096a201b3701002003418d023b01e8082003201c3701ea084100211941c8ecc5004100200341e8086a10722003201437038009200320093a00ff082003200a3a00fe082003201f3b01fc08200320203a00fb08200320213a00fa08200320223b01f808200320233a00f708200320243a00f608200320253b01f408200320263a00f308200320273600ef08200320083600eb08200320073a00ea08200320023b01e808200341c0066a41086a22024200370300200342003703c00641fae6c2004108200341c0066a100320034188086a41086a2002290300370300200320032903c00637038808200341103602f403200320034188086a3602f003200341e8086a200341f0036a109a02410121080b4101210b41012106410121074101210c4101210d4101210e4101210f4101211041012111410121180c290b2006102f2006102e0b41002119410121084101210b41012106410121074101210c4101210d4101210e4101210f4101211041012111410121184101211a0c330b200341e8086a200141086a41800110f6041a200341f0036a41206a200241206a290200370300200341f0036a41186a200241186a290200370300200341f0036a41106a200241106a290200370300200341f0036a41086a200241086a290200370300200320022902003703f003200341b0036a200341e8086a200341f0036a109b0220032802b403210a20032802b003210941002118410121084101210b41012106410121074101210c4101210d4101210e4101210f41012110410121110c310b200341d0036a41086a2209200141206a290300370300200341d0036a410d6a220d200141256a2900003700002003200141186a2903003703d003200241086a2802002107200241046a280200210c410e210a2001410c6a280200210820022d00002106024002400240024002400240024002400240024002400240024002400240024002400240200141086a2802000e0400010203000b200341e8086a41146a4101360200200342013702ec08200341cc91c5003602e8082003411c3602a407200341c491c5003602a0072003200341a0076a3602f808200341e8086a41d0f4c000106a000b200141386a2903002115200141306a29030021042002411a6a2901002114200241196a2d00002110200241186a2d00002111200241166a2f01002118200241156a2d00002119200241146a2d0000211a200241126a2f0100210b200241116a2d00002105200241106a2d000021122002410e6a2f010021132002410d6a2d000021162002410c6a2d00002117200241026a2f0100211d200141146a280200210f200141106a280200210e20022d0001210220034198056a41086a200929030037030020034198056a410d6a200d290000370000200320084118763a00b605200320084108763b01b405200320032903d0033703980541b5f0c2002109412a210a200641ff01710d27200241ff01714101470d272003201437038804200320103a008704200320113a008604200320183b018404200320193a0083042003201a3a0082042003200b3b018004200320053a00ff03200320123a00fe03200320133b01fc03200320163a00fb032003200c3a00f2032003201d3b01f00320032007411076410874200741087641ff0171722017411874723600f7032003200c411076410874200c41087641ff0171722007411874723600f303200341ec036a41026a220220032d00b6053a0000200320032f01b4053b01ec03200341e8086a41086a220620034198056a41086a290300370300200341e8086a410d6a220720034198056a410d6a29000037000020032003290398053703e8080240200841ff01714101460d00200341f8046a41026a20022d00003a0000200341a0066a41086a2006290300370300200341a0066a410d6a2007290000370000200320032f01ec033b01f804200320032903e8083703a0060c0f0b20034188086a200e41067610bb01200328028808210802400240200328029008200e413f7122024b0d00410021020c010b200341f8046a41026a200820024105746a220241026a2d00003a0000200341a8066a200241136a290000370300200341ad066a200241186a290000370000200320022f00003b01f8042003200229000b3703a0062002280007210f2002280003210e410121020b0240200328028c08450d002008102e0b20020d0e410121024115210f41ccc4c200210e0c0f0b41bbb7c2002109200641ff01714101470d2620074102490d26200c41ff01710d26411210292202450d03200241106a41002f00ffda403b0000200241086a41002900f7da40370000200241002900efda40370000200241124124102a2202450d0420022008360012200341f8046a41186a22084200370300200341f8046a41106a22064200370300200341f8046a41086a22074200370300200342003703f80420024116200341f8046a1000200341d8046a41186a2008290300370300200341d8046a41106a2006290300370300200341d8046a41086a2007290300370300200320032903f8043703d804200341e8086a200341d8046a10ae01024020032903e80842015222080d00200341d8046a412010060b20032802f0082106200341a0076a200341f4086a41dc0010f6041a024020080d0020034188086a200341a0076a41dc0010f6041a2002102e200341c0066a20034188086a41dc0010f6041a200320063602f003200341f0036a410472200341c0066a41dc0010f6041a200341a0036a20034190046a20032903800420034188046a290300109201200341a0036a41086a290300211520032903a0032104200341c0066a41086a22024200370300200342003703c00641c28cc0004116200341c0066a100320034188086a41086a22062002290300370300200320032903c0063703880820034188036a20034188086a10970120034188036a41106a2903002114200329039003211b200328028803210820024200370300200342003703c00641c28cc0004116200341c0066a100320062002290300370300200320032903c00637038808200342002014420020081b221420157d201b420020081b2215200454ad7d221b201520047d2204201556201b201456201b2014511b22021b3703f00820034200200420021b3703e80820034188086a4110200341e8086a411010040c250b2002102e0c010b41bbb7c2002109200641ff01714101470d2520074104490d25200c41ff01710d25411210292202450d04200241106a41002f00ffda403b0000200241086a41002900f7da40370000200241002900efda40370000200241124124102a2202450d0520022008360012200341f8046a41186a22064200370300200341f8046a41106a22074200370300200341f8046a41086a22094200370300200342003703f80420024116200341f8046a1000200341d8046a41186a2006290300370300200341d8046a41106a2007290300370300200341d8046a41086a2009290300370300200320032903f8043703d804200341d8046a412041c8ecc50041004100100521062002102e2006417f470d010b41faf4c00021094119210a410121084101210b0c340b200341c0066a41086a22024200370300200342003703c00641ae98c5004112200341c0066a100320034188086a41086a2002290300370300200320032903c00637038808200341003602e80820034188086a4110200341e8086a1008210620032802e8082207417f460d052006450d05200320073602f403200320063602f003200341e8086a200341f0036a104120032802e808220f450d04200341f0086a280200210220032802ec08210e02402007450d002006102e0b2002200e470d070c060b41124101102c000b41244101102c000b41124101102c000b41244101102c000b41eff0c200413320034198056a4184f4c2001053000b4100210e4104210f0b200e41016a2202200e490d0b200e4101742206200220022006491b220641ffffffff03712006470d0b200641027422024100480d0b02400240200e0d0020021029210f0c010b200f200e4102742002102a210f0b200f450d01200e21022006210e0b200f200241027422076a2008360200200341c0066a41086a22084200370300200342003703c00641ae98c5004112200341c0066a100320034188086a41086a2008290300370300200320032903c00637038808200341003602f008200342013703e808200241016a2208200341e8086a104702400240200820024f0d0020032802f008210a20032802ec08210920032802e80821080c010b410020032802f00822026b2106200741046a210c20032802ec082109200f210703402007280200210d02400240200920066a4104490d0020032802e80821080c010b200241046a22082002490d0d2009410174220a20082008200a491b220a4100480d0d0240024020090d00200a102921080c010b20032802e8082009200a102a21080b2008450d042003200a3602ec08200320083602e808200a21090b200741046a21072003200241046a220a3602f008200820026a200d3600002006417c6a2106200a2102200c417c6a220c0d000b0b20034188086a41102008200a100402402009450d002008102e0b41002109200e450d1a200f102e0c1a0b20024104102c000b200a4101102c000b200341d8046a41026a200341f8046a41026a2d00003a0000200341c0066a41086a200341a0066a41086a290300370300200341c0066a410d6a200341a0066a410d6a290000370000200320032f01f8043b01d804200320032903a0063703c006410021020b200341bc056a41026a2208200341d8046a41026a2d00003a0000200341c0056a41086a2206200341c0066a41086a290300370300200341c0056a41106a200341c0066a41106a290300370300200320032f01d8043b01bc05200320032903c0063703c00502402002450d00200f210a200e2109410121084101210b0c280b200341f0026a2004201542c0843d420010fc04200341e0026a20032903f0022214200341f0026a41086a290300221b42c0fb42427f10fb04200341d0026a2014201b42d08603420010fb04200341b8056a41026a20082d00003a0000200341a0076a41086a2006290300370300200341a0076a410d6a2208200341c0056a410d6a290000370000200320032f01bc053b01b805200320032903c0053703a00720034180036a200341f0036a20032903d002221b200420032903e0027c42148042ffffffff0f837c2214428080e983b1de162014428080e983b1de1656200341d0026a41086a2903002014201b54ad7c22144200522014501b22021b221b2014420020021b22141093010240200328028003450d0041e0f4c0002109411a210a410121084101210b0c280b200341c8026a419898c5004116107d20032802cc02210220032802c8022106200341c0066a41086a22074200370300200342003703c006419898c5004116200341c0066a100320034188086a41086a2007290300370300200320032903c0063703880820032002410020061b220941016a3602e80820034188086a4110200341e8086a41041004200341a0096a200341f0036a41186a29030037030020034198096a200341f0036a41106a29030037030020034190096a200341f0036a41086a290300370300200341aa096a200341ba056a2d00003a0000200341af096a200f360000200341ab096a200e360000200341b3096a20032903a007370000200341bb096a200341a0076a41086a290300370000200341c0096a2008290000370000200320153703f008200320043703e808200320032903f00337038809200320032f01b8053b01a809200341e8086a41186a20143703002003201b3703f8080240024002400240411210292202450d00200241106a41002f00ffda403b0000200241086a41002900f7da40370000200241002900efda40370000200241124124102a2206450d0120062009360012200341f8046a41186a22024200370300200341f8046a41106a22084200370300200341f8046a41086a22074200370300200342003703f80420064116200341f8046a1000200341d8046a41186a2002290300370300200341d8046a41106a2008290300370300200341d8046a41086a2007290300370300200320032903f8043703d8042003410036029008200342013703880820034188096a20034188086a104a200341e8086a41086a290300210420032903e808211402400240200328028c08220820032802900822026b4110490d0020032802880821080c010b200241106a22072002490d0b20084101742202200720072002491b22024100480d0b0240024020080d002002102921080c010b20032802880820082002102a21080b2008450d032003200236028c08200320083602880820032802900821020b200820026a22082004370008200820143700002003200241106a36029008200341a8096a20034188086a104a20034180096a290300210420032903f808211402400240200328028c08220720032802900822086b4110490d0020032802880821020c010b200841106a22022008490d0b20074101742208200220022008491b220a4100480d0b0240024020070d00200a102921020c010b2003280288082007200a102a21020b2002450d042003200a36028c0820032002360288082003280290082108200a21070b200220086a220a2004370008200a2014370000200341d8046a41202002200841106a100402402007450d002002102e0b2006102e200341f4086a200936020041002109200341f0086a41003a00002003410b3a00e80841c8ecc5004100200341e8086a10720c1a0b41124101102c000b41244101102c000b20024101102c000b200a4101102c000b200141086a2802002106200141046a28020021070240024020022d00000d004101210820022d000141ff01714101460d010b41b5f0c2002109412a210a41002111410121082006450d022007102e0c020b200241096a280000210a02402006450d002007102e0b410021114101210b41012106410121074101210c4101210d4101210e4101210f410121100b41012118410121194101211a410021090c2f0b4101210b41012106410121074101210c4101210d4101210e4101210f410121100c2c0b41e9efc20021094124210a4101210820022d00000d0020022d000141ff01714102470d00200141046a2802002102200341c0066a41086a22064200370300200342003703c00641fbd8c0004110200341c0066a100320034188086a41086a2006290300370300200320032903c00637038808024020034188086a411041c8ecc500410041001005417f470d00200341c0026a41b0f3c200410d107d024020032802c402410020032802c0021b2002490d00200341c0066a41086a22064200370300200342003703c00641fbd8c0004110200341c0066a100320034188086a41086a2006290300370300200320032903c00637038808200320023602e80820034188086a4110200341e8086a41041004410021094101210b0c250b41b4dac0001058000b41a0d9c0001058000b4101210b0c220b200341d8046a41026a2209200141076a2d00003a0000200341f0036a41086a220a2001411c6a290200370300200341f0036a41106a220d200141246a290200370300200341f0036a41186a2001412c6a29020037030020034190046a200141346a29020037030020034198046a2001413c6a290200370300200341a0046a200141c4006a2d00003a00002003200141056a2f00003b01d8042003200141146a2902003703f003200141086a28020021062001410c6a2802002107200141106a280200210820022f0001200241036a2d000041107472210e2002410c6a280200210f200241086a2802002110200241046a280200211120022d00002102024002400240024002400240024002400240024002400240024002400240200141046a2d0000220c0e050001020304000b200341e8086a41146a4101360200200342013702ec08200341cc91c5003602e8082003411c3602a407200341c491c5003602a0072003200341a0076a3602f808200341e8086a419cb4c200106a000b200341b7076a200a290300370000200341bf076a200d2d00003a0000200320032f01d8043b01a007200320083600ab07200320073600a707200320063600a307200320032903f0033700af07200320092d00003a00a207024002402002417f6a220841024b0d00024020080e03000102000b2010410174200f4d0d00201141ff0171450d010b2002200e7241ff0171450d0041d7b4c2002109410a210a410021080c130b200341c0066a41086a22024200370300200342003703c00641acb4c200411b200341c0066a1003200341e8086a41086a2002290300370300200320032903c0063703e8082003410036028808200341e8086a411020034188086a100821020240024002402003280288082208417f460d002002450d00200320083602c406200320023602c00620034188086a200341c0066a1030200328028808220a450d06200329028c08210402402008450d002002102e0b2003200a360288082003200437028c082004a7210e41002102024002402004422088a7220f41014b0d0041002109200f0e020301030b200f210803402008410176220920026a220d2002200a200d4105746a200341a0076a412010f8044101481b2102200820096b220841014b0d000b0b0240200a20024105746a200341a0076a412010f8042208450d002008411f7620026a2109200f21020c020b41c7b4c2002109200e450d02200a102e0c020b4100210e200341003602900820034201370388084101210a41002102410021090b200341e8086a41186a200341a0076a41186a290300370300200341e8086a41106a200341a0076a41106a290300370300200341e8086a41086a200341a0076a41086a290300370300200320032903a0073703e80802400240024020022009490d002002200e460d01200e210d0c020b41c0c6c5001058000b200e41016a2208200e490d0f200e410174220d20082008200d491b220d41ffffff3f71200d470d0f200d41057422084100480d0f02400240200e0d0020081029210a0c010b200a200e4105742008102a210a0b200a450d062003200d36028c082003200a360288080b200a20094105746a220841206a2008200220096b41057410f7041a200820032903e808370000200841186a200341e8086a41186a2209290300370000200841106a200341e8086a41106a220a290300370000200841086a200341e8086a41086a22082903003700002003200241016a3602900820034188086a109c022009200341a0076a41186a290300370300200a200341a0076a41106a2903003703002008200341a0076a41086a290300370300200320032903a0073703e8084100210941c8ecc50041002003280288082202200328029008109d02200341093b01e80841c8ecc5004100200341e8086a1072200d450d002002102e0b4110210a410021080c120b200341b7076a200a290300370000200341bf076a200d2d00003a0000200320032f01d8043b01a007200320083600ab07200320073600a707200320063600a307200320032903f0033700af07200320092d00003a00a207024002402002417f6a220841024b0d00024020080e03000102000b2010410174200f4d0d00201141ff0171450d010b2002200e7241ff0171450d0041d7b4c2002109410a210a410021080c120b200341c0066a41086a22024200370300200342003703c00641acb4c200411b200341c0066a1003200341e8086a41086a2002290300370300200320032903c0063703e8082003410036028808200341e8086a411020034188086a100821022003280288082208417f460d052002450d05200320083602c406200320023602c00620034188086a200341c0066a1030200328028808220d450d04200329028c08210402402008450d002002102e0b2003200d360288082003200437028c082004a7210f41002102024002400240024002402004422088a7220e41014b0d00200e0e020201020b200e210803402008410176220920026a220a2002200d200a4105746a200341a0076a412010f8044101481b2102200820096b220841014b0d000b0b200d20024105746a200341a0076a412010f804450d010b41e1b4c2002109200f0d010c120b2002200e4f0d07200d20024105746a2208200841206a2002417f73200e6a41057410f7041a2003200e417f6a22023602900820034188086a109c02200341e8086a41186a200341a0076a41186a290300370300200341e8086a41106a200341a0076a41106a290300370300200341e8086a41086a200341a0076a41086a290300370300200320032903a0073703e808200341e8086a4101200d2002109d0220034189023b01e8084100210941c8ecc5004100200341e8086a1072200f450d110b200d102e0c100b2003419f086a200a290300370000200341a7086a200d2d00003a0000200320032f01d8043b01880820032008360093082003200736008f082003200636008b08200320032903f00337009708200320092d00003a008a08200341a0076a41186a20034199046a290000370300200341a0076a41106a20034191046a290000370300200341a0076a41086a20034189046a29000037030020032003290081043703a007024002402002417f6a220841024b0d00024020080e03000102000b2010410174200f4d0d00201141ff0171450d010b2002200e7241ff0171450d0041d7b4c2002109410a210a410021080c110b0240024020034188086a200341a0076a412010f8040d00410021090c010b200341c0066a41086a22024200370300200342003703c00641acb4c200411b200341c0066a1003200341e8086a41086a2002290300370300200320032903c0063703e808200341003602c006200341e8086a4110200341c0066a1008210220032802c0062208417f460d082002450d08200320083602a406200320023602a006200341c0066a200341a0066a103020032802c006220f450d0720032902c406210402402008450d002002102e0b2003200f3602c005200320043702c4052004a7211141e1b4c2002109410c210a41002102024002402004422088a7221041014b0d0020100e021001100b2010210803402008410176220d20026a220e2002200f200e4105746a20034188086a412010f8044101481b21022008200d6b220841014b0d000b0b200f20024105746a220820034188086a412010f8040d0e200341f8046a41186a2209200341a0076a41186a290300370300200341f8046a41106a220a200341a0076a41106a290300370300200341f8046a41086a220d200341a0076a41086a290300370300200320032903a0073703f804200220104f0d09200820032903f804370000200841186a2009290300370000200841106a200a290300370000200841086a200d2903003700004101210841002102024020104101460d00410021022010210803402008410176220920026a220a2002200f200a4105746a200341a0076a412010f8044101481b2102200820096b220841014b0d000b201021080b0240200f20024105746a200341a0076a412010f8040d0041c7b4c20021094110210a0c0f0b200f2008105d200341c0056a109c02200341e8086a41186a20034188086a41186a290300370300200341e8086a41106a20034188086a41106a290300370300200341e8086a41086a20034188086a41086a29030037030020032003290388083703e808200341e8086a4101200f2010109d0220034189043b01e8084100210941c8ecc5004100200341e8086a10722011450d00200f102e0b0c0e0b024002402002417f6a220941024b0d00024020090e03000102000b2010410174200f4d0d00201141ff0171450d010b2002200e7241ff0171450d00410a210a41d7b4c200210920070d110c120b20062008105d200341c0066a41086a22024200370300200342003703c00641acb4c200411b200341c0066a1003200341e8086a41086a2002290300370300200320032903c0063703e808200341003602a007200341e8086a4110200341a0076a1008210220032802a0072209417f460d092002450d092003200936028c082003200236028808200341a0076a20034188086a103020032802a007220a450d08200341a8076a280200210d20032802a407210e02402009450d002002102e0b20062008200a200d109e02200e450d0b200a102e0c0b0b41eff0c200413320034198056a4184f4c2001053000b20084101102c000b41eff0c200413320034198056a4184f4c2001053000b2003410036029008200342013703880841e1b4c20021090c0a0b418080c0001058000b41eff0c200413320034198056a4184f4c2001053000b200341003602c805200342013703c005410c210a41e1b4c2002109410021080c080b41f0b4c200200220101038000b41eff0c200413320034198056a4184f4c2001053000b2006200841014100109e020c010b102d000b200341c0066a41086a22024200370300200342003703c00641acb4c200411b200341c0066a100320034188086a41086a2002290300370300200320032903c00637038808200341003602f008200342013703e8082008200341e8086a104702402008450d00200841057421082006210203402002200341e8086a104a200241206a2102200841606a22080d000b0b20032802ec08210220034188086a411020032802e808220820032802f008100402402002450d002008102e0b02402007450d002006102e0b20034189063b01e8084100210941c8ecc5004100200341e8086a1072410121080c030b2011450d00200f102e410021080c020b410021080c010b410c210a410021080b0240200c417f6a220241034b0d00024020020e0403030300030b200820074572450d010c020b200c4104490d012007450d010b2006102e0b41002110410121084101210b41012106410121074101210c4101210d4101210e4101210f0c200b200341e8086a41386a200141c0006a290300370300200341e8086a41306a200141386a290300370300200341e8086a41286a200141306a290300370300200341e8086a41206a200141286a290300370300200341e8086a41186a200141206a290300370300200341e8086a41106a200141186a290300370300200341e8086a41086a200141106a2903003703002003200141086a2903003703e808200341f0036a41206a200241206a290200370300200341f0036a41186a200241186a290200370300200341f0036a41106a200241106a290200370300200341f0036a41086a200241086a290200370300200320022902003703f003200341b8026a200341e8086a200341f0036a10d90120032802bc02210a20032802b80221094100210f410121084101210b41012106410121074101210c4101210d4101210e0c1e0b200341f0036a41206a200141246a290200370300200341f0036a41186a2001411c6a290200370300200341f0036a41106a200141146a290200370300200341f0036a41086a2001410c6a2902003703002003200141046a2902003703f003200341e8086a41206a200241206a290200370300200341e8086a41186a200241186a290200370300200341e8086a41106a200241106a290200370300200341e8086a41086a200241086a290200370300200320022902003703e808200341b0026a200341f0036a200341e8086a109f0220032802b402210a20032802b00221094100210e410121084101210b41012106410121074101210c4101210d0c1c0b200341f0036a41206a200141246a290200370300200341f0036a41186a2001411c6a290200370300200341f0036a41106a200141146a290200370300200341f0036a41086a2001410c6a2902003703002003200141046a2902003703f003200341e8086a41206a200241206a290200370300200341e8086a41186a200241186a290200370300200341e8086a41106a200241106a290200370300200341e8086a41086a200241086a290200370300200320022902003703e808200341a8026a200341f0036a200341e8086a10a00220032802ac02210a20032802a80221094100210d410121084101210b41012106410121074101210c0c1a0b200341e8086a41286a200141306a290300370300200341e8086a41206a200141286a290300370300200341e8086a41186a200141206a290300370300200341e8086a41106a200141186a290300370300200341e8086a41086a200141106a2903003703002003200141086a2903003703e808200341f0036a41206a200241206a290200370300200341f0036a41186a200241186a290200370300200341f0036a41106a200241106a290200370300200341f0036a41086a200241086a290200370300200320022902003703f003200341a0026a200341e8086a200341f0036a10a10220032802a402210a20032802a00221094100210c410121084101210b41012106410121070c180b200141086a280200211a200141046a280200210b200341e8086a2001410c6a41e40010f6041a2002411a6a2901002104200241196a2d0000210c200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002118200241106a2d000021192002410e6a2f010021052002410d6a2d000021122002410c6a2d000021132002410a6a2f01002116200241096a2d00002117200241086a2d0000211d200241066a2f0100211e200241056a2d0000211f200241046a2d00002120200241026a2f0100212120022d0001210a20022d00002107200341c0056a200341e8086a41046a41e00010f6041a4101210241b5f0c200210941002108412a2106024002402007450d00410021070c010b41002107200a41ff01714101470d00201e410874201f72201d411874722109410021022017210620162108201321070b200841ffff0371410874200641ff017172200741187472210a0240024020020d00200320043703a0082003200c3a009f082003200d3a009e082003200e3b019c082003200f3a009b08200320103a009a08200320113b019808200320183a009708200320193a009608200320053b019408200320123a0093082003200a36008f082003200936008b08200320203a008a08200320213b018808200341f0036a20034188086a10830202400240024002402003280290042202450d00200341a0076a41106a200341a8046a290300370300200341a0076a41086a200341a0046a290300370300200341a0076a41186a200341b0046a290300370300200341c0076a200341b8046a280200360200200341f8046a41086a2208200341ac076a290200370300200341f8046a41106a2206200341b4076a290200370300200341f8046a41186a2207200341bc076a290200370300200320034198046a2903003703a007200320032902a4073703f8040240200328029404450d002002102e0b200341a0066a41086a2008290300370300200341a0066a41106a2006290300370300200341a0066a41186a2007290300370300200320032903f8043703a006200341c0066a200341c0056a41e00010f6041a200341f8046a200341a0066a107720032802f80421022003280280052108200341003602f00320022008200341f0036a1008210820032802f0032206417f460d022008450d02200320063602dc04200320083602d804200341f0036a200341d8046a107820032d00f0034101460d0120034188086a200341f0036a41017241e00010f6041a02402006450d002008102e0b200341f0036a20034188086a41e00010f6041a200341013a00a007200341a0076a410172200341f0036a41e00010f6041a0c030b41a19ac20021094127210a0c030b41eff0c200413320034198056a4184f4c2001053000b200341003a00a0070b024020032802fc04450d002002102e0b200341c1076a2105200341e1076a2112200341c0066a41206a211820034180076a2119200341a0076a4101722113200341f0036a410172210a4104210941e7e485f30621080240024003400240024002400240200841e9dabdf30646220e0d000240200841e7e485f306470d00200341c0066a21070c020b200841e2c289ab06470d02201821070c010b201921070b0240412010292206450d0020062007290000370000200641186a200741186a290000370000200641106a200741106a290000370000200641086a200741086a290000370000412021024100210c0c020b41204101102c000b4101210c41c8ecc500210741002102410121060b200320023602940820032002360290082003200636028c082003200836028808200341f8046a20034188086a1079200341f0036a20032802f804220d20032802800510dc010240024020032d00f0034101470d00200341d8046a41186a220f200a41186a290000370300200341d8046a41106a2210200a41106a290000370300200341d8046a41086a2211200a41086a2900003703002003200a2900003703d804024020032802fc04450d00200d102e0b02402002450d002006102e0b200341f0036a41186a200f290300370300200341f0036a41106a2010290300370300200341f0036a41086a2011290300370300200320032903d8043703f003200341f0036a200341a0066a412010f804450d0141c89ac20021094118210a0c050b024020032802fc04450d00200d102e0b2002450d002006102e0b0240024020032d00a0074101470d00024002400240200841e2c289ab06460d00200e0d010240200841e7e485f306460d004100210641c8ecc500210e0c030b412021062013210e0c020b412021062005210e0c010b412021062012210e0b024020022006470d002007200e460d022007200e200210f804450d020b0240024020060d004101210d0c010b20061029220d450d04200d200e200610f6041a0b200320063602fc03200320063602f8032003200d3602f403200320083602f00320034188086a200341f0036a1079200328028808220e20032802900810060240200328028c08450d00200e102e0b2006450d00200d102e0b410121060240200c0d00200210292206450d0420062007200210f6041a0b200320023602fc03200320023602f803200320063602f403200320083602f00320034188086a200341f0036a1079200328028808210820032003280290083602fc04200320083602f804200341a0066a200341f8046a109a020240200328028c08450d002008102e0b2002450d002006102e0b02402009410c460d002009418cd8c1006a2800002108200941046a21090c010b0b20034188086a200341a0066a107720032802900821082003280288082102200341003602f803200342013703f003200341c0066a200341f0036a104a2018200341f0036a104a2019200341f0036a104a20032802f40321062002200820032802f003220720032802f803100402402006450d002007102e0b0240200328028c08450d002002102e0b200341013a00f003200341c0066a41086a22024200370300200342003703c00641ccdfc500410f200341c0066a100320034188086a41086a2002290300370300200320032903c0063703880820034188086a4110200341f0036a41011004410021090240201a450d00200b102e0b0c030b20064101102c000b20024101102c000b201a450d00200b102e0b41002107410121084101210b410121060c160b200341e8086a41306a200141386a290300370300200341e8086a41286a200141306a290300370300200341e8086a41206a200141286a290300370300200341e8086a41186a200141206a290300370300200341e8086a41106a200141186a290300370300200341e8086a41086a200141106a2903003703002003200141086a2903003703e808200341f0036a41206a200241206a290200370300200341f0036a41186a200241186a290200370300200341f0036a41106a200241106a290200370300200341f0036a41086a200241086a290200370300200320022902003703f00320034198026a200341e8086a200341f0036a10a202200328029c02210a200328029802210941002106410121084101210b0c140b200341cc036a41026a22062001410f6a2d00003a0000200341d0036a41086a2207200141206a290300370300200341d0036a410d6a2209200141256a29000037000020032001410d6a2f00003b01cc032003200141186a2903003703d003200141386a2903002114200141306a2903002104200141146a280200210d200141106a28020021082001410c6a2d0000210e20022d0001210c20022d0000210a0240024002400240024002400240200141086a2802000e03000102000b200341e8086a41146a4101360200200342013702ec08200341cc91c5003602e8082003411c3602a407200341c491c5003602a0072003200341a0076a3602f808200341e8086a41d4b4c000106a000b2002411a6a2901002115200241196a2d0000210f200241186a2d00002110200241166a2f01002111200241156a2d00002118200241146a2d00002119200241126a2f0100211a200241116a2d0000210b200241106a2d000021052002410e6a2f010021122002410d6a2d000021132002410c6a2d000021162002410a6a2f01002117200241096a2d0000211d200241086a2d0000211e200241066a2f0100211f200241056a2d00002120200241046a2d00002121200241026a2f01002122200341bc056a41026a20062d00003a000020034198056a41086a200729030037030020034198056a410d6a2009290000370000200320032f01cc033b01bc05200320032903d003370398054101210241b5f0c200210941002106412a210702400240200a41ff0171450d004100210a0c010b4100210a200c41ff01714101470d00201f410874202072201e41187472210941002102201d2107201721062016210a0b200641ffff0371410874200741ff017172200a41187472210a20020d07200320153703b8072003200f3a00b707200320103a00b607200320113b01b407200320183a00b307200320193a00b2072003201a3b01b0072003200b3a00af07200320053a00ae07200320123b01ac07200320133a00ab072003200a3600a707200320093600a307200320213a00a207200320223b01a007200341ec036a41026a2202200341bc056a41026a2d00003a0000200320032f01bc053b01ec03200341e8086a41086a20034198056a41086a290300370300200341e8086a410d6a220620034198056a410d6a29000037000020032003290398053703e8080240200e41ff01714101460d00200341f8046a41026a20022d00003a0000200341a0066a41086a200341e8086a41086a290300370300200341a0066a410d6a2006290000370000200320032f01ec033b01f804200320032903e8083703a0060c020b200341c0056a200841067610bb0120032802c00521060240024020032802c8052008413f7122024b0d00410021020c010b200341f8046a41026a200620024105746a220241026a2d00003a0000200341a8066a200241136a290000370300200341ad066a200241186a290000370000200320022f00003b01f8042003200229000b3703a0062002280007210d20022800032108410121020b024020032802c405450d002006102e0b20020d01410121024115210d41ccc4c20021080c020b200141c8006a2903002115200141c0006a290300211b200341a0076a41086a2007290300370300200341a0076a410d6a2009290000370000200320032f01cc033b01b405200320032903d0033703a007200320062d00003a00b6050240200c200a7241ff0171450d00418df0c20021094128210a410121084101210b0c170b200341ec036a41026a220220032d00b6053a0000200341e8086a41086a2206200341a0076a41086a290300370300200341e8086a410d6a2207200341a0076a410d6a290000370000200320032f01b4053b01ec03200320032903a0073703e808024002400240200e41ff01714101460d00200341f8046a41026a20022d00003a0000200341a0066a41086a2006290300370300200341a0066a410d6a2007290000370000200320032f01ec033b01f804200320032903e8083703a0060c010b200341f0036a200841067610bb0120032802f00321060240024020032802f8032008413f7122024b0d00410021020c010b200341f8046a41026a200620024105746a220241026a2d00003a0000200341a8066a200241136a290000370300200341ad066a200241186a290000370000200320022f00003b01f8042003200229000b3703a0062002280007210d20022800032108410121020b024020032802f403450d002006102e0b20020d004101210241ccc4c20021084115210d0c010b200341bc056a41026a200341f8046a41026a2d00003a0000200341c0056a41086a200341a0066a41086a290300370300200341c0056a410d6a200341a0066a410d6a290000370000200320032f01f8043b01bc05200320032903a0063703c005410021020b200341b8056a41026a2206200341bc056a41026a2d00003a000020034188086a41086a2207200341c0056a41086a29030037030020034188086a41106a200341c0056a41106a290300370300200320032f01bc053b01b805200320032903c0053703880820020d02200341fb086a200729030037000020034180096a20034195086a290000370000200320032f01b8053b01e8082003200d3600ef08200320083600eb0820032003290388083700f308200320062d00003a00ea080240024002400240411410292202450d00200241002900d88c40370000200241106a41002800e88c40360000200241086a41002900e08c4037000020034294808080c0023702f403200320023602f003200341e8086a200341f0036a104a20032802f403210220034180026a20032802f003220620032802f803106e20034180026a41106a290300420020032802800222081b211c200329038802420020081b212802402002450d002006102e0b20282004542208201c201454201c20145122021b0d012028200456201c20145620021b450d03200341e8016a41c28cc00041161070200341f8016a290300212920032903f001212a20032802e8012102200341c0066a41086a22064200370300200342003703c00641c28cc0004116200341c0066a100320034188086a41086a2006290300370300200320032903c00637038808200342002029420020021b22292008ad2014201c7d7c7c202a420020021b221c202820047d222a54ad7d2228201c202a7d222a201c56202820295620282029511b22021b3703f80320034200202a20021b3703f003200341f0036a21020c020b41144101102c000b200341d0016a41c28cc00041161070200341e0016a290300212920032903d801212a20032802d0012102200341c0066a41086a22084200370300200342003703c00641c28cc0004116200341c0066a100320034188086a41086a2008290300370300200320032903c006370388082003427f2029420020021b22292014201c7d2004202854ad7d7c202a420020021b221c200420287d7c2228201c542202ad7c221c2002201c202954201c2029511b22021b3703f8032003427f202820021b3703f003200341f0036a21020b20034188086a41102002411010040b200341e8086a2004201410730240024002400240411810292202450d00200241002900ec8c40370000200241106a41002900fc8c40370000200241086a41002900f48c403700002003429880808080033702f403200320023602f003200341e8086a200341f0036a104a20032802f4032102200341b8016a20032802f003220620032802f803106e200341b8016a41106a290300420020032802b80122081b210420032903c001420020081b211402402002450d002006102e0b2014201b5422082004201554200420155122021b0d012014201b56200420155620021b450d03200341a0016a41c28cc00041161070200341b0016a290300211c20032903a801212820032802a0012102200341c0066a41086a22064200370300200342003703c00641c28cc0004116200341c0066a100320034188086a41086a2006290300370300200320032903c0063703880820034200201c420020021b221c2008ad201520047d7c7c2028420020021b22042014201b7d222854ad7d2214200420287d22282004562014201c562014201c511b22021b3703f80320034200202820021b3703f003200341f0036a21020c020b41184101102c000b20034188016a41c28cc0004116107020034198016a290300211c20032903900121282003280288012102200341c0066a41086a22084200370300200342003703c00641c28cc0004116200341c0066a100320034188086a41086a2008290300370300200320032903c006370388082003427f201c420020021b221c201520047d201b201454ad7d7c2028420020021b2204201b20147d7c22142004542202ad7c220420022004201c542004201c511b22021b3703f8032003427f201420021b3703f003200341f0036a21020b20034188086a41102002411010040b200341e8086a201b2015108c010c040b200341d8046a41026a200341f8046a41026a2d00003a0000200341c0066a41086a200341a0066a41086a290300370300200341c0066a410d6a200341a0066a410d6a290000370000200320032f01f8043b01d804200320032903a0063703c006410021020b200341b8056a41026a2206200341d8046a41026a2d00003a000020034188086a41086a2207200341c0066a41086a29030037030020034188086a41106a200341c0066a41106a290300370300200320032f01d8043b01b805200320032903c006370388082002450d010b200d210a20082109410121084101210b0c130b20034183046a200729030037000020034188046a20034195086a290000370000200320032f01b8053b01f0032003200d3600f703200320083600f30320032003290388083700fb03200320062d00003a00f203411410292202450d03200241002900d88c40370000200241106a41002800e88c40360000200241086a41002900e08c4037000020034294808080c0023702ec08200320023602e808200341a0076a200341e8086a104a20032802ec082102200341f0006a20032802e808220620032802f008106e200341f0006a41106a290300211b200328027021082003290378211c02402002450d002006102e0b411410292202450d04200241002900d88c40370000200241106a41002800e88c40360000200241086a41002900e08c4037000020034294808080c0023702ec08200320023602e808200341f0036a200341e8086a104a20032802ec082102200341d8006a20032802e808220620032802f008106e200341d8006a41106a2903002129200328025821072003290360212a02402002450d002006102e0b024020044280a094a58d1d7c2215200454220220142002ad7c2228201454201520045a1b450d004128210a41aeb5c0002109410121084101210b0c130b0240201c420020081b221c20157d222b201c56201b420020081b221b20287d201c201554ad7d2215201b562015201b511b450d00411d210a4191b5c0002109410121084101210b0c130b2029420020071b211b202a420020071b211c0240200442ffffe883b1de165620144200522014501b0d00201c201b8450450d00411f210a41d6b5c0002109410121084101210b0c130b200341d0006a200341a0076a4102202b201510560240200328025022090d000240201c20047c2228201c542202201b20147c2002ad7c221c201b54201c201b511b450d00412d210a41e4b4c0002109410121084101210b0c140b200341a0076a200341f0036a412010f804450d01200341a0076a202b20151073411410292202450d06200241002900d88c40370000200241106a41002800e88c40360000200241086a41002900e08c4037000020034294808080c0023702ec08200320023602e808200341f0036a200341e8086a104a20032802ec08210820032802f008210620032802e8082102200341f8046a41186a22074200370300200341f8046a41106a22094200370300200341f8046a41086a220a4200370300200342003703f80420022006200341f8046a1000200341d8046a41186a2007290300370300200341d8046a41106a2009290300370300200341d8046a41086a200a290300370300200320032903f8043703d804200341d8046a412041c8ecc500410041001005210602402008450d002002102e0b02402006417f470d00200341f0036a1071200341a0096a201c37030020034198096a2028370300200341e8086a41086a41003a0000200341f1086a20032903f003370000200341f9086a200341f0036a41086a29030037000020034181096a20034180046a29030037000020034189096a20034188046a290300370000200341023a00e80841c8ecc5004100200341e8086a10720b200341f0036a2028201c1073200341386a41c28cc00041161070200341386a41106a29030021152003290340211b20032802382102200341c0066a41086a22084200370300200342003703c00641c28cc0004116200341c0066a100320034188086a41086a2008290300370300200320032903c00637038808200342002015420020021b221c201b420020021b22154280a094a58d1d54ad7d221b20154280e0ebdaf2627c2228201556201b201c56201542ff9f94a58d1d561b22021b3703f00820034200202820021b3703e80820034188086a4110200341e8086a41101004200341d0096a4200370300200341c8096a4280a094a58d1d370300200341c0096a2014370300200341b8096a2004370300200341e8086a41086a41023a0000200341f1086a20032903a007370000200341f9086a200341a0076a41086a29030037000020034181096a200341a0076a41106a29030037000020034189096a200341a0076a41186a29030037000020034191096a20032903f00337000020034199096a200341f0036a41086a290300370000200341a1096a200341f0036a41106a290300370000200341a9096a200341f0036a41186a290300370000200341023a00e80841c8ecc5004100200341e8086a10720c010b2003280254210a410121084101210b0c120b410021090b0b410121084101210b0c0f0b41144101102c000b41144101102c000b41144101102c000b10a302000b024020032802f4082208450d0020032802ec082102200841246c210803400240024020022d0000220641034b0d0002400240024020060e0404000102040b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022008415c6a22080d000b0b024020032802f008450d0020032802ec08102e0b02402007200d460d0003402007280204220e450d01200741086a280200210f02402007410c6a2802002202450d00200241246c2108200e210203400240024020022d0000220641034b0d0002400240024020060e0404000102040b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022008415c6a22080d000b0b200741f0006a21070240200f450d00200e102e0b2007200d470d000b0b02402005450d002010102e0b4100210b410121082004a7450d0a200c102e0c0a0b2007200d460d00034020072802042209450d01200741086a280200210a02402007410c6a2802002202450d00200241246c21082009210203400240024020022d0000220641034b0d0002400240024020060e0404000102040b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022008415c6a22080d000b0b200741f0006a21070240200a450d002009102e0b2007200d470d000b0b02402005450d002010102e0b200341c0066a41086a22024200370300200342003703c006419893c2004111200341c0066a100320034188086a41086a2002290300370300200320032903c00637038808200341e8086a200c2004422088a710a40220034188086a411020032802e808220220032802f0081004024020032802ec08450d002002102e0b4101210802402004a70d004100210b0c060b200c102e4100210b0c050b02402008450d002010200841f0006c6a210c20102107034002402007410c6a2802002208450d0020072802042102200841246c210803400240024020022d0000220641034b0d0002400240024020060e0404000102040b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022008415c6a22080d000b0b200741f0006a21020240200741086a280200450d002007280204102e0b200221072002200c470d000b0b4100210b410121082005450d072010102e0c070b41002112410021090c010b41002113410021090b4128210a4101210b4100210802402007417f6a220241054b0d0041012106410121074101210c4101210d4101210e4101210f410121104101211141012118410121194101211a024002400240024020020e06130013010203130b4100210841000d082004a70d070c080b4100210841000d072004a70d060c070b2013450d0602402004422088a72202450d00200241186c21062005210203400240200241046a280200450d002002280200102e0b0240200241106a280200450d002002410c6a280200102e0b200241186a2102200641686a22060d000b0b2004a70d050c060b2012450d0502402004422088a72202450d002002410c6c21062005210203400240200241046a280200450d002002280200102e0b2002410c6a2102200641746a22060d000b0b2004a70d040c050b02402004422088a72202450d002002410c6c21062005210203400240200241046a280200450d002002280200102e0b2002410c6a2102200641746a22060d000b0b2004a70d030c040b410021080b41012106410121074101210c4101210d4101210e4101210f410121104101211141012118410121190b4101211a410021090c0b0b2005102e0b410121060b410121070b4101210c0b4101210d0b4101210e0b4101210f0b410121100b410121110b410121180b410121194101211a0b0240024020012d0000220241114b0d0002400240024002400240024002400240024002400240024020020e12000d0d010d0d020304050607080d090d0a0b000b2008450d0c0240200141086a280200220241054b0d0002400240024020020e06101000100102100b200141106a280200450d0f2001410c6a280200102e0c0f0b200141106a280200450d0e2001410c6a280200102e0c0e0b0240200141146a2802002208450d002001410c6a2802002102200841186c210803400240200241046a280200450d002002280200102e0b0240200241106a280200450d002002410c6a280200102e0b200241186a2102200841686a22080d000b0b200141106a280200450d0d200128020c102e0c0d0b0240200141146a2802002208450d002001410c6a28020021022008410c6c210803400240200241046a280200450d002002280200102e0b2002410c6a2102200841746a22080d000b0b200141106a280200450d0c200128020c102e0c0c0b200b450d0b02402001410c6a2802002202450d00200141046a2802002207200241f0006c6a210c034002402007410c6a2802002208450d0020072802042102200841246c210803400240024020022d0000220641034b0d0002400240024020060e0404000102040b2002410c6a280200450d03200241086a280200102e0c030b2002410c6a280200450d02200241086a280200102e0c020b2002410c6a280200450d01200241086a280200102e0c010b200241086a280200450d00200241046a280200102e0b200241246a21022008415c6a22080d000b0b200741f0006a21020240200741086a280200450d002007280204102e0b200221072002200c470d000b0b200141086a280200450d0b2001280204102e0c0b0b2006450d0a0240200141086a2d00002202410d4b0d0020024106470d0b200141106a280200450d0b2001410c6a280200102e0c0b0b200141106a280200450d0a2001410c6a280200102e0c0a0b2007450d09200141086a280200450d09200141046a280200102e0c090b200c450d08200141086a2d0000417f6a220241074b0d08024002400240024020020e08000c0c0c0c010203000b2001410c6a2202280200102f2002280200102e0c0b0b2001410c6a2202280200102f2002280200102e0c0a0b2001410c6a2202280200102f2002280200102e0c090b2001410c6a2202280200102f2002280200102e0c080b200d450d07200141046a2d0000417f6a220241024b0d0702400240024020020e03000102000b2001410c6a280200450d09200141086a280200102e0c090b200141086a2202280200102f2002280200102e0c080b2001410c6a2202280200102f2002280200102e0c070b200e450d06200141046a2d0000417f6a220241024b0d0602400240024020020e03000102000b2001410c6a280200450d08200141086a280200102e0c080b200141086a2202280200102f2002280200102e0c070b2001410c6a2202280200102f2002280200102e0c060b200f450d05200141086a280200417f6a220241014b0d050240024020020e020001000b200141106a280200450d062001410c6a280200102e0c060b200141106a280200450d052001410c6a280200102e0c050b2010450d04200141046a2d00004104490d042001410c6a280200450d04200141086a280200102e0c040b2011450d03200141086a280200450d03200141046a280200102e0c030b2018450d02200141086a2d0000417e6a220241024b0d0202400240024020020e03000102000b200141106a280200450d042001410c6a280200102e0c040b200141346a280200450d03200141306a280200102e0c030b200141306a280200450d022001412c6a280200102e0c020b2019450d01200141046a2802004101470d01200141086a2202280200102f2002280200102e0c010b201a450d0002402001410c6a280200450d00200141086a280200102e0b02402001411c6a2802002208450d00200141146a28020021022008410c6c210803400240200241046a280200450d002002280200102e0b2002410c6a2102200841746a22080d000b0b200141186a280200450d002001280214102e0b2000200a36020420002009360200200341f0096a24000be30301097f230041306b220224002002410036020820024201370300200141106a20021046200120021066200141306a20021046200141d0006a20021046200128020421032001410c6a280200220120021047024002400240024020010d002002280208210420022802042105200228020021060c010b200141246c210720022802042105200228020821010340200241106a200310452002280210210802400240200520016b20022802182209490d00200120096a2104200228020021060c010b200120096a22042001490d0420054101742206200420042006491b220a4100480d040240024020050d00200a102921060c010b20022802002005200a102a21060b2006450d032002200a36020420022006360200200a21050b20022004360208200620016a2008200910f6041a02402002280214450d002008102e0b200341246a2103200421012007415c6a22070d000b0b200241106a41186a22014200370300200241106a41106a22034200370300200241106a41086a220942003703002002420037031020062004200241106a1000200041186a2001290300370000200041106a2003290300370000200041086a20092903003700002000200229031037000002402005450d002006102e0b200241306a24000f0b200a4101102c000b102d000baf0b030f7f037e027f230041c0006b22012400200028020821022000280204210320002802002104200141086a220042003703002001420037030041999bc500411920011003200141206a41086a22052000290300370300200120012903003703202001200141206a10b30302400240200128020422060d00410421064100210741002108410021090c010b2001410c6a280200210720012802082108200128020021090b20004200370300200142003703004192e9c300411620011003200520002903003703002001200129030037032020014100360200200141206a41102001100821050240024020012802002200417f460d0020012000360234200120053602302001200141306a103002402001280200220a450d00200141086a280200210b2001280204210c2000450d022005102e0c020b41eff0c2004133200141386a4184f4c2001053000b4100210c4101210a4100210b0b0240024002400240024002402002450d002004200241246c6a210d200a200b4105746a210e2004210503402005280220210f200541086a2900002110200541106a290000211120052900002112200141186a200541186a290000370300200141106a2011370300200141086a201037030020012012370300200541246a2105200a2100410021020240024003400240200e20006b41e0004b0d002000200e460d03034020012000460d03200220002001412010f804220b4100476a2102200b450d03200e200041206a2200470d000c040b0b20012000460d01200220002001412010f804220b4100476a2102200b450d01200041206a220b2001460d012002200b2001412010f804220b4100476a2102200b450d01200041c0006a220b2001460d012002200b2001412010f804220b4100476a2102200b450d01200041e0006a220b2001460d0120004180016a21002002200b2001412010f804220b4100476a2102200b0d000b0b2009200f6a22132009490d00024002402007200241016a2200490d00200821090c010b02400240200820076b2000200720072000491b221420076b220b490d00200821090c010b2007200b6a22002007490d0920084101742209200020002009491b220941ffffffff03712009470d09200941027422004100480d090240024020080d002000102921060c010b200620084102742000102a21060b2006450d050b200620074102746a210002400240200b4102490d002007417f7320146a210b034020004100360200200041046a2100200b417f6a220b0d000b2014417f6a21070c010b200b450d010b20004100360200200741016a21070b200720024d0d04200620024102746a22002000280200200f6a36020020092108201321090b2005200d470d000b0b02402003450d002004102e0b0240200c450d00200a102e0b200141086a220042003703002001420037030041999bc500411920011003200141206a41086a2000290300370300200120012903003703202001410036020820014201370300410410292200450d022000200936000020014284808080c000370204200120003602002007200110470240024020070d00200128020821072001280204210e200128020021020c010b200741027421094100200128020822006b21052001280204210e2006210b0340200b280200210f02400240200e20056a4104490d00200128020021020c010b200041046a22022000490d07200e4101742207200220022007491b22074100480d0702400240200e0d002007102921020c010b2001280200200e2007102a21020b2002450d0620012007360204200120023602002007210e0b200b41046a210b2001200041046a2207360208200220006a200f3600002005417c6a2105200721002009417c6a22090d000b0b200141206a41102002200710040240200e450d002002102e0b02402008450d002006102e0b200141c0006a24000f0b20004104102c000b41c099c500200220071038000b41044101102c000b20074101102c000b102d000b8505010e7f230041e0006b220224002002410036023820014110200241386a1008210302400240024002400240024020022802382204417f470d00200041003602000c010b2002200436021420022003360210200241086a200241106a103120022802080d04200228021422054160712201417f4c0d01200228020c210602400240200541057622070d00410121080c010b200110292208450d030b02402006450d004100210903402005210a200241003a00582009220b41016a2109410021010240024002400340200a2001460d01200241386a20016a2002280210220c2d00003a00002002200c41016a3602102002200141016a220c3a0058200c2101200c4120470d000b200241186a41186a220d200241386a41186a290300370300200241186a41106a220e200241386a41106a290300370300200241186a41086a220f200241386a41086a290300370300200220022903383703182007200b470d020240200b4101742201200920092001491b220741ffffff3f712007470d002007410574220141004e0d020b102d000b200241003602140240200141ff0171450d00200241003a00580b2007450d082008102e0c080b02400240200b0d002001102921080c010b2008200b4105742001102a21080b2008450d060b200a200c6b21052008200b4105746a22012002290318370000200141186a200d290300370000200141106a200e290300370000200141086a200f29030037000020092006470d000b2002200a200c6b3602140b2008450d042000200736020420002008360200200041086a20063602002004450d002003102e0b200241e0006a24000f0b1032000b20014101102c000b20014101102c000b41eff0c2004133200241386a4184f4c2001053000b9c0201057f230041106b220324000240024002400240200141046a2204417f4c0d000240024020040d00410121050c010b200410292205450d020b2003410036020820032004360204200320053602002001200310470240024020032802042206200328020822056b2001490d00200328020021040c010b200520016a22042005490d0420064101742207200420042007491b22074100480d040240024020060d002007102921040c010b200328020020062007102a21040b2004450d032003200736020420032004360200200721060b200420056a2000200110f6041a200228020020022802042004200520016a100402402006450d002004102e0b200341106a24000f0b1032000b20044101102c000b20074101102c000b102d000bdf0301017f024002400240024002400240410110292202450d00200220002d00003a0000200241014102102a2202450d01200220002d00013a0001200241024104102a2202450d02200220002d00023a0002200220002d00033a0003200241044108102a2202450d03200220002d00043a0004200220002d00053a0005200220002d00063a0006200220002d00073a0007200241084110102a2202450d04200220002d00083a0008200220002d00093a0009200220002d000a3a000a200220002d000b3a000b200220002d000c3a000c200220002d000d3a000d200220002d000e3a000e200220002d000f3a000f200241104120102a2202450d05200220002d00103a0010200220002d00113a0011200220002d00123a0012200220002d00133a0013200220002d00143a0014200220002d00153a0015200220002d00163a0016200220002d00173a0017200220002d00183a0018200220002d00193a0019200220002d001a3a001a200220002d001b3a001b200220002d001c3a001c200220002d001d3a001d200220002d001e3a001e200220002d001f3a001f200128020020012802042002412010042002102e0f0b41014101102c000b41024101102c000b41044101102c000b41084101102c000b41104101102c000b41204101102c000b806406077f017e0f7f047e0e7f0b7e230041a00b6b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e06000102030405000b200341ec036a4101360200200342013702dc03200341cc91c5003602d8032003411c3602d407200341c491c5003602d0072003200341d0076a3602e803200341d8036a41a0e1c300106a000b200141e0006a2802002104200341d0076a200141086a41d80010f6041a200341a0066a41186a200141fc006a280200360200200341a0066a41106a200141f4006a290200370300200341a0066a41086a200141ec006a2902003703002003200141e4006a2902003703a006024020022d000120022d000072450d00418df0c2002105412821040c060b20034180096a41086a22024200370300200342003703800941ffa0c500411820034180096a1003200341e80a6a41086a200229030037030020032003290380093703e80a41002102200341003602d803200341e80a6a4110200341d8036a10082106024020032802d8032205417f460d00200320053602e409200320063602e009200341d8036a200341e0096a10fb0120032d00c8044102460d0720032802b00421022005450d002006102e0b024020022004490d0041b0e1c3002105413521040c060b200341d8036a41086a41033a00002003410c3a00d803200341d8036a410c6a20043602004100210541c8ecc5004100200341d8036a1072200341d8036a200341d0076a41d80010f6041a200341bc046a200341a0066a41086a290300370200200341c4046a200341a0066a41106a290300370200200341cc046a200341a0066a41186a280200360200200320043602b004200320032903a0063702b40420034180096a41086a22024200370300200342003703800941ffa0c500411820034180096a1003200341e80a6a41086a200229030037030020032003290380093703e80a200341003602e809200342013703e009200341d8036a200341e0096a10fe0120032802e4092102200341e80a6a411020032802e009220420032802e80910042002450d042004102e0c040b200141086a2802002107200141046a280200210841b5f0c2002105412a210420022d00000d1320022d00014101470d132001410c6a2802002109200141106a290300210a200241196a2d00002105200241186a2d00002104200241166a2f01002106200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211920032002411a6a2901003703b805200320053a00b705200320043a00b605200320063b01b4052003200b3a00b3052003200c3a00b2052003200d3b01b0052003200e3a00af052003200f3a00ae05200320103b01ac05200320113a00ab05200320183a00a205200320193b01a005200320142013410874201241187472723600a705200320172016410874722015411874723600a305200341e0006a41eea0c500411110810102404280ade20420032903687d4280ade20420032802601b200a5a0d00418de3c3002105411b21040c140b200341c8006a41fce2c30041111070024020032802480d004201211a4200211b0c120b2003290350221a200341d8006a290300221b8450450d114200211a4200211b4200211c4200211d0c120b200141c0006a290300211d200141386a290300211c2002411a6a290100211a200241196a2d0000210f200241186a2d00002110200241166a2f01002111200241156a2d00002112200241146a2d00002113200241126a2f01002114200241116a2d00002115200241106a2d000021162002410e6a2f010021172002410d6a2d00002118200241046a2d00002119200241026a2f01002109200141306a280200211e2001412c6a2802002108200141286a280200210d2001411d6a290000211b2001411c6a2d0000211f2001411b6a2d00002120200141196a2f00002121200141186a2d00002122200141176a2d00002123200141156a2f00002124200141146a2d00002125200141136a2d00002126200141116a2f00002127200141106a2d000021282001410c6a2802002129200141086a280200210c200141076a2d0000212a200141056a2f0000212b200141046a2d0000210e200141c8006a290300210a41b5f0c2002105412a21070240024020022d0000450d0041012106410021044100210b0c010b41012106410021044100210b20022d00014101470d002002410c6a2d0000210b2002410a6a2f01002104200241096a2d00002107200241066a2f0100410874200241056a2d000072200241086a2d0000411874722105410021060b200441ffff0371410874200741ff017172200b41187472210420060d0f0240200e41ff01714101470d00200341d8036a200c41067610bb0120032802d80321060240024020032802e003200c413f7122024b0d00410021020c010b200620024105746a2202290018211b20022d0017211f20022d0016212020022f0014212120022d0013212220022d0012212320022f0010212420022d000f212520022d000e212620022f000c212720022d000b2128200228000721292002280003210c20022d0002212a20022f0000212b410121020b024020032802dc03450d002006102e0b20020d0041ccc4c2002105411521040c100b2003201a3703b0032003200f3a00af03200320103a00ae03200320113b01ac03200320123a00ab03200320133a00aa03200320143b01a803200320153a00a703200320163a00a603200320173b01a403200320183a00a3032003200436009f032003200536009b03200320193a009a03200320093b019803200341d8016a41eea0c500411110810102404280ade20420032903e0017d4280ade20420032802d8011b200a5a0d00418de3c3002105411b21040c0d0b200341c0016a41fce2c30041111070024020032802c0010d004201211a4200212c0c0b0b20032903c801221a200341d0016a290300222c8450450d0a4200211a4200212c4200212d4200212e0c0b0b200141386a290300211b200141306a290300211d200141c0006a290300210a200341f8026a41186a200141196a290000370300200341f8026a41106a200141116a290000370300200341f8026a41086a200141096a290000370300200320012900013703f8022002411a6a290100211a200241196a2d0000210d200241186a2d0000210e200241166a2f0100210f200241156a2d00002110200241146a2d00002111200241126a2f01002112200241116a2d00002113200241106a2d000021142002410e6a2f010021152002410d6a2d00002116200241046a2d00002117200241026a2f010021182001412c6a2802002119200141286a2802002108200141246a280200210c41b5f0c2002105412a21070240024020022d0000450d0041012106410021044100210b0c010b41012106410021044100210b20022d00014101470d002002410c6a2d0000210b2002410a6a2f01002104200241096a2d00002107200241066a2f0100410874200241056a2d000072200241086a2d0000411874722105410021060b200441ffff0371410874200741ff017172200b41187472210402402006450d002008450d09200c102e0c090b2003201a3703b0032003200d3a00af032003200e3a00ae032003200f3b01ac03200320103a00ab03200320113a00aa03200320123b01a803200320133a00a703200320143a00a603200320153b01a403200320163a00a3032003200436009f032003200536009b03200320173a009a03200320183b019803200341d0026a41eea0c500411110810102404280ade20420032903d8027d4280ade20420032802d0021b200a5a0d00418de3c3002105411b21040c070b200341b8026a41fce2c30041111070024020032802b8020d004201211a4200211c0c050b20032903c002221a200341c8026a290300221c8450450d044200211a4200211c4200212e4200212c0c050b200341e0096a41186a200141196a290000370300200341e0096a41106a200141116a290000370300200341e0096a41086a200141096a290000370300200320012900013703e009200341a0066a41206a200141c1006a2d00003a0000200341a0066a41186a200141396a290000370300200341a0066a41106a200141316a290000370300200341a0066a41086a200141296a2900003703002003200141216a2900003703a006200341d8036a41086a2205200241096a290000370300200341d8036a41106a2204200241116a290000370300200341d8036a41186a2206200241196a290000370300200341d8036a41206a220b200241216a2d00003a0000200341a4056a2207200241266a2f01003b0100200320022900013703d8032003200241226a2801003602a005024020022d00002202450d00200341d0076a41266a20032802a005360100200341dd076a2005290300370000200341e5076a2004290300370000200341ed076a2006290300370000200341f5076a200b2d00003a0000200341fa076a20072f01003b0100200320023a00d407200320032903d8033700d507200341013a00d00741e5e1c300210541e90021040c020b200341d0076a41216a200b2d00003a0000200341d0076a41196a2006290300370000200341d0076a41116a2004290300370000200341d0076a41096a2005290300370000200320032903d803220a3700d107200341003a00d00741e5e1c300210541e9002104200aa741ff0171417f6a220241014b0d0102400240024020020e020100010b20032d00a0064101470d03200341a0066a4101722104410021020c010b20032d00a0064101460d0241022102200341d0076a41027221040b41002105200341d8036a200341e0096a20024100105b20032d00d8032102024020032d00e0030d00200341fc036a280200450d00200341f8036a280200102e0b200241ff01714101470d00200341d8036a20044296014200108e01024020032802d8034101470d0020032802e003210420032802dc0321050c020b200341d8036a41106a290300211a20032903e003211b200341e0026a41c28cc00041161070200341e0026a41106a290300210a20032903e802211d20032802e002210220034180096a41086a22044200370300200342003703800941c28cc000411620034180096a1003200341e80a6a41086a200429030037030020032003290380093703e80a2003427f201a200a420020021b220a7c201b201d420020021b221a7c221b201a542202ad7c221a2002201a200a54201a200a511b22021b3703a8052003427f201b20021b3703a005200341e80a6a4110200341a0056a411010040b0b4101210b410121060c0f0b41eff0c2004133200341980b6a4184f4c2001053000b20034198026a201c4200200a420010fb04200341a8026a201a4200200a420010fb0420034188026a42004200201a420010fb04024020032903a00220032903900284420052200341b0026a290300222e2003290398022003290388027c7c222c202e5472450d0041a8e3c3002105412721040c020b20032903a802212e0b200341d8036a20034198036a202e202c4108107a20032802d8034101470d0120032802e003210420032802dc0321050b2008450d01200c102e0c010b200341d8036a41106a290300212e20032903e003212c200341b8036a41186a201c3703002003201a3703c8032003200a3703c0032003200a3703b80320034180096a41086a22024200370300200342003703800941ffa0c500411820034180096a1003200341e80a6a41086a200229030037030020032003290380093703e80a200341003602d803200341e80a6a4110200341d8036a100821020240024020032802d803220f417f460d002002450d002003200f3602d407200320023602d007200341d8036a200341d0076a10fb01024020032d00c80422054102460d0020032802c404210420032802c004210620032802bc04210b20032802b804210720032802b404210d20032802b004210e20032903a804210a20032903a004211a200329039804211c200329039004212d200329038804212f200329038004213020032903f803213120032903f003213220032903e803213320032903e003213420032903d8032135200320032800c9043602a0062003200341cc046a2800003600a3060240200f450d002002102e0b200320032802a0063602d007200320032800a3063600d3070c020b41eff0c2004133200341980b6a4184f4c2001053000b428701212d42af01211c4201210a410021054104210d4180800421074110210b418080012106412021044100210e4201211a4201212f4201213042012131420121324201213342012134420121350b200320053a00c804200320043602c404200320063602c0042003200b3602bc04200320073602b8042003200d3602b4042003200e3602b0042003200a3703a8042003201a3703a0042003201c370398042003202d370390042003202f370388042003203037038004200320313703f803200320323703f003200320333703e803200320343703e003200320353703d803200341d8046a420037030020034188056a4200370300200341f8046a4200370300200341e8046a4200370300200341cc046a20032800d30736000020034280888080808010370390052003428080e983b1de163703d00420034280a094a58d1d3703800520034280a094a58d1d3703f00420034280a094a58d1d3703e004200320032802d0073600c9042003200341d8036a360298052003200341d8036a36029c05200341d0076a41186a220520034198036a41186a290300370300200341d0076a41106a220420034198036a41106a290300370300200341d0076a41086a220220034198036a41086a29030037030020032003290398033703d007200341f8016a41c5c1c200410d108101200329038002210a20032802f801210620034180096a41086a220b4200370300200342003703800941b0f3c200410d20034180096a1003200341e80a6a41086a200b29030037030020032003290380093703e80a200341f0016a200341e80a6a10ac03200341d4056a4200370200200341a0056a41286a41a481c000360200200341a0056a41246a41c8ecc500360200200341bc056a4200370200200341a0056a41186a41e08dc000360200200341f4056a2002290300370200200341fc056a200429030037020020034184066a20052903003702002003428080808080013702cc054100211f200341003602b405200341003602a805200320032903d0073702ec0520032802f001210520032802f401210420032003419c056a3602e405200320034198056a3602e0052003200341d8036a3602dc0520032004410020051b3602e8052003200a420020061b3703a005200320193602a806200320083602a4062003200c3602a006200341d0076a200341a0056a201d201b200341b8036a200341f8026a200341a0066a104d410121200240024020032802d0074101470d00200341dc076a290200221b422888211c201b422088211d2002280200210420032802d40721054101211f410121200c010b200341fc076a290200221b422888211c200341d0076a41286a2802002104200341d0076a41246a2802002105201b422088221da741ff01710d00200341d0076a41086a200341bc056a290200370300200341a0066a41086a200341dc076a280200360200200320032902b4053703d007200320032902d4073703a006200341980b6a200341a0066a10ec014100211f4200211d410021200b20034198036a20032903b80320032903c00320032903c803200341b8036a41186a290300202c202e10d90320032802d805210620032802d405210b200320032802d0052202360298062003200b36029406200320023602900620032002200641b0016c6a221036029c0602402006450d00200341e0096a410172211720034187096a2118200341e9096a210720034180096a4102722108200341d0076a41106a2119200341f8076a2116200341b4086a211220034191086a210c200341f1076a210d200341d0076a4101722111200341c8086a2109034020022d00002106200341a0066a200241016a41af0110f6041a0240024020064103460d00200320063a00d0072011200341a0066a41af0110f604210b024002400240024020060e03000102000b20032802d807210f20032802dc07210b20032802d40721062018201941d80010f6041a2003410c3a00e009201720034180096a41df0010f6041a2006200b200341e0096a10724101210b4100210e0240200f450d002006102e0b4100210f0c020b200341e80a6a41186a2206200b41186a220e290000370300200341e80a6a41106a220f200b41106a2213290000370300200341e80a6a41086a2214200b41086a22152900003703002003200b2900003703e80a200341e0096a201641880110f6041a2008200b290000370000200841086a2015290000370000200841106a2013290000370000200841186a200e29000037000020034180023b018009200341e8016a200341e0096a20034180096a10950220032802e801210b200720032903e80a370000200741086a2014290300370000200741106a200f290300370000200741186a2006290300370000200341043a00e8092003410c3a00e0092003200b453a00890a4100210b41c8ecc5004100200341e0096a10724101210e4100210f0c010b2009290300210a20032903c008211a200341e80a6a41186a200b41186a290000370300200341e80a6a41106a200b41106a290000370300200341e80a6a41086a200b41086a2900003703002003200b2900003703e80a20034180096a41186a200d41186a29000037030020034180096a41106a200d41106a29000037030020034180096a41086a200d41086a2900003703002003200d29000037038009200341e0096a41186a200c41186a290000370300200341e0096a41106a200c41106a290000370300200341e0096a41086a200c41086a2900003703002003200c2900003703e009200341880b6a41086a201241086a280200360200200320122902003703880b200341e80a6a20034180096a200341e0096a201a200a200341880b6a10da034101210e4101210b4101210f0b024020032d00d007220641014b0d000240024020060e020001000b200e450d03024020032802d807450d0020032802d407102e0b20032d00e0074105490d03200328028808450d03200328028408102e0c030b200b450d022016102f0c020b200f20032802b80845720d0120032802b408102e0c010b2003200241b0016a360298060c020b200241b0016a22022010470d000b20032010360298060b20034190066a102b02400240201f0d00024020040d00410021050c020b2005102e410021050c010b024020050d00410021050c010b201c422886201d4220864280808080f01f8384500d00201ba7102e0b024020032802a8052202450d00200341ac056a280200450d002002102e0b2020450d00200341a0056a41186a280200210220032802c00521080240024020032802bc05220b0d00200221060c010b200b210720022106034020062802880b21062007417f6a22070d000b0340200220022f01064102746a41880b6a2802002102200b417f6a220b0d000b0b200341ec076a20022f0106360200200341d0076a41186a4100360200200341e4076a2002360200200320083602f007200341003602e007200342003703d807200320063602d407200341003602d007200341d0076a10540b410021074101210b410121060c0a0b200341a0016a202c4200200a420010fb04200341b0016a201a4200200a420010fb0420034190016a42004200201a420010fb04024020032903a80120032903980184420052200341b8016a290300222d20032903a0012003290390017c7c222e202d5472450d0041a8e3c3002105412721040c020b20032903b001212d0b200341d8036a20034198036a202d202e4108107a20032802d8034101470d0120032802e003210420032802dc0321050b2008450d01200d102e0c010b200341d8036a41106a290300212d20032903e003212e200341b8036a41186a202c3703002003201a3703c8032003200a3703c0032003200a3703b80320034180096a41086a22024200370300200342003703800941ffa0c500411820034180096a1003200341e80a6a41086a200229030037030020032003290380093703e80a200341003602d803200341e80a6a4110200341d8036a100821020240024020032802d8032210417f460d002002450d00200320103602d407200320023602d007200341d8036a200341d0076a10fb01024020032d00c80422054102460d0020032802c404210420032802c004210620032802bc04210b20032802b804210720032802b404210e20032802b004210f20032903a804210a20032903a004211a200329039804212c200329039004212f2003290388042130200329038004213120032903f803213220032903f003213320032903e803213420032903e003213520032903d8032136200320032800c9043602a0062003200341cc046a2800003600a30602402010450d002002102e0b200320032802a0063602d007200320032800a3063600d3070c020b41eff0c2004133200341980b6a4184f4c2001053000b428701212f42af01212c4201210a410021054104210e4180800421074110210b418080012106412021044100210f4201211a420121304201213142012132420121334201213442012135420121360b200320053a00c804200320043602c404200320063602c0042003200b3602bc04200320073602b8042003200e3602b4042003200f3602b0042003200a3703a8042003201a3703a0042003202c370398042003202f3703900420032030370388042003203137038004200320323703f803200320333703f003200320343703e803200320353703e003200320363703d803200341d8046a4200370300200341d8036a41b0016a4200370300200341f8046a4200370300200341e8046a4200370300200341cc046a20032800d30736000020034280888080808010370390052003428080e983b1de163703d00420034280a094a58d1d3703800520034280a094a58d1d3703f00420034280a094a58d1d3703e004200320032802d0073600c9042003200341d8036a360298052003200341d8036a36029c05200341d0076a41186a220220034198036a41186a290300370300200341d0076a41106a220520034198036a41106a290300370300200341d0076a41086a220420034198036a41086a29030037030020032003290398033703d00720034180016a41c5c1c200410d108101200329038801210a200328028001210620034180096a41086a220b4200370300200342003703800941b0f3c200410d20034180096a1003200341e80a6a41086a200b29030037030020032003290380093703e80a200341f8006a200341e80a6a10ac03200341d4056a4200370200200341c8056a41a481c000360200200341c4056a41c8ecc500360200200341bc056a4200370200200341a0056a41186a41e08dc000360200200341f4056a2004290300370200200341fc056a200529030037020020034184066a20022903003702002003428080808080013702cc05200341003602b405200341003602a805200320032903d0073702ec0520032802782102200328027c210520032003419c056a3602e405200320034198056a3602e0052003200341d8036a3602dc0520032005410020021b3602e8052003200a420020061b3703a0052003201b3703e8072003201f3a00e707200320203a00e607200320213b01e407200320223a00e307200320233a00e207200320243b01e007200320253a00df07200320263a00de07200320273b01dc07200320283a00db07200320293600d7072003200c3600d3072003202a3a00d2072003202b3b01d0072003201e3602a806200320083602a4062003200d3602a006200341f8026a200341a0056a200341d0076a201c201d200341b8036a200341a0066a105a41012119024020032802f80222090d00200341f8026a41106a2d00000d00200341d0076a41086a200341bc056a290200370300200341a0066a41086a200341dc076a280200360200200320032902b4053703d007200320032902d4073703a006200341980b6a200341a0066a10ec01410021190b20034198036a20032903b80320032903c00320032903c803200341b8036a41186a290300202e202d10d90320032802d805210520032802d4052104200320032802d0052202360298062003200436029406200320023602900620032002200541b0016c6a220e36029c0602402005450d00200341e0096a410172211520034187096a2116200341e9096a210620034180096a410272210b200341d0076a41106a2117200341f8076a2114200341b4086a211020034191086a2107200341f1076a2108200341d0076a410172210f200341c8086a2118034020022d00002105200341a0066a200241016a41af0110f6041a0240024020054103460d00200320053a00d007200f200341a0066a41af0110f6042104024002400240024020050e03000102000b20032802d807210d20032802dc07210420032802d40721052016201741d80010f6041a2003410c3a00e009201520034180096a41df0010f6041a20052004200341e0096a1072410121044100210c0240200d450d002005102e0b4100210d0c020b200341e80a6a41186a2205200441186a220c290000370300200341e80a6a41106a220d200441106a2211290000370300200341e80a6a41086a2212200441086a2213290000370300200320042900003703e80a200341e0096a201441880110f6041a200b2004290000370000200b41086a2013290000370000200b41106a2011290000370000200b41186a200c29000037000020034180023b018009200341f0006a200341e0096a20034180096a10950220032802702104200620032903e80a370000200641086a2012290300370000200641106a200d290300370000200641186a2005290300370000200341043a00e8092003410c3a00e00920032004453a00890a4100210441c8ecc5004100200341e0096a10724101210c4100210d0c010b2018290300210a20032903c008211a200341e80a6a41186a200441186a290000370300200341e80a6a41106a200441106a290000370300200341e80a6a41086a200441086a290000370300200320042900003703e80a20034180096a41186a200841186a29000037030020034180096a41106a200841106a29000037030020034180096a41086a200841086a2900003703002003200829000037038009200341e0096a41186a200741186a290000370300200341e0096a41106a200741106a290000370300200341e0096a41086a200741086a290000370300200320072900003703e009200341880b6a41086a201041086a280200360200200320102902003703880b200341e80a6a20034180096a200341e0096a201a200a200341880b6a10da034101210c410121044101210d0b024020032d00d007220541014b0d000240024020050e020001000b200c450d03024020032802d807450d0020032802d407102e0b20032d00e0074105490d03200328028808450d03200328028408102e0c030b2004450d022014102f0c020b200d20032802b80845720d0120032802b408102e0c010b2003200241b0016a360298060c020b200241b0016a2202200e470d000b2003200e360298060b20034190066a102b20034180036a280200210420032802fc0221050240024020090d00024020040d00410021050c020b2005102e410021050c010b024020050d00410021050c010b20034184036a290200220a428080808010540d00200aa7102e0b024020032802a8052202450d00200341ac056a280200450d002002102e0b2019450d00200341a0056a41186a280200210220032802c00521080240024020032802bc05220b0d00200221060c010b200b210720022106034020062802880b21062007417f6a22070d000b0340200220022f01064102746a41880b6a2802002102200b417f6a220b0d000b0b200341ec076a20022f0106360200200341d0076a41186a4100360200200341e4076a2002360200200320083602f007200341003602e007200342003703d807200320063602d407200341003602d007200341d0076a10540b410021064101210b0c040b410021064101210b2008450d03200d102e0c030b200341286a201b4200200a420010fb04200341386a201a4200200a420010fb04200341186a42004200201a420010fb0402402003290330200329032084420052200341c0006a290300221c200329032820032903187c7c221d201c5472450d0041a8e3c3002105412721040c020b2003290338211c0b200341d8036a200341a0056a201c201d4108107a024020032802d8034101470d0020032802e003210420032802dc0321050c010b200341d8036a41106a290300211c20032903e003211d20034180096a41086a22024200370300200342003703800941ffa0c500411820034180096a1003200341e80a6a41086a200229030037030020032003290380093703e80a200341003602d803200341e80a6a4110200341d8036a100821020240024020032802d8032204417f460d002002450d00200320043602a406200320023602a006200341d8036a200341a0066a10fb01024020032d00c80422054102460d00200341d0076a200341d8036a41f00010f6041a2003200341cc046a22062800003600e309200320032800c9043602e00902402004450d002002102e0b200341d8036a200341d0076a41f00010f6041a200620032800e309360000200320032802e0093600c90420032903d803212c0c020b41eff0c2004133200341980b6a4184f4c2001053000b41002105200341003602b004200341203602c404200342908080808080103702bc04200342848080808080c0003702b4044201212c200342013703a804200342013703a004200342af013703980420034287013703900420034201370388042003420137038004200342013703f803200342013703f003200342013703e803200342013703e003200342013703d8030b200341086a202c42002009ad420010fb04200320053a00c8044200200a427f200329030820032903104200521b7d222c202c200a5622021b212c0240024002402002450d00419ddbc1002105412c21040c010b200341d0076a20082009200341d8036a10f701024020032802d0074101470d00200341d8076a280200210420032802d40721050c010b200341e80a6a41186a2202200341ec076a280200360200200341e80a6a41106a220d200341d0076a41146a290200370300200341e80a6a41086a220e200341dc076a290200370300200320032902d4073703e80a200341d0076a41186a22054200370300200341d0076a41106a220b4200370300200341d0076a41086a220c4200370300200342003703d00720082009200341d0076a10002003419a036a20032d00d207220f3a0000200341b8036a41086a2210200341d0076a41136a290000370300200341c5036a22112005290000370000200320032f01d00722123b019803200320032900db07222e3703b80320032800d307210620032800d7072104200341e0096a41136a2010290300370000200341e0096a41186a20112900003700002003200f3a00e209200320123b01e009200320043600e709200320063600e3092003202e3700eb0920034180096a41186a200228020036020020034180096a41106a200d29030037030020034180096a41086a200e290300370300200320032903e80a3703800902400240411410292202450d00200241106a41002800aca543360000200241086a41002900a4a5433700002002410029009ca54337000020034294808080c0023702d407200320023602d007200341e0096a200341d0076a104620032802d407210d20032802d807210e20032802d007210220054200370300200b4200370300200c4200370300200342003703d0072002200e200341d0076a1000200341a0066a41186a2005290300370300200341a0066a41106a200b290300370300200341a0066a41086a200c290300370300200320032903d0073703a006200341203602d4072003200341a0066a3602d00720034180096a200341d0076a10f8010240200d450d002002102e0b024020034190096a280200450d00200328028c09102e0b200341f3096a200341b8036a41086a290300370000200341e0096a41186a200341b8036a410d6a29000037000020032003419a036a2d00003a00e209200320032f0198033b01e009200320043600e709200320063600e309200320032903b8033700eb09411510292202450d012002410d6a4100290094a543370000200241086a410029008fa54337000020024100290087a54337000020034295808080d0023702d407200320023602d007200341e0096a200341d0076a104620032802d407210520032802d807210b20032802d0072102200341d0076a41186a220c4200370300200341d0076a41106a220d4200370300200341d0076a41086a220e4200370300200342003703d0072002200b200341d0076a1000200341a0066a41186a200c290300370300200341a0066a41106a200d290300370300200341a0066a41086a200e290300370300200320032903d0073703a006200341203602d4072003200341a0066a3602d00720082009200341d0076a10990202402005450d002002102e0b02402007450d002008102e0b20034180096a41026a20034198036a41026a2d000022023a0000200341a0066a41086a2205200341b8036a41086a290300370300200341a0066a410d6a220b200341b8036a410d6a290000370000200320032f01980322073b018009200320032903b8033703a006200341d0076a41086a41023a0000200341d9076a20073b0000200341db076a20023a0000200341e0076a20043602002003410c3a00d007200341d0076a410c6a2006360200200341e4076a20032903a006370200200341ec076a2005290300370200200341f1076a200b2900003700004100210541c8ecc5004100200341d0076a1072200341a0056a200a202c201a201b201d201c10d9030c030b41144101102c000b41154101102c000b02402007450d002008102e0b200341a0056a200a202c201a201b201d201c10d9030b410121064100210b0c010b410121064100210b2007450d002008102e0b410121070b024020012d0000417e6a220241024b0d00024002400240024020020e03000102000b200b450d03200141086a280200450d03200141046a280200102e0c030b20060d010c020b2007450d01200141286a280200450d01200141246a280200102e0c010b2001412c6a280200450d00200141286a280200102e0b2000200436020420002005360200200341a00b6a24000bc40101027f230041206b22012400200141106a41086a220242003703002001420037031041acb4c200411b200141106a1003200141086a200229030037030020012001290310370300200028020021022000280208210020014100360218200142013703102000200141106a104702402000450d002000410574210003402002200141106a104a200241206a2102200041606a22000d000b0b2001280214210220014110200128021022002001280218100402402002450d002000102e0b200141206a24000bae0f030b7f077e057f230022042105200441c0016b41607122042400024002400240024002400240200141ffffff3f712001470d0020014105742206417f4c0d000240024020060d00410121070c010b200610292207450d020b410021084100210602402001450d0020014105742109416020006b210a2007210620002108034020062008290000370000200641186a200841186a290000370000200641106a200841106a290000370000200641086a200841086a290000370000200641206a2106200841206a2108200941606a22090d000b200020014105746a200a6a41057641016a2106200121080b20042006360218200420083602142004200736021020072006200441206a410041202006676b105f200441a0016a41086a22064200370300200442003703a00141e0c9c200411d200441a0016a100320044180016a41086a2006290300370300200420042903a00137038001200441003602a00120044180016a4110200441a0016a100821080240024020042802a0012206417f460d002004200636024420042008360240200441a0016a200441c0006a103020042802a001220b450d04200441a8016a280200210920042802a401210c2006450d012008102e0c010b4101210b410021094100210c0b2009410574220a450d05200441a0016a411472210d200441a0016a410872210e200b21060340200641086a290000210f200641106a290000211020062900002111200441206a41186a200641186a290000370300200441206a41106a2010370300200441206a41086a200f37030020042011370320200441c0006a200441206a109003200441003602a80120042903582111200420042903b801221237035820042903502113200420042903b001221437035020042903402115200420042903a0013703402004290348210f200420042903a80122103703482014422088a721002010422088a721012012a721072010a721080240200fa72209450d00200420153703a0012004200f3703a801200420133703b001200420113703b801200420092013a74105746a36028c0120042009360288012004200f422088a73602840120042009360280012004200441106a36029001200441f0006a20044180016a1042200e41086a200441f0006a41086a2216280200360200200e200429037037020020042013422088a722092011422088a74105746a36028c01200420093602880120042011a73602840120042009360280012004200441106a36029001200441f0006a20044180016a1042200d41086a2016280200360200200d200429037037020020042903a801210f20042903a001211320042903b801211020042903b001211102402008450d0002402001450d002008102e0b2007450d002000102e0b200420133703402004200f370348200f422088a72101200420113703502011422088a7210020042010370358200fa721082010a721070b0240024020080d00411a10292208450d06200841186a41002f0095ca423b0000200841106a410029008dca42370000200841086a4100290085ca42370000200841002900fdc9423700002004429a808080a0033702a401200420083602a001200441206a200441a0016a104620042802a401210920042802a801210120042802a0012108200441a0016a41186a22074200370300200441a0016a41106a22004200370300200441a0016a41086a22164200370300200442003703a00120082001200441a0016a100020044180016a41186a200729030037030020044180016a41106a200029030037030020044180016a41086a2016290300370300200420042903a0013703800120044180016a412010062009450d012008102e0c010b411a10292209450d06200941186a41002f0095ca423b0000200941106a410029008dca42370000200941086a4100290085ca42370000200941002900fdc9423700002004429a808080a0033702a401200420093602a001200441206a200441a0016a104620042802a401211620042802a801211720042802a0012109200441a0016a41186a22184200370300200441a0016a41106a22194200370300200441a0016a41086a221a4200370300200442003703a00120092017200441a0016a100020044180016a41186a201829030037030020044180016a41106a201929030037030020044180016a41086a201a290300370300200420042903a00137038001200441203602a401200420044180016a3602a001200441c0006a200441a0016a108e0302402016450d002009102e0b02402001450d002008102e0b2007450d002000102e0b200641206a2106200a41606a220a0d000c060b0b1032000b20064101102c000b41eff0c2004133200441206a4184f4c2001053000b411a4101102c000b411a4101102c000b0240200c450d00200b102e0b200441003602a801200442013703a0012003200441a0016a104702402003450d002003410574210603402002200441a0016a104a200241206a2102200641606a22060d000b0b20042802a401210820042802a801210920042802a0012106200441a0016a41086a22024200370300200442003703a00141d2c1c200411b200441a0016a100320044180016a41086a2002290300370300200420042903a0013703800120044180016a411020062009100402402008450d002006102e0b02402004280214450d002004280210102e0b200524000ba808010e7f230041206b220424002002410020031b21052000410020011b2106200241206a200220031b2107200041206a200020011b2108200020014105746a2109200220034105746a210a4100210b4100210c4101210d4100210e4100210f410121100340024002400240024002400240024002402005450d0003402006450d02024020052006460d0020052006412010f80422020d040b410020072007200a4622021b210541002008200820094622031b21062007200741206a20021b21072008200841206a20031b210820050d000b0b4100210520060d03200d200b20002001109d020240200c450d00200d102e0b0240200f450d002010102e0b200441206a24000f0b200441186a2202200541186a290000370300200441106a2203200541106a290000370300200441086a2211200541086a290000370300200420052900003703000240200c200b470d00200b41016a2206200b490d04200b4101742205200620062005491b220c41ffffff3f71200c470d04200c41057422064100480d0402400240200b0d0020061029210d0c010b200d200b4105742006102a210d0b200d450d020b200d200b4105746a22062004290300370000200641186a2002290300370000200641106a2003290300370000200641086a20112903003700002007200741206a2007200a4622051b2102410021064100200720051b21050c050b2002417f4a0d01200441186a2202200541186a290000370300200441106a2203200541106a290000370300200441086a2211200541086a290000370300200420052900003703000240200c200b470d00200b41016a2205200b490d03200b410174220c20052005200c491b220c41ffffff3f71200c470d03200c41057422054100480d0302400240200b0d0020051029210d0c010b200d200b4105742005102a210d0b200d0d0020054101102c000b200d200b4105746a22052004290300370000200541186a2002290300370000200541106a2003290300370000200541086a20112903003700002007200741206a2007200a4622051b21024100200720051b21050c040b20064101102c000b200441186a2202200641186a290000370300200441106a2203200641106a290000370300200441086a2211200641086a290000370300200420062900003703000240200f200e470d00200e41016a2206200e490d01200e410174220f20062006200f491b220f41ffffff3f71200f470d01200f41057422064100480d0102400240200e0d002006102921100c010b2010200e4105742006102a21100b2010450d020b2010200e4105746a22062004290300370000200641186a2002290300370000200641106a2003290300370000200641086a201129030037000041002008200820094622021b2106200e41016a210e2008200841206a20021b21080c030b102d000b20064101102c000b200b41016a210b200221070c000b0bec5302157f037e230041b0046b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d000022040e050001020304000b200341ac036a41013602002003420137029c03200341cc91c500360298032003411c36029402200341c491c50036029002200320034190026a3602a80320034198036a41b4e7c200106a000b200141086a2802002105200141046a2802002106024020022d000120022d000072450d00418df0c200210741282108410021094101210a02402005450d002006102e0b410121060c160b20062001410c6a2802002202105d20034198036a41086a22074200370300200342003703980341d2c1c200411b20034198036a100320034190026a41086a2007290300370300200320032903980337039002200341003602980320034190026a411020034198036a100821082003280298032207417f460d042003200736026c2003200836026820034198036a200341e8006a10302003280298032209450d03200341a0036a280200210a200328029c03210b02402007450d002008102e0b200620022009200a109e02200b450d142009102e0c140b200141046a280200210941b5f0c2002107412a210820022d00000d1220022d00014101470d12200241196a2d00002107200241186a2d00002108200241166a2f0100210a200241156a2d00002106200241146a2d00002105200241126a2f0100210b200241116a2d0000210c200241106a2d0000210d2002410e6a2f0100210e2002410d6a2d0000210f2002410c6a2d000021102002410a6a2f01002111200241096a2d00002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f0100211720032002411a6a29010037038802200320073a008702200320083a0086022003200a3b018402200320063a008302200320053a0082022003200b3b0180022003200c3a00ff012003200d3a00fe012003200e3b01fc012003200f3a00fb01200320163a00f201200320173b01f001200320122011410874201041187472723600f701200320152014410874722013411874723600f30120034198036a41086a22024200370300200342003703980341d2c1c200411b20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a10082107024002402003280298032202417f460d002003200236026c2003200736026820034198036a200341e8006a10302003280298032208450d06200341a0036a280200210a200328029c03210602402002450d002007102e0b2008200a200341f0016a108a03210202402006450d002008102e0b2002450d010c120b41014100200341f0016a108a030d110b41c4e7c2002107411521080c120b200141086a2802002109200141046a28020021172002411a6a2901002118200241196a2d0000210b200241186a2d0000210c200241166a2f0100210d200241156a2d0000210e200241146a2d0000210f200241126a2f01002110200241116a2d00002111200241106a2d000021122002410e6a2f010021132002410d6a2d00002114200241046a2d00002115200241026a2f01002116412a210841b5f0c20021070240024020022d0000450d004101210a41002106410021050c010b4101210a410021064100210520022d00014101470d002002410c6a2d000021062002410a6a2f01002105200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d00004118747221074100210a0b200541ffff0371410874200641187472200841ff0171722108200a0d0e200320183703402003200b3a003f2003200c3a003e2003200d3b013c2003200e3a003b2003200f3a003a200320103b0138200320113a0037200320123a0036200320133b0134200320143a00332003200836002f2003200736002b200320153a002a200320163b012820034198036a41086a22024200370300200342003703980341d2c1c200411b20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a10082102024002402003280298032207417f460d002002450d002003200736026c2003200236026820034198036a200341e8006a10302003280298032208450d06200341a0036a280200210a200328029c03210602402007450d002002102e0b2008200a200341286a108a03210202402006450d002008102e0b2002450d010c0a0b41014100200341286a108a030d090b41c4e7c2002107411521080c0e0b200141216a2d00002117200141246a2802002116200341286a41186a200141196a290000370300200341286a41106a200141116a290000370300200341286a41086a200141096a290000370300200320012900013703282002411a6a2901002118200241196a2d00002105200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d00002113200241046a2d00002114200241026a2f0100211541b5f0c2002107412a21080240024020022d0000450d00410121094100210a410021060c010b410121094100210a4100210620022d00014101470d002002410c6a2d000021062002410a6a2f0100210a200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d0000411874722107410021090b200a41ffff0371410874200841ff017172200641187472210820090d0620032018370360200320053a005f2003200b3a005e2003200c3b015c2003200d3a005b2003200e3a005a2003200f3b0158200320103a0057200320113a0056200320123b0154200320133a00532003200836004f2003200736004b200320143a004a200320153b014820034198036a41086a22024200370300200342003703980341d2c1c200411b20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a10082102024002402003280298032207417f460d002002450d002003200736026c2003200236026820034198036a200341e8006a10302003280298032208450d06200341a0036a2802002109200328029c03210a02402007450d002002102e0b20082009200341c8006a108a0321020240200a450d002008102e0b2002450d010c070b41014100200341c8006a108a030d060b41cae8c2002107411221080c060b41eff0c2004133200341a8046a4184f4c2001053000b2006200241014100109e020c0f0b41eff0c2004133200341a8046a4184f4c2001053000b41eff0c2004133200341a8046a4184f4c2001053000b41eff0c2004133200341a8046a4184f4c2001053000b20034198036a200341286a109003024020032802a00322090d0041b7e8c2002107411321080c010b200341b0036a280200210b200341ac036a28020021064110210820032802a403210c41dce8c2002107024020162003280298032210470d00200341b4036a280200210d200328029c032111200920034198036a41106a280200220e4105746a210a200921024100210802400240024003400240200a20026b41e0004b0d002002200a470d024100210f0c040b200341c8006a2002460d0220082002200341c8006a412010f80422074100476a21082007450d02200241206a2207200341c8006a460d0220082007200341c8006a412010f80422074100476a21082007450d02200241c0006a2207200341c8006a460d0220082007200341c8006a412010f80422074100476a21082007450d02200241e0006a2207200341c8006a460d0220024180016a210220082007200341c8006a412010f80422074100476a210820070d000c020b0b2009200e4105746a210a0340200341c8006a2002460d0120082002200341c8006a412010f80422074100476a21082007450d014100210f200a200241206a2202470d000c020b0b4101210f0b2006200d4105746a2105200621024100210702400240024003400240200520026b41e0004b0d0020022005470d024100210a0c040b200341c8006a2002460d0220072002200341c8006a412010f804220a4100476a2107200a450d02200241206a220a200341c8006a460d022007200a200341c8006a412010f804220a4100476a2107200a450d02200241c0006a220a200341c8006a460d022007200a200341c8006a412010f804220a4100476a2107200a450d02200241e0006a220a200341c8006a460d0220024180016a21022007200a200341c8006a412010f804220a4100476a2107200a0d000c020b0b0340200341c8006a2002460d0120072002200341c8006a412010f804220a4100476a2107200a450d014100210a2005200241206a2202470d000c020b0b4101210a0b024002400240024002400240024002400240201741ff01710d00200a450d010c080b200f0d0720034198036a41186a2205200341c8006a41186a29030037030020034198036a41106a220f200341c8006a41106a29030037030020034198036a41086a2212200341c8006a41086a29030037030020032003290348370398030240200c200e460d00200c21080c020b200c41016a2202200c490d0b200c4101742208200220022008491b220841ffffff3f712008470d0b200841057422024100480d0b02400240200c0d002002102921090c010b2009200c4105742002102a21090b20090d0120024101102c000b20034198036a41186a220a200341c8006a41186a29030037030020034198036a41106a2205200341c8006a41106a29030037030020034198036a41086a2212200341c8006a41086a290300370300200320032903483703980302400240200b200d460d00200b21070c010b200b41016a2202200b490d0b200b4101742207200220022007491b220741ffffff3f712007470d0b200741057422024100480d0b02400240200b0d002002102921060c010b2006200b4105742002102a21060b20060d0020024101102c000b2006200d4105746a2202200329039803370000200241186a200a290300370000200241106a2005290300370000200241086a2012290300370000200d41016a210d02400240200f450d00200e20084d0d012009200e417f6a220e4105746a22022900002118200229000821192002290010211a200920084105746a220841186a200241186a2900003700002008201a37001020082019370008200820183700000b200c21082007210b0c020b4184e9c2002008200e1038000b2009200e4105746a2202200329039803370000200241186a2005290300370000200241106a200f290300370000200241086a2012290300370000200e41016a210e200a450d00200d20074d0d012006200d417f6a220d4105746a22022900002118200229000821192002290010211a200620074105746a220741186a200241186a2900003700002007201a37001020072019370008200720183700000b200341bd036a2003290328370000200341a5036a200341c8006a41086a290300370000200341ad036a200341c8006a41106a290300370000200341b5036a200341c8006a41186a290300370000200341c5036a200341286a41086a290300370000200341cd036a200341286a41106a290300370000200341d5036a200341286a41186a290300370000200341013a009c03200341073a0098032003200329034837009d03200341e4036a200d360200200341e0036a200e360200200341dd036a20173a000041c8ecc500410020034198036a107220034198036a41086a22024200370300200342003703980341d2c1c200411b20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a10082107200328029803220a417f460d022007450d022003200a36026c2003200736026820034198036a200341e8006a1030200328029803220c450d01200341a0036a2802002102200328029c0321050240200a450d002007102e0b2005450d03200c102e0c030b4184e9c2002007200d1038000b41eff0c2004133200341a8046a4184f4c2001053000b410021020b024002400240024002400240024002400240200e20114f220a0d0041002002200d6b2207200720024b1b2011490d00200341b4036a200d36020020034198036a41186a200b36020020034198036a41106a200e360200200341a4036a2008360200200320063602ac03200320093602a0032003201136029c032003201036029803411a10292202450d01200241186a41002f0095ca423b0000200241106a410029008dca42370000200241086a4100290085ca42370000200241002900fdc9423700002003429a808080a003370294022003200236029002200341286a20034190026a10462003280294022107200328029802210a200328029002210220034190026a41186a2205420037030020034190026a41106a220c420037030020034190026a41086a220d420037030020034200370390022002200a20034190026a1000200341f0016a41186a2005290300370300200341f0016a41106a200c290300370300200341f0016a41086a200d29030037030020032003290390023703f00120034120360294022003200341f0016a3602900220034198036a20034190026a108e0302402007450d002002102e0b02402008450d002009102e0b200b0d050c060b0240200a0d00200341a5036a200341306a290300370000200341ad036a200341386a290300370000200341b5036a200341c0006a290300370000200341033a009c03200341073a0098032003200329032837009d0341c8ecc500410020034198036a10720c040b200341a5036a200341286a41086a290300370000200341ad036a200341286a41106a290300370000200341b5036a200341286a41186a290300370000200341023a009c03200341073a0098032003200329032837009d0341c8ecc500410020034198036a1072411e10292207450d01200741166a41002900fee942370000200741106a41002900f8e942370000200741086a41002900f0e942370000200741002900e8e9423700002003429e808080e00337029c032003200736029803200341286a20034198036a1046200328029c03210c20032802a003210a200328029803210720034190026a41186a2205420037030020034190026a41106a220d420037030020034190026a41086a220e420037030020034200370390022007200a20034190026a1000200341f0016a41186a2005290300370300200341f0016a41106a200d290300370300200341f0016a41086a200e29030037030020032003290390023703f0012003410036029803200341f0016a412020034198036a1008210502400240200328029803220d417f470d004113210a0c010b024020050d004113210a0c010b2003200d3602a404200320053602a00420034198036a200341a0046a10b80120032d009803220a4113460d0320034190026a20034198036a41017241870110f6041a0240200d450d002005102e0b200341f0016a412010060b200341e8006a20034190026a41870110f6041a0240200a4113470d00200c450d042007102e0c040b20034190026a200341e8006a41870110f6041a0240200c450d002007102e0b2003200a3a00980320034198036a41017220034190026a41870110f6041a200341f4006a2002360200200341e8006a41086a2011360200200341003a006c200341023a0068200341206a20034198036a200341e8006a10950220032802202102200341a5036a200341286a41086a290300370000200341ad036a200341386a290300370000200341b5036a200341c0006a290300370000200341bd036a2002453a0000200341043a009c03200341073a0098032003200329032837009d0341c8ecc500410020034198036a10720c030b411a4101102c000b411e4101102c000b41eff0c2004133200341a8046a4184f4c2001053000b411a10292202450d02200241186a41002f0095ca423b0000200241106a410029008dca42370000200241086a4100290085ca42370000200241002900fdc9423700002003429a808080a00337029c032003200236029803200341286a20034198036a1046200328029c03210a20032802a0032105200328029803210720034190026a41186a220c420037030020034190026a41106a220d420037030020034190026a41086a2202420037030020034200370390022007200520034190026a1000200341f0016a41186a200c290300370300200341f0016a41106a200d290300370300200341f0016a41086a200229030037030020032003290390023703f001200341f0016a412010060240200a450d002007102e0b20034198036a41086a22074200370300200342003703980341e0c9c200411d20034198036a100320022007290300370300200320032903980337039002200341003602980320034190026a411020034198036a10082107024002402003280298032202417f460d002003200236026c2003200736026820034198036a200341e8006a1030200328029803220a450d05200329029c03211802402002450d002007102e0b2003201837026c2003200a3602680c010b20034100360270200342013703680b200341e8006a200341286a103720034198036a41086a22024200370300200342003703980341e0c9c200411d20034198036a100320034190026a41086a20022903003703002003200329039803370390022003280268210a20032802702102200341003602a0032003420137039803200220034198036a104702402002450d0020024105742107200a21020340200220034198036a1046200241206a2102200741606a22070d000b0b200328029c03210220034190026a4110200328029803220720032802a003100402402002450d002007102e0b0240200328026c450d00200a102e0b02402008450d002009102e0b200b450d010b2006102e0b410021070c040b411a4101102c000b41eff0c2004133200341a8046a4184f4c2001053000b41ece8c2002107411621080b0240200c450d002009102e0b200b450d002006102e0b4101210a41012106410121090c0b0b200341003602a0032003420137039803200920034198036a10bc01200328029c03210720032802a0032108200328029803210220034190026a41186a220a420037030020034190026a41106a2206420037030020034190026a41086a2205420037030020034200370390022002200820034190026a1000200341c8006a41186a2208200a290300370300200341c8006a41106a220a2006290300370300200341c8006a41086a22062005290300370300200320032903900237034802402007450d002002102e0b20034198036a41186a200829030037030020034198036a41106a200a29030037030020034198036a41086a2006290300370300200320032903483703980302400240024002400240024002400240411e10292202450d00200241166a41002900fee942370000200241106a41002900f8e942370000200241086a41002900f0e942370000200241002900e8e9423700002003429e808080e00337029402200320023602900220034198036a20034190026a104620032802940221072003280298022108200328029002210220034190026a41186a220a420037030020034190026a41106a2206420037030020034190026a41086a2205420037030020034200370390022002200820034190026a1000200341f0016a41186a200a290300370300200341f0016a41106a2006290300370300200341f0016a41086a200529030037030020032003290390023703f001200341f0016a412041c8ecc500410041001005210802402007450d002002102e0b2008417f470d01024020174102490d00200341186a4186eac2004121107d200328021c21052003280218210b200341106a4186eac2004121107d200328021021072003280214210820034198036a41086a2202420037030020034200370398034186eac200412120034198036a100320034190026a41086a220a20022903003703002003200329039803370390022003200841016a410120071b3602980320034190026a411020034198036a4104100420024200370300200342003703980341e0c9c200411d20034198036a1003200a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a100821022003280298032206417f460d042002450d042003200636026c2003200236026820034198036a200341e8006a1030200328029803220a450d0320034198036a41086a220c2802002107200328029c03210802402006450d002002102e0b20034198036a41186a200341c8006a41186a29030037030020034198036a41106a200341c8006a41106a290300370300200c200341c8006a41086a290300370300200320032903483703980320034198036a210220072008470d070c060b20034198036a41086a22024200370300200342003703980341d2c1c200411b20034198036a100320034190026a41086a200229030037030020032003290398033703900241002102200341003602980320034190026a411020034198036a1008210802402003280298032207417f460d002003200736026c2003200836026820034198036a200341e8006a10302003280298032206450d05200341a0036a2802002102200328029c03210a02402007450d002008102e0b200a450d002006102e0b20034198036a200941880110f6041a2003419c026a200236020020034190026a41086a4101360200200341003a009402200341023a009002200341086a20034198036a20034190026a10950220032802082102200341a5036a200341c8006a41086a290300370000200341ad036a200341d8006a290300370000200341b5036a200341e0006a290300370000200341bd036a2002453a0000200341043a009c03200341073a0098032003200329034837009d0320034198036a21020c070b411e4101102c000b41d9e7c2002107411f21080c0b0b41eff0c2004133200341a8046a4184f4c2001053000b20034198036a41186a200341c8006a41186a29030037030020034198036a41106a200341c8006a41106a29030037030020034198036a41086a200341c8006a41086a29030037030020032003290348370398034101210a4100210820034198036a21020c010b41eff0c2004133200341a8046a4184f4c2001053000b200841016a22072008490d0220084101742206200720072006491b220641ffffff3f712006470d022006410574220c4100480d020240024020080d00200c1029210a0c010b200a2008410574200c102a210a0b2008210720062108200a450d060b200a2007410574220c6a22062002290000370000200641186a200241186a290000370000200641106a200241106a290000370000200641086a200241086a29000037000020034198036a41086a22024200370300200342003703980341e0c9c200411d20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602a0032003420137039803200741016a220220034198036a1047024020022007490d00200c41206a2107200a21020340200220034198036a1046200241206a2102200741606a22070d000b0b200328029c03210220034190026a4110200328029803220720032802a003100402402002450d002007102e0b02402008450d00200a102e0b200341e8006a41186a200341c8006a41186a290300370300200341e8006a41106a200341c8006a41106a290300370300200341e8006a41086a200341c8006a41086a2903003703002003200329034837036820034198036a200941880110f6041a411e10292202450d02200241166a41002900fee942370000200241106a41002900f8e942370000200241086a41002900f0e942370000200241002900e8e9423700002003429e808080e003370294022003200236029002200341e8006a20034190026a104620032802940221072003280298022108200328029002210220034190026a41186a220a420037030020034190026a41106a2206420037030020034190026a41086a220c420037030020034200370390022002200820034190026a1000200341f0016a41186a200a290300370300200341f0016a41106a2006290300370300200341f0016a41086a200c29030037030020032003290390023703f0012003410036029802200342013703900220034198036a20034190026a10bc012003280294022108200341f0016a4120200328029002220a200328029802100402402008450d00200a102e0b02402007450d002002102e0b20034198036a102f412010292202450d0320022003290328370000200241186a200341286a41186a290300370000200241106a200341286a41106a290300370000200241086a200341286a41086a290300370000200341e8006a41186a200341c8006a41186a290300370300200341e8006a41106a200341c8006a41106a290300370300200341e8006a41086a200341c8006a41086a29030037030020032003290348370368200341b4036a4100360200200341a4036a428180808010370200200342013702ac03200320023602a0032003201736029c03200320054100200b1b220836029803411a10292207450d04200741186a41002f0095ca423b0000200741106a410029008dca42370000200741086a4100290085ca42370000200741002900fdc9423700002003429a808080a003370294022003200736029002200341e8006a20034190026a1046200328029402210a2003280298022106200328029002210720034190026a41186a2205420037030020034190026a41106a220b420037030020034190026a41086a220c420037030020034200370390022007200620034190026a1000200341f0016a41186a2005290300370300200341f0016a41106a200b290300370300200341f0016a41086a200c29030037030020032003290390023703f00120034120360294022003200341f0016a3602900220034198036a20034190026a108e030240200a450d002007102e0b2002102e200341a5036a200341286a41086a290300370000200341ad036a200341286a41106a290300370000200341b5036a200341286a41186a290300370000200341bd036a2003290348370000200341c5036a200341c8006a41086a290300370000200341cd036a200341c8006a41106a290300370000200341d5036a200341c8006a41186a290300370000200341e4036a2017360200200341e0036a2008360200200341003a009c03200341073a0098032003200329032837009d0320034198036a21020b4100210641c8ecc5004100200210722009102e4101210a0c070b102d000b411e4101102c000b41204101102c000b411a4101102c000b200c4101102c000b2009102f2009102e410021064101210a410121090c040b4100210a200341003602a0032003420137039803200920034198036a10bc01200328029c03210720032802a0032108200328029803210220034190026a41186a2206420037030020034190026a41106a2205420037030020034190026a41086a220b420037030020034200370390022002200820034190026a1000200341e8006a41186a22082006290300370300200341e8006a41106a220c2005290300370300200341e8006a41086a2205200b290300370300200320032903900237036802402007450d002002102e0b20034198036a200941880110f6041a20034190026a410d6a200341f0016a41086a29030037000020034190026a41156a200341f0016a41106a29030037000020034190026a411d6a200341f0016a41186a29030037000041012106200341013a009402200320032903f00137009502200341023a009002200320034198036a20034190026a1095022003280200210220034198036a410d6a200529030037000020034198036a41156a200c29030037000020034198036a411d6a2008290300370000200341bd036a2002453a0000200341053a009c03200341073a0098032003200329036837009d0341c8ecc500410020034198036a10722009102e0b41012109410021070c020b2009102f2009102e410121064100210a410121090c010b20034198036a41086a22074200370300200342003703980341d2c1c200411b20034198036a100320034190026a41086a2007290300370300200320032903980337039002200341003602a0032003420137039803200220034198036a104702402002450d0020024105742107200621020340200220034198036a104a200241206a2102200741606a22070d000b0b200328029c03210220034190026a4110200328029803220720032802a003100402402002450d002007102e0b4101210a02402005450d002006102e0b4100210941012106410021070b02402004410771417f6a220241024b0d0002400240024020020e03000102000b2009450d02200141086a280200450d02200141046a280200102e0c020b200a450d01200141046a2802002202102f2002102e0c010b2006450d00200141086a2802002202102f2002102e0b2000200836020420002007360200200341b0046a24000ba65c02157f037e230041b0046b2203240002400240024002400240024002400240024002400240024002400240024020012d000022040e0500010a0302000b200341ac036a41013602002003420137029c03200341cc91c500360298032003411c36029402200341c491c50036029002200320034190026a3602a80320034198036a41b4e7c200106a000b200141086a2802002105200141046a2802002106024020022d000120022d000072450d00418df0c200210741282108410021094101210a02402005450d002006102e0b4101210b0c0d0b20062001410c6a280200220c105d20034198036a41086a22024200370300200342003703980341edc1c200411b20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a100821020240024002402003280298032207417f460d002002450d002003200736026c2003200236026820034198036a200341e8006a1030200328029803220d450d02200341a0036a280200210a200328029c03210e2007450d012002102e0c010b4101210d4100210a4100210e0b200d4100200a1b210920064100200c1b2108200d41206a200d200a1b2107200641206a2006200c1b21022006200c4105746a210f200d200a4105746a21104100211141002112410121134100211441002115410121160340024002400240024002400240024002402009450d0003402008450d02024020092008460d0020092008412010f804220a0d040b410020072007201046220a1b2109410020022002200f46220b1b21082007200741206a200a1b21072002200241206a200b1b210220090d000b0b4100210920080d05201320112006200c10df0102402012450d002013102e0b02402015450d002016102e0b0240200e450d00200d102e0b20034198036a41086a22024200370300200342003703980341edc1c200411b20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602a0032003420137039803200c20034198036a10470240200c450d00200c4105742107200621020340200220034198036a104a200241206a2102200741606a22070d000b0b200328029c03210220034190026a4110200328029803220720032802a003100402402002450d002007102e0b4101210a20050d020c140b20034198036a41186a220a200941186a29000037030020034198036a41106a220b200941106a29000037030020034198036a41086a2217200941086a2900003703002003200929000037039803024020122011470d00201141016a22082011490d0b20114101742209200820082009491b221241ffffff3f712012470d0b201241057422084100480d0b0240024020110d002008102921130c010b201320114105742008102a21130b2013450d030b201320114105746a2208200329039803370000200841186a200a290300370000200841106a200b290300370000200841086a20172903003700002007200741206a200720104622091b210a410021084100200720091b21090c050b200a417f4a0d0320034198036a41186a220a200941186a29000037030020034198036a41106a220b200941106a29000037030020034198036a41086a2217200941086a2900003703002003200929000037039803024020122011470d00201141016a22092011490d0a20114101742212200920092012491b221241ffffff3f712012470d0a201241057422094100480d0a0240024020110d002009102921130c010b201320114105742009102a21130b2013450d030b201320114105746a2209200329039803370000200941186a200a290300370000200941106a200b290300370000200941086a20172903003700002007200741206a200720104622091b210a4100200720091b21090c040b2006102e0c110b20084101102c000b20094101102c000b20034198036a41186a220a200841186a29000037030020034198036a41106a220b200841106a29000037030020034198036a41086a2217200841086a29000037030020032008290000370398030240024020152014470d00201441016a22082014490d0720144101742215200820082015491b221541ffffff3f712015470d07201541057422084100480d070240024020140d002008102921160c010b201620144105742008102a21160b2016450d010b201620144105746a2208200329039803370000200841186a200a290300370000200841106a200b290300370000200841086a2017290300370000410020022002200f46220a1b2108201441016a21142002200241206a200a1b21020c020b20084101102c000b201141016a2111200a21070c000b0b41eff0c2004133200341a8046a4184f4c2001053000b200141216a2d0000210e200141246a2802002105200341286a41186a200141196a290000370300200341286a41106a200141116a290000370300200341286a41086a200141096a290000370300200320012900013703282002411a6a2901002118200241196a2d0000210f200241186a2d00002110200241166a2f01002114200241156a2d00002111200241146a2d00002115200241126a2f01002116200241116a2d00002117200241106a2d000021122002410e6a2f010021132002410d6a2d00002106200241046a2d0000210c200241026a2f0100210d41b5f0c2002107412a21080240024020022d0000450d00410121094100210a4100210b0c010b410121094100210a4100210b20022d00014101470d002002410c6a2d0000210b2002410a6a2f0100210a200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d0000411874722107410021090b200a41ffff0371410874200841ff017172200b411874722108024020090d00200320183703602003200f3a005f200320103a005e200320143b015c200320113a005b200320153a005a200320163b0158200320173a0057200320123a0056200320133b0154200320063a00532003200836004f2003200736004b2003200c3a004a2003200d3b014820034198036a41086a22024200370300200342003703980341edc1c200411b20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a1008210202400240024002402003280298032207417f460d002002450d002003200736026c2003200236026820034198036a200341e8006a10302003280298032208450d02200341a0036a2802002109200328029c03210a02402007450d002002102e0b20082009200341c8006a108a0321020240200a450d002008102e0b2002450d010c030b41014100200341c8006a108a030d020b41cae8c2002107411221080c020b41eff0c2004133200341a8046a4184f4c2001053000b20034198036a200341286a108d03024020032802a00322090d0041b7e8c2002107411321080c010b200341b0036a2802002110200341ac036a280200210b4110210820032802a403211441dce8c2002107024020052003280298032217470d00200341b4036a2802002111200328029c032112200920034198036a41106a28020022154105746a210a200921024100210802400240024003400240200a20026b41e0004b0d002002200a470d02410021160c040b200341c8006a2002460d0220082002200341c8006a412010f80422074100476a21082007450d02200241206a2207200341c8006a460d0220082007200341c8006a412010f80422074100476a21082007450d02200241c0006a2207200341c8006a460d0220082007200341c8006a412010f80422074100476a21082007450d02200241e0006a2207200341c8006a460d0220024180016a210220082007200341c8006a412010f80422074100476a210820070d000c020b0b200920154105746a210a0340200341c8006a2002460d0120082002200341c8006a412010f80422074100476a21082007450d0141002116200a200241206a2202470d000c020b0b410121160b200b20114105746a210f200b21024100210702400240024003400240200f20026b41e0004b0d002002200f470d024100210a0c040b200341c8006a2002460d0220072002200341c8006a412010f804220a4100476a2107200a450d02200241206a220a200341c8006a460d022007200a200341c8006a412010f804220a4100476a2107200a450d02200241c0006a220a200341c8006a460d022007200a200341c8006a412010f804220a4100476a2107200a450d02200241e0006a220a200341c8006a460d0220024180016a21022007200a200341c8006a412010f804220a4100476a2107200a0d000c020b0b0340200341c8006a2002460d0120072002200341c8006a412010f804220a4100476a2107200a450d014100210a200f200241206a2202470d000c020b0b4101210a0b024002400240024002400240024002400240200e41ff01710d00200a450d010c080b20160d0720034198036a41186a220f200341c8006a41186a29030037030020034198036a41106a2216200341c8006a41106a29030037030020034198036a41086a2213200341c8006a41086a2903003703002003200329034837039803024020142015460d00201421080c020b201441016a22022014490d0b20144101742208200220022008491b220841ffffff3f712008470d0b200841057422024100480d0b0240024020140d002002102921090c010b200920144105742002102a21090b20090d0120024101102c000b20034198036a41186a220a200341c8006a41186a29030037030020034198036a41106a220f200341c8006a41106a29030037030020034198036a41086a2213200341c8006a41086a29030037030020032003290348370398030240024020102011460d00201021070c010b201041016a22022010490d0b20104101742207200220022007491b220741ffffff3f712007470d0b200741057422024100480d0b0240024020100d0020021029210b0c010b200b20104105742002102a210b0b200b0d0020024101102c000b200b20114105746a2202200329039803370000200241186a200a290300370000200241106a200f290300370000200241086a2013290300370000201141016a2111024002402016450d00201520084d0d0120092015417f6a22154105746a22022900002118200229000821192002290010211a200920084105746a220841186a200241186a2900003700002008201a37001020082019370008200820183700000b20142108200721100c020b4184e9c200200820151038000b200920154105746a2202200329039803370000200241186a200f290300370000200241106a2016290300370000200241086a2013290300370000201541016a2115200a450d00201120074d0d01200b2011417f6a22114105746a22022900002118200229000821192002290010211a200b20074105746a220741186a200241186a2900003700002007201a37001020072019370008200720183700000b200341bd036a2003290328370000200341a5036a200341c8006a41086a290300370000200341ad036a200341c8006a41106a290300370000200341b5036a200341c8006a41186a290300370000200341c5036a200341286a41086a290300370000200341cd036a200341286a41106a290300370000200341d5036a200341286a41186a290300370000200341013a009c03200341063a0098032003200329034837009d03200341e4036a2011360200200341e0036a2015360200200341dd036a200e3a000041c8ecc500410020034198036a107220034198036a41086a22024200370300200342003703980341edc1c200411b20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a10082107200328029803220a417f460d022007450d022003200a36026c2003200736026820034198036a200341e8006a10302003280298032214450d01200341a0036a2802002102200328029c03210f0240200a450d002007102e0b200f450d032014102e0c030b4184e9c200200720111038000b41eff0c2004133200341a8046a4184f4c2001053000b410021020b024002400240024002400240024002400240201520124f220a0d004100200220116b2207200720024b1b2012490d00200341b4036a201136020020034198036a41186a201036020020034198036a41106a2015360200200341a4036a20083602002003200b3602ac03200320093602a0032003201236029c032003201736029803411a10292202450d01200241186a41002f00dec9423b0000200241106a41002900d6c942370000200241086a41002900cec942370000200241002900c6c9423700002003429a808080a003370294022003200236029002200341286a20034190026a10462003280294022107200328029802210a200328029002210220034190026a41186a220f420037030020034190026a41106a2214420037030020034190026a41086a2211420037030020034200370390022002200a20034190026a1000200341f0016a41186a200f290300370300200341f0016a41106a2014290300370300200341f0016a41086a201129030037030020032003290390023703f00120034120360294022003200341f0016a3602900220034198036a20034190026a108e0302402007450d002002102e0b02402008450d002009102e0b20100d050c060b0240200a0d00200341a5036a200341306a290300370000200341ad036a200341386a290300370000200341b5036a200341c0006a290300370000200341033a009c03200341063a0098032003200329032837009d0341c8ecc500410020034198036a10720c040b200341a5036a200341286a41086a290300370000200341ad036a200341286a41106a290300370000200341b5036a200341286a41186a290300370000200341023a009c03200341063a0098032003200329032837009d0341c8ecc500410020034198036a1072411e10292207450d01200741166a410029008ee842370000200741106a4100290088e842370000200741086a4100290080e842370000200741002900f8e7423700002003429e808080e00337029c032003200736029803200341286a20034198036a1046200328029c03211420032802a003210a200328029803210720034190026a41186a220f420037030020034190026a41106a2211420037030020034190026a41086a2215420037030020034200370390022007200a20034190026a1000200341f0016a41186a200f290300370300200341f0016a41106a2011290300370300200341f0016a41086a201529030037030020032003290390023703f0012003410036029803200341f0016a412020034198036a1008210f024002402003280298032211417f470d004113210a0c010b0240200f0d004113210a0c010b200320113602a4042003200f3602a00420034198036a200341a0046a10b80120032d009803220a4113460d0320034190026a20034198036a41017241870110f6041a02402011450d00200f102e0b200341f0016a412010060b200341e8006a20034190026a41870110f6041a0240200a4113470d002014450d042007102e0c040b20034190026a200341e8006a41870110f6041a02402014450d002007102e0b2003200a3a00980320034198036a41017220034190026a41870110f6041a200341f4006a2002360200200341e8006a41086a2012360200200341003a006c200341013a0068200341206a20034198036a200341e8006a10950220032802202102200341a5036a200341286a41086a290300370000200341ad036a200341386a290300370000200341b5036a200341c0006a290300370000200341bd036a2002453a0000200341043a009c03200341063a0098032003200329032837009d0341c8ecc500410020034198036a10720c030b411a4101102c000b411e4101102c000b41eff0c2004133200341a8046a4184f4c2001053000b411a10292202450d02200241186a41002f00dec9423b0000200241106a41002900d6c942370000200241086a41002900cec942370000200241002900c6c9423700002003429a808080a00337029c032003200236029803200341286a20034198036a1046200328029c03210a20032802a003210f200328029803210720034190026a41186a2214420037030020034190026a41106a2211420037030020034190026a41086a2202420037030020034200370390022007200f20034190026a1000200341f0016a41186a2014290300370300200341f0016a41106a2011290300370300200341f0016a41086a200229030037030020032003290390023703f001200341f0016a412010060240200a450d002007102e0b20034198036a41086a22074200370300200342003703980341a9c9c200411d20034198036a100320022007290300370300200320032903980337039002200341003602980320034190026a411020034198036a10082107024002402003280298032202417f460d002003200236026c2003200736026820034198036a200341e8006a1030200328029803220a450d05200329029c03211802402002450d002007102e0b2003201837026c2003200a3602680c010b20034100360270200342013703680b200341e8006a200341286a103720034198036a41086a22024200370300200342003703980341a9c9c200411d20034198036a100320034190026a41086a20022903003703002003200329039803370390022003280268210a20032802702102200341003602a0032003420137039803200220034198036a104702402002450d0020024105742107200a21020340200220034198036a1046200241206a2102200741606a22070d000b0b200328029c03210220034190026a4110200328029803220720032802a003100402402002450d002007102e0b0240200328026c450d00200a102e0b02402008450d002009102e0b2010450d010b200b102e0b410021070c040b411a4101102c000b41eff0c2004133200341a8046a4184f4c2001053000b41ece8c2002107411621080b02402014450d002009102e0b2010450d00200b102e0b4101210a4101210b410121090c0b0b200141086a2802002109200141046a280200210e2002411a6a2901002118200241196a2d00002110200241186a2d00002114200241166a2f01002111200241156a2d00002115200241146a2d00002116200241126a2f01002117200241116a2d00002112200241106a2d000021132002410e6a2f010021062002410d6a2d0000210c200241046a2d0000210d200241026a2f01002105412a210841b5f0c20021070240024020022d0000450d004101210a4100210b4100210f0c010b4101210a4100210b4100210f20022d00014101470d002002410c6a2d0000210b2002410a6a2f0100210f200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d00004118747221074100210a0b200f41ffff0371410874200b41187472200841ff0171722108200a0d0520032018370340200320103a003f200320143a003e200320113b013c200320153a003b200320163a003a200320173b0138200320123a0037200320133a0036200320063b01342003200c3a00332003200836002f2003200736002b2003200d3a002a200320053b012820034198036a41086a22024200370300200342003703980341edc1c200411b20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a1008210202400240024002402003280298032207417f460d002002450d002003200736026c2003200236026820034198036a200341e8006a10302003280298032208450d02200341a0036a280200210a200328029c03210b02402007450d002002102e0b2008200a200341286a108a0321020240200b450d002008102e0b2002450d010c030b41014100200341286a108a030d020b41c4e7c2002107411521080c070b41eff0c2004133200341a8046a4184f4c2001053000b200341003602a0032003420137039803200920034198036a10bc01200328029c03210720032802a0032108200328029803210220034190026a41186a220a420037030020034190026a41106a220b420037030020034190026a41086a220f420037030020034200370390022002200820034190026a1000200341c8006a41186a2208200a290300370300200341c8006a41106a220a200b290300370300200341c8006a41086a220b200f290300370300200320032903900237034802402007450d002002102e0b20034198036a41186a200829030037030020034198036a41106a200a29030037030020034198036a41086a200b290300370300200320032903483703980302400240024002400240024002400240411e10292202450d00200241166a410029008ee842370000200241106a4100290088e842370000200241086a4100290080e842370000200241002900f8e7423700002003429e808080e00337029402200320023602900220034198036a20034190026a104620032802940221072003280298022108200328029002210220034190026a41186a220a420037030020034190026a41106a220b420037030020034190026a41086a220f420037030020034200370390022002200820034190026a1000200341f0016a41186a200a290300370300200341f0016a41106a200b290300370300200341f0016a41086a200f29030037030020032003290390023703f001200341f0016a412041c8ecc500410041001005210802402007450d002002102e0b2008417f470d010240200e4102490d00200341186a4196e8c2004121107d200328021c210f20032802182110200341106a4196e8c2004121107d200328021021072003280214210820034198036a41086a2202420037030020034200370398034196e8c200412120034198036a100320034190026a41086a220a20022903003703002003200329039803370390022003200841016a410120071b3602980320034190026a411020034198036a4104100420024200370300200342003703980341a9c9c200411d20034198036a1003200a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a10082102200328029803220b417f460d042002450d042003200b36026c2003200236026820034198036a200341e8006a1030200328029803220a450d0320034198036a41086a22142802002107200328029c0321080240200b450d002002102e0b20034198036a41186a200341c8006a41186a29030037030020034198036a41106a200341c8006a41106a2903003703002014200341c8006a41086a290300370300200320032903483703980320034198036a210220072008470d070c060b20034198036a41086a22024200370300200342003703980341edc1c200411b20034198036a100320034190026a41086a200229030037030020032003290398033703900241002102200341003602980320034190026a411020034198036a1008210802402003280298032207417f460d002003200736026c2003200836026820034198036a200341e8006a1030200328029803220b450d05200341a0036a2802002102200328029c03210a02402007450d002008102e0b200a450d00200b102e0b20034198036a200941880110f6041a2003419c026a200236020020034190026a41086a4101360200200341003a009402200341013a009002200341086a20034198036a20034190026a10950220032802082102200341a5036a200341c8006a41086a290300370000200341ad036a200341d8006a290300370000200341b5036a200341e0006a290300370000200341bd036a2002453a0000200341043a009c03200341063a0098032003200329034837009d0320034198036a21020c070b411e4101102c000b41d9e7c2002107411f21080c0b0b41eff0c2004133200341a8046a4184f4c2001053000b20034198036a41186a200341c8006a41186a29030037030020034198036a41106a200341c8006a41106a29030037030020034198036a41086a200341c8006a41086a29030037030020032003290348370398034101210a4100210820034198036a21020c010b41eff0c2004133200341a8046a4184f4c2001053000b200841016a22072008490d022008410174220b20072007200b491b220b41ffffff3f71200b470d02200b41057422144100480d020240024020080d0020141029210a0c010b200a20084105742014102a210a0b20082107200b2108200a450d060b200a200741057422146a220b2002290000370000200b41186a200241186a290000370000200b41106a200241106a290000370000200b41086a200241086a29000037000020034198036a41086a22024200370300200342003703980341a9c9c200411d20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602a0032003420137039803200741016a220220034198036a1047024020022007490d00201441206a2107200a21020340200220034198036a1046200241206a2102200741606a22070d000b0b200328029c03210220034190026a4110200328029803220720032802a003100402402002450d002007102e0b02402008450d00200a102e0b200341e8006a41186a200341c8006a41186a290300370300200341e8006a41106a200341c8006a41106a290300370300200341e8006a41086a200341c8006a41086a2903003703002003200329034837036820034198036a200941880110f6041a411e10292202450d02200241166a410029008ee842370000200241106a4100290088e842370000200241086a4100290080e842370000200241002900f8e7423700002003429e808080e003370294022003200236029002200341e8006a20034190026a104620032802940221072003280298022108200328029002210220034190026a41186a220a420037030020034190026a41106a220b420037030020034190026a41086a2214420037030020034200370390022002200820034190026a1000200341f0016a41186a200a290300370300200341f0016a41106a200b290300370300200341f0016a41086a201429030037030020032003290390023703f0012003410036029802200342013703900220034198036a20034190026a10bc012003280294022108200341f0016a4120200328029002220a200328029802100402402008450d00200a102e0b02402007450d002002102e0b20034198036a102f412010292202450d0320022003290328370000200241186a200341286a41186a290300370000200241106a200341286a41106a290300370000200241086a200341286a41086a290300370000200341e8006a41186a200341c8006a41186a290300370300200341e8006a41106a200341c8006a41106a290300370300200341e8006a41086a200341c8006a41086a29030037030020032003290348370368200341b4036a4100360200200341a4036a428180808010370200200342013702ac03200320023602a0032003200e36029c032003200f410020101b220836029803411a10292207450d04200741186a41002f00dec9423b0000200741106a41002900d6c942370000200741086a41002900cec942370000200741002900c6c9423700002003429a808080a003370294022003200736029002200341e8006a20034190026a1046200328029402210a200328029802210b200328029002210720034190026a41186a220f420037030020034190026a41106a2210420037030020034190026a41086a2214420037030020034200370390022007200b20034190026a1000200341f0016a41186a200f290300370300200341f0016a41106a2010290300370300200341f0016a41086a201429030037030020032003290390023703f00120034120360294022003200341f0016a3602900220034198036a20034190026a108e030240200a450d002007102e0b2002102e200341a5036a200341286a41086a290300370000200341ad036a200341286a41106a290300370000200341b5036a200341286a41186a290300370000200341bd036a2003290348370000200341c5036a200341c8006a41086a290300370000200341cd036a200341c8006a41106a290300370000200341d5036a200341c8006a41186a290300370000200341e4036a200e360200200341e0036a2008360200200341003a009c03200341063a0098032003200329032837009d0320034198036a21020b4100210b41c8ecc5004100200210722009102e4101210a0c070b102d000b411e4101102c000b41204101102c000b411a4101102c000b20144101102c000b2009102f2009102e4100210b4101210a410121090c040b200141046a280200210941b5f0c2002107412a210820022d00000d0120022d00014101470d01200241196a2d00002107200241186a2d00002108200241166a2f0100210a200241156a2d0000210b200241146a2d0000210f200241126a2f01002110200241116a2d00002114200241106a2d000021112002410e6a2f010021152002410d6a2d000021162002410c6a2d000021172002410a6a2f01002112200241096a2d00002113200241086a2d00002106200241066a2f0100210c200241056a2d0000210d200241046a2d00002105200241026a2f0100210e20032002411a6a29010037038802200320073a008702200320083a0086022003200a3b0184022003200b3a0083022003200f3a008202200320103b018002200320143a00ff01200320113a00fe01200320153b01fc01200320163a00fb01200320053a00f2012003200e3b01f001200320132012410874201741187472723600f7012003200d200c410874722006411874723600f30120034198036a41086a22024200370300200342003703980341edc1c200411b20034198036a100320034190026a41086a2002290300370300200320032903980337039002200341003602980320034190026a411020034198036a1008210702400240024002402003280298032202417f460d002003200236026c2003200736026820034198036a200341e8006a10302003280298032208450d02200341a0036a280200210a200328029c03210b02402002450d002007102e0b2008200a200341f0016a108a0321020240200b450d002008102e0b2002450d010c030b41014100200341f0016a108a030d020b41c4e7c2002107411521080c030b41eff0c2004133200341a8046a4184f4c2001053000b4100210a200341003602a0032003420137039803200920034198036a10bc01200328029c03210720032802a0032108200328029803210220034190026a41186a220b420037030020034190026a41106a220f420037030020034190026a41086a2210420037030020034200370390022002200820034190026a1000200341e8006a41186a2208200b290300370300200341e8006a41106a2214200f290300370300200341e8006a41086a220f2010290300370300200320032903900237036802402007450d002002102e0b20034198036a200941880110f6041a20034190026a410d6a200341f0016a41086a29030037000020034190026a41156a200341f0016a41106a29030037000020034190026a411d6a200341f0016a41186a2903003700004101210b200341013a009402200320032903f00137009502200341013a009002200320034198036a20034190026a1095022003280200210220034198036a410d6a200f29030037000020034198036a41156a201429030037000020034198036a411d6a2008290300370000200341bd036a2002453a0000200341053a009c03200341063a0098032003200329036837009d0341c8ecc500410020034198036a10722009102e0b41012109410021070c020b2009102f2009102e4101210b4100210a410121090c010b410021094101210b410021070b02402004410771417f6a220241024b0d0002400240024020020e03000102000b2009450d02200141086a280200450d02200141046a280200102e0c020b200a450d01200141046a2802002202102f2002102e0c010b200b450d00200141086a2802002202102f2002102e0b2000200836020420002007360200200341b0046a24000bd3ac0107017f027e017f017e157f017e017f230041d0076b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e12000102030405060708090b0c0d0e0f101112000b200341c4036a4101360200200342013702b403200341cc91c5003602b0032003411c36028401200341c491c50036028001200320034180016a3602c003200341b0036a41d491c500106a000b200141106a2903002104200141086a2903002105200141046a28020021062002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d00002111200241046a2d00002112200241026a2f01002113024002400240024020022d0000450d002003200737028c05200320083a008b05200320093a008a052003200a3b018805410121020c010b2002410c6a2d000021142002410a6a2f01002115200241096a2d00002116200241086a2d00002117200241066a2f01002118200241056a2d0000211920022d0001211a200320073703880541012102201a41ff01714101460d010b412a21164100211441b5f0c200211a410021150c010b2018410874201972201741187472211a410021020b201541ffff0371410874201441187472201641ff017172211420020d452003200737039801200320083a009701200320093a0096012003200a3b0194012003200b3a0093012003200c3a0092012003200d3b0190012003200e3a008f012003200f3a008e01200320103b018c01200320113a008b0120032014360087012003201a36008301200320123a008201200320133b0180010240200542808084fea6dee1115441002004501b450d0041e491c500211a410d21140c460b200341106a20034180016a2005200410930102402003280210450d0041f191c500211a411a21140c460b200341086a41dc98c5004119107d200328020c211a200328020821164108211420034188056a41086a22154200370300200342003703880541dc98c500411920034188056a1003200341a8076a41086a2208201529030037030020032003290388053703a807410021022003201a410020161b221641016a3602b003200341a8076a4110200341b0036a4104100441201029221a450d11201a200329038001370000200341c4036a428180808010370200201a41186a20034180016a41186a2209290300370000201a41106a20034180016a41106a290300370000201a41086a20034180016a41086a290300370000200320053703b0032003201a3602c003200320043703b8032016200341b0036a10fe0320154200370300200342003703880541c7c9c400411520034188056a10032008201529030037030020032003290388053703a807200341b0036a200341a8076a10b0030240024020032802b003221a0d00410021150c010b200341b8036a280200210220032802b4032115201a21140b200341b0036a200610fd03200341e0006a41186a2009290300370300200341e0006a41106a220820034180016a41106a290300370300200341e0006a41086a220920034180016a41086a2903003703002003200329038001370360024020152002470d00200241016a221a2002490d3a20024101742215201a201a2015491b2215ad42b0017e2207422088a70d3a2007a7221a4100480d3a0240024020020d00201a102921140c010b2014200241b0016c201a102a21140b2014450d130b2014200241b0016c220a6a200341b0036a41880110f604221a201636028801201a200329036037028c01201a4194016a2009290300370200201a419c016a2008290300370200201a41a4016a200341f8006a29030037020020034188056a41086a221a4200370300200342003703880541c7c9c400411520034188056a1003200341a8076a41086a201a29030037030020032003290388053703a807200341103602b4032003200341a8076a3602b0032014200241016a221a200341b0036a10ff010240201a2002490d00200a41b0016a211a2014210203402002102f200241b0016a2102201a41d07e6a221a0d000b0b02402015450d002014102e0b200341c8036a2004370300200341c0036a2005370300200341bc036a201636020041002115200341b8036a41003a0000200341053a00b00341c8ecc5004100200341b0036a10722006102f2006102e4101210641012116410121084100211a0c460b200141046a280200210a2002411a6a2901002107200241196a2d00002116200241186a2d00002108200241166a2f01002109200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d00002111200241046a2d00002112200241026a2f01002113024002400240024020022d0000450d002003200737028c05200320163a008b05200320083a008a05200320093b018805410121020c010b2002410c6a2d000021142002410a6a2f01002106200241096a2d00002115200241086a2d00002117200241066a2f01002118200241056a2d0000211920022d0001211a200320073703880541012102201a41ff01714101460d010b412a21154100211441b5f0c200211a410021060c010b2018410874201972201741187472211a410021020b200641ffff0371410874201441187472201541ff017172211420020d412003200737039801200320163a009701200320083a009601200320093b0194012003200b3a0093012003200c3a0092012003200d3b0190012003200e3a008f012003200f3a008e01200320103b018c01200320113a008b0120032014360087012003201a36008301200320123a008201200320133b018001200341b0036a200a10f103024020032802c00322020d00418b92c500211a41242114410121060c430b200341cc036a2802002115200341b0036a41186a280200211a20032802c4032106200341186a20034180016a20032902b403220742208620033502b003842204200341bc036a350200422086200742208884220710930120032802180d40200341e0006a41186a20034180016a41186a290300370300200341e0006a41106a220820034180016a41106a290300370300200341e0006a41086a220920034180016a41086a290300370300200320032903800137036002402006201a460d00200621160c3e0b200641016a22142006490d3820064101742216201420142016491b221641ffffff3f712016470d38201641057422144100480d380240024020060d002014102921020c010b200220064105742014102a21020b20020d3d20144101102c000b2002411a6a2901002107200241196a2d0000211a200241186a2d00002114200241166a2f01002115024020022d0000450d002003200737028c052003201a3a008b05200320143a008a05200320153b0188050c3c0b200241156a2d00002116200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002117200241026a2f01002118200141026a2d00002119200141046a280200211b20022d0001210220012d0001211c200320073703880541012106200241ff01714101460d060c3b0b2002411a6a2901002107200241196a2d0000211a200241186a2d00002114200241166a2f01002106024020022d0000450d002003200737028c052003201a3a008b05200320143a008a05200320063b0188050c3b0b200141026a2d00002118200141046a280200211920012d0001211b200241156a2d00002115200241146a2d00002116200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211720022d000121022003200737038805200241ff01714101470d3a20032007370398012003201a3a009701200320143a009601200320063b019401200320153a009301200320163a009201200320083b019001200320093a008f012003200a3a008e012003200b3b018c012003200c3a008b01200320133a008201200320173b0180012003200e410874200d41187472200f72360087012003201141087420127220104118747236008301200341b0036a20034180016a10ff0320032d00b0034101470d39200341bc036a2d00002102200341bd036a2900002107200341c5036a280000211a20032f00b103211420032d00b303210620032902b40321042003200341c9036a2900003703c8032003201a3602c403200320073702bc03200320023a00bb03200320043700b303200320063a00b203200320143b01b003200341b0036a2019201b41ff01714100472018108004211a41222114410121060c400b41bbb7c200211a410e211420022d0000417f6a220941024b0d3e200141046a280200210a410121064101211641012108410121150240024020090e03004401000b200241046a2d00000d3f41012106410121164101210841012115200241086a28020041036c2002410c6a280200410174490d430b200341b0036a200a108103024020032d00c0044103470d0041e596c500211a410d2114410121060c400b20032802b003210220034198026a200341b0036a41047241940110f6041a200320023602800120034180016a41047220034198026a41940110f6041a200341003602b803200342013703b00320034180016a200341b0036a10bc0120032802b403211a20032802b803211420032802b0032102200341a8076a41186a22064200370300200341a8076a41106a22154200370300200341a8076a41086a22164200370300200342003703a80720022014200341a8076a100020034198026a41186a2214200629030037030020034198026a41106a2206201529030037030020034198026a41086a22152016290300370300200320032903a807370398020240201a450d002002102e0b200341b0036a41186a2014290300370300200341b0036a41106a2006290300370300200341b0036a41086a201529030037030020032003290398023703b003411710292202450d0f2002410f6a41002900e39245370000200241086a41002900dc9245370000200241002900d4924537000020034297808080f0023702c406200320023602c006200341b0036a200341c0066a104620032802c406211a20032802c806211420032802c0062102200341a8076a41186a22064200370300200341a8076a41106a22154200370300200341a8076a41086a22164200370300200342003703a80720022014200341a8076a100020034188076a41186a200629030037030020034188076a41106a201529030037030020034188076a41086a2016290300370300200320032903a8073703880720034188076a412041c8ecc50041004100100521140240201a450d002002102e0b2014417f460d3720034180016a102f41f296c500211a41252114410121060c3f0b200141046a280200210641bbb7c200211a410e211420022d0000417f6a221541024b0d350240024020150e03003701000b200241086a2802004101742002410c6a280200490d36200241046a28020041ff01710d360b20034188056a41086a2202420037030020034200370388054198cbc400411620034188056a1003200341a8076a41086a221a200229030037030020032003290388053703a807200341a8076a411041c8ecc500410041001005417f460d30418593c500211a411521140c350b200141046a280200211a0240024020022d0000417f6a221441024b0d00024020140e03000102000b200241046a2d00000d00200241086a2802004102742002410c6a28020041036c4f0d010b201a102f201a102e41bbb7c200211a410e21144100211641012106410121080c3f0b200341b0036a201a41880110f6041a200341023a00b80420034188056a41086a2202420037030020034200370388054198cbc400411620034188056a1003200341a8076a41086a200229030037030020032003290388053703a80720034100360288012003420137038001200341b0036a20034180016a10bc01024020032d00b804220241024b0d00024002400240024020020e03000102000b410021140c020b410121140c010b410221140b200320143a00cf07024002402003280284012003280288012202460d0020032802800121060c010b200241016a22142002490d3520024101742206201420142006491b22144100480d350240024020020d002014102921060c010b20032802800120022014102a21060b2006450d102003201436028401200320063602800120032d00cf07211420032802880121020b2003200241016a36028801200620026a20143a00000b2003280284012102200341a8076a41102003280280012214200328028801100402402002450d002014102e0b200341b0036a102f201a102e41002116410121060c300b200141046a280200211a0240024020022d0000417f6a221441024b0d00024020140e03000102000b200241086a2802002002410c6a280200490d00200241046a28020041ff0171450d010b201a102f201a102e41bbb7c200211a410e21144100210841012106410121160c3e0b200341b0036a201a41880110f6041a200341013a00b80420034188056a41086a2202420037030020034200370388054198cbc400411620034188056a1003200341a8076a41086a200229030037030020032003290388053703a80720034100360288012003420137038001200341b0036a20034180016a10bc01024020032d00b804220241024b0d00024002400240024020020e03000102000b410021140c020b410121140c010b410221140b200320143a00cf07024002402003280284012003280288012202460d0020032802800121060c010b200241016a22142002490d3420024101742206201420142006491b22144100480d340240024020020d002014102921060c010b20032802800120022014102a21060b2006450d102003201436028401200320063602800120032d00cf07211420032802880121020b2003200241016a36028801200620026a20143a00000b2003280284012102200341a8076a41102003280280012214200328028801100402402002450d002014102e0b200341b0036a102f201a102e4100210841012106410121160c300b200141286a2802002108200141246a2802002116200341d8066a200141196a290000370300200341d0066a200141116a290000370300200341c0066a41086a200141096a290000370300200320012900013703c0064101210641bbb7c200211a410e211420022d0000417e6a221541014b0d3b0240024020150e020001000b200241046a2d00000d3c200241086a28020041036c2002410c6a280200410174490d3c0b20034188056a41086a2202420037030020034200370388054198cbc400411620034188056a1003200341a8076a41086a200229030037030020032003290388053703a807200341b0036a200341a8076a10b103024020032d00b80422024103470d0041d093c500211a411021140c3c0b20032802b003211a20034198026a200341b0036a41047241840110f6041a2003201a3602800120034180016a41047220034198026a41840110f6041a20020d2b41a693c500211a412a21140c2c0b200320073703c8032003201a3a00c703200320143a00c603200320153b01c403200320163a00c303200320083a00c203200320093b01c0032003200a3a00bf032003200b3a00be032003200c3b01bc032003200d3a00bb03200320173a00b203200320183b01b0032003200f410874200e411874722010723600b703200320124108742013722011411874723600b303200341b0036a201b201c41ff01714100472019108004211a412221140c3a0b20034190066a200141196a290000370300200341f8056a41106a200141116a290000370300200341f8056a41086a200141096a290000370300200320012900013703f80541bbb7c200211a410e211420022d00004102470d38200241236a2d00002115200241216a2f000021162002411f6a2d000021082002411d6a2f000021092002410f6a2d0000210a2002410d6a2f0000210b2002410b6a2d0000210c200241096a2f0000210d200241076a2d0000210e200241056a2f0000210f200241246a3502002105200241206a310000211d200241116a2900002107200241106a2d000021102002410c6a2d00002111200241086a2d00002112200241046a2d000021062003200241196a28000036029005200320073703880520064101470d382003200329028c0522043d01d006200320103a00cb06200320044238883c00d706200320044230883c00d606200320044220883d01d406200320044218883c00d306200320044210883c00d206200320073d01cc06200320074218883c00cf062003200b200a411074724108742011723600c7062003200d200c411074724108742012723600c3062003200f200e4110747222023b01c006200320024110763a00c20620032007a74110763a00ce062003201d4218862009200841107472ad42ffffff0783842016201541107472ad42ffffff0783422086842005423886843703d80620034188056a41086a2202420037030020034200370388054198cbc400411620034188056a1003200341a8076a41086a221a200229030037030020032003290388053703a807200341b0036a200341a8076a10b1030240024020032d00b8044103460d0020034180016a200341b0036a41880110f6041a200341b0036a20034180016a41880110f6041a200341003602a0022003420137039802200341b0036a20034198026a10bc01200328029c02211420032802a00221062003280298022102200341a8076a41186a22154200370300200341a8076a41106a22164200370300201a4200370300200342003703a80720022006200341a8076a100020034198026a41186a201529030037030020034198026a41106a201629030037030020034198026a41086a201a290300370300200320032903a8073703980202402014450d002002102e0b200341f8056a20034198026a412010f8042102200341b0036a102f2002450d0141102114418794c500211a410121060c3b0b4114211441f393c500211a410121060c3a0b200341b0036a200341f8056a10810420032802b40322150d264100210241012115420021070c270b4101210620022d000120022d0000720d24200141046a2802001085030c340b4101210620022d000120022d0000720d232001410c6a2802002115200141086a280200210220034180016a200141046a28020022161086032003280280012114024002400240200328028801221a20024d0d00201420024190016c6a22082d00004113460d01201420024190016c6a4188016a2802002015470d012008102f200841133a00002003280284012115411710292202450d0d2002410f6a410029008fc944370000200241086a4100290088c94437000020024100290080c94437000020024117412e102a2202450d0e20022016360017200341a8076a41186a22164200370300200341a8076a41106a22084200370300200341a8076a41086a22094200370300200342003703a8072002411b200341a8076a100020034188076a41186a201629030037030020034188076a41106a200829030037030020034188076a41086a2009290300370300200320032903a80737038807200341b0036a2014201a10be0120034188076a412020032802b003221620032802b8031004024020032802b403450d002016102e0b2002102e201a4190016c211a201421020340024020022d00004113460d002002102f0b20024190016a2102201a41f07e6a221a0d000b2015450d362014102e0c360b201a450d010b201a4190016c211a201421020340024020022d00004113460d002002102f0b20024190016a2102201a41f07e6a221a0d000b0b0240200328028401450d002014102e0b419797c500211a411221140c370b20034198026a41186a200141196a29000037030020034198026a41106a200141116a29000037030020034198026a41086a200141096a2900003703002003200129000137039802200241166a2f0100211a200241186a2d00002114200241196a2d000021062002411a6a2901002107024020022d0000450d002003200737028c05200320063a008b05200320143a008a052003201a3b0188050c310b200241026a2f01002115200241046a2d00002116200241056a2d00002108200241066a2f01002109200241086a2d0000210a200241096a2d0000210b2002410a6a2f0100210c2002410c6a2d0000210d2002410d6a2d0000210e2002410e6a2f0100210f200241106a2d00002110200241116a2d00002111200241126a2f01002112200241146a2d00002113200241156a2d0000211720022d000121022003200737038805200241ff01714101470d30410f10292202450d0b200241002900bd9445370000200241076a41002900c494453700002003428f808080f0013702b403200320023602b00320034198026a200341b0036a104a20032802b403211820032802b803211920032802b0032102200341a8076a41186a221b4200370300200341a8076a41106a221c4200370300200341a8076a41086a221e4200370300200342003703a80720022019200341a8076a100020034188076a41186a201b29030037030020034188076a41106a201c29030037030020034188076a41086a201e290300370300200320032903a8073703880720034188076a412041c8ecc500410041001005211902402018450d002002102e0b02402019417f460d0041cc94c500211a410f2114410121060c370b20034180016a41186a20034198026a41186a29030037030020034180016a41106a20034198026a41106a29030037030020034180016a41086a20034198026a41086a290300370300200320032903980237038001200320073703c803200320063a00c703200320143a00c6032003201a3b01c403200320173a00c303200320133a00c203200320123b01c003200320113a00bf03200320103a00be032003200f3b01bc032003200e3a00bb032003200c410874200b72200d411874723600b70320032009410874200872200a411874723600b303200320163a00b203200320153b01b003410f10292202450d0c4100211a200241002900bd9445370000200241076a41002900c494453700002003428f808080f0013702c406200320023602c00620034180016a200341c0066a104a20032802c406211420032802c806210620032802c0062102200341a8076a41186a22154200370300200341a8076a41106a22164200370300200341a8076a41086a22084200370300200342003703a80720022006200341a8076a100020034188076a41186a201529030037030020034188076a41106a201629030037030020034188076a41086a2008290300370300200320032903a80737038807200341203602c406200320034188076a3602c006200341b0036a200341c0066a109a0202402014450d002002102e0b410121060c360b2002411a6a2901002107200241196a2d0000211a200241186a2d00002114200241166a2f01002106024020022d0000450d002003200737028c052003201a3a008b05200320143a008a05200320063b0188050c300b200241156a2d00002115200241146a2d00002116200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211720022d000121022003200737038805200241ff01714101470d2f200320073703c8032003201a3a00c703200320143a00c603200320063b01c403200320153a00c303200320163a00c203200320083b01c003200320093a00bf032003200a3a00be032003200b3b01bc032003200c3a00bb03200320133a00b203200320173b01b0032003200e410874200f72200d411874723600b703200320114108742012722010411874723600b303410f10292202450d0c4100211a200241002900bd9445370000200241076a41002900c494453700002003428f808080f001370284012003200236028001200341b0036a20034180016a104a200328028401211420032802880121062003280280012102200341a8076a41186a22154200370300200341a8076a41106a22164200370300200341a8076a41086a22084200370300200342003703a80720022006200341a8076a100020034188076a41186a201529030037030020034188076a41106a201629030037030020034188076a41086a2008290300370300200320032903a8073703880720034188076a4120100602402014450d002002102e0b410121060c320b200341c0066a41186a200141196a290000370300200341c0066a41106a200141116a290000370300200341c0066a41086a200141096a290000370300200320012900013703c0062002411a6a2901002107200241196a2d0000211a200241186a2d00002114200241166a2f01002106024020022d0000450d002003200737028c052003201a3a008b05200320143a008a05200320063b0188050c2f0b200241156a2d00002115200241146a2d00002116200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211720022d000121022003200737038805200241ff01714101470d2e200320073703b0022003201a3a00af02200320143a00ae02200320063b01ac02200320153a00ab02200320163a00aa02200320083b01a802200320093a00a7022003200a3a00a6022003200b3b01a4022003200c3a00a302200320133a009a02200320173b0198022003200e410874200f72200d4118747236009f022003201141087420127220104118747236009b02200341b0036a200341c0066a10ff0320032d00b0034101470d2d200320032902b40337008301200320032d00b3033a008201200320032f00b1033b0180012003200341c9036a290000370398012003200341c5036a280000360294012003200341bd036a29000037028c012003200341bc036a2d00003a008b01024020034180016a20034198026a412010f804450d0041db94c500211a410b2114410121060c350b200341b0036a41186a200341c0066a41186a290300370300200341b0036a41106a200341c0066a41106a290300370300200341b0036a41086a200341c0066a41086a290300370300200320032903c0063703b003410f10292202450d0c4100211a200241002900bd9445370000200241076a41002900c494453700002003428f808080f001370284012003200236028001200341b0036a20034180016a104a200328028401211420032802880121062003280280012102200341a8076a41186a22154200370300200341a8076a41106a22164200370300200341a8076a41086a22084200370300200342003703a80720022006200341a8076a100020034188076a41186a201529030037030020034188076a41106a201629030037030020034188076a41086a2008290300370300200320032903a8073703880720034188076a4120100602402014450d002002102e0b410121060c340b200141216a2d0000210a200341c0006a41186a200141196a290000370300200341c0006a41106a200141116a290000370300200341c0006a41086a200141096a290000370300200320012900013703402002411a6a2901002107200241196a2d00002116200241186a2d00002108200241166a2f01002109200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d00002111200241046a2d00002112200241026a2f01002113024002400240024020022d0000450d002003200737028c05200320163a008b05200320083a008a05200320093b018805410121020c010b2002410c6a2d000021142002410a6a2f01002106200241096a2d00002115200241086a2d00002117200241066a2f01002118200241056a2d0000211920022d0001211a200320073703880541012102201a41ff01714101460d010b41b5f0c200211a41002106412a2115410021140c010b2018410874201972201741187472211a410021020b200641ffff0371410874201541ff017172201441187472211420020d32200320143600cf042003201a3600cb04200320123a00ca04200320133b01c8042003200e3a00d7042003200f3a00d604200320103b01d404200320113a00d304200320163a00df04200320083a00de04200320093b01dc042003200b3a00db042003200c3a00da042003200d3b01d804200320073703e004200341e8046a41186a2007370300200341e8046a41106a20032903d804370300200341e8046a41086a200341c8046a41086a290300370300200320032903c8043703e80420034188056a41186a200341c0006a41186a29030037030020034188056a41106a200341c0006a41106a29030037030020034188056a41086a200341c0006a41086a2903003703002003200a3a00a8052003200329034037038805411510292202450d0c200241002900bec8443700002002410d6a41002900cbc844370000200241086a41002900c6c84437000020034295808080d0023702b403200320023602b003200341e8046a200341b0036a104a20032802b403210820032802b803210220032802b003211a200341a8076a41186a22064200370300200341a8076a41106a22164200370300200341a8076a41086a22154200370300200342003703a807201a2002200341a8076a100020034188076a41186a2209200629030037030020034188076a41106a201629030037030020034188076a41086a220a2015290300370300200320032903a8073703880720034198026a20034188076a10b2030240024020032d00b90222164102470d0020064200370300200341a8076a41106a2216420037030020154200370300200342003703a80741aac9c400411d200341a8076a10002009200629030037030020034188076a41106a22062016290300370300200a2015290300370300200320032903a80737038807200341f8056a20034188076a412010dc01024020032d00f8050d00200341a8076a41186a2215420037030020164200370300200341a8076a41086a22094200370300200342003703a80741aac9c400411d200341a8076a100020034188076a41186a20152903003703002006201629030037030020034188076a41086a2009290300370300200320032903a80737038807200341203602b403200320034188076a3602b003200341e8046a200341b0036a109a0241002106410021160c020b200341d8056a41186a20034191066a290000370300200341d8056a41106a20034189066a290000370300200341d8056a41086a20034181066a290000370300200320032900f9053703d805411510292206450d0f200641002900bec8443700002006410d6a41002900cbc844370000200641086a41002900c6c84437000020034295808080d0023702b403200320063602b003200341d8056a200341b0036a104a20032802b403210a20032802b803211620032802b0032115200341a8076a41186a22094200370300200341a8076a41106a22064200370300200341a8076a41086a220b4200370300200342003703a80720152016200341a8076a100020034188076a41186a200929030037030020034188076a41106a220c200629030037030020034188076a41086a200b290300370300200320032903a80737038807200341b0036a20034188076a10b20320032d00d1034102460d1020034180016a200341b0036a41e30010f6041a200341c0066a41206a220b20034180016a41206a22092d00003a0000200341c0066a41186a220d20034180016a41186a220e290300370300200341c0066a41106a220f20034180016a41106a2210290300370300200341c0066a41086a221120034180016a41086a221229030037030020032003290380013703c006200341b0036a200341a1016a41c20010f6041a2009200b2d00003a0000200e200d2903003703002010200f29030037030020122011290300370300200341a8016a200341d2036a410020032d00d1034101461b360200200320032903c006370380012003200341e8046a3602a401200341a8076a41186a220b420037030020064200370300200341a8076a41086a220d4200370300200342003703a80720152016200341a8076a100020034188076a41186a200b290300370300200c200629030037030020034188076a41086a200d290300370300200320032903a80737038807200341003602b007200342013703a80720034180016a200341a8076a104a024020092d0000220641064b0d000240024002400240024002400240024020060e0700010203040506000b410021160c060b410121160c050b410221160c040b410321160c030b410421160c020b410521160c010b410621160b200320163a00cf070240024020032802ac0720032802b0072206460d0020032802a80721090c010b200641016a22162006490d2d20064101742209201620162009491b22164100480d2d0240024020060d002016102921090c010b20032802a80720062016102a21090b2009450d13200320163602ac07200320093602a80720032d00cf07211620032802b00721060b2003200641016a3602b007200920066a20163a00000b0240024020032802a40122090d0041002109200341003a00cf070240024020032802ac0720032802b0072206460d0020032802a80721160c010b200641016a22162006490d2e20064101742209201620162009491b22094100480d2e0240024020060d002009102921160c010b20032802a80720062009102a21160b2016450d15200320093602ac07200320163602a80720032d00cf07210920032802b00721060b2003200641016a3602b007201620066a20093a00000c010b4101210b200341013a00cf070240024020032802ac0720032802b0072206460d0020032802a80721160c010b200641016a22162006490d2d2006410174220b20162016200b491b220b4100480d2d0240024020060d00200b102921160c010b20032802a8072006200b102a21160b2016450d152003200b3602ac07200320163602a80720032d00cf07210b20032802b00721060b2003200641016a3602b007201620066a200b3a00002009200341a8076a104a0b0240024020032802a80122090d0041002109200341003a00cf070240024020032802ac0720032802b0072206460d0020032802a80721160c010b200641016a22162006490d2e20064101742209201620162009491b22094100480d2e0240024020060d002009102921160c010b20032802a80720062009102a21160b2016450d17200320093602ac07200320163602a80720032d00cf07210920032802b00721060b2003200641016a3602b007201620066a20093a00000c010b4101210b200341013a00cf070240024020032802ac0720032802b0072206460d0020032802a80721160c010b200641016a22162006490d2d2006410174220b20162016200b491b220b4100480d2d0240024020060d00200b102921160c010b20032802a8072006200b102a21160b2016450d172003200b3602ac07200320163602a80720032d00cf07210b20032802b00721060b2003200641016a3602b007201620066a200b3a00002009200341a8076a104a0b20032802ac07210620034188076a412020032802a807221620032802b007100402402006450d002016102e0b0240200a450d002015102e0b200341a8076a41186a22064200370300200341a8076a41106a22154200370300200341a8076a41086a22164200370300200342003703a80741aac9c400411d200341a8076a100020034188076a41186a200629030037030020034188076a41106a201529030037030020034188076a41086a2016290300370300200320032903a80737038807200341203602b403200320034188076a3602b003200341e8046a200341b0036a109a02200341b8056a41086a200341d8056a41086a290300370300200341b8056a41106a200341d8056a41106a290300370300200341b8056a41186a200341d8056a41186a290300370300200320032903d8053703b80541012106410021160c010b200341e0006a41186a200341d2026a290100370300200341e0006a41106a200341ca026a290100370300200341e0006a41086a200341c2026a290100370300200341b8056a41086a200341e3026a290000370300200341b8056a41106a200341eb026a290000370300200341b8056a41186a200341f3026a290000370300200320032901ba023703602003200341db026a2900003703b805200341da026a2d000021060b200341d5036a20063a0000200341d6036a20032903b805370100200341bd036a200341e0006a41086a290300370000200341c5036a200341e0006a41106a290300370000200341cd036a200341e0006a41186a290300370000200341de036a200341b8056a41086a290300370100200341e6036a200341b8056a41106a290300370100200341ee036a200341b8056a41186a290300370100200320163a00b403200320032903603700b503200320034188056a3602b003200341a8076a41186a22064200370300200341a8076a41106a22154200370300200341a8076a41086a22164200370300200342003703a807201a2002200341a8076a100020034188076a41186a200629030037030020034188076a41106a201529030037030020034188076a41086a2016290300370300200320032903a807370388072003410036028801200342013703800120034188056a20034180016a104a024020032d00a805220241064b0d000240024002400240024002400240024020020e0700010203040506000b410021060c060b410121060c050b410221060c040b410321060c030b410421060c020b410521060c010b410621060b200320063a00cf07024002402003280284012003280288012202460d0020032802800121150c010b200241016a22062002490d2b20024101742215200620062015491b22064100480d2b0240024020020d002006102921150c010b20032802800120022006102a21150b2015450d162003200636028401200320153602800120032d00cf07210620032802880121020b2003200241016a36028801201520026a20063a00000b200341b0036a41047220034180016a10de03200328028401210220034188076a41202003280280012206200328028801100402402002450d002006102e0b02402008450d00201a102e0b200342e4cab5fbb6ccdcb0e3003703b005200341b0056a200341c8046a417f108f01200341b0036a41086a41083a0000200341b9036a20032903c804370000200341c1036a200341c8046a41086a290300370000200341c9036a200341c8046a41106a290300370000200341d1036a200341c8046a41186a290300370000200341d9036a2003290340370000200341e1036a200341c0006a41086a290300370000200341e9036a200341c0006a41106a290300370000200341f1036a200341c0006a41186a290300370000200341053a00b0034100211a41c8ecc5004100200341b0036a1072410121060c330b2002411a6a2901002107200241196a2d00002116200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d00002110200241046a2d00002111200241026a2f01002112024002400240024020022d0000450d002003200737028c05200320163a008b05200320083a008a05200320093b018805410121020c010b2002410c6a2d000021142002410a6a2f01002106200241096a2d00002115200241086a2d00002113200241066a2f01002117200241056a2d0000211820022d0001211a200320073703880541012102201a41ff01714101460d010b41b5f0c200211a41002106412a2115410021140c010b2017410874201872201341187472211a410021020b200641ffff0371410874201541ff017172201441187472211420020d31200320073703f005200320163a00ef05200320083a00ee05200320093b01ec052003200a3a00eb052003200b3a00ea052003200c3b01e8052003200d3a00e7052003200e3a00e6052003200f3b01e405200320103a00e305200320143600df052003201a3600db05200320113a00da05200320123b01d805411510292202450d14200241002900bec844370000410d21142002410d6a41002900cbc844370000200241086a41002900c6c84437000020034295808080d0023702b403200320023602b003200341d8056a200341b0036a104a20032802b403211a20032802b803210620032802b0032102200341a8076a41186a22154200370300200341a8076a41106a22164200370300200341a8076a41086a22084200370300200342003703a80720022006200341a8076a100020034188076a41186a201529030037030020034188076a41106a201629030037030020034188076a41086a2008290300370300200320032903a8073703880720034188076a412041c8ecc50041004100100521060240201a450d002002102e0b02402006417f470d0041d896c500211a410121060c330b411510292202450d15200241002900bec8443700002002410d6a41002900cbc844370000200241086a41002900c6c84437000020034295808080d0023702b403200320023602b003200341d8056a200341b0036a104a20032802b403210620032802b803210220032802b003211a200341a8076a41186a22144200370300200341a8076a41106a22154200370300200341a8076a41086a22164200370300200342003703a807201a2002200341a8076a100020034188076a41186a201429030037030020034188076a41106a201529030037030020034188076a41086a2016290300370300200320032903a80737038807200341b0036a20034188076a10b203024020032d00d10322024102460d0020034188076a412010060b20034188056a41186a200341b0036a41186a29030037030020034188056a41106a200341b0036a41106a29030037030020034188056a41086a200341b0036a41086a290300370300200320032903b0033703880520032d00d0032114200341f8056a200341d2036a41c10010f6041a02402006450d00201a102e0b200341b8056a41086a221a20034188056a41086a290300370300200341b8056a41106a220620034188056a41106a290300370300200341b8056a41186a221520034188056a41186a29030037030020032003290388053703b805200341c0066a200341f8056a41c10010f6041a20024102460d1c200341e0006a41186a2015290300370300200341e0006a41106a2006290300370300200341e0006a41086a201a290300370300200320032903b805370360200320023a00980220034198026a410172200341c0066a41c10010f6042108200341ba026a21060240024020032d00b9024101460d004100211a0c010b411510292202450d17200241002900bec8443700002002410d6a41002900cbc844370000200241086a41002900c6c84437000020034295808080d0023702b403200320023602b0032006200341b0036a104a20032802b803210a20032802b403211620032802b003211a20032d00980221020b02400240200241ff01714101470d00411510292202450d19200241002900bec8443700002002410d6a41002900cbc844370000200241086a41002900c6c84437000020034295808080d0023702b403200320023602b0032008200341b0036a104a20032802b403211520032802b00322020d010b20032d00b9022102200341a8076a41186a22084200370300200341a8076a41106a22094200370300200341a8076a41086a220b4200370300200342003703a80741aac9c400411d200341a8076a100020034188076a41186a200829030037030020034188076a41106a200929030037030020034188076a41086a200b290300370300200320032903a80737038807024020024101460d0020034188076a412010060c1c0b200341203602b403200320034188076a3602b0032006200341b0036a109a020c1b0b20032802b803210b200341a8076a41186a22084200370300200341a8076a41106a22094200370300200341a8076a41086a22064200370300200342003703a8072002200b200341a8076a100020034188076a41186a220c200829030037030020034188076a41106a220d200929030037030020034188076a41086a2006290300370300200320032903a80737038807200341b0036a20034188076a10b20320032d00d1034102460d1820034180016a200341b0036a41c20010f6041a20034180016a41c2006a200341b9026a2206290000370100200341ca016a200641086a290000370100200341d2016a200641106a290000370100200341da016a200641186a290000370100200341e2016a200641206a2d00003a00002008420037030020094200370300200341a8076a41086a22064200370300200342003703a8072002200b200341a8076a1000200c2008290300370300200d200929030037030020034188076a41086a2006290300370300200320032903a80737038807200341003602b803200342013703b00320034180016a200341b0036a104a024020032d00a001220641064b0d000240024002400240024002400240024020060e0700010203040506000b410021080c060b410121080c050b410221080c040b410321080c030b410421080c020b410521080c010b410621080b200320083a00a8070240024020032802b40320032802b8032206460d0020032802b00321090c010b200641016a22092006490d2a2006410174220b20092009200b491b220b4100480d2a0240024020060d00200b102921090c010b20032802b0032006200b102a21090b2009450d1b2003200b3602b403200320093602b00320032802b80321060b2003200641016a3602b803200920066a20083a00000b200341a1016a200341b0036a10de0320032802b403210620034188076a412020032802b003220820032802b803100402402006450d002008102e0b4101210b024020150d00410021150c1c0b2002102e0c1b0b41204101102c000b201a4108102c000b41174101102c000b20144101102c000b20144101102c000b41174101102c000b412e4101102c000b410f4101102c000b410f4101102c000b410f4101102c000b410f4101102c000b41154101102c000b41154101102c000b41e694c500419f01109b01000b20164101102c000b20094101102c000b200b4101102c000b20094101102c000b200b4101102c000b20064101102c000b41154101102c000b41154101102c000b41154101102c000b41154101102c000b418596c50041d300109b01000b200b4101102c000b410021024100210b0b02400240024002400240201a0d00410021060c010b200341a8076a41186a22064200370300200341a8076a41106a22084200370300200341a8076a41086a22094200370300200342003703a807201a200a200341a8076a100020034188076a41186a220c200629030037030020034188076a41106a220d200829030037030020034188076a41086a220e2009290300370300200320032903a80737038807200341b0036a20034188076a10b20320032d00d1034102460d0120034180016a200341b0036a41e30010f6041a200341a9016a20034198026a41086a290300370000200341b1016a20034198026a41106a290300370000200341b9016a20034198026a41186a290300370000200341c1016a20034198026a41206a2d00003a000020032003290398023700a101200642003703002008420037030020094200370300200342003703a807201a200a200341a8076a1000200c2006290300370300200d2008290300370300200e2009290300370300200320032903a80737038807200341003602b803200342013703b00320034180016a200341b0036a104a024020032d00a001220641064b0d000240024002400240024002400240024020060e0700010203040506000b410021080c060b410121080c050b410221080c040b410321080c030b410421080c020b410521080c010b410621080b200320083a00a8070240024020032802b40320032802b8032206460d0020032802b00321090c010b200641016a22092006490d122006410174220a20092009200a491b220a4100480d120240024020060d00200a102921090c010b20032802b0032006200a102a21090b2009450d042003200a3602b403200320093602b00320032802b80321060b2003200641016a3602b803200920066a20083a00000b200341a1016a200341b0036a10de0320032802b403210620034188076a412020032802b003220820032802b803100402402006450d002008102e0b410121062016450d00201a102e0b2015450d02200b200245720d022002102e0c020b418596c50041d300109b01000b200a4101102c000b02402016450d00201a452006720d00201a102e0b201441ff01714107470d010b410021140b200341386a41b0f3c200410d107d200342e4cab5fbb6ccdcb0e300370380014100211a20034180016a200341d8056a427f427f200328023c410020032802381b201441187441187541027441c098c5006a2802004180af1a6c6a4102109101200341b0036a41086a41093a0000200341b0036a41096a20032903d805370000200341c1036a200341d8056a41086a290300370000200341c9036a200341e8056a290300370000200341d1036a200341d8056a41186a290300370000200341053a00b00341c8ecc5004100200341b0036a1072410121060c140b418df0c200211a412821140c130b410021020240024020032903b8032207422088a7221a41014b0d00201a0e020201020b0340201a410176221420026a22062002201520064105746a200341c0066a412010f8044101481b2102201a20146b221a41014b0d000b0b201520024105746a200341c0066a412010f804221a450d01201a411f7620026a21020b200341b0036a41186a200341c0066a41186a290300370300200341b0036a41106a200341c0066a41106a290300370300200341b0036a41086a200341c0066a41086a290300370300200320032903c0063703b003024002400240024020022007422088a7221a4b0d000240201a2007a7470d00201a41016a2214201a490d0c201a4101742206201420142006491b221441ffffff3f712014470d0c201441057422064100480d0c02400240201a0d002006102921150c010b2015201a4105742006102a21150b2015450d022014ad21070b201520024105746a221441206a2014201a20026b41057410f7041a201441186a200341b0036a41186a290300370000201441106a200341b0036a41106a290300370000201441086a200341b0036a41086a290300370000201420032903b003370000200341306a41b0f3c200410d107d2003280234210620032802302116411310292202450d022002410f6a41002800ef9345360000200241086a41002900e89345370000200241002900e0934537000020034293808080b0023702b403200320023602b003200341f8056a200341b0036a104620032802b403210820032802b803210220032802b0032114200341a8076a41186a22094200370300200341a8076a41106a220a4200370300200341a8076a41086a220b4200370300200342003703a80720142002200341a8076a100020034188076a41186a200929030037030020034188076a41106a200a29030037030020034188076a41086a200b290300370300200320032903a80737038807410410292202450d0320034284808080c0003702b403200320023602b003200220064180ce186a4180ce1820161b2206360000201a41016a2202200341b0036a104702402002201a490d00201a41057441206a211a2015210203402002200341b0036a104a200241206a2102201a41606a221a0d000b0b20032802b403210220034188076a412020032802b003221a20032802b803100402402002450d00201a102e0b02402008450d002014102e0b02402007a7450d002015102e0b200341b0036a41086a410a3a0000200341b9036a20032903c006370000200341d9036a20032903f805370000200341c1036a200341c0066a41086a290300370000200341c9036a200341c0066a41106a290300370000200341d1036a200341c0066a41186a290300370000200341e1036a200341f8056a41086a290300370000200341e9036a200341f8056a41106a290300370000200341f1036a200341f8056a41186a290300370000200341053a00b003200341fc036a20063602004100211a41c8ecc5004100200341b0036a107220034188056a41086a2202420037030020034200370388054198cbc400411620034188056a1003200341a8076a41086a200229030037030020032003290388053703a807200341a8076a41101006410121060c150b41c0c6c5001058000b20064101102c000b41134101102c000b41044101102c000b419794c500211a412621142007a7450d0f2015102e410121060c100b200341003602b803200342013703b00320034180016a200341b0036a10bc0120032802b403211420032802b803211520032802b003211a200341a8076a41186a22094200370300200341a8076a41106a220a4200370300200341a8076a41086a220b4200370300200342003703a807201a2015200341a8076a1000200341b0036a41186a2009290300370300200341b0036a41106a200a290300370300200341b0036a41086a200b290300370300200320032903a8073703b00302402014450d00201a102e0b0240200341c0066a200341b0036a412010f804450d00419a93c500211a410c21140c010b20034188056a41086a221a420037030020034200370388054198cbc400411620034188056a1003200341a8076a41086a201a29030037030020032003290388053703a807200341a8076a41101006200341286a41b0f3c200410d107d200328022c211420032802282115200341b0036a20034180016a41880110f6041a4100211a20034198026a2014410020151b201641c0d102201641c0d1024b1b6a200341b0036a2002200810f00302402003280298024101470d00200328029c022202450d0020034198026a41086a28020021142002211a0c100b0c0f0b20034180016a102f0c0e0b200341003602b803200342013703b0032006200341b0036a10bc0120032802b403211420032802b803211520032802b0032102200341a8076a41186a22164200370300200341a8076a41106a22084200370300201a4200370300200342003703a80720022015200341a8076a100020034180016a41186a2215201629030037030020034180016a41106a200829030037030020034180016a41086a201a290300370300200320032903a8073703800102402014450d002002102e0b200341b0036a41186a2015290300370300200341b0036a41106a20034180016a41106a290300370300200341b0036a41086a20034180016a41086a29030037030020032003290380013703b00320034198026a200341b0036a1081040240200328029c022202450d00200328029802211a200341206a41b0f3c200410d107d2003280224410020032802201b2114024020032802a002450d002002102e0b2014201a4f0d0041eb92c500211a411a21140c050b200341b0036a200641880110f7041a200341003a00b80420034188056a41086a2202420037030020034200370388054198cbc400411620034188056a1003200341a8076a41086a200229030037030020032003290388053703a807200341003602a0022003420137039802200341b0036a20034198026a10bc01024020032d00b804220241024b0d00024002400240024020020e03000102000b4100211a0c020b4101211a0c010b4102211a0b2003201a3a00cf0702400240200328029c0220032802a0022202460d0020032802980221140c010b200241016a221a2002490d0520024101742214201a201a2014491b221a4100480d050240024020020d00201a102921140c010b2003280298022002201a102a21140b2014450d042003201a36029c02200320143602980220032d00cf07211a20032802a00221020b2003200241016a3602a002201420026a201a3a00000b200328029c022102200341a8076a4110200328029802221a20032802a002100402402002450d00201a102e0b200341b0036a102f2006102e41002106410121160b410121080b410121154100211a0c0e0b201a4101102c000b102d000b2006102f2006102e4101211641002106410121080c090b200341b0036a41186a20034198026a41186a290300370300200341b0036a41106a20034198026a41106a290300370300200341b0036a41086a20034198026a41086a29030037030020032003290398023703b003200341013a00f8050240411710292202450d004100211a2002410f6a41002900e39245370000200241086a41002900dc9245370000200241002900d4924537000020034297808080f0023702c406200320023602c006200341b0036a200341c0066a104620032802c406211420032802c806210620032802c0062102200341a8076a41186a22154200370300200341a8076a41106a22164200370300200341a8076a41086a22084200370300200342003703a80720022006200341a8076a100020034188076a41186a201529030037030020034188076a41106a201629030037030020034188076a41086a2008290300370300200320032903a8073703880720034188076a4120200341f8056a4101100402402014450d002002102e0b200a10850320034180016a102f410121060c050b41174101102c000b41c992c500211a410b2114410121060c060b41b5f0c200211a412a2114410121060c050b2002201a4105746a22142003290360370000201441186a200341e0006a41186a290300370000201441106a2008290300370000201441086a200929030037000041012106200341b0036a41186a201a41016a360200200341c4036a2016360200200320073703b803200320043703b003200320153602cc03200320023602c003200a200341b0036a10fe030b4100211a0b4101211641012108410121150c050b41af92c500211a411a21142006450d002002102e410121060c010b410121060b41012116410121080b410121150c010b2006102f2006102e410021154101210641012116410121080b0240024020012d0000417f6a2202410f4b0d00024002400240024020020e1000040404040102030404040405040505000b2015450d04200141046a2202280200102f2002280200102e0c040b2006450d03200141046a2202280200102f2002280200102e0c030b2016450d02200141046a2202280200102f2002280200102e0c020b2008450d01200141046a2202280200102f2002280200102e0c010b200241074b0d00024002400240024020020e080004040404010203000b200141046a2202280200102f2002280200102e0c030b200141046a2202280200102f2002280200102e0c020b200141046a2202280200102f2002280200102e0c010b200141046a2202280200102f2002280200102e0b200020143602042000201a360200200341d0076a24000bdda90106017f037e107f017e117f057e230041b0056b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0f000102030405060708090a0b0c0d0e000b20034184036a4101360200200342013702f402200341cc91c5003602f0022003411c3602cc01200341c491c5003602c8012003200341c8016a36028003200341f0026a4194c0c400106a000b200141306a2903002104200141286a29030021052001411d6a29000021062001411c6a2d000021072001411b6a2d00002108200141196a2f00002109200141186a2d0000210a200141176a2d0000210b200141156a2f0000210c200141146a2d0000210d200141136a2d0000210e200141116a2f0000210f200141106a2d000021102001410c6a2802002111200141086a2802002112200141076a2d00002113200141056a2f00002114200141046a2d0000211520012d000121162002411a6a2901002117200241196a2d00002118200241186a2d00002119200241166a2f0100211a200241156a2d0000211b200241146a2d0000211c200241126a2f0100211d200241116a2d0000211e200241106a2d0000211f2002410e6a2f010021202002410d6a2d00002121200241046a2d00002122200241026a2f01002123412a212441b5f0c20021250240024020022d0000450d004101212641002127410021280c010b41012126410021274100212820022d00014101470d002002410c6a2d000021272002410a6a2f01002128200241096a2d00002124200241066a2f0100410874200241056a2d000072200241086a2d0000411874722125410021260b202841ffff0371410874202741187472202441ff017172212420260d3b200320173703e803200320183a00e703200320193a00e6032003201a3b01e4032003201b3a00e3032003201c3a00e2032003201d3b01e0032003201e3a00df032003201f3a00de03200320203b01dc03200320213a00db03200320243600d703200320253600d303200320223a00d203200320233b01d003410e10292202450d0d200241002900d9e743370000200241066a41002900dfe7433700002003428e808080e0013702f402200320023602f002200341d0036a200341f0026a104a20032802f402212520032802f802212420032802f0022102200341a8026a41186a22264200370300200341a8026a41106a22274200370300200341a8026a41086a22284200370300200342003703a80220022024200341a8026a100020034188056a41186a202629030037030020034188056a41106a202729030037030020034188056a41086a2028290300370300200320032903a8023703880520034188056a412041c8ecc500410041001005212402402025450d002002102e0b02402024417f460d0041eec0c4002125411421240c3c0b0240201541ff01714101470d00200341f0026a201241067610bb0120032802f00221250240024020032802f8022012413f7122024b0d00410021020c010b202520024105746a2202290018210620022d0017210720022d0016210820022f0014210920022d0013210a20022d0012210b20022f0010210c20022d000f210d20022d000e210e20022f000c210f20022d000b2110200228000721112002280003211220022d0002211320022f00002114410121020b024020032802f402450d002025102e0b2002450d3b0b200320063703e001200320073a00df01200320083a00de01200320093b01dc012003200a3a00db012003200b3a00da012003200c3b01d8012003200d3a00d7012003200e3a00d6012003200f3b01d401200320103a00d301200320113600cf01200320123600cb01200320133a00ca01200320143b01c801410e10292202450d0e200241002900b1e843370000200241066a41002900b7e8433700002003428e808080e0013702f402200320023602f002200341c8016a200341f0026a104a20032802f402212520032802f802212420032802f0022102200341a8026a41186a22264200370300200341a8026a41106a22274200370300200341a8026a41086a22284200370300200342003703a80220022024200341a8026a100020034188056a41186a202629030037030020034188056a41106a202729030037030020034188056a41086a2028290300370300200320032903a8023703880520034188056a412041c8ecc500410041001005212402402025450d002002102e0b2024417f470d3902402005428080e983b1de165441002004501b450d0041bdc0c4002125413121240c3c0b200341f0026a41186a200341c8016a41186a290300370300200341f0026a41106a200341c8016a41106a290300370300200341f0026a41086a200341c8016a41086a290300370300200320032903c8013703f002410e10292202450d0f200241002900d9e743370000200241066a41002900dfe7433700002003428e808080e0013702ac02200320023602a802200341d0036a200341a8026a104a20032802ac02212520032802b002212420032802a8022102200341a8026a41186a22264200370300200341a8026a41106a22274200370300200341a8026a41086a22284200370300200342003703a80220022024200341a8026a100020034188056a41186a202629030037030020034188056a41106a202729030037030020034188056a41086a2028290300370300200320032903a80237038805200341203602ac02200320034188056a3602a802200341f0026a200341a8026a109a0202402025450d002002102e0b410d10292202450d10200241002900bfe843370000200241056a41002900c4e8433700002003428d808080d0013702f402200320023602f002200341d0036a200341f0026a104a20032802f402212420032802f802210220032802f0022125200341a8026a41186a22264200370300200341a8026a41106a22274200370300200341a8026a41086a22284200370300200342003703a80220252002200341a8026a100020034188056a41186a202629030037030020034188056a41106a202729030037030020034188056a41086a2028290300370300200320032903a80237038805024002400240024002400240201641037122024103460d0020020e03010203010b20034188056a41204101410010040c040b200341003a00ac050c020b200341013a00ac050c010b200341023a00ac050b410110292202450d12200220032d00ac053a000020034188056a41202002410110042002102e0b02402024450d002025102e0b411410292202450d12200241002900d88c40370000200241106a41002800e88c40360000200241086a41002900e08c4037000020034294808080c0023702f402200320023602f002200341d0036a200341f0026a104a20032802f4022102200341086a20032802f002222420032802f802106e200341086a41106a2903004200200328020822251b21172003290310420020251b210602402002450d002024102e0b20034198036a4100360200200341a4036a200341d0036a41086a290300370200200341ac036a200341d0036a41106a290300370200200341b4036a200341d0036a41186a290300370200200341f0026a41186a201720042006200554201720045420172004511b22021b2217370300200320032903d00337029c03200342083703900320032006200520021b220637038003200320173703f802200320063703f002200341c8016a200341f0026a10ec0320034194036a280200450d38200328029003102e0c380b20022d00000d3620022d00014101470d36200141106a2903002117200141086a2903002106200241196a2d00002125200241186a2d00002124200241166a2f01002126200241156a2d00002127200241146a2d00002128200241126a2f01002118200241116a2d00002119200241106a2d0000211a2002410e6a2f0100211b2002410d6a2d0000211c2002410c6a2d0000211d2002410a6a2f0100211e200241096a2d0000211f200241086a2d00002120200241066a2f01002121200241056a2d00002122200241046a2d00002123200241026a2f0100211220032002411a6a2901003703b804200320253a00b704200320243a00b604200320263b01b404200320273a00b304200320283a00b204200320183b01b004200320193a00af042003201a3a00ae042003201b3b01ac042003201c3a00ab04200320233a00a204200320123b01a0042003201f201e410874201d41187472723600a704200320222021410874722020411874723600a304200341f0026a200341a0046a108202024020032d00f0024101460d004192c1c4002125410b21240c3b0b200320032902f4023700ab02200320032d00f3023a00aa02200320032f00f1023b01a802200320034189036a2900003703c002200320034185036a2800003602bc022003200341fd026a2900003702b4022003200341f0026a410c6a22022d00003a00b302200341f0026a200341a8026a1083022003280290032224450d3520034188056a41086a200341f0026a41346a2902002204370300200341d0036a41086a22262004370300200341d0036a41106a2227200341f0026a413c6a290200370300200341d0036a41186a2228200341f0026a41c4006a29020037030020032003419c036a290200220437038805200320043703d003200341bc036a2802002118200341f0026a41286a28020021192002350200210420032802f002210220032902f402210520032903800321292003280294032125200341c8016a41186a200341f0026a41186a290300222a370300200341c8016a410c6a20043e0200200341c8016a41286a2019360200200341ec016a2025360200200320293703d801200320053702cc01200320243602e801200320023602c801200341c8016a41c4006a2028290300370200200341c8016a413c6a2027290300370200200341c8016a41346a2026290300370200200320032903d0033702f4012003201836029402411410292202450d12200241002900d88c40370000200241106a41002800e88c40360000200241086a41002900e08c4037000020034294808080c0023702f402200320023602f002200341a0046a200341f0026a104a20032802f4022102200341206a20032802f002222620032802f802106e200341206a41106a2903004200200328022022241b21042003290328420020241b210502402002450d002026102e0b200520032903c801222b7d222c2005562004200341d0016a290300222d7d2005202b54ad7d220520045620052004511b450d330c340b200141106a2903002106200141086a29030021042002411a6a2901002117200241196a2d00002118200241186a2d00002119200241166a2f0100211a200241156a2d0000211b200241146a2d0000211c200241126a2f0100211d200241116a2d0000211e200241106a2d0000211f2002410e6a2f010021202002410d6a2d00002121200241046a2d00002122200241026a2f01002123412a212441b5f0c20021250240024020022d0000450d004101212641002127410021280c010b41012126410021274100212820022d00014101470d002002410c6a2d000021272002410a6a2f01002128200241096a2d00002124200241066a2f0100410874200241056a2d000072200241086a2d0000411874722125410021260b202841ffff0371410874202741187472202441ff017172212420260d39200320173703c002200320183a00bf02200320193a00be022003201a3b01bc022003201b3a00bb022003201c3a00ba022003201d3b01b8022003201e3a00b7022003201f3a00b602200320203b01b402200320213a00b302200320243600af02200320253600ab02200320223a00aa02200320233b01a802200341f0026a200341a8026a1083022003280290032226450d3420034188056a41086a200341f0026a41346a2902002217370300200341d0036a41086a22242017370300200341e0036a2227200341f0026a413c6a290200370300200341d0036a41186a2228200341f0026a41c4006a29020037030020032003419c036a290200221737038805200320173703d003200341bc036a2802002118200341f0026a41286a2802002125200341f0026a410c6a350200212920032802f002211920032902f402212b20032903800321172003280294032102200341c8016a41186a200341f0026a41186a2903002205370300200341c8016a410c6a20293e0200200341c8016a41286a2025360200200341ec016a2002360200200320173703d8012003202b3702cc01200320263602e801200320193602c801200341c8016a41c4006a2028290300370200200341c8016a413c6a2027290300370200200341c8016a41346a2024290300370200200320032903d0033702f401200320183602940202400240024002402025411f4b0d00201720042017200454200520065420052006511b22241b22042005200620241b220684500d03200341c8016a41186a4200200520067d2017200454ad7d2229201720047d222b428080e983b1de165441002029501b22241b37030020034200202b20241b3703d801200341386a41e49ac5004112107d200328023c21272003280238212820252002470d02200241016a22252002490d3520024101742218202520252018491b2218ad42187e2229422088a70d352029a7222541004e0d010c350b419dc1c4002125412321242002450d3c2026102e0c3c0b0240024020020d002025102921260c010b2026200241186c2025102a21260b2026450d14200320183602ec01200320263602e80120032802f00121250b2026202541186c6a22022005200620241b37030820022017200420241b3703002002202741a0056a41a00520281b360210200320032802f00141016a3602f001200341a8026a200341c8016a10ec0320032802ec0121020b2002450d3620032802e801102e0c360b41b5f0c2002125412a212420022d00000d3820022d00014101470d38200241196a2d00002125200241186a2d00002124200241166a2f01002126200241156a2d00002127200241146a2d00002128200241126a2f01002118200241116a2d00002119200241106a2d0000211a2002410e6a2f0100211b2002410d6a2d0000211c2002410c6a2d0000211d2002410a6a2f0100211e200241096a2d0000211f200241086a2d00002120200241066a2f01002121200241056a2d00002122200241046a2d00002123200241026a2f0100211220032002411a6a2901003703e803200320253a00e703200320243a00e603200320263b01e403200320273a00e303200320283a00e203200320183b01e003200320193a00df032003201a3a00de032003201b3b01dc032003201c3a00db03200320233a00d203200320123b01d0032003201f201e410874201d41187472723600d703200320222021410874722020411874723600d303200341f0026a200341d0036a1083022003280290032218450d33200341d0006a41086a200341a4036a290200370300200341d0006a41106a200341ac036a290200370300200341d0006a41186a200341b4036a29020037030020032003419c036a290200370350200341f0026a41186a290300212920034198036a280200211a200341fc026a3502002117200329038003212b200328029403211b20033502f002210420032902f4022106200341c8006a41e49ac5004112107d410021282017422086200642208884211720042006422086842106024002400240201a41186c2202450d00200328024c410020032802481b2126201820026a2127201a41186c41686a2125201821020340200241086a2903002105200229030021042026200241106a2802002224490d024200201720057d2006200454ad7d2205200620047d2204200656200520175620052017511b22241b21174200200420241b2106202541686a2125200241186a22022027470d000b0b410821190240201b0d00410021240c020b2018102e410021240c010b411810292219450d132019200437030020192024360210201920053703080240024020250d0041012128410121240c010b200241186a211c201a41186c20186a41686a211d41012128410121240340201c210202400340200241086a2903002105200229030021042026200241106a2802002225490d014200201720057d2006200454ad7d2205200620047d2204200656200520175620052017511b22251b21174200200420251b2106200241186a22022027470d000c030b0b024020242028470d00202841016a22242028490d342028410174221a20242024201a491b2224ad42187e222c422088a70d34202ca7221a4100480d340240024020280d00201a102921190c010b2019202841186c201a102a21190b2019450d170b200241186a211c2019202841186c6a221a2005370308201a2004370300201a2025360210202841016a2128201d2002470d000b0b201b450d002018102e0b20034198036a202836020020034194036a20243602002003202b37038003200341f0026a41186a2029370300200341b4036a200341d0006a41186a290300370200200341ac036a200341e0006a290300370200200341a4036a200341d8006a290300370200200320063703f0022003200329035037029c032003201936029003200320173703f8020240202b2029844200520d002028450d280b200341d0036a200341f0026a10ec030c2f0b200141106a2903002106200141086a2903002104200141186a28020021122002411a6a2901002117200241196a2d00002118200241186a2d00002119200241166a2f0100211a200241156a2d0000211b200241146a2d0000211c200241126a2f0100211d200241116a2d0000211e200241106a2d0000211f2002410e6a2f010021202002410d6a2d00002121200241046a2d00002122200241026a2f0100212341b5f0c2002125412a21240240024020022d0000450d004101212641002127410021280c010b41012126410021274100212820022d00014101470d002002410c6a2d000021282002410a6a2f01002127200241096a2d00002124200241066a2f0100410874200241056a2d000072200241086a2d0000411874722125410021260b202741ffff0371410874202441ff017172202841187472212420260d372003201737038801200320183a008701200320193a0086012003201a3b0184012003201b3a0083012003201c3a0082012003201d3b0180012003201e3a007f2003201f3a007e200320203b017c200320213a007b2003202436007720032025360073200320223a0072200320233b0170200341f0026a200341f0006a1083022003280290032202450d3220034188056a41086a200341f0026a41346a2902002217370300200341c8016a41086a22252017370300200341d8016a2224200341f0026a413c6a290200370300200341c8016a41186a2227200341f0026a41c4006a2902003703002003200341f0026a412c6a290200221737038805200320173703c801200341bc036a2802002128200341f0026a41286a2802002118200341f0026a410c6a350200211720032802f002211920032902f402210520032903800321292003280294032126200341d0036a41186a200341f0026a41186a290300370300200341d0036a410c6a20173e0200200341d0036a41286a2018360200200341f4036a2026360200200320293703e003200320053702d403200320023602f003200320193602d003200341d0036a41c4006a2027290300370200200341d0036a413c6a2024290300370200200341d0036a41346a2025290300370200200320032903c8013702fc032003202836029c0402402012410a4b0d00200341d0036a412c6a222810dc0320032006370398012003200437039001200320123602a001411210292202450d1420024100290090e843370000200241106a41002f00a0e8433b0000200241086a4100290098e84337000020034292808080a0023702f402200320023602f0022028200341f0026a104a20032802f402211920032802f802212720032802f0022102200341a8026a41186a22254200370300200341a8026a41106a22244200370300200341a8026a41086a22264200370300200342003703a80220022027200341a8026a100020034188056a41186a221a202529030037030020034188056a41106a221b202429030037030020034188056a41086a221c2026290300370300200320032903a80237038805200341c8016a20034188056a10ad030240024020032d00e00122184102470d00202542003703002024420037030020264200370300200342003703a80241f8e8c300411a200341a8026a1000201a2025290300370300201b2024290300370300201c2026290300370300200320032903a80237038805200341a0046a20034188056a412010dc01024020032d00a0040d00200341a8026a41186a22254200370300200341a8026a41106a22244200370300200341a8026a41086a22264200370300200342003703a80241f8e8c300411a200341a8026a100020034188056a41186a202529030037030020034188056a41106a202429030037030020034188056a41086a2026290300370300200320032903a80237038805200341203602f402200320034188056a3602f0022028200341f0026a109a0241002125410021180c020b200341c8046a41186a200341b9046a290000370300200341c8046a41106a200341b1046a290000370300200341c8046a41086a200341a9046a290000370300200320032900a1043703c804411210292225450d1720254100290090e843370000202541106a41002f00a0e8433b0000202541086a4100290098e84337000020034292808080a0023702f402200320253602f002200341c8046a200341f0026a104a20032802f402212620032802f802212520032802f0022124200341a8026a41186a22184200370300200341a8026a41106a221a4200370300200341a8026a41086a221b4200370300200342003703a80220242025200341a8026a100020034188056a41186a201829030037030020034188056a41106a201a29030037030020034188056a41086a201b290300370300200320032903a80237038805200341f0026a20034188056a10ad0320032d0088034102460d18200341f0026a41086a2903002117200328028003211820032903f0022106200341a8026a20034184036a41c60010f6041a200341f0026a200341ac026a41c20010f6041a20034184056a20034192036a410020032d0091034101461b360200200320173703f004200320063703e8042003202836028005200320183602f804200341a8026a41186a22184200370300200341a8026a41106a221a4200370300200341a8026a41086a221b4200370300200342003703a80220242025200341a8026a100020034188056a41186a201829030037030020034188056a41106a201a29030037030020034188056a41086a201b290300370300200320032903a80237038805200341003602b002200342013703a802200341e8046a41106a200341a8026a10662003200341e8046a3602ac05200341ac056a200341a8026a106b02400240200328028005221a0d004100211a200341003a00ac050240024020032802ac0220032802b0022225460d0020032802a80221180c010b202541016a22182025490d352025410174221a20182018201a491b221a4100480d350240024020250d00201a102921180c010b20032802a8022025201a102a21180b2018450d1c2003201a3602ac02200320183602a80220032d00ac05211a20032802b00221250b2003202541016a3602b002201820256a201a3a00000c010b200341013a00ac050240024020032802ac0220032802b0022225460d004101211b20032802a80221180c010b202541016a22182025490d342025410174221b20182018201b491b221b4100480d340240024020250d00201b102921180c010b20032802a8022025201b102a21180b2018450d1c2003201b3602ac02200320183602a80220032d00ac05211b20032802b00221250b2003202541016a3602b002201820256a201b3a0000201a200341a8026a104a0b02400240200328028405221a0d004100211a200341003a00ac050240024020032802ac0220032802b0022225460d0020032802a80221180c010b202541016a22182025490d352025410174221a20182018201a491b221a4100480d350240024020250d00201a102921180c010b20032802a8022025201a102a21180b2018450d1e2003201a3602ac02200320183602a80220032d00ac05211a20032802b00221250b2003202541016a3602b002201820256a201a3a00000c010b4101211b200341013a00ac050240024020032802ac0220032802b0022225460d0020032802a80221180c010b202541016a22182025490d342025410174221b20182018201b491b221b4100480d340240024020250d00201b102921180c010b20032802a8022025201b102a21180b2018450d1e2003201b3602ac02200320183602a80220032d00ac05211b20032802b00221250b2003202541016a3602b002201820256a201b3a0000201a200341a8026a104a0b20032802ac02212520034188056a412020032802a802221820032802b002100402402025450d002018102e0b02402026450d002024102e0b200341a8026a41186a22254200370300200341a8026a41106a22244200370300200341a8026a41086a22264200370300200342003703a80241f8e8c300411a200341a8026a100020034188056a41186a202529030037030020034188056a41106a202429030037030020034188056a41086a2026290300370300200320032903a80237038805200341203602f402200320034188056a3602f0022028200341f0026a109a02200341a8016a41086a200341c8046a41086a290300370300200341a8016a41106a200341c8046a41106a290300370300200341a8016a41186a200341c8046a41186a290300370300200320032903c8043703a80141012125410021180c010b200341d0006a41186a200341f9016a290000370300200341d0006a41106a200341f1016a290000370300200341d0006a41086a200341e9016a290000370300200341a8016a41086a2003418a026a290100370300200341a8016a41106a20034192026a290100370300200341a8016a41186a2003419a026a2901003703002003200341e1016a290000370350200320034182026a2901003703a80120034181026a2d000021250b20034195036a20253a000020034196036a20032903a801370100200341fd026a200341d0006a41086a29030037000020034185036a200341d0006a41106a2903003700002003418d036a200341d0006a41186a2903003700002003419e036a200341a8016a41086a290300370100200341a6036a200341a8016a41106a290300370100200341ae036a200341a8016a41186a290300370100200320183a00f402200320032903503700f502200320034190016a3602f002200341a8026a41186a22254200370300200341a8026a41106a22244200370300200341a8026a41086a22264200370300200342003703a80220022027200341a8026a100020034188056a41186a202529030037030020034188056a41106a202429030037030020034188056a41086a2026290300370300200320032903a80237038805200341003602d001200342013703c80120032802f002222541106a200341c8016a1066200320253602a802200341a8026a200341c8016a106b0240024020032d00f4024101460d00200341003a00ac050240024020032802cc0120032802d0012225460d004100212620032802c80121240c010b202541016a22242025490d3320254101742226202420242026491b22264100480d330240024020250d002026102921240c010b20032802c80120252026102a21240b2024450d1e200320263602cc01200320243602c80120032d00ac05212620032802d00121250b2003202541016a3602d001202420256a20263a00000c010b200341013a00ac050240024020032802cc0120032802d0012225460d004101212620032802c80121240c010b202541016a22242025490d3220254101742226202420242026491b22264100480d320240024020250d002026102921240c010b20032802c80120252026102a21240b2024450d1e200320263602cc01200320243602c80120032d00ac05212620032802d00121250b2003202541016a3602d001202420256a20263a0000200341f0026a410572200341c8016a104a0b0240024020032d0095034101460d0041002126200341003a00ac050240024020032802cc0120032802d0012225460d0020032802c80121240c010b202541016a22242025490d3320254101742226202420242026491b22264100480d330240024020250d002026102921240c010b20032802c80120252026102a21240b2024450d20200320263602cc01200320243602c80120032d00ac05212620032802d00121250b2003202541016a3602d001202420256a20263a00000c010b200341013a00ac050240024020032802cc0120032802d0012225460d004101212620032802c80121240c010b202541016a22242025490d3220254101742226202420242026491b22264100480d320240024020250d002026102921240c010b20032802c80120252026102a21240b2024450d20200320263602cc01200320243602c80120032d00ac05212620032802d00121250b2003202541016a3602d001202420256a20263a000020034196036a200341c8016a104a0b20032802cc01212520034188056a412020032802c801222420032802d001100402402025450d002024102e0b02402019450d002002102e0b20032802f403450d3520032802f003102e0c350b41c0c1c4002125411b21242026450d372002102e0c370b2001410c6a2802002118200141086a280200211d200141046a280200211c2002411a6a2901002117200241196a2d00002119200241186a2d0000211a200241166a2f0100211b200241156a2d0000211e200241146a2d0000211f200241126a2f01002120200241116a2d00002121200241106a2d000021222002410e6a2f010021232002410d6a2d00002112200241046a2d00002107200241026a2f0100210841b5f0c2002125412a21240240024020022d0000450d004101212641002127410021280c010b41012126410021274100212820022d00014101470d002002410c6a2d000021282002410a6a2f01002127200241096a2d00002124200241066a2f0100410874200241056a2d000072200241086a2d0000411874722125410021260b202741ffff0371410874202441ff017172202841187472212420260d2c200320173703e004200320193a00df042003201a3a00de042003201b3b01dc042003201e3a00db042003201f3a00da04200320203b01d804200320213a00d704200320223a00d604200320233b01d404200320123a00d304200320243600cf04200320253600cb04200320073a00ca04200320083b01c804200341f0026a200341c8046a108302024020032802900322250d00411021244182c1c40021250c2d0b20034188056a41086a200341f0026a41346a2902002217370300200341c8016a41086a22242017370300200341c8016a41106a2226200341f0026a413c6a290200370300200341c8016a41186a2227200341f0026a41c4006a2902003703002003200341f0026a412c6a290200221737038805200320173703c801200341bc036a2802002128200341f0026a41286a2802002119200341f0026a410c6a350200211720032802f002211a20032902f402210620032903800321042003280294032102200341d0036a41186a200341f0026a41186a290300370300200341d0036a410c6a20173e0200200341d0036a41286a2019360200200341d0036a41246a2002360200200320043703e003200320063702d403200320253602f0032003201a3602d003200341d0036a41c4006a2027290300370200200341d0036a413c6a2026290300370200200341d0036a41346a2024290300370200200320032903c8013702fc032003202836029c0420180d2a41dbc1c400212541172124410121260c2b0b20022d00000d3120022d00014101470d31200241196a2d00002125200241186a2d00002124200241166a2f01002126200241156a2d00002127200241146a2d00002128200241126a2f01002118200241116a2d00002119200241106a2d0000211a2002410e6a2f0100211b2002410d6a2d0000211c2002410c6a2d0000211d2002410a6a2f0100211e200241096a2d0000211f200241086a2d00002120200241066a2f01002121200241056a2d00002122200241046a2d00002123200241026a2f0100211220032002411a6a2901003703c002200320253a00bf02200320243a00be02200320263b01bc02200320273a00bb02200320283a00ba02200320183b01b802200320193a00b7022003201a3a00b6022003201b3b01b4022003201c3a00b302200320233a00aa02200320123b01a8022003201f201e41087472201d411874723600af02200320222021410874722020411874723600ab02200341f0026a200341a8026a1083022003280290032202450d3020034188056a41086a200341f0026a41346a2902002217370300200341d0036a41086a22252017370300200341e0036a2224200341f0026a413c6a290200370300200341d0036a41186a2226200341f0026a41c4006a2902003703002003200341f0026a412c6a290200221737038805200320173703d003200341bc036a2802002127200341f0026a410c6a350200211720032802f002212820032902f402210620032903800321042003290294032105200341c8016a41186a200341f0026a41186a290300370300200341c8016a410c6a20173e0200200341ec016a22182005370200200320043703d801200320063702cc01200320023602e801200320283602c801200341c8016a41c4006a2026290300370200200341c8016a413c6a2024290300370200200341c8016a41346a2025290300370200200320032903d0033702f4012003202736029402200341c8016a412c6a220210db03200210dc032018280200450d3220032802e801102e0c320b20022d00000d3020022d00014101470d3020012d00012107200241196a2d00002125200241186a2d00002124200241166a2f01002126200241156a2d00002127200241146a2d00002128200241126a2f01002118200241116a2d00002119200241106a2d0000211a2002410e6a2f0100211b2002410d6a2d0000211c2002410c6a2d0000211d2002410a6a2f0100211e200241096a2d0000211f200241086a2d00002120200241066a2f01002121200241056a2d00002122200241046a2d00002123200241026a2f0100211220032002411a6a2901003703b804200320253a00b704200320243a00b604200320263b01b404200320273a00b304200320283a00b204200320183b01b004200320193a00af042003201a3a00ae042003201b3b01ac042003201c3a00ab04200320233a00a204200320123b01a0042003201f201e41087472201d411874723600a704200320222021410874722020411874723600a304200341f0026a200341a0046a1083022003280290032202450d2f20034188056a41086a200341f0026a41346a2902002217370300200341d0036a41086a22252017370300200341d0036a41106a2224200341f0026a413c6a290200370300200341d0036a41186a2226200341f0026a41c4006a2902003703002003200341f0026a412c6a290200221737038805200320173703d003200341bc036a2802002127200341f0026a410c6a350200211720032802f002212820032902f402210620032903800321042003290294032105200341c8016a41186a200341f0026a41186a290300370300200341c8016a410c6a20173e0200200341ec016a2005370200200320043703d801200320063702cc01200320023602e801200320283602c801200341c8016a41c4006a2026290300370200200341c8016a413c6a2024290300370200200341c8016a41346a2025290300370200200320032903d0033702f4012003202736029402410d10292202450d1b200241002900bfe843370000200241056a41002900c4e8433700002003428d808080d0013702f402200320023602f002200341c8016a412c6a200341f0026a104a20032802f402212420032802f802210220032802f0022125200341a8026a41186a22264200370300200341a8026a41106a22274200370300200341a8026a41086a22284200370300200342003703a80220252002200341a8026a100020034188056a41186a202629030037030020034188056a41106a202729030037030020034188056a41086a2028290300370300200320032903a80237038805024002400240024002400240200741037122024103460d0020020e03010203010b20034188056a41204101410010040c040b200341003a00ac050c020b200341013a00ac050c010b200341023a00ac050b410110292202450d1d200220032d00ac053a000020034188056a41202002410110042002102e0b02402024450d002025102e0b20032802ec01450d3120032802e801102e0c310b2001411d6a29000021062001411c6a2d000021072001411b6a2d00002108200141196a2f00002109200141186a2d0000210a200141176a2d0000210b200141156a2f0000210c200141146a2d0000210d200141136a2d0000210e200141116a2f0000210f200141106a2d000021102001410c6a2802002111200141086a2802002118200141076a2d00002113200141056a2f00002114200141046a2d000021152002411a6a2901002117200241196a2d00002119200241186a2d0000211a200241166a2f0100211b200241156a2d0000211c200241146a2d0000211d200241126a2f0100211e200241116a2d0000211f200241106a2d000021202002410e6a2f010021212002410d6a2d00002122200241046a2d00002123200241026a2f0100211241b5f0c2002125412a21240240024020022d0000450d004101212641002127410021280c010b41012126410021274100212820022d00014101470d002002410c6a2d000021282002410a6a2f01002127200241096a2d00002124200241066a2f0100410874200241056a2d000072200241086a2d0000411874722125410021260b202741ffff0371410874202441ff017172202841187472212420260d33200320173703e004200320193a00df042003201a3a00de042003201b3b01dc042003201c3a00db042003201d3a00da042003201e3b01d8042003201f3a00d704200320203a00d604200320213b01d404200320223a00d304200320243600cf04200320253600cb04200320233a00ca04200320123b01c804200341f0026a200341c8046a10820241012126024020032d00f0024101460d004192c1c4002125410b2124410121270c350b200320032902f4023700eb04200320032d00f3023a00ea04200320032f00f1023b01e804200320034189036a29000037038005200320034185036a2800003602fc042003200341fd026a2900003702f4042003200341fc026a2d00003a00f3040240201541ff01714101470d00200341f0026a201841067610bb0120032802f00221250240024020032802f8022018413f7122024b0d00410021020c010b202520024105746a2202290018210620022d0017210720022d0016210820022f0014210920022d0013210a20022d0012210b20022f0010210c20022d000f210d20022d000e210e20022f000c210f20022d000b2110200228000721112002280003211820022d0002211320022f00002114410121020b024020032802f402450d002025102e0b2002450d330b200320063703b804200320073a00b704200320083a00b604200320093b01b4042003200a3a00b3042003200b3a00b2042003200c3b01b0042003200d3a00af042003200e3a00ae042003200f3b01ac04200320103a00ab04200320113600a704200320183600a304200320133a00a204200320143b01a004410e10292202450d1c200241002900b1e843370000200241066a41002900b7e8433700002003428e808080e0013702f402200320023602f002200341a0046a200341f0026a104a20032802f402212520032802f802212420032802f0022102200341a8026a41186a22264200370300200341a8026a41106a22274200370300200341a8026a41086a22284200370300200342003703a80220022024200341a8026a100020034188056a41186a202629030037030020034188056a41106a202729030037030020034188056a41086a2028290300370300200320032903a8023703880520034188056a412041c8ecc500410041001005212402402025450d002002102e0b2024417f470d31200341a0046a200341e8046a412010f804450d30410e10292202450d1d200241002900d9e743370000200241066a41002900dfe7433700002003428e808080e0013702f402200320023602f002200341c8046a200341f0026a104a20032802f402212520032802f802212420032802f0022102200341a8026a41186a22264200370300200341a8026a41106a22274200370300200341a8026a41086a22284200370300200342003703a80220022024200341a8026a100020034188056a41186a202629030037030020034188056a41106a202729030037030020034188056a41086a2028290300370300200320032903a80237038805200341203602f402200320034188056a3602f002200341a0046a200341f0026a109a0202402025450d002002102e0b410e10292202450d1e200241002900b1e843370000200241066a41002900b7e8433700002003428e808080e0013702f402200320023602f002200341e8046a200341f0026a104a20032802f402212520032802f802212420032802f0022102200341a8026a41186a22264200370300200341a8026a41106a22274200370300200341a8026a41086a22284200370300200342003703a80220022024200341a8026a100020034188056a41186a202629030037030020034188056a41106a202729030037030020034188056a41086a2028290300370300200320032903a80237038805200341f0026a20034188056a10ae0302402003280290032224450d0020034188056a41201006200341d0036a41186a200341f0026a41186a290300370300200341d0036a41106a200341f0026a41106a290300370300200341d0036a41086a200341f0026a41086a290300370300200341c8016a41086a2003419c036a2226290200370300200341c8016a41106a200341a4036a2227290200370300200341c8016a41186a200341ac036a2228290200370300200341c8016a41206a2218200341b4036a2219290200370300200341f0016a221a200341bc036a221b280200360200200320032903f0023703d00320032003290294033703c80102402025450d002002102e0b20034194036a20032903c801370200200341f0026a41186a200341d0036a41186a290300370300200341f0026a41106a200341d0036a41106a290300370300200341f0026a41086a200341d0036a41086a2903003703002026200341c8016a41086a2903003702002027200341c8016a41106a2903003702002028200341c8016a41186a29030037020020192018290300370200201b201a280200360200200320032903d0033703f0022003202436029003410e10292202450d20200241002900b1e843370000200241066a41002900b7e8433700002003428e808080e0013702ac02200320023602a802200341a0046a200341a8026a104a20032802ac02212520032802b002212420032802a8022102200341a8026a41186a22264200370300200341a8026a41106a22274200370300200341a8026a41086a22284200370300200342003703a80220022024200341a8026a100020034188056a41186a202629030037030020034188056a41106a202729030037030020034188056a41086a2028290300370300200320032903a80237038805200341203602ac02200320034188056a3602a802200341f0026a200341a8026a10ef0302402025450d002002102e0b200328029403450d31200328029003102e0c310b2025450d302002102e0c300b4101212620022d000120022d0000720d25200141046a2802002102200341f0026a41086a22254200370300200342003703f00241989ac5004116200341f0026a1003200341c8016a41086a2025290300370300200320032903f0023703c801200320023602f002200341c8016a4110200341f0026a410410040c230b20022d000120022d0000720d23200341f0026a41086a22024200370300200342003703f00241b29bc5004110200341f0026a1003200341c8016a41086a2002290300370300200320032903f0023703c801200341023a00ac0541012126410110292202450d1e200220032d00ac053a0000200341c8016a41102002410110042002102e0c220b20022d000120022d0000720d22200341f0026a41086a22024200370300200342003703f00241b29bc5004110200341f0026a1003200341c8016a41086a2002290300370300200320032903f0023703c80141012126200341013a00ac05410110292202450d1e200220032d00ac053a0000200341c8016a41102002410110042002102e0c210b4101212620022d000120022d0000720d22200141046a2802002102200341f0026a41086a22254200370300200342003703f00241cb9ac5004119200341f0026a1003200341c8016a41086a2025290300370300200320032903f0023703c801200320023602f002200341c8016a4110200341f0026a410410040c200b200141086a2802002128200141046a2802002118024020022d000120022d000072450d00418df0c20021254128212441002127410121262028450d302018102e0c300b2001410c6a2802002102200341f0026a41086a22254200370300200342003703f00241f2c1c4004115200341f0026a1003200341c8016a41086a2025290300370300200320032903f0023703c801200341003602f802200342013703f0022002200341f0026a104702402002450d00200241057421252018210203402002200341f0026a104a200241206a2102202541606a22250d000b0b20032802f4022102200341c8016a411020032802f002222520032802f802100402402002450d002025102e0b410121262028450d1e2018102e0c1e0b410e4101102c000b410e4101102c000b410e4101102c000b410d4101102c000b41014101102c000b41144101102c000b41144101102c000b20254108102c000b41184108102c000b201a4108102c000b41124101102c000b41124101102c000b41e694c500419f01109b01000b201a4101102c000b201b4101102c000b201a4101102c000b201b4101102c000b20264101102c000b20264101102c000b20264101102c000b20264101102c000b410d4101102c000b41014101102c000b410e4101102c000b410e4101102c000b410e4101102c000b410e4101102c000b41014101102c000b41014101102c000b200341c8016a41186a2003419c036a220241186a290000370300200341c8016a41106a200241106a290000370300200341c8016a41086a200241086a290000370300200342f3e885db96cddbb32037038805200320022900003703c801200341c0006a41b0f3c200410d107d20032003280244410020032802401b3602e804200341a8026a200341c8016a107c20032802ac02212520032802a802210220032802b0022124200341bc026a20034188056a3602002003200220244105746a3602b402200320023602b002200320253602ac02200320023602a8022003200341e8046a3602b802200341a0046a200341a8026a1044200341a8026a41086a200341a0046a41086a280200360200200320032903a0043703a802200341c8016a200341a8026a109001200341c8016a10750c070b41002127410021250c100b41002125410121270c0f0b418df0c2002125412821240c0d0b418df0c200212541282124410121270c0d0b2003410036028805200341103602b0042003201c201841246c6a3602ac042003201c3602a8042003201d3602a4042003201c3602a004200320034188056a3602b404200341f0026a200341a0046a10e301024002400240024002400240024002400240024020032d00f0024101460d0020032802ac04212620032802a804210202400340024020262002470d00200221240c020b20022d00002125200241246a2224210220254102470d000b0b200320243602a8044100212841012118024020032802a4040d00410021020c020b20032802a004102e410021020c010b412010292218450d01201820032900f102370000201841186a20034189036a290000370000201841106a20034181036a290000370000201841086a200341f9026a290000370000200341c8016a41106a200341a0046a41106a290300370300200341c8016a41086a200341a0046a41086a290300370300200320032903a0043703c801200341f0026a200341c8016a10e3010240024020032d00f0020d0041012102410121280c010b200341f0026a4101722125410221274120212641012102410121280340200341a8026a41186a2219202541186a290000370300200341a8026a41106a221a202541106a290000370300200341a8026a41086a221b202541086a290000370300200320252900003703a802024020022028470d00200241016a22242002490d0f2027202420242027491b222841ffffff3f712028470d0f202841057422244100480d0f0240024020020d002024102921180c010b201820262024102a21180b2018450d0b0b201820266a222420032903a802370000202441186a2019290300370000202441106a201a290300370000202441086a201b290300370000202741026a2127202641206a2126200241016a2102200341f0026a200341c8016a10e30120032d00f0020d000b0b20032802d401212620032802d001212502400340024020262025470d00202521270c020b20252d00002124202541246a2227212520244102470d000b0b200320273602d00120032802cc01450d0020032802c801102e0b02402003280288052225450d00200328028c05212402402028450d002018102e0b4100212620032802f40321020c090b200341d0036a412c6a221910db03200320023602782003202836027420032018360270411210292202450d01200241002900fee743370000200241106a41002f008ee8433b0000200241086a4100290086e84337000020034292808080a0023702f402200320023602f0022019200341f0026a104a20032802f402211820032802f802212620032802f0022124200341a8026a41186a22024200370300200341a8026a41106a22254200370300200341a8026a41086a22274200370300200342003703a80220242026200341a8026a100020034188056a41186a221a200229030037030020034188056a41106a221b202529030037030020034188056a41086a221c2027290300370300200320032903a80237038805200341c8016a20034188056a10ab030240024020032d00d40122284102470d00200242003703002025420037030020274200370300200342003703a80241dee8c300411a200341a8026a1000201a2002290300370300201b2025290300370300201c2027290300370300200320032903a80237038805200341a0046a20034188056a412010dc01024020032d00a0040d00200341a8026a41186a22024200370300200341a8026a41106a22254200370300200341a8026a41086a22274200370300200342003703a80241dee8c300411a200341a8026a100020034188056a41186a200229030037030020034188056a41106a202529030037030020034188056a41086a2027290300370300200320032903a80237038805200341203602f402200320034188056a3602f0022019200341f0026a109a0241002102410021280c020b200341e8046a41186a200341b9046a290000370300200341e8046a41106a200341b1046a290000370300200341e8046a41086a200341a9046a290000370300200320032900a1043703e804411210292202450d04200241002900fee743370000200241106a41002f008ee8433b0000200241086a4100290086e84337000020034292808080a0023702f402200320023602f002200341e8046a200341f0026a104a20032802f402211b20032802f802212520032802f0022127200341a8026a41186a22024200370300200341a8026a41106a22284200370300200341a8026a41086a221a4200370300200342003703a80220272025200341a8026a100020034188056a41186a200229030037030020034188056a41106a202829030037030020034188056a41086a201a290300370300200320032903a80237038805200341f0026a20034188056a10ab0320032d00fc024102460d0520032802f402211c20032802f002211a20032802f8022102200341a8026a200341fc026a41c20010f6041a200341f0026a200341a8026a41c20010f6041a20032d009103211d200341a8026a41186a22284200370300200341a8026a41106a221e4200370300200341a8026a41086a221f4200370300200342003703a80220272025200341a8026a100020034188056a41186a202829030037030020034188056a41106a201e29030037030020034188056a41086a201f290300370300200320032903a80237038805200341003602b002200342013703a8022002200341a8026a104702402002450d0020024105742125201a210203402002200341a8026a104a200241206a2102202541606a22250d000b0b41012128200341013a00ac050240024020032802ac0220032802b0022202460d0020032802a80221250c010b200241016a22252002490d0e20024101742228202520252028491b22284100480d0e0240024020020d002028102921250c010b20032802a80220022028102a21250b2025450d07200320283602ac02200320253602a80220032d00ac05212820032802b00221020b2003200241016a3602b002202520026a20283a00002019200341a8026a104a02400240201d41ff01714101460d0041002128200341003a00ac050240024020032802ac0220032802b0022202460d0020032802a80221250c010b200241016a22252002490d1020024101742228202520252028491b22284100480d100240024020020d002028102921250c010b20032802a80220022028102a21250b2025450d0a200320283602ac02200320253602a80220032d00ac05212820032802b00221020b2003200241016a3602b002202520026a20283a00000c010b200341013a00ac050240024020032802ac0220032802b0022202460d004101212820032802a80221250c010b200241016a22252002490d0f20024101742228202520252028491b22284100480d0f0240024020020d002028102921250c010b20032802a80220022028102a21250b2025450d0a200320283602ac02200320253602a80220032d00ac05212820032802b00221020b2003200241016a3602b002202520026a20283a000020034192036a200341a8026a104a0b20032802ac02210220034188056a412020032802a802222520032802b002100402402002450d002025102e0b0240201c450d00201a102e0b0240201b450d002027102e0b200341a8026a41186a22024200370300200341a8026a41106a22254200370300200341a8026a41086a22274200370300200342003703a80241dee8c300411a200341a8026a100020034188056a41186a200229030037030020034188056a41106a202529030037030020034188056a41086a2027290300370300200320032903a80237038805200341203602f402200320034188056a3602f0022019200341f0026a109a02200341a8016a41086a200341e8046a41086a290300370300200341a8016a41106a200341e8046a41106a290300370300200341a8016a41186a200341e8046a41186a290300370300200320032903e8043703a80141012102410021280c010b200341d0006a41086a200341dd016a290000370300200341d0006a41106a200341e5016a290000370300200341d0006a41186a200341ed016a290000370300200341a8016a41086a200341fe016a290100370300200341a8016a41106a20034186026a290100370300200341a8016a41186a2003418e026a2901003703002003200341d5016a2900003703502003200341f6016a2901003703a801200341f5016a2d0000210220032802cc01450d0020032802c801102e0b20034195036a20023a000020034196036a20032903a801370100200341fd026a200341d0006a41086a29030037000020034185036a200341d0006a41106a2903003700002003418d036a200341d0006a41186a2903003700002003419e036a200341a8016a41086a290300370100200341a6036a200341a8016a41106a290300370100200341ae036a200341a8016a41186a290300370100200320283a00f402200320032903503700f5022003200341f0006a3602f002200341a8026a41186a22024200370300200341a8026a41106a22254200370300200341a8026a41086a22274200370300200342003703a80220242026200341a8026a100020034188056a41186a200229030037030020034188056a41106a202529030037030020034188056a41086a2027290300370300200320032903a80237038805200341003602d001200342013703c8012003280270210220032802782225200341c8016a1047200341f0026a410472212602402025450d002025410574212503402002200341c8016a104a200241206a2102202541606a22250d000b0b2026200341c8016a10de0320032802cc01210220034188056a412020032802c801222520032802d001100402402002450d002025102e0b02402018450d002024102e0b02402003280274450d002003280270102e0b024020032802f403450d0020032802f003102e0b4100212641012127410021250c140b41204101102c000b41124101102c000b41124101102c000b41e694c500419f01109b01000b20284101102c000b20284101102c000b20284101102c000b20244101102c000b02402002450d0020032802f003102e0b20260d0041012127410021260c0b0b4101212741002126201d450d0a201c102e0c0a0b0240200328029403450d00200328029003102e0b410021250c080b102d000b20032006202c202c200656200520175620052017511b22021b220620297c22043703d801200341e0016a2017200520021b2217202a7c2004200654ad7c37030020032006202b7c22043703c80120032017202d7c2004200654ad7c3703d001200341a8026a200341c8016a10ec0320032802ec0121250b2025450d0220032802e801102e0c020b4182c1c4002125411021240c040b41b5f0c2002125412a21240c030b4100212541012126410121270c030b41a4c0c4002125411921240c010b41ccc4c2002125411521240b41012126410121270b0240024020012d00002202410e4b0d00410120027441beff00710d01024020024106460d002002410e470d012027450d02200141086a280200450d02200141046a280200102e0c020b2026450d01200141086a280200450d01200141046a280200102e0c010b200141086a280200450d00200141046a280200102e0b2000202436020420002025360200200341b0056a24000b4d01017f230041206b22002400200041146a410136020020004201370204200041cc91c5003602002000411c36021c200041c491c5003602182000200041186a360210200041bcc4c200106a000ba60701057f230041106b22032400200341003602082003420137030020022003104702400240024002400240024002402002450d00200241c4006c210403400240024020012d00004101460d0002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d0a20024101742206200520052006491b22064100480d0a0240024020020d002006102921050c010b200328020020022006102a21050b2005450d052003200636020420032005360200200328020821020b2003200241016a360208200520026a41003a0000200141046a28020021060240024020032802042205200328020822026b4104490d00200328020021050c010b200241046a22072002490d0a20054101742202200720072002491b22024100480d0a0240024020050d002002102921050c010b200328020020052002102a21050b2005450d062003200236020420032005360200200328020821020b2003200241046a360208200520026a20063600000c010b02400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d0920024101742206200520052006491b22064100480d090240024020020d002006102921050c010b200328020020022006102a21050b2005450d062003200636020420032005360200200328020821020b2003200241016a360208200520026a41013a0000200141016a200310460240200141216a2d00004101460d0002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d0a20024101742206200520052006491b22064100480d0a0240024020020d002006102921050c010b200328020020022006102a21050b2005450d082003200636020420032005360200200328020821020b2003200241016a360208200520026a41003a00000c010b02400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d0920024101742206200520052006491b22064100480d090240024020020d002006102921050c010b200328020020022006102a21050b2005450d082003200636020420032005360200200328020821020b2003200241016a360208200520026a41013a0000200141226a2003104a0b200141c4006a2101200441bc7f6a22040d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b20064101102c000b20024101102c000b20064101102c000b20064101102c000b20064101102c000b102d000b3400200041bceac10036020420004100360200200041146a4103360200200041106a41e0ebc100360200200041086a42083702000b130020004101360204200041c4eac1003602000b5101027f230041106b2202240002404104102922030d0041044101102c000b2002420437020420022003360200410020021047200041086a200228020836020020002002290300370200200241106a24000bb01102077f027e230041106b2202240020024100360208200242013703004104200210470240024002400240024002400240024002400240024002400240024002400240024020022802042203200228020822046b4104490d00200441046a2105200228020021030c010b200441046a22052004490d0f20034101742206200520052006491b22064100480d0f0240024020030d002006102921030c010b200228020020032006102a21030b2003450d0120022006360204200220033602000b20022005360208200320046a41eede91ab06360000410e200210470240024020022802042203200228020822066b410e490d002006410e6a2104200228020021050c010b2006410e6a22042006490d0f20034101742205200420042005491b22074100480d0f0240024020030d002007102921050c010b200228020020032007102a21050b2005450d022002200736020420022005360200200721030b20022004360208200520066a220641002900a9f041370000200641066a41002900aff0413700000240200320046b41034b0d00200441046a22062004490d0f20034101742207200620062007491b22064100480d0f0240024020030d002006102921050c010b200520032006102a21050b2005450d0320022006360204200220053602000b2002200441046a360208200520046a410a3600000240024020022802042205200228020822046b4104490d00200228020021050c010b200441046a22032004490d0f20054101742206200320032006491b22034100480d0f0240024020050d002003102921050c010b200228020020052003102a21050b2005450d0420022003360204200220053602000b2002200441046a360208200520046a4191013600000240024020022802042205200228020822046b4104490d00200228020021050c010b200441046a22032004490d0f20054101742206200320032006491b22034100480d0f0240024020050d002003102921050c010b200228020020052003102a21050b2005450d0520022003360204200220053602000b2002200441046a360208200520046a41910136000041092002104741b8f0c1002104034002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006102921030c010b200228020020052006102a21030b2003450d0720022006360204200220033602000b2002200541016a360208200320056a20042d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006102921030c010b200228020020052006102a21030b2003450d0820022006360204200220033602000b2002200541016a360208200320056a200441016a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006102921030c010b200228020020052006102a21030b2003450d0920022006360204200220033602000b2002200541016a360208200320056a200441026a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006102921030c010b200228020020052006102a21030b2003450d0a20022006360204200220033602000b2002200541016a360208200320056a200441036a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006102921030c010b200228020020052006102a21030b2003450d0b20022006360204200220033602000b2002200541016a360208200320056a200441046a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006102921030c010b200228020020052006102a21030b2003450d0c20022006360204200220033602000b2002200541016a360208200320056a200441056a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006102921030c010b200228020020052006102a21030b2003450d0d20022006360204200220033602000b2002200541016a360208200320056a200441066a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006102921030c010b200228020020052006102a21030b2003450d0e20022006360204200220033602000b2002200541016a360208200320056a200441076a2d00003a0000200441086a28020021060240024020022802042203200228020822056b4104490d00200228020021030c010b200541046a22072005490d1020034101742208200720072008491b22074100480d100240024020030d002007102921030c010b200228020020032007102a21030b2003450d0f20022007360204200220033602000b2002200541046a360208200320056a20063600002004410c6a220441a4f1c100470d000b200235020821092002350200210a200241106a2400200a2009422086840f0b20064101102c000b20074101102c000b20064101102c000b20034101102c000b20034101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20074101102c000b102d000bc61802097f017e230041800a6b22022400024002402001450d00200220003602080c010b200241c8ecc5003602080b2002200136020c200241e0076a200241086a10aa020240024002400240024020022802e407450d00200241106a200241e0076a41fc0010f6041a20024190016a200241106a41fc0010f6041a20024190016a10ab0202400240024002402002280290012201450d00200241e0076a2001417f6a10ba01200241e0076a200241a0016a412010f8040d004100210320022802800221000240024020024188026a280200220141a0026c0d0041042104410021050c010b2001410c6c220610292204450d04200121050b02402001450d00200141a0026c2106200141057441606a2107200421010340200220003602b004200241e0076a200241b0046a10ac02200141086a200241e0076a41086a280200360200200120022903e0073702002001410c6a2101200041a0026a2100200641e07d6a22060d000b200741057641016a21030b41002106024002402003410c6c22010d0041042108410021090c010b2001410c6e220941037422004100480d02200010292208450d030b0240200420016a220a2004460d00410021062008210120042100034020002802002107200141046a200041086a28020036020020012007360200200141086a2101200641016a21062000410c6a2200200a470d000b0b200220063602b804200220093602b404200220083602b004200241e0076a200241b0046a10ad0202402009450d002008102e0b02402003450d002003410c6c21002004210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b02402005450d002004102e0b0240200241e0016a2201200241e0076a412010f804450d0041a8e5c500410e100920014120100d200241e0076a4120100d0b02402001200241e0076a412010f8040d0020024184026a2802002104200228028002210a200228028802210620024190026a20024190016a41f00010f6041a200a200641a0026c6a21002002280290022103200a210102402006450d00200241b0046a41f0006a2107200a2101024002400340200241f8066a200141e80010f6041a200141e8006a290300210b20024180036a200141f0006a41b00110f6041a200b4203510d02200241b0046a200241f8066a41e80010f6041a2002200b37039805200720024180036a41b00110f6041a2002200241b0046a3602d006200241e0076a200241d0066a10ac0220022802e8072106024020022802e407450d0020022802e007102e0b200241e0076a200241b0046a41a00210f6041a200241003602e006200241d0066a200241e0076a2006200241e0066a10ae0220022802d0064101460d01024020022802d4062206450d00200620022802d80610090b200141a0026a22012000470d000b200021010c020b024020022802d4060e050b00000c0a0b0b41e8a7c2001058000b200141a0026a21010b20012000460d06200241f8086a2106200241e0076a41f0006a2107034020024180036a200141e80010f6041a200141e8006a290300210b200241e0076a200141f0006a41b00110f6041a200b4203510d07200241f8066a20024180036a41e80010f6041a200241b0046a200241e0076a41b00110f6041a200241e0076a200241f8066a41e80010f6041a2002200b3703c8082007200241b0046a41b00110f6041a2006102f200141a0026a22012000470d000c070b0b4188a7c2001058000b41f0a6c2001058000b102d000b20004104102c000b20064104102c000b2002418c036a411c360200200241c4046a4102360200200242023702b404200241d4f1c1003602b0042002411c36028403200241ccf1c100360280032002410036029401200241c8ecc50036029001200220024180036a3602c004200220024190016a36028803200241b0046a41e4f1c100106a000b02402004450d00200a102e0b10af022003109501200241e0076a10b002200220024190026a410c6a28020022043602f00620022802940221072002200241e0076a410c6a28020022013602f406024020042001470d0002402004450d0020022802e407210a41002106034002400240024002400240024002400240200720066a22012d00002203200a20066a22002d0000470d000240024002400240024020030e050400010203040b02402007200a460d00200141016a280000200041016a280000470d050b200141106a2802002203200041106a280200470d04200141086a2802002208200041086a2802002209460d0920082009200310f8040d040c090b02402007200a460d00200141016a280000200041016a280000470d040b200141106a2802002203200041106a280200470d03200141086a2802002208200041086a2802002209460d0720082009200310f8040d030c070b02402007200a460d00200141016a280000200041016a280000470d030b200141106a2802002203200041106a280200470d02200141086a2802002208200041086a2802002209460d0520082009200310f8040d020c050b2001410c6a28020022032000410c6a280200470d01200141046a2802002208200041046a2802002209460d0320082009200310f8040d010c030b2007200a460d07200141016a200041016a412010f804450d010b41c882c00041141009200241b0046a2001104520022802b004220320022802b804100d024020022802b404450d002003102e0b200241b0046a2000104520022802b004220320022802b804100d024020022802b404450d002003102e0b20012d000020002d00002203470d05024020030e050005040302000b2007200a460d060b200141016a200041016a412010f8040d040c050b2001410c6a28020022032000410c6a280200470d03200141046a2802002201200041046a2802002200460d0420012000200310f804450d040c030b02402007200a460d00200141016a280000200041016a280000470d030b200141106a2802002203200041106a280200470d02200141086a2802002201200041086a2802002200460d0320012000200310f8040d020c030b02402007200a460d00200141016a280000200041016a280000470d020b200141106a2802002203200041106a280200470d01200141086a2802002201200041086a2802002200460d0220012000200310f8040d010c020b02402007200a460d00200141016a280000200041016a280000470d010b200141106a2802002203200041106a280200470d00200141086a2802002201200041086a2802002200460d0120012000200310f804450d010b4198a8c2001058000b200641246a21062004417f6a22040d000b0b024020024190026a41306a2201200241e0076a41306a2200412010f804450d0041a8e5c500410e100920014120100d20004120100d0b024020012000412010f804450d0041b0a8c2001058000b024020022802ec072200450d0020022802e4072101200041246c210003400240024020012d0000220641034b0d0002400240024020060e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b0240200241e8076a280200450d0020022802e407102e0b0240200228029c022200450d002002280294022101200041246c210003400240024020012d0000220641034b0d0002400240024020060e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b024020024198026a280200450d00200228029402102e0b200241800a6a240042010f0b20024180036a41146a411d36020020024180036a410c6a4120360200200241f8066a41146a41033602002002200241f0066a3602e0062002200241f4066a3602d006200241b0046a41146a4100360200200242033702fc062002419ce7c5003602f8062002412036028403200241c8ecc5003602c004200242013702b40420024180a8c2003602b004200220024180036a360288072002200241b0046a360290032002200241d0066a360288032002200241e0066a36028003200241f8066a4188a8c200106a000b41d0a7c2001058000b41b8a7c2001058000b41a0a7c2001058000bea05030c7f017e017f230041b0056b2202240020024190036a2001103c0240024020022802940322030d00200041003602040c010b2002419c036a280200210420022802980321052002280290032106200241106a200241a0036a41e00010f6041a200241086a20011031024020022802080d000240024002400240200128020441a0026e220741a0026c2208417f4c0d00200228020c21090240024020080d004108210a0c010b20081029220a450d020b024002402009450d004100210b410021084100210c034020024190036a200110b70120022903f8034203510d02200c41016a210d200241f0006a20024190036a41a00210f6041a0240200c2007470d00200b200d200d200b491b2207ad42a0027e220e422088a70d07200ea7220f4100480d0702400240200c0d00200f1029210a0c010b200a2008200f102a210a0b200a450d060b200a20086a200241f0006a41a00210f6041a200b41026a210b200841a0026a2108200d210c2009200d470d000b0b200a450d0520024190036a200241106a41e00010f6041a2000410c6a2004360200200020053602082000200336020420002006360200200041106a20024190036a41e00010f6041a200041f8006a2009360200200041f4006a2007360200200041f0006a200a3602000c060b0240200c450d00200a4198016a210d0340200d102f200d41a0026a210d200841e07d6a22080d000b0b2007450d04200a102e0c040b1032000b20084108102c000b200f4108102c000b102d000b2000410036020402402004450d00200441246c210d2003210803400240024020082d0000220c41034b0d00024002400240200c0e0404000102040b2008410c6a280200450d03200841086a280200102e0c030b2008410c6a280200450d02200841086a280200102e0c020b2008410c6a280200450d01200841086a280200102e0c010b200841086a280200450d00200841046a280200102e0b200841246a2108200d415c6a220d0d000b0b2005450d002003102e0b200241b0056a24000bb9cb01070c7f017e0b7f0e7e017f027e167f230041c00c6b220124000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402000410c6a28020041246c22020d004100210341002104410421050c010b200028020421064104210541002103410021040340024020062d00004101470d00200641106a2802002207417f4c0d16200641016a28000021080240024020070d00410121090c010b200641086a280200210a200710292209450d042009200a200710f6041a0b200141a00b6a41086a220b200141a8056a41086a290200370300200120012902a8053703a00b024020032004470d00200341016a220a2003490d1c2003410174220c200a200a200c491b2204ad42247e220d422088a70d1c200da7220a4100480d1c0240024020030d00200a102921050c010b2005200341246c200a102a21050b2005450d050b2005200341246c6a220a2007360210200a200736020c200a2009360208200a2008360001200a41013a0000200a20012903a00b370214200a411c6a200b290300370200200341016a21030b200641246a21062002415c6a22020d000b0b200141003602a00b41dff0c2004110200141a00b6a41041004200141f0086a41086a22064200370300200142003703f00841b0f3c200410d200141f0086a1003200141d8076a41086a220a2006290300370300200120012903f0083703d80720012000280200220e3602a00b200141d8076a4110200141a00b6a4104100420064200370300200142003703f00841d2f3c200410d200141f0086a1003200a2006290300370300200120012903f0083703d807200141003602b005200142013703a8052003200141a8056a10470240024020030d0020012802b005210a20012802ac05210820012802a80521070c010b200341246c210c20012802ac05210820012802b0052106200521020340200141a00b6a2002104520012802a00b210b02400240200820066b20012802a80b2209490d00200620096a210a20012802a80521070c010b200620096a220a2006490d1b20084101742207200a200a2007491b220f4100480d1b0240024020080d00200f102921070c010b20012802a8052008200f102a21070b2007450d052001200f3602ac05200120073602a805200f21080b2001200a3602b005200720066a200b200910f6041a024020012802a40b450d00200b102e0b200241246a2102200a2106200c415c6a220c0d000b0b200041106a2102200141d8076a41102007200a100402402008450d002007102e0b200141f0086a41086a22064200370300200142003703f008418cf5c2004111200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d8072001200141d8076a3602a00b200141103602a40b2002200141a00b6a10b802411010292206450d03200641086a41002900e7f342370000200641002900dff342370000200641104120102a220a450d04200a200e417f6a360010200141f0086a41186a22074200370300200141f0086a41106a22094200370300200141f0086a41086a22064200370300200142003703f008200a4114200141f0086a100020014198046a41186a200729030037030020014198046a41106a200929030037030020014198046a41086a2006290300370300200120012903f00837039804200141203602a40b200120014198046a3602a00b2002200141a00b6a10b802200a102e20064200370300200142003703f00841bdf3c2004115200141f0086a1003200141d8076a41086a220a2006290300370300200120012903f0083703d807200141103602a40b2001200141d8076a3602a00b200041d0006a200141a00b6a10b80220064200370300200142003703f008419df5c2004115200141f0086a1003200a2006290300370300200120012903f0083703d807200141a00b6a200141d8076a10fe02024020012802a40b22060d00200141013602a8054100210a41002107410021020c070b200120063602a80520012c00a00b210220012802a80b2107200141ac0b6a280200220a41d100490d06200141a00b6a41186a2208200041286a290000370300200141a00b6a41106a220b200041206a290000370300200141a00b6a41086a220c200041186a290000370300200120002900103703a00b200a20024d0d05200620024105746a220920012903a00b370000200941186a2008290300370000200941106a200b290300370000200941086a200c290300370000200241187441808080086a41187541d1006f21020c070b20074101102c000b200a4104102c000b200f4101102c000b41104101102c000b41204101102c000b41b4f5c2002002200a1038000b200141a00b6a41186a200041286a290000370300200141b00b6a200041206a290000370300200141a80b6a200041186a290000370300200120002900103703a00b02400240200a2007460d0020012802a80521060c010b200a41016a2206200a490d12200a4101742207200620062007491b220741ffffff3f712007470d12200741057422094100480d1202400240200a0d002009102921060c010b20012802a805200a4105742009102a21060b2006450d02200120063602a8050b2006200a4105746a220920012903a00b370000200941186a200141a00b6a41186a290300370000200941106a200141a00b6a41106a290300370000200941086a200141a00b6a41086a290300370000200a41016a210a0b200141f0086a41086a22094200370300200142003703f008419df5c2004115200141f0086a1003200141d8076a41086a2009290300370300200120012903f0083703d807410110292209450d01200920023a000020014281808080103702a40b200120093602a00b200a200141a00b6a1047200a410574210a03402006200141a00b6a1046200641206a2106200a41606a220a0d000b20012802a40b2106200141d8076a411020012802a00b220a20012802a80b100402402006450d00200a102e0b02402007450d0020012802a805102e0b200141f0086a41086a22064200370300200142003703f00841c4f5c200410d200141f0086a1003200141d8076a41086a220a2006290300370300200120012903f0083703d807200141d8076a4110100620064200370300200142003703f0084197e5c5004111200141f0086a1003200a2006290300370300200120012903f0083703d807200141d8076a4110100641121029220a450d02200a41106a41002f00e1f5423b0000200a41086a41002900d9f542370000200a41002900d1f542370000200141f0086a41186a22074200370300200141f0086a41106a2202420037030020064200370300200142003703f008200a4112200141f0086a100020014198046a41186a2209200729030037030020014198046a41106a200229030037030020014198046a41086a2006290300370300200120012903f00837039804412010292206450d032006200129039804370000200641186a2009290300370000200641106a20014198046a41106a290300370000200641086a20014198046a41086a290300370000200a102e2006412010182006102e20002802002110107f200141f0086a41086a22064200370300200142003703f008419893c2004111200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141003602a00b200141d8076a4110200141a00b6a100821060240024020012802a00b220a417f460d002006450d002001200a3602ac05200120063602a805200141a00b6a200141a8056a103d20012802a00b2208450d0620012902a40b210d200a450d012006102e0c010b410421084200210d0b20104105490d082010417b6a21022008200d422088a7220b41c4006c22066a21090240200641cd014f0d00410021062008210a0c070b200841d0016a210a4100210603400240200a41b07e6a22072d00004101460d00200a41b47e6a28020020024f0d090b0240200741c4006a2d00004101460d00200a41f87e6a2802002002490d00200641016a21060c090b024020074188016a2d00004101460d00200a41bc7f6a2802002002490d00200641026a21060c090b02400240200741cc016a2d00004101460d00200a28020020024f0d010b200a4190026a210a200641046a2106200920074190026a6b41cc014d0d070c010b0b200641036a21060c070b20094101102c000b41014101102c000b41124101102c000b41204101102c000b41eff0c2004133200141c0066a4184f4c2001053000b200a41b07e6a210a0b200a2009460d002008200b41c4006c6a210703400240200a2d00004101460d00200a41046a28020020024f0d020b200641016a21062007200a41c4006a220a470d000b0b2006200b4b0d01200d42ffffffff0f83210d200b20066b220a450d002006450d0020082008200641c4006c6a200a41c4006c10f7041a0b200141003a00a00b200141f0086a41086a22064200370300200142003703f00841d49bc5004117200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141d8076a4110200141a00b6a41011004200141a00b6a1088010240412410292206450d00200620012903a00b37000020064114360220200641186a200141a00b6a41186a290300370000200641106a200141a00b6a41106a290300370000200641086a200141a00b6a41086a29030037000020014281808080103702ac05200120063602a805200141a8056a1097020240200da7450d002008102e0b10d902024020104180ce18700d000240024041a199c500411f109c01220641ff01714102460d0020064101710d010b201010ff02450d0120101080031a0c010b2010108003450d00201010ff021a0b20014190046a418e99c5004113107d2001280294042106200128029004210a20014188046a41f598c5004119107d0240024002400240024020064100200a1b2206200128028c0441002001280288041b22074f0d00200141b10c6a21022001418c0a6a21080340200141a00b6a2006108103024020012d00b00c220a4103460d002008200141a00b6a41900110f6041a2001200241036a28000036008b052001200228000036028805200141f0086a200141880a6a41940110f6041a200621090b200141d8076a200141f0086a41940110f6041a2001200128008b053600eb0420012001280288053602e8040240200a4103470d002007200641016a2206470d010c020b0b200141c0066a200141d8076a41940110f6041a200120012800eb043600c304200120012802e8043602c004200120093602a00b200141a00b6a410472200141c0066a41940110f6041a200141a00b6a4198016a200a3a0000200141b90c6a220220012802c004360000200141bc0c6a20012800c30436000002400240200141b00c6a2802002010460d00200141a80b6a102f4103210a410121020c010b200141a8056a200141a00b6a41980110f6041a2001200241036a28000036009b042001200228000036029804410021020b200a4103470d010b410821114100210a410021120c010b200141a00b6a200141a8056a41980110f6041a2001200128009b0436008b0a20012001280298043602880a41a00110292211450d022011200141a00b6a41980110f6042209200a3a009801200920012802880a360099012009419c016a200128008b0a3600004101210a02402002450d00410121120c010b02400240200641016a220620074f0d00200141b10c6a21092001418c0a6a210c0340200141a00b6a2006108103024020012d00b00c22024103460d00200c200141a00b6a41900110f6041a2001200941036a28000036008b052001200928000036028805200141f0086a200141880a6a41940110f6041a2006210b0b200141d8076a200141f0086a41940110f6041a2001200128008b053600eb0420012001280288053602e80420024103470d022007200641016a2206470d000b0b410121120c010b200141c0066a200141d8076a41940110f6041a200120012800eb043600c304200120012802e8043602c0042001200b3602a00b200141a00b6a410472200141c0066a41940110f6041a200141a00b6a4198016a20023a0000200141b90c6a220a20012802c004360000200141bc0c6a20012800c30436000002400240200141b00c6a2802002010460d00200141a80b6a102f410321024101210c0c010b200141a8056a200141a00b6a41980110f6041a2001200a41036a28000036009b042001200a280000360298044100210c0b024020024103470d004101210a410121120c010b200641016a2106200141a00b6a4104722100200141a80b6a2113200141a00b6a4199016a210f200141b10c6a21094101210a410121120340200141a00b6a200141a8056a41980110f6041a2001200128009b0436008b0a20012001280298043602880a02402012200a470d00200a41016a220b200a490d0d200a410174220e200b200b200e491b2212ad42a0017e220d422088a70d0d200da7220b4100480d0d02400240200a0d00200b102921110c010b2011200a41a0016c200b102a21110b2011450d030b2011200a41a0016c6a200141a00b6a41980110f604220b4198016a20023a0000200b4199016a20012802880a360000200b419c016a200128008b0a360000200a41016a210a200c41ff01710d01200620074f0d010340200141a00b6a2006108103024020012d00b00c22024103460d002008200141a00b6a41900110f6041a2001200941036a28000036008b052001200928000036028805200141f0086a200141880a6a41940110f6041a2006210b0b200141d8076a200141f0086a41940110f6041a2001200128008b053600eb0420012001280288053602e804024020024103470d002007200641016a2206470d010c030b0b200141c0066a200141d8076a41940110f6041a200120012800eb043600c304200120012802e8043602c0042001200b3602a00b2000200141c0066a41940110f6041a200f20012802c004360000200f41036a220b20012800c304360000200120023a00b80c0240024020012802b00c2010460d002013102f410321024101210c0c010b200141a8056a200141a00b6a41980110f6041a2001200b28000036009b042001200f280000360298044100210c0b200641016a210620024103470d000b0b2011200a41a0016c6a21140240200a0d00201121150c050b200141a00b6a4104722106200141b9066a2116200141880a6a41046a2117200141f0026a41106a21182011211503402015220a2802002102200141a00b6a200a41046a41940110f6041a2001200a4199016a2800003602a8052001200a419c016a2800003600ab05200a41a0016a2115200a4198016a2d0000220a4103460d05200141880a6a200141a00b6a41940110f6041a200120012800ab053600bb04200120012802a8053602b804200141a8056a201741900110f6041a201620012802b804360000201641036a20012800bb043600002001200a3a00b806200141f0086a200210820320012802f008210b0240024020012802f808220a0d00420021194200211a4200211b4200211c4200211d4200211e0c010b200a41057421094200211d200b210a4200211e4200211b4200211c420021194200211a0340200141f8036a200a108401200141f8036a41086a290300211f20012903f803210d2006200a290000370000200641086a200a41086a290000370000200641106a200a41106a290000370000200641186a200a41186a290000370000200120023602a00b200141f0036a200141a00b6a10830320012d00f00341017121070240024020012d00f10322080d00200141b0036a200d201f420a420010fc0420012903b0032220210d200141b0036a41086a2903002221211f0c010b200141d0036a201f42002008ad2220420010fb04200141e0036a200d42002020420010fb04200141c0036a42004200200d420010fb04427f200141e0036a41086a290300222020012903d00320012903c0037c7c222120012903d80320012903c8038442005220212020547222081b2121427f20012903e00320081b21200b200a41206a210a4200202120071b201c7c4200202020071b2222201b7c221b202254ad7c211c2021420020071b201a7c2020420020071b222020197c2219202054ad7c211a201f201e7c200d201d7c221d200d54ad7c211e200941606a22090d000b0b024020012802f408450d00200b102e0b200141f0086a200210820320012802f00821000240024020012802f808220a0d004200212242002123420021244200212542002121420021260c010b200a4105742109420021212000210a420021264200212442002125420021224200212303402006200a290000370000200641086a200a41086a2207290000370000200641106a200a41106a2208290000370000200641186a200a41186a220b290000370000200120023602a00b200141a8036a200141a00b6a10830320012d00a803210c20012d00a903210f200141a00b6a41186a200b290000370300200141a00b6a41106a2008290000370300200141a00b6a41086a20072900003703002001200a2900003703a00b20014188036a2002200141a00b6a200f411010840320014188036a41186a29030020267c200129039803220d20217c2221200d54ad7c2126420020014188036a41086a290300220d200c41017122071b20257c4200200129038803221f20071b222020247c2224202054ad7c2125200d420020071b20237c201f420020071b220d20227c2222200d54ad7c2123200a41206a210a200941606a22090d000b0b024020012802f408450d002000102e0b200141f0086a41086a22274200370300200142003703f00841c28cc0004116200141f0086a1003200141d8076a41086a22072027290300370300200120012903f0083703d807200141f0026a200141d8076a1097012018290300420020012802f002220a1b210d20012903f8024200200a1b211f024002402021201d7c22204202882026201e7c2020202154ad7c2221423e8684221d2020852021420288221e20218584500d00201d201e84500d004100210a02400340200141e0026a20202021200a41046a41fe007110fa04200a41026a210a20012903e002221d202085200141e0026a41086a290300221e20218584500d01201d201e844200520d000b0b200141d0026a20202021200a41fe007110fa0420012903d002200141d0026a41086a29030084211d4200211e0240200a0d00201d420052ad211d0c020b201d420052ad211d0340200141b0026a202020214100200a417e6a22092009200a4b1b220a41ff007110fa04200141c0026a201d42018622284201842226201e420186201d423f8884221e2026201e10fb042028202620012903c00220012903b00256200141c0026a41086a290300221d200141b0026a41086a290300222956201d2029511b1b211d200a0d000c020b0b4200211e2020202184420052ad211d0b02400240201f420288200d423e86842220201f85200d4202882221200d8584500d002020202184500d004100210a02400340200141a0026a201f200d200a41046a41fe007110fa04200a41026a210a20012903a0022220201f85200141a0026a41086a2903002221200d8584500d0120202021844200520d000b0b20014190026a201f200d200a41fe007110fa0420012903900220014190026a41086a290300842120420021210240200a0d002020420052ad21200c020b2020420052ad21200340200141f0016a201f200d4100200a417e6a22092009200a4b1b220a41ff007110fa0420014180026a20204201862228420184222620214201862020423f888422212026202110fb042028202620012903800220012903f0015620014180026a41086a2903002220200141f0016a41086a29030022295620202029511b1b2120200a0d000c020b0b42002121201f200d84420052ad21200b02400240024002400240201d201e8450450d004100210e0c010b2025201c7c2024201b7c221f202454ad7c21242023201a7c202220197c220d202254ad7c212202400240024020012d00b8060e03010200010b200d201f56202220245620222024511b210e0c020b0340200141a0016a201f2024201d201e10fc04202022192021221a844200510d04200141a0016a41086a290300212020012903a001212620014190016a200d20222019201a10fc044101210e2026200129039001221b54202020014190016a41086a2903002221542020202151220a1b0d020240201b2026542021202054200a1b450d004100210e0c030b20014180016a20262020201d201e10fb04200141f0006a201b20212019201a10fb040240200d200129037022207d22212022200141f0006a41086a2903007d200d202054ad7d222684500d00202420014180016a41086a2903007d211b201f200129038001220d54210a201f200d7d2120201d210d201e21222021211d2026211e2019211f201a21242020201b200aad7d222184500d030c010b0b4100210e0c010b0340201e2126201d211920202021844200510d02200141d0016a200d20222019202610fc04200141e0016a201f20242020202110fc044101210e20012903e001221a20012903d001221b54200141e0016a41086a290300221d200141d0016a41086a290300221e54201d201e51220a1b0d010240201b201a54201e201d54200a1b450d004100210e0c020b200141c0016a201a201d2020202110fb04200141b0016a201b201e2019202610fb040240200d20012903b001221d7d221e2022200141b0016a41086a2903007d200d201d54ad7d221a8450450d004100210e0c020b2024200141c0016a41086a2903007d211b201f20012903c001220d54210a201f200d7d211d2020210d20212122201e2120201a21212019211f20262124201d201b200aad7d221e844200520d000b0b200141a00b6a200210820320012802a00b212a20012802a40b212b20012802a80b220a450d02202a200a410574222c6a212d202a210a0340200141f0086a41186a222e200a41186a2209290000220d370300200141f0086a41106a222f200a41106a2208290000221f3703002027200a41086a220b29000022203703002001200a29000022213703f00820014188056a41186a2230200929000037030020014188056a41106a2231200829000037030020014188056a41086a2232200b290000370300200a290000211d20014198046a41086a220c202037030020014198046a41106a220f201f37030020014198046a41186a2200200d3703002001201d370388052001202137039804200a290000210d200641186a223320092900003700002006200d370000200641086a2234200b290000370000200641106a22352008290000370000200120023602a00b200141e8006a200141a00b6a108303410221090240200e20012d0068410171220845734101470d0020012d00692136200141d8076a41186a2000290300370300200141d8076a41106a200f2903003703002007200c29030037030020012001290398043703d807200821090b200141c0066a41086a22372007290300370300200141c0066a41106a2238200141d8076a41106a2213290300370300200141c0066a41186a2239200141d8076a41186a223a290300370300200120012903d8073703c0060240024020094102460d00200a41206a210a0c010b200a41206a210a202c41606a222c0d010c040b0b0340200141c0046a41086a2037290300220d370300200141c0046a41106a2038290300221f370300200141c0046a41186a20392903002220370300200120012903c00622213703c004200141a00b6a41186a2020370300200141a00b6a41106a201f370300200141a00b6a41086a200d370300200120213703a00b200142e4cab5fbb6ccdcb0e3003703e004200141e0046a200141a00b6a203641187441187541027441c098c5006a2802004180af1a6c20106a108f01200a202d460d030340202e200a41186a2209290000220d370300202f200a41106a2208290000221f3703002027200a41086a220b29000022203703002001200a29000022213703f00820302009290000370300203120082900003703002032200b290000370300200a290000211d200c2020370300200f201f3703002000200d3703002001201d370388052001202137039804200120023602a00b200b290000210d2008290000211f200a2900002120203320092900003700002035201f3700002034200d37000020062020370000200141e0006a200141a00b6a108303410221090240200e20012d0060410171220845734101470d0020012d00612136203a20002903003703002013200f2903003703002007200c29030037030020012001290398043703d807200821090b20372007290300370300203820132903003703002039203a290300370300200120012903d8073703c006024020094102470d00202d200a41206a220a470d010c050b0b200a41206a210a0c000b0b41c881c0001058000b41c881c0001058000b0240202b450d00202a102e0b200210850302400240200e0d00200141053a00a80b200141053a00a00b200120023602ac0b41c8ecc5004100200141a00b6a107220274200370300200142003703f008418e99c5004113200141f0086a100320072027290300370300200120012903f0083703d8072001200241016a3602a00b200141d8076a4110200141a00b6a41041004200141a8056a102f0c010b200120023602ac0b200141043a00a80b200141053a00a00b41c8ecc5004100200141a00b6a1072024020012802b406220a450d00200141a00b6a200141a8056a41980110f6041a200141d8076a200a20106a220c108603200141f0086a200141a00b6a41880110f6041a0240024002400240024020012802dc07220b20012802e007220a460d0020012802d80721080c010b200a41016a2209200a490d11200a4101742208200920092008491b220bad4290017e220d422088a70d11200da722094100480d1102400240200a0d002009102921080c010b20012802d807200a4190016c2009102a21080b2008450d012001200b3602dc07200120083602d8070b2008200a4190016c22006a200141f0086a41880110f6042002360288012001200a41016a22093602e00741171029220a450d01200a410f6a410029008fc944370000200a41086a4100290088c944370000200a4100290080c944370000200a4117412e102a220a450d02200a200c360017200141f0086a41186a220c4200370300200141f0086a41106a220f420037030020274200370300200142003703f008200a411b200141f0086a100020014188056a41186a200c29030037030020014188056a41106a200f29030037030020014188056a41086a2027290300370300200120012903f00837038805200141f0086a2008200910be0120014188056a412020012802f008220c20012802f8081004024020012802f408450d00200c102e0b200a102e02402009450d0020004190016a21092008210a03400240200a2d00004113460d00200a102f0b200a4190016a210a200941f07e6a22090d000b0b0240200b450d002008102e0b20274200370300200142003703f008418e99c5004113200141f0086a100320072027290300370300200120012903f0083703d8072001200241016a3602a00b200141d8076a4110200141a00b6a410410040c040b20094108102c000b41174101102c000b412e4101102c000b200141a00b6a200141a8056a41880110f6041a200141003b01f008200141d8006a200141a00b6a200141f0086a10950220012001280258453a00a90b200141073a00a80b200141053a00a00b200120023602ac0b41c8ecc5004100200141a00b6a107220274200370300200142003703f008418e99c5004113200141f0086a100320072027290300370300200120012903f0083703d8072001200241016a3602a00b200141d8076a4110200141a00b6a410410040b20152014470d000b201421150c040b200b4108102c000b41a0014108102c000b41244104102c000b418cc6c5001058000b024020152014460d00200141a80b6a2107200141a00b6a4199016a210a0340200141a00b6a201541980110f6041a20154198016a2d0000210620012015419c016a28000036008b0a200120154199016a2800003602880a20064103460d01200141a8056a200141a00b6a41980110f6041a2001200128008b0a3600f308200120012802880a3602f008200141a00b6a200141a8056a41980110f6041a200a20012802f008360000200a41036a20012800f308360000200120063a00b80c2007102f201541a0016a22152014470d000b0b02402012450d002011102e0b024002400240411710292206450d002006410f6a410029008fc944370000200641086a4100290088c94437000020064100290080c94437000020064117412e102a2206450d0120062010360017200141f0086a41186a220a4200370300200141f0086a41106a22074200370300200141f0086a41086a22024200370300200142003703f0082006411b200141f0086a100020014188056a41186a200a29030037030020014188056a41106a200729030037030020014188056a41086a2002290300370300200120012903f00837038805200141a00b6a20014188056a108703024020012802a00b220b450d0020014188056a412010060b200141a00b6a41086a280200210a20012802a40b210f2006102e200b4108200b1b220c200a4100200b1b4190016c220a6a2102200c21060240200a450d00200a41f07e6a2107200141a00b6a4101722108200c21060240034020062d0000210a200141a8056a200641016a41870110f6041a200a4114460d01200141a00b6a200141a8056a41870110f6041a024002400240200a4113470d0020070d01200221060c050b20064188016a2800002109200141880a6a200141a00b6a41870110f6041a2001200a3a00a00b2008200141880a6a41870110f6041a200141003b01a805200141d0006a200141a00b6a200141a8056a1095022001280250210a200120093602ac0b2001200a453a00a90b200141073a00a80b200141053a00a00b41c8ecc5004100200141a00b6a10722007450d010b20064190016a2106200741f07e6a21070c010b0b200221060c010b20064190016a21060b20062002460d02200141a00b6a4101722107034020062d0000210a200141a00b6a200641016a418f0110f6041a200a4114460d03200141a8056a200141a00b6a418f0110f6041a2001200a3a00a00b2007200141a8056a418f0110f6041a0240200a4113460d00200141a00b6a102f0b20064190016a22062002470d000c030b0b41174101102c000b412e4101102c000b0240200b450d00200f450d00200c102e0b024002400240024002400240024002400240024020104180e101700d00200141c8006a41abd9c5004114107d2001280248450d00200128024c220a450d00200141f0086a41086a22064200370300200142003703f00841edf8c000410f200141f0086a1003200141d8076a41086a22092006290300370300200120012903f0083703d807200141a00b6a200141d8076a10de010240024020012802a00b22070d004104210741002102410021080c010b200141a00b6a41086a280200210220012802a40b21080b20064200370300200142003703f00841fcf8c0004114200141f0086a100320092006290300370300200120012903f0083703d807200141a00b6a200141d8076a10dd010240024020012802a80b220c0d00200141c0006a41b0f3c200410d107d4100210b2001280244410020012802401b2106200221090c010b20012802a40b220b20026a200141b00b6a2802006b210920012802a00b210620012802ac0b450d00200c102e0b024002400240024002402009200a490d000240200b200a4f0d00200b200a6b220620026a220a20064f0d022007200a41246c6a28022021060c010b200141386a41a0f9c0004114107d200128023c410020012802381b20066a21060b200641ffe0016a220620064180e101706b210602402008450d002007102e0b20062010470d04200141f0086a41086a22064200370300200142003703f00841edf8c000410f200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141a00b6a200141d8076a10de010240024020012802a00b220f0d004104210f41002113410021370c010b200141a00b6a41086a280200211320012802a40b21370b200141306a41abd9c5004114107d2001280234213820012802302139200141286a41b0f3c200410d107d200128022c410020012802281b210e0240024002400240200f200f201341246c6a220a460d00200f41206a280200200e4d0d010b4101210941002107410021020c010b200141a00b6a41186a2206200f41186a290200370300200141a00b6a41106a2207200f41106a290200370300200141a00b6a41086a2202200f41086a2902003703002001200f2902003703a00b412010292209450d01200920012903a00b370000200941186a2006290300370000200941106a2007290300370000200941086a20022903003700000240200f41246a2206200a470d0041012107410121020c010b200f201341246c6a213a412021084101210a4101210703400240200641206a280200200e4d0d00200a21020c020b200141c0046a41186a220b200641186a290200370300200141c0046a41106a220c200641106a290200370300200141c0046a41086a2200200641086a290200370300200120062902003703c004024002402007200a460d00200a21020c010b200a41016a2202200a490d17200a4101742227200220022027491b220241ffffff3f712002470d17200241057422274100480d1702400240200a0d002027102921090c010b2009200a4105742027102a21090b20090d0020274101102c000b200920086a220a20012903c004370000200a41186a200b290300370000200a41106a200c290300370000200a41086a2000290300370000200841206a2108200741016a21072002210a203a200641246a2206470d000b0b024002400240024002402038410020391b2208201320076b220a4d0d00200141206a41b4f9c000411c107d2001280224210b2001280220210c200141f0086a41086a22064200370300200142003703f00841fcf8c0004114200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807410810292206450d0120014288808080c0003702a40b200120063602a00b2006200b4100200c1b200e6a3600000240024020012802a40b220b20012802a80b22066b4104490d0020012802a00b210b0c010b200641046a220c2006490d1a200b4101742206200c200c2006491b22064100480d1a02400240200b0d0020061029210b0c010b20012802a00b200b2006102a210b0b200b450d03200120063602a40b2001200b3602a00b20012802a80b21060b2001200641046a3602a80b200b20066a2008200a6b22003600002007200141a00b6a104702402007450d002007410574210a2009210603402006200141a00b6a104a200641206a2106200a41606a220a0d000b0b20012802a40b2106200141d8076a411020012802a00b220a20012802a80b100402402006450d00200a102e0b02402002450d002009102e0b200141c0056a4200370300200141b8056a4200370300200141b0056a4200370300200142003703a805200041066a220ead42307e220d422088a70d14200da72206417f4c0d140240024020060d004108213a4108210a0c010b20061029223a450d04203a210a0b200141a00b6a41186a220b200141a8056a41186a290300370300200141a00b6a41106a220c200141a8056a41106a290300370300200141a00b6a41086a200141a8056a41086a290300370300200120012903a8053703a00b200e4102490d04200820076a20136b41056a2107200a21060340200141c0046a41186a2202200b290300370300200141c0046a41106a2209200c290300370300200141c0046a41086a2208200141a00b6a41086a290300370300200120012903a00b3703c0042006420037030820064200370300200641106a20012903c004370300200641186a2008290300370300200641206a2009290300370300200641286a2002290300370300200641306a21062007417f6a22070d000b200041056a21070c070b2002450d082009102e0c080b41084101102c000b20064101102c000b20064108102c000b41002107200a2106200e0d020c030b41204101102c000b4190f9c000200a20021038000b2006420037030820064200370300200620012903a00b370310200641186a200141a80b6a290300370300200641206a200141b00b6a290300370300200641286a200141a00b6a41186a290300370300200741016a21070b200141f0086a41086a22064200370300200142003703f00841d0f9c0004113200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141003602a80b200142013703a00b2007200141a00b6a104702402007450d00200a200741306c6a21090340200a41086a290300210d200a290300211f0240024020012802a40b220720012802a80b22066b4110490d0020012802a00b21070c010b200641106a22022006490d1320074101742206200220022006491b22064100480d130240024020070d002006102921070c010b20012802a00b20072006102a21070b2007450d05200120063602a40b200120073602a00b20012802a80b21060b200720066a2207200d3700082007201f3700002001200641106a3602a80b200a41106a200141a00b6a104a200a41306a220a2009470d000b0b20012802a40b2106200141d8076a411020012802a00b220a20012802a80b100402402006450d00200a102e0b0240200e450d00203a102e0b200141083a00a00b200141a00b6a41086a2000360200200141023a00a40b41c8ecc5004100200141a00b6a10720b2037450d00200f102e0b200141f0086a41086a22064200370300200142003703f00841fcf8c0004114200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141a00b6a200141d8076a10dd0120012802a80b2218450d1120012802ac0b211120012802a00b2010470d10200141f0086a41086a22064200370300200142003703f00841fcf8c0004114200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141a00b6a200141d8076a10dd01024020012802a80b223b450d00200141d8076a411010060b0240203b0d0002402011450d002018102e0b4199fac000410f100941a8fac000413510090c120b20012902ac0b211d20012802a40b211442002121200141f0086a41086a22064200370300200142003703f00841d0f9c0004113200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141a00b6a200141d8076a10e0010240024020012802a00b222a450d00200141d8076a4110100620012902a40b21210c010b4108212a0b200141186a41b0f3c200410d107d200128021c21392001280218212c200141106a41a0f9c0004114107d2001280210212f20012802142130202a2021422088a7223c41306c6a210e0240024020140d0041002100410021094100210a0c010b2014417f6a21094100210a0240202a200e460d000240202a203c41306c6a220641506a220e290300200e41086a2903008450450d00410121000c020b20014188056a41186a200641606a220641186a29000037030020014188056a41106a200641106a29000037030020014188056a41086a200641086a29000037030020012006290000370388054101210a0b410021000b200141a90b6a20014188056a41086a290300370000200141b10b6a20014188056a41106a290300370000200141b90b6a20014188056a41186a2903003700002001200a3a00a00b20012001290388053700a10b200141a00b6a4101722106200a450d0620064280809aa6eaafe3014200109401200141e8046a41086a200641086a290000370300200141e8046a41106a200641106a290000370300200141e8046a41186a200641186a290000370300200120062900003703e80420012d00a00b4101470d07412010292236450d01203620012903e804370000203641186a200141e8046a41186a290300370000203641106a200141e8046a41106a290300370000203641086a200141e8046a41086a290300370000200141a00b6a41017221064102210241202107410121354101212d0340024002400240024020090d00410021090c010b2009417f6a2109200041ff01710d000240202a200e470d00410021000c010b200e41506a2208290300200841086a290300844200520d01410121002008210e0b200620012903c004370000200641086a200141c0046a41086a290300370000200641106a200141c0046a41106a290300370000200641186a200141c0046a41186a2903003700004100210a200141003a00a00b0c010b200141c0046a41186a200e41606a220a41186a290000220d370300200141c0046a41106a200a41106a290000221f370300200141c0046a41086a200a41086a29000022203703002001200a29000022223703c00420062022370000200641086a2020370000200641106a201f370000200641186a200d370000200141013a00a00b20064280809aa6eaafe30142001094014100210020012d00a00b210a2008210e0b200141c0066a41186a2208200641186a290000370300200141c0066a41106a220b200641106a290000370300200141c0066a41086a220c200641086a290000370300200120062900003703c0060240200a41ff0171450d00200141a00b6a41186a220f2008290300370300200141a00b6a41106a2208200b290300370300200141a00b6a41086a220b200c290300370300200120012903c0063703a00b02402035202d470d00203541016a220a2035490d112002200a200a2002491b222d41ffffff3f71202d470d11202d410574220a4100480d110240024020350d00200a102921360c010b20362007200a102a21360b2036450d080b203620076a220a20012903a00b370000200a41186a200f290300370000200a41106a2008290300370000200a41086a200b290300370000200241026a2102200741206a2107203541016a21350c010b0b203620076a21372035450d08200141a00b6a41086a21022036210f0340200141d8076a200f10c501024020012802d8074101470d0020012802e0072107200141880a6a10c70120012802880a2138024020012802900a2206450d00200641216c210a203841016a21062007410876210941012007411f7174210020074105764107712208417f73210e034002402006417f6a2d00004101470d00200141a00b6a41186a200641186a290000370300200141a00b6a41106a200641106a2900003703002002200641086a290000370300200120062900003703a00b200120093602c00b200141a8056a200141a00b6a10c9010240200820012802b00522074f0d002007200e6a220b20074f0d0820012802a805220c200b4102746a2802002000712107024020012802ac05450d00200c102e0b2007450d01200141a00b6a200610ca01024020012903a00b4201510d00411310292207450d0a20074100290086fa403700002007410f6a4100280095fa40360000200741086a410029008efa4037000020014293808080b0023702ac05200120073602a8052006200141a8056a104a20012802ac05210b20012802b005210c20012802a8052107200141c0046a41186a22134200370300200141c0046a41106a223a4200370300200141c0046a41086a22274200370300200142003703c0042007200c200141c0046a1000200141f0086a41186a2013290300370300200141f0086a41106a203a290300370300200141f0086a41086a2027290300370300200120012903c0043703f008200141f0086a41201006200b450d022007102e0c020b200141086a41bfd9c5004111107d2001200128020c41016a410120012802081b3602cc0b411310292207450d0a20074100290086fa403700002007410f6a4100280095fa40360000200741086a410029008efa4037000020014293808080b0023702ac05200120073602a8052006200141a8056a104a20012802ac05210b20012802b005210c20012802a8052107200141c0046a41186a22134200370300200141c0046a41106a223a4200370300200141c0046a41086a22274200370300200142003703c0042007200c200141c0046a1000200141f0086a41186a2013290300370300200141f0086a41106a203a290300370300200141f0086a41086a2027290300370300200120012903c0043703f008200141203602ac052001200141f0086a3602a8052002200141a8056a10cb01200b450d012007102e0c010b20012802ac05450d0020012802a805102e0b200641216a2106200a415f6a220a0d000b0b200128028c0a450d002038102e0b2037200f41206a220f470d000c090b0b20064101102c000b41204101102c000b4190f9c000200b20071038000b41134101102c000b41134101102c000b200a4101102c000b200141e8046a41186a200641186a290000370300200141e8046a41106a200641106a290000370300200141e8046a41086a200641086a290000370300200120062900003703e8040b4100212d4101213741012136410021350b200141f0086a41086a22064200370300200142003703f00841edf8c000410f200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141a00b6a200141d8076a10de010240024020012802a00b222e0d00410021324104212e410021080c010b200141a00b6a41086a280200210820012802a40b21320b200141013602a00b0240024002400240201d422088a72209450d00410021174100213d024002402009202e200841246c6a2202202e6b41246e2206200620094b1b2206450d002006410574220a4100480d0b200a10292207450d01200120073602a00b2006213d0b202e21062009210720012802a00b223e210a03400240200220066b41ec004b0d0020022006460d06202e200841246c6a210c4101210b02400340200a2006290000370000200a41186a200641186a290000370000200a41106a200641106a290000370000200a41086a200641086a2900003700002007200b2202460d01200241016a210b200a41206a210a200c200641246a2206470d000b0b201720026a21170c060b200a2006290000370000200a41186a200641186a290000370000200a41106a200641106a290000370000200a41086a200641086a290000370000024020074101470d00201741017221170c060b200a2006290024370020200a41386a2006413c6a290000370000200a41306a200641346a290000370000200a41286a2006412c6a29000037000020074102460d04200a2006290048370040200a41d8006a200641e0006a290000370000200a41d0006a200641d8006a290000370000200a41c8006a200641d0006a29000037000020074103460d03200a200629006c370060200a41f8006a20064184016a290000370000200a41f0006a200641fc006a290000370000200a41e8006a200641f4006a290000370000201741046a2117200a4180016a210a20064190016a21062007417c6a22070d000c050b0b200a4101102c000b4100213d20012802a00b213e410021170c020b201741037221170c010b201741027221170b20304100202f1b20394100202c1b6a212f202e200841246c6a21390240024002400240024002400240024002402009450d002039202e460d01200941016a210a200841246c2107202e21060340200141c0046a41186a200641186a290200370300200141c0046a41106a200641106a290200370300200141c0046a41086a200641086a290200370300200120062902003703c004200a417f6a220a450d04200641246a21062007415c6a22070d000b203921060c020b2039202e470d040b202e21060b20362037460d0120014198046a41186a203641186a220a29000037030020014198046a41106a203641106a220729000037030020014198046a41086a203641086a220229000037030020012036290000370398042002290000210d2007290000211f20362900002120200141a8056a41186a200a290000370300200141a8056a41106a201f370300200141a8056a41086a200d370300200120203703a805203641206a210741022102202f21090c040b200641206a2802002109200141a00b6a41186a200141c0046a41186a290300370300200141a00b6a41106a200141c0046a41106a290300370300200141a00b6a41086a200141c0046a41086a290300370300200120012903c0043703a00b200641246a21060c020b02402032450d00202e102e0b41042113410021314100212b4104210b0c030b200141a00b6a41186a202e41186a290200370300200141a00b6a41106a202e41106a290200370300200141a00b6a41086a202e41086a2902003703002001202e2902003703a00b202e41246a2106202e28022021090b200141a8056a41186a200141a00b6a41186a290300370300200141a8056a41106a200141a00b6a41106a290300370300200141a8056a41086a200141a00b6a41086a290300370300200120012903a00b3703a80541002102203621070b417f417f203920066b41246d220a203720076b4105766a22082008200a491b220a41016a22082008200a491b222bad42247e220d422088a70d01200da7220a417f4c0d01024002400240024002400240024002400240200a0d00410421130c010b200a10292213450d010b201320012903a805370200201341186a200141a8056a41186a290300370200201341106a200141a8056a41106a290300370200201341086a200141a8056a41086a2903003702002013200936022002402002450d00024020072037470d00410121310c050b200141f0086a41186a200741186a220a290000370300200141f0086a41106a200741106a2202290000370300200141f0086a41086a200741086a2209290000370300200120072900003703f0082009290000210d2002290000211f20072900002120200141a8056a41186a200a290000370300200141a8056a41106a201f370300200141a8056a41086a200d370300200120203703a805200741206a21070c020b024020062039470d00024020072037460d0020014198046a41186a200741186a220a29000037030020014198046a41106a200741106a220229000037030020014198046a41086a200741086a220929000037030020012007290000370398042009290000210d2002290000211f20072900002120200141a8056a41186a200a290000370300200141a8056a41106a201f370300200141a8056a41086a200d370300200120203703a805200741206a21070c030b410121310c040b200141a00b6a41186a200641186a220a290200370300200141a00b6a41106a200641106a2202290200370300200141a00b6a41086a200641086a2209290200370300200120062902003703a00b200141a8056a41086a2009290200370300200141a8056a41106a2002290200370300200141a8056a41186a200a290200370300200120062902003703a8052006280220210041002108200641246a21060c020b200a4104102c000b41022108202f21000b410221094102210a412421020340200141d8076a41186a220b200141a8056a41186a220e290300370300200141d8076a41106a220c200141a8056a41106a223a290300370300200141d8076a41086a220f200141a8056a41086a2227290300370300200120012903a8053703d8070240200a2231417f6a220a202b470d00200a417f417f203920066b41246d2238203720076b4105766a222c202c2038491b223841016a222c202c2038491b6a2238200a490d0c2009203820382009491b222bad42247e220d422088a70d0c200da7220a4100480d0c0240024020314101470d00200a102921130c010b20132002200a102a21130b2013450d030b201320026a220a20012903d807370200200a41186a200b290300370200200a41106a200c290300370200200a41086a200f290300370200200a41206a20003602000240024002400240200841ff01710e03010200010b20072037460d04200141f0086a41186a200741186a220a290000370300200141f0086a41106a200741106a2208290000370300200141f0086a41086a200741086a220b290000370300200120072900003703f008200b290000210d2008290000211f20072900002120200e200a290000370300203a201f3703002027200d370300200120203703a805200741206a21074101210b41022108202f21000c020b024020392006470d0041022108024020072037470d004100210b0c030b20014198046a41186a200741186a220a29000037030020014198046a41106a200741106a220b29000037030020014198046a41086a200741086a220c2900003703002001200729000037039804200c290000210d200b290000211f20072900002120200e200a290000370300203a201f3703002027200d370300200120203703a805200741206a21074101210b202f21000c020b200141a00b6a41186a200641186a220a290200370300200141a00b6a41106a200641106a2208290200370300200141a00b6a41086a200641086a220b290200370300200120062902003703a00b200b290200210d2008290200211f20062902002120200e200a290200370300203a201f3703002027200d370300200120203703a805200628022021004101210b41002108200641246a21060c010b20392006460d02200e200641186a290200370300203a200641106a2902003703002027200641086a290200370300200120062902003703a8052006280220210041012108200641246a21064101210b0b200941026a2109203141016a210a200241246a2102200b0d000b0b02402032450d00202e102e0b20314115490d012031410176223fad42247e220d422088a70d04200da72206417f4c0d0402400240024020060d00410421344104210b0c010b200610292234450d012034210b0b2013415c6a2110201341b47f6a21124104213a41002115410021082031212c0340202c21024100212c4101210902402002417f6a2216450d000240024002400240024002402013201641246c6a41206a280200200241246c220a20136a41586a2802002206490d002002417e6a210f2012200a6a21074100212c4100210a03400240200f200a470d00200221090c080b200a41016a210a2006200728020022094f210c2007415c6a210720092106200c0d000b200a41016a2109200a417f7320026a21070c010b2012200241096c410274220f6a210a2016210702400340024020074101470d00410021070c020b2007417f6a21072006200a280200220949210c200a415c6a210a20092106200c0d000b0b20022007490d01200220314b0d03200220076b2209410176220c450d002010200f6a21062013200741246c6a210a0340200141a00b6a41206a220f200a41206a2200280200360200200141a00b6a41186a220e200a41186a2227290200370300200141a00b6a41106a2237200a41106a2238290200370300200141a00b6a41086a2239200a41086a222c2902003703002001200a2902003703a00b200641206a222e280200212f200641186a2230290200210d200641106a2232290200211f200641086a22332902002120200a2006290200370200202c20203702002038201f3702002027200d3702002000202f360200202e200f2802003602002030200e2903003702002032203729030037020020332039290300370200200620012903a00b3702002006415c6a2106200a41246a210a200c417f6a220c0d000b0b024020070d002007212c0c050b0240200941094d0d002007212c0c050b200220314b0d012013200741246c6a210f034020022007417f6a222c490d0402402002202c6b22094102490d002013200741246c6a220641206a220a2802002013202c41246c6a220041206a220c280200220e4f0d00200141c0046a41186a2227200041186a2237290200370300200141c0046a41106a2238200041106a2239290200370300200141c0046a41086a222e200041086a222f290200370300200120002902003703c00420002006290200370200202f200641086a2902003702002039200641106a2902003702002037200641186a290200370200200c200a280200360200024020094103490d002016210a200f210c200041e8006a280200200e4f0d0002400340200c220641206a200641c4006a280200360200200641186a2006413c6a290200370200200641106a200641346a290200370200200641086a2006412c6a2902003702002006200641246a220c2902003702002007200a417f6a220a460d01200641e8006a280200200e490d000b0b200641246a21060b200620012903c0043702002006200e360220200641186a2027290300370200200641106a2038290300370200200641086a202e2903003702000b202c450d05200f415c6a210f202c21072009410a4f0d050c000b0b200720021035000b20022007417f6a222c490d010b20022031105e000b202c20021035000b02400240024020152008470d00201541016a22062015490d0e2015410174220a20062006200a491b220641ffffffff01712006470d0e2006410374220a4100480d0e0240024020150d00200a1029213a0c010b203a2015410374200a102a213a0b203a450d01200621150b203a20084103746a220620093602042006202c360200200841016a2227210820274102490d0103400240024002400240203a20272200417f6a22274103746a2206280200450d002000410374203a6a220941746a28020022022006280204220a4d0d0041022108200041024d0d06203a2000417d6a22064103746a2802042207200a20026a4d0d0141032108200041034d0d06200941646a280200200720026a4d0d01200021080c060b20004103490d012006280204210a203a2000417d6a22064103746a28020421070b2007200a490d010b2000417e6a21060b0240024002400240024002402000200641016a222e4d0d00200020064d0d01203a20064103746a2237280204222f20372802006a2206203a202e4103746a22382802002239490d02200620314b0d03203741046a21302013203941246c6a220f2038280204220e41246c220a6a2109200641246c2107200620396b2208200e6b2206200e4f0d0420342009200641246c220a10f6041a200b200a6a210202400240200e4101480d00200641014e0d010b20092106200b210a0c060b201020076a210720092106034020072006415c6a22082002415c6a220c2002417c6a2802002006417c6a2802004922091b220a290200370200200741206a200a41206a280200360200200741186a200a41186a290200370200200741106a200a41106a290200370200200741086a200a41086a2902003702002002200c20091b21020240200f2008200620091b2206490d00200b210a0c070b2007415c6a2107200b210a200b2002490d000c060b0b41f484c000202e20001038000b41f484c000200620001038000b203920061035000b20062031105e000b2034200f200a10f6041a200b200a6a210202400240200e4101480d002008200e4a0d010b200f2106200b210a0c010b201320076a210c200b210a200f2106034020062009200a200941206a280200200a41206a2802004922081b2207290200370200200641206a200741206a280200360200200641186a200741186a290200370200200641106a200741106a290200370200200641086a200741086a290200370200200a200a41246a20081b210a200641246a2106200941246a200920081b2209200c4f0d012002200a4b0d000b0b2006200a2002200a6b220720074124706b10f6041a2030202f200e6a360200203720393602002038203841086a202e417f7320006a41037410f7041a20272108202741014d0d020c000b0b200a4104102c000b202c0d000b02402015450d00203a102e0b203f450d032034102e0c030b20064104102c000b200a4104102c000b20314102490d002031417f6a21072013203141246c6a2109410021080340024002400240203120072206417f6a2207490d00203120076b220a4102490d022013200641246c6a220641206a22022802002013200741246c6a220b41206a220f280200220c4f0d02200141c0046a41186a2200200b41186a220e290200370300200141c0046a41106a223a200b41106a2227290200370300200141c0046a41086a2237200b41086a22382902003703002001200b2902003703c004200b20062902003702002038200641086a2902003702002027200641106a290200370200200e200641186a290200370200200f2002280200360200200a4103490d01200821022009210a200b41e8006a280200200c4f0d010340200a2206415c6a220a2006290200370200200a41206a200641206a280200360200200a41186a200641186a290200370200200a41106a200641106a290200370200200a41086a200641086a2902003702002002417f6a2202450d02200641246a210a200641c4006a280200200c4f0d020c000b0b200720311035000b200620012903c0043702002006200c360220200641186a2000290300370200200641106a203a290300370200200641086a20372903003702000b200841016a21082009415c6a210920070d000b0b2013210b0b200141f0086a41086a22064200370300200142003703f00841edf8c000410f200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141003602a80b200142013703a00b2031200141a00b6a10470240024002402031450d002013203141246c6a21082013210a0340200a200141a00b6a104a200a41206a28020021020240024020012802a40b220720012802a80b22066b4104490d0020012802a00b21070c010b200641046a22092006490d0a20074101742206200920092006491b22064100480d0a0240024020070d002006102921070c010b20012802a00b20072006102a21070b2007450d03200120063602a40b200120073602a00b20012802a80b21060b2001200641046a3602a80b200720066a20023600002008200a41246a220a470d000b0b20012802a40b2106200141d8076a411020012802a00b220a20012802a80b100402402006450d00200a102e0b4100210a0240203141246c22060d0041012102410021090c020b200641246d220941ffffff3f712009470d07200941057422064100480d072006102922020d0120064101102c000b20064101102c000b02402031450d002013203141246c6a21074100210a200221060340201341086a290000210d201341106a290000211f20132900002120200641186a201341186a290000370000200641106a201f370000200641086a200d37000020062020370000200a41016a210a200641206a21062007201341246a2213470d000b0b0240202b450d00200b102e0b2002200a200141c0066a41004120200a676b105f203e20172002200a10df0102402009450d002002102e0b200141f0086a41086a22064200370300200142003703f00841f4f9c0004112200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141003602a00b200141d8076a4110200141a00b6a100821060240024020012802a00b220a417f460d002006450d002001200a3602ac05200120063602a805200141a00b6a200141a8056a1030024020012802a00b2237450d00200141a80b6a280200213a20012802a40b2138200a450d022006102e0c020b41eff0c2004133200141c0066a4184f4c2001053000b41002138410121374100213a0b20014188096a420037030020014180096a4200370300200141f8086a4200370300200142003703f008203a41ffffff3f71203a470d00203a4105742206417f4c0d000240024020060d00410121080c010b200610292208450d020b200141a00b6a41186a2207200141f0086a41186a290300370300200141a00b6a41106a2202200141f0086a41106a290300370300200141a00b6a41086a2209200141f0086a41086a290300370300200120012903f0083703a00b203a4102490d02203a417f6a210a200821060340200620012903a00b370000200641186a2007290300370000200641106a2002290300370000200641086a2009290300370000200641206a2106200a417f6a220a0d000b203a417f6a21130c030b1032000b20064101102c000b4100211320082106203a450d010b200620012903a00b370000200641186a200141a00b6a41186a290300370000200641106a200141a00b6a41106a290300370000200641086a200141a00b6a41086a290300370000201341016a21130b202a203c41306c6a21062021a72100410021270c010b102d000b024002400240024002400240034002402014450d002006202a460d02200641506a2206290300200641086a29030084500d0203402014417f6a2214450d01202a2006460d03200641506a210a200641506a2106200a290300200a41086a2903008450450d000c030b0b2006202a460d0102400340200641506a2207290300210d200741086a290300211f200141a8056a41186a2202200641606a220a41186a290300370300200141a8056a41106a2209200a41106a290300370300200141a8056a41086a220b200a41086a2903003703002001200a2903003703a805200d201f84500d01200141a00b6a41186a220a2002290300370300200141a00b6a41106a22022009290300370300200141a00b6a41086a2209200b290300370300200120012903a8053703a00b20014188056a200141a00b6a10c501200141f0086a41186a220b200a290300370300200141f0086a41106a220c2002290300370300200141f0086a41086a220f2009290300370300200120012903a00b3703f00802402001280288054101460d0020072106202a2007470d010c040b0b200141c0066a41086a220e200f290300370300200141c0066a41106a220f200c290300370300200141c0066a41186a220c200b290300370300200120012903f008220d3703d8072001200d3703c0062001280290052107200a200c2903003703002002200f2903003703002009200e290300370300200120012903c0063703a00b201320074d0d03200641506a2106200820074105746a220720012903a00b370000200741186a200a290300370000200741106a2002290300370000200741086a2009290300370000202741016a2127410021140c010b0b200141d8076a41086a200141880a6a41086a290300370300200141d8076a41106a200141880a6a41106a290300370300200141d8076a41186a200141880a6a41186a290300370300200120012903880a3703d8070b02402000450d00202a102e0b02402013203a203a20134b1b2209450d00203721062008210a41002107034002402006200a460d002006200a412010f804450d00411610292202450d04200241002900d7f8403700002002410e6a41002900e5f840370000200241086a41002900dff84037000020014296808080e0023702a40b200120023602a00b2006200141a00b6a104a20012802a40b210b20012802a80b210c20012802a00b2102200141c0046a41186a220f4200370300200141c0046a41106a22004200370300200141c0046a41086a220e4200370300200142003703c0042002200c200141c0046a1000200141f0086a41186a200f290300370300200141f0086a41106a2000290300370300200141f0086a41086a200e290300370300200120012903c0043703f008200141f0086a41201006200b450d002002102e0b200641206a2106200a41206a210a200741016a22072009490d000b0b200820134105746a21062013210b20134104490d02200141a00b6a41206a210c200141e00b6a210f200141a00b6a41e0006a2100200141a00c6a210e200141b80b6a2107200141b00b6a2102200141a80b6a21092006210a2013210b0340200742003703002002420037030020094200370300200142003703a00b0240200c200a460d00200a41606a200141a00b6a412010f804450d00200b417f6a210a0c050b200742003703002002420037030020094200370300200142003703a00b0240200f200a460d00200a41406a200141a00b6a412010f804450d00200b417e6a210a0c050b200742003703002002420037030020094200370300200142003703a00b02402000200a460d00200a41a07f6a200141a00b6a412010f804450d00200b417d6a210a0c050b200742003703002002420037030020094200370300200142003703a00b200a41807f6a210602400240200e200a460d002006200141a00b6a412010f8040d010b200b417c6a210b2006210a200620086b41e0004b0d010c040b0b200b417c6a210a0c030b41e4f9c000200720131038000b41164101102c000b20062008460d01200b417f6a210a200141a00b6a41206a2107200141b80b6a2102200141b00b6a2109200141a80b6a210b03402002420037030020094200370300200b4200370300200142003703a00b024020072006460d00200641606a200141a00b6a412010f8040d020b200a417f6a210a2008200641606a2206470d000c020b0b200a41016a22062013201320064b1b21130b200141bc0b6a2017360200200141b80b6a203d360200200141b40b6a203e360200200141a00b6a41106a2035360200200141ac0b6a202d360200200141083a00a00b200141a00b6a41086a2036360200200141033a00a40b41c8ecc5004100200141a00b6a1072200141f0086a41086a22064200370300200142003703f00841f4f9c0004112200141f0086a1003200141d8076a41086a2006290300370300200120012903f0083703d807200141003602a80b200142013703a00b2013200141a00b6a104702402013450d002013410574210a2008210603402006200141a00b6a104a200641206a2106200a41606a220a0d000b0b20012802a40b2106200141d8076a411020012802a00b220a20012802a80b100402402006450d00200a102e0b0240203a450d002008102e0b200141f0086a41086a22064200370300200142003703f00841f6d9c5004116200141f0086a1003200141d8076a41086a220a2006290300370300200120012903f0083703d807200120273602a00b200141d8076a4110200141a00b6a41041004200141bfd9c5004111107d200128020021072001280204210220064200370300200142003703f00841bfd9c5004111200141f0086a1003200a2006290300370300200120012903f0083703d8072001200241016a410120071b3602a00b200141d8076a4110200141a00b6a4104100402402038450d002037102e0b201da7450d00203b102e0b2011450d002018102e0b02402003450d00200341246c210a2005210603400240024020062d0000220741034b0d0002400240024020070e0404000102040b2006410c6a280200450d03200641086a280200102e0c030b2006410c6a280200450d02200641086a280200102e0c020b2006410c6a280200450d01200641086a280200102e0c010b200641086a280200450d00200641046a280200102e0b200641246a2106200a415c6a220a0d000b0b02402004450d002005102e0b200141c00c6a24000bef0e03047f027e077f230041206b2202240002400240024002400240024002400240024002400240024002400240024041a20210292203450d00200242a20237020420022003360200200341003b00002002410236020802400240200128020022032903684202520d0020022802002101024020022802044102470d00200141024104102a2201450d0420024104360204200220013602000b200141033a00022002200228020841016a3602080c010b20022802002101024020022802044102470d00200141024104102a2201450d0420024104360204200220013602000b20014183013a00022002200228020841016a360208200320021049200341246a200210e1020240024020032903684201510d0002400240200228020420022802082201460d00200228020021040c010b200141016a22042001490d1220014101742205200420042005491b22054100480d120240024020010d002005102921040c010b200228020020012005102a21040b2004450d072002200536020420022004360200200228020821010b2002200141016a360208200420016a41003a00000c010b200341f8006a29030020032903702206420c882207420120074201561b8021070240024020022802042204200228020822016b4102490d00200228020021040c010b200141026a22052001490d1120044101742201200520052001491b22014100480d110240024020040d002001102921040c010b200228020020042001102a21040b2004450d072002200136020420022004360200200228020821010b2002200141026a360208200420016a2007a741047420067aa7417f6a22014101200141014b1b2201410f2001410f491b723b00000b20034180016a20021066200220034188016a360210200241106a2002106b0b20034198016a200210bc012002280208210320024100360218200242013703102003417e6a200241106a10472002280208220841014d0d0520022802182105200228021421092002280210210a2002410036020820022802002103024002402008417e6a220b450d004102210c2005450d0d2003200a2d00003a0000410121042002200228020841016a36020820054101460d0d200a20056a210d2003200a2d00013a00012002200228020841016a3602084102210c200a41026a21012005417e6a220e0d014100210e0c0b0b0240024002402002280204220120054f0d0020014101742204200520052004491b22044100480d120240024020010d002004102921030c010b200320012004102a21030b2003450d0a20022004360204200220033602002002280208210c0c010b4100210c2005450d010b2003200c6a2201200a2d00003a0000024020054101470d00200c41016a210c0c010b2005417f6a2104200a41016a2103200141016a21010340200120032d00003a0000200141016a2101200341016a21032004417f6a22040d000b200c20056a210c0b2002200c3602084102210c0c0b0b024002402002280204220320086b200e490d00200228020021030c010b2008200e6a22042008490d0f2003410174220c20042004200c491b22044100480d0f0240024020030d002004102921030c010b200228020020032004102a21030b2003450d0820022004360204200220033602000b200320056a200341026a200b10f7041a0240200520022802082203460d00200520036b210c2005417e6a2104200228020020036a2108410021030340024020042003470d002005210c0c0d0b200820036a20012d00003a00002002200228020841016a360208200141016a2101200c200341016a2203470d000b200d20016b220e0d004100210e410121040c090b200e4100480d0e200e102922040d08200e4101102c000b41a2024101102c000b41044101102c000b41044101102c000b20054101102c000b20014101102c000b418cc6c5001058000b20044101102c000b20044101102c000b2005210c0b0240200d2001460d00200420012d00003a000002400240200141016a200d470d00410121050c010b200a200520016b6a2108200a200520016b6a2105410121030340200420036a200120036a2d00003a00002008200341016a2203470d000b2005450d010b200420056a21080240024020022802042203200b200c6a22016b2005490d00200228020021030c010b200120056a220d2001490d0620034101742201200d200d2001491b22014100480d060240024020030d002001102921030c010b200228020020032001102a21030b2003450d0520022001360204200220033602000b2003200c20056a220d6a2003200c6a200b10f7041a0240200d20022802082203460d00200228020020036a2101200c20056a20036b210520042103034020082003460d01200120032d00003a00002002200228020841016a360208200341016a2103200141016a21012005417f6a22050d000b0b200d210c0b200e450d002004102e0b200b450d010b0240200c20022802082203460d002002280200220120036a2001200c6a200b10f7041a0b2002200b20036a3602080b02402009450d00200a102e0b20002002290300370200200041086a200241086a280200360200200241206a24000f0b20014101102c000b102d000b9104010d7f230041206b2202240002400240024002400240200128020822030d0041012104410421054100210641002107410021080c010b2001280200220920034103746a210a41042105410021014100210641002103410021084101210403402009280200210b02400240200820036b200941046a220c2802002207490d00200720036a210d0c010b200320076a220d2003490d042008410174220e200d200d200e491b220e4100480d040240024020080d00200e102921040c010b20042008200e102a21040b2004450d05200e21080b200420036a200b200710f6041a200c28020021030240024020062001460d00200141016a21070c010b200141016a22072001490d0420014101742206200720072006491b220641ffffffff03712006470d042006410274220b4100480d040240024020010d00200b102921050c010b20052001410274200b102a21050b2005450d030b200520014102746a200336020020072101200d2103200941086a2209200a470d000b0b200241186a22014200370300200241106a22034200370300200241086a22094200370300200242003703002004200520072002101e200041186a2001290300370000200041106a2003290300370000200041086a20092903003700002000200229030037000002402006450d002005102e0b02402008450d002004102e0b200241206a24000f0b200b4104102c000b102d000b200e4101102c000b8e1505027f017e057f017e047f230041b0086b22042400200441b0056a200141a00210f6041a200441d0036a200441b0056a10b901410121050240024002400240024002400240024002400240024020042802d0034101460d00200441d0036a41086a290300210620044180026a200441d0036a41106a41d00110f6041a20042006370328200441286a41086a20044180026a41d00110f6041a024020032802002201450d00200341086a28020021072003280204210841002109200441003602b00541dff0c2004110200441b0056a10082105024020042802b005220a417f460d002005450d00200a4104490d05200528000021092005102e0b411410292205450d05200541106a4100280093e545360000200541086a410029008be54537000020054100290083e545370000200541144128102a2205450d0620052009360014200441d0036a41186a22094200370300200441d0036a41106a220a4200370300200441d0036a41086a220b4200370300200442003703d00320054118200441d0036a1000200441f0076a41186a2009290300370300200441f0076a41106a200a290300370300200441f0076a41086a200b290300370300200420042903d0033703f007200441203602b4052004200441f0076a3602b00520012007200441b0056a1099022005102e02402008450d002001102e0b410021050b200441206a200441286a41d0006a1094022004280220210820042d0024210a200441b0056a200441286a41d80110f6041a41002109024002400240024002400240024002400240024020042903d0054202510d0020044180026a41186a200441b0056a41186a29030037030020044180026a41106a200441b0056a41106a29030037030020044180026a41086a200441b0056a41086a290300370300200420042903b00537038002200441f8056a2903002106200441f0056a290300210c200441e8056a2802002107411310292209450d10200941002900eff3423700002009410f6a41002800fef342360000200941086a41002900f7f34237000020044293808080b0023702d403200420093602d00320044180026a200441d0036a104a20042802d403210b200441186a20042802d003220d20042802d80310c002200428021c410020042802181b21090240200b450d00200d102e0b20092007470d04411310292209450d11200a410171210a200941002900eff3423700002009410f6a41002800fef342360000200941086a41002900f7f34237000020044293808080b0023702d403200420093602d00320044180026a200441d0036a104a20042802d403210b20042802d803210d20042802d0032109200441d0036a41186a220e4200370300200441d0036a41106a220f4200370300200441d0036a41086a22104200370300200442003703d0032009200d200441d0036a1000200441f0076a41186a200e290300370300200441f0076a41106a200f290300370300200441f0076a41086a2010290300370300200420042903d0033703f0072004200741016a3602d003200441f0076a4120200441d0036a410410040240200b450d002009102e0b200441106a41d1e4c5004117107d417f2004280214410020042802101b220920026a220720072009491b2209418080c002418080f001200a1b4b0d02200441d0036a41086a22074200370300200442003703d00341d1e4c5004117200441d0036a1003200441f0076a41086a220e2007290300370300200420042903d0033703f007200420093602d003200441f0076a4110200441d0036a41041004200441086a41b7e4c500411a107d417f200428020c410020042802081b220b418094ebdc034180afd0e502200a1b2209200820092008491b6a220d200d200b491b220b20094b0d0220074200370300200442003703d00341b7e4c500411a200441d0036a1003200e2007290300370300200420042903d0033703f0072004200b3602d003200441f0076a4110200441d0036a41041004200441d0036a200c200620044180026a2008200a200210850120042d00d0034101460d01200441fc036a2802002107200441f8036a280200210b200441f4036a2802002108200441ec036a280200210d200441e8036a280200210a0240200441f0036a2802002209450d002009410c6c2102200a210903400240200941046a280200450d002009280200102e0b2009410c6a2109200241746a22020d000b0b0240200d450d00200a102e0b02402007450d002007410c6c21022008210903400240200941046a280200450d002009280200102e0b2009410c6a2109200241746a22020d000b0b0240200b450d002008102e0b20044190086a41086a20044180026a41086a29030037030020044190086a41106a20044180026a41106a29030037030020044190086a41186a20044180026a41186a290300370300200420042903800237039008410121090b200441d0076a41186a220a20044190086a41186a2202290300370300200441d0076a41106a220b20044190086a41106a2207290300370300200441d0076a41086a220d20044190086a41086a220829030037030020042004290390083703d007200441d0036a200441b0056a41d0006a41880110f6041a2002200a2903003703002007200b2903003703002008200d290300370300200420042903d007370390084102210a02402009450d00200441f0076a41186a2002290300370300200441f0076a41106a2007290300370300200441f0076a41086a200829030037030020042004290390083703f0074101210a0b2004418a026a200441f0076a41086a29030037010020044192026a200441f0076a41106a2903003701002004419a026a200441f0076a41186a2903003701002004200a3a008102200420042903f00737018202200441003a0080022004200441d0036a20044180026a109502200428020421022004200428020022094100473a00b105200441003a00b00541c8ecc5004100200441b0056a1072200441003602b00541dff0c2004110200441b0056a1008210720042802b0052208417f470d07410121070c080b20042d00d103210220044180066a102f41032109024020020e0706020606040500060b410021090c050b20044180066a102f0b410421090c030b20044180066a102f200920074d0d010b410121090c010b410221090b20002009360204200041013602002000410c6a4100360200200041086a41c8ecc50036020020054521000c030b024020070d00410121070c010b20084104490d09200728000021082007102e200841016a21070b200420073602b00541dff0c2004110200441b0056a410410040240024020090d004100210920004100360204200041086a20023602000c010b02402002411b470d0002402009418de3c300460d002009418de3c300411b10f8040d010b20004104360204410121090c010b20002009360204200041086a2002360200410021090b200020093602002001450d0a20050d020c0a0b200041086a20042902d4033702002000420137020020032802002101410021000b20000d0820010d070c080b200341046a280200450d072001102e0c070b41eff0c200413320044180026a4184f4c2001053000b41144101102c000b41284101102c000b41134101102c000b41134101102c000b41eff0c200413320044180026a4184f4c2001053000b200341046a280200450d002001102e0b200441b0086a24000bcb0101047f230041306b22002400410021012000410036021841dff0c2004110200041186a100821020240024020002802182203417f460d002002450d0020034104490d01200228000021012002102e41dff0c200411010060b200041186a41086a220242003703002000420037031841a2e4c5004115200041186a1003200041086a41086a20022903003703002000200029031837030820002001360218200041086a4110200041186a41041004200041306a24000f0b41eff0c2004133200041286a4184f4c2001053000bad1604057f037e067f017e230041a0026b22012400200141b8016a41086a22024200370300200142003703b80141a2e4c5004115200141b8016a1003200141e0016a41086a22032002290300370300200120012903b8013703e001200141e0016a41101006200141306a41b7e4c500411a107d200128023421042001280230210520024200370300200142003703b80141e8e4c500411b200141b8016a1003200141106a4180e59af7002004410020051b220420044180e59af7004922051b20044180e59af70020051b6b2205ad220642002006420010fb0420032002290300370300200120012903b8013703e001200642a8c30180210742ffffffffffffffffff00428080808080808080807f20051b2001290310220620012903182006423f87521b42808090bbbad6adf00d7f2108200141206a200141e0016a1086012001290328420020012802201b210602400240200441ffe49af7004b0d0042ffffffffffffffffff00428080808080808080807f2006200720087d22087d22074200531b20072006427f5522022008427f554720022007427f5547711b22064280ec94a37c20064280ec94a37c551b21060c010b42ffffffffffffffffff00428080808080808080807f2006200720087c22087c22074200531b20072006427f5522022008427f554620022007427f5547711b21060b200141b8016a41086a22024200370300200142003703b80141e8e4c500411b200141b8016a1003200141e0016a41086a22042002290300370300200120012903b8013703e001200120063703b801200141e0016a4110200141b8016a4108100420024200370300200142003703b80141b7e4c500411a200141b8016a100320042002290300370300200120012903b8013703e001200141e0016a4110100620024200370300200142003703b80141d1e4c5004117200141b8016a100320042002290300370300200120012903b8013703e001200141e0016a4110100620024200370300200142003703b80141b0f3c200410d200141b8016a100320042002290300370300200120012903b8013703e001200141086a200141e0016a4110109a01200128020c21032001280208210520024200370300200142003703b801418cf5c2004111200141b8016a100320042002290300370300200120012903b8013703e001200141b8016a200141e0016a411010dc010240024020012d00b8014101470d00200141e0016a4110100620014180026a41186a200141d1016a290000220637030020014180026a41106a200141b8016a41116a290000220737030020014180026a41086a200141c1016a2900002208370300200141386a41086a2008370300200141386a41106a2007370300200141386a41186a2006370300200120012900b901220637038002200120063703380c010b20014180026a41186a200141d1016a29000037030020014180026a41106a200141b8016a41116a29000037030020014180026a41086a200141c1016a290000370300200141386a41086a4200370300200141386a41106a4200370300200141386a41186a4200370300200120012900b90137038002200142003703380b200141b8016a41086a22024200370300200142003703b80141d2f3c200410d200141b8016a1003200141e0016a41086a2002290300370300200120012903b8013703e001200141003602b801200141e0016a4110200141b8016a10082102024002400240024002400240024020012802b8012204417f460d002002450d0020012004360284022001200236028002200141b8016a20014180026a103f20012802b8012209450d0220012902bc01210602402004450d002002102e0b200141e0016a411010062006422088a721022006a7210a0c010b41042109410021024100210a0b2003410020051b210b200141b8016a41086a22044200370300200142003703b80141bdf3c2004115200141b8016a1003200141e0016a41086a2004290300370300200120012903b8013703e001200141b8016a200141e0016a411010dc010240024020012d00b8014101470d00200141e0016a4110100620014180026a41186a200141d1016a290000220637030020014180026a41106a200141c9016a290000220737030020014180026a41086a200141c1016a2900002208370300200141d8006a41086a2008370300200141d8006a41106a2007370300200141d8006a41186a2006370300200120012900b901220637038002200120063703580c010b20014180026a41186a200141d1016a29000037030020014180026a41106a200141c9016a29000037030020014180026a41086a200141c1016a290000370300200141d8006a41086a4200370300200141d8006a41106a4200370300200141d8006a41186a4200370300200120012900b90137038002200142003703580b0240200b41fb01490d00200b41857e6a2203450d00411010292204450d02200441086a41002900e7f342370000200441002900dff342370000200441104120102a2204450d0320042003360010200141e0016a41186a22034200370300200141e0016a41106a22054200370300200141e0016a41086a220c4200370300200142003703e00120044114200141e0016a1000200141b8016a41186a2003290300370300200141b8016a41106a2005290300370300200141b8016a41086a200c290300370300200120012903e0013703b801200141b8016a412010062004102e0b200141e0016a41186a22044200370300200141e0016a41106a22034200370300200141e0016a41086a22054200370300200142003703e001200141e0016a101f200141f8006a41186a2004290300370300200141f8006a41106a2003290300370300200141f8006a41086a2005290300370300200120012903e001370378200141b8016a41186a220c200141386a41186a290300370300200141b8016a41106a220d200141386a41106a290300370300200141b8016a41086a220e200141386a41086a290300370300200120012903383703b801200442003703002003420037030020054200370300200142003703e0010240200141b8016a4120200141e0016a1020450d0020014198016a41086a2005290300220637030020014198016a41106a2003290300220737030020014198016a41186a20042903002208370300200120012903e001220f37039801200e2006370300200d2007370300200c20083703002001200f3703b80102402002200a470d00200241016a22042002490d0620024101742203200420042003491b220aad42247e2206422088a70d062006a722044100480d060240024020020d002004102921090c010b2009200241246c2004102a21090b2009450d050b2009200241246c6a220441003a0000200420012903b801370001200441096a200141c0016a290300370000200441116a200141c8016a290300370000200441196a200141d0016a290300370000200420012f0080023b0021200441236a20014182026a2d00003a0000200241016a21020b200020012903383700102000200b36020020002001290378370030200041286a200141386a41186a290300370000200041206a200141386a41106a290300370000200041186a200141386a41086a290300370000200041386a200141f8006a41086a290300370000200041c0006a200141f8006a41106a290300370000200041c8006a200141f8006a41186a2903003700002000410c6a2002360200200041086a200a36020020002009360204200041e8006a200141d8006a41186a290300370000200041e0006a200141d8006a41106a290300370000200041d8006a200141d8006a41086a29030037000020002001290358370050200141a0026a24000f0b41eff0c2004133200141b8016a4184f4c2001053000b41104101102c000b41204101102c000b20044104102c000b102d000ba40301027f23004180026b22022400024002402001450d00200220003602000c010b200241c8ecc5003602000b20022001360204200241f8006a2002103c0240200228027c450d00200241086a200241f8006a41f00010f6041a200241086a10ab020240200241086a410c6a2802002200450d00200228020c2101200041246c210003400240024020012d0000220341034b0d0002400240024020030e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b0240200241106a280200450d00200228020c102e0b20024180026a240042010f0b200241f4016a411c3602002002411c6a41023602002002420237020c200241d4f1c1003602082002411c3602ec01200241e0f2c1003602e801200241003602fc01200241c8ecc5003602f8012002200241e8016a3602182002200241f8016a3602f001200241086a41e4f1c100106a000bcc28010b7f230041d0006b220224002002410036022820024201370320024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240410410292203450d0020024284808080c00037022420022003360220200341edcad18b0636000002400240200228022420022802282203460d00200228022021040c010b200341016a22042003490d1b20034101742205200420042005491b22054100480d1b0240024020030d002005102921040c010b200228022020032005102a21040b2004450d0220022005360224200220043602200b2002200341016a360228200420036a41073a00004113200241206a10474180dcc100210603402006280204210720062802082203200241206a10470240024020022802242205200228022822046b2003490d00200228022021050c010b200420036a22082004490d1c20054101742204200820082004491b22044100480d1c0240024020050d002004102921050c010b200228022020052004102a21050b2005450d042002200436022420022005360220200228022821040b2002200420036a360228200520046a2007200310f6041a200228022421042002280228210302400240200628020c4102470d000240024020042003460d00200228022021040c010b200341016a22042003490d1e20034101742205200420042005491b22054100480d1e0240024020030d002005102921040c010b200228022020032005102a21040b2004450d072002200536022420022004360220200228022821030b2002200341016a360228200420036a41003a00000c010b0240024020042003460d00200228022021040c010b200341016a22042003490d1d20034101742205200420042005491b22054100480d1d0240024020030d002005102921040c010b200228022020032005102a21040b2004450d072002200536022420022004360220200228022821030b2002200341016a360228200420036a41013a00000240200628020c4101460d00200241306a20062802101101002002280234210720022802382203200241206a10470240024020022802242205200228022822046b2003490d00200228022021050c010b200420036a22082004490d1e20054101742204200820082004491b22044100480d1e0240024020050d002004102921050c010b200228022020052004102a21050b2005450d092002200436022420022005360220200228022821040b2002200420036a360228200520046a2007200310f6041a200228024021050240200228023c4101460d0020052002280244200241206a10b3020c020b200520022802482203200241206a10b30202402003450d00200341d8006c21074100210403400240200520046a220341346a280200450d002003413c6a280200450d00200341386a280200102e0b0240200341c4006a280200450d00200341cc006a280200450d00200341c8006a280200102e0b2007200441d8006a2204470d000b0b2002280244450d012005102e0c010b2006280214210720062802182203200241206a10470240024020022802242205200228022822046b2003490d00200228022021050c010b200420036a22082004490d1d20054101742204200820082004491b22044100480d1d0240024020050d002004102921050c010b200228022020052004102a21050b2005450d092002200436022420022005360220200228022821040b2002200420036a360228200520046a2007200310f6041a200628022021030240200628021c4101460d002003200641246a280200200241206a10b3020c010b20032006280228200241206a10b3020b200228022421042002280228210302400240200628022c4102470d000240024020042003460d00200228022021040c010b200341016a22042003490d1e20034101742205200420042005491b22054100480d1e0240024020030d002005102921040c010b200228022020032005102a21040b2004450d0b2002200536022420022004360220200228022821030b2002200341016a360228200420036a41003a00000c010b0240024020042003460d00200228022021040c010b200341016a22042003490d1d20034101742205200420042005491b22054100480d1d0240024020030d002005102921040c010b200228022020032005102a21040b2004450d0b2002200536022420022004360220200228022821030b2002200341016a360228200420036a41013a00000240200628022c4101460d00200241186a200628023011010020022802182104200228021c2203200241206a10472003450d012003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a10470240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d1f20074101742205200a200a2005491b22054100480d1f0240024020070d002005102921070c010b200228022020072005102a21070b2007450d0e2002200536022420022007360220200228022821050b2002200520046a360228200720056a2009200410f6041a200341706a200241206a10b4022003200241206a10b5022003412c6a2103200841546a22080d000c020b0b2006280230210420062802382203200241206a10472003450d002003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a10470240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d1e20074101742205200a200a2005491b22054100480d1e0240024020070d002005102921070c010b200228022020072005102a21070b2007450d0e2002200536022420022007360220200228022821050b2002200520046a360228200720056a2009200410f6041a200341706a200241206a10b4022003200241206a10b5022003412c6a2103200841546a22080d000b0b200228022421042002280228210302400240200628023c4102470d000240024020042003460d00200228022021040c010b200341016a22042003490d1e20034101742205200420042005491b22054100480d1e0240024020030d002005102921040c010b200228022020032005102a21040b2004450d0f2002200536022420022004360220200228022821030b2002200341016a360228200420036a41003a00000c010b0240024020042003460d00200228022021040c010b200341016a22042003490d1d20034101742205200420042005491b22054100480d1d0240024020030d002005102921040c010b200228022020032005102a21040b2004450d0f2002200536022420022004360220200228022821030b2002200341016a360228200420036a41013a00000240200628023c4101460d00200241106a20062802401101002002280210210420022802142203200241206a10472003450d012003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a10470240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d1f20074101742205200a200a2005491b22054100480d1f0240024020070d002005102921070c010b200228022020072005102a21070b2007450d122002200536022420022007360220200228022821050b2002200520046a360228200720056a2009200410f6041a200341706a200241206a10b5022003200241206a10b5022003412c6a2103200841546a22080d000c020b0b2006280240210420062802482203200241206a10472003450d002003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a10470240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d1e20074101742205200a200a2005491b22054100480d1e0240024020070d002005102921070c010b200228022020072005102a21070b2007450d122002200536022420022007360220200228022821050b2002200520046a360228200720056a2009200410f6041a200341706a200241206a10b5022003200241206a10b5022003412c6a2103200841546a22080d000b0b02400240200628024c4101460d00200241086a20062802501101002002280208210b200228020c2203200241206a10472003450d01200341386c210c410021070340200b20076a220341046a2802002109200341086a2802002204200241206a10470240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1f20084101742205200a200a2005491b22054100480d1f0240024020080d002005102921080c010b200228022020082005102a21080b2008450d142002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410f6041a200341106a2802002109200341146a2802002204200241206a10470240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1f20084101742205200a200a2005491b22054100480d1f0240024020080d002005102921080c010b200228022020082005102a21080b2008450d152002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410f6041a02400240200341186a2802004101460d00200241306a2003411c6a280200200341206a28020028020c1100002002280230210920022802382204200241206a10470240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2120084101742205200a200a2005491b22054100480d210240024020080d002005102921080c010b200228022020082005102a21080b2008450d182002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410f6041a2002280234450d012009102e0c010b2003411c6a2802002109200341246a2802002204200241206a10470240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2020084101742205200a200a2005491b22054100480d200240024020080d002005102921080c010b200228022020082005102a21080b2008450d182002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410f6041a0b200341286a200241206a10b502200c200741386a2207470d000c020b0b2006280250210b20062802582203200241206a10472003450d00200341386c210c410021070340200b20076a220341046a2802002109200341086a2802002204200241206a10470240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1e20084101742205200a200a2005491b22054100480d1e0240024020080d002005102921080c010b200228022020082005102a21080b2008450d172002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410f6041a200341106a2802002109200341146a2802002204200241206a10470240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1e20084101742205200a200a2005491b22054100480d1e0240024020080d002005102921080c010b200228022020082005102a21080b2008450d182002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410f6041a02400240200341186a2802004101460d00200241306a2003411c6a280200200341206a28020028020c1100002002280230210920022802382204200241206a10470240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2020084101742205200a200a2005491b22054100480d200240024020080d002005102921080c010b200228022020082005102a21080b2008450d1b2002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410f6041a2002280234450d012009102e0c010b2003411c6a2802002109200341246a2802002204200241206a10470240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1f20084101742205200a200a2005491b22054100480d1f0240024020080d002005102921080c010b200228022020082005102a21080b2008450d1b2002200536022420022008360220200228022821050b2002200520046a360228200820056a2009200410f6041a0b200341286a200241206a10b502200c200741386a2207470d000b0b200641dc006a220641d4e9c100470d000b2002280228220341046a2204417f4c0d1720022802242108200228022021070240024020040d00410121050c010b200410292205450d190b2002410036023820022004360234200220053602302003200241306a10470240024020022802342205200228023822046b2003490d00200228023021050c010b200420036a22092004490d1b2005410174220a20092009200a491b22094100480d1b0240024020050d002009102921050c010b200228023020052009102a21050b2005450d1a20022009360234200220053602300b200520046a2007200310f6041a200420036a210302402008450d002007102e0b200241d0006a24002003ad4220862005ad840f0b41044101102c000b20054101102c000b20044101102c000b20054101102c000b20054101102c000b20044101102c000b20044101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b20054101102c000b1032000b20044101102c000b20094101102c000b102d000b921d010a7f230041106b22032400200120021047024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001450d00200141d8006c2104410021050340200020056a220641046a2802002107200641086a28020022082002104702400240200241046a2209280200220a200241086a2201280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d18200a410174220b200c200c200b491b220b4100480d1802400240200a0d00200b1029210a0c010b2002280200200a200b102a210a0b200a450d032002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810f6041a200641d4006a2d0000210a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1820084101742207200b200b2007491b22074100480d180240024020080d0020071029210b0c010b200228020020082007102a210b0b200b450d042002200b36020020092007360200200128020021080b2001200841016a360200200b20086a200a3a000002402006410c6a2d0000220841024b0d0002400240024020080e03000102000b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1b2008410174220a200b200b200a491b220a4100480d1b0240024020080d00200a1029210b0c010b20022802002008200a102a210b0b200b450d082002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41003a0000200641146a2802002107200641186a280200220820021047024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1b200a410174220b200c200c200b491b220b4100480d1b02400240200a0d00200b1029210a0c010b2002280200200a200b102a210a0b200a450d092002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810f6041a0c020b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a2008410174220a200b200b200a491b220a4100480d1a0240024020080d00200a1029210b0c010b20022802002008200a102a210b0b200b450d092002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41013a00002006410d6a2d0000210a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a20084101742207200b200b2007491b22074100480d1a0240024020080d0020071029210b0c010b200228020020082007102a210b0b200b450d0a2002200b36020020092007360200200128020021080b2001200841016a360200200b20086a200a3a0000200641146a2802002107200641186a280200220820021047024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1a200a410174220b200c200c200b491b220b4100480d1a02400240200a0d00200b1029210a0c010b2002280200200a200b102a210a0b200a450d0b2002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810f6041a200641206a2802002107200641246a280200220820021047024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1a200a410174220b200c200c200b491b220b4100480d1a02400240200a0d00200b1029210a0c010b2002280200200a200b102a210a0b200a450d0c2002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810f6041a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a2008410174220a200b200b200a491b220a4100480d1a0240024020080d00200a1029210b0c010b20022802002008200a102a210b0b200b450d0d2002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a2006410e6a2d00003a00000c010b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d192008410174220a200b200b200a491b220a4100480d190240024020080d00200a1029210b0c010b20022802002008200a102a210b0b200b450d0d2002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41023a00002006410d6a2d0000210a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1920084101742207200b200b2007491b22074100480d190240024020080d0020071029210b0c010b200228020020082007102a210b0b200b450d0e2002200b36020020092007360200200128020021080b2001200841016a360200200b20086a200a3a0000200641146a2802002107200641186a280200220820021047024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200c200b491b220b4100480d1902400240200a0d00200b1029210a0c010b2002280200200a200b102a210a0b200a450d0f2002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810f6041a200641206a2802002107200641246a280200220820021047024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200c200b491b220b4100480d1902400240200a0d00200b1029210a0c010b2002280200200a200b102a210a0b200a450d102002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810f6041a2006412c6a2802002107200641306a280200220820021047024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200c200b491b220b4100480d1902400240200a0d00200b1029210a0c010b2002280200200a200b102a210a0b200a450d112002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810f6041a2006410e6a2d0000220841044b0d000240024002400240024020080e050001020304000b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1d2008410174220a200b200b200a491b220a4100480d1d0240024020080d00200a1029210b0c010b20022802002008200a102a210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41003a00000c040b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1c2008410174220a200b200b200a491b220a4100480d1c0240024020080d00200a1029210b0c010b20022802002008200a102a210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41013a00000c030b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1b2008410174220a200b200b200a491b220a4100480d1b0240024020080d00200a1029210b0c010b20022802002008200a102a210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41023a00000c020b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a2008410174220a200b200b200a491b220a4100480d1a0240024020080d00200a1029210b0c010b20022802002008200a102a210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41033a00000c010b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d192008410174220a200b200b200a491b220a4100480d190240024020080d00200a1029210b0c010b20022802002008200a102a210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41043a00000b02400240200641346a2802004101460d002003200641386a2802002006413c6a28020028020c110000200328020021072003280208220820021047024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1a200a410174220b200c200c200b491b220b4100480d1a02400240200a0d00200b1029210a0c010b2002280200200a200b102a210a0b200a450d182002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810f6041a2003280204450d012007102e0c010b200641386a2802002107200641c0006a280200220820021047024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200c200b491b220b4100480d1902400240200a0d00200b1029210a0c010b2002280200200a200b102a210a0b200a450d182002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a2007200810f6041a0b200641c4006a200210b5022004200541d8006a2205470d000b0b200341106a24000f0b200b4101102c000b20074101102c000b200a4101102c000b200b4101102c000b200a4101102c000b20074101102c000b200b4101102c000b200b4101102c000b200a4101102c000b200a4101102c000b20074101102c000b200b4101102c000b200b4101102c000b200b4101102c000b200a4101102c000b200a4101102c000b200a4101102c000b200a4101102c000b200a4101102c000b200b4101102c000b200b4101102c000b102d000bfe0601087f20002802042102024002400240024002400240024020002802004101460d00200041086a2802002200200110472000450d01200041186c2103200241146a2100200141086a2102200141046a21040340200041706a2802002105200041746a2802002206200110470240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d0820074101742208200920092008491b22084100480d080240024020070d002008102921070c010b200128020020072008102a21070b2007450d042001200736020020042008360200200228020021080b2002200820066a360200200720086a2005200610f6041a2000417c6a280200210520002802002206200110470240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d0820074101742208200920092008491b22084100480d080240024020070d002008102921070c010b200128020020072008102a21070b2007450d052001200736020020042008360200200228020021080b2002200820066a360200200720086a2005200610f6041a200041186a2100200341686a22030d000c020b0b2000410c6a2802002200200110472000450d00200041186c2103200241146a2100200141086a2102200141046a21040340200041706a2802002105200041746a2802002206200110470240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d0720074101742208200920092008491b22084100480d070240024020070d002008102921070c010b200128020020072008102a21070b2007450d052001200736020020042008360200200228020021080b2002200820066a360200200720086a2005200610f6041a2000417c6a280200210520002802002206200110470240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d0720074101742208200920092008491b22084100480d070240024020070d002008102921070c010b200128020020072008102a21070b2007450d062001200736020020042008360200200228020021080b2002200820066a360200200720086a2005200610f6041a200041186a2100200341686a22030d000b0b0f0b20084101102c000b20084101102c000b20084101102c000b20084101102c000b102d000b800401087f200028020421020240024002400240024020002802004101460d00200041086a28020022002001104720004103742200450d01200220006a2103200141086a2104034020022802002105200241046a28020022002001104702400240200141046a22062802002207200428020022086b2000490d00200128020021070c010b200820006a22092008490d0620074101742208200920092008491b22084100480d060240024020070d002008102921070c010b200128020020072008102a21070b2007450d042001200736020020062008360200200428020021080b2004200820006a360200200720086a2005200010f6041a200241086a22022003470d000c020b0b2000410c6a28020022002001104720004103742200450d00200220006a2103200141086a2104034020022802002105200241046a28020022002001104702400240200141046a22062802002207200428020022086b2000490d00200128020021070c010b200820006a22092008490d0520074101742208200920092008491b22084100480d050240024020070d002008102921070c010b200128020020072008102a21070b2007450d042001200736020020062008360200200428020021080b2004200820006a360200200720086a2005200010f6041a200241086a22022003470d000b0b0f0b20084101102c000b20084101102c000b102d000bd10301027f230041a0076b22022400024002402001450d00200220003602080c010b200241c8ecc5003602080b2002200136020c200241f0046a200241086a10b70102400240024020022903d8054203510d00200241106a200241f0046a41a00210f6041a200241b0026a200241106a41a00210f6041a2002200241b0026a3602f004200241d0046a200241f0046a10ac0220022802d8042101200241f0046a200241b0026a41a00210f6041a20024198076a20022802d804360200200220022903d00437039007200241e0046a200241f0046a200120024190076a10ae02410121000240024020022802e0044101460d004100210020022802e40441004721030c010b4280828898f01f20022802e404410374ad88a721030b410110292201450d01200120003a0000200141014102102a2201450d02200120033a0001200241a0076a24002001ad428080808020840f0b2002411c6a411c360200200241c4026a4102360200200242023702b402200241d4f1c1003602b0022002411c360214200241f8f2c100360210200241003602e404200241c8ecc5003602e0042002200241106a3602c0022002200241e0046a360218200241b0026a41e4f1c100106a000b41014101102c000b41024101102c000ba70d04067f017e087f017e230041d0016b2202240010af02200241186a41b0f3c200410d107d41002103200228021c410020022802181b109501200241106a41a2e4c5004115107d410421040240024002400240024002400240024002402002280214410020022802101b22050d004104210641042107410021050c010b2005ad420c7e2208422088a70d062008a722094100480d06200910292206450d072006210a4100210b0340411410292209450d02200941106a4100280093e545360000200941086a410029008be54537000020094100290083e545370000200941144128102a2209450d032009200b360014200241206a41186a220c4200370300200241206a41106a220d4200370300200241206a41086a220742003703002002420037032020094118200241206a1000200241a0016a41186a200c290300370300200241a0016a41106a200d290300370300200241a0016a41086a2007290300370300200220022903203703a00120024100360220200241a0016a4120200241206a10082107024002402002280220220e417f460d002007450d002002200e36022420022007360220200241086a200241206a103102400240024020022802080d002002280224220f200228020c220d490d00200d417f4c0d0902400240200d0d004101210c0c010b200d1034220c450d02200c20022802202210200d10f6041a2002200f200d6b36022420022010200d6a3602200b200c0d020b41eff0c2004133200241c0016a4184f4c2001053000b200d4101102c000b200dad220842208621110240200e450d002007102e0b20112008842108200241a0016a412010060c010b4101210c420021080b2009102e200a41046a2008370200200a200c360200200a410c6a210a2005200b41016a220b470d000b200621070b02402005410c6c2209450d002009410c6e2203410374220a4100480d06200a10292204450d040b4100210b02402006200620096a220d460d00200421092006210a0340200a280200210c200941046a200a41086a2802003602002009200c360200200941086a2109200b41016a210b200a410c6a220a200d470d000b0b2002200b3602282002200336022420022004360220200241a0016a200241206a10ad0202402003450d002004102e0b02402005450d002005410c6c210903400240200641046a280200450d002006280200102e0b2006410c6a2106200941746a22090d000b2005450d002007102e0b200241206a41186a200241a0016a41186a290300370300200241206a41106a2209200241a0016a41106a290300370300200241206a41086a200241a0016a41086a290300370300200220022903a001370320200241c0016a41086a220a4200370300200242003703c00141bdf3c2004115200241c0016a100320024190016a41086a200a290300370300200220022903c00137039001200241103602c401200220024190016a3602c001200241206a200241c0016a10b802200241206a10b002200241003602c801200242013703c0012009200241c0016a1046200241206a200241c0016a1066200241d0006a200241c0016a1046200241f0006a200241c0016a10462002280224210b2002412c6a2802002209200241c0016a10470240024020090d0020022802c801210a20022802c00121060c010b200941246c210e20022802c401210d20022802c80121090340200241a0016a200b104520022802a001210702400240200d20096b20022802a801220c490d002009200c6a210a20022802c00121060c010b2009200c6a220a2009490d08200d4101742206200a200a2006491b22054100480d0802400240200d0d002005102921060c010b20022802c001200d2005102a21060b2006450d07200220053602c401200220063602c0012005210d0b2002200a3602c801200620096a2007200c10f6041a024020022802a401450d002007102e0b200b41246a210b200a2109200e415c6a220e0d000b0b0240200228022c220b450d0020022802242109200b41246c210b03400240024020092d0000220c41034b0d00024002400240200c0e0404000102040b2009410c6a280200450d03200941086a280200102e0c030b2009410c6a280200450d02200941086a280200102e0c020b2009410c6a280200450d01200941086a280200102e0c010b200941086a280200450d00200941046a280200102e0b200941246a2109200b415c6a220b0d000b0b0240200241286a280200450d002002280224102e0b200241d0016a2400200aad4220862006ad840f0b41144101102c000b41284101102c000b1032000b200a4104102c000b20054101102c000b102d000b20094104102c000bdf0301017f024002400240024002400240410110292202450d00200220002d00003a0000200241014102102a2202450d01200220002d00013a0001200241024104102a2202450d02200220002d00023a0002200220002d00033a0003200241044108102a2202450d03200220002d00043a0004200220002d00053a0005200220002d00063a0006200220002d00073a0007200241084110102a2202450d04200220002d00083a0008200220002d00093a0009200220002d000a3a000a200220002d000b3a000b200220002d000c3a000c200220002d000d3a000d200220002d000e3a000e200220002d000f3a000f200241104120102a2202450d05200220002d00103a0010200220002d00113a0011200220002d00123a0012200220002d00133a0013200220002d00143a0014200220002d00153a0015200220002d00163a0016200220002d00173a0017200220002d00183a0018200220002d00193a0019200220002d001a3a001a200220002d001b3a001b200220002d001c3a001c200220002d001d3a001d200220002d001e3a001e200220002d001f3a001f200128020020012802042002412010042002102e0f0b41014101102c000b41024101102c000b41044101102c000b41084101102c000b41104101102c000b41204101102c000bc12605017f027e107f027e047f230041d0036b22022400024002402001450d00200220003602200c010b200241c8ecc5003602200b20022001360224200241386a200241206a10e4010240024020022802382201450d002002200229023c37022c20022001360228200241386a200241286a10ba02024020022802384101470d002002200229023c3703a0024186c5c2004128200241a0026a4198c2c2001053000b200241386a41086a2903002103200241106a41c5c1c200410d108101200229031821042002280210210141a002102922050d0141a0024108102c000b200241cc006a4102360200200241ac026a411c3602002002420237023c200241d4f1c1003602382002411c3602a40220024190f3c1003602a002200241003602bc01200241c8ecc5003602b8012002200241a0026a3602482002200241b8016a3602a802200241386a41e4f1c100106a000b2005200241a0026a41e80010f60422064202370368200641023a009801200620022903b801370370200641f8006a200241b8016a41086a29030037030020064180016a200241c8016a29030037030020064188016a200241d0016a29030037030020064190016a200241d8016a290300370300200620022800b003360099012006419c016a200241b0036a41036a28000036000020062003200442b8177c42b81720011b220420042003541b3703a001200641a8016a200241386a41f80010f6041a200241286a2101200228022c2107024002400240024003402001280200220841086a210020082f0106220941037421014100210a0240024003402001450d0141fb9bc2002000410810f804220b450d02200141786a2101200a41016a210a200041086a2100200b417f4a0d000b200a417f6a21090b2007450d022007417f6a2107200820094102746a41e4016a21010c010b0b20022008200a410c6c6a220141e8006a2802003602a4022002200141e0006a2802003602a002200241386a200241a0026a103b2002280238220c450d00200228023c210d02400240200241386a41086a22012802002209450d00200241a0026a41086a22004200370300200242003703a002419893c2004111200241a0026a100320012000290300370300200220022903a002370338200241003602a002200241386a4110200241a0026a1008210102400240024020022802a0022200417f460d002001450d00200220003602bc01200220013602b801200241a0026a200241b8016a103d20022802a0022207450d02200241a8026a280200210e20022802a402210f2000450d012001102e0c010b4100210f410421074100210e0b2007200e41c4006c22016a210002400240024002400240024020010d00200721010c010b4100210102400340200720016a220a2d0000210b200241386a200a41016a41c30010f6041a200b4102460d01200241b8016a41186a200241386a41186a290000370300200241b8016a41106a200241386a41106a290000370300200241b8016a41086a200241386a41086a290000370300200220022900383703b801200b4101460d03200141c4006a2101200a41c4006a2000470d000b200021010c010b200a41c4006a21010b0240034020002001460d0120012d0000210a200141c4006a2101200a4102470d000b0b41012108410021100240200f0d00410021110c020b2007102e410021110c010b200241a0026a41086a220b200241b8016a41086a290300370300200241a0026a41106a2212200241b8016a41106a290300370300200241a0026a41186a2210200241b8016a41186a290300370300200220022903b801220337039003200220033703a002412010292208450d02200820022903a002370000200841186a2010290300370000200841106a2012290300370000200841086a200b29030037000002400240200e41c4006c41bc7f6a2001470d0041012110410121110c010b200a41c4006a210a200e41c4006c20076a41bc7f6a211341012110410121110340200a21010240034020012d0000210a200241386a200141016a41c30010f6041a200a4102460d01200241b8016a41186a220b200241386a41186a290000370300200241b8016a41106a2212200241386a41106a290000370300200241b8016a41086a2214200241386a41086a290000370300200220022900383703b8010240200a4101460d00200141c4006a22012000470d010c040b0b200241a0026a41086a20142903002203370300200241a0026a41106a20122903002204370300200241a0026a41186a200b2903002215370300200220022903b80122163703a00220024190036a41186a2212201537030020024190036a41106a2214200437030020024190036a41086a221720033703002002201637039003024020112010470d00201041016a220a2010490d0d2010410174220b200a200a200b491b221141ffffff3f712011470d0d2011410574220a4100480d0d0240024020100d00200a102921080c010b20082010410574200a102a21080b2008450d050b200141c4006a210a200820104105746a220b200229039003370000200b41186a2012290300370000200b41106a2014290300370000200b41086a2017290300370000201041016a211020132001470d010c020b0b200141c4006a21000b2007200e41c4006c6a210a02400340200a2000460d0120002d00002101200041c4006a210020014102470d000b0b200f450d002007102e0b200c200941f0006c6a2109200241a0026a41106a2118200241a0026a41086a210f4200210341042119200c210b02400340200b2802042101200b2802002100200241386a200b41086a41e80010f6041a200b41f0006a210b024020010d00200b2009460d070340200b2802042207450d08200b41086a280200210e0240200b410c6a2802002201450d00200141246c21002007210103400240024020012d0000220a41034b0d00024002400240200a0e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b200b41f0006a210b0240200e450d002007102e0b200b2009470d000c080b0b200241b8016a200241386a41e80010f6041a200220013602a402200220003602a002200f200241b8016a41e80010f6041a200241086a41b0f3c200410d107d20022802082101200228020c2100200241b0036a200241a0026a109602024002400240024020022802a002417f6a220a2000410020011b22014f0d00200241386a200a10ba01200241386a2018412010f8040d0020022802a002221a41002001417b6a2200200020014b1b490d00200241b0036a20086b220741606a2112200741406a2114200741a07f6a211320082010410574220a6a210e410021010240024002400340024002400240200e200820016a22006b41e0004b0d0020104105742001470d01410021000c060b024020072001470d00200241b0036a21000c060b2000200241b0036a412010f804450d0520122001470d01200241b0036a21000c050b03400240200241b0036a2000470d00200241b0036a21000c060b2000200241b0036a412010f804450d05200041206a2100200a41606a220a0d000b410021000c040b200041206a2217200241b0036a412010f804450d02024020142001470d00200241b0036a21000c040b200041c0006a2217200241b0036a412010f804450d01024020132001470d00200241b0036a21000c040b200a41807f6a210a20014180016a2101200041e0006a200241b0036a412010f8040d000b200820016a41606a21000c020b201721000c010b201721000b200241386a201a10ba01200241386a200241b0036a412010f804210120000d0020010d010b024020022802ac022200450d0020022802a4022101200041246c210003400240024020012d0000220a41034b0d00024002400240200a0e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b20022802a802450d0120022802a402102e0c010b200241b0036a200241a0026a109602200241386a200241a0026a41f00010f6041a02402003a72003422088a72201470d00200141016a22002001490d0d2001410174220a20002000200a491bad220442f0007e2215422088a70d0d2015a722004100480d0d0240024020010d002000102921190c010b2019200141f0006c2000102a21190b2019450d0220034280808080708320048421030b2019200141f0006c6a200241386a41f00010f6041a200241386a41186a2200200241b0036a41186a290300370300200241386a41106a220a200241b0036a41106a290300370300200241386a41086a2207200241b0036a41086a290300370300200220022903b003370338024020112010470d00201041016a22012010490d0d2010410174220e20012001200e491b221141ffffff3f712011470d0d201141057422014100480d0d0240024020100d002001102921080c010b200820104105742001102a21080b2008450d040b20034280808080107c2103200820104105746a22012002290338370000200141186a2000290300370000200141106a200a290300370000200141086a2007290300370000201041016a21100b200b2009470d010c070b0b20004104102c000b20014101102c000b200a4101102c000b41204101102c000b41eff0c2004133200241b0036a4184f4c2001053000b41012109200d450d03200c102e0c030b0240200d450d00200c102e0b02402011450d002008102e0b0240200342ffffffff0f560d00410121092003a7450d032019102e0c030b20190d010b410121090c010b0240200641a00241c004102a22050d0041c0044108102c000b200541a0026a200241a0026a41e80010f6041a2005420237038803200541033a00b803200520033703c003200520193602bc03200520022903b8013703900320054198036a200241c0016a290300370300200541a0036a200241c8016a290300370300200541a8036a200241d0016a290300370300200541b0036a200241d8016a290300370300200520022f00b0033b00b90341022109200541bb036a200241b0036a41026a2d00003a0000200541c8036a200241386a41f80010f6041a0b200241286a2101200228022c21060240024002400240024003402001280200220841086a210020082f0106220741037421014100210a0240024003402001450d0141d5f4c1002000410810f804220b450d02200141786a2101200a41016a210a200041086a2100200b417f4a0d000b200a417f6a21070b2006450d022006417f6a2106200820074102746a41e4016a21010c010b0b200841e0006a200a410c6c6a22012802084104490d0020012802002800002106200241a0026a41086a22014200370300200242003703a002418bd9c0004115200241a0026a1003200241386a41086a2001290300370300200220022903a00237033841002101200241003602a002200241386a4110200241a0026a1008210a0240024020022802a0022200417f460d00200220003602bc012002200a3602b801200241a0026a200241b8016a1041024020022802a002220b450d00200241a8026a280200210120022802a40221082000450d02200a102e0c020b41eff0c2004133200241b0036a4184f4c2001053000b4104210b410021080b4100210002402001417f6a220a20014b0d00200a20014f0d00200b200a4102746a2201450d00200128020020064721000b02402008450d00200b102e0b20000d010b200921120c010b2005200941a0026c220120094101742200200941016a221220122000491b41a0026c2200102a2205450d01200520016a200241a0026a41e80010f604220142023703682001410d3a0098012001419c016a2006360200200120022903b801370370200141f8006a200241c0016a29030037030020014180016a200241c8016a29030037030020014188016a200241d0016a29030037030020014190016a200241d8016a29030037030020014199016a20022f00b0033b00002001419b016a200241b2036a2d00003a0000200141a0016a200241386a41800110f6041a0b2002280228200228022c200228023010e501200241003602a802200242013703a0022012200241a0026a1047201241a0026c210920022802a402210620022802a80221012005210a03402002200a3602b801200241386a200241b8016a10ac022002280238210702400240200620016b20022802402208490d00200120086a210020022802a002210b0c010b200120086a22002001490d042006410174220b20002000200b491b220e4100480d040240024020060d00200e1029210b0c010b20022802a0022006200e102a210b0b200b450d032002200e3602a4022002200b3602a002200e21060b200220003602a802200b20016a2007200810f6041a0240200228023c450d002007102e0b200a41a0026a210a20002101200941e07d6a22090d000b201241a0026c210a20054198016a210103402001102f200141a0026a2101200a41e07d6a220a0d000b2005102e200241d0036a24002000ad422086200bad840f0b20004108102c000b200e4101102c000b102d000bf00101067f2001280204210202400240024003402001280200220341086a210420032f01062205410374210141002106024003402001450d0141f4e1c5002004410810f8042207450d03200141786a2101200641016a2106200441086a21042007417f4a0d000b2006417f6a21050b02402002450d002002417f6a2102200320054102746a41e4016a21010c010b0b200041fce1c500360204200041086a41283602000c010b200341e0006a2006410c6c6a220128020841074b0d01200041a4e2c500360204200041086a41293602000b200041013602000f0b200041086a2001280200290000370300200041003602000bde29060c7f017e057f027e017f017e230041c0026b22022400024002402001450d00200220003602180c010b200241c8ecc5003602180b2002200136021c200241d0006a200241186a10aa020240024002400240024002400240024002400240024002400240024020022802542203450d00200241c8016a2802002104200241c4016a2802002105200241c0016a2802002106200241d0006a410c6a280200210720022802582108200241d0006a200241186a10e40120022802502201450d012002200229025437022420022001360220200241013b013c20024200370234200241e08dc000360230200241306a41086a21092004450d0b2006200441a0026c6a210a200241d8016a410272210b2006210c0340200c41e8006a2903004202520d0c0240200c2d009801410247220d0d00200c2903a001210e200241206a21012002280224210f0240024002400240024002400240024002400240024002400240024002400240024003402001280200221041086a210020102f010622114103742101410021120240024003402001450d0141d8dec5002000410810f8042213450d02200141786a2101201241016a2112200041086a21002013417f4a0d000b2012417f6a21110b200f450d02200f417f6a210f201020114102746a41e4016a21010c010b0b0240201041e0006a2012410c6c6a220128020841074b0d00201442808080807083422984210e41e0dec50021110c020b200e42f02e8020012802002900002214510d0341928dc00021114131210f0c020b201442808080807083421c84210e4189dfc50021110b200ea7210f0b024002400240024020022d003d450d004131210141b09cc20021000c010b20022802302002280234200228023810e50120024200370234200241e08dc000360230200242e2c289abb68edbb7f400370340200241d8016a410272410041da0010f5041a200241d0006a410041840110f5041a41e40110292213450d0420134100360200201341046a200241d8016a41dc0010f6041a201341e0006a200241d0006a41840110f6041a200241003602342002201336023020132f0106220c4103742110417f210041002101024002400340024020102001470d00200c21000c020b200241c0006a201320016a41086a410810f8042212450d02200141086a2101200041016a2100201241004e0d000b0b200242e2c289abb68edbb7f400370264200220093602602002200036025c20022013360254200241003602502002200241306a360258200f41046a2200417f4c0d062000450d02200010292201450d07200220003602bc02200220013602d801200241003602b802200f413f4b0d032001200f4102743a0000410121120c1c0b412d210141839cc20021000b200220013602542002200036025041e19cc2004122200241d0006a41849dc2001053000b200241003602bc02200241003602b80241012100200241013602d801410110292201450d05200141033a0000200241013602bc02200220013602d801200241013602b802410521120c140b200f41808001490d17200f418080808004490d160c120b200d0d0d200c2903a0012115200241d0006a200241206a10ba020240024020022802504101470d002002350258210e200228025421164101210d0c010b2002290358210e200241086a41c5c1c200410d10810102402015200e423c7c560d004100210d2015200229031042b8177c42b81720022802081b220e540d010c0f0b201742808080807083422584210e4101210d41e1c4c20021160b024020022d003d450d004131210141b09cc20021000c070b0240200d450d0020022802302002280234200228023810e50120024200370234200241e08dc000360230200242f4d2b59bc7ae98b8303703400c050b20022802302110200242f4d2b59bc7ae98b830370340201041e08dc000460d042002280234210f0c050b41e4014104102c000b1032000b20004101102c000b41014101102c000b200b410041da0010f5041a200241d0006a410041840110f5041a41e40110292210450d024100210f20104100360200201041046a200241d8016a41dc0010f6041a201041e0006a200241d0006a41840110f6041a20024100360234200220103602300b02400340201041086a210020102f01062211410374210141002112024003402001450d01200241c0006a2000410810f8042213450d03200141786a2101201241016a2112200041086a21002013417f4a0d000b2012417f6a21110b0240200f450d00200f417f6a210f201020114102746a41e4016a28020021100c010b0b200242f4d2b59bc7ae98b830370264200220093602602002201136025c20022010360254200241003602502002200241306a360258200241003602e001200242013703d8014101102921010240200d0d002001450d04200141003a000020024281808080103702dc01200220013602d801200141014109102a2201450d052001200e3700012002428980808090013702dc01200220013602d8010c080b2001450d05200141013a000020024281808080103702dc01200220013602d801200ea72201200241d8016a10470240024020022802dc01221220022802e00122006b2001490d0020022802d80121120c010b200020016a22132000490d1820124101742210201320132010491b22134100480d180240024020120d002013102921120c010b20022802d80120122013102a21120b2012450d07200220133602dc01200220123602d8010b2002200020016a3602e001201220006a2016200110f6041a0c070b412d210141839cc20021000b200220013602542002200036025041e19cc2004122200241d0006a41849dc2001053000b41e4014104102c000b41014101102c000b41094101102c000b41014101102c000b20134101102c000b200241c0006a41086a200241d8016a41086a280200360200200220022903d801370340200241d0006a200241c0006a10e6012002200d3a003d200241003a003c200e2117200d450d00200241d8016a41086a200241306a41086a290300370300200220022903303703d8010c0e0b200c41a0026a220c200a470d000c0c0b0b2002413c6a411c360200200241ec016a4102360200200242023702dc01200241d4f1c1003602d8012002411c360234200241acf3c10036023020024100360244200241c8ecc5003602402002200241306a3602e8012002200241c0006a360238200241d8016a41e4f1c100106a000b200241e4006a4102360200200241d8016a410c6a411c36020020024202370254200241d4f1c1003602502002411c3602dc01200241acf3c1003602d80120024100360234200241c8ecc5003602302002200241d8016a3602602002200241306a3602e001200241d0006a41e4f1c100106a000b200141033a0000200241013602b8022000417f6a41034b0d01200041017422124105201241054b1b22124100480d0a0b200120002012102a2201450d01200220123602bc02200220013602d801201221000b2001200f360001410521120c030b20124101102c000b02400240200041034b0d00200041017422124104201241044b1b22124100480d08200120002012102a2201450d01200220123602bc02200220013602d801201221000b2001200f410274410272360000410421120c020b20124101102c000b0240200041014b0d0020012000200041017422124102201241024b1b2212102a2201450d02200220123602bc02200220013602d801201221000b410221122001200f4102744101723b00000b200220123602b8020240200020126b200f4f0d002012200f6a22132012490d0520004101742210201320132010491b22134100480d05200120002013102a2201450d02200220133602bc02200220013602d8010b20022012200f6a3602b802200120126a2011200f10f6041a200220022802d801360240200220022802bc02360244200220022802b802360248200241d0006a200241c0006a10e60120024180023b013c200241d8016a41086a200241306a41086a290300370300200220022903303703d8010c030b20124101102c000b20134101102c000b200241d8016a41086a2009290300370300200220022903303703d8010b20022802202002280224200228022810e50102402007450d00200741246c21002003210103400240024020012d0000221241034b0d0002400240024020120e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b02402008450d002003102e0b02402004450d00200441a0026c210020064198016a210103402001102f200141a0026a2101200041e07d6a22000d000b0b02402005450d002006102e0b20024100360258200242013703500240410110292201450d002002410136025420022002280258220041016a36025820022001360250200120006a20022d00e4013a0000024002400240200228025420022802582201460d00200228025021000c010b200141016a22002001490d0320014101742212200020002012491b22124100480d030240024020010d002012102921000c010b200228025020012012102a21000b2000450d012002201236025420022000360250200228025821010b2002200141016a360258200020016a20022d00e5013a000020022802e001200241d0006a104720022802d80122122100024020022802dc012213450d002013210120122100034020002802e40121002001417f6a22010d000b0b0240024002400240024002400240024002400240024020022802e00122110d00410021010c010b200241d8016a210d41002113034002400240201320002f01064f0d0020002013410c6c6a41e0006a2110200020134103746a41086a2101201341016a21130c010b02400240200028020022010d00201542808080807083200dad84211541002112410021010c010b2000330104422086200dad842115410121120b201521142015210e02402015422088a7220020012f0106490d000340200e221442ffffffff0f83210e201241016a211220012f01042200200128020022012f01064f0d000b0b20012000410c6c6a2113200120004103746a210f200041027420016a41e8016a28020021002014a7210d02402012417f6a2201450d00034020002802e40121002001417f6a22010d000b0b201341e0006a2110200f41086a2101410021130b02400240200228025420022802582212460d002002280250210f0c010b201241016a220f2012490d0e2012410174220c200f200f200c491b220c4100480d0e0240024020120d00200c1029210f0c010b20022802502012200c102a210f0b200f450d032002200c3602542002200f360250200228025821120b2002201241016a360258200f20126a20012d00003a000002400240200228025420022802582212460d002002280250210f0c010b201241016a220f2012490d0e2012410174220c200f200f200c491b220c4100480d0e0240024020120d00200c1029210f0c010b20022802502012200c102a210f0b200f450d042002200c3602542002200f360250200228025821120b2002201241016a360258200f20126a20012d00013a000002400240200228025420022802582212460d002002280250210f0c010b201241016a220f2012490d0e2012410174220c200f200f200c491b220c4100480d0e0240024020120d00200c1029210f0c010b20022802502012200c102a210f0b200f450d052002200c3602542002200f360250200228025821120b2002201241016a360258200f20126a20012d00023a000002400240200228025420022802582212460d002002280250210f0c010b201241016a220f2012490d0e2012410174220c200f200f200c491b220c4100480d0e0240024020120d00200c1029210f0c010b20022802502012200c102a210f0b200f450d062002200c3602542002200f360250200228025821120b2002201241016a360258200f20126a20012d00033a000002400240200228025420022802582212460d002002280250210f0c010b201241016a220f2012490d0e2012410174220c200f200f200c491b220c4100480d0e0240024020120d00200c1029210f0c010b20022802502012200c102a210f0b200f450d072002200c3602542002200f360250200228025821120b2002201241016a360258200f20126a20012d00043a000002400240200228025420022802582212460d002002280250210f0c010b201241016a220f2012490d0e2012410174220c200f200f200c491b220c4100480d0e0240024020120d00200c1029210f0c010b20022802502012200c102a210f0b200f450d082002200c3602542002200f360250200228025821120b2002201241016a360258200f20126a20012d00053a000002400240200228025420022802582212460d002002280250210f0c010b201241016a220f2012490d0e2012410174220c200f200f200c491b220c4100480d0e0240024020120d00200c1029210f0c010b20022802502012200c102a210f0b200f450d092002200c3602542002200f360250200228025821120b2002201241016a360258200f20126a20012d00063a000002400240200228025420022802582212460d002002280250210f0c010b201241016a220f2012490d0e2012410174220c200f200f200c491b220c4100480d0e0240024020120d00200c1029210f0c010b20022802502012200c102a210f0b200f450d0a2002200c3602542002200f360250200228025821120b2002201241016a360258200f20126a20012d00073a00002010280200210f20102802082201200241d0006a10470240024020022802542210200228025822126b2001490d00200228025021100c010b201220016a220c2012490d0e20104101742212200c200c2012491b22124100480d0e0240024020100d002012102921100c010b200228025020102012102a21100b2010450d0b2002201236025420022010360250200228025821120b2002201220016a360258201020126a200f200110f6041a2011417f6a22110d000b20022802e001210120022802dc01211320022802d80121120b2002350250210e2002350258211420122013200110e501200241c0026a2400200e2014422086840f0b200c4101102c000b200c4101102c000b200c4101102c000b200c4101102c000b200c4101102c000b200c4101102c000b200c4101102c000b200c4101102c000b20124101102c000b20124101102c000b41014101102c000b102d000b4f02017f027e230041306b22022400200241c8ecc500410010bd0220024100360228200242013703202002200241206a10462002350228210320023502202104200241306a240020042003422086840b9718012d7f230041b00d6b220324002003200236020c20032001360208200341106a41086a2201420037030020034200370310419df5c2004115200341106a1003200341900d6a41086a2001290300370300200320032903103703900d200341f00c6a200341900d6a10fe02024002400240024020032802f40c22040d0041012104410021050c010b20032802f80c2105200341f00c6a410c6a28020022020d010b20004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b20032c00f00c2101200341106a410041e00c10f5041a200441206a2106200420024105746a210741002108410021094100210a4100210b4100210c4100210d4100210e4100210f410021104100211141002112410021134100211441002115410021164100211741002118410021194100211a4100211b4100211c4100211d4100211e4100211f4100212041002121410021224100212341002124410021254100212641002127200421024100212841d1002129024003402028212a02400240024002402001450d0020072004460d01200141016a210103400240024020022007470d002006212b200621022004212c0c010b2002212c200241206a222b21020b2001417f6a22010d000c030b0b024020022007460d00200241206a212b2002212c0c030b2006212b2004212c20072004460d040c010b200141016a2101034020072002460d04200241206a21022001417f6a22010d000b200241606a212c2002212b0b202c450d020b202b2102024002400240024002400240200328020c220141056a222b417f4c0d002003280208212802400240202b450d00202b1029222d450d03200341003602980d2003202b3602940d0c010b200341003602980d2003202b3602940d200341013602900d41011029222d450d03200341013602940d0b2003202d3602900d200341013602980d202d202a3a00002001200341900d6a10470240024020032802940d222d20032802980d222b6b2001490d0020032802900d212d0c010b202b20016a222e202b490d05202d410174222f202e202e202f491b222e4100480d0502400240202d0d00202e1029212d0c010b20032802900d202d202e102a212d0b202d450d042003202e3602940d2003202d3602900d0b2003202b20016a3602980d202d202b6a2028200110f6041a202c200341900d6a104620032802940d212c20032802980d212b20032802900d2101200341900d6a41186a222d4200370300200341900d6a41106a22284200370300200341900d6a41086a222e4200370300200342003703900d2001202b200341900d6a1000200341f00c6a41186a222b202d290300370300200341f00c6a41106a222d2028290300370300200341f00c6a41086a222f202e290300370300200320032903900d3703f00c0240202c450d002001102e0b2029417f6a2129202a41016a2128200341106a202a4103704105746a220120032903f00c370000200141186a202b290300370000200141106a202d290300370000200141086a202f2903003700004100212c0340202a202a41036e222b417d6c6a4102470d06200341106a202c6a220141df006a2d000022082001411f6a2d000022097120082009722001413f6a2d00007172211f200141de006a2d000022082001411e6a2d000022097120082009722001413e6a2d00007172211e200141dd006a2d000022082001411d6a2d000022097120082009722001413d6a2d00007172211d200141dc006a2d000022082001411c6a2d000022097120082009722001413c6a2d00007172211c200141db006a2d000022082001411b6a2d000022097120082009722001413b6a2d00007172211b200141da006a2d000022082001411a6a2d000022097120082009722001413a6a2d00007172211a200141d9006a2d00002208200141196a2d00002209712008200972200141396a2d000071722119200141d8006a2d00002208200141186a2d00002209712008200972200141386a2d000071722118200141d7006a2d00002208200141176a2d00002209712008200972200141376a2d000071722117200141d6006a2d00002208200141166a2d00002209712008200972200141366a2d000071722116200141d5006a2d00002208200141156a2d00002209712008200972200141356a2d000071722115200141d4006a2d00002208200141146a2d00002209712008200972200141346a2d000071722114200141d3006a2d00002208200141136a2d00002209712008200972200141336a2d000071722113200141d2006a2d00002208200141126a2d00002209712008200972200141326a2d000071722112200141d1006a2d00002208200141116a2d00002209712008200972200141316a2d000071722111200141d0006a2d00002208200141106a2d00002209712008200972200141306a2d000071722110200141cf006a2d000022082001410f6a2d000022097120082009722001412f6a2d00007172210f200141ce006a2d000022082001410e6a2d000022097120082009722001412e6a2d00007172210e200141cd006a2d000022082001410d6a2d000022097120082009722001412d6a2d00007172210d200141cc006a2d000022082001410c6a2d000022097120082009722001412c6a2d00007172210c200141cb006a2d000022082001410b6a2d000022097120082009722001412b6a2d00007172210b200141ca006a2d000022082001410a6a2d000022097120082009722001412a6a2d00007172210a200141c9006a2d00002208200141096a2d00002209712008200972200141296a2d000071722109200141c8006a2d00002208200141086a2d00002220712008202072200141286a2d000071722108200141c7006a2d00002220200141076a2d00002221712020202172200141276a2d000071722120200141c6006a2d00002221200141066a2d00002222712021202272200141266a2d000071722121200141c5006a2d00002222200141056a2d00002223712022202372200141256a2d000071722122200141c4006a2d00002223200141046a2d00002224712023202472200141246a2d000071722123200141c3006a2d00002224200141036a2d00002225712024202572200141236a2d000071722124200141c2006a2d00002225200141026a2d00002226712025202672200141226a2d000071722125200141c1006a2d00002226200141016a2d00002227712026202772200141216a2d000071722126200141c0006a2d0000222720012d0000222d712027202d72200141206a2d000071722127202c41800c460d06200341106a202c202b410574202a41096e41e0006c6b6a6a220141ff006a201f3a0000200141fe006a201e3a0000200141fd006a201d3a0000200141fc006a201c3a0000200141fb006a201b3a0000200141fa006a201a3a0000200141f9006a20193a0000200141f8006a20183a0000200141f7006a20173a0000200141f6006a20163a0000200141f5006a20153a0000200141f4006a20143a0000200141f3006a20133a0000200141f2006a20123a0000200141f1006a20113a0000200141f0006a20103a0000200141ef006a200f3a0000200141ee006a200e3a0000200141ed006a200d3a0000200141ec006a200c3a0000200141eb006a200b3a0000200141ea006a200a3a0000200141e9006a20093a0000200141e8006a20083a0000200141e7006a20203a0000200141e6006a20213a0000200141e5006a20223a0000200141e4006a20233a0000200141e3006a20243a0000200141e2006a20253a0000200141e1006a20263a0000200141e0006a20273a0000202b212a202c41e0006a222c41e00c470d000c060b0b1032000b202b4101102c000b41014101102c000b202e4101102c000b102d000b4100210120290d000b0b2000201f3a001f2000201e3a001e2000201d3a001d2000201c3a001c2000201b3a001b2000201a3a001a200020193a0019200020183a0018200020173a0017200020163a0016200020153a0015200020143a0014200020133a0013200020123a0012200020113a0011200020103a00102000200f3a000f2000200e3a000e2000200d3a000d2000200c3a000c2000200b3a000b2000200a3a000a200020093a0009200020083a0008200020203a0007200020213a0006200020223a0005200020233a0004200020243a0003200020253a0002200020263a0001200020273a00000b02402005450d002004102e0b200341b00d6a24000bf756040b7f017e127f027e230041b00a6b22022400024002402001450d00200220003602300c010b200241c8ecc5003602300b20022001360234200241d8066a200241306a10b7010240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022903c0074203510d00200241386a200241d8066a41a00210f6041a200241d8026a200241386a41a00210f6041a2002200241d8026a3602f804200241d8066a200241f8046a10ac0220022802e0062100024020022802dc06450d0020022802d806102e0b200241d8066a200241d8026a41a00210f6041a200241f8046a200241d8066a10b901024020022802f8044101470d00200228028005416b6a220041054b0d1b20022802fc04210102400240024020000e06001e1e1e1e01000b4102210341f6012104200141ccc4c200460d01200141ccc4c200411510f804450d010c1d0b410021040240200141949dc200470d00410021030c1e0b41002103200141949dc200411a10f8040d1c0b0c1c0b200241d8066a20024180056a41d80110f6041a200241286a200241a8076a2205109402024020022903f8064202520d0041f00110292201450d04200141013a00e801200142003703e00120014280808080c0003703d801200142043703d0012001427f3703c801200142003703c001200142013703b801200142003703b00120014280808080c0003703a801200142043703a0012001427f3703980120014200370390012001420137038801200142003703800120014280808080c000370378200142043703702001427f37036820014200370360200142013703582001420037035020014280808080c000370348200142043703402001427f37033820014200370330200142013703282001420037032020014280808080c000370318200142043703102001427f37030820014200370300200141ec016a200241f8046a41036a280000360000200120022800f8043600e9012002200141f0016a3602fc09200220013602f809200241053602f409200220013602f009200241800a6a41206a22044200370300200241800a6a41186a22064280808080c000370300200241013a00a80a200242043703900a2002427f3703880a200242003703800a200241b8096a41086a22072001290308370300200241b8096a41106a22082001290310370300200241b8096a41186a22032001290318370300200241b8096a41206a22092001290320370300200220012903003703b809200220012800293602e80920022001412c6a2800003600eb09200141306a210020012d0028220a4102460d0f200241f8086a41286a220b200241800a6a41286a220c290300370300200241f8086a41206a2004290300370300200241f8086a41186a2006290300370300200241f8086a41106a200241800a6a41106a290300370300200241f8086a41086a200241800a6a41086a290300370300200220022903800a3703f808200241f8046a41206a2009290300370300200241f8046a41186a2003290300370300200241f8046a41106a2008290300370300200241f8046a41086a2007290300370300200220022903b8093703f8042002200a3a00a005200241a1056a220a20022802e809360000200a41036a20022800eb09360000200241800a6a200241f8086a200241f8046a10bf022007200041086a2903003703002008200041106a2903003703002003200041186a2903003703002009200041206a290300370300200220002903003703b809200220012800593602e8092002200141dc006a2800003600eb09200141e0006a210020012d005822074102470d020c0f0b20022d002c210a2002280228210941f00110292204450d042002280290072106411310292201450d05200141002900eff3423700002001410f6a41002800fef342360000200141086a41002900f7f34237000020024293808080b0023702fc04200220013602f804200241d8066a200241f8046a104a20022802fc042107200241206a20022802f804220820022802800510c0022002280224410020022802201b210102402007450d002008102e0b0240024002400240200120064b0d00410c10292207450d0a410410292208450d0b200242043702fc04200220083602f804200241d8066a200241f8046a104a0240024020022802fc04220320022802800522086b4104490d0020022802f804210b0c010b200841046a220b2008490d2120034101742208200b200b2008491b22084100480d210240024020030d0020081029210b0c010b20022802f80420032008102a210b0b200b450d0d200220083602fc042002200b3602f80420022802800521080b410421032002200841046a36028005200b20086a2006360000200241f8086a41086a2002280280052208360200200220022903f804220d3703f808200741086a20083602002007200d370200410021080240200120064f0d00410c10292203450d0e410410292201450d0f200242043702fc04200220013602f804200241d8066a200241f8046a104a0240024020022802fc04220820022802800522016b4104490d0020022802f80421080c010b200141046a220b2001490d2220084101742201200b200b2001491b22014100480d220240024020080d002001102921080c010b20022802f80420082001102a21080b2008450d11200220013602fc04200220083602f80420022802800521010b2002200141046a36028005200820016a2006417f6a360000200241f8086a41086a2002280280052201360200200220022903f804220d3703f808200341086a20013602002003200d370200410121080b200220022800800a3602f0092002200241800a6a41036a2800003600f309200220022802f0093602e809200220022800f3093600eb09200241186a41d1e4c5004117107d417f200228021c410020022802181b220120006a220620062001491b418080c002418080f001200a41017122011b4b0d01200241106a41b7e4c500411a107d417f2002280214410020022802101b220a418094ebdc034180afd0e50220011b2206200920062009491b6a220b200b200a491b20064b0d01200220022800f8043602800a2002200241fb046a2800003600830a200220022802800a3602b809200220022800830a3600bb09200241f8046a200229039807200241a0076a290300200241d8066a20092001200010850120022d00f8044101460d02200441013a0088012004428180808010370380012004200736027c2004200836027820042008360274200420033602702004427f37036820042009ad220d370360200442013703582004420037035020044280808080c000370348200442043703402004427f37033820044200370330200442013703282004420037032020044280808080c000370318200442043703102004427f370308200442003703002004427f200d20011b370390012004427f37039801200442043703a00120044280808080c0003703a801200442003703b001200441013a00b8012004418c016a20022800eb09360000200420022802e80936008901200420022802b8093600b901200441bc016a20022800bb0936000020042002290380053703c001200441c8016a200241f8046a41106a2200290300370300200441d0016a200241f8046a41186a2206290300370300200441d8016a200241f8046a41206a2207290300370300200441e0016a200241f8046a41286a2208290300370300200441e8016a200241f8046a41306a2903003703002002200441f0016a3602fc09200220043602f809200241053602f409200220043602f009200241800a6a41206a22034200370300200241800a6a41186a22094280808080c000370300200241013a00a80a200242043703900a2002427f3703880a200242003703800a200241b8096a41086a220a2004290308370300200241b8096a41106a220b2004290310370300200241b8096a41186a220c2004290318370300200241b8096a41206a220e2004290320370300200220042903003703b809200220042800293602e80920022004412c6a2800003600eb09200441306a210120042d0028220f4102460d10200241f8086a41286a200241800a6a41286a290300370300200241f8086a41206a2003290300370300200241f8086a41186a2009290300370300200241f8086a41106a200241800a6a41106a290300370300200241f8086a41086a200241800a6a41086a290300370300200220022903800a3703f8082007200e2903003703002006200c2903003703002000200b290300370300200241f8046a41086a200a290300370300200220022903b8093703f8042002200f3a00a005200241a1056a220f20022802e809360000200f41036a221020022800eb09360000200241800a6a200241f8086a200241f8046a10bf02200a200141086a290300370300200b200141106a290300370300200c200141186a290300370300200e200141206a290300370300200220012903003703b809200220042800593602e8092002200441dc006a2800003600eb09200441e0006a210120042d0058220a4102470d060c100b200220022800800a3602f0092002200241830a6a2800003600f30920024181083b01f8082004102e41012101410421060c020b200220022800f8043602800a2002200241f8046a41036a2800003600830a20024181023b01f80802402008450d002008410c6c21002003210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b2003102e0b0240200741046a280200450d002007280200102e0b2007102e2004102e41012106410121010c0f0b200220022d00f90422063a00f908200241013a00f80802402008450d002008410c6c21002003210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b2003102e0b0240200741046a280200450d002007280200102e0b2007102e2004102e410121010b0c0d0b200241c4006a411c360200200241ec026a4102360200200242023702dc02200241d4f1c1003602d8022002411c36023c200241c4f3c100360238200241003602fc04200241c8ecc5003602f8042002200241386a3602e8022002200241f8046a360240200241d8026a41e4f1c100106a000b200b200c290300370300200241f8086a41206a220c200241800a6a41206a220e290300370300200241f8086a41186a220f200241800a6a41186a2210290300370300200241f8086a41106a2211200241800a6a41106a2212290300370300200241f8086a41086a2213200241800a6a41086a2214290300370300200220022903800a3703f808200241f8046a41206a2215200241b8096a41206a2208290300370300200241f8046a41186a2216200241b8096a41186a2203290300370300200241f8046a41106a2217200241b8096a41106a2209290300370300200241f8046a41086a2218200241b8096a41086a220b290300370300200220022903b8093703f804200220073a00a005200a20022802e809360000200a41036a220720022800eb09360000200241800a6a200241f8086a200241f8046a10bf02200b200041086a2903003703002009200041106a2903003703002003200041186a2903003703002008200041206a290300370300200220002903003703b80920022001280089013602e80920022001418c016a2800003600eb0920014190016a210020012d00880122194102460d0c200241f8086a41286a221a200241800a6a41286a221b290300370300200c200e290300370300200f20102903003703002011201229030037030020132014290300370300200220022903800a3703f8082015200829030037030020162003290300370300201720092903003703002018200b290300370300200220022903b8093703f804200220193a00a005200a20022802e809360000200720022800eb09360000200241800a6a200241f8086a200241f8046a10bf02200b200041086a2903003703002009200041106a2903003703002003200041186a2903003703002008200041206a290300370300200220002903003703b809200220012800b9013602e8092002200141bc016a2800003600eb09200141c0016a210020012d00b80122074102460d0c201a201b290300370300200241f8086a41206a220c200241800a6a41206a220e290300370300200241f8086a41186a220f200241800a6a41186a2210290300370300200241f8086a41106a2211200241800a6a41106a2212290300370300200241f8086a41086a2213200241800a6a41086a2214290300370300200220022903800a3703f808200241f8046a41206a2215200241b8096a41206a2208290300370300200241f8046a41186a2216200241b8096a41186a2203290300370300200241f8046a41106a2217200241b8096a41106a2209290300370300200241f8046a41086a2218200241b8096a41086a220b290300370300200220022903b8093703f804200220073a00a005200a20022802e809360000200a41036a220720022800eb09360000200241800a6a200241f8086a200241f8046a10bf02200b200041086a2903003703002009200041106a2903003703002003200041186a2903003703002008200041206a290300370300200220002903003703b809200220012800e9013602e8092002200141ec016a2800003600eb09200141f0016a210020012d00e80122014102460d0c200241f8086a41286a200241800a6a41286a290300370300200c200e290300370300200f20102903003703002011201229030037030020132014290300370300200220022903800a3703f8082015200829030037030020162003290300370300201720092903003703002018200b290300370300200220022903b8093703f804200220013a00a005200a20022802e809360000200720022800eb09360000200241800a6a200241f8086a200241f8046a10bf020c0c0b200241f8086a41286a2212200241800a6a41286a2213290300370300200241f8086a41206a2214200241800a6a41206a2215290300370300200241f8086a41186a2216200241800a6a41186a2217290300370300200241f8086a41106a2218200241800a6a41106a2219290300370300200241f8086a41086a221a200241800a6a41086a221b290300370300200220022903800a3703f808200241f8046a41206a221c200241b8096a41206a220b290300370300200241f8046a41186a221d200241b8096a41186a220c290300370300200241f8046a41106a221e200241b8096a41106a220e290300370300200241f8046a41086a221f200241b8096a41086a2211290300370300200220022903b8093703f8042002200a3a00a005200f20022802e809360000201020022800eb09360000200241800a6a200241f8086a200241f8046a10bf022011200141086a290300370300200e200141106a290300370300200c200141186a290300370300200b200141206a290300370300200220012903003703b80920022004280089013602e80920022004418c016a2800003600eb0920044190016a210120042d008801220a4102460d0920122013290300370300201420152903003703002016201729030037030020182019290300370300201a201b290300370300200220022903800a3703f808201c200b290300370300201d200c290300370300201e200e290300370300201f2011290300370300200220022903b8093703f8042002200a3a00a005200f20022802e809360000200f41036a220a20022800eb09360000200241800a6a200241f8086a200241f8046a10bf022011200141086a290300370300200e200141106a290300370300200c200141186a290300370300200b200141206a290300370300200220012903003703b809200220042800b9013602e8092002200441bc016a2800003600eb09200441c0016a210120042d00b801220b4102460d09200241f8086a41286a2212200241800a6a41286a2213290300370300200241f8086a41206a2214200241800a6a41206a2215290300370300200241f8086a41186a2216200241800a6a41186a2217290300370300200241f8086a41106a2218200241800a6a41106a2219290300370300200241f8086a41086a221a200241800a6a41086a221b290300370300200220022903800a3703f808200241f8046a41206a221c200241b8096a41206a220c290300370300200241f8046a41186a221d200241b8096a41186a220e290300370300200241f8046a41106a221e200241b8096a41106a2210290300370300200241f8046a41086a221f200241b8096a41086a2211290300370300200220022903b8093703f8042002200b3a00a005200f20022802e809360000200a20022800eb09360000200241800a6a200241f8086a200241f8046a10bf022011200141086a2903003703002010200141106a290300370300200e200141186a290300370300200c200141206a290300370300200220012903003703b809200220042800e9013602e8092002200441ec016a2800003600eb09200441f0016a210120042d00e80122044102460d0920122013290300370300201420152903003703002016201729030037030020182019290300370300201a201b290300370300200220022903800a3703f808201c200c290300370300201d200e290300370300201e2010290300370300201f2011290300370300200220022903b8093703f804200220043a00a005200f20022802e809360000200f41036a20022800eb09360000200241800a6a200241f8086a200241f8046a10bf020c090b41f0014108102c000b41f0014108102c000b41134101102c000b410c4104102c000b41044101102c000b20084101102c000b410c4104102c000b41044101102c000b20014101102c000b200241f8046a41086a2204200241800a6a41086a2903003703002000200241800a6a41106a29030037030020062009290300370300200720032903003703002008200241800a6a41286a290300370300200220013602f809200220022903800a3703f804200241f0096a103a200241f8086a41086a20022903f8042220370300200241f8086a41106a20042903002221370300200241f8086a41186a2000290300220d370300200241f8086a41206a2006290300370300200241f8086a41286a2007290300370300200241f8086a41306a200829030037030041002101200241003a00f808200da7210c20022d00f90821060b200241a8096a2d00002110200241a4096a2802002109200241a0096a280200210e2002419c096a280200210b20024198096a280200210a20024194096a280200210f024020010d00410121030c020b42bcf7ea858cf8afdfbd7f2006410473ad42078342038688a72104410021030c0b0b200241f8086a41086a2201200241800a6a41086a290300370300200241f8086a41106a2207200241800a6a41106a290300370300200241f8086a41186a22082006290300370300200241f8086a41206a22062004290300370300200241f8086a41286a2204200241800a6a41286a290300370300200220003602f809200220022903800a3703f808200241f0096a103a200241f8046a41106a2001290300220d370300200241f8046a41186a22012007290300370300200241f8046a41206a22002008290300370300200241f8046a41286a22072006290300370300200241f8046a41306a22032004290300370300200220022903f80822213703800541002104200241003a00f804200241f0096a41086a200d370300200220213703f009200241f8046a412c6a28020021062007280200210a2002419c056a28020021082000280200210020024194056a280200210b2001280200210920022d00a8074112470d092003290300210d200241cc076a2802002110200241086a41b8dfc5004114107d200241b8096a200228020c410020022802081b10f601200220103602e809200241f8086a41186a22014200370300200241f8086a41106a22044200370300200241f8086a41086a22074200370300200242003703f808200241e8096a4104200241f8086a1000200241800a6a41186a2001290300370300200241800a6a41106a2004290300370300200241800a6a41086a2007290300370300200220022903f8083703800a0240024020022802bc09220720022802c00922046b4120490d00200441206a210320022802b80921010c010b200441206a22032004490d0e20074101742201200320032001491b220c4100480d0e0240024020070d00200c102921010c010b20022802b8092007200c102a21010b2001450d022002200c3602bc09200220013602b809200c21070b200120046a220420022903800a370000200441186a200241800a6a41186a290300370000200441106a200241800a6a41106a290300370000200441086a200241800a6a41086a2903003700002001200341c8ecc500410041001005210302402007450d002001102e0b410121042003417f470d09200241b8dfc5004114107d200241c8076a2802002002280204410020022802001b2212470d09200241f8086a41086a22014200370300200242003703f8084183d9c500410d200241f8086a1003200241800a6a41086a2001290300370300200220022903f8083703800a200241b8096a200241800a6a109802024020022802b80922130d00410021040c0a0b20022802bc09211402400240200241b8096a41086a28020020104d0d002002410036028009200242013703f80820022802ac072104410410292201450d0420024284808080c0003702fc08200220013602f80820012004360000200241b0076a2802002103200241b8076a2802002201200241f8086a10470240024020022802fc08220720022802800922046b2001490d0020022802f80821070c010b200420016a220c2004490d102007410174220e200c200c200e491b220c4100480d100240024020070d00200c102921070c010b20022802f8082007200c102a21070b2007450d062002200c3602fc08200220073602f8080b2002200420016a36028009200720046a2003200110f6041a200241bc076a2802002104200241c4076a2802002201200241f8086a10470240024020010d0020022802fc082103200228028009210f201221070c010b20042001410c6c6a211103402004280200210e200441086a2802002201200241f8086a10470240024020022802fc08220320022802800922076b2001490d0020022802f808210c0c010b200720016a220c2007490d122003410174220f200c200c200f491b220f4100480d120240024020030d00200f1029210c0c010b20022802f8082003200f102a210c0b200c450d092002200f3602fc082002200c3602f808200f21030b2002200720016a220f36028009200c20076a200e200110f6041a2004410c6a22042011470d000b20022802c80721070b024002402003200f6b4104490d0020022802f80821010c010b200f41046a2201200f490d1020034101742204200120012004491b22044100480d100240024020030d002004102921010c010b20022802f80820032004102a21010b2001450d08200220043602fc08200220013602f808200421030b2002200f41046a2204360280092001200f6a200736000020022802cc07210c02400240200320046b41034d0d00200321070c010b200441046a22072004490d102003410174220e20072007200e491b22074100480d100240024020030d002007102921010c010b200120032007102a21010b2001450d09200220073602fc08200220013602f8080b200120046a200c3600002001200f41086a200241d0076a201320104105746a2203100c210402402007450d002001102e0b2004450d010b410021042014450d0a2013102e0c0a0b410c10292201450d07410410292204450d0820024284808080c0003702fc08200220043602f808200420123600002003200241f8086a104a200241800a6a41086a2002280280092204360200200220022903f80822213703800a200141086a200436020020012021370200200220022802e8093602b009200220022800eb093600b30902402014450d002013102e0b200241800a6a41206a428180808010370300200241800a6a41186a4100360200200241ac0a6a20022800b30936000041012103200241013a00a80a2002200136029c0a200242043703900a2002427f3703880a200242003703800a200220022802b0093600a90a200241f8086a41086a200241f0096a41086a290300370300200241f8086a41246a2006360200200241f8086a41206a200a360200200241f8086a41186a2000360200200241f8086a41146a200b360200200220022903f0093703f8082002200d3703a00920022008360294092002200936028809200241b8096a200241800a6a200241f8086a10bf02200241b8096a41146a280200210f200241b8096a41186a280200210a200241b8096a41206a280200210e200241b8096a41246a280200210920022903b809212020022903c009212120022802c809210c20022802d409210b20022d00e00921100b0c090b200c4101102c000b41044101102c000b200c4101102c000b200f4101102c000b20044101102c000b20074101102c000b410c4104102c000b41044101102c000b02402000450d002000410c6c21002009210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b0240200b450d002009102e0b02402006450d002006410c6c21002008210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b42002120427f21214104210c0240200a450d002008102e0b4100210a41012110410121094101210e4100210f410021030b2005102f0c010b4100210341810121040b200241003602e0064201210d200242013703d806024002400240024002400240024002400240024002400240200341024d0d00420021210c010b024002400240024020030e03000102000b410110292201450d04200241013602dc06200220022802e006220041016a3602e006200220013602d806200120006a41003a00000240024020022802dc0620022802e0062201460d0020022802d80621000c010b200141016a22002001490d0f20014101742205200020002005491b22054100480d0f0240024020010d002005102921000c010b20022802d80620012005102a21000b2000450d06200220053602dc06200220003602d80620022802e00621010b2002200141016a3602e006200020016a20043a00000c020b410110292201450d05200241013602dc06200220022802e006220041016a3602e006200220013602d806200120006a41013a00000240024020022802dc06220020022802e00622016b4108490d0020022802d80621000c010b200141086a22042001490d0e20004101742201200420042001491b22014100480d0e0240024020000d002001102921000c010b20022802d80620002001102a21000b2000450d07200220013602dc06200220003602d80620022802e00621010b2002200141086a3602e006200020016a2020370000200a200241d8066a10470240200a450d00200c200a410c6c6a2108200c2104034020042802002106200441086a2802002201200241d8066a10470240024020022802dc06220520022802e00622006b2001490d0020022802d80621050c010b200020016a22072000490d1020054101742200200720072000491b22004100480d100240024020050d002000102921050c010b20022802d80620052000102a21050b2005450d0a200220003602dc06200220053602d80620022802e00621000b2002200020016a3602e006200520006a2006200110f6041a2004410c6a22042008470d000b0b2009200241d8066a104702402009450d00200b2009410c6c6a2108200b2104034020042802002106200441086a2802002201200241d8066a10470240024020022802dc06220520022802e00622006b2001490d0020022802d80621050c010b200020016a22072000490d1020054101742200200720072000491b22004100480d100240024020050d002000102921050c010b20022802d80620052000102a21050b2005450d0b200220003602dc06200220053602d80620022802e00621000b2002200020016a3602e006200520006a2006200110f6041a2004410c6a22042008470d000b0b0240024020022802dc06220020022802e00622016b4108490d0020022802d80621000c010b200141086a22042001490d0e20004101742201200420042001491b22014100480d0e0240024020000d002001102921000c010b20022802d80620002001102a21000b2000450d0a200220013602dc06200220003602d80620022802e00621010b2002200141086a3602e006200020016a20213700000240024020022802dc0620022802e0062201460d0020022802d80621000c010b200141016a22002001490d0e20014101742204200020002004491b22044100480d0e0240024020010d002004102921000c010b20022802d80620012004102a21000b2000450d0b200220043602dc06200220003602d80620022802e00621010b2002200141016a3602e006200020016a20103a00000c010b410110292201450d0a200241013602dc06200220022802e006220041016a3602e006200220013602d806200120006a41023a00000240024020022802dc0620022802e0062201460d0020022802d80621000c010b200141016a22002001490d0d20014101742205200020002005491b22054100480d0d0240024020010d002005102921000c010b20022802d80620012005102a21000b2000450d0c200220053602dc06200220003602d80620022802e00621010b2002200141016a3602e006200020016a20043a00000b20023502e006422086212120023502d806210d0b024020034101470d000240200a450d00200a410c6c2100200c210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b0240200f450d00200c102e0b02402009450d002009410c6c2100200b210103400240200141046a280200450d002001280200102e0b2001410c6a2101200041746a22000d000b0b200e450d00200b102e0b200241b00a6a24002021200d840f0b41014101102c000b20054101102c000b41014101102c000b20014101102c000b20004101102c000b20004101102c000b20014101102c000b20044101102c000b41014101102c000b20054101102c000b102d000b980505017f027e077f017e017f230041106b220324002002290300210420012903002105200141106a21062002280210210702400240024002400240200141146a2802002208200141186a28020022096b200241186a280200220a490d00200628020021080c010b2009200a6a220b2009490d032008410174220c200b200b200c491b220bad420c7e220d422088a70d03200da7220c4100480d030240024020080d00200c102921080c010b20062802002008410c6c200c102a21080b2008450d0120012008360210200141146a200b3602000b20082009410c6c6a2007200a410c6c10f6041a200141186a2009200a6a36020020024100360218200341086a200641086a280200360200200320062902003703002001411c6a2106200228021c210b02400240200141206a2802002208200141246a28020022096b200241246a280200220a490d00200628020021080c010b2009200a6a220c2009490d032008410174220e200c200c200e491b220cad420c7e220d422088a70d03200da7220e4100480d030240024020080d00200e102921080c010b20062802002008410c6c200e102a21080b2008450d022001200836021c200141206a200c3602000b20082009410c6c6a200b200a410c6c10f6041a200141246a2009200a6a360200200241003602242000427f200520047c220420042005541b37030020002003290300370210200041186a200341086a2802003602002000200629020037021c200041246a200641086a280200360200200020022d0028410020012d00281b3a00282000200229030822052001290308220420042005561b3703080240200241146a280200450d002007102e0b0240200241206a280200450d00200b102e0b200341106a24000f0b200c4104102c000b200e4104102c000b102d000bf70101047f230041c0006b22032400200341206a41186a22044200370300200341206a41106a22054200370300200341206a41086a220642003703002003420037032020012002200341206a1000200341186a2004290300370300200341106a2005290300370300200341086a200629030037030020032003290320370300410021022003410036022020034120200341206a1008210102400240024020032802202204417f470d000c010b024020010d000c010b20044104490d01200128000021042001102e410121020b2000200436020420002002360200200341c0006a24000f0b41eff0c2004133200341206a4184f4c2001053000bce3705057f017e0c7f027e1b7f23004190046b22022400024002400240024002400240024002400240024020014104490d00200041c8ecc50020011b2800002103100e4101470d08200241286a41d2d7c1004111107d200228022c2100200228022821044100210520024100360270410141d0d9c100411c200241f0006a100f21012000410020041b21040240024020022802702200417f470d0041012100410121060c010b2000ad220742208620078421072001452100024020010d00410121060c010b2007422088a74105490d0320012800012205200449200520034920012d00001b2106200121050b200420034f0d012006450d010240410110292201450d00200141003a00000240200141014105102a2201450d0020012003360001410141d0d9c100411c4100200520001b22042007422088a7417f20041b20014105101021042001102e024020002007a745720d002005102e0b20040d0a200241f0006a41086a22014200370300200242003703704183d9c500410d200241f0006a100320024190036a41086a20012903003703002002200229037037039003200241f0006a20024190036a1098024100210802400240200228027022090d00410121094100210a4100210b0c010b2001280200210b2002280274210a0b200241e9dabdf30636028004200241003602840420024180046a20024184046a10112101200220022802840436028c042002200136028804200241206a20024188046a10312002280224210620022802200d05200228028c0422014160712200417f4c0d070240024002402001410576220c0d00410121080c010b200010292208450d010b2006450d0741002105034020012104200241003a0090012005220d41016a2105410021010240024002400240034020042001460d01200241f0006a20016a20022802880422002d00003a00002002200041016a360288042002200141016a22003a0090012000210120004120470d000b200241306a41086a220e200241f0006a41086a290300370300200241306a41106a220f200241f0006a41106a290300370300200241306a41186a2210200241f0006a41186a29030037030020022002290370370330200c200d470d03200d4101742201200520052001491b220c41ffffff3f71200c470d11200c410574220141004e0d010c110b2002410036028c040240200141ff0171450d00200241003a0090010b200c0d01410021080c0b0b02400240200d0d002001102921080c010b2008200d4105742001102a21080b20080d0120014101102c000b2008102e410021080c080b200420006b21012008200d4105746a220d2002290330370000200d41186a2010290300370000200d41106a200f290300370000200d41086a200e29030037000020052006470d000b2002200420006b36028c040c070b20004101102c000b41054101102c000b41014101102c000b2002419c036a411c36020020024184016a410236020020024202370274200241d4f1c1003602702002411c36029403200241e0f3c1003602900320024100360234200241c8ecc500360230200220024190036a360280012002200241306a36029803200241f0006a41e4f1c100106a000b20002007a745720d062005102e0c060b02402007a7450d002001102e0b41d2d6c500412d10090c050b0b410121112008410120081b21054100211241002113024002400240024002402006410020081b2200450d0020004105742201410575221241ffffff3f712012470d0920014100480d09200110292211450d01200520016a210d20004105742106410021010340200520016a22002900002107200041086a2900002114200041106a2900002115201120016a220441186a200041186a290000370000200441106a2015370000200441086a2014370000200420073700002006200141206a2201470d000b200d20056b41606a41057641016a21130b02402008450d00200c450d002005102e0b20134115490d024101450d04201341017622164105742201417f4c0d04200110292217450d01201141606a2118201141a07f6a21194104211a4100211b4100210c2013211c0340201c21084100211c4101210602402008417f6a2204450d00024002400240024002400240201120044105746a2008410574220d20116a41406a412010f8044100480d002008417e6a21052019200d6a21014100211c410021000340024020052000470d00200821060c080b200041016a2100200141206a2001412010f8042104200141606a21012004417f4a0d000b200041016a21062000417f7320086a21040c010b2019200d6a210102400340024020044101470d00410021040c020b2004417f6a2104200141206a2001412010f8042100200141606a210120004100480d000b0b20082004490d01200820134b0d03200820046b22064101762205450d002018200d6a2101201120044105746a2100034020024190036a41186a220d200041186a220e29000037030020024190036a41106a220f200041106a221029000037030020024190036a41086a221d200041086a221e2900003703002002200029000037039003200141086a221f2900002107200141106a22202900002114200141186a221c290000211520002001290000370000200e201537000020102014370000201e2007370000201c200d2903003700002020200f290300370000201f201d2903003700002001200229039003370000200141606a2101200041206a21002005417f6a22050d000b0b024020040d002004211c0c050b0240200641094d0d002004211c0c050b200820134b0d01200820046b2105201120044105746a210d034020082004417f6a221c490d0402402008201c6b22064102490d00201120044105746a22012011201c4105746a2204412010f804417f4a0d002004290000210720042001290000370000200241f0006a41186a221d200441186a2200290000370300200241f0006a41106a221e200441106a220e290000370300200241f0006a41086a221f200441086a220f290000370300200f200141086a290000370000200e200141106a2900003700002000200141186a2900003700002002200737037041012110024020064103490d00200441c0006a200241f0006a412010f804417f4a0d0041022100200d210102400340200141186a200141386a290000370000200141106a200141306a290000370000200141086a200141286a2900003700002001200141206a220e29000037000020052000460d01200141c0006a210f20002110200e2101200041016a2100200f200241f0006a412010f804417f4a0d020c000b0b200021100b200420104105746a22012002290370370000200141186a201d290300370000200141106a201e290300370000200141086a201f2903003700000b201c450d05200d41606a210d200541016a2105201c21042006410a4f0d050c000b0b200420081035000b20082004417f6a221c490d010b20082013105e000b201c20081035000b024002400240201b200c470d00201b41016a2201201b490d0c201b4101742200200120012000491b220141ffffffff01712001470d0c200141037422004100480d0c02400240201b0d0020001029211a0c010b201a201b4103742000102a211a0b201a450d012001211b0b201a200c4103746a220120063602042001201c360200200c41016a221d210c201d4102490d0103400240024002400240201a201d220f417f6a221d4103746a2201280200450d00200f410374201a6a220641746a2802002205200128020422004d0d004102210c200f41024d0d06201a200f417d6a22014103746a2802042204200020056a4d0d014103210c200f41034d0d06200641646a280200200420056a4d0d01200f210c0c060b200f4103490d0120012802042100201a200f417d6a22014103746a28020421040b20042000490d010b200f417e6a21010b024002400240024002400240200f200141016a22214d0d00200f20014d0d01201a20014103746a221e2802042222201e2802006a2201201a20214103746a221f2802002220490d02200120134b0d03201e41046a2123201120204105746a220e201f280204221041057422006a210520014105742104200120206b220820106b220120104f0d04201720052001410574220010f604220d20006a21060240024020104101480d00200141014e0d010b20052101200d21000c060b201820046a21042005210103402004200141606a2205200641606a220820082005412010f804410048220c1b2200290000370000200441186a200041186a290000370000200441106a200041106a290000370000200441086a200041086a29000037000020062008200c1b21060240200e20052001200c1b2201490d00200d21000c070b200441606a2104200d2100200d2006490d000c060b0b41f484c0002021200f1038000b41f484c0002001200f1038000b202020011035000b20012013105e000b2017200e200010f604220d20006a21060240024020104101480d00200820104a0d010b200e2101200d21000c010b201120046a210c200d2100200e2101034020012005200020052000412010f80441004822081b2204290000370000200141186a200441186a290000370000200141106a200441106a290000370000200141086a200441086a2900003700002000200041206a20081b2100200141206a2101200541206a200520081b2205200c4f0d01200620004b0d000b0b20012000200620006b41607110f6041a2023202220106a360200201e2020360200201f201f41086a2021417f73200f6a41037410f7041a201d210c201d41014d0d020c000b0b20004104102c000b201c0d000b0240201b450d00201a102e0b2016450d032017102e0c030b20014101102c000b20014101102c000b20134102490d002013417f6a2100201341057420116a41606a21064101210403400240024002400240201320002201417f6a2200490d00201320006b22084102490d03201120014105746a2201201120004105746a2205412010f804417f4a0d032005290000210720052001290000370000200241f0006a41186a220f200541186a220c290000370300200241f0006a41106a2210200541106a220d290000370300200241f0006a41086a221a200541086a220e290000370300200e200141086a290000370000200d200141106a290000370000200c200141186a290000370000200220073703704101210120084103490d02200541c0006a200241f0006a412010f804417f4a0d0241002108200621010340200141186a200141386a290000370000200141106a200141306a290000370000200141086a200141286a2900003700002001200141206a220d29000037000020042008220c460d02200c417f6a2108200141c0006a210e200d2101200e200241f0006a412010f804417f4a0d020c000b0b200020131035000b4102200c6b21010b200520014105746a22012002290370370000200141186a200f290300370000200141106a2010290300370000200141086a201a2903003700000b200641606a21062004417f6a210420000d000b0b200b450d022009200b4105746a210e200241b1026a211d20024196036a2124200241f0006a41016a211e20024188026a2125200241a8016a2126200241f0006a41306a2127200241f0006a41286a21284100210820092106024002400240024002400340024002400240201341014b0d00024020130e020c000c0b0340200241f0006a41186a200641186a290000370300200241f0006a41106a200641106a290000370300200241f0006a41086a200641086a290000370300200220062900003703702011200241f0006a412010f804450d02200841016a2108200e200641206a2206470d000c0c0b0b0340200241f0006a41186a200641186a290000370300200241f0006a41106a200641106a290000370300200241f0006a41086a200641086a29000037030020022006290000370370200641206a210602402013450d004100210120132100034020012000410176220420016a2205201120054105746a200241f0006a412010f80441004a1b2101200020046b220041014b0d000b201120014105746a200241f0006a412010f804450d030b200841016a21082006200e460d0b0c000b0b200641206a2106410021010b0240024002400240024002400240201320014d0d00200241003602900320024190036a1012210402402002280290032200417f470d00410321010c0f0b20022000360274200220043602702000450d0320042d0000210520022000417f6a3602742002200441016a360270200541014b0d030240024020050e020100010b4100212120222116201a211f2010211c200f2129200d212a200c21202022212b201a212c2010212d200f212e200d212f200c21300c060b200241186a200241f0006a103120022802180d0320022802742205200228021c222c490d03202c417f4c0d0d02400240202c0d004101212141010d010c050b202c10342221450d0220212002280270221f202c10f604212020022005202c6b3602742002201f202c6a3602702020450d040b200241106a200241f0006a103120022802100d022002280274410c6e222f410c6c2205417f4c0d0d200228021421300240024002400240024020050d004104212e0c010b20051029222e450d010b02400240024020300d00202e212d0c010b410021164100211f4100211c202e212d0340200241086a200241f0006a103120022802080d0220022802742220200228020c2205490d022005417f4c0d130240024020050d004101212a0c010b20051034222a450d05202a20022802702229200510f6041a2002202020056b3602742002202920056a3602700b201c41016a21200240201c202f470d002016202020202016491b222fad420c7e2207422088a70d182007a722294100480d1802400240201c0d0020291029212e0c010b202e201f2029102a212e0b202e450d06202e212d0b202d201f6a221c202a360200201c41046a2005ad2207422086200784370200201641026a2116201f410c6a211f2020211c20302020470d000b0b202d450d06202c212b20302120202f212a202e2129202d211c202c211f202c211620210d080c070b0240201c450d004100210503400240202d20056a222041046a280200450d002020280200102e0b201f2005410c6a2205470d000b0b202f450d05202e102e0c050b20054104102c000b20054101102c000b20294104102c000b41ecd9c100200120131038000b202c4101102c000b202c450d002021102e0b41002121200c2130200d212f200f212e2010212d201a212c2022212b202321202017212a201b21292018211c2019211f200b21160b2000450d010b2004102e0b024020210d00410321010c080b200241b8dfc5004114107d2002280204212220022802002123200242013703702002410036027802400240024002400240410410292200450d0020024284808080c0003702742002200036027020002003360000201f200241f0006a10470240024020022802742204200228027822006b201f490d00200228027021040c010b2000201f6a22052000490d102004410174220c20052005200c491b22054100480d100240024020040d002005102921040c010b200228027020042005102a21040b2004450d0220022005360274200220043602700b20022000201f6a360278200420006a2021201f10f6041a2020200241f0006a10472020450d02201c2020410c6c6a211a201c210403402004280200210f200441086a2802002200200241f0006a1047024002402002280274220c200228027822056b2000490d002002280270210d0c010b200520006a220d2005490d11200c4101742210200d200d2010491b22104100480d1102400240200c0d0020101029210d0c010b2002280270200c2010102a210d0b200d450d05200220103602742002200d3602702010210c0b2002200520006a2210360278200d20056a200f200010f6041a2004410c6a2204201a470d000c050b0b41044101102c000b20054101102c000b2002280274210c200228027821100c010b20104101102c000b02400240200c20106b4104490d00200228027021000c010b201041046a22002010490d0b200c4101742204200020002004491b22044100480d0b02400240200c0d002004102921000c010b2002280270200c2004102a21000b2000450d0220022004360274200220003602702004210c0b2002201041046a2204360278200020106a2022410020231b220d36000002400240200c20046b41034d0d00200c21050c010b200441046a22052004490d0b200c410174220f20052005200f491b22054100480d0b02400240200c0d002005102921000c010b2000200c2005102a21000b2000450d0320022005360274200220003602700b200020046a2008360000200241e9dabdf30636029003202642003703002027420037030020284200370300200241f0006a41206a4200370300200241f0006a41186a4200370300200241f0006a41106a4200370300200241f0006a41086a420037030020024200370370024020024190036a201120014105746a2000201041086a200241f0006a10130d00200241306a41086a2201201e41086a290000370300200241306a41106a2204201e41106a290000370300200241306a41186a220c201e41186a290000370300200241306a41206a220f201e41206a290000370300200241306a41286a2210201e41286a290000370300200241306a41306a221a201e41306a290000370300200241306a41376a2222201e41376a2900003700002002201e29000037033020022d0070212302402005450d002000102e0b200241f0006a202441e80010f6041a201d2002290330370000201d41086a2001290300370000201d41106a2004290300370000201d41186a200c290300370000201d41206a200f290300370000201d41286a2010290300370000201d41306a201a290300370000201d41376a2022290000370000200220233a00b002200220083602ac022002200d3602a802200220203602a4022002202a3602a0022002202936029c022002201f36029802200220163602940220022021360290022002200336028c02200241123a008802200242023703d8012002200241f0006a3602880420024190036a20024188046a10ac022002280290032200200228029803101421010240200228029403450d002000102e0b20010d04410110292201450d05200141013a0000200141014105102a2201450d06200841016a210820012003360001410141d0d9c100411c2001410510152001102e2025102f2030210c202f210d202e210f202d2110202c211a202b212220202123202a21172029211b201c2118201f21192016210b2006200e470d010c090b0b02402005450d002000102e0b02402016450d002021102e0b02402020450d002020410c6c210103400240201c41046a280200450d00201c280200102e0b201c410c6a211c200141746a22010d000b0b41022101202a450d062029102e0c060b20044101102c000b20054101102c000b2025102f410421010c030b41014101102c000b41054101102c000b1032000b0240200a450d002009102e0b02402012450d002011102e0b0240024002400240024020010e050102030400010b41a4d6c500412e10090c050b41d2d6c500412d10090c040b41ffd6c500412a10090c030b41a9d7c500411f10090c020b41c8d7c500412e10090c010b0240200a450d002009102e0b2012450d002011102e0b20024190046a240042010f0b102d000b8f0806027f017e047f017e017f017e230041c0006b22022400024002402001450d00200220003602080c010b200241c8ecc5003602080b2002200136020c200241206a200241086a103f0240024002400240024020022802202203450d002002200229022422043702142002200336021020024101360238200241ddf4c10036023c200241206a200241106a200241386a104b024002400240200228022022054105470d0041002100200241003602380c010b2002412c6a2802002101200241286a2802002106024020050d00200220022802242200360238200241306a28020021070c020b410021002002410036023820054101470d002001450d002006102e0b0b410110292205450d012002428180808010370224200220053602200240024020000d00200541003a00000c010b200541013a00002001200241206a104702402001450d002000200141286c6a210803402000200241206a104a200041206a29030021090240024020022802242205200228022822016b4108490d00200228022021050c010b200141086a220a2001490d0820054101742201200a200a2001491b22014100480d080240024020050d002001102921050c010b200228022020052001102a21050b2005450d062002200136022420022005360220200228022821010b2002200141086a360228200520016a20093700002008200041286a2200470d000b0b0240024020022802242200200228022822016b4104490d00200228022021000c010b200141046a22052001490d0620004101742201200520052001491b22014100480d060240024020000d002001102921000c010b200228022020002001102a21000b2000450d052002200136022420022000360220200228022821010b2002200141046a360228200020016a20073600000b2004422088a72101200235022821092002350220210b024020022802382200450d002006450d002000102e0b2004a7210a02402001450d00200141246c21002003210103400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b0240200a450d002003102e0b200241c0006a24002009422086200b840f0b200241346a41023602002002411c6a411c36020020024202370224200241d4f1c1003602202002411c360214200241f8f3c1003602102002410036023c200241c8ecc5003602382002200241106a3602302002200241386a360218200241206a41e4f1c100106a000b41014101102c000b20014101102c000b20014101102c000b102d000ba40904027f017e067f027e230041c0006b22022400024002402001450d00200220003602080c010b200241c8ecc5003602080b2002200136020c200241206a200241086a103f02400240024002400240024020022802202203450d002002200229022422043702142002200336021020024101360238200241ddf4c10036023c200241206a200241106a200241386a104b4100210502400240200228022022014105470d000c010b200241346a2802002106200241306a28020021002002412c6a2802002107200241286a280200210820022802242109024020014101470d00200821050c010b20010d002008450d002009102e0b4105410120051b220810292201450d012002410136022820022008360224200220013602200240024020050d00200141003a00000c010b200141013a00000240024020022802242208200228022822016b4104490d00200228022021080c010b200141046a220a2001490d0720084101742201200a200a2001491b22014100480d070240024020080d002001102921080c010b200228022020082001102a21080b2008450d042002200136022420022008360220200228022821010b2002200141046a360228200820016a20093600002000200241206a104702402000450d002005200041286c6a210a2005210003402000200241206a104a200041206a290300210b0240024020022802242208200228022822016b4108490d00200228022021080c010b200141086a22092001490d0920084101742201200920092001491b22014100480d090240024020080d002001102921080c010b200228022020082001102a21080b2008450d072002200136022420022008360220200228022821010b2002200141086a360228200820016a200b370000200a200041286a2200470d000b0b0240024020022802242200200228022822016b4104490d00200228022021000c010b200141046a22082001490d0720004101742201200820082001491b22014100480d070240024020000d002001102921000c010b200228022020002001102a21000b2000450d062002200136022420022000360220200228022821010b2002200141046a360228200020016a20063600000b2004422088a721012002350228210b2002350220210c02402005450d002007450d002005102e0b2004a7210902402001450d00200141246c21002003210103400240024020012d0000220841034b0d0002400240024020080e0404000102040b2001410c6a280200450d03200141086a280200102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2001410c6a280200450d01200141086a280200102e0c010b200141086a280200450d00200141046a280200102e0b200141246a21012000415c6a22000d000b0b02402009450d002003102e0b200241c0006a2400200b422086200c840f0b200241346a41023602002002411c6a411c36020020024202370224200241d4f1c1003602202002411c36021420024198f4c1003602102002410036023c200241c8ecc5003602382002200241106a3602302002200241386a360218200241206a41e4f1c100106a000b20084101102c000b20014101102c000b20014101102c000b20014101102c000b102d000bf10303077f017e017f230041306b2202240041082103200241106a41086a220442003703002002420037031041dadcc500411b200241106a1003200241086a200429030037030020022002290310370300410021052002410036021020024110200241106a100821060240024020022802102207417f460d002002200736022420022006360220200241106a200241206a103e024020022802102203450d00200241186a2802002104200228021421052007450d022006102e0c020b41eff0c2004133200241286a4184f4c2001053000b410021040b20024100360218200242013703102004200241106a10470240024002402004450d002003200441286c6a21082003210703402007200241106a104a200741206a29030021090240024020022802142206200228021822046b4108490d00200228021021060c010b200441086a220a2004490d0420064101742204200a200a2004491b22044100480d040240024020060d002004102921060c010b200228021020062004102a21060b2006450d032002200436021420022006360210200228021821040b2002200441086a360218200620046a20093700002008200741286a2207470d000b0b200235021821092002280210210402402005450d002003102e0b200241306a240020094220862004ad840f0b20044101102c000b102d000b7101017f024002400240410810292202450d00200242f02e370000200241084110102a2202450d012002429602370008200241104120102a2202450d02200242e807370018200242e8073700102002ad42808080808004840f0b41084101102c000b41104101102c000b41204101102c000bd40b06017f017e067f017e017f017e230041a0016b22022400200241186a41a9ddc50041131081012002290320210320022802182104200241286a41086a22054200370300200242003703284199ddc5004110200241286a100320024190016a41086a220620052903003703002002200229032837039001200241286a20024190016a10c7022005280200210720022802282108200228022c2109200241086a418addc500410f1081012002290310210a2002280208210b200542003703002002420037032841ffddc500410f200241286a10032006200529030037030020022002290328370390012003420020041b210c2009410020081b21052007410020081b2104200a4200200b1b21032008410820081b2108200241286a20024190016a10c8020240024020022d00284101460d0020024188016a4200370300200241f0006a41106a4200370300200241f0006a41086a4200370300200242003703700c010b20024188016a200241c1006a290000370300200241f0006a41106a200241396a290000370300200241f0006a41086a200241316a290000370300200220022900293703700b200241286a41086a220642003703002002420037032841ccddc5004113200241286a100320024190016a41086a20062903003703002002200229032837039001200220024190016a10c902200241c8006a2004360200200241c4006a2005360200200241d4006a200241f0006a41086a290300370200200241dc006a20024180016a290300370200200241e4006a20024188016a29030037020020022008360240200242e4003703382002200c370330200220033703282002200229037037024c2002410120022d0000220541017120054102461b3a006c2002410036027820024201370370024002400240024002400240410810292205450d002002410836027420022002280278220841086a36027820022005360270200520086a2003370000200229033021030240024020022802742208200228027822056b4108490d00200228027021080c010b200541086a22042005490d0620084101742205200420042005491b22054100480d060240024020080d002005102921080c010b200228027020082005102a21080b2008450d022002200536027420022008360270200228027821050b2002200541086a360278200820056a2003370000200229033821030240024020022802742208200228027822056b4108490d00200228027021080c010b200541086a22042005490d0620084101742205200420042005491b22054100480d060240024020080d002005102921080c010b200228027020082005102a21080b2008450d032002200536027420022008360270200228027821050b2002200541086a360278200820056a20033700002002280240210820022802482205200241f0006a104702402005450d002008200541286c6a210703402008200241f0006a104a200841206a29030021030240024020022802742204200228027822056b4108490d00200228027021040c010b200541086a22062005490d0820044101742205200620062005491b22054100480d080240024020040d002005102921040c010b200228027020042005102a21040b2004450d062002200536027420022004360270200228027821050b2002200541086a360278200420056a20033700002007200841286a2208470d000b0b200241cc006a200241f0006a10ca0202400240200228027420022802782205460d00200228027021080c010b200541016a22082005490d0620054101742204200820082004491b22044100480d060240024020050d002004102921080c010b200228027020052004102a21080b2008450d052002200436027420022008360270200228027821050b2002200541016a360278200820056a20022d006c3a0000200235027821032002350270210a02402002280244450d002002280240102e0b200241a0016a24002003422086200a840f0b41084101102c000b20054101102c000b20054101102c000b20054101102c000b20044101102c000b102d000bcd06020e7f047e230041c0016b2202240020024100360298012001411020024198016a1008210302400240024002400240024002402002280298012204417f470d00200041003602000c010b2002200436021420022003360210200241086a200241106a103120022802080d052002280214220541286e220641286c2201417f4c0d01200228020c21070240024020010d00410821080c010b200110292208450d030b02402007450d00410021090340200241003a00b8012009220a41016a21094100210102400240024002400240034020052001460d0120024198016a20016a2002280210220b2d00003a00002002200b41016a3602102002200141016a220c3a00b801200c2101200c4120470d000b200241f8006a41086a220d20024198016a41086a290300370300200241f8006a41106a220e20024198016a41106a290300370300200241f8006a41186a220f20024198016a41186a290300370300200220022903980137037820022005200c6b2201360214200141074d0d01200241386a41086a200d2903002210370300200241386a41106a200e2903002211370300200241386a41186a200f2903002212370300200241186a41086a220c2010370300200241186a41106a220d2011370300200241186a41186a220e20123703002002200b41096a3602102002200141786a220536021420022002290378221037033820022010370318200b29000121102006200a470d04200a4101742201200920092001491b2206ad42287e2211422088a70d0b2011a722014100480d0b200a0d022001102921080c030b20024100360214200141ff0171450d00200241003a00b8010b200241386a41186a200241d8006a41186a2903003703002006450d0a2008102e0c0a0b2008200a41286c2001102a21080b2008450d060b2008200a41286c6a22012002290318370300200c2903002111200d2903002112200e290300211320012010370320200141186a2013370300200141106a2012370300200141086a201137030020092007470d000b0b2008450d052000200636020420002008360200200041086a20073602002004450d002003102e0b200241c0016a24000f0b1032000b20014108102c000b20014108102c000b102d000b41eff0c200413320024198016a4184f4c2001053000bcb0201057f230041d0006b220224002002410036022820014110200241286a1008210302400240024020022802282204417f460d0020030d010b200041003a00000c010b41002101200241003a00480340024020042001470d000240200141ff0171450d00200241003a00480b41eff0c2004133200241286a4184f4c2001053000b200241286a20016a200320016a2d00003a00002002200141016a22053a00482005210120054120470d000b200241086a41186a2201200241286a41186a290300370300200241086a41106a2205200241286a41106a290300370300200241086a41086a2206200241286a41086a2903003703002002200229032837030802402004450d002003102e0b20002002290308370001200041013a0000200041196a2001290300370000200041116a2005290300370000200041096a20062903003700000b200241d0006a24000b960101037f230041106b220224002002410036020420014110200241046a100821010240024020022802042203417f460d002001450d00200241003a000202402003450d0020012d00002104200241003a000320034101460d0020012d000121032001102e0c020b41eff0c2004133200241086a4184f4c2001053000b410221040b200020033a0001200020043a0000200241106a24000b952801057f02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2202280200200141086a22032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00003a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00013a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00023a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00033a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00043a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00053a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00063a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00073a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00083a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00093a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d0f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000e3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1020012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000f3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00103a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00113a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00123a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00133a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00143a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00153a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00163a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00173a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00183a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00193a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006102921050c010b200128020020042006102a21050b2005450d1f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001e3a000002400240200228020020032802002202460d00200128020021040c010b200241016a22042002490d2120024101742205200420042005491b22054100480d210240024020020d002005102921040c010b200128020020022005102a21040b2004450d2020012004360200200141046a2005360200200141086a28020021020b2003200241016a360200200420026a20002d001f3a00000f0b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20054101102c000b102d000bce0302097f037e230041306b22022400200241206a41086a22034200370300200242003703204199ddc5004110200241206a1003200241106a41086a2003290300370300200220022903203703102002200241106a10c70202400240200228020022040d004101210541002106410021070c010b200228020421084100210602400240200241086a280200220341286c22090d0041012105410021070c010b0240200941286d220741ffffff3f712007470d00200741057422094100480d002009102922050d0120094101102c000b102d000b02402003450d00200341286c210a4100210620052103200421090340200941086a290000210b200941106a290000210c2009290000210d200341186a200941186a290000370000200341106a200c370000200341086a200b3700002003200d370000200641016a2106200341206a2103200941286a2109200a41586a220a0d000b0b2008450d002004102e0b20024100360228200242013703202006200241206a104702402006450d00200641057421092005210303402003200241206a104a200341206a2103200941606a22090d000b0b2002350228210b2002280220210302402007450d002005102e0b200241306a2400200b4220862003ad840bc90c03047f017e067f23004180026b220224000240024020010d002002200136020c200241c8ecc5003602080c010b20022001417f6a36020c410121032002200041016a36020820002d0000220141014b0d0041002104410021000240024002400240024002400240024020010e020100010b2002200241086a103120022802000d07200228020c220120022802042200490d072000417f4c0d010240024020000d00410121040c010b200010342204450d03200420022802082205200010f6041a2002200120006b36020c2002200520006a3602080b2004450d07200241106a20042000ad22064220862006842206422088a710cd0220022802104101460d03200241186a280200210520022802142100410021030b2002200536021420022000360210200241e7e485f3063602b001200241d0016a41186a22074200370300200241d0016a41106a22084200370300200241d0016a41086a22094200370300200242003703d00141002101200241106a410020001b210a0240024020000d004100210b0c010b200a41046a280200210c200a280200210b0b200241b0016a200b41c8ecc500200b1b200c4100200b1b200241d0016a1016200241f0006a41186a2007290300370300200241f0006a41106a2008290300370300200241f0006a41086a2009290300370300200220022903d0013703702002200536021420022000360210200241e2c289ab063602b001200742003703002008420037030020094200370300200242003703d0010240024020000d000c010b200a41046a280200210b200a28020021010b200241b0016a200141c8ecc50020011b200b410020011b200241d0016a101720024190016a41186a2207200241d0016a41186a220129030037030020024190016a41106a2208200241d0016a41106a220b29030037030020024190016a41086a2209200241d0016a41086a220a290300370300200220022903d00137039001200220053602fc01200220003602f801200241e9dabdf3063602f40120014200370300200b4200370300200a4200370300200242003703d0010240024020000d00410021000c010b200241f8016a410020001b220041046a2802002105200028020021000b200241f4016a200041c8ecc50020001b2005410020001b200241d0016a1017200241b0016a41186a22002001290300370300200241b0016a41106a2201200b290300370300200241b0016a41086a2205200a290300370300200241106a41086a200241f0006a41086a290300370300200241106a41106a200241f0006a41106a290300370300200241106a41186a200241f0006a41186a290300370300200220022903d0013703b00120022002290370370310200241c8006a2007290300370300200241c0006a2008290300370300200241386a20092903003703002002200229039001370330200241e8006a2000290300370300200241e0006a2001290300370300200241d8006a2005290300370300200220022903b001370350200241003602d801200242013703d001200241106a200241d0016a104a200241306a200241d0016a104a200241d0006a200241d0016a104a20022802d801210020022802d401210a20022802d001210b024020032006a745720d002004102e0b200041046a2201417f4c0d000240024020010d00410121050c010b200110292205450d040b2002410036021820022001360214200220053602102000200241106a10470240024020022802142205200228021822016b2000490d00200228021021050c010b200120006a22042001490d0620054101742207200420042007491b22044100480d060240024020050d002004102921050c010b200228021020052004102a21050b2005450d0520022004360214200220053602100b200520016a200b200010f6041a200120006a21000240200a450d00200b102e0b20024180026a24002000ad4220862005ad840f0b1032000b20004101102c000b200220022902143703d00141a4f1c1004116200241d0016a41bcf1c1001053000b20014101102c000b20044101102c000b102d000b200241dc016a411c360200200241246a410236020020024202370214200241d4f1c1003602102002411c3602d401200241b8f4c1003602d001200241003602b401200241c8ecc5003602b0012002200241d0016a3602202002200241b0016a3602d801200241106a41e4f1c100106a000b850804057f017e017f017e02400240024002402002450d00410020016b410020014103711b2103200241796a4100200241074b1b210441002105034002400240200120056a2d000022064118744118752207417f4a0d0042808080801021080240200641b6eac5006a2d0000417e6a220941024d0d0042808080808020210a0c070b0240024002400240024020090e03000102000b200541016a22062002490d024200210a0c090b4200210a200541016a220920024f0d08200120096a2d0000210902400240200641a07e6a2206410d4b0d000240024020060e0e0002020202020202020202020201000b200941e0017141a001460d0242808080808020210a0c0c0b02402009411874411875417f4c0d0042808080808020210a0c0c0b200941ff017141a001490d0142808080808020210a0c0b0b02402007411f6a41ff0171410b4b0d0002402009411874411875417f4c0d0042808080808020210a0c0c0b200941ff017141c001490d0142808080808020210a0c0b0b0240200941ff017141bf014d0d0042808080808020210a0c0b0b0240200741fe017141ee01460d0042808080808020210a0c0b0b2009411874411875417f4c0d0042808080808020210a0c0a0b42002108200541026a220620024f0d09200120066a2d000041c00171418001460d020c070b4200210a200541016a220920024f0d07200120096a2d0000210902400240200641907e6a220641044b0d000240024020060e050002020201000b200941f0006a41ff01714130490d0242808080808020210a0c0b0b02402009411874411875417f4c0d0042808080808020210a0c0b0b200941ff0171419001490d0142808080808020210a0c0a0b0240200941ff017141bf014d0d0042808080808020210a0c0a0b02402007410f6a41ff017141024d0d0042808080808020210a0c0a0b2009411874411875417f4c0d0042808080808020210a0c090b200541026a220620024f0d07200120066a2d000041c00171418001470d0642002108200541036a220620024f0d08200120066a2d000041c00171418001460d01428080808080e000210a42808080801021080c080b42808080808020210a4280808080102108200120066a2d000041c00171418001470d070b200641016a21050c010b0240200320056b4103710d000240200520044f0d000340200120056a220641046a280200200628020072418081828478710d01200541086a22052004490d000b0b200520024f0d010340200120056a2c00004100480d022002200541016a2205470d000c040b0b200541016a21050b20052002490d000b0b20002001360204200041086a2002360200200041003602000f0b428080808080c000210a42808080801021080c010b420021080b2000200a2008842005ad84370204200041013602000b130020004101360204200041b8f5c1003602000b3400200041b8f6c10036020420004100360200200041146a4105360200200041106a41c8f6c100360200200041086a420f3702000b02000b2201017f230041106b220224002002410036020020002002109901200241106a24000b130020004101360204200041d0fdc1003602000b34002000419981c20036020420004100360200200041146a4107360200200041106a41a081c200360200200041086a42073702000b2f01017f02404101102922020d0041014101102c000b200042818080801037020420002002360200200241003a00000b130020004101360204200041e48cc2003602000b880201057f230041106b22022400024002400240411110292203450d002002421137020420022003360200410d200210470240024020022802042204200228020822036b410d490d002003410d6a2105200228020021040c010b2003410d6a22052003490d0320044101742206200520052006491b22064100480d030240024020040d002006102921040c010b200228020020042006102a21040b2004450d0220022006360204200220043602000b20022005360208200420036a220341002900e1f441370000200341056a41002900e6f44137000020002002290300370200200041086a2002280208360200200241106a24000f0b41114101102c000b20064101102c000b102d000ba504010b7f230041106b220324002003420037030820012002200341086a102420032003290308370300200120026a21040240024002400240200241086a220520024f0d00200341086a2106200321074100210841002105410121094100210a0340200841017421022006200741016a220b6b210c034020072d00002107024002400240024020082005470d002008417f417f200c200420016b6a22052005200c491b220541016a220d200d2005491b6a22052008490d072002200520052002491b22054100480d070240024020080d002005102921090c010b200920082005102a21090b2009450d010b200920086a20073a00000240024002400240200a41ff01710e03010300010b20042001460d010c050b0240200b2006460d004100210a0c040b20042001470d040b200841016a21080c090b4101210a200b2006470d01200841016a21080c080b20054101102c000b200841016a2108200b21070c020b200841016a21084102210a200241026a21022001220741016a21010c000b0b0b410121092005450d0120054100480d002005102922090d0120054101102c000b102d000b410021080340200920086a200320086a2d00003a0000200841016a22084108470d000b024020020d00410821080c010b200920086a2107410021080340200720086a200120086a2d00003a00002002200841016a2208470d000b200420016b41086a21080b200020083602082000200536020420002009360200200341106a24000bef0702067f017e230041106b220224002002410036020820024201370300200028020021030240024002400240024002400240410410292204450d0020024284808080c0003702042002200436020020042003360000200028020421050240024020022802042206200228020822046b4104490d00200441046a2103200228020021060c010b200441046a22032004490d0720064101742207200320032007491b22074100480d070240024020060d002007102921060c010b200228020020062007102a21060b2006450d0220022007360204200220063602000b20022003360208200620046a200536000020002802082103200041106a28020022042002104702402004450d002003200441286c6a2107034020032002104a200341206a29030021080240024020022802042206200228020822046b4108490d00200228020021060c010b200441086a22052004490d0920064101742204200520052004491b22044100480d090240024020060d002004102921060c010b200228020020062004102a21060b2006450d052002200436020420022006360200200228020821040b2002200441086a360208200620046a20083700002007200341286a2203470d000b0b0240024020002802144101460d0002400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d0920044101742206200320032006491b22064100480d090240024020040d002006102921030c010b200228020020042006102a21030b2003450d062002200636020420022003360200200228020821040b2002200441016a360208200320046a41003a00000c010b02400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d0820044101742206200320032006491b22064100480d080240024020040d002006102921030c010b200228020020042006102a21030b2003450d062002200636020420022003360200200228020821040b2002200441016a360208200320046a41013a0000200028021821060240024020022802042203200228020822046b4104490d00200228020021030c010b200441046a22052004490d0820034101742204200520052004491b22044100480d080240024020030d002004102921030c010b200228020020032004102a21030b2003450d072002200436020420022003360200200228020821040b2002200441046a360208200320046a20063600000b2002280204210420012802002001280204200228020022032002280208100402402004450d002003102e0b200241106a24000f0b41044101102c000b20074101102c000b20044101102c000b20064101102c000b20064101102c000b20044101102c000b102d000baa6408017f017e017f017e1a7f017e037f027e230041e0056b22002400107f200041a0016a41bcddc500411010810120002903a801210120002802a001210220004190016a41a9ddc500411310810102400240024042002001420020021b220120002903980142002000280290011b7d220320032001561b42e400540d0020004188016a41b8dfc5004114107d200028028c0121042000280288012105200041c8046a41086a22024200370300200042003703c80441dbdfc5004115200041c8046a1003200041b0056a41086a2002290300370300200020002903c8043703b005200041003602c803200041b0056a4110200041c8036a1008210202400240024002400240024002400240024020002802c8032206417f470d00410221070c010b024020020d00410221070c010b2006450d0120022d000021072002102e0b41ccdfc500410f109c012108200041c8046a41086a22024200370300200042003703c80441ec8ec2004112200041c8046a1003200041b0056a41086a2002290300370300200020002903c8043703b005200041003602c803200041b0056a4110200041c8036a100821090240024002400240024002400240024002400240024020002802c803220a417f460d002009450d002000200a3602fc04200020093602f80420004180016a200041f8046a10312000280280010d1320002802fc04220b41807f712202417f4c0d11200028028401210c02400240200b410776220d0d004101210e0c010b20021029220e450d0b0b0240200c450d00200041c8036a41206a210f200041e0026a4101722110410021110340200041003a008003201141016a21124100210202400240024002400340200b2002460d01200041e0026a20026a20002802f80422062d00003a00002000200641016a3602f8042000200241016a22063a0080032006210220064120470d000b200041c0026a41086a2202200041e0026a41086a290300370300200041c0026a41106a2213200041e0026a41106a290300370300200041c0026a41186a2214200041e0026a41186a290300370300200020002903e0023703c0022000200b20066b3602fc04200041e0026a200041f8046a107820002d00e0024101460d01200041c8036a41186a2014290300370300200041c8036a41106a2013290300370300200041c8036a41086a2002290300370300200020002903c0023703c803200f201041e00010f6041a200041c0016a200041c8036a41800110f6041a200d2011470d0320114101742202201220122002491b220d41ffffff0f71200d470d1a200d410774220241004e0d020c1a0b200041003602fc04200241ff0171450d00200041003a0080030b200d450d17200e102e0c170b0240024020110d0020021029210e0c010b200e20114107742002102a210e0b200e450d050b200e20114107746a200041c0016a41800110f6041a2012200c460d0120002802fc04210b201221110c000b0b200e450d13200a450d012009102e0c010b4101210e4100210c4100210d0b4100210202400240200c41077422060d0041012115410021160c010b2006410276220b10292215450d08200641077621160b0240200e200e20066a22174622180d00200c410774210b20152102200e2106034020022006290000370000200241186a200641186a290000370000200241106a200641106a290000370000200241086a200641086a290000370000200241206a210220064180016a2106200b41807f6a220b0d000b200c41077441807f6a41077641016a21020b200041c8046a41086a22064200370300200042003703c80441fff4c1004112200041c8046a1003200041b0056a41086a2006290300370300200020002903c8043703b005200041003602d003200042013703c8032002200041c8036a104702402002450d00200241057421062015210203402002200041c8036a104a200241206a2102200641606a22060d000b0b2004410020051b210220002802cc032106200041b0056a411020002802c803220b20002802d003100402402006450d00200b102e0b200041b0016a200241026a10da020240024020002802b00122190d002008200841ff0171410247712108200041c8046a41086a22064200370300200042003703c80441fff4c1004112200041c8046a1003200041b0056a41086a2006290300370300200020002903c8043703b005200041003602c803200041b0056a4110200041c8036a1008210b024020002802c8032211417f460d00200b450d00200020113602c4012000200b3602c001200041c8036a200041c0016a103020002802c8032205450d09200041d0036a280200210620002802cc03211a02402011450d00200b102e0b4100211b0c020b41002106410121054100211a4100211b0c010b200041b8016a28020021064101211b20002802b401211a20192105410121080b200041c8046a41086a220b4200370300200042003703c80441b8dfc5004114200041c8046a1003200041b0056a41086a200b290300370300200020002903c8043703b0054101211c2000200241016a220a3602c803200041b0056a4110200041c8036a410410044100211202400240200641057422020d004100211d0c010b2002410575221d41ffffff0f71201d470d13201d410774220b4100480d13200b1029221c450d060b0240200520026a2005460d0020064105742111200041c0016a4101722104200041c8036a41206a210941002112201c2113200521020340200241086a2900002101200241106a29000021032002290000211e200041b0056a41186a2214200241186a290000370300200041b0056a41106a220c2003370300200041b0056a41086a220f20013703002000201e3703b005200041f8046a200041b0056a1077200028028005210b20002802f8042106200041003602c0012006200b200041c0016a1008210b0240024020002802c0012210417f470d004100210b0c010b0240200b0d004100210b0c010b200020103602cc042000200b3602c804200041c0016a200041c8046a107820002d00c0014101460d07200041e0026a200441e00010f6041a02402010450d00200b102e0b200041c0016a200041e0026a41e00010f6041a4101210b0b024020002802fc04450d002006102e0b02400240200b0d00200041e0026a410041e00010f5041a0c010b200041e0026a200041c0016a41e00010f6041a0b200241206a2102200041c8036a41086a200f290300370300200041c8036a41106a200c290300370300200041c8036a41186a2014290300370300200020002903b0053703c8032009200041e0026a41e00010f6041a201241016a21122013200041c8036a41800110f6044180016a2113201141606a22110d000b0b0240201a450d002005102e0b201241ffffff0f712012470d0f20124107742202417f4c0d0f0240024020020d004101210c0c010b20021029220c450d040b4100210202402012450d00201c20124107746a211441807f201c6b210f200041c8036a41e0006a2106200041c8036a41c0006a210b200041c8036a41206a2111200c2113201c21020340200041c8036a41186a200241186a290000370300200041c8036a41106a200241106a290000370300200041c8036a41086a200241086a290000370300200020022900003703c803201141186a200241386a290000370000201141106a200241306a290000370000201141086a200241286a2900003700002011200241206a290000370000200b41186a200241d8006a290000370000200b41106a200241d0006a290000370000200b41086a200241c8006a290000370000200b200241c0006a2900003700002006200241e0006a290000370000200641086a200241e8006a290000370000200641106a200241f0006a290000370000200641186a200241f8006a2900003700002013200041c8036a41800110f6044180016a211320024180016a22022014470d000b201c20124107746a200f6a41077641016a21020b200041c8046a41086a22064200370300200042003703c80441ec8ec2004112200041c8046a1003200041b0056a41086a2006290300370300200020002903c8043703b005200041003602d003200042013703c8032002200041c8036a104702402002450d00200c20024107746a2106200c210203402002200041c8036a104a200241206a200041c8036a104a200241c0006a200041c8036a104a200241e0006a200041c8036a104a20024180016a22022006470d000b0b20002802cc032102200041b0056a411020002802c803220620002802d003100402402002450d002006102e0b02402012450d00200c102e0b200020083a00c803200041c8046a41086a22024200370300200042003703c80441dbdfc5004115200041c8046a1003200041b0056a41086a2002290300370300200020002903c8043703b005200041b0056a4110200041c8036a410110042000200a3602cc03200041043a00c80341c8ecc5004100200041c8036a1072410810292206450d02200620173602042006200e3602002007200741ff017141024771450d0a0240024020180d002006200e4180016a22143602002000200e2900223701ca032000200e29002a3701d203200041c0026a41086a220220002903d0033703002000200e2900323701da03200041c0026a41106a220b20002903d8033703002000200e28003a3601e2032000200e2f003e3b01e603200041c0026a41186a221120002903e003370300200041003a00e8032000200e2d00213a00c9032000200e2d00203a00c803200020002903c8033703c002200041c8046a41186a22132011290300370300200041c8046a41106a2211200b290300370300200041c8046a41086a220b2002290300370300200020002903c0023703c804200041c0016a41186a22022013290300370300200041c0016a41106a22132011290300370300200041c0016a41086a2211200b290300370300200020002903c8043703c001200e0d010b2006102e4108210f41002114410021024108210b0c0d0b200041e0026a41186a2002290300370300200041e0026a41106a2013290300370300200041e0026a41086a2011290300370300200020002903c0013703e002201720146b41077641016a220241286c220b417f4c0d0f200b1029220f450d01200f20002903e002370300200f4201370320200f41186a200041e0026a41186a221f290300370300200f41106a200041e0026a41106a2220290300370300200f41086a200041e0026a41086a222129030037030002402006280200220b2006280204221a470d0041012114200f210b0c0c0b2006200b4180016a22183602002000200b2900223701ca032000200b29002a3701d203200041c0026a41086a221020002903d0033703002000200b2900323701da03200041c0026a41106a220920002903d8033703002000200b28003a3601e2032000200b2f003e3b01e603200041c0026a41186a220420002903e003370300200041003a00e8032000200b2d00213a00c9032000200b2d00203a00c803200020002903c8033703c002200041c8046a41186a220b2004290300370300200041c8046a41106a22112009290300370300200041c8046a41086a22132010290300370300200020002903c0023703c804200041c0016a41186a2205200b290300370300200041c0016a41106a22072011290300370300200041c0016a41086a220a2013290300370300200020002903c8043703c0014102211441c800210c0340201f200529030022013703002020200729030022033703002021200a290300221e370300200020002903c00122223703e002200b2001370300201120033703002013201e370300200020223703c80402400240024002402014417f6a2002460d00200221080c010b201a20186b41077620026a41016a22082002490d162002410174221a20082008201a491b2208ad42287e2201422088a70d162001a7221a4100480d160240024020020d00201a1029210f0c010b200f200241286c201a102a210f0b200f450d010b200f200c6a221a41606a220220002903c8043703002013290300210120112903002103200b290300211e201a4201370300200241186a201e370300200241106a2003370300200241086a2001370300200628020022022006280204221a470d01200f210b200821020c0e0b201a4108102c000b200620024180016a2218360200200020022900223701ca032000200229002a3701d203201020002903d003370300200020022900323701da03200920002903d8033703002000200228003a3601e203200020022f003e3b01e603200420002903e003370300200041003a00e803200020022d00213a00c903200020022d00203a00c803200020002903c8033703c002200b20042903003703002011200929030037030020132010290300370300200020002903c0023703c8042005200b29030037030020072011290300370300200a2013290300370300200020002903c8043703c001200c41286a210c201441016a2114200821020c000b0b20024101102c000b200b4108102c000b41084104102c000b20024101102c000b41eff0c2004133200041c0026a4184f4c2001053000b200b4101102c000b41eff0c2004133200041c0026a4184f4c2001053000b200b4101102c000b20024101102c000b41eff0c2004133200041c0026a4184f4c2001053000b2006102e0c020b2006102e0b200041c8046a41086a22064200370300200042003703c80441dadcc500411b200041c8046a1003200041b0056a41086a2006290300370300200020002903c8043703b005200041003602c803200041b0056a4110200041c8036a100821060240024020002802c8032213417f460d002006450d00200020133602c401200020063602c001200041c8036a200041c0016a103e20002802c8032210450d03200041d0036a280200211120002802cc0321092013450d012006102e0c010b4100210941082110410021110b0240024020142011470d00200b2010460d01201441016a21112010210603402011417f6a2211450d02200b2006412010f8040d01200641206a2113200b41206a210c200641286a2106200b41286a210b200c2903002013290300510d000b0b200041c8046a41086a22064200370300200042003703c8044191f5c1004117200041c8046a1003200041b0056a41086a220b2006290300370300200020002903c8043703b005200041c8036a200041b0056a411010c601024020002802c80322114101470d00200041b0056a411010060b200041c8036a41086a280200210c20002802cc03211320064200370300200042003703c80441ba8ec200411d200041c8046a1003200b2006290300370300200020002903c8043703b005200041b0056a411041c8ecc500410041001005210602400240024020114101460d0002402006417f470d00200041f8006a41b0f3c200410d107d200028027c21062000280278210b200041c8036a41106a2014360200200041d4036a2002360200200041003602dc032000200f3602d003200041003602cc03200020064100200b1b3602c803200041c8046a41086a22064200370300200042003703c80441ba8ec200411d200041c8046a1003200041b0056a41086a2006290300370300200020002903c8043703b005200041103602c4012000200041b0056a3602c001200041c8036a200041c0016a10d8020b20020d010c020b02402006417f470d00200041f0006a41b0f3c200410d107d200028027421062000280270210b200041e8006a41fe8ec200411a107d20064100200b1b210602402000280268450d00200028026c20064b0d010b200041c8046a41086a220b4200370300200042003703c80441fe8ec200411a200041c8046a1003200041b0056a41086a2211200b290300370300200020002903c8043703b0052000200620134101746a3602c803200041b0056a4110200041c8036a41041004200041e0036a200c360200200041c8036a41106a2014360200200041d4036a2002360200200041013602dc032000200f3602d003200020133602cc03200020063602c803200b4200370300200042003703c80441ba8ec200411d200041c8046a10032011200b290300370300200020002903c8043703b005200041103602c4012000200041b0056a3602c001200041c8036a200041c0016a10d8020b2002450d010b200f102e0b2009450d012010102e0c010b02402009450d002010102e0b2002450d00200f102e0b0240410810292202450d00200220173602042002200e360200024041081029221f450d00201f201c20124107746a2220360204201f201c360200200041d8006a418addc500410f10810102402000290360420020002802581b220142017c22222001540d00200041c8046a41086a22064200370300200042003703c804418addc500410f200041c8046a1003200041c0016a41086a220b2006290300370300200020002903c8043703c001200020223703c803200041c0016a4110200041c8036a41081004200041e8046a200241988fc200104320002802ec04211420002802e804211320002802f004210220064200370300200042003703c8044199ddc5004110200041c8046a1003200b2006290300370300200020002903c8043703c001200041003602d003200042013703c8032002200041c8036a1047024002402002450d002013200241286c6a21122013210603402006200041c8036a104a200641206a29030021010240024020002802cc03220b20002802d00322026b4108490d0020002802c803210b0c010b200241086a22112002490d0b200b4101742202201120112002491b22024100480d0b02400240200b0d0020021029210b0c010b20002802c803200b2002102a210b0b200b450d03200020023602cc032000200b3602c80320002802d00321020b2000200241086a3602d003200b20026a20013700002012200641286a2206470d000b0b20002802cc032102200041c0016a411020002802c803220620002802d003100402402002450d002006102e0b02402014450d002013102e0b200041c8006a41bcddc50041101081012000290350210120002802482102200041386a41a9ddc5004113108101024042002001420020021b22032000290340420020002802381b22017d221e201e2003561b42e400540d00034042002003427f200142e4007c221e201e2001541b22017d221e201e2003561b42e300560d000b0b200041c8046a41086a22024200370300200042003703c80441a9ddc5004113200041c8046a1003200041c0016a41086a22062002290300370300200020002903c8043703c001200020013703c803200041c0016a4110200041c8036a410810040240202242017c22032022540d0020024200370300200042003703c804418edec5004113200041c8046a100320062002290300370300200020002903c8043703c001200041c8036a200041c0016a10c8020240024020002d00c8034101460d0020004190056a420037030020004188056a420037030020004180056a4200370300200042003703f8040c010b20004190056a200041e1036a29000037030020004188056a200041d9036a29000037030020004180056a200041d1036a290000370300200020002900c9033703f8040b200041306a41a1dec5004111107d2000280234210220002802302106200041c8046a41086a220b4200370300200042003703c80441a1dec5004111200041c8046a1003200041c0016a41086a2211200b290300370300200020002903c8043703c001200041003602c803200041c0016a4110200041c8036a41041004200041c0016a41186a200041f8046a41186a290300370300200041c0016a41106a200041f8046a41106a2903003703002011200041f8046a41086a290300370300200020002903f8043703c001417f2002410020061b221041016a220220022010491b410d744128722205417f4c0d060240200510292207450d00200720002903c00137000020072003370020200741186a200041c0016a41186a290300370000200741106a200041c0016a41106a290300370000200741086a200041c0016a41086a290300370000200041d4036a20002902a405370200200041dc036a200041a4056a41086a280200360200200041003602d003200020103602cc03200041003602c803200041003602e003200041e4036a200029029805370200200041ec036a20004198056a41086a280200360200200041c8036a41106a2118200041c8036a41186a211a412821044100210241002111410021144100210f41002113410021064100210b034020002802d403210c20002802dc03211202400240024003400240200b450d0020002802d80322092012460d00200020123602dc03200020023602d0032000200c3602d403200020063602c803201821120c040b0240024002400240200620104f0d00411610292202450d032002410e6a41002900c0de45370000200241086a41002900bade45370000200241002900b2de4537000020024116412c102a220b450d05200b2006360016200041c0026a41186a22024200370300200041c0026a41106a22114200370300200041c0026a41086a22144200370300200042003703c002200b411a200041c0026a1000200041c8046a41186a2002290300370300200041c8046a41106a2011290300370300200041c8046a41086a2014290300370300200020002903c0023703c804200041c0026a200041c8046a10820120002802c0022202450d01200041c8046a4120100620002902c4022101200221110c020b200020123602dc03200020023602d0032000200c3602d403200020063602c803024020002802e00322080d00410021080c060b201a410020081b220a2802082209200a28020c460d05200a41086a21120c060b4200210141012102410121110b200b102e2001422088a7410574210b02402013450d00024020002802d80322132012460d002000201220136b41606a41607120136a41206a3602d8030b200c450d00200f102e0b200641016a21062011200b6a21122001a7210c200020023602d803200221142011210f200221132002210b0c010b0b41164101102c000b412c4101102c000b02402014450d00024020002802d80322022012460d002000201220026b41606a41607120026a41206a3602d8030b200c450d002011102e0b02402008450d000240200041c8036a41206a2802002202200041ec036a2802002206460d002000200620026b41606a41607120026a41206a3602e8030b200041e4036a280200450d002008102e0b200041c0026a41186a22024200370300200041c0026a41106a22064200370300200041c0026a41086a220b4200370300200042003703c00220072004200041c0026a1000200041c8036a41186a22112002290300370300200041c8036a41106a22122006290300370300200041c8036a41086a2213200b290300370300200020002903c0023703c80302402005450d002007102e0b200041c8046a41086a22024200370300200042003703c804418edec5004113200041c8046a1003200041c0016a41086a22062002290300370300200020002903c8043703c001200041103602e4022000200041c0016a3602e002200041c8036a200041e0026a10b802200041b0056a41186a200041f8046a41186a2903002201370300200041b0056a41106a200041f8046a41106a290300221e370300200041b0056a41086a200041f8046a41086a2903002222370300200020002903f80422233703b005201120013703002012201e37030020132022370300200020233703c80320024200370300200042003703c80441ffddc500410f200041c8046a100320062002290300370300200020002903c8043703c001200041103602e4022000200041c0016a3602e002200041c8036a200041e0026a10b802200041c0026a201f419891c2001043200041206a41a9ddc5004113108101200029032821012000280220211120024200370300200042003703c804418edec5004113200041c8046a100320062002290300370300200020002903c8043703c001200041c8036a200041c0016a10c8020240024020002d00c8034101460d00200041f8026a4200370300200041f0026a4200370300200041e8026a4200370300200042003703e0020c010b200041f8026a200041e1036a290000370300200041f0026a200041d9036a290000370300200041e8026a200041d1036a290000370300200020002900c9033703e0020b200041c8046a41086a22024200370300200042003703c80441ccddc5004113200041c8046a1003200041c0016a41086a22062002290300370300200020002903c8043703c001200041186a200041c0016a10c90220002d0019211220002d0018211341dfddc5004120109c01210b20024200370300200042003703c80441ccddc5004113200041c8046a100320062002290300370300200020002903c8043703c001200041106a200041c0016a10c90220024200370300200042003703c80441ccddc5004113200041c8046a100320062002290300370300200020002903c8043703c001024002400240410210292202450d0020024101201241017120134102461b2206200b410171200b41ff01714102461b220b3a0001200220063a0000200041c0016a41102002410210042002102e200041c8036a41186a42e400370300200041c8036a41106a427f2001420020111b220142e4007c221e201e2001541b370300200041c8036a41206a20002903c002370300200041f0036a200041c0026a41086a280200360200200041f4036a20002903e002370200200041fc036a200041e0026a41086a29030037020020004184046a200041e0026a41106a2903003702002000418c046a200041e0026a41186a29030037020020004194046a200b3a0000200020033703d003200041003602c803200041003602c801200042013703c0010240410110292202450d00200041013602c401200020002802c801220641016a3602c801200020023602c001200220066a41013a000020002903d003210102400240024020002802c401220620002802c80122026b4108490d0020002802c00121060c010b200241086a220b2002490d1220064101742202200b200b2002491b22024100480d120240024020060d002002102921060c010b20002802c00120062002102a21060b2006450d01200020023602c401200020063602c00120002802c80121020b2000200241086a3602c801200620026a200137000020002903d803210102400240024020002802c401220620002802c80122026b4108490d0020002802c00121060c010b200241086a220b2002490d1320064101742202200b200b2002491b22024100480d130240024020060d002002102921060c010b20002802c00120062002102a21060b2006450d01200020023602c401200020063602c00120002802c80121020b2000200241086a3602c801200620026a200137000020002903e003210102400240024020002802c401220620002802c80122026b4108490d0020002802c00121060c010b200241086a220b2002490d1420064101742202200b200b2002491b22024100480d140240024020060d002002102921060c010b20002802c00120062002102a21060b2006450d01200020023602c401200020063602c00120002802c80121020b2000200241086a3602c801200620026a2001370000200041c8036a41206a2802002106200041c8036a41286a2802002202200041c0016a1047024002402002450d002006200241286c6a211203402006200041c0016a104a200641206a29030021010240024020002802c401220b20002802c80122026b4108490d0020002802c001210b0c010b200241086a22112002490d17200b4101742202201120112002491b22024100480d1702400240200b0d0020021029210b0c010b20002802c001200b2002102a210b0b200b450d03200020023602c4012000200b3602c00120002802c80121020b2000200241086a3602c801200b20026a20013700002012200641286a2206470d000b0b200041f4036a200041c0016a10ca0202400240024020002802c40120002802c8012202460d0020002802c00121060c010b200241016a22062002490d162002410174220b20062006200b491b220b4100480d160240024020020d00200b102921060c010b20002802c0012002200b102a21060b2006450d012000200b3602c401200020063602c00120002802c80121020b2000200241016a3602c801200620026a20002d0094043a000020004183056a20002802c801360000200020002903c0013700fb04200041cc016a200041ff046a290000370000200041c28289aa043600c101200041023a00c001200020002900f8043700c501200041c0016a109801024020002802c8030d00200041ec036a280200450d0020002802e803102e0b0240410810292212450d00201220173602042012200e3602000240410810292218450d00201820203602042018201c360200200041086a41b8dfc5004114107d200041c8036a200028020c410020002802081b10f60120002802c803220220002802d0031018024020002802cc03450d002002102e0b200041b0f3c200410d107d2000280204210220002802002111200041c8046a41086a22064200370300200042003703c80441d2d7c1004111200041c8046a1003200041c0016a41086a220b2006290300370300200020002903c8043703c00120002002410020111b3602c803200041c0016a4110200041c8036a4104100402402012280200220220122802042211470d002012102e410021024101210f410021130c0b0b201220024180016a2214360200200020022900623701ca032000200229006a3701d203200041c0026a41086a221320002903d003370300200020022900723701da03200041c0026a41106a220c20002903d8033703002000200228007a3601e203200020022f007e3b01e603200041c0026a41186a220f20002903e003370300200020022f00603b01c803200020002903c8033703c002200041c8046a41186a2202200f290300370300200041c8046a41106a220f200c29030037030020062013290300370300200020002903c0023703c804200041c0016a41186a22132002290300370300200041c0016a41106a2202200f290300370300200b2006290300370300200020002903c8043703c001200041b0056a41186a22062013290300370300200041b0056a41106a2002290300370300200041b0056a41086a200b290300370300200020002903c0013703b005410121130240201120146b41077641016a2202410574220b1029220f450d00200f20002903b005370000200f41186a2006290300370000200f41106a200041b0056a41106a290300370000200f41086a200041b0056a41086a2903003700002012280200220620122802042208460d0a201220064180016a221a360200200020062900623701ca032000200629006a3701d203200041c0026a41086a220520002903d003370300200020062900723701da03200041c0026a41106a220720002903d8033703002000200628007a3601e203200020062f007e3b01e603200041c0026a41186a220a20002903e003370300200020062f00603b01c803200020002903c8033703c002200041c8046a41186a2206200a290300370300200041c8046a41106a220b2007290300370300200041c8046a41086a22112005290300370300200020002903c0023703c804200041c0016a41186a22102006290300370300200041c0016a41106a2209200b290300370300200041c0016a41086a22042011290300370300200020002903c8043703c001410221134120210c0340200041e0026a41186a20102903002201370300200041e0026a41106a20092903002203370300200041e0026a41086a2004290300221e370300200020002903c00122223703e00220062001370300200b20033703002011201e370300200020223703c804024002402013417f6a2002460d00200221140c010b2008201a6b41077620026a41016a22142002490d1a20024101742208201420142008491b221441ffffff3f712014470d1a201441057422084100480d1a0240024020020d0020081029210f0c010b200f20024105742008102a210f0b200f0d0020084101102c000b200f200c6a220220002903c804370000200241186a2006290300370000200241106a200b290300370000200241086a201129030037000002402012280200220220122802042208470d00201421020c0c0b201220024180016a221a360200200020022900623701ca032000200229006a3701d203200520002903d003370300200020022900723701da03200720002903d8033703002000200228007a3601e203200020022f007e3b01e603200a20002903e003370300200020022f00603b01c803200020002903c8033703c0022006200a290300370300200b200729030037030020112005290300370300200020002903c0023703c804201020062903003703002009200b29030037030020042011290300370300200020002903c8043703c001200c41206a210c201341016a2113201421020c000b0b200b4101102c000b41084104102c000b41084104102c000b200b4101102c000b20024101102c000b20024101102c000b20024101102c000b20024101102c000b41014101102c000b41024101102c000b2012102e0b200041c8046a41086a22064200370300200042003703c8044183d9c500410d200041c8046a1003200041c0016a41086a2006290300370300200020002903c8043703c001200041003602d003200042013703c8032013200041c8036a104702402013450d002013410574210b200f210603402006200041c8036a104a200641206a2106200b41606a220b0d000b0b20002802cc032106200041c0016a411020002802c803220b20002802d003100402402006450d00200b102e0b02402002450d00200f102e0b2018102e0240201d450d00201c102e0b0240201b201945720d0020002802b401450d002019102e0b02402016450d002015102e0b200d450d0a200e102e0c0a0b2012200941206a360200200041b0056a41086a200941086a2212290000370300200041b0056a41106a200941106a220c290000370300200041b0056a41186a200941186a220a290000370300200020092900003703b005200041c8046a41186a2208200a290000370300200041c8046a41106a220a200c290000370300200041c8046a41086a220c2012290000370300200020092900003703c80402400240200520046b411f4b0d00200441206a22122004490d0d20054101742209201220122009491b22124100480d0d0240024020050d002012102921070c010b200720052012102a21070b2007450d01201221050b200720046a221220002903c804370000201241186a2008290300370000201241106a200a290300370000201241086a200c290300370000200441206a21040c010b0b20124101102c000b20054101102c000b41c08fc00041c900109b01000b20024101102c000b41c08fc00041c900109b01000b41084104102c000b41084104102c000b41eff0c2004133200041c0026a4184f4c2001053000b1032000b200041e0056a24000f0b41eff0c2004133200041c0026a4184f4c2001053000b102d000bdada0109097f017e027f027e0a7f097e027f0a7e2d7f230041f0176b22022400200241a80c6a41086a22034200370300200242003703a80c41b29bc5004110200241a80c6a1003200241e80d6a41086a2003290300370300200220022903a80c3703e80d200241003602c8102001417f6a2104200241e80d6a4110200241c8106a1008210102400240024002400240024002400240024002400240024020022802c8102203417f460d002001450d002003450d0220012d0000220341034f0d022001102e200341014b0d07024020030e020100010b200241a80c6a41086a22014200370300200242003703a80c41b29bc5004110200241a80c6a1003200241e80d6a41086a2001290300370300200220022903a80c3703e80d200241e80d6a411010060c010b20044106700d060b200241a80c6a41086a22014200370300200242003703a80c41fff4c1004112200241a80c6a1003200241e80d6a41086a2001290300370300200220022903a80c3703e80d200241003602c810200241e80d6a4110200241c8106a1008210120022802c8102203417f460d022001450d02200220033602e40b200220013602e00b200241c8106a200241e00b6a103020022802c8102205450d0141082106200241c8106a41086a280200210720022802cc10210802402003450d002001102e0b0240024020070d00410021094100210a0c010b20074105744105752209ad42d0007e220b422088a70d0a200ba722014100480d0a200110292206450d042007410574220741606a410576210c200241c8106a41206a21012006210d200521030340200341086a290000210b200341106a290000210e2003290000210f200241e00b6a41186a2210200341186a290000370300200241e00b6a41106a2211200e370300200241e00b6a41086a2212200b3703002002200f3703e00b200241e80d6a200241e00b6a10e903200241c8106a41186a2010290300370300200241c8106a41106a2011290300370300200241c8106a41086a2012290300370300200120022903e80d370300200141086a200241e80d6a41086a290300370300200141106a200241e80d6a41106a290300370300200141186a200241e80d6a41186a290300370300200141206a200241e80d6a41206a290300370300200141286a200241e80d6a41286a290300370300200220022903e00b3703c810200d200241c8106a41d00010f60441d0006a210d200341206a2103200741606a22070d000b200c41016a210a0b02402008450d002005102e0b200621130c040b41eff0c2004133200241e00d6a4184f4c2001053000b41eff0c2004133200241e00d6a4184f4c2001053000b410821064100210a41002109410821130c010b20014108102c000b200241a80c6a41086a22014200370300200242003703a80c41999bc5004119200241a80c6a1003200241e80d6a41086a2001290300370300200220022903a80c3703e80d200241c8106a200241e80d6a10b303024020022802cc102214450d00200241e80d6a411010060b410021150240024020140d00410421144100211041002116410021110c010b200241d4106a280200211020022802d010211620022802c81021110b200241b00a6a41c5c1c200410d10810120022903b80a210b20022802b00a2101200241a00a6a41e7e7c300411710810120022903a80a210e20022802a00a2103200241a80c6a41086a220c4200370300200242003703a80c41e7e7c3004117200241a80c6a1003200241e80d6a41086a2217200c290300370300200220022903a80c3703e80d2002200b420020011b220b3703c810200241e80d6a4110200241c8106a410810040240200b200e420020031b7d220f500d00200c4200370300200242003703a80c4192e9c3004116200241a80c6a10032017200c290300370300200220022903a80c3703e80d200241003602c810200241e80d6a4110200241c8106a100821010240024020022802c8102203417f460d002001450d00200220033602e40b200220013602e00b200241c8106a200241e00b6a1030024020022802c8102218450d00200241d0106a280200210d20022802cc1021192003450d022001102e0c020b41eff0c2004133200241e00d6a4184f4c2001053000b410121184100210d410021190b200241880a6a41a5bcc40041111070200241880a6a41106a290300211a20022903900a211b20022802880a2101200241f0096a41c28cc00041161070200241e0096a20022903f809420020022802f00922031b221c200241f0096a41106a290300420020031b428094ebdc03420010fc04200241d0096a20022903e009220b200241e0096a41086a290300220e4280ec94a37c427f10fb04200241c0096a201b420020011b201a420020011b200dad420010fb04200f42ffffffff0f8342ffffffff0f200f428080808010541b211d20022903d009201c7c210f200241c0096a41086a290300211e4100210741b0a4c200210320022903c009211f024002400340024041f0a6c200200322016b41304b0d00200141f0a6c200460d032002200128020022033602c8102002418094ebdc033602cc10200241b0096a200b200e200241c8106a2003418094ebdc034b4102746a350200221a420010fb0420022903b009221b201a200f7e428094ebdc038042ffffffff0f837c221a201f5a200241b0096a41086a290300201a201b54ad7c221a201e5a201a201e511b0d03200241a0096a41086a21120c020b2002200128020022033602c8102002418094ebdc033602cc1020024190096a200b200e200241c8106a2003418094ebdc034b4102746a350200221a420010fb04200229039009221b201a200f7e428094ebdc038042ffffffff0f837c221a201f5a20024190096a41086a290300201a201b54ad7c221a201e5a201a201e511b0d022002200128021022033602c8102002418094ebdc033602cc1020024180096a200b200e200241c8106a2003418094ebdc034b4102746a350200221a420010fb040240200229038009221b201a200f7e428094ebdc038042ffffffff0f837c221a201f5a20024180096a41086a290300201a201b54ad7c221a201e5a201a201e511b450d00200121070c030b2002200128022022033602c8102002418094ebdc033602cc10200241f0086a200b200e200241c8106a2003418094ebdc034b4102746a350200221a420010fb04024020022903f008221b201a200f7e428094ebdc038042ffffffff0f837c221a201f5a200241f0086a41086a290300201a201b54ad7c221a201e5a201a201e511b450d00200141106a21070c030b2002200128023022033602c8102002418094ebdc033602cc10200241e0086a200b200e200241c8106a2003418094ebdc034b4102746a350200221a420010fb04200141c0006a2103200141306a210720022903e008221b201a200f7e428094ebdc038042ffffffff0f837c221a201f54200241e0086a41086a290300201a201b54ad7c221a201e54201a201e511b0d000b200141206a21070c010b034041e0a6c20020012207460d01200741106a21012002200741106a28020022033602c8102002418094ebdc033602cc10200241a0096a200b200e200241c8106a2003418094ebdc034b4102746a350200221a420010fb0420022903a009221b201a200f7e428094ebdc038042ffffffff0f837c221a201f5a2012290300201a201b54ad7c221a201e5a201a201e511b450d000b0b42002120200241c0086a201f201e428094ebdc03420010fc04200241b0086a20022903c008221b200241c0086a41086a290300221c4280ec94a37c427f10fb04200741b0a4c20020071b2201410c6a2d00002103200141046a2802002107200141086a28020021012002418094ebdc033602cc10200220013602c810200241c8106a2001418094ebdc034b4102746a350200211a2002418094ebdc033602cc10200220073602c810200241a0086a201b201c200241c8106a2007418094ebdc034b4102746a3502002221420010fb04200241d0086a200b200e201a420010fb0420024190086a420020022903d008220e201a200f7e428094ebdc038042ffffffff0f837c220b20022903a008221a202120022903b008201f7c7e428094ebdc038042ffffffff0f837c220f7d221b201b200b56200241d0086a41086a290300200b200e54ad7c220e200241a0086a41086a290300200f201a54ad7c221b7d200b200f54ad7d221a200e56201a200e511b22011b427f200b200f7c220f200f200b542207200e201b7c2007ad7c220b200e54200b200e511b22071b20031b4200201a20011b427f200b20071b20031b201d420010fb0420024180086a20022903900820024190086a41086a29030042e08f860f420010fc0402400240200d0d00420021220c010b201420104102746a21232018200d4105746a212420024180086a41086a290300212520022903800821262011ad212742002120420021222014210d20182110024002400340200d2023460d0302400240200d2802002201450d00024002400240024002402011450d00200241f0076a202620252027420010fc04200241e0076a20022903f007220b200241f0076a41086a290300220e2027420010fb04200241d0076a200b200e20112001200120114b1bad220f420010fb04202620022903e0077d200f7e202780210b20022903d007210e200241d0076a41086a290300211a411210292201450d0120014100290090e843370000200141106a41002f00a0e8433b0000200141086a4100290098e84337000020024292808080a0023702cc10200220013602c8102010200241c8106a104a20022802cc10210720022802d010210320022802c8102101200241f00a6a41186a22124200370300200241f00a6a41106a22054200370300200241f00a6a41086a22084200370300200242003703f00a20012003200241f00a6a1000200241e80d6a41186a2012290300370300200241e80d6a41106a2005290300370300200241e80d6a41086a22122008290300370300200220022903f00a3703e80d200241003602c810200241e80d6a4120200241c8106a1008210320022802c8102205417f460d032003450d03200220053602cc10200220033602c810200241c8076a200241c8106a103120022802c8070d02200241b0076a200241c8106a106520022903b007a70d02200241b0076a41106a290300210f20022903b807211b2005450d042003102e0c040b41b8bcc4001058000b41124101102c000b41eff0c2004133200241e00d6a4184f4c2001053000b4200211b4200210f0b201a200e200b42ffffffff0f837c220b200e54ad7c210e02402007450d002001102e0b4200211a200242003703f00d200242003703e80d02400240200b201b200b201b200b54200f200e54200f200e511b22011b22287d2229200e200f200e20011b222a7d200b202854ad7d222b8450450d004200210b0c010b200241c8106a201010e903200241c8106a41086a290300220b420020022903c810220e420156200b420052200b501b22011b210b200e420120011b210e20022802e81021050240024020022802f01022010d00200241a8066a200e200b428094ebdc03420010fc04200241a8066a41086a290300212c20022903a806212d0c010b2005200141306c6a2107200241a0076a200e200b428094ebdc03420010fc0420024180076a2029202b428094ebdc03420010fc0420024190076a2029202b428094ebdc03420010fd04200241a0076a41086a290300222c420020022903a007222d420156202c420052202c501b22011b211a202d420120011b211b20024180076a41086a290300211d2002290380072121200229039007212e200521010340200241f0066a200e2001290300220f200f200e56200141086a290300220f200b56200f200b511b22031b200b200f20031b201b201a10fc0420022903f006221c428080808010544100200241f0066a41086a290300501b450d04200241e0066a200e200b201b201a10fc0420022903e006220f428080808010544100200241e0066a41086a290300501b450d060240200fa7450d00200241b8066a2021201d201c42ffffffff0f83428094ebdc037e200f42ffffffff0f838042ffffffff0f83220f420010fb04200241c8066a200141106a20022903b806221c200f202e7e428094ebdc038042ffffffff0f837c220f200241b8066a41086a290300200f201c54ad7c10ea03200241e80d6a20022903c80620022903d006200241c8066a41106a29030010a601200141306a22012007460d020c010b0b41a4f1c2001058000b20024198066a200e20022903d810220f200f200e56200241c8106a41186a290300220f200b56200f200b511b22011b200b200f20011b202d4201202d420156202c420052202c501b22011b220f202c420020011b221a10fc04200229039806221b42808080801054410020024198066a41086a290300501b450d0220024188066a200e200b200f201a10fc04200229038806220b42808080801054410020024188066a41086a290300501b450d04200ba7450d05200241f8056a2029202b428094ebdc03420010fc04200241e8056a20022903f805220e200241f8056a41086a290300220f4280ec94a37c427f10fb04200241d8056a200e200f201b42ffffffff0f83428094ebdc037e200b42ffffffff0f838042ffffffff0f83220b420010fb0420022903d805220e200b202920022903e8057c7e428094ebdc038042ffffffff0f837c221a200e54ad210b200241d8056a41086a290300210e024020022802ec10450d002005102e0b200e200b7c210b0b200241c0056a2010201a20287c220e200b202a7c200e201a54ad7c10ea03200241e80d6a20022903c00520022903c805200241c0056a41106a29030010a601427f202220122903007c202020022903e80d7c220e2020542201ad7c220b2001200b202254200b2022511b22011b2122427f200e20011b21200b200d41046a210d201041206a22102024470d010c040b0b10b403000b10b503000b41a4f1c2001058000b02402016450d002014102e0b200241e0106a2022370300200241c8106a41106a2020370300200241c8106a41086a41003a0000200241033a00c81041c8ecc5004100200241c8106a1072200241a8056a41c28cc00041161070200241a8056a41106a290300210b20022903b005210e20022802a8052101200241a80c6a41086a22034200370300200242003703a80c41c28cc0004116200241a80c6a1003200241e80d6a41086a2003290300370300200220022903a80c3703e80d2002427f200b420020011b220b20227c200e420020011b220e20207c220f200e542201ad7c220e2001200e200b54200e200b511b22011b3703d0102002427f200f20011b3703c810200241e80d6a4110200241c8106a4110100402402020202284500d00201f201e84500d00200241e00b6a41086a22014200370300200242003703e00b41c28cc0004116200241e00b6a1003200241e80d6a41086a2001290300370300200220022903e00b3703e80d20024190056a200241e80d6a109701200229039805420020022802900522011b220b201f7d220f200b56200241a0056a290300420020011b220e201e7d200b201f54ad7d220b200e56200b200e511b0d0020024180056a200f200b201f201e10fc04200241d0046a20024180056a41086a290300220b42002020420010fb04200241e0046a20224200200229038005220e420010fb04200241f0046a200e42002020420010fb04200b42005220224200527120022903d8044200527220022903e80442005272200241f0046a41086a290300220b20022903d00420022903e0047c7c220e200b54720d0020022903f004210b200241e00b6a41086a22014200370300200242003703e00b41c28cc0004116200241e00b6a1003200241e80d6a41086a22072001290300370300200220022903e00b3703e80d200241b8046a200241e80d6a109701200241b8046a41106a290300210f20022903c004211a20022802b804210320014200370300200242003703e00b41c28cc0004116200241e00b6a100320072001290300370300200220022903e00b3703e80d2002427f200f420020031b220f200e7c200b201a420020031b221a7c221c201a542203ad7c221b2003201b200f54201b200f511b22031b3703d0102002427f201c20031b3703c810200241e80d6a4110200241c8106a41101004200241c8106a108701200241a8046a200241c8106a201a427f85200b20031b220b200f427f85200e20031b220f106d200241a8046a41086a290300211a20022903a804210e20024190046a41c28cc00041161070200b200e7d200e200b7d200e200b58201a200f58201a200f5122031b220d1b211d200f201a7d200b200e54ad7d201a200f7d200e200b54ad7d200d1b212120024190046a41106a2903004200200228029004220d1b211b2002290398044200200d1b211c02400240200e200b56201a200f5620031b0d0020074200370300200242003703e80d41c28cc0004116200241e80d6a100320012007290300370300200220022903e80d3703e00b20024200201b20217d201c201d54ad7d220b201c201d7d220e201c56200b201b56200b201b511b22011b3703f00d20024200200e20011b3703e80d200241e80d6a21010c010b200241a80c6a41086a22034200370300200242003703a80c41c28cc0004116200241a80c6a100320012003290300370300200220022903a80c3703e00b2002427f201b20217c201c201d7c220e201c542201ad7c220b2001200b201b54200b201b511b22011b3703f00d2002427f200e20011b3703e80d200241e80d6a21010b200241e00b6a41102001411010040b410121152019450d002018102e0b20024188046a41e49ac5004112107d2002280288042101200228028c042103200c4200370300200242003703a80c41e49ac5004112200241a80c6a10032017200c290300370300200220022903a80c3703e80d2002200341016a410120011b22233602c810200241e80d6a4110200241c8106a4104100420024180046a41f69ac5004123107d200c4200370300200242003703a80c41f69ac5004123200241a80c6a10032017200c290300370300200220022903a80c3703e80d200220043602c810200241e80d6a4110200241c8106a41041004024002400240024002400240024002400240024002400240024002400240202341a105490d00200241a80c6a41086a22014200370300200242003703a80c41c29bc5004112200241a80c6a1003200241e80d6a41086a2001290300370300200220022903a80c3703e80d200241003602c810200241e80d6a4110200241c8106a1008211702400240024002400240024020022802c8102218417f460d002017450d00200220183602cc10200220173602c810200241f8036a200241c8106a103120022802f8030d1820022802cc1022104178712201417f4c0d1220022802fc0321080240024002400240201041037622240d00410421050c010b200110292205450d010b02402008450d00410021114100210d410021070340200241003602e00b02400240024020104104490d0020022010417c6a22103602cc10200220022802c810220141046a3602c81020012800002112200241003602e00b20104104490d00200741016a210320022010417c6a22103602cc102002200141086a3602c8102001280004210120072024470d022011200320032011491b222441ffffffff01712024470d202024410374220c41004e0d010c200b2024450d1e2005102e0c1e0b0240024020070d00200c102921050c010b2005200d200c102a21050b2005450d040b2005200d6a22072012360200200741046a2001360200201141026a2111200d41086a210d2003210720082003470d000b0b2005450d1a02402018450d002017102e0b20082024470d040c030b20014104102c000b200c4104102c000b41002108410421050b200841016a22012008490d1720084101742203200120012003491b222441ffffffff01712024470d17202441037422014100480d170240024020080d002001102921050c010b200520084103742001102a21050b2005450d010b202341e07a6a2103200520084103746a22012004360204200120233602002005200841016a221141037422076a210d410021010240200741194f0d00200521070c020b20052110024003402010220728020020034f0d040240200741086a2802002003490d00200141016a21010c050b0240200741106a2802002003490d00200141026a21010c050b200741186a28020020034f0d01200141046a2101200d200741206a22106b41184b0d000b200741206a21070c020b200141036a21010c020b20014104102c000b2007200d460d000340200728020020034f0d01200141016a2101200d200741086a2207470d000b0b0240024002400240024020112001490d00201120016b2211450d0402402001450d002005200520014103746a201141037410f7041a0b20052802042108200241a80c6a41086a22014200370300200242003703a80c41a5dfc5004113200241a80c6a1003200241e80d6a41086a2001290300370300200220022903a80c3703e80d200241c8106a200241e80d6a411010c601024020022802c8104101470d000240200241c8106a41086a280200220c2008200c2008491b221220022802cc1022034f0d00200321120c050b0240200320124f0d000340411a10292201450d04200141186a41002f00f482403b0000200141106a41002900ec8240370000200141086a41002900e48240370000200141002900dc82403700002001411a4134102a2201450d052001200336001a200241f00a6a41186a22074200370300200241f00a6a41106a220d4200370300200241f00a6a41086a22104200370300200242003703f00a2001411e200241f00a6a1000200241900b6a41186a2007290300370300200241900b6a41106a200d290300370300200241900b6a41086a2010290300370300200220022903f00a3703900b200241900b6a412010062001102e200341016a2201210320122001470d000b0b200c20084b0d040b200241a80c6a41086a22014200370300200242003703a80c41a5dfc5004113200241a80c6a1003200241e80d6a41086a2001290300370300200220022903a80c3703e80d200241e80d6a411010060c040b418cc6c5001058000b411a4101102c000b41344101102c000b200241a80c6a41086a22014200370300200242003703a80c41a5dfc5004113200241a80c6a1003200241e80d6a41086a2001290300370300200220022903a80c3703e80d410810292201450d022001200c36000420012012360000200241e80d6a41102001410810042001102e0b200241a80c6a41086a22014200370300200242003703a80c41c29bc5004112200241a80c6a1003200241e80d6a41086a2001290300370300200220022903a80c3703e80d200241003602d010200242013703c8102011200241c8106a10470240024020110d0020022802d010210120022802cc10210720022802c81021030c010b200520114103746a2104410020022802d01022116b210d20022802cc102107410021010340201120016a2110200520016a22122802002108024002402007200d6a4104490d0020022802c81021030c010b201041046a22032010490d162007410174220c20032003200c491b220c4100480d160240024020070d00200c102921030c010b20022802c8102007200c102a21030b2003450d052002200c3602cc10200220033602c810200c21070b2002201041046a220c3602d010200320116a20016a2008360000201241046a280200210802402007200d6a417c6a41034b0d00200c41046a2223200c490d162007410174220c20232023200c491b220c4100480d160240024020070d00200c102921030c010b20032007200c102a21030b2003450d062002200c3602cc10200220033602c810200c21070b2002201041086a3602d010200320116a20016a41046a2008360000200d41786a210d200141086a2101201241086a2004470d000b201120016a21010b200241e80d6a411020032001100402402007450d002003102e0b2024450d002005102e0b200241f0036a41989ac5004116107d20022802f403212f20022802f0032130200241e8036a41ae9ac500411d107d20022802ec03213120022802e8032132200241f00a6a41186a22034200370300200241f00a6a41106a22074200370300200241f00a6a41086a220d4200370300200242003703f00a41f8e8c300411a200241f00a6a1000200241e80d6a41186a22102003290300370300200241e80d6a41106a22112007290300370300200241e80d6a41086a2212200d290300370300200220022903f00a3703e80d200241c8106a200241e80d6a412010dc01412810292201450d03200141c8ecc500360200200120022903c810370204200120022f00e00b3b00252001410c6a200241c8106a41086a290300370200200141146a200241c8106a41106a2903003702002001411c6a200241c8106a41186a290300370200200141246a200241c8106a41206a2d00003a0000200141276a200241e00b6a41026a22052d00003a00002003420037030020074200370300200d4200370300200242003703f00a41dee8c300411a200241f00a6a100020102003290300370300201120072903003703002012200d290300370300200220022903f00a3703e80d200241c8106a200241e80d6a412010dc01412810292233450d04203341c8ecc500360200203320022903c810370204203320022f00e00b3b00252033410c6a200241c8106a41086a2203290300370200203341146a200241c8106a41106a22072903003702002033411c6a200241c8106a41186a220d290300370200203341246a200241c8106a41206a22102d00003a0000203341276a20052d00003a0000200242003702bc0d200241e08dc0003602b80d200241003602d80d200242083703d00d200241e80c6a411c6a200241b80d6a360200200241e80c6a41186a200241e00d6a360200200241003602f80c200241d0bcc4003602ec0c200220013602e80c2002200241d00d6a3602fc0c2002200241e00d6a3602f40c2002200241e00d6a3602f00c200241c8106a200241e80c6a10810202400240024020022d00881122114102470d00200241023a00a80e0c010b200241a80c6a41386a2212200241c8106a41386a290300370300200241a80c6a41306a2205200241c8106a41306a290300370300200241a80c6a41286a2208200241c8106a41286a290300370300200241a80c6a41206a220c2010290300370300200241a80c6a41186a2210200d290300370300200241a80c6a41106a220d2007290300370300200241a80c6a41086a22072003290300370300200241900b6a41086a220320024191116a22232900003703002002419f0b6a222420024198116a290000370000200220022903c8103703a80c20022002290089113703900b20024184116a2012290300370200200241fc106a2005290300370200200241f4106a2008290300370200200241ec106a200c290300370200200241e4106a2010290300370200200241dc106a200d290300370200200241d4106a2007290300370200200241013602f80c200220022903a80c3702cc10200241e00b6a200241c8106a41c40010f6041a200241003602c810200241c8106a410472200241e00b6a41c40010f6041a200241c8106a41c8006a20113a0000202320022903900b37000020024199116a2003290300370000200241a0116a2024290000370000200241e80d6a200241e80c6a41146a200241c8106a10c20320022d00a80e4102470d010b2001102e41082134410021354108210541082118410021080c0b0b200241c8106a200110eb0341c80010292234450d052034200241e80d6a41c80010f6041a200241880d6a41186a200241e80c6a41186a290300370300200241880d6a41106a200241e80c6a41106a290300370300200241880d6a41086a200241e80c6a41086a290300370300200220022903e80c3703880d200241c8106a200241880d6a108102024020022d00881122054102470d0041012108410121350c090b200241c8106a41046a210120024191116a210d200241c8106a41047221362002419c0d6a213720024189116a211020022802980d21384102211141c8002107410021034101213502400340200241a80c6a41386a2212200241c8106a41386a290300370300200241a80c6a41306a2208200241c8106a41306a290300370300200241a80c6a41286a220c200241c8106a41286a290300370300200241a80c6a41206a2223200241c8106a41206a290300370300200241a80c6a41186a2224200241c8106a41186a290300370300200241a80c6a41106a2204200241c8106a41106a290300370300200241a80c6a41086a2217200241c8106a41086a290300370300200241900b6a41086a2218201041086a290000370300200241900b6a410f6a22192010410f6a290000370000200220022903c8103703a80c200220102900003703900b200141386a2012290300370200200141306a2008290300370200200141286a200c290300370200200141206a2023290300370200200141186a2024290300370200200141106a2004290300370200200141086a2017290300370200200120022903a80c3702002002203820036a221241016a3602980d200241e00b6a200241c8106a41c40010f6041a200220123602c8102036200241e00b6a41c40010f6041a200d20022903900b370000200d41086a2018290300370000200d410f6a2019290000370000200220053a009011200241e80d6a2037200241c8106a10c20320022d00a80e4102460d01200241c8106a200241e80d6a41c80010f6041a0240200341016a22122035470d00200241e00b6a20022802880d200228028c0d280210110000201241016a22052012490d152011200520052011491b2235ad42c8007e220b422088a70d15200ba722054100480d15024002402003417f470d002005102921340c010b203420072005102a21340b2034450d090b203420076a200241c8106a41c80010f6041a201141026a2111200741c8006a2107200241c8106a200241880d6a1081022012210320022d00881122054102460d090c000b0b200341016a2108203421050c090b41084101102c000b200c4101102c000b200c4101102c000b41284104102c000b41284104102c000b41c8004108102c000b20054108102c000b201241016a21080b20342105200241023a00a80e0b20022802880d2203200228028c0d220128020011010002402001280204450d002003102e0b200521180b200241e80d6a203310d603024020022802880e2236450d00200241e00b6a41017221370240024002400240034020022802900e2124200228028c0e2138200241880d6a41186a2239200241e80d6a41186a290300370300200241880d6a41106a223a200241e80d6a41106a290300370300200241880d6a41086a223b200241e80d6a41086a290300370300200220022903e80d3703880d200241e00b6a200241880d6a108202024002400240024020022d00e00b4101460d00200241003602e8100c010b200241a80c6a41186a203741186a290000370300200241a80c6a41106a203741106a290000370300200241a80c6a41086a203741086a290000370300200220372900003703a80c200241c8106a200241a80c6a10830220022802e81022010d010b4200211b4200211c0c010b200241c8106a41186a290300211c20022903d810211b20022802ec10450d002001102e0b2024ad42c8007e220b422088a70d06200ba72201417f4c0d0602400240024020010d00410821170c010b200110292217450d010b02400240202441057422010d00410021230c010b203620016a2119410021232036210403402004221041206a2104200241b80d6a210120022802bc0d2112024003402001280200221141086a210320112f0106220c4105742101410021070240024003402001450d0120102003412010f804220d450d02200141606a2101200741016a2107200341206a2103200d417f4a0d000b2007417f6a210c0b2012450d022012417f6a21122011200c4102746a4194036a21010c010b0b2008201120074102746a41e8026a220128020022034d0d052005200341c8006c6a2203290310210b200341186a290300210e200241d0036a41c28cc00041161070200241c0036a20022903d803200241d0036a41106a290300427f420010fc042008200128020022034d0d06200241b0036a201b201c20022903c003420020022802d00322071b220f4201200f420156200241c0036a41086a290300420020071b220f420052200f501b22071b200f420020071b10fc042005200341c8006c6a220341186a427f200e200b20022903b0037c220f200b542207ad7c221a2007201a200e54200f200b5a1b22071b3703002003427f200f20071b370310200241900b6a41186a2203201041186a290000370300200241900b6a41106a2207201041106a290000370300200241900b6a41086a220d201041086a290000370300200220102900003703900b20012802002110024020242023470d00202441016a22012024490d1220244101742211200120012011491b2201ad42c8007e220b422088a70d12200ba722114100480d120240024020240d002011102921170c010b2017202441c8006c2011102a21170b2017450d08200121240b2017202341c8006c6a2201420037030020012010360220200141186a4200370300200141106a4200370300200141086a4200370300200120022903900b3702242001412c6a200d290300370200200141346a20072903003702002001413c6a2003290300370200202341016a21230b20042019470d000b0b200241f00a6a41186a22012039290300370300200241f00a6a41106a2203203a290300370300200241f00a6a41086a2207203b290300370300200220022903880d3703f00a20024198036a41c28cc0004116107020024188036a20022903a00320024198036a41106a290300427f420010fc04200241f8026a201b201c2002290388034200200228029803220d1b220b4201200b42015620024188036a41086a2903004200200d1b220b420052200b501b220d1b200b4200200d1b10fc04200241e80c6a41086a220d2007290300370300200241e80c6a41106a22072003290300370300200241e80c6a41186a22032001290300370300200220022903f00a3703e80c20022903f802210b02402038450d002036102e0b2017450d06200241c8106a41186a22102003290300370300200241c8106a41106a22112007290300370300200241c8106a41086a2207200d290300370300200220022903e80c3703c810024020022802d80d220320022802d40d470d00200241e80d6a203310eb0320022802d40d220120022802d80d220d6b417f20022802e80d221241016a220c200c2012491b22124f0d00200d20126a2212200d490d0f2001410174220d20122012200d491b220dad42d0007e220e422088a70d0f200ea722124100480d0f0240024020010d002012102921010c010b20022802d00d200141d0006c2012102a21010b2001450d062002200d3602d40d200220013602d00d0b20022802d00d200341d0006c6a22012017360220200120022903c81037022c200141286a2023360200200141246a202436020020014200370310200142003703082001200b370300200141186a4200370300200141346a20072903003702002001413c6a2011290300370200200141c4006a20102903003702002002200341016a3602d80d200241e80d6a203310d60320022802880e22360d010c060b0b20014108102c000b41849ec300200320081038000b41b4f5c200200320081038000b20114108102c000b20124108102c000b2033102e0240024020082031410420321b22014101200141014b1b4f0d0002402035450d002034102e0b024020022802d80d2201450d00200141d0006c210320022802d00d41206a210103400240200141046a280200450d002001280200102e0b200141d0006a2101200341b07f6a22030d000b0b024020022802d40d0d00410021370c020b20022802d00d102e410021370c010b2008202f410020301b220120082001491b223a41ffffff3f71203a470d01203a4105742201417f4c0d01024002400240024020010d00410121370c010b200110292237450d010b203aad422c7e220b422088a70d03200ba72201417f4c0d0302400240024020010d00410421320c010b200110292232450d010b0240203a0d00410021314100213c0c030b2005200841c8006c22386a2104200241c8106a41186a2119200241c8106a41106a2136200241c8106a41086a213341002117203a213c034002402008450d002038210103400240201841c0006a2d00000d00200241e8026a427f427f201841106a290300220b4201200b420156201841186a290300220b420052200b501b22031b200b420020031b10fc042018200241e8026a41086a290300370308201820022903e8023703000b201841c8006a2118200141b87f6a22010d000b0b20022802d00d220d20022802d80d220c41d0006c6a2124024002400240024002400240200c450d00200d21100340024020102802282201450d00200141c8006c2107201028022041206a210103402008200128020022034d0d0402402005200341c8006c6a22032d00400d002003290310220e200341186a290300220f84500d00200241d8026a2010290300220b4200428080808010420010fb04200241a8026a42004200200b420010fb04200241c8026a427f20022903d802201041086a290300220b42ffffffff0f83200b5220022903b00242005272200241d8026a41086a290300221a200b42208620022903a8027c7c220b201a547222111b427f200b20111b200e200f10fc04200241b8026a201041146a350200201041186a290300220b42208684200b42208820022903c802200241c8026a41086a29030010fb042003427f2003290300220b20022903b8027c220e200e200b542211200341086a2212290300220b200241b8026a41086a2903007c2011ad7c220e200b54200e200b511b22111b3703002012427f200e20111b3703000b200141c8006a2101200741b87f6a22070d000b0b201041d0006a22102024470d000b0b201741016a21312005200841c8006c6a2110203821032005210103402001210702400240201020016b41d8014d0d00200741c0006a2d00000d01200741c8006a21010c070b0340024020030d00201721310c0c0b200341b87f6a2103200741c0006a2111200741c8006a2201210720112d00000d000b200141b87f6a21070c060b20074188016a2d0000450d03200741d0016a2d0000450d02200341e07d6a2103200741a0026a210120074198026a2d00000d000b410321030c030b41b4f5c200200320081038000b200741d8016a2101410221030c010b20074190016a2101410121030b2007200341c8006c6a21070b024020012010460d00200741086a290300210b2007290300210e0340200141c8006a21030240200141c0006a2d00000d00200141086a290300220f200b2001290300221a200e54200f200b54200f200b511b22101b210b201a200e20101b210e2001200720101b21070b2003210120042003470d000b0b200741013a00400240200c450d002007417c6a2112200741206a210c0340200d41d0006a21230240200d2802282203450d00200d2802202101200341c8006c210303400240024020122001460d00200141246a200c412010f8040d010b200d41186a2210290300210b200741086a2211290300210e20012007290300220f200d290310221a7d3703002001200e200b7d200f201a54ad7d3703082007290300210b20102011290300370300200d200b3703100b200141c8006a2101200341b87f6a22030d000b0b2023210d20232024470d000b0b2019200741386a2900003703002036200741306a2900003703002033200741286a290000370300200220072900203703c81002400240203c2017470d0020174101742201203120312001491b223c41ffffff3f71203c470d0e203c41057422014100480d0e0240024020170d002001102921370c010b203720174105742001102a21370b2037450d010b203720174105746a220120022903c810370000200141186a2019290300370000200141106a2036290300370000200141086a203329030037000020052118203121172031203a4f0d040c010b0b20014101102c000b20014104102c000b20014101102c000b0240024020022802d80d22010d004100213b0c010b20022802d00d2233200141d0006c6a212f410020376b213d2037203141057422396a210c4100213b0340200220332f002c3b01e80d20022033412e6a2d00003a00ea0d20022033413f6a2900003703c8102002203341c4006a2900003700cd10024020332802282201450d002033412c6a211820332802202224200141c8006c6a21382033413b6a2800002130203341376a280000213e203341336a280000213f2033412f6a28000021402024203d6a41246a21044100211941082136410021170240024003402024221141046a2112201141246a2103201141646a2105201141446a2108201141c8006a21242039210d20042110203721010240024003400240024002400240200c20016b41e0004d0d0020032001460d0220012003412010f8040d01200121070c050b0340200d450d06024002402010450d004100210720012003412010f8040d010b200121070b200141206a2101200d41606a210d201041606a21102007450d000c050b0b20122001460d00200141206a22072003412010f804450d0320052001460d00200141c0006a22072003412010f804450d0320082001470d010b200321070c020b200141e0006a2107200d41807f6a210d201041807f6a211020014180016a2223210120072003412010f8040d000b202341606a21070b20182007460d0020072018412010f804450d00024002402033290310221a2011290300220e85203341186a290300220f201141086a290300220b858450450d004200210b428080808010210e0c010b20024198026a200e4200428080808010420010fb0420024188026a42004200200e420010fb040240200b42ffffffff0f83200b522002290390024200527220024198026a41086a290300221b200b4220862002290388027c7c221c201b54724101470d000240201a422088200f42208684221a200f422088220f84500d00200241e8016a200e200b201a200f10fc04200241e8016a41086a290300210b20022903e801210e0c020b41a899c3001058000b200241f8016a200229039802201c201a4201201a420156200f420052200f501b22011b200f420020011b10fc04200241f8016a41086a290300210b20022903f801210e0b2011200e370310201141186a200b370300200220112f00243b01c00b2002201141266a2d00003a00c20b2002201141376a2900003703b00b20022011413c6a2900003700b50b201141336a28000021032011412f6a28000021072011412b6a280000210d201141276a2800002110024020192017470d00201941016a22012019490d1020194101742211200120012011491b2201ad42307e220f422088a70d10200fa722114100480d100240024020190d002011102921360c010b2036201941306c2011102a21360b2036450d03200121190b20022d00c20b211120022f01c00b21122036201741306c6a2201200336000f2001200736000b2001200d36000720012010360003200120123b0100200141026a20113a00002001200e370320200141286a200b370300200120022903b00b370013200141186a20022900b50b370000201741016a21170b200441c8006a210420242038470d000b02402017450d0002400240201741306c22030d004200210b4200210e0c010b203641206a21014200210b4200210e0340200141086a290300200e7c2001290300220e200b7c220b200e54ad7c210e200141306a2101200341506a22030d000b0b200241d8016a4200428080808010200b7d220f200f428080808010564200200e200b42808080801056ad7c7d220b420052200b501b22011b221b4200200b20011b220b2017ad221c420010fc0420022903d801210f0240201b201c544100200b501b0d00200241d8016a41086a290300211a203641206a21012017210303402001427f2001290300220b200f7c220e200e200b542207200141086a220d290300220b201a7c2007ad7c220e200b54200e200b511b22071b370300200d427f200e20071b370300200141306a21012003417f6a22030d000b0b200241c8016a200f200b201c200b10fb040240201b20022903c8017da7220d450d004100210103402036200120177041306c6a2203427f2003290320220b42017c220e200e200b542207200341286a2203290300220f2007ad7c221a200f54200e200b5a1b22071b3703202003427f201a20071b370300200141016a2201200d490d000b0b200220022f01e80d3b01dc0b200220022d00ea0d3a00de0b200220022903c8103703c80b200220022900cd103700cd0b0240203a203b470d00203a41016a2201203a490d0f203a4101742203200120012003491b2201ad422c7e220b422088a70d0f200ba722034100480d0f02400240203a0d002003102921320c010b2032203a412c6c2003102a21320b2032450d032001213a0b20022d00de0b210320022f01dc0b21072032203b412c6c6a2201203036000f2001203e36000b2001203f36000720012040360003200120073b0100200141026a20033a0000200120022903c80b370013200141186a20022900cd0b370000200120173602282001201936022420012036360220203b41016a213b0c030b2019450d022036102e0c020b20114108102c000b20034104102c000b203341d0006a2233202f470d000b0b02402035450d002034102e0b024020022802d80d2201450d00200141d0006c210320022802d00d41206a210103400240200141046a280200450d002001280200102e0b200141d0006a2101200341b07f6a22030d000b0b20022802d40d450d0020022802d00d102e0b20022802c00d211120022802b80d2103024020022802bc0d2201450d00034020032802940321032001417f6a22010d000b0b02402011450d00410021074100210103402011417f6a211102400240200120032f01064f0d00200141016a21010c010b02400240200328020022010d002007ad210b4100210d410021010c010b20033301044220862007ad84210b4101210d0b2003102e200ba7210702400240200b422088a7221020012f01064f0d00200121030c010b034002400240200128020022030d002007ad210b410021030c010b200d41016a210d20013301044220862007ad84210b0b2001102e200ba7210720032101200b422088a7221020032f01064f0d000b0b201041027420036a4198036a28020021030240200d417f6a2201450d00034020032802940321032001417f6a22010d000b0b410021010b20110d000b0b0240200341e08dc000460d00200328020021012003102e2001450d00200128020021032001102e2003450d00024020032802002201450d0003402003102e2001210320012802002207210120070d000b0b2003102e0b024020370d00200241086a41a5bcc400411110700c030b203b412c6c2201412c6e214141002118024002400240024020010d0041082142410021410c010b204141ffffff1f712041470d0a204141067422034100480d0a200310292242450d010b024002402032203220016a2238460d00200241e80d6a410172211141002118204221232032210c0340200241f00a6a41186a2219200c41186a290200370300200241f00a6a41106a2236200c41106a290200370300200241f00a6a41086a2233200c41086a2902003703002002200c2902003703f00a200241e80d6a200c108202024002400240024020022d00e80d4101460d00200241003602e8100c010b200241e00b6a41186a201141186a290000370300200241e00b6a41106a201141106a290000370300200241e00b6a41086a201141086a290000370300200220112900003703e00b200241c8106a200241e00b6a10830220022802e81022010d010b4200211c4200211d0c010b200241c8106a41186a290300211d20022903d810211c20022802ec10450d002001102e0b200c280220210d4100211002400240200c280228222441306c22120d0041082117410021240c010b202441ffffff1f712024470d0d202441067422014100480d0d200110292217450d030b200c412c6a21040240200d200d20126a460d0041002110201721010340200d220341286a290300210e200341206a290300210b200241e80d6a200c108202024002400240024020022d00e80d4101460d00200241003602e8100c010b200241e00b6a41186a201141186a290000370300200241e00b6a41106a201141106a290000370300200241e00b6a41086a201141086a290000370300200220112900003703e00b200241c8106a200241e00b6a10830220022802e81022070d010b4200211a4200211b0c010b200241c8106a41186a290300211b20022903d810211a20022802ec10450d002007102e0b200341306a210d200241a80c6a41086a22074200370300200242003703a80c41c28cc0004116200241a80c6a1003200241e80d6a41086a22052007290300370300200220022903a80c3703e80d200241b0016a200241e80d6a10970120024188016a20022903b801200241b0016a41106a290300427f420010fc04200241e8006a201a201b200229038801420020022802b00122081b220f4201200f42015620024188016a41086a290300420020081b220f420052200f501b22081b200f420020081b10fc0420074200370300200242003703a80c41c28cc0004116200241a80c6a100320052007290300370300200220022903a80c3703e80d20024198016a200241e80d6a109701200241f8006a20022903a00120024198016a41106a290300427f420010fc04200241386a200e42002002290368220f420010fb04200241d8006a200b4200200f420010fb04200241286a42004200200b420010fb04200241c8006a2002290378420020022802980122071b220f4201200f420156200241f8006a41086a290300420020071b220f420052200f501b22071b200f420020071b427f200235025c200241d8006a41086a290300221a200229033820022903287c7c220f422086842002290340200229033084420052200f201a547222071b42ffffffff0f200f42208820071b10fb042001200e3703082001200b370300200141106a2003290300370300200141186a200341086a290300370300200141206a200341106a290300370300200141286a200341186a290300370300200141386a200241c8006a41086a290300370300200141306a2002290348370300200141c0006a2101201041016a2110201241506a22120d000b0b2023201c3703002023201d37030820232017360230202341386a2010360200202341346a2024360200202320022903f00a370310202341186a2033290300370300202341206a2036290300370300202341286a2019290300370300201841016a2118202341c0006a21232004210c20042038470d000b0b200242003702c40a200241e08dc0003602c00a0240203720314105746a22392037460d00200241c8106a4102722143200241f00a6a41136a212f200241900b6a41136a2144200241e80d6a410172210c203721050340200241e80d6a2005108202024002400240024020022d00e80d4101460d00200241003602e8100c010b200241e00b6a41186a200c41186a290000370300200241e00b6a41106a200c41106a290000370300200241e00b6a41086a200c41086a2900003703002002200c2900003703e00b200241c8106a200241e00b6a10830220022802e81022010d010b4200210b4200210e0c010b200241c8106a41186a290300210e20022903d810210b20022802ec10450d002001102e0b200241e00b6a41186a2223200541186a290000370300200241e00b6a41106a2224200541106a290000370300200241e00b6a41086a2204200541086a290000370300200220052900003703e00b0240024002400240024002400240024020022802c00a221041e08dc000460d0020022802c40a21110c010b200241e80d6a410041e00210f5041a200241c8106a410041900410f5041a41f80610292210450d0141002111201041003b010620104100360200201041086a200241e80d6a41e00210f6041a201041e8026a200241c8106a41900410f6041a200241003602c40a200220103602c00a0b200541206a210502400340201041086a2103201041066a210820102f010622124105742101410021070240024003402001450d01200241e00b6a2003412010f804220d450d02200141606a2101200741016a2107200341206a2103200d417f4a0d000b2007417f6a21120b2011450d022011417f6a2111201020124102746a41f8066a28020021100c010b0b2010200741306c6a22014180036a200e370300200141f8026a200b370300200141f0026a200e370300200141e8026a200b37030020014190036a410036020020014188036a220728020021032001418c036a2802002101200742083703002003450d062001450d062003102e0c060b200241e80c6a41186a22012023290300370300200241e80c6a41106a2024290300220f370300200241e80c6a41086a2004290300221a370300200220022903e00b221b3703e80c200220022802c80a41016a3602c80a200241a80c6a41106a223f200f370300200241a80c6a41086a2240201a370300200241a80c6a41186a223420012903003703002002201b3703a80c20082f01002203410b490d03200241e80d6a410041e00210f5041a200241c8106a410041900410f5041a41f80610292201450d01200141003b010620014100360200200141086a200241e80d6a41e00210f6042107200141e8026a200241c8106a41900410f604210d200241900b6a41086a2245201041d0016a290000370300200241900b6a41106a2246201041d8016a290000370300200241900b6a41186a2247201041e0016a290000370300200241c8106a41086a221720104190056a290300370300200241c8106a41106a221920104198056a290300370300200241c8106a41186a2236201041a0056a290300370300200241c8106a41206a2233201041a8056a290300370300200241c8106a41286a2238201041b0056a290300370300200220102900c8013703900b20022010290388053703c8102007201041e8016a20102f010641796a220341057410f6042107200d201041b8056a200341306c10f604210d201041063b0106200120033b0106200220022f01900b3b01dc0b200220022d00920b3a00de0b200220442900003703c80b2002204441056a22482900003700cd0b20022800930b214920022800970b214a200228009b0b214b200228009f0b214c200241e80d6a41286a224d2038290300370300200241e80d6a41206a224e2033290300370300200241e80d6a41186a224f2036290300370300200241e80d6a41106a22502019290300370300200241e80d6a41086a22512017290300370300200220022903c8103703e80d0240024020124107490d00201241057420076a41c07e6a2007201241796a22114105746a2207200341ffff037120116b41057410f7041a200741186a2034290300370000200741106a203f290300370000200741086a2040290300370000200720022903a80c370000201241306c200d6a220341e07d6a200341b07d6a2203200141066a22082f010020116b41306c10f7041a200341186a200e3703002003200b3703102003200e3703082003200b370300200341286a4100360200200342083703200c010b201041086a20124105746a220341206a200320082f010020126b41057410f7041a200341186a2034290300370000200341106a203f290300370000200341086a2040290300370000200320022903a80c370000201041e8026a201241306c6a220341306a200320082f010020126b41306c10f7041a200341186a200e3703002003200b3703102003200e3703082003200b370300200341286a4100360200200342083703200b200820082f010041016a3b0100200241d00d6a41026a220320022d00de0b3a000020042051290300370300202420502903003703002023204f290300370300200241e00b6a41206a223d204e290300370300200241e00b6a41286a2235204d290300370300200220022f01dc0b3b01d00d200220022903c80b3703f00a200220022900cd0b3700f50a200220022903e80d3703e00b200241880d6a41286a22522035290300370300200241880d6a41206a2253203d290300370300200241880d6a41186a22542023290300370300200241880d6a41106a22552024290300370300200241880d6a41086a22562004290300370300200220022903e00b3703880d200220022f01d00d3b01c00b200220032d00003a00c20b200220022903f00a3703b00b200220022900f50a3700b50b0240201028020022110d00200241c00a6a2103200121070c050b20102f0104213041002157200121580340200241e00d6a41026a225920022d00c20b3a0000200220022f01c00b3b01e00d200220022903b00b3703d00d200220022900b50b3700d50d20352052290300370300203d2053290300370300202320542903003703002024205529030037030020042056290300370300200220022903880d3703e00b203041ffff0371211202400240024020112f01062201410b490d002043410041a20710f5041a41a8071029220d450d06200d4100360200200d41046a200241c8106a41a40710f6041a2047201141e0016a2900003703002046201141d8016a2900003703002045201141d0016a290000370300200220112900c8013703900b2038201141b0056a2903003703002033201141a8056a2903003703002036201141a0056a290300370300201920114198056a290300370300201720114190056a29030037030020022011290388053703c810200d41086a201141e8016a20112f0106220341796a220141057410f604215a200d41e8026a201141b8056a200141306c10f604215b200d41f8066a20114194076a2003417a6a220841027410f604213e201141063b0106200d20013b010602402008450d0041002101203e210303402003280200220720013b01042007200d360200200341046a21032008200141016a2201470d000b0b204d2038290300370300204e2033290300370300204f20362903003703002050201929030037030020512017290300370300200220022903c8103703e80d200220022f01900b3b01dc0b200220022d00920b3a00de0b20022900930b210b200229009b0b210e200220482900003700cd0b200220442900003703c80b202f20022903c80b370000202f41056a220820022900cd0b370000200220022d00de0b3a00f20a200220022f01dc0b3b01f00a2002200e3700fb0a2002200b3700f30a2038204d2903003703002033204e2903003703002036204f2903003703002019205029030037030020172051290300370300200220022903e80d3703c810203041ffff037122034107490d01205a2012417a6a22074105746a205a201241796a22014105746a2203200d2f010620016b41057410f7041a200341186a20022900d50d3700002003204c36000f2003204b36000b2003204a36000720032049360003200341026a20592d00003a0000200320022f01e00d3b0000200320022903d00d370013201241306c205b6a220341e07d6a200341b07d6a2203200d2f0106223020016b41306c10f7041a200341286a2035290300370300200341206a203d290300370300200341186a2023290300370300200341106a2024290300370300200341086a2004290300370300200320022903e00b370300200d203041016a22033b010620124102742230203e6a416c6a203e20074102746a2212200341ffff037120076b41027410f7041a201220583602002007200d2f010622124b0d02200d20306a41e0066a2103034020032802002207200141016a22013b01042007200d360200200341046a210320012012490d000c030b0b201141086a2203201241016a22074105746a200320124105746a2203200120126b220d41057410f7041a2003204c36000f2003204b36000b2003204a36000720032049360003200341026a20592d00003a0000200320022f01e00d3b0000200320022903d00d370013200341186a20022900d50d3700002011201241306c6a22034198036a200341e8026a2208200d41306c10f7041a20034190036a203529030037030020034188036a203d29030037030020034180036a2023290300370300200341f8026a2024290300370300200341f0026a2004290300370300200820022903e00b3703002011200141016a22013b01062012410274201141f8066a22036a41086a200320074102746a2203200141ffff037120076b41027410f7041a200320583602000240201220112f010622014f0d00205820073b010420582011360200200720014f0d002001417f6a210d20112007417f6a22014102746a4180076a2103034020032802002207200141026a3b010420072011360200200341046a2103200d200141016a2201470d000b0b41001a200241c00a6a1a20101a0c080b201141086a2201201241016a22074105746a200120124105746a220120112f0106223020126b223e41057410f7041a2001204c36000f2001204b36000b2001204a36000720012049360003200141026a20592d00003a0000200120022f01e00d3b0000200120022903d00d370013200141186a20022900d50d370000201141e8026a201241306c6a220141306a2001203e41306c10f7041a200141286a2035290300370300200141206a203d290300370300200141186a2023290300370300200141106a2024290300370300200141086a2004290300370300200120022903e00b3703002011203041016a22013b01062012410274223e201141f8066a22306a41086a203020074102746a2230200141ffff037120076b41027410f7041a20302058360200200320112f010622074f0d002011203e6a41fc066a2101034020012802002203201241016a22123b010420032011360200200141046a210120072012470d000b0b205741016a2112200241cc0d6a41026a220120022d00f20a3a000020402017290300370300203f201929030037030020342036290300370300200241a80c6a41206a22032033290300370300200241a80c6a41286a22072038290300370300200220022f01f00a3b01cc0d200220022903c8103703a80c2002202f2900003703b80d200220082900003700bd0d20022800f30a214920022800f70a214a20022800fb0a214b20022800ff0a214c2052200729030037030020532003290300370300205420342903003703002055203f29030037030020562040290300370300200220022903a80c3703880d200220022f01cc0d3b01c00b200220012d00003a00c20b200220022903b80d3703b00b200220022900bd0d3700b50b0240201128020022010d0020111a200241c00a6a22031a200d21070c060b20112f01042130200241c00a6a1a20111a20012111200d2158201221570c000b0b41f8064108102c000b41f8064108102c000b41a8074108102c000b201020124105746a220141286a200141086a2207200320126b41057410f7041a200141206a2034290300370000200141186a203f290300370000200141106a2040290300370000200720022903a80c3700002010201241306c6a22014198036a200141e8026a220320102f010620126b41306c10f7041a20014190036a410036020020014188036a420837030020014180036a200e370300200141f8026a200b370300200141f0026a200e3703002003200b370300201020102f010641016a3b01060c010b2043410041a20710f5041a024041a80710292201450d0020014100360200200141046a200241c8106a41a40710f6041a20012003280200220d3602f806200320013602002003200328020441016a360204200d41003b0104200d2001360200200120012f0106220d4105746a220341086a20022f01c00b3b00002003410a6a20022d00c20b3a0000200341176a204c360000200341136a204b3600002003410f6a204a3600002003410b6a20493600002003411b6a20022903b00b370000200341206a20022900b50b3700002001200d41306c6a220341e8026a20022903880d370300200341f0026a2056290300370300200341f8026a205529030037030020034180036a205429030037030020034188036a205329030037030020034190036a2052290300370300200141f8066a200d41016a22034102746a2007360200200120033b0106200720033b01042007200136020020101a0c010b41a8074108102c000b20052039470d000b0b20184106742201450d02204220016a21172042210403402004450d030240024020042802382201450d002004280230222320014106746a2124200441106a210c03402023220841106a2110200841c0006a2123200241c00a6a210120022802c40a2112024003402001280200221141086a210320112f010622054105742101410021070240024003402001450d0120102003412010f804220d450d02200141606a2101200741016a2107200341206a2103200d417f4a0d000b2007417f6a21050b2012450d022012417f6a2112201120054102746a41f8066a21010c010b0b2011200741306c6a220141e8026a2203427f2003290300220b20082903307c220e200e200b542203200141f0026a2207290300220b200841386a220d2903007c2003ad7c220e200b54200e200b511b22031b3703002007427f200e20031b370300200241c8106a41086a2210200c41086a290000370300200c290000210b200241c8106a41106a2211200c41106a290000370300200241c8106a41186a2212200c41186a2900003703002002200b3703c810200d290300210b2008290330210e20014188036a210d0240024020014190036a220728020022032001418c036a280200460d00200d28020021010c010b200341016a22012003490d1020034101742205200120012005491b2205ad42307e220f422088a70d10200fa722084100480d100240024020030d002008102921010c010b200d280200200341306c2008102a21010b2001450d04200d2001360200200d41046a2005360200200728020021030b2001200341306c6a2201200b3703082001200e370300200120022903c810370310200141186a2010290300370300200141206a2011290300370300200141286a20122903003703002007200728020041016a3602000b20232024470d000b0b200441c0006a22042017470d010c040b0b20084108102c000b20014108102c000b20034108102c000b200241a80c6a41086a22014200370300200242003703a80c4192e9c3004116200241a80c6a1003200241e80d6a41086a2001290300370300200220022903a80c3703e80d200241003602c810200241e80d6a4110200241c8106a100821030240024020022802c8102207417f460d002003450d00200220073602e40b200220033602e00b200241c8106a200241e00b6a1030024020022802c8102204450d00200241d0106a280200210120022802cc1021172007450d022003102e0c020b41eff0c2004133200241e00d6a4184f4c2001053000b4100211741012104410021010b02400240024002402001450d002001410574210c200421100340410f10292201450d04200141002900a2e843370000200141076a41002900a9e8433700002002428f808080f0013702cc10200220013602c8102010200241c8106a104a20022802cc10210820022802d010211120022802c810210d200241f00a6a41186a22014200370300200241f00a6a41106a22034200370300200241f00a6a41086a22074200370300200242003703f00a200d2011200241f00a6a1000200241e80d6a41186a22112001290300370300200241e80d6a41106a22122003290300370300200241e80d6a41086a22052007290300370300200220022903f00a3703e80d200241e80d6a4120100602402008450d00200d102e0b41121029220d450d03200d41002900cce843220b370000200d41106a41002f00dce84322243b0000200d41086a41002900d4e843220e37000020024292808080a0023702cc102002200d3602c8102010200241c8106a104a20022802cc10212320022802d010210820022802c810210d200142003703002003420037030020074200370300200242003703f00a200d2008200241f00a6a1000201120012903003703002012200329030037030020052007290300370300200220022903f00a3703e80d200241206a200241e80d6a4120109a012002280224410020022802201b210802402023450d00200d102e0b024020084102490d0041121029220d450d03200d200b370000200d41106a20243b0000200d41086a200e37000020024292808080a0023702cc102002200d3602c8102010200241c8106a104a20022802cc10212320022802d010212420022802c810210d200142003703002003420037030020074200370300200242003703f00a200d2024200241f00a6a1000201120012903003703002012200329030037030020052007290300370300200220022903f00a3703e80d20022008417f6a3602c810200241e80d6a4120200241c8106a410410042023450d00200d102e0b201041206a2110200c41606a220c0d000b0b02402017450d002004102e0b20022802c00a210d024020022802c40a2201450d00200121030340200d2802f806210d2003417f6a22030d000b03402001417f6a22010d000b0b024020022802c80a22050d00427f210f427f210b0c050b02400240200d2f0106450d00200d41e8026a2110200d41086a2111410121120c010b02400240200d28020022010d004100210741002103410021010c010b200d2f01042107410121030b0240200720012f0106490d000340200341016a210320012f01042207200128020022012f01064f0d000b0b2001200741306c6a41e8026a2110200120074105746a41086a2111200741027420016a41fc066a280200210d410021122003417f6a2201450d000340200d2802f806210d2001417f6a22010d000b0b200241c8106a41106a210c427f210f427f210b0340201041086a2201290300210e2010290300211a200241e00b6a41186a201141186a290000370300200241e00b6a41106a201141106a290000370300200241e00b6a41086a201141086a290000370300200220112900003703e00b20102802282211ad42307e221b422088a70d04201ba72203417f4c0d04201041186a290300211b2001290300211c2010290310211d20102903002121201028022021010240024002400240024020030d00410821080c010b200310292208450d010b0240024020110d00410021070c010b2001201141306c6a211041002107200821030340200320012903003703002003200141086a290300370308200341106a200141106a290300370300200341186a200141186a290300370300200341206a200141206a290300370300200341286a200141286a290300370300200341306a2103200741016a2107200141306a22012010470d000b0b200241c8106a41186a201b3703002002201d3703d810200220213703c810200220073602f010200220113602ec10200220083602e8102002201c3703d010410f10292201450d01200141002900a2e843370000200141076a41002900a9e8433700002002428f808080f0013702ec0d200220013602e80d200241e00b6a200241e80d6a104a20022802ec0d211020022802f00d210120022802e80d2107200241f00a6a41186a22034200370300200241f00a6a41106a22114200370300200241f00a6a41086a22084200370300200242003703f00a20072001200241f00a6a1000200241e80d6a41186a2003290300370300200241e80d6a41106a2011290300370300200241e80d6a41086a2008290300370300200220022903f00a3703e80d200241003602b00c200242013703a80c2002200241c8106a3602880d200241880d6a200241a80c6a106b2002200c3602880d200241880d6a200241a80c6a106b20022802e810210120022802f0102203200241a80c6a104702402003450d00200341306c21030340200141106a200241a80c6a104a200220013602880d200141306a2101200241880d6a200241a80c6a106b200341506a22030d000b0b20022802ac0c2101200241e80d6a412020022802a80c220320022802b00c100402402001450d002003102e0b201a200f542101200e200b512103200e200b54211102402010450d002007102e0b2001201120031b21012005417f6a2105024020022802ec10450d0020022802e810102e0b200e200b20011b210b201a200f20011b210f2005450d0802402012200d2f01064f0d00200d201241306c6a41e8026a2110200d20124105746a41086a2111201241016a21120c040b02400240200d28020022010d004100210741002103410021010c010b200d2f01042107410121030b200720012f0106490d020340200341016a210320012f01042207200128020022012f01064f0d000c030b0b20034108102c000b410f4101102c000b2001200741306c6a41e8026a2110200120074105746a41086a2111200741027420016a41fc066a280200210d410021122003417f6a2201450d000340200d2802f806210d2001417f6a22010d000c010b0b0b41124101102c000b41124101102c000b410f4101102c000b1032000b200241a80c6a41086a22014200370300200242003703a80c41a5bcc4004111200241a80c6a1003200241e80d6a41086a22032001290300370300200220022903a80c3703e80d2002200b3703d0102002200f3703c810200241e80d6a4110200241c8106a4110100420014200370300200242003703a80c4192e9c3004116200241a80c6a100320032001290300370300200220022903a80c3703e80d200241003602d010200242013703c8102031200241c8106a104702402031450d00203720314105746a21032037210103402001200241c8106a104a2003200141206a2201470d000b0b20022802cc102101200241e80d6a411020022802c810220320022802d010100402402001450d002003102e0b20022802c80a211220022802c00a2107024020022802c40a2201450d00034020072802f80621072001417f6a22010d000b0b02402012450d004100210d41002101034002400240200120072f01064f0d002007200141306c6a2203418c036a280200211120034188036a2802002103200141016a21010c010b02400240200728020022010d00200dad210b41002110410021010c010b2007330104422086200dad84210b410121100b2007102e200ba7210d02400240200b422088a7221120012f01064f0d00200121030c010b034002400240200128020022030d00200dad210b410021030c010b201041016a21102001330104422086200dad84210b0b2001102e200ba7210d20032101200b422088a7221120032f01064f0d000b0b201141027420036a41fc066a28020021072003201141306c6a2201418c036a280200211120014188036a280200210302402010417f6a2201450d00034020072802f80621072001417f6a22010d000b0b410021010b2003450d012012417f6a211202402011450d002003102e0b20120d000b0b0240200741e08dc000460d00200728020021012007102e2001450d00200128020021032001102e2003450d00024020032802002201450d0003402003102e2001210320012802002207210120070d000b0b2003102e0b02402018450d0020184106742103204241306a210103400240200141046a280200450d002001280200102e0b200141c0006a2101200341406a22030d000b0b2031ad210b02402041450d002042102e0b200b422086210b203cad210e0240203b450d00203b412c6c2103203241206a210103400240200141046a280200450d002001280200102e0b2001412c6a2101200341546a22030d000b0b200b200e84210b203a450d002032102e0b02402016452015720d002014102e0b20370d010240200a450d00200a41d0006c2103201341c0006a210103400240200141046a280200450d002001280200102e0b200141d0006a2101200341b07f6a22030d000b0b2009450d002006102e0b200041003602000c010b2000200b370204200020373602000240200a450d00200a41d0006c2103201341c0006a210103400240200141046a280200450d002001280200102e0b200141d0006a2101200341b07f6a22030d000b0b2009450d002006102e0b200241f0176a24000f0b41eff0c2004133200241e00d6a4184f4c2001053000b102d000b02000b280020004101360204200041086a200128020420012802006b4107762201360200200020013602000ba50201057f230041d0006b21020240200128020022032001280204470d00200041003602000f0b200120034180016a3602002002200329004237012a2002200329004a370132200241086a41086a220120022903303703002002200329005237013a200241086a41106a220420022903383703002002200328005a360142200220032f005e3b0146200241086a41186a22052002290340370300200220032f00403b012820022002290328370308200241286a41186a22062005290300370300200241286a41106a22052004290300370300200241286a41086a220420012903003703002002200229030837032820002003360200200020022903283702042000410c6a2004290300370200200041146a20052903003702002000411c6a20062903003702000bb905020b7f047e23004190016b22032400024002402001280200220420012802042205460d00200120044180016a22063602002003200441c2006a29000037016a2003200441ca006a290000370172200341c8006a41086a220720032903703703002003200441d2006a29000037017a200341c8006a41106a220820032903783703002003200441da006a280000360182012003200441de006a2f00003b018601200341c8006a41186a22092003290380013703002003200441c0006a2f00003b016820032003290368370348200341286a41186a220a2009290300370300200341286a41106a220b2008290300370300200341286a41086a220c200729030037030020032003290348370328200541807f6a210d02400340200341086a41186a200a290300220e370300200341086a41106a200b290300220f370300200341086a41086a200c2903002210370300200320032903282211370308200341e8006a41186a200e370300200341e8006a41106a200f370300200341e8006a41086a2010370300200320113703682002450d01200d2004460d02200120064180016a22053602002003200641c2006a29000037016a2003200641ca006a290000370172200720032903703703002003200641d2006a29000037017a200820032903783703002003200641da006a280000360182012003200641de006a2f00003b01860120092003290380013703002003200641c0006a2f00003b016820032003290368370348200a2009290300370300200b2008290300370300200c20072903003703002003200329034837032820044180016a21042002417f6a2102200521060c000b0b20002004360200200020032903683702042000410c6a200341f0006a290300370200200041146a200341f8006a2903003702002000411c6a20034180016a2903003702000c010b200041003602000b20034190016a24000b130020004101360204200041bc93c2003602000b3400200041c594c20036020420004100360200200041146a4103360200200041106a41d094c200360200200041086a420a3702000bd10801037f024002400240024002400240024002400240410110292202450d00200220002d00003a0000200241014102102a2202450d01200220002d00013a0001200241024104102a2202450d02200220002d00023a0002200220002d00033a0003200241044108102a2202450d03200220002d00043a0004200220002d00053a0005200220002d00063a0006200220002d00073a0007200241084110102a2202450d04200220002d00083a0008200220002d00093a0009200220002d000a3a000a200220002d000b3a000b200220002d000c3a000c200220002d000d3a000d200220002d000e3a000e200220002d000f3a000f200241104120102a2202450d05200220002d00103a0010200220002d00113a0011200220002d00123a0012200220002d00133a0013200220002d00143a0014200220002d00153a0015200220002d00163a0016200220002d00173a0017200220002d00183a0018200220002d00193a0019200220002d001a3a001a200220002d001b3a001b200220002d001c3a001c200220002d001d3a001d200220002d001e3a001e200220002d001f3a001f2002412041c000102a2202450d06200220002d00203a0020200220002d00213a0021200220002d00223a0022200220002d00233a0023200220002d00243a0024200220002d00253a0025200220002d00263a0026200220002d00273a0027200220002d00283a0028200220002d00293a0029200220002d002a3a002a200220002d002b3a002b200220002d002c3a002c200220002d002d3a002d200220002d002e3a002e200220002d002f3a002f200220002d00303a0030200220002d00313a0031200220002d00323a0032200220002d00333a0033200220002d00343a0034200220002d00353a0035200220002d00363a0036200220002d00373a0037200220002d00383a0038200220002d00393a0039200220002d003a3a003a200220002d003b3a003b200220002d003c3a003c200220002d003d3a003d200220002d003e3a003e200220002d003f3a003f02400240200141046a2802002203200141086a28020022006b41c000490d00200128020021030c010b200041c0006a22042000490d0920034101742200200420042000491b22004100480d090240024020030d002000102921030c010b200128020020032000102a21030b2003450d0820012003360200200141046a2000360200200141086a28020021000b200141086a200041c0006a360200200320006a220041386a200241386a290000370000200041306a200241306a290000370000200041286a200241286a290000370000200041206a200241206a290000370000200041186a200241186a290000370000200041106a200241106a290000370000200041086a200241086a290000370000200020022900003700002002102e0f0b41014101102c000b41024101102c000b41044101102c000b41084101102c000b41104101102c000b41204101102c000b41c0004101102c000b20004101102c000b102d000b0a0041c498c2001058000b5201027e024002402003450d002002280200450d010b41c8a6c30041f403109b01000b2001280218220342002003290308220420023502047d2205200520045622021b37030820004105410420021b3602000bc80d06047f027e027f017e027f027e230041c00c6b22042400024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d0320022802042105200241246a2802002106200241346a28020021030240200241146a2802002207450d0041052102200128020028021828023c2802bc012003490d080b200441306a4200370300200441286a4200370300200441206a420037030020012802182202420020022903082208427f20012802102903482209420586200942ffffffffffffffff07832009521b7d22092009200856220a1b3703082004420037031841052102200a0d070240024020012802142802082005200441186a4120102241026a220a41024b0d00200a0e03090001090b41fcd4c5001058000b024002400240024020070d00410121034100210b0c010b200441086a200128021029034842002003ad220c420010fb042001280218220a4200200a2903082209427f200429030820042903104200521b7d22082008200956220a1b370308200a0d0a2003417f4c0d070240024020030d004101210b02402001280214280208200641014100102241026a220341024b0d0020030e030d00020d0b41fcd4c5001058000b024020031034220b450d00024020012802142802082006200b2003102241026a220341024b0d0020030e03040002040b41fcd4c5001058000b20034101102c000b200c422086200c842109200b4521030b20012802002101200441386a41186a220a200441186a41186a290300370300200441386a41106a2205200441186a41106a290300370300200441386a41086a2206200441186a41086a290300370300200420042903183703382001280218210720030d01200728023c2802bc012009422088a74f0d012009a7450d090b200b102e0c080b200441d8006a41186a200a290300370300200441d8006a41106a2005290300370300200441d8006a41086a20062903003703002004200429033837035820072802140d052007417f36021420044198016a41186a200741e4006a290000370300200441a8016a200741dc006a290000370300200441a0016a200741d4006a2900003703002004200729004c3703980102400240200741186a220d280200220a41e08dc000460d002007411c6a28020021060c010b41002106200441e0096a410041e00210f5041a200441c0016a410041a00810f5041a41880b1029220a450d07200a41003b0106200a4100360200200a41086a200441e0096a41e00210f6041a200a41e8026a200441c0016a41a00810f6041a2007411c6a41003602002007200a3602180b024002400340200a2f0106220e410574210541002102410021030240034020052002460d0120044198016a200a20026a41086a412010f8042201450d03200241206a2102200341016a21032001417f4a0d000b2003417f6a210e0b02402006450d002006417f6a2106200a200e4102746a41880b6a280200210a0c010b0b200441f8006a41186a20044198016a41186a2903002208370300200441f8006a41106a20044198016a41106a290300220c370300200441f8006a41086a20044198016a41086a290300220f37030020042004290398012210370378200441fc096a200f370200200441840a6a200c3702002004418c0a6a20083702002004200741206a3602f0092004200e3602ec092004200d3602e8092004200a3602e409200441003602e009200420103702f409200441f4016a4200370200200441fc016a41003a0000200441e08dc0003602f001200442003703d801200442003703c001200441e0096a200441c0016a104f21020c010b200441d8016a4200370300200441d4016a41e08dc000360200200441003602e001200441003602d001200442003703c801200441e08dc0003602c401200441003602c001200a200341e0006c6a41e8026a2102200441c0016a10ee010b200441c0016a41186a200441d8006a41186a290300370300200441c0016a41106a200441d8006a41106a290300370300200441c0016a41086a200441d8006a41086a290300370300200420042903583703c0012004200937029c012004200b36029801200441e0096a200241306a200441c0016a20044198016a10f501024020042802e009450d0020042802e4092202450d00200441e8096a280200450d002002102e0b2007200728021441016a360214410421020c070b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b1032000b41aed9c1004110200441c0016a41c0d9c1001053000b41880b4108102c000b20002002360200200441c00c6a24000b950302017f027e230041c0006b22042400024002402003450d0020022802000d0020022802042103200441186a4200370300200441106a4200370300200441086a420037030020012802182202420020022903082205427f20012802102903482206420586200642ffffffffffffffff07832006521b7d2206200620055622021b3703082004420037030002400240024020020d00024002402001280214280208200320044120102241026a220241024b0d0020020e03020001020b41fcd4c5001058000b200441206a2001280200280218220241146a200241cc006a200241086a410020022802081b200410f2012004280220450d01200441306a41086a200441206a41086a28020036020020042004290320370330200141046a21020240200141086a280200450d002002280200102e0b20022004290330370200200241086a200441306a41086a280200360200410021010c020b200041053602000c030b2001410c6a4100360200410121010b20004100360200200020013602040c010b41c8a6c30041f403109b01000b200441c0006a24000b880e06017f017e057f027e037f027e230041d0016b220424000240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802204101470d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620022802042103200241286a2903002105200241346a2802002106200241c4006a2802002107200241d4006a2802002108200241e4006a2802002109200441286a20012802102903484200200241146a280200220aad420010fb042001280218220242002002290308220b427f200429032820042903304200521b7d220c200c200b5622021b370308024002400240024020020d00200a417f4c0d0b02400240024002400240200a0d004101210d02402001280214280208200341014100102241026a220241024b0d00200141146a210e20020e03060002060b41fcd4c5001058000b0240200a1034220d450d00024020012802142802082003200d200a102241026a220241024b0d00200141146a210e20020e03030002030b41fcd4c5001058000b200a4101102c000b41002102200441003a00b80102400340200a2002460d0120044198016a20026a200d20026a2d00003a00002004200241016a22033a00b8012003210220034120470d000b200441f8006a41186a220220044198016a41186a290300370300200441f8006a41106a220320044198016a41106a290300370300200441f8006a41086a220f20044198016a41086a29030037030020042004290398013703780240200a450d00200d102e0b200441386a41086a200f290300370300200441386a41106a2003290300370300200441386a41186a200229030037030020042004290378370338200441186a200128021029034842002007ad420010fb042001280218220242002002290308220b427f200429031820042903204200521b7d220c200c200b5622021b37030820020d042007417f4c0d0f20070d03200e280200280208200641014100102241026a220241024b0d0220020e03040204040b0240200241ff0171450d00200441003a00b8010b200a450d030b200d102e0c020b41fcd4c5001058000b024002400240200710342202450d000240200e280200280208200620022007102241026a220341024b0d0020030e03030002030b41fcd4c5001058000b20074101102c000b2007410f4d0d00200241086a2900002110200229000021112002102e200441086a200128021029034842002009ad420010fb042001280218220242002002290308220b427f200429030820042903104200521b7d220c200c200b5622021b37030820020d01200141046a220a20091036024002402001280214280208200820012802042001410c6a280200102241026a220241024b0d0020020e03030001030b41fcd4c5001058000b200128020c21032001410036020c200141086a280200210d20012802042107200142013702042001280218220241086a2206290300220c210b024002400240024002402005500d002005210b200c2005540d010b2006200c200b7d3703002002290310210c200441f8006a41186a200241186a2903003703002004200b370380012004200b3703782004200c370388012001280200280218210620044198016a41186a200441386a41186a29030037030020044198016a41106a200441386a41106a29030037030020044198016a41086a200441386a41086a2903003703002004200429033837039801200420033602c8012004200d3602c401200420073602c001200441d8006a200620044198016a20112010200441f8006a200441c0016a105a4101210d20042802584101460d01200441d8006a41106a2d00002103200441e4006a2802002107200441e0006a28020021064100210d200428025c21090c020b200420033602a0012004200d36029c01200420073602980120044198016a21020c020b200441ec006a2802002107200441d8006a41106a2802002106200441e4006a2802002109410021030b200241086a220220042903800120022903007c370300200141086a28020021020240200d0d0002402002450d00200a280200102e0b2001200736020c20012009360204200141086a20063602000c060b200420073602a0012004200636029c01200420093602980120020d0320044198016a21020b200120022902003702042001410036020c0c030b2002102e0b200041053602000c0b0b2001280204102e20012004290398013702042001410036020c0b41800221030b20004100360200200020033602040c080b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b1032000b200441d0016a24000ba00f07017f017e057f027e037f027e017f230041e0016b220424000240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802204101470d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620022802042103200241286a2903002105200241346a2802002106200241c4006a2802002107200241d4006a2802002108200241e4006a2802002109200441206a20012802102903484200200241146a280200220aad420010fb042001280218220242002002290308220b427f200429032020042903284200521b7d220c200c200b5622021b370308024002400240024020020d00200a417f4c0d0b02400240024002400240200a0d004101210d02402001280214280208200341014100102241026a220241024b0d00200141146a210e20020e03060002060b41fcd4c5001058000b0240200a1034220d450d00024020012802142802082003200d200a102241026a220241024b0d00200141146a210e20020e03030002030b41fcd4c5001058000b200a4101102c000b41002102200441003a00c80102400340200a2002460d01200441a8016a20026a200d20026a2d00003a00002004200241016a22033a00c8012003210220034120470d000b20044188016a41186a2202200441a8016a41186a29030037030020044188016a41106a2203200441a8016a41106a29030037030020044188016a41086a220f200441a8016a41086a290300370300200420042903a801370388010240200a450d00200d102e0b200441306a41086a200f290300370300200441306a41106a2003290300370300200441306a41186a20022903003703002004200429038801370330200441106a200128021029034842002007ad420010fb042001280218220242002002290308220b427f200429031020042903184200521b7d220c200c200b5622021b37030820020d042007417f4c0d0f20070d03200e280200280208200641014100102241026a220241024b0d0220020e03040204040b0240200241ff0171450d00200441003a00c8010b200a450d030b200d102e0c020b41fcd4c5001058000b024002400240200710342202450d000240200e280200280208200620022007102241026a220341024b0d0020030e03030002030b41fcd4c5001058000b20074101102c000b2007410f4d0d00200241086a2900002110200229000021112002102e2004200128021029034842002009ad420010fb042001280218220242002002290308220b427f200429030020042903084200521b7d220c200c200b5622021b37030820020d01200141046a220320091036024002402001280214280208200820012802042001410c6a280200102241026a220241024b0d0020020e03030001030b41fcd4c5001058000b200128020c210a2001410036020c200141086a280200210d20012802042107200142013702042001280218220241086a2206290300220c210b0240024002402005500d002005210b200c2005540d010b2006200c200b7d3703002002290310210c20044188016a41186a200241186a2903003703002004200b370390012004200b370388012004200c37039801200128020028021821062004200a3602582004200d36025420042007360250200441a8016a20062011201020044188016a200441306a200441d0006a104d4101210a0240024020042802a8014101460d00200441d0006a41086a200441a8016a41186a290300370300200441d0006a41106a200441c8016a2802003602002004200441a8016a41106a290300370350200441d8016a2d00002109200441d0016a2802002108200441cc016a280200210e200441b4016a280200210d200441a8016a41086a28020021074100210a20042802ac0121060c010b200441bc016a280200210d200441b8016a2802002107200441b4016a2802002106410021090b200441f0006a41086a220f200441d0006a41086a290300370300200441f0006a41106a2212200441d0006a41106a280200360200200241086a220220042903900120022903007c370300200420042903503703700240200a0d00200441bc016a200f290300370200200441c4016a20122802003602002004200d3602b001200420073602ac01200420063602a801200420042903703702b4010240200141086a280200450d002003280200102e0b2001410036020c2001200e360204200141086a2008360200200941ff017122020d07200441a8016a2003104a0c070b200141086a28020021022004200d3602b001200420073602ac01200420063602a80120020d04200441a8016a21020c010b2004200a3602b0012004200d3602ac01200420073602a801200441a8016a21020b200120022902003702042001410036020c0c030b2002102e0b200041053602000c0b0b2001280204102e200120042903a8013702042001410036020c0b41800221020b20004100360200200020023602040c080b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b1032000b200441e0016a24000b990303027f037e017f230041206b22042400024002402003450d0020022802000d0020034101460d0120022802100d0120022802042103200441106a20012802102903184200200241146a2802002205ad2206420010fb0420012802182202420020022903082207427f200429031020042903184200521b7d2208200820075622021b370308024020020d002004200128021029034842002006420010fb0420012802182202420020022903082207427f200429030020042903084200521b7d2208200820075622021b37030820020d00200141046a20051036024002402001280214280208200320012802042001410c6a280200102241026a220241024b0d0020020e03020001020b41fcd4c5001058000b200128020c21022001410036020c200141086a280200210320012802042105200142013702040240200128021c2209450d00200141206a280200450d002009102e0b2001200536021c200141246a2002360200200141206a20033602000b20004105360200200441206a24000f0b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b22002001410c6a4100360200200128020041206a200141046a104a200041043602000b26002001410c6a4100360200200128020028021841cc006a200141046a104a200041043602000bd50102027f027e410021042001410c6a41003602002001280218220541186a2903002106200529031021070240024002400240200141086a28020022054110490d00200128020421050c010b200541017422044110200441104b1b22044100480d020240024020050d002004102921050c010b200128020420052004102a21050b2005450d0120012005360204200141086a20043602002001410c6a28020021040b2001410c6a200441106a360200200520046a2201200637000820012007370000200041043602000f0b20044101102c000b102d000bc50103017f017e017f410021042001410c6a4100360200200128021841086a29030021050240024002400240200141086a28020022064108490d00200128020421060c010b200641017422044108200441084b1b22044100480d020240024020060d002004102921060c010b200128020420062004102a21060b2006450d0120012006360204200141086a20043602002001410c6a28020021040b2001410c6a200441086a360200200620046a2005370000200041043602000f0b20044101102c000b102d000b9c04020b7f027e230041206b220424002001410c6a41003602000240024002402001280200280218220528021441016a220641004c0d00200541cc006a210720052006360214200541186a21082005411c6a28020021090240024003402008280200220a41086a210b200a2f0106220c41057421084100210d0240024003402008450d012007200b412010f804220e450d02200841606a2108200d41016a210d200b41206a210b200e417f4a0d000b200d417f6a210c0b2009450d022009417f6a2109200a200c4102746a41880b6a21080c010b0b200a200d41e0006c6a220841e8026a280200450d00200841f8026a290300210f200841f0026a29030021100c010b200441086a200541246a2802002007200541286a28020028021c110300200441106a290300210f20052802142106200429030821100b20052006417f6a36021402400240200141086a280200220b2001410c6a28020022086b4110490d002001280204210b0c010b200841106a220d2008490d03200b4101742208200d200d2008491b22084100480d0302400240200b0d0020081029210b0c010b2001280204200b2008102a210b0b200b450d022001200b360204200141086a20083602002001410c6a28020021080b2001410c6a200841106a360200200b20086a2208200f3700082008201037000020004104360200200441206a24000f0b41e3d7c1004118200441186a41fcd7c1001053000b20084101102c000b102d000bd50102027f027e410021042001410c6a41003602002001280200220541086a2903002106200529030021070240024002400240200141086a28020022054110490d00200128020421050c010b200541017422044110200441104b1b22044100480d020240024020050d002004102921050c010b200128020420052004102a21050b2005450d0120012005360204200141086a20043602002001410c6a28020021040b2001410c6a200441106a360200200520046a2201200637000820012007370000200041043602000f0b20044101102c000b102d000bf80202047f027e230041306b220424000240024002402003450d0020022802000d0020034101460d0120022802100d01410521050240200241146a28020022032001280210220628026c4b0d00200228020421072004200629034842002003ad420010fb0420012802182202420020022903082208427f200429030020042903084200521b7d2209200920085622021b37030820020d002003417f4c0d0302400240024020030d004101210202402001280214280208200741014100102241026a220641024b0d0020060e03040002040b41fcd4c5001058000b0240200310342202450d0002402001280214280208200720022003102241026a220641024b0d0020060e03030002030b41fcd4c5001058000b20034101102c000b2001410c6a4100360200200441106a2002200310bd0241042105200441106a200141046a10462003450d010b2002102e0b20002005360200200441306a24000f0b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b1032000bc20103017f017e017f410021042001410c6a4100360200200128020029031021050240024002400240200141086a28020022064108490d00200128020421060c010b200641017422044108200441084b1b22044100480d020240024020060d002004102921060c010b200128020420062004102a21060b2006450d0120012006360204200141086a20043602002001410c6a28020021040b2001410c6a200441086a360200200620046a2005370000200041043602000f0b20044101102c000b102d000bb40803027f047e027f230041e0046b2204240002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200441286a20012802102903484200200241146a2802002202ad420010fb0420012802182203420020032903082206427f200429032820042903304200521b7d2207200720065622031b3703080240024020030d002002417f4c0d0402400240024020020d004101210302402001280214280208200541014100102241026a220541024b0d0020050e03040002040b41fcd4c5001058000b0240200210342203450d0002402001280214280208200520032002102241026a220541024b0d0020050e03030002030b41fcd4c5001058000b20024101102c000b2004200236023c20042003360238200441d0036a200441386a10b801024020042d00d00322054113460d00200441c8026a200441d0036a41017241870110f6041a02402002450d002003102e0b200441c0016a200441c8026a41870110f6041a200420053a0038200441386a410172200441c0016a41870110f6041a200441003602d803200442013703d003200441386a200441d0036a10bc0120042802d8032103024020042802d403450d0020042802d003102e0b200128021822022903102206200241186a2903002207844200510d07200441186a2003ad42004280c8afa025420010fb04200441086a200429031822084280a094a58d1d7c2209200441186a41086a2903002009200854ad7c2006200710fc0420024200200229030822062004290308427f200441086a41086a290300501b7d220720072006561b37030820072006580d03200441386a102f0c020b2002450d010b2003102e0b410521020c070b20012802002102200441c8026a200441386a41880110f6041a200441c0016a41086a2002280218220241d4006a290000370300200441d0016a2203200241dc006a290000370300200441d8016a2205200241e4006a2900003703002004200229004c3703c001200441d7036a200441c8026a41880110f6041a0240200241386a2802002201200241346a280200470d00200141016a220a2001490d062001410174220b200a200a200b491b220aad42b0017e2206422088a70d062006a7220b4100480d060240024020010d00200b102921010c010b2002280230200141b0016c200b102a21010b2001450d0520022001360230200241346a200a360200200228023821010b2002280230200141b0016c6a220141013a0000200120042903c001370001200141096a200441c8016a290300370000200141116a2003290300370000200141196a2005290300370000200141216a200441d0036a418f0110f6041a2002200228023841016a360238410421020c060b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b1032000b41c8a5c3001058000b200b4108102c000b102d000b20002002360200200441e0046a24000b911705087f027e037f027e057f230041a0026b22042400024002400240024002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620034107460d0720022802700d0720022802042103200241246a2802002105200241346a2802002106200241c4006a2802002107200241d4006a2802002108200241e4006a2802002109200241f4006a280200210a200441206a20012802102903484200200241146a280200220bad420010fb042001280218220242002002290308220c427f200429032020042903284200521b7d220d200d200c5622021b3703080240024020020d00200b417f4c0d0a024002400240200b0d004101210e02402001280214280208200341014100102241026a220241024b0d00200141146a210f20020e03040002040b41fcd4c5001058000b0240200b1034220e450d00024020012802142802082003200e200b102241026a220241024b0d00200141146a210f20020e03030002030b41fcd4c5001058000b200b4101102c000b41002102200441003a00f00102400340200b2002460d01200441d0016a20026a200e20026a2d00003a00002004200241016a22033a00f0012003210220034120470d000b20044180026a41086a2202200441d0016a41086a29030037030020044180026a41106a2203200441d0016a41106a29030037030020044180026a41186a2210200441d0016a41186a290300370300200420042903d001370380020240200b450d00200e102e0b200441306a41086a2002290300370300200441306a41106a2003290300370300200441306a41186a20102903003703002004200429038002370330200441106a200128021029034842002006ad420010fb042001280218220242002002290308220c427f200429031020042903184200521b7d220d200d200c5622021b3703082002450d030c100b0240200241ff0171450d00200441003a00f0010b200b450d010b200e102e0b200441f0006a41186a20044180026a41186a290300370300200441f0006a41106a20044180026a41106a290300370300200441f0006a41086a20044180026a41086a2903003703002004200429038002370370410521020c0e0b2006417f4c0d080240024002400240024020060d004101210b0240200f280200280208200541014100102241026a220241024b0d0020020e03120002120b41fcd4c5001058000b024020061034220b450d000240200f2802002802082005200b2006102241026a220241024b0d0020020e03030002030b41fcd4c5001058000b20064101102c000b41002102200441003a00f0010240034020062002460d01200441d0016a20026a200b20026a2d00003a00002004200241016a22033a00f0012003210220034120470d000b20044180026a41086a2202200441d0016a41086a29030037030020044180026a41106a2203200441d0016a41106a29030037030020044180026a41186a220e200441d0016a41186a290300370300200420042903d0013703800202402006450d00200b102e0b200441d0006a41086a2002290300370300200441d0006a41106a2003290300370300200441d0006a41186a200e29030037030020042004290380023703502004200128021029034842002008ad420010fb042001280218220242002002290308220c427f200429030020042903084200521b7d220d200d200c5622031b3703084105210220030d112008417f4c0d0c20080d03200f280200280208200741014100102241026a220341024b0d0220030e03110211110b0240200241ff0171450d00200441003a00f0010b2006450d0f0b200b102e410521020c0f0b41fcd4c5001058000b02400240024002400240200810342203450d000240200f280200280208200720032008102241026a220b41024b0d00200b0e03030002030b41fcd4c5001058000b20084101102c000b2008410f4d0d00200341086a2900002111200329000021122003102e024002400240200a0d004101210e4100210b0c010b20044180026a41186a210620044180026a41106a210520044180026a41086a21084100211041002102410021034100210b4101210e03402006420037030020054200370300200842003703002001280218220742002007290308220d427f2001280210290348220c420586200c42ffffffffffffffff0783200c521b7d220c200c200d5622071b370308200442003703800220070d1102400240200f280200280208200920026a221320044180026a4120102241026a220741024b0d0020070e03130001130b41fcd4c5001058000b200341016a2107200441d0016a41186a22142006290300370300200441d0016a41106a22152005290300370300200441d0016a41086a2216200829030037030020042004290380023703d00102402003200b470d002010200720072010491b220b41ffffff3f71200b470d03200b41057422174100480d030240024020030d0020171029210e0c010b200e20022017102a210e0b200e450d110b200e20026a220320042903d001370000200341186a2014290300370000200341106a2015290300370000200341086a2016290300370000201341206a2013490d11201041026a2110200241206a210220072103200a2007470d000b0b2001280200280218210320044190016a41086a200441306a41086a29030037030020044190016a41106a2201200441306a41106a29030037030020044190016a41186a2206200441306a41186a290300370300200441b0016a41086a200341d4006a290000370300200441b0016a41106a2205200341dc006a290000370300200441b0016a41186a2208200341e4006a29000037030020042004290330370390012004200329004c3703b00120044180026a41186a2207200441d0006a41186a29030037030020044180026a41106a2209200441d0006a41106a29030037030020044180026a41086a200441d0006a41086a2903003703002004200429035037038002200341386a2802002202200341346a280200470d03200241016a220f2002490d0020024101742210200f200f2010491b220fad42b0017e220c422088a70d00200ca7221041004e0d020b102d000b2003102e0c0f0b0240024020020d002010102921020c010b2003280230200241b0016c2010102a21020b2002450d0a20032002360230200341346a200f360200200328023821020b2003280230200241b0016c6a220241023a0000200220042903b0013700012002200429039001370021200241096a200441b0016a41086a290300370000200241116a2005290300370000200241196a2008290300370000200241296a20044190016a41086a290300370000200241316a2001290300370000200241396a20062903003700002002200e3600642002200b3600682002200a36006c20022012370370200241f8006a20113703002002200429038002370041200241c9006a20044180026a41086a290300370000200241d1006a2009290300370000200241d9006a2007290300370000200220042f00703b0061200241e3006a200441f0006a41026a2d00003a0000200220042903d0013703800120024188016a200441d0016a41086a29030037030020024190016a200441d0016a41106a29030037030020024198016a200441d0016a41186a290300370300200241a0016a200441f0016a290300370300200241a8016a200441f8016a2903003703002003200328023841016a360238410421020c0d0b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b1032000b20104108102c000b20174101102c000b41052102200b450d01200e102e0c010b410521020b20002002360200200441a0026a24000b16002000410036020020002001410c6a2802003602040bae0202057f027e230041106b220424000240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d024105210302402001410c6a2802002205200241146a2802002206490d00200520066b200241246a2802002205470d0020022802042107200128020421082004200128021029035042002005ad420010fb0420012802182202420020022903082209427f200429030020042903084200521b7d220a200a20095622021b37030820020d000240024020012802142802082007200820066a2005102341026a220241024b0d0020020e03020001020b418cd6c5001058000b410421030b20002003360200200441106a24000f0b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000bf80102037f027e230041106b22042400024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200420012802102903484200200241146a2802002206ad420010fb0420012802182202420020022903082207427f200429030020042903084200521b7d2208200820075622031b37030841052102024020030d00200141046a20061036024002402001280214280208200520012802042001410c6a280200102241026a220141024b0d0020010e03020001020b41fcd4c5001058000b410421020b20002002360200200441106a24000f0b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000bbe0b05047f027e037f017e037f230041e0016b2204240002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d03200241246a2802002105200241346a280200210602400240024002400240200241146a2802002203450d0020022802042107200441306a200128021029034842002003ad420010fb0420012802182202420020022903082208427f200429033020042903384200521b7d22092009200856220a1b37030841052102200a0d0e2003417f4c0d0920031034220a450d0a024020012802142802082007200a2003102241026a220741024b0d0020070e03040002040b41fcd4c5001058000b4101210b410021074100210c0c010b2004200336028c012004200a36028801200441c0006a20044188016a1030200429024421082004280240210b200a102e200b450d0c2008a7210c200128021028025c2008422088a72207490d0b0b200b2007410041202007676b1063024020074102490d00200b21022007210303402002200241206a220a412010f804450d0c200a21022003417f6a220341024f0d000b0b200441206a200128021029034842002006ad220d420010fb0420012802182202420020022903082208427f200429032020042903284200521b7d2209200920085622021b37030820020d0a2006417f4c0d060240024020060d004101210a02402001280214280208200541014100102241026a220241024b0d0020020e030d00020d0b41fcd4c5001058000b0240024020061034220a450d00024020012802142802082005200a2006102241026a220241024b0d0020020e03020003020b41fcd4c5001058000b20064101102c000b200a102e0c0b0b20042001280210220329032842002007ad420010fb04200441106a20032903204200200d420010fb0420012802182102427f2109024020042903184200520d0020042903084200520d002004290310220820042903007c220d2008540d00427f200d20032903307c22082008200d541b21090b200242002002290308220820097d220920092008561b37030820092008580d012006450d0a200a102e0c0a0b200a102e0c0a0b200441b8016a41086a22052001280200280218220341d4006a290000370300200441b8016a41106a2201200341dc006a290000370300200441b8016a41186a220e200341e4006a2900003703002004200329004c3703b8010240200341386a2802002202200341346a280200470d00200241016a220f2002490d0820024101742210200f200f2010491b2210ad42b0017e2208422088a70d082008a7220f4100480d080240024020020d00200f102921020c010b2003280230200241b0016c200f102a21020b2002450d0720032002360230200341346a2010360200200328023821020b2003280230200241b0016c6a220241003a0000200220042f00dd013b0001200241053a00102002200736000c2002200c3600082002200b360004200220042903b801370011200241036a200441dd016a41026a2d00003a0000200241196a2005290300370000200241216a2001290300370000200241296a200e2903003700002002200a360034200220063600382002200636003c200220042f00b5013b0031200241336a200441b5016a41026a2d00003a00002002200429038801370340200241c8006a20044188016a41086a290300370300200241d0006a20044188016a41106a290300370300200241d8006a20044188016a41186a290300370300200241e0006a200441a8016a290300370300200241e8006a200441c0006a41c80010f6041a2003200328023841016a360238410421020c090b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b1032000b20034101102c000b200f4108102c000b102d000b41052102200c450d00200b102e0b20002002360200200441e0016a24000be70804027f027e057f047e230041e00b6b220424000240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200441086a20012802102903484200200241146a2802002202ad420010fb0420012802182203420020032903082206427f200429030820042903104200521b7d2207200720065622081b3703084105210320080d052002417f4c0d02024020020d0002402001280214280208200541014100102241026a220241024b0d0020020e03070007070b41fcd4c5001058000b0240024002400240200210342208450d0002402001280214280208200520082002102241026a220541024b0d0020050e03030002030b41fcd4c5001058000b20024101102c000b2002410f4b0d010b2008102e0c060b200841086a2900002106200829000021072008102e200128020028021822092802140d032009417f360214200441386a41186a200941e4006a290000370300200441c8006a200941dc006a290000370300200441386a41086a200941d4006a2900003703002004200929004c37033802400240200941186a220a280200220841e08dc000460d002009411c6a280200210b0c010b4100210b20044180096a410041e00210f5041a200441e0006a410041a00810f5041a41880b10292208450d05200841003b010620084100360200200841086a20044180096a41e00210f6041a200841e8026a200441e0006a41a00810f6041a2009411c6a4100360200200920083602180b02400240034020082f0106220c410574210541002102410021010240034020052002460d01200441386a200820026a41086a412010f8042203450d03200241206a2102200141016a21012003417f4a0d000b2001417f6a210c0b0240200b450d00200b417f6a210b2008200c4102746a41880b6a28020021080c010b0b200441186a41186a200441386a41186a290300220d370300200441186a41106a200441386a41106a290300220e370300200441186a41086a200441386a41086a290300220f3703002004200429033822103703182004419c096a200f370200200441a4096a200e370200200441ac096a200d3702002004200941206a360290092004200c36028c092004200a3602880920042008360284092004410036028009200420103702940920044194016a42003702002004419c016a41003a0000200441e08dc00036029001200442003703782004420037036020044180096a200441e0006a104f21020c010b200441f8006a4200370300200441f4006a41e08dc00036020020044100360280012004410036027020044200370368200441e08dc000360264200441003602602008200141e0006c6a41e8026a2102200441e0006a10ee010b200241286a2006370300200241206a2007370300200242013703182009200928021441016a360214410421030c050b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b1032000b41aed9c1004110200441e0006a41c0d9c1001053000b41880b4108102c000b20002003360200200441e00b6a24000bac04020b7f027e230041206b220424002001410c6a41003602000240024002402001280200280218220528021441016a220641004c0d00200541cc006a210720052006360214200541186a21082005411c6a28020021090240024003402008280200220a41086a210b200a2f0106220c41057421084100210d0240024003402008450d012007200b412010f804220e450d02200841606a2108200d41016a210d200b41206a210b200e417f4a0d000b200d417f6a210c0b2009450d022009417f6a2109200a200c4102746a41880b6a21080c010b0b200a200d41e0006c6a22084180036a280200220b450d0020084190036a290300210f20084188036a29030021100c010b2004200541246a2802002007200541286a280200280214110300200441106a290300210f20052802142106200429030821102004280200210b0b20052006417f6a36021402400240200141086a280200220d2001410c6a28020022086b4110490d002001280204210d0c010b200841106a220e2008490d03200d4101742208200e200e2008491b22084100480d0302400240200d0d0020081029210d0c010b2001280204200d2008102a210d0b200d450d022001200d360204200141086a20083602002001410c6a28020021080b2001410c6a200841106a360200200d20086a2208200f427f200b1b37000820082010427f200b1b37000020004104360200200441206a24000f0b41e3d7c1004118200441186a41fcd7c1001053000b20084101102c000b102d000bf10203027f027e017f230041206b220424000240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200420012802102903484200200241146a2802002202ad420010fb0420012802182203420020032903082206427f200429030020042903084200521b7d2207200720065622081b37030841052103024020080d002002417f4c0d0302400240024020020d004101210802402001280214280208200541014100102241026a220141024b0d0020010e03040002040b41fcd4c5001058000b0240200210342208450d0002402001280214280208200520082002102241026a220141024b0d0020010e03030002030b41fcd4c5001058000b20024101102c000b200441106a2008200210cd02024020042802100d002004280214200441186a28020010090b410421032002450d010b2008102e0b20002003360200200441206a24000f0b41c8a6c30041f403109b01000b41c8a6c30041f403109b01000b1032000bbe0101037f410021042001410c6a4100360200200128020028021c21050240024002400240200141086a28020022064104490d00200128020421060c010b200641017422044104200441044b1b22044100480d020240024020060d002004102921060c010b200128020420062004102a21060b2006450d0120012006360204200141086a20043602002001410c6a28020021040b2001410c6a200441046a360200200620046a2005360000200041043602000f0b20044101102c000b102d000bc505020a7f017e230041c0006b220424002004200136020c2004200041c8ecc50020011b3602082004200441086a1031024020042802000d000240024002400240024002400240200428020c22014170712200417f4c0d002004280204210502400240200141047622060d00410821070c010b200010292207450d020b02402005450d00200441206a4104722108410021094100210a410021000340200441206a200441086a10fc02200441306a41086a220b200841086a2802003602002004200829020037033002402004280220220c4104470d002006450d0a2007102e0c0a0b200041016a2101200441106a41086a220d200b28020036020020042004290330370310024020002006470d002009200120012009491b220641ffffffff00712006470d062006410474220b4100480d060240024020000d00200b102921070c010b2007200a200b102a21070b2007450d050b2007200a6a2200200c360200200041046a20042903103702002000410c6a200d280200360200200941026a2109200a41106a210a2001210020052001470d000b0b2007450d07200441206a200220072005200311060020042802202100410110292201450d042004428180808010370234200420013602300240024020004105460d00200141003a0000200141014102102a2101024020004104470d002001450d08200141003a00012004428280808020370234200420013602304202210e0c020b2001450d08200141013a0001200442828080802037023420042001360230200441206a200441306a10fd022004350238210e200428023021010c010b200141013a00004201210e0b2001ad422086200e84210e02402006450d002007102e0b200441c0006a2400200e0f0b1032000b20004108102c000b200b4108102c000b102d000b41014101102c000b41024101102c000b41024101102c000b41a5a3c20041f000200441206a41b8a2c2001053000bde0202047f017e02400240024002400240024020012802042202450d00200128020022032d0000210420012002417f6a22053602042001200341016a3602002004417f6a220441034b0d0520040e0401020304010b200041043602000f0b0240200541034b0d00200041043602000f0b200041003602002003280001210420012002417b6a3602042001200341056a360200200020043602040f0b024020054108490d0020004101360200200329000121062001200241776a3602042001200341096a360200200041086a20063703000f0b200041043602000f0b0240200541034b0d00200041043602000f0b200041023602002003280001210420012002417b6a3602042001200341056a360200200020043602040f0b024020054108490d0020004103360200200329000121062001200241776a3602042001200341096a360200200041086a20063703000f0b200041043602000f0b200041043602000b840b02037f017e024002400240024002400240024002400240024002400240024020002802000e0400010203000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0c20024101742204200320032004491b22044100480d0c0240024020020d002004102921030c010b200128020020022004102a21030b2003450d0420012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41013a00002000280204210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d0c20024101742200200420042000491b22004100480d0c0240024020020d002000102921020c010b200128020020022000102a21020b2002450d0520012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0b20024101742204200320032004491b22044100480d0b0240024020020d002004102921030c010b200128020020022004102a21030b2003450d0520012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41023a00002000290308210502400240200141046a2802002202200428020022006b4108490d00200128020021020c010b200041086a22032000490d0b20024101742200200320032000491b22004100480d0b0240024020020d002000102921020c010b200128020020022000102a21020b2002450d0620012002360200200141046a2000360200200141086a28020021000b200141086a200041086a360200200220006a20053700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0a20024101742204200320032004491b22044100480d0a0240024020020d002004102921030c010b200128020020022004102a21030b2003450d0620012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a00002000280204210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d0a20024101742200200420042000491b22004100480d0a0240024020020d002000102921020c010b200128020020022000102a21020b2002450d0720012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0920024101742204200320032004491b22044100480d090240024020020d002004102921030c010b200128020020022004102a21030b2003450d0720012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41043a00002000290308210502400240200141046a2802002202200428020022006b4108490d00200128020021020c010b200041086a22032000490d0920024101742200200320032000491b22004100480d090240024020020d002000102921020c010b200128020020022000102a21020b2002450d0820012002360200200141046a2000360200200141086a28020021000b200141086a200041086a360200200220006a20053700000f0b20044101102c000b20004101102c000b20044101102c000b20004101102c000b20044101102c000b20004101102c000b20044101102c000b20004101102c000b102d000bfd0102057f017e230041306b220224002002410036022020014110200241206a10082101024002400240024020022802202203417f460d0020010d010b200041003602040c010b20022003360214200220013602102003450d0120022003417f6a3602142002200141016a36021020012d00002103200241206a200241106a103020022802202204450d012002410c6a41026a2002411d6a41026a2d000022053a0000200220022f001d22063b010c20022902242107200020033a0000200020063b0001200041036a20053a000020002007370208200020043602042001102e0b200241306a24000f0b41eff0c2004133200241206a4184f4c2001053000bcf0201057f230041b0026b22012400200141a0016a41086a22024200370300200142003703a0014198cbc4004116200141a0016a100320014190016a41086a22032002290300370300200120012903a00137039001200141a0016a20014190016a10b1030240024020012d00a80222044103460d0020014190016a411010062001200141a0016a41880110f604220541013a008f0120024200370300200542003703a00141a199c500411f200541a0016a100320032002290300370300200520052903a0013703900120054190016a41102005418f016a41011004200241023a0000200541053a00a0014100210241c8ecc5004100200541a0016a1072200541a0016a200541880110f6041a20054190016a20004180ce186a200541a0016a20044180af1a10f0032005280290014101470d0120052802940121020c010b41aecbc40021020b200141b0026a240020020bda1008057f037e017f017e017f0f7e017f047e230041e0026b2201240041082102200141a8016a41086a22034200370300200142003703a80141c7c9c4004115200141a8016a1003200141c0026a41086a2003290300370300200120012903a8013703c002200141a8016a200141c0026a10b0030240024020012802a80122030d0041002104410021050c010b200141b0016a280200210420012802ac012105200321020b0240024002400240024002402004450d00200141a8016a20022802880110f1030240024020012802b80122030d0042002106420021070c010b200141106a20012903a801200141a8016a41086a290300200141c0016a350200420010fb04200141106a41086a29030021072001290310210620012802bc01450d002003102e0b2002ad4220862108024020044101460d00200241b0016a2103200441b0016c41d07e6a21094201210a0340200141a8016a20034188016a28020010f1030240024020012802b801220b0d004200210c4200210d0c010b200120012903a801200141a8016a41086a29030020013502c001420010fb04200141086a290300210d2001290300210c20012802bc01450d00200b102e0b02402006200c562007200d562007200d511b0d002003ad422086200a842108200c2106200d21070b200341b0016a2103200a42017c210a200941d07e6a22090d000b0b02402008428080808010540d0020042008a722034d0d0220022004417f6a220b41b0016c6a22094180016a290300210d20094188016a290300210720094190016a290300210a20094198016a290300210c200941e0006a2903002106200941e8006a2903002108200941f0006a290300210e200941f8006a290300210f200941c0006a2903002110200941c8006a2903002111200941d0006a2903002112200941d8006a2903002113200941206a2903002114200941286a2903002115200941306a2903002116200941386a290300211720092903002118200929030821192009290310211a2002200341b0016c6a220341186a221b290300211c200941a8016a290300211d200941a0016a290300211e201b200941186a2903003703002003290310211f2003201a3703102003290308211a200320193703082003290300211920032018370300200341386a2209290000211820092017370000200341306a2209290000211720092016370000200341286a2209290000211620092015370000200341206a2209290000211520092014370000200341d8006a2209290000211420092013370000200341d0006a2209290000211320092012370000200341c8006a2209290000211220092011370000200341c0006a2209290000211120092010370000200341f8006a220929000021102009200f370000200341f0006a2209290000210f2009200e370000200341e8006a2209290000210e20092008370000200341e0006a220929000021082009200637000020034198016a200c37000020034190016a200a37000020034188016a2209280000211b2009200737000020034180016a220929000021072009200d370000200341a0016a201e370200200341a8016a201d370200200141206a41f8006a2010370300200141206a41f0006a200f370300200141206a41e8006a200e370300200141206a41e0006a2008370300200141206a41d8006a2014370300200141206a41d0006a2013370300200141206a41c8006a2012370300200141206a41c0006a2011370300200141206a41386a2018370300200141206a41306a2017370300200141206a41286a2016370300200141206a41206a2015370300200141206a41186a201c370300200141206a4180016a20073703002001201f3703302001201a37032820012019370320200141a8016a41086a22034200370300200142003703a80141c7c9c4004115200141a8016a1003200141c0026a41086a2003290300370300200120012903a8013703c002200141103602ac012001200141c0026a3602a8012002200b200141a8016a10ff010240200b450d00200441b0016c41d07e6a21092002210303402003102f200341b0016a2103200941d07e6a22090d000b0b02402005450d002002102e0b411310292203450d032003410f6a41002800fcc844360000200341086a41002900f5c844370000200341002900edc844370000200341134126102a2203450d042003201b360013200141a8016a41186a22094200370300200141a8016a41106a220b4200370300200141a8016a41086a22024200370300200142003703a80120034117200141a8016a1000200141c0026a41186a2009290300370300200141c0026a41106a200b290300370300200141c0026a41086a2002290300370300200120012903a8013703c002200141a8016a200141c0026a10af03024020012802b801220b450d00200141c0026a412010060b200141b0016a290300210d2009280200210220012903a801210720012802bc0121042003102e0240200b0d00200141206a102f0c060b024020024105742209450d00200b2103034020032007200d109401200341206a2103200941606a22090d000b0b200141d0016a200d370300200141c8016a2007370300200141c0016a2002360200200141bc016a2004360200200141b8016a200b360200200141b4016a201b360200200141b0016a41013a0000200141053a00a80141c8ecc5004100200141a8016a1072200141a8016a200141206a41880110f6041a200141c0026a20004180ce186a200141a8016a41004180af1a10f00320012802c0024101470d0520012802c40221030c060b200441b0016c21092002210303402003102f200341b0016a2103200941d07e6a22090d000b0b41ecc9c40021032005450d042002102e0c040b41dcc9c400200320041038000b41134101102c000b41264101102c000b410021030b200141e0026a240020030b9e0501077f230041d0026b2202240002400240411a10292203450d00200341186a41002f00ebc8443b0000200341106a41002900e3c844370000200341086a41002900dbc844370000200341002900d3c8443700002003411a4134102a2203450d012003200136001a200241c0016a41186a22014200370300200241c0016a41106a22044200370300200241c0016a41086a22054200370300200242003703c0012003411e200241c0016a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903c001370300200241003602c00120024120200241c0016a1008210102400240024020022802c0012204417f460d002001450d00200220013602282002200436022c024020044104490d002001280000210620022004417c6a36022c2002200141046a360228200241c0016a200241286a10b80120022d00c0014113460d00200241386a200241c0016a41880110f6041a0240200228022c2207450d00200228022822052d0000210420022007417f6a220836022c2002200541016a360228200441034f0d00200841034b0d03200241386a102f0c010b200241386a102f0b41eff0c2004133200241c8026a4184f4c2001053000b410321040c010b2005280001210820022007417b6a36022c2002200541056a360228200241c0016a200241386a41880110f6041a200220022800303602202002200241336a280000360023200241386a200241c0016a41880110f6041a20022002280023360033200220022802203602302001102e2000200241386a41880110f6042201200836028c012001200636028801200120022802303600910120014194016a20022800333600000b200020043a0090012003102e200241d0026a24000f0b411a4101102c000b41344101102c000bfc0202047f017e230041d0006b22022400024002400240411310292203450d002003410f6a41002800a6c944360000200341086a410029009fc94437000020034100290097c944370000200341134126102a2203450d0120032001360013200241206a41186a22014200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034117200241206a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903203703002002410036022020024120200241206a100821040240024020022802202201417f460d002002200136024420022004360240200241206a200241c0006a103020022802202205450d042002290224210602402001450d002004102e0b20002006370204200020053602000c010b20004100360208200042013702000b2003102e200241d0006a24000f0b41134101102c000b41264101102c000b41eff0c2004133200241c8006a4184f4c2001053000ba40301067f230041c0006b22022400024002400240411010292203450d00200341002900aec844370000200341086a41002900b6c8443700002002429080808080023702242002200336022020012802002104200341104120102a2203450d0120032004360010200242a0808080c00237022420022003360220200141046a200241206a104a200228022421042002280228210120022802202103200241206a41186a22054200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020032001200241206a1000200241186a2005290300370300200241106a2006290300370300200241086a2007290300370300200220022903203703002002410036022020024120200241206a100821010240024020022802202205417f460d002005450d0420012d0000220641ff0071220541074f0d042001102e200641077621010c010b41002105410021010b02402004450d002003102e0b200020053a0001200020013a0000200241c0006a24000f0b41104101102c000b41204101102c000b41eff0c2004133200241206a4184f4c2001053000be20c04017f047e107f087e230041b0036b220524000240024002400240024020040d00420021064200210742002108420021090c010b4200210820054190036a41186a220a420037030020054190036a41106a220b420037030020054190036a41086a220c4200370300200542003703900341aac9c400411d20054190036a1000200541c8026a41186a200a290300370300200541c8026a41106a200b290300370300200541c8026a41086a200c29030037030020052005290390033703c802200541e0016a200541c8026a412010dc0141281029220c450d01200c41c8ecc500360200200c20052903e001370204200c20052f0098013b0025200c410c6a200541e0016a41086a290300370200200c41146a200541e0016a41106a290300370200200c411c6a200541e0016a41186a290300370200200c41246a200541e0016a41206a2d00003a0000200c41276a2005419a016a2d00003a000020054198016a200c10d703420021094200210642002107024020052d00d8014107460d002004417f6a210d200541e8026a410472210a200541a0026a210e200541e0016a41206a210f200541e0016a41186a2110200341ff0171211142002106420021074200210842002109034020102007370300200520063703f001200520083703e001200520093703e801200f20054198016a41c10010f604210402400240200e2002460d00200e2002412010f8040d010b200a2004290200370200200a41086a200441086a2212290200370200200a41106a200441106a2213290200370200200a41186a200441186a2214290200370200200520013602e80241101029220b450d05200b41002900aec844370000200b41086a41002900b6c844370000200542908080808002370294032005200b3602900320052802e8022115200b41104120102a220b450d062005200528029803221641046a360298032005200b360290032005412036029403200b20166a2015360000200a20054190036a104a20052802940321172005280298032118200528029003211920054190036a41186a220b420037030020054190036a41106a2215420037030020054190036a41086a2216420037030020054200370390032019201820054190036a1000200541c8026a41186a200b290300370300200541c8026a41106a2015290300370300200541c8026a41086a201629030037030020052005290390033703c802200541c8026a412041c8ecc500410041001005211802402017450d002019102e0b2018417f470d0020052d00c0022119200b20142900003703002015201329000037030020162012290000370300200520042900003703900302404100417f4101201920114b1b20192011461b41016a41014b0d00200321190b20054188016a20054190036a10840120054188016a41086a290300211a200529038801211b02400240201941ff01710d00200541086a201b201a420a420010fc04200541e8026a41186a200b290300370300200541e8026a41106a2015290300370300200541e8026a41086a201629030037030020052005290390033703e802200541186a2001200541e8026a4100200d108403200541186a41186a290300211c200541186a41086a290300211d2005290328211e2005290318211f20052903082220211b200541086a41086a2903002221211a0c010b200541c8006a201a42002019ad42ff01832220420010fb04200541d8006a201b42002020420010fb04200541e8026a41186a200b290300370300200541e8026a41106a2015290300370300200541e8026a41086a201629030037030020052005290390033703e802200541e8006a2001200541e8026a2019200d108403200541386a42004200201b420010fb04427f200541d8006a41086a2903002220200529034820052903387c7c221c2005290350200529034084420052201c2020547222041b2121427f200529035820041b2120200541e8006a41186a290300211c200541e8006a41086a290300211d2005290378211e2005290368211f0b201a20077c201b20067c2207201b54ad7c201c7c2007201e7c2206200754ad7c2107202120097c202020087c2209202054ad7c201d7c2009201f7c2208200954ad7c21090b20054198016a200c10d70320052d00d8014107470d000b0b200c102e0b2000200637031020002008370300200041186a200737030020002009370308200541b0036a24000f0b41284104102c000b41104101102c000b41204101102c000bc107030b7f037e037f23004190016b22012400024002400240024002400240411a10292202450d00200241186a41002f00ebc8443b0000200241106a41002900e3c844370000200241086a41002900dbc844370000200241002900d3c8443700002002411a4134102a2202450d012002200036001a200141f0006a41186a22034200370300200141f0006a41106a22044200370300200141f0006a41086a22054200370300200142003703702002411e200141f0006a1000200141d0006a41186a2003290300370300200141d0006a41106a2004290300370300200141d0006a41086a200529030037030020012001290370370350200141d0006a412010062002102e411310292202450d022002410f6a41002800a6c944360000200241086a410029009fc94437000020024100290097c944370000200241134126102a2202450d0320022000360013200141f0006a41186a22054200370300200141f0006a41106a22064200370300200141f0006a41086a220342003703002001420037037020024117200141f0006a1000200141d0006a41186a22072005290300370300200141d0006a41106a22082006290300370300200141d0006a41086a200329030037030020012001290370370350200141d0006a412010062002102e200141086a2000108203200128020c21092001280208210a024020012802102202450d002002410574210b200141086a4104722103200a21020340200241186a290000210c200241106a290000210d200241086a290000210e20032002290000370000200341086a200e370000200341106a200d370000200341186a200c37000020012000360208411010292204450d06200441002900aec844370000200441086a41002900b6c844370000200142908080808002370274200120043602702001280208210f200441104120102a2204450d072001412036027420012001280278221041046a36027820012004360270200420106a200f3600002003200141f0006a104a2001280274210f20012802782110200128027021042005420037030020064200370300200141f0006a41086a221142003703002001420037037020042010200141f0006a10002007200529030037030020082006290300370300200141d0006a41086a201129030037030020012001290370370350200141d0006a412010060240200f450d002004102e0b200241206a2102200b41606a220b0d000b0b02402009450d00200a102e0b20014190016a24000f0b411a4101102c000b41344101102c000b41134101102c000b41264101102c000b41104101102c000b41204101102c000bab0201047f230041c0006b2202240002400240411710292203450d002003410f6a410029008fc944370000200341086a4100290088c94437000020034100290080c94437000020034117412e102a2203450d0120032001360017200241206a41186a22014200370300200241206a41106a22044200370300200241206a41086a22054200370300200242003703202003411b200241206a1000200241186a2001290300370300200241106a2004290300370300200241086a200529030037030020022002290320370300200241206a2002108703024002402002280220450d0020002002290320370200200041086a200241206a41086a2802003602000c010b20004100360208200042083702000b2003102e200241c0006a24000f0b41174101102c000b412e4101102c000beb05020d7f017e230041c0056b22022400200241003602b80420014120200241b8046a1008210302400240024002400240024020022802b8042204417f470d00200041003602000c010b2002200436021420022003360210200241086a200241106a103120022802080d0420022802144190016e22054190016c2201417f4c0d01200228020c21060240024020010d00410821070c010b200110292207450d030b02402006450d00200241b0036a4101722108410021094100210a4100210b03400240024002402002280214220c450d002002280210220d2d000021012002200c417f6a3602142002200d41016a360210200141014b0d004113210c02400240024020010e020100010b200241b8046a200241106a10b80120022d00b8044113460d02200241b0036a200241b8046a41880110f6041a200228021422014104490d012002280210220c280000210e20022001417c6a3602142002200c41046a36021020022d00b003210c200241a9026a200841870110f6041a200c4113460d02200241a2016a200241a9026a41870110f6041a200c4114460d020b200b41016a21012002411b6a200241a2016a41870110f6041a200b2005470d0302402009200120012009491b2205ad4290017e220f422088a70d00200fa7220d41004e0d030b102d000b200241b0036a102f0b0240200b450d00200721010340024020012d00004113460d002001102f0b20014190016a2101200a41f07e6a220a0d000b0b2005450d082007102e0c080b02400240200b0d00200d102921070c010b2007200a200d102a21070b2007450d060b2007200a6a220b200c3a0000200b41016a2002411b6a41870110f6041a200b4188016a200e360200200941026a2109200a4190016a210a2001210b20062001470d000b0b2007450d042000200536020420002007360200200041086a20063602002004450d002003102e0b200241c0056a24000f0b1032000b20014108102c000b200d4108102c000b41eff0c2004133200241b8046a4184f4c2001053000b13002000410436020420004184acc2003602000b3400200041e5b2c20036020420004100360200200041146a4101360200200041106a41f8b2c200360200200041086a42133702000bcd0101047f200020014105746a210320002104024003400240200320046b41e0004b0d00024020042003460d00200020014105746a210503404101210620022004460d0420042002412010f804450d042005200441206a2204470d000b0b41000f0b4101210620042002460d0120042002412010f804450d01200441206a22052002460d0120052002412010f804450d01200441c0006a22052002460d0120052002412010f804450d01200441e0006a22052002460d0120044180016a210420052002412010f8040d000b0b20060bc40401067f0240024002400240024020012d0000417f6a220241034b0d0020020e0401020304010b41c8a2c2001058000b200041013a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b200041023a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b200041033a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200041216a200141216a290000370000200041296a200141296a290000370000200041316a200141316a290000370000200041396a200141396a2900003700000f0b024002402001410c6a280200220341ffffff3f712003470d0020034105742202417f4c0d00200141046a28020021040240024020020d00410121050c010b200210292205450d020b0240024020030d0041002103410021010c010b20034105742106416020046b21072005210120042102034020012002290000370000200141186a200241186a290000370000200141106a200241106a290000370000200141086a200241086a290000370000200141206a2101200241206a2102200641606a22060d000b200420034105746a20076a41057641016a21010b200041043a00002000410c6a2001360200200041086a2003360200200041046a20053602000f0b1032000b20024101102c000b340020004188c7c20036020420004100360200200041146a4102360200200041106a4190c7c200360200200041086a42073702000b870402077f017e230041e0006b220224000240024002400240411a10292203450d00200341186a41002f00dec9423b0000200341106a41002900d6c942370000200341086a41002900cec942370000200341002900c6c9423700002002429a808080a003370244200220033602402001200241c0006a1046200228024421042002280248210120022802402103200241c0006a41186a22054200370300200241c0006a41106a22064200370300200241c0006a41086a220742003703002002420037034020032001200241c0006a1000200241186a41186a2005290300370300200241186a41106a2006290300370300200241186a41086a20072903003703002002200229034037031820024100360240200241186a4120200241c0006a1008210520022802402201417f460d022002200136023c20022005360238200241c0006a200241386a108f0320022802482206450d01200241086a2207200241c0006a41146a290200370300200241106a2208200241c0006a411c6a2802003602002002200229024c3703002002290340210902402001450d002005102e0b20002006360208200020093702002000200229030037020c200041146a20072903003702002000411c6a20082802003602000c030b411a4101102c000b41eff0c200413320024184f4c2001053000b200041003602080b02402004450d002003102e0b200241e0006a24000ba20301067f230041106b22022400200241003602082002420137030020002802002103024002400240410410292204450d0020024284808080c0003702042002200436020020042003360000200028020421050240024020022802042206200228020822046b4104490d00200441046a2103200228020021060c010b200441046a22032004490d0320064101742207200320032007491b22074100480d030240024020060d002007102921060c010b200228020020062007102a21060b2006450d0220022007360204200220063602000b20022003360208200620046a200536000020002802082104200041106a28020022032002104702402003450d0020034105742103034020042002104a200441206a2104200341606a22030d000b0b200028021421042000411c6a28020022032002104702402003450d0020034105742103034020042002104a200441206a2104200341606a22030d000b0b2002280204210420012802002001280204200228020022032002280208100402402004450d002003102e0b200241106a24000f0b41044101102c000b20074101102c000b102d000bb40202067f017e230041206b220224000240024002400240200128020422034104490d0020012802002204280000210520012003417c6a22063602042001200441046a36020020064104490d01200428000421062001200341786a3602042001200441086a360200200241106a20011030200228021022030d02200041003602080c030b200041003602080c020b200041003602080c010b200241106a41086a280200210720022802142104200241106a2001103002402002280210450d00200241086a200241106a41086a2802002201360200200220022903102208370300200041106a20073602002000200436020c200020033602082000200636020420002005360200200041146a20083702002000411c6a20013602000c010b200041003602082004450d002003102e0b200241206a24000b870402077f017e230041e0006b220224000240024002400240411a10292203450d00200341186a41002f0095ca423b0000200341106a410029008dca42370000200341086a4100290085ca42370000200341002900fdc9423700002002429a808080a003370244200220033602402001200241c0006a1046200228024421042002280248210120022802402103200241c0006a41186a22054200370300200241c0006a41106a22064200370300200241c0006a41086a220742003703002002420037034020032001200241c0006a1000200241186a41186a2005290300370300200241186a41106a2006290300370300200241186a41086a20072903003703002002200229034037031820024100360240200241186a4120200241c0006a1008210520022802402201417f460d022002200136023c20022005360238200241c0006a200241386a108f0320022802482206450d01200241086a2207200241c0006a41146a290200370300200241106a2208200241c0006a411c6a2802003602002002200229024c3703002002290340210902402001450d002005102e0b20002006360208200020093702002000200229030037020c200041146a20072903003702002000411c6a20082802003602000c030b411a4101102c000b41eff0c200413320024184f4c2001053000b200041003602080b02402004450d002003102e0b200241e0006a24000be20201047f230041c0006b2202240002400240410f10292203450d00200341076a410029008fc24237000020034100290088c2423700002003410f411e102a2204450d012004200036000f200241206a41186a22034200370300200241206a41106a22004200370300200241206a41086a220542003703002002420037032020044113200241206a1000200241186a2003290300370300200241106a2000290300370300200241086a200529030037030020022002290320370300200128020021052001280208210320024100360228200242013703202003200241206a104702402003450d00200341057421002005210303402003200241206a104a200341206a2103200041606a22000d000b0b2002280224210320024120200228022022002002280228100402402003450d002000102e0b2004102e0240200141046a280200450d002005102e0b200241c0006a24000f0b410f4101102c000b411e4101102c000b130020004101360204200041accac2003602000b34002000418bcec20036020420004100360200200041146a4102360200200041106a4194cec200360200200041086a42093702000b130020004101360204200041e0d0c2003602000b3101017f02404108102922020d0041084101102c000b20004288808080800137020420002002360200200242b8173700000b13002000410436020420004184d4c2003602000b340020004183dcc20036020420004100360200200041146a4105360200200041106a4198dcc200360200200041086a42133702000b3400200041cce2c20036020420004100360200200041146a4105360200200041106a41e0e2c200360200200041086a42133702000bd11e03037f027e047f23004190026b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e13000102030405060708090a0b0c0d0e0f101112000b20024188016a200141086a109a03200041003a0000200041106a20024188016a41086a290300370300200041086a2002290388013703000c120b200041013a00002000410220012d0001220141004720014102461b3a00010c110b200041023a0000200041086a200141086a2903003703000c100b20024188016a200141046a1039200041033a00002000410c6a20024190016a280200360200200041046a2002290388013702000c0f0b109b03000b0240024002400240200141086a280200417f6a220341014b0d0020030e020102010b41f8b3c0001058000b41012103024002402001410c6a2d00004101460d00200241026a2001410f6a2d00003a000020024190016a2001411c6a29020037030020024188016a41106a200141246a290200370300200241a0016a2001412c6a2d00003a000020022001410d6a2f00003b01002002200141146a29020037038801200141106a2802002104410021030c010b200141106a28020021040b200241246a41026a200241026a2d00003a0000200241286a41086a20024188016a41086a290300370300200241286a41106a20024188016a41106a290300370300200241286a41186a20024188016a41186a280200360200200220022f01003b01242002200229038801370328200141386a29030021052001290330210641012107200241106a21010c010b41012103024002402001410c6a2d00004101460d002002418e026a2001410f6a2d00003a000020024190016a2001411c6a29020037030020024188016a41106a200141246a290200370300200241a0016a2001412c6a2d00003a000020022001410d6a2f00003b018c022002200141146a29020037038801200141106a2802002104410021030c010b200141106a28020021040b41022107200241246a41026a2002418c026a41026a2d00003a0000200241286a41086a20024188016a41086a290300370300200241286a41106a20024188016a41106a290300370300200241286a41186a20024188016a41186a280200360200200220022f018c023b01242002200229038801370328200220012903303703102002200141386a290300370318200141c8006a290300210520012903402106200221010b20012006370300200120053703082000410c6a20033a0000200041086a20073602002000410d6a20022f01243b00002000410f6a200241266a2d00003a0000200041106a2004360200200041146a20022903283702002000411c6a200241286a41086a290300370200200041246a200241286a41106a2903003702002000412c6a200241c0006a280200360200200041386a200241106a41086a290300370300200041306a2002290310370300200041c0006a2002290300370300200041c8006a200241086a290300370300200041053a00000c0d0b20024188016a200141086a109c03200041063a0000200041386a20024188016a41306a290300370300200041306a20024188016a41286a290300370300200041286a20024188016a41206a290300370300200041206a20024188016a41186a290300370300200041186a20024188016a41106a290300370300200041106a20024188016a41086a290300370300200041086a2002290388013703000c0c0b20024188016a41186a200141286a29000037030020024188016a41106a200141206a29000037030020024190016a200141186a29000037030020024188016a41286a200141386a29000037030020024188016a41306a200141c0006a29000037030020024188016a41386a200141c8006a29000037030020024188016a41c8006a200141d8006a29000037030020024188016a41d0006a200141e0006a29000037030020024188016a41d8006a200141e8006a2900003703002002200141106a290000370388012002200141306a2900003703a8012002200141d0006a2900003703c8012001410c6a2802002203417f4c0d0c0240024020030d00410121010c010b200141046a2802002104200310292201450d0e20012004200310f6041a0b200241286a20024188016a41e00010f6041a2000410c6a2003360200200041086a2003360200200041046a2001360200200041106a200241286a41e00010f6041a200041073a00000c0b0b20024188016a200141086a109d03200041083a0000200041306a20024188016a41286a290300370300200041286a20024188016a41206a290300370300200041206a20024188016a41186a290300370300200041186a20024188016a41106a290300370300200041106a20024188016a41086a290300370300200041086a2002290388013703000c0a0b20024188016a200141046a109e03200041093a0000200041246a200241a8016a2903003702002000411c6a200241a0016a290300370200200041146a20024198016a2903003702002000410c6a20024190016a290300370200200041046a2002290388013702000c090b024002400240024002400240200141046a2d0000417f6a220341034b0d0020030e0401020304010b41dcc3c2001058000b200141106a280200220741ffffff3f712007470d0d20074105742203417f4c0d0d200141086a2802002108410121014101210902402003450d00200310292209450d100b024020070d0041002103410021070c040b20074105742104416020086b210a2009210120082103034020012003290000370000200141186a200341186a290000370000200141106a200341106a290000370000200141086a200341086a290000370000200141206a2101200341206a2103200441606a22040d000b41012101200820074105746a200a6a41057641016a21030c030b41880110292209450d0f2009200141086a280200109903410221010c020b200141086a280200210941880110292207450d0f20072001410c6a280200109903410321010c010b2002412a6a200141076a2d00003a000020024188016a41086a2001411c6a29000037030020024188016a41106a200141246a2d00003a00002002200141056a2f00003b01282002200141146a29000037038801200141256a2d00004100472108200141286a2802002104200141106a28000021032001410c6a2800002107200141086a2800002109410421010b2000410a3a0000200041046a20013a0000200041056a20022f01283b0000200041106a20033602002000410c6a2007360200200041086a2009360200200041146a200229038801370200200041286a2004360200200041256a20083a0000200041076a2002412a6a2d00003a00002000411c6a20024188016a41086a290300370200200041246a20024188016a41106a2d00003a00000c080b20024188016a200141086a10d8012000410b3a0000200041c0006a20024188016a41386a290300370300200041386a20024188016a41306a290300370300200041306a20024188016a41286a290300370300200041286a20024188016a41206a290300370300200041206a20024188016a41186a290300370300200041186a20024188016a41106a290300370300200041106a20024188016a41086a290300370300200041086a2002290388013703000c070b20024188016a200141046a108b03200041046a20024188016a41c40010f6041a2000410c3a00000c060b2000410d3a0000200041046a200141046a2802003602000c050b2001410c6a2802002203417f4c0d050240024020030d00410121010c010b200141046a2802002104200310292201450d0b20012004200310f6041a0b2000410e3a00002000410c6a2003360200200041086a2003360200200041046a20013602000c040b024002400240024002400240200141086a280200417f6a220341024b0d0020030e03010203010b4184dbc0001058000b200141386a2903002105200141306a290300210641012103024002402001410c6a2d00004101460d0020024190016a2001411c6a29020037030020024188016a41106a200141246a290200370300200241a0016a2001412c6a2d00003a00002002200141146a290200370388012001410d6a2f00002001410f6a2d0000411074722104200141106a2802002101410021030c010b200141106a28020021010b200241286a41186a20024188016a41186a280200360200200241286a41106a20024188016a41106a290300370300200241286a41086a20024188016a41086a2903003703002002200229038801370328410121070c030b2001410c6a28020022034108762104410221070c010b2001410c6a28020022034108762104410321070b0b2000410f3a0000200041386a2005370300200041306a2006370300200041106a2001360200200041086a2007360200200041146a20022903283702002000410c6a2004410874200341ff0171723602002000411c6a200241286a41086a290300370200200041246a200241286a41106a2903003702002000412c6a200241c0006a2802003602000c030b20024188016a200141086a109f03200041086a20024188016a41800110f6041a200041103a00000c020b0240024002400240200141046a280200417f6a220341014b0d0020030e020102010b41a8c2c2001058000b41880110292203450d0a2003200141086a280200109903410121010c010b4101210302400240200141086a2d00004101460d0020024188016a41086a200141186a29000037030020024188016a41106a200141206a29000037030020024188016a41186a200141286a2d00003a00002002200141106a29000037038801200141096a2f00002001410b6a2d00004110747241087421072001410c6a2800002104410021030c010b2001410c6a2802002104410021070b200241286a41186a20024188016a41186a280200360200200241286a41106a20024188016a41106a290300370300200241286a41086a20024188016a41086a290300370300200220022903880137032820032007722103410221010b200041113a00002000410c6a2004360200200041086a2003360200200041046a2001360200200041106a2002290328370200200041186a200241286a41086a290300370200200041206a200241286a41106a290300370200200041286a200241286a41186a2802003602000c010b20024188016a200141046a108002200041046a20024188016a41e40010f6041a200041123a00000b20024190026a24000f0b1032000b20034101102c000b20034101102c000b4188014108102c000b4188014108102c000b20034101102c000b4188014108102c000bac0703037f017e077f0240024002400240024002400240024002400240024002400240024002402001280200417f6a220241054b0d0020020e06010203040506010b4194f4c2001058000b200041013602000f0b2001410c6a2802002202417f4c0d04200128020421010240024020020d00410121030c010b200210292203450d060b20032001200210f60421012000410c6a2002360200200041086a200236020020002001360204200041023602000f0b20004103360200200041086a200141086a2903003703000f0b2001410c6a2802002202417f4c0d02200128020421010240024020020d00410121030c010b200210292203450d050b20032001200210f60421012000410c6a2002360200200041086a200236020020002001360204200041043602000f0b2001410c6a2802002204ad42187e2205422088a70d012005a72203417f4c0d01200128020421020240024020030d00410421060c010b200310292206450d050b0240024020040d00410021070c010b2002200441186c6a210841002107200621010340200241086a2802002203417f4c0d030240024020030d00410121090c010b2002280200210a200310292209450d082009200a200310f6041a0b200241146a280200220a417f4c0d0302400240200a0d004101210b0c010b2002410c6a280200210c200a1029220b450d09200b200c200a10f6041a0b20012009360200200141146a200a360200200141106a200a3602002001410c6a200b360200200141086a2003360200200141046a2003360200200141186a2101200741016a2107200241186a22022008470d000b0b20002006360204200041053602002000410c6a2007360200200041086a20043602000f0b2001410c6a280200220cad420c7e2205422088a70d002005a72202417f4c0d00200128020421030240024020020d00410421080c010b200210292208450d070b02400240200c0d004100210a0c010b2003200c410c6c6a21074100210a200821020340200341086a2802002201417f4c0d02200328020021090240024020010d004101210b0c010b20011029220b450d0a0b200b2009200110f6042109200241086a2001360200200241046a2001360200200220093602002002410c6a2102200a41016a210a2003410c6a22032007470d000b0b20002008360204200041063602002000410c6a200a360200200041086a200c3602000f0b1032000b20024101102c000b20024101102c000b20034104102c000b20034101102c000b200a4101102c000b20024104102c000b20014101102c000b0a004180c3c2001058000bcc0c03047f017e057f230041206b22022400024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a2203410d4b0d0020030e0e0102030405060708090a0b0c0d0e010b41b8bfc4001058000b4101210302400240200141046a2d00004101460d002002411e6a200141076a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a00002002200141056a2f00003b011c20022001410c6a290000370300200141086a2800002104410021030c010b200141086a28020021040b200041286a2001290328370300200041046a20033a0000200041056a20022f011c3b0000200041086a20043602002000410c6a2002290300370200200041306a200141306a290300370300200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a28020036020020012d00012101200041013a0000200020013a00010c0d0b200041023a0000200041106a200141106a290300370300200041086a200141086a2903003703000c0c0b200041033a0000200041106a200141106a290300370300200041086a200141086a2903003703000c0b0b200041043a00000c0a0b200041053a0000200041106a200141106a290300370300200041086a200141086a290300370300200041186a200141186a2802003602000c090b2001410c6a2802002205ad42247e2206422088a70d092006a72204417f4c0d09200141046a28020021030240024020040d00410421070c010b200410292207450d0b0b0240024020050d00410021040c010b200541246c2108410021042002411e6a21092007210103400240024020032d00004101460d002009200341036a2d00003a0000200341046a280000210a200341016a2f0000210b200241086a200341106a290000370300200241106a200341186a290000370300200241186a200341206a2d00003a00002002200b3b011c2002200341086a2900003703004100210b0c010b200341046a280200210a4101210b0b200341246a21032001200b3a0000200141046a200a360200200141016a20022f011c3b0000200141036a20092d00003a0000200141086a2002290300370200200141106a200241086a290300370200200141186a200241106a290300370200200141206a200241186a280200360200200141246a2101200441016a21042008415c6a22080d000b0b200041063a00002000410c6a2004360200200041086a2005360200200041046a20073602000c080b200041073a00000c070b200041083a0000200020012d00013a00010c060b4101210302400240200141046a2d00004101460d002002411e6a200141076a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a00002002200141056a2f00003b011c20022001410c6a290000370300200141086a2800002101410021030c010b200141086a28020021010b200041093a0000200041046a20033a0000200041056a20022f011c3b0000200041086a20013602002000410c6a2002290300370200200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c050b2000410a3a0000200041046a200141046a2802003602000c040b2000410b3a00000c030b2000410c3a00000c020b2000410d3a0000200041046a200141046a2802003602000c010b2001410c6a280200220841ffffff3f712008470d0120084105742203417f4c0d01200141046a280200210a0240024020030d004101210b0c010b20031029220b450d040b0240024020080d0041002108410021010c010b200841057421044160200a6b2109200b2101200a2103034020012003290000370000200141186a200341186a290000370000200141106a200341106a290000370000200141086a200341086a290000370000200141206a2101200341206a2103200441606a22040d000b200a20084105746a20096a41057641016a21010b2000410e3a00002000410c6a2001360200200041086a2008360200200041046a200b3602000b200241206a24000f0b1032000b20044104102c000b20034101102c000bab0701017f024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a220241104b0d0020020e110102030405060708090a0b0c0d0e0f1011010b41e890c5001058000b41880110292202450d102002200141046a28020010fd03200041046a2002360200200041013a0000200041106a200141106a290300370300200041086a200141086a2903003703000f0b200041023a0000200041046a200141046a2802003602000f0b200041033a0000200041046a200141046a280200360200200041026a200141026a2d00003a0000200020012d00014101713a00010f0b200041043a0000200041046a200141046a280200360200200041026a200141026a2d00003a0000200020012d00014101713a00010f0b200041053a0000200041046a200141046a2802003602000f0b41880110292202450d0c2002200141046a28020010fd03200041063a0000200041046a20023602000f0b41880110292202450d0c2002200141046a28020010fd03200041073a0000200041046a20023602000f0b41880110292202450d0c2002200141046a28020010fd03200041083a0000200041046a20023602000f0b200041093a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2902003702000f0b2000410a3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b2000410b3a0000200041046a200141046a2802003602000f0b2000410c3a00002000410c6a2001410c6a280200360200200041046a200141046a2902003702000f0b2000410d3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b2000410e3a00000f0b2000410f3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b200041103a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00003a00000f0b200041113a00000f0b4188014108102c000b4188014108102c000b4188014108102c000b4188014108102c000b9f0401067f02400240024002400240024002400240024020012d0000417f6a220241034b0d0020020e0401020304010b41dcc3c2001058000b2001410c6a280200220341ffffff3f712003470d0320034105742202417f4c0d03200141046a28020021040240024020020d00410121050c010b200210292205450d050b0240024020030d0041002103410021010c010b20034105742106416020046b21072005210120042102034020012002290000370000200141186a200241186a290000370000200141106a200241106a290000370000200141086a200241086a290000370000200141206a2101200241206a2102200641606a22060d000b200420034105746a20076a41057641016a21010b200041013a00002000410c6a2001360200200041086a2003360200200041046a20053602000f0b41880110292202450d042002200141046a280200109903200041023a0000200041046a20023602000f0b200141046a280200210641880110292202450d042002200141086a280200109903200041086a2002360200200041046a2006360200200041033a00000f0b200041043a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a280200360200200041216a200141216a2d00004100473a00000f0b1032000b20024101102c000b4188014108102c000b4188014108102c000bee0b05027f017e027f027e017f230041c0006b220224000240024002400240024002400240024002400240024020012d0000417f6a220341044b0d0020030e050102030405010b41c4e0c3001058000b200041f9006a2002280020360000200041086a200141086a290300370300200041fc006a200241236a280000360000200041106a200141106a290300370300200041186a200141186a290300370300200041206a200141206a290300370300200041286a200141286a290300370300200041306a200141306a290300370300200041386a200141386a290300370300200041c0006a200141c0006a290300370300200041c8006a200141c8006a290300370300200041d0006a200141d0006a290300370300200041d8006a200141d8006a290300370300200041e0006a200141e0006a290300370300200041e8006a200141e8006a290300370300200041f0006a200141f0006a290300370300200041f8006a200141f8006a2d00004100473a0000200041013a00000c040b2001410c6a2802002203417f4c0d04200141106a29030021040240024020030d00410121010c010b200141046a2802002105200310292201450d0620012005200310f6041a0b200041023a00002000410c6a2003360200200041086a2003360200200041046a2001360200200041106a20043703000c030b4101210502400240200141046a2d00004101460d00200241026a200141076a2d00003a0000200241206a41086a200141146a290000370300200241306a2001411c6a290000370300200241386a200141246a2d00003a00002002200141056a2f00003b010020022001410c6a290000370320200141086a2800002106410021050c010b200141086a28020021060b200141306a2802002203417f4c0d03200141c0006a290300210420012903382107200129034821080240024020030d00410121010c010b20012802282109200310292201450d0620012009200310f6041a0b200041c0006a2004370300200041386a2007370300200041046a20053a0000200041056a20022f01003b0000200041086a20063602002000410c6a2002290320370200200041c8006a2008370300200041306a20033602002000412c6a2003360200200041286a2001360200200041076a200241026a2d00003a0000200041146a200241206a41086a2903003702002000411c6a200241306a290300370200200041246a200241386a280200360200200041033a00000c020b200141386a2903002104200141306a2903002107200141c0006a2903002108200241386a200141196a290000370300200241306a200141116a290000370300200241286a200141096a290000370300200220012900013703202001412c6a2802002203417f4c0d020240024020030d00410121010c010b200141246a2802002105200310292201450d0620012005200310f6041a0b20002002290320370001200041043a0000200041386a2004370300200041306a2007370300200041c0006a20083703002000412c6a2003360200200041286a2003360200200041246a2001360200200041096a200241286a290300370000200041116a200241306a290300370000200041196a200241386a2903003700000c010b200241186a2205200141196a290000370300200241106a2206200141116a290000370300200241086a2209200141096a29000037030020022001290001370300410021030240200141216a2d00004101470d00200241206a41186a2001413a6a290000370300200241206a41106a200141326a290000370300200241206a41086a2001412a6a2900003703002002200141226a290000370320410121030b20002002290300370001200041216a20033a0000200041226a2002290320370000200041196a2005290300370000200041116a2006290300370000200041096a20092903003700002000412a6a200241206a41086a290300370000200041326a200241206a41106a2903003700002000413a6a200241206a41186a290300370000200041053a00000b200241c0006a24000f0b1032000b20034101102c000b20034101102c000b20034101102c000b130020004102360204200041a8eac2003602000b3400200041cdeec20036020420004100360200200041146a4101360200200041106a41d4eec200360200200041086a42043702000bcf0101017f024002400240024002400240410110292202450d00200241003a0000200241014102102a2202450d01200241003a0001200241024104102a2202450d02200241003b0002200241044108102a2202450d0320024100360004200241084110102a2202450d0420024200370008200241104120102a2202450d052002420037001820024200370010200042a08080808004370204200020023602000f0b41014101102c000b41024101102c000b41044101102c000b41084101102c000b41104101102c000b41204101102c000bd40201027f0240024002402002450d002002417f6a2103024020012d0000220241037122044103460d000240024020040e03040001040b2003450d0220012d0001410874200272220241ffff0371418002490d02200241fcff037141027621020c040b20034103490d0120012f0001200141036a2d000041107472410874200272220241808004490d01200241027621020c030b200241034b0d0020034104490d002001280001220241ffffffff034b0d020b200041013602000f0b200241027621020b410121040240200241016a220120024f0d00200041013602000f0b0240200241c000490d0041022104200241808001490d00410441052002418080808004491b21040b410121020240200141c000490d0041022102200141808001490d00410441052001418080808004491b21020b20002001360204200041003602002000410c6a2002360200200041086a20043602000bdf0401047f02400240024002400240024020002802704101460d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0620024101742204200320032004491b22044100480d060240024020020d002004102921030c010b200128020020022004102a21030b2003450d0320012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41003a00002000280274210502400240200141046a2802002203200428020022026b4104490d00200128020021030c010b200241046a22042002490d0620034101742202200420042002491b22024100480d060240024020030d002002102921030c010b200128020020032002102a21030b2003450d0420012003360200200141046a2002360200200141086a28020021020b200141086a200241046a360200200320026a20053600000c010b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0520024101742204200320032004491b22044100480d050240024020020d002004102921030c010b200128020020022004102a21030b2003450d0420012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a00000b200020011084022000280278210220004180016a28020022002001104702402000450d00200041057421000340200220011046200241206a2102200041606a22000d000b0b0f0b20044101102c000b20024101102c000b20044101102c000b102d000be80101017f024020002d0000417b6a220141074b0d00024002400240024020010e080004040104020403000b200041086a2d00004101470d03200041146a280200450d03200041106a280200102e0c030b200041046a2d00004103470d0202402000410c6a280200450d00200041086a280200102e0b200041186a280200450d02200041146a280200102e0c020b200041046a2802000d012000410c6a280200450d01200041086a280200102e0c010b200041086a2d00004105490d00200041306a280200450d002000412c6a280200102e0b0240200041fc006a280200450d002000280278102e0b0b130020004106360204200041b8f6c2003602000b3400200041c3fcc20036020420004100360200200041146a410f360200200041106a41ccfcc200360200200041086a42063702000b6701017f230041306b22022400200241186a4200370300200241106a4200370300200241086a42003703002002420037030020024100360228200242013703202002200241206a1046200041086a200228022836020020002002290320370200200241306a24000b5c01027f230041106b2202240002404101102922030d0041014101102c000b200341003a0000200242818080801037020420022003360200410020021047200041086a200228020836020020002002290300370200200241106a24000b130020004100360204200041c8ecc5003602000b9609030b7f017e027f230041c0016b2202240020024100360298012001412020024198016a1008210302400240024002402002280298012204417f470d00200041023a000c0c010b2002200436020420022003360200200241086a2002103020022802082205450d02200228020c210620022802042201450d01200241106a280200210720022001417f6a220836020420022002280200220941016a220a36020020092d0000220141014b0d014100210b0240024020010e020100010b41002101200241003a00b8010340024020082001470d0020024100360204200141ff0171450d04200241003a00b8010c040b20024198016a20016a200920016a220c41016a2d00003a00002002200c41026a3602002002200141016a220c3a00b801200c2101200c4120470d000b200241d8006a41086a20024198016a41086a290300220d370300200241386a41186a20024198016a41186a290300370300200241386a41106a20024198016a41106a290300370300200241386a41086a200d37030020022008200c6b22083602042002200229039801220d3703582002200d3703384101210b2009200c6a41016a210a0b200241186a41186a200241386a41186a290300370300200241186a41106a200241386a41106a290300370300200241186a41086a200241386a41086a290300370300200220022903383703182008450d0120022008417f6a22083602042002200a41016a360200200a2d0000220c41014b0d014100210102400240200c0e020100010b41002101200241003a00b8010340024020082001470d0020024100360204200141ff0171450d04200241003a00b8010c040b20024198016a20016a200a20016a220c41016a2d00003a00002002200c41026a3602002002200141016a220c3a00b801200c2101200c4120470d000b200241d8006a41086a20024198016a41086a290300220d370300200241386a41186a20024198016a41186a290300370300200241386a41106a20024198016a41106a290300370300200241386a41086a200d37030020022008200c6b3602042002200229039801220d3703582002200d370338410121010b200241f8006a41186a220c200241386a41186a290300370300200241f8006a41106a2208200241386a41106a290300370300200241f8006a41086a220a200241386a41086a29030037030020024198016a41086a2209200241186a41086a29030037030020024198016a41106a220e200241186a41106a29030037030020024198016a41186a220f200241186a41186a290300370300200220022903383703782002200229031837039801200b4102460d022000200b3a000c200020073602082000200636020420002005360200200020022903980137000d2000412d6a20013a00002000412e6a2002290378370000200041156a20092903003700002000411d6a200e290300370000200041256a200f290300370000200041366a200a2903003700002000413e6a2008290300370000200041c6006a200c290300370000200041ce006a20022f01583b01002004450d002003102e0b200241c0016a24000f0b2006450d002005102e0b41eff0c2004133200241386a4184f4c2001053000b850101037f230041106b22022400410021032002410036020420014110200241046a1008210102400240024020022802042204417f470d000c010b024020010d000c010b20044104490d01200128000021042001102e410121030b2000200436020420002003360200200241106a24000f0b41eff0c2004133200241086a4184f4c2001053000beb0905047f027e057f017e037f230041e0016b22022400200241003602b80120014120200241b8016a1008210302400240024020022802b8012204417f470d00200041023a00180c010b2002200436022c20022003360228200241206a200241286a103120022802200d0120022802242105200241086a200241286a10652002290308a70d01200228022c2201450d01200241186a29030021062002290310210720022001417f6a220836022c20022002280228220941016a220a36022820092d0000220141014b0d014100210b0240024020010e020100010b41002101200241003a00d8010340024020082001470d002002410036022c200141ff0171450d04200241003a00d8010c040b200241b8016a20016a200920016a220c41016a2d00003a00002002200c41026a3602282002200141016a220c3a00d801200c2101200c4120470d000b200241f8006a41086a200241b8016a41086a290300220d370300200241d8006a41186a200241b8016a41186a290300370300200241d8006a41106a200241b8016a41106a290300370300200241d8006a41086a200d37030020022008200c6b220836022c200220022903b801220d3703782002200d3703584101210b2009200c6a41016a210a0b200241386a41186a200241d8006a41186a290300370300200241386a41106a200241d8006a41106a290300370300200241386a41086a200241d8006a41086a290300370300200220022903583703382008450d0120022008417f6a220836022c2002200a41016a360228200a2d0000220c41014b0d014100210102400240200c0e020100010b41002101200241003a00d8010340024020082001470d002002410036022c200141ff0171450d04200241003a00d8010c040b200241b8016a20016a200a20016a220c41016a2d00003a00002002200c41026a3602282002200141016a220c3a00d801200c2101200c4120470d000b200241f8006a41086a200241b8016a41086a290300220d370300200241d8006a41186a200241b8016a41186a290300370300200241d8006a41106a200241b8016a41106a290300370300200241d8006a41086a200d37030020022008200c6b36022c200220022903b801220d3703782002200d370358410121010b20024198016a41186a220c200241d8006a41186a29030037030020024198016a41106a2208200241d8006a41106a29030037030020024198016a41086a220a200241d8006a41086a290300370300200241b8016a41086a2209200241386a41086a290300370300200241b8016a41106a220e200241386a41106a290300370300200241b8016a41186a220f200241386a41186a2903003703002002200229035837039801200220022903383703b801200241f8006a41046a2210200241326a41046a2f01003b010020022002280132360278200b4102460d01200020073703002000200b3a001820002005360210200020022903b80137001920002006370308200041396a20013a00002000413a6a200229039801370000200041216a2009290300370000200041296a200e290300370000200041316a200f290300370000200041c2006a200a290300370000200041ca006a2008290300370000200041d2006a200c290300370000200041de006a20102f01003b0100200041da006a20022802783601002004450d002003102e0b200241e0016a24000f0b41eff0c2004133200241d8006a4184f4c2001053000bca0708047f047e067f027e017f017e017f017e230041b0016b2202240020024100360288012001412020024188016a10082103024002400240024002400240024002402002280288012204417f460d0020030d010b200041003602200c010b200220043602642002200336026041002101200241003a00a8010340024020042001470d0020024100360264200141ff0171450d07200241003a00a8010c070b20024188016a20016a200320016a22052d00003a00002002200541016a3602602002200141016a22053a00a8012005210120054120470d000b200241e8006a41086a20024188016a41086a290300370300200241e8006a41106a20024188016a41106a290300370300200241e8006a41186a20024188016a41186a29030037030020022002290388013703682002200420056b360264200241c8006a200241e0006a10652002290348a70d05200241c8006a41106a290300210620022903502107200241306a200241e0006a10652002290330a70d05200241306a41106a290300210820022903382109200241286a200241e0006a103120022802280d05200228026441186e220a41186c2201417f4c0d01200228022c210b0240024020010d004108210c0c010b20011029220c450d030b0240200b450d00200241106a41106a210d4100210e4100210f410021050340200241106a200241e0006a1065024002402002290310a70d00200d290300211020022903182111200241086a200241e0006a10312002280208450d010b200a450d08200c102e0c080b200541016a2101200228020c211202402005200a470d00200e20012001200e491b220aad42187e2213422088a70d072013a722144100480d070240024020050d0020141029210c0c010b200c200f2014102a210c0b200c450d060b200c200f6a2205201037030820052011370300200541106a2012360200200e41026a210e200f41186a210f20012105200b2001470d000b0b200c450d0520024188016a41186a200241e8006a41186a290300221037030020024188016a41106a200241e8006a41106a290300221137030020024188016a41086a200241e8006a41086a290300221337030020022002290368221537038801200041186a20083703002000200937031020002006370308200020073703002000200bad422086200aad843702242000200c3602202000412c6a2015370200200041346a20133702002000413c6a2011370200200041c4006a20103702002004450d002003102e0b200241b0016a24000f0b1032000b20014108102c000b20144108102c000b102d000b41eff0c2004133200241e8006a4184f4c2001053000bdb0102027f037e230041206b220224002002410036021020014120200241106a10082101024002400240024020022802102203417f460d0020010d010b200041003602100c010b200220013602082002200336020c20034110490d012002200341706a36020c2002200141106a360208200141086a290000210420012900002105200241106a200241086a103020022802102203450d0120022902142106200020043703082000200537030020002006370214200020033602102001102e0b200241206a24000f0b41eff0c2004133200241106a4184f4c2001053000bcb0702107f017e230041a0056b22022400200241003602f00320014110200241f0036a1008210302400240024002400240024020022802f0032204417f470d00200041003602000c010b2002200436021420022003360210200241086a200241106a103120022802080d04200228021441b0016e220541b0016c2201417f4c0d01200228020c21060240024020010d00410821070c010b200110292207450d030b02402006450d00200241e8026a4101722108410021094100210a0340024002400240200228021422014104490d002002280210220b280000210c20022001417c6a3602142002200b41046a360210200241f0036a200241106a10b80120022d00f0034113460d00200a41016a210d200241e8026a200241f0036a41880110f6041a4100210b200241003a0098052002280214417f6a2101024003402001417f460d01200241f8046a200b6a2002280210220e2d00003a00002002200e41016a3602102002200b41016a220e3a009805200220013602142001417f6a2101200e210b200e4120470d000b200241c0016a41186a2201200241f8046a41186a290300370300200241c0016a41106a220e200241f8046a41106a290300370300200241c0016a41086a220f200241f8046a41086a290300370300200220022903f8043703c00120022d00e802210b200241e1016a200841870110f6041a200b4113460d01200241396a200241e1016a41870110f6041a200241186a41186a22102001290300370300200241186a41106a2211200e290300370300200241186a41086a220e200f290300370300200220022903c0013703182005200a470d030240200a4101742201200d200d2001491b2205ad42b0017e2212422088a70d002012a7220141004e0d030b102d000b0240200b41ff0171450d00200241003a0098050b200241e8026a102f0b0240200a450d002007210103402001102f200141b0016a2101200941d07e6a22090d000b0b2005450d082007102e0c080b02400240200a0d002001102921070c010b2007200a41b0016c2001102a21070b2007450d060b2007200a41b0016c6a2201200b3a0000200141016a200241396a41870110f6041a2001200c360288012001200229031837028c0120014194016a200e2903003702002001419c016a2011290300370200200141a4016a2010290300370200200941b0016a2109200d210a200d2006470d000b0b2007450d042000200536020420002007360200200041086a20063602002004450d002003102e0b200241a0056a24000f0b1032000b20014108102c000b20014108102c000b41eff0c2004133200241f0036a4184f4c2001053000bab0201057f230041b0026b22022400200241003602a80120014110200241a8016a100821030240024020022802a8012201417f470d00200041033a0088010c010b2002200136021420022003360210200241a8016a200241106a10b8010240024020022d00a8014113460d00200241206a200241a8016a41880110f6041a024020022802142204450d00200228021022052d0000210620022004417f6a3602142002200541016a36021020064103490d020b200241206a102f0b41eff0c2004133200241a8016a4184f4c2001053000b2000200241206a41880110f60421002002200241196a41036a28000036000b20022002280019360208200020063a00880120002002280208360089012000418c016a200228000b3600002001450d002003102e0b200241b0026a24000bc50b03087f017e067f230041d0016b22022400200241003602a80120014120200241a8016a10082103024002400240024020022802a8012204417f460d0020030d010b200041023a00210c010b41002101200241003a00c8012004417e6a21050340024020042001470d00200141ff0171450d03200241003a00c8010c030b200241a8016a20016a200320016a2d00003a00002002200141016a22063a00c8012005417f6a21052006210120064120470d000b20024188016a41186a200241a8016a41186a29030037030020024188016a41106a200241a8016a41106a29030037030020024188016a41086a200241a8016a41086a290300370300200220022903a8013703880120042006460d01200320066a22072d0000220841074f0d01200241086a41186a20024188016a41186a290300370300200241086a41106a20024188016a41106a290300370300200241086a41086a20024188016a41086a29030037030020022002290388013703082004417f6a2006460d01200741016a2d0000220141014b0d01200420066b210902400240024020010e020100010b41002101200241003a00c8012009417e6a21090340024020092001470d00200141ff0171450d05200241003a00c8010c050b200241a8016a20016a200720016a41026a2d00003a00002002200141016a22063a00c8012006210120064120470d000b200241e8006a41086a200241a8016a41086a290300220a370300200241c8006a41186a200241a8016a41186a290300370300200241c8006a41106a200241a8016a41106a290300370300200241c8006a41086a200a370300200220022903a801220a3703682002200a370348200520066b210b200720066a41026a2106410121090c010b200741026a21062009417e6a210b410021090b200241286a41186a200241c8006a41186a290300370300200241286a41106a200241c8006a41106a290300370300200241286a41086a200241c8006a41086a29030037030020022002290348370328200b450d0120062d0000220541014b0d01410021010240024020050e020100010b41002101200241003a00c801200641016a2105200b417f6a21070340024020072001470d00200141ff0171450d04200241003a00c8010c040b200241a8016a20016a200520016a2d00003a00002002200141016a22063a00c8012006210120064120470d000b200241e8006a41086a200241a8016a41086a290300220a370300200241c8006a41186a200241a8016a41186a290300370300200241c8006a41106a200241a8016a41106a290300370300200241c8006a41086a200a370300200220022903a801220a3703682002200a370348410121010b200241e8006a41186a2206200241c8006a41186a290300370300200241e8006a41106a2205200241c8006a41106a290300370300200241e8006a41086a2207200241c8006a41086a29030037030020024188016a41086a220b200241286a41086a29030037030020024188016a41106a220c200241286a41106a29030037030020024188016a41186a220d200241286a41186a290300370300200220022903483703682002200229032837038801200241a8016a41186a220e200241086a41186a290300370300200241a8016a41106a220f200241086a41106a290300370300200241a8016a41086a2210200241086a41086a290300370300200220022903083703a80120094102460d01200020022903a801370000200020093a0021200020083a00202000200229038801370022200041186a200e290300370000200041106a200f290300370000200041086a20102903003700002000412a6a200b290300370000200041326a200c2903003700002000413a6a200d290300370000200041c2006a20013a0000200041c3006a2002290368370000200041cb006a2007290300370000200041d3006a2005290300370000200041db006a20062903003700002004450d002003102e0b200241d0016a24000f0b41eff0c2004133200241c8006a4184f4c2001053000bc40101037f230041206b220224002002410036021020014110200241106a10082101024002400240024020022802102203417f460d0020010d010b200041003602040c010b200220013602082002200336020c20034104490d0120022003417c6a36020c2002200141046a36020820012800002103200241106a200241086a104120022802102204450d012000200229021437020820002004360204200020033602002001102e0b200241206a24000f0b41eff0c2004133200241106a4184f4c2001053000b0a004198f3c2001058000b0a0041a8f2c2001058000bcd6704167f017e087f017e23004180036b2204240041002105200441003602f002200420023602ec02200420013602e8020240024002400240024002400240200241034b0d0041012106200441013a00d002200441ec016a4101360200200442013702dc01200441e8d4c5003602d801200441213602b4022004200441b0026a3602e8012004200441d0026a3602b00220044180016a200441d8016a108a042004280280012107200428028401210820042802880121094105210a4100210b0c010b200441043602f002024020012800004180c2cdeb06460d004101210a410121060c010b024002402002417c714104460d00200241074b0d0141082002105e000b41012106200441013a00d002200441ec016a4101360200200442013702dc01200441e8d4c5003602d801200441213602b4022004200441b0026a3602e8012004200441d0026a3602b00220044180016a200441d8016a108a042004280280012107200428028401210820042802880121094105210a410021054100210b0c010b200441083602f002410121060240200128000422074101460d004102210a0c010b200441d8016a200441e8026a10960402400240024020042802d8014101470d00410421084100210c410021090c010b200441d8016a410572210d410421084128210a410021054100210c410021094100210b02400340200441d0026a41026a2201200d41026a2d00003a00002004200d2f00003b01d002200428028402210e200428028002210f20042802fc01211020042802f801211120042802f401211220042802f001211320042802ec01211420042802e801211520042802e401211620042802e0012117024020042d00dc012206417e6a41ff0171410a4b0d004100211802400240024002400240024002400240024002400240024020060e0f0b0b000102030405060708090a0b0b0b0b410121180c0a0b410221180c090b410321180c080b410421180c070b410521180c060b410621180c050b410721180c040b410821180c030b410921180c020b410a21180c010b410b21180b0240200b41ff0171221920184d0d004113210a0c030b4100211802400240024002400240024002400240024002400240024020060e0f0b0b000102030405060708090a0b0b0b0b410121180c0a0b410221180c090b410321180c080b410421180c070b410521180c060b410621180c050b410721180c040b410821180c030b410921180c020b410a21180c010b410b21180b024020192018470d004114210a0c030b4100210b0240024002400240024002400240024002400240024020060e0f0b0b000102030405060708090a0b0b0b0b4101210b0c0a0b4102210b0c090b4103210b0c080b4104210b0c070b4105210b0c060b4106210b0c050b4107210b0c040b4108210b0c030b4109210b0c020b410a210b0c010b410b210b0b20044180016a41026a221820012d00003a0000200420042f01d0023b01800102400240200c2009470d00200c41016a2201200c490d072005200120012005491b2209ad422c7e221a422088a70d07201aa722014100480d0702400240200c0d002001102921080c010b2008200a41586a2001102a21080b2008450d010b2008200a6a220141586a20063a00002001200e3602002001417c6a200f360200200141786a2010360200200141746a2011360200200141706a20123602002001416c6a2013360200200141686a2014360200200141646a2015360200200141606a20163602002001415c6a2017360200200141596a220120042f0180013b0000200141026a20182d00003a0000200541026a2105200a412c6a210a200c41016a210c200441d8016a200441e8026a10960420042802d8014101460d030c010b0b20014104102c000b024002402006410d4b0d00024002400240024002400240024002400240024002400240024020060e0e0001020304050607080e090a0b0c000b2016450d0d2017102e0c0d0b02402016450d002017102e0b2013450d0c2014102e0c0c0b02402015450d00201541047421062017210103400240200141046a280200450d002001280200102e0b200141106a2101200641706a22060d000b0b2016450d0b2017102e0c0b0b02402015450d00201541286c21062017210103400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141286a2101200641586a22060d000b0b2016450d0a2017102e0c0a0b2016450d092017102e0c090b2016450d082017102e0c080b2016450d072017102e0c070b02402015450d00201720154104746a210d201721050340024020052802082206450d0020052802002101200641047421060340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200641706a22060d000b0b200541106a21010240200541046a280200450d002005280200102e0b200121052001200d470d000b0b2016450d062017102e0c060b02402015450d00201541146c21062017210103400240200141046a280200450d002001280200102e0b200141146a21012006416c6a22060d000b0b2016450d052017102e0c050b02402015450d0020172015411c6c6a210d20172105034002402005410c6a2802002206450d0020052802042101200641047421060340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200641706a22060d000b0b0240200541086a280200450d002005280204102e0b2005411c6a21010240200541146a280200450d002005280210102e0b200121052001200d470d000b0b2016450d042017102e0c040b02402015450d002017201541186c6a210d2017210503400240200541046a280200450d002005280200102e0b0240200541146a2802002206450d00200528020c2101200641047421060340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200641706a22060d000b0b200541186a21010240200541106a280200450d00200528020c102e0b200121052001200d470d000b0b2016450d032017102e0c030b02402015450d0020172015411c6c6a210d20172105034002402005410c6a2802002206450d0020052802042101200641047421060340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200641706a22060d000b0b0240200541086a280200450d002005280204102e0b2005411c6a21010240200541146a280200450d002005280210102e0b200121052001200d470d000b0b2016450d022017102e0c020b0240201741ff0171220141024b0d0002400240024020010e03000102000b2015450d042016102e0c040b02402013450d002013410c6c2106201521010340024020012802002205450d00200141046a280200450d002005102e0b2001410c6a2101200641746a22060d000b0b2014450d032015102e0c030b02402013450d00201520134104746a21162015211703402017220d41106a21170240200d2802042201450d000240200d410c6a2802002206450d002006410c6c21060340024020012802002205450d00200141046a280200450d002005102e0b2001410c6a2101200641746a22060d000b0b200d41086a280200450d00200d280204102e0b20172016470d000b0b2014450d022015102e0c020b2015450d012016102e0c010b02402016450d002017102e0b02402013450d002012450d002013102e0b200f450d002010102e0b0c010b024020042d00dc010d00200c412c6c210641002105410021010240034020062001460d01200820016a210a2001412c6a220b2101200a2d0000410b470d000b2008200b6a41606a28020021050b200c412c6c21064100210d410021010240034020062001460d01200820016a210a2001412c6a220b2101200a2d00004104470d000b200441f8006a2008200b6a41586a10b703200428027c210d0b02402005200d470d004100210a4101210741e100210b41f3da012105410021060c030b0240200c450d00200c412c6c210a200821010340200110bf032001412c6a2101200a41546a220a0d000b0b410121064119210a024020090d000c030b2008102e0c020b20042802dc01220a4110762105200a410876210b200441d8016a41106a280200210d200441e4016a2802002117200441d8016a41086a28020021070b0240200c450d00200c412c6c2106200821010340200110bf032001412c6a2101200641546a22060d000b0b4101210602402009450d002008102e0b200d2109201721080b02402006450d00200821060c040b20042802f0022002470d022005411074200b41ff017141087472200a41ff017172211b2008200c412c6c6a210a20082101024002400340200a2001460d0120012d000021022001412c6a2206210120024102470d000b200441f0006a200641586a10b7034104211c200428027021024100211002400240024002400240200428027422010d004100211d0c010b2001410474220a4100480d06200a1029221c450d012001211d0b02402001450d002001410474210641002110201c21010340200241086a280200220a417f4c0d032002410c6a2d0000210b2002280200210502400240200a0d004101210d0c010b200a1029220d450d050b200d2005200a10f60421052001410d6a2002410d6a2d00003a00002001410c6a200b3a0000200141086a200a360200200141046a200a36020020012005360200200141106a2101201041016a2110200241106a2102200641706a22060d000b0b201c450d030c040b200a4104102c000b1032000b200a4101102c000b4100211d4104211c410021100b2008200c412c6c6a210a20082101024003404100210641c8ecc500210b0240200a2001470d00410021010c020b20012d000021022001412c6a2205210120024103470d000b200441e8006a200541586a10b7034100210120042802682202450d00200428026c21012002210b0b0240024020010d0041012112410021134100210a4100210e410421154100210b4100211e41042114410421174100210241002105410021164100211f410121190c010b200141286c210d200b411c6a2101410421154100210641002113410121124100210a4100210e4100210b4100211e41042114410421174100210241002105410021164100211f41012119024002400240024002400340024002400240024002402001417c6a2d00000e0400010203000b2001280200210f0240024020052002460d00200521110c010b200241016a22112002490d0c20024101742218201120112018491b221841ffffffff03712018470d0c201841027422114100480d0c0240024020020d002011102921170c010b201720024102742011102a21170b2017450d0620022111201821020b201720114102746a200f360200200541016a21050c030b200441d8016a41086a220f200141086a280200360200200420012902003703d8010240200a200e470d00200a41016a220e200a490d0b200a4101742211200e200e2011491b220ead420c7e221a422088a70d0b201aa722114100480d0b02400240200a0d002011102921150c010b2015200a410c6c2011102a21150b2015450d060b2015200a410c6c6a221120042903d801370200201141086a200f280200360200200a41016a210a0c020b200441d8016a41086a220f200141086a280200360200200420012902003703d8010240200b201e470d00200b41016a2211200b490d0a200b4101742218201120112018491b221ead420c7e221a422088a70d0a201aa722114100480d0a02400240200b0d002011102921140c010b2014200b410c6c2011102a21140b2014450d060b2014200b410c6c6a221120042903d801370200201141086a200f280200360200200b41016a210b0c010b2001417e6a220f2d000021112001417d6a22182d00002120024020062013470d00200641016a22132006490d0920064101742221201320132021491b221320136a22222013490d0920224100480d090240024020060d002022102921120c010b201220212022102a21120b2012450d060b201220064101746a222220114101713a0001202220203a0000200f2d0000210f20182d000021110240201f2016470d00201641016a22182016490d0920164101742220201820182020491b221f201f6a2218201f490d0920184100480d090240024020160d002018102921190c010b201920202018102a21190b2019450d070b200641016a2106201920164101746a2218200f4101713a0001201820113a0000201641016a21160b200141286a2101200d41586a220d450d060c000b0b20114104102c000b20114104102c000b20114104102c000b20224101102c000b20184101102c000b2008200c412c6c6a210f200821010240024002400240024002400240024002400240024002400240024003400240200f2001470d002002210d0c020b20012d0000210d2001412c6a22112101200d4104470d000b200441e0006a201141586a10b70302402004280264220d0d002002210d0c010b20042802602101200d410274210f0340200128020021110240024020052002460d002002210d200521180c010b200241016a220d2002490d1020024101742218200d200d2018491b220d41ffffffff0371200d470d10200d41027422184100480d100240024020020d002018102921170c010b201720024102742018102a21170b2017450d0320022118200d21020b200141046a2101201720184102746a2011360200200541016a2105200f417c6a220f0d000b0b2008200c412c6c6a210f20082101024002400340200f2001460d0120012d000021022001412c6a2211210120024105470d000b200441d8006a201141586a10b703200428025c410c6c2218450d0020042802582101200a410174210f200a410c6c21020340200141086a2111024002400240200141046a2802004101470d002004201128020022203602c0022001280200222220204b0d010b20044100360280010c010b200441023602ec01200442023702dc01200441d0b1c5003602d801200441013602f402200441013602ec02200420223602d0022004200441e8026a3602e8012004200441d0026a3602f0022004200441c0026a3602e80220044180016a200441d8016a108a04200428028001450d0020044180016a21010c0e0b2001290200211a200441d8016a41086a222020112802003602002004201a3703d8010240200a200e470d00200a41016a220e200a490d11200f200e200e200f491b220ead420c7e221a422088a70d11201aa722114100480d1102400240200a0d002011102921150c010b201520022011102a21150b2015450d030b2001410c6a2101201520026a221120042903d801370200201141086a2020280200360200200f41026a210f2002410c6a2102200a41016a210a201841746a22180d000b0b2008200c412c6c6a210f20082101024002400340200f2001460d0120012d000021022001412c6a2211210120024106470d000b200441d0006a201141586a10b70320042802542202450d00200428025021012002410c6c2111200b410174210f200b410c6c21020340200441d8016a2001109904024020042802d801450d00200441d8016a21010c0f0b2001290200211a200441d8016a41086a2218200141086a2802003602002004201a3703d8010240200b201e470d00200b41016a221e200b490d12200f201e201e200f491b221ead420c7e221a422088a70d12201aa722204100480d1202400240200b0d002020102921140c010b201420022020102a21140b2014450d030b2001410c6a2101201420026a222020042903d801370200202041086a2018280200360200200f41026a210f2002410c6a2102200b41016a210b201141746a22110d000b0b2008200c412c6c6a210f20082101024002400240024002400340200f2001460d0120012d000021022001412c6a2211210120024107470d000b200441c8006a201141586a10b703200428024c2202450d002004280248220120024104746a212220064101742102200441d8016a41047221200340200441d8016a200120192016109a0402400240024020042d00d8014101460d00200420042d00d901220f3a00c0020240200f2001410c6a2d00002211470d0020044100360280010c030b200441023602ec01200442023702dc01200441e4b2c5003602d801200441223602f402200441223602ec02200420113a00d0022004200441e8026a3602e8012004200441c0026a3602f0022004200441d0026a3602e80220044180016a200441d8016a108a040c010b20044180016a41086a202041086a28020036020020042020290200370380010b0240200428028001450d0020044180016a21010c140b2001410c6a2d0000210f0b2001410d6a2d00002111024020062013470d00200641016a22132006490d162002201320132002491b221320136a22182013490d1620184100480d160240024020060d002018102921120c010b201220022018102a21120b2012450d030b201220026a2218200f3a0000201841016a20114101713a0000200241026a2102200641016a2106200141106a22012022470d000b0b200441b8016a2005360200200441b4016a200d36020020044180016a412c6a2010360200200441a8016a201d360200200441a0016a20063602002004419c016a201336020020044194016a200a36020020044190016a200e360200200420173602b0012004201c3602a40120042012360298012004201536028c012004200b360288012004201e3602840120042014360280012008200c412c6c6a210a20082101024003400240200a2001470d004100210b0c020b20012d000021022001412c6a2206210120024104470d000b200441c0006a200641586a10b7032004280244210b0b2004200b3602bc012008200c412c6c6a210a20082101024003400240200a2001470d00410021010c020b20012d000021022001412c6a220621012002410b470d000b200641606a28020021010b200420013602c001200b2001470d0d0240200b450d002008200c412c6c6a210a200821010340200a2001460d0520012d000021022001412c6a2206210120024104470d000b2008200c412c6c6a210b200821010340200b2001460d0420012d000021022001412c6a220a21012002410b470d000b200441386a200641586a10b703200428023c2201450d002004280238220d20014102746a2115200a41606a2117200a41586a211620044191026a2111410021050340200420053602c4012017280200210120162802002102200442013702dc01200441e8a7c5003602d801200441013602d402200441013602ec012004200441d0026a3602e8012004200441c4016a3602d002200441e8026a200441d8016a108a0420042802e802210a20042902ec02211a200120054d0d110240201aa7450d00200a102e0b2004200d28020022013602d002024002400240024020042802ac0120014b0d00200441013602ec01200442023702dc01200441dcb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a108a0420042902ec02221a422088a7210120042802e8022106201aa721020c010b0240024002402002200541186c6a22022802142210450d0020042802a40120014104746a220a2d000d2113200a280200210e200228020c210120022802002114200a280208220f2106024020022802082212450d002012410374210b200f21022014210a034002402002200a2802006a220620024f0d0002404120102922060d0041204101102c000b200641186a41002900acb845370000200641106a41002900a4b845370000200641086a410029009cb84537000020064100290094b8453700000c040b200a41086a210a20062102200b41786a220b0d000b0b0240410810292202450d0020022013ad42ff0183422886370200200441d0026a41026a220a200441e8026a41026a2d00003a0000200420042f00e8023b01d002200420133a00900220044180800136028c022004428180808010370284022004200236028002200442808080808080103703f801200442013703f001200420063602ec01200420123602e801200420143602e4012004200f3602e0012004200e3602dc01200420044180016a3602d801201120042f01d0023b0000201141026a200a2d00003a00002010410474210a41002102034020042002360298022004200136029c02200441b0026a200441d8016a2001109c04024020042802b002450d00200441c0026a41086a200441b0026a41086a280200360200200420042903b0023703c002200441033602e402200442033702d4022004419c9fc5003602d002200441233602fc02200441013602f402200441243602ec022004200441e8026a3602e0022004200441c0026a3602f802200420044198026a3602f00220042004419c026a3602e802200441a0026a200441d0026a108a04024020042802c402450d0020042802c002102e0b20042802a0022206450d0020042902a402211a024020042802f401450d0020042802f001102e0b201a42208821230240200428028402450d00200428028002102e0b2023a72101201aa721020c070b200141106a2101200241016a2102200a41706a220a0d000b02402004280288020d00024020042802f401450d0020042802f001102e0b200428028402450d07200428028002102e0c070b41b49fc5001058000b41084104102c000b412010292206450d01200641186a41002900919f45370000200641106a41002900899f45370000200641086a41002900819f45370000200641002900f99e453700000b41202102412021010c010b41204101102c000b2006450d010b200420063602d00220042001ad4220862002ad843702d4022004200441d0026a3602c002200441023602ec01200442023702dc01200441f0a7c5003602d801200441253602f402200441013602ec022004200441e8026a3602e8012004200441c0026a3602f0022004200441c4016a3602e802200441c8016a200441d8016a108a04024020042802d402450d0020042802d002102e0b20042802c801220a450d0020042902cc01211a0c120b200541016a2105200d41046a220d2015470d000b0b2008200c412c6c6a210a2008210102400340200a2001460d0120012d000021022001412c6a2206210120024109470d000b2004200641586a28020022013602b002024020042802b80120014b0d00200441ec016a4101360200200442023702dc01200441ccb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441b0026a3602c002200441e8026a200441d8016a108a040c0d0b200420042802b00120014102746a28020022013602d002024020042802ac0120014b0d00200441ec016a4101360200200442023702dc01200441dcb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a108a040c0d0b024020042802a40120014104746a22013502084200520d00200131000d4220864280808080f000834280808080c000510d010b412d1029220a450d02200a41256a41002900a5a845370000200a41206a41002900a0a845370000200a41186a4100290098a845370000200a41106a4100290090a845370000200a41086a4100290088a845370000200a4100290080a84537000042ad808080d005211a0c100b2008200c412c6c6a210a200821010340200a2001460d0b20012d000021022001412c6a2206210120024108470d000b200441306a200641586a220110b703200441d8016a2004280234109f04200441e8026a41086a200441e4016a290200370300200441e8026a41106a200441d8016a41146a280200360200200420042902dc013703e802200441286a200110b703200428022c2201450d0920042802282215200141146c6a210e034020152217450d0a410021022017280208220d210120172802002216210a0240200d4104490d004100210220162101200d210a0340200128000020024105777341b9f3ddf1796c2102200141046a2101200a417c6a220a41034b0d000b200d417c6a22012001417c71220a6b2101200a20166a41046a210a0b02400240200141014b0d00200a21060c010b200a41026a21062001417e6a21012002410577200a2f00007341b9f3ddf1796c21020b02402001450d00200241057720062d00007341b9f3ddf1796c21020b201741146a2115200241057741ff017341b9f3ddf1796c22024119762213410874201372220141107420017221054100210f20042802f002211220042802e802210b20042802ec0221062002210103400240200b200120067122016a2800002214200573220a417f73200a41fffdfb776a7141808182847871220a450d00024003400240200d2012200a6841037620016a2006714103746a221041046a280200470d00201620102802002210460d0220162010200d10f804450d020b200a417f6a200a71220a450d020c000b0b200441ec016a4101360200200442013702dc01200441b0a8c5003602d8012004411c3602b4022004200d3602c402200420163602c0022004200441b0026a3602e8012004200441c0026a3602b002200441d0026a200441d8016a108a040c0a0b200f41046a220f20016a2101201420144101747141808182847871450d000b024020042802f8020d00200441e8026a10a00420042802e802210b20042802ec0221060b200620027121024104210103402002220a20016a2006712102200141046a2101200b200a6a280000418081828478712205450d000b0240200b200568410376200a6a20067122016a2c000022024100480d00200b200b280200418081828478716841037622016a2d000021020b200b20016a20133a00002001417c6a200671200b6a41046a20133a000020042802f00220014103746a200dad4220862016ad84370200200420042802f40241016a3602f402200420042802f80220024101716b3602f802024002400240024002400240201728020c0e0400030201000b2004201728021022013602a002024020042802b80120014b0d00200441ec016a4101360200200442023702dc01200441ccb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441a0026a3602c002200441d0026a200441d8016a108a040c0e0b200420042802b00120014102746a28020022013602b00220042802ac0120014b0d03200441013602ec01200442023702dc01200441dcb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441b0026a3602c002200441d0026a200441d8016a108a040c0d0b2004201728021022013602a002024020042802a00120014b0d00200441ec016a4101360200200442023702dc01200441fcb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441a0026a3602c002200441d0026a200441d8016a108a040c0d0b20042802980120014101746a2d0001450d02200441ec016a4101360200200442023702dc012004419cb6c5003602d801200441013602c4022004200441c0026a3602e8012004200441a0026a3602c002200441d0026a200441d8016a108a040c0c0b2004201728021022013602b00220042802880120014b0d01200441013602ec01200442023702dc01200441fcb4c5003602d801200441013602c4022004200441c0026a3602e8012004200441b0026a3602c002200441d0026a200441d8016a108a0420042802d002220a0d0c0c010b2004201728021022013602b00220042802940120014d0d010b2015200e470d010c0b0b0b200441ec016a4101360200200442023702dc01200441acb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441b0026a3602c002200441d0026a200441d8016a108a040c070b20184101102c000b412d4101102c000b419ea7c50041c800109b01000b4180a7c500411e109b01000b20204104102c000b20114104102c000b20184104102c000b20042802d002210a0b20042902d402211a2006450d060240200641016a220141ffffffff01712001470d00200641086a417c712202200641056a490d00200220014103746a2002491a0b200b102e0c060b20042802ec022201450d000240200141016a220241ffffffff01712002470d00200141086a417c71220a200141056a490d00200a20024103746a200a491a0b20042802e802102e0b2008200c412c6c6a210a2008210102400340200a2001460d0120012d000021022001412c6a2206210120024103470d000b200441206a200641586a10b70320042802242201450d0020042802202106200141286c210b41002101034002400240024002400240200620016a220241186a2d00000e0400030201000b20042002411c6a28020022023602d00220042802ac0120024b0d03200441ec016a4101360200200442023702dc01200441dcb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a108a040c060b2002411a6a2d0000450d022002410c6a2802002101200241146a2802002102200441d8016a41146a4101360200200420023602d402200420013602d0022004411c3602c402200442013702dc01200441b8a8c5003602d8012004200441d0026a3602c0022004200441c0026a3602e801200441e8026a200441d8016a108a040c050b200441d8016a2002411c6a10990420042802d801220a450d0120042902dc01211a0c080b200241206a2802004101470d002002411c6a280200210a2004200241246a28020022023602b002200a20024d0d00200441023602ec01200442023702dc01200441d0b1c5003602d801200441013602f402200441013602ec022004200a3602c0022004200441e8026a3602e8012004200441c0026a3602f0022004200441b0026a3602e802200441d0026a200441d8016a108a0420042802d002220a0d060b200b200141286a2201470d000b0b024002400240200428029401220141014b0d00200428028801220141014b0d012008200c412c6c6a210a2008210102400240024002400340200a2001460d0120012d000021022001412c6a220621012002410c470d000b200441186a200641586a10b70320042802182201200428021c411c6c6a2106034020012006460d012004200128020022023602d002024020042802880120024b0d00200441013602ec01200442023702dc01200441fcb4c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a108a0420042802e802220a450d0020042902ec02211a0c0d0b200441d8016a200141046a220120042802980120042802a001109a0420042d00d8014101460d02200141186a210120042d00d901450d000b41201029220a450d06200a41186a41002900e8a845370000200a41106a41002900e0a845370000200a41086a41002900d8a845370000200a41002900d0a84537000042a08080808004211a0c0b0b2008200c412c6c6a210a2008210102400340200a2001460d0120012d000021022001412c6a220621012002410a470d000b200441106a200641586a10b70320042802142201450d002004280210220b2001411c6c6a21050340200b450d012004200b28020022013602d00220042802940120014d0d03200441d8016a200b41046a20042802980120042802a001109a0420042d00d8014101460d0420042d00d9010d09200441086a200b10a10402400240200428020c2201450d00200428020821022001410274210a20042802b801210603402004200228020022013602b0020240200620014b0d00200441ec016a4101360200200442023702dc01200441ccb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441b0026a3602c002200441e8026a200441d8016a108a040c0c0b200420042802b00120014102746a28020022013602d00220042802ac0120014d0d02200241046a2102200a417c6a220a0d000b0b200b411c6a220b2005460d020c010b0b200441013602ec01200442023702dc01200441dcb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a108a040c070b0240200428028401450d00200428028001102e0b0240200428029001450d00200428028c01102e0b0240200428029c01450d00200428029801102e0b024020042802ac012202450d0020042802a40121012002410474210203400240200141046a280200450d002001280200102e0b200141106a2101200241706a22020d000b0b024020042802a801450d0020042802a401102e0b024020042802b401450d0020042802b001102e0b201f450d0d2019102e0c0d0b200441e0016a290300211a20042802dc01210a0c090b200441ec016a4101360200200442023702dc01200441acb5c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a108a040c040b200441e0016a290300211a20042802dc01210a0c070b200441ec016a4101360200200442013702dc01200441c0a8c5003602d801200441013602d402200420013602c0022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a108a040c020b200441ec016a4101360200200442013702dc01200441c8a8c5003602d801200441013602d402200420013602c0022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a108a040c010b41204101102c000b20042802e802210a20042902ec02211a0c030b024041201029220a450d00200a41186a41002900e8a845370000200a41106a41002900e0a845370000200a41086a41002900d8a845370000200a41002900d0a84537000042a08080808004211a0c030b41204101102c000b200441ec016a4102360200200441f4026a4101360200200442023702dc01200441f0a6c5003602d801200441013602ec022004200441e8026a3602e8012004200441c0016a3602f0022004200441bc016a3602e802200441d0026a200441d8016a108a0420042802d002210a0b20042902d402211a0b0240200428028401450d00200428028001102e0b0240200428029001450d00200428028c01102e0b0240200428029c01450d00200428029801102e0b024020042802ac012202450d0020042802a40121012002410474210203400240200141046a280200450d002001280200102e0b200141106a2101200241706a22020d000b0b024020042802a801450d0020042802a401102e0b024020042802b401450d0020042802b001102e0b201f450d012019102e200a0d040c020b2001290204211a2001280200210a0240201f450d002019102e0b0240201e450d002014102e0b0240200e450d002015102e0b02402013450d002012102e0b02402010450d0020104104742102201c210103400240200141046a280200450d002001280200102e0b200141106a2101200241706a22020d000b0b0240201d450d00201c102e0b200d450d002017102e0b200a0d020b2000201b36020420004100360200200041186a2003360200200041146a200c360200200041106a20093602002000410c6a2008360200200041086a20073602000c040b102d000b0240201aa7450d00200a102e0b200041e8a1c50036020420004101360200200041086a41133602000240200c450d00200c412c6c2102200821010340200110bf032001412c6a2101200241546a22020d000b0b2009450d022008102e0c020b200441003a00d002200441ec016a4101360200200442013702dc01200441e8d4c5003602d801200441213602b4022004200441b0026a3602e8012004200441d0026a3602b00220044180016a200441d8016a108a04200428028001210720042802840121060240200c450d00200c412c6c2102200821010340200110bf032001412c6a2101200241546a22020d000b0b4105210a2009450d002008102e0b02402006450d00200a41ff01714105470d002007102e0b200041d2a1c50036020420004101360200200041086a41163602000b20044180036a24000b160020002001280208360204200020012802003602000bd41301177f23004190026b220224000240024002400240024002402000280200220341e08dc000460d00200028020421040c010b41002104200241b8016a410041d80010f5041a2002411f6a220542003700002002420037011a41ec0010292203450d0120034100360200200320022902183702042003410b6a2005290000370000200341136a200241b7016a41d90010f6041a20004100360204200020033602000b200141ff01712106024003402003410c6a2107200341086a210820032f010621094100210502400240034020092005460d01200820056a210a200741086a2107200541016a210502404100417f4101200a2d0000220a20064b1b200a2006461b41016a0e03000301000b0b2005417f6a21090b2004450d022004417f6a2104200320094102746a41ec006a28020021030c010b0b200742013702000c030b2000200028020841016a360208024002400240024020032f01062205410b490d00200241276a41016a410041d80010f5041a200241003a001941ec0010292204450d03200441003602002004410036000f20044200370007200420022f01183b0005200441136a200241276a41d90010f6041a2003410e6a2d0000210b2003280248210c2003280244210d200441086a2003410f6a20032f010641796a220510f6042107200441146a200341cc006a200541037410f6042106200341063b0106200420053b010620094107490d0120072009417a6a220a6a2007200941796a22096a2207200541ffff037120096b10f7041a200720013a00002006200a4103746a200620094103746a2207200441066a22052f010020096b41037410f7041a2007410136020020052f010021070c020b200341086a2207200941016a22066a200720096a2207200520096b220a10f7041a200720013a0000200341146a220720064103746a200720094103746a2207200a41037410f7041a200741013602002003200541016a3b01060c050b200341086a2205200941016a22066a200520096a220a200341066a22052f0100220720096b220810f7041a200a20013a0000200341146a220a20064103746a200a20094103746a2209200841037410f7041a200941013602000b2005200741016a3b01002003280200220a450d02200341046a2105200241276a41016a210e200241a8016a210f200241a0016a211020024198016a211120024190016a211220024180016a41086a2113034020052f0100210602400240024002400240200a2f01062205410b490d00200e410041d80010f5041a200241003a0019200220022f01183b0108200241b7016a200241276a41d90010f6041a200f4200370300201042003703002011420037030020124200370300201342003703002002420037038001419c0110292207450d03200741003602002007410036000f20074200370007200720022f01083b0005200741136a200241b7016a41d90010f6041a20074194016a200f2903003702002007418c016a201029030037020020074184016a2011290300370200200741fc006a2012290300370200200741f4006a2013290300370200200720022903800137026c200a41c8006a2802002114200a41c4006a2802002115200a410e6a2d00002116200741086a200a410f6a200a2f0106220341796a220510f6042117200741146a200a41cc006a200541037410f6042118200741ec006a200a4188016a2003417a6a220841027410f6042101200a41063b0106200720053b010602402008450d00410021052001210303402003280200220920053b010420092007360200200341046a21032008200541016a2205470d000b0b20064107490d0120172006417a6a22036a2017200641796a22056a220920072f010620056b10f7041a2009200b3a0000201820034103746a201820054103746a220920072f010620056b41037410f7041a2009200d3602002009200c360204200720072f010641016a22093b01062006410274220b20016a416c6a200120034102746a2208200941ffff0371220620036b41027410f7041a2008200436020020062003490d022007200b6a41d4006a2103034020032802002209200541016a22053b010420092007360200200341046a210320052006490d000c030b0b200a41086a2207200641016a22036a200720066a2207200520066b220910f7041a2007200b3a0000200a41146a220720034103746a200720064103746a2207200941037410f7041a2007200d3602002007200c360204200a200541016a22053b01062006410274200a41ec006a22076a41086a200720034102746a2207200541ffff0371220920036b41027410f7041a20072004360200200620094f0d08200a2003417f6a22054102746a41f0006a2103034020032802002207200541016a22053b01042007200a360200200341046a210320052009490d000c090b0b200a41086a2203200641016a22056a200320066a2203200a2f0106220920066b220810f7041a2003200b3a0000200a41146a220320054103746a200320064103746a2203200841037410f7041a2003200d3602002003200c360204200a200941016a22033b010620064102742201200a41ec006a22096a41086a200920054102746a2208200341ffff0371220920056b41027410f7041a20082004360200200620094f0d00200a20016a41f0006a2105034020052802002203200641016a22063b01042003200a360200200541046a210520092006470d000b0b200a28020022030d01200721042014210c2015210d2016210b0c050b419c014104102c000b200a41046a21052003210a2016210b2015210d2014210c200721040c000b0b41ec004104102c000b41ec004104102c000b200241b7016a41016a410041d80010f5041a2002411f6a220542003700002002420037011a200220022902183703082002200529000037000f200241276a200241b7016a41d90010f6041a200241a8016a22034200370300200241a0016a2207420037030020024180016a41186a2209420037030020024190016a2206420037030020024180016a41086a220a42003703002002420037038001419c0110292205450d0120054100360200200520022903083702042005410b6a200229000f370000200541136a200241276a41d90010f6041a20054194016a20032903003702002005418c016a200729030037020020054184016a2009290300370200200541fc006a2006290300370200200541f4006a200a290300370200200520022903800137026c20052000280200220336026c200020053602002000200028020441016a360204200341003b010420032005360200200520052f010622034103746a220741186a200c360200200741146a200d360200200520036a41086a200b3a0000200541ec006a200341016a22034102746a2004360200200520033b0106200420033b0104200420053602000b20024190026a24000f0b419c014104102c000bd11e01387f23004190016b2202240020024184016a4200370200200241fc006a4280808080c000370200200241ec006a4200370200200241e4006a4280808080c000370200200241d0006a4200370300200241c0006a4200370300200241386a4280808080c000370300200241286a4200370300200241206a4280808080c000370300200241106a4200370300200242043702742002420437025c20024204370348200242043703302002420437031820024280808080c000370308200242043703002001410c6a280200210320024180016a210420012802082105024002400240200141106a28020022060d00410421014100210741002108410021094100210a4104210b4100210c4100210d4104210e4100210f41002110410421114100211241002113410421144100210641002115410421164100211741002118410421194100211a4100211b4104211c4100211d4100211e4104211f41002120410021210c010b410021224100211f41002123410021244100211c410021254100212641002127410021284100212941002107024003402001212a2007211520052006417f6a2206412c6c6a2201280024211720012800202119200128001821182001280014211420012800102116200128000c210c2001280008210b200128000421094101210741012112024002400240024002400240024020012d0000220a417e6a2208410d4d0d00410121130c010b4101211341012110410121114101210f4101210d4101210e20092101024002400240024002400240024002400240024020080e0e000102030405060f0708090e0e11000b02402029450d000240202b450d00202b41047421072029210103400240200141046a280200450d002001280200102e0b200141106a2101200741706a22070d000b0b202c450d002029102e0b4101211341002112200c212b200b212c200921290c090b02402028450d000240202d450d00202d41286c21072028210103400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141286a2101200741586a22070d000b0b202e450d002028102e0b4100211341012112200c212d200b212e200921280c080b0240202f450d002027450d002027102e0b20152107202a210120092127200b212f200c21300c0c0b02402031450d002026450d002026102e0b20152107202a210120092126200b2131200c21320c0b0b02402033450d002025450d002025102e0b20152107202a210120092125200b2133200c21340c0a0b0240201c450d000240201a450d00201c201a4104746a210d201c21080340024020082802082207450d0020082802002101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200741706a22070d000b0b200841106a21010240200841046a280200450d002008280200102e0b200121082001200d470d000b0b2035450d00201c102e0b4100211041012112200c211a200b21352009211c410121130c050b02402024450d000240201e450d00201e41146c21072024210103400240200141046a280200450d002001280200102e0b200141146a21012007416c6a22070d000b0b2036450d002024102e0b4100211141012112200c211e200b21362009212441012113410121100c050b02402023450d000240201d450d002023201d411c6c6a210d20232108034002402008410c6a2802002207450d0020082802042101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200741706a22070d000b0b0240200841086a280200450d002008280204102e0b2008411c6a21010240200841146a280200450d002008280210102e0b200121082001200d470d000b0b2037450d002023102e0b4100210f41012112200c211d200b2137200921234101211341012110410121110c050b0240201f450d000240201b450d00201f201b41186c6a210d201f210803400240200841046a280200450d002008280200102e0b0240200841146a2802002207450d00200828020c2101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200741706a22070d000b0b200841186a21010240200841106a280200450d00200828020c102e0b200121082001200d470d000b0b2020450d00201f102e0b4100210d41012112200c211b200b21202009211f4101211341012110410121114101210f4101210e0c050b02402022450d0002402038450d0020222038411c6c6a210d20222108034002402008410c6a2802002207450d0020082802042101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200741706a22070d000b0b0240200841086a280200450d002008280204102e0b2008411c6a21010240200841146a280200450d002008280210102e0b200121082001200d470d000b0b2039450d002022102e0b4100210e41012112200c2138200b2139200921224101211341012110410121114101210f4101210d0c040b410121100b410121110b4101210f0b4101210d4101210e0b02400240024002400240200a410d4b0d0020152107202a210102400240024002400240024002400240024002400240200a0e0e080900010202020304100506070a080b2012450d0e0240200c450d00200c41047421072009210103400240200141046a280200450d002001280200102e0b200141106a2101200741706a22070d000b0b200b450d0e0c0d0b2013450d0d200c450d00200c41286c21072009210103400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141286a2101200741586a22070d000b0b200b0d0b0c0c0b2010450d0b0240200c450d002009200c4104746a210a200921080340024020082802082207450d0020082802002101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200741706a22070d000b0b200841106a21010240200841046a280200450d002008280200102e0b200121082001200a470d000b0b200b0d0a0c0b0b2011450d0a0240200c450d00200c41146c21072009210103400240200141046a280200450d002001280200102e0b200141146a21012007416c6a22070d000b0b200b0d090c0a0b200f450d090240200c450d002009200c411c6c6a210a20092108034002402008410c6a2802002207450d0020082802042101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200741706a22070d000b0b0240200841086a280200450d002008280204102e0b2008411c6a21010240200841146a280200450d002008280210102e0b200121082001200a470d000b0b200b0d080c090b200d450d080240200c450d002009200c41186c6a210a2009210803400240200841046a280200450d002008280200102e0b0240200841146a2802002207450d00200828020c2101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200741706a22070d000b0b200841186a21010240200841106a280200450d00200828020c102e0b200121082001200a470d000b0b200b0d070c080b200e450d07200c450d002009200c411c6c6a210a20092108034002402008410c6a2802002207450d0020082802042101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200741706a22070d000b0b0240200841086a280200450d002008280204102e0b2008411c6a21010240200841146a280200450d002008280210102e0b200121082001200a470d000b0b200b0d050c060b0240200b450d002009102e0b2014450d052016102e0c050b0240200941ff0171220141024b0d0002400240024020010e03000102000b200c450d070c050b02402014450d002014410c6c2107200c21010340024020012802002208450d00200141046a280200450d002008102e0b2001410c6a2101200741746a22070d000b0b2016450d060c030b02402014450d00200c20144104746a210b200c210a0340200a220941106a210a024020092802042201450d0002402009410c6a2802002207450d002007410c6c21070340024020012802002208450d00200141046a280200450d002008102e0b2001410c6a2101200741746a22070d000b0b200941086a280200450d002009280204102e0b200a200b470d000b0b20160d020c050b200c0d020c040b0240200b450d002009102e0b02402014450d002018450d002014102e0b2017450d032019102e0c030b200c102e0c020b200b102e0c010b2009102e0b20152107202a21010b20060d000b410021062001212a200721150b201b4100201f1b210720204100201f1b2108201d410020231b21212037410020231b2120201e410020241b21092036410020241b210a201a4100201c1b211e20354100201c1b211d2034410020251b210c2033410020251b210d2032410020261b211b2031410020261b211a2030410020271b210f202f410020271b2110202d410020281b2118202e410020281b2117202b410020291b2112202c410020291b2113201f4104201f1b21012023410420231b211f2024410420241b210b201c4104201c1b211c2025410420251b210e2026410420261b21192027410420271b21112028410420281b21162029410420291b211420220d010b4104212241002139410021380b200410c8040240200228028401450d00200228028001102e0b200241d8006a202a3602002002200636028801200220033602840120022005360280012002203836027c2002203936027820022022360274200220073602702002200836026c2002200136026820022021360264200220203602602002201f36025c20022015360254200220093602502002200a36024c2002200b3602482002201e3602442002201d3602402002201c36023c2002200c3602382002200d3602342002200e3602302002201b36022c2002201a360228200220193602242002200f3602202002201036021c2002201136021820022018360214200220173602102002201636020c20022012360208200220133602042002201436020020002002418c0110f6041a20024190016a24000bc30a01107f230041106b220224000240024002400240024020012802004101470d00200141106a2d000021032001410c6a2802002104200141086a280200210520012f0112210620012d0011210720012802042108200241086a200010b70320022802082201200228020c22094104746a210a4100210b20094104490d01200341ff0171210c024002400340024020012d000c200c470d0020012802082004470d002001280200210d200421092008210e024003402009450d012009417f6a2109200e2d0000210f200d2d00002110200e41016a210e200d41016a210d2010200f460d000c020b0b20012d000d2209410446220f200741ff0171220d410446220e470d002009200d460d06200e0d06200f0d060b024002402001411c6a2d0000200c470d00200141186a2802002004470d002001280210210d200421092008210e024003402009450d012009417f6a2109200e2d0000210f200d2d00002110200e41016a210e200d41016a210d2010200f460d000c020b0b20012d001d2209410446220f200741ff0171220d410446220e470d002009200d460d01200e0d01200f0d010b02402001412c6a2d0000200c470d00200141286a2802002004470d002001280220210d200421092008210e024003402009450d012009417f6a2109200e2d0000210f200d2d00002110200e41016a210e200d41016a210d2010200f460d000c020b0b20012d002d2209410446220f200741ff0171220d410446220e470d002009200d460d03200e0d03200f0d030b02402001413c6a2d0000200c470d00200141386a2802002004470d002001280230210d200421092008210e024003402009450d012009417f6a2109200e2d0000210f200d2d00002110200e41016a210e200d41016a210d2010200f460d000c020b0b20012d003d2209410446220f200741ff0171220d410446220e470d002009200d460d04200e0d04200f0d040b200b41046a210b200a200141c0006a22016b41304d0d050c010b0b200b410172210b0c040b200b410272210b0c030b200b410372210b0c020b2001280204210b0c030b2001200a460d0102400240200741ff017122114104460d00200341ff0171210c0c010b200341ff0171210c0340024020012d000c200c470d0020012802082004470d002001280200210d200421092008210e024003402009450d012009417f6a2109200e2d0000210f200d2d00002110200e41016a210e200d41016a210d2010200f460d000c020b0b20012d000d4104460d030b200b41016a210b200141106a2201200a470d000c030b0b0340024020012d000c200c470d0020012802082004470d002001280200210e200421092008210d024003402009450d012009417f6a2109200d2d0000210f200e2d00002110200d41016a210d200e41016a210e2010200f460d000c020b0b20012d000d22092011470d0020094104470d020b200b41016a210b200141106a2201200a460d020c000b0b2005450d012008102e0c010b02400240200041046a28020020002802082201460d00200028020021090c010b02400240200141016a22092001490d002001410174220d20092009200d491b220d41ffffffff0071200d470d00200d410474220e4100480d000240024020010d00200e102921090c010b20002802002001410474200e102a21090b2009450d0120002009360200200041046a200d360200200028020821010c020b102d000b200e4104102c000b200920014104746a220120063b010e200120073a000d200120033a000c2001200436020820012005360204200120083602002000200028020841016a3602082002200010b7032002280204417f6a210b0b200241106a2400200b0bcc21032d7f017e017f230041306b2202240020012802042103200128020021044101210502400240024002400240024002400240024002400240024002400240024002400240200128020822060d004104210741002108410121090c010b412c10292207450d01200741023a0000200720022f002d3b00012007200636000c200720033600082007200436000420072002290208370210200741036a2002412d6a41026a2d00003a0000200741186a200241106a290200370200200741206a200241186a290200370200200741286a200241086a41186a28020036020041002109410121080b200141106a280200210a200128020c210b02400240200141146a280200220c0d002008210d0c010b2008410174220d200841016a220e200e200d491b220d412c6c210e0240024020080d00200e102921070c010b20072008412c6c200e102a21070b2007450d0220072008412c6c6a220e41033a0000200e20022f002d3b0001200e200c36000c200e200a360008200e200b360004200e2002290208370210200e41036a2002412f6a2d00003a0000200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a280200360200200841016a2108410021050b2001411c6a280200210f200128021821104100211102400240200141206a28020022120d00410021130c010b0240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22142014200e491b220ead422c7ea722144100480d0e02400240200d0d002014102921070c010b2007200d412c6c2014102a21070b2007450d04200e210d0b20072008412c6c6a220e41043a0000200e201236000c200e200f360008200e2010360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a28020036020041012113200841016a21080b200141286a28020021122001280224211502402001412c6a2802002214450d000240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22112011200e491b220ead422c7ea722114100480d0e02400240200d0d002011102921070c010b2007200d412c6c2011102a21070b2007450d05200e210d0b20072008412c6c6a220e41053a0000200e201436000c200e2012360008200e2015360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a28020036020041012111200841016a21080b200141346a28020021142001280230211602400240200141386a28020022170d00410021180c010b0240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22192019200e491b220ead422c7ea722194100480d0e02400240200d0d002019102921070c010b2007200d412c6c2019102a21070b2007450d06200e210d0b20072008412c6c6a220e41063a0000200e201736000c200e2014360008200e2016360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a28020036020041012118200841016a21080b200141c0006a280200211a200128023c211b4101211702400240200141c4006a280200221c0d004101211d0c010b0240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22192019200e491b220ead422c7ea722194100480d0e02400240200d0d002019102921070c010b2007200d412c6c2019102a21070b2007450d07200e210d0b20072008412c6c6a220e41073a0000200e201c36000c200e201a360008200e201b360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a280200360200200841016a21084100211d0b200141cc006a280200211e2001280248211f0240200141d0006a2802002220450d000240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22172017200e491b220ead422c7ea722174100480d0e02400240200d0d002017102921070c010b2007200d412c6c2017102a21070b2007450d08200e210d0b20072008412c6c6a220e41083a0000200e202036000c200e201e360008200e201f360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241086a41086a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a280200360200200841016a2108410021170b41012119024020012802544101470d00200141d8006a28020021210240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22222022200e491b220ead422c7ea722224100480d0e02400240200d0d002022102921070c010b2007200d412c6c2022102a21070b2007450d09200e210d0b20072008412c6c6a220e41093a0000200e2021360204200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370208200e41106a200241106a290200370200200e41186a200241086a41106a290200370200200e41206a200241086a41186a290200370200200e41286a200241086a41206a280200360200200841016a21080b200141e0006a2802002123200128025c21220240200141e4006a2802002224450d000240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22192019200e491b220ead422c7ea722194100480d0e02400240200d0d002019102921070c010b2007200d412c6c2019102a21070b2007450d0a200e210d0b20072008412c6c6a220e410a3a0000200e202436000c200e2023360008200e2022360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a280200360200200841016a2108410021190b200141ec006a2802002125200128026821264101212102400240200141f0006a28020022270d00410121280c010b0240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22292029200e491b220ead422c7ea722294100480d0e02400240200d0d002029102921070c010b2007200d412c6c2029102a21070b2007450d0b200e210d0b20072008412c6c6a220e410b3a0000200e202736000c200e2025360008200e2026360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a280200360200200841016a2108410021280b200141f8006a280200212a200128027421290240200141fc006a280200222b450d000240200d2008470d0041000d0e41000d0e200d410174220e200d41016a22212021200e491b220ead422c7ea722214100480d0e02400240200d0d002021102921070c010b2007200d412c6c2021102a21070b2007450d0c200e210d0b20072008412c6c6a220e410c3a0000200e202b36000c200e202a360008200e2029360004200e20022f002d3b0001200e41036a2002412f6a2d00003a0000200e2002290208370210200e41186a200241106a290200370200200e41206a200241186a290200370200200e41286a200241086a41186a280200360200200841016a2108410021210b20014184016a280200212c200128028001210e02400240200d20086b20014188016a280200412c6c222d412c6d2201490d00200820016a21010c010b200820016a22012008490d0d200d410174222e20012001202e491b222ead422c7e222f422088a70d0d202fa722304100480d0d02400240200d0d002030102921070c010b2007200d412c6c2030102a21070b2007450d0c202e210d0b20072008412c6c6a200e202d10f6041a0240202c450d00200e102e0b41c00510292208450d0d2000200736020820004280c2cdeb16370200200241086a410c6a4210370200200041106a20013602002000410c6a200d3602002002200836021020024280c2cdeb16370308200241106a10c8042008102e2021450d0e0240202b450d002029202b411c6c6a210d20292107034002402007410c6a2802002208450d0020072802042101200841047421080340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200841706a22080d000b0b0240200741086a280200450d002007280204102e0b2007411c6a21010240200741146a280200450d002007280210102e0b200121072001200d470d000b0b202a450d0e2029102e0c0e0b412c4104102c000b200e4104102c000b20144104102c000b20114104102c000b20194104102c000b20194104102c000b20174104102c000b20224104102c000b20194104102c000b20294104102c000b20214104102c000b20304104102c000b102d000b41c0054104102c000b02402028450d0002402027450d002026202741186c6a210d2026210703400240200741046a280200450d002007280200102e0b0240200741146a2802002208450d00200728020c2101200841047421080340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200841706a22080d000b0b200741186a21010240200741106a280200450d00200728020c102e0b200121072001200d470d000b0b2025450d002026102e0b02402019450d0002402024450d0020222024411c6c6a210d20222107034002402007410c6a2802002208450d0020072802042101200841047421080340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200841706a22080d000b0b0240200741086a280200450d002007280204102e0b2007411c6a21010240200741146a280200450d002007280210102e0b200121072001200d470d000b0b2023450d002022102e0b02402017450d0002402020450d00202041146c2108201f210103400240200141046a280200450d002001280200102e0b200141146a21012008416c6a22080d000b0b201e450d00201f102e0b0240201d450d000240201c450d00201b201c4104746a210d201b21070340024020072802082208450d0020072802002101200841047421080340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200841706a22080d000b0b200741106a21010240200741046a280200450d002007280200102e0b200121072001200d470d000b0b201a450d00201b102e0b02402014410047201841017371450d002016102e0b02402012410047201141017371450d002015102e0b0240200f410047201341017371450d002010102e0b02402005450d000240200c450d00200c41286c2108200b210103400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141286a2101200841586a22080d000b0b200a450d00200b102e0b02402009450d0002402006450d00200641047421082004210103400240200141046a280200450d002001280200102e0b200141106a2101200841706a22080d000b0b2003450d002004102e0b200241306a24000b860501017f411021010240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200041ff01710eac010001020202020202020202020202020303030404050506060707080809090a0a0b0b0c0d0d0e0e0f0f1010111213131414151516161717181819191a1a1b1b1c1c1d1d1e1e1f1f2020212122222323242425252627272828292a2a2b2b2c2d2d2e2e2f2f303031313232333434353536363737383839393a3a3b3b3c3c3d3d3e3e3f3f40404141424243434444454546464747484a4a4a4a49494a4a4a4a4a4a4a4a4a4a4a4a4a4a4b4b4b4b000b41110f0b41120f0b410a0f0b41080f0b41080f0b41040f0b41040f0b41040f0b41040f0b41040f0b41040f0b41040f0b41050f0b41050f0b41050f0b41050f0b41050f0b41130f0b41140f0b41060f0b41070f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410c0f0b410c0f0b410c0f0b410c0f0b410c0f0b410c0f0b41000f0b41000f0b41010f0b41020f0b41030f0b41030f0b41000f0b41000f0b41000f0b41000f0b41000f0b41000f0b41010f0b41020f0b41030f0b41030f0b41000f0b41000f0b41000f0b41000f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410e0f0b410e0f0b410f21010b20010bfe0101057f02400240024002400240200041086a28020022032001490d002003200041046a280200460d01200341016a2104200028020021050c020b41c0c6c5001058000b200341016a22042003490d0220034101742205200420042005491b220641ffffffff00712006470d02200641047422074100480d020240024020030d002007102921050c010b200028020020034104742007102a21050b2005450d0120002005360200200041046a20063602000b200520014104746a220541106a2005200320016b41047410f7041a200541086a200241086a29030037030020052002290300370300200041086a20043602000f0b20074108102c000b102d000b800502067f017e230041306b22022400200241106a200141246a290200370300200241086a2001411c6a29020037030020022001290214370300200241186a41106a200141106a280200360200200241186a41086a200141086a290200370300200220012902003703182000200241186a10ba032103024002400240024002402000411c6a280200200041206a2802002204460d00200028021821050c010b200441016a22052004490d0320044101742206200520052006491b220641ffffffff03712006470d03200641027422074100480d030240024020040d002007102921050c010b200028021820044102742007102a21050b2005450d01200020053602182000411c6a2006360200200028022021040b200520044102746a20033602002000200028022041016a360220200241186a41106a200241106a290300370300200241186a41086a200241086a2903003703002002200229030037031802400240200041ec006a280200200041f0006a2802002204460d00200028026821050c010b200441016a22052004490d0320044101742203200520052003491b2203ad42187e2208422088a70d032008a722064100480d030240024020040d002006102921050c010b2000280268200441186c2006102a21050b2005450d0220002005360268200041ec006a2003360200200041f0006a28020021040b2005200441186c6a22042002290318370200200441106a200241186a41106a290300370200200441086a200241186a41086a290300370200200041f0006a22042004280200220441016a360200024020012d002c450d0020004101360254200041d8006a20043602000b200241306a24000f0b20074104102c000b20064104102c000b102d000bcf0d01067f0240024020002d00002201410d4b0d00024002400240024002400240024002400240024002400240024020010e0e0001020304050607080e090a0b0c000b200041086a280200450d0d200041046a280200102e0f0b0240200041086a280200450d00200041046a280200102e0b200041146a280200450d0c200041106a280200102e0f0b02402000410c6a2802002202450d00200041046a28020021012002410474210203400240200141046a280200450d002001280200102e0b200141106a2101200241706a22020d000b0b200041086a280200450d0b2000280204102e0f0b02402000410c6a2802002202450d00200041046a2802002101200241286c210203400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141286a2101200241586a22020d000b0b200041086a280200450d0a2000280204102e0f0b200041086a280200450d09200041046a280200102e0f0b200041086a280200450d08200041046a280200102e0f0b200041086a280200450d07200041046a280200102e0f0b02402000410c6a2802002201450d00200041046a280200220320014104746a21040340024020032802082202450d0020032802002101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200241706a22020d000b0b200341106a21010240200341046a280200450d002003280200102e0b2001210320012004470d000b0b200041086a280200450d062000280204102e0f0b02402000410c6a2802002202450d00200041046a2802002101200241146c210203400240200141046a280200450d002001280200102e0b200141146a21012002416c6a22020d000b0b200041086a280200450d052000280204102e0f0b02402000410c6a2802002201450d00200041046a28020022032001411c6c6a2104034002402003410c6a2802002202450d0020032802042101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200241706a22020d000b0b0240200341086a280200450d002003280204102e0b2003411c6a21010240200341146a280200450d002003280210102e0b2001210320012004470d000b0b200041086a280200450d042000280204102e0f0b02402000410c6a2802002201450d00200041046a2802002203200141186c6a210403400240200341046a280200450d002003280200102e0b0240200341146a2802002202450d00200328020c2101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200241706a22020d000b0b200341186a21010240200341106a280200450d00200328020c102e0b2001210320012004470d000b0b200041086a280200450d032000280204102e0f0b02402000410c6a2802002201450d00200041046a28020022032001411c6c6a2104034002402003410c6a2802002202450d0020032802042101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200241706a22020d000b0b0240200341086a280200450d002003280204102e0b2003411c6a21010240200341146a280200450d002003280210102e0b2001210320012004470d000b0b200041086a280200450d022000280204102e0f0b0240200041046a2d0000220141024b0d0002400240024020010e03000102000b2000410c6a280200450d04200041086a280200102e0f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c21020340024020012802002203450d00200141046a280200450d002003102e0b2001410c6a2101200241746a22020d000b0b200041106a280200450d03200028020c102e0f0b0240200041146a2802002201450d002000410c6a280200220520014104746a210603402005220441106a2105024020042802042201450d0002402004410c6a2802002202450d002002410c6c21020340024020012802002203450d00200141046a280200450d002003102e0b2001410c6a2101200241746a22020d000b0b200441086a280200450d002004280204102e0b20052006470d000b0b200041106a280200450d02200028020c102e0c020b2000410c6a280200450d01200041086a280200102e0f0b0240200041086a280200450d00200041046a280200102e0b0240200041146a2802002201450d00200041186a280200450d002001102e0b200041246a280200450d00200041206a280200102e0f0b0bb07e07087f017e1b7f027e017f017e197f23002203210420034180096b41607122032400024002400240024002400240024002400240024002400240024002400240411010292205450d00200541063a0000412010292206450d01200641063a00104100210720064100360204200620032f00f0053b00012006412d3a0000200641036a200341f2056a2d00003a0000024020052d00004109470d00200528020841ffffffff0371450d002005280204102e0b2005102e200141106a2802002208412c6c21092001280208210a02400340024020092007470d00411010292205450d0520054180023b010c200542828080802037020420052006360200200520032f01d0033b010e02402001410c6a2802002008470d00200841016a22072008490d0f20084101742209200720072009491b2207ad422c7e220b422088a70d0f200ba722094100480d0f0240024020080d0020091029210a0c010b200a2008412c6c2009102a210a0b200a450d072001200a3602082001410c6a20073602000b2001200841016a220c360210200a2008412c6c6a220741073a0000200720032f00e0043b0001200742818080801037000820072005360004200720032902f005370210200741036a200341e2046a2d00003a0000200741186a200341f8056a290200370200200741206a20034180066a290200370200200741286a200341f0056a41186a2802003602004100210d0c020b200a20076a21052007412c6a220e210720052d00004107470d000b200320032f01d0033b01f005200a200e6a220541586a210a024002402005415c6a220c280200200541606a22092802002207460d00200a280200210e0c010b200741016a220e2007490d0d20074101742208200e200e2008491b220841ffffffff00712008470d0d2008410474220d4100480d0d0240024020070d00200d1029210e0c010b200541586a2802002007410474200d102a210e0b200e450d06200c2008360200200541586a200e360200200928020021070b200e20074104746a22074180023b010c200742828080802037020420072006360200200720032f01f0053b010e2009200928020041016a360200200341c0006a200a10b7032003280244417f6a210d2001280210210c2001280208210a0b200c412c6c2107200a41586a210502400340410021062007450d01200741546a2107200541286a21092005412c6a220e210520092d00004103470d000b200e41086a2802002207450d00200741286c2105200e28020041186a2107410021060340200620072d0000456a2106200741286a2107200541586a22050d000b0b200c412c6c2107200a41586a210502400340410021092007450d01200741546a2107200541286a210e2005412c6a22082105200e2d00004103470d000b200841086a2802002207450d00200741286c2105200828020041186a2107410021090340200920072d0000456a2109200741286a2107200541586a22050d000b0b200c412c6c2107200a41606a210502400340024020070d00410021070c020b200741546a2107200541206a210e2005412c6a220a2105200e2d00004104470d000b200a28020021070b200720096a220f41ffffffff0371200f470d0c200f4102742207417f4c0d0c0240024020070d00410421100c010b200710342210450d060b024002400240024002400240200f450d002010200f4102746a211141002112201021130340024020122006490d0020012802102214412c6c220921072001280208221541586a220e2105024003404100210a2007450d01200741546a2107200541286a21082005412c6a220c210520082d00004103470d000b200c41086a2802002207450d00200741286c2105200c28020041186a21074100210a0340200a20072d0000456a210a200741286a2107200541586a22050d000b0b2012200a6b220a20124b0d0303402009450d05200941546a2109200e41286a2107200e412c6a2205210e20072d0000410b470d000b200541086a280200200a4d0d052005280200200a41186c6a2802082105200341f0056a200a200110ba0420032802f405210720032802f0054101460d072013200720056a3602000b201241016a2112201341046a22132011470d000b0b20012802102114200128020821150c0f0b412c10292207450d0a200741286a4100280082c145360000200741206a41002900fac045370000200741186a41002900f2c045370000200741106a41002900eac045370000200741086a41002900e2c045370000200741002900dac04537000042ac808080c005210b0c020b412c10292207450d0a200741286a41002800aec145360000200741206a41002900a6c145370000200741186a410029009ec145370000200741106a4100290096c145370000200741086a410029008ec14537000020074100290086c14537000042ac808080c005210b0c010b411e10292207450d0a200741166a41002900c8c145370000200741106a41002900c2c145370000200741086a41002900bac145370000200741002900b2c145370000429e808080e003210b0b2010102e0c0a0b20032903f805210b2010102e20070d09410021100c0a0b41104108102c000b41204108102c000b41104104102c000b20094104102c000b200d4104102c000b20074104102c000b412c4101102c000b412c4101102c000b411e4101102c000b410021100c030b02402014450d0020152014412c6c6a2116200341e0046a41146a2117200341e0076a2118200341f0056a41017221190340024020152d0000410b470d00201528020c2207450d002015280204220a200741186c6a211a03400240200a41146a220c2802002207450d00200a410c6a21124100210e0240024002400240024002400340200e20074f0d014101210702402012280200200e41047422136a22052d0000410b470d002003200541046a22053602c0022010450d04200f200528020022054d0d03201020054102746a2802002209450d00201920032f00e0043b0000201941026a200341e0046a41026a2d00003a0000200341123a00f0052003200d3602d407200341133a00d007200341d7003a00c007200320093602b4072003412d3a00b0072003200d3602a407200341123a00a00720032005360294072003410b3a009007200341063a008007200341003a00f00620034184083b01e006200341373a00d006200320023602c4062003412d3a00c0062003200d3602b406200341123a00b0062003200d3602a406200341133a00a006200341d6003a00900620032009360284062003412d3a0080062003200d3602f405200c2802002211200e4d0d05200c200e360200200a28020c2107200320183602f804200320123602f0042003200720136a220841106a22063602e8042003200e41016a22143602e0042003201120146b221b3602e404200320072014410474221c6a221d3602ec042003200341f0056a3602f40420062107024020082d0000220941ac01460d004100210702400340200820076a21050240200941ff01714109470d00200541086a28020041ffffffff0371450d00200541046a280200102e0b2007450d012003200541206a3602e804200741106a2107200541106a2d0000220941ac01470d000b200820076a41106a21070c010b200541106a21070b02402007201d460d00034020032007220541106a22073602e8040240024020052d000022094109460d00200941ac01470d010c030b200541086a28020041ffffffff0371450d00200541046a280200102e0b20062007470d000b0b0240024002400240201b450d0002402014200a2802142207470d00200341f0056a2107201821080c030b2013200741047422076b2109200a28020c20076a2105200341f0056a21072018210603400240024020072006470d00410021070c010b2003200741106a3602f4040b200341d0036a200710c00420032d00d00341ac01460d04200520032903d003370300200541086a200341d0036a41086a290300370300200a200a28021441016a3602142009450d02200541106a2105200941706a210920032802f804210620032802f40421070c000b0b2012201710c1040c020b20032802f804210820032802f40421070b0240200820076b2205450d000240024020032802f004220641046a221d280200221320116b20054104762209490d00200628020021050c010b201120096a22052011490d1020134101742211200520052011491b221141ffffffff00712011470d102011410474221e4100480d100240024020130d00201e102921050c010b20062802002013410474201e102a21050b2005450d0920062005360200201d20113602000b2005201420096a22134104746a2005201c6a201b41047410f7041a200320133602e004201320062802082205460d00200e20096a410474200541047422056b2109200628020020056a210503400240024020072008470d00410021070c010b2003200741106a3602f4040b200341d0036a200710c00420032d00d00341ac01460d02200520032903d003370300200541086a200341d0036a41086a2903003703002006200628020841016a3602082009450d01200541106a2105200941706a210920032802f804210820032802f40421070c000b0b200341003602d803200342083703d003200341d0036a201710c10420032802d003221b20032802d803220541047422086a210620032802d403211c201b210702402005450d000240024020032802f004221341046a221d280200220720032802e404221420032802e00422056a22116b20084104752209490d00201328020021070c010b201120096a221e2011490d1020074101742211201e201e2011491b221141ffffffff00712011470d102011410474221e4100480d100240024020070d00201e102921070c010b20132802002007410474201e102a21070b2007450d0a20132007360200201d20113602000b2007200520096a220941047422116a200720054104746a201441047410f7041a200320093602e004201b2107200920132802082205460d002013280200220720116a211d200720054104746a2109201b21050340024020080d00200621070c020b200341d0036a41026a2207200541036a2d00003a0000200320052f00013b01d003024020052d0000221441ac01470d00200541106a21070c020b200541046a290200210b2005410c6a2802002111200920143a00002009410c6a2011360200200941046a200b37020020032f01d0032114200941036a20072d00003a0000200941016a20143b00002013201328020841016a360208200841706a2108200541106a22072105200941106a2209201d470d000b0b024020072006460d0003400240024020072d000022054109460d00200541ac01470d010c030b200741086a28020041ffffffff0371450d00200741046a280200102e0b200741106a22072006470d000b0b201c450d00201b102e0b024020032802e804220720032802ec042206460d00034020032007220541106a22073602e8040240024020052d000022094109460d00200941ac01470d010c030b200541086a28020041ffffffff0371450d00200541046a280200102e0b20062007470d000b0b024020032802e4042207450d00024020032802e004220620032802f004220841086a22092802002205460d002008280200220820054104746a200820064104746a200741047410f7041a0b2009200720056a3602000b024020032d00f0054109470d0020032802f80541ffffffff0371450d0020032802f405102e0b024020032d0080064109470d0020032802880641ffffffff0371450d00200328028406102e0b024020032d0090064109470d0020032802980641ffffffff0371450d00200328029406102e0b024020032d00a0064109470d0020032802a80641ffffffff0371450d0020032802a406102e0b024020032d00b0064109470d0020032802b80641ffffffff0371450d0020032802b406102e0b024020032d00c0064109470d0020032802c80641ffffffff0371450d0020032802c406102e0b024020032d00d0064109470d0020032802d80641ffffffff0371450d0020032802d406102e0b024020032d00e0064109470d0020032802e80641ffffffff0371450d0020032802e406102e0b024020032d00f0064109470d0020032802f80641ffffffff0371450d0020032802f406102e0b024020032d0080074109470d0020032802880741ffffffff0371450d00200328028407102e0b024020032d0090074109470d0020032802980741ffffffff0371450d00200328029407102e0b024020032d00a0074109470d0020032802a80741ffffffff0371450d0020032802a407102e0b024020032d00b0074109470d0020032802b80741ffffffff0371450d0020032802b407102e0b024020032d00c0074109470d0020032802c80741ffffffff0371450d0020032802c407102e0b024020032d00d0074109470d0020032802d80741ffffffff0371450d0020032802d407102e0b410f21070b2007200e6a220e200c2802002207490d000c070b0b41d0c1c500200e20071038000b2003410136028406200342013702f405200341e0c1c5003602f005200341263602d4032003200341d0036a360280062003200341c0026a3602d003200341e0046a200341f0056a108a0420032802e0042207450d0420032902e404210b0c0b0b418ec0c50041cc00109b01000b418cc6c5001058000b201e4108102c000b201e4108102c000b200a41186a220a201a470d000b0b2015412c6a22152016470d000b0b200341c8006a41106a200141106a280200221f360200200341c8006a41086a200141086a290200220b37030020032001290200370348201f412c6c2107200ba7222041586a210502400340024020070d00410021070c020b200741546a2107200541286a21092005412c6a220e210520092d00004108470d000b200341386a200e10b70320032802382107200328023c21050b2005410020071b2106201f412c6c2105202041586a2109200741c8ecc50020071b210702400340024020050d004100210e0c020b200541546a2105200941286a210e2009412c6a220a2109200e2d0000410a470d000b200341306a200a10b7032003280230210e200328023421050b20054100200e1b2108201f412c6c2105202041586a2109200e41c8ecc500200e1b211e02400340024020050d00410021210c020b200541546a2105200941286a210e2009412c6a220a2109200e2d00004109470d000b200a2802002109410121210b20034200370274200341e08dc000360270201e2008411c6c6a21222007200641146c6a2106200341e0046a410272220141266a2123200141186a21244100211741002125410021264100210c4100211c4104211a410421110240024002400240410041ff01710e03000102000b410021050c020b410221050c010b410121050b03400240024002400240024002400240024002400240024020050e03000105050b0240201741ff01710e03020700020b20264101470d02410021050c030b2021450d0441022119410021214100211d200921050c060b024002400240034002400240024002400240200620076b413c4b0d00024020072006460d002007410c6a21050340200728020c450d03200541146a2105200741146a22072006470d000b200621070b20264101470d02410021050c030b200728020c0d032007410c6a2105200741146a21070c070b200541086a21070c060b410121050b0340024002400240024020050e020001010b20182025470d014101212620252118410121050c030b41022117201e2022460d0e200341106a201e10a104201e411c6a211e20032802102205450d0f200520032802144102746a2125200521180c010b201841046a210e024020180d004101212641022117200e21180c0f0b201828020021054101212641022117410021192009211d200e21180c0c0b410021050c000b0b200741206a2205280200450d01200741346a2205280200450d02200741c8006a2105200741d0006a220e210720052802000d000b200e21070c020b200741286a21070c010b2007413c6a21070b20052802042105410021192009211d410021170c050b410121050b0340024002400240024020050e020001010b20182025470d014101212620252118410121050c030b41022117201e2022460d07200341186a201e10a104201e411c6a211e20032802182205450d082005200328021c4102746a2125200521180c010b201841046a210e024020180d004101212641022117200e21180c080b201828020021054101212641022117410021192009211d200e21180c050b410021050c000b0b02400240024002400240201741ff01710e03010400010b20264101470d01410021050c020b024002400240034002400240024002400240200620076b413c4b0d00024020072006460d002007410c6a21050340200728020c450d03200541146a2105200741146a22072006470d000b200621070b20264101470d02410021050c030b200728020c0d032007410c6a2105200741146a21070c070b200541086a21070c060b410121050b0340024002400240024020050e020001010b20182025470d01410121050c030b201e2022460d0b200341206a201e10a10420032802202218450d0b201e411c6a211e201820032802244102746a21250c010b2018450d0a2018280200210541012119410221172009211d201841046a2118410121260c0c0b410021050c000b0b200741206a2205280200450d01200741346a2205280200450d02200741c8006a2105200741d0006a220e210720052802000d000b200e21070c020b200741286a21070c010b2007413c6a21070b2005280204210541002117410121192009211d0c050b410121050b0340024002400240024020050e020001010b20182025470d01410121050c030b201e2022460d04200341286a201e10a10420032802282218450d04201e411c6a211e2018200328022c4102746a21250c010b2018450d032018280200210541012119410221172009211d201841046a2118410121260c050b410021050c000b0b024002400240024003400240200620076b413c4b0d0020072006460d06200741106a21050340200728020c450d03200541146a2105200741146a22072006470d000c070b0b0240200728020c0d002007410c6a2105200741146a2107200528020421050c050b200741206a2205280200450d02200741346a2205280200450d03200741c8006a2105200741d0006a220e210720052802000d000b200e2107200528020421050c030b200541046a2107200528020021050c020b200741286a2107200528020421050c010b2007413c6a2107200528020421050b410121192009211d410121170c020b200341e0006a41086a200341f0006a41086a28020036020020032003290370370360201f412c6c2107202041586a210502400340410021092007450d01200741546a2107200541286a210e2005412c6a220a2105200e2d00004103470d000b200a41086a2802002207450d00200741286c2105200a28020041186a2107410021090340200920072d0000456a2109200741286a2107200541586a22050d000b0b201f412c6c2107202041606a210502400340024020070d00410021070c020b200741546a2107200541206a210e2005412c6a220a2105200e2d00004104470d000b200a28020021070b200341f0056a41106a200341c8006a41106a280200360200200341f0056a41086a200341c8006a41086a290300370300200320032903483703f005200341b0016a200341f0056a10b9030240200c450d002011200c4102746a2118200720096a211b200341e0076a2112200341e7046a211703402011220741046a21112007280200210a200341e0006a21072003280264210803402007280200220641086a210520062f0106220c4102742107417f210902400340024020070d00200c21090c020b2005280200210e2007417c6a2107200941016a2109200541046a210502404100417f4101200e200a4b1b200e200a461b41016a0e03020001020b0b200641346a20094105746a22132802182105201328021c21072003200d3602d407200341133a00d007200341d7003a00c007200320073602b4072003412d3a00b0072003200d3602a407200341123a00a00720032005360294072003410b3a009007200341063a008007200341003a00f00620034184083b01e006200341373a00d006200320023602c4062003412d3a00c0062003200d3602b406200341123a00b0062003200d3602a406200341133a00a006200341d6003a00900620032007360284062003412d3a0080062003200d3602f405200341123a00f0052013280208220a41106a220e41ffffffff0071200e470d0a200e4104742207417f4c0d0a201341086a21190240024002400240024020070d004108210c0c010b20071029220c450d012019280200210a0b0240200a0d00410021050c030b4100210941002107034002402007200e470d00200e41016a2205200e490d0e200e4101742206200520052006491b220541ffffffff00712005470d0e200541047422064100480d0e02400240200e0d0020061029210c0c010b200c200e4104742006102a210c0b200c450d032005210e0b200c20096a2205410f3a0000200541046a2007360200200541016a20032f01d0033b0000200541036a200341d0036a41026a2d00003a0000200941106a2109200741016a22052107200a2005460d030c000b0b20074108102c000b20064108102c000b02400240024002400240024002400240200e20056b410f4f0d002005410f6a22072005490d11200e4101742209200720072009491b220741ffffffff00712007470d11200741047422094100480d1102400240200e0d0020091029210c0c010b200c200e4104742009102a210c0b200c450d012007210e0b200c20054104746a2107200341f0056a2109034020052108024002400240024020092d00002205414f6a41fb004f0d000c010b02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020050e312c2c0001022c2c0304052c06072c2c08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292c0b20092d00012106410221050c2b0b20092d00012106410321050c2a0b20092d00012106410421050c290b200941046a280200210a410721050c270b200941046a280200210a410821050c260b2009280208221d41ffffffff0371201d470d39201d4102742205417f4c0d390240024020050d004104210a0c010b20051029220a450d2a0b0240201d450d0020092802042105201d4102742114200a2106034020062005280200360200200641046a2106200541046a21052014417c6a22140d000b0b200935020c422086201dad84210b410921050c250b200941046a280200210a410b21050c240b200941046a280200210a20092d00012106410c21050c240b200941046a280200210a410f21050c220b200941046a280200210a411021050c210b200941046a280200210a411121050c200b200941046a280200210a411221050c1f0b200941046a280200210a411321050c1e0b200941046a280200210a2009350208210b411421050c1d0b200941046a280200210a2009350208210b411521050c1c0b200941046a280200210a2009350208210b411621050c1b0b200941046a280200210a2009350208210b411721050c1a0b200941046a280200210a2009350208210b411821050c190b200941046a280200210a2009350208210b411921050c180b200941046a280200210a2009350208210b411a21050c170b200941046a280200210a2009350208210b411b21050c160b200941046a280200210a2009350208210b411c21050c150b200941046a280200210a2009350208210b411d21050c140b200941046a280200210a2009350208210b411e21050c130b200941046a280200210a2009350208210b411f21050c120b200941046a280200210a2009350208210b412021050c110b200941046a280200210a2009350208210b412121050c100b200941046a280200210a2009350208210b412221050c0f0b200941046a280200210a2009350208210b412321050c0e0b200941046a280200210a2009350208210b412421050c0d0b200941046a280200210a2009350208210b412521050c0c0b200941046a280200210a2009350208210b412621050c0b0b200941046a280200210a2009350208210b412721050c0a0b200941046a280200210a2009350208210b412821050c090b200941046a280200210a2009350208210b412921050c080b200941046a280200210a2009350208210b412a21050c070b20092d00012106412b21050c070b20092d00012106412c21050c060b200941046a280200210a412d21050c040b2009290308210b412e21050c020b200941046a280200210a412f21050c020b2009290308210b413021050b0b0b200720063a0001200720053a0000200741086a200b370300200741046a200a360200200841016a2105200741106a2107200941106a22092012470d000b02400240200e2005460d00200e21090c010b200e41016a2207200e490d11200e4101742205200720072005491b220941ffffffff00712009470d11200941047422074100480d1102400240200e0d0020071029210c0c010b200c200e4104742007102a210c0b200c450d03200e21050b200c20054104746a220741063a0000200720032900e004370001200741086a2017290000370000200341e0046a200341b0016a418c0110f6041a411010292205450d03200541063a0000200341d0036a200341e0046a418c0110f6041a20192802002207417f4c0d110240024020070d004101210a41014101200710f6041a2007ad210b410021070c010b2013280200210e20071029220a450d05200a200e200710f604210e20071029220a450d06200a200e200710f6041a200e102e2007ad210b0b200341e0046a200341d0036a418c0110f6041a201331000d2127200341d0036a200341e0046a418c0110f6041a200341e0046a200341d0036a418c0110f6041a200341c0026a200341e0046a418c0110f6041a41101029220e450d06200841026a210620284280808080808040832228200b842027422886844280808080800c84210b200e41063a0000200e102e200341d0036a200341c0026a418c0110f6041a200341e0046a200341d0036a418c0110f6041a024020052d00004109470d00200528020841ffffffff0371450d002005280204102e0b2005102e200341c0026a200341e0046a418c0110f6041a200341e0046a200341c0026a418c0110f6041a200341003602fc03200320063602f803200320093602f4032003200c3602f003200341003602ec03200342043702e4032003200b3702dc03200320073602d8032003200a3602d403200341013602d003200341e0046a200341d0036a10be03200341b0016a200341e0046a418c0110f6041a201341013602102013201b360214024020032d00f0054109470d0020032802f80541ffffffff0371450d0020032802f405102e0b024020032d0080064109470d0020032802880641ffffffff0371450d00200328028406102e0b024020032d0090064109470d0020032802980641ffffffff0371450d00200328029406102e0b024020032d00a0064109470d0020032802a80641ffffffff0371450d0020032802a406102e0b024020032d00b0064109470d0020032802b80641ffffffff0371450d0020032802b406102e0b024020032d00c0064109470d0020032802c80641ffffffff0371450d0020032802c406102e0b024020032d00d0064109470d0020032802d80641ffffffff0371450d0020032802d406102e0b024020032d00e0064109470d0020032802e80641ffffffff0371450d0020032802e406102e0b024020032d00f0064109470d0020032802f80641ffffffff0371450d0020032802f406102e0b024020032d0080074109470d0020032802880741ffffffff0371450d00200328028407102e0b024020032d0090074109470d0020032802980741ffffffff0371450d00200328029407102e0b024020032d00a0074109470d0020032802a80741ffffffff0371450d0020032802a407102e0b024020032d00b0074109470d0020032802b80741ffffffff0371450d0020032802b407102e0b024020032d00c0074109470d0020032802c80741ffffffff0371450d0020032802c407102e0b024020032d00d0074109470d0020032802d80741ffffffff0371450d0020032802d407102e0b20284280808080808c01842128201b41016a211b20112018470d090c0a0b20094108102c000b20054104102c000b20074108102c000b41104108102c000b20074101102c000b20074101102c000b41104108102c000b02402008450d002008417f6a2108200620094102746a4194036a21070c010b0b0b4198c7c500418001109b01000b0240201c450d00201a102e0b200341f0056a200341b0016a418c0110f6041a200341e0046a200341f0056a10bb030240200341e0046a41106a2802002207450d0020032802e80422192007412c6c6a211d0340024020192d000041786a220741024b0d0002400240024020070e03000102000b201928020c2207450d0220192802042209200741146c6a211203400240200928020c0d002009280210210c2003280264210d200341e0006a210703402007280200220841286a210e200841086a210520082f010622134102742107417f210a02400340024020070d002013210a0c020b200528020021062007417c6a2107200a41016a210a200e41206a210e200541046a210502404100417f41012006200c4b1b2006200c461b41016a0e03020001020b0b0240200e417c6a280200450d002009200e2802003602100c030b4198c8c5004135109b01000b200d450d01200d417f6a210d2008200a4102746a4194036a21070c000b0b200941146a22092012470d000c030b0b201928020421082003280264210c200341e0006a210703402007280200220641286a2109200641086a210520062f0106220d4102742107417f210e02400340024020070d00200d210e0c020b2005280200210a2007417c6a2107200e41016a210e200941206a2109200541046a210502404100417f4101200a20084b1b200a2008461b41016a0e03020001020b0b02402009417c6a280200450d00201920092802003602040c040b4198c8c5004135109b01000b200c450d02200c417f6a210c2006200e4102746a4194036a21070c000b0b201928020c2207450d00201928020422112007411c6c6a211b0340024020112802182207450d002011280210220d20074102746a21140340200d221241046a210d201228020021082003280264210c200341e0006a210703402007280200220641286a2109200641086a210520062f010622134102742107417f210e024002400340024020070d002013210e0c020b2005280200210a2007417c6a2107200e41016a210e200941206a2109200541046a210502404100417f4101200a20084b1b200a2008461b41016a0e03020001020b0b02402009417c6a280200450d00201220092802003602000c020b4198c8c5004135109b01000b200c450d00200c417f6a210c2006200e4102746a4194036a21070c010b0b200d2014470d000b0b2011411c6a2211201b470d000b0b2019412c6a2219201d470d000b0b200341ec046a290200210b20032802e004210720032902e404212820032802602003280264200328026810c304200041106a200b370200200041086a202837020020002007360204200041003602002010450d08200f450d082010102e200424000f0b0240024002400240024003400240200620076b413c4b0d004101211720072006460d09200741106a21050340200728020c450d03200541146a2105200741146a22072006470d000b200621070c090b0240200728020c0d002007410c6a2105200741146a21070c050b200741206a2205280200450d02200741346a2205280200450d03200741c8006a2105200741d0006a220e210720052802000d000b200e21070c030b200541046a2107200528020021050c030b200741286a21070c010b2007413c6a21070b200528020421050b41012117410021192009211d0b2003200536027c0240024002400240024002400240024002402010450d000240200f20054b0d002003410136028406200342023702f40520034188c7c5003602f005200341013602d4032003200341d0036a360280062003200341fc006a3602d003200341e0046a200341f0056a108a0420032902e404220b422088a7210920032802e0042113200ba721290c090b201020054102746a2802002209450d0402400240201c200c470d00200c41016a220e200c490d0e200c410174220a200e200e200a491b221c41ffffffff0371201c470d0e201c410274220e4100480d0e02400240200c0d00200e1029211a0c010b201a200c410274200e102a211a0b201a450d01201a21110b2011200c4102746a2005360200200341f0056a200328027c2208200341c8006a10bf0420032802f805212920032802f4052113024020032802f00522164101470d0020032802fc0521090c0a0b20132802082205417f4c0d0e20132d000c210a02400240024020050d004101210e0c010b2013280200211220051029220e450d01200e2012200510f6041a0b2003200a3a008c01200320053602880120032005360284012003200e3602800120132d000d21052003200936029c012003200328027c360298012003410036029001200320053a008d010240024002402003280270220541e08dc000460d002003280274211b0c010b20234200370100200141206a420037010020244200370100200141106a4200370100200141086a420037010020014200370100200341f0056a410041e00210f5041a41940310292205450d014100211b20054100360200200520032903e0043702042005410c6a200341e0046a41086a290300370200200541146a200341e0046a41106a2903003702002005411c6a200341e0046a41186a290300370200200541246a200341e0046a41206a2903003702002005412c6a200341e0046a41286a290300370200200541346a200341f0056a41e00210f6041a20034100360274200320053602700b200c41016a210c0340200541146a210e20052f010622154102742114417f210a4100210902400340024020142009470d002015210a0c020b200520096a2112200941046a2109200a41016a210a200e41206a210e02404100417f4101201241086a280200221220084b1b20122008461b41016a0e03020001020b0b200e290200210b200e200329038001370200200e41186a200329039801370200200e41106a220529020021282005200329039001370200200e41086a200329038801370200202842ffffffff0f83420285500d08200b42808080807083500d08200ba7102e0c080b0240201b450d00201b417f6a211b2005200a4102746a4194036a28020021050c010b0b2003200328027841016a360278200329039801210b20032903900121282003290388012127200329038001212a20052f0106220e410b490d0420234200370100200141206a222b420037010020244200370100200141106a222c4200370100200141086a222d420037010020014200370100200341f0056a410041e00210f5041a024041940310292209450d0020094100360200200920032903e0043702042009410c6a200341e0046a41086a222e290300370200200941146a200341e0046a41106a222f2903003702002009411c6a200341e0046a41186a2230290300370200200941246a200341e0046a41206a22312903003702002009412c6a200341e0046a41286a2232290300370200200941346a200341f0056a41e00210f6042112200341f0056a41086a221b200541fc016a290200370300200341f0056a41106a221520054184026a290200370300200341f0056a41186a22332005418c026a290200370300200320052902f4013703f00520052802202134200941086a200541246a20052f010641796a220e41027410f6042114201220054194026a200e41057410f6042112200541063b01062009200e3b010620302033290300370300202f2015290300370300202e201b290300370300200320032903f0053703e00402400240200a4107490d002014200a417a6a22354102746a2014200a41796a220a4102746a2214200e41ffff0371200a6b41027410f7041a20142008360200201220354105746a2012200a4105746a220e200941066a22122f0100200a6b41057410f7041a200e41186a200b370200200e2028370210200e2027370208200e202a37020020122f010021140c010b200541086a220e200a41016a22354102746a200e200a4102746a220e200541066a22122f01002214200a6b223641027410f7041a200e2008360200200541346a220e20354105746a200e200a4105746a220e203641057410f7041a200e41186a200b370200200e2028370210200e2027370208200e202a3702000b2012201441016a3b0100200341d0036a41186a22372030290300220b370300200341d0036a41106a2238202f2903002228370300200341d0036a41086a2239202e2903002227370300200341b0016a41186a223a200b370300200341b0016a41106a223b2028370300200341b0016a41086a223c2027370300200320032903e004220b3703d0032003200b3703b0010240200528020022120d002009210e0c070b20052f010421352009213d0340200341c0026a41186a223e203a290300370300200341c0026a41106a223f203b290300370300200341c0026a41086a2240203c290300370300200320032903b0013703c002203541ffff037121080240024002400240024020122f01062205410b490d0020234200370100202b420037010020244200370100202c4200370100202d4200370100200142003701002039202e2903003703002038202f29030037030020372030290300370300200341d0036a41206a22052031290300370300200341d0036a41286a22092032290300370300200320032903e0043703d003200341f0056a410041900310f5041a41c4031029220e450d03200e4100360200200e20032903d003370204200e410c6a2039290300370200200e41146a2038290300370200200e411c6a2037290300370200200e41246a2005290300370200200e412c6a2009290300370200200e41346a200341f0056a41900310f6042109201241206a280200214120332012418c026a290200370300201520124184026a290200370300201b201241fc016a2902003703002003201241f4016a2902003703f005200e41086a201241246a20122f0106220a41796a220541027410f6042142200920124194026a200541057410f6042143200e4194036a201241b0036a200a417a6a221441027410f6042136201241063b0106200e20053b010602402014450d00410021052036210903402009280200220a20053b0104200a200e360200200941046a21092014200541016a2205470d000b0b20302033290300220b370300202f20152903002228370300202e201b2903002227370300200320032903f005222a3703e0042033200b37030020152028370300201b20273703002003202a3703f005203541ffff037122094107490d0120422008417a6a220a41027422146a2042200841796a22054102746a2209200e2f010620056b41027410f7041a200920343602002043200a4105746a204320054105746a2209200e2f010620056b41057410f7041a200941186a203e290300370200200941106a203f290300370200200941086a2040290300370200200920032903c002370200200e200e2f010641016a22093b01062008410274223520366a416c6a203620146a2214200941ffff03712208200a6b41027410f7041a2014203d3602002008200a490d02200e20356a41fc026a210903402009280200220a200541016a22053b0104200a200e360200200941046a210920052008490d000c030b0b201241086a2209200841016a220e410274220a6a2009200841027422146a2209200520086b221b41027410f7041a20092034360200201241346a2209200e4105746a200920084105746a2209201b41057410f7041a200941186a203e290300370200200941106a203f290300370200200941086a2040290300370200200920032903c0023702002012200541016a22053b0106201420124194036a22096a41086a2009200a6a2209200541ffff0371220a200e6b41027410f7041a2009203d3602002008200a4f0d0c2012200e417f6a22054102746a4198036a210903402009280200220e200541016a22053b0104200e2012360200200941046a21092005200a490d000c0d0b0b201241086a2205200841016a2214410274220a6a2005200841027422356a220520122f0106223620086b224241027410f7041a20052034360200201241346a220520144105746a200520084105746a2205204241057410f7041a200541186a203e290300370200200541106a203f290300370200200541086a2040290300370200200520032903c0023702002012203641016a22053b0106203520124194036a22366a41086a2036200a6a2236200541ffff0371220a20146b41027410f7041a2036203d3602002009200a4f0d00201220356a4198036a2105034020052802002209200841016a22083b010420092012360200200541046a2105200a2008470d000b0b203a2033290300370300203b2015290300370300203c201b290300370300200320032903f0053703b001201228020022050d01204121340c090b41c4034104102c000b20122f010421352005211220412134200e213d0c000b0b4194034104102c000b4194034104102c000b20054101102c000b200e4104102c000b418ec0c50041cc00109b01000b200541086a2209200a41016a22124102746a2009200a4102746a2209200e200a6b221441027410f7041a20092008360200200541346a220920124105746a2009200a4105746a2209201441057410f7041a200941186a200b37020020092028370210200920273702082009202a3702002005200e41016a3b01060c010b20234200370100202b420037010020244200370100202c4200370100202d4200370100200142003701002039202e2903003703002038202f29030037030020372030290300370300200341d0036a41206a22092031290300370300200341d0036a41286a220a2032290300370300200320032903e0043703d003200341f0056a410041900310f5041a41c40310292205450d0220054100360200200520032903d0033702042005410c6a2039290300370200200541146a20382903003702002005411c6a2037290300370200200541246a20092903003702002005412c6a200a290300370200200541346a200341f0056a41900310f604210820052003280270220936029403200320053602702003200328027441016a36027420092005360200200941003b0104200820052f0106220a4105746a220920032903b001370200200941186a203a290300370200200941106a203b290300370200200941086a203c2903003702002005200a4102746a41086a203436020020054194036a200a41016a22094102746a200e360200200520093b0106200e20093b0104200e20053602000b2016450d002029450d002013102e0b201d2109201941ff01710e03010205010b41c4034104102c000b410021050c040b410221050c030b20032802702003280274200328027810c3040240201c450d00201a102e0b0240201f450d00201f412c6c2105202021070340200710bf032007412c6a2107200541546a22050d000b0b0240200341d4006a280200450d002020102e0b2000201336020420004101360200200041086a2009ad4220862029ad843702002010450d06200f450d062010102e200424000f0b2022211e0b410121050c000b0b102d000b1032000b2000200736020420004101360200200041086a200b37020002402010450d00200f450d002010102e0b20012802082105024020012802102203450d002003412c6c2107200521030340200310bf032003412c6a2103200741546a22070d000b0b2001410c6a280200450d002005102e0b200424000b94830204117f017e037f017e230041e0006b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0f0100021211100f0e0d0c0b0a080706010b200141186a2802002104200141146a2802002105200141106a28020021062001410c6a2802002107200141086a2802002108200141046a28020021090240200241046a280200200241086a280200220a460d002002280200210b0c180b200a41016a220c200a490d14200a410174220d200c200c200d491b220c4100480d1402400240200a0d00200c1029210b0c010b2002280200200a200c102a210b0b200b450d042002200b360200200241046a200c360200200241086a280200210a0c170b2001410c6a280200210c200141086a2802002104200141046a280200210b20012d0001210502400240200241046a280200200241086a280200220a460d002002280200210d0c010b200a41016a220d200a490d14200a4101742206200d200d2006491b22064100480d1402400240200a0d0020061029210d0c010b2002280200200a2006102a210d0b200d450d032002200d360200200241046a2006360200200241086a280200210a0b200241086a2206200a41016a360200200d200a6a20053a000002400240200241046a280200220d2006280200220a6b200c490d002002280200210d0c010b200a200c6a2205200a490d14200d410174220a20052005200a491b220a4100480d1402400240200d0d00200a1029210d0c010b2002280200200d200a102a210d0b200d450d022002200d360200200241046a200a360200200241086a280200210a0b200241086a200a200c6a360200200d200a6a200b200c10f6041a4100210c41012107024020040d004101210d0c220b200b102e4101210d0c210b2001410c6a2802002106200141086a280200210e200141046a280200210f024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d14200a410174220d200c200c200d491b220d4100480d1402400240200a0d00200d1029210c0c010b2002280200200a200d102a210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41013a0000200f20064104746a21104100210d4100210c41002105410121042006210a024003400240200c2005470d00200d200c41016a220b200b200d491b22054100480d1602400240200d0d002005102921040c010b2004200c2005102a21040b2004450d020b2004200c6a200a41807f72200a41ff0071200a410776220b1b3a0000200d41026a210d200c41016a210c200b210a200b0d000b024020060d00200f21080c130b200f210a02400340200a41106a2108200a2d000d22114105460d14200a2d000c210d200a2802082109200a2802042112200a28020021130240024002400240024002402005200c470d00200c41016a220a200c490d1c200c410174220b200a200a200b491b22054100480d1c02400240200c0d002005102921040c010b2004200c2005102a21040b2004450d010b2004200c6a200d3a0000200c41016a210a200c410174220c41046a2107200c41026a210d2009210c0340200721060240200a2005470d00200a41016a220b200a490d1d200d200b200b200d491b22054100480d1d02400240200a0d002005102921040c010b2004200a2005102a21040b2004450d030b2004200a6a200c41807f72200c41ff0071200c410776220b1b3a0000200641026a2107200d41026a210d200a41016a210a200b210c200b0d000b0240024020090d00200a210c0c010b4100210d0340200a200d6a210c41fc00210b02400240024002402013200d6a2d00000e050200010305020b41fe00210b0c020b41fd00210b0c010b41ff00210b0b0240200c2005470d00200c41016a2205200c490d1e2006200520052006491b22054100480d1e02400240200c0d002005102921040c010b2004200c2005102a21040b2004450d050b2004200a6a200d6a200b3a0000200641026a21062009200d41016a220d470d000b200a200d6a210c0b20120d030c040b20054101102c000b20054101102c000b20054101102c000b2013102e0b4100210a024020114104460d0002402005200c470d00200c41016a220a200c490d18200c410174220d200a200a200d491b22054100480d1802400240200c0d002005102921040c010b2004200c2005102a21040b2004450d030b2004200c6a41013a0000200c41016a210c201141077141ff0073210a0b024002402005200c470d00200c41016a220d200c490d18200c410174220b200d200d200b491b22054100480d1802400240200c0d002005102921040c010b2004200c2005102a21040b2004450d010b2004200c6a200a3a0000200c41016a210c2008210a20082010470d010c160b0b20054101102c000b20054101102c000b20054101102c000b200d4101102c000b200a4101102c000b20064101102c000b200c4101102c000b200141286a2802002104200141246a2802002111200141206a28020021092001411c6a2802002106200141186a2802002113200141146a28020021082001410c6a2902002114200141086a280200210d200141046a280200210b024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d22200a4101742205200c200c2005491b22054100480d2202400240200a0d0020051029210c0c010b2002280200200a2005102a210c0b200c450d012002200c360200200241046a2005360200200241086a280200210a0b200241086a200a41016a36020041002105200c200a6a41003a0000200341dc006a41003602002003420137025420032002360250200320143e02482003200d3602442003200b360240200341086a200341c0006a200341d0006a109004024020032d0008220a411a460d0020032f000920032d000b41107472210c200341086a41086a2903002114200328020c21044100210d0c1e0b2014422088a7210c0340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d23200a410174220b200d200d200b491b220b4100480d2302400240200a0d00200b1029210d0c010b2003280254200a200b102a210d0b200d450d032003200b3602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b4101211202402008450d00200320063602482003201336024420032008360240200341086a200341c0006a200341d0006a109004024020032d0008220a411a460d0020032f000920032d000b41107472210c200341106a2903002114200328020c21044100210d410121050c1f0b410021120b200920044104746a21062004210c0340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d23200a410174220b200d200d200b491b220b4100480d2302400240200a0d00200b1029210d0c010b2003280254200a200b102a210d0b200d450d042003200b3602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b024020040d002009210b0c1d0b200441047441706a21072009210d0340200d41106a210b200d410c6a2802002102200d41086a280200210a200d280204210c0240024002400240024002400240024002400240200d2802000e09000102030405060727000b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2c200d4101742205200420042005491b22054100480d2c02400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d0e2003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a41003a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2d200d4101742205200420042005491b22054100480d2d02400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d102003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2d200c4101742204200d200d2004491b22044100480d2d02400240200c0d0020041029210d0c010b2003280254200c2004102a210d0b200d450d11200320043602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000c080b0b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2b200d4101742205200420042005491b22054100480d2b02400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d102003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a41013a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2c200d4101742205200420042005491b22054100480d2c02400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d122003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2c200c4101742204200d200d2004491b22044100480d2c02400240200c0d0020041029210d0c010b2003280254200c2004102a210d0b200d450d13200320043602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000c070b0b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2a200d4101742205200420042005491b22054100480d2a02400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d122003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a41023a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2b200d4101742205200420042005491b22054100480d2b02400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d142003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2b200c4101742204200d200d2004491b22044100480d2b02400240200c0d0020041029210d0c010b2003280254200c2004102a210d0b200d450d15200320043602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000c060b0b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d29200d4101742205200420042005491b22054100480d2902400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d142003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a41033a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d2a200d4101742205200420042005491b22054100480d2a02400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d162003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d2a200c4101742204200d200d2004491b22044100480d2a02400240200c0d0020041029210d0c010b2003280254200c2004102a210d0b200d450d17200320043602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000b200341086a2002200341d0006a10850420032d0008220a411a460d0520032f000920032d000b41107472210c0c220b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d28200d4101742205200420042005491b22054100480d2802400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d162003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a41043a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d29200d4101742205200420042005491b22054100480d2902400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d182003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d29200c4101742204200d200d2004491b22044100480d2902400240200c0d0020041029210d0c010b2003280254200c2004102a210d0b200d450d19200320043602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000b200341086a2002200341d0006a10850420032d0008220a411a460d0420032f000920032d000b41107472210c0c210b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d27200d4101742205200420042005491b22054100480d2702400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d182003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a41053a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d28200d4101742205200420042005491b22054100480d2802400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d1a2003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d28200c4101742204200d200d2004491b22044100480d2802400240200c0d0020041029210d0c010b2003280254200c2004102a210d0b200d450d1b200320043602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000b200341086a2002200341d0006a10850420032d0008220a411a460d0320032f000920032d000b41107472210c0c200b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d26200d4101742205200420042005491b22054100480d2602400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d1a2003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a41063a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d27200d4101742205200420042005491b22054100480d2702400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d1c2003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d27200c4101742204200d200d2004491b22044100480d2702400240200c0d0020041029210d0c010b2003280254200c2004102a210d0b200d450d1d200320043602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000c020b0b024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d25200d4101742205200420042005491b22054100480d2502400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d1c2003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a41073a00000340024002402003280258200328025c220d460d00200328025421040c010b200d41016a2204200d490d26200d4101742205200420042005491b22054100480d2602400240200d0d002005102921040c010b2003280254200d2005102a21040b2004450d1e2003200536025820032004360254200328025c210d0b2003200d41016a36025c2004200d6a200c41807f72200c41ff0071200c410776220d1b3a0000200d210c200d0d000b0340024002402003280258200328025c220c460d002003280254210d0c010b200c41016a220d200c490d26200c4101742204200d200d2004491b22044100480d2602400240200c0d0020041029210d0c010b2003280254200c2004102a210d0b200d450d1f200320043602582003200d360254200328025c210c0b2003200c41016a36025c200d200c6a200a41807f72200a41ff0071200a410776220c1b3a0000200c210a200c0d000b0b2003411a3a00080b200741706a2107200b210d200b2006470d000b2006210b0c1c0b20054101102c000b200b4101102c000b200b4101102c000b20054101102c000b20054101102c000b20044101102c000b20054101102c000b20054101102c000b20044101102c000b20054101102c000b20054101102c000b20044101102c000b20054101102c000b20054101102c000b20044101102c000b20054101102c000b20054101102c000b20044101102c000b20054101102c000b20054101102c000b20044101102c000b20054101102c000b20054101102c000b20044101102c000b20054101102c000b20054101102c000b20044101102c000b20032903102114200328020c2104024003402007450d01200741706a2107200b280200210d200b41106a210b200d4108470d000b0b02402011450d002009102e0b20124521054101210d0c010b024003402006200b460d01200b280200210a200b41106a210b200a4108470d000b0b02402011450d002009102e0b20032802582109200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d08200a4101742206200d200d2006491b22064100480d0802400240200a0d0020061029210d0c010b2004280200200a2006102a210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d07200c410174220a200d200d200a491b220a4100480d0702400240200c0d00200a1029210c0c010b2004280200200c200a102a210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710f6041a02402009450d002002102e0b41002110410121072008450d032012450d032013450d032008102e0c030b20064101102c000b200a4101102c000b02402003280258450d002003280254102e0b02402008452005720d002013450d002008102e0b0240200d201145720d002009102e0b200a411a470d1141002110410121070b4101210c4101210d4101210b4101210841012109410121044101210541012113410121064101210241012111410121120c350b200141146a280200210f200141106a28020021112001410c6a2802002113200141086a2802002110200141056a2d0000210d200141046a2d00002109024002400240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d0c200a410174220b200c200c200b491b220b4100480d0c02400240200a0d00200b1029210c0c010b2002280200200a200b102a210c0b200c450d012002200c360200200241046a200b360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41003a00000240410410292212450d00201241eec2b5ab06360000024020090e0400050403000b410121064100210a4100210c2011210d034002400240200a200c460d00200a21070c010b200a41016a220c200a490d0e200a410174220b200c200c200b491b22074100480d0e02400240200a0d002007102921060c010b2006200a2007102a21060b02402006450d00200a210c2007210a0c010b20074101102c000b2006200c6a200d41807f72200d41ff0071200d410776220b1b3a0000200c41016a210c200b210d200b0d000b0240024002402007200c6b20114f0d00200c20116a220a200c490d0f2007410174220d200a200a200d491b220a4100480d0f0240024020070d00200a102921060c010b20062007200a102a21060b2006450d01200a21070b2006200c6a2010201110f6041a200c20116a21084101210e20130d010c080b200a4101102c000b2010102e0c060b41044101102c000b200b4101102c000b410021154101210e20102106201321072011210841012116410121170c040b2003410036024820034201370340410121044100210d4100210a2010210c02400240024002400240024003400240200a200d470d00200d41016a220b200d490d10200d4101742205200b200b2005491b220b4100480d1002400240200d0d00200b102921040c010b2004200d200b102a21040b2004450d022003200b36024420032004360240200b210d0b2003200a41016a22053602482004200a6a200c41807f72200c41ff0071200c410776220b1b3a00002005210a200b210c200b0d000b2013200f4104746a21060240200f0d002013210b0c040b2013210b2010450d03200641706a21162010210e4100210a2013210803402008210b02400340200b41046a28020022070d01200a41016a210a2006200b41106a220b470d000c070b0b200b41106a2108200a41016a2115200e417f6a210e200b41086a2902002114200b28020021172003280244210d2003280248210c02400240034002400240200c200d460d00200328024021040c010b200d41016a2204200d490d13200d4101742205200420042005491b22054100480d1302400240200d0d002005102921040c010b2003280240200d2005102a21040b2004450d0220032005360244200320043602402005210d0b2003200c41016a22053602482004200c6a200a41807f72200a41ff0071200a41077622041b3a00002005210c2004210a20040d000b200320143703102003200736020c20032017360208200341d0006a200341086a200341c0006a108d0420032d00502204411a460d010c040b20054101102c000b2016200b460d032015210a200e0d000c030b0b200b4101102c000b20032d0053210e20032f0051211720032802542105200329035821140240200641706a200b460d00200b41106a210b0340200b220a41106a210b0240200a2802042207450d00200a28020821080240200a410c6a280200220a450d00200a410c6c210c2007210a03400240200a280200220d450d00200a41046a280200450d00200d102e0b200a410c6a210a200c41746a220c0d000b0b2008450d002007102e0b200b2006470d000b0b02402011450d002013102e0b2004411a460d03200e411074210a02402003280244450d002003280240102e0b2017200a72210a02400240200941024b0d000240024020090e03000109000b2013450d080c020b0240200f450d00200f410c6c210d2013210c03400240200c280200220b450d00200c41046a280200450d00200b102e0b200c410c6a210c200d41746a220d0d000b0b02402011450d002013102e0b2004411a470d074100210541012104410021080c0a0b2013450d060b2010102e0c050b200b41106a210b0b200b2006460d000340200b220a41106a210b0240200a2802042204450d00200a28020821050240200a410c6a280200220a450d00200a410c6c210c2004210a03400240200a280200220d450d00200a41046a280200450d00200d102e0b200a410c6a210a200c41746a220c0d000b0b2005450d002004102e0b200b2006470d000b0b2011450d002013102e0b2003280248210820032802442107200328024021064102210d410021164101210e41002117410021150c030b4100210e2003410036024820034201370340200341146a200f360200200341086a41086a20113602002003201336020c20032010360208200341d0006a200341086a200341c0006a108d04024020032d00502204411a460d0020032d0053411074210a20032f0051210c200341d0006a41086a29030021142003280254210502402003280244450d002003280240102e0b200c200a72210a0c010b2003280248210820032802442107200328024021064101211641002117410021154101210d0c020b200041086a2014370200200041046a20053602002000200a4108742004723602002012102e0c030b4100211741012116410121154100210d0b024002400240410110292204450d002004200d3a00004102210d4101210a410121052008210c03400240200a2005470d00200d200a41016a220b200b200d491b22054100480d092004200a2005102a2204450d030b2004200a6a200c41807f72200c41ff0071200c410776220b1b3a0000200d41026a210d200a41016a210a200b210c200b0d000b02402005200a6b20084f0d00200a20086a220c200a490d082005410174220d200c200c200d491b220c4100480d080240024020050d00200c102921040c010b20042005200c102a21040b2004450d03200c21050b2004200a6a2006200810f6041a02402007450d002006102e0b2008200a6a21080240200941024b0d00024002400240024020090e03000102000b2015201345720d072010102e0c070b200e450d060240200f450d00200f410c6c210c2013210a03400240200a280200220d450d00200a41046a280200450d00200d102e0b200a410c6a210a200c41746a220c0d000b0b20110d010c060b2016450d050240200f450d002013200f4104746a21072013210603402006220b41106a21060240200b280204220a450d000240200b410c6a280200220c450d00200c410c6c210c03400240200a280200220d450d00200a41046a280200450d00200d102e0b200a410c6a210a200c41746a220c0d000b0b200b41086a280200450d00200b280204102e0b20062007470d000b0b2011450d050b2013102e0c040b2017201345720d032010102e0c030b41014101102c000b20054101102c000b200c4101102c000b2003411c6a2008360200200341186a20053602002003200436021420034284808080c00037020c20032012360208200341d0006a200341086a2002109504200320032900513703402003200341d0006a41086a29000037004720032d0050220a411a460d012000200a3a000020002003290340370001200041086a20032900473700000b410021094101210d4101210c4101210b410121044101210541012106410121074101210241012108410121130c1a0b41002112410121074101210c4101210d4101210b41012108410121094101210441012105410121134101210641012102410121110c330b2001410c6a2802002105200141086a2802002113200141046a28020021090240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d15200a410174220d200c200c200d491b220d4100480d1502400240200a0d00200d1029210c0c010b2002280200200a200d102a210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a410b3a0000200341dc006a4100360200200342013702542003200236025020092005411c6c6a21074100210a4100210c2005210d034002400240200a200c460d002003280254210a0c010b200a41016a220b200a490d16200a4101742204200b200b2004491b220b4100480d1602400240200a0d00200b1029210a0c010b2003280254200a200b102a210a0b200a450d032003200b3602582003200a3602540b2003200c41016a36025c200a200c6a200d41807f72200d41ff0071200d410776220d1b3a00000240200d450d002003280258210a200328025c210c200d210d0c010b0b200921042005450d062009210a0340200a411c6a2104200a2802042202450d07200a41186a2802002105200a41146a2802002108200a41086a2902002114200a280200210c200a28021021060340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d17200a410174220b200d200d200b491b220b4100480d1702400240200a0d00200b1029210d0c010b2003280254200a200b102a210d0b200d450d052003200b3602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b2003201437024420032002360240200341086a200341c0006a200341d0006a108204024020032d0008220d411a470d002005210c0340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d18200a410174220b200d200d200b491b220b4100480d1802400240200a0d00200b1029210d0c010b2003280254200a200b102a210d0b200d450d072003200b3602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b024002402003280258220c200328025c220a6b2005490d002003280254210c0c010b200a20056a220d200a490d0b200c410174220a200d200d200a491b220a4100480d0b02400240200c0d00200a1029210c0c010b2003280254200c200a102a210c0b200c450d072003200a3602582003200c360254200328025c210a0b2003200a20056a36025c200c200a6a2006200510f6041a02402008450d002006102e0b2004210a20042007470d010c090b0b20032d000b211220032f0009211020032903102114200328020c21112008450d052006102e0c050b200d4101102c000b200b4101102c000b200b4101102c000b200b4101102c000b200a4101102c000b024020042007460d0003402004280204220b450d01200441146a2802002105200441086a28020021062004280210210202402004410c6a280200220a450d00200a410474210c200b210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b02402006450d00200b102e0b2004411c6a210402402005450d002002102e0b20042007470d000b0b2012411074210a02402013450d002009102e0b2010200a72210a02402003280258450d002003280254102e0b2000200a3b00012000200d3a0000200041036a200a4110763a0000200041086a2014370000200041046a2011360000410021084101210d4101210c4101210b41012104410121054101210641012107410121020c190b20042007460d0003402004280204220d450d01200441146a280200210b200441086a28020021052004280210210602402004410c6a280200220a450d00200a410474210c200d210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b02402005450d00200d102e0b2004411c6a21040240200b450d002006102e0b20042007470d000b0b02402013450d002009102e0b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d04200a4101742206200d200d2006491b22064100480d0402400240200a0d0020061029210d0c010b2004280200200a2006102a210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d03200c410174220a200d200d200a491b220a4100480d0302400240200c0d00200a1029210c0c010b2004280200200c200a102a210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710f6041a02402008450d002002102e0b41002111410121074101210c4101210d4101210b41012108410121094101210441012105410121134101210641012102410121120c340b20064101102c000b200a4101102c000b102d000b2001410c6a2802002105200141086a2802002117200141046a280200210e024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d0f200a410174220d200c200c200d491b220d4100480d0f02400240200a0d00200d1029210c0c010b2002280200200a200d102a210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a410a3a00002003412c6a41003602002003420137022420032002360220200e200541186c6a210f4100210a4100210c2005210d0240034002400240200a200c460d002003280224210a0c010b200a41016a220b200a490d11200a4101742204200b200b2004491b220b4100480d1102400240200a0d00200b1029210a0c010b2003280224200a200b102a210a0b200a450d022003200b3602282003200a3602240b2003200c41016a36022c200a200c6a200d41807f72200d41ff0071200d410776220d1b3a00000240200d450d002003280228210a200328022c210c200d210d0c010b0b200e21092005450d03200341086a4101722102200341086a41026a2107200e210a02400340200a41186a2109200a2802002208450d05200a41146a2802002111200a41106a2802002112200a28020c2113200a29020421144100210c2003410036024c2003420137024420082014422088a7220d4103746a21062003200341206a3602402014a721104100210a024002400240024002400240034002400240200c200a460d002003280244210c0c010b200c41016a220a200c490d19200c410174220b200a200a200b491b220a4100480d1902400240200c0d00200a1029210c0c010b2003280244200c200a102a210c0b200c450d022003200a3602482003200c360244200328024c210a0b2003200a41016a36024c200c200a6a200d41807f72200d41ff0071200d410776220d1b3a00000240200d450d002003280248210c200328024c210a200d210d0c010b0b0240024020062008470d00200821040c010b2008210a0340200a41086a2104200a2902002214422088a7220a41ff01714104460d01200a41187441187521052014a7210c0340024002402003280248200328024c220a460d002003280244210d0c010b200a41016a220d200a490d1b200a410174220b200d200d200b491b220b4100480d1b02400240200a0d00200b1029210d0c010b2003280244200a200b102a210d0b200d450d052003200b3602482003200d360244200328024c210a0b2003200a41016a36024c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b024002402003280248200328024c220a460d002003280244210c0c010b200a41016a220c200a490d1a200a410174220d200c200c200d491b220d4100480d1a02400240200a0d00200d1029210c0c010b2003280244200a200d102a210c0b200c450d052003200d3602482003200c360244200328024c210a0b2003200a41016a36024c200c200a6a2005417f73220a413f7141c00072200a2005417f4a1b3a00002004210a20042006470d000b200621040b0240034020062004460d0120042d0004210a200441086a2104200a4104470d000b0b02402010450d002008102e0b20132011410474220a6a210b024020110d002013210a0c050b201341186a210c200a41706a21042013210a0340200a2d0000210d2007200a41036a2d00003a00002003200a41016a2f00003b01080240200d41ac01470d00200a41106a210a0c060b200341306a41026a20072d000022053a0000200320032f010822063b0130200a41046a2902002114200a410c6a2802002108200220063b0000200241026a20053a00002003200d3a0008200320083602142003201437020c200341d0006a200341086a200341c0006a108c0420032d00502205411a46220d450d04200c41106a210c200441706a2104200a41106a220a200b470d000c060b0b200a4101102c000b200b4101102c000b200d4101102c000b20032d0053210820032f00512111200328025421062003290358211402402004450d00034002400240200c41786a220a2d000022044109460d00200441ac01470d010c030b200c28020041ffffffff0371450d00200a41046a280200102e0b200c41106a210c200a41106a200b470d000b0b02402012450d002013102e0b02402003280248450d002003280244102e0b200d450d062009210a2009200f470d020c080b200a200b460d00034002400240200a2d0000220c4109460d00200c41ac01470d010c030b200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a220a200b470d000b0b02402012450d002013102e0b20032802482111200328024421132003280240210d200328024c2208210c0240034002400240200d41086a2205280200200d410c6a2204280200220a460d00200d280204210b0c010b200a41016a220b200a490d14200a4101742206200b200b2006491b22064100480d1402400240200a0d0020061029210b0c010b200d280204200a2006102a210b0b200b450d02200d200b360204200520063602002004280200210a0b2004200a41016a360200200b200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b024002402005280200220c2004280200220a6b2008490d00200d280204210c0c010b200a20086a220b200a490d13200c410174220a200b200b200a491b220a4100480d1302400240200c0d00200a1029210c0c010b200d280204200c200a102a210c0b200c450d03200d200c3602042005200a3602002004280200210a0b2004200a20086a360200200c200a6a2013200810f6041a02402011450d002013102e0b2009210a2009200f470d010c070b0b20064101102c000b200a4101102c000b200b4101102c000b200d4101102c000b02402009200f460d0003402009280200220c450d01200941146a280200210a200941106a280200210b200928020c210d02402009280204450d00200c102e0b0240200a450d00200a410474210c200d210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b200941186a21090240200b450d00200d102e0b2009200f470d000b0b2008411074210a02402017450d00200e102e0b2011200a72210a02402003280228450d002003280224102e0b2000200a3b0001200020053a0000200041036a200a4110763a0000200041086a2014370000200041046a2006360000410021024101210d4101210c4101210b410121044101210541012106410121070c160b2009200f460d0003402009280200220c450d01200941146a280200210a200941106a280200210b200928020c210d02402009280204450d00200c102e0b0240200a450d00200a410474210c200d210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b200941186a21090240200b450d00200d102e0b2009200f470d000b0b02402017450d00200e102e0b20032802282108200328022421022003280220220441086a210b200441046a2105200328022c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d0e200a4101742206200d200d2006491b22064100480d0e02400240200a0d0020061029210d0c010b2004280200200a2006102a210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d0d200c410174220a200d200d200a491b220a4100480d0d02400240200c0d00200a1029210c0c010b2004280200200c200a102a210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710f6041a02402008450d002002102e0b41002102410121074101210c4101210d4101210b4101210841012109410121044101210541012113410121060c220b20064101102c000b200a4101102c000b2001410c6a2802002105200141086a2802002113200141046a28020021090240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d12200a410174220d200c200c200d491b220d4100480d1202400240200a0d00200d1029210c0c010b2002280200200a200d102a210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41093a0000200341dc006a4100360200200342013702542003200236025020092005411c6c6a21024100210a4100210c2005210d034002400240200a200c460d002003280254210a0c010b200a41016a220b200a490d13200a4101742204200b200b2004491b220b4100480d1302400240200a0d00200b1029210a0c010b2003280254200a200b102a210a0b200a450d032003200b3602582003200a3602540b2003200c41016a36025c200a200c6a200d41807f72200d41ff0071200d410776220d1b3a00000240200d450d002003280258210a200328025c210c200d210d0c010b0b200921062005450d062009210a0340200a411c6a2106200a2802042205450d07200a41186a2802002104200a41146a2802002108200a41086a2902002114200a2802102107200a280200210c0340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d14200a410174220b200d200d200b491b220b4100480d1402400240200a0d00200b1029210d0c010b2003280254200a200b102a210d0b200d450d052003200b3602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b2003201437024420032005360240200341086a200341c0006a200341d0006a108204024020032d0008220d411a470d00200720044102746a21052004210c0340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d15200a410174220b200d200d200b491b220b4100480d1502400240200a0d00200b1029210d0c010b2003280254200a200b102a210d0b200d450d072003200b3602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02402004450d002007210403402004280200210c0340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d17200a410174220b200d200d200b491b220b4100480d1702400240200a0d00200b1029210d0c010b2003280254200a200b102a210d0b200d450d0a2003200b3602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b200441046a22042005470d000b0b02402008450d002007102e0b2006210a20062002470d010c090b0b20032d000b211220032f0009211020032903102114200328020c21112008450d052007102e0c050b200d4101102c000b200b4101102c000b200b4101102c000b200b4101102c000b200b4101102c000b024020062002460d0003402006280204220b450d01200641146a2802002104200641086a28020021052006280210210702402006410c6a280200220a450d00200a410474210c200b210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b02402005450d00200b102e0b2006411c6a210602402004450d002007102e0b20062002470d000b0b2012411074210a02402013450d002009102e0b2010200a72210a02402003280258450d002003280254102e0b2000200a3b00012000200d3a0000200041036a200a4110763a0000200041086a2014370000200041046a2011360000410021074101210d4101210c4101210b4101210441012105410121060c140b20062002460d0003402006280204220d450d01200641146a280200210b200641086a28020021042006280210210502402006410c6a280200220a450d00200a410474210c200d210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b02402004450d00200d102e0b2006411c6a21060240200b450d002005102e0b20062002470d000b0b02402013450d002009102e0b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d0d200a4101742206200d200d2006491b22064100480d0d02400240200a0d0020061029210d0c010b2004280200200a2006102a210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d0c200c410174220a200d200d200a491b220a4100480d0c02400240200c0d00200a1029210c0c010b2004280200200c200a102a210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710f6041a02402008450d002002102e0b41002106410121074101210c4101210d4101210b41012108410121094101210441012105410121130c200b20064101102c000b200a4101102c000b200141046a280200210a0240024002400240024002400240200241046a280200200241086a280200220c460d002002280200210d0c010b200c41016a220d200c490d0e200c410174220b200d200d200b491b220b4100480d0e02400240200c0d00200b1029210d0c010b2002280200200c200b102a210d0b200d450d012002200d360200200241046a200b360200200241086a280200210c0b200241086a200c41016a360200200d200c6a41083a0000410121064100210b4100210c03400240200c200b470d00200b410174220d200b41016a22042004200d491b220d4100480d0f02400240200b0d00200d102921060c010b2006200b200d102a21060b2006450d05200d210b0b2006200c6a200a41807f72200a41ff0071200a410776220d1b3a0000200c41016a210c200d210a200d0d000b200c417f6a2109200241086a2105200241046a2107200c210d03400240024020072802002005280200220a460d00200228020021040c010b200a41016a2204200a490d0f200a4101742208200420042008491b22084100480d0f02400240200a0d002008102921040c010b2002280200200a2008102a21040b2004450d0320022004360200200720083602002005280200210a0b2005200a41016a3602002004200a6a200d41807f72200d41ff0071200d410776220a1b3a0000200a210d200a0d000b02400240200241046a280200220d200241086a280200220a6b20094d0d002002280200210d0c010b200a200c6a2204200a490d0e200d410174220a20042004200a491b220a4100480d0e02400240200d0d00200a1029210d0c010b2002280200200d200a102a210d0b200d450d032002200d360200200241046a200a360200200241086a280200210a0b200241086a200a200c6a360200200d200a6a2006200c10f6041a41012107200b450d042006102e0c040b200b4101102c000b20084101102c000b200a4101102c000b200d4101102c000b4101210c4101210d0c160b2001410c6a2802002109200141086a2802002113200141046a280200210802400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d0e200a410174220d200c200c200d491b220d4100480d0e02400240200a0d00200d1029210c0c010b2002280200200a200d102a210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41073a0000200341dc006a410036020020034201370254200320023602502008200941146c6a2107410121044100210d4100210a2009210c03400240200a200d470d00200d41016a220b200d490d0f200d4101742205200b200b2005491b220b4100480d0f02400240200d0d00200b102921040c010b2004200d200b102a21040b2004450d032003200b36025820032004360254200b210d0b2003200a41016a220536025c2004200a6a200c41807f72200c41ff0071200c410776220b1b3a00002005210a200b210c200b0d000b200821062009450d042008210a0340200a41146a2106200a28020c22054104460d05200a41106a280200210c200a29020021142003200a28020836024820032014370340200341086a200341c0006a200341d0006a10900420032d0008220a411a470d04024002402003280258220d200328025c220b460d00200328025421040c010b200b41016a220a200b490d0f200b410174220d200a200a200d491b220d4100480d0f02400240200b0d00200d102921040c010b2003280254200b200d102a21040b2004450d042003200d360258200320043602540b2003200b41016a220a36025c2004200b6a20053a0000024003400240200a200d470d00200d41016a220b200d490d11200d4101742205200b200b2005491b220b4100480d1102400240200d0d00200b102921040c010b2004200d200b102a21040b2004450d02200b210d0b2004200a6a200c41807f72200c41ff0071200c410776220b1b3a0000200a41016a210a200b210c200b0d000b2003200d3602582003200a36025c200320043602542006210a20062007470d010c070b0b200b4101102c000b200d4101102c000b200b4101102c000b200d4101102c000b20032d000b210c20032f0009210d20032903102114200328020c210b024020062007460d0003402006410c6a2802004104460d010240200641046a280200450d002006280200102e0b200641146a22062007470d000b0b200c411074210c02402013450d002008102e0b200d200c72210c02402003280258450d002003280254102e0b2000200c3b00012000200a3a0000200041036a200c4110763a0000200041086a2014370000200041046a200b360000410021064101210d4101210c4101210b41012104410121050c110b20062007460d0003402006410c6a2802004104460d010240200641046a280200450d002006280200102e0b200641146a22062007470d000b0b02402013450d002008102e0b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d0b200a4101742206200d200d2006491b22064100480d0b02400240200a0d0020061029210d0c010b2004280200200a2006102a210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d0a200c410174220a200d200d200a491b220a4100480d0a02400240200c0d00200a1029210c0c010b2004280200200c200a102a210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710f6041a02402008450d002002102e0b41002113410121074101210c4101210d4101210b410121084101210941012104410121050c1d0b20064101102c000b200a4101102c000b2001410c6a2802002109200141086a2802002113200141046a2802002108024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d0e200a410174220d200c200c200d491b220d4100480d0e02400240200a0d00200d1029210c0c010b2002280200200a200d102a210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41063a0000200341dc006a41003602002003420137025420032002360250200820094104746a21054100210a4100210c2009210d034002400240200a200c460d002003280254210a0c010b200a41016a220b200a490d0f200a4101742204200b200b2004491b220b4100480d0f02400240200a0d00200b1029210a0c010b2003280254200a200b102a210a0b200a450d032003200b3602582003200a3602540b2003200c41016a36025c200a200c6a200d41807f72200d41ff0071200d410776220d1b3a00000240200d450d002003280258210a200328025c210c200d210d0c010b0b2008210d2009450d054100210d0340200341086a41086a220a2008200d6a220c41086a2802003602002003200c2902003703080240200c410d6a2d000022044102470d00200c41106a210d0c070b200341306a41086a200a280200220a360200200320032903082214370330200c410c6a2d00002106200341206a41086a2207200a36020020032014370320024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d0f200a4101742202200b200b2002491b22024100480d0f02400240200a0d0020021029210b0c010b2003280254200a2002102a210b0b200b450d04200320023602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a41fdf9ff77200641037441187141107376413f7141c000723a0000024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d0f200a4101742206200b200b2006491b22064100480d0f02400240200a0d0020061029210b0c010b2003280254200a2006102a210b0b200b450d05200320063602582003200b360254200328025c210a0b2003200a41016a36025c200b200a6a20044100473a0000200341c0006a41086a200728020036020020032003290320370340200341086a200341c0006a200341d0006a10820420032d0008220b411a470d05200d41106a210d200c41106a2005470d000c070b0b200d4101102c000b200b4101102c000b20024101102c000b20064101102c000b20032d000b210720032f00092102200328020c2111200329031021140240200941047441706a200d460d00200c41106a210d0340200d410d6a2d00004102460d01200d2802042106200d28020021040240200d280208220a450d00200a410474210c2004210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b200d41106a210d02402006450d002004102e0b200d2005470d000b0b2007411074210a02402013450d002008102e0b2002200a72210a02402003280258450d002003280254102e0b2000200a3b00012000200b3a0000200041036a200a4110763a0000200041086a2014370000200041046a2011360000410021054101210d4101210c4101210b410121040c0f0b200d2005460d000340200d410d6a2d00004102460d01200d2802042104200d280200210b0240200d280208220a450d00200a410474210c200b210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b200d41106a210d02402004450d00200b102e0b200d2005470d000b0b02402013450d002008102e0b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d0a200a4101742206200d200d2006491b22064100480d0a02400240200a0d0020061029210d0c010b2004280200200a2006102a210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d09200c410174220a200d200d200a491b220a4100480d0902400240200c0d00200a1029210c0c010b2004280200200c200a102a210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710f6041a02402008450d002002102e0b41002105410121074101210c4101210d4101210b4101210841012109410121040c1b0b20064101102c000b200a4101102c000b2001410c6a2802002107200141086a2802002108200141046a280200210602400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d09200a410174220d200c200c200d491b220d4100480d0902400240200a0d00200d1029210c0c010b2002280200200a200d102a210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41053a0000200341d0006a410c6a4100360200200342013702542003200236025020062007410c6c6a2102410121044100210d4100210a2007210c03400240200a200d470d00200d41016a220b200d490d0a200d4101742205200b200b2005491b220b4100480d0a02400240200d0d00200b102921040c010b2004200d200b102a21040b2004450d032003200b36025820032004360254200b210d0b2003200a41016a220536025c2004200a6a200c41807f72200c41ff0071200c410776220b1b3a00002005210a200b210c200b0d000b2006210a2007450d022007410c6c210b4100210c034002402006200c6a220a41046a280200220d4102470d00200a410c6a210a0c040b200341086a200a280200200d200a41086a280200200341d0006a108e04024020032d00082204411a460d0020032f000920032d000b41107472210520032903102114200328020c2107200a410c6a210d200b200c6b41746a210a02400340200a450d01200a41746a210a200d280204210c200d410c6a210d200c4102470d000b0b02402008450d002006102e0b02402003280258450d002003280254102e0b200020053b0001200020043a0000200041036a20054110763a0000200041086a2014370000200041046a2007360000410021044101210d4101210c4101210b0c100b200b200c410c6a220c470d000b2002210a0c020b200d4101102c000b200b4101102c000b200a410020076b410c6c6a210c024003402006200c460d01200c410c6a210c200a280204210d200a410c6a210a200d4102470d000b0b02402008450d002006102e0b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d09200a4101742206200d200d2006491b22064100480d0902400240200a0d0020061029210d0c010b2004280200200a2006102a210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d08200c410174220a200d200d200a491b220a4100480d0802400240200c0d00200a1029210c0c010b2004280200200c200a102a210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710f6041a02402008450d002002102e0b41002104410121074101210c4101210d4101210b41012108410121090c190b20064101102c000b200a4101102c000b2001410c6a2802002109200141086a2802002113200141046a2802002106024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d09200a410174220d200c200c200d491b220d4100480d0902400240200a0d00200d1029210c0c010b2002280200200a200d102a210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41043a0000200341d0006a410c6a4100360200200342013702542003200236025020062009410c6c6a2111410121044100210d4100210a2009210c03400240200a200d470d00200d41016a220b200d490d0a200d4101742205200b200b2005491b220b4100480d0a02400240200d0d00200b102921040c010b2004200d200b102a21040b2004450d032003200b36025820032004360254200b210d0b2003200a41016a220536025c2004200a6a200c41807f72200c41ff0071200c410776220b1b3a00002005210a200b210c200b0d000b2006210a2009450d032009410c6c21084100210d034002402006200d6a220c41046a28020022044102470d00200c410c6a210a0c050b200c2802002105200c41086a2802002107024002402003280258200328025c220a460d002003280254210b0c010b200a41016a220b200a490d0a200a4101742202200b200b2002491b22024100480d0a02400240200a0d0020021029210b0c010b2003280254200a2002102a210b0b200b450d04200320023602582003200b3602540b2003200a41016a36025c200b200a6a41f0003a0000200341086a200520042007200341d0006a108e04024020032d0008220b411a460d0020032f000920032d000b41107472210420032903102114200328020c2105200c410c6a210c2008200d6b41746a210a02400340200a450d01200a41746a210a200c280204210d200c410c6a210c200d4102470d000b0b02402013450d002006102e0b02402003280258450d002003280254102e0b200020043b00012000200b3a0000200041036a20044110763a0000200041086a2014370000200041046a20053600004100210b4101210d4101210c0c0f0b2008200d410c6a220d470d000b2011210a0c030b200d4101102c000b200b4101102c000b20024101102c000b200a410020096b410c6c6a210c024003402006200c460d01200c410c6a210c200a280204210d200a410c6a210a200d4102470d000b0b02402013450d002006102e0b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d08200a4101742206200d200d2006491b22064100480d0802400240200a0d0020061029210d0c010b2004280200200a2006102a210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d07200c410174220a200d200d200a491b220a4100480d0702400240200c0d00200a1029210c0c010b2004280200200c200a102a210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710f6041a02402008450d002002102e0b41002109410121074101210c4101210d4101210b410121080c170b20064101102c000b200a4101102c000b2001410c6a2802002106200141086a2802002109200141046a280200210802400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d0a200a410174220d200c200c200d491b220d4100480d0a02400240200a0d00200d1029210c0c010b2002280200200a200d102a210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41033a0000200820064102746a21074100210d4100210a41002105410121042006210c03400240200a2005470d00200d200a41016a220b200b200d491b22054100480d0b02400240200d0d002005102921040c010b2004200a2005102a21040b2004450d050b2004200a6a200c41807f72200c41ff0071200c410776220b1b3a0000200d41026a210d200a41016a210a200b210c200b0d000b02402006450d00200821060340200a410174210d2006280200210c03400240200a2005470d00200a41016a220b200a490d0d200d200b200b200d491b22054100480d0d02400240200a0d002005102921040c010b2004200a2005102a21040b2004450d080b2004200a6a200c41807f72200c41ff0071200c410776220b1b3a0000200d41026a210d200a41016a210a200b210c200b0d000b200641046a22062007470d000b0b02402009450d002008102e0b200241086a2106200241046a2107200a210d03400240024020072802002006280200220c460d002002280200210b0c010b200c41016a220b200c490d0b200c4101742208200b200b2008491b22084100480d0b02400240200c0d0020081029210b0c010b2002280200200c2008102a210b0b200b450d032002200b360200200720083602002006280200210c0b2006200c41016a360200200b200c6a200d41807f72200d41ff0071200d410776220c1b3a0000200c210d200c0d000b02400240200241046a280200220d200241086a280200220c6b200a490d002002280200210d0c010b200c200a6a220b200c490d0a200d410174220c200b200b200c491b220c4100480d0a02400240200d0d00200c1029210d0c010b2002280200200d200c102a210d0b200d450d032002200d360200200241046a200c360200200241086a280200210c0b200241086a200c200a6a360200200d200c6a2004200a10f6041a41002108410121072005450d052004102e0c050b200d4101102c000b20084101102c000b200c4101102c000b20054101102c000b20054101102c000b4101210c4101210d4101210b0c130b2001410c6a2802002106200141086a2802002111200141046a28020021130240024002400240024002400240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d11200a410174220d200c200c200d491b220d4100480d1102400240200a0d00200d1029210c0c010b2002280200200a200d102a210c0b200c450d012002200c360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200c200a6a41023a0000200341dc006a410036020020034201370254200320023602502013200641286c6a21054100210a4100210c2006210d034002400240200a200c460d002003280254210a0c010b200a41016a220b200a490d12200a4101742204200b200b2004491b220b4100480d1202400240200a0d00200b1029210a0c010b2003280254200a200b102a210a0b200a450d032003200b3602582003200a3602540b2003200c41016a36025c200a200c6a200d41807f72200d41ff0071200d410776220d1b3a00000240200d450d002003280258210a200328025c210c200d210d0c010b0b2013210b2006450d0c2013210b0340200341086a41086a220d200b220a41086a2802003602002003200a290200370308200a41286a210b200a2d001822074104460d0d200a411b6a2d00002108200a41196a2f00002109200a41206a2900002114200a411c6a280000210c200a41146a2802002102200a41106a2802002104200a28020c2106200341206a41086a200d280200220a360200200320032903082218370320200341c0006a41086a200a36020020032018370340200341086a200341c0006a200341d0006a109004024020032d0008220a411a460d0020032f000920032d000b41107472210720032903102114200328020c21022004450d0d2006102e0c0d0b200320023602482003200436024420032006360240200341086a200341c0006a200341d0006a109004024020032d0008220a411a460d0020032f000920032d000b411074722107200328020c2102200329031021140c0d0b2014422088a7210a2014a7210d0240024002400240024020070e0400010203000b024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d16200a4101742204200d200d2004491b22044100480d1602400240200a0d0020041029210d0c010b2003280254200a2004102a210d0b200d450d08200320043602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a41003a00000340024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d17200a4101742204200d200d2004491b22044100480d1702400240200a0d0020041029210d0c010b2003280254200a2004102a210d0b200d450d0a200320043602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000c040b0b024002402003280258200328025c2204460d00200328025421060c010b200441016a22062004490d1520044101742207200620062007491b22074100480d150240024020040d002007102921060c010b200328025420042007102a21060b2006450d092003200736025820032006360254200328025c21040b2003200441016a36025c200620046a41013a0000024002402003280258200328025c2204460d00200328025421060c010b200441016a22062004490d1520044101742207200620062007491b22074100480d150240024020040d002007102921060c010b200328025420042007102a21060b2006450d0a2003200736025820032006360254200328025c21040b2003200441016a36025c200620046a41f0003a0000200341086a200c200d200a200341d0006a108e0420032d0008220a411a460d0220032f000920032d000b4110747221070c0e0b024002402003280258200328025c2204460d00200328025421060c010b200441016a22062004490d1420044101742207200620062007491b22074100480d140240024020040d002007102921060c010b200328025420042007102a21060b2006450d0a2003200736025820032006360254200328025c21040b2003200441016a36025c200620046a41023a0000200341086a200c200d200a200341d0006a108e0420032d0008220a411a460d0120032f000920032d000b4110747221070c0d0b024002402003280258200328025c220a460d002003280254210c0c010b200a41016a220c200a490d13200a410174220d200c200c200d491b220d4100480d1302400240200a0d00200d1029210c0c010b2003280254200a200d102a210c0b200c450d0a2003200d3602582003200c360254200328025c210a0b2003200a41016a36025c200c200a6a41033a0000024002402003280258200328025c220a460d002003280254210c0c010b200a41016a220c200a490d13200a410174220d200c200c200d491b220d4100480d1302400240200a0d00200d1029210c0c010b2003280254200a200d102a210c0b200c450d0b2003200d3602582003200c360254200328025c210a0b2003200a41016a36025c200c200a6a2009200841107472220c417f73220a413f7141c00072200a200c411874411875417f4a1b3a0000024002402003280258200328025c220a460d002003280254210d0c010b200a41016a220d200a490d13200a4101742204200d200d2004491b22044100480d1302400240200a0d0020041029210d0c010b2003280254200a2004102a210d0b200d450d0c200320043602582003200d360254200328025c210a0b2003200a41016a36025c200d200a6a200c4180fe03714100473a00000b200b2005470d000c0e0b0b200d4101102c000b200b4101102c000b20044101102c000b20044101102c000b20074101102c000b20074101102c000b20074101102c000b200d4101102c000b200d4101102c000b20044101102c000b20032903102114200328020c21020b0240200b2005460d000340200b41186a2d00004104460d01200b41106a280200210c200b410c6a280200210d0240200b41046a280200450d00200b280200102e0b0240200c450d00200d102e0b200b41286a220b2005470d000b0b02402011450d002013102e0b02402003280258450d002003280254102e0b200020073b00012000200a3a0000200041036a20074110763a0000200041086a2014370000200041046a20023600004100210c4101210d0c080b200b2005460d000340200b41186a2d00004104460d01200b41106a280200210a200b410c6a280200210c0240200b41046a280200450d00200b280200102e0b0240200a450d00200c102e0b200b41286a220b2005470d000b0b02402011450d002013102e0b20032802582108200328025421022003280250220441086a210b200441046a2105200328025c2207210c024002400340024002402005280200200b280200220a460d002004280200210d0c010b200a41016a220d200a490d06200a4101742206200d200d2006491b22064100480d0602400240200a0d0020061029210d0c010b2004280200200a2006102a210d0b200d450d022004200d36020020052006360200200b280200210a0b200b200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200441046a280200220c200441086a280200220a6b2007490d002004280200210c0c010b200a20076a220d200a490d05200c410174220a200d200d200a491b220a4100480d0502400240200c0d00200a1029210c0c010b2004280200200c200a102a210c0b200c450d022004200c360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200c200a6a2002200710f6041a02402008450d002002102e0b4100210b410121074101210c4101210d0c130b20064101102c000b200a4101102c000b20082010460d0003402008410d6a2d00004105460d010240200841046a280200450d002008280200102e0b200841106a22082010470d000b0b0240200e450d00200f102e0b200241086a2106200241046a2107200c210d0240024003400240024020072802002006280200220a460d002002280200210b0c010b200a41016a220b200a490d04200a4101742208200b200b2008491b22084100480d0402400240200a0d0020081029210b0c010b2002280200200a2008102a210b0b200b450d022002200b360200200720083602002006280200210a0b2006200a41016a360200200b200a6a200d41807f72200d41ff0071200d410776220a1b3a0000200a210d200a0d000b02400240200241046a280200220d200241086a280200220a6b200c490d002002280200210d0c010b200a200c6a220b200a490d03200d410174220a200b200b200a491b220a4100480d0302400240200d0d00200a1029210d0c010b2002280200200d200a102a210d0b200d450d022002200d360200200241046a200a360200200241086a280200210a0b200241086a200a200c6a360200200d200a6a2004200c10f6041a4100210d410121072005450d032004102e0c030b20084101102c000b200a4101102c000b102d000b4101210c0c0c0b2000200c3b00012000200a3a0000200041036a200c4110763a0000200041086a2014370000200041046a2004360000410021134101210d4101210c4101210b410121044101210541012106410121074101210241012108410121090c090b4101210c200241086a200a41016a3602004100210d200b200a6a41003a00002003411c6a2004360200200341186a200536020020032006360214200320073602102003200836020c20032009360208200341d0006a200341086a2002109504200320032900513703402003200341d0006a41086a29000037004720032d0050220a411a460d092000200a3a000020002003290340370001200041086a20032900473700000b4101210b0b410121040b410121050b410121060b410121070b410121020b410121080b41012109410121130b20012d0000220a410e4b0d18200a0e0f0a0b0c0d0e0f1011121813141516170a0b4101210c410021074101210d0b4101210b0b410121080b410121090b410121040b410121050b410121130b410121060b410121020b41012111410121120c0f0b200141086a280200450d10200141046a280200102e0c100b200d450d0f0240200141086a280200450d00200141046a280200102e0b200141146a280200450d0f200141106a280200102e0c0f0b02402001410c6a280200220c450d00200141046a280200210a200c410474210c03400240200a41046a280200450d00200a280200102e0b200a41106a210a200c41706a220c0d000b0b200141086a280200450d0e2001280204102e0c0e0b200c450d0d02402001410c6a280200220c450d00200141046a280200210a200c41286c210c03400240200a41046a280200450d00200a280200102e0b0240200a41106a280200450d00200a410c6a280200102e0b200a41286a210a200c41586a220c0d000b0b200141086a280200450d0d2001280204102e0c0d0b200141086a280200450d0c200141046a280200102e0c0c0b200b450d0b200141086a280200450d0b200141046a280200102e0c0b0b2004450d0a200141086a280200450d0a200141046a280200102e0c0a0b2005450d0902402001410c6a280200220a450d00200141046a280200220d200a4104746a210b03400240200d280208220c450d00200d280200210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b200d41106a210a0240200d41046a280200450d00200d280200102e0b200a210d200a200b470d000b0b200141086a280200450d092001280204102e0c090b2006450d0802402001410c6a280200220c450d00200141046a280200210a200c41146c210c03400240200a41046a280200450d00200a280200102e0b200a41146a210a200c416c6a220c0d000b0b200141086a280200450d082001280204102e0c080b2007450d0702402001410c6a280200220a450d00200141046a280200220d200a411c6c6a210b03400240200d410c6a280200220c450d00200d280204210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b0240200d41086a280200450d00200d280204102e0b200d411c6a210a0240200d41146a280200450d00200d280210102e0b200a210d200a200b470d000b0b200141086a280200450d072001280204102e0c070b2002450d0602402001410c6a280200220a450d00200141046a280200220d200a41186c6a210b03400240200d41046a280200450d00200d280200102e0b0240200d41146a280200220c450d00200d28020c210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b200d41186a210a0240200d41106a280200450d00200d28020c102e0b200a210d200a200b470d000b0b200141086a280200450d062001280204102e0c060b2008450d0502402001410c6a280200220a450d00200141046a280200220d200a411c6c6a210b03400240200d410c6a280200220c450d00200d280204210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b0240200d41086a280200450d00200d280204102e0b200d411c6a210a0240200d41146a280200450d00200d280210102e0b200a210d200a200b470d000b0b200141086a280200450d052001280204102e0c050b2009450d040240200141046a2d0000220a41024b0d00024002400240200a0e03000102000b2001410c6a280200450d07200141086a280200102e0c070b0240200141146a280200220c450d002001410c6a280200210a200c410c6c210c03400240200a280200220d450d00200a41046a280200450d00200d102e0b200a410c6a210a200c41746a220c0d000b0b200141106a280200450d06200128020c102e0c060b0240200141146a280200220a450d002001410c6a2802002204200a4104746a210503402004220b41106a21040240200b280204220a450d000240200b410c6a280200220c450d00200c410c6c210c03400240200a280200220d450d00200a41046a280200450d00200d102e0b200a410c6a210a200c41746a220c0d000b0b200b41086a280200450d00200b280204102e0b20042005470d000b0b200141106a280200450d05200128020c102e0c050b2001410c6a280200450d04200141086a280200102e0c040b2013450d030240200141086a280200450d00200141046a280200102e0b0240200141146a280200220a450d00200141186a280200450d00200a102e0b200141246a280200450d03200141206a280200102e0c030b200110bf030c020b410121100b2000411a3a0000024020012d0000220a410e4b0d0002400240024002400240024002400240024002400240024002400240200a0e0f0001020304050607080e090a0b0c0d000b200c450d0e200141086a280200450d0e200141046a280200102e0c0e0b2007450d0d0240200141086a280200450d00200141046a280200102e0b200141146a280200450d0d200141106a280200102e0c0d0b200d450d0c02402001410c6a280200220c450d00200141046a280200210a200c410474210c03400240200a41046a280200450d00200a280200102e0b200a41106a210a200c41706a220c0d000b0b200141086a280200450d0c2001280204102e0c0c0b200b450d0b02402001410c6a280200220c450d00200141046a280200210a200c41286c210c03400240200a41046a280200450d00200a280200102e0b0240200a41106a280200450d00200a410c6a280200102e0b200a41286a210a200c41586a220c0d000b0b200141086a280200450d0b2001280204102e0c0b0b2008450d0a200141086a280200450d0a200141046a280200102e0c0a0b2009450d09200141086a280200450d09200141046a280200102e0c090b2004450d08200141086a280200450d08200141046a280200102e0c080b2005450d0702402001410c6a280200220a450d00200141046a280200220d200a4104746a210b03400240200d280208220c450d00200d280200210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b200d41106a210a0240200d41046a280200450d00200d280200102e0b200a210d200a200b470d000b0b200141086a280200450d072001280204102e0c070b2013450d0602402001410c6a280200220c450d00200141046a280200210a200c41146c210c03400240200a41046a280200450d00200a280200102e0b200a41146a210a200c416c6a220c0d000b0b200141086a280200450d062001280204102e0c060b2006450d0502402001410c6a280200220a450d00200141046a280200220d200a411c6c6a210b03400240200d410c6a280200220c450d00200d280204210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b0240200d41086a280200450d00200d280204102e0b200d411c6a210a0240200d41146a280200450d00200d280210102e0b200a210d200a200b470d000b0b200141086a280200450d052001280204102e0c050b2002450d0402402001410c6a280200220a450d00200141046a280200220d200a41186c6a210b03400240200d41046a280200450d00200d280200102e0b0240200d41146a280200220c450d00200d28020c210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b200d41186a210a0240200d41106a280200450d00200d28020c102e0b200a210d200a200b470d000b0b200141086a280200450d042001280204102e0c040b2011450d0302402001410c6a280200220a450d00200141046a280200220d200a411c6c6a210b03400240200d410c6a280200220c450d00200d280204210a200c410474210c03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a280200102e0b200a41106a210a200c41706a220c0d000b0b0240200d41086a280200450d00200d280204102e0b200d411c6a210a0240200d41146a280200450d00200d280210102e0b200a210d200a200b470d000b0b200141086a280200450d032001280204102e0c030b2012450d020240200141046a2d0000220a41024b0d00024002400240200a0e03000102000b2001410c6a280200450d05200141086a280200102e0c050b0240200141146a280200220c450d002001410c6a280200210a200c410c6c210c03400240200a280200220d450d00200a41046a280200450d00200d102e0b200a410c6a210a200c41746a220c0d000b0b200141106a280200450d04200128020c102e0c040b0240200141146a280200220a450d002001410c6a2802002204200a4104746a210503402004220b41106a21040240200b280204220a450d000240200b410c6a280200220c450d00200c410c6c210c03400240200a280200220d450d00200a41046a280200450d00200d102e0b200a410c6a210a200c41746a220c0d000b0b200b41086a280200450d00200b280204102e0b20042005470d000b0b200141106a280200450d03200128020c102e0c030b2001410c6a280200450d02200141086a280200102e0c020b2010450d010240200141086a280200450d00200141046a280200102e0b0240200141146a280200220a450d00200141186a280200450d00200a102e0b200141246a280200450d01200141206a280200102e0c010b200110bf030b200341e0006a24000ba62207017f027e077f017e017f017e107f230041d0066b22032400200241d8006a2903002104200241d0006a290300210520022802002106200341c4006a200241046a41cc0010f6041a20034190016a200341c4006a41046a41c80010f6041a2001280200210720034190036a41186a2208200341c8016a29030037030020034190036a41106a2209200341c0016a29030037030020034190036a41086a220a200341b8016a290300370300200320032903b00137039003024002400240024041c80010292202450d002002420037030020022006360220200241186a4200370300200241106a4200370300200241086a42003703002002200341b0016a220b2902003702242002412c6a200b41086a290200370200200241346a200b41106a2902003702002002413c6a200b41186a290200370200200341286a41c28cc00041161070200341186a2003290330200341286a41106a290300427f420010fc04200341086a20052004200329031842002003280228220c1b220d4201200d420156200341186a41086a2903004200200c1b220d420052200d501b220c1b200d4200200c1b10fc04200341e0026a41086a200a290300370300200341e0026a41106a2009290300370300200341e0026a41186a200829030037030020032003290390033703e0022003290308210d0240024002400240200741046a28020020072802082208460d00200728020021090c010b200841016a22092008490d012008410174220a20092009200a491b220aad42d0007e2204422088a70d012004a7220c4100480d010240024020080d00200c102921090c010b2007280200200841d0006c200c102a21090b2009450d0220072009360200200741046a200a360200200728020821080b2009200841d0006c6a22084200370310200842003703082008200d37030020082002360220200820032903e00237022c200841186a4200370300200841246a428180808010370200200841346a200341e0026a41086a22022903003702002008413c6a200341e0026a41106a220a290300370200200841c4006a200341e0026a41186a22082903003702002007200728020841016a3602082001280208210c200341a0026a41186a200b41186a290000370300200341a0026a41106a200b41106a290000370300200341a0026a41086a200b41086a2900003703002003200b2900003703a002024002400240200c280200220141e08dc000460d00200c28020421090c010b4100210920034190036a410041e00210f5041a20034188036a220b410036020020034180036a2207420037030020084200370300200a420037030020024200370300200342003703e00241940310292201450d01200141003b010620014100360200200141086a20034190036a41e00210f6041a20014190036a200b28020036020020014188036a200729030037020020014180036a200341f8026a290300370200200141f8026a200341f0026a290300370200200141f0026a200341e0026a41086a290300370200200120032903e0023702e802200c4100360204200c20013602000b02400340200141086a2108200141066a210e20012f0106220a41057421024100210b0240024003402002450d01200341a0026a2008412010f8042207450d02200241606a2102200b41016a210b200841206a21082007417f4a0d000b200b417f6a210a0b2009450d022009417f6a21092001200a4102746a4194036a28020021010c010b0b2001200b4102746a41e8026a20063602000c060b200341d8016a41186a200341a0026a41186a2202290300220d370300200341d8016a41106a200341a0026a41106a22082903002204370300200341d8016a41086a200341a0026a41086a220b2903002205370300200320032903a002220f3703d801200c200c28020841016a3602082002200d37030020082004370300200b20053703002003200f3703a0020240024002400240200e2f01002209410b490d0020034190036a410041e00210f5041a20034188036a2202410036020020034180036a22084200370300200341e0026a41186a4200370300200341e0026a41106a4200370300200341e0026a41086a4200370300200342003703e00241940310292210450d03201041003b010620104100360200201041086a20034190036a41e00210f604210b20104190036a200228020036020020104188036a200829030037020020104180036a200341e0026a41186a290300370200201041f8026a200341e0026a41106a290300370200201041f0026a200341e0026a41086a290300370200201020032903e0023702e802200320012f00c8013b01dc022003200141ca016a2d00003a00de02200141cb016a2800002111200141cf016a2800002112200141d3016a2800002113200141d7016a28000021142003200141e0016a2900003700cd02200320012900db013703c8022001280280032115200b200141e8016a20012f010641796a220241057410f604210b201041e8026a20014184036a200241027410f6042107200141063b0106201020023b0106200320032f01dc023b01c402200320032d00de023a00c602200320032903c8023703e002200320032900cd023700e502200a4107490d01201041066a210e200b200a417a6a22094105746a200b200a41796a22084105746a220b200241ffff037120086b41057410f7041a200b41186a200341a0026a41186a290300370000200b41106a200341a0026a41106a290300370000200b41086a200341a0026a41086a290300370000200b20032903a002370000200720094102746a210b200720084102746a21020c020b200141086a2207200a41016a220c4105746a2007200a4105746a22072009200a6b41057410f7041a200741186a2002290300370000200741106a2008290300370000200741086a200b290300370000200720032903a002370000200141e8026a2202200c4102746a2002200a4102746a220220012f0106200a6b41027410f7041a20022006360200200120012f010641016a3b01060c080b200141086a2202200a41016a22084105746a2002200a4105746a2202200e2f0100200a6b41057410f7041a200241186a200341a0026a41186a290300370000200241106a200341a0026a41106a290300370000200241086a200341a0026a41086a290300370000200220032903a002370000200141e8026a220b200a4102746a2102200b20084102746a210b200a21080b200b2002200e2f010020086b41027410f7041a20022006360200200e200e2f010041016a3b0100200341c0026a41026a221620032d00c60222023a00002003418c026a41026a221720023a0000200320032900e50237009502200320032903e00237039002200320032f01c40222023b01c00220032003290095023700fd0120032003290390023703f801200320023b018c0220012802002209450d0520012f0104210e20034190036a41027221180340201620172d00003a0000200320032f018c023b01c002200320032903f8013703a002200320032900fd013700a502200e41ffff037121010240024002400240024020092f01062202410b490d002018410041be0310f5041a41c40310292207450d0320074100360200200741046a20034190036a41c00310f6041a200320092f00c8013b01dc022003200941ca016a2d00003a00de022003200941db016a2900003703c8022003200941e0016a2900003700cd02200941cb016a2800002119200941cf016a280000211a200941d3016a280000211b200941d7016a280000211c20094180036a280200211d200741086a200941e8016a20092f0106220841796a220241057410f604211e200741e8026a20094184036a200241027410f604211f20074194036a200941b0036a2008417a6a220a41027410f6042106200941063b0106200720023b01060240200a450d00410021022006210803402008280200220b20023b0104200b2007360200200841046a2108200a200241016a2202470d000b0b200320032d00de0222023a00c602200320032f01dc0222083b01c402200320032903c8023703e002200320032900cd023700e50220034190026a41026a220a20023a0000200320083b019002200320032903e00237039003200320032900e50237009503200e41ffff037122084107490d01201e2001417a6a220b4105746a201e200141796a22024105746a220820072f010620026b41057410f7041a200841186a20032900a5023700002008201436000f2008201336000b2008201236000720082011360003200841026a20162d00003a0000200820032f01c0023b0000200820032903a002370013201f200b41027422086a201f20024102746a220e20072f0106221120026b41027410f7041a200e20153602002007201141016a220e3b01062001410274221120066a416c6a200620086a2208200e41ffff03712201200b6b41027410f7041a200820103602002001200b490d02200720116a41fc026a210803402008280200220b200241016a22023b0104200b2007360200200841046a210820022001490d000c030b0b200941086a2208200141016a220b4105746a200820014105746a2208200220016b41057410f7041a200841186a20032900a5023700002008201436000f2008201336000b2008201236000720082011360003200841026a200341c0026a41026a2d00003a0000200820032f01c0023b0000200820032903a002370013200941e8026a2202200b41027422086a2002200141027422076a220220092f0106220a20016b41027410f7041a200220153602002009200a41016a22023b0106200720094194036a22016a41086a200120086a2208200241ffff03712207200b6b41027410f7041a20082010360200200e41ffff037120074f0d0b2009200b417f6a22024102746a4198036a210803402008280200220b200241016a22023b0104200b2009360200200841046a210820022007490d000c0c0b0b200941086a2202200141016a220e4105746a200220014105746a220220092f010620016b41057410f7041a200241186a20032900a5023700002002201436000f2002201336000b2002201236000720022011360003200241026a20162d00003a0000200220032f01c0023b0000200220032903a002370013200941e8026a220b200e41027422066a200b200141027422026a220b20092f0106221120016b41027410f7041a200b20153602002009201141016a220b3b0106200220094194036a22116a41086a201120066a2206200b41ffff0371220b200e6b41027410f7041a200620103602002008200b4f0d00200920026a4198036a2102034020022802002208200141016a22013b010420082009360200200241046a2102200b2001470d000b0b2017200a2d00003a0000200320032f0190023b018c0220032003290390033703f80120032003290095033700fd01200928020022020d0120192111201c2114201b2113201a211220072110201d21150c080b41c4034104102c000b20092f0104210e20192111201c2114201b2113201a211220022109201d2115200721100c000b0b4194034104102c000b4194034104102c000b102d000b200c4108102c000b41c8004108102c000b20034190036a410272410041be0310f5041a41c40310292202450d0120024100360200200241046a20034190036a41c00310f6041a2002200c280200220836029403200c2002360200200c200c28020441016a360204200841003b010420082002360200200220022f0106220b4105746a220841086a20032f018c023b00002008410a6a2003418c026a41026a2d00003a0000200841176a2014360000200841136a20133600002008410f6a20123600002008410b6a20113600002008411b6a20032903f801370000200841206a20032900fd0137000020024194036a200b41016a22084102746a20103602002002200b4102746a41e8026a2015360200200220083b0106201020083b0104201020023602000b200020034190016a41c80010f6041a200341d0066a24000f0b41c4034104102c000b130020004105360204200041bcaac3003602000b3400200041e0a1c30036020420004100360200200041146a4107360200200041106a4188bdc300360200200041086a42083702000b3701017f02404110102922020d0041104101102c000b2002420037000820024201370000200042908080808002370204200020023602000bc70101017f23004190016b22022400200241003a00782002428080848080023703682002420137035820024201370350200242af0137034820024287013703402002420137033820024201370330200242013703282002420137032020024201370318200242013703102002420137030820024280808080c00037036020024280808180800437037020024100360288012002420137038001200241086a20024180016a10fe01200041086a200228028801360200200020022903800137020020024190016a24000b130020004110360204200041e4c6c3003602000b3301017f02404108102922020d0041084101102c000b2000428880808080013702042000200236020020024280ade2043700000b3201017f02404104102922020d0041044101102c000b20004284808080c000370204200020023602002002418080013600000b3101017f02404104102922020d0041044101102c000b20004284808080c0003702042000200236020020024180083600000b3101017f02404108102922020d0041084101102c000b20004288808080800137020420002002360200200242e8073700000b3c01017f02404110102922020d0041104101102c000b2002420037000820024280a094a58d1d370000200042908080808002370204200020023602000b3b01017f02404110102922020d0041104101102c000b2002420037000820024280c8afa025370000200042908080808002370204200020023602000b3801017f02404110102922020d0041104101102c000b200242003700082002429601370000200042908080808002370204200020023602000b3801017f02404110102922020d0041104101102c000b20024200370008200242e807370000200042908080808002370204200020023602000b3701017f02404110102922020d0041104101102c000b2002420037000820024204370000200042908080808002370204200020023602000b3001017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241083600000b3701017f02404110102922020d0041104101102c000b2002420037000820024210370000200042908080808002370204200020023602000b3001017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241023600000b860a02057f027e20002802102102200041186a2802002203200110470240024002400240024002400240024002400240200141046a2802002204200141086a28020022056b2003490d00200128020021040c010b200520036a22062005490d0820044101742205200620062005491b22054100480d080240024020040d002005102921040c010b200128020020042005102a21040b2004450d0120012004360200200141046a2005360200200141086a28020021050b200141086a2206200520036a360200200420056a2002200310f6041a200028021c210402400240200141046a2802002205200628020022036b4104490d00200128020021050c010b200341046a22022003490d0820054101742203200220022003491b22034100480d080240024020050d002003102921050c010b200128020020052003102a21050b2005450d0220012005360200200141046a2003360200200141086a28020021030b200141086a2202200341046a360200200520036a20043600002000412c6a20011046200041086a29030021072000290300210802400240200141046a2802002205200228020022036b4110490d00200128020021050c010b200341106a22042003490d0820054101742203200420042003491b22034100480d080240024020050d002003102921050c010b200128020020052003102a21050b2005450d0320012005360200200141046a2003360200200141086a28020021030b200141086a2204200341106a360200200520036a22032007370008200320083700002000280220210202400240200141046a2802002205200428020022036b4104490d00200128020021050c010b200341046a22042003490d0820054101742203200420042003491b22034100480d080240024020050d002003102921050c010b200128020020052003102a21050b2005450d0420012005360200200141046a2003360200200141086a28020021030b200141086a2204200341046a360200200520036a2002360000024020002802244101460d0002400240200141046a28020020042802002200460d00200128020021030c010b200041016a22032000490d0920004101742205200320032005491b22054100480d090240024020000d002005102921030c010b200128020020002005102a21030b2003450d0620012003360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200320006a41003a00000f0b02400240200141046a28020020042802002203460d00200128020021050c010b200341016a22052003490d0820034101742204200520052004491b22044100480d080240024020030d002004102921050c010b200128020020032004102a21050b2005450d0620012005360200200141046a2004360200200141086a28020021030b200141086a2204200341016a360200200520036a41013a00002000280228210502400240200141046a2802002203200428020022006b4104490d00200128020021030c010b200041046a22042000490d0820034101742200200420042000491b22004100480d080240024020030d002000102921030c010b200128020020032000102a21030b2003450d0720012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20053600000f0b20054101102c000b20034101102c000b20034101102c000b20034101102c000b20054101102c000b20044101102c000b20004101102c000b102d000bcd0101037f230041106b22022400200241003602082002420137030020002d00002103410110292104024002400240024020034101460d002004450d02200441003a0000200242818080801037020420022004360200200041086a200210d4030c010b2004450d02200441013a0000200242818080801037020420022004360200200041016a200210460b2002280204210420012802002001280204200228020022012002280208100402402004450d002001102e0b200241106a24000f0b41014101102c000b41014101102c000b8f0703037f047e067f23002202210320024180026b416071220224002001411c6a22042902002105200420022903b801370200200141146a22042902002106200420022903b0013702002001410c6a22042902002107200420022903a801370200200241003a00a00120012902042108200120022903a00137020420022005370358200220063703502002200737034820022008370340200141246a2d00002104200241a0016a41176a22092005370000200241a0016a41106a220a2002290051370300200241a0016a41086a220b2002290049370300200220022900413703a001024002402008a741ff01714101460d00200041003602200c010b200241106a41176a2009290000370000200241106a41106a200a290300370300200241106a41086a200b290300370300200220022903a001370310200220043a002f02400240411210292204450d00200441002900fee743370000200441106a41002f008ee8433b0000200441086a4100290086e84337000020024292808080a0023702a401200220043602a001200241106a200241a0016a104a20022802a401210a20022802a801210420022802a0012109200241a0016a41186a220b4200370300200241a0016a41106a220c4200370300200241a0016a41086a220d4200370300200242003703a00120092004200241a0016a1000200241c0006a41186a220e200b290300370300200241c0006a41106a220b200c290300370300200241c0006a41086a2204200d290300370300200220022903a001370340200241a0016a200241c0006a10ab0320022d00ac014102460d01200241c0006a200241a0016a41d00010f6041a200241306a41086a220c200428020036020020022002290340370330200241a0016a200241cc006a41c20010f6041a200141046a220141206a200241e1016a2d00003a0000200141186a200241d9016a290000370000200141106a200241d1016a290000370000200141086a200241c9016a290000370000200120022900c101370000200e200241106a41186a2903002205370300200b200241106a41106a29030022083703002004200241106a41086a2903002206370300200020022903102207370200200041086a2006370200200041106a2008370200200041186a200537020020022007370340200041206a2002290330370200200041286a200c280200360200200a450d022009102e200324000f0b41124101102c000b41ebdfc30041d700109b01000b200324000bdb0703037f047e087f230022022103200241e0026b416071220224002001411c6a22042902002105200420022903f801370200200141146a22042902002106200420022903f0013702002001410c6a22042902002107200420022903e801370200200241003a00e00120012902042108200120022903e00137020420022005370378200220063703702002200737036820022008370360200141246a2d00002104200241e0016a41176a22092005370000200241e0016a41106a220a2002290071370300200241e0016a41086a220b2002290069370300200220022900613703e001024002402008a741ff01714101460d00200041073a00400c010b200241186a41176a2009290000370000200241186a41106a200a290300370300200241186a41086a200b290300370300200220022903e001370318200220043a003702400240411510292204450d00200441002900bec8443700002004410d6a41002900cbc844370000200441086a41002900c6c84437000020024295808080d0023702e401200220043602e001200241186a200241e0016a104a20022802e401210c20022802e801210420022802e001210b200241e0016a41186a22094200370300200241e0016a41106a220a4200370300200241e0016a41086a220d4200370300200242003703e001200b2004200241e0016a1000200241e0006a41186a22042009290300370300200241e0006a41106a2209200a290300370300200241e0006a41086a220a200d290300370300200220022903e001370360200241e0016a200241e0006a10b20320022d0081024102460d01200241e0006a200241e0016a41e30010f6041a200241386a41206a220d200241e0006a41206a2d00003a0000200241386a41186a220e2004290300370300200241386a41106a220f2009290300370300200241386a41086a2210200a29030037030020022002290360370338200241e0016a20024181016a41c20010f6041a200141046a220141206a200241e0016a41c1006a2d00003a0000200141186a20024199026a290000370000200141106a20024191026a290000370000200141086a20024189026a29000037000020012002290081023700002004200241186a41186a2903003703002009200241186a41106a290300370300200a200241186a41086a2903003703002002200229031837036020024188016a201029030037030020024190016a200f29030037030020024198016a200e290300370300200241a0016a200d2d00003a000020022002290338370380012000200241e0006a41c10010f6041a200c450d02200b102e200324000f0b41154101102c000b41ebdfc30041d700109b01000b200324000bd00603037f047e057f230022022103200241e0016b416071220224002001411c6a220429020021052004200229039801370200200141146a2204290200210620042002290390013702002001410c6a220429020021072004200229038801370200200241003a00800120012902042108200120022903800137020420022005370338200220063703302002200737032820022008370320200141246a2d0000210420024180016a41176a2209200537000020024180016a41106a220a200229003137030020024180016a41086a220b20022900293703002002200229002137038001024002402008a741ff01714101460d00200042003703000c010b200241176a2009290000370000200241106a200a290300370300200241086a200b2903003703002002200229038001370300200220043a001f02400240411210292204450d0020044100290090e843370000200441106a41002f00a0e8433b0000200441086a4100290098e84337000020024292808080a002370284012002200436028001200220024180016a104a200228028401210a200228028801210b200228028001210920024180016a41186a220c420037030020024180016a41106a220d420037030020024180016a41086a2204420037030020024200370380012009200b20024180016a1000200241206a41186a200c290300370300200241206a41106a200d290300370300200241206a41086a2004290300370300200220022903800137032020024180016a200241206a10ad0320022d0098014102460d012004290300210520022802900121042002290380012108200241206a20024194016a41c60010f6041a20024180016a200241246a41c20010f6041a200141046a220141206a200241c1016a2d00003a0000200141186a200241b9016a290000370000200141106a200241b1016a290000370000200141086a200241a9016a290000370000200120022900a10137000020002002290300370008200041106a200241086a290300370000200041186a200241106a290300370000200041206a200241186a290300370000200041306a2005370300200041286a2008370300200041386a200436020020004201370300200a450d022009102e200324000f0b41124101102c000b41ebdfc30041d700109b01000b200324000bc30401047f230041f0006b22072400200741086a200242002003200410fb04200741c0006a41eea0c50041111081012007290348210320072802402108200741e0006a41086a220942003703002007420037036041eea0c5004111200741e0006a1003200741d0006a41086a220a2009290300370300200720072903603703502007200120027d2003420020081b7c370360200741d0006a4110200741e0006a41081004200741306a20002007290308200741086a41086a290300106d200741306a41086a290300210120072903302102200741186a41c28cc00041161070200520027d200220057d2002200558200120065820012006511b22001b2103200620017d2005200254ad7d200120067d2002200554ad7d20001b2106200741186a41106a2903004200200728021822081b21052007290320420020081b2102024002402000450d00200942003703002007420037036041c28cc0004116200741e0006a1003200a20092903003703002007200729036037035020074200200520067d2002200354ad7d2206200220037d2201200256200620055620062005511b22091b37036820074200200120091b370360200741e0006a21090c010b200942003703002007420037036041c28cc0004116200741e0006a1003200a2009290300370300200720072903603703502007427f200520067c200220037c22062002542209ad7c22022009200220055420022005511b22091b3703682007427f200620091b370360200741e0006a21090b200741d0006a4110200941101004200741f0006a24000ba32302117f057e230041f0036b22062400200641d0026a200010af01410221070240024020062d00d00222084102470d0041012108413421094102210a0c010b200641d0036a41086a220a200641e4026a290200370300200641d0036a41106a220b200641ec026a290200370300200641d0036a41186a220c200641f4026a290200370300200641a8036a41086a220d20064188036a290300370300200641a8036a41106a220e20064190036a290300370300200641a8036a41186a220f20064198036a290300370300200641a8036a41206a2210200641a0036a2903003703002006200641dc026a2902003703d003200620064180036a2903003703a803200641d0026a41086a2802002109024020080d00200641fc026a2802002107200641a8026a41186a200c290300370300200641a8026a41106a200b290300370300200641a8026a41086a200a29030037030020064180026a41086a200d29030037030020064180026a41106a200e29030037030020064180026a41186a200f29030037030020064180026a41206a2010290300370300200620062903d0033703a802200620062903a803370380020b4102210a024020074102470d0041012108413421090c010b200641a8036a41186a200641a8026a41186a290300370300200641a8036a41106a200641a8026a41106a290300370300200641a8036a41086a200641a8026a41086a290300370300200641d0026a41086a20064180026a41086a290300370300200641d0026a41106a20064180026a41106a290300370300200641d0026a41186a20064180026a41186a290300370300200641d0026a41206a20064180026a41206a290300370300200620062903a8023703a80320062006290380023703d002410021082007210a0b200641e0016a41086a220b200641a8036a41086a2207290300370300200641e0016a41106a220c200641a8036a41106a290300370300200641e0016a41186a220d200641a8036a41186a290300370300200641b8016a41086a220e200641d0026a41086a290300370300200641b8016a41106a220f200641d0026a41106a290300370300200641b8016a41186a2210200641d0026a41186a290300370300200641b8016a41206a2211200641d0026a41206a290300370300200620062903a8033703e001200620062903d0023703b8010240024020080d0020064190016a221220062903b801370300200641f4006a200b290300370200200641fc006a200c29030037020020064184016a200d29030037020020064198016a200e290300370300200641a0016a200f290300370300200641a8016a2010290300370300200641b0016a201129030037030020062009360268200620062903e00137026c2006200a36028c0120074200370300200642003703a80341b0f3c200410d200641a8036a1003200641d0036a41086a2007290300370300200620062903a8033703d003200641e0006a200641d0036a10ac032006280264410020062802601b210d4101210802400240200628028c014101470d002012280200200d460d010b200641d0026a200110af010240024020062d00d002220a4102470d00412e210a41cee2c300210b0c010b200641a8026a41026a20062d00d3023a0000200641a8036a41086a2208200641e4026a280200360200200620062f00d1023b01a8022006200641dc026a2902003703a803200641ec026a2802002107200641e8026a28020021090240200a0d0041012108412e210a41cee2c300210b024020070d000c020b2009102e0c010b200641d0026a41086a280200210a20062802d402210b200641e0016a41026a200641a8026a41026a2d00003a000020064180026a41086a2008280200360200200620062f01a8023b01e001200620062903a80337038002200641f0026a2d0000210c410021080b200641cc026a41026a200641e0016a41026a2d00003a0000200641d0036a41086a220e20064180026a41086a280200360200200620062f01e0013b01cc0220062006290380023703d00320080d00200641cb016a200e280200360000200620062f01cc023b01b8012006200a3600bf012006200b3600bb01200620062903d0033700c3012006200c3a00d701200620073600d301200620093600cf012006200641ce026a2d00003a00ba01200628028c0121132006280290012114200620052802002211200541086a28020022154105746a3602d403200620113602d0032006200641e8006a3602d803200641a8036a200641d0036a10270240024002400240024002400240024002400240024020062802a8030d0041002107200641003602b002200642043703a802410421094100210a0c010b200641d0026a41086a2208200641a8036a41086a290300370300200620062903a8033703d002411010292209450d01200920062903d002370200200941086a200829030037020020064180026a41086a200641d0036a41086a280200360200200620062903d00337038002200641a8036a20064180026a10270240024020062802a8030d00410121074101210a0c010b410121084101210a0340200641d0026a41086a220b200641a8036a41086a290300370300200620062903a8033703d00202400240200a2008460d00200841016a21070c010b200841016a22072008490d082008410174220a20072007200a491b220a41ffffffff0071200a470d08200a410474220c4100480d080240024020080d00200c102921090c010b20092008410474200c102a21090b2009450d050b200920084104746a220820062903d002370200200841086a200b290300370200200641a8036a20064180026a10272007210820062802a8030d000b0b200620073602b0022006200a3602ac02200620093602a8020b200641e8006a41186a28020021082006280278210b200641003602d002200b2008200641d0026a100a211020062802d002220f417f460d02200641a8036a41186a200241186a290000370300200641a8036a41106a200241106a290000370300200641a8036a41086a200241086a290000370300200620022900003703a803200641003602d803200642013703d0032010200f200641d0036a10b0010240024020062802d403220e20062802d803220c6b4120490d00200c41206a210b20062802d00321080c010b200c41206a220b200c490d05200e4101742208200b200b2008491b22124100480d0502400240200e0d002012102921080c010b20062802d003200e2012102a21080b2008450d04200620123602d403200620083602d0032012210e0b2006200b3602d8032008200c6a220c20062903a803370000200c41086a200641a8036a41086a290300370000200c41106a200641a8036a41106a290300370000200c41186a200641a8036a41186a290300370000200641d0026a41186a220c4200370300200641d0026a41106a22124200370300200641d0026a41086a22164200370300200642003703d0022008200b200641d0026a100020064180026a41186a200c29030037030020064180026a41106a201229030037030020064180026a41086a2016290300370300200620062903d002370380020240200e450d002008102e0b0240200f450d002010102e0b024020064180026a200641b8016a412010f8040d000240024020070d004100210b0c010b2007410474210c2009410c6a21084100210b03402008280200200b6a210b200841106a2108200c41706a220c0d000b0b2006200628028401200b6b36028401411710292208450d06200d201420151b210f4101201320151b2110200641e8006a41106a210b200841002900b0a5433700002008410f6a41002900bfa543370000200841086a41002900b8a54337000020064297808080f0023702d402200620083602d0022000200641d0026a104a20062802d402211220062802d802211620062802d002210e200641d0026a41186a22084200370300200641d0026a41106a220c4200370300200641d0026a41086a22154200370300200642003703d002200e2016200641d0026a1000200641a8036a41186a2008290300370300200641a8036a41106a200c290300370300200641a8036a41086a2015290300370300200620062903d0023703a803200641a8036a4120100602402012450d00200e102e0b200c20043703002008200b29030037030020064180036a200f360200200641fc026a2010360200200641f8026a200d360200200641f4026a20062802840136020020064184036a2002290000370200200641d0026a41206a200b41086a2802003602002006418c036a200241086a29000037020020064194036a200241106a2900003702002006419c036a200241186a290000370200200620033703d802200641003a00d0022001200641d0026a10f001411410292208450d07200841002900d88c40370000200841106a41002800e88c40360000200841086a41002900e08c4037000020064294808080c0023702d402200620083602d0022000200641d0026a104a20062802d402210b200641c8006a20062802d002220c20062802d802106e200641c8006a41106a290300210320062802482108200629035021040240200b450d00200c102e0b2003420020081b21172004420020081b2118200641d0026a200042004200106f20062903d0022119200641306a41c28cc00041161070200641306a41106a2903004200200628023022081b21032006290338420020081b2104200641d0026a41106a290300211a20062903d802211b0240024020194200520d00200641a8036a41086a22084200370300200642003703a80341c28cc0004116200641a8036a1003200641d0036a41086a2008290300370300200620062903a8033703d0032006427f2003201a7c2004201b7c221b2004542208ad7c22042008200420035420042003511b22081b3703b0032006427f201b20081b3703a803200641a8036a21080c010b200641a8036a41086a22084200370300200642003703a80341c28cc0004116200641a8036a1003200641d0036a41086a2008290300370300200620062903a8033703d003200642002003201a7d2004201b54ad7d22192004201b7d221b200456201920035620192003511b22081b3703b00320064200201b20081b3703a803200641a8036a21080b200641d0036a4110200841101004200641206a200120182017106d200641206a41086a29030021042006290320211b200641086a41c28cc00041161070200641086a41106a29030021032006290310211720062802082108200641a8036a41086a220b4200370300200642003703a80341c28cc0004116200641a8036a1003200641d0036a41086a200b290300370300200620062903a8033703d0032006427f20042003420020081b22037c201b2017420020081b22047c221b2004542208ad7c22042008200420035420042003511b22081b3703d8022006427f201b20081b3703d002200641d0036a4110200641d0026a4110100402402007450d0020074104742107200941046a210803400240200841046a280200450d002008280200102e0b200841106a2108200741706a22070d000b0b0240200a450d002009102e0b200541046a280200450d0c2011102e0c0c0b200920074104746a2111200921082007450d0720092108034002402008280200220b0d00200841106a21080c090b200841046a2802002107200841086a28020021002008410c6a280200210c20062802800121022006280278210d200641d0026a41186a220e4200370300200641d0026a41106a220f4200370300200641d0026a41086a22104200370300200642003703d002200b4120200641d0026a1000200641a8036a41186a200e290300370300200641a8036a41106a200f290300370300200641a8036a41086a2010290300370300200620062903d0023703a803200d2002200641a8036a41202007200c100b02402000450d002007102e0b200841106a22082011470d000c090b0b41104104102c000b200c4104102c000b41c0e6c5004138109b01000b20124101102c000b102d000b41174101102c000b41144101102c000b20082011460d0003402008280200450d010240200841086a280200450d00200841046a280200102e0b200841106a22082011470d000b0b200a450d002009102e0b200641fc006a280200450d002006280278102e0b200541046a280200450d002005280200102e0b200641f0036a24000bac0e010c7f230041c0036b220124000240024002400240024002400240411210292202450d0020024100290090e843370000200241106a41002f00a0e8433b0000200241086a4100290098e84337000020014292808080a0023702e402200120023602e0022000200141e0026a104a20012802e402210320012802e802210220012802e0022100200141e0026a41186a22044200370300200141e0026a41106a22054200370300200141e0026a41086a22064200370300200142003703e00220002002200141e0026a1000200141c0026a41186a2004290300370300200141c0026a41106a2005290300370300200141c0026a41086a2006290300370300200120012903e0023703c002200141e0026a200141c0026a10ad03024020012d00f80222024102460d00200141c0026a412010060b2001410a6a200141f9026a41c70010f6041a02402003450d002000102e0b200141d1006a2001410a6a41c70010f6041a20024102460d06200120023a00980120014198016a410172200141d1006a41c10010f6042106200141ba016a21050240024020012d00b9014101460d00410021000c010b411210292202450d0220024100290090e843370000200241106a41002f00a0e8433b0000200241086a4100290098e84337000020014292808080a0023702e402200120023602e0022005200141e0026a104a20012802e802210720012802e402210420012802e002210020012d00980121020b02400240200241ff01714101470d00411210292202450d0420024100290090e843370000200241106a41002f00a0e8433b0000200241086a4100290098e84337000020014292808080a0023702e402200120023602e0022006200141e0026a104a20012802e402210320012802e00222020d010b20012d00b9012102200141e0026a41186a22064200370300200141e0026a41106a22084200370300200141e0026a41086a22094200370300200142003703e00241f8e8c300411a200141e0026a1000200141c0026a41186a2006290300370300200141c0026a41106a2008290300370300200141c0026a41086a2009290300370300200120012903e0023703c002024020024101460d00200141c0026a412010060c060b200141203602e4022001200141c0026a3602e0022005200141e0026a109a020c050b20012802e8022108200141e0026a41186a22064200370300200141e0026a41106a22054200370300200141e0026a41086a22094200370300200142003703e00220022008200141e0026a1000200141c0026a41186a220a2006290300370300200141c0026a41106a2005290300370300200141c0026a41086a2009290300370300200120012903e0023703c002200141e0026a200141c0026a10ad0320012d00f8024102460d03200141e0016a200141e0026a41e00010f6041a20014199026a200141b9016a2205290000370000200141a1026a200541086a290000370000200141a9026a200541106a290000370000200141b1026a200541186a290000370000200141b9026a200541206a2d00003a000020064200370300200141e0026a41106a22054200370300200141e0026a41086a22094200370300200142003703e00220022008200141e0026a1000200a2006290300370300200141c0026a41106a2005290300370300200141c0026a41086a2009290300370300200120012903e0023703c002200141203602e4022001200141c0026a3602e002200141e0016a200141e0026a10dd0341012109024020030d00410021030c060b2002102e0c050b41124101102c000b41124101102c000b41124101102c000b418596c50041d300109b01000b41002102410021090b024002400240024020000d00410021050c010b200141e0026a41186a22054200370300200141e0026a41106a22064200370300200141e0026a41086a22084200370300200142003703e00220002007200141e0026a1000200141c0026a41186a220a2005290300370300200141c0026a41106a220b2006290300370300200141c0026a41086a220c2008290300370300200120012903e0023703c002200141e0026a200141c0026a10ad0320012d00f8024102460d01200141e0016a200141e0026a41e00010f6041a200141e0016a41206a20014198016a41086a29030037030020014188026a20014198016a41106a29030037030020014190026a20014198016a41186a29030037030020014198026a20014198016a41206a2d00003a000020012001290398013703f801200542003703002006420037030020084200370300200142003703e00220002007200141e0026a1000200a2005290300370300200b2006290300370300200c2008290300370300200120012903e0023703c002200141203602e4022001200141c0026a3602e002200141e0016a200141e0026a10dd03410121052004450d002000102e0b2003450d012009200245720d012002102e0c010b418596c50041d300109b01000b2004450d002000452005720d002000102e0b200141c0036a24000bd71003067f017e077f23004190036b220124000240024002400240024002400240411210292202450d00200241002900fee743370000200241106a41002f008ee8433b0000200241086a4100290086e84337000020014292808080a0023702c402200120023602c0022000200141c0026a104a20012802c402210320012802c802210220012802c0022100200141c0026a41186a22044200370300200141c0026a41106a22054200370300200141c0026a41086a22064200370300200142003703c00220002002200141c0026a1000200141a0026a41186a2004290300370300200141a0026a41106a2005290300370300200141a0026a41086a2006290300370300200120012903c0023703a002200141c0026a200141a0026a10ab03024020012d00cc0222024102460d00200141a0026a412010060b20012902c402210720012802c0022104200141026a200141cd026a41c30010f6041a02402003450d002000102e0b200141c5006a200141026a41c30010f6041a20024102460d06200120023a00880120014188016a410172200141c5006a41c10010f6042105200141aa016a21000240024020012d00a9014101460d00410021030c010b411210292202450d02200241002900fee743370000200241106a41002f008ee8433b0000200241086a4100290086e84337000020014292808080a0023702c402200120023602c0022000200141c0026a104a20012802c802210820012802c402210920012802c002210320012d00880121020b02400240200241ff01714101470d00411210292202450d04200241002900fee743370000200241106a41002f008ee8433b0000200241086a4100290086e84337000020014292808080a0023702c402200120023602c0022005200141c0026a104a20012802c402210620012802c00222050d010b20012d00a9012102200141c0026a41186a22054200370300200141c0026a41106a220a4200370300200141c0026a41086a220b4200370300200142003703c00241dee8c300411a200141c0026a1000200141a0026a41186a2005290300370300200141a0026a41106a200a290300370300200141a0026a41086a200b290300370300200120012903c0023703a002024020024101460d00200141a0026a412010060c060b200141203602c4022001200141a0026a3602c0022000200141c0026a109a020c050b20012802c802210a200141c0026a41186a22004200370300200141c0026a41106a22024200370300200141c0026a41086a220b4200370300200142003703c0022005200a200141c0026a1000200141a0026a41186a220c2000290300370300200141a0026a41106a2002290300370300200141a0026a41086a200b290300370300200120012903c0023703a002200141c0026a200141a0026a10ab0320012d00cc024102460d03200141d0016a200141c0026a41d00010f6041a200141fd016a200141a9016a220229000037000020014185026a200241086a2900003700002001418d026a200241106a29000037000020014195026a200241186a2900003700002001419d026a200241206a2d00003a000020004200370300200141c0026a41106a22024200370300200141c0026a41086a220b4200370300200142003703c0022005200a200141c0026a1000200c2000290300370300200141a0026a41106a2002290300370300200141a0026a41086a200b290300370300200120012903c0023703a002200141003602c802200142013703c00220012802d001210220012802d8012200200141c0026a1047200141dc016a210a02402000450d002000410574210003402002200141c0026a104a200241206a2102200041606a22000d000b0b200a200141c0026a10de0320012802c4022102200141a0026a412020012802c002220020012802c802100402402002450d002000102e0b024020012802d401450d0020012802d001102e0b4101210b024020060d00410021060c060b2005102e0c050b41124101102c000b41124101102c000b41124101102c000b418596c50041d300109b01000b410021054100210b0b024002400240024020030d00410021020c010b200141c0026a41186a22024200370300200141c0026a41106a22004200370300200141c0026a41086a220a4200370300200142003703c00220032008200141c0026a1000200141a0026a41186a220c2002290300370300200141a0026a41106a220d2000290300370300200141a0026a41086a220e200a290300370300200120012903c0023703a002200141c0026a200141a0026a10ab0320012d00cc024102460d01200141d0016a200141c0026a41d00010f6041a200141e4016a20014188016a41086a290300370200200141ec016a20014188016a41106a290300370200200141f4016a20014188016a41186a290300370200200141fc016a20014188016a41206a2d00003a000020012001290388013702dc012002420037030020004200370300200a4200370300200142003703c00220032008200141c0026a1000200c2002290300370300200d2000290300370300200e200a290300370300200120012903c0023703a002200141003602c802200142013703c00220012802d001210220012802d8012200200141c0026a1047200141dc016a210a02402000450d002000410574210003402002200141c0026a104a200241206a2102200041606a22000d000b0b200a200141c0026a10de0320012802c4022102200141a0026a412020012802c002220020012802c802100402402002450d002000102e0b024020012802d401450d0020012802d001102e0b410121022009450d002003102e0b2006450d01200b200545720d012005102e0c010b418596c50041d300109b01000b02402009450d002003452002720d002003102e0b2004450d002007a7450d002004102e0b20014190036a24000bf40501047f230041106b220224002002410036020820024201370300200041106a200210662002200036020c2002410c6a2002106b024002400240024002400240024020002d00184101460d0002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d0720034101742205200420042005491b22054100480d070240024020030d002005102921040c010b200228020020032005102a21040b2004450d0320022005360204200220043602000b2002200341016a360208200420036a41003a00000c010b02400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d0620034101742205200420042005491b22054100480d060240024020030d002005102921040c010b200228020020032005102a21040b2004450d0320022005360204200220043602000b2002200341016a360208200420036a41013a0000200041196a2002104a0b02400240200041396a2d00004101460d0002400240200228020420022802082200460d00200228020021030c010b200041016a22032000490d0720004101742204200320032004491b22044100480d070240024020000d002004102921030c010b200228020020002004102a21030b2003450d052002200436020420022003360200200228020821000b2002200041016a360208200320006a41003a00000c010b02400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d0620034101742205200420042005491b22054100480d060240024020030d002005102921040c010b200228020020032005102a21040b2004450d052002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a00002000413a6a2002104a0b2002280204210020012802002001280204200228020022012002280208100402402000450d002001102e0b200241106a24000f0b20054101102c000b20054101102c000b20044101102c000b20054101102c000b102d000bd50501037f024002400240024002400240024020002d00004101460d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0720024101742204200320032004491b22044100480d070240024020020d002004102921030c010b200128020020022004102a21030b2003450d0320012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41003a00000c010b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0620024101742204200320032004491b22044100480d060240024020020d002004102921030c010b200128020020022004102a21030b2003450d0320012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a0000200041016a2001104a0b024020002d00214101460d0002400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d0620004101742203200220022003491b22034100480d060240024020000d002003102921020c010b200128020020002003102a21020b2002450d0420012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41003a00000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0520024101742204200320032004491b22044100480d050240024020020d002004102921030c010b200128020020022004102a21030b2003450d0420012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a0000200041226a2001104a0f0b20044101102c000b20044101102c000b20034101102c000b20044101102c000b102d000b13002000410e360204200041a8e9c3003602000b3400200041c196c40036020420004100360200200041146a4115360200200041106a41c896c400360200200041086a42073702000b6b01027f230041106b22022400200241003602082002420137030002404104102922030d0041044101102c000b2003410036000020024284808080c00037020420022003360200410020021047200041086a200228020836020020002002290300370200200241106a24000b3001017f02404108102922020d0041084101102c000b20004288808080800137020420002002360200200242003700000b890201037f230041c0006b22022400200241186a4200370300200241106a22034200370300200241086a4200370300200241286a22044100360200200242003703002002420837032020024100360238200242013703302002200236023c2002413c6a200241306a106b2002200336023c2002413c6a200241306a106b2002280220210320042802002204200241306a104702402004450d00200441306c21040340200341106a200241306a104a2002200336023c200341306a21032002413c6a200241306a106b200441506a22040d000b0b20002002290330370200200041086a200241306a41086a28020036020002402002280224450d002002280220102e0b200241c0006a24000b7001017f230041306b220224002002420037031020024200370308200241033602182002410036022820024201370320200241186a200241206a10662002200241086a36022c2002412c6a200241206a106b200041086a200228022836020020002002290320370200200241306a24000b0b00200041c0843d10ab010b3001017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241043600000b13002000410236020420004190bac4003602000b3101017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241a0053600000b840a04087f047e067f057e230041a0026b2202240002400240024002400240410f10292203450d00200341002900a2e843370000200341076a41002900a9e8433700002002428f808080f0013702fc01200220033602f8012001200241f8016a104a20022802fc012104200228028002210320022802f8012105200241f0006a41186a22014200370300200241f0006a41106a22064200370300200241f0006a41086a220742003703002002420037037020052003200241f0006a1000200241d0006a41186a2001290300370300200241d0006a41106a2006290300370300200241d0006a41086a200729030037030020022002290370370350200241003602f801200241d0006a4120200241f8016a100821080240024020022802f8012209417f460d0020022009360294012002200836029001200241386a20024190016a10652002290338a70d06200241386a41106a290300210a2002290340210b200241206a20024190016a10652002290320a70d06200241306a290300210c2002290328210d200241186a20024190016a103120022802180d06200228029401220641306e220e41306c2203417f4c0d03200228021c210f0240024020030d00410821100c010b200310292210450d050b0240200f450d00410021070340200241003a009802200741016a2111410021030240024002400240034020062003460d01200241f8016a20036a20022802900122012d00003a00002002200141016a360290012002200341016a22013a0098022001210320014120470d000b200241f0006a41086a2203200241f8016a41086a290300370300200241f0006a41106a2212200241f8016a41106a290300370300200241f0006a41186a2213200241f8016a41186a290300370300200220022903f8013703702002200620016b36029401200220024190016a10652002290300a70d01200241106a290300211420022903082115200241b8016a41086a20032903002216370300200241b8016a41106a20122903002217370300200241b8016a41186a2013290300221837030020024198016a41086a2201201637030020024198016a41106a2206201737030020024198016a41186a221220183703002002200229037022163703b8012002201637039801200e2007470d03024020074101742203201120112003491b220ead42307e2216422088a70d002016a7220341004e0d030b102d000b2002410036029401200341ff0171450d00200241003a0098020b200241b8016a41086a200241d8016a41086a290300370300200e450d0a2010102e0c0a0b0240024020070d002003102921100c010b2010200741306c2003102a21100b2010450d080b2010200741306c6a22032014370308200320153703002003200229039801370310200341186a2001290300370300200341206a2006290300370300200341286a20122903003703002011200f460d012002280294012106201121070c000b0b2010450d06200fad422086200ead84211402402009450d002008102e0b2000200d3703102000200b37030020002010360220200041186a200c3703002000200a370308200041246a20143702000c010b200041186a4200370300200041106a4200370300200041086a420037030020004200370300200041286a4100360200200042083703200b02402004450d002005102e0b200241a0026a24000f0b410f4101102c000b1032000b20034108102c000b20034108102c000b41eff0c2004133200241f8016a4184f4c2001053000b860d021e7f037e230041f0026b220424000240024002400240410d10292205450d0041002106200541002900bfe843370000200541056a41002900c4e8433700002004428d808080d0013702a402200420053602a0022001200441a0026a104a20042802a402210720042802a802210820042802a0022105200441a0026a41186a22094200370300200441a0026a41106a220a4200370300200441a0026a41086a220b4200370300200442003703a00220052008200441a0026a1000200441e0016a41186a2009290300370300200441e0016a41106a200a290300370300200441e0016a41086a200b290300370300200420042903a0023703e001200441003602a002200441e0016a4120200441a0026a10082108024020042802a0022209417f460d002009450d0220082d0000220641034f0d022008102e0b02402007450d002005102e0b02400240024020060e03000201000b200441f8006a200110820220042d00784101470d04200441a0016a41186a220520044191016a290000370300200441a0016a41106a220620044189016a290000370300200441a0016a41086a220820044181016a290000370300200420042900793703a001200441a0026a200441a0016a108302200441c0016a41186a22072005290300370300200441c0016a41106a220b2006290300370300200441c0016a41086a220c2008290300370300200420042903a0013703c00120042802c002220d450d04200441e0016a41186a220e2007290300370300200441e0016a41106a220f200b290300370300200441e0016a41086a2210200c290300370300200441e0016a41286a2205200441a0026a41086a2206290300370300200441e0016a41306a2208200441a0026a41106a2207290300370300200441e0016a41386a2209200441a0026a41186a220a290300370300200441086a41286a2211200441ec026a2212280200360200200441086a41206a2213200441e4026a2214290200370300200441086a41186a2215200441dc026a2216290200370300200441086a41106a2217200441d4026a2218290200370300200441086a41086a2219200441cc026a221a290200370300200420042903c0013703e001200420042903a00237038002200420042902c402370308200441386a41386a221b2009290300370300200441386a41306a221c2008290300370300200441386a41286a221d2005290300370300200441386a41206a221e200429038002370300200441386a41186a221f200e290300370300200441386a41106a2220200f290300370300200441386a41086a22212010290300370300200420042903e0013703382009201b2903003703002008201c2903003703002005201d290300370300200441e0016a41206a221b201e290300370300200e201f290300370300200f202029030037030020102021290300370300200420042903383703e001200441f8006a41186a201f290300370300200441f8006a41106a2020290300370300200441f8006a41086a202129030037030020042004290338370378200a200929030037030020072008290300370300200620052903003703002004200d3602c0022004201b2903003703a002200441c4026a22052004290308370200201a201929030037020020182017290300370200201620152903003702002014201329030037020020122011280200360200200a290300212220072007290300222320027c2224370300200a202220037c2024202354ad7c37030020062903002122200420042903a002222320027c22243703a0022006202220037c2024202354ad7c370300200441c0016a200120022003108e0120043502c0012102200b2903002122200c2903002103200441f8006a200441a0026a10ec0302402005280200450d0020042802c002102e0b200242018521020c050b200441a0026a200110820220042d00a0024101470d03200441f8016a200441b9026a290000370300200441e0016a41106a200441b1026a290000370300200441e0016a41086a200441a9026a290000370300200420042900a1023703e001200441386a200441e0016a20022003108e0120043502384201852102200441386a41106a2903002122200441386a41086a29030021030c040b200441a0026a200120022003108e0120043502a0024201852102200441b0026a2903002122200441a8026a29030021030c030b410d4101102c000b41eff0c2004133200441a0026a4184f4c2001053000b420021020b2000200337030820002002370300200041106a2022370300200441f0026a24000b0900200042003702000bc30201067f230041d0006b22022400200242f3e885db96cddbb320370308200241086a2001412c6a2001290300200141086a290300417f410e1091010240410e10292203450d00200341002900b1e843370000200341066a41002900b7e8433700002002428e808080e001370234200220033602302000200241306a104a200228023421002002280238210420022802302103200241306a41186a22054200370300200241306a41106a22064200370300200241306a41086a220742003703002002420037033020032004200241306a1000200241106a41186a2005290300370300200241106a41106a2006290300370300200241106a41086a200729030037030020022002290330370310200241203602342002200241106a3602302001200241306a10ef0302402000450d002003102e0b200241d0006a24000f0b410e4101102c000b02000bd70302027f077e23004180016b22032400200341c0006a200110d80302400240024020032903404201520d00200241016a2104200341c0006a41086a21020340200341086a41306a200241306a2903002205370300200341086a41286a200241286a2903002206370300200341086a41206a200241206a2903002207370300200341086a41186a200241186a2903002208370300200341086a41106a200241106a2903002209370300200341086a41086a200241086a290300220a37030020032002290300220b370308200341c0006a41306a2005370300200341c0006a41286a2006370300200341c0006a41206a2007370300200341c0006a41186a2008370300200341c0006a41106a20093703002002200a3703002003200b3703402004417f6a2204450d02200341c0006a200110d80320032903404201510d000b0b200042003703000c010b2000200329034037030820004201370300200041386a200341c0006a41306a290300370300200041306a200341c0006a41286a290300370300200041286a200341c0006a41206a290300370300200041206a200341c0006a41186a290300370300200041186a200341c0006a41106a290300370300200041106a200341c8006a2903003703000b20034180016a24000bc80101027f230041106b2202240020024100360208200242013703002000412c6a2002104a2002200036020c2002410c6a2002106b2002200041106a36020c2002410c6a2002106b20002802202103200041286a28020022002002104702402000450d002003200041186c6a210003402002200336020c2002410c6a2002106b200341106a200210662000200341186a2203470d000b0b2002280204210320012802002001280204200228020022002002280208100402402003450d002000102e0b200241106a24000bf10801047f230041e0026b22052400200541f598c5004119107d0240024002402005280204410020052802001b2206417f6a220720064d0d00200541033a0098010c010b200541086a200710810320052d0098014103460d00200541a0016a200541086a41980110f6041a20052802a8022107200541a0016a102f200720014d0d0020004187cac40036020420004101360200200041086a41c7003602002002102f0c010b200541a0016a41086a22074200370300200542003703a00141f598c5004119200541a0016a1003200541086a41086a2007290300370300200520052903a0013703082005200641016a3602a001200541086a4110200541a0016a41041004200541a0016a200241880110f6041a200520033a00b002200520043602ac02200520013602a802024002400240024002400240411a10292201450d00200141186a41002f00ebc8443b0000200141106a41002900e3c844370000200141086a41002900dbc844370000200141002900d3c8443700002001411a4134102a2202450d012002200636001a200541086a41186a22014200370300200541086a41106a22044200370300200541086a41086a22074200370300200542003703082002411e200541086a1000200541b8026a41186a2001290300370300200541b8026a41106a2004290300370300200541b8026a41086a2007290300370300200520052903083703b802200541003602102005420137030820052802a8022104410410292201450d022005410436020c20052005280210220741046a36021020052001360208200120076a2004360000200541a0016a200541086a10bc01024020052d00b002220141024b0d00024002400240024020010e03000102000b410021040c020b410121040c010b410221040b200520043a00df0202400240200528020c20052802102201460d00200528020821070c010b200141016a22072001490d0720014101742208200720072008491b22084100480d070240024020010d002008102921070c010b200528020820012008102a21070b2007450d052005200836020c20052007360208200528021021010b2005200141016a360210200720016a20043a00000b20052802ac02210702400240200528020c2204200528021022016b4104490d00200528020821040c010b200141046a22082001490d0620044101742201200820082001491b22014100480d060240024020040d002001102921040c010b200528020820042001102a21040b2004450d052005200136020c20052004360208200528021021010b2005200141046a360210200420016a2007360000200528020c2101200541b8026a4120200528020822042005280210100402402001450d002004102e0b2002102e200541a0016a102f200541ac016a2006360200200541a9016a20033a0000200541a8016a41033a0000200541053a00a00141c8ecc5004100200541a0016a107220004100360200200020063602040c060b411a4101102c000b41344101102c000b41044101102c000b20084101102c000b20014101102c000b102d000b200541e0026a24000bbd0201047f230041c0006b2202240002400240411310292203450d002003410f6a41002800fcc844360000200341086a41002900f5c844370000200341002900edc844370000200341134126102a2203450d0120032001360013200241206a41186a22014200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034117200241206a1000200241186a2001290300370300200241106a2004290300370300200241086a200529030037030020022002290320370300200241206a200210af030240024020022802300d00200041003602100c010b20002002290320370300200041186a2001290300370300200041106a2004290300370300200041086a200241206a41086a2903003703000b2003102e200241c0006a24000f0b41134101102c000b41264101102c000b130020004111360204200041cccbc4003602000b3400200041f9eac40036020420004100360200200041146a410f360200200041106a4184ebc400360200200041086a42093702000b4f01027f230041106b2202240002404101102922030d0041014101102c000b200341003a0000200041086a4101360200200241013602042002200336020020002002290300370200200241106a24000b5d01027f23004190016b22022400200241033a0088010240410110292203450d00200341003a0000200042818080801037020420002003360200024020022d0088014103460d002002102f0b20024190016a24000f0b41014101102c000bfc0201057f230041c0006b22022400200241206a4200370300200241186a4200370300200241086a41086a4200370300200241003a0028200242003703082002410036023820024201370330200241086a200241306a104a02400240024020022d0028220341064b0d000240024002400240024002400240024020030e0700010203040506000b410021040c060b410121040c050b410221040c040b410321040c030b410421040c020b410521040c010b410621040b200220043a003f02400240200228023420022802382203460d00200228023021050c010b200341016a22052003490d0320034101742206200520052006491b22064100480d030240024020030d002006102921050c010b200228023020032006102a21050b2005450d022002200636023420022005360230200228023821030b2002200341016a360238200520036a20043a00000b20002002290330370200200041086a200241306a41086a280200360200200241c0006a24000f0b20064101102c000b102d000b3f01017f230041106b220224002002410036020820024201370300410020021047200041086a200228020836020020002002290300370200200241106a24000b130020004106360204200041ac87c5003602000b3201017f02404104102922020d0041044101102c000b20004284808080c0003702042000200236020020024180ce183600000b3201017f02404104102922020d0041044101102c000b20004284808080c00037020420002002360200200241c0d1023600000b3e01017f02404110102922020d0041104101102c000b20024200370008200242808084fea6dee111370000200042908080808002370204200020023602000b3201017f02404104102922020d0041044101102c000b20004284808080c0003702042000200236020020024180af1a3600000ba11a03037f027e017f23004190026b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e13000102030405060708090a0b0c0d0e0f101112000b20024188016a200141086a109a03200041003a0000200041106a20024188016a41086a290300370300200041086a2002290388013703000c120b200041013a00002000410220012d0001220141004720014102461b3a00010c110b200041023a0000200041086a200141086a2903003703000c100b20024188016a200141046a1039200041033a00002000410c6a20024190016a280200360200200041046a2002290388013702000c0f0b109b03000b0240024002400240200141086a280200417f6a220341014b0d0020030e020102010b41f8b3c0001058000b41012103024002402001410c6a2d00004101460d00200241026a2001410f6a2d00003a000020024190016a2001411c6a29020037030020024188016a41106a200141246a290200370300200241a0016a2001412c6a2d00003a000020022001410d6a2f00003b01002002200141146a29020037038801200141106a2802002104410021030c010b200141106a28020021040b200241246a41026a200241026a2d00003a0000200241286a41086a20024188016a41086a290300370300200241286a41106a20024188016a41106a290300370300200241286a41186a20024188016a41186a280200360200200220022f01003b01242002200229038801370328200141386a29030021052001290330210641012107200241106a21010c010b41012103024002402001410c6a2d00004101460d002002418e026a2001410f6a2d00003a000020024190016a2001411c6a29020037030020024188016a41106a200141246a290200370300200241a0016a2001412c6a2d00003a000020022001410d6a2f00003b018c022002200141146a29020037038801200141106a2802002104410021030c010b200141106a28020021040b41022107200241246a41026a2002418c026a41026a2d00003a0000200241286a41086a20024188016a41086a290300370300200241286a41106a20024188016a41106a290300370300200241286a41186a20024188016a41186a280200360200200220022f018c023b01242002200229038801370328200220012903303703102002200141386a290300370318200141c8006a290300210520012903402106200221010b20012006370300200120053703082000410c6a20033a0000200041086a20073602002000410d6a20022f01243b00002000410f6a200241266a2d00003a0000200041106a2004360200200041146a20022903283702002000411c6a200241286a41086a290300370200200041246a200241286a41106a2903003702002000412c6a200241c0006a280200360200200041386a200241106a41086a290300370300200041306a2002290310370300200041c0006a2002290300370300200041c8006a200241086a290300370300200041053a00000c0d0b20024188016a200141086a109c03200041063a0000200041386a20024188016a41306a290300370300200041306a20024188016a41286a290300370300200041286a20024188016a41206a290300370300200041206a20024188016a41186a290300370300200041186a20024188016a41106a290300370300200041106a20024188016a41086a290300370300200041086a2002290388013703000c0c0b20024188016a41186a200141286a29000037030020024188016a41106a200141206a29000037030020024190016a200141186a29000037030020024188016a41286a200141386a29000037030020024188016a41306a200141c0006a29000037030020024188016a41386a200141c8006a29000037030020024188016a41c8006a200141d8006a29000037030020024188016a41d0006a200141e0006a29000037030020024188016a41d8006a200141e8006a2900003703002002200141106a290000370388012002200141306a2900003703a8012002200141d0006a2900003703c8012001410c6a2802002203417f4c0d0c0240024020030d00410121010c010b200141046a2802002104200310292201450d0e20012004200310f6041a0b200241286a20024188016a41e00010f6041a2000410c6a2003360200200041086a2003360200200041046a2001360200200041106a200241286a41e00010f6041a200041073a00000c0b0b20024188016a200141086a109d03200041083a0000200041306a20024188016a41286a290300370300200041286a20024188016a41206a290300370300200041206a20024188016a41186a290300370300200041186a20024188016a41106a290300370300200041106a20024188016a41086a290300370300200041086a2002290388013703000c0a0b20024188016a200141046a109e03200041093a0000200041246a200241a8016a2903003702002000411c6a200241a0016a290300370200200041146a20024198016a2903003702002000410c6a20024190016a290300370200200041046a2002290388013702000c090b20024188016a200141046a109e032000410a3a0000200041246a200241a8016a2903003702002000411c6a200241a0016a290300370200200041146a20024198016a2903003702002000410c6a20024190016a290300370200200041046a2002290388013702000c080b20024188016a200141086a10d8012000410b3a0000200041c0006a20024188016a41386a290300370300200041386a20024188016a41306a290300370300200041306a20024188016a41286a290300370300200041286a20024188016a41206a290300370300200041206a20024188016a41186a290300370300200041186a20024188016a41106a290300370300200041106a20024188016a41086a290300370300200041086a2002290388013703000c070b20024188016a200141046a108b03200041046a20024188016a41c40010f6041a2000410c3a00000c060b2000410d3a0000200041046a200141046a2802003602000c050b2001410c6a2802002203417f4c0d050240024020030d00410121010c010b200141046a2802002104200310292201450d0820012004200310f6041a0b2000410e3a00002000410c6a2003360200200041086a2003360200200041046a20013602000c040b024002400240024002400240200141086a280200417f6a220341024b0d0020030e03010203010b4184dbc0001058000b200141386a2903002105200141306a290300210641012103024002402001410c6a2d00004101460d0020024190016a2001411c6a29020037030020024188016a41106a200141246a290200370300200241a0016a2001412c6a2d00003a00002002200141146a290200370388012001410d6a2f00002001410f6a2d0000411074722104200141106a2802002101410021030c010b200141106a28020021010b200241286a41186a20024188016a41186a280200360200200241286a41106a20024188016a41106a290300370300200241286a41086a20024188016a41086a2903003703002002200229038801370328410121070c030b2001410c6a28020022034108762104410221070c010b2001410c6a28020022034108762104410321070b0b2000410f3a0000200041386a2005370300200041306a2006370300200041106a2001360200200041086a2007360200200041146a20022903283702002000410c6a2004410874200341ff0171723602002000411c6a200241286a41086a290300370200200041246a200241286a41106a2903003702002000412c6a200241c0006a2802003602000c030b20024188016a200141086a109f03200041086a20024188016a41800110f6041a200041103a00000c020b0240024002400240200141046a280200417f6a220341014b0d0020030e020102010b41a8c2c2001058000b41880110292203450d072003200141086a280200109903410121010c010b4101210302400240200141086a2d00004101460d0020024188016a41086a200141186a29020037030020024188016a41106a200141206a29020037030020024188016a41186a200141286a2d00003a00002002200141106a29020037038801200141096a2f00002001410b6a2d00004110747221072001410c6a2802002104410021030c010b2001410c6a28020021040b200241286a41186a20024188016a41186a280200360200200241286a41106a20024188016a41106a290300370300200241286a41086a20024188016a41086a290300370300200220022903880137032820032007410874722103410221010b200041113a00002000410c6a2004360200200041086a2003360200200041046a2001360200200041106a2002290328370200200041186a200241286a41086a290300370200200041206a200241286a41106a290300370200200041286a200241286a41186a2802003602000c010b20024188016a200141046a108002200041046a20024188016a41e40010f6041a200041123a00000b20024190026a24000f0b1032000b20034101102c000b20034101102c000b4188014108102c000ba10301047f230041c0006b22022400024002400240411310292203450d002003410f6a41002800fcc844360000200341086a41002900f5c844370000200341002900edc844370000200341134126102a2204450d0120042000360013200241206a41186a22034200370300200241206a41106a22004200370300200241206a41086a220542003703002002420037032020044117200241206a1000200241186a2003290300370300200241106a2000290300370300200241086a200529030037030020022002290320370300411010292203450d02200320012903003700002003200141086a2903003700082002429080808080023702242002200336022020012802102105200141186a2802002203200241206a104702402003450d00200341057421002005210303402003200241206a104a200341206a2103200041606a22000d000b0b2002280224210320024120200228022022002002280228100402402003450d002000102e0b2004102e0240200141146a280200450d002005102e0b200241c0006a24000f0b41134101102c000b41264101102c000b41104101102c000be70201067f230041d0006b220224000240410f10292203450d00200341002900bd9445370000200341076a41002900c494453700002002428f808080f00137020c200220033602082001200241086a104a200228020c21042002280210210520022802082103200241086a41186a22014200370300200241086a41106a22064200370300200241086a41086a220742003703002002420037030820032005200241086a1000200241306a41186a2001290300370300200241306a41106a2006290300370300200241306a41086a200729030037030020022002290308370330200241086a200241306a412010dc010240024020022d00084101460d00200041003a00000c010b20002002290308370000200041206a200241086a41206a2d00003a0000200041186a2001290300370000200041106a2006290300370000200041086a20072903003700000b02402004450d002003102e0b200241d0006a24000f0b410f4101102c000b800e01097f23004180016b2204240002400240024002400240024002400240024002400240411a10292205450d00200541186a41002f00ebc8443b0000200541106a41002900e3c844370000200541086a41002900dbc844370000200541002900d3c8443700002005411a4134102a2205450d012005200136001a200441e0006a41186a22064200370300200441e0006a41106a22074200370300200441e0006a41086a22084200370300200442003703602005411e200441e0006a1000200441c0006a41186a2006290300370300200441c0006a41106a2007290300370300200441c0006a41086a200829030037030020042004290360370340200441c0006a412041c8ecc50041004100100521062005102e024002402006417f470d0041a997c50021060c010b200441146a200041086a2900003702002004411c6a200041106a290000370200200441246a200041186a290000370200200420013602082004200029000037020c411010292205450d03200541002900aec844370000200541086a41002900b6c84437000020044290808080800237026420042005360260200541104120102a2205450d0420042004280268220641046a3602682004200536026020044120360264200520066a2001360000200441086a410472200441e0006a104a200428026421062004280268210720042802602105200441e0006a41186a22084200370300200441e0006a41106a22094200370300200441e0006a41086a220a42003703002004420037036020052007200441e0006a1000200441c0006a41186a2008290300370300200441c0006a41106a2009290300370300200441c0006a41086a200a29030037030020042004290360370340200441c0006a412041c8ecc500410041001005210702402006450d002005102e0b02402007417f470d00200441306a2001108203200441086a41186a200041186a290000370300200441086a41106a200041106a290000370300200441086a41086a200041086a29000037030020042000290000370308024002402004280234220820042802382205460d00200428023021070c010b200541016a22062005490d0820054101742207200620062007491b220841ffffff3f712008470d08200841057422064100480d080240024020050d002006102921070c010b200428023020054105742006102a21070b2007450d0720042008360234200420073602300b200720054105746a22062004290308370000200641186a200441086a41186a290300370000200641106a200441086a41106a290300370000200641086a200441086a41086a2903003700002004200541016a220a360238411310292206450d082006410f6a41002800a6c944360000200641086a410029009fc94437000020064100290097c944370000200641134126102a2209450d0920092001360013200441e0006a41186a22064200370300200441e0006a41106a220b4200370300200441e0006a41086a220c42003703002004420037036020094117200441e0006a1000200441c0006a41186a2006290300370300200441c0006a41106a200b290300370300200441c0006a41086a200c290300370300200420042903603703402004410036021020044201370308200a200441086a10470240200a450d00200541057441206a21062007210503402005200441086a104a200541206a2105200641606a22060d000b0b200428020c2105200441c0006a4120200428020822062004280210100402402005450d002006102e0b2009102e2008450d002007102e0b200441146a200041086a2900003702002004411c6a200041106a290000370200200441246a200041186a290000370200200420013602082004200029000037020c411010292205450d09200541002900aec844370000200541086a41002900b6c84437000020044290808080800237026420042005360260200541104120102a2205450d0a2004412036026420042004280268220641046a36026820042005360260200520066a2001360000200441086a410472200441e0006a104a200428026421012004280268210520042802602100200441e0006a41186a22064200370300200441e0006a41106a22074200370300200441e0006a41086a220842003703002004420037036020002005200441e0006a1000200441c0006a41186a2006290300370300200441c0006a41106a2007290300370300200441c0006a41086a200829030037030020042004290360370340410110292205450d0b41002106200541807f410020021b2003723a0000200441c0006a41202005410110042005102e2001450d002000102e0b20044180016a240020060f0b411a4101102c000b41344101102c000b41104101102c000b41204101102c000b20064101102c000b102d000b41134101102c000b41264101102c000b41104101102c000b41204101102c000b41014101102c000bc00302067f017e230041d0006b220224000240411310292203450d002003410f6a41002800ef9345360000200341086a41002900e89345370000200341002900e0934537000020024293808080b00237022c200220033602282001200241286a1046200228022c21042002280230210320022802282101200241286a41186a22054200370300200241286a41106a22064200370300200241286a41086a220742003703002002420037032820012003200241286a1000200241086a41186a2005290300370300200241086a41106a2006290300370300200241086a41086a20072903003703002002200229032837030820024100360228200241086a4120200241286a1008210302400240024020022802282205417f460d002003450d00200220033602482002200536024c024020054104490d0020022005417c6a36024c2002200341046a36024820032800002106200241286a200241c8006a1030200228022822050d020b41eff0c2004133200241286a4184f4c2001053000b410021050c010b200229022c21082003102e20002008370208200020063602000b2000200536020402402004450d002001102e0b200241d0006a24000f0b41134101102c000bb204030e7f017e017f230041c0006b22032400200128020022042001280208220541047422066a210720012802042108200421010240024002402005450d00200341306a41017221094100210a200341306a41026a210b200341206a410172220c41076a210d0340200b2004200a6a220141036a2d00003a00002003200141016a2f00003b0130024020012d0000220e41ac01470d00200141106a21010c020b2003410c6a41026a200b2d0000220f3a0000200320032f013022103b010c200141046a29020021112001410c6a2802002112200920103b0000200941026a200f3a00002003200e3a00302003201236023c20032011370234200341206a200341306a20021083042003200c2900003703102003200d290000370017024020032d0020220e411a470d002006200a41106a220a470d010c030b0b2000200e3a000020002003290310370001200041086a20032900173700000240200541047441706a200a460d00200141186a2101034002400240200141786a220a2d0000220b4109460d00200b41ac01470d010c030b200128020041ffffffff0371450d00200a41046a280200102e0b200141106a2101200a41106a2007470d000b0b2008450d022004102e0c020b20012007460d0003400240024020012d0000220a4109460d00200a41ac01470d010c030b200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a22012007470d000b0b02402008450d002004102e0b2000411a3a00000b200341c0006a24000bf6d60202097f017e230041106b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000eac01000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab01000b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102921050c010b200228020420042006102a21050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41003a00000cab010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102921050c010b200228020420042006102a21050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41013a00000caa010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df50120044101742208200520052008491b22084100480df5010240024020040d002008102921050c010b200628020020042008102a21050b2005450dad0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41023a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df50120044101742208200520052008491b22084100480df5010240024020040d002008102921050c010b200628020020042008102a21050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca9010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df40120044101742208200520052008491b22084100480df4010240024020040d002008102921050c010b200628020020042008102a21050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41033a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df40120044101742208200520052008491b22084100480df4010240024020040d002008102921050c010b200628020020042008102a21050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca8010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df30120044101742208200520052008491b22084100480df3010240024020040d002008102921050c010b200628020020042008102a21050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41043a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df30120044101742208200520052008491b22084100480df3010240024020040d002008102921050c010b200628020020042008102a21050b2005450db00120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca7010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102921050c010b200228020420042006102a21050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41053a00000ca6010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102921050c010b200228020420042006102a21050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410b3a00000ca5010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490df00120044101742207200620062007491b22074100480df0010240024020040d002007102921060c010b200928020020042007102a21060b2006450db00120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410c3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df1012004410174220a20062006200a491b220a4100480df1010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db201200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca5010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490def0120044101742207200620062007491b22074100480def010240024020040d002007102921060c010b200928020020042007102a21060b2006450db10120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410d3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df0012004410174220a20062006200a491b220a4100480df0010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db301200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca4010b0b200241046a210a2001410c6a2802002104200141086a2802002109200141046a280200210b02400240200241086a2802002002410c6a2802002201460d00200a28020021050c010b200141016a22052001490dee0120014101742206200520052006491b22064100480dee010240024020010d002006102921050c010b200a28020020012006102a21050b2005450db20120022005360204200241086a20063602002002410c6a28020021010b2002410c6a2206200141016a360200200520016a410e3a000020032009200b200b20094102746a200210840420032d0000411a470d9303200241086a2107034002400240200728020020062802002201460d00200a28020021050c010b200141016a22052001490def0120014101742208200520052008491b22084100480def010240024020010d002008102921050c010b200a28020020012008102a21050b2005450db4012002200536020420072008360200200628020021010b2006200141016a360200200520016a200441807f72200441ff0071200441077622011b3a00002001210420010d000b0240200941ffffffff0371450d00200b102e0b2000411a3a00000c95030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490ded0120044101742206200520052006491b22064100480ded010240024020040d002006102921050c010b200228020420042006102a21050b2005450db30120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410f3a00000ca1010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490dec0120044101742207200620062007491b22074100480dec010240024020040d002007102921060c010b200928020020042007102a21060b2006450db30120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41103a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490ded012004410174220a20062006200a491b220a4100480ded010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db501200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca1010b0b200241046a2109200141046a280200210520012d0001210b02400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490deb0120044101742207200620062007491b22074100480deb010240024020040d002007102921060c010b200928020020042007102a21060b2006450db40120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41113a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490dec012004410174220a20062006200a491b220a4100480dec010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db601200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b02400240200241086a2802002002410c6a2802002204460d00200928020021050c010b200441016a22052004490deb0120044101742206200520052006491b22064100480deb010240024020040d002006102921050c010b200928020020042006102a21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a200b3a00000c9f010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dea0120044101742206200520052006491b22064100480dea010240024020040d002006102921050c010b200228020420042006102a21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411a3a00000c9e010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490de90120044101742206200520052006491b22064100480de9010240024020040d002006102921050c010b200228020420042006102a21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411b3a00000c9d010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de80120044101742207200620062007491b22074100480de8010240024020040d002007102921060c010b200928020020042007102a21060b2006450db60120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41203a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de9012004410174220a20062006200a491b220a4100480de9010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db801200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9d010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de70120044101742207200620062007491b22074100480de7010240024020040d002007102921060c010b200928020020042007102a21060b2006450db70120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41213a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de8012004410174220a20062006200a491b220a4100480de8010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db901200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9c010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de60120044101742207200620062007491b22074100480de6010240024020040d002007102921060c010b200928020020042007102a21060b2006450db80120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41223a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de7012004410174220a20062006200a491b220a4100480de7010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450dba01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9b010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de50120044101742207200620062007491b22074100480de5010240024020040d002007102921060c010b200928020020042007102a21060b2006450db90120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41233a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de6012004410174220a20062006200a491b220a4100480de6010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450dbb01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9a010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de40120044101742207200620062007491b22074100480de4010240024020040d002007102921060c010b200928020020042007102a21060b2006450dba0120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41243a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de5012004410174220a20062006200a491b220a4100480de5010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450dbc01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c99010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de30120044101742208200720072008491b22084100480de3010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dbb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41283a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de4012004410174220b20072007200b491b220b4100480de4010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dbd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de40120044101742209200620062009491b22094100480de4010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dbe012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c98010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de20120044101742208200720072008491b22084100480de2010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dbd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41293a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de3012004410174220b20072007200b491b220b4100480de3010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dbf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de30120044101742209200620062009491b22094100480de3010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dc0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c97010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de10120044101742208200720072008491b22084100480de1010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dbf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de2012004410174220b20072007200b491b220b4100480de2010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dc101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de20120044101742209200620062009491b22094100480de2010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dc2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c96010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de00120044101742208200720072008491b22084100480de0010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dc10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de1012004410174220b20072007200b491b220b4100480de1010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dc301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de10120044101742209200620062009491b22094100480de1010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dc4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c95010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddf0120044101742208200720072008491b22084100480ddf010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dc30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de0012004410174220b20072007200b491b220b4100480de0010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dc501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de00120044101742209200620062009491b22094100480de0010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dc6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c94010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dde0120044101742208200720072008491b22084100480dde010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dc50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddf012004410174220b20072007200b491b220b4100480ddf010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dc701200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddf0120044101742209200620062009491b22094100480ddf010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dc8012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c93010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddd0120044101742208200720072008491b22084100480ddd010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dc70120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dde012004410174220b20072007200b491b220b4100480dde010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dc901200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dde0120044101742209200620062009491b22094100480dde010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dca012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c92010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddc0120044101742208200720072008491b22084100480ddc010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dc90120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412f3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddd012004410174220b20072007200b491b220b4100480ddd010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dcb01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddd0120044101742209200620062009491b22094100480ddd010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dcc012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c91010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddb0120044101742208200720072008491b22084100480ddb010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dcb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41303a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddc012004410174220b20072007200b491b220b4100480ddc010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dcd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddc0120044101742209200620062009491b22094100480ddc010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dce012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c90010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dda0120044101742208200720072008491b22084100480dda010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dcd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41313a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddb012004410174220b20072007200b491b220b4100480ddb010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dcf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddb0120044101742209200620062009491b22094100480ddb010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dd0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8f010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd90120044101742208200720072008491b22084100480dd9010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dcf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41323a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dda012004410174220b20072007200b491b220b4100480dda010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dd101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dda0120044101742209200620062009491b22094100480dda010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dd2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8e010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd80120044101742208200720072008491b22084100480dd8010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dd10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41333a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd9012004410174220b20072007200b491b220b4100480dd9010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dd301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd90120044101742209200620062009491b22094100480dd9010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dd4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8d010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd70120044101742208200720072008491b22084100480dd7010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dd30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41343a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd8012004410174220b20072007200b491b220b4100480dd8010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dd501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd80120044101742209200620062009491b22094100480dd8010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dd6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8c010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd60120044101742208200720072008491b22084100480dd6010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dd50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41353a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da3022004410174220b20072007200b491b220b4100480da3020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dd801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da30220044101742209200620062009491b22094100480da3020240024020040d002009102921060c010b200a28020020042009102a21060b2006450dd9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8b010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da10220044101742208200720072008491b22084100480da1020240024020040d002008102921070c010b200a28020020042008102a21070b2007450dd80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41363a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da2022004410174220b20072007200b491b220b4100480da2020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dda01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da20220044101742209200620062009491b22094100480da2020240024020040d002009102921060c010b200a28020020042009102a21060b2006450ddb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8a010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da00220044101742208200720072008491b22084100480da0020240024020040d002008102921070c010b200a28020020042008102a21070b2007450dda0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41373a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da1022004410174220b20072007200b491b220b4100480da1020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450ddc01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da10220044101742209200620062009491b22094100480da1020240024020040d002009102921060c010b200a28020020042009102a21060b2006450ddd012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c89010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9f0220044101742208200720072008491b22084100480d9f020240024020040d002008102921070c010b200a28020020042008102a21070b2007450ddc0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41383a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da0022004410174220b20072007200b491b220b4100480da0020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dde01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da00220044101742209200620062009491b22094100480da0020240024020040d002009102921060c010b200a28020020042009102a21060b2006450ddf012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c88010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9e0220044101742208200720072008491b22084100480d9e020240024020040d002008102921070c010b200a28020020042008102a21070b2007450dde0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41393a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9f022004410174220b20072007200b491b220b4100480d9f020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450de001200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9f0220044101742209200620062009491b22094100480d9f020240024020040d002009102921060c010b200a28020020042009102a21060b2006450de1012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c87010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9d0220044101742208200720072008491b22084100480d9d020240024020040d002008102921070c010b200a28020020042008102a21070b2007450de00120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9e022004410174220b20072007200b491b220b4100480d9e020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450de201200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9e0220044101742209200620062009491b22094100480d9e020240024020040d002009102921060c010b200a28020020042009102a21060b2006450de3012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c86010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9c0220044101742208200720072008491b22084100480d9c020240024020040d002008102921070c010b200a28020020042008102a21070b2007450de20120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9d022004410174220b20072007200b491b220b4100480d9d020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450de401200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9d0220044101742209200620062009491b22094100480d9d020240024020040d002009102921060c010b200a28020020042009102a21060b2006450de5012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c85010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9b0220044101742208200720072008491b22084100480d9b020240024020040d002008102921070c010b200a28020020042008102a21070b2007450de40120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9c022004410174220b20072007200b491b220b4100480d9c020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450de601200220073602042009200b360200200828020021040b2008200441016a360200200720046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021050c010b200441016a22052004490d9c0220044101742209200520052009491b22094100480d9c020240024020040d002009102921050c010b200a28020020042009102a21050b2005450de7012002200536020420082009360200200728020021040b2007200441016a360200200520046a200641807f72200641ff0071200641077622041b3a00002004210620040d000c84010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9a0220044101742208200720072008491b22084100480d9a020240024020040d002008102921070c010b200a28020020042008102a21070b2007450de60120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9b022004410174220b20072007200b491b220b4100480d9b020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450de801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9b0220044101742209200620062009491b22094100480d9b020240024020040d002009102921060c010b200a28020020042009102a21060b2006450de9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c83010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d990220044101742208200720072008491b22084100480d99020240024020040d002008102921070c010b200a28020020042008102a21070b2007450de80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9a022004410174220b20072007200b491b220b4100480d9a020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dea01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9a0220044101742209200620062009491b22094100480d9a020240024020040d002009102921060c010b200a28020020042009102a21060b2006450deb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c82010b0b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d980220044101742208200520052008491b22084100480d98020240024020040d002008102921050c010b200628020020042008102a21050b2005450dea0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a413f3a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d980220044101742208200520052008491b22084100480d98020240024020040d002008102921050c010b200628020020042008102a21050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c80010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d970220044101742208200520052008491b22084100480d97020240024020040d002008102921050c010b200628020020042008102a21050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c0003a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d970220044101742208200520052008491b22084100480d97020240024020040d002008102921050c010b200628020020042008102a21050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c7f0b200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d960220044101742207200520052007491b22074100480d96020240024020040d002007102921050c010b200228020420042007102a21050b2005450dec0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c1003a00002003200620021085042003210220032d0000411a470df0020c7e0b200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d950220044101742206200520052006491b22064100480d95020240024020040d002006102921050c010b200228020420042006102a21050b2005450dec0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c2003a00002003200c20021086042003210220032d0000411a470def020c7d0b200241046a2106200141046a280200210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d940220044101742208200520052008491b22084100480d94020240024020040d002008102921050c010b200628020020042008102a21050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c3003a000002400240200241086a2802002205200828020022046b4104490d00200628020021050c010b200441046a22082004490d940220054101742204200820082004491b22044100480d94020240024020050d002004102921050c010b200628020020052004102a21050b2005450ded0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441046a360200200520046a20073600000c7c0b200241046a2106200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d930220044101742207200520052007491b22074100480d93020240024020040d002007102921050c010b200628020020042007102a21050b2005450ded0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200520046a41c4003a000002400240200241086a2802002205200728020022046b4108490d00200628020021050c010b200441086a22072004490d930220054101742204200720072004491b22044100480d93020240024020050d002004102921050c010b200628020020052004102a21050b2005450dee0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441086a360200200520046a200c3700000c7b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d920220044101742206200520052006491b22064100480d92020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c5003a00000c7a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d910220044101742206200520052006491b22064100480d91020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c6003a00000c790b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d900220044101742206200520052006491b22064100480d90020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c7003a00000c780b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f0220044101742206200520052006491b22064100480d8f020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c8003a00000c770b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e0220044101742206200520052006491b22064100480d8e020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c9003a00000c760b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d0220044101742206200520052006491b22064100480d8d020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ca003a00000c750b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c0220044101742206200520052006491b22064100480d8c020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cb003a00000c740b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b0220044101742206200520052006491b22064100480d8b020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cc003a00000c730b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a0220044101742206200520052006491b22064100480d8a020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cd003a00000c720b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d890220044101742206200520052006491b22064100480d89020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ce003a00000c710b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d880220044101742206200520052006491b22064100480d88020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cf003a00000c700b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d870220044101742206200520052006491b22064100480d87020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d0003a00000c6f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d860220044101742206200520052006491b22064100480d86020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d1003a00000c6e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d850220044101742206200520052006491b22064100480d85020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d2003a00000c6d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d840220044101742206200520052006491b22064100480d84020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d3003a00000c6c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d830220044101742206200520052006491b22064100480d83020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d4003a00000c6b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d820220044101742206200520052006491b22064100480d82020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d5003a00000c6a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d810220044101742206200520052006491b22064100480d81020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d6003a00000c690b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d800220044101742206200520052006491b22064100480d80020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d7003a00000c680b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff0120044101742206200520052006491b22064100480dff010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d8003a00000c670b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe0120044101742206200520052006491b22064100480dfe010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d9003a00000c660b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd0120044101742206200520052006491b22064100480dfd010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41da003a00000c650b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41db003a00000c640b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dc003a00000c630b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dd003a00000c620b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41de003a00000c610b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41df003a00000c600b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e0003a00000c5f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e1003a00000c5e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e2003a00000c5d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e3003a00000c5c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e4003a00000c5b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e5003a00000c5a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e6003a00000c590b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df00120044101742206200520052006491b22064100480df0010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e7003a00000c580b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490def0120044101742206200520052006491b22064100480def010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e8003a00000c570b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dba0220044101742206200520052006491b22064100480dba020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e9003a00000c560b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db90220044101742206200520052006491b22064100480db9020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ea003a00000c550b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db80220044101742206200520052006491b22064100480db8020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41eb003a00000c540b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db70220044101742206200520052006491b22064100480db7020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ec003a00000c530b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db60220044101742206200520052006491b22064100480db6020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ed003a00000c520b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db50220044101742206200520052006491b22064100480db5020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ee003a00000c510b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db40220044101742206200520052006491b22064100480db4020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ef003a00000c500b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db30220044101742206200520052006491b22064100480db3020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f0003a00000c4f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db20220044101742206200520052006491b22064100480db2020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f1003a00000c4e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db10220044101742206200520052006491b22064100480db1020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f2003a00000c4d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db00220044101742206200520052006491b22064100480db0020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f3003a00000c4c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daf0220044101742206200520052006491b22064100480daf020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f4003a00000c4b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dae0220044101742206200520052006491b22064100480dae020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f5003a00000c4a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dad0220044101742206200520052006491b22064100480dad020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f6003a00000c490b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dac0220044101742206200520052006491b22064100480dac020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f7003a00000c480b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dab0220044101742206200520052006491b22064100480dab020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f8003a00000c470b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daa0220044101742206200520052006491b22064100480daa020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f9003a00000c460b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da90220044101742206200520052006491b22064100480da9020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fa003a00000c450b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da80220044101742206200520052006491b22064100480da8020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fb003a00000c440b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da70220044101742206200520052006491b22064100480da7020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fc003a00000c430b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da60220044101742206200520052006491b22064100480da6020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fd003a00000c420b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da50220044101742206200520052006491b22064100480da5020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fe003a00000c410b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da40220044101742206200520052006491b22064100480da4020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ff003a00000c400b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da30220044101742206200520052006491b22064100480da3020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4180013a00000c3f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da20220044101742206200520052006491b22064100480da2020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4181013a00000c3e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da10220044101742206200520052006491b22064100480da1020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4182013a00000c3d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da00220044101742206200520052006491b22064100480da0020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4183013a00000c3c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9f0220044101742206200520052006491b22064100480d9f020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4184013a00000c3b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9e0220044101742206200520052006491b22064100480d9e020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4185013a00000c3a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9d0220044101742206200520052006491b22064100480d9d020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4186013a00000c390b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9c0220044101742206200520052006491b22064100480d9c020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4187013a00000c380b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9b0220044101742206200520052006491b22064100480d9b020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4188013a00000c370b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9a0220044101742206200520052006491b22064100480d9a020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4189013a00000c360b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d990220044101742206200520052006491b22064100480d99020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418a013a00000c350b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d980220044101742206200520052006491b22064100480d98020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418b013a00000c340b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d970220044101742206200520052006491b22064100480d97020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418c013a00000c330b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d960220044101742206200520052006491b22064100480d96020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418d013a00000c320b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d950220044101742206200520052006491b22064100480d95020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418e013a00000c310b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d940220044101742206200520052006491b22064100480d94020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418f013a00000c300b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d930220044101742206200520052006491b22064100480d93020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4190013a00000c2f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d920220044101742206200520052006491b22064100480d92020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4191013a00000c2e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d910220044101742206200520052006491b22064100480d91020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4192013a00000c2d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d900220044101742206200520052006491b22064100480d90020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4193013a00000c2c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f0220044101742206200520052006491b22064100480d8f020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4194013a00000c2b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e0220044101742206200520052006491b22064100480d8e020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4195013a00000c2a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d0220044101742206200520052006491b22064100480d8d020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4196013a00000c290b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c0220044101742206200520052006491b22064100480d8c020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4197013a00000c280b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b0220044101742206200520052006491b22064100480d8b020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4198013a00000c270b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a0220044101742206200520052006491b22064100480d8a020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4199013a00000c260b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d890220044101742206200520052006491b22064100480d89020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419a013a00000c250b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d880220044101742206200520052006491b22064100480d88020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419b013a00000c240b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d870220044101742206200520052006491b22064100480d87020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419c013a00000c230b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d860220044101742206200520052006491b22064100480d86020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419d013a00000c220b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d850220044101742206200520052006491b22064100480d85020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419e013a00000c210b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d840220044101742206200520052006491b22064100480d84020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419f013a00000c200b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d830220044101742206200520052006491b22064100480d83020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a0013a00000c1f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d820220044101742206200520052006491b22064100480d82020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a1013a00000c1e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d810220044101742206200520052006491b22064100480d81020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a2013a00000c1d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d800220044101742206200520052006491b22064100480d80020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a3013a00000c1c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff0120044101742206200520052006491b22064100480dff010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a4013a00000c1b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe0120044101742206200520052006491b22064100480dfe010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a5013a00000c1a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd0120044101742206200520052006491b22064100480dfd010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a6013a00000c190b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a7013a00000c180b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a8013a00000c170b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a9013a00000c160b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41aa013a00000c150b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ab013a00000c140b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ac013a00000c130b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ad013a00000c120b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ae013a00000c110b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41af013a00000c100b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b0013a00000c0f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b1013a00000c0e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b2013a00000c0d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df00120044101742206200520052006491b22064100480df0010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b3013a00000c0c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b4013a00000c0b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b5013a00000c0a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b6013a00000c090b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b7013a00000c080b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b8013a00000c070b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b9013a00000c060b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ba013a00000c050b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bb013a00000c040b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bc013a00000c030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bd013a00000c020b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41be013a00000c010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bf013a00000b2000411a3a000020012d00004109470df201200141086a28020041ffffffff0371450df201200141046a280200102e0cf2010b20064101102c000b20064101102c000b20084101102c000b20084101102c000b20084101102c000b20084101102c000b20084101102c000b20084101102c000b20064101102c000b20064101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20064101102c000b20084101102c000b20064101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20064101102c000b20064101102c000b20064101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b102d000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b20084101102c000b20084101102c000b20084101102c000b20074101102c000b20064101102c000b20084101102c000b20044101102c000b20074101102c000b20044101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b102d000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b102d000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b102d000b20002003290300370200200041086a200341086a290300370200200941ffffffff0371450d01200b102e0c010b20002002290200370200200041086a200241086a29020037020020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200341106a24000bb60301057f2004410c6a2105200441086a2106024002400240034002400240200628020020052802002207460d00200428020421080c010b200741016a22082007490d0420074101742209200820082009491b22094100480d040240024020070d002009102921080c010b200428020420072009102a21080b2008450d022004200836020420062009360200200528020021070b2005200741016a360200200820076a200141807f72200141ff0071200141077622071b3a00002007210120070d000b024020022003460d002004410c6a2105200441086a2106034020022802002101034002400240200628020020052802002207460d00200428020421080c010b200741016a22082007490d0620074101742209200820082009491b22094100480d060240024020070d002009102921080c010b200428020420072009102a21080b2008450d052004200836020420062009360200200528020021070b2005200741016a360200200820076a200141807f72200141ff0071200141077622071b3a00002007210120070d000b200241046a22022003470d000b0b2000411a3a00000f0b20094101102c000b20094101102c000b102d000bc30301067f200141c000712103200141ff0071210402400240024002400240200141077522050d002003450d010b2002410c6a2106200241086a2107034002402005417f470d00200341ff01710d020b02400240200728020020062802002208460d00200228020421030c010b200841016a22032008490d0520084101742204200320032004491b22044100480d050240024020080d002004102921030c010b200228020420082004102a21030b2003450d032002200336020420072004360200200628020021080b2006200841016a360200200320086a200141807f723a0000200541c000712103200541ff007121042005210120054107752208210520080d002008210520030d000b0b02400240200241086a2802002002410c6a2802002205460d00200228020421080c010b200541016a22082005490d0320054101742203200820082003491b22034100480d030240024020050d002003102921080c010b200228020420052003102a21080b2008450d0220022008360204200241086a20033602002002410c6a28020021050b2002410c6a200541016a360200200820056a20043a00002000411a3a00000f0b20044101102c000b20034101102c000b102d000bc30301067f2001a7220341c000712104200341ff0071210502400240024002400240200142078722014200520d002004450d010b2002410c6a2106200241086a2107034002402001427f520d00200441ff01710d020b02400240200728020020062802002204460d00200228020421050c010b200441016a22052004490d0520044101742208200520052008491b22084100480d050240024020040d002008102921050c010b200228020420042008102a21050b2005450d032002200536020420072008360200200628020021040b2006200441016a360200200520046a200341807f723a00002001a7220341c000712104200341ff00712105200142078722014200520d0020040d000b0b02400240200241086a2802002002410c6a2802002204460d00200228020421030c010b200441016a22032004490d0320044101742206200320032006491b22064100480d030240024020040d002006102921030c010b200228020420042006102a21030b2003450d0220022003360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200320046a20053a00002000411a3a00000f0b20084101102c000b20064101102c000b102d000bcf03010a7f230041306b22022400200241216a220341076a210441002105410021064100210741002108410821090240024002400340200241186a2001108804024020022802184101470d002000200229021c370204200041013602002000410c6a200241186a410c6a29020037020002402007450d00200921070340024020072d00004109470d00200741086a28020041ffffffff0371450d00200741046a280200102e0b200741106a2107200641706a22060d000b0b2008450d042009102e0c040b200220032900003703082002200429000037000f20022d0020210a2002200229000f37001f200220022903083703180240024020072008470d00200741016a220b2007490d032005200b200b2005491b220841ffffffff00712008470d032008410474220b4100480d030240024020070d00200b102921090c010b20092006200b102a21090b2009450d010b200920066a220b200a3a0000200b41016a2002290318370000200b41086a200229001f370000200541026a2105200641106a2106200741016a2107200a41ff01714106460d030c010b0b200b4108102c000b102d000b20002009360204200041003602002000410c6a2007360200200041086a20083602000b200241306a24000b99b601020a7f017e230041f0006b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802082203200128020c2204460d00200441016a22052004490d02200320054f0d0120052003105e000b200241013a0048200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a108a04200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c610b2001280200220620046a2d000021072001410c6a2208200536020002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200741bf014b0d0020070ec001b702b702010203b70200000000000405060708090a00000000000000000b0c000000000d0e0f101100000012131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901b7020b2000410b3a000420004101360200200041056a20073a00000cb9020b024002400240024002400240024020032005460d00200441026a21092005417f460de00120032009490da102200620056a2c00002101200820093602004100210a0240200141004e0d00411821090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410221070cbd020b20090e0404030506040b200241013a0047200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a108a04200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cbc020b4102210a410221070cb8020b4103210a410221070cb7020b4101210a0b410221070cb5020b024002400240024002400240024020032005460d00200441026a21092005417f460de00120032009490da102200620056a2c00002101200820093602004100210a0240200141004e0d00411821090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410321070cbc020b20090e0404030506040b200241013a0047200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a108a04200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cbb020b4102210a410321070cb7020b4103210a410321070cb6020b4101210a0b410321070cb4020b024002400240024002400240024020032005460d00200441026a21092005417f460de00120032009490da102200620056a2c00002101200820093602004100210a0240200141004e0d00411821090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410421070cbb020b20090e0404030506040b200241013a0047200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a108a04200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cba020b4102210a410421070cb6020b4103210a410421070cb5020b4101210a0b410421070cb3020b410621070cb2020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddd012003200541016a22074f0d01200541016a2003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb5020b410721070cb1020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddd012003200541016a22074f0d01200541016a2003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb4020b410821070cb0020b200241d8006a2001108b0441042109200228025822064101460da201200241e0006a280200210b200228025c210302400240200241e4006a28020022040d00410021074100210a0c010b0240024020044102742205410275220741ffffffff03712007470d0020054100480d002005102922090d0120054104102c000b102d000b200441027421042005417c6a210a410021050340200920056a200320056a2802003602002004200541046a2205470d000b200a41027641016a210a0b0240200b450d002003102e0b20022d005c4105470dae022006450dae0220022802640da3010cae020b410a21070cae020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddb012003200541016a22074f0d01200541016a2003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb1020b410b21070cad020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddb012003200541016a22044f0d01200541016a2003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010c020b200620056a2d0000210720082004360200200741ff00712001411f71742009722109200141076a2101200421052007418001710d000b20014120490d01410d210120074110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb0020b0240024020032004460d00200441016a22012004490dd901200320014f0d0120012003105e000b200241013a0048200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a108a04200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000cb0020b200620046a2d0000210520082001360200024020050d00410c21074100210a0cad020b200041163a000420004101360200200041056a20053a00000caf020b410d21070cab020b410e21070caa020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460dda012003200541016a22074f0d01200541016a2003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cad020b410f21070ca9020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460dda012003200541016a22074f0d01200541016a2003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cac020b411021070ca8020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460dda012003200541016a22074f0d01200541016a2003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cab020b411121070ca7020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460dda012003200541016a22074f0d01200541016a2003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000caa020b411221070ca6020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460dda012003200541016a22074f0d01200541016a2003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000ca9020b411321070ca5020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ddb01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca8020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9c010b20032001460d9a012001417f460dd7012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9b010b200aad210c411421070ca4020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ddc01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca7020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9d010b20032001460d9b012001417f460dd8012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9c010b200aad210c411521070ca3020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ddd01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca6020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9e010b20032001460d9c012001417f460dd9012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9d010b200aad210c411621070ca2020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dde01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca5020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9f010b20032001460d9d012001417f460dda012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9e010b200aad210c411721070ca1020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ddf01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca4020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca0010b20032001460d9e012001417f460ddb012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9f010b200aad210c411821070ca0020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de001200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca3020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca1010b20032001460d9f012001417f460ddc012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da0010b200aad210c411921070c9f020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de101200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca2020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca2010b20032001460da0012001417f460ddd012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da1010b200aad210c411a21070c9e020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de201200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca1020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca3010b20032001460da1012001417f460dde012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da2010b200aad210c411b21070c9d020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de301200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca0020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca4010b20032001460da2012001417f460ddf012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da3010b200aad210c411c21070c9c020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de401200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9f020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca5010b20032001460da3012001417f460de0012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da4010b200aad210c411d21070c9b020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de501200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9e020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca6010b20032001460da4012001417f460de1012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da5010b200aad210c411e21070c9a020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de601200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9d020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca7010b20032001460da5012001417f460de2012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da6010b200aad210c411f21070c99020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de701200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca8010b20032001460da6012001417f460de3012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b41202107024020054120490d00410d21012004410f4b0da7010b200aad210c0c98020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de801200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9b020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca9010b20032001460da7012001417f460de4012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da8010b200aad210c412121070c97020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de901200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9a020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010caa010b20032001460da8012001417f460de5012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da9010b200aad210c412221070c96020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dea01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c99020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cab010b20032001460da9012001417f460de6012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0daa010b200aad210c412321070c95020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450deb01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c98020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cac010b20032001460daa012001417f460de7012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dab010b200aad210c412421070c94020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dec01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c97020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cad010b20032001460dab012001417f460de8012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dac010b200aad210c412521070c93020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ded01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c96020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cae010b20032001460dac012001417f460de9012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dad010b200aad210c412621070c92020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dee01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c95020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010caf010b20032001460dad012001417f460dea012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dae010b200aad210c412721070c91020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450def01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c94020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cb0010b20032001460dae012001417f460deb012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0daf010b200aad210c412821070c90020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450df001200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c93020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cb1010b20032001460daf012001417f460dec012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0db0010b200aad210c412921070c8f020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450df101200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c92020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cb2010b20032001460db0012001417f460ded012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0db1010b200aad210c412a21070c8e020b0240024020032005460d00200441026a21012005417f460dee01200320014f0d0120012003105e000b200241013a0048200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a108a04200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c91020b200620056a2d0000210920082001360200024020090d00412b21074100210a0c8e020b200041153a000420004101360200200041056a20093a00000c90020b0240024020032005460d00200441026a21012005417f460dee01200320014f0d0120012003105e000b200241013a0048200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a108a04200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c90020b200620056a2d0000210920082001360200024020090d00412c21074100210a0c8d020b200041153a000420004101360200200041056a20093a00000c8f020b41002101410021090240024002400340410d210a2001411f4b0d010240024020032005460d002005417f460df2012003200541016a22074f0d01200541016a2003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a044105210a0c020b200620056a2c0000210420082007360200200441ff00712001411f71742009722109200141076a21012007210520044100480d000b200441c00071210502402001411f4b0d0020050d020b0240024020014120490d0020050d010b200441ff01714108490d0320014120490d032005450d010c030b20044180017241ff017141f7014b0d020b2000200a36020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c90020b2009417f2001411f71747221090b412d21070c8b020b4200210c4100210102400240024002400340410e21072001413f4b0d010240024020032005460d002005417f460df3012003200541016a22094f0d01200541016a2003105e000b200241013a0008200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241086a360238200241286a200241d8006a108a042002290328210c20022802302101410521070c030b200620056a2d0000210420082009360200200441ff0071220aad2001413f71ad86200c84210c200141076a210120092105200441187441187522094100480d000b200941c00071210502402001413f4b0d0020050d030b02400240200141c000490d0020050d010b200141c000490d0420090d010c040b200a41ff00460d030b0b200020073a0004200020022f00183b000520004101360200200041106a2001360200200041086a200c370200200041076a2002411a6a2d00003a00000c8f020b200c427f2001413f71ad8684210c0b412e21070c8a020b02400240200320056b4104490d00200441056a21012005417b4b0dee01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a0420004281808080d000370300200041086a2002290228370200200041106a200241286a41086a2802003602000c8d020b200620056a280000210920082001360200412f21070c89020b02400240200320056b4108490d00200441096a2101200541774b0dee01200320014f0d0120012003105e000b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a042002290328210c200041106a2002280230360200200041086a200c37020020004281808080d0003703000c8c020b200620056a290000210c20082001360200413021070c88020b413121070c87020b413221070c86020b413321070c85020b413421070c84020b413521070c83020b413621070c82020b413721070c81020b413821070c80020b413921070cff010b413a21070cfe010b413b21070cfd010b413c21070cfc010b413d21070cfb010b413e21070cfa010b413f21070cf9010b41c00021070cf8010b41c10021070cf7010b41c20021070cf6010b41c30021070cf5010b41c40021070cf4010b41c50021070cf3010b41c60021070cf2010b41c70021070cf1010b41c80021070cf0010b41c90021070cef010b41ca0021070cee010b41cb0021070ced010b41cc0021070cec010b41cd0021070ceb010b41ce0021070cea010b41cf0021070ce9010b41d00021070ce8010b41d10021070ce7010b41d20021070ce6010b41d30021070ce5010b41d40021070ce4010b41d50021070ce3010b41d60021070ce2010b41d70021070ce1010b41d80021070ce0010b41d90021070cdf010b41da0021070cde010b41db0021070cdd010b41dc0021070cdc010b41dd0021070cdb010b41de0021070cda010b41df0021070cd9010b41e00021070cd8010b41e10021070cd7010b41e20021070cd6010b41e30021070cd5010b41e40021070cd4010b41e50021070cd3010b41e60021070cd2010b41e70021070cd1010b41e80021070cd0010b41e90021070ccf010b41ea0021070cce010b41eb0021070ccd010b41ec0021070ccc010b41ed0021070ccb010b41ee0021070cca010b41ef0021070cc9010b41f00021070cc8010b41f10021070cc7010b41f20021070cc6010b41f30021070cc5010b41f40021070cc4010b41f50021070cc3010b41f60021070cc2010b41f70021070cc1010b41f80021070cc0010b41f90021070cbf010b41fa0021070cbe010b41fb0021070cbd010b41fc0021070cbc010b41fd0021070cbb010b41fe0021070cba010b41ff0021070cb9010b41800121070cb8010b41810121070cb7010b41820121070cb6010b41830121070cb5010b41840121070cb4010b41850121070cb3010b41860121070cb2010b41870121070cb1010b41880121070cb0010b41890121070caf010b418a0121070cae010b418b0121070cad010b418c0121070cac010b418d0121070cab010b418e0121070caa010b418f0121070ca9010b41900121070ca8010b41910121070ca7010b41920121070ca6010b41930121070ca5010b41940121070ca4010b41950121070ca3010b41960121070ca2010b41970121070ca1010b41980121070ca0010b41990121070c9f010b419a0121070c9e010b419b0121070c9d010b419c0121070c9c010b419d0121070c9b010b419e0121070c9a010b419f0121070c99010b41a00121070c98010b41a10121070c97010b41a20121070c96010b41a30121070c95010b41a40121070c94010b41a50121070c93010b41a60121070c92010b41a70121070c91010b41a80121070c90010b41a90121070c8f010b41aa0121070c8e010b41ab0121070c8d010b200041013602002000200241d8006a41047222012902003702042000410c6a200141086a2902003702000c8f010b2002280260102e0c8a010b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c8c010b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c8a010b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c88010b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c86010b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c84010b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c82010b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c80010b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c7e0b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c7c0b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c7a0b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c780b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c760b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c740b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c720b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c700b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c6e0b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c6c0b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c6a0b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c680b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c660b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c640b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c620b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c600b417f20051035000b417f20091035000b417f20091035000b417f20091035000b417f200541016a1035000b417f200541016a1035000b417f200541016a1035000b417f200541016a1035000b417f20011035000b417f200541016a1035000b417f200541016a1035000b417f200541016a1035000b417f200541016a1035000b417f200541016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f200141016a1035000b417f20011035000b417f20011035000b417f200541016a1035000b417f200541016a1035000b200520011035000b200520011035000b20092003105e000b20092003105e000b20092003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b200141016a2003105e000b0240024002400240024002402007200a470d002007210a0c010b2007200a490d010240200a0d004100210a024020070d00410421090c020b2009102e410421090c010b20092007410274200a4102742205102a2209450d020b4100210541002107034002402005411f4d0d00410f21010c080b20012802082206200128020c2203460d06200341016a22042003490d0320062004490d04200128020020036a2d0000210320082004360200200341ff00712005411f71742007722107200541076a21052003418001710d000b024020054120490d00410d21012003410f4b0d070b2007ad422086200aad84210c410921070c040b41809cc5001058000b20054104102c000b417f20041035000b20042006105e000b20004100360200200041106a200c3703002000410c6a2009360200200041096a200a3a0000200041086a20073a00000c020b200241013a0018200241ec006a41013602002002420137025c200241e8d4c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a108a04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a280200360200200a41ffffffff0371450d002009102e0b200241f0006a24000bd30101017f230041106b22022400024002400240024020002d00000e03010200010b2002200128021841c4d4c500410b2001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c020b2002200128021841cfd4c500410c2001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c010b2002200128021841dbd4c500410d2001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040b200241106a240020000b890301067f230041306b2202240020012802002103024002402001280204220441037422050d00410021060c010b200341046a2107410021060340200728020020066a2106200741086a2107200541786a22050d000b0b024002400240024002400240200141146a2802000d00200621070c010b02402004450d00024002402006410f4b0d002003280204450d010b200620066a220720064f0d020b4101210541002107200241086a21060c020b41fce8c500410041001038000b2007417f4c0d01200241086a2106024020070d0041012105410021070c010b200710292205450d020b200241003602102002200736020c200220053602082002200241086a360214200241186a41106a200141106a290200370300200241186a41086a200141086a29020037030020022001290200370318200241146a418ce9c500200241186a10b5040d0220002006290200370200200041086a200641086a280200360200200241306a24000f0b1032000b20074101102c000b41a4e9c5004133200241186a41d8e9c5001053000bf30603067f017e067f230041c0006b2202240041002103410021040240024002400240024002400240034002402003411f4d0d00410f21030c020b0240024020012802082205200128020c2206460d00200641016a22072006490d05200520074f0d0120072005105e000b200241013a000f2002413c6a41013602002002420137022c200241e8d4c500360228200241213602142002200241106a36023820022002410f6a360210200241186a200241286a108a04410521030c020b200128020020066a2d000021062001200736020c200641ff00712003411f71742004722104200341076a21032006418001710d000b20034120490d01410d210320064110490d010b200241086a200241186a41086a280200220136020020022002290218220837030020002003360204200041086a2008370200200041106a2001360200200041013602000c050b410421090240024020040d004100210a0c010b4100210a4100210b0340200b220c41016a210b4100210341002105024002400240034002402003411f4d0d00410f21010c020b024002402001280208220d200128020c2206460d00200641016a22072006490d09200d20074f0d012007200d105e000b200241013a00002002413c6a41013602002002420137022c200241e8d4c500360228200241213602142002200241106a36023820022002360210200241186a200241286a108a0420022802182103200228021c2106200228022021074100210e410521010c030b200128020020066a2d000021062001200736020c200641ff00712003411f71742005722105200341076a21032006418001710d000b20034120490d0220064110490d02410d21010b0b20004101360200200041106a20073602002000410c6a2006360200200041086a20033602002000200e410874200172360204200a450d072009102e0c070b0240200a200c470d00200a4101742203200a41016a220620062003491b220341ffffffff03712003470d06200341027422064100480d0602400240200a0d002006102921090c010b2009200a4102742006102a21090b2009450d052003210a0b2005410876210e2009200c4102746a2005360200200b2004470d000b0b20002009360204200041003602002000410c6a2004360200200041086a200a3602000c040b417f20071035000b417f20071035000b20064104102c000b102d000b200241c0006a24000bf6d60202097f017e230041106b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000eac01000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab01000b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102921050c010b200228020420042006102a21050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41003a00000cab010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102921050c010b200228020420042006102a21050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41013a00000caa010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df50120044101742208200520052008491b22084100480df5010240024020040d002008102921050c010b200628020020042008102a21050b2005450dad0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41023a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df50120044101742208200520052008491b22084100480df5010240024020040d002008102921050c010b200628020020042008102a21050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca9010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df40120044101742208200520052008491b22084100480df4010240024020040d002008102921050c010b200628020020042008102a21050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41033a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df40120044101742208200520052008491b22084100480df4010240024020040d002008102921050c010b200628020020042008102a21050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca8010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df30120044101742208200520052008491b22084100480df3010240024020040d002008102921050c010b200628020020042008102a21050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41043a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df30120044101742208200520052008491b22084100480df3010240024020040d002008102921050c010b200628020020042008102a21050b2005450db00120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca7010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102921050c010b200228020420042006102a21050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41053a00000ca6010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102921050c010b200228020420042006102a21050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410b3a00000ca5010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490df00120044101742207200620062007491b22074100480df0010240024020040d002007102921060c010b200928020020042007102a21060b2006450db00120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410c3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df1012004410174220a20062006200a491b220a4100480df1010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db201200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca5010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490def0120044101742207200620062007491b22074100480def010240024020040d002007102921060c010b200928020020042007102a21060b2006450db10120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410d3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df0012004410174220a20062006200a491b220a4100480df0010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db301200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca4010b0b200241046a210a2001410c6a2802002104200141086a2802002109200141046a280200210b02400240200241086a2802002002410c6a2802002201460d00200a28020021050c010b200141016a22052001490dee0120014101742206200520052006491b22064100480dee010240024020010d002006102921050c010b200a28020020012006102a21050b2005450db20120022005360204200241086a20063602002002410c6a28020021010b2002410c6a2206200141016a360200200520016a410e3a000020032009200b200b20094102746a200210840420032d0000411a470d9303200241086a2107034002400240200728020020062802002201460d00200a28020021050c010b200141016a22052001490def0120014101742208200520052008491b22084100480def010240024020010d002008102921050c010b200a28020020012008102a21050b2005450db4012002200536020420072008360200200628020021010b2006200141016a360200200520016a200441807f72200441ff0071200441077622011b3a00002001210420010d000b0240200941ffffffff0371450d00200b102e0b2000411a3a00000c95030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490ded0120044101742206200520052006491b22064100480ded010240024020040d002006102921050c010b200228020420042006102a21050b2005450db30120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410f3a00000ca1010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490dec0120044101742207200620062007491b22074100480dec010240024020040d002007102921060c010b200928020020042007102a21060b2006450db30120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41103a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490ded012004410174220a20062006200a491b220a4100480ded010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db501200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca1010b0b200241046a2109200141046a280200210520012d0001210b02400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490deb0120044101742207200620062007491b22074100480deb010240024020040d002007102921060c010b200928020020042007102a21060b2006450db40120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41113a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490dec012004410174220a20062006200a491b220a4100480dec010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db601200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b02400240200241086a2802002002410c6a2802002204460d00200928020021050c010b200441016a22052004490deb0120044101742206200520052006491b22064100480deb010240024020040d002006102921050c010b200928020020042006102a21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a200b3a00000c9f010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dea0120044101742206200520052006491b22064100480dea010240024020040d002006102921050c010b200228020420042006102a21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411a3a00000c9e010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490de90120044101742206200520052006491b22064100480de9010240024020040d002006102921050c010b200228020420042006102a21050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411b3a00000c9d010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de80120044101742207200620062007491b22074100480de8010240024020040d002007102921060c010b200928020020042007102a21060b2006450db60120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41203a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de9012004410174220a20062006200a491b220a4100480de9010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db801200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9d010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de70120044101742207200620062007491b22074100480de7010240024020040d002007102921060c010b200928020020042007102a21060b2006450db70120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41213a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de8012004410174220a20062006200a491b220a4100480de8010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450db901200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9c010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de60120044101742207200620062007491b22074100480de6010240024020040d002007102921060c010b200928020020042007102a21060b2006450db80120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41223a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de7012004410174220a20062006200a491b220a4100480de7010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450dba01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9b010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de50120044101742207200620062007491b22074100480de5010240024020040d002007102921060c010b200928020020042007102a21060b2006450db90120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41233a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de6012004410174220a20062006200a491b220a4100480de6010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450dbb01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9a010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de40120044101742207200620062007491b22074100480de4010240024020040d002007102921060c010b200928020020042007102a21060b2006450dba0120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41243a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de5012004410174220a20062006200a491b220a4100480de5010240024020040d00200a102921060c010b20092802002004200a102a21060b2006450dbc01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c99010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de30120044101742208200720072008491b22084100480de3010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dbb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41283a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de4012004410174220b20072007200b491b220b4100480de4010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dbd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de40120044101742209200620062009491b22094100480de4010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dbe012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c98010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de20120044101742208200720072008491b22084100480de2010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dbd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41293a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de3012004410174220b20072007200b491b220b4100480de3010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dbf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de30120044101742209200620062009491b22094100480de3010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dc0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c97010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de10120044101742208200720072008491b22084100480de1010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dbf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de2012004410174220b20072007200b491b220b4100480de2010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dc101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de20120044101742209200620062009491b22094100480de2010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dc2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c96010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de00120044101742208200720072008491b22084100480de0010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dc10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de1012004410174220b20072007200b491b220b4100480de1010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dc301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de10120044101742209200620062009491b22094100480de1010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dc4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c95010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddf0120044101742208200720072008491b22084100480ddf010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dc30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de0012004410174220b20072007200b491b220b4100480de0010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dc501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de00120044101742209200620062009491b22094100480de0010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dc6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c94010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dde0120044101742208200720072008491b22084100480dde010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dc50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddf012004410174220b20072007200b491b220b4100480ddf010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dc701200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddf0120044101742209200620062009491b22094100480ddf010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dc8012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c93010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddd0120044101742208200720072008491b22084100480ddd010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dc70120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dde012004410174220b20072007200b491b220b4100480dde010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dc901200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dde0120044101742209200620062009491b22094100480dde010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dca012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c92010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddc0120044101742208200720072008491b22084100480ddc010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dc90120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412f3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddd012004410174220b20072007200b491b220b4100480ddd010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dcb01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddd0120044101742209200620062009491b22094100480ddd010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dcc012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c91010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddb0120044101742208200720072008491b22084100480ddb010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dcb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41303a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddc012004410174220b20072007200b491b220b4100480ddc010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dcd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddc0120044101742209200620062009491b22094100480ddc010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dce012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c90010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dda0120044101742208200720072008491b22084100480dda010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dcd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41313a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddb012004410174220b20072007200b491b220b4100480ddb010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dcf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddb0120044101742209200620062009491b22094100480ddb010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dd0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8f010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd90120044101742208200720072008491b22084100480dd9010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dcf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41323a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dda012004410174220b20072007200b491b220b4100480dda010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dd101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dda0120044101742209200620062009491b22094100480dda010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dd2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8e010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd80120044101742208200720072008491b22084100480dd8010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dd10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41333a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd9012004410174220b20072007200b491b220b4100480dd9010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dd301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd90120044101742209200620062009491b22094100480dd9010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dd4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8d010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd70120044101742208200720072008491b22084100480dd7010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dd30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41343a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd8012004410174220b20072007200b491b220b4100480dd8010240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dd501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd80120044101742209200620062009491b22094100480dd8010240024020040d002009102921060c010b200a28020020042009102a21060b2006450dd6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8c010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd60120044101742208200720072008491b22084100480dd6010240024020040d002008102921070c010b200a28020020042008102a21070b2007450dd50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41353a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da3022004410174220b20072007200b491b220b4100480da3020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dd801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da30220044101742209200620062009491b22094100480da3020240024020040d002009102921060c010b200a28020020042009102a21060b2006450dd9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8b010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da10220044101742208200720072008491b22084100480da1020240024020040d002008102921070c010b200a28020020042008102a21070b2007450dd80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41363a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da2022004410174220b20072007200b491b220b4100480da2020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dda01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da20220044101742209200620062009491b22094100480da2020240024020040d002009102921060c010b200a28020020042009102a21060b2006450ddb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8a010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da00220044101742208200720072008491b22084100480da0020240024020040d002008102921070c010b200a28020020042008102a21070b2007450dda0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41373a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da1022004410174220b20072007200b491b220b4100480da1020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450ddc01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da10220044101742209200620062009491b22094100480da1020240024020040d002009102921060c010b200a28020020042009102a21060b2006450ddd012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c89010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9f0220044101742208200720072008491b22084100480d9f020240024020040d002008102921070c010b200a28020020042008102a21070b2007450ddc0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41383a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da0022004410174220b20072007200b491b220b4100480da0020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dde01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da00220044101742209200620062009491b22094100480da0020240024020040d002009102921060c010b200a28020020042009102a21060b2006450ddf012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c88010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9e0220044101742208200720072008491b22084100480d9e020240024020040d002008102921070c010b200a28020020042008102a21070b2007450dde0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41393a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9f022004410174220b20072007200b491b220b4100480d9f020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450de001200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9f0220044101742209200620062009491b22094100480d9f020240024020040d002009102921060c010b200a28020020042009102a21060b2006450de1012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c87010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9d0220044101742208200720072008491b22084100480d9d020240024020040d002008102921070c010b200a28020020042008102a21070b2007450de00120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9e022004410174220b20072007200b491b220b4100480d9e020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450de201200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9e0220044101742209200620062009491b22094100480d9e020240024020040d002009102921060c010b200a28020020042009102a21060b2006450de3012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c86010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9c0220044101742208200720072008491b22084100480d9c020240024020040d002008102921070c010b200a28020020042008102a21070b2007450de20120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9d022004410174220b20072007200b491b220b4100480d9d020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450de401200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9d0220044101742209200620062009491b22094100480d9d020240024020040d002009102921060c010b200a28020020042009102a21060b2006450de5012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c85010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9b0220044101742208200720072008491b22084100480d9b020240024020040d002008102921070c010b200a28020020042008102a21070b2007450de40120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9c022004410174220b20072007200b491b220b4100480d9c020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450de601200220073602042009200b360200200828020021040b2008200441016a360200200720046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021050c010b200441016a22052004490d9c0220044101742209200520052009491b22094100480d9c020240024020040d002009102921050c010b200a28020020042009102a21050b2005450de7012002200536020420082009360200200728020021040b2007200441016a360200200520046a200641807f72200641ff0071200641077622041b3a00002004210620040d000c84010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9a0220044101742208200720072008491b22084100480d9a020240024020040d002008102921070c010b200a28020020042008102a21070b2007450de60120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9b022004410174220b20072007200b491b220b4100480d9b020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450de801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9b0220044101742209200620062009491b22094100480d9b020240024020040d002009102921060c010b200a28020020042009102a21060b2006450de9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c83010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d990220044101742208200720072008491b22084100480d99020240024020040d002008102921070c010b200a28020020042008102a21070b2007450de80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9a022004410174220b20072007200b491b220b4100480d9a020240024020040d00200b102921070c010b200a2802002004200b102a21070b2007450dea01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9a0220044101742209200620062009491b22094100480d9a020240024020040d002009102921060c010b200a28020020042009102a21060b2006450deb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c82010b0b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d980220044101742208200520052008491b22084100480d98020240024020040d002008102921050c010b200628020020042008102a21050b2005450dea0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a413f3a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d980220044101742208200520052008491b22084100480d98020240024020040d002008102921050c010b200628020020042008102a21050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c80010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d970220044101742208200520052008491b22084100480d97020240024020040d002008102921050c010b200628020020042008102a21050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c0003a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d970220044101742208200520052008491b22084100480d97020240024020040d002008102921050c010b200628020020042008102a21050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c7f0b200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d960220044101742207200520052007491b22074100480d96020240024020040d002007102921050c010b200228020420042007102a21050b2005450dec0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c1003a00002003200620021085042003210220032d0000411a470df0020c7e0b200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d950220044101742206200520052006491b22064100480d95020240024020040d002006102921050c010b200228020420042006102a21050b2005450dec0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c2003a00002003200c20021086042003210220032d0000411a470def020c7d0b200241046a2106200141046a280200210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d940220044101742208200520052008491b22084100480d94020240024020040d002008102921050c010b200628020020042008102a21050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c3003a000002400240200241086a2802002205200828020022046b4104490d00200628020021050c010b200441046a22082004490d940220054101742204200820082004491b22044100480d94020240024020050d002004102921050c010b200628020020052004102a21050b2005450ded0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441046a360200200520046a20073600000c7c0b200241046a2106200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d930220044101742207200520052007491b22074100480d93020240024020040d002007102921050c010b200628020020042007102a21050b2005450ded0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200520046a41c4003a000002400240200241086a2802002205200728020022046b4108490d00200628020021050c010b200441086a22072004490d930220054101742204200720072004491b22044100480d93020240024020050d002004102921050c010b200628020020052004102a21050b2005450dee0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441086a360200200520046a200c3700000c7b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d920220044101742206200520052006491b22064100480d92020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c5003a00000c7a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d910220044101742206200520052006491b22064100480d91020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c6003a00000c790b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d900220044101742206200520052006491b22064100480d90020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c7003a00000c780b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f0220044101742206200520052006491b22064100480d8f020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c8003a00000c770b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e0220044101742206200520052006491b22064100480d8e020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c9003a00000c760b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d0220044101742206200520052006491b22064100480d8d020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ca003a00000c750b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c0220044101742206200520052006491b22064100480d8c020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cb003a00000c740b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b0220044101742206200520052006491b22064100480d8b020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cc003a00000c730b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a0220044101742206200520052006491b22064100480d8a020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cd003a00000c720b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d890220044101742206200520052006491b22064100480d89020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ce003a00000c710b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d880220044101742206200520052006491b22064100480d88020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cf003a00000c700b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d870220044101742206200520052006491b22064100480d87020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d0003a00000c6f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d860220044101742206200520052006491b22064100480d86020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d1003a00000c6e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d850220044101742206200520052006491b22064100480d85020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d2003a00000c6d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d840220044101742206200520052006491b22064100480d84020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d3003a00000c6c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d830220044101742206200520052006491b22064100480d83020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d4003a00000c6b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d820220044101742206200520052006491b22064100480d82020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d5003a00000c6a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d810220044101742206200520052006491b22064100480d81020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d6003a00000c690b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d800220044101742206200520052006491b22064100480d80020240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d7003a00000c680b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff0120044101742206200520052006491b22064100480dff010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d8003a00000c670b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe0120044101742206200520052006491b22064100480dfe010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d9003a00000c660b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd0120044101742206200520052006491b22064100480dfd010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41da003a00000c650b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41db003a00000c640b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dc003a00000c630b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dd003a00000c620b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41de003a00000c610b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41df003a00000c600b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e0003a00000c5f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e1003a00000c5e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e2003a00000c5d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e3003a00000c5c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e4003a00000c5b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e5003a00000c5a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e6003a00000c590b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df00120044101742206200520052006491b22064100480df0010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e7003a00000c580b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490def0120044101742206200520052006491b22064100480def010240024020040d002006102921050c010b200228020420042006102a21050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e8003a00000c570b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dba0220044101742206200520052006491b22064100480dba020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e9003a00000c560b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db90220044101742206200520052006491b22064100480db9020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ea003a00000c550b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db80220044101742206200520052006491b22064100480db8020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41eb003a00000c540b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db70220044101742206200520052006491b22064100480db7020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ec003a00000c530b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db60220044101742206200520052006491b22064100480db6020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ed003a00000c520b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db50220044101742206200520052006491b22064100480db5020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ee003a00000c510b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db40220044101742206200520052006491b22064100480db4020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ef003a00000c500b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db30220044101742206200520052006491b22064100480db3020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f0003a00000c4f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db20220044101742206200520052006491b22064100480db2020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f1003a00000c4e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db10220044101742206200520052006491b22064100480db1020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f2003a00000c4d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db00220044101742206200520052006491b22064100480db0020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f3003a00000c4c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daf0220044101742206200520052006491b22064100480daf020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f4003a00000c4b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dae0220044101742206200520052006491b22064100480dae020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f5003a00000c4a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dad0220044101742206200520052006491b22064100480dad020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f6003a00000c490b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dac0220044101742206200520052006491b22064100480dac020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f7003a00000c480b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dab0220044101742206200520052006491b22064100480dab020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f8003a00000c470b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daa0220044101742206200520052006491b22064100480daa020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f9003a00000c460b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da90220044101742206200520052006491b22064100480da9020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fa003a00000c450b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da80220044101742206200520052006491b22064100480da8020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fb003a00000c440b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da70220044101742206200520052006491b22064100480da7020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fc003a00000c430b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da60220044101742206200520052006491b22064100480da6020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fd003a00000c420b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da50220044101742206200520052006491b22064100480da5020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fe003a00000c410b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da40220044101742206200520052006491b22064100480da4020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ff003a00000c400b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da30220044101742206200520052006491b22064100480da3020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4180013a00000c3f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da20220044101742206200520052006491b22064100480da2020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4181013a00000c3e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da10220044101742206200520052006491b22064100480da1020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4182013a00000c3d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da00220044101742206200520052006491b22064100480da0020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4183013a00000c3c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9f0220044101742206200520052006491b22064100480d9f020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4184013a00000c3b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9e0220044101742206200520052006491b22064100480d9e020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4185013a00000c3a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9d0220044101742206200520052006491b22064100480d9d020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4186013a00000c390b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9c0220044101742206200520052006491b22064100480d9c020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4187013a00000c380b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9b0220044101742206200520052006491b22064100480d9b020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4188013a00000c370b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9a0220044101742206200520052006491b22064100480d9a020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4189013a00000c360b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d990220044101742206200520052006491b22064100480d99020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418a013a00000c350b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d980220044101742206200520052006491b22064100480d98020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418b013a00000c340b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d970220044101742206200520052006491b22064100480d97020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418c013a00000c330b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d960220044101742206200520052006491b22064100480d96020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418d013a00000c320b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d950220044101742206200520052006491b22064100480d95020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418e013a00000c310b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d940220044101742206200520052006491b22064100480d94020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418f013a00000c300b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d930220044101742206200520052006491b22064100480d93020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4190013a00000c2f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d920220044101742206200520052006491b22064100480d92020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4191013a00000c2e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d910220044101742206200520052006491b22064100480d91020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4192013a00000c2d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d900220044101742206200520052006491b22064100480d90020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4193013a00000c2c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f0220044101742206200520052006491b22064100480d8f020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4194013a00000c2b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e0220044101742206200520052006491b22064100480d8e020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4195013a00000c2a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d0220044101742206200520052006491b22064100480d8d020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4196013a00000c290b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c0220044101742206200520052006491b22064100480d8c020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4197013a00000c280b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b0220044101742206200520052006491b22064100480d8b020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4198013a00000c270b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a0220044101742206200520052006491b22064100480d8a020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4199013a00000c260b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d890220044101742206200520052006491b22064100480d89020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419a013a00000c250b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d880220044101742206200520052006491b22064100480d88020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419b013a00000c240b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d870220044101742206200520052006491b22064100480d87020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419c013a00000c230b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d860220044101742206200520052006491b22064100480d86020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419d013a00000c220b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d850220044101742206200520052006491b22064100480d85020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419e013a00000c210b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d840220044101742206200520052006491b22064100480d84020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419f013a00000c200b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d830220044101742206200520052006491b22064100480d83020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a0013a00000c1f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d820220044101742206200520052006491b22064100480d82020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a1013a00000c1e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d810220044101742206200520052006491b22064100480d81020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a2013a00000c1d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d800220044101742206200520052006491b22064100480d80020240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a3013a00000c1c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff0120044101742206200520052006491b22064100480dff010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a4013a00000c1b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe0120044101742206200520052006491b22064100480dfe010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a5013a00000c1a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd0120044101742206200520052006491b22064100480dfd010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a6013a00000c190b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a7013a00000c180b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a8013a00000c170b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a9013a00000c160b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41aa013a00000c150b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ab013a00000c140b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ac013a00000c130b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ad013a00000c120b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ae013a00000c110b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41af013a00000c100b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b0013a00000c0f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b1013a00000c0e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b2013a00000c0d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df00120044101742206200520052006491b22064100480df0010240024020040d002006102921050c010b200228020420042006102a21050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b3013a00000c0c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b4013a00000c0b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b5013a00000c0a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b6013a00000c090b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b7013a00000c080b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b8013a00000c070b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b9013a00000c060b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ba013a00000c050b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bb013a00000c040b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bc013a00000c030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bd013a00000c020b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41be013a00000c010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006102921050c010b200228020420042006102a21050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bf013a00000b2000411a3a000020012d00004109470df201200141086a28020041ffffffff0371450df201200141046a280200102e0cf2010b20064101102c000b20064101102c000b20084101102c000b20084101102c000b20084101102c000b20084101102c000b20084101102c000b20084101102c000b20064101102c000b20064101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20064101102c000b20084101102c000b20064101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20064101102c000b20064101102c000b20064101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20074101102c000b200a4101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b102d000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b200b4101102c000b20094101102c000b20084101102c000b20084101102c000b20084101102c000b20084101102c000b20074101102c000b20064101102c000b20084101102c000b20044101102c000b20074101102c000b20044101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b102d000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b102d000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b20064101102c000b102d000b20002003290300370200200041086a200341086a290300370200200941ffffffff0371450d01200b102e0c010b20002002290200370200200041086a200241086a29020037020020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200341106a24000bfb07030e7f017e017f200241086a2103200241046a210420012802002205210602400240024002400240034002400240200428020020032802002207460d00200228020021080c010b200741016a22082007490d0220074101742209200820082009491b22094100480d020240024020070d002009102921080c010b200228020020072009102a21080b2008450d032002200836020020042009360200200328020021070b2003200741016a360200200820076a200641807f72200641ff0071200641077622071b3a00002007210620070d000b2001280204220a2001410c6a2802002206410c6c6a210b200141086a280200210c200a21072006450d03200a21072005450d03200b41746a210d200241086a210841002107200a210e02400340200e2103024003402003280200220f0d01200741016a2107200b2003410c6a2203470d000c080b0b2003410c6a210e200741016a21102005417f6a2105200341046a290200211102400240034002400240200241046a220428020020082802002206460d00200228020021090c010b200641016a22092006490d0620064101742201200920092001491b22014100480d060240024020060d002001102921090c010b200228020020062001102a21090b2009450d022002200936020020042001360200200828020021060b2008200641016a360200200920066a200741807f72200741ff0071200741077622061b3a0000200621072006450d020c000b0b20014101102c000b2011422088a7221221060240034002400240200428020020082802002207460d00200228020021090c010b200741016a22092007490d0520074101742201200920092001491b22014100480d050240024020070d002001102921090c010b200228020020072001102a21090b2009450d022002200936020020042001360200200828020021070b2008200741016a360200200920076a200641807f72200641ff0071200641077622071b3a00002007210620070d000b0240024020042802002206200828020022076b2012490d00200228020021060c010b200720126a22092007490d0420064101742207200920092007491b22074100480d040240024020060d002007102921060c010b200228020020062007102a21060b2006450d032002200636020020042007360200200828020021070b2008200720126a360200200620076a200f201210f6041a02402011a7450d00200f102e0b200d2003460d052010210720050d010c050b0b20014101102c000b20074101102c000b102d000b20094101102c000b2003410c6a21070b2007200b460d000340024020072802002206450d00200741046a280200450d002006102e0b2007410c6a2207200b470d000b0b0240200c450d00200a102e0b2000411a3a00000bcb0401067f200441046a2105024002400240024002400240200441086a2802002004410c6a2802002206460d00200528020021070c010b200641016a22072006490d0420064101742208200720072008491b22084100480d040240024020060d002008102921070c010b200528020020062008102a21070b2007450d0120042007360204200441086a20083602002004410c6a28020021060b2004410c6a2208200641016a360200200720066a20024101463a0000200441086a2109034002400240200928020020082802002206460d00200528020021070c010b200641016a22072006490d052006410174220a20072007200a491b220a4100480d050240024020060d00200a102921070c010b20052802002006200a102a21070b2007450d03200420073602042009200a360200200828020021060b2008200641016a360200200720066a200141807f72200141ff0071200141077622061b3a00002006210120060d000b024020024101470d002004410c6a2107200441086a2108034002400240200828020020072802002206460d00200528020021010c010b200641016a22012006490d0620064101742209200120012009491b22094100480d060240024020060d002009102921010c010b200528020020062009102a21010b2001450d052004200136020420082009360200200728020021060b2007200641016a360200200120066a200341807f72200341ff0071200341077622061b3a00002006210320060d000b0b2000411a3a00000f0b20084101102c000b200a4101102c000b20094101102c000b102d000bc30701097f230041d0006b2202240002400240024002400240024002400240024020012802082203200128020c2204460d00200441016a22052004490d0420032005490d072001280200220620046a2d000021072001200536020c0240200741014d0d00410c21040c020b4100210820070e020302030b200241013a001f200241cc006a41013602002002420137023c200241e8d4c500360238200241213602342002200241306a36024820022002411f6a360230200241206a200241386a108a042002411a6a200241286a28020036010020022002290320370112200220022901103703002002200241166a290100370106410521040b200020073a0005200020043a000420002002290300370106200041013602002000410c6a20022901063701000c060b410121080b410120036b2109200441026a2104410021074100210a02400240034002402007411f4d0d00410f21070c020b02400240200920046a4102460d002004450d06200320044f0d0120042003105e000b200241013a0000200241cc006a41013602002002420137023c200241e8d4c500360238200241213602342002200241306a36024820022002360230200241106a200241386a108a04410521070c020b200620046a417f6a2d000021052001200436020c200541ff00712007411f7174200a72210a200441016a2104200741076a21072005418001710d000b20074120490d01410d210720054110490d010b2000200736020420004101360200200041086a2002290210370200200041106a200241106a41086a2802003602000c050b0240024020080d00410021040c010b2004417f6a2104410021074100210802400240034002402007411f4d0d00410f21040c020b0240024020032004460d002004417f460d082003200441016a22094f0d01200441016a2003105e000b200241013a0000200241cc006a41013602002002420137023c200241e8d4c500360238200241213602342002200241306a36024820022002360230200241106a200241386a108a04410521040c020b200620046a2d000021052001200936020c200541ff00712007411f71742008722108200741076a2107200921042005418001710d000b20074120490d01410d210420054110490d010b2000200436020420004101360200200041086a2002290210370200200041106a200241106a41086a2802003602000c060b410121040b2000200a360204200041003602002000410c6a2008360200200041086a20043602000c040b417f20051035000b417f20041035000b417f200441016a1035000b20052003105e000b200241d0006a24000ba60301077f2002410c6a2103200141086a28020022042105024002400240034002400240200241086a220628020020032802002207460d00200228020421080c010b200741016a22082007490d0420074101742209200820082009491b22094100480d040240024020070d002009102921080c010b200228020420072009102a21080b2008450d022002200836020420062009360200200328020021070b2003200741016a360200200820076a200541807f72200541ff0071200541077622071b3a00002007210520070d000b200128020421032001280200210802400240200241086a28020022052002410c6a28020022076b2004490d00200228020421050c010b200720046a22062007490d0320054101742207200620062007491b22074100480d030240024020050d002007102921050c010b200228020420052007102a21050b2005450d0220022005360204200241086a20073602002002410c6a28020021070b2002410c6a200720046a360200200520076a2008200410f6041a02402003450d002008102e0b2000411a3a00000f0b20094101102c000b20074101102c000b102d000b8b07010b7f230041d0086b22022400410021034100210402400240024002400240034002402003411f4d0d00410f21030c020b0240024020012802082205200128020c2206460d00200641016a22072006490d05200520074f0d0120072005105e000b200241013a0089082002411c6a41013602002002420137020c200241e8d4c5003602082002412136029c08200220024198086a360218200220024189086a36029808200241b8086a200241086a108a04410521030c020b2001280200220820066a2d000021062001200736020c200641ff00712003411f71742004722104200341076a21032006418001710d000b20034120490d01410d210320064110490d010b2000200336020420004101360200200041086a20022902b808370200200041106a200241b8086a41086a2802003602000c030b024020040d002000428080808010370200200041086a42003702000c030b200241086a410041800810f5041a410121094100210a410021064100210b03400240024002400240200520076b2004200b6b22034180082003418008491b2203490d00200720036a220c2007490d022005200c4f0d01200c2005105e000b200241013a00a708200241cc086a4101360200200242013702bc08200241e8d4c5003602b8082002412136029c08200220024198086a3602c8082002200241a7086a36029808200241a8086a200241b8086a108a0420024194086a200241b0086a280200360000200220022903a80837008c08200041053a000420002002290089083700052000410c6a20024190086a29000037000020004101360200200a450d062009102e0c060b200241086a200820076a200310f6041a2001200c36020c0240200a20066b2003490d00200320066a210c0c020b0240200620036a220c2006490d00200a4101742207200c200c2007491b22074100480d0002400240200a0d002007102921090c010b2009200a2007102a21090b02402009450d002007210a0c030b20074101102c000b102d000b2007200c1035000b200920066a200241086a200310f6041a20042003200b6a220b4d0d02200128020c21072001280208210520012802002108200c21060c000b0b417f20071035000b200241086a2009200c10cd02024020022802084101470d000240200a450d002009102e0b200041083a0004200041013602000c010b200020093602042000410c6a200c360200200041086a200a360200200041003602000b200241d0086a24000b160020012000280200220028020020002802081093040b8307010c7f200028021021030240024002400240200028020822044101460d0020030d012000280218200120022000411c6a28020028020c11040021030c030b2003450d010b0240024020020d00410021020c010b200120026a2105200041146a28020041016a21064100210720012103200121080340200341016a210902400240024020032c0000220a417f4a0d000240024020092005470d004100210b200521030c010b20032d0001413f71210b200341026a220921030b200a411f71210c0240200a41ff0171220a41df014b0d00200b200c41067472210a0c020b0240024020032005470d004100210d2005210e0c010b20032d0000413f71210d200341016a2209210e0b200d200b41067472210b0240200a41f0014f0d00200b200c410c7472210a0c020b02400240200e2005470d004100210a200921030c010b200e41016a2103200e2d0000413f71210a0b200b410674200c411274418080f0007172200a72220a418080c400470d020c040b200a41ff0171210a0b200921030b02402006417f6a2206450d00200720086b20036a21072003210820052003470d010c020b0b200a418080c400460d00024002402007450d0020072002460d0041002103200720024f0d01200120076a2c00004140480d010b200121030b2007200220031b21022003200120031b21010b20040d002000280218200120022000411c6a28020028020c1104000f0b4100210902402002450d002002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b0240200220096b200028020c2206490d002000280218200120022000411c6a28020028020c1104000f0b410021074100210902402002450d00410021092002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b200920026b20066a210a024002400240410020002d0030220320034103461b0e0402000100020b200a21074100210a0c010b200a4101762107200a41016a410176210a0b200741016a2103024003402003417f6a2203450d0120002802182000280204200028021c280210110200450d000b41010f0b2000280204210941012103200028021820012002200028021c28020c1104000d00200a41016a2103200028021c210a20002802182100034002402003417f6a22030d0041000f0b20002009200a280210110200450d000b41010f0b20030bef0201067f230041c0006b2202240041002103410021040240024003400240024002402003411f4b0d002001280204220520012802082206460d01200641016a22072006490d04200520074f0d0220072005105e000b200041013602002000410f3a00040c040b200241013a000f200241346a410136020020024201370224200241e8d4c5003602202002412136023c2002200241386a36023020022002410f6a360238200241106a200241206a108a042002410b6a200241186a28020036000020022002290310370003200041053a0004200020022900003700052000410c6a200241076a290000370000200041013602000c030b200128020020066a2d0000210620012007360208200641ff00712003411f71742004722104200341076a21032006418001710d000b0240024020034120490d002006410f4b0d010b20004100360200200020043602040c020b200041013602002000410d3a00040c010b417f20071035000b200241c0006a24000bdb06010a7f20012802042103200128020021044100210541012106410021072001280208220821090240024002400240024002400340024020072005470d002005410174220a200541016a220b200b200a491b220a4100480d070240024020050d00200a102921060c010b20062005200a102a21060b2006450d02200a21050b200620076a200941807f72200941ff00712009410776220a1b3a0000200741016a2107200a2109200a0d000b200520076b20084f0d02200720086a22092007490d052005410174220a20092009200a491b220941004e0d010c050b200a4101102c000b0240024020050d002009102921060c010b200620052009102a21060b2006450d01200921050b200620076a2004200810f6041a02402003450d002004102e0b200128020c210c0240200520086b20076b200141146a2802002209490d00200820096a20076a21030c020b200820076a220a20096a2203200a490d022005410174220a20032003200a491b220a4100480d020240024020050d00200a102921060c010b20062005200a102a21060b02402006450d00200a21050c020b200a4101102c000b20094101102c000b200620086a20076a200c200910f6041a200241086a210b200241046a210820032109024002400340024002402008280200200b2802002207460d002002280200210a0c010b200741016a220a2007490d0420074101742204200a200a2004491b22044100480d040240024020070d0020041029210a0c010b200228020020072004102a210a0b200a450d022002200a36020020082004360200200b28020021070b200b200741016a360200200a20076a200941807f72200941ff0071200941077622071b3a00002007210920070d000b02400240200241046a2802002209200241086a28020022076b2003490d00200228020021090c010b200720036a220a2007490d0320094101742207200a200a2007491b22074100480d030240024020090d002007102921090c010b200228020020092007102a21090b2009450d0220022009360200200241046a2007360200200241086a28020021070b200241086a200720036a360200200920076a2006200310f6041a02402005450d002006102e0b2000411a3a00000240200141106a280200450d00200c102e0b0f0b20044101102c000b20074101102c000b102d000be5bc0106077f017e047f017e197f027e230041f080046b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001280204220320012802082204460d00200441016a22052004490d02200320054f0d0120052003105e000b200241013a0028200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022802d88004210420022802dc8004210120004101360200200041003a00042001450d1d2004102e0c1d0b200128020020046a2d00002104200120053602082004410b4b0d02024020040e0c00100f0e0d0c0b0a02060504000b200241c0006a20011094044101210620022802442107024020022802404101470d0020074108762108200241d0006a2802002101200241c0006a41086a29030021090c1c0b4100210a200241c0006a41004180800110f5041a4100210b410021032007450d10410121064100210b410021054100210c034002400240024002402001280204220d200128020822036b2007200c6b220441808001200441808001491b2204490d00200320046a22082003490d02200d20084f0d012008200d105e000b200241013a00c88004200241ec80046a4101360200200242013702dc8004200241e8d4c5003602d88004200241213602242002200241206a3602e880042002200241c880046a360220200241286a200241d880046a108a042002290328210920022802302101410521070240200b450d002006102e0b0c1f0b200241c0006a200128020020036a200410f6041a200120083602080240200b20056b2004490d00200420056a21030c020b200520046a22032005490d14200b4101742208200320032008491b22084100480d1402400240200b0d002008102921060c010b2006200b2008102a21060b02402006450d002008210b0c020b20084101102c000b200320081035000b200620056a200241c0006a200410f6041a2003210520072004200c6a220c4b0d000c110b0b417f20051035000b200241c0006a2001109704024020022802404101470d00200041013602002000200241c0006a41047222012902003702042000410c6a200141086a2902003702000c1b0b200241d4006a2802002108200241d0006a2802002101200241cc006a2802002105200241c8006a280200210b2002280244210c410021044100210302400240034002402004411f4d0d00410f21010c0a0b20052001460d082001417f460d012005200141016a2206490d02200c20016a2d0000220a41ff00712004411f71742003722103200441076a210420062101200a418001710d000b20044120490d06410d2101200a410f4b0d080c060b417f200141016a1035000b200141016a2005105e000b200041123a000420004101360200200041056a20043a00000c190b200241c0006a20011097040240024020022802404101470d00200228024422014108762106200241c0006a41086a2903002209422088210e200241d0006a280200210a0c010b200241386a200241d4006a280200360200200241306a200241cc006a29020037030020022002290244370328410021064100210141002105024002400240024002400240024002400240034002402001411f4d0d00410f21070c070b2002280230220a20022802342204460d08200441016a22032004490d02200a2003490d01200228022820046a2d0000210420022003360234200441ff00712001411f71742005722105200141076a21012004418001710d000b024020014120490d002004410f4d0d0041002106410d21070c060b02400240024020050d004100210d410421030c010b410421034100210d4100210703402007220f41016a2107410021014100210c02400240024002400240024003404100210602402001411f4d0d00410f21070c0f0b2002280230220b20022802342204460d01200441016a220a2004490d02200b200a490d04200228022820046a2d000021042002200a360234200441ff00712001411f7174200c72210c200141076a21012004418001710d000b024020014120490d002004410f4d0d00410d21070c0e0b200241c0006a200241286a108704024020022802404101470d002002280244220741087621062002280250210a200228024c210b200228024821080c0e0b200228024c21102002280248211120022802442112410021044100210b034002402004411f4d0d00410f21070c0e0b200228023022062002280234220a460d0c200a41016a2201200a490d0320062001490d0520022802282208200a6a2d0000210a20022001360234200a41ff00712004411f7174200b72210b200441076a2104200a418001710d000b20044120490d05200a410f4d0d05410d21070c0c0b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022903d880042209422088a7210b20022802e08004210a2009a72108410521070c0c0b417f200a1035000b417f20011035000b200a200b105e000b20012006105e000b41002113200241c0006a41004180800410f5041a02400240200b0d0041012114410021150c010b41002113410121144100210a4100211603400240024002400240200620016b200b20166b220441808004200441808004491b2204490d00200120046a22152001490d02200620154f0d0120152006105e000b200241013a00c78004200241013602ec8004200242013702dc8004200241e8d4c5003602d88004200241213602242002200241206a3602e880042002200241c780046a360220200241c880046a200241d880046a108a0420022802c88004210820022802cc8004210b20022802d08004210a410521072013450d0b2014102e0c0b0b200241c0006a200820016a200410f6041a2002201536023402402013200a6b2004490d002004200a6a21150c020b200a20046a2215200a490d1e20134101742201201520152001491b22014100480d1e0240024020130d002001102921140c010b201420132001102a21140b02402014450d00200121130c020b20014101102c000b200120151035000b2014200a6a200241c0006a200410f6041a200b200420166a22164d0d012002280234210120022802302106200228022821082015210a0c000b0b0240200d200f470d00200d4101742201200d41016a220420042001491b2201ad421c7e2209422088a70d1b2009a722044100480d1b02400240200d0d002004102921030c010b2003200d411c6c2004102a21030b2003450d032001210d0b2003200f411c6c6a2201200c41087622043b000120012014360210200120123602042001200c3a0000200141036a20044110763a0000200141186a2015360200200141146a20133602002001410c6a2010360200200141086a201136020020072005470d000b0b200228023420022802384621010240200228022c450d002002280228102e0b2001450d072005ad422086200dad842109410c21040c1c0b20044104102c000b2003200a105e000b417f20031035000b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022903d880042209422088a7210b20022802e08004210a2009a72108410521070b02402010450d0020104104742104201221010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b410021062011450d002012102e0b0240200f450d002003200f411c6c6a210c20032105034002402005410c6a2802002204450d0020052802042101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b0240200541086a280200450d002005280204102e0b2005411c6a21010240200541146a280200450d002005280210102e0b200121052001200c470d000b0b200d450d032003102e0c030b4100210b410021080c020b20024103410220011b3a00c88004200241c0006a41146a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022903d88004210920022802e08004210a02402005450d0020032005411c6c6a210620032105034002402005410c6a2802002204450d0020052802042101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b0240200541086a280200450d002005280204102e0b2005411c6a21010240200541146a280200450d002005280210102e0b2001210520012006470d000b0b2009422088210e4105210141002106200d450d022003102e0c020b200241013a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022903d880042209422088a7210b20022802e08004210a2009a7210841052107410021060b2006410874200741ff0171722101200bad220e4220862008ad842109200228022c450d002002280228102e0b20004101360200200041106a200a360200200041086a200e422086200942ffffffff0f838437020020002006410874200141ff0171723602040c180b200241c0006a20011097040240024020022802404101470d002002280244220b4108762101200241c0006a41086a2903002209422088210e200241d0006a28020021080c010b200241d4006a2802002114200241d0006a2802002101200241cc006a280200210a200241c8006a28020021132002280244210c410021044100210602400240024002400240024002400240024002400240024002400240034002402004411f4d0d00410f210b0c020b02400240200a2001460d002001417f460d06200a200141016a22054f0d01200141016a200a105e000b200241013a0028200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022903d88004210920022802e0800421084105210b0c030b200c20016a2d0000220341ff00712004411f71742006722106200441076a2104200521012003418001710d000b20044120490d0220034110490d02410d210b0b0b2009422088a7210d2009a721160c0b0b024002400240024002400240024002400240024002400240024020060d0041002117410421030c010b200241c9006a211841042103410021174100211903402019221a41016a2119410021014100210b034002402001411f4d0d00410f210b0c170b200a2005460d142005417f460d0d200a200541016a2204490d06200c20056a2d0000220741ff00712001411f7174200b72210b200141076a2101200421052007418001710d000b024020014120490d002007410f4d0d00410d210b0c160b4100210f200241c0006a41004180800110f5041a02400240200b0d00410121102004210541002111410021070c010b41002111410121104100211541002112034002400240200a20046b200b20126b220141808001200141808001491b2201490d00200420016a22052004490d0f200a20054f0d012005200a105e000b200241013a00c78004200241013602ec8004200242013702dc8004200241e8d4c5003602d88004200241213602242002200241206a3602e880042002200241c780046a360220200241c880046a200241d880046a108a0420022903c880042209422088a7210d20022802d0800421082009a721164105210b2011450d182010102e0c180b200241c0006a200c20046a200110f6041a02400240201120156b2001490d00200120156a21070c010b201520016a22072015490d2820114101742204200720072004491b22044100480d280240024020110d002004102921100c010b201020112004102a21100b2010450d0d200421110b201020156a200241c0006a200110f6041a2005210420072115200b200120126a22124b0d000b0b20024100360234200220103602282002200736023820022007ad4220862011ad8437022c4100210141002112034002402001411f4d0d00410f210b0c140b2007200f460d12200f417f460d0a2007200f41016a220b490d052010200f6a2d000021042002200b360234200441ff00712001411f71742012722112200141076a2101200b210f2004418001710d000b024020014120490d002004410f4d0d00410d210b0c130b4100211b0240024020120d004104211c410021110c010b410021114104211c4100211d0340201d221e41016a211d4100210141002115024002400240034002402001411f4d0d00410f211520162101200d211f0c020b024002402002280230220f20022802342204460d00200441016a220b2004490d10200f200b4f0d01200b200f105e000b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022903d880042209422088a7211f20022802e0800421082009a72101410521150c020b2002280228221020046a2d000021072002200b360234200741ff00712001411f71742015722115200141076a21012007418001710d000b20014120490d0120074110490d0120162101200d211f410d21150b200141087621204101210741002104200821214100210b20012116201f210d0c010b0240024002400240200f200b460d00200441026a2101200b417f460d0e200f20014f0d012001200f105e000b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022802d88004212220022802dc8004212320022802e080042124410521150c010b2010200b6a2c00002104200220013602340240200441004e0d00411821150c010b0240200441c000710d00410621150c010b200441807f72220141ff017141fb014b0d0141062115200121040b20224108762120410121074100210b2023211f20242121202221010c010b20154180807c71210b201541087621042001417f732101410021070b200b200441ff017141087472201541ff017172210b02402007450d002020410874200141ff01717221162011450d15201c102e0c150b02402011201e470d0020114101742204201141016a220720072004491b220441ffffffff01712004470d28200441037422074100480d280240024020110d0020071029211c0c010b201c20114103742007102a211c0b201c450d09200421110b201c201e4103746a220420013a00042004200b360200201d2012470d000b0b4101210b41082110410021014100210741002115034020012104200241c0006a200241286a108804024020022802404101470d0020022802502121200228024c211f200228024821162002280244210b0c120b200241d880046a41026a2201201841026a2d00003a0000200220182f00003b01d88004200228024c211e2002280250211d200228025421250240024020022d0048220f4106470d00200b417f6a210b0c010b200f417e6a41034f0d00200b41016a2226200b4f21272026210b20270d004115211f41eb9bc50021164104210b200f4109470d11201d41ffffffff03710d100c110b200241c0006a41026a222620012d00003a0000200220022f01d880043b0140024020072015470d00200741016a22012007490d27201b20012001201b491b221541ffffffff00712015470d27201541047422014100480d270240024020070d002001102921100c010b201020042001102a21100b2010450d040b201020046a2201200f3a00002001410c6a2025360200200141086a201d360200200141046a201e360200200141016a20022f01403b0000200141036a20262d00003a0000201b41026a211b200441106a2101200741016a2107200b0d000b200228023420022802384621010240200228022c450d002002280228102e0b2001450d1402402017201a470d0020174101742201201741016a220420042001491b2201ad42187e2209422088a70d262009a722044100480d260240024020170d002004102921030c010b2003201741186c2004102a21030b2003450d04200121170b2003201a41186c6a2201201036020c20012012360208200120113602042001201c360200200141146a2007360200200141106a201536020020192006470d000b0b2005201446210102402013450d00200c102e0b2001450d142006ad4220862017ad842109410b21040c270b20014108102c000b20044104102c000b200f41016a2007105e000b200541016a200a105e000b20074104102c000b417f20011035000b417f200b1035000b417f200f41016a1035000b20044101102c000b200420051035000b417f200541016a1035000b417f200141016a1035000b201e102e0b0b02402007450d00201021010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b02402015450d002010102e0b2011450d01201c102e0c010b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022903d880042209422088a7211f20022802e0800421212009a721164105210b0b0240200228022c450d002002280228102e0b201f210d202121080c020b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022903d880042209422088a7210d20022802e0800421082009a721164105210b0c010b20024103410220011b3a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022802d88004211620022802dc8004210d20022802e08004210802402007450d00200441106a21054100210103400240201020016a22042d00004109470d00200441086a28020041ffffffff0371450d00200441046a280200102e0b2005200141106a2201470d000b0b02402015450d002010102e0b4105210b2011450d00201c102e0b0240201a450d002003201a41186c6a210a2003210503400240200541046a280200450d002005280200102e0b0240200541146a2802002204450d00200528020c2101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b200541186a21010240200541106a280200450d00200528020c102e0b200121052001200a470d000b0b2017450d012003102e0c010b20024103410220011b3a0028200241c0006a41146a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022903d88004210920022802e08004210802402006450d002003200641186c6a210a2003210503400240200541046a280200450d002005280200102e0b0240200541146a2802002204450d00200528020c2101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b200541186a21010240200541106a280200450d00200528020c102e0b200121052001200a470d000b0b2009422088210e4105210b410021012017450d012003102e0c010b200b4108762101200dad220e4220862016ad8421092013450d00200c102e0b20004101360200200041106a2008360200200041086a200e422086200942ffffffff0f838437020020002001410874200b41ff0171723602040c170b200241c0006a20011097040240024020022802404101470d00200228024422014108762106200241c0006a41086a2903002209422088210e200241d0006a280200210a0c010b200241e880046a200241d4006a280200360200200241e080046a200241cc006a290200370300200220022902443703d880044100210641002101410021050240024002400240024002400240024002400240034002402001411f4d0d00410f210b0c080b20022802e08004220a20022802e480042204460d09200441016a22032004490d01200a2003490d0420022802d8800420046a2d00002104200220033602e48004200441ff00712001411f71742005722105200141076a21012004418001710d000b024020014120490d002004410f4d0d0041002106410d210b0c070b0240024020050d004100210d410421030c010b410421034100210d4100210803402008221641016a2108410021014100210c0240024002400240024003404100210602402001411f4d0d00410f210b0c030b20022802e08004220b20022802e480042204460d01200441016a220a2004490d09200b200a490d0c20022802d8800420046a2d000021042002200a3602e48004200441ff00712001411f7174200c72210c200141076a21012004418001710d000b024020014120490d002004410f4d0d00410d210b0c020b200241c0006a200241d880046a108704024020022802404101470d002002280244220b41087621062002280250210a200228024c2108200228024821070c020b200228024c21132002280248210f20022802442115200241c0006a200241d880046a108b04024020022802404101470d002002280244210b2002280250210a200228024c21082002280248210702402013450d0020134104742104201521010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b200b4108762106200f450d022015102e0c020b200228024821142002280244210702400240200228024c22010d00410021064104210b4100210a0c010b2001410274220a410275220641ffffffff03712006470d1e200a4100480d1e200a1029220b450d0d200a417c6a2110200b210120072104034020012004280200360200200141046a2101200441046a2104200a417c6a220a0d000b201041027641016a210a0b02402014450d002007102e0b200d2016470d04200d4101742201200d41016a220420042001491b2201ad421c7e2209422088a70d1d2009a722044100480d1d200d0d022004102921030c030b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022903282209422088a721082002280230210a2009a721074105210b0b02402016450d0020032016411c6c6a210c20032105034002402005410c6a2802002204450d0020052802042101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b0240200541086a280200450d002005280204102e0b2005411c6a21010240200541146a280200450d002005280210102e0b200121052001200c470d000b0b200d450d0e2003102e0c0e0b2003200d411c6c2004102a21030b2003450d052001210d0b20032016411c6c6a2201200c41087622043b00012001200b360210200120153602042001200c3a0000200141036a20044110763a0000200141186a200a360200200141146a20063602002001410c6a2013360200200141086a200f36020020082005470d000b0b20022802e4800420022802e88004462101024020022802dc8004450d0020022802d88004102e0b2001450d072005ad422086200dad842109410a21040c1a0b417f20031035000b417f200a1035000b20044104102c000b2003200a105e000b200a200b105e000b200a4104102c000b41002108410021070c020b20024103410220011b3a00c88004200241c0006a41146a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a04200229032821092002280230210a02402005450d0020032005411c6c6a210620032105034002402005410c6a2802002204450d0020052802042101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b0240200541086a280200450d002005280204102e0b2005411c6a21010240200541146a280200450d002005280210102e0b2001210520012006470d000b0b2009422088210e4105210141002106200d450d022003102e0c020b200241013a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022903282209422088a721082002280230210a2009a721074105210b410021060b2006410874200b41ff01717221012008ad220e4220862007ad84210920022802dc8004450d0020022802d88004102e0b20004101360200200041106a200a360200200041086a200e422086200942ffffffff0f838437020020002006410874200141ff0171723602040c160b200820064621010240200b450d00200c102e0b02402001450d00410921040c0f0b20024103410220011b3a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a04200241e380046a200241306a280200360000200220022903283700db8004200041053a0004200020022900d880043700052000410c6a200241df80046a290000370000200041013602000c150b200241013a0028200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a04410521010b2000200136020420004101360200200041086a20022902d88004370200200041106a200241d880046a41086a280200360200200b450d13200c102e0c130b200241c0006a20011097040240024020022802404101470d00200228024422044108762101200241c0006a41086a2903002209422088210e200241d0006a28020021060c010b200241e880046a200241d4006a280200360200200241e080046a200241cc006a290200370300200220022902443703d880044100210c4100210141002105024002400240024002400240024002400240024002400240024002400240024002400240034002402001411f4d0d00410f2104410021050c130b20022802e08004220a20022802e480042204460d11200441016a22032004490d01200a2003490d0820022802d8800420046a2d00002104200220033602e48004200441ff00712001411f71742005722105200141076a21012004418001710d000b024020014120490d002004410f4d0d00410d2104410021050c120b0240024020050d0041002116410421030c010b410421034100210a41002116410021130340200241c0006a200241d880046a109104024020022802404101470d002002200229024c22093703c8800420022802482105200228024421042009a7210c0c110b200228024821152002280244210f0240024020022802e08004220420022802e480042206460d00200641016a22012006490d05200420014f0d0120012004105e000b200241013a00c780042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c780046a360220200241286a200241c0006a108a040c0e0b200228024c211420022802d88004220c20066a2d0000210d200220013602e480040240200d41034d0d00410a21010c100b02400240024002400240200d0e0400010203000b4100210d4100210b4100210603400240200b411f4d0d00410f21010c150b20042001460d132001417f460d092004200141016a2207490d0f200c20016a2d00002108200220073602e48004200841ff0071200b411f71742006722106200b41076a210b200721012008418001710d000b4100210d200b4120490d032008410f4d0d03410d21010c130b4100210b410021060340200b411f4b0d100240024020042001460d002001417f460d0b2004200141016a22074f0d01200141016a2004105e000b200241013a00c780042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c780046a360220200241286a200241c0006a108a040c120b200c20016a2d00002108200220073602e48004200841ff0071200b411f71742006722106200b41076a210b200721012008418001710d000b4101210d200b4120490d022008410f4d0d020c0e0b4100210b410021060340200b411f4b0d0f0240024020042001460d002001417f460d0b2004200141016a22074f0d01200141016a2004105e000b200241013a00c780042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c780046a360220200241286a200241c0006a108a040c110b200c20016a2d00002108200220073602e48004200841ff0071200b411f71742006722106200b41076a210b200721012008418001710d000b4102210d200b4120490d012008410f4b0d0d0c010b4100210b410021060340200b411f4b0d0e0240024020042001460d002001417f460d0b2004200141016a22074f0d01200141016a2004105e000b200241013a00c780042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c780046a360220200241286a200241c0006a108a040c100b200c20016a2d00002108200220073602e48004200841ff0071200b411f71742006722106200b41076a210b200721012008418001710d000b4103210d200b4120490d002008410f4b0d0c0b200220063602d080042002200d3602cc800420022902cc80042109024020162013470d0020164101742201201641016a220420042001491b2201ad42147e220e422088a70d1d200ea722044100480d1d0240024020160d002004102921030c010b2003201641146c2004102a21030b2003450d09200121160b2003201341146c6a2201200937020c20012014360208200120153602042001200f360200200a41146a210a201341016a2201211320012005470d000b0b20022802e4800420022802e88004462101024020022802dc8004450d0020022802d88004102e0b2001450d0f2005ad4220862016ad842109410821040c1e0b417f20031035000b417f20011035000b417f200141016a1035000b417f200141016a1035000b417f200141016a1035000b417f200141016a1035000b20044104102c000b2003200a105e000b200141016a2004105e000b410d21014100210d0c030b410f21014100210d0c020b20022802282105200229022c2109410521014100210d0c010b200241013a00c780042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c780046a360220200241286a200241c0006a108a0420022802282105200229022c2109410521010b200d4108742001722104200220093703c880042009a7210c2015450d00200f102e0b20022802cc8004210602402013450d002003210103400240200141046a280200450d002001280200102e0b200141146a2101200a416c6a220a0d000b0b2016450d022003102e0c020b20024103410220011b3a00c88004200241c0006a41146a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a04200229032821092002280230210602402005450d00200541146c21042003210103400240200141046a280200450d002001280200102e0b200141146a21012004416c6a22040d000b0b2009422088210e41052104410021012016450d022003102e0c020b200241013a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022903282209422088a7210c200228023021062009a72105410521040b20044108762101200cad220e4220862005ad84210920022802dc8004450d0020022802d88004102e0b20004101360200200041106a2006360200200041086a200e422086200942ffffffff0f838437020020002001410874200441ff0171723602040c120b200241c0006a20011097040240024020022802404101470d00200228024422054108762101200241c0006a41086a2903002209422088210e200241d0006a280200210a0c010b200241386a200241d4006a280200360200200241306a200241cc006a290200370300200220022902443703284100210b410021014100210602400240024002400240024002400240034002402001411f4d0d00410f21054100210c0c090b2002280230220a20022802342204460d07200441016a22052004490d01200a2005490d052002280228220c20046a2d0000210420022005360234200441ff00712001411f71742006722106200141076a21012004418001710d000b024020014120490d002004410f4d0d00410d21054100210c0c080b024020060d00410421034100210d0c060b2006417f6a21144100211641002107410021084100210d4104210f410421030340024002400240024002400240024002400240200a2005460d00200541016a22042005490d0b200a20044f0d012004200a105e000b200241013a00c78004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c780046a360220200241c880046a200241c0006a108a0420022802c88004210c20022802cc8004210b20022802d08004210a410521130c010b200c20056a2c000021012002200436023402400240200141004e0d00411821130c010b41062113200141c00071450d00200141807f72220141ff017141fb014b0d020b0b200241e880046a200a360200200241e480046a200b360200200241e080046a200c360200200220013a00dd8004200220133a00dc80040c010b024002400240200a2004460d00200541026a21052004417f460d0b200a20054f0d012005200a105e000b200241013a00c78004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c780046a360220200241c880046a200241c0006a108a0420022802c88004210c20022802cc8004210b20022802d08004210a410521010c010b200c20046a2d00002104200220053602340240200441014b0d004100210a20040e020403040b410c21010b200241e880046a200a360200200241e480046a200b360200200241e080046a200c360200200220043a00dd8004200220013a00dc80040b200241013a00d8800420022802dc800421050c020b418002210a0b200241c0006a200241286a108704200228024c210b2002280248210c2002280244210520022802404101470d01200241d0006a280200210a0b02402008450d00200320076a21060340024020032802082204450d0020032802002101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b200341106a21010240200341046a280200450d002003280200102e0b2001210320062001470d000b0b200d450d09200f102e0c090b200841016a211302402008200d470d002016201320132016491b220d41ffffffff0071200d470d11200d41047422044100480d110240024020080d0020041029210f0c010b200f20072004102a210f0b200f450d05200f21030b200320076a220420053602002004410c6a20154180807c712001417f7341ff017172200a722215360200200441086a200b360200200441046a200c36020020142008460d06201641026a2116200741106a2107200228023421052002280230210a2002280228210c201321080c000b0b417f20051035000b417f20041035000b417f20051035000b20044104102c000b2005200a105e000b200228023420022802384621010240200228022c450d002002280228102e0b02402001450d002006ad422086200dad842109410721040c0e0b20024103410220011b3a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022903d88004210920022802e08004210a02402006450d00200320064104746a2106200321050340024020052802082204450d0020052802002101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a280200102e0b200141106a2101200441706a22040d000b0b200541106a21010240200541046a280200450d002005280200102e0b2001210520012006470d000b0b2009422088210e4105210541002101200d450d022003102e0c020b200241013a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241d880046a200241c0006a108a0420022903d880042209422088a7210b20022802e08004210a2009a7210c410521050b20054108762101200bad220e422086200cad842109200228022c450d002002280228102e0b20004101360200200041106a200a360200200041086a200e422086200942ffffffff0f838437020020002001410874200541ff0171723602040c110b200241c0006a20011097040240024020022802404101470d00200228024422044108762105200241c0006a41086a2903002209422088210e200241d0006a28020021010c010b200241e880046a200241d4006a280200360200200241e080046a200241cc006a290200220937030020022002290244220e3703d88004200ea7210c2009a721034100210420022802e4800421014100210502400240024002400240024002400240024003402004411f4b0d0120032001460d032001417f460d042003200141016a220a490d06200c20016a2d0000220641ff00712004411f71742005722105200441076a2104200a21012006418001710d000b2002200a3602e4800420044120490d012006410f4d0d0141002104410d210c0c060b200220013602e4800441002104410f210c0c050b0240024020050d00410421034100210d0c010b4100210741002106410021014100210d410421030340200241c0006a200241d880046a108f0420022f004520022d0047411074722104200228024c210b2002280248210820022d0044210c024020022802404101470d00200241d0006a2802002101200d450d082003102e0c080b200141016a210a02402001200d470d002007200a200a2007491b220dad420c7e2209422088a70d102009a722164100480d100240024020010d002016102921030c010b200320062016102a21030b2003450d050b200320066a2201200c3a0000200141036a20044110763a0000200141016a20043b0000200141086a200b360200200141046a2008360200200741026a21072006410c6a2106200a21012005200a470d000b0b20022802e4800420022802e88004462101024020022802dc8004450d0020022802d88004102e0b2001450d062005ad422086200dad842109410621040c110b200220033602e48004200241013a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022903282209422088a7210b200228023021012009a721084105210c410021040c040b417f200141016a1035000b20164104102c000b200141016a2003105e000b4100210b410021080b200441ffffff07712205410874200c41ff0171722104200bad220e4220862008ad84210920022802dc8004450d0120022802d88004102e0c010b20024103410220011b3a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022903282209422088210e200228023021014105210441002105200d450d002003102e0b20004101360200200041106a2001360200200041086a200e422086200942ffffffff0f838437020020002005410874200441ff0171723602040c100b200241c0006a20011097040240024020022802404101470d00200228024422044108762105200241c0006a41086a2903002209422088210e200241d0006a28020021010c010b200241e880046a200241d4006a280200360200200241e080046a200241cc006a290200220937030020022002290244220e3703d88004200ea7210c2009a721054100210420022802e480042101410021060240024002400240024002400240024002400240024003402004411f4b0d0120052001460d032001417f460d042005200141016a220a490d07200c20016a2d0000220341ff00712004411f71742006722106200441076a2104200a21012003418001710d000b2002200a3602e4800420044120490d012003410f4d0d0141002104410d210a0c080b200220013602e4800441002104410f210a0c070b024020060d004100210b410421030c060b2006417f6a2116410421034108210d4100210841002107034002400240024002402005200a460d00200a41016a2201200a490d07200520014f0d0120012005105e000b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a042002280228210b200228022c210c200228023021014105210a0c010b200c200a6a2c00002104200220013602e480040240200441004e0d004118210a0c010b4107210a0240200441c000710d000c010b200441807f7222044170470d00200241c0006a200241d880046a108f0420022f004520022d004741107472210420022d0044210a20022802404101470d0120044180feff0771410876210520022802502101200228024c210c2002280248210b0b2005410874200441ff01717221042008450d092003102e0c090b200228024c21052002280248210c0240024020072008460d002008210b0c010b20084101742201200841016a220b200b2001491b220bad420c7e2209422088a70d102009a722014100480d100240024020080d002001102921030c010b20032008410c6c2001102a21030b2003450d050b2003200d6a22012005360200200141796a220520043b00002001417c6a200c360200200141786a200a3a0000200541026a20044110763a000020162007460d06200741016a2107200d410c6a210d20022802e48004210a20022802e08004210520022802d88004210c200b21080c000b0b200220053602e48004200241013a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022903282209422088a7210c200228023021012009a7210b4105210a410021040c060b417f200141016a1035000b417f20011035000b20014104102c000b200141016a2005105e000b20022802e4800420022802e88004462101024020022802dc8004450d0020022802d88004102e0b2001450d022006ad422086200bad842109410521040c0c0b4100210c4100210b0b200441ffffff07712205410874200a41ff0171722104200cad220e422086200bad84210920022802dc8004450d0120022802d88004102e0c010b20024103410220011b3a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022903282209422088210e200228023021014105210441002105200b450d002003102e0b20004101360200200041106a2001360200200041086a200e422086200942ffffffff0f838437020020002005410874200441ff0171723602040c0f0b200241c0006a20011097040240024020022802404101470d00200228024422044108762105200241c0006a41086a2903002209422088210e200241d0006a28020021010c010b200241d4006a280200210d200241d0006a2802002101200241cc006a2802002105200241c8006a28020021072002280244210c4100210b41002104410021060240024002400240024002400240034002402004411f4d0d00410f2104410021050c030b20052001460d012001417f460d032005200141016a220a490d06200c20016a2d0000220341ff00712004411f71742006722106200441076a2104200a21012003418001710d000b024020044120490d002003410f4d0d00410d2104410021050c020b410421030240024020060d00410021130c010b410021164100211303402016221541016a2116200a2101410021044100210b024002400240034002402004411f4d0d00410f21040c020b0240024020052001460d002001417f460d0b2005200141016a220a4f0d01200141016a2005105e000b200241013a0028200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022802d88004210520022802dc8004210b20022802e080042101410521040c030b200c20016a2d0000220841ff00712004411f7174200b72210b200441076a2104200a21012008418001710d000b20044120490d0220084110490d02410d21040b0b2013450d042003102e0c040b024020132015470d0020154101742201201620162001491b221341ffffffff03712013470d0e201341027422014100480d0e0240024020150d002001102921030c010b200320154102742001102a21030b2003450d070b200320154102746a200b36020020162006470d000b0b200a200d46210102402007450d00200c102e0b2001450d062006ad4220862013ad842109410421040c0f0b200241013a0028200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022903d880042209422088a7210b20022802e0800421012009a72105410521040b200bad220e4220862005ad842109410021052007450d05200c102e0c050b417f200141016a1035000b417f200141016a1035000b20014104102c000b200141016a2005105e000b20024103410220011b3a0028200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022903d880042209422088210e20022802e08004210141052104410021052013450d002003102e0b20004101360200200041106a2001360200200041086a200e422086200942ffffffff0f838437020020002005410874200441ff0171723602040c0e0b200241c0006a20011097040240024020022802404101470d00200228024422044108762101200241c0006a41086a2903002209422088210e200241d0006a28020021060c010b200241e880046a200241d4006a280200360200200241e080046a200241cc006a290200370300200220022902443703d880044100210c41002101410021050240024002400240024002400240024002400240034002402001411f4d0d00410f2104410021050c0b0b20022802e08004220a20022802e480042204460d09200441016a22032004490d02200a2003490d0120022802d8800420046a2d00002104200220033602e48004200441ff00712001411f71742005722105200141076a21012004418001710d000b024020014120490d002004410f4d0d00410d2104410021050c0a0b02400240024020050d0041002116410421030c010b410421034100210a41002116410021130340200241c0006a200241d880046a109104200228024c210c2002280248210f20022802442110024020022802404101470d0020022802502106200f2105201021040c0a0b200241c0006a200241d880046a109104200228024c21112002280248211420022802442112024020022802404101470d0020022802502106201421052011210c201221040c090b024002400240024002400240024002400240024002400240024002400240024020022802e08004220620022802e48004220b460d00200b41016a2201200b490d02200620014f0d0120012006105e000b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022802282105200229022c210e4105210741002115410021060c160b20022802d88004220d200b6a2d00002104200220013602e48004410021150240200441034d0d0041092107410021060c160b024002400240024020040e0400010203000b410021154100210441002107034002402004411f4d0d00410f21070c180b0240024020062001460d002001417f460d072006200141016a22084f0d01200141016a2006105e000b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022802282105200229022c210e41052107410021150c190b200d20016a2d0000210b200220083602e48004200b41ff00712004411f71742007722107200441076a210420082101200b418001710d000b4100211520044120490d0f200b410f4d0d0f410d21070c160b0240024020062001460d00200b41026a21042001417f460d0620062004490d07200d20016a2c00002101200220043602e4800402402001417f4a0d00411821050c0e0b200141c000710d010c0c0b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a042002290328210920022802302104410521050c0c0b200141807f7222014170470d0a200241c0006a200241d880046a108f042002290348210920022802442107024020022802404101470d00200228025021040c0d0b410121150c0f0b200241c0006a200241d880046a108f042002290348210920022802442107024020022802404101460d00410221150c0f0b200220022802503602482007418080807871211520074180807c712106200741087621040c0c0b0240024020062001460d00200b41026a21082001417f460d0620062008490d08200d20016a2c00002104200220083602e480040240200441004e0d0041182107410021060c180b200441c000710d010c090b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0441052107200229022c210e20022802282105410021060c160b200441807f72220441ff017141fc01490d070240024020062008460d00200b41036a21012008417f460d07200620014f0d0120012006105e000b200241013a00c880042002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022802282105200229022c210e41052107410021060c160b200d20086a2d0000210b200220013602e48004410021060240200b41014d0d00410c210741002115200b21040c160b2004417f732104410321150240200b0e020e000e0b410121060c0d0b417f20011035000b417f200141016a1035000b417f20041035000b20042006105e000b417f20081035000b417f20011035000b20082006105e000b41062107410021060c0d0b410721050b200141ff017141087420057221070b200220043602482007418080807871211520074180807c712106200741087621040b200220093703402002290244210e2009a721050c090b0b024020162013470d0020164101742201201641016a220b200b2001491b2201ad42287e220e422088a70d11200ea7220b4100480d110240024020160d00200b102921030c010b2003201641286c200b102a21030b2003450d03200121160b2003201341286c6a2201201236020c2001200c3602082001200f36020420012010360200200141206a20093702002001411c6a20073602002001411a6a20063a0000200141196a20043a0000200141186a20153a0000200141146a2011360200200141106a2014360200200a41286a210a201341016a2201211320012005470d000b0b20022802e4800420022802e88004462101024020022802dc8004450d0020022802d88004102e0b2001450d082005ad4220862016ad842109410321040c120b200b4104102c000b2003200a105e000b417f20031035000b0b41002106410021040b200741ff0171200441ff0171410874722006418080fc0771722015722104200e422088a72106200ea7210c2014450d002012102e0b200f450d002010102e0b02402013450d002003210103400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141286a2101200a41586a220a0d000b0b2016450d022003102e0c020b20024103410220011b3a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a04200229032821092002280230210602402005450d00200541286c21042003210103400240200141046a280200450d002001280200102e0b0240200141106a280200450d002001410c6a280200102e0b200141286a2101200441586a22040d000b0b2009422088210e41052104410021012016450d022003102e0c020b200241013a00c88004200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241c880046a360220200241286a200241c0006a108a0420022903282209422088a7210c200228023021062009a72105410521040b20044108762101200cad220e4220862005ad84210920022802dc8004450d0020022802d88004102e0b20004101360200200041106a2006360200200041086a200e422086200942ffffffff0f838437020020002001410874200441ff0171723602040c0d0b200241c0006a20011097040240024020022802404101470d00200228024422014108762105200241c0006a41086a2903002209422088210e200241d0006a28020021040c010b200241d4006a2802002113200241d0006a2802002101200241cc006a2802002105200241c8006a28020021072002280244210c41002108410021044100210a024002400240024002400240024002400240034002402004411f4d0d00410f21014100210a0c0a0b20052001460d082001417f460d022005200141016a2206490d01200c20016a2d0000220341ff00712004411f7174200a72210a200441076a2104200621012003418001710d000b024020044120490d002003410f4d0d00410d21014100210a0c090b024002400240200a0d0041002112410421030c010b410120056b210d4100210b4104210341002112410021110340024002400240024002400240024002400240024020052006460d00200641016a22012006490d0120052001490d050240200c20066a2d0000221641e000460d004117210f0c130b201141016a211a200641026a2101410021164100210441002108034002402004411f4d0d00410f210f0c0a0b200d20016a4102460d082001450d0320052001490d07200c20016a417f6a2d0000220641ff00712004411f71742008722108200141016a2101200441076a21042006418001710d000b024020044120490d002006410f4d0d00410d210f0c090b2001417f6a210441002115410121100240024020080d00410021170c010b4100211441002106410021170340024002400240024020052004460d00200120066a2216450d09200520164f0d0120162005105e000b200241013a00282002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022802d88004210a20022802dc8004210820022802e0800421014105210f0c010b02400240200c20046a2c0000221641004e0d004118210f0c010b4106210f201641c00071450d00201641807f72221641ff017141fb014b0d020b0b2017450d0b2010102e0c0b0b200641016a210f024020062017470d002014200f200f2014491b22174100480d1b0240024020060d002017102921100c010b201020062017102a21100b20100d0020174101102c000b200441016a2104201020066a2016417f733a0000201441026a2114200f21062008200f470d000b0b2010411076411074221f201041087641ff0171410874221872201041ff017122107221144100210103404100211602402015411f4d0d00410f210f0c130b0240024020052004460d002004417f460d072005200441016a22064f0d01200441016a2005105e000b200241013a00282002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022802d88004210a20022802dc8004210820022d00e08004210120022d00e18004210520022f01e2800421044105210f0c130b200c20046a2d0000220f41ff00712015411f71742001722101201541076a211520062104200f418001710d000b20154120490d09200f410f4d0d09410d210f0c110b200241013a00282002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022802d88004210a20022802dc8004210820022d00e08004210120022d00e18004210520022f01e2800421044105210f0c110b417f20011035000b417f20011035000b417f20161035000b417f200441016a1035000b20012005105e000b20012005105e000b200241013a00282002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022903d880042209422088a7210820022802e0800421012009a7210a4105210f0b20014110762104200141087621050c090b0240200141014d0d004104210f41aea1c500210a412421080c070b02400240024020010e020001000b410421040c010b20052006460d06024002400240200641016a22012006490d0020052001490d010240200c20066a2c0000221641004e0d004118210f0c0c0b4106210f201641c00071450d02201641807f72221641ff017141fb014d0d022016417f732104200121060c030b417f200641016a1035000b200641016a2005105e000b0c080b024020122011470d0020124101742201201241016a221620162001491b220141ffffffff00712001470d0f200141047422164100480d0f0240024020120d002016102921030c010b200320124104742016102a21030b2003450d03200121120b200320114104746a220120194180807c71200441ff01714108747241e00072221936020c200120083602082001201736020420012018201072201f72360200200b41106a210b201a2111201a200a470d000b0b2006201346210102402007450d00200c102e0b2001450d07200aad4220862012ad842109410221040c100b20164104102c000b200141016a2005105e000b417f200141016a1035000b200241013a00282002410136025420024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022802d88004210a20022802dc8004210820022d00e08004210120022d00e18004210520022f01e2800421044105210f0b0b2017450d002014102e0b200541ff0171410874200141ff017172210520044110742104201641ff0171410874210602402011450d002003210103400240200141046a280200450d002001280200102e0b200141106a2101200b41706a220b0d000b0b200520047221042006200f7221012012450d022003102e0c020b20024103410220011b3a0028200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022903d88004210920022802e0800421040240200a450d00200a41047421052003210103400240200141046a280200450d002001280200102e0b200141106a2101200541706a22050d000b0b2009422088210e41052101410021052012450d022003102e0c020b200241013a0028200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022903d880042209422088a7210820022802e0800421042009a7210a410521010b200141087621052008ad220e422086200aad8421092007450d00200c102e0b20004101360200200041106a2004360200200041086a200e422086200942ffffffff0f838437020020002005410874200141ff0171723602040c0c0b410021014100210402400340410021080240200a4105470d00410f21070c0b0b2003200a460d032003200a4d0d012006200a6a2d0000220541ff00712001411f71742004722104200141076a2101200a41016a220c210a2005418001710d000b024020014120490d002005410f4d0d00410d21070c0a0b024020040d0041002105410121134100210a4100210d0c050b200241c0006a410041800810f5041a410121134100210d4100210541002107034002400240024002402003200c6b200420076b22014180082001418008491b2201490d00200c20016a2216200c490d02200320164f0d0120162003105e000b200241013a00c88004200241ec80046a4101360200200242013702dc8004200241e8d4c5003602d88004200241213602242002200241206a3602e880042002200241c880046a360220200241286a200241d880046a108a0420022903282209422088a7210a200228023021012009a72104410521070240200d0d002004210d0c0f0b2013102e2004210d0c0e0b200241c0006a2006200c6a200110f6041a0240200d20056b2001490d00200120056a210a0c020b200520016a220a2005490d04200d410174220c200a200a200c491b220c4100480d0402400240200d0d00200c102921130c010b2013200d200c102a21130b02402013450d00200c210d0c020b200c4101102c000b200c20161035000b201320056a200241c0006a200110f6041a2016210c200a21052004200120076a22074d0d040c000b0b200a41016a2003105e000b102d000b200241013a0028200241d4006a410136020020024201370244200241e8d4c500360240200241213602242002200241206a3602502002200241286a360220200241d880046a200241c0006a108a0420022903d880042209422088a7210a20022802e0800421012009a7210d410521070c070b200241c0006a2013200a10cd02024020022802404101470d00410821070240200d0d000c080b2013102e0c070b201341087621052016210c0b2003200c490d012003200c6b2204417f4c0d020240024020040d00410121010c010b200410292201450d0420012006200c6a200410f6041a0b200aad4220862109200dad210e2004ad222842208621290240200b450d002006102e0b2009200e8421092029202884210e2005410874201341ff0171722103410121040b200020043a000420004100360200200041056a20022f001d3b0000200041186a200e370200200041146a20013602002000410c6a2009370200200041086a2003360200200041206a200229020c370200200041076a2002411f6a2d00003a0000200041286a2002410c6a41086a2902003702000c060b200c20031035000b1032000b20044101102c000b4100210a4100210d0b200aad422086200dad842109200b450d002006102e0b20004101360200200041106a2001360200200041086a200937020020002008410874200741ff0171723602040b200241f080046a24000bf404010b7f230041c080016b2202240020022001109404410121030240024020022802004101470d0020002002290204370204200041013602002000410c6a2002410c6a2902003702000c010b20022802042104200241004180800110f5042105410021064100210702400240024002402004450d00410021084100210641012103410021090340024002402001280204220a200128020822076b200420096b220b41808001200b41808001491b220b490d002007200b6a220c2007490d04200a200c4f0d01200c200a105e000b200541013a008f8001200541b480016a4101360200200542013702a48001200541e8d4c5003602a08001200541213602bc80012005200541b880016a3602b0800120052005418f80016a3602b880012005419080016a200541a080016a108a042005418b80016a2005419880016a2802003600002005200529039080013700838001200041053a00042000200529008080013700052000410c6a2005418780016a290000370000200041013602002006450d062003102e0c060b2005200128020020076a200b10f604210a2001200c36020802400240200620086b200b490d00200b20086a21070c010b2008200b6a22072008490d052006410174220c20072007200c491b220c4100480d050240024020060d00200c102921030c010b20032006200c102a21030b2003450d04200c21060b200320086a200a200b10f6041a200721082004200b20096a22094b0d000b0b2000200336020420004100360200200041146a2007360200200041106a41003602002000410c6a2007360200200041086a20063602000c030b2007200c1035000b200c4101102c000b102d000b200241c080016a24000b0e0020003502004101200110b5010bf60201037f230041c0006b22022400200141086a2802002103200128020421042002200128020022013602100240024002402001418080044b0d0002402004450d0020022003360214200120034b0d022003418080044d0d002002413c6a41013602002002420237022c200241e0b1c5003602282002410136021c200241bcb1c5003602182002200241186a3602382002200241286a108a040c030b200241003602000c020b2002413c6a41013602002002420237022c200241c0b1c5003602282002410136021c200241bcb1c5003602182002200241186a3602382002200241286a108a040c010b200241246a41013602002002413c6a41023602002002420237022c200241d0b1c5003602282002410136021c2002200241186a3602382002200241106a3602202002200241146a3602182002200241286a108a040b024002402002280200450d0020002002290300370200200041086a200241086a2802003602000c010b200041003602000b200241c0006a24000bf90501037f230041f0006b2204240002400240024002400240024020012802084102460d00412e10292201450d01200041013a0000200141266a41002900d4b345370000200141206a41002900ceb345370000200141186a41002900c6b345370000200141106a41002900beb345370000200141086a41002900b6b345370000200141002900aeb345370000200041086a42ae808080e005370200200041046a20013602000c050b02400240024002400240200128020022052d0000416e6a2201411e4b0d004100210620010e1f03000000000000000000000000000000000000000000000000000008040102030b412010292201450d05200041013a0000200141186a41002900f4b345370000200141106a41002900ecb345370000200141086a41002900e4b345370000200141002900dcb345370000200041086a42a08080808004370200200041046a20013602000c080b410221060c060b410321060c050b20042005280204220136020c0240024020012003490d0041fcb3c5002105200441e8006a2103200441d0006a2101200441c0006a21020c010b200220014101746a22012d0001450d04418cb4c5002105200441386a2103200441206a2101200441106a21020b20034101360204200141146a410136020020012003360210200142023702042001200536020020032004410c6a36020020022001108a04200041013a00002000410c6a200241086a280200360200200041046a20022902003702000c050b410121060c030b412e4101102c000b41204101102c000b20012d000021060b0240200541106a2d00004106470d00200041003a0000200020063a00010c010b0240412910292201450d00200041013a0000200141286a41002d00c4b4453a0000200141206a41002900bcb445370000200141186a41002900b4b445370000200141106a41002900acb445370000200141086a41002900a4b4453700002001410029009cb445370000200041086a42a98080809005370200200041046a20013602000c010b41294101102c000b200441f0006a24000b8f0201017f230041106b220224000240024002400240024020002d00000e0401020300010b2002200128021841b8d4c50041032001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c030b2002200128021841bbd4c50041032001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c020b2002200128021841bed4c50041032001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c010b2002200128021841c1d4c50041032001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040b200241106a240020000bf5c30103077f027e027f230041f0006b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022d00000eac0100df010102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01000b02400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810292200450dab012003421837025c20032000360258200341d8006a4100411810a20420032003280260220041186a3602602000200328025822016a411841eab6c500411810a3042003200329025c37025c2003200136025841faabc500413b200341d8006a41b8acc5001053000b02400240200128022820044103746a22052802002206200141206a28020022024b0d002006200220062002491b21040c010b024002402001411c6a280200220420026b200620026b2207490d0020012802182108200221040c010b200220076a22082002490dde0120044101742209200820082009491b22094100480dde010240024020040d002009102921080c010b200128021820042009102a21080b2008450dad01200120083602182001411c6a2009360200200141206a28020021040b200820046a21090240024020074102490d002009410420062002417f736a220210f5041a2008200220046a22046a21090c010b2007450d010b200941043a0000200441016a21040b200141206a2004360200200541013a00060cde010b0240200141306a2802002204200141346a22062802004f0d002002310001210a200141206a350200210b024020042001412c6a280200470d00200441016a22022004490ddd0120044101742206200220022006491b220241ffffffff01712002470ddd01200241037422064100480ddd010240024020040d002006102921040c010b200128022820044103742006102a21040b2004450dad01200120043602282001412c6a2002360200200141306a28020021040b200128022820044103746a200a422886200b84370200200141306a2201200128020041016a3602000cde010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200636020020032003360268200341106a200341d8006a108a0420032802102202450ddd012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450ddd012000200329023c370204200020013602000cde010b0240200141306a2802002204200141346a22062802004f0d002002310001210a200141206a350200210b024020042001412c6a280200470d00200441016a22022004490ddc0120044101742206200220022006491b220241ffffffff01712002470ddc01200241037422064100480ddc010240024020040d002006102921040c010b200128022820044103742006102a21040b2004450dad01200120043602282001412c6a2002360200200141306a28020021040b200128022820044103746a200a422886200b8442808080803084370200200141306a2201200128020041016a3602000cdd010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200636020020032003360268200341106a200341d8006a108a0420032802102202450ddc012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450ddc012000200329023c370204200020013602000cdd010b2002310001210a200341d8006a200141186a200141286a2204410010a404024020032d00584101470d002000200329025c370200200041086a200341e4006a2802003602000cdd010b0240200141306a2802002202200141346a22062802004f0d00200141206a350200210b024020022001412c6a280200470d00200241016a22062002490ddb0120024101742205200620062005491b220641ffffffff01712006470ddb01200641037422054100480ddb010240024020020d002005102921020c010b200428020020024103742005102a21020b2002450dad01200120023602282001412c6a2006360200200141306a28020021020b200128022820024103746a200a422886200b8442808080801084370200200141306a2201200128020041016a3602000cdc010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200636020020032003360268200341106a200341d8006a108a0420032802102202450ddb012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450ddb012000200329023c370204200020013602000cdc010b02400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810292200450dac012003421837025c20032000360258200341d8006a4100411810a20420032003280260220041186a3602602000200328025822016a411841eab6c500411810a3042003200329025c37025c2003200136025841c8acc5004134200341d8006a41b8acc5001053000b02400240200141286a220228020020044103746a22042d00044101470d002004310005210a200341d8006a200141186a200210a5042003280258450d0120002003290358370200200041086a200341d8006a41086a2802003602000cdd010b411a10292201450dad01200141186a41002f0094ad453b0000200141106a410029008cad45370000200141086a4100290084ad45370000200141002900fcac453700002000429a808080a003370204200020013602000cdc010b0240200141306a2802002204200141346a22062802004f0d00200141206a350200210b024020042001412c6a280200470d00200441016a22062004490dda0120044101742205200620062005491b220641ffffffff01712006470dda01200641037422054100480dda010240024020040d002005102921020c010b200228020020044103742005102a21020b2002450daf01200120023602282001412c6a2006360200200141306a28020021040b200128022820044103746a200a422886200b8442808080802084370200200141306a2201200128020041016a3602000cdb010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200636020020032003360268200341106a200341d8006a108a0420032802102202450dda012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450dda012000200329023c370204200020013602000cdb010b02400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810292200450dae012003421837025c20032000360258200341d8006a4100411810a20420032003280260220041186a3602602000200328025822016a411841eab6c500411810a3042003200329025c37025c2003200136025841c8acc5004134200341d8006a41b8acc5001053000b200141286a220528020020044103746a22042d00052106024020042d00044101470d00200641ff01714104470daf010b0240024020024101460d00200341d8006a200141186a2202200510a5042003280258450d0120002003290358370200200041086a200341d8006a41086a2802003602000cdc010b20012d003822024104460dd901200341d8006a200141186a22062005200210a4040240024020032d00584101460d000240200141206a2802002204200141246a22082802004f0d00024020042001411c6a280200470d00200441016a22082004490ddc0120044101742207200820082007491b22084100480ddc010240024020040d002008102921040c010b200628020020042008102a21040b2004450db401200120043602182001411c6a2008360200200141206a28020021040b200128021820046a20023a0000200141206a2202200228020041016a3602000cdc010b200341ec006a220241013602002003420137025c200341e4b7c500360258200341013602042003200836020020032003360268200341106a200341d8006a108a0420032802102204450ddb012003200329021437021420032004360210200241013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382202450ddb01200329023c210a0c010b200328025c2202450dda01200341e0006a290300210a0b2000200a370204200020023602000cdb010b200641ff01714104460dd9010240200141206a2802002204200141246a22052802004f0d00024020042001411c6a280200470d00200441016a22052004490dd90120044101742208200520052008491b22054100480dd9010240024020040d002005102921020c010b200228020020042005102a21020b2002450db201200120023602182001411c6a2005360200200141206a28020021040b200128021820046a20063a0000200141206a2201200128020041016a3602000cda010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200536020020032003360268200341106a200341d8006a108a0420032802102202450dd9012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450dd9012000200329023c370204200020013602000cda010b2003200241046a280200220236024802400240200141306a280200220420024d0d0020042002417f736a22022004490d0141c6b7c500411d109b01000b200341ec006a220241023602002003411c6a41013602002003420237025c20034184b7c50036025820034101360214200320043602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a108a04200328023821042003200329023c37021420032004360210200241013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a042003280214450dd1012003280210102e0cd1010b200141286a220428020020024103746a22022d00044103460dd10120022d0005220241ff01714104460dd101200341d8006a200141186a22062004200210a404024020032d00584101460d000240200141206a2802002204200141246a22052802004f0d00024020042001411c6a280200470d00200441016a22052004490dd90120044101742208200520052008491b22054100480dd9010240024020040d002005102921040c010b200628020020042005102a21040b2004450db301200120043602182001411c6a2005360200200141206a28020021040b200128021820046a20023a0000200141206a2202200228020041016a3602000cd3010b200341ec006a220241013602002003420137025c200341e4b7c500360258200341013602042003200536020020032003360268200341106a200341d8006a108a0420032802102204450dd2012003200329021437021420032004360210200241013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a042003280214450dd1012003280210102e0cd1010b200328025c2202450dd101200341e0006a290300210a0cd2010b200241046a2802002102200341d8006a200141186a2205200141286a2206410010a4040240024020032d00584101470d00200341e0006a290300210a200328025c22010d010cd9010b200141306a28020021042003200236024802400240200420024d0d0020042002417f736a22022004490d0141c6b7c500411d109b01000b200341ec006a220141023602002003411c6a41013602002003420237025c20034184b7c50036025820034101360214200320043602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a108a04200328023821022003200329023c37021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b200329023c210a200328023822010d010cd9010b200628020020024103746a22022d00044103460dd80120022d0005220241ff01714104460dd801200341d8006a20052006200210a404024020032d00584101460d000240200141206a2802002204200141246a22062802004f0d00024020042001411c6a280200470d00200441016a22062004490dd90120044101742208200620062008491b22064100480dd9010240024020040d002006102921040c010b200528020020042006102a21040b2004450db401200120043602182001411c6a2006360200200141206a28020021040b200128021820046a20023a0000200141206a2201200128020041016a3602000cda010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200636020020032003360268200341106a200341d8006a108a0420032802102202450dd9012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450dd901200329023c210a0c010b200328025c2201450dd801200341e0006a290300210a0b2000200a370204200020013602000cd8010b200241086a2802002105200241046a280200210420032002410c6a280200220636024802400240200141306a280200220220064d0d0020022006417f736a22062002490d0141c6b7c500411d109b01000b200341ec006a22044102360200200341106a410c6a41013602002003420237025c20034184b7c50036025820034101360214200320023602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a108a04200328023821022003200329023c37021420032002360210200441013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b2003200329023c370204200320032802383602000ccd010b410421090240200141286a220c280200220820064103746a22062d00044103460d0020062d000521090b200320093a00302005450dc801200941ff0171220d4104460dc701200541027421050340200320042802002206360248200220064d0dca0120022006417f736a220620024f0dce01200820064103746a22062d00044103460dcb0120062d000522074104460dcb01200d2007470dcb01200441046a21042005417c6a22050d000cc9010b0b20012d003822024104460dc501200341d8006a200141186a2206200141286a200210a4040240024020032d00584101460d000240200141206a2802002204200141246a22052802004f0d00024020042001411c6a280200470d00200441016a22052004490dd70120044101742208200520052008491b22054100480dd7010240024020040d002005102921040c010b200628020020042005102a21040b2004450db301200120043602182001411c6a2005360200200141206a28020021040b200128021820046a20023a0000200141206a2202200228020041016a3602000cc8010b200341ec006a220241013602002003420137025c200341e4b7c500360258200341013602042003200536020020032003360268200341106a200341d8006a108a0420032802102204450dc7012003200329021437021420032004360210200241013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382202450dc701200329023c210a0c010b200328025c2202450dc601200341e0006a290300210a0b2000200a370204200020023602000cd6010b200128020021042003200241046a2802002202360254024002400240200441386a28020020024b0d00200341ec006a41013602002003420237025c200341ccb5c500360258200341013602342003200341306a3602682003200341d4006a360230200341386a200341d8006a108a04200341186a200329023c370300200341013602102003200328023822043602140c010b2003200428023020024102746a2802002202360200024002402004412c6a28020020024b0d0041012106200341ec006a41013602002003420237025c200341dcb5c5003602582003410136024c2003200341c8006a36026820032003360248200341386a200341d8006a108a04200341186a200329023c220a370300200a422088a7210820032802382104200aa721020c010b2003411c6a200428022420024104746a22042d000d22083a0000200341186a2004280208220236020020042802002104410021060b20032006360210200320043602142006450d010b200341186a21010cc3010b02402002450d002004417f6a2104200141286a2106200141186a21050340200341d8006a20052006200420026a2d000010a404024020032d00584101470d00200341e0006a2101200328025c21040cc5010b2002417f6a22020d000b0b200841ff01714104460dd4010240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490dd40120024101742206200420042006491b22044100480dd4010240024020020d002004102921020c010b200128021820022004102a21020b2002450db101200120023602182001411c6a2004360200200141206a28020021020b200128021820026a20083a0000200141206a2201200128020041016a3602000cd5010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200436020020032003360268200341106a200341d8006a108a0420032802102202450dd4012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382204450dd401200329023c210a0cc3010b200241046a28020021052001280200210220034100360238024002400240200241146a2802000d00200341d8006a41146a41013602002003420237025c200341acb5c50036025820034101360204200320033602682003200341386a360200200341106a200341d8006a108a040c010b200341d8006a200141186a2204200141286a2206410010a404024020032d00584101470d00200341e0006a290300210a0cc2010b20012802002208412c6a280200210220032005360238200220054b0d01200341ec006a41013602002003420237025c200341dcb5c50036025820034101360204200320033602682003200341386a360200200341106a200341d8006a108a040b2003290214210a200328021022010dc1010cd4010b200828022420054104746a22052d000d2108024020052802082202450d002005280200417f6a21050340200341d8006a20042006200520026a2d000010a404024020032d00584101470d00200341e0006a290300210a0cc2010b2002417f6a22020d000b0b200841ff01714104460dd3010240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490dd30120024101742205200620062005491b22064100480dd3010240024020020d002006102921020c010b200428020020022006102a21020b2002450db101200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20083a0000200141206a2201200128020041016a3602000cd4010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200636020020032003360268200341106a200341d8006a108a0420032802102202450dd3012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450dd301200329023c210a0cc0010b200341d8006a200141186a200141286a410410a40420032d00584101470dd201200328025c2201450dd2012000200341e0006a290300370204200020013602000cd3010b200341d8006a200141186a2204200141286a2206410010a404200341d8006a21020240024020032d00584101460d00200341d8006a20042006410410a404200341d8006a210220032d00584101460d00200341d8006a2004200620032d0059220510a404200341d8006a210220032d00584101460d000240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490dd30120024101742208200620062008491b22064100480dd3010240024020020d002006102921020c010b200428020020022006102a21020b2002450db201200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20053a0000200141206a2201200128020041016a3602000cd4010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200636020020032003360268200341106a200341d8006a108a0420032802102202450dd3012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450dd301200329023c210a0c010b200241046a2802002201450dd201200241086a290200210a0b2000200a370204200020013602000cd2010b200341d8006a200141046a200241046a28020010a6040240024020032d00584101460d000240200141206a2802002202200141246a22042802004f0d0020032d00592104024020022001411c6a280200470d00200241016a22062002490dd20120024101742205200620062005491b22064100480dd2010240024020020d002006102921020c010b200128021820022006102a21020b2002450db201200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20043a0000200141206a2201200128020041016a3602000cd3010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200436020020032003360268200341106a200341d8006a108a0420032802102202450dd2012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450dd201200329023c210a0c010b200328025c2201450dd101200341e0006a290300210a0b2000200a370204200020013602000cd1010b2003200241046a2802002202360200200341d8006a200141046a200210a604024020032d00584101470d002003200328025c22013602382003200341e0006a290300220a37023c0cbb010b200320032d005922023a0030200341d8006a200141186a200141286a410410a404024020032d00584101470d00200341c0006a200341e4006a2802003602002003200329025c3703380cba010b200320032d005922013a004820014104460dcf01200241ff01712001460dcf01200341106a41146a41273602002003411c6a4122360200200341d8006a41146a41033602002003420337025c200341b8adc500360258200341013602142003200341106a3602682003200341c8006a3602202003200341306a36021820032003360210200341386a200341d8006a108a040cb9010b200341d8006a200141046a200241046a28020010a6040240024020032d00584101460d00200341d8006a200141186a2206200141286a20032d0059220410a404024020032d00584101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490dd10120024101742208200520052008491b22054100480dd1010240024020020d002005102921020c010b200628020020022005102a21020b2002450db201200120023602182001411c6a2005360200200141206a28020021020b200128021820026a20043a0000200141206a2201200128020041016a3602000cd2010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200536020020032003360268200341106a200341d8006a108a0420032802102202450dd1012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450dd101200329023c210a0c020b200328025c2201450dd001200341e0006a290300210a0c010b200328025c2201450dcf01200341e0006a290300210a0b2000200a370204200020013602000ccf010b200128020021042003200241046a280200220236023802400240200441206a28020020024d0d000240200141206a2802002206200141246a22052802004f0d00200428021820024101746a2d00002102024020062001411c6a280200470d00200641016a22042006490dcf0120064101742205200420042005491b22044100480dcf010240024020060d002004102921060c010b200128021820062004102a21060b2006450db101200120063602182001411c6a2004360200200141206a28020021060b200128021820066a20023a0000200141206a2201200128020041016a3602000cd0010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200536020020032003360268200341106a200341d8006a108a0420032802102202450dcf012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450dcf01200329023c210a0c010b200341ec006a41013602002003420237025c200341fcb5c5003602582003410136024c2003200341c8006a3602682003200341386a360248200341106a200341d8006a108a0420032802102201450dce012003290214210a0b2000200a370204200020013602000cce010b2003200241046a28020022023602282001280200210420032002360254024002400240200441206a28020020024b0d00200341ec006a41013602002003420237025c200341fcb5c5003602582003410136024c2003200341c8006a3602682003200341d4006a360248200341106a200341d8006a108a040c010b200428021820024101746a22022d00010d01200341ec006a41013602002003420237025c2003418cb6c50036025820034101360204200320033602682003200341d4006a360200200341106a200341d8006a108a040b2003280210210120032003290214220a37023c200320013602380cb6010b200320022d000022023a002f200341d8006a200141186a200141286a410410a404024020032d00584101470d00200341c0006a200341e4006a2802003602002003200329025c3703380cb5010b200320032d005922013a00002001200241ff0171460dcc0120014104460dcc01200341106a41146a41273602002003411c6a4127360200200341d8006a41146a41033602002003420337025c200341d0adc500360258200341013602142003200341106a3602682003200336022020032003412f6a3602182003200341286a360210200341386a200341d8006a108a040cb4010b200341d8006a2001200241046a2802004104410010a8042003280258450dcb0120002003290358370200200041086a200341d8006a41086a2802003602000ccc010b200341d8006a2001200241046a2802004108410110a8042003280258450dca0120002003290358370200200041086a200341d8006a41086a2802003602000ccb010b200341d8006a2001200241046a2802004104410210a8042003280258450dc90120002003290358370200200041086a200341d8006a41086a2802003602000cca010b200341d8006a2001200241046a2802004108410310a8042003280258450dc80120002003290358370200200041086a200341d8006a41086a2802003602000cc9010b200341d8006a2001200241046a2802004101410010a8042003280258450dc70120002003290358370200200041086a200341d8006a41086a2802003602000cc8010b200341d8006a2001200241046a2802004101410010a8042003280258450dc60120002003290358370200200041086a200341d8006a41086a2802003602000cc7010b200341d8006a2001200241046a2802004102410010a8042003280258450dc50120002003290358370200200041086a200341d8006a41086a2802003602000cc6010b200341d8006a2001200241046a2802004102410010a8042003280258450dc40120002003290358370200200041086a200341d8006a41086a2802003602000cc5010b200341d8006a2001200241046a2802004101410110a8042003280258450dc30120002003290358370200200041086a200341d8006a41086a2802003602000cc4010b200341d8006a2001200241046a2802004101410110a8042003280258450dc20120002003290358370200200041086a200341d8006a41086a2802003602000cc3010b200341d8006a2001200241046a2802004102410110a8042003280258450dc10120002003290358370200200041086a200341d8006a41086a2802003602000cc2010b200341d8006a2001200241046a2802004102410110a8042003280258450dc00120002003290358370200200041086a200341d8006a41086a2802003602000cc1010b200341d8006a2001200241046a2802004104410110a8042003280258450dbf0120002003290358370200200041086a200341d8006a41086a2802003602000cc0010b200341d8006a2001200241046a2802004104410110a8042003280258450dbe0120002003290358370200200041086a200341d8006a41086a2802003602000cbf010b200341d8006a2001200241046a2802004104410010a9042003280258450dbd0120002003290358370200200041086a200341d8006a41086a2802003602000cbe010b200341d8006a2001200241046a2802004108410110a9042003280258450dbc0120002003290358370200200041086a200341d8006a41086a2802003602000cbd010b200341d8006a2001200241046a2802004104410210a9042003280258450dbb0120002003290358370200200041086a200341d8006a41086a2802003602000cbc010b200341d8006a2001200241046a2802004108410310a9042003280258450dba0120002003290358370200200041086a200341d8006a41086a2802003602000cbb010b200341d8006a2001200241046a2802004101410010a9042003280258450db90120002003290358370200200041086a200341d8006a41086a2802003602000cba010b200341d8006a2001200241046a2802004102410010a9042003280258450db80120002003290358370200200041086a200341d8006a41086a2802003602000cb9010b200341d8006a2001200241046a2802004101410110a9042003280258450db70120002003290358370200200041086a200341d8006a41086a2802003602000cb8010b200341d8006a2001200241046a2802004102410110a9042003280258450db60120002003290358370200200041086a200341d8006a41086a2802003602000cb7010b200341d8006a2001200241046a2802004104410110a9042003280258450db50120002003290358370200200041086a200341d8006a41086a2802003602000cb6010b20012802002102200341003602380240024020022802080d00200341ec006a41013602002003420237025c200341fcb4c50036025820034101360204200320033602682003200341386a360200200341106a200341d8006a108a0420032802102202450d002003290214210a0c010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db50120024101742206200420042006491b22044100480db5010240024020020d002004102921020c010b200128021820022004102a21020b2002450d9801200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000cb6010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200436020020032003360268200341106a200341d8006a108a0420032802102202450db5012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382202450db501200329023c210a0b2000200a370204200020023602000cb5010b20012802002102200341003602380240024020022802080d00200341ec006a41013602002003420237025c200341fcb4c50036025820034101360204200320033602682003200341386a360200200341106a200341d8006a108a0420032802102202450d002003290214210a0c010b200341d8006a200141186a2204200141286a410010a404024020032d00584101460d000240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490db50120024101742205200620062005491b22064100480db5010240024020020d002006102921020c010b200428020020022006102a21020b2002450d9901200120023602182001411c6a2006360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000cb6010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200636020020032003360268200341106a200341d8006a108a0420032802102202450db5012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382202450db501200329023c210a0c010b200328025c2202450db401200341e0006a290300210a0b2000200a370204200020023602000cb4010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db20120024101742206200420042006491b22044100480db2010240024020020d002004102921020c010b200128021820022004102a21020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000cb3010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200436020020032003360268200341106a200341d8006a108a0420032802102202450db2012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450db2012000200329023c370204200020013602000cb3010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db10120024101742206200420042006491b22044100480db1010240024020020d002004102921020c010b200128021820022004102a21020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000cb2010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200436020020032003360268200341106a200341d8006a108a0420032802102202450db1012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450db1012000200329023c370204200020013602000cb2010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db00120024101742206200420042006491b22044100480db0010240024020020d002004102921020c010b200128021820022004102a21020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000cb1010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200436020020032003360268200341106a200341d8006a108a0420032802102202450db0012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450db0012000200329023c370204200020013602000cb1010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490daf0120024101742206200420042006491b22044100480daf010240024020020d002004102921020c010b200128021820022004102a21020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000cb0010b200341ec006a220141013602002003420137025c200341e4b7c500360258200341013602042003200436020020032003360268200341106a200341d8006a108a0420032802102202450daf012003200329021437021420032002360210200141013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382201450daf012000200329023c370204200020013602000cb0010b200341d8006a2001410010aa042003280258450dae0120002003290358370200200041086a200341d8006a41086a2802003602000caf010b200341d8006a2001410010ab042003280258450dad0120002003290358370200200041086a200341d8006a41086a2802003602000cae010b200341d8006a2001410010ab042003280258450dac0120002003290358370200200041086a200341d8006a41086a2802003602000cad010b200341d8006a2001410010ab042003280258450dab0120002003290358370200200041086a200341d8006a41086a2802003602000cac010b200341d8006a2001410010ab042003280258450daa0120002003290358370200200041086a200341d8006a41086a2802003602000cab010b200341d8006a2001410010ab042003280258450da90120002003290358370200200041086a200341d8006a41086a2802003602000caa010b200341d8006a2001410010ab042003280258450da80120002003290358370200200041086a200341d8006a41086a2802003602000ca9010b200341d8006a2001410010ab042003280258450da70120002003290358370200200041086a200341d8006a41086a2802003602000ca8010b200341d8006a2001410010ab042003280258450da60120002003290358370200200041086a200341d8006a41086a2802003602000ca7010b200341d8006a2001410010ab042003280258450da50120002003290358370200200041086a200341d8006a41086a2802003602000ca6010b200341d8006a2001410010ab042003280258450da40120002003290358370200200041086a200341d8006a41086a2802003602000ca5010b200341d8006a2001410110aa042003280258450da30120002003290358370200200041086a200341d8006a41086a2802003602000ca4010b200341d8006a2001410110ab042003280258450da20120002003290358370200200041086a200341d8006a41086a2802003602000ca3010b200341d8006a2001410110ab042003280258450da10120002003290358370200200041086a200341d8006a41086a2802003602000ca2010b200341d8006a2001410110ab042003280258450da00120002003290358370200200041086a200341d8006a41086a2802003602000ca1010b200341d8006a2001410110ab042003280258450d9f0120002003290358370200200041086a200341d8006a41086a2802003602000ca0010b200341d8006a2001410110ab042003280258450d9e0120002003290358370200200041086a200341d8006a41086a2802003602000c9f010b200341d8006a2001410110ab042003280258450d9d0120002003290358370200200041086a200341d8006a41086a2802003602000c9e010b200341d8006a2001410110ab042003280258450d9c0120002003290358370200200041086a200341d8006a41086a2802003602000c9d010b200341d8006a2001410110ab042003280258450d9b0120002003290358370200200041086a200341d8006a41086a2802003602000c9c010b200341d8006a2001410110ab042003280258450d9a0120002003290358370200200041086a200341d8006a41086a2802003602000c9b010b200341d8006a2001410110ab042003280258450d990120002003290358370200200041086a200341d8006a41086a2802003602000c9a010b200341d8006a2001410210ab042003280258450d980120002003290358370200200041086a200341d8006a41086a2802003602000c99010b200341d8006a2001410210ab042003280258450d970120002003290358370200200041086a200341d8006a41086a2802003602000c98010b200341d8006a2001410210ab042003280258450d960120002003290358370200200041086a200341d8006a41086a2802003602000c97010b200341d8006a2001410210ab042003280258450d950120002003290358370200200041086a200341d8006a41086a2802003602000c96010b200341d8006a2001410210ab042003280258450d940120002003290358370200200041086a200341d8006a41086a2802003602000c95010b200341d8006a2001410210ab042003280258450d930120002003290358370200200041086a200341d8006a41086a2802003602000c94010b200341d8006a2001410310ab042003280258450d920120002003290358370200200041086a200341d8006a41086a2802003602000c93010b200341d8006a2001410310ab042003280258450d910120002003290358370200200041086a200341d8006a41086a2802003602000c92010b200341d8006a2001410310ab042003280258450d900120002003290358370200200041086a200341d8006a41086a2802003602000c91010b200341d8006a2001410310ab042003280258450d8f0120002003290358370200200041086a200341d8006a41086a2802003602000c90010b200341d8006a2001410310ab042003280258450d8e0120002003290358370200200041086a200341d8006a41086a2802003602000c8f010b200341d8006a2001410310ab042003280258450d8d0120002003290358370200200041086a200341d8006a41086a2802003602000c8e010b200341d8006a2001410010ac042003280258450d8c0120002003290358370200200041086a200341d8006a41086a2802003602000c8d010b200341d8006a2001410010ac042003280258450d8b0120002003290358370200200041086a200341d8006a41086a2802003602000c8c010b200341d8006a2001410010ac042003280258450d8a0120002003290358370200200041086a200341d8006a41086a2802003602000c8b010b200341d8006a2001410010ad042003280258450d890120002003290358370200200041086a200341d8006a41086a2802003602000c8a010b200341d8006a2001410010ad042003280258450d880120002003290358370200200041086a200341d8006a41086a2802003602000c89010b200341d8006a2001410010ad042003280258450d870120002003290358370200200041086a200341d8006a41086a2802003602000c88010b200341d8006a2001410010ad042003280258450d860120002003290358370200200041086a200341d8006a41086a2802003602000c87010b200341d8006a2001410010ad042003280258450d850120002003290358370200200041086a200341d8006a41086a2802003602000c86010b200341d8006a2001410010ad042003280258450d840120002003290358370200200041086a200341d8006a41086a2802003602000c85010b200341d8006a2001410010ad042003280258450d830120002003290358370200200041086a200341d8006a41086a2802003602000c84010b200341d8006a2001410010ad042003280258450d820120002003290358370200200041086a200341d8006a41086a2802003602000c83010b200341d8006a2001410010ad042003280258450d810120002003290358370200200041086a200341d8006a41086a2802003602000c82010b200341d8006a2001410010ad042003280258450d800120002003290358370200200041086a200341d8006a41086a2802003602000c81010b200341d8006a2001410010ad042003280258450d7f20002003290358370200200041086a200341d8006a41086a2802003602000c80010b200341d8006a2001410010ad042003280258450d7e20002003290358370200200041086a200341d8006a41086a2802003602000c7f0b200341d8006a2001410010ad042003280258450d7d20002003290358370200200041086a200341d8006a41086a2802003602000c7e0b200341d8006a2001410010ad042003280258450d7c20002003290358370200200041086a200341d8006a41086a2802003602000c7d0b200341d8006a2001410010ad042003280258450d7b20002003290358370200200041086a200341d8006a41086a2802003602000c7c0b200341d8006a2001410110ac042003280258450d7a20002003290358370200200041086a200341d8006a41086a2802003602000c7b0b200341d8006a2001410110ac042003280258450d7920002003290358370200200041086a200341d8006a41086a2802003602000c7a0b200341d8006a2001410110ac042003280258450d7820002003290358370200200041086a200341d8006a41086a2802003602000c790b200341d8006a2001410110ad042003280258450d7720002003290358370200200041086a200341d8006a41086a2802003602000c780b200341d8006a2001410110ad042003280258450d7620002003290358370200200041086a200341d8006a41086a2802003602000c770b200341d8006a2001410110ad042003280258450d7520002003290358370200200041086a200341d8006a41086a2802003602000c760b200341d8006a2001410110ad042003280258450d7420002003290358370200200041086a200341d8006a41086a2802003602000c750b200341d8006a2001410110ad042003280258450d7320002003290358370200200041086a200341d8006a41086a2802003602000c740b200341d8006a2001410110ad042003280258450d7220002003290358370200200041086a200341d8006a41086a2802003602000c730b200341d8006a2001410110ad042003280258450d7120002003290358370200200041086a200341d8006a41086a2802003602000c720b200341d8006a2001410110ad042003280258450d7020002003290358370200200041086a200341d8006a41086a2802003602000c710b200341d8006a2001410110ad042003280258450d6f20002003290358370200200041086a200341d8006a41086a2802003602000c700b200341d8006a2001410110ad042003280258450d6e20002003290358370200200041086a200341d8006a41086a2802003602000c6f0b200341d8006a2001410110ad042003280258450d6d20002003290358370200200041086a200341d8006a41086a2802003602000c6e0b200341d8006a2001410110ad042003280258450d6c20002003290358370200200041086a200341d8006a41086a2802003602000c6d0b200341d8006a2001410110ad042003280258450d6b20002003290358370200200041086a200341d8006a41086a2802003602000c6c0b200341d8006a2001410110ad042003280258450d6a20002003290358370200200041086a200341d8006a41086a2802003602000c6b0b200341d8006a2001410110ad042003280258450d6920002003290358370200200041086a200341d8006a41086a2802003602000c6a0b200341d8006a2001410210ac042003280258450d6820002003290358370200200041086a200341d8006a41086a2802003602000c690b200341d8006a2001410210ac042003280258450d6720002003290358370200200041086a200341d8006a41086a2802003602000c680b200341d8006a2001410210ac042003280258450d6620002003290358370200200041086a200341d8006a41086a2802003602000c670b200341d8006a2001410210ac042003280258450d6520002003290358370200200041086a200341d8006a41086a2802003602000c660b200341d8006a2001410210ac042003280258450d6420002003290358370200200041086a200341d8006a41086a2802003602000c650b200341d8006a2001410210ac042003280258450d6320002003290358370200200041086a200341d8006a41086a2802003602000c640b200341d8006a2001410210ac042003280258450d6220002003290358370200200041086a200341d8006a41086a2802003602000c630b200341d8006a2001410210ad042003280258450d6120002003290358370200200041086a200341d8006a41086a2802003602000c620b200341d8006a2001410210ad042003280258450d6020002003290358370200200041086a200341d8006a41086a2802003602000c610b200341d8006a2001410210ad042003280258450d5f20002003290358370200200041086a200341d8006a41086a2802003602000c600b200341d8006a2001410210ad042003280258450d5e20002003290358370200200041086a200341d8006a41086a2802003602000c5f0b200341d8006a2001410210ad042003280258450d5d20002003290358370200200041086a200341d8006a41086a2802003602000c5e0b200341d8006a2001410210ad042003280258450d5c20002003290358370200200041086a200341d8006a41086a2802003602000c5d0b200341d8006a2001410210ad042003280258450d5b20002003290358370200200041086a200341d8006a41086a2802003602000c5c0b200341d8006a2001410310ac042003280258450d5a20002003290358370200200041086a200341d8006a41086a2802003602000c5b0b200341d8006a2001410310ac042003280258450d5920002003290358370200200041086a200341d8006a41086a2802003602000c5a0b200341d8006a2001410310ac042003280258450d5820002003290358370200200041086a200341d8006a41086a2802003602000c590b200341d8006a2001410310ac042003280258450d5720002003290358370200200041086a200341d8006a41086a2802003602000c580b200341d8006a2001410310ac042003280258450d5620002003290358370200200041086a200341d8006a41086a2802003602000c570b200341d8006a2001410310ac042003280258450d5520002003290358370200200041086a200341d8006a41086a2802003602000c560b200341d8006a2001410310ac042003280258450d5420002003290358370200200041086a200341d8006a41086a2802003602000c550b200341d8006a2001410310ad042003280258450d5320002003290358370200200041086a200341d8006a41086a2802003602000c540b200341d8006a2001410310ad042003280258450d5220002003290358370200200041086a200341d8006a41086a2802003602000c530b200341d8006a2001410310ad042003280258450d5120002003290358370200200041086a200341d8006a41086a2802003602000c520b200341d8006a2001410310ad042003280258450d5020002003290358370200200041086a200341d8006a41086a2802003602000c510b200341d8006a2001410310ad042003280258450d4f20002003290358370200200041086a200341d8006a41086a2802003602000c500b200341d8006a2001410310ad042003280258450d4e20002003290358370200200041086a200341d8006a41086a2802003602000c4f0b200341d8006a2001410310ad042003280258450d4d20002003290358370200200041086a200341d8006a41086a2802003602000c4e0b200341d8006a20014101410010ae042003280258450d4c20002003290358370200200041086a200341d8006a41086a2802003602000c4d0b200341d8006a20014102410010ae042003280258450d4b20002003290358370200200041086a200341d8006a41086a2802003602000c4c0b200341d8006a20014102410010ae042003280258450d4a20002003290358370200200041086a200341d8006a41086a2802003602000c4b0b200341d8006a20014103410010ae042003280258450d4920002003290358370200200041086a200341d8006a41086a2802003602000c4a0b200341d8006a20014103410010ae042003280258450d4820002003290358370200200041086a200341d8006a41086a2802003602000c490b200341d8006a20014100410110ae042003280258450d4720002003290358370200200041086a200341d8006a41086a2802003602000c480b200341d8006a20014100410110ae042003280258450d4620002003290358370200200041086a200341d8006a41086a2802003602000c470b200341d8006a20014102410110ae042003280258450d4520002003290358370200200041086a200341d8006a41086a2802003602000c460b200341d8006a20014102410110ae042003280258450d4420002003290358370200200041086a200341d8006a41086a2802003602000c450b200341d8006a20014103410110ae042003280258450d4320002003290358370200200041086a200341d8006a41086a2802003602000c440b200341d8006a20014103410110ae042003280258450d4220002003290358370200200041086a200341d8006a41086a2802003602000c430b200341d8006a20014100410210ae042003280258450d4120002003290358370200200041086a200341d8006a41086a2802003602000c420b200341d8006a20014100410210ae042003280258450d4020002003290358370200200041086a200341d8006a41086a2802003602000c410b200341d8006a20014101410210ae042003280258450d3f20002003290358370200200041086a200341d8006a41086a2802003602000c400b200341d8006a20014101410210ae042003280258450d3e20002003290358370200200041086a200341d8006a41086a2802003602000c3f0b200341d8006a20014103410210ae042003280258450d3d20002003290358370200200041086a200341d8006a41086a2802003602000c3e0b200341d8006a20014100410310ae042003280258450d3c20002003290358370200200041086a200341d8006a41086a2802003602000c3d0b200341d8006a20014100410310ae042003280258450d3b20002003290358370200200041086a200341d8006a41086a2802003602000c3c0b200341d8006a20014101410310ae042003280258450d3a20002003290358370200200041086a200341d8006a41086a2802003602000c3b0b200341d8006a20014101410310ae042003280258450d3920002003290358370200200041086a200341d8006a41086a2802003602000c3a0b200341d8006a20014102410310ae042003280258450d3820002003290358370200200041086a200341d8006a41086a2802003602000c390b200341d8006a20014102410010ae042003280258450d3720002003290358370200200041086a200341d8006a41086a2802003602000c380b200341d8006a20014103410110ae042003280258450d3620002003290358370200200041086a200341d8006a41086a2802003602000c370b200341d8006a20014100410210ae042003280258450d3520002003290358370200200041086a200341d8006a41086a2802003602000c360b200341d8006a20014101410310ae0420032802580d1b0c340b41184101102c000b20094101102c000b20064104102c000b20064104102c000b20054104102c000b41184101102c000b411a4101102c000b20054104102c000b41184101102c000b200341ec006a41013602002003420237025c20034198adc5003602582003412836023c2003200441056a3602382003200341386a360268200341106a200341d8006a108a04200041086a200341106a41086a280200360200200020032903103702000c2b0b20084101102c000b20054101102c000b20054101102c000b20064101102c000b20054101102c000b20044101102c000b20064101102c000b20064101102c000b20064101102c000b20054101102c000b20044101102c000b20044101102c000b20064101102c000b20044101102c000b20044101102c000b20044101102c000b20044101102c000b20002003290358370200200041086a200341d8006a41086a2802003602000c190b200329023c210a200328023821010b2001450d162000200a370204200020013602000c170b200329023c210a200328023821010b2001450d142000200a370204200020013602000c150b200328025c2201450d130b2000200a370204200020013602000c130b2004450d112001290200210a0b2000200a370204200020043602000c110b0240024002400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810292200450d012003421837025c20032000360258200341d8006a4100411810a20420032003280260220041186a3602602000200328025822016a411841eab6c500411810a3042003200329025c37025c2003200136025841faabc500413b200341d8006a41b8acc5001053000b02400240200128022820044103746a22052802002206200141206a28020022024b0d002006200220062002491b21040c010b024002402001411c6a280200220420026b200620026b2207490d0020012802182108200221040c010b200220076a22082002490d1120044101742209200820082009491b22094100480d110240024020040d002009102921080c010b200128021820042009102a21080b2008450d03200120083602182001411c6a2009360200200141206a28020021040b200820046a21090240024020074102490d002009410420062002417f736a220210f5041a2008200220046a22046a21090c010b2007450d010b200941043a0000200441016a21040b200141206a2004360200200541013a00060c110b41184101102c000b20094101102c000b200541027421050340200320042802002206360248200220064d0d0220022006417f736a220620024f0d060240200820064103746a22062d00044103460d0020062d00054104470d040b200441046a21042005417c6a22050d000b410421090b200341d8006a200141186a2202200c410010a40420032d00584101470d02200341086a200341e4006a2802003602002003200329025c3703000c030b200341ec006a220441023602002003411c6a41013602002003420237025c20034184b7c50036025820034101360214200320023602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a108a04200328023821022003200329023c37021420032002360210200441013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b2003200329023c370204200320032802383602000c020b2003411c6a4128360200200341ec006a41023602002003420237025c200341a8adc5003602582003200641056a360218200341283602142003200341106a3602682003200341306a3602102003200341d8006a108a040c010b0240200941ff01714104460d00200341d8006a2002200c200910a40402400240024020032d00584101460d000240200141206a2802002204200141246a22062802004f0d00024020042001411c6a280200470d00200441016a22062004490d0e20044101742205200620062005491b22064100480d0e0240024020040d002006102921020c010b200228020020042006102a21020b2002450d04200120023602182001411c6a2006360200200141206a28020021040b200128021820046a20093a0000200141206a2202200228020041016a3602000c040b200341ec006a220241013602002003420137025c200341e4b7c500360258200341013602042003200636020020032003360268200341106a200341d8006a108a0420032802102204450d032003200329021437021420032004360210200241013602002003420137025c200341acb1c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a108a0402402003280214450d002003280210102e0b20032802382202450d03200329023c210a0c010b200328025c2202450d02200341e0006a290300210a0b2003200a370204200320023602000c020b20064101102c000b200341003602000b024020032802002202450d0020002003290204370204200020023602000c0b0b0240024002400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810292200450d012003421837025c20032000360258200341d8006a4100411810a20420032003280260220041186a3602602000200328025822016a411841eab6c500411810a3042003200329025c37025c2003200136025841faabc500413b200341d8006a41b8acc5001053000b02400240200128022820044103746a22052802002206200141206a28020022024b0d002006200220062002491b21040c010b024002402001411c6a280200220420026b200620026b2207490d0020012802182108200221040c010b200220076a22082002490d0b20044101742209200820082009491b22094100480d0b0240024020040d002009102921080c010b200128021820042009102a21080b2008450d03200120083602182001411c6a2009360200200141206a28020021040b200820046a21090240024020074102490d002009410420062002417f736a220210f5041a2008200220046a22046a21090c010b2007450d010b200941043a0000200441016a21040b200141206a2004360200200541013a00060c0b0b41184101102c000b20094101102c000b41c6b7c500411d109b01000b20032802382202450d00200329023c210a0c010b0240200141306a2802002202417f6a220420024f0d00200420024d0d020b411810292200450d022003421837025c20032000360258200341d8006a4100411810a20420032003280260220041186a3602602000200328025822016a411841eab6c500411810a3042003200329025c37025c2003200136025841faabc500413b200341d8006a41b8acc5001053000b2000200a370204200020023602000c060b02400240200128022820044103746a22052802002206200141206a28020022024b0d002006200220062002491b21040c010b024002402001411c6a280200220420026b200620026b2207490d0020012802182108200221040c010b200220076a22082002490d0420044101742209200820082009491b22094100480d040240024020040d002009102921080c010b200128021820042009102a21080b2008450d03200120083602182001411c6a2009360200200141206a28020021040b200820046a21090240024020074102490d002009410420062002417f736a220210f5041a2008200220046a22046a21090c010b2007450d010b200941043a0000200441016a21040b200141206a2004360200200541013a00060c040b41184101102c000b20094101102c000b102d000b200341d8006a200141186a200510a5042003280258450d0020002003290358370200200041086a200341d8006a41086a2802003602000c010b200041003602000b200341f0006a24000b6501017f230041206b2202240020024129360204200220003602002001411c6a2802002100200128021821012002411c6a41013602002002420137020c200241e897c6003602082002200236021820012000200241086a10b5042101200241206a240020010b0c002000280200200110b7040bcd0201067f02400240024002402001450d0020014108490d010240200141ffffffff01712001470d00200141037441076e21010c030b41e8aac5001058000b200041106a4200370200200041086a4280808080c000370200200041046a4180abc5003602000c020b200141016a21010b02400240417f2001417f6a6776220141016a220241ffffffff01712002470d00200141086a417c712203200141056a2204490d00200320024103746a22052003490d002005417d4f0d00200510292206450d012001200241037641076c20014108491b2107200641ff01200410f504220520036a21030240200241034b0d00200520026a418001410320016b10f5041a0b200041146a2007360200200041106a41003602002000410c6a2003360200200041086a2001360200200041046a20053602000c020b41e8aac5001058000b20054104102c000b200041003a00000b9d0d02107f017e230041206b220124000240024002400240200028020c220241016a22032002490d00200041046a28020022022104024020024108490d00200241016a41037641076c21040b024020032004410176490d00200141086a2003109f0420012d00084101460d042001411c6a2802002105200141146a2802002106200141106a2802002107200128020c210820002802002209280200417f7341808182847871210a200041046a28020020096a41016a210b2000280208210c200028020c210d03400240024002400240200a0d00200941046a210203402002200b4f0d02200c41206a210c20022802002103200241046a220421022003418081828478712203418081828478460d000b200341808182847873210a2004417c6a21090b200c200a684138716a220e280200210f410021030240200e41046a28020022104104490d0041002103200f2102201021040340200228000020034105777341b9f3ddf1796c2103200241046a21022004417c6a220441034b0d000b2010417c6a22022002417c7122026b21102002200f6a41046a210f0b201041014b0d01200f21040c020b2000200d36020c2000200636020820002005200d6b3602102000280200210420002008360200200041046a22032802002102200320073602002002450d070240200241016a220341ffffffff01712003470d00200241086a417c712208200241056a490d00200820034103746a2008491a0b2004102e0c070b200f41026a21042010417e6a21102003410577200f2f00007341b9f3ddf1796c21030b200a417f6a210202402010450d00200341057720042d00007341b9f3ddf1796c21030b2002200a71210a41002102200341057741ff017341b9f3ddf1796c220f21030340200241046a2202200320077122046a2103200820046a280000418081828478712210450d000b0240200820106841037620046a20077122026a2c00004100480d002008280200418081828478716841037621020b200820026a200f41197622033a00002002417c6a20077120086a41046a20033a0000200620024103746a200e2902003702000c000b0b200241016a21044100210341002102024003400240024020034101710d00200220044f0d0320022103200241016a21020c010b200241036a220320024922080d0220032004492207450d022004200241046a20081b200420071b21020b200028020020036a220320032802002203410776417f73418182840871200341fffefdfb07726a360200410121030c000b0b20002802002102200041046a220428020041016a220341044f0d01200241046a2002200310f7041a2004280200220220002802006a41016a418001410320026b10f5041a0c020b41e8aac5001058000b200220036a20022800003600000b417f210202400240200041046a2206280200220341016a220f2003490d00200041086a21094100210b0340200b220c41016a210b0240200c20002802006a2d0000418001470d00024003402009280200200c4103746a220e2802002107410021030240200e41046a28020022084104490d004100210320072102200821040340200228000020034105777341b9f3ddf1796c2103200241046a21022004417c6a220441034b0d000b2008417c6a22022002417c7122026b2108200220076a41046a21070b02400240200841014b0d00200721020c010b200741026a21022008417e6a2108200341057720072f00007341b9f3ddf1796c21030b02402008450d00200341057720022d00007341b9f3ddf1796c21030b200628020021082000280200210741002102200341057741ff017341b9f3ddf1796c220a21030340200241046a2202200320087122046a2103200720046a280000418081828478712210450d000b0240200720106841037620046a20087122026a2c00004100480d002007280200418081828478716841037621020b2002200a20087122036b200c20036b732008714104490d01200720026a22032d000021042003200a41197622103a00002002417c6a20087120076a41046a20103a00000240200441ff01460d00200928020020024103746a220229020021112002200e290200370200200e20113702000c010b0b20002802002203200c6a41ff013a000020032006280200200c417c6a716a41046a41ff013a0000200928020020024103746a200e2902003702000c010b2007200c6a200a41197622023a00002008200c417c6a7120076a41046a20023a00000b200b200f470d000b200041046a28020022024108490d010b200241016a41037641076c21020b20002002200028020c6b3602100b200141206a24000b19002000200141186a280200360204200020012802103602000b810101017f024002400240200041046a280200220320016b20024f0d00200120026a22022001490d0220034101742201200220022001491b22014100480d020240024020030d002001102921020c010b200028020020032001102a21020b2002450d0120002002360200200041046a20013602000b0f0b20014101102c000b102d000bea0101017f230041e0006b22042400200420013602082004200336020c024020012003470d0020002002200110f6041a200441e0006a24000f0b200441286a41146a411d360200200441346a4120360200200441106a41146a41033602002004200441086a36024020042004410c6a360244200441c8006a41146a4100360200200442033702142004419ce7c5003602102004412036022c200441c8ecc5003602582004420137024c200441f0e7c5003602482004200441286a3602202004200441c8006a3602382004200441c4006a3602302004200441c0006a360228200441106a41ace8c500106a000bbb0601037f230041d0006b22042400200420033a000f0240024002400240024020022802082205417f6a220620054f0d00200620054d0d010b411810292202450d012004421837023420042002360230200441306a4100411810a20420042004280238220241186a3602382002200428023022056a411841eab6c500411810a304200420042902343702342004200536023041c8acc5004134200441306a41b8acc5001053000b200141086a2802002105200228020020064103746a2206280200210202400240024020062d0006450d0020052002460d010b024002400240200520024d0d00200141086a2005417f6a2202360200200128020020026a2d00002205417c6a220241014b0d02024020020e020400040b4118102922020d0141184101102c000b412b10292202450d05200041013a0000200241276a41002800e6b045360000200241206a41002900dfb045370000200241186a41002900d7b045370000200241106a41002900cfb045370000200241086a41002900c7b045370000200241002900bfb045370000200041086a42ab808080b005370200200041046a20023602000c060b200241106a41002900fab645370000200241086a41002900f2b645370000200241002900eab64537000020044298808080800337022420042002360220200441c4006a410136020020044201370234200441acb1c5003602302004412336024c2004200441c8006a3602402004200441206a360248200441106a200441306a108a0402402004280224450d002004280220102e0b200041013a0000200041046a20042903103702002000410c6a200441106a41086a2802003602000c050b0240200341ff017122024104460d0020052002470d020b200041003a0000200020053a00010c040b20004180083b01000c030b200420053a0048200441c4006a4102360200200441206a410c6a412736020020044202370234200441ecb0c500360230200441273602242004200441206a3602402004200441c8006a36022820042004410f6a360220200441106a200441306a108a042000410c6a200441186a280200360200200041046a2004290310370200200041013a00000c020b41184101102c000b412b4101102c000b200441d0006a24000bc00502047f017e230041d0006b22032400024002400240024002400240200241086a2802002204417f6a220520044f0d00200520044d0d010b411810292202450d01200241106a41002900fab645370000200241086a41002900f2b645370000200241002900eab64537000020034298808080800337022420032002360220200341cc006a41013602002003420137023c200341acb1c500360238200341233602142003200341106a3602482003200341206a3602102000200341386a108a042003280224450d042003280220102e0c040b0240024002402002280200220620054103746a2d000522054104460d00200341386a20012002200510a404024020032d00384101470d002000200329023c370200200041086a200341c4006a2802003602000c070b200241086a2802002204450d01200228020021060b200241086a2004417f6a2202360200200620024103746a290200220742808080808080c0ff0083428080808080808001520d010b411810292202450d02200241106a41002900fab645370000200241086a41002900f2b645370000200241002900eab64537000020034298808080800337022420032002360220200341cc006a41013602002003420137023c200341acb1c500360238200341233602142003200341106a3602482003200341206a3602102000200341386a108a042003280224450d042003280220102e0c040b200141086a28020021022003200737030820022007a7470d02200041003602000c030b41184101102c000b41184101102c000b200341cc006a41023602002003412c6a41013602002003420237023c2003418cb0c50036023820034101360224200320023602342003200341206a3602482003200341086a3602282003200341346a360220200341106a200341386a108a04200041086a200341106a41086a280200360200200020032903103702000b200341d0006a24000bad0301057f230041c0006b2203240020032002360200024002402001280204220420024b0d002001280208417c6a21052001410c6a280200410374210102400340024020010d00200320043602042003412c6a4102360200200341306a410c6a41013602002003420337021c200341b4b8c500360218200341013602342003200341306a3602282003200341046a36023820032003360230200341086a200341186a108a042000410c6a200341106a280200360200200041046a2003290308370200200041013a00000c040b02402004200541046a2802006a220620044f0d00412010292204450d02200041013a0000200441186a41002900acb845370000200441106a41002900a4b845370000200441086a410029009cb84537000020044100290094b845370000200041086a42a08080808004370200200041046a20043602000c040b200141786a2101200541086a2105200420024b21072006210420070d0020062104200620024d0d000b20052d00002104200041003a0000200020043a00010c020b41204101102c000b200041003a00002000200128020020026a2d00003a00010b200341c0006a24000bbe0201037f230041106b220224000240024020002d00004104470d002002200128021841e8aec50041032001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c010b2002200128021841ebaec50041082001411c6a28020028020c1104003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a41f4aec50010b004210120022d0008210020022802042203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d00410121002004280218418499c60041012004411c6a28020028020c1104000d010b2001280200220028021841bb98c60041012000411c6a28020028020c11040021000b200120003a00080b200241106a2400200041ff01714100470b820601037f230041d0006b22052400200520023602082005200336020c024002400240417f41012002411f71742002411f4b1b20034b0d00200541386a200141186a2203200141286a410010a40420052d00384101470d012000200529023c370200200041086a200541c4006a2802003602000c020b200541cc006a41023602002005411c6a41013602002005420337023c200541e8adc500360238200541013602142005200541106a36024820052005410c6a3602182005200541086a360210200541206a200541386a108a04200041086a200541206a41086a280200360200200020052903203702000c010b2001280200210220054100360220024020022802080d00200541cc006a41013602002005420237023c200541fcb4c500360238200541013602342005200541306a3602482005200541206a360230200541106a200541386a108a0420052802102202450d0020002005290214370204200020023602000c010b0240024002400240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490d0320024101742207200620062007491b22064100480d030240024020020d002006102921020c010b200328020020022006102a21020b2002450d02200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20043a0000200141206a2202200228020041016a3602000c030b200541cc006a220241013602002005420137023c200541e4b7c50036023820054101360234200520063602302005200541306a360248200541106a200541386a108a0420052802102201450d022005200529021437021420052001360210200241013602002005420137023c200541acb1c500360238200541233602342005200541306a3602482005200541106a360230200541206a200541386a108a0402402005280214450d002005280210102e0b20052802202202450d0220002005290224370204200020023602000c030b20064101102c000b102d000b200041003602000b200541d0006a24000bb00301017f230041d0006b22052400200520023602082005200336020c024002400240417f41012002411f71742002411f4b1b20034b0d00200128020021022005410036023420022802080d01200541cc006a41013602002005420237023c200541fcb4c500360238200541013602142005200541106a3602482005200541346a360210200541206a200541386a108a0420052802202202450d0120002005290224370204200020023602000c020b200541cc006a41023602002005412c6a41013602002005420337023c200541e8adc500360238200541013602242005200541206a36024820052005410c6a3602282005200541086a360220200541106a200541386a108a04200041086a200541106a41086a280200360200200020052903103702000c010b200541386a200141186a2202200141286a2203200410a404024020052d00384101470d002000200529023c370200200041086a200541c4006a2802003602000c010b200541386a20022003410010a404024020052d00384101470d002000200529023c370200200041086a200541c4006a2802003602000c010b200041003602000b200541d0006a24000be70301047f230041c0006b22032400200341286a200141186a2204200141286a200210a4040240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d0320024101742206200520052006491b22054100480d030240024020020d002005102921020c010b200428020020022005102a21020b2002450d02200120023602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c200341e4b7c50036022820034101360214200320053602102003200341106a360238200341186a200341286a108a0420032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c200341acb1c500360228200341233602142003200341106a3602382003200341186a3602102003200341286a108a040240200328021c450d002003280218102e0b20032802002201450d0220002003290204370204200020013602000c030b20054101102c000b102d000b200041003602000b200341c0006a24000ba00401047f230041c0006b22032400200341286a200141186a2204200141286a2205200210a4040240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b200341286a20042005200210a404024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d0320024101742206200520052006491b22054100480d030240024020020d002005102921020c010b200428020020022005102a21020b2002450d02200120023602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c200341e4b7c50036022820034101360214200320053602102003200341106a360238200341186a200341286a108a0420032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c200341acb1c500360228200341233602142003200341106a3602382003200341186a3602102003200341286a108a040240200328021c450d002003280218102e0b20032802002201450d0220002003290204370204200020013602000c030b20054101102c000b102d000b200041003602000b200341c0006a24000be70301057f230041c0006b22032400200341286a200141186a2204200141286a200210a4040240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002205200141246a22062802004f0d00024020052001411c6a280200470d00200541016a22062005490d0320054101742207200620062007491b22064100480d030240024020050d002006102921050c010b200428020020052006102a21050b2005450d02200120053602182001411c6a2006360200200141206a28020021050b200128021820056a20023a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c200341e4b7c50036022820034101360214200320063602102003200341106a360238200341186a200341286a108a0420032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c200341acb1c500360228200341233602142003200341106a3602382003200341186a3602102003200341286a108a040240200328021c450d002003280218102e0b20032802002201450d0220002003290204370204200020013602000c030b20064101102c000b102d000b200041003602000b200341c0006a24000ba00401057f230041c0006b22032400200341286a200141186a2204200141286a2205200210a4040240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b200341286a20042005200210a404024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002205200141246a22062802004f0d00024020052001411c6a280200470d00200541016a22062005490d0320054101742207200620062007491b22064100480d030240024020050d002006102921040c010b200428020020052006102a21040b2004450d02200120043602182001411c6a2006360200200141206a28020021050b200128021820056a20023a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c200341e4b7c50036022820034101360214200320063602102003200341106a360238200341186a200341286a108a0420032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c200341acb1c500360228200341233602142003200341106a3602382003200341186a3602102003200341286a108a040240200328021c450d002003280218102e0b20032802002201450d0220002003290204370204200020013602000c030b20064101102c000b102d000b200041003602000b200341c0006a24000be70301047f230041c0006b22042400200441286a200141186a2205200141286a200210a4040240024020042d00284101470d002000200429022c370200200041086a200441346a2802003602000c010b0240024002400240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490d0320024101742207200620062007491b22064100480d030240024020020d002006102921020c010b200528020020022006102a21020b2002450d02200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20033a0000200141206a2201200128020041016a3602000c030b2004413c6a220141013602002004420137022c200441e4b7c50036022820044101360214200420063602102004200441106a360238200441186a200441286a108a0420042802182202450d022004200429021c37021c20042002360218200141013602002004420137022c200441acb1c500360228200441233602142004200441106a3602382004200441186a3602102004200441286a108a040240200428021c450d002004280218102e0b20042802002201450d0220002004290204370204200020013602000c030b20064101102c000b102d000b200041003602000b200441c0006a24000bc10201037f230041206b220224000240024020002d00004104470d0020022001280218419ad4c50041082001411c6a28020028020c11040022003a001820022001360210200241003a0019200241003602140c010b2002200128021841a2d4c50041052001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200036020c200241106a2002410c6a41a8d4c50010b004210120022d0018210020022802142203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d00410121002004280218418499c60041012004411c6a28020028020c1104000d010b2001280200220028021841bb98c60041012000411c6a28020028020c11040021000b200120003a00080b200241206a2400200041ff01714100470bf30202047f057e230041d0006b2203240041012104024020002d00080d00200028020421050240200028020022062d00004104710d0041012104200628021841da98c600418199c60020051b4102410120051b2006411c6a28020028020c1104000d0120012000280200200228020c11020021040c010b024020050d00410121042006280218418299c60041022006411c6a28020028020c1104000d01200028020021060b41012104200341013a00172003200341176a3602102006290208210720062902102108200341346a41c098c60036020020032006290218370308200629022021092006290228210a200320062d00303a00482006290200210b2003200a3703402003200937033820032008370328200320073703202003200b3703182003200341086a3602302001200341186a200228020c1102000d00200328023041d898c6004102200328023428020c11040021040b200020043a00082000200028020441016a360204200341d0006a240020000b02000b17000240200041046a280200450d002000280200102e0b0b1600200028020022002802002000280208200110b3010b11002001200028020020002802081093040bbd0801087f230041c0006b22032400200341246a2001360200200341346a200241146a2802002204360200200341033a00382003412c6a2002280210220520044103746a36020020034280808080800437030820032000360220410021062003410036021820034100360210200320053602302003200536022802400240024002400240200228020822070d0020022802002108200228020422092004200420094b1b220a450d0141012104200020082802002008280204200128020c1104000d04200841086a210241012106034002402005280200200341086a200541046a280200110200450d00410121040c060b2006200a4f0d02200241046a210020022802002101200541086a2105200241086a210241012104200641016a2106200328022020012000280200200328022428020c110400450d000c050b0b20022802002108200228020422092002410c6a2802002205200520094b1b220a450d0041012104200020082802002008280204200128020c1104000d03200741106a2105200841086a21024101210603402003200541786a28020036020c2003200541106a2d00003a003820032005417c6a28020036020841002101410021040240024002400240200541086a2802000e0400010203000b2005410c6a2802002100410121040c020b02402005410c6a2802002207200328023422044f0d0041002104200328023020074103746a2207280204412a470d0220072802002802002100410121040c020b4188f2c500200720041038000b4100210420032802282207200328022c460d002003200741086a360228410021042007280204412a470d0020072802002802002100410121040b2003200036021420032004360210024002400240024002400240024020052802000e0404010006040b20032802282200200328022c470d010c050b200541046a2802002200200328023422044f0d01200328023020004103746a2200280204412a470d04200028020028020021040c030b2003200041086a3602282000280204412a470d03200028020028020021040c020b4188f2c500200020041038000b200541046a28020021040b410121010b2003200436021c2003200136021802400240200541706a2802004101460d0020032802282204200328022c460d042003200441086a3602280c010b200541746a2802002204200328023422004f0d04200328023020044103746a21040b02402004280200200341086a200441046a280200110200450d00410121040c050b2006200a4f0d01200241046a210020022802002101200541246a2105200241086a210241012104200641016a2106200328022020012000280200200328022428020c110400450d000c040b0b0240200920064d0d00410121042003280220200820064103746a22052802002005280204200328022428020c1104000d030b410021040c020b41d8f0c5001058000b4198f2c500200420001038000b200341c0006a240020040bfc0101027f230041106b220224002002200128021841e099c60041052001411c6a28020028020c1104003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a4184b8c50010b0041a20022d00082101024020022802042203450d00200141ff0171210041012101024020000d00024020034101470d0020022d000941ff0171450d00200228020022002d00004104710d00410121012000280218418499c60041012000411c6a28020028020c1104000d010b2002280200220128021841bb98c60041012001411c6a28020028020c11040021010b200220013a00080b200241106a2400200141ff01714100470ba46601037f230041206b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002d00000eac010102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab0100010b2002200128021841ebc8c50041112001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000cab010b2002200128021841fcc8c500410b2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000caa010b200220012802184187c9c50041032001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000ca9010b20022001280218418ac9c50041052001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a4190c9c50010b00421000ca8010b2002200128021841a0c9c50041042001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a4190c9c50010b00421000ca7010b2002200128021841a4c9c50041022001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a4190c9c50010b00421000ca6010b2002200128021841a6c9c50041042001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000ca5010b2002200128021841aac9c50041032001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000ca4010b2002200128021841adc9c50041022001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421000ca3010b2002200128021841c0c9c50041042001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421000ca2010b2002200128021841c4c9c50041072001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41ccc9c50010b004210120022000410c6a36020c20012002410c6a41b0c9c50010b00421000ca1010b2002200128021841dcc9c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000ca0010b2002200128021841e2c9c50041042001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421000c9f010b2002200128021841e6c9c500410c2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041016a36020c20012002410c6a41f4c9c50010b00421000c9e010b200220012802184184cac50041042001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c9d010b200220012802184188cac50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c9c010b20022001280218418ecac50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421000c9b010b200220012802184196cac50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421000c9a010b20022001280218419ecac50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421000c99010b2002200128021841a6cac50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421000c98010b2002200128021841afcac50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421000c97010b2002200128021841b8cac50041072001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c96010b2002200128021841bfcac50041072001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c95010b2002200128021841c6cac50041072001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c94010b2002200128021841cdcac50041072001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c93010b2002200128021841d4cac50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c92010b2002200128021841ddcac50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c91010b2002200128021841e6cac500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c90010b2002200128021841f0cac500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c8f010b2002200128021841facac50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c8e010b200220012802184183cbc50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c8d010b20022001280218418ccbc500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c8c010b200220012802184196cbc500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c8b010b2002200128021841a0cbc500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c8a010b2002200128021841aacbc500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c89010b2002200128021841b4cbc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c88010b2002200128021841bccbc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c87010b2002200128021841c4cbc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c86010b2002200128021841cccbc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c85010b2002200128021841d4cbc50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c84010b2002200128021841ddcbc500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c83010b2002200128021841e7cbc50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c82010b2002200128021841f0cbc500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c81010b2002200128021841facbc500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421012002200041086a36020c20012002410c6a41b0c9c50010b00421000c80010b200220012802184184ccc500410d2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41f4c9c50010b00421000c7f0b200220012802184191ccc500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41f4c9c50010b00421000c7e0b20022001280218419bccc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a4ccc50010b00421000c7d0b2002200128021841b4ccc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041086a36020c200241106a2002410c6a41bcccc50010b00421000c7c0b2002200128021841ccccc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41b0c9c50010b00421000c7b0b2002200128021841d4ccc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041086a36020c200241106a2002410c6a41dcccc50010b00421000c7a0b2002200128021841ecccc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c790b2002200128021841f2ccc50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c780b2002200128021841f7ccc50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c770b2002200128021841fcccc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c760b200220012802184182cdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c750b200220012802184188cdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c740b20022001280218418ecdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c730b200220012802184194cdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c720b20022001280218419acdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c710b2002200128021841a0cdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c700b2002200128021841a6cdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c6f0b2002200128021841accdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c6e0b2002200128021841b2cdc50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c6d0b2002200128021841b7cdc50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c6c0b2002200128021841bccdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c6b0b2002200128021841c2cdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c6a0b2002200128021841c8cdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c690b2002200128021841cecdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c680b2002200128021841d4cdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c670b2002200128021841dacdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c660b2002200128021841e0cdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c650b2002200128021841e6cdc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c640b2002200128021841eccdc50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c630b2002200128021841f1cdc50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c620b2002200128021841f6cdc50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c610b2002200128021841fbcdc50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c600b200220012802184180cec50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c5f0b200220012802184185cec50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c5e0b20022001280218418acec50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c5d0b20022001280218418fcec50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c5c0b200220012802184194cec50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c5b0b200220012802184199cec50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c5a0b20022001280218419ecec50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c590b2002200128021841a3cec50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c580b2002200128021841a8cec50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c570b2002200128021841aecec50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c560b2002200128021841b4cec50041092001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c550b2002200128021841bdcec50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c540b2002200128021841c3cec50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c530b2002200128021841c9cec50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c520b2002200128021841cfcec50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c510b2002200128021841d6cec50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c500b2002200128021841ddcec50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c4f0b2002200128021841e4cec50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c4e0b2002200128021841ebcec50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c4d0b2002200128021841f1cec50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c4c0b2002200128021841f6cec50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c4b0b2002200128021841fccec50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c4a0b200220012802184182cfc50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c490b200220012802184189cfc50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c480b200220012802184190cfc50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c470b200220012802184197cfc50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c460b20022001280218419ecfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c450b2002200128021841a4cfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c440b2002200128021841aacfc50041092001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c430b2002200128021841b3cfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c420b2002200128021841b9cfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c410b2002200128021841bfcfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c400b2002200128021841c5cfc50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c3f0b2002200128021841cccfc50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c3e0b2002200128021841d3cfc50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c3d0b2002200128021841dacfc50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c3c0b2002200128021841e1cfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c3b0b2002200128021841e7cfc50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c3a0b2002200128021841eccfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c390b2002200128021841f2cfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c380b2002200128021841f8cfc50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c370b2002200128021841ffcfc50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c360b200220012802184186d0c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c350b20022001280218418dd0c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c340b200220012802184194d0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c330b20022001280218419ad0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c320b2002200128021841a0d0c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c310b2002200128021841a7d0c50041082001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c300b2002200128021841afd0c50041082001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c2f0b2002200128021841b7d0c500410a2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c2e0b2002200128021841c1d0c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c2d0b2002200128021841c8d0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c2c0b2002200128021841ced0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c2b0b2002200128021841d4d0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c2a0b2002200128021841dad0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c290b2002200128021841e0d0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c280b2002200128021841e6d0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c270b2002200128021841ecd0c500410b2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c260b2002200128021841f7d0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c250b2002200128021841fdd0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c240b200220012802184183d1c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c230b20022001280218418ad1c50041082001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c220b200220012802184192d1c50041082001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c210b20022001280218419ad1c500410a2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c200b2002200128021841a4d1c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c1f0b2002200128021841abd1c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c1e0b2002200128021841b1d1c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c1d0b2002200128021841b7d1c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c1c0b2002200128021841bdd1c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c1b0b2002200128021841c3d1c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c1a0b2002200128021841c9d1c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c190b2002200128021841cfd1c500410b2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c180b2002200128021841dad1c500410a2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c170b2002200128021841e4d1c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c160b2002200128021841f0d1c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c150b2002200128021841fcd1c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c140b200220012802184188d2c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c130b200220012802184194d2c500410d2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c120b2002200128021841a1d2c500410d2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c110b2002200128021841aed2c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c100b2002200128021841bad2c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c0f0b2002200128021841c6d2c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c0e0b2002200128021841d2d2c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c0d0b2002200128021841ded2c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c0c0b2002200128021841ecd2c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c0b0b2002200128021841fad2c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c0a0b200220012802184188d3c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c090b200220012802184196d3c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c080b2002200128021841a2d3c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c070b2002200128021841b0d3c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c060b2002200128021841bed3c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c050b2002200128021841ccd3c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c040b2002200128021841dad3c500410d2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c030b2002200128021841e7d3c50041112001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c020b2002200128021841f8d3c50041112001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c010b200220012802184189d4c50041112001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000b20002d00082101024020002802042203450d00200141ff0171210441012101024020040d00024020034101470d0020002d0009450d00200028020022042d00004104710d00410121012004280218418499c60041012004411c6a28020028020c1104000d010b2000280200220128021841bb98c60041012001411c6a28020028020c11040021010b200020013a00080b200241206a2400200141ff01714100470bd00201027f230041106b22022400200028020028020021002001280218418ab9c50041052001411c6a28020028020c1104002103200241003a0005200220033a00042002200136020020022000410c6a36020c2002418fb9c500410e2002410c6a41a0b9c50010b90421012002200036020c200141b0b9c50041092002410c6a41bcb9c50010b90421012002200041046a36020c200141ccb9c500410c2002410c6a41bcb9c50010b90421012002200041086a36020c200141d8b9c500410c2002410c6a41bcb9c50010b9041a20022d00042100024020022d0005450d00200041ff0171210141012100024020010d0020022802002200411c6a28020028020c210120002802182103024020002d00004104710d00200341fe98c6004102200111040021000c010b2003418099c6004101200111040021000b200220003a00040b200241106a2400200041ff01714100470bdd0302047f057e230041d0006b2205240041012106024020002d00040d0020002d000521070240200028020022082d00004104710d0041012106200828021841da98c60041f898c600200741ff017122071b4102410320071b2008411c6a28020028020c1104000d014101210620002802002208280218200120022008411c6a28020028020c1104000d014101210620002802002208280218419098c60041022008411c6a28020028020c1104000d0120032000280200200428020c11020021060c010b0240200741ff01710d0041012106200828021841fb98c60041032008411c6a28020028020c1104000d01200028020021080b41012106200541013a00172005200541176a360210200829020821092008290210210a200541346a41c098c600360200200520082902183703082008290220210b2008290228210c200520082d00303a00482008290200210d2005200c3703402005200b3703382005200a370328200520093703202005200d3703182005200541086a360230200541086a2001200210ea040d00200541086a419098c600410210ea040d002003200541186a200428020c1102000d00200528023041d898c6004102200528023428020c11040021060b200041013a0005200020063a0004200541d0006a240020000b865f010b7f23004190016b220324002003200136021c2002280208220441586a2105200241106a2802002206412c6c2101024002400240024002400240024002400240024002400240024002400240024002400240024003402001450d01200141546a2101200541286a21072005412c6a2208210520072d00004104470d000b2006412c6c2101200441586a210503402001450d02200141546a2101200541286a21072005412c6a2209210520072d0000410b470d000b2006412c6c2101200441586a210503402001450d03200141546a2101200541286a21072005412c6a2204210520072d00004102470d000b024041002802e899464105490d002003410136023c20032003411c6a36023841002802ec9946210120034188016a41980136020020034180016a42ec80808010370300200341f8006a4125360200200341f0006a4101360200200341e0006a4201370300200341d8006a410a3602002003419bbdc50036027c200341f6bcc500360274200341ec006a200341386a36020020034198bac50036025c200341ecbcc5003602542003410536025041f099c60041c8ecc500200141024622011b200341d0006a41c4e1c50041dce1c50020011b2802101100000b200341106a200810b7032003280214200328021c22014d0d03200328021020014102746a2201450d03200341086a200410b7030240200328020c200128020022014d0d00200328020820014104746a22010d050b412510292201450d092001411d6a41002900bdba45370000200141186a41002900b8ba45370000200141106a41002900b0ba45370000200141086a41002900a8ba45370000200141002900a0ba45370000200041086a42a5808080d00437020020002001360204200041013602000c120b411310292201450d042001410f6a41002800f3b945360000200141086a41002900ecb945370000200141002900e4b945370000200041086a4293808080b00237020020002001360204200041013602000c110b410f10292201450d04200141076a41002900feb945370000200141002900f7b945370000200041086a428f808080f00137020020002001360204200041013602000c100b410f10292201450d04200141076a410029008dba4537000020014100290086ba45370000200041086a428f808080f00137020020002001360204200041013602000c0f0b412510292201450d042001411d6a41002900bdba45370000200141186a41002900b8ba45370000200141106a41002900b0ba45370000200141086a41002900a8ba45370000200141002900a0ba45370000200041086a42a5808080d00437020020002001360204200041013602000c0e0b0240200941086a280200200328021c22054b0d00412710292201450d062001411f6a41002900e4ba45370000200141186a41002900ddba45370000200141106a41002900d5ba45370000200141086a41002900cdba45370000200141002900c5ba45370000200041086a42a7808080f00437020020002001360204200041013602000c0e0b20092802002109200341206a41086a420037030020034280808080c00037032020012d000d2107410021012003410036024020032007410447220a36023c2003200a360238200341003a0044024041002802e8994641044b0d00200341d0006a41086a200341386a41086a29030037030020032003290338370350200341d0006a21070c070b2003412b36024c2003200341386a36024841002802ec9946210120034188016a41cb0036020020034180016a42ec80808010370300200341f8006a4125360200200341f0006a4101360200200341e0006a4201370300200341d0006a41086a2207410a3602002003419bbdc50036027c200341f6bcc500360274200341ec006a200341c8006a360200200341ecbac50036025c200341ecbcc5003602542003410536025041f099c60041c8ecc500200141024622011b200341d0006a41c4e1c50041dce1c50020011b280210110000200328022c2108200328022821012007200341386a41086a29030037030020032003290338370350200341d0006a210720082001460d0620032802242101200341d0006a21070c070b41134101102c000b410f4101102c000b410f4101102c000b41254101102c000b41254101102c000b41274101102c000b200141016a22082001490d0520014101742206200820082006491b220841ffffffff00712008470d05200841047422064100480d050240024020010d002006102921010c010b200328022420014104742006102a21010b2001450d012003200836022820032001360224200328022c21080b200120084104746a22012007290200370200200141086a200741086a2902003702002003200328022c41016a36022c410021072009200541186c6a2201280214450d022009200541186c6a410c6a2109200141146a2108200341d0006a410472210b410021074100210103400240200328022020074d0d00200341d0006a200341206a410010bc04024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c060b2007200328022020032802542d000c1b21070b02400240024002400240024002402001200828020022054f0d002003200928020020014104746a2205360234024041002802e899464105490d002003412436023c2003200341346a36023841002802ec99462105200341c90136028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc5003602742003410136027020034201370360200341e897c60036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328023421050b024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020052d000022060eac0102220000002201030405060708090a0b0c0d0e0f1010101010101010101010101010111111111111111111121314141414151616161616161616161615161616161616161616161616161616161616161616161717171818181818181818181818181818181717171818181818181818181818181818181717171717171718181818181818171717171717171818181818181819191919191919191919191919191919191919191919191919020b20052d00012105200320032802203602402003200541044722053602382003200641034720057136023c200341003a0044024041002802e899464105490d002003412b36024c2003200341386a36024841002802ec99462105200341cb0036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc5003602742003410136027020034201370360200341ecbac50036025c2003410a360258200341ecbcc500360254200341053602502003200341c8006a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b2802101100000b200341d0006a41086a200341386a41086a2903003703002003200329033837035002400240200328022c22052003280228460d00200328022421060c010b200541016a22062005490d282005410174220c20062006200c491b220c41ffffffff0071200c470d28200c410474220d4100480d280240024020050d00200d102921060c010b20032802242005410474200d102a21060b2006450d1d2003200c36022820032006360224200328022c21050b200620054104746a22052003290350370200200541086a200341d0006a41086a2903003702002003200328022c41016a36022c0c210b41002105024041002802e899464105490d000240200328022c2206417f6a220c20064b0d002003280224200c4104746a4100200c2006491b21050b2003412c36024c200320053602382003200341386a36024841002802ec99462105200341d30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc5003602742003410136027020034201370360200341f4bac50036025c2003410a360258200341ecbcc500360254200341053602502003200341c8006a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b2802101100000b0240200328022c2205450d0020032005417f6a220536022c200328022420054104746a22052d000c4102470d1a0b411710292201450d1c2001410f6a410029008bbb45370000200141086a4100290084bb45370000200141002900fcba45370000200041086a4297808080f00237020020002001360204200041013602000c250b024041002802e899464105490d0041002802ec99462105200341c10036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc500360274200341003602702003420137036020034194bbc50036025c2003410a360258200341ecbcc50036025420034105360250200341c8ecc50036026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b2802101100000b0240200328022c2205417f6a220620054f0d00200620054d0d180b411710292201450d1e2001410f6a410029008bbb45370000200141086a4100290084bb45370000200141002900fcba45370000200041086a4297808080f00237020020002001360204200041013602000c240b200341d0006a200341206a200541046a28020010bc04024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c240b200341d0006a200341206a200328025428020410be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c240b024041002802e899464105490d0041002802ec99462105200341c10036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc500360274200341003602702003420137036020034194bbc50036025c2003410a360258200341ecbcc50036025420034105360250200341c8ecc50036026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b2802101100000b024002400240200328022c2205417f6a220620054f0d00200620054d0d010b4117102922010d0141174101102c000b200328022420064104746a41013a000c0c1f0b2001410f6a410029008bbb45370000200141086a4100290084bb45370000200141002900fcba45370000200041086a4297808080f00237020020002001360204200041013602000c230b200341d0006a200341206a200541046a28020010bc04024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c230b200341d0006a200341206a2003280254280204220510be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c230b200341d0006a200341206a410110be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c230b20032005360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c1e0b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c220b200341d0006a200341206a2005410c6a28020010bc04024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c220b2003280254280204210c200541086a2802004102742106200541046a280200210502400340024020060d00200341d0006a200341206a200c10be042003280250450d0220002003290350370204200041013602002000410c6a200341d8006a2802003602000c240b200341d0006a200341206a200528020010bc04024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c240b2006417c6a2106200541046a21052003280254280204200c460d000b412710292201450d1a2001411f6a41002900d1bb45370000200141186a41002900cabb45370000200141106a41002900c2bb45370000200141086a41002900babb45370000200141002900b2bb45370000200041086a42a7808080f00437020020002001360204200041013602000c220b024041002802e899464105490d0041002802ec99462105200341c10036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc500360274200341003602702003420137036020034194bbc50036025c2003410a360258200341ecbcc50036025420034105360250200341c8ecc50036026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b2802101100000b024002400240200328022c2205417f6a220620054f0d00200620054d0d010b4117102922010d0141174101102c000b200328022420064104746a41013a000c0c1d0b2001410f6a410029008bbb45370000200141086a4100290084bb45370000200141002900fcba45370000200041086a4297808080f00237020020002001360204200041013602000c210b200341d0006a200341206a200a10be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c210b024041002802e899464105490d0041002802ec99462105200341c10036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc500360274200341003602702003420137036020034194bbc50036025c2003410a360258200341ecbcc50036025420034105360250200341c8ecc50036026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b2802101100000b024002400240200328022c2205417f6a220620054f0d00200620054d0d010b4117102922010d0141174101102c000b200328022420064104746a41013a000c0c1c0b2001410f6a410029008bbb45370000200141086a4100290084bb45370000200141002900fcba45370000200041086a4297808080f00237020020002001360204200041013602000c200b200341d0006a200541046a280200200210bf04024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c200b200341d0006a200341206a2003280254220528020810be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c200b200320052d000d4104472205360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c1b0b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c1f0b2003200410b703024002402003280204200541046a28020022054d0d002003280200220620054104746a220c0d010b410e10292201450d18200141066a41002900dfbb45370000200141002900d9bb45370000200041086a428e808080e00137020020002001360204200041013602000c1f0b200341d0006a200341206a200620054104746a28020810be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1f0b2003200c2d000d4104472205360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c1a0b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c1e0b200341d0006a200341206a410110be042003280250450d1820002003290350370204200041013602002000410c6a200341d8006a2802003602000c1d0b200341d0006a200341206a410210be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1d0b41012105200341d0006a200341206a410110be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1d0b20034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c180b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c1c0b4101210520034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c170b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c1b0b200341d0006a200341206a410110be042003280250450d1520002003290350370204200041013602002000410c6a200341d8006a2802003602000c1a0b41012105200341d0006a200341206a410110be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1a0b20034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c150b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c190b4101210520034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c140b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c180b200341d0006a200341206a410110be042003280250450d1220002003290350370204200041013602002000410c6a200341d8006a2802003602000c170b41012105200341d0006a200341206a410110be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c170b20034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c120b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c160b200341d0006a200341206a410210be042003280250450d1020002003290350370204200041013602002000410c6a200341d8006a2802003602000c150b4101210520034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c100b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c140b41012105200341d0006a200341206a410110be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c140b20034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c0f0b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c130b4101210520034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c0e0b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c120b41012105200341d0006a200341206a410110be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c120b20034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c0d0b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c110b200341d0006a200341206a410210be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c110b4101210520034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c0c0b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c100b41012105200341d0006a200341206a410110be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c100b20034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c0b0b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c0f0b200341d0006a200341206a410210be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c0f0b4101210520034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c0a0b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c0e0b41012105200341d0006a200341206a410110be0402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c0e0b20034101360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e102922010d01410e4101102c000b200320053602200c090b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c0d0b200328022420064104746a41013a000c0c070b20052802002106200320052802082205360238024041002802e899464105490d002003410136024c2003200341386a36024841002802ec99462105200341db0036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc5003602742003410136027020034201370360200341e8bbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341c8006a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b280210110000200328023821050b2003200536022020032006360248024041002802e899464105490d002003410136023c2003200341c8006a36023841002802ec99462105200341e30036028801200342ec80808010370380012003419bbdc50036027c20034125360278200341f6bcc50036027420034101360270200342013703602003419cbbc50036025c2003410a360258200341ecbcc500360254200341053602502003200341386a36026c41f099c60041c8ecc500200541024622051b200341d0006a41c4e1c50041dce1c50020051b28021011000020032802202105200328024821060b0240200520066a220620054f0d00410e102922010d0a410e4101102c000b200320063602200c060b41f0bbc500200120051038000b200d4104102c000b41174101102c000b41274101102c000b410e4101102c000b41174101102c000b200141016a22012008280200490d000c030b0b20064104102c000b200141066a41002900aabb45370000200141002900a4bb45370000200041086a428e808080e00137020020002001360204200041013602000c010b20004100360200200020073602042003280228450d022003280224102e0c020b2003280228450d012003280224102e0c010b102d000b20034190016a24000bc60201027f230041106b220224002001280218418ab9c50041052001411c6a28020028020c1104002103200241003a0005200220033a00042002200136020020022000410c6a36020c2002418fb9c500410e2002410c6a41a0b9c50010b90421012002200036020c200141b0b9c50041092002410c6a41bcb9c50010b90421012002200041046a36020c200141ccb9c500410c2002410c6a41bcb9c50010b90421012002200041086a36020c200141d8b9c500410c2002410c6a41bcb9c50010b9041a20022d00042100024020022d0005450d00200041ff0171210141012100024020010d0020022802002200411c6a28020028020c210120002802182103024020002d00004104710d00200341fe98c6004102200111040021000c010b2003418099c6004101200111040021000b200220003a00040b200241106a2400200041ff01714100470b9b0201027f024002400240024002402001410c6a2802002203417f6a220420034d0d00411610292201450d01200020013602042001410e6a41002900f9be45370000200141086a41002900f3be45370000200141002900ebbe45370000200041086a4296808080e0023702000c040b0240200420026b220220044d0d00411b10292201450d0220002001360204200141176a4100280098bf45360000200141106a4100290091bf45370000200141086a4100290089bf4537000020014100290081bf45370000200041086a429b808080b0033702000c040b200320024d0d022000200128020420024104746a360204200041003602000f0b41164101102c000b411b4101102c000b419cbfc500200220031038000b200041013602000bbb0201037f230041106b220224000240024020002802000d002002200128021841a899c60041042001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c010b2002200128021841ac99c60041042001411c6a28020028020c1104003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a41f8c6c50010b004210120022d0008210020022802042203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d00410121002004280218418499c60041012004411c6a28020028020c1104000d010b2001280200220028021841bb98c60041012000411c6a28020028020c11040021000b200120003a00080b200241106a2400200041ff01714100470bc50401027f230041d0006b2203240020032002360204024041002802e899464105490d002003410136020c2003200341046a36020841002802ec99462102200341c8006a41ef00360200200341c0006a42ec80808010370300200341386a4125360200200341306a4101360200200341206a4201370300200341186a410a3602002003419bbdc50036023c200341f6bcc5003602342003412c6a200341086a36020020034194bec50036021c200341ecbcc5003602142003410536021041f099c60041c8ecc500200241024622021b200341106a41c4e1c50041dce1c50020021b280210110000200328020421020b0240024002402002450d00200341106a2001410010bc0420032802104101470d012000200341106a4104722202290200370200200041086a200241086a2802003602000c020b200041003602000c010b02400240024002402001280200220220032802142204280208460d00200220032802046b220420024d0d02410f102922020d01410f4101102c000b024020042d000c0d00412510292202450d03200042a5808080d004370204200020023602002002411d6a41002900b9be45370000200241186a41002900b4be45370000200241106a41002900acbe45370000200241086a41002900a4be453700002002410029009cbe453700000c040b200041003602000c030b2000428f808080f00137020420002002360200200241076a41002900c8be45370000200241002900c1be453700000c020b20004100360200200120043602000c010b41254101102c000b200341d0006a24000bda09010b7f230041e0006b22032400200320013602202002280208220441586a2105200241106a2802002206412c6c210202400340024020020d00410021070c020b200241546a2102200541286a21072005412c6a2208210520072d00004102470d000b200341186a200810b70320032802182107200328021c21020b2002410020071b21092006412c6c2102200441586a2105200741c8ecc50020071b210a02400340024020020d004100210b0c020b200241546a2102200541286a21072005412c6a2208210520072d00004104470d000b200341106a200810b7032003280210210b2003280214210c0b2006412c6c2102200441586a2105200b41c8ecc500200b1b210d0240024002400240024002400240024003402002450d01200241546a2102200541286a21072005412c6a2208210520072d00004103470d000b200841086a2802002202450d00200241286c2107200828020041186a2102410021050340200520022d0000456a2105200241286a2102200741586a22070d000b200520014d0d012006412c6c2102200441586a210502400240024003402002450d01200241546a2102200541286a21072005412c6a2208210520072d00004103470d000b200341086a200810b70320032802082207200328020c41286c6a2108024003400240024002402008200722026b41f8004b0d0020022008460d0f2002411c6a2105034020022d0018450d02200541286a2105200241286a22022008470d000c100b0b20022d00180d012002411c6a2105200241286a21070c060b2005410c6a21070c050b200241c0006a2d0000450d01200241e8006a2d0000450d03200241a0016a210720024190016a2d00000d000b20024194016a21050c030b200241c4006a2105200241d0006a21070c020b41f5c2c50041c200109b01000b200241ec006a2105200241f8006a21070b2001450d0203402001417f6a21010240024003400240024002402008200722026b41f8004b0d0020022008460d0e2002411c6a2105034020022d0018450d02200541286a2105200241286a22022008460d0f0c000b0b20022d00180d01200241286a210720010d052002411c6a21050c080b2005410c6a21072001450d070c040b200241c0006a2d0000450d02200241e8006a2d0000450d01200241a0016a210720024190016a2d00000d000b20010d0220024194016a21050c050b200241f8006a210720010d01200241ec006a21050c040b200241d0006a210720010d000b200241c4006a21050c020b410021050b200c4100200b1b200120056b22024d0d01200d20024102746a2205450d010b200320052802002202360224200920024d0d01200a20024104746a2202450d0120002002360204410021020c030b200341cc006a41013602002003420237023c20034194c4c5003602382003410136022c2003200341286a3602482003200341206a360228200341d0006a200341386a108a04200341d0006a21020c010b200341cc006a4102360200200341dc006a41013602002003420337023c200341a4c4c500360238200341013602542003200341d0006a3602482003200341206a3602582003200341246a360250200341286a200341386a108a04200341286a21020b20022802002105200041086a200229020437020020002005360204410121020b20002002360200200341e0006a24000f0b41b7c3c50041dd00109b01000bc60902057f017e024020010d00200041ac013a00000f0b02400240024002400240024020012d00002202414f6a41fb004f0d000c010b02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020020e312c2c0001022c2c0304052c06072c2c08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292c0b20012d00012103410221020c2b0b20012d00012103410321020c2a0b20012d00012103410421020c290b200141046a2802002104410721020c270b200141046a2802002104410821020c260b2001280208220541ffffffff03712005470d2720054102742202417f4c0d270240024020020d00410421040c010b200210292204450d290b02402005450d00200128020421022005410274210620042103034020032002280200360200200341046a2103200241046a21022006417c6a22060d000b0b200135020c4220862005ad842107410921020c250b200141046a2802002104410b21020c240b200141046a280200210420012d00012103410c21020c240b200141046a2802002104410f21020c220b200141046a2802002104411021020c210b200141046a2802002104411121020c200b200141046a2802002104411221020c1f0b200141046a2802002104411321020c1e0b200141046a280200210420013502082107411421020c1d0b200141046a280200210420013502082107411521020c1c0b200141046a280200210420013502082107411621020c1b0b200141046a280200210420013502082107411721020c1a0b200141046a280200210420013502082107411821020c190b200141046a280200210420013502082107411921020c180b200141046a280200210420013502082107411a21020c170b200141046a280200210420013502082107411b21020c160b200141046a280200210420013502082107411c21020c150b200141046a280200210420013502082107411d21020c140b200141046a280200210420013502082107411e21020c130b200141046a280200210420013502082107411f21020c120b200141046a280200210420013502082107412021020c110b200141046a280200210420013502082107412121020c100b200141046a280200210420013502082107412221020c0f0b200141046a280200210420013502082107412321020c0e0b200141046a280200210420013502082107412421020c0d0b200141046a280200210420013502082107412521020c0c0b200141046a280200210420013502082107412621020c0b0b200141046a280200210420013502082107412721020c0a0b200141046a280200210420013502082107412821020c090b200141046a280200210420013502082107412921020c080b200141046a280200210420013502082107412a21020c070b20012d00012103412b21020c070b20012d00012103412c21020c060b200141046a2802002104412d21020c040b20012903082107412e21020c020b200141046a2802002104412f21020c020b20012903082107413021020b0b0b200020033a0001200020023a0000200041086a2007370300200041046a20043602000f0b1032000b20024104102c000b8d0301067f230041106b220224000240024002400240200041046a2802002203200041086a28020022046b20012802042205200128020022066b4104762207490d00200028020021030c010b200420076a22062004490d0220034101742205200620062005491b220641ffffffff00712006470d02200641047422054100480d020240024020030d002005102921030c010b200028020020034104742005102a21030b2003450d0120002003360200200041046a2006360200200041086a280200210420012802042105200128020021060b0240024020062005470d00410021060c010b2001200641106a3602000b2002200610c004024020022d000041ac01460d00200320044104746a2106034020062002290300370300200641086a200241086a29030037030002400240200128020022052001280204470d00410021050c010b2001200541106a3602000b200441016a2104200641106a21062002200510c00420022d000041ac01470d000b0b200041086a2004360200200241106a24000f0b20054108102c000b102d000b110020002802003502004101200110b5010bea0302057f017e02402001450d00034020002802940321002001417f6a22010d000b0b02402002450d004100210341002101034002400240200120002f01064f0d00200020014105746a220441c4006a2802002105200441386a2802002106200441346a2802002107200141016a21010c010b02400240200028020022010d002003ad210841002104410021010c010b20003301044220862003ad842108410121040b2000102e2008a72103024002402008422088a7220620012f01064f0d00200121050c010b034002400240200128020022050d002003ad2108410021050c010b200441016a210420013301044220862003ad8421080b2001102e2008a72103200521012008422088a7220620052f01064f0d000b0b200641027420056a4198036a2802002100200520064105746a220141c4006a2802002105200141386a2802002106200141346a280200210702402004417f6a2201450d00034020002802940321002001417f6a22010d000b0b410021010b20054102460d012002417f6a210202402006450d002007102e0b20020d000b0b0240200041e08dc000460d00200028020021012000102e2001450d00200128020021052001102e2005450d00024020052802002201450d0003402005102e2001210520012802002200210120000d000b0b2005102e0b0b23002001418d97c600418897c60020002802002d000022001b4104410520001b1093040bc60201037f230041206b2202240002400240200028020022002d00004104470d0020022001280218419ad4c50041082001411c6a28020028020c11040022003a001820022001360210200241003a0019200241003602140c010b2002200128021841a2d4c50041052001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200036020c200241106a2002410c6a41a8d4c50010b004210120022d0018210020022802142203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d00410121002004280218418499c60041012004411c6a28020028020c1104000d010b2001280200220028021841bb98c60041012000411c6a28020028020c11040021000b200120003a00080b200241206a2400200041ff01714100470b0c0020002802002001109b040b890501047f230041d0006b220224002000280200220041046a28020021032000280200210041012104200128021841b998c60041012001411c6a28020028020c110400210502402003450d0020022000360204024020050d00024020012d0000410471450d0041012104200128021841bc98c6004101200128021c28020c1104000d012001280200210541012104200241013a001720022005360218200241c098c60036023420022001290218370308200220012d00303a00482002200128020436021c200220012902283703402002200129022037033820022001290210370328200220012902083703202002200241176a3602102002200241086a360230200241046a200241186a109e010d01200228023041d898c6004102200228023428020c11040021040c010b200241046a2001109e0121040b024020034101470d00200421050c010b200041046a21002003410274417c6a210320042105034020022000360204200541ff0171210441012105024020040d00024020012802002204410471450d00200241013a001720022004360218200241c098c60036023420022001290218370308200220012d00303a00482002200128020436021c200220012902283703402002200129022037033820022001290210370328200220012902083703202002200241176a3602102002200241086a360230200241046a200241186a109e010d01200228023041d898c6004102200228023428020c11040021050c010b200128021841da98c6004102200128021c28020c1104000d00200241046a2001109e0121050b200041046a21002003417c6a22030d000b0b41012100024020050d00200128021841ba98c6004101200128021c28020c11040021000b200241d0006a240020000b8c0e01087f024020002802082201450d00200028020022022001412c6c6a2103034020022204412c6a21020240024020042d00002200410d4b0d00024002400240024002400240024002400240024002400240024020000e0e0001020304050607080e090a0b0c000b200441086a280200450d0d200441046a280200102e0c0d0b0240200441086a280200450d00200441046a280200102e0b200441146a280200450d0c200441106a280200102e0c0c0b02402004410c6a2802002201450d00200441046a28020021002001410474210103400240200041046a280200450d002000280200102e0b200041106a2100200141706a22010d000b0b200441086a280200450d0b2004280204102e0c0b0b02402004410c6a2802002201450d00200441046a2802002100200141286c210103400240200041046a280200450d002000280200102e0b0240200041106a280200450d002000410c6a280200102e0b200041286a2100200141586a22010d000b0b200441086a280200450d0a2004280204102e0c0a0b200441086a280200450d09200441046a280200102e0c090b200441086a280200450d08200441046a280200102e0c080b200441086a280200450d07200441046a280200102e0c070b02402004410c6a2802002200450d00200441046a280200220520004104746a21060340024020052802082201450d0020052802002100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a280200102e0b200041106a2100200141706a22010d000b0b200541106a21000240200541046a280200450d002005280200102e0b2000210520002006470d000b0b200441086a280200450d062004280204102e0c060b02402004410c6a2802002201450d00200441046a2802002100200141146c210103400240200041046a280200450d002000280200102e0b200041146a21002001416c6a22010d000b0b200441086a280200450d052004280204102e0c050b02402004410c6a2802002200450d00200441046a28020022052000411c6c6a2106034002402005410c6a2802002201450d0020052802042100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a280200102e0b200041106a2100200141706a22010d000b0b0240200541086a280200450d002005280204102e0b2005411c6a21000240200541146a280200450d002005280210102e0b2000210520002006470d000b0b200441086a280200450d042004280204102e0c040b02402004410c6a2802002200450d00200441046a2802002205200041186c6a210603400240200541046a280200450d002005280200102e0b0240200541146a2802002201450d00200528020c2100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a280200102e0b200041106a2100200141706a22010d000b0b200541186a21000240200541106a280200450d00200528020c102e0b2000210520002006470d000b0b200441086a280200450d032004280204102e0c030b02402004410c6a2802002200450d00200441046a28020022052000411c6c6a2106034002402005410c6a2802002201450d0020052802042100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a280200102e0b200041106a2100200141706a22010d000b0b0240200541086a280200450d002005280204102e0b2005411c6a21000240200541146a280200450d002005280210102e0b2000210520002006470d000b0b200441086a280200450d022004280204102e0c020b0240200441046a2d0000220041024b0d0002400240024020000e03000102000b2004410c6a280200450d04200441086a280200102e0c040b0240200441146a2802002201450d002004410c6a28020021002001410c6c21010340024020002802002205450d00200041046a280200450d002005102e0b2000410c6a2100200141746a22010d000b0b200441106a280200450d03200428020c102e0c030b0240200441146a2802002200450d002004410c6a280200220720004104746a210803402007220641106a2107024020062802042200450d0002402006410c6a2802002201450d002001410c6c21010340024020002802002205450d00200041046a280200450d002005102e0b2000410c6a2100200141746a22010d000b0b200641086a280200450d002006280204102e0b20072008470d000b0b200441106a280200450d02200428020c102e0c020b2004410c6a280200450d01200441086a280200102e0c010b0240200441086a280200450d00200441046a280200102e0b0240200441146a2802002200450d00200441186a280200450d002000102e0b200441246a280200450d00200441206a280200102e0b20022003470d000b0b0bd00203027f017e017f23004180016b220224002000280200210002400240024002400240200128020022034110710d002000280200210020034120710d012000ac22042004423f8722047c2004852000417f73411f76200110b50121000c020b20002802002103410021000340200220006a41ff006a2003410f712205413072200541d7006a2005410a491b3a00002000417f6a2100200341047622030d000b20004180016a22034181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000c010b410021030340200220036a41ff006a2000410f712205413072200541376a2005410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d022001410141f8efc5004102200220036a4180016a410020036b10b60121000b20024180016a240020000f0b20034180011035000b20004180011035000bd00202027f027e23004180016b220224002000280200210002400240024002400240200128020022034110710d002000290300210420034120710d0120042004423f8722057c2005852004427f55200110b50121000c020b20002903002104410021000340200220006a41ff006a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000c010b410021000340200220006a41ff006a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000b20024180016a240020000f0b20034180011035000b20034180011035000bc30201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d0020002d0000210420034120710d012004ad42ff01834101200110b50121000c020b20002d00002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000b20024180016a240020000f0b20044180011035000b20044180011035000b040041000b02000b02000baf0301047f230041c0006b2202240020002802002100410121030240200128021841aa97c600410c2001411c6a28020028020c1104000d0002400240200028020822030d0020002802002203200028020428020c11070042e4aec285979ba58811520d012002200336020c2002412d36021420022002410c6a36021020012802182104200128021c2105410121032002413c6a41013602002002420237022c200241b897c6003602282002200241106a36023820042005200241286a10b5040d020c010b2002200336020c2002412e36021420022002410c6a36021020012802182104200128021c2105410121032002413c6a41013602002002420237022c200241b897c6003602282002200241106a36023820042005200241286a10b5040d010b200241106a41146a4101360200200241106a410c6a41013602002002411c3602142002200041186a3602202002200041146a36021820022000410c6a36021020012802182100200128021c2101200241286a41146a41033602002002420337022c200241c897c6003602282002200241106a36023820002001200241286a10b50421030b200241c0006a240020030b160020012000280200220028020020002802041093040b6a01037f230041206b220224002001411c6a280200210320012802182104200241086a41106a2000280200220141106a290200370300200241086a41086a200141086a2902003703002002200129020037030820042003200241086a10b5042101200241206a240020010b6f01017f230041c0006b220124002001200036020c200141346a410136020020014201370224200141e897c6003602202001412f36023c2001200141386a36023020012001410c6a360238200141106a200141206a108a042001280210200128021810d304200141106a10d40400000b08002000200110090b17000240200041046a280200450d002000280200102e0b0b0600200010250b0600200010260b2801017f0240200210252203450d002003200020022001200120024b1b10f6041a200010260b20030b1c01017f0240200010252201450d0020014100200010f5041a0b20010bb10101037f0240024002400240200028020022002802042203200028020822046b2002490d00200028020021030c010b200420026a22052004490d0220034101742204200520052004491b22044100480d020240024020030d002004102921030c010b200028020020032004102a21030b2003450d012000200436020420002003360200200028020821040b2000200420026a360208200320046a2001200210f6041a41000f0b20044101102c000b102d000ba70401047f230041106b220224002000280200210002400240024002400240024002402001418001490d002002410036020c2001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c040b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c030b0240200028020822032000280204470d00200341016a22042003490d0620034101742205200420042005491b22044100480d060240024020030d002004102921030c010b200028020020032004102a21030b2003450d022000200436020420002003360200200028020821030b200028020020036a20013a00002000200028020841016a3602080c030b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010c010b20044101102c000b0240024020002802042204200028020822036b2001490d00200028020021040c010b200320016a22052003490d0320044101742203200520052003491b22034100480d030240024020040d002003102921040c010b200028020020042003102a21040b2004450d022000200336020420002004360200200028020821030b2000200320016a360208200420036a2002410c6a200110f6041a0b200241106a240041000f0b20034101102c000b102d000b6401017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a418ce9c500200241086a10b5042101200241206a240020010b0d00429b8bdbb5d1988ae5dc000b5401017f024002402001418080c400460d0041012104200028021820012000411c6a2802002802101102000d010b024020020d0041000f0b2000280218200220032000411c6a28020028020c11040021040b20040bcd0801067f230041f0006b220424002004200336020c20042002360208410121052001210602402001418102490d00410020016b2107418002210803400240200820014f0d00200020086a2c000041bf7f4c0d0041002105200821060c020b2008417f6a21064100210520084101460d01200720086a21092006210820094101470d000b0b200420063602142004200036021020044100410520051b36021c200441c8ecc50041faefc50020051b3602180240024002400240200220014b22080d00200320014b0d00200220034b0d01024002402002450d0020012002460d00200120024d0d01200020026a2c00004140480d010b200321020b200420023602202002450d0220022001460d02200141016a210903400240200220014f0d00200020026a2c000041404e0d040b2002417f6a210820024101460d0420092002462106200821022006450d000c040b0b20042002200320081b360228200441306a41146a4103360200200441c8006a41146a411c360200200441d4006a411c3602002004420337023420044180f0c5003602302004410136024c2004200441c8006a3602402004200441186a3602582004200441106a3602502004200441286a360248200441306a4198f0c500106a000b200441e4006a411c360200200441c8006a41146a411c360200200441d4006a4101360200200441306a41146a410436020020044204370234200441a8f0c5003602302004410136024c2004200441c8006a3602402004200441186a3602602004200441106a36025820042004410c6a3602502004200441086a360248200441306a41c8f0c500106a000b200221080b024020082001460d00410121060240024002400240200020086a22092c00002202417f4a0d0041002105200020016a220621010240200941016a2006460d00200941026a210120092d0001413f7121050b2002411f712109200241ff017141df014b0d01200520094106747221010c020b2004200241ff0171360224200441286a21020c020b4100210020062107024020012006460d00200141016a210720012d0000413f7121000b200020054106747221010240200241ff017141f0014f0d0020012009410c747221010c010b41002102024020072006460d0020072d0000413f7121020b20014106742009411274418080f00071722002722201418080c400460d020b2004200136022441012106200441286a21022001418001490d00410221062001418010490d0041034104200141808004491b21060b200420083602282004200620086a36022c200441306a41146a4105360200200441ec006a411c360200200441e4006a411c360200200441c8006a41146a4130360200200441d4006a413136020020044205370234200441f0f0c500360230200420023602582004410136024c2004200441c8006a3602402004200441186a3602682004200441106a3602602004200441246a3602502004200441206a360248200441306a4198f1c500106a000b41d8f0c5001058000b7c01037f230041206b2202240002402000200110e2040d002001411c6a2802002103200128021821042002411c6a4100360200200241c8ecc5003602182002420137020c20024180f2c50036020820042003200241086a10b5040d00200041046a200110e2042101200241206a240020010f0b200241206a240041010bf00a03037f017e047f410121020240200128021841272001411c6a2802002802101102000d004102210302400240024002402000280200220241776a2200411e4d0d00200241dc00470d010c020b41f400210402400240024020000e1f05010303000303030303030303030303030303030303030303040303030304050b41f20021040c010b41ee0021040b0c020b02400240200210e104450d00200241017267410276410773ad4280808080d0008421050c010b024002400240200241808004490d000240024002402002418080084f0d0020024180fe0371410876210641f183c600210041002107200241ff017121040340200041026a2108200720002d000122036a2109024020002d000022002006460d00200020064b0d062009210720082100200841b784c600470d010c060b20092007490d02200941a6014b0d03200741b784c6006a2100024003402003450d012003417f6a210320002d00002107200041016a210020072004470d000c080b0b2009210720082100200841b784c600470d000c050b0b200241ef83384b0d04200241e28b746a41e28d2c490d042002419fa8746a419f18490d04200241dee2746a410e490d04200241feffff0071419ef00a460d04200241a9b2756a4129490d04200241cb91756a410a4d0d0441012103200221040c070b200720091035000b200941a601105e000b20024180fe0371410876210641c0fec500210041002107200241ff01712104024002400340200041026a2108200720002d000122036a2109024020002d000022002006460d00200020064b0d03200921072008210020084192ffc500470d010c030b024020092007490d00200941a5024b0d0220074192ffc5006a2100024003402003450d012003417f6a210320002d00002107200041016a210020072004470d000c070b0b200921072008210020084192ffc500470d010c030b0b200720091035000b200941a502105e000b200241ffff0371210741b781c60021034101210402400340200341016a21090240024020032d0000220041187441187522084100480d00200921030c010b200941f183c600460d02200841ff007141087420032d0001722100200341026a21030b0240200720006b22074100480d0020044101732104200341f183c600470d010b0b4101210320044101710d040c020b41d8f0c5001058000b200241ffff0371210741dd85c60021034101210402400340200341016a21090240024020032d0000220041187441187522084100480d00200921030c010b200941f588c600460d02200841ff007141087420032d0001722100200341026a21030b0240200720006b22074100480d0020044101732104200341f588c600470d010b0b4101210320044101710d030c010b41d8f0c5001058000b200241017267410276410773ad4280808080d0008421050b41032103200221040c010b200221040b03402003210741dc0021004101210241012103024002400240024020070e0401020300010b024002400240024002402005422088a741ff01710e06050403020100050b200542ffffffff8f60834280808080c000842105410321030c060b200542ffffffff8f608342808080803084210541f5002100410321030c050b200542ffffffff8f608342808080802084210541fb002100410321030c040b20042005a72207410274411c7176410f712203413072200341d7006a2003410a491b210002402007450d002005427f7c42ffffffff0f83200542808080807083842105410321030c040b200542ffffffff8f6083428080808010842105410321030c030b200542ffffffff8f6083210541fd002100410321030c020b20012802184127200128021c2802101102000f0b41002103200421000b20012802182000200128021c280210110200450d000b0b20020b950201017f024002402000418010490d00024002400240024002400240200041808004490d002000410c7641706a2201418002490d01419889c60020014180021038000b200041067641606a220141df074b0d01200141e0f4c5006a2d0000220141c9004b0d02200141037441f089c6006a21010c060b200141c0fcc5006a2d00004106742000410676413f7172220141ff034b0d02200141c08ec6006a2d0000220141394b0d03200141037441c092c6006a21010c050b41f888c600200141e0071038000b418889c600200141ca001038000b41a889c60020014180041038000b41b889c6002001413a1038000b200041037641f8ffffff017141c8f2c5006a21010b200129030042012000413f71ad86834200520bb20201037f23004180016b2202240002400240024002400240200128020022034110710d002000280200210420034120710d012004ad4101200110b50121000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000b20024180016a240020000f0b20044180011035000b20044180011035000b0e0020003502004101200110b5010b1c002001280218419197c600410b2001411c6a28020028020c1104000b1c002001280218419c97c600410e2001411c6a28020028020c1104000b140020002802002001200028020428020c1102000bc30501077f410021040240024020024103712205450d00410420056b2205450d00200220032005200520034b1b22046a210641002105200141ff017121072004210820022109024003400240200620096b41034b0d0041002107200141ff0171210603402008450d04200920076a210a2008417f6a2108200741016a2107200a2d0000220a2006470d000b2005200a200141ff01714641016a4101716a20076a417f6a21050c020b200520092d0000220a2007476a2105200a2007460d012005200941016a2d0000220a2007476a2105200a2007460d012005200941026a2d0000220a2007476a2105200a2007460d012005200941036a2d0000220a2007476a21052008417c6a2108200941046a2109200a2007470d000b0b410121090c010b200141ff017121070240024020034108490d002004200341786a220a4b0d00200741818284086c210502400340200220046a220941046a2802002005732208417f73200841fffdfb776a7120092802002005732209417f73200941fffdfb776a7172418081828478710d01200441086a2204200a4d0d000b0b200420034b0d010b200220046a2109200220036a2102200320046b2108410021050240024003400240200220096b41034b0d0041002107200141ff0171210203402008450d04200920076a210a2008417f6a2108200741016a2107200a2d0000220a2002470d000b200a200141ff01714641016a41017120056a20076a417f6a21050c020b200520092d0000220a2007476a2105200a2007460d012005200941016a2d0000220a2007476a2105200a2007460d012005200941026a2d0000220a2007476a2105200a2007460d012005200941036a2d0000220a2007476a21052008417c6a2108200941046a2109200a2007470d000b0b41012109200520046a21050c020b41002109200520076a20046a21050c010b200420031035000b20002005360204200020093602000b2701017f2000280200220128020020012802042000280204280200200028020828020010de04000b02000ba60401077f230041306b220324000240024020020d00410021040c010b200341286a210502400240024002400340024020002802082d0000450d00200028020041f498c6004104200028020428020c1104000d050b2003410a3602282003428a808080103703202003200236021c200341003602182003200236021420032001360210200341086a410a2001200210e704024002400240024020032802084101470d00200328020c210403402003200420032802186a41016a2204360218024002402004200328022422064f0d00200328021421070c010b200328021422072004490d00200641054f0d072003280210200420066b22086a22092005460d0420092005200610f804450d040b200328021c22092004490d0220072009490d0220032006200341106a6a41176a2d0000200328021020046a200920046b10e7042003280204210420032802004101460d000b0b2003200328021c3602180b200028020841003a0000200221040c010b200028020841013a0000200841016a21040b2000280204210920002802002106024020044520022004467222070d00200220044d0d03200120046a2c000041bf7f4c0d030b200620012004200928020c1104000d04024020070d00200220044d0d04200120046a2c000041bf7f4c0d040b200120046a2101200220046b22020d000b410021040c040b20064104105e000b200120024100200410de04000b200120022004200210de04000b410121040b200341306a240020040bfa0101017f230041106b220224002002410036020c0240024002402001418001490d002001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c020b200220013a000c410121010c010b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010b20002002410c6a200110ea042101200241106a240020010b6101017f230041206b2202240020022000360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41dc98c600200241086a10b5042101200241206a240020010b0e0020002802002001200210ea040b810201017f230041106b22022400200028020021002002410036020c0240024002402001418001490d002001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c020b200220013a000c410121010c010b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010b20002002410c6a200110ea042101200241106a240020010b6401017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41dc98c600200241086a10b5042101200241206a240020010bc30201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d0020002d0000210420034120710d012004ad42ff01834101200110b50121000c020b20002d00002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d022001410141f8efc5004102200220006a4180016a410020006b10b60121000b20024180016a240020000f0b20044180011035000b20044180011035000b0c002000280200200110e2040b820201027f230041106b22022400200128021841b099c60041092001411c6a28020028020c1104002103200241003a0005200220033a0004200220013602002002200036020c200241b999c600410b2002410c6a418899c60010b90421012002200041046a36020c200141c499c60041092002410c6a41d099c60010b9041a20022d00042101024020022d0005450d00200141ff0171210041012101024020000d0020022802002201411c6a28020028020c210020012802182103024020012d00004104710d00200341fe98c6004102200011040021010c010b2003418099c6004101200011040021010b200220013a00040b200241106a2400200141ff01714100470bb60201027f230041106b2202240002400240200028020022002d00004101460d00200128021841a899c60041042001411c6a28020028020c11040021010c010b2002200128021841ac99c60041042001411c6a28020028020c1104003a000820022001360200200241003a0009200241003602042002200041016a36020c20022002410c6a419899c60010b0041a20022d00082101024020022802042203450d00200141ff0171210041012101024020000d00024020034101470d0020022d000941ff0171450d00200228020022002d00004104710d00410121012000280218418499c60041012000411c6a28020028020c1104000d010b2002280200220128021841bb98c60041012001411c6a28020028020c11040021010b200220013a00080b200141ff017141004721010b200241106a240020010b1c00200128021841e099c60041052001411c6a28020028020c1104000b2c01017f02402002450d00200021030340200320013a0000200341016a21032002417f6a22020d000b0b20000b3601017f02402002450d00200021030340200320012d00003a0000200341016a2103200141016a21012002417f6a22020d000b0b20000b7101017f0240024020012000490d002002450d01200021030340200320012d00003a0000200141016a2101200341016a21032002417f6a22020d000c020b0b2002450d002001417f6a21012000417f6a21030340200320026a200120026a2d00003a00002002417f6a22020d000b0b20000b4a01037f4100210302402002450d000240034020002d0000220420012d00002205470d01200141016a2101200041016a21002002417f6a2202450d020c000b0b200420056b21030b20030b5701017e02400240200341c000710d002003450d012001410020036b413f71ad8820022003413f71ad220486842102200120048621010c010b20012003413f71ad862102420021010b20002001370300200020023703080b5701017e02400240200341c000710d002003450d0120012003413f71ad2204882002410020036b413f71ad86842101200220048821020c010b20022003413f71ad882101420021020b20002001370300200020023703080b7501027e200020034220882205200142208822067e200320027e7c200420017e7c200342ffffffff0f832203200142ffffffff0f8322017e2204422088200320067e7c22034220887c200342ffffffff0f83200520017e7c22034220887c37030820002003422086200442ffffffff0f83843703000b3e01017f230041106b2205240020052001200220032004410010fe04200529030021012000200541086a29030037030820002001370300200541106a24000b4c01017f230041206b22052400200542003703182005420037031020052001200220032004200541106a10fe04200529031021012000200529031837030820002001370300200541206a24000be20502037f067e230041306b2206240002400240024002400240024002400240024002402002500d002003500d012004500d02200479a7200279a76b2207413f4b0d0341ff0020076b2108200741016a21070c080b02402004500d0020050d040c060b024002402005450d0020034200510d0620054200370308200520012003823703000c010b20034200510d050b200120038021010c060b2004500d030240024002402001500d0020047b4201510d01200479a7200279a76b2207413e4b0d0241ff0020076b2108200741016a21070c090b02402005450d0020054200370300200520022004823703080b200220048021010c070b02402005450d002005200137030020052004427f7c2002833703080b200220047a423f838821010c060b2005450d040c020b024020037b4201510d0041bf7f200379a7200279a76b22076b2108200741c1006a21070c060b02402005450d002005420037030820052003427f7c2001833703000b20034201510d06200641206a2001200220037aa710fa04200641286a2903002102200629032021010c060b2005450d020b2005200137030020052002370308420021010c020b00000b420021010b420021020c010b200620012002200841ff007110f904200641106a20012002200741ff007110fa04200641086a2903002102200641106a41086a2903002109200629030021012006290310210a0240024020070d004200210b4200210c0c010b4200210c4200210d03402009420186200a423f8884220b200b427f8520047c200a4201862002423f8884220a427f85220b20037c200b54ad7c423f87220b2004837d200a200b200383220e54ad7d2109200a200e7d210a420020024201862001423f8884842102200d2001420186842101200b420183220b210d2007417f6a22070d000b0b02402005450d002005200a370300200520093703080b200c20024201862001423f8884842102200b20014201868421010b2000200137030020002002370308200641306a24000b0b809a060200418080c0000be59906180010001d000000f862110013000000dc03000009000000617373657274696f6e206661696c65643a20696e646578203c206c656e0000005000100043000000f10a00003000000000000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962616c6c6f632f7665632e7273005000100043000000fd0a00002c000000320000000000000001000000330000003400000035000000360000003700000038000000e0001000190000000001100048000000bb0100002d000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f6f70732f61726974682e72734469676573744974656d206e6f7420657175616c53657373696f6e20486973746f726963616c53657373696f6e7372656163686564206d6178696d756d2064657074682c2063616e6e6f742063726561746500003900000018000000040000003a0000003b0000003c0000003d0000003e0000003f0000006e6f7420656e6f7567682067617320746f20706179206261736520696e7374616e7469617465206665656e6f7420656e6f7567682067617320746f20706179207472616e736665722066656572656163686564206d6178696d756d2064657074682c2063616e6e6f74206d616b6520612063616c6c6e6f7420656e6f7567682067617320746f2070617920626173652063616c6c20666565636f6e747261637420686173206265656e20657669637465640000009002100048000000900a00000a0000000000000000000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e72739003100048000000b1010000230000009003100048000000b201000023000000690310001c0000007477110018000000e50300000d0000002003100049000000870200001d0000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f736f72742e7273617373657274696f6e206661696c65643a206d6964203c3d206c656e00000000000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e727320031000490000009d0000003a0000002003100049000000a4000000300000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d312e302e342f7372632f636f6d706163742e72730000000000e00410000a00000000000000a8f21000020000000000000000000000ec041000010000000000000000000000f40410000d00000000000000b0231100010000000000000000000000040510000100000000000000000000003cd0100008000000000000000c0510000400000000000000000000002c05100001000000000000004e65774163636f756e740000770510001b0000005265617065644163636f756e740000006005100017000000d823110009000000d82311000900000019241100070000001924110007000000340510002c000000205472616e7366657220737563636565646564202866726f6d2c20746f2c2076616c75652c2066656573292e20416e206163636f756e7420776173207265617065642e2041206e6577206163636f756e742077617320637265617465642e76657374696e672062616c616e636520746f6f206869676820746f2073656e642076616c75656163636f756e74206c6971756964697479207265737472696374696f6e732070726576656e74207769746864726177616c62656e6566696369617279206163636f756e74206d757374207072652d6578697374746f6f2066657720667265652066756e647320696e206163636f756e747061796d656e7420776f756c64206b696c6c206163636f756e7442616c616e63657320546f74616c49737375616e636542616c616e636573204672656542616c616e636542616c616e63657320526573657276656442616c616e636542616c616e636573204c6f636b7374696d657374616d702073657420696e20626c6f636b20646f65736e2774206d6174636820736c6f7420696e207365616c003d07100036000000f8031000630000005e01000005000000000000000000000000000000000710003d000000f8031000630000006501000005000000736869667465642073756666696369656e74206269747320726967687420746f206c656164206f6e6c79206c656164696e67207a65726f733b2071656450726576696f7573206d617463682061726d206d61746368657320616e7974696e67206c657373207468616e20325e33303b20716564003d07100036000000f8031000630000008a010000050000000000000000000000000000000000000000000000f803100063000000910100000500000042616c616e6365732056657374696e6765706f636820696e64696365732077696c6c206e6576657220726561636820325e3634206265666f726520746865206465617468206f662074686520756e6976657273653b20716564000000000000006408100008000000000000006c0810000200000000000000000000009c081000170000000000000000000000540910000b0000000000000060091000030000000000000000000000a80910000d000000000000007472616e736665720000000072d910000400000000000000a7ff100023000000000000005f3511000500000000000000c50b100013000000e40b10003600000048761100000000001a0c1000420000005c0c100048000000a40c100045000000e90c10002d0000004876110000000000160d1000460000004876110000000000c52d11000b0000005c0d10004c000000a80d100033000000db0d10005a0000004876110000000000350e1000130000004876110000000000480e1000540000009c0e10004b000000e70e1000350000001c0f100037000000530f1000560000004876110000000000d82d11000c0000007365745f62616c616e63650000000000629910000300000000000000a7ff10002300000000000000bd0b10000800000000000000c50b10001300000000000000d80b10000c00000000000000c50b100013000000100a1000250000004876110000000000350a1000480000007d0a100042000000bf0a100046000000050b10003a00000048761100000000003f0b10002d0000004876110000000000c52d11000b0000006c0b1000200000008c0b100031000000d82d11000c00000020536574207468652062616c616e636573206f66206120676976656e206163636f756e742e20546869732077696c6c20616c74657220604672656542616c616e63656020616e642060526573657276656442616c616e63656020696e2073746f726167652e2069742077696c6c20616c736f2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d202860546f74616c49737375616e636560292e20496620746865206e65772066726565206f722072657365727665642062616c616e63652069732062656c6f7720746865206578697374656e7469616c206465706f7369742c2069742077696c6c20726573657420746865206163636f756e74206e6f6e636520286073797374656d3a3a4163636f756e744e6f6e636560292e20546865206469737061746368206f726967696e20666f7220746869732063616c6c2069732060726f6f74602e202d20496e646570656e64656e74206f662074686520617267756d656e74732e202d20436f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e64207772697465732e6e65775f66726565436f6d706163743c543a3a42616c616e63653e6e65775f7265736572766564205472616e7366657220736f6d65206c697175696420667265652062616c616e636520746f20616e6f74686572206163636f756e742e20607472616e73666572602077696c6c207365742074686520604672656542616c616e636560206f66207468652073656e64657220616e642072656365697665722e2049742077696c6c2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d2062792074686520605472616e73666572466565602e204966207468652073656e6465722773206163636f756e742069732062656c6f7720746865206578697374656e7469616c206465706f736974206173206120726573756c74206f6620746865207472616e736665722c20746865206163636f756e742077696c6c206265207265617065642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d75737420626520605369676e65646020627920746865207472616e736163746f722e202d20446570656e64656e74206f6e20617267756d656e747320627574206e6f7420637269746963616c2c20676976656e2070726f70657220696d706c656d656e746174696f6e7320666f72202020696e70757420636f6e6669672074797065732e205365652072656c617465642066756e6374696f6e732062656c6f772e202d20497420636f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e642077726974657320696e7465726e616c6c7920616e64206e6f20636f6d706c657820636f6d7075746174696f6e2e2052656c617465642066756e6374696f6e733a2020202d2060656e737572655f63616e5f77697468647261776020697320616c776179732063616c6c656420696e7465726e616c6c792062757420686173206120626f756e64656420636f6d706c65786974792e2020202d205472616e7366657272696e672062616c616e63657320746f206163636f756e7473207468617420646964206e6f74206578697374206265666f72652077696c6c20636175736520202020202060543a3a4f6e4e65774163636f756e743a3a6f6e5f6e65775f6163636f756e746020746f2062652063616c6c65642e2020202d2052656d6f76696e6720656e6f7567682066756e64732066726f6d20616e206163636f756e742077696c6c2074726967676572202020202060543a3a4475737452656d6f76616c3a3a6f6e5f756e62616c616e6365646020616e642060543a3a4f6e4672656542616c616e63655a65726f3a3a6f6e5f667265655f62616c616e63655f7a65726f602e00000000000000641110000d0000000000000000000000711110000a00000000000000000000000000000000000000000000000000000000000000e88c11004412100000000000000000007c11100001000000000000000100000000000000841110000700000001010000000000000b2e11000c000000000000008b1110002b00000000000000000000000000000000000000e88c1100b81110000000000000000000c811100001000000000000000000000000000000d01110000b00000001010000000000000b2e11000c00000000000000711110000a00000000000000000000000000000000000000e88c1100441210000000000000000000dc1110000b000000000000000100000000000000341210000f00000001010000000000000b2e11000c00000000000000711110000a00000000000000000000000000000000000000e88c1100441210000000000000000000541210000b000000000000000100000000000000ac1210000500000001010000000000000b2e11000c00000000000000b11210002c00000000000000000000000000000000000000e88c1100e01210000000000000000000f0121000010000000000000001000000546f74616c49737375616e6365543a3a42616c616e636500211810002600000056657374696e6756657374696e675363686564756c653c543a3a42616c616e63652c20543a3a426c6f636b4e756d6265723e000032000000000000000100000040000000eb171000360000004672656542616c616e636500711510002700000048761100000000009815100050000000e81510005d00000045161000550000009a1610004f000000e9161000510000003a1710001500000048761100000000004f17100057000000a617100045000000526573657276656442616c616e63650032000000000000000100000041000000261310005d00000083131000270000004876110000000000aa1310005b000000051410004900000048761100000000004e1410005d000000ab1410002d0000004876110000000000d8141000530000002b151000460000004c6f636b735665633c42616c616e63654c6f636b3c543a3a42616c616e63652c20543a3a426c6f636b4e756d6265723e3e00000032000000000000000100000042000000f81210002e00000020416e79206c6971756964697479206c6f636b73206f6e20736f6d65206163636f756e742062616c616e6365732e2054686520616d6f756e74206f66207468652062616c616e6365206f66206120676976656e206163636f756e7420746861742069732065787465726e616c6c792072657365727665643b20746869732063616e207374696c6c2067657420736c61736865642c20627574206765747320736c6173686564206c617374206f6620616c6c2e20546869732062616c616e63652069732061202772657365727665272062616c616e63652074686174206f746865722073756273797374656d732075736520696e206f7264657220746f2073657420617369646520746f6b656e73207468617420617265207374696c6c20276f776e65642720627920746865206163636f756e7420686f6c6465722c20627574207768696368206172652073757370656e6461626c652e205768656e20746869732062616c616e63652066616c6c732062656c6f77207468652076616c7565206f6620604578697374656e7469616c4465706f736974602c207468656e2074686973202772657365727665206163636f756e74272069732064656c657465643a207370656369666963616c6c792c2060526573657276656442616c616e6365602e206073797374656d3a3a4163636f756e744e6f6e63656020697320616c736f2064656c6574656420696620604672656542616c616e63656020697320616c736f207a65726f2028697420616c736f206765747320636f6c6c617073656420746f207a65726f2069662069742065766572206265636f6d6573206c657373207468616e20604578697374656e7469616c4465706f736974602e2920546865202766726565272062616c616e6365206f66206120676976656e206163636f756e742e205468697320697320746865206f6e6c792062616c616e63652074686174206d61747465727320696e207465726d73206f66206d6f7374206f7065726174696f6e73206f6e20746f6b656e732e20497420616c6f6e65206973207573656420746f2064657465726d696e65207468652062616c616e6365207768656e20696e2074686520636f6e747261637420657865637574696f6e20656e7669726f6e6d656e742e205768656e20746869732062616c616e63652066616c6c732062656c6f77207468652076616c7565206f6620604578697374656e7469616c4465706f736974602c207468656e20746865202763757272656e74206163636f756e74272069732064656c657465643a207370656369666963616c6c7920604672656542616c616e6365602e20467572746865722c2074686520604f6e4672656542616c616e63655a65726f602063616c6c6261636b20697320696e766f6b65642c20676976696e672061206368616e636520746f2065787465726e616c206d6f64756c657320746f20636c65616e2075702064617461206173736f6369617465642077697468207468652064656c65746564206163636f756e742e206073797374656d3a3a4163636f756e744e6f6e63656020697320616c736f2064656c657465642069662060526573657276656442616c616e63656020697320616c736f207a65726f2028697420616c736f206765747320636f6c6c617073656420746f207a65726f2069662069742065766572206265636f6d6573206c657373207468616e20604578697374656e7469616c4465706f736974602e20496e666f726d6174696f6e20726567617264696e67207468652076657374696e67206f66206120676976656e206163636f756e742e2054686520746f74616c20756e6974732069737375656420696e207468652073797374656d2e0000000000601910001200000000000000711110000a00000000000000e88c11007419100000000000000000008419100001000000000000000000000034e810000b00000000000000711110000a00000000000000e88c11008c191000000000000000000040e8100001000000000000000000000048e810000b00000000000000711110000a00000000000000e88c11008c191000000000000000000054e810000100000000000000000000005ce810001200000000000000711110000a00000000000000e88c11008c191000000000000000000070e8100001000000000000000000000078e810001200000000000000711110000a00000000000000e88c11009c19100000000000000000009ce8100001000000000000004578697374656e7469616c4465706f736974000032000000000000000100000043000000ac19100035000000320000000000000001000000440000003200000000000000010000004500000020546865206d696e696d756d20616d6f756e7420726571756972656420746f206b65657020616e206163636f756e74206f70656e2e6e6f7420656e6f75676820667265652066756e64730000946a110028000000101a1000430000008c010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f62616c616e6365732f7372632f6c69622e727300101a1000430000008c0100000100000064657374696e6174696f6e2062616c616e636520746f6f206869676820746f20726563656976652076616c756562616c616e636520746f6f206c6f7720746f2073656e642076616c7565676f74206f766572666c6f7720616674657220616464696e6720612066656520746f2076616c756576616c756520746f6f206c6f7720746f20637265617465206163636f756e7400000000000000241b10002200000000000000481b1000010000000000000000000000601b100003000000000000007365745f70656e64696e675f7365636f6e646172795f736c6f74735f6368616e6765000000000000281c100006000000000000002e1c10000c000000781b100045000000bd1b100043000000001c100028000000205365747320612070656e64696e67206368616e676520746f20656e61626c65202f2064697361626c65207365636f6e6461727920736c6f742061737369676e6d656e742e205468652070656e64696e67206368616e67652077696c6c206265207365742061742074686520656e64206f66207468652063757272656e742065706f636820616e642077696c6c20626520656e6163746564206174206063757272656e745f65706f6368202b2032602e6368616e67654f7074696f6e3c626f6f6c3e000000000000042010000a00000000000000000000009ae110000300000000000000000000000000000000000000000000000000000000000000e88c11008c20100000000000000000001020100001000000000000000100000000000000007d10000b0000000000000000000000182010002700000000000000000000000000000000000000000000000000000000000000e88c11004020100000000000000000005020100001000000000000000100000000000000582010000e00000000000000000000009ae110000300000000000000000000000000000000000000000000000000000000000000e88c11008c20100000000000000000006820100003000000000000000100000000000000802010000b00000000000000000000009ae110000300000000000000000000000000000000000000000000000000000000000000e88c11008c20100000000000000000009c20100001000000000000000100000000000000a42010000e0000000000000000000000b22010000c00000000000000000000000000000000000000000000000000000000000000e88c1100c02010000000000000000000d020100002000000000000000100000000000000e02010001b0000000000000000000000ff2311000400000000000000000000000000000000000000000000000000000000000000e88c1100382210000000000000000000fc201000020000000000000000000000000000000c2110000a0000000000000000000000162110000800000000000000000000000000000000000000000000000000000000000000e88c1100802110000000000000000000202110000a000000000000000100000000000000702110000e0000000000000000000000162110000800000000000000000000000000000000000000000000000000000000000000e88c11008021100000000000000000009021100001000000000000000100000000000000982110000c00000000000000000000009ef310000300000000000000000000000000000000000000000000000000000000000000e88c1100a42110000000000000000000b421100009000000000000000100000000000000fc2110001100000001010000000000009ef3100003000000000000000d2210000d00000000000000000000000000000000000000e88c11001c221000000000000000000048761100000000000000000001000000000000002c2210000b0000000000000000000000ff2311000400000000000000000000000000000000000000000000000000000000000000e88c11003822100000000000000000004822100002000000000000000000000045706f6368496e6465780000a9271000150000005665633c28417574686f7269747949642c2042616265417574686f72697479576569676874293e00320000000000000001000000420000008e2710001b00000045706f63685374617274536c6f740000f526100040000000352710003e000000732710001b00000043757272656e74536c6f740032000000000000000100000046000000e0261000150000005365636f6e64617279536c6f747328626f6f6c2c20626f6f6c290000320000000000000001000000470000006026100042000000a22610003e00000050656e64696e675365636f6e64617279536c6f74734368616e676500ff2510003f0000003e2610002200000052616e646f6d6e6573735b75383b2033325d0000392410002e0000004876110000000000672410000b00000048761100000000007224100041000000b32410003e000000f12410004500000036251000450000007b25100041000000bc251000430000004e65787452616e646f6d6e65737300003200000000000000010000004800000022241000170000005365676d656e74496e64657832000000000000000100000049000000dd2210001f0000004876110000000000fc2210003d0000003923100040000000792310002500000048761100000000009e2310003b000000d9231000420000001b24100007000000556e646572436f6e737472756374696f6e5665633c5b75383b2033325d3e000032000000000000000100000042000000496e697469616c697a65640032000000000000000100000040000000582210003e00000096221000470000002054656d706f726172792076616c75652028636c656172656420617420626c6f636b2066696e616c697a6174696f6e292077686963682069732074727565206966207065722d626c6f636b20696e697469616c697a6174696f6e2068617320616c7265616479206265656e2063616c6c656420666f722063757272656e7420626c6f636b2e2052616e646f6d6e65737320756e64657220636f6e737472756374696f6e2e205765206d616b6520612074726164656f6666206265747765656e2073746f7261676520616363657373657320616e64206c697374206c656e6774682e2057652073746f72652074686520756e6465722d636f6e737472756374696f6e2072616e646f6d6e65737320696e207365676d656e7473206f6620757020746f2060554e4445525f434f4e535452554354494f4e5f5345474d454e545f4c454e475448602e204f6e63652061207365676d656e7420726561636865732074686973206c656e6774682c20776520626567696e20746865206e657874206f6e652e20576520726573657420616c6c207365676d656e747320616e642072657475726e20746f206030602061742074686520626567696e6e696e67206f662065766572792065706f63682e204e6578742065706f63682072616e646f6d6e6573732e205468652065706f63682072616e646f6d6e65737320666f7220746865202a63757272656e742a2065706f63682e20232053656375726974792054686973204d555354204e4f54206265207573656420666f722067616d626c696e672c2061732069742063616e20626520696e666c75656e6365642062792061206d616c6963696f75732076616c696461746f7220696e207468652073686f7274207465726d2e204974204d4159206265207573656420696e206d616e792063727970746f677261706869632070726f746f636f6c732c20686f77657665722c20736f206c6f6e67206173206f6e652072656d656d626572732074686174207468697320286c696b652065766572797468696e6720656c7365206f6e2d636861696e29206974206973207075626c69632e20466f72206578616d706c652c2069742063616e20626520757365642077686572652061206e756d626572206973206e656564656420746861742063616e6e6f742068617665206265656e2063686f73656e20627920616e206164766572736172792c20666f7220707572706f7365732073756368206173207075626c69632d636f696e207a65726f2d6b6e6f776c656467652070726f6f66732e2050656e64696e67206368616e676520746f20656e61626c652f64697361626c65207365636f6e6461727920736c6f74732077686963682077696c6c20626520747269676765726564206174206063757272656e745f65706f6368202b2032602e2057686574686572207365636f6e6461727920736c6f74732061726520656e61626c656420696e206361736520746865205652462d626173656420736c6f7420697320656d70747920666f72207468652063757272656e742065706f636820616e6420746865206e6578742065706f63682c20726573706563746976656c792e2043757272656e7420736c6f74206e756d6265722e20536c6f74206174207768696368207468652063757272656e742065706f636820737461727465642e20497420697320706f737369626c652074686174206e6f20626c6f636b2077617320617574686f7265642061742074686520676976656e20736c6f7420616e64207468652065706f6368206368616e676520776173207369676e616c6c6564206c61746572207468616e20746869732e2043757272656e742065706f636820617574686f7269746965732e2043757272656e742065706f636820696e6465782e000000000000302810000d000000000000009ae110000300000000000000e88c110040281000000000000000000050281000020000000000000000000000602810001100000000000000c7a710000900000000000000e88c110074281000000000000000000084281000050000000000000045706f63684475726174696f6e0000003200000000000000010000004a000000dc291000430000001f2a10003f0000004578706563746564426c6f636b54696d650000003200000000000000010000004b000000ac28100041000000ed2810004400000031291000410000007229100042000000b42910002800000020546865206578706563746564206176657261676520626c6f636b2074696d6520617420776869636820424142452073686f756c64206265206372656174696e6720626c6f636b732e2053696e636520424142452069732070726f626162696c6973746963206974206973206e6f74207472697669616c20746f20666967757265206f7574207768617420746865206578706563746564206176657261676520626c6f636b2074696d652073686f756c64206265206261736564206f6e2074686520736c6f74206475726174696f6e20616e642074686520736563757269747920706172616d657465722060636020287768657265206031202d20636020726570726573656e7473207468652070726f626162696c697479206f66206120736c6f74206265696e6720656d707479292e20546865206e756d626572206f66202a2a736c6f74732a2a207468617420616e2065706f63682074616b65732e20576520636f75706c652073657373696f6e7320746f2065706f6368732c20692e652e2077652073746172742061206e65772073657373696f6e206f6e636520746865206e65772065706f636820626567696e732e000000000000ec22110008000000000000003c2b1000010000000000000000000000442b10000100000000000000000000004c2b100008000000000000005cf21000010000000000000000000000542b10000100000000000000000000005c2b10000700000000000000642b10000300000000000000000000007c2b1000010000000000000000000000842b100005000000000000005cf210000100000000000000000000008c2b1000010000000000000000000000942b100008000000000000005cf210000100000000000000000000009c2b10000100000000000000b8a010000d0000006d2c10000e0000005370656e64696e67332c10003a0000004177617264656400b8a010000d0000001924110007000000d823110009000000132c1000200000004275726e74000000f02b100023000000526f6c6c6f766572a42b10004c000000205370656e64696e67206861732066696e69736865643b20746869732069732074686520616d6f756e74207468617420726f6c6c73206f76657220756e74696c206e657874207370656e642e20536f6d65206f66206f75722066756e64732068617665206265656e206275726e742e20536f6d652066756e64732068617665206265656e20616c6c6f63617465642e205765206861766520656e6465642061207370656e6420706572696f6420616e642077696c6c206e6f7720616c6c6f636174652066756e64732e204e65772070726f706f73616c2e54696d657374616d702055706461746554696d657374616d7020526563656e7448696e7473b82c100031000000e92c10004b0000007e0000000400000046696e616c2068696e74206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b2f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f66696e616c6974792d747261636b65722f7372632f6c69622e72734c2d100023000000e92c10004b0000007f0000000400000046696e616c697a6564206865696768742061626f766520626c6f636b206e756d62657254726561737572792050726f706f73616c73000000946a1100280000009c2d10004300000084000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f74726561737572792f7372632f6c69622e72730000000000642e10000d00000000000000742e1000020000000000000000000000a42e1000090000000000000000000000ec2e10000f00000000000000fc2e1000010000000000000000000000142f10000700000000000000000000004c2f10001000000000000000fc2e10000100000000000000000000005c2f1000080000000000000070726f706f73655f7370656e64000000000000005f35110005000000000000006435110015000000000000003a3110000b00000000000000a7ff100023000000683010004b000000b33010004d00000000311000150000004876110000000000c52d11000b000000d02d110008000000c5b61000190000001531100025000000d82d11000c00000072656a6563745f70726f706f73616c00000000005d3010000b0000000000000065ac1000160000001e3010003f0000004876110000000000c52d11000b000000d02d110008000000c5b6100019000000512e110010000000d82d11000c000000617070726f76655f70726f706f73616c9c2f100057000000f32f10002b0000004876110000000000c52d11000b000000d02d110008000000c5b6100019000000deb6100011000000d82d11000c00000020417070726f766520612070726f706f73616c2e2041742061206c617465722074696d652c207468652070726f706f73616c2077696c6c20626520616c6c6f636174656420746f207468652062656e656669636961727920616e6420746865206f726967696e616c206465706f7369742077696c6c2062652072657475726e65642e2052656a65637420612070726f706f736564207370656e642e20546865206f726967696e616c206465706f7369742077696c6c20626520736c61736865642e70726f706f73616c5f69642050757420666f727761726420612073756767657374696f6e20666f72207370656e64696e672e2041206465706f7369742070726f706f7274696f6e616c20746f207468652076616c756520697320726573657276656420616e6420736c6173686564206966207468652070726f706f73616c2069732072656a65637465642e2049742069732072657475726e6564206f6e6365207468652070726f706f73616c20697320617761726465642e202d204f6e65204442206368616e67652c206f6e6520657874726120444220656e7472792e62656e65666963696172790000000000000040b010000d0000000000000000000000b8a010000d00000000000000000000000000000000000000000000000000000000000000e88c11005032100000000000000000006032100001000000000000000100000000000000d0af1000090000000101000000000000b8a010000d00000000000000683210002400000000000000000000000000000000000000e88c11008c32100000000000000000009c32100001000000000000000000000000000000a4321000090000000000000000000000ad3210001200000000000000000000000000000000000000000000000000000000000000e88c1100c03210000000000000000000d032100001000000000000000100000032000000000000000100000049000000353310002900000050726f706f73616c3c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e32000000000000000100000040000000163310001f000000417070726f76616c735665633c50726f706f73616c496e6465783e0032000000000000000100000042000000d83210003e0000002050726f706f73616c20696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f742079657420617761726465642e2050726f706f73616c7320746861742068617665206265656e206d6164652e204e756d626572206f662070726f706f73616c7320746861742068617665206265656e206d6164652e000000000000403410000c000000000000004c3410000700000000000000e88c1100543410000000000000000000643410000200000000000000000000007434100013000000000000007a4511000c00000000000000e88c110088341000000000000000000098341000010000000000000000000000a03410000b00000000000000923111000e00000000000000e88c1100ac3410000000000000000000bc341000010000000000000000000000c434100004000000000000004c3410000700000000000000e88c1100c83410000000000000000000d8341000010000000000000050726f706f73616c426f6e645065726d696c6c003200000000000000010000004c0000009835100055000000ed3510004400000050726f706f73616c426f6e644d696e696d756d003200000000000000010000004300000046351000520000005370656e64506572696f64003200000000000000010000004d00000024351000220000004275726e3200000000000000010000004e000000e0341000440000002050657263656e74616765206f662073706172652066756e64732028696620616e7929207468617420617265206275726e7420706572207370656e6420706572696f642e20506572696f64206265747765656e2073756363657373697665207370656e64732e204d696e696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e204672616374696f6e206f6620612070726f706f73616c27732076616c756520746861742073686f756c6420626520626f6e64656420696e206f7264657220746f20706c616365207468652070726f706f73616c2e20416e2061636365707465642070726f706f73616c2067657473207468657365206261636b2e20412072656a65637465642070726f706f73616c20646f6573206e6f742e496e636f6e73697374656e74207374617465202d20636f756c646e277420736574746c6520696d62616c616e636520666f722066756e6473207370656e74206279207472656173757279576974686472617720686173206265656e20636865636b65642061626f76653b0a090909647565735f6c696d69746564203c2072656e745f627564676574203c2062616c616e6365202d2073756273697374656e6365203c2062616c616e6365202d206578697374656e7469616c5f6465706f7369743b0a0909097165640000004f00000008000000040000005000000054696d657374616d70204f72646572656448696e747354696d657374616d70204d656469616e616c77617973206174206c65617374206f6e6520726563656e742073616d706c653b20716564726563656e7420616e64206f72646572656420636f6e7461696e207468652073616d65206974656d733b207165640000510000000400000004000000520000000838100043000000e92c10004b000000b700000004000000c037100048000000900a00000a0000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e72737072756e696e672064696374617465642062792077696e646f775f73697a6520776869636820697320616c776179732073617475726174656420617420313b207165640000000000783810000a00000000000000843810000100000000000000000000009c381000020000000000000066696e616c5f68696e74000000000000c25010000400000000000000de2e110017000000ac3810003d000000e93810001b0000002048696e7420746861742074686520617574686f72206f66207468697320626c6f636b207468696e6b732074686520626573742066696e616c697a656420626c6f636b2069732074686520676976656e206e756d6265722e00000000743910000a00000000000000923111000e00000000000000e88c110080391000000000000000000090391000010000000000000000000000983910000d00000000000000923111000e00000000000000e88c1100a83910000000000000000000b8391000010000000000000057696e646f7753697a65000032000000000000000100000053000000073a1000460000005265706f72744c6174656e637900000032000000000000000100000054000000c039100047000000205468652064656c617920616674657220776869636820706f696e74207468696e6773206265636f6d6520737573706963696f75732e2044656661756c7420697320313030302e20546865206e756d626572206f6620726563656e742073616d706c657320746f206b6565702066726f6d207468697320636861696e2e2044656661756c74206973203130312e0000009c2d100043000000840000000100000050726f706f73657227732062616c616e636520746f6f206c6f774e6f2070726f706f73616c206174207468617420696e6465780000000000443b10000b0000000000000094231100020000000000000000000000503b1000010000000000000000000000583b10001000000000000000b0231100010000000000000000000000683b1000010000000000000000000000703b10000c00000000000000a4d010000100000000000000000000007c3b1000010000000000000000000000843b10000e00000000000000943b1000020000000000000000000000a43b10000100000000000000566f74657252656170656400423c100015000000426164526561706572536c6173686564333c10000f00000054616c6c7953746172746564fe3b10003500000054616c6c7946696e616c697a65640000202411000e000000202411000e000000ac3b10005200000020412074616c6c792028666f7220617070726f76616c20766f746573206f662073656174287329292068617320656e646564202877697468206f6e65206f72206d6f7265206e6577206d656d62657273292e20412074616c6c792028666f7220617070726f76616c20766f746573206f662073656174287329292068617320737461727465642e20736c6173686564207265617065722072656170656420766f7465722c20726561706572436f756e63696c205265676973746572496e666f4f66436f756e63696c204d656d62657273436f756e63696c204e65787446696e616c697a65803d100048000000900a00000a000000436f756e63696c205465726d4475726174696f6e436f756e63696c2050726573656e746174696f6e4475726174696f6e436f756e63696c204c6561646572626f61726400803d100048000000960a00000e000000436f756e63696c2043616e64696461746573436f756e63696c20566f746572496e666f4f6647757275206d656469746174696f6e66696e616c697a652063616e206f6e6c792062652063616c6c656420616674657220612074616c6c7920697320737461727465642e436f756e63696c20417070726f76616c734f66436f756e63696c20566f7465727300002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e727300000000803f10000d00000000000000903f1000030000000000000000000000d83f1000180000000000000000000000984010001300000000000000903f1000030000000000000000000000ac401000060000000000000000000000dc4010001300000000000000f0401000040000000000000000000000504110000c0000000000000000000000b04110000d00000000000000c0411000010000000000000000000000d84110000a000000000000000000000028421000100000000000000038421000010000000000000000000000504210000d0000000000000000000000b84210000e00000000000000c842100003000000000000000000000010431000080000000000000000000000504310001100000000000000644310000100000000000000000000007c431000030000000000000000000000f09610000d0000000000000094431000010000000000000000000000ac431000040000000000000000000000cc4310001900000000000000e843100001000000000000000000000000441000020000000000000000000000104410001100000000000000e84310000100000000000000000000002444100002000000000000007365745f617070726f76616c7300000000000000b45010000500000000000000b9501000090000000000000060ac100005000000000000009d4710001200000000000000c25010000400000000000000c650100008000000824c100058000000364c1000100000004876110000000000da4c1000300000000a4d10004a0000004876110000000000544d100035000000894d100051000000da4d10002c000000064e100053000000594e100062000000bb4e1000600000001b4f10001d000000384f1000570000008f4f1000350000004876110000000000c44f10006b0000002f5010001d0000004876110000000000c52d11000b000000d02d1100080000004c501000270000007350100041000000d82d11000c00000070726f78795f7365745f617070726f76616c7300d14b100065000000364c1000100000004876110000000000c52d11000b000000464c10003c000000d82d11000c000000726561705f696e6163746976655f766f7465720000000000a84b10000e00000000000000fa2e11000c00000000000000629910000300000000000000a7ff10002300000000000000b64b10000900000000000000fa2e11000c00000000000000bf4b100012000000000000009d47100012000000474a1000580000009f4a10005c000000fb4a1000280000004876110000000000234b1000450000004876110000000000684b1000400000004876110000000000c52d11000b000000d02d110008000000204a100027000000d82d11000c000000726574726163745f766f7465720000000000000060ac10000500000000000000fa2e11000c000000444910004b00000048761100000000008f491000420000004876110000000000d14910004f0000004876110000000000c52d11000b000000d02d110008000000204a100027000000d82d11000c0000007375626d69745f63616e64696461637900000000404910000400000000000000fa2e11000c000000af4710001e0000004876110000000000cd47100044000000487611000000000011481000480000005948100051000000aa4810004c000000f64810001e0000004876110000000000c52d11000b00000014491000180000002c49100014000000d82d11000c00000070726573656e745f77696e6e65720000000000008f4710000900000000000000a7ff1000230000000000000098471000050000000000000064351100150000000000000060ac100005000000000000009d471000120000009b46100059000000f4461000680000005c4710001e0000004876110000000000c52d11000b0000007a47100015000000deb6100011000000d82d11000c0000007365745f646573697265645f736561747300000000000000f64410000500000000000000fa2e11000c000000db451000590000003446100052000000864610001500000000000000629910000300000000000000a7ff100023000000fb44100048000000487611000000000043451000480000008b451000500000007365745f70726573656e746174696f6e5f6475726174696f6e00000000000000f64410000500000000000000de2e110017000000a04410005600000088441000180000007365745f7465726d5f6475726174696f6e0000003444100054000000884410001800000020536574207468652070726573656e746174696f6e206475726174696f6e2e2049662074686572652069732063757272656e74206120766f7465206265696e672070726573656e74656420666f722c2077696c6c20696e766f6b65206066696e616c697a655f766f7465602e20536574207468652070726573656e746174696f6e206475726174696f6e2e2049662074686572652069732063757272656e746c79206120766f7465206265696e672070726573656e74656420666f722c2077696c6c636f756e742052656d6f7665206120706172746963756c6172206d656d6265722066726f6d20746865207365742e20546869732069732065666665637469766520696d6d6564696174656c792e204e6f74653a20412074616c6c792073686f756c642068617070656e20696e7374616e746c7920286966206e6f7420616c726561647920696e20612070726573656e746174696f6e20706572696f642920746f2066696c6c2074686520736561742069662072656d6f76616c206d65616e732074686174207468652064657369726564206d656d6265727320617265206e6f74206d65742e20536574207468652064657369726564206d656d62657220636f756e743b206966206c6f776572207468616e207468652063757272656e7420636f756e742c207468656e2073656174732077696c6c206e6f7420626520757020656c656374696f6e207768656e2074686579206578706972652e204966206d6f72652c207468656e2061206e657720766f74652077696c6c2062652073746172746564206966206f6e65206973206e6f7420616c726561647920696e2070726f67726573732e20436c61696d207468617420607369676e656460206973206f6e65206f662074686520746f702053656c663a3a63617272795f636f756e742829202b2063757272656e745f766f746528292e312063616e646964617465732e204f6e6c7920776f726b73206966207468652060626c6f636b5f6e756d626572203e3d2063757272656e745f766f746528292e306020616e6420603c2063757272656e745f766f746528292e30202b2070726573656e746174696f6e5f6475726174696f6e28296020607369676e6564602073686f756c642068617665206174206c65617374202d204f28766f746572732920636f6d707574652e63616e646964617465746f74616c436f6d706163743c566f7465496e6465783e205375626d6974206f6e6573656c6620666f722063616e6469646163792e204163636f756e74206d757374206861766520656e6f756768207472616e736665727261626c652066756e647320696e20697420746f207061792074686520626f6e642e204e4f54453a20696620606f726967696e602068617320616c72656164792061737369676e656420617070726f76616c7320766961205b607365745f617070726f76616c73605d2c2069742077696c6c204e4f54206861766520616e7920757361626c652066756e647320746f20706173732063616e64696461637920626f6e6420616e64206d75737420666972737420726574726163742e204e6f746520746861742073657474696e6720617070726f76616c732077696c6c206c6f636b2074686520656e746972652062616c616e6365206f662074686520766f74657220756e74696c2072657472616374696f6e206f72206265696e67207265706f727465642e202d20496e646570656e64656e74206f6620696e7075742e202d205468726565204442206368616e6765732e736c6f742052656d6f7665206120766f7465722e20416c6c20766f746573206172652063616e63656c6c656420616e642074686520766f746572206465706f7369742069732072657475726e65642e2054686520696e646578206d7573742062652070726f7669646564206173206578706c61696e656420696e205b60766f7465725f6174605d2066756e6374696f6e2e20416c736f2072656d6f76657320746865206c6f636b206f6e207468652062616c616e6365206f662074686520766f7465722e20536565205b60646f5f7365745f617070726f76616c732829605d2e202d2054776f20666577657220444220656e74726965732c206f6e65204442206368616e67652e2052656d6f7665206120766f7465722e20466f72206974206e6f7420746f206265206120626f6e642d636f6e73756d696e67206e6f2d6f702c20616c6c20617070726f7665642063616e64696461746520696e6469636573206d757374206e6f772062652065697468657220756e72656769737465726564206f72207265676973746572656420746f20612063616e646964617465207468617420726567697374657265642074686520736c6f742061667465722074686520766f7465722067617665207468656972206c61737420617070726f76616c207365742e20426f746820696e6469636573206d7573742062652070726f7669646564206173206578706c61696e656420696e205b60766f7465725f6174605d2066756e6374696f6e2e204d61792062652063616c6c656420627920616e796f6e652e2052657475726e732074686520766f746572206465706f73697420746f20607369676e6564602e7265706f727465725f696e64657877686f5f696e646578617373756d65645f766f74655f696e646578205365742063616e64696461746520617070726f76616c732066726f6d20612070726f78792e20417070726f76616c20736c6f747320737461792076616c6964206173206c6f6e672061732063616e6469646174657320696e2074686f736520736c6f74732061726520726567697374657265642e202d2053616d6520617320607365745f617070726f76616c73602077697468206f6e65206164646974696f6e616c2073746f7261676520726561642e205365742063616e64696461746520617070726f76616c732e20417070726f76616c20736c6f747320737461792076616c6964206173206c6f6e672061732063616e6469646174657320696e2074686f736520736c6f7473204c6f636b732074686520746f74616c2062616c616e6365206f662063616c6c657220696e646566696e6974656c792e204f6e6c79205b60726574726163745f766f746572605d206f72205b60726561705f696e6163746976655f766f746572605d2063616e20756e6c6f636b207468652062616c616e63652e206068696e746020617267756d656e7420697320696e74657270726574656420646966666572656e746c79206261736564206f6e3a202d20696620606f726967696e602069732073657474696e6720617070726f76616c7320666f72207468652066697273742074696d653a2054686520696e6465782077696c6c20626520636865636b656420666f72206265696e6720612076616c6964205f686f6c655f20696e2074686520766f746572206c6973742e2020202d206966207468652068696e7420697320636f72726563746c7920706f696e74696e6720746f206120686f6c652c206e6f206665652069732064656475637465642066726f6d20606f726967696e602e2020202d204f74686572776973652c207468652063616c6c2077696c6c2073756363656564206275742074686520696e6465782069732069676e6f72656420616e642073696d706c792061207075736820746f20746865206c617374206368756e6b2020207769746820667265652073706163652068617070656e732e20496620746865206e65772070757368206361757365732061206e6577206368756e6b20746f20626520637265617465642c20612066656520696e646963617465642062792020205b60566f74696e67466565605d2069732064656475637465642e202d20696620606f726967696e6020697320616c7265616479206120766f7465723a2074686520696e646578205f5f6d7573745f5f2062652076616c696420616e6420706f696e7420746f2074686520636f727265637420706f736974696f6e206f662074686520606f726967696e6020696e207468652063757272656e7420766f74657273206c6973742e204e6f7465207468617420616e7920747261696c696e67206066616c73656020766f74657320696e2060766f746573602069732069676e6f7265643b20496e20617070726f76616c20766f74696e672c206e6f7420766f74696e6720666f7220612063616e64696461746520616e6420766f74696e672066616c73652c2061726520657175616c2e202d2054776f20657874726120444220656e74726965732c206f6e65204442206368616e67652e202d20417267756d656e742060766f74657360206973206c696d6974656420696e206c656e67746820746f206e756d626572206f662063616e646964617465732e766f7465735665633c626f6f6c3e68696e74536574496e64657800000000000050561000140000000000000000000000923111000e00000000000000000000000000000000000000000000000000000000000000e88c110018621000000000000000000064561000010000000000000001000000000000006c5610000c0000000000000000000000923111000e00000000000000000000000000000000000000000000000000000000000000e88c11001862100000000000000000007856100001000000000000000100000000000000805610000c00000000000000000000009ef310000300000000000000000000000000000000000000000000000000000000000000e88c11001862100000000000000000008c5610000100000000000000010000000000000058b01000070000000000000000000000945610002300000000000000000000000000000000000000000000000000000000000000e88c1100285810000000000000000000b856100004000000000000000100000000000000d8561000090000000000000000000000e15610000900000000000000000000000000000000000000000000000000000000000000e88c1100186210000000000000000000ec56100001000000000000000100000000000000f45610000b0000000101000000000000ff5610001800000000000000175710001100000000000000000000000000000000000000e88c11002858100000000000000000002857100005000000000000000100000000000000505710000e00000001010000000000000b2e11000c000000000000005e5710001000000000000000000000000000000000000000e88c11007057100000000000000000008057100002000000000000000000000000000000905710000b00000001010000000000000b2e11000c000000000000009b5710001700000000000000000000000000000000000000e88c1100b45710000000000000000000c457100001000000000000000000000000000000cc571000060000000101000000000000c65010000800000000000000d25710001900000000000000000000000000000000000000e88c1100285810000000000000000000ec57100001000000000000000100000000000000f45710000c0000000000000000000000c65010000800000000000000000000000000000000000000000000000000000000000000e88c11001862100000000000000000000058100001000000000000000100000000000000085810000a0000000000000000000000c65010000800000000000000000000000000000000000000000000000000000000000000e88c110018621000000000000000000014581000010000000000000001000000000000001c5810000a0000000000000000000000253c11001100000000000000000000000000000000000000000000000000000000000000e88c11002858100000000000000000003858100001000000000000000100000000000000405810000e00000000000000000000009ef310000300000000000000000000000000000000000000000000000000000000000000e88c11001862100000000000000000005058100001000000000000000100000000000000585810000c0000000000000000000000645810002800000000000000000000000000000000000000000000000000000000000000e88c11008c58100000000000000000009c58100001000000000000000000000000000000a45810000b0000000000000000000000af5810002100000000000000000000000000000000000000000000000000000000000000e88c1100d05810000000000000000000e058100002000000000000000000000000000000a83c11000500000001010000000000000b2e11000c000000000000000b2e11000c00000000000000000000000000000000000000e88c1100f05810000000000000000000c03c110002000000000000000000000050726573656e746174696f6e4475726174696f6e4f5e10004f0000005465726d4475726174696f6e295e100026000000446573697265645365617473ef5d10003a0000005665633c28543a3a4163636f756e7449642c20543a3a426c6f636b4e756d626572293e00c75c10005e000000255d10005c000000815d100054000000d55d10001a000000566f7465436f756e74566f7465496e6465780000805c100047000000417070726f76616c734f6628543a3a4163636f756e7449642c20536574496e646578295665633c417070726f76616c466c61673e6b5b1000680000004876110000000000d35b10005900000048761100000000002c5c1000540000005265676973746572496e666f4f6628566f7465496e6465782c2075333229000032000000000000000100000055000000f65a10005f000000555b100016000000566f746572496e666f4f66566f746572496e666f3c42616c616e63654f663c543e3e000032000000000000000100000040000000d55a100021000000566f746572735665633c4f7074696f6e3c543a3a4163636f756e7449643e3e00925a1000430000004e657874566f746572536574535a10003f000000566f746572436f756e740000395a10001a00000043616e646964617465730000320000000000000001000000420000001d5a10001c00000043616e646964617465436f756e740000f9591000240000004e65787446696e616c697a6528543a3a426c6f636b4e756d6265722c207533322c205665633c543a3a4163636f756e7449643e2932000000000000000100000056000000b1591000480000004c6561646572626f6172645665633c2842616c616e63654f663c543e2c20543a3a4163636f756e744964293e320000000000000001000000400000000059100067000000675910004a000000320000000000000001000000400000002047657420746865206c6561646572626f61726420696620776527726520696e207468652070726573656e746174696f6e2070686173652e2054686520666972737420656c656d656e742069732074686520776569676874206f66206561636820656e7472793b204974206d617920626520746865206469726563742073756d6d656420617070726f76616c207374616b65732c206f7220612077656967687465642076657273696f6e206f662069742e20546865206163636f756e747320686f6c64696e672074686520736561747320746861742077696c6c206265636f6d652066726565206f6e20746865206e6578742074616c6c792e2043757272656e74206e756d626572206f66206163746976652063616e64696461746573205468652070726573656e742063616e646964617465206c6973742e2043757272656e74206e756d626572206f6620566f746572732e20746865206e65787420667265652073657420746f2073746f7265206120766f74657220696e2e20546869732077696c6c206b6565702067726f77696e672e205468652070726573656e7420766f746572206c69737420286368756e6b656420616e6420636170706564206174205b60564f5445525f5345545f53495a45605d292e20426173696320696e666f726d6174696f6e2061626f7574206120766f7465722e2054686520766f746520696e64657820616e64206c69737420736c6f742074686174207468652063616e646964617465206077686f60207761732072656769737465726564206f7220604e6f6e6560206966207468657920617265206e6f742063757272656e746c7920726567697374657265642e2041206c697374206f6620766f74657320666f72206561636820766f7465722e2054686520766f746573206172652073746f726564206173206e756d657269632076616c75657320616e642070617273656420696e2061206269742d77697365206d616e6e65722e20496e206f7264657220746f2067657420612068756d616e2d7265616461626c6520726570726573656e746174696f6e2028605665633c626f6f6c3e60292c20757365205b60616c6c5f617070726f76616c735f6f66605d2e20467572746865726d6f72652c206561636820766563746f72206f66207363616c617273206973206368756e6b656420776974682074686520636170206f662060415050524f56414c5f5345545f53495a45602e2054686520746f74616c206e756d626572206f6620766f746520726f756e6473207468617420686176652068617070656e6564206f722061726520696e2070726f67726573732e205468652063757272656e74206d656d626572736869702e205768656e2074686572652773206120766f746520676f696e67206f6e2c20746869732073686f756c64207374696c6c206265207573656420666f7220657865637574697665206d6174746572732e2054686520626c6f636b206e756d62657220287365636f6e6420656c656d656e7420696e20746865207475706c65292069732074686520626c6f636b207468617420746865697220706f736974696f6e2069732061637469766520756e74696c202863616c63756c61746564206279207468652073756d206f662074686520626c6f636b206e756d626572207768656e20746865206d656d6265722077617320656c656374656420616e64207468656972207465726d206475726174696f6e292e204e756d626572206f66206163636f756e747320746861742073686f756c6420636f6e737469747574652074686520636f6c6c6563746976652e20486f77206c6f6e67206561636820706f736974696f6e2069732061637469766520666f722e20486f77206c6f6e6720746f2067697665206561636820746f702063616e64696461746520746f2070726573656e74207468656d73656c7665732061667465722074686520766f746520656e64732e000000000000d06010000d000000000000007a4511000c00000000000000e88c1100e06010000000000000000000f0601000020000000000000000000000006110000a000000000000007a4511000c00000000000000e88c11000c61100000000000000000001c6110000100000000000000000000002461100009000000000000007a4511000c00000000000000e88c1100306110000000000000000000406110000200000000000000000000005061100014000000000000007a4511000c00000000000000e88c110064611000000000000000000074611000020000000000000000000000846110000a000000000000009ef310000300000000000000e88c1100906110000000000000000000a0611000020000000000000000000000b06110001300000000000000e15610000900000000000000e88c1100c46110000000000000000000d4611000030000000000000000000000584511000c00000000000000923111000e00000000000000e88c1100ec6110000000000000000000fc6110000200000000000000000000000c6210000a000000000000009ef310000300000000000000e88c110018621000000000000000000028621000050000000000000000000000506210000e000000000000009ef310000300000000000000e88c1100606210000000000000000000706210000100000000000000000000007862100011000000000000009ef310000300000000000000e88c11008c62100000000000000000009c621000010000000000000043616e646964616379426f6e6400000032000000000000000100000057000000ac6610004e000000fa66100014000000566f74696e67426f6e640000320000000000000001000000430000006a66100042000000566f74696e6746656500000032000000000000000100000058000000036610004a0000004d6610001d00000050726573656e74536c617368506572566f746572320000000000000001000000440000009f65100045000000e46510001f0000004361727279436f756e7400003200000000000000010000005900000031651000470000007865100027000000496e6163746976654772616365506572696f64003200000000000000010000005a000000946410004c000000e06410004b0000002b651000060000003200000000000000010000005b00000042641000490000008b641000090000004465636179526174696f000032000000000000000100000049000000ef6210004d0000003c631000410000007d63100047000000c46310004a0000000e64100034000000564f5445525f5345545f53495a4500003200000000000000010000005c000000cb62100024000000415050524f56414c5f5345545f53495a450000003200000000000000010000005d000000a46210002700000020546865206368756e6b2073697a65206f662074686520617070726f76616c20766563746f722e20546865206368756e6b2073697a65206f662074686520766f74657220766563746f722e20446563617920666163746f72206f6620776569676874207768656e206265696e6720616363756d756c617465642e2049742073686f756c64207479706963616c6c792062652073657420746f205f5f6174206c656173745f5f20606d656d626572736869705f73697a65202d316020746f206b6565702074686520636f6c6c656374697665207365637572652e205768656e2073657420746f20604e602c20697420696e64696361746573206028312f4e295e7460206f66207374616b656420697320646563617965642061742077656967687420696e6372656d656e742073746570206074602e20302077696c6c20726573756c7420696e206e6f20776569676874206265696e6720616464656420617420616c6c20286e6f726d616c20617070726f76616c20766f74696e67292e204120726561736f6e61626c652064656661756c742076616c75652069732032342e20486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e204120726561736f6e61626c652064656661756c742076616c756520697320313030302e20486f77206d616e7920766f746520696e6469636573206e65656420746f20676f20627920616674657220612074617267657420766f7465722773206c61737420766f7465206265666f726520746865792063616e2062652072656170656420696620746865697220617070726f76616c7320617265206d6f6f742e204120726561736f6e61626c652064656661756c742076616c756520697320312e20486f77206d616e792072756e6e6572732d75702073686f756c64206861766520746865697220617070726f76616c73207065727369737420756e74696c20746865206e65787420766f74652e204120726561736f6e61626c652064656661756c742076616c756520697320322e205468652070756e6973686d656e742c2070657220766f7465722c20696620796f752070726f7669646520616e20696e76616c69642070726573656e746174696f6e2e204120726561736f6e61626c652064656661756c742076616c756520697320312e2054686520616d6f756e74206f662066656520706169642075706f6e206561636820766f7465207375626d697373696f6e2c20756e6c6573732069662074686579207375626d69742061205f686f6c655f20696e64657820616e64207265706c6163652069742e20486f77206d7563682073686f756c64206265206c6f636b656420757020696e206f7264657220746f2062652061626c6520746f207375626d697420766f7465732e20486f77206d7563682073686f756c64206265206c6f636b656420757020696e206f7264657220746f207375626d6974206f6e6527732063616e6469646163792e204120726561736f6e61626c652064656661756c742076616c756520697320392e0000946a11002800000028671000440000000b010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f656c656374696f6e732f7372632f6c69622e727328671000440000000b01000001000000436f756e63696c2050726f787963616e6e6f74207265617020647572696e672070726573656e746174696f6e20706572696f647265706f72746572206d757374206265206120766f746572696e76616c6964207265706f7274657220696e646578766f746520696e646578206e6f742063757272656e7463616e6e6f74207265617020647572696e6720677261636520706572696f6474617267657420666f7220696e616374697669747920636c65616e7570206d75737420626520616374697665626164207265706f7274657220696e6465786261642074617267657420696e646578696e76616c69642074617267657420696e64657872657472616374696f6e20696e646578206d69736d6174636872657472616374696f6e20696e64657820696e76616c696463616e6e6f742072657472616374207768656e2070726573656e74696e6763616e6e6f742072657472616374206e6f6e2d766f7465726475706c69636174652063616e646964617465207375626d697373696f6e696e76616c69642063616e64696461746520736c6f7463616e64696461746520686173206e6f7420656e6f7567682066756e647363616e6e6f742070726573656e74206f757473696465206f662070726573656e746174696f6e20706572696f64696e646578206e6f742063757272656e747374616b65206465706f736974656420746f2070726573656e742077696e6e657220616e6420626520616464656420746f206c6561646572626f6172642073686f756c64206265206e6f6e2d7a65726f6c6561646572626f617264206d757374206578697374207768696c652070726573656e742070686173652061637469766570726573656e746572206d75737420686176652073756666696369656e7420736c61736861626c652066756e647370726573656e7465642063616e646964617465206d7573742062652063757272656e7463616e646964617465206e6f7420776f72746879206f66206c6561646572626f61726463616e646964617465206d757374206e6f7420666f726d2061206475706c696361746564206d656d62657220696620656c65637465646475706c69636174652070726573656e746174696f6e696e636f727265637420746f74616c6e6f20617070726f76616c206368616e67657320647572696e672070726573656e746174696f6e20706572696f64696e636f727265637420766f746520696e646578616d6f756e74206f662063616e6469646174657320746f207265636569766520617070726f76616c20766f7465732073686f756c64206265206e6f6e2d7a65726f616d6f756e74206f662063616e64696461746520766f7465732063616e6e6f742065786365656420616d6f756e74206f662063616e64696461746573696e76616c696420766f74657220696e64657877726f6e6720766f74657220696e6465786e657720766f746572206d75737420686176652073756666696369656e742066756e647320746f207061792074686520626f6e64496d4f6e6c696e6520476f737369704174616c7265616479206d757461626c7920626f72726f776564003200000000000000010000005e0000006772616e62616265696d6f6e306c100033000000636c10004b000000b200000005000000636f6e74726163742073756273797374656d20726573756c74696e6720696e20706f73697469766520696d62616c616e6365212f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6e7472616374732f7372632f6163636f756e745f64622e7273616c726561647920626f72726f77656400003200000000000000010000005f00000073726d6c2f696d2d6f6e6c696e652d776f726b65722d737461747573006d100048000000900a00000a000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e7273416c69766520636f6e7472616374206f7220746f6d6273746f6e6520616c726561647920657869737473636f6465206973206e6f7420666f756e647072697374696e6520636f6465206973206e6f7420666f756e647468657265206973206e6f7420656e6f7567682067617320666f722073746f72696e672074686520636f64654f757464617465642068656172626561742072656365697665642e496e76616c6964206865617262656174207369676e61747572652e000000000043be100006000000000000006000000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000006200000000000000000000000000000063000000000000000000000000000000d4741000040000000000000064000000000000000000000000000000000000000000000000000000000000006500000000000000000000000200000000000000000000000000000000000000660000000000000000000000000000000ba7100009000000000000006700000000000000000000000000000000000000000000000000000000000000680000000000000000000000020000000000000000000000000000000000000069000000000000000000000000000000458a10000a000000000000006a000000000000000000000000000000000000000000000000000000000000006b000000000000000000000002000000000000000000000000000000000000006300000000000000000000000000000088a3100007000000000000006c00000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000006d00000000000000000000000000000063000000000000000000000000000000d874100008000000000000006e000000000000000000000000000000000000000000000000000000000000006f0000000000000000000000000000007000000000000000000000000000000071000000000000000000000000000000410b11000700000000000000720000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000740000000000000000000000000000007500000000000000000000000000000099801000070000000000000076000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000078000000000000000000000000000000790000000000000000000000000000007935110009000000000000007a000000000000000000000000000000000000000000000000000000000000007b0000000000000000000000000000007c0000000000000000000000000000007d000000000000000000000000000000e074100007000000000000007e000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000008000000000000000000000000000000063000000000000000000000000000000e7741000120000000000000081000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000008000000000000000000000000000000063000000000000000000000000000000f9741000090000000000000082000000000000000000000000000000000000000000000000000000000000008300000000000000000000000000000084000000000000000000000000000000850000000000000000000000000000000275100013000000000000008600000000000000000000000000000000000000000000000000000000000000870000000000000000000000000000008800000000000000000000000000000063000000000000000000000000000000157510000f00000002000000000000000000000000000000000000000000000000000000000000000000000089000000000000000000000002000000000000000000000000000000000000008a0000000000000000000000000000002475100007000000000000008b000000000000000000000000000000000000000000000000000000000000008c0000000000000000000000000000008d000000000000000000000000000000630000000000000000000000000000002b75100008000000000000008e000000000000000000000000000000000000000000000000000000000000008f000000000000000000000000000000900000000000000000000000000000009100000000000000000000000000000033751000090000000000000092000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000094000000000000000000000000000000950000000000000000000000000000004db71000040000000000000096000000000000000000000000000000000000000000000000000000000000009700000000000000000000000000000098000000000000000000000000000000630000000000000000000000000000003c751000080000000000000099000000000000000000000000000000000000000000000000000000000000009a0000000000000000000000000000009b0000000000000000000000000000006300000000000000000000004261626542616c616e636573436f756e63696c546563686e6963616c436f6d6d6974746565456c656374696f6e73546563686e6963616c4d656d6265727368697046696e616c697479547261636b65724772616e6470615472656173757279436f6e747261637473496d4f6e6c696e65000000007075100009000000000000007c75100002000000000000000000000048761100000000000000000068656172746265617400000000000000707510000900000000000000ac7510001900000000000000c57510000900000000000000ce751000120000004865617274626561743c543a3a426c6f636b4e756d6265723e7369676e6174757265417574686f726974795369676e617475726500000000e8761000080000000000000000000000923111000e00000000000000000000000000000000000000000000000000000000000000e88c1100f076100000000000000000000077100001000000000000000100000000000000087710000400000000000000000000000c7710001000000000000000000000000000000000000000000000000000000000000000e88c11001c77100000000000000000002c7710000100000000000000010000000000000034771000120000000201010000000000b77011000c0000000000000046771000090000000000000023d110000700000000000000e88c110050771000000000000000000060771000020000000000000001000000476f7373697041743200000000000000010000004900000001781000280000004b6579735665633c417574686f7269747949643e32000000000000000100000042000000cd7710003400000052656365697665644865617274626561747341757468496e646578003200000000000000010000009c000000707710003a000000aa7710002300000020466f7220656163682073657373696f6e20696e646578207765206b6565702061206d617070696e67206f662060417574686f7269747949646020746f20606f6666636861696e3a3a4f70617175654e6574776f726b5374617465602e205468652063757272656e7420736574206f66206b6579732074686174206d61792069737375652061206865617274626561742e2054686520626c6f636b206e756d626572207768656e2077652073686f756c6420676f737369702e7375627374726174652d6e6f646500df6acb689907609b0200000037e397fc7c91f5e40100000040fe3ad401f8959a03000000d2bc9897eed08f1501000000f78b278be53f454c01000000ed99c5acb25eedf502000000cbca25e39f1423870100000022f09549cb59f9ff01000000ab3c0572291feb8b010000005365656420697320616e207574663820737472696e6700004f00000008000000040000009d000000517910000d000000367910001b000000108c110002000000f478100042000000d4010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f6e6f64652f72756e74696d652f7372632f6c69622e727342616420696e70757420646174612070726f766964656420746f20657865637574655f626c6f636b00006879100010000000696e697469616c697a655f626c6f636b807910000f0000006170706c795f65787472696e736963009879100013000000696e686572656e745f65787472696e7369637300b47910000f000000636865636b5f696e686572656e747300cc7910001400000076616c69646174655f7472616e73616374696f6ee87910000f0000006f6666636861696e5f776f726b657200007a1000160000006772616e6470615f70656e64696e675f6368616e67650000207a1000150000006772616e6470615f666f726365645f6368616e6765000000407a10001500000067656e65726174655f73657373696f6e5f6b65797366696e616c6e756d46524e4b3a73657373696f6e3a6b657973417574686f727368697020417574686f7253657373696f6e2056616c696461746f72734772616e64706146696e616c697479205374616c6c656453657373696f6e204e6578744b65797300000000e47a10001200000000000000f87a1000010000000000000000000000107b100001000000000000007265706f72745f6d69736265686176696f72000000000000317b1000070000000000000023d1100007000000187b100019000000205265706f727420736f6d65206d69736265686176696f722e5f7265706f72744772616e64706146696e616c6974790000000000007d10000b00000000000000000000000b7d10002300000000000000000000000000000000000000000000000000000000000000e88c1100988310000000000000000000307d100001000000000000000100000000000000387d10000500000000000000000000003d7d10001b00000000000000000000000000000000000000000000000000000000000000e88c1100587d10000000000000000000687d100001000000000000000100000000000000707d10000d00000000000000000000007d7d10002300000000000000000000000000000000000000000000000000000000000000e88c1100b88b10000000000000000000a07d100001000000000000000000000000000000a87d10000a0000000000000000000000923111000e00000000000000000000000000000000000000000000000000000000000000e88c1100b47d10000000000000000000c47d100001000000000000000000000000000000cc7d1000070000000000000000000000d37d10002000000000000000000000000000000000000000000000000000000000000000e88c1100f47d10000000000000000000047e1000010000000000000000000000417574686f7269746965735665633c28417574686f7269747949642c20417574686f72697479576569676874293e0000b47e10001b000000537461746553746f72656453746174653c543a3a426c6f636b4e756d6265723e3200000000000000010000009e000000907e10002400000050656e64696e674368616e676553746f72656450656e64696e674368616e67653c543a3a426c6f636b4e756d6265723e5f7e1000310000004e657874466f72636564000032000000000000000100000040000000307e10002f0000005374616c6c656428543a3a426c6f636b4e756d6265722c20543a3a426c6f636b4e756d6265722900320000000000000001000000550000000c7e10002400000020607472756560206966207765206172652063757272656e746c79207374616c6c65642e206e65787420626c6f636b206e756d6265722077686572652077652063616e20666f7263652061206368616e67652e2050656e64696e67206368616e67653a20287369676e616c65642061742c207363686564756c6564206368616e6765292e205374617465206f66207468652063757272656e7420617574686f72697479207365742e205468652063757272656e7420617574686f72697479207365742e0000000000fc7e10000800000000000000047f1000020000000000000000000000347f10000a000000000000007365745f6b657973000000004abd100004000000000000008d801000070000000000000094801000050000000000000023d1100007000000847f100039000000bd7f1000480000000580100031000000487611000000000036801000350000004876110000000000c52d11000b0000006b80100022000000f32d110016000000d82d11000c0000002053657473207468652073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c657220746f20606b6579602e20416c6c6f777320616e206163636f756e7420746f20736574206974732073657373696f6e206b6579207072696f7220746f206265636f6d696e6720612076616c696461746f722e205468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e20546865206469737061746368206f726967696e206f6620746869732066756e6374696f6e206d757374206265207369676e65642e202d204f286c6f67206e2920696e206e756d626572206f66206163636f756e74732e543a3a4b65797370726f6f6653657373696f6e00000000a41311000a0000000000000000000000088310001300000000000000000000000000000000000000000000000000000000000000e88c11009883100000000000000000001c83100001000000000000000100000000000000248310000c0000000000000000000000b77011000c00000000000000000000000000000000000000000000000000000000000000e88c1100308310000000000000000000408310000100000000000000010000000000000048831000070000000000000000000000ff2311000400000000000000000000000000000000000000000000000000000000000000e88c1100dc8b100000000000000000005083100001000000000000000100000000000000588310000d0000000000000000000000ff2311000400000000000000000000000000000000000000000000000000000000000000e88c1100dc8b100000000000000000006883100001000000000000000100000000000000708310000a00000000000000000000007a8310001e00000000000000000000000000000000000000000000000000000000000000e88c1100988310000000000000000000a883100002000000000000000100000000000000b883100008000000020401000000000023d110000700000000000000c08310000e000000000000008d8010000700000000000000e88c1100d08310000000000000000000e0831000040000000000000000000000000000000084100008000000020401000000000023d110000700000000000000088410001400000000000000c08310000e00000000000000e88c1100b88b100000000000000000001c8410000400000000000000000000005665633c543a3a56616c696461746f7249643e00428610001f00000043757272656e74496e64657832000000000000000100000049000000248610001e0000004368616e67656400f68510002e0000005175657565644368616e676564000000e1851000150000005175657565644b6579735665633c28543a3a56616c696461746f7249642c20543a3a4b657973293e320000000000000001000000420000005a8510004f000000a9851000380000004e6578744b657973543a3a56616c696461746f724964000032000000000000000100000040000000338510002700000048761100000000008584100056000000db841000580000004b65794f776e6572284b65795479706549642c205665633c75383e293c8410004900000048761100000000008584100056000000db8410005800000020546865206f776e6572206f662061206b65792e20546865207365636f6e64206b65792069732074686520604b657954797065496460202b2074686520656e636f646564206b65792e20546865206669727374206b657920697320616c77617973206044454455505f4b45595f5052454649586020746f206861766520616c6c20746865206461746120696e207468652073616d65206272616e6368206f662074686520747269652e20486176696e6720616c6c206461746120696e207468652073616d65206272616e63682073686f756c642070726576656e7420736c6f77696e6720646f776e206f7468657220717565726965732e20546865206e6578742073657373696f6e206b65797320666f7220612076616c696461746f722e2054686520717565756564206b65797320666f7220746865206e6578742073657373696f6e2e205768656e20746865206e6578742073657373696f6e20626567696e732c207468657365206b6579732077696c6c206265207573656420746f2064657465726d696e65207468652076616c696461746f7227732073657373696f6e206b6579732e20517565756564206b657973206368616e6765642e205472756520696620616e797468696e6720686173206368616e67656420696e20746869732073657373696f6e2e2043757272656e7420696e646578206f66207468652073657373696f6e2e205468652063757272656e7420736574206f662076616c696461746f72732e000000000000009c8610001000000000000000ac8610000500000000000000e88c1100b48610000000000000000000c4861000020000000000000044454455505f4b45595f505245464958265b75385d0000003200000000000000010000009f000000d4861000590000002d8710000d0000002055736564206173206669727374206b657920666f7220604e6578744b6579736020616e6420604b65794f776e65726020746f2070757420616c6c20746865206461746120696e746f207468652073616d65206272616e6368206f662074686520747269652e4772616e64706146696e616c6974792050656e64696e674368616e67654772616e64706146696e616c69747920537461746553657373696f6e205175657565644b6579734772616e64706146696e616c697479204e657874466f726365644f0000000800000004000000a0000000a10000000000000000000000a200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004f0000000800000004000000a0000000a10000000000000000000000a20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000417574686f727368697020556e636c657353657373696f6e204b65794f776e657200000000000000e88910000a00000000000000f48910000100000000000000000000000c8a100001000000000000007365745f756e636c65730000000000002d8a10000a00000000000000378a10000e000000148a1000190000002050726f76696465206120736574206f6620756e636c65732e6e65775f756e636c65735665633c543a3a4865616465723e417574686f72736869700000000000588b10000600000000000000000000005e8b10003a00000000000000000000000000000000000000000000000000000000000000e88c1100988b10000000000000000000a88b100001000000000000000100000000000000b08b10000600000000000000000000000b2e11000c00000000000000000000000000000000000000000000000000000000000000e88c1100b88b10000000000000000000c88b100001000000000000000000000000000000d08b10000c0000000000000000000000ff2311000400000000000000000000000000000000000000000000000000000000000000e88c1100dc8b10000000000000000000ec8b1000010000000000000001000000556e636c65735665633c556e636c65456e7472794974656d3c543a3a426c6f636b4e756d6265722c20543a3a486173682c20543a3a4163636f756e7449643e3e320000000000000001000000420000003c8c100007000000417574686f72000032000000000000000100000040000000238c100019000000446964536574556e636c657332000000000000000100000040000000f48b10002f000000205768657468657220756e636c6573207765726520616c72656164792073657420696e207468697320626c6f636b2e20417574686f72206f662063757272656e7420626c6f636b2e20556e636c6573005c8c10007c000000d88c1000490000007900000006000000657865632e7072656661625f6d6f64756c652e696e697469616c2063616e27742062652067726561746572207468616e20657865632e7072656661625f6d6f64756c652e6d6178696d756d3b0a09090909090974687573204d656d6f72793a3a6e6577206d757374206e6f74206661696c3b0a0909090909097165642f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6e7472616374732f7372632f7761736d2f6d6f642e72736e6f206173736f6369617465642076616c696461746f7220494420666f72206163636f756e742e72656769737465726564206475706c6963617465206b6579556e636c657320616c72656164792073657420696e20626c6f636b2e756e636c6520616c726561647920696e636c75646564756e636c652069732067656e65736973756e636c6520697320746f6f206869676820696e20636861696e756e636c6520706172656e74206e6f7420696e20636861696e756e636c65206e6f7420726563656e7420656e6f75676820746f20626520696e636c75646564756e636c65733030496e686572656e7420776974682073616d65206964656e74696669657220616c726561647920657869737473214e6f206f74686572206572726f72732061726520616363657074656420616674657220616e2068617264206572726f72215468657265206973206f6e6c79206f6e6520666174616c206572726f723b20716564004f000000080000000400000050000000626164207369676e617475726520696e2065787472696e7369630000000000008c8f10000b0000000000000048761100000000000000000000000000988f1000010000000000000000000000a08f10000d0000000000000048761100000000000000000000000000b08f1000010000000000000000000000b88f10000e0000000000000048761100000000000000000000000000c88f1000010000000000000000000000d08f10000c0000000000000048761100000000000000000000000000dc8f1000010000000000000000000000e48f10000500000000000000ec8f1000010000000000000000000000f48f100001000000000000004d656d626572416464656400ff901000390000004d656d62657252656d6f766564000000c49010003b0000004d656d626572735377617070656400008d901000370000004d656d626572735265736574479010004600000044756d6d79000000189010002f000000fc8f10001c000000205068616e746f6d206d656d6265722c206e6576657220757365642e73725f7374643a3a6d61726b65723a3a5068616e746f6d446174613c284163636f756e7449642c204576656e74293e20546865206d656d62657273686970207761732072657365743b2073656520746865207472616e73616374696f6e20666f722077686f20746865206e6577207365742069732e2054776f206d656d62657273207765726520737761707065643b2073656520746865207472616e73616374696f6e20666f722077686f2e2054686520676976656e206d656d626572207761732072656d6f7665643b2073656520746865207472616e73616374696f6e20666f722077686f2e2054686520676976656e206d656d626572207761732061646465643b2073656520746865207472616e73616374696f6e20666f722077686f2e320000000000000001000000a3000000946a110028000000609110004500000061000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f6d656d626572736869702f7372632f6c69622e727373657269616c697a656420617267732073686f756c642062652070726f7669646564206279207468652072756e74696d653b0a090909636f72726563746c792073657269616c697a656420646174612073686f756c6420626520646573657269616c697a61626c653b0a090909716564000000946a110028000000bc6a11005000000037010000090000000000000080d1f00840787d01000000000065cd1d23b4cc3a113b5c2301000000d31b421e4fdcba34836c472001000000c75bbd1e52a1fd2e01b4511d010000005feb3f1f1d03952998c57b1a01000000bdb6ca1fa50181245d60c61701000000abd95e20029dc11fec4f3215010000006fadfd2034d5561b086ec01201000000efdba82133aa4017c3a4711001000000eb7a6222fd1b7f132df1460e01000000c1332d23942a1210ad66410c01000000777f0c2408d6f90c5e33620a01000000a3040525591e360ab7a5aa080100000085311d268803c70760341c070100000097465e279f85ac054289b805010000007346d628a4a4e603ce9181040100000019e89b2abe607502ad987903010000009db7d72c54ba5801bb71a30201000000eb88dd2ff4b29000c5cf0202010000000b8c8d349e412700f8d7a50101000000e59510001c0000007094100044000000bf00000003000000c1951000240000007094100044000000c80000000300000089951000380000007094100044000000060100002a00000061951000280000007094100044000000070100003200000039951000280000007094100044000000090100002c0000000d9510002c0000007094100044000000080100004c000000db9410003200000070941000440000003101000003000000b49410002700000070941000440000003901000004000000489410002800000070941000440000003f0100000300000053746f7261676520726f6f74206d757374206d6174636820746861742063616c63756c617465642e2f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f6578656375746976652f7372632f6c69622e7273446967657374206974656d206d757374206d6174636820746861742063616c63756c617465642e4e756d626572206f6620646967657374206974656d73206d757374206d6174636820746861742063616c63756c617465642e416c6c2065787472696e736963732073686f756c6420686176652074686520636f7272656374206e6f6e636545787472696e736963732073686f756c64206e6f742065786365656420626c6f636b206c696d6974416c6c2065787472696e736963732073686f756c642062652070726f7065726c79207369676e6564416c6c2065787472696e736963732073686f756c6420686176652073656e6465722061626c6520746f2070617920746865697220666565735472616e73616374696f6e207472696520726f6f74206d7573742062652076616c69642e506172656e7420686173682073686f756c642062652076616c69642e00000000000000b49610000a00000000000000c0961000010000000000000000000000d8961000030000000000000000000000f09610000d00000000000000c096100001000000000000000000000000971000030000000000000000000000189710000b0000000000000024971000020000000000000000000000549710000300000000000000000000006c9710000d000000000000007c9710000100000000000000000000009497100004000000000000006164645f6d656d6265720000000000006299100003000000000000000b2e11000c000000169910001f0000004876110000000000359910002d00000072656d6f76655f6d656d626572000000c2981000240000004876110000000000e698100030000000737761705f6d656d6265720000000000b998100006000000000000000b2e11000c00000000000000bf98100003000000000000000b2e11000c0000005b9810003000000048761100000000008b9810002e00000072657365745f6d656d6265727300000000000000549810000700000000000000253c110011000000b4971000560000000a9810001b0000004876110000000000259810002f000000204368616e676520746865206d656d6265727368697020746f2061206e6577207365742c20646973726567617264696e6720746865206578697374696e67206d656d626572736869702e204265206e69636520616e64207061737320606d656d6265727360207072652d736f727465642e204d6179206f6e6c792062652063616c6c65642066726f6d206052657365744f726967696e60206f7220726f6f742e6d656d626572732053776170206f7574206f6e65206d656d626572206072656d6f76656020666f7220616e6f746865722060616464602e204d6179206f6e6c792062652063616c6c65642066726f6d2060537761704f726967696e60206f7220726f6f742e72656d6f76656164642052656d6f76652061206d656d626572206077686f602066726f6d20746865207365742e204d6179206f6e6c792062652063616c6c65642066726f6d206052656d6f76654f726967696e60206f7220726f6f742e204164642061206d656d626572206077686f6020746f20746865207365742e204d6179206f6e6c792062652063616c6c65642066726f6d20604164644f726967696e60206f7220726f6f742e77686f496e7374616e6365314d656d626572736869700000000058b01000070000000000000000000000253c11001100000000000000000000000000000000000000000000000000000000000000e88c1100d09910000000000000000000e099100001000000000000000100000032000000000000000100000042000000e899100032000000205468652063757272656e74206d656d626572736869702c2073746f72656420617320616e206f726465726564205665632e000060911000450000006100000001000000496e7374616e6365314d656d62657273686970204d656d62657273616c72656164792061206d656d626572626164206f726967696e6e6f742061206d656d626572000000809a100048000000960a00000e0000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e727300000000f49a10000f00000000000000049b1000020000000000000000000000149b100004000000000000004e65774163636f756e74496e64657800d823110009000000af9b10000c000000349b1000220000004876110000000000569b100041000000979b1000180000002041206e6577206163636f756e7420696e646578207761732061737369676e65642e2054686973206576656e74206973206e6f7420747269676765726564207768656e20616e206578697374696e6720696e64657820697320726561737369676e656420746f20616e6f7468657220604163636f756e744964602e4163636f756e74496e646578496e76616c6964206f726967696e000000e49b10002b0000000f9c100044000000000100000400000054696d657374616d70206d7573742062652075706461746564206f6e636520696e2074686520626c6f636b2f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f74696d657374616d702f7372632f6c69622e7273006c9c1000300000000f9c100044000000f40000000400000054696d657374616d70206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636bb49c10004e0000000f9c100044000000f50000000400000054696d657374616d70206d75737420696e6372656d656e74206279206174206c65617374203c4d696e696d756d506572696f643e206265747765656e2073657175656e7469616c20626c6f636b73000000000000ec22110008000000000000000c9e10000400000000000000000000002c9e10000200000000000000000000003c9e10000500000000000000449e10000500000000000000000000006c9e10000200000000000000000000007c9e1000080000000000000084d01000010000000000000000000000849e10000100000000000000000000008c9e10000b0000000000000084d01000010000000000000000000000989e10000100000000000000000000006e2311000800000000000000a09e1000020000000000000000000000b09e1000010000000000000000000000b89e10000e00000000000000a09e1000020000000000000000000000c89e10000100000000000000d823110009000000b8a010000d000000e1231100040000004aa010000b00000055a0100053000000a8a0100010000000566f746564000000d823110009000000e123110004000000ff231100040000004aa010000b0000004aa010000b000000c29f10004200000004a0100046000000417070726f766564919f100031000000446973617070726f766564005c9f100035000000e123110004000000ff231100040000001b9f1000410000004d656d62657245786563757465640000d09e10004b00000020412073696e676c65206d656d6265722064696420736f6d6520616374696f6e3b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e2041206d6f74696f6e207761732065786563757465643b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e2041206d6f74696f6e20776173206e6f7420617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2077617320617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2028676976656e20686173682920686173206265656e20766f746564206f6e20627920676976656e206163636f756e742c206c656176696e6720612074616c6c79202879657320766f74657320616e64206e6f20766f74657320676976656e20726573706563746976656c7920617320604d656d626572436f756e7460292e4d656d626572436f756e742041206d6f74696f6e2028676976656e20686173682920686173206265656e2070726f706f7365642028627920676976656e206163636f756e742920776974682061207468726573686f6c642028676976656e20604d656d626572436f756e7460292e50726f706f73616c496e64657854696d657374616d70204e6f77496e7374616e636532436f6c6c656374697665204d656d62657273496e7374616e636531436f6c6c656374697665204d656d62657273496e646963657320456e756d536574004f000000080000000400000050000000946a11002800000040a110003f0000006a000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f7375646f2f7372632f6c69622e727300946a11002800000098a11000420000004a000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f696e64696365732f7372632f6c69622e72730000946a110028000000f4a11000450000008b000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6c6c6563746976652f7372632f6c69622e727300000098a11000420000004a00000001000000696e76616c6964206163636f756e7420696e64657854696d657374616d7020746f6f2066617220696e2066757475726520746f206163636570744765747320616e64206465636f6465732074696d657374616d7020696e686572656e74206461746100000000000008a31000050000000000000010a3100001000000000000000000000018a3100001000000000000000000000020a310000a00000000000000b02311000100000000000000000000002ca3100001000000000000005375646964000000ff2311000400000070a31000180000004b65794368616e676564000034a310003c00000020546865207375646f6572206a757374207377697463686564206964656e746974793b20746865206f6c64206b657920697320737570706c6965642e2041207375646f206a75737420746f6f6b20706c6163652e496e6469636573000000000040a410000b00000000000000000000004ba410000f00000000000000000000000000000000000000000000000000000000000000e88c110028b3100000000000000000005ca410000100000000000000010000000000000064a410000700000001010000000000004ba410000f00000000000000253c11001100000000000000000000000000000000000000e88c110038b3100000000000000000006ca410000100000000000000010000004e657874456e756d536574543a3a4163636f756e74496e64657800008aa410001f000000456e756d5365740074a41000160000002054686520656e756d65726174696f6e20736574732e20546865206e657874206672656520656e756d65726174696f6e207365742e496e7374616e636531436f6c6c6563746976652050726f706f73616c73496e7374616e636531436f6c6c65637469766520566f74696e67496e7374616e636532436f6c6c6563746976652050726f706f73616c73496e7374616e636532436f6c6c65637469766520566f74696e67496e6469636573204e657874456e756d53657400000000000058a5100003000000000000005ca5100001000000000000000000000074a5100009000000000000007365740000000000f6a610000300000000000000f9a6100012000000bca51000160000004876110000000000d2a510005600000028a610003600000048761100000000005ea6100051000000afa61000110000004876110000000000c0a610003600000020536574207468652063757272656e742074696d652e20546869732063616c6c2073686f756c6420626520696e766f6b65642065786163746c79206f6e63652070657220626c6f636b2e2049742077696c6c2070616e6963206174207468652066696e616c697a6174696f6e2070686173652c20696620746869732063616c6c206861736e2774206265656e20696e766f6b656420627920746861742074696d652e205468652074696d657374616d702073686f756c642062652067726561746572207468616e207468652070726576696f7573206f6e652062792074686520616d6f756e742073706563696669656420627920604d696e696d756d506572696f64602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652060496e686572656e74602e6e6f77436f6d706163743c543a3a4d6f6d656e743e54696d657374616d7000000000c4a71000030000000000000000000000c7a710000900000000000000000000000000000000000000000000000000000000000000e88c1100d0a710000000000000000000e0a7100001000000000000000100000000000000e8a71000090000000000000000000000ff2311000400000000000000000000000000000000000000000000000000000000000000e88c1100f4a71000000000000000000004a810000100000000000000010000004e6f77543a3a4d6f6d656e743200000000000000010000004600000039a8100024000000446964557064617465000000320000000000000001000000400000000ca810002d00000020446964207468652074696d657374616d7020676574207570646174656420696e207468697320626c6f636b3f2043757272656e742074696d6520666f72207468652063757272656e7420626c6f636b2e0000000000000098a810000d00000000000000c7a710000900000000000000e88c1100a8a810000000000000000000b8a8100004000000000000004d696e696d756d506572696f64000000320000000000000001000000a4000000d8a810005a00000032a910005a0000008ca9100059000000e5a910001c00000020546865206d696e696d756d20706572696f64206265747765656e20626c6f636b732e204265776172652074686174207468697320697320646966666572656e7420746f20746865202a65787065637465642a20706572696f6420746861742074686520626c6f636b2070726f64756374696f6e206170706172617475732070726f76696465732e20596f75722063686f73656e20636f6e73656e7375732073797374656d2077696c6c2067656e6572616c6c7920776f726b2077697468207468697320746f2064657465726d696e6520612073656e7369626c6520626c6f636b2074696d652e20652e672e20466f7220417572612c2069742077696c6c20626520646f75626c65207468697320706572696f64206f6e2064656661756c742073657474696e67732e00000000000000b4aa10000b00000000000000c0aa1000010000000000000000000000d8aa1000040000000000000000000000f8aa1000070000000000000000ab100001000000000000000000000018ab1000030000000000000000000000b8281100070000000000000030ab100002000000000000000000000060ab100004000000000000000000000070291100040000000000000080ab1000030000000000000000000000c8ab100004000000000000007365745f6d656d626572730000000000f8ad10000b00000000000000253c11001100000077ad100054000000cbad1000170000004876110000000000e2ad100016000000657865637574650000000000583311000800000000000000f1ac10001e0000000fad10003d00000048761100000000004cad10002b00000000000000d4ac10000900000000000000ddac10001400000000000000583311000800000000000000f1ac10001e000000c52d11000b00000082ac100024000000a6ac10002e000000d82d11000c000000000000005833110008000000000000007c2f1100070000000000000060ac1000050000000000000065ac100016000000000000007bac10000700000000000000ff23110004000000c52d11000b000000e8ab1000230000000bac100055000000d82d11000c000000202d20426f756e6465642073746f72616765207265616420616e64207772697465732e202d2057696c6c20626520736c696768746c792068656176696572206966207468652070726f706f73616c20697320617070726f766564202f20646973617070726f7665642061667465722074686520766f74652e696e646578436f6d706163743c50726f706f73616c496e6465783e617070726f7665202d20426f756e6465642073746f7261676520726561647320616e64207772697465732e202d20417267756d656e7420607468726573686f6c6460206861732062656172696e67206f6e207765696768742e7468726573686f6c64436f6d706163743c4d656d626572436f756e743e426f783c3c542061732054726169743c493e3e3a3a50726f706f73616c3e20446973706174636820612070726f706f73616c2066726f6d2061206d656d626572207573696e672074686520604d656d62657260206f726967696e2e204f726967696e206d7573742062652061206d656d626572206f662074686520636f6c6c6563746976652e205365742074686520636f6c6c6563746976652773206d656d62657273686970206d616e75616c6c7920746f20606e65775f6d656d62657273602e204265206e69636520746f2074686520636861696e20616e642070726f76696465206974207072652d736f727465642e20526571756972657320726f6f74206f726967696e2e6e65775f6d656d62657273496e7374616e636531436f6c6c656374697665000000000000d0af1000090000000000000000000000d9af10000c00000000000000000000000000000000000000000000000000000000000000e88c110038b310000000000000000000e8af100001000000000000000100000000000000f0af10000a00000001010000000000007c2f11000700000000000000faaf10001900000000000000000000000000000000000000e88c110018b31000000000000000000014b01000010000000000000000000000000000001cb010000600000001010000000000007c2f1100070000000000000022b010001300000000000000000000000000000000000000e88c110018b31000000000000000000038b010000100000000000000000000000000000040b010000d00000000000000000000009ef310000300000000000000000000000000000000000000000000000000000000000000e88c110028b31000000000000000000050b010000100000000000000010000000000000058b01000070000000000000000000000253c11001100000000000000000000000000000000000000000000000000000000000000e88c110038b31000000000000000000060b0100001000000000000000100000050726f706f73616c735665633c543a3a486173683e00000028b110002400000050726f706f73616c4f663c542061732054726169743c493e3e3a3a50726f706f73616c00f5b0100033000000566f74696e67566f7465733c543a3a4163636f756e7449643e000000c8b010002d00000050726f706f73616c436f756e74000000b6b01000120000004d656d626572730068b010004e000000205468652063757272656e74206d656d62657273206f662074686520636f6c6c6563746976652e20546869732069732073746f72656420736f7274656420286a7573742062792076616c7565292e2050726f706f73616c7320736f206661722e20566f746573206f6e206120676976656e2070726f706f73616c2c206966206974206973206f6e676f696e672e2041637475616c2070726f706f73616c20666f72206120676976656e20686173682c20696620697427732063757272656e742e2054686520686173686573206f6620746865206163746976652070726f706f73616c732e496e7374616e636532436f6c6c6563746976650000000000d0af1000090000000000000000000000d9af10000c00000000000000000000000000000000000000000000000000000000000000e88c110038b310000000000000000000e8af100001000000000000000100000000000000f0af10000a00000001010000000000007c2f11000700000000000000faaf10001900000000000000000000000000000000000000e88c110018b31000000000000000000014b01000010000000000000000000000000000001cb010000600000001010000000000007c2f1100070000000000000022b010001300000000000000000000000000000000000000e88c110018b31000000000000000000038b010000100000000000000000000000000000040b010000d00000000000000000000009ef310000300000000000000000000000000000000000000000000000000000000000000e88c110028b31000000000000000000050b010000100000000000000010000000000000058b01000070000000000000000000000253c11001100000000000000000000000000000000000000000000000000000000000000e88c110038b31000000000000000000060b0100001000000000000000100000032000000000000000100000040000000320000000000000001000000490000003200000000000000010000004200000040a110003f0000006a000000010000006f6e6c79207468652063757272656e74207375646f206b65792063616e207375646f5375646f204b65796f6e6c79207468652063757272656e74207375646f206b65792063616e206368616e676520746865207375646f206b657900f4a11000450000008b0000000100000070726f706f736572206e6f742061206d656d6265726475706c69636174652070726f706f73616c73206e6f7420616c6c6f776564496e7374616e636531436f6c6c6563746976652050726f706f73616c4f66496e7374616e636531436f6c6c6563746976652050726f706f73616c436f756e7470726f706f73616c206d757374206578697374766f746572206e6f742061206d656d6265726d69736d61746368656420696e6465786475706c696361746520766f74652069676e6f7265640000a0b4100048000000960a00000e0000000000000000000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e7273496e7374616e636532436f6c6c6563746976652050726f706f73616c4f66496e7374616e636532436f6c6c6563746976652050726f706f73616c436f756e74000000000080b510000400000000000000682a110001000000000000000000000084b51000090000000000000000000000ccb510000700000000000000d4b51000010000000000000000000000ecb5100009000000000000007375646fefb610004e000000487611000000000091b61000340000004876110000000000c52d11000b000000d02d110008000000c5b61000190000003db7100010000000d82d11000c0000007365745f6b6579000000000058fe10000300000000000000a7ff10002300000034b610005d000000487611000000000091b61000340000004876110000000000c52d11000b000000d02d110008000000c5b6100019000000deb6100011000000d82d11000c0000002041757468656e74696361746573207468652063757272656e74207375646f206b657920616e6420736574732074686520676976656e204163636f756e7449642028606e6577602920617320746865206e6577207375646f206b65792e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e202d204c696d697465642073746f726167652072656164732e202d204f6e65204442206368616e67652e2041757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c20776974682060526f6f7460206f726967696e2e202d204e6f204442207772697465732e5375646f00000000000000acb710000300000000000000000000000b2e11000c00000000000000000000000000000000000000000000000000000000000000e88c1100b0b710000000000000000000c0b710000100000000000000010000004b65790032000000000000000100000048000000c8b71000210000002054686520604163636f756e74496460206f6620746865207375646f206b65792e626164206f726967696e3a20657870656374656420746f206265206e6f206f726967696e626164206f726967696e3a20657870656374656420746f206265206120726f6f74206f726967696e626164206f726967696e3a20657870656374656420746f2062652061207369676e6564206f726967696e3a65787472696e7369635f696e64657873746f72616765206973206e6f74206e756c6c2c207468657265666f7265206d75737420626520612076616c696420747970650000c0b8100019000000e0b8100048000000290100000e00000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f6c69622e727340b910000e0000004eb9100048000000280100004a0000006578706c696369742070616e69632f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f6c69622e7273000040b910000e0000004eb9100048000000270100004a00000053797374656d204e756d62657253797374656d2045787472696e73696373526f6f7453797374656d2044696765737453797374656d20426c6f636b4861736853797374656d204163636f756e744e6f6e63650000320000000000000001000000a3000000946a1100280000002cba100041000000e3000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f73797374656d2f7372632f6c69622e72737472616e73616374696f6e20626972746820626c6f636b20616e6369656e7453797374656d20506172656e744861736853797374656d2052616e646f6d4d6174657269616c0000f0ba100048000000960a00000e00000053797374656d204576656e747353797374656d204576656e74546f70696373000000000000000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e72730000000040bc10000a00000000000000487611000000000000000000000000004cbc100001000000000000000000000054bc100006000000000000005cbc100001000000000000000000000074bc10000100000000000000000000007cbc10000e000000000000008cbc1000010000000000000000000000a4bc1000010000000000000000000000acbc10000800000000000000b4bc1000010000000000000000000000ccbc1000010000000000000000000000d4bc10000b00000000000000e0bc1000010000000000000000000000f8bc100001000000000000000000000000bd10000c000000000000000cbd100001000000000000000000000024bd1000010000000000000066696c6c5f626c6f636b0000fbbd10004800000072656d61726b000000000000f4bd1000070000000000000023d1100007000000d9bd10001b0000007365745f686561705f7061676573000000000000d4bd100005000000000000009ae110000300000095bd10003f0000007365745f636f64650000000058fe1000030000000000000023d110000700000083bd1000120000007365745f73746f72616765000000000071bd1000050000000000000076bd10000d00000056bd10001b0000006b696c6c5f73746f72616765000000004abd100004000000000000004ebd1000080000002cbd10001e000000204b696c6c20736f6d65206974656d732066726f6d2073746f726167652e6b6579735665633c4b65793e2053657420736f6d65206974656d73206f662073746f726167652e6974656d735665633c4b657956616c75653e2053657420746865206e657720636f64652e2053657420746865206e756d626572206f6620706167657320696e2074686520576562417373656d626c7920656e7669726f6e6d656e74277320686561702e7061676573204d616b6520736f6d65206f6e2d636861696e2072656d61726b2e5f72656d61726b20412062696720646973706174636820746861742077696c6c20646973616c6c6f7720616e79206f74686572207472616e73616374696f6e20746f20626520696e636c756465642e53797374656d0000000000000074c310000c00000001010000000000000b2e11000c0000000000000080c310000800000000000000000000000000000000000000e88c110084c51000000000000000000088c310000100000000000000010000000000000090c310000e00000000000000000000009ef310000300000000000000000000000000000000000000000000000000000000000000e88c1100dcc310000000000000000000a0c3100001000000000000000000000000000000a8c31000130000000000000000000000bbc310000600000000000000000000000000000000000000000000000000000000000000e88c1100dcc310000000000000000000c4c3100001000000000000000000000000000000ccc310001000000000000000000000009ef310000300000000000000000000000000000000000000000000000000000000000000e88c1100dcc310000000000000000000ecc3100001000000000000000000000000000000f4c3100014000000000000000000000008c410001000000000000000000000000000000000000000000000000000000000000000e88c110018c41000000000000000000028c410000200000000000000010000000000000038c41000090000000101000000000000923111000e000000000000007c2f11000700000000000000000000000000000000000000e88c1100e8c41000000000000000000044c41000010000000000000001000000000000004cc410000d00000001010000000000009ef31000030000000000000023d110000700000000000000000000000000000000000000e88c11005cc4100000000000000000006cc410000100000000000000010000000000000074c410000e000000000000000000000082c410001200000000000000000000000000000000000000000000000000000000000000e88c110094c410000000000000000000a4c4100002000000000000000100000000000000b4c41000060000000000000000000000923111000e00000000000000000000000000000000000000000000000000000000000000e88c110084c510000000000000000000bcc4100001000000000000000100000000000000c4c410000a00000000000000000000007c2f11000700000000000000000000000000000000000000000000000000000000000000e88c1100e8c410000000000000000000d0c4100001000000000000000100000000000000d8c410000e00000000000000000000007c2f11000700000000000000000000000000000000000000000000000000000000000000e88c1100e8c410000000000000000000f8c410000100000000000000010000000000000000c5100006000000000000000000000006c510000b00000000000000000000000000000000000000000000000000000000000000e88c110014c51000000000000000000024c51000010000000000000001000000000000002cc5100006000000000000000000000032c510002300000000000000000000000000000000000000000000000000000000000000e88c110058c51000000000000000000068c510000100000000000000010000000000000070c510000a00000000000000000000007ac510000a00000000000000000000000000000000000000000000000000000000000000e88c110084c51000000000000000000094c51000010000000000000001000000000000009cc510000b0000000201010000000000a7c5100002000000000000007c2f11000700000000000000a9c510002100000000000000e88c1100ccc510000000000000000000dcc510000d00000000000000010000004163636f756e744e6f6e6365543a3a496e64657889cc10001f00000045787472696e736963436f756e7400005bcc10002e000000416c6c45787472696e7369637357656967687457656967687400000016cc100045000000416c6c45787472696e736963734c656e32000000000000000100000040000000c6cb1000500000004e6578745765696768744d756c7469706c6965725765696768744d756c7469706c6965723200000000000000010000004600000052cb100059000000abcb10001b000000426c6f636b486173680000002ccb10002600000045787472696e736963446174610000003200000000000000010000009c000000ddca10004f00000052616e646f6d4d6174657269616c2869382c205665633c543a3a486173683e29320000000000000001000000a500000020ca10006900000089ca1000540000004e756d6265720000dec9100042000000506172656e74486173680000c2c910001c00000045787472696e73696373526f6f740000320000000000000001000000a60000007dc91000450000004469676573744469676573744f663c543e0000003200000000000000010000004200000041c910003c0000004576656e74735665633c4576656e745265636f72643c543a3a4576656e742c20543a3a486173683e3e0000003200000000000000010000004200000019c91000280000004576656e74436f756e744576656e74496e64657832000000000000000100000049000000ebc810002e0000004576656e74546f7069637328295665633c28543a3a426c6f636b4e756d6265722c204576656e74496e646578293e00003200000000000000010000004200000044c61000490000008dc61000250000004876110000000000b2c610004b000000fdc610002a000000487611000000000027c71000540000007bc7100051000000ccc7100039000000487611000000000005c810005300000058c8100053000000abc8100040000000204d617070696e67206265747765656e206120746f7069632028726570726573656e74656420627920543a3a486173682920616e64206120766563746f72206f6620696e6465786573206f66206576656e747320696e2074686520603c4576656e74733c543e3e60206c6973742e20546865206669727374206b657920736572766573206e6f20707572706f73652e2054686973206669656c64206973206465636c6172656420617320646f75626c655f6d6170206a75737420666f7220636f6e76656e69656e6365206f66207573696e67206072656d6f76655f707265666978602e20416c6c20746f70696320766563746f727320686176652064657465726d696e69737469632073746f72616765206c6f636174696f6e7320646570656e64696e67206f6e2074686520746f7069632e205468697320616c6c6f7773206c696768742d636c69656e747320746f206c6576657261676520746865206368616e67657320747269652073746f7261676520747261636b696e67206d656368616e69736d20616e6420696e2063617365206f66206368616e67657320666574636820746865206c697374206f66206576656e7473206f6620696e7465726573742e205468652076616c756520686173207468652074797065206028543a3a426c6f636b4e756d6265722c204576656e74496e646578296020626563617573652069662077652075736564206f6e6c79206a7573742074686520604576656e74496e64657860207468656e20696e20636173652069662074686520746f70696320686173207468652073616d6520636f6e74656e7473206f6e20746865206e65787420626c6f636b206e6f206e6f74696669636174696f6e2077696c6c20626520747269676765726564207468757320746865206576656e74206d69676874206265206c6f73742e20546865206e756d626572206f66206576656e747320696e2074686520604576656e74733c543e60206c6973742e204576656e7473206465706f736974656420666f72207468652063757272656e7420626c6f636b2e20446967657374206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2045787472696e7369637320726f6f74206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2048617368206f66207468652070726576696f757320626c6f636b2e205468652063757272656e7420626c6f636b206e756d626572206265696e672070726f6365737365642e205365742062792060657865637574655f626c6f636b602e20536572696573206f6620626c6f636b20686561646572732066726f6d20746865206c61737420383120626c6f636b73207468617420616374732061732072616e646f6d2073656564206d6174657269616c2e205468697320697320617272616e67656420617320612072696e6720627566666572207769746820746865206069386020707265666978206265696e672074686520696e64657820696e746f20746865206056656360206f6620746865206f6c6465737420686173682e2045787472696e73696373206461746120666f72207468652063757272656e7420626c6f636b20286d61707320616e2065787472696e736963277320696e64657820746f206974732064617461292e204d6170206f6620626c6f636b206e756d6265727320746f20626c6f636b206861736865732e20546865206e65787420776569676874206d756c7469706c6965722e20546869732073686f756c6420626520757064617465642061742074686520656e64206f66206561636820626c6f636b206261736564206f6e207468652073617475726174696f6e206c6576656c2028776569676874292e20546f74616c206c656e6774682028696e2062797465732920666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e20546f74616c2077656967687420666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e20546f74616c2065787472696e7369637320636f756e7420666f72207468652063757272656e7420626c6f636b2e2045787472696e73696373206e6f6e636520666f72206163636f756e74732ec0b8100019000000c0cc100047000000e20000000a0000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f7374616b696e672f7372632f70687261676d656e2e72736d656d6f727976616c69646174696f6e3a20696d706f727420656e74727920706f696e747320746f2061206e6f6e2d6578697374656e74207479706543616e6e6f7420696d706f727420676c6f62616c736d6f64756c6520696d706f7274732061206e6f6e2d6578697374656e742066756e6374696f6e6d6f64756c6520696d706f72747320606578745f7072696e746c6e60206275742064656275672066656174757265732064697361626c656443616e6e6f7420696d706f7274207461626c65736d6f64756c652068617320696d706f7274732066726f6d2061206e6f6e2d27656e7627206e616d6573706163654d756c7469706c65206d656d6f727920696d706f72747320646566696e65644d656d6f727920696d706f7274206d757374206861766520746865206669656c64206e616d6520276d656d6f7279274d6178696d756d206e756d626572206f662070616765732073686f756c6420626520616c77617973206465636c617265642e52657175657374656420696e697469616c206e756d626572206f662070616765732073686f756c64206e6f74206578636565642074686520726571756573746564206d6178696d756d4d6178696d756d206e756d626572206f662070616765732073686f756c64206e6f74206578636565642074686520636f6e66696775726564206d6178696d756d2e000000f0ba100048000000900a00000a0000002cba100041000000e3000000010000003a6865617070616765733a636f646500000000003cd01000080000000000000044d010000300000000000000000000005cd0100001000000000000000000000064d010000c000000000000009423110002000000000000000000000070d0100001000000000000000000000078d010000a0000000000000084d010000100000000000000000000008cd0100001000000000000000000000094d010000f00000000000000a4d01000010000000000000000000000acd01000010000000000000000000000b4d010000a00000000000000c0d01000020000000000000000000000d0d01000020000000000000000000000e0d010000800000000000000e8d01000020000000000000000000000f8d0100001000000000000005472616e73666572d823110009000000d82311000900000019241100070000002ad2100055000000496e7374616e746961746564f3d1100037000000436f646553746f7265640000e123110004000000c5d110002e0000005363686564756c6555706461746564009ef310000300000095d1100030000000446973706174636865640000d823110009000000ff231100040000002ad110004e00000078d110001d000000436f6e7472616374d82311000900000023d110000700000000d110002300000020416e206576656e742066726f6d20636f6e7472616374206f66206163636f756e742e5665633c75383e20412063616c6c2077617320646973706174636865642066726f6d2074686520676976656e206163636f756e742e2054686520626f6f6c207369676e616c73207768657468657220697420776173207375636365737366756c20657865637574696f6e206f72206e6f742e20547269676765726564207768656e207468652063757272656e74207363686564756c6520697320757064617465642e20436f646520776974682074686520737065636966696564206861736820686173206265656e2073746f7265642e20436f6e7472616374206465706c6f7965642062792061646472657373206174207468652073706563696669656420616464726573732e205472616e736665722068617070656e6564206066726f6d6020746f2060746f60207769746820676976656e206076616c7565602061732070617274206f662061206063616c6c60206f722060637265617465602e64656661756c743a436f6e7472616374205072697374696e65436f6465436f6e747261637420436f646553746f72616765436f6e747261637420436f6e7472616374496e666f4f6600e0d210001900000000d3100048000000bb0100002d000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f6f70732f61726974682e7273707265636f6e646974696f6e3a20616c6c20696d706f7274732073686f756c6420626520636865636b656420616761696e737420746865207369676e617475726573206f6620636f72726573706f6e64696e670a09090909090966756e6374696f6e7320646566696e65642062792060646566696e655f656e762160206d6163726f206279207468652075736572206f6620746865206d6163726f3b0a0909090909097369676e617475726573206f662074686573652066756e6374696f6e7320646566696e6564206279206024706172616d73603b0a09090909090963616c6c7320616c77617973206d616465207769746820617267756d656e7473207479706573206f662077686963682061726520646566696e65642062792074686520636f72726573706f6e64696e6720696d706f7274733b0a09090909090974687573207479706573206f6620617267756d656e74732073686f756c6420626520657175616c20746f2074797065206c69737420696e206024706172616d736020616e640a0909090909096c656e677468206f6620617267756d656e74206c69737420616e642024706172616d732073686f756c6420626520657175616c3b0a0909090909097468757320746869732063616e206e6576657220626520604e6f6e65603b0a0909090909097165643b0a0909090909090000000018d610000f0000000000000028d6100001000000000000000000000040d6100003000000000000000000000058d61000080000000000000060d6100002000000000000000000000090d610000200000000000000000000002d5211000400000000000000a0d6100004000000000000000000000000d7100007000000000000000000000038d71000060000000000000040d71000040000000000000000000000a0d710000a0000000000000000000000f0d710000f0000000000000000d8100002000000000000000000000030d8100005000000000000007570646174655f7363686564756c65000000000076de100008000000000000007ede10000800000006de10002d000000487611000000000033de1000430000007075745f636f646500000000b4db10000900000000000000bddb10000c0000000000000002de1000040000000000000023d110000700000076dd100057000000cddd1000350000000000000072d910000400000000000000a7ff100023000000000000005f3511000500000000000000643511001500000000000000b4db10000900000000000000bddb10000c00000000000000dddb1000040000000000000023d1100007000000e1db100042000000487611000000000023dc10004a0000006ddc10002c00000099dc100046000000dfdc10005200000031dd100045000000637265617465000000000000abdb10000900000000000000643511001500000000000000b4db10000900000000000000bddb10000c00000000000000c9db10000900000000000000d2db10000b00000000000000dddb1000040000000000000023d110000700000094d910006a0000004876110000000000fed910002100000048761100000000001fda1000500000006fda100041000000b0da10005b0000000bdb10005700000062db10002a0000008cdb10001f000000636c61696d5f737572636861726765000000000072d9100004000000000000000b2e11000c0000000000000076d910000a0000000000000080d910001400000058d810005c000000b4d81000450000004876110000000000f9d810004e00000047d910002b00000020416c6c6f777320626c6f636b2070726f64756365727320746f20636c61696d206120736d616c6c2072657761726420666f72206576696374696e67206120636f6e74726163742e204966206120626c6f636b2070726f6475636572206661696c7320746f20646f20736f2c206120726567756c61722075736572732077696c6c20626520616c6c6f77656420746f20636c61696d20746865207265776172642e20496620636f6e7472616374206973206e6f742065766963746564206173206120726573756c74206f6620746869732063616c6c2c206e6f20616374696f6e73206172652074616b656e20616e64207468652073656e646572206973206e6f7420656c696769626c6520666f7220746865207265776172642e646573746175785f73656e6465724f7074696f6e3c543a3a4163636f756e7449643e20437265617465732061206e657720636f6e74726163742066726f6d207468652060636f646568617368602067656e65726174656420627920607075745f636f6465602c206f7074696f6e616c6c79207472616e7366657272696e6720736f6d652062616c616e63652e204372656174696f6e20697320657865637574656420617320666f6c6c6f77733a202d205468652064657374696e6174696f6e206164647265737320697320636f6d7075746564206261736564206f6e207468652073656e64657220616e642068617368206f662074686520636f64652e202d2054686520736d6172742d636f6e7472616374206163636f756e7420697320637265617465642061742074686520636f6d707574656420616464726573732e202d20546865206063746f725f636f64656020697320657865637574656420696e2074686520636f6e74657874206f6620746865206e65776c792d63726561746564206163636f756e742e204275666665722072657475726e656420202061667465722074686520657865637574696f6e206973207361766564206173207468652060636f646560206f6620746865206163636f756e742e205468617420636f64652077696c6c20626520696e766f6b656420202075706f6e20616e792063616c6c2072656365697665642062792074686973206163636f756e742e202d2054686520636f6e747261637420697320696e697469616c697a65642e656e646f776d656e746761735f6c696d6974436f6d706163743c4761733e636f64655f68617368436f6465486173683c543e64617461204d616b657320612063616c6c20746f20616e206163636f756e742c206f7074696f6e616c6c79207472616e7366657272696e6720736f6d652062616c616e63652e202a20496620746865206163636f756e74206973206120736d6172742d636f6e7472616374206163636f756e742c20746865206173736f63696174656420636f64652077696c6c20626520657865637574656420616e6420616e792076616c75652077696c6c206265207472616e736665727265642e202a20496620746865206163636f756e74206973206120726567756c6172206163636f756e742c20616e792076616c75652077696c6c206265207472616e736665727265642e202a204966206e6f206163636f756e742065786973747320616e64207468652063616c6c2076616c7565206973206e6f74206c657373207468616e20606578697374656e7469616c5f6465706f736974602c206120726567756c6172206163636f756e742077696c6c206265206372656174656420616e6420616e792076616c75652077696c6c206265207472616e736665727265642e2053746f7265732074686520676976656e2062696e617279205761736d20636f646520696e746f2074686520636861696e27732073746f7261676520616e642072657475726e73206974732060636f646568617368602e20596f752063616e20696e7374616e746961746520636f6e747261637473206f6e6c7920776974682073746f72656420636f64652e636f6465205570646174657320746865207363686564756c6520666f72206d65746572696e6720636f6e7472616374732e20546865207363686564756c65206d7573742068617665206120677265617465722076657273696f6e207468616e207468652073746f726564207363686564756c652e7363686564756c655363686564756c65000000000000f0e01000080000000000000000000000f8e010000300000000000000000000000000000000000000000000000000000000000000e88c1100a0e110000000000000000000fce010000100000000000000010000000000000004e110000f00000000000000000000007ede10000800000000000000000000000000000000000000000000000000000000000000e88c110014e11000000000000000000024e11000010000000000000001000000000000002ce110000c0000000101000000000000d2db10000b0000000000000023d110000700000000000000000000000000000000000000e88c110038e11000000000000000000048e110000100000000000000000000000000000050e110000b0000000101000000000000d2db10000b000000000000005be110001600000000000000000000000000000000000000e88c110074e11000000000000000000084e11000010000000000000000000000000000008ce110000e00000000000000000000009ae110000300000000000000000000000000000000000000000000000000000000000000e88c1100a0e110000000000000000000b0e1100001000000000000000100000000000000b8e110000e00000001010000000000000b2e11000c00000000000000c6e110000f00000000000000000000000000000000000000e88c1100d8e110000000000000000000e8e1100001000000000000000000000000000000f0e110000800000000000000000000007a4511000c00000000000000000000000000000000000000000000000000000000000000e88c1100f8e11000000000000000000008e210000100000000000000010000004761735370656e744761730044e310002000000043757272656e745363686564756c6500320000000000000001000000a70000001fe31000250000005072697374696e65436f646532000000000000000100000040000000c6e2100059000000436f646553746f726167657761736d3a3a5072656661625761736d4d6f64756c65000000320000000000000001000000400000006de21000590000004163636f756e74436f756e7465727536340000003200000000000000010000004600000058e2100015000000436f6e7472616374496e666f4f66436f6e7472616374496e666f3c543e000000320000000000000001000000400000002ee210002a0000004761735072696365320000000000000001000000a800000010e210001e00000020546865207072696365206f66206f6e6520756e6974206f66206761732e2054686520636f6465206173736f6369617465642077697468206120676976656e206163636f756e742e20546865207375627472696520636f756e7465722e2041206d617070696e67206265747765656e20616e206f726967696e616c20636f6465206861736820616e6420696e737472756d656e746564207761736d20636f64652c20726561647920666f7220657865637574696f6e2e2041206d617070696e672066726f6d20616e206f726967696e616c20636f6465206861736820746f20746865206f726967696e616c20636f64652c20756e746f756368656420627920696e737472756d656e746174696f6e2e2043757272656e7420636f7374207363686564756c6520666f7220636f6e7472616374732e20476173207370656e7420736f2066617220696e207468697320626c6f636b2e00000000e4e610001300000000000000923111000e00000000000000e88c1100f8e61000000000000000000008e7100004000000000000000000000028e7100010000000000000007a4511000c00000000000000e88c110038e71000000000000000000048e7100001000000000000000000000050e7100011000000000000009ef310000300000000000000e88c110064e71000000000000000000074e7100002000000000000000000000084e710000b000000000000007a4511000c00000000000000e88c110090e710000000000000000000a0e71000010000000000000000000000a8e7100011000000000000007a4511000c00000000000000e88c1100bce710000000000000000000cce7100007000000000000000000000004e810000f000000000000007a4511000c00000000000000e88c110014e81000000000000000000024e8100002000000000000000000000034e810000b000000000000007a4511000c00000000000000e88c1100b0e81000000000000000000040e8100001000000000000000000000048e810000b000000000000007a4511000c00000000000000e88c1100b0e81000000000000000000054e810000100000000000000000000005ce8100012000000000000007a4511000c00000000000000e88c1100b0e81000000000000000000070e8100001000000000000000000000078e8100012000000000000007a4511000c00000000000000e88c11008ce8100000000000000000009ce81000010000000000000000000000a4e810000b000000000000007a4511000c00000000000000e88c1100b0e810000000000000000000c0e81000020000000000000000000000d0e810000b00000000000000f8e010000300000000000000e88c1100fce810000000000000000000dce81000020000000000000000000000ece810000d00000000000000f8e010000300000000000000e88c1100fce8100000000000000000000ce910000200000000000000000000001ce9100008000000000000009ef310000300000000000000e88c110024e91000000000000000000034e9100002000000000000000000000044e910000c000000000000009ef310000300000000000000e88c110050e91000000000000000000060e9100001000000000000000000000068e910000d00000000000000f8e010000300000000000000e88c110078e91000000000000000000088e9100002000000000000005369676e6564436c61696d48616e646963617000320000000000000001000000a900000025ef10003800000048761100000000005def100043000000a0ef10001a000000546f6d6273746f6e654465706f736974320000000000000001000000aa000000f0ee10003500000053746f7261676553697a654f66667365740000003200000000000000010000005d00000077ee10004b000000c2ee10002e00000052656e744279746546656500320000000000000001000000ab0000002aee10004d00000052656e744465706f7369744f6666736574000000320000000000000001000000ac000000b2ec100041000000f3ec100016000000487611000000000009ed10005a00000063ed100056000000b9ed1000530000000cee10001e00000053757263686172676552657761726400320000000000000001000000ad0000005fec10003900000098ec10001a0000005472616e73666572466565003aec1000250000004372656174696f6e4665650013ec1000270000005472616e73616374696f6e426173654665650000dceb1000370000005472616e73616374696f6e4279746546656500003200000000000000010000004500000099eb100043000000436f6e7472616374466565003200000000000000010000004400000047eb10004b00000092eb10000700000043616c6c4261736546656500f2ea10004700000039eb10000e00000043726561746542617365466565000000320000000000000001000000ae000000a1ea100049000000eaea1000080000004d61784465707468320000000000000001000000af0000004cea10004700000093ea10000e0000004d617856616c756553697a65320000000000000001000000b0000000fee910004e000000426c6f636b4761734c696d6974000000320000000000000001000000b100000098e9100049000000e1e910001d00000020546865206d6178696d756d20616d6f756e74206f6620676173207468617420636f756c6420626520657870656e6465642070657220626c6f636b2e204120726561736f6e61626c652064656661756c742076616c75652069732031305f3030305f3030302e20546865206d6178696d756d2073697a65206f6620612073746f726167652076616c756520696e2062797465732e204120726561736f6e61626c652064656661756c74206973203136204b69422e20546865206d6178696d756d206e657374696e67206c6576656c206f6620612063616c6c2f63726561746520737461636b2e204120726561736f6e61626c652064656661756c742076616c7565206973203130302e20546865206261736520666565206368617267656420666f72206372656174696e67206120636f6e74726163742e204120726561736f6e61626c652064656661756c742076616c7565206973203137352e20546865206261736520666565206368617267656420666f722063616c6c696e6720696e746f206120636f6e74726163742e204120726561736f6e61626c652064656661756c742076616c7565206973203133352e205468652066656520726571756972656420746f20637265617465206120636f6e747261637420696e7374616e63652e204120726561736f6e61626c652064656661756c742076616c75652069732032312e205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b20746865207065722d6279746520706f7274696f6e2e205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b2074686520626173652e205468652066656520726571756972656420746f2063726561746520616e206163636f756e742e205468652066656520726571756972656420746f206d616b652061207472616e736665722e205265776172642074686174206973207265636569766564206279207468652070617274792077686f736520746f75636820686173206c656420746f2072656d6f76616c206f66206120636f6e74726163742e2054686520616d6f756e74206f662066756e6473206120636f6e74726163742073686f756c64206465706f73697420696e206f7264657220746f206f66667365742074686520636f7374206f66206f6e6520627974652e204c6574277320737570706f736520746865206465706f73697420697320312c303030204255202862616c616e636520756e697473292f6279746520616e64207468652072656e7420697320312042552f627974652f6461792c207468656e206120636f6e7472616374207769746820312c3030302c3030302042552074686174207573657320312c303030206279746573206f662073746f7261676520776f756c6420706179206e6f2072656e742e20427574206966207468652062616c616e6365207265647563656420746f203530302c30303020425520616e64207468652073746f7261676520737461796564207468652073616d6520617420312c3030302c207468656e20697420776f756c6420706179203530302042552f6461792e205072696365206f6620612062797465206f662073746f7261676520706572206f6e6520626c6f636b20696e74657276616c2e2053686f756c642062652067726561746572207468616e20302e2053697a65206f66206120636f6e7472616374206174207468652074696d65206f66206372656174696f6e2e205468697320697320612073696d706c652077617920746f20656e73757265207468617420656d70747920636f6e747261637473206576656e7475616c6c7920676574732064656c657465642e20546865206d696e696d756d20616d6f756e7420726571756972656420746f2067656e6572617465206120746f6d6273746f6e652e204e756d626572206f6620626c6f636b2064656c617920616e2065787472696e73696320636c61696d20737572636861726765206861732e205768656e20636c61696d207375726368617267652069732063616c6c656420627920616e2065787472696e736963207468652072656e7420697320636865636b656420666f722063757272656e745f626c6f636b202d2064656c617972657475726e2074797065206572726f7276616c69646174696f6e206572726f72647572696e6720657865637574696f6e70726576696f75732f6e657874206f6e6c7920636f6e7461696e206578697374696e6720656e74697265733b20776520656e756d6572617465207573696e67206e6578743b20656e747279206578697374733b207165640000946a1100280000005cf0100044000000b7010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6e7472616374732f7372632f6c69622e72735cf0100044000000b7010000010000006e6577207363686564756c65206d7573742068617665206120677265617465722076657273696f6e207468616e2063757272656e74496e76616c69642073757263686172676520636c61696d3a206f726967696e206d757374206265207369676e6564206f7220696e686572656e7420616e6420617578696c696172792073656e646572206f6e6c792070726f7669646564206f6e20696e686572656e7443616e6e6f7420726573746f726520746f20696e6578697374696e67206f7220616c69766520636f6e7472616374436f6e7472616374204761735072696365626c6f636b2073697a65206c696d697420697320726561636865646f766572666c6f77206d756c7469706c79696e6720676173206c696d6974206279207072696365000000000054f2100006000000000000005cf2100001000000000000000000000064f210000100000000000000000000006cf210000e000000000000007cf210000200000000000000000000008cf210000200000000000000000000009cf210000c00000000000000a8f21000020000000000000000000000b8f21000010000000000000052657761726400001924110007000000a1f31000380000004f66666c696e655761726e696e670000d8231100090000009ef310000300000009f31000520000005bf31000430000004f66666c696e65536c617368d8231100090000001924110007000000c0f2100049000000204f6e652076616c696461746f722028616e6420697473206e6f6d696e61746f72732920686173206265656e20736c61736865642062792074686520676976656e20616d6f756e742e204f6e652076616c696461746f722028616e6420697473206e6f6d696e61746f72732920686173206265656e20676976656e20616e206f66666c696e652d7761726e696e6720286974206973207374696c6c2077697468696e20697473206772616365292e205468652061636372756564206e756d626572206f6620736c6173686573206973207265636f726465642c20746f6f2e75333220416c6c2076616c696461746f72732068617665206265656e2072657761726465642062792074686520676976656e2062616c616e63652e5374616b696e6720426f6e6465645374616b696e672043757272656e7445726153746172745374616b696e67204e6f6d696e61746f72735374616b696e672056616c696461746f72735374616b696e67205374616b6572735374616b696e67204c65646765725374616b696e672050617965655374616b696e6720536c617368436f756e7468656164206f66205374616b696e67204e6f6d696e61746f727368656164206f66205374616b696e672056616c696461746f72735374616b696e672043757272656e74456c65637465640000000010f71000040000000000000014f710000300000000000000000000005cf710000f0000000000000000000000d4f710000a00000000000000e0f71000010000000000000000000000f8f710000e000000000000000000000068f81000060000000000000070f8100001000000000000000000000088f8100017000000000000000000000040f9100011000000000000004876110000000000000000000000000054f91000100000000000000000000000d4f910000800000000000000dcf91000010000000000000000000000f4f910000b00000000000000000000004cfa1000080000000000000054fa10000100000000000000000000006cfa10000b0000000000000000000000c4fa1000050000000000000048761100000000000000000000000000ccfa10000b000000000000000000000024fb1000090000000000000030fb100001000000000000000000000048fb10000b0000000000000000000000a0fb10000e00000000000000b0fb1000010000000000000000000000c8fb10000b000000000000000000000020fc1000130000000000000034fc10000100000000000000000000004cfc100001000000000000000000000054fc10000d000000000000004876110000000000000000000000000064fc10000500000000000000000000008cfc10000d00000000000000487611000000000000000000000000009cfc1000060000000000000000000000ccfc1000170000000000000034fc1000010000000000000000000000e4fc1000010000000000000000000000ecfc1000110000000000000000fd100001000000000000000000000018fd10000100000000000000626f6e64000000009dff10000a00000000000000a7ff100023000000000000005f35110005000000000000006435110015000000000000004d00110005000000000000005200110011000000370911005900000090091100210000004876110000000000b1091100540000004876110000000000050a1100490000004876110000000000c52d11000b0000004e0a110035000000d02d110008000000830a11001a00000048761100000000009d0a11005b000000f80a110049000000d82d11000c000000626f6e645f6578747261000000000000290911000e00000000000000643511001500000003081100590000005c0811000d00000048761100000000006908110054000000bd0811005900000016091100130000004876110000000000b6fe1000550000004876110000000000c52d11000b0000000bff10003a000000d02d1100080000001d35110010000000d82d11000c000000756e626f6e640000000000005f3511000500000000000000643511001500000024041100550000007904110040000000b90411004d0000004876110000000000060511005200000058051100300000004876110000000000880511004f000000d70511004f000000260611003f0000004876110000000000f8ff100055000000487611000000000065061100260000004876110000000000c52d11000b0000008b0611005000000045ff100026000000db06110059000000340711005c00000090071100690000001d35110010000000f90711000a00000077697468647261775f756e626f6e6465640000001d0211004b0000004876110000000000680211004d000000b5021100130000004876110000000000f8ff1000550000004876110000000000c80211001b0000004876110000000000c52d11000b000000e3021100550000003803110051000000890311003d000000c60311005e0000006bff100032000000d82d11000c00000076616c696461746500000000fc0111000500000000000000010211001c000000c20111003a00000048761100000000007ffe1000370000004876110000000000f8ff1000550000004876110000000000c52d11000b0000000bff10003a00000045ff1000260000006bff100032000000d82d11000c0000006e6f6d696e617465000000009301110007000000000000009a01110028000000aa0011004400000048761100000000007ffe1000370000004876110000000000f8ff1000550000004876110000000000c52d11000b000000ee0011004900000037011100260000005d01110036000000d82d11000c0000006368696c6c000000630011003200000048761100000000007ffe1000370000004876110000000000f8ff1000550000004876110000000000c52d11000b0000000bff10003a00000095001100150000006bff100032000000d82d11000c0000007365745f7061796565000000000000004d00110005000000000000005200110011000000caff10002e00000048761100000000007ffe1000370000004876110000000000f8ff1000550000004876110000000000c52d11000b0000000bff10003a00000045ff1000260000006bff100032000000d82d11000c0000007365745f636f6e74726f6c6c65720000000000009dff10000a00000000000000a7ff1000230000005bfe10002400000048761100000000007ffe1000370000004876110000000000b6fe1000550000004876110000000000c52d11000b0000000bff10003a00000045ff1000260000006bff100032000000d82d11000c0000007365745f76616c696461746f725f636f756e74000000000058fe10000300000000000000fa2e11000c00000038fe100020000000666f7263655f6e6f5f657261730000000cfe10002c0000004876110000000000c52d11000b000000fcfd100010000000d82d11000c000000666f7263655f6e65775f65726100000081fd100053000000d4fd1000280000004876110000000000c52d11000b000000fcfd100010000000d82d11000c0000007365745f6f66666c696e655f736c6173685f6772616365005dfd1000240000007365745f696e76756c6e657261626c65730000000000000053fd10000a00000000000000253c11001100000020fd10003300000020536574207468652076616c696461746f72732077686f2063616e6e6f7420626520736c61736865642028696620616e79292e76616c696461746f72732053657420746865206f66666c696e6520736c61736820677261636520706572696f642e20466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f6620746865206e6578742073657373696f6e2e20416674657220746869732c2069742077696c6c20626520726573657420746f206e6f726d616c20286e6f6e2d666f7263656429206265686176696f75722e202d204e6f20617267756d656e74732e20466f72636520746865726520746f206265206e6f206e6577206572617320696e646566696e6974656c792e2054686520696465616c206e756d626572206f662076616c696461746f72732e6e6577202852652d297365742074686520636f6e74726f6c6c6572206f6620612073746173682e20456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c65722e202d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732e202d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e636f6e74726f6c6c65723c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f75726365202852652d2973657420746865207061796d656e742074617267657420666f72206120636f6e74726f6c6c65722e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e706179656552657761726444657374696e6174696f6e204465636c617265206e6f2064657369726520746f206569746865722076616c6964617465206f72206e6f6d696e6174652e202d20436f6e7461696e73206f6e6520726561642e204465636c617265207468652064657369726520746f206e6f6d696e6174652060746172676574736020666f7220746865206f726967696e20636f6e74726f6c6c65722e202d20546865207472616e73616374696f6e277320636f6d706c65786974792069732070726f706f7274696f6e616c20746f207468652073697a65206f66206074617267657473602c2077686963682069732063617070656420617420604d41585f4e4f4d494e4154494f4e53602e202d20426f74682074686520726561647320616e642077726974657320666f6c6c6f7720612073696d696c6172207061747465726e2e746172676574735665633c3c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263653e204465636c617265207468652064657369726520746f2076616c696461746520666f7220746865206f726967696e20636f6e74726f6c6c65722e707265667356616c696461746f7250726566733c42616c616e63654f663c543e3e2052656d6f766520616e7920756e6c6f636b6564206368756e6b732066726f6d207468652060756e6c6f636b696e67602071756575652066726f6d206f7572206d616e6167656d656e742e205468697320657373656e7469616c6c7920667265657320757020746861742062616c616e636520746f206265207573656420627920746865207374617368206163636f756e7420746f20646f2077686174657665722069742077616e74732e2053656520616c736f205b6043616c6c3a3a756e626f6e64605d2e202d20436f756c6420626520646570656e64656e74206f6e2074686520606f726967696e6020617267756d656e7420616e6420686f77206d7563682060756e6c6f636b696e6760206368756e6b732065786973742e2020497420696d706c6965732060636f6e736f6c69646174655f756e6c6f636b656460207768696368206c6f6f7073206f76657220604c65646765722e756e6c6f636b696e67602c2077686963682069732020696e6469726563746c7920757365722d636f6e74726f6c6c65642e20536565205b60756e626f6e64605d20666f72206d6f72652064657461696c2e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732c20796574207468652073697a65206f6620776869636820636f756c64206265206c61726765206261736564206f6e20606c6564676572602e205363686564756c65206120706f7274696f6e206f662074686520737461736820746f20626520756e6c6f636b656420726561647920666f72207472616e73666572206f75742061667465722074686520626f6e6420706572696f6420656e64732e2049662074686973206c656176657320616e20616d6f756e74206163746976656c7920626f6e646564206c657373207468616e20543a3a43757272656e63793a3a6578697374656e7469616c5f6465706f73697428292c207468656e20697420697320696e6372656173656420746f207468652066756c6c20616d6f756e742e204f6e63652074686520756e6c6f636b20706572696f6420697320646f6e652c20796f752063616e2063616c6c206077697468647261775f756e626f6e6465646020746f2061637475616c6c79206d6f7665207468652066756e6473206f7574206f66206d616e6167656d656e7420726561647920666f72207472616e736665722e204e6f206d6f7265207468616e2061206c696d69746564206e756d626572206f6620756e6c6f636b696e67206368756e6b73202873656520604d41585f554e4c4f434b494e475f4348554e4b5360292063616e20636f2d657869737473206174207468652073616d652074696d652e20496e207468617420636173652c205b6043616c6c3a3a77697468647261775f756e626f6e646564605d206e65656420746f2062652063616c6c656420666972737420746f2072656d6f766520736f6d65206f6620746865206368756e6b732028696620706f737369626c65292e2053656520616c736f205b6043616c6c3a3a77697468647261775f756e626f6e646564605d2e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204c696d697465642062757420706f74656e7469616c6c79206578706c6f697461626c6520636f6d706c65786974792e202d20456163682063616c6c20287265717569726573207468652072656d61696e646572206f662074686520626f6e6465642062616c616e636520746f2062652061626f766520606d696e696d756d5f62616c616e6365602920202077696c6c2063617573652061206e657720656e74727920746f20626520696e73657274656420696e746f206120766563746f722028604c65646765722e756e6c6f636b696e676029206b65707420696e2073746f726167652e202020546865206f6e6c792077617920746f20636c65616e207468652061666f72656d656e74696f6e65642073746f72616765206974656d20697320616c736f20757365722d636f6e74726f6c6c656420766961206077697468647261775f756e626f6e646564602e203c2f7765696768743e2041646420736f6d6520657874726120616d6f756e742074686174206861766520617070656172656420696e207468652073746173682060667265655f62616c616e63656020696e746f207468652062616c616e636520757020666f72207374616b696e672e20557365207468697320696620746865726520617265206164646974696f6e616c2066756e647320696e20796f7572207374617368206163636f756e74207468617420796f75207769736820746f20626f6e642e20556e6c696b65205b60626f6e64605d206f72205b60756e626f6e64605d20746869732066756e6374696f6e20646f6573206e6f7420696d706f736520616e79206c696d69746174696f6e206f6e2074686520616d6f756e7420746861742063616e2062652061646465642e6d61785f6164646974696f6e616c2054616b6520746865206f726967696e206163636f756e74206173206120737461736820616e64206c6f636b207570206076616c756560206f66206974732062616c616e63652e2060636f6e74726f6c6c6572602077696c6c20626520746865206163636f756e74207468617420636f6e74726f6c732069742e206076616c756560206d757374206265206d6f7265207468616e2074686520606578697374656e7469616c5f6465706f7369746020646566696e656420696e207468652042616c616e636573206d6f64756c652e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20627920746865207374617368206163636f756e742e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204d6f64657261746520636f6d706c65786974792e202d20546872656520657874726120444220656e74726965732e204e4f54453a2054776f206f66207468652073746f726167652077726974657320286053656c663a3a626f6e646564602c206053656c663a3a7061796565602920617265205f6e657665725f20636c65616e656420756e6c6573732074686520606f726967696e602066616c6c732062656c6f77205f6578697374656e7469616c206465706f7369745f20616e6420676574732072656d6f76656420617320647573742e5374616b696e6700000000801211000e00000000000000000000009ef310000300000000000000000000000000000000000000000000000000000000000000e88c11003815110000000000000000009012110001000000000000000100000000000000981211001500000000000000000000009ef310000300000000000000000000000000000000000000000000000000000000000000e88c1100b01211000000000000000000c0121100010000000000000001000000000000009cf210000c0000000000000000000000c81211000700000000000000000000000000000000000000000000000000000000000000e88c1100d01211000000000000000000e012110001000000000000000100000000000000e81211001100000000000000000000009ef310000300000000000000000000000000000000000000000000000000000000000000e88c1100381511000000000000000000fc12110001000000000000000100000000000000041311000d0000000000000000000000253c11001100000000000000000000000000000000000000000000000000000000000000e88c1100f0151100000000000000000014131100030000000000000001000000000000002c1311000600000001010000000000000b2e11000c000000000000000b2e11000c00000000000000000000000000000000000000e88c11006c131100000000000000000034131100010000000000000000000000000000003c1311000600000001010000000000000b2e11000c00000000000000421311002900000000000000000000000000000000000000e88c11006c13110000000000000000007c13110001000000000000000000000000000000841311000500000001010000000000000b2e11000c00000000000000520011001100000000000000000000000000000000000000e88c11008c13110000000000000000009c13110001000000000000000100000000000000a41311000a00000001010100000000000b2e11000c00000000000000010211001c00000000000000000000000000000000000000e88c1100b01311000000000000000000c013110001000000000000000100000000000000c81311000a00000001010100000000000b2e11000c00000000000000253c11001100000000000000000000000000000000000000e88c1100f01511000000000000000000d413110001000000000000000100000000000000dc1311000700000001010000000000000b2e11000c00000000000000e31311002400000000000000000000000000000000000000e88c11000814110000000000000000001814110004000000000000000100000000000000381411000e0000000000000000000000253c11001100000000000000000000000000000000000000000000000000000000000000e88c1100f015110000000000000000004814110001000000000000000100000000000000501411000a00000000000000000000005a1411000800000000000000000000000000000000000000000000000000000000000000e88c110038151100000000000000000064141100010000000000000001000000000000006c1411000f00000000000000000000007b1411000b00000000000000000000000000000000000000000000000000000000000000e88c11008814110000000000000000009814110001000000000000000100000000000000a01411001b0000000000000000000000b77011000c00000000000000000000000000000000000000000000000000000000000000e88c1100381511000000000000000000bc14110001000000000000000100000000000000c4141100110000000000000000000000d51411000a00000000000000000000000000000000000000000000000000000000000000e88c1100e01411000000000000000000f014110001000000000000000100000000000000f81411000900000000000000000000007a4511000c00000000000000000000000000000000000000000000000000000000000000e88c110004151100000000000000000014151100030000000000000001000000000000002c1511000a00000001010000000000000b2e11000c000000000000009ef310000300000000000000000000000000000000000000e88c11003815110000000000000000004815110002000000000000000100000000000000581511000f0000000000000000000000671511002800000000000000000000000000000000000000000000000000000000000000e88c1100f015110000000000000000009015110002000000000000000100000000000000a0151100080000000000000000000000a81511000700000000000000000000000000000000000000000000000000000000000000e88c1100b01511000000000000000000c015110001000000000000000100000000000000c81511000a0000000000000000000000d21511001d00000000000000000000000000000000000000000000000000000000000000e88c1100f015110000000000000000000016110001000000000000000100000056616c696461746f72436f756e740000e61c11002a0000004d696e696d756d56616c696461746f72436f756e74000000320000000000000001000000b2000000961c11005000000050657262696c6c00320000000000000001000000b3000000421c1100540000004f66666c696e65536c6173684772616365000000f41b11004e000000496e76756c6e657261626c6573000000201b110056000000761b110053000000c91b11002b000000426f6e6465640000e01a1100400000004c65646765725374616b696e674c65646765723c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e00320000000000000001000000400000008f1a110051000000506179656500000032000000000000000100000040000000561a11003900000056616c696461746f72730000320000000000000001000000b4000000051a1100510000004e6f6d696e61746f72730000ac191100590000005374616b6572734578706f737572653c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e00320000000000000001000000b5000000ef1811005300000042191100460000004876110000000000881911002400000043757272656e74456c65637465640000b01811003f00000043757272656e74457261457261496e6465780000991811001700000043757272656e7445726153746172744d6f6d656e744f663c543e0000320000000000000001000000460000007b1811001e00000043757272656e74457261537461727453657373696f6e496e64657800471811003400000043757272656e74457261526577617264734572615265776172647300320000000000000001000000b60000000418110043000000536c6f745374616b6500000032000000000000000100000041000000881711004c0000004876110000000000d417110030000000536c617368436f756e7400003200000000000000010000004900000014171100570000006b1711001d000000526563656e746c794f66666c696e655665633c28543a3a4163636f756e7449642c20543a3a426c6f636b4e756d6265722c20753332293e009816110055000000ed16110027000000466f726365457261466f7263696e6700320000000000000001000000400000005116110047000000426f6e646564457261735665633c28457261496e6465782c2053657373696f6e496e646578293e003200000000000000010000004200000008161100490000002041206d617070696e672066726f6d207374696c6c2d626f6e646564206572617320746f207468652066697273742073657373696f6e20696e646578206f662074686174206572612e205472756520696620746865206e6578742073657373696f6e206368616e67652077696c6c2062652061206e657720657261207265676172646c657373206f6620696e6465782e204d6f737420726563656e742060524543454e545f4f46464c494e455f434f554e546020696e7374616e6365732e202857686f206974207761732c207768656e20697420776173207265706f727465642c20686f77206d616e7920696e7374616e63657320746865792077657265206f66666c696e6520666f72292e20546865206e756d626572206f662074696d6573206120676976656e2076616c696461746f7220686173206265656e207265706f72746564206f66666c696e652e205468697320676574732064656372656d656e746564206279206f6e652065616368206572612074686174207061737365732e2054686520616d6f756e74206f662062616c616e6365206163746976656c79206174207374616b6520666f7220656163682076616c696461746f7220736c6f742c2063757272656e746c792e2054686973206973207573656420746f20646572697665207265776172647320616e642070756e6973686d656e74732e205265776172647320666f72207468652063757272656e74206572612e205573696e6720696e6469636573206f662063757272656e7420656c6563746564207365742e205468652073657373696f6e20696e646578206174207768696368207468652063757272656e742065726120737461727465642e20546865207374617274206f66207468652063757272656e74206572612e205468652063757272656e742065726120696e6465782e205468652063757272656e746c7920656c65637465642076616c696461746f7220736574206b65796564206279207374617368206163636f756e742049442e204e6f6d696e61746f727320666f72206120706172746963756c6172206163636f756e74207468617420697320696e20616374696f6e207269676874206e6f772e20596f752063616e27742069746572617465207468726f7567682076616c696461746f727320686572652c2062757420796f752063616e2066696e64207468656d20696e207468652053657373696f6e206d6f64756c652e2054686973206973206b6579656420627920746865207374617368206163636f756e742e20546865206d61702066726f6d206e6f6d696e61746f72207374617368206b657920746f2074686520736574206f66207374617368206b657973206f6620616c6c2076616c696461746f727320746f206e6f6d696e6174652e20546865206d61702066726f6d202877616e6e616265292076616c696461746f72207374617368206b657920746f2074686520707265666572656e636573206f6620746861742076616c696461746f722e2057686572652074686520726577617264207061796d656e742073686f756c64206265206d6164652e204b657965642062792073746173682e204d61702066726f6d20616c6c2028756e6c6f636b6564292022636f6e74726f6c6c657222206163636f756e747320746f2074686520696e666f20726567617264696e6720746865207374616b696e672e204d61702066726f6d20616c6c206c6f636b65642022737461736822206163636f756e747320746f2074686520636f6e74726f6c6c6572206163636f756e742e20416e792076616c696461746f72732074686174206d6179206e6576657220626520736c6173686564206f7220666f726369626c79206b69636b65642e20497427732061205665632073696e63652074686579277265206561737920746f20696e697469616c697a6520616e642074686520706572666f726d616e636520686974206973206d696e696d616c2028776520657870656374206e6f206d6f7265207468616e20666f757220696e76756c6e657261626c65732920616e64207265737472696374656420746f20746573746e6574732e204e756d626572206f6620696e7374616e636573206f66206f66666c696e65207265706f727473206265666f726520736c617368696e6720626567696e7320666f722076616c696461746f72732e20536c6173682c207065722076616c696461746f7220746861742069732074616b656e20666f72207468652066697273742074696d6520746865792061726520666f756e6420746f206265206f66666c696e652e204d696e696d756d206e756d626572206f66207374616b696e67207061727469636970616e7473206265666f726520656d657267656e637920636f6e646974696f6e732061726520696d706f7365642e2054686520696465616c206e756d626572206f66207374616b696e67207061727469636970616e74732e00000000801d11000e00000000000000b77011000c00000000000000e88c1100901d11000000000000000000a01d1100010000000000000000000000a81d11000f000000000000005a1411000800000000000000e88c1100b81d11000000000000000000c81d1100010000000000000053657373696f6e73506572457261000032000000000000000100000059000000091e11001c000000426f6e64696e674475726174696f6e00320000000000000001000000b7000000d01d110039000000204e756d626572206f6620657261732074686174207374616b65642066756e6473206d7573742072656d61696e20626f6e64656420666f722e204e756d626572206f662073657373696f6e7320706572206572612e5374616b696e6720536c6f745374616b650000501f110019000000701f110048000000bb0100002d000000b80000002800000004000000b9000000ba0000000000000000000000bb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f6f70732f61726974682e7273946a110028000000d01f110042000000bb020000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f7374616b696e672f7372632f6c69622e72730000d01f110042000000bb02000001000000636f6e74726f6c6c657220616c72656164792070616972656463616e206e6f7420626f6e6420776974682076616c7565206c657373207468616e206d696e696d756d2062616c616e6365737461736820616c726561647920626f6e6465646e6f74206120636f6e74726f6c6c65726e6f74206120737461736863616e206e6f74207363686564756c65206d6f726520756e6c6f636b206368756e6b73756e7374616b65207468726573686f6c6420746f6f206c61726765746172676574732063616e6e6f7420626520656d7074795374616b696e6720496e76756c6e657261626c65730000000000ec2211000800000000000000f4221100020000000000000000000000487611000000000000000000000000000423110006000000000000000c23110003000000000000000000000048761100000000000000000000000000242311000e0000000000000048761100000000000000000000000000487611000000000000000000000000003223110007000000000000003c231100020000000000000000000000487611000000000000000000000000004c231100060000000000000054231100010000000000000000000000487611000000000000000000000000005c2311000900000000000000542311000100000000000000000000004876110000000000000000000000000065231100090000000000000054231100010000000000000000000000487611000000000000000000000000006e231100080000000000000078231100020000000000000000000000487611000000000000000000000000008823110009000000000000009423110002000000000000000000000048761100000000000000000000000000a42311000b00000000000000b023110001000000000000000000000048761100000000000000000000000000b82311000600000000000000c023110003000000000000000000000048761100000000000000000050726f706f736564102411000900000019241100070000005461626c6564000010241100090000001924110007000000202411000e00000045787465726e616c5461626c656453746172746564000000f02311000f000000032411000d0000005061737365640000f02311000f0000004e6f7450617373656443616e63656c6c656445786563757465640000f02311000f000000ff2311000400000044656c656761746564000000d823110009000000d823110009000000556e64656c65676174656400d8231100090000005665746f65640000d823110009000000e123110004000000e52311000b0000004163636f756e74496448617368426c6f636b4e756d6265725265666572656e64756d496e646578626f6f6c566f74655468726573686f6c6450726f70496e64657842616c616e63655665633c4163636f756e7449643e44656d6f637261637920566f74654f6644656d6f63726163792044656c65676174696f6e7344656d6f6372616379205265666572656e64756d496e666f4f6644656d6f6372616379204465706f7369744f6644656d6f6372616379204469737061746368517565756544656d6f637261637920566f74657273466f7268656164206f662044656d6f63726163792044656c65676174696f6e7344656d6f6372616379205075626c696350726f70735025110048000000960a00000e0000004e6f207075626c69632070726f706f73616c732077616974696e6743616e6e6f7420696e6a6563742061207265666572656e64756d207468617420656e6473206561726c696572207468616e2070726563656564696e67207265666572656e64756d00002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e727344656d6f6372616379204e65787445787465726e616c4e6f2065787465726e616c2070726f706f73616c2077616974696e67000000000000b82811000700000000000000c0281100020000000000000000000000f0281100060000000000000000000000202911000600000000000000282911000100000000000000000000004029110006000000000000000000000070291100040000000000000074291100020000000000000000000000a4291100070000000000000000000000dc2911000a0000000000000074291100020000000000000000000000e8291100070000000000000000000000202a11001000000000000000302a1100010000000000000000000000482a1100020000000000000000000000582a11001000000000000000682a1100010000000000000000000000802a1100020000000000000000000000902a11001900000000000000682a1100010000000000000000000000ac2a1100050000000000000000000000d42a11001800000000000000682a1100010000000000000000000000ec2a1100050000000000000000000000142b11000a00000000000000202b1100030000000000000000000000682b1100080000000000000000000000a82b11000d00000000000000b82b1100010000000000000000000000d02b1100010000000000000000000000d82b11001100000000000000ec2b1100010000000000000000000000042c11000100000000000000000000000c2c11000d000000000000001c2c1100030000000000000000000000642c11000100000000000000000000006c2c11000900000000000000782c1100010000000000000000000000902c1100050000000000000000000000b82c11000c0000000000000048761100000000000000000000000000c42c1100050000000000000000000000ec2c11000c00000000000000782c1100010000000000000000000000f82c1100050000000000000000000000202d11000800000000000000282d1100020000000000000000000000582d1100050000000000000000000000802d11000a00000000000000487611000000000000000000000000008c2d1100050000000000000070726f706f736500000000005833110008000000000000006033110010000000000000005f35110005000000000000006435110015000000f5341100280000004876110000000000c52d11000b000000d02d1100080000003f35110020000000d82d11000c0000007365636f6e640000000000005833110008000000000000002d35110012000000f5341100280000004876110000000000c52d11000b000000d02d1100080000001d35110010000000d82d11000c000000766f746500000000372f110009000000000000000a2f11001800000000000000702911000400000000000000f134110004000000753411004d000000c23411002f0000004876110000000000c52d11000b000000d02d110008000000563411001f000000d82d11000c00000070726f78795f766f74650000c433110054000000183411003e0000004876110000000000c52d11000b000000d02d110008000000563411001f000000d82d11000c000000656d657267656e63795f63616e63656c00000000372f11000900000000000000f02311000f00000070331100540000004c3311000c00000065787465726e616c5f70726f706f7365000000005833110008000000000000006033110010000000003311004c0000004c3311000c00000065787465726e616c5f70726f706f73655f6d616a6f726974790000009232110056000000e832110018000000487611000000000018321100530000006b3211002700000065787465726e616c5f70726f706f73655f64656661756c74a531110052000000f731110021000000487611000000000018321100530000006b32110027000000666173745f747261636b0000000000006f2f11000d000000000000007c2f11000700000000000000853111000d00000000000000923111000e00000000000000a03111000500000000000000923111000e000000832f110054000000d72f110059000000303011003b00000048761100000000006b3011003e000000a93011004b000000f430110055000000493111003c0000007665746f5f65787465726e616c000000000000006f2f11000d000000000000007c2f110007000000402f11002f00000063616e63656c5f7265666572656e64756d00000000000000372f110009000000000000000a2f110018000000222f11001500000063616e63656c5f71756575656400000000000000da2e11000400000000000000de2e11001700000000000000f52e11000500000000000000fa2e11000c00000000000000062f110004000000000000000a2f110018000000b22e1100280000007365745f70726f787900000000000000ad2e110005000000000000000b2e11000c000000872e1100260000004876110000000000c52d11000b000000f32d110016000000d82d11000c00000072657369676e5f70726f7879612e1100260000004876110000000000c52d11000b000000512e110010000000d82d11000c00000072656d6f76655f70726f78792b2e1100260000004876110000000000c52d11000b000000512e110010000000d82d11000c00000064656c656761746500000000092e110002000000000000000b2e11000c00000000000000172e11000a00000000000000212e11000a000000e42d11000f0000004876110000000000c52d11000b000000f32d110016000000d82d11000c000000756e64656c65676174650000b42d1100110000004876110000000000c52d11000b000000d02d110008000000d82d11000c00000020556e64656c656761746520766f74652e2023203c7765696768743e202d204f2831292e2023203c2f7765696768743e2044656c656761746520766f74652e202d204f6e6520657874726120444220656e7472792e746f543a3a4163636f756e744964636f6e76696374696f6e436f6e76696374696f6e20436c656172207468652070726f78792e2043616c6c6564206279207468652073746173682e202d204f6e6520444220636c6561722e20436c656172207468652070726f78792e2043616c6c6564206279207468652070726f78792e205370656369667920612070726f78792e2043616c6c6564206279207468652073746173682e70726f78792043616e63656c20612070726f706f73616c2071756575656420666f7220656e6163746d656e742e7768656e436f6d706163743c543a3a426c6f636b4e756d6265723e7768696368436f6d706163743c7533323e77686174436f6d706163743c5265666572656e64756d496e6465783e2052656d6f76652061207265666572656e64756d2e7265665f696e646578205665746f20616e6420626c61636b6c697374207468652065787465726e616c2070726f706f73616c20686173682e70726f706f73616c5f68617368543a3a48617368205363686564756c65207468652063757272656e746c792065787465726e616c6c792d70726f706f736564206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c656420696d6d6564696174656c792e204966207468657265206973206e6f2065787465726e616c6c792d70726f706f736564207265666572656e64756d2063757272656e746c792c206f72206966207468657265206973206f6e6520627574206974206973206e6f742061206d616a6f726974792d63617272696573207265666572656e64756d207468656e206974206661696c732e202d206070726f706f73616c5f68617368603a205468652068617368206f66207468652063757272656e742065787465726e616c2070726f706f73616c2e202d2060766f74696e675f706572696f64603a2054686520706572696f64207468617420697320616c6c6f77656420666f7220766f74696e67206f6e20746869732070726f706f73616c2e202d206064656c6179603a20546865206e756d626572206f6620626c6f636b20616674657220766f74696e672068617320656e64656420696e20617070726f76616c20616e6420746869732073686f756c64206265202020656e61637465642e20496e6372656173656420746f2060456d657267656e6379566f74696e67506572696f646020696620746f6f206c6f772e766f74696e675f706572696f64543a3a426c6f636b4e756d62657264656c6179205363686564756c652061206e656761746976652d7475726e6f75742d62696173207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e20556e6c696b65206065787465726e616c5f70726f706f7365602c20626c61636b6c697374696e6720686173206e6f20656666656374206f6e207468697320616e64206974206d6179207265706c6163652061207072652d7363686564756c6564206065787465726e616c5f70726f706f7365602063616c6c2e205363686564756c652061206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e205363686564756c652061207265666572656e64756d20746f206265207461626c6564206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e70726f706f73616c426f783c543a3a50726f706f73616c3e205363686564756c6520616e20656d657267656e63792063616e63656c6c6174696f6e206f662061207265666572656e64756d2e2043616e6e6f742068617070656e20747769636520746f207468652073616d6520566f746520696e2061207265666572656e64756d206f6e20626568616c66206f6620612073746173682e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b20206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e202d204f6e65204442206368616e67652c206f6e6520444220656e7472792e20566f746520696e2061207265666572656e64756d2e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e566f74652050726f706f736520612073656e73697469766520616374696f6e20746f2062652074616b656e2e202d204f6e6520444220656e7472792e436f6d706163743c50726f70496e6465783e202d2054776f204442206368616e6765732c206f6e6520444220656e7472792e76616c7565436f6d706163743c42616c616e63654f663c543e3e44656d6f6372616379000000000000ac3a11000f0000000000000000000000102411000900000000000000000000000000000000000000000000000000000000000000e88c11006c3b11000000000000000000bc3a110001000000000000000100000000000000c43a11000b0000000000000000000000cf3a11002b00000000000000000000000000000000000000000000000000000000000000e88c1100383c11000000000000000000fc3a110001000000000000000100000000000000043b11000900000001010000000000001024110009000000000000000d3b11002100000000000000000000000000000000000000e88c1100303b11000000000000000000403b110001000000000000000000000000000000483b11000f0000000000000000000000f02311000f00000000000000000000000000000000000000000000000000000000000000e88c11006c3b11000000000000000000583b110001000000000000000100000000000000603b1100090000000000000000000000f02311000f00000000000000000000000000000000000000000000000000000000000000e88c11006c3b110000000000000000007c3b110001000000000000000100000000000000843b1100100000000101000000000000f02311000f00000000000000943b11002d00000000000000000000000000000000000000e88c1100b03c11000000000000000000c43b110001000000000000000000000000000000cc3b11000d0000000101000000000000923111000e00000000000000d93b11002b00000000000000000000000000000000000000e88c1100043c11000000000000000000143c1100010000000000000001000000000000001c3c1100090000000101000000000000f02311000f00000000000000253c11001100000000000000000000000000000000000000e88c1100383c11000000000000000000483c110001000000000000000100000000000000503c1100060000000101000000000000563c11001f00000000000000f13411000400000000000000000000000000000000000000e88c1100783c11000000000000000000883c110004000000000000000100000000000000a83c11000500000001010000000000000b2e11000c000000000000000b2e11000c00000000000000000000000000000000000000e88c1100b03c11000000000000000000c03c110002000000000000000000000000000000d03c11000b00000001010100000000000b2e11000c00000000000000db3c11001a00000000000000000000000000000000000000e88c1100f83c11000000000000000000083d110001000000000000000100000000000000103d1100150000000000000000000000ff2311000400000000000000000000000000000000000000000000000000000000000000e88c1100ec3d11000000000000000000283d110002000000000000000100000000000000383d11000c0000000000000000000000443d11001c00000000000000000000000000000000000000000000000000000000000000e88c1100603d11000000000000000000703d110004000000000000000000000000000000903d11000900000001010000000000007c2f11000700000000000000993d11002300000000000000000000000000000000000000e88c1100bc3d11000000000000000000cc3d110002000000000000000000000000000000dc3d11000d00000001010000000000007c2f11000700000000000000ff2311000400000000000000000000000000000000000000e88c1100ec3d11000000000000000000fc3d11000100000000000000010000005075626c696350726f70436f756e74006c4311003d0000005075626c696350726f70735665633c2850726f70496e6465782c20543a3a50726f706f73616c2c20543a3a4163636f756e744964293e00004c431100200000004465706f7369744f662842616c616e63654f663c543e2c205665633c543a3a4163636f756e7449643e290000320000000000000001000000560000002b431100210000005265666572656e64756d436f756e7400df4211004c0000004e65787454616c6c7900000032000000000000000100000049000000ad421100320000005265666572656e64756d496e666f4f66285265666572656e64756d496e666f3c543a3a426c6f636b4e756d6265722c20543a3a50726f706f73616c3e29000000804211002d000000446973706174636851756575655665633c4f7074696f6e3c28543a3a50726f706f73616c2c205265666572656e64756d496e646578293e3e320000000000000001000000420000005042110030000000566f74657273466f725665633c543a3a4163636f756e7449643e0000320000000000000001000000420000002742110029000000566f74654f66285265666572656e64756d496e6465782c20543a3a4163636f756e7449642900000032000000000000000100000040000000e84011005800000040411100530000009341110057000000ea4111003d00000050726f7879000000320000000000000001000000400000007a4011004c000000c64011002200000044656c65676174696f6e7328543a3a4163636f756e7449642c20436f6e76696374696f6e29000000320000000000000001000000bc0000002a401100500000004c6173745461626c656457617345787465726e616c000000ca3f110056000000204011000a0000004e65787445787465726e616c28543a3a50726f706f73616c2c20566f74655468726573686f6c6429320000000000000001000000bd000000dc3e110056000000323f110055000000873f110029000000b03f11001a000000426c61636b6c69737428543a3a426c6f636b4e756d6265722c205665633c543a3a4163636f756e7449643e29320000000000000001000000560000004e3e110054000000a23e11003a00000043616e63656c6c6174696f6e7300000032000000000000000100000040000000043e11004a000000205265636f7264206f6620616c6c2070726f706f73616c7320746861742068617665206265656e207375626a65637420746f20656d657267656e63792063616e63656c6c6174696f6e2e2041207265636f7264206f662077686f207665746f656420776861742e204d6170732070726f706f73616c206861736820746f206120706f737369626c65206578697374656e7420626c6f636b206e756d6265722028756e74696c207768656e206974206d6179206e6f742062652072657375626d69747465642920616e642077686f207665746f65642069742e20546865207265666572656e64756d20746f206265207461626c6564207768656e6576657220697420776f756c642062652076616c696420746f207461626c6520616e2065787465726e616c2070726f706f73616c2e20546869732068617070656e73207768656e2061207265666572656e64756d206e6565647320746f206265207461626c656420616e64206f6e65206f662074776f20636f6e646974696f6e7320617265206d65743a202d20604c6173745461626c656457617345787465726e616c60206973206066616c7365603b206f72202d20605075626c696350726f70736020697320656d7074792e205472756520696620746865206c617374207265666572656e64756d207461626c656420776173207375626d69747465642065787465726e616c6c792e2046616c7365206966206974207761732061207075626c69632070726f706f73616c2e2047657420746865206163636f756e742028616e64206c6f636b20706572696f64732920746f20776869636820616e6f74686572206163636f756e742069732064656c65676174696e6720766f74652e2057686f2069732061626c6520746f20766f746520666f722077686f6d2e2056616c7565206973207468652066756e642d686f6c64696e67206163636f756e742c206b65792069732074686520766f74652d7472616e73616374696f6e2d73656e64696e67206163636f756e742e204765742074686520766f746520696e206120676976656e207265666572656e64756d206f66206120706172746963756c617220766f7465722e2054686520726573756c74206973206d65616e696e6766756c206f6e6c792069662060766f746572735f666f726020696e636c756465732074686520766f746572207768656e2063616c6c6564207769746820746865207265666572656e64756d2028796f75276c6c20676574207468652064656661756c742060566f7465602076616c7565206f7468657277697365292e20496620796f7520646f6e27742077616e7420746f20636865636b2060766f746572735f666f72602c207468656e20796f752063616e20616c736f20636865636b20666f722073696d706c65206578697374656e636520776974682060566f74654f663a3a657869737473602066697273742e204765742074686520766f7465727320666f72207468652063757272656e742070726f706f73616c2e205175657565206f66207375636365737366756c207265666572656e646120746f20626520646973706174636865642e20496e666f726d6174696f6e20636f6e6365726e696e6720616e7920676976656e207265666572656e64756d2e20546865206e657874207265666572656e64756d20696e64657820746861742073686f756c642062652074616c6c6965642e20546865206e6578742066726565207265666572656e64756d20696e6465782c20616b6120746865206e756d626572206f66207265666572656e6461207374617274656420736f206661722e2054686f73652077686f2068617665206c6f636b65642061206465706f7369742e20546865207075626c69632070726f706f73616c732e20556e736f727465642e20546865206e756d626572206f6620287075626c6963292070726f706f73616c7320746861742068617665206265656e206d61646520736f206661722e00000000000000fc4411000f00000000000000923111000e00000000000000e88c11000c45110000000000000000001c451100050000000000000000000000444511000c00000000000000923111000e00000000000000e88c1100e0451100000000000000000050451100010000000000000000000000584511000c00000000000000923111000e00000000000000e88c1100e04511000000000000000000644511000100000000000000000000006c4511000e000000000000007a4511000c00000000000000e88c110088451100000000000000000098451100010000000000000000000000a04511001500000000000000923111000e00000000000000e88c1100b84511000000000000000000c8451100010000000000000000000000d04511000d00000000000000923111000e00000000000000e88c1100e04511000000000000000000f04511000100000000000000456e6163746d656e74506572696f6400320000000000000001000000be0000003f4711005c00000048761100000000009b4711004c000000e74711005a00000041481100270000004c61756e6368506572696f640647110039000000566f74696e67506572696f64d84611002e0000004d696e696d756d4465706f73697442616c616e63654f663c543e0000320000000000000001000000bf0000008b4611004d000000456d657267656e6379566f74696e67506572696f64000000320000000000000001000000c0000000504611003b000000436f6f6c6f6666506572696f64000000320000000000000001000000c1000000f84511005800000020506572696f6420696e20626c6f636b7320776865726520616e2065787465726e616c2070726f706f73616c206d6179206e6f742062652072652d7375626d6974746564206166746572206265696e67207665746f65642e204d696e696d756d20766f74696e6720706572696f6420616c6c6f77656420666f7220616e20656d657267656e6379207265666572656e64756d2e20546865206d696e696d756d20616d6f756e7420746f20626520757365642061732061206465706f73697420666f722061207075626c6963207265666572656e64756d2070726f706f73616c2e20486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e20486f77206f6674656e2028696e20626c6f636b7329206e6577207075626c6963207265666572656e646120617265206c61756e636865642e20546865206d696e696d756d20706572696f64206f66206c6f636b696e6720616e642074686520706572696f64206265747765656e20612070726f706f73616c206265696e6720617070726f76656420616e6420656e61637465642e2049742073686f756c642067656e6572616c6c792062652061206c6974746c65206d6f7265207468616e2074686520756e7374616b6520706572696f6420746f20656e73757265207468617420766f74696e67207374616b657273206861766520616e206f70706f7274756e69747920746f2072656d6f7665207468656d73656c7665732066726f6d207468652073797374656d20696e207468652063617365207768657265207468657920617265206f6e20746865206c6f73696e672073696465206f66206120766f74652e946a110028000000804811004400000054010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f64656d6f63726163792f7372632f6c69622e7273f54b110023000000cb4b11002a0000008048110044000000540100000100000076616c756520746f6f206c6f7770726f706f73657227732062616c616e636520746f6f206c6f7763616e206f6e6c79207365636f6e6420616e206578697374696e672070726f706f73616c7365636f6e64657227732062616c616e636520746f6f206c6f776e6f7420612070726f787944656d6f63726163792043616e63656c6c6174696f6e7370726f706f73616c207374696c6c20626c61636b6c697374656470726f706f73616c20616c7265616479206d616465696e76616c696420686173686e6578742065787465726e616c2070726f706f73616c206e6f742073696d706c65206d616a6f726974796e6f2070726f706f73616c206d61646544656d6f637261637920426c61636b6c6973746e6f2065787465726e616c2070726f706f73616c756e6b6e6f776e2070726f706f73616c6964656e74697479206d6179206e6f74207665746f20612070726f706f73616c20747769636544656d6f63726163792050726f7879616c726561647920612070726f787977726f6e672070726f78790a09090909090909096865616420697320736574207768656e20666972737420656c656d656e7420697320696e73657274656420616e6420756e736574207768656e206c61737420656c656d656e742069732072656d6f7665643b0a09090909090909096966206865616420697320536f6d65207468656e20697420706f696e747320746f206578697374696e67206b65793b207165640a090909090909094c696e6b616765206973207570646174656420696e206361736520656e7472792069732072656d6f7665643b20697420616c7761797320706f696e747320746f206578697374696e67206b6579733b207165646e6f742064656c656761746564756e6b6e6f776e20696e64657863616e6e6f742063616e63656c207468652073616d652070726f706f73616c20747769636570726f706f73616c206e6f7420666f756e64766f746520676976656e20666f7220696e76616c6964207265666572656e64756d2e696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64653a205f5f5068616e746f6d4974656d2073686f756c64206e6576657220626520757365642e54726561737572792050726f706f73616c436f756e74547265617375727920417070726f76616c730000000001000000020000000400000008000000100000002000000044656d6f6372616379205075626c696350726f70436f756e7444656d6f6372616379205265666572656e64756d436f756e7444656d6f6372616379204e65787454616c6c7944656d6f6372616379204c6173745461626c656457617345787465726e616cd04c110048000000960a00000e0000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e72735374616b696e672056616c696461746f72436f756e745374616b696e67204d696e696d756d56616c696461746f72436f756e745374616b696e67204f66666c696e65536c61736847726163655374616b696e672043757272656e744572615374616b696e672043757272656e74457261537461727453657373696f6e496e6465785374616b696e672043757272656e74457261526577617264735374616b696e6720466f7263654572615374616b696e6720426f6e64656445726173417574686f727368697020446964536574556e636c6573746f6f206d616e7920696e737472756374696f6e73184e11002400000065741100170000004402000009000000547269656420746f20736872696e6b20746f2061206c61726765722063617061636974796578745f7365745f73746f726167656578745f6765745f73746f726167656578745f63616c6c6578745f6372656174656578745f72657475726e6578745f63616c6c65726578745f616464726573736578745f6761735f70726963656578745f6761735f6c6566746578745f62616c616e63656578745f76616c75655f7472616e736665727265646578745f72616e646f6d6578745f6e6f776578745f64697370617463685f63616c6c6578745f726573746f72655f746f6578745f736372617463685f73697a656578745f736372617463685f726561646578745f736372617463685f77726974656578745f6465706f7369745f6576656e746578745f7365745f72656e745f616c6c6f77616e63656578745f72656e745f616c6c6f77616e63656578745f7072696e746c6e6578745f626c6f636b5f6e756d6265724e6f6e2d656d7074792066756e6374696f6e20626f64792065787065637465640000005a5011000f00000069501100020000006b50110003000000cc4f110030000000fc4f11005e0000007d00000005000000617373657274696f6e206661696c65643a20636f6e746578742e6672616d655f737461636b2e69735f656d70747928292f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7761736d692d76616c69646174696f6e2d302e312e302f7372632f66756e632e7273417420696e737472756374696f6e202840293a20436f6e7472616374204761735370656e74436f6e74726163742043757272656e745363686564756c65436f6e7472616374204163636f756e74436f756e74657252657475726e207479706573206c656e6774682073686f756c642062652030206f72203143616e2774206465636f6465207761736d20636f64654d6f64756c65206973206e6f742076616c69646d6f64756c65206465636c6172657320696e7465726e616c206d656d6f72796d756c7469706c65207461626c6573206465636c617265647461626c652065786365656473206d6178696d756d2073697a6520616c6c6f776564757365206f6620666c6f6174696e6720706f696e74207479706520696e2066756e6374696f6e20747970657320697320666f7262696464656e757365206f6620666c6f6174696e6720706f696e74207479706520696e206c6f63616c7320697320666f7262696464656e757365206f6620666c6f6174696e6720706f696e74207479706520696e20676c6f62616c7320697320666f7262696464656e67617320696e737472756d656e746174696f6e206661696c6564737461636b2068656967687420696e737472756d656e746174696f6e206661696c656463616c6c6465706c6f796465706c6f792066756e6374696f6e2069736e2774206578706f72746564756e6b6e6f776e206578706f72743a20657870656374696e67206f6e6c79206465706c6f7920616e642063616c6c2066756e6374696f6e7366756e6374696f6e206861732061206e6f6e2d6578697374656e7420747970656578706f72742072656665727320746f206e6f6e2d6578697374656e742066756e6374696f6e657870656374656420612066756e6374696f6e656e74727920706f696e7420706f696e747320746f20616e20696d706f727465642066756e6374696f6e656e74727920706f696e74206861732077726f6e67207369676e617475726563616c6c2066756e6374696f6e2069736e2774206578706f727465646572726f722073657269616c697a696e6720696e737472756d656e746564206d6f64756c65285511001e000000465511001f00000066756e6374696f6e5f73656374696f6e5f6c656e20213d20303b2071656466756e6374696f6e5f73656374696f6e5f6c656e20213d20303b2066756e6374696f6e5f73656374696f6e5f6c656e203d3d20636f64655f73656374696f6e5f6c656e3b2071656400000e5511001a000000e95411000a000000f35411001b00000073746172742066756e6374696f6e20657870656374656420746f20686176652074797065205b5d202d3e205b5d000000d854110011000000b854110020000000985411002000000070541100280000007365676d656e74206f66667365742073686f756c642072657475726e20493332746f6f206d616e79206d656d6f727920726567696f6e7320696e20696e6465782073706163653a20746f6f206d616e79207461626c657320696e20696e6465782073706163653a20747279696e6720746f20696d706f7274206d757461626c6520676c6f62616c206475706c6963617465206578706f72742046756e6374696f6e20232072656164696e672f76616c69646174696f6e206572726f723a204d697373696e6720626f647920666f722066756e6374696f6e206c656e677468206f662066756e6374696f6e2073656374696f6e206973202c207768696c65206c656e206f6620636f64652073656374696f6e20697320000000845511001c000000a05511005a0000004d00000028000000ffffffff48617368207461626c65206361706163697479206f766572666c6f772f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6861736862726f776e2d302e312e382f7372632f7261772f6d6f642e72736d616b655f746f705f6672616d655f706f6c796d6f72706869632069732063616c6c6564207769746820656d707479206672616d6520737461636b000000c20000000c00000004000000c3000000746869732066756e6374696f6e2063616e27742062652063616c6c6564207769746820656d707479206672616d6520737461636b4d6973706c6163656420656c736520696e737472756374696f6e0000c05711004700000007581100050000008457110037000000bb57110005000000515711001700000048571100090000009a59110014000000305711001800000048571100090000009a59110014000000005711001d0000001d571100130000003b8c110001000000546f6f206c61726765206d656d6f727920616c69676e6d656e7420325e20286578706563746564206174206d6f737420547279696e6720746f2075706461746520676c6f62616c20206f66207479706520547279696e6720746f20757064617465206c6f63616c20416e79537065636966696300510000000400000004000000c40000004c6162656c7320696e2062725f7461626c6520706f696e747320746f20626c6f636b206f6620646966666572656e742074797065733a2020616e6420496620626c6f636b20776974686f757420656c736520726571756972656420746f2068617665204e6f526573756c7420626c6f636b20747970652e20427574206974206861732020747970651c58110018000000345811000b000000556e657870656374656420737461636b20686569676874202c20657870656374656420547279696e6720746f2061636365737320706172656e74206672616d6520737461636b2076616c7565732e00007c58110017000000935811001600000045787065637465642076616c7565206f66207479706520206f6e20746f70206f6620737461636b2e20476f7420000000b458110007000000537461636b3a2000000001003e5911002400000014591100060000001a5911000e0000002859110016000000f05811002400000014591100060000006d6178696d756d206d656d6f72792073697a65206d757374206265206174206d6f7374202070616765736d6178696d756d206c696d697420206973206c657373207468616e206d696e696d756d20696e697469616c206d656d6f72792073697a65206d757374206265206174206d6f737420000074591100260000009a59110014000000547279696e6720746f20696e697469616c697a65207661726961626c65206f6620747970652020776974682076616c7565206f66207479706520496e69742065787072657373696f6e2073686f756c6420616c776179732062652077697468206c656e67746820324e6f6e20636f6e7374616e74206f70636f646520696e20696e69742065787072455a110007000000575a110022000000455a1100070000004c5a11000b00000045787072657373696f6e20646f65736e277420656e647320776974682060656e6460206f70636f6465476c6f62616c20206973206d757461626c6520646f65736e277420657869737473206f72206e6f742079657420646566696e65640000008c5a1100100000009c5a11000f0000004d656d6f727920617420696e6465782020646f65736e27742065786973747300bc5a11000f0000009c5a11000f0000005461626c6520617420696e646578200069621100120000009c5a11000f000000ec5a11000e0000009c5a11000f0000005479706520617420696e6465782000005a5b1100100000009c5a11000f0000002c5b1100100000004c5b11000e0000002c5b1100100000003c5b110010000000457870656374656420676c6f62616c2020746f20626520696d6d757461626c6520746f206265206d757461626c65476c6f62616c20617420696e646578206e6f6e2d656d70747920737461636b2065787065637465640000945b110020000000b45b110012000000747279696e6720746f206765742076616c756520617420706f736974696f6e20206f6e20737461636b206f662073697a6520636865636b656420636f75706c65206f66206c696e65732061626f766500ec5b110015000000657863656564656420737461636b206c696d697420000000510000000400000004000000c50000004c6f63616c732072616e6765206e6f7420696e2033322d6269742072616e67654c5c1100220000006e5c110015000000835c110007000000547279696e6720746f20616363657373206c6f63616c207769746820696e64657820207768656e20746865726520617265206f6e6c7920206c6f63616c734672616d6569735f706f6c796d6f7270686963000000510000000400000004000000c6000000656e645f6172697479000000510000000400000004000000200000006272616e63685f617269747973746172745f6865696768744e6f2066756e6374696f6e2073656374696f6e4e6f20636f64652073656374696f6e4e6f20747970652073656374696f6e000000046011000a00000046756e6374696f6e206973206e6f7420666f756e6420696e2066756e632073656374696f6e46756e6374696f6e20626f647920666f722074686520696e6465782069736e277420666f756e64f85f11000c000000605f11000b000000737461636b206d757374206265206e6f6e2d656d70747900555f11000b0000000e5f110006000000737461636b206f766572666c6f774172697479206f6620616c6c206a756d702d74617267657473206d75737420626520657175616c54797065206e6f7420666f756e6400075f110007000000005e11006c000000c8000000110000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e362e322f7372632f737461636b5f6865696768742f6d61785f6865696768742e72736d61785f686569676874707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768742f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e362e322f7372632f737461636b5f6865696768742f6d61785f6865696768742e72737472756e633a20707573683a20505f110005000000747279696e6720746f20706f70206d6f72652076616c756573207468616e20707573686564737461636b20756e646572666c6f77706f703a20756e726561636861626c65706f705f6672616d653a20636f6e74726f6c20737461636b20697320656d707479636f6e74726f6c20737461636b206f75742d6f662d626f756e6473b05f110048000000900a00000a000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f736c6963652f6d6f642e7273707573685f6672616d653a2066756e635f6964783a2066756e635f737461636b5f636f7374732069736e27742079657420636f6d70757465643b0a0909090944696420796f752063616c6c2060636f6d707574655f737461636b5f636f737473603f546869732073686f756c64206265206120696e646578206f66206120646566696e65642066756e6374696f6e44756520746f2076616c69646174696f6e20636f64652073656374696f6e2073686f756c642065786973747346756e6374696f6e20626f6479206973206f7574206f6620626f756e647310611100650000002301000017000000e86011002500000043616c6c20746f2066756e6374696f6e2074686174206f75742d6f662d626f756e64733a200000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e362e322f7372632f737461636b5f6865696768742f6d6f642e727366756e6374696f6e20696d706f727420636f756e74206973206e6f74207a65726f3b20696d706f72742073656374696f6e206d757374206578697374733b2071656466756e635f696478206973206c657373207468616e2066756e6374696f6e20696d706f72747320636f756e743b0a090909096e74682066756e6374696f6e20696d706f7274206d7573742062652060536f6d65603b0a0909090971656469621100120000007b6211000f0000003c6211000a00000046621100140000005a6211000f0000005369676e61747572652020287370656369666965642062792066756e6320292069736e277420646566696e656446756e6374696f6e20617420696e64657820206973206e6f7420646566696e6564656e76676173a06211005800000088000000160000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e362e322f7372632f6761732e72737372632f6c6962616c6c6f632f7665632e727300246311001c000000f862110013000000c704000009000000617373657274696f6e206661696c65643a20656e64203c3d206c656e586311001e000000f862110013000000b403000009000000617373657274696f6e206661696c65643a20696e646578203c3d206c656e0000510000000400000004000000c70000004d641100120000005f6411000c0000006066756e635f696478602073686f756c6420636f6d652066726f6d20606e6565645f7468756e6b73603b0a09090909606e6565645f7468756e6b736020697320706f70756c617465642077697468207468652073616d65206974656d73207468617420696e20607265706c6163656d656e745f6d6170603b0a090909097165644174207468697320706f696e7420616e20696e646578206d7573742062652061737369676e656420746f2065616368207468756e6b66756e6374696f6e207769746820696478202069736e277420666f756e644636345265696e74657270726574493634556e726561636861626c654e6f70426c6f636b00510000000400000004000000c80000004c6f6f704966456c7365456e64427200510000000400000004000000200000004272496642725461626c6500510000000400000004000000c900000052657475726e43616c6c43616c6c496e6469726563740000510000000400000004000000ca00000044726f7053656c6563744765744c6f63616c5365744c6f63616c5465654c6f63616c476574476c6f62616c536574476c6f62616c4933324c6f61644936344c6f61644633324c6f61644636344c6f61644933324c6f616438534933324c6f616438554933324c6f61643136534933324c6f61643136554936344c6f616438534936344c6f616438554936344c6f61643136534936344c6f61643136554936344c6f61643332534936344c6f616433325549333253746f726549363453746f726546333253746f726546363453746f726549333253746f72653849333253746f7265313649363453746f72653849363453746f7265313649363453746f7265333243757272656e744d656d6f727947726f774d656d6f7279493332436f6e737400510000000400000004000000cb000000493634436f6e7374510000000400000004000000cc000000463332436f6e7374463634436f6e73745100000004000000040000001e00000049333245717a49333245714933324e654933324c74534933324c74554933324774534933324774554933324c65534933324c655549333247655349333247655549363445717a49363445714936344e654936344c74534936344c74554936344774534936344774554936344c65534936344c655549363447655349363447655546333245714633324e654633324c7446333247744633324c65463332476546363445714636344e654636344c7446363447744636344c654636344765493332436c7a49333243747a493332506f70636e744933324164644933325375624933324d756c493332446976534933324469765549333252656d5349333252656d55493332416e644933324f72493332586f7249333253686c4933325368725349333253687255493332526f746c493332526f7472493634436c7a49363443747a493634506f70636e744936344164644936345375624936344d756c493634446976534936344469765549363452656d5349363452656d55493634416e644936344f72493634586f7249363453686c4936345368725349363453687255493634526f746c493634526f74724633324162734633324e65674633324365696c463332466c6f6f724633325472756e634633324e656172657374463332537172744633324164644633325375624633324d756c4633324469764633324d696e4633324d6178463332436f70797369676e4636344162734636344e65674636344365696c463634466c6f6f724636345472756e634636344e656172657374463634537172744636344164644636345375624636344d756c4636344469764636344d696e4636344d6178463634436f70797369676e493332577261704936344933325472756e63534633324933325472756e63554633324933325472756e63534636344933325472756e6355463634493634457874656e6453493332493634457874656e64554933324936345472756e63534633324936345472756e63554633324936345472756e63534636344936345472756e6355463634463332436f6e7665727453493332463332436f6e7665727455493332463332436f6e7665727453493634463332436f6e766572745549363446333244656d6f7465463634463634436f6e7665727453493332463634436f6e7665727455493332463634436f6e7665727453493634463634436f6e766572745549363446363450726f6d6f74654633324933325265696e746572707265744633324936345265696e746572707265744636344633325265696e746572707265744933324e6f526573756c7456616c756500510000000400000004000000c4000000463634493332493634463332496e76616c696444617461547261696c696e6744617461556e6578706563746564456f66706a11000b000000492f4f204572726f723a2000946a110028000000bc6a1100500000008700000009000000696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64652f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d73616e64626f782f7372632f2e2e2f776974686f75745f7374642e7273946a110028000000bc6a11005000000090000000090000004f6666636861696e206572726f723a207375626d697474696e67207472616e73616374696f6e206661696c6564214f6666636861696e206572726f723a206465636f64696e6720576f726b6572537461747573206661696c6564214f6666636861696e206572726f723a2065787472696e736963206372656174696f6e206661696c6564214f6666636861696e206572726f723a207369676e696e67206661696c6564214f6666636861696e206572726f723a206665746368696e67206e6574776f726b207374617465206661696c656421000000000000246c11001100000000000000386c1100010000000000000000000000406c110001000000000000004865617274626561745265636569766564000000786c11000b000000486c1100300000002041206e657720686561727462656174207761732072656365697665642066726f6d2060417574686f72697479496460417574686f726974794964496d4f6e6c696e65204b657973496d4f6e6c696e6520526563656976656448656172746265617473436f756e63696c20446573697265645365617473436f756e63696c20566f7465436f756e74436f756e63696c204e657874566f746572536574436f756e63696c20566f746572436f756e74436f756e63696c2043616e646964617465436f756e7400000000906d11000e00000000000000a06d1100010000000000000000000000a86d1100010000000000000000000000b06d1100060000000000000048761100000000000000000000000000b86d1100010000000000000000000000c06d1100070000000000000048761100000000000000000000000000c86d110001000000000000004e6577417574686f7269746965730000436e1100170000001f6e1100240000005061757365640000f86d110027000000526573756d656400d06d1100280000002043757272656e7420617574686f726974792073657420686173206265656e20726573756d65642e2043757272656e7420617574686f726974792073657420686173206265656e207061757365642e204e657720617574686f726974792073657420686173206265656e206170706c6965642e5665633c28417574686f7269747949642c20753634293e4772616e64706146696e616c69747920417574686f72697469657354696d657374616d7020496e697469616c697a6564426162652045706f6368496e6465784261626520417574686f726974696573426162652045706f63685374617274536c6f74426162652043757272656e74536c6f7442616265205365636f6e64617279536c6f7473426162652050656e64696e675365636f6e64617279536c6f74734368616e6765426162652052616e646f6d6e65737342616265204e65787452616e646f6d6e65737342616265205365676d656e74496e6465784261626520556e646572436f6e737472756374696f6e4261626520496e697469616c697a656462616265736c6f74436f756c64206e6f74206465636f64652072657175657374656420696e686572656e742074797065214241424520696e686572656e742064617461206e6f7420666f756e6453657373696f6e2053746f72656452616e676553657373696f6e2043757272656e74496e64657853657373696f6e204368616e67656453657373696f6e205175657565644368616e676564000000001c7011000a00000000000000287011000100000000000000000000003070110002000000000000004e657753657373696f6e0000b77011000c00000040701100550000009570110022000000204e65772073657373696f6e206861732068617070656e65642e204e6f746520746861742074686520617267756d656e74206973207468652073657373696f6e20696e6465782c206e6f742074686520626c6f636b206e756d626572206173207468652074797065206d6967687420737567676573742e53657373696f6e496e64657800320000000000000001000000cd000000ce000000cf000000320000000000000001000000cd000000ce000000cf00000074696d737461703054696d657374616d7020696e686572656e742064617461206973206e6f742070726f76696465642e496e76616c69642074696d657374616d7020696e686572656e74206461746120656e636f64696e672e54696d657374616d702044696455706461746500000000b8711100100000000000000048761100000000000000000000000000c8711100010000000000000000000000d07111000f0000000000000048761100000000000000000000000000e0711100010000000000000045787472696e73696353756363657373fd7111002500000045787472696e7369634661696c656400e87111001500000020416e2065787472696e736963206661696c65642e20416e2065787472696e73696320636f6d706c65746564207375636365737366756c6c792e53797374656d2045787472696e736963436f756e7453797374656d20416c6c45787472696e7369637357656967687453797374656d20416c6c45787472696e736963734c656e53797374656d204e6578745765696768744d756c7469706c69657253797374656d2045787472696e7369634461746153797374656d204576656e74436f756e7448617368206e6f7420657175616c0000d072110019000000f0721100500000005800000022000000617474656d707420746f20646976696465206279207a65726f000000000000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f67656e657269632f6572612e72736578745f6368696c645f73746f726167655f726f6f74206e657665722072657475726e73207533323a3a6d61785f76616c75653b2071656452756e74696d65206d656d6f7279206578686175737465642e2041626f7274696e670000b47311002d000000e17311000c000000ed73110003000000617373657274696f6e206661696c65643a2060286c656674203d3d20726967687429600a20206c6566743a2060602c0a2072696768743a2060603a20f87311003400000064657374696e6174696f6e20616e6420736f7572636520736c69636573206861766520646966666572656e74206c656e6774687374771100180000004d0800000900000054741100110000006574110017000000f0020000050000006361706163697479206f766572666c6f777372632f6c6962616c6c6f632f7261775f7665632e7273f0741100460000006301000013000000510000000400000004000000d0000000d1000000d20000006120666f726d617474696e6720747261697420696d706c656d656e746174696f6e2072657475726e656420616e206572726f7200320000000000000001000000a300000000000000000000002f72757374632f326431613535316531343433333565306436306136333764313266343130636636353834393837362f7372632f6c6962636f72652f666d742f6d6f642e727301010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000202020202020202020202020202020202020202020202020202020202020303030303030303030303030303030304040404040000000000000000000000000058761100200000007876110012000000320000000000000001000000d3000000696e646578206f7574206f6620626f756e64733a20746865206c656e20697320206275742074686520696e64657820697320303030313032303330343035303630373038303931303131313231333134313531363137313831393230323132323233323432353236323732383239333033313332333333343335333633373338333934303431343234333434343534363437343834393530353135323533353435353536353735383539363036313632363336343635363636373638363937303731373237333734373537363737373837393830383138323833383438353836383738383839393039313932393339343935393639373938393900008c77110006000000927711002200000074771100180000000c0a0000050000007372632f6c6962636f72652f736c6963652f6d6f642e7273696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e67746820d477110016000000ea7711000d0000007477110018000000120a000005000000736c69636520696e64657820737461727473206174202062757420656e6473206174206030785b2e2e2e5d00be7811000b000000728b110016000000f777110001000000a878110016000000ed07000009000000508b11000e0000005e8b110004000000628b110010000000f777110001000000a878110016000000f107000005000000108b11002b0000003b8b1100150000007a01000015000000be7811000b000000c978110026000000ef78110008000000f778110006000000f777110001000000a878110016000000fe070000050000007372632f6c6962636f72652f7374722f6d6f642e72736279746520696e64657820206973206e6f742061206368617220626f756e646172793b20697420697320696e7369646520202862797465732029206f6620600000004679110002000000307911001600000054040000110000003079110016000000480400002800000000000000000000007372632f6c6962636f72652f666d742f6d6f642e72732e2e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000f8030000000000000000000000000000000000000000000000000000000000000000feffffffffbfb6000000000000000000ff070000000000f8ffff0000010000000000000000000000c09f9f3d0000000002000000ffffff0700000000000000000000c0ff01000000000000f80f20f08411004a0000004087110000020000408911003a00000000010203040506070809080a0b0c0d0e0f10111213140215161718191a1b1c1d1e1f2002020202020202020202210202020202020202020202020202222324252602270228020202292a2b022c2d2e2f300202310202023202020202020202023302023402020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202023502360237020202020202020238023902020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202023a3b3c020202023d02023e3f4041424344454602020247020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202024802020202020202020202024902020202023b020001020202020302020202040205060202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020207020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020200010305050606030706080809110a1c0b190c140d120e0d0f0410031212130916011705180219031a071c021d011f1620032b042c022d0b2e01300331023201a702a902aa04ab08fa02fb05fd04fe03ff09ad78798b8da23057588b8c901c1ddd0e0f4b4cfbfc2e2f3f5c5d5fb5e2848d8e9192a9b1babbc5c6c9cadee4e5ff00041112293134373a3b3d494a5d848e92a9b1b4babbc6cacecfe4e500040d0e11122931343a3b4546494a5e646584919b9dc9cecf0d112945495764658d91a9b4babbc5c9dfe4e5f0040d1145496465808184b2bcbebfd5d7f0f183858ba4a6bebfc5c7cecfdadb4898bdcdc6cecf494e4f57595e5f898e8fb1b6b7bfc1c6c7d71116175b5cf6f7feff800d6d71dedf0e0f1f6e6f1c1d5f7d7eaeafbbbcfa16171e1f46474e4f585a5c5e7e7fb5c5d4d5dcf0f1f572738f747596972f5f262e2fa7afb7bfc7cfd7df9a409798308f1fc0c1ceff4e4f5a5b07080f10272feeef6e6f373d3f42459091feff536775c8c9d0d1d8d9e7feff00205f2282df048244081b04061181ac0e80ab351e1580e003190801042f043404070301070607110a500f1207550802041c0a090308030703020303030c0405030b06010e15053a0311070605100757070207150d500443032d03010411060f0c3a041d255f206d046a2580c80582b0031a0682fd035907150b1709140c140c6a060a061a0659072b05460a2c040c040103310b2c041a060b0380ac060a061f414c042d0374083c030f033c0738082b0582ff1118082f112d032010210f808c048297190b158894052f053b07020e180980b030740c80d61a0c0580ff0580b605240c9bc60ad23010848d033709815c1480b80880c73035040a06380846080c06740b1e035a0459098083181c0a16094808808a06aba40c170431a10481da26070c050580a511816d1078282a064c04808d0480be031b030f0d0006010103010402080809020a050b02100111041205131114021502170219041c051d0824016a036b02bc02d102d40cd509d602d702da01e005e102e802ee20f004f906fa020c273b3e4e4f8f9e9e9f060709363d3e56f3d0d104141836375657bd35cecfe01287898e9e040d0e11122931343a4546494a4e4f64655a5cb6b71b1ca8a9d8d909379091a8070a3b3e66698f926f5feeef5a629a9b2728559da0a1a3a4a7a8adbabcc4060b0c151d3a3f4551a6a7cccda007191a22253e3fc5c604202325262833383a484a4c50535556585a5c5e606365666b73787d7f8aa4aaafb0c0d00c72a3a4cbcc6e6f5e227b0503042d036504012f2e80821d03310f1c0424091e052b0544040e2a80aa06240424042808340b018090813709160a088098390363080930160521031b05014038044b052f040a070907402027040c0936033a051a07040c07504937330d33072e080a81261f808128082a808617094e041e0f430e19070a0647092709750b3f412a063b050a0651060105100305808b602048080a80a65e22450b0a060d1339070a362c041080c03c64530c0180a0451b4808531d398107460a1d03474937030e080a0639070a81361980c7320d839b66750b80c48abc842f8fd18247a1b98239072a040260260a460a28051382b05b654b0439071140041c97f80882f3a50d811f3103110408818c89046b050d03090710936080f60a73086e1746809a140c570919808781470385420f1585502b80d52d031a040281703a0501850080d7294c040a04028311444c3d80c23c06010455051b3402810e2c04640c560a0d035d033d391d0d2c040907020e06809a83d60a0d030b05740c59070c140c0438080a0628081e527703310380a60c14040305030d06856a000000d0841100200000002700000019000000d0841100200000002800000020000000d0841100200000002a00000019000000d0841100200000002b00000018000000d0841100200000002c0000002000000000000000000000007372632f6c6962636f72652f756e69636f64652f626f6f6c5f747269652e72730000c0fbef3e00000000000e0000000000000000000000000000f8fffbffffff0700000000000014fe21fe000c00000002000000000000501e2080000c00004006000000000000108639020000002300be2100000c0000fc02000000000000d01e20c0000c0000000400000000000040012080000000000011000000000000c0c13d60000c0000000200000000000090443060000c00000003000000000000581e2080000c00000000845c8000000000000000000000f207807f000000000000000000000000f21f003f000000000000000000030000a002000000000000fe7fdfe0fffeffffff1f40000000000000000000000000e0fd66000000c301001e006420002000000000000000e00000000000001c0000001c0000000c0000000c00000000000000b03f40fe0f200000000000380000000000006000000000020000000000008701040e00008009000000000000407fe51ff89f000000000000ff7f0f0000000000f0170400000000f80f00030000003c3b00000000000040a303000000000000f0cf000000f7fffd211003fffffffffffffffb00100000000000000000ffffffff01000000000000800300000000000000008000000000ffffffff0000000000fc00000000000600000000000000000080f73f000000c0000000000000000000000300440800006000000030000000ffff038000000000c03f000080ff030000000000070000000000c833000000002000000000000000007e660008100000000000100000000000009dc1020000000030400000000000202100000000004000000000ffff0000ffff00000000000000000001000000020003000000000000000000000000000000000000000000000000000004000005000000000000000006000000000000000007000008090a000b0c0d0e0f000010111200001314151600001718191a1b001c0000001d0000000000001e1f202100000000002200230024252600000000270000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002829000000000000000000000000000000002a2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000002d2e00002f0000000000000000000000000000000000000000000000000000000000003031320000000000000000000000000000000000000000003300000029000000000000340000000000000000000000000000000000000000000000350036000000000000000000000000000000000000000000000000000037380000383838390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000001000000000000000000c0076ef0000000000087000000006000000000000000f0000000c0ff01000000000002000000000000ff7f0000000000008003000000000078060700000080ef1f000000000000000800030000000000c07f001e000000000000000000000080d34000000080f8070000030000000000005801008000c01f1f0000000000000000ff5c00004000000000000000000000f9a50d000000000000000000000000803cb00100003000000000000000000000f8a70100000000000000000000000028bf00000000e0bc0f0000000000000080ff060000f00c01000000fe0700000000f87980007e0e0000000000fc7f03000000000000000000007fbf0000fcfffffc6d000000000000007eb4bf000000000000000000a3000000000000000000000018000000000000001f000000000000007f0000800000000000000080070000000000000000600000000000000000a0c307f8e70f0000003c00001c00000000000000ffffffffffff7ff8ffffffffff1f2000100000f8feff00007ffffff9db0700000000000000f0000000007f0000000000f00700000000000000000000ffffffffffffffffffffffffffffffffffff000063616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c75657372632f6c6962636f72652f6f7074696f6e2e7273626567696e203c3d20656e642028203c3d2029207768656e20736c6963696e672060206973206f7574206f6620626f756e6473206f66206066616c736574727565426f72726f774572726f72426f72726f774d75744572726f7270616e69636b6564206174200000e18b110001000000e28b1100030000004876110000000000e08b110001000000e08b1100010000003a27272c2000000048761100000000003b8b1100150000008e040000050000004876110000000000108c1100020000003a200000248c1100150000003c040000050000007372632f6c6962636f72652f726573756c742e72735b5d290a000000d40000000c00000004000000d5000000d6000000d70000002c0a2c20510000000400000004000000d8000000d9000000da00000020202020207b20207b0a207d7d28280a2c000000510000000400000004000000db000000510000000400000004000000dc0000004e6f6e65536f6d65557466384572726f7276616c69645f75705f746f6572726f725f6c656e000000510000000400000004000000dd0000004572726f720041e899c6000b08000000000000000000d1a403046e616d6501c8a403ff04000e6578745f626c616b65325f323536011f6578745f6765745f616c6c6f63617465645f6368696c645f73746f7261676502176578745f636c6561725f6368696c645f73746f72616765030c6578745f74776f785f313238040f6578745f7365745f73746f7261676505146578745f6765745f73746f726167655f696e746f06116578745f636c6561725f73746f7261676507166578745f6b696c6c5f6368696c645f73746f7261676508196578745f6765745f616c6c6f63617465645f73746f72616765090e6578745f7072696e745f757466380a166578745f6368696c645f73746f726167655f726f6f740b156578745f7365745f6368696c645f73746f726167650c126578745f737232353531395f7665726966790d0d6578745f7072696e745f6865780e106578745f69735f76616c696461746f720f156578745f6c6f63616c5f73746f726167655f67657410216578745f6c6f63616c5f73746f726167655f636f6d706172655f616e645f73657411176578745f737232353531395f7075626c69635f6b65797312116578745f6e6574776f726b5f737461746513106578745f737232353531395f7369676e14166578745f7375626d69745f7472616e73616374696f6e15156578745f6c6f63616c5f73746f726167655f73657416146578745f656432353531395f67656e657261746517146578745f737232353531395f67656e657261746518106578745f636c6561725f70726566697819166578745f73616e64626f785f6d656d6f72795f6e65771a1b6578745f73616e64626f785f6d656d6f72795f74656172646f776e1b176578745f73616e64626f785f696e7374616e74696174651c126578745f73616e64626f785f696e766f6b651d1d6578745f73616e64626f785f696e7374616e63655f74656172646f776e1e236578745f626c616b65325f3235365f656e756d6572617465645f747269655f726f6f741f106578745f73746f726167655f726f6f7420186578745f73746f726167655f6368616e6765735f726f6f7421126578745f656432353531395f76657269667922166578745f73616e64626f785f6d656d6f72795f67657423166578745f73616e64626f785f6d656d6f72795f736574240b6578745f74776f785f3634250a6578745f6d616c6c6f6326086578745f6672656527693c636f72653a3a697465723a3a61646170746572733a3a46696c7465724d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a686233613264373361363531643330313428693c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c616c6c6f633a3a7665633a3a496e746f497465723c543e3e3e3a3a737065635f657874656e643a3a6839353139326336653130323738616638290c5f5f727573745f616c6c6f632a0e5f5f727573745f7265616c6c6f632b4b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a68383837613138326238666137666366612c08727573745f6f6f6d2d34616c6c6f633a3a7261775f7665633a3a63617061636974795f6f766572666c6f773a3a68326562373664643539623264336265342e0e5f5f727573745f6465616c6c6f632f30636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a683461633562326331643134663633643930543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6861386438343236613162343632653038316b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68366532383865303936326331363036663248616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a616c6c6f636174655f696e3a3a7b7b636c6f737572657d7d3a3a6830303735663439666263346466363232337d7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72202851302c205230293e3a3a6465636f64653a3a683765306432313465663934363736646134135f5f727573745f616c6c6f635f7a65726f65643536636f72653a3a736c6963653a3a736c6963655f696e6465785f6f726465725f6661696c3a3a6838613764636139656338646233313932362d616c6c6f633a3a7665633a3a5665633c543e3a3a726573697a653a3a6864313234663032323030616464623764372d616c6c6f633a3a7665633a3a5665633c543e3a3a72657461696e3a3a68316138316361326661643163313136613836636f72653a3a70616e69636b696e673a3a70616e69635f626f756e64735f636865636b3a3a686135653366323238656436353166623939443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68303665613630326633653263366337613a4b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a68643039383066323966373732663561313b543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68313163383931333362633739643763393c753c73725f7072696d6974697665733a3a67656e657269633a3a6865616465723a3a4865616465723c4e756d6265722c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68323363313238346662306239343163653d543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68366430366636633938313632353435323e543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68383766633464333234656162663437363f543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a686531623639643464646330366335626640543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a686537386161653739663139396662383441543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a686663633936376334616338346238656142513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a683234376431616632323437663235333643513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a683939313139333763616435303563653344513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a686234373062623433636165626133326345723c73725f7072696d6974697665733a3a67656e657269633a3a6469676573743a3a4469676573744974656d3c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6835663131386236383664333738303838463f7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a6838646434653064356163616139303738476c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a683030323930663135306234653936343848783c73726d6c5f696e64696365733a3a616464726573733a3a416464726573733c4163636f756e7449642c4163636f756e74496e6465783e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6866333466643738386639303838346163497b3c73726d6c5f696e64696365733a3a616464726573733a3a416464726573733c4163636f756e7449642c4163636f756e74496e6465783e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68323934613638626137653239326439334a463c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68343761333236636537323361633565324b4e73725f7072696d6974697665733a3a67656e657269633a3a6469676573743a3a4469676573743c486173683e3a3a636f6e766572745f66697273743a3a68333733343832616264373635363237654c7a3c636f72653a3a697465723a3a61646170746572733a3a46696c7465724d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a7b7b636c6f737572657d7d3a3a68323762383464363361336331316562344d4d73726d6c5f636f6e7472616374733a3a657865633a3a457865637574696f6e436f6e746578743c542c562c4c3e3a3a696e7374616e74696174653a3a68613433343935613162326233363937624e81013c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6e74726163745f6578697374733a3a68663134376335393033616266303061364f4b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6861333237333735633637383338306265503173726d6c5f636f6e7472616374733a3a657865633a3a7472616e736665723a3a6832343336613236633030393164663866513973726d6c5f636f6e7472616374733a3a7761736d3a3a636f64655f63616368653a3a6c6f61643a3a686662353936636263633431623732653752593c73726d6c5f636f6e7472616374733a3a7761736d3a3a5761736d566d2061732073726d6c5f636f6e7472616374733a3a657865633a3a566d3c543e3e3a3a657865637574653a3a6863393839663736646330636531633538532e636f72653a3a726573756c743a3a756e777261705f6661696c65643a3a68653664623630383563633433383962375430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a686438306462613131363363396237326455783c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6d6d69743a3a6837323735646631646462373635346564568c013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a656e737572655f63616e5f77697468647261773a3a6838383139643032303437646533313265574f73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e3a3a7365745f62616c616e63653a3a68336135306239613864636266666263315829636f72653a3a70616e69636b696e673a3a70616e69633a3a68383437343861613365313530303538645930636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68383062346238373239353835363462665a4673726d6c5f636f6e7472616374733a3a657865633a3a457865637574696f6e436f6e746578743c542c562c4c3e3a3a63616c6c3a3a68306136656366356637646262353833615b4273726d6c5f636f6e7472616374733a3a72656e743a3a7472795f65766963745f6f725f616e645f7061795f72656e743a3a68393531613662346431663131303833625c3c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a68396233393231646336386338393434395d2b616c6c6f633a3a736c6963653a3a6d657267655f736f72743a3a68323766613130313034633634613863385e34636f72653a3a736c6963653a3a736c6963655f696e6465785f6c656e5f6661696c3a3a68303636323330386261383262383836375f2d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a68393339343365636337346665373436336034636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a6834643538303031323139303934663664612e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a6861643261613439303934623963663334623c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6833376135653238316261313630393262632d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6865333035633335633939613563313432646b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7536343e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6831363061323131393563633731663033656c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683031383665396336343938613431323666713c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a686661646564366534366630393035376467713c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c7536343e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a686364323238356130613465303136373568443c636f72653a3a666d743a3a417267756d656e747320617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a683966656139363163383337616565343169303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68343031313136626439613631373837316a2d636f72653a3a70616e69636b696e673a3a70616e69635f666d743a3a68326131633365306237353630393832396b723c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68636236386434323961396339393730626c303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68633461353138633662636639643863366d89013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6465706f7369745f6372656174696e673a3a68393832333930663535663765663337326e3573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a6765743a3a68393461653532316564326531613362376f8d013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6d616b655f667265655f62616c616e63655f62653a3a6866623835643365313131633264383035703573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a6765743a3a6866643535373663643531646330616334717f3c73726d6c5f696e64696365733a3a4d6f64756c653c543e2061732073726d6c5f73797374656d3a3a4f6e4e65774163636f756e743c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6f6e5f6e65775f6163636f756e743a3a6863613139653633306131343864396635724073726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6576656e745f696e64657865643a3a6833306164626137303636363031363563733f73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a7365745f667265655f62616c616e63653a3a6861396562623938653737656335326336743873726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a74616b653a3a6832393234623866333664303461646437753673726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6b696c6c5f73746173683a3a6835376439393863333663306362326637763773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683764623730313338656531343930393477d5013c73726d6c5f73657373696f6e3a3a4e6578744b6579733c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a67656e657261746f723a3a53746f72616765446f75626c654d61703c616c6c6f633a3a7665633a3a5665633c75383e2c3c542061732073726d6c5f73657373696f6e3a3a54726169743e3a3a56616c696461746f7249642c3c542061732073726d6c5f73657373696f6e3a3a54726169743e3a3a4b6579733e3e3a3a6b65795f666f723a3a6836656264623531353334333866306661788d016e6f64655f72756e74696d653a3a5f494d504c5f4445434f44455f464f525f53657373696f6e4b6579733a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72206e6f64655f72756e74696d653a3a53657373696f6e4b6579733e3a3a6465636f64653a3a683561323332613463366163363431313379f3013c73726d6c5f73657373696f6e3a3a4b65794f776e65723c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a67656e657261746f723a3a53746f72616765446f75626c654d61703c616c6c6f633a3a7665633a3a5665633c75383e2c287375627374726174655f7072696d6974697665733a3a63727970746f3a3a4b65795479706549642c20616c6c6f633a3a7665633a3a5665633c75383e292c3c542061732073726d6c5f73657373696f6e3a3a54726169743e3a3a56616c696461746f7249643e3e3a3a6b65795f666f723a3a68313632656166323566323535313330357a81013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a77697468647261773a3a68393937343763623132396566663633637b3e73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a76657374696e675f62616c616e63653a3a68626135333633393137393139353261377c3473726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6c6f636b733a3a68616564326164626136343730303962367d3573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a6765743a3a68626466616138376439316239343663317e483c5b543b205f5d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68636239313066666238623665666266387f3673726d6c5f626162653a3a4d6f64756c653c543e3a3a646f5f696e697469616c697a653a3a68613261613737356631363337393135388001d5017375627374726174655f636f6e73656e7375735f626162655f7072696d6974697665733a3a6469676573743a3a5f494d504c5f4445434f44455f464f525f526177426162655072654469676573743a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72207375627374726174655f636f6e73656e7375735f626162655f7072696d6974697665733a3a6469676573743a3a526177426162655072654469676573743e3a3a6465636f64653a3a683165383633313231663531373333636181013573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a6765743a3a686134623264616561303834363264313882013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a686234363361376531636539623163366283013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6835303765393466663935386165383035840186013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a746f74616c5f62616c616e63653a3a68356566336637643432396336346530358501653c73726d6c5f62616c616e6365733a3a54616b65466565733c542c493e2061732073725f7072696d6974697665733a3a7472616974733a3a5369676e6564457874656e73696f6e3e3a3a76616c69646174653a3a683237323639383463613634373132393286013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683532333239356264323838303133626487014b73725f7072696d6974697665733a3a7472616974733a3a4163636f756e744964436f6e76657273696f6e3a3a696e746f5f6163636f756e743a3a683464353134633738623636366364396388013573726d6c5f617574686f72736869703a3a4d6f64756c653c543e3a3a617574686f723a3a686262323839663234366633643538623189013d73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a68316630663962613433636433613737368a013f73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a68346633386537396538316634623832368b016f3c73726d6c5f62616c616e6365733a3a5f5f476574427974655374727563744672656542616c616e63653c542c493e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68386331646135303462653136623834328c014373726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a7365745f72657365727665645f62616c616e63653a3a68313131313562353038383462333065358d014873726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68373634656336386538393863626631328e018e013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6465706f7369745f696e746f5f6578697374696e673a3a68653361653433333566633330386231318f018c013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a657874656e645f6c6f636b3a3a68356130643538663138373639323133639001483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a6832396131323632666462363630623166910189013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7365745f6c6f636b3a3a6866313962383864373035373235333031920191013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a736c6173685f72657365727665643a3a683862666531396563663561303939353993018a013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a726573657276653a3a683538303162336636373431313931613594018c013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a756e726573657276653a3a6834353831346134613436316461663664950185013c28412c20422c20432c20442c20452c20462c20472c20482c20492c204a2c204b2c204c2c204d2c204e2c204f2c20502c20512c2052292061732073725f7072696d6974697665733a3a7472616974733a3a4f6e46696e616c697a653c4e756d6265723e3e3a3a6f6e5f66696e616c697a653a3a686632353832623439663864373239383596013673726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a70726f706f73616c733a3a683166393933303265646138393366336497013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a686361626666313438336530643334616298013673726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6c6f673a3a683732316430323263613030363533366399013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a68396337653466346638313763633235669a013873726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a74616b653a3a68333130646536303733613730373564639b012e636f72653a3a6f7074696f6e3a3a6578706563745f6661696c65643a3a68336536643062643066633434316138639c013673726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a74616b653a3a68373965643430653861373130303239309d01703c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a68323061393538343339306430316631629e01303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68346462656130333936616137316335379f013773726d6c5f626162653a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6830343636333139393732616235306662a0013973726d6c5f626162653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6866323635643031666539653365363837a1016c3c73726d6c5f626162653a3a5f5f476574427974655374727563745365636f6e64617279536c6f74733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836306236326130356662343438356664a2014273726d6c5f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6864336438666230353938383830623432a30197013c73726d6c5f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4578706563746564426c6f636b54696d6544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861393234636630663233333436373565a40193013c73726d6c5f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a45706f63684475726174696f6e44656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866333562613166356534306239333038a5014473726d6c5f737570706f72743a3a7472616974733a3a5369676e6564496d62616c616e63653c422c503e3a3a6d657267653a3a6836353130623436323432343138393034a6014173726d6c5f737570706f72743a3a7472616974733a3a496d62616c616e63653a3a6d617962655f73756273756d653a3a6832353363313936336130343663323232a7013b73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6866613261633065383362346337623066a8013d73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6863303933316539396261316563326434a9014673726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6836346563366239623637393438383937aa018e013c73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4275726e44656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865663930613064323235363663333833ab01870173725f7072696d6974697665733a3a5f494d504c5f454e434f44455f464f525f50657262696c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073725f7072696d6974697665733a3a50657262696c6c3e3a3a656e636f64653a3a6832303537333866626531326339393464ac0195013c73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5370656e64506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864363365653733343139336537323035ad0196013c73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a50726f706f73616c426f6e6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833636231353437336665363263393339ae013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862346566346230303163363338363236af01453c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a6765743a3a6864323865646665323862316438626461b001437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6838316138626637386664393238396262b101483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a6838643839376466316463383730353034b201303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6864343335386361386131336134613461b301313c73747220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832353334343133333961336462333838b40149636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207573697a653e3a3a666d743a3a6830303232623134376237336161363832b5012f636f72653a3a666d743a3a6e756d3a3a696d703a3a666d745f7536343a3a6835313561363538333432643134653438b60135636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a6864326239326336376133363832663736b7019f013c73725f7072696d6974697665733a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6837643463383761363231356161613164b8017f6e6f64655f72756e74696d653a3a5f494d504c5f4445434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72206e6f64655f72756e74696d653a3a43616c6c3e3a3a6465636f64653a3a6834323762633232356334336538343738b901a5013c73725f7072696d6974697665733a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e2061732073725f7072696d6974697665733a3a7472616974733a3a436865636b61626c653c4c6f6f6b75703e3e3a3a636865636b3a3a6832623933373833616633313036653937ba01b3013c73726d6c5f73797374656d3a3a426c6f636b486173683c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265722c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a486173683e3e3a3a6765743a3a6836376662386130366633633630306236bb013473726d6c5f696e64696365733a3a4d6f64756c653c543e3a3a656e756d5f7365743a3a6863386132613366373030373061343833bc0182016e6f64655f72756e74696d653a3a5f494d504c5f454e434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206e6f64655f72756e74696d653a3a43616c6c3e3a3a656e636f64655f746f3a3a6832656437646539303161323035633462bd01593c73725f7072696d6974697665733a3a416e795369676e61747572652061732073725f7072696d6974697665733a3a7472616974733a3a5665726966793e3a3a7665726966793a3a6834613134356435376535326338343963be013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6839353062666164353137373934643662bf01437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6864363166323962316336666636613036c0013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6835376439383535326565653232646339c1014373726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6863346436656162623065346166643463c2014e73726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6865656661363966306265383130353437c3019f013c73726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5265706f72744c6174656e637944656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863633261373461633262363466313432c4019c013c73726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a57696e646f7753697a6544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862643336313466363737666463623930c5014073726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a63616e6469646174655f7265675f696e666f3a3a6836356532366463323666646564326338c6013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830396161353530393261393136306536c7013873726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a616c6c5f766f746572733a3a6835626330333038373734356266626433c801bc013c73726d6c5f656c656374696f6e733a3a566f746572733c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c7533322c616c6c6f633a3a7665633a3a5665633c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3e3e3a3a6765743a3a6836343530373839643631313335623537c9013a73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a617070726f76616c735f6f663a3a6834636531323262386364616632373164ca01ab023c73726d6c5f656c656374696f6e733a3a566f746572496e666f4f663c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c73726d6c5f656c656374696f6e733a3a566f746572496e666f3c3c3c542061732073726d6c5f656c656374696f6e733a3a54726169743e3a3a43757272656e63792061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a42616c616e63653e3e3e3a3a6765743a3a6839353435373563623033623266376164cb01437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830306266613131376363643966636132cc013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6834663737383166383261323335656539cd013e73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6834323032333065653761646566366563ce01713c73726d6c5f656c656374696f6e733a3a5f5f4765744279746553747275637443616e646964617465436f756e743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832313632376138373035633133303162cf01713c73726d6c5f656c656374696f6e733a3a5f5f476574427974655374727563745265676973746572496e666f4f663c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834323831373366323661626463646162d0014773726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6864616130663132633563653965326435d10199013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a564f5445525f5345545f53495a4544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836303730626637383966323937336166d20197013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e67506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839353566336533306138393966303763d3019e013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a496e6163746976654772616365506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836356636383762373536303464663736d40195013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4361727279436f756e7444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836376234376230363730366262646464d50194013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e6746656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838306538626439313063303464353137d60195013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e67426f6e6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863343535613630633138373737646633d70198013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a43616e646964616379426f6e6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833643839663436306138616365373238d801493c73726d6c5f656c656374696f6e733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6836363738326430343830333932303333d9015d3c73726d6c5f656c656374696f6e733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6865313237343265643436323863313363da01323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6835376666316531393764316133666165db013e73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a646f5f7365745f617070726f76616c733a3a6862393861646234643932613964643436dc013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830613136663763326436636162396437dd013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834303933656263613764633935336334de013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864653433636134386432663839633832df0195013c73726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572735f736f727465643a3a6862323334656531656565643065363330e0013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830346139336461663937383038353530e1013a73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a72656d6f76655f766f7465723a3a6837333663623433653862356165653863e201483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a6835326537643661333538353933376237e3016b3c636f72653a3a697465723a3a61646170746572733a3a526573756c745368756e743c492c453e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6831376535333234653963653362376639e4016f3c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6830663235353062306664313165336230e501613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6831393036623737303332303538303032e6014b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6838323661353839396163653264643933e701793c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f62616c616e63653a3a6831633536643839383565616533346136e801793c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f73746f726167653a3a6838323365336331613035316361383235e9017b3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f636f64655f686173683a3a6837656235376339626262656132613466ea017d3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6e74726163745f6578697374733a3a6863363036643063313939636263343237eb0180013c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f72656e745f616c6c6f77616e63653a3a6836346138616262393064333362666338ec01743c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6d6d69743a3a6830613039663435383032383038326239ed01723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6833666335383965313231316634363262ee0130636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6864353337376434623436666631393963ef01723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6839653635346335653663363733626330f001483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a6830323030313266383334633262363030f1017d3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f62616c616e63653a3a6864636131353435636431626232323536f2017d3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f73746f726167653a3a6865623963366463656435363161666630f3017f3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f636f64655f686173683a3a6830336532333238633564323665643838f40184013c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f72656e745f616c6c6f77616e63653a3a6836643561326232386136333236613363f50148616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a6831646664313862353264343937383138f601a0013c73726d6c5f696d5f6f6e6c696e653a3a5265636569766564486561727462656174732061732073726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a67656e657261746f723a3a53746f72616765446f75626c654d61703c7533322c7533322c616c6c6f633a3a7665633a3a5665633c75383e3e3e3a3a7072656669785f666f723a3a6835613938623863393466316234356134f7014273726d6c5f636f6e7472616374733a3a7761736d3a3a707265706172653a3a707265706172655f636f6e74726163743a3a6866303437623561343464646262646531f801437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6837323564303066303039383134333333f901860173726d6c5f64656d6f63726163793a3a5f494d504c5f4445434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f64656d6f63726163793a3a43616c6c3c543e3e3a3a6465636f64653a3a6834346230653034373133306439393834fa018a0173726d6c5f636f6c6c6563746976653a3a5f494d504c5f4445434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a6465636f64653a3a6832616233336636646466353633306434fb018b0173726d6c5f636f6e7472616374733a3a5f494d504c5f4445434f44455f464f525f5363686564756c653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f636f6e7472616374733a3a5363686564756c653e3a3a6465636f64653a3a6861613264383132353633386637633666fc013f7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a6833666166363831343034336663383630fd018d0173726d6c5f636f6c6c6563746976653a3a5f494d504c5f454e434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a656e636f64655f746f3a3a6835333135326365646331366166383464fe018e0173726d6c5f636f6e7472616374733a3a5f494d504c5f454e434f44455f464f525f5363686564756c653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6e7472616374733a3a5363686564756c653e3a3a656e636f64655f746f3a3a6864383034666435326663303564373531ff01437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68346132326137353166353039353936328002493c73726d6c5f696d5f6f6e6c696e653a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68313036663538373734343235316465348102673c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a686234353032666435333739313233616382023273726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a626f6e6465643a3a68323633646436393437646235363265358302c9023c73726d6c5f7374616b696e673a3a4c65646765723c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c73726d6c5f7374616b696e673a3a5374616b696e674c65646765723c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c3c542061732073726d6c5f7374616b696e673a3a54726169743e3a3a43757272656e63792061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a42616c616e63653e3e3e3a3a6765743a3a6833666131383938383333316666383663840284016e6f64655f72756e74696d653a3a5f494d504c5f454e434f44455f464f525f4576656e743a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206e6f64655f72756e74696d653a3a4576656e743e3a3a656e636f64655f746f3a3a68393762653937383763633865626266318502a20173726d6c5f636f6c6c6563746976653a3a5f494d504c5f454e434f44455f464f525f5261774576656e743a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6c6c6563746976653a3a5261774576656e743c486173682c4163636f756e7449642c493e3e3a3a656e636f64655f746f3a3a68303331646338363335326565636231328602406e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f73797374656d3a3a68333261646664636161383334393535328702416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f696e64696365733a3a68613034396361643731306365653430368802426e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f62616c616e6365733a3a68363238613533396333393637636462638902416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7374616b696e673a3a68623337316439313866393336343062358a02416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f73657373696f6e3a3a68363832643363396535326631336462668b02436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f64656d6f63726163793a3a68666665633839356537663861633666378c024e6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f636f6c6c6563746976655f496e7374616e6365313a3a68373063633031333665633365643135358d02436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f656c656374696f6e733a3a68663639336437313461396535656238628e024e6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6d656d626572736869705f496e7374616e6365313a3a68366637666234666531326366343937318f02416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6772616e6470613a3a68386566353837313562643065323738669002426e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f74726561737572793a3a68633765303238653734336464626362399102436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f636f6e7472616374733a3a686261316237366535356436393037303692023e6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7375646f3a3a68353863303666626565323936373235629302436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f696d5f6f6e6c696e653a3a68643332616335396531626334643066369402653c6e6f64655f72756e74696d653a3a43616c6c2061732073725f7072696d6974697665733a3a776569676874733a3a4765744469737061746368496e666f3e3a3a6765745f64697370617463685f696e666f3a3a68346461636332356639643933386631339502583c6e6f64655f72756e74696d653a3a43616c6c2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68366338306263356133666633323537319602437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a683435303231343364633366333963663397023973726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a7265776172645f62795f6964733a3a686263393430313534393466383564636298023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68663832653331633661353963616365319902437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68623639633438353461383832303864389a024a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a68323332343564323130376336323965669b025d3c73726d6c5f636f6e7472616374733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68623238613734653764656536616261629c023573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a7075743a3a68656132383836636363373062353139399d0295013c73726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572735f736f727465643a3a68666338373537393139636464626330359e024a73726d6c5f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733a3a7365745f6d656d626572735f736f727465643a3a68373334353435373836393236393136389f02603c73726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6866663161323763383665616361336235a002603c73726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6839346636343562633634613438323938a1025d3c73726d6c5f64656d6f63726163793a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6834633966363032616161366635323337a2025b3c73726d6c5f7374616b696e673a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6835306130386461383561623933383337a3025b3c73726d6c5f696e64696365733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6863663263336164363030366362333537a4023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6837636234326363623163646638656430a5023e73726d6c5f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6837336434626463343032333438373839a6023c73726d6c5f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6839653664653439383632343434633638a702753c73726d6c5f696d5f6f6e6c696e653a3a5f5f476574427974655374727563745265636569766564486561727462656174733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861343834393433303832393066623730a8020c436f72655f76657273696f6ea90212436f72655f657865637574655f626c6f636baa02b50173725f7072696d6974697665733a3a67656e657269633a3a626c6f636b3a3a5f494d504c5f4445434f44455f464f525f426c6f636b3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073725f7072696d6974697665733a3a67656e657269633a3a626c6f636b3a3a426c6f636b3c4865616465722c45787472696e7369633e3e3a3a6465636f64653a3a6838366339653938303663353462323361ab027173726d6c5f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65733e3a3a696e697469616c697a655f626c6f636b3a3a6836646364623637373930646561363237ac024173725f7072696d6974697665733a3a67656e657269633a3a656e636f64655f776974685f7665635f7072656669783a3a6830323431303037333433373866356263ad027f3c7375627374726174655f7072696d6974697665733a3a6861736865723a3a626c616b65323a3a426c616b65324861736865722061732073725f696f3a3a696d703a3a6578743a3a45787465726e5472696543727970746f3e3a3a6f7264657265645f747269655f726f6f743a3a6864383135623231376565623662353738ae027973726d6c5f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65733e3a3a6170706c795f65787472696e7369635f776974685f6c656e3a3a6864353937356438633730303938303136af024373726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a6e6f74655f66696e69736865645f65787472696e736963733a3a6866613138303832393933316463363535b0023373726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a66696e616c697a653a3a6864336430636135396133636463366566b10215436f72655f696e697469616c697a655f626c6f636bb202114d657461646174615f6d65746164617461b302483c5b545d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6832636633346366303231366637336539b402683c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6832383038363338326364316363353830b502683c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6864386466343664663832656362323136b6021c426c6f636b4275696c6465725f6170706c795f65787472696e736963b7021b426c6f636b4275696c6465725f66696e616c697a655f626c6f636bb8027c7072696d69746976655f74797065733a3a636f6465633a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72207072696d69746976655f74797065733a3a483235363e3a3a7573696e675f656e636f6465643a3a6831653364343864633134353231656162b90220426c6f636b4275696c6465725f696e686572656e745f65787472696e73696373ba023873726d6c5f74696d657374616d703a3a657874726163745f696e686572656e745f646174613a3a6831356665643666626266303530666134bb021c426c6f636b4275696c6465725f636865636b5f696e686572656e7473bc0218426c6f636b4275696c6465725f72616e646f6d5f73656564bd023173726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a72616e646f6d3a3a6862666535396239643439333736653863be022b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6ebf025673725f7072696d6974697665733a3a7472616e73616374696f6e5f76616c69646974793a3a56616c69645472616e73616374696f6e3a3a636f6d62696e655f776974683a3a6832373835623536643266616336303836c0023573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a6765743a3a6866646234303435383937333161333065c102214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b6572c202214772616e6470614170695f6772616e6470615f70656e64696e675f6368616e6765c302204772616e6470614170695f6772616e6470615f666f726365645f6368616e6765c4021e4772616e6470614170695f6772616e6470615f617574686f726974696573c50214426162654170695f737461727475705f64617461c6020d426162654170695f65706f6368c7023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830643931356335646261613239393435c8023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6866393732346531363966663634633565c9023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6836323062323465303635313838313338ca024b3c5b543b205f5d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6835363136613262363566353139636235cb0218436f6e73656e7375734170695f617574686f726974696573cc022153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b657973cd0227636f72653a3a7374723a3a66726f6d5f757466383a3a6837633338356538383431666465623434ce023a73726d6c5f6772616e6470613a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6831633336323939633666303661646664cf023c73726d6c5f6772616e6470613a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6830663633633535633736653431383736d00230636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6830306439646362643565373738643963d102663c73726d6c5f6772616e6470613a3a5f5f4765744279746553747275637453746174653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837346563633864653435386537336131d2023a73726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6862643337373331386533303265646230d3023c73726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6838613636306438646635323233653934d402703c73726d6c5f617574686f72736869703a3a5f5f47657442797465537472756374446964536574556e636c65733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864333832663030376230393064666665d5024573726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6830383763353238386134626163663933d60299013c73726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a44454455505f4b45595f50524546495844656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863336638346135306137323531323930d7028c013c73726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a54776f783634436f6e6361742061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654861736865723e3a3a686173683a3a6832373336666232393066643533613963d802437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6835623264626138643338653935333963d9028a013c73726d6c5f73657373696f6e3a3a4d6f64756c653c543e2061732073725f7072696d6974697665733a3a7472616974733a3a4f6e496e697469616c697a653c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a6832633433313034663564613465353663da0286013c73726d6c5f7374616b696e673a3a4d6f64756c653c543e2061732073726d6c5f73657373696f6e3a3a4f6e53657373696f6e456e64696e673c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6f6e5f73657373696f6e5f656e64696e673a3a6862343239383835633937393431623834db0230636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6830346237623962366364623263303261dc02683c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a73697a655f68696e743a3a6837386633396438623462363334636432dd02633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6833636537383730346330633037646361de023e636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a6e74683a3a6830333036613335326664306536333630df023d73726d6c5f617574686f72736869703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6832353961306464656638323635323030e0023f73726d6c5f617574686f72736869703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6835343766383234353438366135306431e102463c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6865306265346464323831666130326239e202663c73726d6c5f636f6e7472616374733a3a7761736d3a3a5761736d566d2061732073726d6c5f636f6e7472616374733a3a657865633a3a566d3c543e3e3a3a657865637574653a3a7b7b636c6f737572657d7d3a3a6837376364383239393538633464386562e3027d3c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6761733a3a6865613734653736656339343830643937e40289013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7365745f73746f726167653a3a6832373065316632663362323166333864e50289013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6765745f73746f726167653a3a6864613734663730636531633637336334e60282013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f63616c6c3a3a6866336337653562636230633739623831e70284013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6372656174653a3a6832383030613732333335366434616137e80284013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72657475726e3a3a6866663931646564376262393861373130e90284013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f63616c6c65723a3a6866663136383535623636653666356463ea0285013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f616464726573733a3a6865333930333962663230646566366134eb0287013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6761735f70726963653a3a6861333563656361346536663234383134ec0286013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6761735f6c6566743a3a6834636537323964363761346535323461ed0285013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f62616c616e63653a3a6863303765646436626337663437373566ee028f013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f76616c75655f7472616e736665727265643a3a6834363264623564633033333630396438ef0284013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72616e646f6d3a3a6832303863363137636665636665616366f00281013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6e6f773a3a6862393735623466653631383265613236f1028b013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f64697370617463685f63616c6c3a3a6864386532323333373533376139663335f20288013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f726573746f72655f746f3a3a6835383732663634316362343037393861f3028a013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f73697a653a3a6861363061613366626132613338623862f4028a013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f726561643a3a6833353139306435663464393830343263f5028b013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f77726974653a3a6838366135616133643265326431343164f6028b013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6465706f7369745f6576656e743a3a6833373733363338346330376532343966f70290013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7365745f72656e745f616c6c6f77616e63653a3a6833613231313531363337613832373733f8028c013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72656e745f616c6c6f77616e63653a3a6838303766353562623462333963623034f90285013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7072696e746c6e3a3a6865336537393162303534636336633031fa028a013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f626c6f636b5f6e756d6265723a3a6839313435306566323232383662386435fb023273725f73616e64626f783a3a696d703a3a64697370617463685f7468756e6b3a3a6837633036386361393732613463396237fc02ad017375627374726174655f7072696d6974697665733a3a73616e64626f783a3a5f494d504c5f4445434f44455f464f525f547970656456616c75653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72207375627374726174655f7072696d6974697665733a3a73616e64626f783a3a547970656456616c75653e3a3a6465636f64653a3a6865333930656237616663366662333531fd02b0017375627374726174655f7072696d6974697665733a3a73616e64626f783a3a5f494d504c5f454e434f44455f464f525f547970656456616c75653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72207375627374726174655f7072696d6974697665733a3a73616e64626f783a3a547970656456616c75653e3a3a656e636f64655f746f3a3a6862316231383534333932323433383632fe023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6833616165313362393663313863393332ff023d73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f65787465726e616c3a3a686437343534353137316163353764326180033b73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f7075626c69633a3a686631616133393731303637323064333981033d73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a7265666572656e64756d5f696e666f3a3a68306262616566353330666666303166348203a9013c73726d6c5f64656d6f63726163793a3a566f74657273466f723c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c7533322c616c6c6f633a3a7665633a3a5665633c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3e3a3a6765743a3a683333353137323362666365643064373783033573726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a766f74655f6f663a3a683664656235633530333236333330366484033d73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a64656c6567617465645f766f7465733a3a683962663262626531393362383839303685033e73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a636c6561725f7265666572656e64756d3a3a68373162616466333130363466343339348603ef013c73726d6c5f64656d6f63726163793a3a446973706174636851756575653c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265722c616c6c6f633a3a7665633a3a5665633c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c283c542061732073726d6c5f64656d6f63726163793a3a54726169743e3a3a50726f706f73616c2c20753332293e3e3e3e3a3a6765743a3a683538333165316536633832386165333987033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683133316361386331656532306636626688033f73726d6c5f6d656d626572736869703a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a686532326235316134333034613739386489034173726d6c5f6d656d626572736869703a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a68353738613465313834383037306662648a0334636f72653a3a736c6963653a3a3c696d706c205b545d3e3a3a636f6e7461696e733a3a68356465363231313533636561333938658b034c3c73726d6c5f6d656d626572736869703a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68333835306563326466346630316331628c033c73726d6c5f696e64696365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68633261643539636165356633343863358d03cc013c73726d6c5f636f6c6c6563746976653a3a566f74696e673c542c493e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a486173682c73726d6c5f636f6c6c6563746976653a3a566f7465733c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3e3a3a6765743a3a68393461313166376661346261623661638e03437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68633039353530386266346434323036348f03920173726d6c5f636f6c6c6563746976653a3a5f494d504c5f4445434f44455f464f525f566f7465733a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f636f6c6c6563746976653a3a566f7465733c4163636f756e7449643e3e3a3a6465636f64653a3a68343065303966363462353731613438669003cc013c73726d6c5f636f6c6c6563746976653a3a566f74696e673c542c493e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a486173682c73726d6c5f636f6c6c6563746976653a3a566f7465733c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3e3a3a6765743a3a68356363653664343731373534363738329103483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a683061643237616562663031393863623092033c73726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a683737353062626463643037643137336193033e73726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a683138666563333764623561646133373394034773726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6866623061613132383138346263323231950398013c73726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a686433396465333239346138363534333096033f73726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a683030346539366438633238666534386597034173726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a683538383839366339623863323163393398034173726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a68656538353964363531306461366339309903443c6e6f64655f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68663764303838373736613431383166629a03463c73726d6c5f73797374656d3a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68313765356234643836336365383063619b03473c73726d6c5f696e64696365733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68346139316534306361613562316135399c03473c73726d6c5f7374616b696e673a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68663730346139323533653262356162309d03493c73726d6c5f64656d6f63726163793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68646237653230613337366464653933619e034c3c73726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68653438666534343361643664613031339f03493c73726d6c5f636f6e7472616374733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6830646261343433363238323631623032a0033773726d6c5f7375646f3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6863306337373939383131646631363134a1033973726d6c5f7375646f3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6865383662336537383533633663353534a203613c73726d6c5f7375646f3a3a5f5f476574427974655374727563744b65793c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835663436323933346436393966363339a303497061726974795f7363616c655f636f6465633a3a656e636f64655f617070656e643a3a657874726163745f6c656e6774685f646174613a3a6861363539393739636263333761636634a403930173726d6c5f73797374656d3a3a5f494d504c5f454e434f44455f464f525f4576656e745265636f72643a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f73797374656d3a3a4576656e745265636f72643c452c543e3e3a3a656e636f64655f746f3a3a6835313964643238383166656535656566a50330636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6830393062643931663636306366616536a6033973726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6864663737666166303565326132626162a7033b73726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6866323230343262643939393666376332a803693c73726d6c5f73797374656d3a3a5f5f47657442797465537472756374426c6f636b486173683c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831333062366433643865353165353363a9036e3c73726d6c5f73797374656d3a3a5f5f4765744279746553747275637452616e646f6d4d6174657269616c3c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862306164336334656565303334393161aa034473726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6830393337353364656532626235623761ab033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830383732316431613536376564613731ac033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861306461356534326562393764646632ad033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861353133323561323464326335306330ae033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861646534366530356437383864366131af033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861656438316334343038383438626233b0033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864313034346237306363653161393961b1033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6865353236613866336534333962366537b2033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6865373432653234383330616230386339b3033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6865643163396538393738633632633638b4035373725f7072696d6974697665733a3a50657262696c6c3a3a66726f6d5f726174696f6e616c5f617070726f78696d6174696f6e3a3a7b7b636c6f737572657d7d3a3a6866323639386362373634336330303133b5035373725f7072696d6974697665733a3a50657262696c6c3a3a66726f6d5f726174696f6e616c5f617070726f78696d6174696f6e3a3a7b7b636c6f737572657d7d3a3a6833373266353739373964386264373139b6034573726d6c5f636f6e7472616374733a3a7761736d3a3a707265706172653a3a436f6e74726163744d6f64756c653a3a6e65773a3a6866396465633037636462366163373331b703467061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a436f646553656374696f6e3a3a626f646965733a3a6835653661353535643235383264383234b80348616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a6866366138323963323130326432653731b9033c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a66726f6d5f6d6f64756c653a3a6861353632393762323966303433313661ba03537061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c654275696c6465723c463e3a3a7265736f6c76655f747970655f7265663a3a6861316261313638326630323933646633bb03a9017061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c6553636166666f6c643e20666f72207061726974795f7761736d3a3a656c656d656e74733a3a6d6f64756c653a3a4d6f64756c653e3a3a66726f6d3a3a6861633764383431666461656134386630bc033a707761736d5f7574696c733a3a72756c65733a3a496e737472756374696f6e547970653a3a6f703a3a6837663032626234366239666235643333bd032d616c6c6f633a3a7665633a3a5665633c543e3a3a696e736572743a3a6831653534363162633065353731666435be03507061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c654275696c6465723c463e3a3a707573685f66756e6374696f6e3a3a6832636136636638623462303866353532bf0330636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6830663230326262346463356565323434c0033c707761736d5f7574696c733a3a737461636b5f6865696768743a3a696e6a6563745f6c696d697465723a3a6833623232653831666332613762343934c1036b3c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6831626432303938386265356364303666c2036a636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653c413e20666f7220266d757420463e3a3a63616c6c5f6f6e63653a3a6832643530343666643364323333393536c3033c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6862653131303735633036636232323830c4033e73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6861343964363337373636636639633361c5036b3c73726d6c5f636f6e7472616374733a3a5f5f4765744279746553747275637447617350726963653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861343038666337613034346331386266c603723c73726d6c5f636f6e7472616374733a3a5f5f4765744279746553747275637443757272656e745363686564756c653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863336262613266313261373761613733c7034773726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6835343436366431356565353932323362c80398013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426c6f636b4761734c696d697444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832623861333630363033356638363932c90397013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d617856616c756553697a6544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864383632376638633637316661336135ca0393013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6178446570746844656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830386531343162656136623036363365cb0396013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a43616c6c4261736546656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835346362633237613638373230393939cc0396013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a436f6e747261637446656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864666164343934396165373830323339cd039d013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5472616e73616374696f6e4279746546656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837643937363438323333393262653265ce039a013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53757263686172676552657761726444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863633039396430633865643830643162cf039c013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a52656e744465706f7369744f666673657444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861383537303136316138373334663730d00396013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a52656e744279746546656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861313161353736306636313237336662d1039c013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53746f7261676553697a654f666673657444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838333835383032363334653562336639d2039b013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a546f6d6273746f6e654465706f73697444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832663265363164333630336336326438d3039e013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5369676e6564436c61696d48616e646963617044656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834343564303633636466383337636537d403c40173726d6c5f636f6e7472616374733a3a5f494d504c5f454e434f44455f464f525f526177416c697665436f6e7472616374496e666f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6e7472616374733a3a526177416c697665436f6e7472616374496e666f3c436f6465486173682c42616c616e63652c426c6f636b4e756d6265723e3e3a3a656e636f64655f746f3a3a6835623566356134666332643133373362d503437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6838313030366432613139363036313139d603f0013c73726d6c5f7374616b696e673a3a5f5f6c696e6b65645f6d61705f64657461696c735f666f725f6e6f6d696e61746f72735f646f5f6e6f745f7573653a3a456e756d657261746f723c532c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c28616c6c6f633a3a7665633a3a5665633c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e2c2054293e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6833636539383438363130643636336233d70380023c73726d6c5f64656d6f63726163793a3a5f5f6c696e6b65645f6d61705f64657461696c735f666f725f64656c65676174696f6e735f646f5f6e6f745f7573653a3a456e756d657261746f723c532c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c28283c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c2073726d6c5f64656d6f63726163793a3a436f6e76696374696f6e292c2054293e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6830643135663934303539353539646135d803d0023c73726d6c5f7374616b696e673a3a5f5f6c696e6b65645f6d61705f64657461696c735f666f725f76616c696461746f72735f646f5f6e6f745f7573653a3a456e756d657261746f723c532c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c2873726d6c5f7374616b696e673a3a56616c696461746f7250726566733c3c3c542061732073726d6c5f7374616b696e673a3a54726169743e3a3a43757272656e63792061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a42616c616e63653e2c2054293e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6832306238646261393563666665636665d9033973726d6c5f636f6e7472616374733a3a6761733a3a726566756e645f756e757365645f6761733a3a6837383463396263653861336131636533da033873726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a726573746f72655f746f3a3a6833613437626533343536383030323037db03483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a72656d6f76653a3a6865636232646233366531616633623662dc03483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a72656d6f76653a3a6837333534333263363965363563643462dd03437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6831356362666331623635363864613733de03bb0173726d6c5f7374616b696e673a3a5f494d504c5f454e434f44455f464f525f5f5f4c696e6b616765466f724e6f6d696e61746f7273446f4e6f745573653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f7374616b696e673a3a5f5f4c696e6b616765466f724e6f6d696e61746f7273446f4e6f745573653c4b65793e3e3a3a656e636f64655f746f3a3a6862646133323037643266613563313166df033a73726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6830396333643261353566356661353039e0033c73726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6832623062636235653736333261646262e103723c73726d6c5f7374616b696e673a3a5f5f4765744279746553747275637443757272656e74457261526577617264733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864366332613234346434633966663138e203703c73726d6c5f7374616b696e673a3a5f5f4765744279746553747275637443757272656e7445726153746172743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864643834653439643038366232363934e303683c73726d6c5f7374616b696e673a3a5f5f476574427974655374727563745374616b6572733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865643262376437383731633161393565e4036b3c73726d6c5f7374616b696e673a3a5f5f4765744279746553747275637456616c696461746f72733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837346364633736306437613030636134e5036d3c73726d6c5f7374616b696e673a3a5f5f476574427974655374727563744f66666c696e65536c6173683c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835366166323535393262343534363135e603763c73726d6c5f7374616b696e673a3a5f5f476574427974655374727563744d696e696d756d56616c696461746f72436f756e743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837306633633862383633383130613363e7034573726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6861626530386438333330393939373438e80398013c73726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426f6e64696e674475726174696f6e44656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864373363383237363639306237323061e9033373726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a7374616b6572733a3a6863366134663830336364383464653464ea033773726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6d616b655f7061796f75743a3a6837643166336137313735306132326561eb0344636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a73697a655f68696e743a3a6833323236316661303831373232356664ec033973726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a7570646174655f6c65646765723a3a6831393734376131313534386631663364ed0330636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6830646434613164636362326132636435ee033e636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a6e74683a3a6837346562656431303134633266303237ef03437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6862646432373135396662613161323063f0033f73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a696e6a6563745f7265666572656e64756d3a3a6833633939633739396230386437313534f1033873726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6465706f7369745f6f663a3a6865636565366166353764376161333735f2033c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6835346538643332396139666132663638f3033e73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6865383838316637326130373865613135f4036c3c73726d6c5f64656d6f63726163793a3a5f5f47657442797465537472756374426c61636b6c6973743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832333461393665306430323936613335f5036f3c73726d6c5f64656d6f63726163793a3a5f5f476574427974655374727563744e65787445787465726e616c3c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832633434636131353831313366373535f6036e3c73726d6c5f64656d6f63726163793a3a5f5f4765744279746553747275637444656c65676174696f6e733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861623538663136633833333338386566f703703c73726d6c5f64656d6f63726163793a3a5f5f47657442797465537472756374446973706174636851756575653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830333933316565633336353634623365f8034773726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6864316666666265346438316362363730f90397013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4c61756e6368506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863623434386336653063626433376362fa03a0013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a456d657267656e6379566f74696e67506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833363138656437663661343938383130fb0399013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d4465706f73697444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861303538613535303838646264386338fc039a013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a456e6163746d656e74506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832616561313564356566633462663462fd03443c6e6f64655f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6866376430383837373661343138316662fe03483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a6834303661636364376534643331336337ff03b5013c73726d6c5f64656d6f63726163793a3a50726f78793c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6765743a3a683265373962366233626364333137303080043573726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a646f5f766f74653a3a68363364356434383233623131646236328104ef013c73726d6c5f64656d6f63726163793a3a426c61636b6c6973743c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a486173682c283c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265722c20616c6c6f633a3a7665633a3a5665633c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e293e3e3a3a6765743a3a68303239633730396638643037353831318204683c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e697445787072206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a683664393335333839373336373638306483046b3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a683135313738306562653934363739313384047d3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a436f756e7465644c6973745772697465723c492c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a683235323965613062323865376135346485046f3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a566172496e743332206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a686135363034363538343563643533643386046f3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a566172496e743634206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a683131636261643839333861393064613187046c3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e697445787072206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a686462613634353735316439313963363088046f3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a68353363353465393563396333626233388904443c7061726974795f7761736d3a3a696f3a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68333638383133363166623465663263668a0425616c6c6f633a3a666d743a3a666f726d61743a3a68643763346335363338353636616230398b04793c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a436f756e7465644c6973743c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a68636139393434653637313333376230368c046b3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a68666163323231313639383033366233618d04713c7061726974795f7761736d3a3a656c656d656e74733a3a696e6465785f6d61703a3a496e6465784d61703c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a68646532346562333561666632336562328e04783c7061726974795f7761736d3a3a656c656d656e74733a3a696d706f72745f656e7472793a3a526573697a61626c654c696d697473206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a68633934386234333634396238313339378f047c3c7061726974795f7761736d3a3a656c656d656e74733a3a696d706f72745f656e7472793a3a526573697a61626c654c696d697473206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6831656438636339373431623565656432900482017061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a3c696d706c207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a6520666f7220616c6c6f633a3a737472696e673a3a537472696e673e3a3a73657269616c697a653a3a6866383833666364346466363833623162910486017061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a3c696d706c207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a6520666f7220616c6c6f633a3a737472696e673a3a537472696e673e3a3a646573657269616c697a653a3a68643263653432376264613631363536349204323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a686663336633643330393833623232353193042c636f72653a3a666d743a3a466f726d61747465723a3a7061643a3a68666631303739666431333639376233339404743c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a56617255696e743332206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a68353938333365346536393239346161629504713c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a437573746f6d53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a686130366134383234373137643166313996046f3c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a68646139366130656531653064323239359704457061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e5265616465723a3a6e65773a3a683735643633653437326166306638303998044e636f72653a3a666d743a3a6e756d3a3a696d703a3a3c696d706c20636f72653a3a666d743a3a446973706c617920666f72207533323e3a3a666d743a3a68336462646430663735643064303662309904397761736d695f76616c69646174696f6e3a3a76616c69646174655f6d656d6f72795f747970653a3a68666335353931663238353066326239659a04347761736d695f76616c69646174696f6e3a3a657870725f636f6e73745f747970653a3a68656264643462326433366132343830369b04553c7061726974795f7761736d3a3a656c656d656e74733a3a74797065733a3a56616c75655479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68656561373932353138616238356639359c044a7761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a737465703a3a68613231623430373966613366656436619d04473c7761736d695f76616c69646174696f6e3a3a4572726f7220617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68386330313739343335383463306566339e04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68313865633037343436346561303864659f04416861736862726f776e3a3a7261773a3a5261775461626c653c543e3a3a7472795f776974685f63617061636974793a3a6866613764663139356631353039326230a0043e6861736862726f776e3a3a7261773a3a5261775461626c653c543e3a3a726573657276655f7265686173683a3a6833333462393935646661383539626134a104457061726974795f7761736d3a3a656c656d656e74733a3a7365676d656e743a3a446174615365676d656e743a3a76616c75653a3a6836666366336139336337363466663239a20437616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6831306437636466366264353063306138a3043b636f72653a3a736c6963653a3a3c696d706c205b545d3e3a3a636f70795f66726f6d5f736c6963653a3a6838666665333530336630333966653637a404347761736d695f76616c69646174696f6e3a3a66756e633a3a706f705f76616c75653a3a6862636432636433643664313539313131a504347761736d695f76616c69646174696f6e3a3a66756e633a3a706f705f6c6162656c3a3a6862353864373362326236303263356338a604407761736d695f76616c69646174696f6e3a3a7574696c3a3a4c6f63616c733a3a747970655f6f665f6c6f63616c3a3a6835336638303133346430396365353338a704543c7761736d695f76616c69646174696f6e3a3a66756e633a3a537461636b56616c75655479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6834323630393137373566353065373335a804537761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f6c6f61643a3a6830666530353637646634313565303830a904547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f73746f72653a3a6836343831366461313832353161393364aa04557761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f746573746f703a3a6837633361336566656463343337383266ab04547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f72656c6f703a3a6866303134313436626433316534313762ac04537761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f756e6f703a3a6834333861323731306431663330313066ad04547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f62696e6f703a3a6830383964643835663232356431343336ae04547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f6376746f703a3a6833643162643361393839356261366533af04553c7061726974795f7761736d3a3a656c656d656e74733a3a74797065733a3a426c6f636b5479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6865306333623161386665303165633866b00439636f72653a3a666d743a3a6275696c646572733a3a44656275675475706c653a3a6669656c643a3a6836656537346534333039366131376439b10430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6830366266386636353839656239343162b20430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6836303864393331383235343033383132b304303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6834383234393832626634393662336162b404453c616c6c6f633a3a737472696e673a3a537472696e6720617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6832646462323137376530333166613835b50423636f72653a3a666d743a3a77726974653a3a6839333633326337643033326561343638b6044c3c7761736d695f76616c69646174696f6e3a3a737461636b3a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6865663033363161663731346134643663b704553c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832303633366265663837633738363461b804303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832313765353138386132346630616461b9043a636f72653a3a666d743a3a6275696c646572733a3a44656275675374727563743a3a6669656c643a3a6865383864336131323366383730373832ba0441707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a636f6d707574653a3a6836326566306165663138633338326661bb045a3c707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a4672616d6520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6831366461373838396539666336323662bc0446707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a537461636b3a3a6672616d653a3a6839393266666465383836333563613535bd04453c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c543e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832313263393630353433363939303161be044b707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a537461636b3a3a706f705f76616c7565733a3a6831653832313935383362613030623863bf043f707761736d5f7574696c733a3a737461636b5f6865696768743a3a7265736f6c76655f66756e635f747970653a3a6836633834316630393864653935396264c00433636f72653a3a6f7074696f6e3a3a4f7074696f6e3c26543e3a3a636c6f6e65643a3a6838633139376264356561643438643933c104533c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a737065635f657874656e643a3a6834386138633063333762343963626631c204323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6835333231663034383064306266653134c304613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6832336564346436386530313364323065c404303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6836346562613066656334653933386232c504303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6831353430356262616337383538393663c604303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6838663462376362383535333861663138c704303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6862363063396333663532656166646538c804463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6834353238333930656664323762613338c904303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830346163346666393137356464653030ca04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6839313138306134663333666366303034cb04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6863613534626362393066363435393237cc04383c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a656e61626c65643a3a6834333134336430636534313465386633cd04343c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a6c6f673a3a6861636432356666393666663062343134ce04363c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a666c7573683a3a6865653936353737386662623832643737cf04323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6836313738613030333334663561373330d004323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6839616566383235616539653730303930d104323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6830666531623664623462663262636638d20411727573745f626567696e5f756e77696e64d3044e73725f696f3a3a696d703a3a6578743a3a65787465726e5f66756e6374696f6e735f686f73745f696d706c3a3a6578745f7072696e745f757466383a3a6839656666356362333033373663303437d40430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6862316238333037353039303066353931d5040a5f5f72675f616c6c6f63d6040c5f5f72675f6465616c6c6f63d7040c5f5f72675f7265616c6c6f63d804115f5f72675f616c6c6f635f7a65726f6564d9043a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6836323130386463346536396162356461da043b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6839326334633164656235383732383039db043a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a6831383737376664373066636134616436dc04313c5420617320636f72653a3a616e793a3a416e793e3a3a747970655f69643a3a6863376539376432336334343031616461dd0443636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a77726974655f7072656669783a3a6866353739323864636432363165643336de042e636f72653a3a7374723a3a736c6963655f6572726f725f6661696c3a3a6831363365316338303737343135326331df044a3c636f72653a3a6f70733a3a72616e67653a3a52616e67653c4964783e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832386561383230636339623134613633e004323c6368617220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6833363436396430663335626433316330e1043d636f72653a3a756e69636f64653a3a626f6f6c5f747269653a3a426f6f6c547269653a3a6c6f6f6b75703a3a6837383739366463316163303430646364e2044e636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207573697a653e3a3a666d743a3a68303032326231343762373361613638322e32383133e30434636f72653a3a666d743a3a417267756d656e7456313a3a73686f775f7573697a653a3a6864383031626235373566376562393161e404453c636f72653a3a63656c6c3a3a426f72726f774572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6838333264636132343436363033363537e504483c636f72653a3a63656c6c3a3a426f72726f774d75744572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6865666438626331333133666237396165e604303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6833303638343935663833376230316464e7042e636f72653a3a736c6963653a3a6d656d6368723a3a6d656d6368723a3a6861303831383836616536616630613231e8048001636f72653a3a7374723a3a7472616974733a3a3c696d706c20636f72653a3a736c6963653a3a536c696365496e6465783c7374723e20666f7220636f72653a3a6f70733a3a72616e67653a3a52616e67653c7573697a653e3e3a3a696e6465783a3a7b7b636c6f737572657d7d3a3a6833316463643933376162353865333164e90430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6830633265616634383732313435613930ea04533c636f72653a3a666d743a3a6275696c646572733a3a5061644164617074657220617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6839376430303239666633316637396366eb042f636f72653a3a666d743a3a57726974653a3a77726974655f636861723a3a6839623134626561303263303534316330ec042e636f72653a3a666d743a3a57726974653a3a77726974655f666d743a3a6836396661333266396337306532303163ed043a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6834316530363363373237653132323935ee043b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6838396661663833336237616264326133ef043a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a6838303733616330326435373331613136f004303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832373333653662396330656136666132f104303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832663435616232666237326439623730f204423c636f72653a3a7374723a3a557466384572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832633861613936646264306262346130f304303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6838366434386330303335636663343265f4043e3c636f72653a3a666d743a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6861383238366138363432326238666461f504066d656d736574f604066d656d637079f704076d656d6d6f7665f804066d656d636d70f904095f5f6173686c746933fa04095f5f6c736872746933fb04085f5f6d756c746933fc04095f5f75646976746933fd04095f5f756d6f64746933fe040c5f5f756469766d6f6474693400550970726f64756365727302086c616e6775616765010452757374000c70726f6365737365642d62790105727573746325312e33382e302d6e696768746c79202832643161353531653120323031392d30382d303829", - "0xbde3e43a2a348359d103d64bc95928146bdd9ae3490e26da38d2e4d19c137507": "0x0000a0dec5adc9353600000000000000", - "0x040ff70c23416b89ce6afb75ee0d362e": "0x00000000", - "0xfff675c76ad8a5dfbd7db9a4e80f7c0ece595ad1878d2b6fca6086b2483a055b": "0x0000c16ff28623000000000000000000", - "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b657973e54094c2d5af8ae10b91e1288f4f59f2946d7738f2c509b7effd909e5e9ba0ad": "0x5633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a", - "0x78f4ad73d6b7279f8d06f359e363c829": "0x0000a49d8fc957363600000000000000", - "0x52b963fbdb3d6e1b03808fc20071f07f": "0x00270600", - "0x4664fb5d4e16f894df23cadb3faaa9a6": "0x04000000", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797301dd273832961ca94116fd224019ea1370c0e3d27bebb1041b35651146d17832": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", - "0x4ac2684a5a20e7a5adf17ed7aa792a3f6334a0505f02b2a44c3934d36cc4ee0a": "0xc8dc79e36b29395413399edaec3e20fcca7205fb19776ed8ddb25d6f427ec40e", - "0x633daafcb669e97549c1b9d65660881016f969040bc16171709159437c31294a": "0x0f0000c16ff286230f0000c16ff2862300", - "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b6579737f325c981c2b001f5fe8c51cc7b89e50ebb1f60feb7ab3fa3bc79d6ab71d45cb": "0x9becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993326e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106", - "0x72143961950b9317e15506626c4524c4": "0x1000299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106", - "0x8cb577756012d928f17362e0741f9f2c": "0x01000000", - "0x7eb7a404bf7e3466c3f6c5914e25edfaab48b1e24fd29ea5a94deaaa1aba80e6": "0x0c0001547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65019c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", - "0xdfaac108e0d4bc78fc9419a7fcfa84dc": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d6568655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde789c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", + "0x52b963fbdb3d6e1b03808fc20071f07f": "0x004e0c00", "0xfacbe054606f2488121046f9c5539d98": "0x00", - "0x3ae31af9a378162eb2736f26855c9ad8": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x886726f904d8372fdabb7707870c2fad": "0x1000299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f43780100000000000000482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a0100000000000000482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e01000000000000006e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91060100000000000000", + "0xc1fdc3d212357bc2fa98f2a77b941f0c": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d6568655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde789c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", + "0xdfaac108e0d4bc78fc9419a7fcfa84dc": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d6568655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde789c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", + "0xa5e869ecc1b914a6b0cf5f02b874f5eb90f1739fbd3edd01e5835d1517fd9f72": "0x781ead1e2fa9ccb74b44c19d29cb2a7a4b5be3972927ae98cd3877523976a276", + "0xeecb67c20ca6cc8ba4d4434687f61309": "0x103919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef01000000000000005633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce44001000000000000007932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f01000000000000009becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993320100000000000000", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b6579732c1312343dce08149336968907c27cc602536aaf7a2b105d6fa07058a3803d31": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b65797394f72a73893fbd00b11fcce65a014cc5b9ff5066ec15aa6be068b4cabfe67fdb": "0x3919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f437800299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378", + "0x2dce29f1a768624dc5343063cb77f77d": "0x07000000", + "0x4ac2684a5a20e7a5adf17ed7aa792a3f6334a0505f02b2a44c3934d36cc4ee0a": "0xc8dc79e36b29395413399edaec3e20fcca7205fb19776ed8ddb25d6f427ec40e", + "0x71020fee971bd00e8248d1830b8cffbe5b9cf4de1ea2911a1665c44fd70ab6f3": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26630f0000c16ff286230f0000c16ff2862300", + "0x6e4ab2ac5a7cf9b1829eacc84a75bde0804be01fc31c9419ea72407f50a33384": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0x26ac4a74e1ba94e0e7dbfc3b2aea083cf3c0f0d80eb999c7cebb340ee8934da9": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde780f0000c16ff286230f0000c16ff2862300", + "0xf14d23a9d4492a1efc9194e257b3c3d9": "0x00000000", + "0x637414312dac3b280120bf15b4f66cee": "0x00000000", + "0x92f53c21a80e624b3c606bc8ec0ce2a3003c4fe385bed33998bf4dc79b8970f2": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d650f0000c16ff286230f0000c16ff2862300", + "0x78f4ad73d6b7279f8d06f359e363c829": "0x0000a49d8fc957363600000000000000", "0x50a63a871aced22e88ee6466fe5aa5d9": "0x9ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b6579730cd914acf7b89329ae59e8f7e3b8f1ee7a4f5f68d4749cca82814f2f5b1d6bbb": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", + "0x46cef122497fefa60faf6c66d3ef05caf9870446796ae11f0a4f734fee993d8b": "0x00", "0x717a2ee9c64ad3424e10e4461ec08296": "0x0000000001000000000000000100000000000000010000000000000001000000000000000100000000000000010000000000000001000000000000008700000000000000af0000000000000001000000000000000100000000000000040000000000010010000000004000000020000000", - "0x26ac4a74e1ba94e0e7dbfc3b2aea083cf3c0f0d80eb999c7cebb340ee8934da9": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde780f0000c16ff286230f0000c16ff2862300", - "0xccea67b51b4fa33ecbff70a8977ad91d9c60d620f3ab5ac9626dea15cde023b7": "0x0f0000c16ff286230f0000c16ff2862300", - "0xe026dd082e3158e72eb7c985fc8bac4f": "0x40380000", - "0xbf18c0c65fb39f32ee7c8016685c0a6056f8f924192efb2655be9a692d0b03b6": "0x00", - "0x7c79972b34b7e51bdd5f168ba3accd35fbec396be75dfad19dd1121327f1a1ad": "0x0c000168655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde7800", - "0xc1bc13c775b3406279618b05c28523cb": "0x00", - "0xf186665804ca50670311307912458ce448d82cb96e7e4fe71df38c283a8720f4": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d120f0000c16ff286230f0000c16ff2862300", - "0x686f6c72b7b80bad8dba022335cb7c9e4556ac7ea200008da8046e3178eb89c1": "0x0f0000c16ff286230f0000c16ff2862300", - "0x71020fee971bd00e8248d1830b8cffbe5b9cf4de1ea2911a1665c44fd70ab6f3": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26630f0000c16ff286230f0000c16ff2862300", - "0x90e2849b965314409e8bc00011f3004f": "0x04000000", + "0x579ab55d37b1220812be3c3df29d4858": "0x00000000", + "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b657973711590f60a214f6f06502eb29dd14f55aa04e72e2fa12c098ba4fa5a00c57fa9": "0x7932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e", "0x1ba14d232d3c301a93e35f55e3d7aef2d98dbb9cc0ce48f457b81b421e0f704d": "0x0000c16ff28623000000000000000000", - "0xb49a6659ec27619e87dd18e11b6838c0": "0x00", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797340944475c781bbdc9726766a78b1964888e039600b1c865c62586ab8f98c171e": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", - "0x125dc846383907f5846f72ce53ca0e4b": "0x00ca9a3b000000000000000000000000", - "0xb2029f8665aac509629f2d28cea790a3": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26633919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f437800299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d655633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde787932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d129becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993326e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106", - "0xa902f1f0ef97177b8df9f9fd413768e7": "0x00000000", - "0xc63b8a0db7e72fd87c88d8dcf4777b883f86728613c57148c4e5cdceb05b7a1a": "0x0c0001f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26630168655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b657973be035f25cd43adc80f1dcf505f5ffd158d1592ab3719f354a256a4c3b7571934": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", - "0xc98362e2ca21b342cc749022ed9b560e4d29ec9862a960c2538c314f1d279635": "0x149ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e3180973474718099c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d1268655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", - "0x68c8d2f39c4605e65218c22c5664917047e4900c797b7dd33999d94213c75049": "0x047374616b696e67200000c16ff28623000000000000000000ffffffff0e", - "0x46cef122497fefa60faf6c66d3ef05caf9870446796ae11f0a4f734fee993d8b": "0x00", - "0x886726f904d8372fdabb7707870c2fad": "0x1000299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f43780100000000000000482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a0100000000000000482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e01000000000000006e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91060100000000000000", + "0x75f6361fd25fec35714be80f2d9870af8c92e73cb6d299ba4774f5b0ad842275": "0x00", + "0x9651d20f401bfac47731a01d6eba33b4": "0x00000000", "0xd368b9d9bb1cc910c9a2b8e5d0f5f2fc": "0x0000c16ff28623000000000000000000", - "0xfd0cbba69a04d769ddcdbb15f5123c98041978f5241f33f78f62b48e3a02b740": "0x047374616b696e67200000c16ff28623000000000000000000ffffffff0e", - "0x2b334d6ac6698775ed17edf8cd3cbd9dae56cead0d69cb54f6af6aaecba544d8": "0x0f0000c16ff286230f0000c16ff2862300", + "0x686f6c72b7b80bad8dba022335cb7c9e4556ac7ea200008da8046e3178eb89c1": "0x0f0000c16ff286230f0000c16ff2862300", + "0x8b4621d5f16433d6024b5a31547c59ee24e749e051dbb4bc7e64502f2a4f62fb": "0x66bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f", + "0xc98362e2ca21b342cc749022ed9b560e4d29ec9862a960c2538c314f1d279635": "0x149ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e3180973474718099c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d1268655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0xb49a6659ec27619e87dd18e11b6838c0": "0x00", + "0x7c79972b34b7e51bdd5f168ba3accd35fbec396be75dfad19dd1121327f1a1ad": "0x000168655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde7800", "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797397dddc7aba561f16ac00da4bae75ab812aa7b81418bebdab74425f0d6aa31cee": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b6579731143fa96e07eb73af3db3a1b057d18899f864e6fc5d2f905f9296ca641565564": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", - "0x6e4ab2ac5a7cf9b1829eacc84a75bde0804be01fc31c9419ea72407f50a33384": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", - "0x92f53c21a80e624b3c606bc8ec0ce2a3003c4fe385bed33998bf4dc79b8970f2": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d650f0000c16ff286230f0000c16ff2862300", + "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b657973e54094c2d5af8ae10b91e1288f4f59f2946d7738f2c509b7effd909e5e9ba0ad": "0x5633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a", + "0xe026dd082e3158e72eb7c985fc8bac4f": "0x80700000", + "0x3a636f6465": "0x0061736d010000000198022560027f7f0060017f0060037f7f7f0060027f7f017f60037f7f7f017f60047f7f7f7f0060057f7f7f7f7f0060017f017e60057f7f7f7f7f017f60067f7f7f7f7f7f017f60087f7f7f7f7f7f7f7f017f60047f7f7f7f017f60067f7f7f7f7f7f006000017f60077f7f7f7f7f7f7f017f60017f017f60000060037f7e7e0060047f7f7e7e0060067f7f7e7e7f7f0060057f7f7e7e7f0060057f7f7f7e7e0060077f7e7e7f7f7f7f0060077f7f7e7e7f7f7f0060087f7f7f7f7f7e7e7f0060077f7f7f7e7e7f7f0060077f7e7e7e7e7e7e0060037e7f7f017f60047f7f7f7f017e60027f7e0060037f7f7e0060067f7f7f7e7e7f0060027f7f017e60037f7e7f0060047f7e7e7f0060057f7e7e7e7e0060067f7e7e7e7e7f00029b082703656e760e6578745f626c616b65325f323536000203656e761f6578745f6765745f616c6c6f63617465645f6368696c645f73746f72616765000803656e76176578745f636c6561725f6368696c645f73746f72616765000503656e760c6578745f74776f785f313238000203656e76116578745f636c6561725f73746f72616765000003656e760f6578745f7365745f73746f72616765000503656e76196578745f6765745f616c6c6f63617465645f73746f72616765000403656e76146578745f6765745f73746f726167655f696e746f000803656e76166578745f6b696c6c5f6368696c645f73746f72616765000003656e760e6578745f7072696e745f75746638000003656e76166578745f6368696c645f73746f726167655f726f6f74000403656e76236578745f626c616b65325f3235365f656e756d6572617465645f747269655f726f6f74000503656e76166578745f73616e64626f785f6d656d6f72795f6e6577000303656e761b6578745f73616e64626f785f6d656d6f72795f74656172646f776e000103656e76176578745f73616e64626f785f696e7374616e7469617465000903656e76126578745f73616e64626f785f696e766f6b65000a03656e761d6578745f73616e64626f785f696e7374616e63655f74656172646f776e000103656e76126578745f737232353531395f766572696679000b03656e76106578745f636c6561725f707265666978000003656e76106578745f73746f726167655f726f6f74000103656e76186578745f73746f726167655f6368616e6765735f726f6f74000403656e76126578745f656432353531395f766572696679000b03656e76156578745f7365745f6368696c645f73746f72616765000c03656e760d6578745f7072696e745f686578000003656e76106578745f69735f76616c696461746f72000d03656e76156578745f6c6f63616c5f73746f726167655f676574000b03656e76216578745f6c6f63616c5f73746f726167655f636f6d706172655f616e645f736574000e03656e76116578745f6e6574776f726b5f7374617465000f03656e76106578745f737232353531395f7369676e000803656e76166578745f7375626d69745f7472616e73616374696f6e000303656e76156578745f6c6f63616c5f73746f726167655f736574000603656e76146578745f656432353531395f67656e6572617465000503656e76146578745f737232353531395f67656e6572617465000503656e76166578745f73616e64626f785f6d656d6f72795f676574000b03656e76166578745f73616e64626f785f6d656d6f72795f736574000b03656e76176578745f737232353531395f7075626c69635f6b657973000303656e760b6578745f74776f785f3634000203656e760a6578745f6d616c6c6f63000f03656e76086578745f66726565000103ff04fd040001010100000f001000000f10040002000000010100000000000000000000000200000f0002060f000002001105000000060200000102000001010000000000010000000000010010000000000000000010100002030012000500020b0000000002000000000200000303001302020000000003000300000012021202011100010000000001141500000016000101020502010100110100121200120015020000030100050001020500000306100200000200170318020c00120119050101020001010000000100000003100101000100000101001a0101000100000000000001000002000001000000020502000000020001010304010101000000000000031b090000000b00010100000206000000020101010101010101010101010101010500000000000200100505050505050505050505050505050505050505050505051c0000000000020001100002020505020200021002000101000100020200100000001d000000010100000400010101010000000102000110100100050001010100010101010001000000000000000000010101020f010101000000010000000000000000000000000005000003000f0001020200000000001e001a1f20200020200200002020200000202020022001202020202020202020202002010100010100000000000000010000120000000102000002060203020602020201000100020206022100000300000202040600000300020000030005030203030001000205050202030606020202020503040103030403030308020302030202000003020303030301030303200300010303030100010f01040f01040303070b0503030f03030303030501010403030403030303030303040404042222232323240407017001e101e10105030100120619037f01418080c0000b7f004180acc6000b7f004180acc6000b07f8051b066d656d6f72790200195f5f696e6469726563745f66756e6374696f6e5f7461626c6501000a5f5f646174615f656e6403010b5f5f686561705f6261736503020c436f72655f76657273696f6e00e40312436f72655f657865637574655f626c6f636b00e50315436f72655f696e697469616c697a655f626c6f636b00e703114d657461646174615f6d6574616461746100e8031c426c6f636b4275696c6465725f6170706c795f65787472696e73696300ec031b426c6f636b4275696c6465725f66696e616c697a655f626c6f636b00ed0320426c6f636b4275696c6465725f696e686572656e745f65787472696e7369637300ee031c426c6f636b4275696c6465725f636865636b5f696e686572656e747300f10318426c6f636b4275696c6465725f72616e646f6d5f7365656400f2032b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6e00f303214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b657200f503214772616e6470614170695f6772616e6470615f70656e64696e675f6368616e676500f703204772616e6470614170695f6772616e6470615f666f726365645f6368616e676500f8031e4772616e6470614170695f6772616e6470615f617574686f72697469657300f90314426162654170695f737461727475705f6461746100fa030d426162654170695f65706f636800fb0322417574686f72697479446973636f766572794170695f617574686f726974795f696400fc0321417574686f72697479446973636f766572794170695f617574686f72697469657300fd031a417574686f72697479446973636f766572794170695f7369676e00fe031c417574686f72697479446973636f766572794170695f76657269667900ff031d4163636f756e744e6f6e63654170695f6163636f756e745f6e6f6e63650080042153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b65797300810409686173685f7465737400ef0409bb03010041010be001bc04900191018b057c9a019c01d002d102d202d302d402d502d602d702d802d902da02db02dc02dd02de02df02e002e102e202e302e402e502e602e702e802ae04bf04c104c204b704e504cb04d304d7048805de04e004f404f504f30484058505bd036562ff01800364636b6a6968bb018402c803c9039b049c049e049d049a04e103e1019f04a204a004db01a104df01a4048a04f501ad03f801f701fb018502830281029a029b02a502a402a302a202a102a002cd03fd04a602b102b002b602b502b702970597039603b8029b03f401f301f601a603a503a7038f038e03ae03b902ba01b901ba02bd0187048604bb028f04ff02fe02bc0281036160bd0267b903b803be02ba039e029d02bf029f02aa03a903c002ae02af02fa01f901c102fe01fd01c2028002bf03be03c302c303ac03ab03c402e501e401c502a304c602990582039a0399039803a803c203c103c003cf03ce03cc03cb03ca03c703c603c503c4038d048c048b048904880490049604de039404970489058a05d504d904e904d604e704db04e804ea04ed04ee04ec04f004f104f204fe04ff04800581058e058f05900591059205930594059605950598050a97ee41fd049e10020a7f017e23004180016b2202240002400240024020012802042203200128020022046b41e100490d000240024003402001200441206a3602002001280208220341186a280200210520032802102106200241e0006a41186a22034200370300200241e0006a41106a22074200370300200241e0006a41086a220842003703002002420037036020044120200241e0006a1000200241106a41186a22092003290300370300200241106a41106a220a2007290300370300200241106a41086a220b2008290300370300200220022903603703102002410036026020062005200241106a4120200241e0006a10012106024020022802602205417f460d0020022005360258200220053602542002200636025020012802082201280218210320012802102101200241e0006a41186a22074200370300200241e0006a41106a22084200370300200241e0006a41086a220942003703002002420037036020044120200241e0006a1000200241306a41186a2007290300370300200241306a41106a2008290300370300200241306a41086a20092903003703002002200229036037033020012003200241306a41201002200241086a2002280258360200200220022903503703000c050b20012001280200220441206a3602002001280208220541186a2802002106200528021021052003420037030020074200370300200842003703002002420037036020044120200241e0006a100020092003290300370300200a2007290300370300200b2008290300370300200220022903603703102002410036026020052006200241106a4120200241e0006a10012106024020022802602205417f470d0020012001280200220441206a3602002001280208220541186a2802002106200528021021052003420037030020074200370300200842003703002002420037036020044120200241e0006a100020092003290300370300200a2007290300370300200b2008290300370300200220022903603703102002410036026020052006200241106a4120200241e0006a1001210620022802602205417f470d0320012001280200220441206a3602002001280208220541186a2802002106200528021021052003420037030020074200370300200842003703002002420037036020044120200241e0006a100020092003290300370300200a2007290300370300200b2008290300370300200220022903603703102002410036026020052006200241106a4120200241e0006a1001210720022802602203417f470d0220012802042203200128020022046b41e0004b0d010c040b0b20022005360258200220053602542002200636025020012802082201280218210320012802102101200241e0006a41186a22074200370300200241e0006a41106a22084200370300200241e0006a41086a220942003703002002420037036020044120200241e0006a1000200241306a41186a2007290300370300200241306a41106a2008290300370300200241306a41086a20092903003703002002200229036037033020012003200241306a41201002200241086a2002280258360200200220022903503703000c030b20022003360258200220033602542002200736025020012802082201280218210320012802102101200241e0006a41186a22074200370300200241e0006a41106a22084200370300200241e0006a41086a220942003703002002420037036020044120200241e0006a1000200241306a41186a2007290300370300200241306a41106a2008290300370300200241306a41086a20092903003703002002200229036037033020012003200241306a41201002200241086a2002280258360200200220022903503703000c020b20022005360258200220053602542002200636025020012802082201280218210320012802102101200241e0006a41186a22074200370300200241e0006a41106a22084200370300200241e0006a41086a220942003703002002420037036020044120200241e0006a1000200241306a41186a2007290300370300200241306a41106a2008290300370300200241306a41086a20092903003703002002200229036037033020012003200241306a41201002200241086a2002280258360200200220022903503703000c010b024020042003460d0003402001200441206a3602002001280208220341186a280200210720032802102103200241e0006a41186a22084200370300200241e0006a41106a22094200370300200241e0006a41086a220a42003703002002420037036020044120200241e0006a1000200241106a41186a2008290300370300200241106a41106a2009290300370300200241106a41086a200a290300370300200220022903603703102002410036026020032007200241106a4120200241e0006a10012107024020022802602203417f460d0020022003360258200220033602542002200736025020012802082201280218210320012802102101200241e0006a41186a22074200370300200241e0006a41106a22084200370300200241e0006a41086a220942003703002002420037036020044120200241e0006a1000200241306a41186a2007290300370300200241306a41106a2008290300370300200241306a41086a20092903003703002002200229036037033020012003200241306a41201002200241086a2002280258360200200220022903503703000c030b200128020022042001280204470d000b0b200041003602000c010b200241e0006a41086a2002220141086a280200220336020020022001290200220c370360200020043602002000200c3702042000410c6a20033602000b20024180016a24000b950201057f230041e0026b22012400024020002802082202200028020c460d00200141b0016a4101722103200141d8016a210403402000200241b0016a36020820022d00002105200141b0016a200241016a41af01109b051a20054103460d01200141016a200141b0016a41af01109b051a200120053a00b0012003200141016a41af01109b051a02400240200541014b0d000240024020050e020001000b024020012802b801450d0020012802b40110290b20012d00c0014105490d0220012802e801450d0220012802e40110290c020b2004102a0c010b200128029802450d0020012802940210290b20002802082202200028020c470d000b0b02402000280204450d00200028020010290b200141e0026a24000b0700200010fa040b9b0b01057f024020002d0000220141124b0d00024002400240024002400240024002400240024002400240024020010e13000d0d010d0d020304050607080d090d0a0b0c000b0240200041086a280200220141054b0d0002400240024020010e06101000100102100b200041106a280200450d0f2000410c6a28020010290f0b200041106a280200450d0e2000410c6a28020010290f0b0240200041146a2802002202450d002000410c6a2802002101200241186c210203400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141186a2101200241686a22020d000b0b200041106a280200450d0d200028020c10290f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c210203400240200141046a280200450d00200128020010290b2001410c6a2101200241746a22020d000b0b200041106a280200450d0c200028020c10290f0b02402000410c6a2802002201450d00200041046a2802002203200141f0006c6a2104034002402003410c6a2802002202450d0020032802042101200241246c210203400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012002415c6a22020d000b0b200341f0006a21010240200341086a280200450d00200328020410290b2001210320012004470d000b0b200041086a280200450d0b200028020410290f0b0240200041086a2d00002201410c4b0d0020014106470d0b200041106a280200450d0b2000410c6a28020010290f0b200041106a280200450d0a2000410c6a28020010290f0b200041086a280200450d09200041046a28020010290f0b200041086a2d0000417f6a220141074b0d08024002400240024020010e08000c0c0c0c010203000b2000410c6a2201280200102a200128020010290f0b2000410c6a2201280200102a200128020010290f0b2000410c6a2201280200102a200128020010290f0b2000410c6a2201280200102a200128020010290f0b200041046a2d0000417f6a220141024b0d0702400240024020010e03000102000b2000410c6a280200450d09200041086a28020010290f0b200041086a2201280200102a200128020010290f0b2000410c6a2201280200102a200128020010290f0b200041046a2d0000417f6a220141024b0d0602400240024020010e03000102000b2000410c6a280200450d08200041086a28020010290f0b200041086a2201280200102a200128020010290f0b2000410c6a2201280200102a200128020010290f0b200041086a280200417f6a220141014b0d050240024020010e020001000b200041106a280200450d062000410c6a28020010290f0b200041106a280200450d052000410c6a28020010290f0b200041046a2d00004104490d042000410c6a280200450d04200041086a28020010290c040b200041086a280200450d03200041046a28020010290f0b200041086a2d0000417e6a220141024b0d0202400240024020010e03000102000b200041106a280200450d042000410c6a28020010290f0b200041346a280200450d03200041306a28020010290f0b200041306a280200450d022000412c6a28020010290f0b200041046a2802004101470d01200041086a2201280200102a200128020010290f0b02402000410c6a280200450d00200041086a28020010290b02402000411c6a2802002202450d00200041146a28020021012002410c6c210203400240200141046a280200450d00200128020010290b2001410c6a2101200241746a22020d000b0b200041186a280200450d00200028021410290f0b0b960301097f230041106b2202240002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002006450d0020042d0001210720012003417e6a22063602042001200441026a3602002006450d0020042d0002210820012003417d6a22063602042001200441036a3602002006450d0020042d0003210620012003417c6a3602042001200441046a360200200241086a2001102c20022802080d022001280204200228020c2204490d022004417f4c0d0302400240024020040d004101210341010d010c050b2004102d2203450d0120012802042004490d03200320012802002004109b0521092001280204220a2004490d062001200a20046b3602042001200128020020046a3602002009450d040b20002004360208200020033602042000410c6a2004360200200020074108742005722008411074722006411874723602000c060b20044101102e000b200041003602040c040b200310290b200041003602040c020b102f000b2004200a1030000b200241106a24000bcf0201067f0240024020012802042202450d00200128020022032d0000210420012002417f6a2205360204410121062001200341016a3602000240200441037122074103460d0002400240024020070e03000102000b20044102762107410021060c040b41012106024020050d000c040b20032d0001210520012002417e6a3602042001200341026a3602002005410874200472220141ffff0371418002490d03200141fcff03714102762107410021060c030b20054103490d01200341036a2d0000210620032f0001210720012002417c6a3602042001200341046a3602002007200641107472410874200472220141027621072001418080044921060c020b0240200441034d0d000c020b20054104490d012003280001210720012002417b6a3602042001200341056a36020020074180808080044921060c010b410121060b20002007360204200020063602000b0700200010fc040b0e004188f9c500412210f70400000b05001033000b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420237020c200241c481c600360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41d481c600107d000baf04010a7f230041d0006b2202240020022001102c0240024002400240024020022802000d00200128020422034160712204417f4c0d022002280204210502400240200341057622060d00410121070c010b200410322207450d040b02402005450d00410021080340200241003a00482008220941016a21082001280204417f6a21034100210402400240024003402003417f460d01200241286a20046a2001280200220a2d00003a0000200120033602042001200a41016a3602002002200441016a220a3a00482003417f6a2103200a2104200a4120470d000b200241086a41186a2204200241286a41186a290300370300200241086a41106a220a200241286a41106a290300370300200241086a41086a220b200241286a41086a2903003703002002200229032837030820062009470d02024020094101742203200820082003491b220641ffffff3f712006470d002006410574220341004e0d020b1033000b0240200441ff0171450d00200241003a00480b200041003602002006450d05200710290c050b0240024020090d002003103221070c010b200720094105742003103421070b2007450d070b200720094105746a22032002290308370000200341186a2004290300370000200341106a200a290300370000200341086a200b29030037000020082005470d000b0b2000200636020420002007360200200041086a20053602000c010b200041003602000b200241d0006a24000f0b102f000b20044101102e000b20034101102e000b0700200010f9040b0a0041ccfac500106d000b0b0020002001200210fb040b9203010a7f200041086a220228020021034100210420024100360200024002402003450d004100210541002106410021044100210702400340024002402004450d00200741057421080340200720034f0d062001200028020022096b2008460d02200920086a220a20014120109d05450d020240200620076a220b20034f0d00200920056a20086a2209200a290000370000200941186a200a41186a290000370000200941106a200a41106a290000370000200941086a200a41086a290000370000200841206a2108200741016a22072003490d010c050b0b419481c000200b20031036000b200028020020074105746a21080340200720034f0d0520012008460d01200820014120109d05450d01200841206a2108200741016a22072003490d000b410021040c030b200541606a21052006417f6a2106200441016a2104200741016a22072003490d000b0b2004450d00200320074d0d00200028020020074105746a220820044105746b2008200320076b410574109c051a0b2002200320046b3602000f0b41b880c000200720031036000b6c01017f230041306b2203240020032002360204200320013602002003411c6a41023602002003412c6a41013602002003420237020c200341c8fec500360208200341013602242003200341206a360218200320033602282003200341046a360220200341086a2000107d000bc90a03027f017e1c7f230041f0006b22022400024002400240024002400240024020012802082203ad42f0007e2204422088a70d002004a72205417f4c0d00200128020021060240024020050d00410421070c010b200510322207450d020b0240024020030d00410021080c010b2006200341f0006c6a2109410021082007210a0340200241c0006a41086a220b200641186a290000370300200241c0006a41106a220c200641206a290000370300200241c0006a41186a220d200641286a290000370300200241206a41086a220e200641386a29000037030020062900102104200241206a41106a220f200641c0006a290000370300200241206a41186a2210200641c8006a290000370300200241186a2211200641e8006a290000370300200241106a2212200641e0006a290000370300200241086a2213200641d8006a290000370300200220043703402002200629003037032020022006290050370300200628020c2214ad42247e2204422088a70d022004a72201417f4c0d0220062802002115200628020421160240024020010d00410421170c010b200110322217450d050b0240024020140d00410021180c010b201441246c211941002105410021180340024002400240024002400240201620056a22012d00000e050001020304000b2002200141146a2900003703602002200141196a290000370065200141056a2f0000200141076a2d000041107472211a200141106a280000211b2001410c6a280000211c200141086a280000211d200141016a280000211e4100211f0c040b200141106a280200221b417f4c0d08200141086a2802002120200141016a280000211e4101211f0240201b0d004100211c4101211d41012020201b109b051a0c040b201b211c201b1032221d450d0b201d2020201b109b051a0c030b200141106a280200221b417f4c0d07200141086a280200211f200141016a280000211e02400240201b0d004100211c4101211d0c010b201b211c201b1032221d450d0c0b201d201f201b109b051a4102211f0c020b200141106a280200221b417f4c0d06200141086a280200211f200141016a280000211e02400240201b0d004100211c4101211d0c010b201b211c201b1032221d450d0c0b201d201f201b109b051a4103211f0c010b2001410c6a280200221c417f4c0d05200141046a280200210102400240201c0d004101211a4100211d0c010b201c211d201c1032221a450d0c0b201a2001201c109b052201411874211e2001410876211a4104211f0b201720056a2201201f3a0000200141076a201a4110763a0000200141056a201a3b0000200141106a201b3600002001410c6a201c360000200141086a201d360000200141016a201e360000200141146a20022903603702002001411c6a200241e0006a41086a290300370200201841016a21182019200541246a2205470d000b0b200a2017360204200a410c6a2018360200200a41086a2014360200200a2002290340370210200a41186a200b290300370200200a2015360200200a2002290320370230200a41206a200c290300370200200a41286a200d290300370200200a41386a200e290300370200200a41c0006a200f290300370200200a41c8006a2010290300370200200a41e8006a2011290300370200200a41e0006a2012290300370200200a41d8006a2013290300370200200a2002290300370250200841016a2108200a41f0006a210a200641f0006a22062009470d000b0b200020083602082000200336020420002007360200200241f0006a24000f0b102f000b20054104102e000b20014104102e000b201b4101102e000b201b4101102e000b201b4101102e000b201c4101102e000bfe0203017f017e0b7f024002400240024020012802082202ad42187e2203422088a70d002003a72204417f4c0d00200128020021050240024020040d00410421060c010b200410322206450d020b0240024020020d00410021070c010b2005200241186c6a210841002107200621010340200541086a2802002204417f4c0d02200528020021090240024020040d004101210a4100210b0c010b2004210b20041032220a450d050b200a20092004109b05210a200541146a2802002209417f4c0d022005410c6a280200210c0240024020090d004100210d4101210e0c010b2009210d20091032220e450d060b200e200c2009109b05210c200141146a2009360200200141106a200d3602002001410c6a200c360200200141086a2004360200200141046a200b3602002001200a360200200141186a2101200741016a2107200541186a22052008470d000b0b2000200736020820002002360204200020063602000f0b102f000b20044104102e000b20044101102e000b20094101102e000b890203017f017e077f02400240024020012802082202ad420c7e2203422088a70d002003a72204417f4c0d00200128020021050240024020040d00410421060c010b200410322206450d020b0240024020020d00410021070c010b20052002410c6c6a210841002107200621040340200541086a2802002201417f4c0d02200528020021090240024020010d004101210a0c010b20011032220a450d050b200a20092001109b052109200441086a2001360200200441046a2001360200200420093602002004410c6a2104200741016a21072005410c6a22052008470d000b0b2000200736020820002002360204200020063602000f0b102f000b20044104102e000b20014101102e000bd70201037f024020002802082201450d002000280200220020014188016c6a2102200041f8006a2100034002400240200041887f6a22012d00002203410e4b0d00024002400240024020030e0f050505050500050501050205030505050b200041907f6a2d00004101470d042000419c7f6a280200450d04200041987f6a28020010290c040b2000418c7f6a2d00004103470d030240200041947f6a280200450d00200041907f6a28020010290b200041a07f6a280200450d032000419c7f6a28020010290c030b2000418c7f6a2802000d02200041947f6a280200450d02200041907f6a28020010290c020b200041907f6a2d00004105490d01200041b87f6a280200450d01200041b47f6a28020010290c010b200041907f6a280200450d002000418c7f6a28020010290b0240200141fc006a280200450d00200028020010290b20004188016a210020014188016a2002470d000b0b0b900201077f024020002802082201200028020c460d0003402000200141306a36020820012d00284102460d01200141246a2802002102200141206a2802002103200141146a2802002104200128021c2105200128021021060240200141186a2802002201450d002001410c6c21072006210103400240200141046a280200450d00200128020010290b2001410c6a2101200741746a22070d000b0b02402004450d00200610290b02402002450d002002410c6c21072005210103400240200141046a280200450d00200128020010290b2001410c6a2101200741746a22070d000b0b02402003450d00200510290b20002802082201200028020c470d000b0b02402000280204450d00200028020010290b0bf602010b7f230041106b22022400200241086a2001102c0240024002400240024020022802080d0020012802042203417c712204417f4c0d02200228020c210502400240200341027622060d00410421070c010b200410322207450d040b02402005450d0041002108410021094100210403400240024002402001280204220a4104490d00200441016a21032001280200220b280000210c2001200a417c6a3602042001200b41046a36020020042006470d0202402008200320032008491b220641ffffffff03712006470d002006410274220a41004e0d020b1033000b200041003602002006450d05200710290c050b0240024020040d00200a103221070c010b20072009200a103421070b2007450d070b200720096a200c360200200841026a2108200941046a21092003210420052003470d000b0b2000200636020420002007360200200041086a20053602000c010b200041003602000b200241106a24000f0b102f000b20044104102e000b200a4104102e000b990a02137f017e230041e0006b22022400200241086a2001102c0240024020022802080d000240200128020441246e220341246c2204417f4c0d00200228020c210502400240024020040d00410421060c010b200410322206450d010b02400240024020050d00410021040c010b2002412d6a2107200241cb006a220841056a21094100210a4100210b0340024002402001280204220c450d002001280200220d2d000021042001200c417f6a220e3602042001200d41016a360200200441064b0d00024002400240024002400240024020040e0700070107030402000b20022001102c20022802000d0620012802042002280204220c490d06200c417f4c0d0c024002400240200c0d004101210441010d010c090b200c102d2204450d012001280204200c490d0620042001280200200c109b05210f2001280204220d200c490d072001200d200c6b36020420012001280200200c6a360200200f450d080b200241206a41086a200241386a41086a290200370300200220022902383703202004410876210f4104210d200c210e201041ffffff0771200441187472221021110c080b200c4101102e000b41002104200241003a0058200c417e6a210c03400240200e2004470d00200441ff0171450d07200241003a00580c070b200241386a20046a200d20046a220f41016a2d00003a00002001200c3602042001200f41026a3602002002200441016a220f3a0058200c417f6a210c200f2104200f4120470d000b2002200829000037032020022009290000370025200228004721122002280043210e200228003f210c2002280238211120022f013c210420022d003e210f200741026a200241356a41026a2d00003a0000200720022f00353b00002004200f41107472210f4100210d0c060b200241386a2001102b200228023c220c450d04200228024421122002280240210e200228023821114101210d0c050b200241386a2001102b200228023c220c450d03200228024421122002280240210e200228023821114102210d0c040b200241386a2001102b200228023c220c450d02200228024421122002280240210e200228023821114103210d0c030b200410290c010b200c200d1030000b200041003602000240200b450d002006210403400240024020042d0000220141034b0d0002400240024020010e0404000102040b2004410c6a280200450d03200441086a28020010290c030b2004410c6a280200450d02200441086a28020010290c020b2004410c6a280200450d01200441086a28020010290c010b200441086a280200450d00200441046a28020010290b200441246a2104200a415c6a220a0d000b0b2003450d07200610290c070b200241106a41086a2213200241206a41086a290300370300200220022903203703100240200b2003470d0002400240200341016a22042003490d0020034101742214200420042014491b2204ad42247e2215422088a70d002015a7221441004e0d010b1033000b0240024020030d002014103221060c010b2006200341246c2014103421060b2006450d03200421030b2006200b41246c6a220420123600102004200e36000c2004200c3600082004200f3b0005200420113600012004200d3a0000200441076a200f4110763a0000200420022903103700142004411c6a2013290300370000200a41246a210a200b41016a2204210b20042005470d000b0b2000200336020420002006360200200041086a20043602000c040b20144104102e000b20044104102e000b102f000b200041003602000b200241e0006a24000bfb1002147f037e230041c0026b22022400200241086a2001102c0240024020022802080d000240200128020441c4006e220341c4006c2204417f4c0d00200228020c210502400240024020040d00410421060c010b200410322206450d010b024002402005450d0020024198026a410772210741002108034002400240024002400240024020012802042209450d002001280200220a2d0000210420012009417f6a220b3602042001200a41016a360200200441014b0d000240024020040e020001000b200b41034d0d01200a280001210c20012009417b6a3602042001200a41056a360200200241d4016a41026a200241d8016a41026a2d00003a0000200241b8016a41086a200241f8016a41086a290200370300200241b8016a41106a200241f8016a41106a290200370300200241b8016a41186a200241f8016a41186a2d00003a000020024198016a41086a20024198026a41086a29010037030020024198016a41106a20024198026a41106a29010037030020024198016a41186a20024198026a41186a290100370300200220022f00d8013b01d401200220022902f8013703b801200220022901980237039801200220022f01f4013b0196014100210d0c030b4100210e200241003a00b8022009417e6a210d03400240200b200e2204470d000240200441ff0171450d00200241003a00b8020b4102210d0c040b20024198026a20046a200a20046a220e41016a2d00003a00002001200d3602042001200e41026a3602002002200441016a220e3a00b802200d417f6a210d200e4120470d000b200241f4016a41026a220f20022d009a023a0000200241d8016a41086a2210200741086a290000370300200241d8016a41106a2211200741106a290000370300200241d8016a41186a2212200741186a2d00003a0000200220022f0198023b01f401200220072900003703d801200b200e460d01200228009b022113200a200e6a220a41016a2d0000210b2001200d3602042001200a41026a360200200b41014b0d014100211402400240200b0e020100010b4100210d200241003a00b802200e20096b41026a210b200920046b417c6a210403400240200b200d6a0d00200d41ff0171450d04200241003a00b8020c040b20024198026a200d6a200a200d6a220e41026a2d00003a0000200120043602042001200e41036a3602002002200d41016a220e3a00b8022004417f6a2104200e210d200e4120470d000b200241f8016a41186a20024198026a41186a290300370300200241f8016a41106a20024198026a41106a290300370300200241f8016a41086a20024198026a41086a29030037030020022002290398023703f801410121140b20024198016a41186a200241f8016a41186a29030037030020024198016a41106a200241f8016a41106a29030037030020024198016a41086a200241f8016a41086a290300370300200241d4016a41026a200f2d00003a0000200241b8016a41086a2010290300370300200241b8016a41106a2011290300370300200241b8016a41186a20122d00003a0000200220022903f80137039801200220022f01f4013b01d401200220022903d8013703b8014101210d201421152013210c0c020b20024192016a41026a200241d4016a41026a2d00003a0000200241f8006a41086a200241b8016a41086a290300370300200241f8006a41106a200241b8016a41106a290300370300200241f8006a41186a200241b8016a41186a2d00003a0000200241d8006a41086a20024198016a41086a290300370300200241d8006a41106a20024198016a41106a290300370300200241d8006a41186a20024198016a41186a290300370300200220022f01d4013b019201200220022903b8013703782002200229039801370358200220022f0196013b01560c020b4102210d0b20024192016a41026a2204200241d4016a41026a2d00003a0000200241f8006a41086a220a200241b8016a41086a290300370300200241f8006a41106a220b200241b8016a41106a290300370300200241f8006a41186a2209200241b8016a41186a2d00003a0000200241d8006a41086a220f20024198016a41086a290300370300200241d8006a41106a221020024198016a41106a290300370300200241d8006a41186a221120024198016a41186a290300370300200220022f01d4013b019201200220022903b8013703782002200229039801370358200220022f0196013b0156200d4102460d00200841016a210e200241d2006a41026a221220042d00003a0000200241386a41086a2213200a290300370300200241386a41106a220a200b290300370300200241386a41186a220b20092d00003a0000200241186a41086a2209200f290300370300200241186a41106a220f2010290300370300200241186a41186a22102011290300370300200220022f0192013b01522002200229037837033820022002290358370318200220022f01563b011620032008470d02024020084101742204200e200e2004491b2203ad42c4007e2216422088a70d002016a7220441004e0d020b1033000b200041003602002003450d08200610290c080b0240024020080d002004103221060c010b2006200841c4006c2004103421060b2006450d030b2006200841c4006c6a2204200d3a00002004200c360004200441036a20122d00003a0000200420022f01523b0001200b2d0000210d200a29030021162013290300211720022903382118200420153a002120042018370008200441106a2017370000200441186a2016370000200441206a200d3a00002004413a6a2010290300370000200441326a200f2903003700002004412a6a200929030037000020042002290318370022200420022f01163b0042200e2108200e2005470d000b0b2000200336020420002006360200200041086a20053602000c040b20044104102e000b20044104102e000b102f000b200041003602000b200241c0026a24000bc902010a7f230041106b22022400200241086a2001102c0240024020022802080d00024020012802042203417f4c0d00200228020c210402400240024020030d00410121050c010b200310322205450d010b02402004450d004100210641002107034002400240024020012802042208450d00200741016a21092001280200220a2d0000210b20012008417f6a3602042001200a41016a36020020072003460d010c020b200041003602002003450d07200510290c070b02402006200920092006491b22034100480d000240024020070d002003103221050c010b200520072003103421050b20050d0120034101102e000b1033000b200520076a200b3a0000200641026a21062009210720042009470d000b0b2000200336020420002005360200200041086a20043602000c030b20034101102e000b102f000b200041003602000b200241106a24000bb906020c7f047e230041b0016b2202240020022001102c02400240024002400240024020022802000d00200128020441286e220341286c2204417f4c0d02200228020421050240024020040d00410821060c010b200410322206450d040b02402005450d00410021070340200241003a00a8012007220841016a210720012802042109417f210a4100210402400240024002400240034020092004460d0120024188016a20046a2001280200220b2d00003a000020012009200a6a3602042001200b41016a3602002002200441016a220c3a00a801200a417f6a210a200c2104200c4120470d000b200241e8006a41186a220420024188016a41186a290300370300200241e8006a41106a220a20024188016a41106a290300370300200241e8006a41086a220d20024188016a41086a29030037030020022002290388013703682009200c6b220c41074d0d01200b290001210e2001200b41096a3602002001200c41786a360204200241286a41086a200d290300220f370300200241286a41106a200a2903002210370300200241286a41186a20042903002211370300200241086a41086a220a200f370300200241086a41106a220c2010370300200241086a41186a2209201137030020022002290368220f3703282002200f37030820032008470d0420084101742204200720072004491b2203ad42287e220f422088a70d0c200fa722044100480d0c20080d022004103221060c030b200441ff0171450d00200241003a00a8010b200241286a41186a200241c8006a41186a290300370300200241286a41106a200241c8006a41106a290300370300200241286a41086a200241c8006a41086a29030037030020022002290348370328200041003602002003450d06200610290c060b2006200841286c2004103421060b2006450d070b2006200841286c6a22042002290308370300200a290300210f200c2903002110200929030021112004200e370320200441186a2011370300200441106a2010370300200441086a200f37030020072005470d000b0b2000200336020420002006360200200041086a20053602000c010b200041003602000b200241b0016a24000f0b102f000b20044108102e000b20044108102e000b1033000be60403087f017e017f230041f0016b22022400200241086a2001102c02400240024002400240024020022802080d00200128020441f0006e220341f0006c2204417f4c0d02200228020c21050240024020040d00410421060c010b200410322206450d040b024002402005450d00410021074100210841002109034020024180016a20011042200228028401450d02200941016a2104200241106a20024180016a41f000109b051a024020092003470d002007200420042007491b2203ad42f0007e220a422088a70d09200aa7220b4100480d090240024020090d00200b103221060c010b20062008200b103421060b2006450d080b200620086a200241106a41f000109b051a200741026a2107200841f0006a21082004210920052004470d000b0b2000200336020420002006360200200041086a20053602000c020b2000410036020002402009450d00200620086a210120062107034002402007410c6a2802002209450d0020072802042104200941246c210903400240024020042d0000220841034b0d0002400240024020080e0404000102040b2004410c6a280200450d03200441086a28020010290c030b2004410c6a280200450d02200441086a28020010290c020b2004410c6a280200450d01200441086a28020010290c010b200441086a280200450d00200441046a28020010290b200441246a21042009415c6a22090d000b0b200741f0006a21040240200741086a280200450d00200728020410290b2004210720012004470d000b0b2003450d01200610290c010b200041003602000b200241f0016a24000f0b102f000b20044104102e000b200b4104102e000b1033000b9f0a03077f037e057f230041d0026b2202240041002103200241003a00c8022001280204417f6a210402400240024003402004417f460d01200241a8026a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00c8022004417f6a21042005210320054120470d000b200241e8006a41086a200241a8026a41086a290300370300200241e8006a41106a200241a8026a41106a290300370300200241e8006a41186a200241a8026a41186a290300370300200220022903a80237036820022001102c2002280200450d01200041003602040c020b0240200341ff0171450d00200241003a00c8020b200041003602040c010b2002280204210641002104200241003a00c80220012802042107417f21030240034020072004460d01200241a8026a20046a200128020022082d00003a00002001200720036a3602042001200841016a3602002002200441016a22053a00c8022003417f6a21032005210420054120470d000b200241a8016a41086a200241a8026a41086a2903002209370300200241a8016a41106a200241a8026a41106a290300220a370300200241a8016a41186a200241a8026a41186a290300220b37030020024188016a41086a200937030020024188016a41106a200a37030020024188016a41186a200b370300200220022903a80222093703a801200220093703880141002104200241003a00c802200720056b210c200720036a210303400240200c2004470d000240200441ff0171450d00200241003a00c8020b200041003602040c030b200241a8026a20046a200820046a220541016a2d00003a0000200120033602042001200541026a3602002002200441016a22053a00c8022003417f6a21032005210420054120470d000b200241e8016a41086a200241a8026a41086a2903002209370300200241e8016a41106a200241a8026a41106a290300220a370300200241e8016a41186a200241a8026a41186a290300220b370300200241c8016a41086a22042009370300200241c8016a41106a2203200a370300200241c8016a41186a2205200b370300200220022903a80222093703e801200220093703c801200241a8026a2001103d024020022802a8022201450d00200241c8006a41086a2208200241e8006a41086a290300370300200241c8006a41106a2207200241e8006a41106a290300370300200241c8006a41186a220c200241e8006a41186a290300370300200241286a41086a220d20024188016a41086a290300370300200241286a41106a220e20024188016a41106a290300370300200241286a41186a220f20024188016a41186a29030037030020022002290368370348200220022903880137032820022902ac022109200241086a41186a22102005290300370300200241086a41106a22052003290300370300200241086a41086a22032004290300370300200220022903c801370308200020093702082000200136020420002006360200200041106a2002290348370200200041186a2008290300370200200041206a2007290300370200200041286a200c290300370200200041306a2002290328370200200041386a200d290300370200200041c0006a200e290300370200200041c8006a200f290300370200200041e8006a2010290300370200200041e0006a2005290300370200200041d8006a2003290300370200200041d0006a20022903083702000c020b200041003602040c010b0240200441ff0171450d00200241003a00c8020b200041003602040b200241d0026a24000ba40303087f017e017f230041d0046b22022400200241086a2001102c02400240024002400240024020022802080d00200128020441a0026e220341a0026c2204417f4c0d02200228020c21050240024020040d00410821060c010b200410322206450d040b024002402005450d004100210741002104410021080340200241b0026a200110442002290398034203510d02200841016a2109200241106a200241b0026a41a002109b051a024020082003470d002007200920092007491b2203ad42a0027e220a422088a70d09200aa7220b4100480d090240024020080d00200b103221060c010b20062004200b103421060b2006450d080b200620046a200241106a41a002109b051a200741026a2107200441a0026a21042009210820052009470d000b0b2000200336020420002006360200200041086a20053602000c020b2000410036020002402008450d0020064198016a210903402009102a200941a0026a2109200441e07d6a22040d000b0b2003450d01200610290c010b200041003602000b200241d0046a24000f0b102f000b20044108102e000b200b4108102e000b1033000bad0c04047f017e097f067e23004180066b22022400200241286a2001102c02400240024002400240024020022802280d000240200228022c2203450d0003402003417f6a22030d000b0b20012802042203450d01200128020022042d0000210520012003417f6a3602042001200441016a36020002400240200541ff00714103470d0020054118744118754100480d01420221060c060b200042033703680c060b20024198046a2001109e0120022d0098044102460d02200241f0036a41206a20024198046a41206a280200360200200241f0036a41186a20024198046a41186a290300370300200241f0036a41106a20024198046a41106a290300370300200241f0036a41086a20024198046a41086a29030037030020022002290398043703f00341002103200241003a00c00220012802042107417f2105024002400240034020072003460d0120024180026a20036a200128020022082d00003a00002001200720056a3602042001200841016a3602002002200341016a22043a00c0022005417f6a210520042103200441c000470d000b200241c0056a41386a220320024180026a41386a290300370300200241c0056a41306a220920024180026a41306a290300370300200241c0056a41286a220a20024180026a41286a290300370300200241c0056a41206a220b20024180026a41206a290300370300200241c0056a41186a220c20024180026a41186a290300370300200241c0056a41106a220d20024180026a41106a290300370300200241c0056a41086a220e20024180026a41086a29030037030020022002290380023703c005200441ff017141c000490d0520024180056a41386a220f200329030037030020024180056a41306a2009290300220637030020024180056a41286a200a290300221037030020024180056a41206a200b290300221137030020024180056a41186a200c290300221237030020024180056a41106a200d290300221337030020024180056a41086a200e2903002214370300200220022903c005221537038005200241c0046a41306a2006370300200241c0046a41286a2010370300200241c0046a41206a2011370300200241c0046a41186a2012370300200241c0046a41106a2013370300200241c0046a41086a2014370300200241c0046a41386a200f290300370300200220153703c00420072004460d05200831000121112001200720056a3602042001200841026a360200201150450d01420021060c020b200341ff0171450d04200241003a00c0020c040b2007417f6a2004460d03200831000221122001200841036a3602002001200720046b417e6a36020442022011420f838622104204540d034201210620124208862011844204882010420c882211420120114201561b7e221120105a0d030b200241206a2001102c20022802200d0220022802242105200241086a20011097012002290308a70d02200241086a41106a290300211320022903102112200241e8026a41206a200241f0036a41206a280200360200200241e8026a41186a200241f0036a41186a290300370300200241e8026a41106a200241f0036a41106a290300370300200241e8026a41086a200241f0036a41086a29030037030020024194036a200241c0046a41086a2903003702002002419c036a200241c0046a41106a290300370200200241a4036a200241c0046a41186a290300370200200241ac036a200241c0046a41206a290300370200200241b4036a200241e8046a290300370200200241bc036a200241f0046a290300370200200241c4036a200241f8046a290300370200200220022903f0033703e802200220022903c00437028c0320024180026a200241e8026a41e800109b051a0c030b200042033703680c040b200042033703680c030b420221060b20024198016a20024180026a41e800109b051a024020064202520d00200042033703680c020b200241306a20024198016a41e800109b051a0b200241e8026a2001104f024020022d00e8024113460d002000200241306a41e800109b0522034190016a201337030020034188016a201237030020034180016a2005360200200341f8006a2011370300200320103703702003200637036820034198016a200241e8026a418801109b051a0c010b200042033703680b20024180066a24000bc90401057f23004180016b2202240002400240024020012802042203200128020022046b41e100490d0003402001200441206a360200200241206a20041046024020022802602204450d00200241206a21010c030b20012001280200220441206a360200200241206a20041046024020022802602204450d00200241206a21010c030b20012001280200220441206a360200200241206a20041046024020022802602204450d00200241206a21010c030b20012001280200220441206a360200200241206a20041046024020022802602204450d00200241206a21010c030b20012802042203200128020022046b41e0004b0d000b0b024020042003460d0003402001200441206a360200200241206a20041046024020022802602204450d00200241206a21010c030b200128020022042001280204470d000b0b200041003602400c010b20002001290300370300200041386a200141386a290300370300200041306a200141306a290300370300200041286a200141286a290300370300200041206a200141206a290300370300200041186a200141186a290300370300200041106a200141106a290300370300200041086a200141086a290300370300200241086a2203200141cc006a290200370300200241106a2205200141d4006a290200370300200241186a2206200141dc006a2802003602002002200141c4006a2902003703002000200436024020002002290300370244200041cc006a2003290300370200200041d4006a2005290300370200200041dc006a20062802003602000b20024180016a24000ba90b030d7f017e077f230041a0026b22022400024002400240411010322203450d00200341002900ca9745370000200341086a41002900d297453700002002429080808080023702e401200220033602e0012002200241e0016a3602a0012001200241a0016a10850120022802e401210420022802e001210520022802e8012103200241f8006a41186a22014200370300200241f8006a41106a22064200370300200241f8006a41086a220742003703002002420037037820052003200241f8006a1000200241d8006a41186a2001290300370300200241d8006a41106a2006290300370300200241d8006a41086a200729030037030020022002290378370358200241003602e001200241d8006a4120200241e0016a1006210620022802e0012207417f460d012006450d012002200736029c01200220063602980141002103200241003a0038024002400340024020072003470d002002410036029c01200341ff0171450d02200241003a00380c020b200241186a20036a200620036a22012d00003a00002002200141016a360298012002200341016a22013a00382001210320014120470d000b200241f8006a41086a2208200241186a41086a2209290300370300200241f8006a41106a220a200241186a41106a220b290300370300200241f8006a41186a220c200241186a41186a220d290300370300200220022903183703782002200720016b36029c01200241186a20024198016a10910420022802382203450d00200241e0016a41186a220e200c290300370300200241e0016a41106a220c200a290300370300200241e0016a41086a220a2008290300370300200241e0016a41286a22012009290300370300200241e0016a41306a2208200b290300370300200241e0016a41386a2209200d290300370300200220022903783703e00120022002290318370380022002413c6a280200210b200241186a41286a220d290300210f200241a0016a41086a200a290300370300200241a0016a41106a200c290300370300200241a0016a41186a200e290300370300200241a0016a41206a220c200229038002370300200241a0016a41286a220e2001290300370300200241a0016a41306a22102008290300370300200241a0016a41386a22112009290300370300200220022903e0013703a001200241186a20024198016a103120022802180d01200b450d00200310290b41f7cdc3004133200241a0016a41ecd6c3001054000b200241f8006a41086a2212200241186a41086a220a280200360200200241e0016a41086a2213200241a0016a41086a290300370300200241e0016a41106a2214200241a0016a41106a290300370300200241e0016a41186a2215200241a0016a41186a290300370300200241e0016a41206a2216200c2903003703002001200e290300370300200820102903003703002009201129030037030020022002290318370378200220022903a0013703e001200a2013290300370300200241186a41106a220c2014290300370300200241186a41186a220e2015290300370300200241186a41206a2016290300370300200d2001290300370300200241186a41306a2008290300370300200241186a41386a2009290300370300200241086a41086a22012012280200360200200220022903e0013703182002200229037837030802402007450d00200610290b200020022903183703002000200b360244200041c8006a200f370200200041386a200241186a41386a290300370300200041306a200241186a41306a290300370300200041286a200241186a41286a290300370300200041206a200241186a41206a290300370300200041186a200e290300370300200041106a200c290300370300200041086a200a290300370300200041d0006a2002290308370200200041d8006a20012802003602000c020b41104101102e000b410021030b2000200336024002402004450d00200510290b200241a0026a24000bed0704067f017e0a7f027e230041f0006b22032400200341206a2001200228020c22041100000240024020032802200d002000410036020820004208370200200120022802001101002002280204450d01200110290c010b200341c8006a41106a200341206a41106a290300370300200341c8006a41086a200341206a41086a290300370300200341c8006a41186a200341206a41186a290300370300200341c8006a41206a200341206a41206a280200360200200341086a200341d4006a290200370300200341106a200341dc006a290200370300200341186a200341e4006a290200370300200320032903203703482003200329024c370300200341c8006a2001200228021022051100000240024002400240417f2003280248220641016a220720072006491b2208ad42287e2209422088a70d002009a72206417f4c0d000240024020060d004108210a4108210b0c010b20061032220a450d02200a210b0b200a2003290300370300200a41186a200341186a220c290300370300200a41106a200341106a220d290300370300200a41086a200341086a290300370300200b4201370320200341206a200120041100000240024020032802200d004101210e0c010b200341c8006a410472210641c800210f4101210e0340200341c8006a41206a200341206a41206a280200360200200341c8006a41186a2210200341206a41186a290300370300200341c8006a41106a2211200341206a41106a290300370300200341c8006a41086a2212200341206a41086a29030037030020032003290320370348200341086a2207200641086a290200370300200d200641106a290200370300200c200641186a290200370300200320062902003703002010200c2903003703002011200d29030037030020122007290300370300200320032903003703480240200e2008470d00200341206a200120051100002008417f2003280220220741016a221320132007491b6a22072008490d0620084101742213200720072013491b2213ad42287e2209422088a70d062009a722074100480d060240024020080d0020071032210a0c010b200a200841286c20071034210a0b200a450d05200a210b201321080b200b200f6a221341606a2207200329034837030020122903002109201129030021142010290300211520134201370300200741186a2015370300200741106a2014370300200741086a2009370300200341206a20012004110000200f41286a210f200e41016a210e20032802200d000b0b2001200228020011010002402002280204450d00200110290b2000200e360208200020083602042000200b3602000c040b102f000b20064108102e000b20074108102e000b1033000b200341f0006a24000bd408040c7f017e057f037e23004180016b22022400024002400240200141086a220328020022042001410c6a2802002205460d002001280210220628020021072006280208220841014b210903402003200441206a220a360200200241e0006a41186a200441186a290000370300200241e0006a41106a200441106a290000370300200241e0006a41086a200441086a29000037030020022004290000370360410021040240024020090d0020080e020401040b2008210b0340200b410176220c20046a220d20042007200d4105746a200241e0006a4120109d054101481b2104200b200c6b220b41014b0d000b0b200720044105746a200241e0006a4120109d050d02200a2104200a2005470d000b200521040b2000410036020820004201370200024020042005460d00200141086a200520046b41606a41607120046a41206a3602000b2001280204450d01200128020010290c010b200241c0006a41086a2204200241e0006a41086a290300370300200241c0006a41106a220b200241e0006a41106a290300370300200241c0006a41186a220c200241e0006a41186a29030037030020022002290360220e3703002002200e370340024041201032220f450d00200f2002290340370000200f41186a200c290300370000200f41106a200b290300370000200f41086a2004290300370000200128020421102001280200211102400240200a2005470d0041012112410121130c010b41012112410121130340200628020821032006280200210702400340200241e0006a41186a2208200a41186a290000370300200241e0006a41106a2209200a41106a290000370300200241e0006a41086a2201200a41086a2900003703002002200a290000370360200a41206a210a4100210402400240200341014b0d0020030e020301030b2003210b0340200b410176220c20046a220d20042007200d4105746a200241e0006a4120109d054101481b2104200b200c6b220b41014b0d000b0b200720044105746a200241e0006a4120109d050d01200a2005470d000c030b0b200241c0006a41086a2001290300220e370300200241c0006a41106a20092903002214370300200241c0006a41186a20082903002215370300200220022903602216370340200241186a220b2015370300200241106a220c2014370300200241086a220d200e37030020022016370300024020132012470d000240201241016a22042012490d0020124101742207200420042007491b221341ffffff3f712013470d00201341057422044100480d000240024020120d0020041032210f0c010b200f201241057420041034210f0b200f0d0120044101102e000b1033000b200f20124105746a22042002290300370000200441186a200b290300370000200441106a200c290300370000200441086a200d290300370000201241016a2112200a2005470d000b0b02402010450d00201110290b20002012360208200020133602042000200f3602000c010b41204101102e000b20024180016a24000bd70705077f037e097f017e017f23004180016b22022400024002400240200141086a220328020022042001410c6a2802002205460d0020012802102106200241f4006a2107034020032004220841206a2204360200200841086a2903002109200841106a290300210a2008290300210b200241e0006a41186a200841186a290300370300200241e0006a41106a200a370300200241e0006a41086a20093703002002200b3703600240200aa720062802004d0d002001280214220c2007460d002007290000200c290000520d030b20052004470d000b200521040b2000410036020820004208370200024020042005460d00200141086a200520046b41606a41607120046a41206a3602000b2001280204450d01200128020010290c010b200241086a2204200241e0006a41086a290300370300200241106a2203200241e0006a41106a290300370300200241186a2207200241e0006a41186a29030037030020022002290360220a3703202002200a3703000240024002400240024041201032220d450d00200d2002290300370300200d41186a2007290300370300200d41106a2003290300370300200d41086a20042903003703002001280204210e2001280200210f200541606a2008460d03200841206a2110200541606a2111200241f4006a21074101211241012113200d21140340200c2007460d042010210802400340200241e0006a41186a2204200841186a290300370300200241e0006a41106a2203200841106a290300220a370300200241e0006a41086a2201200841086a290300370300200220082903003703600240200aa720062802004d0d002007290000200c290000520d020b2005200841206a2208470d000c070b0b200241206a41086a2001290300220a370300200241206a41106a20032903002209370300200241206a41186a2004290300220b3703002002200229036022153703202004200b370300200320093703002001200a37030020022015370360024020132012470d00201241016a22132012490d0420124101742210201320132010491b221341ffffff3f712013470d04201341057422104100480d040240024020120d002010103221140c010b201420124105742010103421140b2014450d030b200841206a2110201420124105746a22162002290360370300201641186a2004290300370300201641106a2003290300370300201641086a2001290300370300201241016a211220112008470d000c050b0b41204108102e000b20104108102e000b1033000b4101211241012113200d21140b0240200e450d00200f10290b2000201236020820002013360204200020143602000b20024180016a24000bca0201057f230041b0026b22012400200141a0016a41086a22024200370300200142003703a00141e889c0004116200141a0016a100320014190016a41086a22032002290300370300200120012903a00137039001200141a0016a20014190016a104b0240024020012d00a80222044103460d0020014190016a411010042001200141a0016a418801109b05220541013a008f0120024200370300200542003703a00141f9abc500411f200541a0016a100320032002290300370300200520052903a0013703900120054190016a41102005418f016a41011005200241023a0000200541053a00a0014100210241014100200541a0016a104c200541a0016a2005418801109b051a20054190016a200041809c316a200541a0016a20044180de34104d2005280290014101470d0120052802940121020c010b41fe89c00021020b200141b0026a240020020baa0201057f230041b0026b22022400200241003602a80120014110200241a8016a100621030240024020022802a8012201417f470d00200041033a0088010c010b2002200136021420022003360210200241a8016a200241106a104f0240024020022d00a8014113460d00200241206a200241a8016a418801109b051a024020022802142204450d00200228021022052d0000210620022004417f6a3602142002200541016a36021020064103490d020b200241206a102a0b41f7cdc3004133200241a8016a41ecd6c3001054000b2000200241206a418801109b0521002002200241196a41036a28000036000b20022002280019360208200020063a00880120002002280208360089012000418c016a200228000b3600002001450d00200310290b200241b0026a24000ba52203097f047e027f230041b0036b22032400200341003602a00141caf9c2004110200341a0016a100621040240024020032802a0012205417f460d002004450d00024020054104490d002004280000210620041029410021070c020b41f7cdc3004133200341a8036a41ecd6c3001054000b410121070b20014105742108410121094100210441002105024002400240024002400240024002400240024002402001450d0020084100480d09200810322209450d012001410574220a41606a410576210b410021040340200341b8026a41186a200020046a220541186a290000220c370300200341b8026a41106a200541106a290000220d370300200341b8026a41086a200541086a290000220e37030020032005290000220f3703b802200920046a220541186a200c370000200541106a200d370000200541086a200e3700002005200f370000200a200441206a2204470d000b200b41016a2105200121040b2003418c016a20063602002003200736028801200341186a200241f000109b051a20034198016a200536020020034194016a20043602002003200936029001200341106a41a7f7c5004111105d0240024002400240024002402003280214410020032802101b220641016a22052006490d00200341b8026a41086a22044200370300200342003703b80241a7f7c5004111200341b8026a100320034180036a41086a22092004290300370300200320032903b80237038003200320053602a00120034180036a4110200341a0016a41041005200341a0016a200341186a418801109b051a20044200370300200342003703b80241b089c300410d200341b8026a100320092004290300370300200320032903b80237038003200341003602b80220034180036a4110200341b8026a1006210402400240024002400240024020032802b8022205417f460d0020040d010b20034100360288032003420837038003200341003602c002200342013703b8024100200341b8026a106620032902bc02210c20032802b802210420034180036a103a2004450d02200320043602a8022003200c3702ac02200c422088a721050c010b200320053602b002200320053602ac02200320043602a8020b2005450d01200341b8026a20042005410110800120032802b8024101470d0220032802ac02450d0c20032802a80210290c0c0b200341003602b002200342013703a8020b4101200341a8026a1066200341a0016a200341a8026a1093030c080b20032802bc02210a0240200341c4026a2802002204200341c0026a2802002205460d0020032802b002200420056b6a22094188016a2202417f4c0d100240024020020d00410121070c010b200210322207450d030b200320023602dc02200320073602d802200320093602e0022003200341d8026a3602b802200a200341b8026a200410820120092004490d0320032802e002220a2009490d0420032802b002220a2005490d0520032802d802210220032802a80221072003200920046b2209360298032003200a20056b220a36029c032009200a470d06200220046a200720056a2009109b051a200341a0016a200341d8026a10930320032802e002210520032802dc02210920032802d802210420032802ac02450d0920032802a80210290c090b2003200341a8026a3602b802200a200341b8026a2005108201200341a0016a200341a8026a1093030c070b200341186a1094030c0a0b20024101102e000b200420091030000b2009200a108f01000b2005200a1030000b20034180036a41146a41023602002003418c036a4103360200200341e8026a41146a4103360200200342033702ec02200341acf9c5003602e8022003410336028403200320034198036a3602a00320032003419c036a3602a403200342043703c802200342013702bc0220034180fac5003602b802200320034180036a3602f8022003200341b8026a360290032003200341a4036a360288032003200341a0036a36028003200341e8026a41bcfac500107d000b20084101102e000b20032802b002210520032802ac02210920032802a80221040b20040d010b200341a0016a1094030c010b200341b8026a41086a220a4200370300200342003703b80241b089c300410d200341b8026a100320034180036a41086a200a290300370300200320032903b8023703800320034180036a411020042005100502402009450d00200410290b200341a0016a109403200341086a41d983c300410d105d2001450d00200020086a2110200328020c410020032802081b210b02400340200320063602ac022003200b3602a80220034180036a1095030240024002400240024002400240024002400240024002400240024002400240024002400240410110322204450d00200420002d00003a000020044101410210342204450d012004200041016a2d00003a000120044102410410342204450d022004200041026a2d00003a00022004200041036a2d00003a000320044104410810342204450d032004200041046a2d00003a00042004200041056a2d00003a00052004200041066a2d00003a00062004200041076a2d00003a000720044108411010342204450d042004200041086a2d00003a00082004200041096a2d00003a000920042000410a6a2d00003a000a20042000410b6a2d00003a000b20042000410c6a2d00003a000c20042000410d6a2d00003a000d20042000410e6a2d00003a000e20042000410f6a2d00003a000f20044110412010342204450d052004200041106a2d00003a00102004200041116a2d00003a00112004200041126a2d00003a00122004200041136a2d00003a00132004200041146a2d00003a00142004200041156a2d00003a00152004200041166a2d00003a00162004200041176a2d00003a00172004200041186a2d00003a00182004200041196a2d00003a001920042000411a6a2d00003a001a20042000411b6a2d00003a001b20042000411c6a2d00003a001c20042000411d6a2d00003a001d20042000411e6a2d00003a001e20042000411f6a2d00003a001f200341b8026a41186a22054200370300200341b8026a41106a22094200370300200341b8026a41086a220a4200370300200342003703b80220044120200341b8026a1000200341a0016a41186a22082005290300370300200341a0016a41106a22022009290300370300200341a0016a41086a2207200a290300370300200320032903b8023703a00102400240200328028403220120032802880322096b4120490d0020032802800321050c010b200941206a22052009490d192001410174220a20052005200a491b220a4100480d190240024020010d00200a103221050c010b2003280280032001200a103421050b2005450d072003200a360284032003200536028003200a21010b200520096a220a41086a2007290300370000200a41106a2002290300370000200a41186a20082903003700002003200941206a220936028803200a20032903a00137000020041029200341003602a00120052009200341a0016a1006210a024020032802a0012204417f470d00200341003602e002200342013703d8020c110b200320043602e002200320043602dc022003200a3602d8022004450d10200341a0016a200a20044101108001024020032802a0014101460d0020032802a4012102024020032802ac01220420032802a801220a460d0020032802e0022004200a6b6a220841086a2207417f4c0d1b0240024020070d00410121110c010b200710322211450d0a0b200320073602ec02200320113602e802200320083602f0022003200341e8026a3602a0012002200341a0016a200410820120082004490d0a20032802f00222022008490d0b20032802e0022202200a490d0c20032802e802210720032802d80221112003200820046b22083602980320032002200a6b220236029c0320082002470d0d200720046a2011200a6a2008109b051a20032802a80221080240024020032802ec02220a20032802f00222046b4104490d0020032802e802210a0c010b200441046a22022004490d1b200a4101742204200220022004491b22044100480d1b02400240200a0d0020041032210a0c010b20032802e802200a20041034210a0b200a450d0f200320043602ec022003200a3602e80220032802f00221040b2003200441046a3602f002200a20046a200836000020032802ac0221080240024020032802ec02220a20032802f00222046b4104490d0020032802e802210a0c010b200441046a22022004490d1b200a4101742204200220022004491b22044100480d1b02400240200a0d0020041032210a0c010b20032802e802200a20041034210a0b200a450d10200320043602ec022003200a3602e80220032802f00221040b2003200441046a3602f002200a20046a200836000020032802f002210a20032802ec02210820032802e802210420032802dc02450d1420032802d80210290c140b2003200341d8026a3602a0012002200341a0016a200a10820120032802a80221080240024020032802dc02220a20032802e00222046b4104490d0020032802d802210a0c010b200441046a22022004490d1a200a4101742204200220022004491b22044100480d1a02400240200a0d0020041032210a0c010b20032802d802200a20041034210a0b200a450d10200320043602dc022003200a3602d80220032802e00221040b2003200441046a3602e002200a20046a200836000020032802ac0221080240024020032802dc02220a20032802e00222046b4104490d0020032802d802210a0c010b200441046a22022004490d1a200a4101742204200220022004491b22044100480d1a02400240200a0d0020041032210a0c010b20032802d802200a20041034210a0b200a450d11200320043602dc022003200a3602d80220032802e00221040b2003200441046a3602e002200a20046a20083600000c120b20032802dc02450d1420032802d80210290c140b41014101102e000b41024101102e000b41044101102e000b41084101102e000b41104101102e000b41204101102e000b200a4101102e000b20074101102e000b200420081030000b20082002108f01000b200a20021030000b20034180036a41146a41023602002003418c036a4103360200200341b8026a41146a4103360200200342033702bc02200341acf9c5003602b8022003410336028403200320034198036a3602a00320032003419c036a3602a403200342043703b001200342013702a40120034180fac5003602a001200320034180036a3602c8022003200341a0016a360290032003200341a4036a360288032003200341a0036a36028003200341b8026a41bcfac500107d000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b4101200341d8026a106620032802a80221080240024020032802dc02220a20032802e00222046b4104490d0020032802d802210a0c010b200441046a22022004490d08200a4101742204200220022004491b22044100480d0802400240200a0d0020041032210a0c010b20032802d802200a20041034210a0b200a450d06200320043602dc022003200a3602d80220032802e00221040b2003200441046a3602e002200a20046a200836000020032802ac0221080240024020032802dc02220a20032802e00222046b4104490d0020032802d802210a0c010b200441046a22022004490d08200a4101742204200220022004491b22044100480d0802400240200a0d0020041032210a0c010b20032802d802200a20041034210a0b200a450d07200320043602dc022003200a3602d80220032802e00221040b2003200441046a3602e002200a20046a20083600000b20032802e002210a20032802dc02210820032802d80221040b2004450d01200520092004200a100502402008450d00200410290b02402001450d00200510290b200041206a22002010470d000c020b0b2001450d00200510290b200341b0036a24000f0b20044101102e000b20044101102e000b1033000b102f000bec0801047f230041e0026b22052400200541cdabc5004119105d0240024002402005280204410020052802001b2206417f6a220720064d0d00200541033a0098010c010b200541086a2007105e20052d0098014103460d00200541a0016a200541086a419801109b051a20052802a8022107200541a0016a102a200720014d0d00200041d388c00036020420004101360200200041086a41c7003602002002102a0c010b200541a0016a41086a22074200370300200542003703a00141cdabc5004119200541a0016a1003200541086a41086a2007290300370300200520052903a0013703082005200641016a3602a001200541086a4110200541a0016a41041005200541a0016a2002418801109b051a200520033a00b002200520043602ac02200520013602a802024002400240024002400240411a10322201450d00200141186a41002f00b587403b0000200141106a41002900ad8740370000200141086a41002900a587403700002001410029009d87403700002001411a413410342202450d012002200636001a200541086a41186a22014200370300200541086a41106a22044200370300200541086a41086a22074200370300200542003703082002411e200541086a1000200541b8026a41186a2001290300370300200541b8026a41106a2004290300370300200541b8026a41086a2007290300370300200520052903083703b802200541003602102005420137030820052802a8022104410410322201450d022005410436020c20052005280210220741046a36021020052001360208200120076a2004360000200541a0016a200541086a105f024020052d00b002220141024b0d00024002400240024020010e03000102000b410021040c020b410121040c010b410221040b200520043a00df0202400240200528020c20052802102201460d00200528020821070c010b200141016a22072001490d0720014101742208200720072008491b22084100480d070240024020010d002008103221070c010b200528020820012008103421070b2007450d052005200836020c20052007360208200528021021010b2005200141016a360210200720016a20043a00000b20052802ac02210702400240200528020c2204200528021022016b4104490d00200528020821040c010b200141046a22082001490d0620044101742201200820082001491b22014100480d060240024020040d002001103221040c010b200528020820042001103421040b2004450d052005200136020c20052004360208200528021021010b2005200141046a360210200420016a2007360000200528020c2101200541b8026a4120200528020822042005280210100502402001450d00200410290b20021029200541a0016a102a200541ac016a2006360200200541a9016a20033a0000200541a8016a41033a0000200541053a00a00141014100200541a0016a104c20004100360200200020063602040c060b411a4101102e000b41344101102e000b41044101102e000b20084101102e000b20014101102e000b1033000b200541e0026a24000bb31802127f177e230041f0056b22012400200141a0046a41086a22024200370300200142003703a004419188c0004115200141a0046a1003200141306a41086a2002290300370300200120012903a004370330200141003602a004200141306a4110200141a0046a1006210302400240024020012802a0042204417f460d002003450d002001200436024420012003360240200141286a200141c0006a102c20012802280d02024002400240200128024441b0016e220541b0016c2202417f4c0d00200128022c21060240024020020d00410821070c010b200210322207450d020b0240024020060d00200721020c010b20014198036a4101722108410021094100210a2007210203400240024002402001280244220b4104490d002001280240220c280000210d2001200b417c6a3602442001200c41046a360240200141a0046a200141c0006a104f20012d00a0044113460d00200a41016a210e20014198036a200141a0046a418801109b051a4100210c200141003a00e8052001280244417f6a210b02400340200b417f460d01200141c8056a200c6a2001280240220f2d00003a00002001200f41016a3602402001200c41016a220f3a00e8052001200b360244200b417f6a210b200f210c200f4120470d000b200141a8056a41186a220b200141c8056a41186a290300370300200141a8056a41106a220f200141c8056a41106a290300370300200141a8056a41086a2210200141c8056a41086a290300370300200120012903c8053703a80520012d009803210c20014190026a2008418701109b051a200141f0016a41086a22112010290300370300200141f0016a41106a2210200f290300370300200141f0016a41186a220f200b290300370300200120012903a8053703f001200c4113460d01200141e9006a20014190026a418701109b051a200141c8006a41186a2212200f290300370300200141c8006a41106a220f2010290300370300200141c8006a41086a22102011290300370300200120012903f0013703482005200a470d030240200a4101742202200e200e2002491b2205ad42b0017e2213422088a70d002013a7220241004e0d030b1033000b0240200c41ff0171450d00200141003a00e8050b20014198036a102a0b0240200a450d0003402002102a200241b0016a2102200941d07e6a22090d000b0b2005450d09200710290c090b02400240200a0d002002103221070c010b2007200a41b0016c2002103421070b2007450d05200721020b2002200a41b0016c6a220b200c3a0000200b41016a200141e9006a418701109b051a200b200d36028801200b200129034837028c01200b4194016a2010290300370200200b419c016a200f290300370200200b41a4016a2012290300370200200941b0016a2109200e210a200e2006470d000b0b2002450d0502402004450d00200310290b2002210f0c040b102f000b20024108102e000b20024108102e000b4108210f410021064100210541082107410821020b0240024002402006450d00200141a0046a200f2802880110500240024020012802b00422090d0042002114420021150c010b200141186a20012903a004200141a0046a41086a290300200141b8046a350200420010a005200141186a41086a29030021152001290318211420012802b404450d00200910290b200fad4220862116024020064101460d00200f41b0016a2109200641b0016c41d07e6a210b420121170340200141a0046a20094188016a28020010500240024020012802b004220c0d0042002118420021130c010b200141086a20012903a004200141a0046a41086a29030020013502b804420010a005200141086a41086a29030021132001290308211820012802b404450d00200c10290b02402014201856201520135620152013511b0d002009ad422086201784211620182114201321150b200941b0016a2109201742017c2117200b41d07e6a220b0d000b0b201642ffffffff0f560d01200641b0016c210903402002102a200241b0016a2102200941d07e6a22090d000b0b41b888c00021022005450d01200710290c010b024002400240024020062016a722094d0d00200f2006417f6a220c41b0016c6a220b4180016a2903002115200b4188016a2903002117200b4190016a2903002118200b4198016a2903002114200b41e0006a2903002116200b41e8006a2903002119200b41f0006a290300211a200b41f8006a290300211b200b41c0006a290300211c200b41c8006a290300211d200b41d0006a290300211e200b41d8006a290300211f200b41206a2903002120200b41286a2903002121200b41306a2903002122200b41386a2903002123200b2903002124200b2903082125200b2903102126200b41186a2903002127200141a0046a41086a2203200b41a8016a2903002228370300200f200941b0016c6a220941186a220a2903002129200b41a0016a2903002113200a2027370300200929031021272009202637031020092903082126200920253703082009290300212520092024370300200941386a220b2900002124200b2023370000200941306a220b2900002123200b2022370000200941286a220b2900002122200b2021370000200941206a220b2900002121200b2020370000200941d8006a220b2900002120200b201f370000200941d0006a220b290000211f200b201e370000200941c8006a220b290000211e200b201d370000200941c0006a220b290000211d200b201c370000200941f8006a220b290000211c200b201b370000200941f0006a220b290000211b200b201a370000200941e8006a220b290000211a200b2019370000200941e0006a220b2900002119200b201637000020094198016a201437000020094190016a201837000020094188016a220b280000210a200b201737000020094180016a220b2900002117200b2015370000200120133703a004200941a0016a2013370200200941a8016a202837020020014198036a41f8006a201c37030020014198036a41f0006a201b37030020014198036a41e8006a201a37030020014198036a41e0006a201937030020014198036a41d8006a202037030020014198036a41d0006a201f37030020014198036a41c8006a201e37030020014198036a41c0006a201d37030020014198036a41386a202437030020014198036a41306a202337030020014198036a41286a202237030020014198036a41206a202137030020014198036a41186a202937030020014198036a4180016a2017370300200120273703a803200120263703a003200120253703980320034200370300200142003703a004419188c0004115200141a0046a1003200141306a41086a2003290300370300200120012903a004370330200141103602a4042001200141306a3602a004200f200c200141a0046a10510240200c450d00200641b0016c41d07e6a210903402002102a200241b0016a2102200941d07e6a22090d000b0b02402005450d00200710290b411310322202450d012002410f6a41002800c68740360000200241086a41002900bf8740370000200241002900b7874037000020024113412610342202450d022002200a360013200141a8056a41186a22094200370300200141a8056a41106a220b4200370300200141a8056a41086a220c4200370300200142003703a80520024117200141a8056a100020014190026a41186a200929030037030020014190026a41106a200b29030037030020014190026a41086a200c290300370300200120012903a80537039002200141a0046a20014190026a1052024020012802b004220b450d0020014190026a412010040b200141a8046a2903002113200141a0046a41186a280200210c20012903a004211520012802b404210f200210290240200b0d0020014198036a102a0c040b0240200c4105742209450d00200b210203402002201520131053200241206a2102200941606a22090d000b0b200141c8046a2013370300200141c0046a2015370300200141b8046a200c360200200141b4046a200f360200200141b0046a200b360200200141ac046a200a360200200141a8046a41013a0000200141053a00a00441014100200141a0046a104c200141a0046a20014198036a418801109b051a20014190026a200041809c316a200141a0046a41004180de34104d2001280290024101470d0320012802940221020c040b41a888c000200920061036000b41134101102e000b41264101102e000b410021020b200141f0056a240020020f0b41f7cdc3004133200141a0046a41ecd6c3001054000b9f950107087f017e067f087e087f017e017f230041800a6b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200200541144b0d16200141046a210720050e150102030405060708090a0b0c0d0e0f101112131415010b200041133a00000c4c0b02402006450d0020042d0001210620012003417e6a22083602042001200441026a360200200641054b0d004101210902400240024002400240024020060e06510001020304510b200241086a2001102c20022802080d052001280204200228020c2204490d052004417f4c0d2002400240024020040d00410121050c010b2004102d2205450d0120072802002004490d06200520012802002004109b051a200128020422032004490d232001200320046b3602042001200128020020046a3602000b2005450d062004ad220a422086200a84210a410221090c510b20044101102e000b20084108490d042004290002210a2001200341766a36020420012004410a6a360200410321090c4f0b200241106a2001102c20022802100d03200128020420022802142204490d032004417f4c0d1e02400240024020040d00410121050c010b2004102d2205450d0120072802002004490d04200520012802002004109b051a200128020422032004490d222001200320046b3602042001200128020020046a3602000b2005450d042004ad220a422086200a84210a410421090c4f0b20044101102e000b200241286a2001102c20022802280d02200728020041186e220b41186c2204417f4c0d1d200228022c210c0240024020040d00410421050c010b200410322205450d210b0240200c450d004100210d41002106410021080340200241206a2001102c02400240024020022802200d00200128020420022802242204490d002004417f4c0d2202400240024020040d004101210e0c010b2004102d220e450d3a20072802002004490d01200e20012802002004109b051a200128020422032004490d282001200320046b3602042001200128020020046a3602000b200241186a2001102c024020022802180d002001280204200228021c2203490d002003417f4c0d24024002400240024020030d004101210f0c010b2003102d220f450d0120072802002003490d02200f20012802002003109b051a200128020422092003490d2c2001200920036b3602042001200128020020036a3602000b200841016a21092008200b470d06200d20092009200d491b220bad42187e220a422088a70d55200aa7221041004e0d050c550b20034101102e000b200f10290b2004450d010b200e10290b02402008450d002005210103400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141186a2101200641686a22060d000b0b200b0d050c060b0240024020080d002010103221050c010b200520062010103421050b2005450d260b200520066a2208200e360200200841146a2003ad220a3e02002008410c6a200a422086200fad84370200200841046a2004ad220a422086200a84370200200d41026a210d200641186a210620092108200c2009470d000b0b2005450d02200cad422086200bad84210a410521090c4d0b200241386a2001102c20022802380d012007280200410c6e220e410c6c2204417f4c0d1c200228023c210f0240024020040d00410421050c010b200410322205450d240b024002400240200f450d004100210841002103410021090340200241306a2001102c20022802300d03200128020420022802342204490d032004417f4c0d200240024020040d004101210d0c010b2004102d220d450d3820072802002004490d03200d20012802002004109b051a200128020422062004490d292001200620046b3602042001200128020020046a3602000b200941016a210602402009200e470d002008200620062008491b220ead420c7e220a422088a70d50200aa7220b4100480d500240024020090d00200b103221050c010b20052003200b103421050b2005450d2a0b200520036a2209200d360200200941086a2004360200200941046a2004360200200841026a21082003410c6a210320062109200f2006470d000b0b2005450d03200fad422086200ead84210a410621090c4e0b200d10290b02402009450d002005210103400240200141046a280200450d00200128020010290b2001410c6a2101200341746a22030d000b0b200e450d010b200510290b200041133a00000c4b0b2006450d2320042d0001210520012003417e6a22063602042001200441026a36020020050d232006450d2320042d0002210520012003417d6a22073602042001200441036a360200200541014b0d23410221060240024020050e020100010b2007450d2420042d0003210620012003417c6a3602042001200441046a3602000b200020063a0001200041013a0000200041026a200241f8086a418601109b051a0c4a0b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241c0006a20011096012002290340a70d002002290348210a200041023a0000200020022800f007360001200041086a200a370300200041046a200241f3076a280000360000200041106a200241f8086a41f800109b051a0c4a0b200041133a00000c490b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241f0076a2001104120022802f00722010d130b200041133a00000c480b02402006450d0020012003417e6a3602042001200441026a3602000b200041133a00000c470b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541024b0d00024002400240024020050e03000102000b200241f8086a2001109e0120022d00f8084102460d0320024194096a290200210a2002418c096a2902002111200241f8086a41106a280200210720024184096a280200210420024180096a280200210320022802fc08210520022802f8082106200241d0006a200110970120022802500d03200241d0006a41106a29030021124101210142002113200229035821140c020b200241f8086a2001109e0120022d00f8084102460d02200241f0076a41086a20024190096a290300370300200241f0076a41106a20024198096a2802003602002002200241f8086a41106a2903003703f00720024184096a2802002104200241f8086a41086a280200210320022802fc08210520022802f808210620024180016a2001109701200229038001a70d0220024180016a41106a29030021122002290388012114200241e8006a20011097012002290368a70d02200241e8006a41106a290300211520022903702116200241b0056a41106a200241f0076a41106a280200360200200241b0056a41086a200241f0076a41086a290300370300200220022903f00722133703b005200241bc056a290200210a20022902b40521112013a7210741022101420021130c010b200241f8086a2001109e0120022d00f8084102460d0120024194096a290200210a2002418c096a2902002111200241f8086a41106a2209280200210720024184096a2802002104200241f8086a41086a2208280200210320022802fc08210520022802f8082106200241f8086a2001109e0120022d00f8084102460d01200241f0076a41206a220d200241f8086a41206a280200360200200241f0076a41186a220e200241f8086a41186a290300370300200241f0076a41106a2009290300370300200241f0076a41086a2008290300370300200220022903f8083703f00720024198016a2001109701200229039801a70d0120024198016a41106a290300211720022903a0012118200241f8076a290300211220024180086a2903002116200e2903002115200d350200211320022903f0072114410321010b200041053a00002000200228009807360001200041e0006a2017370000200041d8006a2018370000200041c8006a2015370000200041c0006a2016370000200041386a2012370000200041306a2014370000200041286a200a370000200041206a2011370000200041d0006a20133700002000411c6a2007360000200041186a2004360000200041146a2003360000200041106a20053600002000410c6a2006360000200041086a2001360000200041e8006a200229039006370300200041046a2002419b076a280000360000200041f0006a20024190066a41086a290300370300200041f8006a20024190066a41106a29030037030020004180016a20024190066a41186a2903003703000c470b200041133a00000c460b2006450d4120042d0001210520012003417e6a22193602042001200441026a3602002005410c4b0d41410421104100211a4100211b02400240024002400240024002400240024002400240024020050e0d0001024e030405060708090a0b000b200241f0076a2001109e0120022d00f0074102460d4c200241fc076a290200211120024190086a280200210b2002418f086a2d000021082002418e086a2d0000210d2002418d086a2d0000210c20024189086a280000210420024185086a280000210f20024184086a2d0000210e20022902f407210a20022802f0072106200241b0016a200110970120022903b001a70d4c20072802002203450d4c200241c0016a290300211420022903b8012112200128020022052d0000210920012003417f6a360204410121102001200541016a36020020094103492201450d4c200441807e71410020011b211b2004410020011b211a0c4d0b200241c8016a200110970120022903c801a70d4b200241d8016a290300211120022903d001210a410221104100211b0c4c0b200241e0016a200110970120022903e001a70d4a200241f0016a290300211120022903e801210a410321104100210c4100211a4100211b0c4b0b200241f8016a200110970120022903f801a70d4920024188026a2903002111200229038002210a410521104100211b0c4a0b20024190026a2001102c2002280290020d48200728020041246e221c41246c2204417f4c0d1b200228029402211d0240024020040d00410421060c010b200410322206450d270b0240201d450d004123210520024180086a211e41002107410021040340200241f0076a2001109e01024020022d00f00722094102470d00201c450d4b200610290c4b0b200441016a2103201e290300210a20022903f807211120022d009308210820022d009208210d20022d009108210e200228008d08210f200228008908210b20022d008808210c20022802f407211020022d00f307211b20022d00f207211920022d00f107211f02402004201c470d002007200320032007491b221cad42247e2212422088a70d4d2012a722204100480d4d0240024020040d002020103221060c010b20062005415d6a2020103421060b2006450d2a0b200620056a220420083a0000200441656a2208200a370008200820113700002004417f6a200d3a00002004417e6a200e3a00002004417a6a200f360000200441766a200b360000200441756a200c3a0000200441616a2010360000200441606a201b3a00002004415f6a20193a00002004415e6a201f3a00002004415d6a20093a0000200741026a2107200541246a210520032104201d2003470d000b0b2006450d48201dad422086201cad84210a42002111410621104100211b0c490b410721104100211b0c480b2019450d4620042d0002210920012003417d6a3602042001200441036a360200200941034f0d46410821104100211b0c470b200241f0076a2001109e0120022d00f0074102460d4520024189086a280000221a41807e71211b200241fc076a290200211120024190086a280200210b2002418f086a2d000021082002418e086a2d0000210d2002418d086a2d0000210c20024185086a280000210f20024184086a2d0000210e20022902f407210a20022802f0072106410921100c460b20024198026a2001102c2002280298020d44200228029c022106410a21104100211b0c450b410b21104100211b0c440b410c21104100211b0c430b200241f0076a2001103120022802f0072206450d4120022902f407210a42002111410d21104100211b0c420b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241f8086a200110aa0120022d00f8084101460d00200241f0076a200241f8086a41017241e000109b051a200241a0026a2001102c20022802a0020d00200128020420022802a4022204490d002004417f4c0d14024002400240024020040d004101210341010d010c040b2004102d2203450d0120072802002004490d02200320012802002004109b052105200128020422062004490d242001200620046b3602042001200128020020046a3602002005450d030b20024190066a200241f0076a41e000109b051a200241b0056a20024190066a41e000109b051a200041073a0000200020022f00f8063b0001200041036a200241fa066a2d00003a00002000410c6a2004360000200041086a2004360000200041046a2003360000200041106a200241b0056a41e000109b051a20004180016a20024198076a41106a290300370300200041f8006a20024198076a41086a290300370300200041f0006a2002290398073703000c470b20044101102e000b200310290b200041133a00000c440b2006450d3e20042d0001210520012003417e6a221d3602042001200441026a360200200541104b0d3e410e211a4100211c024002400240024002400240024002400240024002400240024002400240024020050e11000102030405060708090a0b0c4d0d0e0f000b200241f0076a2001104f20022d00f0074113460d4d200241f8086a200241f0076a418801109b051a41880110322206450d392006200241f8086a418801109b052104200241a8026a2001109701024020022903a802a7450d002004102a200410290c4e0b200241b8026a290300210a2004411876211c20022903b0022211422088a7211f2011a7211b4101211a0c4c0b200241c0026a2001102c20022802c0020d4c20022802c4022206411876211c4102211a0c4a0b200241c8026a2001102c20022802c8020d4b20072802002204450d4b20022802cc022106200128020022052d0000210320012004417f6a3602042001200541016a360200200341ff0071220d41064b0d4b2006411876211c200341077621084103211a0c480b200241d0026a2001102c20022802d0020d4a20072802002204450d4a20022802d4022106200128020022052d0000210320012004417f6a3602042001200541016a360200200341ff0071220d41064b0d4a2006411876211c200341077621084104211a0c470b201d4104490d492004280002210620012003417a6a3602042001200441066a3602002006411876211c4105211a0c470b200241f0076a2001104f20022d00f0074113460d48200241f8086a200241f0076a418801109b051a41880110322206450d352006200241f8086a418801109b05411876211c4106211a0c460b200241f0076a2001104f20022d00f0074113460d47200241f8086a200241f0076a418801109b051a41880110322206450d352006200241f8086a418801109b05411876211c4107211a0c450b200241f0076a2001104f20022d00f0074113460d46200241f8086a200241f0076a418801109b051a41880110322206450d352006200241f8086a418801109b05411876211c4108211a0c440b41002105200241003a0098092003417e6a2109417d21060340024020092005470d00200541ff0171450d47200241003a0098090c470b200241f8086a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a0098092006417f6a21062007210520074120470d000b200241b8056a220520024181096a290000370300200241b0056a41106a20024189096a290000370300200241c7056a220620024190096a290000370000200220022900f908220a3703b005200320076b2203417e6a4104490d4520022d00b405210920022f01b205210d200241bd056a330000211120023500b905211220052d0000211b20022f01b605211a200241c5056a3100002114200241c3056a330000211320023500bf05211820022d00f80821082006280000210f20022d00b505211c20022d00b105211020022800cb05210b20022d00c605210e200420076a220441026a280000210c20012003417a6a22053602042001200441066a220736020020054104490d45200d2009411074722106200aa7210d200728000021192001200341766a36020420012004410a6a36020020182013201442108684422086844208862012201142208684221142ffffffffffff3f83221242288884210a2012421886201a201b41107472ad42ffffff078384a7211b2011420888a7211f4109211a0c440b41002105200241003a0098092003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d46200241003a0098090c460b200241f8086a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a0098092003417f6a21032006210520064120470d000b200241b8056a20024181096a290000370300200241c7056a220120024190096a290000370000200241b0056a41106a20024189096a290000370300200220022900f90822113703b00520022f01b20520022d00b40541107472210620022901b6052212422088a7211f20022d00f80821082001280000210f200241be056a290100210a20022d00b505211c20022d00b105211020022800cb05210b20022d00c605210e2011a7210d2012a7211b410a211a0c430b200241d8026a2001102c20022802d8020d4320022802dc022206411876211c410b211a0c410b200241f0026a2001102c20022802f0020d4220022802f4022106200241e8026a2001102c20022802e8020d4220022802ec02211b200241e0026a2001102c20022802e0020d4220022802e402211f2006411876211c410c211a0c410b41002105200241003a0098092003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d43200241003a0098090c430b200241f8086a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a0098092003417f6a21032006210520064120470d000b200241b8056a20024181096a290000370300200241c7056a220120024190096a290000370000200241b0056a41106a20024189096a290000370300200220022900f90822113703b00520022f01b20520022d00b40541107472210620022901b6052212422088a7211f20022d00f80821082001280000210f200241be056a290100210a20022d00b505211c20022d00b105211020022800cb05210b20022d00c605210e2011a7210d2012a7211b410d211a0c400b41002105200241003a0098092003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d42200241003a0098090c420b200241f8086a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a0098092003417f6a21032006210520064120470d000b200241b8056a220120024181096a290000370300200241b0056a41106a20024189096a290000370300200241c7056a220420024190096a290000370000200220022900f90822123703b00520023500bf05200241c3056a330000200241c5056a310000421086844220868442088620023500b905200241bd056a33000042208684221142288884210a201142188620023301b60520013100004210868484a7211b20022f01b20520022d00b4054110747221062011420888a7211f20022d00f80821082004280000210f20022d00b505211c20022d00b105211020022800cb05210b20022d00c605210e2012a7210d410f211a0c3f0b41002105200241003a0098092003417e6a21092003417d6a21060340024020092005470d00200541ff0171450d41200241003a0098090c410b200241f8086a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a0098092006417f6a21062007210520074120470d000b200241b8056a20024181096a290000370300200241c0056a20024189096a290000370300200241c7056a220520024190096a290000370000200220022900f908220a3703b005200241e8076a41046a20022d00b4053a0000200241f8066a41046a200241bd056a2f00003b01002002200a3e02e807200220022800b9053602f8062003417e6a2007460d3f20022d00f808210820022800b505211c2005290000211120022900bf05210a200420076a220441026a2d00002109200120063602042001200441036a360200200941064b0d3f200241a0076a200241f8066a41046a2f01003b0100200220022802e807220d3602e007200220022802f80636029c072002201c360298072002200a3701a207200a423888201142088684a7210e4110211a20022f01e207200241e8076a41046a2d00004110747221062011422088a7210b2002290099072212422088a7211f200241a1076a290000210a20022d00e10721102011a7210f2012a7211b0c3e0b4111211a0c3d0b20024190066a200110c90220022d0090064105470d0d200041133a00000c420b20024190066a200110c90220022d0090064105470d0d200041133a00000c410b2006450d3720042d0001210520012003417e6a3602042001200441026a360200200541094b0d37024002400240024002400240024002400240024020050e0a00010203040506070809000b200241f0076a2001103f20022802f0072204450d40200241f8076a280200210520022802f4072103200241f8026a2001102c024020022802f802450d0020030d400c410b0240200728020022094104490d0020022802fc02210620012802002208280000210720012009417c6a3602042001200841046a360200410121010c3f0b20030d3f0c400b200241f0076a2001103f20022802f0072204450d3f200241f8076a280200210520022802f407210320024180036a2001102c0240200228028003450d002003450d400c3f0b0240200728020022094104490d00200228028403210620012802002208280000210720012009417c6a3602042001200841046a360200410221010c3e0b20030d3e0c3f0b20024198036a2001102c2002280298030d3e200228029c032104200241f0076a2001109e0120022d00f0074102460d3e20024190066a41086a20024188086a29030037030020024190066a41106a20024190086a2802003602002002200241f0076a41106a29030037039006200241fc076a2802002107200241f0076a41086a280200210620022802f407210520022802f007210320024190036a2001102c2002280290030d3e200228029403210920024188036a2001102c2002280288030d3e200241a0066a280200210820024198066a29030021142002290390062112200228028c03ad210a42002111410321010c3c0b200241a0036a2001102c20022802a0030d3d4104210120022802a40321040c3b0b200241a8036a2001102c20022802a8030d3c4105210120022802ac0321040c3a0b200241f0076a2001109e0120022d00f0074102460d3b20024190066a41086a20024188086a29030037030020024190066a41106a20024190086a2802003602002002200241f0076a41106a29030037039006200241f0076a41086a290300211320022903f0072118200241b8036a200110970120022903b803a70d3b200241b8036a41106a290300211120022903c003210a200241b0036a2001102c20022802b0030d3b20022802b4032108200241b0056a41106a20024190066a41106a280200360200200241b0056a41086a20024190066a41086a290300370300200220022903900622173703b0052018422088a721032013422088a72106200241bc056a290200211420022902b40521122017a721072018a721042013a72105410621010c390b200241d0036a2001102c20022802d0030d3a4107210120022802d40321040c380b200241f0076a2001109e0120022d00f0074102460d392002418c086a290200211420024184086a290200211220024180086a2802002107200241fc076a280200210641082101200241f0076a41086a280200210520022802f407210320022802f00721040c370b200241d8036a2001102c20022802d8030d384109210120022802dc0321040c360b200241e0036a2001102c20022802e0030d37410a210120022802e40321040c350b2006450d3320042d0001210520012003417e6a3602042001200441026a360200200541034b0d33024002400240024020050e0400010203000b41002105200241003a0090082003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d38200241003a0090080c380b200241f0076a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a0090082003417f6a21032006210520064120470d000b200241b0056a41106a20024181086a290000370300200241b8056a200241f0076a41096a290000220a370300200241c7056a2201200241f0076a41186a290000370000200241f8066a41096a200a370000200241f8066a41106a200241bf056a290000370000200220022d00f007220d3a00f806200220022900f1073700f9062001280000210f20022800cb05210b20022800ff06220c411876211020022800fb062201411876210820022d008f07211b2002290087072112200228008307211a20022d00fa06211920022d00f906211f4101211c0c350b41002105200241003a0090082003417e6a21072003417d6a21030340024020072005470d00200541ff0171450d37200241003a0090080c370b200241f0076a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a0090082003417f6a21032006210520064120470d000b200241b8056a200241f9076a290000370300200241c7056a2204200241f0076a41186a290000370000200241b0056a41106a20024181086a290000370300200220022900f107220a3703b00520022f01b20520022d00b40541107472210120022901b6052211a7220c41187621102011422088a7211a20022d00f007210d2004280000210f200241be056a290100211220022d00b505210820022d00b105211920022800cb05210b20022d00c605211b200aa7211f4102211c0c340b41002105200241003a009008410220036b21092003417d6a210603400240200920056a0d00200541ff0171450d36200241003a0090080c360b200241f0076a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a0090082006417f6a21062007210520074120470d000b200241b8056a200241f9076a290000370300200241c0056a20024181086a290000370300200241c7056a220520024188086a290000370000200220022900f107220a3703b005200241e8076a41046a20022d00b4053a0000200241f8066a41046a200241bd056a2f00003b01002002200a3e02e807200220022800b9053602f80620022d00f007210d20022800b50521082005290000211420022900bf05211241002105200241003a009008200420076a2109200720036b41026a210303400240200320056a0d00200541ff0171450d36200241003a0090080c360b200241f0076a20056a200920056a220441026a2d00003a0000200120063602042001200441036a3602002002200541016a22043a0090082006417f6a21062004210520044120470d000b200241c7056a220120024188086a290000370000200241b0056a41106a20024181086a290000370300200241b0056a41086a2203200241f9076a290000370300200220022900f10722133703b00520022d00f007210420012800002109200241c3056a3300002111200241c5056a3100002118200241bd056a330000210a2003310000211720022801b205210620022d00b105210520022800cb05210e20022d00c605210720023500bf05211620023500b905211520023301b6052121200241e0076a41046a2201200241e8076a41046a2d00003a0000200220022802e8073602e007200220083602980720024198076a41086a200241f8066a41046a2f01003b0100200220022802f80636029c07200220123701a207200241aa076a20143701002015200a422086842215421886202120174210868484210a201620112018421086844220868442088620154228888421112012423888201442088684a7211b2008410876210c20022f01e20720012d00004110747221012014422088a7210b20022900a1072112200228009d07211a20022d009c07211020022d00e107211920022d00e007211f2013a721032014a7210f4103211c0c330b200241f0076a2001103120022802f0072201450d3320022802f407220c411876211020014118762108200241f8076a280200211a4104211c0c320b024002402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241e8036a2001102c20022802e803450d010b200041133a00000c3f0b20022802ec0321012000410d3a0000200020022f00f0073b0001200041046a2001360200200041036a200241f2076a2d00003a0000200041086a200241f8086a418001109b051a0c3e0b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241f0036a2001102c20022802f0030d00200128020420022802f4032204490d002004417f4c0d0d024002400240024020040d00410121030c010b2004102d2203450d0120072802002004490d02200320012802002004109b051a200128020422052004490d1e2001200520046b3602042001200128020020046a3602000b2003450d022000410e3a0000200020022f00f0073b0001200041086a2004ad220a422086200a84370000200041046a2003360000200041036a200241f2076a2d00003a0000200041106a200241f8086a41f800109b051a0c400b20044101102e000b200310290b200041133a00000c3d0b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541024b0d0002400240024020050e03000102000b200241f8036a200110970120022903f803a70d0220024188046a290300210a2002290380042111200241f0076a2001109e0120022d00f0074102460d022002418c086a290200211220024184086a290200211420024180086a2802002101200241fc076a2802002104200241f8076a280200210320022802f407210520022802f0072106410121070c310b20024190046a2001102c2002280290040d014102210720022802940421060c300b20024198046a2001102c2002280298040d0041032107200228029c0421060c2f0b200041133a00000c3c0b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541044b0d0002400240024002400240024002400240024020050e050001020607000b200241f8086a200110ca0220022d00e8094102460d08200241f8076a200241a8096a29030037030020024180086a200241b0096a290300370300200220022903a0093703f0072002419c096a280200210b20024194096a28020021042002418d096a280000210820024189096a280000210d200228029809211b20022d009309210520022d009209210620022d009109210f20022d008809210e200229038009210a20022903f8082111200241e8096a2903002114200241c8096a2903002113200241d5096a2800002101200241d1096a280000210320022903e009211820022903c009211720022802dc09210720022d00db09210c20022d00da09211f20022d00d909211c20022d00d009211d20022903b8092112410121220c020b200241a8046a200110960120022903a804a70d0720022903b004210a200241a0046a2001102c20022802a0040d07200128020420022802a4042204490d072004417f4c0d1202400240024020040d00410121090c010b2004102d2209450d0120072802002004490d08200920012802002004109b051a200128020422032004490d232001200320046b3602042001200128020020046a3602000b2009450d082004ad22114220862011842111200241f0076a41106a200241f8086a41106a290300370300200241f0076a41086a200241f8086a41086a290300370300200220022903f8083703f007410221220c350b20044101102e000b200241f8086a2001109e0120022d00f8084102460d0620024184096a290200210a20024198096a280200210420024197096a2d0000210520024196096a2d0000210620024195096a2d0000210f20024191096a28000021082002418d096a280000210d2002418c096a2d0000210e20022902fc08211120022802f8082109200241d0046a200110970120022903d004a70d06200241e0046a290300211420022903d8042113200241c0046a200110960120022903c004a70d0620022903c8042112200241b8046a2001102c20022802b8040d06200128020420022802bc04220b490d06200b417f4c0d1102400240200b0d004101211b41010d010c080b200b102d221b450d022007280200200b490d03201b2001280200200b109b05210320012802042207200b490d2220012007200b6b36020420012001280200200b6a3602002003450d070b20024180086a2014370300200220133703f8072002200b3602f007410321220b0c320b200b4101102e000b201b10290c030b20024180056a2001109701200229038005a70d0220024190056a290300210a2002290388052111200241f0046a200110960120022903f004a70d0220022903f804211241002103200241003a0098092007280200417f6a21040240024002400240024003402004417f460d01200241f8086a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a0098092004417f6a21042005210320054120470d000b200241a0076a200241f8086a410e6a2901002214370300200241a8076a200241f8086a41166a2204290100370300200241b0076a20024196096a2f01003b0100200241f8066a410e6a2014370100200241f8066a41166a20042f01003b0100200220022d00f80822103a00f806200220022800f9083600f906200220022d00fd083a00fd06200220022901fe0822143701fe06200220143703980720022801ae07210820022801aa07210d200241e8046a2001102c20022802e8040d07200128020420022802ec04220b490d07200b417f4c0d12200b0d01410121040c020b200341ff0171450d06200241003a0098090c060b200b102d2204450d012007280200200b490d0220042001280200200b109b051a20012802042203200b490d2120012003200b6b36020420012001280200200b6a3602000b2004450d04200220113703f00720022012370380082002200a3703f80720024187076a290000210a20022900ff06211120022d008f07210e20022800fb06210920022d00fa06211a20022d00f906211941042122200b211b0c310b200b4101102e000b200410290c020b41002105200241003a0098092003417e6a21092003417d6a21060340024020092005470d00200541ff0171450d03200241003a0098090c030b200241f8086a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a0098092006417f6a21062007210520074120470d000b2003417e6a2007460d0120024187096a290000210a20022900ff08211120022d00f808211020022d00f908211920022d00fa08211a20022800fb08210920022d008f09210e200228029009210d2002280294092108200420076a220c41026a2d0000211f200120063602042001200c41036a360200201f41014b0d014100210f02400240201f0e020100010b41002104200241003a009809200720036b41036a2106200320076b417c6a210303400240200620046a0d00200441ff0171450d04200241003a0098090c040b200241f8086a20046a200c20046a220541036a2d00003a0000200120033602042001200541046a3602002002200441016a22053a0098092003417f6a21032005210420054120470d000b200241b8056a20024181096a290000370300200241c0056a20024189096a290000370300200241c7056a220120024190096a290000370000200220022900f90822123703b005200241e8076a41046a20022d00b4053a0000200241f8066a41046a2203200241bd056a2f00003b0100200220123e02e807200220022800b9053602f80620022d00f808210620022800b505211b2001290000211420022900bf05211220022802f806210b20022800e907210420022d00e8072105200220032f01003b0198074101210f0b200241fa076a201437010020024186086a200241de076a2f01003b0100200220022f0198073b01f007200220123701f207200220022801da0736018208410521220c2e0b200910290b200041133a00000c3b0b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541014b0d000240024020050e020001000b200241f0076a2001104f20022d00f0074113460d01200241f8086a200241f0076a418801109b051a418801103222010d094188014108102e000b200241f8086a2001109e014102210420022d00f8084102460d0020024194096a290200210a2002418c096a290200211120024188096a280200210320024184096a280200210520024180096a280200210620022802fc08210720022802f80821010c090b200041133a00000c3a0b2006450d2920042d0001210520012003417e6a22063602042001200441026a36020020050d2920064104490d292004280002210b20012003417a6a3602042001200441066a360200200241a8056a2001102c20022802a8050d29200128020420022802ac052205490d292005417f4c0d080240024020050d004101210c41010d010c2b0b2005102d220c450d2620072802002005490d29200c20012802002005109b052104200128020422032005490d1b2001200320056b3602042001200128020020056a3602002004450d2a0b200241a0056a2001102c20022802a0050d272007280200410c6e220f410c6c2204417f4c0d0820022802a40521100240024020040d004104210e0c010b20041032220e450d1c0b0240024002400240024002402010450d00410021084100210341002109034020024198056a2001102c2002280298050d032001280204200228029c052204490d032004417f4c0d0f0240024020040d004101210d0c010b2004102d220d450d2c20072802002004490d03200d20012802002004109b051a200128020422062004490d242001200620046b3602042001200128020020046a3602000b200941016a210602402009200f470d002008200620062008491b220fad420c7e220a422088a70d3f200aa7221b4100480d3f0240024020090d00201b1032210e0c010b200e2003201b1034210e0b200e450d250b200e20036a2209200d360200200941046a2004ad220a422086200a84370200200841026a21082003410c6a21032006210920102006470d000b0b200e450d2c200c450d2e200728020022034104490d0220012802002207280000210820012003417c6a22043602042001200741046a36020020044104490d032007280004210d2001200341786a22093602042001200741086a36020041002104200241003a00b809200341776a2103034020092004460d05200241f8086a20046a200720046a220641086a2d00003a0000200120033602042001200641096a3602002002200441016a22063a00b8092003417f6a210320062104200641c000470d000b200241f0076a41386a2201200241f8086a41386a290300370300200241f0076a41306a2204200241f8086a41306a290300370300200241f0076a41286a2203200241f8086a41286a290300370300200241f0076a41206a2207200241f8086a41206a290300370300200241f0076a41186a2209200241f8086a41186a290300370300200241f0076a41106a221b200241f8086a41106a290300370300200241f0076a41086a221a200241f8086a41086a290300370300200220022903f8083703f007200641ff017141c000490d2b20024190066a41386a2206200129030037030020024190066a41306a2004290300220a37030020024190066a41286a2003290300221137030020024190066a41206a2007290300221237030020024190066a41186a2009290300221437030020024190066a41106a201b290300221337030020024190066a41086a201a2903002218370300200220022903f007221737039006200241b0056a41306a200a370300200241b0056a41286a2011370300200241b0056a41206a2012370300200241b0056a41186a2014370300200241b0056a41106a2013370300200241b0056a41086a2018370300200241b0056a41386a2006290300370300200220173703b005200c450d2e20024198076a41386a2201200241b0056a41386a29030037030020024198076a41306a2204200241b0056a41306a29030037030020024198076a41286a2203200241b0056a41286a29030037030020024198076a41206a2206200241b0056a41206a29030037030020024198076a41186a2207200241b0056a41186a29030037030020024198076a41106a2209200241b0056a41106a29030037030020024198076a41086a221b200241b0056a41086a290300370300200220022903b00537039807200041123a0000200041246a200d360000200041206a20083600002000411c6a2010360000200041186a200f360000200041146a200e360000200041106a20053600002000410c6a2005360000200041086a200c360000200041046a200b360000200020022f00f1063b0001200041036a200241f3066a2d00003a0000200041286a200229039807370000200041306a201b290300370000200041386a2009290300370000200041c0006a2007290300370000200041c8006a2006290300370000200041d0006a2003290300370000200041d8006a2004290300370000200041e0006a200129030037000020004180016a200241f8066a41186a290300370300200041f8006a200241f8066a41106a290300370300200041f0006a200241f8066a41086a290300370300200041e8006a20022903f8063703000c3e0b200d10290b02402009450d00200e210103400240200141046a280200450d00200128020010290b2001410c6a2101200341746a22030d000b0b200f450d2a200e10290c2a0b02402005450d00200c10290b02402010450d002010410c6c2104200e210103400240200141046a280200450d00200128020010290b2001410c6a2101200441746a22040d000b0b200f450d2b200e10290c2b0b02402005450d00200c10290b02402010450d002010410c6c2104200e210103400240200141046a280200450d00200128020010290b2001410c6a2101200441746a22040d000b0b200f450d2a200e10290c2a0b200441ff0171450d26200241003a00b8090c260b02402006450d0020012003417e6a3602042001200441026a3602000b200041133a00000c380b02402006450d0020012003417e6a3602042001200441026a3602000b200041133a00000c370b200041133a00000c360b20022902f407210a200041033a0000200020022f0090063b0001200041086a200a370000200041046a2001360000200041036a20024192066a2d00003a0000200041106a200241f8086a41f800109b051a0c350b200241b0056a41206a20024190066a41206a290300220a370300200241fb076a20024190066a41086a29030037000020024183086a20024190066a41106a2903003700002002418b086a20024190066a41186a29030037000020024193086a200a37000020022002290390063700f307200041093a0000200020022900f007370001200041096a200241f0076a41086a290000370000200041116a200241f0076a41106a290000370000200041196a200241f0076a41186a290000370000200041216a200241f0076a41206a290000370000200041286a20024197086a2800003600002000412c6a200241f8086a41dc00109b051a0c340b200241b0056a41206a20024190066a41206a290300220a370300200241fb076a20024190066a41086a29030037000020024183086a20024190066a41106a2903003700002002418b086a20024190066a41186a29030037000020024193086a200a37000020022002290390063700f3072000410a3a0000200020022900f007370001200041096a200241f0076a41086a290000370000200041116a200241f0076a41106a290000370000200041196a200241f0076a41186a290000370000200041216a200241f0076a41206a290000370000200041286a20024197086a2800003600002000412c6a200241f8086a41dc00109b051a0c330b2001200241f8086a418801109b051a410121040b200041113a0000200020022f00b0053b0001200041246a200a3700002000411c6a2011370000200041186a2003360000200041146a2005360000200041106a20063600002000410c6a2007360000200041086a2001360000200041046a2004360000200041036a200241b2056a2d00003a00002000412c6a20024190066a41dc00109b051a0c310b102f000b200420031030000b200420031030000b20044104102e000b200420031030000b200320091030000b20104104102e000b20044104102e000b200420061030000b200b4104102e000b200041133a00000c260b20044104102e000b20204104102e000b200420061030000b200420051030000b200420031030000b200b20071030000b200b20031030000b200520031030000b20044104102e000b200420061030000b201b4104102e000b20044101102e000b20044101102e000b4188014108102e000b4188014108102e000b4188014108102e000b4188014108102e000b20044101102e000b20054101102e000b02402005450d00200c10290b02402010450d002010410c6c2104200e210103400240200141046a280200450d00200128020010290b2001410c6a2101200441746a22040d000b0b200f450d02200e10290c020b2005450d010b200c10290b200041133a00000c0f0b20024190066a41106a221e200241f0076a41106a29030037030020024190066a41086a2220200241f0076a41086a290300370300200220022903f00737039006200041103a0000200020022800f106360001200041046a200241f4066a280000360000200041346a200b360000200041306a201b3600002000412c6a20043600002000412b6a20053a00002000412a6a20063a0000200041296a200f3a0000200041256a2008360000200041216a200d360000200041206a200e3a0000200041186a200a370000200041106a20113700002000410c6a20093600002000410b6a201a3a00002000410a6a20193a0000200041096a20103a0000200041086a20223a0000200041d0006a2012370000200041e9006a2003360000200041ed006a2001360000200041f4006a2007360000200041f8006a201837000020004180016a2014370000200041f3006a200c3a0000200041f2006a201f3a0000200041f1006a201c3a0000200041e8006a201d3a0000200041d8006a2017370000200041e0006a2013370000200041c8006a201e290300370000200041c0006a2020290300370000200041386a2002290390063700000c0e0b2000410f3a00002000200228009006360001200041386a200a370000200041306a2011370000200041286a2012370000200041206a20143700002000411c6a2001360000200041186a2004360000200041146a2003360000200041106a20053600002000410c6a2006360000200041086a2007360000200041046a20024193066a280000360000200041c0006a200241f8086a41c800109b051a0c0d0b2000410c3a0000200020022f0090063b0001200041346a20113700002000412c6a200a370000200041c1006a200e3600002000413d6a20093600002000413c6a20073a0000200041286a2006360000200041276a20053a0000200041266a20033a0000200041256a20043a0000200041216a200b3600002000411d6a200f3600002000411c6a201b3a0000200041146a2012370000200041106a201a360000200041076a20193a0000200041066a201f3a0000200041056a200d3a0000200041046a201c3a0000200041036a20024192066a2d00003a00002000410c6a2010411874200c41ffffff077172360000200041086a2008411874200141ffffff07717236000020004180016a200241b0096a290300370300200041f8006a200241a8096a290300370300200041f0006a200241f8086a41286a290300370300200041e8006a20024198096a290300370300200041e0006a200241f8086a41186a290300370300200041d8006a200241f8086a41106a290300370300200041d0006a200241f8086a41086a290300370300200041c8006a20022903f8083703000c0c0b200041133a00000c0b0b2000410b3a00002000200228009807360001200041c0006a2011370000200041386a200a370000200041286a2014370000200041206a2012370000200041346a2009360000200041306a20083600002000411c6a2007360000200041186a2006360000200041146a2005360000200041106a20033600002000410c6a2004360000200041086a2001360000200041c8006a20022903f808370300200041046a2002419b076a280000360000200041d0006a200241f8086a41086a290300370300200041d8006a200241f8086a41106a290300370300200041e0006a200241f8086a41186a290300370300200041e8006a200241f8086a41206a290300370300200041f0006a200241f8086a41286a290300370300200041f8006a200241f8086a41306a29030037030020004180016a200241f8086a41386a2903003703000c0a0b200410290b200041133a00000c080b4100211f4200210a0c010b4100211f4200210a0b200041083a0000200020022800f106360001200041186a200a370000200041346a4100360000200041306a20193600002000412c6a200c360000200041296a20093a0000200041256a200b360000200041216a200f360000200041206a200e3a00002000410b6a20103a00002000410a6a200d3a0000200041096a20083a0000200041086a201a3a0000200041046a200241f4066a2800003600002000410c6a201c411874200641ffffff077172360000200041106a201fad422086201bad84370000200041386a20024190066a41d000109b051a0c050b200041133a00000c040b200041133a00000c030b200041063a00002000200228009006360001200041386a2014370000200041306a2012370000200041186a2011370000200041106a200a3700002000412c6a200b3600002000412b6a20083a00002000412a6a200d3a0000200041296a200c3a0000200041216a200f360000200041206a200e3a00002000410c6a2006360000200041096a20093a0000200041086a20103a0000200041046a20024193066a280000360000200041256a201b201a41ff017172360000200041c0006a200241f8086a41c800109b051a0c020b1033000b200041003a0000200020022800f007360001200041106a200a3700002000410c6a2005360000200041086a2009360000200041046a200241f3076a280000360000200041186a200241f8086a41f000109b051a0b200241800a6a24000bbc0201047f230041c0006b2202240002400240411310322203450d002003410f6a41002800c68740360000200341086a41002900bf8740370000200341002900b7874037000020034113412610342203450d0120032001360013200241206a41186a22014200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034117200241206a1000200241186a2001290300370300200241106a2004290300370300200241086a200529030037030020022002290320370300200241206a200210520240024020022802300d00200041003602100c010b20002002290320370300200041186a2001290300370300200041106a2004290300370300200041086a200241206a41086a2903003703000b20031029200241c0006a24000f0b41134101102e000b41264101102e000bb70201057f230041106b2203240020034100360208200342013703002001200310660240024002402001450d00200141b0016c2104034020004188016a28020021050240024020032802042206200328020822016b4104490d00200328020021060c010b200141046a22072001490d0420064101742201200720072001491b22014100480d040240024020060d002001103221060c010b200328020020062001103421060b2006450d032003200136020420032006360200200328020821010b2003200141046a360208200620016a200536000020002003105f2000418c016a2003108101200041b0016a2100200441d07e6a22040d000b0b2003280204210020022802002002280204200328020022012003280208100502402000450d00200110290b200341106a24000f0b20014101102e000b1033000bdb0102027f037e230041206b220224002002410036021020014120200241106a10062101024002400240024020022802102203417f460d0020010d010b200041003602100c010b200220013602082002200336020c20034110490d012002200341706a36020c2002200141106a360208200141086a290000210420012900002105200241106a200241086a103120022802102203450d012002290214210620002004370308200020053703002000200637021420002003360210200110290b200241206a24000f0b41f7cdc3004133200241106a41ecd6c3001054000bb50304037f017e017f047e230041c0006b2203240002400240411810322204450d00200441002900ecd540370000200441106a41002900fcd540370000200441086a41002900f4d540370000200342988080808003370234200320043602302000200341306a10810120032802342104200341186a20032802302205200328023810a101200341186a41106a2903002106200328021821072003290320210802402004450d00200510290b411410322204450d0120022006420020071b22062008420020071b2208200156200620025620062002511b22071b21092001200820071b2102200441002900d8d540370000200441106a41002800e8d540360000200441086a41002900e0d54037000020034294808080c002370234200320043602302000200341306a10810120032802342104200320032802302205200328023810a101200341106a2903004200200328020022071b210a2003290308420020071b210102402004450d00200510290b2000200120027c220b200a20097c200b200154ad7c10a5012000200820027d200620097d2008200254ad7d10bc01200341c0006a24000f0b41184101102e000b41144101102e000b810101017f230041c0006b220424002004200136020c2004200036020820042003360214200420023602102004412c6a41023602002004413c6a41043602002004420237021c20044190aac600360218200441053602342004200441306a3602282004200441106a3602382004200441086a360230200441186a41a4aac600107d000bfc0202047f017e230041d0006b22022400024002400240411310322203450d002003410f6a41002800f08740360000200341086a41002900e98740370000200341002900e1874037000020034113412610342203450d0120032001360013200241206a41186a22014200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034117200241206a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903203703002002410036022020024120200241206a100621040240024020022802202201417f460d002002200136024420022004360240200241206a200241c0006a103120022802202205450d042002290224210602402001450d00200410290b20002006370204200020053602000c010b20004100360208200042013702000b20031029200241d0006a24000f0b41134101102e000b41264101102e000b41f7cdc3004133200241c8006a41ecd6c3001054000be90201077f230041c0006b2202240002400240411010322203450d0041002104200341002900f88640370000200341086a41002900808740370000200242908080808002370224200220033602202001200241206a1057200228022421052002280228210120022802202103200241206a41186a22064200370300200241206a41106a22074200370300200241206a41086a220842003703002002420037032020032001200241206a1000200241186a2006290300370300200241106a2007290300370300200241086a2008290300370300200220022903203703002002410036022020024120200241206a100621010240024020022802202206417f460d002006450d0320012d0000220641ff0071220441074f0d0320011029200641077621010c010b410021010b02402005450d00200310290b200020043a0001200020013a0000200241c0006a24000f0b41104101102e000b41f7cdc3004133200241206a41ecd6c3001054000bbe2901067f20002802002102024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a22032802002204200141086a220528020022066b4104490d00200128020021040c010b200641046a22072006490d2220044101742206200720072006491b22064100480d220240024020040d002006103221040c010b200128020020042006103421040b2004450d0120012004360200200141046a2006360200200141086a28020021060b2005200641046a360200200420066a200236000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d0220012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d00043a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d0320012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d00053a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d0420012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d00063a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d0520012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d00073a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d0620012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d00083a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d0720012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d00093a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d0820012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d000a3a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d0920012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d000b3a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d0a20012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d000c3a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d0b20012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d000d3a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d0c20012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d000e3a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d0d20012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d000f3a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d0e20012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d00103a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d0f20012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d00113a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d1020012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d00123a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d1120012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d00133a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d1220012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d00143a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d1320012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d00153a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d1420012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d00163a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d1520012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d00173a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d1620012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d00183a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d1720012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d00193a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d1820012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d001a3a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d1920012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d001b3a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d1a20012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d001c3a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d1b20012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d001d3a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d1c20012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d001e3a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d1d20012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d001f3a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d1e20012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d00203a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d1f20012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d00213a000002400240200328020020052802002206460d00200128020021040c010b200641016a22042006490d2220064101742202200420042002491b22024100480d220240024020060d002002103221040c010b200128020020062002103421040b2004450d2020012004360200200141046a2002360200200141086a28020021060b2005200641016a360200200420066a20002d00223a000002400240200328020020052802002203460d00200128020021060c010b200341016a22062003490d2220034101742204200620062004491b22044100480d220240024020030d002004103221060c010b200128020020032004103421060b2006450d2120012006360200200141046a2004360200200141086a28020021030b2005200341016a360200200620036a20002d00233a00000f0b20064101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20024101102e000b20044101102e000b1033000b950c04017f047e107f087e230041b0036b22052400024002400240024020040d00420021064200210742002108420021090c010b4200210820054190036a41186a220a420037030020054190036a41106a220b420037030020054190036a41086a220c4200370300200542003703900341f487c000411d20054190036a1000200541c8026a41186a200a290300370300200541c8026a41106a200b290300370300200541c8026a41086a200c29030037030020052005290390033703c802200541e0016a200541c8026a4120105941281032220c450d01200c4101360200200c20052903e001370204200c20052f0098013b0025200c410c6a200541e0016a41086a290300370200200c41146a200541e0016a41106a290300370200200c411c6a200541e0016a41186a290300370200200c41246a200541e0016a41206a2d00003a0000200c41276a2005419a016a2d00003a000020054198016a200c105a420021094200210642002107024020052d00d8014107460d002004417f6a210d200541e8026a410472210a200541a0026a210e200541e0016a41206a210f200541e0016a41186a2110200341ff0171211142002106420021074200210842002109034020102007370300200520063703f001200520083703e001200520093703e801200f20054198016a41c100109b05210402400240200e2002460d00200e20024120109d050d010b200a2004290200370200200a41086a200441086a2212290200370200200a41106a200441106a2213290200370200200a41186a200441186a2214290200370200200520013602e80241101032220b450d05200b41002900f88640370000200b41086a41002900808740370000200542908080808002370294032005200b36029003200541e8026a20054190036a105720052802940321152005280298032116200528029003211720054190036a41186a220b420037030020054190036a41106a2218420037030020054190036a41086a2219420037030020054200370390032017201620054190036a1000200541c8026a41186a200b290300370300200541c8026a41106a2018290300370300200541c8026a41086a201929030037030020052005290390033703c802200541c8026a41204101410041001007211602402015450d00201710290b2016417f470d0020052d00c0022117200b2014290000370300201820132900003703002019201229000037030020052004290000370390030240024020172011460d00417f2017201149201720114b1b41016a41014b0d010b200321170b20054188016a20054190036a105b20054188016a41086a290300211a200529038801211b02400240201741ff01710d00200541086a201b201a420a420010a105200541e8026a41186a200b290300370300200541e8026a41106a2018290300370300200541e8026a41086a201929030037030020052005290390033703e802200541186a2001200541e8026a4100200d1058200541186a41186a290300211c200541186a41086a290300211d2005290328211e2005290318211f20052903082220211b200541086a41086a2903002221211a0c010b200541c8006a201a42002017ad42ff01832220420010a005200541d8006a201b42002020420010a005200541e8026a41186a200b290300370300200541e8026a41106a2018290300370300200541e8026a41086a201929030037030020052005290390033703e802200541e8006a2001200541e8026a2017200d1058200541386a42004200201b420010a005427f200541d8006a41086a2903002220200529034820052903387c7c221c2005290350200529034084420052201c2020547222041b2121427f200529035820041b2120200541e8006a41186a290300211c200541e8006a41086a290300211d2005290378211e2005290368211f0b201a20077c201b20067c2207201b54ad7c201c7c2007201e7c2206200754ad7c2107202120097c202020087c2209202054ad7c201d7c2009201f7c2208200954ad7c21090b20054198016a200c105a20052d00d8014107470d000b0b200c10290b2000200637031020002008370300200041186a200737030020002009370308200541b0036a24000f0b41284104102e000b41104101102e000bcb0201047f230041d0006b220324002003410036022820012002200341286a1006210402400240024020032802282205417f460d0020040d010b200041003a00000c010b41002101200341003a00480340024020052001470d000240200141ff0171450d00200341003a00480b41f7cdc3004133200341286a41ecd6c3001054000b200341286a20016a200420016a2d00003a00002003200141016a22023a00482002210120024120470d000b200341086a41186a2201200341286a41186a290300370300200341086a41106a2202200341286a41106a290300370300200341086a41086a2206200341286a41086a2903003703002003200329032837030802402005450d00200410290b20002003290308370001200041013a0000200041196a2001290300370000200041116a2002290300370000200041096a20062903003700000b200341d0006a24000be70703037f047e087f230022022103200241e0026b416071220224002001411c6a22042902002105200420022903f801370200200141146a22042902002106200420022903f0013702002001410c6a22042902002107200420022903e801370200200241003a00e00120012902042108200120022903e00137020420022005370378200220063703702002200737036820022008370360200141246a2d00002104200241e0016a41176a22092005370000200241e0016a41106a220a2002290071370300200241e0016a41086a220b2002290069370300200220022900613703e001024002402008a741ff01714101460d00200041073a00400c010b200241186a41176a2009290000370000200241186a41106a200a290300370300200241186a41086a200b290300370300200220022903e001370318200220043a00372002200241186a36026002400240411510322204450d002004410029008887403700002004410d6a41002900958740370000200441086a4100290090874037000020024295808080d0023702e401200220043602e001200241e0006a200241e0016a108a0120022802e401210c20022802e801210420022802e001210b200241e0016a41186a22094200370300200241e0016a41106a220a4200370300200241e0016a41086a220d4200370300200242003703e001200b2004200241e0016a1000200241e0006a41186a22042009290300370300200241e0006a41106a2209200a290300370300200241e0006a41086a220a200d290300370300200220022903e001370360200241e0016a200241e0006a108b0120022d0081024102460d01200241e0006a200241e0016a41e300109b051a200241386a41206a220d200241e0006a41206a2d00003a0000200241386a41186a220e2004290300370300200241386a41106a220f2009290300370300200241386a41086a2210200a29030037030020022002290360370338200241e0016a20024181016a41c200109b051a200141046a220141206a200241e0016a41c1006a2d00003a0000200141186a20024199026a290000370000200141106a20024191026a290000370000200141086a20024189026a29000037000020012002290081023700002004200241186a41186a2903003703002009200241186a41106a290300370300200a200241186a41086a2903003703002002200229031837036020024188016a201029030037030020024190016a200f29030037030020024198016a200e290300370300200241a0016a200d2d00003a000020022002290338370380012000200241e0006a41c100109b051a200c450d02200b1029200324000f0b41154101102e000b41acb3c40041d700109201000b200324000b860304037f017e017f037e230041c0006b2202240002400240411410322203450d00200341002900d8d540370000200341106a41002800e8d540360000200341086a41002900e0d54037000020024294808080c002370234200220033602302001200241306a10810120022802342103200241186a20022802302204200228023810a101200241186a41106a2903002105200228021821062002290320210702402003450d00200410290b411810322203450d012005420020061b21082007420020061b2107200341002900ecd540370000200341106a41002900fcd540370000200341086a41002900f4d540370000200242988080808003370234200220033602302001200241306a10810120022802342103200220022802302206200228023810a101200241106a2903004200200228020022011b21092002290308420020011b210502402003450d00200610290b2000200520077c22073703002000200920087c2007200554ad7c370308200241c0006a24000f0b41144101102e000b41184101102e000bfe06030b7f037e037f23004190016b2201240002400240024002400240411a10322202450d00200241186a41002f00b587403b0000200241106a41002900ad8740370000200241086a41002900a587403700002002410029009d87403700002002411a413410342202450d012002200036001a200141f0006a41186a22034200370300200141f0006a41106a22044200370300200141f0006a41086a22054200370300200142003703702002411e200141f0006a1000200141d0006a41186a2003290300370300200141d0006a41106a2004290300370300200141d0006a41086a200529030037030020012001290370370350200141d0006a4120100420021029411310322202450d022002410f6a41002800f08740360000200241086a41002900e98740370000200241002900e1874037000020024113412610342202450d0320022000360013200141f0006a41186a22054200370300200141f0006a41106a22064200370300200141f0006a41086a220342003703002001420037037020024117200141f0006a1000200141d0006a41186a22072005290300370300200141d0006a41106a22082006290300370300200141d0006a41086a200329030037030020012001290370370350200141d0006a4120100420021029200141086a20001055200128020c21092001280208210a024020012802102202450d002002410574210b200141086a4104722103200a21020340200241186a290000210c200241106a290000210d200241086a290000210e20032002290000370000200341086a200e370000200341106a200d370000200341186a200c37000020012000360208411010322204450d06200441002900f88640370000200441086a4100290080874037000020014290808080800237027420012004360270200141086a200141f0006a10572001280274210f20012802782110200128027021042005420037030020064200370300200141f0006a41086a221142003703002001420037037020042010200141f0006a10002007200529030037030020082006290300370300200141d0006a41086a201129030037030020012001290370370350200141d0006a412010040240200f450d00200410290b200241206a2102200b41606a220b0d000b0b02402009450d00200a10290b20014190016a24000f0b411a4101102e000b41344101102e000b41134101102e000b41264101102e000b41104101102e000bbd0101027f230041206b22032400200341106a41086a220442003703002003420037031020012002200341106a1003200341086a200429030037030020032003290310370300410021022003410036021020034110200341106a1006210102400240024020032802102204417f470d000c010b024020010d000c010b20044104490d012001280000210420011029410121020b2000200436020420002002360200200341206a24000f0b41f7cdc3004133200341106a41ecd6c3001054000b9d0501077f230041d0026b2202240002400240411a10322203450d00200341186a41002f00b587403b0000200341106a41002900ad8740370000200341086a41002900a587403700002003410029009d87403700002003411a413410342203450d012003200136001a200241c0016a41186a22014200370300200241c0016a41106a22044200370300200241c0016a41086a22054200370300200242003703c0012003411e200241c0016a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903c001370300200241003602c00120024120200241c0016a1006210102400240024020022802c0012204417f460d002001450d00200220013602282002200436022c024020044104490d002001280000210620022004417c6a36022c2002200141046a360228200241c0016a200241286a104f20022d00c0014113460d00200241386a200241c0016a418801109b051a0240200228022c2207450d00200228022822052d0000210420022007417f6a220836022c2002200541016a360228200441034f0d00200841034b0d03200241386a102a0c010b200241386a102a0b41f7cdc3004133200241c8026a41ecd6c3001054000b410321040c010b2005280001210820022007417b6a36022c2002200541056a360228200241c0016a200241386a418801109b051a200220022800303602202002200241336a280000360023200241386a200241c0016a418801109b051a2002200228002336003320022002280220360230200110292000200241386a418801109b052201200836028c012001200636028801200120022802303600910120014194016a20022800333600000b200020043a00900120031029200241d0026a24000f0b411a4101102e000b41344101102e000bcf910203057f017e077f230041206b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002d0000220341144b0d00024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e15000102030405060708090a0b0c0d0e0f1011121314000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6220034101742205200420042005491b22054100480d620240024020030d002005103221040c010b200128020020032005103421040b2004450d1720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002000280208417f6a220341054b0d1502400240024002400240024020030e06000102030405000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d6720034101742204200020002004491b22044100480d670240024020030d002004103221000c010b200128020020032004103421000b2000450d1d20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c1a0b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6620034101742205200420042005491b22054100480d660240024020030d002005103221040c010b200128020020032005103421040b2004450d1d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200028020c2106200041146a28020022032001106602400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d6620044101742200200520052000491b22004100480d660240024020040d002000103221040c010b200128020020042000103421040b2004450d1e20012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20062003109b051a0c190b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6520034101742205200420042005491b22054100480d650240024020030d002005103221040c010b200128020020032005103421040b2004450d1e20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a00002000290310210702400240200141046a2802002200200528020022036b4108490d00200128020021000c010b200341086a22042003490d6520004101742203200420042003491b22034100480d650240024020000d002003103221000c010b200128020020002003103421000b2000450d1f20012000360200200141046a2003360200200141086a28020021030b200141086a200341086a360200200020036a20073700000c180b200241033a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6420034101742205200420042005491b22054100480d640240024020030d002005103221040c010b200128020020032005103421040b2004450d1f20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a0000200028020c2106200041146a28020022032001106602400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d6420044101742200200520052000491b22004100480d640240024020040d002000103221040c010b200128020020042000103421040b2004450d2020012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20062003109b051a0c170b200141086a2802002103200241043a0018024002402003200141046a280200460d00200128020021050c010b200341016a22042003490d6320034101742205200420042005491b22044100480d630240024020030d002004103221050c010b200128020020032004103421050b2005450d2020012005360200200141046a2004360200200141086a28020021030b200141086a2204200341016a360200200520036a41043a0000200028020c2103200041146a2802002200200110662000450d162003200041186c6a2108200141046a2106034020032802002109200341086a280200220020011066024002402006280200220a200428020022056b2000490d002001280200210a0c010b200520006a220b2005490d64200a4101742205200b200b2005491b22054100480d6402400240200a0d0020051032210a0c010b2001280200200a20051034210a0b200a450d222001200a36020020062005360200200428020021050b2004200520006a360200200a20056a20092000109b051a2003410c6a2802002109200341146a280200220020011066024002402006280200220a200428020022056b2000490d002001280200210a0c010b200520006a220b2005490d64200a4101742205200b200b2005491b22054100480d6402400240200a0d0020051032210a0c010b2001280200200a20051034210a0b200a450d232001200a36020020062005360200200428020021050b2004200520006a360200200a20056a20092000109b051a200341186a22032008470d000c170b0b200241053a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6220034101742205200420042005491b22054100480d620240024020030d002005103221040c010b200128020020032005103421040b2004450d2220012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41053a0000200028020c2104200041146a2802002203200110662003450d1520042003410c6c6a2108200141046a210903402004280200210a200441086a2802002203200110660240024020092802002205200628020022006b2003490d00200128020021050c010b200020036a220b2000490d6320054101742200200b200b2000491b22004100480d630240024020050d002000103221050c010b200128020020052000103421050b2005450d242001200536020020092000360200200628020021000b2006200020036a360200200520006a200a2003109b051a2004410c6a22042008470d000c160b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6120034101742205200420042005491b22054100480d610240024020030d002005103221040c010b200128020020032005103421040b2004450d2320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d6120034101742205200420042005491b22054100480d610240024020030d002005103221040c010b200128020020032005103421040b2004450d2420012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200141046a280200210420052802002103024020002d00014102470d000240024020042003460d00200128020021000c010b200341016a22002003490d6220034101742204200020002004491b22044100480d620240024020030d002004103221000c010b200128020020032004103421000b2000450d2620012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c150b0240024020042003460d00200128020021040c010b200341016a22042003490d6120034101742205200420042005491b22054100480d610240024020030d002005103221040c010b200128020020032005103421040b2004450d2620012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d6120034101742205200420042005491b22054100480d610240024020030d002005103221040c010b200128020020032005103421040b2004450d2720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00013a00000c140b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6020034101742205200420042005491b22054100480d600240024020030d002005103221040c010b200128020020032005103421040b2004450d2720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d6020034101742205200420042005491b22054100480d600240024020030d002005103221040c010b200128020020032005103421040b2004450d2820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041086a20011099010c130b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5f20034101742205200420042005491b22054100480d5f0240024020030d002005103221040c010b200128020020032005103421040b2004450d2820012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5f20034101742205200420042005491b22054100480d5f0240024020030d002005103221040c010b200128020020032005103421040b2004450d2920012004360200200141046a2005360200200141086a28020021030b200141086a220a200341016a360200200420036a41003a00002000280204210c2000410c6a2802002203200110662003450d12200c200341f0006c6a210d200141046a210b034020022001360208200c41106a200241086a108501200c200110980120022001360208200c41306a200241086a10850120022001360208200c41d0006a200241086a108501200c2802042104200c28020c22032001106602402003450d00200341246c21090340200241086a2004109d012002280208210602400240200b2802002205200a28020022036b20022802102200490d00200128020021050c010b200320006a22082003490d6220054101742203200820082003491b22034100480d620240024020050d002003103221050c010b200128020020052003103421050b2005450d2d20012005360200200b2003360200200a28020021030b200a200320006a360200200520036a20062000109b051a0240200228020c450d00200610290b200441246a21042009415c6a22090d000b0b200c41f0006a220c200d470d000c130b0b02400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d5e20034101742204200020002004491b22044100480d5e0240024020030d002004103221000c010b200128020020032004103421000b2000450d2a20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41043a00000c100b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5d20034101742205200420042005491b22054100480d5d0240024020030d002005103221040c010b200128020020032005103421040b2004450d2a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a00002000280208417f6a220341024b0d10024002400240024020030e03000102000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021050c010b200341016a22042003490d6020034101742205200420042005491b22044100480d600240024020030d002004103221050c010b200128020020032004103421050b2005450d2e20012005360200200141046a2004360200200141086a28020021030b200041306a2104200141086a200341016a360200200520036a41003a00002000410c6a2001109f01200241146a21030c020b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021050c010b200341016a22042003490d5f20034101742205200420042005491b22044100480d5f0240024020030d002004103221050c010b200128020020032004103421050b2005450d2e20012005360200200141046a2004360200200141086a28020021030b200041c0006a2104200141086a200341016a360200200520036a41013a00002000410c6a2001109f012002200041306a360218200241186a2001109b012002411c6a21030c010b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021050c010b200341016a22042003490d5e20034101742205200420042005491b22044100480d5e0240024020030d002004103221050c010b200128020020032004103421050b2005450d2e20012005360200200141046a2004360200200141086a28020021030b200041d8006a2104200141086a200341016a360200200520036a41023a00002000410c6a2001109f01200041306a2001109f01200241086a21030b2003200436020020032001109b010c100b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5c20034101742205200420042005491b22054100480d5c0240024020030d002005103221040c010b200128020020032005103421040b2004450d2d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a000020002d0008417f6a2203410c4b0d0f024002400240024002400240024002400240024002400240024020030e0d000102030405060708090a0b0c000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6820034101742205200420042005491b22054100480d680240024020030d002005103221040c010b200128020020032005103421040b2004450d3a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002000410c6a2001109f012002200041306a360208200241086a2001109b0120002d0009220341024b0d1b02400240024020030e03000102000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d6a20034101742204200020002004491b22044100480d6a0240024020030d002004103221000c010b200128020020032004103421000b2000450d3d20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c1d0b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d6920034101742204200020002004491b22044100480d690240024020030d002004103221000c010b200128020020032004103421000b2000450d3d20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41013a00000c1c0b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d6820034101742204200020002004491b22044100480d680240024020030d002004103221000c010b200128020020032004103421000b2000450d3d20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41023a00000c1b0b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6720034101742205200420042005491b22054100480d670240024020030d002005103221040c010b200128020020032005103421040b2004450d3d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002002200041106a360208200241086a2001109b010c1a0b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6620034101742205200420042005491b22054100480d660240024020030d002005103221040c010b200128020020032005103421040b2004450d3d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002002200041106a360208200241086a2001109b010c190b200241033a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d6520034101742204200020002004491b22044100480d650240024020030d002004103221000c010b200128020020032004103421000b2000450d3d20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41033a00000c180b200141086a2802002103200241043a0018024002402003200141046a280200460d00200128020021040c010b200341016a22042003490d6420034101742205200420042005491b22054100480d640240024020030d002005103221040c010b200128020020032005103421040b2004450d3d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41043a00002002200041106a360208200241086a2001109b010c170b200241053a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6320034101742205200420042005491b22054100480d630240024020030d002005103221040c010b200128020020032005103421040b2004450d3d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a0000200028020c2103200041146a2802002200200110662000450d16200041246c2100034020032001109f01200341246a21032000415c6a22000d000c170b0b200241063a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d6220034101742204200020002004491b22044100480d620240024020030d002004103221000c010b200128020020032004103421000b2000450d3d20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41063a00000c150b200241073a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6120034101742205200420042005491b22054100480d610240024020030d002005103221040c010b200128020020032005103421040b2004450d3d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a000020002d0009220341024b0d1402400240024020030e03000102000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d6320034101742204200020002004491b22044100480d630240024020030d002004103221000c010b200128020020032004103421000b2000450d4020012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c160b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d6220034101742204200020002004491b22044100480d620240024020030d002004103221000c010b200128020020032004103421000b2000450d4020012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41013a00000c150b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d6120034101742204200020002004491b22044100480d610240024020030d002004103221000c010b200128020020032004103421000b2000450d4020012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41023a00000c140b200141046a2802002104200241083a0018024002402004200141086a2802002203460d00200128020021040c010b200341016a22042003490d6020034101742205200420042005491b22054100480d600240024020030d002005103221040c010b200128020020032005103421040b2004450d4020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41083a00002000410c6a2001109f010c130b200241093a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5f20034101742205200420042005491b22054100480d5f0240024020030d002005103221040c010b200128020020032005103421040b2004450d4020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a00002000410c6a20011098010c120b2002410a3a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d5e20034101742204200020002004491b22044100480d5e0240024020030d002004103221000c010b200128020020032004103421000b2000450d4020012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a410a3a00000c110b2002410b3a001802400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490d5d20034101742204200020002004491b22044100480d5d0240024020030d002004103221000c010b200128020020032004103421000b2000450d4020012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a410b3a00000c100b2002410c3a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5c20034101742205200420042005491b22054100480d5c0240024020030d002005103221040c010b200128020020032005103421040b2004450d4020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410c3a0000200028020c200041146a28020020011094010c0f0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5b20034101742205200420042005491b22054100480d5b0240024020030d002005103221040c010b200128020020032005103421040b2004450d4020012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41073a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5b20034101742205200420042005491b22054100480d5b0240024020030d002005103221040c010b200128020020032005103421040b2004450d4120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041106a200110ee012002200041306a360208200241086a2001108a012002200041d0006a360208200241086a2001108a01200028020421062000410c6a28020022032001106602400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d5b20044101742200200520052000491b22004100480d5b0240024020040d002000103221040c010b200128020020042000103421040b2004450d4220012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20062003109b051a0c0e0b02400240200141046a2206280200200141086a22042802002203460d00200128020021050c010b200341016a22052003490d5a2003410174220a20052005200a491b220a4100480d5a0240024020030d00200a103221050c010b20012802002003200a103421050b2005450d4220012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a41083a000020002d0008417f6a220341104b0d0d0240024002400240024002400240024002400240024002400240024002400240024020030e11000102030405060708090a0b0c0d0e0f10000b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6a20034101742205200420042005491b22054100480d6a0240024020030d002005103221040c010b200128020020032005103421040b2004450d5320012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200028020c2001105f2002200041106a360208200241086a2001109b010c1d0b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6920034101742205200420042005491b22054100480d690240024020030d002005103221040c010b200128020020032005103421040b2004450d5320012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000410c6a20011098010c1c0b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d6820034101742206200520052006491b22064100480d680240024020030d002006103221050c010b200128020020032006103421050b2005450d5320012005360200200141046a2006360200200141086a28020021030b200141086a2206200341016a360200200520036a41023a00002000410c6a2001109801200041096a2d000021052000410a6a2d0000210a02400240200141046a28020020062802002203460d00200128020021000c010b200341016a22002003490d6820034101742206200020002006491b22064100480d680240024020030d002006103221000c010b200128020020032006103421000b2000450d5420012000360200200141046a2006360200200141086a28020021030b2004200341016a360200200020036a2005410047410774200a723a00000c1b0b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d6720034101742206200520052006491b22064100480d670240024020030d002006103221050c010b200128020020032006103421050b2005450d5420012005360200200141046a2006360200200141086a28020021030b200141086a2206200341016a360200200520036a41033a00002000410c6a2001109801200041096a2d000021052000410a6a2d0000210a02400240200141046a28020020062802002203460d00200128020021000c010b200341016a22002003490d6720034101742206200020002006491b22064100480d670240024020030d002006103221000c010b200128020020032006103421000b2000450d5520012000360200200141046a2006360200200141086a28020021030b2004200341016a360200200020036a2005410047410774200a723a00000c1a0b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d662003410174220a20052005200a491b220a4100480d660240024020030d00200a103221050c010b20012802002003200a103421050b2005450d5520012005360200200141046a200a360200200141086a28020021030b2004200341016a360200200520036a41043a0000200028020c21050240024020062802002200200428020022036b4104490d00200128020021000c010b200341046a22062003490d6620004101742203200620062003491b22034100480d660240024020000d002003103221000c010b200128020020002003103421000b2000450d5620012000360200200141046a2003360200200141086a28020021030b2004200341046a360200200020036a20053600000c190b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6520034101742205200420042005491b22054100480d650240024020030d002005103221040c010b200128020020032005103421040b2004450d5620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a0000200028020c2001105f0c180b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6420034101742205200420042005491b22054100480d640240024020030d002005103221040c010b200128020020032005103421040b2004450d5620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a0000200028020c2001105f0c170b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6320034101742205200420042005491b22054100480d630240024020030d002005103221040c010b200128020020032005103421040b2004450d5620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a0000200028020c2001105f0c160b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d622003410174220a20052005200a491b220a4100480d620240024020030d00200a103221050c010b20012802002003200a103421050b2005450d5620012005360200200141046a200a360200200141086a28020021030b200141086a220a200341016a360200200520036a41083a000020022001360208200041096a200241086a108501200028022c210902400240200141046a2802002205200a28020022036b4104490d00200128020021050c010b200341046a220a2003490d6220054101742203200a200a2003491b22034100480d620240024020050d002003103221050c010b200128020020052003103421050b2005450d5720012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a2009360000200028023021050240024020062802002200200428020022036b4104490d00200128020021000c010b200341046a22062003490d6220004101742203200620062003491b22034100480d620240024020000d002003103221000c010b200128020020002003103421000b2000450d5820012000360200200141046a2003360200200141086a28020021030b2004200341046a360200200020036a20053600000c150b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6120034101742205200420042005491b22054100480d610240024020030d002005103221040c010b200128020020032005103421040b2004450d5820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a000020022001360208200041096a200241086a1085010c140b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d6020034101742205200420042005491b22054100480d600240024020030d002005103221040c010b200128020020032005103421040b2004450d5820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410a3a00002000410c6a20011098010c130b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5f20034101742205200420042005491b22054100480d5f0240024020030d002005103221040c010b200128020020032005103421040b2004450d5820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410b3a00002000410c6a2001109801200041106a2001109801200041146a20011098010c120b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5e20034101742205200420042005491b22054100480d5e0240024020030d002005103221040c010b200128020020032005103421040b2004450d5820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410c3a0000200041096a20011081010c110b02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5d20034101742205200020002005491b22054100480d5d0240024020030d002005103221000c010b200128020020032005103421000b2000450d5820012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a410d3a00000c100b02400240200628020020042802002203460d00200128020021040c010b200341016a22042003490d5c20034101742205200420042005491b22054100480d5c0240024020030d002005103221040c010b200128020020032005103421040b2004450d5820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410e3a0000200041096a20011081010c0f0b02400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5b2003410174220a20052005200a491b220a4100480d5b0240024020030d00200a103221050c010b20012802002003200a103421050b2005450d5820012005360200200141046a200a360200200141086a28020021030b200141086a200341016a360200200520036a410f3a0000200041096a200110810120002d0029220341064b0d0e0240024002400240024002400240024020030e0700010203040506000b410021000c060b410121000c050b410221000c040b410321000c030b410421000c020b410521000c010b410621000b200220003a001802400240200628020020042802002203460d00200128020021050c010b200341016a22052003490d5b20034101742206200520052006491b22064100480d5b0240024020030d002006103221050c010b200128020020032006103421050b2005450d5920012005360200200141046a2006360200200141086a28020021030b2004200341016a360200200520036a20003a00000c0e0b02400240200628020020042802002203460d00200128020021000c010b200341016a22002003490d5a20034101742205200020002005491b22054100480d5a0240024020030d002005103221000c010b200128020020032005103421000b2000450d5920012000360200200141046a2005360200200141086a28020021030b2004200341016a360200200020036a41103a00000c0d0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da40120034101742205200420042005491b22054100480da4010240024020030d002005103221040c010b200128020020032005103421040b2004450d5a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a0000200041046a200110cb020c0c0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da30120034101742205200420042005491b22054100480da3010240024020030d002005103221040c010b200128020020032005103421040b2004450d5a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410a3a0000200041046a200110cb020c0b0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da20120034101742205200420042005491b22054100480da2010240024020030d002005103221040c010b200128020020032005103421040b2004450d5a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410b3a00002000280208417f6a220341094b0d0a024002400240024002400240024002400240024020030e0a00010203040506070809000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490dab0120034101742205200420042005491b22054100480dab010240024020030d002005103221040c010b200128020020032005103421040b2004450d6420012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41003a0000200028020c2104200041146a280200220a200110660240200a450d00200141046a2109034002400240200928020020062802002203460d00200128020021050c010b200341016a22052003490dad012003410174220b20052005200b491b220b4100480dad010240024020030d00200b103221050c010b20012802002003200b103421050b2005450d67200120053602002009200b360200200628020021030b2006200341016a360200200520036a20042d00003a0000200441016a2104200a417f6a220a0d000b0b200041186a2001109801200028021c210402400240200141046a2802002200200628020022036b4104490d00200128020021000c010b200341046a22052003490dab0120004101742203200520052003491b22034100480dab010240024020000d002003103221000c010b200128020020002003103421000b2000450d6620012000360200200141046a2003360200200141086a28020021030b200141086a200341046a360200200020036a20043600000c130b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490daa0120034101742205200420042005491b22054100480daa010240024020030d002005103221040c010b200128020020032005103421040b2004450d6620012004360200200141046a2005360200200141086a28020021030b200141086a2206200341016a360200200420036a41013a0000200028020c2104200041146a280200220a200110660240200a450d00200141046a2109034002400240200928020020062802002203460d00200128020021050c010b200341016a22052003490dac012003410174220b20052005200b491b220b4100480dac010240024020030d00200b103221050c010b20012802002003200b103421050b2005450d69200120053602002009200b360200200628020021030b2006200341016a360200200520036a20042d00003a0000200441016a2104200a417f6a220a0d000b0b200041186a2001109801200028021c210402400240200141046a2802002200200628020022036b4104490d00200128020021000c010b200341046a22052003490daa0120004101742203200520052003491b22034100480daa010240024020000d002003103221000c010b200128020020002003103421000b2000450d6820012000360200200141046a2003360200200141086a28020021030b200141086a200341046a360200200020036a20043600000c120b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da90120034101742205200420042005491b22054100480da9010240024020030d002005103221040c010b200128020020032005103421040b2004450d6820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002000410c6a2001109801200041106a2001109f01200041346a2001109801200041386a20011098010c110b200241033a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da80120034101742205200420042005491b22054100480da8010240024020030d002005103221040c010b200128020020032005103421040b2004450d6820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a00002000410c6a20011098010c100b200141086a2802002103200241043a0018024002402003200141046a280200460d00200128020021040c010b200341016a22042003490da70120034101742205200420042005491b22054100480da7010240024020030d002005103221040c010b200128020020032005103421040b2004450d6820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41043a00002000410c6a20011098010c0f0b200241053a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da60120034101742205200420042005491b22054100480da6010240024020030d002005103221040c010b200128020020032005103421040b2004450d6820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41053a00002000410c6a2001109f012002200041386a360208200241086a2001109b01200041306a20011098010c0e0b200241063a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da50120034101742205200420042005491b22054100480da5010240024020030d002005103221040c010b200128020020032005103421040b2004450d6820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a00002000410c6a20011098010c0d0b200241073a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da40120034101742205200420042005491b22054100480da4010240024020030d002005103221040c010b200128020020032005103421040b2004450d6820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a00002000410c6a2001109f010c0c0b200141046a2802002104200241083a0018024002402004200141086a2802002203460d00200128020021040c010b200341016a22042003490da30120034101742205200420042005491b22054100480da3010240024020030d002005103221040c010b200128020020032005103421040b2004450d6820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41083a00002000410c6a20011098010c0b0b200241093a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da20120034101742205200420042005491b22054100480da2010240024020030d002005103221040c010b200128020020032005103421040b2004450d6820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a00002000410c6a20011098010c0a0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da10120034101742205200420042005491b22054100480da1010240024020030d002005103221040c010b200128020020032005103421040b2004450d6820012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410c3a000020002d0004417f6a220341034b0d09024002400240024020030e0400010203000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da40120034101742205200420042005491b22054100480da4010240024020030d002005103221040c010b200128020020032005103421040b2004450d6c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041056a20011081010c0c0b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da30120034101742205200420042005491b22054100480da3010240024020030d002005103221040c010b200128020020032005103421040b2004450d6c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041056a20011081010c0b0b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da20120034101742205200420042005491b22054100480da2010240024020030d002005103221040c010b200128020020032005103421040b2004450d6c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a0000200041056a2001108101200041256a20011081010c0a0b200241033a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da10120034101742205200420042005491b22054100480da1010240024020030d002005103221040c010b200128020020032005103421040b2004450d6c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a00002000280208200041106a28020020011094010c090b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da00120034101742205200420042005491b22054100480da0010240024020030d002005103221040c010b200128020020032005103421040b2004450d6c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410d3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490da00120034101742205200420042005491b22054100480da0010240024020030d002005103221040c010b200128020020032005103421040b2004450d6d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041046a20011098010c080b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9f0120034101742205200420042005491b22054100480d9f010240024020030d002005103221040c010b200128020020032005103421040b2004450d6d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410e3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d9f0120034101742205200420042005491b22054100480d9f010240024020030d002005103221040c010b200128020020032005103421040b2004450d6e20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200028020421062000410c6a28020022032001106602400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d9f0120044101742200200520052000491b22004100480d9f010240024020040d002000103221040c010b200128020020042000103421040b2004450d6f20012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20062003109b051a0c070b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9e0120034101742205200420042005491b22054100480d9e010240024020030d002005103221040c010b200128020020032005103421040b2004450d6f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410f3a00002000280208417f6a220341024b0d0602400240024020030e03000102000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da00120034101742205200420042005491b22054100480da0010240024020030d002005103221040c010b200128020020032005103421040b2004450d7220012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002002200041306a360208200241086a2001109b012000410c6a2001109f010c080b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9f0120034101742205200420042005491b22054100480d9f010240024020030d002005103221040c010b200128020020032005103421040b2004450d7220012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000410c6a20011098010c070b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9e0120034101742205200420042005491b22054100480d9e010240024020030d002005103221040c010b200128020020032005103421040b2004450d7220012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002000410c6a20011098010c060b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9d0120034101742205200420042005491b22054100480d9d010240024020030d002005103221040c010b200128020020032005103421040b2004450d7220012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41103a000020002d0008417f6a220341044b0d050240024002400240024020030e050001020304000b200241003a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da10120034101742205200420042005491b22054100480da1010240024020030d002005103221040c010b200128020020032005103421040b2004450d7720012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041106a200110cc020c090b200241013a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490da00120034101742205200420042005491b22054100480da0010240024020030d002005103221040c010b200128020020032005103421040b2004450d7720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200041186a2001109901200028020c2106200041146a28020022032001106602400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490da00120044101742200200520052000491b22004100480da0010240024020040d002000103221040c010b200128020020042000103421040b2004450d7820012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20062003109b051a0c080b200241023a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9f0120034101742205200420042005491b22054100480d9f010240024020030d002005103221040c010b200128020020032005103421040b2004450d7820012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a00002000410c6a2001109f012002200041c0006a360208200241086a2001109b01200041d0006a200110990120002802302106200041386a28020022032001106602400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d9f0120044101742200200520052000491b22004100480d9f010240024020040d002000103221040c010b200128020020042000103421040b2004450d7920012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20062003109b051a0c070b200241033a001802400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9e0120034101742205200420042005491b22054100480d9e010240024020030d002005103221040c010b200128020020032005103421040b2004450d7920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a00002002200041386a360208200241086a2001109b01200041c8006a200110990120022001360208200041096a200241086a108501200028022c2106200041346a28020022032001106602400240200141046a2802002204200528020022006b2003490d00200128020021040c010b200020036a22052000490d9e0120044101742200200520052000491b22004100480d9e010240024020040d002000103221040c010b200128020020042000103421040b2004450d7a20012004360200200141046a2000360200200141086a28020021000b200141086a200020036a360200200420006a20062003109b051a0c060b200141086a2802002103200241043a0018024002402003200141046a280200460d00200128020021040c010b200341016a22042003490d9d0120034101742205200420042005491b22054100480d9d010240024020030d002005103221040c010b200128020020032005103421040b2004450d7a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a0000200041096a2001108101024020002d00294101460d00200241003a001802400240200141046a28020020052802002203460d00200128020021000c010b200341016a22002003490d9e0120034101742204200020002004491b22044100480d9e010240024020030d002004103221000c010b200128020020032004103421000b2000450d7c20012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c060b200241013a001802400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d9d0120034101742205200420042005491b22054100480d9d010240024020030d002005103221040c010b200128020020032005103421040b2004450d7c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00002000412a6a20011081010c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9c0120034101742205200420042005491b22054100480d9c010240024020030d002005103221040c010b200128020020032005103421040b2004450d7c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41113a00002000280204417f6a220341014b0d040240024020030e020001000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9d0120034101742205200420042005491b22054100480d9d010240024020030d002005103221040c010b200128020020032005103421040b2004450d7e20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a000020002802082001105f0c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d9c0120034101742205200420042005491b22054100480d9c010240024020030d002005103221040c010b200128020020032005103421040b2004450d7e20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041086a2001109f010c040b02400240200141046a220a280200200141086a22032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d7e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a41123a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d7f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a41003a00002000280204210602400240200a2802002205200328020022046b4104490d00200128020021050c010b200441046a22092004490d9b0120054101742204200920092004491b22044100480d9b010240024020050d002004103221050c010b200128020020052004103421050b2005450d800120012005360200200141046a2004360200200141086a28020021040b200141086a2209200441046a360200200520046a2006360000200041086a280200210b200041106a28020022042001106602400240200141046a2802002206200928020022056b2004490d00200128020021060c010b200520046a22092005490d9b0120064101742205200920092005491b22054100480d9b010240024020060d002005103221060c010b200128020020062005103421060b2006450d810120012006360200200141046a2005360200200141086a28020021050b200141086a2208200520046a360200200620056a200b2004109b051a200041146a28020021062000411c6a28020022042001106602402004450d0020062004410c6c6a210e200141046a210c03402006280200210b200641086a28020022042001106602400240200c2802002209200828020022056b2004490d00200128020021090c010b200520046a220d2005490d9d0120094101742205200d200d2005491b22054100480d9d010240024020090d002005103221090c010b200128020020092005103421090b2009450d840120012009360200200c2005360200200828020021050b2003200520046a360200200920056a200b2004109b051a2006410c6a2206200e470d000b0b200041206a280200210602400240200a2802002205200328020022046b4104490d00200128020021050c010b200441046a22092004490d9b0120054101742204200920092004491b22044100480d9b010240024020050d002004103221050c010b200128020020052004103421050b2005450d830120012005360200200141046a2004360200200141086a28020021040b2003200441046a360200200520046a2006360000200041246a280200210602400240200a2802002205200328020022046b4104490d00200128020021050c010b200441046a22092004490d9b0120054101742204200920092004491b22044100480d9b010240024020050d002004103221050c010b200128020020052004103421050b2005450d840120012005360200200141046a2004360200200141086a28020021040b2003200441046a360200200520046a200636000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d850120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00283a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d860120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00293a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d870120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d002a3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d880120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d002b3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d890120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d002c3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d8a0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d002d3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d8b0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d002e3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d8c0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d002f3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d8d0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00303a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d8e0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00313a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d8f0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00323a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d900120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00333a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d910120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00343a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d920120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00353a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d930120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00363a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d940120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00373a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d950120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00383a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d960120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00393a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d970120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d003a3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d980120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d003b3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d990120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d003c3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490d9b0120044101742206200520052006491b22064100480d9b010240024020040d002006103221050c010b200128020020042006103421050b2005450d9a0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d003d3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450d9c0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d003e3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450d9d0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d003f3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450d9e0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00403a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450d9f0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00413a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450da00120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00423a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450da10120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00433a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450da20120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00443a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450da30120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00453a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450da40120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00463a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450da50120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00473a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450da60120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00483a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450da70120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00493a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450da80120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d004a3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450da90120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d004b3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450daa0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d004c3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450dab0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d004d3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450dac0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d004e3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450dad0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d004f3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450dae0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00503a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450daf0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00513a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450db00120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00523a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450db10120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00533a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450db20120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00543a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450db30120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00553a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450db40120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00563a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450db50120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00573a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450db60120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00583a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450db70120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00593a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450db80120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d005a3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450db90120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d005b3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450dba0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d005c3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450dbb0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d005d3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450dbc0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d005e3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450dbd0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d005f3a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450dbe0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00603a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450dbf0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00613a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450dc00120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00623a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450dc10120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00633a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450dc20120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00643a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450dc30120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00653a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450dc40120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00663a000002400240200a28020020032802002204460d00200128020021050c010b200441016a22052004490dc80120044101742206200520052006491b22064100480dc8010240024020040d002006103221050c010b200128020020042006103421050b2005450dc50120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00673a00000c030b02400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490dc70120034101742204200020002004491b22044100480dc7010240024020030d002004103221000c010b200128020020032004103421000b2000450dc50120012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41133a00000c010b02400240200141046a280200200141086a2802002203460d00200128020021000c010b200341016a22002003490dc60120034101742204200020002004491b22044100480dc6010240024020030d002004103221000c010b200128020020032004103421000b2000450dc50120012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41143a00000b200110e8010b200241206a24000f0b20054101102e000b20044101102e000b20054101102e000b20004101102e000b20054101102e000b20034101102e000b20054101102e000b20004101102e000b20044101102e000b20054101102e000b20054101102e000b20054101102e000b20004101102e000b20054101102e000b20054101102e000b20044101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20034101102e000b20044101102e000b20054101102e000b20044101102e000b20044101102e000b20044101102e000b20054101102e000b20054101102e000b20044101102e000b20044101102e000b20044101102e000b20054101102e000b20054101102e000b20044101102e000b20054101102e000b20054101102e000b20044101102e000b20054101102e000b20044101102e000b20044101102e000b20044101102e000b20054101102e000b20054101102e000b20044101102e000b20044101102e000b20054101102e000b20054101102e000b20054101102e000b20004101102e000b200a4101102e000b20054101102e000b20054101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b200a4101102e000b20034101102e000b20054101102e000b20054101102e000b20054101102e000b200a4101102e000b20034101102e000b20034101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b200a4101102e000b20064101102e000b20054101102e000b1033000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b200b4101102e000b20034101102e000b20054101102e000b200b4101102e000b20034101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20004101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20004101102e000b20054101102e000b20004101102e000b20054101102e000b20004101102e000b20054101102e000b20044101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20064101102e000b20064101102e000b20044101102e000b20054101102e000b20054101102e000b20044101102e000b20044101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b1033000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20044101102e000b20044101102e000b1033000b1300200041113602042000419c8ac0003602000b3400200041d0d7c20036020420004100360200200041146a410f360200200041106a41dca7c000360200200041086a42093702000b4f01027f230041106b2202240002404101103222030d0041014101102e000b200341003a0000200041086a4101360200200241013602042002200336020020002002290300370200200241106a24000b5d01027f23004190016b22022400200241033a0088010240410110322203450d00200341003a0000200042818080801037020420002003360200024020022d0088014103460d002002102a0b20024190016a24000f0b41014101102e000bef0101017f0240024002400240024002400240410110322202450d00200241003a000020024101410210342202450d01200241003a000120024102410410342202450d02200241003b000220024104410810342202450d032002410036000420024108411010342202450d042002420037000820024110412010342202450d0520024200370018200242003700102002412041c00010342202450d06200042c0808080900437020420002002360200200241003a00200f0b41014101102e000b41024101102e000b41044101102e000b41084101102e000b41104101102e000b41204101102e000b41c0004101102e000b3f01017f230041106b220224002002410036020820024201370300410020021066200041086a200228020836020020002002290300370200200241106a24000b920701037f0240024002400240024002402000413f4b0d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0620024101742204200320032004491b22044100480d060240024020020d002004103221030c010b200128020020022004103421030b2003450d0220012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20004102743a00000f0b200041808001490d032000418080808004490d020c010b20044101102e000b0240024002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0520024101742204200320032004491b22044100480d050240024020020d002004103221030c010b200128020020022004103421030b2003450d0120012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a000002400240200141046a2802002203200428020022026b4104490d00200128020021030c010b200241046a22042002490d0520034101742202200420042002491b22024100480d050240024020030d002002103221030c010b200128020020032002103421030b2003450d0220012003360200200141046a2002360200200141086a28020021020b200141086a200241046a360200200320026a20003600000f0b20044101102e000b20024101102e000b024002400240200141046a2802002203200141086a28020022026b4104490d00200128020021030c010b200241046a22042002490d0320034101742202200420042002491b22024100480d030240024020030d002002103221030c010b200128020020032002103421030b2003450d0120012003360200200141046a2002360200200141086a28020021020b200141086a200241046a360200200320026a20004102744102723600000f0b20024101102e000b024002400240200141046a2802002203200141086a28020022026b4102490d00200128020021030c010b200241026a22042002490d0220034101742202200420042002491b22024100480d020240024020030d002002103221030c010b200128020020032002103421030b2003450d0120012003360200200141046a2002360200200141086a28020021020b200141086a200241026a360200200320026a20004102744101723b00000f0b20024101102e000b1033000b130020004106360204200041fcc2c0003602000b3201017f02404104103222020d0041044101102e000b20004284808080c00037020420002002360200200241809c313600000b3201017f02404104103222020d0041044101102e000b20004284808080c0003702042000200236020020024180a3053600000b3e01017f02404110103222020d0041104101102e000b20024200370008200242808084fea6dee111370000200042908080808002370204200020023602000b3201017f02404104103222020d0041044101102e000b20004284808080c0003702042000200236020020024180de343600000ba70701017f024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a220241104b0d0020020e110102030405060708090a0b0c0d0e0f1011010b41a0ccc000106d000b41880110322202450d102002200141046a280200106e200041046a2002360200200041013a0000200041106a200141106a290300370300200041086a200141086a2903003703000f0b200041023a0000200041046a200141046a2802003602000f0b200041033a0000200041046a200141046a280200360200200041026a200141026a2d00003a0000200020012d00014101713a00010f0b200041043a0000200041046a200141046a280200360200200041026a200141026a2d00003a0000200020012d00014101713a00010f0b200041053a0000200041046a200141046a2802003602000f0b41880110322202450d0c2002200141046a280200106e200041063a0000200041046a20023602000f0b41880110322202450d0c2002200141046a280200106e200041073a0000200041046a20023602000f0b41880110322202450d0c2002200141046a280200106e200041083a0000200041046a20023602000f0b200041093a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2902003702000f0b2000410a3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b2000410b3a0000200041046a200141046a2802003602000f0b2000410c3a00002000410c6a2001410c6a280200360200200041046a200141046a2902003702000f0b2000410d3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b2000410e3a00000f0b2000410f3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b200041103a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00003a00000f0b200041113a00000f0b4188014108102e000b4188014108102e000b4188014108102e000b4188014108102e000b5b02017f037e230041306b220124002000290208210220002902102103200029020021042001420437031020014201370204200120043703182001200141186a36020020012003370328200120023703202001200141206a107d000bd31302047f027e230041e0016b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e1514000102030405060708090a0b0c0d0e0f10111213140b200041013a00002000410220012d0001220141004720014102461b3a00010c140b200041023a0000200041086a200141086a2903003703000c130b200241e0006a200141046a1037200041033a00002000410c6a200241e8006a280200360200200041046a20022903603702000c120b106f000b200241e0006a200141086a1070200041086a200241e0006a41e000109b051a200041053a00000c100b200241e0006a200141086a1071200041063a0000200041386a200241e0006a41306a290300370300200041306a200241e0006a41286a290300370300200041286a200241e0006a41206a290300370300200041206a200241e0006a41186a290300370300200041186a200241e0006a41106a290300370300200041106a200241e0006a41086a290300370300200041086a20022903603703000c0f0b200241e0006a41186a200141286a290000370300200241e0006a41106a200141206a290000370300200241e8006a200141186a290000370300200241e0006a41286a200141386a290000370300200241e0006a41306a200141c0006a290000370300200241e0006a41386a200141c8006a290000370300200241e0006a41c8006a200141d8006a290000370300200241e0006a41d0006a200141e0006a290000370300200241e0006a41d8006a200141e8006a2900003703002002200141106a2900003703602002200141306a290000370380012002200141d0006a2900003703a0012001410c6a2802002203417f4c0d0f200141046a28020021040240024020030d0041012101410021050c010b20032105200310322201450d110b200120042003109b0521012002200241e0006a41e000109b0521042000410c6a2003360200200041086a2005360200200041046a2001360200200041106a200441e000109b051a200041073a00000c0e0b200241e0006a200141086a106c200041083a0000200041306a200241e0006a41286a290300370300200041286a200241e0006a41206a290300370300200041206a200241e0006a41186a290300370300200041186a200241e0006a41106a290300370300200041106a200241e0006a41086a290300370300200041086a20022903603703000c0d0b200241e0006a200141046a1072200041093a0000200041246a20024180016a2903003702002000411c6a200241f8006a290300370200200041146a200241f0006a2903003702002000410c6a200241e8006a290300370200200041046a20022903603702000c0c0b200241e0006a200141046a10722000410a3a0000200041246a20024180016a2903003702002000411c6a200241f8006a290300370200200041146a200241f0006a2903003702002000410c6a200241e8006a290300370200200041046a20022903603702000c0b0b200241e0006a200141086a10732000410b3a0000200041c0006a200241e0006a41386a290300370300200041386a200241e0006a41306a290300370300200041306a200241e0006a41286a290300370300200041286a200241e0006a41206a290300370300200041206a200241e0006a41186a290300370300200041186a200241e0006a41106a290300370300200041106a200241e0006a41086a290300370300200041086a20022903603703000c0a0b200241e0006a200141046a1074200041046a200241e0006a41c400109b051a2000410c3a00000c090b2000410d3a0000200041046a200141046a2802003602000c080b2001410c6a2802002203417f4c0d08200141046a28020021040240024020030d0041002101410121050c010b20032101200310322205450d0b0b200520042003109b0521052000410c6a2003360200200041086a2001360200200041046a20053602002000410e3a00000c070b024002400240024002400240200141086a280200417f6a220341024b0d0020030e03010203010b4198bdc100106d000b200141386a2903002106200141306a290300210741012103024002402001410c6a2d00004101460d00200241e8006a2001411c6a290200370300200241e0006a41106a200141246a290200370300200241f8006a2001412c6a2d00003a00002002200141146a2902003703602001410d6a2f00002001410f6a2d0000411074722105200141106a2802002101410021030c010b200141106a28020021010b200241186a200241e0006a41186a280200360200200241106a200241e0006a41106a290300370300200241086a200241e0006a41086a29030037030020022002290360370300410121040c030b2001410c6a28020022034108762105410221040c010b2001410c6a28020022034108762105410321040b0b2000410f3a0000200041386a2006370300200041306a2007370300200041106a2001360200200041086a2004360200200041146a20022903003702002000410c6a2005410874200341ff0171723602002000411c6a200241086a290300370200200041246a200241106a2903003702002000412c6a200241186a2802003602000c060b200241e0006a200141086a1075200041086a200241e0006a418001109b051a200041103a00000c050b0240024002400240200141046a280200417f6a220341014b0d0020030e020102010b41bc84c300106d000b41880110322203450d0a2003200141086a2802001076410121010c010b4101210302400240200141086a2d00004101460d00200241e0006a41086a200141186a290200370300200241e0006a41106a200141206a290200370300200241e0006a41186a200141286a2d00003a00002002200141106a290200370360200141096a2f00002001410b6a2d00004110747221042001410c6a2802002105410021030c010b2001410c6a28020021050b200241186a200241e0006a41186a280200360200200241106a200241e0006a41106a290300370300200241086a200241e0006a41086a2903003703002002200229036037030020032004410874722103410221010b200041113a00002000410c6a2005360200200041086a2003360200200041046a2001360200200041106a2002290300370200200041186a200241086a290300370200200041206a200241106a290300370200200041286a200241186a2802003602000c040b200241e0006a200141046a1077200041046a200241e0006a41e400109b051a200041123a00000c030b1078000b1079000b200241e0006a200141086a107a200041003a0000200041106a200241e0006a41086a290300370300200041086a20022903603703000b200241e0016a24000f0b102f000b20034101102e000b20034101102e000b4188014108102e000b0a0041fcd6c300106d000bcc0902057f027e230041c0006b22022400024002400240024002402001280200417f6a220341024b0d0020030e03010203010b4188fec000106d000b410121030240024020012d00044101460d00200241026a200141046a220341036a2d00003a0000200241206a41086a200141146a290200370300200241306a2001411c6a290200370300200241386a200141246a2d00003a0000200220032f00013b010020022001410c6a290200370320200141086a2802002104410021030c010b200141086a28020021040b200020033a0004200020022f01003b000520004101360200200041286a2001290328370300200041086a20043602002000410c6a2002290320370200200041306a200141306a290300370300200041076a200241026a2d00003a0000200041146a200241206a41086a2903003702002000411c6a200241306a290300370200200041246a200241386a2802003602000c020b410121030240024020012d00044101460d00200241026a200141046a220341036a2d00003a0000200241206a41086a200141146a290200370300200241306a2001411c6a290200370300200241386a200141246a2d00003a0000200220032f00013b010020022001410c6a290200370320200141086a2802002104410021030c010b200141086a28020021040b200020033a0004200020022f01003b0005200041286a2001290328370300200041386a2001290338370300200041086a20043602002000410c6a2002290320370200200041306a200141306a290300370300200041c0006a200141c0006a290300370300200041076a200241026a2d00003a0000200041146a200241206a41086a2903003702002000411c6a200241306a290300370200200041246a200241386a280200360200200041023602000c010b200141286a2103410121040240024020012d00044101460d002002411e6a200141046a220441036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220042f00013b011c20022001410c6a290200370300200141086a2802002105410021040c010b200141086a28020021050b410121060240024020032d00004101460d002002413e6a200341036a2d00003a0000200241286a200141386a290200370300200241306a200141c0006a290200370300200241386a200141c8006a2d00003a0000200220032f00013b013c2002200141306a2902003703202001412c6a2802002103410021060c010b2001412c6a28020021030b200020043a0004200020022f011c3b0005200020022f013c3b0029200041086a20053602002000410c6a2002290300370200200041286a20063a0000200041076a2002411c6a41026a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602002000412b6a2002413c6a41026a2d00003a0000200141d8006a2903002107200129035021082000412c6a2003360200200041d0006a2008370300200041d8006a200737030020004103360200200041306a2002290320370200200041386a200241206a41086a290300370200200041c0006a200241206a41106a290300370200200041c8006a200241206a41186a2802003602000b200241c0006a24000b910c03047f017e057f230041206b2202240002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a2203410c4b0d0020030e0d0102030405060708090a0b0c0d010b41a093c500106d000b4101210302400240200141046a2d00004101460d002002411e6a200141076a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a00002002200141056a2f00003b011c20022001410c6a290000370300200141086a2800002104410021030c010b200141086a28020021040b200041286a2001290328370300200041046a20033a0000200041056a20022f011c3b0000200041086a20043602002000410c6a2002290300370200200041306a200141306a290300370300200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a28020036020020012d00012101200041013a0000200020013a00010c0c0b200041023a0000200041106a200141106a290300370300200041086a200141086a2903003703000c0b0b200041033a0000200041106a200141106a290300370300200041086a200141086a2903003703000c0a0b200041043a00000c090b200041053a0000200041106a200141106a290300370300200041086a200141086a2903003703000c080b2001410c6a2802002205ad42247e2206422088a70d082006a72204417f4c0d08200141046a28020021030240024020040d00410421070c010b200410322207450d0a0b0240024020050d00410021040c010b200541246c2108410021042002411e6a21092007210103400240024020032d00004101460d002009200341036a2d00003a0000200341046a280000210a200341016a2f0000210b200241086a200341106a290000370300200241106a200341186a290000370300200241186a200341206a2d00003a00002002200b3b011c2002200341086a2900003703004100210b0c010b200341046a280200210a4101210b0b200341246a21032001200b3a0000200141046a200a360200200141016a20022f011c3b0000200141036a20092d00003a0000200141086a2002290300370200200141106a200241086a290300370200200141186a200241106a290300370200200141206a200241186a280200360200200141246a2101200441016a21042008415c6a22080d000b0b200041063a00002000410c6a2004360200200041086a2005360200200041046a20073602000c070b200041073a00000c060b200041083a0000200020012d00013a00010c050b4101210302400240200141046a2d00004101460d002002411e6a200141076a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a00002002200141056a2f00003b011c20022001410c6a290000370300200141086a2800002101410021030c010b200141086a28020021010b200041093a0000200041046a20033a0000200041056a20022f011c3b0000200041086a20013602002000410c6a2002290300370200200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c040b2000410a3a0000200041046a200141046a2802003602000c030b2000410b3a00000c020b2000410c3a00000c010b2001410c6a280200220841ffffff3f712008470d0120084105742203417f4c0d01200141046a28020021010240024020030d004101210a0c010b20031032220a450d040b0240024020080d0041002108410021010c010b20084105742104200a2103034020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a290000370000200341206a2103200141206a2101200441606a22040d000b200841057441606a41057641016a21010b2000410d3a00002000410c6a2001360200200041086a2008360200200041046a200a3602000b200241206a24000f0b102f000b20044104102e000b20034101102e000bdd0301047f024002400240024002400240024020012d0000417f6a220241034b0d0020020e0401020304010b41d8d7c300106d000b2001410c6a280200220341ffffff3f712003470d0320034105742202417f4c0d03200141046a28020021010240024020020d00410121040c010b200210322204450d050b0240024020030d0041002103410021010c010b2003410574210520042102034020022001290000370000200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a290000370000200241206a2102200141206a2101200541606a22050d000b200341057441606a41057641016a21010b200041013a00002000410c6a2001360200200041086a2003360200200041046a20043602000f0b200141046a10bc032101200041023a0000200041046a20013602000f0b200141046a2802002102200041086a200141086a10bc03360200200041046a2002360200200041033a00000f0b200041043a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a280200360200200041216a200141216a2d00004100473a00000f0b102f000b20024101102e000be50901047f230041206b220224000240024002400240024002400240024002400240024002400240024002402001280200417f6a220341094b0d0020030e0a0102030405060708090a010b41e8b8c200106d000b2001410c6a2802002203417f4c0d0a200128020421044101210502402003450d00200310322205450d0c0b200520042003109b0521052000410c6a2003360200200041086a20033602002000200536020420004101360200200041106a20012902103703000c090b2001410c6a2802002203417f4c0d09200128020421050240024020030d00410121040c010b200310322204450d0c0b200420052003109b0521052000410c6a2003360200200041086a20033602002000200536020420004102360200200041106a20012902103703000c080b200128020421054101210302400240200141086a22042d00004101460d002002411e6a200441036a2d00003a0000200241086a200141186a290200370300200241106a200141206a290200370300200241186a200141286a2d00003a0000200220042f00013b011c2002200141106a2902003703002001410c6a2802002104410021030c010b2001410c6a28020021040b20002005360204200020022f011c3b0009200041086a20033a00002000410c6a2004360200200041106a20022903003702002000412c6a200129022c3702002000410b6a2002411e6a2d00003a0000200041186a200241086a290300370200200041206a200241106a290300370200200041286a200241186a280200360200200041033602000c070b20004104360200200020012802043602040c060b20004105360200200020012802043602040c050b410121030240024020012d00044101460d002002411e6a200141046a220341036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290200370300200141086a2802002105410021030c010b200141086a28020021050b200020033a0004200020022f011c3b0005200041306a2001290330370300200041086a20053602002000410c6a2002290300370200200041386a200141386a290300370300200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602002001280228210120004106360200200041286a20013602000c040b20004107360200200020012802043602040c030b410121030240024020012d00044101460d002002411e6a200141046a220341036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290200370300200141086a2802002101410021030c010b200141086a28020021010b200020033a0004200020022f011c3b000520004108360200200041086a20013602002000410c6a2002290300370200200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c020b20004109360200200020012802043602040c010b2000410a360200200020012802043602040b200241206a24000f0b102f000b20034101102e000b20034101102e000bb60401047f0240024002400240024020012d0000417f6a220241034b0d0020020e0401020304010b41f085c300106d000b200041013a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b200041023a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000f0b200041033a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200041216a200141216a290000370000200041296a200141296a290000370000200041316a200141316a290000370000200041396a200141396a2900003700000f0b024002402001410c6a280200220341ffffff3f712003470d0020034105742202417f4c0d00200141046a28020021010240024020020d00410121040c010b200210322204450d020b0240024020030d0041002103410021010c010b2003410574210520042102034020022001290000370000200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a290000370000200241206a2102200141206a2101200541606a22050d000b200341057441606a41057641016a21010b200041043a00002000410c6a2001360200200041086a2003360200200041046a20043602000f0b102f000b20024101102e000b8d0c07037f017e017f017e017f017e017f230041c0006b220224000240024002400240024002400240024002400240024020012d0000417f6a220341044b0d0020030e050102030405010b4184b4c400106d000b200041f9006a2002280020360000200041086a200141086a290300370300200041fc006a200241236a280000360000200041106a200141106a290300370300200041186a200141186a290300370300200041206a200141206a290300370300200041286a200141286a290300370300200041306a200141306a290300370300200041386a200141386a290300370300200041c0006a200141c0006a290300370300200041c8006a200141c8006a290300370300200041d0006a200141d0006a290300370300200041d8006a200141d8006a290300370300200041e0006a200141e0006a290300370300200041e8006a200141e8006a290300370300200041f0006a200141f0006a290300370300200041f8006a200141f8006a2d00004100473a0000200041013a00000c040b2001410c6a2802002203417f4c0d04200141046a2802002104200141106a29030021050240024020030d0041002101410121060c010b20032101200310322206450d060b200620042003109b0521042000410c6a2003360200200041086a2001360200200041046a2004360200200041106a2005370300200041023a00000c030b4101210402400240200141046a2d00004101460d00200241026a200141076a2d00003a0000200241206a41086a200141146a290000370300200241306a2001411c6a290000370300200241386a200141246a2d00003a00002002200141056a2f00003b010020022001410c6a290000370320200141086a2800002106410021040c010b200141086a28020021060b200141306a2802002203417f4c0d03200141c0006a29030021052001290338210720012802282108200129034821090240024020030d00410021014101210a0c010b2003210120031032220a450d060b200a20082003109b052108200041c0006a2005370300200041386a2007370300200041046a20043a0000200041086a2006360200200041c8006a2009370300200041306a20033602002000412c6a2001360200200041286a2008360200200041056a20022f01003b0000200041076a200241026a2d00003a00002000410c6a2002290320370200200041146a200241206a41086a2903003702002000411c6a200241306a290300370200200041246a200241386a280200360200200041033a00000c020b200141386a2903002105200141306a2903002107200141c0006a2903002109200241386a200141196a290000370300200241306a200141116a290000370300200241286a200141096a290000370300200220012900013703202001412c6a2802002203417f4c0d02200141246a28020021010240024020030d0041012104410021060c010b20032106200310322204450d060b200420012003109b052101200041386a2005370300200041306a2007370300200041c0006a20093703002000412c6a2003360200200041286a2006360200200041246a2001360200200041043a000020002002290320370001200041096a200241286a290300370000200041116a200241306a290300370000200041196a200241386a2903003700000c010b200241186a2204200141196a290000370300200241106a2206200141116a290000370300200241086a2208200141096a29000037030020022001290001370300410021030240200141216a2d00004101470d00200241206a41186a2001413a6a290000370300200241206a41106a200141326a290000370300200241206a41086a2001412a6a2900003703002002200141226a290000370320410121030b20002002290300370001200041216a20033a0000200041226a2002290320370000200041196a2004290300370000200041116a2006290300370000200041096a20082903003700002000412a6a200241206a41086a290300370000200041326a200241206a41106a2903003700002000413a6a200241206a41186a290300370000200041053a00000b200241c0006a24000f0b102f000b20034101102e000b20034101102e000b20034101102e000bd11d04047f017e047f017e230041f0016b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e1500140102030405060708090a0b0c0d0e0f10111213000b0240024002400240024002400240200141086a280200417f6a220341054b0d004101210420030e06060102030405060b419485c300106d000b200141146a2802002204417f4c0d1a2001410c6a28020021010240024020040d0020024200370370410121050c010b200410322205450d1c20024100360274200220043602700b20022004360274200520012004109b051a20022903702106410221040c040b200141106a2903002106410321040c030b200141146a2802002204417f4c0d182001410c6a28020021010240024020040d0020024200370370410121050c010b200410322205450d1b20024100360274200220043602700b20022004360274200520012004109b051a20022903702106410421040c020b200241f0006a2001410c6a10382002290274210620022802702105410521040c010b200241f0006a2001410c6a10392002290274210620022802702105410621040b200041003a0000200041106a20063703002000410c6a2005360200200041086a20043602000c140b200041023a0000200041086a200141086a2903003703000c130b200241f0006a200141046a1037200041033a00002000410c6a200241f8006a280200360200200041046a20022903703702000c120b106f000b200241f0006a200141086a1070200041086a200241f0006a41e000109b051a200041053a00000c100b200241f0006a200141086a1071200041063a0000200041386a200241f0006a41306a290300370300200041306a200241f0006a41286a290300370300200041286a200241f0006a41206a290300370300200041206a200241f0006a41186a290300370300200041186a200241f0006a41106a290300370300200041106a200241f0006a41086a290300370300200041086a20022903703703000c0f0b200241f0006a41186a200141286a290000370300200241f0006a41106a200141206a290000370300200241f8006a200141186a290000370300200241f0006a41286a200141386a290000370300200241f0006a41306a200141c0006a290000370300200241f0006a41386a200141c8006a290000370300200241f0006a41c8006a200141d8006a290000370300200241f0006a41d0006a200141e0006a290000370300200241f0006a41d8006a200141e8006a2900003703002002200141106a2900003703702002200141306a290000370390012002200141d0006a2900003703b0012001410c6a2802002205417f4c0d0f200141046a28020021030240024020050d0041012101410021040c010b20052104200510322201450d130b200120032005109b052101200241086a200241f0006a41e000109b051a2000410c6a2005360200200041086a2004360200200041046a2001360200200041106a200241086a41e000109b051a200041073a00000c0e0b200241f0006a200141086a106c200041083a0000200041306a200241f0006a41286a290300370300200041286a200241f0006a41206a290300370300200041206a200241f0006a41186a290300370300200041186a200241f0006a41106a290300370300200041106a200241f0006a41086a290300370300200041086a20022903703703000c0d0b200241f0006a200141046a1072200041093a0000200041246a20024190016a2903003702002000411c6a20024188016a290300370200200041146a20024180016a2903003702002000410c6a200241f8006a290300370200200041046a20022903703702000c0c0b200241f0006a200141046a10722000410a3a0000200041246a20024190016a2903003702002000411c6a20024188016a290300370200200041146a20024180016a2903003702002000410c6a200241f8006a290300370200200041046a20022903703702000c0b0b200241f0006a200141086a10732000410b3a0000200041c0006a200241f0006a41386a290300370300200041386a200241f0006a41306a290300370300200041306a200241f0006a41286a290300370300200041286a200241f0006a41206a290300370300200041206a200241f0006a41186a290300370300200041186a200241f0006a41106a290300370300200041106a200241f0006a41086a290300370300200041086a20022903703703000c0a0b024002400240024002400240200141046a2d0000417f6a220541034b0d0020050e0401020304010b41f085c300106d000b200241ee006a200141076a2d00003a0000200241086a41086a2001411c6a290000370300200241086a41106a200141246a2d00003a00002002200141056a2f00003b016c2002200141146a290000370308200141106a28000021052001410c6a2800002107200141086a2800002103410121080c030b41022108200241ec006a41026a200141076a2d00003a0000200241086a41086a2001411c6a290000370300200241086a41106a200141246a2d00003a00002002200141056a2f00003b016c2002200141146a290000370308200141106a28000021052001410c6a2800002107200141086a28000021030c020b200241ee006a200141076a2d00003a0000200241086a41086a2001411c6a290000370300200241086a41106a200141246a2d00003a0000200241f0006a41086a2001412d6a290000370300200241f0006a41106a200141356a29000037030020024188016a2001413d6a2900003703002002200141056a2f00003b016c2002200141146a2900003703082002200141256a290000370370200141106a28000021052001410c6a2800002107200141086a2800002103410321080c010b200141106a280200220741ffffff3f712007470d0b20074105742205417f4c0d0b200141086a28020021090240024020050d00410121030c010b200510322203450d100b41042108024020070d0041002105410021070c010b2007410574210a410021010340200320016a2205200920016a2204290000370000200541186a200441186a290000370000200541106a200441106a290000370000200541086a200441086a290000370000200a200141206a2201470d000b200741057441606a41057641016a21050b200041046a20083a0000200041056a20022f016c3b0000200041106a20053600002000410c6a2007360000200041086a2003360000200041146a2002290308370000200041256a2002290370370000200041076a200241ec006a41026a2d00003a00002000411c6a200241086a41086a290300370000200041246a200241086a41106a2d00003a00002000412d6a200241f0006a41086a290300370000200041356a200241f0006a41106a2903003700002000413d6a20024188016a2903003700002000410c3a0000200041c7006a200241e9006a41026a2d00003a0000200041c5006a20022f00693b00000c090b2000410d3a0000200041046a200141046a2802003602000c080b2001410c6a2802002205417f4c0d08200141046a28020021030240024020050d0041002101410121040c010b20052101200510322204450d0e0b200420032005109b0521042000410c6a2005360200200041086a2001360200200041046a20043602002000410e3a00000c070b024002400240024002400240200141086a280200417f6a220541024b0d0020050e03010203010b4198bdc100106d000b200141386a2903002106200141306a290300210b41012105024002402001410c6a2d00004101460d00200241f8006a2001411c6a290200370300200241f0006a41106a200141246a29020037030020024188016a2001412c6a2d00003a00002002200141146a2902003703702001410d6a2f00002001410f6a2d0000411074722104200141106a2802002101410021050c010b200141106a28020021010b200241086a41186a200241f0006a41186a280200360200200241086a41106a200241f0006a41106a290300370300200241086a41086a200241f0006a41086a29030037030020022002290370370308410121030c030b2001410c6a28020022054108762104410221030c010b2001410c6a28020022054108762104410321030b0b2000410f3a0000200041386a2006370300200041306a200b370300200041106a2001360200200041086a2003360200200041146a20022903083702002000410c6a2004410874200541ff0171723602002000411c6a200241086a41086a290300370200200041246a200241086a41106a2903003702002000412c6a200241206a2802003602000c060b200241f0006a200141086a1075200041086a200241f0006a418001109b051a200041103a00000c050b0240024002400240200141046a280200417f6a220541014b0d0020050e020102010b41bc84c300106d000b41880110322205450d0d2005200141086a2802001076410121010c010b4101210502400240200141086a2d00004101460d00200241f0006a41086a200141186a290000370300200241f0006a41106a200141206a290000370300200241f0006a41186a200141286a2d00003a00002002200141106a290000370370200141096a2f00002001410b6a2d00004110747241087421032001410c6a2800002104410021050c010b2001410c6a2802002104410021030b200241086a41186a200241f0006a41186a280200360200200241086a41106a200241f0006a41106a290300370300200241086a41086a200241f0006a41086a2903003703002002200229037037030820052003722105410221010b200041113a00002000410c6a2004360200200041086a2005360200200041046a2001360200200041106a2002290308370200200041186a200241086a41086a290300370200200041206a200241086a41106a290300370200200041286a200241086a41186a2802003602000c040b200241f0006a200141046a1077200041046a200241f0006a41e400109b051a200041123a00000c030b1078000b1079000b200041013a00002000410220012d0001220141004720014102461b3a00010b200241f0016a24000f0b102f000b20044101102e000b20044101102e000b20054101102e000b20054101102e000b20054101102e000b4188014108102e000b960403077f017e067f02400240024002402001410c6a2802002202417f4c0d0020012802042103200128020021040240024020020d0041012105410021060c010b20022106200210322205450d020b200520032002109b052107200141186a2802002208ad420c7e2209422088a70d002009a72203417f4c0d002001280210210a0240024020030d004104210b0c010b20031032220b450d030b0240024020080d004100210c0c010b200a2008410c6c6a210d4100210c200b21050340200a41086a2802002203417f4c0d02200a280200210e0240024020030d004101210f0c010b20031032220f450d060b200f200e2003109b05210e200541086a2003360200200541046a20033602002005200e3602002005410c6a2105200c41016a210c200a410c6a220a200d470d000b0b20002007360204200020043602002000200129021c37021c200041186a200c360200200041146a2008360200200041106a200b3602002000410c6a2002360200200041086a2006360200200020012902243702242000412c6a2001412c6a290200370200200041346a200141346a2902003702002000413c6a2001413c6a290200370200200041c4006a200141c4006a290200370200200041cc006a200141cc006a290200370200200041d4006a200141d4006a290200370200200041dc006a200141dc006a2902003702000f0b102f000b20024101102e000b20034104102e000b20034101102e000b0a00419885c100106d000b0a0041b099c500106d000bad0301047f230041106b22022400024002400240024002400240024002400240024002402001280200417f6a220341054b0d0020030e06010203040506010b419485c300106d000b200041013602000c050b2001410c6a2802002203417f4c0d05200128020421010240024020030d0041002104410121050c010b20032104200310322205450d070b200520012003109b0521012000410c6a2003360200200041086a200436020020002001360204200041023602000c040b20004103360200200041086a200141086a2903003703000c030b2001410c6a2802002203417f4c0d03200128020421010240024020030d0041012104410021050c010b20032105200310322204450d060b200420012003109b0521012000410c6a2003360200200041086a200536020020002001360204200041043602000c020b2002200141046a1038200041053602002000410c6a200241086a280200360200200020022903003702040c010b2002200141046a1039200041063602002000410c6a200241086a280200360200200020022903003702040b200241106a24000f0b102f000b20034101102e000b20034101102e000bc1830207017f027e017f017e157f017e017f23004180086b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e12000102030405060708090a0b0c0d0e0f1011000b200341bc066a4101360200200342013702ac062003418c9ac5003602a80620034105360264200341c09ac5003602602003200341e0006a3602b806200341a8066a41fcccc000107d000b200141106a2903002104200141086a2903002105200141046a28020021062002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d00002111200241046a2d00002112200241026a2f01002113024002400240024020022d0000450d002003200737028c04200320083a008b04200320093a008a042003200a3b018804410121020c010b2002410c6a2d000021142002410a6a2f01002115200241096a2d00002116200241086a2d00002117200241066a2f01002118200241056a2d0000211920022d0001211a200320073703880441012102201a41ff01714101460d010b412a21164100211441a0f9c200211a410021150c010b2018410874201972201741187472211a410021020b201541ffff0371410874201441187472201641ff017172211420020d9601200320073703d805200320083a00d705200320093a00d6052003200a3b01d4052003200b3a00d3052003200c3a00d2052003200d3b01d0052003200e3a00cf052003200f3a00ce05200320103b01cc05200320113a00cb05200320143600c7052003201a3600c305200320123a00c205200320133b01c0050240200542808084fea6dee1115441002004501b450d00418ccdc000211a410d21140c97010b200341106a200341c0056a20052004107e02402003280210450d004199cdc000211a411a21140c97010b200341086a41b4abc5004119105d200328020c21022003280208211420034188046a41086a221a4200370300200342003703880441b4abc500411920034188046a1003200341d8076a41086a2215201a29030037030020032003290388043703d80720032002410020141b221441016a3602a806200341d8076a4110200341a8066a41041005412010322202450d10200220032903c005370000200341bc066a428180808010370200200241186a200341c0056a41186a2216290300370000200241106a200341c0056a41106a2208290300370000200241086a200341c0056a41086a2209290300370000200320053703a806200320023602b806200320043703b0062014200341a8066a107f200341b0026a2006106e200341e0006a200341b0026a418801109b051a200341f4016a2009290300370200200341fc016a200829030037020020034184026a2016290300370200200320143602e801200320032903c0053702ec01201a42003703002003420037038804419188c000411520034188046a10032015201a29030037030020032003290388043703d807200341003602a806200341d8076a4110200341a8066a1006210202400240024002400240024020032802a806221a417f460d0020020d010b200341003602b006200342013703a8064100200341a8066a106620032802a8062202450d0220032902ac06210720032002360288062003200737028c062007422088a7211a0c010b2003201a360290062003201a36028c0620032002360288060b201a450d01200341a8066a2002201a410110800120032802a8064101470d02200328028c06450d960120032802880610290c96010b200341003602900620034201370388060b410120034188066a106620032802e801211502400240200328028c06221a20032802900622026b4104490d00200328028806211a0c010b200241046a22162002490d8801201a4101742202201620162002491b22024100480d880102400240201a0d0020021032211a0c010b200328028806201a20021034211a0b201a450d132003200236028c062003201a3602880620032802900621020b2003200241046a36029006201a20026a2015360000200341e0006a20034188066a105f200341ec016a20034188066a1081010c92010b20032802ac0621160240200341b4066a2802002202200341b0066a280200221a460d002003280290062002201a6b6a221541b0016a2208417f4c0d130240024020080d00410121090c010b200810322209450d150b200320083602dc07200320093602d807200320153602e0072003200341d8076a3602a8062016200341a8066a200210820120152002490d1520032802e00722162015490d162003280290062216201a490d1720032802d807210820032802880621092003201520026b22153602c80320032016201a6b22163602e80320152016470d18200820026a2009201a6a2015109b051a20032802e80121150240024020032802dc07221a20032802e00722026b4104490d0020032802d807211a0c010b200241046a22162002490d8801201a4101742202201620162002491b22024100480d880102400240201a0d0020021032211a0c010b20032802d807201a20021034211a0b201a450d1a200320023602dc072003201a3602d80720032802e00721020b2003200241046a3602e007201a20026a2015360000200341e0006a200341d8076a105f200341ec016a200341d8076a10810120032802e007211a20032802dc07211520032802d8072102200328028c06450d930120032802880610290c93010b200320034188066a3602a8062016200341a8066a201a10820120032802e801211502400240200328028c06221a20032802900622026b4104490d00200328028806211a0c010b200241046a22162002490d8701201a4101742202201620162002491b22024100480d870102400240201a0d0020021032211a0c010b200328028806201a20021034211a0b201a450d1a2003200236028c062003201a3602880620032802900621020b2003200241046a36029006201a20026a2015360000200341e0006a20034188066a105f200341ec016a20034188066a1081010c91010b2002411a6a2901002107200241196a2d0000211a200241186a2d00002114200241166a2f01002115024020022d0000450d002003200737028c042003201a3a008b04200320143a008a04200320153b0188040c8e010b200141046a2802002106200241156a2d00002116200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002117200241026a2f0100211820022d000121022003200737038804200241ff01714101470d8d01200320073703782003201a3a0077200320143a0076200320153b0174200320163a0073200320083a0072200320093b01702003200a3a006f2003200b3a006e2003200c3b016c2003200d3a006b200320173a0062200320183b01602003200f410874200e4118747220107236006720032012410874201372201141187472360063200341a8066a20061050024020032802b80622160d0041b3cdc000211a412421140c8d010b200341c4066a2802002114200341a8066a41186a280200211a20032802bc062102200341186a200341e0006a20032902ac06220742208620033502a806842204200341b4066a3502004220862007422088842207107e20032802180d8b0120034190026a41186a2215200341e0006a41186a29030037030020034190026a41106a2209200341e0006a41106a29030037030020034190026a41086a220a200341e0006a41086a29030037030020032003290360370390020240201a2002460d0020022108201a21020c8a010b200241016a22082002490d85012002410174220b20082008200b491b220841ffffff3f712008470d85012008410574220b4100480d85010240024020020d00200b103221160c010b20162002410574200b103421160b20160d8901200b4101102e000b2002411a6a2901002107200241196a2d0000211a200241186a2d00002114200241166a2f01002106024020022d0000450d002003200737028c042003201a3a008b04200320143a008a04200320063b0188040c8d010b200241156a2d00002116200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002117200241026a2f01002118200141026a2d00002119200141046a280200211b20022d0001210220012d0001211c200320073703880441012115200241ff01714101470d8c01200320073703c0062003201a3a00bf06200320143a00be06200320063b01bc06200320163a00bb06200320083a00ba06200320093b01b8062003200a3a00b7062003200b3a00b6062003200c3b01b4062003200d3a00b306200320173a00aa06200320183b01a8062003200f410874200e411874722010723600af06200320124108742013722011411874723600ab06200341a8066a201b201c41ff01714100472019108301211a412221140c8d010b2002411a6a2901002107200241196a2d0000211a200241186a2d00002114200241166a2f01002115024020022d0000450d002003200737028c042003201a3a008b04200320143a008a04200320153b0188040c8c010b200141026a2d00002118200141046a280200211920012d0001211b200241156a2d00002106200241146a2d00002116200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211720022d000121022003200737038804200241ff01714101470d8b01200320073703782003201a3a0077200320143a0076200320153b0174200320063a0073200320163a0072200320083b0170200320093a006f2003200a3a006e2003200b3b016c2003200c3a006b200320133a0062200320173b01602003200e410874200d41187472200f7236006720032011410874201272201041187472360063200341a8066a200341e0006a10840120032d00a8064101470d8601200341b4066a2d00002102200341b5066a2900002107200341bd066a280000211a20032f00a906211420032d00ab06211520032902ac0621042003200341c1066a2900003703c0062003201a3602bc06200320073702b406200320023a00b306200320043700ab06200320153a00aa06200320143b01a806200341a8066a2019201b41ff01714100472018108301211a41222114410121150c8c010b41aacec300211a410e211420022d0000417f6a220941024b0d8901200141046a280200210a410121154101210841012106410121160240024020090e0300950101000b200241046a2d00000d8a0141012115410121084101210641012116200241086a28020041036c2002410c6a280200410174490d94010b200341a8066a200a105e024020032d00b8074103470d004190d0c000211a410d2114410121150c8c010b20032802a8062102200341b0026a200341a8066a410472419401109b051a20032002360260200341e0006a410472200341b0026a419401109b051a200341003602b006200342013703a806200341e0006a200341a8066a105f20032802ac06211a20032802b006211420032802a8062102200341d8076a41186a22154200370300200341d8076a41106a22064200370300200341d8076a41086a22164200370300200342003703d80720022014200341d8076a1000200341b0026a41186a22142015290300370300200341b0026a41106a22152006290300370300200341b0026a41086a22062016290300370300200320032903d8073703b0020240201a450d00200210290b200341a8066a41186a2014290300370300200341a8066a41106a2015290300370300200341a8066a41086a2006290300370300200320032903b0023703a806411710322202450d16200241002900f1cd403700002002410f6a4100290080ce40370000200241086a41002900f9cd4037000020034297808080f0023702c405200320023602c0052003200341c0056a3602f804200341a8066a200341f8046a10850120032802c405211a20032802c005210220032802c8052114200341d8076a41186a22154200370300200341d8076a41106a22064200370300200341d8076a41086a22164200370300200342003703d80720022014200341d8076a100020034188066a41186a201529030037030020034188066a41106a200629030037030020034188066a41086a2016290300370300200320032903d8073703880620034188066a4120410141004100100721140240201a450d00200210290b2014417f460d8401200341e0006a102a419dd0c000211a41252114410121150c8b010b200141046a280200211541aacec300211a410e211420022d0000417f6a220641024b0d82010240024020060e0300840101000b200241086a2802004101742002410c6a280200490d8301200241046a28020041ff01710d83010b20034188046a41086a22024200370300200342003703880441e889c000411620034188046a1003200341d8076a41086a221a200229030037030020032003290388043703d807200341d8076a41104101410041001007417f460d7d41a2cec000211a411521140c82010b200141046a280200211a0240024020022d0000417f6a221441024b0d00024020140e03000102000b200241046a2d00000d00200241086a2802004102742002410c6a28020041036c4f0d010b201a102a201a102941aacec300211a410e21144100210841012115410121060c8b010b200341a8066a201a418801109b051a200341023a00b00720034188046a41086a22024200370300200342003703880441e889c000411620034188046a1003200341d8076a41086a200229030037030020032003290388043703d8072003410036026820034201370360200341a8066a200341e0006a105f024020032d00b007220241024b0d00024002400240024020020e03000102000b410021140c020b410121140c010b410221140b200320143a00ff0702400240200328026420032802682202460d00200328026021150c010b200241016a22142002490d820120024101742215201420142015491b22144100480d82010240024020020d002014103221150c010b200328026020022014103421150b2015450d17200320143602642003201536026020032d00ff072114200328026821020b2003200241016a360268201520026a20143a00000b20032802642102200341d8076a4110200328026022142003280268100502402002450d00201410290b200341a8066a102a201a102941002108410121150c7d0b200141046a280200211a0240024020022d0000417f6a221441024b0d00024020140e03000102000b200241086a2802002002410c6a280200490d00200241046a28020041ff0171450d010b201a102a201a102941aacec300211a410e21144100210641012115410121080c8a010b200341a8066a201a418801109b051a200341013a00b00720034188046a41086a22024200370300200342003703880441e889c000411620034188046a1003200341d8076a41086a200229030037030020032003290388043703d8072003410036026820034201370360200341a8066a200341e0006a105f024020032d00b007220241024b0d00024002400240024020020e03000102000b410021140c020b410121140c010b410221140b200320143a00ff0702400240200328026420032802682202460d00200328026021150c010b200241016a22142002490d810120024101742215201420142015491b22144100480d81010240024020020d002014103221150c010b200328026020022014103421150b2015450d17200320143602642003201536026020032d00ff072114200328026821020b2003200241016a360268201520026a20143a00000b20032802642102200341d8076a4110200328026022142003280268100502402002450d00201410290b200341a8066a102a201a10294100210641012115410121080c7d0b200141286a2802002108200141246a2802002116200341d8056a200141196a290000370300200341d0056a200141116a290000370300200341c0056a41086a200141096a290000370300200320012900013703c0054101211541aacec300211a410e211420022d0000417e6a220641014b0d87010240024020060e020001000b200241046a2d00000d8801200241086a28020041036c2002410c6a280200410174490d88010b20034188046a41086a22024200370300200342003703880441e889c000411620034188046a1003200341d8076a41086a200229030037030020032003290388043703d807200341a8066a200341d8076a104b024020032d00b00722024103460d0020032802a806211a200341b0026a200341a8066a410472418401109b051a2003201a360260200341e0006a410472200341b0026a418401109b051a024002402002450d00200341003602b006200342013703a806200341e0006a200341a8066a105f20032802ac06211420032802b006210620032802a806211a200341d8076a41186a22094200370300200341d8076a41106a220a4200370300200341d8076a41086a220b4200370300200342003703d807201a2006200341d8076a1000200341a8066a41186a2009290300370300200341a8066a41106a200a290300370300200341a8066a41086a200b290300370300200320032903d8073703a80602402014450d00201a10290b0240200341c0056a200341a8066a4120109d05450d0041b7cec000211a410c21140c020b20034188046a41086a221a4200370300200342003703880441e889c000411620034188046a1003200341d8076a41086a201a29030037030020032003290388043703d807200341d8076a41101004200341286a41d983c300410d105d200328022c211420032802282106200341a8066a200341e0006a418801109b051a4100211a200341b0026a2014410020061b20164180a30520164180a3054b1b6a200341a8066a20022008104d024020032802b0024101470d0020032802b4022202450d00200341b0026a41086a28020021142002211a0c8b010b0c8a010b41c3cec000211a412a21140b200341e0006a102a0c88010b41edcec000211a411021140c87010b20034190056a200141196a290000370300200341f8046a41106a200141116a290000370300200341f8046a41086a200141096a290000370300200320012900013703f80441aacec300211a410e211420022d00004102470d8401200241236a2d00002106200241216a2f000021162002411f6a2d000021082002411d6a2f000021092002410f6a2d0000210a2002410d6a2f0000210b2002410b6a2d0000210c200241096a2f0000210d200241076a2d0000210e200241056a2f0000210f200241246a3502002105200241206a310000211d200241116a2900002107200241106a2d000021102002410c6a2d00002111200241086a2d00002112200241046a2d000021152003200241196a28000036029004200320073703880420154101470d84012003200329028c0422043d01d005200320103a00cb05200320044238883c00d705200320044230883c00d605200320044220883d01d405200320044218883c00d305200320044210883c00d205200320073d01cc05200320074218883c00cf052003200b200a411074724108742011723600c7052003200d200c411074724108742012723600c3052003200f200e4110747222023b01c005200320024110763a00c20520032007a74110763a00ce052003201d4218862009200841107472ad42ffffff0783842016200641107472ad42ffffff0783422086842005423886843703d80520034188046a41086a22024200370300200342003703880441e889c000411620034188046a1003200341d8076a41086a221a200229030037030020032003290388043703d807200341a8066a200341d8076a104b0240024020032d00b0074103460d00200341e0006a200341a8066a418801109b051a200341a8066a200341e0006a418801109b051a200341003602b802200342013703b002200341a8066a200341b0026a105f20032802b402211420032802b802211520032802b0022102200341d8076a41186a22064200370300200341d8076a41106a22164200370300201a4200370300200342003703d80720022015200341d8076a1000200341b0026a41186a2006290300370300200341b0026a41106a2016290300370300200341b0026a41086a201a290300370300200320032903d8073703b00202402014450d00200210290b200341f8046a200341b0026a4120109d052102200341a8066a102a2002450d014110211441a4cfc000211a410121150c88010b411421144190cfc000211a410121150c87010b200341a8066a200341f8046a10860120032802ac0622060d704101210641002108410021090c710b4101211520022d000120022d0000720d6e200141046a280200105c4100211a0c81010b4101211520022d000120022d0000720d6d2001410c6a280200210b200141086a2802002114200141046a2802002108411710322202450d12410021162002410f6a41002900d9874037000041082106200241086a41002900d28740370000200241002900ca874037000020024117412e10342202450d1320022008360017200341d8076a41186a221a4200370300200341d8076a41106a22094200370300200341d8076a41086a220a4200370300200342003703d8072002411b200341d8076a100020034188066a41186a201a29030037030020034188066a41106a200929030037030020034188066a41086a200a290300370300200320032903d80737038806200341a8066a20034188066a1087010240024020032802a80622090d004100211a0c010b200341b0066a280200211a20032802ac062116200921060b200210290240024002400240200620144190016c6a2202450d00201a20144d0d0020022d00004113460d01200620144190016c6a4188016a280200200b470d012002102a200241133a0000411710322202450d182002410f6a41002900d98740370000200241086a41002900d28740370000200241002900ca874037000020024117412e10342202450d1920022008360017200341d8076a41186a22144200370300200341d8076a41106a22084200370300200341d8076a41086a22094200370300200342003703d8072002411b200341d8076a100020034188066a41186a201429030037030020034188066a41106a200829030037030020034188066a41086a2009290300370300200320032903d80737038806200341a8066a2006201a10880120034188066a412020032802a806221420032802b0061005024020032802ac06450d00201410290b20021029201a4190016c211a200621020340024020022d00004113460d002002102a0b20024190016a2102201a41f07e6a221a0d000b4100211a20160d030c84010b201a450d010b201a4190016c211a200621020340024020022d00004113460d002002102a0b20024190016a2102201a41f07e6a221a0d000b0b41c2d0c000211a411221142016450d8501200610290c85010b200610290c80010b200341b0026a41186a200141196a290000370300200341b0026a41106a200141116a290000370300200341b0026a41086a200141096a290000370300200320012900013703b002200241166a2f0100211a200241186a2d00002114200241196a2d000021152002411a6a2901002107024020022d0000450d002003200737028c04200320153a008b04200320143a008a042003201a3b0188040c83010b200241026a2f01002106200241046a2d00002116200241056a2d00002108200241066a2f01002109200241086a2d0000210a200241096a2d0000210b2002410a6a2f0100210c2002410c6a2d0000210d2002410d6a2d0000210e2002410e6a2f0100210f200241106a2d00002110200241116a2d00002111200241126a2f01002112200241146a2d00002113200241156a2d0000211720022d000121022003200737038804200241ff01714101470d8201410f10322202450d15200241002900dacf40370000200241076a41002900e1cf403700002003428f808080f0013702ac06200320023602a806200341b0026a200341a8066a10810120032802ac06211820032802b006211920032802a8062102200341d8076a41186a221b4200370300200341d8076a41106a221c4200370300200341d8076a41086a221e4200370300200342003703d80720022019200341d8076a100020034188066a41186a201b29030037030020034188066a41106a201c29030037030020034188066a41086a201e290300370300200320032903d8073703880620034188066a41204101410041001007211902402018450d00200210290b02402019417f460d0041e9cfc000211a410f2114410121150c84010b200341e0006a41186a200341b0026a41186a290300370300200341e0006a41106a200341b0026a41106a290300370300200341e0006a41086a200341b0026a41086a290300370300200320032903b002370360200320073703c006200320153a00bf06200320143a00be062003201a3b01bc06200320173a00bb06200320133a00ba06200320123b01b806200320113a00b706200320103a00b6062003200f3b01b4062003200e3a00b3062003200c410874200b72200d411874723600af0620032009410874200872200a411874723600ab06200320163a00aa06200320063b01a806410f10322202450d164100211a200241002900dacf40370000200241076a41002900e1cf403700002003428f808080f0013702c405200320023602c005200341e0006a200341c0056a10810120032802c405211420032802c805211520032802c0052102200341d8076a41186a22064200370300200341d8076a41106a22164200370300200341d8076a41086a22084200370300200342003703d80720022015200341d8076a100020034188066a41186a200629030037030020034188066a41106a201629030037030020034188066a41086a2008290300370300200320032903d80737038806200341203602c405200320034188066a3602c005200341a8066a200341c0056a10890102402014450d00200210290b410121150c83010b2002411a6a2901002107200241196a2d0000211a200241186a2d00002114200241166a2f01002115024020022d0000450d002003200737028c042003201a3a008b04200320143a008a04200320153b0188040c82010b200241156a2d00002106200241146a2d00002116200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211720022d000121022003200737038804200241ff01714101470d8101200320073703c0062003201a3a00bf06200320143a00be06200320153b01bc06200320063a00bb06200320163a00ba06200320083b01b806200320093a00b7062003200a3a00b6062003200b3b01b4062003200c3a00b306200320133a00aa06200320173b01a8062003200e410874200f72200d411874723600af06200320114108742012722010411874723600ab06410f10322202450d164100211a200241002900dacf40370000200241076a41002900e1cf403700002003428f808080f00137026420032002360260200341a8066a200341e0006a108101200328026421142003280268211520032802602102200341d8076a41186a22064200370300200341d8076a41106a22164200370300200341d8076a41086a22084200370300200342003703d80720022015200341d8076a100020034188066a41186a200629030037030020034188066a41106a201629030037030020034188066a41086a2008290300370300200320032903d8073703880620034188066a4120100402402014450d00200210290b410121150c7e0b200341c0056a41186a200141196a290000370300200341c0056a41106a200141116a290000370300200341c0056a41086a200141096a290000370300200320012900013703c0052002411a6a2901002107200241196a2d0000211a200241186a2d00002114200241166a2f01002115024020022d0000450d002003200737028c042003201a3a008b04200320143a008a04200320153b0188040c81010b200241156a2d00002106200241146a2d00002116200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211720022d000121022003200737038804200241ff01714101470d8001200320073703c8022003201a3a00c702200320143a00c602200320153b01c402200320063a00c302200320163a00c202200320083b01c002200320093a00bf022003200a3a00be022003200b3b01bc022003200c3a00bb02200320133a00b202200320173b01b0022003200e410874200f72200d411874723600b702200320114108742012722010411874723600b302200341a8066a200341c0056a10840120032d00a8064101470d7b200320032902ac06370063200320032d00ab063a0062200320032f00a9063b01602003200341c1066a2900003703782003200341bd066a2800003602742003200341b5066a29000037026c2003200341b4066a2d00003a006b0240200341e0006a200341b0026a4120109d05450d0041f8cfc000211a410b2114410121150c82010b200341a8066a41186a200341c0056a41186a290300370300200341a8066a41106a200341c0056a41106a290300370300200341a8066a41086a200341c0056a41086a290300370300200320032903c0053703a806410f10322202450d164100211a200241002900dacf40370000200241076a41002900e1cf403700002003428f808080f00137026420032002360260200341a8066a200341e0006a108101200328026421142003280268211520032802602102200341d8076a41186a22064200370300200341d8076a41106a22164200370300200341d8076a41086a22084200370300200342003703d80720022015200341d8076a100020034188066a41186a200629030037030020034188066a41106a201629030037030020034188066a41086a2008290300370300200320032903d8073703880620034188066a4120100402402014450d00200210290b410121150c81010b200141216a2d0000210a200341c0006a41186a200141196a290000370300200341c0006a41106a200141116a290000370300200341c0006a41086a200141096a290000370300200320012900013703402002411a6a2901002107200241196a2d00002116200241186a2d00002108200241166a2f01002109200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d00002111200241046a2d00002112200241026a2f01002113024002400240024020022d0000450d002003200737028c04200320163a008b04200320083a008a04200320093b018804410121020c010b2002410c6a2d000021142002410a6a2f01002115200241096a2d00002106200241086a2d00002117200241066a2f01002118200241056a2d0000211920022d0001211a200320073703880441012102201a41ff01714101460d010b41a0f9c200211a41002115412a2106410021140c010b2018410874201972201741187472211a410021020b201541ffff0371410874200641ff017172201441187472211420020d7e200320143600cf032003201a3600cb03200320123a00ca03200320133b01c8032003200e3a00d7032003200f3a00d603200320103b01d403200320113a00d303200320163a00df03200320083a00de03200320093b01dc032003200b3a00db032003200c3a00da032003200d3b01d803200320073703e003200341e8036a41186a2007370300200341e8036a41106a20032903d803370300200341e8036a41086a200341c8036a41086a290300370300200320032903c8033703e80320034188046a41186a200341c0006a41186a29030037030020034188046a41106a200341c0006a41106a29030037030020034188046a41086a200341c0006a41086a2903003703002003200a3a00a80420032003290340370388042003200341e8036a360260411510322202450d162002410029008887403700002002410d6a41002900958740370000200241086a4100290090874037000020034295808080d0023702ac06200320023602a806200341e0006a200341a8066a108a0120032802ac06210820032802b006210220032802a806211a200341d8076a41186a22154200370300200341d8076a41106a22164200370300200341d8076a41086a22064200370300200342003703d807201a2002200341d8076a100020034188066a41186a2209201529030037030020034188066a41106a201629030037030020034188066a41086a220a2006290300370300200320032903d80737038806200341b0026a20034188066a108b010240024020032d00d10222164102470d0020154200370300200341d8076a41106a2216420037030020064200370300200342003703d80741f487c000411d200341d8076a10002009201529030037030020034188066a41106a22152016290300370300200a2006290300370300200320032903d80737038806200341f8046a20034188066a41201059024020032d00f8040d00200341d8076a41186a2206420037030020164200370300200341d8076a41086a22094200370300200342003703d80741f487c000411d200341d8076a100020034188066a41186a20062903003703002015201629030037030020034188066a41086a2009290300370300200320032903d80737038806200341203602ac06200320034188066a3602a806200341e8036a200341a8066a10890141002115410021160c020b200341d8046a41186a20034191056a290000370300200341d8046a41106a20034189056a290000370300200341d8046a41086a20034181056a290000370300200320032900f9043703d8042003200341d8046a360260411510322215450d192015410029008887403700002015410d6a41002900958740370000201541086a4100290090874037000020034295808080d0023702ac06200320153602a806200341e0006a200341a8066a108a0120032802ac06211220032802b006211620032802a8062106200341d8076a41186a22094200370300200341d8076a41106a22154200370300200341d8076a41086a220a4200370300200342003703d80720062016200341d8076a100020034188066a41186a200929030037030020034188066a41106a2209201529030037030020034188066a41086a200a290300370300200320032903d80737038806200341a8066a20034188066a108b0120032d00c9064102460d1a200341e0006a200341a8066a41e300109b051a200341c0056a41206a220a200341e0006a41206a220b2d00003a0000200341c0056a41186a220c200341e0006a41186a220d290300370300200341c0056a41106a220e200341e0006a41106a220f290300370300200341c0056a41086a2210200341e0006a41086a2211290300370300200320032903603703c005200341a8066a20034181016a41c200109b051a200b200a2d00003a0000200d200c290300370300200f200e2903003703002011201029030037030020034188016a220c200341ca066a410020032d00c9064101461b360200200320032903c0053703602003200341e8036a36028401200341d8076a41186a220a420037030020154200370300200341d8076a41086a220b4200370300200342003703d80720062016200341d8076a100020034188066a41186a200a2903003703002009201529030037030020034188066a41086a200b290300370300200320032903d80737038806200341003602e007200342013703d807410110322215450d1b200341013602dc07200320032802e007221641016a3602e007200320153602d807201520166a20032d00603a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d1d200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d00613a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d1e200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d00623a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d1f200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d00633a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d20200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d00643a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d21200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d00653a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d22200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d00663a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d23200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d00673a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d24200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d00683a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d25200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d00693a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d26200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d006a3a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d27200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d006b3a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d28200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d006c3a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d29200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d006d3a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d2a200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d006e3a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d2b200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d006f3a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d2c200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d00703a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d2d200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d00713a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d2e200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d00723a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d2f200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d00733a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d30200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d00743a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d31200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d00753a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d32200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d00763a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d33200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d00773a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d34200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d00783a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d35200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d00793a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d36200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d007a3a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d37200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d007b3a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d38200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d007c3a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d39200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d007d3a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d3a200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d007e3a00000240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7a20154101742209201620162009491b22094100480d7a0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d3b200320093602dc07200320163602d80720032802e00721150b2003201541016a3602e007201620156a20032d007f3a0000024020032d008001221541064b0d000240024002400240024002400240024020150e0700010203040506000b410021160c060b410121160c050b410221160c040b410321160c030b410421160c020b410521160c010b410621160b200320163a00ff070240024020032802dc0720032802e0072215460d0020032802d80721090c010b201541016a22162015490d7b20154101742209201620162009491b22164100480d7b0240024020150d002016103221090c010b20032802d80720152016103421090b2009450d3d200320163602dc07200320093602d80720032d00ff07211620032802e00721150b2003201541016a3602e007200920156a20163a00000b024002402003280284010d0041002109200341003a00ff070240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7c20154101742209201620162009491b22094100480d7c0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d3f200320093602dc07200320163602d80720032d00ff07210920032802e00721150b2003201541016a3602e007201620156a20093a00000c010b41012109200341013a00ff070240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7b20154101742209201620162009491b22094100480d7b0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d3f200320093602dc07200320163602d80720032d00ff07210920032802e00721150b2003201541016a3602e007201620156a20093a000020034184016a200341d8076a108a010b024002402003280288010d0041002109200341003a00ff070240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7c20154101742209201620162009491b22094100480d7c0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d41200320093602dc07200320163602d80720032d00ff07210920032802e00721150b2003201541016a3602e007201620156a20093a00000c010b41012109200341013a00ff070240024020032802dc0720032802e0072215460d0020032802d80721160c010b201541016a22162015490d7b20154101742209201620162009491b22094100480d7b0240024020150d002009103221160c010b20032802d80720152009103421160b2016450d41200320093602dc07200320163602d80720032d00ff07210920032802e00721150b2003201541016a3602e007201620156a20093a0000200c200341d8076a108a010b20032802dc07211520034188066a412020032802d807221620032802e007100502402015450d00201610290b02402012450d00200610290b200341d8076a41186a22154200370300200341d8076a41106a22064200370300200341d8076a41086a22164200370300200342003703d80741f487c000411d200341d8076a100020034188066a41186a201529030037030020034188066a41106a200629030037030020034188066a41086a2016290300370300200320032903d80737038806200341203602ac06200320034188066a3602a806200341e8036a200341a8066a108901200341b8046a41086a200341d8046a41086a290300370300200341b8046a41106a200341d8046a41106a290300370300200341b8046a41186a200341d8046a41186a290300370300200320032903d8043703b80441012115410021160c010b20034190026a41186a200341ea026a29010037030020034190026a41106a200341e2026a29010037030020034190026a41086a200341da026a290100370300200341b8046a41086a200341fb026a290000370300200341b8046a41106a20034183036a290000370300200341b8046a41186a2003418b036a290000370300200320032901d202370390022003200341f3026a2900003703b804200341f2026a2d000021150b200341cd066a20153a0000200341ce066a20032903b804370100200341b5066a20034190026a41086a290300370000200341bd066a20034190026a41106a290300370000200341c5066a20034190026a41186a290300370000200341d6066a200341b8046a41086a290300370100200341de066a200341b8046a41106a290300370100200341e6066a200341b8046a41186a290300370100200320163a00ac0620032003290390023700ad06200320034188046a3602a806200341d8076a41186a22154200370300200341d8076a41106a22064200370300200341d8076a41086a22164200370300200342003703d807201a2002200341d8076a100020034188066a41186a201529030037030020034188066a41106a200629030037030020034188066a41086a2016290300370300200320032903d807370388062003410036026820034201370360410110322202450d3e2003410136026420032003280268221541016a36026820032002360260200220156a20032d0088043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d7820024101742206201520152006491b22064100480d780240024020020d002006103221150c010b200328026020022006103421150b2015450d402003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d0089043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d7820024101742206201520152006491b22064100480d780240024020020d002006103221150c010b200328026020022006103421150b2015450d412003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d008a043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d7820024101742206201520152006491b22064100480d780240024020020d002006103221150c010b200328026020022006103421150b2015450d422003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d008b043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d7820024101742206201520152006491b22064100480d780240024020020d002006103221150c010b200328026020022006103421150b2015450d432003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d008c043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d7820024101742206201520152006491b22064100480d780240024020020d002006103221150c010b200328026020022006103421150b2015450d442003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d008d043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d7820024101742206201520152006491b22064100480d780240024020020d002006103221150c010b200328026020022006103421150b2015450d452003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d008e043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d7820024101742206201520152006491b22064100480d780240024020020d002006103221150c010b200328026020022006103421150b2015450d462003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d008f043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d7820024101742206201520152006491b22064100480d780240024020020d002006103221150c010b200328026020022006103421150b2015450d472003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d0090043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d7820024101742206201520152006491b22064100480d780240024020020d002006103221150c010b200328026020022006103421150b2015450d482003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d0091043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d7820024101742206201520152006491b22064100480d780240024020020d002006103221150c010b200328026020022006103421150b2015450d492003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d0092043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d7820024101742206201520152006491b22064100480d780240024020020d002006103221150c010b200328026020022006103421150b2015450d4a2003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d0093043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d7820024101742206201520152006491b22064100480d780240024020020d002006103221150c010b200328026020022006103421150b2015450d4b2003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d0094043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d7820024101742206201520152006491b22064100480d780240024020020d002006103221150c010b200328026020022006103421150b2015450d4c2003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d0095043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d7820024101742206201520152006491b22064100480d780240024020020d002006103221150c010b200328026020022006103421150b2015450d4d2003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d0096043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d7820024101742206201520152006491b22064100480d780240024020020d002006103221150c010b200328026020022006103421150b2015450d4e2003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d0097043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d7820024101742206201520152006491b22064100480d780240024020020d002006103221150c010b200328026020022006103421150b2015450d4f2003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d0098043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d7820024101742206201520152006491b22064100480d780240024020020d002006103221150c010b200328026020022006103421150b2015450d502003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d0099043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d6020024101742206201520152006491b22064100480d600240024020020d002006103221150c010b200328026020022006103421150b2015450d512003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d009a043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d6020024101742206201520152006491b22064100480d600240024020020d002006103221150c010b200328026020022006103421150b2015450d522003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d009b043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d6020024101742206201520152006491b22064100480d600240024020020d002006103221150c010b200328026020022006103421150b2015450d532003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d009c043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d6020024101742206201520152006491b22064100480d600240024020020d002006103221150c010b200328026020022006103421150b2015450d542003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d009d043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d6020024101742206201520152006491b22064100480d600240024020020d002006103221150c010b200328026020022006103421150b2015450d552003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d009e043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d6020024101742206201520152006491b22064100480d600240024020020d002006103221150c010b200328026020022006103421150b2015450d562003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d009f043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d6020024101742206201520152006491b22064100480d600240024020020d002006103221150c010b200328026020022006103421150b2015450d572003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d00a0043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d6020024101742206201520152006491b22064100480d600240024020020d002006103221150c010b200328026020022006103421150b2015450d582003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d00a1043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d6020024101742206201520152006491b22064100480d600240024020020d002006103221150c010b200328026020022006103421150b2015450d592003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d00a2043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d6020024101742206201520152006491b22064100480d600240024020020d002006103221150c010b200328026020022006103421150b2015450d5a2003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d00a3043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d6020024101742206201520152006491b22064100480d600240024020020d002006103221150c010b200328026020022006103421150b2015450d5b2003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d00a4043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d6020024101742206201520152006491b22064100480d600240024020020d002006103221150c010b200328026020022006103421150b2015450d5c2003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d00a5043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d6020024101742206201520152006491b22064100480d600240024020020d002006103221150c010b200328026020022006103421150b2015450d5d2003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d00a6043a000002400240200328026420032802682202460d00200328026021150c010b200241016a22152002490d6020024101742206201520152006491b22064100480d600240024020020d002006103221150c010b200328026020022006103421150b2015450d5e2003200636026420032015360260200328026821020b2003200241016a360268201520026a20032d00a7043a0000024020032d00a804220241064b0d000240024002400240024002400240024020020e0700010203040506000b410021150c060b410121150c050b410221150c040b410321150c030b410421150c020b410521150c010b410621150b200320153a00ff0702400240200328026420032802682202460d00200328026021060c010b200241016a22152002490d6120024101742206201520152006491b22154100480d610240024020020d002015103221060c010b200328026020022015103421060b2006450d60200320153602642003200636026020032d00ff072115200328026821020b2003200241016a360268200620026a20153a00000b200341a8066a410472200341e0006a108c012003280264210220034188066a4120200328026022152003280268100502402002450d00201510290b02402008450d00201a10290b200342e4cab5fbb6ccdcb0e3003703b004200341b0046a200341c8036a417f108d01200341a8066a41086a41083a0000200341b1066a20032903c803370000200341b9066a200341c8036a41086a290300370000200341c1066a200341c8036a41106a290300370000200341c9066a200341c8036a41186a290300370000200341d1066a2003290340370000200341d9066a200341c0006a41086a290300370000200341e1066a200341c0006a41106a290300370000200341e9066a200341c0006a41186a290300370000200341053a00a8064100211a4101211541014100200341a8066a104c0c80010b2002411a6a2901002107200241196a2d00002116200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d00002110200241046a2d00002111200241026a2f01002112024002400240024020022d0000450d002003200737028c04200320163a008b04200320083a008a04200320093b018804410121020c010b2002410c6a2d000021142002410a6a2f01002115200241096a2d00002106200241086a2d00002113200241066a2f01002117200241056a2d0000211820022d0001211a200320073703880441012102201a41ff01714101460d010b41a0f9c200211a41002115412a2106410021140c010b2017410874201872201341187472211a410021020b201541ffff0371410874200641ff017172201441187472211420020d7d200320073703f004200320163a00ef04200320083a00ee04200320093b01ec042003200a3a00eb042003200b3a00ea042003200c3b01e8042003200d3a00e7042003200e3a00e6042003200f3b01e404200320103a00e304200320143600df042003201a3600db04200320113a00da04200320123b01d8042003200341d8046a360260411510322202450d5f200241002900888740370000410d21142002410d6a41002900958740370000200241086a4100290090874037000020034295808080d0023702ac06200320023602a806200341e0006a200341a8066a108a0120032802ac06211a20032802b006211520032802a8062102200341d8076a41186a22064200370300200341d8076a41106a22164200370300200341d8076a41086a22084200370300200342003703d80720022015200341d8076a100020034188066a41186a200629030037030020034188066a41106a201629030037030020034188066a41086a2008290300370300200320032903d8073703880620034188066a4120410141004100100721150240201a450d00200210290b02402015417f470d004183d0c000211a410121150c80010b2003200341d8046a360260411510322202450d602002410029008887403700002002410d6a41002900958740370000200241086a4100290090874037000020034295808080d0023702ac06200320023602a806200341e0006a200341a8066a108a0120032802ac06211520032802b006210220032802a806211a200341d8076a41186a22144200370300200341d8076a41106a22064200370300200341d8076a41086a22164200370300200342003703d807201a2002200341d8076a100020034188066a41186a201429030037030020034188066a41106a200629030037030020034188066a41086a2016290300370300200320032903d80737038806200341a8066a20034188066a108b01024020032d00c90622024102460d0020034188066a412010040b20034188046a41186a200341a8066a41186a29030037030020034188046a41106a200341a8066a41106a29030037030020034188046a41086a200341a8066a41086a290300370300200320032903a8063703880420032d00c8062114200341f8046a200341ca066a41c100109b051a02402015450d00201a10290b200341b8046a41086a221a20034188046a41086a290300370300200341b8046a41106a221520034188046a41106a290300370300200341b8046a41186a220620034188046a41186a29030037030020032003290388043703b804200341c0056a200341f8046a41c100109b051a20024102460d6620034190026a41186a200629030037030020034190026a41106a201529030037030020034190026a41086a201a290300370300200320032903b80437039002200320023a00b002200341b0026a410172200341c0056a41c100109b052108200341d2026a21160240024020032d00d1024101460d004100211a0c010b20032016360260411510322202450d622002410029008887403700002002410d6a41002900958740370000200241086a4100290090874037000020034295808080d0023702ac06200320023602a806200341e0006a200341a8066a108a0120032802b006210a20032802ac06210620032802a806211a20032d00b00221020b02400240200241ff01714101470d0020032008360260411510322202450d642002410029008887403700002002410d6a41002900958740370000200241086a4100290090874037000020034295808080d0023702ac06200320023602a806200341e0006a200341a8066a108a0120032802ac06211520032802a80622020d010b024020032d00d1024101460d00200341d8076a41186a22024200370300200341d8076a41106a22164200370300200341d8076a41086a22084200370300200342003703d80741f487c000411d200341d8076a100020034188066a41186a200229030037030020034188066a41106a201629030037030020034188066a41086a2008290300370300200320032903d8073703880620034188066a412010040c660b200341d8076a41186a22024200370300200341d8076a41106a22084200370300200341d8076a41086a22094200370300200342003703d80741f487c000411d200341d8076a100020034188066a41186a200229030037030020034188066a41106a200829030037030020034188066a41086a2009290300370300200320032903d80737038806200341203602ac06200320034188066a3602a8062016200341a8066a1089010c650b20032802b006210b200341d8076a41186a22084200370300200341d8076a41106a22094200370300200341d8076a41086a22164200370300200342003703d8072002200b200341d8076a100020034188066a41186a220c200829030037030020034188066a41106a220d200929030037030020034188066a41086a2016290300370300200320032903d80737038806200341a8066a20034188066a108b0120032d00c9064102460d63200341e0006a200341a8066a41c200109b051a200341e0006a41c2006a200341d1026a2216290000370100200341aa016a201641086a290000370100200341b2016a201641106a290000370100200341ba016a201641186a290000370100200341c2016a201641206a2d00003a00002008420037030020094200370300200341d8076a41086a22164200370300200342003703d8072002200b200341d8076a1000200c2008290300370300200d200929030037030020034188066a41086a2016290300370300200320032903d80737038806200341203602ac06200320034188066a3602a806200341e0006a200341a8066a108e014101210b024020150d00410021150c660b200210290c650b41204101102e000b20024101102e000b102f000b20084101102e000b200220151030000b20152016108f01000b201a20161030000b200341f8046a41146a410236020020034184056a410336020020034188046a41146a41033602002003420337028c04200341acf9c50036028804200341033602fc042003200341c8036a3602b8042003200341e8036a3602d804200342043703b806200342013702ac0620034180fac5003602a8062003200341f8046a360298042003200341a8066a360288052003200341d8046a360280052003200341b8046a3602f80420034188046a41bcfac500107d000b20024101102e000b20024101102e000b41174101102e000b20144101102e000b20144101102e000b41174101102e000b412e4101102e000b41174101102e000b412e4101102e000b410f4101102e000b410f4101102e000b410f4101102e000b410f4101102e000b41154101102e000b41154101102e000b41a895c500419f01109201000b41014101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20164101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b41014101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20154101102e000b1033000b41154101102e000b41154101102e000b41154101102e000b41154101102e000b41f1bec40041d300109201000b410021024100210b0b0240024002400240201a0d00410021160c010b200341d8076a41186a22164200370300200341d8076a41106a22084200370300200341d8076a41086a22094200370300200342003703d807201a200a200341d8076a100020034188066a41186a220c201629030037030020034188066a41106a220d200829030037030020034188066a41086a220e2009290300370300200320032903d80737038806200341a8066a20034188066a108b0120032d00c9064102460d01200341e0006a200341a8066a41e300109b051a20034189016a200341b0026a41086a29030037000020034191016a200341b0026a41106a29030037000020034199016a200341b0026a41186a290300370000200341a1016a200341b0026a41206a2d00003a0000200320032903b00237008101201642003703002008420037030020094200370300200342003703d807201a200a200341d8076a1000200c2016290300370300200d2008290300370300200e2009290300370300200320032903d80737038806200341203602ac06200320034188066a3602a806200341e0006a200341a8066a108e01410121162006450d00201a10290b2015450d01200b200245720d01200210290c010b41f1bec40041d300109201000b02402006450d00201a452016720d00201a10290b201441ff01714107470d010b410021140b200341386a41d983c300410d105d200342e4cab5fbb6ccdcb0e3003703604100211a200341e0006a200341d8046a427f427f200328023c410020032802381b20144118744118754102744198abc5006a2802004180de346c6a4102109301200341a8066a41086a41093a0000200341a8066a41096a20032903d804370000200341b9066a200341d8046a41086a290300370000200341c1066a200341e8046a290300370000200341c9066a200341d8046a41186a290300370000200341053a00a80641014100200341a8066a104c410121150c170b41f8f8c200211a412821140c160b20032802b006210820032903b0062207a7210941002102024002402007422088a7221641014b0d0020160e020201020b2016211a0340201a410176221420026a22152002200620154105746a200341c0056a4120109d054101481b2102201a20146b221a41014b0d000b0b200620024105746a200341c0056a4120109d05221a450d070c010b200341a8066a41186a200341c0056a41186a290300370300200341a8066a41106a200341c0056a41106a290300370300200341a8066a41086a200341c0056a41086a290300370300200320032903c0053703a80641002116200341a8066a211a410021140c010b200341a8066a41186a200341c0056a41186a290300370300200341a8066a41106a200341c0056a41106a290300370300200341a8066a41086a200341c0056a41086a290300370300200320032903c0053703a806201a411f7620026a221420164b0d01200341a8066a211a0b20162009460d01200821150c020b41b0d9c500106d000b024020082016460d00200821150c010b200841016a22022008490d0720084101742215200220022015491b221541ffffff3f712015470d07201541057422024100480d070240024020080d002002103221060c010b200620084105742002103421060b2006450d010b200620144105746a220241206a2002201620146b410574109c051a200241186a201a41186a290000370000200241106a201a41106a290000370000200241086a201a41086a2900003700002002201a290000370000200341306a41d983c300410d105d200328023421142003280230210802400240411310322202450d00200241002900fdce403700002002410f6a410028008ccf40360000200241086a4100290085cf4037000020034293808080b0023702ac06200320023602a8062003200341a8066a360260200341f8046a200341e0006a10850120032802ac06210920032802a806211a20032802b0062102200341d8076a41186a220a4200370300200341d8076a41106a220b4200370300200341d8076a41086a220c4200370300200342003703d807201a2002200341d8076a100020034188066a41186a200a29030037030020034188066a41106a200b29030037030020034188066a41086a200c290300370300200320032903d80737038806410410322202450d0120034284808080c0003702ac06200320023602a8062002201441809c316a41809c3120081b22143600002006201641016a200341a8066a10940120032802ac06210220034188066a412020032802a806221620032802b006100502402002450d00201610290b02402009450d00201a10290b02402015450d00200610290b200341a8066a41086a410a3a0000200341b1066a20032903c005370000200341d1066a20032903f804370000200341b9066a200341c0056a41086a290300370000200341c1066a200341c0056a41106a290300370000200341c9066a200341c0056a41186a290300370000200341d9066a200341f8046a41086a290300370000200341e1066a200341f8046a41106a290300370000200341e9066a200341f8046a41186a290300370000200341053a00a806200341f4066a20143602004100211a41014100200341a8066a104c20034188046a41086a22024200370300200342003703880441e889c000411620034188046a1003200341d8076a41086a200229030037030020032003290388043703d807200341d8076a41101004410121150c110b41134101102e000b41044101102e000b20024101102e000b41b4cfc000211a412621142009450d0b20061029410121150c0d0b200341003602b006200342013703a8062015200341a8066a105f20032802ac06211420032802b006210620032802a8062102200341d8076a41186a22164200370300200341d8076a41106a22084200370300201a4200370300200342003703d80720022006200341d8076a1000200341e0006a41186a22062016290300370300200341e0006a41106a2008290300370300200341e0006a41086a201a290300370300200320032903d80737036002402014450d00200210290b200341a8066a41186a2006290300370300200341a8066a41106a200341e0006a41106a290300370300200341a8066a41086a200341e0006a41086a290300370300200320032903603703a806200341b0026a200341a8066a108601024020032802b4022202450d0020032802b002211a200341206a41d983c300410d105d2003280224410020032802201b2114024020032802b802450d00200210290b2014201a4f0d004188cec000211a411a21140c050b200341a8066a2015418801109c051a200341003a00b00720034188046a41086a22024200370300200342003703880441e889c000411620034188046a1003200341d8076a41086a200229030037030020032003290388043703d807200341003602b802200342013703b002200341a8066a200341b0026a105f024020032d00b007220241024b0d00024002400240024020020e03000102000b4100211a0c020b4101211a0c010b4102211a0b2003201a3a00ff070240024020032802b40220032802b8022202460d0020032802b00221140c010b200241016a221a2002490d0520024101742214201a201a2014491b221a4100480d050240024020020d00201a103221140c010b20032802b0022002201a103421140b2014450d042003201a3602b402200320143602b00220032d00ff07211a20032802b80221020b2003200241016a3602b802201420026a201a3a00000b20032802b4022102200341d8076a411020032802b002221a20032802b802100502402002450d00201a10290b200341a8066a102a2015102941002115410121080b410121060b410121164100211a0c120b201a4101102e000b1033000b2015102a201510294101210841002115410121060c080b200341a8066a41186a200341b0026a41186a290300370300200341a8066a41106a200341b0026a41106a290300370300200341a8066a41086a200341b0026a41086a290300370300200320032903b0023703a806200341013a0088040240411710322202450d004100211a200241002900f1cd403700002002410f6a4100290080ce40370000200241086a41002900f9cd4037000020034297808080f0023702c405200320023602c0052003200341c0056a3602f804200341a8066a200341f8046a10850120032802c405211420032802c005210220032802c8052115200341d8076a41186a22064200370300200341d8076a41106a22164200370300200341d8076a41086a22084200370300200342003703d80720022015200341d8076a100020034188066a41186a200629030037030020034188066a41106a201629030037030020034188066a41086a2008290300370300200320032903d8073703880620034188066a412020034188046a4101100502402014450d00200210290b200a105c200341e0006a102a410121150c030b41174101102e000b4198bac200211a410b2114410121150c050b201620024105746a2202200329039002370000200241186a2015290300370000200241106a2009290300370000200241086a200a29030037000041012115200341a8066a41186a201a41016a360200200341bc066a2008360200200320073703b006200320043703a806200320143602c406200320163602b8062006200341a8066a107f4100211a0b4101210841012106410121160c0b0b41d7cdc000211a411a21142002450d0020161029410121150c020b410121150c010b41a0f9c200211a412a2114410121150b41012108410121060b410121160c060b200328029006211a200328028c06211520032802880621020b2002450d0020034188046a41086a221642003703002003420037038804419188c000411520034188046a1003200341d8076a41086a201629030037030020032003290388043703d807200341d8076a41102002201a10052015450d01200210290c010b41b00110322202450d01200320032802e8013602b007200341a8066a200341e0006a106e200341a8066a41a4016a200341e0006a41a4016a290200370200200341a8066a419c016a200341e0006a419c016a290200370200200341a8066a4194016a200341e0006a4194016a290200370200200320032902ec013702b4072002200341a8066a41b001109b05210220034188046a41086a221a42003703002003420037038804419188c000411520034188046a1003200341d8076a41086a201a29030037030020032003290388043703d807200341103602ac062003200341d8076a3602a80620024101200341a8066a10512002102a200210290b200341e0006a102a200341c0066a2004370300200341b8066a2005370300200341b4066a201436020041002116200341b0066a41003a0000200341053a00a8064101211541014100200341a8066a104c2006102a2006102941012108410121064100211a0c020b41b0014108102e000b2006102a20061029410021164101211541012108410121060b0240024020012d0000417f6a2202410f4b0d00024002400240024020020e1000040404040102030404040405040505000b2016450d04200141046a2202280200102a200228020010290c040b2015450d03200141046a2202280200102a200228020010290c030b2008450d02200141046a2202280200102a200228020010290c020b2006450d01200141046a2202280200102a200228020010290c010b200241074b0d00024002400240024020020e080004040404010203000b200141046a2202280200102a200228020010290c030b200141046a2202280200102a200228020010290c020b200141046a2202280200102a200228020010290c010b200141046a2202280200102a200228020010290b200020143602042000201a36020020034180086a24000b110020012000280200200028020410b3040b4802017f017e230041206b2202240020012902002103200241146a20012902083702002002200337020c20022000360208200241d8fec50036020420024101360200200210f604000bf40304047f027e017f027e230041d0006b220424000240024002400240411410322205450d00200541002900d8d540370000200541106a41002800e8d540360000200541086a41002900e0d54037000020044294808080c002370244200420053602402001200441c0006a10810120042802442105200441286a20042802402206200428024810a101200441286a41106a2903004200200428022822071b21082004290330420020071b210902402005450d00200610290b024020092002542205200820035420082003511b450d0041f1fdc0002105411521010c040b200441206a20014104200920027d2209200820037d2005ad7d220810ae01200428022022050d02411810322207450d0141002105200741002900ecd540370000200741106a41002900fcd540370000200741086a41002900f4d540370000200442988080808003370244200420073602402001200441c0006a10810120042802442107200441086a2004280240220a200428024810a101200441086a41106a2903004200200428020822061b210b2004290310420020061b210c02402007450d00200a10290b2001200c20027c2202200b20037c2002200c54ad7c10bc0120012009200810a5010c030b41144101102e000b41184101102e000b200428022421010b2000200136020420002005360200200441d0006a24000bf10201047f230041c0006b22022400024002400240411310322203450d002003410f6a41002800c68740360000200341086a41002900bf8740370000200341002900b7874037000020034113412610342203450d0120032000360013200241206a41186a22004200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034117200241206a1000200241186a2000290300370300200241106a2004290300370300200241086a200529030037030020022002290320370300411010322200450d02200020012903003700002000200141086a2903003700082002429080808080023702242002200036022020012802102204200141186a280200200241206a1094012002280224210020024120200228022022052002280228100502402000450d00200510290b200310290240200141146a280200450d00200410290b200241c0006a24000f0b41134101102e000b41264101102e000b41104101102e000bd40201027f0240024002402002450d002002417f6a2104024020012d0000220241037122054103460d000240024020050e03040001040b2004450d0220012d0001410874200272220241ffff0371418002490d02200241fcff037141027621020c040b20044103490d0120012f0001200141036a2d000041107472410874200272220241808004490d01200241027621020c030b200241034b0d0020044104490d002001280001220241ffffffff034b0d020b200041013602000f0b200241027621020b0240200220036a220120024f0d00200041013602000f0b41012103410121050240200241c000490d0041022105200241808001490d00410441052002418080808004491b21050b0240200141c000490d0041022103200141808001490d00410441052001418080808004491b21030b20002001360204200041003602002000410c6a2003360200200041086a20053602000b952801057f02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2202280200200141086a22032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00003a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00013a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00023a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00033a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00043a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00053a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00063a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00073a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00083a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00093a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000e3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1020012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000f3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00103a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00113a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00123a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00133a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00143a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00153a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00163a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00173a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00183a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00193a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001e3a000002400240200228020020032802002202460d00200128020021040c010b200241016a22042002490d2120024101742205200420042005491b22054100480d210240024020020d002005103221040c010b200128020020022005103421040b2004450d2020012004360200200141046a2005360200200141086a28020021020b2003200241016a360200200420026a20002d001f3a00000f0b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20054101102e000b1033000b8e0301027f230041e0006b22032400200341003a0005024002402000413f4b0d0041012104200341013a0005200320004102743a00000c010b02400240200041808001490d0020004180808080044f0d0141042104200341043a0005200320004102744102723602000c020b41022104200341023a0005200320004102744101723b01000c010b41052104200341053a0005200341033a0000200320003600010b024002402001280200220028020822012002490d0020002802002100200320023602082003200436020c20042002470d01200020032002109b051a200341e0006a24000f0b20022001108f01000b200341286a41146a4102360200200341346a4103360200200341106a41146a410336020020034203370214200341acf9c5003602102003410336022c2003200341086a36024020032003410c6a360244200342043703582003420137024c20034180fac5003602482003200341286a3602202003200341c8006a3602382003200341c4006a3602302003200341c0006a360228200341106a41bcfac500107d000ba91403077f017e017f230041c0016b22042400024002400240024002400240024002400240024002400240024002400240024002400240024002400240411a10322205450d00200541186a41002f00b587403b0000200541106a41002900ad8740370000200541086a41002900a587403700002005410029009d87403700002005411a413410342205450d012005200136001a200441e0006a41186a22064200370300200441e0006a41106a22074200370300200441e0006a41086a22084200370300200442003703602005411e200441e0006a1000200441c0006a41186a2006290300370300200441c0006a41106a2007290300370300200441c0006a41086a200829030037030020042004290360370340200441c0006a4120410141004100100721062005102902402006417f470d0041d4d0c00021000c100b200441146a200041086a2900003702002004411c6a200041106a290000370200200441246a200041186a290000370200200420013602082004200029000037020c411010322205450d02200541002900f88640370000200541086a4100290080874037000020044290808080800237026420042005360260200441086a200441e0006a1057200428026421062004280268210720042802602105200441e0006a41186a22084200370300200441e0006a41106a22094200370300200441e0006a41086a220a42003703002004420037036020052007200441e0006a1000200441c0006a41186a2008290300370300200441c0006a41106a2009290300370300200441c0006a41086a200a29030037030020042004290360370340200441c0006a41204101410041001007210702402006450d00200510290b2007417f470d0e200441086a41186a200041186a290000370300200441086a41106a200041106a290000370300200441086a41086a200041086a29000037030020042000290000370308411310322205450d032005410f6a41002800f08740360000200541086a41002900e98740370000200541002900e1874037000020054113412610342205450d0420052001360013200441e0006a41186a22064200370300200441e0006a41106a22074200370300200441e0006a41086a220842003703002004420037036020054117200441e0006a1000200441c0006a41186a2006290300370300200441c0006a41106a2007290300370300200441c0006a41086a20082903003703002004200429036037034020044100360260200441c0006a4120200441e0006a1006210602400240024002400240024020042802602207417f460d0020060d010b20044100360268200442013703604100200441e0006a106620042802602206450d022004290264210b200420063602302004200b370234200b422088a721070c010b2004200736023820042007360234200420063602300b2007450d01200441e0006a20062007410110800120042802604101470d022004280234450d10200428023010290c100b20044100360238200442013703300b4101200441306a1066200441086a200441306a1081010c0c0b200428026421090240200441ec006a2802002206200441e8006a2802002207460d002004280238200620076b6a220841206a220a417f4c0d0602400240200a0d004101210c0c010b200a1032220c450d080b2004200a360284012004200c360280012004200836028801200420044180016a3602602009200441e0006a200610820120082006490d0820042802880122092008490d09200428023822092007490d0a200428028001210a2004280230210c2004200820066b2208360290012004200920076b22093602940120082009470d0b200a20066a200c20076a2008109b051a200441086a20044180016a1081012004280288012107200428028401210820042802800121062004280234450d0d200428023010290c0d0b2004200441306a3602602009200441e0006a2007108201200441086a200441306a1081010c0b0b411a4101102e000b41344101102e000b41104101102e000b41134101102e000b41264101102e000b102f000b200a4101102e000b200620081030000b20082009108f01000b200720091030000b200441c0006a41146a4102360200200441cc006a410336020020044198016a41146a41033602002004420337029c01200441acf9c5003602980120044103360244200420044190016a3602b001200420044194016a3602b401200442043703702004420137026420044180fac5003602602004200441c0006a3602a8012004200441e0006a3602502004200441b4016a3602482004200441b0016a36024020044198016a41bcfac500107d000b2004280238210720042802342108200428023021060b2006450d00200441e0006a41186a22094200370300200441e0006a41106a220a4200370300200441e0006a41086a220c42003703002004420037036020054117200441e0006a1000200441c0006a41186a2009290300370300200441c0006a41106a200a290300370300200441c0006a41086a200c29030037030020042004290360370340200441c0006a412020062007100502402008450d00200610290b200510290c010b20051029412010322205450d0220052004290308370000200541186a200441086a41186a290300370000200541106a200441086a41106a290300370000200541086a200441086a41086a290300370000411310322206450d032006410f6a41002800f08740360000200641086a41002900e98740370000200641002900e1874037000020064113412610342206450d0420062001360013200441e0006a41186a22074200370300200441e0006a41106a22084200370300200441e0006a41086a220942003703002004420037036020064117200441e0006a1000200441c0006a41186a2007290300370300200441c0006a41106a2008290300370300200441c0006a41086a200929030037030020042004290360370340200441203602642004200441c0006a36026020054101200441e0006a10950120061029200510290b200441146a200041086a2900003702002004411c6a200041106a290000370200200441246a200041186a290000370200200420013602082004200029000037020c411010322200450d04200041002900f88640370000200041086a4100290080874037000020044290808080800237026420042000360260200441086a200441e0006a1057200428026421012004280268210020042802602105200441e0006a41186a22064200370300200441e0006a41106a22074200370300200441e0006a41086a220842003703002004420037036020052000200441e0006a1000200441c0006a41186a2006290300370300200441c0006a41106a2007290300370300200441c0006a41086a200829030037030020042004290360370340410110322200450d05200041807f410020021b2003723a0000200441c0006a41202000410110052000102902402001450d00200510290b410021000b200441c0016a240020000f0b41204101102e000b41134101102e000b41264101102e000b41104101102e000b41014101102e000be70201067f230041d0006b220224000240410f10322203450d00200341002900dacf40370000200341076a41002900e1cf403700002002428f808080f00137020c200220033602082001200241086a108101200228020c21042002280210210520022802082103200241086a41186a22014200370300200241086a41106a22064200370300200241086a41086a220742003703002002420037030820032005200241086a1000200241306a41186a2001290300370300200241306a41106a2006290300370300200241306a41086a200729030037030020022002290308370330200241086a200241306a412010590240024020022d00084101460d00200041003a00000c010b20002002290308370000200041206a200241086a41206a2d00003a0000200041186a2001290300370000200041106a2006290300370000200041086a20072903003700000b02402004450d00200310290b200241d0006a24000f0b410f4101102e000bba0501037f02400240024002400240024002400240410110322202450d00200220002d00003a000020024101410210342202450d01200220002d00013a000120024102410410342202450d02200220002d00023a0002200220002d00033a000320024104410810342202450d03200220002d00043a0004200220002d00053a0005200220002d00063a0006200220002d00073a000720024108411010342202450d04200220002d00083a0008200220002d00093a0009200220002d000a3a000a200220002d000b3a000b200220002d000c3a000c200220002d000d3a000d200220002d000e3a000e200220002d000f3a000f20024110412010342202450d05200220002d00103a0010200220002d00113a0011200220002d00123a0012200220002d00133a0013200220002d00143a0014200220002d00153a0015200220002d00163a0016200220002d00173a0017200220002d00183a0018200220002d00193a0019200220002d001a3a001a200220002d001b3a001b200220002d001c3a001c200220002d001d3a001d200220002d001e3a001e200220002d001f3a001f024002402001280200220041046a2802002203200041086a28020022016b4120490d00200028020021030c010b200141206a22042001490d0820034101742201200420042001491b22014100480d080240024020030d002001103221030c010b200028020020032001103421030b2003450d0720002003360200200041046a2001360200200041086a28020021010b200041086a200141206a360200200320016a220041186a200241186a290000370000200041106a200241106a290000370000200041086a200241086a29000037000020002002290000370000200210290f0b41014101102e000b41024101102e000b41044101102e000b41084101102e000b41104101102e000b41204101102e000b20014101102e000b1033000bcb0302067f017e230041d0006b220224000240411310322203450d00200341002900fdce403700002003410f6a410028008ccf40360000200341086a4100290085cf4037000020024293808080b00237022c200220033602282002200241286a3602082001200241086a108501200228022c21042002280228210120022802302103200241286a41186a22054200370300200241286a41106a22064200370300200241286a41086a220742003703002002420037032820012003200241286a1000200241086a41186a2005290300370300200241086a41106a2006290300370300200241086a41086a20072903003703002002200229032837030820024100360228200241086a4120200241286a1006210302400240024020022802282205417f460d002003450d00200220033602482002200536024c024020054104490d0020022005417c6a36024c2002200341046a36024820032800002106200241286a200241c8006a1031200228022822050d020b41f7cdc3004133200241286a41ecd6c3001054000b410021050c010b200229022c21082003102920002008370208200020063602000b2000200536020402402004450d00200110290b200241d0006a24000f0b41134101102e000bea05020d7f017e230041c0056b22022400200241003602b80420014120200241b8046a1006210302400240024002400240024020022802b8042204417f470d00200041003602000c010b2002200436021420022003360210200241086a200241106a102c20022802080d0420022802144190016e22054190016c2201417f4c0d01200228020c21060240024020010d00410821070c010b200110322207450d030b02402006450d00200241b0036a4101722108410021094100210a4100210b03400240024002402002280214220c450d002002280210220d2d000021012002200c417f6a3602142002200d41016a360210200141014b0d004113210c02400240024020010e020100010b200241b8046a200241106a104f20022d00b8044113460d02200241b0036a200241b8046a418801109b051a200228021422014104490d012002280210220c280000210e20022001417c6a3602142002200c41046a36021020022d00b003210c200241a9026a2008418701109b051a200c4113460d02200241a2016a200241a9026a418701109b051a200c4114460d020b200b41016a21012002411b6a200241a2016a418701109b051a200b2005470d0302402009200120012009491b2205ad4290017e220f422088a70d00200fa7220d41004e0d030b1033000b200241b0036a102a0b0240200b450d00200721010340024020012d00004113460d002001102a0b20014190016a2101200a41f07e6a220a0d000b0b2005450d08200710290c080b02400240200b0d00200d103221070c010b2007200a200d103421070b2007450d060b2007200a6a220b200c3a0000200b41016a2002411b6a418701109b051a200b4188016a200e360200200941026a2109200a4190016a210a2001210b20062001470d000b0b2007450d042000200536020420002007360200200041086a20063602002004450d00200310290b200241c0056a24000f0b102f000b20014108102e000b200d4108102e000b41f7cdc3004133200241b8046a41ecd6c3001054000bd90401057f230041106b220324002003410036020820034201370300200220031066024002400240024002402002450d0020024190016c2104034020032802042105200328020821020240024020012d00004113470d000240024020052002460d00200328020021050c010b200241016a22052002490d0820024101742206200520052006491b22064100480d080240024020020d002006103221050c010b200328020020022006103421050b2005450d052003200636020420032005360200200328020821020b2003200241016a360208200520026a41003a00000c010b0240024020052002460d00200328020021050c010b200241016a22052002490d0720024101742206200520052006491b22064100480d070240024020020d002006103221050c010b200328020020022006103421050b2005450d052003200636020420032005360200200328020821020b2003200241016a360208200520026a41013a000020012003105f20014188016a28020021060240024020032802042205200328020822026b4104490d00200328020021050c010b200241046a22072002490d0720054101742202200720072002491b22024100480d070240024020050d002002103221050c010b200328020020052002103421050b2005450d062003200236020420032005360200200328020821020b2003200241046a360208200520026a20063600000b20014190016a2101200441f07e6a22040d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b20064101102e000b20064101102e000b20024101102e000b1033000bdf0301017f024002400240024002400240410110322202450d00200220002d00003a000020024101410210342202450d01200220002d00013a000120024102410410342202450d02200220002d00023a0002200220002d00033a000320024104410810342202450d03200220002d00043a0004200220002d00053a0005200220002d00063a0006200220002d00073a000720024108411010342202450d04200220002d00083a0008200220002d00093a0009200220002d000a3a000a200220002d000b3a000b200220002d000c3a000c200220002d000d3a000d200220002d000e3a000e200220002d000f3a000f20024110412010342202450d05200220002d00103a0010200220002d00113a0011200220002d00123a0012200220002d00133a0013200220002d00143a0014200220002d00153a0015200220002d00163a0016200220002d00173a0017200220002d00183a0018200220002d00193a0019200220002d001a3a001a200220002d001b3a001b200220002d001c3a001c200220002d001d3a001d200220002d001e3a001e200220002d001f3a001f20012802002001280204200241201005200210290f0b41014101102e000b41024101102e000b41044101102e000b41084101102e000b41104101102e000b41204101102e000b9c2801057f2000280200210202400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2203280200200141086a22002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0120012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d00003a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0220012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d00013a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0320012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d00023a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0420012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d00033a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0520012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d00043a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0620012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d00053a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0720012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d00063a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0820012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d00073a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0920012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d00083a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0a20012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d00093a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0b20012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d000a3a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0c20012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d000b3a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0d20012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d000c3a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0e20012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d000d3a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0f20012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d000e3a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1020012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d000f3a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1120012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d00103a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1220012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d00113a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1320012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d00123a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1420012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d00133a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1520012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d00143a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1620012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d00153a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1720012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d00163a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1820012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d00173a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1920012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d00183a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1a20012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d00193a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1b20012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d001a3a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1c20012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d001b3a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1d20012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d001c3a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1e20012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d001d3a000002400240200328020020002802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1f20012005360200200141046a2006360200200141086a28020021040b2000200441016a360200200520046a20022d001e3a000002400240200328020020002802002203460d00200128020021040c010b200341016a22042003490d2120034101742205200420042005491b22054100480d210240024020030d002005103221040c010b200128020020032005103421040b2004450d2020012004360200200141046a2005360200200141086a28020021030b2000200341016a360200200420036a20022d001f3a00000f0b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20054101102e000b1033000bc50b03087f017e067f230041d0016b22022400200241003602a80120014120200241a8016a10062103024002400240024020022802a8012204417f460d0020030d010b200041023a00210c010b41002101200241003a00c8012004417e6a21050340024020042001470d00200141ff0171450d03200241003a00c8010c030b200241a8016a20016a200320016a2d00003a00002002200141016a22063a00c8012005417f6a21052006210120064120470d000b20024188016a41186a200241a8016a41186a29030037030020024188016a41106a200241a8016a41106a29030037030020024188016a41086a200241a8016a41086a290300370300200220022903a8013703880120042006460d01200320066a22072d0000220841074f0d01200241086a41186a20024188016a41186a290300370300200241086a41106a20024188016a41106a290300370300200241086a41086a20024188016a41086a29030037030020022002290388013703082004417f6a2006460d01200741016a2d0000220141014b0d01200420066b210902400240024020010e020100010b41002101200241003a00c8012009417e6a21090340024020092001470d00200141ff0171450d05200241003a00c8010c050b200241a8016a20016a200720016a41026a2d00003a00002002200141016a22063a00c8012006210120064120470d000b200241e8006a41086a200241a8016a41086a290300220a370300200241c8006a41186a200241a8016a41186a290300370300200241c8006a41106a200241a8016a41106a290300370300200241c8006a41086a200a370300200220022903a801220a3703682002200a370348200520066b210b200720066a41026a2106410121090c010b200741026a21062009417e6a210b410021090b200241286a41186a200241c8006a41186a290300370300200241286a41106a200241c8006a41106a290300370300200241286a41086a200241c8006a41086a29030037030020022002290348370328200b450d0120062d0000220541014b0d01410021010240024020050e020100010b41002101200241003a00c801200641016a2105200b417f6a21070340024020072001470d00200141ff0171450d04200241003a00c8010c040b200241a8016a20016a200520016a2d00003a00002002200141016a22063a00c8012006210120064120470d000b200241e8006a41086a200241a8016a41086a290300220a370300200241c8006a41186a200241a8016a41186a290300370300200241c8006a41106a200241a8016a41106a290300370300200241c8006a41086a200a370300200220022903a801220a3703682002200a370348410121010b200241e8006a41186a2206200241c8006a41186a290300370300200241e8006a41106a2205200241c8006a41106a290300370300200241e8006a41086a2207200241c8006a41086a29030037030020024188016a41086a220b200241286a41086a29030037030020024188016a41106a220c200241286a41106a29030037030020024188016a41186a220d200241286a41186a290300370300200220022903483703682002200229032837038801200241a8016a41186a220e200241086a41186a290300370300200241a8016a41106a220f200241086a41106a290300370300200241a8016a41086a2210200241086a41086a290300370300200220022903083703a80120094102460d01200020022903a801370000200020093a0021200020083a00202000200229038801370022200041186a200e290300370000200041106a200f290300370000200041086a20102903003700002000412a6a200b290300370000200041326a200c2903003700002000413a6a200d290300370000200041c2006a20013a0000200041c3006a2002290368370000200041cb006a2007290300370000200041d3006a2005290300370000200041db006a20062903003700002004450d00200310290b200241d0016a24000f0b41f7cdc3004133200241c8006a41ecd6c3001054000bd70501037f024002400240024002400240024020002d00004101460d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0720024101742204200320032004491b22044100480d070240024020020d002004103221030c010b200128020020022004103421030b2003450d0320012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41003a00000c010b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0620024101742204200320032004491b22044100480d060240024020020d002004103221030c010b200128020020022004103421030b2003450d0320012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a0000200041016a20011081010b024020002d00214101460d0002400240200141046a280200200141086a2802002200460d00200128020021020c010b200041016a22022000490d0620004101742203200220022003491b22034100480d060240024020000d002003103221020c010b200128020020002003103421020b2002450d0420012002360200200141046a2003360200200141086a28020021000b200141086a200041016a360200200220006a41003a00000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0520024101742204200320032004491b22044100480d050240024020020d002004103221030c010b200128020020022004103421030b2003450d0420012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41013a0000200041226a20011081010f0b20044101102e000b20044101102e000b20034101102e000b20044101102e000b1033000b940b09027f017e087f037e017f027e067f017e017f230041c0006b22032400200341086a41d983c300410d105d2000280000210420003500042105200328020c210620032802082107200341206a200110b00141002108200328022021092003280224210a0240024002400240024002400240024002402003280228220b450d002006410020071b210c2009200b410574220b6a210d200341346a2107200921060340200641086a290300210e200641106a290300210f20062903002110200341206a41186a200641186a290300370300200341206a41106a200f370300200341206a41086a200e3703002003201037032020072000460d0220072900002000290000510d02024020032802302211200c4d0d002003411e6a2003413f6a2d00003a0000200320032f003d3b011c200341286a2903002110427f210f200329032021124201210e20032d003c2107200329023421130c040b200641206a2106200b41606a220b0d000b0b41082114200a450d02200910290c020b200328023022072002200720024b1b211120032d003c4102722107427f21124200210f41002102200329023421134200210e41002104427f21100b200341106a41026a22082003411c6a41026a2d00003a0000200320032f011c3b011002400240412010322214450d0020142012370300201420073a001c2014201337021420142011360210201420032f01103b001d201420103703082014411f6a20082d00003a000002400240200b4120470d0041012108200f2110410121110c010b200641206a2115200d41606a21162003413d6a2117200341346a2107200f21104101210841012111034020152106024002400340200341206a41186a200641186a290300370300200341206a41106a200641106a290300370300200341206a41086a220b200641086a290300370300200320062903003703200240024020072000460d0020072900002000290000510d0020032802302218200c4d0d012003411c6a41026a201741026a2d00003a0000200320172f00003b011c200b29030021122003290320211320032d003c21192003290234211a0c040b200e4201510d024200210f41002102420021104200210e410021040b200d200641206a2206470d000c040b0b200b290300220e201020032903202213200f56200e201056200e2010511b220b1b21122013200f200b1b21132003280230220b2002200b20024b1b211820032d003c41027221194200210f410021022003290234211a420021104200210e410021040b200341146a41026a2003411c6a41026a2d0000220b3a0000200320032f011c22153b0114200341206a41026a221b200b3a0000200320153b0120024020112008470d00200841016a220b2008490d0a20084101742211200b200b2011491b221141ffffff3f712011470d0a2011410574220b4100480d0a0240024020080d00200b103221140c010b20142008410574200b103421140b2014450d040b200641206a2115201420084105746a220b20193a001c200b2012370308200b2013370300200b201a370214200b2018360210200b20032f01203b001d200b411f6a201b2d00003a0000200841016a210820162006470d000b0b0240200a450d00200910290b200e4201520d0520082011470d040c030b41204108102e000b200b4108102e000b427f210f427f21100b200841016a22062008490d0320084101742200200620062000491b221141ffffff3f712011470d03201141057422064100480d030240024020080d002006103221140c010b201420084105742006103421140b2014450d020b201420084105746a220620103703082006200f3703002006200436021420062002360210200641186a200542808080802084370300200841016a21080b2003200836022820032011360224200320143602202001200341206a10c101200341c0006a24000f0b20064108102e000b1033000bcc2601057f230041106b2202240020024100360208200242013703000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240410110322203450d00200242818080801037020420022003360200200320002d00003a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d0220022005360204200220043602000b2002200341016a360208200420036a20002d00013a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d0320022005360204200220043602000b2002200341016a360208200420036a20002d00023a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d0420022005360204200220043602000b2002200341016a360208200420036a20002d00033a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d0520022005360204200220043602000b2002200341016a360208200420036a20002d00043a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d0620022005360204200220043602000b2002200341016a360208200420036a20002d00053a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d0720022005360204200220043602000b2002200341016a360208200420036a20002d00063a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d0820022005360204200220043602000b2002200341016a360208200420036a20002d00073a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d0920022005360204200220043602000b2002200341016a360208200420036a20002d00083a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d0a20022005360204200220043602000b2002200341016a360208200420036a20002d00093a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d0b20022005360204200220043602000b2002200341016a360208200420036a20002d000a3a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d0c20022005360204200220043602000b2002200341016a360208200420036a20002d000b3a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d0d20022005360204200220043602000b2002200341016a360208200420036a20002d000c3a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d0e20022005360204200220043602000b2002200341016a360208200420036a20002d000d3a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d0f20022005360204200220043602000b2002200341016a360208200420036a20002d000e3a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d1020022005360204200220043602000b2002200341016a360208200420036a20002d000f3a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d1120022005360204200220043602000b2002200341016a360208200420036a20002d00103a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d1220022005360204200220043602000b2002200341016a360208200420036a20002d00113a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d1320022005360204200220043602000b2002200341016a360208200420036a20002d00123a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d1420022005360204200220043602000b2002200341016a360208200420036a20002d00133a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d1520022005360204200220043602000b2002200341016a360208200420036a20002d00143a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d1620022005360204200220043602000b2002200341016a360208200420036a20002d00153a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d1720022005360204200220043602000b2002200341016a360208200420036a20002d00163a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d1820022005360204200220043602000b2002200341016a360208200420036a20002d00173a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d1920022005360204200220043602000b2002200341016a360208200420036a20002d00183a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d1a20022005360204200220043602000b2002200341016a360208200420036a20002d00193a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d1b20022005360204200220043602000b2002200341016a360208200420036a20002d001a3a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d1c20022005360204200220043602000b2002200341016a360208200420036a20002d001b3a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d1d20022005360204200220043602000b2002200341016a360208200420036a20002d001c3a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d1e20022005360204200220043602000b2002200341016a360208200420036a20002d001d3a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d1f20022005360204200220043602000b2002200341016a360208200420036a20002d001e3a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d2220034101742205200420042005491b22054100480d220240024020030d002005103221040c010b200228020020032005103421040b2004450d2020022005360204200220043602000b2002200341016a360208200420036a20002d001f3a0000024020002d0020220341064b0d000240024002400240024002400240024020030e0700010203040506000b410021040c060b410121040c050b410221040c040b410321040c030b410421040c020b410521040c010b410621040b200220043a000f02400240200228020420022802082203460d00200228020021050c010b200341016a22052003490d2320034101742206200520052006491b22064100480d230240024020030d002006103221050c010b200228020020032006103421050b2005450d2220022006360204200220053602000b2002200341016a360208200520036a20043a00000b200041216a2002108c012002280204210020012802002001280204200228020022032002280208100502402000450d00200310290b200241106a24000f0b41014101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20064101102e000b1033000b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420237020c200241e480c600360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41f480c600107d000b6501027f230041206b220224002001411c6a280200210320012802182101200241086a41106a200041106a290200370300200241086a41086a200041086a2902003703002002200029020037030820012003200241086a10d8042100200241206a240020000bb90201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d002000280200210420034120710d012004ad4101200110a70221000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d0220014101418882c6004102200220006a4180016a410020006b10a80221000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d0220014101418882c6004102200220006a4180016a410020006b10a80221000b20024180016a240020000f0b20044180011030000b20044180011030000b5e01017f230041306b220224002002200136020c20022000360208200241246a410136020020024201370214200241f8a9c6003602102002410536022c2002200241286a3602202002200241086a360228200241106a4180aac600107d000bb40b07047f017e017f017e047f0c7e017f230022062107200641e0006b41607122062400200641186a41d983c300410d105d200628021c2108200628021821092006200337033020062002370328200620043602384201210a200642013703202006200028000036023c20003500042102200641c0006a200110b0014100210b20022005ad42ff018342208684210c2006280240210d2006280244210e024002400240024002400240024020062802482205450d002008410020091b210f200d200541057422046a2110200641d4006a21082006290320220a2102200629032822112112200629033022132114200629033822152116200d21050340200541086a2903002103200541106a290300211720052903002118200641c0006a41186a200541186a290300370300200641c0006a41106a22092017370300200641c0006a41086a2003370300200620183703400240024020082000460d0020082900002000290000510d0002402006280250200f4b0d0020022103420021020c020b200929030021192006290348211a2006290340211b2006290358211c20022103420121020c010b4200210a42002111420021134200211542002103200c211c2012211b2014211a201621190b20024201510d02200541206a210520032102200441606a22040d000b2006200a3703202006201137032820062013370330200620153703380b0240200e0d00410021094108211d410821050c020b200d10294108211d41002109410821050c010b2006200337032020062012370328200620143703302006201637033841201032221d450d04201d201c370318201d201b370300201d201a370308201d41106a20193703000240024020044120470d004101210b410121090c010b200541206a2105200641d4006a2108200321024101210b4101210903400240024020082000460d00200221170340200641c0006a41186a200541186a290300370300200641c0006a41106a2204200541106a290300370300200641c0006a41086a200541086a290300370300200620052903003703400240024020082900002000290000510d0002402006280250200f4b0d0020172102420021170c020b2004290300211c2006290348210a200629034021182006290358211b20172102420121170c010b420021032006420037032042002102201221182014210a2016211c200c211b0b024020174201510d00200221172010200541206a2205470d010c050b0b200541206a21050c010b024003402006420037032020024201510d01420021022010200541206a2205470d000b420021030c030b200541206a21054200210342002102201221182014210a2016211c200c211b0b02402009200b470d00200b41016a2204200b490d06200b4101742209200420042009491b220941ffffff3f712009470d06200941057422044100480d0602400240200b0d0020041032211d0c010b201d200b41057420041034211d0b201d450d040b201d200b4105746a2204200a37030820042018370300200441106a201c370300200441186a201b370300200b41016a210b20052010470d000b0b0240200e450d00200d10290b2003210a201d21050b0240200a4201520d00200641c0006a41106a2204200641206a410872220041106a290300370300200641c0006a41086a2208200041086a290300370300200620002903003703400240200b2009470d00200b41016a2205200b490d04200b4101742200200520052000491b220941ffffff3f712009470d04200941057422004100480d0402400240200b0d002000103221050c010b201d200b4105742000103421050b2005450d030b2005200b4105746a22002006290340370300200041106a2004290300370300200041086a2008290300370300200041186a200c370300200b41016a210b0b2006200b36024820062009360244200620053602402001200641c0006a10c101200724000f0b20044108102e000b20004108102e000b1033000b41204108102e000bdd2701057f20012002106602400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001450d00200020014105746a2103200241046a2104200241086a2101034002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d032002200636020020042007360200200128020021050b2001200541016a360200200620056a20002d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d042002200636020020042007360200200128020021050b2001200541016a360200200620056a200041016a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d052002200636020020042007360200200128020021050b2001200541016a360200200620056a200041026a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d062002200636020020042007360200200128020021050b2001200541016a360200200620056a200041036a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d072002200636020020042007360200200128020021050b2001200541016a360200200620056a200041046a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d082002200636020020042007360200200128020021050b2001200541016a360200200620056a200041056a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d092002200636020020042007360200200128020021050b2001200541016a360200200620056a200041066a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d0a2002200636020020042007360200200128020021050b2001200541016a360200200620056a200041076a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d0b2002200636020020042007360200200128020021050b2001200541016a360200200620056a200041086a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d0c2002200636020020042007360200200128020021050b2001200541016a360200200620056a200041096a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d0d2002200636020020042007360200200128020021050b2001200541016a360200200620056a2000410a6a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d0e2002200636020020042007360200200128020021050b2001200541016a360200200620056a2000410b6a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d0f2002200636020020042007360200200128020021050b2001200541016a360200200620056a2000410c6a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d102002200636020020042007360200200128020021050b2001200541016a360200200620056a2000410d6a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d112002200636020020042007360200200128020021050b2001200541016a360200200620056a2000410e6a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d122002200636020020042007360200200128020021050b2001200541016a360200200620056a2000410f6a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d132002200636020020042007360200200128020021050b2001200541016a360200200620056a200041106a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d142002200636020020042007360200200128020021050b2001200541016a360200200620056a200041116a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d152002200636020020042007360200200128020021050b2001200541016a360200200620056a200041126a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d162002200636020020042007360200200128020021050b2001200541016a360200200620056a200041136a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d172002200636020020042007360200200128020021050b2001200541016a360200200620056a200041146a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d182002200636020020042007360200200128020021050b2001200541016a360200200620056a200041156a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d192002200636020020042007360200200128020021050b2001200541016a360200200620056a200041166a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d1a2002200636020020042007360200200128020021050b2001200541016a360200200620056a200041176a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d1b2002200636020020042007360200200128020021050b2001200541016a360200200620056a200041186a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d1c2002200636020020042007360200200128020021050b2001200541016a360200200620056a200041196a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d1d2002200636020020042007360200200128020021050b2001200541016a360200200620056a2000411a6a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d1e2002200636020020042007360200200128020021050b2001200541016a360200200620056a2000411b6a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d1f2002200636020020042007360200200128020021050b2001200541016a360200200620056a2000411c6a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d202002200636020020042007360200200128020021050b2001200541016a360200200620056a2000411d6a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d212002200636020020042007360200200128020021050b2001200541016a360200200620056a2000411e6a2d00003a000002400240200428020020012802002205460d00200228020021060c010b200541016a22062005490d2320054101742207200620062007491b22074100480d230240024020050d002007103221060c010b200228020020052007103421060b2006450d222002200636020020042007360200200128020021050b2001200541016a360200200620056a2000411f6a2d00003a0000200041206a22002003470d000b0b0f0b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b1033000bb82601047f230041106b22032400200341003602082003420137030020012003106602400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001450d00200020014105746a2104034002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d0320032006360204200320053602000b2003200141016a360208200520016a20002d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d0420032006360204200320053602000b2003200141016a360208200520016a200041016a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d0520032006360204200320053602000b2003200141016a360208200520016a200041026a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d0620032006360204200320053602000b2003200141016a360208200520016a200041036a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d0720032006360204200320053602000b2003200141016a360208200520016a200041046a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d0820032006360204200320053602000b2003200141016a360208200520016a200041056a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d0920032006360204200320053602000b2003200141016a360208200520016a200041066a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d0a20032006360204200320053602000b2003200141016a360208200520016a200041076a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d0b20032006360204200320053602000b2003200141016a360208200520016a200041086a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d0c20032006360204200320053602000b2003200141016a360208200520016a200041096a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d0d20032006360204200320053602000b2003200141016a360208200520016a2000410a6a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d0e20032006360204200320053602000b2003200141016a360208200520016a2000410b6a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d0f20032006360204200320053602000b2003200141016a360208200520016a2000410c6a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d1020032006360204200320053602000b2003200141016a360208200520016a2000410d6a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d1120032006360204200320053602000b2003200141016a360208200520016a2000410e6a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d1220032006360204200320053602000b2003200141016a360208200520016a2000410f6a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d1320032006360204200320053602000b2003200141016a360208200520016a200041106a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d1420032006360204200320053602000b2003200141016a360208200520016a200041116a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d1520032006360204200320053602000b2003200141016a360208200520016a200041126a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d1620032006360204200320053602000b2003200141016a360208200520016a200041136a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d1720032006360204200320053602000b2003200141016a360208200520016a200041146a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d1820032006360204200320053602000b2003200141016a360208200520016a200041156a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d1920032006360204200320053602000b2003200141016a360208200520016a200041166a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d1a20032006360204200320053602000b2003200141016a360208200520016a200041176a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d1b20032006360204200320053602000b2003200141016a360208200520016a200041186a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d1c20032006360204200320053602000b2003200141016a360208200520016a200041196a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d1d20032006360204200320053602000b2003200141016a360208200520016a2000411a6a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d1e20032006360204200320053602000b2003200141016a360208200520016a2000411b6a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d1f20032006360204200320053602000b2003200141016a360208200520016a2000411c6a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d2020032006360204200320053602000b2003200141016a360208200520016a2000411d6a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d2120032006360204200320053602000b2003200141016a360208200520016a2000411e6a2d00003a000002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d2320014101742206200520052006491b22064100480d230240024020010d002006103221050c010b200328020020012006103421050b2005450d2220032006360204200320053602000b2003200141016a360208200520016a2000411f6a2d00003a0000200041206a22002004470d000b0b2003280204210020022802002002280204200328020022012003280208100502402000450d00200110290b200341106a24000f0b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b1033000bb50404057f017e017f017e0240024020012802042202450d00200128020022032d0000210420012002417f6a22053602042001200341016a3602000240200441037122064103460d00024002400240024020060e03000102000b2004410276ad21070c020b41012106024020050d000c050b20032d0001210520012002417e6a3602042001200341026a3602002005410874200472220141ffff0371418002490d04200141fcff0371410276ad21070c010b410121060240200541034f0d000c040b200341036a2d0000210520032f0001210820012002417c6a3602042001200341046a3602002008200541107472410874200472220141808004490d032001410276ad21070b410021060c020b02402004410276220841044b0d000240024020080e050002020201000b20054104490d022003350001210720012002417b6a3602042001200341056a36020020074280808080045421060c030b20054108490d01200329000121072001200241776a3602042001200341096a3602002007428080808080808080015421060c020b200841046a220541084b0d002002417e6a2102200341026a2103410021044200210741012106034002402002417f470d000c030b2003417f6a310000210920012002360204200120033602002002417f6a2102200341016a210320092004410374413871ad862007842107200441016a220441ff01712005490d000b2007427f412820084103746b413871ad885821060c010b410121060b2000200737030820002006ad3703000bde0506067f017e017f017e017f017e230041206b220224000240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200024002400240200541037122074103460d0002400240024020070e03000102000b2005410276ad21080c040b410121072006450d0220042d0001210620012003417e6a3602042001200441026a3602002006410874200572220141ffff0371418002490d02200141fcff0371410276ad21080c030b4101210720064103490d01200441036a2d0000210620042f0001210920012003417c6a3602042001200441046a3602002009200641107472410874200572220141808004490d012001410276ad21080c020b024020054102762209410c4b0d0002400240024020090e0d00030303010303030303030302000b20064104490d052004350001210820012003417b6a3602042001200441056a36020020084280808080045421074200210a0c060b20064108490d04200429000121082001200341776a3602042001200441096a3602002008428080808080808080015421074200210a0c050b20064110490d03200441096a290000210a2004290001210820012003416f6a3602042001200441116a360200200a428080808080808080015421070c040b200941046a220641104b0d022003417e6a2103200441026a21044100210541012107200241186a210b420021084200210a03402003417f460d01200241106a2004417f6a3100004200200541037441f80071109e0520012003360204200120043602002003417f6a2103200441016a2104200b290300200a84210a20022903102008842108200541016a220541ff01712006490d000b2002427f427f41e80020094103746b41f80071109f052008200229030058200a200241086a290300220c58200a200c511b21070c030b0c020b4200210a410021070c010b410121070b20002008370308200041106a200a37030020002007ad370300200241206a24000b9e0701037f02400240024002400240024020002802002202413f4b0d0002400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d0620004101742204200320032004491b22044100480d060240024020000d002004103221030c010b200128020020002004103421030b2003450d0220012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a20024102743a00000f0b200241808001490d032002418080808004490d020c010b20044101102e000b0240024002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0520024101742204200320032004491b22044100480d050240024020020d002004103221030c010b200128020020022004103421030b2003450d0120012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a00002000280200210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d0520024101742200200420042000491b22004100480d050240024020020d002000103221020c010b200128020020022000103421020b2002450d0220012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b20044101102e000b20004101102e000b024002400240200141046a2802002203200141086a28020022006b4104490d00200128020021030c010b200041046a22042000490d0320034101742200200420042000491b22004100480d030240024020030d002000103221030c010b200128020020032000103421030b2003450d0120012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20024102744102723600000f0b20004101102e000b024002400240200141046a2802002203200141086a28020022006b4102490d00200128020021030c010b200041026a22042000490d0220034101742200200420042000491b22004100480d020240024020030d002000103221030c010b200128020020032000103421030b2003450d0120012003360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200320006a20024102744101723b00000f0b20004101102e000b1033000bac0903017f017e057f230041e0006b220224000240024002400240024002400240024002400240024020002903002203423f560d0002400240200141046a280200200141086a2802002200460d00200128020021040c010b200041016a22042000490d0b20004101742205200420042005491b22054100480d0b0240024020000d002005103221040c010b200128020020002005103421040b2004450d0220012004360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200420006a2003a74102743a00000c080b200342808001540d062003428080808004540d054108200379a741037622056b4104490d0402400240200141046a280200200141086a2802002204460d00200128020021060c010b200441016a22072004490d0a20044101742206200720072006491b22074100480d0a0240024020040d002007103221060c010b200128020020042007103421060b2006450d0220012006360200200141046a2007360200200141086a28020021040b200141086a2207200441016a360200200620046a411320054102746b3a0000200220002903002203370308200541786a2104200141046a2106034002400240200628020020072802002200460d00200128020021050c010b200041016a22052000490d0b20004101742208200520052008491b22084100480d0b0240024020000d002008103221050c010b200128020020002008103421050b2005450d042001200536020020062008360200200728020021000b2007200041016a360200200520006a2003a73a000020034208882103200441016a22002004492105200021042005450d000b20022003370308200350450d030c070b20054101102e000b20074101102e000b20084101102e000b200241286a41146a4102360200200241346a4106360200200241106a41146a41033602002002200241086a360240200241b0d6c00036024420024203370214200241acf9c5003602102002410636022c200242043703582002420137024c200241b8d6c0003602482002200241286a3602202002200241c8006a3602382002200241c4006a3602302002200241c0006a360228200241106a41c0d6c000107d000b4194d6c000106d000b024002400240200141046a2802002204200141086a28020022006b4104490d00200128020021040c010b200041046a22052000490d0520044101742200200520052000491b22004100480d050240024020040d002000103221040c010b200128020020042000103421040b2004450d0120012004360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200420006a2003a74102744102723600000c020b20004101102e000b02400240200141046a2802002204200141086a28020022006b4102490d00200128020021040c010b200041026a22052000490d0320044101742200200520052000491b22004100480d030240024020040d002000103221040c010b200128020020042000103421040b2004450d0220012004360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200420006a2003a74102744101723b00000b200241e0006a24000f0b20004101102e000b1033000bc20202027f017e23004180016b220224002000280200210002400240024002400240200128020022034110710d002000290300210420034120710d0120044101200110a70221000c020b20002903002104410021000340200220006a41ff006a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d0220014101418882c6004102200220006a4180016a410020006b10a80221000c010b410021000340200220006a41ff006a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d0220014101418882c6004102200220006a4180016a410020006b10a80221000b20024180016a240020000f0b20034180011030000b20034180011030000b800a03017f027e057f230041e0006b2202240002400240024002400240024002400240024002400240200028020022002903002203423f56200041086a290300220442005220045022051b0d0002400240200141046a280200200141086a2802002200460d00200128020021050c010b200041016a22052000490d0b20004101742206200520052006491b22064100480d0b0240024020000d002006103221050c010b200128020020002006103421050b2005450d0220012005360200200141046a2006360200200141086a28020021000b200141086a200041016a360200200520006a2003a74102743a00000c080b20034280800154410020051b0d06200342808080800454410020051b0d05411020047920037942c0007c20044200521ba741037622066b4104490d0402400240200141046a280200200141086a2802002205460d00200128020021070c010b200541016a22082005490d0a20054101742207200820082007491b22084100480d0a0240024020050d002008103221070c010b200128020020052008103421070b2007450d0220012007360200200141046a2008360200200141086a28020021050b200141086a2208200541016a360200200720056a413320064102746b3a0000200029030021032002200041086a290300220437030820022003370300200641706a2105200141046a2107034002400240200728020020082802002200460d00200128020021060c010b200041016a22062000490d0b20004101742209200620062009491b22094100480d0b0240024020000d002009103221060c010b200128020020002009103421060b2006450d042001200636020020072009360200200828020021000b2008200041016a360200200620006a2003a73a00002003420888200442388684210320044208882104200541016a22002005492106200021052006450d000b2002200337030020022004370308200320048450450d030c070b20064101102e000b20084101102e000b20094101102e000b200241286a41146a4102360200200241346a4107360200200241106a41146a410336020020022002360240200241e0d7c00036024420024203370214200241acf9c5003602102002410736022c200242043703582002420137024c200241b8d6c0003602482002200241286a3602202002200241c8006a3602382002200241c4006a3602302002200241c0006a360228200241106a41f0d7c000107d000b41c4d7c000106d000b024002400240200141046a2802002205200141086a28020022006b4104490d00200128020021050c010b200041046a22062000490d0520054101742200200620062000491b22004100480d050240024020050d002000103221050c010b200128020020052000103421050b2005450d0120012005360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200520006a2003a74102744102723600000c020b20004101102e000b02400240200141046a2802002205200141086a28020022006b4102490d00200128020021050c010b200041026a22062000490d0320054101742200200620062000491b22004100480d030240024020050d002000103221050c010b200128020020052000103421050b2005450d0220012005360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200520006a2003a74102744101723b00000b200241e0006a24000f0b20004101102e000b1033000b840605027f027e017f027e027f230041a0016b220224002000280200210002400240024002400240024002400240200128020022034110710d00200041086a29030021042000290300210520034120710d0220054290ce005441002004501b450d012005a72103412721000c060b200041086a2903002105200029030021044180012100024003402000450d01200241206a20006a417f6a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a210020044204882005423c8684220420054204882205844200520d000b0b20004181014f0d0220014101418882c6004102200241206a20006a41800120006b10a80221000c060b41272100200241186a21060340200241106a200520044290ce00420010a1052002200229031022072006290300220842f0b17f427f10a005200241206a20006a2203417c6a200520022903007ca7220941ffff037141e4006e220a410174419affc5006a2f00003b00002003417e6a200a419c7f6c20096a41ffff0371410174419affc5006a2f00003b0000200542ffc1d72f56210320044200522109200450210a2000417c6a2100200721052008210420032009200a1b0d000c040b0b4180012100024003402000450d01200241206a20006a417f6a2005a7410f712203413072200341376a2003410a491b3a00002000417f6a210020054204882004423c8684220520044204882204844200520d000b0b20004181014f0d0120014101418882c6004102200241206a20006a41800120006b10a80221000c040b20004180011030000b20004180011030000b2007a721030b02400240200341e3004a0d00200321090c010b200241206a2000417e6a22006a2003200341ffff037141e4006e2209419c7f6c6a41ffff0371410174419affc5006a2f00003b00000b024002402009410a480d00200241206a2000417e6a22006a2009410174419affc5006a2f00003b00000c010b200241206a2000417f6a22006a200941306a3a00000b2001410141e480c6004100200241206a20006a412720006b10a80221000b200241a0016a240020000baf1601067f230041106b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e050003010204000b2002410036020820024201370300410110322203450d05200242818080801037020420022003360200200341023a00002002200236020c200141016a2002410c6a1085010c040b2002410036020820024201370300410110322203450d05200242818080801037020420022003360200200341043a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1a20034101742205200420042005491b22054100480d1a0240024020030d002005103221040c010b200228020020032005103421040b2004450d0720022005360204200220043602000b2002200341016a360208200420036a20012d00013a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1a20034101742205200420042005491b22054100480d1a0240024020030d002005103221040c010b200228020020032005103421040b2004450d0820022005360204200220043602000b2002200341016a360208200420036a20012d00023a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1a20034101742205200420042005491b22054100480d1a0240024020030d002005103221040c010b200228020020032005103421040b2004450d0920022005360204200220043602000b2002200341016a360208200420036a20012d00033a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1a20034101742205200420042005491b22054100480d1a0240024020030d002005103221040c010b200228020020032005103421040b2004450d0a20022005360204200220043602000b2002200341016a360208200420036a20012d00043a000020012802082105200141106a2802002201200210660240024020022802042204200228020822036b2001490d00200228020021040c010b200320016a22062003490d1a20044101742207200620062007491b22064100480d1a0240024020040d002006103221040c010b200228020020042006103421040b2004450d0b20022006360204200220043602000b2002200320016a360208200420036a20052001109b051a0c030b2002410036020820024201370300410110322203450d0a200242818080801037020420022003360200200341053a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1920034101742205200420042005491b22054100480d190240024020030d002005103221040c010b200228020020032005103421040b2004450d0c20022005360204200220043602000b2002200341016a360208200420036a20012d00013a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1920034101742205200420042005491b22054100480d190240024020030d002005103221040c010b200228020020032005103421040b2004450d0d20022005360204200220043602000b2002200341016a360208200420036a20012d00023a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1920034101742205200420042005491b22054100480d190240024020030d002005103221040c010b200228020020032005103421040b2004450d0e20022005360204200220043602000b2002200341016a360208200420036a20012d00033a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1920034101742205200420042005491b22054100480d190240024020030d002005103221040c010b200228020020032005103421040b2004450d0f20022005360204200220043602000b2002200341016a360208200420036a20012d00043a000020012802082105200141106a2802002201200210660240024020022802042204200228020822036b2001490d00200228020021040c010b200320016a22062003490d1920044101742207200620062007491b22064100480d190240024020040d002006103221040c010b200228020020042006103421040b2004450d1020022006360204200220043602000b2002200320016a360208200420036a20052001109b051a0c020b2002410036020820024201370300410110322203450d0f200242818080801037020420022003360200200341063a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1820034101742205200420042005491b22054100480d180240024020030d002005103221040c010b200228020020032005103421040b2004450d1120022005360204200220043602000b2002200341016a360208200420036a20012d00013a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1820034101742205200420042005491b22054100480d180240024020030d002005103221040c010b200228020020032005103421040b2004450d1220022005360204200220043602000b2002200341016a360208200420036a20012d00023a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1820034101742205200420042005491b22054100480d180240024020030d002005103221040c010b200228020020032005103421040b2004450d1320022005360204200220043602000b2002200341016a360208200420036a20012d00033a000002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d1820034101742205200420042005491b22054100480d180240024020030d002005103221040c010b200228020020032005103421040b2004450d1420022005360204200220043602000b2002200341016a360208200420036a20012d00043a000020012802082105200141106a2802002201200210660240024020022802042204200228020822036b2001490d00200228020021040c010b200320016a22062003490d1820044101742207200620062007491b22064100480d180240024020040d002006103221040c010b200228020020042006103421040b2004450d1520022006360204200220043602000b2002200320016a360208200420036a20052001109b051a0c010b2002410036020820024201370300410110322203450d14200242818080801037020420022003360200200341003a0000200141046a28020021052001410c6a2802002201200210660240024020022802042204200228020822036b2001490d00200228020021040c010b200320016a22062003490d1720044101742207200620062007491b22064100480d170240024020040d002006103221040c010b200228020020042006103421040b2004450d1620022006360204200220043602000b2002200320016a360208200420036a20052001109b051a0b200020022201290200370200200041086a200141086a280200360200200241106a24000f0b41014101102e000b41014101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20064101102e000b41014101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20064101102e000b41014101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20064101102e000b41014101102e000b20064101102e000b1033000bf40601067f230041f0006b21020240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a2206360204410121072001200441016a360200200541f001490d0a200541847e6a220541034b0d0420050e0401020803010b200041023a00000f0b20064102490d0320042f0001210520012003417d6a3602042001200441036a360200200541ef014b0d04200041023a00000f0b20064104490d042004280001210520012003417b6a3602042001200441056a36020041012107200541ffff034b0d07200041023a00000f0b41002105200241003a00682003417f6a21062003417e6a210302400340024020062005470d000240200541ff0171450d00200241003a00680b410121010c020b200241c8006a20056a200420056a220741016a2d00003a0000200120033602042001200741026a3602002002200541016a22073a00682003417f6a21032007210520074120470d000b200241c6006a20022d004a3a0000200241306a200241d7006a290000370300200241386a200241df006a290000370300200241c0006a200241e7006a2d00003a0000200220022f01483b01442002200229004f370328200228004b2105410021010b200241246a41026a2203200241c4006a41026a2d00003a0000200241086a41086a2207200241286a41086a290300370300200241086a41106a2204200241286a41106a290300370300200241086a41186a2206200241286a41186a2d00003a0000200220022f01443b0124200220022903283703082001450d05200041023a00000f0b200041023a00000f0b200041023a00000f0b410121070c030b200041023a00000f0b0240200641044f0d00200041023a00000f0b200041023a000020012003417b6a3602042001200441056a3602000f0b200241286a41026a20032d00003a0000200241c8006a41086a2007290300370300200241c8006a41106a2004290300370300200241c8006a41186a20062d00003a0000200220022f01243b012820022002290308370348410021070b200020073a0000200020022f01283b0001200041046a2005360200200041086a2002290348370200200041036a2002412a6a2d00003a0000200041106a200241c8006a41086a290300370200200041186a200241c8006a41106a290300370200200041206a200241c8006a41186a2802003602000bb30801037f0240024002400240024002400240024020002d00004101460d0002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0820024101742204200320032004491b22044100480d080240024020020d002004103221030c010b200128020020022004103421030b2003450d0220012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a41ff013a0000200041016a20011081010f0b0240024002400240200041046a280200220241ffff034b0d00200241ef014b0d03200141046a280200200141086a2802002200460d01200128020021030c020b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d0a20004101742204200320032004491b22044100480d0a0240024020000d002004103221030c010b200128020020002004103421030b2003450d0520012003360200200141046a2004360200200141086a28020021000b200141086a2204200041016a360200200320006a41fd013a000002400240200141046a2802002203200428020022006b4104490d00200128020021030c010b200041046a22042000490d0a20034101742200200420042000491b22004100480d0a0240024020030d002000103221030c010b200128020020032000103421030b2003450d0620012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20023600000f0b200041016a22032000490d0820004101742204200320032004491b22044100480d080240024020000d002004103221030c010b200128020020002004103421030b2003450d0520012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a20023a00000f0b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d0720004101742204200320032004491b22044100480d070240024020000d002004103221030c010b200128020020002004103421030b2003450d0520012003360200200141046a2004360200200141086a28020021000b200141086a2204200041016a360200200320006a41fc013a000002400240200141046a2802002203200428020022006b4102490d00200128020021030c010b200041026a22042000490d0720034101742200200420042000491b22004100480d070240024020030d002000103221030c010b200128020020032000103421030b2003450d0620012003360200200141046a2000360200200141086a28020021000b200141086a200041026a360200200320006a20023b00000f0b20044101102e000b20044101102e000b20004101102e000b20044101102e000b20044101102e000b20004101102e000b1033000bd60302047f037e230041e0006b2204240002400240411410322205450d00200541002900d8d540370000200541106a41002800e8d540360000200541086a41002900e0d54037000020044294808080c002370234200420053602302001200441306a10810120042802342105200441186a20042802302206200428023810a101200441186a41106a2903004200200428021822071b21082004290320420020071b210902402005450d00200610290b200441306a2001200920027c2202200820037c2002200954ad7c10a201200441306a41106a290300210920042903382102024020042903304200520d00200221030c020b200441c2d5c000411610a301200441106a29030021082004290308210a2004280200210542002103200441306a41086a220142003703002004420037033041c2d5c0004116200441306a1003200441d0006a41086a200129030037030020042004290330370350200442002008420020051b220820097d200a420020051b2209200254ad7d220a200920027d2202200956200a200856200a2008511b22051b37033820044200200220051b370330200441d0006a4110200441306a41101005420021090c010b41144101102e000b2000200337030020002009370308200441e0006a24000b880204017f017e037f027e230041c0006b2203240042002104200341206a41186a22054200370300200341206a41106a22064200370300200341206a41086a220742003703002003420037032020012002200341206a1000200341186a2005290300370300200341106a2006290300370300200341086a2007290300370300200320032903203703002003410036022020034120200341206a1006210102400240024020032802202202417f470d000c010b20024110490d01200141086a29000021082001290000210920011029420121040b2000200937030820002004370300200041106a2008370300200341c0006a24000f0b41f7cdc3004133200341206a41ecd6c3001054000b9d0603047f037e047f230041b0016b22042400024002400240411410322205450d00200541002900d8d540370000200541106a41002800e8d540360000200541086a41002900e0d54037000020044294808080c002370224200420053602202001200441206a10810120042802242106200441086a20042802202207200428022810a101200441086a41106a2903002108200428020821052004290310210902402006450d00200710290b2008420020051b210a2009420020051b21080240200242ffffe883b1de1656200342005220035022051b0d002008200a844200520d0020004200370300200041013a0018200041106a4200370300200041086a42003703000c030b4101210602402002428080e983b1de1654410020051b0d00411410322205450d0241002106200541002900d8d540370000200541106a41002800e8d540360000200541086a41002900e0d54037000020044294808080c002370224200420053602202001200441206a108101200428022421072004280228210b20042802202105200441206a41186a220c4200370300200441206a41106a220d4200370300200441206a41086a220e4200370300200442003703202005200b200441206a100020044190016a41186a200c29030037030020044190016a41106a200d29030037030020044190016a41086a200e290300370300200420042903203703900120044190016a41204101410041001007210b02402007450d00200510290b200b417f470d00200110a401200441d8006a2003370300200441d0006a200237030041002106200441206a41086a41003a0000200441296a2001290000370000200441316a200141086a290000370000200441396a200141106a290000370000200441c1006a200141186a290000370000200441023a002041014100200441206a104c0b20012002200310a501200041106a200a20037d2008200254ad7d2003200a7d2002200854ad7d2008200256200a200356200a2003511b22051b3703002000200820027d200220087d20051b370308200020063a001820002005ad3703000c020b41144101102e000b41144101102e000b200441b0016a24000bce0104017f017e017f027e230041206b2203240042002104200341106a41086a220542003703002003420037031020012002200341106a1003200341086a2005290300370300200320032903103703002003410036021020034110200341106a1006210102400240024020032802102202417f470d000c010b20024110490d01200141086a29000021062001290000210720011029420121040b2000200737030820002004370300200041106a2006370300200341206a24000f0b41f7cdc3004133200341106a41ecd6c3001054000be90a03067f037e037f230041b0016b22012400200141186a41c6ddc3004113105d20012802182102200128021c2103024002400240024002400240024002400240410110322204450d00200420002d00003a000020044101410210342204450d01200420002d00013a000120044102410410342204450d02200420002d00023a0002200420002d00033a000320044104410810342204450d03200420002d00043a0004200420002d00053a0005200420002d00063a0006200420002d00073a000720044108411010342204450d04200420002d00083a0008200420002d00093a0009200420002d000a3a000a200420002d000b3a000b200420002d000c3a000c200420002d000d3a000d200420002d000e3a000e200420002d000f3a000f20044110412010342204450d05200420002d00103a0010200420002d00113a0011200420002d00123a0012200420002d00133a0013200420002d00143a0014200420002d00153a0015200420002d00163a0016200420002d00173a0017200420002d00183a0018200420002d00193a0019200420002d001a3a001a200420002d001b3a001b200420002d001c3a001c200420002d001d3a001d200420002d001e3a001e200420002d001f3a001f20042d0000210520042d0001210620041029200141a0016a2005200641087472410676220610ab0202402005413f71220420012802a8014f0d00200141086a20012802a00120044105746a2204105b2001290308200141086a41086a290300844200520d00200041086a2900002107200041106a2900002108200041186a290000210920042000290000370000200441186a2009370000200441106a2008370000200441086a2007370000200141306a41086a200141a0016a41086a280200360200200120012903a0013703302006200141306a10b7030c090b2003410020021b2104024020012802a401450d0020012802a00110290b200141306a200410ab020240200128023841c000490d000340200441016a210402402001280234450d00200128023010290b200141306a200410ab022001280238413f4b0d000b0b200141206a41086a200141306a41086a2202280200220536020020012001290330370320200141306a41186a2203200041186a290000370300200141306a41106a220a200041106a2900003703002002200041086a29000037030020012000290000370330024020052001280224470d00200541016a22062005490d082005410174220b20062006200b491b220641ffffff3f712006470d082006410574220c4100480d080240024020050d00200c1032210b0c010b20012802202005410574200c1034210b0b200b450d07200120063602242001200b3602200b200520044106746a210b200128022020054105746a22062001290330370000200641086a2002290300370000200641106a200a290300370000200641186a20032903003700002001200541016a22053602280240200541c000470d00200141306a41086a220542003703002001420037033041c6ddc3004113200141306a1003200141a0016a41086a2005290300370300200120012903303703a0012001200441016a360230200141a0016a4110200141306a410410050b200141306a41086a2205200141206a41086a280200360200200120012903203703302004200141306a10b70320052000290000370300200141306a41106a200041086a290000370300200141306a41186a200041106a290000370300200141d0006a200041186a2900003703002001200b360234200141013a003041014100200141306a104c0c080b41014101102e000b41024101102e000b41044101102e000b41084101102e000b41104101102e000b41204101102e000b200c4101102e000b1033000b200141b0016a24000bfe1103087f027e017f230041f0036b2203240002400240024002400240411410322204450d00200441002900d8d540370000200441106a41002800e8d540360000200441086a41002900e0d54037000020034294808080c00237024c200320043602482000200341c8006a108101200328024c21052003280250210620032802482104200341c8006a41186a22074200370300200341c8006a41106a22084200370300200341c8006a41086a220942003703002003420037034820042006200341c8006a100020034188036a41186a200729030037030020034188036a41106a200829030037030020034188036a41086a20092903003703002003200329034837038803200320023703502003200137034820034188036a4120200341c8006a4110100502402005450d00200410290b200142ffffe883b1de165620024200522002501b0d030240411410322204450d00200441002900d8d540370000200441106a41002800e8d540360000200441086a41002900e0d54037000020034294808080c00237024c200320043602482000200341c8006a108101200328024c21052003280250210620032802482104200341c8006a41186a22074200370300200341c8006a41106a22084200370300200341c8006a41086a220942003703002003420037034820042006200341c8006a100020034188036a41186a200729030037030020034188036a41106a200829030037030020034188036a41086a20092903003703002003200329034837038803200341306a20034188036a10a601200341306a41106a2903002101200329033821022003280230210a02402005450d00200410290b0240410e10322204450d0020044100290084d640370000200441066a410029008ad6403700002003428e808080e00137024c200320043602482000200341c8006a108101200328024c21052003280250210620032802482104200341c8006a41186a22074200370300200341c8006a41106a22084200370300200341c8006a41086a220942003703002003420037034820042006200341c8006a100020034188036a41186a200729030037030020034188036a41106a200829030037030020034188036a41086a2009290300370300200320032903483703880320034188036a4120100402402005450d00200410290b02402002200184500d00200a450d00200341186a41c2d5c000411610a301200341186a41106a290300210b2003290320210c20032802182104200341c8006a41086a220542003703002003420037034841c2d5c0004116200341c8006a100320034188036a41086a2005290300370300200320032903483703880320034200200b420020041b220b20017d200c420020041b2201200254ad7d220c200120027d2202200156200c200b56200c200b511b22041b37035020034200200220041b37034820034188036a4110200341c8006a411010050b200010a7010240411710322204450d00200441002900f9f9433700002004410f6a4100290088fa43370000200441086a4100290081fa4337000020034297808080f00237024c200320043602482000200341c8006a108101200328024c21072003280250210620032802482105200341c8006a41186a22044200370300200341c8006a41106a22084200370300200341c8006a41086a220942003703002003420037034820052006200341c8006a100020034188036a41186a200429030037030020034188036a41106a200829030037030020034188036a41086a20092903003703002003200329034837038803200341c8006a20034188036a10a801024020032d004822064102460d0020034188036a412010040b200341e8006a280200210a200341e4006a28020021092004280200210802402007450d00200510290b0240024002400240200641037122044103460d0020040e03010003010b20060d0220090d010c020b2008200a10082009450d010b200810290b200341b8016a200010a90120032802b801210420032802c00121052003410036024820042005200341c8006a1006210720032802482206417f460d04200320063602ec03200320073602e803200341c8006a200341e8036a10aa01024020032d00484101460d0020034188036a200341c8006a41017241e000109b051a02402006450d00200710290b200341a8026a20034188036a41e000109b051a200420051004200341c8016a200341a8026a41e000109b051a20034188036a200341c8016a41e000109b051a024020032802bc01450d00200410290b200341c8006a20034188036a41e000109b051a200341e8006a210d20034188016a210a4104210641e7e485f30621040340200a210702400240200441e9dabdf306460d000240200441e7e485f306470d00200341c8006a21070c010b200d2107200441e2c289ab06460d00410121084100210541012107410121090c010b41202105410021084120103222090d0041204101102e000b200920072005109b052107200320053602b402200320053602b002200320073602ac02200320043602a802200341c8016a200341a8026a10ab0120032802c801220420032802d0011004024020032802cc01450d00200410290b024020080d00200710290b2006410c460d07200641acc8c2006a2800002104200641046a21060c000b0b41f7cdc300413320034188036a41ecd6c3001054000b41174101102e000b410e4101102e000b41144101102e000b41144101102e000b200341c8016a200341a8026a41e000109b051a20032802bc01450d00200410290b411810322204450d01200441002900ecd540370000200441106a41002900fcd540370000200441086a41002900f4d54037000020034298808080800337024c200320043602482000200341c8006a108101200328024c2104200320032802482206200328025010a101200341106a2903002102200329030821012003280200210502402004450d00200610290b02402001200284500d0020050d010b200010ac01200341c8006a41086a41013a0000200341d1006a2000290000370000200341d9006a200041086a290000370000200341e1006a200041106a290000370000200341e9006a200041186a290000370000200341023a004841014100200341c8006a104c0b200341f0036a24000f0b41184101102e000b980102037f037e230041106b220224002002410036020420014120200241046a1006210302400240024020022802042204417f470d00420021050c010b20044110490d01200341086a29000021062003290000210720031029200141201004420121050b2000200537030020002007370308200041106a2006370300200241106a24000f0b41f7cdc3004133200241086a41ecd6c3001054000bc30701077f23004190016b22012400024002400240410e10322202450d00200241002900e4bd44370000200241066a41002900eabd443700002001428e808080e00137026c200120023602682000200141e8006a108101200128026c21032001280270210420012802682102200141e8006a41186a22054200370300200141e8006a41106a22064200370300200141e8006a41086a220742003703002001420037036820022004200141e8006a1000200141c8006a41186a2005290300370300200141c8006a41106a2006290300370300200141c8006a41086a200729030037030020012001290368370348200141e8006a200141c8006a412010590240024020012d00684101470d00200141c8006a41201004200141086a41186a20014181016a290000370300200141086a41106a200141f9006a290000370300200141086a41086a200141f1006a2900003703002001200129006937030802402003450d00200210290b200141286a41186a200141086a41186a290300370300200141286a41106a200141086a41106a290300370300200141286a41086a200141086a41086a29030037030020012001290308370328410e10322202450d03200241002900bcbe44370000200241066a41002900c2be443700002001428e808080e00137026c20012002360268200141286a200141e8006a108101200128026c21032001280270210420012802682102200141e8006a41186a22054200370300200141e8006a41106a22064200370300200141e8006a41086a220742003703002001420037036820022004200141e8006a1000200141c8006a41186a2005290300370300200141c8006a41106a2006290300370300200141c8006a41086a200729030037030020012001290368370348200141c8006a412010042003450d01200210290c010b2003450d00200210290b410d10322202450d02200241002900cabe44370000200241056a41002900cfbe443700002001428d808080d00137026c200120023602682000200141e8006a108101200128026c21032001280270210420012802682102200141e8006a41186a22054200370300200141e8006a41106a22064200370300200141e8006a41086a220742003703002001420037036820022004200141e8006a1000200141c8006a41186a2005290300370300200141c8006a41106a2006290300370300200141c8006a41086a200729030037030020012001290368370348200141c8006a4120100402402003450d00200210290b2000108304200010840420014190016a24000f0b410e4101102e000b410e4101102e000b410d4101102e000bae0a050a7f027e037f027e017f230041e0006b220224002002410036023820014120200241386a1006210302400240024002400240024002400240024020022802382204417f460d0020030d010b200041023a00000c010b2002200436021c200220033602182004450d0520032d0000210120022004417f6a36021c2002200341016a360218200141014b0d0502400240024020010e020001000b200241086a200241186a102c20022802080d07200228021c200228020c2205490d072005417f4c0d030240024020050d004101210641010d010c090b2005102d2206450d092006200228021822012005109b052104200228021c22072005490d052002200720056b36021c2002200120056a3602182004450d080b200228021c22084104490d0520022802182209280000210a20022008417c6a220b36021c2002200941046a36021841002101200241003a0058417b210703400240200b2001470d000240200141ff0171450d00200241003a00580b20050d080c090b200241386a20016a200920016a220441046a2d00003a00002002200820076a36021c2002200441056a3602182002200141016a22043a00582007417f6a21072004210120044120470d000b200220022802383602302002200228003b3600330240024002400240200820046b2207417c6a4110490d00200241c7006a290000210c200229003f210d20022d0057210b2002280053210e200228004f210f2002200920046a220141146a220936021820022007416c6a221036021c20104104490d002001410c6a2900002111200141046a2900002112200928000021092002200741686a36021c2002200141186a2210360218200841686a2004460d0320102d000021102002200741676a221336021c2002200141196a360218201041014b0d034100210420100e020201020b20050d090c0a0b20134104490d01200141196a28000021082002200741636a36021c20022001411d6a360218410121040b2002200228003336002b20022002280230360228200220022802283602382002200228002b36003b200220022800213602102002200241246a28000036001341002101200521070c020b2005450d070c060b41002101200241003a00582004417f6a21082004417e6a21040340024020082001470d00200141ff0171450d08200241003a00580c080b200241386a20016a200320016a220741016a2d00003a00002002200741026a3602182002200141016a22073a00582002200436021c2004417f6a21042007210120074120470d000b2002200228003b360033200220022802383602302002200228003336002b20022002280230360228200220022802283602102002200228002b360013200241c7006a2900002111200229003f211220022d0057210520022800532107200228004f21062002200241246a28000036003b20022002280021360238410121010b200020013a000020002002280210360001200041106a2011370300200041086a2012370300200041c3006a200c3700002000413b6a200d370000200041046a2002280013360000200041306a20083602002000412c6a2004360200200041286a2009360200200041246a200a360200200041206a20053602002000411c6a2007360200200041186a2006360200200041346a2002280238360200200041376a200228003b360000200041d3006a200b3a0000200041cf006a200e360000200041cb006a200f360000200310290b200241e0006a24000f0b102f000b200520071030000b2005450d010b200610290b41f7cdc3004133200241306a41ecd6c3001054000b20054101102e000b860901087f230041c0006b2202240002400240024002400240024002400240024002400240411010322203450d00200341086a41002900daed42370000200341002900d2ed4237000020024290808080800237020420022003360200410d2002106602400240024020022802042204200228020822056b410d490d002005410d6a2106200228020021030c010b2005410d6a22062005490d0120044101742203200620062003491b22074100480d010240024020040d002007103221030c010b200228020020042007103421030b2003450d032002200736020420022003360200200721040b2002200636020841002107200320056a220541002900a1db42370000200541056a41002900a6db42370000200241206a2003200610830320022802282206417f4c0d03200228022021080240024020060d00410121050c010b20062107200610322205450d050b200520082006109b05210902402004450d00200310290b02402002280224450d00200810290b410110322203450d05200320012d00003a000020034101410210342203450d06200320012d00013a000120034102410410342203450d07200320012d00023a0002200320012d00033a000320034104410810342203450d08200320012d00043a0004200320012d00053a0005200320012d00063a0006200320012d00073a000720034108411010342203450d09200320012d00083a0008200320012d00093a0009200320012d000a3a000a200320012d000b3a000b200320012d000c3a000c200320012d000d3a000d200320012d000e3a000e200320012d000f3a000f20034110412010342203450d0a200320012d00103a0010200320012d00113a0011200320012d00123a0012200320012d00133a0013200320012d00143a0014200320012d00153a0015200320012d00163a0016200320012d00173a0017200320012d00183a0018200320012d00193a0019200320012d001a3a001a200320012d001b3a001b200320012d001c3a001c200320012d001d3a001d200320012d001e3a001e200320012d001f3a001f200241206a41186a22014200370300200241206a41106a22044200370300200241206a41086a220842003703002002420037032020034120200241206a1000200241186a2001290300370300200241106a2004290300370300200241086a2008290300370300200220022903203703000240200720066b4120490d00200641206a21040c0c0b200641206a22042006490d0020074101742201200420042001491b22014100480d000240024020070d002001103221050c010b200920072001103421050b02402005450d00200121070c0c0b20014101102e000b1033000b41104101102e000b20074101102e000b102f000b20064101102e000b41014101102e000b41024101102e000b41044101102e000b41084101102e000b41104101102e000b41204101102e000b200520066a22012002290300370000200141186a200241186a290300370000200141106a200241106a290300370000200141086a200241086a29030037000020031029200020043602082000200736020420002005360200200241c0006a24000b8b0701077f23004190026b2202240041002103200241003a002820012802042104417f210502400240034020042003460d01200241086a20036a200128020022062d00003a00002001200420056a3602042001200641016a3602002002200341016a22073a00282005417f6a21052007210320074120470d000b200241e8006a41086a200241086a41086a290300370300200241e8006a41106a200241086a41106a290300370300200241e8006a41186a200241086a41186a2903003703002002200229030837036841002103200241003a0028200420076b2108200420056a21050340024020082003470d000240200341ff0171450d00200241003a00280b200041013a00000c030b200241086a20036a200620036a220741016a2d00003a0000200120053602042001200741026a3602002002200341016a22073a00282005417f6a21052007210320074120470d000b20024188016a41086a200241086a41086a29030037030020024188016a41106a200241086a41106a29030037030020024188016a41186a200241086a41186a290300370300200220022903083703880141002103200241003a008802200620076a2106034002402005417f470d000240200341ff0171450d00200241003a0088020b200041013a00000c030b200241e8016a20036a200620036a220741016a2d00003a0000200120053602042001200741026a3602002002200341016a22073a0088022005417f6a21052007210320074120470d000b200241a8016a41086a2201200241e8016a41086a290300370300200241a8016a41106a2203200241e8016a41106a290300370300200241a8016a41186a2205200241e8016a41186a290300370300200241086a41086a200241e8006a41086a290300370300200241086a41106a200241e8006a41106a290300370300200241086a41186a200241e8006a41186a290300370300200220022903e8013703a80120022002290368370308200241c0006a20024188016a41186a290300370300200241386a20024188016a41106a290300370300200241306a20024188016a41086a2903003703002002200229038801370328200241e0006a2005290300370300200241d8006a2003290300370300200241d0006a2001290300370300200220022903a801370348200041016a200241086a41e000109b051a200041003a00000c010b0240200341ff0171450d00200241003a00280b200041013a00000b20024190026a24000bce0a010b7f230041c0006b2202240002400240024002400240024002400240024002400240411010322203450d00200341086a41002900cff042370000200341002900c7f04237000020024290808080800237020420022003360200410d2002106602400240024020022802042204200228020822056b410d490d002005410d6a2106200228020021030c010b2005410d6a22062005490d0120044101742203200620062003491b22074100480d010240024020040d002007103221030c010b200228020020042007103421030b2003450d032002200736020420022003360200200721040b2002200636020841002107200320056a220541002900a1db42370000200541056a41002900a6db42370000200241206a2003200610830320022802282206417f4c0d03200228022021050240024020060d00410121080c010b20062107200610322208450d050b200820052006109b05210902402004450d00200310290b02402002280224450d00200510290b2001410c6a28020041046a2204417f4c0d03024002402004450d00200410322203450d0720024100360228200220043602240c010b200241003602282002200436022420024101360220410110322203450d07200241013602240b2002200336022020024101360228200320012d00003a00000240200228022422044101470d0041000d014102410241024102491b22044100480d0120034101200410342203450d0820022004360224200220033602200b20024102360228200320012d00013a00010240024020044102460d00200421050c010b200441016a22052004490d012004410174220a20052005200a491b22054100480d010240024020040d002005103221030c010b200320042005103421030b2003450d0920022005360224200220033602200b20024103360228200341026a20012d00023a0000024020054103470d00200541016a22042005490d012005410174220a20042004200a491b22044100480d010240024020050d002004103221030c010b200320052004103421030b2003450d0a20022004360224200220033602200b20024104360228200341036a20012d00033a00002001280204210a200128020c2201200241206a10660240024020022802242205200228022822046b2001490d00200228022021030c010b200420016a22032004490d012005410174220b20032003200b491b220b4100480d010240024020050d00200b103221030c010b20022802202005200b103421030b2003450d0b2002200b36022420022003360220200b21050b200320046a200a2001109b051a200241206a41186a220a4200370300200241206a41106a220b4200370300200241206a41086a220c4200370300200242003703202003200420016a200241206a1000200241186a200a290300370300200241106a200b290300370300200241086a200c290300370300200220022903203703000240200720066b4120490d00200641206a21040c0c0b200641206a22042006490d0020074101742201200420042001491b22014100480d000240024020070d002001103221080c010b200920072001103421080b02402008450d00200121070c0c0b20014101102e000b1033000b41104101102e000b20074101102e000b102f000b20064101102e000b20044101102e000b41014101102e000b20044101102e000b20054101102e000b20044101102e000b200b4101102e000b200820066a22012002290300370000200141186a200241186a290300370000200141106a200241106a290300370000200141086a200241086a29030037000002402005450d00200310290b200020043602082000200736020420002008360200200241c0006a24000b880201067f230041c0006b220124000240411310322202450d002002410029009884433700002002410f6a41002800a78443360000200241086a41002900a0844337000020014293808080b002370224200120023602202000200141206a108101200128022421002001280228210320012802202102200141206a41186a22044200370300200141206a41106a22054200370300200141206a41086a220642003703002001420037032020022003200141206a1000200141186a2004290300370300200141106a2005290300370300200141086a20062903003703002001200129032037030020014120100402402000450d00200210290b200141c0006a24000f0b41134101102e000b910302047f037e230041306b2205240002400240411410322206450d00200641002900d8d540370000200641106a41002800e8d540360000200641086a41002900e0d54037000020054294808080c002370224200520063602202001200541206a10810120052802242106200541086a20052802202207200528022810a101200541086a41106a2903004200200528020822081b21092005290310420020081b210a02402006450d00200710290b410121060240200a20027d220b200a56200920037d200a200254ad7d220a200956200a2009511b4101470d002000418bd5c000360204200041086a411d3602000c020b024002400240200b428080e983b1de16544100200a501b0d00200520012004200b200a10ae0120052802002206450d022005280204210120002006360204200041086a20013602000c010b200041a8d5c000360204200041086a411a3602000b410121060c020b2001200b200a10a501200041106a2003370300200041086a2002370300410021060c010b41144101102e000b20002006360200200541306a24000b8d0303027f017e037f230041c0006b22052400024002400240200241ff0171417e6a220641024b0d000240024020060e03000201000b200541106a200110af012005290310200358200541186a290300220720045820072004511b0d010c020b200541206a200110af012005290320200356200541286a290300220720045620072004511b0d010b200541306a200110b0010240200528023822010d0002402005280234450d00200528023010290b410021010c020b200541086a41d983c300410d105d200528020c410020052802081b210820014105742106200528023421092005280230220a2101024002400240034002402008200141106a2802004f0d002001290300200358200141086a290300220720045820072004511b0d002001411c6a2d000020027141ff0171200241ff0171460d020b200141206a2101200641606a22060d000b4100210120090d010c020b41b8d4c00021012009450d010b200a10290b413121060c010b4192d4c0002101412621060b2000200636020420002001360200200541c0006a24000bd70602087f087e23004190016b220224000240024002400240411010322203450d004100210420034100290094d840370000200341086a410029009cd840370000200242908080808002370274200220033602702001200241f0006a108101200228027421052002280278210320022802702106200241f0006a41186a22074200370300200241f0006a41106a22084200370300200241f0006a41086a220942003703002002420037037020062003200241f0006a1000200241d0006a41186a2007290300370300200241d0006a41106a2008290300370300200241d0006a41086a20092903003703002002200229037037035020024100360270200241d0006a4120200241f0006a1006210320022802702207417f460d022003450d0220074110490d0120074170714110460d012007417c714120460d01200341086a290000210a2003290000210b200341186a290000210c2003290010210d2003280020210720031029410121040c030b41104101102e000b41f7cdc3004133200241f0006a41ecd6c3001054000b0b02402005450d00200610290b4200210e4200210f024002402004450d00411410322203450d01200341002900d8d540370000200341106a41002800e8d540360000200341086a41002900e0d54037000020024294808080c002370274200220033602702001200241f0006a10810120022802742106200241386a20022802702201200228027810a101200241386a41106a290300210e42002110200228023821032002290340211102402006450d00200110290b200e420020031b210f2011420020031b2111200241306a41d983c300410d105d200241106a200c420041002002280234410020022802301b220320076b2206200620034b1bad220e420010a005200241206a200e4200200d420010a005200242004200200d420010a0054200210e02402002290308200229031884420052200241206a41086a290300220c200229030020022903107c7c220d200c54720d00200a200d20022903202210200b54200d200a54200d200a511b22031b200d7d200b201020031b220d201054ad7d210e200d20107d21100b200e200f2011201056200f200e56200f200e511b22031b210f2010201120031b210e0b2000200e3703002000200f37030820024190016a24000f0b41144101102e000ba807030d7f037e037f230041e0006b22022400024002400240024002400240410e10322203450d0020034100290084d640370000200341066a410029008ad6403700002002428e808080e00137022c200220033602282001200241286a108101200228022c21042002280230210320022802282105200241286a41186a22014200370300200241286a41106a22064200370300200241286a41086a220742003703002002420037032820052003200241286a1000200241086a41186a2001290300370300200241086a41106a2006290300370300200241086a41086a20072903003703002002200229032837030820024100360228200241086a4120200241286a100621080240024020022802282209417f460d002002200936024c200220083602482002200241c8006a102c20022802000d07200228024c22034160712201417f4c0d032002280204210a024002402003410576220b0d004108210c0c010b20011032220c450d050b0240200a450d004100210d4100210e410021070340200241286a200241c8006a10b1010240024020022d00284101460d00200228024c22014110490d002002290029210f20022002280248220341106a3602482002200141706a220636024c20064104490d00200341086a29000021102003290000211120022001416c6a220636024c2002200341146a36024820060d010b200b450d0a200c10290c0a0b200741016a210620032800102112200241d6006a41026a200241dd006a41026a2d000022133a0000200241d2006a41026a221420133a000020022001416b6a36024c2002200341156a360248200220022f005d22013b0156200220013b015220032d0014210102402007200b470d00200d20062006200d491b220b41ffffff3f71200b470d09200b41057422034100480d090240024020070d0020031032210c0c010b200c200e20031034210c0b200c450d080b200c200e6a2203411c6a20013a00002003201037030820032011370300200341146a200f370200200341106a20123602002003411d6a20022f01523b00002003411f6a20142d00003a0000200d41026a210d200e41206a210e20062107200a2006470d000b0b200c450d07200aad422086200bad84210f02402009450d00200810290b2000200f3702042000200c3602000c010b20004100360208200042083702000b02402004450d00200510290b200241e0006a24000f0b410e4101102e000b102f000b20014108102e000b20034108102e000b1033000b41f7cdc3004133200241286a41ecd6c3001054000bf00204027f017e017f077e0240024020012802042202450d0020012802002203310000210420012002417f6a22053602042001200341016a3602002005450d012003310001210620012002417e6a22053602042001200341026a3602002005450d012003310002210720012002417d6a22053602042001200341036a3602002005450d012003310003210820012002417c6a22053602042001200341046a3602002005450d012003310004210920012002417b6a22053602042001200341056a3602002005450d012003310005210a20012002417a6a22053602042001200341066a3602002005450d012003310006210b2001200241796a22053602042001200341076a3602002005450d01200041003a00002003310007210c2001200241786a3602042001200341086a3602002000200c423886200b42308684200a422886842009422086842008421886842007421086842006420886842004843700010f0b200041013a00000f0b200041013a00000b930e06017f037e017f017e017f067e230041f0016b220724004200210842002109024020050d00200741a0016a2006ad42004280c8afa025420010a005200741a8016a29030020072903a001220a4280a094a58d1d7c2208200a54ad7c21090b200741d0016a41086a22054200370300200742003703d00141f8f6c500411b200741d0016a1003200741b0016a41086a220b2005290300370300200720072903d0013703b00120074190016a200741b0016a10b3012007280290012105200729039801210a2007418094ebdc033602b4012007200a420020051b220a200a423f87220c7c200c85220c200c428094ebdc037f220c4280ec94a37c7e7ca722053602b00120074180016a417f2004418094ebdc032004418094ebdc03491b2204417f417f2004ad200ca7417f200c428080808010541bad7e220ca7200c422088a71b2206200741b0016a2005418094ebdc034b4102746a28020022052004418094ebdc036e220d6c2005ad2004200d4180ec94a37c6c6aad7e428094ebdc0380a76a6a220520052006491b22056a220620062004491b4100200420056b2205200520044b1b200a4200551bad420042e807420010a00541012104200741b0016a2003427f20082007290380017c220a20017c220c200c200a542205200920074180016a41086a2903007c200a200854ad7c220820027c2005ad7c220a200854200a2008511b22051b220e427f200a20051b220f410110ad010240024020072802b0014101470d00200041003a00010c010b200741b0016a41106a290300210a200741386a200b290300220242004204420010a005200741286a420042002002420010a005200741c8006a2007290338200741386a41086a2903002208200a42028620072903287c7c220c4205420010a10520072903302109200741c8006a41086a290300210120072903482110200741b0016a10b401200741f0006a200741b0016a42b3e6cc99b3e6cc99332010200a200a42ffffffffffffffff3f8352200942005272200c2008547222041b22082002200820025442b3e6cc99b3e6cc9933200120041b220c200a54200c200a511b22041b2208200c200a20041b220c10a001200741f0006a41086a290300211020072903702109200741d8006a41c2d5c000411610a301200820097d200920087d20092008582010200c582010200c5122041b22051b2111200c20107d2008200954ad7d2010200c7d2009200854ad7d20051b2112200a200c7d2002200854ad7d2101200220087d210a200741d8006a41106a2903004200200728025822051b21022007290360420020051b21130240024020092008562010200c5620041b0d00200741e0016a41086a22044200370300200742003703e00141c2d5c0004116200741e0016a1003200741d0016a41086a2004290300370300200720072903e0013703d00120074200200220127d2013201154ad7d2208201320117d220c201356200820025620082002511b22041b3703e80120074200200c20041b3703e001200741e0016a21040c010b200741e0016a41086a22044200370300200742003703e00141c2d5c0004116200741e0016a1003200741d0016a41086a2004290300370300200720072903e0013703d0012007427f200220127c201320117c220c2013542204ad7c22082004200820025420082002511b22041b3703e8012007427f200c20041b3703e001200741e0016a21040b200741d0016a4110200441101005200741b0016a10b501200741186a200741b0016a200a200110a001200741186a41086a290300210c20072903182108200741c2d5c000411610a301200a20087d2008200a7d2008200a58200c200158200c20015122041b22051b21102001200c7d200a200854ad7d200c20017d2008200a54ad7d20051b2113200741106a2903004200200728020022051b21092007290308420020051b2102024002402008200a56200c20015620041b0d00200741e0016a41086a22044200370300200742003703e00141c2d5c0004116200741e0016a1003200741d0016a41086a2004290300370300200720072903e0013703d00120074200200920137d2002201054ad7d2208200220107d220a200256200820095620082009511b22041b3703e80120074200200a20041b3703e001200741e0016a21040c010b200741e0016a41086a22044200370300200742003703e00141c2d5c0004116200741e0016a1003200741d0016a41086a2004290300370300200720072903e0013703d0012007427f200920137c200220107c220a2002542204ad7c22082004200820095420082009511b22041b3703e8012007427f200a20041b3703e001200741e0016a21040b200741d0016a4110200441101005200041306a41013a0000200041286a4200370300200041206a4280808080c000370300200041186a4204370300200041106a427f370300200041086a200e427f200f501b370300410021040b200020043a0000200741f0016a24000b820102027f027e230041106b220224002002410036020420014110200241046a100621010240024020022802042203417f460d002001450d00024020034108490d002001290000210420011029420121050c020b41f7cdc3004133200241086a41ecd6c3001054000b420021050b2000200437030820002005370300200241106a24000bbf0401077f230041f0006b22012400024002400240024002400240410110322202450d00200241ed003a000020024101410210342202450d01200241ef003a000120024102410410342202450d02200241e4d8013b000220024104410810342202450d03200241f0f2bda10736000420024108411010342203450d04200341f2e6c9cb07360008200141003a0048410c210220032104410021050340200141003a0050200141d0006a200420024100472206109b051a024020020d00200141003a00500b20022006490d06200141286a20056a20012d00503a00002001200541016a22073a0048200420066a2104200220066b21022007210520074120470d000b200141d0006a41186a2202200141286a41186a290300370300200141d0006a41106a2206200141286a41106a290300370300200141d0006a41086a2204200141286a41086a2903003703002001200129032837035002400240200741ff017141204f0d0020031029200041186a4200370000200041106a4200370000200041086a4200370000200042003700000c010b200141086a41186a22052002290300370300200141086a41106a22022006290300370300200141086a41086a220620042903003703002001200129035037030820031029200041186a2005290300370000200041106a2002290300370000200041086a2006290300370000200020012903083700000b200141f0006a24000f0b41014101102e000b41024101102e000b41044101102e000b41084101102e000b41104101102e000b200620021030000bed0b03047f017e057f230041c0016b22012400200141306a41086a220242003703002001420037033041aedbc2004111200141306a1003200141206a41086a200229030037030020012001290330370320200141c0006a200141206a411010590240024020012d00404101470d0020002001290041370000200041186a200141d9006a290000370000200041106a200141c0006a41116a290000370000200041086a200141c9006a2900003700000c010b200242003703002001420037033041fb83c300410d200141306a1003200141c0006a41086a20022903003703002001200129033037034020014100360200200141c0006a411020011006210202400240024020012802002203417f460d002002450d0020012003360234200120023602302001200141306a103d20012802002204450d02200129020421052003450d01200210290c010b41042104420021050b20042005422088a7220641246c6a210720042102024002400240034002400240200720026b41ed00490d0003400240200222032d00004101470d00200341246a2108200341106a2109200341086a210a200341016a21020c030b0240200341246a2d00004101470d00200341c8006a2108200341346a21092003412c6a210a200341256a21020c030b0240200341c8006a2d00004101470d00200341ec006a2108200341d8006a2109200341d0006a210a200341c9006a21020c030b0240200341ec006a2d00004101470d0020034190016a2108200341fc006a2109200341f4006a210a200341ed006a21020c030b200720034190016a22026b41ec004b0d000b20034190016a21020b20022007460d020240034020022d00004101460d012007200241246a2202460d040c000b0b200241246a2108200241106a2109200241086a210a200241016a21020b20022800002102200a280200210320012009280200360204200120033602000240200241c28289aa04460d00200821020c010b0b200141c0006a200110c30120012d004022024102460d00200141a4016a28020021092001280244210a200141306a41086a220342003703002001420037033041bfdbc2004112200141306a1003200141206a41086a20032903003703002001200129033037032020014100360240200141206a4110200141c0006a1006210720012802402203417f460d002001200336020420012007360200200141c0006a2001103120012802402208450d02200a200920024101711b2102200141c8006a28020021092001280244210a02402003450d00200710290b0240200920024d0d00200141186a2203200820024105746a220241186a290000370300200141106a2207200241106a290000370300200141086a2209200241086a290000370300200120022900003703000240200a450d00200810290b200141c0006a41186a22022003290300370300200141c0006a41106a22032007290300370300200141c0006a41086a2207200929030037030020012001290300370340200141306a41086a220942003703002001420037033041aedbc2004111200141306a1003200141206a41086a200929030037030020012001290330370320200141103602342001200141206a360230200141c0006a200141306a108901200041186a2002290300370000200041106a2003290300370000200041086a2007290300370000200020012903403700000c020b200a450d00200810290b20004200370000200041186a4200370000200041106a4200370000200041086a42003700000b02402006450d00200641246c21032004210203400240024020022d0000220741034b0d0002400240024020070e0404000102040b2002410c6a280200450d03200241086a28020010290c030b2002410c6a280200450d02200241086a28020010290c020b2002410c6a280200450d01200241086a28020010290c010b200241086a280200450d00200241046a28020010290b200241246a21022003415c6a22030d000b0b2005a7450d02200410290c020b41f7cdc3004133200141b8016a41ecd6c3001054000b41f7cdc3004133200141b8016a41ecd6c3001054000b200141c0016a24000bc90302087f027e230041306b22032400200128020022042001280208220541246c22016a210620042107024002400240200141ed00490d002002280204210720022802002108200421010340200341186a200122092008200710b7010240200328021822014105460d00200341186a21070c030b200341186a200941246a220a2008200710b7010240200328021822014105460d00200341186a21070c030b200341186a200a41246a220a2008200710b7010240200328021822014105460d00200341186a21070c030b200341186a200a41246a220a2008200710b7010240200328021822014105460d00200341186a21070c030b2006200a41246a22016b41ec004b0d000b20094190016a21070b024020072006460d002004200541246c6a210a20022802042108200228020021090340200341186a20072009200810b7010240200328021822014105460d00200341186a21070c030b200a200741246a2207470d000b0b200041053602000c010b200341106a200741146a2802002208360200200341086a2007410c6a290200220b37030020032007290204220c370300200020013602002000200c3702042000410c6a200b370200200041146a20083602000b200341306a24000b840702047f017e230041206b22042400024002400240024002400240024002400240024002400240024020012d00000e050001020304000b200141016a21014100210520020e0406040507060b200141086a210641012105200141016a210120020e0405030406050b200141086a2106200141016a21014102210520020e0404020305040b200141086a2106200141016a21014103210520020e0403010204030b41042105200141046a210120020e0402000103020b20054102470d0520012003470d03200621010c040b20054103470d04024020012003470d00200621010c040b200128000021022006210120022003280000470d040c030b20054101470d03024020012003470d00200621010c030b200128000021022006210120022003280000470d030c020b20054104460d010c020b200128000021022006210120022003280000470d010b2001280200210220042001280208220136020c200420023602084105210502402001450d0020022d0000210320042001417f6a220636020c2004200241016a3602082003417f6a220341044b0d00024002400240024002400240024020030e050001020304000b200441106a200441086a104020042802102203450d06200428020c22074104490d05200441186a28020021022004280214210120042802082205280000210620042007417c6a36020c2004200541046a360208410021050c040b20064104490d052002280001210320042001417b6a36020c410521052004200241056a360208200441106a200441086a104020042802102201450d05200429021421080240200428020c220241044f0d00410521052008a7450d06200110290c060b20042802082205280000210720042002417c6a36020c2004200541046a3602082008422088a721062008a72102410121050c030b20064108490d04200229000121082004200141776a36020c2004200241096a3602082008422088a721022008a72101410221050c020b20064104490d032002280001210320042001417b6a36020c2004200241056a36020841032105410021060c010b20064104490d022002280001210320042001417b6a36020c2004200241056a36020841002106410421050b20002003360204200041146a2007360200200041086a20013602002000410c6a2006ad4220862002ad843702000c010b2004290214a7450d00200310290b200020053602000c010b200041053602000b200441206a24000bd30201087f230041206b220324002003410036020820034201370300200120031066024002400240024020010d002003280208210420032802042105200328020021060c010b200141246c210720032802042105200328020821010340200341106a2000109d012003280210210802400240200520016b20032802182209490d00200120096a2104200328020021060c010b200120096a22042001490d0420054101742206200420042006491b220a4100480d040240024020050d00200a103221060c010b20032802002005200a103421060b2006450d032003200a36020420032006360200200a21050b20032004360208200620016a20082009109b051a02402003280214450d00200810290b200041246a2100200421012007415c6a22070d000b0b2002280200200228020420062004100502402005450d00200610290b200341206a24000f0b200a4101102e000b1033000b130020004103360204200041a4d8c0003602000b3400200041c8d7c20036020420004100360200200041146a4105360200200041106a41bce9c000360200200041086a42083702000b3701017f02404110103222020d0041104101102e000b2002420037000820024200370000200042908080808002370204200020023602000bdd0802077f027e230041e0016b22032400024002400240411810322204450d00200441002900ecd540370000200441106a41002900fcd540370000200441086a41002900f4d540370000200342988080808003370254200320043602502000200341d0006a108101200328025421052003280258210620032802502104200341d0006a41186a22074200370300200341d0006a41106a22084200370300200341d0006a41086a220942003703002003420037035020042006200341d0006a1000200341c0016a41186a2007290300370300200341c0016a41106a2008290300370300200341c0016a41086a2009290300370300200320032903503703c0012003200237035820032001370350200341c0016a4120200341d0006a4110100502402005450d00200410290b0240200142ffffe883b1de165620024200522002501b0d00411810322204450d02200441002900ecd540370000200441106a41002900fcd540370000200441086a41002900f4d540370000200342988080808003370254200320043602502000200341d0006a108101200328025421052003280258210620032802502104200341d0006a41186a22074200370300200341d0006a41106a22084200370300200341d0006a41086a220942003703002003420037035020042006200341d0006a1000200341c0016a41186a2007290300370300200341c0016a41106a2008290300370300200341c0016a41086a2009290300370300200320032903503703c001200341386a200341c0016a10a601200341386a41106a2903002101200329034021022003280238210602402005450d00200410290b02402002200184500d002006450d00200341206a41c2d5c000411610a301200341206a41106a290300210a2003290328210b20032802202104200341d0006a41086a220542003703002003420037035041c2d5c0004116200341d0006a1003200341c0016a41086a2005290300370300200320032903503703c00120034200200a420020041b220a20017d200b420020041b2201200254ad7d220b200120027d2202200156200b200a56200b200a511b22041b37035820034200200220041b370350200341c0016a4110200341d0006a411010050b411410322204450d03200441002900d8d540370000200441106a41002800e8d540360000200441086a41002900e0d54037000020034294808080c002370254200320043602502000200341d0006a10810120032802542104200341086a20032802502206200328025810a101200341086a41106a2903002102200329031021012003280208210502402004450d00200610290b02402001200284500d0020050d010b200010ac01200341d0006a41086a41013a0000200341d9006a2000290000370000200341e1006a200041086a290000370000200341e9006a200041106a290000370000200341f1006a200041186a290000370000200341023a005041014100200341d0006a104c0b200341e0016a24000f0b41184101102e000b41184101102e000b41144101102e000b130020004105360204200041d8fac0003602000bc90102037f027e230041306b220224000240411410322203450d00200341002900d8d540370000200341106a41002800e8d540360000200341086a41002900e0d54037000020024294808080c002370224200220033602202001200241206a10810120022802242103200241086a20022802202204200228022810a101200241086a41106a2903004200200228020822011b21052002290310420020011b210602402003450d00200410290b2000200637030020002005370308200241306a24000f0b41144101102e000bb10202057f037e230041c0006b22042400200441206a2001105b0240024002402004290320200441206a41086a29030084500d00411410322205450d0241002106200541002900d8d540370000200541106a41002800e8d540360000200541086a41002900e0d54037000020044294808080c002370234200420053602302001200441306a10810120042802342105200441086a20042802302207200428023810a101200441086a41106a2903004200200428020822081b21092004290310420020081b210a02402005450d00200710290b2001200a20027c220b200920037c200b200a54ad7c10a501200041106a2003370300200041086a20023703000c010b200041e9d4c000360204200041086a4122360200410121060b20002006360200200441c0006a24000f0b41144101102e000bb80404037f017e017f057e230041c0006b2204240002400240411410322205450d00200541002900d8d540370000200541106a41002800e8d540360000200541086a41002900e0d54037000020044294808080c002370234200420053602302001200441306a10810120042802342105200441186a20042802302206200428023810a10142002107200441186a41106a2903004200200428021822081b21092004290320420020081b210a02402005450d00200610290b2001200a2002200a200a200256200920035620092003511b22051b220b7d20092003200920051b220c7d200a200b54ad7d10a501024002402002200b7d220a2003200c7d2002200b54ad7d220d8450450d004200210d0c010b411810322205450d02200541002900ecd540370000200541106a41002900fcd540370000200541086a41002900f4d540370000200442988080808003370234200420053602302001200441306a10810120042802342105200420042802302206200428023810a101200441106a2903004200200428020022081b21022004290308420020081b210302402005450d00200610290b20012003200a20032003200a562002200d562002200d511b22051b22097d2002200d200220051b22077d2003200954ad7d10bc01200d20077d200a200954ad7d210d2007200c7c2009200b7c2202200954ad7c2103200a20097d21070b2000200737031020002002370300200041186a200d37030020002003370308200441c0006a24000f0b41144101102e000b41184101102e000bce1003097f027e027f230041c0006b220224000240024002400240024002400240024002400240024002400240410e10322203450d0020034100290084d640370000200341066a410029008ad6403700002002428e808080e001370224200220033602202000200241206a108101200228022421042002280228210320022802202105200241206a41186a22004200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020052003200241206a1000200241186a2000290300370300200241106a2006290300370300200241086a200729030037030020022002290320370300200128020021082001280208210320024100360228200242013703202003200241206a106602402003450d00200341057421094100210a034002400240200228022420022802282203460d00200228022021000c010b200341016a22002003490d0f20034101742206200020002006491b22064100480d0f0240024020030d002006103221000c010b200228022020032006103421000b2000450d042002200636022420022000360220200228022821030b2002200341016a360228200020036a2008200a6a220341146a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007103221060c010b200228022020002007103421060b2006450d052002200736022420022006360220200228022821000b2002200041016a360228200620006a200341156a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007103221060c010b200228022020002007103421060b2006450d062002200736022420022006360220200228022821000b2002200041016a360228200620006a200341166a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007103221060c010b200228022020002007103421060b2006450d072002200736022420022006360220200228022821000b2002200041016a360228200620006a200341176a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007103221060c010b200228022020002007103421060b2006450d082002200736022420022006360220200228022821000b2002200041016a360228200620006a200341186a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007103221060c010b200228022020002007103421060b2006450d092002200736022420022006360220200228022821000b2002200041016a360228200620006a200341196a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007103221060c010b200228022020002007103421060b2006450d0a2002200736022420022006360220200228022821000b2002200041016a360228200620006a2003411a6a2d00003a000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007103221060c010b200228022020002007103421060b2006450d0b2002200736022420022006360220200228022821000b2002200041016a360228200620006a2003411b6a2d00003a0000200341086a290300210b2003290300210c0240024020022802242207200228022822066b4110490d00200228022021000c010b200641106a22002006490d0f20074101742206200020002006491b220d4100480d0f0240024020070d00200d103221000c010b20022802202007200d103421000b2000450d0c2002200d3602242002200036022020022802282106200d21070b200020066a220d200b370008200d200c3700002002200641106a2206360228200341106a280200210d0240200720066b41034b0d00200641046a220e2006490d0f20074101742206200e200e2006491b22064100480d0f0240024020070d002006103221000c010b200020072006103421000b2000450d0d2002200636022420022000360220200228022821060b2002200641046a360228200020066a200d36000002400240200228022420022802282200460d00200228022021060c010b200041016a22062000490d0f20004101742207200620062007491b22074100480d0f0240024020000d002007103221060c010b200228022020002007103421060b2006450d0e2002200736022420022006360220200228022821000b2002200041016a360228200620006a2003411c6a2d00003a00002009200a41206a220a470d000b0b2002280224210320024120200228022022002002280228100502402003450d00200010290b02402004450d00200510290b0240200141046a280200450d00200810290b200241c0006a24000f0b410e4101102e000b20064101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b200d4101102e000b20064101102e000b20074101102e000b1033000bfd0102047f027e230041306b220424000240411810322205450d00200541002900ecd540370000200541106a41002900fcd540370000200541086a41002900f4d540370000200442988080808003370224200420053602202001200441206a10810120042802242105200441086a20042802202206200428022810a101200441086a41106a2903004200200428020822071b21082004290310420020071b210902402005450d00200610290b20012009200220092009200256200820035620082003511b22051b22027d20082003200820051b22037d2009200254ad7d10bc012000200337030820002002370300200441306a24000f0b41184101102e000bb30a03067f017e067f230041f0016b2202240002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200200541014b0d0420050e020102010b200041023a00000c070b20064104490d012004280001210720012003417b6a22053602042001200441056a36020020054108490d05200429000521082001200341736a220536020420012004410d6a36020020054104490d04200428000d210920012003416f6a3602042001200441116a36020041002105200241003a00b001411120036b210a2003416e6a210603400240200a20056a0d000240200541ff0171450d00200241003a00b0010b200041023a00000c080b20024190016a20056a200420056a220b41116a2d00003a0000200120063602042001200b41126a3602002002200541016a220b3a00b0012006417f6a2106200b2105200b4120470d000b200241f0006a41186a20024190016a41186a290300370300200241f0006a41106a20024190016a41106a290300370300200241f0006a41086a20024190016a41086a290300370300200220022903900137037041002105200241003a00d0012004200b6a210a200b20036b41116a210303400240200320056a0d000240200541ff0171450d00200241003a00d0010b200041023a00000c080b20024190016a20056a200a20056a220441116a2d00003a0000200120063602042001200441126a3602002002200541016a22043a00d0012006417f6a210620042105200441c000470d000b200241106a41386a220120024190016a41386a290300370300200241106a41306a220420024190016a41306a290300370300200241106a41286a220520024190016a41286a290300370300200241106a41206a220320024190016a41206a290300370300200241106a41186a220620024190016a41186a290300370300200241106a41106a220b20024190016a41106a290300370300200241106a41086a220a20024190016a41086a290300370300200241d0006a41086a220c200241f0006a41086a290300370300200241d0006a41106a220d200241f0006a41106a290300370300200241d0006a41186a220e200241f0006a41186a290300370300200220022903900137031020022002290370370350200041003a000020002002290350370001200041096a200c290300370000200041116a200d290300370000200041196a200e290300370000200041216a2002290310370000200041296a200a290300370000200041316a200b290300370000200041396a2006290300370000200041c1006a2003290300370000200041c9006a2005290300370000200041d1006a2004290300370000200041d9006a2001290300370000200041e3006a2002410f6a2d00003a0000200041e1006a20022f000d3b0000200041f0006a2008370300200041e8006a2009360200200041e4006a20073602000c060b20064104490d022004280001210620012003417b6a22053602042001200441056a36020020054108490d02200429000521082001200341736a220536020420012004410d6a36020020054104490d02200428000d210520012003416f6a3602042001200441116a360200200041013a0000200020022f00103b0001200041106a2008370300200041086a2005360200200041046a2006360200200041036a200241126a2d00003a0000200041186a20024190016a41e000109b051a0c050b200041023a00000c040b200041023a00000c030b200041023a00000c020b200041023a00000c010b200041023a00000b200241f0016a24000be60b07037f017e017f027e017f047e027f230041e0016b220524000240024002400240411410322206450d00200641002900d8d540370000200641106a41002800e8d540360000200641086a41002900e0d54037000020054294808080c002370254200520063602502001200541d0006a10810120052802542106200541386a20052802502207200528025810a101200541386a41106a2903002108200528023821092005290340210a02402006450d00200710290b411410322206450d01200641002900d8d540370000200641106a41002800e8d540360000200641086a41002900e0d54037000020054294808080c002370254200520063602502002200541d0006a10810120052802542106200541206a20052802502207200528025810a101200541206a41106a290300210b2005280220210c2005290328210d02402006450d00200710290b024020034280a094a58d1d7c220e200354220620042006ad7c220f200454200e20035a1b450d0041f4fec0002106412821010c040b0240200a420020091b220a200e7d2210200a562008420020091b2208200f7d200a200e54ad7d220e200856200e2008511b4101470d0041ca8ac1002106411d21010c040b200b4200200c1b2108200d4200200c1b210a0240200342ffffe883b1de165620044200522004501b0d00200a20088450450d0041e78ac1002106411f21010c040b200541186a200141022010200e10ae01024020052802182206450d00200528021c21010c040b0240200a20037c220f200a542206200820047c2006ad7c220a200854200a2008511b450d0041868bc1002106412d21010c040b41002106024020012002470d000c040b0240200120024120109d050d000c040b20012010200e10a501411410322206450d02200641002900d8d540370000200641106a41002800e8d540360000200641086a41002900e0d54037000020054294808080c002370254200520063602502002200541d0006a108101200528025421092005280258210720052802502106200541d0006a41186a220c4200370300200541d0006a41106a22114200370300200541d0006a41086a221242003703002005420037035020062007200541d0006a1000200541c0016a41186a200c290300370300200541c0016a41106a2011290300370300200541c0016a41086a2012290300370300200520052903503703c001200541c0016a41204101410041001007210702402009450d00200610290b02402007417f470d00200210a40120054188016a200a37030020054180016a200f370300200541d0006a41086a41003a0000200541d9006a2002290000370000200541e1006a200241086a290000370000200541e9006a200241106a290000370000200541f1006a200241186a290000370000200541023a005041014100200541d0006a104c0b2002200f200a10a501200541c2d5c000411610a301200541106a290300210e2005290308210820052802002106200541d0006a41086a220942003703002005420037035041c2d5c0004116200541d0006a1003200541c0016a41086a2009290300370300200520052903503703c00120054200200e420020061b220a2008420020061b220e4280a094a58d1d54ad7d2208200e4280e0ebdaf2627c220f200e562008200a56200e42ff9f94a58d1d561b22061b37035820054200200f20061b370350200541c0016a4110200541d0006a41101005200541b8016a4200370300200541b0016a4280a094a58d1d370300200541a8016a2004370300200541a0016a2003370300200941023a0000200541d9006a2001290000370000200541e1006a200141086a290000370000200541e9006a200141106a290000370000200541f1006a200141186a290000370000200541f9006a200229000037000020054181016a200241086a29000037000020054189016a200241106a29000037000020054191016a200241186a290000370000200541023a00504100210641014100200541d0006a104c0c030b41144101102e000b41144101102e000b41144101102e000b2000200136020420002006360200200541e0016a24000bd90303027f017e027f02402001450d00034020002802e40121002001417f6a22010d000b0b02402002450d004100210341002101034002400240200120002f01064f0d0020002001410c6c6a220441e4006a2902002105200441e0006a2802002104200141016a21010c010b02400240200028020022010d002003ad210541002106410021010c010b20003301044220862003ad842105410121060b200010292005a72103024002402005422088a7220720012f01064f0d00200121040c010b034002400240200128020022040d002003ad2105410021040c010b200641016a210620013301044220862003ad8421050b200110292005a72103200421012005422088a7220720042f01064f0d000b0b200741027420046a41e8016a280200210020042007410c6c6a220141e4006a2902002105200141e0006a280200210402402006417f6a2201450d00034020002802e40121002001417f6a22010d000b0b410021010b2004450d012002417f6a210202402005a7450d00200410290b20020d000b0b0240200041b0d6c000460d0020002802002101200010292001450d0020012802002104200110292004450d00024020042802002201450d000340200410292001210420012802002200210120000d000b0b200410290b0bf90503087f017e017f23004180026b2202240002400240024020012802202203450d0020012003417f6a36022020012802082104200128020c2203200128020422052f01064f0d01200241186a2206200520034105746a220741206a290000370300200241106a2208200741186a290000370300200241086a2209200741106a2900003703002002200741086a290000370300200241206a2005200341e0006c6a41e8026a41e000109b051a2001200341016a36020c200120043602082001200536020420024180016a41186a200629030037030020024180016a41106a200829030037030020024180016a41086a2009290300370300200220022903003703800120024180016a41206a200241206a41e000109b051a200020024180016a418001109b051a0c020b200042023703200c010b2001280200210702400240200528020022030d002004ad210a410021030c010b200741016a210720053301044220862004ad84210a0b20051029200aa7210402400240200a422088a7220620032f01064f0d00200321050c010b034002400240200328020022050d002004ad210a410021050c010b200741016a210720033301044220862004ad84210a0b20031029200aa7210420052103200a422088a7220620052f01064f0d000b0b200241186a2208200520064105746a220341206a290000370300200241106a2209200341186a290000370300200241086a220b200341106a2900003703002002200341086a290000370300200241206a2005200641e0006c6a41e8026a41e000109b051a200641027420056a418c0b6a280200210302402007417f6a2205450d00034020032802880b21032005417f6a22050d000b0b2001410036020c20012004360208200120033602042001410036020020024180016a41186a200829030037030020024180016a41106a200929030037030020024180016a41086a200b290300370300200220022903003703800120024180016a41206a200241206a41e000109b051a200020024180016a418001109b051a0b20024180026a24000bdd0605057f047e017f017e047f23004190016b2202240002400240024020012802202203450d0020012003417f6a36022020012802082104200128020c2203200128020422052f01064f0d01200241e0006a41186a200520034105746a220641206a2900002207370300200241e0006a41106a200641186a2900002208370300200241e0006a41086a200641106a29000022093703002002200641086a290000220a370360200241306a41086a20052003410c6c6a220641f0026a280200220b360200200641e8026a290200210c2001200341016a36020c20012004360208200120053602042002200c3703302000200a3702042000410c6a2009370200200041146a20083702002000411c6a2007370200200041246a200c3702002000412c6a200b360200200041013602000c020b200041003602000c010b2001280200210602400240200528020022030d002004ad210c410021030c010b200641016a210620053301044220862004ad84210c0b20051029200ca7210402400240200c422088a7220b20032f01064f0d00200321050c010b034002400240200328020022050d002004ad210c410021050c010b200641016a210620033301044220862004ad84210c0b20031029200ca7210420052103200c422088a7220b20052f01064f0d000b0b200241306a41186a220d2005200b4105746a220341206a290000370300200241306a41106a220e200341186a290000370300200241306a41086a220f200341106a2900003703002002200341086a290000370330200241d0006a41086a22102005200b410c6c6a220341f0026a2802003602002002200341e8026a290200370350200b41027420056a41f0036a280200210302402006417f6a2205450d00034020032802ec0321032005417f6a22050d000b0b2001410036020c200120043602082001200336020420014100360200200241e0006a41186a200d290300220c370300200241e0006a41106a200e2903002207370300200241e0006a41086a200f290300220837030020024188016a201028020022033602002000200229033022093702042000410c6a2008370200200041146a20073702002000411c6a200c370200200041246a2002290350220c3702002000412c6a2003360200200220093703602002200c37038001200041013602000b20024190016a24000b8f1901187f230041d0116b2202240020002802102203200328020041016a360200200028020c21042000280208210520002802042103200241206a41186a22062000412c6a290000370300200241206a41106a2207200041246a290000370300200241206a41086a22082000411c6a29000037030020022000290014370320200241a0026a200141e000109b051a024002400240024020032f01062201410b490d00200241b0036a410041e002109a051a20024198066a410041a008109a051a0240024041880b10322209450d00200941003b010620094100360200200941086a200241b0036a41e002109b052101200941e8026a20024198066a41a008109b052106200220032f00c8013b01ac032002200341ca016a2d00003a00ae03200220032900db01370398032002200341e0016a29000037009d03200341cb016a280000210a200341cf016a280000210b200341d3016a280000210c200341d7016a280000210d20024198066a200341a8076a41e000109b051a2001200341e8016a20032f010641796a2200410574109b052101200620034188086a200041e0006c109b052106200341063b0106200920003b0106200220022f01ac033b019403200220022d00ae033a0096032002200229039803370380032002200229009d0337008503200241b0036a20024198066a41e000109b051a0240024020044107490d00200441057420016a41c07e6a2001200441796a22074105746a2201200041ffff037120076b410574109c051a200141186a200241206a41186a290300370000200141106a200241206a41106a290300370000200141086a200241206a41086a29030037000020012002290320370000200441e0006c20066a220041c07b6a200041e07a6a220e200941066a22002f010020076b41e0006c109c051a200e200241a0026a41e000109b051a0c010b200341086a20044105746a220141206a2001200341066a22002f010020046b410574109c051a200141186a200241206a41186a290300370000200141106a200241206a41106a290300370000200141086a200241206a41086a29030037000020012002290320370000200341e8026a200441e0006c6a220e41e0006a200e20002f010020046b41e0006c109c051a200e200241a0026a41e000109b051a0b20024188026a41026a220420022d0096033a0000200020002f010041016a3b0100200220022f0194033b01880220022002290380033703800120022002290085033700850120024190016a200241b0036a41e000109b051a2002411c6a41026a220f20042d00003a0000200220022f0188023b011c2002200229038001370308200220022900850137000d200241206a20024190016a41e000109b051a20032802002206450d0320032f0104211020024198066a410272211103402002419c026a41026a2212200f2d00003a0000200220022f011c3b019c0220022002290308370388022002200229000d37008d02200241a0026a200241206a41e000109b051a201041ffff0371210702400240024020062f01062203410b490d002011410041b20b109a051a41b80b10322201450d0520014100360200200141046a20024198066a41b40b109b051a200220062f00c8013b01ac032002200641ca016a2d00003a00ae03200220062900db01370398032002200641e0016a29000037009d03200641cb016a2800002113200641cf016a2800002114200641d3016a2800002115200641d7016a280000211620024198066a200641a8076a41e000109b051a200141086a200641e8016a20062f0106220041796a2203410574109b052117200141e8026a20064188086a200341e0006c109b052118200141880b6a200641a40b6a2000417a6a2208410274109b052119200641063b0106200120033b010602402008450d00410021032019210003402000280200220420033b010420042001360200200041046a21002008200341016a2203470d000b0b200241b0036a20024198066a41e000109b051a200220022d00ae0322033a009603200220022f01ac0322003b0194032002200229009d033700850320022002290398033703800320024194066a41026a220820033a0000200220003b01940620022002290380033703800120022002290085033700850120024198066a200241b0036a41e000109b051a201041ffff037122004107490d0120172007417a6a22044105746a2017200741796a22034105746a220020012f010620036b410574109c051a200041186a200229008d023700002000200d36000f2000200c36000b2000200b3600072000200a360003200041026a20122d00003a0000200020022f019c023b00002000200229038802370013200741e0006c20186a220041c07b6a200041e07a6a220020012f010620036b41e0006c109c051a2000200241a0026a41e000109b051a200120012f010641016a22003b01062007410274220a20196a416c6a201920044102746a2210200041ffff0371220720046b410274109c051a2010200936020020072004490d022001200a6a41f00a6a2100034020002802002204200341016a22033b010420042001360200200041046a210020032007490d000c030b0b200641086a2200200741016a22044105746a200020074105746a2200200320076b2201410574109c051a2000200d36000f2000200c36000b2000200b3600072000200a360003200041026a2002419c026a41026a2d00003a0000200020022f019c023b00002000200229038802370013200041186a200229008d023700002006200741e0006c6a220041c8036a200041e8026a2200200141e0006c109c051a2000200241a0026a41e000109b051a2006200341016a22033b01062007410274200641880b6a22006a41086a200020044102746a2200200341ffff037120046b410274109c051a20002009360200201041ffff037120062f010622034f0d07200920043b010420092006360200200420034f0d072003417f6a210120062004417f6a22034102746a41900b6a2100034020002802002204200341026a3b010420042006360200200041046a21002001200341016a2203470d000c080b0b200641086a2203200741016a22044105746a200320074105746a220320062f0106221020076b2219410574109c051a2003200d36000f2003200c36000b2003200b3600072003200a360003200341026a20122d00003a0000200320022f019c023b00002003200229038802370013200341186a200229008d02370000200641e8026a200741e0006c6a220341e0006a2003201941e0006c109c051a2003200241a0026a41e000109b051a2006201041016a22033b010620074102742219200641880b6a22106a41086a201020044102746a2210200341ffff037120046b410274109c051a20102009360200200020062f010622044f0d00200620196a418c0b6a2103034020032802002200200741016a22073b010420002006360200200341046a210320042007470d000b0b20024184026a41026a220320082d00003a0000200220022f0194063b01840220022002290380013703f00120022002290085013700f50120024190016a20024198066a41e000109b051a200f20032d00003a0000200220022f0184023b011c200220022903f001370308200220022900f50137000d200241206a20024190016a41e000109b051a0240200628020022030d002013210a2016210d2015210c2014210b200121090c050b20062f010421102013210a2016210d2015210c2014210b20032106200121090c000b0b41880b4108102e000b41b80b4108102e000b200320044105746a220041286a200041086a2210200120046b410574109c051a200041206a2006290300370000200041186a2007290300370000200041106a2008290300370000201020022903203700002003200441e0006c6a220041c8036a200041e8026a220e20032f010620046b41e0006c109c051a200e200241a0026a41e000109b051a200320032f010641016a3b01060c010b20024198066a410272410041b20b109a051a41b80b10322203450d0120034100360200200341046a20024198066a41b40b109b051a2003200528020022003602880b200520033602002005200528020441016a360204200041003b010420002003360200200320032f010622044105746a220041086a20022f011c3b00002000410a6a2002411c6a41026a2d00003a0000200041176a200d360000200041136a200c3600002000410f6a200b3600002000410b6a200a3600002000411b6a2002290308370000200041206a200229000d3700002003200441e0006c6a41e8026a200241206a41e000109b051a200341880b6a200441016a22004102746a2009360200200320003b0106200920003b0104200920033602000b200241d0116a2400200e0f0b41b80b4108102e000bb00101037f230041306b220124002001200010c701024020012802004101470d000340024020012802242202450d002001280228450d00200210290b2001200010c70120012802004101460d000b0b02402000280204220241b0d6c000460d0020022802002103200210292003450d0020032802002100200310292000450d00024020002802002202450d000340200010292002210020022802002203210220030d000b0b200010290b200141306a24000be71207027f017e057f027e017f017e0a7f230041b0036b2202240020002802102203200328020041016a36020020002902142104200028020c2103200028020821052000280200210620002802042100200241f0016a41086a2207200141086a280200360200200220012902003703f001024002400240024020002f01062201410b490d00200241d0026a410272410041da00109a051a200241386a4100418401109a051a0240024041e40110322208450d0020084100360200200841046a200241d0026a41dc00109b051a200841e0006a200241386a418401109b052107200241386a41086a2209200041b0016a280200360200200220002902a8013703382000413c6a330000210a2000413e6a310000210b20002d003f210c2000350038210d200841086a200041c0006a20002f010641796a2201410374109b05210e2007200041b4016a2001410c6c109b052107200041063b0106200820013b0106200241d0026a41086a2009280200360200200220022903383703d002200d200a200b4210868442208684210a0240024020034107490d002003410374200e6a41506a200e200341796a22094103746a220e200141ffff037120096b410374109c051a200e20043700002003410c6c20076a220341b87f6a200341ac7f6a2203200841066a22012f010020096b410c6c109c051a200341086a200241f0016a41086a280200360200200320022903f0013702000c010b200041086a20034103746a220741086a2007200041066a22012f010020036b410374109c051a20072004370000200041e0006a2003410c6c6a2207410c6a200720012f010020036b410c6c109c051a200741086a200241f0016a41086a280200360200200720022903f0013702000b200120012f010041016a3b0100200241286a41086a220f200241d0026a41086a22102802002203360200200241086a221120033602002002200c3a0017200220022903d00222043703282002200a3e02102002200a4230883c00162002200a4220883d011420022004370300200229031021042000280200220c450d0320002f01042112200241d0026a410272211303402002200641016a22063602202002200c360224200f201128020036020020022002290300370328201241ffff03712109024002400240200c2f01062200410b490d002013410041da00109a051a200241f0016a200241d0026a41dc00109b051a200241386a410041b401109a051a41940210322207450d0520074100360200200741046a200241f0016a41dc00109b051a200741e0006a200241386a41b401109b052103200c41386a290000210a200241386a41086a2214200c41b0016a2802003602002002200c41a8016a290200370338200741086a200c41c0006a200c2f0106220141796a2200410374109b0521152003200c41b4016a2000410c6c109b052116200741e4016a200c4180026a2001417a6a220e410274109b052117200c41063b0106200720003b01060240200e450d00410021002017210303402003280200220120003b010420012007360200200341046a2103200e200041016a2200470d000b0b20102014280200220036020020022002290338220b3703d002201420003602002002200b370338201241ffff037122034107490d0120152009417a6a22034103746a2015200941796a22004103746a220120072f010620006b410374109c051a200120043700002009410c6c20166a220141b87f6a200141ac7f6a220120072f0106220e20006b410c6c109c051a200141086a200f280200360200200120022903283702002007200e41016a22013b01062009410274221220176a416c6a201720034102746a220e200141ffff0371220920036b410274109c051a200e200836020020092003490d02200720126a41cc016a2103034020032802002201200041016a22003b010420012007360200200341046a210320002009490d000c030b0b200c41086a2201200941016a22034103746a200120094103746a2201200020096b2207410374109c051a20012004370000200c2009410c6c6a220141ec006a200141e0006a220e2007410c6c109c051a200141e8006a200241286a41086a280200360200200e2002290328370200200c200041016a22003b01062009410274200c41e4016a22016a41086a200120034102746a2201200041ffff0371220720036b410274109c051a20012008360200201241ffff037120074f0d07200c2003417f6a22004102746a41e8016a2103034020032802002201200041016a22003b01042001200c360200200341046a210320002007490d000c080b0b200c41086a2200200941016a220e4103746a200020094103746a2200200c2f0106220120096b2212410374109c051a20002004370000200c41e0006a2009410c6c6a2200410c6a20002012410c6c109c051a200041086a200f28020036020020002002290328370200200c200141016a22003b010620094102742217200c41e4016a22016a41086a2001200e4102746a2212200041ffff03712201200e6b410274109c051a20122008360200200320014f0d00200c20176a41e8016a2100034020002802002203200941016a22093b01042003200c360200200041046a210020012009470d000b0b200241106a41086a2014280200220036020020112000360200200220022903382204370310200220043703000240200c28020022000d0020072108200a21040c050b200c2f010421122000210c200a2104200721080c000b0b41e4014104102e000b4194024104102e000b200020034103746a220941106a200941086a2209200120036b410374109c051a2009200437000020002003410c6c6a220141ec006a200141e0006a220920002f010620036b410c6c109c051a200141e8006a2007280200360200200920022903f001370200200020002f010641016a3b01060c010b200241d0026a410272410041da00109a051a200241f0016a200241d0026a41dc00109b051a200241386a410041b401109a051a41940210322200450d0120004100360200200041046a200241f0016a41dc00109b051a200041e0006a200241386a41b401109b0521012000200528020022033602e401200520003602002005200528020441016a360204200341003b010420032000360200200120002f01062203410c6c6a22012002290300370200200020034103746a41086a2004370000200141086a200241086a280200360200200041e4016a200341016a22034102746a2008360200200020033b0106200820033b0104200820003602000b200241b0036a24000f0b4194024104102e000bc31e03087f037e127f23004180076b22042400200441e0006a41186a200241186a290000370300200441e0006a41106a200241106a290000370300200441e0006a41086a200241086a290000370300200420022900003703600240024002400240024002400240024002402001280200220541b0d6c000460d00200128020421060c010b41002106200441e8026a410041e002109a051a200441c0016a4100418401109a051a41ec0310322205450d01200541003b010620054100360200200541086a200441e8026a41e002109b051a200541e8026a200441c0016a418401109b051a20014100360204200120053602000b02400340200541086a2107200541066a210820052f0106220941057421024100210a0240024003402002450d01200441e0006a20074120109d05220b450d02200241606a2102200a41016a210a200741206a2107200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200520094102746a41ec036a28020021050c010b0b200441e8026a41086a22022005200a410c6c6a220741f0026a220a2802003602002004200741e8026a22072902003703e80220072003290200370200200a200341086a280200360200200441c0016a41086a20022802002202360200200420042903e802220c3703c0012000410c6a20023602002000200c370204200041013602000c060b200441086a41186a220b200441e0006a41186a2202290300370300200441086a41106a200441e0006a41106a2207290300220c370300200441086a41086a200441e0006a41086a220a290300220d37030020042004290360220e3703082001200128020841016a3602082007200c370300200a200d3703002002200b2903003703002004200e370360200441d8026a41086a2206200341086a280200360200200420032902003703d802024020082f01002203410b490d00200441e8026a410041e002109a051a200441c0016a4100418401109a051a41ec031032220f450d02200f41003b0106200f4100360200200f41086a200441e8026a41e002109b052107200f41e8026a200441c0016a418401109b05210a200441e8026a41086a220b200541b8036a280200360200200420052900db013703a8012004200541e0016a2900003700ad01200420052902b0033703e802200420052f00c8013b01bc012004200541ca016a2d00003a00be01200541cb016a2800002110200541cf016a2800002111200541d3016a2800002112200541d7016a28000021132007200541e8016a20052f010641796a2202410574109b052107200a200541bc036a2002410c6c109b05210a200541063b0106200f20023b0106200420042f01bc013b01a401200420042d00be013a00a601200420042903a8013703c001200420042900ad013700c501200441286a41086a200b280200360200200420042903e8023703280240024020094107490d00200941057420076a41c07e6a2007200941796a220b4105746a2207200241ffff0371200b6b410574109c051a200741186a200441e0006a41186a290300370000200741106a200441e0006a41106a290300370000200741086a200441e0006a41086a290300370000200720042903603700002009410c6c200a6a220241b87f6a200241ac7f6a2202200f41066a22082f0100200b6b410c6c109c051a200241086a200441d8026a41086a280200360200200220042903d8023702000c010b200541086a20094105746a220241206a200220082f010020096b410574109c051a200241186a200441e0006a41186a290300370000200241106a200441e0006a41106a290300370000200241086a200441e0006a41086a29030037000020022004290360370000200541e8026a2009410c6c6a2202410c6a200220082f010020096b410c6c109c051a200241086a200441d8026a41086a280200360200200220042903d8023702000b200820082f010041016a3b010020044198016a41026a220220042d00a6013a0000200441c8026a41086a2214200441286a41086a280200360200200420042f01a4013b019801200420042903c001370350200420042900c501370055200420042903283703c8022004413c6a41026a221520022d00003a0000200420042f0198013b013c2004200429005537002d20042004290350370328200441c0006a41086a22162014280200360200200420042903c80237034020052802002206450d0420052f01042103200441e8026a4102722117034020044194016a41026a221820152d00003a0000200420042f013c3b019401200420042903283703602004200429002d37006520044198016a41086a221920162802003602002004200429034037039801200341ffff0371210502400240024020062f01062202410b490d0020174100419604109a051a419c041032220b450d07200b4100360200200b41046a200441e8026a419804109b051a200420062f00c8013b01bc012004200641ca016a2d00003a00be012004200641db016a2900003703a8012004200641e0016a2900003700ad01200641cb016a280000211a200641cf016a280000211b200641d3016a280000211c200641d7016a280000211d200441e8026a41086a221e200641b8036a2802003602002004200641b0036a2902003703e802200b41086a200641e8016a20062f0106220741796a2202410574109b05211f200b41e8026a200641bc036a2002410c6c109b052120200b41ec036a20064188046a2007417a6a2209410274109b052108200641063b0106200b20023b010602402009450d00410021022008210703402007280200220a20023b0104200a200b360200200741046a21072009200241016a2202470d000b0b200441d8026a41086a2202201e280200360200200420042d00be0122073a00a601200420042f01bc01220a3b01a401200420042903a8013703c001200420042900ad013700c501200420042903e8023703d802200441c4026a41026a220920073a00002004200a3b01c402200420042903c0013703e802200420042900c5013700ed0220142002280200360200200420042903d8023703c802200341ffff037122074107490d01201f2005417a6a220a4105746a201f200541796a22024105746a2207200b2f010620026b410574109c051a200741186a20042900653700002007201336000f2007201236000b2007201136000720072010360003200741026a20182d00003a0000200720042f0194013b0000200720042903603700132005410c6c20206a220741b87f6a200741ac7f6a2207200b2f0106220320026b410c6c109c051a200741086a20192802003602002007200429039801370200200b200341016a22073b01062005410274221020086a416c6a2008200a4102746a2203200741ffff03712205200a6b410274109c051a2003200f3602002005200a490d02200b20106a41d4036a210703402007280200220a200241016a22023b0104200a200b360200200741046a210720022005490d000c030b0b200641086a2207200541016a220a4105746a200720054105746a2207200220056b410574109c051a200741186a20042900653700002007201336000f2007201236000b2007201136000720072010360003200741026a20044194016a41026a2d00003a0000200720042f0194013b00002007200429036037001320062005410c6c6a220241f4026a200241e8026a220720062f0106220b20056b410c6c109c051a200241f0026a20044198016a41086a28020036020020072004290398013702002006200b41016a22023b01062005410274200641ec036a22076a41086a2007200a4102746a2207200241ffff0371220b200a6b410274109c051a2007200f360200200341ffff0371200b4f0d082006200a417f6a22024102746a41f0036a210703402007280200220a200241016a22023b0104200a2006360200200741046a21072002200b490d000c090b0b200641086a2202200541016a22034105746a200220054105746a220220062f010620056b410574109c051a200241186a20042900653700002002201336000f2002201236000b2002201136000720022010360003200241026a20182d00003a0000200220042f0194013b000020022004290360370013200641e8026a2005410c6c6a2202410c6a200220062f0106220a20056b410c6c109c051a200241086a201928020036020020022004290398013702002006200a41016a22023b010620054102742210200641ec036a220a6a41086a200a20034102746a2208200241ffff0371220a20036b410274109c051a2008200f3602002007200a4f0d00200620106a41f0036a2102034020022802002207200541016a22053b010420072006360200200241046a2102200a2005470d000b0b20044190016a41026a220220092d00003a000020044180016a41086a22072014280200360200200420042f01c402220a3b019001200420042903e802370350200420042900ed02370055200420042903c80237038001201520022d00003a00002004200a3b013c2004200429005537002d200420042903503703282016200728020036020020042004290380013703400240200628020022020d00201a2110201d2113201c2112201b2111200b210f0c060b20062f01042103201a2110201d2113201c2112201b211120022106200b210f0c000b0b200520094105746a220b41286a200b41086a2201200320096b410574109c051a200b41206a2002290300370000200b41186a2007290300370000200b41106a200a2903003700002001200429036037000020052009410c6c6a220241f4026a200241e8026a220720052f010620096b410c6c109c051a200241f0026a2006280200360200200720042903d802370200200520052f010641016a3b01060c040b41ec034104102e000b41ec034104102e000b419c044104102e000b200441e8026a4102724100419604109a051a419c0410322202450d0220024100360200200241046a200441e8026a419804109b051a2002200128020022073602ec03200120023602002001200128020441016a360204200741003b010420072002360200200220022f0106220a4105746a220741086a20042f013c3b00002007410a6a2004413c6a41026a2d00003a0000200741176a2013360000200741136a20123600002007410f6a20113600002007410b6a20103600002007411b6a2004290328370000200741206a200429002d3700002002200a410c6c6a220741f0026a200441c0006a41086a280200360200200741e8026a2004290340370200200241ec036a200a41016a22074102746a200f360200200220073b0106200f20073b0104200f20023602000b200041003602000b20044180076a24000f0b419c044104102e000bf01405177f017e017f027e047f230041206b220224000240024020014115490d0002402001410176220341ffffff3f712003470d0020034105742204417f4c0d0041012105024002402004450d00200410322205450d010b200041606a2106200041a07f6a210741002108410021094104210a4100210b2001210c034002400240200c220d417f6a220e0d004101210f4100210c0c010b0240024002400240024002402000200e4105746a200d410574221020006a41406a4120109d054100480d004102200d6b210e200720106a21044101210f03400240200e200f6a4101470d004100210c200d210f0c080b200f41016a210f200441206a20044120109d052111200441606a21042011417f4a0d000b200d200f6b210e0c010b200720106a2104024003400240200e4101470d004100210e0c020b200e417f6a210e200441206a20044120109d052111200441606a210420114100480d000b0b200d200e490d01200d20014b0d03200d200e6b220f4101762212450d00200620106a21042000200e4105746a21110340200241186a2210201141186a2213290000370300200241106a2214201141106a2215290000370300200241086a2216201141086a221729000037030020022011290000370300200441086a22182900002119200441106a221a290000211b200441186a220c290000211c201120042900003700002013201c3700002015201b37000020172019370000200c2010290300370000201a20142903003700002018201629030037000020042002290300370000200441606a2104201141206a21112012417f6a22120d000b0b0240200e0d00200e210c0c050b0240200f41094d0d00200e210c0c050b200d20014b0d01200d200e6b21122000200e4105746a21100340200d200e417f6a220c490d040240200d200c6b220f4102490d002000200e4105746a22042000200c4105746a220e4120109d05417f4a0d00200e2900002119200e2004290000370000200241186a2216200e41186a2211290000370300200241106a2217200e41106a2213290000370300200241086a2218200e41086a22142900003703002014200441086a2900003700002013200441106a2900003700002011200441186a29000037000020022019370300410121150240200f4103490d00200e41c0006a20024120109d05417f4a0d00410221112010210402400340200441186a200441386a290000370000200441106a200441306a290000370000200441086a200441286a2900003700002004200441206a221329000037000020122011460d01200441c0006a21142011211520132104201141016a2111201420024120109d05417f4a0d020c000b0b201121150b200e20154105746a22042002290300370000200441186a2016290300370000200441106a2017290300370000200441086a20182903003700000b200c450d05201041606a2110201241016a2112200c210e200f410a4f0d050c000b0b200e200d1030000b200d200e417f6a220c490d010b200d2001108f01000b200c200d1030000b024002400240200b2009470d0002400240200941016a22042009490d0020094101742211200420042011491b220441ffffffff01712004470d002004410374221141004e0d010b1033000b0240024020090d0020111032210a0c010b200a200941037420111034210a0b200a450d01200421092008210b0b200a200b4103746a2204200f3602042004200c360200200841016a220b2108200b4102490d01024003400240024002400240200a200b417f6a22084103746a2204280200450d00200b410374200a6a220f41746a280200220e200428020422114d0d000240200b41024b0d00200b21084102210b0c080b200a200b417d6a22164103746a28020422042011200e6a4d0d010240200b41034b0d00200b21084103210b0c080b200f41646a2802002004200e6a4d0d01200b21080c070b200b4103490d0120042802042111200a200b417d6a22164103746a28020421040b20042011490d010b200b417e6a21160b024002400240024002400240200b201641016a221d4b221e450d00200b20164b221f450d01200a20164103746a2217280204222020172802006a2204200a201d4103746a2218280200221a490d02200420014b0d032000201a4105746a22142018280204221541057422116a210f2004410574210e2004201a6b220d20156b220420154f0d042005200f20044105742211109b05221320116a21120240024020154101480d00200441014e0d010b200f2104201321110c060b2006200e6a210e200f21040340200e200441606a220f201241606a220d200d200f4120109d0541004822101b2211290000370000200e41186a201141186a290000370000200e41106a201141106a290000370000200e41086a201141086a2900003700002012200d20101b211202402014200f200420101b2204490d00201321110c070b200e41606a210e2013211120132012490d000c060b0b419cffc000201d200b1036000b419cffc0002016200b1036000b201a20041030000b20042001108f01000b200520142011109b05221320116a21120240024020154101480d00200d20154a0d010b20142104201321110c010b2000200e6a2110201321112014210403402004200f2011200f20114120109d05410048220d1b220e290000370000200441186a200e41186a290000370000200441106a200e41106a290000370000200441086a200e41086a2900003700002011201141206a200d1b2111200441206a2104200f41206a200f200d1b220f20104f0d01201220114b0d000b0b20042011201220116b416071109b051a0240201f450d002017201a360200201741046a202020156a360200201e450d022018201841086a200b201d417f736a410374109c051a2008210b200841014d0d040c010b0b41acffc0002016200b1036000b418080c000106d000b20114104102e000b200c0d000b02402009450d00200a10290b2003450d03200510290c030b20044101102e000b102f000b20014102490d002001417f6a2111200141057420006a41206a2110410121120340024002400240024020112204417f6a221120014b0d00200120116b220e4102490d03200020044105746a2204200020114105746a220d4120109d05417f4a0d03200d2900002119200d2004290000370000200241186a2214200d41186a220f290000370300200241106a220b200d41106a2213290000370300200241086a2215200d41086a220a290000370300200a200441086a2900003700002013200441106a290000370000200f200441186a2900003700002002201937030041012104200e4103490d02200d41c0006a20024120109d05417f4a0d0241002113201021040340200441406a220e200441606a220f290000370000200e41186a200f41186a290000370000200e41106a200f41106a290000370000200e41086a200f41086a29000037000020122013220e460d02200e417f6a2113200420024120109d05210f200441206a2104200f417f4a0d020c000b0b201120011030000b4102200e6b21040b200d20044105746a22042002290300370000200441186a2014290300370000200441106a200b290300370000200441086a20152903003700000b201041606a21102012417f6a211220110d000b0b200241206a24000bca0201067f230041b0016b22012400200141086a200010c601024020012903284202510d000340200128026021022001280258210302400240200128025c22040d00200321050c010b2004210620032105034020052802ec0321052006417f6a22060d000b0340200320032f01064102746a41ec036a28020021032004417f6a22040d000b0b200120023602a801200141003602a001200141003602980120014200370390012001200536028c0120014100360288012001200336029c01200120032f01063602a40120014188016a10c901200141086a200010c60120012903284202520d000b0b02402000280204220341b0d6c000460d0020032802002104200310292004450d0020042802002105200410292005450d00024020052802002203450d000340200510292003210520032802002204210320040d000b0b200510290b200141b0016a24000bee0303047f017e017f02402001450d00034020002802f80621002001417f6a22010d000b0b02402002450d004100210341002101034002400240200120002f01064f0d004108200041086a200041b0d6c000461b200141d0006c6a22042802442105200441c0006a2802002106200141016a21010c010b02400240200028020022010d002003ad210741002104410021010c010b20003301044220862003ad842107410121040b200010292007a72103024002402007422088a7220820012f01064f0d00200121000c010b034002400240200128020022000d002003ad2107410021000c010b200441016a210420013301044220862003ad8421070b200110292007a72103200021012007422088a7220820002f01064f0d000b0b4108200041086a200041b0d6c000461b200841d0006c6a22012802442105200141c0006a2802002106200841027420006a41fc066a280200210002402004417f6a2201450d00034020002802f80621002001417f6a22010d000b0b410021010b2006450d012002417f6a210202402005450d00200610290b20020d000b0b0240200041b0d6c000460d0020002802002101200010292001450d0020012802002100200110292000450d00024020002802002201450d000340200010292001210020012802002203210120030d000b0b200010290b0bdf2003167f037e067f230041c0026b220424000240024020014115490d0041012105410121060240024002400340200121072000210820052006714101732109024002400240024002400240034002400240024002402003450d00024020054101710d002000200110d0012003417f6a21030b2001410276220a41036c210b200a410174210c4100210d024020014132490d00200a200a417f6a220d2000200a4105746a2000200d4105746a4120109d05220e410048220f1b2210200a41016a2211200d200a200f1b220a200020114105746a2000200a4105746a4120109d0541004822111b220a2000200a4105746a200020104105746a4120109d0522104100481b210a200c200c417f6a220d2000200c4105746a2000200d4105746a4120109d05221241004822131b2214200c4101722215200d200c20131b220c200020154105746a2000200c4105746a4120109d0522134100481b220c2000200c4105746a200020144105746a4120109d0522144100481b210c200b200b417f6a220d2000200b4105746a2000200d4105746a4120109d05221541004822161b2217200b41016a2218200d200b20161b220b200020184105746a2000200b4105746a4120109d05220d4100481b220b2000200b4105746a200020174105746a4120109d0522164100481b210b41024101200f1b200e411f7620111b2010411f766a2012411f766a2013411f766a2014411f766a2015411f766a200d411f766a2016411f766a210d0b2000200c4105746a2000200a4105746a4120109d05220f411f76200d6a2000200b4105746a2000200a200c200f410048220f1b220e4105746a4120109d052210411f766a210d2000200b200e20104100481b220b4105746a2000200c200a200f1b22194105746a4120109d05417f4c0d01200b21190c020b2000200110d1010c0f0b200d41016a220d410c490d0002402001410176220b450d00200020014105746a41606a210a2000210c0340200441206a41186a220d200c41186a220f290000370300200441206a41106a220e200c41106a2210290000370300200441206a41086a2211200c41086a22122900003703002004200c290000370320200a41086a2213290000211a200a41106a2214290000211b200a41186a2215290000211c200c200a290000370000200f201c3700002010201b3700002012201a3700002015200d2903003700002014200e29030037000020132011290300370000200a2004290320370000200a41606a210a200c41206a210c200b417f6a220b0d000b0b20012019417f736a21194101210a0c010b200d45210a0b0240200a452009724101710d002000200110d2010d0d0b2002450d02201920014f0d0102402002200020194105746a220a4120109d0541004e0d0020002108200121070c040b200441206a41186a2212200041186a220e290000370300200441206a41106a2213200041106a2210290000370300200441206a41086a2214200041086a221129000037030020042000290000370320200a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2000200a290000370000200e201c3700002010201b3700002011201a370000200d2012290300370000200b2013290300370000200c2014290300370000200a2004290320370000200441c0016a41186a2217200e290000370300200441c0016a41106a22182010290000370300200441c0016a41086a22192011290000370300200420002900003703c001200041606a2115200041206a21164100210c2001210b03400240200c200b417f6a220d4f0d002016200c4105746a210a0340200441c0016a200a4120109d05417f4c0d01200a41206a210a200d200c41016a220c470d000b200d210c0b2015200b4105746a210a02400340200c200b417f6a220b4f0d01200441c0016a200a4120109d05210d200a41606a220f210a200d4100480d000b20122016200c4105746a220a41186a220d2900003703002013200a41106a221d2900003703002014200a41086a22062900003703002004200a290000370320200f41286a221e290000211a200f41306a221f290000211b200f41386a2220290000211c200a200f41206a220f290000370000200d201c370000201d201b3700002006201a37000020202012290300370000201f2013290300370000201e2014290300370000200f2004290320370000200c41016a210c0c010b0b200020042903c001370000200e2017290300370000201020182903003700002011201929030037000002402001200c41016a220a490d002000200a4105746a21002001200a6b220141154f0d010c0c0b0b200a20011030000b41c080c100201920011036000b2007450d010b201920074f0d01200441206a41186a2216200841186a221e290000370300200441206a41106a2217200841106a221f290000370300200441206a41086a2218200841086a222029000037030020042008290000370320200820194105746a220a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2008200a290000370000201e201c370000201f201b3700002020201a370000200d2016290300370000200b2017290300370000200c2018290300370000200a2004290320370000200441186a2205201e290000370300200441106a2209201f290000370300200441086a2221202029000037030020042008290000370300200841206a21014100211d2007417f6a220d450d022001210a0340200a20044120109d0541004e0d03200a41206a210a200d201d41016a221d470d000b200d211d0c020b418880c100410041001036000b419880c100201920071036000b200820074105746a210c200d210b02400340200c2100200b220a201d4d22060d01200a417f6a210b200041606a220c20044120109d05417f4a0d000b0b0240200a201d490d00200d200a490d0241800121144100210f410021124100210d4100211141800121152001201d4105746a2222210103400240200020016b220a419fc0004b22190d00200a410576220a41807f6a200a2012200f492011200d49220c72220b1b210a0240200b450d002015200a200c1b2115200a2014200c1b21140c010b200a200a41017622156b21140b02402011200d470d00024020150d00200441c0006a220d21110c010b4100210a200441c0006a2211210d2001210c0340200d200a3a0000200d200c20044120109d05417f73411f766a210d200c41206a210c2015200a41016a220a470d000b0b02402012200f470d00024020140d00200441c0016a220f21120c010b200041606a210a4100210c200441c0016a2212210f0340200f200c3a0000200f200a20044120109d05411f766a210f200a41606a210a2014200c41016a220c470d000b0b0240200f20126b220a200d20116b220c200c200a4b1b2213450d002016200120112d00004105746a220a41186a2900003703002017200a41106a2900003703002018200a41086a2900003703002004200a290000370320200120112d00004105746a220a200020122d0000417f734105746a220c290000370000200a41186a200c41186a290000370000200a41106a200c41106a290000370000200a41086a200c41086a290000370000024020134101460d004100210a034020002012200a6a220e2d0000417f734105746a220c20012011200a6a41016a22102d00004105746a220b290000370000200c41186a200b41186a290000370000200c41106a200b41106a290000370000200c41086a200b41086a290000370000200120102d00004105746a220c2000200e41016a2d0000417f734105746a220b290000370000200c41186a200b41186a290000370000200c41106a200b41106a290000370000200c41086a200b41086a290000370000200a41026a210c200a41016a220b210a200c2013490d000b2012200b6a21122011200b6a21110b200020122d0000417f734105746a220a2004290320370000200a41186a2016290300370000200a41106a2017290300370000200a41086a2018290300370000201241016a2112201141016a21110b200020144105746b20002012200f461b2100200120154105746a20012011200d461b210120190d000b024002402011200d4f0d002000210a034020162001200d417f6a220d2d00004105746a220c41186a220b2900003703002017200c41106a220f2900003703002018200c41086a22002900003703002004200c290000370320200a41606a220a41086a220e290000211a200a41106a2210290000211b200a41186a2212290000211c200c200a290000370000200b201c370000200f201b3700002000201a3700002012201629030037000020102017290300370000200e2018290300370000200a20042903203700002011200d490d000c020b0b2001210a2012200f4f0d000340200f417f6a220f2d0000210c2016200a41186a220b2900003703002017200a41106a220d2900003703002018200a41086a22012900003703002004200a2900003703202000200c417f734105746a220c41086a220e290000211a200c41106a2210290000211b200c41186a2211290000211c200a200c290000370000200b201c370000200d201b3700002001201a3700002011201629030037000020102017290300370000200e2018290300370000200c2004290320370000200a41206a210a2012200f490d000b0b20082004290300370000201e2005290300370000201f2009290300370000202020212903003700002007200a20226b410576201d6a22014d0d032016201e2900003703002017201f2900003703002018202029000037030020042008290000370320200820014105746a220a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2008200a290000370000201e201c370000201f201b3700002020201a370000200d2016290300370000200b2017290300370000200c2018290300370000200a2004290320370000200720016b220c450d04200c20012001200c4b1b210b2007410376210d200a41206a2100024002402001200c417f6a220c490d002000200c200a200310cf01200821000c010b200820012002200310cf01200a2102200c21010b200b200d4f2105200141154f0d010c050b0b201d200a1030000b200a200d108f01000b419880c100200120071036000b41a880c100106d000b20014102490d00200041606a210f4101210b0340200b410574210a200b417f6a210c200b41016a210b02402000200a6a220a2000200c4105746a220d4120109d05417f4a0d00200441c0016a41186a220e200a41186a2210290000370300200441c0016a41106a2211200a41106a2212290000370300200441c0016a41086a2213200a41086a22142900003703002004200a2900003703c001200a200d2900003700002014200d41086a2900003700002012200d41106a2900003700002010200d41186a2900003700004100210d0240200c450d00200f210a03400240200441c0016a200a4120109d054100480d00200c210d0c020b200a41206a200a290000370000200a41386a200a41186a290000370000200a41306a200a41106a290000370000200a41286a200a41086a290000370000200a41606a210a200c417f6a220c0d000b0b2000200d4105746a220a20042903c001370000200a41186a200e290300370000200a41106a2011290300370000200a41086a20132903003700000b200f41206a210f200b2001470d000b0b200441c0026a24000beb050a067f017e017f017e017f017e017f017e017f017e230041206b2202240002400240024020014108490d00200141017641feffffff07712203417f6a220420014f0d022001410d74200173220541117620057322054105742005732206417f2001417f6a677622077122054100200120052001491b6b220520014f0d01200020044105746a22042900002108200020054105746a220541086a2209290000210a200541106a220b290000210c200541186a220d290000210e20042005290000370000200441186a220f2900002110200f200e370000200441106a220f290000210e200f200c370000200441086a2204290000210c2004200a370000200d2010370000200b200e3700002009200c37000020052008370000024020032001490d00200321040c030b2006410d7420067322054111762005732205410574200573220620077122054100200120052001491b6b220520014f0d01200020034105746a22042900002108200020054105746a220541086a2209290000210a200541106a220b290000210c200541186a220d290000210e20042005290000370000200441186a220f2900002110200f200e370000200441106a220f290000210e200f200c370000200441086a2204290000210c2004200a370000200d2010370000200b200e3700002009200c370000200520083700002003410172220420014f0d022006410d742006732205411176200573220541057420057320077122054100200120052001491b6b220520014f0d01200020044105746a22012900002108200020054105746a220041086a2205290000210a200041106a2204290000210c200041186a2203290000210e20012000290000370000200141186a220629000021102006200e370000200141106a2206290000210e2006200c370000200141086a2201290000210c2001200a370000200320103700002004200e3700002005200c370000200020083700000b200241206a24000f0b419880c100200520011036000b418880c100200420011036000be90609067f017e017f017e017f027e017f017e027f230041206b22022400024020014101762203450d0003402003417f6a2203210402400240024003402004410174220541017221060240200541026a220520014f0d00200620014f0d0220052006200020064105746a200020054105746a4120109d054100481b21060b200620014f0d03200420014f0d02200020044105746a2204200020064105746a22054120109d0541004e0d03200541086a22072900002108200541106a2209290000210a200541186a220b290000210c2004290000210d20042005290000370000200441186a220e290000210f200e200c370000200441106a220e290000210c200e200a370000200441086a2204290000210a20042008370000200b200f3700002009200c3700002007200a3700002005200d370000200621040c000b0b418882c100200620011036000b419882c100200420011036000b20030d000b0b0240024020014102490d002001210703402007417f6a220720014f0d02200241186a2209200041186a2204290000370300200241106a220b200041106a2205290000370300200241086a220e200041086a2203290000370300200020074105746a220641086a2900002108200641106a290000210a200641186a290000210c2000290000210d200020062900003700002004200c3700002005200a370000200320083700002002200d37030041002105024002400240034020062002290300370000200641186a2009290300370000200641106a200b290300370000200641086a200e2903003700002005410174220641017221040240200641026a220620074f0d00200420074f0d0220062004200020044105746a200020064105746a4120109d054100481b21040b200420074f0d03200520074f0d02200020054105746a2205200020044105746a22064120109d0541004e0d032009200541186a2203290000370300200b200541106a2210290000370300200e200541086a2211290000370300200641086a2900002108200641106a290000210a200641186a290000210c2005290000210d200520062900003700002003200c3700002010200a370000201120083700002002200d370300200421050c000b0b418882c100200420071036000b419882c100200520071036000b200741014b0d000b0b200241206a24000f0b419880c100200720011036000bdb08030a7f017e0a7f230041c0006b22022400200041a07f6a21032001417f6a2104200141324921054101210641002107024003400240024020062001490d00410021080c010b41012108200020064105746a2209200941606a4120109d054100480d0003404101210a20042006460d03200641016a2106200941206a220a20094120109d052108200a21092008417f4a0d000b200620014921080b2006200146210a20050d0120062001460d0102400240024002402006417f6a220920014f0d002008450d0120002006410574220b6a220a290000210c200a200020094105746a22092900003700002009200c370000200a41086a220d290000210c200d200941086a220e290000370000200e200c370000200a41106a220f290000210c200f200941106a22102900003700002010200c370000200a41186a2211290000210c2011200941186a22122900003700002012200c37000020064102490d03200920002006417e6a22084105746a22134120109d05417f4a0d032009290000210c20092013290000370000200241206a41186a22142012290000370300200241206a41106a22152010290000370300200241206a41086a2216200e290000370300200e201341086a2900003700002010201341106a2900003700002012201341186a2900003700002002200c3703204100210e2008450d022003200b6a210903400240200241206a20094120109d054100480d002008210e0c040b200941206a2009290000370000200941386a200941186a290000370000200941306a200941106a290000370000200941286a200941086a290000370000200941606a21092008417f6a22080d000c030b0b418880c100200920011036000b419880c100200620011036000b2000200e4105746a22092002290320370000200941186a2014290300370000200941106a2015290300370000200941086a20162903003700000b200741016a21070240200120066b22104102490d00200a41206a2209200a4120109d05417f4a0d00200a290000210c200a2009290000370000200241206a41186a22122011290000370300200241206a41106a2213200f290000370300200241206a41086a220b200d290000370300200d200941086a290000370000200f200941106a2900003700002011200941186a2900003700002002200c3703204101210d024020104103490d00200a41c0006a200241206a4120109d05417f4a0d00410321084102210e0340200a200e4105746a220941606a220d2009290000370000200d41186a200941186a290000370000200d41106a200941106a290000370000200d41086a200941086a290000370000024020082010490d00200e210d0c020b20084105742109200e210d2008210e200841016a2108200a20096a200241206a4120109d054100480d000b0b200a200d4105746a22092002290320370000200941186a2012290300370000200941106a2013290300370000200941086a200b2903003700000b20074105470d000b4100210a0b200241c0006a2400200a0be32003167f037e067f230041c0026b220524000240024020014115490d004101210641012107024002400240034020012108200021092006200771410173210a024002400240024002400240034002400240024002402004450d00024020064101710d002000200110d0012004417f6a21040b2001410276220b41036c210c200b410174210d4100210e024020014132490d00200b200b417f6a220e2000200b4105746a2000200e4105746a4120109d05220f41004822101b2211200b41016a2212200e200b20101b220b200020124105746a2000200b4105746a4120109d0541004822121b220b2000200b4105746a200020114105746a4120109d0522114100481b210b200d200d417f6a220e2000200d4105746a2000200e4105746a4120109d05221341004822141b2215200d4101722216200e200d20141b220d200020164105746a2000200d4105746a4120109d0522144100481b220d2000200d4105746a200020154105746a4120109d0522154100481b210d200c200c417f6a220e2000200c4105746a2000200e4105746a4120109d05221641004822171b2218200c41016a2219200e200c20171b220c200020194105746a2000200c4105746a4120109d05220e4100481b220c2000200c4105746a200020184105746a4120109d0522174100481b210c4102410120101b200f411f7620121b2011411f766a2013411f766a2014411f766a2015411f766a2016411f766a200e411f766a2017411f766a210e0b2000200d4105746a2000200b4105746a4120109d052210411f76200e6a2000200c4105746a2000200b200d201041004822101b220f4105746a4120109d052211411f766a210e2000200c200f20114100481b220c4105746a2000200d200b20101b221a4105746a4120109d05417f4c0d01200c211a0c020b2000200110d1010c0f0b200e41016a220e410c490d0002402001410176220c450d00200020014105746a41606a210b2000210d0340200541206a41186a220e200d41186a2210290000370300200541206a41106a220f200d41106a2211290000370300200541206a41086a2212200d41086a22132900003703002005200d290000370320200b41086a2214290000211b200b41106a2215290000211c200b41186a2216290000211d200d200b2900003700002010201d3700002011201c3700002013201b3700002016200e2903003700002015200f29030037000020142012290300370000200b2005290320370000200b41606a210b200d41206a210d200c417f6a220c0d000b0b2001201a417f736a211a4101210b0c010b200e45210b0b0240200b45200a724101710d002000200110d2010d0d0b2003450d02201a20014f0d01024020032000201a4105746a220b4120109d0541004e0d0020002109200121080c040b200541206a41186a2213200041186a220f290000370300200541206a41106a2214200041106a2211290000370300200541206a41086a2215200041086a221229000037030020052000290000370320200b41086a220d290000211b200b41106a220c290000211c200b41186a220e290000211d2000200b290000370000200f201d3700002011201c3700002012201b370000200e2013290300370000200c2014290300370000200d2015290300370000200b2005290320370000200541c0016a41186a2218200f290000370300200541c0016a41106a22192011290000370300200541c0016a41086a221a2012290000370300200520002900003703c001200041606a2116200041206a21174100210d2001210c03400240200d200c417f6a220e4f0d002017200d4105746a210b0340200541c0016a200b4120109d05417f4c0d01200b41206a210b200e200d41016a220d470d000b200e210d0b2016200c4105746a210b02400340200d200c417f6a220c4f0d01200541c0016a200b4120109d05210e200b41606a2210210b200e4100480d000b20132017200d4105746a220b41186a220e2900003703002014200b41106a221e2900003703002015200b41086a22072900003703002005200b290000370320201041286a221f290000211b201041306a2220290000211c201041386a2221290000211d200b201041206a2210290000370000200e201d370000201e201c3700002007201b3700002021201329030037000020202014290300370000201f201529030037000020102005290320370000200d41016a210d0c010b0b200020052903c001370000200f2018290300370000201120192903003700002012201a29030037000002402001200d41016a220b490d002000200b4105746a21002001200b6b220141154f0d010c0c0b0b200b20011030000b41c080c100201a20011036000b2008450d010b201a20084f0d01200541206a41186a2217200941186a221f290000370300200541206a41106a2218200941106a2220290000370300200541206a41086a2219200941086a2221290000370300200520092900003703202009201a4105746a220b41086a220d290000211b200b41106a220c290000211c200b41186a220e290000211d2009200b290000370000201f201d3700002020201c3700002021201b370000200e2017290300370000200c2018290300370000200d2019290300370000200b2005290320370000200541186a2206201f290000370300200541106a220a2020290000370300200541086a2222202129000037030020052009290000370300200941206a21014100211e2008417f6a220e450d022001210b0340200b20054120109d0541004e0d03200b41206a210b200e201e41016a221e470d000b200e211e0c020b418880c100410041001036000b419880c100201a20081036000b200920084105746a210d200e210c02400340200d2100200c220b201e4d22070d01200b417f6a210c200041606a220d20054120109d05417f4a0d000b0b0240200b201e490d00200e200b490d02418001211541002110410021134100210e4100211241800121162001201e4105746a2223210103400240200020016b220b419fc0004b221a0d00200b410576220b41807f6a200b20132010492012200e49220d72220c1b210b0240200c450d002016200b200d1b2116200b2015200d1b21150c010b200b200b41017622166b21150b02402012200e470d00024020160d00200541c0006a220e21120c010b4100210b200541c0006a2212210e2001210d0340200e200b3a0000200e200d20054120109d05417f73411f766a210e200d41206a210d2016200b41016a220b470d000b0b024020132010470d00024020150d00200541c0016a221021130c010b200041606a210b4100210d200541c0016a2213211003402010200d3a00002010200b20054120109d05411f766a2110200b41606a210b2015200d41016a220d470d000b0b0240201020136b220b200e20126b220d200d200b4b1b2214450d002017200120122d00004105746a220b41186a2900003703002018200b41106a2900003703002019200b41086a2900003703002005200b290000370320200120122d00004105746a220b200020132d0000417f734105746a220d290000370000200b41186a200d41186a290000370000200b41106a200d41106a290000370000200b41086a200d41086a290000370000024020144101460d004100210b034020002013200b6a220f2d0000417f734105746a220d20012012200b6a41016a22112d00004105746a220c290000370000200d41186a200c41186a290000370000200d41106a200c41106a290000370000200d41086a200c41086a290000370000200120112d00004105746a220d2000200f41016a2d0000417f734105746a220c290000370000200d41186a200c41186a290000370000200d41106a200c41106a290000370000200d41086a200c41086a290000370000200b41026a210d200b41016a220c210b200d2014490d000b2013200c6a21132012200c6a21120b200020132d0000417f734105746a220b2005290320370000200b41186a2017290300370000200b41106a2018290300370000200b41086a2019290300370000201341016a2113201241016a21120b200020154105746b200020132010461b2100200120164105746a20012012200e461b2101201a0d000b024002402012200e4f0d002000210b034020172001200e417f6a220e2d00004105746a220d41186a220c2900003703002018200d41106a22102900003703002019200d41086a22002900003703002005200d290000370320200b41606a220b41086a220f290000211b200b41106a2211290000211c200b41186a2213290000211d200d200b290000370000200c201d3700002010201c3700002000201b3700002013201729030037000020112018290300370000200f2019290300370000200b20052903203700002012200e490d000c020b0b2001210b201320104f0d0003402010417f6a22102d0000210d2017200b41186a220c2900003703002018200b41106a220e2900003703002019200b41086a22012900003703002005200b2900003703202000200d417f734105746a220d41086a220f290000211b200d41106a2211290000211c200d41186a2212290000211d200b200d290000370000200c201d370000200e201c3700002001201b3700002012201729030037000020112018290300370000200f2019290300370000200d2005290320370000200b41206a210b20132010490d000b0b20092005290300370000201f20062903003700002020200a290300370000202120222903003700002008200b20236b410576201e6a22014d0d032017201f290000370300201820202900003703002019202129000037030020052009290000370320200920014105746a220b41086a220d290000211b200b41106a220c290000211c200b41186a220e290000211d2009200b290000370000201f201d3700002020201c3700002021201b370000200e2017290300370000200c2018290300370000200d2019290300370000200b2005290320370000200820016b220d450d04200d20012001200d4b1b210c2008410376210e200b41206a2100024002402001200d417f6a220d490d002000200d2002200b200410d301200921000c010b2009200120022003200410d301200b2103200d21010b200c200e4f2106200141154f0d010c050b0b201e200b1030000b200b200e108f01000b419880c100200120081036000b41a880c100106d000b20014102490d00200041606a21104101210c0340200c410574210b200c417f6a210d200c41016a210c02402000200b6a220b2000200d4105746a220e4120109d05417f4a0d00200541c0016a41186a220f200b41186a2211290000370300200541c0016a41106a2212200b41106a2213290000370300200541c0016a41086a2214200b41086a22152900003703002005200b2900003703c001200b200e2900003700002015200e41086a2900003700002013200e41106a2900003700002011200e41186a2900003700004100210e0240200d450d002010210b03400240200541c0016a200b4120109d054100480d00200d210e0c020b200b41206a200b290000370000200b41386a200b41186a290000370000200b41306a200b41106a290000370000200b41286a200b41086a290000370000200b41606a210b200d417f6a220d0d000b0b2000200e4105746a220b20052903c001370000200b41186a200f290300370000200b41106a2012290300370000200b41086a20142903003700000b201041206a2110200c2001470d000b0b200541c0026a24000b8f1805047f017e047f017e057f230041e0036b22002400200041b8016a41086a22014200370300200042003703b80141e4f0c5004110200041b8016a1003200041b8036a41086a2001290300370300200020002903b8013703b803200041003602b002200041b8036a4110200041b0026a100621010240024002400240024020002802b0022202417f460d002001450d002002450d0120012d000021022001102920024102460d0020024101710d030b200041013a00b002200041b8016a41086a22014200370300200042003703b80141e4f0c5004110200041b8016a1003200041b8036a41086a22022001290300370300200020002903b8013703b803200041b8036a4110200041b0026a4101100520014200370300200042003703b80141fb83c300410d200041b8016a100320022001290300370300200020002903b8013703b803200041003602b002200041b8036a4110200041b0026a10062101024020002802b0022202417f460d002001450d00200020023602bc01200020013602b801200041b0026a200041b8016a103d024020002802b0022203450d0020002902b402210402402002450d00200110290b2004422088a721052004a721060c030b41f7cdc3004133200041d8036a41ecd6c3001054000b4104210341002105410021060c010b41f7cdc3004133200041d8036a41ecd6c3001054000b2003200541246c22076a210220032101024002400240200741ed00490d00200321010340024020012d00004101470d00200141016a2800002107200141086a28020021082000200141106a2802003602bc03200020083602b803200741c28289aa04470d00200041b0026a200041b8036a10c30120002d00b00222074102460d00200041b0026a2101200041b8016a21020c030b0240200141246a2d00004101470d00200141256a28000021072001412c6a28020021082000200141346a2802003602bc03200020083602b803200741c28289aa04470d00200041b0026a200041b8036a10c30120002d00b00222074102460d00200041b0026a2101200041b8016a21020c030b0240200141c8006a2d00004101470d00200141c9006a2800002107200141d0006a28020021082000200141d8006a2802003602bc03200020083602b803200741c28289aa04470d00200041b0026a200041b8036a10c30120002d00b00222074102460d00200041b0026a2101200041b8016a21020c030b0240200141ec006a2d00004101470d00200141ed006a2800002107200141f4006a28020021082000200141fc006a2802003602bc03200020083602b803200741c28289aa04470d00200041b0026a200041b8036a10c30120002d00b00222074102460d00200041b0026a2101200041b8016a21020c030b200220014190016a22016b41ec004b0d000b0b024020012002460d002003200541246c6a21020340024020012d00004101470d00200141016a2800002107200141086a28020021082000200141106a2802003602bc03200020083602b803200741c28289aa04470d00200041b0026a200041b8036a10c30120002d00b00222074102460d00200041b0026a2101200041b8016a21020c030b2002200141246a2201470d000b0b02402005450d00200541246c21022003210103400240024020012d0000220741034b0d0002400240024020070e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012002415c6a22020d000b0b20060d010c020b20002002200141016a41f700109b0522012900003703782000200141076a29000037007f20002900c7012104200041206a200041cf016a41d800109b051a20002900a702210920002000290378370388012000200029007f37008f01200041b0026a200041206a41d800109b051a200041106a41c5efc500411310d501024002402000290318500d0020002802100d010b200041b8016a41086a22014200370300200042003703b80141c5efc5004113200041b8016a1003200041b8036a41086a2001290300370300200020002903b8013703b80320002004200920074101461b3703b801200041b8036a4110200041b8016a410810050b200041b8016a41086a22014200370300200042003703b80141d8efc5004110200041b8016a1003200041b8036a41086a22022001290300370300200020002903b8013703b80320002004200920074101461b3703b801200041b8036a4110200041b8016a41081005024020070d0020004198016a41086a200041b0026a41086a2d00003a000020002000290388013703a8012000200029008f013700af01200020002903b00237039801200041086a41bdf0c5004111105d200041a8036a200028020c410020002802081b220a10d60120002802a803210720002802b0032108200041b8016a41186a220b4200370300200041b8016a41106a220c420037030020014200370300200042003703b80120072008200041b8016a1000200041b8036a41186a200b290300370300200041b8036a41106a200c29030037030020022001290300370300200020002903b8013703b803200041b8016a200041b8036a10d70120002802bc0121082001280200410020002802b80122021b2101024020002802ac03450d00200710290b2008410020021b21072002410120021b2102024002402001418002490d00412010322201450d05200120002903a8013700002001200437000f2001200029039801370017200141076a20002900af013700002001411f6a20004198016a41086a2d00003a0000200041a8036a200a41016a220a10d60120002802b003210b20002802a8032108200041b8016a41186a220c4200370300200041b8016a41106a220d4200370300200041b8016a41086a220e4200370300200042003703b8012008200b200041b8016a1000200041b8036a41186a200c290300370300200041b8036a41106a200d290300370300200041b8036a41086a200e290300370300200020002903b8013703b803200041b8016a2001410110d801200041b8036a412020002802b801220b20002802c0011005024020002802bc01450d00200b10290b024020002802ac03450d00200810290b20011029200041b8016a41086a22014200370300200042003703b80141bdf0c5004111200041b8016a1003200041b8036a41086a2001290300370300200020002903b8013703b8032000200a3602b801200041b8036a4110200041b8016a410410050c010b200041b8036a41086a220b20004198016a41086a2d00003a0000200020002903a8013703b801200020002900af013700bf0120002000290398013703b803024020012007470d000240200141016a22072001490d0020014101742208200720072008491b220741ffffff3f712007470d00200741057422084100480d000240024020010d002008103221020c010b200220014105742008103421020b20020d0120084101102e000b1033000b200220014105746a220820002903b80137000020002900bf0121092008200437000f200841076a2009370000200820002903b8033700172008411f6a200b2d00003a0000200041a8036a200a10d60120002802b003210a20002802a8032108200041b8016a41186a220c4200370300200041b8016a41106a220d4200370300200041b8016a41086a220e4200370300200042003703b8012008200a200041b8016a1000200041b8036a41186a200c290300370300200041b8036a41106a200d290300370300200b200e290300370300200020002903b8013703b803200041b8016a2002200141016a10d801200041b8036a412020002802b801220120002802c0011005024020002802bc01450d00200110290b20002802ac03450d00200810290b2007450d00200210290b02402005450d00200541246c21022003210103400240024020012d0000220741034b0d0002400240024020070e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012002415c6a22020d000b0b2006450d010b200310290b200041e0036a24000f0b41204101102e000bc30104017f017e017f017e230041206b2203240042002104200341106a41086a220542003703002003420037031020012002200341106a1003200341086a2005290300370300200320032903103703002003410036021020034110200341106a1006210102400240024020032802102202417f470d000c010b024020010d000c010b20024108490d012001290000210620011029420121040b2000200637030820002004370300200341206a24000f0b41f7cdc3004133200341106a41ecd6c3001054000b7301017f02400240411610322202450d002002410e6a41002900dcf045370000200241086a41002900d6f045370000200241002900cef04537000020024116412c10342202450d01200042ac808080a00337020420002002360200200220013600160f0b41164101102e000b412c4101102e000b8505010e7f230041e0006b220224002002410036023820014120200241386a1006210302400240024002400240024020022802382204417f470d00200041003602000c010b2002200436021420022003360210200241086a200241106a102c20022802080d04200228021422054160712201417f4c0d01200228020c210602400240200541057622070d00410121080c010b200110322208450d030b02402006450d004100210903402005210a200241003a00582009220b41016a2109410021010240024002400340200a2001460d01200241386a20016a2002280210220c2d00003a00002002200c41016a3602102002200141016a220c3a0058200c2101200c4120470d000b200241186a41186a220d200241386a41186a290300370300200241186a41106a220e200241386a41106a290300370300200241186a41086a220f200241386a41086a290300370300200220022903383703182007200b470d020240200b4101742201200920092001491b220741ffffff3f712007470d002007410574220141004e0d020b1033000b200241003602140240200141ff0171450d00200241003a00580b2007450d08200810290c080b02400240200b0d002001103221080c010b2008200b4105742001103421080b2008450d060b200a200c6b21052008200b4105746a22012002290318370000200141186a200d290300370000200141106a200e290300370000200141086a200f29030037000020092006470d000b2002200a200c6b3602140b2008450d042000200736020420002008360200200041086a20063602002004450d00200310290b200241e0006a24000f0b102f000b20014101102e000b20014101102e000b41f7cdc3004133200241386a41ecd6c3001054000ba72601047f230041106b22032400200341003602082003420137030020022003106602400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402002450d00200120024105746a2104034002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d0320032006360204200320053602000b2003200241016a360208200520026a20012d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d0420032006360204200320053602000b2003200241016a360208200520026a200141016a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d0520032006360204200320053602000b2003200241016a360208200520026a200141026a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d0620032006360204200320053602000b2003200241016a360208200520026a200141036a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d0720032006360204200320053602000b2003200241016a360208200520026a200141046a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d0820032006360204200320053602000b2003200241016a360208200520026a200141056a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d0920032006360204200320053602000b2003200241016a360208200520026a200141066a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d0a20032006360204200320053602000b2003200241016a360208200520026a200141076a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d0b20032006360204200320053602000b2003200241016a360208200520026a200141086a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d0c20032006360204200320053602000b2003200241016a360208200520026a200141096a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d0d20032006360204200320053602000b2003200241016a360208200520026a2001410a6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d0e20032006360204200320053602000b2003200241016a360208200520026a2001410b6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d0f20032006360204200320053602000b2003200241016a360208200520026a2001410c6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d1020032006360204200320053602000b2003200241016a360208200520026a2001410d6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d1120032006360204200320053602000b2003200241016a360208200520026a2001410e6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d1220032006360204200320053602000b2003200241016a360208200520026a2001410f6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d1320032006360204200320053602000b2003200241016a360208200520026a200141106a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d1420032006360204200320053602000b2003200241016a360208200520026a200141116a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d1520032006360204200320053602000b2003200241016a360208200520026a200141126a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d1620032006360204200320053602000b2003200241016a360208200520026a200141136a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d1720032006360204200320053602000b2003200241016a360208200520026a200141146a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d1820032006360204200320053602000b2003200241016a360208200520026a200141156a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d1920032006360204200320053602000b2003200241016a360208200520026a200141166a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d1a20032006360204200320053602000b2003200241016a360208200520026a200141176a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d1b20032006360204200320053602000b2003200241016a360208200520026a200141186a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d1c20032006360204200320053602000b2003200241016a360208200520026a200141196a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d1d20032006360204200320053602000b2003200241016a360208200520026a2001411a6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d1e20032006360204200320053602000b2003200241016a360208200520026a2001411b6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d1f20032006360204200320053602000b2003200241016a360208200520026a2001411c6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d2020032006360204200320053602000b2003200241016a360208200520026a2001411d6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d2120032006360204200320053602000b2003200241016a360208200520026a2001411e6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2320024101742206200520052006491b22064100480d230240024020020d002006103221050c010b200328020020022006103421050b2005450d2220032006360204200320053602000b2003200241016a360208200520026a2001411f6a2d00003a0000200141206a22012004470d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b1033000bd40201057f230041c0006b22022400024002400240411b10322203450d00200341176a41002800fdea45360000200341106a41002900f6ea45370000200341086a41002900eeea45370000200341002900e6ea453700002003411b413610342204450d012004200136001b200241206a41186a22034200370300200241206a41106a22014200370300200241206a41086a22054200370300200242003703202004411f200241206a1000200241186a22062003290300370300200241106a2001290300370300200241086a200529030037030020022002290320370300412010322203450d0220032002290300370000200042a0808080800437020420002003360200200341186a2006290300370000200341106a200241106a290300370000200341086a200241086a29030037000020041029200241c0006a24000f0b411b4101102e000b41364101102e000b41204101102e000bd82504027f027e087f037e230041b00d6b220724000240024002402001280230200128024022082802b801460d002004420020042903082209200841c0006a2903007d220a200a20095622081b3703082008450d01200041fe89c10036020420004101360200200041086a412a3602002000410c6a2006290200370200200041146a200641086a2802003602000c020b2000419689c10036020420004101360200200041086a41243602002000410c6a2006290200370200200041146a200641086a2802003602000c010b200741186a41186a200141e8006a290000370300200741186a41106a200141e0006a290000370300200741186a41086a200141d8006a290000370300200720012900503703182006280208210b20062802002108200741b0026a41186a220c4200370300200741b0026a41106a220d4200370300200741b0026a41086a220e4200370300200742003703b0022008200b200741b0026a1000200741d00a6a41186a200c290300370300200741d00a6a41106a200d290300370300200741d00a6a41086a200e290300370300200720072903b0023703d00a0240024002400240024002400240024002400240412010322208450d0020082005290000370000200841186a200541186a290000370000200841106a200541106a290000370000200841086a200541086a2900003700002008412041c00010342208450d01200820072903d00a370020200841386a200741d00a6a41186a290300370000200841306a200741d00a6a41106a290300370000200841286a200741d00a6a41086a290300370000200841c00041800110342208450d0220082007290318370040200841d8006a200741186a41186a290300370000200841d0006a200741186a41106a290300370000200841c8006a200741186a41086a290300370000200741b0026a41186a220c4200370300200741b0026a41106a220d4200370300200741b0026a41086a220e4200370300200742003703b002200841e000200741b0026a1000200741386a41186a220f200c290300370300200741386a41106a220c200d290300370300200741386a41086a220d200e290300370300200720072903b0023703382008102920062902002109200741d8006a41d8006a200d290300370300200741d8006a41e0006a200c290300370300200741c0016a200f29030037030020074194016a410036020020074184016a41bc89c100360200200741f8006a4200370300200741f4006a221041b0d6c00036020020072001360260200741d8006a41286a200141186a2211360200200720072903383703a8012007420837028c012007410036027020074100360264200720012802483602a00120072001290340370398012007200128023041016a360288012001290300210a2007200128024c3602a4012007200a370358200741c8016a41186a200541186a290000370300200741c8016a41106a200541106a290000370300200741c8016a41086a200541086a29000037030020074101360270200720052900003703c8012011200741386a10db01210620072007280270417f6a2208360270024020060d0020080d042007417f36027020074190026a41186a200741386a41186a29030037030020074190026a41106a200741386a41106a29030037030020074190026a41086a200741386a41086a2903003703002007200729033837039002024002402007280274220e41b0d6c000460d002007280278210f0c010b4100210f200741d00a6a410041e002109a051a200741b0026a410041a008109a051a41880b1032220e450d06200e41003b0106200e4100360200200e41086a200741d00a6a41e002109b051a200e41e8026a200741b0026a41a008109b051a200741003602782007200e3602740b024002400340200e41086a2108200e2f0106221241057421064100210c0240024003402006450d0120074190026a20084120109d05220d450d02200641606a2106200c41016a210c200841206a2108200d417f4a0d000b200c417f6a21120b200f450d02200f417f6a210f200e20124102746a41880b6a280200210e0c010b0b200e200c41e0006c6a41e8026a21060c010b200741f0016a41186a20074190026a41186a290300220a370300200741f0016a41106a20074190026a41106a2903002213370300200741f0016a41086a20074190026a41086a2903002214370300200720072903900222153703f001200741ec0a6a2014370200200741d00a6a41246a2013370200200741fc0a6a200a3702002007200741d8006a41246a3602e00a200720123602dc0a200720103602d80a2007200e3602d40a200741003602d00a200720153702e40a200741e4026a4200370200200741003a00ec02200742003703b002200741003a008d03200741b0d6c0003602e002200742003703c802200741d00a6a200741b0026a10c80121060b200741e0016a290300210a20064201370318200641013a003c200641286a427f370300200641206a427f3703002006413d6a20072903c801370000200641d5006a200a370000200641cd006a200741d8016a290300370000200641c5006a200741d0016a2903003700002007200728027041016a360270200741106a20044101200741186a200741386a20022003200741d8006a10dc012007280210220e0d06200741b0026a200520072802a00128020010dd01024020072802b0024101470d002009422088a72106200741b8026a280200210520072802b402210e2009a721010c0b0b20074190026a41186a200741b0026a410472220641186a2802002208360200200741d00a6a41106a200641086a290200370300200741d00a6a41186a200641106a290200370300200741f00a6a2008360200200741063602d40a20074195b7c5003602d00a200720062902003703d80a200728029c0121062007200741d8006a3602c8022007290358210a20072802a4012108200741d8026a200741186a41086a290300370300200741e0026a200741186a41106a290300370300200741e8026a200741186a41186a290300370300200720033703b802200720023703b002200720083602cc022007200a3703c002200720072903183703d0022007200b3602f801200720093703f00120074190026a2006200741d00a6a200741b0026a200741f0016a200410de012007419c026a290200210220074190026a41086a2802002112200728029402210f02402007280290024101470d002002422088a72106200741a4026a280200210b2002a7210120122105200f210e0c0a0b200728027041016a220b41004c0d072007200b360270200728027821040240024003402010280200220541086a210820052f0106220e41057421064100210c0240024003402006450d01200741386a20084120109d05220d450d02200641606a2106200c41016a210c200841206a2108200d417f4a0d000b200c417f6a210e0b2004450d022004417f6a21042005200e4102746a41880b6a21100c010b0b2005200c41e0006c6a220641c5036a310000200641e8026a290300220320035022081ba7450d004200200641f8026a29030020081b21034200200641f0026a29030020081b21090c010b2007200728028001200741386a20072802840128021c110200200741086a2903002103200729030021092007280270210b0b2007200b417f6a3602702009200728029801220629037854200320064180016a29030022095420032009511b450d082002a7210b41e089c100210e411e2105200f2101201221060c090b2009422088a721062009a7210141de96c500210e412a21050c090b41204101102e000b41c0004101102e000b4180014101102e000b41e898c5004110200741b0026a41a099c5001054000b41880b4108102e000b200728021421052009422088a721062009a721010c030b41f898c5004118200741b0026a419099c5001054000b20074190026a41086a2208200741186a41086a29030037030020074190026a41106a220c200741186a41106a29030037030020074190026a41186a220d200741186a41186a290300370300200741f0016a41086a2205200741386a41086a290300370300200741f0016a41106a2204200741386a41106a290300370300200741f0016a41186a220e200741386a41186a2903003703002007200729031837039002200720072903383703f00102400240024002402007280294012206200728029001470d00200641016a220b2006490d0320064101742210200b200b2010491b2210ad42b0017e2203422088a70d032003a7220b4100480d030240024020060d00200b103221060c010b200728028c01200641b0016c200b103421060b2006450d0120072010360290012007200636028c0120072802940121060b200728028c01200641b0016c6a220641003a0000200620072f00ed013b0001200641013a00102006410036000c200642013700042006200729039002370011200620072903f001370031200641036a200741ef016a2d00003a0000200641196a2008290300370000200641216a200c290300370000200641296a200d290300370000200641396a2005290300370000200641c1006a2004290300370000200641c9006a200e290300370000200641e0006a200741d7016a290000370000200641d9006a200741c8016a41086a290000370000200620072900c801370051200641e8006a200741b0026a41c800109b051a200720072802940141016a2208360294010240200741d00a6a41186a280200450d00200741e40a6a280200102920072802940121080b200728029001210e200728028c012105200728027c210b2007280278210d2007280274210602402007280264220c450d00200741e8006a280200450d00200c10290b0240024020024280808080f01f8350450d002007200b3602b8022007200d3602b402200720063602b0022011200741b0026a10df012007200e3602b402200720053602b00220072005200841b0016c22086a22043602bc0202400240200141386a280200220c2001413c6a28020022066b200841b0016d220d490d002001280234210c0c010b2006200d6a220e2006490d05200c4101742206200e200e2006491b2206ad42b0017e2203422088a70d052003a7220e4100480d0502400240200c0d00200e1032210c0c010b2001280234200c41b0016c200e1034210c0b200c450d042001200c360234200141386a20063602002001413c6a28020021060b200c200641b0016c6a20052008109b051a2001413c6a22062006280200200d6a360200200720043602b802200741b0026a10280c010b02402008450d00200841b0016c210441002108034002400240200520086a220c2d0000220141014b0d000240024020010e020001000b0240200c41086a280200450d00200c41046a28020010290b200c41106a2d00004105490d02200c41386a280200450d02200c41346a28020010290c020b200c41286a102a0c010b200c41e8006a280200450d00200c41e4006a28020010290b2004200841b0016a2208470d000b0b0240200e450d00200510290b02400240200d0d00200621080c010b200d210c20062108034020082802880b2108200c417f6a220c0d000b0340200620062f01064102746a41880b6a2802002106200d417f6a220d0d000b0b200741cc026a20062f0106360200200741c8026a4100360200200741c4026a20063602002007200b3602d002200741003602c002200742003703b802200720083602b402200741003602b002200741b0026a10cd010b20002007290338370004200041003602002000412c6a2002370200200041286a2012360200200041246a200f3602002000411c6a200741d0006a290300370000200041146a200741c8006a2903003700002000410c6a200741c0006a2903003700000c050b200b4108102e000b200e4108102e000b1033000b200741e80a6a280200450d00200741e40a6a28020010290b024020072802642208450d00200741e8006a280200450d00200810290b2006ad2102200728027c21042007280274210602400240200728027822080d002006210c0c010b2008210d2006210c0340200c2802880b210c200d417f6a220d0d000b0340200620062f01064102746a41880b6a28020021062008417f6a22080d000b0b200242208621022001ad2103200741cc026a20062f010636020041002108200741c8026a4100360200200741c4026a2006360200200720043602d002200741003602c002200742003703b8022007200c3602b402200741003602b002200741b0026a10cd0102402007280294012206450d00200728028c01210d200641b0016c2101034002400240200d20086a22062d0000220c41014b0d0002400240200c0e020001000b0240200641086a280200450d00200641046a28020010290b200641106a2d00004105490d02200641386a280200450d02200641346a28020010290c020b200641286a102a0c010b200641e8006a280200450d00200641e4006a28020010290b2001200841b0016a2208470d000b0b200220038421020240200728029001450d00200728028c0110290b2000200e36020420004101360200200041146a200b3602002000410c6a2002370200200041086a20053602000b200741b00d6a24000bb80201097f230041106b220224000240200028020041016a220341004c0d0020002003360200200041046a2104200041086a280200210502400240024003402004280200220641086a210720062f010622084105742104410021090240024003402004450d01200120074120109d05220a450d02200441606a2104200941016a2109200741206a2107200a417f4a0d000b2009417f6a21080b2005450d022005417f6a2105200620084102746a41880b6a21040c010b0b2006200941e0006c6a220441a4036a2d000022074101410220074101461b200441c5036a2d00001b22044102470d010b20002802102001200041146a2802002802181103002104200028020021030c010b200441014621040b20002003417f6a360200200241106a240020040f0b41f898c5004118200241086a419099c5001054000bb30d020b7f067e230041d0016b22082400024002400240024002400240200728021841016a220941004c0d00200741186a210a20072009360218200741206a280200210b2007411c6a220c210d024002400340200d280200220e41086a210f200e2f01062210410574210d41002111024002400340200d450d012004200f4120109d052212450d02200d41606a210d201141016a2111200f41206a210f2012417f4a0d000b2011417f6a21100b200b450d02200b417f6a210b200e20104102746a41880b6a210d0c010b0b200e201141e0006c6a220d41c5036a310000200d41e8026a2903002213201350220f1ba7450d004200200d41f8026a290300200f1b21144200200d41f0026a290300200f1b21150c010b200841286a200741286a28020020042007412c6a28020028021c110200200841306a290300211420072802182109200829032821150b20072009417f6a360218200141186a29030021132007280240210d20012903102116024002400240024041004101410220152014842217501b20021b0e03010200010b200d41a8016a210d0c020b200d4188016a210d0c010b200d4198016a210d0b20162013844200510d01200841186a200d290300200d41086a2903002016201310a10520014200200129030822132008290318427f200841186a41086a290300501b7d22162016201356220d1b3703080240200d450d0041a88ac100210d4122210f0c060b200a28020041016a220141004c0d02200720013602182007280220210b024002400340200c280200220e41086a210f200e2f01062210410574210d41002111024002400340200d450d012003200f4120109d052212450d02200d41606a210d201141016a2111200f41206a210f2012417f4a0d000b2011417f6a21100b200b450d02200b417f6a210b200e20104102746a41880b6a210c0c010b0b200e201141e0006c6a220d41c5036a310000200d41e8026a2903002213201350220f1ba7450d004200200d41f8026a290300200f1b21134200200d41f0026a290300200f1b21160c010b200841086a200741286a28020020032007412c6a28020028021c110200200841106a290300211320072802182101200829030821160b200a2001417f6a3602000240201620057d2218201656201320067d2016200554ad7d221620135620162013511b4101470d0041ca8ac100210d411d210f0c060b024020174200520d002007280240220d290378200556200d4180016a290300221320065620132006511b450d0041e78ac100210d411f210f0c060b2008200341022018201610ae0102402008280200220d450d002008280204210f0c060b0240201520057c2217201554220d201420067c200dad7c221320145420132014511b450d0041868bc100210d412d210f0c060b4100210d024020032004470d000c060b0240200320044120109d050d000c060b200a20032018201610e001200a20042017201310e001200841a8016a41086a2211200341086a290000370300200841a8016a41106a2212200341106a290000370300200841a8016a41186a220e200341186a29000037030020084188016a41086a220b200441086a29000037030020084188016a41106a2210200441106a29000037030020084188016a41186a2201200441186a290000370300200820032900003703a801200820042900003703880102402007413c6a280200220f200741386a280200470d00200f41016a220d200f490d05200f4101742204200d200d2004491b2204ad42b0017e2213422088a70d052013a722034100480d0502400240200f0d0020031032210d0c010b2007280234200f41b0016c20031034210d0b200d450d042007200d360234200741386a2004360200200728023c210f0b4100210d2007280234200f41b0016c6a220f41003a0000200f20082f00cd013b0001200f4200370008200f4101360004200f20082903a801370011200f200829038801370031200f41036a200841cf016a2d00003a0000200f41106a41003a0000200f41196a2011290300370000200f41216a2012290300370000200f41296a200e290300370000200f41396a200b290300370000200f41c1006a2010290300370000200f41c9006a2001290300370000200f2005370358200f41e0006a2006370300200f41d4006a20084181016a41036a280000360000200f200828008101360051200f41e8006a200841386a41c800109b051a2007200728023c41016a36023c0c050b41f898c5004118200841386a419099c5001054000b41dc97c500106d000b41f898c5004118200841386a419099c5001054000b20034108102e000b1033000b2000200f3602042000200d360200200841d0016a24000bbb1101117f230041a0016b2203240002400240024002400240024002400240024002400240411410322204450d00200441002900e5f943370000200441106a41002800f5f943360000200441086a41002900edf94337000020034294808080c00237027c200320043602782003200341f8006a3602582001200341d8006a108501200328027c2105200328027821062003280280012104200341f8006a41186a22074200370300200341f8006a41106a22084200370300200341f8006a41086a220942003703002003420037037820062004200341f8006a1000200341d8006a41186a2007290300370300200341d8006a41106a2008290300370300200341d8006a41086a20092903003703002003200329037837035820034100360278200341d8006a4120200341f8006a1006210a2003280278220b417f460d03200a450d032003200b36027c2003200a360278200341286a200341f8006a102c20032802280d02200328022c2107200341206a200341f8006a102c20032802200d0220032802242109200341186a200341f8006a102c20032802180d02200328027c2204450d02200328021c210c20032004417f6a36027c20032003280278220441016a36027820042d0000220441014b0d02410021080240024020040e020100010b410121080b200341106a200341f8006a102c20032802100d02200328027c220d20032802142204490d022004417f4c0d050240024020040d004101210e0c010b2004102d220e450d02200e2003280278220f2004109b051a2003200d20046b36027c2003200f20046a3602780b200e450d02200341d4006a41026a220d200341386a41026a2d00003a0000200320032f00383b01540240200b450d00200a10290b200341f8006a41026a200d2d00003a0000200320032f01543b01780c040b41144101102e000b20044101102e000b41f7cdc3004133200341386a41ecd6c3001054000b410221080b02402005450d00200610290b0240024020084102470d004101210641e5d8c2002107411121090c010b200341d8006a41026a200341f8006a41026a2d00003a0000200320032f01783b0158410021060b200341346a41026a200341d8006a41026a2d00003a0000200320032f01583b013402402006450d002000200736020420004101360200200041086a20093602000c060b200341d4006a41026a2205200341346a41026a2d00003a0000200320032f01343b015402400240200228025820074b0d002004210620042102200e210b0c010b411510322208450d0241002107200841002900d0f9433700002008410d6a41002900ddf943370000200841086a41002900d8f94337000020034295808080d00237027c200320083602782003200341f8006a3602582001200341d8006a108501200328027c2106200328027821082003280280012109200341f8006a41186a220a4200370300200341f8006a41106a220b4200370300200341f8006a41086a220c42003703002003420037037820082009200341f8006a1000200341d8006a41186a200a290300370300200341d8006a41106a200b290300370300200341d8006a41086a200c2903003703002003200329037837035820034100360278200341d8006a4120200341f8006a10062109024002402003280278220b417f470d00410021070c010b024020090d000c010b2003200b36027c20032009360278200341086a200341f8006a102c02400240024020032802080d00200328027c220c200328020c220a490d00200a417f4c0d0502400240200a0d00410121070c010b200a102d2207450d0220072003280278220d200a109b051a2003200c200a6b36027c2003200d200a6a3602780b20070d020b41f7cdc3004133200341386a41ecd6c3001054000b200a4101102e000b200b450d00200910290b02402006450d00200810290b024020070d00200041f6d8c20036020420004101360200200041086a411a3602000c060b2007410020071b210d200341f8006a2007200a200210c702200341f8006a41086a2802002109200328027c2107024020032802784101470d002000200736020420004101360200200041086a2009360200200a450d06200d10290c060b200341d8006a41026a220f20034197016a2d00003a0000200320032f0095013b015820034194016a2d0000210820034190016a28020021062003418c016a280200210220034188016a280200210b20034184016a280200210c02402004450d00200e10290b200341d4006a41026a200f2d00003a0000200320032f01583b01542006417f4c0d010240024020060d004100210e410121040c010b2006210e200610322204450d040b2004200b2006109b05210f200341386a41146a2006360200200341386a41106a200e3602002003200c3602402003200936023c200320073602382003200f3602442003200841ff01714101463a0050411410322204450d04200441002900e5f943370000200441106a41002800f5f943360000200441086a41002900edf94337000020034294808080c00237027c200320043602782003200341f8006a3602582001200341d8006a108501200328027c2101200328027821042003280280012110200341f8006a41186a22114200370300200341f8006a41106a22124200370300200341f8006a41086a221342003703002003420037037820042010200341f8006a1000200341d8006a41186a2011290300370300200341d8006a41106a2012290300370300200341d8006a41086a2013290300370300200320032903783703582003412036027c2003200341d8006a360278200341386a200341f8006a10c80202402001450d00200410290b0240200e450d00200f10290b200a450d00200d10290b20002007360204200020032f01543b001d200041003602002000411c6a20083a0000200041186a2006360200200041146a2002360200200041106a200b3602002000410c6a200c360200200041086a20093602002000411f6a20052d00003a00000c050b102f000b41154101102e000b20064101102e000b41144101102e000b2004450d00200e10290b200341a0016a24000beb3002097f017e230041c0006b22062400024002402002410c6a280200200241106a280200100c2207417f460d00410c103222080d01410c4104102e000b10cf02000b200820073602082008428180808010370200024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002404101450d002008410141016a3602004101417e460d0020084101410272360200410410322209450d01200920083602002008280208210a41031032220b450d02200b41026a41002d00fcd7453a0000200b41002f00fad7453b000041061032220c450d03200c41046a41002f00b6af443b0000200c41002800b2af44360000412010322207450d042007200a36021c2007410136021820074286808080e0003702102007200c36020c20074283808080303702042007200b36020020082008280200417f6a220b3602000240200b0d002008280208100d20082008280204417f6a220b360204200b0d00200810290b41031032220b450d05200b41026a41002d00fcd7453a0000200b41002f00fad7453b000041031032220c450d06200c41026a41002d00ffd7453a0000200c41002f00fdd7453b00002007412041c00010342207450d072007410836023c2007410036023820074283808080303702302007200c36022c20074283808080303702242007200b36022041031032220b450d08200b41026a41002d00fcd7453a0000200b41002f00fad7453b0000410f1032220c450d09200c41076a41002900a7af45370000200c41002900a0af45370000200741c00041800110342207450d0a2007410936025c200741003602582007428f808080f0013702502007200c36024c20074283808080303702442007200b36024041031032220b450d0b200b41026a41002d00fcd7453a0000200b41002f00fad7453b0000410f1032220c450d0c200c41076a41002900b6af45370000200c41002900afaf453700002007410a36027c200741003602782007428f808080f0013702702007200c36026c20074283808080303702642007200b36026041031032220b450d0d200b41026a41002d00fcd7453a0000200b41002f00fad7453b000041081032220c450d0e200c42e5f0d1fbb5ac98b6ec00370000200741800141800210342207450d0f2007410b36029c012007410036029801200742888080808001370290012007200c36028c012007428380808030370284012007200b3602800141031032220b450d10200b41026a41002d00fcd7453a0000200b41002f00fad7453b0000410a1032220c450d11200c41086a41002f00ceaf453b0000200c41002900c6af453700002007410c3602bc01200741003602b8012007428a808080a0013702b0012007200c3602ac0120074283808080303702a4012007200b3602a00141031032220b450d12200b41026a41002d00fcd7453a0000200b41002f00fad7453b0000410a1032220c450d13200c41086a41002f00d8af453b0000200c41002900d0af453700002007410d3602dc01200741003602d8012007428a808080a0013702d0012007200c3602cc0120074283808080303702c4012007200b3602c00141031032220b450d14200b41026a41002d00fcd7453a0000200b41002f00fad7453b0000410a1032220c450d15200c41086a41002f00e2af453b0000200c41002900daaf453700002007410e3602fc01200741003602f8012007428a808080a0013702f0012007200c3602ec0120074283808080303702e4012007200b3602e00141031032220b450d16200b41026a41002d00fcd7453a0000200b41002f00fad7453b0000410b1032220c450d17200c41076a41002800ebaf45360000200c41002900e4af45370000200741800241800410342207450d182007410f36029c0220074100360298022007428b808080b001370290022007200c36028c022007428380808030370284022007200b3602800241031032220b450d19200b41026a41002d00fcd7453a0000200b41002f00fad7453b0000410d1032220c450d1a200c41056a41002900f4af45370000200c41002900efaf45370000200741103602bc02200741003602b8022007428d808080d0013702b0022007200c3602ac0220074283808080303702a4022007200b3602a00241031032220b450d1b200b41026a41002d00fcd7453a0000200b41002f00fad7453b0000410c1032220c450d1c200c41086a4100280084b045360000200c41002900fcaf45370000200741113602dc02200741003602d8022007428c808080c0013702d0022007200c3602cc0220074283808080303702c4022007200b3602c00241031032220b450d1d200b41026a41002d00fcd7453a0000200b41002f00fad7453b0000410b1032220c450d1e200c41076a410028008fb045360000200c4100290088b045370000200741123602fc02200741003602f8022007428b808080b0013702f0022007200c3602ec0220074283808080303702e4022007200b3602e00241031032220c450d1f200c41026a41002d00fcd7453a0000200c41002f00fad7453b000041151032220b450d20200b410d6a41002900a0b045370000200b41086a410029009bb045370000200b4100290093b0453700002007411336029c03200741003602980320074295808080d002370290032007200b36028c032007428380808030370284032007200c3602800341031032220b450d21200b41026a41002d00fcd7453a0000200b41002f00fad7453b0000410a1032220c450d22200c41086a41002f00b0b0453b0000200c41002900a8b045370000200741143602bc03200741003602b8032007428a808080a0013702b0032007200c3602ac0320074283808080303702a4032007200b3602a00341031032220b450d23200b41026a41002d00fcd7453a0000200b41002f00fad7453b000041071032220c450d24200c41036a41002800b5b045360000200c41002800b2b045360000200741153602dc03200741003602d80320074287808080f0003702d0032007200c3602cc0320074283808080303702c4032007200b3602c00341031032220c450d25200c41026a41002d00fcd7453a0000200c41002f00fad7453b000041111032220b450d26200b41106a41002d00c9b0453a0000200b41086a41002900c1b045370000200b41002900b9b045370000200741163602fc03200741003602f8032007429180808090023702f0032007200b3602ec0320074283808080303702e4032007200c3602e00341031032220b450d27200b41026a41002d00fcd7453a0000200b41002f00fad7453b0000410e1032220c450d28200c41066a41002900d0b045370000200c41002900cab04537000020074180044180081034220a450d29200a411736029c04200a410036029804200a428e808080e00137029004200a200c36028c04200a42838080803037028404200a200b36028004410310322207450d2a200741026a41002d00fcd7453a0000200741002f00fad7453b000041101032220b450d2b200b41086a41002900e0b045370000200b41002900d8b045370000200a41183602bc04200a41003602b804200a429080808080023702b004200a200b3602ac04200a4283808080303702a404200a20073602a004410310322207450d2c200741026a41002d00fcd7453a0000200741002f00fad7453b000041101032220b450d2d200b41086a41002900f0b045370000200b41002900e8b045370000200a41193602dc04200a41003602d804200a429080808080023702d004200a200b3602cc04200a4283808080303702c404200a20073602c00441031032220b450d2e200b41026a41002d00fcd7453a0000200b41002f00fad7453b0000411110322207450d2f200741106a41002d0088b1453a0000200741086a4100290080b145370000200741002900f8b045370000200a411a3602fc04200a41003602f804200a429180808090023702f004200a20073602ec04200a4283808080303702e404200a200b3602e00441031032220b450d30200b41026a41002d00fcd7453a0000200b41002f00fad7453b0000411110322207450d31200741106a41002d0099b1453a0000200741086a4100290091b14537000020074100290089b145370000200a411b36029c05200a410036029805200a4291808080900237029005200a200736028c05200a42838080803037028405200a200b3602800541031032220b450d32200b41026a41002d00fcd7453a0000200b41002f00fad7453b0000411610322207450d332007410e6a41002900a8b145370000200741086a41002900a2b1453700002007410029009ab145370000200a411c3602bc05200a41003602b805200a4296808080e0023702b005200a20073602ac05200a4283808080303702a405200a200b3602a00541031032220b450d34200b41026a41002d00fcd7453a0000200b41002f00fad7453b0000411210322207450d35200741106a41002f00c0b1453b0000200741086a41002900b8b145370000200741002900b0b145370000200a411d3602dc05200a41003602d805200a4292808080a0023702d005200a20073602cc05200a4283808080303702c405200a200b3602c005410310322207450d36200741026a41002d00fcd7453a0000200741002f00fad7453b0000410b1032220b450d37200b41076a41002800c9b145360000200b41002900c2b145370000200a411e3602fc05200a41003602f805200a428b808080b0013702f005200a200b3602ec05200a4283808080303702e405200a20073602e005410310322207450d38200741026a41002d00fcd7453a0000200741002f00fad7453b000041101032220b450d39200b41086a41002900d5b145370000200b41002900cdb145370000200a411f36029c06200a410036029806200a4290808080800237029006200a200b36028c06200a42838080803037028406200a2007360280062006410c6a200441086a280200360200200620033602002006410036021c20062005360218200620083602142006200429020037020420062001280200360210200241146a280200210d2002411c6a280200210e20064100360238200642013703304119200641306a1066410021030340200a20036a220b2802002104200b41086a2802002207200641306a1066024002402006280234220c200628023822086b2007490d002006280230210c0c010b200820076a22012008490d41200c4101742205200120012005491b22014100480d4102400240200c0d0020011032210c0c010b2006280230200c20011034210c0b200c450d3c200620013602342006200c3602300b2006200820076a360238200c20086a20042007109b051a200b410c6a2802002105200b41146a280200220c200641306a10660240024020062802342208200628023822016b200c490d00200628023021070c010b2001200c6a22072001490d4120084101742204200720072004491b22044100480d410240024020080d002004103221070c010b200628023020082004103421070b2007450d3d2006200436023420062007360230200421080b20062001200c6a2204360238200720016a2005200c109b051a02400240200b41186a2802004101460d000240024020082004460d002008210c0c010b200841016a220c2008490d4320084101742201200c200c2001491b220c4100480d430240024020080d00200c103221070c010b20072008200c103421070b2007450d402006200c360234200620073602300b2006200441016a2208360238200720046a41013a00002006200b411c6a280200220b360228200641286a21040c010b0240024020082004460d002008210c0c010b200841016a220c2008490d4220084101742201200c200c2001491b220c4100480d420240024020080d00200c103221070c010b20072008200c103421070b2007450d402006200c360234200620073602300b2006200441016a2208360238200720046a41023a00002006200b411c6a280200220b360228200641286a21040b0240200c20086b41034b0d00200841046a220b2008490d41200c4101742201200b200b2001491b220b4100480d4102400240200c0d00200b103221070c010b2007200c200b103421070b2007450d402006200b360234200620073602302004280200210b0b2006200841046a360238200720086a200b360000200341206a220341a006470d000b2006280234210702404120200d200e2006280230220420062802382006100e220b41036a220841024b0d004100210c0240024020080e03000201000b4102210c0b41012101024020070d000c450b200410290c440b410410322208450d402009280200220c28020041016a220141014d0d00200c20013602002008200c36020002402007450d00200410290b200228020421042002280200210120064100360238200642013703304100200641306a106620062802382103200628023421022006280230210c410a102d2207450d410240024002400240200b20012004200c20032007410a2006100f41036a220441034b0d004101210120040e0402000001020b41d4dcc200106d000b2006410936022c410121012006200741016a36022820072d0000220441014b0d01410421030240024020040e020100010b200641306a200641286a10e902200628023022034104460d02200628023421050b410021010b200710292002450d43200c10290c430b20071029024020020d000c430b200c10290c420b00000b41044104102e000b41034101102e000b41064101102e000b41204104102e000b41034101102e000b41034101102e000b41c0004104102e000b41034101102e000b410f4101102e000b4180014104102e000b41034101102e000b410f4101102e000b41034101102e000b41084101102e000b4180024104102e000b41034101102e000b410a4101102e000b41034101102e000b410a4101102e000b41034101102e000b410a4101102e000b41034101102e000b410b4101102e000b4180044104102e000b41034101102e000b410d4101102e000b41034101102e000b410c4101102e000b41034101102e000b410b4101102e000b41034101102e000b41154101102e000b41034101102e000b410a4101102e000b41034101102e000b41074101102e000b41034101102e000b41114101102e000b41034101102e000b410e4101102e000b4180084104102e000b41034101102e000b41104101102e000b41034101102e000b41104101102e000b41034101102e000b41114101102e000b41034101102e000b41114101102e000b41034101102e000b41164101102e000b41034101102e000b41124101102e000b41034101102e000b410b4101102e000b41034101102e000b41104101102e000b20014101102e000b20044101102e000b200c4101102e000b200c4101102e000b200b4101102e000b1033000b41044104102e000b410a4101102e000b200b1010200828020022072007280200417f6a3602000240200828020022072802000d002007280208100d200828020022072007280204417f6a360204200828020022072802040d00200710290b200810294102210c0b200641086a2802002108200628021421072006280204210b024002400240024002400240024002400240200628021c22040d002006410c6a290200210f20010d04200341044b0d0320030e050203030301020b2000200436020420004100360200200041106a41003a0000200041086a200641206a29030037020002402008450d00200b10290b20072007280200417f6a220836020020080d072007280208100d20072007280204417f6a22083602042008450d060c070b2000200b3602044100210b200041106a41003a00002000410c6a4100360200200041086a20083602000c040b2000200b360204200041106a20053a00002000410c6a200f3e0200200041086a20083602004100210b0c030b200041e7a7c500360204200041146a200f3e0200200041106a20083602002000410c6a200b360200200041086a41113602000c010b0240200c450d0020004188a8c500360204200041146a200f3e0200200041106a20083602002000410c6a200b360200200041086a41103602000c010b200041f8a7c500360204200041146a200f3e0200200041106a20083602002000410c6a200b360200200041086a41103602000b4101210b0b2000200b36020020072007280200417f6a220836020020080d012007280208100d20072007280204417f6a220836020420080d010b200710290b4100210803400240200a20086a220741046a280200450d00200728020010290b0240200741106a280200450d002007410c6a28020010290b200841206a220841a006470d000b200a1029200928020022072007280200417f6a3602000240200928020022072802000d002007280208100d200928020022072007280204417f6a360204200928020022072802040d00200710290b20091029200641c0006a24000b8a1409057f017e0c7f047e037f017e037f047e097f230041f00c6b22022400024020002802000d002000417f360200200128020821032001280200210402400240200128020422050d00200421010c010b2005210620042101034020012802880b21012006417f6a22060d000b0340200420042f01064102746a41880b6a28020021042005417f6a22050d000b0b2002411c6a20042f0106360200200241186a4100360200200241146a20043602002002200336022020024100360210200242003703082002200136020420024100360200200241f0016a200210c601024020022903900222074202510d002000410c6a2108200041046a2109200241900a6a41146a210a200241900a6a41206a210b200241f0016a4104722103200241f0016a413d6a210c200241cd026a210d200241b8026a210e200241f0016a41306a210f200241f0016a41286a21100340200241c8006a41086a2204200241f0016a41086a2211290300370300200241c8006a41106a2201200241f0016a41106a2212290300370300200241c8006a41186a2205200241f0016a41186a2213290300370300200220022903f001370348200e2903002114200f290300211520022903b0022116200229039802211720022f01ee02211820022d00ed02211920022d00cc02211a20022903a802211b20022802c002211c20022802c402211d20022802c802211e200241286a41186a200d41186a290000221f370300200241286a41106a200d41106a2900002220370300200241286a41086a200d41086a29000022213703002002200d2900002222370328200241e8006a41186a2223201f370300200241e8006a41106a22242020370300200241e8006a41086a222520213703002002202237036820024188016a41186a2226200529030037030020024188016a41106a2227200129030037030020024188016a41086a222820042903003703002002200229034837038801024002400240024002402009280200222941b0d6c000460d002000280208212a0c010b200241900a6a410041e002109a051a200241f0016a410041a008109a051a41880b10322229450d014100212a202941003b010620294100360200202941086a200241900a6a41e002109b051a202941e8026a200241f0016a41a008109b051a20004100360208200020293602040b0340202941086a210120292f0106222b410574210441002105024003402004450d0120024188016a20014120109d052206450d04200441606a2104200541016a2105200141206a21012006417f4a0d000b2005417f6a212b0b0240202a450d00202a417f6a212a2029202b4102746a41880b6a28020021290c010b0b200241c0016a41186a2026290300221f370300200241c0016a41106a20272903002220370300200241c0016a41086a20282903002221370300200220022903880122223703c001200a2022370200200a41086a2021370200200a41106a2020370200200a41186a201f370200200220083602a00a2002202b36029c0a200220093602980a200220293602940a200241003602900a20102014370300201220153703002002201637039002200220173703f8012002201a3a00ac022002201e3602a8022002201d3602a4022002201c3602a0022002201b37038802200220073703f001200c2002290368370000200c41086a2025290300370000200c41106a2024290300370000200c41186a2023290300370000200220183b01ce02200220193a00cd02200241900a6a200241f0016a10c8011a0c020b41880b4108102e000b202941e8026a200541e0006c6a2129024020194101710d0020292029290300200720075022041b37030020292029290308201720041b370308202941106a22012001290300201520041b370300200241900a6a41186a22062023290300370300200241900a6a41106a222a2024290300370300200241900a6a41086a222b2025290300370300200220022903683703900a20292d003c21012013202941d5006a22052900003703002012202941cd006a22192900003703002011202941c5006a222329000037030020022029413d6a22242900003703f0012028200241900a6a200241f0016a201a41ff0171410146221a1b220441086a2900003703002027200441106a2900003703002026200441186a2900003703002002200429000037038801202941012001201a1b3a003c2024200229038801370000202320282903003700002019202729030037000020052026290300370000202920162029290320201ba722041b370320202941286a22012014200129030020041b3703002029201b202929031820041b37031802400240201d0d00201c21040c010b201d2101201c2104034020042802ec0321042001417f6a22010d000b0340201c201c2f01064102746a41ec036a280200211c201d417f6a221d0d000b0b201c2f010621012002201e3602a801200220013602a401200241003602a0012002201c36029c01200241003602980120024200370390012002200436028c012002410036028801200241f0016a20024188016a10c701024020022802f0014101470d00202941306a211c0340200241900a6a41286a200341286a280200360200200b200341206a2902003703002006200341186a2204290200370300202a200341106a2201290200370300202b200341086a2205290200370300200220032902003703900a200241c0016a41186a2004290000370300200241c0016a41106a2001290000370300200241c0016a41086a2005290000370300200220032900003703c001200241e0016a41086a200b41086a2802003602002002200b2902003703e001200241b0016a201c200241c0016a200241e0016a10cb01024020022802b001450d0020022802b4012204450d0020022802b801450d00200410290b200241f0016a20024188016a10c70120022802f0014101460d000b0b20024188016a10c9010c010b202941386a212b202941306a212a202928023821262029280230210402400240202941346a28020022050d00200421010c010b2005210620042101034020012802ec0321012006417f6a22060d000b0340200420042f01064102746a41ec036a28020021042005417f6a22050d000b0b200220263602900220024100360288022002410036028002200242003703f801200220013602f401200241003602f0012002200436028402200220042f010636028c02200241f0016a10c901202941286a201437030020292016370320202941106a2015370300202920173703082029201b37031820292007370300202a201d360204202a201c360200202b201e3602002029201a3a003c2029413d6a2002290368370000202941c5006a2025290300370000202941cd006a2024290300370000202941d5006a2023290300370000202920183b015e202920193a005d0b200241f0016a200210c60120022903900222074202520d000b0b200210cd012000200028020041016a360200200241f00c6a24000f0b41e898c5004110200241f0016a41a099c5001054000ba50701087f230041d00b6b220424000240024020002802000d002000417f360200200441206a41186a200141186a290000370300200441206a41106a200141106a290000370300200441206a41086a200141086a29000037030020042001290000370320024002402000280204220541b0d6c000460d00200041086a28020021060c010b41002106200441f0086a410041e002109a051a200441d0006a410041a008109a051a41880b10322205450d02200541003b010620054100360200200541086a200441f0086a41e002109b051a200541e8026a200441d0006a41a008109b051a200041086a4100360200200020053602040b200041046a210702400240034020052f010622084105742109410021014100210a02400240034020092001460d01200441206a200520016a41086a4120109d05220b450d02200141206a2101200a41016a210a200b417f4a0d000b200a417f6a21080b2006450d022006417f6a2106200520084102746a41880b6a28020021050c010b0b2000410c6a210b410121010c010b200441186a200441206a41186a290300370300200441106a200441206a41106a290300370300200441086a200441206a41086a290300370300200420042903203703002000410c6a210b410021062008210a410021010b0240024020010d002004418c096a200441086a29030037020020044194096a200441106a2903003702002004419c096a200441186a2903003702002004200b360280092004200a3602fc08200420073602f808200420053602f408200420063602f0082004200429030037028409200441f0006a2004290340370300200441f8006a200441c0006a41086a29030037030020044184016a42003702002004420037036820044200370350200441b0d6c00036028001200441003a008c012004418d016a200429002037000020044195016a200441206a41086a2900003700002004419d016a200441206a41106a290000370000200441a5016a200441206a41186a290000370000200441003a00ad01200441f0086a200441d0006a10c80121010c010b200441e8006a4200370300200441e4006a41b0d6c000360200200441003602702004410036026020044200370358200441b0d6c000360254200441003602502005200a41e0006c6a41e8026a2101200441d0006a10c9010b200141106a200337030020012002370308200142013703002000200028020041016a360200200441d00b6a24000f0b41e898c5004110200441d0006a41a099c5001054000b41880b4108102e000bc50101057f230041306b220124002000410c6a28020021022000280204210302400240200041086a28020022040d00200321000c010b2004210520032100034020002802880b21002005417f6a22050d000b0340200320032f01064102746a41880b6a28020021032004417f6a22040d000b0b200141246a20032f0106360200200141206a41003602002001411c6a20033602002001200236022820014100360218200142003703102001200036020c20014100360208200141086a10cd01200141306a24000bf02b03037f027e0d7f230022072108200741800f6b41607122072400200720043703382007200337033020072005360244024002400240024002402001280230200128024022092802b801460d00200542002005290308220a200941386a2903007d220b200b200a5622091b37030820090d0120074180046a20024100410110e301200741a4046a280200210c200741a0046a280200210d20072d008804220541037122094103460d0220090e03030203030b200041b38bc10036020420004101360200200041086a41293602002000410c6a2006290200370200200041146a200641086a2802003602000c030b200041dc8bc10036020420004101360200200041086a41233602002000410c6a2006290200370200200041146a200641086a280200360200200824000f0b200041ff8bc10036020420004101360200200041086a41193602002000410c6a2006290200370200200041146a200641086a28020036020020050d01200c450d01200d1029200824000f0b200741a8046a2802002109200741e0006a200141e8006a290000370300200741d8006a200141e0006a290000370300200741c8006a41086a200141d8006a290000370300200720012900503703484100210e02400240024002400240024002400240024002400240024002400240024002400240024002400240200541024d0d000c010b024020050e03000102000b2009417f4c0d020240024020090d0020074200370380044101210e0c010b20091032220e450d04200741003602840420072009360280040b2007200936028404200e200d2009109b051a200729038004210a200c450d00200d10290b200741306a41086a2903002104200729033021030b200741a4016a410036020020074194016a41bc89c100360200200741e8006a41206a420037030020074184016a41b0d6c000360200200741e8006a41106a200a370300200741c0016a200241086a290000370300200741c8016a200241106a290000370300200741d0016a200241186a29000037030020072001360270200741e8006a41286a200141186a220f3602002007420837029c0120074100360280012007200e360274200720022900003703b801200720012802483602b001200720012903403703a8012007200128023041016a360298012001290300210a2007200128024c3602b4012007200a370368200741d8016a41206a200741c8006a41086a290300370300200741d8016a41286a200741c8006a41106a29030037030020074188026a200741c8006a41186a290300370300200741ec016a200641086a280200360200200720023602e001200720072903483703f001200720062902003702e4012007200741c4006a3602dc012007200741306a3602d801200741d8016a41186a21100240024002400240200320048450450d00410021060c010b200741286a200728024441002010200220032004200741e8006a10dc01200728022822060d01200728028001210620072802e00121020b200641016a221141004c0d04200741e4016a21122007201136028001200741e8006a41206a280200210c20074184016a2213210602400240024003402006280200220d41086a2105200d2f010622144105742106410021090240024003402006450d01200220054120109d05220e450d02200641606a2106200941016a2109200541206a2105200e417f4a0d000b2009417f6a21140b200c450d02200c417f6a210c200d20144102746a41880b6a21060c010b0b200d200941e0006c6a220541e8026a210602400240200541c5036a2d00000d0020074180046a41086a2209200641c5006a29000037030020074180046a41106a220e200641cd006a29000037030020074180046a41186a220d200641d5006a29000037030020072006413d6a290000370380044102210520062d003c4101470d01200741a00c6a41186a200d290300370300200741a00c6a41106a200e290300370300200741a00c6a41086a200929030037030020072007290380043703a00c410121050c010b200741a80c6a200641c5006a290000370300200741b00c6a200641cd006a290000370300200741b80c6a200641d5006a29000037030020072006413d6a2900003703a00c20062d003c21050b200541ff01714102470d010b20074190026a2007280290012002200728029401280210110200200728028001211120072d00900221050c010b20074199026a200741a80c6a290300370000200741a1026a200741b00c6a290300370000200741a9026a200741b80c6a290300370000200720053a009002200720072903a00c370091020b20072011417f6a36028001410121140240200541ff01714101470d00200741b8026a41186a200741a9026a290000370300200741b8026a41106a200741a1026a290000370300200741b8026a41086a20074199026a29000037030020072007290091023703b80220074180046a200741b8026a20072802b00128020010dd0102402007280280044101470d0020072f00e901200741eb016a2d000041107472210d20074180046a41086a28020021052007280284042106200741d8016a41106a2d00002109200741ec016a280200210c0c030b200741a00c6a41186a220520074180046a410472220641186a2802002209360200200741d8026a41106a200641086a290200370300200741d8026a41186a200641106a290200370300200741f8026a2009360200200741043602dc0220074191b7c5003602d802200720062902003703e00220072802ac0121062005201041186a2900002203370300200741a00c6a41106a201041106a2900002204370300200741a00c6a41086a2205201041086a290000220a370300200741a8046a200a370300200741b0046a2004370300200741b8046a20033703002007201029000022033703a00c200720033703a00420072802d801220941086a29030021032007200741e8006a36029804200929030021042007290368210a20072802b4012109200720033703880420072004370380042007200936029c042007200a370390042005201241086a280200360200200720122902003703a00c200741e0036a2006200741d8026a20074180046a200741a00c6a20072802dc0128020010de01200741e0036a41086a280200211120072802e4032114024020072802e0034101470d0020072f00f103200741f3036a2d000041107472210d200741f4036a280200210c200741e0036a41106a2d00002109200741ec036a280200210e20112105201421060c130b20072802800141016a221541004c0d062011410876210d20072f00f103200741f3036a2d0000411074722110200741e0036a41106a2d00002112200741ec036a280200210c20072802e001210220072015360280012007280288012116201321060240024003402006280200221741086a210520172f010622184105742106410021090240024003402006450d01200220054120109d05220e450d02200641606a2106200941016a2109200541206a2105200e417f4a0d000b2009417f6a21180b2016450d022016417f6a2116201720184102746a41880b6a21060c010b0b2017200941e0006c6a220641c5036a310000200641e8026a290300220320035022051ba7450d004200200641f8026a29030020051b21034200200641f0026a29030020051b21040c010b200741186a200728029001200220072802940128021c110200200741206a29030021032007290318210420072802800121150b20072015417f6a221736028001200420072802a801220629037854200320064180016a29030022045420032004511b0d090c0a0b200741e8016a2802000d060c070b200728022c210520072f00e901200741eb016a2d000041107472210d200741ec016a280200210c200741d8016a41106a2d000021090b20072802e401210e0c100b102f000b20094101102e000b41f898c500411820074180046a419099c5001054000b41f898c500411820074180046a419099c5001054000b20072802e40110290b410021124100210c410021110c020b20072802702209450d0241988cc10021064137210520072802e001220e200941d0006a2202460d072002200e4120109d05450d070240034020092802082209450d01200e200941d0006a2202460d092002200e4120109d05450d090c000b0b20170d032007417f36028001200741003a00bc03200742003702b403200741013a009d03200741b0d6c0003602b003200741e0036a41186a200e41186a290000370300200741e0036a41106a200e41106a290000370300200741e0036a41086a200e41086a2900003703002007200e2900003703e00302400240200728028401220e41b0d6c000460d00200728028801210d0c010b200741a00c6a410041e002109a051a20074180046a410041a008109a051a41880b1032220e450d054100210d200e41003b0106200e4100360200200e41086a200741a00c6a41e002109b051a200e41e8026a20074180046a41a008109b051a20074100360288012007200e360284010b024002400340200e2f010622174105742102410021064100210502400240034020022006460d01200741e0036a200e20066a41086a4120109d052209450d02200641206a2106200541016a21052009417f4a0d000b2005417f6a21170b200d450d02200d417f6a210d200e20174102746a41880b6a280200210e0c010b0b200e200541e0006c6a22064190036a20072903a80337030020064188036a20072903a003370300200641c0036a200729039803370000200641b8036a200729039003370000200641b0036a200729038803370000200641a8036a20072903800337000020064180036a4200370300200641e8026a2205290300210420054200370300200641a0036a22052802002102200520072903b80337030020064198036a22062903002103200620072903b0033703002003a721062003422088a721050c010b200741c0036a41186a200741e0036a41186a2903002203370300200741c0036a41106a200741e0036a41106a2903002204370300200741c0036a41086a200741e0036a41086a290300220a370300200720072903e003220b3703c003200741bc0c6a200a370200200741a00c6a41246a2004370200200741cc0c6a20033702002007200741e8006a41246a3602b00c200720173602ac0c200720133602a80c2007200e3602a40c200741003602a00c2007200b3702b40c20074180046a41186a42003703002007420037038004200741b8046a20072903b803370300200741b0046a20072903b003370300200741a8046a20072903a803370300200741a0046a20072903a003370300200741d8046a200729039803370300200741d0046a200729039003370300200741c8046a200729038803370300200741c0046a200729038003370300200741a00c6a20074180046a10c8011a420221040b024020044202510d000240024020050d00200621090c010b2005210e20062109034020092802ec032109200e417f6a220e0d000b0340200620062f01064102746a41ec036a28020021062005417f6a22050d000b0b2007419c046a20062f010636020020074198046a410036020020074194046a2006360200200720023602a004200741003602900420074200370388042007200936028404200741003602800420074180046a10c9010b200720072802800141016a360280010b200741f0026a280200450d00200741ec026a28020010290b20072802a401210520072802a0012113200728029c01210d200728028c012117200728028801210e2007280284012106024020072802742209450d00200741f8006a280200450d00200910290b02400240201241ff01710d0020072017360288042007200e360284042007200636028004200f20074180046a10df0120072013360284042007200d360280042007200d200541b0016c22056a220236028c0402400240200141386a28020022092001413c6a28020022066b200541b0016d220e490d00200128023421090c010b2006200e6a220f2006490d0720094101742206200f200f2006491b2206ad42b0017e2203422088a70d072003a7220f4100480d070240024020090d00200f103221090c010b2001280234200941b0016c200f103421090b2009450d0620012009360234200141386a20063602002001413c6a28020021060b2009200641b0016c6a200d2005109b051a2001413c6a22062006280200200e6a360200200720023602880420074180046a1028200041136a20104110763a0000200041116a20103b0000200041106a41003a00002000410c6a200c360200200041086a2011360200200020143602040c010b20002014360204200041136a20104110763a0000200041116a20103b0000200041106a20123a00002000410c6a200c360200200041086a201136020002402005450d00200541b0016c210141002105034002400240200d20056a22092d0000220241014b0d000240024020020e020001000b0240200941086a280200450d00200941046a28020010290b200941106a2d00004105490d02200941386a280200450d02200941346a28020010290c020b200941286a102a0c010b200941e8006a280200450d00200941e4006a28020010290b2001200541b0016a2205470d000b0b02402013450d00200d10290b02400240200e0d00200621050c010b200e210920062105034020052802880b21052009417f6a22090d000b0340200620062f01064102746a41880b6a2802002106200e417f6a220e0d000b0b2007419c046a20062f010636020020074198046a410036020020074194046a2006360200200720173602a004200741003602900420074200370388042007200536028404200741003602800420074180046a10cd010b20004100360200200824000f0b41cf8cc1004132109201000b41e898c500411020074180046a41a099c5001054000b41880b4108102e000b200f4108102e000b1033000b201121092014210e0b200741f0026a280200450d00200741ec026a28020010290b2000200636020420004101360200200041136a200d4110763a0000200041116a200d3b0000200041146a200c360200200041106a20093a00002000410c6a200e360200200041086a2005360200024020072802742206450d00200741e8006a41106a280200450d00200610290b200741e8006a411c6a2802002106200728028c01210e0240024020072802880122050d00200621000c010b2005210920062100034020002802880b21002009417f6a22090d000b0340200620062f01064102746a41880b6a28020021062005417f6a22050d000b0b20074180046a411c6a20062f01063602004100210520074198046a410036020020074194046a20063602002007200e3602a004200741003602900420074200370388042007200036028404200741003602800420074180046a10cd01024020072802a4012206450d00200728029c012109200641b0016c210e034002400240200920056a22062d0000220041014b0d000240024020000e020001000b0240200641086a280200450d00200641046a28020010290b200641106a2d00004105490d02200641386a280200450d02200641346a28020010290c020b200641286a102a0c010b200641e8006a280200450d00200641e4006a28020010290b200e200541b0016a2205470d000b0b20072802a001450d00200728029c011029200824000f0b200824000be11404057f027e0a7f077e23004180036b22042400200441e0006a20011096020240024020042d00602205417f6a41ff017141024f0d00200041003a0000200041086a200441e0006a41d800109b051a0c010b200441b8016a41086a2206200441e0006a413c6a290200370300200441b8016a41106a2207200441e0006a41c4006a290200370300200441b8016a41186a2208200441e0006a41cc006a2902003703002004200441e0006a41346a2902003703b801200441e0006a41106a2903002109200441e0006a41086a290300210a200441e0006a41306a280200210b200441e0006a412c6a280200210c200441e0006a41246a280200210d200441e0006a41206a280200210e200441fc006a280200210f200441e0006a41186a2802002110200441e0006a41d4006a2802002111200441e0006a41286a2802002112200441d8006a41d983c300410d105d0240024002400240024002400240024002400240024041004100200428025c410020042802581b221320026b2202200220134b1b220220126b2214201420024b1b2214450d00200441c8006a200110be01200441386a20042903482215200441c8006a41086a290300221642e807420010a1054200200dad2217200429033822187d221920192017564200200441386a41086a2903002017201854ad7c7d22174200522017501b22021b22184200201720021b221784500d042015429080e983b1de165441002016501b0d01200441206a201842028620174202862018423e88842014ad420010a005200441306a2001410842002015201542f0ff96fccea1697c2217200a200a201756200920162017201554ad7c427f7c22175620092017511b22021b22182004290320221920182019542017200920021b2218200441206a41086a29030022175420182017511b22021b221a7d221b201b20155620162018201720021b22187d2015201a54ad7d221520165620152016511b22141b4200201520141b10ae010240024020042802300d000240024020020d002003450d010b20044198026a2001201a2018410810ad012004280298024101460d0820044198026a41106a290300211820044198026a41086a2214290300211520144200370300200442003703980241c2d5c000411620044198026a1003200441f8016a41086a2207201429030037030020042004290398023703f801200441086a200441f8016a10eb01200441086a41106a29030021162004290310211a2004280208210620144200370300200442003703980241c2d5c000411620044198026a10032007201429030037030020042004290398023703f801200442002016420020061b221620187d201a420020061b2218201554ad7d221a201820157d2215201856201a201656201a2016511b22141b3703a00220044200201520141b37039802200441f8016a411020044198026a411010050b20020d0020030d01200041003a0008200041023a0000200041186a2009370000200041106a200a370000200041386a200b360000200041346a200c360000200041306a20123600002000412c6a200d360000200041286a200e360000200041246a200f360000200041206a20103600002000413c6a20042903b801370000200041c4006a200441c0016a290300370000200041cc006a200441b8016a41106a290300370000200041d4006a200441b8016a41186a290300370000200041dc006a2011360000200541037122004103460d0520000e030d05050d0b20044100360298022010200e20044198026a100a21142004280298022213417f460d07200441f8016a41186a200441b8016a41186a290300370300200441f8016a41106a200441b8016a41106a290300370300200441f8016a41086a200441b8016a41086a290300370300200420042903b8013703f801200441003602f802200442013703f00220142013200441f0026a1097020240024020042802f402220320042802f802220d6b4120490d00200d41206a211220042802f00221020c010b200d41206a2212200d490d0a20034101742202201220122002491b220b4100480d0a0240024020030d00200b103221020c010b20042802f0022003200b103421020b2002450d092004200b3602f402200420023602f002200b21030b200420123602f8022002200d6a220d20042903f801370000200d41086a200441f8016a41086a290300370000200d41106a200441f8016a41106a290300370000200d41186a200441f8016a41186a29030037000020044198026a41186a220d420037030020044198026a41106a220b420037030020044198026a41086a220c420037030020044200370398022002201220044198026a1000200441d8016a41186a2212200d290300370300200441d8016a41106a220d200b290300370300200441d8016a41086a220b200c29030037030020042004290398023703d80102402003450d00200210290b200441b1026a2012290300370000200441a9026a200d290300370000200441a1026a200b290300370000200420042903d80137009902200441013a009802200120044198026a1098022010200e1008200041013a0000200041086a20044198026a41d800109b051a2013450d03201410290c030b200441c8026a200b360200200441c4026a200c360200200441c0026a2013360200200441bc026a200d360200200441b8026a200e360200200441b4026a200f36020020044198026a41186a2010360200200441cc026a20042903b801370200200441d4026a200441b8016a41086a290300370200200441dc026a200441b8016a41106a290300370200200441e4026a200441b8016a41186a29030037020020044198026a41106a200920177d200a201954ad7d370300200441003a0098022004200a20197d3703a002200120044198026a109802200041023a0000200041086a20044198026a41d800109b051a0c090b200041003a0008200041003a0000200041186a2009370000200041106a200a370000200041386a200b360000200041346a200c360000200041306a20123600002000412c6a200d360000200041286a200e360000200041246a200f360000200041206a20103600002000413c6a20042903b801370000200041c4006a2006290300370000200041cc006a2007290300370000200041d4006a2008290300370000200041dc006a20113600000c080b20011099022010200e1008200041023a0008200041013a00000b200f450d06201010290c060b200f450d070c060b200041003a0008200041003a0000200041186a2009370000200041106a200a370000200041386a200b360000200041346a200c360000200041306a20123600002000412c6a200d360000200041286a200e360000200041246a200f360000200041206a20103600002000413c6a20042903b801370000200041c4006a200441c0016a290300370000200041cc006a200441b8016a41106a290300370000200041d4006a200441b8016a41186a290300370000200041dc006a20113600000c040b2004200429029c023703f80141d8ddc10041fe00200441f8016a41d8dec1001054000b41d0f8c5004138109201000b200b4101102e000b1033000b0240200541037122004103460d0020000e03020000020b200f450d010b201010290b20044180036a24000b130020004101360204200041848dc1003602000b3400200041b5d8c20036020420004100360200200041146a4103360200200041106a41c08ec100360200200041086a42083702000bc60301047f230041106b22032400200341003602082003420137030020012003106602400240024002402001450d00200141216c210403400240024020002d00004101460d0002400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d0720014101742206200520052006491b22064100480d070240024020010d002006103221050c010b200328020020012006103421050b2005450d052003200636020420032005360200200328020821010b2003200141016a360208200520016a41003a00000c010b02400240200328020420032802082201460d00200328020021050c010b200141016a22052001490d0620014101742206200520052006491b22064100480d060240024020010d002006103221050c010b200328020020012006103421050b2005450d052003200636020420032005360200200328020821010b2003200141016a360208200520016a41013a0000200041016a20031081010b200041216a21002004415f6a22040d000b0b2003280204210020022802002002280204200328020022012003280208100502402000450d00200110290b200341106a24000f0b20064101102e000b20064101102e000b1033000b970301067f230041106b22022400024002400240024002400240024002400240200128020022030d00410121040c010b0240200141086a28020041056a2204417f4c0d0020040d0120024100360208200242013703000c020b102f000b200410322205450d03200241003602082002200436020420022005360200024020030d00200541003a0000200241013602080c030b20040d010b410110322205450d0320024101360204200220053602000b200541013a000020024101360208200141086a2802002204200210660240024020022802042201200228020822056b2004490d00200228020021010c010b200520046a22062005490d0520014101742207200620062007491b22064100480d050240024020010d002006103221010c010b200228020020012006103421010b2001450d0420022006360204200220013602000b2002200520046a360208200120056a20032004109b051a0b20002002290300370200200041086a200241086a280200360200200241106a24000f0b20044101102e000b41014101102e000b20064101102e000b1033000bfb0101077f230041106b220124002001410036020820014201370300200110e80120012802042102200128020021030240024002400240200041046a2802002204200041086a28020022056b20012802082206490d00200028020021040c010b200520066a22072005490d0220044101742205200720072005491b22054100480d020240024020040d002005103221040c010b200028020020042005103421040b2004450d0120002004360200200041046a2005360200200041086a28020021050b200041086a200520066a360200200420056a20032006109b051a02402002450d00200310290b200141106a24000f0b20054101102e000b1033000baa4d06037f027e0e7f027e027f047e230041c0046b22012400200141a8036a41086a22024200370300200142003703a80341ddb1c5004111200141a8036a1003200141c8036a41086a22032002290300370300200120012903a8033703c803200141c8036a411010040240024002400240024002400240024002400240024002400240024020004180e101700d00200141c8036a10b401200141a8016a200141c8036a10be012001200141a8016a41086a29030022043703c001200120012903a80122053703b801200141e0036a2004370300200141c8036a41106a2005370300200341013a00002001410b3a00c80341014100200141c8036a104c200141003a00cf01200142003703d801200142003703d001200141c8026a41086a22034200370300200142003703c8024183abc5004112200141c8026a100320022003290300370300200120012903c8023703a803200141003602c803200141a8036a4110200141c8036a1006210302400240024020012802c8032206417f460d002003450d00200120063602e401200120033602e001200141c8036a200141e0016a103c024020012802c8032207450d00200141d0036a280200210820012802cc03210902402006450d00200310290b4100210a2007410420071b210b200745210c2008410020071b2207450d03200141d1036a210d20014188036a210e200141c8026a41206a210f200141e0016a41086a211020014180046a2111410021124100210a4100210302400240024003400240024002400240200a450d00200b20034102746a2106200b200320126a4102746a21080340200320074f0d02200141e0016a2006280200221310ea0120012903e0014201520d04200141c8026a201041e000109b051a20012903b801221420012903c802221554200141b8016a41086a2903002204200141c8026a41086a29030022055420042005511b450d03200141013a00cf010240201220036a221320074f0d0020082006280200360200200641046a2106200841046a2108200341016a22032007490d010c070b0b419481c000201320071036000b200b20034102746a21060340200320074f0d01200141e0016a2006280200221310ea0120012903e0014201520d03200141c8026a201041e000109b051a20012903b801221420012903c80222155a200141b8016a41086a2903002204200141c8026a41086a29030022055a20042005511b0d02200641046a2106200141013a00cf01200341016a22032007490d000c0a0b0b41b880c000200320071036000b2001201420157d3703b8012001200420057d2014201554ad7d3703c001411210322206450d03200641106a41002f0093bd413b0000200641086a410029008bbd4137000020064100290083bd4137000020064112412410342206450d0420062013360012200141c8036a41186a22084200370300200141c8036a41106a22164200370300200141c8036a41086a22174200370300200142003703c80320064116200141c8036a1000200141a8036a41186a2008290300370300200141a8036a41106a2016290300370300200141a8036a41086a2017290300370300200120012903c8033703a803200141a8036a4120100420061029200f20012903d802200141c8026a41186a290300105320014198016a200e20012903c802200141c8026a41086a220629030010a001200141d0016a41086a2208427f2008290300220420014198016a41086a2903007c20012903d00122052001290398017c22142005542208ad7c22052008200520045420052004511b22081b3703002001427f201420081b3703d00120012903c802210420112006290300370300200d200e290000370000200d41086a200e41086a290000370000200d41106a200e41106a290000370000200d41186a200e41186a290000370000200120043703f803200141023a00d0032001410b3a00c803200120133602f40341014100200141c8036a104c0b2012417f6a2112200a41016a210a200341016a22032007490d000b0b200a450d05200720034d0d05200b20034102746a2206200a4102746b2006200720036b410274109c051a0c050b41124101102e000b41244101102e000b41f7cdc3004133200141b8046a41ecd6c3001054000b4101210c410021074104210b0b4100210a0b200141c8026a41086a22034200370300200142003703c8024183abc5004112200141c8026a1003200141a8036a41086a2003290300370300200120012903c8023703a803200141003602d003200142013703c8032007200a6b2203200141c8036a10660240024020030d0020012802d003210720012802cc03211320012802c80321060c010b2007410274200a4102746b210a20012802cc03211320012802d0032103410021080340200b20086a280200211002400240201320036b4104490d00200341046a210720012802c80321060c010b200341046a22072003490d0e20134101742206200720072006491b22124100480d0e0240024020130d002012103221060c010b20012802c80320132012103421060b2006450d04200120123602cc03200120063602c803201221130b200120073602d003200620036a201036000020072103200a200841046a2208470d000b0b200141a8036a411020062007100502402013450d00200610290b0240200c200945720d00200b10290b024020012d00cf010d00200141f0006a20012903b8012204200141b8016a41086a2203290300220542c0843d420010a105200141e0006a20012903702214200141f0006a41086a290300221542c0fb42427f10a005200141d0006a2014201542a0c21e420010a005200320052005200141d0006a41086a29030020012903502214200420012903607c42018842ffffffff0f837c2215201454ad7c22142015200456201420055620142005511b22071b22147d20042004201520071b220554ad7d3703002001200420057d3703b801200141c8026a41086a22034200370300200142003703c80241c2d5c0004116200141c8026a1003200141a8036a41086a22062003290300370300200120012903c8023703a80320014180016a200141a8036a10eb0120014180016a41106a29030021042001290388012115200128028001210720034200370300200142003703c80241c2d5c0004116200141c8026a100320062003290300370300200120012903c8023703a803200142002004420020071b220420147d2015420020071b2215200554ad7d2218201520057d2219201556201820045620182004511b22031b3703d00320014200201920031b3703c803200141a8036a4110200141c8036a41101005200141d0016a41086a2207427f200729030022182004201420031b7c20012903d00122042015200520031b7c22152004542203ad7c22042003200420185420042018511b22031b3703002001427f201520031b3703d001200141e0036a2014370300200141c8036a41106a2005370300200141c8036a41086a41033a00002001410b3a00c80341014100200141c8036a104c0b200141c8036a10b401200141e0016a200141c8036a20012903d0012204200141d0016a41086a2903002205410210ad010240024020012802e0010d00200141e0016a41106a290300211520012903e8012114200141206a41c2d5c000411610a301200520157d2004201454ad7d201520057d2014200454ad7d20142004582015200558201520055122031b22071b211a200420147d201420047d20071b211b200141206a41106a2903004200200128022022071b21182001290328420020071b2119024002402014200456201520055620031b0d00200141c8026a41086a22034200370300200142003703c80241c2d5c0004116200141c8026a1003200141a8036a41086a2003290300370300200120012903c8023703a8032001427f2018201a7c2019201b7c22052019542203ad7c22042003200420185420042018511b22031b3703d0022001427f200520031b3703c802200141c8026a21030c010b200141c8026a41086a22034200370300200142003703c80241c2d5c0004116200141c8026a1003200141a8036a41086a2003290300370300200120012903c8023703a803200142002018201a7d2019201b54ad7d22042019201b7d2205201956200420185620042018511b22031b3703d00220014200200520031b3703c802200141c8026a21030b200141a8036a41102003411010050c010b41abdac10041ca001009200141c8026a41086a22034200370300200142003703c80241c2d5c0004116200141c8026a1003200141a8036a41086a22062003290300370300200120012903c8023703a803200141386a200141a8036a10eb01200141386a41106a2903002114200129034021152001280238210720034200370300200142003703c80241c2d5c0004116200141c8026a100320062003290300370300200120012903c8023703a8032001427f2014420020071b221420057c2015420020071b220520047c22152005542203ad7c22042003200420145420042014511b22031b3703e8012001427f201520031b3703e001200141a8036a4110200141e0016a411010050b20012903b8012104200141e0036a200141b8016a41086a290300370300200141d8036a2004370300200141c8036a41086a41043a00002001410b3a00c80341014100200141c8036a104c0b20024200370300200142003703a80341f9d9c100411d200141a8036a1003200141c8026a41086a2002290300370300200120012903a8033703c802200141003602c803200141c8026a4110200141c8036a10062103024020012802c8032207417f460d002003450d00200120033602e001200120073602e40120074104490d062001200341046a3602e00120012007417c6a22063602e40120064104490d06200328000021132001200741786a3602e4012001200341086a3602e0012003280004210b200141c8036a200141e0016a104020012802c8032212450d0620012902cc032118410021080240024020012802e40122070d000c010b20012007417f6a22103602e401200120012802e001220641016a3602e001024020062d00004101460d000c010b20104104490d0020012007417b6a3602e4012001200641056a3602e0012006280001210a410121080b200310292018422088a72110024020132000470d00024020080d002010ad42287e2204422088a70d042004a72203417f4c0d040240024020030d004108210a0c010b20031032220a450d060b4100210602402010450d00201041286c210841002106200a2103201221070340200741086a2903002104200741106a2903002105200741186a290300211420072903002115200341206a200741206a290300370300200341186a2014370300200341106a2005370300200341086a200437030020032015370300200341286a2103200641016a2106200741286a2107200841586a22080d000b0b200141f0016a200b360200200141e0016a410c6a2006360200200141e0016a41086a20103602002001200a3602e401200141003602e001200141c8036a200141e0016a10ec01200141d3026a200141c8036a41086a280200360000200120012903c8033700cb02200141c8036a410c6a200141cf026a290000370000200141c6a4b9da043600c903200141023a00c803200120012900c8023700cd03200141c8036a10ed012010450d01200a10290c010b2010ad42287e2204422088a70d032004a72203417f4c0d030240024020030d00410821020c010b200310322202450d060b0240024020100d00410021060c010b201041286c21084100210620022103201221070340200741086a2903002104200741106a2903002105200741186a290300211420072903002115200341206a200741206a290300370300200341186a2014370300200341106a2005370300200341086a200437030020032015370300200341286a2103200641016a2106200741286a2107200841586a22080d000b0b200141f4016a200b360200200141f0016a2006360200200141e0016a410c6a2010360200200141e0016a41086a20023602002001200a3602e401200141013602e001200141c8036a200141e0016a10ec01200141d3026a200141c8036a41086a280200360000200120012903c8033700cb02200141c8036a410c6a200141cf026a290000370000200141c6a4b9da043600c903200141023a00c803200120012900c8023700cd03200141c8036a10ed012010450d00200210290b2018a7210a0240200b20136a2000470d00200141a8036a41086a22034200370300200142003703a80341beeec500411b200141a8036a1003200141c8026a41086a2003290300370300200120012903a8033703c802200141003602d003200142013703c8032010200141c8036a106602402010450d002012201041286c6a21132012210703402007200141c8036a10ee01200741206a29030021040240024020012802cc03220620012802d00322036b4108490d0020012802c80321060c010b200341086a22082003490d0f20064101742203200820082003491b22034100480d0f0240024020060d002003103221060c010b20012802c80320062003103421060b2006450d09200120033602cc03200120063602c80320012802d00321030b2001200341086a3602d003200620036a20043700002013200741286a2207470d000b0b20012802cc032103200141c8026a411020012802c803220720012802d003100502402003450d00200710290b200141c8036a41106a2010360200200141d4036a200a360200200141c8036a41086a2012360200200141003602cc032001410a3a00c80341014100200141c8036a104c200141a8036a41086a22034200370300200142003703a80341f9d9c100411d200141a8036a1003200141c8026a41086a2003290300370300200120012903a8033703c802200141c8026a411010040c010b200a450d00201210290b200141a8036a41086a22034200370300200142003703a8034196dac1004115200141a8036a1003200141c8026a41086a2003290300370300200120012903a8033703c802200141003602c803200141c8026a4110200141c8036a1006210320012802c8032207417f460d092003450d092007450d0820032d0000220641034b0d080240024020060e0401090100010b2007417f6a41074b0d070c090b200310290c090b20124101102e000b102f000b20034108102e000b20034108102e000b20034101102e000b41f7cdc3004133200141b8046a41ecd6c3001054000b200328000521062003280001210720031029024020072000470d00200141043602e001200120063602e401200141c8036a200141e0016a10ec01200141d3026a200141d0036a280200360000200120012903c8033700cb02200141d4036a200141cf026a290000370000200141c6a4b9da043600c903200141023a00c803200120012900c8023700cd03200141c8036a10ed010b200620076a2000470d02200141003602e001200141a8036a41086a22034200370300200142003703a8034196dac1004115200141a8036a1003200141c8026a41086a2003290300370300200120012903a8033703c802200141c8036a200141e0016a10ef01200141c8026a411020012802c803220320012802d0031005024020012802cc03450d00200310290b200141023602cc032001410a3a00c80341014100200141c8036a104c0c020b2007417f6a4108490d00200328000521062003280001210720031029024020072000470d00200141033602e001200120063602e401200141c8036a200141e0016a10ec01200141d3026a200141d0036a280200360000200120012903c8033700cb02200141d4036a200141cf026a290000370000200141c6a4b9da043600c903200141023a00c803200120012900c8023700cd03200141c8036a10ed010b200620076a2000470d01200141023602e001200141a8036a41086a22034200370300200142003703a8034196dac1004115200141a8036a1003200141c8026a41086a2003290300370300200120012903a8033703c802200141c8036a200141e0016a10ef01200141c8026a411020012802c803220320012802d0031005024020012802cc03450d00200310290b200141013602cc032001410a3a00c80341014100200141c8036a104c0c010b41f7cdc3004133200141b8046a41ecd6c3001054000b200141a8036a41086a22034200370300200142003703a80341f9bac1004110200141a8036a1003200141c8026a41086a22072003290300370300200120012903a8033703c802200141186a200141c8026a10f001200128021c21022001280218211320034200370300200142003703a8034191efc5004115200141a8036a100320072003290300370300200120012903a8033703c802200141003602c803200141c8026a4110200141c8036a10062103024002400240024002400240024002400240024020012802c8032207417f460d002003450d002007450d0720032d000021072003102920074102460d0020074101710d010b410410322207450d0120074100360200200141a8036a41086a22034200370300200142003703a803419fbbc1004115200141a8036a1003200141c8026a41086a2003290300370300200120012903a8033703c802200141003602d003200142013703c8034101200141c8036a1066200728020021100240024020012802cc03220820012802d00322066b4104490d0020012802c80321030c010b200641046a22032006490d0a20084101742212200320032012491b22124100480d0a0240024020080d002012103221030c010b20012802c80320082012103421030b2003450d03200120123602cc03200120033602c803201221080b2001200641046a22123602d003200320066a2010360000200141c8026a411020032012100502402008450d00200310290b20071029410410322207450d0320074100360200200141a8036a41086a22034200370300200142003703a80341e6b2c2004116200141a8036a1003200141c8026a41086a2003290300370300200120012903a8033703c802200141003602d003200142013703c8034101200141c8036a1066200728020021100240024020012802cc03220820012802d00322066b4104490d0020012802c80321030c010b200641046a22032006490d0a20084101742212200320032012491b22124100480d0a0240024020080d002012103221030c010b20012802c80320082012103421030b2003450d05200120123602cc03200120033602c803201221080b2001200641046a22123602d003200320066a2010360000200141c8026a411020032012100502402008450d00200310290b20071029200141a8036a41086a22034200370300200142003703a80341fcb2c2004110200141a8036a1003200141c8026a41086a22072003290300370300200120012903a8033703c802200141003602c803200141c8026a4110200141c8036a41041005200141013a00c80320034200370300200142003703a8034191efc5004115200141a8036a100320072003290300370300200120012903a8033703c802200141c8026a4110200141c8036a410110050b200141a8036a41086a22034200370300200142003703a803419fbbc1004115200141a8036a1003200141c8026a41086a2003290300370300200120012903a8033703c8024100210c200141003602c803200141c8026a4110200141c8036a1006210320012802c8032206417f460d062003450d06200120063602e401200120033602e001200141c8036a200141e0016a103c20012802c803220c450d04200141d0036a280200210720012802cc0321162006450d07200310290c070b41044104102e000b20124101102e000b41044104102e000b20124101102e000b41f7cdc3004133200141b8046a41ecd6c3001054000b41f7cdc3004133200141b8046a41ecd6c3001054000b0b200141a8036a41086a22034200370300200142003703a80341e6b2c2004116200141a8036a1003200141c8026a41086a2003290300370300200120012903a8033703c802200141003602c803200141c8026a4110200141c8036a100621030240024020012802c8032208417f460d002003450d00200120083602e401200120033602e001200141c8036a200141e0016a103c024020012802c803220e450d00200141d0036a280200210620012802cc0321112008450d02200310290c020b41f7cdc3004133200141b8046a41ecd6c3001054000b4100210e0b20074100200c1b2100200c4104200c1b210902400240024002400240024020130d002000417f6a220320004f0d01200320004b0d01200920034102746a28020021020b200041002000419c7f6a22032003200041016a4b1b220d490d0120064100200e1b2112200e4104200e1b21102000200d6b210f200d450d042009200d4102746a210a2009210b0340200b280200211302400240024002400240201241014b0d004100210320120e020201020b4100210320122107034020032007410176220620036a22082013201020084102746a280200491b2103200720066b220741014b0d000b0b2013201020034102746a22072802002206460d022003201320064b6a21030c010b410021030b200120033602c80341b2b3c200412e200141c8036a41e0b3c2001054000b201220034d0d032007200741046a2003417f7320126a410274109c051a2012417f6a2112200b41046a220b200a460d040c000b0b418cb3c2004126109201000b41fcd8c500106d000b418080c000106d000b200f450d00200d450d002009200a200f410274109c051a0b41002103024002400240024002400240024002400240024002400240201241014b0d0020120e020201020b20122107034020032007410176220620036a22082002201020084102746a280200491b2103200720066b220741014b0d000b0b02402002201020034102746a2802002207460d002003200220074b6a21030b20122003490d010b201220114100200e1b2207460d01200721110c020b41b0d9c500106d000b200741016a22062007490d0720074101742208200620062008491b221141ffffffff03712011470d07201141027422064100480d070240024020070d002006103221100c010b201020074102742006103421100b2010450d010b201020034102746a220741046a2007201220036b410274109c051a2007200236020002400240200f20164100200c1b2203460d0020032116200f21030c010b200341016a22072003490d0720034101742206200720072006491b221641ffffffff03712016470d07201641027422074100480d070240024020030d002007103221090c010b200920034102742007103421090b2009450d020b200920034102746a20023602000240201241016a220c0d0041f0b3c200106d000b200c200c41017622034d0d02201020034102746a280200210e0240200c4101710d00200c2003417f6a22034d0d04201020034102746a280200200e6a410176210e0b200141a8036a41086a22034200370300200142003703a803419fbbc1004115200141a8036a1003200141c8026a41086a2003290300370300200120012903a8033703c802200141003602d003200142013703c803200f41016a220f200141c8036a106602400240200f0d0020012802d003210b20012802cc03211320012802c80321070c010b2000410274200d4102746b41046a210a410020012802d00322036b210620012802cc0321132009210803402008280200210202400240201320066a4104490d0020012802c80321070c010b200341046a22072003490d092013410174220b20072007200b491b220b4100480d090240024020130d00200b103221070c010b20012802c8032013200b103421070b2007450d072001200b3602cc03200120073602c803200b21130b200841046a21082001200341046a220b3602d003200720036a20023600002006417c6a2106200b2103200a417c6a220a0d000b0b200141c8026a41102007200b100502402013450d00200710290b02402016450d00200910290b200141a8036a41086a22034200370300200142003703a80341e6b2c2004116200141a8036a1003200141c8026a41086a2003290300370300200120012903a8033703c802200142013703c803200141003602d003200c200141c8036a1066201241027441046a2112410020012802d00322036b210620012802cc0321132010210803402008280200210a02400240201320066a4104490d0020012802c80321070c010b200341046a22072003490d082013410174220b20072007200b491b220b4100480d080240024020130d00200b103221070c010b20012802c8032013200b103421070b2007450d072001200b3602cc03200120073602c803200b21130b200841046a21082001200341046a220b3602d003200720036a200a3600002006417c6a2106200b21032012417c6a22120d000b200141c8026a41102007200b100502402013450d00200710290b02402011450d00201010290b200141a8036a41086a22034200370300200142003703a80341fcb2c2004110200141a8036a1003200141c8026a41086a2003290300370300200120012903a8033703c8022001200e3602c803200141c8026a4110200141c8036a410410050240200f41e500470d00200141106a41d983c300410d105d200e419a086a2001280214410020012802101b4b0d00200141a8036a41086a22074200370300200142003703a8034188b4c2004117200141a8036a1003200141c8026a41086a2007290300370300200120012903a8033703c802410810322207450d082007200e360004200741e400360000200141c8026a4110200741081005200710290b20034200370300200142003703a80341f2bdc4004117200141a8036a1003200141c8036a41086a2003290300370300200120012903a8033703c8030240200141c8036a41104101410041001007417f470d00200141cc83c300410d10d5012001290308210420012802002103200141a8036a41086a22074200370300200142003703a80341f2bdc4004117200141a8036a1003200141c8036a41086a2007290300370300200120012903a8033703c80320012004420020031b3703e001200141c8036a4110200141e0016a410810050b200141a8036a41086a22034200370300200142003703a80341aedbc2004111200141a8036a1003200141c8036a41086a22072003290300370300200120012903a8033703c803200141c8036a4110100420034200370300200142003703a80341b6aec5004117200141a8036a100320072003290300370300200120012903a8033703c803200141c8036a4110100441ddf4c500411310f101220341ff01714102460d082003410171450d08200141a8036a41086a22034200370300200142003703a80341e4f0c5004110200141a8036a1003200141c8036a41086a2003290300370300200120012903a8033703c803200141c8036a41101004200141c0046a24000f0b20064104102e000b20074104102e000b4198dbc1002003200c1036000b4198dbc1002003200c1036000b200b4101102e000b200b4101102e000b1033000b41084101102e000b41f0fbc200106d000ba70201047f23004190016b2202240002400240411210322203450d00200341106a41002f0093bd413b0000200341086a410029008bbd4137000020034100290083bd4137000020034112412410342203450d0120032001360012200241086a41186a22014200370300200241086a41106a22044200370300200241086a41086a220542003703002002420037030820034116200241086a1000200241f0006a41186a2001290300370300200241f0006a41106a2004290300370300200241f0006a41086a200529030037030020022002290308370370200241086a200241f0006a1086020240024020022903084201510d00200042003703000c010b2000200241086a41e800109b051a0b2003102920024190016a24000f0b41124101102e000b41244101102e000b920102027f037e230041106b220224002002410036020420014110200241046a1006210102400240024020022802042203417f470d00420021040c010b20034110490d01200141086a29000021052001290000210620011029420121040b2000200637030820002004370300200041106a2005370300200241106a24000f0b41f7cdc3004133200241086a41ecd6c3001054000be00d03047f017e027f230041106b2202240020024100360208200242013703000240024002400240024002400240024002400240024002400240024002402001280200220341044b0d000240024002400240024020030e050001020304000b410110322203450d05200242818080801037020420022003360200200341013a0000200128020421042001410c6a28020022032002106602402003450d002004200341286c6a210503402004200210ee01200441206a29030021060240024020022802042207200228020822036b4108490d00200228020021070c010b200341086a22082003490d1520074101742203200820082003491b22034100480d150240024020070d002003103221070c010b200228020020072003103421070b2007450d092002200336020420022007360200200228020821030b2002200341086a360208200720036a20063700002005200441286a2204470d000b0b200141106a28020021070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d1320044101742203200820082003491b22034100480d130240024020040d002003103221040c010b200228020020042003103421040b2004450d082002200336020420022004360200200228020821030b2002200341046a360208200420036a20073600000c040b410110322203450d07200242818080801037020420022003360200200341023a0000200128020421070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d1220044101742205200820082005491b22084100480d120240024020040d002008103221040c010b200228020020042008103421040b2004450d0920022008360204200220043602000b2002200341046a360208200420036a200736000020012802082104200141106a28020022032002106602402003450d002004200341286c6a210503402004200210ee01200441206a29030021060240024020022802042207200228020822036b4108490d00200228020021070c010b200341086a22082003490d1420074101742203200820082003491b22034100480d140240024020070d002003103221070c010b200228020020072003103421070b2007450d0c2002200336020420022007360200200228020821030b2002200341086a360208200720036a20063700002005200441286a2204470d000b0b200141146a28020021070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d1220044101742203200820082003491b22034100480d120240024020040d002003103221040c010b200228020020042003103421040b2004450d0b2002200336020420022004360200200228020821030b2002200341046a360208200420036a20073600000c030b410110322203450d0a200242818080801037020420022003360200200341033a0000200141086a29030021060240024020022802042207200228020822036b4108490d00200341086a2104200228020021070c010b200341086a22042003490d1120074101742208200420042008491b22084100480d110240024020070d002008103221070c010b200228020020072008103421070b2007450d0c20022008360204200220073602000b20022004360208200720036a20063700000c020b410110322203450d0b200242818080801037020420022003360200200341043a0000200128020421070240024020022802042204200228020822036b4104490d00200228020021040c010b200341046a22082003490d1020044101742201200820082001491b22084100480d100240024020040d002008103221040c010b200228020020042008103421040b2004450d0d20022008360204200220043602000b2002200341046a360208200420036a20073600000c010b410110322203450d0c200242818080801037020420022003360200200341053a0000200128020421080240024020022802042207200228020822036b4104490d00200341046a2104200228020021070c010b200341046a22042003490d0f20074101742201200420042001491b22014100480d0f0240024020070d002001103221070c010b200228020020072001103421070b2007450d0e20022001360204200220073602000b20022004360208200720036a20083600000b20002002290300370200200041086a200241086a280200360200200241106a24000f0b41014101102e000b20034101102e000b20034101102e000b41014101102e000b20084101102e000b20034101102e000b20034101102e000b41014101102e000b20084101102e000b41014101102e000b20084101102e000b41014101102e000b20014101102e000b1033000bba0604017f017e047f027e230041c0006b2201240042002102200141186a41086a220342003703002001420037031841fb83c300410d200141186a1003200141086a200329030037030020012001290318370300410021032001410036021820014110200141186a100621040240024002400240024020012802182205417f460d002001200536021420012004360210200141186a200141106a103d20012802182206450d02200129021c210202402005450d00200410290b2002422088a721032002a721050c010b41042106410021050b200141186a41206a200041206a280200360200200141186a41186a200041186a290200370300200141186a41106a200041106a290200370300200141186a41086a200041086a29020037030020012000290200370318024020032005470d00024020032002a7470d00200341016a22002003490d0420034101742205200020002005491bad220742247e2208422088a70d042008a722004100480d040240024020030d002000103221060c010b2006200341246c2000103421060b2006450d0320024280808080708320078421020b2002422088a721030b2006200341246c22056a22002001290318370200200041206a200141186a41206a280200360200200041186a200141186a41186a290300370200200041106a200141186a41106a290300370200200041086a200141186a41086a2200290300370200200042003703002001420037031841fb83c300410d200141186a1003200141086a2000290300370300200120012903183703002001411036021c200120013602182006200341016a2200200141186a10b801024020002003490d00200541246a21002006210303400240024020032d0000220541034b0d0002400240024020050e0404000102040b2003410c6a280200450d03200341086a28020010290c030b2003410c6a280200450d02200341086a28020010290c020b2003410c6a280200450d01200341086a28020010290c010b200341086a280200450d00200341046a28020010290b200341246a21032000415c6a22000d000b0b02402002a7450d00200610290b200141c0006a24000f0b41f7cdc3004133200141186a41ecd6c3001054000b20004104102e000b1033000b952801057f02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2202280200200141086a22032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00003a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00013a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00023a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00033a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00043a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00053a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00063a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00073a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00083a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00093a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d0f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000e3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1020012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000f3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00103a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00113a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00123a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00133a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00143a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00153a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00163a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00173a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00183a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00193a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2120044101742206200520052006491b22064100480d210240024020040d002006103221050c010b200128020020042006103421050b2005450d1f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001e3a000002400240200228020020032802002202460d00200128020021040c010b200241016a22042002490d2120024101742205200420042005491b22054100480d210240024020020d002005103221040c010b200128020020022005103421040b2004450d2020012004360200200141046a2005360200200141086a28020021020b2003200241016a360200200420026a20002d001f3a00000f0b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20054101102e000b1033000bd60201037f0240024002400240024002400240024002400240024002400240024020012802000e0400010203000b41012102410110322201450d05200141003a0000410121030c040b410110322202450d05200241013a00002001280204210320024101410510342202450d062002200336000120012802082104410a210320024105410a10342201450d07200120043600050c020b41012102410110322201450d07200141023a0000410121030c020b410110322202450d07200241033a00002001280204210320024101410510342202450d082002200336000120012802082104410a210320024105410a10342201450d09200120043600050b410921020b2000200236020820002003360204200020013602000f0b41014101102e000b41014101102e000b41054101102e000b410a4101102e000b41014101102e000b41014101102e000b41054101102e000b410a4101102e000b8b0101047f230041106b22022400410021032002410036020420014110200241046a1006210402400240024020022802042205417f470d000c010b024020040d000c010b20054104490d012004280000210520041029200141101004410121030b2000200336020020002005360204200241106a24000f0b41f7cdc3004133200241086a41ecd6c3001054000ba80101027f230041206b22022400200241106a41086a220342003703002002420037031020002001200241106a1003200241086a2003290300370300200220022903103703002002410036021020024110200241106a1006210002400240024020022802102201417f470d00410221010c010b2001450d0120002d00002101200010292002411010040b200241206a240020010f0b41f7cdc3004133200241106a41ecd6c3001054000b4d01017f230041206b22002400200041146a4101360200200042013702042000418c9ac5003602002000410536021c200041c09ac5003602182000200041186a360210200041b086c100107d000b130020004101360204200041a094c1003602000b3400200041c4d7c20036020420004100360200200041146a410b360200200041106a41e496c100360200200041086a42043702000b3001017f02404102103222020d0041024101102e000b20024181023b00002000428280808020370204200020023602000b130020004102360204200041e8adc1003602000b3101017f02404108103222020d0041084101102e000b20004288808080800137020420002002360200200242b8173700000b3101017f02404108103222020d0041084101102e000b20004288808080800137020420002002360200200242c8013700000b130020004101360204200041f4bdc1003602000b3400200041f4bec10036020420004100360200200041146a4107360200200041106a4184bfc100360200200041086a420f3702000b2201017f230041106b22022400200241003602002000200210ef01200241106a24000bdc0805037f037e027f017e017f23004180016b220724002004a7210802400240024002400240024020014201510d0041012109024020084101460d00427f200320067c200220057c220a2002542208ad7c220b2008200b200354200b2003511b22081b210b427f200a20081b210a4200210c4100210d0c040b2002200556200320065620032006511b450d01200320067d2002200554ad7d210b200220057d210a4200210c0c020b4101210d024020084101470d00427f200320067c200220057c22012002542208ad7c22022008200220035420022003511b22081b210b427f200120081b210a410021094201210c0c040b200741306a20042005200642012002200310fc01200741c0006a290300210b2007290338210a2007290330210c0c040b200620037d2005200254ad7d210b200520027d210a4201210c0b410021094101210d0b2001500d00200741f0006a41086a220842003703002007420037037041c2d5c0004116200741f0006a1003200741e0006a41086a220e200829030037030020072007290370370360200741c8006a200741e0006a10eb01200741c8006a41106a29030021012007290350210f20072802482110200842003703002007420037037041c2d5c0004116200741f0006a1003200e200829030037030020072007290370370360200742002001420020101b220120037d200f420020101b2203200254ad7d220f200320027d2202200356200f200156200f2001511b22081b37037820074200200220081b370370200741e0006a4110200741f0006a411010050b02402004500d002009450d01200741f0006a41086a220842003703002007420037037041c2d5c0004116200741f0006a1003200741e0006a41086a220d200829030037030020072007290370370360200741186a200741e0006a10eb01200741186a41106a29030021032007290320210220072802182109200842003703002007420037037041c2d5c0004116200741f0006a1003200d200829030037030020072007290370370360200742002003420020091b220320067d2002420020091b2202200554ad7d2204200220057d2205200256200420035620042003511b22081b37037820074200200520081b370370200741e0006a4110200741f0006a411010050c010b200d450d00200741f0006a41086a220842003703002007420037037041c2d5c0004116200741f0006a1003200741e0006a41086a220d2008290300370300200720072903703703602007200741e0006a10eb01200741106a29030021032007290308210220072802002109200842003703002007420037037041c2d5c0004116200741f0006a1003200d2008290300370300200720072903703703602007427f2003420020091b220320067c2002420020091b220220057c22052002542208ad7c22022008200220035420022003511b22081b3703782007427f200520081b370370200741e0006a4110200741f0006a411010050b2000200a3703082000200c370300200041106a200b37030020074180016a24000b130020004103360204200041c8c9c1003602000b3400200041a4d8c20036020420004100360200200041146a4103360200200041106a41c0d0c100360200200041086a42083702000b3001017f02404104103222020d0041044101102e000b20004284808080c00037020420002002360200200241003600000b130020004104360204200041b8d4c1003602000b0b00200041a0c21e1082020b3001017f02404104103222020d0041044101102e000b20004284808080c00037020420002002360200200220013600000b3201017f02404104103222020d0041044101102e000b20004284808080c0003702042000200236020020024180e1013600000b3d01017f02404110103222020d0041104101102e000b200242003700082002428080e983b1de16370000200042908080808002370204200020023602000b0b00200041d086031082020bee0704077f027e047f027e230041d0016b22022400200241003602a80120014120200241a8016a10062103024002400240024020022802a8012204417f460d0020030d010b200042003703000c010b41002101200241003a00c801200441706a21050340024020042001470d00200141ff0171450d03200241003a00c8010c030b200241a8016a20016a200320016a2d00003a00002002200141016a22063a00c8012005417f6a21052006210120064120470d000b200241c8006a41086a200241a8016a41086a290300370300200241c8006a41106a200241a8016a41106a290300370300200241c8006a41186a200241a8016a41186a290300370300200220022903a801370348200420066b22074110490d01200320066a22082900002109200841086a290000210a41002101200241003a00c801200741706a21070340024020072001470d00200141ff0171450d03200241003a00c8010c030b200241a8016a20016a200820016a41106a2d00003a00002002200141016a22063a00c8012006210120064120470d000b200241e8006a41086a220b200241a8016a41086a2201290300370300200241e8006a41106a220c200241a8016a41106a2207290300370300200241e8006a41186a220d200241a8016a41186a220e290300370300200220022903a801370368200520066b410f4d0d012001200241c8006a41086a2903003703002007200241c8006a41106a290300370300200e200241c8006a41186a29030037030020024188016a41086a2205200b29030037030020024188016a41106a220b200c29030037030020024188016a41186a220c200d290300370300200220022903483703a8012002200229036837038801200820066a220641186a290000210f200641106a2900002110200241286a41086a2001290300370300200241286a41106a2007290300370300200241286a41186a200e290300370300200241086a41086a2005290300370300200241086a41106a200b290300370300200241086a41186a200c290300370300200220022903a801370328200220022903880137030802402004450d00200310290b20002009370308200041206a200f370300200041186a2010370300200041106a200a370300200041286a2002290328370300200041c8006a2002290308370300200041306a200241286a41086a290300370300200041386a200241286a41106a290300370300200041c0006a200241286a41186a290300370300200041d0006a200241086a41086a290300370300200041d8006a200241086a41106a290300370300200041e0006a200241086a41186a290300370300200042013703000b200241d0016a24000f0b41f7cdc3004133200241e8006a41ecd6c3001054000bd36f09127f017e037f017e017f017e077f037e107f230041a0036b2201240002400240024002400240024002400240024020004180c203700d00200141f8006a4181ebc5004114105d2001280278450d00200128027c2202450d0020014180036a41086a22034200370300200142003703800341f5dac100410f20014180036a1003200141e0026a41086a2204200329030037030020012001290380033703e002200141e0016a200141e0026a1088020240024020012802e00122050d004104210541002106410021070c010b200141e0016a41086a280200210620012802e40121070b2003420037030020014200370380034184dbc100411420014180036a10032004200329030037030020012001290380033703e002200141e0016a200141e0026a1089020240024020012802e80122080d00200141f0006a41d983c300410d105d410021092001280274410020012802701b2103200621040c010b20012802e401220920066a200141f0016a2802006b210420012802e001210320012802ec01450d00200810290b0240024002400240024020042002490d000240200920024f0d00200920026b220320066a220220034f0d022005200241246c6a28022021030c010b200141e8006a41a8dbc1004114105d200128026c410020012802681b20036a21030b200341ffc1036a220320034180c203706b210302402007450d00200510290b20032000470d0420014180036a41086a22034200370300200142003703800341f5dac100410f20014180036a1003200141e0026a41086a200329030037030020012001290380033703e002200141e0016a200141e0026a1088020240024020012802e00122080d00410421084100210a4100210b0c010b200141e0016a41086a280200210a20012802e401210b0b200141e0006a4181ebc5004114105d2001280264210c2001280260210d200141d8006a41d983c300410d105d200128025c410020012802581b210e024002400240024020082008200a41246c6a2202460d00200841206a280200200e4d0d010b4101210441002105410021060c010b200141e0016a41186a2203200841186a290200370300200141e0016a41106a2205200841106a290200370300200141e0016a41086a2206200841086a290200370300200120082902003703e001412010322204450d01200420012903e001370000200441186a2003290300370000200441106a2005290300370000200441086a20062903003700000240200841246a22032002470d0041012105410121060c010b2008200a41246c6a210f41202107410121024101210503400240200341206a280200200e4d0d00200221060c020b200141e0026a41186a2209200341186a290200370300200141e0026a41106a2210200341106a290200370300200141e0026a41086a2211200341086a290200370300200120032902003703e0020240024020052002460d00200221060c010b200241016a22062002490d0920024101742212200620062012491b220641ffffff3f712006470d09200641057422124100480d090240024020020d002012103221040c010b200420024105742012103421040b20040d0020124101102e000b200420076a220220012903e002370000200241186a2009290300370000200241106a2010290300370000200241086a2011290300370000200741206a2107200541016a210520062102200f200341246a2203470d000b0b02400240024002400240200c4100200d1b2202200a20056b22074d0d00200141d0006a41bcdbc100411c105d200128025421092001280250211020014180036a41086a2203420037030020014200370380034184dbc100411420014180036a1003200141e0026a41086a200329030037030020012001290380033703e002410810322203450d0120014288808080c0003702e401200120033602e00120032009410020101b200e6a3600000240024020012802e401220920012802e80122036b4104490d0020012802e00121090c010b200341046a22102003490d0c20094101742203201020102003491b22034100480d0c0240024020090d002003103221090c010b20012802e00120092003103421090b2009450d03200120033602e401200120093602e00120012802e80121030b2001200341046a3602e801200920036a200220076b221036000020042005200141e0016a10940120012802e4012103200141e0026a411020012802e001220720012802e801100502402003450d00200710290b02402006450d00200410290b20014198036a420037030020014190036a420037030020014188036a42003703002001420037038003201041066a2211ad42307e2213422088a70d0d2013a72203417f4c0d0d0240024020030d004108210f4108210e0c010b20031032220f450d04200f210e0b200141e0016a41186a220720014180036a41186a290300370300200141e0016a41106a220920014180036a41106a290300370300200141e0016a41086a20014180036a41086a29030037030020012001290380033703e00120114102490d04200220056a200a6b41056a2102200e21030340200141e0026a41186a22052007290300370300200141e0026a41106a22062009290300370300200141e0026a41086a2204200141e0016a41086a290300370300200120012903e0013703e0022003420037030820034200370300200341106a20012903e002370300200341186a2004290300370300200341206a2006290300370300200341286a2005290300370300200341306a21032002417f6a22020d000b201041056a21020c070b2006450d08200410290c080b41084101102e000b20034101102e000b20034108102e000b41002102200e210320110d020c030b41204101102e000b4198dbc100200220061036000b2003420037030820034200370300200320012903e001370310200341186a200141e8016a290300370300200341206a200141f0016a290300370300200341286a200141e0016a41186a290300370300200241016a21020b20014180036a41086a22034200370300200142003703800341d8dbc100411320014180036a1003200141e0026a41086a200329030037030020012001290380033703e002200141103602e4012001200141e0026a3602e001200e2002200141e0016a108a0202402011450d00200f10290b200141083a00e001200141e0016a41086a2010360200200141023a00e40141014100200141e0016a104c0b200b450d00200810290b20014180036a41086a2203420037030020014200370380034184dbc100411420014180036a1003200141e0026a41086a200329030037030020012001290380033703e002200141e0016a200141e0026a10890220012802e8012214450d0720012802ec01211520012802e0012000470d0620014180036a41086a2203420037030020014200370380034184dbc100411420014180036a1003200141e0026a41086a200329030037030020012001290380033703e002200141e0016a200141e0026a108902024020012802e8012216450d00200141e0026a411010040b024020160d0002402015450d00201410290b41a1dcc100410f100941b0dcc100413510090c080b20012902ec01211720012802e40121184200211920014180036a41086a22034200370300200142003703800341d8dbc100411320014180036a1003200141e0026a41086a200329030037030020012001290380033703e002200141e0016a200141e0026a108b020240024020012802e001221a450d00200141e0026a4110100420012902e40121190c010b4108211a0b200141c8006a41d983c300410d105d200128024c210b2001280248210c200141c0006a41a8dbc1004114105d2001280240211b2001280244211c201a2019422088a7221d41306c6a210f0240024020180d004100210a41002106410021000c010b2018417f6a2106410021000240201a200f460d000240201a201d41306c6a220341506a220f290300200f41086a2903008450450d004101210a0c020b20014180036a41186a200341606a220341186a29000037030020014180036a41106a200341106a29000037030020014180036a41086a200341086a2900003703002001200329000037038003410121000b4100210a0b200141e9016a20014180036a41086a290300370000200141f1016a20014180036a41106a290300370000200141f9016a20014180036a41186a290300370000200120003a00e00120012001290380033700e101200141e0016a41017221030240024002402000450d0020034280809aa6eaafe30142001053200141e0026a41086a200341086a290000370300200141e0026a41106a200341106a290000370300200141e0026a41186a200341186a290000370300200120032900003703e00220012d00e0014101470d010240024002400240024041201032221e450d00201e20012903e002370000201e41186a200141e0026a41186a2210290300370000201e41106a200141e0026a41106a2211290300370000201e41086a200141e0026a41086a220e290300370000200141e0016a410172210341022105412021024101211f410121200340024002400240024020060d00410021060c010b2006417f6a2106200a41ff01710d000240201a200f470d004100210a0c010b200f41506a2204290300200441086a290300844200520d014101210a2004210f0b200320012903e002370000200341086a200e290300370000200341106a2011290300370000200341186a201029030037000041002100200141003a00e0010c010b2010200f41606a220041186a29000022133703002011200041106a2900002221370300200e200041086a29000022223703002001200029000022233703e00220032023370000200341086a2022370000200341106a2021370000200341186a2013370000200141013a00e00120034280809aa6eaafe301420010534100210a20012d00e00121002004210f0b20014180036a41186a2204200341186a29000037030020014180036a41106a2207200341106a29000037030020014180036a41086a2209200341086a29000037030020012003290000370380030240200041ff0171450d00200141e0016a41186a22082004290300370300200141e0016a41106a22042007290300370300200141e0016a41086a2207200929030037030020012001290380033703e0010240201f2020470d00201f41016a2200201f490d0b2005200020002005491b222041ffffff3f712020470d0b202041057422004100480d0b02400240201f0d0020001032211e0c010b201e200220001034211e0b201e450d070b201e20026a220020012903e001370000200041186a2008290300370000200041106a2004290300370000200041086a2007290300370000200541026a2105200241206a2102201f41016a211f0c010b0b201e20026a2124201f450d07200141e0016a41086a2105201e2108034020014180016a2008108c0202402001280280014101470d002001280288012102200141a0016a108d0220012802a0012112024020012802a8012203450d00200341216c2100201241016a21032002410876210641012002411f7174211020024105764107712204417f732111034002402003417f6a2d00004101470d00200141e0016a41186a200341186a290000370300200141e0016a41106a200341106a2900003703002005200341086a290000370300200120032900003703e001200120063602800220014180036a200141e0016a108e020240200420012802880322024f0d00200220116a220720024f0d07200128028003220920074102746a28020020107121020240200128028403450d00200910290b2002450d01200141e0016a2003108f02024020012903e0014201510d00411310322202450d09200241002900fcdb413700002002410f6a410028008bdc41360000200241086a4100290084dc4137000020014293808080b002370284032001200236028003200320014180036a108101200128028403210720012802880321092001280280032102200141e0026a41186a220e4200370300200141e0026a41106a220a4200370300200141e0026a41086a220f4200370300200142003703e00220022009200141e0026a1000200141c0016a41186a200e290300370300200141c0016a41106a200a290300370300200141c0016a41086a200f290300370300200120012903e0023703c001200141c0016a412010042007450d02200210290c020b200141386a4195ebc5004111105d2001200128023c41016a410120012802381b36028c02411310322202450d09200241002900fcdb413700002002410f6a410028008bdc41360000200241086a4100290084dc4137000020014293808080b002370284032001200236028003200320014180036a108101200128028403210720012802880321092001280280032102200141e0026a41186a220e4200370300200141e0026a41106a220a4200370300200141e0026a41086a220f4200370300200142003703e00220022009200141e0026a1000200141c0016a41186a200e290300370300200141c0016a41106a200a290300370300200141c0016a41086a200f290300370300200120012903e0023703c00120014120360284032001200141c0016a36028003200520014180036a1090022007450d01200210290c010b200128028403450d0020012802800310290b200341216a21032000415f6a22000d000b0b20012802a401450d00201210290b2024200841206a2208470d000c080b0b41204101102e000b4198dbc100200720021036000b41134101102e000b41134101102e000b20004101102e000b200141e0026a41186a200341186a290000370300200141e0026a41106a200341106a290000370300200141e0026a41086a200341086a290000370300200120032900003703e0020b41002120410121244101211e4100211f0b20014180036a41086a22034200370300200142003703800341f5dac100410f20014180036a1003200141e0026a41086a200329030037030020012001290380033703e002200141e0016a200141e0026a108802410021250240024020012802e001220d0d004104210d41002126410021090c010b200141e0016a41086a280200210920012802e40121260b200941246c2107024002402017422088a722060d0041012127410021280c010b41002128410021254101212702400240024002402006200d20076a2205200d6b41246e2203200320064b1b2203450d00200341057422004100480d0520032125200010322227450d010b200d2103200621022027210003400240200520036b41ec004b0d0020052003460d05200d200941246c6a2108410121050240034020002003290000370000200041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a290000370000200220052204460d01200441016a2105200041206a21002008200341246a2203470d000b0b202820046a21280c050b20002003290000370000200041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a290000370000024020024101470d00202841017221280c050b20002003290024370020200041386a2003413c6a290000370000200041306a200341346a290000370000200041286a2003412c6a29000037000020024102460d0320002003290048370040200041d8006a200341e0006a290000370000200041d0006a200341d8006a290000370000200041c8006a200341d0006a29000037000020024103460d022000200329006c370060200041f8006a20034184016a290000370000200041f0006a200341fc006a290000370000200041e8006a200341f4006a290000370000202841046a212820004180016a210020034190016a21032002417c6a22020d000c040b0b20004101102e000b202841037221280c010b202841027221280b201c4100201b1b200b4100200c1b6a211b200d20076a210b024002400240024002400240024002402006450d00200b200d460d01200641016a2100200941246c2102200d21030340200141e0026a41186a200341186a290200370300200141e0026a41106a200341106a290200370300200141e0026a41086a200341086a290200370300200120032902003703e0022000417f6a2200450d04200341246a21032002415c6a22020d000b200b21000c020b200b200d470d030b200d21000b0240201e2024470d0002402026450d00200d10290b410021294104210e410421044100212a0c050b201e41086a2900002113201e41106a2900002121201e290000212220014180036a41186a201e41186a290000222337030020014180036a41106a202137030020014180036a41086a20133703002001202237038003200141e0016a41186a2023370300200141e0016a41106a2021370300200141e0016a41086a2013370300200120223703e001201e41206a2102201f41057441606a410576210541022106200141e0016a2103201b21040c030b200341206a2802002104200141e0016a41186a200141e0026a41186a290300370300200141e0016a41106a200141e0026a41106a290300370300200141e0016a41086a200141e0026a41086a290300370300200120012903e0023703e001200341246a21000c010b200141e0016a41186a200d41186a290200370300200141e0016a41106a200d41106a290200370300200141e0016a41086a200d41086a2902003703002001200d2902003703e001200d41246a2100200d28022021040b20014180036a41186a200141e0016a41186a2203290300221337030020014180036a41106a200141e0016a41106a2202290300222137030020014180036a41086a200141e0016a41086a22052903002222370300200120012903e001222337038003200320133703002002202137030020052022370300200120233703e001417f200b20006b41246d22032024201e6b4105766a220220022003491b210541002106200141e0016a2103201e21020b417f200541016a220720072005491b2229ad42247e2213422088a70d032013a72205417f4c0d0302400240024002400240024002400240024020050d004104210e0c010b20051032220e450d010b200e2003290200370200200e41186a200341186a290200370200200e41106a200341106a290200370200200e41086a200341086a290200370200200e200436022002402006450d00024020022024470d004101212a0c050b200241086a2900002113200241106a29000021212002290000212220014180036a41186a200241186a29000037030020014180036a41106a202137030020014180036a41086a20133703002001202237038003200241206a21020c020b0240200b2000460d00200141e0016a41186a200041186a2902002221370300200141e0016a41106a200041106a2902002222370300200141e0016a41086a200041086a29020022233703002000290200211320014180036a41086a202337030020014180036a41106a202237030020014180036a41186a2021370300200120133703e00120012013370380032000280220211041002104200041246a21000c030b024020022024460d00200241086a2900002113200241106a29000021212002290000212220014180036a41186a200241186a29000037030020014180036a41106a202137030020014180036a41086a20133703002001202237038003200241206a21020c020b4101212a0c030b20054104102e000b41022104201b21100b4102210641022103412421050340200141e0016a41186a220720014180036a41186a2211290300370300200141e0016a41106a220920014180036a41106a220a290300370300200141e0016a41086a220820014180036a41086a220f29030037030020012001290380033703e00102402003222a417f6a22032029470d000240024002400240200441ff01710e03010200010b202420026b41057621120c020b417f200b20006b41246d2212202420026b4105766a220c200c2012491b21120c010b200b20006b41246d21120b2003417f201241016a220c200c2012491b6a22122003490d072006201220122006491b2229ad42247e2213422088a70d072013a722034100480d0702400240202a4101470d0020031032210e0c010b200e200520031034210e0b200e450d030b200e20056a220320012903e001370200200341186a2007290300370200200341106a2009290300370200200341086a2008290300370200200341206a20103602000240024002400240200441ff01710e03010200010b20022024460d04200241086a2900002113200241106a2900002121200229000021222011200241186a290000370300200a2021370300200f20133703002001202237038003200241206a21024101210741022104201b21100c020b0240200b2000460d002007200041186a29020022213703002009200041106a29020022223703002008200041086a290200222337030020002902002113200f2023370300200a202237030020112021370300200120133703e0012001201337038003200028022021104101210741002104200041246a21000c020b41022104024020022024470d00410021070c020b200241086a2900002113200241106a2900002121200229000021222011200241186a290000370300200a2021370300200f20133703002001202237038003200241206a210241012107201b21100c010b200b2000460d022011200041186a290200370300200a200041106a290200370300200f200041086a29020037030020012000290200370380032000280220211041012104200041246a2100410121070b200641026a2106202a41016a2103200541246a210520070d000b0b02402026450d00200d10290b202a4115490d01202a410176222bad42247e2213422088a70d062013a72203417f4c0d0602400240024020030d004104212c410421070c010b20031032222c450d01202c21070b200e415c6a212d200e41b47f6a212e4104210a4100212f4100211b41002110202a210d0340200d21054100210d4101210602402005417f6a2230450d00024002400240024002400240200e203041246c6a41206a280200200541246c2200200e6a41586a2802002203490d002005417e6a2109202e20006a21024100210d410021000340024020092000470d00200521060c080b200041016a21002003200228020022064f21042002415c6a21022006210320040d000b200041016a21062000417f7320056a21020c010b202e200541096c41027422096a21002030210202400340024020024101470d00410021020c020b2002417f6a21022003200028020022064921042000415c6a21002006210320040d000b0b20052002490d012005202a4b0d03200520026b22064101762204450d00202d20096a2103200e200241246c6a21000340200141e0016a41206a2209200041206a2208280200360200200141e0016a41186a2211200041186a220f290200370300200141e0016a41106a2212200041106a220b290200370300200141e0016a41086a220c200041086a220d290200370300200120002902003703e001200341206a221c2802002126200341186a22312902002113200341106a22322902002121200341086a2233290200212220002003290200370200200d2022370200200b2021370200200f201337020020082026360200201c200928020036020020312011290300370200203220122903003702002033200c290300370200200320012903e0013702002003415c6a2103200041246a21002004417f6a22040d000b0b024020020d002002210d0c050b0240200641094d0d002002210d0c050b2005202a4b0d01200e200241246c6a2109034020052002417f6a220d490d0402402005200d6b22064102490d00200e200241246c6a220341206a2200280200200e200d41246c6a220841206a220428020022114f0d00200141e0026a41186a220f200841186a2212290200370300200141e0026a41106a220b200841106a220c290200370300200141e0026a41086a221c200841086a2226290200370300200120082902003703e002200820032902003702002026200341086a290200370200200c200341106a2902003702002012200341186a29020037020020042000280200360200024020064103490d002030210020092104200841e8006a28020020114f0d00024003402004220341206a200341c4006a280200360200200341186a2003413c6a290200370200200341106a200341346a290200370200200341086a2003412c6a2902003702002003200341246a220429020037020020022000417f6a2200460d01200341e8006a2802002011490d000b0b200341246a21030b200320012903e00237020020032011360220200341186a200f290300370200200341106a200b290300370200200341086a201c2903003702000b200d450d052009415c6a2109200d21022006410a4f0d050c000b0b200220051030000b20052002417f6a220d490d010b2005202a108f01000b200d20051030000b0240024002402010202f470d00202f41016a2203202f490d09202f4101742200200320032000491b220341ffffffff01712003470d09200341037422004100480d0902400240202f0d0020001032210a0c010b200a202f41037420001034210a0b200a450d012003212f201b21100b200a20104103746a220320063602042003200d360200201b41016a2210211b20104102490d01024003400240024002400240200a2010417f6a221b4103746a2203280200450d002010410374200a6a220541746a2802002202200328020422004d0d000240201041024b0d002010211b410221100c080b200a2010417d6a220f4103746a2802042203200020026a4d0d010240201041034b0d002010211b410321100c080b200541646a280200200320026a4d0d012010211b0c070b20104103490d0120032802042100200a2010417d6a220f4103746a28020421030b20032000490d010b2010417e6a210f0b0240024002400240024002402010200f41016a221c4b2226450d002010200f4b2231450d01200a200f4103746a2212280204223220122802006a2203200a201c4103746a220b280200220c490d022003202a4b0d03200e200c41246c6a2208200b280204221141246c22006a2106200341246c21022003200c6b220420116b220320114f0d04202c2006200341246c2200109b051a200720006a21050240024020114101480d00200341014e0d010b20062103200721000c060b202d20026a210220062103034020022003415c6a22042005415c6a22092005417c6a2802002003417c6a2802004922061b2200290200370200200241206a200041206a280200360200200241186a200041186a290200370200200241106a200041106a290200370200200241086a200041086a2902003702002005200920061b2105024020082004200320061b2203490d00200721000c070b2002415c6a21022007210020072005490d000c060b0b419cffc000201c20101036000b419cffc000200f20101036000b200c20031030000b2003202a108f01000b202c20082000109b051a200720006a21050240024020114101480d00200420114a0d010b20082103200721000c010b200e20026a210920072100200821030340200320062000200641206a280200200041206a2802004922041b2202290200370200200341206a200241206a280200360200200341186a200241186a290200370200200341106a200241106a290200370200200341086a200241086a2902003702002000200041246a20041b2100200341246a2103200641246a200620041b220620094f0d01200520004b0d000b0b20032000200520006b220220024124706b109b051a02402031450d002012200c360200201241046a203220116a3602002026450d02200b200b41086a2010201c417f736a410374109c051a201b2110201b41014d0d040c010b0b41acffc000200f20101036000b418080c000106d000b20004104102e000b200d0d000b0240202f450d00200a10290b202b450d03202c10290c030b20034104102e000b20034104102e000b202a4102490d00202a417f6a2102200e202a41246c6a2106410021040340024002400240202a20022203417f6a2202490d00202a20026b22004102490d02200e200341246c6a220341206a2205280200200e200241246c6a220741206a220828020022094f0d02200141e0026a41186a2210200741186a2211290200370300200141e0026a41106a220a200741106a220f290200370300200141e0026a41086a2212200741086a220b290200370300200120072902003703e00220072003290200370200200b200341086a290200370200200f200341106a2902003702002011200341186a2902003702002008200528020036020020004103490d012004210520062100200741e8006a28020020094f0d01034020002203415c6a22002003290200370200200041206a200341206a280200360200200041186a200341186a290200370200200041106a200341106a290200370200200041086a200341086a2902003702002005417f6a2205450d02200341246a2100200341c4006a28020020094f0d020c000b0b2002202a1030000b200320012903e00237020020032009360220200341186a2010290300370200200341106a200a290300370200200341086a20122903003702000b200441016a21042006415c6a210620020d000b0b200e21040b20014180036a41086a22034200370300200142003703800341f5dac100410f20014180036a1003200141e0026a41086a200329030037030020012001290380033703e002200141e0016a200e202a109102200141e0026a411020012802e001220320012802e8011005024020012802e401450d00200310290b202a41246c220341246d210541002100024020030d0041012106410021050c020b200541ffffff3f712005470d00200541057422034100480d002003103222060d0120034101102e000b1033000b0240202a450d00200e202a41246c6a210241002100200621030340200e41086a2900002113200e41106a2900002121200e2900002122200341186a200e41186a290000370000200341106a2021370000200341086a201337000020032022370000200041016a2100200341206a21032002200e41246a220e470d000b0b02402029450d00200410290b20062000200141d0026a410041202000676b10d301202720282006200010920202402005450d00200610290b20014180036a41086a220342003703002001420037038003418fdcc100411220014180036a1003200141e0026a41086a200329030037030020012001290380033703e002200141003602e001200141e0026a4110200141e0016a100621030240024020012802e0012200417f460d002003450d0020012000360284032001200336028003200141e0016a20014180036a1031024020012802e0012207450d00200141e8016a280200210a20012802e401210b2000450d02200310290c020b41f7cdc3004133200141d0026a41ecd6c3001054000b4100210b410121074100210a0b200141f8016a4200370300200141f0016a4200370300200141e8016a4200370300200142003703e001200a41ffffff3f71200a470d00200a4105742203417f4c0d000240024020030d00410121060c010b200310322206450d020b200141e0026a41186a2202200141e0016a41186a290300370300200141e0026a41106a2205200141e0016a41106a290300370300200141e0026a41086a2204200141e0016a41086a290300370300200120012903e0013703e00202400240200a4102490d00200a417f6a2100200621030340200320012903e002370000200341186a2002290300370000200341106a2005290300370000200341086a2004290300370000200341206a21032000417f6a22000d000b200a210f0c010b200a450d034101210f200621030b200320012903e002370000200341186a200141e0026a41186a290300370000200341106a200141e0026a41106a290300370000200341086a200141e0026a41086a2903003700000c030b102f000b20034101102e000b4100210f0b201a201d41306c6a21032019a72111410021120240024002400240034002402018450d002003201a460d02200341506a2203290300200341086a29030084500d022018417f6a2200450d000340201a2003460d03200341506a2203290300200341086a29030084500d032000417f6a22000d000b0b2003201a460d0102400340200341506a22022903002113200241086a290300212120014180036a41186a2205200341606a220041186a29030037030020014180036a41106a2204200041106a29030037030020014180036a41086a2209200041086a29030037030020012000290300370380032013202184500d01200141e0016a41186a22002005290300370300200141e0016a41106a22052004290300370300200141e0016a41086a2204200929030037030020012001290380033703e001200141d0026a200141e0016a108c02200141c0016a41186a22092000290300370300200141c0016a41106a22082005290300370300200141c0016a41086a22102004290300370300200120012903e0013703c001024020012802d0024101460d0020022103201a2002470d010c040b0b20014180016a41086a220e201029030037030020014180016a41106a2210200829030037030020014180016a41186a22082009290300370300200120012903c00122133703a001200120133703800120012802d802210220002008290300370300200520102903003703002004200e29030037030020012001290380013703e001200f20024d0d03200341506a2103200620024105746a220220012903e001370000200241186a2000290300370000200241106a2005290300370000200241086a2004290300370000201241016a2112410021180c010b0b200141a0016a41086a200141e0026a41086a290300370300200141a0016a41106a200141e0026a41106a290300370300200141a0016a41186a200141e0026a41186a290300370300200120012903e0023703a0010b02402011450d00201a10290b200f200a200a200f4b1b2209450d0220072104410021050340024020072006460d002007200541057422036a2200200620036a4120109d05450d00411610322203450d0320034100290089bb413700002003410e6a4100290097bb41370000200341086a4100290091bb4137000020014296808080e0023702e401200120033602e0012000200141e0016a10810120012802e401210220012802e801211020012802e0012103200141e0026a41186a22114200370300200141e0026a41106a220e4200370300200141e0026a41086a22084200370300200142003703e00220032010200141e0026a1000200141c0016a41186a2011290300370300200141c0016a41106a200e290300370300200141c0016a41086a2008290300370300200120012903e0023703c001200141c0016a4120100402402002450d00200310290b201e210303400240202420036b41e0004b0d00024020032024460d00034020042003460d04200320004120109d05450d042024200341206a2203470d000b0b200141286a20004280809aa6eaafe301420010c201200141286a41086a29030021222001290328211320014180036a41086a22034200370300200142003703800341c2d5c000411620014180036a10032008200329030037030020012001290380033703e002200141106a200141e0026a10eb01200141106a41106a2903002121200129031821232001280210210020034200370300200142003703800341c2d5c000411620014180036a10032008200329030037030020012001290380033703e002200142002021420020001b222120227d2023420020001b2222201354ad7d2223202220137d2213202256202320215620232021511b22031b3703e80120014200201320031b3703e001200141e0026a4110200141e0016a411010050c020b20002003460d01200320004120109d05450d01200341206a22022000460d01200220004120109d05450d01200341c0006a22022000460d01200220004120109d05450d01200341e0006a22022000460d0120034180016a2103200220004120109d050d000b0b200441206a2104200541016a22052009490d000c030b0b41ecdbc1002002200f1036000b41164101102e000b2006200f4105746a2103200f2109024002400240200f4104490d00200141e0016a41206a2108200141a0026a2110200141e0016a41e0006a2111200141e0026a210e200141f8016a2102200141f0016a2105200141e8016a210420032100200f2109024002400340200242003703002005420037030020044200370300200142003703e001024020082000460d00200041606a200141e0016a4120109d05450d002009417f6a21000c050b200242003703002005420037030020044200370300200142003703e001024020102000460d00200041406a200141e0016a4120109d050d030b200242003703002005420037030020044200370300200142003703e001024020112000460d00200041a07f6a200141e0016a4120109d050d020b200242003703002005420037030020044200370300200142003703e001200041807f6a210302400240200e2000460d002003200141e0016a4120109d050d010b2009417c6a210920032100200320066b41e0004b0d010c040b0b2009417c6a21000c030b2009417d6a21000c020b2009417e6a21000c010b20032006460d012009417f6a2100200141e0016a41206a2102200141f8016a2105200141f0016a2104200141e8016a21090340200542003703002004420037030020094200370300200142003703e001024020022003460d00200341606a200141e0016a4120109d050d020b2000417f6a21002006200341606a2203470d000c020b0b200041016a2203200f200f20034b1b210f0b200141fc016a2028360200200141f8016a2025360200200141f4016a2027360200200141e0016a41106a201f360200200141ec016a2020360200200141083a00e001200141e0016a41086a201e360200200141033a00e40141014100200141e0016a104c20014180036a41086a220342003703002001420037038003418fdcc100411220014180036a1003200141e0026a41086a2200200329030037030020012001290380033703e002200141103602e4012001200141e0026a3602e0012006200f200141e0016a1095010240200a450d00200610290b20034200370300200142003703800341ccebc500411620014180036a10032000200329030037030020012001290380033703e002200120123602e001200141e0026a4110200141e0016a41041005200141086a4195ebc5004111105d20012802082102200128020c21052003420037030020014200370380034195ebc500411120014180036a10032000200329030037030020012001290380033703e0022001200541016a410120021b3602e001200141e0026a4110200141e0016a410410050240200b450d00200710290b2017a7450d00201610290b2015450d00201410290b200141a0036a24000bfa05020e7f037e23004180016b220224002002410036025820014110200241d8006a1006210302400240024002400240024020022802582204417f470d00200041003602000c010b2002200436021420022003360210200241086a200241106a102c20022802080d042002280214220541246e220641246c2201417f4c0d01200228020c21070240024020010d00410421080c010b200110322208450d030b02402007450d00410021090340200241003a00782009220a41016a2109410021010240024002400240034020052001460d01200241d8006a20016a2002280210220b2d00003a00002002200b41016a3602102002200141016a220c3a0078200c2101200c4120470d000b200241386a41086a220d200241d8006a41086a290300370300200241386a41106a220e200241d8006a41106a290300370300200241386a41186a220f200241d8006a41186a2903003703002002200229035837033820022005200c6b220136021420014104490d01200241186a41086a220c200d290300370300200241186a41106a220d200e290300370300200241186a41186a220e200f290300370300200220022903383703182002200b41056a36021020022001417c6a2205360214200b280001210b2006200a470d030240200a4101742201200920092001491b2206ad42247e2210422088a70d002010a7220141004e0d030b1033000b20024100360214200141ff0171450d00200241003a00780b2006450d08200810290c080b02400240200a0d002001103221080c010b2008200a41246c2001103421080b2008450d060b2008200a41246c6a22012002290318370200200c2903002110200d2903002111200e29030021122001200b360220200141186a2012370200200141106a2011370200200141086a201037020020092007470d000b0b2008450d042000200636020420002008360200200041086a20073602002004450d00200310290b20024180016a24000f0b102f000b20014104102e000b20014104102e000b41f7cdc3004133200241d8006a41ecd6c3001054000bef0101047f230041206b220224002002410036021020014110200241106a10062101024002400240024020022802102203417f460d0020010d010b200041003602080c010b200220013602082002200336020c20034104490d012002200141046a36020820022003417c6a220436020c20044104490d01200128000021042002200341786a36020c2002200141086a36020820012800042103200241106a200241086a103120022802102205450d012000200229021437020c200020053602082000200336020420002004360200200110290b200241206a24000f0b41f7cdc3004133200241106a41ecd6c3001054000bdf2703027f027e047f230041106b220324002003410036020820034201370300200120031066024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001450d002000200141306c6a21040340200041086a2903002105200029030021060240024020032802042207200328020822086b4110490d00200841106a2101200328020021090c010b200841106a22012008490d2420074101742209200120012009491b220a4100480d240240024020070d00200a103221090c010b20032802002007200a103421090b2009450d032003200a36020420032009360200200a21070b200920086a220820053700082008200637000020032001360208024020072001470d00200141016a22072001490d2420014101742208200720072008491b22074100480d240240024020010d002007103221090c010b200920012007103421090b2009450d0420032007360204200320093602000b2003200141016a360208200920016a200041106a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d0520032007360204200320093602000b2003200141016a360208200920016a200041116a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d0620032007360204200320093602000b2003200141016a360208200920016a200041126a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d0720032007360204200320093602000b2003200141016a360208200920016a200041136a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d0820032007360204200320093602000b2003200141016a360208200920016a200041146a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d0920032007360204200320093602000b2003200141016a360208200920016a200041156a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d0a20032007360204200320093602000b2003200141016a360208200920016a200041166a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d0b20032007360204200320093602000b2003200141016a360208200920016a200041176a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d0c20032007360204200320093602000b2003200141016a360208200920016a200041186a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d0d20032007360204200320093602000b2003200141016a360208200920016a200041196a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d0e20032007360204200320093602000b2003200141016a360208200920016a2000411a6a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d0f20032007360204200320093602000b2003200141016a360208200920016a2000411b6a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d1020032007360204200320093602000b2003200141016a360208200920016a2000411c6a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d1120032007360204200320093602000b2003200141016a360208200920016a2000411d6a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d1220032007360204200320093602000b2003200141016a360208200920016a2000411e6a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d1320032007360204200320093602000b2003200141016a360208200920016a2000411f6a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d1420032007360204200320093602000b2003200141016a360208200920016a200041206a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d1520032007360204200320093602000b2003200141016a360208200920016a200041216a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d1620032007360204200320093602000b2003200141016a360208200920016a200041226a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d1720032007360204200320093602000b2003200141016a360208200920016a200041236a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d1820032007360204200320093602000b2003200141016a360208200920016a200041246a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d1920032007360204200320093602000b2003200141016a360208200920016a200041256a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d1a20032007360204200320093602000b2003200141016a360208200920016a200041266a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d1b20032007360204200320093602000b2003200141016a360208200920016a200041276a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d1c20032007360204200320093602000b2003200141016a360208200920016a200041286a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d1d20032007360204200320093602000b2003200141016a360208200920016a200041296a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d1e20032007360204200320093602000b2003200141016a360208200920016a2000412a6a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d1f20032007360204200320093602000b2003200141016a360208200920016a2000412b6a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d2020032007360204200320093602000b2003200141016a360208200920016a2000412c6a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d2120032007360204200320093602000b2003200141016a360208200920016a2000412d6a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d2220032007360204200320093602000b2003200141016a360208200920016a2000412e6a2d00003a000002400240200328020420032802082201460d00200328020021090c010b200141016a22092001490d2420014101742207200920092007491b22074100480d240240024020010d002007103221090c010b200328020020012007103421090b2009450d2320032007360204200320093602000b2003200141016a360208200920016a2000412f6a2d00003a0000200041306a22002004470d000b0b2003280204210020022802002002280204200328020022012003280208100502402000450d00200110290b200341106a24000f0b200a4101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b1033000bd505040a7f027e057f017e230041e0006b220224002002410036023820014110200241386a1006210302400240024002400240024002400240024020022802382204417f470d00200041003602000c010b2002200436021420022003360210200241086a200241106a102c20022802080d072002280214220541306e220641306c2201417f4c0d01200228020c21070240024020010d00410821080c010b200110322208450d030b02402007450d004100210903402005220a4110490d05200941016a210b20022002280210220541106a360210200541086a290000210c2005290000210d41002101200241003a0058200a41706a210e03400240200e2001470d0020024100360214200141ff0171450d0a200241003a00580c0a0b200241386a20016a200520016a220f41106a2d00003a00002002200f41116a3602102002200141016a220f3a0058200f2101200f4120470d000b200241186a41186a2210200241386a41186a290300370300200241186a41106a2211200241386a41106a290300370300200241186a41086a2212200241386a41086a29030037030020022002290338370318024020062009470d0020094101742201200b200b2001491b2206ad42307e2213422088a70d082013a722014100480d080240024020090d002001103221080c010b2008200941306c2001103421080b2008450d070b200e200f6b21052008200941306c6a2201200c3703082001200d37030020012002290318370310200141186a2012290300370300200141206a2011290300370300200141286a2010290300370300200b2109200b2007470d000b2002200a200f6b41706a3602140b2008450d072000200636020420002008360200200041086a20073602002004450d00200310290b200241e0006a24000f0b102f000b20014108102e000b2002200a3602140c020b20014108102e000b1033000b2006450d00200810290b41f7cdc3004133200241386a41ecd6c3001054000bbe0201067f230041c0006b220224000240411610322203450d0020034100290089bb413700002003410e6a4100290097bb41370000200341086a4100290091bb4137000020024296808080e002370224200220033602202001200241206a108101200228022421042002280228210520022802202103200241206a41186a22064200370300200241206a41106a22074200370300200241206a41086a220142003703002002420037032020032005200241206a1000200241186a2006290300370300200241106a2007290300370300200241086a200129030037030020022002290320370300200241206a200241201093020240024020022802204101460d00200041003602000c010b20002002290320370200200041086a20012802003602000b02402004450d00200310290b200241c0006a24000f0b41164101102e000bed02030a7f017e017f230041206b2201240020014100109402200141106a410110940202400240024020012802182202450d004102210320012802042104200128020821050340200128021421062001280210210702400240200420056b200241216c220841216d2209490d00200520096a2109200128020021020c010b200520096a22092005490d0420044101742202200920092002491b220aad42217e220b422088a70d04200ba7220c4100480d040240024020040d00200c103221020c010b2001280200200441216c200c103421020b2002450d0320012002360200200a21040b2002200541216c6a20072008109b051a02402006450d00200710290b200141106a2003109402200341016a210320092105200128021822020d000b20012004360204200120093602080b02402001280214450d00200128021010290b20002001290300370200200041086a200141086a280200360200200141206a24000f0b200c4101102e000b1033000b980302067f017e230041d0006b2202240002400240411310322203450d00200341002900e5dc413700002003410f6a41002800f4dc41360000200341086a41002900eddc4137000020024293808080b002370224200220033602202001200241206a109502200228022421042002280228210120022802202103200241206a41186a22054200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020032001200241206a1000200241186a2005290300370300200241106a2006290300370300200241086a2007290300370300200220022903203703002002410036022020024120200241206a100621050240024020022802202201417f460d002002200136024420022005360240200241206a200241c0006a103c20022802202206450d032002290224210802402001450d00200510290b20002008370204200020063602000c010b20004100360208200042043702000b02402004450d00200310290b200241d0006a24000f0b41134101102e000b41f7cdc3004133200241c8006a41ecd6c3001054000bf00302067f047e230041c0006b220224000240024002400240411310322203450d00200341002900fcdb413700002003410f6a410028008bdc41360000200341086a4100290084dc4137000020024293808080b002370224200220033602202001200241206a108101200228022421042002280228210320022802202105200241206a41186a22014200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020052003200241206a1000200241186a2001290300370300200241106a2006290300370300200241086a2007290300370300200220022903203703002002410036022020024120200241206a1006210320022802202201417f460d022003450d0220014104490d012001417c714104460d01200141786a4110490d01200141686a4110490d012003280000210620032800042107200341106a290000210820032900082109200341206a290000210a2003290018210b02402001450d00200310290b20002009370308200041206a200a370300200041186a200b370300200041106a20083703002000412c6a2007360200200041286a2006360200420121080c030b41134101102e000b41f7cdc3004133200241206a41ecd6c3001054000b420021080b2000200837030002402004450d00200510290b200241c0006a24000bd30102027f027e200028022021020240024002400240410410322203450d00200320023600002000280224210220034104410810342203450d0120032002360004200041086a29030021042000290300210520034108411810342203450d0220032005370008200341106a2004370000200041186a29030021042000290310210520034118413010342200450d0320002005370018200041206a200437000020012802002001280204200041281005200010290f0b41044101102e000b41084101102e000b41184101102e000b41304101102e000bc62701067f230041106b220324002003410036020820034201370300200220031066024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402002450d002001200241246c6a2104034002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d0320032006360204200320053602000b2003200241016a360208200520026a20012d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d0420032006360204200320053602000b2003200241016a360208200520026a200141016a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d0520032006360204200320053602000b2003200241016a360208200520026a200141026a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d0620032006360204200320053602000b2003200241016a360208200520026a200141036a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d0720032006360204200320053602000b2003200241016a360208200520026a200141046a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d0820032006360204200320053602000b2003200241016a360208200520026a200141056a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d0920032006360204200320053602000b2003200241016a360208200520026a200141066a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d0a20032006360204200320053602000b2003200241016a360208200520026a200141076a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d0b20032006360204200320053602000b2003200241016a360208200520026a200141086a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d0c20032006360204200320053602000b2003200241016a360208200520026a200141096a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d0d20032006360204200320053602000b2003200241016a360208200520026a2001410a6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d0e20032006360204200320053602000b2003200241016a360208200520026a2001410b6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d0f20032006360204200320053602000b2003200241016a360208200520026a2001410c6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d1020032006360204200320053602000b2003200241016a360208200520026a2001410d6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d1120032006360204200320053602000b2003200241016a360208200520026a2001410e6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d1220032006360204200320053602000b2003200241016a360208200520026a2001410f6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d1320032006360204200320053602000b2003200241016a360208200520026a200141106a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d1420032006360204200320053602000b2003200241016a360208200520026a200141116a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d1520032006360204200320053602000b2003200241016a360208200520026a200141126a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d1620032006360204200320053602000b2003200241016a360208200520026a200141136a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d1720032006360204200320053602000b2003200241016a360208200520026a200141146a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d1820032006360204200320053602000b2003200241016a360208200520026a200141156a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d1920032006360204200320053602000b2003200241016a360208200520026a200141166a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d1a20032006360204200320053602000b2003200241016a360208200520026a200141176a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d1b20032006360204200320053602000b2003200241016a360208200520026a200141186a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d1c20032006360204200320053602000b2003200241016a360208200520026a200141196a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d1d20032006360204200320053602000b2003200241016a360208200520026a2001411a6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d1e20032006360204200320053602000b2003200241016a360208200520026a2001411b6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d1f20032006360204200320053602000b2003200241016a360208200520026a2001411c6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d2020032006360204200320053602000b2003200241016a360208200520026a2001411d6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d2120032006360204200320053602000b2003200241016a360208200520026a2001411e6a2d00003a000002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d2420024101742206200520052006491b22064100480d240240024020020d002006103221050c010b200328020020022006103421050b2005450d2220032006360204200320053602000b2003200241016a360208200520026a2001411f6a2d00003a0000200141206a28020021060240024020032802042205200328020822026b4104490d00200328020021050c010b200241046a22072002490d2420054101742208200720072008491b22074100480d240240024020050d002007103221050c010b200328020020052007103421050b2005450d2320032007360204200320053602000b2003200241046a360208200520026a20063600002004200141246a2201470d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20074101102e000b1033000bc738030a7f077e067f230022042105200441e0016b41607122042400024002400240024002400240200141ffffff3f712001470d0020014105742206417f4c0d000240024020060d00410121070c010b200610322207450d020b410021084100210602402001450d002001410574210820072106034020062000290000370000200641186a200041186a290000370000200641106a200041106a290000370000200641086a200041086a290000370000200641206a2106200041206a2100200841606a22080d000b200141057441606a41057641016a2106200121080b20042006360218200420083602142004200736021020072006200441d8016a410041202006676b10d30120044180016a41086a22004200370300200442003703800141d8dcc300411d20044180016a1003200441a0016a41086a200029030037030020042004290380013703a0012004410036028001200441a0016a411020044180016a10062100024002402004280280012208417f460d002000450d00200420083602442004200036024020044180016a200441c0006a10312004280280012209450d0420044188016a2802002106200428028401210a2008450d01200010290c010b4100210a41012109410021060b2006410574220b450d05200441a0016a411472210c200441a0016a410872210d200921000340200041086a290000210e200041106a290000210f20002900002110200441206a41186a200041186a290000370300200441206a41106a200f370300200441206a41086a200e37030020042010370320200441c0006a200441206a10af03200441003602a80120042903582110200420042903b801221137035820042903502112200420042903b001221337035020042903402114200420042903a0013703402004290348210e200420042903a801220f3703482013422088a72115200f422088a721012011a72107200fa721060240200ea72208450d00200420143703a0012004200e3703a801200420123703b001200420103703b801200420082012a74105746a36028c0120042008360288012004200e422088a73602840120042008360280012004200441106a36029001200441f0006a20044180016a1048200d41086a200441f0006a41086a2216280200360200200d200429037037020020042012422088a722082010422088a74105746a36028c01200420083602880120042010a73602840120042008360280012004200441106a36029001200441f0006a20044180016a1048200c41086a2016280200360200200c200429037037020020042903a801210e20042903a001211220042903b801210f20042903b001211002402006450d0002402001450d00200610290b2007450d00201510290b200420123703402004200e370348200e422088a72101200420103703502010422088a721152004200f370358200ea72106200fa721070b0240024020060d00411a10322206450d06200641002900f5dc43370000200641186a41002f008ddd433b0000200641106a4100290085dd43370000200641086a41002900fddc433700002004429a808080a0033702a401200420063602a0012004200441a0016a36028001200441206a20044180016a10850120042802a401210820042802a001210620042802a8012101200441a0016a41186a22074200370300200441a0016a41106a22154200370300200441a0016a41086a22164200370300200442003703a00120062001200441a0016a100020044180016a41186a200729030037030020044180016a41106a201529030037030020044180016a41086a2016290300370300200420042903a0013703800120044180016a412010042008450d01200610290c010b411a10322208450d06200841002900f5dc43370000200841186a41002f008ddd433b0000200841106a4100290085dd43370000200841086a41002900fddc433700002004429a808080a0033702a401200420083602a0012004200441a0016a36028001200441206a20044180016a10850120042802a401211620042802a001210820042802a8012117200441a0016a41186a22184200370300200441a0016a41106a22194200370300200441a0016a41086a221a4200370300200442003703a00120082017200441a0016a100020044180016a41186a201829030037030020044180016a41106a201929030037030020044180016a41086a201a290300370300200420042903a0013703800120044180016a200441c0006a10b00302402016450d00200810290b02402001450d00200610290b2007450d00201510290b200041206a2100200b41606a220b0d000c060b0b102f000b20064101102e000b41f7cdc3004133200441d8016a41ecd6c3001054000b411a4101102e000b411a4101102e000b0240200a450d00200910290b200441003602a801200442013703a0012003200441a0016a106602400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402003450d00200220034105746a210103400240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d03200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a20022d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d04200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241016a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d05200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241026a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d06200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241036a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d07200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241046a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d08200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241056a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d09200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241066a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d0a200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241076a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d0b200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241086a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d0c200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241096a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d0d200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002410a6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d0e200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002410b6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d0f200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002410c6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d10200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002410d6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d11200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002410e6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d12200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002410f6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d13200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241106a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d14200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241116a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d15200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241126a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d16200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241136a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d17200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241146a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d18200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241156a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d19200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241166a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d1a200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241176a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d1b200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241186a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d1c200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241196a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d1d200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002411a6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d1e200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002411b6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d1f200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002411c6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d20200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002411d6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d21200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002411e6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d22200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002411f6a2d00003a0000200241206a22022001470d000b0b20042802a401210020042802a801210620042802a001210220044180016a41086a22084200370300200442003703800141a4d6c300411b20044180016a1003200441a0016a41086a200829030037030020042004290380013703a001200441a0016a411020022006100502402000450d00200210290b02402004280214450d00200428021010290b200524000f0b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b1033000ba50101027f230041206b22032400410021042003410036021420012002200341146a100621010240024020032802142202417f460d002001450d002003410036020c20024104490d0120012800002104200341003602102002417c714104460d012001280004210220011029200041086a200236020020002004360204410121040b20002004360200200341206a24000f0b41f7cdc3004133200341186a41ecd6c3001054000bc908030c7f037e027f230041e0016b22022400024002400240024002400240410e10322203450d00200341066a41002900fedc41370000200341002900f8dc413700002003410e411c10342204450d012004200136000e200241306a41186a22034200370300200241306a41106a22014200370300200241306a41086a220542003703002002420037033020044112200241306a1000200241106a41186a2003290300370300200241106a41106a2001290300370300200241106a41086a200529030037030020022002290330370310200241003602b801200241106a4120200241b8016a100621060240024020022802b8012207417f460d002002200736025420022006360250200241086a200241d0006a102c20022802080d072002280254220541216e220841216c2203417f4c0d04200228020c21090240024020030d004101210a0c010b20031032220a450d060b02402009450d004100210b03402005450d0820022005417f6a220536025420022002280250220c41016a360250200c2d0000220341014b0d084100210d0240024020030e020100010b41002103200241003a00d8010340024020052003470d0020024100360254200341ff0171450d0b200241003a00d8010c0b0b200241b8016a20036a200c20036a220141016a2d00003a00002002200141026a3602502002200341016a22013a00d8012001210320014120470d000b200241306a41106a200241b8016a41106a290300220e37030020024198016a41086a200241b8016a41086a29030037030020024198016a41106a200e37030020024198016a41186a200241b8016a41186a2903003703002002200520016b2205360254200220022903b801370398014101210d0b200b41016a2101200241f8006a41186a20024198016a41186a290300220e370300200241f8006a41106a20024198016a41106a290300220f370300200241f8006a41086a20024198016a41086a2903002210370300200241d8006a41086a220c2010370300200241d8006a41106a2211200f370300200241d8006a41186a2212200e3703002002200229039801220e3703782002200e37035802402008200b470d000240200b4101742203200120012003491b2208ad42217e220e422088a70d00200ea722034100480d0002400240200b0d0020031032210a0c010b200a200b41216c20031034210a0b200a0d0120034101102e000b1033000b200a200b41216c6a2203200d3a000020032002290358370001200341096a200c290300370000200341116a2011290300370000200341196a20122903003700002001210b20012009470d000b0b200a450d072009ad4220862008ad84210e02402007450d00200610290b2000200e3702042000200a3602000c010b20004100360208200042013702000b20041029200241e0016a24000f0b410e4101102e000b411c4101102e000b102f000b20034101102e000b2008450d00200a10290b41f7cdc3004133200241b8016a41ecd6c3001054000bbe2901057f024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2202280200200141086a22032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d0120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00003a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d0220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00013a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d0320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00023a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d0420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00033a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d0520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00043a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d0620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00053a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d0720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00063a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d0820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00073a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d0920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00083a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d0a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00093a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d0b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d0c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d0d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d0e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d0f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000e3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d1020012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d000f3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d1120012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00103a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d1220012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00113a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d1320012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00123a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d1420012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00133a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d1520012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00143a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d1620012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00153a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d1720012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00163a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d1820012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00173a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d1920012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00183a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d1a20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d00193a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d1b20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001a3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d1c20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001b3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d1d20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001c3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d1e20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001d3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d1f20012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001e3a000002400240200228020020032802002204460d00200128020021050c010b200441016a22052004490d2220044101742206200520052006491b22064100480d220240024020040d002006103221050c010b200128020020042006103421050b2005450d2020012005360200200141046a2006360200200141086a28020021040b2003200441016a360200200520046a20002d001f3a0000200028022021040240024020022802002202200328020022006b4104490d00200128020021020c010b200041046a22052000490d2220024101742200200520052000491b22004100480d220240024020020d002000103221020c010b200128020020022000103421020b2002450d2120012002360200200141046a2000360200200141086a28020021000b2003200041046a360200200220006a20043600000f0b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20004101102e000b1033000bc30201067f23004180016b220224000240411710322203450d00200341002900f9f9433700002003410f6a4100290088fa43370000200341086a4100290081fa4337000020024297808080f00237020c200220033602082001200241086a108101200228020c21012002280210210420022802082103200241086a41186a22054200370300200241086a41106a22064200370300200241086a41086a220742003703002002420037030820032004200241086a1000200241e0006a41186a2005290300370300200241e0006a41106a2006290300370300200241e0006a41086a200729030037030020022002290308370360200241086a200241e0006a10a8010240024020022d00084102470d00200041023a00000c010b2000200241086a41d800109b051a0b02402001450d00200310290b20024180016a24000f0b41174101102e000bbc0301057f230041106b2203240002400240024002400240200141046a2204417f4c0d000240024020040d00410121050c010b200410322205450d020b2003410036020820032004360204200320053602002001200310660240024020032802042206200328020822056b2001490d00200328020021040c010b200520016a22042005490d0520064101742207200420042007491b22074100480d050240024020060d002007103221040c010b200328020020062007103421040b2004450d032003200736020420032004360200200721060b200420056a20002001109b051a02400240200241046a2802002207200241086a28020022006b200520016a2201490d00200228020021050c010b200020016a22052000490d0520074101742200200520052000491b22004100480d050240024020070d002000103221050c010b200228020020072000103421050b2005450d0420022005360200200241046a2000360200200241086a28020021000b200241086a200020016a360200200520006a20042001109b051a02402006450d00200410290b200341106a24000f0b102f000b20044101102e000b20074101102e000b20004101102e000b1033000b9a0201067f230041c0006b220224000240411710322203450d00200341002900f9f9433700002003410f6a4100290088fa43370000200341086a4100290081fa4337000020024297808080f002370224200220033602202000200241206a108101200228022421002002280228210420022802202103200241206a41186a22054200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020032004200241206a1000200241186a2005290300370300200241106a2006290300370300200241086a20072903003703002002200229032037030020024120360224200220023602202001200241206a10dc0302402000450d00200310290b200241c0006a24000f0b41174101102e000b880201067f230041c0006b220124000240411710322202450d00200241002900f9f9433700002002410f6a4100290088fa43370000200241086a4100290081fa4337000020014297808080f002370224200120023602202000200141206a108101200128022421002001280228210320012802202102200141206a41186a22044200370300200141206a41106a22054200370300200141206a41086a220642003703002001420037032020022003200141206a1000200141186a2004290300370300200141106a2005290300370300200141086a20062903003703002001200129032037030020014120100402402000450d00200210290b200141c0006a24000f0b41174101102e000b02000b1100200028020020002802042001109c020bba0f020d7f017e230041206b220324004101210402400240200228021841222002411c6a2802002802101103000d000240024020010d00410021050c010b200020016a21062000210741002105410021080240034020072109200741016a210a02400240024020072c0000220b417f4a0d0002400240200a2006470d004100210c200621070c010b20072d0001413f71210c200741026a220a21070b200b411f7121040240200b41ff0171220b41df014b0d00200c200441067472210b0c020b0240024020072006470d004100210d2006210e0c010b20072d0000413f71210d200741016a220a210e0b200d200c41067472210c0240200b41f0014f0d00200c2004410c7472210b0c020b02400240200e2006470d004100210b200a21070c010b200e41016a2107200e2d0000413f71210b0b200c4106742004411274418080f0007172200b72220b418080c400470d020c040b200b41ff0171210b0b200a21070b4102210a024002400240024002400240200b41776a220c411e4d0d00200b41dc00470d010c020b41f400210e02400240200c0e1f05010202000202020202020202020202020202020202020202030202020203050b41f200210e0c040b41ee00210e0c030b02400240200b1086050d00024002400240024002400240024002400240200b41808004490d00200b41808008490d01200b4190fc476a4190fc0b490d09200b41e28b746a41e28d2c490d09200b419fa8746a419f18490d09200b41dee2746a410e490d09200b41feffff0071419ef00a460d09200b41a9b2756a4129490d09200b41cb91756a410a4d0d090c0e0b200b4180fe0371410876210f41d090c600210c410021040340200c41026a210d2004200c2d0001220a6a210e0240200c2d0000220c200f460d00200c200f4b0d08200e2104200d210c200d41a291c600470d010c080b200e2004490d02200e41a5024b0d03200441a291c6006a210c02400340200a450d01200a417f6a210a200c2d00002104200c41016a210c2004200b41ff0171470d000c0b0b0b200e2104200d210c200d41a291c600470d000c070b0b200b4180fe0371410876210f418196c600210c410021040340200c41026a210d2004200c2d0001220a6a210e0240200c2d0000220c200f460d00200c200f4b0d06200e2104200d210c200d41c796c600470d010c060b200e2004490d03200e41a6014b0d04200441c796c6006a210c02400340200a450d01200a417f6a210a200c2d00002104200c41016a210c2004200b41ff0171470d000c0a0b0b200e2104200d210c200d41c796c600470d000c050b0b2004200e1030000b200e41a502108f01000b2004200e1030000b200e41a601108f01000b200b41ffff0371210e41ed97c600210a4101210c02400340200a41016a210d02400240200a2d00002204411874411875220f4100480d00200d210a0c010b200d41859bc600460d02200f41ff0071410874200a2d0001722104200a41026a210a0b200e20046b220e4100480d03200c410173210c200a41859bc600470d000c030b0b41e882c600106d000b200b41ffff0371210e41c793c600210a4101210c0340200a41016a210d02400240200a2d00002204411874411875220f4100480d00200d210a0c010b200d418196c600460d04200f41ff0071410874200a2d0001722104200a41026a210a0b200e20046b220e4100480d01200c410173210c200a418196c600470d000b0b200c4101710d050b200b41017267410276410773ad4280808080d0008421104103210a0c020b41e882c600106d000b0b200b210e0b2003200136020420032000360200200320053602082003200836020c0240024020082005490d0002402005450d0020052001460d00200520014f0d01200020056a2c000041bf7f4c0d010b02402008450d0020082001460d00200820014f0d01200020086a2c000041bf7f4c0d010b2002280218200020056a200820056b200228021c28020c110400450d01410121040c060b20032003410c6a3602182003200341086a36021420032003360210200341106a108d05000b0340200a210c4101210441dc0021054101210a024002400240024002400240200c0e0402010500020b02400240024002402010422088a741ff01710e06050302010006050b201042ffffffff8f60834280808080308421104103210a41f50021050c070b201042ffffffff8f60834280808080208421104103210a41fb0021050c060b200e2010a7220c410274411c7176410f71220a413072200a41d7006a200a410a491b21050240200c450d002010427f7c42ffffffff0f832010428080808070838421100c050b201042ffffffff8f60834280808080108421100c040b201042ffffffff8f608321104103210a41fd0021050c040b4100210a200e21050c030b4101210a0240200b418001490d004102210a200b418010490d0041034104200b41808004491b210a0b200a20086a21050c040b201042ffffffff8f60834280808080c0008421100b4103210a0b20022802182005200228021c2802101103000d050c000b0b200820096b20076a210820062007470d000b0b2005450d0020052001460d00200520014f0d02200020056a2c000041bf7f4c0d020b410121042002280218200020056a200120056b200228021c28020c1104000d0020022802184122200228021c28021011030021040b200341206a240020040f0b2000200120052001108305000b13002000410a360204200041e8dec1003602000b3400200041d9d7c20036020420004100360200200041146a4110360200200041106a418885c200360200200041086a42073702000b13002000410a360204200041eca1c2003602000b3101017f02404104103222020d0041044101102e000b20004284808080c00037020420002002360200200241c0003600000b3201017f02404104103222020d0041044101102e000b20004284808080c0003702042000200236020020024180c2033600000b3001017f02404104103222020d0041044101102e000b20004284808080c00037020420002002360200200241013600000b3001017f02404104103222020d0041044101102e000b20004284808080c00037020420002002360200200241063600000b3d01017f02404110103222020d0041104101102e000b200242003700082002428080d287e2bc2d370000200042908080808002370204200020023602000b3e01017f02404110103222020d0041104101102e000b2002420037000820024280809aa6eaafe301370000200042908080808002370204200020023602000bb20201037f23004180016b2202240002400240024002400240200128020022034110710d002000280200210420034120710d012004ad4101200110a70221000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d0220014101418882c6004102200220006a4180016a410020006b10a80221000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d0220014101418882c6004102200220006a4180016a410020006b10a80221000b20024180016a240020000f0b20044180011030000b20044180011030000bd50203027f017e037f230041306b22032400412721040240024020004290ce005a0d00200021050c010b412721040340200341096a20046a2206417c6a200020004290ce0080220542f0b17f7e7ca7220741ffff037141e4006e2208410174419affc5006a2f00003b00002006417e6a2008419c7f6c20076a41ffff0371410174419affc5006a2f00003b00002004417c6a2104200042ffc1d72f5621062005210020060d000b0b02402005a7220641e3004c0d00200341096a2004417e6a22046a2005a7220741ffff037141e4006e2206419c7f6c20076a41ffff0371410174419affc5006a2f00003b00000b024002402006410a480d00200341096a2004417e6a22046a2006410174419affc5006a2f00003b00000c010b200341096a2004417f6a22046a200641306a3a00000b2002200141e480c6004100200341096a20046a412720046b10a8022104200341306a240020040be40501057f024002402001450d00412b418080c4002000280200220641017122011b2107200120056a21080c010b200541016a210820002802002106412d21070b0240024020064104710d00410021020c010b4100210902402003450d002003210a200221010340200920012d000041c00171418001466a2109200141016a2101200a417f6a220a0d000b0b200820036a20096b21080b410121010240024020002802084101460d0020002007200220031082050d012000280218200420052000411c6a28020028020c1104000f0b02402000410c6a280200220920084b0d0020002007200220031082050d012000280218200420052000411c6a28020028020c1104000f0b0240024020064108710d00200920086b210941002101024002400240410120002d0030220a200a4103461b0e0402000100020b20092101410021090c010b20094101762101200941016a41017621090b200141016a210103402001417f6a2201450d0220002802182000280204200028021c280210110300450d000b41010f0b41012101200041013a00302000413036020420002007200220031082050d01200920086b210941002101024002400240410120002d0030220a200a4103461b0e0402000100020b20092101410021090c010b20094101762101200941016a41017621090b200141016a2101024003402001417f6a2201450d0120002802182000280204200028021c280210110300450d000b41010f0b2000280204210a41012101200028021820042005200028021c28020c1104000d01200941016a2109200028021c210320002802182100034002402009417f6a22090d0041000f0b410121012000200a2003280210110300450d000c020b0b2000280204210a4101210120002007200220031082050d00200028021820042005200028021c28020c1104000d00200941016a2109200028021c210320002802182100034002402009417f6a22090d0041000f0b410121012000200a2003280210110300450d000b0b20010bb42007017f027e037f017e037f017e097f230041e0066b2202240042022103024002400240024002400240024002400240200129036822044202520d00200241106a20014198016a418801109b051a0c010b200241fc016a41026a200141036a2d00003a0000200241e0016a41086a200141146a290200370300200241e0016a410d6a200141196a290000370000200220012f00013b01fc012002200129020c3703e00120012d000021052001280204210620012802082107200241b8026a200141dc006a290000370300200241b0026a200141d4006a290000370300200241a8026a200141cc006a290000370300200241a0026a200141c4006a29000037030020024180026a41186a2001413c6a29000037030020024180026a41106a200141346a29000037030020024180026a41086a2001412c6a2900003703002002200129002437038002200241c0026a41086a20014188016a290300370300200241c0026a41106a20014190016a290300370300200220014180016a2903003703c002200141f8006a29030021032001290370210841002109200241e0036a410010aa02200241e0056a410d6a220a200241e0036a41186a290000370000200241e0056a41086a220b200241f3036a29000037030020024198066a41026a20022d00e2033a000020024180066a41086a200b29030037030020024180066a410d6a200a290000370000200220022f01e0033b019806200220022900eb03220c3703e0052002200c3703800620022800e303210d20022800e703210e200241086a41d983c300410d105d02400240024002400240024020044201520d0020084200510d01200228020c410020022802081b210a417f2109200aad220c20032003200c541b220c200c20037d2008827d220c42ffffffff0f560d00200ca721090b41101032220a450d01200a41086a41002900908443370000200a41002900888443370000200a411041201034220a450d02200a2009360010200241c0066a41186a220f4200370300200241c0066a41106a220b4200370300200241c0066a41086a22104200370300200242003703c006200a4114200241c0066a1000200241a0066a41186a200f290300370300200241a0066a41106a200b290300370300200241a0066a41086a2010290300370300200220022903c0063703a0064101210f200241a0066a412041014100410010072110200a1029024002402010417f470d00411f210a41fc88c30021090c010b200241e0036a200910aa02200241a2066a20022d00e2033a0000200241c8066a200241f3036a290000370300200241cd066a200241e0036a41186a290000370000200220022f01e0033b01a006200220022900eb033703c00620022800e303210920022800e703210a4100210f0b2002419c066a41026a2210200241a0066a41026a2d00003a0000200241e0036a41086a2211200241c0066a41086a2212290300370300200241e0036a41106a200b290300370300200220022f01a0063b019c06200220022903c0063703e00302400240200f450d002002200a3602d8034101210b200a210f200921100c010b201220024180066a41086a290300370300200241c0066a410d6a20024180066a410d6a290000370000200220022f0198063b01d80320022002290380063703c006200220024198066a41026a2d00003a00da032002200d3600db03200220022f019c063b01d403200220102d00003a00d603200241a0066a410d6a200241e0036a410d6a290000370000200241a0066a41086a2011290300370300200220022903e0033703a0064100210b419a01211020022802d803210f0b200241b8036a41086a220d200241c0066a41086a2211290300370300200241b8036a410d6a2212200241c0066a410d6a221329000037000020024198036a410d6a2214200241a0066a410d6a29000037000020024198036a41086a2215200241a0066a41086a290300370300200220022f01dc033b01d003200220022903c0063703b803200220022f01d4033b01b403200220022d00d6033a00b603200220022903a006370398032002200241de036a2d00003a00d2030240200b450d002000201036020420004101360200200041086a200f36020020014198016a102a0c0d0b200241f8026a41086a220b200d290300370300200241f8026a410d6a220d2012290000370000200241d8026a41086a22122015290300370300200241d8026a410d6a22152014290000370000200220022d00d2033a009603200220022f01d0033b019403200220022903b8033703f802200220022f01b4033b01f402200220022d00b6033a00f60220022002290398033703d802200241e0036a20014198016a418801109b051a200241e0036a4198016a2003370300200241f0046a20083703002002419c056a2214200f360200200241a3056a200e36000020024180056a220f20022903c00237030020024188056a200241c0026a41086a29030037030020024190056a200241d0026a290300370300200241a0056a20022f0194033b0100200241a2056a20022d0096033a0000200241a7056a20022903f802370000200241af056a200b290300370000200241b4056a200d290000370000200220043703e8042002201036029805200241bf056a2009360000200241c3056a200a360000200241be056a20022d00f6023a0000200241bc056a20022f01f4023b0100200241c7056a20022903d802370000200241cf056a2012290300370000200241d4056a201529000037000020024198036a41026a2201200241fc016a41026a2d00003a0000200220022f01fc013b0198032011200241e0016a41086a2903003703002013200241e0016a410d6a290000370000200220022903e0013703c0060240200541ff01714101460d00200241d8036a41026a20012d00003a000020024180066a41086a200241c0066a41086a29030037030020024180066a410d6a200241c0066a410d6a290000370000200220022f0198033b01d803200220022903c006370380060c040b200241b8036a200641067610ab0220022802b803210a0240024020022802c0032006413f7122014b0d00410021010c010b200241d8036a41026a200a20014105746a220141026a2d00003a000020024188066a200141136a2900003703002002418d066a200141186a290000370000200220012f00003b01d8032002200129000b370380062001280007210720012800032106410121010b024020022802bc03450d00200a10290b20010d034101210141c8d8c3002106411521070c040b41c8f7c500106d000b41104101102e000b41204101102e000b200241b8036a41026a200241d8036a41026a2d00003a0000200241c0066a41086a20024180066a41086a290300370300200241c0066a410d6a20024180066a410d6a290000370000200220022f01d8033b01b80320022002290380063703c006410021010b2002419c066a41026a220a200241b8036a41026a2d00003a0000200241a0066a41086a2209200241c0066a41086a290300370300200241a0066a41106a200241c0066a41106a290300370300200220022f01b8033b019c06200220022903c0063703a00602402001450d002000200636020420004101360200200041086a2007360200200241e0036a102a0c080b200241f3056a2009290300370000200241f8056a200241ad066a290000370000200220022f019c063b01e005200220073600e705200220063600e305200220022903a0063700eb052002200a2d00003a00e205410410322201450d01200242043702c406200220013602c006200241e0036a200241c0066a105f0240024020022903e8044201510d000240024020022802c40620022802c8062201460d0020022802c006210a0c010b200141016a220a2001490d0820014101742209200a200a2009491b22094100480d080240024020010d0020091032210a0c010b20022802c006200120091034210a0b200a450d05200220093602c4062002200a3602c00620022802c80621010b2002200141016a3602c806200a20016a41003a00000c010b20022903f80420022903f0042204420c882203420120034201561b8021030240024020022802c406220a20022802c80622016b4102490d0020022802c006210a0c010b200141026a22092001490d07200a4101742201200920092001491b22014100480d0702400240200a0d0020011032210a0c010b20022802c006200a20011034210a0b200a450d05200220013602c4062002200a3602c00620022802c80621010b2002200141026a3602c806200a20016a2003a741047420047aa7417f6a22014101200141014b1b2201410f2001410f491b723b00000b200f200241c0066a109801200220024188056a3602a006200241a0066a200241c0066a109b0120022802980521090240024020022802c406220a20022802c80622016b4104490d0020022802c006210a0c010b200141046a220b2001490d06200a4101742201200b200b2001491b22014100480d0602400240200a0d0020011032210a0c010b20022802c006200a20011034210a0b200a450d05200220013602c4062002200a3602c00620022802c80621010b2002200141046a3602c806200a20016a20093600002002200241c0066a3602a0062014200241a0066a1085012002200241c0066a3602a006200241bc056a200241a0066a10850120022802c006210120022802c406210a0240024020022802c80622094180024b0d0020024180026a20012009200241e0056a10ac0221090c010b200241c0066a41186a220b4200370300200241c0066a41106a220f4200370300200241c0066a41086a22064200370300200242003703c00620012009200241c0066a1000200241a0066a41186a200b290300370300200241a0066a41106a200f290300370300200241a0066a41086a2006290300370300200220022903c0063703a00620024180026a200241a0066a4120200241e0056a10ac0221090b0240200a450d00200110290b2009450d06200241c0016a41186a200241e0056a41186a290300370300200241c0016a41106a200241e0056a41106a290300370300200241c0016a41086a200241e0056a41086a29030037030020024198016a41086a200241f8046a29030037030020024198016a41106a20024180056a29030037030020024198016a41186a20024188056a290300370300200241b8016a20024190056a290300370300200220022903e0053703c0012002200241f0046a2903003703980120022903e8042103200241106a200241e0036a418801109b051a0b200041086a20022903c001370300200041286a2003370300200041306a200229039801370300200041206a200241c0016a41186a290300370300200041186a200241c0016a41106a290300370300200041106a200241c0016a41086a290300370300200041386a20024198016a41086a290300370300200041c0006a20024198016a41106a290300370300200041c8006a20024198016a41186a290300370300200041d0006a20024198016a41206a290300370300200041d8006a200241106a418801109b051a20004100360200200241e0066a24000f0b41044101102e000b20094101102e000b20014101102e000b20014101102e000b1033000b200041f7fcc20036020420004101360200200041086a411a360200200241e0036a102a0b200241e0066a24000bdf0201047f230041d0006b2202240002400240411010322203450d00200341086a4100290090844337000020034100290088844337000020034110412010342203450d0120032001360010200241086a41186a22014200370300200241086a41106a22044200370300200241086a41086a220542003703002002420037030820034114200241086a1000200241306a41186a2001290300370300200241306a41106a2004290300370300200241306a41086a200529030037030020022002290308370330200241086a200241306a412010590240024020022d00084101460d0020004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b20002002290009370000200041186a200241216a290000370000200041106a200241196a290000370000200041086a200241116a2900003700000b20031029200241d0006a24000f0b41104101102e000b41204101102e000bec0202047f017e230041d0006b22022400024002400240410f10322203450d00200341076a41002900c6d643370000200341002900bfd6433700002003410f411e10342203450d012003200136000f200241286a41186a22014200370300200241286a41106a22044200370300200241286a41086a220542003703002002420037032820034113200241286a1000200241186a2001290300370300200241106a2004290300370300200241086a2005290300370300200220022903283703002002410036022820024120200241286a100621040240024020022802282201417f460d002002200136022420022004360220200241286a200241206a103120022802282205450d04200229022c210602402001450d00200410290b20002006370204200020053602000c010b20004100360208200042013702000b20031029200241d0006a24000f0b410f4101102e000b411e4101102e000b41f7cdc3004133200241c8006a41ecd6c3001054000b8305010f7f230041a0026b22042400200441c0016a41386a2205200041386a2206290000370300200441c0016a41306a2207200041306a2208290000370300200441c0016a41286a2209200041286a220a290000370300200441c0016a41206a220b200041206a220c290000370300200441c0016a41186a220d200041186a220e290000370300200441c0016a41106a220f200041106a2210290000370300200441c0016a41086a2211200041086a2212290000370300200420002900003703c0010240024020012002200441c0016a200310110d00410121000c010b20052006290000370300200720082900003703002009200a290000370300200b200c290000370300200d200e290000370300200f20102900003703002011201229000037030020044188026a2205200341086a29000037030020044190026a2206200341106a29000037030020044198026a2207200341186a290000370300200420002900003703c00120042003290000370380022004200441c0016a41e000109b05220041c0016a200041e000109b051a200041e0006a41386a200041386a290000370300200041e0006a41306a200041306a290000370300200041e0006a41286a200041286a290000370300200041e0006a41206a200041206a290000370300200041e0006a41186a200041186a290000370300200041e0006a41106a200041106a290000370300200041e0006a41086a200041086a29000037030020002000290000370360200041a0016a41186a2007290300370300200041a0016a41106a2006290300370300200041a0016a41086a200529030037030020002000290380023703a00120012002200041e0006a200041a0016a10154521000b200441a0026a240020000bf00702067f017e230041106b220224002002410036020820024201370300200028020021030240024002400240024002400240410410322204450d0020024284808080c0003702042002200436020020042003360000200028020421050240024020022802042206200228020822046b4104490d00200441046a2103200228020021060c010b200441046a22032004490d0720064101742207200320032007491b22074100480d070240024020060d002007103221060c010b200228020020062007103421060b2006450d0220022007360204200220063602000b20022003360208200620046a200536000020002802082103200041106a28020022042002106602402004450d002003200441286c6a210703402003200210ee01200341206a29030021080240024020022802042206200228020822046b4108490d00200228020021060c010b200441086a22052004490d0920064101742204200520052004491b22044100480d090240024020060d002004103221060c010b200228020020062004103421060b2006450d052002200436020420022006360200200228020821040b2002200441086a360208200620046a20083700002007200341286a2203470d000b0b0240024020002802144101460d0002400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d0920044101742206200320032006491b22064100480d090240024020040d002006103221030c010b200228020020042006103421030b2003450d062002200636020420022003360200200228020821040b2002200441016a360208200320046a41003a00000c010b02400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d0820044101742206200320032006491b22064100480d080240024020040d002006103221030c010b200228020020042006103421030b2003450d062002200636020420022003360200200228020821040b2002200441016a360208200320046a41013a0000200028021821060240024020022802042203200228020822046b4104490d00200228020021030c010b200441046a22052004490d0820034101742204200520052004491b22044100480d080240024020030d002004103221030c010b200228020020032004103421030b2003450d072002200436020420022003360200200228020821040b2002200441046a360208200320046a20063600000b2002280204210420012802002001280204200228020022032002280208100502402004450d00200310290b200241106a24000f0b41044101102e000b20074101102e000b20044101102e000b20064101102e000b20064101102e000b20044101102e000b1033000b130020004101360204200041e4b4c2003602000b1300200041023602042000419cb6c2003602000b3101017f02404104103222020d0041044101102e000b20004284808080c00037020420002002360200200241e8073600000b3101017f02404104103222020d0041044101102e000b20004284808080c00037020420002002360200200241e5003600000bb9990106197f017e037f017e087f0b7e230041e0046b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e0b000102030405060708090a000b200341f4026a4101360200200342013702e4022003418c9ac5003602e002200341053602b404200341c09ac5003602b0042003200341b0046a3602f002200341e0026a4188bac200107d000b200141086a2802002104200128020421050240024020022d00000d004101210620022d00014101460d010b41a0f9c2002107412a210841002109410121062004450d28200510290c280b200241196a2d00002107200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021182001410c6a2802002119200141146a280200211a200141106a280200211b20032002411a6a2901003703f802200320073a00f702200320083a00f602200320093b01f4022003200a3a00f3022003200b3a00f2022003200c3b01f0022003200d3a00ef022003200e3a00ee022003200f3b01ec02200320103a00eb02200320173a00e202200320183b01e002200320132012410874201141187472723600e702200320162015410874722014411874723600e302200320193602b804200320043602b404200320053602b0042003200341e0026a200341b0046a201b201a10b3022003280204210820032802002107410021090c270b200141086a2802002104200128020421050240024020022d00000d0020022d00014101460d010b41a0f9c2002107412a21080c260b2001410c6a2802002118200141146a2802002119200141106a280200211a200241196a2d00002107200241186a2d00002108200241166a2f01002106200241156a2d00002109200241146a2d0000210a200241126a2f0100210b200241116a2d0000210c200241106a2d0000210d2002410e6a2f0100210e2002410d6a2d0000210f2002410c6a2d000021102002410a6a2f01002111200241096a2d00002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f0100211720032002411a6a2901003703a004200320073a009f04200320083a009e04200320063b019c04200320093a009b042003200a3a009a042003200b3b0198042003200c3a0097042003200d3a0096042003200e3b0194042003200f3a009304200320163a008a04200320173b0188042003201220114108742010411874727236008f042003201520144108747220134118747236008b04410d10322202450d0841002107200241002900a3ba42370000200241056a41002900a8ba423700002003428d808080d0013702e402200320023602e00220034188046a200341e0026a10810120032802e402210620032802e802210920032802e0022102200341e0026a41186a220a4200370300200341e0026a41106a22084200370300200341e0026a41086a220b4200370300200342003703e00220022009200341e0026a1000200341b0046a41186a200a290300370300200341b0046a41106a2008290300370300200341b0046a41086a200b290300370300200320032903e0023703b004200341e0026a200341b0046a412010590240024020032d00e0024101460d000c010b200341f9026a290000211c200341f8026a2d0000210a200341f7026a2d0000210b200341f5026a2f0000210c200341f4026a2d0000210d200341f3026a2d0000210e200341f1026a2f0000210f20082d00002110200341ef026a2d00002111200341ed026a2f00002112200341ec026a2d00002113200341e8026a280200211520032802e402211420032d00e302210820032f00e1022109410121070b02402006450d00200210290b024020070d004198bac2002107410b21080c260b2003201c3703f8022003200a3a00f7022003200b3a00f6022003200c3b01f4022003200d3a00f3022003200e3a00f2022003200f3b01f002200320103a00ef02200320113a00ee02200320123b01ec02200320133a00eb02200320153600e702200320143600e302200320083a00e202200320093b01e002200320183602b804200320043602b404200320053602b004200341086a200341e0026a200341b0046a201a201910b302200328020c21082003280208210741012109410021060c260b200141216a290000211c200141206a2d0000210a2001411d6a2f0000210b2001411c6a2d0000210c200141196a2f0000210d200141186a2d0000210e200141156a2f0000210f200141146a2d00002110200141106a28020021112001410c6a2802002105200141086a2d00002117200141306a280200211d2001412c6a280200211e20012d001f211220012d001b211320012d0017211420012d000b211520012f000921162001280204211f2002411a6a2901002120200241196a2d00002118200241186a2d00002119200241166a2f0100211a200241156a2d0000211b200241146a2d00002121200241126a2f01002122200241116a2d00002123200241106a2d000021242002410e6a2f010021252002410d6a2d00002126200241046a2d00002127200241026a2f01002128412a210841a0f9c20021070240024020022d0000450d004101210641002109410021040c010b41012106410021094100210420022d00014101470d002002410c6a2d000021092002410a6a2f01002104200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d0000411874722107410021060b200441ffff0371410874200941187472200841ff017172210820060d23200320203703c802200320183a00c702200320193a00c6022003201a3b01c4022003201b3a00c302200320213a00c202200320223b01c002200320233a00bf02200320243a00be02200320253b01bc02200320263a00bb02200320083600b702200320073600b302200320273a00b202200320283b01b0020240201741ff01714101470d00200341e0026a200541067610ab0220032802e00221070240024020032802e8022005413f7122024b0d00410021020c010b200720024105746a2202290018211c20022d0017210a20022d0016211220022f0014210b20022d0013210c20022d0012211320022f0010210d20022d000f210e20022d000e211420022f000c210f20022d000b2110200228000721112002280003210520022d0002211520022f00002116410121020b024020032802e402450d00200710290b2002450d230b2003201c3703f8032003200a3a00f703200320123a00f6032003200b3b01f4032003200c3a00f303200320133a00f2032003200d3b01f0032003200e3a00ef03200320143a00ee032003200f3b01ec03200320103a00eb03200320113600e703200320053600e303200320153a00e203200320163b01e003200341d0036a41086a22024200370300200342003703d0034184dbc1004114200341d0036a1003200341d0026a41086a2002290300370300200320032903d0033703d0020240200341d0026a41104101410041001007417f460d0041b0bac2002107412621080c240b200341e0026a200341b0026a108f02024020032903e0024201510d0041d6bac2002107411821080c240b200341e0026a200341e0036a108f02024020032903e0024201510d0041b9bbc2002107412c21080c240b20034188036a280200210c20034180016a4195ebc5004111105d4184bbc20021074116210820032802840141002003280280011b201d470d230240200c41016a201d490d00419abbc2002107411f21080c240b200341e0026a201f41067610940241002107201f413f71220220032802e8024f0d1920032802e002200241216c6a22022d00004101470d1920022f00012106200241196a290000211c200241186a2d00002109200241176a2d00002104200241156a2f00002105200241146a2d0000210a200241136a2d0000210b200241116a2f0000210d200241106a2d0000210e2002410f6a2d0000210f2002410d6a2f000021102002410c6a2d00002111200241086a2800002113200241046a2800002112200241036a2d00002102410121070c1a0b41a0f9c2002107412a210820022d00000d2220022d00014101470d2220012802042116200241196a2d00002107200241186a2d00002108200241166a2f01002106200241156a2d00002109200241146a2d00002104200241126a2f01002105200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002114200241026a2f0100211520032002411a6a2901003703a004200320073a009f04200320083a009e04200320063b019c04200320093a009b04200320043a009a04200320053b0198042003200a3a0097042003200b3a0096042003200c3b0194042003200d3a009304200320143a008a04200320153b01880420032010200f41087472200e4118747236008f042003201320124108747220114118747236008b04200341d0036a41086a22024200370300200342003703d0034184dbc1004114200341d0036a1003200341d0026a41086a2002290300370300200320032903d0033703d0020240200341d0026a41104101410041001007417f460d0041ccbcc2002107411e21080c230b411310322202450d07200241002900fcdb413700002002410f6a410028008bdc41360000200241086a4100290084dc4137000020034293808080b0023702e402200320023602e00220034188046a200341e0026a10810120032802e402210720032802e802210620032802e002210241182108200341e0026a41186a22094200370300200341e0026a41106a22044200370300200341e0026a41086a22054200370300200342003703e00220022006200341e0026a1000200341b0046a41186a2009290300370300200341b0046a41106a2004290300370300200341b0046a41086a2005290300370300200320032903e0023703b004200341b0046a41204101410041001007210602402007450d00200210290b02402006417f470d0041eabcc20021070c230b200341b0046a2016410676109402410021072016413f71220220032802b8044f0d1620032802b004200241216c6a22022d00004101470d1620022f00012106200241196a290000211c200241186a2d00002109200241176a2d00002104200241156a2f00002105200241146a2d0000210a200241136a2d0000210b200241116a2f0000210c200241106a2d0000210d2002410f6a2d0000210e2002410d6a2f0000210f2002410c6a2d00002110200241086a2800002112200241046a2800002111200241036a2d00002102410121070c170b200128020421052002411a6a290100211c200241196a2d0000210a200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d00002113200241046a2d00002114200241026a2f0100211541a0f9c2002107412a21080240024020022d0000450d004101210641002109410021040c010b41012106410021094100210420022d00014101470d002002410c6a2d000021042002410a6a2f01002109200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d0000411874722107410021060b200941ffff0371410874200841ff017172200441187472210820060d212003201c3703a0042003200a3a009f042003200b3a009e042003200c3b019c042003200d3a009b042003200e3a009a042003200f3b019804200320103a009704200320113a009604200320123b019404200320133a0093042003200836008f042003200736008b04200320143a008a04200320153b018804411610322202450d0720024100290089bb413700002002410e6a4100290097bb41370000200241086a4100290091bb4137000020034296808080e0023702e402200320023602e00220034188046a200341e0026a10810120032802e402210720032802e802210820032802e0022102200341e0026a41186a22064200370300200341e0026a41106a22094200370300200341e0026a41086a22044200370300200342003703e00220022008200341e0026a1000200341b0046a41186a2006290300370300200341b0046a41106a2009290300370300200341b0046a41086a2004290300370300200320032903e0023703b004200341b0046a41204101410041001007210802402007450d00200210290b02402008417f460d004182bdc2002107411e21080c220b200341a0016a41ccebc5004116105d20032802a401210820032802a0012104200341d0036a41086a22024200370300200342003703d003418fdcc1004112200341d0036a1003200341d0026a41086a2002290300370300200320032903d0033703d002200341003602e002200341d0026a4110200341e0026a1006210720032802e002220a417f460d092007450d092003200a3602b404200320073602b004200341e0026a200341b0046a103120032802e0022206450d08200341e8026a280200210220032802e4022109200a450d0f200710290c0f0b200141386a290300211c200141306a29030021202001411d6a29000021292001411c6a2d00002116200141196a2f00002117200141186a2d00002118200141156a2f00002119200141146a2d0000211a200141116a2f0000211b200141106a2d000021212001410c6a2802002122200141086a2802002105200141286a280200211d20012d001b212320012d0017212420012d0013212520012d0007212620012f0005212720012d000421282002411a6a290100212a200241196a2d0000210a200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d00002113200241046a2d00002114200241026a2f0100211541a0f9c2002107412a21080240024020022d0000450d004101210641002109410021040c010b41012106410021094100210420022d00014101470d002002410c6a2d000021042002410a6a2f01002109200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d0000411874722107410021060b200941ffff0371410874200841ff017172200441187472210820060d202003202a3703f8032003200a3a00f7032003200b3a00f6032003200c3b01f4032003200d3a00f3032003200e3a00f2032003200f3b01f003200320103a00ef03200320113a00ee03200320123b01ec03200320133a00eb03200320083600e703200320073600e303200320143a00e203200320153b01e00302402020201c8450450d004192bec200210741d00021080c210b0240202841ff01714101470d00200341e0026a200541067610ab0220032802e00221070240024020032802e8022005413f7122024b0d00410021020c010b200720024105746a2202290018212920022d0017211620022d0016212320022f0014211720022d0013211820022d0012212420022f0010211920022d000f211a20022d000e212520022f000c211b20022d000b2121200228000721222002280003210520022d0002212620022f00002127410121020b024020032802e402450d00200710290b2002450d200b200320293703a004200320163a009f04200320233a009e04200320173b019c04200320183a009b04200320243a009a04200320193b0198042003201a3a009704200320253a0096042003201b3b019404200320213a0093042003202236008f042003200536008b04200320263a008a04200320273b0188044111210820034198026a4195ebc5004111105d4181bec2002107200328029c0241002003280298021b201d470d20200341d0036a41086a22024200370300200342003703d0034184dbc1004114200341d0036a1003200341d0026a41086a2002290300370300200320032903d0033703d002200341e0026a200341d0026a108902024020032802e802220a0d0041d4bdc2002107412d21080c210b20032902ec02212b20034190026a41baebc5004112105d20034180026a20032802940241002003280290021bad42004280a094a58d1d420010a005411410322202450d0920034180026a41086a290300212a200329038002212c200241002900d8d540370000200241106a41002800e8d540360000200241086a41002900e0d54037000020034294808080c0023702e402200320023602e002200341e0036a200341e0026a10810120032802e4022102200341e8016a20032802e002220820032802e80210a101200341e8016a41106a290300420020032802e80122071b212920032903f001420020071b212d02402002450d00200810290b202d202c542029202a542029202a511b450d0c4193bfc2002107412e21080c0d0b4101210620022d000120022d0000720d0a20012802042102200341d0036a41086a22074200370300200342003703d0034181ebc5004114200341d0036a1003200341d0026a41086a2007290300370300200320032903d0033703d002200320023602e002200341d0026a4110200341e0026a410410050c0e0b024020022d000120022d000072450d0041f8f8c2002107412821080c1f0b200141086a2802002107024020012d00044101460d00200141106a2d00002108200141146a2d00002106200141186a2d000021092001411c6a2d0000210420012f0005210220012d00072105200128020c210a20012f0011210b20012d0013210c20012f0015210d20012d0017210e20012f0019210f20012d001b2110200129001d211c0c090b200341e0026a200741067610ab0220032802e00221110240024020032802e8022007413f7122024b0d00410021120c010b201120024105746a2202290018211c20022d0017210420022d0016211020022f0014210f20022d0013210920022d0012210e20022f0010210d20022d000f210620022d000e210c20022f000c210b20022d000b21082002280007210a2002280003210720022d0002210520022f00002102410121120b024020032802e402450d00201110290b2012450d1d0c080b4101210620022d000120022d0000720d0820012802042102200341d0036a41086a22074200370300200342003703d00341bcdbc100411c200341d0036a1003200341d0026a41086a2007290300370300200320032903d0033703d002200320023602e002200341d0026a4110200341e0026a410410050c0c0b4101210620022d000120022d0000720d0720012802042102200341d0036a41086a22074200370300200342003703d00341a8dbc1004114200341d0036a1003200341d0026a41086a2007290300370300200320032903d0033703d002200320023602e002200341d0026a4110200341e0026a410410050c0b0b410d4101102e000b41134101102e000b41164101102e000b41f7cdc3004133200341d8046a41ecd6c3001054000b4100210941012106410021020c050b41144101102e000b2003201c3703c802200320043a00c702200320103a00c6022003200f3b01c402200320093a00c3022003200e3a00c2022003200d3b01c002200320063a00bf022003200c3a00be022003200b3b01bc02200320083a00bb022003200a3600b702200320073600b302200320053a00b202200320023b01b002200341d0036a41086a22024200370300200342003703d00341f5dac100410f200341d0036a1003200341d0026a41086a2002290300370300200320032903d0033703d002200341e0026a200341d0026a1088024100210720032802e402410020032802e00222021b210d4104210a2002410420021b2108024002400240024002400240200341e0026a41086a2206280200410020021b2205450d002008200541246c22096a21040340200341e0026a41206a200820076a220241206a280200360200200341e0026a41186a200241186a290200370300200341e0026a41106a200241106a2902003703002006200241086a290200370300200320022902003703e002200341e0026a200341b0026a4120109d050d022009200741246a2207470d000b0b4100210b0240200d0d004100210c0c020b200810294104210a4100210c0c010b20034188046a41086a200341e0026a41086a290300221c370300200341e0036a41086a2206201c370300200341e0036a41106a2209200341e0026a41106a290300370300200341e0036a41186a220b200341e0026a41186a290300370300200341e0036a41206a220c200341e0026a41206a280200360200200320032903e002221c370388042003201c3703e00341241032220a450d01200a20032903e003370200200a41206a200c280200360200200a41186a200b290300370200200a41106a2009290300370200200a41086a200629030037020002400240200541246c415c6a2007470d004101210b4101210c0c010b200241246a210f2004415c6a21104101210b4101210c0340200f210202400340200341e0026a41206a2207200241206a280200360200200341e0026a41186a2206200241186a290200370300200341e0026a41106a2209200241106a290200370300200341e0026a41086a2205200241086a290200370300200320022902003703e002200341e0026a200341b0026a4120109d050d012004200241246a2202470d000c030b0b200341b0046a41206a2007280200220e36020020034188046a41086a2005290300221c37030020034188046a41106a2009290300222037030020034188046a41186a2006290300222a37030020034188046a41206a200e360200200320032903e0022229370388042007200e3602002006202a370300200920203703002005201c370300200320293703e0020240200c200b470d00200b41016a220c200b490d15200b410174220e200c200c200e491b220cad42247e221c422088a70d15201ca7220e4100480d1502400240200b0d00200e1032210a0c010b200a200b41246c200e1034210a0b200a450d050b200241246a210f200a200b41246c6a220e20032903e002370200200e41206a2007280200360200200e41186a2006290300370200200e41106a2009290300370200200e41086a2005290300370200200b41016a210b20102002470d000b0b200d450d00200810290b200341d0036a41086a22024200370300200342003703d00341f5dac100410f200341d0036a1003200341d0026a41086a2002290300370300200320032903d0033703d002200341e0026a200a200b109102200341d0026a411020032802e002220220032802e8021005024020032802e402450d00200210290b200b41246c220241246d210941002108024020020d0041012104410021090c030b200941ffffff3f712009470d11200941057422024100480d112002103222040d0220024101102e000b41244104102e000b200e4104102e000b0240200b450d00200b41246c21064100210820042102200a21070340200741086a290000211c200741106a29000021202007290000212a200241186a200741186a290000370000200241106a2020370000200241086a201c3700002002202a370000200841016a2108200241206a2102200741246a21072006415c6a22060d000b0b0240200c450d00200a10290b200341e0026a41186a200341b0026a41186a290300370300200341e0026a41106a200341b0026a41106a290300370300200341e0026a41086a200341b0026a41086a290300370300200320032903b0023703e0024100210720042008200341d8046a410041202008676b10d30141012106200341e0026a4101200420081092022009450d10200410290c100b41f8f8c200210741282108410121090c160b200341d0036a41086a22024200370300200342003703d00341d8dbc1004113200341d0036a1003200341d0026a41086a2002290300370300200320032903d0033703d002200341e0026a200341d0026a108b02024020032802e002220c0d0041e2bec2002107413121080c010b0240024002400240200341e0026a41086a2802002213450d0020032802e402211041e4bfc200210741232108200c290300202054200c41086a2903002229201c542029201c511b0d010c020b4198dbc100410041001036000b200341d0036a41086a22024200370300200342003703d00341f5dac100410f200341d0036a1003200341d0026a41086a2002290300370300200320032903d0033703d002200341e0026a200341d0026a1088020240024020032802e00222040d00410421044100210b410021050c010b200341e8026a280200210520032802e402210b0b2004200541246c6a210920042102410021070240024003400240200920026b41ec004b0d0020092002460d032004200541246c6a2109034020034188046a2002460d032007200220034188046a4120109d0522064100476a21072006450d032009200241246a2202470d000c040b0b200220034188046a460d012007200220034188046a4120109d0522064100476a21072006450d01200241246a220620034188046a460d012007200620034188046a4120109d0522064100476a21072006450d01200241c8006a220620034188046a460d012007200620034188046a4120109d0522064100476a21072006450d01200241ec006a220620034188046a460d0120024190016a21022007200620034188046a4120109d0522064100476a210720060d000b0b2007202b422088a7490d004187c0c200210741362108200b450d01200410290c010b0240200b450d00200410290b200341a0026a108d02200341e0026a20034188046a108c0220032802e0024101460d01024020032802a402450d0020032802a00210290b41c1bfc20021070b2010450d01200c10290c010b20032802a002212602400240024002400240024020032802a80222020d004200212e4200212f0c010b20032802e4022106200241216c2107202641016a2102200341e8026a2802002208410876210941012008411f7174210d20084105764107712204417f73210e20034180036a21054200212e4200212f034002402002417f6a2d00004101470d00200341e0026a2002108f0220032903e0024201520d002003280288032006490d0020052903002130200341e0026a41106a290300213120032903f802213220032903e8022133200341e0016a4195ebc5004111105d200341b0046a41186a200241186a290000370300200341b0046a41106a200241106a290000370300200341b0046a41086a200241086a290000370300200320022900003703b004200320093602d004200341b0026a200341b0046a108e02420021294200212d0240200420032802b80222084f0d002008200e6a220b20084f0d04203020317c203220337c2229203254ad7c420020032802b002200b4102746a280200200d7122081b212d2029420020081b21290b024020032802b402450d0020032802b00210290b202d202f7c2029202e7c222e202954ad7c212f0b200241216a21022007415f6a22070d000b0b200c201341306c6a2106200c2102024002400240024003400240200620026b4190014b0d00024020022006460d00034041012108200241106a220220034188046a460d04200220034188046a4120109d05450d04200241206a22022006470d000b0b41002108202e202085202f201c858450450d0220034188046a41186a290300212a20034198046a290300212920034190046a290300212c200329038804212d200c201c370308200c2020370300200c202d370310200c41186a202c370300200c41206a2029370300200c41286a202a37030020134115490d072013410176221ead42307e221c422088a70d15201ca72202417f4c0d1520020d03410821254108210b0c040b41012108200241106a220720034188046a460d01200720034188046a4120109d05450d01200241c0006a220720034188046a460d01200720034188046a4120109d05450d01200241f0006a220720034188046a460d01200720034188046a4120109d05450d01200241a0016a220720034188046a460d01200241c0016a2102200720034188046a4120109d050d000b0b200341c0016a200341e0036a202c202a10c001200341c0016a41086a290300212a20032903c001211c200341d0036a41086a22024200370300200342003703d00341c2d5c0004116200341d0036a1003200341d0026a41086a22062002290300370300200320032903d0033703d002200341a8016a200341d0026a10eb01200341a8016a41106a290300212020032903b001212920032802a801210720024200370300200342003703d00341c2d5c0004116200341d0036a100320062002290300370300200320032903d0033703d002200342002020420020071b2220202a7d2029420020071b222a201c54ad7d2229202a201c7d221c202a56202920205620292020511b22021b3703e80220034200201c20021b3703e002200341d0026a4110200341e0026a4110100541bdc0c20041d3c0c20020081b21074116410f20081b2108410121020c060b200210322225450d012025210b0b200c41506a2128200c41306a211f200c41f07e6a211d4104211141002127410021184100210e20132117034020172104410021174101210902402004417f6a2208450d00024002400240024002400240200c200841306c6a2202290300200441306c220d200c6a41a07f6a2207290300222054200241086a290300222a200741086a290300221c54202a201c511b0d002004417e6a2105201d200d6a210241002117410021070340024020052007470d00200421090c080b2020200229030022295a2108201c200241086a290300222a512106201c202a5a2109200241506a2102200741016a210720292120202a211c2008200920061b0d000b200741016a21092007417f7320046a21080c010b201d200d6a210202400340024020084101470d00410021080c020b202020022903002229542107201c200241086a290300222a512106201c202a542109200241506a21022008417f6a210820292120202a211c2007200920061b0d000b0b20042008490d01200420134b0d03200420086b22094101762206450d002028200d6a2102200c200841306c6a21070340200341e0026a41286a2205200741286a220d290300370300200341e0026a41206a220f200741206a2212290300370300200341e0026a41186a2214200741186a2215290300370300200341e0026a41106a2216200741106a2217290300370300200341e0026a41086a2219200741086a221a290300370300200320072903003703e002200241086a221b290300211c200241106a22212903002120200241186a2222290300212a200241206a22232903002129200241286a2224290300212c20072002290300370300200d202c370300201220293703002015202a37030020172020370300201a201c370300202420052903003703002023200f2903003703002022201429030037030020212016290300370300201b2019290300370300200220032903e002370300200741306a2107200241506a21022006417f6a22060d000b0b024020080d00200821170c050b0240200941094d0d00200821170c050b200420134b0d01200420086b2106201f200841306c6a2105034020042008417f6a2217490d040240200420176b22094102490d00200c200841306c6a2202290300200c201741306c6a2208290300222a5a200241086a22072903002220200841086a220d290300221c5a2020201c511b0d00200341e0026a41186a2212200841286a220f290300370300200341e0026a41106a2214200841206a2215290300370300200341e0026a41086a2216200841186a2219290300370300200320082903103703e00220082002290300370300200d2007290300370300200841106a200241106a2903003703002019200241186a2903003703002015200241206a290300370300200f200241286a29030037030041012107024020094103490d002008290360202a5a200841e8006a2903002220201c5a2020201c511b0d004102210d2005210f0340200f220241506a22072002290300370300200741286a200241286a290300370300200741206a200241206a290300370300200741186a200241186a290300370300200741106a200241106a290300370300200741086a200241086a2903003703002006200d2207460d01200741016a210d200241306a220f290300202a5a200241386a2903002220201c5a2020201c511b450d000b0b2002202a3703002002201c3703082008200741306c6a220241286a2012290300370300200241206a2014290300370300200241186a2016290300370300200220032903e0023703100b2017450d05200541506a2105200641016a2106201721082009410a4f0d050c000b0b200820041030000b20042008417f6a2217490d010b20042013108f01000b201720041030000b024002400240200e2027470d00202741016a22022027490d1520274101742207200220022007491b220241ffffffff01712002470d15200241037422074100480d150240024020270d002007103221110c010b201120274103742007103421110b2011450d01200221272018210e0b2011200e4103746a2202200936020420022017360200201841016a220e2118200e4102490d010240034002400240024002402011200e417f6a22184103746a2202280200450d00200e41037420116a220641746a2802002208200228020422074d0d000240200e41024b0d00200e21184102210e0c080b2011200e417d6a22124103746a2802042202200720086a4d0d010240200e41034b0d00200e21184103210e0c080b200641646a280200200220086a4d0d01200e21180c070b200e4103490d01200228020421072011200e417d6a22124103746a28020421020b20022007490d010b200e417e6a21120b024002400240024002400240200e201241016a22194b221a450d00200e20124b221b450d01201120124103746a2214280204222120142802006a2202201120194103746a22152802002216490d02200220134b0d03200c201641306c6a220d2015280204220f41306c22076a2106200241306c2108200220166b2204200f6b2202200f4f0d0420252006200241306c2207109b051a200b20076a210902400240200f4101480d00200241014e0d010b20062102200b21070c060b202820086a21082006210203402008200241506a2206200941506a22042004290300200629030054200441086a290300221c200641086a290300222054201c2020511b22051b2207290300370300200841086a200741086a290300370300200841106a200741106a290300370300200841186a200741186a290300370300200841206a200741206a290300370300200841286a200741286a2903003703002009200420051b21090240200d2006200220051b2202490d00200b21070c070b200841506a2108200b2107200b2009490d000c060b0b419cffc0002019200e1036000b419cffc0002012200e1036000b201620021030000b20022013108f01000b2025200d2007109b051a200b20076a210902400240200f4101480d002004200f4a0d010b200d2102200b21070c010b200c20086a2105200b2107200d210203402002200620072006290300200729030054200641086a290300221c200741086a290300222054201c2020511b22041b2208290300370300200241086a200841086a290300370300200241106a200841106a290300370300200241186a200841186a290300370300200241206a200841206a290300370300200241286a200841286a2903003703002007200741306a20041b2107200241306a2102200641306a200620041b220620054f0d01200920074b0d000b0b20022007200920076b220820084130706b109b051a0240201b450d0020142016360200201441046a2021200f6a360200201a450d022015201541086a200e2019417f736a410374109c051a2018210e201841014d0d040c010b0b41acffc0002012200e1036000b418080c000106d000b20074104102e000b20170d000b02402027450d00201110290b201e450d03202510290c030b20024108102e000b4198dbc100200b20081036000b20134102490d002013417f6a2108200c201341306c6a21044101210603400240024002400240201320082202417f6a2208490d00201320086b22074102490d03200c200241306c6a2202290300200c200841306c6a2209290300222a5a200241086a22052903002220200941086a220b290300221c5a2020201c511b0d03200341e0026a41186a220d200941286a220e290300370300200341e0026a41106a220f200941206a2211290300370300200341e0026a41086a2212200941186a2214290300370300200320092903103703e00220092002290300370300200b2005290300370300200941106a200241106a2903003703002014200241186a2903003703002011200241206a290300370300200e200241286a2903003703004101210520074103490d022009290360202a5a200941e8006a2903002220201c5a2020201c511b0d02410021052004210703402007220241506a22072002290300370300200741286a200241286a290300370300200741206a200241206a290300370300200741186a200241186a290300370300200741106a200241106a290300370300200741086a200241086a29030037030020062005220b460d02200b417f6a2105200241306a2207290300202a5a200241386a2903002220201c5a2020201c511b0d020c000b0b200820131030000b4102200b6b21050b2002202a3703002002201c3703082009200541306c6a220241286a200d290300370300200241206a200f290300370300200241186a2012290300370300200220032903e0023703100b200441506a21042006417f6a210620080d000b0b200341d0036a41086a22024200370300200342003703d00341d8dbc1004113200341d0036a1003200341d0026a41086a2002290300370300200320032903d0033703d002200341103602e4022003200341d0026a3602e002200c2013200341e0026a108a0202402010450d00200c10290b41002102410021070b024020032802a402450d00202610290b0240024020020d00202ba7450d150c010b02402010450d00200c10290b202ba7450d140b200a10290c130b202ba7450d12200a10290c120b02400240024002402008410020041b22042005470d0020022005460d010b41a0bdc200210741162108200220054d0d01200341f8026a4200370300200341f0026a4200370300200341e8026a4200370300200342003703e002200620054105746a220a200341e0026a460d00200a200341e0026a4120109d050d010b20034198016a20034188046a4280809aa6eaafe3014200107e200328029801450d0141b6bdc2002107411e21080b2009450d12200610290c120b20034190016a4195ebc5004111105d200328029001210a200328029401210b411610322207450d0120074100290089bb413700002007410e6a4100290097bb41370000200741086a4100290091bb4137000020034296808080e0023702e402200320073602e00220034188046a200341e0026a10810120032802e402210c20032802e802210720032802e0022108200341e0026a41186a220d4200370300200341e0026a41106a220e4200370300200341e0026a41086a220f4200370300200342003703e00220082007200341e0026a1000200341b0046a41186a200d290300370300200341b0046a41106a200e290300370300200341b0046a41086a200f290300370300200320032903e0023703b004410810322207450d02200720053600042007200b4100200a1b360000200341b0046a4120200741081005200710290240200c450d00200810290b0240024020022005460d00200341e0026a41186a220820034188046a41186a290300370300200341e0026a41106a220a20034188046a41106a290300370300200341e0026a41086a220b20034188046a41086a29030037030020032003290388043703e002200220054d0d05200620054105746a220720032903e002370000200741186a2008290300370000200741106a200a290300370000200741086a200b2903003700000c010b200341e0026a41186a220720034188046a41186a290300370300200341e0026a41106a220820034188046a41106a290300370300200341e0026a41086a220a20034188046a41086a29030037030020032003290388043703e002024020092005470d00200541016a22022005490d0c20054101742209200220022009491b220941ffffff3f712009470d0c200941057422024100480d0c0240024020050d002002103221060c010b200620054105742002103421060b2006450d060b200620054105746a220220032903e002370000200241186a2007290300370000200241106a2008290300370000200241086a200a290300370000200541016a21020b200341d0036a41086a22074200370300200342003703d003418fdcc1004112200341d0036a1003200341d0026a41086a22082007290300370300200320032903d0033703d002200341103602e4022003200341d0026a3602e00220062002200341e0026a10950102402009450d00200610290b20074200370300200342003703d00341ccebc5004116200341d0036a100320082007290300370300200320032903d0033703d002410121062003200441016a3602e002200341d0026a4110200341e0026a410410050b410021070c0b0b41164101102e000b41084101102e000b41ecdbc100200520021036000b20024101102e000b0b024020032802b404450d0020032802b00410290b024020070d0041b4bcc20021070c0b0b2003201c3703f802200320093a00f702200320043a00f602200320053b01f4022003200a3a00f3022003200b3a00f2022003200c3b01f0022003200d3a00ef022003200e3a00ee022003200f3b01ec02200320103a00eb02200320123600e702200320113600e302200320023a00e202200320063b01e0020240200341e0026a20034188046a4120109d050d0020034188046a201610b40220034188046a428080e983b1de1642001053200342f0f2bda9c6add9b1f4003703b00220034188016a41d983c300410d105d410021072003200328028c0141002003280288011b3602d003200341b0046a20034188046a10b00120032802b404210820032802b004210220032802b8042106200341c4046a200341b0026a3602002003200220064105746a3602bc04200320023602b804200320083602b404200320023602b0042003200341d0036a3602c004200341e0036a200341b0046a1049200341b0046a41086a200341e0036a41086a280200360200200320032903e0033703b00420034188046a200341b0046a10c1010c0b0b419bbcc2002107411921080c0a0b0b024020032802e402450d0020032802e00210290b024020070d0041eebac20021070c090b2003201c3703a004200320093a009f04200320043a009e04200320053b019c042003200a3a009b042003200b3a009a042003200d3b0198042003200e3a0097042003200f3a009604200320103b019404200320113a0093042003201336008f042003201236008b04200320023a008a04200320063b018804200341e0026a201e4106761094024100210702400240201e413f71220220032802e8024f0d0020032802e002200241216c6a22022d00004101470d0020022f00012108200241196a290000211c200241186a2d00002106200241176a2d00002109200241156a2f00002104200241146a2d00002105200241136a2d0000210a200241116a2f0000210b200241106a2d0000210d2002410f6a2d0000210e2002410d6a2f0000210f2002410c6a2d00002110200241086a2800002112200241046a2800002111200241036a2d00002102410121070c010b0b024020032802e402450d0020032802e00210290b024020070d004187bcc2002107411421080c090b2003201c3703c804200320063a00c704200320093a00c604200320043b01c404200320053a00c3042003200a3a00c2042003200b3b01c0042003200d3a00bf042003200e3a00be042003200f3b01bc04200320103a00bb04200320123600b704200320113600b304200320023a00b204200320083b01b004024020034188046a200341b0026a4120109d05450d0041e5bbc2002107411221080c090b0240200341b0046a200341e0036a4120109d05450d0041f7bbc2002107411021080c090b200341e0026a41186a2213200341e0036a41186a2214290300370300200341e0026a41106a2215200341e0036a41106a2216290300370300200341e0026a41086a2217200341e0036a41086a2218290300370300200320032903e0033703e002410021022003410036028003200341d0036a200341e0026a108e020240024020032802d80322050d004101210e4100210f0c010b4100210d4100210f4101210e4100211103402005417f4c0d0220032802d403211220032802d0032110024002400240024020051032220a450d0002400240200541027422020d00410021040c010b201020026a210b4100210420102109034020092802002107412010322202450d0320022007411f763a001f200220074101713a000020022007411e764101713a001e20022007411d764101713a001d20022007411c764101713a001c20022007411b764101713a001b20022007411a764101713a001a200220074119764101713a0019200220074118764101713a0018200220074117764101713a0017200220074116764101713a0016200220074115764101713a0015200220074114764101713a0014200220074113764101713a0013200220074112764101713a0012200220074111764101713a0011200220074110764101713a001020022007410f764101713a000f20022007410e764101713a000e20022007410d764101713a000d20022007410c764101713a000c20022007410b764101713a000b20022007410a764101713a000a200220074109764101713a0009200220074108764101713a00082002200741ff017122074107763a0007200220074106764101713a0006200220074105764101713a0005200220074104764101713a0004200220074103764101713a0003200220074102764101713a0002200220074101764101713a0001200941046a21094100210702400240024002400340200741206a220841034d0d010240200220076a2208411f6a2d0000450d002007411f6a21060c040b02402008411e6a2d0000450d002007411e6a21060c040b02402008411d6a2d00000d002007417c6a21072008411c6a2d00000d030c010b0b2007411d6a21060c020b03402008450d03200220086a21072008417f6a220621082007417f6a2d0000450d000c020b0b200741206a21060b200641016a22082006490d000240200520046b2008412020084120491b22074f0d00200420076a22072004490d0b20054101742206200720072006491b22074100480d0b0240024020050d0020071032210a0c010b200a200520071034210a0b200a450d06200721050b200a20046a2106410021070240034020074120460d01200620076a200220076a2d00004101713a00002008200741016a2207470d000b0b200420076a21040b200210292009200b470d000b0b02402012450d00201010290b0240200f200d6b2004490d00200d20046a21020c040b200d20046a2202200d490d07200f4101742207200220022007491b22074100480d0702400240200f0d0020071032210e0c010b200e200f20071034210e0b0240200e450d002007210f0c040b20074101102e000b20054101102e000b41204101102e000b20074101102e000b200e200d6a200a2004109b051a02402005450d00200a10290b201320142903003703002015201629030037030020172018290300370300200320032903e0033703e0022003201141016a221136028003200341d0036a200341e0026a108e022002210d20032802d80322050d000b0b024020032802d403450d0020032802d00310290b200341d0036a41086a22074200370300200342003703d003418fdcc1004112200341d0036a1003200341d0026a41086a2007290300370300200320032903d0033703d002200341003602e002200341d0026a4110200341e0026a10062107024020032802e0022208417f460d002007450d00200320083602d403200320073602d003200341e0026a200341d0036a1031024020032802e002220a450d00200341e8026a280200210620032802e402210b02402008450d00200710290b200641ffffff3f7121070c040b41f7cdc3004133200341d8046a41ecd6c3001054000b4101210a410021074100210b0c020b102f000b1033000b0240024020072002200220074b1b2208450d0041002107200341f8026a2106200341f0026a2109200341e8026a2104200a210203400240200e20076a2d0000450d00200642003703002009420037030020044200370300200342003703e002200341e0026a2002460d002002200341e0026a4120109d05450d00200341e0026a2002108c024101210520032802e0024101470d0020032802e402200c4d0d030b200241206a2102200741016a22072008490d000b0b410021050b0240200b450d00200a10290b0240200f450d00200e10290b200341b0026a200341e0036a20051b2207201f201e20051b10b402200342f0f2bda9c6add9b1f4003703a002200341f8006a41d983c300410d105d2003200328027c410020032802781b3602d002200341e0026a200710b00120032802e402210820032802e002210220032802e8022106200341f4026a200341a0026a3602002003200220064105746a3602ec02200320023602e802200320083602e402200320023602e0022003200341d0026a3602f002200341d0036a200341e0026a1049200341e0026a41086a200341d0036a41086a2202280200360200200320032903d0033703e0022007200341e0026a10c101024002402005450d00200341286a200341b0026a428080e983b1de16420010c201200341286a41086a290300212a2003290328211c20024200370300200342003703d00341c2d5c0004116200341d0036a1003200341d0026a41086a22082002290300370300200320032903d0033703d002200341106a200341d0026a10eb01200341106a41106a2903002120200329031821292003280210210720024200370300200342003703d00341c2d5c0004116200341d0036a100320082002290300370300200320032903d0033703d002200342002020420020071b2220202a7d2029420020071b222a201c54ad7d2229202a201c7d221c202a56202920205620292020511b22021b3703e80220034200201c20021b3703e002200341d0026a4110200341e0026a41101005200341013a00e402200341083a00e002200341e0026a4105722102200341e0026a21080c010b200341e8006a200341b0026a105b2003290368200341e8006a41086a29030084500d04411810322202450d02200241002900ecd540370000200241106a41002900fcd540370000200241086a41002900f4d5403700002003429880808080033702e402200320023602e002200341e0036a200341e0026a10810120032802e4022102200341d0006a20032802e002220820032802e80210a101200341d0006a41106a290300211c200328025021072003290358212002402002450d00200810290b411410322202450d03201c420020071b222a42002020420020071b221c428080e983b1de16544100202a501b22071b2129201c428080e983b1de1620071b2120200241002900d8d540370000200241106a41002800e8d540360000200241086a41002900e0d54037000020034294808080c0023702e402200320023602e002200341b0026a200341e0026a10810120032802e4022102200341386a20032802e002220820032802e80210a101200341386a41106a2903004200200328023822071b212c2003290340420020071b212b02402002450d00200810290b200341b0026a202b20207c222d202c20297c202d202b54ad7c10a501200341e0036a201c20207d202a20297d201c202054ad7d10bc01200341f5026a200341e0036a41106a290300370000200341fd026a200341f8036a290300370000200341083a00e002200341ed026a200341e0036a41086a290300370000200341003a00e402200320032903e0033700e50220034185036a2102200341e0026a21080b200220032903b002370000200241186a200341b0026a41186a290300370000200241106a200341b0026a41106a290300370000200241086a200341b0026a41086a2903003700004100210741012106410141002008104c0b410121090c060b41184101102e000b41144101102e000b41e9d4c0002107412221080c010b41c8d8c3002107411521080b41012106410121090c010b41012109410021062004450d00200510290b02402001280200417f6a220241014b0d000240024020020e020001000b2009450d01200141086a280200450d01200128020410290c010b2006450d00200141086a280200450d00200128020410290b2000200836020420002007360200200341e0046a24000bc93605057f047e047f027e067f230041e0026b22052400200541a0016a41086a22064200370300200542003703a001418fdcc1004112200541a0016a100320054180026a41086a2006290300370300200520052903a00137038002410021072005410036027020054180026a4110200541f0006a10062106024020052802702208417f460d002006450d002005200836027420052006360270200541e8006a200541f0006a102c0240024020052802680d00200528026c21070c010b410021070b2008450d00200610290b200541a0016a41086a22084200370300200542003703a001411421064184dbc1004114200541a0016a100320054180026a41086a2008290300370300200520052903a0013703800202400240024020054180026a41104101410041001007417f460d0041e2c0c2002108412e21060c010b200541e0006a4195ebc5004111105d4190c1c20021082005280264410020052802601b2003470d00024020070d0041a4c1c200210841c10021060c010b02402007200241086a28020022094f0d0041e5c1c2002108413c21060c010b200541d0006a2001105b200541d0006a41086a290300210a2005290350210b200541f0006a2001108f0202400240024002400240024002400240024002400240024020052903704201510d00200541c0006a200110be012005290340428080e983b1de1656200541c8006a290300220c420052200c501b0d0141c5c2c2002108413421060c0c0b20054180016a290300210d2005290378210c20054180026a2004410676109402410021072004413f7122062005280288024f0d01200528028002200641216c6a22082d00004101470d01200541a2026a200841036a2d00003a0000200541b8026a41086a200841146a290000370300200541c5026a200841196a290000370000200520082f00013b01a00220052008410c6a2900003703b802200841086a2800002106200841046a2800002108410121070c020b200541a0016a2004410676220710940241002106024020052802a8012004413f7122084d0d004101410220052802a001200841216c6a2d00001b21060b024020052802a401450d0020052802a00110290b02400240024002400240024002400240024020064102490d00200541b8026a2007109402200541a0016a41186a220e200141186a290000370300200541a0016a41106a220f200141106a290000370300200541a0016a41086a2210200141086a290000370300200520012900003703a00120052802c002221120084d0d0120052802b8022204200841216c6a220641013a0000200620052903a001370001200641096a2010290300370000200641116a200f290300370000200641196a200e290300370000410e10322206450d02200641066a41002900fedc41370000200641002900f8dc413700002006410e411c10342206450d032006200736000e20054180026a41186a2208420037030020054180026a41106a2207420037030020054180026a41086a220e420037030020054200370380022006411220054180026a1000200541e0016a41186a2008290300370300200541e0016a41106a2007290300370300200541e0016a41086a200e29030037030020052005290380023703e001200541203602a4012005200541e0016a3602a00120042011200541a0016a10e6012006102920052802bc02450d08200410290c080b200541386a41a6ebc5004114105d20052802382108200528023c2107410e10322206450d03200641066a41002900fedc41370000200641002900f8dc413700002006410e411c10342206450d0420062007410020081b220436000e20054180026a41186a2208420037030020054180026a41106a2207420037030020054180026a41086a220e420037030020054200370380022006411220054180026a1000200541e0016a41186a2008290300370300200541e0016a41106a2007290300370300200541e0016a41086a200e29030037030020052005290380023703e001200541003602a001200541e0016a4120200541a0016a1006210820052802a001220f417f460d052008450d052005200f3602a401200520083602a001200541306a200541a0016a102c0240024020052802300d002005280234210e410021070c010b4101210741e480c600210e0b200f450d06200810290c060b41ecdbc100200820111036000b410e4101102e000b411c4101102e000b410e4101102e000b411c4101102e000b410021074100210e0b20061029024002400240024020070d00200e413f460d01200e0d030b200541a0016a2001428080d287e2bc2d4200410810ad0120052802a0014101470d0120052802a801210620052802a40121080c0e0b200541a0016a41086a22064200370300200542003703a00141a6ebc5004114200541a0016a100320054180026a41086a2006290300370300200520052903a001370380022005200441016a3602a00120054180026a4110200541a0016a410410050c010b200541a0016a41106a290300211220052903a801210c200541a0016a41086a22064200370300200542003703a00141c2d5c0004116200541a0016a100320054180026a41086a22072006290300370300200520052903a00137038002200541186a20054180026a10eb01200541186a41106a290300210d200529032021132005280218210820064200370300200542003703a00141c2d5c0004116200541a0016a100320072006290300370300200520052903a0013703800220054200200d420020081b220d20127d2013420020081b2212200c54ad7d22132012200c7d220c2012562013200d562013200d511b22061b3703a80120054200200c20061b3703a00120054180026a4110200541a0016a41101005200a200b428080aef89dc3527c220c200b54ad7c427f7c210a200c210b0b200541a9016a200141086a290000370000200541b1016a200141106a290000370000200541b9016a200141186a290000370000200541013a00a001200520012900003700a10102400240024002400240024002400240024002400240024002400240024002400240410e10322206450d00200641066a41002900fedc41370000200641002900f8dc413700002006410e411c10342206450d012006200436000e20054180026a41186a2208420037030020054180026a41106a2207420037030020054180026a41086a220e420037030020054200370380022006411220054180026a1000200541e0016a41186a2008290300370300200541e0016a41106a2007290300370300200541e0016a41086a200e29030037030020052005290380023703e0012005410036028002200541e0016a412020054180026a100621080240024002400240024002402005280280022207417f460d0020080d010b20054100360288022005420137038002410020054180026a10662005280280022208450d02200529028402210c200520083602d0012005200c3702d401200c422088a721070c010b200520073602d801200520073602d401200520083602d0010b2007450d0120054180026a2008200741011080012005280280024101470d0220052802d401450d1320052802d00110290c130b200541003602d801200542013703d0010b4101200541d0016a1066024020052d00a0014101460d000240024020052802d40120052802d8012208460d0020052802d00121070c010b200841016a22072008490d182008410174220e20072007200e491b220e4100480d180240024020080d00200e103221070c010b20052802d0012008200e103421070b2007450d052005200e3602d401200520073602d00120052802d80121080b2005200841016a3602d801200720086a41003a00000c100b0240024020052802d40120052802d8012208460d0020052802d00121070c010b200841016a22072008490d172008410174220e20072007200e491b220e4100480d170240024020080d00200e103221070c010b20052802d0012008200e103421070b2007450d052005200e3602d401200520073602d00120052802d80121080b2005200841016a3602d801200720086a41013a0000200541a0016a410172200541d0016a1081010c0f0b200528028402210f02402005418c026a280200220820054188026a2802002207460d0020052802d801200820076b6a220e41216a2210417f4c0d050240024020100d00410121110c010b201010322211450d070b200520103602a402200520113602a0022005200e3602a8022005200541a0026a36028002200f20054180026a2008108201200e2008490d0720052802a802220f200e490d0820052802d801220f2007490d0920052802a002211020052802d00121112005200e20086b220e3602b0022005200f20076b220f3602b402200e200f470d0a201020086a201120076a200e109b051a0240024020052d00a0014101460d000240024020052802a40220052802a8022208460d0020052802a00221070c010b200841016a22072008490d192008410174220e20072007200e491b220e4100480d190240024020080d00200e103221070c010b20052802a0022008200e103421070b2007450d0e2005200e3602a402200520073602a00220052802a80221080b2005200841016a3602a802200720086a41003a00000c010b0240024020052802a40220052802a8022208460d0020052802a00221070c010b200841016a22072008490d182008410174220e20072007200e491b220e4100480d180240024020080d00200e103221070c010b20052802a0022008200e103421070b2007450d0e2005200e3602a402200520073602a00220052802a80221080b2005200841016a3602a802200720086a41013a0000200541a0016a410172200541a0026a1081010b20052802a802210720052802a402210e20052802a002210820052802d401450d1020052802d00110290c100b2005200541d0016a36028002200f20054180026a2007108201024020052d00a0014101460d000240024020052802d40120052802d8012208460d0020052802d00121070c010b200841016a22072008490d172008410174220e20072007200e491b220e4100480d170240024020080d00200e103221070c010b20052802d0012008200e103421070b2007450d0e2005200e3602d401200520073602d00120052802d80121080b2005200841016a3602d801200720086a41003a00000c0f0b0240024020052802d40120052802d8012208460d0020052802d00121070c010b200841016a22072008490d162008410174220e20072007200e491b220e4100480d160240024020080d00200e103221070c010b20052802d0012008200e103421070b2007450d0e2005200e3602d401200520073602d00120052802d80121080b2005200841016a3602d801200720086a41013a0000200541a0016a410172200541d0016a1081010c0e0b410e4101102e000b411c4101102e000b200e4101102e000b200e4101102e000b102f000b20104101102e000b2008200e1030000b200e200f108f01000b2007200f1030000b200541e0016a41146a4102360200200541ec016a4103360200200541b8026a41146a4103360200200542033702bc02200541acf9c5003602b802200541033602e4012005200541b0026a3602d0022005200541b4026a3602d4022005420437039002200542013702840220054180fac500360280022005200541e0016a3602c802200520054180026a3602f0012005200541d4026a3602e8012005200541d0026a3602e001200541b8026a41bcfac500107d000b200e4101102e000b200e4101102e000b200e4101102e000b200e4101102e000b20052802d801210720052802d401210e20052802d00121080b2008450d0020054180026a41186a2204420037030020054180026a41106a220f420037030020054180026a41086a2210420037030020054200370380022006411220054180026a1000200541e0016a41186a2004290300370300200541e0016a41106a200f290300370300200541e0016a41086a201029030037030020052005290380023703e001200541e0016a41202008200710050240200e450d00200810290b200610290c010b20061029024002400240412110322206450d0041002108024020052d00a0014101470d0020054198026a200541b9016a29000037030020054190026a200541b1016a29000037030020054188026a200541a9016a290000370300200520052900a10137038002410121080b200620083a00002006200529038002370001200641096a20054188026a290300370000200641116a20054190026a290300370000200641196a20054198026a290300370000410e10322208450d01200841066a41002900fedc41370000200841002900f8dc413700002008410e411c10342208450d022008200436000e20054180026a41186a2207420037030020054180026a41106a2204420037030020054180026a41086a220e420037030020054200370380022008411220054180026a1000200541e0016a41186a2007290300370300200541e0016a41106a2004290300370300200541e0016a41086a200e29030037030020052005290380023703e00120054120360284022005200541e0016a360280022006410120054180026a10e60120081029200610290c030b41214101102e000b410e4101102e000b411c4101102e000b4200210c200541106a2001428080e983b1de164200107e024020052802102208450d00200528021421060c0b0b200541086a41baebc5004112105d20052802082106200528020c2108200541a0016a41086a22074200370300200542003703a00141baebc5004112200541a0016a100320054180026a41086a2007290300370300200520052903a001370380022005200841016a410120061b3602a00120054180026a4110200541a0016a410410054200210d0c020b0b0240200528028402450d0020052802800210290b0240024020070d00410121074113210641a1c2c20021080c010b200541d0016a41026a200541a0026a41026a2d00003a000020054180026a41086a200541b8026a41086a29030037030020054180026a410d6a200541b8026a410d6a290000370000200520052f01a0023b01d001200520052903b80237038002410021070b200541d4026a41026a2204200541d0016a41026a2d00003a0000200541e0016a41086a220e20054180026a41086a290300370300200541e0016a41106a20054180026a41106a290300370300200520052f01d0013b01d40220052005290380023703e00120070d08200541b3016a200e290300370000200541b8016a200541ed016a290000370000200520052f01d4023b01a001200520063600a701200520083600a301200520052903e0013700ab01200520042d00003a00a201200541a0016a2001460d00200541a0016a20014120109d05450d0041b4c2c2002108411121060c080b200542f0f2bda9c6add9b1f4003703c801200541c8016a2001200b200a417f410e109301200541f0006a41186a200a3703002005200b370380012005200d3703782005200c37037020052003360294012005200336029001411310322206450d03200641002900fcdb413700002006410f6a410028008bdc41360000200641086a4100290084dc4137000020054293808080b0023702a401200520063602a0012001200541a0016a10810120052802a401210820052802a801210720052802a001210620054180026a41186a2203420037030020054180026a41106a2204420037030020054180026a41086a220e420037030020054200370380022006200720054180026a1000200541e0016a41186a2003290300370300200541e0016a41106a2004290300370300200541e0016a41086a200e29030037030020052005290380023703e001200541203602a4012005200541e0016a3602a001200541f0006a200541a0016a10900202402008450d00200610290b2002280204210f2002280200210302400240200941057622140d0041042115410421160c010b2014410274220610322215450d03201521160b2009450d05024020140d00410410322215450d0241012114201521160b201641003602002009417f6a210441012111410021064100210802400340201620084102746a2202200320066a2d00002006411f717420022802006a36020002400240024020042006460d00200641016a2202411f71450d01201421070c020b0240200f450d00200310290b410021170240024002400340200541f0006a41186a200141186a290000370300200541f0006a41106a200141106a290000370300200541f0006a41086a200141086a2900003703002005201736029001200520012900003703702011410820114108491b2208410274220f10322206450d0120062016200f109b052110411310322202450d02201120086b21112016200f6a211641002106200241002900e5dc413700002002410f6a41002800f4dc41360000200241086a41002900eddc4137000020054293808080b0023702a401200520023602a001200541f0006a200541a0016a10950220052802a401211820052802a801210220052802a001211920054180026a41186a2207420037030020054180026a41106a2203420037030020054180026a41086a2204420037030020054200370380022019200220054180026a1000200541e0016a41186a2007290300370300200541e0016a41106a2003290300370300200541e0016a41086a200429030037030020052005290380023703e001200541003602a801200542013703a0012008200541a0016a1066410020052802a80122046b210820052802a40121030340200420066a2107201020066a280200210902400240200320086a4104490d0020052802a00121020c010b200741046a22022007490d0a2003410174220e20022002200e491b220e4100480d0a0240024020030d00200e103221020c010b20052802a0012003200e103421020b2002450d052005200e3602a401200520023602a001200e21030b2005200741046a3602a801200220046a20066a20093600002008417c6a2108200f200641046a2206470d000b200541e0016a41202002200420066a100502402003450d00200210290b02402018450d00201910290b20101029201741016a211720110d000b410021082014450d0d201510290c0d0b200f4104102e000b41134101102e000b200e4101102e000b0240024020112014460d0020142107201121140c010b201441016a22072014490d042014410174220e20072007200e491b220741ffffffff03712007470d042007410274220e4100480d040240024020140d00200e103221150c010b20152014410274200e103421150b2015450d03201521160b201620144102746a4100360200200841016a2108201141016a21110b200920024d0d062007211420022106201120084b0d000b41ecdbc100200820111036000b200e4104102e000b1033000b41044104102e000b20064104102e000b41134101102e000b4198dbc100200641016a20091036000b0240200f450d00200310290b410021080b0c010b200241046a280200450d00200228020010290b2000200636020420002008360200200541e0026a24000bbf0a010d7f23004190016b22022400200241086a2001410676220310940202400240024002400240200228021022042001413f7122014d0d0020022802082205200141216c6a220141003a000020012002290028370001200141096a200241306a290000370000200141116a200241386a290000370000200141196a200241c0006a290000370000200228020c2106410e10322201450d01200141066a41002900fedc41370000200141002900f8dc413700002001410e411c10342201450d022001200336000e200241f0006a41186a22074200370300200241f0006a41106a22084200370300200241f0006a41086a220342003703002002420037037020014112200241f0006a1000200241d0006a41186a2007290300370300200241d0006a41106a2008290300370300200241d0006a41086a2003290300370300200220022903703703502002412036022c2002200241d0006a36022820052004200241286a10e6012001102902402006450d00200510290b200241baebc5004112105d2002280200210520022802042104200241286a41086a220142003703002002420037032841baebc5004112200241286a1003200320012903003703002002200229032837037020022004417f6a417f20051b360228200241f0006a4110200241286a41041005200241286a41186a200041186a290000370300200241286a41106a200041106a2900003703002001200041086a2900003703002002410036024820022000290000370328200241186a200241286a108e0202402002280220450d00410121030340200241286a41186a2205200041186a2204290000370300200241286a41106a2206200041106a2207290000370300200241286a41086a2208200041086a22092900003703002002200029000037032820022003417f6a360248411310322201450d05200141002900e5dc413700002001410f6a41002800f4dc41360000200141086a41002900eddc4137000020024293808080b00237027420022001360270200241286a200241f0006a1095022002280274210a2002280278210b20022802702101200241f0006a41186a220c4200370300200241f0006a41106a220d4200370300200241f0006a41086a220e4200370300200242003703702001200b200241f0006a1000200241d0006a41186a200c290300370300200241d0006a41106a200d290300370300200241d0006a41086a200e29030037030020022002290370370350200241d0006a412010040240200a450d00200110290b0240200228021c450d00200228021810290b2005200429000037030020062007290000370300200820092900003703002002200029000037032820022003360248200341016a2103200241186a200241286a108e0220022802200d000b0b0240200228021c450d00200228021810290b411310322201450d04200141002900fcdb413700002001410f6a410028008bdc41360000200141086a4100290084dc4137000020024293808080b00237022c200220013602282000200241286a108101200228022c21012002280230210320022802282100200241f0006a41186a22054200370300200241f0006a41106a22044200370300200241f0006a41086a220642003703002002420037037020002003200241f0006a1000200241d0006a41186a2005290300370300200241d0006a41106a2004290300370300200241d0006a41086a200629030037030020022002290370370350200241d0006a4120100402402001450d00200010290b20024190016a24000f0b41ecdbc100200120041036000b410e4101102e000b411c4101102e000b41134101102e000b41134101102e000b280020004101360204200041086a200128020420012802006b4107762201360200200020013602000bf40101047f230041d0006b21020240200128020022032001280204470d00200041003602000f0b200120034180016a3602002002200341c2006a29000037012a2002200341ca006a290000370132200241106a220120022903303703002002200341d2006a29000037013a200241186a220420022903383703002002200341da006a2800003601422002200341de006a2f00003b0146200241206a220520022903403703002002200341c0006a2f00003b01282002200229032837030820002003360200200020022903083700042000410c6a2001290300370000200041146a20042903003700002000411c6a20052903003700000bb905020b7f047e23004190016b22032400024002402001280200220420012802042205460d00200120044180016a22063602002003200441c2006a29000037016a2003200441ca006a290000370172200341c8006a41086a220720032903703703002003200441d2006a29000037017a200341c8006a41106a220820032903783703002003200441da006a280000360182012003200441de006a2f00003b018601200341c8006a41186a22092003290380013703002003200441c0006a2f00003b016820032003290368370348200341286a41186a220a2009290300370300200341286a41106a220b2008290300370300200341286a41086a220c200729030037030020032003290348370328200541807f6a210d02400340200341086a41186a200a290300220e370300200341086a41106a200b290300220f370300200341086a41086a200c2903002210370300200320032903282211370308200341e8006a41186a200e370300200341e8006a41106a200f370300200341e8006a41086a2010370300200320113703682002450d01200d2004460d02200120064180016a22053602002003200641c2006a29000037016a2003200641ca006a290000370172200720032903703703002003200641d2006a29000037017a200820032903783703002003200641da006a280000360182012003200641de006a2f00003b01860120092003290380013703002003200641c0006a2f00003b016820032003290368370348200a2009290300370300200b2008290300370300200c20072903003703002003200329034837032820044180016a21042002417f6a2102200521060c000b0b20002004360200200020032903683702042000410c6a200341f0006a290300370200200041146a200341f8006a2903003702002000411c6a20034180016a2903003702000c010b200041003602000b20034190016a24000b130020004102360204200041f0f4c5003602000b13002000410136020420004184ccc3003602000b130020004103360204200041dcd1c0003602000b130020004103360204200041fcb9c4003602000b13002000410136020420004180f2c5003602000b13002000410b360204200041a481c0003602000b130020004106360204200041b8cec3003602000b130020004104360204200041a8b7c1003602000b130020004105360204200041c4fec2003602000b130020004103360204200041e4ebc5003602000b1300200041053602042000418cb3c1003602000b130020004106360204200041ecf2c3003602000b1300200041023602042000419c87c3003602000b130020004101360204200041cc82c1003602000b130020004101360204200041e4a8c5003602000bc77104147f027e107f027e230041c0046b22042400200441b0036a20012002200310d103200441b0036a41086a280200210520042802b40321060240024020042802b0034101470d002000200636020420004101360200200041086a20053602000c010b200441c4036a2802002207412c6c2108200441c8036a2802002109200441c0036a280200210a200441bc036a280200210b4100210c4100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004102470d000b200441d8006a200b200d6a41586a10a2032004280258210c200428025c21010b4100210e20014100200c1b210f2007412c6c2108200c4104200c1b21104100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004108470d000b200441d0006a200b200d6a41586a10a2032004280250210e200428025421010b4100211120014100200e1b21122007412c6c2108200e4104200e1b210c4100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004104470d000b200441c8006a200b200d6a41586a10a20320042802482111200428024c21010b4100210e2001410020111b21132007412c6c21082011410420111b21114100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004103470d000b200441c0006a200b200d6a41586a10a2032004280240210e200428024421010b41002102024020014100200e1b2201450d00200141286c2108200e4104200e1b41186a2101410021020340200220012d0000456a2102200141286a2101200841586a22080d000b0b0240024020120d00411e21012000419bb7c5003602040c010b200c201241146c6a2112410021144100211502400240034041b9b7c500210841382101200c41086a280200417c6a220e41024b0d01200c280200210d024002400240200e0e03000401000b41012115200d4191b7c500460d01200d28000041e3c2b1e306460d010c030b41012114200d4195b7c500460d00200d4195b7c5004106109d050d020b0240200c410c6a280200450d0041132101200041b7b8c5003602040c040b0240200c41106a280200220120026b220d20014d0d00412a2101200041cab8c5003602040c040b4191b8c5002108412621012013200d4d0d012011200d4102746a220d450d0141f1b7c500210841202101200f200d280200220d4d0d012010200d4104746a220d450d0141f4b8c5002108411f2101200d2802080d01200d2d000d220d41077141044b0d010240200d0e050002020200000b200c41146a220c2012470d000b20142015714101710d01411c411e201441017122021b210120004193b9c500419bb7c50020021b3602040c020b200020083602040c010b2007412c6c2108410021010240034020082001460d01200b20016a21022001412c6a220d210120022d00004106470d000b200441386a200b200d6a41586a10a203200428023c450d00200041dfb4c500360204411f21010c010b2007412c6c21082003280268210c410021010240034020082001460d01200b20016a21022001412c6a220d210120022d00004105470d000b200441306a200b200d6a41586a220110a2030240200428023441014d0d0041182101200041feb4c5003602040c020b200441286a200110a203200428022c450d0020042802282201450d002001280200200c4d0d004122210120004196b5c5003602040c010b2007412c6c2108410021010240034020082001460d01200b20016a21022001412c6a220d210120022d00004107470d000b200441206a200b200d6a41586a10a2032004280220220120042802244104746a2108034020012008460d012001450d012001410c6a2102200141106a210120022d0000410271450d000b41322101200041a2b6c5003602040c010b2007412c6c2108410021010240034020082001460d01200b20016a21022001412c6a220d210120022d0000410b470d000b200b200d6a220141606a2802002202450d00200141586a280200220d200241186c6a210c0340200d220241186a210d2002280208410374210120022802002102024003402001450d01200141786a210120022d00042108200241086a21022008410271450d000b41312101200041f1b5c5003602040c030b200d200c470d000b0b2007412c6c2108410021010240034020082001460d01200b20016a21022001412c6a220d210120022d00004102470d000b200441186a200b200d6a41586a10a203200428021c2201450d002004280218220220014104746a211103402002450d01200241106a210e200420022d000d22083a00b0032002280200220120022802086a210c410021024100200441b0036a20084104461b210d024003400240024002400240200241ff01710e03000102000b2001200c460d014100210220012108200141016a21010c020b2001200c460d034101210220012108200141016a21010c010b200d450d0241022102200d21084100210d0b20082d0000410271450d000b41392101200041b8b5c5003602040c030b200e2102200e2011470d000b0b2007412c6c21084100210c4100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004102470d000b200441106a200b200d6a41586a10a2032004280210210c200428021421010b4100210e20014100200c1b21102007412c6c2108200c4104200c1b21124100210102400340024020082001470d000c020b200b20016a21022001412c6a220d210120022d00004103470d000b200441086a200b200d6a41586a10a2032004280208210e200428020c21010b200e4104200e1b220220014100200e1b41286c6a210d41002113024002400340024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402002200d460d00412d210141f5b0c400210820022802084103470d2102402002280200220c41fad7c500460d00200c41fad7c5004103109d050d220b200241286a21114115210c41eeafc400210e4114210141e1b0c400210802400240024020022d00180e0400240123000b4136210c41b8afc400210e2010200228021c22014d0d22201220014104746a220f450d222002280214210c200228020c210220092d00700d01200c410b470d014138210141a9b0c4002108200241c2b1c500460d23200241c2b1c500410b109d05450d230c210b412f210141a2b1c400210820022802144106470d220240200228020c220c41b2afc400460d00200c41b2afc4004106109d050d230b02402013450d00411f2101200041d1b1c4003602040c280b2002411c6a2113201121020c240b412621014183b0c4002108200c417d6a220c41134b0d210240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200c0e14003d3d3d0e043d063b0b0a110113101a3d3d0c18000b200241fdd7c500460d3c200241fdd7c5004103109d05450d3c41fdd7c50020024103109d050d3c41011032220e450d1c200e41003a0000200f2d000c41e000460d010c390b200241a0afc500460d0141a0afc5002002410f109d05450d010240200241afafc500460d0041afafc5002002410f109d050d3c0b41011032220e450d1d200e41003a0000200f2d000c41e000460d030c370b200f2802084101470d37200f2802002114410021020240034020024101460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d390c000b0b200f2d000d4104470d37200e1029201121020c3c0b41041032220e450d1a200e4100360000200f2d000c41e000470d34200f2802084104470d34200f2802002114410021020240034020024104460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d360c000b0b200f2d000d4104470d34200e1029201121020c3b0b0240200241beafc500460d00200229000042e5f0d1fbb5ac98b6ec00520d390b41071032220e450d1b200e4100360003200e41013a0002200e41003b0000200f2d000c41e000460d020c320b200f2802084101470d33200f280200211441002102034020024101460d31200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d340c000b0b200241c6afc500460d0141c6afc5002002410a109d05450d01200241d0afc500460d0241d0afc5002002410a109d05450d020240200241daafc500460d0041daafc5002002410a109d050d070b4126210c4183b0c400210e200f2d000c41e000470d35200f2802080d3520112102200f2d000d4104460d380c350b200f2802084107470d2f200f280200211441002102034020024107460d2e200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d300c000b0b41071032220e450d18200e4100360003200e41013a0002200e41003b0000200f2d000c41e000470d2b200f2802084107470d2b200f280200211441002102034020024107460d2b200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d2c0c000b0b41021032220e450d18200e41003b0000200f2d000c41e000470d28200f2802084102470d28200f2802002114410021020240034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d2a0c000b0b200f2d000d4104470d28200e1029201121020c350b0240200241efafc500460d0041efafc5002002410d109d050d330b4126210c4183b0c400210e200f2d000c41e000470d31200f2802080d3120112102200f2d000d4104460d340c310b0240200241fcafc500460d0041fcafc5002002410c109d050d320b4126210c4183b0c400210e200f2d000c41e000470d30200f2802080d3020112102200f2d000d4104460d330c300b024020024193b0c500460d004193b0c50020024115109d050d310b4126210c4183b0c400210e200f2d000c41e000470d2f200f2802080d2f20112102200f2d000d4104460d320c2f0b0240200241a8b0c500460d0041a8b0c5002002410a109d050d300b41021032220e450d15200e41003b0000200f2d000c41e000460d010c230b0240200241b2b0c500460d0041b2b0c50020024107109d050d2f0b4126210c4183b0c400210e200f2d000c41e000470d2d200f2802080d2d20112102200f2d000d4104460d300c2d0b200f2802084102470d21200f2802002114410021020240034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d230c000b0b200f2d000d4104470d21200e1029201121020c2f0b200241b9b0c500460d0141b9b0c50020024111109d05450d01200241f8b0c500460d0641f8b0c50020024111109d05450d06024020024189b1c500460d004189b1c50020024111109d050d2d0b41041032220e450d17200e4100360000200f2d000c41e000460d080c1f0b0240200241cab0c500460d0041cab0c5002002410e109d050d2c0b41081032220e450d13200e4200370000200f2d000c41e000460d020c1d0b41021032220e450d11200e41003b0000200f2d000c41e000470d1b200f2802084102470d1b200f2802002114410021020240034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d1d0c000b0b200f2d000d4104470d1b200e1029201121020c2c0b200241d8b0c500460d0141d8b0c50020024110109d05450d01200241e8b0c500460d0241e8b0c50020024110109d05450d020240200241cdb1c500460d0041cdb1c50020024110109d050d2a0b4126210c4183b0c400210e200f2d000c41e000470d28200f2802080d2820112102200f2d000d4104460d2b0c280b200f2802084108470d1a200f2802002114410021020240034020024108460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d1c0c000b0b200f2d000d4104470d1a200e1029201121020c2a0b4126210c4183b0c400210e200f2d000c41e000470d26200f2802080d26200f2d000d22014104460d2620112102200141fb0171450d290c260b41031032220e450d0f200e41003a0002200e41003b0000200f2d000c41e000470d16200f2802084103470d16200f2802002114410021020240034020024103460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d180c000b0b200f2d000d4104470d16200e1029201121020c280b41021032220e450d0f200e41003b0000200f2d000c41e000470d14200f2802084102470d14200f2802002114410021020240034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d160c000b0b200f2d000d4104470d14200e1029201121020c270b02402002419ab1c500460d00419ab1c50020024116109d050d250b41021032220e450d10200e41003b0000200f2d000c41e000460d020c120b200f2802084104470d16200f2802002114410021020240034020024104460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d180c000b0b200f2d000d4104470d16200e1029201121020c250b0240200241b0b1c500460d0041b0b1c50020024112109d050d230b4126210c4183b0c400210e200f2d000c41e000470d21200f2802080d2120112102200f2d000d4104460d240c210b200f2802084102470d0f200f2802002114410021020240034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d110c000b0b200f2d000d4104470d0f200e1029201121020c230b024020130d0041002116410021170c0e0b024020132802040d00200041f0b1c400360204413221010c260b024020132802002216201341086a28020022174d0d00200041a2b2c40036020441c90021010c260b201720032802644d0d0d200041ebb2c40036020441c10021010c250b41014101102e000b41044101102e000b41014101102e000b41074101102e000b41074101102e000b41024101102e000b41024101102e000b41024101102e000b41084101102e000b41034101102e000b41024101102e000b41044101102e000b41024101102e000b20092903082118200441b8036a22024200370300200441b0d6c0003602b4032009290310211920042018a7417f2018428080808010541b3602c00320042019a7417f2019428080808010541b3602b003200441b0036a4104722201410d10d2032001410c10d2032001410710d2032001410f10d203200441b0036a410c6a2201280200211a2002280200211b20042802c003211c20042802b403210c20042802b003211d200441c0036a220820073602002001200a3602002004200b3602b803200420053602b403200420063602b003200441e0006a200441b0036a10d303024002400240410110322201450d00200141003a0000200420042f01b003220d3b01a002200841e0083b01002002428180808010370300200420013602b403200441013602b0032004200d3b01c203200441e0006a200441b0036a10d403210b0240410310322202450d00200241026a41002d00fcd7453a0000200241002f00fad7453b00000240410310322208450d00200841026a41002d00ffd7453a0000200841002f00fdd7453b0000200441a0026a41026a200441b0036a41026a22072d0000220e3a0000200420042f00b00322113b01a002200441f4006a280200210d200441e0006a41106a28020021012007200e3a0000200420113b01b00302400240024002400240024002400240200d2001470d00200141016a220d2001490d0120014101742207200d200d2007491b220dad42287e2218422088a70d012018a722074100480d010240024020010d002007103221010c010b200428026c200141286c2007103421010b2001450d072004200d3602702004200136026c2004280274210d0b200428026c200d41286c6a220141003a00182001200836020c200142838080803037020420012002360200200141106a428380808030370200200141196a20042f01b0033b00002001411b6a200441b2036a2d00003a00002001411c6a200b3602002004200428027441016a360274200441b0036a200441e0006a418c01109b051a200441f0016a200441b0036a10d503200441f0016a41106a2802002211412c6c210120042802f801220641586a210202400340410021082001450d01200141546a2101200241286a210d2002412c6a220b2102200d2d00004103470d000b200b41086a2802002201450d00200141286c2102200b28020041186a2101410021080340200820012d0000456a2108200141286a2101200241586a22020d000b0b2011412c6c2101200641586a21022008417f6a210d02400340410021082001450d01200141546a2101200241286a210b2002412c6a22072102200b2d00004103470d000b200741086a2802002201450d00200141286c2102200728020041186a2101410021080340200820012d0000456a2108200141286a2101200241586a22020d000b0b2011412c6c2101200641606a21020240034041002107024020010d00410021010c020b200141546a2101200241206a210b2002412c6a220e2102200b2d00004104470d000b200e28020021010b02400240024002402011450d00200120086a211e20062011412c6c6a211f410021204100210e0340024020062d000041786a220141034b0d00024002400240024020010e0403010200030b200628020c2201450d0320062802042207200141186c6a21210240024002400340200e212202402007220b41146a22052802004104742202450d00200b28020c21010340024020012d0000410b470d00200141046a22082802002207200d490d002008200741016a3602000b200141106a2101200241706a22020d000b0b0240024002400240024002400240024002400240024002400240410810322223450d002023428080808010370200410410322224450d012024410036020020052802002225450d024100210141012108202521024101211041012107410121130340200120024f0d08200141016a211402400240024002400240024002400240200b28020c20014104746a2d00002202417e6a220141044b0d0020010e050101010302010b200210d6032126200c2102201b21270340200241146a210f200241086a211520022f0106210a41002101024002400340200f2112200a2001460d01201520016a2d0000220e202641ff01712211460d02201241086a210f200141016a21010240417f200e201149200e20114b1b41016a0e03000301000b0b2001417f6a210a0b024020270d00201d21020c070b2027417f6a21272002200a4102746a41ec006a28020021020c010b0b201d210220122802000e0404100304040b200210d6032126200c2102201b212702400340200241146a210f200241086a211520022f0106210a41002101024002400340200f2112200a2001460d01201520016a2d0000220e202641ff01712211460d02201241086a210f200141016a21010240417f200e201149200e20114b1b41016a0e03000301000b0b2001417f6a210a0b024020270d00201d21020c030b2027417f6a21272002200a4102746a41ec006a28020021020c010b0b201d2102024020122802000e0401110001010b201241046a28020021020b2013417f6a220120134f0d0f200120134b0d0f2010202420014102746a28020022014d0d0f202320014103746a220e280204220120026a22022001490d0f200e20023602040240024020102008460d0020082128201021080c010b200841016a22012008490d2220084101742202200120012002491b222841ffffffff01712028470d22202841037422014100480d220240024020080d002001103221230c010b202320084103742001103421230b2023450d0b0b202320084103746a22014101360204200120143602000240024020132007460d0020072129201321070c010b200741016a22012007490d2220074101742202200120012002491b222941ffffffff03712029470d22202941027422014100480d220240024020070d002001103221240c010b202420074102742001103421240b2024450d0c0b201041016a2101202420074102746a2010360200201341016a21130c050b2013450d0e2013417f6a21130c030b2013450d0d0240024020102008460d0020082128201021080c010b200841016a22012008490d2020084101742202200120012002491b222841ffffffff01712028470d20202841037422014100480d200240024020080d002001103221230c010b202320084103742001103421230b2023450d0b0b202320084103746a2201410136020420012014360200024002402013417f6a22012007460d0020072129200121070c010b200741016a22012007490d2020074101742202200120012002491b222941ffffffff03712029470d20202941027422014100480d200240024020070d002001103221240c010b202420074102742001103421240b2024450d0c0b201041016a2101202420074102746a20103602000c030b201241046a28020021020b2013417f6a220120134f0d0b200120134b0d0b2010202420014102746a28020022014d0d0b202320014103746a220e280204220120026a22022001490d0b200e20023602040b2008212820102101200721290b20142025460d0a20052802002102202821082001211020292107201421010c000b0b41084104102e000b41044104102e000b202341086a211441012129410121280c070b20014104102e000b20014104102e000b20014104102e000b20014104102e000b4180d8c500200120021036000b02402008450d00202310290b41012120024020070d002022210e0c0c0b202410292022210e0c0b0b2001450d01202320014103746a21140b2005280200220a417f732127200a410174210e410021084100200a6b2126200a4104742110202321110340200a20086a2201200820112902002218a76a2207490d0202402001200b41106a220f280200470d00200141016a22022001490d11200e20022002200e491b220241ffffffff00712002470d11200241047422124100480d110240024020262008470d002012103221130c010b200b28020c20102012103421130b2013450d05200b201336020c200f20023602000b200b28020c20074104746a220241106a2002200120076b410474109c051a2002412d3a0000200241046a2018422088a7360200200220042f00b0033b0001200241036a200441b0036a41026a2d00003a00002005200141016a22023602002002200741016a2213490d0502402002200f280200470d00200241016a22072002490d11200e41026a2212200720072012491b220741ffffffff00712007470d11200741047422154100480d110240024020272008470d002015103221120c010b200b28020c201041106a2015103421120b2012450d07200b201236020c200f20073602000b200b28020c20134104746a220741106a2007200220136b410474109c051a200741046a200d3602002007410b3a00002005200141026a360200200e41046a210e201041206a2110200841026a21082014201141086a2211470d000b0b02402028450d00202310290b02402029450d00202410290b200b41186a210702400240201c450d0020052802002202450d00200b28020c210120024104742102410021080340024020012d0000412c470d002001410b3a0000200141046a201e360200200841016a21080b200141106a2101200241706a22020d000b4101210e20080d010b2022210e0b20072021470d010c080b0b41b0d9c500106d000b20124108102e000b41b0d9c500106d000b20154108102e000b20062802042201200d490d022006200141016a3602040c020b200628020c2201450d012006280204220b2001411c6c6a21070340200b2201411c6a210b024020012802182202450d0020012802102101200241027421020340024020012802002208200d490d002001200841016a3602000b200141046a21012002417c6a22020d000b0b200b2007460d020c000b0b200628020c2201450d00200141146c2102200628020441106a2101034002402001417c6a2802000d0020012802002208200d490d002001200841016a3602000b200141146a21012002416c6a22020d000b0b2006412c6a2206201f470d000b20204101710d02200e4101710d01200428028002210720042802f80121060b200441fc016a280200210f20042802f401210e20042802f0012111410021130c020b200441b0036a41106a200441f0016a41106a280200360200200441b0036a41086a200441f0016a41086a290300370300200420042903f0013703b003200441a0026a200441b0036a10d303411010322202450d07200241063a0000410110322201450d06200141003a000041011032220b450d05200b20012d00003a000020011029411010322208450d04200841063a000041f00010322201450d03200141063a00602001412c3b01502001200d3602442001410b3a0040200141d8003a00302001201c3602242001412d3a0020200141003602142001410f3a0010200141003602042001410f3a0000024020082d00004109470d00200828020841ffffffff0371450d00200828020410290b20081029024020022d00004109470d00200228020841ffffffff0371450d00200228020410290b20021029200441d4036a4287808080f000370200200441d0036a2001360200200441cc036a4100360200200441b0036a410c6a4281808080800c370200200441b8036a4101360200200441003602dc03200442043702c4032004200b3602b403200441013602b003200441a0026a200441b0036a10d703200441b0036a200441a0026a418c01109b051a20044188026a200441b0036a10d50320044188026a410c6a280200210f20044198026a28020021072004280288022111200428028c02210e2004280290022106410021130c010b200441fc016a280200210f20042802f801210602402004280280022207450d002007412c6c2102200621010340200110d8032001412c6a2101200241546a22020d000b0b41012113411a210e41d4b6c50021110240200f450d00200610290b0b0240201b450d000340200c28026c210c201b417f6a221b0d000b0b410021084100210102400340201a450d01024002402001200c2f01064f0d00200c20014103746a41146a2902002118200141016a21010c010b02400240200c28020022010d002008ad21184100210d410021010c010b200c3301044220862008ad8421184101210d0b200c10292018a72108024002402018422088a7220b20012f01064f0d00200121020c010b034002400240200128020022020d002008ad2118410021020c010b200d41016a210d20013301044220862008ad8421180b200110292018a72108200221012018422088a7220b20022f01064f0d000b0b200b41027420026a41f0006a280200210c2002200b4103746a41146a29020021180240200d417f6a2201450d000340200c28026c210c2001417f6a22010d000b0b410021010b201a417f6a211a2018a74103470d000b0b0240200c41b0d6c000460d00200c2802002101200c10292001450d0020012802002102200110292002450d00024020022802002201450d000340200210292001210220012802002208210120080d000b0b200210290b02402013450d002000201136020420004101360200200041086a200e3602000c250b200441a0026a41106a2007360200200441a0026a410c6a200f360200200420063602a8022004200e3602a402200420113602a002200441b0036a200441a0026a200928026010d903024020042802b0034101470d000240200441b0036a41086a280200450d0020042802b40310290b200041eeb6c50036020420004101360200200041086a41233602000c250b200441c4036a2802002102200441b0036a41106a2802002105200441b0036a410c6a2802002110200441b8036a280200210d20042802b4032108200328025821062004410036029002200442013703880202400240410410322201450d002004410436028c022004200428029002220b41046a3602900220042001360288022001200b6a200836000002400240200428028c02220820042802900222016b4104490d0020042802880221080c010b200141046a220b2001490d0320084101742201200b200b2001491b22014100480d030240024020080d002001103221080c010b20042802880220082001103421080b2008450d022004200136028c02200420083602880220042802900221010b2004200141046a36029002200820016a200d36000020102002412c6c22016a210d024020020d00201021010c0e0b200141546a2103200441b0036a4101722102200441b0036a41276a210b200441b0036a41206a210c200441b0036a41186a2107200441b0036a41106a210e200441b0036a41086a211120102101034020012d00002108200b200141286a280000360000200c200141216a2900003703002007200141196a290000370300200e200141116a2900003703002011200141096a2900003703002004200141016a2900003703b00302402008410f470d002001412c6a21010c0f0b200441a0026a41276a2213200b280000360000200441a0026a41206a220f200c290300370300200441a0026a41186a20072903002218370300200441a0026a41106a200e2903002219370300200441a0026a41086a2011290300222a370300200420042903b003222b3703a0022002202b370000200241086a202a370000200241106a2019370000200241186a2018370000200241206a200f290300370000200241276a2013280000360000200420083a00b003200441e0006a200441b0036a20044188026a10da0320042d00602208411a470d0d200341546a21032001412c6a2201200d470d000b200d21010c0d0b41044101102e000b20014101102e000b1033000b41f0004108102e000b41104108102e000b41014101102e000b41014101102e000b41104108102e000b20074104102e000b41034101102e000b41034101102e000b41014101102e000b200428026421122004280268210602402003450d002001412c6a2101200441b0036a4101722102200441b0036a41276a210c200441b0036a41206a2107200441b0036a41186a210e200441b0036a41106a2111200441b0036a41086a2103034020012d0000210b200c200141286a2800003600002007200141216a290000370300200e200141196a2900003703002011200141116a2900003703002003200141096a2900003703002004200141016a2900003703b003200b410f460d01200441a0026a41276a2213200c280000360000200441a0026a41206a220f2007290300370300200441a0026a41186a200e2903002218370300200441a0026a41106a20112903002219370300200441a0026a41086a2003290300222a370300200420042903b003222b3703a0022002202b370000200241086a202a370000200241106a2019370000200241186a2018370000200241206a200f290300370000200241276a20132800003600002004200b3a00b003200441b0036a10d8032001412c6a2201200d470d000b0b02402005450d00201010290b0240200428028c02450d0020042802880210290b024020084105470d002006450d00201210290b200041afb9c50036020420004101360200200041086a41253602000c190b02402001200d460d00200441b0036a4101722102200441b0036a41276a210b200441b0036a41206a210c200441b0036a41186a2107200441b0036a41106a210e200441b0036a41086a2111034020012d00002108200b200141286a280000360000200c200141216a2900003703002007200141196a290000370300200e200141116a2900003703002011200141096a2900003703002004200141016a2900003703b0032008410f460d01200441a0026a41276a2203200b280000360000200441a0026a41206a2213200c290300370300200441a0026a41186a20072903002218370300200441a0026a41106a200e2903002219370300200441a0026a41086a2011290300222a370300200420042903b003222b3703a0022002202b370000200241086a202a370000200241106a2019370000200241186a2018370000200241206a2013290300370000200241276a2003280000360000200420083a00b003200441b0036a10d8032001412c6a2201200d470d000b0b02402005450d00201010290b2004280288022101200429028c0221182000411c6a41003a0000200041146a2018370200200041106a20013602002000410c6a2017360200200041086a2016360200200020063602042000411d6a20042f00f0013b0000200041003602002000411f6a200441f2016a2d00003a00000c180b200e102920004183b0c4003602040c160b200e102920004183b0c4003602040c150b200e102920004183b0c4003602040c140b200e102920004183b0c4003602040c130b200e102920004183b0c4003602040c120b200e102920004183b0c4003602040c110b200e102920004183b0c4003602040c100b200e102920004183b0c4003602040c0f0b200f2d000d22024104460d00200241fb01710d00200e1029201121020c0b0b200e102920004183b0c4003602040c0d0b200f2d000d22024104460d01200241fb01710d01200e1029201121020c090b200f2d000d22024104460d02200241fb01710d02200e1029201121020c080b200e102920004183b0c4003602040c0a0b200e102920004183b0c4003602040c090b200e102920004183b0c4003602040c080b200e102920004183b0c4003602040c070b02400240200241e4afc500460d0041e4afc5002002410b109d050d010b4126210c4183b0c400210e200f2d000c41e000470d01200f2802080d0120112102200f2d000d4104460d040c010b024020024188b0c500460d004188b0c5002002410b109d050d030b4126210c4183b0c400210e200f2d000c41e000470d00200f2802080d0020112102200f2d000d4104460d030b200e2108200c21010b200020083602040c040b0240200241c2b1c500460d0041c2b1c5002002410b109d050d030b024041021032220c450d00200c41003b0000200f2d000c41e000470d02200f2802084102470d02200f280200210e410021010240034020014102460d01200c20016a2102200e20016a2108200141016a210120082d000020022d0000470d040c000b0b200f2d000d4104470d02200c1029201121020c010b0b41024101102e000b200c10290b4126210120004183b0c4003602040b20004101360200200041086a200136020002402007450d00200b2007412c6c6a2107200b210c0340200c220d412c6a210c02400240200d2d00002201410d4b0d00024002400240024002400240024002400240024002400240024020010e0e0001020304050607080e090a0b0c000b200d41086a280200450d0d200d41046a28020010290c0d0b0240200d41086a280200450d00200d41046a28020010290b200d41146a280200450d0c200d41106a28020010290c0c0b0240200d410c6a2802002202450d00200d41046a28020021012002410474210203400240200141046a280200450d00200128020010290b200141106a2101200241706a22020d000b0b200d41086a280200450d0b200d28020410290c0b0b0240200d410c6a2802002202450d00200d41046a2802002101200241286c210203400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141286a2101200241586a22020d000b0b200d41086a280200450d0a200d28020410290c0a0b200d41086a280200450d09200d41046a28020010290c090b200d41086a280200450d08200d41046a28020010290c080b200d41086a280200450d07200d41046a28020010290c070b0240200d410c6a2802002201450d00200d41046a280200220820014104746a21000340024020082802082202450d0020082802002101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200241706a22020d000b0b200841106a21010240200841046a280200450d00200828020010290b2001210820012000470d000b0b200d41086a280200450d06200d28020410290c060b0240200d410c6a2802002202450d00200d41046a2802002101200241146c210203400240200141046a280200450d00200128020010290b200141146a21012002416c6a22020d000b0b200d41086a280200450d05200d28020410290c050b0240200d410c6a2802002201450d00200d41046a28020022082001411c6c6a2100034002402008410c6a2802002202450d0020082802042101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200241706a22020d000b0b0240200841086a280200450d00200828020410290b2008411c6a21010240200841146a280200450d00200828021010290b2001210820012000470d000b0b200d41086a280200450d04200d28020410290c040b0240200d410c6a2802002201450d00200d41046a2802002208200141186c6a210003400240200841046a280200450d00200828020010290b0240200841146a2802002202450d00200828020c2101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200241706a22020d000b0b200841186a21010240200841106a280200450d00200828020c10290b2001210820012000470d000b0b200d41086a280200450d03200d28020410290c030b0240200d410c6a2802002201450d00200d41046a28020022082001411c6c6a2100034002402008410c6a2802002202450d0020082802042101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200241706a22020d000b0b0240200841086a280200450d00200828020410290b2008411c6a21010240200841146a280200450d00200828021010290b2001210820012000470d000b0b200d41086a280200450d02200d28020410290c020b0240200d41046a2d0000220141024b0d0002400240024020010e03000102000b200d410c6a280200450d04200d41086a28020010290c040b0240200d41146a2802002202450d00200d410c6a28020021012002410c6c21020340024020012802002208450d00200141046a280200450d00200810290b2001410c6a2101200241746a22020d000b0b200d41106a280200450d03200d28020c10290c030b0240200d41146a2802002201450d00200d410c6a280200220e20014104746a21110340200e220041106a210e024020002802042201450d0002402000410c6a2802002202450d002002410c6c21020340024020012802002208450d00200141046a280200450d00200810290b2001410c6a2101200241746a22020d000b0b200041086a280200450d00200028020410290b200e2011470d000b0b200d41106a280200450d02200d28020c10290c020b200d410c6a280200450d01200d41086a28020010290c010b0240200d41086a280200450d00200d41046a28020010290b0240200d41146a2802002201450d00200d41186a280200450d00200110290b200d41246a280200450d00200d41206a28020010290b200c2007470d000b0b200a450d00200b10290b200441c0046a24000ba10301067f230041106b22022400200241003602082002420137030020002002109801200041046a2002109801200041086a200210980120002d0018210302400240024002400240200228020420022802082204460d00200228020021050c010b200441016a22052004490d0320044101742206200520052006491b22064100480d030240024020040d002006103221050c010b200228020020042006103421050b2005450d0120022006360204200220053602000b2002200441016a360208200520046a20033a0000200028020c2106200041146a2802002204200210660240024020022802042203200228020822056b2004490d00200228020021000c010b200520046a22002005490d0320034101742207200020002007491b22074100480d030240024020030d002007103221000c010b200228020020032007103421000b2000450d022002200736020420022000360200200721030b200020056a20062004109b051a200128020020012802042000200520046a100502402003450d00200010290b200241106a24000f0b20064101102e000b20074101102e000b1033000bf70802067f047e230041d0026b220224000240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a3602042001200441016a360200200541034b0d0620050e0401020304010b200041053a00000c090b200241206a2001103120022802200d03200041053a00000c080b200241c0006a2001104f0240024020022d00404113460d00200241c8016a200241c0006a418801109b051a418801103222050d014188014108102e000b200041053a00000c080b2005200241c8016a418801109b052105200041023a0000200020022f00103b0001200041036a200241106a41026a2d00003a0000200041046a2005360200200041086a2002290220370200200041106a200241206a41086a290200370200200041186a200241206a41106a290200370200200041206a200241206a41186a2902003702000c070b20022001102c20022802000d0520022802042105200241c0006a2001104f20022d00404113460d05200241c8016a200241c0006a418801109b051a41880110322201450d032001200241c8016a418801109b052101200041033a0000200020022f00103b0001200041036a200241126a2d00003a0000200041086a2001360200200041046a20053602002000410c6a2002290220370200200041146a200241206a41086a2902003702002000411c6a200241306a290200370200200041246a200241386a2802003602000c060b41002105200241003a00e8012003417f6a21062003417e6a21030340024020062005470d00200541ff0171450d05200241003a00e8010c050b200241c8016a20056a200420056a220741016a2d00003a0000200120033602042001200741026a3602002002200541016a22073a00e8012003417f6a21032007210520074120470d000b200241c0006a41186a200241c8016a41186a290300370300200241c0006a41106a200241c8016a41106a290300370300200241c0006a41086a200241c8016a41086a290300370300200220022903c801370340200241086a2001102c20022802080d0320012802042205450d03200228020c2103200128020022072d0000210420012005417f6a3602042001200741016a360200200241206a41086a200241c0006a41086a2903002208370300200241206a41106a200241c0006a41106a2903002209370300200241206a41186a200241c0006a41186a290300220a37030020022002290340220b370320200041043a00002000200b370001200041096a2008370000200041116a2009370000200041196a200a370000200041246a2003360200200041216a20043a00000c050b200241cb006a200241206a41086a28020036000020022002290320370043200041013a000020002002290040370001200041086a200241c7006a290000370000200041106a20022902c801370200200041186a200241c8016a41086a290200370200200041206a200241c8016a41106a2902003702000c040b200041053a00000c030b4188014108102e000b200041053a00000c010b200041053a00000b200241d0026a24000bd50603057f0b7e057f230041106b21020240200128020422034104490d0020012802002204280000210520012003417c6a22063602042001200441046a36020020064108490d00200429000421072001200341746a220636020420012004410c6a36020020064108490d00200429000c210820012003416c6a22063602042001200441146a36020020064108490d00200429001421092001200341646a220636020420012004411c6a36020020064108490d00200429001c210a20012003415c6a22063602042001200441246a36020020064108490d002004290024210b2001200341546a220636020420012004412c6a36020020064108490d00200429002c210c20012003414c6a22063602042001200441346a36020020064108490d002004290034210d2001200341446a220636020420012004413c6a36020020064108490d00200429003c210e2001200341bc7f6a22063602042001200441c4006a36020020064108490d002004290044210f2001200341b47f6a22063602042001200441cc006a36020020064108490d00200429004c21102001200341ac7f6a22063602042001200441d4006a36020020064108490d00200429005421112001200341a47f6a22063602042001200441dc006a36020020064104490d00200428005c21122001200341a07f6a22063602042001200441e0006a36020020064104490d002004280060211320012003419c7f6a22063602042001200441e4006a36020020064104490d00200428006421142001200341987f6a22063602042001200441e8006a36020020064104490d00200428006821152001200341947f6a22063602042001200441ec006a22043602002006450d0020042d000021162001200341937f6a22063602042001200441016a36020020064104490d00200020163a00702000201536026820002014360264200020133602602000201236025c2000200536025820002011370350200020103703482000200f3703402000200e3703382000200d3703302000200c3703282000200b3703202000200a3703182000200937031020002008370308200020073703002004280001210620012003418f7f6a3602042001200441056a3602002000200636026c200041f4006a2002410c6a280000360000200020022800093600710f0b200041023a00700bd40701047f230041106b22022400024002400240024002400240024020002d0000417f6a220341034b0d00024002400240024020030e0400010203000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d0a20034101742205200420042005491b22054100480d0a0240024020030d002005103221040c010b200128020020032005103421040b2004450d0520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a000020002802042000410c6a28020020011094010c030b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d0920034101742205200420042005491b22054100480d090240024020030d002005103221040c010b200128020020032005103421040b2004450d0520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a000020002802042001105f0c020b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d0820034101742205200420042005491b22054100480d080240024020030d002005103221040c010b200128020020032005103421040b2004450d0520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a0000200041046a200110980120002802082001105f0c010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d0720034101742205200420042005491b22054100480d070240024020030d002005103221040c010b200128020020032005103421040b2004450d0520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a00002002200136020c200041016a2002410c6a108501200041246a200110980102400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d0720034101742205200420042005491b22054100480d070240024020030d002005103221040c010b200128020020032005103421040b2004450d0620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00213a00000b200241106a24000f0b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b1033000bf71802047f017e20002802582102024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2802002203200141086a28020022046b4104490d00200128020021030c010b200441046a22052004490d1320034101742204200520052004491b22044100480d130240024020030d002004103221030c010b200128020020032004103421030b2003450d0120012003360200200141046a2004360200200141086a28020021040b200141086a2205200441046a360200200320046a20023600002000290300210602400240200141046a2802002203200528020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004103221030c010b200128020020032004103421030b2003450d0220012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290308210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004103221030c010b200128020020032004103421030b2003450d0320012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290310210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004103221030c010b200128020020032004103421030b2003450d0420012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290318210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004103221030c010b200128020020032004103421030b2003450d0520012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290320210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004103221030c010b200128020020032004103421030b2003450d0620012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290328210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004103221030c010b200128020020032004103421030b2003450d0720012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290330210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004103221030c010b200128020020032004103421030b2003450d0820012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290338210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004103221030c010b200128020020032004103421030b2003450d0920012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290340210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004103221030c010b200128020020032004103421030b2003450d0a20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290348210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004103221030c010b200128020020032004103421030b2003450d0b20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a20063700002000290350210602400240200141046a2802002203200228020022046b4108490d00200128020021030c010b200441086a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004103221030c010b200128020020032004103421030b2003450d0c20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441086a360200200320046a2006370000200028025c210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004103221030c010b200128020020032004103421030b2003450d0d20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a20053600002000280260210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004103221030c010b200128020020032004103421030b2003450d0e20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a20053600002000280264210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004103221030c010b200128020020032004103421030b2003450d0f20012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a20053600002000280268210502400240200141046a2802002203200228020022046b4104490d00200128020021030c010b200441046a22022004490d1320034101742204200220022004491b22044100480d130240024020030d002004103221030c010b200128020020032004103421030b2003450d1020012003360200200141046a2004360200200141086a28020021040b200141086a2202200441046a360200200320046a200536000002400240200141046a28020020022802002204460d00200128020021030c010b200441016a22032004490d1320044101742202200320032002491b22024100480d130240024020040d002002103221030c010b200128020020042002103421030b2003450d1120012003360200200141046a2002360200200141086a28020021040b200141086a2202200441016a360200200320046a20002d00703a0000200028026c210302400240200141046a2802002204200228020022006b4104490d00200128020021040c010b200041046a22022000490d1320044101742200200220022000491b22004100480d130240024020040d002000103221040c010b200128020020042000103421040b2004450d1220012004360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200420006a20033600000f0b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20024101102e000b20004101102e000b1033000b9d05070a7f047e037f027e057f027e017f200128020821032001280204210420012802002105200241386a2106200241286a2107034002400240200441b0d6c000462208450d00410021094108210a4108210b0c010b20042f01062109200441086a220a210b0b200b200941d0006c6a210c2006290300210d2007290300210e2002290330210f2002290320211020022802482111200228024021124100210b0240024002400340200b21090240200a200c470d0002402008450d00410021090c030b20042f010621090c020b024002402002200a4120109d05220b450d00417f4101200b4100481b21130c010b417f2010200a290320221456200e200a41286a290300221556200e201551220b1b2010201454200e201554200b1b1b22130d00417f200f200a41306a290300221456200d200a41386a290300221556200d201551220b1b200f201454200d201554200b1b1b22130d00200a41c8006a28020022162011201120164b22171b2118200a280240210b417f21192012211a03400240201941016a22192018490d00417f201720112016491b21130c020b0240201a41106a200b41106a4120109d052213450d00417f410120134100481b21130c020b201a290300221b200b290300221c54201a41086a2903002215200b41086a2903002214542015201451221d1b0d03200b41306a210b201a41306a211a41012113201b201c582015201458201d1b0d000b0b200941016a210b200a41d0006a210a0240201341016a0e03020001020b0b4100210a0c010b20050d014101210a410021050b200020053602042000200a360200200041106a20093602002000410c6a2003360200200041086a20043602000f0b2001200336020820012005417f6a22053602002001200420094102746a41f8066a28020022043602040c000b0b8b04010f7f230041206b22022400024002400240200128020822030d0041042104410121054100210641002107410021010c010b2001280200220820034103746a21094100210a4100210b41012103410021064104210441002101410021074101210503402008280200210c02400240024002400240200720016b200841046a220d280200220e4f0d002001200e6a220f2001490d0120074101742210200f200f2010491b220f4100480d010240024020070d00200f103221050c010b20052007200f103421050b2005450d02200f21070b200520016a200c200e109b051a200d280200210c2003417f6a2006470d03200a20032003200a491b220641ffffffff03712006470d002006410274220d41004e0d020b1033000b200f4101102e000b02400240200b0d00200d103221040c010b2004200b200d103421040b2004450d030b2001200e6a21012004200b6a200c360200200a41026a210a200b41046a210b200341016a2103200841086a22082009470d000b2003417f6a21010b200241186a22034200370300200241106a22084200370300200241086a220b4200370300200242003703002005200420012002100b200041186a2003290300370000200041106a2008290300370000200041086a200b2903003700002000200229030037000002402006450d00200410290b02402007450d00200510290b200241206a24000f0b200d4104102e000b0a0041bcd9c200106d000b5201027e024002402003450d002002280200450d010b41929cc50041f403109201000b2001280218220342002003290308220420023502047d2205200520045622021b37030820004105410420021b3602000bf80e05047f027e027f017e027f230041c00c6b22042400024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d0320022802042105200241246a2802002106200241346a28020021030240200241146a2802002207450d004105210220012802002802182802402802bc012003490d080b200441286a4200370300200441206a4200370300200441186a420037030020012802182202420020022903082208427f20012802102903482209420586200942ffffffffffffffff07832009521b7d22092009200856220a1b3703082004420037031041052102200a0d070240024020012802142802082005200441106a4120102141026a220a41024b0d00200a0e03090001090b41ece7c500106d000b024002400240024020070d00410121034100210b0c010b2004200128021029034842002003ad220c420010a0052001280218220a4200200a2903082209427f200429030020042903084200521b7d22082008200956220a1b370308200a0d0a2003417f4c0d070240024020030d004101210b02402001280214280208200641014100102141026a220341024b0d0020030e030d00020d0b41ece7c500106d000b02402003102d220b450d00024020012802142802082006200b2003102141026a220341024b0d0020030e03040002040b41ece7c500106d000b20034101102e000b200c422086200c842109200b4521030b20012802002101200441306a41186a220a200441106a41186a290300370300200441306a41106a2205200441106a41106a290300370300200441306a41086a2206200441106a41086a290300370300200420042903103703302001280218210720030d0120072802402802bc012009422088a74f0d012009a7450d090b200b10290c080b200441d0006a41186a200a290300370300200441d0006a41106a2005290300370300200441d0006a41086a20062903003703002004200429033037035020072802180d052007417f360218200441a8016a200741e8006a290000370300200441a0016a200741e0006a29000037030020044198016a200741d8006a2900003703002004200729005037039001024002402007411c6a220d280200220a41b0d6c000460d00200741206a28020021060c010b41002106200441e0096a410041e002109a051a200441c0016a410041a008109a051a41880b1032220a450d07200a41003b0106200a4100360200200a41086a200441e0096a41e002109b051a200a41e8026a200441c0016a41a008109b051a200741206a41003602002007200a36021c0b024002400340200a2f0106220e4105742105410021024100210302400240034020052002460d0120044190016a200a20026a41086a4120109d052201450d02200241206a2102200341016a21032001417f4a0d000b2003417f6a210e0b2006450d022006417f6a2106200a200e4102746a41880b6a280200210a0c010b0b200741246a2101410121020c010b200441f0006a41186a20044190016a41186a290300370300200441f0006a41106a20044190016a41106a290300370300200441f0006a41086a20044190016a41086a2903003703002004200429039001370370200741246a210141002106200e2103410021020b0240024020020d00200441fc096a200441f0006a41086a290300370200200441840a6a200441f0006a41106a2903003702002004418c0a6a200441f0006a41186a290300370200200420013602f009200420033602ec092004200d3602e8092004200a3602e409200420063602e009200420042903703702f409200441e0016a20042903b001370300200441e8016a200441b0016a41086a290300370300200441f4016a4200370200200442003703d801200442003703c001200441b0d6c0003602f001200441003a00fc01200441fd016a20042900900137000020044185026a20044190016a41086a2900003700002004418d026a20044190016a41106a29000037000020044195026a20044190016a41186a290000370000200441003a009d02200441e0096a200441c0016a10c80121020c010b200441d8016a4200370300200441d4016a41b0d6c000360200200441003602e001200441003602d001200442003703c801200441b0d6c0003602c401200441003602c001200a200341e0006c6a41e8026a2102200441c0016a10c9010b200441c0016a41186a200441d0006a41186a290300370300200441c0016a41106a200441d0006a41106a290300370300200441c0016a41086a200441d0006a41086a290300370300200420042903503703c00120042009370294012004200b36029001200441e0096a200241306a200441c0016a20044190016a10cb01024020042802e009450d0020042802e4092202450d00200441e8096a280200450d00200210290b2007200728021841016a360218410421020c070b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b102f000b41e898c5004110200441c0016a41a099c5001054000b41880b4108102e000b20002002360200200441c00c6a24000b910302017f027e230041c0006b22042400024002402003450d0020022802000d0020022802042103200441186a4200370300200441106a4200370300200441086a420037030020012802182202420020022903082205427f20012802102903482206420586200642ffffffffffffffff07832006521b7d2206200620055622021b3703082004420037030002400240024020020d00024002402001280214280208200320044120102141026a220241024b0d0020020e03020001020b41ece7c500106d000b200441206a2001280200280218220241186a200241d0006a2002410c6a4100200228020c1b2004109f042004280220450d01200441306a41086a2203200441206a41086a28020036020020042004290320370330200141046a21020240200141086a280200450d00200228020010290b20022004290330370200200241086a2003280200360200410021010c020b200041053602000c030b2001410c6a4100360200410121010b20004100360200200020013602040c010b41929cc50041f403109201000b200441c0006a24000b9f1006017f017e057f027e037f027e230041d0016b22042400024002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802204101470d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620022802042103200241286a2903002105200241346a2802002106200241c4006a2802002107200241d4006a2802002108200241e4006a2802002109200441286a20012802102903484200200241146a280200220aad420010a0052001280218220242002002290308220b427f200429032820042903304200521b7d220c200c200b5622021b370308024002400240024020020d00200a417f4c0d0b02400240024002400240200a0d004101210d02402001280214280208200341014100102141026a220241024b0d00200141146a210e20020e03060002060b41ece7c500106d000b0240200a102d220d450d00024020012802142802082003200d200a102141026a220241024b0d00200141146a210e20020e03030002030b41ece7c500106d000b200a4101102e000b41002102200441003a00b80102400340200a2002460d0120044198016a20026a200d20026a2d00003a00002004200241016a22033a00b8012003210220034120470d000b200441f8006a41186a220220044198016a41186a290300370300200441f8006a41106a220320044198016a41106a290300370300200441f8006a41086a220f20044198016a41086a29030037030020042004290398013703780240200a450d00200d10290b200441386a41086a200f290300370300200441386a41106a2003290300370300200441386a41186a200229030037030020042004290378370338200441186a200128021029034842002007ad420010a0052001280218220242002002290308220b427f200429031820042903204200521b7d220c200c200b5622021b37030820020d042007417f4c0d0f20070d03200e280200280208200641014100102141026a220241024b0d0220020e03040204040b0240200241ff0171450d00200441003a00b8010b200a450d030b200d10290c020b41ece7c500106d000b0240024002402007102d2202450d000240200e280200280208200620022007102141026a220341024b0d0020030e03030002030b41ece7c500106d000b20074101102e000b2007410f4d0d00200241086a29000021102002290000211120021029200441086a200128021029034842002009ad420010a0052001280218220242002002290308220b427f200429030820042903104200521b7d220c200c200b5622021b37030820020d010240024020092001410c6a28020022034b0d002009200320092003491b21020c010b02400240200141086a280200220220036b200920036b220d490d002001280204210a200321020c010b2003200d6a220a2003490d1020024101742207200a200a2007491b22074100480d100240024020020d0020071032210a0c010b2001280204200220071034210a0b200a450d0f2001200a360204200141086a20073602002001410c6a28020021020b200a20026a210702400240200d4102490d002007410020092003417f7322036a220d109a051a200a200920026a20036a6a2107200d20026a21020c010b200d450d010b200741003a0000200241016a21020b2001410c6a2002360200024002402001280214280208200820012802042002102141026a220241024b0d0020020e03030001030b41ece7c500106d000b2001410c6a2202280200210320024100360200200141086a280200210a2001280204210d200142013702042001280218220241086a2207290300220c210b024002400240024002402005500d002005210b200c2005540d010b2007200c200b7d3703002002290310210c200441f8006a41186a200241186a2903003703002004200b370380012004200b3703782004200c370388012001280200280218210720044198016a41186a200441386a41186a29030037030020044198016a41106a200441386a41106a29030037030020044198016a41086a200441386a41086a2903003703002004200429033837039801200420033602c8012004200a3602c4012004200d3602c001200441d8006a200720044198016a20112010200441f8006a200441c0016a10e2014101210a20042802584101460d01200441d8006a41106a2d00002103200441e4006a280200210d200441e0006a28020021074100210a200428025c21060c020b200420033602a0012004200a36029c012004200d3602980120044198016a21020c020b200441ec006a280200210d200441d8006a41106a2802002107200441e4006a2802002106410021030b200241086a220220042903800120022903007c370300200141086a28020021020240200a0d0002402002450d00200128020410290b200120063602042001410c6a200d360200200141086a20073602000c060b2004200d3602a0012004200736029c01200420063602980120020d0320044198016a21020b200120022902003702042001410c6a41003602000c030b200210290b200041053602000c0d0b2001280204102920012004290398013702042001410c6a41003602000b41800221030b20004100360200200020033602040c0a0b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b102f000b20074101102e000b1033000b200441d0016a24000bbf1107017f017e057f027e037f027e017f230041e0016b22042400024002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802204101470d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620022802042103200241286a2903002105200241346a2802002106200241c4006a2802002107200241d4006a2802002108200241e4006a2802002109200441206a20012802102903484200200241146a280200220aad420010a0052001280218220242002002290308220b427f200429032020042903284200521b7d220c200c200b5622021b370308024002400240024020020d00200a417f4c0d0b02400240024002400240200a0d004101210d02402001280214280208200341014100102141026a220241024b0d00200141146a210e20020e03060002060b41ece7c500106d000b0240200a102d220d450d00024020012802142802082003200d200a102141026a220241024b0d00200141146a210e20020e03030002030b41ece7c500106d000b200a4101102e000b41002102200441003a00c80102400340200a2002460d01200441a8016a20026a200d20026a2d00003a00002004200241016a22033a00c8012003210220034120470d000b20044188016a41186a2202200441a8016a41186a29030037030020044188016a41106a2203200441a8016a41106a29030037030020044188016a41086a220f200441a8016a41086a290300370300200420042903a801370388010240200a450d00200d10290b200441306a41086a200f290300370300200441306a41106a2003290300370300200441306a41186a20022903003703002004200429038801370330200441106a200128021029034842002007ad420010a0052001280218220242002002290308220b427f200429031020042903184200521b7d220c200c200b5622021b37030820020d042007417f4c0d0f20070d03200e280200280208200641014100102141026a220241024b0d0220020e03040204040b0240200241ff0171450d00200441003a00c8010b200a450d030b200d10290c020b41ece7c500106d000b0240024002402007102d2202450d000240200e280200280208200620022007102141026a220341024b0d0020030e03030002030b41ece7c500106d000b20074101102e000b2007410f4d0d00200241086a290000211020022900002111200210292004200128021029034842002009ad420010a0052001280218220242002002290308220b427f200429030020042903084200521b7d220c200c200b5622021b37030820020d01200141046a210d0240024020092001410c6a28020022034b0d002009200320092003491b21020c010b02400240200141086a280200220220036b200920036b2207490d00200d280200210a200321020c010b200320076a220a2003490d1020024101742206200a200a2006491b22064100480d100240024020020d0020061032210a0c010b200d280200200220061034210a0b200a450d0f2001200a360204200141086a20063602002001410c6a28020021020b200a20026a21060240024020074102490d002006410020092003417f7322036a2207109a051a200a200920026a20036a6a2106200720026a21020c010b2007450d010b200641003a0000200241016a21020b2001410c6a2002360200024002402001280214280208200820012802042002102141026a220241024b0d0020020e03030001030b41ece7c500106d000b2001410c6a2202280200210320024100360200200141086a280200210a20012802042107200142013702042001280218220241086a2206290300220c210b0240024002402005500d002005210b200c2005540d010b2006200c200b7d3703002002290310210c20044188016a41186a200241186a2903003703002004200b370390012004200b370388012004200c3703980120012802002802182106200420033602582004200a36025420042007360250200441a8016a20062011201020044188016a200441306a200441d0006a10da01410121030240024020042802a8014101460d00200441d0006a41086a200441a8016a41186a290300370300200441d0006a41106a200441c8016a2802003602002004200441a8016a41106a290300370350200441d8016a2d00002109200441d0016a2802002108200441cc016a280200210e200441b4016a280200210a200441a8016a41086a28020021074100210320042802ac0121060c010b200441bc016a280200210a200441b8016a2802002107200441b4016a2802002106410021090b200441f0006a41086a220f200441d0006a41086a290300370300200441f0006a41106a2212200441d0006a41106a280200360200200241086a220220042903900120022903007c37030020042004290350370370024020030d00200441bc016a200f290300370200200441c4016a20122802003602002004200a3602b001200420073602ac01200420063602a801200420042903703702b4010240200141086a280200450d00200d28020010290b2001200e3602042001410c6a4100360200200141086a2008360200200941ff017122020d07200441a8016a200d1081010c070b200141086a28020021022004200a3602b001200420073602ac01200420063602a80120020d04200441a8016a21020c010b200420033602b0012004200a3602ac01200420073602a801200441a8016a21020b200120022902003702042001410c6a41003602000c030b200210290b200041053602000c0d0b20012802041029200120042903a8013702042001410c6a41003602000b41800221020b20004100360200200020023602040c0a0b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b102f000b20064101102e000b1033000b200441e0016a24000ba80503027f037e047f230041206b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200441106a20012802102903184200200241146a2802002203ad2206420010a00520012802182202420020022903082207427f200429031020042903184200521b7d2208200820075622021b370308024020020d002004200128021029034842002006420010a00520012802182202420020022903082207427f200429030020042903084200521b7d2208200820075622021b37030820020d000240024020032001410c6a28020022094b0d002003200920032009491b21020c010b02400240200141086a280200220220096b200320096b220a490d002001280204210b200921020c010b2009200a6a220b2009490d062002410174220c200b200b200c491b220c4100480d060240024020020d00200c1032210b0c010b20012802042002200c1034210b0b200b450d052001200b360204200141086a200c3602002001410c6a28020021020b200b20026a210c02400240200a4102490d00200c410020032009417f7322096a220a109a051a200b200320026a20096a6a210c200a20026a21020c010b200a450d010b200c41003a0000200241016a21020b2001410c6a2002360200024002402001280214280208200520012802042002102141026a220241024b0d0020020e03020001020b41ece7c500106d000b2001410c6a2202280200210320024100360200200141086a280200210220012802042105200142013702040240200128021c2209450d00200141206a280200450d00200910290b2001200536021c200141246a2003360200200141206a20023602000b20004105360200200441206a24000f0b41929cc50041f403109201000b41929cc50041f403109201000b200c4101102e000b1033000b23002001410c6a4100360200200128020041206a200141046a108101200041043602000b27002001410c6a4100360200200128020028021841d0006a200141046a108101200041043602000bd50102027f027e410021042001410c6a41003602002001280218220541186a2903002106200529031021070240024002400240200141086a28020022054110490d00200128020421050c010b200541017422044110200441104b1b22044100480d020240024020050d002004103221050c010b200128020420052004103421050b2005450d0120012005360204200141086a20043602002001410c6a28020021040b2001410c6a200441106a360200200520046a2201200637000820012007370000200041043602000f0b20044101102e000b1033000bc50103017f017e017f410021042001410c6a4100360200200128021841086a29030021050240024002400240200141086a28020022064108490d00200128020421060c010b200641017422044108200441084b1b22044100480d020240024020060d002004103221060c010b200128020420062004103421060b2006450d0120012006360204200141086a20043602002001410c6a28020021040b2001410c6a200441086a360200200620046a2005370000200041043602000f0b20044101102e000b1033000bb804020b7f027e230041206b220424002001410c6a41003602000240024002402001280200280218220528021841016a220641004c0d00200541d0006a2107200520063602182005411c6a2108200541206a28020021090240024003402008280200220a41086a210b200a2f0106220c41057421084100210d0240024003402008450d012007200b4120109d05220e450d02200841606a2108200d41016a210d200b41206a210b200e417f4a0d000b200d417f6a210c0b2009450d022009417f6a2109200a200c4102746a41880b6a21080c010b0b200a200d41e0006c6a220841c5036a310000200841e8026a290300220f200f50220b1ba7450d004200200841f8026a290300200b1b210f4200200841f0026a290300200b1b21100c010b200441086a200541286a28020020072005412c6a28020028021c110200200441106a290300210f20052802182106200429030821100b20052006417f6a36021802400240200141086a280200220b2001410c6a28020022086b4110490d002001280204210b0c010b200841106a220d2008490d03200b4101742208200d200d2008491b22084100480d0302400240200b0d0020081032210b0c010b2001280204200b20081034210b0b200b450d022001200b360204200141086a20083602002001410c6a28020021080b2001410c6a200841106a360200200b20086a2208200f3700082008201037000020004104360200200441206a24000f0b41f898c5004118200441186a419099c5001054000b20084101102e000b1033000bd50102027f027e410021042001410c6a41003602002001280200220541086a2903002106200529030021070240024002400240200141086a28020022054110490d00200128020421050c010b200541017422044110200441104b1b22044100480d020240024020050d002004103221050c010b200128020420052004103421050b2005450d0120012005360204200141086a20043602002001410c6a28020021040b2001410c6a200441106a360200200520046a2201200637000820012007370000200041043602000f0b20044101102e000b1033000b880302047f027e230041c0006b220424000240024002402003450d0020022802000d0020034101460d0120022802100d01410521050240200241146a28020022032001280210220628026c4b0d0020022802042107200441086a200629034842002003ad420010a00520012802182202420020022903082208427f200429030820042903104200521b7d2209200920085622021b37030820020d002003417f4c0d0302400240024020030d004101210202402001280214280208200741014100102141026a220641024b0d0020060e03040002040b41ece7c500106d000b02402003102d2202450d0002402001280214280208200720022003102141026a220641024b0d0020060e03030002030b41ece7c500106d000b20034101102e000b2001410c6a4100360200200441186a20022003109c03410421052004200141046a36023c200441186a2004413c6a1085012003450d010b200210290b20002005360200200441c0006a24000f0b41929cc50041f403109201000b41929cc50041f403109201000b102f000bc20103017f017e017f410021042001410c6a4100360200200128020029031021050240024002400240200141086a28020022064108490d00200128020421060c010b200641017422044108200441084b1b22044100480d020240024020060d002004103221060c010b200128020420062004103421060b2006450d0120012006360204200141086a20043602002001410c6a28020021040b2001410c6a200441086a360200200620046a2005370000200041043602000f0b20044101102e000b1033000bb20803027f047e027f230041e0046b2204240002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200441286a20012802102903484200200241146a2802002202ad420010a00520012802182203420020032903082206427f200429032820042903304200521b7d2207200720065622031b3703080240024020030d002002417f4c0d0402400240024020020d004101210302402001280214280208200541014100102141026a220541024b0d0020050e03040002040b41ece7c500106d000b02402002102d2203450d0002402001280214280208200520032002102141026a220541024b0d0020050e03030002030b41ece7c500106d000b20024101102e000b2004200236023c20042003360238200441d0036a200441386a104f024020042d00d00322054113460d00200441c8026a200441d0036a410172418701109b051a02402002450d00200310290b200441c0016a200441c8026a418701109b051a200420053a0038200441386a410172200441c0016a418701109b051a200441003602d803200442013703d003200441386a200441d0036a105f20042802d8032103024020042802d403450d0020042802d00310290b200128021822022903102206200241186a2903002207844200510d07200441186a2003ad42004280c8afa025420010a005200441086a200429031822084280a094a58d1d7c2209200441186a41086a2903002009200854ad7c2006200710a10520024200200229030822062004290308427f200441086a41086a290300501b7d220720072006561b37030820072006580d03200441386a102a0c020b2002450d010b200310290b410521020c070b20012802002102200441c8026a200441386a418801109b051a200441c0016a41086a2002280218220241d8006a290000370300200441d0016a2203200241e0006a290000370300200441d8016a2205200241e8006a290000370300200420022900503703c001200441d7036a200441c8026a418801109b051a02402002413c6a2802002201200241386a280200470d00200141016a220a2001490d062001410174220b200a200a200b491b220aad42b0017e2206422088a70d062006a7220b4100480d060240024020010d00200b103221010c010b2002280234200141b0016c200b103421010b2001450d0520022001360234200241386a200a360200200228023c21010b2002280234200141b0016c6a220141013a0000200120042903c001370001200141096a200441c8016a290300370000200141116a2003290300370000200141196a2005290300370000200141216a200441d0036a418f01109b051a2002200228023c41016a36023c410421020c060b41929cc50041f403109201000b41929cc50041f403109201000b102f000b41dc97c500106d000b200b4108102e000b1033000b20002002360200200441e0046a24000b941705087f027e037f027e047f230041a0026b22042400024002400240024002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620034107460d0720022802700d0720022802042103200241246a2802002105200241346a2802002106200241c4006a2802002107200241d4006a2802002108200241e4006a2802002109200241f4006a280200210a200441206a20012802102903484200200241146a280200220bad420010a0052001280218220242002002290308220c427f200429032020042903284200521b7d220d200d200c5622021b3703080240024020020d00200b417f4c0d0a024002400240200b0d004101210e02402001280214280208200341014100102141026a220241024b0d00200141146a210f20020e03040002040b41ece7c500106d000b0240200b102d220e450d00024020012802142802082003200e200b102141026a220241024b0d00200141146a210f20020e03030002030b41ece7c500106d000b200b4101102e000b41002102200441003a00f00102400340200b2002460d01200441d0016a20026a200e20026a2d00003a00002004200241016a22033a00f0012003210220034120470d000b20044180026a41086a2202200441d0016a41086a29030037030020044180026a41106a2203200441d0016a41106a29030037030020044180026a41186a2210200441d0016a41186a290300370300200420042903d001370380020240200b450d00200e10290b200441306a41086a2002290300370300200441306a41106a2003290300370300200441306a41186a20102903003703002004200429038002370330200441106a200128021029034842002006ad420010a0052001280218220242002002290308220c427f200429031020042903184200521b7d220d200d200c5622021b3703082002450d030c100b0240200241ff0171450d00200441003a00f0010b200b450d010b200e10290b200441f0006a41186a20044180026a41186a290300370300200441f0006a41106a20044180026a41106a290300370300200441f0006a41086a20044180026a41086a2903003703002004200429038002370370410521020c0e0b2006417f4c0d080240024002400240024020060d004101210b0240200f280200280208200541014100102141026a220241024b0d0020020e03120002120b41ece7c500106d000b02402006102d220b450d000240200f2802002802082005200b2006102141026a220241024b0d0020020e03030002030b41ece7c500106d000b20064101102e000b41002102200441003a00f0010240034020062002460d01200441d0016a20026a200b20026a2d00003a00002004200241016a22033a00f0012003210220034120470d000b20044180026a41086a2202200441d0016a41086a29030037030020044180026a41106a2203200441d0016a41106a29030037030020044180026a41186a220e200441d0016a41186a290300370300200420042903d0013703800202402006450d00200b10290b200441d0006a41086a2002290300370300200441d0006a41106a2003290300370300200441d0006a41186a200e29030037030020042004290380023703502004200128021029034842002008ad420010a0052001280218220242002002290308220c427f200429030020042903084200521b7d220d200d200c5622031b3703084105210220030d112008417f4c0d0c20080d03200f280200280208200741014100102141026a220341024b0d0220030e03110211110b0240200241ff0171450d00200441003a00f0010b2006450d0f0b200b1029410521020c0f0b41ece7c500106d000b024002400240024002402008102d2203450d000240200f280200280208200720032008102141026a220b41024b0d00200b0e03030002030b41ece7c500106d000b20084101102e000b2008410f4d0d00200341086a29000021112003290000211220031029024002400240200a0d00410121064100210b4100210e0c010b20044180026a41186a210320044180026a41106a210520044180026a41086a210841002110410021024100210b4100210e4101210603402003420037030020054200370300200842003703002001280218220742002007290308220d427f2001280210290348220c420586200c42ffffffffffffffff0783200c521b7d220c200c200d5622071b370308200442003703800220070d1102400240200f280200280208200920026a221320044180026a4120102141026a220741024b0d0020070e03130001130b41ece7c500106d000b200441d0016a41186a22142003290300370300200441d0016a41106a22152005290300370300200441d0016a41086a2216200829030037030020042004290380023703d0010240200b200e470d002010200b41016a220e200e2010491b220e41ffffff3f71200e470d03200e41057422074100480d0302400240200b0d002007103221060c010b200620022007103421060b2006450d110b200620026a220720042903d001370000200741186a2014290300370000200741106a2015290300370000200741086a2016290300370000201341206a2013490d11201041026a2110200241206a2102200a200b41016a220b470d000b0b2001280200280218210320044190016a41086a200441306a41086a29030037030020044190016a41106a2201200441306a41106a29030037030020044190016a41186a2205200441306a41186a290300370300200441b0016a41086a200341d8006a290000370300200441b0016a41106a2208200341e0006a290000370300200441b0016a41186a2207200341e8006a2900003703002004200429033037039001200420032900503703b00120044180026a41186a220a200441d0006a41186a29030037030020044180026a41106a2209200441d0006a41106a29030037030020044180026a41086a200441d0006a41086a29030037030020042004290350370380022003413c6a2802002202200341386a280200470d03200241016a220f2002490d0020024101742210200f200f2010491b220fad42b0017e220c422088a70d00200ca7221041004e0d020b1033000b200310290c0f0b0240024020020d002010103221020c010b2003280234200241b0016c2010103421020b2002450d0a20032002360234200341386a200f360200200328023c21020b2003280234200241b0016c6a220241023a0000200220042903b0013700012002200429039001370021200241096a200441b0016a41086a290300370000200241116a2008290300370000200241196a2007290300370000200241296a20044190016a41086a290300370000200241316a2001290300370000200241396a2005290300370000200220063600642002200e3600682002200b36006c20022012370370200241f8006a20113703002002200429038002370041200241c9006a20044180026a41086a290300370000200241d1006a2009290300370000200241d9006a200a290300370000200220042f00703b0061200241e3006a200441f0006a41026a2d00003a0000200220042903d0013703800120024188016a200441d0016a41086a29030037030020024190016a200441d0016a41106a29030037030020024198016a200441d0016a41186a290300370300200241a0016a200441f0016a290300370300200241a8016a200441f8016a2903003703002003200328023c41016a36023c410421020c0d0b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b102f000b20104108102e000b20074101102e000b41052102200e450d01200610290c010b410521020b20002002360200200441a0026a24000b16002000410036020020002001410c6a2802003602040bae0202057f027e230041106b220424000240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d024105210302402001410c6a2802002205200241146a2802002206490d00200520066b200241246a2802002205470d0020022802042107200128020421082004200128021029035042002005ad420010a00520012802182202420020022903082209427f200429030020042903084200521b7d220a200a20095622021b37030820020d000240024020012802142802082007200820066a2005102241026a220241024b0d0020020e03020001020b41fce8c500106d000b410421030b20002003360200200441106a24000f0b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b840403027f027e057f230041106b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200420012802102903484200200241146a2802002203ad420010a00520012802182202420020022903082206427f200429030020042903084200521b7d2207200720065622021b37030841052108024020020d000240024020032001410c6a28020022094b0d002003200920032009491b21020c010b02400240200141086a280200220220096b200320096b220a490d002001280204210b200921020c010b2009200a6a220b2009490d062002410174220c200b200b200c491b220c4100480d060240024020020d00200c1032210b0c010b20012802042002200c1034210b0b200b450d052001200b360204200141086a200c3602002001410c6a28020021020b200b20026a210c02400240200a4102490d00200c410020032009417f7322096a220a109a051a200b200320026a20096a6a210c200a20026a21020c010b200a450d010b200c41003a0000200241016a21020b2001410c6a2002360200024002402001280214280208200520012802042002102141026a220141024b0d0020010e03020001020b41ece7c500106d000b410421080b20002008360200200441106a24000f0b41929cc50041f403109201000b41929cc50041f403109201000b200c4101102e000b1033000bbf0b05047f027e037f017e037f230041e0016b2204240002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d03200241246a2802002105200241346a280200210602400240024002400240200241146a2802002203450d0020022802042107200441306a200128021029034842002003ad420010a00520012802182202420020022903082208427f200429033020042903384200521b7d22092009200856220a1b37030841052102200a0d0e2003417f4c0d092003102d220a450d0a024020012802142802082007200a2003102141026a220741024b0d0020070e03040002040b41ece7c500106d000b4101210b410021074100210c0c010b2004200336028c012004200a36028801200441c0006a20044188016a1031200429024421082004280240210b200a1029200b450d0c2008a7210c200128021028025c2008422088a72207490d0b0b200b2007410041202007676b10cf01024020074102490d00200b21022007210303402002200241206a220a4120109d05450d0c200a21022003417f6a220341024f0d000b0b200441206a200128021029034842002006ad220d420010a00520012802182202420020022903082208427f200429032020042903284200521b7d2209200920085622021b37030820020d0a2006417f4c0d060240024020060d004101210a02402001280214280208200541014100102141026a220241024b0d0020020e030d00020d0b41ece7c500106d000b024002402006102d220a450d00024020012802142802082005200a2006102141026a220241024b0d0020020e03020003020b41ece7c500106d000b20064101102e000b200a10290c0b0b20042001280210220329032842002007ad420010a005200441106a20032903204200200d420010a00520012802182102427f2109024020042903184200520d0020042903084200520d002004290310220820042903007c220d2008540d00427f200d20032903307c22082008200d541b21090b200242002002290308220820097d220920092008561b37030820092008580d012006450d0a200a10290c0a0b200a10290c0a0b200441b8016a41086a22052001280200280218220341d8006a290000370300200441b8016a41106a2201200341e0006a290000370300200441b8016a41186a220e200341e8006a290000370300200420032900503703b80102402003413c6a2802002202200341386a280200470d00200241016a220f2002490d0820024101742210200f200f2010491b2210ad42b0017e2208422088a70d082008a7220f4100480d080240024020020d00200f103221020c010b2003280234200241b0016c200f103421020b2002450d0720032002360234200341386a2010360200200328023c21020b2003280234200241b0016c6a220241003a0000200220042f00dd013b0001200241053a00102002200736000c2002200c3600082002200b360004200220042903b801370011200241036a200441dd016a41026a2d00003a0000200241196a2005290300370000200241216a2001290300370000200241296a200e2903003700002002200a360034200220063600382002200636003c200220042f00b5013b0031200241336a200441b5016a41026a2d00003a00002002200429038801370340200241c8006a20044188016a41086a290300370300200241d0006a20044188016a41106a290300370300200241d8006a20044188016a41186a290300370300200241e0006a200441a8016a290300370300200241e8006a200441c0006a41c800109b051a2003200328023c41016a36023c410421020c090b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b41929cc50041f403109201000b102f000b20034101102e000b200f4108102e000b1033000b41052102200c450d00200b10290b20002002360200200441e0016a24000b900a03027f027e057f230041e00b6b220424000240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200420012802102903484200200241146a2802002202ad420010a00520012802182203420020032903082206427f200429030020042903084200521b7d2207200720065622081b3703084105210320080d052002417f4c0d02024020020d0002402001280214280208200541014100102141026a220241024b0d0020020e03070007070b41ece7c500106d000b02400240024002402002102d2208450d0002402001280214280208200520082002102141026a220541024b0d0020050e03030002030b41ece7c500106d000b20024101102e000b2002410f4b0d010b200810290c060b200841086a29000021062008290000210720081029200128020028021822092802180d032009417f360218200441c8006a200941e8006a290000370300200441c0006a200941e0006a290000370300200441306a41086a200941d8006a29000037030020042009290050370330024002402009411c6a220a280200220841b0d6c000460d00200941206a280200210b0c010b4100210b20044180096a410041e002109a051a200441e0006a410041a008109a051a41880b10322208450d05200841003b010620084100360200200841086a20044180096a41e002109b051a200841e8026a200441e0006a41a008109b051a200941206a41003602002009200836021c0b02400240034020082f0106220c4105742105410021024100210102400240034020052002460d01200441306a200820026a41086a4120109d052203450d02200241206a2102200141016a21012003417f4a0d000b2001417f6a210c0b200b450d02200b417f6a210b2008200c4102746a41880b6a28020021080c010b0b200941246a2103410121020c010b200441106a41186a200441306a41186a290300370300200441106a41106a200441306a41106a290300370300200441106a41086a200441306a41086a29030037030020042004290330370310200941246a21034100210b200c2101410021020b0240024020020d002004419c096a200441106a41086a290300370200200441a4096a200441106a41106a290300370200200441ac096a200441106a41186a29030037020020042003360290092004200136028c092004200a3602880920042008360284092004200b36028009200420042903103702940920044180016a200429035037030020044188016a200441d0006a41086a29030037030020044194016a42003702002004420037037820044200370360200441b0d6c00036029001200441003a009c012004419d016a2004290030370000200441a5016a200441306a41086a290000370000200441ad016a200441306a41106a290000370000200441b5016a200441306a41186a290000370000200441003a00bd0120044180096a200441e0006a10c80121020c010b200441f8006a4200370300200441f4006a41b0d6c00036020020044100360280012004410036027020044200370368200441b0d6c000360264200441003602602008200141e0006c6a41e8026a2102200441e0006a10c9010b200241286a2006370300200241206a2007370300200242013703182009200928021841016a360218410421030c050b41929cc50041f403109201000b41929cc50041f403109201000b102f000b41e898c5004110200441e0006a41a099c5001054000b41880b4108102e000b20002003360200200441e00b6a24000ba30203037f027e027f230041206b220424002001410c6a22054100360200200441086a2001280200280218220641186a200641d0006a10a004200441086a41106a290300210720042802082106200429031021080240024002400240200141086a2802002209200528020022056b4110490d00200128020421090c010b200541106a220a2005490d0220094101742205200a200a2005491b22054100480d020240024020090d002005103221090c010b200128020420092005103421090b2009450d0120012009360204200141086a20053602002001410c6a28020021050b2001410c6a200541106a360200200920056a22012007427f20061b37000820012008427f20061b37000020004104360200200441206a24000f0b20054101102e000b1033000bf10203027f027e017f230041206b220424000240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200420012802102903484200200241146a2802002202ad420010a00520012802182203420020032903082206427f200429030020042903084200521b7d2207200720065622081b37030841052103024020080d002002417f4c0d0302400240024020020d004101210802402001280214280208200541014100102141026a220141024b0d0020010e03040002040b41ece7c500106d000b02402002102d2208450d0002402001280214280208200520082002102141026a220141024b0d0020010e03030002030b41ece7c500106d000b20024101102e000b200441106a20082002108204024020042802100d002004280214200441186a28020010090b410421032002450d010b200810290b20002003360200200441206a24000f0b41929cc50041f403109201000b41929cc50041f403109201000b102f000bbe0101037f410021042001410c6a4100360200200128020028021c21050240024002400240200141086a28020022064104490d00200128020421060c010b200641017422044104200441044b1b22044100480d020240024020060d002004103221060c010b200128020420062004103421060b2006450d0120012006360204200141086a20043602002001410c6a28020021040b2001410c6a200441046a360200200620046a2005360000200041043602000f0b20044101102e000b1033000bc205020a7f017e230041c0006b220424002004200136020c20042000410120011b3602082004200441086a102c024020042802000d000240024002400240024002400240200428020c22014170712200417f4c0d002004280204210502400240200141047622060d00410821070c010b200010322207450d020b02402005450d00200441206a4104722108410021094100210a410021000340200441206a200441086a10e902200441306a41086a220b200841086a2802003602002004200829020037033002402004280220220c4104470d002006450d0a200710290c0a0b200041016a2101200441106a41086a220d200b28020036020020042004290330370310024020002006470d002009200120012009491b220641ffffffff00712006470d062006410474220b4100480d060240024020000d00200b103221070c010b2007200a200b103421070b2007450d050b2007200a6a2200200c360200200041046a20042903103702002000410c6a200d280200360200200941026a2109200a41106a210a2001210020052001470d000b0b2007450d07200441206a200220072005200311050020042802202100410110322201450d042004428180808010370234200420013602300240024020004105460d00200141003a000020014101410210342101024020004104470d002001450d08200141003a00012004428280808020370234200420013602304202210e0c020b2001450d08200141013a0001200442828080802037023420042001360230200441206a200441306a10fd022004350238210e200428023021010c010b200141013a00004201210e0b2001ad422086200e84210e02402006450d00200710290b200441c0006a2400200e0f0b102f000b20004108102e000b200b4108102e000b1033000b41014101102e000b41024101102e000b41024101102e000b41d1dbc20041f000200441206a41c4dcc2001054000bde0202047f017e02400240024002400240024020012802042202450d00200128020022032d0000210420012002417f6a22053602042001200341016a3602002004417f6a220441034b0d0520040e0401020304010b200041043602000f0b0240200541034b0d00200041043602000f0b200041003602002003280001210420012002417b6a3602042001200341056a360200200020043602040f0b024020054108490d0020004101360200200329000121062001200241776a3602042001200341096a360200200041086a20063703000f0b200041043602000f0b0240200541034b0d00200041043602000f0b200041023602002003280001210420012002417b6a3602042001200341056a360200200020043602040f0b024020054108490d0020004103360200200329000121062001200241776a3602042001200341096a360200200041086a20063703000f0b200041043602000f0b200041043602000b9c8c0103047f027e037f230041106b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002d00000e10000102030405060708090a0b0c0d0e0f000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5c20034101742205200420042005491b22054100480d5c0240024020030d002005103221040c010b200128020020032005103421040b2004450d1120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200141046a280200210420052802002103024020002d00014101460d000240024020042003460d00200128020021000c010b200341016a22002003490d5d20034101742204200020002004491b22044100480d5d0240024020030d002004103221000c010b200128020020032004103421000b2000450d1320012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41003a00000c100b0240024020042003460d00200128020021000c010b200341016a22002003490d5c20034101742204200020002004491b22044100480d5c0240024020030d002004103221000c010b200128020020032004103421000b2000450d1320012000360200200141046a2004360200200141086a28020021030b200141086a200341016a360200200020036a41013a00000c0f0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5b20034101742205200420042005491b22054100480d5b0240024020030d002005103221040c010b200128020020032005103421040b2004450d1320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5b20034101742205200420042005491b22054100480d5b0240024020030d002005103221040c010b200128020020032005103421040b2004450d1420012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041086a20011081012000280204210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d5b20034101742200200520052000491b22004100480d5b0240024020030d002000103221030c010b200128020020032000103421030b2003450d1520012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c0e0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5a20034101742205200420042005491b22054100480d5a0240024020030d002005103221040c010b200128020020032005103421040b2004450d1520012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a000020002d0008220341024b0d0d02400240024020030e03000102000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5c20034101742205200420042005491b22054100480d5c0240024020030d002005103221040c010b200128020020032005103421040b2004450d1820012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041096a2001108101200041386a29030021062000290330210702400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5c20034101742200200420042000491b22004100480d5c0240024020030d002000103221030c010b200128020020032000103421030b2003450d1920012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012006370008200120073700000c0f0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5b20034101742205200420042005491b22054100480d5b0240024020030d002005103221040c010b200128020020032005103421040b2004450d1920012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041096a20011081010c0e0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5a20034101742205200420042005491b22054100480d5a0240024020030d002005103221040c010b200128020020032005103421040b2004450d1920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a0000200041096a2001108101200041296a2001108101200041d8006a29030021062000290350210702400240200141046a2802002204200528020022036b4110490d00200128020021040c010b200341106a22052003490d5a20044101742203200520052003491b22034100480d5a0240024020040d002003103221040c010b200128020020042003103421040b2004450d1a20012004360200200141046a2003360200200141086a28020021030b200141086a2205200341106a360200200420036a2203200637000820032007370000200041e8006a29030021062000290360210702400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5a20034101742200200420042000491b22004100480d5a0240024020030d002000103221030c010b200128020020032000103421030b2003450d1b20012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012006370008200120073700000c0d0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5920034101742205200420042005491b22054100480d590240024020030d002005103221040c010b200128020020032005103421040b2004450d1b20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a000020002d0008220341024b0d0c02400240024020030e03000102000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5b20034101742205200420042005491b22054100480d5b0240024020030d002005103221040c010b200128020020032005103421040b2004450d1e20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041186a29030021062000290310210702400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5b20034101742200200420042000491b22004100480d5b0240024020030d002000103221030c010b200128020020032000103421030b2003450d1f20012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012006370008200120073700000c0e0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5a20034101742205200420042005491b22054100480d5a0240024020030d002005103221040c010b200128020020032005103421040b2004450d1f20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200041096a2001108101200041386a29030021062000290330210702400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5a20034101742200200420042000491b22004100480d5a0240024020030d002000103221030c010b200128020020032000103421030b2003450d2020012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012006370008200120073700000c0d0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5920034101742205200420042005491b22054100480d590240024020030d002005103221040c010b200128020020032005103421040b2004450d2020012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a0000200028020c210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d5920034101742200200520052000491b22004100480d590240024020030d002000103221030c010b200128020020032000103421030b2003450d2120012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c0c0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5820034101742205200420042005491b22054100480d580240024020030d002005103221040c010b200128020020032005103421040b2004450d2120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5820034101742205200420042005491b22054100480d580240024020030d002005103221040c010b200128020020032005103421040b2004450d2220012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a00002000280204210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d5820034101742200200520052000491b22004100480d580240024020030d002000103221030c010b200128020020032000103421030b2003450d2320012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c0b0b02400240200141046a2208280200200141086a22042802002203460d00200128020021050c010b200341016a22052003490d5720034101742209200520052009491b22094100480d570240024020030d002009103221050c010b200128020020032009103421050b2005450d2320012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41053a000020002d00082203410a4b0d0a0240024002400240024002400240024002400240024020030e0b000102030405060708090a000b02400240200828020020042802002203460d00200128020021050c010b200341016a22052003490d6120034101742209200520052009491b22094100480d610240024020030d002009103221050c010b200128020020032009103421050b2005450d2e20012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41003a0000200028020c21090240024020082802002205200428020022036b4104490d00200128020021050c010b200341046a220a2003490d6120054101742203200a200a2003491b22034100480d610240024020050d002003103221050c010b200128020020052003103421050b2005450d2f20012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a2009360000200041186a2903002106200029031021070240024020082802002203200428020022006b4110490d00200128020021030c010b200041106a22052000490d6120034101742200200520052000491b22004100480d610240024020030d002000103221030c010b200128020020032000103421030b2003450d3020012003360200200141046a2000360200200141086a28020021000b2004200041106a360200200320006a22012006370008200120073700000c140b02400240200828020020042802002203460d00200128020021050c010b200341016a22052003490d6020034101742209200520052009491b22094100480d600240024020030d002009103221050c010b200128020020032009103421050b2005450d3020012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41013a0000200028020c21090240024020082802002205200428020022036b4104490d00200128020021050c010b200341046a220a2003490d6020054101742203200a200a2003491b22034100480d600240024020050d002003103221050c010b200128020020052003103421050b2005450d3120012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a2009360000200041286a2903002106200029032021070240024020082802002205200428020022036b4110490d00200128020021040c010b200341106a22042003490d6020054101742203200420042003491b22034100480d600240024020050d002003103221040c010b200128020020052003103421040b2004450d3220012004360200200141046a2003360200200141086a28020021030b200141086a200341106a360200200420036a22032006370008200320073700002000280210200041186a28020020011094010c130b02400240200828020020042802002200460d00200128020021030c010b200041016a22032000490d5f20004101742205200320032005491b22054100480d5f0240024020000d002005103221030c010b200128020020002005103421030b2003450d3220012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41023a00000c120b02400240200828020020042802002203460d00200128020021050c010b200341016a22052003490d5e20034101742209200520052009491b22094100480d5e0240024020030d002009103221050c010b200128020020032009103421050b2005450d3220012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41033a0000200028020c21090240024020082802002205200428020022036b4104490d00200128020021050c010b200341046a220a2003490d5e20054101742203200a200a2003491b22034100480d5e0240024020050d002003103221050c010b200128020020052003103421050b2005450d3320012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a200936000020002d0009220041024b0d1102400240024020000e03000102000b02400240200828020020042802002200460d00200128020021030c010b200041016a22032000490d6020004101742205200320032005491b22054100480d600240024020000d002005103221030c010b200128020020002005103421030b2003450d3620012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41003a00000c130b02400240200828020020042802002200460d00200128020021030c010b200041016a22032000490d5f20004101742205200320032005491b22054100480d5f0240024020000d002005103221030c010b200128020020002005103421030b2003450d3620012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41013a00000c120b02400240200828020020042802002200460d00200128020021030c010b200041016a22032000490d5e20004101742205200320032005491b22054100480d5e0240024020000d002005103221030c010b200128020020002005103421030b2003450d3620012003360200200141046a2005360200200141086a28020021000b2004200041016a360200200320006a41023a00000c110b02400240200828020020042802002203460d00200128020021050c010b200341016a22052003490d5d20034101742209200520052009491b22094100480d5d0240024020030d002009103221050c010b200128020020032009103421050b2005450d3620012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41043a0000200028020c21050240024020082802002203200428020022006b4104490d00200128020021030c010b200041046a22082000490d5d20034101742200200820082000491b22004100480d5d0240024020030d002000103221030c010b200128020020032000103421030b2003450d3720012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000c100b02400240200828020020042802002203460d00200128020021050c010b200341016a22052003490d5c20034101742209200520052009491b22094100480d5c0240024020030d002009103221050c010b200128020020032009103421050b2005450d3720012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41053a0000200028020c21050240024020082802002203200428020022006b4104490d00200128020021030c010b200041046a22082000490d5c20034101742200200820082000491b22004100480d5c0240024020030d002000103221030c010b200128020020032000103421030b2003450d3820012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000c0f0b02400240200828020020042802002203460d00200128020021050c010b200341016a22052003490d5b20034101742209200520052009491b22094100480d5b0240024020030d002009103221050c010b200128020020032009103421050b2005450d3820012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41063a0000200028020c21050240024020082802002203200428020022006b4104490d00200128020021030c010b200041046a22082000490d5b20034101742200200820082000491b22004100480d5b0240024020030d002000103221030c010b200128020020032000103421030b2003450d3920012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000c0e0b02400240200828020020042802002203460d00200128020021050c010b200341016a22052003490d5a20034101742209200520052009491b22094100480d5a0240024020030d002009103221050c010b200128020020032009103421050b2005450d3920012005360200200141046a2009360200200141086a28020021030b2004200341016a360200200520036a41073a0000200028020c21090240024020082802002205200428020022036b4104490d00200128020021050c010b200341046a220a2003490d5a20054101742203200a200a2003491b22034100480d5a0240024020050d002003103221050c010b200128020020052003103421050b2005450d3a20012005360200200141046a2003360200200141086a28020021030b2004200341046a360200200520036a200936000002400240200828020020042802002203460d00200128020021050c010b200341016a22052003490d5a20034101742208200520052008491b22084100480d5a0240024020030d002008103221050c010b200128020020032008103421050b2005450d3b20012005360200200141046a2008360200200141086a28020021030b2004200341016a360200200520036a20002d00093a00000c0d0b02400240200828020020042802002203460d00200128020021040c010b200341016a22042003490d5920034101742205200420042005491b22054100480d590240024020030d002005103221040c010b200128020020032005103421040b2004450d3b20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41083a0000200041096a2001108101200041296a20011081010c0c0b02400240200828020020042802002203460d00200128020021040c010b200341016a22042003490d5820034101742205200420042005491b22054100480d580240024020030d002005103221040c010b200128020020032005103421040b2004450d3b20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a0000200041096a20011081010c0b0b02400240200828020020042802002203460d00200128020021050c010b200341016a22052003490d5720034101742208200520052008491b22084100480d570240024020030d002008103221050c010b200128020020032008103421050b2005450d3b20012005360200200141046a2008360200200141086a28020021030b200141086a2208200341016a360200200520036a410a3a0000200041096a200110810120022001360208200041296a200241086a108501200028024c210502400240200141046a2802002203200828020022006b4104490d00200128020021030c010b200041046a22082000490d5720034101742200200820082000491b22004100480d570240024020030d002000103221030c010b200128020020032000103421030b2003450d3c20012003360200200141046a2000360200200141086a28020021000b2004200041046a360200200320006a20053600000c0a0b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5620034101742205200420042005491b22054100480d560240024020030d002005103221040c010b200128020020032005103421040b2004450d3c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41063a0000200041046a200110eb020c090b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5520034101742205200420042005491b22054100480d550240024020030d002005103221040c010b200128020020032005103421040b2004450d3c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41073a0000200041046a200110eb020c080b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5420034101742205200420042005491b22054100480d540240024020030d002005103221040c010b200128020020032005103421040b2004450d3c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41083a0000024002400240024020002d00040e0400010203000b02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5720034101742205200420042005491b22054100480d570240024020030d002005103221040c010b200128020020032005103421040b2004450d4020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a0000200041056a2001108101200041256a20011081010c0a0b02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5620034101742205200420042005491b22054100480d560240024020030d002005103221040c010b200128020020032005103421040b2004450d4020012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041056a20011081010c090b02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5520034101742205200420042005491b22054100480d550240024020030d002005103221040c010b200128020020032005103421040b2004450d4020012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a00002000280208210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d5520034101742200200520052000491b22004100480d550240024020030d002000103221030c010b200128020020032000103421030b2003450d4120012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c080b02400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d5420034101742205200420042005491b22054100480d540240024020030d002005103221040c010b200128020020032005103421040b2004450d4120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a00002000280208200041106a280200200110940120002802142000411c6a28020020011094010c070b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5320034101742205200420042005491b22054100480d530240024020030d002005103221040c010b200128020020032005103421040b2004450d4120012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41093a000020002d0001220041044b0d060240024002400240024020000e050001020304000b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d5720004101742204200320032004491b22044100480d570240024020000d002004103221030c010b200128020020002004103421030b2003450d4620012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41003a00000c0a0b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d5620004101742204200320032004491b22044100480d560240024020000d002004103221030c010b200128020020002004103421030b2003450d4620012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41013a00000c090b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d5520004101742204200320032004491b22044100480d550240024020000d002004103221030c010b200128020020002004103421030b2003450d4620012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41023a00000c080b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d5420004101742204200320032004491b22044100480d540240024020000d002004103221030c010b200128020020002004103421030b2003450d4620012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41033a00000c070b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d5320004101742204200320032004491b22044100480d530240024020000d002004103221030c010b200128020020002004103421030b2003450d4620012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41043a00000c060b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5220034101742205200420042005491b22054100480d520240024020030d002005103221040c010b200128020020032005103421040b2004450d4620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410a3a00002000280204220341024b0d0502400240024020030e03000102000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5420034101742205200420042005491b22054100480d540240024020030d002005103221040c010b200128020020032005103421040b2004450d4920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a000020002802082103200041106a2802002200200110662000450d072003200041286c6a210a200141046a210803402003200110ee01200341206a29030021060240024020082802002204200528020022006b4108490d00200128020021040c010b200041086a22092000490d5520044101742200200920092000491b22004100480d550240024020040d002000103221040c010b200128020020042000103421040b2004450d4b2001200436020020082000360200200528020021000b2005200041086a360200200420006a2006370000200a200341286a2203470d000c080b0b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d5320004101742204200320032004491b22044100480d530240024020000d002004103221030c010b200128020020002004103421030b2003450d4a20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41013a00000c060b02400240200141046a280200200141086a2802002200460d00200128020021030c010b200041016a22032000490d5220004101742204200320032004491b22044100480d520240024020000d002004103221030c010b200128020020002004103421030b2003450d4a20012003360200200141046a2004360200200141086a28020021000b200141086a200041016a360200200320006a41023a00000c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5120034101742205200420042005491b22054100480d510240024020030d002005103221040c010b200128020020032005103421040b2004450d4a20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410b3a000020002d0008220341044b0d040240024002400240024020030e050001020304000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5520034101742205200420042005491b22054100480d550240024020030d002005103221040c010b200128020020032005103421040b2004450d4f20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200028020c210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d5520034101742200200520052000491b22004100480d550240024020030d002000103221030c010b200128020020032000103421030b2003450d5020012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c080b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5420034101742205200420042005491b22054100480d540240024020030d002005103221040c010b200128020020032005103421040b2004450d5020012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200041186a29030021062000290310210702400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d5420034101742200200420042000491b22004100480d540240024020030d002000103221030c010b200128020020032000103421030b2003450d5120012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012006370008200120073700000c070b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d5320034101742205200420042005491b22054100480d530240024020030d002005103221040c010b200128020020032005103421040b2004450d5120012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41023a0000200028022c210802400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490d5320044101742203200520052003491b22034100480d530240024020040d002003103221040c010b200128020020042003103421040b2004450d5220012004360200200141046a2003360200200141086a28020021030b200141086a2205200341046a360200200420036a2008360000200041386a29030021062000290330210702400240200141046a2802002204200528020022036b4110490d00200128020021040c010b200341106a22052003490d6d20044101742203200520052003491b22034100480d6d0240024020040d002003103221040c010b200128020020042003103421040b2004450d5420012004360200200141046a2003360200200141086a28020021030b200141086a200341106a360200200420036a2203200637000820032007370000200041096a20011081010c060b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6c20034101742205200420042005491b22054100480d6c0240024020030d002005103221040c010b200128020020032005103421040b2004450d5420012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a0000200041186a29030021062000290310210702400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d6c20034101742200200420042000491b22004100480d6c0240024020030d002000103221030c010b200128020020032000103421030b2003450d5520012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012006370008200120073700000c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6b20034101742205200420042005491b22054100480d6b0240024020030d002005103221040c010b200128020020032005103421040b2004450d5520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a0000200041186a29030021062000290310210702400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d6b20034101742200200420042000491b22004100480d6b0240024020030d002000103221030c010b200128020020032000103421030b2003450d5620012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012006370008200120073700000c040b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6a20034101742205200420042005491b22054100480d6a0240024020030d002005103221040c010b200128020020032005103421040b2004450d5620012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a410c3a000020002d0008220341054b0d0302400240024002400240024020030e06000102030405000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6f20034101742205200420042005491b22054100480d6f0240024020030d002005103221040c010b200128020020032005103421040b2004450d5c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041096a2001108101200041296a2001108101200041d8006a29030021062000290350210702400240200141046a2802002203200528020022006b4110490d00200128020021030c010b200041106a22042000490d6f20034101742200200420042000491b22004100480d6f0240024020030d002000103221030c010b200128020020032000103421030b2003450d5d20012003360200200141046a2000360200200141086a28020021000b200141086a200041106a360200200320006a22012006370008200120073700000c080b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6e20034101742205200420042005491b22054100480d6e0240024020030d002005103221040c010b200128020020032005103421040b2004450d5d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a0000200041096a2001108101200041296a20011081010c070b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6d20034101742205200420042005491b22054100480d6d0240024020030d002005103221040c010b200128020020032005103421040b2004450d5d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002002200136020c200041096a2002410c6a1085010c060b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6c20034101742205200420042005491b22054100480d6c0240024020030d002005103221040c010b200128020020032005103421040b2004450d5d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41033a0000200028020c210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d6c20034101742200200520052000491b22004100480d6c0240024020030d002000103221030c010b200128020020032000103421030b2003450d5e20012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6b20034101742205200420042005491b22054100480d6b0240024020030d002005103221040c010b200128020020032005103421040b2004450d5e20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a0000200041096a200110810102400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d6b20034101742205200420042005491b22054100480d6b0240024020030d002005103221040c010b200128020020032005103421040b2004450d5f20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00293a00000c040b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6a20034101742205200420042005491b22054100480d6a0240024020030d002005103221040c010b200128020020032005103421040b2004450d5f20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41053a0000200041096a2001108101200028022c2108200041346a28020022002001106602400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490d6a20044101742203200520052003491b22034100480d6a0240024020040d002003103221040c010b200128020020042003103421040b2004450d6020012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a20082000109b051a0c030b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6920034101742205200420042005491b22054100480d690240024020030d002005103221040c010b200128020020032005103421040b2004450d6020012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410d3a0000200041026a2103024020002d00014101460d0002400240200141046a28020020052802002200460d00200128020021040c010b200041016a22042000490d6a20004101742205200420042005491b22054100480d6a0240024020000d002005103221040c010b200128020020002005103421040b2004450d6220012004360200200141046a2005360200200141086a28020021000b200141086a2205200041016a360200200420006a41003a000002400240200141046a28020020052802002200460d00200128020021040c010b200041016a22042000490d6a20004101742205200420042005491b22054100480d6a0240024020000d002005103221040c010b200128020020002005103421040b2004450d6320012004360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200420006a20032d00003a00000c030b02400240200141046a28020020052802002200460d00200128020021040c010b200041016a22042000490d6920004101742205200420042005491b22054100480d690240024020000d002005103221040c010b200128020020002005103421040b2004450d6320012004360200200141046a2005360200200141086a28020021000b200141086a200041016a360200200420006a41013a0000200320011081010c020b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6820034101742205200420042005491b22054100480d680240024020030d002005103221040c010b200128020020032005103421040b2004450d6320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410e3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d6820034101742205200420042005491b22054100480d680240024020030d002005103221040c010b200128020020032005103421040b2004450d6420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41003a00002002200041016a360204200241046a2001108a010c010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d6720034101742205200420042005491b22054100480d670240024020030d002005103221040c010b200128020020032005103421040b2004450d6420012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a410f3a000002400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d6720034101742205200420042005491b22054100480d670240024020030d002005103221040c010b200128020020032005103421040b2004450d6520012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041106a200110ec02200028020421082000410c6a28020022002001106602400240200141046a2802002204200528020022036b2000490d00200128020021040c010b200320006a22052003490d6720044101742203200520052003491b22034100480d670240024020040d002003103221040c010b200128020020042003103421040b2004450d6620012004360200200141046a2003360200200141086a28020021030b200141086a200320006a360200200420036a20082000109b051a0b200241106a24000f0b20054101102e000b20044101102e000b20044101102e000b20054101102e000b20054101102e000b20004101102e000b20054101102e000b20054101102e000b20004101102e000b20054101102e000b20054101102e000b20034101102e000b20004101102e000b20054101102e000b20054101102e000b20004101102e000b20054101102e000b20004101102e000b20054101102e000b20004101102e000b20054101102e000b20054101102e000b20004101102e000b20094101102e000b20094101102e000b20034101102e000b20004101102e000b20094101102e000b20034101102e000b20034101102e000b20054101102e000b20094101102e000b20034101102e000b20054101102e000b20054101102e000b20054101102e000b20094101102e000b20004101102e000b20094101102e000b20004101102e000b20094101102e000b20004101102e000b20094101102e000b20034101102e000b20084101102e000b20054101102e000b20054101102e000b20084101102e000b20004101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20004101102e000b20054101102e000b20054101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20054101102e000b20054101102e000b20004101102e000b20044101102e000b20044101102e000b20054101102e000b20054101102e000b20004101102e000b20054101102e000b20004101102e000b20054101102e000b20034101102e000b1033000b20034101102e000b20054101102e000b20004101102e000b20054101102e000b20004101102e000b20054101102e000b20054101102e000b20004101102e000b20054101102e000b20054101102e000b20054101102e000b20004101102e000b20054101102e000b20054101102e000b20054101102e000b20034101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20034101102e000b1033000bfd1201057f230041106b2202240002400240024002400240024002400240024002400240024002400240024020002d0000220341054b0d0002400240024002400240024020030e06000102030405000b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d1420034101742205200420042005491b22054100480d140240024020030d002005103221040c010b200128020020032005103421040b2004450d0720012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a0000200041016a20011081012000280244210602400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490d1420044101742203200520052003491b22034100480d140240024020040d002003103221040c010b200128020020042003103421040b2004450d0820012004360200200141046a2003360200200141086a28020021030b200141086a2205200341046a360200200420036a20063600002002200136020c200041216a2002410c6a1085012000280248210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d1420034101742200200520052000491b22004100480d140240024020030d002000103221030c010b200128020020032000103421030b2003450d0920012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c050b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d1320034101742205200420042005491b22054100480d130240024020030d002005103221040c010b200128020020032005103421040b2004450d0920012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41013a0000200041016a20011081012002200136020c200041216a2002410c6a10850102400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d1320034101742205200420042005491b22054100480d130240024020030d002005103221040c010b200128020020032005103421040b2004450d0a20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a20002d00413a00002000280244210602400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490d1320044101742203200520052003491b22034100480d130240024020040d002003103221040c010b200128020020042003103421040b2004450d0b20012004360200200141046a2003360200200141086a28020021030b200141086a2205200341046a360200200420036a20063600002000280248210402400240200141046a2802002203200528020022006b4104490d00200128020021030c010b200041046a22052000490d1320034101742200200520052000491b22004100480d130240024020030d002000103221030c010b200128020020032000103421030b2003450d0c20012003360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200320006a20043600000c040b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d1220034101742205200420042005491b22054100480d120240024020030d002005103221040c010b200128020020032005103421040b2004450d0c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41023a00002002200136020c200041016a2002410c6a1085010c030b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d1120034101742205200420042005491b22054100480d110240024020030d002005103221040c010b200128020020032005103421040b2004450d0c20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41033a00002002200136020c200041016a2002410c6a1085010c020b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d1020034101742205200420042005491b22054100480d100240024020030d002005103221040c010b200128020020032005103421040b2004450d0c20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41043a00002002200136020c200041016a2002410c6a10850102400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d1020034101742205200420042005491b22054100480d100240024020030d002005103221040c010b200128020020032005103421040b2004450d0d20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00213a00000c010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d0f20034101742205200420042005491b22054100480d0f0240024020030d002005103221040c010b200128020020032005103421040b2004450d0d20012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41053a00002002200136020c200041016a2002410c6a10850102400240200141046a28020020052802002203460d00200128020021040c010b200341016a22042003490d0f20034101742205200420042005491b22054100480d0f0240024020030d002005103221040c010b200128020020032005103421040b2004450d0e20012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a20002d00213a00000b200241106a24000f0b20054101102e000b20034101102e000b20004101102e000b20054101102e000b20054101102e000b20034101102e000b20004101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b1033000b8c1501037f0240024002400240024002400240024002400240024002400240024002400240024002400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d1120024101742204200320032004491b22044100480d110240024020020d002004103221030c010b200128020020022004103421030b2003450d0120012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00003a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1120024101742204200320032004491b22044100480d110240024020020d002004103221030c010b200128020020022004103421030b2003450d0220012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00013a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1120024101742204200320032004491b22044100480d110240024020020d002004103221030c010b200128020020022004103421030b2003450d0320012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00023a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1120024101742204200320032004491b22044100480d110240024020020d002004103221030c010b200128020020022004103421030b2003450d0420012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00033a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1120024101742204200320032004491b22044100480d110240024020020d002004103221030c010b200128020020022004103421030b2003450d0520012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00043a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1120024101742204200320032004491b22044100480d110240024020020d002004103221030c010b200128020020022004103421030b2003450d0620012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00053a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1120024101742204200320032004491b22044100480d110240024020020d002004103221030c010b200128020020022004103421030b2003450d0720012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00063a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1120024101742204200320032004491b22044100480d110240024020020d002004103221030c010b200128020020022004103421030b2003450d0820012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00073a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1120024101742204200320032004491b22044100480d110240024020020d002004103221030c010b200128020020022004103421030b2003450d0920012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00083a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1120024101742204200320032004491b22044100480d110240024020020d002004103221030c010b200128020020022004103421030b2003450d0a20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d00093a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1120024101742204200320032004491b22044100480d110240024020020d002004103221030c010b200128020020022004103421030b2003450d0b20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d000a3a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1120024101742204200320032004491b22044100480d110240024020020d002004103221030c010b200128020020022004103421030b2003450d0c20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d000b3a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1120024101742204200320032004491b22044100480d110240024020020d002004103221030c010b200128020020022004103421030b2003450d0d20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d000c3a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1120024101742204200320032004491b22044100480d110240024020020d002004103221030c010b200128020020022004103421030b2003450d0e20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d000d3a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1120024101742204200320032004491b22044100480d110240024020020d002004103221030c010b200128020020022004103421030b2003450d0f20012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a20002d000e3a000002400240200141046a28020020042802002202460d00200128020021030c010b200241016a22032002490d1120024101742204200320032004491b22044100480d110240024020020d002004103221030c010b200128020020022004103421030b2003450d1020012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20002d000f3a00000f0b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b1033000bcd0501027f4190ce002102410121030240024002400240024002400240024002400240024002400240024002400240024020012d00000e15001010100e010203040506090b0e0e0c0e0d0e0e0e000b417f2102200141086a280200417f6a220141054b0d0d4101210320010e060f0d090709090f0b41002103200141086a280200417f6a220141024b0d0d41c0843d2102024020010e030f000f0f0b41d086032102410121030c0e0b41002103200141086a2d0000417f6a2201410c4b0d0c41a0c21e210202400240024020010e0d101000000101101001020a0a0a100b4180b51821020c0f0b41b0e32d21020c0e0b41f093092102410121030c0d0b4100210341f0930921020c0c0b41002103200141086a2d0000417f6a220141104b0d0a41c096b10221020240024002400240024020010e11101000000110101002020a0a0303030404100b41c09a0c21020c0f0b41a0c21e2102410121030c0e0b41c09a0c21020c0d0b41a08d0621020c0c0b41a0c21e21020c0b0b200141046a2d0000417f6a220141034b0d0841a08d0621024101210320010e040a0a01020a0b200141046a2d0000417f6a220141034b0d0741a08d0621024101210320010e0409090001090b41c096b1022102410121030c080b41c09a0c2102410121030c070b41002103200141086a280200417f6a220141094b0d0541a0cb980121020240024020010e0a08080800080102020202080b41d0a5cc0021020c070b4180ade20421020c060b4190ce002102410121030c050b41d086034190ce00200141046a2d0000411d7441808080807e6a411d75417f4a1b2102410021030c040b41002103200141086a280200417f6a220141024b0d0241a0c21e2102024020010e03040000040b41a08d062102410121030c030b41012103200141046a280200417f6a220141014b0d0041c0843d210220010e020200020b410021030b4190ce0021020b200020033a0004200020023602000bf7e10108017f017e0f7f027e057f037e0d7f027e23004180096b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e15000102032321201f1e1d1c1b100f0c0b0a09080706000b200141106a29030021042001410c6a280200210520022d0001210620022d000021020240024002400240024002400240024002400240200141086a28020022070e0700010203040607000b20034184086a4101360200200342013702f4072003418c9ac5003602f0072003410536029407200341c09ac50036029007200320034190076a36028008200341f0076a41a4c5c300107d000b4100210841f8f8c2004100200220067241ff01711b21094128210a4101210b0c370b2004a7210702400240200241ff01710d004101210b200641ff01714101460d010b41a0f9c2002109412a210a4101210b410021082007450d370c360b20070d020c320b4128210a4101210b0240200220067241ff0171450d0041f8f8c2002109410021080c360b410810322202450d0a2002200437000041b4c5c300410a200241081005200210294100210841012106410121074101210c4101210d4101210e4101210f41012110410121110c120b2004a721070240200220067241ff0171450d0041f8f8c20021094128210a4101210b4100210820070d340c350b41bec5c300410520052004422088a710054101210b2007450d300b200510290c2f0b2004422088a721092004a7210a0240200220067241ff0171450d0002402009450d00200941186c21082005210203400240200241046a280200450d00200228020010290b0240200241106a280200450d002002410c6a28020010290b200241186a2102200841686a22080d000b0b41f8f8c20021094101211241002113200a0d020c2e0b0240200941186c2202450d00200520026a21082005210203402002280200200241086a2802002002410c6a280200200241146a2802001005200241186a22022008470d000b0b02402009450d00200941186c21082005210203400240200241046a280200450d00200228020010290b0240200241106a280200450d002002410c6a28020010290b200241186a2102200841686a22080d000b0b41012112200a450d2c200510290c2c0b2004422088a721092004a7210a200220067241ff0171450d0102402009450d002009410c6c21082005210203400240200241046a280200450d00200228020010290b2002410c6a2102200841746a22080d000b0b41f8f8c20021094100211241012113200a450d2c0b200510290c2b0b02402009410c6c2202450d00200520026a21082005210203402002280200200241086a28020010042002410c6a22022008470d000b0b02402009450d002009410c6c21082005210203400240200241046a280200450d00200228020010290b2002410c6a2102200841746a22080d000b0b41012113200a450d28200510290c280b41f8f8c20021094128210a4101210820022d000120022d0000720d26024020012d0001220241ff01714102470d0041fbefc500412010f1011a410021094101210b0c2f0b41012108200320024101713a00f007200341c8056a41086a22024200370300200342003703c80541fbefc5004120200341c8056a1003200341c8046a41086a2002290300370300200320032903c8053703c804200341c8046a4110200341f0076a41011005410021094101210b0c2e0b41d4f8c20021094124210a4101210820022d00000d2520022d000141ff01714102470d25200141086a2903002104200341c8056a41086a22024200370300200342003703c80541ddf4c5004113200341c8056a1003200341c8046a41086a2002290300370300200320032903c8053703c804200341c8046a41104101410041001007417f470d01200341186a41cc83c300410d10d501024002402003290320500d002003280218450d00200341086a41cc83c300410d10d501200329031042dc0b7c42dc0b20032802081b2004560d010b200341c8056a41086a22024200370300200342003703c80541cc83c300410d200341c8056a1003200341c8046a41086a22062002290300370300200320032903c8053703c804200320043703f007200341c8046a4110200341f0076a4108100541012108200341013a00f00720024200370300200342003703c80541ddf4c5004113200341c8056a100320062002290300370300200320032903c8053703c804200341c8046a4110200341f0076a41011005410021094101210b0c2e0b41dcfdc200106d000b2001410c6a2802002106200141086a2802002105200141046a280200211041d4f8c20021094124210a20022d00000d2320022d000141ff01714102470d23200341c8056a41086a22024200370300200342003703c80541b6aec5004117200341c8056a1003200341c8046a41086a2002290300370300200320032903c8053703c804200341003602f007200341c8046a4110200341f0076a10062102024002400240024020032802f0072208417f460d002002450d002008450d0120022d000021082002102920084102460d002008410171450d00419ef6c2002109411c210a0c270b200341013a00f007200341c8056a41086a22024200370300200342003703c80541b6aec5004117200341c8056a1003200341c8046a41086a22082002290300370300200320032903c8053703c804200341c8046a4110200341f0076a41011005200341306a41d983c300410d105d200328023421072003280230210920024200370300200342003703c80541b6f0c2004111200341c8056a100320082002290300370300200320032903c8053703c804200341003602f007200341c8046a4110200341f0076a1006210202400240024020032802f0072208417f460d002002450d00200320083602a403200320023602a003200341f0076a200341a0036a103e20032802f007220c450d0520032902f407210402402008450d00200210290b2003200c36028803024020044220882214a722022004a7470d00200341f0076a21080c020b200341f0076a21080c020b4104210c20034104360288034200210441002102200341f0076a21080b024020022004a7470d00200241016a220a2002490d122002410174220d200a200a200d491bad221442c4007e2215422088a70d122015a7220a4100480d120240024020020d00200a1032210c0c010b200c200241c4006c200a1034210c0b200c450d032003200c3602880320044280808080708320148421040b20044220882214a721020b200c200241c4006c6a22022007410020091b360204200241003a000020022008290200370208200241106a200841086a290200370200200241186a200841106a290200370200200241206a200841186a290200370200200241286a200841206a290200370200200241306a200841286a290200370200200241386a200841306a290200370200200241c0006a200841386a2802003602002014422086200442ffffffff0f83844280808080107c21042010200641f0006c6a210d024020060d00201021070c250b20034190076a417f6a210e200341c3056a211320034187066a2112200341cb066a210b200341f0076a41106a2116200341f0076a41086a2117200341a8066a41186a211820102107024003402007280204210220072802002108200341f0076a200741086a41e800109b051a200741f0006a21072002450d26200341a0036a200341f0076a41e800109b051a200320023602f407200320083602f0072017200341a0036a41e800109b051a200341286a41d983c300410d105d20032802282108200328022c210620034190076a200341f0076a10ef0202400240024020032802f00722020d0041d0f6c20021094110210a0c010b024020022006410020081b22084d0d00411a210a41e0f6c20021090c010b200341a8066a2002417f6a10aa020240200341a8066a20164120109d05450d004119210a41faf6c20021090c010b024020032802f007220941002008417b6a2202200220084b1b4f0d004126210a4193f7c20021090c010b200c20044220882214a7220f41c4006c22116a2106200c210202400240201141cd01490d00200c21020340024020022d00004101470d00200241016a2108200e2002460d03200820034190076a4120109d05450d030b0240200241c4006a2d00004101470d00200241c5006a2108200b2002460d03200820034190076a4120109d05450d030b024020024188016a2d00004101470d0020024189016a210820122002460d03200820034190076a4120109d05450d030b0240200241cc016a2d00004101470d00200241cd016a210820132002460d03200820034190076a4120109d05450d030b200620024190026a22026b41cc014b0d000b0b024020022006460d000340024020022d00004101470d00200241016a2108200e2002460d03200820034190076a4120109d05450d030b2006200241c4006a2202470d000b0b410021080b200341a8066a200910aa02200341a8066a20034190076a4120109d052102200341c8046a41086a2206200341c8056a41086a290300370300200341c8046a41106a200341c8056a41106a290300370300200320032903c8053703c80441baf6c20021094116210a20080d2720020d010c270b200341c8046a41086a200341c8056a41086a290300370300200341c8046a41106a200341c8056a41106a290300370300200320032903c8053703c8040c260b200341a8056a410e6a2209200341c8046a410e6a290100370100200341a8056a41086a220a2006290300370300200320032903c8043703a80520034190076a200341f0076a10ef0220184200370300200341a8066a41106a22064200370300200341a8066a41086a22084200370300200342003703a806024041c80010322202450d00200341a8046a10b5012002410236022020024101360244200241186a200341a8046a41186a290300370200200241106a200341a8046a41106a290300370200200241086a200341a8046a41086a290300370200200220032903a804370200200220032903a8063700242002412c6a2008290300370000200241346a20062903003700002002413c6a2018290300370000200320023602c80520034282808080203702cc05200341c8056a10f00220034188046a41086a220620034190076a41086a29030037030020034188046a41106a221920034190076a41106a29030037030020034188046a41186a221a20034190076a41186a2903003703002008200a290300370300200341a8066a410e6a220a2009290100370100200320032903900737038804200320032903a8053703a80602400240200f2004a7460d00200421150c010b200f41016a2202200f490d142014a74101742209200220022009491bad221542c4007e2214422088a70d142014a722094100480d1402400240200f0d002009103221020c010b200c20112009103421020b2002450d03200320023602880320044220882214a7210f0b200328028803220c200f41c4006c6a220241013a0000201a29030021042019290300211b2006290300211c200329038804211d20024116360028200241baf6c200360024200241003a00212002413a6a200a290100370000200241346a2008290300370000200220032903a80637002c2002201d370001200241096a201c370000200241116a201b370000200241196a2004370000201542ffffffff0f83210420144220862114024020032802fc072208450d0020032802f4072102200841246c210803400240024020022d0000220641034b0d0002400240024020060e0404000102040b2002410c6a280200450d03200241086a28020010290c030b2002410c6a280200450d02200241086a28020010290c020b2002410c6a280200450d01200241086a28020010290c010b200241086a280200450d00200241046a28020010290b200241246a21022008415c6a22080d000b0b20142004842104024020032802f807450d0020032802f40710290b20044280808080107c21042007200d470d010c280b0b41c8004104102e000b20094104102e000b41f7cdc3004133200341f8086a41ecd6c3001054000b200a4104102e000b41f7cdc3004133200341f8086a41ecd6c3001054000b4194fdc200106d000b41084101102e000b10f102000b10f201000b4124210a200141246a280200210b200141206a28020021192001411c6a280200210f200141186a2802002111200141146a2802002110200141106a28020021052001410c6a2802002118200141086a280200211a200141046a280200210620022d0001210820022d00002102200341a0036a41386a200141e0006a290000370300200341a0036a41306a200141d8006a290000370300200341a0036a41286a200141d0006a290000370300200341a0036a41206a200141c8006a290000370300200341a0036a41186a200141c0006a290000370300200341a0036a41106a200141386a290000370300200341a0036a41086a200141306a2900003703002003200141286a2900003703a00341d4f8c20021090240024020020d00200841ff01714102470d0020034180036a41d4f1c5004114105d41e893c1002109411c210a20032802840341002003280280031b2019470d00200341f0076a201910d9012003200b3602a806200341a8046a41186a22024200370300200341a8046a41106a22084200370300200341a8046a41086a22074200370300200342003703a804200341a8066a4104200341a8046a100020034188046a41186a200229030037030020034188046a41106a200829030037030020034188046a41086a2007290300370300200320032903a80437038804024002400240024002400240024002400240024020032802f407220720032802f80722086b4120490d00200841206a210920032802f00721020c010b200841206a22092008490d1320074101742202200920092002491b220c4100480d130240024020070d00200c103221020c010b20032802f0072007200c103421020b2002450d012003200c3602f407200320023602f007200c21070b200220086a2208200329038804370000200841186a20034188046a41186a290300370000200841106a20034188046a41106a290300370000200841086a20034188046a41086a2903003700004100211341012112200220094101410041001007210802402007450d00200210290b200341c8056a41086a22024200370300200342003703c80541e883c100410d200341c8056a1003200341c8046a41086a2002290300370300200320032903c8053703c804200341f0076a200341c8046a10f2020240024020032802f00722070d00410021020c010b200341f8076a280200210220032802f4072113200721120b2008417f470d062012200b4105746a41002002200b4b1b2217450d06200341003602f807200342013703f007410410322202450d0120034284808080c0003702f407200320023602f007200220063600002005200341f0076a10660240024020032802f407220820032802f80722026b2005490d0020032802f00721080c010b200220056a22062002490d1320084101742207200620062007491b22064100480d130240024020080d002006103221080c010b20032802f00720082006103421080b2008450d03200320063602f407200320083602f0070b2003200220056a3602f807200820026a201a2005109b051a200f200341f0076a10662010200f410c6c6a210e200f450d032010210803402008280200210c200841086a2802002202200341f0076a10660240024020032802f407220720032802f80722066b2002490d0020032802f00721090c010b200620026a22092006490d142007410174220d20092009200d491b220d4100480d140240024020070d00200d103221090c010b20032802f0072007200d103421090b2009450d062003200d3602f407200320093602f007200d21070b2003200620026a220d3602f807200920066a200c2002109b051a2008410c6a2208200e470d000c060b0b200c4101102e000b41044101102e000b20064101102e000b20032802f407210720032802f807210d0c010b200d4101102e000b024002400240024002400240024002402007200d6b4104490d00200d41046a210820032802f00721020c010b200d41046a2208200d490d1320074101742202200820082002491b22064100480d130240024020070d002006103221020c010b20032802f00720072006103421020b2002450d01200320063602f407200320023602f007200621070b200320083602f8072002200d6a201936000002400240200720086b41034d0d00200721060c010b200841046a22062008490d1320074101742209200620062009491b22064100480d130240024020070d002006103221020c010b200220072006103421020b2002450d02200320063602f407200320023602f0070b200220086a200b3600002002200841046a200341a0036a20171011210802402006450d00200210290b024020080d00200341f9076a201741086a29000037000020034181086a201741106a29000037000020034189086a201741186a2900003700002003410e3a00f007200320172900003700f10741014100200341f0076a104c200341003602f807200342013703f0072005200341f0076a10660240024020032802f407220820032802f80722026b2005490d0020032802f00721080c010b200220056a22062002490d1420084101742207200620062007491b22064100480d140240024020080d002006103221080c010b20032802f00720082006103421080b2008450d04200320063602f407200320083602f0070b2003200220056a3602f807200820026a201a2005109b051a200f200341f0076a1066200f450d042010210803402008280200210a200841086a2802002202200341f0076a10660240024020032802f407220920032802f80722066b2002490d0020032802f00721070c010b200620026a22072006490d152009410174220c20072007200c491b220c4100480d150240024020090d00200c103221070c010b20032802f0072009200c103421070b2007450d072003200c3602f407200320073602f007200c21090b2003200620026a220c3602f807200720066a200a2002109b051a2008410c6a2208200e470d000c070b0b418494c10021092013450d08201210290c080b20064101102e000b20064101102e000b20064101102e000b20032802f807210c20032802f407210920032802f00721070c010b200c4101102e000b200341f0076a201910d9012003200b3602a806200341a8046a41186a22024200370300200341a8046a41106a22084200370300200341a8046a41086a22064200370300200342003703a804200341a8066a4104200341a8046a100020034188046a41186a200229030037030020034188046a41106a200829030037030020034188046a41086a2006290300370300200320032903a804370388040240024020032802f407220a20032802f80722066b4120490d0020032802f00721020c010b200641206a22022006490d0d200a4101742208200220022008491b22084100480d0d02400240200a0d002008103221020c010b20032802f007200a2008103421020b2002450d02200320083602f407200320023602f0072008210a0b200220066a2208200329038804370000200841186a20034188046a41186a290300370000200841106a20034188046a41106a290300370000200841086a20034188046a41086a2903003700002003200641206a3602f407200320023602f0072007200c200341f0076a10f3020240200a450d00200210290b2009450d00200710290b02402013450d00201210290b02402018450d00201a10290b0240200f450d00200f410c6c21082010210203400240200241046a280200450d00200228020010290b2002410c6a2102200841746a22080d000b0b4100210902402011450d00201010290b0c020b20084101102e000b02402018450d00201a10290b0240200f450d00200f410c6c21082010210203400240200241046a280200450d00200228020010290b2002410c6a2102200841746a22080d000b0b2011450d00201010290b4100211a410121084101210b41012106410121074101210c4101210d4101210e4101210f410121104101211141012118410121190c310b200241216a2d000021072002411d6a280000210c200241196a280000210d200241156a280000210e200241116a280000210f2002410d6a2800002110200241096a2800002111200241056a2800002118200141086a28020021062002280001210820022d00002102024002400240024002400240200141046a2802000e03000102000b200341f0076a41146a4101360200200342013702f4072003418c9ac5003602f0072003410536029407200341c09ac50036029007200320034190076a36028008200341f0076a41b8c4c300107d000b41a0f9c2002109412a210a200241ff01710d02200841ff01714101470d02200320073a00c7062003200c3600c3062003200d3600bf062003200e3600bb062003200f3600b706200320103600b306200320113600af06200320183600ab06200320084118763a00aa06200320084108763b01a806200341c8056a41086a22024200370300200342003703c80541eac4c3004108200341c8056a1003200341c8046a41086a2002290300370300200320032903c8053703c804200341f0076a200341c8046a411010590240024020032d00f0074101460d00200341a0036a41186a4200370300200341a0036a41106a4200370300200341a0036a41086a4200370300200342003703a0030c010b200341a0036a41186a20034189086a290000370300200341a0036a41106a20034181086a290000370300200341a0036a41086a200341f9076a290000370300200320032900f1073703a0030b0240200341a8066a200341a0036a4120109d05450d0041c8c4c30021094122210a0c030b200341f0076a2006418801109b051a41002119200341003b01a003200341f8026a200341f0076a200341a0036a10ee024101210841012102024020032802f8022207450d00200720032802fc021009410021020b200320023a00f2072003410d3b01f00741014100200341f0076a104c200610290c010b02400240200241ff01710d00200841ff01714101460d010b41a0f9c2002109412a210a0c030b200141286a2d0000210a200141246a280200211a200141206a280200210b2001411c6a2802002105200141186a2802002112200141146a2802002113200141106a28020021172001410c6a2802002109200320073a00c7062003200c3600c3062003200d3600bf062003200e3600bb062003200f3600b706200320103600b306200320113600af06200320183600ab06200320084118763a00aa06200320084108763b01a806200341c8056a41086a22024200370300200342003703c80541eac4c3004108200341c8056a1003200341c8046a41086a2002290300370300200320032903c8053703c804200341f0076a200341c8046a411010590240024020032d00f0074101460d00200341a0036a41186a4200370300200341a0036a41106a4200370300200341a0036a41086a4200370300200342003703a0030c010b200341a0036a41186a20034189086a290000370300200341a0036a41106a20034181086a290000370300200341a0036a41086a200341f9076a290000370300200320032900f1073703a0030b0240200341a8066a200341a0036a4120109d05450d0041f2c4c30021094131210a0c030b02400240200641ff01714101460d0020064118762107200641087621020c010b200341f0076a200941067610ab0220032802f00721080240024020032802f8072009413f7122024b0d00410021060c010b200820024105746a22022d001f210a200228001b211a2002280017210b20022800132105200228000f2112200228000b2113200228000721172002280003210920022d0002210720022f00002102410121060b024020032802f407450d00200810290b20060d0041c8d8c30021094115210a0c030b200341c8056a41086a22084200370300200342003703c80541eac4c3004108200341c8056a1003200341c8046a41086a2008290300370300200320032903c8053703c804200341f0076a200341c8046a411010590240024020032d00f0074101460d00200341c0046a4200370300200341a8046a41106a4200370300200341a8046a41086a4200370300200342003703a8040c010b200341c0046a20034189086a290000370300200341a8046a41106a20034181086a290000370300200341a8046a41086a200341f9076a290000370300200320032900f1073703a8040b20034188046a41086a200341a8046a41086a290300220437030020034188046a41106a200341a8046a41106a290300221437030020034188046a41186a200341a8046a41186a2903002215370300200320032903a804221b37038804200341fa076a200437010020034182086a20143701002003418a086a20153701002003418d023b01f0072003201b3701f207410021194101210841014100200341f0076a104c2003200a3a008f082003201a36008b082003200b360087082003200536008308200320123600ff07200320133600fb07200320173600f707200320093600f307200320073a00f207200320023b01f007200341c8056a41086a22024200370300200342003703c80541eac4c3004108200341c8056a1003200341c8046a41086a2002290300370300200320032903c8053703c804200341103602a4032003200341c8046a3602a003200341f0076a200341a0036a1089010b4101210b41012106410121074101210c4101210d4101210e4101210f4101211041012111410121180c260b2006102a200610290b41002119410121084101210b41012106410121074101210c4101210d4101210e4101210f4101211041012111410121184101211a0c300b200341f0076a200141086a418001109b051a200341a0036a41206a200241206a290200370300200341a0036a41186a200241186a290200370300200341a0036a41106a200241106a290200370300200341a0036a41086a200241086a290200370300200320022902003703a003200341f0026a200341f0076a200341a0036a10f40220032802f402210a20032802f002210941002118410121084101210b41012106410121074101210c4101210d4101210e4101210f41012110410121110c2e0b20034188036a41086a2209200141206a29030037030020034188036a410d6a220d200141256a2900003700002003200141186a29030037038803200241086a2802002106200241046a28020021072001410c6a280200210c410e210a20022d00002108024002400240024002400240024002400240024002400240024002400240024002400240200141086a2802000e0400010203000b200341f0076a41146a4101360200200342013702f4072003418c9ac5003602f0072003410536029407200341c09ac50036029007200320034190076a36028008200341f0076a41c4b9c200107d000b200141386a2903002115200141306a29030021042002411a6a2901002114200241196a2d00002110200241186a2d00002111200241166a2f01002118200241156a2d00002119200241146a2d0000211a200241126a2f0100210b200241116a2d00002105200241106a2d000021122002410e6a2f010021132002410d6a2d000021172002410c6a2d00002116200241026a2f0100211e200141146a280200210f200141106a280200210e20022d00012102200341a8056a410d6a200d290000370000200341a8056a41086a200929030037030020032003290388033703a80541a0f9c2002109412a210a200841ff01710d26200241ff01714101470d26200320143703b803200320103a00b703200320113a00b603200320183b01b403200320193a00b3032003201a3a00b2032003200b3b01b003200320053a00af03200320123a00ae03200320133b01ac03200320173a00ab03200320073a00a2032003201e3b01a00320032006411076410874200641087641ff0171722016411874723600a70320032007411076410874200741087641ff0171722006411874723600a303200341f0076a410d6a2202200341a8056a410d6a290000370000200341f0076a41086a2206200341a8056a41086a290300370300200320032903a8053703f0070240200c41ff01714101460d00200c4108762108200341a8066a410d6a2002290000370000200341a8066a41086a2006290300370300200320032903f0073703a8060c0f0b200341a8046a200e41067610ab0220032802a80421060240024020032802b004200e413f7122024b0d00410021020c010b200341b0066a200620024105746a220241136a290000370300200341b5066a200241186a2900003700002003200229000b3703a80620022f0000200241026a2d00004110747221082002280007210f2002280003210e410121020b024020032802ac04450d00200610290b20020d0e410121024115210f41c8d8c300210e0c0f0b41aacec3002109200841ff01714101470d2520064102490d25200741ff01710d25411210322202450d03200241106a41002f0093bd413b0000200241086a410029008bbd4137000020024100290083bd4137000020024112412410342202450d042002200c360012200341a8046a41186a22084200370300200341a8046a41106a22064200370300200341a8046a41086a22074200370300200342003703a80420024116200341a8046a100020034188046a41186a200829030037030020034188046a41106a200629030037030020034188046a41086a2007290300370300200320032903a80437038804200341f0076a20034188046a108602024020032903f00742015222080d0020034188046a412010040b20032802f8072106200341a8066a200341fc076a41dc00109b051a024020080d0020034190076a200341a8066a41dc00109b051a20021029200341c8056a20034190076a41dc00109b051a200320063602a003200341a0036a410472200341c8056a41dc00109b051a200341e0026a200341c0036a20032903b003200341b8036a29030010c201200341e0026a41086a290300211520032903e0022104200341c8056a41086a22024200370300200342003703c80541c2d5c0004116200341c8056a1003200341c8046a41086a22062002290300370300200320032903c8053703c804200341c8026a200341c8046a10eb01200341c8026a41106a290300211420032903d002211b20032802c802210820024200370300200342003703c80541c2d5c0004116200341c8056a100320062002290300370300200320032903c8053703c804200342002014420020081b221420157d201b420020081b2215200454ad7d221b201520047d2204201556201b201456201b2014511b22021b3703f80720034200200420021b3703f007200341c8046a4110200341f0076a41101005410021090c260b200210290c010b41aacec3002109200841ff01714101470d2420064104490d24200741ff01710d24411210322202450d04200241106a41002f0093bd413b0000200241086a410029008bbd4137000020024100290083bd4137000020024112412410342202450d052002200c360012200341a8046a41186a22084200370300200341a8046a41106a22064200370300200341a8046a41086a22074200370300200342003703a80420024116200341a8046a100020034188046a41186a200829030037030020034188046a41106a200629030037030020034188046a41086a2007290300370300200320032903a8043703880420034188046a412041014100410010072108200210292008417f470d010b41eeb9c20021094119210a0c230b200341c8056a41086a22024200370300200342003703c8054183abc5004112200341c8056a1003200341c8046a41086a2002290300370300200320032903c8053703c804200341003602f007200341c8046a4110200341f0076a1006210820032802f0072206417f460d052008450d05200320063602a403200320083602a003200341f0076a200341a0036a103c20032802f007220f450d04200341f8076a280200210220032802f407210e02402006450d00200810290b2002200e470d070c060b41124101102e000b41244101102e000b41124101102e000b41244101102e000b41f7cdc3004133200341f8086a41ecd6c3001054000b4104210f4100210e0b200e220241016a22082002490d0a20024101742206200820082006491b220e41ffffffff0371200e470d0a200e41027422084100480d0a0240024020020d0020081032210f0c010b200f200241027420081034210f0b200f450d010b200f200241027422076a200c360200200341c8056a41086a22084200370300200342003703c8054183abc5004112200341c8056a1003200341c8046a41086a2008290300370300200320032903c8053703c804200341003602f807200342013703f007200241016a2208200341f0076a106602400240200820024f0d0020032802f807210a20032802f407210920032802f00721080c010b410020032802f80722026b2106200741046a210c20032802f4072109200f210703402007280200210d02400240200920066a4104490d0020032802f00721080c010b200241046a22082002490d0c2009410174220a20082008200a491b220a4100480d0c0240024020090d00200a103221080c010b20032802f0072009200a103421080b2008450d042003200a3602f407200320083602f007200a21090b200741046a21072003200241046a220a3602f807200820026a200d3600002006417c6a2106200a2102200c417c6a220c0d000b0b200341c8046a41102008200a100502402009450d00200810290b410021090240200e450d00200f10290b0c1a0b20084104102e000b200a4101102e000b200341c8056a410d6a200341a8066a410d6a290000370000200341c8056a41086a200341a8066a41086a290300370300200320032903a8063703c805410021020b200341c8046a41086a2206200341c8056a41086a290300370300200341c8046a41106a200341c8056a41106a290300370300200320032903c8053703c80402402002450d00200f210a200e21090c170b200341b0026a2004201542c0843d420010a105200341a0026a20032903b0022214200341b0026a41086a290300221b42c0fb42427f10a00520034190026a2014201b42d08603420010a00520034190076a410d6a2207200341c8046a410d6a29000037000020034190076a41086a2006290300370300200320032903c80437039007200341c0026a200341a0036a200329039002221b200420032903a0027c42148042ffffffff0f837c2214428080e983b1de162014428080e983b1de165620034190026a41086a2903002014201b54ad7c22144200522014501b22021b221b2014420020021b2214107e024020032802c002450d0041d4b9c2002109411a210a0c170b20034188026a41edaac5004116105d200328028c0221022003280288022106200341c8056a41086a22094200370300200342003703c80541edaac5004116200341c8056a1003200341c8046a41086a2009290300370300200320032903c8053703c80420032002410020061b220941016a3602f007200341c8046a4110200341f0076a41041005200341a8086a200341a0036a41186a290300370300200341a0086a200341a0036a41106a29030037030020034198086a200341a0036a41086a290300370300200341b7086a200f360000200341b3086a200e360000200341bb086a200329039007370000200341c3086a20034190076a41086a290300370000200341c8086a2007290000370000200320083b01b008200341b2086a20084110763a0000200320153703f807200320043703f007200320032903a00337039008200341f0076a41186a20143703002003201b370380080240024002400240411210322202450d00200241106a41002f0093bd413b0000200241086a410029008bbd4137000020024100290083bd4137000020024112412410342206450d0120062009360012200341a8046a41186a22024200370300200341a8046a41106a22084200370300200341a8046a41086a22074200370300200342003703a80420064116200341a8046a100020034188046a41186a200229030037030020034188046a41106a200829030037030020034188046a41086a2007290300370300200320032903a80437038804200341003602b006200342013703a80620034190086a200341a8066a108101200341f0076a41086a290300210420032903f00721140240024020032802ac06220820032802b00622026b4110490d0020032802a80621080c010b200241106a22072002490d0a20084101742202200720072002491b22024100480d0a0240024020080d002002103221080c010b20032802a80620082002103421080b2008450d03200320023602ac06200320083602a80620032802b00621020b200820026a22082004370008200820143700002003200241106a3602b006200341b0086a200341a8066a10810120034188086a290300210420032903800821140240024020032802ac06220720032802b00622086b4110490d0020032802a80621020c010b200841106a22022008490d0a20074101742208200220022008491b220a4100480d0a0240024020070d00200a103221020c010b20032802a8062007200a103421020b2002450d042003200a3602ac06200320023602a80620032802b0062108200a21070b200220086a220a2004370008200a201437000020034188046a41202002200841106a100502402007450d00200210290b20061029200341fc076a200936020041002109200341f8076a41003a00002003410b3a00f00741014100200341f0076a104c0c1a0b41124101102e000b41244101102e000b20024101102e000b200a4101102e000b200141086a2802002106200141046a28020021070240024020022d00000d004101210820022d000141ff01714101460d010b41a0f9c2002109412a210a41002111410121082006450d02200710290c020b200241096a280000210a02402006450d00200710290b410021114101210b41012106410121074101210c4101210d4101210e4101210f410121100b41012118410121194101211a410021090c2c0b4101210b41012106410121074101210c4101210d4101210e4101210f410121100c290b410041d4f8c20020022d00004520022d00014102467122021b21094124210a410121082002450d18200141046a2802002102200341c8056a41086a22084200370300200342003703c80541f9bac1004110200341c8056a1003200341c8046a41086a2008290300370300200320032903c8053703c8040240200341c8046a41104101410041001007417f470d0020034180026a41d983c300410d105d024020032802840241002003280280021b2002490d00200341c8056a41086a22084200370300200342003703c80541f9bac1004110200341c8056a1003200341c8046a41086a2008290300370300200320032903c8053703c804200320023602f007200341c8046a4110200341f0076a410410050c140b41c8bcc100106d000b41b4bbc100106d000b2003418a036a2206200141076a2d00003a0000200341a0036a41086a22072001411c6a290200370300200341a0036a41106a2209200141246a290200370300200341a0036a41186a2001412c6a290200370300200341c0036a200141346a290200370300200341c8036a2001413c6a290200370300200341d0036a200141c4006a2d00003a00002003200141056a2f00003b0188032003200141146a2902003703a003200141086a280200210c2001410c6a280200210d200141106a280200210820022f0001200241036a2d000041107472210e2002410c6a2802002110200241086a2802002111200241046a280200211820022d0000210202400240024002400240024002400240024002400240200141046a2d0000220f0e050001020304000b200341f0076a41146a4101360200200342013702f4072003418c9ac5003602f0072003410536029407200341c09ac50036029007200320034190076a36028008200341f0076a41c4c5c300107d000b200341bf066a2007290300370000200341c7066a20092d00003a0000200320032f0188033b01a806200320083600b3062003200d3600af062003200c3600ab06200320032903a0033700b706200320062d00003a00aa06200241034b0d1102400240024020020e0401001402010b201141017420104d0d13201841ff0171450d010c130b200e41ff01710d120b200341c8056a41086a22024200370300200342003703c80541d4c5c300411b200341c8056a1003200341c8046a41086a2002290300370300200320032903c8053703c804200341003602f007200341c8046a4110200341f0076a100621020240024002400240024002400240024020032802f0072208417f460d002002450d0020032008360294072003200236029007200341f0076a20034190076a103120032802f0072206450d0b20032902f407210420032802f407210e02402008450d00200210290b200320063602a8052004a72110410021022004422088a7220a41014b0d02200a0e020103010b41012106200341013602a8054100210e410021100b20034188046a41186a200341a8066a41186a29030037030020034188046a41106a200341a8066a41106a29030037030020034188046a41086a200341a8066a41086a290300370300200320032903a806370388044100210a20034188046a2108410021070c020b200a210803402008410176220720026a22092002200620094105746a200341a8066a4120109d054101481b2102200820076b220841014b0d000b0b0240200620024105746a200341a8066a4120109d0522080d0002402010450d00200610290b41fbc5c30021094110210a0c120b20034188046a41186a200341a8066a41186a29030037030020034188046a41106a200341a8066a41106a29030037030020034188046a41086a200341a8066a41086a290300370300200320032903a806370388042008411f7620026a2207200a4b0d0120034188046a21080b200a2010460d01200e21100c020b41b0d9c500106d000b0240200e200a460d00200e21100c010b200e41016a2202200e490d0a200e4101742209200220022009491b221041ffffff3f712010470d0a201041057422024100480d0a02400240200e0d002002103221060c010b2006200e4105742002103421060b2006450d05200320063602a8050b200620074105746a220241206a2002200a20076b410574109c051a200241186a200841186a290000370000200241106a200841106a290000370000200241086a200841086a29000037000020022008290000370000200341c8056a41086a22024200370300200342003703c80541d4c5c300411b200341c8056a1003200341c8046a41086a2002290300370300200320032903c8053703c804200341103602f4072003200341c8046a3602f0072006200a41016a2202200341f0076a109501200341f0076a41186a200341a8066a41186a290300370300200341f0076a41106a200341a8066a41106a290300370300200341f0076a41086a200341a8066a41086a290300370300200320032903a8063703f007410021094101410020032802a8052208200210f502200341093b01f00741014100200341f0076a104c2010450d0c200810290c0d0b200341bf066a2007290300370000200341c7066a20092d00003a0000200320032f0188033b01a806200320083600b3062003200d3600af062003200c3600ab06200320032903a0033700b706200320062d00003a00aa06200241034b0d1002400240024020020e0401001302010b201141017420104d0d12201841ff0171450d010c120b200e41ff01710d110b200341c8056a41086a22024200370300200342003703c80541d4c5c300411b200341c8056a1003200341c8046a41086a2002290300370300200320032903c8053703c804200341003602f007200341c8046a4110200341f0076a100621020240024020032802f0072208417f460d002002450d0020032008360294072003200236029007200341f0076a20034190076a103120032802f007220e450d0620032902f40721042008450d01200210290c010b4101210e420021040b4100210202400240024002402004422088a7220941014b0d0020090e020201020b2009210803402008410176220620026a22072002200e20074105746a200341a8066a4120109d054101481b2102200820066b220841014b0d000b0b200e20024105746a200341a8066a4120109d05450d010b41efc5c3002109410c210a2004a7450d0d200e10290c0d0b200220094f0d05200e20024105746a2208200841206a2002417f7320096a410574109c051a200341c8056a41086a22024200370300200342003703c80541d4c5c300411b200341c8056a1003200341c8046a41086a2002290300370300200320032903c8053703c8042003200341c8046a3602f007200341103602f407200e2009417f6a2202200341f0076a109501200341f0076a41186a200341a8066a41186a290300370300200341f0076a41106a200341a8066a41106a290300370300200341f0076a41086a200341a8066a41086a290300370300200320032903a8063703f007200341f0076a4101200e200210f50220034189023b01f0074100210941014100200341f0076a104c2004a7450d0b200e10290c0b0b200341a7076a2007290300370000200341af076a20092d00003a0000200320032f0188033b0190072003200836009b072003200d360097072003200c36009307200320032903a00337009f07200320062d00003a009207200341a8066a41186a200341c9036a290000370300200341a8066a41106a200341c1036a290000370300200341a8066a41086a200341b9036a290000370300200320032900b1033703a806418bc6c3002109410a210a200241034b0d0b02400240024020020e0401000e02010b201141017420104d0d0d201841ff01710d0d0c010b200e41ff01710d0c0b024020034190076a200341a8066a4120109d050d00410021090c0c0b200341c8056a41086a22024200370300200342003703c80541d4c5c300411b200341c8056a1003200341c8046a41086a2002290300370300200320032903c8053703c804200341003602f007200341c8046a4110200341f0076a100621020240024020032802f0072208417f460d002002450d00200320083602cc05200320023602c805200341f0076a200341c8056a103120032802f007220e450d0720032902f40721042008450d01200210290c010b4101210e420021040b41efc5c3002109410c210a41002102024002402004422088a7221041014b0d0020100e020b010b0b2010210803402008410176220620026a22072002200e20074105746a20034190076a4120109d054101481b2102200820066b220841014b0d000b0b200e20024105746a220820034190076a4120109d050d09200341a8046a41186a2206200341a8066a41186a290300370300200341a8046a41106a2207200341a8066a41106a290300370300200341a8046a41086a2209200341a8066a41086a290300370300200320032903a8063703a804200220104f0d06200820032903a804370000200841186a2006290300370000200841106a2007290300370000200841086a200929030037000041002102024020104101460d00410021022010210803402008410176220620026a22072002200e20074105746a200341a8066a4120109d054101481b2102200820066b220841014b0d000b0b0240200e20024105746a200341a8066a4120109d050d0041fbc5c30021094110210a0c0a0b200e201010cc01200341c8056a41086a22024200370300200342003703c80541d4c5c300411b200341c8056a1003200341c8046a41086a2002290300370300200320032903c8053703c8042003200341c8046a3602f007200341103602f407200e2010200341f0076a109501200341f0076a41186a20034190076a41186a290300370300200341f0076a41106a20034190076a41106a290300370300200341f0076a41086a20034190076a41086a29030037030020032003290390073703f007200341f0076a4101200e201010f50220034189043b01f0074100210941014100200341f0076a104c2004a7450d0a200e10290c0b0b0240200241034b0d000240024020020e040100020a010b201141017420104d0d01201841ff01710d010c090b200e41ff0171450d080b410a210a418bc6c30021090c0b0b41f7cdc3004133200341f8086a41ecd6c3001054000b20024101102e000b41f7cdc3004133200341f8086a41ecd6c3001054000b418080c000106d000b41f7cdc3004133200341f8086a41ecd6c3001054000b41e8b1c300200220101036000b1033000b200c200810cc01200341c8056a41086a22024200370300200342003703c80541d4c5c300411b200341c8056a1003200341c8046a41086a2002290300370300200320032903c8053703c804200341003602f007200341c8046a4110200341f0076a100621020240024020032802f0072206417f460d002002450d00200320063602ac06200320023602a806200341f0076a200341a8066a1031024020032802f0072207450d00200341f8076a280200210920032802f407210a02402006450d00200210290b200c20082007200910f602200a450d02200710290c020b41f7cdc3004133200341f8086a41ecd6c3001054000b200c20084101410010f6020b200341c8056a41086a22024200370300200342003703c80541d4c5c300411b200341c8056a1003200341c8046a41086a2002290300370300200320032903c8053703c804200341103602f4072003200341c8046a3602f007200c2008200341f0076a1095010240200d450d00200c10290b20034189063b01f0074100210941014100200341f0076a104c0c070b2004a7450d01200e10290c010b0b200f417f6a220241034b0d0120020e0404040400040b200d0d010c030b200f4104490d02200d450d020b200c10290c010b410a210a418bc6c30021090b41002110410121084101210b41012106410121074101210c4101210d4101210e4101210f0c1c0b200341f0076a41386a200141c0006a290300370300200341f0076a41306a200141386a290300370300200341f0076a41286a200141306a290300370300200341f0076a41206a200141286a290300370300200341f0076a41186a200141206a290300370300200341f0076a41106a200141186a290300370300200341f0076a41086a200141106a2903003703002003200141086a2903003703f007200341a0036a41206a200241206a290200370300200341a0036a41186a200241186a290200370300200341a0036a41106a200241106a290200370300200341a0036a41086a200241086a290200370300200320022902003703a003200341f8016a200341f0076a200341a0036a10b20220032802fc01210a20032802f80121094100210f410121084101210b41012106410121074101210c4101210d4101210e0c1a0b200341a0036a41206a200141246a290200370300200341a0036a41186a2001411c6a290200370300200341a0036a41106a200141146a290200370300200341a0036a41086a2001410c6a2902003703002003200141046a2902003703a003200341f0076a41206a200241206a290200370300200341f0076a41186a200241186a290200370300200341f0076a41106a200241106a290200370300200341f0076a41086a200241086a290200370300200320022902003703f007200341f0016a200341a0036a200341f0076a10f70220032802f401210a20032802f00121094100210e410121084101210b41012106410121074101210c4101210d0c180b200341a0036a41206a200141246a290200370300200341a0036a41186a2001411c6a290200370300200341a0036a41106a200141146a290200370300200341a0036a41086a2001410c6a2902003703002003200141046a2902003703a003200341f0076a41206a200241206a290200370300200341f0076a41186a200241186a290200370300200341f0076a41106a200241106a290200370300200341f0076a41086a200241086a290200370300200320022902003703f007200341e8016a200341a0036a200341f0076a10f80220032802ec01210a20032802e80121094100210d410121084101210b41012106410121074101210c0c160b200341f0076a41286a200141306a290300370300200341f0076a41206a200141286a290300370300200341f0076a41186a200141206a290300370300200341f0076a41106a200141186a290300370300200341f0076a41086a200141106a2903003703002003200141086a2903003703f007200341a0036a41206a200241206a290200370300200341a0036a41186a200241186a290200370300200341a0036a41106a200241106a290200370300200341a0036a41086a200241086a290200370300200320022902003703a003200341e0016a200341f0076a200341a0036a107b20032802e401210a20032802e00121094100210c410121084101210b41012106410121070c140b200141086a280200211a200141046a280200210b200341f0076a2001410c6a41e400109b051a2002411a6a2901002104200241196a2d0000210c200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002118200241106a2d000021192002410e6a2f010021052002410d6a2d000021122002410c6a2d000021132002410a6a2f01002117200241096a2d00002116200241086a2d0000211e200241066a2f0100211f200241056a2d00002120200241046a2d00002121200241026a2f0100212220022d0001210a20022d00002107200341c8046a200341f0076a41046a41e000109b051a4101210241a0f9c200210941002108412a2106024002402007450d00410021070c010b41002107200a41ff01714101470d00201f410874202072201e411874722109410021022016210620172108201321070b200841ffff0371410874200641ff017172200741187472210a0240024020020d00200320043703a8072003200c3a00a7072003200d3a00a6072003200e3b01a4072003200f3a00a307200320103a00a207200320113b01a007200320183a009f07200320193a009e07200320053b019c07200320123a009b072003200a360097072003200936009307200320213a009207200320223b019007200341a0036a20034190076a10f902024002400240024020032802c0032202450d00200341a8066a41106a200341d8036a290300370300200341a8066a41086a200341d0036a290300370300200341a8066a41186a200341e0036a290300370300200341c8066a200341e8036a280200360200200341a8046a41086a2208200341b4066a290200370300200341a8046a41106a2206200341bc066a290200370300200341a8046a41186a2207200341c4066a2902003703002003200341c8036a2903003703a806200320032902ac063703a804024020032802c403450d00200210290b200341a8056a41086a2008290300370300200341a8056a41106a2006290300370300200341a8056a41186a2007290300370300200320032903a8043703a805200341c8056a200341c8046a41e000109b051a200341a8046a200341a8056a10a90120032802a804210220032802b0042108200341003602a00320022008200341a0036a1006210820032802a0032206417f460d022008450d022003200636028c042003200836028804200341a0036a20034188046a10aa0120032d00a0034101460d0120034190076a200341a0036a41017241e000109b051a02402006450d00200810290b200341a0036a20034190076a41e000109b051a200341013a00a806200341a8066a410172200341a0036a41e000109b051a0c030b41dff5c20021094127210a0c030b41f7cdc3004133200341f8086a41ecd6c3001054000b200341003a00a8060b024020032802ac04450d00200210290b200341c9066a2105200341e9066a2112200341c8056a41206a211820034188066a2119200341a8066a4101722113200341a0036a410172210c4104210641e7e485f30621080240024003400240024002400240200841e9dabdf30646220e0d000240200841e7e485f306470d00200341c8056a21090c020b200841e2c289ab06470d02201821090c010b201921090b412021024100210741201032220a0d0141204101102e000b4101210741002102410121094101210a0b200a20092002109b05210a2003200236029c0720032002360298072003200a360294072003200836029007200341a8046a20034190076a10ab01200341a0036a20032802a804220d20032802b00410590240024020032d00a0034101470d0020034188046a41186a220f200c41186a29000037030020034188046a41106a2210200c41106a29000037030020034188046a41086a2211200c41086a2900003703002003200c29000037038804024020032802ac04450d00200d10290b024020070d00200a10290b200341a0036a41186a200f290300370300200341a0036a41106a2010290300370300200341a0036a41086a201129030037030020032003290388043703a003200341a0036a200341a8056a4120109d05450d014186f6c20021094118210a0c050b024020032802ac04450d00200d10290b20070d00200a10290b0240024020032d00a8064101470d00024002400240200841e2c289ab06460d00200e0d010240200841e7e485f306460d004100210a4101210d0c030b4120210a2013210d0c020b4120210a2005210d0c010b4120210a2012210d0b02402002200a470d002009200d460d022009200d2002109d05450d020b02400240200a0d004100210e4101210f0c010b200a210e200a1032220f450d040b200f200d200a109b05210d2003200a3602ac032003200e3602a8032003200d3602a403200320083602a00320034190076a200341a0036a10ab01200328029007220a20032802980710040240200328029407450d00200a10290b200e450d00200d10290b4101210a024020070d0020021032220a450d040b200a20092002109b052109200320023602ac03200320023602a803200320093602a403200320083602a00320034190076a200341a0036a10ab01200328029007210220032003280298073602ac04200320023602a804200341a8056a200341a8046a1089010240200328029407450d00200210290b20070d00200910290b02402006410c460d00200641acc8c2006a2800002108200641046a21060c010b0b20034190076a200341a8056a10a90120032802980721082003280290072102200341003602a803200342013703a003200341c8056a200341a0036a10ee01200320183602a804200341a8046a200341a0036a108a01200320193602a804200341a8046a200341a0036a108a0120032802a40321062002200820032802a003220720032802a803100502402006450d00200710290b0240200328029407450d00200210290b410021090240201a450d00200b10290b0c030b200a4101102e000b20024101102e000b201a450d00200b10290b41002107410121084101210b410121060c120b200341f0076a41306a200141386a290300370300200341f0076a41286a200141306a290300370300200341f0076a41206a200141286a290300370300200341f0076a41186a200141206a290300370300200341f0076a41106a200141186a290300370300200341f0076a41086a200141106a2903003703002003200141086a2903003703f007200341a0036a41206a200241206a290200370300200341a0036a41186a200241186a290200370300200341a0036a41106a200241106a290200370300200341a0036a41086a200241086a290200370300200320022902003703a003200341d8016a200341f0076a200341a0036a10fa0220032802dc01210a20032802d801210941002106410121084101210b0c100b200141256a2900002115200141246a2d00002111200141236a2d00002118200141216a2f00002119200141206a2d0000211a2001411f6a2d0000210b2001411d6a2f000021052001411c6a2d000021122001411b6a2d0000210a200141196a2f0000210c200141186a2d0000210d200141146a280200210e200141106a28020021072001410f6a2d0000210f2001410d6a2f000021102001410c6a2d00002113200141086a2802002106200141306a2903002104200141386a2903002114200341a8066a41106a200141d0006a2d00003a0000200341a8066a41086a2217200141c8006a2903003703002003200141c0006a2903003703a80620022d0001210920022d000021080240024002400240024002400240024002400240024020060e0400010203000b200341f0076a41146a4101360200200342013702f4072003418c9ac5003602f0072003410536029407200341c09ac50036029007200320034190076a36028008200341f0076a41e4fec000107d000b02400240200841ff01710d00200941ff01714101460d010b41a0f9c2002109412a210a0c0a0b200241196a2d00002108200241186a2d00002106200241166a2f01002109200241156a2d00002117200241146a2d00002116200241126a2f0100211e200241116a2d0000211f200241106a2d000021202002410e6a2f010021212002410d6a2d000021222002410c6a2d000021232002410a6a2f01002124200241096a2d00002125200241086a2d00002126200241066a2f01002127200241056a2d00002128200241046a2d00002129200241026a2f0100212a20032002411a6a2901003703b803200320083a00b703200320063a00b603200320093b01b403200320173a00b303200320163a00b2032003201e3b01b0032003201f3a00af03200320203a00ae03200320213b01ac03200320223a00ab03200320293a00a2032003202a3b01a003200320252024410874202341187472723600a703200320282027410874722026411874723600a3030240201341ff01714101470d0020034190076a200741067610ab022003280290072108024002402003280298072007413f7122024b0d00410021020c010b200820024105746a2202290018211520022d0017211120022d0016211820022f0014211920022d0013211a20022d0012210b20022f0010210520022d000f211220022d000e210a20022f000c210c20022d000b210d2002280007210e2002280003210720022d0002210f20022f00002110410121020b0240200328029407450d00200810290b2002450d090b2003201537038808200320113a008708200320183a008608200320193b0184082003201a3a0083082003200b3a008208200320053b018008200320123a00ff072003200a3a00fe072003200c3b01fc072003200d3a00fb072003200e3600f707200320073600f3072003200f3a00f207200320103b01f007200341386a200341a0036a200341f0076a2004201410c40120032802382209450d06200328023c210a0c090b200920087241ff01710d062017290300211b20032903a806211c0240201341ff01714101470d00200341a0036a200741067610ab0220032802a00321080240024020032802a8032007413f7122024b0d00410021020c010b200820024105746a2202290018211520022d0017211120022d0016211820022f0014211920022d0013211a20022d0012210b20022f0010210520022d000f211220022d000e210a20022f000c210c20022d000b210d2002280007210e2002280003210720022d0002210f20022f00002110410121020b024020032802a403450d00200810290b2002450d080b2003201537038808200320113a008708200320183a008608200320193b0184082003201a3a0083082003200b3a008208200320053b018008200320123a00ff072003200a3a00fe072003200c3b01fc072003200d3a00fb072003200e3600f707200320073600f3072003200f3a00f207200320103b01f007411410322202450d01200241002900d8d540370000200241106a41002800e8d540360000200241086a41002900e0d54037000020034294808080c0023702a403200320023602a003200341f0076a200341a0036a10810120032802a4032102200341b8016a20032802a003220620032802a80310a101200341b8016a41106a290300420020032802b80122081b211520032903c001420020081b211d02402002450d00200610290b201d20045422082015201454201520145122021b0d02201d200456201520145620021b450d04200341a0016a41c2d5c000411610a301200341b0016a290300212b20032903a801212c20032802a0012102200341c8056a41086a22064200370300200342003703c80541c2d5c0004116200341c8056a1003200341c8046a41086a2006290300370300200320032903c8053703c80420034200202b420020021b222b2008ad201420157d7c7c202c420020021b2215201d20047d222c54ad7d221d2015202c7d222c201556201d202b56201d202b511b22021b3703a80320034200202c20021b3703a003200341a0036a21020c030b200920087241ff01710d05200141e0006a290300211c200141d8006a290300211d20032900b106211b20032d00b006210620032d00af06210920032f00ad06211720032d00ac06211620032d00ab06211e20032f00a906211f20032d00a80621200240201341ff01714101470d00200341f0076a200741067610ab0220032802f00721080240024020032802f8072007413f7122024b0d00410021020c010b200820024105746a2202290018211520022d0017211120022d0016211820022f0014211920022d0013211a20022d0012210b20022f0010210520022d000f211220022d000e210a20022f000c210c20022d000b210d2002280007210e2002280003210720022d0002210f20022f00002110410121020b024020032802f407450d00200810290b2002450d070b2004422088a72108200320153703b803200320113a00b703200320183a00b603200320193b01b4032003201a3a00b3032003200b3a00b203200320053b01b003200320123a00af032003200a3a00ae032003200c3b01ac032003200d3a00ab032003200e3600a703200320073600a3032003200f3a00a203200320103b01a003024002402004a741ff01714101460d002014a7210e2014423888a7210a2014422888a7210c2014422088a7210d2004421888a7210f2004420888a721100c010b20034190076a2004422688a710ab022003280290072107024002402003280298072008413f7122024b0d00410021022015211b201121062018210920192117201a2116200b211e2005211f201221200c010b200720024105746a2202290018211b20022d0017210620022d0016210920022f0014211720022d0013211620022d0012211e20022f0010211f20022d000f212020022d000e210a20022f000c210c20022d000b210d2002280007210e2002280003210820022d0002210f20022f00002110410121020b0240200328029407450d00200710290b2002450d070b2003201b37038808200320063a008708200320093a008608200320173b018408200320163a0083082003201e3a0082082003201f3b018008200320203a00ff072003200a3a00fe072003200c3b01fc072003200d3a00fb072003200e3600f707200320083600f3072003200f3a00f207200320103b01f007200341d0016a200341a0036a200341f0076a201d201c10c40120032802d0012209450d0420032802d401210a0c070b41144101102e000b20034188016a41c2d5c000411610a30120034198016a290300212b200329039001212c2003280288012102200341c8056a41086a22084200370300200342003703c80541c2d5c0004116200341c8056a1003200341c8046a41086a2008290300370300200320032903c8053703c8042003427f202b420020021b222b201420157d2004201d54ad7d7c202c420020021b22152004201d7d7c221d2015542202ad7c221520022015202b542015202b511b22021b3703a8032003427f201d20021b3703a003200341a0036a21020b200341c8046a41102002411010050b200341f0076a2004201410a5010240024002400240411810322202450d00200241002900ecd540370000200241106a41002900fcd540370000200241086a41002900f4d5403700002003429880808080033702a403200320023602a003200341f0076a200341a0036a10810120032802a4032102200341f0006a20032802a003220620032802a80310a101200341f0006a41106a2903004200200328027022081b21042003290378420020081b211402402002450d00200610290b2014201c5422082004201b542004201b5122021b0d012014201c562004201b5620021b450d03200341d8006a41c2d5c000411610a301200341e8006a29030021152003290360211d20032802582102200341c8056a41086a22064200370300200342003703c80541c2d5c0004116200341c8056a1003200341c8046a41086a2006290300370300200320032903c8053703c804200342002015420020021b22152008ad201b20047d7c7c201d420020021b22042014201c7d221d54ad7d22142004201d7d221d200456201420155620142015511b22021b3703a80320034200201d20021b3703a003200341a0036a21020c020b41184101102e000b200341c0006a41c2d5c000411610a301200341d0006a29030021152003290348211d20032802402102200341c8056a41086a22084200370300200342003703c80541c2d5c0004116200341c8056a1003200341c8046a41086a2008290300370300200320032903c8053703c8042003427f2015420020021b2215201b20047d201c201454ad7d7c201d420020021b2204201c20147d7c22142004542202ad7c22042002200420155420042015511b22021b3703a8032003427f201420021b3703a003200341a0036a21020b200341c8046a41102002411010050b200341f0076a201c201b10bc010b410021090c020b41f8f8c20021094128210a0c010b41c8d8c30021094115210a0b410121084101210b0c0d0b10fb02000b024020032802fc072208450d0020032802f4072102200841246c210803400240024020022d0000220641034b0d0002400240024020060e0404000102040b2002410c6a280200450d03200241086a28020010290c030b2002410c6a280200450d02200241086a28020010290c020b2002410c6a280200450d01200241086a28020010290c010b200241086a280200450d00200241046a28020010290b200241246a21022008415c6a22080d000b0b024020032802f807450d0020032802f40710290b02402007200d460d0003402007280204220e450d01200741086a280200210f02402007410c6a2802002202450d00200241246c2108200e210203400240024020022d0000220641034b0d0002400240024020060e0404000102040b2002410c6a280200450d03200241086a28020010290c030b2002410c6a280200450d02200241086a28020010290c020b2002410c6a280200450d01200241086a28020010290c010b200241086a280200450d00200241046a28020010290b200241246a21022008415c6a22080d000b0b200741f0006a21070240200f450d00200e10290b2007200d470d000b0b02402005450d00201010290b02402004a7450d00200c10290b4100210b410121080c0b0b2007200d460d00034020072802042209450d01200741086a280200210a02402007410c6a2802002202450d00200241246c21082009210203400240024020022d0000220641034b0d0002400240024020060e0404000102040b2002410c6a280200450d03200241086a28020010290c030b2002410c6a280200450d02200241086a28020010290c020b2002410c6a280200450d01200241086a28020010290c010b200241086a280200450d00200241046a28020010290b200241246a21022008415c6a22080d000b0b200741f0006a21070240200a450d00200910290b2007200d470d000b0b02402005450d00201010290b200341c8056a41086a22024200370300200342003703c80541b6f0c2004111200341c8056a1003200341c8046a41086a2002290300370300200320032903c8053703c804200341f0076a200c2004422088a710fc02200341c8046a411020032802f007220220032802f8071005024020032802f407450d00200210290b02402004a7450d00200c10290b4100210b410121080c060b02402006450d002010200641f0006c6a210c20102107034002402007410c6a2802002208450d0020072802042102200841246c210803400240024020022d0000220641034b0d0002400240024020060e0404000102040b2002410c6a280200450d03200241086a28020010290c030b2002410c6a280200450d02200241086a28020010290c020b2002410c6a280200450d01200241086a28020010290c010b200241086a280200450d00200241046a28020010290b200241246a21022008415c6a22080d000b0b200741f0006a21020240200741086a280200450d00200728020410290b200221072002200c470d000b0b4100210b410121082005450d08201010290c080b4101210b0c070b41002112410021090c010b41002113410021090b4128210a4101210b4100210802402007417f6a220241054b0d0041012106410121074101210c4101210d4101210e4101210f410121104101211141012118410121194101211a024002400240024020020e06130013010203130b4100210841000d082004a70d070c080b4100210841000d072004a70d060c070b2013450d0602402004422088a72202450d00200241186c21062005210203400240200241046a280200450d00200228020010290b0240200241106a280200450d002002410c6a28020010290b200241186a2102200641686a22060d000b0b2004a70d050c060b2012450d0502402004422088a72202450d002002410c6c21062005210203400240200241046a280200450d00200228020010290b2002410c6a2102200641746a22060d000b0b2004a70d040c050b02402004422088a72202450d002002410c6c21062005210203400240200241046a280200450d00200228020010290b2002410c6a2102200641746a22060d000b0b2004a70d030c040b410021080b41012106410121074101210c4101210d4101210e4101210f410121104101211141012118410121190b4101211a410021090c0b0b200510290b410121060b410121070b4101210c0b4101210d0b4101210e0b4101210f0b410121100b410121110b410121180b410121194101211a0b024020012d0000220241124b0d00024002400240024002400240024002400240024002400240024020020e13000d0d010d0d020304050607080d090d0a0b0c000b2008450d0c0240200141086a280200220241054b0d0002400240024020020e06101000100102100b200141106a280200450d0f2001410c6a28020010290c0f0b200141106a280200450d0e2001410c6a28020010290c0e0b0240200141146a2802002208450d002001410c6a2802002102200841186c210803400240200241046a280200450d00200228020010290b0240200241106a280200450d002002410c6a28020010290b200241186a2102200841686a22080d000b0b200141106a280200450d0d200128020c10290c0d0b0240200141146a2802002208450d002001410c6a28020021022008410c6c210803400240200241046a280200450d00200228020010290b2002410c6a2102200841746a22080d000b0b200141106a280200450d0c200128020c10290c0c0b200b450d0b02402001410c6a2802002202450d00200141046a2802002207200241f0006c6a210c034002402007410c6a2802002208450d0020072802042102200841246c210803400240024020022d0000220641034b0d0002400240024020060e0404000102040b2002410c6a280200450d03200241086a28020010290c030b2002410c6a280200450d02200241086a28020010290c020b2002410c6a280200450d01200241086a28020010290c010b200241086a280200450d00200241046a28020010290b200241246a21022008415c6a22080d000b0b200741f0006a21020240200741086a280200450d00200728020410290b200221072002200c470d000b0b200141086a280200450d0b200128020410290c0b0b2006450d0a0240200141086a2d00002202410c4b0d0020024106470d0b200141106a280200450d0b2001410c6a28020010290c0b0b200141106a280200450d0a2001410c6a28020010290c0a0b2007450d09200141086a280200450d09200141046a28020010290c090b200c450d08200141086a2d0000417f6a220241074b0d08024002400240024020020e08000c0c0c0c010203000b2001410c6a2202280200102a200228020010290c0b0b2001410c6a2202280200102a200228020010290c0a0b2001410c6a2202280200102a200228020010290c090b2001410c6a2202280200102a200228020010290c080b200d450d07200141046a2d0000417f6a220241024b0d0702400240024020020e03000102000b2001410c6a280200450d09200141086a28020010290c090b200141086a2202280200102a200228020010290c080b2001410c6a2202280200102a200228020010290c070b200e450d06200141046a2d0000417f6a220241024b0d0602400240024020020e03000102000b2001410c6a280200450d08200141086a28020010290c080b200141086a2202280200102a200228020010290c070b2001410c6a2202280200102a200228020010290c060b200f450d05200141086a280200417f6a220241014b0d050240024020020e020001000b200141106a280200450d062001410c6a28020010290c060b200141106a280200450d052001410c6a28020010290c050b2010450d04200141046a2d00004104490d042001410c6a280200450d04200141086a28020010290c040b2011450d03200141086a280200450d03200141046a28020010290c030b2018450d02200141086a2d0000417e6a220241024b0d0202400240024020020e03000102000b200141106a280200450d042001410c6a28020010290c040b200141346a280200450d03200141306a28020010290c030b200141306a280200450d022001412c6a28020010290c020b2019450d01200141046a2802004101470d01200141086a2202280200102a200228020010290c010b201a450d0002402001410c6a280200450d00200141086a28020010290b02402001411c6a2802002208450d00200141146a28020021022008410c6c210803400240200241046a280200450d00200228020010290b2002410c6a2102200841746a22080d000b0b200141186a280200450d00200128021410290b2000200a3602042000200936020020034180096a24000bf90301077f230041306b22022400200241003602082002420137030020022002360210200141106a200241106a1085012001200210980120022002360210200141306a200241106a10850120022002360210200141d0006a200241106a108501200128020421032001410c6a2802002201200210660240024002402001450d00200141246c21040340200241106a2003109d01200228021021050240024020022802042206200228020822016b20022802182207490d00200228020021060c010b200120076a22082001490d0420064101742201200820082001491b22014100480d040240024020060d002001103221060c010b200228020020062001103421060b2006450d032002200136020420022006360200200228020821010b2002200120076a360208200620016a20052007109b051a02402002280214450d00200510290b200341246a21032004415c6a22040d000b0b200228020421072002280208210320022802002101200241106a41186a22064200370300200241106a41106a22054200370300200241106a41086a220442003703002002420037031020012003200241106a1000200041186a2006290300370000200041106a2005290300370000200041086a20042903003700002000200229031037000002402007450d00200110290b200241306a24000f0b20014101102e000b1033000bab0b030f7f037e027f230041c0006b22012400200028020821022000280204210320002802002104200141086a220042003703002001420037030041e0adc500411920011003200141206a41086a22052000290300370300200120012903003703202001200141206a10b40302400240200128020422060d00410421064100210741002108410021090c010b2001410c6a280200210720012802082108200128020021090b200042003703002001420037030041cebdc400411620011003200520002903003703002001200129030037032020014100360200200141206a41102001100621050240024020012802002200417f460d0020012000360234200120053602302001200141306a103102402001280200220a450d00200141086a280200210b2001280204210c2000450d02200510290c020b41f7cdc3004133200141386a41ecd6c3001054000b4100210c4101210a4100210b0b0240024002400240024002402002450d002004200241246c6a210d200a200b4105746a210e2004210503402005280220210f200541086a2900002110200541106a290000211120052900002112200141186a200541186a290000370300200141106a2011370300200141086a201037030020012012370300200541246a2105200a2100410021020240024003400240200e20006b41e0004b0d002000200e460d03034020012000460d032002200020014120109d05220b4100476a2102200b450d03200e200041206a2200470d000c040b0b20012000460d012002200020014120109d05220b4100476a2102200b450d01200041206a220b2001460d012002200b20014120109d05220b4100476a2102200b450d01200041c0006a220b2001460d012002200b20014120109d05220b4100476a2102200b450d01200041e0006a220b2001460d0120004180016a21002002200b20014120109d05220b4100476a2102200b0d000b0b2009200f6a22002009490d00024002402007200241016a220b490d002008210b0c010b02400240200820076b200b20072007200b491b221320076b2209490d002008210b0c010b200720096a220b2007490d0920084101742214200b200b2014491b220b41ffffffff0371200b470d09200b41027422144100480d090240024020080d002014103221060c010b200620084102742014103421060b2006450d050b200620074102746a21080240024020094102490d002008410020132007417f736a410274109a051a2013417f6a2107200620134102746a417c6a21080c010b2009450d010b20084100360200200741016a21070b200720024d0d04200620024102746a22022002280200200f6a360200200b2108200021090b2005200d470d000b0b02402003450d00200410290b0240200c450d00200a10290b200141086a220042003703002001420037030041e0adc500411920011003200141206a41086a2000290300370300200120012903003703202001410036020820014201370300410410322200450d022000200936000020014284808080c000370204200120003602002007200110660240024020070d00200128020821072001280204210e200128020021020c010b200741027421094100200128020822006b21052001280204210e2006210b0340200b280200210f02400240200e20056a4104490d00200128020021020c010b200041046a22022000490d07200e4101742207200220022007491b22074100480d0702400240200e0d002007103221020c010b2001280200200e2007103421020b2002450d0620012007360204200120023602002007210e0b200b41046a210b2001200041046a2207360208200220006a200f3600002005417c6a2105200721002009417c6a22090d000b0b200141206a41102002200710050240200e450d00200210290b02402008450d00200610290b200141c0006a24000f0b20144104102e000b4198acc500200220071036000b41044101102e000b20074101102e000b1033000b4d01017f230041206b22002400200041146a4101360200200042013702042000418c9ac5003602002000410536021c200041c09ac5003602182000200041186a360210200041ec9ac500107d000b8505010e7f230041e0006b220224002002410036023820014110200241386a1006210302400240024002400240024020022802382204417f470d00200041003602000c010b2002200436021420022003360210200241086a200241106a102c20022802080d04200228021422054160712201417f4c0d01200228020c210602400240200541057622070d00410121080c010b200110322208450d030b02402006450d004100210903402005210a200241003a00582009220b41016a2109410021010240024002400340200a2001460d01200241386a20016a2002280210220c2d00003a00002002200c41016a3602102002200141016a220c3a0058200c2101200c4120470d000b200241186a41186a220d200241386a41186a290300370300200241186a41106a220e200241386a41106a290300370300200241186a41086a220f200241386a41086a290300370300200220022903383703182007200b470d020240200b4101742201200920092001491b220741ffffff3f712007470d002007410574220141004e0d020b1033000b200241003602140240200141ff0171450d00200241003a00580b2007450d08200810290c080b02400240200b0d002001103221080c010b2008200b4105742001103421080b2008450d060b200a200c6b21052008200b4105746a22012002290318370000200141186a200d290300370000200141106a200e290300370000200141086a200f29030037000020092006470d000b2002200a200c6b3602140b2008450d042000200736020420002008360200200041086a20063602002004450d00200310290b200241e0006a24000f0b102f000b20014101102e000b20014101102e000b41f7cdc3004133200241386a41ecd6c3001054000b9c0201057f230041106b220324000240024002400240200141046a2204417f4c0d000240024020040d00410121050c010b200410322205450d020b2003410036020820032004360204200320053602002001200310660240024020032802042206200328020822056b2001490d00200328020021040c010b200520016a22042005490d0420064101742207200420042007491b22074100480d040240024020060d002007103221040c010b200328020020062007103421040b2004450d032003200736020420032004360200200721060b200420056a20002001109b051a200228020020022802042004200520016a100502402006450d00200410290b200341106a24000f0b102f000b20044101102e000b20074101102e000b1033000bca5d06067f017e107f067e0e7f097e23004190096b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e06000102030405000b200341dc016a4101360200200342013702cc012003418c9ac5003602c801200341053602c405200341c09ac5003602c0052003200341c0056a3602d801200341c8016a41e0b4c400107d000b200141e0006a2802002104200341c0056a200141086a41d800109b051a20034190046a41186a200141fc006a28020036020020034190046a41106a200141f4006a29020037030020034190046a41086a200141ec006a2902003703002003200141e4006a29020037039004024020022d000120022d000072450d0041f8f8c2002105412821040c060b200341f0066a41086a22024200370300200342003703f00641eeb1c5004118200341f0066a1003200341d8086a41086a2002290300370300200320032903f0063703d80841002102200341003602c801200341d8086a4110200341c8016a10062106024020032802c8012205417f460d00200320053602d407200320063602d007200341c8016a200341d0076a10ca0220032d00b8024102460d0720032802a00221022005450d00200610290b024020022004490d0041f0b4c4002105413521040c060b200341c8016a41086a41033a00002003410c3a00c801200341c8016a410c6a20043602004100210541014100200341c8016a104c200341c8016a200341c0056a41d800109b051a200341ac026a20034190046a41086a290300370200200341b4026a20034190046a41106a290300370200200341bc026a20034190046a41186a280200360200200320043602a00220032003290390043702a402200341f0066a41086a22024200370300200342003703f00641eeb1c5004118200341f0066a1003200341d8086a41086a2002290300370300200320032903f0063703d808200341003602d807200342013703d007200341c8016a200341d0076a10cc0220032802d4072102200341d8086a411020032802d007220420032802d80710052002450d04200410290c040b200141086a2802002107200141046a280200210841a0f9c2002105412a210420022d00000d1220022d00014101470d122001410c6a2802002105200141106a2903002109200241196a2d00002104200241186a2d00002106200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211920032002411a6a2901003703a803200320043a00a703200320063a00a6032003200a3b01a4032003200b3a00a3032003200c3a00a2032003200d3b01a0032003200e3a009f032003200f3a009e03200320103b019c03200320113a009b03200320183a009203200320193b01900320032014201341087420124118747272360097032003201720164108747220154118747236009303200341c8016a20034190036a200910e003024020032802c8014101470d0020032802d001210420032802cc0121050c130b200341e8016a290300211a200341c8016a41186a290300211b200341f8016a290300211c200341f0016a290300211d200341c8016a41106a290300210920032903d001211e200341f0066a41086a22024200370300200342003703f00641eeb1c5004118200341f0066a1003200341d8086a41086a2002290300370300200320032903f0063703d808200341003602c801200341d8086a4110200341c8016a1006210220032802c8012206417f460d072002450d0720032006360294042003200236029004200341c8016a20034190046a10ca0220032d00b80222044102460d06200341c0056a200341c8016a41f000109b051a2003200341bc026a220a2800003600d307200320032800b9023602d00702402006450d00200210290b200341c8016a200341c0056a41f000109b051a200a20032800d307360000200320032802d0073600b90220032903c801211f0c110b200141c0006a290300211c200141386a290300211e2002411a6a290100211f200241196a2d00002120200241186a2d00002121200241166a2f01002122200241156a2d00002123200241146a2d00002124200241126a2f01002125200241116a2d00002126200241106a2d000021272002410e6a2f010021282002410d6a2d00002129200241046a2d0000212a200241026a2f0100212b200141306a280200212c2001412c6a2802002108200141286a280200210c2001411d6a29000021092001411c6a2d0000210e2001411b6a2d0000210f200141196a2f00002110200141186a2d00002111200141176a2d00002112200141156a2f00002113200141146a2d00002114200141136a2d00002115200141116a2f00002116200141106a2d000021172001410c6a2802002118200141086a280200210b200141076a2d00002119200141056a2f0000212d200141046a2d0000210d200141c8006a290300211d41a0f9c2002105412a21040240024020022d0000450d00410121064100210a410021070c010b410121064100210a4100210720022d00014101470d002002410c6a2d000021072002410a6a2f0100210a200241096a2d00002104200241066a2f0100410874200241056a2d000072200241086a2d0000411874722105410021060b200a41ffff0371410874200441ff017172200741187472210420060d0f0240200d41ff01714101470d00200341c8016a200b41067610ab0220032802c80121060240024020032802d001200b413f7122024b0d00410021020c010b200620024105746a2202290018210920022d0017210e20022d0016210f20022f0014211020022d0013211120022d0012211220022f0010211320022d000f211420022d000e211520022f000c211620022d000b2117200228000721182002280003210b20022d0002211920022f0000212d410121020b024020032802cc01450d00200610290b20020d0041c8d8c3002105411521040c100b2003201f3703a001200320203a009f01200320213a009e01200320223b019c01200320233a009b01200320243a009a01200320253b019801200320263a009701200320273a009601200320283b019401200320293a0093012003200436008f012003200536008b012003202a3a008a012003202b3b018801200341c8016a20034188016a201d10e003024020032802c8014101470d0020032802d001210420032802cc0121052008450d0f200c10290c0f0b200341f8016a290300212e200341f0016a290300212f200341a8016a41186a200341e8016a290300370300200341a8016a41106a200341c8016a41186a290300370300200341a8016a41086a200341c8016a41106a290300370300200320032903d0013703a801200341f0066a41086a22024200370300200342003703f00641eeb1c5004118200341f0066a1003200341d8086a41086a2002290300370300200320032903f0063703d808200341003602c801200341d8086a4110200341c8016a1006210220032802c8012221417f460d082002450d08200320213602c405200320023602c005200341c8016a200341c0056a10ca0220032d00b80222054102460d0720032802b402210420032802b002210620032802ac02210a20032802a802210720032802a402210d20032802a0022120200329039802211f200329039002211d200329038802211b200329038002211a20032903f801213020032903f001213120032903e801213220032903e001213320032903d801213420032903d001213520032903c8012136200320032800b902360290042003200341bc026a2800003600930402402021450d00200210290b20032003280290043602c00520032003280093043600c3050c0d0b200141386a290300211d200141306a290300211c200141c0006a2903002109200341e8006a41186a200141196a290000370300200341e8006a41106a200141116a290000370300200341e8006a41086a200141096a290000370300200320012900013703682002411a6a290100211f200241196a2d0000210c200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d000021132002410e6a2f010021142002410d6a2d00002115200241046a2d00002116200241026a2f010021172001412c6a2802002118200141286a2802002108200141246a280200210b41a0f9c2002105412a21040240024020022d0000450d00410121064100210a410021070c010b410121064100210a4100210720022d00014101470d002002410c6a2d000021072002410a6a2f0100210a200241096a2d00002104200241066a2f0100410874200241056a2d000072200241086a2d0000411874722105410021060b200a41ffff0371410874200441ff017172200741187472210402402006450d002008450d0c200b10290c0c0b2003201f3703a0012003200c3a009f012003200d3a009e012003200e3b019c012003200f3a009b01200320103a009a01200320113b019801200320123a009701200320133a009601200320143b019401200320153a0093012003200436008f012003200536008b01200320163a008a01200320173b018801200341c8016a20034188016a200910e003024020032802c8014101470d0020032802d001210420032802cc0121052008450d0c200b10290c0c0b200341f8016a290300211f200341f0016a2903002109200341a8016a41186a200341e8016a290300370300200341a8016a41106a200341c8016a41186a290300370300200341a8016a41086a200341c8016a41106a290300370300200320032903d0013703a801200341f0066a41086a22024200370300200342003703f00641eeb1c5004118200341f0066a1003200341d8086a41086a2002290300370300200320032903f0063703d808200341003602c801200341d8086a4110200341c8016a1006210220032802c801220e417f460d092002450d092003200e3602c405200320023602c005200341c8016a200341c0056a10ca0220032d00b80222054102460d0820032802b402210420032802b002210620032802ac02210a20032802a802210720032802a402210c20032802a002210d200329039802211e200329039002211b200329038802211a200329038002213020032903f801213120032903f001213220032903e801213320032903e001213420032903d801213520032903d001213620032903c801212f200320032800b902360290042003200341bc026a280000360093040240200e450d00200210290b20032003280290043602c00520032003280093043600c3050c0a0b200341d0076a41186a200141196a290000370300200341d0076a41106a200141116a290000370300200341d0076a41086a200141096a290000370300200320012900013703d00720034190046a41206a200141c1006a2d00003a000020034190046a41186a200141396a29000037030020034190046a41106a200141316a29000037030020034190046a41086a200141296a2900003703002003200141216a29000037039004200341c8016a41086a2205200241096a290000370300200341c8016a41106a2204200241116a290000370300200341c8016a41186a2206200241196a290000370300200341c8016a41206a220a200241216a2d00003a000020034194036a2207200241266a2f01003b0100200320022900013703c8012003200241226a28010036029003024020022d00002202450d00200341c0056a41266a200328029003360100200341cd056a2005290300370000200341d5056a2004290300370000200341dd056a2006290300370000200341e5056a200a2d00003a0000200341ea056a20072f01003b0100200320023a00c405200320032903c8013700c505200341013a00c00541a5b5c400210541e90021040c020b200341c0056a41216a200a2d00003a0000200341c0056a41196a2006290300370000200341c0056a41116a2004290300370000200341c0056a41096a2005290300370000200320032903c80122093700c105200341003a00c00541a5b5c400210541e90021042009a741ff0171417f6a220241014b0d0102400240024020020e020100010b20032d0090044101470d0320034190046a4101722104410021020c010b20032d0090044101460d0241022102200341c0056a41027221040b41002105200341c8016a200341d0076a2002410010e30120032d00c8012102024020032d00d0010d00200341ec016a280200450d00200341e8016a28020010290b200241ff01714101470d00200341c8016a2004429601420010bf01024020032802c8014101470d0020032802d001210420032802cc0121050c020b200341c8016a41106a290300211f20032903d001211d200341d0006a41c2d5c000411610a301200341d0006a41106a29030021092003290358211c20032802502102200341f0066a41086a22044200370300200342003703f00641c2d5c0004116200341f0066a1003200341d8086a41086a2004290300370300200320032903f0063703d8082003427f201f2009420020021b22097c201d201c420020021b221f7c221d201f542202ad7c221f2002201f200954201f2009511b22021b370398032003427f201d20021b37039003200341d8086a411020034190036a411010050b0b4101210a410121060c0e0b41f7cdc300413320034188096a41ecd6c3001054000b41f7cdc300413320034188096a41ecd6c3001054000b41002104200341003602a002200341203602b402200342908080808080103702ac02200342848080808080c0003702a4024201211f20034201370398022003420137039002200342af0137038802200342870137038002200342013703f801200342013703f001200342013703e801200342013703e001200342013703d801200342013703d001200342013703c8010c090b41f7cdc300413320034188096a41ecd6c3001054000b428701211a42af01211b4201211f410021054104210d4180800421074110210a41808001210641202104410021204201211d420121304201213142012132420121334201213442012135420121360c040b41f7cdc300413320034188096a41ecd6c3001054000b428701213042af01211a4201211e410021054104210c4180800421074110210a418080012106412021044100210d4201211b4201213142012132420121334201213442012135420121364201212f0b200320053a00b802200320043602b402200320063602b0022003200a3602ac02200320073602a8022003200c3602a4022003200d3602a0022003201e370398022003201b370390022003201a370388022003203037038002200320313703f801200320323703f001200320333703e801200320343703e001200320353703d801200320363703d0012003202f3703c801200341c8026a4200370300200341f8026a4200370300200341e8026a4200370300200341d8026a4200370300200341bc026a20032800c30536000020034280888080808010370380032003428080e983b1de163703c00220034280a094a58d1d3703f00220034280a094a58d1d3703e00220034280a094a58d1d3703d002200320032802c0053600b9022003200341c8016a360288032003200341c8016a36028c03200341c0056a41186a220520034188016a41186a290300370300200341c0056a41106a220420034188016a41106a290300370300200341c0056a41086a220220034188016a41086a29030037030020032003290388013703c005200341c0006a41cc83c300410d10d5012003290348211e20032802402106200341386a41d983c300410d105d200341c8036a420037030020034190036a412c6a41a882c1003602004101212020034190036a41286a4101360200200341b0036a4200370300200341ac036a41b0d6c000360200200341e8036a2002290300370300200341f0036a2004290300370300200341f8036a20052903003703002003428080808080013703c0032003420037039803200320032903c0053703e0034100212d200341003602a80320032802382105200328023c210420032003418c036a3602d803200320034188036a3602d4032003200341c8016a3602d00320032004410020051b3602dc032003201e420020061b37039003200320183602980420032008360294042003200b36029004200341c0056a20034190036a201c201d200341a8016a200341e8006a20034190046a10da010240024020032802c0054101470d00200341cc056a290200221d422888211e201d422088211c2002280200210420032802c40521054101212d410121200c010b200341c0056a412c6a290200221d422888211e200341c0056a41286a2802002104200341e4056a2802002105201d422088221ca741ff01710d00200341c0056a41086a200341b0036a29030037030020034190046a41086a200341cc056a280200360200200320032903a8033703c005200320032902c4053703900420034188096a20034190046a10e1034100212d4200211c410021200b20034188016a20032903a80120032903b00120032903b801200341a8016a41186a2903002009201f10e20320032802cc03210620032802c803210a200320032802c4032202360288042003200a36028404200320023602800420032002200641b0016c6a220f36028c0402402006450d00200341d0076a4101722116200341f7066a2117200341d9076a2107200341f0066a4102722108200341c0056a41106a2118200341e8056a2115200341a4066a211120034181066a210b200341e1056a210c200341c0056a4101722110200341b8066a2119034020022d0000210620034190046a200241016a41af01109b051a0240024020064103460d00200320063a00c005201020034190046a41af01109b05210a024002400240024020060e03000102000b20032802c805210e20032802cc05210a20032802c40521062017201841d800109b051a2003410c3a00d0072016200341f0066a41df00109b051a2006200a200341d0076a104c4101210a4100210d0240200e450d00200610290b4100210e0c020b200341d8086a41186a2206200a41186a220d290000370300200341d8086a41106a220e200a41106a2212290000370300200341d8086a41086a2213200a41086a22142900003703002003200a2900003703d808200341d0076a2015418801109b051a2008200a290000370000200841086a2014290000370000200841106a2012290000370000200841186a200d29000037000020034180023b01f006200341306a200341d0076a200341f0066a10ee022003280230210a200720032903d808370000200741086a2013290300370000200741106a200e290300370000200741186a2006290300370000200341043a00d8072003410c3a00d0072003200a453a00f9074100210a4101210d41014100200341d0076a104c4100210e0c010b2019290300210920032903b006211f200341d8086a41186a200a41186a290000370300200341d8086a41106a200a41106a290000370300200341d8086a41086a200a41086a2900003703002003200a2900003703d808200341f0066a41186a200c41186a290000370300200341f0066a41106a200c41106a290000370300200341f0066a41086a200c41086a2900003703002003200c2900003703f006200341d0076a41186a200b41186a290000370300200341d0076a41106a200b41106a290000370300200341d0076a41086a200b41086a2900003703002003200b2900003703d007200341f8086a41086a201141086a280200360200200320112902003703f808200341d8086a200341f0066a200341d0076a201f2009200341f8086a10e3034101210d4101210a4101210e0b024020032d00c005220641014b0d000240024020060e020001000b200d450d03024020032802c805450d0020032802c40510290b20032d00d0054105490d0320032802f805450d0320032802f40510290c030b200a450d022015102a0c020b200e20032802a80645720d0120032802a40610290c010b2003200241b0016a360288040c020b200241b0016a2202200f470d000b2003200f360288040b20034180046a102802400240202d0d00024020040d00410021050c020b20051029410021050c010b024020050d00410021050c010b201e422886201c4220864280808080f01f8384500d00201da710290b0240200328029c032202450d00200341a0036a280200450d00200210290b2020450d0020034190036a411c6a280200210220032802b40321080240024020032802b003220a0d00200221060c010b200a210720022106034020062802880b21062007417f6a22070d000b0340200220022f01064102746a41880b6a2802002102200a417f6a220a0d000b0b200341c0056a411c6a20022f0106360200200341d8056a4100360200200341d4056a2002360200200320083602e005200341003602d005200342003703c805200320063602c405200341003602c005200341c0056a10cd010b410021074101210a410121060c060b200320053a00b802200320043602b402200320063602b0022003200a3602ac02200320073602a8022003200d3602a402200320203602a0022003201f370398022003201d370390022003201b370388022003201a37038002200320303703f801200320313703f001200320323703e801200320333703e001200320343703d801200320353703d001200320363703c801200341c8026a4200370300200341c8016a41b0016a4200370300200341e8026a4200370300200341d8026a4200370300200341bc026a20032800c30536000020034280888080808010370380032003428080e983b1de163703c00220034280a094a58d1d3703f00220034280a094a58d1d3703e00220034280a094a58d1d3703d002200320032802c0053600b9022003200341c8016a360288032003200341c8016a36028c03200341c0056a41186a220220034188016a41186a290300370300200341c0056a41106a220520034188016a41106a290300370300200341c0056a41086a220420034188016a41086a29030037030020032003290388013703c005200341206a41cc83c300410d10d5012003290328211f20032802202106200341186a41d983c300410d105d200341c8036a4200370300200341bc036a41a882c10036020041012120200341b8036a4101360200200341b0036a4200370300200341ac036a41b0d6c000360200200341e8036a2004290300370300200341f0036a2005290300370300200341f8036a20022903003703002003428080808080013703c0032003420037039803200320032903c0053703e003200341003602a80320032802182102200328021c210520032003418c036a3602d803200320034188036a3602d4032003200341c8016a3602d00320032005410020021b3602dc032003201f420020061b37039003200320093703d8052003200e3a00d7052003200f3a00d605200320103b01d405200320113a00d305200320123a00d205200320133b01d005200320143a00cf05200320153a00ce05200320163b01cc05200320173a00cb05200320183600c7052003200b3600c305200320193a00c2052003202d3b01c0052003202c3602980420032008360294042003200c36029004200341e8006a20034190036a200341c0056a201e201c200341a8016a20034190046a10e2010240200328026822180d00200341e8006a41106a2d00000d00200341c0056a41086a200341b0036a29030037030020034190046a41086a200341cc056a280200360200200320032903a8033703c005200320032902c4053703900420034188096a20034190046a10e103410021200b20034188016a20032903a80120032903b00120032903b801200341a8016a41186a290300202f202e10e20320032802cc03210520032802c8032104200320032802c4032202360288042003200436028404200320023602800420032002200541b0016c6a220d36028c0402402005450d00200341d0076a4101722114200341f7066a2115200341d9076a2106200341f0066a410272210a200341c0056a41106a2116200341e8056a2113200341a4066a210f20034181066a2107200341e1056a2108200341c0056a410172210e200341b8066a2117034020022d0000210520034190046a200241016a41af01109b051a0240024020054103460d00200320053a00c005200e20034190046a41af01109b052104024002400240024020050e03000102000b20032802c805210c20032802cc05210420032802c40521052015201641d800109b051a2003410c3a00d0072014200341f0066a41df00109b051a20052004200341d0076a104c410121044100210b0240200c450d00200510290b4100210c0c020b200341d8086a41186a2205200441186a220b290000370300200341d8086a41106a220c200441106a2210290000370300200341d8086a41086a2211200441086a2212290000370300200320042900003703d808200341d0076a2013418801109b051a200a2004290000370000200a41086a2012290000370000200a41106a2010290000370000200a41186a200b29000037000020034180023b01f006200341106a200341d0076a200341f0066a10ee0220032802102104200620032903d808370000200641086a2011290300370000200641106a200c290300370000200641186a2005290300370000200341043a00d8072003410c3a00d00720032004453a00f907410021044101210b41014100200341d0076a104c4100210c0c010b2017290300210920032903b006211f200341d8086a41186a200441186a290000370300200341d8086a41106a200441106a290000370300200341d8086a41086a200441086a290000370300200320042900003703d808200341f0066a41186a200841186a290000370300200341f0066a41106a200841106a290000370300200341f0066a41086a200841086a290000370300200320082900003703f006200341d0076a41186a200741186a290000370300200341d0076a41106a200741106a290000370300200341d0076a41086a200741086a290000370300200320072900003703d007200341f8086a41086a200f41086a2802003602002003200f2902003703f808200341d8086a200341f0066a200341d0076a201f2009200341f8086a10e3034101210b410121044101210c0b024020032d00c005220541014b0d000240024020050e020001000b200b450d03024020032802c805450d0020032802c40510290b20032d00d0054105490d0320032802f805450d0320032802f40510290c030b2004450d022013102a0c020b200c20032802a80645720d0120032802a40610290c010b2003200241b0016a360288040c020b200241b0016a2202200d470d000b2003200d360288040b20034180046a1028200341f0006a2802002104200328026c21050240024020180d00024020040d00410021050c020b20051029410021050c010b024020050d00410021050c010b200341f4006a2902002209428080808010540d002009a710290b0240200328029c032202450d00200341a0036a280200450d00200210290b2020450d0020034190036a411c6a280200210220032802b40321080240024020032802b003220a0d00200221060c010b200a210720022106034020062802880b21062007417f6a22070d000b0340200220022f01064102746a41880b6a2802002102200a417f6a220a0d000b0b200341c0056a411c6a20022f0106360200200341d8056a4100360200200341d4056a2002360200200320083602e005200341003602d005200342003703c805200320063602c405200341003602c005200341c0056a10cd010b410021064101210a0c030b410021064101210a2008450d02200c10290c020b2003201f42002005ad420010a005200320043a00b80242002009427f200329030020032903084200521b7d221f201f20095622021b21090240024002402002450d004190d9c2002105412c21040c010b200341c0056a20082005200341c8016a10c702024020032802c0054101470d00200341c8056a280200210420032802c40521050c010b200341d8086a41186a220d200341c0056a410472220241186a280200360200200341d8086a41106a220e200241106a290200370300200341d8086a41086a220f200241086a290200370300200320022902003703d808200341c0056a41186a22064200370300200341c0056a41106a220b4200370300200341c0056a41086a220c4200370300200342003703c00520082005200341c0056a10002003418a016a20032d00c20522023a0000200341a8016a41086a2210200341c0056a41136a290000370300200341b5016a22112006290000370000200320032f01c00522123b018801200320032900cb05221f3703a80120032800c305210a20032800c7052104200341d0076a41136a2010290300370000200341d0076a41186a2011290000370000200320023a00d207200320123b01d007200320043600d7072003200a3600d3072003201f3700db07200341f0066a41186a200d280200360200200341f0066a41106a200e290300370300200341f0066a41086a200f290300370300200320032903d8083703f00602400240411410322202450d00200241002900e5f943370000200241106a41002800f5f943360000200241086a41002900edf94337000020034294808080c0023702c405200320023602c0052003200341c0056a36029004200341d0076a20034190046a10850120032802c405210d20032802c005210220032802c805210e20064200370300200b4200370300200c4200370300200342003703c0052002200e200341c0056a100020034190046a41186a200629030037030020034190046a41106a200b29030037030020034190046a41086a200c290300370300200320032903c00537039004200341203602c405200320034190046a3602c005200341f0066a200341c0056a10c8020240200d450d00200210290b024020034180076a280200450d0020032802fc0610290b200341e3076a200341a8016a41086a290300370000200341d0076a41186a200341a8016a410d6a29000037000020032003418a016a2d00003a00d207200320032f0188013b01d007200320043600d7072003200a3600d307200320032903a8013700db07411510322202450d01200241002900d0f9433700002002410d6a41002900ddf943370000200241086a41002900d8f94337000020034295808080d0023702c405200320023602c0052003200341c0056a36029004200341d0076a20034190046a10850120032802c405210620032802c005210220032802c805210b200341c0056a41186a220c4200370300200341c0056a41106a220d4200370300200341c0056a41086a220e4200370300200342003703c0052002200b200341c0056a100020034190046a41186a200c29030037030020034190046a41106a200d29030037030020034190046a41086a200e290300370300200320032903c00537039004200341203602c405200320034190046a3602c00520082005200341c0056a10f30202402006450d00200210290b02402007450d00200810290b200341f0066a41026a20034188016a41026a2d000022023a000020034190046a41086a2205200341a8016a41086a29030037030020034190046a410d6a2206200341a8016a410d6a290000370000200320032f01880122073b01f006200320032903a80137039004200341c0056a41086a41023a0000200341c9056a20073b0000200341cb056a20023a0000200341d0056a20043602002003410c3a00c005200341c0056a410c6a200a360200200341d4056a200329039004370200200341dc056a2005290300370200200341e1056a20062900003700004100210541014100200341c0056a104c20034190036a201e2009201b201a201d201c10e2030c030b41144101102e000b41154101102e000b02402007450d00200810290b20034190036a201e2009201b201a201d201c10e2030b410121064100210a0c010b410121064100210a2007450d00200810290b410121070b024020012d0000417e6a220241024b0d00024002400240024020020e03000102000b200a450d03200141086a280200450d03200141046a28020010290c030b20060d010c020b2007450d01200141286a280200450d01200141246a28020010290c010b2001412c6a280200450d00200141286a28020010290b200020043602042000200536020020034190096a24000bc738030a7f077e067f230022042105200441e0016b41607122042400024002400240024002400240200141ffffff3f712001470d0020014105742206417f4c0d000240024020060d00410121070c010b200610322207450d020b410021084100210602402001450d002001410574210820072106034020062000290000370000200641186a200041186a290000370000200641106a200041106a290000370000200641086a200041086a290000370000200641206a2106200041206a2100200841606a22080d000b200141057441606a41057641016a2106200121080b20042006360218200420083602142004200736021020072006200441d8016a410041202006676b10d30120044180016a41086a220042003703002004420037038001418fddc300411d20044180016a1003200441a0016a41086a200029030037030020042004290380013703a0012004410036028001200441a0016a411020044180016a10062100024002402004280280012208417f460d002000450d00200420083602442004200036024020044180016a200441c0006a10312004280280012209450d0420044188016a2802002106200428028401210a2008450d01200010290c010b4100210a41012109410021060b2006410574220b450d05200441a0016a411472210c200441a0016a410872210d200921000340200041086a290000210e200041106a290000210f20002900002110200441206a41186a200041186a290000370300200441206a41106a200f370300200441206a41086a200e37030020042010370320200441c0006a200441206a10b203200441003602a80120042903582110200420042903b801221137035820042903502112200420042903b001221337035020042903402114200420042903a0013703402004290348210e200420042903a801220f3703482013422088a72115200f422088a721012011a72107200fa721060240200ea72208450d00200420143703a0012004200e3703a801200420123703b001200420103703b801200420082012a74105746a36028c0120042008360288012004200e422088a73602840120042008360280012004200441106a36029001200441f0006a20044180016a1048200d41086a200441f0006a41086a2216280200360200200d200429037037020020042012422088a722082010422088a74105746a36028c01200420083602880120042010a73602840120042008360280012004200441106a36029001200441f0006a20044180016a1048200c41086a2016280200360200200c200429037037020020042903a801210e20042903a001211220042903b801210f20042903b001211002402006450d0002402001450d00200610290b2007450d00201510290b200420123703402004200e370348200e422088a72101200420103703502010422088a721152004200f370358200ea72106200fa721070b0240024020060d00411a10322206450d06200641002900acdd43370000200641186a41002f00c4dd433b0000200641106a41002900bcdd43370000200641086a41002900b4dd433700002004429a808080a0033702a401200420063602a0012004200441a0016a36028001200441206a20044180016a10850120042802a401210820042802a001210620042802a8012101200441a0016a41186a22074200370300200441a0016a41106a22154200370300200441a0016a41086a22164200370300200442003703a00120062001200441a0016a100020044180016a41186a200729030037030020044180016a41106a201529030037030020044180016a41086a2016290300370300200420042903a0013703800120044180016a412010042008450d01200610290c010b411a10322208450d06200841002900acdd43370000200841186a41002f00c4dd433b0000200841106a41002900bcdd43370000200841086a41002900b4dd433700002004429a808080a0033702a401200420083602a0012004200441a0016a36028001200441206a20044180016a10850120042802a401211620042802a001210820042802a8012117200441a0016a41186a22184200370300200441a0016a41106a22194200370300200441a0016a41086a221a4200370300200442003703a00120082017200441a0016a100020044180016a41186a201829030037030020044180016a41106a201929030037030020044180016a41086a201a290300370300200420042903a0013703800120044180016a200441c0006a10b00302402016450d00200810290b02402001450d00200610290b2007450d00201510290b200041206a2100200b41606a220b0d000c060b0b102f000b20064101102e000b41f7cdc3004133200441d8016a41ecd6c3001054000b411a4101102e000b411a4101102e000b0240200a450d00200910290b200441003602a801200442013703a0012003200441a0016a106602400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402003450d00200220034105746a210103400240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d03200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a20022d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d04200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241016a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d05200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241026a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d06200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241036a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d07200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241046a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d08200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241056a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d09200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241066a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d0a200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241076a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d0b200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241086a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d0c200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241096a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d0d200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002410a6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d0e200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002410b6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d0f200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002410c6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d10200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002410d6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d11200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002410e6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d12200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002410f6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d13200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241106a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d14200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241116a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d15200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241126a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d16200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241136a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d17200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241146a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d18200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241156a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d19200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241166a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d1a200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241176a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d1b200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241186a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d1c200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a200241196a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d1d200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002411a6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d1e200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002411b6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d1f200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002411c6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d20200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002411d6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d21200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002411e6a2d00003a00000240024020042802a40120042802a8012200460d0020042802a00121060c010b200041016a22062000490d2320004101742208200620062008491b22084100480d230240024020000d002008103221060c010b20042802a00120002008103421060b2006450d22200420083602a401200420063602a00120042802a80121000b2004200041016a3602a801200620006a2002411f6a2d00003a0000200241206a22022001470d000b0b20042802a401210020042802a801210620042802a001210220044180016a41086a2208420037030020044200370380014189d6c300411b20044180016a1003200441a0016a41086a200829030037030020042004290380013703a001200441a0016a411020022006100502402000450d00200210290b02402004280214450d00200428021010290b200524000f0b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b1033000bb30901177f230041206b220424002002410020031b21052000410020011b2106200241206a200220031b2107200041206a200020011b2108200020014105746a2109200220034105746a210a4100210b4100210c4101210d4100210e4100210f4101211002400340200b4101742111200b410574211202400240024002400340024020050d0020072113200d2114200c2115200b21160c030b2005210220072103200d2114200c2115200b2116201221172011211802400340024002402006450d0020022006460d05200220064120109d052213450d052013417f4c0d01200321072014210d2015210c2016210b200221050c070b200441186a2203200541186a290000370300200441106a2216200541106a290000370300200441086a2206200541086a290000370300200420052900003703000240200b200c470d00200b41016a2202200b490d08200b4101742217200220022017491b220c41ffffff3f71200c470d08200c41057422024100480d0802400240200b0d0020021032210d0c010b200d200b41057420021034210d0b200d450d030b200d200b4105746a22022004290300370000200241186a2003290300370000200241106a2016290300370000200241086a200629030037000041002106410020072007200a4622021b2105201141026a2111201241206a2112200b41016a210b2007200741206a20021b21070c030b200441186a2213200241186a290000370300200441106a2219200241106a290000370300200441086a221a200241086a29000037030020042002290000370300024020162015470d00201641016a22022016490d072018200220022018491b221541ffffff3f712015470d07201541057422024100480d070240024020160d002002103221140c010b201420172002103421140b20140d0020024101102e000b201420176a22022004290300370000200241186a2013290300370000200241106a2019290300370000200241086a201a290300370000410020032003200a4622131b2102201841026a2118201741206a2117201641016a21162003200341206a20131b221321032002450d040c000b0b0b20024101102e000b2014210d2015210c2016210b2003200341206a2003200a4622021b210741002008200820094622161b21064100200320021b21052008200841206a20161b21080c030b41002105024020060d00201420162000200110f50202402015450d00201410290b0240200f450d00201010290b200441206a24000f0b201321072014210d2015210c2016210b0b200441186a2203200641186a290000370300200441106a2216200641106a290000370300200441086a2217200641086a290000370300200420062900003703000240200e200f470d00200e41016a2202200e490d01200e4101742206200220022006491b220f41ffffff3f71200f470d01200f41057422024100480d0102400240200e0d002002103221100c010b2010200e4105742002103421100b2010450d030b2010200e4105746a22022004290300370000200241186a2003290300370000200241106a2016290300370000200241086a201729030037000041002008200820094622021b2106200e41016a210e2008200841206a20021b21080c010b0b1033000b20024101102e000b865402157f037e230041c0056b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d000022040e050001020304000b200341bc046a4101360200200342013702ac042003418c9ac5003602a804200341053602a403200341c09ac5003602a0032003200341a0036a3602b804200341a8046a41dcf0c300107d000b200141086a2802002105200141046a2802002106024020022d000120022d000072450d0041f8f8c200210741282108410021094101210a02402005450d00200610290b410121060c1a0b20062001410c6a280200220210cc01200341a8046a41086a22074200370300200342003703a8044189d6c300411b200341a8046a1003200341a0036a41086a2007290300370300200320032903a8043703a003200341003602a804200341a0036a4110200341a8046a1006210820032802a8042207417f460d04200320073602fc01200320083602f801200341a8046a200341f8016a103120032802a8042209450d03200341b0046a280200210a20032802ac04210b02402007450d00200810290b200620022009200a10f602200b450d18200910290c180b200141046a280200210941a0f9c2002107412a210820022d00000d1620022d00014101470d16200241196a2d00002107200241186a2d00002108200241166a2f0100210a200241156a2d00002106200241146a2d00002105200241126a2f0100210b200241116a2d0000210c200241106a2d0000210d2002410e6a2f0100210e2002410d6a2d0000210f2002410c6a2d000021102002410a6a2f01002111200241096a2d00002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f0100211720032002411a6a29010037038801200320073a008701200320083a0086012003200a3b018401200320063a008301200320053a0082012003200b3b0180012003200c3a007f2003200d3a007e2003200e3b017c2003200f3a007b200320163a0072200320173b01702003201220114108742010411874727236007720032015201441087472201341187472360073200341a8046a41086a22024200370300200342003703a8044189d6c300411b200341a8046a1003200341a0036a41086a2002290300370300200320032903a8043703a003200341003602a804200341a0036a4110200341a8046a100621070240024020032802a8042202417f460d00200320023602fc01200320073602f801200341a8046a200341f8016a103120032802a8042208450d06200341b0046a280200210a20032802ac04210602402002450d00200710290b2008200a200341f0006a109203210202402006450d00200810290b2002450d010c160b41014100200341f0006a1092030d150b41ecf0c3002107411521080c160b200141086a2802002109200141046a28020021172002411a6a2901002118200241196a2d0000210b200241186a2d0000210c200241166a2f0100210d200241156a2d0000210e200241146a2d0000210f200241126a2f01002110200241116a2d00002111200241106a2d000021122002410e6a2f010021132002410d6a2d00002114200241046a2d00002115200241026a2f0100211641a0f9c2002107412a21080240024020022d0000450d004101210a41002106410021050c010b4101210a410021064100210520022d00014101470d002002410c6a2d000021052002410a6a2f01002106200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d00004118747221074100210a0b200641ffff0371410874200841ff0171722005411874722108200a0d12200320183703682003200b3a00672003200c3a00662003200d3b01642003200e3a00632003200f3a0062200320103b0160200320113a005f200320123a005e200320133b015c200320143a005b2003200836005720032007360053200320153a0052200320163b0150200341a8046a41086a22024200370300200342003703a8044189d6c300411b200341a8046a1003200341a0036a41086a2002290300370300200320032903a8043703a003200341003602a804200341a0036a4110200341a8046a100621020240024020032802a8042207417f460d002002450d00200320073602fc01200320023602f801200341a8046a200341f8016a103120032802a8042208450d06200341b0046a280200210a20032802ac04210602402007450d00200210290b2008200a200341d0006a109203210202402006450d00200810290b2002450d010c0a0b41014100200341d0006a1092030d090b41ecf0c3002107411521080c120b200141216a2d00002117200141246a2802002116200341306a41186a200141196a290000370300200341306a41106a200141116a290000370300200341306a41086a200141096a290000370300200320012900013703302002411a6a2901002118200241196a2d00002105200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d00002113200241046a2d00002114200241026a2f0100211541a0f9c2002107412a21080240024020022d0000450d00410121094100210a410021060c010b410121094100210a4100210620022d00014101470d002002410c6a2d000021062002410a6a2f0100210a200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d0000411874722107410021090b200a41ffff0371410874200841ff017172200641187472210820090d0620032018370368200320053a00672003200b3a00662003200c3b01642003200d3a00632003200e3a00622003200f3b0160200320103a005f200320113a005e200320123b015c200320133a005b2003200836005720032007360053200320143a0052200320153b0150200341a8046a41086a22024200370300200342003703a8044189d6c300411b200341a8046a1003200341a0036a41086a2002290300370300200320032903a8043703a003200341003602a804200341a0036a4110200341a8046a100621020240024020032802a8042207417f460d002002450d00200320073602fc01200320023602f801200341a8046a200341f8016a103120032802a8042208450d06200341b0046a280200210920032802ac04210a02402007450d00200210290b20082009200341d0006a10920321020240200a450d00200810290b2002450d010c070b41014100200341d0006a1092030d060b41f2f1c3002107411221080c060b41f7cdc3004133200341b8056a41ecd6c3001054000b200620024101410010f6020c130b41f7cdc3004133200341b8056a41ecd6c3001054000b41f7cdc3004133200341b8056a41ecd6c3001054000b41f7cdc3004133200341b8056a41ecd6c3001054000b200341a8046a200341306a10b203024020032802b00422090d0041dff1c3002107411321080c010b200341c0046a2802002105200341bc046a280200210a4110210820032802b404210b4184f2c30021070240201620032802a8042212470d00200341c4046a280200210c20032802ac0421132009200341a8046a41106a280200220d4105746a21074100210e2009210241002108024002400240200d4104490d00200341306a2106200341706a2110200341106a210f41002108200921020340200341d0006a2002460d022002200341d0006a4120109d05450d020240024020062002460d00200241206a200341d0006a4120109d050d010b200841016a21080c030b02400240200f2002460d00200241c0006a200341d0006a4120109d050d010b200841026a21080c030b024020102002460d00200241e0006a200341d0006a4120109d05450d00200841046a2108200720024180016a22026b41e0004b0d010c020b0b200841036a21080c010b20022007460d012009200d4105746a21070340200341d0006a2002460d012002200341d0006a4120109d05450d01200841016a21082007200241206a2202470d000c020b0b4101210e0b200a200c4105746a210641002110200a210241002107024002400240200c4104490d00200341306a210f200341706a2114200341106a211141002107200a21020340200341d0006a2002460d022002200341d0006a4120109d05450d0202400240200f2002460d00200241206a200341d0006a4120109d050d010b200741016a21070c030b0240024020112002460d00200241c0006a200341d0006a4120109d050d010b200741026a21070c030b024020142002460d00200241e0006a200341d0006a4120109d05450d00200741046a2107200620024180016a22026b41e0004b0d010c020b0b200741036a21070c010b20022006460d010340200341d0006a2002460d012002200341d0006a4120109d05450d01200741016a21072006200241206a2202470d000c020b0b410121100b024002400240024002400240024002400240201741ff01710d002010450d010c080b200e0d07200341a8046a41186a2206200341d0006a41186a290300370300200341a8046a41106a220e200341d0006a41106a290300370300200341a8046a41086a220f200341d0006a41086a290300370300200320032903503703a8040240200d200b460d00200b2108200d210b0c020b200b41016a2202200b490d0b200b4101742208200220022008491b220841ffffff3f712008470d0b200841057422024100480d0b02400240200b0d002002103221090c010b2009200b4105742002103421090b20090d0120024101102e000b200341a8046a41186a2206200341d0006a41186a290300370300200341a8046a41106a220f200341d0006a41106a290300370300200341a8046a41086a2210200341d0006a41086a290300370300200320032903503703a80402400240200c2005460d0020052107200c21050c010b200541016a22022005490d0b20054101742207200220022007491b220741ffffff3f712007470d0b200741057422024100480d0b0240024020050d0020021032210a0c010b200a200541057420021034210a0b200a0d0020024101102e000b200a20054105746a220220032903a804370000200241186a2006290300370000200241106a200f290300370000200241086a2010290300370000200c41016a210c02400240200e450d00200d20084d0d012009200d417f6a220d4105746a22022900002118200229000821192002290010211a200920084105746a220841186a200241186a2900003700002008201a37001020082019370008200820183700000b20072105200b21080c020b4180dbc3002008200d1036000b2009200b4105746a220220032903a804370000200241186a2006290300370000200241106a200e290300370000200241086a200f290300370000200d41016a210d2010450d00200c20074d0d01200a200c417f6a220c4105746a22022900002118200229000821192002290010211a200a20074105746a220741186a200241186a2900003700002007201a37001020072019370008200720183700000b200341cd046a2003290330370000200341b5046a200341d0006a41086a290300370000200341bd046a200341d0006a41106a290300370000200341c5046a200341d0006a41186a290300370000200341d5046a200341306a41086a290300370000200341dd046a200341306a41106a290300370000200341e5046a200341306a41186a290300370000200341013a00ac04200341073a00a804200320032903503700ad04200341f4046a200c360200200341f0046a200d360200200341ed046a20173a000041014100200341a8046a104c200341a8046a41086a22024200370300200342003703a8044189d6c300411b200341a8046a1003200341a0036a41086a2002290300370300200320032903a8043703a003200341003602a804200341a0036a4110200341a8046a1006210720032802a8042206417f460d022007450d02200320063602fc01200320073602f801200341a8046a200341f8016a103120032802a804220e450d01200341b0046a280200210220032802ac04210b02402006450d00200710290b200b450d03200e10290c030b4180dbc3002007200c1036000b41f7cdc3004133200341b8056a41ecd6c3001054000b410021020b024002400240024002400240024002400240200d20134f22060d0041002002200c6b2207200720024b1b2013490d00200341c4046a200c360200200341a8046a41186a2005360200200341a8046a41106a200d360200200341b4046a20083602002003200a3602bc04200320093602b004200320133602ac04200320123602a804411a10322202450d01200241002900acdd43370000200241186a41002f00c4dd433b0000200241106a41002900bcdd43370000200241086a41002900b4dd433700002003429a808080a0033702a403200320023602a0032003200341a0036a3602f801200341306a200341f8016a10850120032802a403210720032802a003210220032802a8032106200341a0036a41186a220b4200370300200341a0036a41106a220c4200370300200341a0036a41086a220d4200370300200342003703a00320022006200341a0036a100020034180036a41186a200b29030037030020034180036a41106a200c29030037030020034180036a41086a200d290300370300200320032903a0033703800320034180036a200341a8046a10b00302402007450d00200210290b02402008450d00200910290b20050d050c060b024020060d00200341b5046a200341386a290300370000200341bd046a200341c0006a290300370000200341c5046a200341c8006a290300370000200341033a00ac04200341073a00a804200320032903303700ad0441014100200341a8046a104c0c040b200341b5046a200341306a41086a290300370000200341bd046a200341306a41106a290300370000200341c5046a200341306a41186a290300370000200341023a00ac04200341073a00a804200320032903303700ad0441014100200341a8046a104c411e10322207450d01200741002900a0f143370000200741166a41002900b6f143370000200741106a41002900b0f143370000200741086a41002900a8f1433700002003429e808080e0033702ac04200320073602a8042003200341a8046a3602a003200341306a200341a0036a10850120032802ac04210c20032802a804210720032802b0042106200341a0036a41186a220b4200370300200341a0036a41106a220d4200370300200341a0036a41086a220e4200370300200342003703a00320072006200341a0036a100020034180036a41186a200b29030037030020034180036a41106a200d29030037030020034180036a41086a200e290300370300200320032903a00337038003200341003602a80420034180036a4120200341a8046a1006210b0240024020032802a804220d417f470d00411321060c010b0240200b0d00411321060c010b2003200d3602b4052003200b3602b005200341a8046a200341b0056a104f20032d00a80422064113460d03200341a0036a200341a8046a410172418701109b051a0240200d450d00200b10290b20034180036a412010040b200341f8016a200341a0036a418701109b051a024020064113470d00200c450d04200710290c040b200341f0006a200341f8016a418701109b051a0240200c450d00200710290b200320063a00a804200341a8046a410172200341f0006a418701109b051a200341ac036a2002360200200341a0036a41086a2013360200200341003a00a403200341023a00a003200341286a200341a8046a200341a0036a10ee0220032802282102200341b5046a200341306a41086a290300370000200341bd046a200341c0006a290300370000200341c5046a200341c8006a290300370000200341cd046a2002453a0000200341043a00ac04200341073a00a804200320032903303700ad0441014100200341a8046a104c0c030b411a4101102e000b411e4101102e000b41f7cdc3004133200341b8056a41ecd6c3001054000b411a10322202450d02200241002900acdd43370000200241186a41002f00c4dd433b0000200241106a41002900bcdd43370000200241086a41002900b4dd433700002003429a808080a0033702ac04200320023602a8042003200341a8046a3602a003200341306a200341a0036a10850120032802ac04210620032802a804210720032802b004210b200341a0036a41186a220c4200370300200341a0036a41106a220d4200370300200341a0036a41086a22024200370300200342003703a0032007200b200341a0036a100020034180036a41186a200c29030037030020034180036a41106a200d29030037030020034180036a41086a2002290300370300200320032903a0033703800320034180036a4120100402402006450d00200710290b200341a8046a41086a22074200370300200342003703a804418fddc300411d200341a8046a100320022007290300370300200320032903a8043703a003200341003602a804200341a0036a4110200341a8046a100621070240024020032802a8042202417f460d00200320023602fc01200320073602f801200341a8046a200341f8016a103120032802a8042206450d0520032902ac04211802402002450d00200710290b200320183702fc01200320063602f8010c010b2003410036028002200342013703f8010b200341f8016a200341306a1035200341a8046a41086a22024200370300200342003703a804418fddc300411d200341a8046a1003200341a0036a41086a2002290300370300200320032903a8043703a00320032802f80121062003280280022102200341003602b004200342013703a8042002200341a8046a106602402002450d00200241057421072006210203402003200341a8046a3602702002200341f0006a108501200241206a2102200741606a22070d000b0b20032802ac042102200341a0036a411020032802a804220720032802b004100502402002450d00200710290b024020032802fc01450d00200610290b02402008450d00200910290b2005450d010b200a10290b410021070c040b411a4101102e000b41f7cdc3004133200341b8056a41ecd6c3001054000b4194f2c3002107411621080b0240200b450d00200910290b2005450d00200a10290b4101210a41012106410121090c0f0b200341003602b004200342013703a8042009200341a8046a105f20032802ac04210720032802b004210820032802a8042102200341a0036a41186a220a4200370300200341a0036a41106a22064200370300200341a0036a41086a22054200370300200342003703a00320022008200341a0036a1000200341f0006a41186a2208200a290300370300200341f0006a41106a220a2006290300370300200341f0006a41086a22062005290300370300200320032903a00337037002402007450d00200210290b200341a8046a41186a2008290300370300200341a8046a41106a200a290300370300200341a8046a41086a2006290300370300200320032903703703a804411e10322202450d01200241002900a0f143370000200241166a41002900b6f143370000200241106a41002900b0f143370000200241086a41002900a8f1433700002003429e808080e0033702a403200320023602a0032003200341a0036a3602f801200341a8046a200341f8016a10850120032802a403210720032802a003210220032802a8032108200341a0036a41186a220a4200370300200341a0036a41106a22064200370300200341a0036a41086a22054200370300200342003703a00320022008200341a0036a100020034180036a41186a200a29030037030020034180036a41106a200629030037030020034180036a41086a2005290300370300200320032903a0033703800320034180036a41204101410041001007210802402007450d00200210290b2008417f470d020240024020174102490d00200341206a41bef1c3004121105d2003280224210620032802202105200341186a41bef1c3004121105d20032802182107200328021c2108200341a8046a41086a22024200370300200342003703a80441bef1c3004121200341a8046a1003200341a0036a41086a220a2002290300370300200320032903a8043703a0032003200841016a410120071b3602a804200341a0036a4110200341a8046a4104100520024200370300200342003703a804418fddc300411d200341a8046a1003200a2002290300370300200320032903a8043703a003200341003602a804200341a0036a4110200341a8046a1006210202400240024020032802a8042207417f460d002002450d00200320073602fc01200320023602f801200341a8046a200341f8016a103120032802a8042208450d0820032902ac04211802402007450d00200210290b200341a8046a41186a200341f0006a41186a290300370300200341a8046a41106a200341f0006a41106a290300370300200341a8046a41086a200341f0006a41086a290300370300200320032903703703a804200341a8046a21072018422088a722022018a7460d010c020b200341a8046a41186a200341f0006a41186a290300370300200341a8046a41106a200341f0006a41106a290300370300200341a8046a41086a200341f0006a41086a290300370300200320032903703703a804420021184101210841002102200341a8046a21070b024020022018a7470d00200241016a220a2002490d042002410174220b200a200a200b491b220a41ffffff3f71200a470d04200a410574220b4100480d040240024020020d00200b103221080c010b20082002410574200b103421080b2008450d08201842808080807083200aad8421180b2018422088a721020b20082002410574220b6a220a2007290000370000200a41186a200741186a290000370000200a41106a200741106a290000370000200a41086a200741086a290000370000200341a8046a41086a22074200370300200342003703a804418fddc300411d200341a8046a1003200341a0036a41086a2007290300370300200320032903a8043703a003200341003602b004200342013703a804200241016a2207200341a8046a1066024020072002490d00200b41206a21072008210203402003200341a8046a3602f8012002200341f8016a108501200241206a2102200741606a22070d000b0b20032802ac042102200341a0036a411020032802a804220720032802b004100502402002450d00200710290b02402018a7450d00200810290b200341f8016a41186a200341f0006a41186a290300370300200341f8016a41106a200341f0006a41106a290300370300200341f8016a41086a200341f0006a41086a290300370300200320032903703703f801200341a8046a2009418801109b051a411e10322202450d07200241002900a0f143370000200241166a41002900b6f143370000200241106a41002900b0f143370000200241086a41002900a8f1433700002003429e808080e0033702a403200320023602a0032003200341a0036a36028003200341f8016a20034180036a10850120032802a403210720032802a003210220032802a8032108200341a0036a41186a220a4200370300200341a0036a41106a220b4200370300200341a0036a41086a220c4200370300200342003703a00320022008200341a0036a100020034180036a41186a200a29030037030020034180036a41106a200b29030037030020034180036a41086a200c290300370300200320032903a00337038003200341003602a803200342013703a003200341a8046a200341a0036a105f20032802a403210820034180036a412020032802a003220a20032802a803100502402008450d00200a10290b02402007450d00200210290b200341a8046a102a412010322202450d0820022003290350370000200241186a200341d0006a41186a290300370000200241106a200341d0006a41106a290300370000200241086a200341d0006a41086a290300370000200341f8016a41186a200341f0006a41186a290300370300200341f8016a41106a200341f0006a41106a290300370300200341f8016a41086a200341f0006a41086a290300370300200320032903703703f801200341c4046a4100360200200341b4046a428180808010370200200342013702bc04200320023602b004200320173602ac0420032006410020051b22083602a804411a10322207450d09200741002900acdd43370000200741186a41002f00c4dd433b0000200741106a41002900bcdd43370000200741086a41002900b4dd433700002003429a808080a0033702a403200320073602a0032003200341a0036a36028003200341f8016a20034180036a10850120032802a403210a20032802a003210720032802a8032106200341a0036a41186a22054200370300200341a0036a41106a220b4200370300200341a0036a41086a220c4200370300200342003703a00320072006200341a0036a100020034180036a41186a200529030037030020034180036a41106a200b29030037030020034180036a41086a200c290300370300200320032903a0033703800320034180036a200341a8046a10b0030240200a450d00200710290b20021029200341b5046a200341d0006a41086a290300370000200341bd046a200341d0006a41106a290300370000200341c5046a200341d0006a41186a290300370000200341cd046a2003290370370000200341d5046a200341f0006a41086a290300370000200341dd046a200341f0006a41106a290300370000200341e5046a200341f0006a41186a290300370000200341f4046a2017360200200341f0046a2008360200200341003a00ac04200341073a00a804200320032903503700ad04200341a8046a21020c010b200341a8046a41086a22024200370300200342003703a8044189d6c300411b200341a8046a1003200341a0036a41086a2002290300370300200320032903a8043703a00341002102200341003602a804200341a0036a4110200341a8046a10062108024020032802a8042207417f460d00200320073602fc01200320083602f801200341a8046a200341f8016a103120032802a8042206450d0a200341b0046a280200210220032802ac04210a02402007450d00200810290b200a450d00200610290b200341a8046a2009418801109b051a200341ac036a2002360200200341a0036a41086a4101360200200341003a00a403200341023a00a003200341106a200341a8046a200341a0036a10ee0220032802102102200341b5046a200341f0006a41086a290300370000200341bd046a20034180016a290300370000200341c5046a20034188016a290300370000200341cd046a2002453a0000200341043a00ac04200341073a00a804200320032903703700ad04200341a8046a21020b410021064101210a410141002002104c200910290c0b0b1033000b411e4101102e000b4181f1c3002107411f21080c060b41f7cdc3004133200341b8056a41ecd6c3001054000b200b4101102e000b411e4101102e000b41204101102e000b411a4101102e000b41f7cdc3004133200341b8056a41ecd6c3001054000b2009102a20091029410021064101210a410121090c040b4100210a200341003602b004200342013703a8042009200341a8046a105f20032802ac04210720032802b004210820032802a8042102200341a0036a41186a22064200370300200341a0036a41106a22054200370300200341a0036a41086a220b4200370300200342003703a00320022008200341a0036a1000200341f8016a41186a22082006290300370300200341f8016a41106a220c2005290300370300200341f8016a41086a2205200b290300370300200320032903a0033703f80102402007450d00200210290b200341a8046a2009418801109b051a200341a0036a410d6a200341f0006a41086a290300370000200341a0036a41156a200341f0006a41106a290300370000200341a0036a411d6a200341f0006a41186a29030037000041012106200341013a00a403200320032903703700a503200341023a00a003200341086a200341a8046a200341a0036a10ee0220032802082102200341a8046a410d6a2005290300370000200341a8046a41156a200c290300370000200341a8046a411d6a2008290300370000200341cd046a2002453a0000200341053a00ac04200341073a00a804200320032903f8013700ad0441014100200341a8046a104c200910290b41012109410021070c020b2009102a20091029410121064100210a410121090c010b200341a8046a41086a22074200370300200342003703a8044189d6c300411b200341a8046a1003200341a0036a41086a2007290300370300200320032903a8043703a003200341103602ac042003200341a0036a3602a80420062002200341a8046a10950102402005450d00200610290b410021094101210a41012106410021070b02402004410771417f6a220241024b0d0002400240024020020e03000102000b2009450d02200141086a280200450d02200141046a28020010290c020b200a450d01200141046a2802002202102a200210290c010b2006450d00200141086a2802002202102a200210290b2000200836020420002007360200200341c0056a24000bc65d021e7f037e230041c0056b2203240002400240024002400240024002400240024002400240024002400240024002400240024020012d000022040e0500010e0302000b200341bc046a4101360200200342013702ac042003418c9ac5003602a804200341053602a403200341c09ac5003602a0032003200341a0036a3602b804200341a8046a41dcf0c300107d000b200141086a2802002105200141046a2802002106024020022d000120022d000072450d0041f8f8c200210741282108410021094101210a02402005450d00200610290b4101210b0c100b20062001410c6a280200220c10cc01200341a8046a41086a22024200370300200342003703a80441a4d6c300411b200341a8046a1003200341a0036a41086a2002290300370300200320032903a8043703a003200341003602a804200341a0036a4110200341a8046a1006210702400240024020032802a8042208417f460d002007450d00200320083602fc01200320073602f801200341a8046a200341f8016a103120032802a804220d450d02200341b0046a280200210220032802ac04210e2008450d01200710290c010b4101210d410021024100210e0b200d410020021b210f20064100200c1b2109200d41206a200d20021b2110200641206a2006200c1b21112006200c4105746a2112200d20024105746a2113410021144100211541012116410021174100211841012119024003402014410174211a2014410574211b0240024002400240024003400240200f0d002010211c2016211d2015211e201421080c040b200f2102201021072016211d2015211e20142108201b210a201a210b02400340024002402009450d0020022009460d06200220094120109d05221c450d06201c417f4c0d0120072110201d2116201e2115200821142002210f0c080b200341a8046a41186a2207200f41186a290000370300200341a8046a41106a2208200f41106a290000370300200341a8046a41086a2209200f41086a2900003703002003200f2900003703a804024020142015470d00201441016a22022014490d0f2014410174220a20022002200a491b221541ffffff3f712015470d0f201541057422024100480d0f0240024020140d002002103221160c010b201620144105742002103421160b2016450d030b201620144105746a220220032903a804370000200241186a2007290300370000200241106a2008290300370000200241086a20092903003700004100210941002010201020134622021b210f201a41026a211a201b41206a211b201441016a21142010201041206a20021b21100c030b200341a8046a41186a221c200241186a290000370300200341a8046a41106a221f200241106a290000370300200341a8046a41086a2220200241086a290000370300200320022900003703a80402402008201e470d00200841016a22022008490d0e200b20022002200b491b221e41ffffff3f71201e470d0e201e41057422024100480d0e0240024020080d0020021032211d0c010b201d200a20021034211d0b201d450d040b201d200a6a220220032903a804370000200241186a201c290300370000200241106a201f290300370000200241086a2020290300370000410020072007201346221c1b2102200b41026a210b200a41206a210a200841016a21082007200741206a201c1b221c21072002450d050c000b0b0b20024101102e000b20024101102e000b201d2116201e2115200821142007200741206a200720134622021b211041002011201120124622081b21094100200720021b210f2011201141206a20081b21110c030b4100210f2009450d01201c2110201d2116201e2115200821140b200341a8046a41186a2207200941186a290000370300200341a8046a41106a2208200941106a290000370300200341a8046a41086a220a200941086a290000370300200320092900003703a804024020172018470d00201741016a22022017490d0720174101742209200220022009491b221841ffffff3f712018470d07201841057422024100480d070240024020170d002002103221190c010b201920174105742002103421190b2019450d030b201920174105746a220220032903a804370000200241186a2007290300370000200241106a2008290300370000200241086a200a29030037000041002011201120124622021b2109201741016a21172011201141206a20021b21110c010b0b201d20082006200c1092020240201e450d00201d10290b02402018450d00201910290b0240200e450d00200d10290b200341a8046a41086a22024200370300200342003703a80441a4d6c300411b200341a8046a1003200341a0036a41086a2002290300370300200320032903a8043703a003200341103602ac042003200341a0036a3602a8042006200c200341a8046a10950102402005450d00200610290b410021094101210a4101210b410021070c110b20024101102e000b41f7cdc3004133200341b8056a41ecd6c3001054000b200141216a2d0000211a200141246a2802002116200341306a41186a200141196a290000370300200341306a41106a200141116a290000370300200341306a41086a200141096a290000370300200320012900013703302002411a6a2901002121200241196a2d0000211e200241186a2d0000211d200241166a2f0100211c200241156a2d0000211f200241146a2d00002120200241126a2f01002113200241116a2d00002114200241106a2d000021112002410e6a2f0100210f2002410d6a2d00002110200241046a2d00002117200241026a2f0100211541a0f9c2002107412a21080240024020022d0000450d00410121094100210a4100210b0c010b410121094100210a4100210b20022d00014101470d002002410c6a2d0000210b2002410a6a2f0100210a200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d0000411874722107410021090b200a41ffff0371410874200841ff017172200b411874722108024020090d00200320213703682003201e3a00672003201d3a00662003201c3b01642003201f3a0063200320203a0062200320133b0160200320143a005f200320113a005e2003200f3b015c200320103a005b2003200836005720032007360053200320173a0052200320153b0150200341a8046a41086a22024200370300200342003703a80441a4d6c300411b200341a8046a1003200341a0036a41086a2002290300370300200320032903a8043703a003200341003602a804200341a0036a4110200341a8046a10062102024002400240024020032802a8042207417f460d002002450d00200320073602fc01200320023602f801200341a8046a200341f8016a103120032802a8042208450d02200341b0046a280200210920032802ac04210a02402007450d00200210290b20082009200341d0006a10920321020240200a450d00200810290b2002450d010c030b41014100200341d0006a1092030d020b41f2f1c3002107411221080c020b41f7cdc3004133200341b8056a41ecd6c3001054000b200341a8046a200341306a10af03024020032802b00422090d0041dff1c3002107411321080c010b200341c0046a280200211e200341bc046a280200210a4110210820032802b404211d4184f2c30021070240201620032802a804220f470d00200341c4046a280200211c20032802ac0421102009200341a8046a41106a280200221f4105746a2107410021202009210241002108024002400240201f4104490d00200341306a210b200341706a2114200341106a211341002108200921020340200341d0006a2002460d022002200341d0006a4120109d05450d0202400240200b2002460d00200241206a200341d0006a4120109d050d010b200841016a21080c030b0240024020132002460d00200241c0006a200341d0006a4120109d050d010b200841026a21080c030b024020142002460d00200241e0006a200341d0006a4120109d05450d00200841046a2108200720024180016a22026b41e0004b0d010c020b0b200841036a21080c010b20022007460d012009201f4105746a21070340200341d0006a2002460d012002200341d0006a4120109d05450d01200841016a21082007200241206a2202470d000c020b0b410121200b200a201c4105746a210b41002114200a210241002107024002400240201c4104490d00200341306a2113200341706a2117200341106a211141002107200a21020340200341d0006a2002460d022002200341d0006a4120109d05450d020240024020132002460d00200241206a200341d0006a4120109d050d010b200741016a21070c030b0240024020112002460d00200241c0006a200341d0006a4120109d050d010b200741026a21070c030b024020172002460d00200241e0006a200341d0006a4120109d05450d00200741046a2107200b20024180016a22026b41e0004b0d010c020b0b200741036a21070c010b2002200b460d010340200341d0006a2002460d012002200341d0006a4120109d05450d01200741016a2107200b200241206a2202470d000c020b0b410121140b024002400240024002400240024002400240201a41ff01710d002014450d010c080b20200d07200341a8046a41186a220b200341d0006a41186a290300370300200341a8046a41106a2220200341d0006a41106a290300370300200341a8046a41086a2213200341d0006a41086a290300370300200320032903503703a8040240201f201d460d00201d2108201f211d0c020b201d41016a2202201d490d0b201d4101742208200220022008491b220841ffffff3f712008470d0b200841057422024100480d0b02400240201d0d002002103221090c010b2009201d4105742002103421090b20090d0120024101102e000b200341a8046a41186a220b200341d0006a41186a290300370300200341a8046a41106a2213200341d0006a41106a290300370300200341a8046a41086a2214200341d0006a41086a290300370300200320032903503703a80402400240201c201e460d00201e2107201c211e0c010b201e41016a2202201e490d0b201e4101742207200220022007491b220741ffffff3f712007470d0b200741057422024100480d0b02400240201e0d0020021032210a0c010b200a201e41057420021034210a0b200a0d0020024101102e000b200a201e4105746a220220032903a804370000200241186a200b290300370000200241106a2013290300370000200241086a2014290300370000201c41016a211c024002402020450d00201f20084d0d012009201f417f6a221f4105746a220229000021212002290008212220022900102123200920084105746a220841186a200241186a2900003700002008202337001020082022370008200820213700000b2007211e201d21080c020b4180dbc3002008201f1036000b2009201d4105746a220220032903a804370000200241186a200b290300370000200241106a2020290300370000200241086a2013290300370000201f41016a211f2014450d00201c20074d0d01200a201c417f6a221c4105746a220229000021212002290008212220022900102123200a20074105746a220741186a200241186a2900003700002007202337001020072022370008200720213700000b200341cd046a2003290330370000200341b5046a200341d0006a41086a290300370000200341bd046a200341d0006a41106a290300370000200341c5046a200341d0006a41186a290300370000200341d5046a200341306a41086a290300370000200341dd046a200341306a41106a290300370000200341e5046a200341306a41186a290300370000200341013a00ac04200341063a00a804200320032903503700ad04200341f4046a201c360200200341f0046a201f360200200341ed046a201a3a000041014100200341a8046a104c200341a8046a41086a22024200370300200342003703a80441a4d6c300411b200341a8046a1003200341a0036a41086a2002290300370300200320032903a8043703a003200341003602a804200341a0036a4110200341a8046a1006210720032802a804220b417f460d022007450d022003200b3602fc01200320073602f801200341a8046a200341f8016a103120032802a8042220450d01200341b0046a280200210220032802ac04211d0240200b450d00200710290b201d450d03202010290c030b4180dbc3002007201c1036000b41f7cdc3004133200341b8056a41ecd6c3001054000b410021020b024002400240024002400240024002400240201f20104f220b0d0041002002201c6b2207200720024b1b2010490d00200341c4046a201c360200200341a8046a41186a201e360200200341a8046a41106a201f360200200341b4046a20083602002003200a3602bc04200320093602b004200320103602ac042003200f3602a804411a10322202450d01200241002900f5dc43370000200241186a41002f008ddd433b0000200241106a4100290085dd43370000200241086a41002900fddc433700002003429a808080a0033702a403200320023602a0032003200341a0036a3602f801200341306a200341f8016a10850120032802a403210720032802a003210220032802a803210b200341a0036a41186a221d4200370300200341a0036a41106a221c4200370300200341a0036a41086a221f4200370300200342003703a0032002200b200341a0036a100020034180036a41186a201d29030037030020034180036a41106a201c29030037030020034180036a41086a201f290300370300200320032903a0033703800320034180036a200341a8046a10b00302402007450d00200210290b02402008450d00200910290b201e0d050c060b0240200b0d00200341b5046a200341386a290300370000200341bd046a200341c0006a290300370000200341c5046a200341c8006a290300370000200341033a00ac04200341063a00a804200320032903303700ad0441014100200341a8046a104c0c040b200341b5046a200341306a41086a290300370000200341bd046a200341306a41106a290300370000200341c5046a200341306a41186a290300370000200341023a00ac04200341063a00a804200320032903303700ad0441014100200341a8046a104c411e10322207450d01200741002900aaf243370000200741166a41002900c0f243370000200741106a41002900baf243370000200741086a41002900b2f2433700002003429e808080e0033702ac04200320073602a8042003200341a8046a3602a003200341306a200341a0036a10850120032802ac04211c20032802a804210720032802b004210b200341a0036a41186a221d4200370300200341a0036a41106a221f4200370300200341a0036a41086a22204200370300200342003703a0032007200b200341a0036a100020034180036a41186a201d29030037030020034180036a41106a201f29030037030020034180036a41086a2020290300370300200320032903a00337038003200341003602a80420034180036a4120200341a8046a1006211d0240024020032802a804221f417f470d004113210b0c010b0240201d0d004113210b0c010b2003201f3602b4052003201d3602b005200341a8046a200341b0056a104f20032d00a804220b4113460d03200341a0036a200341a8046a410172418701109b051a0240201f450d00201d10290b20034180036a412010040b200341f8016a200341a0036a418701109b051a0240200b4113470d00201c450d04200710290c040b200341f0006a200341f8016a418701109b051a0240201c450d00200710290b2003200b3a00a804200341a8046a410172200341f0006a418701109b051a200341ac036a2002360200200341a0036a41086a2010360200200341003a00a403200341013a00a003200341286a200341a8046a200341a0036a10ee0220032802282102200341b5046a200341306a41086a290300370000200341bd046a200341c0006a290300370000200341c5046a200341c8006a290300370000200341cd046a2002453a0000200341043a00ac04200341063a00a804200320032903303700ad0441014100200341a8046a104c0c030b411a4101102e000b411e4101102e000b41f7cdc3004133200341b8056a41ecd6c3001054000b411a10322202450d02200241002900f5dc43370000200241186a41002f008ddd433b0000200241106a4100290085dd43370000200241086a41002900fddc433700002003429a808080a0033702ac04200320023602a8042003200341a8046a3602a003200341306a200341a0036a10850120032802ac04210b20032802a804210720032802b004211d200341a0036a41186a221c4200370300200341a0036a41106a221f4200370300200341a0036a41086a22024200370300200342003703a0032007201d200341a0036a100020034180036a41186a201c29030037030020034180036a41106a201f29030037030020034180036a41086a2002290300370300200320032903a0033703800320034180036a412010040240200b450d00200710290b200341a8046a41086a22074200370300200342003703a80441d8dcc300411d200341a8046a100320022007290300370300200320032903a8043703a003200341003602a804200341a0036a4110200341a8046a100621070240024020032802a8042202417f460d00200320023602fc01200320073602f801200341a8046a200341f8016a103120032802a804220b450d0520032902ac04212102402002450d00200710290b200320213702fc012003200b3602f8010c010b2003410036028002200342013703f8010b200341f8016a200341306a1035200341a8046a41086a22024200370300200342003703a80441d8dcc300411d200341a8046a1003200341a0036a41086a2002290300370300200320032903a8043703a00320032802f801210b2003280280022102200341003602b004200342013703a8042002200341a8046a106602402002450d0020024105742107200b210203402003200341a8046a3602702002200341f0006a108501200241206a2102200741606a22070d000b0b20032802ac042102200341a0036a411020032802a804220720032802b004100502402002450d00200710290b024020032802fc01450d00200b10290b02402008450d00200910290b201e450d010b200a10290b410021070c040b411a4101102e000b41f7cdc3004133200341b8056a41ecd6c3001054000b4194f2c3002107411621080b0240201d450d00200910290b201e450d00200a10290b4101210a4101210b410121090c0e0b200141086a2802002109200141046a280200211a2002411a6a2901002121200241196a2d0000211d200241186a2d0000211c200241166a2f0100211f200241156a2d00002120200241146a2d00002113200241126a2f01002114200241116a2d00002111200241106a2d0000210f2002410e6a2f010021102002410d6a2d00002117200241046a2d00002115200241026a2f0100211641a0f9c2002107412a21080240024020022d0000450d004101210a4100210b4100211e0c010b4101210a4100210b4100211e20022d00014101470d002002410c6a2d0000211e2002410a6a2f0100210b200241096a2d00002108200241066a2f0100410874200241056a2d000072200241086a2d00004118747221074100210a0b200b41ffff0371410874200841ff017172201e411874722108200a0d09200320213703682003201d3a00672003201c3a00662003201f3b0164200320203a0063200320133a0062200320143b0160200320113a005f2003200f3a005e200320103b015c200320173a005b2003200836005720032007360053200320153a0052200320163b0150200341a8046a41086a22024200370300200342003703a80441a4d6c300411b200341a8046a1003200341a0036a41086a2002290300370300200320032903a8043703a003200341003602a804200341a0036a4110200341a8046a10062102024002400240024020032802a8042207417f460d002002450d00200320073602fc01200320023602f801200341a8046a200341f8016a103120032802a8042208450d02200341b0046a280200210a20032802ac04210b02402007450d00200210290b2008200a200341d0006a10920321020240200b450d00200810290b2002450d010c030b41014100200341d0006a1092030d020b41ecf0c3002107411521080c0b0b41f7cdc3004133200341b8056a41ecd6c3001054000b200341003602b004200342013703a8042009200341a8046a105f20032802ac04210720032802b004210820032802a8042102200341a0036a41186a220a4200370300200341a0036a41106a220b4200370300200341a0036a41086a221e4200370300200342003703a00320022008200341a0036a1000200341f0006a41186a2208200a290300370300200341f0006a41106a220a200b290300370300200341f0006a41086a220b201e290300370300200320032903a00337037002402007450d00200210290b200341a8046a41186a2008290300370300200341a8046a41106a200a290300370300200341a8046a41086a200b290300370300200320032903703703a804411e10322202450d01200241002900aaf243370000200241166a41002900c0f243370000200241106a41002900baf243370000200241086a41002900b2f2433700002003429e808080e0033702a403200320023602a0032003200341a0036a3602f801200341a8046a200341f8016a10850120032802a403210720032802a003210220032802a8032108200341a0036a41186a220a4200370300200341a0036a41106a220b4200370300200341a0036a41086a221e4200370300200342003703a00320022008200341a0036a100020034180036a41186a200a29030037030020034180036a41106a200b29030037030020034180036a41086a201e290300370300200320032903a0033703800320034180036a41204101410041001007210802402007450d00200210290b2008417f470d0202400240201a4102490d00200341206a41c8f2c3004121105d2003280224210b2003280220211e200341186a41c8f2c3004121105d20032802182107200328021c2108200341a8046a41086a22024200370300200342003703a80441c8f2c3004121200341a8046a1003200341a0036a41086a220a2002290300370300200320032903a8043703a0032003200841016a410120071b3602a804200341a0036a4110200341a8046a4104100520024200370300200342003703a80441d8dcc300411d200341a8046a1003200a2002290300370300200320032903a8043703a003200341003602a804200341a0036a4110200341a8046a1006210202400240024020032802a8042207417f460d002002450d00200320073602fc01200320023602f801200341a8046a200341f8016a103120032802a8042208450d0820032902ac04212102402007450d00200210290b200341a8046a41186a200341f0006a41186a290300370300200341a8046a41106a200341f0006a41106a290300370300200341a8046a41086a200341f0006a41086a290300370300200320032903703703a804200341a8046a21072021422088a722022021a7460d010c020b200341a8046a41186a200341f0006a41186a290300370300200341a8046a41106a200341f0006a41106a290300370300200341a8046a41086a200341f0006a41086a290300370300200320032903703703a804420021214101210841002102200341a8046a21070b024020022021a7470d00200241016a220a2002490d042002410174221d200a200a201d491b220a41ffffff3f71200a470d04200a410574221d4100480d040240024020020d00201d103221080c010b20082002410574201d103421080b2008450d08202142808080807083200aad8421210b2021422088a721020b20082002410574221d6a220a2007290000370000200a41186a200741186a290000370000200a41106a200741106a290000370000200a41086a200741086a290000370000200341a8046a41086a22074200370300200342003703a80441d8dcc300411d200341a8046a1003200341a0036a41086a2007290300370300200320032903a8043703a003200341003602b004200342013703a804200241016a2207200341a8046a1066024020072002490d00201d41206a21072008210203402003200341a8046a3602f8012002200341f8016a108501200241206a2102200741606a22070d000b0b20032802ac042102200341a0036a411020032802a804220720032802b004100502402002450d00200710290b02402021a7450d00200810290b200341f8016a41186a200341f0006a41186a290300370300200341f8016a41106a200341f0006a41106a290300370300200341f8016a41086a200341f0006a41086a290300370300200320032903703703f801200341a8046a2009418801109b051a411e10322202450d07200241002900aaf243370000200241166a41002900c0f243370000200241106a41002900baf243370000200241086a41002900b2f2433700002003429e808080e0033702a403200320023602a0032003200341a0036a36028003200341f8016a20034180036a10850120032802a403210720032802a003210220032802a8032108200341a0036a41186a220a4200370300200341a0036a41106a221d4200370300200341a0036a41086a221c4200370300200342003703a00320022008200341a0036a100020034180036a41186a200a29030037030020034180036a41106a201d29030037030020034180036a41086a201c290300370300200320032903a00337038003200341003602a803200342013703a003200341a8046a200341a0036a105f20032802a403210820034180036a412020032802a003220a20032802a803100502402008450d00200a10290b02402007450d00200210290b200341a8046a102a412010322202450d0820022003290350370000200241186a200341d0006a41186a290300370000200241106a200341d0006a41106a290300370000200241086a200341d0006a41086a290300370000200341f8016a41186a200341f0006a41186a290300370300200341f8016a41106a200341f0006a41106a290300370300200341f8016a41086a200341f0006a41086a290300370300200320032903703703f801200341c4046a4100360200200341b4046a428180808010370200200342013702bc04200320023602b0042003201a3602ac042003200b4100201e1b22083602a804411a10322207450d09200741002900f5dc43370000200741186a41002f008ddd433b0000200741106a4100290085dd43370000200741086a41002900fddc433700002003429a808080a0033702a403200320073602a0032003200341a0036a36028003200341f8016a20034180036a10850120032802a403210a20032802a003210720032802a803210b200341a0036a41186a221e4200370300200341a0036a41106a221d4200370300200341a0036a41086a221c4200370300200342003703a0032007200b200341a0036a100020034180036a41186a201e29030037030020034180036a41106a201d29030037030020034180036a41086a201c290300370300200320032903a0033703800320034180036a200341a8046a10b0030240200a450d00200710290b20021029200341b5046a200341d0006a41086a290300370000200341bd046a200341d0006a41106a290300370000200341c5046a200341d0006a41186a290300370000200341cd046a2003290370370000200341d5046a200341f0006a41086a290300370000200341dd046a200341f0006a41106a290300370000200341e5046a200341f0006a41186a290300370000200341f4046a201a360200200341f0046a2008360200200341003a00ac04200341063a00a804200320032903503700ad04200341a8046a21020c010b200341a8046a41086a22024200370300200342003703a80441a4d6c300411b200341a8046a1003200341a0036a41086a2002290300370300200320032903a8043703a00341002102200341003602a804200341a0036a4110200341a8046a10062108024020032802a8042207417f460d00200320073602fc01200320083602f801200341a8046a200341f8016a103120032802a804220b450d0a200341b0046a280200210220032802ac04210a02402007450d00200810290b200a450d00200b10290b200341a8046a2009418801109b051a200341ac036a2002360200200341a0036a41086a4101360200200341003a00a403200341013a00a003200341106a200341a8046a200341a0036a10ee0220032802102102200341b5046a200341f0006a41086a290300370000200341bd046a20034180016a290300370000200341c5046a20034188016a290300370000200341cd046a2002453a0000200341043a00ac04200341063a00a804200320032903703700ad04200341a8046a21020b4100210b4101210a410141002002104c200910290c0b0b1033000b411e4101102e000b4181f1c3002107411f21080c060b41f7cdc3004133200341b8056a41ecd6c3001054000b201d4101102e000b411e4101102e000b41204101102e000b411a4101102e000b41f7cdc3004133200341b8056a41ecd6c3001054000b2009102a200910294100210b4101210a410121090c030b200141046a280200210941a0f9c2002107412a210820022d00000d0120022d00014101470d01200241196a2d00002107200241186a2d00002108200241166a2f0100210a200241156a2d0000210b200241146a2d0000211e200241126a2f0100211d200241116a2d0000211c200241106a2d0000211f2002410e6a2f010021202002410d6a2d000021132002410c6a2d000021142002410a6a2f01002111200241096a2d0000210f200241086a2d00002110200241066a2f01002117200241056a2d00002115200241046a2d00002116200241026a2f0100211a20032002411a6a29010037038801200320073a008701200320083a0086012003200a3b0184012003200b3a0083012003201e3a0082012003201d3b0180012003201c3a007f2003201f3a007e200320203b017c200320133a007b200320163a00722003201a3b01702003200f20114108742014411874727236007720032015201741087472201041187472360073200341a8046a41086a22024200370300200342003703a80441a4d6c300411b200341a8046a1003200341a0036a41086a2002290300370300200320032903a8043703a003200341003602a804200341a0036a4110200341a8046a10062107024002400240024020032802a8042202417f460d00200320023602fc01200320073602f801200341a8046a200341f8016a103120032802a8042208450d02200341b0046a280200210a20032802ac04210b02402002450d00200710290b2008200a200341f0006a10920321020240200b450d00200810290b2002450d010c030b41014100200341f0006a1092030d020b41ecf0c3002107411521080c030b41f7cdc3004133200341b8056a41ecd6c3001054000b4100210a200341003602b004200342013703a8042009200341a8046a105f20032802ac04210720032802b004210820032802a8042102200341a0036a41186a220b4200370300200341a0036a41106a221e4200370300200341a0036a41086a221d4200370300200342003703a00320022008200341a0036a1000200341f8016a41186a2208200b290300370300200341f8016a41106a221c201e290300370300200341f8016a41086a221e201d290300370300200320032903a0033703f80102402007450d00200210290b200341a8046a2009418801109b051a200341a0036a410d6a200341f0006a41086a290300370000200341a0036a41156a200341f0006a41106a290300370000200341a0036a411d6a200341f0006a41186a2903003700004101210b200341013a00a403200320032903703700a503200341013a00a003200341086a200341a8046a200341a0036a10ee0220032802082102200341a8046a410d6a201e290300370000200341a8046a41156a201c290300370000200341a8046a411d6a2008290300370000200341cd046a2002453a0000200341053a00ac04200341063a00a804200320032903f8013700ad0441014100200341a8046a104c200910290b41012109410021070c010b2009102a200910294101210b4100210a410121090b02402004410771417f6a220241024b0d0002400240024020020e03000102000b2009450d02200141086a280200450d02200141046a28020010290c020b200a450d01200141046a2802002202102a200210290c010b200b450d00200141086a2802002202102a200210290b2000200836020420002007360200200341c0056a24000b9c0201067f230041f0006b220224000240410e10322203450d00200341002900bcbe44370000200341066a41002900c2be443700002002428e808080e0013702042002200336020020012002108101200228020421012002280208210420022802002103200241186a22054200370300200241106a22064200370300200241086a22074200370300200242003703002003200420021000200241d0006a41186a2005290300370300200241d0006a41106a2006290300370300200241d0006a41086a2007290300370300200220022903003703502002200241d0006a10b6030240024020022802200d00200041003602200c010b2000200241d000109b051a0b02402001450d00200310290b200241f0006a24000f0b410e4101102e000bd8a40106017f037e107f017e117f057e230041a0056b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0e000102030405060708090a0b0c0d000b200341fc016a4101360200200342013702ec012003418c9ac5003602e8012003410536029401200341c09ac50036029001200320034190016a3602f801200341e8016a41fc93c500107d000b200141306a2903002104200141286a29030021052001411d6a29000021062001411c6a2d000021072001411b6a2d00002108200141196a2f00002109200141186a2d0000210a200141176a2d0000210b200141156a2f0000210c200141146a2d0000210d200141136a2d0000210e200141116a2f0000210f200141106a2d000021102001410c6a2802002111200141086a2802002112200141076a2d00002113200141056a2f00002114200141046a2d0000211520012d000121162002411a6a2901002117200241196a2d00002118200241186a2d00002119200241166a2f0100211a200241156a2d0000211b200241146a2d0000211c200241126a2f0100211d200241116a2d0000211e200241106a2d0000211f2002410e6a2f010021202002410d6a2d00002121200241046a2d00002122200241026a2f01002123412a212441a0f9c20021250240024020022d0000450d004101212641002127410021280c010b41012126410021274100212820022d00014101470d002002410c6a2d000021272002410a6a2f01002128200241096a2d00002124200241066a2f0100410874200241056a2d000072200241086a2d0000411874722125410021260b202841ffff0371410874202741187472202441ff017172212420260d36200320173703d803200320183a00d703200320193a00d6032003201a3b01d4032003201b3a00d3032003201c3a00d2032003201d3b01d0032003201e3a00cf032003201f3a00ce03200320203b01cc03200320213a00cb03200320243600c703200320253600c303200320223a00c203200320233b01c003410e10322202450d0c200241002900e4bd44370000200241066a41002900eabd443700002003428e808080e0013702ec01200320023602e801200341c0036a200341e8016a10810120032802ec01212520032802f001212420032802e8012102200341f8046a41186a22264200370300200341f8046a41106a22274200370300200341f8046a41086a22284200370300200342003703f80420022024200341f8046a1000200341d8046a41186a2026290300370300200341d8046a41106a2027290300370300200341d8046a41086a2028290300370300200320032903f8043703d804200341d8046a41204101410041001007212402402025450d00200210290b02402024417f460d0041d694c5002125411421240c370b0240201541ff01714101470d00200341e8016a201241067610ab0220032802e80121250240024020032802f0012012413f7122024b0d00410021020c010b202520024105746a2202290018210620022d0017210720022d0016210820022f0014210920022d0013210a20022d0012210b20022f0010210c20022d000f210d20022d000e210e20022f000c210f20022d000b2110200228000721112002280003211220022d0002211320022f00002114410121020b024020032802ec01450d00202510290b2002450d360b200320063703a801200320073a00a701200320083a00a601200320093b01a4012003200a3a00a3012003200b3a00a2012003200c3b01a0012003200d3a009f012003200e3a009e012003200f3b019c01200320103a009b0120032011360097012003201236009301200320133a009201200320143b019001410e10322202450d0d200241002900bcbe44370000200241066a41002900c2be443700002003428e808080e0013702ec01200320023602e80120034190016a200341e8016a10810120032802ec01212520032802f001212420032802e8012102200341f8046a41186a22264200370300200341f8046a41106a22274200370300200341f8046a41086a22284200370300200342003703f80420022024200341f8046a1000200341d8046a41186a2026290300370300200341d8046a41106a2027290300370300200341d8046a41086a2028290300370300200320032903f8043703d804200341d8046a41204101410041001007212402402025450d00200210290b2024417f470d3402402005428080e983b1de165441002004501b450d0041a594c5002125413121240c370b200341e8016a41186a20034190016a41186a290300370300200341e8016a41106a20034190016a41106a290300370300200341e8016a41086a20034190016a41086a29030037030020032003290390013703e801410e10322202450d0e200241002900e4bd44370000200241066a41002900eabd443700002003428e808080e0013702e402200320023602e002200341c0036a200341e0026a10810120032802e402212520032802e802212420032802e0022102200341f8046a41186a22264200370300200341f8046a41106a22274200370300200341f8046a41086a22284200370300200342003703f80420022024200341f8046a1000200341d8046a41186a2026290300370300200341d8046a41106a2027290300370300200341d8046a41086a2028290300370300200320032903f8043703d804200341203602e4022003200341d8046a3602e002200341e8016a200341e0026a10890102402025450d00200210290b410d10322202450d0f200241002900cabe44370000200241056a41002900cfbe443700002003428d808080d0013702ec01200320023602e801200341c0036a200341e8016a10810120032802ec01212420032802f001210220032802e8012125200341f8046a41186a22264200370300200341f8046a41106a22274200370300200341f8046a41086a22284200370300200342003703f80420252002200341f8046a1000200341d8046a41186a2026290300370300200341d8046a41106a2027290300370300200341d8046a41086a2028290300370300200320032903f8043703d804024002400240024002400240201641037122024103460d0020020e03010203010b200341d8046a41204101410010050c040b200341003a009f050c020b200341013a009f050c010b200341023a009f050b410110322202450d11200220032d009f053a0000200341d8046a4120200241011005200210290b02402024450d00202510290b200341086a200341c0036a10be01200341086a41086a2903002117200329030821062003419c026a200341c0036a41086a290300370200200341a4026a200341d0036a290300370200200341ac026a200341c0036a41186a2903003702004100212520034190026a4100360200200341e8016a41186a201720042006200554201720045420172004511b22021b2217370300200320032903c00337029402200342083703880220032006200520021b22063703f801200320173703f001200320063703e80120034190016a200341e8016a1095042003418c026a280200450d3320032802880210290c330b20022d00000d3120022d00014101470d31200141106a2903002117200141086a2903002106200241196a2d00002125200241186a2d00002124200241166a2f01002126200241156a2d00002127200241146a2d00002128200241126a2f01002118200241116a2d00002119200241106a2d0000211a2002410e6a2f0100211b2002410d6a2d0000211c2002410c6a2d0000211d2002410a6a2f0100211e200241096a2d0000211f200241086a2d00002120200241066a2f01002121200241056a2d00002122200241046a2d00002123200241026a2f0100211220032002411a6a29010037039005200320253a008f05200320243a008e05200320263b018c05200320273a008b05200320283a008a05200320183b018805200320193a0087052003201a3a0086052003201b3b0184052003201c3a008305200320233a00fa04200320123b01f8042003201f201e410874201d41187472723600ff04200320222021410874722020411874723600fb04200341e8016a200341f8046a108e04024020032d00e8014101460d0041fa94c5002125410b21240c360b200320032902ec013700e302200320032d00eb013a00e202200320032f00e9013b01e002200320034181026a2900003703f8022003200341fd016a2800003602f4022003200341f5016a2900003702ec022003200341e8016a410c6a22022d00003a00eb02200341e8016a200341e0026a10f9022003280288022225450d3020034190046a41086a200341e8016a41346a2902002204370300200341c0036a41086a22242004370300200341d0036a2226200341e8016a413c6a290200370300200341c0036a41186a2227200341e8016a41c4006a290200370300200320034194026a290200220437039004200320043703c003200341b4026a2802002128200341e8016a41286a28020021182002350200210420032802e801211920032902ec01210520032903f8012129200328028c02210220034190016a41186a221a200341e8016a41186a290300222a37030020034190016a410c6a20043e020020034190016a41286a2018360200200341b4016a2002360200200320293703a0012003200537029401200320253602b001200320193602900120034190016a41c4006a202729030037020020034190016a413c6a202629030037020020034190016a41346a2024290300370200200320032903c0033702bc01200320283602dc01200341186a200341f8046a10be01024020032903182204200329039001222b7d222c200456200341186a41086a290300220520034190016a41086a290300222d7d2004202b54ad7d220420055620042005511b0d0020032006202c202c200656200420175620042017511b22021b220620297c22053703a001201a2017200420021b2217202a7c2005200654ad7c37030020032006202b7c22043703900120032017202d7c2004200654ad7c37039801200341e0026a20034190016a10950420032802b40121020b2002450d2f20032802b00110290c2f0b20022d00000d3020022d00014101470d30200141106a2903002104200141086a2903002105200241196a2d00002125200241186a2d00002124200241166a2f01002126200241156a2d00002127200241146a2d00002128200241126a2f01002118200241116a2d00002119200241106a2d0000211a2002410e6a2f0100211b2002410d6a2d0000211c2002410c6a2d0000211d2002410a6a2f0100211e200241096a2d0000211f200241086a2d00002120200241066a2f01002121200241056a2d00002122200241046a2d00002123200241026a2f0100211220032002411a6a2901003703f802200320253a00f702200320243a00f602200320263b01f402200320273a00f302200320283a00f202200320183b01f002200320193a00ef022003201a3a00ee022003201b3b01ec022003201c3a00eb02200320233a00e202200320123b01e0022003201f201e410874201d41187472723600e702200320222021410874722020411874723600e302200341e8016a200341e0026a10f9022003280288022226450d2f20034190046a41086a200341e8016a41346a2902002217370300200341c0036a41086a22242017370300200341d0036a2227200341e8016a413c6a290200370300200341c0036a41186a2228200341e8016a41c4006a290200370300200320034194026a290200221737039004200320173703c003200341b4026a2802002118200341e8016a41286a2802002125200341e8016a410c6a350200212920032802e801211920032902ec01212b20032903f8012117200328028c02210220034190016a41186a200341e8016a41186a290300220637030020034190016a410c6a20293e020020034190016a41286a2025360200200341b4016a2002360200200320173703a0012003202b37029401200320263602b001200320193602900120034190016a41c4006a202829030037020020034190016a413c6a202729030037020020034190016a41346a2024290300370200200320032903c0033702bc01200320183602dc0102400240024002402025411f4b0d00201720052017200554200620045420062004511b22241b22052006200420241b220484500d0320034190016a41186a4200200620047d2017200554ad7d2229201720057d222b428080e983b1de165441002029501b22241b37030020034200202b20241b3703a001200341286a41abadc5004112105d200328022c21272003280228212820252002470d02200241016a22252002490d3120024101742218202520252018491b2225ad42187e2229422088a70d312029a7221841004e0d010c310b418595c5002125412321242002450d37202610290c370b0240024020020d002018103221260c010b2026200241186c2018103421260b2026450d11200320253602b401200320263602b00120032802b80121250b2026202541186c6a22022006200420241b37030820022017200520241b3703002002202741a0056a41a00520281b360210200320032802b80141016a3602b801200341e0026a20034190016a10950420032802b40121020b2002450d2e20032802b0011029410021250c310b41a0f9c2002125412a212420022d00000d3320022d00014101470d33200241196a2d00002125200241186a2d00002124200241166a2f01002126200241156a2d00002127200241146a2d00002128200241126a2f01002118200241116a2d00002119200241106a2d0000211a2002410e6a2f0100211b2002410d6a2d0000211c2002410c6a2d0000211d2002410a6a2f0100211e200241096a2d0000211f200241086a2d00002120200241066a2f01002121200241056a2d00002122200241046a2d00002123200241026a2f0100211220032002411a6a2901003703d803200320253a00d703200320243a00d603200320263b01d403200320273a00d303200320283a00d203200320183b01d003200320193a00cf032003201a3a00ce032003201b3b01cc032003201c3a00cb03200320233a00c203200320123b01c0032003201f201e410874201d41187472723600c703200320222021410874722020411874723600c303200341e8016a200341c0036a10f9022003280288022218450d2e200341c0006a41086a2003419c026a290200370300200341c0006a41106a200341a4026a290200370300200341c0006a41186a200341ac026a290200370300200320034194026a290200370340200341e8016a41186a290300212920034190026a280200211a200341f4016a350200211720032903f801212b200328028c02211b20033502e801210420032902ec012106200341386a41abadc5004112105d410021282017422086200642208884211720042006422086842106024002400240201a41186c2202450d00200328023c410020032802381b2126201820026a2127201a41186c41686a2125201821020340200241086a2903002105200229030021042026200241106a2802002224490d024200201720057d2006200454ad7d2205200620047d2204200656200520175620052017511b22241b21174200200420241b2106202541686a2125200241186a22022027470d000b0b410821190240201b0d00410021240c020b20181029410021240c010b411810322219450d102019200437030020192024360210201920053703080240024020250d0041012128410121240c010b200241186a211c201a41186c20186a41686a211d41012128410121240340201c210202400340200241086a2903002105200229030021042026200241106a2802002225490d014200201720057d2006200454ad7d2205200620047d2204200656200520175620052017511b22251b21174200200420251b2106200241186a22022027470d000c030b0b024020242028470d00202841016a22242028490d302028410174221a20242024201a491b2224ad42187e222c422088a70d30202ca7221a4100480d300240024020280d00201a103221190c010b2019202841186c201a103421190b2019450d140b200241186a211c2019202841186c6a221a2005370308201a2004370300201a2025360210202841016a2128201d2002470d000b0b201b450d00201810290b20034190026a20283602002003418c026a20243602002003202b3703f801200341e8016a41186a2029370300200341ac026a200341c0006a41186a290300370200200341a4026a200341d0006a2903003702002003419c026a200341c8006a290300370200200320063703e80120032003290340370294022003201936028802200320173703f0010240202b2029844200520d002028450d250b200341c0036a200341e8016a1095040c2b0b200141106a2903002106200141086a29030021042002411a6a2901002117200241196a2d00002118200241186a2d00002119200241166a2f0100211a200241156a2d0000211b200241146a2d0000211c200241126a2f0100211d200241116a2d0000211e200241106a2d0000211f2002410e6a2f010021202002410d6a2d00002121200241046a2d00002122200241026a2f0100212341a0f9c2002125412a21240240024020022d0000450d004101212641002127410021280c010b41012126410021274100212820022d00014101470d002002410c6a2d000021282002410a6a2f01002127200241096a2d00002124200241066a2f0100410874200241056a2d000072200241086a2d0000411874722125410021260b202741ffff0371410874202441ff017172202841187472212420260d32200320173703d802200320183a00d702200320193a00d6022003201a3b01d4022003201b3a00d3022003201c3a00d2022003201d3b01d0022003201e3a00cf022003201f3a00ce02200320203b01cc02200320213a00cb02200320243600c702200320253600c302200320223a00c202200320233b01c002200341e8016a200341c0026a10f9022003280288022202450d2d20034190046a41086a200341e8016a41346a290200221737030020034190016a41086a2225201737030020034190016a41106a2224200341e8016a413c6a29020037030020034190016a41186a2226200341e8016a41c4006a2902003703002003200341e8016a412c6a2902002217370390042003201737039001200341b4026a2802002127200341e8016a410c6a350200211720032802e801212820032902ec01210520032903f8012129200329028c02212b200341c0036a41186a200341e8016a41186a290300370300200341c0036a410c6a20173e0200200341e4036a202b370200200320293703d003200320053702c403200320023602e003200320283602c003200341c0036a41c4006a2026290300370200200341c0036a413c6a2024290300370200200341c0036a41346a202529030037020020032003290390013702ec032003202736028c04200341c0036a412c6a222410840420032006370368200320043703602003202436029001411210322202450d102002410029009bbe44370000200241106a41002f00abbe443b0000200241086a41002900a3be4437000020034292808080a0023702ec01200320023602e80120034190016a200341e8016a108a0120032802ec01212720032802f001212520032802e8012102200341f8046a41186a22264200370300200341f8046a41106a22284200370300200341f8046a41086a22184200370300200342003703f80420022025200341f8046a1000200341d8046a41186a2026290300370300200341d8046a41106a2028290300370300200341d8046a41086a2018290300370300200320032903f8043703d80420034190016a200341d8046a10b3030240024020032d00a00122264102470d00200341f8046a41186a22264200370300200341f8046a41106a22284200370300200341f8046a41086a22184200370300200342003703f80441c4bfc400411a200341f8046a1000200341d8046a41186a22192026290300370300200341d8046a41106a221a2028290300370300200341d8046a41086a221b2018290300370300200320032903f8043703d80420034190046a200341d8046a41201059024020032d0090040d00202642003703002028420037030020184200370300200342003703f80441c4bfc400411a200341f8046a100020192026290300370300201a2028290300370300201b2018290300370300200320032903f8043703d804200341203602ec012003200341d8046a3602e8012024200341e8016a10890141002124410021260c020b200341b8046a41186a200341a9046a290000370300200341b8046a41106a200341a1046a290000370300200341b8046a41086a20034199046a29000037030020032003290091043703b8042003200341b8046a3602e002411210322226450d132026410029009bbe44370000202641106a41002f00abbe443b0000202641086a41002900a3be4437000020034292808080a0023702ec01200320263602e801200341e0026a200341e8016a108a0120032802ec01211b20032802f001211a20032802e8012119200341f8046a41186a22264200370300200341f8046a41106a22284200370300200341f8046a41086a22184200370300200342003703f8042019201a200341f8046a1000200341d8046a41186a221c2026290300370300200341d8046a41106a221d2028290300370300200341d8046a41086a221e2018290300370300200320032903f8043703d804200341e8016a200341d8046a10b30320032d00f8014102460d14200341e8016a41086a290300211720032903e8012106200341e0026a200341e8016a41106a41c200109b051a200341e8016a200341e0026a41c200109b051a200341f4026a221f2003418a026a410020032d0089024101461b360200200320173703e802200320063703e002200320243602f002202642003703002028420037030020184200370300200342003703f8042019201a200341f8046a1000201c2026290300370300201d2028290300370300201e2018290300370300200320032903f8043703d8042003410036028005200342013703f8042003200341e0026a3602b003200341b0036a200341f8046a109b010240024020032802f0020d0041002118200341003a009f050240024020032802fc042003280280052226460d0020032802f80421280c010b202641016a22282026490d3020264101742218202820282018491b22184100480d300240024020260d002018103221280c010b20032802f80420262018103421280b2028450d18200320183602fc04200320283602f80420032d009f05211820032802800521260b2003202641016a36028005202820266a20183a00000c010b200341013a009f050240024020032802fc042003280280052226460d004101211820032802f80421280c010b202641016a22282026490d2f20264101742218202820282018491b22184100480d2f0240024020260d002018103221280c010b20032802f80420262018103421280b2028450d18200320183602fc04200320283602f80420032d009f05211820032802800521260b2003202641016a36028005202820266a20183a0000200341e0026a41106a200341f8046a108a010b0240024020032802f4020d0041002118200341003a009f050240024020032802fc042003280280052226460d0020032802f80421280c010b202641016a22282026490d3020264101742218202820282018491b22184100480d300240024020260d002018103221280c010b20032802f80420262018103421280b2028450d1a200320183602fc04200320283602f80420032d009f05211820032802800521260b2003202641016a36028005202820266a20183a00000c010b41012118200341013a009f050240024020032802fc042003280280052226460d0020032802f80421280c010b202641016a22282026490d2f20264101742218202820282018491b22184100480d2f0240024020260d002018103221280c010b20032802f80420262018103421280b2028450d1a200320183602fc04200320283602f80420032d009f05211820032802800521260b2003202641016a36028005202820266a20183a0000201f200341f8046a108a010b20032802fc042126200341d8046a412020032802f8042228200328028005100502402026450d00202810290b0240201b450d00201910290b200341f8046a41186a22264200370300200341f8046a41106a22284200370300200341f8046a41086a22184200370300200342003703f80441c4bfc400411a200341f8046a1000200341d8046a41186a2026290300370300200341d8046a41106a2028290300370300200341d8046a41086a2018290300370300200320032903f8043703d804200341203602ec012003200341d8046a3602e8012024200341e8016a108901200341f0006a41086a200341b8046a41086a290300370300200341f0006a41106a200341b8046a41106a290300370300200341f0006a41186a200341b8046a41186a290300370300200320032903b80437037041012124410021260c010b200341c0006a41186a200341b9016a290000370300200341c0006a41106a200341b1016a290000370300200341c0006a41086a200341a9016a290000370300200341f0006a41086a200341ca016a290100370300200341f0006a41106a200341d2016a290100370300200341f0006a41186a200341da016a2901003703002003200341a1016a2900003703402003200341c2016a290100370370200341c1016a2d000021240b2003418d026a20243a00002003418e026a2003290370370100200341f5016a200341c0006a41086a290300370000200341fd016a200341c0006a41106a29030037000020034185026a200341c0006a41186a29030037000020034196026a200341f0006a41086a2903003701002003419e026a200341f0006a41106a290300370100200341a6026a200341f0006a41186a290300370100200320263a00ec01200320032903403700ed012003200341e0006a3602e801200341f8046a41186a22244200370300200341f8046a41106a22264200370300200341f8046a41086a22284200370300200342003703f80420022025200341f8046a1000200341d8046a41186a2024290300370300200341d8046a41106a2026290300370300200341d8046a41086a2028290300370300200320032903f8043703d80420034100360298012003420137039001200320032802e8013602e002200341e0026a20034190016a109b010240024020032d00ec014101460d00200341003a009f05024002402003280294012003280298012225460d004100212620032802900121240c010b202541016a22242025490d2e20254101742226202420242026491b22264100480d2e0240024020250d002026103221240c010b20032802900120252026103421240b2024450d1a2003202636029401200320243602900120032d009f05212620032802980121250b2003202541016a36029801202420256a20263a00000c010b200341013a009f05024002402003280294012003280298012225460d004101212620032802900121240c010b202541016a22242025490d2d20254101742226202420242026491b22264100480d2d0240024020250d002026103221240c010b20032802900120252026103421240b2024450d1a2003202636029401200320243602900120032d009f05212620032802980121250b2003202541016a36029801202420256a20263a0000200341e8016a41057220034190016a1081010b0240024020032d008d024101460d0041002126200341003a009f05024002402003280294012003280298012225460d0020032802900121240c010b202541016a22242025490d2e20254101742226202420242026491b22264100480d2e0240024020250d002026103221240c010b20032802900120252026103421240b2024450d1c2003202636029401200320243602900120032d009f05212620032802980121250b2003202541016a36029801202420256a20263a00000c010b200341013a009f05024002402003280294012003280298012225460d004101212620032802900121240c010b202541016a22242025490d2d20254101742226202420242026491b22264100480d2d0240024020250d002026103221240c010b20032802900120252026103421240b2024450d1c2003202636029401200320243602900120032d009f05212620032802980121250b2003202541016a36029801202420256a20263a00002003418e026a20034190016a1081010b2003280294012125200341d8046a41202003280290012224200328029801100502402025450d00202410290b02402027450d00200210290b20032802e403450d2c20032802e0031029410021250c2f0b2001410c6a2802002118200141086a280200211d200141046a280200211c2002411a6a2901002117200241196a2d00002119200241186a2d0000211a200241166a2f0100211b200241156a2d0000211e200241146a2d0000211f200241126a2f01002120200241116a2d00002121200241106a2d000021222002410e6a2f010021232002410d6a2d00002112200241046a2d00002107200241026a2f0100210841a0f9c2002125412a21240240024020022d0000450d004101212641002127410021280c010b41012126410021274100212820022d00014101470d002002410c6a2d000021282002410a6a2f01002127200241096a2d00002124200241066a2f0100410874200241056a2d000072200241086a2d0000411874722125410021260b202741ffff0371410874202441ff017172202841187472212420260d28200320173703d802200320193a00d7022003201a3a00d6022003201b3b01d4022003201e3a00d3022003201f3a00d202200320203b01d002200320213a00cf02200320223a00ce02200320233b01cc02200320123a00cb02200320243600c702200320253600c302200320073a00c202200320083b01c002200341e8016a200341c0026a10f902024020032802880222250d004110212441ea94c50021250c290b20034190046a41086a200341e8016a41346a290200221737030020034190016a41086a2224201737030020034190016a41106a2226200341e8016a413c6a29020037030020034190016a41186a2227200341e8016a41c4006a2902003703002003200341e8016a412c6a2902002217370390042003201737039001200341b4026a2802002128200341e8016a41286a2802002119200341e8016a410c6a350200211720032802e801211a20032902ec01210620032903f8012104200328028c022102200341e0026a41186a200341e8016a41186a290300370300200341e0026a410c6a20173e0200200341e0026a41286a2019360200200341e0026a41246a2002360200200320043703f002200320063702e40220032025360280032003201a3602e002200341e0026a41c4006a2027290300370200200341e0026a413c6a2026290300370200200341e0026a41346a2024290300370200200320032903900137028c03200320283602ac0320180d2641c796c500212541172124410121260c270b20022d00000d2c20022d00014101470d2c200241196a2d00002125200241186a2d00002124200241166a2f01002126200241156a2d00002127200241146a2d00002128200241126a2f01002118200241116a2d00002119200241106a2d0000211a2002410e6a2f0100211b2002410d6a2d0000211c2002410c6a2d0000211d2002410a6a2f0100211e200241096a2d0000211f200241086a2d00002120200241066a2f01002121200241056a2d00002122200241046a2d00002123200241026a2f0100211220032002411a6a2901003703f802200320253a00f702200320243a00f602200320263b01f402200320273a00f302200320283a00f202200320183b01f002200320193a00ef022003201a3a00ee022003201b3b01ec022003201c3a00eb02200320233a00e202200320123b01e0022003201f201e41087472201d411874723600e702200320222021410874722020411874723600e302200341e8016a200341e0026a10f9022003280288022202450d2b20034190046a41086a200341e8016a41346a2902002217370300200341c0036a41086a22252017370300200341d0036a2224200341e8016a413c6a290200370300200341c0036a41186a2226200341e8016a41c4006a2902003703002003200341e8016a412c6a290200221737039004200320173703c003200341b4026a2802002127200341e8016a410c6a350200211720032802e801212820032902ec01210620032903f8012104200329028c02210520034190016a41186a200341e8016a41186a29030037030020034190016a410c6a20173e0200200341b4016a22182005370200200320043703a0012003200637029401200320023602b001200320283602900120034190016a41c4006a202629030037020020034190016a413c6a202429030037020020034190016a41346a2025290300370200200320032903c0033702bc01200320273602dc0120034190016a412c6a220210830420021084042018280200450d2a20032802b0011029410021250c2d0b20022d00000d2b20022d00014101470d2b20012d00012107200241196a2d00002125200241186a2d00002124200241166a2f01002126200241156a2d00002127200241146a2d00002128200241126a2f01002118200241116a2d00002119200241106a2d0000211a2002410e6a2f0100211b2002410d6a2d0000211c2002410c6a2d0000211d2002410a6a2f0100211e200241096a2d0000211f200241086a2d00002120200241066a2f01002121200241056a2d00002122200241046a2d00002123200241026a2f0100211220032002411a6a2901003703f802200320253a00f702200320243a00f602200320263b01f402200320273a00f302200320283a00f202200320183b01f002200320193a00ef022003201a3a00ee022003201b3b01ec022003201c3a00eb02200320233a00e202200320123b01e0022003201f201e41087472201d411874723600e702200320222021410874722020411874723600e302200341e8016a200341e0026a10f9022003280288022202450d2a20034190046a41086a200341e8016a41346a2902002217370300200341c0036a41086a22252017370300200341c0036a41106a2224200341e8016a413c6a290200370300200341c0036a41186a2226200341e8016a41c4006a2902003703002003200341e8016a412c6a290200221737039004200320173703c003200341b4026a2802002127200341e8016a410c6a350200211720032802e801212820032902ec01210620032903f8012104200329028c02210520034190016a41186a200341e8016a41186a29030037030020034190016a410c6a20173e0200200341b4016a2005370200200320043703a0012003200637029401200320023602b001200320283602900120034190016a41c4006a202629030037020020034190016a413c6a202429030037020020034190016a41346a2025290300370200200320032903c0033702bc01200320273602dc01410d10322202450d18200241002900cabe44370000200241056a41002900cfbe443700002003428d808080d0013702ec01200320023602e80120034190016a412c6a200341e8016a10810120032802ec01212420032802f001210220032802e8012125200341f8046a41186a22264200370300200341f8046a41106a22274200370300200341f8046a41086a22284200370300200342003703f80420252002200341f8046a1000200341d8046a41186a2026290300370300200341d8046a41106a2027290300370300200341d8046a41086a2028290300370300200320032903f8043703d804024002400240024002400240200741037122024103460d0020020e03010203010b200341d8046a41204101410010050c040b200341003a009f050c020b200341013a009f050c010b200341023a009f050b410110322202450d1a200220032d009f053a0000200341d8046a4120200241011005200210290b02402024450d00202510290b20032802b401450d2920032802b0011029410021250c2c0b2001411d6a29000021062001411c6a2d000021072001411b6a2d00002108200141196a2f00002109200141186a2d0000210a200141176a2d0000210b200141156a2f0000210c200141146a2d0000210d200141136a2d0000210e200141116a2f0000210f200141106a2d000021102001410c6a2802002111200141086a2802002118200141076a2d00002113200141056a2f00002114200141046a2d000021152002411a6a2901002117200241196a2d00002119200241186a2d0000211a200241166a2f0100211b200241156a2d0000211c200241146a2d0000211d200241126a2f0100211e200241116a2d0000211f200241106a2d000021202002410e6a2f010021212002410d6a2d00002122200241046a2d00002123200241026a2f0100211241a0f9c2002125412a21240240024020022d0000450d004101212641002127410021280c010b41012126410021274100212820022d00014101470d002002410c6a2d000021282002410a6a2f01002127200241096a2d00002124200241066a2f0100410874200241056a2d000072200241086a2d0000411874722125410021260b202741ffff0371410874202441ff017172202841187472212420260d2e200320173703d004200320193a00cf042003201a3a00ce042003201b3b01cc042003201c3a00cb042003201d3a00ca042003201e3b01c8042003201f3a00c704200320203a00c604200320213b01c404200320223a00c304200320243600bf04200320253600bb04200320233a00ba04200320123b01b804200341e8016a200341b8046a108e0441012126024020032d00e8014101460d0041fa94c5002125410b2124410121270c300b200320032902ec0137009304200320032d00eb013a009204200320032f00e9013b019004200320034181026a2900003703a8042003200341fd016a2800003602a4042003200341f5016a29000037029c042003200341f4016a2d00003a009b040240201541ff01714101470d00200341e8016a201841067610ab0220032802e80121250240024020032802f0012018413f7122024b0d00410021020c010b202520024105746a2202290018210620022d0017210720022d0016210820022f0014210920022d0013210a20022d0012210b20022f0010210c20022d000f210d20022d000e210e20022f000c210f20022d000b2110200228000721112002280003211820022d0002211320022f00002114410121020b024020032802ec01450d00202510290b2002450d2e0b200320063703f802200320073a00f702200320083a00f602200320093b01f4022003200a3a00f3022003200b3a00f2022003200c3b01f0022003200d3a00ef022003200e3a00ee022003200f3b01ec02200320103a00eb02200320113600e702200320183600e302200320133a00e202200320143b01e002410e10322202450d19200241002900bcbe44370000200241066a41002900c2be443700002003428e808080e0013702ec01200320023602e801200341e0026a200341e8016a10810120032802ec01212520032802f001212420032802e8012102200341f8046a41186a22264200370300200341f8046a41106a22274200370300200341f8046a41086a22284200370300200342003703f80420022024200341f8046a1000200341d8046a41186a2026290300370300200341d8046a41106a2027290300370300200341d8046a41086a2028290300370300200320032903f8043703d804200341d8046a41204101410041001007212402402025450d00200210290b2024417f470d2c200341e0026a20034190046a4120109d05450d28410e10322202450d1a200241002900e4bd44370000200241066a41002900eabd443700002003428e808080e0013702ec01200320023602e801200341b8046a200341e8016a10810120032802ec01212520032802f001212420032802e8012102200341f8046a41186a22264200370300200341f8046a41106a22274200370300200341f8046a41086a22284200370300200342003703f80420022024200341f8046a1000200341d8046a41186a2026290300370300200341d8046a41106a2027290300370300200341d8046a41086a2028290300370300200320032903f8043703d804200341203602ec012003200341d8046a3602e801200341e0026a200341e8016a10890102402025450d00200210290b410e10322202450d1b200241002900bcbe44370000200241066a41002900c2be443700002003428e808080e0013702ec01200320023602e80120034190046a200341e8016a10810120032802ec01212520032802f001212420032802e8012102200341f8046a41186a22264200370300200341f8046a41106a22274200370300200341f8046a41086a22284200370300200342003703f80420022024200341f8046a1000200341d8046a41186a2026290300370300200341d8046a41106a2027290300370300200341d8046a41086a2028290300370300200320032903f8043703d804200341e8016a200341d8046a10b60302402003280288022224450d00200341d8046a41201004200341c0036a41186a200341e8016a41186a290300370300200341c0036a41106a200341e8016a41106a290300370300200341c0036a41086a200341e8016a41086a29030037030020034190016a41086a20034194026a222629020037030020034190016a41106a2003419c026a222729020037030020034190016a41186a200341a4026a222829020037030020034190016a41206a2218200341ac026a2219290200370300200341b8016a221a200341b4026a221b280200360200200320032903e8013703c0032003200329028c023703900102402025450d00200210290b2003418c026a200329039001370200200341e8016a41186a200341c0036a41186a290300370300200341e8016a41106a200341c0036a41106a290300370300200341e8016a41086a200341c0036a41086a290300370300202620034190016a41086a290300370200202720034190016a41106a290300370200202820034190016a41186a29030037020020192018290300370200201b201a280200360200200320032903c0033703e8012003202436028802410e10322202450d1d200241002900bcbe44370000200241066a41002900c2be443700002003428e808080e0013702fc04200320023602f804200341e0026a200341f8046a10810120032802fc042125200328028005212420032802f8042102200341f8046a41186a22264200370300200341f8046a41106a22274200370300200341f8046a41086a22284200370300200342003703f80420022024200341f8046a1000200341d8046a41186a2026290300370300200341d8046a41106a2027290300370300200341d8046a41086a2028290300370300200320032903f8043703d804200341203602fc042003200341d8046a3602f804200341e8016a200341f8046a10980402402025450d00200210290b200328028c02450d292003280288021029410021250c2c0b2025450d2820021029410021250c2b0b41012126024020022d000120022d000072450d0041f8f8c200212541282124410121270c2f0b200141046a2802002102200341e8016a41086a22254200370300200342003703e80141f8acc5004116200341e8016a100320034190016a41086a2025290300370300200320032903e80137039001200320023602e80120034190016a4110200341e8016a410410050c200b20022d000120022d0000720d20200341e8016a41086a22024200370300200342003703e80141f9adc5004110200341e8016a100320034190016a41086a2002290300370300200320032903e80137039001200341023a009f0541012126410110322202450d1b200220032d009f053a000020034190016a4110200241011005200210290c1f0b20022d000120022d0000720d1f200341e8016a41086a22024200370300200342003703e80141f9adc5004110200341e8016a100320034190016a41086a2002290300370300200320032903e8013703900141012126200341013a009f05410110322202450d1b200220032d009f053a000020034190016a4110200241011005200210290c1e0b200141086a2802002128200141046a2802002118024020022d000120022d000072450d0041f8f8c20021254128212441002127410121262028450d2c201810290c2c0b2001410c6a2802002102200341e8016a41086a22254200370300200342003703e801418893c5004115200341e8016a100320034190016a41086a2025290300370300200320032903e80137039001200341103602ec01200320034190016a3602e80120182002200341e8016a109501410121262028450d1c201810290c1c0b410e4101102e000b410e4101102e000b410e4101102e000b410d4101102e000b41014101102e000b20184108102e000b41184108102e000b201a4108102e000b41124101102e000b41124101102e000b41a895c500419f01109201000b20184101102e000b20184101102e000b20184101102e000b20184101102e000b20264101102e000b20264101102e000b20264101102e000b20264101102e000b410d4101102e000b41014101102e000b410e4101102e000b410e4101102e000b410e4101102e000b410e4101102e000b41014101102e000b41014101102e000b20034190016a41186a20034194026a220241186a29000037030020034190016a41106a200241106a29000037030020034190016a41086a200241086a290000370300200342f3e885db96cddbb3203703f8042003200229000037039001200341306a41d983c300410d105d20032003280234410020032802301b3602d804200341e0026a20034190016a10b00120032802e402212520032802e002210220032802e8022124200341f4026a200341f8046a3602002003200220244105746a3602ec02200320023602e802200320253602e402200320023602e0022003200341d8046a3602f00220034190046a200341e0026a1049200341e0026a41086a20034190046a41086a28020036020020032003290390043703e00220034190016a200341e0026a10c10120034190016a10a7010c060b41002127410021250c0e0b41002125410121270c0d0b41f8f8c2002125412821240c0b0b2003410036029004200341103602d0032003201c201841246c6a3602cc032003201c3602c8032003201d3602c4032003201c3602c003200320034190046a3602d403200341e8016a200341c0036a109904024002400240024002400240024002400240024020032d00e8014101460d0020032802cc03212420032802c803210202400340024020242002470d00200221260c020b20022d00002125200241246a2226210220254102470d000b0b200320263602c8034100212841012118024020032802c4030d00410021020c020b20032802c0031029410021020c010b412010322218450d01201820032900e901370000201841186a20034181026a290000370000201841106a200341f9016a290000370000201841086a200341f1016a29000037000020034190016a41106a200341c0036a41106a29030037030020034190016a41086a200341c0036a41086a290300370300200320032903c00337039001200341e8016a20034190016a1099040240024020032d00e8010d0041012102410121280c010b200341e8016a4101722125410221274120212641012102410121280340200341f8046a41186a2219202541186a290000370300200341f8046a41106a221a202541106a290000370300200341f8046a41086a221b202541086a290000370300200320252900003703f804024020022028470d00200241016a22242002490d0f2027202420242027491b222841ffffff3f712028470d0f202841057422244100480d0f0240024020020d002024103221180c010b201820262024103421180b2018450d0b0b201820266a222420032903f804370000202441186a2019290300370000202441106a201a290300370000202441086a201b290300370000202741026a2127202641206a2126200241016a2102200341e8016a20034190016a10990420032d00e8010d000b0b200328029c012126200328029801212502400340024020262025470d00202521270c020b20252d00002124202541246a2227212520244102470d000b0b2003202736029801200328029401450d0020032802900110290b02402003280290042225450d00200328029404212402402028450d00201810290b4100212620032802840321020c090b200341e0026a412c6a2219108304200320023602b803200320283602b403200320183602b0032003201936029001411210322202450d0120024100290089be44370000200241106a41002f0099be443b0000200241086a4100290091be4437000020034292808080a0023702ec01200320023602e80120034190016a200341e8016a108a0120032802ec01211820032802f001212520032802e8012102200341f8046a41186a22244200370300200341f8046a41106a22264200370300200341f8046a41086a22274200370300200342003703f80420022025200341f8046a1000200341d8046a41186a221a2024290300370300200341d8046a41106a221b2026290300370300200341d8046a41086a221c2027290300370300200320032903f8043703d804200341c0036a200341d8046a10b5030240024020032d00cc0322284102470d00202442003703002026420037030020274200370300200342003703f80441d7bec400411a200341f8046a1000201a2024290300370300201b2026290300370300201c2027290300370300200320032903f8043703d80420034190046a200341d8046a41201059024020032d0090040d00200341f8046a41186a22244200370300200341f8046a41106a22264200370300200341f8046a41086a22274200370300200342003703f80441d7bec400411a200341f8046a1000200341d8046a41186a2024290300370300200341d8046a41106a2026290300370300200341d8046a41086a2027290300370300200320032903f8043703d804200341203602ec012003200341d8046a3602e8012019200341e8016a10890141002124410021280c020b200341b8046a41186a200341a9046a290000370300200341b8046a41106a200341a1046a290000370300200341b8046a41086a20034199046a29000037030020032003290091043703b8042003200341b8046a36029001411210322224450d0420244100290089be44370000202441106a41002f0099be443b0000202441086a4100290091be4437000020034292808080a0023702ec01200320243602e80120034190016a200341e8016a108a0120032802ec01211a20032802f001212420032802e8012126200341f8046a41186a22274200370300200341f8046a41106a22284200370300200341f8046a41086a221b4200370300200342003703f80420262024200341f8046a1000200341d8046a41186a2027290300370300200341d8046a41106a2028290300370300200341d8046a41086a201b290300370300200320032903f8043703d804200341e8016a200341d8046a10b50320032d00f4014102460d0520034190016a200341e8016a41d000109b051a200341e0006a41086a222820034190016a41086a22272802003602002003200329039001370360200341e8016a2003419c016a221b41c200109b051a202720282802003602004101212820034190016a41106a22202003418a026a410020032d0089024101461b221c36020020032003290360370390012003201936029c01200341f8046a41186a221d4200370300200341f8046a41106a221e4200370300200341f8046a41086a221f4200370300200342003703f80420262024200341f8046a1000200341d8046a41186a201d290300370300200341d8046a41106a201e290300370300200341d8046a41086a201f290300370300200320032903f8043703d8042003410036028005200342013703f804200328029001221d2027280200200341f8046a109401200341013a009f050240024020032802fc042003280280052224460d0020032802f80421270c010b202441016a22272024490d0e20244101742228202720272028491b22284100480d0e0240024020240d002028103221270c010b20032802f80420242028103421270b2027450d07200320283602fc04200320273602f80420032d009f05212820032802800521240b2003202441016a36028005202720246a20283a0000201b200341f8046a108a0102400240201c0d0041002128200341003a009f050240024020032802fc042003280280052224460d0020032802f80421270c010b202441016a22272024490d1020244101742228202720272028491b22284100480d100240024020240d002028103221270c010b20032802f80420242028103421270b2027450d0a200320283602fc04200320273602f80420032d009f05212820032802800521240b2003202441016a36028005202720246a20283a00000c010b200341013a009f050240024020032802fc042003280280052224460d004101212820032802f80421270c010b202441016a22272024490d0f20244101742228202720272028491b22284100480d0f0240024020240d002028103221270c010b20032802f80420242028103421270b2027450d0a200320283602fc04200320273602f80420032d009f05212820032802800521240b2003202441016a36028005202720246a20283a00002020200341f8046a108a010b20032802fc042124200341d8046a412020032802f8042227200328028005100502402024450d00202710290b0240200328029401450d00201d10290b0240201a450d00202610290b200341f8046a41186a22244200370300200341f8046a41106a22264200370300200341f8046a41086a22274200370300200342003703f80441d7bec400411a200341f8046a1000200341d8046a41186a2024290300370300200341d8046a41106a2026290300370300200341d8046a41086a2027290300370300200320032903f8043703d804200341203602ec012003200341d8046a3602e8012019200341e8016a108901200341f0006a41086a200341b8046a41086a290300370300200341f0006a41106a200341b8046a41106a290300370300200341f0006a41186a200341b8046a41186a290300370300200320032903b80437037041012124410021280c010b200341c0006a41086a200341d5036a290000370300200341c0006a41106a200341dd036a290000370300200341c0006a41186a200341e5036a290000370300200341f0006a41086a200341f6036a290100370300200341f0006a41106a200341fe036a290100370300200341f0006a41186a20034186046a2901003703002003200341cd036a2900003703402003200341ee036a290100370370200341ed036a2d0000212420032802c403450d0020032802c00310290b2003418d026a20243a00002003418e026a2003290370370100200341f5016a200341c0006a41086a290300370000200341fd016a200341c0006a41106a29030037000020034185026a200341c0006a41186a29030037000020034196026a200341f0006a41086a2903003701002003419e026a200341f0006a41106a290300370100200341a6026a200341f0006a41186a290300370100200320283a00ec01200320032903403700ed012003200341b0036a3602e801200341f8046a41186a22244200370300200341f8046a41106a22264200370300200341f8046a41086a22274200370300200342003703f80420022025200341f8046a1000200341d8046a41186a2024290300370300200341d8046a41106a2026290300370300200341d8046a41086a2027290300370300200320032903f8043703d8042003410036029801200342013703900120032802b00320032802b80320034190016a109401200341e8016a41047220034190016a108c012003280294012125200341d8046a41202003280290012224200328029801100502402025450d00202410290b02402018450d00200210290b024020032802b403450d0020032802b00310290b0240200328028403450d0020032802800310290b4100212641012127410021250c130b41204101102e000b41124101102e000b41124101102e000b41a895c500419f01109201000b20284101102e000b20284101102e000b20284101102e000b20244101102e000b02402002450d0020032802800310290b20260d0041012127410021260c0a0b4101212741002126201d450d09201c10290c090b0240200328028c02450d0020032802880210290b410021250c070b1033000b410021250c020b41ea94c5002125411021240c040b41a0f9c2002125412a21240c030b41012126410121270c030b418c94c5002125411921240c010b41c8d8c3002125411521240b41012126410121270b0240024020012d00002202410d4b0d00410120027441be3f710d01024020024106460d002002410d470d012027450d02200141086a280200450d02200141046a28020010290c020b2026450d01200141086a280200450d01200141046a28020010290c010b200141086a280200450d00200141046a28020010290b2000202436020420002025360200200341a0056a24000b4d01017f230041206b22002400200041146a4101360200200042013702042000418c9ac5003602002000410536021c200041c09ac5003602182000200041186a360210200041b8d8c300107d000bb20701057f230041106b22032400200341003602082003420137030020022003106602400240024002400240024002402002450d00200241c4006c210403400240024020012d00004101460d0002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d0a20024101742206200520052006491b22064100480d0a0240024020020d002006103221050c010b200328020020022006103421050b2005450d052003200636020420032005360200200328020821020b2003200241016a360208200520026a41003a0000200141046a28020021060240024020032802042205200328020822026b4104490d00200328020021050c010b200241046a22072002490d0a20054101742202200720072002491b22024100480d0a0240024020050d002002103221050c010b200328020020052002103421050b2005450d062003200236020420032005360200200328020821020b2003200241046a360208200520026a20063600000c010b02400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d0920024101742206200520052006491b22064100480d090240024020020d002006103221050c010b200328020020022006103421050b2005450d062003200636020420032005360200200328020821020b2003200241016a360208200520026a41013a00002003200336020c200141016a2003410c6a1085010240200141216a2d00004101460d0002400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d0a20024101742206200520052006491b22064100480d0a0240024020020d002006103221050c010b200328020020022006103421050b2005450d082003200636020420032005360200200328020821020b2003200241016a360208200520026a41003a00000c010b02400240200328020420032802082202460d00200328020021050c010b200241016a22052002490d0920024101742206200520052006491b22064100480d090240024020020d002006103221050c010b200328020020022006103421050b2005450d082003200636020420032005360200200328020821020b2003200241016a360208200520026a41013a0000200141226a20031081010b200141c4006a2101200441bc7f6a22040d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b20064101102e000b20024101102e000b20064101102e000b20064101102e000b20064101102e000b1033000b840b02037f017e024002400240024002400240024002400240024002400240024020002802000e0400010203000b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0c20024101742204200320032004491b22044100480d0c0240024020020d002004103221030c010b200128020020022004103421030b2003450d0420012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41013a00002000280204210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d0c20024101742200200420042000491b22004100480d0c0240024020020d002000103221020c010b200128020020022000103421020b2002450d0520012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0b20024101742204200320032004491b22044100480d0b0240024020020d002004103221030c010b200128020020022004103421030b2003450d0520012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41023a00002000290308210502400240200141046a2802002202200428020022006b4108490d00200128020021020c010b200041086a22032000490d0b20024101742200200320032000491b22004100480d0b0240024020020d002000103221020c010b200128020020022000103421020b2002450d0620012002360200200141046a2000360200200141086a28020021000b200141086a200041086a360200200220006a20053700000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0a20024101742204200320032004491b22044100480d0a0240024020020d002004103221030c010b200128020020022004103421030b2003450d0620012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41033a00002000280204210302400240200141046a2802002202200428020022006b4104490d00200128020021020c010b200041046a22042000490d0a20024101742200200420042000491b22004100480d0a0240024020020d002000103221020c010b200128020020022000103421020b2002450d0720012002360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200220006a20033600000f0b02400240200141046a280200200141086a2802002202460d00200128020021030c010b200241016a22032002490d0920024101742204200320032004491b22044100480d090240024020020d002004103221030c010b200128020020022004103421030b2003450d0720012003360200200141046a2004360200200141086a28020021020b200141086a2204200241016a360200200320026a41043a00002000290308210502400240200141046a2802002202200428020022006b4108490d00200128020021020c010b200041086a22032000490d0920024101742200200320032000491b22004100480d090240024020020d002000103221020c010b200128020020022000103421020b2002450d0820012002360200200141046a2000360200200141086a28020021000b200141086a200041086a360200200220006a20053700000f0b20044101102e000b20004101102e000b20044101102e000b20004101102e000b20044101102e000b20004101102e000b20044101102e000b20004101102e000b1033000b130020004101360204200041ecdcc2003602000b3400200041cbe0c20036020420004100360200200041146a4106360200200041106a41d4e0c200360200200041086a42073702000b2f01017f02404101103222020d0041014101102e000b200042818080801037020420002002360200200241003a00000b130020004101360204200041fcebc2003602000b880201057f230041106b22022400024002400240411110322203450d002002421137020420022003360200410d200210660240024020022802042204200228020822036b410d490d002003410d6a2105200228020021040c010b2003410d6a22052003490d0320044101742206200520052006491b22064100480d030240024020040d002006103221040c010b200228020020042006103421040b2004450d0220022006360204200220043602000b20022005360208200420036a220341002900a1db42370000200341056a41002900a6db4237000020002002290300370200200041086a2002280208360200200241106a24000f0b41114101102e000b20064101102e000b1033000bc904010b7f230041106b220324002003420037030820012002200341086a102420032003290308370300200120026a21040240024002400240200241086a220520024f0d00200341086a2106200321074100210841002105410121094100210a0340200841017421022006200741016a220b6b210c034020072d00002107024002400240024020082005470d00200c2105024002400240200a41ff01710e03010200010b200420016b21050c010b417f200c200420016b6a22052005200c491b21050b2008417f200541016a220d200d2005491b6a22052008490d072002200520052002491b22054100480d070240024020080d002005103221090c010b200920082005103421090b2009450d010b200920086a20073a00000240024002400240200a41ff01710e03010300010b20042001460d010c050b0240200b2006460d004100210a0c040b20042001470d040b200841016a21080c090b4101210a200b2006470d01200841016a21080c080b20054101102e000b200841016a2108200b21070c020b200841016a21084102210a200241026a21022001220741016a21010c000b0b0b410121092005450d0120054100480d002005103222090d0120054101102e000b1033000b410021080340200920086a200320086a2d00003a0000200841016a22084108470d000b024020020d00410821080c010b200920086a210a410021080340200a20086a200120086a2d00003a00002002200841016a2208470d000b200420016b41086a21080b200020083602082000200536020420002009360200200341106a24000bf70101047f230041c0006b22032400200341206a41186a22044200370300200341206a41106a22054200370300200341206a41086a220642003703002003420037032020012002200341206a1000200341186a2004290300370300200341106a2005290300370300200341086a200629030037030020032003290320370300410021022003410036022020034120200341206a1006210102400240024020032802202204417f470d000c010b024020010d000c010b20044104490d012001280000210420011029410121020b2000200436020420002002360200200341c0006a24000f0b41f7cdc3004133200341206a41ecd6c3001054000ba72901067f230041106b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141046a2203280200200141086a22042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d0120012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d00003a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d0220012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d00013a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d0320012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d00023a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d0420012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d00033a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d0520012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d00043a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d0620012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d00053a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d0720012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d00063a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d0820012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d00073a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d0920012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d00083a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d0a20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d00093a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d0b20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d000a3a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d0c20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d000b3a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d0d20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d000c3a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d0e20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d000d3a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d0f20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d000e3a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d1020012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d000f3a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d1120012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d00103a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d1220012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d00113a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d1320012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d00123a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d1420012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d00133a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d1520012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d00143a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d1620012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d00153a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d1720012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d00163a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d1820012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d00173a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d1920012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d00183a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d1a20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d00193a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d1b20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d001a3a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d1c20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d001b3a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d1d20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d001c3a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d1e20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d001d3a000002400240200328020020042802002205460d00200128020021060c010b200541016a22062005490d2120054101742207200620062007491b22074100480d210240024020050d002007103221060c010b200128020020052007103421060b2006450d1f20012006360200200141046a2007360200200141086a28020021050b2004200541016a360200200620056a20002d001e3a000002400240200328020020042802002204460d00200128020021030c010b200441016a22032004490d2120044101742205200320032005491b22054100480d210240024020040d002005103221030c010b200128020020042005103421030b2003450d2020012003360200200141046a2005360200200141086a28020021040b200141086a200441016a360200200320046a20002d001f3a00002002200041206a360204200241046a2001109b012002200041306a360208200241086a2001109b01200041c0006a2802002104200041c8006a28020022002001106602402000450d00200041306c21000340200441106a20011081012002200436020c2002410c6a2001109b01200441306a2104200041506a22000d000b0b200241106a24000f0b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20074101102e000b20054101102e000b1033000bb28f0106017f017e017f017e1d7f037e230041b0066b2200240010d401200041d8016a41d8efc500411010d50120002903e001210120002802d8012102200041c8016a41c5efc500411310d50102400240024042002001420020021b220120002903d001420020002802c8011b7d220320032001561b42c801540d00200041c0016a41d4f1c5004114105d20002802c401210420002802c001210520004180026a41086a22024200370300200042003703800241e8f1c500411520004180026a1003200041a8046a41086a200229030037030020002000290380023703a8042000410036028805200041a8046a411020004188056a1006210202400240024002400240024002400240024002402000280288052206417f470d00410221070c010b024020020d00410221070c010b2006450d0120022d00002107200210290b200041b8016a41d4f1c5004114105d20002802bc01210620002802b801210820004180026a41086a22024200370300200042003703800241e883c100410d20004180026a100320004188046a41086a2209200229030037030020002000290380023703880420004188056a20004188046a10f20220004188056a41086a280200210a200028028c05210b200028028805210c20024200370300200042003703800241cebdc400411620004180026a10032009200229030037030020002000290380023703880420004100360288052006410020081b210d20004188046a411020004188056a100621022000280288052206417f460d022002450d02200020063602a402200020023602a00220004188056a200041a0026a1031200028028805220e450d014108210f20004188056a41086a2802002108200028028c05211002402006450d00200210290b024020080d0041002111410021120c070b2008410574211320004188056a41206a211441002111410021124108210f41002115200e2102034020004180026a41186a2216200241186a29000037030020004180026a41106a2217200241106a29000037030020004180026a41086a2218200241086a290000370300200020022900003703800220004188056a200d10d901200020153602a00220004188046a41186a2206420037030020004188046a41106a2208420037030020004188046a41086a220942003703002000420037038804200041a0026a410420004188046a1000200041a0036a41186a22192006290300370300200041a0036a41106a221a2008290300370300200041a0036a41086a221b200929030037030020002000290388043703a00302400240200028028c05220920002802900522086b4120490d00200841206a211c20002802880521060c010b200841206a221c2008490d0c20094101742206201c201c2006491b221d4100480d0c0240024020090d00201d103221060c010b2000280288052009201d103421060b2006450d052000201d36028c052000200636028805201d21090b200620086a220820002903a003370000200841186a2019290300370000200841106a201a290300370000200841086a201b2903003700002006201c4101410041001007210802402009450d00200610290b02402008417f470d00200041a0026a41186a22062016290300370300200041a0026a41106a22082017290300370300200041a0026a41086a2209201829030037030020002000290380023703a00220004188056a200041a0026a10870320002802a805450d06200041a0026a41286a221c20004188056a41286a290300370300200041a0026a41206a22192014290300370300200620004188056a41186a221a290300370300200820004188056a41106a221b290300370300200920004188056a41086a221d29030037030020002000290388053703a002201a2016290300370300201b2017290300370300201d2018290300370300200020002903800237038805201420002903a002370300201441086a2009290300370300201441106a2008290300370300201441186a2006290300370300201441206a2019290300370300201441286a201c290300370300024020112012470d00201141016a22062011490d0d20114101742208200620062008491b2212ad42d0007e2201422088a70d0d2001a722064100480d0d0240024020110d0020061032210f0c010b200f201141d0006c20061034210f0b200f450d080b200f201141d0006c6a20004188056a41d000109b051a201141016a21110b200241206a2102201541016a2115201341606a2213450d070c000b0b41f7cdc3004133200041a8066a41ecd6c3001054000b41f7cdc3004133200041a8066a41ecd6c3001054000b410021124108210f410021110c040b201d4101102e000b418987c100418d02109201000b20064108102e000b2010450d00200e10290b200041003602a802200042013703a00220004188056a41106a201136020020004194056a20123602002000200f360290052000200a4100200c1b36028c052000200d36028805200041a0026a20004188056a1088030240200c450d00200b450d00200c4101200c1b10290b20004180026a41086a22024200370300200042003703800241a4f0c200411220004180026a1003200041a8046a41086a200229030037030020002000290380023703a8042000410036028805200041a8046a411020004188056a1006211b0240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200028028805221d417f460d00201b450d002000201d360284022000201b36028002200041b0016a20004180026a102c20002802b0010d32200028028402220841807f712202417f4c0d2e20002802b4012111024002402008410776220f0d004101211a0c010b20021032221a450d2b0b02402011450d0020004188056a41206a2113200041a0036a4101722119410021090340200041003a00c003200941016a2115410021020240024002400240034020082002460d01200041a0036a20026a20002802800222062d00003a00002000200641016a360280022000200241016a22063a00c0032006210220064120470d000b20004188046a41086a2202200041a0036a41086a29030037030020004188046a41106a221c200041a0036a41106a29030037030020004188046a41186a2214200041a0036a41186a290300370300200020002903a003370388042000200820066b36028402200041a0036a20004180026a10aa0120002d00a0034101460d0120004188056a41186a201429030037030020004188056a41106a201c29030037030020004188056a41086a20022903003703002000200029038804370388052013201941e000109b051a200041a0026a20004188056a418001109b051a200f2009470d0320094101742202201520152002491b220f41ffffff0f71200f470d39200f410774220241004e0d020c390b2000410036028402200241ff0171450d00200041003a00c0030b200f450d36201a10290c360b0240024020090d0020021032211a0c010b201a200941077420021034211a0b201a450d050b201a20094107746a200041a0026a418001109b051a20152011460d012000280284022108201521090c000b0b201a450d32201d450d01201b10290c010b4101211a410021114100210f0b4100210602400240201141077422020d00410121104100211e0c010b2002410276220810322210450d282002410776211e0b2004410020051b21090240201a201a20026a22044622050d002011410774210820102102201a2106034020022006290000370000200241186a200641186a290000370000200241106a200641106a290000370000200241086a200641086a290000370000200241206a210220064180016a2106200841807f6a22080d000b201141077441807f6a41077641016a21060b20004180026a41086a22024200370300200042003703800241bfdbc200411220004180026a1003200041a8046a41086a2208200229030037030020002000290380023703a8042000411036028c052000200041a8046a360288052010200620004188056a109501200041e8016a200941026a1089030240024020002802e801221f0d0020024200370300200042003703800241bfdbc200411220004180026a10032008200229030037030020002000290380023703a8042000410036028805200041a8046a411020004188056a1006210202402000280288052208417f460d002002450d00200020083602a402200020023602a00220004188056a200041a0026a10312000280288052218450d2920004190056a2802002106200028028c05211202402008450d00200210290b410021200c020b410021064101211841002112410021200c010b200041e8016a41086a28020021064101212020002802ec012112201f21180b20004180026a41086a22024200370300200042003703800241d4f1c500411420004180026a1003200041a8046a41086a200229030037030020002000290380023703a8044101211b2000200941016a220c36028805200041a8046a411020004188056a41041005200020203a00f701200020043602fc012000201a3602f8012000200041f8016a36028c062000200041f7016a360288064100211c4100210e024020064105742202450d002002410575220e41ffffff0f71200e470d32200e41077422084100480d3220081032221b450d020b0240201820026a2018460d0020064105742109200041a0026a410172211620004188056a41206a211d200041a8046a41c0006a210d200041a8046a41206a21174100211c201b2115201821020340200241086a2900002101200241106a29000021032002290000212120004188046a41186a2214200241186a29000037030020004188046a41106a2211200337030020004188046a41086a22132001370300200020213703880420004180026a20004188046a10a90120002802880221082000280280022106200041003602a00220062008200041a0026a100621080240024020002802a0022219417f470d00410021080c010b024020080d00410021080c010b2000201936029c062000200836029806200041a0026a20004198066a10aa0120002d00a0024101460d28200041a0036a201641e000109b051a02402019450d00200810290b200041a0026a200041a0036a41e000109b051a410121080b0240200028028402450d00200610290b0240024020080d00200041a8046a410041e000109a051a0c010b200041a8046a200041a0026a41e000109b051a0b02402000280288062d00000d00200028028c06220828020022062008280204460d00200820064180016a36020002400240200041a8046a200641206a2208460d002008200041a8046a4120109d050d010b02402017200641c0006a2208460d00200820174120109d050d010b200d200641e0006a2206460d012006200d4120109d05450d010b20002802880641013a00000b200241206a210220004188056a41186a201429030037030020004188056a41106a201129030037030020004188056a41086a2013290300370300200020002903880437038805201d200041a8046a41e000109b051a201c41016a211c201520004188056a418001109b054180016a2115200941606a22090d000b0b02402012450d00201810290b201c41ffffff0f71201c470d2c201c4107742202417f4c0d2c20002d00f70121130240024020020d00410121140c010b200210322214450d250b410021020240201c450d00201b201c4107746a211120004188056a41e0006a210620004188056a41c0006a210820004188056a41206a210941002115034020004188056a41186a201b20156a220241186a29000037030020004188056a41106a200241106a29000037030020004188056a41086a200241086a2900003703002009200241206a290000370000200941086a200241286a290000370000200941106a200241306a290000370000200941186a200241386a2900003700002008200241c0006a290000370000200841086a200241c8006a290000370000200841106a200241d0006a290000370000200841186a200241d8006a2900003700002000200229000037038805200641186a200241f8006a290000370000200641106a200241f0006a290000370000200641086a200241e8006a2900003700002006200241e0006a290000370000201420156a20004188056a418001109b051a20154180016a211520024180016a2011470d000b201c41077441807f6a41077641016a21020b20004180026a41086a22064200370300200042003703800241a4f0c200411220004180026a1003200041a8046a41086a200629030037030020002000290380023703a80420004100360290052000420137038805200220004188056a106602402002450d00201420024107746a211520142102034002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d262000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a20022d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d252000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a200241016a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d242000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a200241026a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d232000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a200241036a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d222000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a200241046a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d212000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a200241056a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d202000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a200241066a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d1f2000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a200241076a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d1e2000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a200241086a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d1d2000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a200241096a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d1c2000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a2002410a6a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d1b2000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a2002410b6a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d1a2000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a2002410c6a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d192000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a2002410d6a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d182000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a2002410e6a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d172000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a2002410f6a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d162000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a200241106a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d152000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a200241116a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d142000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a200241126a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d132000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a200241136a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d122000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a200241146a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d112000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a200241156a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d102000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a200241166a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d0f2000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a200241176a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d0e2000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a200241186a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d0d2000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a200241196a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d0c2000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a2002411a6a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d0b2000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a2002411b6a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d0a2000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a2002411c6a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d092000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a2002411d6a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d082000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a2002411e6a2d00003a000002400240200028028c052000280290052206460d0020002802880521080c010b200641016a22082006490d3420064101742209200820082009491b22094100480d340240024020060d002009103221080c010b20002802880520062009103421080b2008450d072000200936028c05200020083602880520002802900521060b2000200641016a36029005200820066a2002411f6a2d00003a0000200241206a20004188056a10ee012000200241c0006a3602a002200041a0026a20004188056a108a012000200241e0006a3602a002200041a0026a20004188056a108a0120024180016a22022015470d000b0b200028028c052102200041a8046a41102000280288052206200028029005100502402002450d00200610290b0240201c450d00201410290b200020133a00880520004180026a41086a22024200370300200042003703800241e8f1c500411520004180026a1003200041a8046a41086a200229030037030020002000290380023703a804200041a8046a411020004188056a410110052000200c36028c05200041043a0088054101410020004188056a104c410810322206450d03200620043602042006201a36020002402007200741ff0171410247710d00200041a0016a41d9eec500411c10d50120002903a801210120002802a001210220004198016a41d4f1c5004114105d200028029c0121082000280298012109200041a0026a2001420020021b108a0320002802a802211520002802a0022102200041a8046a41186a22144200370300200041a8046a41106a22114200370300200041a8046a41086a22134200370300200042003703a80420022015200041a8046a100020004188056a41186a201429030037030020004188056a41106a201129030037030020004188056a41086a2013290300370300200020002903a8043703880520002008410020091b3602a00320004188056a4120200041a0036a41041005024020002802a402450d00200210290b200610290c2c0b0240024020050d002006201a4180016a22153602002000201a29002237018a052000201a29002a37019205200041a8046a41086a22022000290390053703002000201a29003237019a05200041a8046a41106a22082000290398053703002000201a28003a3601a2052000201a2f003e3b01a605200041a8046a41186a220920002903a005370300200041003a00a8052000201a2d00213a0089052000201a2d00203a00880520002000290388053703a804200041a0026a41186a22142009290300370300200041a0026a41106a22092008290300370300200041a0026a41086a22082002290300370300200020002903a8043703a002201a0d010b200610294108211541002108410021020c2b0b200041a0036a41186a2014290300370300200041a0036a41106a2009290300370300200041a0036a41086a2008290300370300200020002903a0023703a003200420156b41077641016a220241286c2208417f4c0d2c200810322215450d02201520002903a00337030020154201370320201541186a200041a0036a41186a2205290300370300201541106a200041a0036a41106a220a290300370300201541086a200041a0036a41086a220b29030037030002402006280200220820062802042219470d00410121080c2a0b200620084180016a22073602002000200841226a29000037018a0520002008412a6a29000037019205200041a8046a41086a221d2000290390053703002000200841326a29000037019a05200041a8046a41106a221620002903980537030020002008413a6a2800003601a20520002008413e6a2f00003b01a605200041a8046a41186a221720002903a005370300200041003a00a8052000200841216a2d00003a008905200020082d00203a00880520002000290388053703a804200041a0026a41186a22182017290300370300200041a0026a41106a220d2016290300370300200041a0026a41086a2212201d290300370300200020002903a8043703a0024102210841c80021090340200520182903002201370300200a200d2903002203370300200b20122903002221370300200020002903a00222223703a00320004188056a41186a2214200137030020004188056a41106a2211200337030020004188056a41086a22132021370300200020223703880502400240024002402008417f6a2002460d002002210c0c010b201920076b41077620026a41016a22192002490d352002410174220c20192019200c491b220cad42287e2201422088a70d352001a722194100480d350240024020020d002019103221150c010b2015200241286c2019103421150b2015450d010b201520096a221941606a220220002903880537030020132903002101201129030021032014290300212120194201370300200241186a2021370300200241106a2003370300200241086a20013703002006280200220220062802042219470d01200c21020c2c0b20194108102e000b200620024180016a22073602002000200241226a29000037018a0520002002412a6a29000037019205201d2000290390053703002000200241326a29000037019a05201620002903980537030020002002413a6a2800003601a20520002002413e6a2f00003b01a605201720002903a005370300200041003a00a8052000200241216a2d00003a008905200020022d00203a00880520002000290388053703a80420182017290300370300200d20162903003703002012201d290300370300200020002903a8043703a002200941286a2109200841016a2108200c21020c000b0b20024101102e000b20084101102e000b20084108102e000b41084104102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20024101102e000b41f7cdc3004133200041a8066a41ecd6c3001054000b41f7cdc3004133200041a8066a41ecd6c3001054000b20084101102e000b20024101102e000b200610290b20004188046a41086a2206420037030020004200370388044188b4c200411720004188046a1003200041a0026a41086a2209200629030037030020002000290388043703a00220004188056a200041a0026a4110109302024020002802880522144101470d00200041a0026a411010040b20004188056a41086a2802002113200028028c05211120064200370300200042003703880441f9d9c100411d20004188046a10032009200629030037030020002000290388043703a002200041a0026a41104101410041001007210602400240024020144101460d0002402006417f470d0020004190016a41d983c300410d105d2000280294012106200028029001210920004188056a41106a200836020020004194056a20023602002000410036029c0520002015360290052000410036028c0520002006410020091b3602880520004188046a41086a22064200370300200042003703880441f9d9c100411d20004188046a1003200041a0026a41086a200629030037030020002000290388043703a002200041103602a4032000200041a0026a3602a00320004188056a200041a0036a10ad020b20020d010c020b02402006417f470d0020004188016a41d983c300410d105d200028028c012106200028028801210920004180016a41f9c2c200411a105d2006410020091b21060240200028028001450d0020002802840120064b0d010b20004188046a41086a22094200370300200042003703880441f9c2c200411a20004188046a1003200041a0026a41086a2214200929030037030020002000290388043703a0022000200620114101746a36028805200041a0026a411020004188056a41041005200041a0056a201336020020004188056a41106a200836020020004194056a20023602002000410136029c0520002015360290052000201136028c05200020063602880520094200370300200042003703880441f9d9c100411d20004188046a10032014200929030037030020002000290388043703a002200041103602a4032000200041a0026a3602a00320004188056a200041a0036a10ad020b2002450d010b201510290b200041f0006a41d9eec500411c10d501200028027021022000290378210120004188046a41086a22064200370300200042003703880441d9eec500411c20004188046a1003200041a0026a41086a200629030037030020002000290388043703a0022000200142017c420120021b220137038805200041a0026a411020004188056a41081005200041e8006a41d4f1c5004114105d200028026c210620002802682108200041a0026a2001108a0320002802a802210920002802a0022102200041a8046a41186a22154200370300200041a8046a41106a22144200370300200041a8046a41086a22114200370300200042003703a80420022009200041a8046a100020004188056a41186a201529030037030020004188056a41106a201429030037030020004188056a41086a2011290300370300200020002903a8043703880520002006410020081b3602a00320004188056a4120200041a0036a4104100520002802a402450d00200210290b0240410810322202450d00200220043602042002201a360200024041081032220d450d00200d201b201c4107746a220c360204200d201b36020010d401200041d8006a41a6efc500410f10d50102402000290360420020002802581b220142017c22222001540d0020004188046a41086a22064200370300200042003703880441a6efc500410f20004188046a100320004180026a41086a22082006290300370300200020002903880437038002200020223703880520004180026a411020004188056a4108100520004188066a20024194c3c2001047200028028c062114200028028806211c200028029006210220064200370300200042003703880441b5efc500411020004188046a10032008200629030037030020002000290388043703800220004100360290052000420137038805200220004188056a1066024002402002450d00201c200241286c6a2115201c21060340200020063602a002200041a0026a20004188056a108a01200641206a290300210102400240200028028c05220820002802900522026b4108490d0020002802880521080c010b200241086a22092002490d0c20084101742202200920092002491b22024100480d0c0240024020080d002002103221080c010b20002802880520082002103421080b2008450d032000200236028c05200020083602880520002802900521020b2000200241086a36029005200820026a20013700002015200641286a2206470d000b0b200028028c05210220004180026a41102000280288052206200028029005100502402002450d00200610290b02402014450d00201c10290b200041c8006a41d8efc500411010d5012000290350210120002802482102200041386a41c5efc500411310d501024042002001420020021b22032000290340420020002802381b22017d222120212003561b42c801540d00034042002003427f200142c8017c222120212001541b22017d222120212003561b42c701560d000b0b20004188046a41086a22024200370300200042003703880441c5efc500411320004188046a100320004180026a41086a22062002290300370300200020002903880437038002200020013703880520004180026a411020004188056a410810050240202242017c22232022540d0020024200370300200042003703880441aaf0c500411320004188046a10032006200229030037030020002000290388043703800220004188056a20004180026a108b030240024020002d0088054101460d00200041b8026a4200370300200041b0026a4200370300200041a8026a4200370300200042003703a0020c010b200041b8026a200041a1056a290000370300200041b0026a20004199056a290000370300200041a8026a20004191056a29000037030020002000290089053703a0020b200041306a41bdf0c5004111105d200028023421022000280230210620004188046a41086a22084200370300200042003703880441bdf0c500411120004188046a100320004180026a41086a22092008290300370300200020002903880437038002200041003602880520004180026a411020004188056a4104100520004180026a41186a200041a0026a41186a29030037030020004180026a41106a200041a0026a41106a2903003703002009200041a0026a41086a290300370300200020002903a00237038002417f2002410020061b221941016a220220022019491b410d744128722218417f4c0d050240201810322216450d00201620002903800237000020162023370020201641186a20004180026a41186a290300370000201641106a20004180026a41106a290300370000201641086a20004180026a41086a29030037000041282117410021064100211d410021134100211c0240024002400340024002400240024002400240201c450d0020082002470d010b201c4521090340200620194f0d0220004188046a200610d60120002802900421022000280288042108200041a8046a41186a221c4200370300200041a8046a41106a22144200370300200041a8046a41086a22114200370300200042003703a80420082002200041a8046a100020004188056a41186a201c29030037030020004188056a41106a201429030037030020004188056a41086a2011290300370300200020002903a80437038805200041a8046a20004188056a10d7010240024020002802a8042202450d0020004188056a4120100420002902ac0421010c010b42002101410121020b0240200028028c04450d00200810290b2002450d0220022001422088a74105746a210802402009201545724101710d00201310290b200641016a21062001a7211541002109200221132002211d20082002460d000b2002211d200221132002211c0b200241086a2900002101200241106a290000210320022900002121200041a0036a41186a200241186a2900002222370300200041a0036a41106a2003370300200041a0036a41086a2001370300200020213703a00320004188046a41186a2214202237030020004188046a41106a2211200337030020004188046a41086a221220013703002000202137038804201820176b411f4b0d03201741206a22092017490d1320184101742207200920092007491b22094100480d1320180d012009103221160c020b02402009201545724101710d00201d10290b200041a8046a41186a22064200370300200041a8046a41106a22084200370300200041a8046a41086a22094200370300200042003703a80420162017200041a8046a100020004188056a41186a221c200629030037030020004188056a41106a2214200829030037030020004188056a41086a22112009290300370300200020002903a8043703880502402018450d00201610290b20004188046a41086a22024200370300200042003703880441aaf0c500411320004188046a100320004180026a41086a22152002290300370300200020002903880437038002200041103602a403200020004180026a3602a00320004188056a200041a0036a1089012006200041a0026a41186a29030022013703002008200041a0026a41106a29030022033703002009200041a0026a41086a2903002221370300200020002903a00222223703a804201c200137030020142003370300201120213703002000202237038805200242003703002000420037038804419bf0c500410f20004188046a100320152002290300370300200020002903880437038002200041103602a402200020004180026a3602a00220004188056a200041a0026a10890120004198066a200d4194c5c2001047200041206a41c5efc500411310d501200029032821012000280220210920024200370300200042003703880441aaf0c500411320004188046a10032015200229030037030020002000290388043703800220004188056a20004180026a108b0320002d0088054101460d05200041b8036a4200370300200041b0036a4200370300200041a8036a4200370300200042003703a0030c060b201620182009103421160b2016450d02200921180b200241206a2102201620176a2209200029038804370000200941186a2014290300370000200941106a2011290300370000200941086a2012290300370000201741206a21170c000b0b20094101102e000b200041b8036a200041a1056a290000370300200041b0036a20004199056a290000370300200041a8036a20004191056a29000037030020002000290089053703a0030b20004188046a41086a22024200370300200042003703880441e8efc500411320004188046a100320004180026a41086a22062002290300370300200020002903880437038002200041186a20004180026a108c0320002d0019211520002d0018211c41fbefc500412010f101210820024200370300200042003703880441e8efc500411320004188046a100320062002290300370300200020002903880437038002200041106a20004180026a108c0320024200370300200042003703880441e8efc500411320004188046a1003200620022903003703002000200029038804370380020240410210322202450d00200241012015410171201c4102461b22062008410171200841ff01714102461b22083a0001200220063a000020004180026a41102002410210052002102920004188056a41186a42c80137030020004188056a41106a427f2001420020091b220142c8017c220320032001541b37030020004188056a41206a200029039806370300200041b0056a20004198066a41086a280200360200200041b4056a20002903a003370200200041bc056a200041a0036a41086a290300370200200041c4056a200041a0036a41106a290300370200200041cc056a200041a0036a41186a290300370200200041d4056a20083a000020002023370390052000410036028805200041a0026a20004188056a108d0320004193046a200041a0026a41086a280200360000200020002903a00237008b04200041ac026a2000418f046a290000370000200041c28289aa043600a102200041023a00a00220002000290088043700a502200041a0026a10ed0102402000280288050d00200041ac056a280200450d0020002802a80510290b0240410810322206450d00200620043602042006201a3602000240410810322207450d002007200c3602042007201b360200200041086a41d4f1c5004114105d20004188056a200028020c410020002802081b10d901200028028805220220002802900510120240200028028c05450d00200210290b200041d983c300410d105d200028020421022000280200210820004188046a41086a22094200370300200042003703880441d783c100411120004188046a100320004180026a41086a200929030037030020002000290388043703800220002002410020081b3602880520004180026a411020004188056a4104100502402006280200220220062802042209470d0020061029410021024101211c410021080c0c0b200620024180016a22153602002000200241e2006a29000037018a052000200241ea006a29000037019205200041a8046a41086a22082000290390053703002000200241f2006a29000037019a05200041a8046a41106a221c2000290398053703002000200241fa006a2800003601a2052000200241fe006a2f00003b01a605200041a8046a41186a221420002903a0053703002000200241e0006a2f00003b01880520002000290388053703a804200041a0026a41186a22022014290300370300200041a0026a41106a2214201c290300370300200041a0026a41086a221c2008290300370300200020002903a8043703a002200041a0036a41186a22112002290300370300200041a0036a41106a2014290300370300200041a0036a41086a201c290300370300200020002903a0023703a003410121080240200920156b41077641016a220241057422091032221c450d00201c20002903a003370000201c41186a2011290300370000201c41106a200041a0036a41106a290300370000201c41086a200041a0036a41086a2903003700002006280200220920062802042212460d0b200620094180016a220c3602002000200941e2006a29000037018a052000200941ea006a29000037019205200041a8046a41086a22172000290390053703002000200941f2006a29000037019a05200041a8046a41106a22182000290398053703002000200941fa006a2800003601a2052000200941fe006a2f00003b01a605200041a8046a41186a220d20002903a0053703002000200941e0006a2f00003b01880520002000290388053703a804200041a0026a41186a2214200d290300370300200041a0026a41106a22112018290300370300200041a0026a41086a22132017290300370300200020002903a8043703a0024102210841202115034020004188046a41186a2014290300220137030020004188046a41106a2011290300220337030020004188046a41086a20132903002221370300200020002903a00222223703880420004188056a41186a2219200137030020004188056a41106a221d200337030020004188056a41086a221620213703002000202237038805024002402008417f6a2002460d00200221090c010b2012200c6b41077620026a41016a22092002490d1120024101742212200920092012491b220941ffffff3f712009470d11200941057422124100480d110240024020020d0020121032211c0c010b201c200241057420121034211c0b201c0d0020124101102e000b201c20156a2202200029038805370000200241186a2019290300370000200241106a201d290300370000200241086a201629030037000002402006280200220220062802042212470d00200921020c0d0b200620024180016a220c3602002000200241e2006a29000037018a052000200241ea006a2900003701920520172000290390053703002000200241f2006a29000037019a0520182000290398053703002000200241fa006a2800003601a2052000200241fe006a2f00003b01a605200d20002903a0053703002000200241e0006a2f00003b01880520002000290388053703a8042014200d2903003703002011201829030037030020132017290300370300200020002903a8043703a002201541206a2115200841016a2108200921020c000b0b20094101102e000b41084104102e000b41084104102e000b41024101102e000b20184101102e000b41c086c10041c900109201000b20024101102e000b41c086c10041c900109201000b41084104102e000b41084104102e000b102f000b200610290b20004188046a41086a22064200370300200042003703880441e883c100410d20004188046a100320004180026a41086a200629030037030020002000290388043703800220004100360290052000420137038805200820004188056a106602402008450d0020084105742108201c21060340200020063602a002200641206a2106200041a0026a20004188056a108a01200841606a22080d000b0b200028028c05210620004180026a41102000280288052208200028029005100502402006450d00200810290b02402002450d00201c10290b200710290240200e450d00201b10290b02402020201f45720d0020002802ec01450d00201f10290b0240201e450d00201010290b200f450d00201a10290b200041b0066a24000f0b41f7cdc3004133200041a8066a41ecd6c3001054000b1033000bf90401097f23004190016b2202240002400240410f10322203450d00200341002900adbe44370000200341076a41002900b4be443700002002428f808080f00137025c200220033602582001200241d8006a108101200228025c21042002280260210120022802582103200241d8006a41186a22054200370300200241d8006a41106a22064200370300200241d8006a41086a220742003703002002420037035820032001200241d8006a1000200241386a41186a2005290300370300200241386a41106a2006290300370300200241386a41086a20072903003703002002200229035837033820024100360258200241386a4120200241d8006a100621050240024020022802582201417f460d002002200136028c012002200536028801200241d8006a20024188016a10910420022802782206450d03200241186a41186a2207200241d8006a41186a290300370300200241186a41106a2208200241d8006a41106a290300370300200241186a41086a2209200241d8006a41086a290300370300200241086a41086a220a200241d8006a412c6a280200360200200220022903583703182002200229027c37030802402001450d00200510290b2000200229031837030020002006360220200041246a2002290308370200200041186a2007290300370300200041106a2008290300370300200041086a20092903003703002000412c6a200a2802003602000c010b200041186a4200370300200041106a4200370300200041086a420037030020004200370300200041286a4100360200200042083703200b02402004450d00200310290b20024190016a24000f0b410f4101102e000b41f7cdc3004133200241186a41ecd6c3001054000bcead0108027f017e0b7f037e2e7f027e067f0e7e230041c0106b2202240002400240024002400240200141106a2802002203ad42d0007e2204422088a70d002004a72205417f4c0d002001280208210602400240024002400240024002400240024020050d00410821070c010b200510322207450d010b0240024020030d00410021080c010b2006200341d0006c6a2109410021082007210a0340200241f8046a41186a220b200641186a290300370300200241f8046a41106a220c200641106a290300370300200241f8046a41086a220d200641086a290300370300200220062903003703f8042006280248220ead42307e2204422088a70d092004a7220f417f4c0d09200641386a2903002104200641286a290300211020062903302111200629032021122006280240210502400240200f0d00410821130c010b200f10322213450d040b200641d0006a210602400240200e0d00410021140c010b2005200e41306c6a2115410021142013210f0340200f2005290300370300200f200541086a290300370308200f41106a200541106a290300370300200f41186a200541186a290300370300200f41206a200541206a290300370300200f41286a200541286a290300370300200f41306a210f201441016a2114200541306a22052015470d000b0b200a2012370320200a20022903f804370300200a41386a2004370300200a41306a2011370300200a41286a2010370300200a41c8006a2014360200200a41c4006a200e360200200a41c0006a2013360200200a41186a200b290300370300200a41106a200c290300370300200a41086a200d290300370300200841016a2108200a41d0006a210a20062009470d000b0b200028020821162000280204211720002802002118200128020421192001280200210b41041032221a450d02201a200b36000020024284808080c0003702ec072002201a3602e807200241b8086a10a50420022802c008210520022802b808210f200241f8046a41186a22144200370300200241f8046a41106a22154200370300200241f8046a41086a22064200370300200242003703f804200f2005200241f8046a1000200241e00f6a41186a2014290300370300200241e00f6a41106a2015290300370300200241e00f6a41086a2006290300370300200220022903f8043703e00f410021062002410036028807200241e00f6a412020024188076a10062114024002402002280288072215417f470d00410021060c010b024020140d000c010b2002201536028c07200220143602880720024180036a20024188076a102c0240024002402002280280030d00200228028c07220a2002280284032205490d002005417f4c0d0b0240024020050d00410121060c010b2005102d2206450d022006200228028807220e2005109b051a2002200a20056b36028c072002200e20056a360288070b20060d020b41f7cdc3004133200241a8066a41ecd6c3001054000b20054101102e000b2015450d00201410290b4100210a2005410020061b210e2006410120061b2105024020022802bc08450d00200f10290b2002200e3602e40f200220053602e00f200241f8026a200241e00f6a102c20022802fc02210d024020022802f802450d000c070b20022802e40f220541246e221341246c220f417f4c0d0702400240200f0d004104210a0c010b200f1032220a450d040b200d450d064100210c034020054104490d06200c41016a210920022005417c6a22143602e40f200220022802e00f221541046a3602e00f2015280000210041002105200241003a00d8080340024020142005470d00200241003602e40f200541ff0171450d08200241003a00d8080c080b200241b8086a20056a201520056a220f41046a2d00003a00002002200f41056a3602e00f2002200541016a220f3a00d808200f2105200f4120470d000b200241f8046a41086a2215200241b8086a41086a290300370300200241f8046a41106a221b200241b8086a41106a290300370300200241f8046a41186a221c200241b8086a41186a290300370300200220022903b8083703f80420022014200f6b22053602e40f02402013200c470d00200c410174220f20092009200f491b2213ad42247e2204422088a70d0d2004a7220f4100480d0d02400240200c0d00200f1032210a0c010b200a200c41246c200f1034210a0b200a450d060b200a200c41246c6a220f2000360200200f20022903f804370204200f410c6a2015290300370200200f41146a201b290300370200200f411c6a201c2903003702002009210c2009200d470d000c070b0b20054108102e000b200f4108102e000b41044101102e000b200f4104102e000b200f4104102e000b024020130d004100210a0c010b200a10294100210a0b200241e00f6a200241e8076a10a60420022802e80f210f20022802e00f2105200241003602b8082005200f200241b8086a1006210f0240024020022802b8082214417f460d00200f450d002002201436028c072002200f36028807200241b8086a20024188076a1031024020022802b808221d450d00200241c0086a280200211e20022802bc08211f2014450d02200f10290c020b41f7cdc3004133200241a8066a41ecd6c3001054000b4101211d4100211f4100211e0b024020022802e40f450d00200510290b0240200e450d002006410120061b10290b200a4104200a1b210c200d4100200a1b212020134100200a1b21212002420037028c03200241b0d6c000360288032007200841d0006c6a21220240024020080d00200721130c010b200241e8036a41306a2123200241b8086a410c6a212420164101742205201641ffffff3f71222520252005491b222641ffffff3f71202647212720264105742128202520164721292016410574222a41606a41057641016a212b200241b8086a410272212c200241c8056a41046a212d200241b8086a41c0006a212e200241e00f6a41106a211c200241e8076a410472212f200241e8036a41c4006a213020182018202a6a46213120072113024002400340200241b8086a41386a22062013220541386a290300370300200241b8086a41306a220a200541306a290300370300200241b8086a41286a220e200541286a290300370300200241b8086a41206a2232200541206a290300370300200241b8086a41186a2233200541186a290300370300200241b8086a41106a2234200541106a290300370300200241b8086a41086a2235200541086a290300370300200241e00f6a41086a220d200541cc006a280200360200200220052903003703b8082002200541c4006a2902003703e00f200541d0006a2113200541c0006a2802002205450d03200241a8036a41386a220f2006290300370300200241a8036a41306a2214200a290300370300200241a8036a41286a2215200e290300370300200241a8036a41206a22092032290300370300200241a8036a41186a22002033290300370300200241a8036a41106a221b2034290300370300200241a8036a41086a2236203529030037030020024198036a41086a2237200d280200360200200220022903b8083703a803200220022903e00f37039803200241e8036a41386a2238200f29030037030020232014290300370300200241e8036a41286a22392015290300370300200241e8036a41206a22152009290300370300200241e8036a41186a223a2000290300370300200241e8036a41106a223b201b290300370300200241e8036a41086a223c2036290300370300200220022903a8033703e803200220053602a8042030200229039803370200203041086a2037280200360200024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240410410322214450d002014200b36000020244100290098a845370000202441086a41002900a0a84537000020024284808080c0003702bc08200220143602b8082002200241e8036a3602d408410810322205450d01200242083702e40f200220053602e00f2024200241e00f6a10ec024104200241e00f6a10660240024020022802e40f220f20022802e80f22056b4104490d0020022802e00f210f0c010b200541046a22092005490d30200f4101742205200920092005491b22054100480d3002400240200f0d0020051032210f0c010b20022802e00f200f20051034210f0b200f450d03200220053602e40f2002200f3602e00f20022802e80f21050b2002200541046a3602e80f200f20056a20142800003600000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d04200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00e8033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d05200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00e9033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d06200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00ea033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d07200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00eb033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d08200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00ec033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d09200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00ed033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d0a200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00ee033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d0b200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00ef033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d0c200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00f0033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d0d200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00f1033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d0e200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00f2033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d0f200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00f3033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d10200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00f4033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d11200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00f5033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d12200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00f6033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d13200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00f7033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d14200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00f8033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d15200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00f9033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d16200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00fa033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d17200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00fb033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d18200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00fc033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d19200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00fd033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d1a200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00fe033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d1b200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d00ff033a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d1c200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d0080043a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d1d200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d0081043a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d1e200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d0082043a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d1f200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d0083043a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d20200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d0084043a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d21200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d0085043a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d22200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d0086043a00000240024020022802e40f20022802e80f2205460d0020022802e00f210f0c010b200541016a220f2005490d3020054101742209200f200f2009491b22094100480d300240024020050d0020091032210f0c010b20022802e00f200520091034210f0b200f450d23200220093602e40f2002200f3602e00f20022802e80f21050b2002200541016a3602e80f200f20056a20022d0087043a0000200220153602e807200241e8076a200241e00f6a109b01200220233602e807200241e8076a200241e00f6a109b0120022802a804210520022802b004220f200241e00f6a10660240200f450d00200f41306c210f0340200541106a200241e00f6a108101200220053602e807200541306a2105200241e8076a200241e00f6a109b01200f41506a220f0d000b0b20022802e40f210f20022802e80f211520022802e00f2105200241f8046a41186a22094200370300200241f8046a41106a22004200370300200241f8046a41086a221b4200370300200242003703f80420052015200241f8046a1000200241b8046a41186a223d2009290300370300200241b8046a41106a223e2000290300370300200241b8046a41086a223f201b290300370300200220022903f8043703b8040240200f450d00200510290b20141029411010322205450d23200541002900ca97452204370000200541086a41002900d2974522103700002002429080808080023702bc08200220053602b8082002200241b8086a3602e00f200241b8046a200241e00f6a10850120022802bc08210f20022802b808210520022802c00821142009420037030020004200370300201b4200370300200242003703f80420052014200241f8046a1000200241e00f6a41186a22362009290300370300201c2000290300370300200d201b290300370300200220022903f8043703e00f200241e00f6a4120410141004100100721140240200f450d00200510290b2014417f460d250c240b41044101102e000b41084101102e000b20054101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b20094101102e000b41104101102e000b20022802ac04450d0120022802a80410290c010b200241d8046a41186a2240203a290300370300200241d8046a41106a223a203b290300370300200241d8046a41086a223b203c290300370300200220022903e8033703d80420022802b0042237ad42307e2211422088a70d052011a7220f417f4c0d0520382903002111203929030021122002290398042141200229038804214220022802a8042105024002400240024002400240024002400240024002400240200f0d00410821380c010b200f10322238450d010b0240024020370d00410021140c010b2005203741306c6a2115410021142038210f0340200f2005290300370300200f200541086a290300370308200f41106a200541106a290300370300200f41186a200541186a290300370300200f41206a200541206a290300370300200f41286a200541286a290300370300200f41306a210f201441016a2114200541306a22052015470d000b0b200241e00f6a41386a2011370300200241e00f6a41286a201237030020362040290300370300201c203a290300370300200d203b29030037030020022041370390102002204237038010200220022903d8043703e00f200220143602a810200220373602a410200220383602a01002400240200228028803220541b0d6c000460d00200228028c03210f0c010b200241b8086a410041f006109a051a41f80610322205450d024100210f200541003b010620054100360200200541086a200241b8086a41f006109b051a2002410036028c0320022005360288030b200220053602bc082002200f3602b808200220024188036a3602c008200241e8076a200241b8086a200241e00f6a10cd02024020022802e8074101470d00202e202f2902003702002035201c41086a2903003703002034201c41106a2903003703002033201c41186a2903003703002032201c41206a290300370300200e201c41286a290300370300200a201c41306a2903003703002006201c41386a290300370300202e41086a202f41086a2902003702002002201c2903003703b80820022802ec0f2115202d41086a220f200d280200360200202d20022903e00f370200200241f8046a200241b8086a41d000109b051a200241d8056a200241f8046a41d000109b051a200220022802900341016a3602900320022802a006213c20022802a4062114200228029c06210520024188076a41086a2243201b29030037030020024188076a41106a2238200029030037030020024188076a41186a2239200929030037030020024188076a41206a223a200241f8046a41206a29030037030020024188076a41286a223b200241f8046a41286a29030037030020024188076a41306a2240200241f8046a41306a29030037030020024188076a41386a2244200241f8046a41386a290300370300200241f8066a41086a2245200f280200360200200220022903f804370388072002202d2902003703f80620052f01062237410b490d05200241b8086a410041f006109a051a41f80610322237450d03203741003b010620374100360200203741086a200241b8086a41f006109b05210f200241b8086a4108200541086a2246200541b0d6c0004622471b224841e0036a41d000109b051a200f204841b0046a20052f010641796a224841d0006c109b05210f200541063b0106203720483b0106200241e00f6a200241b8086a41d000109b051a0240024020144107490d00201441d0006c4108200f203741b0d6c0004622061b6a220f41a07c6a200f41d07b6a220f4100204841ffff037120061b20146b41d0006c41b0046a109c051a200f201536020c200f41086a2045280200360200200f20022903f806370300200f200229038807370310200f41186a2043290300370300200f41206a2038290300370300200f41286a2039290300370300200f41306a203a290300370300200f41386a203b290300370300200f41c0006a2040290300370300200f41c8006a2044290300370300203720372f010641016a3b01060c010b4108210f200241d8076a41086a200241f8066a41086a280200360200200241b8086a41086a20024188076a41086a29030037030020342038290300370300203320392903003703002032203a290300370300200e203b290300370300200a204029030037030020062044290300370300200220022903f8063703d80720022002290388073703b808024002402047450d00410021380c010b20052f010621382046210f0b200f201441d0006c6a220f41d0006a200f203820146b41d0006c109c051a200f201536020c200f41086a200241d8076a41086a280200360200200f20022903d807370300200f20022903b808370310200f41186a2035290300370300200f41206a2034290300370300200f41286a2033290300370300200f41306a2032290300370300200f41386a200e290300370300200f41c0006a200a290300370300200f41c8006a2006290300370300200520052f010641016a3b01060b200241e8076a200241e00f6a41d000109b051a200241a8066a200241e8076a41d000109b051a2005280200220e450d0620052f01042132034020024188076a200241a8066a41d000109b051a203241ffff0371210602400240024002400240200e2f01062205410b490d00202c410041a207109a051a41a80710322215450d0a20154100360200201541046a200241b8086a41a407109b051a200241b8086a4108200e41086a223a200e41b0d6c00046223b1b220541e0036a41d000109b051a201541086a2239200541b0046a200e2f0106220541796a220f41d0006c109b051a201541f8066a200e4194076a2005417a6a220a410274109b052138200e41063b01062015200f3b01060240200a450d00410021052038210f0340200f280200221420053b010420142015360200200f41046a210f200a200541016a2205470d000b0b200241e00f6a200241b8086a41d000109b051a200241e8076a200241e00f6a41d000109b051a203241ffff037122054107490d03200241b8086a20024188076a41d000109b051a200641796a210541b0d6c0002114201541b0d6c000470d01410821394100210a0c020b4108200e41086a200e41b0d6c0004622141b200641d0006c6a220f41d0006a200f4100200520141b20066b41d0006c109c051a200f20024188076a41d000109b051a200e200e2f010641016a220f3b01062006410274200e41f8066a22146a41086a2014200641016a22054102746a2214200f41ffff0371220f20056b410274109c051a201420373602002006200f4f0d0c203720053b01042037200e3602002005200f4f0d0c200f417f6a2115200e2005417f6a22054102746a4180076a210f0340200f2802002214200541026a3b01042014200e360200200f41046a210f2015200541016a2205470d000c0d0b0b20152f0106210a201521140b20392006417a6a220f41d0006c6a2039200541d0006c6a2232200a20056b41d0006c109c051a2032200241b8086a41d000109b051a201520152f010641016a220a3b01062006410274223220386a416c6a2038200f4102746a2206200a41ffff0371200f6b410274109c051a20062037360200200f20142f010622064b0d01201520326a41e0066a210f0340200f2802002214200541016a22053b010420142015360200200f41046a210f20052006490d000c020b0b200e41f8066a210f200241b8086a20024188076a41d000109b051a02400240203b450d004108213a4100210a0c010b200e2f0106210a0b203a200641d0006c6a221441d0006a2014200a20066b41d0006c109c051a2014200241b8086a41d000109b051a200e200e2f010641016a22143b010620064102742232200f6a41086a200f200641016a220a4102746a220f201441ffff0371200a6b410274109c051a200f20373602002005200e2f010622144f0d00200e20326a41fc066a210503402005280200220f200641016a22063b0104200f200e360200200541046a210520142006470d000b0b200241a8066a200241e8076a41d000109b051a0240200e28020022050d00201521370c080b200e2f010421322005210e201521370c000b0b200241c8056a41086a202f41086a2902003703002002202f2902003703c8052037450d06203810290c060b200f4108102e000b41f8064108102e000b41f8064108102e000b41a8074108102e000b4108200541086a200541b0d6c0004622061b201441d0006c6a220f41d0006a200f4100203720061b20146b41d0006c109c051a200f201536020c200f41086a2045280200360200200f20022903f806370300200f200229038807370310200f41186a2043290300370300200f41206a2038290300370300200f41286a2039290300370300200f41306a203a290300370300200f41386a203b290300370300200f41c0006a2040290300370300200f41c8006a2044290300370300200520052f010641016a3b01060c010b202c410041a207109a051a41a80710322205450d0120054100360200200541046a200241b8086a41a407109b051a2005203c280200220f3602f806203c2005360200203c203c28020441016a360204200f41003b0104200f20053602004108200541086a200541b0d6c000461b20052f0106220f41d0006c6a200241a8066a41d000109b051a200541f8066a200f41016a220f4102746a2037360200200520052f010641016a3b01062037200f3b0104203720053602000b200241e00f6a200241e8036a41d000109b051a20290d08202a417f4c0d0802400240202a0d00410121150c010b202a10322215450d020b024020162025490d00201621060c030b20272028410048720d0c0240024020160d002028103221150c010b2015202a2028103421150b2026210620150d0220284101102e000b41a8074108102e000b202a4101102e000b024002402031450d00410021050c010b202a2114201521052018210f03402005200f290000370000200541186a200f41186a290000370000200541106a200f41106a290000370000200541086a200f41086a290000370000200541206a2105200f41206a210f201441606a22140d000b202b21050b200241b8086a200241e00f6a41d000109b051a20022005360290092002200636028c092002201536028809024002400240411010322205450d0020052004370000200541086a20103700002002429080808080023702e40f200220053602e00f2002200241e00f6a3602e807200241b8046a200241e8076a10850120022802e40f210f20022802e00f210520022802e80f21142009420037030020004200370300201b4200370300200242003703f80420052014200241f8046a100020362009290300370300201c2000290300370300200d201b290300370300200220022903f8043703e00f200241003602f007200242013703e807200241b8086a200241e8076a108503200228028809200228029009200241e8076a10940120022802ec072114200241e00f6a412020022802e807221520022802f007100502402014450d00201510290b0240200f450d00200510290b024020022802fc08450d0020022802f80810290b0240200228028c09450d0020022802880910290b2036203d290300370300201c203e290300370300200d203f290300370300200220022903b8043703e00f410021050240202041014b0d00024020200e020003000b203320362903003703002034201c2903003703002035200d290300370300200220022903e00f3703b808410021050c030b2020210f03402005200f410176221420056a2215200c201541246c6a280200200b4b1b2105200f20146b220f41014b0d000c020b0b41104101102e000b0240200c200541246c6a280200220f200b460d002005200f200b496a21050b203320362903003703002034201c2903003703002035200d290300370300200220022903e00f3703b808202020054f0d0041b0d9c500106d000b024020202021470d00202041016a220f2020490d0a20204101742214200f200f2014491b2221ad42247e2204422088a70d0a2004a7220f4100480d0a0240024020200d00200f1032210c0c010b200c202041246c200f1034210c0b200c450d030b200c200541246c6a220f41246a200f202020056b41246c109c051a200f200b360200200f411c6a2033290300370200200f41146a2034290300370200200f410c6a2035290300370200200f20022903b808370204203320362903003703002034201c2903003703002035200d290300370300200220022903e00f3703b8080240201e201f470d00201e41016a2205201e490d0a201e410174220f20052005200f491b221f41ffffff3f71201f470d0a201f41057422054100480d0a02400240201e0d0020051032211d0c010b201d201e41057420051034211d0b201d450d040b202041016a2120201d201e4105746a220520022903b808370000200541186a2033290300370000200541106a2034290300370000200541086a2035290300370000201e41016a211e0b20132022470d000b202221130c020b200f4104102e000b20054101102e000b024020132022460d002007200841d0006c6a21140340201341c0006a280200220f450d01201341d0006a21050240201341c4006a280200450d00200f10290b2005211320142005470d000b0b02402003450d00200710290b02400240024002400240024002400240024002402002280290030d00200228028803200228028c03410010ce01201a10290240201f450d00201d10290b02402021450d00200c10290b2017450d01201810290c010b2002201d360288072002201d201e4105746a36028c07200241e00f6a20024188076a104502400240200241a0106a2802000d00410821094100210d4100211b0c010b200241b8086a200241e00f6a41e000109b051a41e00010322209450d032009200241b8086a41e000109b051a20022002290388073703e807200241e00f6a200241e8076a10450240200241a0106a2802000d004101210d4101211b0c010b4102210f41e00021054101210d4101211b0340200241b8086a200241e00f6a41e000109b051a0240200d201b470d00200d41016a2214200d490d10200f20142014200f491b221bad42e0007e2204422088a70d102004a722144100480d1002400240200d0d002014103221090c010b200920052014103421090b2009450d060b200920056a200241b8086a41e000109b051a200f41026a210f200541e0006a2105200d41016a210d200241e00f6a200241e8076a104520022802a0100d000b0b200241b8086a41206a2020360200200241d4086a2021360200200241cc086a201e360200200241b8086a41106a201f3602002002201d3602c40820024284808080c0003702bc082002201a3602b8082002200c3602d008200241003602e80f200242013703e00f2020200241e00f6a106602402020450d00200c202041246c6a210a200c210f0340200f28020021150240024020022802e40f221420022802e80f22056b4104490d0020022802e00f21140c010b200541046a22062005490d1020144101742205200620062005491b22054100480d100240024020140d002005103221140c010b20022802e00f20142005103421140b2014450d07200220053602e40f200220143602e00f20022802e80f21050b2002200541046a3602e80f201420056a20153600002002200241e00f6a3602e807200f41046a200241e8076a108501200f41246a220f200a470d000b0b20022802e40f211420022802e80f211520022802e00f2105200241e8076a10a50420022802f007210620022802e807210f200241f8046a41186a220a4200370300200241f8046a41106a220e4200370300200241f8046a41086a22134200370300200242003703f804200f2006200241f8046a1000200241e00f6a41186a200a290300370300200241e00f6a41106a200e290300370300200241e00f6a41086a2013290300370300200220022903f8043703e00f2002412036028c072002200241e00f6a360288072005201520024188076a10f302024020022802ec07450d00200f10290b02402014450d00200510290b200241e8076a200241b8086a10a60420022802f007211520022802e8072114200241003602e80f200242013703e00f201e200241e00f6a10660240201e450d00201e410574210f201d210503402002200241e00f6a36028807200520024188076a108501200541206a2105200f41606a220f0d000b0b20022802e40f21052014201520022802e00f220f20022802e80f100502402005450d00200f10290b024020022802ec07450d00201410290b201a10290240201f450d00201d10290b02402021450d00200c10290b2002280288032105200229028c03210402402017450d00201810290b20050d010b20012802082114024020012802102205450d00200541d0006c210f201441c0006a210503400240200541046a280200450d00200528020010290b200541d0006a2105200f41b07f6a220f0d000b0b2001410c6a280200450d0a201410290c0a0b200220043702ec03200220053602e803410410322205450d032005200b360000200241c0086a4284808080c000370300200241c8086a4100290098a845370300200241d0086a41002900a0a845370300200220053602bc082002410f3a00b80841014100200241b8086a104c2019418094ebdc036e22054101200541014b1b220520194b0d042019200d41036c417d6a220f200f20194b1b20056ead428094ebdc037e201920056ead221080a741146e22062115200d2004422088a76b220f0d050c060b41e0004108102e000b20144108102e000b20054101102e000b41044101102e000b41dcf9c200106d000b2002418094ebdc033602bc082002418094ebdc0320194100200d200f6b22142014200d4b1b41036c417d6a2214201420194b1b20056ead428094ebdc037e201080a741146e22056bad4100200620056b2205200520064b1bad7e428094ebdc0380a722053602b808200241b8086a2005418094ebdc034b4102746a28020021150b200d41e0006c220541e0006e21234100210b02400240024020050d004104211e410021230c010b202341027422141032221e450d010b02402009200920056a460d000240200f0d00200d41e0006c210f4100210b201e2105034020052015360200200b41016a210b200541046a2105200f41a07f6a220f0d000c020b0b200d41e0006c2114200d41057441606a210a201e21052009210f0340200220022802e8033602e40f200220022802ec033602e00f2002200241e8036a3602e80f200241b8086a200241e00f6a200f10cd0220052015200620022802b8084101461b360200200541046a2105200f41e0006a210f201441a07f6a22140d000b200a41057641016a210b0b200241e8076a41086a22054200370300200242003703e8074189aec500411b200241e8076a1003200241b8086a41086a2005290300370300200220022903e8073703b80841002134200241003602e00f200241b8086a4110200241e00f6a100621050240024020022802e00f220f417f460d002005450d00200f4104490d0120052800002134200510290b200241f0026a41abadc5004112105d20022802f002210f20022802f40221140240411710322205450d002005410f6a410029008f9045370000200541086a41002900889045370000200541002900809045370000024020054117412e10342208450d00200820144100200f1b2239360017200241a8066a41186a22054200370300200241a8066a41106a220f4200370300200241a8066a41086a22144200370300200242003703a8062008411b200241a8066a1000200241d8056a41186a2005290300370300200241d8056a41106a200f290300370300200241d8056a41086a2014290300370300200220022903a8063703d8054100210e200241003602b808200241d8056a4120200241b8086a1006213302400240024002400240024020022802b8082235417f470d004100210e0c010b20330d010b4100210f410021050c010b200220353602ac03200220333602a803200241e8026a200241a8036a102c20022802e8020d0a20022802ac0322154140712205417f4c0d0720022802ec02211c02400240201541067622130d004108210e0c010b20051032220e450d030b0240201c450d004100210a0340200241003a00d808200a220641016a210a41002105024002400240034020152005460d01200241b8086a20056a20022802a80322142d00003a00002002201441016a3602a8032002200541016a220f3a00d808200f2105200f4120470d000b200241a8066a41186a2205200241b8086a41186a290300370300200241a8066a41106a220c200241b8086a41106a290300370300200241a8066a41086a2200200241b8086a41086a290300370300200220022903b8083703a8062015200f6b220f4110490d012002201441116a3602a803200f41706a410f4b0d02200f41706a210f0c010b0240200541ff0171450d00200241003a00d8080b4100210f0b200241e8076a41086a200241e00f6a41086a290300370300200220022903e00f3703e8072002200f3602ac032013450d0d200e10290c0d0b201441096a290000210420142900012110200241e8076a41086a22152000290300370300200241e8076a41106a2200200c290300370300200241e8076a41186a220c20052903003703002002201441216a3602a803200220022903a80622113703e00f200220113703e807201441196a29000021112014290011211220024188076a41186a2214200c29030037030020024188076a41106a220c200029030037030020024188076a41086a22002015290300370300200220022903e80737038807024020132006470d0020064101742205200a200a2005491b221341ffffff1f712013470d0e201341067422054100480d0e0240024020060d0020051032210e0c010b200e200641067420051034210e0b200e450d040b200f41606a2115200e20064106746a220520123703102005200437030820052010370300200541186a20113703002005200229038807370320200541286a2000290300370300200541306a200c290300370300200541386a2014290300370300200a201c470d000b2002200f41606a3602ac030b200e450d0a02402035450d00203310290b200e210f200e21050b20081029201c410020051b211c2013410020051b210c200f410820051b210a200e410820051b21360240200b200d200d200b4b1b22350d00420021494200214a0c080b200241e00f6a4105722137200241b8086a4105722138200241e8076a41036a21202034ad214b200241c1086a213320024198026a41186a213020092115420021494200214a4100210b0340200241e8076a41086a220e4200370300200242003703e807418893c5004115200241e8076a1003200241b8086a41086a2213200e290300370300200220022903e8073703b808200241003602e00f2009200b41e0006c6a210f200241b8086a4110200241e00f6a100621050240024002400240024002400240024002400240024020022802e00f2214417f460d0020050d010b41014100200f109203450d010c090b200220143602ec07200220053602e807200241e00f6a200241e8076a103120022802e00f2206450d0120022802e80f210020022802e40f210802402014450d00200510290b20062000200f109203210502402008450d00200610290b20050d080b200241d8026a200f41206a22082903002204200841086a2224290300428094ebdc03420010a105200241c8026a20022903d8022210200241d8026a41086a29030022114280ec94a37c427f10a005200241b8026a20102011201e200b4102746a3502002212420010a00520022903b80222102012200420022903c8027c7e428094ebdc038042ffffffff0f837c2204200241b8026a41086a2903002004201054ad7c2210844200510d07200e4200370300200242003703e80741bfdbc2004112200241e8076a10032013200e290300370300200220022903e8073703b808200241003602e00f200241b8086a4110200241e00f6a100621050240024020022802e00f2206417f460d002005450d00200220063602ec07200220053602e807200241e00f6a200241e8076a103120022802e00f2234450d0320022802e80f211420022802e40f21322006450d01200510290c010b4101213441002114410021320b203420144105746a210041002114203421050240024003400240200020056b41e0004b0d0020052000460d03034020152005460d0320142005200f4120109d0522064100476a21142006450d032000200541206a2205470d000c040b0b2005200f460d0120142005200f4120109d0522064100476a21142006450d01200541206a2206200f460d0120142006200f4120109d0522064100476a21142006450d01200541c0006a2206200f460d0120142006200f4120109d0522064100476a21142006450d01200541e0006a2206200f460d0120142006200f4120109d0522064100476a211420054180016a210520060d000b0b200241023602e00f20022014ad3703e80f200241b8086a200241e00f6a10ec01202041086a22052013280200360000202020022903b808370000203820022900e807370000203841076a200241e8076a41076a2206290000370000200241c6a4b9da043600b908200241023a00b808200241b8086a10ed01200241013602b808200220143602bc08200241e00f6a200241b8086a108d032005200241e00f6a41086a280200360000202020022903e00f370000203720022900e807370000203741076a2006290000370000200241c28289aa043600e10f200241023a00e00f200241e00f6a10ed0120022802b8080d0020022802dc08450d0020022802d80810290b02402032450d00203410290b200e4200370300200242003703e80741f9adc5004110200241e8076a10032013200e290300370300200220022903e8073703b808410110322205450d02200541013a0000200241b8086a41102005410110052005102920242903002212201020082903002242200454201220105420122010511b22051b214c2042200420051b214d02400240201c0d0042002110420021040c010b201c4106742114200a41206a2105420021104200210403400240024020152005460d002005200f4120109d050d010b427f2004200541706a220641086a2903007c201020062903007c22112010542206ad7c22102006201020045420102004511b22061b2104427f201120061b21100b200541c0006a2105201441406a22140d000b0b20024198026a200f204d4200200f290330221120107d22412041201156200f41386a290300224120047d2011201054ad7d220420415620042041511b22051b22102010204d564200200420051b2204204c562004204c511b22051b2210204c200420051b220410c00120024198026a41086a290300214e200229039802214f0240204d201020022903a80222507d22517d2252204c200420302903007d2010205054ad7d22537d204d205154ad7d225084500d00204220117d2210201220417d2042201154ad7d220484500d00200f2802482214450d00200f2802402205201441306c6a2106200241f8016a20522050428094ebdc03420010a10520024188026a20102004428094ebdc03420010a105200241e8016a20022903f8012250200241f8016a41086a29030022544280ec94a37c427f10a00520024188026a41086a29030022114200200229038802224142015620114200522011501b22141b21122041420120141b2141205220022903e8017c21520340200241d8016a2010200529030022112011201056200541086a290300221120045620112004511b22141b2004201120141b2041201210a10520022903d8012242428080808010544100200241d8016a41086a290300501b450d05200241c8016a201020042041201210a10520022903c8012211428080808010544100200241c8016a41086a290300501b450d062011a7450d0720024198016a20502054204242ffffffff0f83428094ebdc037e201142ffffffff0f838042ffffffff0f832211420010a005200241a8016a200541106a2002290398012242201120527e428094ebdc038042ffffffff0f837c221120024198016a41086a2903002011204254ad7c10c001427f204e200241a8016a41086a2903007c204f20022903a8017c2242204f542214ad7c221120142011204e542011204e511b22141b214e427f204220141b214f200541306a22052006470d000b0b200241b8086a41186a2214200f41186a2206290300370300200241b8086a41106a2208200f41106a22342903003703002013200f41086a22242903003703002002200f2903003703b80802400240201c200c460d00200c2100201c210c0c010b200c41016a2205200c490d14200c410174220a20052005200a491b220041ffffff1f712000470d14200041067422054100480d1402400240200c0d002005103221360c010b2036200c4106742005103421360b2036450d072036210a0b20024188016a204f204e428094ebdc03420010a105200241f8006a200229038801220420024188016a41086a29030022104280ec94a37c427f10a005200241e8006a20042010204b420010a005200a200c4106746a220520513703102005204c3703082005204d370300200541186a2053370300200520022903b808370320200541286a2013290300370300200541306a2008290300370300200541386a2014290300370300200241013a00c008200241033a00b808200629000021042034290000211020242900002111200f2900002112200241b8086a41386a204c37030020332012370000203341086a2011370000203341106a2010370000203341186a20043700002002204d3703e80841014100200241b8086a104c200c41016a211c0240024020022903682210204f20022903787c204b7e428094ebdc038042ffffffff0f837c2204200241e8006a41086a2903002004201054ad7c221084500d00200f41d8006a28020022050d010b427f204a204e7c2049204f7c22102049542205ad7c220420052004204a542004204a511b22051b214a427f201020051b21492000210c0c080b200241d8006a2004204f204f200456204e201056204e2010511b22141b22552010204e20141b22562005ad420010a10520054105742114200f2802502105200241d8006a41086a29030021542002290358214c20552141205621420340200241c8006a2005204c20412041204c56204220545620422054511b220f1b220420542042200f1b221010a001200241c8006a41086a290300211220022903482111200241306a41c2d5c000411610a301200420117d201120047d201120045820122010582012201051220f1b22061b2152201020127d2004201154ad7d201220107d2011200454ad7d20061b214d204220107d21512041200454ad2153200241306a41106a2903004200200228023022061b21422002290338420020061b21500240024020112004562012201056200f1b0d0020134200370300200242003703b80841c2d5c0004116200241b8086a1003200e2013290300370300200220022903b8083703e807200242002042204d7d2050205254ad7d2210205020527d2211205056201020425620102042511b220f1b3703c008200242002011200f1b3703b808200241b8086a210f0c010b200241c8056a41086a220f4200370300200242003703c80541c2d5c0004116200241c8056a1003200e200f290300370300200220022903c8053703e8072002427f2042204d7c205020527c2211205054220fad7c2210200f201020425420102042511b220f1b3703c0082002427f2011200f1b3703b808200241b8086a210f0b205120537d2142204120047d2141200541206a2105200241e8076a4110200f41101005201441606a22140d000b427f427f204a20427c204920417c22102049542205ad7c220420052004204a542004204a511b22051b2204204e20567d204f205554ad7d7c427f201020051b2210204f20557d7c22112010542205ad7c22102005201020045420102004511b22051b214a427f201120051b21492000210c0c070b41f7cdc3004133200241a8066a41ecd6c3001054000b41f7cdc3004133200241a8066a41ecd6c3001054000b41014101102e000b109f03000b10a003000b41dcf9c200106d000b20054108102e000b201541e0006a2115200b41016a220b20354f0d080c000b0b20054108102e000b20054108102e000b412e4101102e000b41174101102e000b41f7cdc3004133200241a8066a41ecd6c3001054000b20144104102e000b102f000b024002400240024002400240411710322205450d002005410f6a410029008f9045370000200541086a4100290088904537000020054100290080904537000020054117412e1034220e450d01200e2039360017200241a8066a41186a22054200370300200241a8066a41106a220f4200370300200241a8066a41086a22144200370300200242003703a806200e411b200241a8066a1000200241d8056a41186a2005290300370300200241d8056a41106a200f290300370300200241d8056a41086a2014290300370300200220022903a8063703d805200241003602c008200242013703b808201c200241b8086a1066201c450d02201c41067421060340200a41206a200241b8086a108101200a41086a2903002104200a29030021100240024020022802bc08220f20022802c00822146b4110490d0020022802b80821050c010b201441106a22052014490d0a200f4101742214200520052014491b22154100480d0a02400240200f0d002015103221050c010b20022802b808200f2015103421050b2005450d05200220153602bc08200220053602b80820022802c00821142015210f0b200520146a22152004370008201520103700002002201441106a22143602c008200a41186a2903002104200a41106a290300211002400240200f20146b410f4d0d00200f21150c010b201441106a22152014490d0a200f4101742214201520152014491b22154100480d0a02400240200f0d002015103221050c010b2005200f2015103421050b2005450d06200220153602bc08200220053602b80820022802c00821140b200a41c0006a210a200520146a220f2004370008200f20103700002002201441106a220f3602c008200641406a22060d000c060b0b41174101102e000b412e4101102e000b20022802c008210f20022802bc08211520022802b80821050c020b20154101102e000b20154101102e000b200241d8056a41202005200f100502402015450d00200510290b200e10290240200c450d00203610290b200241b8086a10b401200241206a200241b8086a2049204a10a001200241206a41086a290300211020022903202104200241086a41c2d5c000411610a301204920047d200420497d20042049582010204a582010204a5122051b220f1b2141204a20107d2049200454ad7d2010204a7d2004204954ad7d200f1b2142200241186a29030042002002280208220f1b211120022903104200200f1b21120240024020042049562010204a5620051b0d00200241e00f6a41086a22054200370300200242003703e00f41c2d5c0004116200241e00f6a1003200241e8076a41086a2005290300370300200220022903e00f3703e80720024200201120427d2012204154ad7d2204201220417d2210201256200420115620042011511b22051b3703e80f20024200201020051b3703e00f200241e00f6a21050c010b200241e00f6a41086a22054200370300200242003703e00f41c2d5c0004116200241e00f6a1003200241e8076a41086a2005290300370300200220022903e00f3703e8072002427f201120427c201220417c22102012542205ad7c22042005200420115420042011511b22051b3703e80f2002427f201020051b3703e00f200241e00f6a21050b200241e8076a411020054110100502402023450d00201e10290b0240200d450d00200d41e0006c210f200941d4006a210503400240200541706a280200450d002005416c6a28020010290b02402005280200450d002005417c6a28020010290b200541e0006a2105200f41a07f6a220f0d000b0b0240201b450d00200910290b20022802e80320022802ec0320022802f00310ce0120012802082114024020012802102205450d00200541d0006c210f201441c0006a210503400240200541046a280200450d00200528020010290b200541d0006a2105200f41b07f6a220f0d000b0b2001410c6a280200450d00201410290b200241c0106a24000f0b41f7cdc3004133200241a8066a41ecd6c3001054000b1033000bafe201090a7f017e017f027e0a7f097e017f0e7e2d7f230041c0186b22022400200241f00a6a41bdadc5004123105d20022802f40a210320022802f00a2104200241b80d6a41086a22054200370300200242003703b80d41f9adc5004110200241b80d6a1003200241b00c6a41086a2005290300370300200220022903b80d3703b00c20024100360298112001417f6a2106200241b00c6a411020024198116a10062101024002400240024002400240024002400240024002402002280298112205417f460d002001450d002005450d0220012d0000220541034f0d0220011029200541014b0d06024020050e020100010b200241b80d6a41086a22014200370300200242003703b80d41f9adc5004110200241b80d6a1003200241b00c6a41086a2001290300370300200220022903b80d3703b00c200241b00c6a411010040c010b20062003410020041b6b220120064b2001410649720d050b200241b80d6a41086a22014200370300200242003703b80d41bfdbc2004112200241b80d6a1003200241b00c6a41086a2001290300370300200220022903b80d3703b00c2002410036029811200241b00c6a411020024198116a100621052002280298112203417f460d022005450d02200220033602bc0e200220053602b80e20024198116a200241b80e6a10312002280298112207450d01200241a0116a2802002101200228029c1121082003450d03200510290c030b41f7cdc3004133200241b00e6a41ecd6c3001054000b41f7cdc3004133200241b00e6a41ecd6c3001054000b4101210741002101410021080b410021090240024002400240024002400240200141057422030d004108210a4100210b0c010b2003410575220bad42d0007e220c422088a70d0a200ca722054100480d0a20051032220a450d010b02402001450d00200341606a210d20024198116a41206a2101200a2104200721050340200541086a290000210c200541106a290000210e2005290000210f200241b00c6a41186a2210200541186a290000370300200241b00c6a41106a2211200e370300200241b00c6a41086a2212200c3703002002200f3703b00c200241b80e6a200241b00c6a10870320024198116a41186a201029030037030020024198116a41106a201129030037030020024198116a41086a2012290300370300200120022903b80e370300200141086a200241b80e6a41086a290300370300200141106a200241b80e6a41106a290300370300200141186a200241b80e6a41186a290300370300200141206a200241b80e6a41206a290300370300200141286a200241b80e6a41286a290300370300200220022903b00c37039811200420024198116a41d000109b0541d0006a2104200541206a2105200341606a22030d000b200d41057641016a21090b02402008450d00200710290b200241b80d6a41086a22014200370300200242003703b80d41e0adc5004119200241b80d6a1003200241b00c6a41086a2001290300370300200220022903b80d3703b00c20024198116a200241b00c6a10b4030240200228029c112213450d00200241b00c6a411010040b410021140240024020130d00410421134100211241002115410021110c010b200241a4116a280200211120022802a011211520022802981121120b200241e00a6a41cc83c300410d10d50120022903e80a210c20022802e00a2101200241d00a6a41f2bdc400411710d50120022903d80a210e20022802d00a2105200241b80d6a41086a22164200370300200242003703b80d41f2bdc4004117200241b80d6a1003200241b00c6a41086a22172016290300370300200220022903b80d3703b00c2002200c420020011b220c37039811200241b00c6a411020024198116a41081005200c200e420020051b7d220f500d0420164200370300200242003703b80d41cebdc4004116200241b80d6a100320172016290300370300200220022903b80d3703b00c2002410036029811200241b00c6a411020024198116a100621012002280298112205417f460d022001450d02200220053602bc0e200220013602b80e20024198116a200241b80e6a10312002280298112218450d01200241a0116a2802002110200228029c1121192005450d03200110290c030b20054108102e000b41f7cdc3004133200241b00e6a41ecd6c3001054000b4100211941012118410021100b200241b80a6a41d58fc500411110a301200241b80a6a41106a290300211a20022903c00a211b20022802b80a2101200241a00a6a41c2d5c000411610a301200241800a6a20022903a80a420020022802a00a22051b221c200241a00a6a41106a290300420020051b221d428094ebdc03420010a105200241f0096a20022903800a220c200241800a6a41086a290300220e4280ec94a37c427f10a005200241e0096a201b420020011b201a420020011b2010ad420010a005200241900a6a201c201d428094ebdc03420010a205200f42ffffffff0f8342ffffffff0f200f428080808010541b211d20022903f009201c7c210f200241e0096a41086a290300211e4100210120022903e009211f20022903900a211c4100210441e4edc200210302400240024002400240024003402002200141e4edc2006a2802002205360298112002418094ebdc0336029c11200241d0096a200c200e20024198116a2005418094ebdc034b4102746a350200221a420010a00520022903d009221b201c201a7e428094ebdc038042ffffffff0f837c221a201f5a200241d0096a41086a290300201a201b54ad7c221a201e5a201a201e511b0d062002200141f4edc2006a2802002205360298112002418094ebdc0336029c11200241c0096a200c200e20024198116a2005418094ebdc034b4102746a350200221a420010a00520022903c009221b200f201a7e428094ebdc038042ffffffff0f837c221a201f5a200241c0096a41086a290300201a201b54ad7c221a201e5a201a201e511b0d03200220014184eec2006a2802002205360298112002418094ebdc0336029c11200241b0096a200c200e20024198116a2005418094ebdc034b4102746a350200221a420010a00520022903b009221b201c201a7e428094ebdc038042ffffffff0f837c221a201f5a200241b0096a41086a290300201a201b54ad7c221a201e5a201a201e511b0d04200220014194eec2006a22042802002205360298112002418094ebdc0336029c11200241a0096a200c200e20024198116a2005418094ebdc034b4102746a350200221a420010a00520022903a009221b200f201a7e428094ebdc038042ffffffff0f837c221a201f54200241a0096a41086a290300201a201b54ad7c221a201e54201a201e511b450d01200141a4eec2006a2103200141c0006a210141a4f0c20020036b41304b0d000b200141d4edc2006a2104200141c002460d052002200141e4edc2006a22032802002205360298112002418094ebdc0336029c1120024190096a200c200e20024198116a2005418094ebdc034b4102746a350200221c420010a005200229039009221a200f201c7e428094ebdc038042ffffffff0f837c221c201f5a20024198096a290300201c201a54ad7c221c201e5a201c201e511b0d05200141b002470d01200321040c050b200341206a21040c040b20024188096a210303402002200141f4edc2006a2802002205360298112002418094ebdc0336029c1120024180096a200c200e20024198116a2005418094ebdc034b4102746a350200221c420010a005200229038009221a200f201c7e428094ebdc038042ffffffff0f837c221c201f5a2003290300201c201a54ad7c221c201e5a201c201e511b0d03200141106a220141b002470d000b200141e4edc2006a21040c030b200321040c020b200341106a21040c010b200141e4edc2006a21040b42002120200241e0086a201f201e428094ebdc03420010a105200241d0086a20022903e008221a200241e0086a41086a290300221b4280ec94a37c427f10a005200441e4edc20020041b2201410c6a2d00002105200141046a2802002103200141086a28020021012002418094ebdc0336029c11200220013602981120024198116a2001418094ebdc034b4102746a350200211c2002418094ebdc0336029c112002200336029811200241c0086a201a201b20024198116a2003418094ebdc034b4102746a3502002221420010a005200241f0086a200c200e201c420010a005200241b0086a420020022903f008220e201c200f7e428094ebdc038042ffffffff0f837c220c20022903c008221c202120022903d008201f7c7e428094ebdc038042ffffffff0f837c220f7d221a201a200c56200241f0086a41086a290300200c200e54ad7c220e200241c0086a41086a290300200f201c54ad7c221a7d200c200f54ad7d221c200e56201c200e511b22011b427f200c200f7c220f200f200c542203200e201a7c2003ad7c220c200e54200c200e511b22031b20051b4200201c20011b427f200c20031b20051b201d420010a005200241a0086a20022903b008200241b0086a41086a29030042e08f860f420010a1050240024020100d00420021220c010b201320114102746a210d201820104105746a2123200241a0086a41086a290300212420022903a00821252012ad21264200212042002122201321042018211103402004200d460d01024020042802002201450d00024002400240024002402012450d0020024190086a202520242026420010a105200241f0076a200229039008220c20024190086a41086a290300220e2026420010a00520024180086a200c200e20122001200120124b1bad220f420010a005200220113602b80e202520022903f0077d200f7e202680210c200229038008210e20024180086a41086a290300211a411210322201450d012001410029009bbe44370000200141106a41002f00abbe443b0000200141086a41002900a3be4437000020024292808080a00237029c112002200136029811200241b80e6a20024198116a108a01200228029c11210320022802a01121052002280298112101200241980b6a41186a22104200370300200241980b6a41106a22074200370300200241980b6a41086a22084200370300200242003703980b20012005200241980b6a1000200241b80e6a41186a2010290300370300200241b80e6a41106a2007290300370300200241b80e6a41086a2008290300370300200220022903980b3703b80e2002410036029811200241b80e6a412020024198116a100621052002280298112210417f460d032005450d032002201036029c112002200536029811200241d8076a20024198116a10970120022903d807a70d02200241d8076a41106a290300210f20022903e007211c2010450d04200510290c040b41e88fc500106d000b41124101102e000b41f7cdc3004133200241b00e6a41ecd6c3001054000b4200211c4200210f0b201a200e200c42ffffffff0f837c220c200e54ad7c210e02402003450d00200110290b0240024002400240024002400240200c201c200c201c200c54200f200e54200f200e511b22011b22277d2228200e200f200e20011b22297d200c202754ad7d222a8450450d00420021214200211c4200210c4200210e0c010b20024198116a201110870320024198116a41086a290300220c4200200229039811220e420156200c420052200c501b22011b210c200e420120011b210e20022802b81121070240024020022802c01122010d0042002121200241b8066a200e200c428094ebdc03420010a105200241b8066a41086a290300212b20022903b806212c4200211c0c010b2007200141306c6a210342002121200241c8076a200e200c428094ebdc03420010a105200241a8076a2028202a428094ebdc03420010a105200241b8076a2028202a428094ebdc03420010a205200241c8076a41086a290300222b420020022903c807222c420156202b420052202b501b22011b211a202c420120011b211b200241a8076a41086a290300212d20022903a807212e20022903b807212f4200211c20072101034020024198076a200e2001290300220f200f200e56200141086a290300220f200c56200f200c511b22051b200c200f20051b201b201a10a105200229039807221d42808080801054410020024198076a41086a290300501b450d0320024188076a200e200c201b201a10a105200229038807220f42808080801054410020024188076a41086a290300501b450d04024002400240200fa7450d00200241e0066a202e202d201d42ffffffff0f83428094ebdc037e200f42ffffffff0f838042ffffffff0f83220f420010a005200241f0066a200141106a220120022903e006221d200f202f7e428094ebdc038042ffffffff0f837c220f200241e0066a41086a290300200f201d54ad7c109204200241f0066a41106a290300210f20022903f806211d024020022903f0062230a74101470d00427f201c200f7c2021201d7c221d2021542205ad7c220f2005200f201c54200f201c511b22051b211c427f201d20051b21210c030b20304201510d010c020b41dcf9c200106d000b200241c8066a41c2d5c000411610a301200241c8066a41106a290300213020022903d006213120022802c8062105200241b80d6a41086a22104200370300200242003703b80d41c2d5c0004116200241b80d6a1003200241b00c6a41086a2010290300370300200220022903b80d3703b00c2002427f2030420020051b2230200f7c2031420020051b220f201d7c221d200f542205ad7c220f2005200f203054200f2030511b22051b3703c00e2002427f201d20051b3703b80e200241b00c6a4110200241b80e6a411010050b200141206a22012003470d000b0b200241a8066a200e20022903a811220f200f200e5620024198116a41186a290300220f200c56200f200c511b22011b200c200f20011b202c4201202c420156202b420052202b501b22011b220f202b420020011b221a10a10520022903a806221b428080808010544100200241a8066a41086a290300501b450d0120024198066a200e200c200f201a10a105200229039806220c42808080801054410020024198066a41086a290300501b450d02200ca7450d0320024188066a2028202a428094ebdc03420010a105200241f8056a200229038806220e20024188066a41086a290300220f4280ec94a37c427f10a005200241e8056a200e200f201b42ffffffff0f83428094ebdc037e200c42ffffffff0f838042ffffffff0f83220c420010a00520022903e805220e200c202820022903f8057c7e428094ebdc038042ffffffff0f837c220c200e54ad210e200241e8056a41086a290300210f024020022802bc11450d00200710290b200f200e7c210e0b200241d0056a2011200c20277c220f200e20297c200f200c54ad7c109204200241d0056a41106a290300210c20022903d805210e024020022903d005220fa74101470d00427f201c200c7c2021200e7c220e2021542201ad7c220c2001200c201c54200c201c511b22011b211c427f200e20011b21210c050b200f4201510d030c040b109f03000b10a003000b41dcf9c200106d000b200241b8056a41c2d5c000411610a301200241b8056a41106a290300210f20022903c005211a20022802b8052101200241b80d6a41086a22054200370300200242003703b80d41c2d5c0004116200241b80d6a1003200241b00c6a41086a2005290300370300200220022903b80d3703b00c2002427f200f420020011b220f200c7c201a420020011b220c200e7c220e200c542201ad7c220c2001200c200f54200c200f511b22011b3703a0112002427f200e20011b37039811200241b00c6a411020024198116a411010050b427f2022201c7c202020217c220e2020542201ad7c220c2001200c202254200c2022511b22011b2122427f200e20011b21200b200441046a2104201141206a22112023470d000b0b02402015450d00201310290b200241b0116a202237030020024198116a41106a202037030020024198116a41086a41003a0000200241033a009811410121144101410020024198116a104c200241a0056a41c2d5c000411610a301200241a0056a41106a290300210c20022903a805210e20022802a0052101200241b80d6a41086a22054200370300200242003703b80d41c2d5c0004116200241b80d6a1003200241b00c6a41086a2005290300370300200220022903b80d3703b00c2002427f200c420020011b220c20227c200e420020011b220e20207c220f200e542201ad7c220e2001200e200c54200e200c511b22011b3703a0112002427f200f20011b37039811200241b00c6a411020024198116a4110100502402020202284500d00201f201e84500d00200241b00c6a41086a22014200370300200242003703b00c41c2d5c0004116200241b00c6a1003200241b80e6a41086a2001290300370300200220022903b00c3703b80e20024188056a200241b80e6a10eb01200229039005420020022802880522011b220c201f7d220f200c5620024198056a290300420020011b220e201e7d200c201f54ad7d220c200e56200c200e511b0d00200241f8046a200f200c201f201e10a105200241c8046a200241f8046a41086a290300220c42002020420010a005200241d8046a2022420020022903f804220e420010a005200241e8046a200e42002020420010a005200c42005220224200527120022903d0044200527220022903e00442005272200241e8046a41086a290300220c20022903c80420022903d8047c7c220e200c54720d0020022903e804210c200241b00c6a41086a22014200370300200242003703b00c41c2d5c0004116200241b00c6a1003200241b80e6a41086a22032001290300370300200220022903b00c3703b80e200241b0046a200241b80e6a10eb01200241b0046a41106a290300210f20022903b804211c20022802b004210520014200370300200242003703b00c41c2d5c0004116200241b00c6a100320032001290300370300200220022903b00c3703b80e2002427f200f420020051b220f200e7c200c201c420020051b221c7c221b201c542205ad7c221a2005201a200f54201a200f511b22051b3703a0112002427f201b20051b37039811200241b80e6a411020024198116a4110100520024198116a10b401200241a0046a20024198116a201c427f85200c20051b220c200f427f85200e20051b220f10a001200241a0046a41086a290300211c20022903a004210e20024188046a41c2d5c000411610a301200c200e7d200e200c7d200e200c58201c200f58201c200f5122051b22041b211d200f201c7d200c200e54ad7d201c200f7d200e200c54ad7d20041b212120024188046a41106a290300420020022802880422041b211a200229039004420020041b211b02400240200e200c56201c200f5620051b0d0020034200370300200242003703b80e41c2d5c0004116200241b80e6a100320012003290300370300200220022903b80e3703b00c20024200201a20217d201b201d54ad7d220c201b201d7d220e201b56200c201a56200c201a511b22011b3703c00e20024200200e20011b3703b80e200241b80e6a21010c010b200241b80d6a41086a22054200370300200242003703b80d41c2d5c0004116200241b80d6a100320012005290300370300200220022903b80d3703b00c2002427f201a20217c201b201d7c220e201b542201ad7c220c2001200c201a54200c201a511b22011b3703c00e2002427f200e20011b3703b80e200241b80e6a21010b200241b00c6a41102001411010050b2019450d00201810290b20024180046a41abadc5004112105d2002280280042101200228028404210520164200370300200242003703b80d41abadc5004112200241b80d6a100320172016290300370300200220022903b80d3703b00c2002200541016a410120011b220d36029811200241b00c6a411020024198116a410410050240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240411710322201450d002001410f6a410029008f9045370000200141086a4100290088904537000020014100290080904537000020014117412e10342201450d012001200d417f6a360017200241980b6a41186a22174200370300200241980b6a41106a22184200370300200241980b6a41086a22054200370300200242003703980b2001411b200241980b6a1000200241b80e6a41186a22192017290300370300200241b80e6a41106a22322018290300370300200241b80e6a41086a2005290300370300200220022903980b3703b80e200241b80e6a4120100420011029200241f8036a41bdadc5004123105d200241b80d6a41086a22014200370300200242003703b80d41bdadc5004123200241b80d6a1003200241b00c6a41086a2001290300370300200220022903b80d3703b00c2002200636029811200241b00c6a411020024198116a41041005200d41a105490d0a200241b80d6a41086a22014200370300200242003703b80d41a4aec5004112200241b80d6a1003200241b00c6a41086a2001290300370300200220022903b80d3703b00c2002410036029811200241b00c6a411020024198116a100621332002280298112234417f460d042033450d042002203436029c112002203336029811200241f0036a20024198116a102c20022802f0030d1c200228029c1122104178712201417f4c0d1620022802f403210802400240201041037622160d00410421070c010b200110322207450d030b02402008450d004100211141002104410021030340200241003602b80e02400240024020104104490d0020022010417c6a221036029c112002200228029811220141046a3602981120012800002112200241003602b80e20104104490d00200341016a210520022010417c6a221036029c112002200141086a360298112001280004210120032016470d022011200520052011491b221641ffffffff01712016470d222016410374222341004e0d010c220b2016450d20200710290c200b0240024020030d002023103221070c010b200720042023103421070b2007450d060b200720046a22032012360200200341046a2001360200201141026a2111200441086a21042005210320082005470d000b0b2007450d1c02402034450d00203310290b20082016470d060c050b41174101102e000b412e4101102e000b20014104102e000b20234104102e000b41042107410021080b200841016a22012008490d1720084101742205200120012005491b221641ffffffff01712016470d17201641037422014100480d170240024020080d002001103221070c010b200720084103742001103421070b2007450d010b200d41e07a6a2105200720084103746a220120063602042001200d3602002007200841016a22114103746a2104410021010240201141044f0d00200721030c020b20072110024003402010220328020020054f0d040240200341086a2802002005490d00200141016a21010c050b0240200341106a2802002005490d00200141026a21010c050b200341186a28020020054f0d01200141046a21012004200341206a22106b41184b0d000b200341206a21030c020b200141036a21010c020b20014104102e000b20032004460d000340200328020020054f0d01200141016a21012004200341086a2203470d000b0b02400240024002400240024020112001490d0041002105201120016b2212450d0502402001450d002007200720014103746a2012410374109c051a0b20072802042108200241b80d6a41086a22014200370300200242003703b80d41c1f1c5004113200241b80d6a1003200241b80e6a41086a2001290300370300200220022903b80d3703b80e20024198116a200241b80e6a411010930202402002280298114101470d00024020024198116a41086a280200220d2008200d2008491b2211200228029c1122054f0d00200521110c050b0240200520114f0d000340411a10322201450d04200141186a41002f009ea0453b0000200141106a4100290096a045370000200141086a410029008ea04537000020014100290086a0453700002001411a413410342201450d052001200536001a200241980b6a41186a22034200370300200241980b6a41106a22044200370300200241980b6a41086a22104200370300200242003703980b2001411e200241980b6a1000200241b80b6a41186a2003290300370300200241b80b6a41106a2004290300370300200241b80b6a41086a2010290300370300200220022903980b3703b80b200241b80b6a4120100420011029200541016a2201210520112001470d000b0b200d20084b0d040b200241b80d6a41086a22014200370300200242003703b80d41c1f1c5004113200241b80d6a1003200241b80e6a41086a2001290300370300200220022903b80d3703b80e200241b80e6a411010040c040b41fcd8c500106d000b411a4101102e000b41344101102e000b200241b80d6a41086a22014200370300200242003703b80d41c1f1c5004113200241b80d6a1003200241b80e6a41086a2001290300370300200220022903b80d3703b80e410810322201450d032001200d36000420012011360000200241b80e6a4110200141081005200110290b201221050b200241b80d6a41086a22014200370300200242003703b80d41a4aec5004112200241b80d6a1003200241b00c6a41086a2001290300370300200220022903b80d3703b00c200241003602a0112002420137039811200520024198116a10660240024020050d0020022802a0112101200228029c11210320022802981121050c010b200720054103746a2106410020022802a01122116b2104200228029c112103410021010340201120016a2110200720016a2212280200210802400240200320046a4104490d0020022802981121050c010b201041046a22052010490d162003410174220d20052005200d491b220d4100480d160240024020030d00200d103221050c010b2002280298112003200d103421050b2005450d052002200d36029c112002200536029811200d21030b2002201041046a220d3602a011200520116a20016a2008360000201241046a28020021080240200320046a417c6a41034b0d00200d41046a2223200d490d162003410174220d20232023200d491b220d4100480d160240024020030d00200d103221050c010b20052003200d103421050b2005450d062002200d36029c112002200536029811200d21030b2002201041086a3602a011200520116a20016a41046a2008360000200441786a2104200141086a2101201241086a2006470d000b201120016a21010b200241b00c6a411020052001100502402003450d00200510290b2016450d00200710290b200241e8036a41f8acc5004116105d20022802ec03213520022802e8032136200241e0036a418eadc500411d105d20022802e403213720022802e00321382017420037030020184200370300200241980b6a41086a22054200370300200242003703980b41c4bfc400411a200241980b6a10002019201729030037030020322018290300370300200241b80e6a41086a22032005290300370300200220022903980b3703b80e20024198116a200241b80e6a41201059412810322201450d03200141013602002001200229039811370204200120022f00b00c3b00252001410c6a20024198116a41086a290300370200200141146a20024198116a41106a22042903003702002001411c6a20024198116a41186a2210290300370200200141246a20024198116a41206a22112d00003a0000200141276a200241b00c6a41026a22122d00003a0000200241980b6a41186a22074200370300200241980b6a41106a2208420037030020054200370300200242003703980b41d7bec400411a200241980b6a1000200241b80e6a41186a2007290300370300200241b80e6a41106a200829030037030020032005290300370300200220022903980b3703b80e20024198116a200241b80e6a41201059412810322233450d04203341013602002033200229039811370204203320022f00b00c3b00252033410c6a20024198116a41086a2205290300370200203341146a20042903003702002033411c6a2010290300370200203341246a20112d00003a0000203341276a20122d00003a0000200242003702dc0b200241b0d6c0003602d80b200241003602a00e200242083703980e200241f80d6a411c6a200241d80b6a360200200241f80d6a41186a200241b00e6a360200200241003602880e2002419890c5003602fc0d200220013602f80d2002200241980e6a36028c0e2002200241b00e6a3602840e2002200241b00e6a3602800e20024198116a200241f80d6a109304024020022d00d81122034102460d00200241b80d6a41386a20024198116a41386a290300370300200241b80d6a41306a20024198116a41306a290300370300200241b80d6a41286a20024198116a41286a290300370300200241b80d6a41206a20024198116a41206a290300370300200241b80d6a41186a20024198116a41186a290300370300200241b80d6a41106a20024198116a41106a290300370300200241b80d6a41086a2005290300370300200241980b6a41086a200241e1116a290000370300200241a70b6a200241e8116a29000037000020022002290398113703b80d200220022900d9113703980b0b2005200241b80d6a41086a29030037030020024198116a41106a2205200241b80d6a41106a29030037030020024198116a41186a2204200241b80d6a41186a29030037030020024198116a41206a2210200241b80d6a41206a29030037030020024198116a41286a2211200241b80d6a41286a29030037030020024198116a41306a2212200241b80d6a41306a29030037030020024198116a41386a2207200241b80d6a41386a290300370300200220022903b80d37039811200241b80b6a41086a200241980b6a41086a290300370300200241b80b6a410f6a2208200241980b6a410f6a290000370000200220022903980b3703b80b02400240024020034102470d00200241023a00f80e0c010b200241f80c6a41386a220d2007290300370300200241f80c6a41306a22072012290300370300200241f80c6a41286a22122011290300370300200241f80c6a41206a22112010290300370300200241f80c6a41186a22102004290300370300200241f80c6a41106a22042005290300370300200241f80c6a41086a220520024198116a41086a290300370300200241980c6a41086a2223200241b80b6a41086a290300370300200241980c6a410f6a2216200829000037000020022002290398113703f80c200220022903b80b3703980c200241013602880e200241d4116a200d290300370200200241cc116a2007290300370200200241c4116a2012290300370200200241bc116a2011290300370200200241b4116a2010290300370200200241ac116a2004290300370200200241a4116a2005290300370200200220022903f80c37029c11200241b00c6a20024198116a41c400109b051a200241003602981120024198116a410472200241b00c6a41c400109b051a20024198116a41c8006a20033a0000200241e1116a20022903980c370000200241e9116a2023290300370000200241f0116a2016290000370000200241b80e6a200241f80d6a41146a20024198116a10bb0320022d00f80e4102470d010b20011029410821394100213a4108210741082118410021080c0b0b20024198116a200110940441c80010322239450d052039200241b80e6a41c800109b051a200241f80c6a41186a200241f80d6a41186a290300370300200241f80c6a41106a200241f80d6a41106a290300370300200241f80c6a41086a200241f80d6a41086a290300370300200220022903f80d3703f80c20024198116a200241f80c6a109304024020022d00d81122074102470d00410121084101213a0c090b20024198116a41046a2101200241e1116a210420024198116a41047221342002418c0d6a213b200241d9116a211020022802880d213c4102211141c8002103410021054101213a02400340200241b80d6a41386a221220024198116a41386a290300370300200241b80d6a41306a220820024198116a41306a290300370300200241b80d6a41286a220d20024198116a41286a290300370300200241b80d6a41206a222320024198116a41206a290300370300200241b80d6a41186a221620024198116a41186a290300370300200241b80d6a41106a220620024198116a41106a290300370300200241b80d6a41086a221720024198116a41086a290300370300200241b80b6a41086a2218201041086a290000370300200241b80b6a410f6a22192010410f6a29000037000020022002290398113703b80d200220102900003703b80b2002203c20056a223241016a3602880d200141386a2012290300370200200141306a2008290300370200200141286a200d290300370200200141206a2023290300370200200141186a2016290300370200200141106a2006290300370200200141086a2017290300370200200120022903b80d370200200241b00c6a20024198116a41c400109b051a20022032360298112034200241b00c6a41c400109b051a200420022903b80b370000200441086a20182903003700002004410f6a2019290000370000200220073a00e011200241b80e6a203b20024198116a10bb0320022d00f80e4102460d0120024198116a200241b80e6a41c800109b051a0240200541016a2212203a470d00200241b00c6a20022802f80c20022802fc0c280210110000201241016a22072012490d152011200720072011491b223aad42c8007e220c422088a70d15200ca722074100480d15024002402005417f470d002007103221390c010b203920032007103421390b2039450d090b203920036a20024198116a41c800109b051a201141026a2111200341c8006a210320024198116a200241f80c6a1093042012210520022d00d81122074102460d090c000b0b200541016a2108203921070c090b41084101102e000b200d4101102e000b200d4101102e000b41284104102e000b41284104102e000b41c8004108102e000b20074108102e000b201241016a21080b20392107200241023a00f80e0b20022802f80c220520022802fc0c220128020011010002402001280204450d00200510290b200721180b200241b80e6a203310dd03024020022802d80e2232450d00200241b00c6a41017221340240024002400240034020022802e00e212320022802dc0e213b200241f80c6a41186a223c200241b80e6a41186a290300370300200241f80c6a41106a223d200241b80e6a41106a290300370300200241f80c6a41086a223e200241b80e6a41086a290300370300200220022903b80e3703f80c200241b00c6a200241f80c6a108e04024002400240024020022d00b00c4101460d00200241003602b8110c010b200241b80d6a41186a203441186a290000370300200241b80d6a41106a203441106a290000370300200241b80d6a41086a203441086a290000370300200220342900003703b80d20024198116a200241b80d6a10f90220022802b81122010d010b4200211a4200211b0c010b20024198116a41186a290300211b20022903a811211a20022802bc11450d00200110290b2023ad42c8007e220c422088a70d06200ca72201417f4c0d0602400240024020010d00410821170c010b200110322217450d010b02400240202341057422010d00410021160c010b203220016a2119410021162032210603402006221041206a2106200241d80b6a210120022802dc0b2112024003402001280200221141086a210520112f0106220d4105742101410021030240024003402001450d01201020054120109d052204450d02200141606a2101200341016a2103200541206a21052004417f4a0d000b2003417f6a210d0b2012450d022012417f6a21122011200d4102746a4194036a21010c010b0b2008201120034102746a41e8026a220128020022054d0d052007200541c8006c6a2205290310210c200541186a290300210e200241c8036a41c2d5c000411610a301200241b8036a20022903d003200241c8036a41106a290300427f420010a1052008200128020022054d0d06200241a8036a201a201b20022903b803420020022802c80322031b220f4201200f420156200241b8036a41086a290300420020031b220f420052200f501b22031b200f420020031b10a1052007200541c8006c6a220541186a427f200e200c20022903a8037c220f200c542203ad7c221c2003201c200e54200f200c5a1b22031b3703002005427f200f20031b370310200241b80b6a41186a2205201041186a290000370300200241b80b6a41106a2203201041106a290000370300200241b80b6a41086a2204201041086a290000370300200220102900003703b80b200128020021100240024020162023460d00201621010c010b202341016a22012023490d1220234101742211200120012011491b2211ad42c8007e220c422088a70d12200ca722014100480d120240024020230d002001103221170c010b2017202341c8006c2001103421170b2017450d0820232101201121230b2017200141c8006c6a2201420037030020012010360220200141186a4200370300200141106a4200370300200141086a4200370300200120022903b80b3702242001412c6a2004290300370200200141346a20032903003702002001413c6a2005290300370200201641016a21160b20062019470d000b0b200241980b6a41186a2201203c290300370300200241980b6a41106a2205203d290300370300200241980b6a41086a2203203e290300370300200220022903f80c3703980b20024190036a41c2d5c000411610a30120024180036a20022903980320024190036a41106a290300427f420010a105200241f0026a201a201b200229038003420020022802900322041b220c4201200c42015620024180036a41086a290300420020041b220c420052200c501b22041b200c420020041b10a105200241f80d6a41086a22042003290300370300200241f80d6a41106a22032005290300370300200241f80d6a41186a22052001290300370300200220022903980b3703f80d20022903f002210c0240203b450d00203210290b2017450d0620024198116a41186a2210200529030037030020024198116a41106a2211200329030037030020024198116a41086a22032004290300370300200220022903f80d37039811024020022802a00e2205200228029c0e470d00200241b80e6a2033109404200228029c0e220120022802a00e22046b417f20022802b80e221241016a220d200d2012491b22124f0d00200420126a22122004490d0f20014101742204201220122004491b2204ad42d0007e220e422088a70d0f200ea722124100480d0f0240024020010d002012103221010c010b20022802980e200141d0006c2012103421010b2001450d062002200436029c0e200220013602980e0b20022802980e200541d0006c6a22012017360220200120022903981137022c200141286a2016360200200141246a202336020020014200370310200142003703082001200c370300200141186a4200370300200141346a20032903003702002001413c6a2011290300370200200141c4006a20102903003702002002200541016a3602a00e200241b80e6a203310dd0320022802d80e22320d010c060b0b20014108102e000b4190dbc300200520081036000b4180dbc300200520081036000b20014108102e000b20124108102e000b203310290240024020082037410420381b22014101200141014b1b4f0d000240203a450d00203910290b024020022802a00e2201450d00200141d0006c210520022802980e41206a210103400240200141046a280200450d00200128020010290b200141d0006a2101200541b07f6a22050d000b0b0240200228029c0e0d00410021340c020b20022802980e1029410021340c010b20082035410020361b220120082001491b223d41ffffff3f71203d470d01203d4105742201417f4c0d01024002400240024020010d00410121340c010b200110322234450d010b203dad422c7e220c422088a70d03200ca72201417f4c0d0302400240024020010d00410421360c010b200110322236450d010b4100213e0240203d0d004100213f410021400c030b2007200841c8006c22336a2106200241fc0b6a41026a2132203d21174100214041002119034002402008450d002033210103400240201841c0006a2d00000d00200241e0026a427f427f201841106a290300220c4201200c420156201841186a290300220c420052200c501b22051b200c420020051b10a1052018200241e0026a41086a290300370308201820022903e0023703000b201841c8006a2118200141b87f6a22010d000b0b20022802980e220420022802a00e220d41d0006c6a211602400240024002400240200d450d00200421100340024020102802282201450d00200141c8006c2103201028022041206a210103402008200128020022054d0d0402402007200541c8006c6a22052d00400d002005290310220e200541186a290300220f84500d00200241d0026a2010290300220c4200428080808010420010a005200241a0026a42004200200c420010a005200241c0026a427f20022903d002201041086a290300220c42ffffffff0f83200c5220022903a80242005272200241d0026a41086a290300221c200c42208620022903a0027c7c220c201c547222111b427f200c20111b200e200f10a105200241b0026a201041146a350200201041186a290300220c42208684200c42208820022903c002200241c0026a41086a29030010a0052005427f2005290300220c20022903b0027c220e200e200c542211200541086a2212290300220c200241b0026a41086a2903007c2011ad7c220e200c54200e200c511b22111b3703002012427f200e20111b3703000b200141c8006a2101200341b87f6a22030d000b0b201041d0006a22102016470d000b0b201941016a21192007200841c8006c6a21102033210320072101024003402001210502400240201020016b41d8014d0d00200541c0006a2d00000d01200541c8006a21010c070b0340024020030d002017213f0c0c0b200341b87f6a2103200541c0006a2111200541c8006a2201210520112d00000d000b200141b87f6a21050c060b20054188016a2d0000450d01200541d0016a2d0000450d03200341e07d6a2103200541a0026a210120054198026a2d00000d000b410321030c030b20054190016a2101410121030c020b4180dbc300200520081036000b200541d8016a2101410221030b2005200341c8006c6a21050b024020012010460d00200541086a290300210c2005290300210e0340200141c8006a21030240200141c0006a2d00000d00200141086a290300220f200c2001290300221c200e54200f200c54200f200c511b22101b210c201c200e20101b210e2001200520101b21050b2003210120062003470d000b0b200541013a00400240200d450d002005417c6a2112200541206a210d0340200441d0006a2123024020042802282203450d0020042802202101200341c8006c210303400240024020122001460d00200141246a200d4120109d050d010b200441186a2210290300210c200541086a2211290300210e20012005290300220f2004290310221c7d3703002001200e200c7d200f201c54ad7d3703082005290300210c201020112903003703002004200c3703100b200141c8006a2101200341b87f6a22030d000b0b2023210420232016470d000b0b2032200541226a2d00003a0000200220052f00203b01fc0b200220052900333703e80b2002200541386a2900003700ed0b2005412f6a28000021032005412b6a2800002104200541276a2800002110200541236a28000021050240024020402017460d002017213f204021170c010b201741016a22012017490d0d20174101742211200120012011491b223f41ffffff3f71203f470d0d203f41057422014100480d0d0240024020170d002001103221340c010b203420174105742001103421340b20340d0020014101102e000b203420174105746a2201200336000f2001200436000b2001201036000720012005360003200120022f01fc0b3b0000200141026a20322d00003a0000200120022903e80b370013200141186a20022900ed0b370000201741016a214020072118203f21172019203d4f0d030c000b0b20014104102e000b20014101102e000b024020022802a00e2201450d0020022802980e2233200141d0006c6a2141410020346b214220342040410574223c6a210d200241b80e6a41186a2137200241b80e6a41106a2138200241b80e6a41086a21354100213e03402037203341c4006a29000037030020382033413c6a2900003703002035203341346a2900003703002002203329002c3703b80e024020332802282201450d002033412c6a211920332802202216200141c8006c6a213b201620426a41246a210641002118410821324100211702400240024003402016221141046a2112201141246a2105201141646a2107201141446a2108201141c8006a2116203c210420062110203421010240024003400240024002400240200d20016b41e0004d0d0020052001460d02200120054120109d050d01200121030c050b03402004450d06024002402010450d0041002103200120054120109d050d010b200121030b200141206a2101200441606a2104201041606a21102003450d000c050b0b20122001460d00200141206a220320054120109d05450d0320072001460d00200141c0006a220320054120109d05450d0320082001470d010b200521030c020b200141e0006a2103200441807f6a2104201041807f6a211020014180016a22232101200320054120109d050d000b202341606a21030b20192003460d00200320194120109d05450d00024002402033290310221c2011290300220e85203341186a290300220f201141086a290300220c858450450d004200210c428080808010210e0c010b20024190026a200e4200428080808010420010a00520024180026a42004200200e420010a0050240200c42ffffffff0f83200c522002290388024200527220024190026a41086a290300221a200c4220862002290380027c7c221b201a54724101470d000240201c422088200f42208684221c200f422088220f84500d00200241e0016a200e200c201c200f10a105200241e0016a41086a290300210c20022903e001210e0c020b41a0dbc300106d000b200241f0016a200229039002201b201c4201201c420156200f420052200f501b22011b200f420020011b10a105200241f0016a41086a290300210c20022903f001210e0b2011200e370310201141186a200c370300200220112f00243b01900c2002201141266a2d00003a00920c2002201141376a2900003703800c20022011413c6a2900003700850c201141336a28000021052011412f6a28000021032011412b6a2800002104201141276a28000021100240024020172018460d00201721010c010b201841016a22012018490d1120184101742211200120012011491b2211ad42307e220f422088a70d11200fa722014100480d110240024020180d002001103221320c010b2032201841306c2001103421320b2032450d0320182101201121180b20022d00920c211120022f01900c21122032200141306c6a2201200536000f2001200336000b2001200436000720012010360003200120123b0100200141026a20113a00002001200e370320200141286a200c370300200120022903800c370013200141186a20022900850c370000201741016a21170b200641c8006a21062016203b470d000b02402017450d0002400240201741306c22050d004200210c4200210e0c010b203241206a21014200210c4200210e0340200141086a290300200e7c2001290300220e200c7c220c200e54ad7c210e200141306a2101200541506a22050d000b0b200241d0016a4200428080808010200c7d220f200f428080808010564200200e200c42808080801056ad7c7d220c420052200c501b22011b221a4200200c20011b220c2017ad221b420010a10520022903d001210f0240201a201b544100200c501b0d00200241d0016a41086a290300211c2017417f6a2110203241206a21014100210503402001427f2001290300220c200f7c220e200e200c542203200141086a2204290300220c201c7c2003ad7c220e200c54200e200c511b22031b3703002004427f200e20031b37030020102005460d01200141306a21012017200541016a22054b0d000b4190dbc300200520171036000b200241c0016a200f200c201b200c10a0050240201a20022903c0017da72204450d004100210103402017200120177022054d0d052032200541306c6a2205427f2005290320220c42017c220e200e200c542203200541286a2205290300220f2003ad7c221c200f54200e200c5a1b22031b3703202005427f201c20031b370300200141016a22012004490d000b0b20024198116a41186a2205203729030037030020024198116a41106a2203203829030037030020024198116a41086a22042035290300370300200220022903b80e370398110240203e203d470d00203d41016a2201203d490d10203d4101742210200120012010491b2201ad422c7e220c422088a70d10200ca722104100480d1002400240203d0d002010103221360c010b2036203d412c6c2010103421360b2036450d03203d213e2001213d0b2036203e412c6c6a22012002290398113702002004290300210c2003290300210e2005290300210f200120173602282001201836022420012032360220200141186a200f370200200141106a200e370200200141086a200c370200203e41016a213e0c040b2018450d03203210290c030b20014108102e000b20104104102e000b4190dbc300200520171036000b203341d0006a22332041470d000b0b2040ad210c0240203a450d00203910290b200c422086210c203fad210e024020022802a00e2201450d00200141d0006c210520022802980e41206a210103400240200141046a280200450d00200128020010290b200141d0006a2101200541b07f6a22050d000b0b200c200e842130200228029c0e450d0020022802980e10290b20022802e00b211120022802d80b2105024020022802dc0b2201450d00034020052802940321052001417f6a22010d000b0b02402011450d00410021034100210103402011417f6a211102400240200120052f01064f0d00200141016a21010c010b02400240200528020022010d002003ad210c41002104410021010c010b20053301044220862003ad84210c410121040b20051029200ca7210302400240200c422088a7221020012f01064f0d00200121050c010b034002400240200128020022050d002003ad210c410021050c010b200441016a210420013301044220862003ad84210c0b20011029200ca7210320052101200c422088a7221020052f01064f0d000b0b201041027420056a4198036a280200210502402004417f6a2201450d00034020052802940321052001417f6a22010d000b0b410021010b20110d000b0b0240200541b0d6c000460d0020052802002101200510292001450d0020012802002105200110292005450d00024020052802002201450d000340200510292001210520012802002203210120030d000b0b200510290b024020340d00200241086a41d58fc500411110a3010c030b203e412c6c2201412c6e214341002117024002400240024020010d0041082144410021430c010b204341ffffff1f712043470d0a204341067422054100480d0a200510322244450d010b024002402036203620016a223b460d00200241b80e6a410172211141002117204421232036210d0340200241980b6a41186a2218200d41186a290200370300200241980b6a41106a2219200d41106a290200370300200241980b6a41086a2232200d41086a2902003703002002200d2902003703980b200241b80e6a200d108e04024002400240024020022d00b80e4101460d00200241003602b8110c010b200241b00c6a41186a201141186a290000370300200241b00c6a41106a201141106a290000370300200241b00c6a41086a201141086a290000370300200220112900003703b00c20024198116a200241b00c6a10f90220022802b81122010d010b4200211b4200211d0c010b20024198116a41186a290300211d20022903a811211b20022802bc11450d00200110290b200d28022021044100211002400240200d28022822010d0041082106410021330c010b200141ffffff1f712001470d0d200141067422054100480d0d200510322206450d03200121330b200d412c6a2116024020042004200141306c22126a460d00410021102006210103402004220541286a290300210e200541206a290300210c200241b80e6a200d108e04024002400240024020022d00b80e4101460d00200241003602b8110c010b200241b00c6a41186a201141186a290000370300200241b00c6a41106a201141106a290000370300200241b00c6a41086a201141086a290000370300200220112900003703b00c20024198116a200241b00c6a10f90220022802b81122030d010b4200211c4200211a0c010b20024198116a41186a290300211a20022903a811211c20022802bc11450d00200310290b200541306a2104200241b80d6a41086a22034200370300200242003703b80d41c2d5c0004116200241b80d6a1003200241b80e6a41086a22072003290300370300200220022903b80d3703b80e200241a8016a200241b80e6a10eb0120024180016a20022903b001200241a8016a41106a290300427f420010a105200241e0006a201c201a200229038001420020022802a80122081b220f4201200f42015620024180016a41086a290300420020081b220f420052200f501b22081b200f420020081b10a10520034200370300200242003703b80d41c2d5c0004116200241b80d6a100320072003290300370300200220022903b80d3703b80e20024190016a200241b80e6a10eb01200241f0006a20022903980120024190016a41106a290300427f420010a105200241306a200e42002002290360220f420010a005200241d0006a200c4200200f420010a005200241206a42004200200c420010a005200241c0006a2002290370420020022802900122031b220f4201200f420156200241f0006a41086a290300420020031b220f420052200f501b22031b200f420020031b427f2002350254200241d0006a41086a290300221c200229033020022903207c7c220f422086842002290338200229032884420052200f201c547222031b42ffffffff0f200f42208820031b10a0052001200e3703082001200c370300200141106a2005290300370300200141186a200541086a290300370300200141206a200541106a290300370300200141286a200541186a290300370300200141386a200241c0006a41086a290300370300200141306a2002290340370300200141c0006a2101201041016a2110201241506a22120d000b0b2023201b3703002023201d37030820232006360230202341386a2010360200202341346a2033360200202320022903980b370310202341186a2032290300370300202341206a2019290300370300202341286a2018290300370300201741016a2117202341c0006a21232016210d2016203b470d000b0b200242003702dc0b200241b0d6c0003602d80b02400240024020342030422088a722454105746a223c2034460d0020024198116a4102722146200241980b6a41136a2137200241b80b6a41136a2147200241b80e6a410172210d203421070340200241b80e6a2007108e04024002400240024020022d00b80e4101460d00200241003602b8110c010b200241b00c6a41186a200d41186a290000370300200241b00c6a41106a200d41106a290000370300200241b00c6a41086a200d41086a2900003703002002200d2900003703b00c20024198116a200241b00c6a10f90220022802b81122010d010b4200210c4200210e0c010b20024198116a41186a290300210e20022903a811210c20022802bc11450d00200110290b200241b00c6a41186a2223200741186a290000370300200241b00c6a41106a2216200741106a290000370300200241b00c6a41086a2206200741086a290000370300200220072900003703b00c0240024002400240024002400240024020022802d80b221041b0d6c000460d0020022802dc0b21110c010b200241b80e6a410041e002109a051a20024198116a4100419004109a051a41f80610322210450d0141002111201041003b010620104100360200201041086a200241b80e6a41e002109b051a201041e8026a20024198116a419004109b051a200241003602dc0b200220103602d80b0b200741206a210702400340201041086a2105201041066a210820102f01062212410574210141002103024003402001450d01200241b00c6a20054120109d052204450d03200141606a2101200341016a2103200541206a21052004417f4a0d000b2003417f6a21120b02402011450d002011417f6a2111201020124102746a41f8066a28020021100c010b0b200241f80d6a41186a22012023290300370300200241f80d6a41106a2016290300220f370300200241f80d6a41086a2006290300221c370300200220022903b00c221a3703f80d200220022802e00b41016a3602e00b200241b80d6a41106a2241200f370300200241b80d6a41086a223f201c370300200241b80d6a41186a223920012903003703002002201a3703b80d20082f01002205410b490d04200241b80e6a410041e002109a051a20024198116a4100419004109a051a41f80610322201450d02200141003b010620014100360200200141086a200241b80e6a41e002109b052103200141e8026a20024198116a419004109b052104200241b80b6a41086a2248201041d0016a290000370300200241b80b6a41106a2249201041d8016a290000370300200241b80b6a41186a224a201041e0016a29000037030020024198116a41086a221820104190056a29030037030020024198116a41106a221920104198056a29030037030020024198116a41186a2232201041a0056a29030037030020024198116a41206a2233201041a8056a29030037030020024198116a41286a223b201041b0056a290300370300200220102900c8013703b80b2002201029038805370398112003201041e8016a20102f010641796a2205410574109b0521032004201041b8056a200541306c109b052104201041063b0106200120053b0106200220022f01b80b3b01900c200220022d00ba0b3a00920c200220472900003703800c2002204741056a224b2900003700850c20022800bb0b213a20022800bf0b214c20022800c30b214d20022800c70b214e200241b80e6a41286a224f203b290300370300200241b80e6a41206a22502033290300370300200241b80e6a41186a22512032290300370300200241b80e6a41106a22522019290300370300200241b80e6a41086a2253201829030037030020022002290398113703b80e0240024020124107490d00201241057420036a41c07e6a2003201241796a22114105746a2203200541ffff037120116b410574109c051a200341186a2039290300370000200341106a2041290300370000200341086a203f290300370000200320022903b80d370000201241306c20046a220541e07d6a200541b07d6a2205200141066a22082f010020116b41306c109c051a200541186a200e3703002005200c3703102005200e3703082005200c370300200541286a4100360200200542083703200c010b201041086a20124105746a220541206a200520082f010020126b410574109c051a200541186a2039290300370000200541106a2041290300370000200541086a203f290300370000200520022903b80d370000201041e8026a201241306c6a220541306a200520082f010020126b41306c109c051a200541186a200e3703002005200c3703102005200e3703082005200c370300200541286a4100360200200542083703200b200820082f010041016a3b0100200241980c6a41026a220520022d00920c3a0000200620532903003703002016205229030037030020232051290300370300200241b00c6a41206a22422050290300370300200241b00c6a41286a2240204f290300370300200220022f01900c3b01980c200220022903800c3703980b200220022900850c37009d0b200220022903b80e3703b00c200241f80c6a41286a22542040290300370300200241f80c6a41206a22552042290300370300200241f80c6a41186a22562023290300370300200241f80c6a41106a22572016290300370300200241f80c6a41086a22582006290300370300200241fc0b6a41026a225920052d00003a0000200220022903b00c3703f80c200220022903980b3703e80b2002200229009d0b3700ed0b200220022f01980c3b01fc0b0240201028020022110d00200241d80b6a2105200121030c060b20102f010421384100215a2001215b0340200241b00e6a41026a225c20592d00003a0000200220022f01fc0b3b01b00e200220022903e80b3703980c200220022900ed0b37009d0c2040205429030037030020422055290300370300202320562903003703002016205729030037030020062058290300370300200220022903f80c3703b00c203841ffff0371211202400240024020112f01062201410b490d002046410041a207109a051a41a80710322204450d0720044100360200200441046a20024198116a41a407109b051a204a201141e0016a2900003703002049201141d8016a2900003703002048201141d0016a290000370300200220112900c8013703b80b203b201141b0056a2903003703002033201141a8056a2903003703002032201141a0056a290300370300201920114198056a290300370300201820114190056a290300370300200220112903880537039811200441086a201141e8016a20112f0106220541796a2201410574109b05215d200441e8026a201141b8056a200141306c109b05215e200441f8066a20114194076a2005417a6a2208410274109b052135201141063b0106200420013b010602402008450d00410021012035210503402005280200220320013b010420032004360200200541046a21052008200141016a2201470d000b0b204f203b2903003703002050203329030037030020512032290300370300205220192903003703002053201829030037030020022002290398113703b80e200220022f01b80b3b01900c200220022d00ba0b3a00920c20022900bb0b210c20022900c30b210e2002204b2900003700850c200220472900003703800c203720022903800c370000203741056a220820022900850c370000200220022d00920c3a009a0b200220022f01900c3b01980b2002200e3700a30b2002200c37009b0b203b204f29030037030020332050290300370300203220512903003703002019205229030037030020182053290300370300200220022903b80e37039811203841ffff037122054107490d01205d2012417a6a22034105746a205d201241796a22014105746a220520042f010620016b410574109c051a200541186a200229009d0c3700002005204e36000f2005204d36000b2005204c3600072005203a360003200541026a205c2d00003a0000200520022f01b00e3b0000200520022903980c370013201241306c205e6a220541e07d6a200541b07d6a220520042f0106223820016b41306c109c051a200541286a2040290300370300200541206a2042290300370300200541186a2023290300370300200541106a2016290300370300200541086a2006290300370300200520022903b00c3703002004203841016a22053b01062012410274223820356a416c6a203520034102746a2212200541ffff037120036b410274109c051a2012205b360200200320042f010622124b0d02200420386a41e0066a2105034020052802002203200141016a22013b010420032004360200200541046a210520012012490d000c030b0b201141086a2205201241016a22034105746a200520124105746a2205200120126b2204410574109c051a2005204e36000f2005204d36000b2005204c3600072005203a360003200541026a205c2d00003a0000200520022f01b00e3b0000200520022903980c370013200541186a200229009d0c3700002011201241306c6a22054198036a200541e8026a2208200441306c109c051a20054190036a204029030037030020054188036a204229030037030020054180036a2023290300370300200541f8026a2016290300370300200541f0026a2006290300370300200820022903b00c3703002011200141016a22013b01062012410274201141f8066a22056a41086a200520034102746a2205200141ffff037120036b410274109c051a2005205b3602000240201220112f010622014f0d00205b20033b0104205b2011360200200320014f0d002001417f6a210420112003417f6a22014102746a4180076a2105034020052802002203200141026a3b010420032011360200200541046a21052004200141016a2201470d000b0b41001a200241d80b6a1a20101a0c090b201141086a2201201241016a22034105746a200120124105746a220120112f0106223820126b2235410574109c051a2001204e36000f2001204d36000b2001204c3600072001203a360003200141026a205c2d00003a0000200120022f01b00e3b0000200120022903980c370013200141186a200229009d0c370000201141e8026a201241306c6a220141306a2001203541306c109c051a200141286a2040290300370300200141206a2042290300370300200141186a2023290300370300200141106a2016290300370300200141086a2006290300370300200120022903b00c3703002011203841016a22013b010620124102742235201141f8066a22386a41086a203820034102746a2238200141ffff037120036b410274109c051a2038205b360200200520112f010622034f0d00201120356a41fc066a2101034020012802002205201241016a22123b010420052011360200200141046a210120032012470d000b0b205a41016a2112200241ac0e6a41026a220120022d009a0b3a0000203f20182903003703002041201929030037030020392032290300370300200241b80d6a41206a22052033290300370300200241b80d6a41286a2203203b290300370300200220022f01980b3b01ac0e20022002290398113703b80d200220372900003703980e2002200829000037009d0e200228009b0b213a200228009f0b214c20022800a30b214d20022800a70b214e205420032903003703002055200529030037030020562039290300370300205720412903003703002058203f290300370300205920012d00003a0000200220022903b80d3703f80c200220022903980e3703e80b2002200229009d0e3700ed0b200220022f01ac0e3b01fc0b0240201128020022010d0020111a200241d80b6a22051a200421030c070b20112f01042138200241d80b6a1a20111a200121112004215b2012215a0c000b0b2010200341306c6a22014180036a200e370300200141f8026a200c370300200141f0026a200e370300200141e8026a200c37030020014190036a410036020020014188036a220328020021052001418c036a2802002101200342083703002005450d052001450d05200510290c050b41f8064108102e000b41f8064108102e000b41a8074108102e000b201020124105746a220141286a200141086a2203200520126b410574109c051a200141206a2039290300370000200141186a2041290300370000200141106a203f290300370000200320022903b80d3700002010201241306c6a22014198036a200141e8026a220520102f010620126b41306c109c051a20014190036a410036020020014188036a420837030020014180036a200e370300200141f8026a200c370300200141f0026a200e3703002005200c370300201020102f010641016a3b01060c010b2046410041a207109a051a41a80710322201450d0320014100360200200141046a20024198116a41a407109b051a2001200528020022043602f806200520013602002005200528020441016a360204200441003b010420042001360200200120012f010622044105746a220541086a20022f01fc0b3b00002005410a6a20592d00003a0000200541176a204e360000200541136a204d3600002005410f6a204c3600002005410b6a203a3600002005411b6a20022903e80b370000200541206a20022900ed0b3700002001200441306c6a220541e8026a20022903f80c370300200541f0026a2058290300370300200541f8026a205729030037030020054180036a205629030037030020054188036a205529030037030020054190036a2054290300370300200141f8066a200441016a22054102746a2003360200200120053b010620032001360200200320053b010420101a0b2007203c470d000b0b20174106742201450d04204420016a21182044210603402006450d05024020062802382201450d002006280230222320014106746a2116200641106a210d03402023220841106a2110200841c0006a2123200241d80b6a210120022802dc0b2112024003402001280200221141086a210520112f010622074105742101410021030240024003402001450d01201020054120109d052204450d02200141606a2101200341016a2103200541206a21052004417f4a0d000b2003417f6a21070b2012450d022012417f6a2112201120074102746a41f8066a21010c010b0b2011200341306c6a220141e8026a2205427f2005290300220c20082903307c220e200e200c542205200141f0026a2203290300220c200841386a22042903007c2005ad7c220e200c54200e200c511b22051b3703002003427f200e20051b37030020024198116a41086a2210200d41086a290000370300200d290000210c20024198116a41106a2211200d41106a29000037030020024198116a41186a2212200d41186a2900003703002002200c370398112004290300210c2008290330210e20014188036a2104024020014190036a220328020022052001418c036a280200470d00200541016a22012005490d1120054101742207200120012007491b2207ad42307e220f422088a70d11200fa722084100480d110240024020050d002008103221010c010b2004280200200541306c2008103421010b2001450d0620042001360200200441046a2007360200200328020021050b2004280200200541306c6a2201200c3703082001200e3703002001200229039811370310200141186a2010290300370300200141206a2011290300370300200141286a20122903003703002003200328020041016a3602000b20232016470d000b0b200641c0006a22062018470d000c050b0b41a8074108102e000b20084108102e000b20054108102e000b20054108102e000b200241b80d6a41086a22014200370300200242003703b80d41cebdc4004116200241b80d6a1003200241b00c6a41086a2001290300370300200220022903b80d3703b00c2002410036029811200241b00c6a411020024198116a10062101024002402002280298112203417f460d002001450d00200220033602bc0e200220013602b80e20024198116a200241b80e6a103102402002280298112208450d00200241a0116a2802002105200228029c11210d2003450d02200110290c020b41f7cdc3004133200241b00e6a41ecd6c3001054000b4100210d41012108410021050b024002402008450d002005450d0020054105742103200821050340410f10322201450d02200141002900adbe44370000200141076a41002900b4be443700002002428f808080f00137029c112002200136029811200520024198116a108101200228029c11210420022802a01121102002280298112101200241980b6a41186a22114200370300200241980b6a41106a22124200370300200241980b6a41086a22074200370300200242003703980b20012010200241980b6a1000200241b80e6a41186a2011290300370300200241b80e6a41106a2012290300370300200241b80e6a41086a2007290300370300200220022903980b3703b80e200241b80e6a4120100402402004450d00200110290b200541206a2105200341606a22030d000b0b0240200d450d00200810290b20022802d80b2104024020022802dc0b2201450d0020012105034020042802f80621042005417f6a22050d000b03402001417f6a22010d000b0b024020022802e00b22070d00427f210f427f210c0c030b0240024020042f0106450d00200441e8026a2110200441086a2111410121120c010b02400240200428020022010d004100210341002105410021010c010b20042f01042103410121050b0240200320012f0106490d000340200541016a210520012f01042203200128020022012f01064f0d000b0b2001200341306c6a41e8026a2110200120034105746a41086a2111200341027420016a41fc066a2802002104410021122005417f6a2201450d00034020042802f80621042001417f6a22010d000b0b20024198116a41106a210d427f210f427f210c0340201041086a2201290300210e2010290300211c200241b00c6a41186a201141186a290000370300200241b00c6a41106a201141106a290000370300200241b00c6a41086a201141086a290000370300200220112900003703b00c20102802282211ad42307e221a422088a70d02201aa72205417f4c0d02201041186a290300211a2001290300211b2010290310211d20102903002121201028022021010240024002400240024020050d00410821080c010b200510322208450d010b0240024020110d00410021030c010b2001201141306c6a211041002103200821050340200520012903003703002005200141086a290300370308200541106a200141106a290300370300200541186a200141186a290300370300200541206a200141206a290300370300200541286a200141286a290300370300200541306a2105200341016a2103200141306a22012010470d000b0b20024198116a41186a201a3703002002201d3703a8112002202137039811200220033602c011200220113602bc11200220083602b8112002201b3703a011410f10322201450d01200141002900adbe44370000200141076a41002900b4be443700002002428f808080f0013702bc0e200220013602b80e200241b00c6a200241b80e6a10810120022802bc0e211020022802c00e210120022802b80e2103200241980b6a41186a22054200370300200241980b6a41106a22114200370300200241980b6a41086a22084200370300200242003703980b20032001200241980b6a1000200241b80e6a41186a2005290300370300200241b80e6a41106a2011290300370300200241b80e6a41086a2008290300370300200220022903980b3703b80e200241003602c00d200242013703b80d200220024198116a3602f80c200241f80c6a200241b80d6a109b012002200d3602f80c200241f80c6a200241b80d6a109b0120022802b811210120022802c0112205200241b80d6a106602402005450d00200541306c21050340200141106a200241b80d6a108101200220013602f80c200141306a2101200241f80c6a200241b80d6a109b01200541506a22050d000b0b20022802bc0d2101200241b80e6a412020022802b80d220520022802c00d100502402001450d00200510290b201c200f542101200e200c512105200e200c54211102402010450d00200310290b2001201120051b21012007417f6a2107024020022802bc11450d0020022802b81110290b200e200c20011b210c201c200f20011b210f2007450d060240201220042f01064f0d002004201241306c6a41e8026a2110200420124105746a41086a2111201241016a21120c040b02400240200428020022010d004100210341002105410021010c010b20042f01042103410121050b200320012f0106490d020340200541016a210520012f01042203200128020022012f01064f0d000c030b0b20054108102e000b410f4101102e000b2001200341306c6a41e8026a2110200120034105746a41086a2111200341027420016a41fc066a2802002104410021122005417f6a2201450d00034020042802f80621042001417f6a22010d000c010b0b0b410f4101102e000b102f000b200241b80d6a41086a22014200370300200242003703b80d41d58fc5004111200241b80d6a1003200241b00c6a41086a22052001290300370300200220022903b80d3703b00c2002200c3703a0112002200f37039811200241b00c6a411020024198116a4110100520014200370300200242003703b80d41cebdc4004116200241b80d6a100320052001290300370300200220022903b80d3703b00c2002411036029c112002200241b00c6a360298112034204520024198116a10950120022802e00b211220022802d80b2103024020022802dc0b2201450d00034020032802f80621032001417f6a22010d000b0b02402012450d004100210441002101034002400240200120032f01064f0d002003200141306c6a2205418c036a280200211120054188036a2802002105200141016a21010c010b02400240200328020022010d002004ad210c41002110410021010c010b20033301044220862004ad84210c410121100b20031029200ca7210402400240200c422088a7221120012f01064f0d00200121050c010b034002400240200128020022050d002004ad210c410021050c010b201041016a211020013301044220862004ad84210c0b20011029200ca7210420052101200c422088a7221120052f01064f0d000b0b201141027420056a41fc066a28020021032005201141306c6a2201418c036a280200211120014188036a280200210502402010417f6a2201450d00034020032802f80621032001417f6a22010d000b0b410021010b2005450d012012417f6a211202402011450d00200510290b20120d000b0b0240200341b0d6c000460d0020032802002101200310292001450d0020012802002105200110292005450d00024020052802002201450d000340200510292001210520012802002203210120030d000b0b200510290b02402017450d0020174106742105204441306a210103400240200141046a280200450d00200128020010290b200141c0006a2101200541406a22050d000b0b02402043450d00204410290b0240203e450d00203e412c6c2105203641206a210103400240200141046a280200450d00200128020010290b2001412c6a2101200541546a22050d000b0b203d450d00203610290b02402015452014720d00201310290b20340d0102402009450d00200941d0006c2105200a41c0006a210103400240200141046a280200450d00200128020010290b200141d0006a2101200541b07f6a22050d000b0b200b450d00200a10290b200041003602000c010b200020303702042000203436020002402009450d00200941d0006c2105200a41c0006a210103400240200141046a280200450d00200128020010290b200141d0006a2101200541b07f6a22050d000b0b200b450d00200a10290b200241c0186a24000f0b41f7cdc3004133200241b00e6a41ecd6c3001054000b1033000b820101017f02400240411c10322202450d00200241186a410028008def45360000200241106a4100290085ef45370000200241086a41002900fdee45370000200241002900f5ee453700002002411c413810342202450d01200042b8808080c004370204200020023602002002200137001c0f0b411c4101102e000b41384101102e000bcb0201057f230041d0006b220224002002410036022820014110200241286a1006210302400240024020022802282204417f460d0020030d010b200041003a00000c010b41002101200241003a00480340024020042001470d000240200141ff0171450d00200241003a00480b41f7cdc3004133200241286a41ecd6c3001054000b200241286a20016a200320016a2d00003a00002002200141016a22053a00482005210120054120470d000b200241086a41186a2201200241286a41186a290300370300200241086a41106a2205200241286a41106a290300370300200241086a41086a2206200241286a41086a2903003703002002200229032837030802402004450d00200310290b20002002290308370001200041013a0000200041196a2001290300370000200041116a2005290300370000200041096a20062903003700000b200241d0006a24000b960101037f230041106b220224002002410036020420014110200241046a100621010240024020022802042203417f460d002001450d00200241003a000202402003450d0020012d00002104200241003a000320034101460d0020012d00012103200110290c020b41f7cdc3004133200241086a41ecd6c3001054000b410221040b200020033a0001200020043a0000200241106a24000bc40903037f017e037f230041106b220224002002410036020820024201370300200128020021034101103221040240024002400240024002400240024002400240024020034101460d002004450d02200242818080801037020420022004360200200441013a0000200141086a29030021050240024020022802042206200228020822046b4108490d00200441086a2103200228020021060c010b200441086a22032004490d0b20064101742207200320032007491b22074100480d0b0240024020060d002007103221060c010b200228020020062007103421060b2006450d0420022007360204200220063602000b20022003360208200620046a2005370000200141106a29030021050240024020022802042203200228020822046b4108490d00200228020021030c010b200441086a22062004490d0b20034101742207200620062007491b22064100480d0b0240024020030d002006103221030c010b200228020020032006103421030b2003450d0520022006360204200220033602000b2002200441086a360208200320046a2005370000200141186a29030021050240024020022802042203200228020822046b4108490d00200228020021030c010b200441086a22062004490d0b20034101742207200620062007491b22064100480d0b0240024020030d002006103221030c010b200228020020032006103421030b2003450d0620022006360204200220033602000b2002200441086a360208200320046a2005370000200141206a2802002103200141286a28020022042002106602402004450d002003200441286c6a210803402002200336020c2002410c6a2002108a01200341206a29030021050240024020022802042206200228020822046b4108490d00200228020021060c010b200441086a22072004490d0d20064101742204200720072004491b22044100480d0d0240024020060d002004103221060c010b200228020020062004103421060b2006450d092002200436020420022006360200200228020821040b2002200441086a360208200620046a20053700002008200341286a2203470d000b0b2001412c6a200210810102400240200228020420022802082204460d00200228020021030c010b200441016a22032004490d0b20044101742206200320032006491b22064100480d0b0240024020040d002006103221030c010b200228020020042006103421030b2003450d082002200636020420022003360200200228020821040b2002200441016a360208200320046a20012d004c3a00000c010b2004450d07200242818080801037020420022004360200200441023a0000200128020421060240024020022802042203200228020822046b4104490d00200228020021030c010b200441046a22072004490d0a20034101742208200720072008491b22074100480d0a0240024020030d002007103221030c010b200228020020032007103421030b2003450d0920022007360204200220033602000b2002200441046a360208200320046a20063600000b20002002290300370200200041086a200241086a280200360200200241106a24000f0b41014101102e000b20074101102e000b20064101102e000b20064101102e000b20044101102e000b20064101102e000b41014101102e000b20074101102e000b1033000b130020004101360204200041d8f0c2003602000b3400200041e1f1c20036020420004100360200200041146a4103360200200041106a41ecf1c200360200200041086a420a3702000bd60801037f024002400240024002400240024002400240410110322202450d00200220002d00003a000020024101410210342202450d01200220002d00013a000120024102410410342202450d02200220002d00023a0002200220002d00033a000320024104410810342202450d03200220002d00043a0004200220002d00053a0005200220002d00063a0006200220002d00073a000720024108411010342202450d04200220002d00083a0008200220002d00093a0009200220002d000a3a000a200220002d000b3a000b200220002d000c3a000c200220002d000d3a000d200220002d000e3a000e200220002d000f3a000f20024110412010342202450d05200220002d00103a0010200220002d00113a0011200220002d00123a0012200220002d00133a0013200220002d00143a0014200220002d00153a0015200220002d00163a0016200220002d00173a0017200220002d00183a0018200220002d00193a0019200220002d001a3a001a200220002d001b3a001b200220002d001c3a001c200220002d001d3a001d200220002d001e3a001e200220002d001f3a001f2002412041c00010342202450d06200220002d00203a0020200220002d00213a0021200220002d00223a0022200220002d00233a0023200220002d00243a0024200220002d00253a0025200220002d00263a0026200220002d00273a0027200220002d00283a0028200220002d00293a0029200220002d002a3a002a200220002d002b3a002b200220002d002c3a002c200220002d002d3a002d200220002d002e3a002e200220002d002f3a002f200220002d00303a0030200220002d00313a0031200220002d00323a0032200220002d00333a0033200220002d00343a0034200220002d00353a0035200220002d00363a0036200220002d00373a0037200220002d00383a0038200220002d00393a0039200220002d003a3a003a200220002d003b3a003b200220002d003c3a003c200220002d003d3a003d200220002d003e3a003e200220002d003f3a003f024002402001280200220041046a2802002203200041086a28020022016b41c000490d00200028020021030c010b200141c0006a22042001490d0920034101742201200420042001491b22014100480d090240024020030d002001103221030c010b200028020020032001103421030b2003450d0820002003360200200041046a2001360200200041086a28020021010b200041086a200141c0006a360200200320016a220041386a200241386a290000370000200041306a200241306a290000370000200041286a200241286a290000370000200041206a200241206a290000370000200041186a200241186a290000370000200041106a200241106a290000370000200041086a200241086a29000037000020002002290000370000200210290f0b41014101102e000b41024101102e000b41044101102e000b41084101102e000b41104101102e000b41204101102e000b41c0004101102e000b20014101102e000b1033000bdc0301027f02400240024002400240410410322202450d002002200128020022032d00003a0000200220032d00013a0001200220032d00023a0002200220032d00033a000320024104410810342202450d01200220032d00043a0004200220032d00053a0005200220032d00063a0006200220032d00073a000720024108411010342202450d02200220032d00083a0008200220032d00093a0009200220032d000a3a000a200220032d000b3a000b200220032d000c3a000c200220032d000d3a000d200220032d000e3a000e200220032d000f3a000f20024110412010342202450d03200220032d00103a0010200220032d00113a0011200220032d00123a0012200220032d00133a0013200220032d00143a0014200220032d00153a0015200220032d00163a0016200220032d00173a0017200220032d00183a0018200220032d00193a0019200220032d001a3a001a200220032d001b3a001b200220032d001c3a001c200220032d001d3a001d200220032d001e3a001e200220032d001f3a001f200128020421012002412041c00010342203450d04200042c0808080c00437020420002003360200200320013600200f0b41044101102e000b41084101102e000b41104101102e000b41204101102e000b41c0004101102e000bcd0101047f200020014105746a210320002104024003400240200320046b41e0004b0d00024020042003460d00200020014105746a210503404101210620022004460d04200420024120109d05450d042005200441206a2204470d000b0b41000f0b4101210620042002460d01200420024120109d05450d01200441206a22052002460d01200520024120109d05450d01200441c0006a22052002460d01200520024120109d05450d01200441e0006a22052002460d0120044180016a2104200520024120109d050d000b0b20060bfa0401057f230041106b2202240002400240024002400240024020002802704101460d0002400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d0620034101742205200420042005491b22054100480d060240024020030d002005103221040c010b200128020020032005103421040b2004450d0320012004360200200141046a2005360200200141086a28020021030b200141086a2205200341016a360200200420036a41003a00002000280274210602400240200141046a2802002204200528020022036b4104490d00200128020021040c010b200341046a22052003490d0620044101742203200520052003491b22034100480d060240024020040d002003103221040c010b200128020020042003103421040b2004450d0420012004360200200141046a2003360200200141086a28020021030b200141086a200341046a360200200420036a20063600000c010b02400240200141046a280200200141086a2802002203460d00200128020021040c010b200341016a22042003490d0520034101742205200420042005491b22054100480d050240024020030d002005103221040c010b200128020020032005103421040b2004450d0420012004360200200141046a2005360200200141086a28020021030b200141086a200341016a360200200420036a41013a00000b2000200110ea022000280278210320004180016a28020022002001106602402000450d002000410574210003402002200136020c20032002410c6a108501200341206a2103200041606a22000d000b0b200241106a24000f0b20054101102e000b20034101102e000b20054101102e000b1033000b860201017f0240024020002d00002201410e4b0d00024002400240024020010e0f050505050500050501050205030505050b200041086a2d00004101470d04200041146a280200450d04200041106a28020010290c040b200041046a2d00004103470d0302402000410c6a280200450d00200041086a28020010290b200041186a280200450d03200041146a28020010290c030b200041046a2802000d022000410c6a280200450d02200041086a28020010290c020b200041086a2d00004105490d01200041306a280200450d012000412c6a28020010290c010b200041086a280200450d00200041046a28020010290b0240200041fc006a280200450d00200028027810290b0ba50201077f230041c0006b2201240002400240411210322202450d00200241106a41002f00cd89433b0000200241086a41002900c58943370000200241002900bd8943370000200141206a41186a22034200370300200141206a41106a22044200370300200141206a41086a220542003703002001420037032020024112200141206a1000200141186a22062003290300370300200141106a22072004290300370300200141086a2204200529030037030020012001290320370300412010322203450d0120032001290300370000200042a0808080800437020420002003360200200341186a2006290300370000200341106a2007290300370000200341086a200429030037000020021029200141c0006a24000f0b41124101102e000b41204101102e000b130020004106360204200041d089c3003602000b3400200041db8fc30036020420004100360200200041146a410f360200200041106a41e48fc300360200200041086a42063702000b5401017f230041206b22022400200241003602082002420837030020024100360218200242013703104100200241106a1066200041086a2002280218360200200020022903103702002002103a200241206a24000b7201017f230041306b22022400200241186a4200370300200241106a4200370300200241086a42003703002002420037030020024100360228200242013703202002200241206a36022c20022002412c6a108501200041086a200228022836020020002002290320370200200241306a24000b5c01027f230041106b2202240002404101103222030d0041014101102e000b200341003a0000200242818080801037020420022003360200410020021066200041086a200228020836020020002002290300370200200241106a24000b0900200042043702000bc618012d7f230041b00d6b220324002003200236020420032001360200200341086a41086a2201420037030020034200370308419b89c3004115200341086a1003200341900d6a41086a2001290300370300200320032903083703900d200341e80c6a200341900d6a109d03024002400240024020032802ec0c22040d0041012104410021050c010b20032802f00c2105200341e80c6a410c6a28020022020d010b20004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b20032c00e80c2101200341086a410041e00c109a051a200441206a2106200420024105746a210741002108410021094100210a4100210b4100210c4100210d4100210e4100210f410021104100211141002112410021134100211441002115410021164100211741002118410021194100211a4100211b4100211c4100211d4100211e4100211f4100212041002121410021224100212341002124410021254100212641002127200421024100212841d1002129024003402028212a02400240024002402001450d0020072004460d01200141016a210103400240024020022007470d002006212b200621022004212c0c010b2002212c200241206a222b21020b2001417f6a22010d000c030b0b024020022007460d00200241206a212b2002212c0c030b2006212b2004212c20072004460d040c010b200141016a2101034020072002460d04200241206a21022001417f6a22010d000b200241606a212c2002212b0b202c450d020b202b21020240024002400240024002402003280204220141056a222b417f4c0d002003280200212d02400240202b450d00202b1032222e450d0341002128200341003602980d2003202b3602940d2003202e3602900d0c010b200341003602980d2003202b3602940d200341013602900d41011032222e450d03200341013602940d2003202e3602900d20032802980d21280b2003202841016a3602980d202e20286a202a3a00002001200341900d6a10660240024020032802940d222e20032802980d222b6b2001490d0020032802900d212e0c010b202b20016a2228202b490d05202e410174222b20282028202b491b222b4100480d0502400240202e0d00202b1032212e0c010b20032802900d202e202b1034212e0b202e450d042003202b3602940d2003202e3602900d20032802980d212b0b2003202b20016a3602980d202e202b6a202d2001109b051a2003200341900d6a36028c0d202c2003418c0d6a10850120032802940d212c20032802900d210120032802980d212b200341900d6a41186a222e4200370300200341900d6a41106a22284200370300200341900d6a41086a222d4200370300200342003703900d2001202b200341900d6a1000200341e80c6a41186a222b202e290300370300200341e80c6a41106a222e2028290300370300200341e80c6a41086a222f202d290300370300200320032903900d3703e80c0240202c450d00200110290b2029417f6a2129202a41016a2128200341086a202a4103704105746a220120032903e80c370000200141186a202b290300370000200141106a202e290300370000200141086a202f2903003700004100212c0340202a202a41036e222b417d6c6a4102470d06200341086a202c6a220141df006a2d000022082001411f6a2d000022097120082009722001413f6a2d00007172211f200141de006a2d000022082001411e6a2d000022097120082009722001413e6a2d00007172211e200141dd006a2d000022082001411d6a2d000022097120082009722001413d6a2d00007172211d200141dc006a2d000022082001411c6a2d000022097120082009722001413c6a2d00007172211c200141db006a2d000022082001411b6a2d000022097120082009722001413b6a2d00007172211b200141da006a2d000022082001411a6a2d000022097120082009722001413a6a2d00007172211a200141d9006a2d00002208200141196a2d00002209712008200972200141396a2d000071722119200141d8006a2d00002208200141186a2d00002209712008200972200141386a2d000071722118200141d7006a2d00002208200141176a2d00002209712008200972200141376a2d000071722117200141d6006a2d00002208200141166a2d00002209712008200972200141366a2d000071722116200141d5006a2d00002208200141156a2d00002209712008200972200141356a2d000071722115200141d4006a2d00002208200141146a2d00002209712008200972200141346a2d000071722114200141d3006a2d00002208200141136a2d00002209712008200972200141336a2d000071722113200141d2006a2d00002208200141126a2d00002209712008200972200141326a2d000071722112200141d1006a2d00002208200141116a2d00002209712008200972200141316a2d000071722111200141d0006a2d00002208200141106a2d00002209712008200972200141306a2d000071722110200141cf006a2d000022082001410f6a2d000022097120082009722001412f6a2d00007172210f200141ce006a2d000022082001410e6a2d000022097120082009722001412e6a2d00007172210e200141cd006a2d000022082001410d6a2d000022097120082009722001412d6a2d00007172210d200141cc006a2d000022082001410c6a2d000022097120082009722001412c6a2d00007172210c200141cb006a2d000022082001410b6a2d000022097120082009722001412b6a2d00007172210b200141ca006a2d000022082001410a6a2d000022097120082009722001412a6a2d00007172210a200141c9006a2d00002208200141096a2d00002209712008200972200141296a2d000071722109200141c8006a2d00002208200141086a2d00002220712008202072200141286a2d000071722108200141c7006a2d00002220200141076a2d00002221712020202172200141276a2d000071722120200141c6006a2d00002221200141066a2d00002222712021202272200141266a2d000071722121200141c5006a2d00002222200141056a2d00002223712022202372200141256a2d000071722122200141c4006a2d00002223200141046a2d00002224712023202472200141246a2d000071722123200141c3006a2d00002224200141036a2d00002225712024202572200141236a2d000071722124200141c2006a2d00002225200141026a2d00002226712025202672200141226a2d000071722125200141c1006a2d00002226200141016a2d00002227712026202772200141216a2d000071722126200141c0006a2d0000222720012d0000222e712027202e72200141206a2d000071722127202c41800c460d06200341086a202c202b410574202a41096e41e0006c6b6a6a220141ff006a201f3a0000200141fe006a201e3a0000200141fd006a201d3a0000200141fc006a201c3a0000200141fb006a201b3a0000200141fa006a201a3a0000200141f9006a20193a0000200141f8006a20183a0000200141f7006a20173a0000200141f6006a20163a0000200141f5006a20153a0000200141f4006a20143a0000200141f3006a20133a0000200141f2006a20123a0000200141f1006a20113a0000200141f0006a20103a0000200141ef006a200f3a0000200141ee006a200e3a0000200141ed006a200d3a0000200141ec006a200c3a0000200141eb006a200b3a0000200141ea006a200a3a0000200141e9006a20093a0000200141e8006a20083a0000200141e7006a20203a0000200141e6006a20213a0000200141e5006a20223a0000200141e4006a20233a0000200141e3006a20243a0000200141e2006a20253a0000200141e1006a20263a0000200141e0006a20273a0000202b212a202c41e0006a222c41e00c470d000c060b0b102f000b202b4101102e000b41014101102e000b202b4101102e000b1033000b4100210120290d000b0b2000201f3a001f2000201e3a001e2000201d3a001d2000201c3a001c2000201b3a001b2000201a3a001a200020193a0019200020183a0018200020173a0017200020163a0016200020153a0015200020143a0014200020133a0013200020123a0012200020113a0011200020103a00102000200f3a000f2000200e3a000e2000200d3a000d2000200c3a000c2000200b3a000b2000200a3a000a200020093a0009200020083a0008200020203a0007200020213a0006200020223a0005200020233a0004200020243a0003200020253a0002200020263a0001200020273a00000b02402005450d00200410290b200341b00d6a24000bfd0102057f017e230041306b220224002002410036022020014110200241206a10062101024002400240024020022802202203417f460d0020010d010b200041003602040c010b20022003360214200220013602102003450d0120022003417f6a3602142002200141016a36021020012d00002103200241206a200241106a103120022802202204450d012002410c6a41026a2002411d6a41026a2d000022053a0000200220022f001d22063b010c20022902242107200020033a0000200020063b0001200041036a20053a00002000200737020820002004360204200110290b200241306a24000f0b41f7cdc3004133200241206a41ecd6c3001054000ba91604057f037e067f017e230041a0026b22012400200141b8016a41086a22024200370300200142003703b80141b2f6c5004115200141b8016a1003200141e0016a41086a22032002290300370300200120012903b8013703e001200141e0016a41101004200141306a41c7f6c500411a105d200128023421042001280230210520024200370300200142003703b80141f8f6c500411b200141b8016a1003200141106a4180e59af7002004410020051b220420044180e59af7004922051b20044180e59af70020051b6b2205ad220642002006420010a00520032002290300370300200120012903b8013703e001200642a8c30180210742ffffffffffffffffff00428080808080808080807f20051b2001290310220620012903182006423f87521b42808090bbbad6adf00d7f2108200141206a200141e0016a10b3012001290328420020012802201b210602400240200441ffe49af7004b0d0042ffffffffffffffffff00428080808080808080807f2006200720087d22087d22074200531b20072006427f5522022008427f554720022007427f5547711b22064280ec94a37c20064280ec94a37c551b21060c010b42ffffffffffffffffff00428080808080808080807f2006200720087c22087c22074200531b20072006427f5522022008427f554620022007427f5547711b21060b200141b8016a41086a22024200370300200142003703b80141f8f6c500411b200141b8016a1003200141e0016a41086a22042002290300370300200120012903b8013703e001200120063703b801200141e0016a4110200141b8016a4108100520024200370300200142003703b80141c7f6c500411a200141b8016a100320042002290300370300200120012903b8013703e001200141e0016a4110100420024200370300200142003703b80141e1f6c5004117200141b8016a100320042002290300370300200120012903b8013703e001200141e0016a4110100420024200370300200142003703b80141d983c300410d200141b8016a100320042002290300370300200120012903b8013703e001200141086a200141e0016a10f001200128020c21032001280208210520024200370300200142003703b80141c0acc3004111200141b8016a100320042002290300370300200120012903b8013703e001200141b8016a200141e0016a411010590240024020012d00b8014101470d00200141e0016a4110100420014180026a41186a200141d1016a290000220637030020014180026a41106a200141b8016a41116a290000220737030020014180026a41086a200141c1016a2900002208370300200141386a41086a2008370300200141386a41106a2007370300200141386a41186a2006370300200120012900b901220637038002200120063703380c010b20014180026a41186a200141d1016a29000037030020014180026a41106a200141b8016a41116a29000037030020014180026a41086a200141c1016a290000370300200141386a41086a4200370300200141386a41106a4200370300200141386a41186a4200370300200120012900b90137038002200142003703380b200141b8016a41086a22024200370300200142003703b80141fb83c300410d200141b8016a1003200141e0016a41086a2002290300370300200120012903b8013703e001200141003602b801200141e0016a4110200141b8016a10062102024002400240024002400240024020012802b8012204417f460d002002450d0020012004360284022001200236028002200141b8016a20014180026a103d20012802b8012209450d0220012902bc01210602402004450d00200210290b200141e0016a411010042006422088a721022006a7210a0c010b41042109410021024100210a0b2003410020051b210b200141b8016a41086a22044200370300200142003703b80141e683c3004115200141b8016a1003200141e0016a41086a2004290300370300200120012903b8013703e001200141b8016a200141e0016a411010590240024020012d00b8014101470d00200141e0016a4110100420014180026a41186a200141d1016a290000220637030020014180026a41106a200141c9016a290000220737030020014180026a41086a200141c1016a2900002208370300200141d8006a41086a2008370300200141d8006a41106a2007370300200141d8006a41186a2006370300200120012900b901220637038002200120063703580c010b20014180026a41186a200141d1016a29000037030020014180026a41106a200141c9016a29000037030020014180026a41086a200141c1016a290000370300200141d8006a41086a4200370300200141d8006a41106a4200370300200141d8006a41186a4200370300200120012900b90137038002200142003703580b0240200b41fb01490d00200b41857e6a2203450d00411010322204450d02200441086a4100290090844337000020044100290088844337000020044110412010342204450d0320042003360010200141e0016a41186a22034200370300200141e0016a41106a22054200370300200141e0016a41086a220c4200370300200142003703e00120044114200141e0016a1000200141b8016a41186a2003290300370300200141b8016a41106a2005290300370300200141b8016a41086a200c290300370300200120012903e0013703b801200141b8016a41201004200410290b200141e0016a41186a22044200370300200141e0016a41106a22034200370300200141e0016a41086a22054200370300200142003703e001200141e0016a1013200141f8006a41186a2004290300370300200141f8006a41106a2003290300370300200141f8006a41086a2005290300370300200120012903e001370378200141b8016a41186a220c200141386a41186a290300370300200141b8016a41106a220d200141386a41106a290300370300200141b8016a41086a220e200141386a41086a290300370300200120012903383703b801200442003703002003420037030020054200370300200142003703e0010240200141b8016a4120200141e0016a1014450d0020014198016a41086a2005290300220637030020014198016a41106a2003290300220737030020014198016a41186a20042903002208370300200120012903e001220f37039801200e2006370300200d2007370300200c20083703002001200f3703b80102402002200a470d00200241016a22042002490d0620024101742203200420042003491b220aad42247e2206422088a70d062006a722044100480d060240024020020d002004103221090c010b2009200241246c2004103421090b2009450d050b2009200241246c6a220441003a0000200420012903b801370001200441096a200141c0016a290300370000200441116a200141c8016a290300370000200441196a200141d0016a290300370000200420012f0080023b0021200441236a20014182026a2d00003a0000200241016a21020b200020012903383700102000200b36020020002001290378370030200041286a200141386a41186a290300370000200041206a200141386a41106a290300370000200041186a200141386a41086a290300370000200041386a200141f8006a41086a290300370000200041c0006a200141f8006a41106a290300370000200041c8006a200141f8006a41186a2903003700002000410c6a2002360200200041086a200a36020020002009360204200041e8006a200141d8006a41186a290300370000200041e0006a200141d8006a41106a290300370000200041d8006a200141d8006a41086a29030037000020002001290358370050200141a0026a24000f0b41f7cdc3004133200141b8016a41ecd6c3001054000b41104101102e000b41204101102e000b20044104102e000b1033000b0a0041d8fbc200106d000b0a0041e8fac200106d000b9668050e7f017e097f107e087f230041c00c6b22012400200141d0036a200041046a10a2030240024002400240024002400240024002400240024002400240024002400240024002400240024020012802d40341246c22020d004100210341002104410421050c010b20012802d00321064104210541002103410021040340024020062d00004101470d00200641106a2802002207417f4c0d12200641086a2802002108200641016a28000021090240024020070d004101210a4100210b0c010b2007210b20071032220a450d040b200a20082007109b05210a200141f8036a41026a220c200141e0086a41026a2d00003a0000200141f8096a41086a220d200141980b6a41086a290200370300200120012f00e0083b01f803200120012902980b3703f809024020032004470d00200341016a22082003490d152003410174220e20082008200e491b2204ad42247e220f422088a70d15200fa722084100480d150240024020030d002008103221050c010b2005200341246c2008103421050b2005450d050b2005200341246c6a220841013a000020082009360001200820073600102008200b36000c2008200a360008200820012f01f8033b0005200841076a200c2d00003a0000200820012903f8093702142008411c6a200d290300370200200341016a21030b200641246a21062002415c6a22020d000b0b200141003602f80941caf9c2004110200141f8096a41041005200141e0086a41086a22064200370300200142003703e00841d983c300410d200141e0086a1003200141f8096a41086a22082006290300370300200120012903e0083703f809200120002802003602980b200141f8096a4110200141980b6a4104100520064200370300200142003703e00841fb83c300410d200141e0086a100320082006290300370300200120012903e0083703f8092001411036029c0b2001200141f8096a3602980b20052003200141980b6a10b80120064200370300200142003703e00841c0acc3004111200141e0086a100320082006290300370300200120012903e0083703f8092001411036029c0b2001200141f8096a3602980b200041106a2207200141980b6a10890120002802002108411010322206450d02200641086a4100290090844337000020064100290088844337000020064110412010342206450d0320062008417f6a360010200141c8076a41186a22084200370300200141c8076a41106a22024200370300200141c8076a41086a22094200370300200142003703c80720064114200141c8076a1000200141f8096a41186a2008290300370300200141f8096a41106a2002290300370300200141f8096a41086a22082009290300370300200120012903c8073703f8092001412036029c0b2001200141f8096a3602980b2007200141980b6a10890120061029200141e0086a41086a22064200370300200142003703e00841e683c3004115200141e0086a100320082006290300370300200120012903e0083703f8092001411036029c0b2001200141f8096a3602980b200041d0006a200141980b6a10890120064200370300200142003703e008419b89c3004115200141e0086a100320082006290300370300200120012903e0083703f809200141980b6a200141f8096a109d03024002400240024002400240200128029c0b0d004100210620014184046a4100360200200142013702fc03200141003a00f803200141f8036a4104722107410021080c010b200141f8036a41086a200141980b6a41086a290300370300200120012903980b3703f803200141f8036a410472210720014184046a280200220841d0004b0d0120014180046a28020021060b200141f8096a41186a2209200041286a290000370300200141f8096a41106a220a200041206a290000370300200141f8096a41086a220b200041186a290000370300200120002900103703f80920082006470d02200641016a22082006490d1520064101742202200820082002491b220841ffffff3f712008470d152008410574220241004e0d010c150b200141f8096a41186a220a200041286a290000370300200141f8096a41106a220b200041206a290000370300200141f8096a41086a220c200041186a290000370300200120002900103703f809200820012c00f80322094d0d0720012802fc03220620094105746a220220012903f809370000200241086a200c290300370000200241106a200b290300370000200241186a200a2903003700002001200941187441808080086a41187541d1006f3a00f8030c020b0240024020060d002002103221060c010b200728020020064105742002103421060b2006450d0720072006360200200120083602800420012802840421080b2007280200220620084105746a220220012903f809370000200241086a200b290300370000200241106a200a290300370000200241186a20092903003700002001200841016a2208360284040b200141e0086a41086a22024200370300200142003703e008419b89c3004115200141e0086a1003200141f8096a41086a2002290300370300200120012903e0083703f809410110322202450d06200142818080801037029c0b200120023602980b200220012d00f8033a00002008200141980b6a106602402008450d002008410574210803402001200141980b6a3602e0082006200141e0086a108501200641206a2106200841606a22080d000b0b200128029c0b2106200141f8096a411020012802980b220820012802a00b100502402006450d00200810290b0240200741046a280200450d00200728020010290b200141e0086a41086a22064200370300200142003703e00841b089c300410d200141e0086a1003200141f8096a41086a22082006290300370300200120012903e0083703f809200141f8096a4110100420064200370300200142003703e00841a7f7c5004111200141e0086a100320082006290300370300200120012903e0083703f809200141f8096a41101004200141f8096a10950320012802f809220620012802800a1012024020012802fc09450d00200610290b2000280200211010d401201041044d0d0b200141e0086a41086a22064200370300200142003703e00841b6f0c2004111200141e0086a1003200141f8036a41086a2006290300370300200120012903e0083703f803200141003602f809200141f8036a4110200141f8096a100621060240024020012802f8092208417f460d002006450d002001200836029c0b200120063602980b200141f8096a200141980b6a103e20012802f809220a450d0920012902fc09210f2008450d01200610290c010b4104210a4200210f0b2010417b6a2102200a200f422088a7220b41c4006c22066a21090240200641cd014f0d0041002106200a21080c0a0b200a41d0016a21084100210603400240200841b07e6a22072d00004101460d00200841b47e6a28020020024f0d0c0b0240200741c4006a2d00004101460d00200841f87e6a2802002002490d00200641016a21060c0c0b024020074188016a2d00004101460d00200841bc7f6a2802002002490d00200641026a21060c0c0b02400240200741cc016a2d00004101460d00200828020020024f0d010b20084190026a2108200641046a2106200920074190026a6b41cc014d0d0a0c010b0b200641036a21060c0a0b20074101102e000b20084104102e000b41104101102e000b41204101102e000b41e8b1c300200920081036000b20024101102e000b41014101102e000b41f7cdc3004133200141c8076a41ecd6c3001054000b200841b07e6a21080b20082009460d00200a200b41c4006c6a21070340024020082d00004101460d00200841046a28020020024f0d020b200641016a21062007200841c4006a2208470d000b0b2006200b4b0d01200f42ffffffff0f83210f0240200b20066b2208450d0002402006450d00200a200a200641c4006c6a200841c4006c109c051a0b2008ad422086200f84210f0b200141e0086a41086a22064200370300200142003703e00841b6f0c2004111200141e0086a1003200141f8036a41086a2006290300370300200120012903e0083703f803200141f8096a200a200f422088a710fc02200141f8036a411020012802f809220820012802800a1005200fa72106024020012802fc09450d00200810290b2006450d00200a10290b200141003a00f809200141e0086a41086a22064200370300200142003703e00841b6aec5004117200141e0086a1003200141f8036a41086a2006290300370300200120012903e0083703f803200141f8036a4110200141f8096a41011005200141f8096a10b5010240412410322206450d00200620012903f80937000020064114360220200641186a200141f8096a41186a290300370000200641106a200141f8096a41106a290300370000200641086a200141f8096a41086a290300370000200142818080801037029c0b200120063602980b200141980b6a10f0021086030240201041809c31700d000240024041f9abc500411f10f101220641ff01714102460d0020064101710d010b2010104a450d012010104e1a0c010b2010104e450d002010104a1a0b200141c8036a41e6abc5004113105d20012802cc03210620012802c8032108200141c0036a41cdabc5004119105d024002402006410020081b220620012802c403410020012802c0031b2208490d0020062109410321020c010b02400340200141980b6a2006105e20012d00a80c22024103470d012008200641016a2206470d000b41032102200821090c010b200141e4086a200141980b6a419001109b051a2001200141980b6a4194016a2800003600e303200120012800a90c3602e003200141c8076a200141e0086a419401109b051a200141b0066a200141c8076a419401109b051a200120012800e3033600db03200120012802e0033602d803200641016a21090b200141c8076a200141b0066a419401109b051a200120012800db033600e303200120012802d8033602e0030240024020024103460d0020014198056a200141c8076a419401109b051a200120012800e30336009305200120012802e00336029005200120063602f809200141f8096a41047220014198056a419401109b051a200141f8096a4198016a20023a0000200141910b6a2206200128029005360000200141940b6a200128009305360000200141880b6a2802002010460d01200141800a6a102a0b410821114100210241002112410821130c040b200141f8036a200141f8096a419801109b051a410321072001200641036a2800003600f303200120062800003602f003200141f8096a200141f8036a419801109b051a200120012800f30336009b0b200120012802f0033602980b024041a00110322211450d002011200141f8096a419801109b05220620023a009801200620012802980b360099012006419c016a200128009b0b3600000240024020092008490d00200921060c010b02400340200141980b6a2009105e20012d00a80c22074103470d012008200941016a2209470d000b41032107200821060c010b200141e4086a200141980b6a419001109b051a2001200141980b6a4194016a2800003600e303200120012800a90c3602e003200141c8076a200141e0086a419401109b051a200141b0066a200141c8076a419401109b051a200120012800e3033600db03200120012802e0033602d803200941016a21060b200141c8076a200141b0066a419401109b051a200120012800db033600e303200120012802d8033602e0030240024020074103460d0020014198056a200141c8076a419401109b051a200120012800e30336009305200120012802e00336029005200120093602f809200141f8096a41047220014198056a419401109b05210c200141f8096a4198016a20073a0000200141f8096a4199016a220a200128029005360000200141f8096a419c016a200128009305360000200141f8096a4190016a2802002010460d01200141800a6a102a0b41012102410121120c040b200141f8036a200141f8096a419801109b051a2001200a41036a220b2800003600f3032001200a2800003602f003200141a90c6a2100200141e0086a41046a210e41012102410121120340200141f8096a200141f8036a419801109b051a200120012800f30336009b0b200120012802f0033602980b02400240024020122002470d00200241016a22092002490d0b2002410174220d20092009200d491b2212ad42a0017e220f422088a70d0b200fa722094100480d0b0240024020020d002009103221110c010b2011200241a0016c2009103421110b2011450d010b2011200241a0016c6a200141f8096a419801109b0522094198016a20073a000020094199016a20012802980b3600002009419c016a200128009b0b3600000240024020062008490d0020062109410321070c010b02400340200141980b6a2006105e20012d00a80c22074103470d012008200641016a2206470d000b20082109410321070c010b200e200141980b6a419001109b051a2001200041036a2800003600e303200120002800003602e003200141c8076a200141e0086a419401109b051a200141b0066a200141c8076a419401109b051a200120012800e3033600db03200120012802e0033602d803200641016a21090b200241016a2102200141c8076a200141b0066a419401109b051a200120012800db033600e303200120012802d8033602e00320074103460d0620014198056a200141c8076a419401109b051a200120012800e30336009305200120012802e00336029005200120063602f809200c20014198056a419401109b051a200a200128029005360000200b200128009305360000200120073a00900b20012802880b2010460d01200141800a6a102a0c060b20094108102e000b200141f8036a200141f8096a419801109b051a2001200b2800003600f3032001200a2800003602f003200921060c000b0b41a0014108102e000b41244104102e000b41fcd8c500106d000b201121130b2013200241a0016c6a21142002450d01200141f8036a4104722106200141f8036a4101722115200141890b6a2116200141980b6a41046a2117200141a8026a41106a21180340201322082802002102200141f8096a200841046a419401109b051a200120084199016a2800003602f80320012008419c016a2800003600fb03200841a0016a211320084198016a2d000022084103460d02200141980b6a200141f8096a419401109b051a200120012800fb0336009305200120012802f80336029005200141f8096a2017419001109b051a2016200128029005360000201641036a200128009305360000200120083a00880b200141e0086a2002105520012802e008210b0240024020012802e80822080d00420021194200211a4200211b4200211c4200211d4200211e0c010b200841057421094200211d200b21084200211e4200211b4200211c420021194200211a0340200141b0036a2008105b200141b0036a41086a290300211f20012903b003210f20062008290000370000200641086a200841086a290000370000200641106a200841106a290000370000200641186a200841186a290000370000200120023602f803200141a8036a200141f8036a105620012d00a80341017121070240024020012d00a903220a0d00200141e8026a200f201f420a420010a10520012903e8022220210f200141e8026a41086a2903002221211f0c010b20014188036a201f4200200aad2220420010a00520014198036a200f42002020420010a005200141f8026a42004200200f420010a005427f20014198036a41086a290300222020012903880320012903f8027c7c222120012903900320012903800384420052202120205472220a1b2121427f200129039803200a1b21200b200841206a21084200202120071b201c7c4200202020071b2222201b7c221b202254ad7c211c2021420020071b201a7c2020420020071b222020197c2219202054ad7c211a201f201e7c200f201d7c221d200f54ad7c211e200941606a22090d000b0b024020012802e408450d00200b10290b200141e0086a2002105520012802e00821000240024020012802e80822080d004200212242002123420021244200212542002121420021260c010b2008410574210942002121200021084200212642002124420021254200212242002123034020062008290000370000200641086a200841086a2207290000370000200641106a200841106a220a290000370000200641186a200841186a220b290000370000200120023602f803200141e0026a200141f8036a105620012d00e002210c20012d00e102210d200141f8036a41186a200b290000370300200141f8036a41106a200a290000370300200141f8036a41086a2007290000370300200120082900003703f803200141c0026a2002200141f8036a200d41101058200141c0026a41186a29030020267c20012903d002220f20217c2221200f54ad7c21264200200141c0026a41086a290300220f200c41017122071b20257c420020012903c002221f20071b222020247c2224202054ad7c2125200f420020071b20237c201f420020071b220f20227c2222200f54ad7c2123200841206a2108200941606a22090d000b0b024020012802e408450d00200010290b200141e0086a41086a22074200370300200142003703e00841c2d5c0004116200141e0086a1003200141f8036a41086a220c2007290300370300200120012903e0083703f803200141a8026a200141f8036a10eb012018290300420020012802a80222081b210f20012903b002420020081b211f024002402021201d7c22204202882026201e7c2020202154ad7c2221423e8684221d2021420288221e84500d00201d202085201e20218584500d00410021080240034020014198026a20202021200841046a41fe0071109f05200841026a2108200129039802221d20014198026a41086a290300221e84500d01201d202085201e2021858450450d000b0b20014188026a20202021200841fe0071109f0520012903880220014188026a41086a29030084211d4200211e024020080d00201d420052ad211d0c020b201d420052ad211d0340200141e8016a2020202141002008417e6a2209200920084b1b220841ff0071109f05200141f8016a201d42018622274201842226201e420186201d423f8884221e2026201e10a0052027202620012903f80120012903e80156200141f8016a41086a290300221d200141e8016a41086a290300222856201d2028511b1b211d20080d000c020b0b4200211e2020202184420052ad211d0b02400240201f420288200f423e86842220200f420288222184500d002020201f852021200f8584500d004100210802400340200141d8016a201f200f200841046a41fe0071109f05200841026a210820012903d8012220200141d8016a41086a290300222184500d012020201f852021200f858450450d000b0b200141c8016a201f200f200841fe0071109f0520012903c801200141c8016a41086a29030084212042002121024020080d002020420052ad21200c020b2020420052ad21200340200141a8016a201f200f41002008417e6a2209200920084b1b220841ff0071109f05200141b8016a20204201862227420184222620214201862020423f888422212026202110a0052027202620012903b80120012903a80156200141b8016a41086a2903002220200141a8016a41086a29030022285620202028511b1b212020080d000c020b0b42002121201f200f84420052ad21200b02400240024002400240201d201e8450450d004100210b0c010b2025201c7c2024201b7c221f202454ad7c21242023201a7c202220197c220f202254ad7c212202400240024020012d00880b0e03010200010b200f201f56202220245620222024511b210b0c020b0340200141d8006a201f2024201d201e10a105202022192021221a844200510d04200141d8006a41086a290300212020012903582126200141c8006a200f20222019201a10a1054101210b20262001290348221b542020200141c8006a41086a290300222154202020215122081b0d020240201b202654202120205420081b450d004100210b0c030b200141386a20262020201d201e10a005200141286a201b20212019201a10a0050240200f200129032822207d22212022200141286a41086a2903007d200f202054ad7d222684500d002024200141386a41086a2903007d211b201f2001290338220f542108201f200f7d2120201d210f201e21222021211d2026211e2019211f201a21242020201b2008ad7d222184500d030c010b0b4100210b0c010b0340201e2126201d211920202021844200510d0220014188016a200f20222019202610a10520014198016a201f20242020202110a1054101210b200129039801221a200129038801221b5420014198016a41086a290300221d20014188016a41086a290300221e54201d201e5122081b0d010240201b201a54201e201d5420081b450d004100210b0c020b200141f8006a201a201d2020202110a005200141e8006a201b201e2019202610a0050240200f2001290368221d7d221e2022200141e8006a41086a2903007d200f201d54ad7d221a8450450d004100210b0c020b2024200141f8006a41086a2903007d211b201f2001290378220f542108201f200f7d211d2020210f20212122201e2120201a21212019211f20262124201d201b2008ad7d221e844200520d000b0b200141f8036a2002105520012802f803212920012802fc03212a2001280280042208450d0220292008410574222b6a212c2029210802400340200141e0086a41186a2209200841186a220d290000370300200141e0086a41106a220a200841106a22002900003703002007200841086a220e290000370300200120082900003703e0082008290000210f200641186a222d200d2900003700002006200f370000200641086a222e200e290000370000200641106a222f2000290000370000200120023602f803200141206a200141f8036a105620012d0021210e20012d00202130200141f8036a41186a220d2009290300370300200141f8036a41106a2200200a290300370300200c2007290300370300200120012903e0083703f8030240200b203041017145734101470d00200841206a21080c020b200841206a2108202b41606a222b0d000c040b0b0340200141c8076a41186a200d290300220f370300200141c8076a41106a2000290300221f370300200141c8076a41086a200c2903002220370300200120012903f80322213703c807200d200f3703002000201f370300200c2020370300200142e4cab5fbb6ccdcb0e3003703d803200120213703f803200141d8036a200141f8036a200e4118744118754102744198abc5006a2802004180de346c20106a108d012008202c460d03024003402009200841186a220e290000370300200a200841106a22302900003703002007200841086a222b290000370300200120082900003703e008200120023602f803202b290000210f2030290000211f20082900002120202d200e290000370000202f201f370000202e200f37000020062020370000200141186a200141f8036a105620012d0019210e20012d00182130200d20092903003703002000200a290300370300200c2007290300370300200120012903e0083703f803200b203041017145730d01202c200841206a2208470d000c050b0b200841206a21080c000b0b418c84c100106d000b418c84c100106d000b0240202a450d00202910290b2002105c02400240200b0d00200141053a008004200141053a00f803200120023602840441014100200141f8036a104c20074200370300200142003703e00841e6abc5004113200141e0086a1003200c2007290300370300200120012903e0083703f8032001200241016a3602e008200141f8036a4110200141e0086a41041005200141f8096a102a0c010b2001200236028404200141043a008004200141053a00f80341014100200141f8036a104c024020012802840b2209450d00200141e0086a200141f8096a418801109b051a200120023602e80902400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240411710322208450d002008410f6a41002900d98740220f370000200841086a41002900d28740221f370000200841002900ca8740222037000020084117412e10342208450d012008200920106a222b360017200141c8076a41186a22094200370300200141c8076a41106a220a4200370300200141c8076a41086a220b4200370300200142003703c8072008411b200141c8076a1000200141f8036a41186a220e2009290300370300200141f8036a41106a2230200a290300370300200c200b290300370300200120012903c8073703f803200141003602c807200141f8036a4120200141c8076a100621000240024002400240024002400240024020012802c807220d417f470d002001410036028004200142013703f8034100200141f8036a106620012802f8032200450d0220012902fc032121200120003602e003200120213702e4032021422088a7210d0c010b2001200d3602e8032001200d3602e403200120003602e0030b200d450d01200141f8036a2000200d410110800120012802f8034101460d0520012802fc03212e200128028404220d2001280280042200460d0420012802e803200d20006b6a222d4190016a222f417f4c0d20202f0d024101212c0c030b200141003602e803200142013703e0030b4101200141e0036a106620012802e403210020012802e803210d024020012d00e0084113470d00024002402000200d460d0020012802e00321000c010b200d41016a2200200d490d22200d410174222d20002000202d491b222d4100480d2202400240200d0d00202d103221000c010b20012802e003200d202d103421000b2000450d082001202d3602e403200120003602e00320012802e803210d0b2001200d41016a3602e8032000200d6a41003a00000c150b024002402000200d460d0020012802e00321000c010b200d41016a2200200d490d21200d410174222d20002000202d491b222d4100480d2102400240200d0d00202d103221000c010b20012802e003200d202d103421000b2000450d082001202d3602e403200120003602e00320012802e803210d0b2001200d41016a3602e8032000200d6a41013a0000200141e0086a200141e0036a105f200141e0086a4188016a280200212d0240024020012802e403220020012802e803220d6b4104490d0020012802e00321000c010b200d41046a222e200d490d212000410174220d202e202e200d491b220d4100480d210240024020000d00200d103221000c010b20012802e0032000200d103421000b2000450d092001200d3602e403200120003602e00320012802e803210d0b2001200d41046a3602e8032000200d6a202d3600000c140b202f1032222c450d080b2001202f36029c052001202c360298052001202d3602a005200120014198056a3602f803202e200141f8036a200d108201202d200d490d0820012802a005222e202d490d0920012802e803222e2000490d0a200128029805212f20012802e003212c2001202d200d6b222d3602b40c2001202e20006b222e3602b80c202d202e470d0b202f200d6a202c20006a202d109b051a200128029c05210020012802a005210d0240024020012d00e0084113470d00024002402000200d460d0020012802980521000c010b200d41016a2200200d490d21200d410174222d20002000202d491b222d4100480d2102400240200d0d00202d103221000c010b200128029805200d202d103421000b2000450d0f2001202d36029c05200120003602980520012802a005210d0b2001200d41016a3602a0052000200d6a41003a00000c010b024002402000200d460d0020012802980521000c010b200d41016a2200200d490d20200d410174222d20002000202d491b222d4100480d2002400240200d0d00202d103221000c010b200128029805200d202d103421000b2000450d0f2001202d36029c05200120003602980520012802a005210d0b2001200d41016a3602a0052000200d6a41013a0000200141e0086a20014198056a105f200141e0086a4188016a280200212d02400240200128029c05220020012802a005220d6b4104490d0020012802980521000c010b200d41046a222e200d490d202000410174220d202e202e200d491b220d4100480d200240024020000d00200d103221000c010b2001280298052000200d103421000b2000450d102001200d36029c05200120003602980520012802a005210d0b2001200d41046a3602a0052000200d6a202d3600000b20012802a0052100200128029c05212d200128029805210d20012802e403450d1320012802e00310290c130b2001200141e0036a3602f803202e200141f8036a200010820120012802e403210020012802e803210d024020012d00e0084113470d00024002402000200d460d0020012802e00321000c010b200d41016a2200200d490d1f200d410174222d20002000202d491b222d4100480d1f02400240200d0d00202d103221000c010b20012802e003200d202d103421000b2000450d102001202d3602e403200120003602e00320012802e803210d0b2001200d41016a3602e8032000200d6a41003a00000c120b024002402000200d460d0020012802e00321000c010b200d41016a2200200d490d1e200d410174222d20002000202d491b222d4100480d1e02400240200d0d00202d103221000c010b20012802e003200d202d103421000b2000450d102001202d3602e403200120003602e00320012802e803210d0b2001200d41016a3602e8032000200d6a41013a0000200141e0086a200141e0036a105f200141e0086a4188016a280200212d0240024020012802e403220020012802e803220d6b4104490d0020012802e00321000c010b200d41046a222e200d490d1e2000410174220d202e202e200d491b220d4100480d1e0240024020000d00200d103221000c010b20012802e0032000200d103421000b2000450d112001200d3602e403200120003602e00320012802e803210d0b2001200d41046a3602e8032000200d6a202d3600000c110b20012802e403450d1220012802e00310290c120b41174101102e000b412e4101102e000b202d4101102e000b202d4101102e000b200d4101102e000b202f4101102e000b200d202d1030000b202d202e108f01000b2000202e1030000b200141c8076a41146a4102360200200141d4076a4103360200200141b0066a41146a4103360200200142033702b406200141acf9c5003602b006200141033602cc072001200141b40c6a3602bc0c2001200141b80c6a3602f0032001420437038804200142013702fc0320014180fac5003602f8032001200141c8076a3602c0062001200141f8036a3602d8072001200141f0036a3602d0072001200141bc0c6a3602c807200141b0066a41bcfac500107d000b202d4101102e000b202d4101102e000b200d4101102e000b202d4101102e000b202d4101102e000b200d4101102e000b20012802e803210020012802e403212d20012802e003210d0b200d450d0020094200370300200a4200370300200b4200370300200142003703c8072008411b200141c8076a1000200e20092903003703002030200a290300370300200c200b290300370300200120012903c8073703f803200141f8036a4120200d200010050240202d450d00200d10290b200810290c010b2008102941900110322208450d014113210d024020012d00e0084113460d00200141f8036a200141e0086a106e2001200141e0086a4188016a2802003602800520012d00f803210d200141c8076a2015418f01109b051a0b2008200d3a0000200841016a200141c8076a418f01109b051a41171032220d450d02200d410f6a200f370000200d41086a201f370000200d2020370000200d4117412e1034220d450d03200d202b36001720094200370300200a4200370300200b4200370300200142003703c807200d411b200141c8076a1000200e20092903003703002030200a290300370300200c200b290300370300200120012903c8073703f803200141c8076a20084101108801200141f8036a412020012802c807220920012802d0071005024020012802cc07450d00200910290b200d1029024020082d00004113460d002008102a0b200810290b024020012d00e0084113460d00200141e0086a102a0b20074200370300200142003703e00841e6abc5004113200141e0086a1003200c2007290300370300200120012903e0083703f8032001200241016a3602e008200141f8036a4110200141e0086a410410050c040b4190014108102e000b41174101102e000b412e4101102e000b200141f8036a200141f8096a418801109b051a200141003b01e008200141106a200141f8036a200141e0086a10ee0220012001280210453a008104200141073a008004200141053a00f803200120023602840441014100200141f8036a104c20074200370300200142003703e00841e6abc5004113200141e0086a1003200c2007290300370300200120012903e0083703f8032001200241016a3602e008200141f8036a4110200141e0086a410410050b20132014470d000b201421130c010b102f000b024020132014460d00200141800a6a2107200141f8096a4199016a21080340200141f8096a2013419801109b051a20134198016a2d0000210620012013419c016a2800003600fb03200120134199016a2800003602f80320064103460d01200141980b6a200141f8096a419801109b051a200120012800fb033600e308200120012802f8033602e008200141f8096a200141980b6a419801109b051a200820012802e008360000200841036a20012800e308360000200120063a00900b2007102a201341a0016a22132014470d000b0b02402012450d00201110290b024002400240411710322206450d002006410f6a41002900d98740370000200641086a41002900d28740370000200641002900ca874037000020064117412e10342206450d0120062010360017200141c8076a41186a22084200370300200141c8076a41106a22074200370300200141c8076a41086a22024200370300200142003703c8072006411b200141c8076a1000200141f8036a41186a2008290300370300200141f8036a41106a2007290300370300200141f8036a41086a2002290300370300200120012903c8073703f803200141f8096a200141f8036a108701024020012802f809220b450d00200141f8036a412010040b200141f8096a41086a280200210820012802fc09210d20061029200b4108200b1b220c20084100200b1b4190016c22086a2102200c210602402008450d00200841f07e6a2107200141f8096a410172210a200c21060240034020062d00002108200141980b6a200641016a418701109b051a20084114460d01200141f8096a200141980b6a418701109b051a02400240024020084113470d0020070d01200221060c050b20064188016a2800002109200141f8036a200141f8096a418701109b051a200120083a00f809200a200141f8036a418701109b051a200141003b01980b200141086a200141f8096a200141980b6a10ee0220012802082108200120093602840a20012008453a00810a200141073a00800a200141053a00f80941014100200141f8096a104c2007450d010b20064190016a2106200741f07e6a21070c010b0b200221060c010b20064190016a21060b20062002460d02200141f8096a4101722107034020062d00002108200141f8096a200641016a418f01109b051a20084114460d03200141980b6a200141f8096a418f01109b051a200120083a00f8092007200141980b6a418f01109b051a024020084113460d00200141f8096a102a0b20064190016a22062002470d000c030b0b41174101102e000b412e4101102e000b0240200b450d00200d450d00200c10290b201010870202402003450d00200341246c21082005210603400240024020062d0000220741034b0d0002400240024020070e0404000102040b2006410c6a280200450d03200641086a28020010290c030b2006410c6a280200450d02200641086a28020010290c020b2006410c6a280200450d01200641086a28020010290c010b200641086a280200450d00200641046a28020010290b200641246a21062008415c6a22080d000b0b02402004450d00200510290b200141c00c6a24000f0b1033000b160020002001280208360204200020012802003602000bc91405027f017e067f017e037f230041b0086b22042400200441b0056a200141a002109b051a200441d0036a200441b0056a10a9024101210502400240024002400240024002400240024020042802d0034101460d00200441d0036a41086a290300210620044180026a200441d0036a41106a41d001109b051a20042006370328200441286a41086a20044180026a41d001109b051a024020032802002201450d00200341086a28020021072003280204210841002109200441003602b00541caf9c2004110200441b0056a10062105024020042802b005220a417f460d002005450d00200a4104490d0520052800002109200510290b200441d0036a200910a40320042802d803210920042802d0032105200441f0076a41186a220a4200370300200441f0076a41106a220b4200370300200441f0076a41086a220c4200370300200442003703f00720052009200441f0076a1000200441b0056a41186a200a290300370300200441b0056a41106a200b290300370300200441b0056a41086a200c290300370300200420042903f0073703b00520044120360284022004200441b0056a360280022001200720044180026a10f302024020042802d403450d00200510290b410021052008450d00200110290b200441206a200441286a41d0006a10ed022004280220210820042d0024210a200441b0056a200441286a41d801109b051a41002109024002400240024002400240024002400240024020042903d0054202510d0020044180026a41186a200441b0056a41186a29030037030020044180026a41106a200441b0056a41106a29030037030020044180026a41086a200441b0056a41086a290300370300200420042903b00537038002200441f8056a2903002106200441f0056a290300210d200441e8056a2802002107411310322209450d0e2009410029009884433700002009410f6a41002800a78443360000200941086a41002900a0844337000020044293808080b0023702d403200420093602d00320044180026a200441d0036a10810120042802d403210b200441186a20042802d003220c20042802d803108403200428021c410020042802181b21090240200b450d00200c10290b20092007470d04411310322209450d0f200a410171210a2009410029009884433700002009410f6a41002800a78443360000200941086a41002900a0844337000020044293808080b0023702d403200420093602d00320044180026a200441d0036a10810120042802d403210b20042802d803210c20042802d0032109200441f0076a41186a220e4200370300200441f0076a41106a220f4200370300200441f0076a41086a22104200370300200442003703f0072009200c200441f0076a1000200441d0036a41186a200e290300370300200441d0036a41106a200f290300370300200441d0036a41086a2010290300370300200420042903f0073703d0032004200741016a3602f007200441d0036a4120200441f0076a410410050240200b450d00200910290b200441106a41e1f6c5004117105d417f2004280214410020042802101b220920026a220720072009491b2209418080c002418080f001200a1b4b0d02200441d0036a41086a22074200370300200442003703d00341e1f6c5004117200441d0036a1003200441f0076a41086a220e2007290300370300200420042903d0033703f007200420093602d003200441f0076a4110200441d0036a41041005200441086a41c7f6c500411a105d417f200428020c410020042802081b220b418094ebdc034180afd0e502200a1b2209200820092008491b6a220c200c200b491b220b20094b0d0220074200370300200442003703d00341c7f6c500411a200441d0036a1003200e2007290300370300200420042903d0033703f0072004200b3602d003200441f0076a4110200441d0036a41041005200441d0036a200d200620044180026a2008200a200210b20120042d00d0034101460d01200441fc036a2802002107200441f8036a280200210b200441f4036a2802002108200441ec036a280200210c200441e8036a280200210a0240200441f0036a2802002209450d002009410c6c2102200a210903400240200941046a280200450d00200928020010290b2009410c6a2109200241746a22020d000b0b0240200c450d00200a10290b02402007450d002007410c6c21022008210903400240200941046a280200450d00200928020010290b2009410c6a2109200241746a22020d000b0b0240200b450d00200810290b20044190086a41086a20044180026a41086a29030037030020044190086a41106a20044180026a41106a29030037030020044190086a41186a20044180026a41186a290300370300200420042903800237039008410121090b200441d0076a41186a220a20044190086a41186a2202290300370300200441d0076a41106a220b20044190086a41106a2207290300370300200441d0076a41086a220c20044190086a41086a220829030037030020042004290390083703d007200441d0036a200441b0056a41d0006a418801109b051a2002200a2903003703002007200b2903003703002008200c290300370300200420042903d007370390084102210a02402009450d00200441f0076a41186a2002290300370300200441f0076a41106a2007290300370300200441f0076a41086a200829030037030020042004290390083703f0074101210a0b2004418a026a200441f0076a41086a29030037010020044192026a200441f0076a41106a2903003701002004419a026a200441f0076a41186a2903003701002004200a3a008102200420042903f00737018202200441003a0080022004200441d0036a20044180026a10ee02200428020421022004200428020022094100473a00b105200441003a00b0054101210841014100200441b0056a104c200441003602b00541caf9c2004110200441b0056a10062107024020042802b005220a417f460d002007450d00200a4104490d102007280000210820071029200841016a21080b200420083602b00541caf9c2004110200441b0056a4104100520090d074100210920004100360204200041086a20023602000c080b20042d00d103210220044180066a102a41032109024020020e0706020606040500060b410021090c050b20044180066a102a0b410421090c030b20044180066a102a200920074d0d010b410121090c010b410221090b20002009360204200041013602002000410c6a4100360200200041086a41e480c60036020020054521000c030b02402002411b470d0002402009418897c500460d002009418897c500411b109d050d010b20004104360204410121090c010b20002009360204200041086a2002360200410021090b200020093602002005450d0820010d020c080b200041086a20042902d4033702002000420137020020032802002101410021000b20000d0620010d050c060b200341046a280200450d05200110290c050b41f7cdc3004133200441b0056a41ecd6c3001054000b41134101102e000b41134101102e000b41f7cdc3004133200441b0056a41ecd6c3001054000b200341046a280200450d00200110290b200441b0086a24000b7301017f02400240411410322202450d00200241106a41002800a3f745360000200241086a410029009bf74537000020024100290093f74537000020024114412810342202450d01200042a8808080800337020420002002360200200220013600140f0b41144101102e000b41284101102e000b130020004101360204200041c8b2c3003602000b3400200041a7b6c30036020420004100360200200041146a4102360200200041106a41b0b6c300360200200041086a42093702000b130020004101360204200041fcb8c3003602000b3101017f02404108103222020d0041084101102e000b20004288808080800137020420002002360200200242dc0b3700000b130020004104360204200041a0bcc3003602000b340020004181c3c30036020420004100360200200041146a4101360200200041106a4194c3c300360200200041086a42133702000b13002000410236020420004198c6c3003602000b3400200041e5cac30036020420004100360200200041146a4101360200200041106a41eccac300360200200041086a42043702000bcf0101017f024002400240024002400240410110322202450d00200241003a000020024101410210342202450d01200241003a000120024102410410342202450d02200241003b000220024104410810342202450d032002410036000420024108411010342202450d042002420037000820024110412010342202450d052002420037001820024200370010200042a08080808004370204200020023602000f0b41014101102e000b41024101102e000b41044101102e000b41084101102e000b41104101102e000b41204101102e000b3400200041ddd8c30036020420004100360200200041146a4102360200200041106a41e4d8c300360200200041086a42073702000be90201067f230041c0006b220224000240411a10322203450d00200341002900f5dc43370000200341186a41002f008ddd433b0000200341106a4100290085dd43370000200341086a41002900fddc433700002002429a808080a003370224200220033602202002200241206a36020020012002108501200228022421042002280220210320022802282105200241206a41186a22014200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020032005200241206a1000200241186a2001290300370300200241106a2006290300370300200241086a200729030037030020022002290320370300200241206a200210b1030240024020022802280d00200041003602080c010b20002002290320370200200041186a2001290300370200200041106a2006290300370200200041086a20072903003702000b02402004450d00200310290b200241c0006a24000f0b411a4101102e000bc60201067f230041106b22022400200241003602082002420137030020012802002103024002400240410410322204450d0020024284808080c0003702042002200436020020042003360000200128020421050240024020022802042206200228020822046b4104490d00200441046a2103200228020021060c010b200441046a22032004490d0320064101742207200320032007491b22074100480d030240024020060d002007103221060c010b200228020020062007103421060b2006450d0220022007360204200220063602000b20022003360208200620046a20053600002001280208200141106a280200200210940120012802142001411c6a28020020021094012002280204210120004120200228020022042002280208100502402001450d00200410290b200241106a24000f0b41044101102e000b20074101102e000b1033000bd20203047f017e017f230041306b220224002002410036022020014120200241206a1006210102400240024020022802202203417f460d0020010d010b200041003602080c010b200220013602182002200336021c0240024020034104490d002002200141046a36021820022003417c6a220436021c20044104490d00200128000021042002200341786a36021c2002200141086a36021820012800042103200241206a200241186a103120022802202205450d0020022902242106200241206a200241186a103120022802200d012006a7450d00200510290b41f7cdc3004133200241206a41ecd6c3001054000b200241086a41086a2207200241206a41086a28020036020020022002290320370308200110292000200637020c200020053602082000200336020420002004360200200041146a20022903083702002000411c6a20072802003602000b200241306a24000be90201067f230041c0006b220224000240411a10322203450d00200341002900acdd43370000200341186a41002f00c4dd433b0000200341106a41002900bcdd43370000200341086a41002900b4dd433700002002429a808080a003370224200220033602202002200241206a36020020012002108501200228022421042002280220210320022802282105200241206a41186a22014200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020032005200241206a1000200241186a2001290300370300200241106a2006290300370300200241086a200729030037030020022002290320370300200241206a200210b1030240024020022802280d00200041003602080c010b20002002290320370200200041186a2001290300370200200041106a2006290300370200200041086a20072903003702000b02402004450d00200310290b200241c0006a24000f0b411a4101102e000bc70905037f027e057f017e037f230041d0016b22022400200241003602a80120014120200241a8016a1006210302400240024020022802a8012204417f470d00200041023a00100c010b2002200436021c200220033602182002200241186a1097012002290300a70d01200228021c2201450d01200241106a29030021052002290308210620022001417f6a220736021c20022002280218220841016a220936021820082d0000220141014b0d014100210a0240024020010e020100010b41002101200241003a00c8010340024020072001470d002002410036021c200141ff0171450d04200241003a00c8010c040b200241a8016a20016a200820016a220b41016a2d00003a00002002200b41026a3602182002200141016a220b3a00c801200b2101200b4120470d000b200241e8006a41086a200241a8016a41086a290300220c370300200241c8006a41186a200241a8016a41186a290300370300200241c8006a41106a200241a8016a41106a290300370300200241c8006a41086a200c37030020022007200b6b220736021c200220022903a801220c3703682002200c3703484101210a2008200b6a41016a21090b200241286a41186a200241c8006a41186a290300370300200241286a41106a200241c8006a41106a290300370300200241286a41086a200241c8006a41086a290300370300200220022903483703282007450d0120022007417f6a220736021c2002200941016a36021820092d0000220b41014b0d014100210102400240200b0e020100010b41002101200241003a00c8010340024020072001470d002002410036021c200141ff0171450d04200241003a00c8010c040b200241a8016a20016a200920016a220b41016a2d00003a00002002200b41026a3602182002200141016a220b3a00c801200b2101200b4120470d000b200241e8006a41086a200241a8016a41086a290300220c370300200241c8006a41186a200241a8016a41186a290300370300200241c8006a41106a200241a8016a41106a290300370300200241c8006a41086a200c37030020022007200b6b36021c200220022903a801220c3703682002200c370348410121010b20024188016a41186a220b200241c8006a41186a29030037030020024188016a41106a2207200241c8006a41106a29030037030020024188016a41086a2209200241c8006a41086a290300370300200241a8016a41086a2208200241286a41086a290300370300200241a8016a41106a220d200241286a41106a290300370300200241a8016a41186a220e200241286a41186a2903003703002002200229034837038801200220022903283703a801200241e8006a41046a220f200241226a41046a2f01003b010020022002280122360268200a4102460d01200020063703002000200a3a0010200020022903a80137001120002005370308200041316a20013a0000200041326a200229038801370000200041196a2008290300370000200041216a200d290300370000200041296a200e2903003700002000413a6a2009290300370000200041c2006a2007290300370000200041ca006a200b290300370000200041d6006a200f2f01003b0100200041d2006a20022802683601002004450d00200310290b200241d0016a24000f0b41f7cdc3004133200241c8006a41ecd6c3001054000bc40101037f230041206b220224002002410036021020014110200241106a10062101024002400240024020022802102203417f460d0020010d010b200041003602040c010b200220013602082002200336020c20034104490d0120022003417c6a36020c2002200141046a36020820012800002103200241106a200241086a103c20022802102204450d01200020022902143702082000200436020420002003360200200110290b200241206a24000f0b41f7cdc3004133200241106a41ecd6c3001054000b9609030b7f017e027f230041c0016b2202240020024100360298012001412020024198016a1006210302400240024002402002280298012204417f470d00200041023a000c0c010b2002200436020420022003360200200241086a2002103120022802082205450d02200228020c210620022802042201450d01200241106a280200210720022001417f6a220836020420022002280200220941016a220a36020020092d0000220141014b0d014100210b0240024020010e020100010b41002101200241003a00b8010340024020082001470d0020024100360204200141ff0171450d04200241003a00b8010c040b20024198016a20016a200920016a220c41016a2d00003a00002002200c41026a3602002002200141016a220c3a00b801200c2101200c4120470d000b200241d8006a41086a20024198016a41086a290300220d370300200241386a41186a20024198016a41186a290300370300200241386a41106a20024198016a41106a290300370300200241386a41086a200d37030020022008200c6b22083602042002200229039801220d3703582002200d3703384101210b2009200c6a41016a210a0b200241186a41186a200241386a41186a290300370300200241186a41106a200241386a41106a290300370300200241186a41086a200241386a41086a290300370300200220022903383703182008450d0120022008417f6a22083602042002200a41016a360200200a2d0000220c41014b0d014100210102400240200c0e020100010b41002101200241003a00b8010340024020082001470d0020024100360204200141ff0171450d04200241003a00b8010c040b20024198016a20016a200a20016a220c41016a2d00003a00002002200c41026a3602002002200141016a220c3a00b801200c2101200c4120470d000b200241d8006a41086a20024198016a41086a290300220d370300200241386a41186a20024198016a41186a290300370300200241386a41106a20024198016a41106a290300370300200241386a41086a200d37030020022008200c6b3602042002200229039801220d3703582002200d370338410121010b200241f8006a41186a220c200241386a41186a290300370300200241f8006a41106a2208200241386a41106a290300370300200241f8006a41086a220a200241386a41086a29030037030020024198016a41086a2209200241186a41086a29030037030020024198016a41106a220e200241186a41106a29030037030020024198016a41186a220f200241186a41186a290300370300200220022903383703782002200229031837039801200b4102460d022000200b3a000c200020073602082000200636020420002005360200200020022903980137000d2000412d6a20013a00002000412e6a2002290378370000200041156a20092903003700002000411d6a200e290300370000200041256a200f290300370000200041366a200a2903003700002000413e6a2008290300370000200041c6006a200c290300370000200041ce006a20022f01583b01002004450d00200310290b200241c0016a24000f0b2006450d00200510290b41f7cdc3004133200241386a41ecd6c3001054000bcd0708047f047e067f027e017f017e017f017e230041b0016b2202240020024100360288012001412020024188016a10062103024002400240024002400240024002402002280288012204417f460d0020030d010b200041003602200c010b200220043602642002200336026041002101200241003a00a8010340024020042001470d0020024100360264200141ff0171450d07200241003a00a8010c070b20024188016a20016a200320016a22052d00003a00002002200541016a3602602002200141016a22053a00a8012005210120054120470d000b200241e8006a41086a20024188016a41086a290300370300200241e8006a41106a20024188016a41106a290300370300200241e8006a41186a20024188016a41186a29030037030020022002290388013703682002200420056b360264200241c8006a200241e0006a1097012002290348a70d05200241c8006a41106a290300210620022903502107200241306a200241e0006a1097012002290330a70d05200241306a41106a290300210820022903382109200241286a200241e0006a102c20022802280d05200228026441186e220a41186c2201417f4c0d01200228022c210b0240024020010d004108210c0c010b20011032220c450d030b0240200b450d00200241106a41106a210d4100210e4100210f410021050340200241106a200241e0006a109701024002402002290310a70d00200d290300211020022903182111200241086a200241e0006a102c2002280208450d010b200a450d08200c10290c080b200541016a2101200228020c211202402005200a470d00200e20012001200e491b220aad42187e2213422088a70d072013a722144100480d070240024020050d0020141032210c0c010b200c200f20141034210c0b200c450d060b200c200f6a2205201037030820052011370300200541106a2012360200200e41026a210e200f41186a210f20012105200b2001470d000b0b200c450d0520024188016a41186a200241e8006a41186a290300221037030020024188016a41106a200241e8006a41106a290300221137030020024188016a41086a200241e8006a41086a290300221337030020022002290368221537038801200041186a20083703002000200937031020002006370308200020073703002000200bad422086200aad843702242000200c3602202000412c6a2015370200200041346a20133702002000413c6a2011370200200041c4006a20103702002004450d00200310290b200241b0016a24000f0b102f000b20014108102e000b20144108102e000b1033000b41f7cdc3004133200241e8006a41ecd6c3001054000b8b0201047f230041c0006b2202240002400240410f10322203450d00200341076a41002900c6d643370000200341002900bfd6433700002003410f411e10342203450d012003200036000f200241206a41186a22004200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032020034113200241206a1000200241186a2000290300370300200241106a2004290300370300200241086a2005290300370300200220022903203703002002412036022420022002360220200128020022002001280208200241206a109501200310290240200141046a280200450d00200010290b200241c0006a24000f0b410f4101102e000b411e4101102e000b130020004104360204200041dcddc3003602000b3400200041f6e5c30036020420004100360200200041146a4105360200200041106a418ce6c300360200200041086a42133702000b3400200041c0ecc30036020420004100360200200041146a4105360200200041106a41d4ecc300360200200041086a42133702000b9e2207017f027e077f017e017f017e107f230041d0066b22032400200241d8006a2903002104200241d0006a290300210520022802002106200341c4006a200241046a41cc00109b051a20034190016a200341c4006a41046a41c800109b051a2001280200210720034190036a41186a2208200341c8016a29030037030020034190036a41106a2209200341c0016a29030037030020034190036a41086a220a200341b8016a290300370300200320032903b00137039003024002400240024041c80010322202450d002002420037030020022006360220200241186a4200370300200241106a4200370300200241086a42003703002002200341b0016a220b2902003702242002412c6a200b41086a290200370200200241346a200b41106a2902003702002002413c6a200b41186a290200370200200341286a41c2d5c000411610a301200341186a2003290330200341286a41106a290300427f420010a105200341086a20052004200329031842002003280228220c1b220d4201200d420156200341186a41086a2903004200200c1b220d420052200d501b220c1b200d4200200c1b10a105200341e0026a41086a200a290300370300200341e0026a41106a2009290300370300200341e0026a41186a200829030037030020032003290390033703e0022003290308210d02400240024020072802082208200741046a280200470d00200841016a22092008490d012008410174220a20092009200a491b2209ad42d0007e2204422088a70d012004a7220a4100480d010240024020080d00200a103221080c010b2007280200200841d0006c200a103421080b2008450d0220072008360200200741046a2009360200200728020821080b2007280200200841d0006c6a22084200370310200842003703082008200d37030020082002360220200820032903e00237022c200841186a4200370300200841246a428180808010370200200841346a200341e0026a41086a22022903003702002008413c6a200341e0026a41106a220a290300370200200841c4006a200341e0026a41186a22082903003702002007200728020841016a3602082001280208210c200341a0026a41186a200b41186a290000370300200341a0026a41106a200b41106a290000370300200341a0026a41086a200b41086a2900003703002003200b2900003703a002024002400240200c280200220141b0d6c000460d00200c28020421090c010b4100210920034190036a410041e002109a051a20034188036a220b410036020020034180036a2207420037030020084200370300200a420037030020024200370300200342003703e00241940310322201450d01200141003b010620014100360200200141086a20034190036a41e002109b051a20014190036a200b28020036020020014188036a200729030037020020014180036a200341f8026a290300370200200141f8026a200341f0026a290300370200200141f0026a200341e0026a41086a290300370200200120032903e0023702e802200c4100360204200c20013602000b02400340200141086a2108200141066a210e20012f0106220a41057421024100210b0240024003402002450d01200341a0026a20084120109d052207450d02200241606a2102200b41016a210b200841206a21082007417f4a0d000b200b417f6a210a0b2009450d022009417f6a21092001200a4102746a4194036a28020021010c010b0b2001200b4102746a41e8026a20063602000c060b200341d8016a41186a200341a0026a41186a2202290300220d370300200341d8016a41106a200341a0026a41106a22082903002204370300200341d8016a41086a200341a0026a41086a220b2903002205370300200320032903a002220f3703d801200c200c28020841016a3602082002200d37030020082004370300200b20053703002003200f3703a0020240024002400240200e2f01002209410b490d0020034190036a410041e002109a051a20034188036a2202410036020020034180036a22084200370300200341e0026a41186a4200370300200341e0026a41106a4200370300200341e0026a41086a4200370300200342003703e00241940310322210450d03201041003b010620104100360200201041086a20034190036a41e002109b05210b20104190036a200228020036020020104188036a200829030037020020104180036a200341e0026a41186a290300370200201041f8026a200341e0026a41106a290300370200201041f0026a200341e0026a41086a290300370200201020032903e0023702e802200320012f00c8013b01dc022003200141ca016a2d00003a00de02200141cb016a2800002111200141cf016a2800002112200141d3016a2800002113200141d7016a28000021142003200141e0016a2900003700cd02200320012900db013703c8022001280280032115200b200141e8016a20012f010641796a2202410574109b05210b201041e8026a20014184036a2002410274109b052107200141063b0106201020023b0106200320032f01dc023b01c402200320032d00de023a00c602200320032903c8023703e002200320032900cd023700e502200a4107490d01201041066a210e200b200a417a6a22094105746a200b200a41796a22084105746a220b200241ffff037120086b410574109c051a200b41186a200341a0026a41186a290300370000200b41106a200341a0026a41106a290300370000200b41086a200341a0026a41086a290300370000200b20032903a002370000200720094102746a210b200720084102746a21020c020b200141086a2207200a41016a220c4105746a2007200a4105746a22072009200a6b410574109c051a200741186a2002290300370000200741106a2008290300370000200741086a200b290300370000200720032903a002370000200141e8026a2202200c4102746a2002200a4102746a220220012f0106200a6b410274109c051a20022006360200200120012f010641016a3b01060c080b200141086a2202200a41016a22084105746a2002200a4105746a2202200e2f0100200a6b410574109c051a200241186a200341a0026a41186a290300370000200241106a200341a0026a41106a290300370000200241086a200341a0026a41086a290300370000200220032903a002370000200141e8026a220b200a4102746a2102200b20084102746a210b200a21080b200b2002200e2f010020086b410274109c051a20022006360200200e200e2f010041016a3b0100200341c0026a41026a221620032d00c60222023a00002003418c026a41026a221720023a0000200320032900e50237009502200320032903e00237039002200320032f01c40222023b01c00220032003290095023700fd0120032003290390023703f801200320023b018c0220012802002209450d0520012f0104210e20034190036a41027221180340201620172d00003a0000200320032f018c023b01c002200320032903f8013703a002200320032900fd013700a502200e41ffff037121010240024002400240024020092f01062202410b490d002018410041be03109a051a41c40310322207450d0320074100360200200741046a20034190036a41c003109b051a200320092f00c8013b01dc022003200941ca016a2d00003a00de022003200941db016a2900003703c8022003200941e0016a2900003700cd02200941cb016a2800002119200941cf016a280000211a200941d3016a280000211b200941d7016a280000211c20094180036a280200211d200741086a200941e8016a20092f0106220841796a2202410574109b05211e200741e8026a20094184036a2002410274109b05211f20074194036a200941b0036a2008417a6a220a410274109b052106200941063b0106200720023b01060240200a450d00410021022006210803402008280200220b20023b0104200b2007360200200841046a2108200a200241016a2202470d000b0b200320032d00de0222023a00c602200320032f01dc0222083b01c402200320032903c8023703e002200320032900cd023700e50220034190026a41026a220a20023a0000200320083b019002200320032903e00237039003200320032900e50237009503200e41ffff037122084107490d01201e2001417a6a220b4105746a201e200141796a22024105746a220820072f010620026b410574109c051a200841186a20032900a5023700002008201436000f2008201336000b2008201236000720082011360003200841026a20162d00003a0000200820032f01c0023b0000200820032903a002370013201f200b41027422086a201f20024102746a220e20072f0106221120026b410274109c051a200e20153602002007201141016a220e3b01062001410274221120066a416c6a200620086a2208200e41ffff03712201200b6b410274109c051a200820103602002001200b490d02200720116a41fc026a210803402008280200220b200241016a22023b0104200b2007360200200841046a210820022001490d000c030b0b200941086a2208200141016a220b4105746a200820014105746a2208200220016b410574109c051a200841186a20032900a5023700002008201436000f2008201336000b2008201236000720082011360003200841026a200341c0026a41026a2d00003a0000200820032f01c0023b0000200820032903a002370013200941e8026a2202200b41027422086a2002200141027422076a220220092f0106220a20016b410274109c051a200220153602002009200a41016a22023b0106200720094194036a22016a41086a200120086a2208200241ffff03712207200b6b410274109c051a20082010360200200e41ffff037120074f0d0b2009200b417f6a22024102746a4198036a210803402008280200220b200241016a22023b0104200b2009360200200841046a210820022007490d000c0c0b0b200941086a2202200141016a220e4105746a200220014105746a220220092f010620016b410574109c051a200241186a20032900a5023700002002201436000f2002201336000b2002201236000720022011360003200241026a20162d00003a0000200220032f01c0023b0000200220032903a002370013200941e8026a220b200e41027422066a200b200141027422026a220b20092f0106221120016b410274109c051a200b20153602002009201141016a220b3b0106200220094194036a22116a41086a201120066a2206200b41ffff0371220b200e6b410274109c051a200620103602002008200b4f0d00200920026a4198036a2102034020022802002208200141016a22013b010420082009360200200241046a2102200b2001470d000b0b2017200a2d00003a0000200320032f0190023b018c0220032003290390033703f80120032003290095033700fd01200928020022020d0120192111201c2114201b2113201a211220072110201d21150c080b41c4034104102e000b20092f0104210e20192111201c2114201b2113201a211220022109201d2115200721100c000b0b4194034104102e000b4194034104102e000b1033000b200a4108102e000b41c8004108102e000b20034190036a410272410041be03109a051a41c40310322202450d0120024100360200200241046a20034190036a41c003109b051a2002200c280200220836029403200c2002360200200c200c28020441016a360204200841003b010420082002360200200220022f0106220b4105746a220841086a20032f018c023b00002008410a6a2003418c026a41026a2d00003a0000200841176a2014360000200841136a20133600002008410f6a20123600002008410b6a20113600002008411b6a20032903f801370000200841206a20032900fd0137000020024194036a200b41016a22084102746a20103602002002200b4102746a41e8026a2015360200200220083b0106201020083b0104201020023602000b200020034190016a41c800109b051a200341d0066a24000f0b41c4034104102e000bdb1a04027f017e067f017e230041e0016b22012400024002400240024002400240024041880110322202450d000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200028020022002d00000e1514000102030405060708090a0b0c0d0e0f10111213140b20002d00012100200241013a000020024102200041004720004102461b3a00010c140b200041086a2903002103200241023a0000200220033703080c130b200141e0006a200041046a1037200241033a00002002410c6a200141e8006a280200360200200220012903603702040c120b106f000b200141e0006a200041086a1070200241086a200141e0006a41e000109b051a200241053a00000c100b200141e0006a200041086a1071200241063a0000200241386a200141e0006a41306a290300370300200241306a200141e0006a41286a290300370300200241286a200141e0006a41206a290300370300200241206a200141e0006a41186a290300370300200241186a200141e0006a41106a290300370300200241106a200141e0006a41086a290300370300200220012903603703080c0f0b200141e0006a41186a200041286a290000370300200141e0006a41106a200041206a290000370300200141e8006a200041186a290000370300200141e0006a41286a200041386a290000370300200141e0006a41306a200041c0006a290000370300200141e0006a41386a200041c8006a290000370300200141e0006a41c8006a200041d8006a290000370300200141e0006a41d0006a200041e0006a290000370300200141e0006a41d8006a200041e8006a2900003703002001200041106a2900003703602001200041306a290000370380012001200041d0006a2900003703a0012000410c6a2802002204417f4c0d10200041046a28020021000240024020040d0041002105410121060c010b20042105200410322206450d120b200620002004109b0521002001200141e0006a41e000109b0521062002200436020c2002200536020820022000360204200241106a200641e000109b051a200241073a00000c0e0b200141e0006a200041086a106c200241083a0000200241306a200141e0006a41286a290300370300200241286a200141e0006a41206a290300370300200241206a200141e0006a41186a290300370300200241186a200141e0006a41106a290300370300200241106a200141e0006a41086a290300370300200220012903603703080c0d0b024002400240024002400240200041046a2d0000417f6a220441034b0d0020040e0401020304010b41d8d7c300106d000b200041106a280200220641ffffff3f712006470d1220064105742205417f4c0d12200041086a2802002100410121044101210702402005450d00200510322207450d150b024020060d0041002105410021060c040b2006410574210520072104034020042000290000370000200441186a200041186a290000370000200441106a200041106a290000370000200441086a200041086a290000370000200441206a2104200041206a2100200541606a22050d000b41012104200641057441606a41057641016a21050c030b200041086a10bc032107410221040c020b200041086a28020021072000410c6a10bc032106410321040c010b200141026a200041076a2d00003a0000200141e0006a41086a2000411c6a290000370300200141e0006a41106a200041246a2d00003a00002001200041056a2f00003b01002001200041146a290000370360200041256a2d00004100472108200041286a2802002109200041106a28000021052000410c6a2800002106200041086a2800002107410421040b200220043a0004200220012f01003b0005200220053602102002200636020c200220073602082002200129036037021420022009360228200220083a0025200241093a0000200241076a200141026a2d00003a00002002411c6a200141e8006a290300370200200241246a200141f0006a2d00003a00000c0c0b024002400240024002400240200041046a2d0000417f6a220441034b0d0020040e0401020304010b41d8d7c300106d000b200041106a280200220641ffffff3f712006470d1120064105742205417f4c0d11200041086a2802002100410121044101210702402005450d00200510322207450d150b024020060d0041002105410021060c040b2006410574210520072104034020042000290000370000200441186a200041186a290000370000200441106a200041106a290000370000200441086a200041086a290000370000200441206a2104200041206a2100200541606a22050d000b41012104200641057441606a41057641016a21050c030b200041086a10bc032107410221040c020b200041086a28020021072000410c6a10bc032106410321040c010b200141026a200041076a2d00003a0000200141e0006a41086a2000411c6a290000370300200141e0006a41106a200041246a2d00003a00002001200041056a2f00003b01002001200041146a290000370360200041256a2d00004100472108200041286a2802002109200041106a28000021052000410c6a2800002106200041086a2800002107410421040b200220043a0004200220012f01003b0005200220053602102002200636020c200220073602082002200129036037021420022009360228200220083a00252002410a3a0000200241076a200141026a2d00003a00002002411c6a200141e8006a290300370200200241246a200141f0006a2d00003a00000c0b0b200141e0006a200041086a10732002410b3a0000200241c0006a200141e0006a41386a290300370300200241386a200141e0006a41306a290300370300200241306a200141e0006a41286a290300370300200241286a200141e0006a41206a290300370300200241206a200141e0006a41186a290300370300200241186a200141e0006a41106a290300370300200241106a200141e0006a41086a290300370300200220012903603703080c0a0b200141e0006a200041046a1074200241046a200141e0006a41c400109b051a2002410c3a00000c090b200041046a28020021002002410d3a0000200220003602040c080b2000410c6a2802002204417f4c0d09200041046a28020021000240024020040d0041012105410021060c010b20042106200410322205450d0e0b200520002004109b0521002002200436020c20022006360208200220003602042002410e3a00000c070b024002400240024002400240200041086a280200417f6a220441024b0d0020040e03010203010b4198bdc100106d000b200041386a2903002103200041306a290300210a41012104024002402000410c6a2d00004101460d00200141e8006a2000411c6a290200370300200141e0006a41106a200041246a290200370300200141f8006a2000412c6a2d00003a00002001200041146a2902003703602000410d6a2f00002000410f6a2d0000411074722105200041106a2802002100410021040c010b200041106a28020021000b200141186a200141e0006a41186a280200360200200141106a200141e0006a41106a290300370300200141086a200141e0006a41086a29030037030020012001290360370300410121060c030b2000410c6a28020022044108762105410221060c010b2000410c6a28020022044108762105410321060b0b2002200a3703302002200036021020022006360208200220012903003702142002410f3a0000200241386a200337030020022005410874200441ff01717236020c2002411c6a200141086a290300370200200241246a200141106a2903003702002002412c6a200141186a2802003602000c060b200141e0006a200041086a1075200241086a200141e0006a418001109b051a200241103a00000c050b0240024002400240200041046a280200417f6a220441014b0d0020040e020102010b41bc84c300106d000b41880110322204450d0d2004200041086a2802001076410121000c010b4101210402400240200041086a2d00004101460d00200141e0006a41086a200041186a290200370300200141e0006a41106a200041206a290200370300200141e0006a41186a200041286a2d00003a00002001200041106a290200370360200041096a2f00002000410b6a2d00004110747221062000410c6a2802002105410021040c010b2000410c6a28020021050b200141186a200141e0006a41186a280200360200200141106a200141e0006a41106a290300370300200141086a200141e0006a41086a2903003703002001200129036037030020042006410874722104410221000b2002200536020c200220043602082002200036020420022001290300370210200241113a0000200241186a200141086a290300370200200241206a200141106a290300370200200241286a200141186a2802003602000c040b200141e0006a200041046a1077200241046a200141e0006a41e400109b051a200241123a00000c030b1078000b1079000b200141e0006a200041086a107a200241003a0000200241106a200141e0006a41086a290300370300200220012903603703080b200141e0016a240020020f0b4188014108102e000b102f000b20044101102e000b20054101102e000b20054101102e000b20044101102e000b4188014108102e000b02000b130020004105360204200041a4fac3003602000b3400200041a8f6c30036020420004100360200200041146a4107360200200041106a41f08cc400360200200041086a42083702000b3701017f02404110103222020d0041104101102e000b2002420037000820024201370000200042908080808002370204200020023602000b2201017f230041106b22022400200241003602002000200210e701200241106a24000bc70101017f23004190016b22022400200241003a00782002428080848080023703682002420137035820024201370350200242af0137034820024287013703402002420137033820024201370330200242013703282002420137032020024201370318200242013703102002420137030820024280808080c00037036020024280808180800437037020024100360288012002420137038001200241086a20024180016a10cc02200041086a200228028801360200200020022903800137020020024190016a24000b130020004110360204200041cc96c4003602000b3301017f02404108103222020d0041084101102e000b2000428880808080013702042000200236020020024280ade2043700000b3201017f02404104103222020d0041044101102e000b20004284808080c000370204200020023602002002418080013600000b3101017f02404104103222020d0041044101102e000b20004284808080c0003702042000200236020020024180083600000b3101017f02404108103222020d0041084101102e000b20004288808080800137020420002002360200200242e8073700000b3c01017f02404110103222020d0041104101102e000b2002420037000820024280a094a58d1d370000200042908080808002370204200020023602000b3b01017f02404110103222020d0041104101102e000b2002420037000820024280c8afa025370000200042908080808002370204200020023602000b3801017f02404110103222020d0041104101102e000b200242003700082002429601370000200042908080808002370204200020023602000b3801017f02404110103222020d0041104101102e000b20024200370008200242e807370000200042908080808002370204200020023602000b3701017f02404110103222020d0041104101102e000b2002420037000820024204370000200042908080808002370204200020023602000b3001017f02404104103222020d0041044101102e000b20004284808080c00037020420002002360200200241083600000b3701017f02404110103222020d0041104101102e000b2002420037000820024210370000200042908080808002370204200020023602000b3001017f02404104103222020d0041044101102e000b20004284808080c00037020420002002360200200241023600000ba50a02067f027e230041106b2202240020002802102103200041186a2802002204200110660240024002400240024002400240024002400240200141046a2802002205200141086a28020022066b2004490d00200128020021050c010b200620046a22072006490d0820054101742206200720072006491b22064100480d080240024020050d002006103221050c010b200128020020052006103421050b2005450d0120012005360200200141046a2006360200200141086a28020021060b200141086a2207200620046a360200200520066a20032004109b051a200028021c210502400240200141046a2802002206200728020022046b4104490d00200128020021060c010b200441046a22032004490d0820064101742204200320032004491b22044100480d080240024020060d002004103221060c010b200128020020062004103421060b2006450d0220012006360200200141046a2004360200200141086a28020021040b200141086a2203200441046a360200200620046a20053600002002200136020c2000412c6a2002410c6a108501200041086a29030021082000290300210902400240200141046a2802002206200328020022046b4110490d00200128020021060c010b200441106a22052004490d0820064101742204200520052004491b22044100480d080240024020060d002004103221060c010b200128020020062004103421060b2006450d0320012006360200200141046a2004360200200141086a28020021040b200141086a2205200441106a360200200620046a22042008370008200420093700002000280220210302400240200141046a2802002206200528020022046b4104490d00200128020021060c010b200441046a22052004490d0820064101742204200520052004491b22044100480d080240024020060d002004103221060c010b200128020020062004103421060b2006450d0420012006360200200141046a2004360200200141086a28020021040b200141086a2205200441046a360200200620046a20033600000240024020002802244101460d0002400240200141046a28020020052802002200460d00200128020021040c010b200041016a22042000490d0a20004101742206200420042006491b22064100480d0a0240024020000d002006103221040c010b200128020020002006103421040b2004450d0720012004360200200141046a2006360200200141086a28020021000b200141086a200041016a360200200420006a41003a00000c010b02400240200141046a28020020052802002204460d00200128020021060c010b200441016a22062004490d0920044101742205200620062005491b22054100480d090240024020040d002005103221060c010b200128020020042005103421060b2006450d0720012006360200200141046a2005360200200141086a28020021040b200141086a2205200441016a360200200620046a41013a00002000280228210602400240200141046a2802002204200528020022006b4104490d00200128020021040c010b200041046a22052000490d0920044101742200200520052000491b22004100480d090240024020040d002000103221040c010b200128020020042000103421040b2004450d0820012004360200200141046a2000360200200141086a28020021000b200141086a200041046a360200200420006a20063600000b200241106a24000f0b20064101102e000b20044101102e000b20044101102e000b20044101102e000b20064101102e000b20054101102e000b20004101102e000b1033000bd66704167f017e087f017e23004180036b2204240041002105200441003602f002200420023602ec02200420013602e8020240024002400240024002400240200241034b0d0041012106200441013a00d002200441ec016a4101360200200442013702dc01200441d8e7c5003602d801200441213602b4022004200441b0026a3602e8012004200441d0026a3602b00220044180016a200441d8016a10af042004280280012107200428028401210820042802880121094105210a4100210b0c010b200441043602f002024020012800004180c2cdeb06460d004101210a410121060c010b024002402002417c714104460d00200241074b0d0141082002108f01000b41012106200441013a00d002200441ec016a4101360200200442013702dc01200441d8e7c5003602d801200441213602b4022004200441b0026a3602e8012004200441d0026a3602b00220044180016a200441d8016a10af042004280280012107200428028401210820042802880121094105210a410021054100210b0c010b200441083602f002410121060240200128000422074101460d004102210a0c010b200441d8016a200441e8026a10ba0402400240024020042802d8014101470d00410421084100210c410021090c010b200441d8016a410572210d410421084128210a410021054100210c410021094100210b02400340200441d0026a41026a2201200d41026a2d00003a00002004200d2f00003b01d002200428028402210e200428028002210f20042802fc01211020042802f801211120042802f401211220042802f001211320042802ec01211420042802e801211520042802e401211620042802e0012117024020042d00dc012206417e6a41ff0171410a4b0d004100211802400240024002400240024002400240024002400240024020060e0f0b0b000102030405060708090a0b0b0b0b410121180c0a0b410221180c090b410321180c080b410421180c070b410521180c060b410621180c050b410721180c040b410821180c030b410921180c020b410a21180c010b410b21180b0240200b41ff0171221920184d0d004113210a0c030b4100211802400240024002400240024002400240024002400240024020060e0f0b0b000102030405060708090a0b0b0b0b410121180c0a0b410221180c090b410321180c080b410421180c070b410521180c060b410621180c050b410721180c040b410821180c030b410921180c020b410a21180c010b410b21180b024020192018470d004114210a0c030b4100210b0240024002400240024002400240024002400240024020060e0f0b0b000102030405060708090a0b0b0b0b4101210b0c0a0b4102210b0c090b4103210b0c080b4104210b0c070b4105210b0c060b4106210b0c050b4107210b0c040b4108210b0c030b4109210b0c020b410a210b0c010b410b210b0b20044180016a41026a221820012d00003a0000200420042f01d0023b01800102400240200c2009470d00200c41016a2201200c490d072005200120012005491b2209ad422c7e221a422088a70d07201aa722014100480d0702400240200c0d002001103221080c010b2008200a41586a2001103421080b2008450d010b2008200a6a220141586a20063a00002001200e3602002001417c6a200f360200200141786a2010360200200141746a2011360200200141706a20123602002001416c6a2013360200200141686a2014360200200141646a2015360200200141606a20163602002001415c6a2017360200200141596a220120042f0180013b0000200141026a20182d00003a0000200541026a2105200a412c6a210a200c41016a210c200441d8016a200441e8026a10ba0420042802d8014101460d030c010b0b20014104102e000b024002402006410d4b0d00024002400240024002400240024002400240024002400240024020060e0e0001020304050607080e090a0b0c000b2016450d0d201710290c0d0b02402016450d00201710290b2013450d0c201410290c0c0b02402015450d00201541047421062017210103400240200141046a280200450d00200128020010290b200141106a2101200641706a22060d000b0b2016450d0b201710290c0b0b02402015450d00201541286c21062017210103400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141286a2101200641586a22060d000b0b2016450d0a201710290c0a0b2016450d09201710290c090b2016450d08201710290c080b2016450d07201710290c070b02402015450d00201720154104746a210d201721050340024020052802082206450d0020052802002101200641047421060340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200641706a22060d000b0b200541106a21010240200541046a280200450d00200528020010290b200121052001200d470d000b0b2016450d06201710290c060b02402015450d00201541146c21062017210103400240200141046a280200450d00200128020010290b200141146a21012006416c6a22060d000b0b2016450d05201710290c050b02402015450d0020172015411c6c6a210d20172105034002402005410c6a2802002206450d0020052802042101200641047421060340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200641706a22060d000b0b0240200541086a280200450d00200528020410290b2005411c6a21010240200541146a280200450d00200528021010290b200121052001200d470d000b0b2016450d04201710290c040b02402015450d002017201541186c6a210d2017210503400240200541046a280200450d00200528020010290b0240200541146a2802002206450d00200528020c2101200641047421060340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200641706a22060d000b0b200541186a21010240200541106a280200450d00200528020c10290b200121052001200d470d000b0b2016450d03201710290c030b02402015450d0020172015411c6c6a210d20172105034002402005410c6a2802002206450d0020052802042101200641047421060340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200641706a22060d000b0b0240200541086a280200450d00200528020410290b2005411c6a21010240200541146a280200450d00200528021010290b200121052001200d470d000b0b2016450d02201710290c020b0240201741ff0171220141024b0d0002400240024020010e03000102000b2015450d04201610290c040b02402013450d002013410c6c2106201521010340024020012802002205450d00200141046a280200450d00200510290b2001410c6a2101200641746a22060d000b0b2014450d03201510290c030b02402013450d00201520134104746a21162015211703402017220d41106a21170240200d2802042201450d000240200d410c6a2802002206450d002006410c6c21060340024020012802002205450d00200141046a280200450d00200510290b2001410c6a2101200641746a22060d000b0b200d41086a280200450d00200d28020410290b20172016470d000b0b2014450d02201510290c020b2015450d01201610290c010b02402016450d00201710290b02402013450d002012450d00201310290b200f450d00201010290b0c010b024020042d00dc010d00200c412c6c2101200841606a210a02400340024020010d004100210d0c020b200141546a2101200a41206a2106200a412c6a220b210a20062d0000410b470d000b200b280200210d0b200c412c6c2101200841586a2106024003404100210a024020010d00410021010c020b200141546a2101200641286a210b2006412c6a22052106200b2d00004104470d000b200441f8006a200510a203200428027c21010b0240200d2001470d004101210741e100210b41f3da012105410021060c030b0240200c450d00200c412c6c210a200821010340200110d8032001412c6a2101200a41546a220a0d000b0b410121064119210a024020090d000c030b200810290c020b20042802dc01220a4110762105200a410876210b200441d8016a41106a280200210d200441e4016a2802002117200441d8016a41086a28020021070b0240200c450d00200c412c6c2106200821010340200110d8032001412c6a2101200641546a22060d000b0b4101210602402009450d00200810290b200d2109201721080b02402006450d00200821060c040b20042802f0022002470d022005411074200b41ff017141087472200a41ff017172211b2008200c412c6c6a210a20082101024002400340200a2001460d0120012d000021022001412c6a2206210120024102470d000b200441f0006a200641586a10a2034104211c200428027021024100210e02400240024002400240200428027422010d004100211d0c010b2001410474220a4100480d06200a1032221c450d012001211d0b02402001450d00200141047421064100210e201c21010340200241086a280200220a417f4c0d032002410c6a2d0000210b2002280200210502400240200a0d004101210d0c010b200a1032220d450d050b200d2005200a109b0521052001410d6a2002410d6a2d00003a00002001410c6a200b3a0000200141086a200a360200200141046a200a36020020012005360200200141106a2101200e41016a210e200241106a2102200641706a22060d000b0b201c450d030c040b200a4104102e000b102f000b200a4101102e000b4100211d4104211c4100210e0b2008200c412c6c6a210a2008210102400340410021064104210d0240200a2001470d0041042102410021010c020b20012d000021022001412c6a220b210120024103470d000b200441e8006a200b41586a10a20341042102410021012004280268220a450d00200428026c2101200a21020b0240024020010d0041012112410021134100210a41002111410421154100210b4100211e4104211441002102410021054101211f41002116410021100c010b200141286c21172002411c6a21014104210d4100210641002113410121124100210a41002111410421154100210b4100211e4104211441002102410021054101211f4100211641002110034002400240024002400240024002400240024002402001417c6a2d00000e0400010203000b2001280200210f0240024020052002460d00200521180c010b200241016a22182002490d0c20024101742219201820182019491b221941ffffffff03712019470d0c201941027422184100480d0c0240024020020d0020181032210d0c010b200d200241027420181034210d0b200d450d0420022118201921020b200d20184102746a200f360200200541016a21050c080b200441d8016a41086a220f200141086a280200360200200420012902003703d8010240200a2011470d00200a41016a2211200a490d0b200a4101742218201120112018491b2211ad420c7e221a422088a70d0b201aa722184100480d0b02400240200a0d002018103221150c010b2015200a410c6c2018103421150b2015450d040b2015200a410c6c6a221820042903d801370200201841086a200f280200360200200a41016a210a0c070b200441d8016a41086a220f200141086a280200360200200420012902003703d8010240200b201e470d00200b41016a2218200b490d0a200b4101742219201820182019491b221ead420c7e221a422088a70d0a201aa722184100480d0a02400240200b0d002018103221140c010b2014200b410c6c2018103421140b2014450d040b2014200b410c6c6a221820042903d801370200201841086a200f280200360200200b41016a210b0c060b2001417e6a220f2d000021182001417d6a22192d00002120024020062013470d00200641016a22132006490d0920064101742221201320132021491b221320136a22222013490d0920224100480d090240024020060d002022103221120c010b201220212022103421120b2012450d040b201220064101746a222220184101713a0001202220203a0000200f2d0000211820192d00002119024020102016460d002016210f201021160c050b201641016a220f2016490d0820164101742222200f200f2022491b220f200f6a2220200f490d0820204100480d080240024020160d0020201032211f0c010b201f202220201034211f0b201f0d0420204101102e000b20184104102e000b20184104102e000b20184104102e000b20224101102e000b200641016a2106201f20164101746a221620184101713a0001201620193a0000201041016a2110200f21160b200141286a2101201741586a22170d000b0b2008200c412c6c6a210f200821010240024002400240024002400240024002400240024002400240024003400240200f2001470d00200221170c020b20012d000021172001412c6a2218210120174104470d000b200441e0006a201841586a10a2030240200428026422170d00200221170c010b200428026021012017410274210f0340200128020021180240024020052002460d0020022117200521190c010b200241016a22172002490d1020024101742219201720172019491b221741ffffffff03712017470d10201741027422194100480d100240024020020d0020191032210d0c010b200d200241027420191034210d0b200d450d0320022119201721020b200141046a2101200d20194102746a2018360200200541016a2105200f417c6a220f0d000b0b2008200c412c6c6a210f20082101024002400340200f2001460d0120012d000021022001412c6a2218210120024105470d000b200441d8006a201841586a10a203200428025c410c6c2219450d0020042802582101200a410174210f200a410c6c21020340200141086a2118024002400240200141046a2802004101470d002004201828020022203602c0022001280200222220204b0d010b20044100360280010c010b200441023602ec01200442023702dc01200441b4c4c5003602d801200441013602f402200441013602ec02200420223602d0022004200441e8026a3602e8012004200441d0026a3602f0022004200441c0026a3602e80220044180016a200441d8016a10af04200428028001450d0020044180016a21010c0e0b2001290200211a200441d8016a41086a222020182802003602002004201a3703d8010240200a2011470d00200a41016a2211200a490d11200f20112011200f491b2211ad420c7e221a422088a70d11201aa722184100480d1102400240200a0d002018103221150c010b201520022018103421150b2015450d030b2001410c6a2101201520026a221820042903d801370200201841086a2020280200360200200f41026a210f2002410c6a2102200a41016a210a201941746a22190d000b0b2008200c412c6c6a210f20082101024002400340200f2001460d0120012d000021022001412c6a2218210120024106470d000b200441d0006a201841586a10a20320042802542202450d00200428025021012002410c6c2118200b410174210f200b410c6c21020340200441d8016a200110bd04024020042802d801450d00200441d8016a21010c0f0b2001290200211a200441d8016a41086a2219200141086a2802003602002004201a3703d8010240200b201e470d00200b41016a221e200b490d12200f201e201e200f491b221ead420c7e221a422088a70d12201aa722204100480d1202400240200b0d002020103221140c010b201420022020103421140b2014450d030b2001410c6a2101201420026a222020042903d801370200202041086a2019280200360200200f41026a210f2002410c6a2102200b41016a210b201841746a22180d000b0b2008200c412c6c6a210f20082101024002400240024002400340200f2001460d0120012d000021022001412c6a2218210120024107470d000b200441c8006a201841586a10a203200428024c2202450d002004280248220120024104746a212220064101742102200441d8016a41047221200340200441d8016a2001201f201010be0402400240024020042d00d8014101460d00200420042d00d901220f3a00c0020240200f2001410c6a2d00002218470d0020044100360280010c030b200441023602ec01200442023702dc01200441c8c5c5003602d801200441223602f402200441223602ec02200420183a00d0022004200441e8026a3602e8012004200441c0026a3602f0022004200441d0026a3602e80220044180016a200441d8016a10af040c010b20044180016a41086a202041086a28020036020020042020290200370380010b0240200428028001450d0020044180016a21010c140b2001410c6a2d0000210f0b2001410d6a2d00002118024020062013470d00200641016a22132006490d162002201320132002491b221320136a22192013490d1620194100480d160240024020060d002019103221120c010b201220022019103421120b2012450d030b201220026a2219200f3a0000201941016a20184101713a0000200241026a2102200641016a2106200141106a22012022470d000b0b200441b8016a2005360200200441b4016a201736020020044180016a412c6a200e360200200441a8016a201d360200200441a0016a20063602002004419c016a201336020020044194016a200a36020020044190016a20113602002004200d3602b0012004201c3602a40120042012360298012004201536028c012004200b360288012004201e3602840120042014360280012008200c412c6c6a210a20082101024003400240200a2001470d004100210b0c020b20012d000021022001412c6a2206210120024104470d000b200441c0006a200641586a10a2032004280244210b0b2004200b3602bc012008200c412c6c6a210a20082101024003400240200a2001470d00410021010c020b20012d000021022001412c6a220621012002410b470d000b200641606a28020021010b200420013602c001200b2001470d0d0240200b450d002008200c412c6c6a210a200821010340200a2001460d0520012d000021022001412c6a2206210120024104470d000b2008200c412c6c6a210b200821010340200b2001460d0420012d000021022001412c6a220a21012002410b470d000b200441386a200641586a10a203200428023c2201450d002004280238220d20014102746a2113200a41606a2117200a41586a211520044191026a2118410021050340200420053602c4012017280200210120152802002102200442013702dc01200441ccbac5003602d801200441013602d402200441013602ec012004200441d0026a3602e8012004200441c4016a3602d002200441e8026a200441d8016a10af0420042802e802210a20042902ec02211a200120054d0d110240201aa7450d00200a10290b2004200d28020022013602d002024002400240024020042802ac0120014b0d00200441013602ec01200442023702dc01200441c0c8c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a10af0420042902ec02221a422088a7210120042802e8022106201aa721020c010b0240024002402002200541186c6a2202280214220e450d0020042802a40120014104746a220a2d000d2114200a2802002111200228020c21012002280200210f200a28020822122106024020022802082210450d002010410374210b20122102200f210a034002402002200a2802006a220620024f0d0002404120103222060d0041204101102e000b200641186a4100290090cb45370000200641106a4100290088cb45370000200641086a4100290080cb45370000200641002900f8ca453700000c040b200a41086a210a20062102200b41786a220b0d000b0b0240410810322202450d0020022014ad42ff0183422886370200200441d0026a41026a220a200441e8026a41026a2d00003a0000200420042f00e8023b01d002200420143a00900220044180800136028c022004428180808010370284022004200236028002200442808080808080103703f801200442013703f001200420063602ec01200420103602e8012004200f3602e401200420123602e001200420113602dc01200420044180016a3602d801201820042f01d0023b0000201841026a200a2d00003a0000200e410474210a41002102034020042002360298022004200136029c02200441b0026a200441d8016a200110c004024020042802b002450d00200441c0026a41086a200441b0026a41086a280200360200200420042903b0023703c002200441033602e402200442033702d402200441c0b2c5003602d002200441233602fc02200441013602f402200441243602ec022004200441e8026a3602e0022004200441c0026a3602f802200420044198026a3602f00220042004419c026a3602e802200441a0026a200441d0026a10af04024020042802c402450d0020042802c00210290b20042802a0022206450d0020042902a402211a024020042802f401450d0020042802f00110290b201a42208821230240200428028402450d0020042802800210290b2023a72101201aa721020c070b200141106a2101200241016a2102200a41706a220a0d000b02402004280288020d00024020042802f401450d0020042802f00110290b200428028402450d0720042802800210290c070b41d8b2c500106d000b41084104102e000b412010322206450d01200641186a41002900b5b245370000200641106a41002900adb245370000200641086a41002900a5b2453700002006410029009db2453700000b41202102412021010c010b41204101102e000b2006450d010b200420063602d00220042001ad4220862002ad843702d4022004200441d0026a3602c002200441023602ec01200442023702dc01200441d4bac5003602d801200441253602f402200441013602ec022004200441e8026a3602e8012004200441c0026a3602f0022004200441c4016a3602e802200441c8016a200441d8016a10af04024020042802d402450d0020042802d00210290b20042802c801220a450d0020042902cc01211a0c120b200541016a2105200d41046a220d2013470d000b0b2008200c412c6c6a210a2008210102400340200a2001460d0120012d000021022001412c6a2206210120024109470d000b2004200641586a28020022013602b002024020042802b80120014b0d00200441ec016a4101360200200442023702dc01200441b0c8c5003602d801200441013602c4022004200441c0026a3602e8012004200441b0026a3602c002200441e8026a200441d8016a10af040c0d0b200420042802b00120014102746a28020022013602d002024020042802ac0120014b0d00200441ec016a4101360200200442023702dc01200441c0c8c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a10af040c0d0b20042802a40120014104746a220131000d4220862001350208844280808080c000510d00412d1032220a450d02200a41256a4100290089bb45370000200a41206a4100290084bb45370000200a41186a41002900fcba45370000200a41106a41002900f4ba45370000200a41086a41002900ecba45370000200a41002900e4ba4537000042ad808080d005211a0c100b2008200c412c6c6a210a200821010340200a2001460d0b20012d000021022001412c6a2206210120024108470d000b200441306a200641586a220110a203200441d8016a200428023410c304200441e8026a41086a200441e4016a290200370300200441e8026a41106a200441d8016a41146a280200360200200420042902dc013703e802200441286a200110a203200428022c2201450d0920042802282213200141146c6a2111034020132217450d0a410021022017280208220d210120172802002215210a0240200d4104490d004100210220152101200d210a0340200128000020024105777341b9f3ddf1796c2102200141046a2101200a417c6a220a41034b0d000b200d417c6a22012001417c71220a6b2101200a20156a41046a210a0b02400240200141014b0d00200a21060c010b200a41026a21062001417e6a21012002410577200a2f00007341b9f3ddf1796c21020b02402001450d00200241057720062d00007341b9f3ddf1796c21020b201741146a2113200241057741ff017341b9f3ddf1796c22024119762214410874201472220141107420017221054100211220042802f002211020042802e802210b20042802ec0221062002210103400240200b200120067122016a280000220f200573220a417f73200a41fffdfb776a7141808182847871220a450d00024003400240200d2010200a6841037620016a2006714103746a220e41046a280200470d002015200e280200220e460d022015200e200d109d05450d020b200a417f6a200a71220a450d020c000b0b200441ec016a4101360200200442013702dc0120044194bbc5003602d801200441053602b4022004200d3602c402200420153602c0022004200441b0026a3602e8012004200441c0026a3602b002200441d0026a200441d8016a10af040c0a0b201241046a221220016a2101200f200f4101747141808182847871450d000b024020042802f8020d00200441e8026a10c40420042802e802210b20042802ec0221060b200620027121024104210103402002220a20016a2006712102200141046a2101200b200a6a280000418081828478712205450d000b0240200b200568410376200a6a20067122016a2c000022024100480d00200b200b280200418081828478716841037622016a2d000021020b200b20016a20143a00002001417c6a200671200b6a41046a20143a000020042802f00220014103746a200dad4220862015ad84370200200420042802f40241016a3602f402200420042802f80220024101716b3602f802024002400240024002400240201728020c0e0400030201000b2004201728021022013602a002024020042802b80120014b0d00200441ec016a4101360200200442023702dc01200441b0c8c5003602d801200441013602c4022004200441c0026a3602e8012004200441a0026a3602c002200441d0026a200441d8016a10af040c0e0b200420042802b00120014102746a28020022013602b00220042802ac0120014b0d03200441013602ec01200442023702dc01200441c0c8c5003602d801200441013602c4022004200441c0026a3602e8012004200441b0026a3602c002200441d0026a200441d8016a10af040c0d0b2004201728021022013602a002024020042802a00120014b0d00200441ec016a4101360200200442023702dc01200441e0c8c5003602d801200441013602c4022004200441c0026a3602e8012004200441a0026a3602c002200441d0026a200441d8016a10af040c0d0b20042802980120014101746a2d0001450d02200441ec016a4101360200200442023702dc0120044180c9c5003602d801200441013602c4022004200441c0026a3602e8012004200441a0026a3602c002200441d0026a200441d8016a10af040c0c0b2004201728021022013602b00220042802880120014b0d01200441013602ec01200442023702dc01200441e0c7c5003602d801200441013602c4022004200441c0026a3602e8012004200441b0026a3602c002200441d0026a200441d8016a10af0420042802d002220a0d0c0c010b2004201728021022013602b00220042802940120014d0d010b20132011470d010c0b0b0b200441ec016a4101360200200442023702dc0120044190c8c5003602d801200441013602c4022004200441c0026a3602e8012004200441b0026a3602c002200441d0026a200441d8016a10af040c070b20194101102e000b412d4101102e000b4182bac50041c800109201000b41e4b9c500411e109201000b20204104102e000b20184104102e000b20194104102e000b20042802d002210a0b20042902d402211a2006450d060240200641016a220141ffffffff01712001470d00200641086a417c712202200641056a490d00200220014103746a2002491a0b200b10290c060b20042802ec022201450d000240200141016a220241ffffffff01712002470d00200141086a417c71220a200141056a490d00200a20024103746a200a491a0b20042802e80210290b2008200c412c6c6a210a2008210102400340200a2001460d0120012d000021022001412c6a2206210120024103470d000b200441206a200641586a10a20320042802242201450d0020042802202106200141286c210b41002101034002400240024002400240200620016a220241186a2d00000e0400030201000b20042002411c6a28020022023602d00220042802ac0120024b0d03200441ec016a4101360200200442023702dc01200441c0c8c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a10af040c060b2002411a6a2d0000450d022002410c6a2802002101200241146a2802002102200441d8016a41146a4101360200200420023602d402200420013602d002200441053602c402200442013702dc012004419cbbc5003602d8012004200441d0026a3602c0022004200441c0026a3602e801200441e8026a200441d8016a10af040c050b200441d8016a2002411c6a10bd0420042802d801220a450d0120042902dc01211a0c080b200241206a2802004101470d002002411c6a280200210a2004200241246a28020022023602b002200a20024d0d00200441023602ec01200442023702dc01200441b4c4c5003602d801200441013602f402200441013602ec022004200a3602c0022004200441e8026a3602e8012004200441c0026a3602f0022004200441b0026a3602e802200441d0026a200441d8016a10af0420042802d002220a0d060b200b200141286a2201470d000b0b024002400240200428029401220141014b0d00200428028801220141014b0d012008200c412c6c6a210a2008210102400240024002400340200a2001460d0120012d000021022001412c6a220621012002410c470d000b200441186a200641586a10a20320042802182201200428021c411c6c6a2106034020012006460d012004200128020022023602d002024020042802880120024b0d00200441013602ec01200442023702dc01200441e0c7c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a10af0420042802e802220a450d0020042902ec02211a0c0d0b200441d8016a200141046a220120042802980120042802a00110be0420042d00d8014101460d02200141186a210120042d00d901450d000b41201032220a450d06200a41186a41002900ccbb45370000200a41106a41002900c4bb45370000200a41086a41002900bcbb45370000200a41002900b4bb4537000042a08080808004211a0c0b0b2008200c412c6c6a210a2008210102400340200a2001460d0120012d000021022001412c6a220621012002410a470d000b200441106a200641586a10a20320042802142201450d002004280210220b2001411c6c6a21050340200b450d012004200b28020022013602d00220042802940120014d0d03200441d8016a200b41046a20042802980120042802a00110be0420042d00d8014101460d0420042d00d9010d09200441086a200b10c50402400240200428020c2201450d00200428020821022001410274210a20042802b801210603402004200228020022013602b0020240200620014b0d00200441ec016a4101360200200442023702dc01200441b0c8c5003602d801200441013602c4022004200441c0026a3602e8012004200441b0026a3602c002200441e8026a200441d8016a10af040c0c0b200420042802b00120014102746a28020022013602d00220042802ac0120014d0d02200241046a2102200a417c6a220a0d000b0b200b411c6a220b2005460d020c010b0b200441013602ec01200442023702dc01200441c0c8c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a10af040c070b0240200428028401450d0020042802800110290b0240200428029001450d00200428028c0110290b0240200428029c01450d0020042802980110290b024020042802ac012202450d0020042802a40121012002410474210203400240200141046a280200450d00200128020010290b200141106a2101200241706a22020d000b0b024020042802a801450d0020042802a40110290b024020042802b401450d0020042802b00110290b2016450d0d201f10290c0d0b200441e0016a290300211a20042802dc01210a0c090b200441ec016a4101360200200442023702dc0120044190c8c5003602d801200441013602c4022004200441c0026a3602e8012004200441d0026a3602c002200441e8026a200441d8016a10af040c040b200441e0016a290300211a20042802dc01210a0c070b200441ec016a4101360200200442013702dc01200441a4bbc5003602d801200441013602d402200420013602c0022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10af040c020b200441ec016a4101360200200442013702dc01200441acbbc5003602d801200441013602d402200420013602c0022004200441d0026a3602e8012004200441c0026a3602d002200441e8026a200441d8016a10af040c010b41204101102e000b20042802e802210a20042902ec02211a0c030b024041201032220a450d00200a41186a41002900ccbb45370000200a41106a41002900c4bb45370000200a41086a41002900bcbb45370000200a41002900b4bb4537000042a08080808004211a0c030b41204101102e000b200441ec016a4102360200200441f4026a4101360200200442023702dc01200441d4b9c5003602d801200441013602ec022004200441e8026a3602e8012004200441c0016a3602f0022004200441bc016a3602e802200441d0026a200441d8016a10af0420042802d002210a0b20042902d402211a0b0240200428028401450d0020042802800110290b0240200428029001450d00200428028c0110290b0240200428029c01450d0020042802980110290b024020042802ac012202450d0020042802a40121012002410474210203400240200141046a280200450d00200128020010290b200141106a2101200241706a22020d000b0b024020042802a801450d0020042802a40110290b024020042802b401450d0020042802b00110290b2016450d01201f1029200a0d040c020b2001290204211a2001280200210a02402016450d00201f10290b0240201e450d00201410290b02402011450d00201510290b02402013450d00201210290b0240200e450d00200e4104742102201c210103400240200141046a280200450d00200128020010290b200141106a2101200241706a22020d000b0b0240201d450d00201c10290b2017450d00200d10290b200a0d020b2000201b36020420004100360200200041186a2003360200200041146a200c360200200041106a20093602002000410c6a2008360200200041086a20073602000c040b1033000b0240201aa7450d00200a10290b200041ccb4c50036020420004101360200200041086a41133602000240200c450d00200c412c6c2102200821010340200110d8032001412c6a2101200241546a22020d000b0b2009450d02200810290c020b200441003a00d002200441ec016a4101360200200442013702dc01200441d8e7c5003602d801200441213602b4022004200441b0026a3602e8012004200441d0026a3602b00220044180016a200441d8016a10af04200428028001210720042802840121060240200c450d00200c412c6c2102200821010340200110d8032001412c6a2101200241546a22020d000b0b4105210a2009450d00200810290b02402006450d00200a41ff01714105470d00200710290b200041b6b4c50036020420004101360200200041086a41163602000b20044180036a24000bd61301177f23004190026b220224000240024002400240024002402000280200220341b0d6c000460d00200028020421040c010b41002104200241b8016a410041d800109a051a2002411f6a220542003700002002420037011a41ec0010322203450d0120034100360200200320022902183702042003410b6a2005290000370000200341136a200241b7016a41d900109b051a20004100360204200020033602000b200141ff0171210602400340200341146a2107200341086a210820032f01062109410021050240024003402007210a20092005460d01200820056a2d0000220b2006460d02200a41086a2107200541016a21050240417f200b200649200b20064b1b41016a0e03000301000b0b2005417f6a21090b2004450d022004417f6a2104200320094102746a41ec006a28020021030c010b0b200a42013702000c030b2000200028020841016a360208024002400240024020032f01062205410b490d00200241276a41016a410041d800109a051a200241003a001941ec0010322208450d03200841003602002008410036000f20084200370007200820022f01183b0005200841136a200241276a41d900109b051a2003410e6a2d0000210c2003280248210d2003280244210e200841086a2003410f6a20032f010641796a2205109b052106200841146a200341cc006a2005410374109b05210b200341063b0106200820053b010620094107490d0120062009417a6a220a6a2006200941796a22076a2206200541ffff037120076b109c051a200620013a0000200b200a4103746a200b20074103746a2206200841066a22052f010020076b410374109c051a2006410136020020052f010021060c020b200341086a2206200941016a220b6a200620096a2206200520096b2207109c051a200620013a0000200341146a2206200b4103746a200620094103746a22062007410374109c051a200641013602002003200541016a3b01060c050b200341086a2205200941016a220b6a200520096a2207200341066a22052f0100220620096b220a109c051a200720013a0000200341146a2207200b4103746a200720094103746a220b200a410374109c051a200b41013602000b2005200641016a3b010020032802002209450d02200341046a2105200241276a41016a210f200241a8016a2101200241a0016a211020024198016a211120024190016a211220024180016a41086a2113034020052f010021070240024002400240024020092f01062205410b490d00200f410041d800109a051a200241003a0019200220022f01183b0108200241b7016a200241276a41d900109b051a20014200370300201042003703002011420037030020124200370300201342003703002002420037038001419c0110322206450d03200641003602002006410036000f20064200370007200620022f01083b0005200641136a200241b7016a41d900109b051a20064194016a20012903003702002006418c016a201029030037020020064184016a2011290300370200200641fc006a2012290300370200200641f4006a2013290300370200200620022903800137026c200941c8006a2802002114200941c4006a28020021152009410e6a2d00002116200641086a2009410f6a20092f0106220341796a2205109b052117200641146a200941cc006a2005410374109b052118200641ec006a20094188016a2003417a6a220a410274109b052104200941063b0106200620053b01060240200a450d00410021052004210303402003280200220b20053b0104200b2006360200200341046a2103200a200541016a2205470d000b0b20074107490d0120172007417a6a22036a2017200741796a22056a220b20062f010620056b109c051a200b200c3a0000201820034103746a201820054103746a220b20062f010620056b410374109c051a200b200e360200200b200d360204200620062f010641016a220b3b01062007410274220c20046a416c6a200420034102746a220a200b41ffff0371220720036b410274109c051a200a200836020020072003490d022006200c6a41d4006a210303402003280200220b200541016a22053b0104200b2006360200200341046a210320052007490d000c030b0b200941086a2206200741016a22036a200620076a2206200520076b220b109c051a2006200c3a0000200941146a220620034103746a200620074103746a2206200b410374109c051a2006200e3602002006200d3602042009200541016a22053b01062007410274200941ec006a22066a41086a200620034102746a2206200541ffff0371220b20036b410274109c051a200620083602002007200b4f0d0820092003417f6a22054102746a41f0006a2103034020032802002206200541016a22053b010420062009360200200341046a21032005200b490d000c090b0b200941086a2203200741016a22056a200320076a220320092f0106220b20076b220a109c051a2003200c3a0000200941146a220320054103746a200320074103746a2203200a410374109c051a2003200e3602002003200d3602042009200b41016a22033b010620074102742204200941ec006a220b6a41086a200b20054102746a220a200341ffff0371220b20056b410274109c051a200a20083602002007200b4f0d00200920046a41f0006a2105034020052802002203200741016a22073b010420032009360200200541046a2105200b2007470d000b0b200928020022030d01200621082014210d2015210e2016210c0c050b419c014104102e000b200941046a2105200321092016210c2015210e2014210d200621080c000b0b41ec004104102e000b41ec004104102e000b200241b7016a41016a410041d800109a051a2002411f6a220542003700002002420037011a200220022902183703082002200529000037000f200241276a200241b7016a41d900109b051a200241a8016a22034200370300200241a0016a2206420037030020024180016a41186a220b420037030020024190016a2207420037030020024180016a41086a220942003703002002420037038001419c0110322205450d0120054100360200200520022903083702042005410b6a200229000f370000200541136a200241276a41d900109b051a20054194016a20032903003702002005418c016a200629030037020020054184016a200b290300370200200541fc006a2007290300370200200541f4006a2009290300370200200520022903800137026c20052000280200220336026c200020053602002000200028020441016a360204200341003b010420032005360200200520052f010622034103746a220641186a200d360200200641146a200e360200200520036a41086a200c3a0000200541ec006a200341016a22034102746a2008360200200520033b0106200820033b0104200820053602000b20024190026a24000f0b419c014104102e000bd11e01387f23004190016b2202240020024184016a4200370200200241fc006a4280808080c000370200200241ec006a4200370200200241e4006a4280808080c000370200200241d0006a4200370300200241c0006a4200370300200241386a4280808080c000370300200241286a4200370300200241206a4280808080c000370300200241106a4200370300200242043702742002420437025c20024204370348200242043703302002420437031820024280808080c000370308200242043703002001410c6a280200210320024180016a210420012802082105024002400240200141106a28020022060d00410421014100210741002108410021094100210a4104210b4100210c4100210d4104210e4100210f41002110410421114100211241002113410421144100210641002115410421164100211741002118410421194100211a4100211b4104211c4100211d4100211e4104211f41002120410021210c010b410021224100211f41002123410021244100211c410021254100212641002127410021284100212941002107024003402001212a2007211520052006417f6a2206412c6c6a2201280024211720012800202119200128001821182001280014211420012800102116200128000c210c2001280008210b200128000421094101210741012112024002400240024002400240024020012d0000220a417e6a2208410d4d0d00410121130c010b4101211341012110410121114101210f4101210d4101210e20092101024002400240024002400240024002400240024020080e0e000102030405060f0708090e0e11000b02402029450d000240202b450d00202b41047421072029210103400240200141046a280200450d00200128020010290b200141106a2101200741706a22070d000b0b202c450d00202910290b4101211341002112200c212b200b212c200921290c090b02402028450d000240202d450d00202d41286c21072028210103400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141286a2101200741586a22070d000b0b202e450d00202810290b4100211341012112200c212d200b212e200921280c080b0240202f450d002027450d00202710290b20152107202a210120092127200b212f200c21300c0c0b02402031450d002026450d00202610290b20152107202a210120092126200b2131200c21320c0b0b02402033450d002025450d00202510290b20152107202a210120092125200b2133200c21340c0a0b0240201c450d000240201a450d00201c201a4104746a210d201c21080340024020082802082207450d0020082802002101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200741706a22070d000b0b200841106a21010240200841046a280200450d00200828020010290b200121082001200d470d000b0b2035450d00201c10290b4100211041012112200c211a200b21352009211c410121130c050b02402024450d000240201e450d00201e41146c21072024210103400240200141046a280200450d00200128020010290b200141146a21012007416c6a22070d000b0b2036450d00202410290b4100211141012112200c211e200b21362009212441012113410121100c050b02402023450d000240201d450d002023201d411c6c6a210d20232108034002402008410c6a2802002207450d0020082802042101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200741706a22070d000b0b0240200841086a280200450d00200828020410290b2008411c6a21010240200841146a280200450d00200828021010290b200121082001200d470d000b0b2037450d00202310290b4100210f41012112200c211d200b2137200921234101211341012110410121110c050b0240201f450d000240201b450d00201f201b41186c6a210d201f210803400240200841046a280200450d00200828020010290b0240200841146a2802002207450d00200828020c2101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200741706a22070d000b0b200841186a21010240200841106a280200450d00200828020c10290b200121082001200d470d000b0b2020450d00201f10290b4100210d41012112200c211b200b21202009211f4101211341012110410121114101210f4101210e0c050b02402022450d0002402038450d0020222038411c6c6a210d20222108034002402008410c6a2802002207450d0020082802042101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200741706a22070d000b0b0240200841086a280200450d00200828020410290b2008411c6a21010240200841146a280200450d00200828021010290b200121082001200d470d000b0b2039450d00202210290b4100210e41012112200c2138200b2139200921224101211341012110410121114101210f4101210d0c040b410121100b410121110b4101210f0b4101210d4101210e0b02400240024002400240200a410d4b0d0020152107202a210102400240024002400240024002400240024002400240200a0e0e080900010202020304100506070a080b2012450d0e0240200c450d00200c41047421072009210103400240200141046a280200450d00200128020010290b200141106a2101200741706a22070d000b0b200b450d0e0c0d0b2013450d0d200c450d00200c41286c21072009210103400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141286a2101200741586a22070d000b0b200b0d0b0c0c0b2010450d0b0240200c450d002009200c4104746a210a200921080340024020082802082207450d0020082802002101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200741706a22070d000b0b200841106a21010240200841046a280200450d00200828020010290b200121082001200a470d000b0b200b0d0a0c0b0b2011450d0a0240200c450d00200c41146c21072009210103400240200141046a280200450d00200128020010290b200141146a21012007416c6a22070d000b0b200b0d090c0a0b200f450d090240200c450d002009200c411c6c6a210a20092108034002402008410c6a2802002207450d0020082802042101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200741706a22070d000b0b0240200841086a280200450d00200828020410290b2008411c6a21010240200841146a280200450d00200828021010290b200121082001200a470d000b0b200b0d080c090b200d450d080240200c450d002009200c41186c6a210a2009210803400240200841046a280200450d00200828020010290b0240200841146a2802002207450d00200828020c2101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200741706a22070d000b0b200841186a21010240200841106a280200450d00200828020c10290b200121082001200a470d000b0b200b0d070c080b200e450d07200c450d002009200c411c6c6a210a20092108034002402008410c6a2802002207450d0020082802042101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200741706a22070d000b0b0240200841086a280200450d00200828020410290b2008411c6a21010240200841146a280200450d00200828021010290b200121082001200a470d000b0b200b0d050c060b0240200b450d00200910290b2014450d05201610290c050b0240200941ff0171220141024b0d0002400240024020010e03000102000b200c450d070c050b02402014450d002014410c6c2107200c21010340024020012802002208450d00200141046a280200450d00200810290b2001410c6a2101200741746a22070d000b0b2016450d060c030b02402014450d00200c20144104746a210b200c210a0340200a220941106a210a024020092802042201450d0002402009410c6a2802002207450d002007410c6c21070340024020012802002208450d00200141046a280200450d00200810290b2001410c6a2101200741746a22070d000b0b200941086a280200450d00200928020410290b200a200b470d000b0b20160d020c050b200c0d020c040b0240200b450d00200910290b02402014450d002018450d00201410290b2017450d03201910290c030b200c10290c020b200b10290c010b200910290b20152107202a21010b20060d000b410021062001212a200721150b201b4100201f1b210720204100201f1b2108201d410020231b21212037410020231b2120201e410020241b21092036410020241b210a201a4100201c1b211e20354100201c1b211d2034410020251b210c2033410020251b210d2032410020261b211b2031410020261b211a2030410020271b210f202f410020271b2110202d410020281b2118202e410020281b2117202b410020291b2112202c410020291b2113201f4104201f1b21012023410420231b211f2024410420241b210b201c4104201c1b211c2025410420251b210e2026410420261b21192027410420271b21112028410420281b21162029410420291b211420220d010b4104212241002139410021380b200410eb040240200228028401450d0020022802800110290b200241d8006a202a3602002002200636028801200220033602840120022005360280012002203836027c2002203936027820022022360274200220073602702002200836026c2002200136026820022021360264200220203602602002201f36025c20022015360254200220093602502002200a36024c2002200b3602482002201e3602442002201d3602402002201c36023c2002200c3602382002200d3602342002200e3602302002201b36022c2002201a360228200220193602242002200f3602202002201036021c2002201136021820022018360214200220173602102002201636020c20022012360208200220133602042002201436020020002002418c01109b051a20024190016a24000bc30a01107f230041106b2202240002400240024002400240024020012802004101470d00200141106a2d000021032001410c6a2802002104200141086a280200210520012f0112210620012d0011210720012802042108200241086a200010a20320022802082201200228020c22094104746a210a4100210b20094104490d01200341ff0171210c0340024020012d000c200c470d0020012802082004470d002001280200210d200421092008210e0340024020090d00200741ff0171220941044720012d000d220d410446220e460d02200d2009460d0620094104460d06200e450d020c060b2009417f6a2109200e2d0000210f200d2d00002110200e41016a210e200d41016a210d2010200f460d000b0b02402001411c6a2d0000200c470d00200141186a2802002004470d002001280210210d200421092008210e024003402009450d012009417f6a2109200e2d0000210f200d2d00002110200e41016a210e200d41016a210d2010200f460d000c020b0b200741ff0171220941044720012d001d220d410446220e460d000240200d2009460d0020094104460d00200e450d010b200b410172210b0c040b02402001412c6a2d0000200c470d00200141286a2802002004470d002001280220210d200421092008210e024003402009450d012009417f6a2109200e2d0000210f200d2d00002110200e41016a210e200d41016a210d2010200f460d000c020b0b200741ff0171220941044720012d002d220d410446220e460d000240200d2009460d0020094104460d00200e450d010b200b410272210b0c040b02402001413c6a2d0000200c470d00200141386a2802002004470d002001280230210d200421092008210e024003402009450d012009417f6a2109200e2d0000210f200d2d00002110200e41016a210e200d41016a210d2010200f460d000c020b0b200741ff0171220941044720012d003d220d410446220e460d000240200d2009460d0020094104460d00200e450d010b200b410372210b0c040b200b41046a210b200a200141c0006a22016b41304d0d020c000b0b2001280204210b0c030b2001200a460d0102400240200741ff017122114104460d00200341ff0171210c0c010b200341ff0171210c0340024020012d000c200c470d0020012802082004470d002001280200210d200421092008210e024003402009450d012009417f6a2109200e2d0000210f200d2d00002110200e41016a210e200d41016a210d2010200f460d000c020b0b20012d000d4104460d030b200b41016a210b200141106a2201200a470d000c030b0b0340024020012d000c200c470d0020012802082004470d002001280200210e200421092008210d024003402009450d012009417f6a2109200d2d0000210f200e2d00002110200d41016a210d200e41016a210e2010200f460d000c020b0b20012d000d22092011470d0020094104470d020b200b41016a210b200141106a2201200a460d020c000b0b2005450d01200810290c010b024020002802082201200041046a280200470d0002400240200141016a22092001490d002001410174220d20092009200d491b220941ffffffff00712009470d002009410474220d41004e0d010b1033000b0240024020010d00200d103221010c010b20002802002001410474200d103421010b2001450d0220002001360200200041046a2009360200200028020821010b200028020020014104746a220120063b010e200120073a000d200120033a000c2001200436020820012005360204200120083602002000200028020841016a3602082002200010a2032002280204417f6a210b0b200241106a2400200b0f0b200d4104102e000be522032d7f017e017f230041306b220224002002410436020420012802042103200128020021044101210502400240024002400240024002400240024002400240024002400240024002400240200128020822060d0041002107410121080c010b412c10322207450d012007200636000c200720033600082007200436000420022007360204200741023a000041002108410121070b200141106a2802002109200128020c210a02400240200141146a280200220b0d002007210c0c010b2007410174220d200741016a220c200c200d491b220c412c6c210e0240024020070d00200e1032210d0c010b20022802042007412c6c200e1034210d0b200d450d022002200d360204200d2007412c6c6a220d41033a0000200d20022f002d3b0001200d200b36000c200d2009360008200d200a360004200d2002290208370210200d41036a2002412f6a2d00003a0000200d41186a200241106a290200370200200d41206a200241186a290200370200200d41286a200241086a41186a280200360200200741016a2107410021050b2001411c6a280200210f200128021821104100211102400240200141206a28020022120d00200c210e410021130c010b024002402007200c460d00200c210e0c010b41000d0e41000d0e200c410174220d200c41016a220e200e200d491b220ead422c7ea722144100480d0e02400240200c0d0020141032210d0c010b2002280204200c412c6c20141034210d0b200d450d042002200d3602040b20022802042007412c6c6a220d41043a0000200d20022f002d3b0001200d201236000c200d200f360008200d2010360004200d2002290208370210200d41036a2002412f6a2d00003a0000200d41186a200241106a290200370200200d41206a200241186a290200370200200d41286a200241086a41186a28020036020041012113200741016a21070b200141286a280200211420012802242115024002402001412c6a28020022120d00200e210c0c010b024002402007200e460d00200e210c0c010b41000d0e41000d0e200e410174220d200e41016a220c200c200d491b220cad422c7ea722114100480d0e02400240200e0d0020111032210d0c010b2002280204200e412c6c20111034210d0b200d450d052002200d3602040b20022802042007412c6c6a220d41053a0000200d20022f002d3b0001200d201236000c200d2014360008200d2015360004200d2002290208370210200d41036a2002412f6a2d00003a0000200d41186a200241106a290200370200200d41206a200241186a290200370200200d41286a200241086a41186a28020036020041012111200741016a21070b200141346a28020021162001280230211702400240200141386a280200220e0d00410021180c010b02402007200c470d0041000d0e41000d0e200c410174220d200c41016a22122012200d491b2212ad422c7ea722194100480d0e02400240200c0d0020191032210d0c010b2002280204200c412c6c20191034210d0b200d450d062002200d3602042012210c0b20022802042007412c6c6a220d41063a0000200d20022f002d3b0001200d200e36000c200d2016360008200d2017360004200d2002290208370210200d41036a2002412f6a2d00003a0000200d41186a200241106a290200370200200d41206a200241186a290200370200200d41286a200241086a41186a28020036020041012118200741016a21070b200141c0006a280200211a200128023c211b4101211902400240200141c4006a280200221c0d00200c210e4101211d0c010b024002402007200c460d00200c210e0c010b41000d0e41000d0e200c410174220d200c41016a220e200e200d491b220ead422c7ea722124100480d0e02400240200c0d0020121032210d0c010b2002280204200c412c6c20121034210d0b200d450d072002200d3602040b20022802042007412c6c6a220d41073a0000200d20022f002d3b0001200d201c36000c200d201a360008200d201b360004200d2002290208370210200d41036a2002412f6a2d00003a0000200d41186a200241106a290200370200200d41206a200241186a290200370200200d41286a200241086a41186a280200360200200741016a21074100211d0b200141cc006a280200211e2001280248211f02400240200141d0006a28020022200d00200e21120c010b024002402007200e460d00200e21120c010b41000d0e41000d0e200e410174220d200e41016a220c200c200d491b2212ad422c7ea7220c4100480d0e02400240200e0d00200c1032210d0c010b2002280204200e412c6c200c1034210d0b200d450d082002200d3602040b20022802042007412c6c6a220d41083a0000200d20022f002d3b0001200d202036000c200d201e360008200d201f360004200d2002290208370210200d41036a2002412f6a2d00003a0000200d41186a200241086a41086a290200370200200d41206a200241186a290200370200200d41286a200241086a41186a280200360200200741016a2107410021190b410121210240024020012802544101460d002012210c0c010b200141d8006a280200210e0240024020072012460d002012210c0c010b41000d0e41000d0e2012410174220d201241016a220c200c200d491b220cad422c7ea722224100480d0e0240024020120d0020221032210d0c010b20022802042012412c6c20221034210d0b200d450d092002200d3602040b20022802042007412c6c6a220d41093a0000200d20022f002d3b0001200d200e360204200d2002290208370208200d41036a2002412f6a2d00003a0000200d41106a200241106a290200370200200d41186a200241086a41106a290200370200200d41206a200241086a41186a290200370200200d41286a200241086a41206a280200360200200741016a21070b200141e0006a2802002123200128025c212402400240200141e4006a28020022250d00200c210e0c010b024002402007200c460d00200c210e0c010b41000d0e41000d0e200c410174220d200c41016a220e200e200d491b220ead422c7ea722124100480d0e02400240200c0d0020121032210d0c010b2002280204200c412c6c20121034210d0b200d450d0a2002200d3602040b20022802042007412c6c6a220d410a3a0000200d20022f002d3b0001200d202536000c200d2023360008200d2024360004200d2002290208370210200d41036a2002412f6a2d00003a0000200d41186a200241106a290200370200200d41206a200241186a290200370200200d41286a200241086a41186a280200360200200741016a2107410021210b200141ec006a2802002126200128026821274101212202400240200141f0006a28020022280d00200e2112410121290c010b024002402007200e460d00200e21120c010b41000d0e41000d0e200e410174220d200e41016a220c200c200d491b2212ad422c7ea7220c4100480d0e02400240200e0d00200c1032210d0c010b2002280204200e412c6c200c1034210d0b200d450d0b2002200d3602040b20022802042007412c6c6a220d410b3a0000200d20022f002d3b0001200d202836000c200d2026360008200d2027360004200d2002290208370210200d41036a2002412f6a2d00003a0000200d41186a200241106a290200370200200d41206a200241186a290200370200200d41286a200241086a41186a280200360200200741016a2107410021290b200141f8006a280200212a2001280274210e02400240200141fc006a280200222b0d002012210c0c010b0240024020072012460d002012210c0c010b41000d0e41000d0e2012410174220d201241016a220c200c200d491b220cad422c7ea722224100480d0e0240024020120d0020221032210d0c010b20022802042012412c6c20221034210d0b200d450d0c2002200d3602040b20022802042007412c6c6a220d410c3a0000200d20022f002d3b0001200d202b36000c200d202a360008200d200e360004200d2002290208370210200d41036a2002412f6a2d00003a0000200d41186a200241106a290200370200200d41206a200241186a290200370200200d41286a200241086a41186a280200360200200741016a2107410021220b20014184016a280200212c200128028001210d02400240200c20076b20014188016a280200412c6c222d412c6d2212490d00200228020421010c010b200720126a22012007490d0d200c410174222e20012001202e491b222ead422c7e222f422088a70d0d202fa722304100480d0d02400240200c0d002030103221010c010b2002280204200c412c6c2030103421010b2001450d0c20022001360204202e210c0b20012007412c6c6a200d202d109b051a0240202c450d00200d10290b41c0051032220d450d0d2000200136020820004280c2cdeb16370200200241086a410c6a4210370200200041106a200720126a3602002000410c6a200c3602002002200d36021020024280c2cdeb16370308200241106a10eb04200d10292022450d0e0240202b450d00200e202b411c6c6a210c200e210d03400240200d410c6a2802002207450d00200d2802042101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200741706a22070d000b0b0240200d41086a280200450d00200d28020410290b200d411c6a21010240200d41146a280200450d00200d28021010290b2001210d2001200c470d000b0b202a450d0e200e10290c0e0b412c4104102e000b200e4104102e000b20144104102e000b20114104102e000b20194104102e000b20124104102e000b200c4104102e000b20224104102e000b20124104102e000b200c4104102e000b20224104102e000b20304104102e000b1033000b41c0054104102e000b02402029450d0002402028450d002027202841186c6a210c2027210d03400240200d41046a280200450d00200d28020010290b0240200d41146a2802002207450d00200d28020c2101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200741706a22070d000b0b200d41186a21010240200d41106a280200450d00200d28020c10290b2001210d2001200c470d000b0b2026450d00202710290b02402021450d0002402025450d0020242025411c6c6a210c2024210d03400240200d410c6a2802002207450d00200d2802042101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200741706a22070d000b0b0240200d41086a280200450d00200d28020410290b200d411c6a21010240200d41146a280200450d00200d28021010290b2001210d2001200c470d000b0b2023450d00202410290b02402019450d0002402020450d00202041146c2107201f210103400240200141046a280200450d00200128020010290b200141146a21012007416c6a22070d000b0b201e450d00201f10290b0240201d450d000240201c450d00201b201c4104746a210c201b210d03400240200d2802082207450d00200d2802002101200741047421070340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200741706a22070d000b0b200d41106a21010240200d41046a280200450d00200d28020010290b2001210d2001200c470d000b0b201a450d00201b10290b02402016410047201841017371450d00201710290b02402014410047201141017371450d00201510290b0240200f410047201341017371450d00201010290b02402005450d000240200b450d00200b41286c2107200a210103400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141286a2101200741586a22070d000b0b2009450d00200a10290b02402008450d0002402006450d00200641047421072004210103400240200141046a280200450d00200128020010290b200141106a2101200741706a22070d000b0b2003450d00200410290b200241306a24000b860501017f411021010240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200041ff01710eac010001020202020202020202020202020303030404050506060707080809090a0a0b0b0c0d0d0e0e0f0f1010111213131414151516161717181819191a1a1b1b1c1c1d1d1e1e1f1f2020212122222323242425252627272828292a2a2b2b2c2d2d2e2e2f2f303031313232333434353536363737383839393a3a3b3b3c3c3d3d3e3e3f3f40404141424243434444454546464747484a4a4a4a49494a4a4a4a4a4a4a4a4a4a4a4a4a4a4b4b4b4b000b41110f0b41120f0b410a0f0b41080f0b41080f0b41040f0b41040f0b41040f0b41040f0b41040f0b41040f0b41040f0b41050f0b41050f0b41050f0b41050f0b41050f0b41130f0b41140f0b41060f0b41070f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410c0f0b410c0f0b410c0f0b410c0f0b410c0f0b410c0f0b41000f0b41000f0b41010f0b41020f0b41030f0b41030f0b41000f0b41000f0b41000f0b41000f0b41000f0b41000f0b41010f0b41020f0b41030f0b41030f0b41000f0b41000f0b41000f0b41000f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410e0f0b410e0f0b410f21010b20010be00402097f017e230041306b22022400200241106a2203200141246a290200370300200241086a22042001411c6a29020037030020022001290214370300200241186a41106a2205200141106a280200360200200241186a41086a2206200141086a290200370300200220012902003703182000200241186a10d40321070240024002400240200041206a28020022082000411c6a280200470d00200841016a22092008490d032008410174220a20092009200a491b220941ffffffff03712009470d032009410274220a4100480d030240024020080d00200a103221080c010b20002802182008410274200a103421080b2008450d01200020083602182000411c6a2009360200200028022021080b200028021820084102746a20073602002000200028022041016a3602202005200329030037030020062004290300370300200220022903003703180240200041f0006a22032802002208200041ec006a280200470d00200841016a22042008490d0320084101742205200420042005491b2204ad42187e220b422088a70d03200ba722054100480d030240024020080d002005103221080c010b2000280268200841186c2005103421080b2008450d0220002008360268200041ec006a2004360200200041f0006a28020021080b2000280268200841186c6a22082002290318370200200841106a200241186a41106a290300370200200841086a200241186a41086a29030037020020032003280200220841016a360200024020012d002c450d0020004101360254200041d8006a20083602000b200241306a24000f0b200a4104102e000b20054104102e000b1033000bcf0d01067f0240024020002d00002201410d4b0d00024002400240024002400240024002400240024002400240024020010e0e0001020304050607080e090a0b0c000b200041086a280200450d0d200041046a28020010290f0b0240200041086a280200450d00200041046a28020010290b200041146a280200450d0c200041106a28020010290f0b02402000410c6a2802002202450d00200041046a28020021012002410474210203400240200141046a280200450d00200128020010290b200141106a2101200241706a22020d000b0b200041086a280200450d0b200028020410290f0b02402000410c6a2802002202450d00200041046a2802002101200241286c210203400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141286a2101200241586a22020d000b0b200041086a280200450d0a200028020410290f0b200041086a280200450d09200041046a28020010290f0b200041086a280200450d08200041046a28020010290f0b200041086a280200450d07200041046a28020010290f0b02402000410c6a2802002201450d00200041046a280200220320014104746a21040340024020032802082202450d0020032802002101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200241706a22020d000b0b200341106a21010240200341046a280200450d00200328020010290b2001210320012004470d000b0b200041086a280200450d06200028020410290f0b02402000410c6a2802002202450d00200041046a2802002101200241146c210203400240200141046a280200450d00200128020010290b200141146a21012002416c6a22020d000b0b200041086a280200450d05200028020410290f0b02402000410c6a2802002201450d00200041046a28020022032001411c6c6a2104034002402003410c6a2802002202450d0020032802042101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200241706a22020d000b0b0240200341086a280200450d00200328020410290b2003411c6a21010240200341146a280200450d00200328021010290b2001210320012004470d000b0b200041086a280200450d04200028020410290f0b02402000410c6a2802002201450d00200041046a2802002203200141186c6a210403400240200341046a280200450d00200328020010290b0240200341146a2802002202450d00200328020c2101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200241706a22020d000b0b200341186a21010240200341106a280200450d00200328020c10290b2001210320012004470d000b0b200041086a280200450d03200028020410290f0b02402000410c6a2802002201450d00200041046a28020022032001411c6c6a2104034002402003410c6a2802002202450d0020032802042101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200241706a22020d000b0b0240200341086a280200450d00200328020410290b2003411c6a21010240200341146a280200450d00200328021010290b2001210320012004470d000b0b200041086a280200450d02200028020410290f0b0240200041046a2d0000220141024b0d0002400240024020010e03000102000b2000410c6a280200450d04200041086a28020010290f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c21020340024020012802002203450d00200141046a280200450d00200310290b2001410c6a2101200241746a22020d000b0b200041106a280200450d03200028020c10290f0b0240200041146a2802002201450d002000410c6a280200220520014104746a210603402005220441106a2105024020042802042201450d0002402004410c6a2802002202450d002002410c6c21020340024020012802002203450d00200141046a280200450d00200310290b2001410c6a2101200241746a22020d000b0b200441086a280200450d00200428020410290b20052006470d000b0b200041106a280200450d02200028020c10290c020b2000410c6a280200450d01200041086a28020010290f0b0240200041086a280200450d00200041046a28020010290b0240200041146a2802002201450d00200041186a280200450d00200110290b200041246a280200450d00200041206a28020010290f0b0bb07b05087f017e1e7f037e187f23002203210420034180096b41607122032400024002400240024002400240024002400240024002400240024002400240411010322205450d00200541063a0000412010322206450d01200641063a00104100210720064100360204200620032f00f0053b00012006412d3a0000200641036a200341f2056a2d00003a0000024020052d00004109470d00200528020841ffffffff0371450d00200528020410290b20051029200141106a2802002208412c6c21092001280208210a02400340024020092007470d00411010322205450d0520054180023b010c200542828080802037020420052006360200200520032f01d0033b010e024020082001410c6a280200470d00200841016a22072008490d0f20084101742209200720072009491b2207ad422c7e220b422088a70d0f200ba722094100480d0f0240024020080d0020091032210a0c010b200a2008412c6c20091034210a0b200a450d072001200a3602082001410c6a20073602000b2001200841016a220c360210200a2008412c6c6a220741073a0000200720032f00e0043b0001200742818080801037000820072005360004200720032902f005370210200741036a200341e2046a2d00003a0000200741186a200341f8056a290200370200200741206a20034180066a290200370200200741286a200341f0056a41186a2802003602004100210d0c020b200a20076a21052007412c6a220e210720052d00004107470d000b200320032f01d0033b01f0050240200a200e6a220541606a220928020022072005415c6a220a280200470d00200741016a220e2007490d0d20074101742208200e200e2008491b220e41ffffffff0071200e470d0d200e41047422084100480d0d0240024020070d002008103221070c010b200541586a28020020074104742008103421070b2007450d06200a200e360200200541586a2007360200200928020021070b200541586a220528020020074104746a22074180023b010c200742828080802037020420072006360200200720032f01f0053b010e2009200928020041016a360200200341c0006a200510a2032003280244417f6a210d2001280210210c2001280208210a0b200c412c6c2107200a41586a210502400340410021062007450d01200741546a2107200541286a21092005412c6a220e210520092d00004103470d000b200e41086a2802002207450d00200741286c2105200e28020041186a2107410021060340200620072d0000456a2106200741286a2107200541586a22050d000b0b200c412c6c2107200a41586a210502400340410021092007450d01200741546a2107200541286a210e2005412c6a22082105200e2d00004103470d000b200841086a2802002207450d00200741286c2105200828020041186a2107410021090340200920072d0000456a2109200741286a2107200541586a22050d000b0b200c412c6c2107200a41606a210502400340024020070d00410021070c020b200741546a2107200541206a210e2005412c6a220a2105200e2d00004104470d000b200a28020021070b200720096a220f41ffffffff0371200f470d0c200f4102742207417f4c0d0c0240024020070d00410421100c010b2007102d2210450d060b024002400240024002400240200f450d002010200f4102746a211141002112201021130340024020122006490d0020012802102214412c6c220921072001280208221541586a220e2105024003404100210a2007450d01200741546a2107200541286a21082005412c6a220c210520082d00004103470d000b200c41086a2802002207450d00200741286c2105200c28020041186a21074100210a0340200a20072d0000456a210a200741286a2107200541586a22050d000b0b2012200a6b220a20124b0d0303402009450d05200941546a2109200e41286a2107200e412c6a2205210e20072d0000410b470d000b200541086a280200200a4d0d052005280200200a41186c6a2802082105200341f0056a200a200110dd0420032802f405210720032802f0054101460d072013200720056a3602000b201241016a2112201341046a22132011470d000b0b20012802102114200128020821150c0f0b412c10322207450d0a200741286a41002800f2d345360000200741206a41002900ead345370000200741186a41002900e2d345370000200741106a41002900dad345370000200741086a41002900d2d345370000200741002900cad34537000042ac808080c005210b0c020b412c10322207450d0a200741286a410028009ed445360000200741206a4100290096d445370000200741186a410029008ed445370000200741106a4100290086d445370000200741086a41002900fed345370000200741002900f6d34537000042ac808080c005210b0c010b411e10322207450d0a200741166a41002900b8d445370000200741106a41002900b2d445370000200741086a41002900aad445370000200741002900a2d445370000429e808080e003210b0b201010290c0a0b20032903f805210b2010102920070d09410021100c0a0b41104108102e000b41204108102e000b41104104102e000b20094104102e000b20084104102e000b20074104102e000b412c4101102e000b412c4101102e000b411e4101102e000b410021100c030b02402014450d0020152014412c6c6a2116200341e0046a41146a2117200341e0076a2118200341f0056a41017221190340024020152d0000410b470d00201528020c2207450d0020152802042208200741186c6a211a03400240200841146a220c2802002207450d002008410c6a21124100210e0240024002400240024002400340200e20074f0d014101210702402012280200200e41047422136a22052d0000410b470d002003200541046a22053602c0022010450d04200f200528020022054d0d03201020054102746a2802002209450d00201920032f00e0043b0000201941026a200341e0046a41026a2d00003a0000200341123a00f0052003200d3602d407200341133a00d007200341d7003a00c007200320093602b4072003412d3a00b0072003200d3602a407200341123a00a00720032005360294072003410b3a009007200341063a008007200341003a00f00620034184083b01e006200341373a00d006200320023602c4062003412d3a00c0062003200d3602b406200341123a00b0062003200d3602a406200341133a00a006200341d6003a00900620032009360284062003412d3a0080062003200d3602f405200c2802002211200e4d0d05200c200e360200200828020c2107200320183602f804200320123602f0042003200720136a220641106a220a3602e8042003200e41016a22143602e0042003201120146b221b3602e404200320072014410474221c6a221d3602ec042003200341f0056a3602f404200a2107024020062d0000220941ac01460d004100210702400340200620076a21050240200941ff01714109470d00200541086a28020041ffffffff0371450d00200541046a28020010290b2007450d012003200541206a3602e804200741106a2107200541106a2d0000220941ac01470d000b200620076a41106a21070c010b200541106a21070b02402007201d460d00034020032007220541106a22073602e8040240024020052d000022094109460d00200941ac01470d010c030b200541086a28020041ffffffff0371450d00200541046a28020010290b200a2007470d000b0b0240024002400240201b450d000240201420082802142207470d00200341f0056a2107201821060c030b2013200741047422076b2109200828020c20076a2105200341f0056a21072018210a034002402007200a470d00200341ac013a00d0030c050b2003200741106a3602f404200341d0036a200710e30420032d00d00341ac01460d04200520032903d003370300200541086a200341d0036a41086a2903003703002008200828021441016a3602142009450d02200541106a2105200941706a210920032802f804210a20032802f40421070c000b0b2012201710e4040c020b20032802f804210620032802f40421070b0240200620076b2205450d000240024020032802f004220a41046a221d280200220920116b20054104762213490d00200a28020021050c010b201120136a22052011490d1020094101742211200520052011491b221141ffffffff00712011470d102011410474221e4100480d100240024020090d00201e103221050c010b200a2802002009410474201e103421050b2005450d09200a2005360200201d20113602000b2005201420136a22094104746a2005201c6a201b410474109c051a200320093602e0042009200a2802082205460d00200e20136a410474200541047422056b2109200a28020020056a21050340024020072006470d00200341ac013a00d0030c030b2003200741106a3602f404200341d0036a200710e30420032d00d00341ac01460d02200520032903d003370300200541086a200341d0036a41086a290300370300200a200a28020841016a3602082009450d01200541106a2105200941706a210920032802f804210620032802f40421070c000b0b200341003602d803200342083703d003200341d0036a201710e40420032802d003221b20032802d803220541047422066a210a20032802d403211c201b210702402005450d000240024020032802f004221341046a221d280200220720032802e404221420032802e00422056a22116b20064104752209490d00201328020021070c010b201120096a221e2011490d1020074101742211201e201e2011491b221141ffffffff00712011470d102011410474221e4100480d100240024020070d00201e103221070c010b20132802002007410474201e103421070b2007450d0a20132007360200201d20113602000b2007200520096a220941047422116a200720054104746a2014410474109c051a200320093602e004201b2107200920132802082205460d002013280200220720116a211d200720054104746a2109201b21050340024020060d00200a21070c020b200341d0036a41026a2207200541036a2d00003a0000200320052f00013b01d003024020052d0000221441ac01470d00200541106a21070c020b200541046a290200210b2005410c6a2802002111200920143a00002009410c6a2011360200200941046a200b37020020032f01d0032114200941036a20072d00003a0000200941016a20143b00002013201328020841016a360208200641706a2106200541106a22072105200941106a2209201d470d000b0b02402007200a460d0003400240024020072d000022054109460d00200541ac01470d010c030b200741086a28020041ffffffff0371450d00200741046a28020010290b200741106a2207200a470d000b0b201c450d00201b10290b024020032802e804220720032802ec04220a460d00034020032007220541106a22073602e8040240024020052d000022094109460d00200941ac01470d010c030b200541086a28020041ffffffff0371450d00200541046a28020010290b200a2007470d000b0b024020032802e4042207450d00024020032802e004220a20032802f004220641086a22092802002205460d002006280200220620054104746a2006200a4104746a2007410474109c051a0b2009200720056a3602000b024020032d00f0054109470d0020032802f80541ffffffff0371450d0020032802f40510290b024020032d0080064109470d0020032802880641ffffffff0371450d0020032802840610290b024020032d0090064109470d0020032802980641ffffffff0371450d0020032802940610290b024020032d00a0064109470d0020032802a80641ffffffff0371450d0020032802a40610290b024020032d00b0064109470d0020032802b80641ffffffff0371450d0020032802b40610290b024020032d00c0064109470d0020032802c80641ffffffff0371450d0020032802c40610290b024020032d00d0064109470d0020032802d80641ffffffff0371450d0020032802d40610290b024020032d00e0064109470d0020032802e80641ffffffff0371450d0020032802e40610290b024020032d00f0064109470d0020032802f80641ffffffff0371450d0020032802f40610290b024020032d0080074109470d0020032802880741ffffffff0371450d0020032802840710290b024020032d0090074109470d0020032802980741ffffffff0371450d0020032802940710290b024020032d00a0074109470d0020032802a80741ffffffff0371450d0020032802a40710290b024020032d00b0074109470d0020032802b80741ffffffff0371450d0020032802b40710290b024020032d00c0074109470d0020032802c80741ffffffff0371450d0020032802c40710290b024020032d00d0074109470d0020032802d80741ffffffff0371450d0020032802d40710290b410f21070b2007200e6a220e200c2802002207490d000c070b0b41c0d4c500200e20071036000b2003410136028406200342013702f405200341d0d4c5003602f005200341263602d4032003200341d0036a360280062003200341c0026a3602d003200341e0046a200341f0056a10af0420032802e0042207450d0420032902e404210b0c0b0b41fed2c50041cc00109201000b41fcd8c500106d000b201e4108102e000b201e4108102e000b200841186a2208201a470d000b0b2015412c6a22152016470d000b0b200341c8006a41106a200141106a280200221f360200200341c8006a41086a200141086a290200220b37030020032001290200370348201f412c6c2107200ba7222041586a210502400340024020070d00410021090c020b200741546a2107200541286a21092005412c6a220e210520092d00004108470d000b200341386a200e10a20320032802382109200328023c21070b2007410020091b2106201f412c6c2107202041586a21052009410420091b210e02400340024020070d00410021090c020b200741546a2107200541286a21092005412c6a220a210520092d0000410a470d000b200341306a200a10a20320032802302109200328023421070b2007410020091b2108201f412c6c2107202041586a21052009410420091b211a02400340024020070d00410021210c020b200741546a2107200541286a21092005412c6a220a210520092d00004109470d000b200a2802002105410121210b20034200370274200341b0d6c000360270201a2008411c6c6a2122200e200641146c6a2106200341e0046a410272222341266a2124202341186a2125202341086a21264104211e4104212741042113410021124100211b4100212841002129410021170240024002400240410041ff01710e03000102000b410021070c020b410221070c010b410121070b0340024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020070e03000104040b0240201741ff01710e03020300020b20284101470d05410021070c0a0b2021450d0f41002121410221194100211d200521070c1d0b0340024002400240024002402006200e22076b413c4b0d0020072006470d012007210e0c020b200728020c0d03200741146a210e200741106a28020021070c1f0b200741106a21090340200728020c450d02200941146a2109200741146a22072006470d000b2006210e0b20284101470d05410021070c0c0b200941046a210e200928020021070c1c0b200741206a280200450d1a200741346a280200450d19200741d0006a210e200741c8006a280200450d180c000b0b03400240024002402006200e22076b413c4b0d004101211720072006470d012007210e0c210b200728020c0d01200741146a210e200741106a28020021070c180b200741106a210902400340200728020c450d01200941146a2109200741146a22072006470d000b2006210e0c200b200941046a210e200928020021070c170b200741206a280200450d15200741346a280200450d14200741d0006a210e200741c8006a280200450d130c000b0b024002400240201741ff01710e03010200010b20284101470d04410021070c070b0340024002400240024002402006200e22076b413c4b0d0020072006470d012007210e0c020b200728020c0d03200741146a210e200741106a28020021070c160b200741106a21090340200728020c450d02200941146a2109200741146a22072006470d000b2006210e0b20284101470d07410021070c080b200941046a210e200928020021070c130b200741206a280200450d11200741346a280200450d10200741d0006a210e200741c8006a280200450d0f0c000b0b03400240024002402006200e22076b413c4b0d0020072006460d10200741106a21090340200728020c450d02200941146a2109200741146a22072006470d000c110b0b200728020c0d01200741146a210e200741106a28020021070c0e0b200941046a210e200928020021070c0d0b200741206a280200450d0b200741346a280200450d0a200741d0006a210e200741c8006a280200450d090c000b0b410121070c060b410121070c040b410121070c020b410121070b0340024002400240024020070e020001010b201c2029470d01410121070c030b201a2022460d0a200341206a201a10c5042003280220221c450d0a201a411c6a211a201c20032802244102746a21290c010b201c450d09201c28020021074101212841022117201c41046a211c410121190c160b410021070c000b0b0340024002400240024020070e020001010b201c2029470d01410121070c030b201a2022460d09200341286a201a10c5042003280228221c450d09201a411c6a211a201c200328022c4102746a21290c010b201c450d08201c28020021074101212841022117201c41046a211c410121190c150b410021070c000b0b0340024002400240024020070e020001010b201c2029470d0141012128201c2129410121070c030b41022117201a2022460d17200341186a201a10c504201a411c6a211a20032802182207450d182007200328021c4102746a21292007211c0c010b201c41046a21090240201c0d0041022117410121282009211c0c180b201c28020021074100211941022117410121282009211c0c140b410021070c000b0b0340024002400240024020070e020001010b201c2029470d0141012128201c2129410121070c030b41022117201a2022460d16200341106a201a10c504201a411c6a211a20032802102207450d17200720032802144102746a21292007211c0c010b201c41046a21090240201c0d0041022117410121282009211c0c170b201c28020021074100211941022117410121282009211c0c130b410021070c000b0b200741cc006a28020021070c020b2007413c6a210e200741386a28020021070c010b200741286a210e200741246a28020021070b41012117410121190c0d0b200341e0006a41086a200341f0006a41086a2802003602002003200329037037036020032802582206412c6c21072003280250220841586a210502400340410021092007450d01200741546a2107200541286a210e2005412c6a220a2105200e2d00004103470d000b200a41086a2802002207450d00200741286c2105200a28020041186a2107410021090340200920072d0000456a2109200741286a2107200541586a22050d000b0b2006412c6c2107200841606a210502400340024020070d00410021070c020b200741546a2107200541206a210e2005412c6a220a2105200e2d00004104470d000b200a28020021070b200341f0056a41106a2219200341c8006a41106a280200360200200341f0056a41086a200341c8006a41086a290300370300200320032903483703f005200341b0016a200341f0056a10d3030240201b450d002013201b4102746a211b200720096a2114200341f0056a41e0016a211d200341f0056a41d0016a2118200341f0056a41c0016a211c200341f0056a41b0016a2117200341f0056a41a0016a211e200341f0056a4190016a211a200341f0056a4180016a2115200341f0056a41f0006a2101200341f0056a41e0006a2116200341f0056a41d0006a2123200341f0056a41c0006a2121200341f0056a41306a2129200341f0056a41206a2128200341e7046a212203402013220741046a21132007280200210a200341e0006a21072003280264210803402007280200220641086a210520062f0106220c4102742107417f210902400340024020070d00200c21090c020b2005280200210e2007417c6a2107200941016a2109200541046a21050240417f200e200a49200e200a4b1b41016a0e03020001020b0b200641346a20094105746a220c2802182105200c28021c21072003200d3602d407200341133a00d007200341d7003a00c007200320073602b4072003412d3a00b0072003200d3602a407200341123a00a00720032005360294072003410b3a009007200341063a008007200341003a00f00620034184083b01e006200341373a00d006200320023602c4062003412d3a00c0062003200d3602b406200341123a00b0062003200d3602a406200341133a00a006200341d6003a00900620032007360284062003412d3a0080062003200d3602f405200341123a00f005200c280208220641106a220741ffffffff00712007470d1620074104742205417f4c0d16200c41086a21110240024002400240024020050d004108210a0c010b20051032220a450d01201128020021060b024020060d00410021090c030b4100210e410021050340024020052007470d00200741016a22092007490d1a20074101742208200920092008491b220941ffffffff00712009470d1a200941047422084100480d1a0240024020070d0020081032210a0c010b200a200741047420081034210a0b200a450d03200921070b200a200e6a2209410f3a0000200941046a2005360200200941016a20032f01d0033b0000200941036a200341d0036a41026a2d00003a0000200e41106a210e200541016a2209210520062009460d030c000b0b20054108102e000b20084108102e000b02400240024002400240024002400240200720096b410e4d0d002007210e0c010b2009410f6a22052009490d1c2007410174220e20052005200e491b220e41ffffffff0071200e470d1c200e41047422054100480d1c0240024020070d0020051032210a0c010b200a200741047420051034210a0b200a450d010b200341e0046a200341f0056a10e304200a20094104746a220720032903e004370300200741086a200341e0046a41086a2205290300370300200341e0046a201910e304200741186a2005290300370300200720032903e004370310200341e0046a202810e304200741286a2005290300370300200741206a20032903e004370300200341e0046a202910e304200741386a2005290300370300200741306a20032903e004370300200341e0046a202110e304200741c8006a2005290300370300200741c0006a20032903e004370300200341e0046a202310e304200741d8006a2005290300370300200741d0006a20032903e004370300200341e0046a201610e304200741e8006a2005290300370300200741e0006a20032903e004370300200341e0046a200110e304200741f8006a2005290300370300200741f0006a20032903e004370300200341e0046a201510e30420074188016a200529030037030020074180016a20032903e004370300200341e0046a201a10e30420074198016a200529030037030020074190016a20032903e004370300200341e0046a201e10e304200741a8016a2005290300370300200741a0016a20032903e004370300200341e0046a201710e304200741b8016a2005290300370300200741b0016a20032903e004370300200341e0046a201c10e304200741c8016a2005290300370300200741c0016a20032903e004370300200341e0046a201810e304200741d8016a2005290300370300200741d0016a20032903e004370300200341e0046a201d10e304200741e8016a2005290300370300200741e0016a20032903e004370300024002402009410f6a2207200e460d00200e21062007210e0c010b200e41016a2207200e490d1c200e4101742205200720072005491b220641ffffffff00712006470d1c200641047422074100480d1c02400240200e0d0020071032210a0c010b200a200e41047420071034210a0b200a450d020b200a200e4104746a220741063a0000200720032900e004370001200741086a2022290000370000200341e0046a200341b0016a418c01109b051a411010322205450d02200541063a0000200341d0036a200341e0046a418c01109b051a20112802002207417f4c0d1c200c280200210e0240024020070d00410121084101200e2007109b05220e200e2007109b051a2007ad212a410021070c010b200710322208450d042008200e2007109b05210e200710322208450d052008200e2007109b051a200e10292007ad212a0b200341e0046a200341d0036a418c01109b051a200c31000d212b200341d0036a200341e0046a418c01109b051a200341e0046a200341d0036a418c01109b051a200341c0026a200341e0046a418c01109b051a41101032220e450d05200941106a2109200b428080808080804083220b202a84202b422886844280808080800c84212a200e41063a0000200e1029200341d0036a200341c0026a418c01109b051a200341e0046a200341d0036a418c01109b051a024020052d00004109470d00200528020841ffffffff0371450d00200528020410290b20051029200341c0026a200341e0046a418c01109b051a200341e0046a200341c0026a418c01109b051a200341003602fc03200320093602f803200320063602f4032003200a3602f003200341003602ec03200342043702e4032003202a3702dc03200320073602d803200320083602d403200341013602d003200341e0046a200341d0036a10d703200341b0016a200341e0046a418c01109b051a200c4101360210200c2014360214024020032d00f0054109470d0020032802f80541ffffffff0371450d0020032802f40510290b024020032d0080064109470d0020032802880641ffffffff0371450d0020032802840610290b024020032d0090064109470d0020032802980641ffffffff0371450d0020032802940610290b024020032d00a0064109470d0020032802a80641ffffffff0371450d0020032802a40610290b024020032d00b0064109470d0020032802b80641ffffffff0371450d0020032802b40610290b024020032d00c0064109470d0020032802c80641ffffffff0371450d0020032802c40610290b024020032d00d0064109470d0020032802d80641ffffffff0371450d0020032802d40610290b024020032d00e0064109470d0020032802e80641ffffffff0371450d0020032802e40610290b024020032d00f0064109470d0020032802f80641ffffffff0371450d0020032802f40610290b024020032d0080074109470d0020032802880741ffffffff0371450d0020032802840710290b024020032d0090074109470d0020032802980741ffffffff0371450d0020032802940710290b024020032d00a0074109470d0020032802a80741ffffffff0371450d0020032802a40710290b024020032d00b0074109470d0020032802b80741ffffffff0371450d0020032802b40710290b024020032d00c0074109470d0020032802c80741ffffffff0371450d0020032802c40710290b024020032d00d0074109470d0020032802d80741ffffffff0371450d0020032802d40710290b200b4280808080808c0184210b201441016a21142013201b470d080c090b20054108102e000b20074108102e000b41104108102e000b20074101102e000b20074101102e000b41104108102e000b02402008450d002008417f6a2108200620094102746a4194036a21070c010b0b0b4188dac500418001109201000b02402012450d00202710290b200341f0056a200341b0016a418c01109b051a200341e0046a200341f0056a10d5030240200341e0046a41106a2802002207450d0020032802e80422192007412c6c6a211d0340024020192d000041786a220741024b0d0002400240024020070e03000102000b201928020c2207450d0220192802042209200741146c6a211203400240200928020c0d002009280210210c2003280264210d200341e0006a210703402007280200220841286a210e200841086a210520082f010622134102742107417f210a02400340024020070d002013210a0c020b200528020021062007417c6a2107200a41016a210a200e41206a210e200541046a21050240417f2006200c492006200c4b1b41016a0e03020001020b0b0240200e417c6a280200450d002009200e2802003602100c030b4188dbc5004135109201000b200d450d01200d417f6a210d2008200a4102746a4194036a21070c000b0b200941146a22092012470d000c030b0b201928020421082003280264210c200341e0006a210703402007280200220641286a2109200641086a210520062f0106220d4102742107417f210e02400340024020070d00200d210e0c020b2005280200210a2007417c6a2107200e41016a210e200941206a2109200541046a21050240417f200a200849200a20084b1b41016a0e03020001020b0b02402009417c6a280200450d00201920092802003602040c040b4188dbc5004135109201000b200c450d02200c417f6a210c2006200e4102746a4194036a21070c000b0b201928020c2207450d00201928020422112007411c6c6a211b0340024020112802182207450d002011280210220d20074102746a21140340200d221241046a210d201228020021082003280264210c200341e0006a210703402007280200220641286a2109200641086a210520062f010622134102742107417f210e024002400340024020070d002013210e0c020b2005280200210a2007417c6a2107200e41016a210e200941206a2109200541046a21050240417f200a200849200a20084b1b41016a0e03020001020b0b02402009417c6a280200450d00201220092802003602000c020b4188dbc5004135109201000b200c450d00200c417f6a210c2006200e4102746a4194036a21070c010b0b200d2014470d000b0b2011411c6a2211201b470d000b0b2019412c6a2219201d470d000b0b200341ec046a290200210b20032802e004210720032902e404212a20032802602003280264200328026810e604200041106a200b370200200041086a202a37020020002007360204200041003602002010450d14200f450d1420101029200424000f0b200741cc006a28020021070c020b2007413c6a210e200741386a28020021070c010b200741286a210e200741246a28020021070b41012119410021170c080b200741cc006a28020021070c020b2007413c6a210e200741386a28020021070c010b200741286a210e200741246a28020021070b41002119410121170c040b200741cc006a28020021070c020b2007413c6a210e200741386a28020021070c010b200741286a210e200741246a28020021070b41002117410021190b2005211d0b2003200736027c0240024002400240024002400240024002402010450d000240200f20074b0d002003410136028406200342023702f405200341f8d9c5003602f005200341013602d4032003200341d0036a360280062003200341fc006a3602d003200341e0046a200341f0056a10af0420032902e404220b422088a7210920032802e0042114200ba721160c090b201020074102746a2802002205450d04024002400240201b2012460d0020122118201b21120c010b201241016a22092012490d0e2012410174220a20092009200a491b221841ffffffff03712018470d0e201841027422094100480d0e0240024020120d0020091032211e0c010b201e201241027420091034211e0b201e450d01201e2127201e21130b201320124102746a2007360200200341f0056a200328027c2208200341c8006a10e20420032802f805211620032802f4052114024020032802f00522014101470d0020032802fc052109201821120c0a0b20142802082207417f4c0d0e2014280200210c20142d000c211202400240024020070d00410021094101210a0c010b2007210920071032220a450d010b200a200c2007109b05210a200320073602880120032009360284012003200a36028001200320123a008c01200320142d000d3a008d0120034100360290012003200328027c360298012003200536029c010240024002402003280270220741b0d6c000460d00200328027421110c010b20244200370100202341206a420037010020254200370100202341106a42003701002026420037010020234200370100200341f0056a410041e002109a051a41940310322207450d014100211120074100360200200720032903e0043702042007410c6a200341e0046a41086a290300370200200741146a200341e0046a41106a2903003702002007411c6a200341e0046a41186a290300370200200741246a200341e0046a41206a2903003702002007412c6a200341e0046a41286a290300370200200741346a200341f0056a41e002109b051a20034100360274200320073602700b201b41016a211b0340200741146a210920072f010622154102742112417f210a4100210502400340024020122005470d002015210a0c020b200720056a210c200541046a2105200a41016a210a200941206a21090240417f200c41086a280200220c200849200c20084b1b41016a0e03020001020b0b2009290200210b2009200329038001370200200941186a200329039801370200200941106a2207290200212a2007200329039001370200200941086a200329038801370200202a42ffffffff0f83420285500d08200b42808080807083500d08200ba710290c080b02402011450d002011417f6a21112007200a4102746a4194036a28020021070c010b0b2003200328027841016a360278200329039801210b200329039001212a200329038801212b200329038001212c20072f01062209410b490d0420244200370100202341206a222d420037010020254200370100202341106a222e42003701002026420037010020234200370100200341f0056a410041e002109a051a024041940310322205450d0020054100360200200520032903e0043702042005410c6a200341e0046a41086a222f290300370200200541146a200341e0046a41106a22302903003702002005411c6a200341e0046a41186a2231290300370200200541246a200341e0046a41206a22322903003702002005412c6a200341e0046a41286a2233290300370200200541346a200341f0056a41e002109b05210c200341f0056a41086a2211200741fc016a290200370300200341f0056a41106a221520074184026a290200370300200341f0056a41186a22342007418c026a290200370300200320072902f4013703f00520072802202135200541086a200741246a20072f010641796a2209410274109b052112200c20074194026a2009410574109b05210c200741063b0106200520093b01062031203429030037030020302015290300370300202f2011290300370300200320032903f0053703e00402400240200a4107490d002012200a417a6a22364102746a2012200a41796a220a4102746a2212200941ffff0371200a6b410274109c051a20122008360200200c20364105746a200c200a4105746a2209200541066a220c2f0100200a6b410574109c051a200941186a200b3702002009202a3702102009202b3702082009202c370200200c2f010021120c010b200741086a2209200a41016a22364102746a2009200a4102746a2209200741066a220c2f01002212200a6b2237410274109c051a20092008360200200741346a220920364105746a2009200a4105746a22092037410574109c051a200941186a200b3702002009202a3702102009202b3702082009202c3702000b200c201241016a3b0100200341d0036a41186a22382031290300220b370300200341d0036a41106a22392030290300222a370300200341d0036a41086a223a202f290300222b370300200341b0016a41186a223b200b370300200341b0016a41106a223c202a370300200341b0016a41086a223d202b370300200320032903e004220b3703d0032003200b3703b00102402007280200220c0d00200521090c070b20072f010421362005213e0340200341c0026a41186a223f203b290300370300200341c0026a41106a2240203c290300370300200341c0026a41086a2241203d290300370300200320032903b0013703c002203641ffff0371210802400240024002400240200c2f01062207410b490d0020244200370100202d420037010020254200370100202e42003701002026420037010020234200370100203a202f2903003703002039203029030037030020382031290300370300200341d0036a41206a22072032290300370300200341d0036a41286a22052033290300370300200320032903e0043703d003200341f0056a4100419003109a051a41c40310322209450d0320094100360200200920032903d0033702042009410c6a203a290300370200200941146a20392903003702002009411c6a2038290300370200200941246a20072903003702002009412c6a2005290300370200200941346a200341f0056a419003109b052105200c41206a28020021422034200c418c026a2902003703002015200c4184026a2902003703002011200c41fc016a2902003703002003200c41f4016a2902003703f005200941086a200c41246a200c2f0106220a41796a2207410274109b0521432005200c4194026a2007410574109b05214420094194036a200c41b0036a200a417a6a2212410274109b052137200c41063b0106200920073b010602402012450d00410021072037210503402005280200220a20073b0104200a2009360200200541046a21052012200741016a2207470d000b0b20312034290300220b37030020302015290300222a370300202f2011290300222b370300200320032903f005222c3703e0042034200b3703002015202a3703002011202b3703002003202c3703f005203641ffff037122054107490d0120432008417a6a220a41027422126a2043200841796a22074102746a220520092f010620076b410274109c051a200520353602002044200a4105746a204420074105746a220520092f010620076b410574109c051a200541186a203f290300370200200541106a2040290300370200200541086a2041290300370200200520032903c002370200200920092f010641016a22053b01062008410274223620376a416c6a203720126a2212200541ffff03712208200a6b410274109c051a2012203e3602002008200a490d02200920366a41fc026a210503402005280200220a200741016a22073b0104200a2009360200200541046a210520072008490d000c030b0b200c41086a2205200841016a2209410274220a6a2005200841027422126a2205200720086b2211410274109c051a20052035360200200c41346a220520094105746a200520084105746a22052011410574109c051a200541186a203f290300370200200541106a2040290300370200200541086a2041290300370200200520032903c002370200200c200741016a22073b01062012200c4194036a22056a41086a2005200a6a2205200741ffff0371220a20096b410274109c051a2005203e3602002008200a4f0d0c200c2009417f6a22074102746a4198036a2105034020052802002209200741016a22073b01042009200c360200200541046a21052007200a490d000c0d0b0b200c41086a2207200841016a2212410274220a6a2007200841027422366a2207200c2f0106223720086b2243410274109c051a20072035360200200c41346a220720124105746a200720084105746a22072043410574109c051a200741186a203f290300370200200741106a2040290300370200200741086a2041290300370200200720032903c002370200200c203741016a22073b01062036200c4194036a22376a41086a2037200a6a2237200741ffff0371220a20126b410274109c051a2037203e3602002005200a4f0d00200c20366a4198036a2107034020072802002205200841016a22083b01042005200c360200200741046a2107200a2008470d000b0b203b2034290300370300203c2015290300370300203d2011290300370300200320032903f0053703b001200c28020022070d01204221350c090b41c4034104102e000b200c2f010421362007210c204221352009213e0c000b0b4194034104102e000b4194034104102e000b20074101102e000b20094104102e000b41fed2c50041cc00109201000b200741086a2205200a41016a220c4102746a2005200a4102746a22052009200a6b2212410274109c051a20052008360200200741346a2205200c4105746a2005200a4105746a22052012410574109c051a200541186a200b3702002005202a3702102005202b3702082005202c3702002007200941016a3b01060c010b20244200370100202d420037010020254200370100202e42003701002026420037010020234200370100203a202f2903003703002039203029030037030020382031290300370300200341d0036a41206a22052032290300370300200341d0036a41286a220a2033290300370300200320032903e0043703d003200341f0056a4100419003109a051a41c40310322207450d0220074100360200200720032903d0033702042007410c6a203a290300370200200741146a20392903003702002007411c6a2038290300370200200741246a20052903003702002007412c6a200a290300370200200741346a200341f0056a419003109b05210820072003280270220536029403200320073602702003200328027441016a36027420052007360200200541003b0104200820072f0106220a4105746a220520032903b001370200200541186a203b290300370200200541106a203c290300370200200541086a203d2903003702002007200a4102746a41086a203536020020074194036a200a41016a22054102746a2009360200200720053b0106200920053b0104200920073602000b02402001450d002016450d00201410290b201821120b201d2105201941ff01710e03010205010b41c4034104102e000b410021070c040b410221070c030b20032802702003280274200328027810e60402402012450d00201e10290b0240201f450d00201f412c6c2105202021070340200710d8032007412c6a2107200541546a22050d000b0b0240200341d4006a280200450d00202010290b2000201436020420004101360200200041086a2009ad4220862016ad843702002010450d06200f450d0620101029200424000f0b2022211a0b410121070c000b0b1033000b102f000b2000200736020420004101360200200041086a200b37020002402010450d00200f450d00201010290b20012802082105024020012802102203450d002003412c6c2107200521030340200310d8032003412c6a2103200741546a22070d000b0b2001410c6a280200450d00200510290b200424000bc7810203117f017e037f230041d0006b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0f0100021211100f0e0d0c0b09080706010b200141186a2802002104200141146a2802002105200141106a28020021062001410c6a2802002107200141086a2802002108200141046a28020021090240200241046a280200200241086a280200220a460d002002280200210b0c190b200a41016a220b200a490d14200a410174220c200b200b200c491b220c4100480d1402400240200a0d00200c1032210b0c010b2002280200200a200c1034210b0b200b450d042002200b360200200241046a200c360200200241086a280200210a0c180b2001410c6a280200210b200141086a2802002105200141046a280200210420012d0001210d02400240200241046a280200200241086a280200220a460d002002280200210c0c010b200a41016a220c200a490d14200a4101742206200c200c2006491b22064100480d1402400240200a0d0020061032210c0c010b2002280200200a20061034210c0b200c450d032002200c360200200241046a2006360200200241086a280200210a0b200241086a2206200a41016a360200200c200a6a200d3a000002400240200241046a280200220c2006280200220a6b200b490d002002280200210c0c010b200a200b6a220d200a490d14200c410174220a200d200d200a491b220a4100480d1402400240200c0d00200a1032210c0c010b2002280200200c200a1034210c0b200c450d022002200c360200200241046a200a360200200241086a280200210a0b200241086a200a200b6a360200200c200a6a2004200b109b051a4100210d41012107024020050d004101210b0c220b200410294101210b0c210b2001410c6a2802002106200141086a280200210e200141046a280200210f024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d14200a410174220c200b200b200c491b220c4100480d1402400240200a0d00200c1032210b0c010b2002280200200a200c1034210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41013a0000200f20064104746a21104100210c4100210b41002105410121042006210a024003400240200b2005470d00200c200b41016a220d200d200c491b22054100480d1602400240200c0d002005103221040c010b2004200b2005103421040b2004450d020b2004200b6a200a41807f72200a41ff0071200a410776220d1b3a0000200c41026a210c200b41016a210b200d210a200d0d000b024020060d00200f21080c130b200f210a02400340200a41106a2108200a2d000d22114105460d14200a2d000c210c200a2802082109200a2802042112200a28020021130240024002400240024002402005200b470d00200b41016a220a200b490d1c200b410174220d200a200a200d491b22054100480d1c02400240200b0d002005103221040c010b2004200b2005103421040b2004450d010b2004200b6a200c3a0000200b41016a210a200b410174220b41046a2107200b41026a210c2009210b0340200721060240200a2005470d00200a41016a220d200a490d1d200c200d200d200c491b22054100480d1d02400240200a0d002005103221040c010b2004200a2005103421040b2004450d030b2004200a6a200b41807f72200b41ff0071200b410776220d1b3a0000200641026a2107200c41026a210c200a41016a210a200d210b200d0d000b0240024020090d00200a210b0c010b4100210c0340200a200c6a210b41fc00210d02400240024002402013200c6a2d00000e050200010305020b41fe00210d0c020b41fd00210d0c010b41ff00210d0b0240200b2005470d00200b41016a2205200b490d1e2006200520052006491b22054100480d1e02400240200b0d002005103221040c010b2004200b2005103421040b2004450d050b2004200a6a200c6a200d3a0000200641026a21062009200c41016a220c470d000b200a200c6a210b0b20120d030c040b20054101102e000b20054101102e000b20054101102e000b201310290b4100210a024020114104460d0002402005200b470d00200b41016a220a200b490d18200b410174220c200a200a200c491b22054100480d1802400240200b0d002005103221040c010b2004200b2005103421040b2004450d030b2004200b6a41013a0000200b41016a210b201141077141ff0073210a0b024002402005200b470d00200b41016a220c200b490d18200b410174220d200c200c200d491b22054100480d1802400240200b0d002005103221040c010b2004200b2005103421040b2004450d010b2004200b6a200a3a0000200b41016a210b2008210a20082010470d010c160b0b20054101102e000b20054101102e000b20054101102e000b200c4101102e000b200a4101102e000b20064101102e000b200c4101102e000b200141286a2802002108200141246a280200210e200141206a28020021112001411c6a2802002109200141186a2802002110200141146a28020021132001410c6a2902002114200141086a280200210f200141046a28020021120240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d1e200a410174220c200b200b200c491b220c4100480d1e02400240200a0d00200c1032210b0c010b2002280200200a200c1034210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41003a00002014422088a721044101210b4100210a4100210c2014a72207210d024002400240024003400240200c200a470d00200a41016a2205200a490d23200a4101742206200520052006491b22054100480d2302400240200a0d0020051032210b0c010b200b200a20051034210b0b200b450d022005210a0b200b200c6a200d41807f72200d41ff0071200d41077622051b3a0000200c41016a210c2005210d20050d000b200a200c6b20074f0d03200c20076a220d200c490d21200a4101742205200d200d2005491b220d4100480d21200a0d01200d1032210b0c020b20054101102e000b200b200a200d1034210b0b200b450d02200d210a0b200b200c6a20122007109b051a0240200f450d00201210290b2007200c6a210d02400240024003400240200d200a470d00200a41016a220c200a490d22200a4101742205200c200c2005491b220c4100480d2202400240200a0d00200c1032210b0c010b200b200a200c1034210b0b200b450d02200c210a0b200b200d6a200441807f72200441ff00712004410776220c1b3a0000200d41016a210d200c2104200c0d000b20130d01200d210c4101210f0c020b200c4101102e000b2009200d6a210c20092104024002400240024003400240200d200a470d00200a41016a2205200a490d24200a4101742206200520052006491b22054100480d2402400240200a0d0020051032210b0c010b200b200a20051034210b0b200b450d022005210a0b200b200d6a200441807f72200441ff0071200441077622051b3a0000200c41016a210c200d41016a210d2005210420050d000b200a200d6b20094f0d03200d20096a2204200d490d22200a4101742205200420042005491b22044100480d22200a0d0120041032210b0c020b20054101102e000b200b200a20041034210b0b200b450d042004210a0b200b200d6a20132009109b051a4100210f2010450d00201310290b201120084104746a21092008210d0240024003400240200c200a470d00200a41016a2204200a490d21200a4101742205200420042005491b22044100480d2102400240200a0d0020041032210b0c010b200b200a20041034210b0b200b450d022004210a0b200b200c6a200d41807f72200d41ff0071200d41077622041b3a0000200c41016a210c2004210d20040d000b20080d01201121070c1b0b20044101102e000b20112107024003402007220441106a2107200428020022064108460d1b2004410c6a2802002105200441086a280200210d2004280204210402400240024002400240024002400240024020060e080001020304050607000b0240200a200c470d00200a41016a2205200a490d28200a4101742206200520052006491b22054100480d2802400240200a0d0020051032210b0c010b200b200a20051034210b0b200b450d232005210a0b200b200c6a41003a0000200c41016a210c03400240200c200a470d00200a41016a2205200a490d29200a4101742206200520052006491b22054100480d2902400240200a0d0020051032210b0c010b200b200a20051034210b0b200b450d0f2005210a0b200b200c6a200441807f72200441ff0071200441077622051b3a0000200c41016a210c2005210420050d000b024003400240200c200a470d00200a41016a2204200a490d2a200a4101742205200420042005491b22044100480d2a02400240200a0d0020041032210b0c010b200b200a20041034210b0b200b450d022004210a0b200b200c6a200d41807f72200d41ff0071200d41077622041b3a0000200c41016a210c2004210d20040d000c090b0b20044101102e000b0240200a200c470d00200a41016a2205200a490d27200a4101742206200520052006491b22054100480d2702400240200a0d0020051032210b0c010b200b200a20051034210b0b200b450d212005210a0b200b200c6a41013a0000200c41016a210c03400240200c200a470d00200a41016a2205200a490d28200a4101742206200520052006491b22054100480d2802400240200a0d0020051032210b0c010b200b200a20051034210b0b200b450d0f2005210a0b200b200c6a200441807f72200441ff0071200441077622051b3a0000200c41016a210c2005210420050d000b024003400240200c200a470d00200a41016a2204200a490d29200a4101742205200420042005491b22044100480d2902400240200a0d0020041032210b0c010b200b200a20041034210b0b200b450d022004210a0b200b200c6a200d41807f72200d41ff0071200d41077622041b3a0000200c41016a210c2004210d20040d000c080b0b20044101102e000b0240200a200c470d00200a41016a2205200a490d26200a4101742206200520052006491b22054100480d2602400240200a0d0020051032210b0c010b200b200a20051034210b0b200b450d1f2005210a0b200b200c6a41023a0000200c41016a210c03400240200c200a470d00200a41016a2205200a490d27200a4101742206200520052006491b22054100480d2702400240200a0d0020051032210b0c010b200b200a20051034210b0b200b450d0f2005210a0b200b200c6a200441807f72200441ff0071200441077622051b3a0000200c41016a210c2005210420050d000b024003400240200c200a470d00200a41016a2204200a490d28200a4101742205200420042005491b22044100480d2802400240200a0d0020041032210b0c010b200b200a20041034210b0b200b450d022004210a0b200b200c6a200d41807f72200d41ff0071200d41077622041b3a0000200c41016a210c2004210d20040d000c070b0b20044101102e000b0240200a200c470d00200a41016a2206200a490d25200a4101742208200620062008491b22064100480d2502400240200a0d0020061032210b0c010b200b200a20061034210b0b200b450d1d2006210a0b200b200c6a41033a0000200c41016a210c03400240200c200a470d00200a41016a2206200a490d26200a4101742208200620062008491b22064100480d2602400240200a0d0020061032210b0c010b200b200a20061034210b0b200b450d0f2006210a0b200b200c6a200441807f72200441ff0071200441077622061b3a0000200c41016a210c2006210420060d000b03400240200c200a470d00200a41016a2204200a490d26200a4101742206200420042006491b22044100480d2602400240200a0d0020041032210b0c010b200b200a20041034210b0b200b450d102004210a0b200b200c6a200d41807f72200d41ff0071200d41077622041b3a0000200c41016a210c2004210d20040d000b02402005410775220d200541c0007122047245200d417f4720044572734101470d0003400240200c200a470d00200a41016a2204200a490d27200a4101742206200420042006491b22044100480d2702400240200a0d0020041032210b0c010b200b200a20041034210b0b200b450d122004210a0b200b200c6a200541807f723a0000200d41c000712104200c41016a210c200d2105200d4107752206210d2006200472452006417f4720044572470d000b0b02400240200a200c470d00200a41016a220d200a490d26200a4101742204200d200d2004491b220d4100480d2602400240200a0d00200d1032210b0c010b200b200a200d1034210b0b200b450d01200d210a0b200b200c6a200541ff00713a0000200c41016a210c0c050b200d4101102e000b0240200a200c470d00200a41016a2206200a490d24200a4101742208200620062008491b22064100480d2402400240200a0d0020061032210b0c010b200b200a20061034210b0b200b450d1b2006210a0b200b200c6a41043a0000200c41016a210c03400240200c200a470d00200a41016a2206200a490d25200a4101742208200620062008491b22064100480d2502400240200a0d0020061032210b0c010b200b200a20061034210b0b200b450d112006210a0b200b200c6a200441807f72200441ff0071200441077622061b3a0000200c41016a210c2006210420060d000b03400240200c200a470d00200a41016a2204200a490d25200a4101742206200420042006491b22044100480d2502400240200a0d0020041032210b0c010b200b200a20041034210b0b200b450d122004210a0b200b200c6a200d41807f72200d41ff0071200d41077622041b3a0000200c41016a210c2004210d20040d000b02402005410775220d200541c0007122047245200d417f4720044572734101470d0003400240200c200a470d00200a41016a2204200a490d26200a4101742206200420042006491b22044100480d2602400240200a0d0020041032210b0c010b200b200a20041034210b0b200b450d142004210a0b200b200c6a200541807f723a0000200d41c000712104200c41016a210c200d2105200d4107752206210d2006200472452006417f4720044572470d000b0b02400240200a200c470d00200a41016a220d200a490d25200a4101742204200d200d2004491b220d4100480d2502400240200a0d00200d1032210b0c010b200b200a200d1034210b0b200b450d01200d210a0b200b200c6a200541ff00713a0000200c41016a210c0c040b200d4101102e000b0240200a200c470d00200a41016a2206200a490d23200a4101742208200620062008491b22064100480d2302400240200a0d0020061032210b0c010b200b200a20061034210b0b200b450d192006210a0b200b200c6a41053a0000200c41016a210c03400240200c200a470d00200a41016a2206200a490d24200a4101742208200620062008491b22064100480d2402400240200a0d0020061032210b0c010b200b200a20061034210b0b200b450d132006210a0b200b200c6a200441807f72200441ff0071200441077622061b3a0000200c41016a210c2006210420060d000b03400240200c200a470d00200a41016a2204200a490d24200a4101742206200420042006491b22044100480d2402400240200a0d0020041032210b0c010b200b200a20041034210b0b200b450d142004210a0b200b200c6a200d41807f72200d41ff0071200d41077622041b3a0000200c41016a210c2004210d20040d000b02402005410775220d200541c0007122047245200d417f4720044572734101470d0003400240200c200a470d00200a41016a2204200a490d25200a4101742206200420042006491b22044100480d2502400240200a0d0020041032210b0c010b200b200a20041034210b0b200b450d162004210a0b200b200c6a200541807f723a0000200d41c000712104200c41016a210c200d2105200d4107752206210d2006200472452006417f4720044572470d000b0b02400240200a200c470d00200a41016a220d200a490d24200a4101742204200d200d2004491b220d4100480d2402400240200a0d00200d1032210b0c010b200b200a200d1034210b0b200b450d01200d210a0b200b200c6a200541ff00713a0000200c41016a210c0c030b200d4101102e000b0240200a200c470d00200a41016a2205200a490d22200a4101742206200520052006491b22054100480d2202400240200a0d0020051032210b0c010b200b200a20051034210b0b200b450d172005210a0b200b200c6a41063a0000200c41016a210c03400240200c200a470d00200a41016a2205200a490d23200a4101742206200520052006491b22054100480d2302400240200a0d0020051032210b0c010b200b200a20051034210b0b200b450d152005210a0b200b200c6a200441807f72200441ff0071200441077622051b3a0000200c41016a210c2005210420050d000b024003400240200c200a470d00200a41016a2204200a490d24200a4101742205200420042005491b22044100480d2402400240200a0d0020041032210b0c010b200b200a20041034210b0b200b450d022004210a0b200b200c6a200d41807f72200d41ff0071200d41077622041b3a0000200c41016a210c2004210d20040d000c030b0b20044101102e000b0240200a200c470d00200a41016a2205200a490d21200a4101742206200520052006491b22054100480d2102400240200a0d0020051032210b0c010b200b200a20051034210b0b200b450d152005210a0b200b200c6a41073a0000200c41016a210c03400240200c200a470d00200a41016a2205200a490d22200a4101742206200520052006491b22054100480d2202400240200a0d0020051032210b0c010b200b200a20051034210b0b200b450d152005210a0b200b200c6a200441807f72200441ff0071200441077622051b3a0000200c41016a210c2005210420050d000b03400240200c200a470d00200a41016a2204200a490d22200a4101742205200420042005491b22044100480d2202400240200a0d0020041032210b0c010b200b200a20041034210b0b200b450d042004210a0b200b200c6a200d41807f72200d41ff0071200d41077622041b3a0000200c41016a210c2004210d20040d000b0b20072009470d000b200921070c1a0b20044101102e000b200c4101102e000b200d4101102e000b20044101102e000b20054101102e000b20054101102e000b20054101102e000b20064101102e000b20044101102e000b20044101102e000b20064101102e000b20044101102e000b20044101102e000b20064101102e000b20044101102e000b20044101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20064101102e000b20064101102e000b20064101102e000b20054101102e000b20054101102e000b20054101102e000b0240034020092007460d012007280200210d200741106a2107200d4108470d000b0b0240200e450d00201110290b200241086a2106200241046a2107200c21040240024003400240024020072802002006280200220d460d00200228020021050c010b200d41016a2205200d490d07200d4101742208200520052008491b22084100480d0702400240200d0d002008103221050c010b2002280200200d2008103421050b2005450d0220022005360200200720083602002006280200210d0b2006200d41016a3602002005200d6a200441807f72200441ff00712004410776220d1b3a0000200d2104200d0d000b02400240200241046a2802002204200241086a280200220d6b200c490d00200228020021040c010b200d200c6a2205200d490d062004410174220d20052005200d491b220d4100480d060240024020040d00200d103221040c010b20022802002004200d103421040b2004450d0220022004360200200241046a200d360200200241086a280200210d0b200241086a200d200c6a3602002004200d6a200b200c109b051a0240200a450d00200b10290b410021124101210702402013450d00200f450d002010450d00201310290b4101210d4101210b4101210c4101210641012104410121054101210241012108410121094101211041012113410121110c280b20084101102e000b200d4101102e000b200141146a280200210f200141106a28020021112001410c6a2802002113200141086a2802002110200141056a2d0000210c200141046a2d0000210902400240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d0c200a410174220d200b200b200d491b220d4100480d0c02400240200a0d00200d1032210b0c010b2002280200200a200d1034210b0b200b450d012002200b360200200241046a200d360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41003a00000240410410322212450d00201241eec2b5ab06360000024020090e0400050403000b410121064100210a4100210b2011210c034002400240200a200b460d00200a21070c010b200a41016a220b200a490d0e200a410174220d200b200b200d491b22074100480d0e02400240200a0d002007103221060c010b2006200a2007103421060b02402006450d00200a210b2007210a0c010b20074101102e000b2006200b6a200c41807f72200c41ff0071200c410776220d1b3a0000200b41016a210b200d210c200d0d000b0240024002402007200b6b20114f0d00200b20116a220a200b490d0f2007410174220c200a200a200c491b220a4100480d0f0240024020070d00200a103221060c010b20062007200a103421060b2006450d01200a21070b2006200b6a20102011109b051a200b20116a21084101210e20130d010c080b200a4101102e000b201010290c060b41044101102e000b200d4101102e000b410021154101210e20102106201321072011210841012116410121170c040b2003410036023020034201370328410121044100210c4100210a2010210b02400240024002400240024003400240200a200c470d00200c41016a220d200c490d10200c4101742205200d200d2005491b220d4100480d1002400240200c0d00200d103221040c010b2004200c200d103421040b2004450d022003200d36022c20032004360228200d210c0b2003200a41016a22053602302004200a6a200b41807f72200b41ff0071200b410776220d1b3a00002005210a200d210b200d0d000b2013200f4104746a21060240200f0d002013210d0c040b2013210d2010450d03200641706a21162010210e4100210a2013210803402008210d02400340200d41046a28020022070d01200a41016a210a2006200d41106a220d470d000c070b0b200d41106a2108200a41016a2115200e417f6a210e200d41086a2902002114200d2802002117200328022c210c2003280230210b02400240034002400240200b200c460d00200328022821040c010b200c41016a2204200c490d13200c4101742205200420042005491b22054100480d1302400240200c0d002005103221040c010b2003280228200c2005103421040b2004450d022003200536022c200320043602282005210c0b2003200b41016a22053602302004200b6a200a41807f72200a41ff0071200a41077622041b3a00002005210b2004210a20040d000b200320143703082003200736020420032017360200200341c0006a2003200341286a10b20420032d00402204411a460d010c040b20054101102e000b2016200d460d032015210a200e0d000c030b0b200d4101102e000b20032d0043210e20032f0041211720032802442105200329034821140240200641706a200d460d00200d41106a210d0340200d220a41106a210d0240200a2802042207450d00200a28020821080240200a410c6a280200220a450d00200a410c6c210b2007210a03400240200a280200220c450d00200a41046a280200450d00200c10290b200a410c6a210a200b41746a220b0d000b0b2008450d00200710290b200d2006470d000b0b02402011450d00201310290b2004411a460d03200e411074210a0240200328022c450d00200328022810290b2017200a72210a02400240200941024b0d000240024020090e03000109000b2013450d080c020b0240200f450d00200f410c6c210c2013210b03400240200b280200220d450d00200b41046a280200450d00200d10290b200b410c6a210b200c41746a220c0d000b0b02402011450d00201310290b2004411a470d074101210441002108410021050c0a0b2013450d060b201010290c050b200d41106a210d0b200d2006460d000340200d220a41106a210d0240200a2802042204450d00200a28020821050240200a410c6a280200220a450d00200a410c6c210b2004210a03400240200a280200220c450d00200a41046a280200450d00200c10290b200a410c6a210a200b41746a220b0d000b0b2005450d00200410290b200d2006470d000b0b2011450d00201310290b20032802302108200328022c2107200328022821064102210c410021164101210e41002117410021150c030b4100210e20034100360230200342013703282003410c6a200f360200200341086a20113602002003201336020420032010360200200341c0006a2003200341286a10b204024020032d00402204411a460d0020032d0043411074210a20032f0041210b200341c0006a41086a2903002114200328024421050240200328022c450d00200328022810290b200b200a72210a0c010b20032802302108200328022c2107200328022821064101211641002117410021154101210c0c020b200041086a2014370200200041046a20053602002000200a410874200472360200201210290c030b4100211741012116410121154100210c0b024002400240410110322204450d002004200c3a00004101210a4101210b2008210c034002400240200a200b460d00200a21050c010b200a41016a220b200a490d09200a410174220d200b200b200d491b22054100480d0902400240200a0d002005103221040c010b2004200a2005103421040b2004450d03200a210b2005210a0b2004200b6a200c41807f72200c41ff0071200c410776220d1b3a0000200b41016a210b200d210c200d0d000b02402005200b6b20084f0d00200b20086a220a200b490d082005410174220c200a200a200c491b220a4100480d080240024020050d00200a103221040c010b20042005200a103421040b2004450d03200a21050b2004200b6a20062008109b051a02402007450d00200610290b200b20086a21080240200941024b0d00024002400240024020090e03000102000b2015201345720d07201010290c070b200e450d060240200f450d00200f410c6c210b2013210a03400240200a280200220c450d00200a41046a280200450d00200c10290b200a410c6a210a200b41746a220b0d000b0b20110d010c060b2016450d050240200f450d002013200f4104746a21072013210603402006220d41106a21060240200d280204220a450d000240200d410c6a280200220b450d00200b410c6c210b03400240200a280200220c450d00200a41046a280200450d00200c10290b200a410c6a210a200b41746a220b0d000b0b200d41086a280200450d00200d28020410290b20062007470d000b0b2011450d050b201310290c040b2017201345720d03201010290c030b41014101102e000b20054101102e000b200a4101102e000b200341146a2008360200200341106a20053602002003200436020c20034284808080c00037020420032012360200200341c0006a2003200210b904200320032900413703282003200341c0006a41086a29000037002f024020032d0040220a411a470d0041002111410121074101210d4101210b4101210c4101210641012104410121054101210241012108410121094101211041012113410121120c270b2000200a3a000020002003290328370001200041086a200329002f3700000b410021084101210d4101210c4101210b41012106410121074101210441012105410121020c190b2001410c6a2802002105200141086a2802002113200141046a28020021090240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d0a200a410174220c200b200b200c491b220c4100480d0a02400240200a0d00200c1032210b0c010b2002280200200a200c1034210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a410b3a0000200341cc006a4100360200200342013702442003200236024020092005411c6c6a21074100210a4100210b2005210c034002400240200a200b460d002003280244210a0c010b200a41016a220d200a490d0b200a4101742204200d200d2004491b220d4100480d0b02400240200a0d00200d1032210a0c010b2003280244200a200d1034210a0b200a450d032003200d3602482003200a3602440b2003200b41016a36024c200a200b6a200c41807f72200c41ff0071200c410776220c1b3a00000240200c450d002003280248210a200328024c210b200c210c0c010b0b200921042005450d062009210a0340200a411c6a2104200a2802042202450d07200a41186a2802002105200a41146a2802002108200a41086a2902002114200a280200210b200a28021021060340024002402003280248200328024c220a460d002003280244210c0c010b200a41016a220c200a490d0c200a410174220d200c200c200d491b220d4100480d0c02400240200a0d00200d1032210c0c010b2003280244200a200d1034210c0b200c450d052003200d3602482003200c360244200328024c210a0b2003200a41016a36024c200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b2003201437022c200320023602282003200341286a200341c0006a10a704024020032d0000220c411a470d002005210b0340024002402003280248200328024c220a460d002003280244210c0c010b200a41016a220c200a490d0d200a410174220d200c200c200d491b220d4100480d0d02400240200a0d00200d1032210c0c010b2003280244200a200d1034210c0b200c450d072003200d3602482003200c360244200328024c210a0b2003200a41016a36024c200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024002402003280248220b200328024c220a6b2005490d002003280244210b0c010b200a20056a220c200a490d0c200b410174220a200c200c200a491b220a4100480d0c02400240200b0d00200a1032210b0c010b2003280244200b200a1034210b0b200b450d072003200a3602482003200b360244200328024c210a0b2003200a20056a36024c200b200a6a20062005109b051a02402008450d00200610290b2004210a20042007470d010c090b0b20032d0003211220032f0001211020032903082114200328020421112008450d05200610290c050b200c4101102e000b200d4101102e000b200d4101102e000b200d4101102e000b200a4101102e000b024020042007460d0003402004280204220d450d01200441146a2802002105200441086a28020021062004280210210202402004410c6a280200220a450d00200a410474210b200d210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200b41706a220b0d000b0b02402006450d00200d10290b2004411c6a210402402005450d00200210290b20042007470d000b0b2012411074210a02402013450d00200910290b2010200a72210a02402003280248450d00200328024410290b2000200a3b00012000200c3a0000200041036a200a4110763a0000200041086a2014370000200041046a2011360000410021024101210d4101210c4101210b410121064101210741012104410121050c190b20042007460d0003402004280204220c450d01200441146a280200210d200441086a28020021052004280210210602402004410c6a280200220a450d00200a410474210b200c210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200b41706a220b0d000b0b02402005450d00200c10290b2004411c6a21040240200d450d00200610290b20042007470d000b0b02402013450d00200910290b20032802482108200328024421022003280240220441086a210d200441046a2105200328024c2207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d05200a4101742206200c200c2006491b22064100480d0502400240200a0d0020061032210c0c010b2004280200200a20061034210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d04200b410174220a200c200c200a491b220a4100480d0402400240200b0d00200a1032210b0c010b2004280200200b200a1034210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109b051a02402008450d00200210290b41002113410121074101210d4101210b4101210c410121064101210441012105410121024101210841012109410121100c250b20064101102e000b200a4101102e000b2001410c6a2802002105200141086a2802002117200141046a280200210e024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d10200a410174220c200b200b200c491b220c4100480d1002400240200a0d00200c1032210b0c010b2002280200200a200c1034210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a410a3a0000200341246a41003602002003420137021c20032002360218200e200541186c6a210f4100210a4100210b2005210c0240034002400240200a200b460d00200328021c210a0c010b200a41016a220d200a490d12200a4101742204200d200d2004491b220d4100480d1202400240200a0d00200d1032210a0c010b200328021c200a200d1034210a0b200a450d022003200d3602202003200a36021c0b2003200b41016a360224200a200b6a200c41807f72200c41ff0071200c410776220c1b3a00000240200c450d002003280220210a2003280224210b200c210c0c010b0b200e21092005450d0320034101722102200341026a2107200e210a02400340200a41186a2109200a2802002208450d05200a41146a2802002111200a41106a2802002112200a28020c2113200a29020421144100210b200341003602342003420137022c20082014422088a7220c4103746a21062003200341186a3602282014a721104100210a0240024002400240034002400240200b200a460d00200328022c210b0c010b200b41016a220a200b490d18200b410174220d200a200a200d491b220a4100480d1802400240200b0d00200a1032210b0c010b200328022c200b200a1034210b0b200b450d022003200a3602302003200b36022c2003280234210a0b2003200a41016a360234200b200a6a200c41807f72200c41ff0071200c410776220c1b3a00000240200c450d002003280230210b2003280234210a200c210c0c010b0b024020062008470d00200821040c040b2008210a0340200a41086a2104200a2902002214422088a7220a41ff01714104460d04200a41187441187521052014a7210b03400240024020032802302003280234220a460d00200328022c210c0c010b200a41016a220c200a490d19200a410174220d200c200c200d491b220d4100480d1902400240200a0d00200d1032210c0c010b200328022c200a200d1034210c0b200c450d042003200d3602302003200c36022c2003280234210a0b2003200a41016a360234200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b0240024020032802302003280234220a460d00200328022c210b0c010b200a41016a220b200a490d18200a410174220c200b200b200c491b220c4100480d1802400240200a0d00200c1032210b0c010b200328022c200a200c1034210b0b200b450d042003200c3602302003200b36022c2003280234210a0b2003200a41016a360234200b200a6a2005417f73220a413f7141c00072200a2005417f4a1b3a00002004210a20042006470d000b200621040c030b200a4101102e000b200d4101102e000b200c4101102e000b0240034020062004460d0120042d0004210a200441086a2104200a4104470d000b0b02402010450d00200810290b20132011410474220a6a210d02400240024020110d002013210a0c010b201341186a210b200a41706a21042013210a0340200a2d0000210c2007200a41036a2d00003a00002003200a41016a2f00003b01000240200c41ac01470d00200a41106a210a0c020b2003413c6a41026a20072d000022053a0000200320032f010022063b013c200a41046a2902002114200a410c6a2802002108200220063b0000200241026a20053a00002003200c3a00002003200836020c20032014370204200341c0006a2003200341286a10b104024020032d00402205411a46220c450d00200b41106a210b200441706a2104200a41106a220a200d470d010c030b0b20032d0043210820032f00412111200328024421062003290348211402402004450d00034002400240200b41786a220a2d000022044109460d00200441ac01470d010c030b200b28020041ffffffff0371450d00200a41046a28020010290b200b41106a210b200a41106a200d470d000b0b02402012450d00201310290b02402003280230450d00200328022c10290b200c450d062009210a2009200f470d020c080b200a200d460d00034002400240200a2d0000220b4109460d00200b41ac01470d010c030b200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a220a200d470d000b0b02402012450d00201310290b20032802302111200328022c21132003280228210c20032802342208210b0240034002400240200c41086a2205280200200c410c6a2204280200220a460d00200c280204210d0c010b200a41016a220d200a490d15200a4101742206200d200d2006491b22064100480d1502400240200a0d0020061032210d0c010b200c280204200a20061034210d0b200d450d02200c200d360204200520063602002004280200210a0b2004200a41016a360200200d200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024002402005280200220b2004280200220a6b2008490d00200c280204210b0c010b200a20086a220d200a490d14200b410174220a200d200d200a491b220a4100480d1402400240200b0d00200a1032210b0c010b200c280204200b200a1034210b0b200b450d03200c200b3602042005200a3602002004280200210a0b2004200a20086a360200200b200a6a20132008109b051a02402011450d00201310290b2009210a2009200f470d010c070b0b20064101102e000b200a4101102e000b200d4101102e000b200c4101102e000b02402009200f460d0003402009280200220b450d01200941146a280200210a200941106a280200210d200928020c210c02402009280204450d00200b10290b0240200a450d00200a410474210b200c210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200b41706a220b0d000b0b200941186a21090240200d450d00200c10290b2009200f470d000b0b2008411074210a02402017450d00200e10290b2011200a72210a02402003280220450d00200328021c10290b2000200a3b0001200020053a0000200041036a200a4110763a0000200041086a2014370000200041046a2006360000410021054101210d4101210c4101210b4101210641012107410121040c170b2009200f460d0003402009280200220b450d01200941146a280200210a200941106a280200210d200928020c210c02402009280204450d00200b10290b0240200a450d00200a410474210b200c210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200b41706a220b0d000b0b200941186a21090240200d450d00200c10290b2009200f470d000b0b02402017450d00200e10290b20032802202108200328021c21022003280218220441086a210d200441046a210520032802242207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d04200a4101742206200c200c2006491b22064100480d0402400240200a0d0020061032210c0c010b2004280200200a20061034210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d03200b410174220a200c200c200a491b220a4100480d0302400240200b0d00200a1032210b0c010b2004280200200b200a1034210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109b051a02402008450d00200210290b41002110410121074101210d4101210b4101210c4101210641012104410121054101210241012108410121090c230b20064101102e000b200a4101102e000b1033000b2001410c6a2802002105200141086a2802002113200141046a28020021090240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d12200a410174220c200b200b200c491b220c4100480d1202400240200a0d00200c1032210b0c010b2002280200200a200c1034210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41093a0000200341cc006a4100360200200342013702442003200236024020092005411c6c6a21024100210a4100210b2005210c034002400240200a200b460d002003280244210a0c010b200a41016a220d200a490d13200a4101742204200d200d2004491b220d4100480d1302400240200a0d00200d1032210a0c010b2003280244200a200d1034210a0b200a450d032003200d3602482003200a3602440b2003200b41016a36024c200a200b6a200c41807f72200c41ff0071200c410776220c1b3a00000240200c450d002003280248210a200328024c210b200c210c0c010b0b200921062005450d062009210a0340200a411c6a2106200a2802042205450d07200a41186a2802002104200a41146a2802002108200a41086a2902002114200a2802102107200a280200210b0340024002402003280248200328024c220a460d002003280244210c0c010b200a41016a220c200a490d14200a410174220d200c200c200d491b220d4100480d1402400240200a0d00200d1032210c0c010b2003280244200a200d1034210c0b200c450d052003200d3602482003200c360244200328024c210a0b2003200a41016a36024c200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b2003201437022c200320053602282003200341286a200341c0006a10a704024020032d0000220c411a470d00200720044102746a21052004210b0340024002402003280248200328024c220a460d002003280244210c0c010b200a41016a220c200a490d15200a410174220d200c200c200d491b220d4100480d1502400240200a0d00200d1032210c0c010b2003280244200a200d1034210c0b200c450d072003200d3602482003200c360244200328024c210a0b2003200a41016a36024c200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02402004450d002007210403402004280200210b0340024002402003280248200328024c220a460d002003280244210c0c010b200a41016a220c200a490d17200a410174220d200c200c200d491b220d4100480d1702400240200a0d00200d1032210c0c010b2003280244200a200d1034210c0b200c450d0a2003200d3602482003200c360244200328024c210a0b2003200a41016a36024c200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b200441046a22042005470d000b0b02402008450d00200710290b2006210a20062002470d010c090b0b20032d0003211220032f0001211020032903082114200328020421112008450d05200710290c050b200c4101102e000b200d4101102e000b200d4101102e000b200d4101102e000b200d4101102e000b024020062002460d0003402006280204220d450d01200641146a2802002104200641086a28020021052006280210210702402006410c6a280200220a450d00200a410474210b200d210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200b41706a220b0d000b0b02402005450d00200d10290b2006411c6a210602402004450d00200710290b20062002470d000b0b2012411074210a02402013450d00200910290b2010200a72210a02402003280248450d00200328024410290b2000200a3b00012000200c3a0000200041036a200a4110763a0000200041086a2014370000200041046a2011360000410021044101210d4101210c4101210b41012106410121070c140b20062002460d0003402006280204220c450d01200641146a280200210d200641086a28020021042006280210210502402006410c6a280200220a450d00200a410474210b200c210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200b41706a220b0d000b0b02402004450d00200c10290b2006411c6a21060240200d450d00200510290b20062002470d000b0b02402013450d00200910290b20032802482108200328024421022003280240220441086a210d200441046a2105200328024c2207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d0d200a4101742206200c200c2006491b22064100480d0d02400240200a0d0020061032210c0c010b2004280200200a20061034210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d0c200b410174220a200c200c200a491b220a4100480d0c02400240200b0d00200a1032210b0c010b2004280200200b200a1034210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109b051a02402008450d00200210290b41002109410121074101210d4101210b4101210c41012106410121044101210541012102410121080c200b20064101102e000b200a4101102e000b200141046a280200210a0240024002400240024002400240200241046a280200200241086a280200220b460d002002280200210c0c010b200b41016a220c200b490d0e200b410174220d200c200c200d491b220d4100480d0e02400240200b0d00200d1032210c0c010b2002280200200b200d1034210c0b200c450d012002200c360200200241046a200d360200200241086a280200210b0b200241086a200b41016a360200200c200b6a41083a00004100210c4100210b410021064101210503400240200b2006470d00200c200b41016a220d200d200c491b22064100480d0f02400240200c0d002006103221050c010b2005200b2006103421050b2005450d050b2005200b6a200a41807f72200a41ff0071200a410776220d1b3a0000200c41026a210c200b41016a210b200d210a200d0d000b200b417f6a2109200241086a2104200241046a2107200b210c03400240024020072802002004280200220a460d002002280200210d0c010b200a41016a220d200a490d0f200a4101742208200d200d2008491b22084100480d0f02400240200a0d0020081032210d0c010b2002280200200a20081034210d0b200d450d032002200d360200200720083602002004280200210a0b2004200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200241046a280200220c200241086a280200220a6b20094d0d002002280200210c0c010b200a200b6a220d200a490d0e200c410174220a200d200d200a491b220a4100480d0e02400240200c0d00200a1032210c0c010b2002280200200c200a1034210c0b200c450d032002200c360200200241046a200a360200200241086a280200210a0b200241086a200a200b6a360200200c200a6a2005200b109b051a410121072006450d04200510290c040b200d4101102e000b20084101102e000b200a4101102e000b20064101102e000b4101210d4101210b0c160b2001410c6a2802002106200141086a280200210f200141046a2802002110024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d0f200a410174220c200b200b200c491b220c4100480d0f02400240200a0d00200c1032210b0c010b2002280200200a200c1034210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41073a00002010200641146c6a2112410021044100210a4100210c4101210b2006210d03400240200a200c470d002004200a41016a220c200c2004491b220c4100480d100240024020040d00200c1032210b0c010b200b200a200c1034210b0b200b450d030b200b200a6a200d41807f72200d41ff0071200d41077622051b3a0000200441026a2104200a41016a210a2005210d20050d000b024020060d00201021080c060b201021040340200441146a2108200428020c22134104460d062004280204211120042802002109200a4101742105200441106a280200210d20042802082207210403400240200a200c470d00200a41016a220c200a490d112005200c200c2005491b220c4100480d1102400240200a0d00200c1032210b0c010b200b200a200c1034210b0b200b450d050b200b200a6a200441807f72200441ff0071200441077622061b3a0000200541026a2105200a41016a210a2006210420060d000b0240024002400240200c200a6b20074f0d00200a20076a2204200a490d13200c4101742205200420042005491b22044100480d1302400240200c0d0020041032210b0c010b200b200c20041034210b0b200b450d012004210c0b200b200a6a20092007109b051a2007200c6b200a6a210402402011450d00200910290b20040d02200c41016a2204200c490d12200c4101742205200420042005491b220441004e0d010c120b20044101102e000b02400240200c0d0020041032210b0c010b200b200c20041034210b0b200b450d052004210c0b200b20076a200a6a20133a00002007200a6a41016a210a03400240200a200c470d00200a41016a220c200a490d11200a4101742204200c200c2004491b220c4100480d1102400240200a0d00200c1032210b0c010b200b200a200c1034210b0b200b450d070b200b200a6a200d41807f72200d41ff0071200d41077622041b3a0000200a41016a210a2004210d20040d000b2008210420082012470d000c070b0b200c4101102e000b200c4101102e000b200c4101102e000b20044101102e000b200c4101102e000b20082012460d0003402008410c6a2802004104460d010240200841046a280200450d00200828020010290b200841146a22082012470d000b0b0240200f450d00201010290b200241086a2106200241046a2107200a210402400240024003400240024020072802002006280200220d460d00200228020021050c010b200d41016a2205200d490d0c200d4101742208200520052008491b22084100480d0c02400240200d0d002008103221050c010b2002280200200d2008103421050b2005450d0220022005360200200720083602002006280200210d0b2006200d41016a3602002005200d6a200441807f72200441ff00712004410776220d1b3a0000200d2104200d0d000b02400240200241046a2802002204200241086a280200220d6b200a490d00200228020021040c010b200d200a6a2205200d490d0b2004410174220d20052005200d491b220d4100480d0b0240024020040d00200d103221040c010b20022802002004200d103421040b2004450d0220022004360200200241046a200d360200200241086a280200210d0b200241086a200d200a6a3602002004200d6a200b200a109b051a4100210841012107200c450d02200b10290c020b20084101102e000b200d4101102e000b4101210d4101210b4101210c410121064101210441012105410121020c1b0b2001410c6a2802002105200141086a2802002112200141046a2802002108024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d0e200a410174220c200b200b200c491b220c4100480d0e02400240200a0d00200c1032210b0c010b2002280200200a200c1034210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41063a0000200341cc006a41003602002003420137024420032002360240200820054104746a21134100210a4100210b2005210c034002400240200a200b460d002003280244210a0c010b200a41016a220d200a490d0f200a4101742204200d200d2004491b220d4100480d0f02400240200a0d00200d1032210a0c010b2003280244200a200d1034210a0b200a450d032003200d3602482003200a3602440b2003200b41016a36024c200a200b6a200c41807f72200c41ff0071200c410776220c1b3a00000240200c450d002003280248210a200328024c210b200c210c0c010b0b2008210c2005450d05200541047421114100210c034002402008200c6a220b410d6a2d000022054102470d00200b41106a210c0c070b200b2802002106200b41086a2802002107200b41046a2802002102200b410c6a2c0000210d024002402003280248200328024c220a460d00200328024421040c010b200a41016a2204200a490d0f200a4101742209200420042009491b22094100480d0f02400240200a0d002009103221040c010b2003280244200a2009103421040b2004450d042003200936024820032004360244200328024c210a0b2003200a41016a36024c2004200a6a200d417f73220a413f7141c00072200a200d417f4a1b3a0000024002402003280248200328024c220a460d002003280244210d0c010b200a41016a220d200a490d0f200a4101742204200d200d2004491b22044100480d0f02400240200a0d0020041032210d0c010b2003280244200a20041034210d0b200d450d05200320043602482003200d360244200328024c210a0b2003200a41016a36024c200d200a6a20054100473a0000200320073602302003200236022c200320063602282003200341286a200341c0006a10a70420032d0000220d411a470d052011200c41106a220c470d000c070b0b200c4101102e000b200d4101102e000b20094101102e000b20044101102e000b20032d0003210620032f0001210720032802042102200329030821140240200b41106a2013460d00200b41106a210c0340200c410d6a2d00004102460d01200c2802042105200c28020021040240200c280208220a450d00200a410474210b2004210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200b41706a220b0d000b0b200c41106a210c02402005450d00200410290b200c2013470d000b0b2006411074210a02402012450d00200810290b2007200a72210a02402003280248450d00200328024410290b2000200a3b00012000200d3a0000200041036a200a4110763a0000200041086a2014370000200041046a2002360000410021074101210d4101210c4101210b410121060c100b200c2013460d000340200c410d6a2d00004102460d01200c2802042104200c280200210d0240200c280208220a450d00200a410474210b200d210a03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200b41706a220b0d000b0b200c41106a210c02402004450d00200d10290b200c2013470d000b0b02402012450d00200810290b20032802482108200328024421022003280240220441086a210d200441046a2105200328024c2207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d0a200a4101742206200c200c2006491b22064100480d0a02400240200a0d0020061032210c0c010b2004280200200a20061034210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d09200b410174220a200c200c200a491b220a4100480d0902400240200b0d00200a1032210b0c010b2004280200200b200a1034210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109b051a02402008450d00200210290b41002102410121074101210d4101210b4101210c4101210641012104410121050c1b0b20064101102e000b200a4101102e000b2001410c6a2802002107200141086a2802002108200141046a280200210602400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d09200a410174220c200b200b200c491b220c4100480d0902400240200a0d00200c1032210b0c010b2002280200200a200c1034210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41053a0000200341c0006a410c6a4100360200200342013702442003200236024020062007410c6c6a2102410121044100210c4100210a2007210b03400240200a200c470d00200c41016a220d200c490d0a200c4101742205200d200d2005491b220d4100480d0a02400240200c0d00200d103221040c010b2004200c200d103421040b2004450d04200d210c0b2004200a6a200b41807f72200b41ff0071200b410776220d1b3a0000200a41016a210a200d210b200d0d000b2003200c3602482003200a36024c200320043602442006210a2007450d012007410c6c210d4100210b0340024002402006200b6a220a41046a280200220c4102460d002003200a280200200c200a41086a280200200341c0006a10b40420032d00002204411a460d0120032f000120032d00034110747221052003290308211420032802042107200a410c6a210c200d200b6b41746a210a02400340200a450d01200a41746a210a200c280204210b200c410c6a210c200b4102470d000b0b02402008450d00200610290b02402003280248450d00200328024410290b200020053b0001200020043a0000200041036a20054110763a0000200041086a2014370000200041046a2007360000410021064101210d4101210c4101210b0c120b200a410c6a210a0c030b200d200b410c6a220b470d000b2002210a0c010b200c4101102e000b200a410020076b410c6c6a210b024003402006200b460d01200b410c6a210b200a280204210c200a410c6a210a200c4102470d000b0b02402008450d00200610290b20032802482108200328024421022003280240220441086a210d200441046a2105200328024c2207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d0a200a4101742206200c200c2006491b22064100480d0a02400240200a0d0020061032210c0c010b2004280200200a20061034210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d09200b410174220a200c200c200a491b220a4100480d0902400240200b0d00200a1032210b0c010b2004280200200b200a1034210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109b051a02402008450d00200210290b41002105410121074101210d4101210b4101210c41012106410121040c1a0b20064101102e000b200a4101102e000b200d4101102e000b2001410c6a2802002109200141086a2802002113200141046a2802002106024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d09200a410174220c200b200b200c491b220c4100480d0902400240200a0d00200c1032210b0c010b2002280200200a200c1034210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41043a0000200341c0006a410c6a4100360200200342013702442003200236024020062009410c6c6a2111410121044100210c4100210a2009210b03400240200a200c470d00200c41016a220d200c490d0a200c4101742205200d200d2005491b220d4100480d0a02400240200c0d00200d103221040c010b2004200c200d103421040b2004450d05200d210c0b2004200a6a200b41807f72200b41ff0071200b410776220d1b3a0000200a41016a210a200d210b200d0d000b2003200c3602482003200a36024c200320043602442006210a2009450d022009410c6c21084100210c03400240024002402006200c6a220b41046a28020022044102460d00200b2802002105200b41086a28020021072003280248200328024c220a460d012003280244210d0c020b200b410c6a210a0c050b200a41016a220d200a490d0a200a4101742202200d200d2002491b22024100480d0a02400240200a0d0020021032210d0c010b2003280244200a20021034210d0b200d450d03200320023602482003200d3602440b2003200a41016a36024c200d200a6a41f0003a00002003200520042007200341c0006a10b404024020032d0000220d411a460d0020032f000120032d00034110747221042003290308211420032802042105200b410c6a210b2008200c6b41746a210a02400340200a450d01200a41746a210a200b280204210c200b410c6a210b200c4102470d000b0b02402013450d00200610290b02402003280248450d00200328024410290b200020043b00012000200d3a0000200041036a20044110763a0000200041086a2014370000200041046a20053600004100210b4101210d4101210c0c100b2008200c410c6a220c470d000b2011210a0c020b200c4101102e000b20024101102e000b200a410020096b410c6c6a210b024003402006200b460d01200b410c6a210b200a280204210c200a410c6a210a200c4102470d000b0b02402013450d00200610290b20032802482108200328024421022003280240220441086a210d200441046a2105200328024c2207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d09200a4101742206200c200c2006491b22064100480d0902400240200a0d0020061032210c0c010b2004280200200a20061034210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d08200b410174220a200c200c200a491b220a4100480d0802400240200b0d00200a1032210b0c010b2004280200200b200a1034210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109b051a02402008450d00200210290b41002104410121074101210d4101210b4101210c410121060c180b20064101102e000b200a4101102e000b200d4101102e000b2001410c6a2802002106200141086a2802002109200141046a280200210802400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d0a200a410174220c200b200b200c491b220c4100480d0a02400240200a0d00200c1032210b0c010b2002280200200a200c1034210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41033a0000200820064102746a21074100210c4100210a41002105410121042006210b03400240200a2005470d00200c200a41016a220d200d200c491b22054100480d0b02400240200c0d002005103221040c010b2004200a2005103421040b2004450d050b2004200a6a200b41807f72200b41ff0071200b410776220d1b3a0000200c41026a210c200a41016a210a200d210b200d0d000b02402006450d00200821060340200a410174210c2006280200210b03400240200a2005470d00200a41016a220d200a490d0d200c200d200d200c491b22054100480d0d02400240200a0d002005103221040c010b2004200a2005103421040b2004450d080b2004200a6a200b41807f72200b41ff0071200b410776220d1b3a0000200c41026a210c200a41016a210a200d210b200d0d000b200641046a22062007470d000b0b02402009450d00200810290b200241086a2106200241046a2107200a210c03400240024020072802002006280200220b460d002002280200210d0c010b200b41016a220d200b490d0b200b4101742208200d200d2008491b22084100480d0b02400240200b0d0020081032210d0c010b2002280200200b20081034210d0b200d450d032002200d360200200720083602002006280200210b0b2006200b41016a360200200d200b6a200c41807f72200c41ff0071200c410776220b1b3a0000200b210c200b0d000b02400240200241046a280200220c200241086a280200220b6b200a490d002002280200210c0c010b200b200a6a220d200b490d0a200c410174220b200d200d200b491b220b4100480d0a02400240200c0d00200b1032210c0c010b2002280200200c200b1034210c0b200c450d032002200c360200200241046a200b360200200241086a280200210b0b200241086a200b200a6a360200200c200b6a2004200a109b051a41002106410121072005450d05200410290c050b200c4101102e000b20084101102e000b200b4101102e000b20054101102e000b20054101102e000b4101210d4101210b4101210c0c130b2001410c6a2802002105200141086a2802002116200141046a28020021170240024002400240024002400240024002400240024002400240024002400240024002400240200241046a280200200241086a280200220a460d002002280200210b0c010b200a41016a220b200a490d14200a410174220c200b200b200c491b220c4100480d1402400240200a0d00200c1032210b0c010b2002280200200a200c1034210b0b200b450d012002200b360200200241046a200c360200200241086a280200210a0b200241086a200a41016a360200200b200a6a41023a0000200341cc006a410036020020034201370244200320023602402017200541286c6a21094100210a4100210b2005210c034002400240200a200b460d002003280244210a0c010b200a41016a220d200a490d15200a4101742204200d200d2004491b220d4100480d1502400240200a0d00200d1032210a0c010b2003280244200a200d1034210a0b200a450d032003200d3602482003200a3602440b2003200b41016a36024c200a200b6a200c41807f72200c41ff0071200c410776220c1b3a00000240200c450d002003280248210a200328024c210b200c210c0c010b0b201721062005450d0f2017210603402006220a41286a2106200a2d001822134104460d10200a41196a2f0000200a411b6a2d0000411074722110200a411c6a2800002104200a41146a2802002107200a41106a2802002111200a28020c2102200a2802042112200a2802002108200a41206a2900002214422088a7210f2014a7210e200a2802082205210b0340024002402003280248200328024c220a460d002003280244210c0c010b200a41016a220c200a490d16200a410174220d200c200c200d491b220d4100480d1602400240200a0d00200d1032210c0c010b2003280244200a200d1034210c0b200c450d052003200d3602482003200c3602440b2003200a41016a36024c200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b024002402003280248220a200328024c220c6b2005490d002003280244210d0c010b200c20056a220b200c490d15200a410174220d200b200b200d491b220b4100480d1502400240200a0d00200b1032210d0c010b2003280244200a200b1034210d0b200d450d052003200b3602482003200d360244200b210a0b2003200c20056a220b36024c200d200c6a20082005109b051a02402012450d00200810290b2007210c034002400240200a200b460d002003280244210a0c010b200a41016a220d200a490d16200a4101742205200d200d2005491b220d4100480d1602400240200a0d00200d1032210a0c010b2003280244200a200d1034210a0b200a450d072003200d3602482003200a3602440b2003200b41016a36024c200a200b6a200c41807f72200c41ff0071200c410776220c1b3a00000240200c450d002003280248210a200328024c210b200c210c0c010b0b024002402003280248220a200328024c220c6b2007490d002003280244210b0c010b200c20076a220b200c490d15200a410174220d200b200b200d491b220d4100480d1502400240200a0d00200d1032210b0c010b2003280244200a200d1034210b0b200b450d072003200d3602482003200b360244200d210a0b2003200c20076a220d36024c200b200c6a20022007109b051a02402011450d00200210290b0240024002400240024020130e0400010203000b0240200a200d470d00200a41016a220c200a490d19200a4101742205200c200c2005491b220c4100480d1902400240200a0d00200c1032210b0c010b200b200a200c1034210b0b200b450d0c2003200c3602482003200b3602440b2003200d41016a36024c200b200d6a41003a00000340024002402003280248200328024c220a460d002003280244210b0c010b200a41016a220b200a490d1a200a410174220c200b200b200c491b220c4100480d1a02400240200a0d00200c1032210b0c010b2003280244200a200c1034210b0b200b450d0e2003200c3602482003200b3602440b2003200a41016a36024c200b200a6a200441807f72200441ff00712004410776220a1b3a0000200a2104200a0d000c040b0b0240200a200d470d00200a41016a220c200a490d18200a4101742205200c200c2005491b220c4100480d1802400240200a0d00200c1032210b0c010b200b200a200c1034210b0b200b450d0d2003200c3602482003200b3602440b2003200d41016a36024c200b200d6a41013a0000024002402003280248200328024c220a460d002003280244210b0c010b200a41016a220b200a490d18200a410174220c200b200b200c491b220c4100480d1802400240200a0d00200c1032210b0c010b2003280244200a200c1034210b0b200b450d0e2003200c3602482003200b3602440b2003200a41016a36024c200b200a6a41f0003a000020032004200e200f200341c0006a10b40420032d0000220a411a460d0220032f000120032d000341107472210d0c120b0240200a200d470d00200a41016a220c200a490d17200a4101742205200c200c2005491b220c4100480d1702400240200a0d00200c1032210b0c010b200b200a200c1034210b0b200b450d0e2003200c3602482003200b3602440b2003200d41016a36024c200b200d6a41023a000020032004200e200f200341c0006a10b40420032d0000220a411a460d0120032f000120032d000341107472210d0c110b0240200a200d470d00200a41016a220c200a490d16200a4101742204200c200c2004491b220c4100480d1602400240200a0d00200c1032210b0c010b200b200a200c1034210b0b200b450d0e2003200c3602482003200b3602440b2003200d41016a36024c200b200d6a41033a0000024002402003280248200328024c220a460d002003280244210b0c010b200a41016a220b200a490d16200a410174220c200b200b200c491b220c4100480d1602400240200a0d00200c1032210b0c010b2003280244200a200c1034210b0b200b450d0f2003200c3602482003200b3602440b2003200a41016a36024c200b200a6a2010417f73220a413f7141c00072200a2010411874411875417f4a1b3a0000024002402003280248200328024c220a460d002003280244210b0c010b200a41016a220b200a490d16200a410174220c200b200b200c491b220c4100480d1602400240200a0d00200c1032210b0c010b2003280244200a200c1034210b0b200b450d102003200c3602482003200b3602440b2003200a41016a36024c200b200a6a20104180fe03714100473a00000b20062009470d000c110b0b200c4101102e000b200d4101102e000b200d4101102e000b200b4101102e000b200d4101102e000b200d4101102e000b200c4101102e000b200c4101102e000b200c4101102e000b200c4101102e000b200c4101102e000b200c4101102e000b200c4101102e000b200c4101102e000b2003290308211420032802042104024020062009460d000340200641186a2d00004104460d01200641106a280200210b2006410c6a280200210c0240200641046a280200450d00200628020010290b0240200b450d00200c10290b200641286a22062009470d000b0b02402016450d00201710290b02402003280248450d00200328024410290b2000200d3b00012000200a3a0000200041036a200d4110763a0000200041086a2014370000200041046a20043600004100210c4101210d0c090b20062009460d000340200641186a2d00004104460d01200641106a280200210a2006410c6a280200210b0240200641046a280200450d00200628020010290b0240200a450d00200b10290b200641286a22062009470d000b0b02402016450d00201710290b20032802482108200328024421022003280240220441086a210d200441046a2105200328024c2207210b024002400340024002402005280200200d280200220a460d002004280200210c0c010b200a41016a220c200a490d06200a4101742206200c200c2006491b22064100480d0602400240200a0d0020061032210c0c010b2004280200200a20061034210c0b200c450d022004200c36020020052006360200200d280200210a0b200d200a41016a360200200c200a6a200b41807f72200b41ff0071200b410776220a1b3a0000200a210b200a0d000b02400240200441046a280200220b200441086a280200220a6b2007490d002004280200210b0c010b200a20076a220c200a490d05200b410174220a200c200c200a491b220a4100480d0502400240200b0d00200a1032210b0c010b2004280200200b200a1034210b0b200b450d022004200b360200200441046a200a360200200441086a280200210a0b200441086a200a20076a360200200b200a6a20022007109b051a02402008450d00200210290b4100210c410121074101210d4101210b0c130b20064101102e000b200a4101102e000b20082010460d0003402008410d6a2d00004105460d010240200841046a280200450d00200828020010290b200841106a22082010470d000b0b0240200e450d00200f10290b200241086a2106200241046a2107200b210c03400240024020072802002006280200220a460d002002280200210d0c010b200a41016a220d200a490d02200a4101742208200d200d2008491b22084100480d0202400240200a0d0020081032210d0c010b2002280200200a20081034210d0b200d450d032002200d360200200720083602002006280200210a0b2006200a41016a360200200d200a6a200c41807f72200c41ff0071200c410776220a1b3a0000200a210c200a0d000b02400240200241046a280200220c200241086a280200220a6b200b490d002002280200210c0c010b200a200b6a220d200a490d01200c410174220a200d200d200a491b220a4100480d0102400240200c0d00200a1032210c0c010b2002280200200c200a1034210c0b200c450d032002200c360200200241046a200a360200200241086a280200210a0b200241086a200a200b6a360200200c200a6a2004200b109b051a4100210b410121072005450d03200410290c030b1033000b20084101102e000b200a4101102e000b4101210d0c0a0b4101210c200241086a200a41016a3602004100210d200b200a6a41003a0000200341146a2004360200200341106a20053602002003200636020c200320073602082003200836020420032009360200200341c0006a2003200210b904200320032900413703282003200341c0006a41086a29000037002f20032d0040220a411a460d082000200a3a000020002003290328370001200041086a200329002f3700000b4101210b0b410121060b410121070b410121040b410121050b410121020b410121080b20012d0000220a410e4b0d1a200a0e0f0c0d0e0f10111213141a15161718190c0b4101210d410021074101210b0b4101210c0b410121060b410121040b410121050b410121020b410121080b410121090b410121100b410121130b41012111410121120b2000411a3a000020012d0000220a410e4b0d1d200a0e0f0f10111213141516171d18191a1b1c0f0b200141086a280200450d1d200141046a28020010290c1d0b200d450d1c0240200141086a280200450d00200141046a28020010290b200141146a280200450d1c200141106a28020010290c1c0b02402001410c6a280200220b450d00200141046a280200210a200b410474210b03400240200a41046a280200450d00200a28020010290b200a41106a210a200b41706a220b0d000b0b200141086a280200450d1b200128020410290c1b0b200c450d1a02402001410c6a280200220b450d00200141046a280200210a200b41286c210b03400240200a41046a280200450d00200a28020010290b0240200a41106a280200450d00200a410c6a28020010290b200a41286a210a200b41586a220b0d000b0b200141086a280200450d1a200128020410290c1a0b200141086a280200450d19200141046a28020010290c190b200b450d18200141086a280200450d18200141046a28020010290c180b2006450d17200141086a280200450d17200141046a28020010290c170b2007450d1602402001410c6a280200220a450d00200141046a280200220c200a4104746a210d03400240200c280208220b450d00200c280200210a200b410474210b03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200b41706a220b0d000b0b200c41106a210a0240200c41046a280200450d00200c28020010290b200a210c200a200d470d000b0b200141086a280200450d16200128020410290c160b02402001410c6a280200220b450d00200141046a280200210a200b41146c210b03400240200a41046a280200450d00200a28020010290b200a41146a210a200b416c6a220b0d000b0b200141086a280200450d15200128020410290c150b2004450d1402402001410c6a280200220a450d00200141046a280200220c200a411c6c6a210d03400240200c410c6a280200220b450d00200c280204210a200b410474210b03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200b41706a220b0d000b0b0240200c41086a280200450d00200c28020410290b200c411c6a210a0240200c41146a280200450d00200c28021010290b200a210c200a200d470d000b0b200141086a280200450d14200128020410290c140b2005450d1302402001410c6a280200220a450d00200141046a280200220c200a41186c6a210d03400240200c41046a280200450d00200c28020010290b0240200c41146a280200220b450d00200c28020c210a200b410474210b03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200b41706a220b0d000b0b200c41186a210a0240200c41106a280200450d00200c28020c10290b200a210c200a200d470d000b0b200141086a280200450d13200128020410290c130b2002450d1202402001410c6a280200220a450d00200141046a280200220c200a411c6c6a210d03400240200c410c6a280200220b450d00200c280204210a200b410474210b03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200b41706a220b0d000b0b0240200c41086a280200450d00200c28020410290b200c411c6a210a0240200c41146a280200450d00200c28021010290b200a210c200a200d470d000b0b200141086a280200450d12200128020410290c120b2008450d110240200141046a2d0000220a41024b0d00024002400240200a0e03000102000b2001410c6a280200450d14200141086a28020010290c140b0240200141146a280200220b450d002001410c6a280200210a200b410c6c210b03400240200a280200220c450d00200a41046a280200450d00200c10290b200a410c6a210a200b41746a220b0d000b0b200141106a280200450d13200128020c10290c130b0240200141146a280200220a450d002001410c6a2802002204200a4104746a210503402004220d41106a21040240200d280204220a450d000240200d410c6a280200220b450d00200b410c6c210b03400240200a280200220c450d00200a41046a280200450d00200c10290b200a410c6a210a200b41746a220b0d000b0b200d41086a280200450d00200d28020410290b20042005470d000b0b200141106a280200450d12200128020c10290c120b2001410c6a280200450d11200141086a28020010290c110b0240200141086a280200450d00200141046a28020010290b0240200141146a280200220a450d00200141186a280200450d00200a10290b200141246a280200450d10200141206a28020010290c100b200110d8030c0f0b200d450d0e200141086a280200450d0e200141046a28020010290c0e0b2007450d0d0240200141086a280200450d00200141046a28020010290b200141146a280200450d0d200141106a28020010290c0d0b200b450d0c02402001410c6a280200220b450d00200141046a280200210a200b410474210b03400240200a41046a280200450d00200a28020010290b200a41106a210a200b41706a220b0d000b0b200141086a280200450d0c200128020410290c0c0b200c450d0b02402001410c6a280200220b450d00200141046a280200210a200b41286c210b03400240200a41046a280200450d00200a28020010290b0240200a41106a280200450d00200a410c6a28020010290b200a41286a210a200b41586a220b0d000b0b200141086a280200450d0b200128020410290c0b0b2006450d0a200141086a280200450d0a200141046a28020010290c0a0b2004450d09200141086a280200450d09200141046a28020010290c090b2005450d08200141086a280200450d08200141046a28020010290c080b2002450d0702402001410c6a280200220a450d00200141046a280200220c200a4104746a210d03400240200c280208220b450d00200c280200210a200b410474210b03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200b41706a220b0d000b0b200c41106a210a0240200c41046a280200450d00200c28020010290b200a210c200a200d470d000b0b200141086a280200450d07200128020410290c070b2008450d0602402001410c6a280200220b450d00200141046a280200210a200b41146c210b03400240200a41046a280200450d00200a28020010290b200a41146a210a200b416c6a220b0d000b0b200141086a280200450d06200128020410290c060b2009450d0502402001410c6a280200220a450d00200141046a280200220c200a411c6c6a210d03400240200c410c6a280200220b450d00200c280204210a200b410474210b03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200b41706a220b0d000b0b0240200c41086a280200450d00200c28020410290b200c411c6a210a0240200c41146a280200450d00200c28021010290b200a210c200a200d470d000b0b200141086a280200450d05200128020410290c050b2010450d0402402001410c6a280200220a450d00200141046a280200220c200a41186c6a210d03400240200c41046a280200450d00200c28020010290b0240200c41146a280200220b450d00200c28020c210a200b410474210b03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200b41706a220b0d000b0b200c41186a210a0240200c41106a280200450d00200c28020c10290b200a210c200a200d470d000b0b200141086a280200450d04200128020410290c040b2013450d0302402001410c6a280200220a450d00200141046a280200220c200a411c6c6a210d03400240200c410c6a280200220b450d00200c280204210a200b410474210b03400240200a2d00004109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010290b200a41106a210a200b41706a220b0d000b0b0240200c41086a280200450d00200c28020410290b200c411c6a210a0240200c41146a280200450d00200c28021010290b200a210c200a200d470d000b0b200141086a280200450d03200128020410290c030b2011450d020240200141046a2d0000220a41024b0d00024002400240200a0e03000102000b2001410c6a280200450d05200141086a28020010290c050b0240200141146a280200220b450d002001410c6a280200210a200b410c6c210b03400240200a280200220c450d00200a41046a280200450d00200c10290b200a410c6a210a200b41746a220b0d000b0b200141106a280200450d04200128020c10290c040b0240200141146a280200220a450d002001410c6a2802002204200a4104746a210503402004220d41106a21040240200d280204220a450d000240200d410c6a280200220b450d00200b410c6c210b03400240200a280200220c450d00200a41046a280200450d00200c10290b200a410c6a210a200b41746a220b0d000b0b200d41086a280200450d00200d28020410290b20042005470d000b0b200141106a280200450d03200128020c10290c030b2001410c6a280200450d02200141086a28020010290c020b2012450d010240200141086a280200450d00200141046a28020010290b0240200141146a280200220a450d00200141186a280200450d00200a10290b200141246a280200450d01200141206a28020010290c010b200110d8030b200341d0006a24000bb50503027f017e027f230041d0006b2202240020024186b2c500411710d5012002280200210320022903082104200241306a41086a22054200370300200242003703304186b2c5004117200241306a1003200241106a41086a2005290300370300200220022903303703102002200442017c420120031b2204370330200241106a4110200241306a41081005024002400240412010322203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003412041c00010342201450d0120012004370020200241306a41186a22034200370300200241306a41106a22054200370300200241306a41086a220642003703002002420037033020014128200241306a1000200241106a41186a2003290300370300200241106a41106a2005290300370300200241106a41086a200629030037030020022002290330370310413710322203450d02200342bac6a1cbc68dd9aff300370000200342f4dec98bf6ac999de400370008200341e5cc85ab073600102003413a3a0016200341ece8013b001420032002290310370017200320022f01183b001f2003200228011a360021200320022f011e3b0025200320022d00203a0027200320022d00213a0028200320022d00223a0029200320022d00233a002a200320022d00243a002b200320022d00253a002c200320022d00263a002d200320022d00273a002e200320022d00283a002f200320022d00293a0030200320022d002a3a0031200320022d002b3a0032200320022d002c3a0033200320022d002d3a0034200320022d002e3a0035200320022d002f3a0036200041f0f9c30041c8f9c3006b410f6a360208200041373602042000200336020020011029200241d0006a24000f0b41204101102e000b41c0004101102e000b41374101102e000bd80101037f230041106b22022400200241003602082002420137030020002d00002103410110322104024002400240024020034101460d002004450d02200242818080801037020420022004360200200441003a0000200041086a200210d0030c010b2004450d02200242818080801037020420022004360200200441013a00002002200236020c200041016a2002410c6a1085010b2002280204210420012802002001280204200228020022012002280208100502402004450d00200110290b200241106a24000f0b41014101102e000b41014101102e000b9b0703037f047e067f23002202210320024180026b416071220224002001411c6a22042902002105200420022903b801370200200141146a22042902002106200420022903b0013702002001410c6a22042902002107200420022903a801370200200241003a00a00120012902042108200120022903a00137020420022005370358200220063703502002200737034820022008370340200141246a2d00002104200241a0016a41176a22092005370000200241a0016a41106a220a2002290051370300200241a0016a41086a220b2002290049370300200220022900413703a001024002402008a741ff01714101460d00200041003602200c010b200241106a41176a2009290000370000200241106a41106a200a290300370300200241106a41086a200b290300370300200220022903a001370310200220043a002f2002200241106a36024002400240411210322204450d0020044100290089be44370000200441106a41002f0099be443b0000200441086a4100290091be4437000020024292808080a0023702a401200220043602a001200241c0006a200241a0016a108a0120022802a401210a20022802a801210420022802a0012109200241a0016a41186a220b4200370300200241a0016a41106a220c4200370300200241a0016a41086a220d4200370300200242003703a00120092004200241a0016a1000200241c0006a41186a220e200b290300370300200241c0006a41106a220b200c290300370300200241c0006a41086a2204200d290300370300200220022903a001370340200241a0016a200241c0006a10b50320022d00ac014102460d01200241c0006a200241a0016a41d000109b051a200241306a41086a220c200428020036020020022002290340370330200241a0016a200241cc006a41c200109b051a200141046a220141206a200241e1016a2d00003a0000200141186a200241d9016a290000370000200141106a200241d1016a290000370000200141086a200241c9016a290000370000200120022900c101370000200e200241106a41186a2903002205370300200b200241106a41106a29030022083703002004200241106a41086a2903002206370300200020022903102207370200200041086a2006370200200041106a2008370200200041186a200537020020022007370340200041206a2002290330370200200041286a200c280200360200200a450d0220091029200324000f0b41124101102e000b41acb3c40041d700109201000b200324000bc50603037f047e057f230022022103200241e0016b416071220224002001411c6a220429020021052004200229039801370200200141146a2204290200210620042002290390013702002001410c6a220429020021072004200229038801370200200241003a00800120012902042108200120022903800137020420022005370338200220063703302002200737032820022008370320200141246a2d0000210420024180016a41176a2209200537000020024180016a41106a220a200229003137030020024180016a41086a220b20022900293703002002200229002137038001024002402008a741ff01714101460d00200042003703000c010b200241176a2009290000370000200241106a200a290300370300200241086a200b2903003703002002200229038001370300200220043a001f2002200236022002400240411210322204450d002004410029009bbe44370000200441106a41002f00abbe443b0000200441086a41002900a3be4437000020024292808080a002370284012002200436028001200241206a20024180016a108a01200228028401210b200228028801210c200228028001210a20024180016a41186a220d420037030020024180016a41106a2204420037030020024180016a41086a220942003703002002420037038001200a200c20024180016a1000200241206a41186a200d290300370300200241206a41106a2004290300370300200241206a41086a2009290300370300200220022903800137032020024180016a200241206a10b30320022d0090014102460d01200929030021052002290380012108200241206a200441c200109b051a20024180016a200241206a41c200109b051a200141046a220141206a200241c1016a2d00003a0000200141186a200241b9016a290000370000200141106a200241b1016a290000370000200141086a200241a9016a290000370000200120022900a10137000020002002290300370008200041106a200241086a290300370000200041186a200241106a290300370000200041206a200241186a290300370000200041306a2005370300200041286a200837030020004201370300200b450d02200a1029200324000f0b41124101102e000b41acb3c40041d700109201000b200324000bb90201067f230041c0006b220224000240411710322203450d00200341002900f9f9433700002003410f6a4100290088fa43370000200341086a4100290081fa4337000020024297808080f002370224200220033602202000200241206a108101200228022421002002280228210420022802202103200241206a41186a22054200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020032004200241206a1000200241186a2005290300370300200241106a2006290300370300200241086a20072903003703002002200229032037030020024120360224200220023602202001200241206a10dc0302402000450d00200310290b024020012d00000d002001411c6a280200450d00200141186a28020010290b200241c0006a24000f0b41174101102e000bac0404017f017e027f037e23004180016b2203240042002104200341d8006a41086a220542003703002003420037035841ddb1c5004111200341d8006a1003200341f0006a41086a2206200529030037030020032003290358370370200341c8006a200341f0006a10b301024002400240024002404280ade20420032903507d4280ade20420032802481b2002540d0020054200370300200342003703584190fac3004111200341d8006a10032006200529030037030020032003290358370370200341306a200341f0006a10eb0120032903384201200328023022051b2207200341c0006a290300420020051b22088450450d01420021090c020b2000418897c50036020420004101360200200041086a411b3602000c030b200341106a200842002002420010a005200341206a200742002002420010a0052003420042002007420010a0052003290318200329030884420052200341206a41086a2903002204200329031020032903007c7c2209200454724101460d01200329032021040b200341d8006a200120042009410810ad01024020032802584101470d002000200329025c370204200041013602000c020b20032903602104200041306a200341d8006a41106a290300370300200041286a2004370300200041206a2008370300200041186a2007370300200041106a2002370300200041086a2002370300200041003602000c010b200041a397c50036020420004101360200200041086a41273602000b20034180016a24000bde210a057f047e0d7f067e057f027e0d7f027e067f017e23004180056b22022400200128020821032001280200210402400240200128020422050d00200421010c010b2005210620042101034020012802880b21012006417f6a22060d000b0340200420042f01064102746a41880b6a28020021042005417f6a22050d000b0b200241fc006a20042f0106360200200241e0006a41186a4100360200200241f4006a200436020020022003360280012002410036027042002107200242003703682002200136026420024100360260200241c8016a200241e0006a10c6010240024020022903e80122084202520d00420021094200210a0c010b200241fc016a210b200241c8016a412c6a210c200241c8016a410472210d200241a5026a210e200241c8016a41086a2103200241a8036a412c6a210f200241a8036a41106a2110200241f8016a211120024190026a211242002107420021094200210a0340200241a8016a41186a2206200241c8016a41186a2201290300370300200241a8016a41106a2213200241c8016a41106a2204290300370300200241a8016a41086a2214200329030037030020024188016a41086a2215200e41086a29000037030020024188016a41106a2216200e41106a29000037030020024188016a41186a2217200e41186a290000370300200220022903c8013703a8012002200e29000037038801201129030021182012290300211920022903f001211a200229038802211b200229038002211c200229039802211d20022802a002211e20022d00a402211f20022d00c5022105200241c8026a41186a2006290300370300200241c8026a41106a2013290300370300200241c8026a41086a2014290300370300200220022903a8013703c802200241e8026a41186a22142017290300370300200241e8026a41106a22202016290300370300200241e8026a41086a2221201529030037030020022002290388013703e802024002400240024002402005ad42ff0183200820085022061b4201520d00200241c8016a200241c8026a4200201a20061b4200201820061b10a20120022d00e0012106200241c8006a200a2007200920022903c80120022903d001200429030010fc01200241c8006a41106a2903002109200229035021072002290348210a20060d010b024002400240201f41ff0171222241014622060d00200541ff01710d00201e201ca772450d010b200241c8016a200241c8026a1096020240024020022d00c8012213417f6a221541014b0d00024020150e020002000b20130d0420022802e401450d0420022802e00110290c040b20024188036a41086a200b41086a29020037030020024188036a41106a200b41106a29020037030020024188036a41186a200b41186a2902003703002002200b290200370388032004290300212320022903d0012124200228029c02212520022802f801212620022802f401212720022802f001212820022802ec01212920022802e801212a20022802e401212b20022802e001212c0c020b4102212720130d0120022802e401450d0120022802e00110290c010b201da7210402400240201d422088a722050d00200421010c010b2005210620042101034020012802ec0321012006417f6a22060d000b0340200420042f01064102746a41ec036a28020021042005417f6a22050d000b0b2002201e3602e801200241003602e001200241003602d801200242003703d001200220013602cc01200241003602c801200220043602dc01200220042f01063602e401200241c8016a10c9010c040b4102212d024002400240024020274102460d00202a417f4c0d0202400240202a0d004100212e4101212f0c010b202a212e202a1032222f450d020b202f202c202a109b051a200120024188036a41186a290300370300200420024188036a41106a290300370300200320024188036a41086a29030037030020022002290388033703c8012027410146212d202a213020292131202421322023213320282134202621350b200241f8036a41186a22362001290300370300200241f8036a41106a22372004290300370300200241f8036a41086a22382003290300370300200241e0046a41086a221f2021290300370300200241e0046a41106a22162020290300370300200241e0046a41186a22172014290300370300200220022903c8013703f803200220022903e8023703e00402400240024002400240024002400240200541ff01710d00202d4102460d01200f20022903f803370200200f41086a2038290300370200200f41106a2037290300370200200f41186a2036290300370200200220323703a803200220353602d0032002202d3602cc03200220343602c803200220313602c403200220303602c0032002202e3602bc032002202f3602b803200220333703b00320342139203221182033213a203121130c030b202d4102470d010b2006450d03200241c8016a200241c8026a10db03200241386a41d983c300410d105d41082113200228023c210520022802382106201041086a200241c8016a41086a280200360200201020022903c801370200200f20022903e004370100200f41086a200241e0046a41086a290300370100200f41106a2016290300370100200f41186a2017290300370100427f21182002427f3703b0032002427f3703a803200241083602c4034100212d200241003602cc0320022005410020061b22393602c803427f213a0c010b202f203010082006450d01200241c8016a200241c8026a10db03200241c0006a41d983c300410d105d410821132002280244210520022802402106201041086a200241c8016a41086a280200360200201020022903c801370200200f20022903e004370100200f41086a200241e0046a41086a290300370100200f41106a2016290300370100200f41186a2017290300370100427f21182002427f3703b0032002427f3703a803200241083602c4034100212d200241003602cc0320022005410020061b22393602c8030240202e450d00202f1029427f21180b427f213a0b0240201c4201520d002002201b3703a803200220193703b003201b21182019213a0b02402022450d00200f20022903e802370000200f41186a2014290300370000200f41106a2020290300370000200f41086a20212903003700000b0240201e450d00200241306a41d983c300410d105d4101212d200241013602cc0320022002280234410020022802301b3602d0030b201da72105201d422088a722140d02200521060c030b200241c8026a109902202e450d00202f10290b20274102460d05202b0d044100212b0c050b2014211520052106034020062802ec0321062015417f6a22150d000b0340200520052f01064102746a41ec036a28020021052014417f6a22140d000b0b20052f010621142002201e36029804200220143602940420024100360290042002200536028c0420024100360288042002420037038004200220063602fc03200241003602f803200241c8016a200241f8036a10c70120022802c8014101470d0520022802c003211520022802b803211e0340200241a0046a41186a200d41186a2902002208370300200241a0046a41106a200d41106a290200221d370300200241a0046a41086a200d41086a290200221c3703002002200d290200221a3703a00420022802ec01210520022802f001212020022802f4012106200241c0046a41186a2008370300200241c0046a41106a201d370300200241c0046a41086a201c3703002002201a3703c004200142003703002004420037030020034200370300200242003703c801200241c0046a4120200241c8016a10002017200129030037030020162004290300370300201f2003290300370300200220022903c8013703e004200241003602c801201e2015200241e0046a4120200241c8016a10012121024020022802c8012214417f460d00201320146b21132014450d00202110290b0240024020050d00200142003703002004420037030020034200370300200242003703c801200241c0046a4120200241c8016a10002017200129030037030020162004290300370300201f2003290300370300200220022903c8013703e004201e2015200241e0046a412010020c010b200142003703002004420037030020034200370300200242003703c801200241c0046a4120200241c8016a10002017200129030037030020162004290300370300201f2003290300370300200220022903c8013703e004201e2015200241e0046a4120200520061016201320066a21132020450d00200510290b200241c8016a200241f8036a10c70120022802c8014101470d050c000b0b202a4101102e000b102f000b202c10290b201da7210402400240201d422088a722050d00200421010c010b2005210620042101034020012802ec0321012006417f6a22060d000b0340200420042f01064102746a41ec036a28020021042005417f6a22050d000b0b2002201e3602e801200241003602e001200241003602d801200242003703d001200220013602cc01200241003602c801200220043602dc01200220042f01063602e401200241c8016a10c9010c020b200220133602c4030b200241f8036a10c901203620024188036a41186a290300370300203720024188036a41106a290300370300203820024188036a41086a29030037030020022002290388033703f8030240024020274102460d00200c20022903f803370200200c41086a2038290300370200200c41106a2037290300370200200c41186a2036290300370200200220243703c801200220263602f001200220273602ec01200220283602e801200220293602e4012002202b3602dc012002202c3602d8012002202536029402200220233703d0012002202a3602e001410121040240202a20022802c003470d0002400240202c20022802b8032201460d00202c2001202a109d050d0220292013470d020c010b20292013470d010b200c200f4120109d050d0020242018852023203a85844200520d0020282039470d0002402027202d470d004100210420274101470d01202620022802d003460d010b410121040b0240202b450d00202c10290b20044102460d002004450d010b2003200241a8036a41d000109b051a200241003a00c801200241c8026a200241c8016a10df030c010b20022802bc03450d0020022802b80310290b200241c8016a200241e0006a10c60120022903e80122084202520d000b0b200241e0006a10cd0102400240200a500d00200241c8016a41086a22044200370300200242003703c80141c2d5c0004116200241c8016a1003200241a8036a41086a22052004290300370300200220022903c8013703a803200241186a200241a8036a10eb01200241286a29030021082002290320211d2002280218210120044200370300200242003703c80141c2d5c0004116200241c8016a100320052004290300370300200220022903c8013703a803200242002008420020011b220820097d201d420020011b221d200754ad7d221c201d20077d221a201d56201c200856201c2008511b22041b3703d00120024200201a20041b3703c801200241c8016a2104200241a8036a21010c010b02402007200984500d0041fc9ac500106d000b200241c8016a41086a22044200370300200242003703c80141c2d5c0004116200241c8016a1003200241a8036a41086a22052004290300370300200220022903c8013703a8032002200241a8036a10eb01200241106a29030021082002290308211d2002280200210120044200370300200242003703c80141c2d5c0004116200241c8016a100320052004290300370300200220022903c8013703a80320022008420020011b3703d0012002201d420020011b3703c801200241c8016a2104200241a8036a21010b2001411020044110100520024180056a24000ba50501047f230041f0006b22072400200741086a200242002003200410a005200741e0006a41086a220842003703002007420037036041ddb1c5004111200741e0006a1003200741d0006a41086a2209200829030037030020072007290360370350200741c0006a200741d0006a10b301200729034821032007280240210a200842003703002007420037036041ddb1c5004111200741e0006a100320092008290300370300200720072903603703502007200120027d20034200200a1b7c370360200741d0006a4110200741e0006a41081005200741306a20002007290308200741086a41086a29030010a001200741306a41086a290300210120072903302102200842003703002007420037036041c2d5c0004116200741e0006a10032009200829030037030020072007290360370350200520027d200220057d2002200558200120065820012006511b22001b2103200620017d2005200254ad7d200120067d2002200554ad7d20001b2106200741186a200741d0006a10eb01200741186a41106a29030042002007280218220a1b210520072903204200200a1b2102024002402000450d00200842003703002007420037036041c2d5c0004116200741e0006a1003200920082903003703002007200729036037035020074200200520067d2002200354ad7d2206200220037d2201200256200620055620062005511b22081b37036820074200200120081b370360200741e0006a21080c010b200842003703002007420037036041c2d5c0004116200741e0006a100320092008290300370300200720072903603703502007427f200520067c200220037c22062002542208ad7c22022008200220055420022005511b22081b3703682007427f200620081b370360200741e0006a21080b200741d0006a4110200841101005200741f0006a24000bc02102117f057e230041e0036b22062400200641c0026a2000109602410221070240024020062d00c00222084102470d00410121094134210a410221080c010b200641c0036a41086a2209200641d4026a290200370300200641c0036a41106a220b200641dc026a290200370300200641c0036a41186a220c200641e4026a29020037030020064198036a41086a220d200641f8026a29030037030020064198036a41106a220e20064180036a29030037030020064198036a41186a220f20064188036a29030037030020064198036a41206a221020064190036a2903003703002006200641cc026a2902003703c0032006200641f0026a29030037039803200641c0026a41086a280200210a024020080d00200641ec026a280200210720064198026a41186a200c29030037030020064198026a41106a200b29030037030020064198026a41086a2009290300370300200641f0016a41086a200d290300370300200641f0016a41106a200e290300370300200641f0016a41186a200f290300370300200641f0016a41206a2010290300370300200620062903c0033703980220062006290398033703f0010b41022108024020074102470d00410121094134210a0c010b20064198036a41186a20064198026a41186a29030037030020064198036a41106a20064198026a41106a29030037030020064198036a41086a20064198026a41086a290300370300200641c0026a41086a200641f0016a41086a290300370300200641c0026a41106a200641f0016a41106a290300370300200641c0026a41186a200641f0016a41186a290300370300200641c0026a41206a200641f0016a41206a290300370300200620062903980237039803200620062903f0013703c00241002109200721080b200641d0016a41086a220720064198036a41086a290300370300200641d0016a41106a220b20064198036a41106a290300370300200641d0016a41186a220c20064198036a41186a290300370300200641a8016a41086a220d200641c0026a41086a290300370300200641a8016a41106a220e200641c0026a41106a290300370300200641a8016a41186a220f200641c0026a41186a290300370300200641a8016a41206a2210200641c0026a41206a29030037030020062006290398033703d001200620062903c0023703a8010240024020090d0020064180016a221120062903a801370300200641e4006a2007290300370200200641ec006a200b290300370200200641f4006a200c29030037020020064188016a200d29030037030020064190016a200e29030037030020064198016a200f290300370300200641a0016a20102903003703002006200a360258200620062903d00137025c2006200836027c200641d0006a41d983c300410d105d2006280254410020062802501b210d410121090240024020084101470d002011280200200d460d010b200641c0026a20011096020240024020062d00c002220a4102470d00412e210a418eb6c400210b0c010b20064198026a41026a20062d00c3023a000020064198036a41086a2209200641d4026a280200360200200620062f00c1023b0198022006200641cc026a29020037039803200641dc026a2802002108200641d8026a28020021070240200a0d0041012109412e210a418eb6c400210b024020080d000c020b200710290c010b200641c0026a41086a280200210a20062802c402210b200641d0016a41026a20064198026a41026a2d00003a0000200641f0016a41086a2009280200360200200620062f0198023b01d00120062006290398033703f001200641e0026a2d0000210c410021090b200641bc026a41026a200641d0016a41026a2d00003a0000200641c0036a41086a220e200641f0016a41086a280200360200200620062f01d0013b01bc02200620062903f0013703c00320090d00200641bb016a200e280200360000200620062f01bc023b01a8012006200a3600af012006200b3600ab01200620062903c0033700b3012006200c3a00c701200620083600c301200620073600bf012006200641be026a2d00003a00aa01200628027c21122006280280012113200620052802002211200541086a28020022144105746a3602c403200620113602c0032006200641d8006a3602c80320064198036a200641c0036a102702400240024002400240024002400240024002402006280298030d0041002109200641003602a0022006420437039802410421074100210a0c010b200641c0026a41086a220820064198036a41086a29030037030020062006290398033703c002411010322207450d01200720062903c002370200200741086a2008290300370200200641f0016a41086a200641c0036a41086a280200360200200620062903c0033703f00120064198036a200641f0016a1027024002402006280298030d00410121094101210a0c010b410121084101210a0340200641c0026a41086a220b20064198036a41086a29030037030020062006290398033703c00202400240200a2008460d00200841016a21090c010b200841016a22092008490d082008410174220a20092009200a491b220a41ffffffff0071200a470d08200a410474220c4100480d080240024020080d00200c103221070c010b20072008410474200c103421070b2007450d050b200720084104746a220820062903c002370200200841086a200b29030037020020064198036a200641f0016a1027200921082006280298030d000b0b200620093602a0022006200a36029c0220062007360298020b200641d8006a41186a28020021082006280268210b200641003602c002200b2008200641c0026a100a211020062802c002220f417f460d0220064198036a41186a200241186a29000037030020064198036a41106a200241106a29000037030020064198036a41086a200241086a2900003703002006200229000037039803200641003602c803200642013703c0032010200f200641c0036a1097020240024020062802c403220e20062802c803220c6b4120490d00200c41206a210b20062802c00321080c010b200c41206a220b200c490d05200e4101742208200b200b2008491b22154100480d0502400240200e0d002015103221080c010b20062802c003200e2015103421080b2008450d04200620153602c403200620083602c0032015210e0b2006200b3602c8032008200c6a220c200629039803370000200c41086a20064198036a41086a290300370000200c41106a20064198036a41106a290300370000200c41186a20064198036a41186a290300370000200641c0026a41186a220c4200370300200641c0026a41106a22154200370300200641c0026a41086a22164200370300200642003703c0022008200b200641c0026a1000200641f0016a41186a200c290300370300200641f0016a41106a2015290300370300200641f0016a41086a2016290300370300200620062903c0023703f0010240200e450d00200810290b0240200f450d00201010290b0240200641f0016a200641a8016a4120109d050d000240024020090d004100210b0c010b2009410474210c2007410c6a21084100210b03402008280200200b6a210b200841106a2108200c41706a220c0d000b0b20062006280274200b6b360274411710322208450d06200d201320141b210f4101201220141b2110200641d8006a41106a210b200841002900f9f9433700002008410f6a4100290088fa43370000200841086a4100290081fa4337000020064297808080f0023702c402200620083602c0022000200641c0026a10810120062802c402211520062802c802211620062802c002210e200641c0026a41186a220c4200370300200641c0026a41106a22084200370300200641c0026a41086a22144200370300200642003703c002200e2016200641c0026a100020064198036a41186a200c29030037030020064198036a41106a200829030037030020064198036a41086a2014290300370300200620062903c0023703980320064198036a4120100402402015450d00200e10290b20082004370300200c200b290300370300200641f0026a200f360200200641ec026a2010360200200641e8026a200d360200200641e4026a2006280274360200200641f4026a2002290000370200200641c0026a41206a200b41086a280200360200200641fc026a200241086a29000037020020064184036a200241106a2900003702002006418c036a200241186a290000370200200620033703c802200641003a00c0022001200641c0026a10df03200641c0006a200010be01200641c0006a41086a290300211720062903402118200641c0026a20004200420010a20120062903c0022119200641286a41c2d5c000411610a301200641286a41106a29030042002006280228220b1b210320062903304200200b1b21042008290300211a20062903c802211b0240024020194200520d0020064198036a41086a22084200370300200642003703980341c2d5c000411620064198036a1003200641c0036a41086a200829030037030020062006290398033703c0032006427f2003201a7c2004201b7c221b2004542208ad7c22042008200420035420042003511b22081b3703a0032006427f201b20081b3703980320064198036a21080c010b20064198036a41086a22084200370300200642003703980341c2d5c000411620064198036a1003200641c0036a41086a200829030037030020062006290398033703c003200642002003201a7d2004201b54ad7d22192004201b7d221b200456201920035620192003511b22081b3703a00320064200201b20081b3703980320064198036a21080b200641c0036a4110200841101005200641186a20012018201710a001200641186a41086a29030021042006290318211b200641c2d5c000411610a301200641106a2903002103200629030821172006280200210820064198036a41086a220b4200370300200642003703980341c2d5c000411620064198036a1003200641c0036a41086a200b29030037030020062006290398033703c0032006427f20042003420020081b22037c201b2017420020081b22047c221b2004542208ad7c22042008200420035420042003511b22081b3703c8022006427f201b20081b3703c002200641c0036a4110200641c0026a4110100502402009450d0020094104742109200741046a210803400240200841046a280200450d00200828020010290b200841106a2108200941706a22090d000b0b0240200a450d00200710290b200541046a280200450d0b201110290c0b0b200720094104746a2101200721082009450d0620072108034002402008280200220b0d00200841106a21080c080b200841046a2802002109200841086a28020021002008410c6a280200210c200628027021022006280268210d200641c0026a41186a220e4200370300200641c0026a41106a220f4200370300200641c0026a41086a22104200370300200642003703c002200b4120200641c0026a100020064198036a41186a200e29030037030020064198036a41106a200f29030037030020064198036a41086a2010290300370300200620062903c00237039803200d200220064198036a41202009200c101602402000450d00200910290b200841106a22082001470d000c080b0b41104104102e000b200c4104102e000b41d0f8c5004138109201000b20154101102e000b1033000b41174101102e000b20082001460d0003402008280200450d010240200841086a280200450d00200841046a28020010290b200841106a22082001470d000b0b200a450d00200710290b200641ec006a280200450d00200628026810290b200541046a280200450d00200528020010290b200641e0036a24000bb01102077f027e230041106b2202240020024100360208200242013703004104200210660240024002400240024002400240024002400240024002400240024002400240024020022802042203200228020822046b4104490d00200441046a2105200228020021030c010b200441046a22052004490d0f20034101742206200520052006491b22064100480d0f0240024020030d002006103221030c010b200228020020032006103421030b2003450d0120022006360204200220033602000b20022005360208200320046a41eede91ab06360000410e200210660240024020022802042203200228020822066b410e490d002006410e6a2104200228020021050c010b2006410e6a22042006490d0f20034101742205200420042005491b22074100480d0f0240024020030d002007103221050c010b200228020020032007103421050b2005450d022002200736020420022005360200200721030b20022004360208200520066a220641002900a4c742370000200641066a41002900aac7423700000240200320046b41034b0d00200441046a22062004490d0f20034101742207200620062007491b22064100480d0f0240024020030d002006103221050c010b200520032006103421050b2005450d0320022006360204200220053602000b2002200441046a360208200520046a410a3600000240024020022802042205200228020822046b4104490d00200228020021050c010b200441046a22032004490d0f20054101742206200320032006491b22034100480d0f0240024020050d002003103221050c010b200228020020052003103421050b2005450d0420022003360204200220053602000b2002200441046a360208200520046a419a013600000240024020022802042205200228020822046b4104490d00200228020021050c010b200441046a22032004490d0f20054101742206200320032006491b22034100480d0f0240024020050d002003103221050c010b200228020020052003103421050b2005450d0520022003360204200220053602000b2002200441046a360208200520046a419a01360000410a2002106641b4c7c2002104034002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006103221030c010b200228020020052006103421030b2003450d0720022006360204200220033602000b2002200541016a360208200320056a20042d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006103221030c010b200228020020052006103421030b2003450d0820022006360204200220033602000b2002200541016a360208200320056a200441016a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006103221030c010b200228020020052006103421030b2003450d0920022006360204200220033602000b2002200541016a360208200320056a200441026a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006103221030c010b200228020020052006103421030b2003450d0a20022006360204200220033602000b2002200541016a360208200320056a200441036a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006103221030c010b200228020020052006103421030b2003450d0b20022006360204200220033602000b2002200541016a360208200320056a200441046a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006103221030c010b200228020020052006103421030b2003450d0c20022006360204200220033602000b2002200541016a360208200320056a200441056a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006103221030c010b200228020020052006103421030b2003450d0d20022006360204200220033602000b2002200541016a360208200320056a200441066a2d00003a000002400240200228020420022802082205460d00200228020021030c010b200541016a22032005490d1020054101742206200320032006491b22064100480d100240024020050d002006103221030c010b200228020020052006103421030b2003450d0e20022006360204200220033602000b2002200541016a360208200320056a200441076a2d00003a0000200441086a28020021060240024020022802042203200228020822056b4104490d00200228020021030c010b200541046a22072005490d1020034101742208200720072008491b22074100480d100240024020030d002007103221030c010b200228020020032007103421030b2003450d0f20022007360204200220033602000b2002200541046a360208200320056a20063600002004410c6a220441acc8c200470d000b200235020821092002350200210a200241106a2400200a2009422086840f0b20064101102e000b20074101102e000b20064101102e000b20034101102e000b20034101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20074101102e000b1033000b971d020a7f017e230041900a6b22022400024002402001450d00200220003602280c010b200241013602280b2002200136022c200241f0076a200241286a1042024020022802f4072203450d00200241f0076a410c6a280200210120022802f807210420022802f0072100200241c0046a200241f0076a41106a41e000109b051a200241f0076a200241286a1043024020022802f007450d0020024190036a41086a2205200241f0076a41086a280200360200200220022903f00737039003200241f0076a200241c0046a41e000109b051a200241c0006a200241f0076a41e000109b051a200241306a41086a220620052802003602002002200229039003370330200241a0016a410c6a2001360200200241a0016a41086a2004360200200220033602a401200220003602a001200241a0016a41106a200241c0006a41e000109b05210120024198026a20062802003602002002200229033037039002200241a0016a10a1030240024002400240024020022802a0012200450d00200241f0076a2000417f6a10aa02200241f0076a20014120109d050d00410021074104210802400240024002400240024020024198026a28020022090d004104210a41042105410021094100210b0c010b2009ad420c7e220c422088a70d03200ca722014100480d03200228029002210020011032220a450d01200941a0026c2105200941057441606a2103200a21010340200220003602c004200241f0076a200241c0046a10e603200141086a200241f0076a41086a280200360200200120022903f0073702002001410c6a2101200041a0026a2100200541e07d6a22050d000b200341057641016a210b200a21050b200b410c6c2201410c6e210002402001450d00200041037422034100480d03200310322208450d04200021070b4100210302402005200520016a2206460d002008210120052100034020002802002104200141046a200041086a28020036020020012004360200200141086a2101200341016a21032000410c6a22002006470d000b0b200220033602c804200220073602c404200220083602c004200241f0076a200241c0046a10ce0202402007450d00200810290b0240200b450d00200b410c6c210103400240200541046a280200450d00200528020010290b2005410c6a2105200141746a22010d000b0b02402009450d00200a10290b0240200241f0016a2201200241f0076a4120109d05450d0041b8f7c500410e1009200141201017200241f0076a412010170b2001200241f0076a4120109d050d0120024194026a280200210620022802900221042002280298022105200241a0026a200241a0016a41f000109b051a2004200541a0026c6a210020022802a00221092004210102402005450d00200241c0046a41f0006a21032004210102400240034020024188076a200141e800109b051a200141e8006a290300210c20024190036a200141f0006a41b001109b051a200c4203510d02200241c0046a20024188076a41e800109b051a2002200c3703a805200320024190036a41b001109b051a2002200241c0046a3602e006200241f0076a200241e0066a10e60320022802f8072105024020022802f407450d0020022802f00710290b200241f0076a200241c0046a41a002109b051a200241003602f006200241e0066a200241f0076a2005200241f0066a10a30320022802e0064101460d01024020022802e4062205450d00200520022802e80610090b200141a0026a22012000470d000b200021010c020b024020022802e4060e050a00000b090a0b41ccadc300106d000b200141a0026a21010b20012000460d0520024188096a2105200241f0076a41f0006a2103034020024190036a200141e800109b051a200141e8006a290300210c200241f0076a200141f0006a41b001109b051a200c4203510d0620024188076a20024190036a41e800109b051a200241c0046a200241f0076a41b001109b051a200241f0076a20024188076a41e800109b051a2002200c3703d8082003200241c0046a41b001109b051a2005102a200141a0026a22012000470d000c060b0b20014104102e000b41ecacc300106d000b1033000b20034104102e000b41d4acc300106d000b02402006450d00200410290b200241206a41caf9c20010f0012002280224210120022802202100200241f0076a41086a22054200370300200242003703f00741b2f6c5004115200241f0076a1003200241c0046a41086a2005290300370300200220022903f0073703c00420022001410020001b3602f007200241c0046a4110200241f0076a41041005200910e901200241f0076a109e03200241186a200241a0026a410472220110a2032002200228021c220036028007200241106a200241f0076a410472220510a20320022002280214220336028407024020002003470d00200241086a200110a203200228020821032002200510a203024020022802042201200228020c2200200020014b1b2208450d002002280200210441002105410021060340024002400240024002400240024002400240200320056a22012d00002209200420056a22002d0000470d000240024002400240024020090e050001020304000b20032004460d0c200141016a200041016a4120109d050d040c070b024020032004460d00200141016a280000200041016a280000470d040b200141106a2802002209200041106a280200470d03200141086a2802002207200041086a280200220b460d092007200b2009109d050d030c090b024020032004460d00200141016a280000200041016a280000470d030b200141106a2802002209200041106a280200470d02200141086a2802002207200041086a280200220b460d072007200b2009109d050d020c070b024020032004460d00200141016a280000200041016a280000470d020b200141106a2802002209200041106a280200470d01200141086a2802002207200041086a280200220b460d052007200b2009109d050d010c050b2001410c6a28020022092000410c6a280200470d00200141046a2802002207200041046a280200220b460d012007200b2009109d05450d010b4180d8c00041141009200241c0046a2001109d0120022802c004220920022802c8041017024020022802c404450d00200910290b200241c0046a2000109d0120022802c004220920022802c8041017024020022802c404450d00200910290b20012d000020002d00002209470d0620090e050105040300010b2001410c6a28020022092000410c6a280200470d05200141046a2802002201200041046a2802002200460d06200120002009109d05450d060c050b20032004460d050b200141016a200041016a4120109d050d030c040b024020032004460d00200141016a280000200041016a280000470d030b200141106a2802002209200041106a280200470d02200141086a2802002201200041086a2802002200460d03200120002009109d050d020c030b024020032004460d00200141016a280000200041016a280000470d020b200141106a2802002209200041106a280200470d01200141086a2802002201200041086a2802002200460d02200120002009109d050d010c020b024020032004460d00200141016a280000200041016a280000470d010b200141106a2802002209200041106a280200470d00200141086a2802002201200041086a2802002200460d01200120002009109d05450d010b41fcadc300106d000b200541246a2105200641016a22062008490d000b0b0240200241a0026a41306a2201200241f0076a41306a22004120109d05450d0041b8f7c500410e10092001412010172000412010170b0240200120004120109d05450d004194aec300106d000b0240200241f0076a410c6a2802002200450d0020022802f4072101200041246c210003400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b0240200241f8076a280200450d0020022802f40710290b0240200241a0026a410c6a2802002200450d0020022802a4022101200041246c210003400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b0240200241a8026a280200450d0020022802a40210290b200241900a6a240042010f0b20024190036a41146a41023602002002419c036a410336020020024188076a41146a41033602002002420337028c07200241acf9c500360288072002410336029403200220024180076a3602f006200220024184076a3602e006200242043703d004200242013702c404200241e4adc3003602c004200220024190036a360298072002200241c0046a3602a0032002200241e0066a360298032002200241f0066a3602900320024188076a41ecadc300107d000b41b4adc300106d000b419cadc300106d000b4184adc300106d000b02402001450d00200141246c21002003210103400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b2004450d00200310290b20024184086a4102360200200241cc046a4105360200200242023702f407200241c4b6c4003602f007200241053602c404200241bcb6c4003602c0042002410036029403200241e480c600360290032002200241c0046a36028008200220024190036a3602c804200241f0076a41d4b6c400107d000bf90e03047f027e077f230041206b2202240002400240024002400240024002400240024002400240024002400240024041a20210322203450d00200241a20236020420022003360200200341003b00002002410236020802400240200128020022032903684202520d00024020022802044102470d0020022802004102410410342201450d0420024104360204200220013602000b200228020041033a00022002200228020841016a3602080c010b024020022802044102470d0020022802004102410410342201450d0420024104360204200220013602000b20022802004183013a00022002200228020841016a36020820032002109f0120022002360210200341246a200241106a1090030240024020032903684201510d0002400240200228020420022802082201460d00200228020021040c010b200141016a22042001490d1220014101742205200420042005491b22054100480d120240024020010d002005103221040c010b200228020020012005103421040b2004450d072002200536020420022004360200200228020821010b2002200141016a360208200420016a41003a00000c010b200341f8006a29030020032903702206420c882207420120074201561b8021070240024020022802042204200228020822016b4102490d00200228020021040c010b200141026a22052001490d1120044101742201200520052001491b22014100480d110240024020040d002001103221040c010b200228020020042001103421040b2004450d072002200136020420022004360200200228020821010b2002200141026a360208200420016a2007a741047420067aa7417f6a22014101200141014b1b2201410f2001410f491b723b00000b20034180016a2002109801200220034188016a360210200241106a2002109b010b20034198016a2002105f2002280208210320024100360218200242013703102003417e6a200241106a10662002280208220841014d0d0520022802182105200228021421092002280210210a2002410036020820022802002103024002402008417e6a220b450d004102210c2005450d0d2003200a2d00003a0000410121042002200228020841016a36020820054101460d0d200a20056a210d2003200a2d00013a00012002200228020841016a3602084102210c200a41026a21012005417e6a220e0d014100210e0c0b0b0240024002402002280204220120054f0d0020014101742204200520052004491b22044100480d120240024020010d002004103221030c010b200320012004103421030b2003450d0a20022004360204200220033602002002280208210c0c010b4100210c2005450d010b2003200c6a2201200a2d00003a0000024020054101470d00200c41016a210c0c010b2005417f6a2104200a41016a2103200141016a21010340200120032d00003a0000200141016a2101200341016a21032004417f6a22040d000b200c20056a210c0b2002200c3602084102210c0c0b0b024002402002280204220320086b200e490d00200228020021030c010b2008200e6a22042008490d0f2003410174220c20042004200c491b22044100480d0f0240024020030d002004103221030c010b200228020020032004103421030b2003450d0820022004360204200220033602000b200320056a200341026a200b109c051a0240200520022802082203460d00200520036b210c2005417e6a2104200228020020036a2108410021030340024020042003470d002005210c0c0d0b200820036a20012d00003a00002002200228020841016a360208200141016a2101200c200341016a2203470d000b200d20016b220e0d004100210e410121040c090b200e4100480d0e200e103222040d08200e4101102e000b41a2024101102e000b41044101102e000b41044101102e000b20054101102e000b20014101102e000b41fcd8c500106d000b20044101102e000b20044101102e000b2005210c0b0240200d2001460d00200420012d00003a000002400240200141016a200d470d00410121050c010b200a200520016b6a2108200a200520016b6a2105410121030340200420036a200120036a2d00003a00002008200341016a2203470d000b2005450d010b200420056a21080240024020022802042203200b200c6a22016b2005490d00200228020021030c010b200120056a220d2001490d0620034101742201200d200d2001491b22014100480d060240024020030d002001103221030c010b200228020020032001103421030b2003450d0520022001360204200220033602000b2003200c20056a220d6a2003200c6a200b109c051a0240200d20022802082203460d00200228020020036a2101200c20056a20036b210520042103034020082003460d01200120032d00003a00002002200228020841016a360208200341016a2103200141016a21012005417f6a22050d000b0b200d210c0b200e450d00200410290b200b450d010b0240200c20022802082203460d002002280200220120036a2001200c6a200b109c051a0b2002200b20036a3602080b02402009450d00200a10290b20002002290300370200200041086a200241086a280200360200200241206a24000f0b20014101102e000b1033000ba10301027f23004180026b22022400024002402001450d00200220003602000c010b200241013602000b20022001360204200241f8006a200210420240200228027c450d00200241086a200241f8006a41f000109b051a200241086a10a1030240200241086a410c6a2802002200450d00200228020c2101200041246c210003400240024020012d0000220341034b0d0002400240024020030e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b0240200241106a280200450d00200228020c10290b20024180026a240042010f0b200241f4016a41053602002002411c6a41023602002002420237020c200241c4b6c400360208200241053602ec01200241d0b7c4003602e801200241003602fc01200241e480c6003602f8012002200241e8016a3602182002200241f8016a3602f001200241086a41d4b6c400107d000bcc28010b7f230041d0006b220224002002410036022820024201370320024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240410410322203450d0020024284808080c00037022420022003360220200341edcad18b0636000002400240200228022420022802282203460d00200228022021040c010b200341016a22042003490d1b20034101742205200420042005491b22054100480d1b0240024020030d002005103221040c010b200228022020032005103421040b2004450d0220022005360224200220043602200b2002200341016a360228200420036a41073a00004115200241206a106641b8c8c200210603402006280204210720062802082203200241206a10660240024020022802242205200228022822046b2003490d00200228022021050c010b200420036a22082004490d1c20054101742204200820082004491b22044100480d1c0240024020050d002004103221050c010b200228022020052004103421050b2005450d042002200436022420022005360220200228022821040b2002200420036a360228200520046a20072003109b051a200228022421042002280228210302400240200628020c4102470d000240024020042003460d00200228022021040c010b200341016a22042003490d1e20034101742205200420042005491b22054100480d1e0240024020030d002005103221040c010b200228022020032005103421040b2004450d072002200536022420022004360220200228022821030b2002200341016a360228200420036a41003a00000c010b0240024020042003460d00200228022021040c010b200341016a22042003490d1d20034101742205200420042005491b22054100480d1d0240024020030d002005103221040c010b200228022020032005103421040b2004450d072002200536022420022004360220200228022821030b2002200341016a360228200420036a41013a00000240200628020c4101460d00200241306a20062802101101002002280234210720022802382203200241206a10660240024020022802242205200228022822046b2003490d00200228022021050c010b200420036a22082004490d1e20054101742204200820082004491b22044100480d1e0240024020050d002004103221050c010b200228022020052004103421050b2005450d092002200436022420022005360220200228022821040b2002200420036a360228200520046a20072003109b051a200228024021050240200228023c4101460d0020052002280244200241206a10e9030c020b200520022802482203200241206a10e90302402003450d00200341d8006c21074100210403400240200520046a220341346a280200450d002003413c6a280200450d00200341386a28020010290b0240200341c4006a280200450d00200341cc006a280200450d00200341c8006a28020010290b2007200441d8006a2204470d000b0b2002280244450d01200510290c010b2006280214210720062802182203200241206a10660240024020022802242205200228022822046b2003490d00200228022021050c010b200420036a22082004490d1d20054101742204200820082004491b22044100480d1d0240024020050d002004103221050c010b200228022020052004103421050b2005450d092002200436022420022005360220200228022821040b2002200420036a360228200520046a20072003109b051a200628022021030240200628021c4101460d002003200641246a280200200241206a10e9030c010b20032006280228200241206a10e9030b200228022421042002280228210302400240200628022c4102470d000240024020042003460d00200228022021040c010b200341016a22042003490d1e20034101742205200420042005491b22054100480d1e0240024020030d002005103221040c010b200228022020032005103421040b2004450d0b2002200536022420022004360220200228022821030b2002200341016a360228200420036a41003a00000c010b0240024020042003460d00200228022021040c010b200341016a22042003490d1d20034101742205200420042005491b22054100480d1d0240024020030d002005103221040c010b200228022020032005103421040b2004450d0b2002200536022420022004360220200228022821030b2002200341016a360228200420036a41013a00000240200628022c4101460d00200241186a200628023011010020022802182104200228021c2203200241206a10662003450d012003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a10660240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d1f20074101742205200a200a2005491b22054100480d1f0240024020070d002005103221070c010b200228022020072005103421070b2007450d0e2002200536022420022007360220200228022821050b2002200520046a360228200720056a20092004109b051a200341706a200241206a10ea032003200241206a10eb032003412c6a2103200841546a22080d000c020b0b2006280230210420062802382203200241206a10662003450d002003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a10660240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d1e20074101742205200a200a2005491b22054100480d1e0240024020070d002005103221070c010b200228022020072005103421070b2007450d0e2002200536022420022007360220200228022821050b2002200520046a360228200720056a20092004109b051a200341706a200241206a10ea032003200241206a10eb032003412c6a2103200841546a22080d000b0b200228022421042002280228210302400240200628023c4102470d000240024020042003460d00200228022021040c010b200341016a22042003490d1e20034101742205200420042005491b22054100480d1e0240024020030d002005103221040c010b200228022020032005103421040b2004450d0f2002200536022420022004360220200228022821030b2002200341016a360228200420036a41003a00000c010b0240024020042003460d00200228022021040c010b200341016a22042003490d1d20034101742205200420042005491b22054100480d1d0240024020030d002005103221040c010b200228022020032005103421040b2004450d0f2002200536022420022004360220200228022821030b2002200341016a360228200420036a41013a00000240200628023c4101460d00200241106a20062802401101002002280210210420022802142203200241206a10662003450d012003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a10660240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d1f20074101742205200a200a2005491b22054100480d1f0240024020070d002005103221070c010b200228022020072005103421070b2007450d122002200536022420022007360220200228022821050b2002200520046a360228200720056a20092004109b051a200341706a200241206a10eb032003200241206a10eb032003412c6a2103200841546a22080d000c020b0b2006280240210420062802482203200241206a10662003450d002003412c6c21082004411c6a21030340200341686a28020021092003416c6a2802002204200241206a10660240024020022802242207200228022822056b2004490d00200228022021070c010b200520046a220a2005490d1e20074101742205200a200a2005491b22054100480d1e0240024020070d002005103221070c010b200228022020072005103421070b2007450d122002200536022420022007360220200228022821050b2002200520046a360228200720056a20092004109b051a200341706a200241206a10eb032003200241206a10eb032003412c6a2103200841546a22080d000b0b02400240200628024c4101460d00200241086a20062802501101002002280208210b200228020c2203200241206a10662003450d01200341386c210c410021070340200b20076a220341046a2802002109200341086a2802002204200241206a10660240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1f20084101742205200a200a2005491b22054100480d1f0240024020080d002005103221080c010b200228022020082005103421080b2008450d142002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109b051a200341106a2802002109200341146a2802002204200241206a10660240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1f20084101742205200a200a2005491b22054100480d1f0240024020080d002005103221080c010b200228022020082005103421080b2008450d152002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109b051a02400240200341186a2802004101460d00200241306a2003411c6a280200200341206a28020028020c1100002002280230210920022802382204200241206a10660240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2120084101742205200a200a2005491b22054100480d210240024020080d002005103221080c010b200228022020082005103421080b2008450d182002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109b051a2002280234450d01200910290c010b2003411c6a2802002109200341246a2802002204200241206a10660240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2020084101742205200a200a2005491b22054100480d200240024020080d002005103221080c010b200228022020082005103421080b2008450d182002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109b051a0b200341286a200241206a10eb03200c200741386a2207470d000c020b0b2006280250210b20062802582203200241206a10662003450d00200341386c210c410021070340200b20076a220341046a2802002109200341086a2802002204200241206a10660240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1e20084101742205200a200a2005491b22054100480d1e0240024020080d002005103221080c010b200228022020082005103421080b2008450d172002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109b051a200341106a2802002109200341146a2802002204200241206a10660240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1e20084101742205200a200a2005491b22054100480d1e0240024020080d002005103221080c010b200228022020082005103421080b2008450d182002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109b051a02400240200341186a2802004101460d00200241306a2003411c6a280200200341206a28020028020c1100002002280230210920022802382204200241206a10660240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d2020084101742205200a200a2005491b22054100480d200240024020080d002005103221080c010b200228022020082005103421080b2008450d1b2002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109b051a2002280234450d01200910290c010b2003411c6a2802002109200341246a2802002204200241206a10660240024020022802242208200228022822056b2004490d00200228022021080c010b200520046a220a2005490d1f20084101742205200a200a2005491b22054100480d1f0240024020080d002005103221080c010b200228022020082005103421080b2008450d1b2002200536022420022008360220200228022821050b2002200520046a360228200820056a20092004109b051a0b200341286a200241206a10eb03200c200741386a2207470d000b0b200641dc006a220641c4d7c200470d000b2002280228220341046a2204417f4c0d1720022802242108200228022021070240024020040d00410121050c010b200410322205450d190b2002410036023820022004360234200220053602302003200241306a10660240024020022802342205200228023822046b2003490d00200228023021050c010b200420036a22092004490d1b2005410174220a20092009200a491b22094100480d1b0240024020050d002009103221050c010b200228023020052009103421050b2005450d1a20022009360234200220053602300b200520046a20072003109b051a200420036a210302402008450d00200710290b200241d0006a24002003ad4220862005ad840f0b41044101102e000b20054101102e000b20044101102e000b20054101102e000b20054101102e000b20044101102e000b20044101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b20054101102e000b102f000b20044101102e000b20094101102e000b1033000b921d010a7f230041106b22032400200120021066024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001450d00200141d8006c2104410021050340200020056a220641046a2802002107200641086a28020022082002106602400240200241046a2209280200220a200241086a2201280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d18200a410174220b200c200c200b491b220b4100480d1802400240200a0d00200b1032210a0c010b2002280200200a200b1034210a0b200a450d032002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109b051a200641d4006a2d0000210a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1820084101742207200b200b2007491b22074100480d180240024020080d0020071032210b0c010b2002280200200820071034210b0b200b450d042002200b36020020092007360200200128020021080b2001200841016a360200200b20086a200a3a000002402006410c6a2d0000220841024b0d0002400240024020080e03000102000b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1b2008410174220a200b200b200a491b220a4100480d1b0240024020080d00200a1032210b0c010b20022802002008200a1034210b0b200b450d082002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41003a0000200641146a2802002107200641186a280200220820021066024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1b200a410174220b200c200c200b491b220b4100480d1b02400240200a0d00200b1032210a0c010b2002280200200a200b1034210a0b200a450d092002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109b051a0c020b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a2008410174220a200b200b200a491b220a4100480d1a0240024020080d00200a1032210b0c010b20022802002008200a1034210b0b200b450d092002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41013a00002006410d6a2d0000210a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a20084101742207200b200b2007491b22074100480d1a0240024020080d0020071032210b0c010b2002280200200820071034210b0b200b450d0a2002200b36020020092007360200200128020021080b2001200841016a360200200b20086a200a3a0000200641146a2802002107200641186a280200220820021066024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1a200a410174220b200c200c200b491b220b4100480d1a02400240200a0d00200b1032210a0c010b2002280200200a200b1034210a0b200a450d0b2002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109b051a200641206a2802002107200641246a280200220820021066024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1a200a410174220b200c200c200b491b220b4100480d1a02400240200a0d00200b1032210a0c010b2002280200200a200b1034210a0b200a450d0c2002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109b051a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a2008410174220a200b200b200a491b220a4100480d1a0240024020080d00200a1032210b0c010b20022802002008200a1034210b0b200b450d0d2002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a2006410e6a2d00003a00000c010b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d192008410174220a200b200b200a491b220a4100480d190240024020080d00200a1032210b0c010b20022802002008200a1034210b0b200b450d0d2002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41023a00002006410d6a2d0000210a02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1920084101742207200b200b2007491b22074100480d190240024020080d0020071032210b0c010b2002280200200820071034210b0b200b450d0e2002200b36020020092007360200200128020021080b2001200841016a360200200b20086a200a3a0000200641146a2802002107200641186a280200220820021066024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200c200b491b220b4100480d1902400240200a0d00200b1032210a0c010b2002280200200a200b1034210a0b200a450d0f2002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109b051a200641206a2802002107200641246a280200220820021066024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200c200b491b220b4100480d1902400240200a0d00200b1032210a0c010b2002280200200a200b1034210a0b200a450d102002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109b051a2006412c6a2802002107200641306a280200220820021066024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200c200b491b220b4100480d1902400240200a0d00200b1032210a0c010b2002280200200a200b1034210a0b200a450d112002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109b051a2006410e6a2d0000220841044b0d000240024002400240024020080e050001020304000b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1d2008410174220a200b200b200a491b220a4100480d1d0240024020080d00200a1032210b0c010b20022802002008200a1034210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41003a00000c040b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1c2008410174220a200b200b200a491b220a4100480d1c0240024020080d00200a1032210b0c010b20022802002008200a1034210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41013a00000c030b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1b2008410174220a200b200b200a491b220a4100480d1b0240024020080d00200a1032210b0c010b20022802002008200a1034210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41023a00000c020b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d1a2008410174220a200b200b200a491b220a4100480d1a0240024020080d00200a1032210b0c010b20022802002008200a1034210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41033a00000c010b02400240200928020020012802002208460d002002280200210b0c010b200841016a220b2008490d192008410174220a200b200b200a491b220a4100480d190240024020080d00200a1032210b0c010b20022802002008200a1034210b0b200b450d162002200b3602002009200a360200200128020021080b2001200841016a360200200b20086a41043a00000b02400240200641346a2802004101460d002003200641386a2802002006413c6a28020028020c110000200328020021072003280208220820021066024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d1a200a410174220b200c200c200b491b220b4100480d1a02400240200a0d00200b1032210a0c010b2002280200200a200b1034210a0b200a450d182002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109b051a2003280204450d01200710290c010b200641386a2802002107200641c0006a280200220820021066024002402009280200220a2001280200220b6b2008490d002002280200210a0c010b200b20086a220c200b490d19200a410174220b200c200c200b491b220b4100480d1902400240200a0d00200b1032210a0c010b2002280200200a200b1034210a0b200a450d182002200a3602002009200b3602002001280200210b0b2001200b20086a360200200a200b6a20072008109b051a0b200641c4006a200210eb032004200541d8006a2205470d000b0b200341106a24000f0b200b4101102e000b20074101102e000b200a4101102e000b200b4101102e000b200a4101102e000b20074101102e000b200b4101102e000b200b4101102e000b200a4101102e000b200a4101102e000b20074101102e000b200b4101102e000b200b4101102e000b200b4101102e000b200a4101102e000b200a4101102e000b200a4101102e000b200a4101102e000b200a4101102e000b200b4101102e000b200b4101102e000b1033000bfe0601087f20002802042102024002400240024002400240024020002802004101460d00200041086a2802002200200110662000450d01200041186c2103200241146a2100200141086a2102200141046a21040340200041706a2802002105200041746a2802002206200110660240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d0820074101742208200920092008491b22084100480d080240024020070d002008103221070c010b200128020020072008103421070b2007450d042001200736020020042008360200200228020021080b2002200820066a360200200720086a20052006109b051a2000417c6a280200210520002802002206200110660240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d0820074101742208200920092008491b22084100480d080240024020070d002008103221070c010b200128020020072008103421070b2007450d052001200736020020042008360200200228020021080b2002200820066a360200200720086a20052006109b051a200041186a2100200341686a22030d000c020b0b2000410c6a2802002200200110662000450d00200041186c2103200241146a2100200141086a2102200141046a21040340200041706a2802002105200041746a2802002206200110660240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d0720074101742208200920092008491b22084100480d070240024020070d002008103221070c010b200128020020072008103421070b2007450d052001200736020020042008360200200228020021080b2002200820066a360200200720086a20052006109b051a2000417c6a280200210520002802002206200110660240024020042802002207200228020022086b2006490d00200128020021070c010b200820066a22092008490d0720074101742208200920092008491b22084100480d070240024020070d002008103221070c010b200128020020072008103421070b2007450d062001200736020020042008360200200228020021080b2002200820066a360200200720086a20052006109b051a200041186a2100200341686a22030d000b0b0f0b20084101102e000b20084101102e000b20084101102e000b20084101102e000b1033000b800401087f200028020421020240024002400240024020002802004101460d00200041086a28020022002001106620004103742200450d01200220006a2103200141086a2104034020022802002105200241046a28020022002001106602400240200141046a22062802002207200428020022086b2000490d00200128020021070c010b200820006a22092008490d0620074101742208200920092008491b22084100480d060240024020070d002008103221070c010b200128020020072008103421070b2007450d042001200736020020062008360200200428020021080b2004200820006a360200200720086a20052000109b051a200241086a22022003470d000c020b0b2000410c6a28020022002001106620004103742200450d00200220006a2103200141086a2104034020022802002105200241046a28020022002001106602400240200141046a22062802002207200428020022086b2000490d00200128020021070c010b200820006a22092008490d0520074101742208200920092008491b22084100480d050240024020070d002008103221070c010b200128020020072008103421070b2007450d042001200736020020062008360200200428020021080b2004200820006a360200200720086a20052000109b051a200241086a22022003470d000b0b0f0b20084101102e000b20084101102e000b1033000bcd0301027f230041a0076b22022400024002402001450d00200220003602080c010b200241013602080b2002200136020c200241f0046a200241086a104402400240024020022903d8054203510d00200241106a200241f0046a41a002109b051a200241b0026a200241106a41a002109b051a2002200241b0026a3602f004200241d0046a200241f0046a10e60320022802d8042101200241f0046a200241b0026a41a002109b051a20024198076a20022802d804360200200220022903d00437039007200241e0046a200241f0046a200120024190076a10a303410121000240024020022802e0044101460d004100210020022802e40441004721030c010b4280828898f01f20022802e404410374ad88a721030b410110322201450d01200120003a000020014101410210342201450d02200120033a0001200241a0076a24002001ad428080808020840f0b2002411c6a4105360200200241c4026a4102360200200242023702b402200241c4b6c4003602b00220024105360214200241e8b7c400360210200241003602e404200241e480c6003602e0042002200241106a3602c0022002200241e0046a360218200241b0026a41d4b6c400107d000b41014101102e000b41024101102e000b8d0e04087f017e067f017e230041d0016b22022400200241186a41caf9c20010f001200228021c210320022802182104200241a0016a41086a22054200370300200242003703a00141b2f6c5004115200241a0016a100320024190016a41086a2005290300370300200220022903a001370390014100210620022003410020041b3602204104210720024190016a4110200241206a41041005200241106a41d983c300410d105d2002280214410020022802101b10e901200241086a41b2f6c5004115105d0240024002400240024002400240200228020c410020022802081b22080d004104210541042109410021080c010b2008ad420c7e220a422088a70d04200aa722034100480d04200310322205450d0520052103410021040340200241a0016a200410a40320022802a801210b20022802a001210c200241206a41186a220d4200370300200241206a41106a22094200370300200241206a41086a220e420037030020024200370320200c200b200241206a1000200241b0016a41186a200d290300370300200241b0016a41106a2009290300370300200241b0016a41086a200e290300370300200220022903203703b00120024100360220200241b0016a4120200241206a10062109024002402002280220220e417f460d002009450d002002200e360224200220093602202002200241206a102c02400240024020022802000d002002280224220f2002280204220d490d00200d417f4c0d0702400240200d0d004101210b0c010b200d102d220b450d02200b20022802202210200d109b051a2002200f200d6b36022420022010200d6a3602200b200b0d020b41f7cdc300413320024190016a41ecd6c3001054000b200d4101102e000b200dad220a42208621110240200e450d00200910290b2011200a84210a200241b0016a412010040c010b4101210b4200210a0b200441016a2104024020022802a401450d00200c10290b2003200b360200200341046a200a3702002003410c6a210320082004470d000b200521090b2008410c6c2203410c6e210402402003450d002004410374220b4100480d04200b10322207450d02200421060b4100210b02402005200520036a220d460d00200721032005210403402004280200210c200341046a200441086a2802003602002003200c360200200341086a2103200b41016a210b2004410c6a2204200d470d000b0b2002200b3602282002200636022420022007360220200241b0016a200241206a10ce0202402006450d00200710290b02402008450d002008410c6c210303400240200541046a280200450d00200528020010290b2005410c6a2105200341746a22030d000b2008450d00200910290b200241206a41186a200241b0016a41186a290300370300200241206a41106a2203200241b0016a41106a290300370300200241206a41086a200241b0016a41086a290300370300200220022903b001370320200241a0016a41086a22044200370300200242003703a00141e683c3004115200241a0016a100320024190016a41086a2004290300370300200220022903a00137039001200241103602a401200220024190016a3602a001200241206a200241a0016a108901200241206a109e03200241003602a801200242013703a0012002200241a0016a3602b0012003200241b0016a108501200241206a200241a0016a1098012002200241a0016a3602b001200241d0006a200241b0016a1085012002200241a0016a3602b001200241f0006a200241b0016a108501200228022421052002412c6a2802002203200241a0016a106602402003450d00200341246c210d0340200241b0016a2005109d0120022802b001210c0240024020022802a401220b20022802a80122036b20022802b8012204490d0020022802a001210b0c010b200320046a22092003490d06200b4101742203200920092003491b22034100480d0602400240200b0d0020031032210b0c010b20022802a001200b20031034210b0b200b450d05200220033602a4012002200b3602a00120022802a80121030b2002200320046a3602a801200b20036a200c2004109b051a024020022802b401450d00200c10290b200541246a2105200d415c6a220d0d000b0b20023502a801210a20022802a001210b0240200228022c2204450d0020022802242103200441246c210403400240024020032d0000220541034b0d0002400240024020050e0404000102040b2003410c6a280200450d03200341086a28020010290c030b2003410c6a280200450d02200341086a28020010290c020b2003410c6a280200450d01200341086a28020010290c010b200341086a280200450d00200341046a28020010290b200341246a21032004415c6a22040d000b0b0240200241286a280200450d00200228022410290b200241d0016a2400200a422086200bad840f0b102f000b200b4104102e000b20034101102e000b1033000b20034104102e000bae2805017f027e107f027e047f230041d0036b22022400024002402001450d00200220003602200c010b200241013602200b20022001360224200241186a200241206a102c024020022802180d00200228021c21012002200241206a3602b801200241003a00b003200242003702a402200241b0d6c0003602a0022002200136023c200241003602382002200241b0036a3602442002200241b8016a360240200241386a200241a0026a10ef0320022802a002210120022902a4022103024020022d00b003450d0020012003a72003422088a710c5010c010b2001450d002002200337022c20022001360228200241386a200241286a10f0030240024002400240024002400240024002400240024002400240024020022802384101460d00200241386a41086a2903002103200241086a41cc83c300410d10d5012002290310210420022802082101024041a00210322205450d002005200241a0026a41e800109b0522064202370368200641023a009801200620022903b801370370200641f8006a200241b8016a41086a29030037030020064180016a200241c8016a29030037030020064188016a200241d0016a29030037030020064190016a200241d8016a290300370300200620022800b003360099012006419c016a200241b0036a41036a28000036000020062003200442dc0b7c42dc0b20011b220420042003541b3703a001200641a8016a200241386a41f800109b051a200241286a2101200228022c210703402001280200220841086a210020082f0106220941037421014100210a0240024003402001450d0141b9f7c20020004108109d05220b450d02200141786a2101200a41016a210a200041086a2100200b417f4a0d000b200a417f6a21090b024020070d00410121090c070b2007417f6a2107200820094102746a41e4016a21010c010b0b20022008200a410c6c6a220141e8006a2802003602a4022002200141e0006a2802003602a002200241386a200241a0026a104102402002280238220c0d00410121090c050b200228023c210d200241386a41086a22012802002209450d02200241a0026a41086a22004200370300200242003703a00241b6f0c2004111200241a0026a100320012000290300370300200220022903a002370338200241003602a002200241386a4110200241a0026a1006210102400240024020022802a0022200417f460d002001450d00200220003602bc01200220013602b801200241a0026a200241b8016a103e20022802a0022207450d02200241a8026a280200210e20022802a402210f2000450d01200110290c010b4100210f410421074100210e0b2007200e41c4006c22016a210002400240024002400240024020010d00200721010c010b4100210a024003402007200a6a22012d0000210b200241386a200141016a41c300109b051a200b4102460d01200241a0026a41186a200241386a41186a290000370300200241a0026a41106a200241386a41106a290000370300200241a0026a41086a200241386a41086a290000370300200220022900383703a002200b4101460d03200a41c4006a210a200141c4006a2000470d000b200021010c010b200141c4006a21010b0240034020002001460d0120012d0000210a200141c4006a2101200a4102470d000b0b41012108410021100240200f0d00410021110c020b20071029410021110c010b200241b8016a41086a220b200241a0026a41086a290300370300200241b8016a41106a2210200241a0026a41106a290300370300200241b8016a41186a2212200241a0026a41186a290300370300200220022903a002220337039003200220033703b801412010322208450d02200820022903b801370000200841186a2012290300370000200841106a2010290300370000200841086a200b2903003700004101211002400240200e41c4006c41bc7f6a200a470d00410121110c010b200141c4006a2d0000210a200241386a200141c5006a41c300109b051a20014188016a21120240200a4102470d0041012111201221000c010b2007200e41c4006c6a210b410121104101211103402012210102400340200241a0026a41186a2212200241386a41186a290000370300200241a0026a41106a2213200241386a41106a290000370300200241a0026a41086a2214200241386a41086a290000370300200220022900383703a002200a41ff01714101460d01200b2001460d0320012d0000210a200241386a200141016a41c300109b051a200141c4006a2101200a4102470d000b200121000c020b200241b8016a41086a20142903002203370300200241b8016a41106a20132903002204370300200241b8016a41186a20122903002215370300200220022903a00222163703b80120024190036a41186a2212201537030020024190036a41106a2213200437030020024190036a41086a221420033703002002201637039003024020112010470d00201041016a220a2010490d1520104101742217200a200a2017491b221141ffffff3f712011470d152011410574220a4100480d150240024020100d00200a103221080c010b20082010410574200a103421080b2008450d040b200820104105746a220a200229039003370000200a41186a2012290300370000200a41106a2013290300370000200a41086a2014290300370000201041016a2110200b2001460d0120012d0000210a200241386a200141016a41c300109b051a200141c4006a2112200a4102470d000b200141c4006a21000b2007200e41c4006c6a210a02400340200a2000460d0120002d00002101200041c4006a210020014102470d000b0b200f450d00200710290b200c200941f0006c6a2109200241a0026a41106a2118200241a0026a41086a21134200210341042119200c210b02400340200b2802042101200b2802002100200241386a200b41086a41e800109b051a200b41f0006a210b024020010d00200b2009460d090340200b2802042207450d0a200b41086a280200210e0240200b410c6a2802002201450d00200141246c21002007210103400240024020012d0000220a41034b0d00024002400240200a0e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b200b41f0006a210b0240200e450d00200710290b200b2009470d000c0a0b0b200241b8016a200241386a41e800109b051a200220013602a402200220003602a0022013200241b8016a41e800109b051a200241d983c300410d105d2002280200210120022802042100200241b0036a200241a0026a10ef02024002400240024020022802a002417f6a220a2000410020011b22014f0d00200241386a200a10aa02200241386a20184120109d050d0020022802a002221a41002001417b6a2200200020014b1b490d00200241b0036a20086b220741606a210f200741406a2112200741a07f6a211420082010410574220a6a210e410021010240024002400340024002400240200e200820016a22006b41e0004b0d0020104105742001470d01410021000c060b024020072001470d00200241b0036a21000c060b2000200241b0036a4120109d05450d05200f2001470d01200241b0036a21000c050b03400240200241b0036a2000470d00200241b0036a21000c060b2000200241b0036a4120109d05450d05200041206a2100200a41606a220a0d000b410021000c040b200041206a2217200241b0036a4120109d05450d02024020122001470d00200241b0036a21000c040b200041c0006a2217200241b0036a4120109d05450d01024020142001470d00200241b0036a21000c040b200a41807f6a210a20014180016a2101200041e0006a200241b0036a4120109d050d000b200820016a41606a21000c020b201721000c010b201721000b200241386a201a10aa02200241386a200241b0036a4120109d05210120000d0020010d010b024020022802ac022200450d0020022802a4022101200041246c210003400240024020012d0000220a41034b0d00024002400240200a0e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b20022802a802450d0120022802a40210290c010b200241b0036a200241a0026a10ef02200241386a200241a0026a41f000109b051a0240024020034220882204a722012003a7460d00200121000c010b200141016a220a2001490d162004a722004101742207200a200a2007491bad220342f0007e2204422088a70d162004a7220a4100480d160240024020010d00200a103221190c010b2019200141f0006c200a103421190b2019450d020b2019200041f0006c6a200241386a41f000109b051a200241386a41186a220a200241b0036a41186a290300370300200241386a41106a2207200241b0036a41106a290300370300200241386a41086a220e200241b0036a41086a290300370300200220022903b003370338024020102011470d00201041016a22012010490d162010410174220f20012001200f491b221141ffffff3f712011470d16201141057422014100480d160240024020100d002001103221080c010b200820104105742001103421080b2008450d040b200342ffffffff0f83200041016aad422086842103200820104105746a22012002290338370000200141186a200a290300370000200141106a2007290300370000200141086a200e290300370000201041016a21100b200b2009470d010c090b0b200a4104102e000b20014101102e000b200a4101102e000b41204101102e000b41f7cdc3004133200241b0036a41ecd6c3001054000b41a0024108102e000b2002200229023c3703a00241f286c3004128200241a0026a41ac84c3001054000b41012109200d450d01200c10290c010b0240200d450d00200c10290b02402011450d00200810290b0240200342ffffffff0f560d00410121092003a7450d01201910290c010b024020190d00410121090c010b200641a00241c00410342205450d01200541a0026a200241a0026a41e800109b051a2005420237038803200541033a00b803200520033703c003200520193602bc03200520022903b8013703900320054198036a200241c0016a290300370300200541a0036a200241c8016a290300370300200541a8036a200241d0016a290300370300200541b0036a200241d8016a290300370300200520022f00b0033b00b90341022109200541bb036a200241b0036a41026a2d00003a0000200541c8036a200241386a41f800109b051a0b200241286a2101200228022c210603402001280200220841086a210020082f0106220741037421014100210a0240024003402001450d014199dbc20020004108109d05220b450d02200141786a2101200a41016a210a200041086a2100200b417f4a0d000b200a417f6a21070b2006450d062006417f6a2106200820074102746a41e4016a21010c010b0b200841e0006a200a410c6c6a22012802084104490d0420012802002800002106200241a0026a41086a22014200370300200242003703a002419fbbc1004115200241a0026a1003200241386a41086a2001290300370300200220022903a00237033841002101200241003602a002200241386a4110200241a0026a1006210a20022802a0022200417f460d02200220003602bc012002200a3602b801200241a0026a200241b8016a103c20022802a002220b450d01200241a8026a280200210120022802a40221082000450d03200a10290c030b41c0044108102e000b41f7cdc3004133200241b0036a41ecd6c3001054000b4104210b410021080b4100210002402001417f6a220a20014b0d00200a20014f0d00200b200a4102746a2201450d00200128020020064721000b02402008450d00200b10290b20000d010b2009210f0c010b2005200941a0026c220120094101742200200941016a220f200f2000491b41a0026c220010342205450d01200520016a200241a0026a41e800109b05220142023703682001410d3a0098012001419c016a2006360200200120022903b801370370200141f8006a200241c0016a29030037030020014180016a200241c8016a29030037030020014188016a200241d0016a29030037030020014190016a200241d8016a29030037030020014199016a20022f00b0033b00002001419b016a200241b2036a2d00003a0000200141a0016a200241386a418001109b051a0b2002280228200228022c200228023010c501200241003602a802200242013703a002200f200241a0026a1066200f41a0026c210920022802a402210620022802a80221012005210a03402002200a3602b801200241386a200241b8016a10e6032002280238210702400240200620016b20022802402208490d00200120086a210020022802a002210b0c010b200120086a22002001490d042006410174220b20002000200b491b220e4100480d040240024020060d00200e1032210b0c010b20022802a0022006200e1034210b0b200b450d032002200e3602a4022002200b3602a002200e21060b200220003602a802200b20016a20072008109b051a0240200228023c450d00200710290b200a41a0026a210a20002101200941e07d6a22090d000b200f41a0026c210a20054198016a210103402001102a200141a0026a2101200a41e07d6a220a0d000b20051029200241d0036a24002000ad422086200bad840f0b20004108102e000b200e4101102e000b1033000b200241ac026a4105360200200241cc006a41023602002002420237023c200241c4b6c400360238200241053602a40220024180b8c4003602a002200241003602bc01200241e480c6003602b8012002200241a0026a3602482002200241b8016a3602a802200241386a41d4b6c400107d000bd50505067f017e047f017e027f23004180026b22022400024002400240024002402000280200220320002802044f0d00200028020c2104200141086a2105200241a0016a4102722106024003402000200341016a360200200241186a2000280208280200220710b10120022d00184101460d0120022900192108200241086a2007102c20022802080d012007280204200228020c2203490d012003417f4c0d0302400240024020030d00410121090c010b2003102d2209450d0820072802042003490d01200920072802002003109b051a2007280204220a2003490d062007200a20036b3602042007200728020020036a3602000b20022008370310024002402001280200220b41b0d6c000460d002001280204210c0c010b2006410041da00109a051a200241186a4100418401109a051a41e4011032220b450d074100210c200b4100360200200b41046a200241a0016a41dc00109b051a200b41e0006a200241186a418401109b051a200141003602042001200b3602000b2003ad220d422086200d84210d024002400340200b41086a2107200b2f0106220e41037421034100210a024003402003450d01200241106a20074108109d05220f450d03200341786a2103200a41016a210a200741086a2107200f417f4a0d000b200a417f6a210e0b0240200c450d00200c417f6a210c200b200e4102746a41e4016a280200210b0c010b0b2002200837022c200220053602282002200e360224200220013602202002200b36021c200241003602182002200d3702a401200220093602a001200241186a200241a0016a10ca010c010b200b200a410c6c6a220341e4006a2207280200210a2007200d370200200341e0006a22072802002103200720093602002003450d00200a450d00200310290b200028020022032000280204490d010c030b0b200910290b200441013a00000b20024180026a24000f0b102f000b2003200a1030000b41e4014104102e000b20034101102e000bf00101067f2001280204210202400240024003402001280200220341086a210420032f01062205410374210141002106024003402001450d014184f4c50020044108109d052207450d03200141786a2101200641016a2106200441086a21042007417f4a0d000b2006417f6a21050b02402002450d002002417f6a2102200320054102746a41e4016a21010c010b0b2000418cf4c500360204200041086a41283602000c010b200341e0006a2006410c6c6a220128020841074b0d01200041b4f4c500360204200041086a41293602000b200041013602000f0b200041086a2001280200290000370300200041003602000be02b06087f017e097f027e017f017e230041c0026b22022400024002402001450d00200220003602200c010b200241013602200b20022001360224200241d8006a200241206a104202400240200228025c2203450d00200241e4006a280200210420022802602105200241d8006a200241206a1043200228025822060d0102402004450d00200441246c21002003210103400240024020012d0000220741034b0d0002400240024020070e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b2005450d00200310290b200241ec016a4105360200200241ec006a41023602002002420237025c200241c4b6c400360258200241053602e4012002419cb8c4003602e0012002410036023c200241e480c6003602382002200241e0016a3602682002200241386a3602e801200241d8006a41d4b6c400107d000b200241e0006a2802002108200228025c2109200241186a200241206a102c0240024020022802180d00200228021c21012002200241206a360238200241003a0048200242003702e401200241b0d6c0003602e0012002200136025c200241003602582002200241c8006a3602642002200241386a360260200241d8006a200241e0016a10ef0320022802e001210120022902e401210a024020022d0048450d002001200aa7200a422088a710c5010c010b20010d010b200241ec016a4105360200200241ec006a41023602002002420237025c200241c4b6c400360258200241053602e4012002419cb8c4003602e0012002410036023c200241e480c6003602382002200241e0016a3602682002200241386a3602e801200241d8006a41d4b6c400107d000b2002200a37022c20022001360228200241013b01442002420037023c200241b0d6c000360238200241386a41086a210b024002400240024002402008450d002006200841a0026c6a210c200241e0016a410272210d2006210e024002400240024002400240024002400340200e41e8006a2903004202520d0902400240200e2d009801410247220f0d00200e2903a001210a200241286a2101200228022c21100240024002400240024002400240024002400240024002400240024002400240024003402001280200221141086a210020112f010622124103742101410021070240024003402001450d0141f4f0c50020004108109d052213450d02200141786a2101200741016a2107200041086a21002013417f4a0d000b2007417f6a21120b2010450d022010417f6a2110201120124102746a41e4016a21010c010b0b0240201141e0006a2007410c6c6a220128020841074b0d00201442808080807083422984210a41fcf0c50021120c020b200a42b8178020012802002900002214510d0341fe85c1002112413121100c020b201442808080807083421c84210a41a5f1c50021120b200aa721100b024002400240024020022d0045450d004131210141eef7c20021000c010b2002280238200228023c200228024010c5012002420037023c200241b0d6c000360238200242e2c289abb68edbb7f400370348200241e0016a410272410041da00109a051a200241d8006a4100418401109a051a41e40110322213450d0420134100360200201341046a200241e0016a41dc00109b051a201341e0006a200241d8006a418401109b051a2002410036023c2002201336023820132f0106220e4103742111417f210041002101024002400340024020112001470d00200e21000c020b200241c8006a201320016a41086a4108109d052207450d02200141086a2101200041016a2100200741004e0d000b0b200242e2c289abb68edbb7f40037026c2002200b360268200220003602642002201336025c200241003602582002200241386a360260201041046a2200417f4c0d062000450d02200010322201450d07200241003602bc02200220013602e0012010413f4b0d03200120104102743a0000410121070c1a0b412d210141c1f7c20021000b2002200136025c20022000360258419ff8c2004122200241d8006a41c4f8c2001054000b200241003602bc0241012100200241013602e001410110322201450d05200141033a0000200241013602bc02200220013602e001410521070c120b201041808001490d152010418080808004490d140c0f0b200f0d0d200e2903a0012115200241d8006a200241286a10f0030240024020022802584101470d002002350260210a200228025c21164101210f0c010b2002290360210a200241086a41cc83c300410d10d50102402015200a423c7c560d004100210f2015200229031042dc0b7c42dc0b20022802081b220a540d010c0f0b201742808080807083422584210a4101210f41cd86c30021160b024020022d0045450d004131210141eef7c20021000c070b0240200f450d002002280238200228023c200228024010c5012002420037023c200241b0d6c000360238200242f4d2b59bc7ae98b8303703480c050b20022802382111200242f4d2b59bc7ae98b830370348201141b0d6c000460d04200228023c21100c050b41e4014104102e000b102f000b20004101102e000b41014101102e000b200d410041da00109a051a200241d8006a4100418401109a051a41e40110322211450d024100211020114100360200201141046a200241e0016a41dc00109b051a201141e0006a200241d8006a418401109b051a2002410036023c200220113602380b02400340201141086a210020112f01062212410374210141002107024003402001450d01200241c8006a20004108109d052213450d03200141786a2101200741016a2107200041086a21002013417f4a0d000b2007417f6a21120b02402010450d002010417f6a2110201120124102746a41e4016a28020021110c010b0b200242f4d2b59bc7ae98b83037026c2002200b360268200220123602642002201136025c200241003602582002200241386a360260200241003602e801200242013703e0014101103221010240200f0d002001450d04200141003a000020024281808080103702e401200220013602e00120014101410910342201450d052001200a3700012002428980808090013702e401200220013602e0010c080b2001450d05200141013a000020024281808080103702e401200220013602e001200aa72201200241e0016a10660240024020022802e401220720022802e80122006b2001490d0020022802e00121070c010b200020016a22132000490d1620074101742211201320132011491b22134100480d160240024020070d002013103221070c010b20022802e00120072013103421070b2007450d07200220133602e401200220073602e0010b2002200020016a3602e801200720006a20162001109b051a0c070b412d210141c1f7c20021000b2002200136025c20022000360258419ff8c2004122200241d8006a41c4f8c2001054000b41e4014104102e000b41014101102e000b41094101102e000b41014101102e000b20134101102e000b200241c8006a41086a200241e0016a41086a280200360200200220022903e001370348200241d8006a200241c8006a10ca012002200f3a0045200241003a0044200a2117200f450d00200241e0016a41086a200241386a41086a290300370300200220022903383703e0010c0c0b200e41a0026a220e200c470d010c0a0b0b200141033a0000200241013602bc022000417f6a41034b0d01200041017422074105200741054b1b22074100480d0a0b20012000200710342201450d01200220013602e001200721000b20012010360001410521070c030b20074101102e000b02400240200041034b0d00200041017422074104200741044b1b22074100480d0820012000200710342201450d01200220013602e001200721000b20012010410274410272360000410421070c020b20074101102e000b0240200041014b0d0020012000200041017422074102200741024b1b220710342201450d02200220013602e001200721000b41022107200120104102744101723b00000b200220073602bc0202400240200020076b2010490d00200021130c010b200720106a22132007490d0520004101742211201320132011491b22134100480d0520012000201310342201450d02200220013602e0010b2002200720106a3602bc02200120076a20122010109b051a2002201336024c200220022802e001360248200220022802bc02360250200241d8006a200241c8006a10ca0120024180023b0144200241e0016a41086a200241386a41086a290300370300200220022903383703e0010c030b20074101102e000b20134101102e000b200241e0016a41086a200b290300370300200220022903383703e0010b2002280228200228022c200228023010c50102402004450d00200441246c21002003210103400240024020012d0000220741034b0d0002400240024020070e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b02402005450d00200310290b02402008450d00200841a0026c210020064198016a210103402001102a200141a0026a2101200041e07d6a22000d000b0b02402009450d00200610290b2002410036026020024201370358410110322201450d022002410136025c20022002280260220041016a36026020022001360258200120006a20022d00ec013a000002400240200228025c20022802602201460d00200228025821000c010b200141016a22002001490d0120014101742207200020002007491b22074100480d010240024020010d002007103221000c010b200228025820012007103421000b2000450d022002200736025c20022000360258200228026021010b2002200141016a360260200020016a20022d00ed013a000020022802e801200241d8006a106620022802e00122072100024020022802e4012213450d002013210120072100034020002802e40121002001417f6a22010d000b0b0240024002400240024002400240024002400240024020022802e80122120d00410021010c010b200241e0016a210f41002113034002400240201320002f01064f0d0020002013410c6c6a41e0006a2111200020134103746a41086a2101201341016a21130c010b02400240200028020022010d00201542808080807083200fad84211541002107410021010c010b2000330104422086200fad842115410121070b201521142015210a02402015422088a7220020012f0106490d000340200a221442ffffffff0f83210a200741016a210720012f01042200200128020022012f01064f0d000b0b20012000410c6c6a2113200120004103746a2110200041027420016a41e8016a28020021002014a7210f02402007417f6a2201450d00034020002802e40121002001417f6a22010d000b0b201341e0006a2111201041086a2101410021130b02400240200228025c20022802602207460d00200228025821100c010b200741016a22102007490d0c2007410174220e20102010200e491b220e4100480d0c0240024020070d00200e103221100c010b20022802582007200e103421100b2010450d032002200e36025c20022010360258200228026021070b2002200741016a360260201020076a20012d00003a000002400240200228025c20022802602207460d00200228025821100c010b200741016a22102007490d0c2007410174220e20102010200e491b220e4100480d0c0240024020070d00200e103221100c010b20022802582007200e103421100b2010450d042002200e36025c20022010360258200228026021070b2002200741016a360260201020076a20012d00013a000002400240200228025c20022802602207460d00200228025821100c010b200741016a22102007490d0c2007410174220e20102010200e491b220e4100480d0c0240024020070d00200e103221100c010b20022802582007200e103421100b2010450d052002200e36025c20022010360258200228026021070b2002200741016a360260201020076a20012d00023a000002400240200228025c20022802602207460d00200228025821100c010b200741016a22102007490d0c2007410174220e20102010200e491b220e4100480d0c0240024020070d00200e103221100c010b20022802582007200e103421100b2010450d062002200e36025c20022010360258200228026021070b2002200741016a360260201020076a20012d00033a000002400240200228025c20022802602207460d00200228025821100c010b200741016a22102007490d0c2007410174220e20102010200e491b220e4100480d0c0240024020070d00200e103221100c010b20022802582007200e103421100b2010450d072002200e36025c20022010360258200228026021070b2002200741016a360260201020076a20012d00043a000002400240200228025c20022802602207460d00200228025821100c010b200741016a22102007490d0c2007410174220e20102010200e491b220e4100480d0c0240024020070d00200e103221100c010b20022802582007200e103421100b2010450d082002200e36025c20022010360258200228026021070b2002200741016a360260201020076a20012d00053a000002400240200228025c20022802602207460d00200228025821100c010b200741016a22102007490d0c2007410174220e20102010200e491b220e4100480d0c0240024020070d00200e103221100c010b20022802582007200e103421100b2010450d092002200e36025c20022010360258200228026021070b2002200741016a360260201020076a20012d00063a000002400240200228025c20022802602207460d00200228025821100c010b200741016a22102007490d0c2007410174220e20102010200e491b220e4100480d0c0240024020070d00200e103221100c010b20022802582007200e103421100b2010450d0a2002200e36025c20022010360258200228026021070b2002200741016a360260201020076a20012d00073a00002011280200211020112802082201200241d8006a106602400240200228025c2211200228026022076b2001490d00200228025821110c010b200720016a220e2007490d0c20114101742207200e200e2007491b22074100480d0c0240024020110d002007103221110c010b200228025820112007103421110b2011450d0b2002200736025c20022011360258200228026021070b2002200720016a360260201120076a20102001109b051a2012417f6a22120d000b20022802e801210120022802e401211320022802e00121070b2002350258210a2002350260211420072013200110c501200241c0026a2400200a2014422086840f0b200e4101102e000b200e4101102e000b200e4101102e000b200e4101102e000b200e4101102e000b200e4101102e000b200e4101102e000b200e4101102e000b20074101102e000b1033000b20074101102e000b41014101102e000b5702017f027e230041306b22022400200241014100109c0320024100360228200242013703202002200241206a36022c20022002412c6a1085012002350228210320023502202104200241306a240020042003422086840bf95a040b7f017e127f027e230041b00a6b22022400024002402001450d00200220003602300c010b200241013602300b20022001360234200241d8066a200241306a1044024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022903c0074203510d00200241386a200241d8066a41a002109b051a200241d8026a200241386a41a002109b051a2002200241d8026a3602f804200241d8066a200241f8046a10e60320022802e0062100024020022802dc06450d0020022802d80610290b200241d8066a200241d8026a41a002109b051a200241f8046a200241d8066a10a902024020022802f8044101470d00200228028005416b6a220041054b0d1720022802fc04210102400240024020000e06001a1a1a1a01000b4102210341f6012104200141c8d8c300460d01200141c8d8c3004115109d05450d010c190b410021040240200141f7fcc200470d00410021030c1a0b41002103200141f7fcc200411a109d050d180b0c180b200241d8066a20024180056a41d801109b051a200241286a200241a8076a220510ed02024020022903f8064202520d0041a00210322201450d04200141013a009802200142003703900220014280808080c0003703880220014204370380022001427f3703f801200142003703f001200142013703e801200142003703e00120014280808080c0003703d801200142043703d0012001427f3703c801200142003703c001200142013703b801200142003703b00120014280808080c0003703a801200142043703a0012001427f3703980120014200370390012001420137038801200142003703800120014280808080c000370378200142043703702001427f37036820014200370360200142013703582001420037035020014280808080c000370348200142043703402001427f37033820014200370330200142013703282001420037032020014280808080c000370318200142043703102001427f370308200142003703002001419c026a200241f8046a41036a280000360000200120022800f804360099022002200141a0026a3602fc09200220013602f809200241063602f409200220013602f009200241800a6a41206a22044200370300200241800a6a41186a22064280808080c000370300200241013a00a80a200242043703900a2002427f3703880a200242003703800a200241b8096a41086a22072001290308370300200241b8096a41106a22082001290310370300200241b8096a41186a22032001290318370300200241b8096a41206a22092001290320370300200220012903003703b809200220012800293602e80920022001412c6a2800003600eb09200141306a210020012d0028220a4102460d0b200241f8086a41286a220b200241800a6a41286a220c290300370300200241f8086a41206a2004290300370300200241f8086a41186a2006290300370300200241f8086a41106a200241800a6a41106a290300370300200241f8086a41086a200241800a6a41086a290300370300200220022903800a3703f808200241f8046a41206a2009290300370300200241f8046a41186a2003290300370300200241f8046a41106a2008290300370300200241f8046a41086a2007290300370300200220022903b8093703f8042002200a3a00a005200241a1056a220a20022802e809360000200a41036a20022800eb09360000200241800a6a200241f8086a200241f8046a10f4032007200041086a2903003703002008200041106a2903003703002003200041186a2903003703002009200041206a290300370300200220002903003703b809200220012800593602e8092002200141dc006a2800003600eb09200141e0006a210020012d005822074102470d020c0b0b20022d002c210a2002280228210341a00210322204450d042002280290072106411310322201450d052001410029009884433700002001410f6a41002800a78443360000200141086a41002900a0844337000020024293808080b0023702fc04200220013602f804200241d8066a200241f8046a10810120022802fc042107200241206a20022802f80422082002280280051084032002280224410020022802201b210102402007450d00200810290b0240024002400240200120064b0d00410c10322207450d0a2002200241d8066a3602f808200220063602fc08200241f8046a200241f8086a109103200741086a200241f8046a41086a280200360200200720022903f80437020041042108410021090240200120064f0d00410c10322208450d0c20022006417f6a3602fc082002200241d8066a3602f808200241f8046a200241f8086a109103200841086a200241f8046a41086a280200360200200820022903f804370200410121090b200220022800800a3602f0092002200241800a6a41036a2800003600f309200220022802f0093602e809200220022800f3093600eb09200241186a41e1f6c5004117105d417f200228021c410020022802181b220120006a220620062001491b418080c002418080f001200a41017122011b4b0d01200241106a41c7f6c500411a105d417f2002280214410020022802101b220a418094ebdc034180afd0e50220011b2206200320062003491b6a220b200b200a491b20064b0d01200220022800f8043602800a2002200241fb046a2800003600830a200220022802800a3602b809200220022800830a3600bb09200241f8046a200229039807200241a0076a290300200241d8066a20032001200010b20120022d00f8044101460d02200441013a00b80120044281808080103703b001200420073602ac01200420093602a801200420093602a401200420083602a0012004427f3703980120042003ad220d370390012004420137038801200442003703800120044280808080c000370378200442043703702004427f37036820044200370360200442013703582004420037035020044280808080c000370348200442043703402004427f37033820044200370330200442013703282004420037032020044280808080c000370318200442043703102004427f370308200442003703002004427f200d20011b3703c0012004427f3703c801200442043703d00120044280808080c0003703d801200442003703e001200441013a00e801200441bc016a20022800eb09360000200420022802e8093600b901200420022802b8093600e901200441ec016a20022800bb0936000020042002290380053703f001200441f8016a200241f8046a41106a220029030037030020044180026a200241f8046a41186a220629030037030020044188026a200241f8046a41206a220729030037030020044190026a200241f8046a41286a220829030037030020044198026a200241f8046a41306a2903003703002002200441a0026a3602fc09200220043602f809200241063602f409200220043602f009200241800a6a41206a22034200370300200241800a6a41186a22094280808080c000370300200241013a00a80a200242043703900a2002427f3703880a200242003703800a200241b8096a41086a220a2004290308370300200241b8096a41106a220b2004290310370300200241b8096a41186a220c2004290318370300200241b8096a41206a220e2004290320370300200220042903003703b809200220042800293602e80920022004412c6a2800003600eb09200441306a210120042d0028220f4102460d0c200241f8086a41286a200241800a6a41286a290300370300200241f8086a41206a2003290300370300200241f8086a41186a2009290300370300200241f8086a41106a200241800a6a41106a290300370300200241f8086a41086a200241800a6a41086a290300370300200220022903800a3703f8082007200e2903003703002006200c2903003703002000200b290300370300200241f8046a41086a200a290300370300200220022903b8093703f8042002200f3a00a005200241a1056a220f20022802e809360000200f41036a221020022800eb09360000200241800a6a200241f8086a200241f8046a10f403200a200141086a290300370300200b200141106a290300370300200c200141186a290300370300200e200141206a290300370300200220012903003703b809200220042800593602e8092002200441dc006a2800003600eb09200441e0006a210120042d0058220a4102470d060c0c0b200220022800800a3602f0092002200241830a6a2800003600f30920024181083b01f8082004102941012101410421060c020b200220022800f8043602800a2002200241f8046a41036a2800003600830a20024181023b01f80802402009450d002009410c6c21002008210103400240200141046a280200450d00200128020010290b2001410c6a2101200041746a22000d000b200810290b0240200741046a280200450d00200728020010290b200710292004102941012106410121010c0b0b200220022d00f90422063a00f908200241013a00f80802402009450d002009410c6c21002008210103400240200141046a280200450d00200128020010290b2001410c6a2101200041746a22000d000b200810290b0240200741046a280200450d00200728020010290b2007102920041029410121010b0c090b200241c4006a4105360200200241ec026a4102360200200242023702dc02200241c4b6c4003602d8022002410536023c200241b4b8c400360238200241003602fc04200241e480c6003602f8042002200241386a3602e8022002200241f8046a360240200241d8026a41d4b6c400107d000b200b200c290300370300200241f8086a41206a220c200241800a6a41206a220e290300370300200241f8086a41186a220f200241800a6a41186a2210290300370300200241f8086a41106a2211200241800a6a41106a2212290300370300200241f8086a41086a2213200241800a6a41086a2214290300370300200220022903800a3703f808200241f8046a41206a2215200241b8096a41206a2208290300370300200241f8046a41186a2216200241b8096a41186a2203290300370300200241f8046a41106a2217200241b8096a41106a2209290300370300200241f8046a41086a2218200241b8096a41086a220b290300370300200220022903b8093703f804200220073a00a005200a20022802e809360000200a41036a220720022800eb09360000200241800a6a200241f8086a200241f8046a10f403200b200041086a2903003703002009200041106a2903003703002003200041186a2903003703002008200041206a290300370300200220002903003703b80920022001280089013602e80920022001418c016a2800003600eb0920014190016a210020012d00880122194102460d08200241f8086a41286a221a200241800a6a41286a221b290300370300200c200e290300370300200f20102903003703002011201229030037030020132014290300370300200220022903800a3703f8082015200829030037030020162003290300370300201720092903003703002018200b290300370300200220022903b8093703f804200220193a00a005200a20022802e809360000200720022800eb09360000200241800a6a200241f8086a200241f8046a10f403200b200041086a2903003703002009200041106a2903003703002003200041186a2903003703002008200041206a290300370300200220002903003703b809200220012800b9013602e8092002200141bc016a2800003600eb09200141c0016a210020012d00b80122074102460d08201a201b290300370300200241f8086a41206a220c200241800a6a41206a220e290300370300200241f8086a41186a220f200241800a6a41186a2210290300370300200241f8086a41106a2211200241800a6a41106a2212290300370300200241f8086a41086a2213200241800a6a41086a2214290300370300200220022903800a3703f808200241f8046a41206a2215200241b8096a41206a2208290300370300200241f8046a41186a2216200241b8096a41186a2203290300370300200241f8046a41106a2217200241b8096a41106a2209290300370300200241f8046a41086a2218200241b8096a41086a220b290300370300200220022903b8093703f804200220073a00a005200a20022802e809360000200a41036a220720022800eb09360000200241800a6a200241f8086a200241f8046a10f403200b200041086a2903003703002009200041106a2903003703002003200041186a2903003703002008200041206a290300370300200220002903003703b809200220012800e9013602e8092002200141ec016a2800003600eb09200141f0016a210020012d00e80122194102460d08200241f8086a41286a221a200241800a6a41286a221b290300370300200c200e290300370300200f20102903003703002011201229030037030020132014290300370300200220022903800a3703f8082015200829030037030020162003290300370300201720092903003703002018200b290300370300200220022903b8093703f804200220193a00a005200a20022802e809360000200720022800eb09360000200241800a6a200241f8086a200241f8046a10f403200b200041086a2903003703002009200041106a2903003703002003200041186a2903003703002008200041206a290300370300200220002903003703b80920022001280099023602e80920022001419c026a2800003600eb09200141a0026a210020012d00980222014102460d08201a201b290300370300200241f8086a41206a200241800a6a41206a290300370300200241f8086a41186a200241800a6a41186a290300370300200241f8086a41106a200241800a6a41106a290300370300200241f8086a41086a200241800a6a41086a290300370300200220022903800a3703f808200241f8046a41206a200241b8096a41206a290300370300200241f8046a41186a200241b8096a41186a290300370300200241f8046a41106a200241b8096a41106a290300370300200241f8046a41086a200241b8096a41086a290300370300200220022903b8093703f804200220013a00a005200a20022802e809360000200a41036a20022800eb09360000200241800a6a200241f8086a200241f8046a10f4030c080b200241f8086a41286a2212200241800a6a41286a2213290300370300200241f8086a41206a2214200241800a6a41206a2215290300370300200241f8086a41186a2216200241800a6a41186a2217290300370300200241f8086a41106a2218200241800a6a41106a2219290300370300200241f8086a41086a221a200241800a6a41086a221b290300370300200220022903800a3703f808200241f8046a41206a221c200241b8096a41206a220b290300370300200241f8046a41186a221d200241b8096a41186a220c290300370300200241f8046a41106a221e200241b8096a41106a220e290300370300200241f8046a41086a221f200241b8096a41086a2211290300370300200220022903b8093703f8042002200a3a00a005200f20022802e809360000201020022800eb09360000200241800a6a200241f8086a200241f8046a10f4032011200141086a290300370300200e200141106a290300370300200c200141186a290300370300200b200141206a290300370300200220012903003703b80920022004280089013602e80920022004418c016a2800003600eb0920044190016a210120042d008801220a4102460d0520122013290300370300201420152903003703002016201729030037030020182019290300370300201a201b290300370300200220022903800a3703f808201c200b290300370300201d200c290300370300201e200e290300370300201f2011290300370300200220022903b8093703f8042002200a3a00a005200f20022802e809360000200f41036a220a20022800eb09360000200241800a6a200241f8086a200241f8046a10f4032011200141086a290300370300200e200141106a290300370300200c200141186a290300370300200b200141206a290300370300200220012903003703b809200220042800b9013602e8092002200441bc016a2800003600eb09200441c0016a210120042d00b801220b4102460d05200241f8086a41286a2212200241800a6a41286a2213290300370300200241f8086a41206a2214200241800a6a41206a2215290300370300200241f8086a41186a2216200241800a6a41186a2217290300370300200241f8086a41106a2218200241800a6a41106a2219290300370300200241f8086a41086a221a200241800a6a41086a221b290300370300200220022903800a3703f808200241f8046a41206a221c200241b8096a41206a220c290300370300200241f8046a41186a221d200241b8096a41186a220e290300370300200241f8046a41106a221e200241b8096a41106a2210290300370300200241f8046a41086a221f200241b8096a41086a2211290300370300200220022903b8093703f8042002200b3a00a005200f20022802e809360000200a20022800eb09360000200241800a6a200241f8086a200241f8046a10f4032011200141086a2903003703002010200141106a290300370300200e200141186a290300370300200c200141206a290300370300200220012903003703b809200220042800e9013602e8092002200441ec016a2800003600eb09200441f0016a210120042d00e801220a4102460d0520122013290300370300201420152903003703002016201729030037030020182019290300370300201a201b290300370300200220022903800a3703f808201c200c290300370300201d200e290300370300201e2010290300370300201f2011290300370300200220022903b8093703f8042002200a3a00a005200f20022802e809360000200f41036a220a20022800eb09360000200241800a6a200241f8086a200241f8046a10f4032011200141086a2903003703002010200141106a290300370300200e200141186a290300370300200c200141206a290300370300200220012903003703b80920022004280099023602e80920022004419c026a2800003600eb09200441a0026a210120042d00980222044102460d05200241f8086a41286a200241800a6a41286a290300370300200241f8086a41206a200241800a6a41206a290300370300200241f8086a41186a200241800a6a41186a290300370300200241f8086a41106a200241800a6a41106a290300370300200241f8086a41086a200241800a6a41086a290300370300200220022903800a3703f808200241f8046a41206a200241b8096a41206a290300370300200241f8046a41186a200241b8096a41186a290300370300200241f8046a41106a200241b8096a41106a290300370300200241f8046a41086a200241b8096a41086a290300370300200220022903b8093703f804200220043a00a005200f20022802e809360000200a20022800eb09360000200241800a6a200241f8086a200241f8046a10f4030c050b41a0024108102e000b41a0024108102e000b41134101102e000b410c4104102e000b410c4104102e000b200241f8046a41086a2204200241800a6a41086a2903003703002000200241800a6a41106a29030037030020062009290300370300200720032903003703002008200241800a6a41286a290300370300200220013602f809200220022903800a3703f804200241f0096a103b200241f8086a41086a20022903f8042220370300200241f8086a41106a20042903002221370300200241f8086a41186a2000290300220d370300200241f8086a41206a2006290300370300200241f8086a41286a2007290300370300200241f8086a41306a200829030037030041002101200241003a00f808200da7210c20022d00f90821060b200241a8096a2d00002110200241a4096a2802002109200241a0096a280200210e2002419c096a280200210b20024198096a280200210a20024194096a280200210f024020010d00410121030c020b42bcf7ea858cf8afdfbd7f2006410473ad42078342038688a72104410021030c0b0b200241f8086a41086a2201200241800a6a41086a290300370300200241f8086a41106a2207200241800a6a41106a290300370300200241f8086a41186a22082006290300370300200241f8086a41206a22062004290300370300200241f8086a41286a2204200241800a6a41286a290300370300200220003602f809200220022903800a3703f808200241f0096a103b200241f8046a41106a2001290300220d370300200241f8046a41186a22012007290300370300200241f8046a41206a22002008290300370300200241f8046a41286a22072006290300370300200241f8046a41306a22032004290300370300200220022903f80822213703800541002104200241003a00f804200241f0096a41086a200d370300200220213703f009200241f8046a412c6a28020021062007280200210a2002419c056a28020021082000280200210020024194056a280200210b2001280200210920022d00a8074112470d092003290300210d200241cc076a2802002110200241086a41d4f1c5004114105d200241b8096a200228020c410020022802081b10d901200220103602e809200241f8086a41186a22014200370300200241f8086a41106a22044200370300200241f8086a41086a22074200370300200242003703f808200241e8096a4104200241f8086a1000200241800a6a41186a2001290300370300200241800a6a41106a2004290300370300200241800a6a41086a2007290300370300200220022903f8083703800a0240024020022802bc09220320022802c00922076b4120490d0020022802b80921010c010b200741206a22012007490d0e20034101742204200120012004491b22044100480d0e0240024020030d002004103221010c010b20022802b80920032004103421010b2001450d02200220043602bc09200220013602b809200421030b200120076a220420022903800a370000200441186a200241800a6a41186a290300370000200441106a200241800a6a41106a290300370000200441086a200241800a6a41086a290300370000410121042001200741206a4101410041001007210702402003450d00200110290b2007417f470d09200241d4f1c5004114105d200241c8076a2802002002280204410020022802001b2212470d09200241f8086a41086a22014200370300200242003703f80841e883c100410d200241f8086a1003200241800a6a41086a2001290300370300200220022903f8083703800a200241b8096a200241800a6a10f202024020022802b80922130d00410021040c0a0b20022802bc09211402400240200241b8096a41086a28020020104d0d002002410036028009200242013703f80820022802ac072104410410322201450d0420024284808080c0003702fc08200220013602f80820012004360000200241b0076a2802002103200241b8076a2802002201200241f8086a10660240024020022802fc08220720022802800922046b2001490d0020022802f80821070c010b200420016a220c2004490d102007410174220e200c200c200e491b220c4100480d100240024020070d00200c103221070c010b20022802f8082007200c103421070b2007450d062002200c3602fc08200220073602f8080b2002200420016a36028009200720046a20032001109b051a200241bc076a2802002104200241c4076a2802002201200241f8086a10660240024020010d0020022802fc082103200228028009210f201221070c010b20042001410c6c6a211103402004280200210e200441086a2802002201200241f8086a10660240024020022802fc08220320022802800922076b2001490d0020022802f808210c0c010b200720016a220c2007490d122003410174220f200c200c200f491b220f4100480d120240024020030d00200f1032210c0c010b20022802f8082003200f1034210c0b200c450d092002200f3602fc082002200c3602f808200f21030b2002200720016a220f36028009200c20076a200e2001109b051a2004410c6a22042011470d000b20022802c80721070b024002402003200f6b4104490d0020022802f80821010c010b200f41046a2201200f490d1020034101742204200120012004491b22044100480d100240024020030d002004103221010c010b20022802f80820032004103421010b2001450d08200220043602fc08200220013602f808200421030b2002200f41046a2204360280092001200f6a200736000020022802cc07210c02400240200320046b41034d0d00200321070c010b200441046a22072004490d102003410174220e20072007200e491b22074100480d100240024020030d002007103221010c010b200120032007103421010b2001450d09200220073602fc08200220013602f8080b200120046a200c3600002001200f41086a200241d0076a201320104105746a22031011210402402007450d00200110290b2004450d010b410021042014450d0a201310290c0a0b410c10322201450d07410410322204450d0820024284808080c0003702fc08200220043602f80820042012360000200220033602b809200241b8096a200241f8086a108a01200241800a6a41086a2002280280092204360200200220022903f80822213703800a200141086a200436020020012021370200200220022802e8093602b009200220022800eb093600b30902402014450d00201310290b200241800a6a41206a428180808010370300200241800a6a41186a4100360200200241ac0a6a20022800b30936000041012103200241013a00a80a2002200136029c0a200242043703900a2002427f3703880a200242003703800a200220022802b0093600a90a200241f8086a41086a200241f0096a41086a290300370300200241f8086a41246a2006360200200241f8086a41206a200a360200200241f8086a41186a2000360200200241f8086a41146a200b360200200220022903f0093703f8082002200d3703a00920022008360294092002200936028809200241b8096a200241800a6a200241f8086a10f403200241b8096a41146a280200210f200241b8096a41186a280200210a200241b8096a41206a280200210e200241b8096a41246a280200210920022903b809212020022903c009212120022802c809210c20022802d409210b20022d00e00921100b0c090b20044101102e000b41044101102e000b200c4101102e000b200f4101102e000b20044101102e000b20074101102e000b410c4104102e000b41044101102e000b02402000450d002000410c6c21002009210103400240200141046a280200450d00200128020010290b2001410c6a2101200041746a22000d000b0b0240200b450d00200910290b02402006450d002006410c6c21002008210103400240200141046a280200450d00200128020010290b2001410c6a2101200041746a22000d000b0b42002120427f21214104210c0240200a450d00200810290b4100210a41012110410121094101210e4100210f410021030b2005102a0c010b4100210341810121040b200241003602e0064201210d200242013703d806024002400240024002400240024002400240024002400240200341024d0d00420021210c010b024002400240024020030e03000102000b410110322201450d04200241013602dc06200220022802e006220041016a3602e006200220013602d806200120006a41003a00000240024020022802dc0620022802e0062201460d0020022802d80621000c010b200141016a22002001490d0f20014101742205200020002005491b22054100480d0f0240024020010d002005103221000c010b20022802d80620012005103421000b2000450d06200220053602dc06200220003602d80620022802e00621010b2002200141016a3602e006200020016a20043a00000c020b410110322201450d05200241013602dc06200220022802e006220041016a3602e006200220013602d806200120006a41013a00000240024020022802dc06220020022802e00622016b4108490d0020022802d80621000c010b200141086a22042001490d0e20004101742201200420042001491b22014100480d0e0240024020000d002001103221000c010b20022802d80620002001103421000b2000450d07200220013602dc06200220003602d80620022802e00621010b2002200141086a3602e006200020016a2020370000200a200241d8066a10660240200a450d00200c200a410c6c6a2108200c2104034020042802002106200441086a2802002201200241d8066a10660240024020022802dc06220520022802e00622006b2001490d0020022802d80621050c010b200020016a22072000490d1020054101742200200720072000491b22004100480d100240024020050d002000103221050c010b20022802d80620052000103421050b2005450d0a200220003602dc06200220053602d80620022802e00621000b2002200020016a3602e006200520006a20062001109b051a2004410c6a22042008470d000b0b2009200241d8066a106602402009450d00200b2009410c6c6a2108200b2104034020042802002106200441086a2802002201200241d8066a10660240024020022802dc06220520022802e00622006b2001490d0020022802d80621050c010b200020016a22072000490d1020054101742200200720072000491b22004100480d100240024020050d002000103221050c010b20022802d80620052000103421050b2005450d0b200220003602dc06200220053602d80620022802e00621000b2002200020016a3602e006200520006a20062001109b051a2004410c6a22042008470d000b0b0240024020022802dc06220020022802e00622016b4108490d0020022802d80621000c010b200141086a22042001490d0e20004101742201200420042001491b22014100480d0e0240024020000d002001103221000c010b20022802d80620002001103421000b2000450d0a200220013602dc06200220003602d80620022802e00621010b2002200141086a3602e006200020016a20213700000240024020022802dc0620022802e0062201460d0020022802d80621000c010b200141016a22002001490d0e20014101742204200020002004491b22044100480d0e0240024020010d002004103221000c010b20022802d80620012004103421000b2000450d0b200220043602dc06200220003602d80620022802e00621010b2002200141016a3602e006200020016a20103a00000c010b410110322201450d0a200241013602dc06200220022802e006220041016a3602e006200220013602d806200120006a41023a00000240024020022802dc0620022802e0062201460d0020022802d80621000c010b200141016a22002001490d0d20014101742205200020002005491b22054100480d0d0240024020010d002005103221000c010b20022802d80620012005103421000b2000450d0c200220053602dc06200220003602d80620022802e00621010b2002200141016a3602e006200020016a20043a00000b20023502e006422086212120023502d806210d0b024020034101470d000240200a450d00200a410c6c2100200c210103400240200141046a280200450d00200128020010290b2001410c6a2101200041746a22000d000b0b0240200f450d00200c10290b02402009450d002009410c6c2100200b210103400240200141046a280200450d00200128020010290b2001410c6a2101200041746a22000d000b0b200e450d00200b10290b200241b00a6a24002021200d840f0b41014101102e000b20054101102e000b41014101102e000b20014101102e000b20004101102e000b20004101102e000b20014101102e000b20044101102e000b41014101102e000b20054101102e000b1033000bd40505017f027e077f017e017f230041206b220324002002290300210420012903002105200141106a2106200228021021070240024002400240024002400240200141146a2802002208200141186a28020022096b200241186a280200220a490d00200628020021080c010b2009200a6a220b2009490d032008410174220c200b200b200c491b220bad420c7e220d422088a70d03200da7220c4100480d030240024020080d00200c103221080c010b20062802002008410c6c200c103421080b2008450d0120012008360210200141146a200b3602000b20082009410c6c6a2007200a410c6c109b051a200141186a2009200a6a36020020024100360218200341086a200641086a280200360200200320062902003703002001411c6a2106200228021c210b02400240200141206a2802002208200141246a28020022096b200241246a280200220a490d00200628020021080c010b2009200a6a220c2009490d032008410174220e200c200c200e491b220cad420c7e220d422088a70d03200da7220e4100480d030240024020080d00200e103221080c010b20062802002008410c6c200e103421080b2008450d022001200836021c200141206a200c3602000b427f200520047c220420042005541b210520082009410c6c6a200b200a410c6c109b051a200141246a2009200a6a36020020024100360224200341106a41086a200641086a28020036020020032006290200370310200229030822042001290308220d200d2004561b210420012d0028450d034101210120022d0028450d030c040b200c4104102e000b200e4104102e000b1033000b410021010b20002005370300200020032903003702102000200329031037021c200020013a002820002004370308200041186a200341086a280200360200200041246a200341106a41086a2802003602000240200241146a280200450d00200710290b0240200241206a280200450d00200b10290b200341206a24000bac3205037f017e197f027e0f7f23004190046b2202240002400240024002400240024002400240024020014104490d002000280000210310184101470d07200241206a41d783c1004111105d200228022421012002280220210420024100360278410141ed92c100411c200241f8006a101921002001410020041b2104024002400240024020022802782201417f470d00410121010c010b2001ad22054220862005842105200045210120000d010b41002100410121060c010b2005422088a74105490d03200028000121070240024020002d00000d0020072003460d0141002106200720034f0d02410121060c020b4101210620072004490d010b410021060b200420034f0d012006450d010240410110322204450d00200441003a0000024020044101410510342204450d0020042003360001410141ed92c100411c4100200020011b22062005422088a7417f20061b20044105101a210620041029024020012005a745720d00200010290b20060d09200241f8006a41086a220042003703002002420037037841e883c100410d200241f8006a100320024198036a41086a20002903003703002002200229037837039803200241f8006a20024198036a10f20202400240200228027822080d0041002109410121084100210a0c010b2000280200210a200228027c21090b200241286a10f6032002280228210b2002280230220c4115490d05200c410176220d41ffffff3f71200d470d07200d4105742200417f4c0d074101210e024002402000450d0020001032220e450d010b200b41606a210f200b41a07f6a211041002111410021124104211341002114200c211503400240024020152216417f6a22040d0041012107410021150c010b024002400240024002400240200b20044105746a20164105742217200b6a41406a4120109d054100480d002016417e6a2106201020176a210041002115410021010340024020062001470d00201621070c080b200141016a2101200041206a20004120109d052104200041606a21002004417f4a0d000b200141016a21072001417f7320166a21040c010b201020176a210002400340024020044101470d00410021040c020b2004417f6a2104200041206a20004120109d052101200041606a210020014100480d000b0b20162004490d012016200c4b0d03201620046b22074101762206450d00200f20176a2100200b20044105746a21010340200241f8006a41186a2217200141186a2218290000370300200241f8006a41106a2219200141106a221a290000370300200241f8006a41086a221b200141086a221c29000037030020022001290000370378200041086a221d2900002105200041106a221e290000211f200041186a221529000021202001200029000037000020182020370000201a201f370000201c200537000020152017290300370000201e2019290300370000201d201b29030037000020002002290378370000200041606a2100200141206a21012006417f6a22060d000b0b024020040d00200421150c050b0240200741094d0d00200421150c050b2016200c4b0d01201620046b2106200b20044105746a2117034020162004417f6a2215490d040240201620156b22074102490d00200b20044105746a2200200b20154105746a22044120109d05417f4a0d002004290000210520042000290000370000200241f8006a41186a221b200441186a2201290000370300200241f8006a41106a221c200441106a2218290000370300200241f8006a41086a221d200441086a22192900003703002019200041086a2900003700002018200041106a2900003700002001200041186a290000370000200220053703784101211a024020074103490d00200441c0006a200241f8006a4120109d05417f4a0d00410221012017210002400340200041186a200041386a290000370000200041106a200041306a290000370000200041086a200041286a2900003700002000200041206a221829000037000020062001460d01200041c0006a21192001211a20182100200141016a21012019200241f8006a4120109d05417f4a0d020c000b0b2001211a0b2004201a4105746a22002002290378370000200041186a201b290300370000200041106a201c290300370000200041086a201d2903003700000b2015450d05201741606a2117200641016a2106201521042007410a4f0d050c000b0b200420161030000b20162004417f6a2215490d010b2016200c108f01000b201520161030000b02400240024020142012470d00201241016a22002012490d0f20124101742201200020002001491b220041ffffffff01712000470d0f200041037422014100480d0f0240024020120d002001103221130c010b201320124103742001103421130b2013450d0120002112201121140b201320144103746a2200200736020420002015360200201141016a2214211120144102490d0102400340024002400240024020132014417f6a22114103746a2200280200450d00201441037420136a220641746a2802002204200028020422014d0d000240201441024b0d0020142111410221140c080b20132014417d6a221b4103746a2802042200200120046a4d0d010240201441034b0d0020142111410321140c080b200641646a280200200020046a4d0d01201421110c070b20144103490d012000280204210120132014417d6a221b4103746a28020421000b20002001490d010b2014417e6a211b0b0240024002400240024002402014201b41016a22214b2222450d002014201b4b2223450d012013201b4103746a221c2802042224201c2802006a2200201320214103746a221d280200221e490d022000200c4b0d03200b201e4105746a2219201d280204221a41057422016a2106200041057421042000201e6b2216201a6b2200201a4f0d04200e200620004105742201109b05221820016a210702400240201a4101480d00200041014e0d010b20062100201821010c060b200f20046a21042006210003402004200041606a2206200741606a2216201620064120109d0541004822171b2201290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a2900003700002007201620171b2107024020192006200020171b2200490d00201821010c070b200441606a21042018210120182007490d000c060b0b419cffc000202120141036000b419cffc000201b20141036000b201e20001030000b2000200c108f01000b200e20192001109b05221820016a210702400240201a4101480d002016201a4a0d010b20192100201821010c010b200b20046a211720182101201921000340200020062001200620014120109d0541004822161b2204290000370000200041186a200441186a290000370000200041106a200441106a290000370000200041086a200441086a2900003700002001200141206a20161b2101200041206a2100200641206a200620161b220620174f0d01200720014b0d000b0b20002001200720016b416071109b051a02402023450d00201c201e360200201c41046a2024201a6a3602002022450d02201d201d41086a20142021417f736a410374109c051a20112114201141014d0d040c010b0b41acffc000201b20141036000b418080c000106d000b20014104102e000b20150d000b02402012450d00201310290b200d450d07200e10290c070b20004101102e000b41054101102e000b41014101102e000b200241a4036a41053602002002418c016a41023602002002420237027c200241c4b6c4003602782002410536029c03200241d0b8c400360298032002410036023c200241e480c600360238200220024198036a360288012002200241386a3602a003200241f8006a41d4b6c400107d000b20012005a745720d05200010290c050b02402005a7450d00200010290b41c2e9c500412d10090c040b200c4102490d00200b200c417f6a22014105746a21074101210403400240024002400240200c20012200417f6a2201490d00200c20016b22164102490d03200b20004105746a2200200b20014105746a22064120109d05417f4a0d032006290000210520062000290000370000200241f8006a41186a2214200641186a2217290000370300200241f8006a41106a221a200641106a2218290000370300200241f8006a41086a2213200641086a22192900003703002019200041086a2900003700002018200041106a2900003700002017200041186a290000370000200220053703784101210020164103490d02200641c0006a200241f8006a4120109d05417f4a0d0241002116200721000340200041186a200041386a290000370000200041106a200041306a290000370000200041086a200041286a2900003700002000200041206a2218290000370000200420162217460d022017417f6a2116200041c0006a2119201821002019200241f8006a4120109d05417f4a0d020c000b0b2001200c1030000b410220176b21000b200620004105746a22002002290378370000200041186a2014290300370000200041106a201a290300370000200041086a20132903003700000b200741606a21072004417f6a210420010d000b0b200a450d012008200a4105746a2119200241b9026a211b2002419e036a2125200241f8006a41016a211c20024190026a2126200241b0016a2127200241f8006a41306a2128200241f8006a41286a212941002116200821070240024002400240024002400340024002400240200c41014b0d000240200c0e020c000c0b0340200241f8006a41186a200741186a290000370300200241f8006a41106a200741106a290000370300200241f8006a41086a200741086a29000037030020022007290000370378200b200241f8006a4120109d05450d02201641016a21162019200741206a2207470d000c0c0b0b0340200241f8006a41186a200741186a290000370300200241f8006a41106a200741106a290000370300200241f8006a41086a200741086a29000037030020022007290000370378200741206a21070240200c450d0041002100200c2101034020002001410176220420006a2206200b20064105746a200241f8006a4120109d0541004a1b2100200120046b220141014b0d000b200b20004105746a200241f8006a4120109d05450d030b201641016a211620072019460d0b0c000b0b200741206a2107410021000b0240024002400240024002400240200c20004d0d00200241003602980320024198036a101b210402402002280298032201417f470d00410321000c0a0b2002200136027c200220043602782001450d0320042d0000210620022001417f6a36027c2002200441016a360278200641014b0d030240024020060e020100010b41002111202121102013211d201a21152014210d2018210a2017211e2021212a2013212b201a212c2014212d2018212e2017212f0c060b200241186a200241f8006a102c20022802180d03200228027c2206200228021c222b490d03202b417f4c0d0e02400240202b0d004101211141010d010c050b202b102d2211450d0220112002280278221d202b109b05211e20022006202b6b36027c2002201d202b6a360278201e450d040b200241106a200241f8006a102c20022802100d02200228027c410c6e222e410c6c2206417f4c0d0e2002280214212f0240024002400240024020060d004104212d0c010b20061032222d450d010b024002400240202f0d00202d212c0c010b410021104100211d41002115202d212c0340200241086a200241f8006a102c20022802080d02200228027c221e200228020c2206490d022006417f4c0d140240024020060d004101210a0c010b2006102d220a450d05200a2002280278220d2006109b051a2002201e20066b36027c2002200d20066a3602780b201541016a211e02402015202e470d002010201e201e2010491b222ead420c7e2205422088a70d182005a7220d4100480d180240024020150d00200d1032212d0c010b202d201d200d1034212d0b202d450d06202d212c0b202c201d6a2215200a360200201541046a2006ad2205422086200584370200201041026a2110201d410c6a211d201e2115202f201e470d000b0b202c450d06202b212a202f211e202e210a202d210d202c2115202b211d202b211020110d080c070b02402015450d004100210603400240202c20066a221e41046a280200450d00201e28020010290b201d2006410c6a2206470d000b0b202e450d05202d10290c050b20064104102e000b20064101102e000b200d4104102e000b418c93c1002000200c1036000b202b4101102e000b202b450d00201110290b410021112017212f2018212e2014212d201a212c2013212b2021212a2022211e2023210a2024210d200e21152012211d200f21100b2001450d010b200410290b024020110d00410321000c030b200241d4f1c5004114105d200228020421212002280200212220024201370378200241003602800102400240024002400240410410322201450d0020024284808080c00037027c2002200136027820012003360000201d200241f8006a106602400240200228027c220420022802800122016b201d490d00200228027821040c010b2001201d6a22062001490d1020044101742217200620062017491b22064100480d100240024020040d002006103221040c010b200228027820042006103421040b2004450d022002200636027c200220043602780b20022001201d6a36028001200420016a2011201d109b051a201e200241f8006a1066201e450d022015201e410c6c6a211320152104034020042802002114200441086a2802002201200241f8006a106602400240200228027c221720022802800122066b2001490d00200228027821180c010b200620016a22182006490d112017410174221a20182018201a491b221a4100480d110240024020170d00201a103221180c010b20022802782017201a103421180b2018450d052002201a36027c20022018360278201a21170b2002200620016a221a36028001201820066a20142001109b051a2004410c6a22042013470d000c050b0b41044101102e000b20064101102e000b200228027c2117200228028001211a0c010b201a4101102e000b024002402017201a6b4104490d00200228027821010c010b201a41046a2201201a490d0b20174101742204200120012004491b22044100480d0b0240024020170d002004103221010c010b200228027820172004103421010b2001450d042002200436027c20022001360278200421170b2002201a41046a2204360280012001201a6a2021410020221b221836000002400240201720046b41034d0d00201721060c010b200441046a22062004490d0b20174101742214200620062014491b22064100480d0b0240024020170d002006103221010c010b200120172006103421010b2001450d052002200636027c200220013602780b200120046a2016360000200241e9dabdf30636029803202742003703002028420037030020294200370300200241f8006a41206a4200370300200241f8006a41186a4200370300200241f8006a41106a4200370300200241f8006a41086a420037030020024200370378024020024198036a200b20004105746a2001201a41086a200241f8006a101c0d00200241386a41086a2200201c41086a290000370300200241386a41106a2204201c41106a290000370300200241386a41186a2217201c41186a290000370300200241386a41206a2214201c41206a290000370300200241386a41286a221a201c41286a290000370300200241386a41306a2213201c41306a290000370300200241386a41376a2221201c41376a2900003700002002201c29000037033820022d0078212202402006450d00200110290b200241f8006a202541e800109b051a201b2002290338370000201b41086a2000290300370000201b41106a2004290300370000201b41186a2017290300370000201b41206a2014290300370000201b41286a201a290300370000201b41306a2013290300370000201b41376a2021290000370000200220223a00b802200220163602b402200220183602b0022002201e3602ac022002200a3602a8022002200d3602a4022002201d3602a0022002201036029c0220022011360298022002200336029402200241123a009002200242023703e0012002200241f8006a36028c0420024198036a2002418c046a10e603200228029803220120022802a003101d21000240200228029c03450d00200110290b20000d02410110322200450d06200041013a000020004101410510342200450d07201641016a211620002003360001410141ed92c100411c20004105101e200010292026102a202f2117202e2118202d2114202c211a202b2113202a2121201e2122200a2123200d21242015210e201d21122010210f20072019470d010c090b0b02402006450d00200110290b02402010450d00201110290b0240201e450d00201e410c6c210003400240201541046a280200450d00201528020010290b2015410c6a2115200041746a22000d000b0b41022100200a450d01200d10290c010b2026102a410421000b02402009450d00200810290b0240200228022c450d00200b10290b0240024002400240024020000e050102030400010b4194e9c500412e10090c0a0b41c2e9c500412d10090c090b41efe9c500412a10090c080b4199eac500411f10090c070b41b8eac500412e10090c060b20044101102e000b20064101102e000b41014101102e000b41054101102e000b102f000b02402009450d00200810290b200228022c450d00200b10290b20024190046a240042010f0b1033000bef06020e7f037e230041e0006b22012400200141e9dabdf306360208410021022001410036020c200141086a2001410c6a102321032001200128020c360214200120033602102001200141106a102c410121040240024002402001280200450d004100210541012106410121070c010b0240024002400240200128021422034160712208417f4c0d002001280204210502400240200341057622090d004101210a0c010b20081032220a450d020b2005450d024100210703402003210b200141003a00582007220641016a2107410021030240024002400340200b2003460d01200141386a20036a200128021022082d00003a00002001200841016a3602102001200341016a22083a00582008210320084120470d000b200141186a41186a220c200141386a41186a290300370300200141186a41106a220d200141386a41106a290300370300200141186a41086a220e200141386a41086a2903003703002001200129033837031820092006470d0220064101742203200720072003491b220941ffffff3f712009470d092009410574220341004e0d010c090b41002105200141003602140240200341ff0171450d00200141003a00580b2009450d06200a10290c060b0240024020060d0020031032210a0c010b200a200641057420031034210a0b200a0d0020034101102e000b200b20086b2103200a20064105746a22062001290318370000200641186a200c290300370000200641106a200d290300370000200641086a200e29030037000020072005470d000b2001200b20086b36021441002106200a21070c040b102f000b20084101102e000b20054100200a1b2105200a4101200a1b2107200a4521060c010b41012106410121070b41002103024002402005450d0020054105742203410575220241ffffff3f712002470d02200241057422084100480d02200810322204450d01200720036a210a20054105742105410021030340200720036a2208290000210f200841086a2900002110200841106a2900002111200420036a220b41186a200841186a290000370000200b41106a2011370000200b41086a2010370000200b200f3700002005200341206a2203470d000b200a20076b41606a41057641016a21030b02402006200945720d00200710290b200020033602082000200236020420002004360200200141e0006a24000f0b20084101102e000b1033000b8e0806027f017e047f017e017f017e230041c0006b22022400024002402001450d00200220003602080c010b200241013602080b2002200136020c200241206a200241086a103d0240024002400240024020022802202203450d00200220022902242204370214200220033602102002410136023820024186b3c10036023c200241206a200241106a200241386a10b601024002400240200228022022054105470d0041002100200241003602380c010b2002412c6a2802002101200241286a2802002106024020050d00200220022802242200360238200241306a28020021070c020b410021002002410036023820054101470d002001450d00200610290b0b410110322205450d012002428180808010370224200220053602200240024020000d00200541003a00000c010b200541013a00002001200241206a106602402001450d002000200141286c6a210803402000200241206a10ee01200041206a29030021090240024020022802242205200228022822016b4108490d00200228022021050c010b200141086a220a2001490d0820054101742201200a200a2001491b22014100480d080240024020050d002001103221050c010b200228022020052001103421050b2005450d062002200136022420022005360220200228022821010b2002200141086a360228200520016a20093700002008200041286a2200470d000b0b0240024020022802242200200228022822016b4104490d00200228022021000c010b200141046a22052001490d0620004101742201200520052001491b22014100480d060240024020000d002001103221000c010b200228022020002001103421000b2000450d052002200136022420022000360220200228022821010b2002200141046a360228200020016a20073600000b2004422088a72101200235022821092002350220210b024020022802382200450d002006450d00200010290b2004a7210a02402001450d00200141246c21002003210103400240024020012d0000220541034b0d0002400240024020050e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b0240200a450d00200310290b200241c0006a24002009422086200b840f0b200241346a41023602002002411c6a410536020020024202370224200241c4b6c40036022020024105360214200241e8b8c4003602102002410036023c200241e480c6003602382002200241106a3602302002200241386a360218200241206a41d4b6c400107d000b41014101102e000b20014101102e000b20014101102e000b1033000b9c0904027f017e077f027e230041c0006b22022400024002402001450d00200220003602080c010b200241013602080b2002200136020c200241206a200241086a103d02400240024002400240024020022802202203450d00200220022902242204370214200220033602102002410136023820024186b3c10036023c200241206a200241106a200241386a10b6014100210502400240200228022022014105470d000c010b200241346a2802002106200241306a28020021002002412c6a2802002107200241286a280200210820022802242109024020014101470d00200821050c010b20010d002008450d00200910290b4105410120051b220810322201450d012002410136022820022008360224200220013602200240024020050d00200141003a00000c010b200141013a00000240024020022802242208200228022822016b4104490d00200228022021080c010b200141046a220a2001490d072008410174220b200a200a200b491b220a4100480d070240024020080d00200a103221080c010b20022802202008200a103421080b2008450d042002200a360224200220083602200b2002200141046a360228200820016a20093600002000200241206a106602402000450d002005200041286c6a210a2005210003402000200241206a10ee01200041206a290300210c0240024020022802242208200228022822016b4108490d00200228022021080c010b200141086a22092001490d0920084101742201200920092001491b22014100480d090240024020080d002001103221080c010b200228022020082001103421080b2008450d072002200136022420022008360220200228022821010b2002200141086a360228200820016a200c370000200a200041286a2200470d000b0b0240024020022802242200200228022822016b4104490d00200228022021000c010b200141046a22082001490d0720004101742201200820082001491b22014100480d070240024020000d002001103221000c010b200228022020002001103421000b2000450d062002200136022420022000360220200228022821010b2002200141046a360228200020016a20063600000b2004422088a721012002350228210c2002350220210d02402005450d002007450d00200510290b2004a7210902402001450d00200141246c21002003210103400240024020012d0000220841034b0d0002400240024020080e0404000102040b2001410c6a280200450d03200141086a28020010290c030b2001410c6a280200450d02200141086a28020010290c020b2001410c6a280200450d01200141086a28020010290c010b200141086a280200450d00200141046a28020010290b200141246a21012000415c6a22000d000b0b02402009450d00200310290b200241c0006a2400200c422086200d840f0b200241346a41023602002002411c6a410536020020024202370224200241c4b6c4003602202002410536021420024188b9c4003602102002410036023c200241e480c6003602382002200241106a3602302002200241386a360218200241206a41d4b6c400107d000b20084101102e000b200a4101102e000b20014101102e000b20014101102e000b1033000bf20303077f017e017f230041306b2202240041082103200241106a41086a220442003703002002420037031041beeec500411b200241106a1003200241086a200429030037030020022002290310370300410021052002410036021020024110200241106a100621060240024020022802102207417f460d002002200736022420022006360220200241106a200241206a1040024020022802102203450d00200241186a2802002104200228021421052007450d02200610290c020b41f7cdc3004133200241286a41ecd6c3001054000b410021040b20024100360218200242013703102004200241106a10660240024002402004450d002003200441286c6a21082003210703402007200241106a10ee01200741206a29030021090240024020022802142206200228021822046b4108490d00200228021021060c010b200441086a220a2004490d0420064101742204200a200a2004491b22044100480d040240024020060d002004103221060c010b200228021020062004103421060b2006450d032002200436021420022006360210200228021821040b2002200441086a360218200620046a20093700002008200741286a2207470d000b0b200235021821092002280210210402402005450d00200310290b200241306a240020094220862004ad840f0b20044101102e000b1033000b6f01017f024002400240410810322202450d00200242b81737000020024108411010342202450d012002420137000820024110412010342202450d02200242e807370018200242043700102002ad42808080808004840f0b41084101102e000b41104101102e000b41204101102e000b981204017f017e0f7f047e23004190026b22022400200241206a41c5efc500411310d5012002290328210320022802202104200241306a41086a220542003703002002420037033041b5efc5004110200241306a1003200241f8006a41086a2005290300370300200220022903303703784100210620024100360230200241f8006a4110200241306a1006210702400240024002400240024002400240024002400240024020022802302208417f470d00410021060c010b024020070d000c010b2002200836028c012002200736028801200241186a20024188016a102c20022802180d0a200228028c01220941286e220a41286c2205417f4c0d01200228021c210b0240024020050d00410821060c010b200510322206450d030b0240200b450d004100210c0340200241003a0050200c220d41016a210c4100210502400240024002400240034020092005460d01200241306a20056a200228028801220e2d00003a00002002200e41016a360288012002200541016a220f3a0050200f2105200f4120470d000b200241f0016a41086a2210200241306a41086a290300370300200241f0016a41106a2211200241306a41106a290300370300200241f0016a41186a2212200241306a41186a290300370300200220022903303703f00120022009200f6b220536028c01200541074d0d01200241b0016a41086a20102903002213370300200241b0016a41106a20112903002214370300200241b0016a41186a2012290300221537030020024190016a41086a220f201337030020024190016a41106a2210201437030020024190016a41186a221120153703002002200e41096a360288012002200541786a220936028c01200220022903f00122133703b0012002201337039001200e2900012113200a200d470d04200d4101742205200c200c2005491b220aad42287e2214422088a70d102014a722054100480d10200d0d022005103221060c030b2002410036028c01200541ff0171450d00200241003a00500b200241b0016a41186a200241d0016a41186a290300370300200a450d0f200610290c0f0b2006200d41286c2005103421060b2006450d060b2006200d41286c6a2205200229039001370300200f2903002114201029030021152011290300211620052013370320200541186a2016370300200541106a2015370300200541086a2014370300200c200b470d000b0b2006450d0a2008450d00200710290b2003420020041b2114200241086a41a6efc500410f10d5012002290310211320022802082105200241306a41086a220f420037030020024200370330419bf0c500410f200241306a1003200241f8006a41086a200f290300370300200220022903303703782006410820061b210f200a410020061b210e200b410020061b21092013420020051b2113200241306a200241f8006a108b030240024020022d00304101460d0020024188026a420037030020024180026a4200370300200241f0016a41086a4200370300200242003703f0010c010b20024188026a200241c9006a29000037030020024180026a200241c1006a290000370300200241f0016a41086a200241396a290000370300200220022900313703f0010b200241306a41086a220542003703002002420037033041e8efc5004113200241306a1003200241f8006a41086a2005290300370300200220022903303703782002200241f8006a108c03200241d0006a2009360200200241cc006a200e360200200241dc006a200241f0016a41086a290300370200200241e4006a20024180026a290300370200200241ec006a20024188026a2903003702002002200f360248200242c8013703402002201437033820022013370330200220022903f0013702542002410120022d0000220541017120054102461b3a0074200241003602f801200242013703f001410810322205450d03200241083602f401200220022802f801220f41086a3602f801200220053602f0012005200f6a2013370000200229033821130240024020022802f401220f20022802f80122056b4108490d0020022802f001210f0c010b200541086a220e2005490d09200f4101742205200e200e2005491b22054100480d0902400240200f0d0020051032210f0c010b20022802f001200f20051034210f0b200f450d05200220053602f4012002200f3602f00120022802f80121050b2002200541086a3602f801200f20056a2013370000200229034021130240024020022802f401220f20022802f80122056b4108490d0020022802f001210f0c010b200541086a220e2005490d09200f4101742205200e200e2005491b22054100480d0902400240200f0d0020051032210f0c010b20022802f001200f20051034210f0b200f450d06200220053602f4012002200f3602f00120022802f80121050b2002200541086a3602f801200f20056a20133700002002280248210f20022802502205200241f0016a106602402005450d00200f200541286c6a210d03402002200f3602d001200241d0016a200241f0016a108a01200f41206a29030021130240024020022802f401220e20022802f80122056b4108490d0020022802f001210e0c010b200541086a22092005490d0b200e4101742205200920092005491b22054100480d0b02400240200e0d0020051032210e0c010b20022802f001200e20051034210e0b200e450d09200220053602f4012002200e3602f00120022802f80121050b2002200541086a3602f801200e20056a2013370000200d200f41286a220f470d000b0b200241d4006a200241f0016a1081010240024020022802f40120022802f8012205460d0020022802f001210f0c010b200541016a220f2005490d092005410174220e200f200f200e491b220e4100480d090240024020050d00200e1032210f0c010b20022802f0012005200e1034210f0b200f450d082002200e3602f4012002200f3602f00120022802f80121050b2002200541016a3602f801200f20056a20022d00743a000020023502f801211320023502f00121140240200228024c450d00200228024810290b20024190026a240020134220862014840f0b102f000b20054108102e000b20054108102e000b41084101102e000b20054101102e000b20054101102e000b20054101102e000b200e4101102e000b1033000b41f7cdc3004133200241306a41ecd6c3001054000bcb06030d7f037e027f23004180016b22022400200241086a41086a220342003703002002420037030841f583c1004117200241086a1003200241e0006a41086a200329030037030020022002290308370360200241086a200241e0006a10f2024100210402400240200228020822050d004101210541002103410021060c010b20032802002103200228020c21060b200241306a10f60302402003450d00200520034105746a210720022802302208200228023841057422096a210a200241e0006a41606a210b200241206a210c200241006a210d2005210e0340200e41086a290000210f200e41106a2900002110200e2900002111200241e0006a41186a200e41186a290000370300200241e0006a41106a2010370300200241e0006a41086a200f37030020022011370360200e41206a210e20092112200821030240024002400340200a20036b41e0004d0d01200241e0006a2003460d022003200241e0006a4120109d05450d02200b2003460d02200341206a200241e0006a4120109d05450d02200c2003460d02200341c0006a200241e0006a4120109d05450d02200d2003460d02201241807f6a2112200341e0006a211320034180016a21032013200241e0006a4120109d050d000c020b0b03402012450d02200241e0006a2003460d01201241606a21122003200241e0006a4120109d052113200341206a210320130d000b0b200241c0006a41186a200241e0006a41186a290300220f370300200241c0006a41106a200241e0006a41106a2903002210370300200241c0006a41086a200241e0006a41086a2903002211370300200241116a2011370000200241196a2010370000200241216a200f37000020022002290360220f3703402002200f370009410121040c020b200e2007470d000b0b200220043a000802402002280234450d00200228023010290b02402006450d00200510290b20022d000821120240410110322203450d00200242013702642002200336026002400240201241ff01714101460d0020024101360268200341003a00000c010b20024101360268200341013a00002002200241086a410172360240200241c0006a200241e0006a108a010b2002350268210f2002350260211020024180016a24002010200f422086840f0b41014101102e000bf70102057f017e230041206b22022400200241106a41086a220342003703002002420037031041f583c1004117200241106a1003200241086a200329030037030020022002290310370300200241106a200210f20202400240200228021022040d004101210441002105410021030c010b20032802002103200228021421050b20024100360218200242013703102003200241106a106602402003450d002003410574210620042103034020022003360200200341206a21032002200241106a108a01200641606a22060d000b0b200235021821072002280210210302402005450d00200410290b200241206a240020074220862003ad840bc90f07047f017e017f017e017f027e3c7f230041b0016b22022400024002402001450d00200220003602100c010b200241013602100b20022001360214200241086a200241106a102c02400240024002400240024002400240024002400240024020022802080d0020022802142201200228020c2203490d002003417f4c0d030240024020030d00410121040c010b2003102d2204450d052004200228021022002003109b051a2002200120036b3602142002200020036a3602100b2004450d0041002101200241003a009001200228021421050240034020052001460d01200241f0006a20016a200228021022002d00003a00002002200041016a3602102002200141016a22003a0090012000210120004120470d000b200241186a41086a200241f0006a41086a22012903002206370300200241186a41106a200241f0006a41106a22072903002208370300200241186a41186a200241f0006a41186a2209290300220a37030020022002290370220b3703182002200520006b360214200241c8006a41186a200a370300200241c8006a41106a2008370300200241c8006a41086a20063703002002200b370348200241e9dabdf30636026c200241a8016a4200370300200241a0016a420037030020024198016a420037030020024190016a420037030020094200370300200742003703002001420037030020024200370370200241ec006a200241c8006a20042003200241f0006a101c450d02410021010c030b200241003602140240200141ff0171450d00200241003a0090010b20024184016a4102360200200241d4006a410536020020024202370274200241c4b6c4003602702002410536024c200241a8b9c4003602482002410036021c200241e480c6003602182002200241c8006a360280012002200241186a360250200241f0006a41d4b6c400107d000b200241d4006a410536020020024184016a410236020020024202370274200241c4b6c4003602702002410536024c200241a8b9c4003602482002410036021c200241e480c6003602182002200241c8006a360280012002200241186a360250200241f0006a41d4b6c400107d000b20022d00af01210020022d00ae01210520022d00ad01210720022d00ac01210920022d00ab01210c20022d00aa01210d20022d00a901210e20022d00a801210f20022d00a701211020022d00a601211120022d00a501211220022d00a401211320022d00a301211420022d00a201211520022d00a101211620022d00a001211720022d009f01211820022d009e01211920022d009d01211a20022d009c01211b20022d009b01211c20022d009a01211d20022d009901211e20022d009801211f20022d009701212020022d009601212120022d009501212220022d009401212320022d009301212420022d009201212520022d009101212620022d009001212720022d008f01212820022d008e01212920022d008d01212a20022d008c01212b20022d008b01212c20022d008a01212d20022d008901212e20022d008801212f20022d008701213020022d008601213120022d008501213220022d008401213320022d008301213420022d008201213520022d008101213620022d008001213720022d007f213820022d007e213920022d007d213a20022d007c213b20022d007b213c20022d007a213d20022d0079213e20022d0078213f20022d0077214020022d0076214120022d0075214220022d0074214320022d0073214420022d0072214520022d0071214620022d00702147410110322201450d03200120473a000020014101410210342201450d04200120463a000120014102410410342201450d05200120443a0003200120453a000220014104410810342201450d06200120403a0007200120413a0006200120423a0005200120433a000420014108411010342201450d07200120383a000f200120393a000e2001203a3a000d2001203b3a000c2001203c3a000b2001203d3a000a2001203e3a00092001203f3a000820014110412010342201450d08200120283a001f200120293a001e2001202a3a001d2001202b3a001c2001202c3a001b2001202d3a001a2001202e3a00192001202f3a0018200120303a0017200120313a0016200120323a0015200120333a0014200120343a0013200120353a0012200120363a0011200120373a00102001412041c00010342201450d09200120003a003f200120053a003e200120073a003d200120093a003c2001200c3a003b2001200d3a003a2001200e3a00392001200f3a0038200120103a0037200120113a0036200120123a0035200120133a0034200120143a0033200120153a0032200120163a0031200120173a0030200120183a002f200120193a002e2001201a3a002d2001201b3a002c2001201c3a002b2001201d3a002a2001201e3a00292001201f3a0028200120203a0027200120213a0026200120223a0025200120233a0024200120243a0023200120253a0022200120263a0021200120273a0020200242c0808080800837023c0b2002200136023802402003450d00200410290b200241f0006a200241386a10e70102402001450d00200228023c450d00200110290b2002350278210620023502702108200241b0016a240020082006422086840f0b102f000b20034101102e000b41014101102e000b41024101102e000b41044101102e000b41084101102e000b41104101102e000b41204101102e000b41c0004101102e000bd20c04067f047e0c7f037e230041a0026b22022400024002402001450d00200220003602100c010b200241013602100b20022001360214200241086a200241106a102c02400240024002400240024002400240024020022802080d0020022802142201200228020c2203490d002003417f4c0d050240024020030d00410121040c010b2003102d2204450d072004200228021022002003109b051a2002200120036b3602142002200020036a3602100b2004450d002002200241106a102c20022802000d082002280214220120022802042205490d082005417f4c0d0502400240024020050d004101210641010d010c0b0b2005102d2206450d012006200228021022002005109b0521072002200120056b3602142002200020056a3602102007450d0a0b41002100200241003a00b8012002280214417f6a210103402001417f460d0320024198016a20006a200228021022072d00003a00002002200741016a3602102002200041016a22073a00b801200220013602142001417f6a21012007210020074120470d000b200241186a41186a20024198016a41186a2903002208370300200241186a41106a20024198016a41106a2903002209370300200241186a41086a20024198016a41086a290300220a3703002002200229039801220b370318200241386a41186a2008370300200241386a41106a2009370300200241386a41086a200a3703002002200b37033841002101200241003a00d80120062100034020052001460d0420024198016a20016a20002d00003a00002002200141016a22073a00d801200041016a210020072101200741c000470d000b200241e0016a41386a220120024198016a41386a220c290300370300200241e0016a41306a220020024198016a41306a220d290300370300200241e0016a41286a220e20024198016a41286a220f290300370300200241e0016a41206a221020024198016a41206a2211290300370300200241e0016a41186a221220024198016a41186a2213290300370300200241e0016a41106a221420024198016a41106a2215290300370300200241e0016a41086a221620024198016a41086a221729030037030020022002290398013703e001200741ff017141c000490d04200241d8006a41386a22072001290300370300200241d8006a41306a20002903002208370300200241d8006a41286a200e2903002209370300200241d8006a41206a2010290300220a370300200241d8006a41186a2012290300220b370300200241d8006a41106a20142903002218370300200241d8006a41086a20162903002219370300200220022903e001221a37035820002008370300200e20093703002010200a3703002012200b3703002014201837030020162019370300200120072903003703002002201a3703e001200c2001290300370300200d2000290300370300200f200e29030037030020112010290300370300201320122903003703002015201429030037030020172016290300370300200220022903e001370398012004200320024198016a200241386a10114521010c050b20054101102e000b200241ec016a4105360200200241ac016a41023602002002420237029c01200241c4b6c40036029801200241053602e401200241b4b9c4003602e0012002410036025c200241e480c6003602582002200241e0016a3602a8012002200241d8006a3602e80120024198016a41d4b6c400107d000b0240200041ff0171450d00200241003a00b8010b200241ac016a4102360200200241ec016a41053602002002420237029c01200241c4b6c40036029801200241053602e401200241b4b9c4003602e0012002410036025c200241e480c6003602582002200241e0016a3602a8012002200241d8006a3602e80120024198016a41d4b6c400107d000b200141ff0171450d00200241003a00d8010b410221010b02402005450d00200610290b02402003450d00200410290b410110322200450d02200020012001410247713a0000200241a0026a24002000ad428080808010840f0b102f000b20034101102e000b41014101102e000b200241ec016a4105360200200241ac016a41023602002002420237029c01200241c4b6c40036029801200241053602e401200241b4b9c4003602e0012002410036025c200241e480c6003602582002200241e0016a3602a8012002200241d8006a3602e80120024198016a41d4b6c400107d000b900402037f047e230041e0006b2202240041002103200241003a00482000410120011b2104024002400240034020012003460d01200241286a20036a200420036a2d00003a00002002200341016a22003a00482000210320004120470d000b200241086a41186a200241286a41186a22032903002205370300200241086a41106a200241286a41106a22002903002206370300200241086a41086a200241286a41086a2201290300220737030020022002290328220837030820032005370300200020063703002001200737030020022008370328411310322203450d012003410029009884433700002003410f6a41002800a78443360000200341086a41002900a0844337000020024293808080b00237025420022003360250200241286a200241d0006a108101200228025421032002200228025022042002280258108403200228020021002002280204210102402003450d00200410290b410410322203450d0220032001410020001b360000200241e0006a24002003ad4280808080c000840f0b0240200341ff0171450d00200241003a00480b2002413c6a4102360200200241146a41053602002002420237022c200241c4b6c4003602282002410536020c200241c4b9c40036020820024100360254200241e480c6003602502002200241086a3602382002200241d0006a360210200241286a41d4b6c400107d000b41134101102e000b41044101102e000bd80c03047f017e067f23004180026b220224000240024020010d002002200136020c200241013602080c010b20022001417f6a36020c410121032002200041016a36020820002d0000220141014b0d0041002104410021000240024002400240024002400240024020010e020100010b2002200241086a102c20022802000d07200228020c220120022802042200490d072000417f4c0d010240024020000d00410121040c010b2000102d2204450d032004200228020822052000109b051a2002200120006b36020c2002200520006a3602080b2004450d07200241106a20042000ad22064220862006842206422088a710820420022802104101460d03200241186a280200210520022802142100410021030b2002200536021420022000360210200241e7e485f3063602b001200241d0016a41186a22074200370300200241d0016a41106a22084200370300200241d0016a41086a22094200370300200242003703d00141002101200241106a410020001b210a0240024020000d004100210b0c010b200a41046a280200210c200a280200210b0b200241b0016a200b4101200b1b200c4100200b1b200241d0016a101f200241f0006a41186a2007290300370300200241f0006a41106a2008290300370300200241f0006a41086a2009290300370300200220022903d0013703702002200536021420022000360210200241e2c289ab063602b001200742003703002008420037030020094200370300200242003703d0010240024020000d000c010b200a41046a280200210b200a28020021010b200241b0016a2001410120011b200b410020011b200241d0016a102020024190016a41186a2207200241d0016a41186a220129030037030020024190016a41106a2208200241d0016a41106a220b29030037030020024190016a41086a2209200241d0016a41086a220a290300370300200220022903d00137039001200220053602fc01200220003602f801200241e9dabdf3063602f40120014200370300200b4200370300200a4200370300200242003703d0010240024020000d00410021000c010b200241f8016a410020001b220041046a2802002105200028020021000b200241f4016a2000410120001b2005410020001b200241d0016a1020200241b0016a41186a22002001290300370300200241b0016a41106a2201200b290300370300200241b0016a41086a2205200a290300370300200241106a41086a200241f0006a41086a290300370300200241106a41106a200241f0006a41106a290300370300200241106a41186a200241f0006a41186a290300370300200220022903d0013703b00120022002290370370310200241c8006a2007290300370300200241c0006a2008290300370300200241386a20092903003703002002200229039001370330200241e8006a2000290300370300200241e0006a2001290300370300200241d8006a2005290300370300200220022903b001370350200241003602d801200242013703d001200241106a200241d0016a10ee012002200241306a3602b001200241b0016a200241d0016a108a012002200241d0006a3602b001200241b0016a200241d0016a108a0120022802d001210b20022802d401210a20022802d8012100024020032006a745720d00200410290b200041046a2201417f4c0d000240024020010d00410121050c010b200110322205450d040b2002410036021820022001360214200220053602102000200241106a10660240024020022802142205200228021822016b2000490d00200228021021050c010b200120006a22042001490d0620054101742207200420042007491b22044100480d060240024020050d002004103221050c010b200228021020052004103421050b2005450d0520022004360214200220053602100b200520016a200b2000109b051a200120006a21000240200a450d00200b10290b20024180026a24002000ad4220862005ad840f0b102f000b20004101102e000b200220022902143703d00141cfd8c2004116200241d0016a4194c7c2001054000b20014101102e000b20044101102e000b1033000b200241dc016a4105360200200241246a410236020020024202370214200241c4b6c400360210200241053602d401200241dcb9c4003602d001200241003602b401200241e480c6003602b0012002200241d0016a3602202002200241b0016a3602d801200241106a41d4b6c400107d000b850804057f017e017f017e02400240024002402002450d00410020016b410020014103711b2103200241796a4100200241074b1b210441002105034002400240200120056a2d000022064118744118752207417f4a0d0042808080801021080240200641c6fcc5006a2d0000417e6a220941024d0d0042808080808020210a0c070b0240024002400240024020090e03000102000b200541016a22062002490d024200210a0c090b4200210a200541016a220920024f0d08200120096a2d0000210902400240200641a07e6a2206410d4b0d000240024020060e0e0002020202020202020202020201000b200941e0017141a001460d0242808080808020210a0c0c0b02402009411874411875417f4c0d0042808080808020210a0c0c0b200941ff017141a001490d0142808080808020210a0c0b0b02402007411f6a41ff0171410b4b0d0002402009411874411875417f4c0d0042808080808020210a0c0c0b200941ff017141c001490d0142808080808020210a0c0b0b0240200941ff017141bf014d0d0042808080808020210a0c0b0b0240200741fe017141ee01460d0042808080808020210a0c0b0b2009411874411875417f4c0d0042808080808020210a0c0a0b42002108200541026a220620024f0d09200120066a2d000041c00171418001460d020c070b4200210a200541016a220920024f0d07200120096a2d0000210902400240200641907e6a220641044b0d000240024020060e050002020201000b200941f0006a41ff01714130490d0242808080808020210a0c0b0b02402009411874411875417f4c0d0042808080808020210a0c0b0b200941ff0171419001490d0142808080808020210a0c0a0b0240200941ff017141bf014d0d0042808080808020210a0c0a0b02402007410f6a41ff017141024d0d0042808080808020210a0c0a0b2009411874411875417f4c0d0042808080808020210a0c090b200541026a220620024f0d07200120066a2d000041c00171418001470d0642002108200541036a220620024f0d08200120066a2d000041c00171418001460d01428080808080e000210a42808080801021080c080b42808080808020210a4280808080102108200120066a2d000041c00171418001470d070b200641016a21050c010b0240200320056b4103710d000240200520044f0d000340200120056a220641046a280200200628020072418081828478710d01200541086a22052004490d000b0b200520024f0d010340200120056a2c00004100480d022002200541016a2205470d000c040b0b200541016a21050b20052002490d000b0b20002001360204200041086a2002360200200041003602000f0b428080808080c000210a42808080801021080c010b420021080b2000200a2008842005ad84370204200041013602000bd80f010c7f230041b0036b22012400200120003602e0010240024002400240024002400240411210322200450d002000410029009bbe44370000200041106a41002f00abbe443b0000200041086a41002900a3be4437000020014292808080a0023702dc02200120003602d802200141e0016a200141d8026a108a0120012802dc02210220012802e002210020012802d8022103200141d8026a41186a22044200370300200141d8026a41106a22054200370300200141d8026a41086a22064200370300200142003703d80220032000200141d8026a1000200141b8026a41186a2004290300370300200141b8026a41106a2005290300370300200141b8026a41086a2006290300370300200120012903d8023703b802200141d8026a200141b8026a10b303024020012d00e80222004102460d00200141b8026a412010040b2001410a6a200141e9026a41c700109b051a02402002450d00200310290b200141d1006a2001410a6a41c700109b051a20004102460d06200120003a00980120014198016a410172200141d1006a41c100109b052106200141ba016a21050240024020012d00b9014101460d00410021030c010b200120053602e001411210322200450d022000410029009bbe44370000200041106a41002f00abbe443b0000200041086a41002900a3be4437000020014292808080a0023702dc02200120003602d802200141e0016a200141d8026a108a0120012802e002210720012802dc02210420012802d802210320012d00980121000b02400240200041ff01714101470d00200120063602e001411210322200450d042000410029009bbe44370000200041106a41002f00abbe443b0000200041086a41002900a3be4437000020014292808080a0023702dc02200120003602d802200141e0016a200141d8026a108a0120012802dc02210220012802d80222000d010b024020012d00b9014101460d00200141d8026a41186a22004200370300200141d8026a41106a22054200370300200141d8026a41086a22064200370300200142003703d80241c4bfc400411a200141d8026a1000200141b8026a41186a2000290300370300200141b8026a41106a2005290300370300200141b8026a41086a2006290300370300200120012903d8023703b802200141b8026a412010040c060b200141d8026a41186a22004200370300200141d8026a41106a22064200370300200141d8026a41086a22084200370300200142003703d80241c4bfc400411a200141d8026a1000200141b8026a41186a2000290300370300200141b8026a41106a2006290300370300200141b8026a41086a2008290300370300200120012903d8023703b802200141203602dc022001200141b8026a3602d8022005200141d8026a1089010c050b20012802e0022108200141d8026a41186a22064200370300200141d8026a41106a22054200370300200141d8026a41086a22094200370300200142003703d80220002008200141d8026a1000200141b8026a41186a220a2006290300370300200141b8026a41106a2005290300370300200141b8026a41086a2009290300370300200120012903d8023703b802200141d8026a200141b8026a10b30320012d00e8024102460d03200141e0016a200141d8026a41d800109b051a20014191026a200141b9016a220529000037000020014199026a200541086a290000370000200141a1026a200541106a290000370000200141a9026a200541186a290000370000200141b1026a200541206a2d00003a000020064200370300200141d8026a41106a22054200370300200141d8026a41086a22094200370300200142003703d80220002008200141d8026a1000200a2006290300370300200141b8026a41106a2005290300370300200141b8026a41086a2009290300370300200120012903d8023703b802200141203602dc022001200141b8026a3602d802200141e0016a200141d8026a10850441012109024020020d00410021020c060b200010290c050b41124101102e000b41124101102e000b41124101102e000b41f1bec40041d300109201000b41002100410021090b024002400240024020030d00410021050c010b200141d8026a41186a22054200370300200141d8026a41106a22064200370300200141d8026a41086a22084200370300200142003703d80220032007200141d8026a1000200141b8026a41186a220a2005290300370300200141b8026a41106a220b2006290300370300200141b8026a41086a220c2008290300370300200120012903d8023703b802200141d8026a200141b8026a10b30320012d00e8024102460d01200141e0016a200141d8026a41d800109b051a200141e0016a41186a20014198016a41086a290300370300200141e0016a41206a20014198016a41106a29030037030020014188026a20014198016a41186a29030037030020014190026a20014198016a41206a2d00003a000020012001290398013703f001200542003703002006420037030020084200370300200142003703d80220032007200141d8026a1000200a2005290300370300200b2006290300370300200c2008290300370300200120012903d8023703b802200141203602dc022001200141b8026a3602d802200141e0016a200141d8026a108504410121052004450d00200310290b2002450d012009200045720d01200010290c010b41f1bec40041d300109201000b2004450d002003452005720d00200310290b200141b0036a24000b9a1103067f017e077f23004190036b22012400200120003602d0010240024002400240024002400240411210322200450d0020004100290089be44370000200041106a41002f0099be443b0000200041086a4100290091be4437000020014292808080a0023702c402200120003602c002200141d0016a200141c0026a108a0120012802c402210220012802c802210020012802c0022103200141c0026a41186a22044200370300200141c0026a41106a22054200370300200141c0026a41086a22064200370300200142003703c00220032000200141c0026a1000200141a0026a41186a2004290300370300200141a0026a41106a2005290300370300200141a0026a41086a2006290300370300200120012903c0023703a002200141c0026a200141a0026a10b503024020012d00cc0222004102460d00200141a0026a412010040b20012902c402210720012802c0022104200141026a200141cd026a41c300109b051a02402002450d00200310290b200141c5006a200141026a41c300109b051a20004102460d06200120003a00880120014188016a410172200141c5006a41c100109b052108200141aa016a21060240024020012d00a9014101460d00410021030c010b200120063602d001411210322200450d0220004100290089be44370000200041106a41002f0099be443b0000200041086a4100290091be4437000020014292808080a0023702c402200120003602c002200141d0016a200141c0026a108a0120012802c802210920012802c402210520012802c002210320012d00880121000b02400240200041ff01714101470d00200120083602d001411210322200450d0420004100290089be44370000200041106a41002f0099be443b0000200041086a4100290091be4437000020014292808080a0023702c402200120003602c002200141d0016a200141c0026a108a0120012802c402210220012802c00222000d010b024020012d00a9014101460d00200141c0026a41186a22004200370300200141c0026a41106a22064200370300200141c0026a41086a22084200370300200142003703c00241d7bec400411a200141c0026a1000200141a0026a41186a2000290300370300200141a0026a41106a2006290300370300200141a0026a41086a2008290300370300200120012903c0023703a002200141a0026a412010040c060b200141c0026a41186a22004200370300200141c0026a41106a22084200370300200141c0026a41086a220a4200370300200142003703c00241d7bec400411a200141c0026a1000200141a0026a41186a2000290300370300200141a0026a41106a2008290300370300200141a0026a41086a200a290300370300200120012903c0023703a002200141203602c4022001200141a0026a3602c0022006200141c0026a1089010c050b20012802c802210a200141c0026a41186a22084200370300200141c0026a41106a22064200370300200141c0026a41086a220b4200370300200142003703c0022000200a200141c0026a1000200141a0026a41186a220c2008290300370300200141a0026a41106a2006290300370300200141a0026a41086a200b290300370300200120012903c0023703a002200141c0026a200141a0026a10b50320012d00cc024102460d03200141d0016a200141c0026a41d000109b051a200141fd016a200141a9016a220629000037000020014185026a200641086a2900003700002001418d026a200641106a29000037000020014195026a200641186a2900003700002001419d026a200641206a2d00003a000020084200370300200141c0026a41106a22064200370300200141c0026a41086a220b4200370300200142003703c0022000200a200141c0026a1000200c2008290300370300200141a0026a41106a2006290300370300200141a0026a41086a200b290300370300200120012903c0023703a002200141003602c802200142013703c00220012802d00120012802d801200141c0026a109401200141dc016a200141c0026a108c0120012802c4022106200141a0026a412020012802c002220820012802c802100502402006450d00200810290b024020012802d401450d0020012802d00110290b4101210b024020020d00410021020c060b200010290c050b41124101102e000b41124101102e000b41124101102e000b41f1bec40041d300109201000b410021004100210b0b024002400240024020030d00410021060c010b200141c0026a41186a22064200370300200141c0026a41106a22084200370300200141c0026a41086a220a4200370300200142003703c00220032009200141c0026a1000200141a0026a41186a220c2006290300370300200141a0026a41106a220d2008290300370300200141a0026a41086a220e200a290300370300200120012903c0023703a002200141c0026a200141a0026a10b50320012d00cc024102460d01200141d0016a200141c0026a41d000109b051a200141e4016a20014188016a41086a290300370200200141ec016a20014188016a41106a290300370200200141f4016a20014188016a41186a290300370200200141fc016a20014188016a41206a2d00003a000020012001290388013702dc012006420037030020084200370300200a4200370300200142003703c00220032009200141c0026a1000200c2006290300370300200d2008290300370300200e200a290300370300200120012903c0023703a002200141003602c802200142013703c00220012802d00120012802d801200141c0026a109401200141dc016a200141c0026a108c0120012802c4022106200141a0026a412020012802c002220820012802c802100502402006450d00200810290b024020012802d401450d0020012802d00110290b410121062005450d00200310290b2002450d01200b200045720d01200010290c010b41f1bec40041d300109201000b02402005450d002003452006720d00200310290b2004450d002007a7450d00200410290b20014190036a24000bee0501047f230041106b2202240020024100360208200242013703002002200036020c2002410c6a2002109b01024002400240024002400240024020002d00104101460d0002400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d0720034101742205200420042005491b22054100480d070240024020030d002005103221040c010b200228020020032005103421040b2004450d0320022005360204200220043602000b2002200341016a360208200420036a41003a00000c010b02400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d0620034101742205200420042005491b22054100480d060240024020030d002005103221040c010b200228020020032005103421040b2004450d0320022005360204200220043602000b2002200341016a360208200420036a41013a0000200041116a20021081010b02400240200041316a2d00004101460d0002400240200228020420022802082200460d00200228020021030c010b200041016a22032000490d0720004101742204200320032004491b22044100480d070240024020000d002004103221030c010b200228020020002004103421030b2003450d052002200436020420022003360200200228020821000b2002200041016a360208200320006a41003a00000c010b02400240200228020420022802082203460d00200228020021040c010b200341016a22042003490d0620034101742205200420042005491b22054100480d060240024020030d002005103221040c010b200228020020032005103421040b2004450d052002200536020420022004360200200228020821030b2002200341016a360208200420036a41013a0000200041326a20021081010b2002280204210020012802002001280204200228020022012002280208100502402000450d00200110290b200241106a24000f0b20054101102e000b20054101102e000b20044101102e000b20054101102e000b1033000b13002000410d360204200041e0bfc4003602000b3400200041efecc40036020420004100360200200041146a4113360200200041106a41f8ecc400360200200041086a42073702000b0900200041001082020b6b01027f230041106b22022400200241003602082002420137030002404104103222030d0041044101102e000b2003410036000020024284808080c00037020420022003360200410020021066200041086a200228020836020020002002290300370200200241106a24000b3001017f02404108103222020d0041084101102e000b20004288808080800137020420002002360200200242003700000b8d0201037f230041c0006b22022400200241186a4200370300200241106a22034200370300200241086a4200370300200241286a22044100360200200242003703002002420837032020024100360238200242013703302002200236023c2002413c6a200241306a109b012002200336023c2002413c6a200241306a109b012002280220210320042802002204200241306a106602402004450d00200441306c21040340200341106a200241306a1081012002200336023c200341306a21032002413c6a200241306a109b01200441506a22040d000b0b20002002290330370200200041086a200241306a41086a28020036020002402002280224450d00200228022010290b200241c0006a24000b7001027f230041306b2202240020024200370310200242003703082002200241086a36021c02404101103222030d0041014101102e000b20024201370224200220033602202002411c6a200241206a109b01200041086a200228022836020020002002290320370200200241306a24000b3001017f02404104103222020d0041044101102e000b20004284808080c00037020420002002360200200241043600000be70201067f230041d0006b220224000240410e10322203450d00200341002900e4bd44370000200341066a41002900eabd443700002002428e808080e00137020c200220033602082001200241086a108101200228020c21042002280210210520022802082103200241086a41186a22014200370300200241086a41106a22064200370300200241086a41086a220742003703002002420037030820032005200241086a1000200241306a41186a2001290300370300200241306a41106a2006290300370300200241306a41086a200729030037030020022002290308370330200241086a200241306a412010590240024020022d00084101460d00200041003a00000c010b20002002290308370000200041206a200241086a41206a2d00003a0000200041186a2001290300370000200041106a2006290300370000200041086a20072903003700000b02402004450d00200310290b200241d0006a24000f0b410e4101102e000b130020004102360204200041c08dc5003602000b3101017f02404104103222020d0041044101102e000b20004284808080c00037020420002002360200200241a0053600000b940705017f047e087f057e017f23004180026b22022400200241c0006a2001109701024002402002290340a7450d00200041003602200c010b200241c0006a41106a290300210320022903482104200241286a200110970102402002290328a7450d00200041003602200c010b200241286a41106a290300210520022903302106200241206a2001102c0240024002400240024020022802200d00200128020441306e220741306c2208417f4c0d02200228022421090240024020080d004108210a0c010b20081032220a450d040b02402009450d004100210b0340200241003a00f801200b220c41016a210b2001280204417f6a21084100210d024002400240024003402008417f460d01200241d8016a200d6a2001280200220e2d00003a0000200120083602042001200e41016a3602002002200d41016a220e3a00f8012008417f6a2108200e210d200e4120470d000b200241b8016a41186a2208200241d8016a41186a290300370300200241b8016a41106a220d200241d8016a41106a290300370300200241b8016a41086a220e200241d8016a41086a290300370300200220022903d8013703b801200241086a20011097012002290308a70d01200241086a41106a290300210f20022903102110200241f8006a41086a200e2903002211370300200241f8006a41106a200d2903002212370300200241f8006a41186a20082903002213370300200241d8006a41086a220d2011370300200241d8006a41106a220e2012370300200241d8006a41186a22142013370300200220022903b8012211370378200220113703582007200c470d030240200c4101742208200b200b2008491b2207ad42307e2211422088a70d002011a7220841004e0d030b1033000b200d41ff0171450d00200241003a00f8010b200241f8006a41086a20024198016a41086a2903003703002007450d04200a10290c040b02400240200c0d0020081032210a0c010b200a200c41306c20081034210a0b200a450d070b200a200c41306c6a2208200f3703082008201037030020082002290358370310200841186a200d290300370300200841206a200e290300370300200841286a2014290300370300200b2009470d000b0b200a0d010b200041003602200c040b20002004370300200020073602242000200a3602202000200637031020002003370308200041286a2009360200200041186a20053703000c030b102f000b20084108102e000b20084108102e000b20024180026a24000b870d021e7f037e230041f0026b220424000240024002400240410d10322205450d0041002106200541002900cabe44370000200541056a41002900cfbe443700002004428d808080d0013702a402200420053602a0022001200441a0026a10810120042802a402210720042802a802210820042802a0022105200441a0026a41186a22094200370300200441a0026a41106a220a4200370300200441a0026a41086a220b4200370300200442003703a00220052008200441a0026a1000200441e0016a41186a2009290300370300200441e0016a41106a200a290300370300200441e0016a41086a200b290300370300200420042903a0023703e001200441003602a002200441e0016a4120200441a0026a10062108024020042802a0022209417f460d002009450d0220082d0000220641034f0d02200810290b02402007450d00200510290b02400240024020060e03000201000b200441f8006a2001108e0420042d00784101470d04200441a0016a41186a220520044191016a290000370300200441a0016a41106a220620044189016a290000370300200441a0016a41086a220820044181016a290000370300200420042900793703a001200441a0026a200441a0016a10f902200441c0016a41186a22072005290300370300200441c0016a41106a220b2006290300370300200441c0016a41086a220c2008290300370300200420042903a0013703c00120042802c002220d450d04200441e0016a41186a220e2007290300370300200441e0016a41106a220f200b290300370300200441e0016a41086a2210200c290300370300200441e0016a41286a2205200441a0026a41086a2206290300370300200441e0016a41306a2208200441a0026a41106a2207290300370300200441e0016a41386a2209200441a0026a41186a220a290300370300200441086a41286a2211200441ec026a2212280200360200200441086a41206a2213200441e4026a2214290200370300200441086a41186a2215200441dc026a2216290200370300200441086a41106a2217200441d4026a2218290200370300200441086a41086a2219200441cc026a221a290200370300200420042903c0013703e001200420042903a00237038002200420042902c402370308200441386a41386a221b2009290300370300200441386a41306a221c2008290300370300200441386a41286a221d2005290300370300200441386a41206a221e200429038002370300200441386a41186a221f200e290300370300200441386a41106a2220200f290300370300200441386a41086a22212010290300370300200420042903e0013703382009201b2903003703002008201c2903003703002005201d290300370300200441e0016a41206a221b201e290300370300200e201f290300370300200f202029030037030020102021290300370300200420042903383703e001200441f8006a41186a201f290300370300200441f8006a41106a2020290300370300200441f8006a41086a202129030037030020042004290338370378200a200929030037030020072008290300370300200620052903003703002004200d3602c0022004201b2903003703a002200441c4026a22052004290308370200201a201929030037020020182017290300370200201620152903003702002014201329030037020020122011280200360200200a290300212220072007290300222320027c2224370300200a202220037c2024202354ad7c37030020062903002122200420042903a002222320027c22243703a0022006202220037c2024202354ad7c370300200441c0016a20012002200310bf0120043502c0012102200b2903002122200c2903002103200441f8006a200441a0026a10950402402005280200450d0020042802c00210290b200242018521020c050b200441a0026a2001108e0420042d00a0024101470d03200441f8016a200441b9026a290000370300200441e0016a41106a200441b1026a290000370300200441e0016a41086a200441a9026a290000370300200420042900a1023703e001200441386a200441e0016a2002200310bf0120043502384201852102200441386a41106a2903002122200441386a41086a29030021030c040b200441a0026a20012002200310bf0120043502a0024201852102200441b0026a2903002122200441a8026a29030021030c030b410d4101102e000b41f7cdc3004133200441a0026a41ecd6c3001054000b420021020b2000200337030820002002370300200041106a2022370300200441f0026a24000bac0702077f077e230041f0026b22022400200241386a2001280200200128020428020c1100000240024020022903384201520d00200241a8026a4101722103200241386a41086a21040340200241b8016a41186a2205200441186a290000370300200241b8016a41106a2206200441106a290000370300200241b8016a41086a2207200441086a290000370300200220042900003703b801200241a8026a200241b8016a108e04024002400240024020022d00a8024101460d00200241003602f8010c010b200241d0026a41186a200341186a290000370300200241d0026a41106a200341106a290000370300200241d0026a41086a200341086a290000370300200220032900003703d002200241d8016a200241d0026a10f90220022802f80122080d010b420021094200210a0c010b200241d8016a41186a290300210a20022903e801210920022802fc01450d00200810290b20024198016a41086a2007290300220b37030020024198016a41106a2006290300220c37030020024198016a41186a2005290300220d370300200220022903b801220e37039801200241d8016a41086a200b370300200241d8016a41106a200c370300200241d8016a41186a200d3703002002200e3703d801200241a8026a41086a22054200370300200242003703a80241c2d5c0004116200241a8026a1003200241d0026a41086a2005290300370300200220022903a8023703d002200241206a200241d0026a10eb01200241106a2002290328200241206a41106a290300427f420010a10520022009200a20022903104200200228022022051b220b4201200b420156200241106a41086a290300420020051b220b420052200b501b22051b200b420020051b10a10502402002290300220b500d00200241f8006a41186a200241d8016a41186a290300220c370300200241f8006a41106a200241d8016a41106a290300220d370300200241f8006a41086a200241d8016a41086a290300220e370300200220022903d801220f370378200220022800b8013602702002200241bb016a280000360073200041186a42003703002000200b37031020004200370308200042003703002000200f370320200041286a200e370300200041306a200d370300200041386a200c370300200041003a0040200041d0006a200a370000200041c8006a200937000020002002280270360041200041c4006a20022800733600000c030b200241386a2001280200200128020428020c11000020022903384201510d000b0b200041023a00400b200241f0026a24000b0900200042003702000bc40201067f230041d0006b22022400200242f3e885db96cddbb320370308200241086a2001412c6a2001290300200141086a290300417f410e1093010240410e10322203450d00200341002900bcbe44370000200341066a41002900c2be443700002002428e808080e001370234200220033602302000200241306a108101200228023421002002280238210420022802302103200241306a41186a22054200370300200241306a41106a22064200370300200241306a41086a220742003703002002420037033020032004200241306a1000200241106a41186a2005290300370300200241106a41106a2006290300370300200241106a41086a200729030037030020022002290330370310200241203602342002200241106a3602302001200241306a10980402402000450d00200310290b200241d0006a24000f0b410e4101102e000b02000b950302027f067e230041f0006b22032400200341386a200110de0302400240024020032903384201520d00200241016a2104200341386a41086a21020340200341086a41286a200241286a2903002205370300200341086a41206a200241206a2903002206370300200341086a41186a200241186a2903002207370300200341086a41106a200241106a2903002208370300200341086a41086a200241086a290300220937030020032002290300220a370308200341386a41286a2005370300200341386a41206a2006370300200341386a41186a2007370300200341386a41106a2008370300200220093703002003200a3703382004417f6a2204450d02200341386a200110de0320032903384201510d000b0b200042003703000c010b2000200329033837030820004201370300200041306a200341386a41286a290300370300200041286a200341386a41206a290300370300200041206a200341386a41186a290300370300200041186a200341386a41106a290300370300200041106a200341c0006a2903003703000b200341f0006a24000bcd0101027f230041106b2202240020024100360208200242013703002000412c6a20021081012002200036020c2002410c6a2002109b012002200041106a36020c2002410c6a2002109b0120002802202103200041286a28020022002002106602402000450d002003200041186c6a210003402002200336020c2002410c6a2002109b01200341106a20021098012000200341186a2203470d000b0b2002280204210320012802002001280204200228020022002002280208100502402003450d00200010290b200241106a24000ba108010a7f230041a0016b2202240041002103024020012802102204450d0020012802082205200128020c460d00200128021421062001200541246a3602082002413c6a41026a2207200541036a2d00003a0000200241206a41086a2208200541146a290000370300200241206a410d6a2209200541196a290000370000200220052f00013b013c20022005410c6a29000037032020052d0000220a4102460d00200541086a280000210b200541046a280000210520012004417f6a360210200241026a20072d00003a0000200241e0006a41086a2008290300370300200241e0006a410d6a2009290000370000200220022f013c3b010020022002290320370360024002400240200a4101460d002002419c016a41026a200241026a2d00003a000020024180016a41086a200241e0006a41086a29030037030020024180016a410d6a200241e0006a410d6a290000370000200220022f01003b019c0120022002290360370380010c010b200241c0006a200541067610ab02200228024021040240024020022802482005413f7122014b0d00410021010c010b2002419c016a41026a200420014105746a220141026a2d00003a000020024188016a200141136a2900003703002002418d016a200141186a290000370000200220012f00003b019c012002200129000b370380012001280007210b20012800032105410121010b02402002280244450d00200410290b20010d00410121014115210b41c8d8c30021050c010b200241fc006a41026a2002419c016a41026a2d00003a0000200241e0006a41086a20024180016a41086a290300370300200241e0006a410d6a20024180016a410d6a290000370000200220022f019c013b017c2002200229038001370360410021010b200241dc006a41026a2204200241fc006a41026a2d00003a0000200241c0006a41086a2207200241e0006a41086a290300370300200241c0006a41106a200241e0006a41106a290300370300200220022f017c3b015c200220022903603703400240024020010d002002419c016a41026a20042d00003a000020024180016a41086a200729030037030020024180016a410d6a200241c0006a410d6a290000370000200220022f015c3b019c012002200229034037038001410121010c010b2006200b36020420062005360200410021010b2002411c6a41026a22042002419c016a41026a2d00003a0000200241086a220720024180016a41086a2903003703002002410d6a220820024180016a410d6a290000370000200220022f019c013b011c20022002290380013703002001450d00200020022f011c3b0001200041086a200b360000200041046a20053600002000410c6a2002290300370000200041036a20042d00003a0000200041146a2007290300370000200041196a2008290000370000410121030b200020033a0000200241a0016a24000b3802017f017e230041106b220324002003200210be01200329030021042000200341086a29030037030820002004370300200341106a24000bef0101057f230041c0006b220524000240024020030d00200041003602000c010b2003280208210620032802002103200541206a41186a22074200370300200541206a41106a22084200370300200541206a41086a220942003703002005420037032020044120200541206a1000200541186a2007290300370300200541106a2008290300370300200541086a200929030037030020052005290320370300200541003602202003200620054120200541206a10012104024020052802202203417f460d002000200336020420002004360200200041086a20033602000c010b200041003602000b200541c0006a24000baf0201027f23004190016b22032400200320021096020240024020032d000022024102470d00200041003a00000c010b200341e0006a200341286a290300370300200341e8006a200341306a290300370300200341d8006a41186a200341386a290300370300200341d8006a41206a200341c0006a290300370300200341d8006a41286a200341c8006a290300370300200341d8006a41306a200341d0006a2802003602002003200341206a29030037035802402002450d00200041003a00000c010b2003411c6a2802002102200341186a28020021042000200329026c370001200041013a0000200041196a20034184016a290200370000200041116a200341fc006a290200370000200041096a200341d8006a411c6a2902003700002002450d00200410290b20034190016a24000b950201067f230041c0006b220224000240411710322203450d00200341002900f9f9433700002003410f6a4100290088fa43370000200341086a4100290081fa4337000020024297808080f002370224200220033602202001200241206a108101200228022421012002280228210420022802202103200241206a41186a22054200370300200241206a41106a22064200370300200241206a41086a220742003703002002420037032020032004200241206a1000200241186a2005290300370300200241106a2006290300370300200241086a200729030037030020022002290320370300200241204101410041001007210402402001450d00200310290b200241c0006a24002004417f470f0b41174101102e000b870102017f037e230041e0006b22032400200341086a20021096020240024020032d000822024102470d00420021040c010b2002410173ad2104200341186a2903002105200341106a290300210620020d00200341246a280200450d00200341206a28020010290b2000200637030820002004370300200041106a2005370300200341e0006a24000bd80402097f017e230041106b22052400024002400240200128020041016a220641004c0d0020012006360200200141046a2106200141086a28020021070240024003402006280200220841086a210920082f0106220a41057421064100210b0240024003402006450d01200220094120109d05220c450d02200641606a2106200b41016a210b200941206a2109200c417f4a0d000b200b417f6a210a0b2007450d022007417f6a21072008200a4102746a41880b6a21060c010b0b2008200b41e0006c6a22094198036a2106200941e8026a210d2009419c036a2802002107024003402006280200220841086a210920082f0106220a41057421064100210b0240024003402006450d01200420094120109d05220c450d02200641606a2106200b41016a210b200941206a2109200c417f4a0d000b200b417f6a210a0b024020070d004100210c0c030b2007417f6a21072008200a4102746a41ec036a21060c010b0b4101210c0240200841e8026a200b410c6c6a2206280200220b0d00410021060c010b20062802082209417f4c0d040240024020090d0020054200370300410121060c010b200910322206450d0620054100360204200520093602000b200520093602042006200b2009109b051a2005290300210e0b02400240200d2d005d450d0020064100200c1b21060c010b200c450d010b2000200e370204200020063602000c010b20002001280210200220032004200141146a28020028020c1106000b20012001280200417f6a360200200541106a24000f0b41f898c5004118200541086a419099c5001054000b102f000b20094101102e000bfc0202097f037e230041206b220324000240200128020041016a220441004c0d0020012004360200200141046a2105200141086a28020021060240024003402005280200220741086a210820072f0106220941057421054100210a0240024003402005450d01200220084120109d05220b450d02200541606a2105200a41016a210a200841206a2108200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200720094102746a41880b6a21050c010b0b2007200a41e0006c6a22054190036a290300210c20054188036a290300210d20054180036a290300210e0240200541c5036a2d00000d00200ea721054201210e2005450d010c020b200e4202520d010b200320012802102002200141146a280200280214110200200341106a290300210c200128020021042003290308210d2003290300210e0b20012004417f6a360200200041106a200c3703002000200d3703082000200e370300200341206a24000f0b41f898c5004118200341186a419099c5001054000be80202097f027e230041206b220324000240200128020041016a220441004c0d0020012004360200200141046a2105200141086a28020021060240024003402005280200220741086a210820072f0106220941057421054100210a0240024003402005450d01200220084120109d05220b450d02200541606a2105200a41016a210a200841206a2108200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200720094102746a41880b6a21050c010b0b2007200a41e0006c6a220541c5036a310000200541e8026a290300220c200c5022081ba7450d004200200541f8026a29030020081b210c4200200541f0026a29030020081b210d0c010b200341086a20012802102002200141146a28020028021c110200200341106a290300210c200128020021042003290308210d0b20012004417f6a3602002000200c3703082000200d370300200341206a24000f0b41f898c5004118200341186a419099c5001054000bcb0401097f230041c0006b220324000240200128020041016a220441004c0d0020012004360200200141046a2105200141086a280200210602400240024003402005280200220741086a210820072f0106220941057421054100210a0240024003402005450d01200220084120109d05220b450d02200541606a2105200a41016a210a200841206a2108200b417f4a0d000b200a417f6a21090b2006450d022006417f6a2106200720094102746a41880b6a21050c010b0b2007200a41e0006c6a220841e8026a210502400240200841c5036a2d00000d00200341206a41086a220a200541c5006a290000370300200341206a41106a220b200541cd006a290000370300200341206a41186a2207200541d5006a29000037030020032005413d6a2900003703204102210820052d003c4101470d01200341186a2007290300370300200341106a200b290300370300200341086a200a29030037030020032003290320370300410121080c010b200341086a200541c5006a290000370300200341106a200541cd006a290000370300200341186a200541d5006a29000037030020032005413d6a29000037030020052d003c21080b200841ff01714102470d010b200020012802102002200141146a280200280210110200200128020021040c010b200020083a000020002003290300370001200041096a200341086a290300370000200041116a200341106a290300370000200041196a200341186a2903003700000b20012004417f6a360200200341c0006a24000f0b41f898c5004118200341206a419099c5001054000b3400200041a0a0c50036020420004100360200200041146a4103360200200041106a41a8a0c500360200200041086a42083702000b5101027f230041106b2202240002404104103222030d0041044101102e000b2002420437020420022003360200410020021066200041086a200228020836020020002002290300370200200241106a24000b9b0101017f02400240411b10322201450d00200141176a41002800dea845360000200141106a41002900d7a845370000200141086a41002900cfa845370000200141002900c7a8453700002001411b413610342201450d01200142e5f4bcb3e68cdbb4ee00370023200142e9dab5f9e68ddbb4ee0037001b200042b6808080b005370204200020013602000f0b411b4101102e000b41364101102e000bc20601087f230041d0006b220224000240024002400240024002400240411f10322203450d00200341176a41002900bfa845370000200341106a41002900b8a845370000200341086a41002900b0a845370000200341002900a8a8453700002002429f808080f003370204200220033602004198a8c500200210ec022002280200210420022802082103200241106a41186a22054200370300200241106a41106a22064200370300200241106a41086a220742003703002002420037031020042003200241106a1000200241306a41186a22082005290300370300200241306a41106a22052006290300370300200241306a41086a2206200729030037030020022002290310370330412010322203450d0120032002290330370000200341186a2008290300370000200341106a2005290300370000200341086a200629030037000002402002280204450d00200410290b2001280208220441046a2205417f4c0d02200128020021070240024020050d00410121010c010b200510322201450d040b2002410036023820022005360234200220013602302004200241306a10660240024020022802342206200228023822016b2004490d00200228023021050c010b200120046a22052001490d0620064101742208200520052008491b22084100480d060240024020060d002008103221050c010b200228023020062008103421050b2005450d052002200836023420022005360230200821060b200520016a20072004109b051a200241106a41186a22074200370300200241106a41106a22084200370300200241106a41086a22094200370300200242003703102005200120046a200241106a1000200241306a41186a22042007290300370300200241306a41106a22012008290300370300200241306a41086a22072009290300370300200220022903103703302003412041c00010342203450d0620032002290330370020200341386a2004290300370000200341306a2001290300370000200341286a200729030037000002402006450d00200510290b200042c0808080800837020420002003360200200241d0006a24000f0b411f4101102e000b41204101102e000b102f000b20054101102e000b20084101102e000b1033000b41c0004101102e000bb204030e7f017e017f230041c0006b22032400200128020022042001280208220541047422066a210720012802042108200421010240024002402005450d00200341306a41017221094100210a200341306a41026a210b200341206a410172220c41076a210d0340200b2004200a6a220141036a2d00003a00002003200141016a2f00003b0130024020012d0000220e41ac01470d00200141106a21010c020b2003410c6a41026a200b2d0000220f3a0000200320032f013022103b010c200141046a29020021112001410c6a2802002112200920103b0000200941026a200f3a00002003200e3a00302003201236023c20032011370234200341206a200341306a200210a8042003200c2900003703102003200d290000370017024020032d0020220e411a470d002006200a41106a220a470d010c030b0b2000200e3a000020002003290310370001200041086a20032900173700000240200541047441706a200a460d00200141186a2101034002400240200141786a220a2d0000220b4109460d00200b41ac01470d010c030b200128020041ffffffff0371450d00200a41046a28020010290b200141106a2101200a41106a2007470d000b0b2008450d02200410290c020b20012007460d0003400240024020012d0000220a4109460d00200a41ac01470d010c030b200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a22012007470d000b0b02402008450d00200410290b2000411a3a00000b200341c0006a24000bf6d60202097f017e230041106b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000eac01000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab01000b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006103221050c010b200228020420042006103421050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41003a00000cab010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006103221050c010b200228020420042006103421050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41013a00000caa010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df50120044101742208200520052008491b22084100480df5010240024020040d002008103221050c010b200628020020042008103421050b2005450dad0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41023a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df50120044101742208200520052008491b22084100480df5010240024020040d002008103221050c010b200628020020042008103421050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca9010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df40120044101742208200520052008491b22084100480df4010240024020040d002008103221050c010b200628020020042008103421050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41033a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df40120044101742208200520052008491b22084100480df4010240024020040d002008103221050c010b200628020020042008103421050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca8010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df30120044101742208200520052008491b22084100480df3010240024020040d002008103221050c010b200628020020042008103421050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41043a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df30120044101742208200520052008491b22084100480df3010240024020040d002008103221050c010b200628020020042008103421050b2005450db00120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca7010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006103221050c010b200228020420042006103421050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41053a00000ca6010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006103221050c010b200228020420042006103421050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410b3a00000ca5010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490df00120044101742207200620062007491b22074100480df0010240024020040d002007103221060c010b200928020020042007103421060b2006450db00120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410c3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df1012004410174220a20062006200a491b220a4100480df1010240024020040d00200a103221060c010b20092802002004200a103421060b2006450db201200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca5010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490def0120044101742207200620062007491b22074100480def010240024020040d002007103221060c010b200928020020042007103421060b2006450db10120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410d3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df0012004410174220a20062006200a491b220a4100480df0010240024020040d00200a103221060c010b20092802002004200a103421060b2006450db301200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca4010b0b200241046a210a2001410c6a2802002104200141086a2802002109200141046a280200210b02400240200241086a2802002002410c6a2802002201460d00200a28020021050c010b200141016a22052001490dee0120014101742206200520052006491b22064100480dee010240024020010d002006103221050c010b200a28020020012006103421050b2005450db20120022005360204200241086a20063602002002410c6a28020021010b2002410c6a2206200141016a360200200520016a410e3a000020032009200b200b20094102746a200210a90420032d0000411a470d9303200241086a2107034002400240200728020020062802002201460d00200a28020021050c010b200141016a22052001490def0120014101742208200520052008491b22084100480def010240024020010d002008103221050c010b200a28020020012008103421050b2005450db4012002200536020420072008360200200628020021010b2006200141016a360200200520016a200441807f72200441ff0071200441077622011b3a00002001210420010d000b0240200941ffffffff0371450d00200b10290b2000411a3a00000c95030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490ded0120044101742206200520052006491b22064100480ded010240024020040d002006103221050c010b200228020420042006103421050b2005450db30120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410f3a00000ca1010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490dec0120044101742207200620062007491b22074100480dec010240024020040d002007103221060c010b200928020020042007103421060b2006450db30120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41103a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490ded012004410174220a20062006200a491b220a4100480ded010240024020040d00200a103221060c010b20092802002004200a103421060b2006450db501200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca1010b0b200241046a2109200141046a280200210520012d0001210b02400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490deb0120044101742207200620062007491b22074100480deb010240024020040d002007103221060c010b200928020020042007103421060b2006450db40120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41113a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490dec012004410174220a20062006200a491b220a4100480dec010240024020040d00200a103221060c010b20092802002004200a103421060b2006450db601200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b02400240200241086a2802002002410c6a2802002204460d00200928020021050c010b200441016a22052004490deb0120044101742206200520052006491b22064100480deb010240024020040d002006103221050c010b200928020020042006103421050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a200b3a00000c9f010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dea0120044101742206200520052006491b22064100480dea010240024020040d002006103221050c010b200228020420042006103421050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411a3a00000c9e010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490de90120044101742206200520052006491b22064100480de9010240024020040d002006103221050c010b200228020420042006103421050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411b3a00000c9d010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de80120044101742207200620062007491b22074100480de8010240024020040d002007103221060c010b200928020020042007103421060b2006450db60120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41203a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de9012004410174220a20062006200a491b220a4100480de9010240024020040d00200a103221060c010b20092802002004200a103421060b2006450db801200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9d010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de70120044101742207200620062007491b22074100480de7010240024020040d002007103221060c010b200928020020042007103421060b2006450db70120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41213a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de8012004410174220a20062006200a491b220a4100480de8010240024020040d00200a103221060c010b20092802002004200a103421060b2006450db901200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9c010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de60120044101742207200620062007491b22074100480de6010240024020040d002007103221060c010b200928020020042007103421060b2006450db80120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41223a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de7012004410174220a20062006200a491b220a4100480de7010240024020040d00200a103221060c010b20092802002004200a103421060b2006450dba01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9b010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de50120044101742207200620062007491b22074100480de5010240024020040d002007103221060c010b200928020020042007103421060b2006450db90120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41233a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de6012004410174220a20062006200a491b220a4100480de6010240024020040d00200a103221060c010b20092802002004200a103421060b2006450dbb01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9a010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de40120044101742207200620062007491b22074100480de4010240024020040d002007103221060c010b200928020020042007103421060b2006450dba0120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41243a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de5012004410174220a20062006200a491b220a4100480de5010240024020040d00200a103221060c010b20092802002004200a103421060b2006450dbc01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c99010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de30120044101742208200720072008491b22084100480de3010240024020040d002008103221070c010b200a28020020042008103421070b2007450dbb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41283a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de4012004410174220b20072007200b491b220b4100480de4010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dbd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de40120044101742209200620062009491b22094100480de4010240024020040d002009103221060c010b200a28020020042009103421060b2006450dbe012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c98010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de20120044101742208200720072008491b22084100480de2010240024020040d002008103221070c010b200a28020020042008103421070b2007450dbd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41293a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de3012004410174220b20072007200b491b220b4100480de3010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dbf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de30120044101742209200620062009491b22094100480de3010240024020040d002009103221060c010b200a28020020042009103421060b2006450dc0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c97010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de10120044101742208200720072008491b22084100480de1010240024020040d002008103221070c010b200a28020020042008103421070b2007450dbf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de2012004410174220b20072007200b491b220b4100480de2010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dc101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de20120044101742209200620062009491b22094100480de2010240024020040d002009103221060c010b200a28020020042009103421060b2006450dc2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c96010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de00120044101742208200720072008491b22084100480de0010240024020040d002008103221070c010b200a28020020042008103421070b2007450dc10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de1012004410174220b20072007200b491b220b4100480de1010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dc301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de10120044101742209200620062009491b22094100480de1010240024020040d002009103221060c010b200a28020020042009103421060b2006450dc4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c95010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddf0120044101742208200720072008491b22084100480ddf010240024020040d002008103221070c010b200a28020020042008103421070b2007450dc30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de0012004410174220b20072007200b491b220b4100480de0010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dc501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de00120044101742209200620062009491b22094100480de0010240024020040d002009103221060c010b200a28020020042009103421060b2006450dc6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c94010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dde0120044101742208200720072008491b22084100480dde010240024020040d002008103221070c010b200a28020020042008103421070b2007450dc50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddf012004410174220b20072007200b491b220b4100480ddf010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dc701200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddf0120044101742209200620062009491b22094100480ddf010240024020040d002009103221060c010b200a28020020042009103421060b2006450dc8012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c93010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddd0120044101742208200720072008491b22084100480ddd010240024020040d002008103221070c010b200a28020020042008103421070b2007450dc70120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dde012004410174220b20072007200b491b220b4100480dde010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dc901200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dde0120044101742209200620062009491b22094100480dde010240024020040d002009103221060c010b200a28020020042009103421060b2006450dca012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c92010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddc0120044101742208200720072008491b22084100480ddc010240024020040d002008103221070c010b200a28020020042008103421070b2007450dc90120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412f3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddd012004410174220b20072007200b491b220b4100480ddd010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dcb01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddd0120044101742209200620062009491b22094100480ddd010240024020040d002009103221060c010b200a28020020042009103421060b2006450dcc012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c91010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddb0120044101742208200720072008491b22084100480ddb010240024020040d002008103221070c010b200a28020020042008103421070b2007450dcb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41303a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddc012004410174220b20072007200b491b220b4100480ddc010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dcd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddc0120044101742209200620062009491b22094100480ddc010240024020040d002009103221060c010b200a28020020042009103421060b2006450dce012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c90010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dda0120044101742208200720072008491b22084100480dda010240024020040d002008103221070c010b200a28020020042008103421070b2007450dcd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41313a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddb012004410174220b20072007200b491b220b4100480ddb010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dcf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddb0120044101742209200620062009491b22094100480ddb010240024020040d002009103221060c010b200a28020020042009103421060b2006450dd0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8f010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd90120044101742208200720072008491b22084100480dd9010240024020040d002008103221070c010b200a28020020042008103421070b2007450dcf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41323a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dda012004410174220b20072007200b491b220b4100480dda010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dd101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dda0120044101742209200620062009491b22094100480dda010240024020040d002009103221060c010b200a28020020042009103421060b2006450dd2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8e010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd80120044101742208200720072008491b22084100480dd8010240024020040d002008103221070c010b200a28020020042008103421070b2007450dd10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41333a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd9012004410174220b20072007200b491b220b4100480dd9010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dd301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd90120044101742209200620062009491b22094100480dd9010240024020040d002009103221060c010b200a28020020042009103421060b2006450dd4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8d010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd70120044101742208200720072008491b22084100480dd7010240024020040d002008103221070c010b200a28020020042008103421070b2007450dd30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41343a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd8012004410174220b20072007200b491b220b4100480dd8010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dd501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd80120044101742209200620062009491b22094100480dd8010240024020040d002009103221060c010b200a28020020042009103421060b2006450dd6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8c010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd60120044101742208200720072008491b22084100480dd6010240024020040d002008103221070c010b200a28020020042008103421070b2007450dd50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41353a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da3022004410174220b20072007200b491b220b4100480da3020240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dd801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da30220044101742209200620062009491b22094100480da3020240024020040d002009103221060c010b200a28020020042009103421060b2006450dd9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8b010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da10220044101742208200720072008491b22084100480da1020240024020040d002008103221070c010b200a28020020042008103421070b2007450dd80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41363a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da2022004410174220b20072007200b491b220b4100480da2020240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dda01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da20220044101742209200620062009491b22094100480da2020240024020040d002009103221060c010b200a28020020042009103421060b2006450ddb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8a010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da00220044101742208200720072008491b22084100480da0020240024020040d002008103221070c010b200a28020020042008103421070b2007450dda0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41373a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da1022004410174220b20072007200b491b220b4100480da1020240024020040d00200b103221070c010b200a2802002004200b103421070b2007450ddc01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da10220044101742209200620062009491b22094100480da1020240024020040d002009103221060c010b200a28020020042009103421060b2006450ddd012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c89010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9f0220044101742208200720072008491b22084100480d9f020240024020040d002008103221070c010b200a28020020042008103421070b2007450ddc0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41383a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da0022004410174220b20072007200b491b220b4100480da0020240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dde01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da00220044101742209200620062009491b22094100480da0020240024020040d002009103221060c010b200a28020020042009103421060b2006450ddf012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c88010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9e0220044101742208200720072008491b22084100480d9e020240024020040d002008103221070c010b200a28020020042008103421070b2007450dde0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41393a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9f022004410174220b20072007200b491b220b4100480d9f020240024020040d00200b103221070c010b200a2802002004200b103421070b2007450de001200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9f0220044101742209200620062009491b22094100480d9f020240024020040d002009103221060c010b200a28020020042009103421060b2006450de1012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c87010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9d0220044101742208200720072008491b22084100480d9d020240024020040d002008103221070c010b200a28020020042008103421070b2007450de00120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9e022004410174220b20072007200b491b220b4100480d9e020240024020040d00200b103221070c010b200a2802002004200b103421070b2007450de201200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9e0220044101742209200620062009491b22094100480d9e020240024020040d002009103221060c010b200a28020020042009103421060b2006450de3012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c86010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9c0220044101742208200720072008491b22084100480d9c020240024020040d002008103221070c010b200a28020020042008103421070b2007450de20120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9d022004410174220b20072007200b491b220b4100480d9d020240024020040d00200b103221070c010b200a2802002004200b103421070b2007450de401200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9d0220044101742209200620062009491b22094100480d9d020240024020040d002009103221060c010b200a28020020042009103421060b2006450de5012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c85010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9b0220044101742208200720072008491b22084100480d9b020240024020040d002008103221070c010b200a28020020042008103421070b2007450de40120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9c022004410174220b20072007200b491b220b4100480d9c020240024020040d00200b103221070c010b200a2802002004200b103421070b2007450de601200220073602042009200b360200200828020021040b2008200441016a360200200720046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021050c010b200441016a22052004490d9c0220044101742209200520052009491b22094100480d9c020240024020040d002009103221050c010b200a28020020042009103421050b2005450de7012002200536020420082009360200200728020021040b2007200441016a360200200520046a200641807f72200641ff0071200641077622041b3a00002004210620040d000c84010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9a0220044101742208200720072008491b22084100480d9a020240024020040d002008103221070c010b200a28020020042008103421070b2007450de60120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9b022004410174220b20072007200b491b220b4100480d9b020240024020040d00200b103221070c010b200a2802002004200b103421070b2007450de801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9b0220044101742209200620062009491b22094100480d9b020240024020040d002009103221060c010b200a28020020042009103421060b2006450de9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c83010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d990220044101742208200720072008491b22084100480d99020240024020040d002008103221070c010b200a28020020042008103421070b2007450de80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9a022004410174220b20072007200b491b220b4100480d9a020240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dea01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9a0220044101742209200620062009491b22094100480d9a020240024020040d002009103221060c010b200a28020020042009103421060b2006450deb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c82010b0b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d980220044101742208200520052008491b22084100480d98020240024020040d002008103221050c010b200628020020042008103421050b2005450dea0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a413f3a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d980220044101742208200520052008491b22084100480d98020240024020040d002008103221050c010b200628020020042008103421050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c80010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d970220044101742208200520052008491b22084100480d97020240024020040d002008103221050c010b200628020020042008103421050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c0003a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d970220044101742208200520052008491b22084100480d97020240024020040d002008103221050c010b200628020020042008103421050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c7f0b200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d960220044101742207200520052007491b22074100480d96020240024020040d002007103221050c010b200228020420042007103421050b2005450dec0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c1003a000020032006200210aa042003210220032d0000411a470df0020c7e0b200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d950220044101742206200520052006491b22064100480d95020240024020040d002006103221050c010b200228020420042006103421050b2005450dec0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c2003a00002003200c200210ab042003210220032d0000411a470def020c7d0b200241046a2106200141046a280200210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d940220044101742208200520052008491b22084100480d94020240024020040d002008103221050c010b200628020020042008103421050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c3003a000002400240200241086a2802002205200828020022046b4104490d00200628020021050c010b200441046a22082004490d940220054101742204200820082004491b22044100480d94020240024020050d002004103221050c010b200628020020052004103421050b2005450ded0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441046a360200200520046a20073600000c7c0b200241046a2106200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d930220044101742207200520052007491b22074100480d93020240024020040d002007103221050c010b200628020020042007103421050b2005450ded0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200520046a41c4003a000002400240200241086a2802002205200728020022046b4108490d00200628020021050c010b200441086a22072004490d930220054101742204200720072004491b22044100480d93020240024020050d002004103221050c010b200628020020052004103421050b2005450dee0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441086a360200200520046a200c3700000c7b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d920220044101742206200520052006491b22064100480d92020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c5003a00000c7a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d910220044101742206200520052006491b22064100480d91020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c6003a00000c790b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d900220044101742206200520052006491b22064100480d90020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c7003a00000c780b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f0220044101742206200520052006491b22064100480d8f020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c8003a00000c770b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e0220044101742206200520052006491b22064100480d8e020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c9003a00000c760b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d0220044101742206200520052006491b22064100480d8d020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ca003a00000c750b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c0220044101742206200520052006491b22064100480d8c020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cb003a00000c740b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b0220044101742206200520052006491b22064100480d8b020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cc003a00000c730b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a0220044101742206200520052006491b22064100480d8a020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cd003a00000c720b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d890220044101742206200520052006491b22064100480d89020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ce003a00000c710b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d880220044101742206200520052006491b22064100480d88020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cf003a00000c700b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d870220044101742206200520052006491b22064100480d87020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d0003a00000c6f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d860220044101742206200520052006491b22064100480d86020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d1003a00000c6e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d850220044101742206200520052006491b22064100480d85020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d2003a00000c6d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d840220044101742206200520052006491b22064100480d84020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d3003a00000c6c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d830220044101742206200520052006491b22064100480d83020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d4003a00000c6b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d820220044101742206200520052006491b22064100480d82020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d5003a00000c6a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d810220044101742206200520052006491b22064100480d81020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d6003a00000c690b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d800220044101742206200520052006491b22064100480d80020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d7003a00000c680b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff0120044101742206200520052006491b22064100480dff010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d8003a00000c670b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe0120044101742206200520052006491b22064100480dfe010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d9003a00000c660b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd0120044101742206200520052006491b22064100480dfd010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41da003a00000c650b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41db003a00000c640b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dc003a00000c630b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dd003a00000c620b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41de003a00000c610b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41df003a00000c600b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e0003a00000c5f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e1003a00000c5e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e2003a00000c5d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e3003a00000c5c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e4003a00000c5b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e5003a00000c5a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e6003a00000c590b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df00120044101742206200520052006491b22064100480df0010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e7003a00000c580b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490def0120044101742206200520052006491b22064100480def010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e8003a00000c570b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dba0220044101742206200520052006491b22064100480dba020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e9003a00000c560b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db90220044101742206200520052006491b22064100480db9020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ea003a00000c550b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db80220044101742206200520052006491b22064100480db8020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41eb003a00000c540b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db70220044101742206200520052006491b22064100480db7020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ec003a00000c530b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db60220044101742206200520052006491b22064100480db6020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ed003a00000c520b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db50220044101742206200520052006491b22064100480db5020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ee003a00000c510b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db40220044101742206200520052006491b22064100480db4020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ef003a00000c500b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db30220044101742206200520052006491b22064100480db3020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f0003a00000c4f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db20220044101742206200520052006491b22064100480db2020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f1003a00000c4e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db10220044101742206200520052006491b22064100480db1020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f2003a00000c4d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db00220044101742206200520052006491b22064100480db0020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f3003a00000c4c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daf0220044101742206200520052006491b22064100480daf020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f4003a00000c4b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dae0220044101742206200520052006491b22064100480dae020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f5003a00000c4a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dad0220044101742206200520052006491b22064100480dad020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f6003a00000c490b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dac0220044101742206200520052006491b22064100480dac020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f7003a00000c480b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dab0220044101742206200520052006491b22064100480dab020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f8003a00000c470b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daa0220044101742206200520052006491b22064100480daa020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f9003a00000c460b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da90220044101742206200520052006491b22064100480da9020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fa003a00000c450b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da80220044101742206200520052006491b22064100480da8020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fb003a00000c440b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da70220044101742206200520052006491b22064100480da7020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fc003a00000c430b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da60220044101742206200520052006491b22064100480da6020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fd003a00000c420b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da50220044101742206200520052006491b22064100480da5020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fe003a00000c410b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da40220044101742206200520052006491b22064100480da4020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ff003a00000c400b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da30220044101742206200520052006491b22064100480da3020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4180013a00000c3f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da20220044101742206200520052006491b22064100480da2020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4181013a00000c3e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da10220044101742206200520052006491b22064100480da1020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4182013a00000c3d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da00220044101742206200520052006491b22064100480da0020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4183013a00000c3c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9f0220044101742206200520052006491b22064100480d9f020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4184013a00000c3b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9e0220044101742206200520052006491b22064100480d9e020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4185013a00000c3a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9d0220044101742206200520052006491b22064100480d9d020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4186013a00000c390b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9c0220044101742206200520052006491b22064100480d9c020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4187013a00000c380b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9b0220044101742206200520052006491b22064100480d9b020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4188013a00000c370b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9a0220044101742206200520052006491b22064100480d9a020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4189013a00000c360b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d990220044101742206200520052006491b22064100480d99020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418a013a00000c350b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d980220044101742206200520052006491b22064100480d98020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418b013a00000c340b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d970220044101742206200520052006491b22064100480d97020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418c013a00000c330b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d960220044101742206200520052006491b22064100480d96020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418d013a00000c320b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d950220044101742206200520052006491b22064100480d95020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418e013a00000c310b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d940220044101742206200520052006491b22064100480d94020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418f013a00000c300b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d930220044101742206200520052006491b22064100480d93020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4190013a00000c2f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d920220044101742206200520052006491b22064100480d92020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4191013a00000c2e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d910220044101742206200520052006491b22064100480d91020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4192013a00000c2d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d900220044101742206200520052006491b22064100480d90020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4193013a00000c2c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f0220044101742206200520052006491b22064100480d8f020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4194013a00000c2b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e0220044101742206200520052006491b22064100480d8e020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4195013a00000c2a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d0220044101742206200520052006491b22064100480d8d020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4196013a00000c290b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c0220044101742206200520052006491b22064100480d8c020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4197013a00000c280b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b0220044101742206200520052006491b22064100480d8b020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4198013a00000c270b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a0220044101742206200520052006491b22064100480d8a020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4199013a00000c260b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d890220044101742206200520052006491b22064100480d89020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419a013a00000c250b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d880220044101742206200520052006491b22064100480d88020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419b013a00000c240b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d870220044101742206200520052006491b22064100480d87020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419c013a00000c230b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d860220044101742206200520052006491b22064100480d86020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419d013a00000c220b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d850220044101742206200520052006491b22064100480d85020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419e013a00000c210b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d840220044101742206200520052006491b22064100480d84020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419f013a00000c200b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d830220044101742206200520052006491b22064100480d83020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a0013a00000c1f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d820220044101742206200520052006491b22064100480d82020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a1013a00000c1e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d810220044101742206200520052006491b22064100480d81020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a2013a00000c1d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d800220044101742206200520052006491b22064100480d80020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a3013a00000c1c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff0120044101742206200520052006491b22064100480dff010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a4013a00000c1b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe0120044101742206200520052006491b22064100480dfe010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a5013a00000c1a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd0120044101742206200520052006491b22064100480dfd010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a6013a00000c190b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a7013a00000c180b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a8013a00000c170b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a9013a00000c160b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41aa013a00000c150b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ab013a00000c140b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ac013a00000c130b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ad013a00000c120b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ae013a00000c110b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41af013a00000c100b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b0013a00000c0f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b1013a00000c0e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b2013a00000c0d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df00120044101742206200520052006491b22064100480df0010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b3013a00000c0c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b4013a00000c0b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b5013a00000c0a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b6013a00000c090b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b7013a00000c080b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b8013a00000c070b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b9013a00000c060b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ba013a00000c050b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bb013a00000c040b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bc013a00000c030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bd013a00000c020b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41be013a00000c010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bf013a00000b2000411a3a000020012d00004109470df201200141086a28020041ffffffff0371450df201200141046a28020010290cf2010b20064101102e000b20064101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20064101102e000b20064101102e000b20074101102e000b200a4101102e000b20074101102e000b200a4101102e000b20064101102e000b20084101102e000b20064101102e000b20074101102e000b200a4101102e000b20074101102e000b200a4101102e000b20064101102e000b20064101102e000b20064101102e000b20074101102e000b200a4101102e000b20074101102e000b200a4101102e000b20074101102e000b200a4101102e000b20074101102e000b200a4101102e000b20074101102e000b200a4101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b1033000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20074101102e000b20064101102e000b20084101102e000b20044101102e000b20074101102e000b20044101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b1033000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b1033000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b1033000b20002003290300370200200041086a200341086a290300370200200941ffffffff0371450d01200b10290c010b20002002290200370200200041086a200241086a29020037020020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200341106a24000bb60301057f2004410c6a2105200441086a2106024002400240034002400240200628020020052802002207460d00200428020421080c010b200741016a22082007490d0420074101742209200820082009491b22094100480d040240024020070d002009103221080c010b200428020420072009103421080b2008450d022004200836020420062009360200200528020021070b2005200741016a360200200820076a200141807f72200141ff0071200141077622071b3a00002007210120070d000b024020022003460d002004410c6a2105200441086a2106034020022802002101034002400240200628020020052802002207460d00200428020421080c010b200741016a22082007490d0620074101742209200820082009491b22094100480d060240024020070d002009103221080c010b200428020420072009103421080b2008450d052004200836020420062009360200200528020021070b2005200741016a360200200820076a200141807f72200141ff0071200141077622071b3a00002007210120070d000b200241046a22022003470d000b0b2000411a3a00000f0b20094101102e000b20094101102e000b1033000baf0301067f024002400240024020014107752203200141c00071220472452003417f4720044572460d002002410c6a2105200241086a2106034002400240200628020020052802002204460d00200228020421070c010b200441016a22072004490d0520044101742208200720072008491b22084100480d050240024020040d002008103221070c010b200228020420042008103421070b2007450d032002200736020420062008360200200528020021040b2005200441016a360200200720046a200141807f723a0000200341c000712104200321012003410775220721032007200472452007417f4720044572470d000b0b02400240200241086a2802002002410c6a2802002204460d00200228020421030c010b200441016a22032004490d0320044101742207200320032007491b22074100480d030240024020040d002007103221030c010b200228020420042007103421030b2003450d0220022003360204200241086a20073602002002410c6a28020021040b2002410c6a200441016a360200200320046a200141ff00713a00002000411a3a00000f0b20084101102e000b20074101102e000b1033000bb30302017e067f024002400240024020014207872203502001a7220441c00071452205712003427f52200572460d002002410c6a2106200241086a2107034002400240200728020020062802002205460d00200228020421080c010b200541016a22082005490d0520054101742209200820082009491b22094100480d050240024020050d002009103221080c010b200228020420052009103421080b2008450d032002200836020420072009360200200628020021050b2006200541016a360200200820056a200441807f723a00002003a72104200342078722012103200150200441c00071452205712001427f52200572470d000b0b02400240200241086a2802002002410c6a2802002205460d00200228020421080c010b200541016a22082005490d0320054101742206200820082006491b22064100480d030240024020050d002006103221080c010b200228020420052006103421080b2008450d0220022008360204200241086a20063602002002410c6a28020021050b2002410c6a200541016a360200200820056a200441ff00713a00002000411a3a00000f0b20094101102e000b20064101102e000b1033000bcf03010a7f230041306b22022400200241216a220341076a210441002105410021064100210741002108410821090240024002400340200241186a200110ad04024020022802184101470d002000200229021c370204200041013602002000410c6a200241186a410c6a29020037020002402007450d00200921070340024020072d00004109470d00200741086a28020041ffffffff0371450d00200741046a28020010290b200741106a2107200641706a22060d000b0b2008450d04200910290c040b200220032900003703082002200429000037000f20022d0020210a2002200229000f37001f200220022903083703180240024020072008470d00200741016a220b2007490d032005200b200b2005491b220841ffffffff00712008470d032008410474220b4100480d030240024020070d00200b103221090c010b20092006200b103421090b2009450d010b200920066a220b200a3a0000200b41016a2002290318370000200b41086a200229001f370000200541026a2105200641106a2106200741016a2107200a41ff01714106460d030c010b0b200b4108102e000b1033000b20002009360204200041003602002000410c6a2007360200200041086a20083602000b200241306a24000beab601020b7f017e230041f0006b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802082203200128020c2204460d00200441016a22052004490d02200320054f0d0120052003108f01000b200241013a0048200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a10af04200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c630b2001280200220620046a2d000021072001410c6a2208200536020002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200741bf014b0d0020070ec001b902b902010203b90200000000000405060708090a00000000000000000b0c000000000d0e0f101100000012131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901b9020b2000410b3a000420004101360200200041056a20073a00000cbb020b024002400240024002400240024020032005460d00200441026a21092005417f460de00120032009490da302200620056a2c00002101200820093602004100210a0240200141004e0d00411821090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410221070cbf020b20090e0404030506040b200241013a0047200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a10af04200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cbe020b4102210a410221070cba020b4103210a410221070cb9020b4101210a0b410221070cb7020b024002400240024002400240024020032005460d00200441026a21092005417f460de00120032009490da302200620056a2c00002101200820093602004100210a0240200141004e0d00411821090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410321070cbe020b20090e0404030506040b200241013a0047200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a10af04200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cbd020b4102210a410321070cb9020b4103210a410321070cb8020b4101210a0b410321070cb6020b024002400240024002400240024020032005460d00200441026a21092005417f460de00120032009490da302200620056a2c00002101200820093602004100210a0240200141004e0d00411821090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410421070cbd020b20090e0404030506040b200241013a0047200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a10af04200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cbc020b4102210a410421070cb8020b4103210a410421070cb7020b4101210a0b410421070cb5020b410621070cb4020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddd012003200541016a22074f0d01200541016a2003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb7020b410721070cb3020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddd012003200541016a22074f0d01200541016a2003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb6020b410821070cb2020b200241d8006a200110b00441042109200228025822064101460da201200241e0006a280200210b4100210a200228025c210c02400240200241e4006a280200220541027422030d00410021070c010b2003410275220741ffffffff03712007470dda01200741027422044100480dda01200410322209450dd9010b02402005450d00200541027421042003417c6a210a20092105200c2103034020052003280200360200200541046a2105200341046a21032004417c6a22040d000b200a41027641016a210a0b0240200b450d00200c10290b20022d005c4105470db0022006450db00220022802640da3010cb0020b410a21070cb0020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddd012003200541016a22074f0d01200541016a2003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb3020b410b21070caf020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddd012003200541016a22044f0d01200541016a2003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010c020b200620056a2d0000210720082004360200200741ff00712001411f71742009722109200141076a2101200421052007418001710d000b20014120490d01410d210120074110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cb2020b0240024020032004460d00200441016a22012004490ddb01200320014f0d0120012003108f01000b200241013a0048200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a10af04200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000cb2020b200620046a2d0000210520082001360200024020050d00410c21074100210a0caf020b200041163a000420004101360200200041056a20053a00000cb1020b410d21070cad020b410e21070cac020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddc012003200541016a22074f0d01200541016a2003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000caf020b410f21070cab020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddc012003200541016a22074f0d01200541016a2003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cae020b411021070caa020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddc012003200541016a22074f0d01200541016a2003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cad020b411121070ca9020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddc012003200541016a22074f0d01200541016a2003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cac020b411221070ca8020b410021014100210902400240034002402001411f4d0d00410f21010c020b0240024020032005460d002005417f460ddc012003200541016a22074f0d01200541016a2003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010c020b200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b20014120490d01410d210120044110490d010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000cab020b411321070ca7020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ddd01200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000caa020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9c010b20032001460d9a012001417f460dd9012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9b010b200aad210d411421070ca6020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dde01200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca9020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9d010b20032001460d9b012001417f460dda012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9c010b200aad210d411521070ca5020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ddf01200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca8020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9e010b20032001460d9c012001417f460ddb012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9d010b200aad210d411621070ca4020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de001200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca7020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c9f010b20032001460d9d012001417f460ddc012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9e010b200aad210d411721070ca3020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de101200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca6020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca0010b20032001460d9e012001417f460ddd012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d9f010b200aad210d411821070ca2020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de201200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca5020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca1010b20032001460d9f012001417f460dde012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da0010b200aad210d411921070ca1020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de301200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca4020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca2010b20032001460da0012001417f460ddf012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da1010b200aad210d411a21070ca0020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de401200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca3020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca3010b20032001460da1012001417f460de0012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da2010b200aad210d411b21070c9f020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de501200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca2020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca4010b20032001460da2012001417f460de1012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da3010b200aad210d411c21070c9e020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de601200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca1020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca5010b20032001460da3012001417f460de2012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da4010b200aad210d411d21070c9d020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de701200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000ca0020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca6010b20032001460da4012001417f460de3012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da5010b200aad210d411e21070c9c020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de801200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9f020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca7010b20032001460da5012001417f460de4012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da6010b200aad210d411f21070c9b020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450de901200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9e020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca8010b20032001460da6012001417f460de5012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b41202107024020054120490d00410d21012004410f4b0da7010b200aad210d0c9a020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dea01200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9d020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010ca9010b20032001460da7012001417f460de6012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da8010b200aad210d412121070c99020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450deb01200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010caa010b20032001460da8012001417f460de7012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0da9010b200aad210d412221070c98020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dec01200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9b020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cab010b20032001460da9012001417f460de8012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0daa010b200aad210d412321070c97020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450ded01200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9a020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cac010b20032001460daa012001417f460de9012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dab010b200aad210d412421070c96020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450dee01200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c99020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cad010b20032001460dab012001417f460dea012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dac010b200aad210d412521070c95020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450def01200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c98020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cae010b20032001460dac012001417f460deb012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dad010b200aad210d412621070c94020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450df001200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c97020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010caf010b20032001460dad012001417f460dec012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0dae010b200aad210d412721070c93020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450df101200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c96020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cb0010b20032001460dae012001417f460ded012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0daf010b200aad210d412821070c92020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450df201200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c95020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cb1010b20032001460daf012001417f460dee012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0db0010b200aad210d412921070c91020b410120036b2107200441026a21014100210541002109024002400240034002402005411f4d0d00410f21010c020b02400240200720016a4102460d002001450df301200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420022802282109200228022c210520022802302103410521010c030b200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b20054120490d0220044110490d02410d21010b0b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c94020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010cb2010b20032001460db0012001417f460def012003200141016a2207490d8f02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0db1010b200aad210d412a21070c90020b0240024020032005460d00200441026a21012005417f460df001200320014f0d0120012003108f01000b200241013a0048200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a10af04200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c93020b200620056a2d0000210920082001360200024020090d00412b21074100210a0c90020b200041153a000420004101360200200041056a20093a00000c92020b0240024020032005460d00200441026a21012005417f460df001200320014f0d0120012003108f01000b200241013a0048200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a10af04200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c92020b200620056a2d0000210920082001360200024020090d00412c21074100210a0c8f020b200041153a000420004101360200200041056a20093a00000c91020b41002101410021090240024002400340410d210a2001411f4b0d010240024020032005460d002005417f460df4012003200541016a22074f0d01200541016a2003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af044105210a0c020b200620056a2c0000210420082007360200200441ff00712001411f71742009722109200141076a21012007210520044100480d000b200441c00071210502402001411f4b0d0020050d020b0240024020014120490d0020050d010b200441ff01714108490d0320014120490d032005450d010c030b20044180017241ff017141f7014b0d020b2000200a36020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c92020b2009417f2001411f71747221090b412d21070c8d020b4200210d4100210102400240024002400340410e21072001413f4b0d010240024020032005460d002005417f460df5012003200541016a22094f0d01200541016a2003108f01000b200241013a0008200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241086a360238200241286a200241d8006a10af042002290328210d20022802302101410521070c030b200620056a2d0000210420082009360200200441ff0071220aad2001413f71ad86200d84210d200141076a210120092105200441187441187522094100480d000b200941c00071210502402001413f4b0d0020050d030b02400240200141c000490d0020050d010b200141c000490d0420090d010c040b200a41ff00460d030b0b200020073a0004200020022f00183b000520004101360200200041106a2001360200200041086a200d370200200041076a2002411a6a2d00003a00000c91020b200d427f2001413f71ad8684210d0b412e21070c8c020b02400240200320056b4104490d00200441056a21012005417b4b0df001200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af0420004281808080d000370300200041086a2002290228370200200041106a200241286a41086a2802003602000c8f020b200620056a280000210920082001360200412f21070c8b020b02400240200320056b4108490d00200441096a2101200541774b0df001200320014f0d0120012003108f01000b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af042002290328210d200041106a2002280230360200200041086a200d37020020004281808080d0003703000c8e020b200620056a290000210d20082001360200413021070c8a020b413121070c89020b413221070c88020b413321070c87020b413421070c86020b413521070c85020b413621070c84020b413721070c83020b413821070c82020b413921070c81020b413a21070c80020b413b21070cff010b413c21070cfe010b413d21070cfd010b413e21070cfc010b413f21070cfb010b41c00021070cfa010b41c10021070cf9010b41c20021070cf8010b41c30021070cf7010b41c40021070cf6010b41c50021070cf5010b41c60021070cf4010b41c70021070cf3010b41c80021070cf2010b41c90021070cf1010b41ca0021070cf0010b41cb0021070cef010b41cc0021070cee010b41cd0021070ced010b41ce0021070cec010b41cf0021070ceb010b41d00021070cea010b41d10021070ce9010b41d20021070ce8010b41d30021070ce7010b41d40021070ce6010b41d50021070ce5010b41d60021070ce4010b41d70021070ce3010b41d80021070ce2010b41d90021070ce1010b41da0021070ce0010b41db0021070cdf010b41dc0021070cde010b41dd0021070cdd010b41de0021070cdc010b41df0021070cdb010b41e00021070cda010b41e10021070cd9010b41e20021070cd8010b41e30021070cd7010b41e40021070cd6010b41e50021070cd5010b41e60021070cd4010b41e70021070cd3010b41e80021070cd2010b41e90021070cd1010b41ea0021070cd0010b41eb0021070ccf010b41ec0021070cce010b41ed0021070ccd010b41ee0021070ccc010b41ef0021070ccb010b41f00021070cca010b41f10021070cc9010b41f20021070cc8010b41f30021070cc7010b41f40021070cc6010b41f50021070cc5010b41f60021070cc4010b41f70021070cc3010b41f80021070cc2010b41f90021070cc1010b41fa0021070cc0010b41fb0021070cbf010b41fc0021070cbe010b41fd0021070cbd010b41fe0021070cbc010b41ff0021070cbb010b41800121070cba010b41810121070cb9010b41820121070cb8010b41830121070cb7010b41840121070cb6010b41850121070cb5010b41860121070cb4010b41870121070cb3010b41880121070cb2010b41890121070cb1010b418a0121070cb0010b418b0121070caf010b418c0121070cae010b418d0121070cad010b418e0121070cac010b418f0121070cab010b41900121070caa010b41910121070ca9010b41920121070ca8010b41930121070ca7010b41940121070ca6010b41950121070ca5010b41960121070ca4010b41970121070ca3010b41980121070ca2010b41990121070ca1010b419a0121070ca0010b419b0121070c9f010b419c0121070c9e010b419d0121070c9d010b419e0121070c9c010b419f0121070c9b010b41a00121070c9a010b41a10121070c99010b41a20121070c98010b41a30121070c97010b41a40121070c96010b41a50121070c95010b41a60121070c94010b41a70121070c93010b41a80121070c92010b41a90121070c91010b41aa0121070c90010b41ab0121070c8f010b200041013602002000200241d8006a41047222012902003702042000410c6a200141086a2902003702000c91010b200228026010290c8c010b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c8e010b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c8c010b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c8a010b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c88010b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c86010b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c84010b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c82010b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c80010b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c7e0b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c7c0b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c7a0b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c780b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c760b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c740b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c720b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c700b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c6e0b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c6c0b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c6a0b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c680b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c660b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c640b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a2802003602000c620b417f20051030000b417f20091030000b417f20091030000b417f20091030000b417f200541016a1030000b417f200541016a1030000b20044104102e000b1033000b417f200541016a1030000b417f200541016a1030000b417f20011030000b417f200541016a1030000b417f200541016a1030000b417f200541016a1030000b417f200541016a1030000b417f200541016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f200141016a1030000b417f20011030000b417f20011030000b417f200541016a1030000b417f200541016a1030000b200520011030000b200520011030000b20092003108f01000b20092003108f01000b20092003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b200141016a2003108f01000b024002400240024002402007200a460d002007200a490d010240200a0d00024020070d00410421090c020b20091029410421090c010b20092007410274200a410274220510342209450d020b4100210541002107034002402005411f4d0d00410f21010c080b20012802082206200128020c2203460d06200341016a22042003490d0320062004490d04200128020020036a2d0000210320082004360200200341ff00712005411f71742007722107200541076a21052003418001710d000b024020054120490d00410d21012003410f4b0d070b2007ad422086200aad84210d410921070c040b41e4aec500106d000b20054104102e000b417f20041030000b20042006108f01000b20004100360200200041106a200d3703002000410c6a2009360200200041096a200a3a0000200041086a20073a00000c020b200241013a0018200241ec006a41013602002002420137025c200241d8e7c5003602582002412136023c2002200241386a3602682002200241186a360238200241286a200241d8006a10af04410521010b2000200136020420004101360200200041086a2002290228370200200041106a200241286a41086a280200360200200a41ffffffff0371450d00200910290b200241f0006a24000bd30101017f230041106b22022400024002400240024020002d00000e03010200010b2002200128021841b4e7c500410b2001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c020b2002200128021841bfe7c500410c2001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c010b2002200128021841cbe7c500410d2001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040b200241106a240020000b880301067f230041306b2202240020012802002103024002402001280204220441037422050d00410021060c010b200341046a2107410021060340200728020020066a2106200741086a2107200541786a22050d000b0b024002400240024002400240200141146a2802000d00200621070c010b024020040d00418cfbc500410041001036000b024002402006410f4b0d002003280204450d010b200620066a220720064f0d010b4101210541002107200241086a21060c010b2007417f4c0d01200241086a2106024020070d0041012105410021070c010b200710322205450d020b200241003602102002200736020c200220053602082002200241086a360214200241186a41106a200141106a290200370300200241186a41086a200141086a29020037030020022001290200370318200241146a419cfbc500200241186a10d8040d0220002006290200370200200041086a200641086a280200360200200241306a24000f0b102f000b20074101102e000b41b4fbc5004133200241186a41e8fbc5001054000bda0703067f017e067f230041d0006b220224004100210341002104024002400240024002400240024002400240024002400240034002402003411f4d0d00410f21030c020b0240024020012802082205200128020c2206460d00200641016a22072006490d05200520074f0d0120072005108f01000b200241013a0027200241cc006a41013602002002420137023c200241d8e7c5003602382002412136021c2002200241186a3602482002200241276a360218200241286a200241386a10af04410521030c020b200128020020066a2d000021062001200736020c200641ff00712003411f71742004722104200341076a21032006418001710d000b20034120490d01410d210320064110490d010b200241086a41086a200241286a41086a280200220136020020022002290228220837030820002003360204200041086a2008370200200041106a2001360200200041013602000c0a0b20024100360210200242043703082004450d0841042109410021034100210a03402003210b200a220c41016a210a410021034100210503402003411f4b0d04024002402001280208220d200128020c2206460d00200641016a22072006490d05200d20074f0d012007200d108f01000b2002200b36020c2002200c360210200241013a0027200241cc006a41013602002002420137023c200241d8e7c5003602382002412136021c2002200241186a3602482002200241276a360218200241286a200241386a10af0420022802282103200228022c2106200228023021074100210e410521010c090b200128020020066a2d000021062001200736020c200641ff00712003411f71742005722105200341076a21032006418001710d000b024020034120490d002006410f4d0d002002200b36020c2002200c360210410d21010c070b02400240200c200b460d00200b2103200c210b0c010b200b41016a2203200b490d06200b4101742206200320032006491b220341ffffffff03712003470d06200341027422064100480d0602400240200b0d002006103221090c010b2009200b4102742006103421090b2009450d05200220093602080b2005410876210e2009200b4102746a2005360200200a2004460d080c000b0b417f20071030000b417f20071030000b2002200b36020c2002200c360210410f21010c020b20064104102e000b1033000b0b20004101360200200041106a20073602002000410c6a2006360200200041086a20033602002000200e410874200172360204200b450d02200910290c020b2002200336020c2002200a3602100b20002002290308370204200041003602002000410c6a200241106a2802003602000b200241d0006a24000bf6d60202097f017e230041106b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000eac01000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab01000b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006103221050c010b200228020420042006103421050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41003a00000cab010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006103221050c010b200228020420042006103421050b2005450dad0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41013a00000caa010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df50120044101742208200520052008491b22084100480df5010240024020040d002008103221050c010b200628020020042008103421050b2005450dad0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41023a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df50120044101742208200520052008491b22084100480df5010240024020040d002008103221050c010b200628020020042008103421050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca9010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df40120044101742208200520052008491b22084100480df4010240024020040d002008103221050c010b200628020020042008103421050b2005450dae0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41033a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df40120044101742208200520052008491b22084100480df4010240024020040d002008103221050c010b200628020020042008103421050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca8010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490df30120044101742208200520052008491b22084100480df3010240024020040d002008103221050c010b200628020020042008103421050b2005450daf0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41043a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490df30120044101742208200520052008491b22084100480df3010240024020040d002008103221050c010b200628020020042008103421050b2005450db00120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00000ca7010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006103221050c010b200228020420042006103421050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41053a00000ca6010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006103221050c010b200228020420042006103421050b2005450db00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410b3a00000ca5010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490df00120044101742207200620062007491b22074100480df0010240024020040d002007103221060c010b200928020020042007103421060b2006450db00120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410c3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df1012004410174220a20062006200a491b220a4100480df1010240024020040d00200a103221060c010b20092802002004200a103421060b2006450db201200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca5010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490def0120044101742207200620062007491b22074100480def010240024020040d002007103221060c010b200928020020042007103421060b2006450db10120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a410d3a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490df0012004410174220a20062006200a491b220a4100480df0010240024020040d00200a103221060c010b20092802002004200a103421060b2006450db301200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca4010b0b200241046a210a2001410c6a2802002104200141086a2802002109200141046a280200210b02400240200241086a2802002002410c6a2802002201460d00200a28020021050c010b200141016a22052001490dee0120014101742206200520052006491b22064100480dee010240024020010d002006103221050c010b200a28020020012006103421050b2005450db20120022005360204200241086a20063602002002410c6a28020021010b2002410c6a2206200141016a360200200520016a410e3a000020032009200b200b20094102746a200210a90420032d0000411a470d9303200241086a2107034002400240200728020020062802002201460d00200a28020021050c010b200141016a22052001490def0120014101742208200520052008491b22084100480def010240024020010d002008103221050c010b200a28020020012008103421050b2005450db4012002200536020420072008360200200628020021010b2006200141016a360200200520016a200441807f72200441ff0071200441077622011b3a00002001210420010d000b0240200941ffffffff0371450d00200b10290b2000411a3a00000c95030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490ded0120044101742206200520052006491b22064100480ded010240024020040d002006103221050c010b200228020420042006103421050b2005450db30120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a410f3a00000ca1010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490dec0120044101742207200620062007491b22074100480dec010240024020040d002007103221060c010b200928020020042007103421060b2006450db30120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41103a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490ded012004410174220a20062006200a491b220a4100480ded010240024020040d00200a103221060c010b20092802002004200a103421060b2006450db501200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000ca1010b0b200241046a2109200141046a280200210520012d0001210b02400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490deb0120044101742207200620062007491b22074100480deb010240024020040d002007103221060c010b200928020020042007103421060b2006450db40120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41113a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490dec012004410174220a20062006200a491b220a4100480dec010240024020040d00200a103221060c010b20092802002004200a103421060b2006450db601200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b02400240200241086a2802002002410c6a2802002204460d00200928020021050c010b200441016a22052004490deb0120044101742206200520052006491b22064100480deb010240024020040d002006103221050c010b200928020020042006103421050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a200b3a00000c9f010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dea0120044101742206200520052006491b22064100480dea010240024020040d002006103221050c010b200228020420042006103421050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411a3a00000c9e010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490de90120044101742206200520052006491b22064100480de9010240024020040d002006103221050c010b200228020420042006103421050b2005450db60120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a411b3a00000c9d010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de80120044101742207200620062007491b22074100480de8010240024020040d002007103221060c010b200928020020042007103421060b2006450db60120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41203a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de9012004410174220a20062006200a491b220a4100480de9010240024020040d00200a103221060c010b20092802002004200a103421060b2006450db801200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9d010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de70120044101742207200620062007491b22074100480de7010240024020040d002007103221060c010b200928020020042007103421060b2006450db70120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41213a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de8012004410174220a20062006200a491b220a4100480de8010240024020040d00200a103221060c010b20092802002004200a103421060b2006450db901200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9c010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de60120044101742207200620062007491b22074100480de6010240024020040d002007103221060c010b200928020020042007103421060b2006450db80120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41223a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de7012004410174220a20062006200a491b220a4100480de7010240024020040d00200a103221060c010b20092802002004200a103421060b2006450dba01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9b010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de50120044101742207200620062007491b22074100480de5010240024020040d002007103221060c010b200928020020042007103421060b2006450db90120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41233a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de6012004410174220a20062006200a491b220a4100480de6010240024020040d00200a103221060c010b20092802002004200a103421060b2006450dbb01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c9a010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490de40120044101742207200620062007491b22074100480de4010240024020040d002007103221060c010b200928020020042007103421060b2006450dba0120022006360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200620046a41243a0000200241086a2108034002400240200828020020072802002204460d00200928020021060c010b200441016a22062004490de5012004410174220a20062006200a491b220a4100480de5010240024020040d00200a103221060c010b20092802002004200a103421060b2006450dbc01200220063602042008200a360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c99010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de30120044101742208200720072008491b22084100480de3010240024020040d002008103221070c010b200a28020020042008103421070b2007450dbb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41283a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de4012004410174220b20072007200b491b220b4100480de4010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dbd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de40120044101742209200620062009491b22094100480de4010240024020040d002009103221060c010b200a28020020042009103421060b2006450dbe012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c98010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de20120044101742208200720072008491b22084100480de2010240024020040d002008103221070c010b200a28020020042008103421070b2007450dbd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41293a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de3012004410174220b20072007200b491b220b4100480de3010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dbf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de30120044101742209200620062009491b22094100480de3010240024020040d002009103221060c010b200a28020020042009103421060b2006450dc0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c97010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de10120044101742208200720072008491b22084100480de1010240024020040d002008103221070c010b200a28020020042008103421070b2007450dbf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de2012004410174220b20072007200b491b220b4100480de2010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dc101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de20120044101742209200620062009491b22094100480de2010240024020040d002009103221060c010b200a28020020042009103421060b2006450dc2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c96010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490de00120044101742208200720072008491b22084100480de0010240024020040d002008103221070c010b200a28020020042008103421070b2007450dc10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de1012004410174220b20072007200b491b220b4100480de1010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dc301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de10120044101742209200620062009491b22094100480de1010240024020040d002009103221060c010b200a28020020042009103421060b2006450dc4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c95010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddf0120044101742208200720072008491b22084100480ddf010240024020040d002008103221070c010b200a28020020042008103421070b2007450dc30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490de0012004410174220b20072007200b491b220b4100480de0010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dc501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490de00120044101742209200620062009491b22094100480de0010240024020040d002009103221060c010b200a28020020042009103421060b2006450dc6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c94010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dde0120044101742208200720072008491b22084100480dde010240024020040d002008103221070c010b200a28020020042008103421070b2007450dc50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddf012004410174220b20072007200b491b220b4100480ddf010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dc701200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddf0120044101742209200620062009491b22094100480ddf010240024020040d002009103221060c010b200a28020020042009103421060b2006450dc8012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c93010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddd0120044101742208200720072008491b22084100480ddd010240024020040d002008103221070c010b200a28020020042008103421070b2007450dc70120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dde012004410174220b20072007200b491b220b4100480dde010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dc901200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dde0120044101742209200620062009491b22094100480dde010240024020040d002009103221060c010b200a28020020042009103421060b2006450dca012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c92010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddc0120044101742208200720072008491b22084100480ddc010240024020040d002008103221070c010b200a28020020042008103421070b2007450dc90120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a412f3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddd012004410174220b20072007200b491b220b4100480ddd010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dcb01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddd0120044101742209200620062009491b22094100480ddd010240024020040d002009103221060c010b200a28020020042009103421060b2006450dcc012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c91010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490ddb0120044101742208200720072008491b22084100480ddb010240024020040d002008103221070c010b200a28020020042008103421070b2007450dcb0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41303a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddc012004410174220b20072007200b491b220b4100480ddc010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dcd01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddc0120044101742209200620062009491b22094100480ddc010240024020040d002009103221060c010b200a28020020042009103421060b2006450dce012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c90010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dda0120044101742208200720072008491b22084100480dda010240024020040d002008103221070c010b200a28020020042008103421070b2007450dcd0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41313a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490ddb012004410174220b20072007200b491b220b4100480ddb010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dcf01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490ddb0120044101742209200620062009491b22094100480ddb010240024020040d002009103221060c010b200a28020020042009103421060b2006450dd0012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8f010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd90120044101742208200720072008491b22084100480dd9010240024020040d002008103221070c010b200a28020020042008103421070b2007450dcf0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41323a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dda012004410174220b20072007200b491b220b4100480dda010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dd101200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dda0120044101742209200620062009491b22094100480dda010240024020040d002009103221060c010b200a28020020042009103421060b2006450dd2012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8e010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd80120044101742208200720072008491b22084100480dd8010240024020040d002008103221070c010b200a28020020042008103421070b2007450dd10120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41333a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd9012004410174220b20072007200b491b220b4100480dd9010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dd301200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd90120044101742209200620062009491b22094100480dd9010240024020040d002009103221060c010b200a28020020042009103421060b2006450dd4012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8d010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd70120044101742208200720072008491b22084100480dd7010240024020040d002008103221070c010b200a28020020042008103421070b2007450dd30120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41343a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490dd8012004410174220b20072007200b491b220b4100480dd8010240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dd501200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490dd80120044101742209200620062009491b22094100480dd8010240024020040d002009103221060c010b200a28020020042009103421060b2006450dd6012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8c010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490dd60120044101742208200720072008491b22084100480dd6010240024020040d002008103221070c010b200a28020020042008103421070b2007450dd50120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41353a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da3022004410174220b20072007200b491b220b4100480da3020240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dd801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da30220044101742209200620062009491b22094100480da3020240024020040d002009103221060c010b200a28020020042009103421060b2006450dd9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8b010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da10220044101742208200720072008491b22084100480da1020240024020040d002008103221070c010b200a28020020042008103421070b2007450dd80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41363a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da2022004410174220b20072007200b491b220b4100480da2020240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dda01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da20220044101742209200620062009491b22094100480da2020240024020040d002009103221060c010b200a28020020042009103421060b2006450ddb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c8a010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490da00220044101742208200720072008491b22084100480da0020240024020040d002008103221070c010b200a28020020042008103421070b2007450dda0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41373a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da1022004410174220b20072007200b491b220b4100480da1020240024020040d00200b103221070c010b200a2802002004200b103421070b2007450ddc01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da10220044101742209200620062009491b22094100480da1020240024020040d002009103221060c010b200a28020020042009103421060b2006450ddd012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c89010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9f0220044101742208200720072008491b22084100480d9f020240024020040d002008103221070c010b200a28020020042008103421070b2007450ddc0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41383a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490da0022004410174220b20072007200b491b220b4100480da0020240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dde01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490da00220044101742209200620062009491b22094100480da0020240024020040d002009103221060c010b200a28020020042009103421060b2006450ddf012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c88010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9e0220044101742208200720072008491b22084100480d9e020240024020040d002008103221070c010b200a28020020042008103421070b2007450dde0120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a41393a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9f022004410174220b20072007200b491b220b4100480d9f020240024020040d00200b103221070c010b200a2802002004200b103421070b2007450de001200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9f0220044101742209200620062009491b22094100480d9f020240024020040d002009103221060c010b200a28020020042009103421060b2006450de1012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c87010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9d0220044101742208200720072008491b22084100480d9d020240024020040d002008103221070c010b200a28020020042008103421070b2007450de00120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413a3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9e022004410174220b20072007200b491b220b4100480d9e020240024020040d00200b103221070c010b200a2802002004200b103421070b2007450de201200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9e0220044101742209200620062009491b22094100480d9e020240024020040d002009103221060c010b200a28020020042009103421060b2006450de3012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c86010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9c0220044101742208200720072008491b22084100480d9c020240024020040d002008103221070c010b200a28020020042008103421070b2007450de20120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413b3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9d022004410174220b20072007200b491b220b4100480d9d020240024020040d00200b103221070c010b200a2802002004200b103421070b2007450de401200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9d0220044101742209200620062009491b22094100480d9d020240024020040d002009103221060c010b200a28020020042009103421060b2006450de5012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c85010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9b0220044101742208200720072008491b22084100480d9b020240024020040d002008103221070c010b200a28020020042008103421070b2007450de40120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413c3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9c022004410174220b20072007200b491b220b4100480d9c020240024020040d00200b103221070c010b200a2802002004200b103421070b2007450de601200220073602042009200b360200200828020021040b2008200441016a360200200720046a200541807f72200541ff0071200541077622041b3a00002004210520040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021050c010b200441016a22052004490d9c0220044101742209200520052009491b22094100480d9c020240024020040d002009103221050c010b200a28020020042009103421050b2005450de7012002200536020420082009360200200728020021040b2007200441016a360200200520046a200641807f72200641ff0071200641077622041b3a00002004210620040d000c84010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9a0220044101742208200720072008491b22084100480d9a020240024020040d002008103221070c010b200a28020020042008103421070b2007450de60120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413d3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9b022004410174220b20072007200b491b220b4100480d9b020240024020040d00200b103221070c010b200a2802002004200b103421070b2007450de801200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9b0220044101742209200620062009491b22094100480d9b020240024020040d002009103221060c010b200a28020020042009103421060b2006450de9012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c83010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d990220044101742208200720072008491b22084100480d99020240024020040d002008103221070c010b200a28020020042008103421070b2007450de80120022007360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200720046a413e3a0000200241086a2109034002400240200928020020082802002204460d00200a28020021070c010b200441016a22072004490d9a022004410174220b20072007200b491b220b4100480d9a020240024020040d00200b103221070c010b200a2802002004200b103421070b2007450dea01200220073602042009200b360200200828020021040b2008200441016a360200200720046a200641807f72200641ff0071200641077622041b3a00002004210620040d000b2002410c6a2107200241086a2108034002400240200828020020072802002204460d00200a28020021060c010b200441016a22062004490d9a0220044101742209200620062009491b22094100480d9a020240024020040d002009103221060c010b200a28020020042009103421060b2006450deb012002200636020420082009360200200728020021040b2007200441016a360200200620046a200541807f72200541ff0071200541077622041b3a00002004210520040d000c82010b0b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d980220044101742208200520052008491b22084100480d98020240024020040d002008103221050c010b200628020020042008103421050b2005450dea0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a413f3a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d980220044101742208200520052008491b22084100480d98020240024020040d002008103221050c010b200628020020042008103421050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c80010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d970220044101742208200520052008491b22084100480d97020240024020040d002008103221050c010b200628020020042008103421050b2005450deb0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c0003a000002400240200241086a28020020082802002204460d00200628020021050c010b200441016a22052004490d970220044101742208200520052008491b22084100480d97020240024020040d002008103221050c010b200628020020042008103421050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a200441016a360200200520046a20073a00000c7f0b200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d960220044101742207200520052007491b22074100480d96020240024020040d002007103221050c010b200228020420042007103421050b2005450dec0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c1003a000020032006200210aa042003210220032d0000411a470df0020c7e0b200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d950220044101742206200520052006491b22064100480d95020240024020040d002006103221050c010b200228020420042006103421050b2005450dec0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c2003a00002003200c200210ab042003210220032d0000411a470def020c7d0b200241046a2106200141046a280200210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d940220044101742208200520052008491b22084100480d94020240024020040d002008103221050c010b200628020020042008103421050b2005450dec0120022005360204200241086a20083602002002410c6a28020021040b2002410c6a2208200441016a360200200520046a41c3003a000002400240200241086a2802002205200828020022046b4104490d00200628020021050c010b200441046a22082004490d940220054101742204200820082004491b22044100480d94020240024020050d002004103221050c010b200628020020052004103421050b2005450ded0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441046a360200200520046a20073600000c7c0b200241046a2106200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d930220044101742207200520052007491b22074100480d93020240024020040d002007103221050c010b200628020020042007103421050b2005450ded0120022005360204200241086a20073602002002410c6a28020021040b2002410c6a2207200441016a360200200520046a41c4003a000002400240200241086a2802002205200728020022046b4108490d00200628020021050c010b200441086a22072004490d930220054101742204200720072004491b22044100480d93020240024020050d002004103221050c010b200628020020052004103421050b2005450dee0120022005360204200241086a20043602002002410c6a28020021040b2002410c6a200441086a360200200520046a200c3700000c7b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d920220044101742206200520052006491b22064100480d92020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c5003a00000c7a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d910220044101742206200520052006491b22064100480d91020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c6003a00000c790b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d900220044101742206200520052006491b22064100480d90020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c7003a00000c780b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f0220044101742206200520052006491b22064100480d8f020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c8003a00000c770b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e0220044101742206200520052006491b22064100480d8e020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41c9003a00000c760b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d0220044101742206200520052006491b22064100480d8d020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ca003a00000c750b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c0220044101742206200520052006491b22064100480d8c020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cb003a00000c740b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b0220044101742206200520052006491b22064100480d8b020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cc003a00000c730b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a0220044101742206200520052006491b22064100480d8a020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cd003a00000c720b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d890220044101742206200520052006491b22064100480d89020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ce003a00000c710b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d880220044101742206200520052006491b22064100480d88020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41cf003a00000c700b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d870220044101742206200520052006491b22064100480d87020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d0003a00000c6f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d860220044101742206200520052006491b22064100480d86020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d1003a00000c6e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d850220044101742206200520052006491b22064100480d85020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d2003a00000c6d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d840220044101742206200520052006491b22064100480d84020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d3003a00000c6c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d830220044101742206200520052006491b22064100480d83020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d4003a00000c6b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d820220044101742206200520052006491b22064100480d82020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d5003a00000c6a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d810220044101742206200520052006491b22064100480d81020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d6003a00000c690b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d800220044101742206200520052006491b22064100480d80020240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d7003a00000c680b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff0120044101742206200520052006491b22064100480dff010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d8003a00000c670b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe0120044101742206200520052006491b22064100480dfe010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41d9003a00000c660b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd0120044101742206200520052006491b22064100480dfd010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41da003a00000c650b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41db003a00000c640b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dc003a00000c630b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41dd003a00000c620b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41de003a00000c610b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41df003a00000c600b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e0003a00000c5f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e1003a00000c5e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e2003a00000c5d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e3003a00000c5c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e4003a00000c5b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e5003a00000c5a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e6003a00000c590b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df00120044101742206200520052006491b22064100480df0010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e7003a00000c580b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490def0120044101742206200520052006491b22064100480def010240024020040d002006103221050c010b200228020420042006103421050b2005450dee0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e8003a00000c570b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dba0220044101742206200520052006491b22064100480dba020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41e9003a00000c560b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db90220044101742206200520052006491b22064100480db9020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ea003a00000c550b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db80220044101742206200520052006491b22064100480db8020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41eb003a00000c540b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db70220044101742206200520052006491b22064100480db7020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ec003a00000c530b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db60220044101742206200520052006491b22064100480db6020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ed003a00000c520b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db50220044101742206200520052006491b22064100480db5020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ee003a00000c510b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db40220044101742206200520052006491b22064100480db4020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ef003a00000c500b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db30220044101742206200520052006491b22064100480db3020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f0003a00000c4f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db20220044101742206200520052006491b22064100480db2020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f1003a00000c4e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db10220044101742206200520052006491b22064100480db1020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f2003a00000c4d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490db00220044101742206200520052006491b22064100480db0020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f3003a00000c4c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daf0220044101742206200520052006491b22064100480daf020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f4003a00000c4b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dae0220044101742206200520052006491b22064100480dae020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f5003a00000c4a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dad0220044101742206200520052006491b22064100480dad020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f6003a00000c490b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dac0220044101742206200520052006491b22064100480dac020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f7003a00000c480b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dab0220044101742206200520052006491b22064100480dab020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f8003a00000c470b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490daa0220044101742206200520052006491b22064100480daa020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41f9003a00000c460b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da90220044101742206200520052006491b22064100480da9020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fa003a00000c450b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da80220044101742206200520052006491b22064100480da8020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fb003a00000c440b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da70220044101742206200520052006491b22064100480da7020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fc003a00000c430b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da60220044101742206200520052006491b22064100480da6020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fd003a00000c420b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da50220044101742206200520052006491b22064100480da5020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41fe003a00000c410b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da40220044101742206200520052006491b22064100480da4020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ff003a00000c400b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da30220044101742206200520052006491b22064100480da3020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4180013a00000c3f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da20220044101742206200520052006491b22064100480da2020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4181013a00000c3e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da10220044101742206200520052006491b22064100480da1020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4182013a00000c3d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da00220044101742206200520052006491b22064100480da0020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4183013a00000c3c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9f0220044101742206200520052006491b22064100480d9f020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4184013a00000c3b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9e0220044101742206200520052006491b22064100480d9e020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4185013a00000c3a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9d0220044101742206200520052006491b22064100480d9d020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4186013a00000c390b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9c0220044101742206200520052006491b22064100480d9c020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4187013a00000c380b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9b0220044101742206200520052006491b22064100480d9b020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4188013a00000c370b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9a0220044101742206200520052006491b22064100480d9a020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4189013a00000c360b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d990220044101742206200520052006491b22064100480d99020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418a013a00000c350b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d980220044101742206200520052006491b22064100480d98020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418b013a00000c340b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d970220044101742206200520052006491b22064100480d97020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418c013a00000c330b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d960220044101742206200520052006491b22064100480d96020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418d013a00000c320b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d950220044101742206200520052006491b22064100480d95020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418e013a00000c310b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d940220044101742206200520052006491b22064100480d94020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a418f013a00000c300b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d930220044101742206200520052006491b22064100480d93020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4190013a00000c2f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d920220044101742206200520052006491b22064100480d92020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4191013a00000c2e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d910220044101742206200520052006491b22064100480d91020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4192013a00000c2d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d900220044101742206200520052006491b22064100480d90020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4193013a00000c2c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8f0220044101742206200520052006491b22064100480d8f020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4194013a00000c2b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8e0220044101742206200520052006491b22064100480d8e020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4195013a00000c2a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8d0220044101742206200520052006491b22064100480d8d020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4196013a00000c290b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8c0220044101742206200520052006491b22064100480d8c020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4197013a00000c280b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8b0220044101742206200520052006491b22064100480d8b020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4198013a00000c270b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8a0220044101742206200520052006491b22064100480d8a020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a4199013a00000c260b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d890220044101742206200520052006491b22064100480d89020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419a013a00000c250b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d880220044101742206200520052006491b22064100480d88020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419b013a00000c240b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d870220044101742206200520052006491b22064100480d87020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419c013a00000c230b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d860220044101742206200520052006491b22064100480d86020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419d013a00000c220b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d850220044101742206200520052006491b22064100480d85020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419e013a00000c210b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d840220044101742206200520052006491b22064100480d84020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a419f013a00000c200b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d830220044101742206200520052006491b22064100480d83020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a0013a00000c1f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d820220044101742206200520052006491b22064100480d82020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a1013a00000c1e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d810220044101742206200520052006491b22064100480d81020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a2013a00000c1d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d800220044101742206200520052006491b22064100480d80020240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a3013a00000c1c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dff0120044101742206200520052006491b22064100480dff010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a4013a00000c1b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfe0120044101742206200520052006491b22064100480dfe010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a5013a00000c1a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfd0120044101742206200520052006491b22064100480dfd010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a6013a00000c190b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a7013a00000c180b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a8013a00000c170b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41a9013a00000c160b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41aa013a00000c150b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ab013a00000c140b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ac013a00000c130b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ad013a00000c120b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ae013a00000c110b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41af013a00000c100b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b0013a00000c0f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b1013a00000c0e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b2013a00000c0d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df00120044101742206200520052006491b22064100480df0010240024020040d002006103221050c010b200228020420042006103421050b2005450def0120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b3013a00000c0c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfc0120044101742206200520052006491b22064100480dfc010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b4013a00000c0b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfb0120044101742206200520052006491b22064100480dfb010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b5013a00000c0a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dfa0120044101742206200520052006491b22064100480dfa010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b6013a00000c090b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df90120044101742206200520052006491b22064100480df9010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b7013a00000c080b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df80120044101742206200520052006491b22064100480df8010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b8013a00000c070b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df70120044101742206200520052006491b22064100480df7010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41b9013a00000c060b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df60120044101742206200520052006491b22064100480df6010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41ba013a00000c050b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df50120044101742206200520052006491b22064100480df5010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bb013a00000c040b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df40120044101742206200520052006491b22064100480df4010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bc013a00000c030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df30120044101742206200520052006491b22064100480df3010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bd013a00000c020b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df20120044101742206200520052006491b22064100480df2010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41be013a00000c010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490df10120044101742206200520052006491b22064100480df1010240024020040d002006103221050c010b200228020420042006103421050b2005450df00120022005360204200241086a20063602002002410c6a28020021040b2002410c6a200441016a360200200520046a41bf013a00000b2000411a3a000020012d00004109470df201200141086a28020041ffffffff0371450df201200141046a28020010290cf2010b20064101102e000b20064101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20064101102e000b20064101102e000b20074101102e000b200a4101102e000b20074101102e000b200a4101102e000b20064101102e000b20084101102e000b20064101102e000b20074101102e000b200a4101102e000b20074101102e000b200a4101102e000b20064101102e000b20064101102e000b20064101102e000b20074101102e000b200a4101102e000b20074101102e000b200a4101102e000b20074101102e000b200a4101102e000b20074101102e000b200a4101102e000b20074101102e000b200a4101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b1033000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b200b4101102e000b20094101102e000b20084101102e000b20084101102e000b20084101102e000b20084101102e000b20074101102e000b20064101102e000b20084101102e000b20044101102e000b20074101102e000b20044101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b1033000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b1033000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b20064101102e000b1033000b20002003290300370200200041086a200341086a290300370200200941ffffffff0371450d01200b10290c010b20002002290200370200200041086a200241086a29020037020020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200341106a24000bfb07030e7f017e017f200241086a2103200241046a210420012802002205210602400240024002400240034002400240200428020020032802002207460d00200228020021080c010b200741016a22082007490d0220074101742209200820082009491b22094100480d020240024020070d002009103221080c010b200228020020072009103421080b2008450d032002200836020020042009360200200328020021070b2003200741016a360200200820076a200641807f72200641ff0071200641077622071b3a00002007210620070d000b2001280204220a2001410c6a2802002206410c6c6a210b200141086a280200210c200a21072006450d03200a21072005450d03200b41746a210d200241086a210841002107200a210e02400340200e2103024003402003280200220f0d01200741016a2107200b2003410c6a2203470d000c080b0b2003410c6a210e200741016a21102005417f6a2105200341046a290200211102400240034002400240200241046a220428020020082802002206460d00200228020021090c010b200641016a22092006490d0620064101742201200920092001491b22014100480d060240024020060d002001103221090c010b200228020020062001103421090b2009450d022002200936020020042001360200200828020021060b2008200641016a360200200920066a200741807f72200741ff0071200741077622061b3a0000200621072006450d020c000b0b20014101102e000b2011422088a7221221060240034002400240200428020020082802002207460d00200228020021090c010b200741016a22092007490d0520074101742201200920092001491b22014100480d050240024020070d002001103221090c010b200228020020072001103421090b2009450d022002200936020020042001360200200828020021070b2008200741016a360200200920076a200641807f72200641ff0071200641077622071b3a00002007210620070d000b0240024020042802002206200828020022076b2012490d00200228020021060c010b200720126a22092007490d0420064101742207200920092007491b22074100480d040240024020060d002007103221060c010b200228020020062007103421060b2006450d032002200636020020042007360200200828020021070b2008200720126a360200200620076a200f2012109b051a02402011a7450d00200f10290b200d2003460d052010210720050d010c050b0b20014101102e000b20074101102e000b1033000b20094101102e000b2003410c6a21070b2007200b460d000340024020072802002206450d00200741046a280200450d00200610290b2007410c6a2207200b470d000b0b0240200c450d00200a10290b2000411a3a00000b8307010c7f200028021021030240024002400240200028020822044101460d0020030d012000280218200120022000411c6a28020028020c11040021030c030b2003450d010b0240024020020d00410021020c010b200120026a2105200041146a28020041016a21064100210720012103200121080340200341016a210902400240024020032c0000220a417f4a0d000240024020092005470d004100210b200521030c010b20032d0001413f71210b200341026a220921030b200a411f71210c0240200a41ff0171220a41df014b0d00200b200c41067472210a0c020b0240024020032005470d004100210d2005210e0c010b20032d0000413f71210d200341016a2209210e0b200d200b41067472210b0240200a41f0014f0d00200b200c410c7472210a0c020b02400240200e2005470d004100210a200921030c010b200e41016a2103200e2d0000413f71210a0b200b410674200c411274418080f0007172200a72220a418080c400470d020c040b200a41ff0171210a0b200921030b02402006417f6a2206450d00200720086b20036a21072003210820052003470d010c020b0b200a418080c400460d00024002402007450d0020072002460d0041002103200720024f0d01200120076a2c00004140480d010b200121030b2007200220031b21022003200120031b21010b20040d002000280218200120022000411c6a28020028020c1104000f0b4100210902402002450d002002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b0240200220096b200028020c2206490d002000280218200120022000411c6a28020028020c1104000f0b410021074100210902402002450d00410021092002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b200920026b20066a210a024002400240410020002d0030220320034103461b0e0402000100020b200a21074100210a0c010b200a4101762107200a41016a410176210a0b200741016a2103024003402003417f6a2203450d0120002802182000280204200028021c280210110300450d000b41010f0b2000280204210941012103200028021820012002200028021c28020c1104000d00200a41016a2103200028021c210a20002802182100034002402003417f6a22030d0041000f0b20002009200a280210110300450d000b41010f0b20030bcb0401067f200441046a2105024002400240024002400240200441086a2802002004410c6a2802002206460d00200528020021070c010b200641016a22072006490d0420064101742208200720072008491b22084100480d040240024020060d002008103221070c010b200528020020062008103421070b2007450d0120042007360204200441086a20083602002004410c6a28020021060b2004410c6a2208200641016a360200200720066a20024101463a0000200441086a2109034002400240200928020020082802002206460d00200528020021070c010b200641016a22072006490d052006410174220a20072007200a491b220a4100480d050240024020060d00200a103221070c010b20052802002006200a103421070b2007450d03200420073602042009200a360200200828020021060b2008200641016a360200200720066a200141807f72200141ff0071200141077622061b3a00002006210120060d000b024020024101470d002004410c6a2107200441086a2108034002400240200828020020072802002206460d00200528020021010c010b200641016a22012006490d0620064101742209200120012009491b22094100480d060240024020060d002009103221010c010b200528020020062009103421010b2001450d052004200136020420082009360200200728020021060b2007200641016a360200200120066a200341807f72200341ff0071200341077622061b3a00002006210320060d000b0b2000411a3a00000f0b20084101102e000b200a4101102e000b20094101102e000b1033000bc60701097f230041d0006b2202240002400240024002400240024002400240024020012802082203200128020c2204460d00200441016a22052004490d0420032005490d072001280200220620046a2d000021072001200536020c0240200741014d0d00410c21040c020b4100210820070e020302030b200241013a001f200241cc006a41013602002002420137023c200241d8e7c500360238200241213602342002200241306a36024820022002411f6a360230200241206a200241386a10af042002411a6a200241286a28020036010020022002290320370112200220022901103703002002200241166a290100370106410521040b200020073a0005200020043a000420002002290300370106200041013602002000410c6a20022901063701000c060b410121080b410120036b2109200441026a2104410021074100210a02400240034002402007411f4d0d00410f21070c020b02400240200920046a4102460d002004450d06200320044f0d0120042003108f01000b200241013a0000200241cc006a41013602002002420137023c200241d8e7c500360238200241213602342002200241306a36024820022002360230200241106a200241386a10af04410521070c020b200620046a417f6a2d000021052001200436020c200541ff00712007411f7174200a72210a200441016a2104200741076a21072005418001710d000b20074120490d01410d210720054110490d010b2000200736020420004101360200200041086a2002290210370200200041106a200241106a41086a2802003602000c050b0240024020080d00410021040c010b2004417f6a2104410021074100210802400240034002402007411f4d0d00410f21040c020b0240024020032004460d002004417f460d082003200441016a22094f0d01200441016a2003108f01000b200241013a0000200241cc006a41013602002002420137023c200241d8e7c500360238200241213602342002200241306a36024820022002360230200241106a200241386a10af04410521040c020b200620046a2d000021052001200936020c200541ff00712007411f71742008722108200741076a2107200921042005418001710d000b20074120490d01410d210420054110490d010b2000200436020420004101360200200041086a2002290210370200200041106a200241106a41086a2802003602000c060b410121040b2000200a360204200041003602002000410c6a2008360200200041086a20043602000c040b417f20051030000b417f20041030000b417f200441016a1030000b20052003108f01000b200241d0006a24000b8d07010b7f230041d0086b22022400410021034100210402400240024002400240034002402003411f4d0d00410f21030c020b0240024020012802082205200128020c2206460d00200641016a22072006490d05200520074f0d0120072005108f01000b200241013a0089082002411c6a41013602002002420137020c200241d8e7c5003602082002412136029c08200220024198086a360218200220024189086a36029808200241b8086a200241086a10af04410521030c020b2001280200220820066a2d000021062001200736020c200641ff00712003411f71742004722104200341076a21032006418001710d000b20034120490d01410d210320064110490d010b2000200336020420004101360200200041086a20022902b808370200200041106a200241b8086a41086a2802003602000c030b024020040d002000428080808010370200200041086a42003702000c030b200241086a4100418008109a051a41002106410021094101210a4100210b03400240024002400240200520076b2004200b6b22034180082003418008491b2203490d00200720036a220c2007490d022005200c4f0d01200c2005108f01000b200241013a00a708200241cc086a4101360200200242013702bc08200241d8e7c5003602b8082002412136029c08200220024198086a3602c8082002200241a7086a36029808200241a8086a200241b8086a10af0420024194086a200241b0086a280200360000200220022903a80837008c08200041053a000420002002290089083700052000410c6a20024190086a290000370000200041013602002009450d06200a10290c060b200241086a200820076a2003109b051a2001200c36020c0240200920066b2003490d00200620036a210c0c020b0240200620036a220c2006490d0020094101742207200c200c2007491b22074100480d000240024020090d0020071032210a0c010b200a200920071034210a0b0240200a450d00200721090c030b20074101102e000b1033000b2007200c1030000b200a20066a200241086a2003109b051a20042003200b6a220b4d0d02200128020c21072001280208210520012802002108200c21060c000b0b417f20071030000b200241086a200a200c108204024020022802084101470d0002402009450d00200a10290b200041083a0004200041013602000c010b2000200a3602042000410c6a200c360200200041086a2009360200200041003602000b200241d0086a24000b1600200120002802002200280200200028020810b3040bf00201067f230041c0006b2202240041002103410021040240024003400240024002402003411f4b0d002001280204220520012802082206460d01200641016a22072006490d04200520074f0d0220072005108f01000b200041013602002000410f3a00040c040b200241013a000f200241346a410136020020024201370224200241d8e7c5003602202002412136023c2002200241386a36023020022002410f6a360238200241106a200241206a10af042002410b6a200241186a28020036000020022002290310370003200041053a0004200020022900003700052000410c6a200241076a290000370000200041013602000c030b200128020020066a2d0000210620012007360208200641ff00712003411f71742004722104200341076a21032006418001710d000b0240024020034120490d002006410f4b0d010b20004100360200200020043602040c020b200041013602002000410d3a00040c010b417f20071030000b200241c0006a24000bd806010a7f20012802042103200128020021044100210541002106410021074101210820012802082209210a02400240024002400340024020062007470d002005200641016a220b200b2005491b22074100480d050240024020060d002007103221080c010b200820062007103421080b2008450d020b200820066a200a41807f72200a41ff0071200a410776220b1b3a0000200541026a2105200641016a2106200b210a200b0d000b0240200720066b20094f0d00200620096a220a2006490d0420074101742205200a200a2005491b220a4100480d040240024020070d00200a103221080c010b20082007200a103421080b2008450d02200a21070b200820066a20042009109b051a02402003450d00200410290b200128020c210c0240200720096b20066b200141146a280200220a490d002009200a6a20066a21030c030b200920066a2205200a6a22032005490d0320074101742205200320032005491b22054100480d030240024020070d002005103221080c010b200820072005103421080b02402008450d00200521070c030b20054101102e000b20074101102e000b200a4101102e000b200820096a20066a200c200a109b051a200241086a210b200241046a21092003210a024002400340024002402009280200200b2802002206460d00200228020021050c010b200641016a22052006490d0420064101742204200520052004491b22044100480d040240024020060d002004103221050c010b200228020020062004103421050b2005450d022002200536020020092004360200200b28020021060b200b200641016a360200200520066a200a41807f72200a41ff0071200a41077622061b3a00002006210a20060d000b02400240200241046a280200220a200241086a28020022066b2003490d002002280200210a0c010b200620036a22052006490d03200a4101742206200520052006491b22064100480d0302400240200a0d0020061032210a0c010b2002280200200a20061034210a0b200a450d022002200a360200200241046a2006360200200241086a28020021060b200241086a200620036a360200200a20066a20082003109b051a02402007450d00200810290b2000411a3a00000240200141106a280200450d00200c10290b0f0b20044101102e000b20064101102e000b1033000be3ca0106067f017e057f017e117f027e2300419081046b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001280204220320012802082204460d00200441016a22052004490d02200320054f0d0120052003108f01000b200241013a0030200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a10af0420022802f88004210420022802fc8004210120004101360200200041003a00042001450d1c200410290c1c0b200128020020046a2d00002104200120053602082004410b4b0d02024020040e0c00100f0e0d0c0b0a02060504000b200241e8006a200110b80441012106200228026c2107024020022802684101470d0020074108762101200241f8006a2802002104200241e8006a41086a29030021080c150b41002109200241e8006a410041808001109a051a410021034100210a2007450d10410021054100210a410121064100210b034002400240024002402001280204220c200128020822036b2007200b6b220441808001200441808001491b2204490d00200320046a220d2003490d02200c200d4f0d01200d200c108f01000b200241013a00e880042002418c81046a4101360200200242013702fc8004200241d8e7c5003602f880042002412136021c2002200241186a36028881042002200241e880046a360218200241306a200241f880046a10af042002290330210820022802382104410521070240200a450d00200610290b0c180b200241e8006a200128020020036a2004109b051a2001200d3602080240200a20056b2004490d00200520046a21030c020b200520046a22032005490d14200a410174220d20032003200d491b220d4100480d1402400240200a0d00200d103221060c010b2006200a200d103421060b02402006450d00200d210a0c020b200d4101102e000b2003200d1030000b200620056a200241e8006a2004109b051a2003210520072004200b6a220b4b0d000c110b0b417f20051030000b200241e8006a200110bb04024020022802684101470d00200041013602002000200241e8006a41047222012902003702042000410c6a200141086a2902003702000c1a0b200241fc006a280200210d200241f8006a2802002101200241f4006a2802002103200241f0006a280200210a200228026c210b410021044100210502400240034002402004411f4d0d00410f21010c0a0b20032001460d082001417f460d012003200141016a2206490d02200b20016a2d0000220941ff00712004411f71742005722105200441076a2104200621012009418001710d000b20044120490d06410d21012009410f4b0d080c060b417f200141016a1030000b200141016a2003108f01000b200041123a000420004101360200200041056a20043a00000c180b200241e8006a200110bb040240024020022802684101470d00200228026c22014108762109200241e8006a41086a2903002208422088210e200241f8006a28020021060c010b200241c0006a200241fc006a280200360200200241386a200241f4006a2902003703002002200229026c37033041002101410021090240024002400240024002400240034002402001411f4d0d00410f210a0c020b0240024020022802382205200228023c2204460d00200441016a22032004490d05200520034f0d0120032005108f01000b200241013a00f88004200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241f880046a360218200241c8006a200241e8006a10af044105210a0c020b200228023020046a2d000021042002200336023c200441ff00712001411f71742009722109200141076a21012004418001710d000b20014120490d01410d210a20044110490d010b200241e880046a41086a200241c8006a41086a28020022063602002002200229034822083703e880042008422088a721072008a7210d410021090c050b200241003602502002420437034841042105024002402009450d004100210f410021104100210703402007221141016a210741002101410021060240024002400240024002400240034002402001411f4d0d00410f210a0c030b2002280238220b200228023c2204460d01200441016a22032004490d04200b2003490d06200228023020046a2d000021042002200336023c200441ff00712001411f71742006722106200141076a21012004418001710d000b20014120490d022004410f4d0d02410d210a0c010b200241013a00582002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241d8006a360218200241f880046a200241e8006a10af04200241e880046a41086a200241f880046a41086a280200360200200220022903f8800422083703e880042008a7210d4105210a0b20022802f08004210620022802ec80042107410021090c0a0b200241e8006a200241306a10ac04024020022802684101470d00200228026c220a410876210920022802782106200228027421072002280270210d0c0a0b2002280274211220022802702113200228026c2114410021044100210a02400240034002402004411f4d0d00410f210a0c020b024002402002280238220b200228023c2203460d00200341016a22012003490d06200b20014f0d012001200b108f01000b200241013a00e880042002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241e880046a360218200241f880046a200241e8006a10af04200241206a41086a200241f880046a41086a280200360200200220022903f8800422083703202008a7210d4105210a0c030b2002280230220d20036a2d000021032002200136023c200341ff00712004411f7174200a72210a200441076a21042003418001710d000b20044120490d0520034110490d05410d210a0b0b20022802282106200228022421070c080b417f20031030000b417f20011030000b2003200b108f01000b41002115200241e8006a410041808004109a051a02400240200a0d0041012116410021170c010b4100211541012116410021034100210c03400240024002400240200b20016b200a200c6b220441808004200441808004491b2204490d00200120046a22172001490d02200b20174f0d012017200b108f01000b200241013a00202002410136028c8104200242013702fc8004200241d8e7c5003602f880042002412136021c2002200241186a36028881042002200241206a360218200241e880046a200241f880046a10af0420022802e88004210d20022802ec8004210720022802f0800421064105210a2015450d09201610290c090b200241e8006a200d20016a2004109b051a2002201736023c0240201520036b2004490d00200320046a21170c020b200320046a22172003490d1a20154101742201201720172001491b22014100480d1a0240024020150d002001103221160c010b201620152001103421160b02402016450d00200121150c020b20014101102e000b200120171030000b201620036a200241e8006a2004109b051a200a2004200c6a220c4d0d01200228023c21012002280238210b2002280230210d201721030c000b0b024020112010470d000240200f2010460d00200f21100c010b200f41016a2201200f490d17200f4101742204200120012004491b2210ad421c7e2208422088a70d172008a722014100480d1702400240200f0d002001103221050c010b2005200f411c6c2001103421050b2005450d032002201036024c200220053602482010210f0b20052011411c6c6a22012016360210200120143602042001200641087622043b0001200120063a0000200141186a2017360200200141146a20153602002001410c6a2012360200200141086a2013360200200141036a20044110763a00002002200736025020072009470d000b0b200228023c2002280240462101200229024c2208422088210e02402002280234450d00200228023010290b200ea721042008a7210b2001450d042004ad422086200bad842108410c21040c1a0b20014104102e000b417f20031030000b02402012450d0020124104742104201421010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b410021092013450d00201410290b02402011450d0020052011411c6c6a210b20052103034002402003410c6a2802002204450d0020032802042101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b0240200341086a280200450d00200328020410290b2003411c6a21010240200341146a280200450d00200328021010290b200121032001200b470d000b0b200f450d01200510290c010b20024103410220011b3a00e88004200241e8006a41146a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241e880046a360218200241f880046a200241e8006a10af0420022903f88004210820022802808104210602402004450d0020052004411c6c6a210920052103034002402003410c6a2802002204450d0020032802042101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b0240200341086a280200450d00200328020410290b2003411c6a21010240200341146a280200450d00200328021010290b2001210320012009470d000b0b2008422088210e4105210141002109200b450d01200510290c010b2009410874200a41ff01717221012007ad220e422086200dad8421082002280234450d00200228023010290b20004101360200200041106a2006360200200041086a200e422086200842ffffffff0f838437020020002009410874200141ff0171723602040c170b200241e8006a200110bb040240024020022802684101470d00200228026c220a4108762101200241e8006a41086a2903002208422088210e200241f8006a28020021090c010b200241fc006a2802002115200241f8006a2802002101200241f4006a2802002109200241f0006a280200210d200228026c210b4100210441002106024002400240024002400240024002400240024002400240034002402004411f4d0d00410f210a0c020b0240024020092001460d002001417f460d052009200141016a22034f0d01200141016a2009108f01000b200241013a0030200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241306a360218200241e880046a200241e8006a10af044105210a0c020b200b20016a2d0000220541ff00712004411f71742006722106200441076a2104200321012005418001710d000b20044120490d01410d210a20054110490d010b200241f880046a41086a200241e880046a41086a2802002209360200200220022903e8800422083703f880042008422088a721072008a721060c0a0b200241003602602002420437035802400240024002400240024002400240024002400240024020060d00410421050c010b200241f1006a21104100210f0340200f41016a210f4100210141002105024002400240034002402001411f4d0d00410f210a0c020b0240024020092003460d002003417f460d112009200341016a22044f0d01200341016a2009108f01000b200241013a00f880042002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241f880046a360218200241c8006a200241e8006a10af044105210a200228024821060c030b200b20036a2d0000220a41ff00712001411f71742005722105200141076a210120042103200a418001710d000b20014120490d02200a4110490d02410d210a0b0b20022802502109200228024c21070c140b4100210c200241e8006a410041808001109a051a0240024020050d004101211720042103410021164100210a0c010b41002116410121174100210741002111034002400240200920046b200520116b220141808001200141808001491b2201490d00200420016a22032004490d0e200920034f0d0120032009108f01000b200241013a00482002410136028c8104200242013702fc8004200241d8e7c5003602f880042002412136021c2002200241186a36028881042002200241c8006a360218200241e880046a200241f880046a10af0420022802e88004210620022802ec8004210720022802f0800421094105210a2016450d16201710290c160b200241e8006a200b20046a2001109b051a02400240201620076b2001490d00200720016a210a0c010b200720016a220a2007490d2620164101742204200a200a2004491b22044100480d260240024020160d002004103221170c010b201720162004103421170b2017450d0c200421160b201720076a200241e8006a2001109b051a20032104200a21072005200120116a22114b0d000b0b2002200a3602402002410036023c2002200a3602382002201636023420022017360230410021014100210702400240034002402001411f4d0d00410f210a0c020b02400240200a200c460d00200c417f460d0d200a200c41016a22054f0d01200c41016a200a108f01000b200241013a00482002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241c8006a360218200241f880046a200241e8006a10af04200241206a41086a200241f880046a41086a280200360200200220022903f880043703204105210a0c020b2017200c6a2d000021042002200536023c200441ff00712001411f71742007722107200141076a21012005210c2004418001710d000b20014120490d0120044110490d01410d210a0b200241e880046a41086a200241206a41086a28020022093602002002200229032022083703e880042008a7210620022802ec800421070c120b4100210c200241003602f08004200242043703e880040240024020070d0041042118410021194100211a0c010b41002119410421184100211a034020192114201a221341016a211a4100210141002117024002400240034002402001411f4d0d00410f21040c020b0240024020022802382211200228023c2204460d00200441016a22052004490d0f201120054f0d0120052011108f01000b200241013a00f880042002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241f880046a360218200241c8006a200241e8006a10af0441052104200228024821060c030b2002280230221620046a2d0000210a2002200536023c200a41ff00712001411f71742017722117200141076a2101200a418001710d000b20014120490d02200a4110490d02410d21040b0b20022802502109200228024c2107410021010c120b02400240024020112005460d00200441026a21042005417f460d0b20112004490d09201620056a2c000021012002200436023c0240200141004e0d00411821040c150b41062104200141c00071450d13200141807f72220141ff017141fb014d0d1320132014460d0120142119201321140c020b200241013a00482002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241c8006a360218200241f880046a200241e8006a10af0420022802f88004210620022802fc80042107200228028081042109410521040c130b201441016a22042014490d2620144101742205200420042005491b221941ffffffff01712019470d26201941037422044100480d260240024020140d002004103221180c010b201820144103742004103421180b2018450d08200220183602e880040b201820144103746a2204201241807e712001417f7341ff01717222123a000420042017360200201a2007470d000b200220193602ec80042002201a3602f080040b4101210541082111410021040340200241e8006a200241306a10ad04024020022802684101470d00200228027821092002280274210720022802702106200228026c210a0c0f0b200241f880046a41026a2201201041026a2d00003a0000200220102f00003b01f880042002280274211420022802782116200228027c21070240024002400240024020022d007022174106470d002005417f6a21050c010b2017417e6a41034f0d00200541016a220a20054f2113200a210520130d004115210741cdaec50021064104210a024020174109460d000c130b201641ffffffff03710d010c120b200241e8006a41026a221320012d00003a0000200220022f01f880043b01682004200c460d01200c210a0c020b201410290c100b200c41016a2201200c490d25200c4101742204200120012004491b220a41ffffffff0071200a470d25200a41047422014100480d2502400240200c0d002001103221110c010b2011200c4104742001103421110b2011450d04200c2104200a210c0b201120044104746a220120173a00002001200736020c2001201636020820012014360204200120022f01683b0001200141036a20132d00003a0000200441016a210420050d000b200228023c200228024046210102402002280234450d00200228023010290b2001450d12024020022802602207200228025c470d00200741016a22012007490d2420074101742205200120012005491b2205ad42187e2208422088a70d242008a7220c4100480d240240024020070d00200c103221010c010b2002280258200741186c200c103421010b2001450d042002200536025c200220013602580b20022802582205200741186c6a2201201136020c2001201a3602082001201936020420012018360200200141146a2004360200200141106a200a3602002002200741016a360260200f2006470d000b0b20032015462101200229025c2208422088210e0240200d450d00200b10290b200ea721042008a7210b2001450d122004ad422086200bad842108410b21040c270b20014108102e000b200c4104102e000b20042011108f01000b20044104102e000b417f20041030000b417f20051030000b417f200c41016a1030000b20044101102e000b200420031030000b417f200341016a1030000b417f200141016a1030000b02402004450d0020044104742104201121010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b0240200c450d00201110290b20190d020c030b0b200220143602ec8004200220133602f08004200141ff0171410874200472210a2014450d010b201810290b2002280234450d01200228023010290c010b20024103410220011b3a00e880042002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241e880046a360218200241f880046a200241e8006a10af0420022802f88004210620022802fc8004210720022802808104210902402004450d0020044104742104201121010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b0240200a450d00201110290b4105210a2019450d00201810290b2002280258210c024020022802602201450d00200c200141186c6a2105200c210303400240200341046a280200450d00200328020010290b0240200341146a2802002204450d00200328020c2101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b200341186a21010240200341106a280200450d00200328020c10290b2001210320012005470d000b0b200228025c450d01200c10290c010b20024103410220011b3a0030200241e8006a41146a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a10af0420022903f88004210820022802808104210902402004450d002005200441186c6a21062005210303400240200341046a280200450d00200328020010290b0240200341146a2802002204450d00200328020c2101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b200341186a21010240200341106a280200450d00200328020c10290b2001210320012006470d000b0b2008422088210e4105210a41002101200b450d01200510290c010b200a41087621012007ad220e4220862006ad842108200d450d00200b10290b20004101360200200041106a2009360200200041086a200e422086200842ffffffff0f838437020020002001410874200a41ff0171723602040c160b200241e8006a200110bb040240024020022802684101470d00200228026c22014108762109200241e8006a41086a2903002208422088210e200241f8006a28020021060c010b2002418881046a200241fc006a2802003602002002418081046a200241f4006a2902003703002002200229026c3703f880044100210141002109024002400240024002400240024002400240034002402001411f4d0d00410f210b0c020b02400240200228028081042205200228028481042204460d00200441016a22032004490d05200520034f0d0120032005108f01000b200241013a0058200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a10af04200241e880046a41086a200241306a41086a280200360200200220022903303703e880044105210b0c020b20022802f8800420046a2d00002104200220033602848104200441ff00712001411f71742009722109200141076a21012004418001710d000b20014120490d01410d210b20044110490d010b200241c8006a41086a200241e880046a41086a2802002206360200200220022903e8800422083703482008422088a7210d2008a7210a410021090c070b200241003602f08004200242043703e880040240024020090d00410421050c010b4100210b0340200b41016a210b410021014100210602400240024002400240034002402001411f4d0d00410f210b0c030b200228028081042205200228028481042204460d01200441016a22032004490d0920052003490d0c20022802f8800420046a2d00002104200220033602848104200441ff00712001411f71742006722106200141076a21012004418001710d000b20014120490d022004410f4d0d02410d210b0c010b200241013a00582002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a10af04200241206a41086a200241306a41086a2802003602002002200229033022083703202008a7210a4105210b0b200228022821062002280224210d410021090c010b200241e8006a200241f880046a10ac04024020022802684101470d00200228026c220b4108762109200228027821062002280274210d2002280270210a0c010b2002280274210c20022802702117200228026c2115200241e8006a200241f880046a10b00420022802684101470d01200228026c210b200228027821062002280274210d2002280270210a0240200c450d00200c4104742104201521010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b200b41087621092017450d00201510290b20022802e880042107024020022802f080042201450d0020072001411c6c6a210520072103034002402003410c6a2802002204450d0020032802042101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b0240200341086a280200450d00200328020410290b2003411c6a21010240200341146a280200450d00200328021010290b2001210320012005470d000b0b20022802ec8004450d09200710290c090b4100210d20022802702111200228026c2105024002402002280274220141027422030d00410421074100210a0c010b2003410275220a41ffffffff0371200a470d16200a41027422044100480d16200410322207450d050b02402001450d002003417c6a210d2007210120052104034020012004280200360200200141046a2101200441046a21042003417c6a22030d000b200d41027641016a210d0b02402011450d00200510290b024020022802f08004220420022802ec8004470d00200441016a22012004490d1620044101742203200120012003491b2203ad421c7e2208422088a70d162008a722054100480d160240024020040d002005103221010c010b20022802e880042004411c6c2005103421010b2001450d06200220033602ec8004200220013602e880040b20022802e8800422052004411c6c6a2201200641087622033b00012001200736021020012015360204200120063a0000200141036a20034110763a0000200141186a200d360200200141146a200a3602002001410c6a200c360200200141086a20173602002002200441016a3602f08004200b2009470d000b0b200228028481042002280288810446210120022902ec80042208422088210e024020022802fc8004450d0020022802f8800410290b200ea721042008a7210b2001450d052004ad422086200bad842108410a21040c190b417f20031030000b417f20031030000b20044104102e000b20054104102e000b20032005108f01000b20024103410220011b3a00e88004200241e8006a41146a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241e880046a360218200241306a200241e8006a10af04200229033021082002280238210602402004450d0020052004411c6c6a210920052103034002402003410c6a2802002204450d0020032802042101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b0240200341086a280200450d00200328020410290b2003411c6a21010240200341146a280200450d00200328021010290b2001210320012009470d000b0b2008422088210e4105210141002109200b450d01200510290c010b2009410874200b41ff0171722101200dad220e422086200aad84210820022802fc8004450d0020022802f8800410290b20004101360200200041106a2006360200200041086a200e422086200842ffffffff0f838437020020002009410874200141ff0171723602040c150b200d20064621010240200a450d00200b10290b02402001450d00410921040c110b20024103410220011b3a00e88004200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241e880046a360218200241306a200241e8006a10af042002418381046a200241386a280200360000200220022903303700fb8004200041053a0004200020022900f880043700052000410c6a200241ff80046a290000370000200041013602000c140b200241013a0030200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a10af04410521010b2000200136020420004101360200200041086a20022902f88004370200200041106a200241f880046a41086a280200360200200a450d12200b10290c120b200241e8006a200110bb040240024020022802684101470d00200228026c22034108762101200241e8006a41086a2903002208422088210e200241f8006a28020021090c010b2002418881046a200241fc006a2802003602002002418081046a200241f4006a2902003703002002200229026c3703f880044100210141002109024002400240024002400240024002400240024002400240024002400240024002400240034002402001411f4d0d00410f21030c020b02400240200228028081042205200228028481042204460d00200441016a22032004490d05200520034f0d0120032005108f01000b200241013a0058200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a10af04200241206a41086a200241306a41086a28020036020020022002290330370320410521030c020b20022802f8800420046a2d00002104200220033602848104200441ff00712001411f71742009722109200141076a21012004418001710d000b20014120490d01410d210320044110490d010b200241e880046a41086a200241206a41086a28020022093602002002200229032022083703e880042008422088a721062008a7210b0c100b20024100360260200242043703584104210502402009450d00410021154100210c410021160340200241e8006a200241f880046a10b604024020022802684101470d002002200229027422083703e880042002280270210b200228026c21032008a721060c100b20022802702117200228026c211102400240200228028081042204200228028481042203460d00200341016a22012003490d05200420014f0d0120012004108f01000b200241013a00482002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241c8006a360218200241306a200241e8006a10af040c0d0b2002280274210f20022802f88004220620036a2d000021072002200136028481040240200741034d0d00410a21010c0f0b0240024002400240024020070e0400010203000b410021074100210b4100210303400240200b411f4d0d00410f21010c140b20042001460d122001417f460d092004200141016a220d490d0e200620016a2d0000210a2002200d3602848104200a41ff0071200b411f71742003722103200b41076a210b200d2101200a418001710d000b41002107200b4120490d03200a410f4d0d03410d21010c120b4100210b410021030340200b411f4b0d0f0240024020042001460d002001417f460d0b2004200141016a220d4f0d01200141016a2004108f01000b200241013a00482002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241c8006a360218200241306a200241e8006a10af040c110b200620016a2d0000210a2002200d3602848104200a41ff0071200b411f71742003722103200b41076a210b200d2101200a418001710d000b41012107200b4120490d02200a410f4d0d020c0d0b4100210b410021030340200b411f4b0d0e0240024020042001460d002001417f460d0b2004200141016a220d4f0d01200141016a2004108f01000b200241013a00482002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241c8006a360218200241306a200241e8006a10af040c100b200620016a2d0000210a2002200d3602848104200a41ff0071200b411f71742003722103200b41076a210b200d2101200a418001710d000b41022107200b4120490d01200a410f4b0d0c0c010b4100210b410021030340200b411f4b0d0d0240024020042001460d002001417f460d0b2004200141016a220d4f0d01200141016a2004108f01000b200241013a00482002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241c8006a360218200241306a200241e8006a10af040c0f0b200620016a2d0000210a2002200d3602848104200a41ff0071200b411f71742003722103200b41076a210b200d2101200a418001710d000b41032107200b4120490d00200a410f4b0d0b0b200220033602f08004200220073602ec800420022902ec8004210802400240200c2015460d00201521040c010b201541016a22012015490d1b20154101742204200120012004491b2204ad42147e220e422088a70d1b200ea722014100480d1b0240024020150d002001103221050c010b2005201541146c2001103421050b2005450d09200220053602582015210c200421150b2005200c41146c6a2201200837020c2001200f3602082001201736020420012011360200200c41016a210c201641016a22162009470d000b2002200436025c2002200c3602600b2002280284810420022802888104462101200229025c2208422088210e024020022802fc8004450d0020022802f8800410290b200ea721042008a721062001450d0e2004ad4220862006ad842108410821040c1e0b417f20031030000b417f20011030000b417f200141016a1030000b417f200141016a1030000b417f200141016a1030000b417f200141016a1030000b20014104102e000b200141016a2004108f01000b410d2101410021070c030b410f2101410021070c020b2002280230210b2002290234210841052101410021070c010b200241013a00482002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241c8006a360218200241306a200241e8006a10af042002280230210b20022902342108410521010b20074108742001722103200220083703e880042008a721062017450d00201110290b2002200c3602602002201536025c20022802ec800421090240200c450d00200c41146c21042005210103400240200141046a280200450d00200128020010290b200141146a21012004416c6a22040d000b0b2015450d01200510290c010b20024103410220011b3a00e88004200241e8006a41146a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241e880046a360218200241306a200241e8006a10af04200229033021082002280238210902402004450d00200441146c21042005210103400240200141046a280200450d00200128020010290b200141146a21012004416c6a22040d000b0b2008422088210e41052103410021012006450d01200510290c010b200341087621012006ad220e422086200bad84210820022802fc8004450d0020022802f8800410290b20004101360200200041106a2009360200200041086a200e422086200842ffffffff0f838437020020002001410874200341ff0171723602040c110b200241e8006a200110bb040240024020022802684101470d00200228026c220a4108762101200241e8006a41086a2903002208422088210e200241f8006a28020021030c010b200241c0006a200241fc006a280200360200200241386a200241f4006a2902003703002002200229026c37033041002101410021050240024002400240024002400240024002400240024002400240034002402001411f4d0d00410f210a0c020b0240024020022802382209200228023c2204460d00200441016a22032004490d05200920034f0d0120032009108f01000b200241013a0058200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241d8006a360218200241f880046a200241e8006a10af04200241206a41086a200241f880046a41086a280200360200200220022903f880043703204105210a0c020b2002280230220620046a2d000021042002200336023c200441ff00712001411f71742005722105200141076a21012004418001710d000b20014120490d01410d210a20044110490d010b200241e880046a41086a200241206a41086a28020022033602002002200229032022083703e880042008422088a721062008a721090c0b0b20024100360260200242043703580240024020050d00410421050c010b2005417f6a210c410421054104210f4104210b41042116410421114100210d4100210703400240024020092003460d00200341016a22042003490d05200920044f0d0120042009108f01000b2002200d36025c20022007360260200241013a0048200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241c8006a360218200241e880046a200241e8006a10af0420022802e88004210920022802ec8004210620022802f080042103410521040c090b200620036a2c000021012002200436023c20014100480d0402400240200141c00071450d00200141807f72220141ff017141fb014b0d010b2002200d36025c20022007360260410621040c080b0240024002400240024020092004460d00200341026a21032004417f460d0a200920034f0d0120032009108f01000b2002200d36025c20022007360260200241013a0048200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241c8006a360218200241e880046a200241e8006a10af0420022802e88004210920022802ec8004210620022802f080042103410521010c010b200620046a2d000021042002200336023c0240200441014b0d004100210320040e020302030b2002200d36025c20022007360260410c21010b2002418881046a20033602002002418481046a20063602002002418081046a2009360200200220043a00fd8004200220013a00fc80040c0b0b41800221030b200241e8006a200241306a10ac042002280274210620022802702109200228026c210a024020022802684101470d002002200d36025c20022007360260200241f8006a28020021030c0b0b024002402007200d460d00200d21152007210d0c010b200d41016a2204200d490d15200d4101742205200420042005491b221541ffffffff00712015470d15201541047422044100480d1502400240200d0d002004103221050c010b2016200d4104742004103421050b2005450d07200220053602582005210f2005210b20052116200521110b2011200d4104746a220420174180807c712001417f7341ff017172200372221736020c20042006360208200420093602042004200a360200200d41016a21070240200c450d00200c417f6a210c200228023c210320022802382109200228023021062015210d0c010b0b2002201536025c200220073602600b200228023c2002280240462101200229025c2208422088210e02402002280234450d00200228023010290b200ea721042008a7210b2001450d092004ad422086200bad842108410721040c180b417f20031030000b417f20041030000b2002200d36025c20022007360260411821040c020b417f20031030000b20044104102e000b0b2002418881046a20033602002002418481046a20063602002002418081046a2009360200200220013a00fd8004200220043a00fc80040b200241013a00f8800420022802fc8004210a0b02402007450d00200b20074104746a210503400240200b2802082204450d00200b2802002101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b200b41106a21010240200b41046a280200450d00200b28020010290b2001210b20012005470d000b0b200d450d01200f10290c010b20024103410220011b3a00e88004200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241e880046a360218200241f880046a200241e8006a10af0420022903f88004210820022802808104210302402004450d00200520044104746a2106200521090340024020092802082204450d0020092802002101200441047421040340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010290b200141106a2101200441706a22040d000b0b200941106a21010240200941046a280200450d00200928020010290b2001210920012006470d000b0b2008422088210e4105210a41002101200b450d01200510290c010b200a41087621012006ad220e4220862009ad8421082002280234450d00200228023010290b20004101360200200041106a2003360200200041086a200e422086200842ffffffff0f838437020020002001410874200a41ff0171723602040c100b200241e8006a200110bb040240024020022802684101470d00200228026c22044108762103200241e8006a41086a2903002208422088210e200241f8006a28020021010c010b2002418881046a200241fc006a2802003602002002418081046a200241f4006a29020022083703002002200229026c220e3703f88004200ea7210b2008a7210541002104200228028481042101410021030240024002400240024002400240024003402004411f4b0d010240024020052001460d002001417f460d072005200141016a22094f0d01200141016a2005108f01000b200220053602848104200241013a0058200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a10af04200241206a41086a200241306a41086a280200360200200220022903303703204105210b0c030b200b20016a2d0000220641ff00712004411f71742003722103200441076a2104200921012006418001710d000b200220093602848104024020044120490d00410d210b2006410f4b0d020b200241003602382002420437033020030d02410421050c030b200220013602848104410f210b0b200241e880046a41086a200241206a41086a28020022013602002002200229032022083703e880042008422088a7210a2008a7210d410021090c040b4104210541002104410021060340200241e8006a200241f880046a10b50420022f006d20022d006f4110747221092002280274210a2002280270210d20022d006c210b024020022802684101470d002002200436023420022006360238200241f8006a28020021012004450d05200510290c050b0240024020062004460d0020042107200621010c010b200441016a22012004490d0d20044101742207200120012007491b2207ad420c7e2208422088a70d0d2008a722014100480d0d0240024020040d002001103221050c010b20052004410c6c2001103421050b2005450d042002200536023020042101200721040b20052001410c6c6a220120093b00012001200d3602042001200b3a0000200141036a20094110763a0000200141086a200a3602002003200641016a2206470d000b20022007360234200220063602380b200228028481042002280288810446210120022902342108024020022802fc8004450d0020022802f8800410290b2008a721092001450d032008422088a7ad4220862009ad842108410621040c100b417f200141016a1030000b20014104102e000b200941ffffff07712203410874200b41ff0171722104200aad220e422086200dad84210820022802fc8004450d0120022802f8800410290c010b20024103410220011b3a00e88004200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241e880046a360218200241306a200241e8006a10af0420022903302208422088210e2002280238210141052104410021032009450d00200510290b20004101360200200041106a2001360200200041086a200e422086200842ffffffff0f838437020020002003410874200441ff0171723602040c0f0b200241e8006a200110bb040240024020022802684101470d00200228026c22044108762103200241e8006a41086a2903002208422088210e200241f8006a28020021010c010b2002418881046a200241fc006a2802003602002002418081046a200241f4006a29020022083703002002200229026c220e3703f88004200ea7210b2008a721034100210420022802848104210141002106024002400240024002400240024002400240024003402004411f4b0d010240024020032001460d002001417f460d072003200141016a22094f0d01200141016a2003108f01000b200220033602848104200241013a0058200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a10af04200241206a41086a200241306a41086a280200360200200220022903303703204105210a0c030b200b20016a2d0000220541ff00712004411f71742006722106200441076a2104200921012005418001710d000b200220093602848104024020044120490d00410d210a2005410f4b0d020b41002107200241003602f08004200242043703e8800420060d02410421054100210c0c030b200220013602848104410f210a0b200241e880046a41086a200241206a41086a28020022013602002002200229032022083703e880042008a721094100210420022802ec8004210b0c060b41042105410121074100210d0340024002400240024020032009460d00200941016a22012009490d0720032001490d09200b20096a2c000021042002200136028481040240200441004e0d004118210a0c020b4107210a0240200441c000710d000c020b200441807f7222044170470d02200241e8006a200241f880046a10b50420022f006d20022d006f41107472210420022d006c210a20022802684101470d0320044180feff07714108762103200228027821012002280274210b200228027021090c020b200241013a00582002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a10af04200228023021092002280234210b200228023821014105210a0b0b2002200d3602ec800420022007417f6a3602f080042003410874200441ff0171722104200d450d07200510290c070b2002280274210320022802702109024002402007417f6a2201200d460d00200d210c2001210d0c010b200d41016a2201200d490d0e200d410174220b20012001200b491b220cad420c7e2208422088a70d0e2008a722014100480d0e02400240200d0d002001103221050c010b2005200d410c6c2001103421050b2005450d05200220053602e880040b2005200d410c6c6a220120043b000120012003360208200120093602042001200a3a0000200141036a20044110763a0000024020062007460d00200741016a210720022802848104210920022802808104210320022802f88004210b200c210d0c010b0b2002200c3602ec8004200220073602f080040b2002280284810420022802888104462101024020022802fc8004450d0020022802f8800410290b2001450d052007ad422086200cad842108410521040c110b417f200141016a1030000b417f20011030000b20014104102e000b20012003108f01000b200441ffffff07712203410874200a41ff0171722104200bad220e4220862009ad84210820022802fc8004450d0120022802f8800410290c010b20024103410220011b3a00e88004200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241e880046a360218200241306a200241e8006a10af0420022903302208422088210e200228023821014105210441002103200c450d00200510290b20004101360200200041106a2001360200200041086a200e422086200842ffffffff0f838437020020002003410874200441ff0171723602040c0e0b200241e8006a200110bb040240024020022802684101470d00200228026c22014108762103200241e8006a41086a2903002208422088210e200241f8006a28020021040c010b200241fc006a280200210c200241f8006a2802002101200241f4006a2802002103200241f0006a2802002107200228026c210b41002104410021060240024002400240024002400240024002400240034002402004411f4d0d00410f21010c020b0240024020032001460d002001417f460d052003200141016a22094f0d01200141016a2003108f01000b200241013a0030200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a10af04200241206a41086a200241f880046a41086a280200360200200220022903f88004370320410521010c020b200b20016a2d0000220541ff00712004411f71742006722106200441076a2104200921012005418001710d000b20044120490d01410d210120054110490d010b200241e880046a41086a200241206a41086a28020022043602002002200229032022083703e880042008a7210320022802ec800421090c070b4100211520024100360238200242043703300240024020060d00410421054100210d0c010b410421054100210d410021150340200d21172015221141016a211520092101410021044100210a03402004411f4b0d050240024020032001460d002001417f460d062003200141016a22094f0d01200141016a2003108f01000b2002201736023420022011360238200241013a00e88004200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241e880046a360218200241f880046a200241e8006a10af0420022802f88004210320022802fc80042109200228028081042104410521010c090b200b20016a2d0000220d41ff00712004411f7174200a72210a200441076a210420092101200d418001710d000b024020044120490d00200d410f4d0d002002201736023420022011360238410d21010c070b0240024020112017460d002017210d201121170c010b201741016a22012017490d0f20174101742204200120012004491b220d41ffffffff0371200d470d0f200d41027422014100480d0f0240024020170d002001103221050c010b200520174102742001103421050b2005450d06200220053602300b200520174102746a200a36020020152006470d000b2002200d360234200220153602380b2009200c46210102402007450d00200b10290b2001450d072015ad422086200dad842108410421040c120b417f200141016a1030000b417f200141016a1030000b2002201736023420022011360238410f21010c010b20014104102e000b0b2017450d00200510290b2009ad220e4220862003ad842108410021032007450d01200b10290c010b20024103410220011b3a0030200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a10af0420022903f880042208422088210e2002280280810421044105210141002103200d450d00200510290b20004101360200200041106a2004360200200041086a200e422086200842ffffffff0f838437020020002003410874200141ff0171723602040c0d0b200241e8006a200110bb040240024020022802684101470d00200228026c22034108762101200241e8006a41086a2903002208422088210e200241f8006a28020021040c010b2002418881046a200241fc006a2802003602002002418081046a200241f4006a2902003703002002200229026c3703f8800441002101410021090240024002400240024002400240024002400240034002402001411f4d0d00410f21030c020b02400240200228028081042205200228028481042204460d00200441016a22032004490d05200520034f0d0120032005108f01000b200241013a0058200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a10af04200241206a41086a200241306a41086a28020036020020022002290330370320410521030c020b20022802f8800420046a2d00002104200220033602848104200441ff00712001411f71742009722109200141076a21012004418001710d000b20014120490d01410d210320044110490d010b200241e880046a41086a200241206a41086a28020022043602002002200229032022083703e880042008422088a721062008a721090c080b200241003602f08004200242043703e8800402400240024020090d00410421050c010b20022802ec8004210720022802f08004210d410021100340200241e8006a200241f880046a10b6042002280274210620022802702117200228026c2116024020022802684101470d002002280278210420172109201621030c090b200241e8006a200241f880046a10b6042002280274211220022802702111200228026c210f024020022802684101470d00200228027821042011210920122106200f21030c080b0240024002400240024002400240024002400240024002400240024002400240200228028081042203200228028481042205460d00200541016a22012005490d02200320014f0d0120012003108f01000b200241013a00582002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a10af04200228023021092002290234210e4105210a41002115410021030c150b20022802f88004220c20056a2d00002104200220013602848104410021150240200441034d0d004109210a410021030c150b024002400240024020040e0400010203000b41002115410021044100210a034002402004411f4d0d00410f210a0c170b0240024020032001460d002001417f460d072003200141016a220b4f0d01200141016a2003108f01000b200241013a00582002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a10af04200228023021092002290234210e4105210a410021150c180b200c20016a2d000021052002200b3602848104200541ff00712004411f7174200a72210a200441076a2104200b21012005418001710d000b4100211520044120490d0f2005410f4d0d0f410d210a0c150b0240024020032001460d00200541026a21042001417f460d0620032004490d07200c20016a2c0000210120022004360284810402402001417f4a0d00411821030c0e0b200141c000710d010c0c0b200241013a00582002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a10af042002290330210820022802382104410521030c0c0b200141807f7222014170470d0a200241e8006a200241f880046a10b50420022903702108200228026c210a024020022802684101470d00200228027821040c0d0b410121150c0f0b200241e8006a200241f880046a10b50420022903702108200228026c210a024020022802684101460d00410221150c0f0b20022002280278360270200a4180808078712115200a4180807c712103200a41087621040c0c0b0240024020032001460d00200541026a210b2001417f460d062003200b490d08200c20016a2c000021042002200b36028481040240200441004e0d004118210a410021030c170b200441c000710d010c090b200241013a00582002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a10af044105210a2002290234210e20022802302109410021030c150b200441807f72220441ff017141fc01490d07024002402003200b460d00200541036a2101200b417f460d07200320014f0d0120012003108f01000b200241013a00582002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241d8006a360218200241306a200241e8006a10af04200228023021092002290234210e4105210a410021030c150b200c200b6a2d00002105200220013602848104410021030240200541014d0d00410c210a41002115200521040c150b2004417f73210441032115024020050e020e000e0b410121030c0d0b417f20011030000b417f200141016a1030000b417f20041030000b20042003108f01000b417f200b1030000b417f20011030000b200b2003108f01000b4106210a410021030c0c0b410721030b200141ff0171410874200372210a0b20022004360270200a4180808078712115200a4180807c712103200a41087621040b20022008370368200229026c210e2008a721090c080b0b02400240200d2007460d002007210b0c010b200741016a22012007490d0f20074101742205200120012005491b220bad42287e220e422088a70d0f200ea722054100480d0f0240024020070d002005103221010c010b20022802e88004200741286c2005103421010b2001450d03200220013602e880042007210d200b21070b20022802e880042205200d41286c6a2201200f36020c200120063602082001201736020420012016360200200141206a20083702002001411c6a200a3602002001411a6a20033a0000200141196a20043a0000200141186a20153a0000200141146a2012360200200141106a2011360200200d41016a210d201041016a22102009470d000b2002200b3602ec80042002200d3602f080040b200228028481042002280288810446210120022902ec80042208422088210e024020022802fc8004450d0020022802f8800410290b200ea721032008a721092001450d072003ad4220862009ad842108410321040c120b20054104102e000b417f20031030000b0b41002103410021040b200a41ff0171200441ff0171410874722003418080fc0771722015722103200e422088a72104200ea721062011450d00200f10290b2017450d00201610290b200220073602ec80042002200d3602f0800420022802e88004210b0240200d450d00200d41286c2105200b210103400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141286a2101200541586a22050d000b0b2007450d01200b10290c010b20024103410220011b3a00e88004200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241e880046a360218200241306a200241e8006a10af04200229033021082002280238210402402003450d00200341286c21032005210103400240200141046a280200450d00200128020010290b0240200141106a280200450d002001410c6a28020010290b200141286a2101200341586a22030d000b0b2008422088210e41052103410021012009450d01200510290c010b200341087621012006ad220e4220862009ad84210820022802fc8004450d0020022802f8800410290b20004101360200200041106a2004360200200041086a200e422086200842ffffffff0f838437020020002001410874200341ff0171723602040c0c0b200241e8006a200110bb040240024020022802684101470d00200228026c22014108762103200241e8006a41086a2903002208422088210e200241f8006a28020021040c010b200241fc006a2802002114200241f8006a2802002101200241f4006a2802002103200241f0006a2802002110200228026c210b4100210441002106024002400240024002400240024002400240024002400240034002402004411f4d0d00410f21010c020b0240024020032001460d002001417f460d052003200141016a22094f0d01200141016a2003108f01000b200241013a00f88004200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241f880046a360218200241c8006a200241e8006a10af04410521010c020b200b20016a2d0000220541ff00712004411f71742006722106200441076a2104200921012005418001710d000b20044120490d01410d210120054110490d010b200241e880046a41086a200241c8006a41086a28020022043602002002200229034822083703e880042008422088a721092008a721060c0a0b200241003602602002420437035802400240024020060d00410421050c010b410020036b211b200b41026a211c410120036b21124100210a41042105410021184100211d4100211303402013211a0240024020032009460d000240200941016a22012009490d000240024020032001490d000240200b20096a2d0000220141e000460d004117210d0c100b201a41016a211341022117200941026a21014100210441032111201c211641002115024002400340201621072011210c2017210d02402004411f4d0d00410f210d0c020b02400240201220016a4102460d002001450d06200320014f0d0120012003108f01000b200241013a00302002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a10af04200241206a41086a200241f880046a41086a280200360200200220022903f880043703204105210d0c020b200b20016a417f6a2d0000220f41ff00712004411f71742015722115200d41016a2117200c41016a2111200741016a2116200141016a2101200441076a2104200f418001710d000b20044120490d01200f4110490d01410d210d0b200241e880046a41086a200241206a41086a28020022033602002002200229032022083703e880042008a721064100210120022802ec800421090c0f0b4100211720024100360238200242013703300240024020150d002001417f6a210441012116410021114100210f0c010b201b20096a211e410021044101211641002111034002400240024002400240201e200d6a450d002009200c6a2201450d02200320014f0d0120012003108f01000b200220043602342002201136023820022016360230200241013a00e880042002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241e880046a360218200241f880046a200241e8006a10af0420022802f88004210620022802fc800421092002280280810421034105210d0c130b200720096a2c000022014100480d0102400240200141c00071450d00200141807f72220141ff017141fb014b0d010b2002200436023420022011360238200220163602304106210d0c120b024020112004460d002004210f201121190c030b200441016a220f2004490d1920044101742219200f200f2019491b220f4100480d190240024020040d00200f103221160c010b20162004200f103421160b02402016450d0020042119200f21040c030b200f4101102e000b417f20011030000b2002200436023420022011360238200220163602304118210d0c0f0b201620196a2001417f733a0000200d41016a210d200c41016a210c200741016a21072015201141016a2211470d000b2002200f36023420022011360238200220163602302009200d6a21040b20164110764110742215201641087641ff0171410874221972201641ff0171221672210c4100210d024003404100210102402017411f4d0d00410f210d0c0e0b0240024020032004460d002004417f460d032003200441016a22094f0d01200441016a2003108f01000b200241013a00302002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a10af0420022802f88004210620022802fc8004210920022d00808104210320022d00818104210720022f0182810421044105210d0c0e0b200b20046a2d0000220741ff00712017411f7174200d72210d201741076a2117200921042007418001710d000b20174120490d052007410f4d0d05410d210d0c0c0b417f200441016a1030000b20012003108f01000b417f20011030000b417f20011030000b200241013a00302002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a10af0420022802f88004210620022802fc8004210920022d00808104210320022d00818104210720022f0182810421044105210d0c0b0b0240200d41014d0d004104210d4192b4c5002106412421090c060b024002400240200d0e020001000b410421040c010b20032009460d05024002400240200941016a22072009490d0020032007490d010240200b20096a2c0000220141004e0d004118210d0c0b0b4106210d200141c00071450d02200141807f72220141ff017141fb014d0d022001417f732104200721090c030b417f200941016a1030000b200941016a2003108f01000b0c070b0240201a201d470d0002402018201d460d002018211d0c010b201841016a22012018490d102018410174220d20012001200d491b221d41ffffffff0071201d470d10201d41047422014100480d100240024020180d002001103221050c010b200520184104742001103421050b2005450d032002201d36025c20022005360258201d21180b2005201a4104746a2201201f4180807c71200441ff01714108747241e00072221f36020c200120113602082001200f36020420012019201672201572360200200a41106a210a2002201336026020132006470d000b0b20092014462101200229025c2208422088210e02402010450d00200b10290b200ea721032008a721092001450d092003ad4220862009ad842108410221040c130b20014104102e000b417f200141016a1030000b200241013a00302002410136027c2002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a10af0420022802f88004210620022802fc8004210920022d00808104210320022d00818104210720022f0182810421044105210d0b0b200f450d03200c10290c030b0b2004450d00201610290b20034110762104200341087621070b200741ff0171410874200341ff017172210320044110742104200141ff017141087421070240201a450d002005210103400240200141046a280200450d00200128020010290b200141106a2101200a41706a220a0d000b0b200320047221042007200d7221012018450d01200510290c010b20024103410220011b3a0030200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a10af0420022903f88004210820022802808104210402402003450d00200341047421032005210103400240200141046a280200450d00200128020010290b200141106a2101200341706a22030d000b0b2008422088210e41052101410021032009450d01200510290c010b200141087621032009ad220e4220862006ad8421082010450d00200b10290b20004101360200200041106a2004360200200041086a200e422086200842ffffffff0f838437020020002003410874200141ff0171723602040c0b0b41002101410021040240024002400340024020094105470d00410f21070c020b0240024020032009460d00200320094b0d01200941016a2003108f01000b200241013a0030200241fc006a41013602002002420137026c200241d8e7c5003602682002412136021c2002200241186a3602782002200241306a360218200241f880046a200241e8006a10af04200241206a41086a200241f880046a41086a2802002204360200200220022903f880042208370320410521070c030b200620096a2d0000220541ff00712001411f71742004722104200141076a2101200941016a220b21092005418001710d000b20014120490d0220054110490d02410d21070b0b2008422088a721092008a7210d0c030b024020040d004100210541012115410021094100210d0c060b200241e8006a4100418008109a051a410021054100210d4101211541002107034002400240024002402003200b6b200420076b22014180082001418008491b2201490d00200b20016a220c200b490d022003200c4f0d01200c2003108f01000b200241013a00e880042002418c81046a4101360200200242013702fc8004200241d8e7c5003602f880042002412136021c2002200241186a36028881042002200241e880046a360218200241306a200241f880046a10af0420022903302208422088a72109200228023821042008a72101410521070240200d450d00201510290b2001210d0c060b200241e8006a2006200b6a2001109b051a0240200d20056b2001490d00200520016a21090c020b200520016a22092005490d03200d410174220b20092009200b491b220b4100480d0302400240200d0d00200b103221150c010b2015200d200b103421150b02402015450d00200b210d0c020b200b4101102e000b200b200c1030000b201520056a200241e8006a2001109b051a20092105200c210b2004200120076a22074d0d020c000b0b1033000b200241e8006a2015200910820420022802684101470d02410821070240200d450d00201510290b0b2009ad422086200dad84210841002101200a450d00200610290b20004101360200200041106a2004360200200041086a200837020020002001410874200741ff0171723602040c060b20154108762105200c210b0b2003200b490d012003200b6b2204417f4c0d020240024020040d004200210e410121010c010b200410322201450d042004ad210e0b2009ad4220862108200dad212020012006200b6a2004109b051a2004ad42208621210240200a450d00200610290b200820208421082021200e84210e2005410874201541ff0171722105410121040b200020043a000420004100360200200041056a20022f00153b0000200041186a200e370200200041146a20013602002000410c6a2008370200200041086a2005360200200041206a2002290204370200200041076a200241176a2d00003a0000200041286a200241046a41086a2902003702000c030b200b20031030000b102f000b20044101102e000b2002419081046a24000bf504010b7f230041c080016b220224002002200110b804410121030240024020022802004101470d0020002002290204370204200041013602002000410c6a2002410c6a2902003702000c010b200228020421042002410041808001109a052105410021064100210702400240024002402004450d00410021084100210641012103410021090340024002402001280204220a200128020822076b200420096b220b41808001200b41808001491b220b490d002007200b6a220c2007490d04200a200c4f0d01200c200a108f01000b200541013a008f8001200541b480016a4101360200200542013702a48001200541d8e7c5003602a08001200541213602bc80012005200541b880016a3602b0800120052005418f80016a3602b880012005419080016a200541a080016a10af042005418b80016a2005419880016a2802003600002005200529039080013700838001200041053a00042000200529008080013700052000410c6a2005418780016a290000370000200041013602002006450d06200310290c060b2005200128020020076a200b109b05210a2001200c36020802400240200620086b200b490d002008200b6a21070c010b2008200b6a22072008490d052006410174220c20072007200c491b220c4100480d050240024020060d00200c103221030c010b20032006200c103421030b2003450d04200c21060b200320086a200a200b109b051a200721082004200b20096a22094b0d000b0b2000200336020420004100360200200041146a2007360200200041106a41003602002000410c6a2007360200200041086a20063602000c030b2007200c1030000b200c4101102e000b1033000b200241c080016a24000b0e0020003502004101200110a7020bf60201037f230041c0006b22022400200141086a2802002103200128020421042002200128020022013602100240024002402001418080044b0d0002402004450d0020022003360214200120034b0d022003418080044d0d002002413c6a41013602002002420237022c200241c4c4c5003602282002410136021c200241a0c4c5003602182002200241186a3602382002200241286a10af040c030b200241003602000c020b2002413c6a41013602002002420237022c200241a4c4c5003602282002410136021c200241a0c4c5003602182002200241186a3602382002200241286a10af040c010b200241246a41013602002002413c6a41023602002002420237022c200241b4c4c5003602282002410136021c2002200241186a3602382002200241106a3602202002200241146a3602182002200241286a10af040b024002402002280200450d0020002002290300370200200041086a200241086a2802003602000c010b200041003602000b200241c0006a24000bf90501037f230041f0006b2204240002400240024002400240024020012802084102460d00412e10322201450d01200041013a0000200141266a41002900b8c645370000200141206a41002900b2c645370000200141186a41002900aac645370000200141106a41002900a2c645370000200141086a410029009ac64537000020014100290092c645370000200041086a42ae808080e005370200200041046a20013602000c050b02400240024002400240200128020022052d0000416e6a2201411e4b0d004100210620010e1f03000000000000000000000000000000000000000000000000000008040102030b412010322201450d05200041013a0000200141186a41002900d8c645370000200141106a41002900d0c645370000200141086a41002900c8c645370000200141002900c0c645370000200041086a42a08080808004370200200041046a20013602000c080b410221060c060b410321060c050b20042005280204220136020c0240024020012003490d0041e0c6c5002105200441e8006a2103200441d0006a2101200441c0006a21020c010b200220014101746a22012d0001450d0441f0c6c5002105200441386a2103200441206a2101200441106a21020b20034101360204200141146a410136020020012003360210200142023702042001200536020020032004410c6a3602002002200110af04200041013a00002000410c6a200241086a280200360200200041046a20022902003702000c050b410121060c030b412e4101102e000b41204101102e000b20012d000021060b0240200541106a2d00004106470d00200041003a0000200020063a00010c010b0240412910322201450d00200041013a0000200141286a41002d00a8c7453a0000200141206a41002900a0c745370000200141186a4100290098c745370000200141106a4100290090c745370000200141086a4100290088c74537000020014100290080c745370000200041086a42a98080809005370200200041046a20013602000c010b41294101102e000b200441f0006a24000b8f0201017f230041106b220224000240024002400240024020002d00000e0401020300010b2002200128021841a8e7c50041032001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c030b2002200128021841abe7c50041032001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c020b2002200128021841aee7c50041032001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c010b2002200128021841b1e7c50041032001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040b200241106a240020000bf5c30103077f027e027f230041f0006b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022d00000eac0100df010102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01000b02400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810322200450dab012003421837025c20032000360258200341d8006a4100411810c60420032003280260220041186a3602602000200328025822016a411841cec9c500411810c7042003200329025c37025c2003200136025841debec500413b200341d8006a419cbfc5001054000b02400240200128022820044103746a22052802002206200141206a28020022024b0d002006200220062002491b21040c010b024002402001411c6a280200220420026b200620026b2207490d0020012802182108200221040c010b200220076a22082002490dde0120044101742209200820082009491b22094100480dde010240024020040d002009103221080c010b200128021820042009103421080b2008450dad01200120083602182001411c6a2009360200200141206a28020021040b200820046a21090240024020074102490d002009410420062002417f736a2202109a051a2008200220046a22046a21090c010b2007450d010b200941043a0000200441016a21040b200141206a2004360200200541013a00060cde010b0240200141306a2802002204200141346a22062802004f0d002002310001210a200141206a350200210b024020042001412c6a280200470d00200441016a22022004490ddd0120044101742206200220022006491b220241ffffffff01712002470ddd01200241037422064100480ddd010240024020040d002006103221040c010b200128022820044103742006103421040b2004450dad01200120043602282001412c6a2002360200200141306a28020021040b200128022820044103746a200a422886200b84370200200141306a2201200128020041016a3602000cde010b200341ec006a220141013602002003420137025c200341c8cac500360258200341013602042003200636020020032003360268200341106a200341d8006a10af0420032802102202450ddd012003200329021437021420032002360210200141013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382201450ddd012000200329023c370204200020013602000cde010b0240200141306a2802002204200141346a22062802004f0d002002310001210a200141206a350200210b024020042001412c6a280200470d00200441016a22022004490ddc0120044101742206200220022006491b220241ffffffff01712002470ddc01200241037422064100480ddc010240024020040d002006103221040c010b200128022820044103742006103421040b2004450dad01200120043602282001412c6a2002360200200141306a28020021040b200128022820044103746a200a422886200b8442808080803084370200200141306a2201200128020041016a3602000cdd010b200341ec006a220141013602002003420137025c200341c8cac500360258200341013602042003200636020020032003360268200341106a200341d8006a10af0420032802102202450ddc012003200329021437021420032002360210200141013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382201450ddc012000200329023c370204200020013602000cdd010b2002310001210a200341d8006a200141186a200141286a2204410010c804024020032d00584101470d002000200329025c370200200041086a200341e4006a2802003602000cdd010b0240200141306a2802002202200141346a22062802004f0d00200141206a350200210b024020022001412c6a280200470d00200241016a22062002490ddb0120024101742205200620062005491b220641ffffffff01712006470ddb01200641037422054100480ddb010240024020020d002005103221020c010b200428020020024103742005103421020b2002450dad01200120023602282001412c6a2006360200200141306a28020021020b200128022820024103746a200a422886200b8442808080801084370200200141306a2201200128020041016a3602000cdc010b200341ec006a220141013602002003420137025c200341c8cac500360258200341013602042003200636020020032003360268200341106a200341d8006a10af0420032802102202450ddb012003200329021437021420032002360210200141013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382201450ddb012000200329023c370204200020013602000cdc010b02400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810322200450dac012003421837025c20032000360258200341d8006a4100411810c60420032003280260220041186a3602602000200328025822016a411841cec9c500411810c7042003200329025c37025c2003200136025841acbfc5004134200341d8006a419cbfc5001054000b02400240200141286a220228020020044103746a22042d00044101470d002004310005210a200341d8006a200141186a200210c9042003280258450d0120002003290358370200200041086a200341d8006a41086a2802003602000cdd010b411a10322201450dad01200141186a41002f00f8bf453b0000200141106a41002900f0bf45370000200141086a41002900e8bf45370000200141002900e0bf453700002000429a808080a003370204200020013602000cdc010b0240200141306a2802002204200141346a22062802004f0d00200141206a350200210b024020042001412c6a280200470d00200441016a22062004490dda0120044101742205200620062005491b220641ffffffff01712006470dda01200641037422054100480dda010240024020040d002005103221020c010b200228020020044103742005103421020b2002450daf01200120023602282001412c6a2006360200200141306a28020021040b200128022820044103746a200a422886200b8442808080802084370200200141306a2201200128020041016a3602000cdb010b200341ec006a220141013602002003420137025c200341c8cac500360258200341013602042003200636020020032003360268200341106a200341d8006a10af0420032802102202450dda012003200329021437021420032002360210200141013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382201450dda012000200329023c370204200020013602000cdb010b02400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810322200450dae012003421837025c20032000360258200341d8006a4100411810c60420032003280260220041186a3602602000200328025822016a411841cec9c500411810c7042003200329025c37025c2003200136025841acbfc5004134200341d8006a419cbfc5001054000b200141286a220528020020044103746a22042d00052106024020042d00044101470d00200641ff01714104470daf010b0240024020024101460d00200341d8006a200141186a2202200510c9042003280258450d0120002003290358370200200041086a200341d8006a41086a2802003602000cdc010b20012d003822024104460dd901200341d8006a200141186a22062005200210c8040240024020032d00584101460d000240200141206a2802002204200141246a22082802004f0d00024020042001411c6a280200470d00200441016a22082004490ddc0120044101742207200820082007491b22084100480ddc010240024020040d002008103221040c010b200628020020042008103421040b2004450db401200120043602182001411c6a2008360200200141206a28020021040b200128021820046a20023a0000200141206a2202200228020041016a3602000cdc010b200341ec006a220241013602002003420137025c200341c8cac500360258200341013602042003200836020020032003360268200341106a200341d8006a10af0420032802102204450ddb012003200329021437021420032004360210200241013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382202450ddb01200329023c210a0c010b200328025c2202450dda01200341e0006a290300210a0b2000200a370204200020023602000cdb010b200641ff01714104460dd9010240200141206a2802002204200141246a22052802004f0d00024020042001411c6a280200470d00200441016a22052004490dd90120044101742208200520052008491b22054100480dd9010240024020040d002005103221020c010b200228020020042005103421020b2002450db201200120023602182001411c6a2005360200200141206a28020021040b200128021820046a20063a0000200141206a2201200128020041016a3602000cda010b200341ec006a220141013602002003420137025c200341c8cac500360258200341013602042003200536020020032003360268200341106a200341d8006a10af0420032802102202450dd9012003200329021437021420032002360210200141013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382201450dd9012000200329023c370204200020013602000cda010b2003200241046a280200220236024802400240200141306a280200220420024d0d0020042002417f736a22022004490d0141aacac500411d109201000b200341ec006a220241023602002003411c6a41013602002003420237025c200341e8c9c50036025820034101360214200320043602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a10af04200328023821042003200329023c37021420032004360210200241013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af042003280214450dd101200328021010290cd1010b200141286a220428020020024103746a22022d00044103460dd10120022d0005220241ff01714104460dd101200341d8006a200141186a22062004200210c804024020032d00584101460d000240200141206a2802002204200141246a22052802004f0d00024020042001411c6a280200470d00200441016a22052004490dd90120044101742208200520052008491b22054100480dd9010240024020040d002005103221040c010b200628020020042005103421040b2004450db301200120043602182001411c6a2005360200200141206a28020021040b200128021820046a20023a0000200141206a2202200228020041016a3602000cd3010b200341ec006a220241013602002003420137025c200341c8cac500360258200341013602042003200536020020032003360268200341106a200341d8006a10af0420032802102204450dd2012003200329021437021420032004360210200241013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af042003280214450dd101200328021010290cd1010b200328025c2202450dd101200341e0006a290300210a0cd2010b200241046a2802002102200341d8006a200141186a2205200141286a2206410010c8040240024020032d00584101470d00200341e0006a290300210a200328025c22010d010cd9010b200141306a28020021042003200236024802400240200420024d0d0020042002417f736a22022004490d0141aacac500411d109201000b200341ec006a220141023602002003411c6a41013602002003420237025c200341e8c9c50036025820034101360214200320043602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a10af04200328023821022003200329023c37021420032002360210200141013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b200329023c210a200328023822010d010cd9010b200628020020024103746a22022d00044103460dd80120022d0005220241ff01714104460dd801200341d8006a20052006200210c804024020032d00584101460d000240200141206a2802002204200141246a22062802004f0d00024020042001411c6a280200470d00200441016a22062004490dd90120044101742208200620062008491b22064100480dd9010240024020040d002006103221040c010b200528020020042006103421040b2004450db401200120043602182001411c6a2006360200200141206a28020021040b200128021820046a20023a0000200141206a2201200128020041016a3602000cda010b200341ec006a220141013602002003420137025c200341c8cac500360258200341013602042003200636020020032003360268200341106a200341d8006a10af0420032802102202450dd9012003200329021437021420032002360210200141013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382201450dd901200329023c210a0c010b200328025c2201450dd801200341e0006a290300210a0b2000200a370204200020013602000cd8010b200241086a2802002105200241046a280200210420032002410c6a280200220636024802400240200141306a280200220220064d0d0020022006417f736a22062002490d0141aacac500411d109201000b200341ec006a22044102360200200341106a410c6a41013602002003420237025c200341e8c9c50036025820034101360214200320023602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a10af04200328023821022003200329023c37021420032002360210200441013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b2003200329023c370204200320032802383602000ccd010b410421090240200141286a220c280200220820064103746a22062d00044103460d0020062d000521090b200320093a00302005450dc801200941ff0171220d4104460dc701200541027421050340200320042802002206360248200220064d0dca0120022006417f736a220620024f0dce01200820064103746a22062d00044103460dcb0120062d000522074104460dcb01200d2007470dcb01200441046a21042005417c6a22050d000cc9010b0b20012d003822024104460dc501200341d8006a200141186a2206200141286a200210c8040240024020032d00584101460d000240200141206a2802002204200141246a22052802004f0d00024020042001411c6a280200470d00200441016a22052004490dd70120044101742208200520052008491b22054100480dd7010240024020040d002005103221040c010b200628020020042005103421040b2004450db301200120043602182001411c6a2005360200200141206a28020021040b200128021820046a20023a0000200141206a2202200228020041016a3602000cc8010b200341ec006a220241013602002003420137025c200341c8cac500360258200341013602042003200536020020032003360268200341106a200341d8006a10af0420032802102204450dc7012003200329021437021420032004360210200241013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382202450dc701200329023c210a0c010b200328025c2202450dc601200341e0006a290300210a0b2000200a370204200020023602000cd6010b200128020021042003200241046a2802002202360254024002400240200441386a28020020024b0d00200341ec006a41013602002003420237025c200341b0c8c500360258200341013602342003200341306a3602682003200341d4006a360230200341386a200341d8006a10af04200341186a200329023c370300200341013602102003200328023822043602140c010b2003200428023020024102746a2802002202360200024002402004412c6a28020020024b0d0041012106200341ec006a41013602002003420237025c200341c0c8c5003602582003410136024c2003200341c8006a36026820032003360248200341386a200341d8006a10af04200341186a200329023c220a370300200a422088a7210820032802382104200aa721020c010b2003411c6a200428022420024104746a22042d000d22083a0000200341186a2004280208220236020020042802002104410021060b20032006360210200320043602142006450d010b200341186a21010cc3010b02402002450d002004417f6a2104200141286a2106200141186a21050340200341d8006a20052006200420026a2d000010c804024020032d00584101470d00200341e0006a2101200328025c21040cc5010b2002417f6a22020d000b0b200841ff01714104460dd4010240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490dd40120024101742206200420042006491b22044100480dd4010240024020020d002004103221020c010b200128021820022004103421020b2002450db101200120023602182001411c6a2004360200200141206a28020021020b200128021820026a20083a0000200141206a2201200128020041016a3602000cd5010b200341ec006a220141013602002003420137025c200341c8cac500360258200341013602042003200436020020032003360268200341106a200341d8006a10af0420032802102202450dd4012003200329021437021420032002360210200141013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382204450dd401200329023c210a0cc3010b200241046a28020021052001280200210220034100360238024002400240200241146a2802000d00200341d8006a41146a41013602002003420237025c20034190c8c50036025820034101360204200320033602682003200341386a360200200341106a200341d8006a10af040c010b200341d8006a200141186a2204200141286a2206410010c804024020032d00584101470d00200341e0006a290300210a0cc2010b20012802002208412c6a280200210220032005360238200220054b0d01200341ec006a41013602002003420237025c200341c0c8c50036025820034101360204200320033602682003200341386a360200200341106a200341d8006a10af040b2003290214210a200328021022010dc1010cd4010b200828022420054104746a22052d000d2108024020052802082202450d002005280200417f6a21050340200341d8006a20042006200520026a2d000010c804024020032d00584101470d00200341e0006a290300210a0cc2010b2002417f6a22020d000b0b200841ff01714104460dd3010240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490dd30120024101742205200620062005491b22064100480dd3010240024020020d002006103221020c010b200428020020022006103421020b2002450db101200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20083a0000200141206a2201200128020041016a3602000cd4010b200341ec006a220141013602002003420137025c200341c8cac500360258200341013602042003200636020020032003360268200341106a200341d8006a10af0420032802102202450dd3012003200329021437021420032002360210200141013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382201450dd301200329023c210a0cc0010b200341d8006a200141186a200141286a410410c80420032d00584101470dd201200328025c2201450dd2012000200341e0006a290300370204200020013602000cd3010b200341d8006a200141186a2204200141286a2206410010c804200341d8006a21020240024020032d00584101460d00200341d8006a20042006410410c804200341d8006a210220032d00584101460d00200341d8006a2004200620032d0059220510c804200341d8006a210220032d00584101460d000240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490dd30120024101742208200620062008491b22064100480dd3010240024020020d002006103221020c010b200428020020022006103421020b2002450db201200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20053a0000200141206a2201200128020041016a3602000cd4010b200341ec006a220141013602002003420137025c200341c8cac500360258200341013602042003200636020020032003360268200341106a200341d8006a10af0420032802102202450dd3012003200329021437021420032002360210200141013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382201450dd301200329023c210a0c010b200241046a2802002201450dd201200241086a290200210a0b2000200a370204200020013602000cd2010b200341d8006a200141046a200241046a28020010ca040240024020032d00584101460d000240200141206a2802002202200141246a22042802004f0d0020032d00592104024020022001411c6a280200470d00200241016a22062002490dd20120024101742205200620062005491b22064100480dd2010240024020020d002006103221020c010b200128021820022006103421020b2002450db201200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20043a0000200141206a2201200128020041016a3602000cd3010b200341ec006a220141013602002003420137025c200341c8cac500360258200341013602042003200436020020032003360268200341106a200341d8006a10af0420032802102202450dd2012003200329021437021420032002360210200141013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382201450dd201200329023c210a0c010b200328025c2201450dd101200341e0006a290300210a0b2000200a370204200020013602000cd1010b2003200241046a2802002202360200200341d8006a200141046a200210ca04024020032d00584101470d002003200328025c22013602382003200341e0006a290300220a37023c0cbb010b200320032d005922023a0030200341d8006a200141186a200141286a410410c804024020032d00584101470d00200341c0006a200341e4006a2802003602002003200329025c3703380cba010b200320032d005922013a004820014104460dcf01200241ff01712001460dcf01200341106a41146a41273602002003411c6a4122360200200341d8006a41146a41033602002003420337025c2003419cc0c500360258200341013602142003200341106a3602682003200341c8006a3602202003200341306a36021820032003360210200341386a200341d8006a10af040cb9010b200341d8006a200141046a200241046a28020010ca040240024020032d00584101460d00200341d8006a200141186a2206200141286a20032d0059220410c804024020032d00584101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490dd10120024101742208200520052008491b22054100480dd1010240024020020d002005103221020c010b200628020020022005103421020b2002450db201200120023602182001411c6a2005360200200141206a28020021020b200128021820026a20043a0000200141206a2201200128020041016a3602000cd2010b200341ec006a220141013602002003420137025c200341c8cac500360258200341013602042003200536020020032003360268200341106a200341d8006a10af0420032802102202450dd1012003200329021437021420032002360210200141013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382201450dd101200329023c210a0c020b200328025c2201450dd001200341e0006a290300210a0c010b200328025c2201450dcf01200341e0006a290300210a0b2000200a370204200020013602000ccf010b200128020021042003200241046a280200220236023802400240200441206a28020020024d0d000240200141206a2802002206200141246a22052802004f0d00200428021820024101746a2d00002102024020062001411c6a280200470d00200641016a22042006490dcf0120064101742205200420042005491b22044100480dcf010240024020060d002004103221060c010b200128021820062004103421060b2006450db101200120063602182001411c6a2004360200200141206a28020021060b200128021820066a20023a0000200141206a2201200128020041016a3602000cd0010b200341ec006a220141013602002003420137025c200341c8cac500360258200341013602042003200536020020032003360268200341106a200341d8006a10af0420032802102202450dcf012003200329021437021420032002360210200141013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382201450dcf01200329023c210a0c010b200341ec006a41013602002003420237025c200341e0c8c5003602582003410136024c2003200341c8006a3602682003200341386a360248200341106a200341d8006a10af0420032802102201450dce012003290214210a0b2000200a370204200020013602000cce010b2003200241046a28020022023602282001280200210420032002360254024002400240200441206a28020020024b0d00200341ec006a41013602002003420237025c200341e0c8c5003602582003410136024c2003200341c8006a3602682003200341d4006a360248200341106a200341d8006a10af040c010b200428021820024101746a22022d00010d01200341ec006a41013602002003420237025c200341f0c8c50036025820034101360204200320033602682003200341d4006a360200200341106a200341d8006a10af040b2003280210210120032003290214220a37023c200320013602380cb6010b200320022d000022023a002f200341d8006a200141186a200141286a410410c804024020032d00584101470d00200341c0006a200341e4006a2802003602002003200329025c3703380cb5010b200320032d005922013a00002001200241ff0171460dcc0120014104460dcc01200341106a41146a41273602002003411c6a4127360200200341d8006a41146a41033602002003420337025c200341b4c0c500360258200341013602142003200341106a3602682003200336022020032003412f6a3602182003200341286a360210200341386a200341d8006a10af040cb4010b200341d8006a2001200241046a2802004104410010cc042003280258450dcb0120002003290358370200200041086a200341d8006a41086a2802003602000ccc010b200341d8006a2001200241046a2802004108410110cc042003280258450dca0120002003290358370200200041086a200341d8006a41086a2802003602000ccb010b200341d8006a2001200241046a2802004104410210cc042003280258450dc90120002003290358370200200041086a200341d8006a41086a2802003602000cca010b200341d8006a2001200241046a2802004108410310cc042003280258450dc80120002003290358370200200041086a200341d8006a41086a2802003602000cc9010b200341d8006a2001200241046a2802004101410010cc042003280258450dc70120002003290358370200200041086a200341d8006a41086a2802003602000cc8010b200341d8006a2001200241046a2802004101410010cc042003280258450dc60120002003290358370200200041086a200341d8006a41086a2802003602000cc7010b200341d8006a2001200241046a2802004102410010cc042003280258450dc50120002003290358370200200041086a200341d8006a41086a2802003602000cc6010b200341d8006a2001200241046a2802004102410010cc042003280258450dc40120002003290358370200200041086a200341d8006a41086a2802003602000cc5010b200341d8006a2001200241046a2802004101410110cc042003280258450dc30120002003290358370200200041086a200341d8006a41086a2802003602000cc4010b200341d8006a2001200241046a2802004101410110cc042003280258450dc20120002003290358370200200041086a200341d8006a41086a2802003602000cc3010b200341d8006a2001200241046a2802004102410110cc042003280258450dc10120002003290358370200200041086a200341d8006a41086a2802003602000cc2010b200341d8006a2001200241046a2802004102410110cc042003280258450dc00120002003290358370200200041086a200341d8006a41086a2802003602000cc1010b200341d8006a2001200241046a2802004104410110cc042003280258450dbf0120002003290358370200200041086a200341d8006a41086a2802003602000cc0010b200341d8006a2001200241046a2802004104410110cc042003280258450dbe0120002003290358370200200041086a200341d8006a41086a2802003602000cbf010b200341d8006a2001200241046a2802004104410010cd042003280258450dbd0120002003290358370200200041086a200341d8006a41086a2802003602000cbe010b200341d8006a2001200241046a2802004108410110cd042003280258450dbc0120002003290358370200200041086a200341d8006a41086a2802003602000cbd010b200341d8006a2001200241046a2802004104410210cd042003280258450dbb0120002003290358370200200041086a200341d8006a41086a2802003602000cbc010b200341d8006a2001200241046a2802004108410310cd042003280258450dba0120002003290358370200200041086a200341d8006a41086a2802003602000cbb010b200341d8006a2001200241046a2802004101410010cd042003280258450db90120002003290358370200200041086a200341d8006a41086a2802003602000cba010b200341d8006a2001200241046a2802004102410010cd042003280258450db80120002003290358370200200041086a200341d8006a41086a2802003602000cb9010b200341d8006a2001200241046a2802004101410110cd042003280258450db70120002003290358370200200041086a200341d8006a41086a2802003602000cb8010b200341d8006a2001200241046a2802004102410110cd042003280258450db60120002003290358370200200041086a200341d8006a41086a2802003602000cb7010b200341d8006a2001200241046a2802004104410110cd042003280258450db50120002003290358370200200041086a200341d8006a41086a2802003602000cb6010b20012802002102200341003602380240024020022802080d00200341ec006a41013602002003420237025c200341e0c7c50036025820034101360204200320033602682003200341386a360200200341106a200341d8006a10af0420032802102202450d002003290214210a0c010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db50120024101742206200420042006491b22044100480db5010240024020020d002004103221020c010b200128021820022004103421020b2002450d9801200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000cb6010b200341ec006a220141013602002003420137025c200341c8cac500360258200341013602042003200436020020032003360268200341106a200341d8006a10af0420032802102202450db5012003200329021437021420032002360210200141013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382202450db501200329023c210a0b2000200a370204200020023602000cb5010b20012802002102200341003602380240024020022802080d00200341ec006a41013602002003420237025c200341e0c7c50036025820034101360204200320033602682003200341386a360200200341106a200341d8006a10af0420032802102202450d002003290214210a0c010b200341d8006a200141186a2204200141286a410010c804024020032d00584101460d000240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490db50120024101742205200620062005491b22064100480db5010240024020020d002006103221020c010b200428020020022006103421020b2002450d9901200120023602182001411c6a2006360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000cb6010b200341ec006a220141013602002003420137025c200341c8cac500360258200341013602042003200636020020032003360268200341106a200341d8006a10af0420032802102202450db5012003200329021437021420032002360210200141013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382202450db501200329023c210a0c010b200328025c2202450db401200341e0006a290300210a0b2000200a370204200020023602000cb4010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db20120024101742206200420042006491b22044100480db2010240024020020d002004103221020c010b200128021820022004103421020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000cb3010b200341ec006a220141013602002003420137025c200341c8cac500360258200341013602042003200436020020032003360268200341106a200341d8006a10af0420032802102202450db2012003200329021437021420032002360210200141013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382201450db2012000200329023c370204200020013602000cb3010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db10120024101742206200420042006491b22044100480db1010240024020020d002004103221020c010b200128021820022004103421020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000cb2010b200341ec006a220141013602002003420137025c200341c8cac500360258200341013602042003200436020020032003360268200341106a200341d8006a10af0420032802102202450db1012003200329021437021420032002360210200141013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382201450db1012000200329023c370204200020013602000cb2010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490db00120024101742206200420042006491b22044100480db0010240024020020d002004103221020c010b200128021820022004103421020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000cb1010b200341ec006a220141013602002003420137025c200341c8cac500360258200341013602042003200436020020032003360268200341106a200341d8006a10af0420032802102202450db0012003200329021437021420032002360210200141013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382201450db0012000200329023c370204200020013602000cb1010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490daf0120024101742206200420042006491b22044100480daf010240024020020d002004103221020c010b200128021820022004103421020b2002450d9701200120023602182001411c6a2004360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000cb0010b200341ec006a220141013602002003420137025c200341c8cac500360258200341013602042003200436020020032003360268200341106a200341d8006a10af0420032802102202450daf012003200329021437021420032002360210200141013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382201450daf012000200329023c370204200020013602000cb0010b200341d8006a2001410010ce042003280258450dae0120002003290358370200200041086a200341d8006a41086a2802003602000caf010b200341d8006a2001410010cf042003280258450dad0120002003290358370200200041086a200341d8006a41086a2802003602000cae010b200341d8006a2001410010cf042003280258450dac0120002003290358370200200041086a200341d8006a41086a2802003602000cad010b200341d8006a2001410010cf042003280258450dab0120002003290358370200200041086a200341d8006a41086a2802003602000cac010b200341d8006a2001410010cf042003280258450daa0120002003290358370200200041086a200341d8006a41086a2802003602000cab010b200341d8006a2001410010cf042003280258450da90120002003290358370200200041086a200341d8006a41086a2802003602000caa010b200341d8006a2001410010cf042003280258450da80120002003290358370200200041086a200341d8006a41086a2802003602000ca9010b200341d8006a2001410010cf042003280258450da70120002003290358370200200041086a200341d8006a41086a2802003602000ca8010b200341d8006a2001410010cf042003280258450da60120002003290358370200200041086a200341d8006a41086a2802003602000ca7010b200341d8006a2001410010cf042003280258450da50120002003290358370200200041086a200341d8006a41086a2802003602000ca6010b200341d8006a2001410010cf042003280258450da40120002003290358370200200041086a200341d8006a41086a2802003602000ca5010b200341d8006a2001410110ce042003280258450da30120002003290358370200200041086a200341d8006a41086a2802003602000ca4010b200341d8006a2001410110cf042003280258450da20120002003290358370200200041086a200341d8006a41086a2802003602000ca3010b200341d8006a2001410110cf042003280258450da10120002003290358370200200041086a200341d8006a41086a2802003602000ca2010b200341d8006a2001410110cf042003280258450da00120002003290358370200200041086a200341d8006a41086a2802003602000ca1010b200341d8006a2001410110cf042003280258450d9f0120002003290358370200200041086a200341d8006a41086a2802003602000ca0010b200341d8006a2001410110cf042003280258450d9e0120002003290358370200200041086a200341d8006a41086a2802003602000c9f010b200341d8006a2001410110cf042003280258450d9d0120002003290358370200200041086a200341d8006a41086a2802003602000c9e010b200341d8006a2001410110cf042003280258450d9c0120002003290358370200200041086a200341d8006a41086a2802003602000c9d010b200341d8006a2001410110cf042003280258450d9b0120002003290358370200200041086a200341d8006a41086a2802003602000c9c010b200341d8006a2001410110cf042003280258450d9a0120002003290358370200200041086a200341d8006a41086a2802003602000c9b010b200341d8006a2001410110cf042003280258450d990120002003290358370200200041086a200341d8006a41086a2802003602000c9a010b200341d8006a2001410210cf042003280258450d980120002003290358370200200041086a200341d8006a41086a2802003602000c99010b200341d8006a2001410210cf042003280258450d970120002003290358370200200041086a200341d8006a41086a2802003602000c98010b200341d8006a2001410210cf042003280258450d960120002003290358370200200041086a200341d8006a41086a2802003602000c97010b200341d8006a2001410210cf042003280258450d950120002003290358370200200041086a200341d8006a41086a2802003602000c96010b200341d8006a2001410210cf042003280258450d940120002003290358370200200041086a200341d8006a41086a2802003602000c95010b200341d8006a2001410210cf042003280258450d930120002003290358370200200041086a200341d8006a41086a2802003602000c94010b200341d8006a2001410310cf042003280258450d920120002003290358370200200041086a200341d8006a41086a2802003602000c93010b200341d8006a2001410310cf042003280258450d910120002003290358370200200041086a200341d8006a41086a2802003602000c92010b200341d8006a2001410310cf042003280258450d900120002003290358370200200041086a200341d8006a41086a2802003602000c91010b200341d8006a2001410310cf042003280258450d8f0120002003290358370200200041086a200341d8006a41086a2802003602000c90010b200341d8006a2001410310cf042003280258450d8e0120002003290358370200200041086a200341d8006a41086a2802003602000c8f010b200341d8006a2001410310cf042003280258450d8d0120002003290358370200200041086a200341d8006a41086a2802003602000c8e010b200341d8006a2001410010d0042003280258450d8c0120002003290358370200200041086a200341d8006a41086a2802003602000c8d010b200341d8006a2001410010d0042003280258450d8b0120002003290358370200200041086a200341d8006a41086a2802003602000c8c010b200341d8006a2001410010d0042003280258450d8a0120002003290358370200200041086a200341d8006a41086a2802003602000c8b010b200341d8006a2001410010d1042003280258450d890120002003290358370200200041086a200341d8006a41086a2802003602000c8a010b200341d8006a2001410010d1042003280258450d880120002003290358370200200041086a200341d8006a41086a2802003602000c89010b200341d8006a2001410010d1042003280258450d870120002003290358370200200041086a200341d8006a41086a2802003602000c88010b200341d8006a2001410010d1042003280258450d860120002003290358370200200041086a200341d8006a41086a2802003602000c87010b200341d8006a2001410010d1042003280258450d850120002003290358370200200041086a200341d8006a41086a2802003602000c86010b200341d8006a2001410010d1042003280258450d840120002003290358370200200041086a200341d8006a41086a2802003602000c85010b200341d8006a2001410010d1042003280258450d830120002003290358370200200041086a200341d8006a41086a2802003602000c84010b200341d8006a2001410010d1042003280258450d820120002003290358370200200041086a200341d8006a41086a2802003602000c83010b200341d8006a2001410010d1042003280258450d810120002003290358370200200041086a200341d8006a41086a2802003602000c82010b200341d8006a2001410010d1042003280258450d800120002003290358370200200041086a200341d8006a41086a2802003602000c81010b200341d8006a2001410010d1042003280258450d7f20002003290358370200200041086a200341d8006a41086a2802003602000c80010b200341d8006a2001410010d1042003280258450d7e20002003290358370200200041086a200341d8006a41086a2802003602000c7f0b200341d8006a2001410010d1042003280258450d7d20002003290358370200200041086a200341d8006a41086a2802003602000c7e0b200341d8006a2001410010d1042003280258450d7c20002003290358370200200041086a200341d8006a41086a2802003602000c7d0b200341d8006a2001410010d1042003280258450d7b20002003290358370200200041086a200341d8006a41086a2802003602000c7c0b200341d8006a2001410110d0042003280258450d7a20002003290358370200200041086a200341d8006a41086a2802003602000c7b0b200341d8006a2001410110d0042003280258450d7920002003290358370200200041086a200341d8006a41086a2802003602000c7a0b200341d8006a2001410110d0042003280258450d7820002003290358370200200041086a200341d8006a41086a2802003602000c790b200341d8006a2001410110d1042003280258450d7720002003290358370200200041086a200341d8006a41086a2802003602000c780b200341d8006a2001410110d1042003280258450d7620002003290358370200200041086a200341d8006a41086a2802003602000c770b200341d8006a2001410110d1042003280258450d7520002003290358370200200041086a200341d8006a41086a2802003602000c760b200341d8006a2001410110d1042003280258450d7420002003290358370200200041086a200341d8006a41086a2802003602000c750b200341d8006a2001410110d1042003280258450d7320002003290358370200200041086a200341d8006a41086a2802003602000c740b200341d8006a2001410110d1042003280258450d7220002003290358370200200041086a200341d8006a41086a2802003602000c730b200341d8006a2001410110d1042003280258450d7120002003290358370200200041086a200341d8006a41086a2802003602000c720b200341d8006a2001410110d1042003280258450d7020002003290358370200200041086a200341d8006a41086a2802003602000c710b200341d8006a2001410110d1042003280258450d6f20002003290358370200200041086a200341d8006a41086a2802003602000c700b200341d8006a2001410110d1042003280258450d6e20002003290358370200200041086a200341d8006a41086a2802003602000c6f0b200341d8006a2001410110d1042003280258450d6d20002003290358370200200041086a200341d8006a41086a2802003602000c6e0b200341d8006a2001410110d1042003280258450d6c20002003290358370200200041086a200341d8006a41086a2802003602000c6d0b200341d8006a2001410110d1042003280258450d6b20002003290358370200200041086a200341d8006a41086a2802003602000c6c0b200341d8006a2001410110d1042003280258450d6a20002003290358370200200041086a200341d8006a41086a2802003602000c6b0b200341d8006a2001410110d1042003280258450d6920002003290358370200200041086a200341d8006a41086a2802003602000c6a0b200341d8006a2001410210d0042003280258450d6820002003290358370200200041086a200341d8006a41086a2802003602000c690b200341d8006a2001410210d0042003280258450d6720002003290358370200200041086a200341d8006a41086a2802003602000c680b200341d8006a2001410210d0042003280258450d6620002003290358370200200041086a200341d8006a41086a2802003602000c670b200341d8006a2001410210d0042003280258450d6520002003290358370200200041086a200341d8006a41086a2802003602000c660b200341d8006a2001410210d0042003280258450d6420002003290358370200200041086a200341d8006a41086a2802003602000c650b200341d8006a2001410210d0042003280258450d6320002003290358370200200041086a200341d8006a41086a2802003602000c640b200341d8006a2001410210d0042003280258450d6220002003290358370200200041086a200341d8006a41086a2802003602000c630b200341d8006a2001410210d1042003280258450d6120002003290358370200200041086a200341d8006a41086a2802003602000c620b200341d8006a2001410210d1042003280258450d6020002003290358370200200041086a200341d8006a41086a2802003602000c610b200341d8006a2001410210d1042003280258450d5f20002003290358370200200041086a200341d8006a41086a2802003602000c600b200341d8006a2001410210d1042003280258450d5e20002003290358370200200041086a200341d8006a41086a2802003602000c5f0b200341d8006a2001410210d1042003280258450d5d20002003290358370200200041086a200341d8006a41086a2802003602000c5e0b200341d8006a2001410210d1042003280258450d5c20002003290358370200200041086a200341d8006a41086a2802003602000c5d0b200341d8006a2001410210d1042003280258450d5b20002003290358370200200041086a200341d8006a41086a2802003602000c5c0b200341d8006a2001410310d0042003280258450d5a20002003290358370200200041086a200341d8006a41086a2802003602000c5b0b200341d8006a2001410310d0042003280258450d5920002003290358370200200041086a200341d8006a41086a2802003602000c5a0b200341d8006a2001410310d0042003280258450d5820002003290358370200200041086a200341d8006a41086a2802003602000c590b200341d8006a2001410310d0042003280258450d5720002003290358370200200041086a200341d8006a41086a2802003602000c580b200341d8006a2001410310d0042003280258450d5620002003290358370200200041086a200341d8006a41086a2802003602000c570b200341d8006a2001410310d0042003280258450d5520002003290358370200200041086a200341d8006a41086a2802003602000c560b200341d8006a2001410310d0042003280258450d5420002003290358370200200041086a200341d8006a41086a2802003602000c550b200341d8006a2001410310d1042003280258450d5320002003290358370200200041086a200341d8006a41086a2802003602000c540b200341d8006a2001410310d1042003280258450d5220002003290358370200200041086a200341d8006a41086a2802003602000c530b200341d8006a2001410310d1042003280258450d5120002003290358370200200041086a200341d8006a41086a2802003602000c520b200341d8006a2001410310d1042003280258450d5020002003290358370200200041086a200341d8006a41086a2802003602000c510b200341d8006a2001410310d1042003280258450d4f20002003290358370200200041086a200341d8006a41086a2802003602000c500b200341d8006a2001410310d1042003280258450d4e20002003290358370200200041086a200341d8006a41086a2802003602000c4f0b200341d8006a2001410310d1042003280258450d4d20002003290358370200200041086a200341d8006a41086a2802003602000c4e0b200341d8006a20014101410010d2042003280258450d4c20002003290358370200200041086a200341d8006a41086a2802003602000c4d0b200341d8006a20014102410010d2042003280258450d4b20002003290358370200200041086a200341d8006a41086a2802003602000c4c0b200341d8006a20014102410010d2042003280258450d4a20002003290358370200200041086a200341d8006a41086a2802003602000c4b0b200341d8006a20014103410010d2042003280258450d4920002003290358370200200041086a200341d8006a41086a2802003602000c4a0b200341d8006a20014103410010d2042003280258450d4820002003290358370200200041086a200341d8006a41086a2802003602000c490b200341d8006a20014100410110d2042003280258450d4720002003290358370200200041086a200341d8006a41086a2802003602000c480b200341d8006a20014100410110d2042003280258450d4620002003290358370200200041086a200341d8006a41086a2802003602000c470b200341d8006a20014102410110d2042003280258450d4520002003290358370200200041086a200341d8006a41086a2802003602000c460b200341d8006a20014102410110d2042003280258450d4420002003290358370200200041086a200341d8006a41086a2802003602000c450b200341d8006a20014103410110d2042003280258450d4320002003290358370200200041086a200341d8006a41086a2802003602000c440b200341d8006a20014103410110d2042003280258450d4220002003290358370200200041086a200341d8006a41086a2802003602000c430b200341d8006a20014100410210d2042003280258450d4120002003290358370200200041086a200341d8006a41086a2802003602000c420b200341d8006a20014100410210d2042003280258450d4020002003290358370200200041086a200341d8006a41086a2802003602000c410b200341d8006a20014101410210d2042003280258450d3f20002003290358370200200041086a200341d8006a41086a2802003602000c400b200341d8006a20014101410210d2042003280258450d3e20002003290358370200200041086a200341d8006a41086a2802003602000c3f0b200341d8006a20014103410210d2042003280258450d3d20002003290358370200200041086a200341d8006a41086a2802003602000c3e0b200341d8006a20014100410310d2042003280258450d3c20002003290358370200200041086a200341d8006a41086a2802003602000c3d0b200341d8006a20014100410310d2042003280258450d3b20002003290358370200200041086a200341d8006a41086a2802003602000c3c0b200341d8006a20014101410310d2042003280258450d3a20002003290358370200200041086a200341d8006a41086a2802003602000c3b0b200341d8006a20014101410310d2042003280258450d3920002003290358370200200041086a200341d8006a41086a2802003602000c3a0b200341d8006a20014102410310d2042003280258450d3820002003290358370200200041086a200341d8006a41086a2802003602000c390b200341d8006a20014102410010d2042003280258450d3720002003290358370200200041086a200341d8006a41086a2802003602000c380b200341d8006a20014103410110d2042003280258450d3620002003290358370200200041086a200341d8006a41086a2802003602000c370b200341d8006a20014100410210d2042003280258450d3520002003290358370200200041086a200341d8006a41086a2802003602000c360b200341d8006a20014101410310d20420032802580d1b0c340b41184101102e000b20094101102e000b20064104102e000b20064104102e000b20054104102e000b41184101102e000b411a4101102e000b20054104102e000b41184101102e000b200341ec006a41013602002003420237025c200341fcbfc5003602582003412836023c2003200441056a3602382003200341386a360268200341106a200341d8006a10af04200041086a200341106a41086a280200360200200020032903103702000c2b0b20084101102e000b20054101102e000b20054101102e000b20064101102e000b20054101102e000b20044101102e000b20064101102e000b20064101102e000b20064101102e000b20054101102e000b20044101102e000b20044101102e000b20064101102e000b20044101102e000b20044101102e000b20044101102e000b20044101102e000b20002003290358370200200041086a200341d8006a41086a2802003602000c190b200329023c210a200328023821010b2001450d162000200a370204200020013602000c170b200329023c210a200328023821010b2001450d142000200a370204200020013602000c150b200328025c2201450d130b2000200a370204200020013602000c130b2004450d112001290200210a0b2000200a370204200020043602000c110b0240024002400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810322200450d012003421837025c20032000360258200341d8006a4100411810c60420032003280260220041186a3602602000200328025822016a411841cec9c500411810c7042003200329025c37025c2003200136025841debec500413b200341d8006a419cbfc5001054000b02400240200128022820044103746a22052802002206200141206a28020022024b0d002006200220062002491b21040c010b024002402001411c6a280200220420026b200620026b2207490d0020012802182108200221040c010b200220076a22082002490d1120044101742209200820082009491b22094100480d110240024020040d002009103221080c010b200128021820042009103421080b2008450d03200120083602182001411c6a2009360200200141206a28020021040b200820046a21090240024020074102490d002009410420062002417f736a2202109a051a2008200220046a22046a21090c010b2007450d010b200941043a0000200441016a21040b200141206a2004360200200541013a00060c110b41184101102e000b20094101102e000b200541027421050340200320042802002206360248200220064d0d0220022006417f736a220620024f0d060240200820064103746a22062d00044103460d0020062d00054104470d040b200441046a21042005417c6a22050d000b410421090b200341d8006a200141186a2202200c410010c80420032d00584101470d02200341086a200341e4006a2802003602002003200329025c3703000c030b200341ec006a220441023602002003411c6a41013602002003420237025c200341e8c9c50036025820034101360214200320023602002003200341106a360268200320033602182003200341c8006a360210200341386a200341d8006a10af04200328023821022003200329023c37021420032002360210200441013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b2003200329023c370204200320032802383602000c020b2003411c6a4128360200200341ec006a41023602002003420237025c2003418cc0c5003602582003200641056a360218200341283602142003200341106a3602682003200341306a3602102003200341d8006a10af040c010b0240200941ff01714104460d00200341d8006a2002200c200910c80402400240024020032d00584101460d000240200141206a2802002204200141246a22062802004f0d00024020042001411c6a280200470d00200441016a22062004490d0e20044101742205200620062005491b22064100480d0e0240024020040d002006103221020c010b200228020020042006103421020b2002450d04200120023602182001411c6a2006360200200141206a28020021040b200128021820046a20093a0000200141206a2202200228020041016a3602000c040b200341ec006a220241013602002003420137025c200341c8cac500360258200341013602042003200636020020032003360268200341106a200341d8006a10af0420032802102204450d032003200329021437021420032004360210200241013602002003420137025c20034190c4c50036025820034123360204200320033602682003200341106a360200200341386a200341d8006a10af0402402003280214450d00200328021010290b20032802382202450d03200329023c210a0c010b200328025c2202450d02200341e0006a290300210a0b2003200a370204200320023602000c020b20064101102e000b200341003602000b024020032802002202450d0020002003290204370204200020023602000c0b0b0240024002400240200141306a2802002202417f6a220420024f0d00200420024d0d010b411810322200450d012003421837025c20032000360258200341d8006a4100411810c60420032003280260220041186a3602602000200328025822016a411841cec9c500411810c7042003200329025c37025c2003200136025841debec500413b200341d8006a419cbfc5001054000b02400240200128022820044103746a22052802002206200141206a28020022024b0d002006200220062002491b21040c010b024002402001411c6a280200220420026b200620026b2207490d0020012802182108200221040c010b200220076a22082002490d0b20044101742209200820082009491b22094100480d0b0240024020040d002009103221080c010b200128021820042009103421080b2008450d03200120083602182001411c6a2009360200200141206a28020021040b200820046a21090240024020074102490d002009410420062002417f736a2202109a051a2008200220046a22046a21090c010b2007450d010b200941043a0000200441016a21040b200141206a2004360200200541013a00060c0b0b41184101102e000b20094101102e000b41aacac500411d109201000b20032802382202450d00200329023c210a0c010b0240200141306a2802002202417f6a220420024f0d00200420024d0d020b411810322200450d022003421837025c20032000360258200341d8006a4100411810c60420032003280260220041186a3602602000200328025822016a411841cec9c500411810c7042003200329025c37025c2003200136025841debec500413b200341d8006a419cbfc5001054000b2000200a370204200020023602000c060b02400240200128022820044103746a22052802002206200141206a28020022024b0d002006200220062002491b21040c010b024002402001411c6a280200220420026b200620026b2207490d0020012802182108200221040c010b200220076a22082002490d0420044101742209200820082009491b22094100480d040240024020040d002009103221080c010b200128021820042009103421080b2008450d03200120083602182001411c6a2009360200200141206a28020021040b200820046a21090240024020074102490d002009410420062002417f736a2202109a051a2008200220046a22046a21090c010b2007450d010b200941043a0000200441016a21040b200141206a2004360200200541013a00060c040b41184101102e000b20094101102e000b1033000b200341d8006a200141186a200510c9042003280258450d0020002003290358370200200041086a200341d8006a41086a2802003602000c010b200041003602000b200341f0006a24000b6501017f230041206b2202240020024129360204200220003602002001411c6a2802002100200128021821012002411c6a41013602002002420137020c200241f8a9c6003602082002200236021820012000200241086a10d8042101200241206a240020010b0c002000280200200110da040bcd0201067f02400240024002402001450d0020014108490d010240200141ffffffff01712001470d00200141037441076e21010c030b41ccbdc500106d000b200041106a4200370200200041086a4280808080c000370200200041046a41e4bdc5003602000c020b200141016a21010b02400240417f2001417f6a6776220141016a220241ffffffff01712002470d00200141086a417c712203200141056a2204490d00200320024103746a22052003490d002005417d4f0d00200510322206450d012001200241037641076c20014108491b2107200641ff012004109a05220520036a21030240200241034b0d00200520026a418001410320016b109a051a0b200041146a2007360200200041106a41003602002000410c6a2003360200200041086a2001360200200041046a20053602000c020b41ccbdc500106d000b20054104102e000b200041003a00000b9d0d02107f017e230041206b220124000240024002400240200028020c220241016a22032002490d00200041046a28020022022104024020024108490d00200241016a41037641076c21040b024020032004410176490d00200141086a200310c30420012d00084101460d042001411c6a2802002105200141146a2802002106200141106a2802002107200128020c210820002802002209280200417f7341808182847871210a200041046a28020020096a41016a210b2000280208210c200028020c210d03400240024002400240200a0d00200941046a210203402002200b4f0d02200c41206a210c20022802002103200241046a220421022003418081828478712203418081828478460d000b200341808182847873210a2004417c6a21090b200c200a684138716a220e280200210f410021030240200e41046a28020022104104490d0041002103200f2102201021040340200228000020034105777341b9f3ddf1796c2103200241046a21022004417c6a220441034b0d000b2010417c6a22022002417c7122026b21102002200f6a41046a210f0b201041014b0d01200f21040c020b2000200d36020c2000200636020820002005200d6b3602102000280200210420002008360200200041046a22032802002102200320073602002002450d070240200241016a220341ffffffff01712003470d00200241086a417c712208200241056a490d00200820034103746a2008491a0b200410290c070b200f41026a21042010417e6a21102003410577200f2f00007341b9f3ddf1796c21030b200a417f6a210202402010450d00200341057720042d00007341b9f3ddf1796c21030b2002200a71210a41002102200341057741ff017341b9f3ddf1796c220f21030340200241046a2202200320077122046a2103200820046a280000418081828478712210450d000b0240200820106841037620046a20077122026a2c00004100480d002008280200418081828478716841037621020b200820026a200f41197622033a00002002417c6a20077120086a41046a20033a0000200620024103746a200e2902003702000c000b0b200241016a21044100210341002102024003400240024020034101710d00200220044f0d0320022103200241016a21020c010b200241036a220320024922080d0220032004492207450d022004200241046a20081b200420071b21020b200028020020036a220320032802002203410776417f73418182840871200341fffefdfb07726a360200410121030c000b0b20002802002102200041046a220428020041016a220341044f0d01200241046a20022003109c051a2004280200220220002802006a41016a418001410320026b109a051a0c020b41ccbdc500106d000b200220036a20022800003600000b417f210202400240200041046a2206280200220341016a220f2003490d00200041086a21094100210b0340200b220c41016a210b0240200c20002802006a2d0000418001470d00024003402009280200200c4103746a220e2802002107410021030240200e41046a28020022084104490d004100210320072102200821040340200228000020034105777341b9f3ddf1796c2103200241046a21022004417c6a220441034b0d000b2008417c6a22022002417c7122026b2108200220076a41046a21070b02400240200841014b0d00200721020c010b200741026a21022008417e6a2108200341057720072f00007341b9f3ddf1796c21030b02402008450d00200341057720022d00007341b9f3ddf1796c21030b200628020021082000280200210741002102200341057741ff017341b9f3ddf1796c220a21030340200241046a2202200320087122046a2103200720046a280000418081828478712210450d000b0240200720106841037620046a20087122026a2c00004100480d002007280200418081828478716841037621020b2002200a20087122036b200c20036b732008714104490d01200720026a22032d000021042003200a41197622103a00002002417c6a20087120076a41046a20103a00000240200441ff01460d00200928020020024103746a220229020021112002200e290200370200200e20113702000c010b0b20002802002203200c6a41ff013a000020032006280200200c417c6a716a41046a41ff013a0000200928020020024103746a200e2902003702000c010b2007200c6a200a41197622023a00002008200c417c6a7120076a41046a20023a00000b200b200f470d000b200041046a28020022024108490d010b200241016a41037641076c21020b20002002200028020c6b3602100b200141206a24000b19002000200141186a280200360204200020012802103602000b810101017f024002400240200041046a280200220320016b20024f0d00200120026a22022001490d0220034101742201200220022001491b22014100480d020240024020030d002001103221020c010b200028020020032001103421020b2002450d0120002002360200200041046a20013602000b0f0b20014101102e000b1033000bd90101017f230041e0006b22042400200420013602082004200336020c024020012003470d00200020022001109b051a200441e0006a24000f0b200441286a41146a4102360200200441346a4103360200200441106a41146a410336020020044203370214200441acf9c5003602102004410336022c2004200441086a36024020042004410c6a360244200442043703582004420137024c20044180fac5003602482004200441286a3602202004200441c8006a3602382004200441c4006a3602302004200441c0006a360228200441106a41bcfac500107d000bbb0601037f230041d0006b22042400200420033a000f0240024002400240024020022802082205417f6a220620054f0d00200620054d0d010b411810322202450d012004421837023420042002360230200441306a4100411810c60420042004280238220241186a3602382002200428023022056a411841cec9c500411810c704200420042902343702342004200536023041acbfc5004134200441306a419cbfc5001054000b200141086a2802002105200228020020064103746a2206280200210202400240024020062d0006450d0020052002460d010b024002400240200520024d0d00200141086a2005417f6a2202360200200128020020026a2d00002205417c6a220241014b0d02024020020e020400040b4118103222020d0141184101102e000b412b10322202450d05200041013a0000200241276a41002800cac345360000200241206a41002900c3c345370000200241186a41002900bbc345370000200241106a41002900b3c345370000200241086a41002900abc345370000200241002900a3c345370000200041086a42ab808080b005370200200041046a20023602000c060b200241106a41002900dec945370000200241086a41002900d6c945370000200241002900cec94537000020044298808080800337022420042002360220200441c4006a41013602002004420137023420044190c4c5003602302004412336024c2004200441c8006a3602402004200441206a360248200441106a200441306a10af0402402004280224450d00200428022010290b200041013a0000200041046a20042903103702002000410c6a200441106a41086a2802003602000c050b0240200341ff017122024104460d0020052002470d020b200041003a0000200020053a00010c040b20004180083b01000c030b200420053a0048200441c4006a4102360200200441206a410c6a412736020020044202370234200441d0c3c500360230200441273602242004200441206a3602402004200441c8006a36022820042004410f6a360220200441106a200441306a10af042000410c6a200441186a280200360200200041046a2004290310370200200041013a00000c020b41184101102e000b412b4101102e000b200441d0006a24000bc00502047f017e230041d0006b22032400024002400240024002400240200241086a2802002204417f6a220520044f0d00200520044d0d010b411810322202450d01200241106a41002900dec945370000200241086a41002900d6c945370000200241002900cec94537000020034298808080800337022420032002360220200341cc006a41013602002003420137023c20034190c4c500360238200341233602142003200341106a3602482003200341206a3602102000200341386a10af042003280224450d04200328022010290c040b0240024002402002280200220620054103746a2d000522054104460d00200341386a20012002200510c804024020032d00384101470d002000200329023c370200200041086a200341c4006a2802003602000c070b200241086a2802002204450d01200228020021060b200241086a2004417f6a2202360200200620024103746a290200220742808080808080c0ff0083428080808080808001520d010b411810322202450d02200241106a41002900dec945370000200241086a41002900d6c945370000200241002900cec94537000020034298808080800337022420032002360220200341cc006a41013602002003420137023c20034190c4c500360238200341233602142003200341106a3602482003200341206a3602102000200341386a10af042003280224450d04200328022010290c040b200141086a28020021022003200737030820022007a7470d02200041003602000c030b41184101102e000b41184101102e000b200341cc006a41023602002003412c6a41013602002003420237023c200341f0c2c50036023820034101360224200320023602342003200341206a3602482003200341086a3602282003200341346a360220200341106a200341386a10af04200041086a200341106a41086a280200360200200020032903103702000b200341d0006a24000bad0301057f230041c0006b2203240020032002360200024002402001280204220420024b0d002001280208417c6a21052001410c6a280200410374210102400340024020010d00200320043602042003412c6a4102360200200341306a410c6a41013602002003420337021c20034198cbc500360218200341013602342003200341306a3602282003200341046a36023820032003360230200341086a200341186a10af042000410c6a200341106a280200360200200041046a2003290308370200200041013a00000c040b02402004200541046a2802006a220620044f0d00412010322204450d02200041013a0000200441186a4100290090cb45370000200441106a4100290088cb45370000200441086a4100290080cb45370000200441002900f8ca45370000200041086a42a08080808004370200200041046a20043602000c040b200141786a2101200541086a2105200420024b21072006210420070d0020062104200620024d0d000b20052d00002104200041003a0000200020043a00010c020b41204101102e000b200041003a00002000200128020020026a2d00003a00010b200341c0006a24000bbe0201037f230041106b220224000240024020002d00004104470d002002200128021841ccc1c50041032001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c010b2002200128021841cfc1c50041082001411c6a28020028020c1104003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a41d8c1c50010d404210120022d0008210020022802042203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d004101210020042802184194abc60041012004411c6a28020028020c1104000d010b2001280200220028021841cbaac60041012000411c6a28020028020c11040021000b200120003a00080b200241106a2400200041ff01714100470b820601037f230041d0006b22052400200520023602082005200336020c024002400240417f41012002411f71742002411f4b1b20034b0d00200541386a200141186a2203200141286a410010c80420052d00384101470d012000200529023c370200200041086a200541c4006a2802003602000c020b200541cc006a41023602002005411c6a41013602002005420337023c200541ccc0c500360238200541013602142005200541106a36024820052005410c6a3602182005200541086a360210200541206a200541386a10af04200041086a200541206a41086a280200360200200020052903203702000c010b2001280200210220054100360220024020022802080d00200541cc006a41013602002005420237023c200541e0c7c500360238200541013602342005200541306a3602482005200541206a360230200541106a200541386a10af0420052802102202450d0020002005290214370204200020023602000c010b0240024002400240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490d0320024101742207200620062007491b22064100480d030240024020020d002006103221020c010b200328020020022006103421020b2002450d02200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20043a0000200141206a2202200228020041016a3602000c030b200541cc006a220241013602002005420137023c200541c8cac50036023820054101360234200520063602302005200541306a360248200541106a200541386a10af0420052802102201450d022005200529021437021420052001360210200241013602002005420137023c20054190c4c500360238200541233602342005200541306a3602482005200541106a360230200541206a200541386a10af0402402005280214450d00200528021010290b20052802202202450d0220002005290224370204200020023602000c030b20064101102e000b1033000b200041003602000b200541d0006a24000bb00301017f230041d0006b22052400200520023602082005200336020c024002400240417f41012002411f71742002411f4b1b20034b0d00200128020021022005410036023420022802080d01200541cc006a41013602002005420237023c200541e0c7c500360238200541013602142005200541106a3602482005200541346a360210200541206a200541386a10af0420052802202202450d0120002005290224370204200020023602000c020b200541cc006a41023602002005412c6a41013602002005420337023c200541ccc0c500360238200541013602242005200541206a36024820052005410c6a3602282005200541086a360220200541106a200541386a10af04200041086a200541106a41086a280200360200200020052903103702000c010b200541386a200141186a2202200141286a2203200410c804024020052d00384101470d002000200529023c370200200041086a200541c4006a2802003602000c010b200541386a20022003410010c804024020052d00384101470d002000200529023c370200200041086a200541c4006a2802003602000c010b200041003602000b200541d0006a24000be70301047f230041c0006b22032400200341286a200141186a2204200141286a200210c8040240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d0320024101742206200520052006491b22054100480d030240024020020d002005103221020c010b200428020020022005103421020b2002450d02200120023602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c200341c8cac50036022820034101360214200320053602102003200341106a360238200341186a200341286a10af0420032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c20034190c4c500360228200341233602142003200341106a3602382003200341186a3602102003200341286a10af040240200328021c450d00200328021810290b20032802002201450d0220002003290204370204200020013602000c030b20054101102e000b1033000b200041003602000b200341c0006a24000ba00401047f230041c0006b22032400200341286a200141186a2204200141286a2205200210c8040240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b200341286a20042005200210c804024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d0320024101742206200520052006491b22054100480d030240024020020d002005103221020c010b200428020020022005103421020b2002450d02200120023602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c200341c8cac50036022820034101360214200320053602102003200341106a360238200341186a200341286a10af0420032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c20034190c4c500360228200341233602142003200341106a3602382003200341186a3602102003200341286a10af040240200328021c450d00200328021810290b20032802002201450d0220002003290204370204200020013602000c030b20054101102e000b1033000b200041003602000b200341c0006a24000be70301057f230041c0006b22032400200341286a200141186a2204200141286a200210c8040240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002205200141246a22062802004f0d00024020052001411c6a280200470d00200541016a22062005490d0320054101742207200620062007491b22064100480d030240024020050d002006103221050c010b200428020020052006103421050b2005450d02200120053602182001411c6a2006360200200141206a28020021050b200128021820056a20023a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c200341c8cac50036022820034101360214200320063602102003200341106a360238200341186a200341286a10af0420032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c20034190c4c500360228200341233602142003200341106a3602382003200341186a3602102003200341286a10af040240200328021c450d00200328021810290b20032802002201450d0220002003290204370204200020013602000c030b20064101102e000b1033000b200041003602000b200341c0006a24000ba00401057f230041c0006b22032400200341286a200141186a2204200141286a2205200210c8040240024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b200341286a20042005200210c804024020032d00284101470d002000200329022c370200200041086a200341346a2802003602000c010b0240024002400240200141206a2802002205200141246a22062802004f0d00024020052001411c6a280200470d00200541016a22062005490d0320054101742207200620062007491b22064100480d030240024020050d002006103221040c010b200428020020052006103421040b2004450d02200120043602182001411c6a2006360200200141206a28020021050b200128021820056a20023a0000200141206a2201200128020041016a3602000c030b2003413c6a220141013602002003420137022c200341c8cac50036022820034101360214200320063602102003200341106a360238200341186a200341286a10af0420032802182202450d022003200329021c37021c20032002360218200141013602002003420137022c20034190c4c500360228200341233602142003200341106a3602382003200341186a3602102003200341286a10af040240200328021c450d00200328021810290b20032802002201450d0220002003290204370204200020013602000c030b20064101102e000b1033000b200041003602000b200341c0006a24000be70301047f230041c0006b22042400200441286a200141186a2205200141286a200210c8040240024020042d00284101470d002000200429022c370200200041086a200441346a2802003602000c010b0240024002400240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490d0320024101742207200620062007491b22064100480d030240024020020d002006103221020c010b200528020020022006103421020b2002450d02200120023602182001411c6a2006360200200141206a28020021020b200128021820026a20033a0000200141206a2201200128020041016a3602000c030b2004413c6a220141013602002004420137022c200441c8cac50036022820044101360214200420063602102004200441106a360238200441186a200441286a10af0420042802182202450d022004200429021c37021c20042002360218200141013602002004420137022c20044190c4c500360228200441233602142004200441106a3602382004200441186a3602102004200441286a10af040240200428021c450d00200428021810290b20042802002201450d0220002004290204370204200020013602000c030b20064101102e000b1033000b200041003602000b200441c0006a24000bc10201037f230041206b220224000240024020002d00004104470d0020022001280218418ae7c50041082001411c6a28020028020c11040022003a001820022001360210200241003a0019200241003602140c010b200220012802184192e7c50041052001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200036020c200241106a2002410c6a4198e7c50010d404210120022d0018210020022802142203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d004101210020042802184194abc60041012004411c6a28020028020c1104000d010b2001280200220028021841cbaac60041012000411c6a28020028020c11040021000b200120003a00080b200241206a2400200041ff01714100470bf30202047f057e230041d0006b2203240041012104024020002d00080d00200028020421050240200028020022062d00004104710d0041012104200628021841eaaac6004191abc60020051b4102410120051b2006411c6a28020028020c1104000d0120012000280200200228020c11030021040c010b024020050d004101210420062802184192abc60041022006411c6a28020028020c1104000d01200028020021060b41012104200341013a00172003200341176a3602102006290208210720062902102108200341346a41d0aac60036020020032006290218370308200629022021092006290228210a200320062d00303a00482006290200210b2003200a3703402003200937033820032008370328200320073703202003200b3703182003200341086a3602302001200341186a200228020c1103000d00200328023041e8aac6004102200328023428020c11040021040b200020043a00082000200028020441016a360204200341d0006a240020000b17000240200041046a280200450d00200028020010290b0b16002000280200220028020020002802082001109c020b110020012000280200200028020810b3040bbd0801087f230041c0006b22032400200341246a2001360200200341346a200241146a2802002204360200200341033a00382003412c6a2002280210220520044103746a36020020034280808080800437030820032000360220410021062003410036021820034100360210200320053602302003200536022802400240024002400240200228020822070d0020022802002108200228020422092004200420094b1b220a450d0141012104200020082802002008280204200128020c1104000d04200841086a210241012106034002402005280200200341086a200541046a280200110300450d00410121040c060b2006200a4f0d02200241046a210020022802002101200541086a2105200241086a210241012104200641016a2106200328022020012000280200200328022428020c110400450d000c050b0b20022802002108200228020422092002410c6a2802002205200520094b1b220a450d0041012104200020082802002008280204200128020c1104000d03200741106a2105200841086a21024101210603402003200541786a28020036020c2003200541106a2d00003a003820032005417c6a28020036020841002101410021040240024002400240200541086a2802000e0400010203000b2005410c6a2802002100410121040c020b02402005410c6a2802002207200328023422044f0d0041002104200328023020074103746a2207280204412a470d0220072802002802002100410121040c020b419884c600200720041036000b4100210420032802282207200328022c460d002003200741086a360228410021042007280204412a470d0020072802002802002100410121040b2003200036021420032004360210024002400240024002400240024020052802000e0404010006040b20032802282200200328022c470d010c050b200541046a2802002200200328023422044f0d01200328023020004103746a2200280204412a470d04200028020028020021040c030b2003200041086a3602282000280204412a470d03200028020028020021040c020b419884c600200020041036000b200541046a28020021040b410121010b2003200436021c2003200136021802400240200541706a2802004101460d0020032802282204200328022c460d042003200441086a3602280c010b200541746a2802002204200328023422004f0d04200328023020044103746a21040b02402004280200200341086a200441046a280200110300450d00410121040c050b2006200a4f0d01200241046a210020022802002101200541246a2105200241086a210241012104200641016a2106200328022020012000280200200328022428020c110400450d000c040b0b0240200920064d0d00410121042003280220200820064103746a22052802002005280204200328022428020c1104000d030b410021040c020b41e882c600106d000b41a884c600200420001036000b200341c0006a240020040bfc0101027f230041106b220224002002200128021841f0abc60041052001411c6a28020028020c1104003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a41e8cac50010d4041a20022d00082101024020022802042203450d00200141ff0171210041012101024020000d00024020034101470d0020022d000941ff0171450d00200228020022002d00004104710d004101210120002802184194abc60041012000411c6a28020028020c1104000d010b2002280200220128021841cbaac60041012001411c6a28020028020c11040021010b200220013a00080b200241106a2400200141ff01714100470ba46601037f230041206b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002d00000eac010102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab0100010b2002200128021841dbdbc50041112001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000cab010b2002200128021841ecdbc500410b2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000caa010b2002200128021841f7dbc50041032001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000ca9010b2002200128021841fadbc50041052001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a4180dcc50010d40421000ca8010b200220012802184190dcc50041042001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a4180dcc50010d40421000ca7010b200220012802184194dcc50041022001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a4180dcc50010d40421000ca6010b200220012802184196dcc50041042001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000ca5010b20022001280218419adcc50041032001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000ca4010b20022001280218419ddcc50041022001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421000ca3010b2002200128021841b0dcc50041042001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421000ca2010b2002200128021841b4dcc50041072001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41bcdcc50010d404210120022000410c6a36020c20012002410c6a41a0dcc50010d40421000ca1010b2002200128021841ccdcc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000ca0010b2002200128021841d2dcc50041042001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421000c9f010b2002200128021841d6dcc500410c2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041016a36020c20012002410c6a41e4dcc50010d40421000c9e010b2002200128021841f4dcc50041042001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c9d010b2002200128021841f8dcc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c9c010b2002200128021841fedcc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421000c9b010b200220012802184186ddc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421000c9a010b20022001280218418eddc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421000c99010b200220012802184196ddc50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421000c98010b20022001280218419fddc50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421000c97010b2002200128021841a8ddc50041072001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c96010b2002200128021841afddc50041072001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c95010b2002200128021841b6ddc50041072001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c94010b2002200128021841bdddc50041072001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c93010b2002200128021841c4ddc50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c92010b2002200128021841cdddc50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c91010b2002200128021841d6ddc500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c90010b2002200128021841e0ddc500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c8f010b2002200128021841eaddc50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c8e010b2002200128021841f3ddc50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c8d010b2002200128021841fcddc500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c8c010b200220012802184186dec500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c8b010b200220012802184190dec500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c8a010b20022001280218419adec500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c89010b2002200128021841a4dec50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c88010b2002200128021841acdec50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c87010b2002200128021841b4dec50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c86010b2002200128021841bcdec50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c85010b2002200128021841c4dec50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c84010b2002200128021841cddec500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c83010b2002200128021841d7dec50041092001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c82010b2002200128021841e0dec500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c81010b2002200128021841eadec500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421012002200041086a36020c20012002410c6a41a0dcc50010d40421000c80010b2002200128021841f4dec500410d2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41e4dcc50010d40421000c7f0b200220012802184181dfc500410a2001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41e4dcc50010d40421000c7e0b20022001280218418bdfc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4194dfc50010d40421000c7d0b2002200128021841a4dfc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041086a36020c200241106a2002410c6a41acdfc50010d40421000c7c0b2002200128021841bcdfc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0dcc50010d40421000c7b0b2002200128021841c4dfc50041082001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200041086a36020c200241106a2002410c6a41ccdfc50010d40421000c7a0b2002200128021841dcdfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c790b2002200128021841e2dfc50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c780b2002200128021841e7dfc50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c770b2002200128021841ecdfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c760b2002200128021841f2dfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c750b2002200128021841f8dfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c740b2002200128021841fedfc50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c730b200220012802184184e0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c720b20022001280218418ae0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c710b200220012802184190e0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c700b200220012802184196e0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c6f0b20022001280218419ce0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c6e0b2002200128021841a2e0c50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c6d0b2002200128021841a7e0c50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c6c0b2002200128021841ace0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c6b0b2002200128021841b2e0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c6a0b2002200128021841b8e0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c690b2002200128021841bee0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c680b2002200128021841c4e0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c670b2002200128021841cae0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c660b2002200128021841d0e0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c650b2002200128021841d6e0c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c640b2002200128021841dce0c50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c630b2002200128021841e1e0c50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c620b2002200128021841e6e0c50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c610b2002200128021841ebe0c50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c600b2002200128021841f0e0c50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c5f0b2002200128021841f5e0c50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c5e0b2002200128021841fae0c50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c5d0b2002200128021841ffe0c50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c5c0b200220012802184184e1c50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c5b0b200220012802184189e1c50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c5a0b20022001280218418ee1c50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c590b200220012802184193e1c50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c580b200220012802184198e1c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c570b20022001280218419ee1c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c560b2002200128021841a4e1c50041092001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c550b2002200128021841ade1c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c540b2002200128021841b3e1c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c530b2002200128021841b9e1c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c520b2002200128021841bfe1c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c510b2002200128021841c6e1c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c500b2002200128021841cde1c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c4f0b2002200128021841d4e1c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c4e0b2002200128021841dbe1c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c4d0b2002200128021841e1e1c50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c4c0b2002200128021841e6e1c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c4b0b2002200128021841ece1c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c4a0b2002200128021841f2e1c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c490b2002200128021841f9e1c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c480b200220012802184180e2c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c470b200220012802184187e2c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c460b20022001280218418ee2c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c450b200220012802184194e2c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c440b20022001280218419ae2c50041092001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c430b2002200128021841a3e2c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c420b2002200128021841a9e2c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c410b2002200128021841afe2c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c400b2002200128021841b5e2c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c3f0b2002200128021841bce2c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c3e0b2002200128021841c3e2c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c3d0b2002200128021841cae2c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c3c0b2002200128021841d1e2c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c3b0b2002200128021841d7e2c50041052001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c3a0b2002200128021841dce2c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c390b2002200128021841e2e2c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c380b2002200128021841e8e2c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c370b2002200128021841efe2c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c360b2002200128021841f6e2c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c350b2002200128021841fde2c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c340b200220012802184184e3c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c330b20022001280218418ae3c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c320b200220012802184190e3c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c310b200220012802184197e3c50041082001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c300b20022001280218419fe3c50041082001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c2f0b2002200128021841a7e3c500410a2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c2e0b2002200128021841b1e3c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c2d0b2002200128021841b8e3c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c2c0b2002200128021841bee3c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c2b0b2002200128021841c4e3c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c2a0b2002200128021841cae3c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c290b2002200128021841d0e3c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c280b2002200128021841d6e3c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c270b2002200128021841dce3c500410b2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c260b2002200128021841e7e3c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c250b2002200128021841ede3c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c240b2002200128021841f3e3c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c230b2002200128021841fae3c50041082001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c220b200220012802184182e4c50041082001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c210b20022001280218418ae4c500410a2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c200b200220012802184194e4c50041072001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c1f0b20022001280218419be4c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c1e0b2002200128021841a1e4c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c1d0b2002200128021841a7e4c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c1c0b2002200128021841ade4c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c1b0b2002200128021841b3e4c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c1a0b2002200128021841b9e4c50041062001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c190b2002200128021841bfe4c500410b2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c180b2002200128021841cae4c500410a2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c170b2002200128021841d4e4c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c160b2002200128021841e0e4c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c150b2002200128021841ece4c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c140b2002200128021841f8e4c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c130b200220012802184184e5c500410d2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c120b200220012802184191e5c500410d2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c110b20022001280218419ee5c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c100b2002200128021841aae5c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c0f0b2002200128021841b6e5c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c0e0b2002200128021841c2e5c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c0d0b2002200128021841cee5c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c0c0b2002200128021841dce5c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c0b0b2002200128021841eae5c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c0a0b2002200128021841f8e5c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c090b200220012802184186e6c500410c2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c080b200220012802184192e6c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c070b2002200128021841a0e6c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c060b2002200128021841aee6c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c050b2002200128021841bce6c500410e2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c040b2002200128021841cae6c500410d2001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c030b2002200128021841d7e6c50041112001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c020b2002200128021841e8e6c50041112001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000c010b2002200128021841f9e6c50041112001411c6a28020028020c1104003a001820022001360210200241003a001920024100360214200241106a21000b20002d00082101024020002802042203450d00200141ff0171210441012101024020040d00024020034101470d0020002d0009450d00200028020022042d00004104710d004101210120042802184194abc60041012004411c6a28020028020c1104000d010b2000280200220128021841cbaac60041012001411c6a28020028020c11040021010b200020013a00080b200241206a2400200141ff01714100470bd00201027f230041106b2202240020002802002802002100200128021841eecbc50041052001411c6a28020028020c1104002103200241003a0005200220033a00042002200136020020022000410c6a36020c200241f3cbc500410e2002410c6a4184ccc50010dc0421012002200036020c20014194ccc50041092002410c6a41a0ccc50010dc0421012002200041046a36020c200141b0ccc500410c2002410c6a41a0ccc50010dc0421012002200041086a36020c200141bcccc500410c2002410c6a41a0ccc50010dc041a20022d00042100024020022d0005450d00200041ff0171210141012100024020010d0020022802002200411c6a28020028020c210120002802182103024020002d00004104710d002003418eabc6004102200111040021000c010b20034190abc6004101200111040021000b200220003a00040b200241106a2400200041ff01714100470bdd0302047f057e230041d0006b2205240041012106024020002d00040d0020002d000521070240200028020022082d00004104710d0041012106200828021841eaaac6004188abc600200741ff017122071b4102410320071b2008411c6a28020028020c1104000d014101210620002802002208280218200120022008411c6a28020028020c1104000d01410121062000280200220828021841a0aac60041022008411c6a28020028020c1104000d0120032000280200200428020c11030021060c010b0240200741ff01710d00410121062008280218418babc60041032008411c6a28020028020c1104000d01200028020021080b41012106200541013a00172005200541176a360210200829020821092008290210210a200541346a41d0aac600360200200520082902183703082008290220210b2008290228210c200520082d00303a00482008290200210d2005200c3703402005200b3703382005200a370328200520093703202005200d3703182005200541086a360230200541086a20012002108f050d00200541086a41a0aac6004102108f050d002003200541186a200428020c1103000d00200528023041e8aac6004102200528023428020c11040021060b200041013a0005200020063a0004200541d0006a240020000bc05e010b7f23004190016b220324002003200136021c2002280208220441586a2105200241106a2802002206412c6c21010240024002400240024002400240024002400240024002400240024003402001450d01200141546a2101200541286a21072005412c6a2208210520072d00004104470d000b2006412c6c2101200441586a210503402001450d02200141546a2101200541286a21072005412c6a2209210520072d0000410b470d000b2006412c6c2101200441586a210503402001450d03200141546a2101200541286a21072005412c6a2204210520072d00004102470d000b024041002802f8ab464105490d002003410136023c20032003411c6a36023841002802fcab46210120034188016a41980136020020034180016a42ec80808010370300200341f8006a4125360200200341f0006a4101360200200341e0006a4201370300200341d8006a410a3602002003418bd0c50036027c200341e6cfc500360274200341ec006a200341386a360200200341fcccc50036025c200341dccfc500360254200341053602504180acc60041e480c600200141024622011b200341d0006a41d4f3c50041ecf3c50020011b2802101100000b200341106a200810a2032003280214200328021c22014d0d03200328021020014102746a2201450d03200341086a200410a2030240200328020c200128020022014d0d00200328020820014104746a22010d050b412510322201450d052001411d6a41002900a1cd45370000200141186a410029009ccd45370000200141106a4100290094cd45370000200141086a410029008ccd4537000020014100290084cd45370000200041086a42a5808080d00437020020002001360204200041013602000c0d0b411310322201450d082001410f6a41002800d7cc45360000200141086a41002900d0cc45370000200141002900c8cc45370000200041086a4293808080b00237020020002001360204200041013602000c0c0b410f10322201450d06200141076a41002900e2cc45370000200141002900dbcc45370000200041086a428f808080f00137020020002001360204200041013602000c0b0b410f10322201450d04200141076a41002900f1cc45370000200141002900eacc45370000200041086a428f808080f00137020020002001360204200041013602000c0a0b412510322201450d022001411d6a41002900a1cd45370000200141186a410029009ccd45370000200141106a4100290094cd45370000200141086a410029008ccd4537000020014100290084cd45370000200041086a42a5808080d00437020020002001360204200041013602000c090b02400240200941086a280200200328021c22054b0d00412710322201450d012001411f6a41002900c8cd45370000200141186a41002900c1cd45370000200141106a41002900b9cd45370000200141086a41002900b1cd45370000200141002900a9cd45370000200041086a42a7808080f00437020020002001360204200041013602000c0a0b20092802002109200341206a41086a420037030020034280808080c00037032020012d000d2107410021012003410036024020032007410447220a36023c2003200a360238200341003a00440240024002400240024041002802f8ab4641044b0d00200341d0006a41086a200341386a41086a29030037030020032003290338370350200341d0006a21070c010b2003412b36024c2003200341386a36024841002802fcab46210120034188016a41cb0036020020034180016a42ec80808010370300200341f8006a4125360200200341f0006a4101360200200341e0006a4201370300200341d0006a41086a2207410a3602002003418bd0c50036027c200341e6cfc500360274200341ec006a200341c8006a360200200341d0cdc50036025c200341dccfc500360254200341053602504180acc60041e480c600200141024622011b200341d0006a41d4f3c50041ecf3c50020011b280210110000200328022c2108200328022821012007200341386a41086a29030037030020032003290338370350200341d0006a210720082001470d010b200141016a22082001490d0120014101742206200820082006491b220841ffffffff00712008470d01200841047422064100480d010240024020010d002006103221010c010b200328022420014104742006103421010b2001450d022003200836022820032001360224200328022c21080b200328022420084104746a22012007290200370200200141086a200741086a2902003702002003200328022c41016a36022c410021072009200541186c6a2201280214450d092009200541186c6a410c6a2109200141146a2108200341d0006a410472210b410021074100210103400240200328022020074d0d00200341d0006a200341206a410010df04024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c0d0b2007200328022020032802542d000c1b21070b02400240024002400240024002402001200828020022054f0d002003200928020020014104746a2205360234024041002802f8ab464105490d002003412436023c2003200341346a36023841002802fcab462105200341c90136028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc5003602742003410136027020034201370360200341f8a9c60036025c2003410a360258200341dccfc500360254200341053602502003200341386a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b280210110000200328023421050b024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020052d000022060eac0102220000002201030405060708090a0b0c0d0e0f1010101010101010101010101010111111111111111111121314141414151616161616161616161615161616161616161616161616161616161616161616161717171818181818181818181818181818181717171818181818181818181818181818181717171717171718181818181818171717171717171818181818181819191919191919191919191919191919191919191919191919020b20052d00012105200320032802203602402003200541044722053602382003200641034720057136023c200341003a0044024041002802f8ab464105490d002003412b36024c2003200341386a36024841002802fcab462105200341cb0036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc5003602742003410136027020034201370360200341d0cdc50036025c2003410a360258200341dccfc500360254200341053602502003200341c8006a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b2802101100000b200341d0006a41086a2206200341386a41086a290300370300200320032903383703500240200328022c22052003280228470d00200541016a220c2005490d242005410174220d200c200c200d491b220c41ffffffff0071200c470d24200c410474220d4100480d240240024020050d00200d103221050c010b20032802242005410474200d103421050b2005450d1d2003200c36022820032005360224200328022c21050b200328022420054104746a22052003290350370200200541086a20062903003702002003200328022c41016a36022c0c210b41002105024041002802f8ab464105490d000240200328022c2206417f6a220c20064b0d002003280224200c4104746a4100200c2006491b21050b2003412c36024c200320053602382003200341386a36024841002802fcab462105200341d30036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc5003602742003410136027020034201370360200341d8cdc50036025c2003410a360258200341dccfc500360254200341053602502003200341c8006a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b2802101100000b0240200328022c2205450d0020032005417f6a220536022c200328022420054104746a22052d000c4102470d1a0b411710322201450d1c2001410f6a41002900efcd45370000200141086a41002900e8cd45370000200141002900e0cd45370000200041086a4297808080f00237020020002001360204200041013602000c2c0b024041002802f8ab464105490d0041002802fcab462105200341c10036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc5003602742003420437026c20034201370360200341f8cdc50036025c2003410a360258200341dccfc500360254200341053602504180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b2802101100000b0240200328022c2205417f6a220620054f0d00200620054d0d180b411710322201450d1e2001410f6a41002900efcd45370000200141086a41002900e8cd45370000200141002900e0cd45370000200041086a4297808080f00237020020002001360204200041013602000c2b0b200341d0006a200341206a200541046a28020010df04024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c2b0b200341d0006a200341206a200328025428020410e10402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c2b0b024041002802f8ab464105490d0041002802fcab462105200341c10036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc5003602742003420437026c20034201370360200341f8cdc50036025c2003410a360258200341dccfc500360254200341053602504180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b2802101100000b024002400240200328022c2205417f6a220620054f0d00200620054d0d010b4117103222010d0141174101102e000b200328022420064104746a41013a000c0c1f0b2001410f6a41002900efcd45370000200141086a41002900e8cd45370000200141002900e0cd45370000200041086a4297808080f00237020020002001360204200041013602000c2a0b200341d0006a200341206a200541046a28020010df04024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c2a0b200341d0006a200341206a2003280254280204220510e10402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c2a0b200341d0006a200341206a410110e10402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c2a0b20032005360248024041002802f8ab464105490d002003410136023c2003200341c8006a36023841002802fcab462105200341e30036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc500360274200341013602702003420137036020034180cec50036025c2003410a360258200341dccfc500360254200341053602502003200341386a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e103222010d01410e4101102e000b200320053602200c1e0b200141066a410029008ece4537000020014100290088ce45370000200041086a428e808080e00137020020002001360204200041013602000c290b200341d0006a200341206a2005410c6a28020010df04024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c290b2003280254280204210c200541086a2802004102742106200541046a280200210502400340024020060d00200341d0006a200341206a200c10e1042003280250450d0220002003290350370204200041013602002000410c6a200341d8006a2802003602000c2b0b200341d0006a200341206a200528020010df04024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c2b0b2006417c6a2106200541046a21052003280254280204200c460d000b412710322201450d1a2001411f6a41002900b5ce45370000200141186a41002900aece45370000200141106a41002900a6ce45370000200141086a410029009ece4537000020014100290096ce45370000200041086a42a7808080f00437020020002001360204200041013602000c290b024041002802f8ab464105490d0041002802fcab462105200341c10036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc5003602742003420437026c20034201370360200341f8cdc50036025c2003410a360258200341dccfc500360254200341053602504180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b2802101100000b024002400240200328022c2205417f6a220620054f0d00200620054d0d010b4117103222010d0141174101102e000b200328022420064104746a41013a000c0c1d0b2001410f6a41002900efcd45370000200141086a41002900e8cd45370000200141002900e0cd45370000200041086a4297808080f00237020020002001360204200041013602000c280b200341d0006a200341206a200a10e10402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c280b024041002802f8ab464105490d0041002802fcab462105200341c10036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc5003602742003420437026c20034201370360200341f8cdc50036025c2003410a360258200341dccfc500360254200341053602504180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b2802101100000b024002400240200328022c2205417f6a220620054f0d00200620054d0d010b4117103222010d0141174101102e000b200328022420064104746a41013a000c0c1c0b2001410f6a41002900efcd45370000200141086a41002900e8cd45370000200141002900e0cd45370000200041086a4297808080f00237020020002001360204200041013602000c270b200341d0006a200541046a280200200210e204024020032802504101470d00200041013602002000200b2902003702042000410c6a200b41086a2802003602000c270b200341d0006a200341206a2003280254220528020810e10402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c270b200320052d000d4104472205360248024041002802f8ab464105490d002003410136023c2003200341c8006a36023841002802fcab462105200341e30036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc500360274200341013602702003420137036020034180cec50036025c2003410a360258200341dccfc500360254200341053602502003200341386a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e103222010d01410e4101102e000b200320053602200c1b0b200141066a410029008ece4537000020014100290088ce45370000200041086a428e808080e00137020020002001360204200041013602000c260b2003200410a203024002402003280204200541046a28020022054d0d002003280200220620054104746a220c0d010b410e10322201450d18200141066a41002900c3ce45370000200141002900bdce45370000200041086a428e808080e00137020020002001360204200041013602000c260b200341d0006a200341206a200620054104746a28020810e10402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c260b2003200c2d000d4104472205360248024041002802f8ab464105490d002003410136023c2003200341c8006a36023841002802fcab462105200341e30036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc500360274200341013602702003420137036020034180cec50036025c2003410a360258200341dccfc500360254200341053602502003200341386a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e103222010d01410e4101102e000b200320053602200c1a0b200141066a410029008ece4537000020014100290088ce45370000200041086a428e808080e00137020020002001360204200041013602000c250b200341d0006a200341206a410110e1042003280250450d1820002003290350370204200041013602002000410c6a200341d8006a2802003602000c240b200341d0006a200341206a410210e10402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c240b41012105200341d0006a200341206a410110e10402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c240b20034101360248024041002802f8ab464105490d002003410136023c2003200341c8006a36023841002802fcab462105200341e30036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc500360274200341013602702003420137036020034180cec50036025c2003410a360258200341dccfc500360254200341053602502003200341386a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e103222010d01410e4101102e000b200320053602200c180b200141066a410029008ece4537000020014100290088ce45370000200041086a428e808080e00137020020002001360204200041013602000c230b4101210520034101360248024041002802f8ab464105490d002003410136023c2003200341c8006a36023841002802fcab462105200341e30036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc500360274200341013602702003420137036020034180cec50036025c2003410a360258200341dccfc500360254200341053602502003200341386a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e103222010d01410e4101102e000b200320053602200c170b200141066a410029008ece4537000020014100290088ce45370000200041086a428e808080e00137020020002001360204200041013602000c220b200341d0006a200341206a410110e1042003280250450d1520002003290350370204200041013602002000410c6a200341d8006a2802003602000c210b41012105200341d0006a200341206a410110e10402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c210b20034101360248024041002802f8ab464105490d002003410136023c2003200341c8006a36023841002802fcab462105200341e30036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc500360274200341013602702003420137036020034180cec50036025c2003410a360258200341dccfc500360254200341053602502003200341386a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e103222010d01410e4101102e000b200320053602200c150b200141066a410029008ece4537000020014100290088ce45370000200041086a428e808080e00137020020002001360204200041013602000c200b4101210520034101360248024041002802f8ab464105490d002003410136023c2003200341c8006a36023841002802fcab462105200341e30036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc500360274200341013602702003420137036020034180cec50036025c2003410a360258200341dccfc500360254200341053602502003200341386a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e103222010d01410e4101102e000b200320053602200c140b200141066a410029008ece4537000020014100290088ce45370000200041086a428e808080e00137020020002001360204200041013602000c1f0b200341d0006a200341206a410110e1042003280250450d1220002003290350370204200041013602002000410c6a200341d8006a2802003602000c1e0b41012105200341d0006a200341206a410110e10402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1e0b20034101360248024041002802f8ab464105490d002003410136023c2003200341c8006a36023841002802fcab462105200341e30036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc500360274200341013602702003420137036020034180cec50036025c2003410a360258200341dccfc500360254200341053602502003200341386a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e103222010d01410e4101102e000b200320053602200c120b200141066a410029008ece4537000020014100290088ce45370000200041086a428e808080e00137020020002001360204200041013602000c1d0b200341d0006a200341206a410210e1042003280250450d1020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1c0b4101210520034101360248024041002802f8ab464105490d002003410136023c2003200341c8006a36023841002802fcab462105200341e30036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc500360274200341013602702003420137036020034180cec50036025c2003410a360258200341dccfc500360254200341053602502003200341386a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e103222010d01410e4101102e000b200320053602200c100b200141066a410029008ece4537000020014100290088ce45370000200041086a428e808080e00137020020002001360204200041013602000c1b0b41012105200341d0006a200341206a410110e10402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c1b0b20034101360248024041002802f8ab464105490d002003410136023c2003200341c8006a36023841002802fcab462105200341e30036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc500360274200341013602702003420137036020034180cec50036025c2003410a360258200341dccfc500360254200341053602502003200341386a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e103222010d01410e4101102e000b200320053602200c0f0b200141066a410029008ece4537000020014100290088ce45370000200041086a428e808080e00137020020002001360204200041013602000c1a0b4101210520034101360248024041002802f8ab464105490d002003410136023c2003200341c8006a36023841002802fcab462105200341e30036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc500360274200341013602702003420137036020034180cec50036025c2003410a360258200341dccfc500360254200341053602502003200341386a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e103222010d01410e4101102e000b200320053602200c0e0b200141066a410029008ece4537000020014100290088ce45370000200041086a428e808080e00137020020002001360204200041013602000c190b41012105200341d0006a200341206a410110e10402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c190b20034101360248024041002802f8ab464105490d002003410136023c2003200341c8006a36023841002802fcab462105200341e30036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc500360274200341013602702003420137036020034180cec50036025c2003410a360258200341dccfc500360254200341053602502003200341386a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e103222010d01410e4101102e000b200320053602200c0d0b200141066a410029008ece4537000020014100290088ce45370000200041086a428e808080e00137020020002001360204200041013602000c180b200341d0006a200341206a410210e10402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c180b4101210520034101360248024041002802f8ab464105490d002003410136023c2003200341c8006a36023841002802fcab462105200341e30036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc500360274200341013602702003420137036020034180cec50036025c2003410a360258200341dccfc500360254200341053602502003200341386a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e103222010d01410e4101102e000b200320053602200c0c0b200141066a410029008ece4537000020014100290088ce45370000200041086a428e808080e00137020020002001360204200041013602000c170b41012105200341d0006a200341206a410110e10402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c170b20034101360248024041002802f8ab464105490d002003410136023c2003200341c8006a36023841002802fcab462105200341e30036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc500360274200341013602702003420137036020034180cec50036025c2003410a360258200341dccfc500360254200341053602502003200341386a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e103222010d01410e4101102e000b200320053602200c0b0b200141066a410029008ece4537000020014100290088ce45370000200041086a428e808080e00137020020002001360204200041013602000c160b200341d0006a200341206a410210e10402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c160b4101210520034101360248024041002802f8ab464105490d002003410136023c2003200341c8006a36023841002802fcab462105200341e30036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc500360274200341013602702003420137036020034180cec50036025c2003410a360258200341dccfc500360254200341053602502003200341386a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e103222010d01410e4101102e000b200320053602200c0a0b200141066a410029008ece4537000020014100290088ce45370000200041086a428e808080e00137020020002001360204200041013602000c150b41012105200341d0006a200341206a410110e10402402003280250450d0020002003290350370204200041013602002000410c6a200341d8006a2802003602000c150b20034101360248024041002802f8ab464105490d002003410136023c2003200341c8006a36023841002802fcab462105200341e30036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc500360274200341013602702003420137036020034180cec50036025c2003410a360258200341dccfc500360254200341053602502003200341386a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b280210110000200328024821050b024002402003280220220620056a220520064f0d00410e103222010d01410e4101102e000b200320053602200c090b200141066a410029008ece4537000020014100290088ce45370000200041086a428e808080e00137020020002001360204200041013602000c140b200328022420064104746a41013a000c0c070b20052802002106200320052802082205360238024041002802f8ab464105490d002003410136024c2003200341386a36024841002802fcab462105200341db0036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc5003602742003410136027020034201370360200341cccec50036025c2003410a360258200341dccfc500360254200341053602502003200341c8006a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b280210110000200328023821050b2003200536022020032006360248024041002802f8ab464105490d002003410136023c2003200341c8006a36023841002802fcab462105200341e30036028801200342ec80808010370380012003418bd0c50036027c20034125360278200341e6cfc500360274200341013602702003420137036020034180cec50036025c2003410a360258200341dccfc500360254200341053602502003200341386a36026c4180acc60041e480c600200541024622051b200341d0006a41d4f3c50041ecf3c50020051b28021011000020032802202105200328024821060b0240200520066a220620054f0d00410e103222010d11410e4101102e000b200320063602200c060b41d4cec500200120051036000b200d4104102e000b41174101102e000b41274101102e000b410e4101102e000b41174101102e000b200141016a22012008280200490d000c0a0b0b1033000b20064104102e000b41274101102e000b41254101102e000b41254101102e000b410f4101102e000b410f4101102e000b41134101102e000b200141066a410029008ece4537000020014100290088ce45370000200041086a428e808080e00137020020002001360204200041013602000c010b20004100360200200020073602042003280228450d01200328022410290c010b2003280228450d00200328022410290b20034190016a24000bc60201027f230041106b22022400200128021841eecbc50041052001411c6a28020028020c1104002103200241003a0005200220033a00042002200136020020022000410c6a36020c200241f3cbc500410e2002410c6a4184ccc50010dc0421012002200036020c20014194ccc50041092002410c6a41a0ccc50010dc0421012002200041046a36020c200141b0ccc500410c2002410c6a41a0ccc50010dc0421012002200041086a36020c200141bcccc500410c2002410c6a41a0ccc50010dc041a20022d00042100024020022d0005450d00200041ff0171210141012100024020010d0020022802002200411c6a28020028020c210120002802182103024020002d00004104710d002003418eabc6004102200111040021000c010b20034190abc6004101200111040021000b200220003a00040b200241106a2400200041ff01714100470b9b0201027f024002400240024002402001410c6a2802002203417f6a220420034d0d00411610322201450d01200020013602042001410e6a41002900e9d145370000200141086a41002900e3d145370000200141002900dbd145370000200041086a4296808080e0023702000c040b0240200420026b220220044d0d00411b10322201450d0220002001360204200141176a4100280088d245360000200141106a4100290081d245370000200141086a41002900f9d145370000200141002900f1d145370000200041086a429b808080b0033702000c040b200320024d0d022000200128020420024104746a360204200041003602000f0b41164101102e000b411b4101102e000b418cd2c500200220031036000b200041013602000bbb0201037f230041106b220224000240024020002802000d002002200128021841b8abc60041042001411c6a28020028020c11040022003a000820022001360200200241003a0009200241003602040c010b2002200128021841bcabc60041042001411c6a28020028020c1104003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a41e8d9c50010d404210120022d0008210020022802042203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d004101210020042802184194abc60041012004411c6a28020028020c1104000d010b2001280200220028021841cbaac60041012000411c6a28020028020c11040021000b200120003a00080b200241106a2400200041ff01714100470bc50401027f230041d0006b2203240020032002360204024041002802f8ab464105490d002003410136020c2003200341046a36020841002802fcab462102200341c8006a41ef00360200200341c0006a42ec80808010370300200341386a4125360200200341306a4101360200200341206a4201370300200341186a410a3602002003418bd0c50036023c200341e6cfc5003602342003412c6a200341086a36020020034184d1c50036021c200341dccfc500360214200341053602104180acc60041e480c600200241024622021b200341106a41d4f3c50041ecf3c50020021b280210110000200328020421020b0240024002402002450d00200341106a2001410010df0420032802104101470d012000200341106a4104722202290200370200200041086a200241086a2802003602000c020b200041003602000c010b02400240024002402001280200220220032802142204280208460d00200220032802046b220420024d0d02410f103222020d01410f4101102e000b024020042d000c0d00412510322202450d03200042a5808080d004370204200020023602002002411d6a41002900a9d145370000200241186a41002900a4d145370000200241106a410029009cd145370000200241086a4100290094d1453700002002410029008cd1453700000c040b200041003602000c030b2000428f808080f00137020420002002360200200241076a41002900b8d145370000200241002900b1d1453700000c020b20004100360200200120043602000c010b41254101102e000b200341d0006a24000bbe09010b7f230041e0006b22032400200320013602202002280208220441586a2105200241106a2802002206412c6c210202400340024020020d00410021070c020b200241546a2102200541286a21072005412c6a2208210520072d00004102470d000b200341186a200810a20320032802182107200328021c21020b2002410020071b21092006412c6c2102200441586a21052007410420071b210a02400340024020020d004100210b0c020b200241546a2102200541286a21072005412c6a2208210520072d00004104470d000b200341106a200810a2032003280210210b2003280214210c0b2006412c6c2102200441586a2105200b4104200b1b210d02400240024002400240024003402002450d01200241546a2102200541286a21072005412c6a2208210520072d00004103470d000b200841086a2802002202450d00200241286c2107200828020041186a2102410021050340200520022d0000456a2105200241286a2102200741586a22070d000b200520014d0d012006412c6c2102200441586a2105024003402002450d01200241546a2102200541286a21072005412c6a2208210520072d00004103470d000b200341086a200810a20320032802082202200328020c41286c6a21070240024002400340024002400240200720026b41f8004b0d0020022007460d0d2002411c6a2105034020022d0018450d02200541286a2105200241286a22022007470d000c0e0b0b20022d00180d01200241186a2105200241286a21080c040b2005410c6a21080c040b200241c0006a22052d0000450d010240200241e8006a22052d0000450d0020024190016a2105200241a0016a2208210220052d00000d010c030b0b200241f8006a21080c010b200241d0006a21080b200541046a21050b2001450d0303402001417f6a210120082102024002400340024002400240200720026b41f8004b0d0020022007460d0d2002411c6a2105034020022d0018450d02200541286a2105200241286a22022007460d0e0c000b0b20022d00180d01200241186a2105200241286a21080c040b2005410c6a210820010d040c080b200241c0006a22052d0000450d010240200241e8006a22052d0000450d0020024190016a2105200241a0016a2208210220052d00000d010c030b0b200241f8006a21080c010b200241d0006a21080b20010d000b200541046a21050c030b41e5d5c50041c200109201000b410021050b0240200c4100200b1b200120056b22024d0d00200d20024102746a22050d010b200341cc006a41013602002003420237023c20034184d7c5003602382003410136022c2003200341286a3602482003200341206a360228200341d0006a200341386a10af04200341d0006a21020c010b2003200528020022023602240240200920024d0d00200a20024104746a2202450d0020002002360204410021020c020b200341cc006a4102360200200341dc006a41013602002003420337023c20034194d7c500360238200341013602542003200341d0006a3602482003200341206a3602582003200341246a360250200341286a200341386a10af04200341286a21020b20022802002105200041086a200229020437020020002005360204410121020b20002002360200200341e0006a24000f0b41a7d6c50041dd00109201000bc50a01057f02400240024020012d00002202414f6a41fb00490d0002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020020e312a2a0001022a2a0304052a06072a2a08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a0b200020012d00013a0001200041023a00000f0b200020012d00013a0001200041033a00000f0b200020012d00013a0001200041043a00000f0b200041046a200141046a280200360200200041073a00000f0b200041046a200141046a280200360200200041083a00000f0b200141086a280200220341ffffffff03712003470d2520034102742202417f4c0d250240024020020d00410421040c010b200210322204450d270b02402003450d00200128020421022003410274210520042106034020062002280200360200200641046a2106200241046a21022005417c6a22050d000b0b2000410c6a200128020c360200200041086a2003360200200041046a2004360200200041093a00000f0b200041046a200141046a2802003602002000410b3a00000f0b200020012d00013a0001200041046a200141046a2802003602002000410c3a00000f0b200041046a200141046a2802003602002000410f3a00000f0b200041046a200141046a280200360200200041103a00000f0b200041046a200141046a280200360200200041113a00000f0b200041046a200141046a280200360200200041123a00000f0b200041046a200141046a280200360200200041133a00000f0b200041046a200141046a290200370200200041143a00000f0b200041046a200141046a290200370200200041153a00000f0b200041046a200141046a290200370200200041163a00000f0b200041046a200141046a290200370200200041173a00000f0b200041046a200141046a290200370200200041183a00000f0b200041046a200141046a290200370200200041193a00000f0b200041046a200141046a2902003702002000411a3a00000f0b200041046a200141046a2902003702002000411b3a00000f0b200041046a200141046a2902003702002000411c3a00000f0b200041046a200141046a2902003702002000411d3a00000f0b200041046a200141046a2902003702002000411e3a00000f0b200041046a200141046a2902003702002000411f3a00000f0b200041046a200141046a290200370200200041203a00000f0b200041046a200141046a290200370200200041213a00000f0b200041046a200141046a290200370200200041223a00000f0b200041046a200141046a290200370200200041233a00000f0b200041046a200141046a290200370200200041243a00000f0b200041046a200141046a290200370200200041253a00000f0b200041046a200141046a290200370200200041263a00000f0b200041046a200141046a290200370200200041273a00000f0b200041046a200141046a290200370200200041283a00000f0b200041046a200141046a290200370200200041293a00000f0b200041046a200141046a2902003702002000412a3a00000f0b200020012d00013a00012000412b3a00000f0b200020012d00013a00012000412c3a00000f0b200041046a200141046a2802003602002000412d3a00000f0b200041086a200141086a2903003703002000412e3a00000f0b200041046a200141046a2802003602002000412f3a00000f0b200041086a200141086a290300370300413021020b200020023a00000f0b102f000b20024104102e000b9a0301067f230041106b220224000240024002400240200041046a2802002203200041086a28020022046b20012802042205200128020022066b4104762207490d00200028020021030c010b200420076a22062004490d0220034101742205200620062005491b220641ffffffff00712006470d02200641047422054100480d020240024020030d002005103221030c010b200028020020034104742005103421030b2003450d0120002003360200200041046a2006360200200041086a280200210420012802042105200128020021060b0240024020062005470d00200241ac013a00000c010b2001200641106a3602002002200610e30420022d000041ac01460d00200441016a2105200320044104746a210603402005210420062002290300370300200641086a200241086a2903003703000240200128020022052001280204470d00200241ac013a00000c020b2001200541106a3602002002200510e304200441016a2105200641106a210620022d000041ac01470d000b0b200041086a2004360200200241106a24000f0b20054108102e000b1033000b110020002802003502004101200110a7020bea0302057f017e02402001450d00034020002802940321002001417f6a22010d000b0b02402002450d004100210341002101034002400240200120002f01064f0d00200020014105746a220441c4006a2802002105200441386a2802002106200441346a2802002107200141016a21010c010b02400240200028020022010d002003ad210841002104410021010c010b20003301044220862003ad842108410121040b200010292008a72103024002402008422088a7220620012f01064f0d00200121050c010b034002400240200128020022050d002003ad2108410021050c010b200441016a210420013301044220862003ad8421080b200110292008a72103200521012008422088a7220620052f01064f0d000b0b200641027420056a4198036a2802002100200520064105746a220141c4006a2802002105200141386a2802002106200141346a280200210702402004417f6a2201450d00034020002802940321002001417f6a22010d000b0b410021010b20054102460d012002417f6a210202402006450d00200710290b20020d000b0b0240200041b0d6c000460d0020002802002101200010292001450d0020012802002105200110292005450d00024020052802002201450d000340200510292001210520012802002200210120000d000b0b200510290b0b23002001419da9c6004198a9c60020002802002d000022001b4104410520001b10b3040bc60201037f230041206b2202240002400240200028020022002d00004104470d0020022001280218418ae7c50041082001411c6a28020028020c11040022003a001820022001360210200241003a0019200241003602140c010b200220012802184192e7c50041052001411c6a28020028020c1104003a001820022001360210200241003a0019200241003602142002200036020c200241106a2002410c6a4198e7c50010d404210120022d0018210020022802142203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d004101210020042802184194abc60041012004411c6a28020028020c1104000d010b2001280200220028021841cbaac60041012000411c6a28020028020c11040021000b200120003a00080b200241206a2400200041ff01714100470b0c002000280200200110bf040b890501047f230041d0006b220224002000280200220041046a28020021032000280200210041012104200128021841c9aac60041012001411c6a28020028020c110400210502402003450d0020022000360204024020050d00024020012d0000410471450d0041012104200128021841ccaac6004101200128021c28020c1104000d012001280200210541012104200241013a001720022005360218200241d0aac60036023420022001290218370308200220012d00303a00482002200128020436021c200220012902283703402002200129022037033820022001290210370328200220012902083703202002200241176a3602102002200241086a360230200241046a200241186a1091010d01200228023041e8aac6004102200228023428020c11040021040c010b200241046a200110910121040b024020034101470d00200421050c010b200041046a21002003410274417c6a210320042105034020022000360204200541ff0171210441012105024020040d00024020012802002204410471450d00200241013a001720022004360218200241d0aac60036023420022001290218370308200220012d00303a00482002200128020436021c200220012902283703402002200129022037033820022001290210370328200220012902083703202002200241176a3602102002200241086a360230200241046a200241186a1091010d01200228023041e8aac6004102200228023428020c11040021050c010b200128021841eaaac6004102200128021c28020c1104000d00200241046a200110910121050b200041046a21002003417c6a22030d000b0b41012100024020050d00200128021841caaac6004101200128021c28020c11040021000b200241d0006a240020000b8c0e01087f024020002802082201450d00200028020022022001412c6c6a2103034020022204412c6a21020240024020042d00002200410d4b0d00024002400240024002400240024002400240024002400240024020000e0e0001020304050607080e090a0b0c000b200441086a280200450d0d200441046a28020010290c0d0b0240200441086a280200450d00200441046a28020010290b200441146a280200450d0c200441106a28020010290c0c0b02402004410c6a2802002201450d00200441046a28020021002001410474210103400240200041046a280200450d00200028020010290b200041106a2100200141706a22010d000b0b200441086a280200450d0b200428020410290c0b0b02402004410c6a2802002201450d00200441046a2802002100200141286c210103400240200041046a280200450d00200028020010290b0240200041106a280200450d002000410c6a28020010290b200041286a2100200141586a22010d000b0b200441086a280200450d0a200428020410290c0a0b200441086a280200450d09200441046a28020010290c090b200441086a280200450d08200441046a28020010290c080b200441086a280200450d07200441046a28020010290c070b02402004410c6a2802002200450d00200441046a280200220520004104746a21060340024020052802082201450d0020052802002100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a28020010290b200041106a2100200141706a22010d000b0b200541106a21000240200541046a280200450d00200528020010290b2000210520002006470d000b0b200441086a280200450d06200428020410290c060b02402004410c6a2802002201450d00200441046a2802002100200141146c210103400240200041046a280200450d00200028020010290b200041146a21002001416c6a22010d000b0b200441086a280200450d05200428020410290c050b02402004410c6a2802002200450d00200441046a28020022052000411c6c6a2106034002402005410c6a2802002201450d0020052802042100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a28020010290b200041106a2100200141706a22010d000b0b0240200541086a280200450d00200528020410290b2005411c6a21000240200541146a280200450d00200528021010290b2000210520002006470d000b0b200441086a280200450d04200428020410290c040b02402004410c6a2802002200450d00200441046a2802002205200041186c6a210603400240200541046a280200450d00200528020010290b0240200541146a2802002201450d00200528020c2100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a28020010290b200041106a2100200141706a22010d000b0b200541186a21000240200541106a280200450d00200528020c10290b2000210520002006470d000b0b200441086a280200450d03200428020410290c030b02402004410c6a2802002200450d00200441046a28020022052000411c6c6a2106034002402005410c6a2802002201450d0020052802042100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a28020010290b200041106a2100200141706a22010d000b0b0240200541086a280200450d00200528020410290b2005411c6a21000240200541146a280200450d00200528021010290b2000210520002006470d000b0b200441086a280200450d02200428020410290c020b0240200441046a2d0000220041024b0d0002400240024020000e03000102000b2004410c6a280200450d04200441086a28020010290c040b0240200441146a2802002201450d002004410c6a28020021002001410c6c21010340024020002802002205450d00200041046a280200450d00200510290b2000410c6a2100200141746a22010d000b0b200441106a280200450d03200428020c10290c030b0240200441146a2802002200450d002004410c6a280200220720004104746a210803402007220641106a2107024020062802042200450d0002402006410c6a2802002201450d002001410c6c21010340024020002802002205450d00200041046a280200450d00200510290b2000410c6a2100200141746a22010d000b0b200641086a280200450d00200628020410290b20072008470d000b0b200441106a280200450d02200428020c10290c020b2004410c6a280200450d01200441086a28020010290c010b0240200441086a280200450d00200441046a28020010290b0240200441146a2802002200450d00200441186a280200450d00200010290b200441246a280200450d00200441206a28020010290b20022003470d000b0b0bd00202027f027e23004180016b220224002000280200210002400240024002400240200128020022034110710d002000290300210420034120710d0120042004423f8722057c2005852004427f55200110a70221000c020b20002903002104410021000340200220006a41ff006a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d0220014101418882c6004102200220006a4180016a410020006b10a80221000c010b410021000340200220006a41ff006a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d0220014101418882c6004102200220006a4180016a410020006b10a80221000b20024180016a240020000f0b20034180011030000b20034180011030000bc30201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d0020002d0000210420034120710d012004ad42ff01834101200110a70221000c020b20002d00002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d0220014101418882c6004102200220006a4180016a410020006b10a80221000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d0220014101418882c6004102200220006a4180016a410020006b10a80221000b20024180016a240020000f0b20044180011030000b20044180011030000bd00203027f017e017f23004180016b220224002000280200210002400240024002400240200128020022034110710d002000280200210020034120710d012000ac22042004423f8722047c2004852000417f73411f76200110a70221000c020b20002802002103410021000340200220006a41ff006a2003410f712205413072200541d7006a2005410a491b3a00002000417f6a2100200341047622030d000b20004180016a22034181014f0d0220014101418882c6004102200220006a4180016a410020006b10a80221000c010b410021030340200220036a41ff006a2000410f712205413072200541376a2005410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d0220014101418882c6004102200220036a4180016a410020036b10a80221000b20024180016a240020000f0b20034180011030000b20004180011030000bfa0202017f037e230041206b220224002001ad42adfed5e4d485fda8d8007e42c3007c210302400240024002400240200141084b0d00200141014b0d0120010d02420021040c030b0240200141104b0d00200241106a2000290000200385420042adfed5e4d485fda8d800420010a005200241186a29030020022903107c200120006a41786a2900008521040c040b200120006a41786a2900002105200321040340200029000020048542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e2003852103200041086a2100200442cf829ebbefefde82147c2104200141786a220141084b0d000b200320058521040c030b0240200141034b0d00200120006a417e6a33000042108620003300008420038521040c030b200120006a417c6a35000042208620003500008420038521040c020b200031000021040b200420038521040b20022004420042adfed5e4d485fda8d800420010a005200241086a290300210420022903002103200241206a2400200420037c0b040041000b02000b02000baf0301047f230041c0006b2202240020002802002100410121030240200128021841baa9c600410c2001411c6a28020028020c1104000d0002400240200028020822030d0020002802002203200028020428020c11070042e4aec285979ba58811520d012002200336020c2002412d36021420022002410c6a36021020012802182104200128021c2105410121032002413c6a41013602002002420237022c200241c8a9c6003602282002200241106a36023820042005200241286a10d8040d020c010b2002200336020c2002412e36021420022002410c6a36021020012802182104200128021c2105410121032002413c6a41013602002002420237022c200241c8a9c6003602282002200241106a36023820042005200241286a10d8040d010b200241106a41146a4101360200200241106a410c6a4101360200200241053602142002200041186a3602202002200041146a36021820022000410c6a36021020012802182100200128021c2101200241286a41146a41033602002002420337022c200241d8a9c6003602282002200241106a36023820002001200241286a10d80421030b200241c0006a240020030b1600200120002802002200280200200028020410b3040b6a01037f230041206b220224002001411c6a280200210320012802182104200241086a41106a2000280200220141106a290200370300200241086a41086a200141086a2902003703002002200129020037030820042003200241086a10d8042101200241206a240020010b6f01017f230041c0006b220124002001200036020c200141346a410136020020014201370224200141f8a9c6003602202001412f36023c2001200141386a36023020012001410c6a360238200141106a200141206a10af042001280210200128021810f704200141106a10f80400000b08002000200110090b17000240200041046a280200450d00200028020010290b0b0600200010250b0600200010260b2801017f0240200210252203450d002003200020022001200120024b1b109b051a200010260b20030b1c01017f0240200010252201450d00200141002000109a051a0b20010b02000bb10101037f0240024002400240200028020022002802042203200028020822046b2002490d00200028020021030c010b200420026a22052004490d0220034101742204200520052004491b22044100480d020240024020030d002004103221030c010b200028020020032004103421030b2003450d012000200436020420002003360200200028020821040b2000200420026a360208200320046a20012002109b051a41000f0b20044101102e000b1033000ba70401047f230041106b220224002000280200210002400240024002400240024002402001418001490d002002410036020c2001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c040b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c030b0240200028020822032000280204470d00200341016a22042003490d0620034101742205200420042005491b22044100480d060240024020030d002004103221030c010b200028020020032004103421030b2003450d022000200436020420002003360200200028020821030b200028020020036a20013a00002000200028020841016a3602080c030b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010c010b20044101102e000b0240024020002802042204200028020822036b2001490d00200028020021040c010b200320016a22052003490d0320044101742203200520052003491b22034100480d030240024020040d002003103221040c010b200028020020042003103421040b2004450d022000200336020420002004360200200028020821030b2000200320016a360208200420036a2002410c6a2001109b051a0b200241106a240041000f0b20034101102e000b1033000b6401017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a419cfbc500200241086a10d8042101200241206a240020010b0c0042b2d5ae93e4bba88c2b0b5401017f024002402001418080c400460d0041012104200028021820012000411c6a2802002802101103000d010b024020020d0041000f0b2000280218200220032000411c6a28020028020c11040021040b20040bcd0801067f230041f0006b220424002004200336020c20042002360208410121052001210602402001418102490d00410020016b2107418002210803400240200820014f0d00200020086a2c000041bf7f4c0d0041002105200821060c020b2008417f6a21064100210520084101460d01200720086a21092006210820094101470d000b0b200420063602142004200036021020044100410520051b36021c200441e480c600418a82c60020051b3602180240024002400240200220014b22080d00200320014b0d00200220034b0d01024002402002450d0020012002460d00200120024d0d01200020026a2c00004140480d010b200321020b200420023602202002450d0220022001460d02200141016a210903400240200220014f0d00200020026a2c000041404e0d040b2002417f6a210820024101460d0420092002462106200821022006450d000c040b0b20042002200320081b360228200441306a41146a4103360200200441c8006a41146a4105360200200441d4006a4105360200200442033702342004419082c6003602302004410136024c2004200441c8006a3602402004200441186a3602582004200441106a3602502004200441286a360248200441306a41a882c600107d000b200441e4006a4105360200200441c8006a41146a4105360200200441d4006a4101360200200441306a41146a410436020020044204370234200441b882c6003602302004410136024c2004200441c8006a3602402004200441186a3602602004200441106a36025820042004410c6a3602502004200441086a360248200441306a41d882c600107d000b200221080b024020082001460d00410121060240024002400240200020086a22092c00002202417f4a0d0041002105200020016a220621010240200941016a2006460d00200941026a210120092d0001413f7121050b2002411f712109200241ff017141df014b0d01200520094106747221010c020b2004200241ff0171360224200441286a21020c020b4100210020062107024020012006460d00200141016a210720012d0000413f7121000b200020054106747221010240200241ff017141f0014f0d0020012009410c747221010c010b41002102024020072006460d0020072d0000413f7121020b20014106742009411274418080f00071722002722201418080c400460d020b2004200136022441012106200441286a21022001418001490d00410221062001418010490d0041034104200141808004491b21060b200420083602282004200620086a36022c200441306a41146a4105360200200441ec006a4105360200200441e4006a4105360200200441c8006a41146a4130360200200441d4006a4131360200200442053702342004418083c600360230200420023602582004410136024c2004200441c8006a3602402004200441186a3602682004200441106a3602602004200441246a3602502004200441206a360248200441306a41a883c600107d000b41e882c600106d000b6f01037f230041206b220224000240200020011087050d002001411c6a280200210320012802182104200242043703182002420137020c2002419084c60036020820042003200241086a10d8040d00200041046a20011087052101200241206a240020010f0b200241206a240041010bdc0a02077f017e410121020240200128021841272001411c6a2802002802101103000d0041022103024002400240024002402000280200220241776a2200411e4d0d00200241dc00470d010c020b41f40021040240024020000e1f05010202000202020202020202020202020202020202020202030202020203050b41f20021040c040b41ee0021040c030b024002400240024002400240024020021086050d00024002400240024002400240200241808004490d00200241808008490d0120024190fc476a4190fc0b490d0a200241e28b746a41e28d2c490d0a2002419fa8746a419f18490d0a200241dee2746a410e490d0a200241feffff0071419ef00a460d0a200241a9b2756a4129490d0a200241cb91756a410a4d0d0a410121030c0e0b20024180fe0371410876210541d090c600210041002106200241ff017121040340200041026a2107200620002d000122036a2108024020002d000022002005460d00200020054b0d092008210620072100200741a291c600470d010c090b20082006490d02200841a5024b0d03200641a291c6006a2100024003402003450d012003417f6a210320002d00002106200041016a210020062004470d000c0c0b0b2008210620072100200741a291c600470d000c080b0b20024180fe03714108762105418196c600210041002106200241ff017121040340200041026a2107200620002d000122036a2108024020002d000022002005460d00200020054b0d072008210620072100200741c796c600470d010c070b20082006490d03200841a6014b0d04200641c796c6006a2100024003402003450d012003417f6a210320002d00002106200041016a210020062004470d000c0b0b0b2008210620072100200741c796c600470d000c060b0b200620081030000b200841a502108f01000b200620081030000b200841a601108f01000b200241017267410276410773ad4280808080d0008421090c040b200241ffff0371210441ed97c60021034101210002400340200341016a21080240024020032d0000220641187441187522074100480d00200821030c010b200841859bc600460d02200741ff007141087420032d0001722106200341026a21030b200420066b22044100480d0320004101732100200341859bc600470d000c030b0b41e882c600106d000b200241ffff0371210441c793c6002103410121000340200341016a21080240024020032d0000220641187441187522074100480d00200821030c010b2008418196c600460d05200741ff007141087420032d0001722106200341026a21030b200420066b22044100480d01200041017321002003418196c600470d000b0b4101210320004101710d030b200241017267410276410773ad4280808080d0008421090b410321030c020b41e882c600106d000b0b200221040b03402003210641dc0021004101210241012103024002400240024020060e0401020300010b024002400240024002402009422088a741ff01710e06050403020100050b200942ffffffff8f60834280808080c000842109410321030c060b200942ffffffff8f608342808080803084210941f5002100410321030c050b200942ffffffff8f608342808080802084210941fb002100410321030c040b20042009a72206410274411c7176410f712203413072200341d7006a2003410a491b210002402006450d002009427f7c42ffffffff0f83200942808080807083842109410321030c040b200942ffffffff8f6083428080808010842109410321030c030b200942ffffffff8f6083210941fd002100410321030c020b20012802184127200128021c2802101103000f0b41002103200421000b20012802182000200128021c280210110300450d000b0b20020b950201017f024002402000418010490d00024002400240024002400240200041808004490d002000410c7641706a2201418002490d0141a89bc60020014180021036000b200041067641606a220141df074b0d01200141f086c6006a2d0000220141c9004b0d02200141037441809cc6006a21010c060b200141d08ec6006a2d00004106742000410676413f7172220141ff034b0d02200141d0a0c6006a2d0000220141394b0d03200141037441d0a4c6006a21010c050b41889bc600200141e0071036000b41989bc600200141ca001036000b41b89bc60020014180041036000b41c89bc6002001413a1036000b200041037641f8ffffff017141d884c6006a21010b200129030042012000413f71ad86834200520bb20201037f23004180016b2202240002400240024002400240200128020022034110710d002000280200210420034120710d012004ad4101200110a70221000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d0220014101418882c6004102200220006a4180016a410020006b10a80221000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d0220014101418882c6004102200220006a4180016a410020006b10a80221000b20024180016a240020000f0b20044180011030000b20044180011030000b0e0020003502004101200110a7020b1c00200128021841a1a9c600410b2001411c6a28020028020c1104000b1c00200128021841aca9c600410e2001411c6a28020028020c1104000b140020002802002001200028020428020c1103000bc30501077f410021040240024020024103712205450d00410420056b2205450d00200220032005200520034b1b22046a210641002105200141ff017121072004210820022109024003400240200620096b41034b0d0041002107200141ff0171210603402008450d04200920076a210a2008417f6a2108200741016a2107200a2d0000220a2006470d000b2005200a200141ff01714641016a4101716a20076a417f6a21050c020b200520092d0000220a2007476a2105200a2007460d012005200941016a2d0000220a2007476a2105200a2007460d012005200941026a2d0000220a2007476a2105200a2007460d012005200941036a2d0000220a2007476a21052008417c6a2108200941046a2109200a2007470d000b0b410121090c010b200141ff017121070240024020034108490d002004200341786a220a4b0d00200741818284086c210502400340200220046a220941046a2802002005732208417f73200841fffdfb776a7120092802002005732209417f73200941fffdfb776a7172418081828478710d01200441086a2204200a4d0d000b0b200420034b0d010b200220046a2109200220036a2102200320046b2108410021050240024003400240200220096b41034b0d0041002107200141ff0171210203402008450d04200920076a210a2008417f6a2108200741016a2107200a2d0000220a2002470d000b200a200141ff01714641016a41017120056a20076a417f6a21050c020b200520092d0000220a2007476a2105200a2007460d012005200941016a2d0000220a2007476a2105200a2007460d012005200941026a2d0000220a2007476a2105200a2007460d012005200941036a2d0000220a2007476a21052008417c6a2108200941046a2109200a2007470d000b0b41012109200520046a21050c020b41002109200520076a20046a21050c010b200420031030000b20002005360204200020093602000b2701017f20002802002201280200200128020420002802042802002000280208280200108305000b02000ba70401077f230041306b220324000240024020020d00410021040c010b200341286a210502400240024002400340024020002802082d0000450d0020002802004184abc6004104200028020428020c1104000d050b2003410a3602282003428a808080103703202003200236021c200341003602182003200236021420032001360210200341086a410a20012002108c05024002400240024020032802084101470d00200328020c210403402003200420032802186a41016a2204360218024002402004200328022422064f0d00200328021421070c010b200328021422072004490d00200641054f0d072003280210200420066b22086a22092005460d04200920052006109d05450d040b200328021c22092004490d0220072009490d0220032006200341106a6a41176a2d0000200328021020046a200920046b108c052003280204210420032802004101460d000b0b2003200328021c3602180b200028020841003a0000200221040c010b200028020841013a0000200841016a21040b2000280204210920002802002106024020044520022004467222070d00200220044d0d03200120046a2c000041bf7f4c0d030b200620012004200928020c1104000d04024020070d00200220044d0d04200120046a2c000041bf7f4c0d040b200120046a2101200220046b22020d000b410021040c040b20064104108f01000b2001200241002004108305000b2001200220042002108305000b410121040b200341306a240020040bfa0101017f230041106b220224002002410036020c0240024002402001418001490d002001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c020b200220013a000c410121010c010b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010b20002002410c6a2001108f052101200241106a240020010b6101017f230041206b2202240020022000360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41ecaac600200241086a10d8042101200241206a240020010b0e00200028020020012002108f050b810201017f230041106b22022400200028020021002002410036020c0240024002402001418001490d002001418010490d0102402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c020b200220013a000c410121010c010b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010b20002002410c6a2001108f052101200241106a240020010b6401017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41ecaac600200241086a10d8042101200241206a240020010bc30201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d0020002d0000210420034120710d012004ad42ff01834101200110a70221000c020b20002d00002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d0220014101418882c6004102200220006a4180016a410020006b10a80221000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d0220014101418882c6004102200220006a4180016a410020006b10a80221000b20024180016a240020000f0b20044180011030000b20044180011030000b0c00200028020020011087050b820201027f230041106b22022400200128021841c0abc60041092001411c6a28020028020c1104002103200241003a0005200220033a0004200220013602002002200036020c200241c9abc600410b2002410c6a4198abc60010dc0421012002200041046a36020c200141d4abc60041092002410c6a41e0abc60010dc041a20022d00042101024020022d0005450d00200141ff0171210041012101024020000d0020022802002201411c6a28020028020c210020012802182103024020012d00004104710d002003418eabc6004102200011040021010c010b20034190abc6004101200011040021010b200220013a00040b200241106a2400200141ff01714100470bb60201027f230041106b2202240002400240200028020022002d00004101460d00200128021841b8abc60041042001411c6a28020028020c11040021010c010b2002200128021841bcabc60041042001411c6a28020028020c1104003a000820022001360200200241003a0009200241003602042002200041016a36020c20022002410c6a41a8abc60010d4041a20022d00082101024020022802042203450d00200141ff0171210041012101024020000d00024020034101470d0020022d000941ff0171450d00200228020022002d00004104710d004101210120002802184194abc60041012000411c6a28020028020c1104000d010b2002280200220128021841cbaac60041012001411c6a28020028020c11040021010b200220013a00080b200141ff017141004721010b200241106a240020010b1c00200128021841f0abc60041052001411c6a28020028020c1104000b2c01017f02402002450d00200021030340200320013a0000200341016a21032002417f6a22020d000b0b20000b3601017f02402002450d00200021030340200320012d00003a0000200341016a2103200141016a21012002417f6a22020d000b0b20000b7101017f0240024020012000490d002002450d01200021030340200320012d00003a0000200141016a2101200341016a21032002417f6a22020d000c020b0b2002450d002001417f6a21012000417f6a21030340200320026a200120026a2d00003a00002002417f6a22020d000b0b20000b4a01037f4100210302402002450d000240034020002d0000220420012d00002205470d01200141016a2101200041016a21002002417f6a2202450d020c000b0b200420056b21030b20030b5701017e02400240200341c000710d002003450d012001410020036b413f71ad8820022003413f71ad220486842102200120048621010c010b20012003413f71ad862102420021010b20002001370300200020023703080b5701017e02400240200341c000710d002003450d0120012003413f71ad2204882002410020036b413f71ad86842101200220048821020c010b20022003413f71ad882101420021020b20002001370300200020023703080b7501027e200020034220882205200142208822067e200320027e7c200420017e7c200342ffffffff0f832203200142ffffffff0f8322017e2204422088200320067e7c22034220887c200342ffffffff0f83200520017e7c22034220887c37030820002003422086200442ffffffff0f83843703000b3e01017f230041106b2205240020052001200220032004410010a305200529030021012000200541086a29030037030820002001370300200541106a24000b4c01017f230041206b22052400200542003703182005420037031020052001200220032004200541106a10a305200529031021012000200529031837030820002001370300200541206a24000be20502037f067e230041306b2206240002400240024002400240024002400240024002402002500d002003500d012004500d02200479a7200279a76b2207413f4b0d0341ff0020076b2108200741016a21070c080b02402004500d0020050d040c060b024002402005450d0020034200510d0620054200370308200520012003823703000c010b20034200510d050b200120038021010c060b2004500d030240024002402001500d0020047b4201510d01200479a7200279a76b2207413e4b0d0241ff0020076b2108200741016a21070c090b02402005450d0020054200370300200520022004823703080b200220048021010c070b02402005450d002005200137030020052004427f7c2002833703080b200220047a423f838821010c060b2005450d040c020b024020037b4201510d0041bf7f200379a7200279a76b22076b2108200741c1006a21070c060b02402005450d002005420037030820052003427f7c2001833703000b20034201510d06200641206a2001200220037aa7109f05200641286a2903002102200629032021010c060b2005450d020b2005200137030020052002370308420021010c020b00000b420021010b420021020c010b200620012002200841ff0071109e05200641106a20012002200741ff0071109f05200641086a2903002102200641106a41086a2903002109200629030021012006290310210a0240024020070d004200210b4200210c0c010b4200210c4200210d03402009420186200a423f8884220b200b427f8520047c200a4201862002423f8884220a427f85220b20037c200b54ad7c423f87220b2004837d200a200b200383220e54ad7d2109200a200e7d210a420020024201862001423f8884842102200d2001420186842101200b420183220b210d2007417f6a22070d000b0b02402005450d002005200a370300200520093703080b200c20024201862001423f8884842102200b20014201868421010b2000200137030020002002370308200641306a24000b0b90ac060200418080c0000bf5ab06180010001d000000686c110013000000dc03000009000000617373657274696f6e206661696c65643a20696e646578203c206c656e0000005000100043000000f10a00003000000000000000000000002f72757374632f353231643738343037343731636237386539626266343731363066366161323330343761633439392f7372632f6c6962616c6c6f632f7665632e7273005000100043000000fd0a00002c0000000000000040e8100008000000000000008802100002000000000000000000000064801100000000000000000000000000980210000600000000000000a002100003000000000000000000000064801100000000000000000000000000b80210000e000000000000006480110000000000000000000000000064801100000000000000000000000000c60210000700000000000000d002100002000000000000000000000064801100000000000000000000000000e00210000600000000000000e802100001000000000000000000000064801100000000000000000000000000f00210000900000000000000e802100001000000000000000000000064801100000000000000000000000000f90210000900000000000000e802100001000000000000000000000064801100000000000000000000000000dce8100008000000000000000403100002000000000000000000000064801100000000000000000000000000140310000900000000000000a8fa1000020000000000000000000000648011000000000000000000000000001d0310000b0000000000000018c4100001000000000000000000000064801100000000000000000000000000280310000600000000000000300310000300000000000000000000006480110000000000000000006f031000090000008f1e1100070000005461626c656400006f031000090000008f1e110007000000125d10000e00000045787465726e616c5461626c656453746172746564000000530310000f000000620310000d0000005061737365640000530310000f0000004e6f7450617373656443616e63656c6c65640000530310000f000000d6fb10000400000044656c656761746564556e64656c6567617465645665746f65640000861e11000900000038fc100004000000480310000b000000426c6f636b4e756d6265725265666572656e64756d496e646578566f74655468726573686f6c6450726f70496e64657844656d6f637261637920566f74654f6644656d6f63726163792044656c65676174696f6e7344656d6f6372616379205265666572656e64756d496e666f4f6644656d6f6372616379204465706f7369744f6644656d6f6372616379204469737061746368517565756544656d6f637261637920566f74657273466f7268656164206f662044656d6f63726163792044656c65676174696f6e7344656d6f6372616379205075626c696350726f70730000a004100048000000a10a00000e0000004e6f207075626c69632070726f706f73616c732077616974696e6743616e6e6f7420696e6a6563742061207265666572656e64756d207468617420656e6473206561726c696572207468616e2070726563656564696e67207265666572656e64756d0000000000002f72757374632f353231643738343037343731636237386539626266343731363066366161323330343761633439392f7372632f6c6962636f72652f736c6963652f6d6f642e727344656d6f6372616379204e65787445787465726e616c4e6f2065787465726e616c2070726f706f73616c2077616974696e6700000000000008f0100007000000000000000808100002000000000000000000000038081000060000000000000000000000680810000600000000000000700810000100000000000000000000008808100006000000000000000000000060f010000400000000000000b8081000020000000000000000000000e8081000070000000000000000000000200910000a00000000000000b80810000200000000000000000000002c091000070000000000000000000000640910001000000000000000740910000100000000000000000000008c0910000200000000000000000000009c091000100000000000000074e31000010000000000000000000000ac091000020000000000000000000000bc091000190000000000000074e31000010000000000000000000000d8091000050000000000000000000000000a1000180000000000000074e31000010000000000000000000000180a1000050000000000000000000000400a10000a000000000000004c0a1000030000000000000000000000940a1000080000000000000000000000d40a10000d00000000000000e40a1000010000000000000000000000fc0a1000010000000000000000000000040b10001100000000000000180b1000010000000000000000000000300b1000010000000000000000000000380b10000d00000000000000480b1000030000000000000000000000900b1000010000000000000000000000980b10000900000000000000a40b1000010000000000000000000000bc0b1000050000000000000000000000e40b10000c0000000000000064801100000000000000000000000000f00b1000050000000000000000000000180c10000c00000000000000a40b1000010000000000000000000000240c10000500000000000000000000004c0c10000800000000000000540c1000020000000000000000000000840c1000050000000000000000000000ac0c10000a0000000000000064801100000000000000000000000000b80c100005000000000000000000000044f11000080000000000000055e5100010000000000000000f3311000500000000000000143311001500000080131000280000006480110000000000d52811000b0000004f34110008000000ba13100020000000f02811000c0000007365636f6e6400000000000044f110000800000000000000a81310001200000080131000280000006480110000000000d52811000b0000004f34110008000000f532110010000000f02811000c00000000000000ef0d10000900000000000000c20d1000180000000000000060f0100004000000000000007c13100004000000001310004d0000004d1310002f0000006480110000000000d52811000b0000004f34110008000000e11210001f000000f02811000c00000070726f78795f766f746500004f12100054000000a31210003e0000006480110000000000d52811000b0000004f34110008000000e11210001f000000f02811000c000000656d657267656e63795f63616e63656c00000000ef0d10000900000000000000530310000f000000fb11100054000000ef1110000c00000065787465726e616c5f70726f706f7365a31110004c000000ef1110000c00000065787465726e616c5f70726f706f73655f6d616a6f7269747900000035111000560000008b111000180000006480110000000000bb101000530000000e1110002700000065787465726e616c5f70726f706f73655f64656661756c7448101000520000009a101000210000006480110000000000bb101000530000000e11100027000000666173745f747261636b000000000000270e10000d000000000000004cf110000700000000000000361010000d00000000000000df0e11000e00000000000000431010000500000000000000df0e11000e000000340e100054000000880e100059000000e10e10003b00000064801100000000001c0f10003e0000005a0f10004b000000a50f100055000000fa0f10003c0000007665746f5f65787465726e616c00000000000000270e10000d000000000000004cf1100007000000f80d10002f00000063616e63656c5f7265666572656e64756d00000000000000ef0d10000900000000000000c20d100018000000da0d10001500000063616e63656c5f71756575656400000000000000b50d100004000000000000009b7610001700000000000000b90d100005000000000000004b2911000c00000000000000be0d10000400000000000000c20d1000180000008d0d1000280000007365745f70726f787900000000000000880d100005000000000000007a3d11000c000000620d1000260000006480110000000000d52811000b00000029b0100016000000f02811000c00000072657369676e5f70726f78793c0d1000260000006480110000000000d52811000b0000004567100010000000f02811000c00000072656d6f76655f70726f7879160d1000260000006480110000000000d52811000b0000004567100010000000f02811000c00000064656c656761746500000000000d100002000000000000007a3d11000c00000000000000020d10000a000000000000000c0d10000a000000f10c10000f0000006480110000000000d52811000b00000029b0100016000000f02811000c000000756e64656c65676174650000e00c1000110000006480110000000000d52811000b0000004f34110008000000f02811000c00000020556e64656c656761746520766f74652e2044656c656761746520766f74652e746f636f6e76696374696f6e436f6e76696374696f6e20436c656172207468652070726f78792e2043616c6c6564206279207468652073746173682e20436c656172207468652070726f78792e2043616c6c6564206279207468652070726f78792e205370656369667920612070726f78792e2043616c6c6564206279207468652073746173682e70726f78792043616e63656c20612070726f706f73616c2071756575656420666f7220656e6163746d656e742e7768656e776869636877686174436f6d706163743c5265666572656e64756d496e6465783e2052656d6f76652061207265666572656e64756d2e7265665f696e646578205665746f20616e6420626c61636b6c697374207468652065787465726e616c2070726f706f73616c20686173682e70726f706f73616c5f68617368205363686564756c65207468652063757272656e746c792065787465726e616c6c792d70726f706f736564206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c656420696d6d6564696174656c792e204966207468657265206973206e6f2065787465726e616c6c792d70726f706f736564207265666572656e64756d2063757272656e746c792c206f72206966207468657265206973206f6e6520627574206974206973206e6f742061206d616a6f726974792d63617272696573207265666572656e64756d207468656e206974206661696c732e202d206070726f706f73616c5f68617368603a205468652068617368206f66207468652063757272656e742065787465726e616c2070726f706f73616c2e202d2060766f74696e675f706572696f64603a2054686520706572696f64207468617420697320616c6c6f77656420666f7220766f74696e67206f6e20746869732070726f706f73616c2e202d206064656c6179603a20546865206e756d626572206f6620626c6f636b20616674657220766f74696e672068617320656e64656420696e20617070726f76616c20616e6420746869732073686f756c64206265202020656e61637465642e20496e6372656173656420746f2060456d657267656e6379566f74696e67506572696f646020696620746f6f206c6f772e766f74696e675f706572696f6464656c6179205363686564756c652061206e656761746976652d7475726e6f75742d62696173207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e20556e6c696b65206065787465726e616c5f70726f706f7365602c20626c61636b6c697374696e6720686173206e6f20656666656374206f6e207468697320616e64206974206d6179207265706c6163652061207072652d7363686564756c6564206065787465726e616c5f70726f706f7365602063616c6c2e205363686564756c652061206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e205363686564756c652061207265666572656e64756d20746f206265207461626c6564206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e205363686564756c6520616e20656d657267656e63792063616e63656c6c6174696f6e206f662061207265666572656e64756d2e2043616e6e6f742068617070656e20747769636520746f207468652073616d6520566f746520696e2061207265666572656e64756d206f6e20626568616c66206f6620612073746173682e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b20206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e202d204f6e65204442206368616e67652c206f6e6520444220656e7472792e20566f746520696e2061207265666572656e64756d2e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e566f74652050726f706f736520612073656e73697469766520616374696f6e20746f2062652074616b656e2e436f6d706163743c50726f70496e6465783e202d2054776f204442206368616e6765732c206f6e6520444220656e7472792e000000000000041910000f00000000000000000000006f0310000900000000000000000000000000000000000000000000000000000000000000f8951100d4191000000000000000000014191000010000000000000001000000000000001c1910000b0000000000000000000000271910002b00000000000000000000000000000000000000000000000000000000000000f895110054191000000000000000000064191000010000000000000001000000000000006c1910000900000001010000000000006f0310000900000000000000751910002100000000000000000000000000000000000000f8951100981910000000000000000000a819100001000000000000000000000000000000b01910000f0000000000000000000000530310000f00000000000000000000000000000000000000000000000000000000000000f8951100d41910000000000000000000c019100001000000000000000100000000000000c8191000090000000000000000000000530310000f00000000000000000000000000000000000000000000000000000000000000f8951100d41910000000000000000000e419100001000000000000000100000000000000ec191000100000000101000000000000530310000f00000000000000fc1910002d00000000000000000000000000000000000000f8951100001b100000000000000000002c1a100001000000000000000000000000000000341a10000d0000000101000000000000df0e11000e00000000000000411a10002b00000000000000000000000000000000000000f89511006c1a100000000000000000007c1a100001000000000000000100000000000000841a1000090000000101000000000000530310000f00000000000000492811001100000000000000000000000000000000000000f8951100901a10000000000000000000a01a100001000000000000000100000000000000a81a1000060000000101000000000000ae1a10001f000000000000007c1310000400000000000000000000000000000000000000f8951100d01a10000000000000000000e01a100004000000000000000100000000000000b88a10000500000001010000000000007a3d11000c000000000000007a3d11000c00000000000000000000000000000000000000f8951100001b10000000000000000000d08a100002000000000000000000000000000000101b10000b00000001010100000000007a3d11000c000000000000001b1b10001a00000000000000000000000000000000000000f8951100381b10000000000000000000481b100001000000000000000100000000000000501b1000150000000000000000000000d6fb10000400000000000000000000000000000000000000000000000000000000000000f89511002c1c10000000000000000000681b100002000000000000000100000000000000781b10000c0000000000000000000000841b10001c00000000000000000000000000000000000000000000000000000000000000f8951100a01b10000000000000000000b01b100004000000000000000000000000000000d01b10000900000001010000000000004cf110000700000000000000d91b10002300000000000000000000000000000000000000f8951100fc1b100000000000000000000c1c1000020000000000000000000000000000001c1c10000d00000001010000000000004cf110000700000000000000d6fb10000400000000000000000000000000000000000000f89511002c1c100000000000000000003c1c10000100000000000000010000005075626c696350726f70436f756e74003e2110003d0000005075626c696350726f70735665633c2850726f70496e6465782c20543a3a50726f706f73616c2c20543a3a4163636f756e744964293e0000320000000000000001000000330000001e211000200000004465706f7369744f662842616c616e63654f663c543e2c205665633c543a3a4163636f756e7449643e29000032000000000000000100000034000000fd201000210000005265666572656e64756d436f756e7400b12010004c0000004e65787454616c6c79000000320000000000000001000000350000007f201000320000005265666572656e64756d496e666f4f66285265666572656e64756d496e666f3c543a3a426c6f636b4e756d6265722c20543a3a50726f706f73616c3e29000000522010002d000000446973706174636851756575655665633c4f7074696f6e3c28543a3a50726f706f73616c2c205265666572656e64756d496e646578293e3e320000000000000001000000330000002220100030000000566f74657273466f7200000032000000000000000100000033000000f91f100029000000566f74654f66285265666572656e64756d496e6465782c20543a3a4163636f756e7449642900000032000000000000000100000036000000ba1e100058000000121f100053000000651f100057000000bc1f10003d0000003200000000000000010000003600000044656c65676174696f6e7328543a3a4163636f756e7449642c20436f6e76696374696f6e29000000320000000000000001000000370000006a1e1000500000004c6173745461626c656457617345787465726e616c0000000a1e100056000000601e10000a0000004e65787445787465726e616c28543a3a50726f706f73616c2c20566f74655468726573686f6c6429320000000000000001000000380000001c1d100056000000721d100055000000c71d100029000000f01d10001a000000426c61636b6c69737428543a3a426c6f636b4e756d6265722c205665633c543a3a4163636f756e7449643e29320000000000000001000000340000008e1c100054000000e21c10003a00000043616e63656c6c6174696f6e7300000032000000000000000100000036000000441c10004a000000205265636f7264206f6620616c6c2070726f706f73616c7320746861742068617665206265656e207375626a65637420746f20656d657267656e63792063616e63656c6c6174696f6e2e2041207265636f7264206f662077686f207665746f656420776861742e204d6170732070726f706f73616c206861736820746f206120706f737369626c65206578697374656e7420626c6f636b206e756d6265722028756e74696c207768656e206974206d6179206e6f742062652072657375626d69747465642920616e642077686f207665746f65642069742e20546865207265666572656e64756d20746f206265207461626c6564207768656e6576657220697420776f756c642062652076616c696420746f207461626c6520616e2065787465726e616c2070726f706f73616c2e20546869732068617070656e73207768656e2061207265666572656e64756d206e6565647320746f206265207461626c656420616e64206f6e65206f662074776f20636f6e646974696f6e7320617265206d65743a202d20604c6173745461626c656457617345787465726e616c60206973206066616c7365603b206f72202d20605075626c696350726f70736020697320656d7074792e205472756520696620746865206c617374207265666572656e64756d207461626c656420776173207375626d69747465642065787465726e616c6c792e2046616c7365206966206974207761732061207075626c69632070726f706f73616c2e2047657420746865206163636f756e742028616e64206c6f636b20706572696f64732920746f20776869636820616e6f74686572206163636f756e742069732064656c65676174696e6720766f74652e204765742074686520766f746520696e206120676976656e207265666572656e64756d206f66206120706172746963756c617220766f7465722e2054686520726573756c74206973206d65616e696e6766756c206f6e6c792069662060766f746572735f666f726020696e636c756465732074686520766f746572207768656e2063616c6c6564207769746820746865207265666572656e64756d2028796f75276c6c20676574207468652064656661756c742060566f7465602076616c7565206f7468657277697365292e20496620796f7520646f6e27742077616e7420746f20636865636b2060766f746572735f666f72602c207468656e20796f752063616e20616c736f20636865636b20666f722073696d706c65206578697374656e636520776974682060566f74654f663a3a657869737473602066697273742e204765742074686520766f7465727320666f72207468652063757272656e742070726f706f73616c2e205175657565206f66207375636365737366756c207265666572656e646120746f20626520646973706174636865642e20496e666f726d6174696f6e20636f6e6365726e696e6720616e7920676976656e207265666572656e64756d2e20546865206e657874207265666572656e64756d20696e64657820746861742073686f756c642062652074616c6c6965642e20546865206e6578742066726565207265666572656e64756d20696e6465782c20616b6120746865206e756d626572206f66207265666572656e6461207374617274656420736f206661722e2054686f73652077686f2068617665206c6f636b65642061206465706f7369742e20546865207075626c69632070726f706f73616c732e20556e736f727465642e20546865206e756d626572206f6620287075626c6963292070726f706f73616c7320746861742068617665206265656e206d61646520736f206661722e0000000000cc2210000f00000000000000df0e11000e00000000000000f8951100dc2210000000000000000000ec221000050000000000000000000000142310000c00000000000000df0e11000e00000000000000f895110098231000000000000000000020231000010000000000000000000000389410000c00000000000000df0e11000e00000000000000f895110098231000000000000000000028231000010000000000000000000000302310000e00000000000000753f11000c00000000000000f895110040231000000000000000000050231000010000000000000000000000582310001500000000000000df0e11000e00000000000000f895110070231000000000000000000080231000010000000000000000000000882310000d00000000000000df0e11000e00000000000000f8951100982310000000000000000000a82310000100000000000000456e6163746d656e74506572696f640032000000000000000100000039000000f72410005c0000006480110000000000532510004c0000009f2510005a000000f9251000270000004c61756e6368506572696f64be24100039000000902410002e0000004d696e696d756d4465706f73697400003200000000000000010000003a000000432410004d000000456d657267656e6379566f74696e67506572696f640000003200000000000000010000003b000000082410003b000000436f6f6c6f6666506572696f640000003200000000000000010000003c000000b02310005800000020506572696f6420696e20626c6f636b7320776865726520616e2065787465726e616c2070726f706f73616c206d6179206e6f742062652072652d7375626d6974746564206166746572206265696e67207665746f65642e204d696e696d756d20766f74696e6720706572696f6420616c6c6f77656420666f7220616e20656d657267656e6379207265666572656e64756d2e20546865206d696e696d756d20616d6f756e7420746f20626520757365642061732061206465706f73697420666f722061207075626c6963207265666572656e64756d2070726f706f73616c2e20486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e20486f77206f6674656e2028696e20626c6f636b7329206e6577207075626c6963207265666572656e646120617265206c61756e636865642e20546865206d696e696d756d20706572696f64206f66206c6f636b696e6720616e642074686520706572696f64206265747765656e20612070726f706f73616c206265696e6720617070726f76656420616e6420656e61637465642e2049742073686f756c642067656e6572616c6c792062652061206c6974746c65206d6f7265207468616e2074686520756e7374616b6520706572696f6420746f20656e73757265207468617420766f74696e67207374616b657273206861766520616e206f70706f7274756e69747920746f2072656d6f7665207468656d73656c7665732066726f6d207468652073797374656d20696e207468652063617365207768657265207468657920617265206f6e20746865206c6f73696e672073696465206f66206120766f74652e047411002800000038261000440000004d010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f64656d6f63726163792f7372632f6c69622e727338261000440000004d0100000100000076616c756520746f6f206c6f7770726f706f73657227732062616c616e636520746f6f206c6f7763616e206f6e6c79207365636f6e6420616e206578697374696e672070726f706f73616c7365636f6e64657227732062616c616e636520746f6f206c6f7744656d6f63726163792043616e63656c6c6174696f6e7370726f706f73616c207374696c6c20626c61636b6c697374656470726f706f73616c20616c7265616479206d616465696e76616c696420686173686e6578742065787465726e616c2070726f706f73616c206e6f742073696d706c65206d616a6f726974796e6f2070726f706f73616c206d61646544656d6f637261637920426c61636b6c6973746e6f2065787465726e616c2070726f706f73616c756e6b6e6f776e2070726f706f73616c6964656e74697479206d6179206e6f74207665746f20612070726f706f73616c20747769636544656d6f63726163792050726f7879616c726561647920612070726f787977726f6e672070726f78796e6f742064656c656761746564756e6b6e6f776e20696e64657863616e6e6f742063616e63656c207468652073616d652070726f706f73616c20747769636570726f706f73616c206e6f7420666f756e64766f746520676976656e20666f7220696e76616c6964207265666572656e64756d2e2f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d312e302e352f7372632f636f6d706163742e727300000000000000602910000a00000000000000a01d11000200000000000000000000006c291000010000000000000000000000742910000d0000000000000018c410000100000000000000000000008429100001000000000000000000000074fa100008000000000000008c291000040000000000000000000000ac29100001000000000000004e65774163636f756e740000f72910001b0000005265617065644163636f756e74000000e029100017000000861e110009000000861e1100090000008f1e1100070000008f1e110007000000b42910002c000000205472616e7366657220737563636565646564202866726f6d2c20746f2c2076616c75652c2066656573292e20416e206163636f756e7420776173207265617065642e2041206e6577206163636f756e742077617320637265617465642e76657374696e672062616c616e636520746f6f206869676820746f2073656e642076616c75656163636f756e74206c6971756964697479207265737472696374696f6e732070726576656e74207769746864726177616c62656e6566696369617279206163636f756e74206d757374207072652d6578697374746f6f2066657720667265652066756e647320696e206163636f756e747061796d656e7420776f756c64206b696c6c206163636f756e7442616c616e63657320546f74616c49737375616e636542616c616e636573204672656542616c616e636542616c616e63657320526573657276656442616c616e636542616c616e636573204c6f636b7300008d2b10003600000076281000630000005e01000005000000000000000000000000000000502b10003d00000076281000630000006501000005000000736869667465642073756666696369656e74206269747320726967687420746f206c656164206f6e6c79206c656164696e67207a65726f733b2071656450726576696f7573206d617463682061726d206d61746368657320616e7974696e67206c657373207468616e20325e33303b20716564008d2b10003600000076281000630000008a010000050000000000000000000000000000000000000000000000762810006300000091010000050000004469676573744974656d206e6f7420657175616c42616c616e6365732056657374696e6700000000a82c10000800000000000000b02c1000020000000000000000000000e02c1000170000000000000000000000982d10000b00000000000000a42d1000030000000000000000000000ec2d10000d0000000000000000000000542e10000e00000000000000642e1000030000000000000000000000ac2e100002000000000000007472616e73666572000000005a0111000400000000000000a32a110023000000000000000f3311000500000000000000212f100013000000f53010003600000064801100000000002b311000420000006d31100048000000b531100045000000fa3110002d000000648011000000000027321000460000006480110000000000d52811000b0000006d3210004c000000b932100033000000ec3210005a0000006480110000000000463310001300000064801100000000005933100054000000ad3310004b000000f8331000350000002d3410003700000064341000560000006480110000000000f02811000c0000007365745f62616c616e636500000000007ee110000300000000000000a32a11002300000000000000e13010000800000000000000212f10001300000000000000e93010000c00000000000000212f100013000000342f1000250000006480110000000000592f100048000000a12f100042000000e32f100046000000293010003a0000006480110000000000633010002d0000006480110000000000d52811000b0000009030100020000000b030100031000000f02811000c000000666f7263655f7472616e736665720000000000001b2f10000600000000000000a32a110023000000000000005a0111000400000000000000a32a110023000000000000000f3311000500000000000000212f100013000000bc2e100054000000102f10000b0000002045786163746c7920617320607472616e73666572602c2065786365707420746865206f726967696e206d75737420626520726f6f7420616e642074686520736f75726365206163636f756e74206d6179206265207370656369666965642e736f75726365436f6d706163743c543a3a42616c616e63653e20536574207468652062616c616e636573206f66206120676976656e206163636f756e742e20546869732077696c6c20616c74657220604672656542616c616e63656020616e642060526573657276656442616c616e63656020696e2073746f726167652e2069742077696c6c20616c736f2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d202860546f74616c49737375616e636560292e20496620746865206e65772066726565206f722072657365727665642062616c616e63652069732062656c6f7720746865206578697374656e7469616c206465706f7369742c2069742077696c6c20726573657420746865206163636f756e74206e6f6e636520286073797374656d3a3a4163636f756e744e6f6e636560292e20546865206469737061746368206f726967696e20666f7220746869732063616c6c2069732060726f6f74602e202d20496e646570656e64656e74206f662074686520617267756d656e74732e202d20436f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e64207772697465732e6e65775f667265656e65775f7265736572766564205472616e7366657220736f6d65206c697175696420667265652062616c616e636520746f20616e6f74686572206163636f756e742e20607472616e73666572602077696c6c207365742074686520604672656542616c616e636560206f66207468652073656e64657220616e642072656365697665722e2049742077696c6c2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d2062792074686520605472616e73666572466565602e204966207468652073656e6465722773206163636f756e742069732062656c6f7720746865206578697374656e7469616c206465706f736974206173206120726573756c74206f6620746865207472616e736665722c20746865206163636f756e742077696c6c206265207265617065642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d75737420626520605369676e65646020627920746865207472616e736163746f722e202d20446570656e64656e74206f6e20617267756d656e747320627574206e6f7420637269746963616c2c20676976656e2070726f70657220696d706c656d656e746174696f6e7320666f72202020696e70757420636f6e6669672074797065732e205365652072656c617465642066756e6374696f6e732062656c6f772e202d20497420636f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e642077726974657320696e7465726e616c6c7920616e64206e6f20636f6d706c657820636f6d7075746174696f6e2e2052656c617465642066756e6374696f6e733a2020202d2060656e737572655f63616e5f77697468647261776020697320616c776179732063616c6c656420696e7465726e616c6c792062757420686173206120626f756e64656420636f6d706c65786974792e2020202d205472616e7366657272696e672062616c616e63657320746f206163636f756e7473207468617420646964206e6f74206578697374206265666f72652077696c6c20636175736520202020202060543a3a4f6e4e65774163636f756e743a3a6f6e5f6e65775f6163636f756e746020746f2062652063616c6c65642e2020202d2052656d6f76696e6720656e6f7567682066756e64732066726f6d20616e206163636f756e742077696c6c2074726967676572202020202060543a3a4475737452656d6f76616c3a3a6f6e5f756e62616c616e6365646020616e642060543a3a4f6e4672656542616c616e63655a65726f3a3a6f6e5f667265655f62616c616e63655f7a65726f602e000000000000743610000d0000000000000000000000813610000a00000000000000000000000000000000000000000000000000000000000000f89511005437100000000000000000008c36100001000000000000000100000000000000943610000700000001010000000000007a3d11000c000000000000009b3610002b00000000000000000000000000000000000000f8951100c83610000000000000000000d836100001000000000000000000000000000000e03610000b00000001010000000000007a3d11000c00000000000000813610000a00000000000000000000000000000000000000f8951100543710000000000000000000ec3610000b000000000000000100000000000000443710000f00000001010000000000007a3d11000c00000000000000813610000a00000000000000000000000000000000000000f8951100543710000000000000000000643710000b000000000000000100000000000000bc3710000500000001010000000000007a3d11000c00000000000000c13710002c00000000000000000000000000000000000000f8951100f0371000000000000000000000381000010000000000000001000000546f74616c49737375616e6365543a3a42616c616e636500313d10002600000056657374696e6756657374696e675363686564756c653c543a3a42616c616e63652c20543a3a426c6f636b4e756d6265723e000032000000000000000100000036000000fb3c1000360000004672656542616c616e636500813a1000270000006480110000000000a83a100050000000f83a10005d000000553b100055000000aa3b10004f000000f93b1000510000004a3c10001500000064801100000000005f3c100057000000b63c100045000000526573657276656442616c616e6365003200000000000000010000003d000000363810005d00000093381000270000006480110000000000ba3810005b000000153910004900000064801100000000005e3910005d000000bb3910002d0000006480110000000000e8391000530000003b3a1000460000004c6f636b735665633c42616c616e63654c6f636b3c543a3a42616c616e63652c20543a3a426c6f636b4e756d6265723e3e00000032000000000000000100000033000000083810002e00000020416e79206c6971756964697479206c6f636b73206f6e20736f6d65206163636f756e742062616c616e6365732e2054686520616d6f756e74206f66207468652062616c616e6365206f66206120676976656e206163636f756e7420746861742069732065787465726e616c6c792072657365727665643b20746869732063616e207374696c6c2067657420736c61736865642c20627574206765747320736c6173686564206c617374206f6620616c6c2e20546869732062616c616e63652069732061202772657365727665272062616c616e63652074686174206f746865722073756273797374656d732075736520696e206f7264657220746f2073657420617369646520746f6b656e73207468617420617265207374696c6c20276f776e65642720627920746865206163636f756e7420686f6c6465722c20627574207768696368206172652073757370656e6461626c652e205768656e20746869732062616c616e63652066616c6c732062656c6f77207468652076616c7565206f6620604578697374656e7469616c4465706f736974602c207468656e2074686973202772657365727665206163636f756e74272069732064656c657465643a207370656369666963616c6c792c2060526573657276656442616c616e6365602e206073797374656d3a3a4163636f756e744e6f6e63656020697320616c736f2064656c6574656420696620604672656542616c616e63656020697320616c736f207a65726f2028697420616c736f206765747320636f6c6c617073656420746f207a65726f2069662069742065766572206265636f6d6573206c657373207468616e20604578697374656e7469616c4465706f736974602e2920546865202766726565272062616c616e6365206f66206120676976656e206163636f756e742e205468697320697320746865206f6e6c792062616c616e63652074686174206d61747465727320696e207465726d73206f66206d6f7374206f7065726174696f6e73206f6e20746f6b656e732e20497420616c6f6e65206973207573656420746f2064657465726d696e65207468652062616c616e6365207768656e20696e2074686520636f6e747261637420657865637574696f6e20656e7669726f6e6d656e742e205768656e20746869732062616c616e63652066616c6c732062656c6f77207468652076616c7565206f6620604578697374656e7469616c4465706f736974602c207468656e20746865202763757272656e74206163636f756e74272069732064656c657465643a207370656369666963616c6c7920604672656542616c616e6365602e20467572746865722c2074686520604f6e4672656542616c616e63655a65726f602063616c6c6261636b20697320696e766f6b65642c20676976696e672061206368616e636520746f2065787465726e616c206d6f64756c657320746f20636c65616e2075702064617461206173736f6369617465642077697468207468652064656c65746564206163636f756e742e206073797374656d3a3a4163636f756e744e6f6e63656020697320616c736f2064656c657465642069662060526573657276656442616c616e63656020697320616c736f207a65726f2028697420616c736f206765747320636f6c6c617073656420746f207a65726f2069662069742065766572206265636f6d6573206c657373207468616e20604578697374656e7469616c4465706f736974602e20496e666f726d6174696f6e20726567617264696e67207468652076657374696e67206f66206120676976656e206163636f756e742e2054686520746f74616c20756e6974732069737375656420696e207468652073797374656d2e0000000000703e10001200000000000000813610000a00000000000000f8951100843e10000000000000000000943e10000100000000000000000000002c1011000b00000000000000813610000a00000000000000f89511009c3e1000000000000000000038101100010000000000000000000000401011000b00000000000000813610000a00000000000000f89511009c3e100000000000000000004c101100010000000000000000000000541011001200000000000000813610000a00000000000000f89511009c3e1000000000000000000068101100010000000000000000000000701011001200000000000000813610000a00000000000000f8951100ac3e100000000000000000009410110001000000000000004578697374656e7469616c4465706f73697400003200000000000000010000003e000000bc3e1000350000003200000000000000010000003f0000003200000000000000010000004000000020546865206d696e696d756d20616d6f756e7420726571756972656420746f206b65657020616e206163636f756e74206f70656e2e6e6f7420656e6f75676820667265652066756e647300000474110028000000203f1000430000008f010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f62616c616e6365732f7372632f6c69622e727300203f1000430000008f01000001000000676f74206f766572666c6f7720616674657220616464696e6720612066656520746f2076616c7565c03f1000480000009b0a00000a000000c03f100048000000a10a00000e000000000000002f72757374632f353231643738343037343731636237386539626266343731363066366161323330343761633439392f7372632f6c6962636f72652f736c6963652f6d6f642e7273c040100048000000b101000023000000c040100048000000b201000023000000994010001c0000008480110018000000e50300000d0000005040100049000000870200001d0000002f72757374632f353231643738343037343731636237386539626266343731363066366161323330343761633439392f7372632f6c6962636f72652f736c6963652f736f72742e7273617373657274696f6e206661696c65643a206d6964203c3d206c656e00000000000000000000002f72757374632f353231643738343037343731636237386539626266343731363066366161323330343761633439392f7372632f6c6962636f72652f736c6963652f6d6f642e727350401000490000009d0000003a0000005040100049000000a400000030000000320000000000000001000000410000004200000043000000440000004500000046000000000000007841100011000000000000008c4110000100000000000000000000009441100001000000000000004865617274626561745265636569766564000000cc4110000b0000009c411000300000002041206e657720686561727462656174207761732072656365697665642066726f6d2060417574686f72697479496460417574686f726974794964496d4f6e6c696e6520476f737369704174496d4f6e6c696e65204b657973417574686f72697479446973636f76657279204b65797330421000190000005042100048000000bb0100002d000000000000000000000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f353231643738343037343731636237386539626266343731363066366161323330343761633439392f7372632f6c6962636f72652f6f70732f61726974682e72730474110028000000b04210004e0000003b000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f617574686f726974792d646973636f766572792f7372632f6c69622e727374696d657374616d702073657420696e20626c6f636b20646f65736e2774206d6174636820736c6f7420696e207365616c00b04210004e0000003b0000000100000065706f636820696e64696365732077696c6c206e6576657220726561636820325e3634206265666f726520746865206465617468206f662074686520756e6976657273653b20716564776520676f74207468652076616c696461746f725f69642066726f6d2063757272656e745f656c65637465643b0a09090909090963757272656e745f656c656374656420697320736574206f662063757272656e746c7920656c65637465642076616c696461746f72733b0a090909090909746865206d617070696e67206265747765656e207468652076616c696461746f7220696420616e64206974732066756c6c206964656e74696669636174696f6e2073686f756c642062652076616c69643b0a09090909090974687573206046756c6c4964656e74696669636174696f6e4f663a3a636f6e76657274602063616e27742072657475726e20604e6f6e65603b0a09090909090971656472656163686564206d6178696d756d2064657074682c2063616e6e6f7420637265617465000047000000180000000400000048000000490000004a0000004b0000004c0000004d000000696e73756666696369656e742072656d61696e696e672062616c616e63656e6f7420656e6f7567682067617320746f20706179206261736520696e7374616e7469617465206665656e6f7420656e6f7567682067617320746f20706179207472616e736665722066656562616c616e636520746f6f206c6f7720746f2073656e642076616c756576616c756520746f6f206c6f7720746f20637265617465206163636f756e7464657374696e6174696f6e2062616c616e636520746f6f206869676820746f20726563656976652076616c756572656163686564206d6178696d756d2064657074682c2063616e6e6f74206d616b6520612063616c6c6e6f7420656e6f7567682067617320746f2070617920626173652063616c6c20666565636f6e747261637420686173206265656e2065766963746564636f6e74726163742063616e6e6f742062652064657374726f79656420647572696e672072656375727369766520657865637574696f6e61206e657374656420657865637574696f6e20636f6e74657874206d7573742068617665206120706172656e743b2071656400000000000000b04610000900000000000000bc46100002000000000000000000000064801100000000000000000068656172746265617400000000000000b04610000900000000000000ec46100019000000000000000547100009000000000000000e4710002f0000004865617274626561743c543a3a426c6f636b4e756d6265723e7369676e61747572653c543a3a417574686f7269747949642061732052756e74696d654170705075626c69633e3a3a5369676e61747572650000000000000048481000080000000000000000000000df0e11000e00000000000000000000000000000000000000000000000000000000000000f8951100cc50100000000000000000005048100001000000000000000100000000000000584810000400000000000000000000005c4810001300000000000000000000000000000000000000000000000000000000000000f8951100684f10000000000000000000704810000100000000000000010000000000000078481000120000000201010000000000c77911000c000000000000008a4810000900000000000000e25111000700000000000000f8951100944810000000000000000000a4481000020000000000000001000000476f73736970417445491000280000004b6579735665633c543a3a417574686f7269747949643e00114910003400000052656365697665644865617274626561747341757468496e646578003200000000000000010000004e000000b44810003a000000ee4810002300000020466f7220656163682073657373696f6e20696e646578207765206b6565702061206d617070696e67206f662060417574686f7269747949646020746f20606f6666636861696e3a3a4f70617175654e6574776f726b5374617465602e205468652063757272656e7420736574206f66206b6579732074686174206d61792069737375652061206865617274626561742e2054686520626c6f636b206e756d626572207768656e2077652073686f756c6420676f737369702e73726d6c2f696d2d6f6e6c696e652d776f726b65722d737461747573000000a0491000480000009b0a00000a000000000000002f72757374632f353231643738343037343731636237386539626266343731363066366161323330343761633439392f7372632f6c6962636f72652f736c6963652f6d6f642e72734f75746461746564206865617274626561742072656365697665642e496e76616c696420686561727462656174207369676e61747572652e000000004c4a10002200000000000000704a1000010000000000000000000000884a100003000000000000007365745f70656e64696e675f7365636f6e646172795f736c6f74735f6368616e6765000000000000504b10000600000000000000564b10000c000000a04a100045000000e54a100043000000284b100028000000205365747320612070656e64696e67206368616e676520746f20656e61626c65202f2064697361626c65207365636f6e6461727920736c6f742061737369676e6d656e742e205468652070656e64696e67206368616e67652077696c6c206265207365742061742074686520656e64206f66207468652063757272656e742065706f636820616e642077696c6c20626520656e6163746564206174206063757272656e745f65706f6368202b2032602e6368616e67654f7074696f6e3c626f6f6c3e0000000000002c4f10000a0000000000000000000000820911000300000000000000000000000000000000000000000000000000000000000000f8951100b44f10000000000000000000384f100001000000000000000100000000000000ec6110000b0000000000000000000000404f10002700000000000000000000000000000000000000000000000000000000000000f8951100684f10000000000000000000784f100001000000000000000100000000000000804f10000e0000000000000000000000820911000300000000000000000000000000000000000000000000000000000000000000f8951100b44f10000000000000000000904f100003000000000000000100000000000000a84f10000b0000000000000000000000820911000300000000000000000000000000000000000000000000000000000000000000f8951100b44f10000000000000000000c44f100001000000000000000100000000000000cc4f10000e0000000000000000000000da4f10000c00000000000000000000000000000000000000000000000000000000000000f8951100e84f10000000000000000000f84f100002000000000000000100000000000000085010001b0000000000000000000000d6fb10000400000000000000000000000000000000000000000000000000000000000000f89511006051100000000000000000002450100002000000000000000000000000000000345010000a00000000000000000000003e5010000800000000000000000000000000000000000000000000000000000000000000f8951100a85010000000000000000000485010000a000000000000000100000000000000985010000e00000000000000000000003e5010000800000000000000000000000000000000000000000000000000000000000000f8951100a85010000000000000000000b850100001000000000000000100000000000000c05010000c00000000000000000000000e3d11000300000000000000000000000000000000000000000000000000000000000000f8951100cc5010000000000000000000dc50100009000000000000000100000000000000245110001100000001010000000000000e3d11000300000000000000355110000d00000000000000000000000000000000000000f89511004451100000000000000000006480110000000000000000000100000000000000545110000b0000000000000000000000d6fb10000400000000000000000000000000000000000000000000000000000000000000f89511006051100000000000000000007051100002000000000000000000000045706f6368496e6465780000d1561000150000005665633c28417574686f7269747949642c2042616265417574686f72697479576569676874293e0032000000000000000100000033000000b65610001b00000045706f63685374617274536c6f7400001d561000400000005d5610003e0000009b5610001b00000043757272656e74536c6f74003200000000000000010000004f00000008561000150000005365636f6e64617279536c6f747328626f6f6c2c20626f6f6c290000320000000000000001000000500000008855100042000000ca5510003e00000050656e64696e675365636f6e64617279536c6f74734368616e676500275510003f000000665510002200000052616e646f6d6e6573735b75383b2033325d0000615310002e00000064801100000000008f5310000b00000064801100000000009a53100041000000db5310003e00000019541000450000005e54100045000000a354100041000000e4541000430000004e65787452616e646f6d6e6573730000320000000000000001000000510000004a531000170000005365676d656e74496e64657832000000000000000100000035000000055210001f0000006480110000000000245210003d0000006152100040000000a1521000250000006480110000000000c65210003b00000001531000420000004353100007000000556e646572436f6e737472756374696f6e5665633c5b75383b2033325d3e000032000000000000000100000033000000496e697469616c697a65640032000000000000000100000036000000805110003e000000be511000470000002054656d706f726172792076616c75652028636c656172656420617420626c6f636b2066696e616c697a6174696f6e292077686963682069732074727565206966207065722d626c6f636b20696e697469616c697a6174696f6e2068617320616c7265616479206265656e2063616c6c656420666f722063757272656e7420626c6f636b2e2052616e646f6d6e65737320756e64657220636f6e737472756374696f6e2e205765206d616b6520612074726164656f6666206265747765656e2073746f7261676520616363657373657320616e64206c697374206c656e6774682e2057652073746f72652074686520756e6465722d636f6e737472756374696f6e2072616e646f6d6e65737320696e207365676d656e7473206f6620757020746f2060554e4445525f434f4e535452554354494f4e5f5345474d454e545f4c454e475448602e204f6e63652061207365676d656e7420726561636865732074686973206c656e6774682c20776520626567696e20746865206e657874206f6e652e20576520726573657420616c6c207365676d656e747320616e642072657475726e20746f206030602061742074686520626567696e6e696e67206f662065766572792065706f63682e204e6578742065706f63682072616e646f6d6e6573732e205468652065706f63682072616e646f6d6e65737320666f7220746865202a63757272656e742a2065706f63682e20232053656375726974792054686973204d555354204e4f54206265207573656420666f722067616d626c696e672c2061732069742063616e20626520696e666c75656e6365642062792061206d616c6963696f75732076616c696461746f7220696e207468652073686f7274207465726d2e204974204d4159206265207573656420696e206d616e792063727970746f677261706869632070726f746f636f6c732c20686f77657665722c20736f206c6f6e67206173206f6e652072656d656d626572732074686174207468697320286c696b652065766572797468696e6720656c7365206f6e2d636861696e29206974206973207075626c69632e20466f72206578616d706c652c2069742063616e20626520757365642077686572652061206e756d626572206973206e656564656420746861742063616e6e6f742068617665206265656e2063686f73656e20627920616e206164766572736172792c20666f7220707572706f7365732073756368206173207075626c69632d636f696e207a65726f2d6b6e6f776c656467652070726f6f66732e2050656e64696e67206368616e676520746f20656e61626c652f64697361626c65207365636f6e6461727920736c6f74732077686963682077696c6c20626520747269676765726564206174206063757272656e745f65706f6368202b2032602e2057686574686572207365636f6e6461727920736c6f74732061726520656e61626c656420696e206361736520746865205652462d626173656420736c6f7420697320656d70747920666f72207468652063757272656e742065706f636820616e6420746865206e6578742065706f63682c20726573706563746976656c792e2043757272656e7420736c6f74206e756d6265722e20536c6f74206174207768696368207468652063757272656e742065706f636820737461727465642e20497420697320706f737369626c652074686174206e6f20626c6f636b2077617320617574686f7265642061742074686520676976656e20736c6f7420616e64207468652065706f6368206368616e676520776173207369676e616c6c6564206c61746572207468616e20746869732e2043757272656e742065706f636820617574686f7269746965732e2043757272656e742065706f636820696e6465782e000000000000585710000d00000000000000820911000300000000000000f895110068571000000000000000000078571000020000000000000000000000885710001100000000000000e3db10000900000000000000f89511009c5710000000000000000000ac571000050000000000000045706f63684475726174696f6e000000320000000000000001000000520000000459100043000000475910003f0000004578706563746564426c6f636b54696d6500000032000000000000000100000053000000d457100041000000155810004400000059581000410000009a58100042000000dc5810002800000020546865206578706563746564206176657261676520626c6f636b2074696d6520617420776869636820424142452073686f756c64206265206372656174696e6720626c6f636b732e2053696e636520424142452069732070726f626162696c6973746963206974206973206e6f74207472697669616c20746f20666967757265206f7574207768617420746865206578706563746564206176657261676520626c6f636b2074696d652073686f756c64206265206261736564206f6e2074686520736c6f74206475726174696f6e20616e642074686520736563757269747920706172616d657465722060636020287768657265206031202d20636020726570726573656e7473207468652070726f626162696c697479206f66206120736c6f74206265696e6720656d707479292e20546865206e756d626572206f66202a2a736c6f74732a2a207468617420616e2065706f63682074616b65732e20576520636f75706c652073657373696f6e7320746f2065706f6368732c20692e652e2077652073746172742061206e65772073657373696f6e206f6e636520746865206e65772065706f636820626567696e732e46524e4b00000000000040e810000800000000000000685a1000010000000000000000000000705a1000010000000000000000000000785a10000800000000000000881d1100010000000000000000000000805a1000010000000000000000000000885a10000700000000000000905a1000030000000000000000000000a85a1000010000000000000000000000b05a10000500000000000000881d1100010000000000000000000000b85a1000010000000000000000000000c05a10000800000000000000881d1100010000000000000000000000c85a10000100000000000000fcea10000d000000995b10000e0000005370656e64696e675f5b10003a0000004177617264656400fcea10000d0000008f1e110007000000861e1100090000003f5b1000200000004275726e740000001c5b100023000000526f6c6c6f766572d05a10004c000000205370656e64696e67206861732066696e69736865643b20746869732069732074686520616d6f756e74207468617420726f6c6c73206f76657220756e74696c206e657874207370656e642e20536f6d65206f66206f75722066756e64732068617665206265656e206275726e742e20536f6d652066756e64732068617665206265656e20616c6c6f63617465642e205765206861766520656e6465642061207370656e6420706572696f6420616e642077696c6c206e6f7720616c6c6f636174652066756e64732e204e65772070726f706f73616c2e0000000000585c10000b00000000000000a8fa1000020000000000000000000000645c10000100000000000000000000006c5c1000100000000000000018c410000100000000000000000000007c5c1000010000000000000000000000845c10000c00000000000000ecfa1000010000000000000000000000905c1000010000000000000000000000985c10000e00000000000000a85c1000020000000000000000000000b85c10000100000000000000566f74657252656170656400645d100015000000426164526561706572536c6173686564555d10000f00000054616c6c7953746172746564205d10003500000054616c6c7946696e616c697a65640000125d10000e000000125d10000e000000c05c10005200000020412074616c6c792028666f7220617070726f76616c20766f746573206f662073656174287329292068617320656e646564202877697468206f6e65206f72206d6f7265206e6577206d656d62657273292e5665633c4163636f756e7449643e20412074616c6c792028666f7220617070726f76616c20766f746573206f662073656174287329292068617320737461727465642e20736c6173686564207265617065722072656170656420766f7465722c2072656170657254696d657374616d7020557064617465436f756e63696c205265676973746572496e666f4f6654696d657374616d7020526563656e7448696e7473cc5d100031000000fd5d10004b0000007e0000000400000046696e616c2068696e74206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b2f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f66696e616c6974792d747261636b65722f7372632f6c69622e7273605e100023000000fd5d10004b0000007f0000000400000046696e616c697a6564206865696768742061626f766520626c6f636b206e756d62657254726561737572792050726f706f73616c730000000474110028000000b05e1000430000007f000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f74726561737572792f7372632f6c69622e72730000000000205f10001200000000000000345f10000100000000000000000000004c5f100001000000000000007265706f72745f6d69736265686176696f720000000000006d5f10000700000000000000e251110007000000545f100019000000205265706f727420736f6d65206d69736265686176696f722e5f7265706f72744772616e64706146696e616c6974790000000000ec6110000b00000000000000000000001b7711002300000000000000000000000000000000000000000000000000000000000000f8951100b48910000000000000000000f86110000100000000000000010000000000000000621000050000000000000000000000056210001b00000000000000000000000000000000000000000000000000000000000000f89511002062100000000000000000003062100001000000000000000100000000000000386210000d0000000000000000000000456210002300000000000000000000000000000000000000000000000000000000000000f8951100c08a100000000000000000006862100001000000000000000000000000000000706210000a0000000000000000000000df0e11000e00000000000000000000000000000000000000000000000000000000000000f8951100f462100000000000000000007c62100001000000000000000000000000000000846210000700000000000000000000008b6210002000000000000000000000000000000000000000000000000000000000000000f8951100388910000000000000000000ac62100001000000000000000000000000000000b46210000c0000000000000000000000c06210000500000000000000000000000000000000000000000000000000000000000000f8951100c86210000000000000000000d862100002000000000000000100000000000000e86210000c0000000101000000000000c06210000500000000000000c77911000c00000000000000000000000000000000000000f8951100f4621000000000000000000004631000010000000000000000000000417574686f72697469657300ac6410001b000000537461746553746f72656453746174653c543a3a426c6f636b4e756d6265723e32000000000000000100000054000000886410002400000050656e64696e674368616e676553746f72656450656e64696e674368616e67653c543a3a426c6f636b4e756d6265723e57641000310000004e657874466f726365640000286410002f0000005374616c6c656428543a3a426c6f636b4e756d6265722c20543a3a426c6f636b4e756d6265722900046410002400000043757272656e74536574496453657449640000003200000000000000010000004f0000007c63100057000000d363100031000000536574496453657373696f6e320000000000000001000000360000000c631000700000002041206d617070696e672066726f6d206772616e6470612073657420494420746f2074686520696e646578206f6620746865202a6d6f737420726563656e742a2073657373696f6e20666f7220776869636820697473206d656d62657273207765726520726573706f6e7369626c652e20546865206e756d626572206f66206368616e6765732028626f746820696e207465726d73206f66206b65797320616e6420756e6465726c79696e672065636f6e6f6d696320726573706f6e736962696c69746965732920696e20746865202273657422206f66204772616e6470612076616c696461746f72732066726f6d2067656e657369732e20607472756560206966207765206172652063757272656e746c79207374616c6c65642e206e65787420626c6f636b206e756d6265722077686572652077652063616e20666f7263652061206368616e67652e2050656e64696e67206368616e67653a20287369676e616c65642061742c207363686564756c6564206368616e6765292e205374617465206f66207468652063757272656e7420617574686f72697479207365742e205468652063757272656e7420617574686f72697479207365742e00000000004c6510000d000000000000005c6510000200000000000000000000008c651000090000000000000000000000d46510000f00000000000000e4651000010000000000000000000000fc651000070000000000000000000000346610001000000000000000e465100001000000000000000000000044661000080000000000000070726f706f73655f7370656e64000000000000000f3311000500000000000000143311001500000000000000326810000b00000000000000a32a110023000000606710004b000000ab6710004d000000f8671000150000006480110000000000d52811000b0000004f34110008000000cde41000190000000d68100025000000f02811000c00000072656a6563745f70726f706f73616c0000000000556710000b0000000000000058f1100016000000066710003f0000006480110000000000d52811000b0000004f34110008000000cde41000190000004567100010000000f02811000c000000617070726f76655f70726f706f73616c8466100057000000db6610002b0000006480110000000000d52811000b0000004f34110008000000cde4100019000000e6e4100011000000f02811000c00000020417070726f766520612070726f706f73616c2e2041742061206c617465722074696d652c207468652070726f706f73616c2077696c6c20626520616c6c6f636174656420746f207468652062656e656669636961727920616e6420746865206f726967696e616c206465706f7369742077696c6c2062652072657475726e65642e2052656a65637420612070726f706f736564207370656e642e20546865206f726967696e616c206465706f7369742077696c6c20626520736c61736865642e202d204f6e6520444220636c6561722e70726f706f73616c5f69642050757420666f727761726420612073756767657374696f6e20666f72207370656e64696e672e2041206465706f7369742070726f706f7274696f6e616c20746f207468652076616c756520697320726573657276656420616e6420736c6173686564206966207468652070726f706f73616c2069732072656a65637465642e2049742069732072657475726e6564206f6e6365207468652070726f706f73616c20697320617761726465642e202d204f6e65204442206368616e67652c206f6e6520657874726120444220656e7472792e62656e65666963696172790000000000000034f510000d0000000000000000000000fcea10000d00000000000000000000000000000000000000000000000000000000000000f89511007094100000000000000000004869100001000000000000000100000000000000c4f41000090000000101000000000000fcea10000d00000000000000506910002400000000000000000000000000000000000000f895110074691000000000000000000084691000010000000000000000000000000000008c691000090000000000000000000000956910001200000000000000000000000000000000000000000000000000000000000000f8951100b48910000000000000000000a86910000100000000000000010000000d6a10002900000050726f706f73616c3c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e32000000000000000100000036000000ee6910001f000000417070726f76616c735665633c50726f706f73616c496e6465783e00b06910003e0000002050726f706f73616c20696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f742079657420617761726465642e2050726f706f73616c7320746861742068617665206265656e206d6164652e204e756d626572206f662070726f706f73616c7320746861742068617665206265656e206d6164652e000000000000186b10000c00000000000000246b10000700000000000000f89511002c6b100000000000000000003c6b10000200000000000000000000004c6b10001300000000000000753f11000c00000000000000f8951100589310000000000000000000606b1000010000000000000000000000686b10000b00000000000000df0e11000e00000000000000f8951100746b10000000000000000000846b10000100000000000000000000008c6b10000400000000000000246b10000700000000000000f8951100906b10000000000000000000a06b1000010000000000000050726f706f73616c426f6e645065726d696c6c0032000000000000000100000055000000606c100055000000b56c10004400000050726f706f73616c426f6e644d696e696d756d000e6c1000520000005370656e64506572696f640032000000000000000100000056000000ec6b1000220000004275726e32000000000000000100000057000000a86b1000440000002050657263656e74616765206f662073706172652066756e64732028696620616e7929207468617420617265206275726e7420706572207370656e6420706572696f642e20506572696f64206265747765656e2073756363657373697665207370656e64732e204d696e696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e204672616374696f6e206f6620612070726f706f73616c27732076616c756520746861742073686f756c6420626520626f6e64656420696e206f7264657220746f20706c616365207468652070726f706f73616c2e20416e2061636365707465642070726f706f73616c2067657473207468657365206261636b2e20412072656a65637465642070726f706f73616c20646f6573206e6f742e4772616e64706146696e616c6974792050656e64696e674368616e67654772616e64706146696e616c697479205374617465496e636f6e73697374656e74207374617465202d20636f756c646e277420736574746c6520696d62616c616e636520666f722066756e6473207370656e74206279207472656173757279436f756e63696c204d656d62657273436f756e63696c204e65787446696e616c697a65906e1000480000009b0a00000a000000436f756e63696c205465726d4475726174696f6e436f756e63696c2050726573656e746174696f6e4475726174696f6e436f756e63696c204c6561646572626f61726400906e100048000000a10a00000e000000436f756e63696c20566f746572496e666f4f66436f756e63696c2043616e6469646174657347757275206d656469746174696f6e66696e616c697a652063616e206f6e6c792062652063616c6c656420616674657220612074616c6c7920697320737461727465642e436f756e63696c20417070726f76616c734f66436f756e63696c20566f74657273000000000000000000002f72757374632f353231643738343037343731636237386539626266343731363066366161323330343761633439392f7372632f6c6962636f72652f736c6963652f6d6f642e7273576974686472617720686173206265656e20636865636b65642061626f76653b0a090909647565735f6c696d69746564203c2072656e745f627564676574203c2062616c616e6365202d2073756273697374656e6365203c2062616c616e6365202d206578697374656e7469616c5f6465706f7369743b0a09090971656400005800000008000000040000005900000000000000207110000d000000000000003071100003000000000000000000000078711000180000000000000000000000387210001300000000000000307110000300000000000000000000004c7210000600000000000000000000007c721000130000000000000090721000040000000000000000000000f07210000c0000000000000000000000507310000d0000000000000060731000010000000000000000000000787310000a0000000000000000000000c87310001000000000000000d8731000010000000000000000000000f07310000d0000000000000000000000587410000e0000000000000068741000030000000000000000000000b0741000080000000000000000000000f07410001100000000000000047510000100000000000000000000001c7510000300000000000000000000000cdf10000d00000000000000347510000100000000000000000000004c7510000400000000000000000000006c751000190000000000000088751000010000000000000000000000a0751000020000000000000000000000b0751000110000000000000088751000010000000000000000000000c475100002000000000000007365745f617070726f76616c73000000000000006b821000050000000000000070821000090000000000000053f1100005000000000000005479100012000000000000007982100004000000000000007d82100008000000397e100058000000ed7d1000100000006480110000000000917e100030000000c17e10004a00000064801100000000000b7f100035000000407f100051000000917f10002c000000bd7f10005300000010801000620000007280100060000000d28010001d000000ef80100057000000468110003500000064801100000000007b8110006b000000e68110001d0000006480110000000000d52811000b0000004f3411000800000003821000270000002a82100041000000f02811000c00000070726f78795f7365745f617070726f76616c7300887d100065000000ed7d1000100000006480110000000000d52811000b000000fd7d10003c000000f02811000c000000726561705f696e6163746976655f766f74657200000000005f7d10000e000000000000004b2911000c000000000000007ee110000300000000000000a32a110023000000000000006d7d100009000000000000004b2911000c00000000000000767d100012000000000000005479100012000000fe7b100058000000567c10005c000000b27c1000280000006480110000000000da7c10004500000064801100000000001f7d1000400000006480110000000000d52811000b0000004f34110008000000d77b100027000000f02811000c000000726574726163745f766f7465720000000000000053f1100005000000000000004b2911000c000000fb7a10004b0000006480110000000000467b1000420000006480110000000000887b10004f0000006480110000000000d52811000b0000004f34110008000000d77b100027000000f02811000c0000007375626d69745f63616e64696461637900000000f77a100004000000000000004b2911000c000000667910001e000000648011000000000084791000440000006480110000000000c879100048000000107a100051000000617a10004c000000ad7a10001e0000006480110000000000d52811000b000000cb7a100018000000e37a100014000000f02811000c00000070726573656e745f77696e6e6572000000000000467910000900000000000000a32a110023000000000000004f791000050000000000000014331100150000000000000053f11000050000000000000054791000120000005278100059000000ab78100068000000137910001e0000006480110000000000d52811000b0000003179100015000000e6e4100011000000f02811000c0000007365745f646573697265645f7365617473000000000000009676100005000000000000004b2911000c0000009277100059000000eb771000520000003d78100015000000000000007ee110000300000000000000a32a110023000000b2761000480000006480110000000000fa7610004800000042771000500000007365745f70726573656e746174696f6e5f6475726174696f6e000000000000009676100005000000000000009b76100017000000407610005600000028761000180000007365745f7465726d5f6475726174696f6e000000d475100054000000287610001800000020536574207468652070726573656e746174696f6e206475726174696f6e2e2049662074686572652069732063757272656e74206120766f7465206265696e672070726573656e74656420666f722c2077696c6c20696e766f6b65206066696e616c697a655f766f7465602e20536574207468652070726573656e746174696f6e206475726174696f6e2e2049662074686572652069732063757272656e746c79206120766f7465206265696e672070726573656e74656420666f722c2077696c6c636f756e74436f6d706163743c543a3a426c6f636b4e756d6265723e2052656d6f7665206120706172746963756c6172206d656d6265722066726f6d20746865207365742e20546869732069732065666665637469766520696d6d6564696174656c792e204e6f74653a20412074616c6c792073686f756c642068617070656e20696e7374616e746c7920286966206e6f7420616c726561647920696e20612070726573656e746174696f6e20706572696f642920746f2066696c6c2074686520736561742069662072656d6f76616c206d65616e732074686174207468652064657369726564206d656d6265727320617265206e6f74206d65742e20536574207468652064657369726564206d656d62657220636f756e743b206966206c6f776572207468616e207468652063757272656e7420636f756e742c207468656e2073656174732077696c6c206e6f7420626520757020656c656374696f6e207768656e2074686579206578706972652e204966206d6f72652c207468656e2061206e657720766f74652077696c6c2062652073746172746564206966206f6e65206973206e6f7420616c726561647920696e2070726f67726573732e20436c61696d207468617420607369676e656460206973206f6e65206f662074686520746f702053656c663a3a63617272795f636f756e742829202b2063757272656e745f766f746528292e312063616e646964617465732e204f6e6c7920776f726b73206966207468652060626c6f636b5f6e756d626572203e3d2063757272656e745f766f746528292e306020616e6420603c2063757272656e745f766f746528292e30202b2070726573656e746174696f6e5f6475726174696f6e28296020607369676e6564602073686f756c642068617665206174206c65617374202d204f28766f746572732920636f6d707574652e63616e646964617465746f74616c436f6d706163743c566f7465496e6465783e205375626d6974206f6e6573656c6620666f722063616e6469646163792e204163636f756e74206d757374206861766520656e6f756768207472616e736665727261626c652066756e647320696e20697420746f207061792074686520626f6e642e204e4f54453a20696620606f726967696e602068617320616c72656164792061737369676e656420617070726f76616c7320766961205b607365745f617070726f76616c73605d2c2069742077696c6c204e4f54206861766520616e7920757361626c652066756e647320746f20706173732063616e64696461637920626f6e6420616e64206d75737420666972737420726574726163742e204e6f746520746861742073657474696e6720617070726f76616c732077696c6c206c6f636b2074686520656e746972652062616c616e6365206f662074686520766f74657220756e74696c2072657472616374696f6e206f72206265696e67207265706f727465642e202d20496e646570656e64656e74206f6620696e7075742e202d205468726565204442206368616e6765732e736c6f742052656d6f7665206120766f7465722e20416c6c20766f746573206172652063616e63656c6c656420616e642074686520766f746572206465706f7369742069732072657475726e65642e2054686520696e646578206d7573742062652070726f7669646564206173206578706c61696e656420696e205b60766f7465725f6174605d2066756e6374696f6e2e20416c736f2072656d6f76657320746865206c6f636b206f6e207468652062616c616e6365206f662074686520766f7465722e20536565205b60646f5f7365745f617070726f76616c732829605d2e202d2054776f20666577657220444220656e74726965732c206f6e65204442206368616e67652e2052656d6f7665206120766f7465722e20466f72206974206e6f7420746f206265206120626f6e642d636f6e73756d696e67206e6f2d6f702c20616c6c20617070726f7665642063616e64696461746520696e6469636573206d757374206e6f772062652065697468657220756e72656769737465726564206f72207265676973746572656420746f20612063616e646964617465207468617420726567697374657265642074686520736c6f742061667465722074686520766f7465722067617665207468656972206c61737420617070726f76616c207365742e20426f746820696e6469636573206d7573742062652070726f7669646564206173206578706c61696e656420696e205b60766f7465725f6174605d2066756e6374696f6e2e204d61792062652063616c6c656420627920616e796f6e652e2052657475726e732074686520766f746572206465706f73697420746f20607369676e6564602e7265706f727465725f696e64657877686f5f696e646578617373756d65645f766f74655f696e646578205365742063616e64696461746520617070726f76616c732066726f6d20612070726f78792e20417070726f76616c20736c6f747320737461792076616c6964206173206c6f6e672061732063616e6469646174657320696e2074686f736520736c6f74732061726520726567697374657265642e202d2053616d6520617320607365745f617070726f76616c73602077697468206f6e65206164646974696f6e616c2073746f7261676520726561642e205365742063616e64696461746520617070726f76616c732e20417070726f76616c20736c6f747320737461792076616c6964206173206c6f6e672061732063616e6469646174657320696e2074686f736520736c6f7473204c6f636b732074686520746f74616c2062616c616e6365206f662063616c6c657220696e646566696e6974656c792e204f6e6c79205b60726574726163745f766f746572605d206f72205b60726561705f696e6163746976655f766f746572605d2063616e20756e6c6f636b207468652062616c616e63652e206068696e746020617267756d656e7420697320696e74657270726574656420646966666572656e746c79206261736564206f6e3a202d20696620606f726967696e602069732073657474696e6720617070726f76616c7320666f72207468652066697273742074696d653a2054686520696e6465782077696c6c20626520636865636b656420666f72206265696e6720612076616c6964205f686f6c655f20696e2074686520766f746572206c6973742e2020202d206966207468652068696e7420697320636f72726563746c7920706f696e74696e6720746f206120686f6c652c206e6f206665652069732064656475637465642066726f6d20606f726967696e602e2020202d204f74686572776973652c207468652063616c6c2077696c6c2073756363656564206275742074686520696e6465782069732069676e6f72656420616e642073696d706c792061207075736820746f20746865206c617374206368756e6b2020207769746820667265652073706163652068617070656e732e20496620746865206e65772070757368206361757365732061206e6577206368756e6b20746f20626520637265617465642c20612066656520696e646963617465642062792020205b60566f74696e67466565605d2069732064656475637465642e202d20696620606f726967696e6020697320616c7265616479206120766f7465723a2074686520696e646578205f5f6d7573745f5f2062652076616c696420616e6420706f696e7420746f2074686520636f727265637420706f736974696f6e206f662074686520606f726967696e6020696e207468652063757272656e7420766f74657273206c6973742e204e6f7465207468617420616e7920747261696c696e67206066616c73656020766f74657320696e2060766f746573602069732069676e6f7265643b20496e20617070726f76616c20766f74696e672c206e6f7420766f74696e6720666f7220612063616e64696461746520616e6420766f74696e672066616c73652c2061726520657175616c2e202d2054776f20657874726120444220656e74726965732c206f6e65204442206368616e67652e202d20417267756d656e742060766f74657360206973206c696d6974656420696e206c656e67746820746f206e756d626572206f662063616e646964617465732e766f7465735665633c626f6f6c3e68696e74536574496e6465780000000000000008881000140000000000000000000000df0e11000e00000000000000000000000000000000000000000000000000000000000000f89511007094100000000000000000001c88100001000000000000000100000000000000248810000c0000000000000000000000df0e11000e00000000000000000000000000000000000000000000000000000000000000f89511007094100000000000000000003088100001000000000000000100000000000000388810000c00000000000000000000000e3d11000300000000000000000000000000000000000000000000000000000000000000f895110070941000000000000000000044881000010000000000000001000000000000004cf510000700000000000000000000004c8810002300000000000000000000000000000000000000000000000000000000000000f89511007088100000000000000000008088100004000000000000000100000000000000a0881000090000000000000000000000a98810000900000000000000000000000000000000000000000000000000000000000000f8951100709410000000000000000000b488100001000000000000000100000000000000bc8810000b0000000101000000000000c78810001800000000000000df8810001100000000000000000000000000000000000000f8951100b48910000000000000000000f088100005000000000000000100000000000000188910000e00000001010000000000007a3d11000c00000000000000268910001000000000000000000000000000000000000000f89511003889100000000000000000004889100002000000000000000000000000000000588910000b00000001010000000000007a3d11000c00000000000000638910001700000000000000000000000000000000000000f89511007c89100000000000000000008c89100001000000000000000000000000000000948910000600000001010000000000007d82100008000000000000009a8910001900000000000000000000000000000000000000f8951100b48910000000000000000000c489100001000000000000000100000000000000cc8910000c00000000000000000000007d8210000800000000000000000000000000000000000000000000000000000000000000f8951100709410000000000000000000d889100001000000000000000100000000000000e08910000a00000000000000000000007d8210000800000000000000000000000000000000000000000000000000000000000000f8951100709410000000000000000000ec89100001000000000000000100000000000000f48910000a0000000000000000000000492811001100000000000000000000000000000000000000000000000000000000000000f8951100008a10000000000000000000108a100001000000000000000100000000000000188a10000e00000000000000000000000e3d11000300000000000000000000000000000000000000000000000000000000000000f8951100709410000000000000000000288a100001000000000000000100000000000000308a10000c00000000000000000000003c8a10002800000000000000000000000000000000000000000000000000000000000000f8951100648a10000000000000000000748a1000010000000000000000000000000000007c8a10000b0000000000000000000000878a10002100000000000000000000000000000000000000000000000000000000000000f8951100c08a10000000000000000000a88a100002000000000000000000000000000000b88a10000500000001010000000000007a3d11000c000000000000007a3d11000c00000000000000000000000000000000000000f8951100c08a10000000000000000000d08a100002000000000000000000000050726573656e746174696f6e4475726174696f6e9d9010004f0000005465726d4475726174696f6e77901000260000004465736972656453656174733d9010003a0000005665633c28543a3a4163636f756e7449642c20543a3a426c6f636b4e756d626572293e0032000000000000000100000033000000158f10005e000000738f10005c000000cf8f100054000000239010001a000000566f7465436f756e74566f7465496e6465780000ce8e100047000000417070726f76616c734f6628543a3a4163636f756e7449642c20536574496e646578295665633c417070726f76616c466c61673eb98d1000680000006480110000000000218e10005900000064801100000000007a8e1000540000005265676973746572496e666f4f6628566f7465496e6465782c2075333229000032000000000000000100000036000000448d10005f000000a38d100016000000566f746572496e666f4f66566f746572496e666f3c42616c616e63654f663c543e3e000032000000000000000100000036000000238d100021000000566f746572735665633c4f7074696f6e3c543a3a4163636f756e7449643e3e0032000000000000000100000033000000e08c1000430000004e657874566f746572536574a18c10003f000000566f746572436f756e740000878c10001a00000043616e646964617465730000320000000000000001000000330000006b8c10001c00000043616e646964617465436f756e740000478c1000240000004e65787446696e616c697a6528543a3a426c6f636b4e756d6265722c207533322c205665633c543a3a4163636f756e7449643e2932000000000000000100000034000000ff8b1000480000004c6561646572626f6172645665633c2842616c616e63654f663c543e2c20543a3a4163636f756e744964293e4e8b100067000000b58b10004a00000050726f787900000032000000000000000100000036000000e08a10004c0000002c8b1000220000002057686f2069732061626c6520746f20766f746520666f722077686f6d2e2056616c7565206973207468652066756e642d686f6c64696e67206163636f756e742c206b65792069732074686520766f74652d7472616e73616374696f6e2d73656e64696e67206163636f756e742e2047657420746865206c6561646572626f61726420696620776527726520696e207468652070726573656e746174696f6e2070686173652e2054686520666972737420656c656d656e742069732074686520776569676874206f66206561636820656e7472793b204974206d617920626520746865206469726563742073756d6d656420617070726f76616c207374616b65732c206f7220612077656967687465642076657273696f6e206f662069742e20546865206163636f756e747320686f6c64696e672074686520736561747320746861742077696c6c206265636f6d652066726565206f6e20746865206e6578742074616c6c792e2043757272656e74206e756d626572206f66206163746976652063616e64696461746573205468652070726573656e742063616e646964617465206c6973742e2043757272656e74206e756d626572206f6620566f746572732e20746865206e65787420667265652073657420746f2073746f7265206120766f74657220696e2e20546869732077696c6c206b6565702067726f77696e672e205468652070726573656e7420766f746572206c69737420286368756e6b656420616e6420636170706564206174205b60564f5445525f5345545f53495a45605d292e20426173696320696e666f726d6174696f6e2061626f7574206120766f7465722e2054686520766f746520696e64657820616e64206c69737420736c6f742074686174207468652063616e646964617465206077686f60207761732072656769737465726564206f7220604e6f6e6560206966207468657920617265206e6f742063757272656e746c7920726567697374657265642e2041206c697374206f6620766f74657320666f72206561636820766f7465722e2054686520766f746573206172652073746f726564206173206e756d657269632076616c75657320616e642070617273656420696e2061206269742d77697365206d616e6e65722e20496e206f7264657220746f2067657420612068756d616e2d7265616461626c6520726570726573656e746174696f6e2028605665633c626f6f6c3e60292c20757365205b60616c6c5f617070726f76616c735f6f66605d2e20467572746865726d6f72652c206561636820766563746f72206f66207363616c617273206973206368756e6b656420776974682074686520636170206f662060415050524f56414c5f5345545f53495a45602e2054686520746f74616c206e756d626572206f6620766f746520726f756e6473207468617420686176652068617070656e6564206f722061726520696e2070726f67726573732e205468652063757272656e74206d656d626572736869702e205768656e2074686572652773206120766f746520676f696e67206f6e2c20746869732073686f756c64207374696c6c206265207573656420666f7220657865637574697665206d6174746572732e2054686520626c6f636b206e756d62657220287365636f6e6420656c656d656e7420696e20746865207475706c65292069732074686520626c6f636b207468617420746865697220706f736974696f6e2069732061637469766520756e74696c202863616c63756c61746564206279207468652073756d206f662074686520626c6f636b206e756d626572207768656e20746865206d656d6265722077617320656c656374656420616e64207468656972207465726d206475726174696f6e292e204e756d626572206f66206163636f756e747320746861742073686f756c6420636f6e737469747574652074686520636f6c6c6563746976652e20486f77206c6f6e67206561636820706f736974696f6e2069732061637469766520666f722e20486f77206c6f6e6720746f2067697665206561636820746f702063616e64696461746520746f2070726573656e74207468656d73656c7665732061667465722074686520766f746520656e64732e000000001c9310000d00000000000000753f11000c00000000000000f89511002c93100000000000000000003c9310000200000000000000000000004c9310000a00000000000000753f11000c00000000000000f895110058931000000000000000000068931000010000000000000000000000709310000900000000000000753f11000c00000000000000f89511007c93100000000000000000008c9310000200000000000000000000009c9310001400000000000000753f11000c00000000000000f8951100b09310000000000000000000c0931000020000000000000000000000d09310000a000000000000000e3d11000300000000000000f8951100dc9310000000000000000000ec931000020000000000000000000000fc9310001300000000000000a98810000900000000000000f895110010941000000000000000000020941000030000000000000000000000389410000c00000000000000df0e11000e00000000000000f895110044941000000000000000000054941000020000000000000000000000649410000a000000000000000e3d11000300000000000000f895110070941000000000000000000080941000050000000000000000000000a89410000e000000000000000e3d11000300000000000000f8951100b89410000000000000000000c8941000010000000000000000000000d094100011000000000000000e3d11000300000000000000f8951100e49410000000000000000000f4941000010000000000000043616e646964616379426f6e640000003200000000000000010000005a000000049910004e0000005299100014000000566f74696e67426f6e6400003200000000000000010000003e000000c298100042000000566f74696e674665650000003200000000000000010000005b0000005b9810004a000000a59810001d00000050726573656e74536c617368506572566f7465723200000000000000010000003f000000f7971000450000003c9810001f0000004361727279436f756e7400003200000000000000010000005c0000008997100047000000d097100027000000496e6163746976654772616365506572696f64003200000000000000010000005d000000ec9610004c000000389710004b0000008397100006000000566f74696e67506572696f643200000000000000010000005e0000009a96100049000000e3961000090000004465636179526174696f000032000000000000000100000035000000479510004d0000009495100041000000d5951000470000001c9610004a0000006696100034000000564f5445525f5345545f53495a4500003200000000000000010000005f0000002395100024000000415050524f56414c5f5345545f53495a4500000032000000000000000100000060000000fc9410002700000020546865206368756e6b2073697a65206f662074686520617070726f76616c20766563746f722e20546865206368756e6b2073697a65206f662074686520766f74657220766563746f722e20446563617920666163746f72206f6620776569676874207768656e206265696e6720616363756d756c617465642e2049742073686f756c64207479706963616c6c792062652073657420746f205f5f6174206c656173745f5f20606d656d626572736869705f73697a65202d316020746f206b6565702074686520636f6c6c656374697665207365637572652e205768656e2073657420746f20604e602c20697420696e64696361746573206028312f4e295e7460206f66207374616b656420697320646563617965642061742077656967687420696e6372656d656e742073746570206074602e20302077696c6c20726573756c7420696e206e6f20776569676874206265696e6720616464656420617420616c6c20286e6f726d616c20617070726f76616c20766f74696e67292e204120726561736f6e61626c652064656661756c742076616c75652069732032342e20486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e204120726561736f6e61626c652064656661756c742076616c756520697320313030302e20486f77206d616e7920766f746520696e6469636573206e65656420746f20676f20627920616674657220612074617267657420766f7465722773206c61737420766f7465206265666f726520746865792063616e2062652072656170656420696620746865697220617070726f76616c7320617265206d6f6f742e204120726561736f6e61626c652064656661756c742076616c756520697320312e20486f77206d616e792072756e6e6572732d75702073686f756c64206861766520746865697220617070726f76616c73207065727369737420756e74696c20746865206e65787420766f74652e204120726561736f6e61626c652064656661756c742076616c756520697320322e205468652070756e6973686d656e742c2070657220766f7465722c20696620796f752070726f7669646520616e20696e76616c69642070726573656e746174696f6e2e204120726561736f6e61626c652064656661756c742076616c756520697320312e2054686520616d6f756e74206f662066656520706169642075706f6e206561636820766f7465207375626d697373696f6e2c20756e6c6573732069662074686579207375626d69742061205f686f6c655f20696e64657820616e64207265706c6163652069742e20486f77206d7563682073686f756c64206265206c6f636b656420757020696e206f7264657220746f2062652061626c6520746f207375626d697420766f7465732e20486f77206d7563682073686f756c64206265206c6f636b656420757020696e206f7264657220746f207375626d6974206f6e6527732063616e6469646163792e204120726561736f6e61626c652064656661756c742076616c756520697320392e54696d657374616d70204f72646572656448696e747354696d657374616d70204d656469616e616c77617973206174206c65617374206f6e6520726563656e742073616d706c653b20716564726563656e7420616e64206f72646572656420636f6e7461696e207468652073616d65206974656d733b20716564610000000400000004000000620000001f9a100043000000fd5d10004b000000b7000000040000004772616e64706146696e616c697479205374616c6c65647072756e696e672064696374617465642062792077696e646f775f73697a6520776869636820697320616c776179732073617475726174656420617420313b20716564000000000000909a10000a000000000000009c9a1000010000000000000000000000b49a1000020000000000000066696e616c5f68696e740000000000007982100004000000000000009b76100017000000c49a10003d000000019b10001b0000002048696e7420746861742074686520617574686f72206f66207468697320626c6f636b207468696e6b732074686520626573742066696e616c697a656420626c6f636b2069732074686520676976656e206e756d6265722e000000008c9b10000a00000000000000df0e11000e00000000000000f8951100989b10000000000000000000a89b1000010000000000000000000000b09b10000d00000000000000df0e11000e00000000000000f8951100c09b10000000000000000000d09b1000010000000000000057696e646f7753697a650000320000000000000001000000630000001f9c1000460000005265706f72744c6174656e637900000032000000000000000100000064000000d89b100047000000205468652064656c617920616674657220776869636820706f696e74207468696e6773206265636f6d6520737573706963696f75732e2044656661756c7420697320313030302e20546865206e756d626572206f6620726563656e742073616d706c657320746f206b6565702066726f6d207468697320636861696e2e2044656661756c74206973203130312e0000000474110028000000809c10004400000001010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f656c656374696f6e732f7372632f6c69622e7273b05e1000430000007f0000000100000050726f706f73657227732062616c616e636520746f6f206c6f774e6f2070726f706f73616c206174207468617420696e64657800809c10004400000001010000010000006e6f7420612070726f7879436f756e63696c2050726f787963616e6e6f74207265617020647572696e672070726573656e746174696f6e20706572696f647265706f72746572206d757374206265206120766f746572696e76616c6964207265706f7274657220696e646578766f746520696e646578206e6f742063757272656e7463616e6e6f74207265617020647572696e6720677261636520706572696f6474617267657420666f7220696e616374697669747920636c65616e7570206d75737420626520616374697665626164207265706f7274657220696e6465786261642074617267657420696e646578696e76616c69642074617267657420696e64657872657472616374696f6e20696e646578206d69736d6174636872657472616374696f6e20696e64657820696e76616c696463616e6e6f742072657472616374207768656e2070726573656e74696e6763616e6e6f742072657472616374206e6f6e2d766f7465726475706c69636174652063616e646964617465207375626d697373696f6e696e76616c69642063616e64696461746520736c6f7463616e64696461746520686173206e6f7420656e6f7567682066756e647363616e6e6f742070726573656e74206f757473696465206f662070726573656e746174696f6e20706572696f64696e646578206e6f742063757272656e747374616b65206465706f736974656420746f2070726573656e742077696e6e657220616e6420626520616464656420746f206c6561646572626f6172642073686f756c64206265206e6f6e2d7a65726f6c6561646572626f617264206d757374206578697374207768696c652070726573656e742070686173652061637469766570726573656e746572206d75737420686176652073756666696369656e7420736c61736861626c652066756e647370726573656e7465642063616e646964617465206d7573742062652063757272656e7463616e646964617465206e6f7420776f72746879206f66206c6561646572626f61726463616e646964617465206d757374206e6f7420666f726d2061206475706c696361746564206d656d62657220696620656c65637465646475706c69636174652070726573656e746174696f6e696e636f727265637420746f74616c6e6f20617070726f76616c206368616e67657320647572696e672070726573656e746174696f6e20706572696f64696e636f727265637420766f746520696e646578616d6f756e74206f662063616e6469646174657320746f207265636569766520617070726f76616c20766f7465732073686f756c64206265206e6f6e2d7a65726f616d6f756e74206f662063616e64696461746520766f7465732063616e6e6f742065786365656420616d6f756e74206f662063616e64696461746573696e76616c696420766f74657220696e64657877726f6e6720766f74657220696e6465786e657720766f746572206d75737420686176652073756666696369656e742066756e647320746f207061792074686520626f6e644772616e64706146696e616c697479204e657874466f72636564005800000008000000040000006500000066000000000000000000000067000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000058000000080000000400000065000000660000000000000000000000670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000580000000800000004000000680000007375627374726174652d6e6f64650000df6acb689907609b0200000037e397fc7c91f5e40100000040fe3ad401f8959a03000000d2bc9897eed08f1501000000f78b278be53f454c01000000ed99c5acb25eedf502000000cbca25e39f14238701000000687ad44ad37f03c201000000bc9d89904f5b923f01000000ab3c0572291feb8b010000006772616e62616265696d6f6e00000000dbc71000060000000000000069000000000000000000000000000000000000000000000000000000000000006a0000000000000000000000000000006b0000000000000000000000000000006c000000000000000000000000000000c4ab100004000000000000006d000000000000000000000000000000000000000000000000000000000000006e000000000000000000000002000000000000000000000000000000000000006f00000000000000000000000000000027db100009000000000000007000000000000000000000000000000000000000000000000000000000000000710000000000000000000000020000000000000000000000000000000000000072000000000000000000000000000000e1b810000a00000000000000730000000000000000000000000000000000000000000000000000000000000074000000000000000000000002000000000000000000000000000000000000006c0000000000000000000000000000005dec1000070000000000000075000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000760000000000000000000000000000006c000000000000000000000000000000c8ab10000800000000000000770000000000000000000000000000000000000000000000000000000000000078000000000000000000000000000000790000000000000000000000000000007a0000000000000000000000000000006f36110007000000000000007b000000000000000000000000000000000000000000000000000000000000007c0000000000000000000000000000007d0000000000000000000000000000007e0000000000000000000000000000004bb0100007000000000000007f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000008100000000000000000000000000000082000000000000000000000000000000d0ab100009000000000000008300000000000000000000000000000000000000000000000000000000000000840000000000000000000000000000008500000000000000000000000000000086000000000000000000000000000000d9ab10000700000000000000870000000000000000000000000000000000000000000000000000000000000088000000000000000000000000000000890000000000000000000000000000006c000000000000000000000000000000e0ab100012000000000000008a0000000000000000000000000000000000000000000000000000000000000088000000000000000000000000000000890000000000000000000000000000006c000000000000000000000000000000f2ab100009000000000000008b000000000000000000000000000000000000000000000000000000000000008c0000000000000000000000000000008d0000000000000000000000000000008e000000000000000000000000000000fbab100013000000000000008f0000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000910000000000000000000000000000006c0000000000000000000000000000000eac10000f0000000200000000000000000000000000000000000000000000000000000000000000000000009200000000000000000000000200000000000000000000000000000000000000930000000000000000000000000000001dac10000700000000000000940000000000000000000000000000000000000000000000000000000000000095000000000000000000000000000000960000000000000000000000000000006c00000000000000000000000000000024ac10000800000000000000970000000000000000000000000000000000000000000000000000000000000098000000000000000000000000000000990000000000000000000000000000009a0000000000000000000000000000002cac100009000000000000009b000000000000000000000000000000000000000000000000000000000000009c0000000000000000000000000000009d0000000000000000000000000000009e00000000000000000000000000000065e5100004000000000000009f00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000a10000000000000000000000000000006c00000000000000000000000000000035ac10000800000000000000a200000000000000000000000000000000000000000000000000000000000000a3000000000000000000000000000000a40000000000000000000000000000006c0000000000000000000000000000003dac1000120000000200000000000000000000000000000000000000000000000000000000000000000000006c000000000000000000000002000000000000000000000000000000000000006c000000000000000000000000000000205011000800000000000000a5000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000a60000000000000000000000000000006c00000000000000000000004261626542616c616e63657344656d6f6372616379436f756e63696c546563686e6963616c436f6d6d6974746565456c656374696f6e73546563686e6963616c4d656d6265727368697046696e616c697479547261636b65724772616e6470615472656173757279436f6e747261637473496d4f6e6c696e65417574686f72697479446973636f766572795365656420697320616e207574663820737472696e67636f6465206973206e6f7420666f756e647072697374696e6520636f6465206973206e6f7420666f756e647468657265206973206e6f7420656e6f7567682067617320666f722073746f72696e672074686520636f6465d4ac10007c00000050ad1000490000007900000006000000657865632e7072656661625f6d6f64756c652e696e697469616c2063616e27742062652067726561746572207468616e20657865632e7072656661625f6d6f64756c652e6d6178696d756d3b0a09090909090974687573204d656d6f72793a3a6e6577206d757374206e6f74206661696c3b0a0909090909097165642f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6e7472616374732f7372632f7761736d2f6d6f642e727366696e616c6e756d3a73657373696f6e3a6b657973417574686f727368697020417574686f7253657373696f6e2056616c696461746f727373657269616c697a656420617267732073686f756c642062652070726f7669646564206279207468652072756e74696d653b0a090909636f72726563746c792073657269616c697a656420646174612073686f756c6420626520646573657269616c697a61626c653b0a090909716564000000320000000000000001000000a700000004741100280000002c7411005000000037010000090000000000000098ae10000800000000000000a0ae1000020000000000000000000000d0ae10000a000000000000007365745f6b65797300000000e2c6100004000000000000003fb01000070000000000000046b010000500000000000000e25111000700000020af10003900000059af100048000000a1af1000310000006480110000000000d2af1000350000006480110000000000d52811000b00000007b010002200000029b0100016000000f02811000c0000002053657473207468652073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c657220746f20606b6579602e20416c6c6f777320616e206163636f756e7420746f20736574206974732073657373696f6e206b6579207072696f7220746f206265636f6d696e6720612076616c696461746f722e205468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e20546865206469737061746368206f726967696e206f6620746869732066756e6374696f6e206d757374206265207369676e65642e202d204f286c6f67206e2920696e206e756d626572206f66206163636f756e74732e202d204f6e6520657874726120444220656e7472792e543a3a4b65797370726f6f6653657373696f6e000000000000f83d11000a000000000000000000000064b210001300000000000000000000000000000000000000000000000000000000000000f895110078b21000000000000000000088b210000100000000000000010000000000000090b210000c0000000000000000000000c77911000c00000000000000000000000000000000000000000000000000000000000000f89511009cb210000000000000000000acb2100001000000000000000100000000000000b4b210000d0000000000000000000000d6fb10000400000000000000000000000000000000000000000000000000000000000000f895110078ba10000000000000000000c4b2100002000000000000000100000000000000d4b210000a0000000000000000000000deb210001e00000000000000000000000000000000000000000000000000000000000000f8951100fcb2100000000000000000000cb31000020000000000000001000000000000001cb31000080000000204010000000000e2511100070000000000000024b310000e000000000000003fb010000700000000000000f895110034b31000000000000000000044b310000400000000000000000000000000000064b31000080000000204010000000000e251110007000000000000006cb31000140000000000000024b310000e00000000000000f895110054ba1000000000000000000080b310000400000000000000000000005665633c543a3a56616c696461746f7249643e0032000000000000000100000033000000dab510001f00000043757272656e74496e64657832000000000000000100000035000000bcb510001e0000005175657565644368616e67656400000045b510004e00000093b51000290000005175657565644b6579735665633c28543a3a56616c696461746f7249642c20543a3a4b657973293e32000000000000000100000033000000beb410004f0000000db51000380000004e6578744b657973543a3a56616c696461746f72496400003200000000000000010000003600000097b41000270000006480110000000000e9b31000560000003fb41000580000004b65794f776e6572284b65795479706549642c205665633c75383e29a0b31000490000006480110000000000e9b31000560000003fb410005800000020546865206f776e6572206f662061206b65792e20546865207365636f6e64206b65792069732074686520604b657954797065496460202b2074686520656e636f646564206b65792e20546865206669727374206b657920697320616c77617973206044454455505f4b45595f5052454649586020746f206861766520616c6c20746865206461746120696e207468652073616d65206272616e6368206f662074686520747269652e20486176696e6720616c6c206461746120696e207468652073616d65206272616e63682073686f756c642070726576656e7420736c6f77696e6720646f776e206f7468657220717565726965732e20546865206e6578742073657373696f6e206b65797320666f7220612076616c696461746f722e2054686520717565756564206b65797320666f7220746865206e6578742073657373696f6e2e205768656e20746865206e6578742073657373696f6e20626567696e732c207468657365206b6579732077696c6c206265207573656420746f2064657465726d696e65207468652076616c696461746f7227732073657373696f6e206b6579732e20547275652069662074686520756e6465726c79696e672065636f6e6f6d6963206964656e746974696573206f7220776569676874696e6720626568696e64207468652076616c696461746f727320686173206368616e67656420696e20746865207175657565642076616c696461746f72207365742e2043757272656e7420696e646578206f66207468652073657373696f6e2e205468652063757272656e7420736574206f662076616c696461746f72732e0000000000000034b61000100000000000000044b610000500000000000000f89511004cb6100000000000000000005cb61000020000000000000044454455505f4b45595f505245464958265b75385d000000320000000000000001000000a80000006cb6100059000000c5b610000d0000002055736564206173206669727374206b657920666f7220604e6578744b6579736020616e6420604b65794f776e65726020746f2070757420616c6c20746865206461746120696e746f207468652073616d65206272616e6368206f662074686520747269652e53657373696f6e204e6578744b65797300000000000080d1f00840787d01000000000065cd1d23b4cc3a113b5c2301000000d31b421e4fdcba34836c472001000000c75bbd1e52a1fd2e01b4511d010000005feb3f1f1d03952998c57b1a01000000bdb6ca1fa50181245d60c61701000000abd95e20029dc11fec4f3215010000006fadfd2034d5561b086ec01201000000efdba82133aa4017c3a4711001000000eb7a6222fd1b7f132df1460e01000000c1332d23942a1210ad66410c01000000777f0c2408d6f90c5e33620a01000000a3040525591e360ab7a5aa080100000085311d268803c70760341c070100000097465e279f85ac054289b805010000007346d628a4a4e603ce9181040100000019e89b2abe607502ad987903010000009db7d72c54ba5801bb71a30201000000eb88dd2ff4b29000c5cf0202010000000b8c8d349e412700f8d7a5010100000053657373696f6e205175657565644b657973417574686f727368697020556e636c657353657373696f6e204b65794f776e6572000000000084b810000a0000000000000090b81000010000000000000000000000a8b8100001000000000000007365745f756e636c6573000000000000c9b810000a00000000000000d3b810000e000000b0b81000190000002050726f76696465206120736574206f6620756e636c65732e6e65775f756e636c65735665633c543a3a4865616465723e417574686f72736869700000000000f4b91000060000000000000000000000fab910003a00000000000000000000000000000000000000000000000000000000000000f895110034ba1000000000000000000044ba1000010000000000000001000000000000004cba10000600000000000000000000007a3d11000c00000000000000000000000000000000000000000000000000000000000000f895110054ba1000000000000000000064ba1000010000000000000000000000000000006cba10000c0000000000000000000000d6fb10000400000000000000000000000000000000000000000000000000000000000000f895110078ba1000000000000000000088ba1000010000000000000001000000556e636c65735665633c556e636c65456e7472794974656d3c543a3a426c6f636b4e756d6265722c20543a3a486173682c20543a3a4163636f756e7449643e3e32000000000000000100000033000000d8ba100007000000417574686f72000032000000000000000100000036000000bfba100019000000446964536574556e636c65733200000000000000010000003600000090ba10002f000000205768657468657220756e636c6573207765726520616c72656164792073657420696e207468697320626c6f636b2e20417574686f72206f662063757272656e7420626c6f636b2e20556e636c65736e6f206173736f6369617465642076616c696461746f7220494420666f72206163636f756e742e72656769737465726564206475706c6963617465206b6579556e636c657320616c72656164792073657420696e20626c6f636b2e756e636c6520616c726561647920696e636c75646564756e636c652069732067656e65736973756e636c6520697320746f6f206869676820696e20636861696e756e636c6520706172656e74206e6f7420696e20636861696e756e636c65206e6f7420726563656e7420656e6f75676820746f20626520696e636c75646564756e636c65733030496e686572656e7420776974682073616d65206964656e74696669657220616c726561647920657869737473214e6f206f74686572206572726f72732061726520616363657074656420616674657220616e2068617264206572726f72215468657265206973206f6e6c79206f6e6520666174616c206572726f723b2071656400000058000000080000000400000059000000626164206f726967696e3a20657870656374656420746f206265206e6f206f726967696e626164206f726967696e3a20657870656374656420746f206265206120726f6f74206f726967696e626164206f726967696e3a20657870656374656420746f2062652061207369676e6564206f726967696e3a65787472696e7369635f696e646578000000bd10001900000020bd100048000000290100000e000000000000000000000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f6c69622e727380bd10000e0000008ebd100048000000280100004a0000006578706c696369742070616e69632f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f6c69622e7273000080bd10000e0000008ebd100048000000270100004a00000008be10002b00000033be100044000000000100000400000054696d657374616d70206d7573742062652075706461746564206f6e636520696e2074686520626c6f636b2f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f74696d657374616d702f7372632f6c69622e7273626164207369676e617475726520696e2065787472696e736963000000acbe10003000000033be100044000000f40000000400000054696d657374616d70206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636bf4be10004e00000033be100044000000f50000000400000054696d657374616d70206d75737420696e6372656d656e74206279206174206c65617374203c4d696e696d756d506572696f643e206265747765656e2073657175656e7469616c20626c6f636b7300000000000020c010000b00000000000000648011000000000000000000000000002cc0100001000000000000000000000034c010000d000000000000006480110000000000000000000000000044c010000100000000000000000000004cc010000e00000000000000648011000000000000000000000000005cc0100001000000000000000000000064c010000c000000000000006480110000000000000000000000000070c0100001000000000000000000000078c01000050000000000000080c0100001000000000000000000000088c0100001000000000000004d656d62657241646465640093c11000390000004d656d62657252656d6f76656400000058c110003b0000004d656d6265727353776170706564000021c11000370000004d656d626572735265736574dbc010004600000044756d6d79000000acc010002f00000090c010001c000000205068616e746f6d206d656d6265722c206e6576657220757365642e73725f7374643a3a6d61726b65723a3a5068616e746f6d446174613c284163636f756e7449642c204576656e74293e20546865206d656d62657273686970207761732072657365743b2073656520746865207472616e73616374696f6e20666f722077686f20746865206e6577207365742069732e2054776f206d656d62657273207765726520737761707065643b2073656520746865207472616e73616374696f6e20666f722077686f2e2054686520676976656e206d656d626572207761732072656d6f7665643b2073656520746865207472616e73616374696f6e20666f722077686f2e2054686520676976656e206d656d626572207761732061646465643b2073656520746865207472616e73616374696f6e20666f722077686f2e54696d657374616d70204e6f7753797374656d204e756d62657253797374656d2045787472696e73696373526f6f7453797374656d2044696765737453797374656d20426c6f636b4861736853797374656d204163636f756e744e6f6e63650058000000080000000400000059000000047411002800000054c210003f0000006a000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f7375646f2f7372632f6c69622e7273000474110028000000acc2100041000000f7000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f73797374656d2f7372632f6c69622e7273000000047411002800000008c310004500000061000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f6d656d626572736869702f7372632f6c69622e727354696d657374616d7020746f6f2066617220696e2066757475726520746f206163636570744765747320616e64206465636f6465732074696d657374616d7020696e686572656e742064617461000000000000f4c310000500000000000000fcc3100001000000000000000000000004c410000100000000000000000000000cc410000a0000000000000018c4100001000000000000000000000020c4100001000000000000005375646964000000d6fb10000400000064c41000180000004b65794368616e6765640000861e11000900000028c410003c00000020546865207375646f6572206a757374207377697463686564206964656e746974793b20746865206f6c64206b657920697320737570706c6965642e2041207375646f206a75737420746f6f6b20706c6163652e7472616e73616374696f6e20626972746820626c6f636b20616e6369656e7453797374656d2052616e646f6d4d6174657269616c53797374656d204576656e747353797374656d204576656e74546f706963730000000000d8c510000a0000000000000064801100000000000000000000000000e4c51000010000000000000000000000ecc510000600000000000000f4c510000100000000000000000000000cc6100001000000000000000000000014c610000e0000000000000024c610000100000000000000000000003cc6100001000000000000000000000044c6100008000000000000004cc6100001000000000000000000000064c610000100000000000000000000006cc610000b0000000000000078c6100001000000000000000000000090c6100001000000000000000000000098c610000c00000000000000a4c61000010000000000000000000000bcc61000010000000000000066696c6c5f626c6f636b000093c710004800000072656d61726b0000000000008cc710000700000000000000e25111000700000071c710001b0000007365745f686561705f70616765730000000000006cc71000050000000000000082091100030000002dc710003f0000007365745f636f646500000000482911000300000000000000e2511100070000001bc71000120000007365745f73746f72616765000000000009c7100005000000000000000ec710000d000000eec610001b0000006b696c6c5f73746f7261676500000000e2c610000400000000000000e6c6100008000000c4c610001e000000204b696c6c20736f6d65206974656d732066726f6d2073746f726167652e6b6579735665633c4b65793e2053657420736f6d65206974656d73206f662073746f726167652e6974656d735665633c4b657956616c75653e2053657420746865206e657720636f64652e2053657420746865206e756d626572206f6620706167657320696e2074686520576562417373656d626c7920656e7669726f6e6d656e74277320686561702e7061676573204d616b6520736f6d65206f6e2d636861696e2072656d61726b2e5f72656d61726b20412062696720646973706174636820746861742077696c6c20646973616c6c6f7720616e79206f74686572207472616e73616374696f6e20746f20626520696e636c756465642e53797374656d000000000000000ccd10000c00000001010000000000007a3d11000c0000000000000018cd10000800000000000000000000000000000000000000f89511001ccf1000000000000000000020cd10000100000000000000010000000000000028cd10000e00000000000000000000000e3d11000300000000000000000000000000000000000000000000000000000000000000f895110074cd1000000000000000000038cd10000100000000000000000000000000000040cd100013000000000000000000000053cd10000600000000000000000000000000000000000000000000000000000000000000f895110074cd100000000000000000005ccd10000100000000000000000000000000000064cd10001000000000000000000000000e3d11000300000000000000000000000000000000000000000000000000000000000000f895110074cd1000000000000000000084cd1000010000000000000000000000000000008ccd1000140000000000000000000000a0cd10001000000000000000000000000000000000000000000000000000000000000000f8951100b0cd10000000000000000000c0cd100002000000000000000100000000000000d0cd1000090000000101000000000000df0e11000e000000000000004cf110000700000000000000000000000000000000000000f895110080ce10000000000000000000dccd100001000000000000000100000000000000e4cd10000d00000001010000000000000e3d11000300000000000000e25111000700000000000000000000000000000000000000f8951100f4cd1000000000000000000004ce1000010000000000000001000000000000000cce10000e00000000000000000000001ace10001200000000000000000000000000000000000000000000000000000000000000f89511002cce100000000000000000003cce1000020000000000000001000000000000004cce1000060000000000000000000000df0e11000e00000000000000000000000000000000000000000000000000000000000000f89511001ccf1000000000000000000054ce1000010000000000000001000000000000005cce10000a00000000000000000000004cf110000700000000000000000000000000000000000000000000000000000000000000f895110080ce1000000000000000000068ce10000100000000000000010000000000000070ce10000e00000000000000000000004cf110000700000000000000000000000000000000000000000000000000000000000000f895110080ce1000000000000000000090ce10000100000000000000010000000000000098ce10000600000000000000000000009ece10000b00000000000000000000000000000000000000000000000000000000000000f8951100acce10000000000000000000bcce100001000000000000000100000000000000c4ce1000060000000000000000000000cace10002300000000000000000000000000000000000000000000000000000000000000f8951100f0ce1000000000000000000000cf10000100000000000000010000000000000008cf10000a000000000000000000000012cf10000a00000000000000000000000000000000000000000000000000000000000000f89511001ccf100000000000000000002ccf10000100000000000000010000000000000034cf10000b00000002010100000000003fcf100002000000000000004cf11000070000000000000041cf10002100000000000000f895110064cf1000000000000000000074cf10000d00000000000000010000004163636f756e744e6f6e6365543a3a496e64657821d610001f00000045787472696e736963436f756e740000f3d510002e000000416c6c45787472696e73696373576569676874576569676874000000aed5100045000000416c6c45787472696e736963734c656e320000000000000001000000360000005ed51000500000004e6578745765696768744d756c7469706c6965725765696768744d756c7469706c6965723200000000000000010000004f000000ead410005900000043d510001b000000426c6f636b48617368000000c4d410002600000045787472696e736963446174610000003200000000000000010000004e00000075d410004f00000052616e646f6d4d6174657269616c2869382c205665633c543a3a486173683e29320000000000000001000000a9000000b8d310006900000021d41000540000004e756d626572000076d3100042000000506172656e744861736800005ad310001c00000045787472696e73696373526f6f740000320000000000000001000000aa00000015d31000450000004469676573744469676573744f663c543e00000032000000000000000100000033000000d9d210003c0000004576656e74735665633c4576656e745265636f72643c543a3a4576656e742c20543a3a486173683e3e000000320000000000000001000000ab000000b1d21000280000004576656e74436f756e744576656e74496e6465783200000000000000010000003500000083d210002e0000004576656e74546f7069637328295665633c28543a3a426c6f636b4e756d6265722c204576656e74496e646578293e000032000000000000000100000033000000dccf10004900000025d010002500000064801100000000004ad010004b00000095d010002a0000006480110000000000bfd010005400000013d110005100000064d110003900000064801100000000009dd1100053000000f0d110005300000043d2100040000000204d617070696e67206265747765656e206120746f7069632028726570726573656e74656420627920543a3a486173682920616e64206120766563746f72206f6620696e6465786573206f66206576656e747320696e2074686520603c4576656e74733c543e3e60206c6973742e20546865206669727374206b657920736572766573206e6f20707572706f73652e2054686973206669656c64206973206465636c6172656420617320646f75626c655f6d6170206a75737420666f7220636f6e76656e69656e6365206f66207573696e67206072656d6f76655f707265666978602e20416c6c20746f70696320766563746f727320686176652064657465726d696e69737469632073746f72616765206c6f636174696f6e7320646570656e64696e67206f6e2074686520746f7069632e205468697320616c6c6f7773206c696768742d636c69656e747320746f206c6576657261676520746865206368616e67657320747269652073746f7261676520747261636b696e67206d656368616e69736d20616e6420696e2063617365206f66206368616e67657320666574636820746865206c697374206f66206576656e7473206f6620696e7465726573742e205468652076616c756520686173207468652074797065206028543a3a426c6f636b4e756d6265722c204576656e74496e646578296020626563617573652069662077652075736564206f6e6c79206a7573742074686520604576656e74496e64657860207468656e20696e20636173652069662074686520746f70696320686173207468652073616d6520636f6e74656e7473206f6e20746865206e65787420626c6f636b206e6f206e6f74696669636174696f6e2077696c6c20626520747269676765726564207468757320746865206576656e74206d69676874206265206c6f73742e20546865206e756d626572206f66206576656e747320696e2074686520604576656e74733c543e60206c6973742e204576656e7473206465706f736974656420666f72207468652063757272656e7420626c6f636b2e20446967657374206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2045787472696e7369637320726f6f74206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2048617368206f66207468652070726576696f757320626c6f636b2e205468652063757272656e7420626c6f636b206e756d626572206265696e672070726f6365737365642e205365742062792060657865637574655f626c6f636b602e20536572696573206f6620626c6f636b20686561646572732066726f6d20746865206c61737420383120626c6f636b73207468617420616374732061732072616e646f6d2073656564206d6174657269616c2e205468697320697320617272616e67656420617320612072696e6720627566666572207769746820746865206069386020707265666978206265696e672074686520696e64657820696e746f20746865206056656360206f6620746865206f6c6465737420686173682e2045787472696e73696373206461746120666f72207468652063757272656e7420626c6f636b20286d61707320616e2065787472696e736963277320696e64657820746f206974732064617461292e204d6170206f6620626c6f636b206e756d6265727320746f20626c6f636b206861736865732e20546865206e65787420776569676874206d756c7469706c6965722e20546869732073686f756c6420626520757064617465642061742074686520656e64206f66206561636820626c6f636b206261736564206f6e207468652073617475726174696f6e206c6576656c2028776569676874292e20546f74616c206c656e6774682028696e2062797465732920666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e20546f74616c2077656967687420666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e20546f74616c2065787472696e7369637320636f756e7420666f72207468652063757272656e7420626c6f636b2e2045787472696e73696373206e6f6e636520666f72206163636f756e74732e53797374656d20506172656e7448617368000000c9d810001c00000054d7100044000000bf00000003000000a5d810002400000054d7100044000000c8000000030000006dd810003800000054d7100044000000060100002a00000045d810002800000054d710004400000007010000320000001dd810002800000054d7100044000000090100002c000000f1d710002c00000054d7100044000000080100004c000000bfd710003200000054d7100044000000310100000300000098d710002700000054d710004400000039010000040000002cd710002800000054d71000440000003f0100000300000053746f7261676520726f6f74206d757374206d6174636820746861742063616c63756c617465642e2f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f6578656375746976652f7372632f6c69622e7273446967657374206974656d206d757374206d6174636820746861742063616c63756c617465642e4e756d626572206f6620646967657374206974656d73206d757374206d6174636820746861742063616c63756c617465642e416c6c2065787472696e736963732073686f756c6420686176652074686520636f7272656374206e6f6e636545787472696e736963732073686f756c64206e6f742065786365656420626c6f636b206c696d6974416c6c2065787472696e736963732073686f756c642062652070726f7065726c79207369676e6564416c6c2065787472696e736963732073686f756c6420686176652073656e6465722061626c6520746f2070617920746865697220666565735472616e73616374696f6e207472696520726f6f74206d7573742062652076616c69642e506172656e7420686173682073686f756c642062652076616c69642e00000000d9100048000000a10a00000e00000000000000000000002f72757374632f353231643738343037343731636237386539626266343731363066366161323330343761633439392f7372632f6c6962636f72652f736c6963652f6d6f642e72730000000074d91000030000000000000078d9100001000000000000000000000090d910000900000000000000736574000000000012db1000030000000000000015db100012000000d8d91000160000006480110000000000eed910005600000044da10003600000064801100000000007ada100051000000cbda1000110000006480110000000000dcda10003600000020536574207468652063757272656e742074696d652e20546869732063616c6c2073686f756c6420626520696e766f6b65642065786163746c79206f6e63652070657220626c6f636b2e2049742077696c6c2070616e6963206174207468652066696e616c697a6174696f6e2070686173652c20696620746869732063616c6c206861736e2774206265656e20696e766f6b656420627920746861742074696d652e205468652074696d657374616d702073686f756c642062652067726561746572207468616e207468652070726576696f7573206f6e652062792074686520616d6f756e742073706563696669656420627920604d696e696d756d506572696f64602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652060496e686572656e74602e6e6f77436f6d706163743c543a3a4d6f6d656e743e54696d657374616d7000000000e0db1000030000000000000000000000e3db10000900000000000000000000000000000000000000000000000000000000000000f8951100ecdb10000000000000000000fcdb10000100000000000000010000000000000004dc1000090000000000000000000000d6fb10000400000000000000000000000000000000000000000000000000000000000000f895110010dc1000000000000000000020dc10000100000000000000010000004e6f77543a3a4d6f6d656e743200000000000000010000004f00000055dc1000240000004469645570646174650000003200000000000000010000003600000028dc10002d00000020446964207468652074696d657374616d7020676574207570646174656420696e207468697320626c6f636b3f2043757272656e742074696d6520666f72207468652063757272656e7420626c6f636b2e00000000000000b4dc10000d00000000000000e3db10000900000000000000f8951100c4dc10000000000000000000d4dc100004000000000000004d696e696d756d506572696f64000000320000000000000001000000ac000000f4dc10005a0000004edd10005a000000a8dd10005900000001de10001c00000020546865206d696e696d756d20706572696f64206265747765656e20626c6f636b732e204265776172652074686174207468697320697320646966666572656e7420746f20746865202a65787065637465642a20706572696f6420746861742074686520626c6f636b2070726f64756374696f6e206170706172617475732070726f76696465732e20596f75722063686f73656e20636f6e73656e7375732073797374656d2077696c6c2067656e6572616c6c7920776f726b2077697468207468697320746f2064657465726d696e6520612073656e7369626c6520626c6f636b2074696d652e20652e672e20466f7220417572612c2069742077696c6c20626520646f75626c65207468697320706572696f64206f6e2064656661756c742073657474696e67732e00000000000000d0de10000a00000000000000dcde1000010000000000000000000000f4de10000300000000000000000000000cdf10000d00000000000000dcde10000100000000000000000000001cdf100003000000000000000000000034df10000b0000000000000040df100002000000000000000000000070df100003000000000000000000000088df10000d0000000000000098df1000010000000000000000000000b0df100004000000000000006164645f6d656d6265720000000000007ee1100003000000000000007a3d11000c00000032e110001f000000648011000000000051e110002d00000072656d6f76655f6d656d626572000000dee0100024000000648011000000000002e1100030000000737761705f6d656d6265720000000000d5e0100006000000000000007a3d11000c00000000000000dbe0100003000000000000007a3d11000c00000077e01000300000006480110000000000a7e010002e00000072657365745f6d656d626572730000000000000070e0100007000000000000004928110011000000d0df10005600000026e010001b000000648011000000000041e010002f000000204368616e676520746865206d656d6265727368697020746f2061206e6577207365742c20646973726567617264696e6720746865206578697374696e67206d656d626572736869702e204265206e69636520616e64207061737320606d656d6265727360207072652d736f727465642e204d6179206f6e6c792062652063616c6c65642066726f6d206052657365744f726967696e60206f7220726f6f742e6d656d626572732053776170206f7574206f6e65206d656d626572206072656d6f76656020666f7220616e6f746865722060616464602e204d6179206f6e6c792062652063616c6c65642066726f6d2060537761704f726967696e60206f7220726f6f742e72656d6f76656164642052656d6f76652061206d656d626572206077686f602066726f6d20746865207365742e204d6179206f6e6c792062652063616c6c65642066726f6d206052656d6f76654f726967696e60206f7220726f6f742e204164642061206d656d626572206077686f6020746f20746865207365742e204d6179206f6e6c792062652063616c6c65642066726f6d20604164644f726967696e60206f7220726f6f742e77686f496e7374616e6365314d656d62657273686970000000004cf51000070000000000000000000000492811001100000000000000000000000000000000000000000000000000000000000000f8951100ece110000000000000000000fce110000100000000000000010000003200000000000000010000003300000004e2100032000000205468652063757272656e74206d656d626572736869702c2073746f72656420617320616e206f726465726564205665632e000054c210003f0000006a000000010000006f6e6c79207468652063757272656e74207375646f206b65792063616e207375646f5375646f204b65796f6e6c79207468652063757272656e74207375646f206b65792063616e206368616e676520746865207375646f206b657900acc2100041000000f7000000010000003a6865617070616765733a636f64650008c31000450000006100000001000000496e7374616e6365314d656d62657273686970204d656d626572736e6f742061206d656d626572616c72656164792061206d656d626572626164206f726967696e0000000000000070e31000040000000000000074e310000100000000000000000000008ce31000090000000000000000000000d4e310000700000000000000dce31000010000000000000000000000f4e3100009000000000000007375646f0000000044f11000080000000000000055e5100010000000f7e410004e000000648011000000000099e41000340000006480110000000000d52811000b0000004f34110008000000cde410001900000045e5100010000000f02811000c0000007365745f6b65790000000000482911000300000000000000a32a1100230000003ce410005d000000648011000000000099e41000340000006480110000000000d52811000b0000004f34110008000000cde4100019000000e6e4100011000000f02811000c0000002041757468656e74696361746573207468652063757272656e74207375646f206b657920616e6420736574732074686520676976656e204163636f756e7449642028606e6577602920617320746865206e6577207375646f206b65792e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e202d204c696d697465642073746f726167652072656164732e202d204f6e65204442206368616e67652e2041757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c20776974682060526f6f7460206f726967696e2e202d204e6f204442207772697465732e426f783c543a3a50726f706f73616c3e5375646f00000000000000c4e510000300000000000000000000007a3d11000c00000000000000000000000000000000000000000000000000000000000000f8951100c8e510000000000000000000d8e510000100000000000000010000004b65790032000000000000000100000051000000e0e51000210000002054686520604163636f756e74496460206f6620746865207375646f206b65792e0000000000000030e610000f0000000000000040e6100002000000000000000000000050e6100004000000000000004e65774163636f756e74496e64657800861e110009000000ebe610000c00000070e6100022000000648011000000000092e6100041000000d3e61000180000002041206e6577206163636f756e7420696e646578207761732061737369676e65642e2054686973206576656e74206973206e6f7420747269676765726564207768656e20616e206578697374696e6720696e64657820697320726561737369676e656420746f20616e6f7468657220604163636f756e744964602e4163636f756e74496e64657873746f72616765206973206e6f74206e756c6c2c207468657265666f7265206d75737420626520612076616c69642074797065496e76616c6964206f726967696e0000000040e81000080000000000000048e8100004000000000000000000000068e8100002000000000000000000000078e81000050000000000000080e81000050000000000000000000000a8e81000020000000000000000000000b8e810000800000000000000ccfa1000010000000000000000000000c0e81000010000000000000000000000c8e810000b00000000000000ccfa1000010000000000000000000000d4e81000010000000000000000000000dce810000800000000000000e4e81000020000000000000000000000f4e81000010000000000000000000000fce810000e00000000000000e4e810000200000000000000000000000ce91000010000000000000050726f706f736564861e110009000000fcea10000d00000038fc1000040000008eea10000b00000099ea100053000000ecea100010000000566f746564000000861e11000900000038fc100004000000d6fb1000040000008eea10000b0000008eea10000b00000006ea10004200000048ea100046000000417070726f766564d5e9100031000000446973617070726f76656400a0e9100035000000457865637574656438fc100004000000d6fb1000040000005fe91000410000004d656d6265724578656375746564000014e910004b00000020412073696e676c65206d656d6265722064696420736f6d6520616374696f6e3b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e2041206d6f74696f6e207761732065786563757465643b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e2041206d6f74696f6e20776173206e6f7420617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2077617320617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2028676976656e20686173682920686173206265656e20766f746564206f6e20627920676976656e206163636f756e742c206c656176696e6720612074616c6c79202879657320766f74657320616e64206e6f20766f74657320676976656e20726573706563746976656c7920617320604d656d626572436f756e7460292e4d656d626572436f756e742041206d6f74696f6e2028676976656e20686173682920686173206265656e2070726f706f7365642028627920676976656e206163636f756e742920776974682061207468726573686f6c642028676976656e20604d656d626572436f756e7460292e50726f706f73616c496e646578496e7374616e636532436f6c6c656374697665204d656d62657273496e7374616e636531436f6c6c656374697665204d656d62657273496e646963657320456e756d5365740000617474656d707420746f20646976696465206279207a65726f000000320000000000000001000000a7000000047411002800000094eb1000420000004a000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f696e64696365732f7372632f6c69622e727300000474110028000000f0eb1000450000008b000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6c6c6563746976652f7372632f6c69622e727300000094eb1000420000004a00000001000000696e76616c6964206163636f756e7420696e646578496e64696365730000000014ed10000b00000000000000000000001fed10000f00000000000000000000000000000000000000000000000000000000000000f89511003cf81000000000000000000030ed10000100000000000000010000000000000038ed10000700000001010000000000001fed10000f00000000000000492811001100000000000000000000000000000000000000f89511004cf81000000000000000000040ed10000100000000000000010000004e657874456e756d536574543a3a4163636f756e74496e64657800005eed10001f000000456e756d5365740048ed1000160000002054686520656e756d65726174696f6e20736574732e20546865206e657874206672656520656e756d65726174696f6e207365742e00000010ee100048000000a10a00000e00000010ee1000480000009b0a00000a00000050eb100019000000c0ed100047000000e20000000a00000000000000000000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f7374616b696e672f7372632f70687261676d656e2e72730000000000000000002f72757374632f353231643738343037343731636237386539626266343731363066366161323330343761633439392f7372632f6c6962636f72652f736c6963652f6d6f642e7273496e7374616e636531436f6c6c6563746976652050726f706f73616c73496e7374616e636531436f6c6c65637469766520566f74696e67496e7374616e636532436f6c6c6563746976652050726f706f73616c73496e7374616e636532436f6c6c65637469766520566f74696e67496e6469636573204e657874456e756d536574000000000000008cef10000b0000000000000098ef1000010000000000000000000000b0ef1000040000000000000000000000d0ef10000700000000000000d8ef1000010000000000000000000000f0ef100003000000000000000000000008f01000070000000000000010f0100002000000000000000000000040f0100004000000000000000000000060f01000040000000000000064f01000030000000000000000000000acf0100004000000000000007365745f6d656d626572730000000000ebf210000b0000000000000049281100110000006af2100054000000bef21000170000006480110000000000d5f210001600000065786563757465000000000044f110000800000000000000e4f110001e00000002f210003d00000064801100000000003ff210002b00000070726f706f73650000000000c7f110000900000000000000d0f11000140000000000000044f110000800000000000000e4f110001e000000d52811000b00000075f110002400000099f110002e000000f02811000c000000766f74650000000044f1100008000000000000004cf11000070000000000000053f11000050000000000000058f1100016000000000000006ef110000700000000000000d6fb100004000000d52811000b000000ccf0100023000000eff0100055000000f02811000c000000202d20426f756e6465642073746f72616765207265616420616e64207772697465732e202d2057696c6c20626520736c696768746c792068656176696572206966207468652070726f706f73616c20697320617070726f766564202f20646973617070726f7665642061667465722074686520766f74652e70726f706f73616c543a3a48617368696e646578436f6d706163743c50726f706f73616c496e6465783e617070726f7665202d20426f756e6465642073746f7261676520726561647320616e64207772697465732e202d20417267756d656e7420607468726573686f6c6460206861732062656172696e67206f6e207765696768742e7468726573686f6c64436f6d706163743c4d656d626572436f756e743e426f783c3c542061732054726169743c493e3e3a3a50726f706f73616c3e20446973706174636820612070726f706f73616c2066726f6d2061206d656d626572207573696e672074686520604d656d62657260206f726967696e2e204f726967696e206d7573742062652061206d656d626572206f662074686520636f6c6c6563746976652e205365742074686520636f6c6c6563746976652773206d656d62657273686970206d616e75616c6c7920746f20606e65775f6d656d62657273602e204265206e69636520746f2074686520636861696e20616e642070726f76696465206974207072652d736f727465642e20526571756972657320726f6f74206f726967696e2e6e65775f6d656d62657273496e7374616e636531436f6c6c65637469766500000000000000c4f41000090000000000000000000000cdf410000c00000000000000000000000000000000000000000000000000000000000000f89511000cf810000000000000000000dcf4100001000000000000000100000000000000e4f410000a00000001010000000000004cf110000700000000000000eef410001900000000000000000000000000000000000000f89511001cf81000000000000000000008f510000100000000000000000000000000000010f510000600000001010000000000004cf11000070000000000000016f510001300000000000000000000000000000000000000f89511002cf8100000000000000000002cf510000100000000000000000000000000000034f510000d00000000000000000000000e3d11000300000000000000000000000000000000000000000000000000000000000000f89511003cf81000000000000000000044f51000010000000000000001000000000000004cf51000070000000000000000000000492811001100000000000000000000000000000000000000000000000000000000000000f89511004cf81000000000000000000054f5100001000000000000000100000050726f706f73616c735665633c543a3a486173683e0000001cf610002400000050726f706f73616c4f663c542061732054726169743c493e3e3a3a50726f706f73616c00e9f5100033000000566f74696e67566f7465733c543a3a4163636f756e7449643e000000bcf510002d00000050726f706f73616c436f756e74000000aaf51000120000004d656d62657273005cf510004e000000205468652063757272656e74206d656d62657273206f662074686520636f6c6c6563746976652e20546869732069732073746f72656420736f7274656420286a7573742062792076616c7565292e2050726f706f73616c7320736f206661722e20566f746573206f6e206120676976656e2070726f706f73616c2c206966206974206973206f6e676f696e672e2041637475616c2070726f706f73616c20666f72206120676976656e20686173682c20696620697427732063757272656e742e2054686520686173686573206f6620746865206163746976652070726f706f73616c732e496e7374616e636532436f6c6c6563746976650000000000c4f41000090000000000000000000000cdf410000c00000000000000000000000000000000000000000000000000000000000000f89511000cf810000000000000000000dcf4100001000000000000000100000000000000e4f410000a00000001010000000000004cf110000700000000000000eef410001900000000000000000000000000000000000000f89511001cf81000000000000000000008f510000100000000000000000000000000000010f510000600000001010000000000004cf11000070000000000000016f510001300000000000000000000000000000000000000f89511002cf8100000000000000000002cf510000100000000000000000000000000000034f510000d00000000000000000000000e3d11000300000000000000000000000000000000000000000000000000000000000000f89511003cf81000000000000000000044f51000010000000000000001000000000000004cf51000070000000000000000000000492811001100000000000000000000000000000000000000000000000000000000000000f89511004cf81000000000000000000054f510000100000000000000010000003200000000000000010000003300000032000000000000000100000036000000320000000000000001000000360000003200000000000000010000003500000032000000000000000100000033000000f0eb1000450000008b0000000100000070726f706f736572206e6f742061206d656d6265726475706c69636174652070726f706f73616c73206e6f7420616c6c6f776564496e7374616e636532436f6c6c6563746976652050726f706f73616c4f66496e7374616e636532436f6c6c6563746976652050726f706f73616c436f756e7470726f706f73616c206d757374206578697374766f746572206e6f742061206d656d6265726d69736d61746368656420696e6465786475706c696361746520766f74652069676e6f726564496e7374616e636531436f6c6c6563746976652050726f706f73616c4f66496e7374616e636531436f6c6c6563746976652050726f706f73616c436f756e740000000000000074fa100008000000000000007cfa100003000000000000000000000094fa10000100000000000000000000009cfa10000c00000000000000a8fa1000020000000000000000000000b8fa1000010000000000000000000000c0fa10000a00000000000000ccfa1000010000000000000000000000d4fa1000010000000000000000000000dcfa10000f00000000000000ecfa1000010000000000000000000000f4fa1000010000000000000000000000fcfa10000a0000000000000008fb100002000000000000000000000018fb100002000000000000000000000028fb1000080000000000000030fb100002000000000000000000000040fb100001000000000000005472616e73666572861e110009000000861e1100090000008f1e11000700000073fc100055000000496e7374616e746961746564861e110009000000861e1100090000003cfc100037000000436f646553746f726564000038fc1000040000000afc10002e0000005363686564756c6555706461746564000e3d110003000000dafb100030000000446973706174636865640000861e110009000000d6fb1000040000006bfb10004e000000b9fb10001d000000436f6e7472616374861e110009000000e25111000700000048fb10002300000020416e206576656e742066726f6d20636f6e7472616374206f66206163636f756e742e20412063616c6c2077617320646973706174636865642066726f6d2074686520676976656e206163636f756e742e2054686520626f6f6c207369676e616c73207768657468657220697420776173207375636365737366756c20657865637574696f6e206f72206e6f742e626f6f6c20547269676765726564207768656e207468652063757272656e74207363686564756c6520697320757064617465642e20436f646520776974682074686520737065636966696564206861736820686173206265656e2073746f7265642e4861736820436f6e7472616374206465706c6f7965642062792061646472657373206174207468652073706563696669656420616464726573732e205472616e736665722068617070656e6564206066726f6d6020746f2060746f60207769746820676976656e206076616c7565602061732070617274206f662061206063616c6c60206f722060637265617465602e64656661756c743a436f6e7472616374205072697374696e65436f6465436f6e747261637420436f646553746f72616765436f6e747261637420436f6e7472616374496e666f4f66436f6e74726163742047617350726963650000000000000000fe10000f0000000000000010fe100001000000000000000000000028fe100003000000000000000000000040fe1000080000000000000048fe100002000000000000000000000078fe1000020000000000000000000000915b1100040000000000000088fe1000040000000000000000000000e8fe100007000000000000000000000020ff1000060000000000000028ff100004000000000000000000000088ff10000a0000000000000000000000d8ff10000f00000000000000e8ff10000200000000000000000000001800110005000000000000007570646174655f7363686564756c6500000000005e06110008000000000000006606110008000000ee0511002d00000064801100000000001b061100430000007075745f636f6465000000009c0311000900000000000000a50311000c00000000000000ea0511000400000000000000e2511100070000005e05110057000000b505110035000000000000005a0111000400000000000000a32a110023000000000000000f33110005000000000000001433110015000000000000009c0311000900000000000000a50311000c00000000000000c50311000400000000000000e251110007000000c90311004200000064801100000000000b0411004a000000550411002c0000008104110046000000c70411005200000019051100450000006372656174650000000000009303110009000000000000001433110015000000000000009c0311000900000000000000a50311000c00000000000000b10311000900000000000000ba0311000b00000000000000c50311000400000000000000e2511100070000007c0111006a0000006480110000000000e601110021000000648011000000000007021100500000005702110041000000980211005b000000f3021100570000004a0311002a000000740311001f000000636c61696d5f73757263686172676500000000005a01110004000000000000007a3d11000c000000000000005e0111000a000000000000006801110014000000400011005c0000009c001100450000006480110000000000e10011004e0000002f0111002b00000020416c6c6f777320626c6f636b2070726f64756365727320746f20636c61696d206120736d616c6c2072657761726420666f72206576696374696e67206120636f6e74726163742e204966206120626c6f636b2070726f6475636572206661696c7320746f20646f20736f2c206120726567756c61722075736572732077696c6c20626520616c6c6f77656420746f20636c61696d20746865207265776172642e20496620636f6e7472616374206973206e6f742065766963746564206173206120726573756c74206f6620746869732063616c6c2c206e6f20616374696f6e73206172652074616b656e20616e64207468652073656e646572206973206e6f7420656c696769626c6520666f7220746865207265776172642e646573746175785f73656e6465724f7074696f6e3c543a3a4163636f756e7449643e20437265617465732061206e657720636f6e74726163742066726f6d207468652060636f646568617368602067656e65726174656420627920607075745f636f6465602c206f7074696f6e616c6c79207472616e7366657272696e6720736f6d652062616c616e63652e204372656174696f6e20697320657865637574656420617320666f6c6c6f77733a202d205468652064657374696e6174696f6e206164647265737320697320636f6d7075746564206261736564206f6e207468652073656e64657220616e642068617368206f662074686520636f64652e202d2054686520736d6172742d636f6e7472616374206163636f756e7420697320637265617465642061742074686520636f6d707574656420616464726573732e202d20546865206063746f725f636f64656020697320657865637574656420696e2074686520636f6e74657874206f6620746865206e65776c792d63726561746564206163636f756e742e204275666665722072657475726e656420202061667465722074686520657865637574696f6e206973207361766564206173207468652060636f646560206f6620746865206163636f756e742e205468617420636f64652077696c6c20626520696e766f6b656420202075706f6e20616e792063616c6c2072656365697665642062792074686973206163636f756e742e202d2054686520636f6e747261637420697320696e697469616c697a65642e656e646f776d656e746761735f6c696d6974436f6d706163743c4761733e636f64655f68617368436f6465486173683c543e64617461204d616b657320612063616c6c20746f20616e206163636f756e742c206f7074696f6e616c6c79207472616e7366657272696e6720736f6d652062616c616e63652e202a20496620746865206163636f756e74206973206120736d6172742d636f6e7472616374206163636f756e742c20746865206173736f63696174656420636f64652077696c6c20626520657865637574656420616e6420616e792076616c75652077696c6c206265207472616e736665727265642e202a20496620746865206163636f756e74206973206120726567756c6172206163636f756e742c20616e792076616c75652077696c6c206265207472616e736665727265642e202a204966206e6f206163636f756e742065786973747320616e64207468652063616c6c2076616c7565206973206e6f74206c657373207468616e20606578697374656e7469616c5f6465706f736974602c206120726567756c6172206163636f756e742077696c6c206265206372656174656420616e6420616e792076616c75652077696c6c206265207472616e736665727265642e2053746f7265732074686520676976656e2062696e617279205761736d20636f646520696e746f2074686520636861696e27732073746f7261676520616e642072657475726e73206974732060636f646568617368602e20596f752063616e20696e7374616e746961746520636f6e747261637473206f6e6c7920776974682073746f72656420636f64652e636f6465205570646174657320746865207363686564756c6520666f72206d65746572696e6720636f6e7472616374732e20546865207363686564756c65206d7573742068617665206120677265617465722076657273696f6e207468616e207468652073746f726564207363686564756c652e7363686564756c655363686564756c65000000000000d8081100080000000000000000000000e00811000300000000000000000000000000000000000000000000000000000000000000f8951100880911000000000000000000e408110001000000000000000100000000000000ec0811000f0000000000000000000000660611000800000000000000000000000000000000000000000000000000000000000000f8951100fc08110000000000000000000c09110001000000000000000100000000000000140911000c0000000101000000000000ba0311000b00000000000000e25111000700000000000000000000000000000000000000f89511002009110000000000000000003009110001000000000000000000000000000000380911000b0000000101000000000000ba0311000b00000000000000430911001600000000000000000000000000000000000000f89511005c09110000000000000000006c09110001000000000000000000000000000000740911000e0000000000000000000000820911000300000000000000000000000000000000000000000000000000000000000000f89511008809110000000000000000009809110001000000000000000100000000000000a00911000e00000001010000000000007a3d11000c00000000000000ae0911000f00000000000000000000000000000000000000f8951100c00911000000000000000000d009110001000000000000000000000000000000d8091100080000000000000000000000753f11000c00000000000000000000000000000000000000000000000000000000000000f8951100e00911000000000000000000f00911000100000000000000010000004761735370656e74476173002c0b11002000000043757272656e745363686564756c6500320000000000000001000000ad000000070b1100250000005072697374696e65436f6465320000000000000001000000ae000000ae0a110059000000436f646553746f726167657761736d3a3a5072656661625761736d4d6f64756c6500000032000000000000000100000036000000550a1100590000004163636f756e74436f756e7465727536340000003200000000000000010000004f000000400a110015000000436f6e7472616374496e666f4f66436f6e7472616374496e666f3c543e00000032000000000000000100000036000000160a11002a0000004761735072696365320000000000000001000000af000000f80911001e00000020546865207072696365206f66206f6e6520756e6974206f66206761732e2054686520636f6465206173736f6369617465642077697468206120676976656e206163636f756e742e20546865207375627472696520636f756e7465722e2041206d617070696e67206265747765656e20616e206f726967696e616c20636f6465206861736820616e6420696e737472756d656e746564207761736d20636f64652c20726561647920666f7220657865637574696f6e2e2041206d617070696e672066726f6d20616e206f726967696e616c20636f6465206861736820746f20746865206f726967696e616c20636f64652c20756e746f756368656420627920696e737472756d656e746174696f6e2e2043757272656e7420636f7374207363686564756c6520666f7220636f6e7472616374732e20476173207370656e7420736f2066617220696e207468697320626c6f636b2e00000000cc0e11001300000000000000df0e11000e00000000000000f8951100f00e11000000000000000000000f1100040000000000000000000000200f11001000000000000000753f11000c00000000000000f8951100300f11000000000000000000400f1100010000000000000000000000480f110011000000000000000e3d11000300000000000000f89511005c0f110000000000000000006c0f11000200000000000000000000007c0f11000b00000000000000753f11000c00000000000000f8951100880f11000000000000000000980f1100010000000000000000000000a00f11001100000000000000753f11000c00000000000000f8951100b40f11000000000000000000c40f1100070000000000000000000000fc0f11000f00000000000000753f11000c00000000000000f89511000c10110000000000000000001c1011000200000000000000000000002c1011000b00000000000000753f11000c00000000000000f8951100a8101100000000000000000038101100010000000000000000000000401011000b00000000000000753f11000c00000000000000f8951100a810110000000000000000004c101100010000000000000000000000541011001200000000000000753f11000c00000000000000f8951100a8101100000000000000000068101100010000000000000000000000701011001200000000000000753f11000c00000000000000f8951100841011000000000000000000941011000100000000000000000000009c1011000b00000000000000753f11000c00000000000000f8951100a81011000000000000000000b8101100020000000000000000000000c81011000b00000000000000e00811000300000000000000f8951100f41011000000000000000000d4101100020000000000000000000000e41011000d00000000000000e00811000300000000000000f8951100f41011000000000000000000041111000200000000000000000000001411110008000000000000000e3d11000300000000000000f89511001c11110000000000000000002c1111000200000000000000000000003c1111000c000000000000000e3d11000300000000000000f895110048111100000000000000000058111100010000000000000000000000601111000d00000000000000e00811000300000000000000f89511007011110000000000000000008011110002000000000000005369676e6564436c61696d48616e6469636170543a3a426c6f636b4e756d626572000000320000000000000001000000b00000001d1711003800000064801100000000005517110043000000981711001a000000546f6d6273746f6e654465706f736974320000000000000001000000b1000000e81611003500000053746f7261676553697a654f6666736574000000320000000000000001000000600000006f1611004b000000ba1611002e00000052656e744279746546656500320000000000000001000000b2000000221611004d00000052656e744465706f7369744f6666736574000000320000000000000001000000b3000000aa14110041000000eb141100160000006480110000000000011511005a0000005b15110056000000b115110053000000041611001e00000053757263686172676552657761726400320000000000000001000000b40000005714110039000000901411001a0000005472616e736665724665650032141100250000004372656174696f6e466565000b141100270000005472616e73616374696f6e426173654665650000d4131100370000005472616e73616374696f6e427974654665650000320000000000000001000000400000009113110043000000436f6e7472616374466565003200000000000000010000003f0000003f1311004b0000008a1311000700000043616c6c4261736546656500ea12110047000000311311000e00000043726561746542617365466565000000320000000000000001000000b50000009912110049000000e2121100080000004d61784465707468320000000000000001000000b600000044121100470000008b1211000e0000004d617856616c756553697a65320000000000000001000000b7000000f61111004e000000426c6f636b4761734c696d6974000000320000000000000001000000b80000009011110049000000d91111001d00000020546865206d6178696d756d20616d6f756e74206f6620676173207468617420636f756c6420626520657870656e6465642070657220626c6f636b2e204120726561736f6e61626c652064656661756c742076616c75652069732031305f3030305f3030302e20546865206d6178696d756d2073697a65206f6620612073746f726167652076616c756520696e2062797465732e204120726561736f6e61626c652064656661756c74206973203136204b69422e20546865206d6178696d756d206e657374696e67206c6576656c206f6620612063616c6c2f63726561746520737461636b2e204120726561736f6e61626c652064656661756c742076616c7565206973203130302e20546865206261736520666565206368617267656420666f72206372656174696e67206120636f6e74726163742e204120726561736f6e61626c652064656661756c742076616c7565206973203137352e20546865206261736520666565206368617267656420666f722063616c6c696e6720696e746f206120636f6e74726163742e204120726561736f6e61626c652064656661756c742076616c7565206973203133352e205468652066656520726571756972656420746f20637265617465206120636f6e747261637420696e7374616e63652e204120726561736f6e61626c652064656661756c742076616c75652069732032312e205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b20746865207065722d6279746520706f7274696f6e2e205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b2074686520626173652e205468652066656520726571756972656420746f2063726561746520616e206163636f756e742e205468652066656520726571756972656420746f206d616b652061207472616e736665722e205265776172642074686174206973207265636569766564206279207468652070617274792077686f736520746f75636820686173206c656420746f2072656d6f76616c206f66206120636f6e74726163742e2054686520616d6f756e74206f662066756e6473206120636f6e74726163742073686f756c64206465706f73697420696e206f7264657220746f206f66667365742074686520636f7374206f66206f6e6520627974652e204c6574277320737570706f736520746865206465706f73697420697320312c303030204255202862616c616e636520756e697473292f6279746520616e64207468652072656e7420697320312042552f627974652f6461792c207468656e206120636f6e7472616374207769746820312c3030302c3030302042552074686174207573657320312c303030206279746573206f662073746f7261676520776f756c6420706179206e6f2072656e742e20427574206966207468652062616c616e6365207265647563656420746f203530302c30303020425520616e64207468652073746f7261676520737461796564207468652073616d6520617420312c3030302c207468656e20697420776f756c6420706179203530302042552f6461792e205072696365206f6620612062797465206f662073746f7261676520706572206f6e6520626c6f636b20696e74657276616c2e2053686f756c642062652067726561746572207468616e20302e2053697a65206f66206120636f6e7472616374206174207468652074696d65206f66206372656174696f6e2e205468697320697320612073696d706c652077617920746f20656e73757265207468617420656d70747920636f6e747261637473206576656e7475616c6c7920676574732064656c657465642e20546865206d696e696d756d20616d6f756e7420726571756972656420746f2067656e6572617465206120746f6d6273746f6e652e204e756d626572206f6620626c6f636b2064656c617920616e2065787472696e73696320636c61696d20737572636861726765206861732e205768656e20636c61696d207375726368617267652069732063616c6c656420627920616e2065787472696e736963207468652072656e7420697320636865636b656420666f722063757272656e745f626c6f636b202d2064656c61796d656d6f727976616c69646174696f6e3a20696d706f727420656e74727920706f696e747320746f2061206e6f6e2d6578697374656e74207479706543616e6e6f7420696d706f727420676c6f62616c736d6f64756c6520696d706f7274732061206e6f6e2d6578697374656e742066756e6374696f6e6d6f64756c6520696d706f72747320606578745f7072696e746c6e60206275742064656275672066656174757265732064697361626c656443616e6e6f7420696d706f7274207461626c65736d6f64756c652068617320696d706f7274732066726f6d2061206e6f6e2d27656e7627206e616d6573706163654d656d6f727920696d706f7274206d757374206861766520746865206669656c64206e616d6520276d656d6f7279274d756c7469706c65206d656d6f727920696d706f72747320646566696e65644d6178696d756d206e756d626572206f662070616765732073686f756c6420626520616c77617973206465636c617265642e52657175657374656420696e697469616c206e756d626572206f662070616765732073686f756c64206e6f74206578636565642074686520726571756573746564206d6178696d756d4d6178696d756d206e756d626572206f662070616765732073686f756c64206e6f74206578636565642074686520636f6e66696775726564206d6178696d756d2e70726576696f75732f6e657874206f6e6c7920636f6e7461696e206578697374696e6720656e74697265733b20776520656e756d6572617465207573696e67206e6578743b20656e747279206578697374733b207165640004741100280000001c1a110044000000b8010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6e7472616374732f7372632f6c69622e72731c1a110044000000b8010000010000006e6577207363686564756c65206d7573742068617665206120677265617465722076657273696f6e207468616e2063757272656e74496e76616c69642073757263686172676520636c61696d3a206f726967696e206d757374206265207369676e6564206f7220696e686572656e7420616e6420617578696c696172792073656e646572206f6e6c792070726f7669646564206f6e20696e686572656e7443616e6e6f7420726573746f726520746f20696e6578697374696e67206f7220616c69766520636f6e7472616374c11b11000d000000a61b11001b0000002095110002000000641b110042000000e3010000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f6e6f64652f72756e74696d652f7372632f6c69622e727342616420696e70757420646174612070726f766964656420746f20657865637574655f626c6f636b0000d81b110010000000696e697469616c697a655f626c6f636bf01b11000f0000006170706c795f65787472696e73696300081c110013000000696e686572656e745f65787472696e7369637300241c11000f000000636865636b5f696e686572656e7473003c1c11001400000076616c69646174655f7472616e73616374696f6e581c11000f0000006f6666636861696e5f776f726b657200701c1100160000006772616e6470615f70656e64696e675f6368616e67650000901c1100150000006772616e6470615f666f726365645f6368616e6765000000b01c1100040000007369676ebc1c1100060000007665726966790000cc1c11000d0000006163636f756e745f6e6f6e6365000000e41c11001500000067656e65726174655f73657373696f6e5f6b65797300000000000000801d11000600000000000000881d1100010000000000000000000000901d1100010000000000000000000000981d11000500000000000000a01d1100020000000000000000000000b01d1100010000000000000000000000b81d11001a0000000000000038791100010000000000000000000000d41d1100020000000000000052657761726400008f1e110007000000961e110038000000536c617368000000861e1100090000008f1e1100070000003d1e1100490000004f6c64536c617368696e675265706f72744469736361726465640000e41d1100470000002b1e11001200000020416e206f6c6420736c617368696e67207265706f72742066726f6d2061207072696f72206572612077617320646973636172646564206265636175736520697420636f756c64206e6f742062652070726f6365737365642e204f6e652076616c696461746f722028616e6420697473206e6f6d696e61746f72732920686173206265656e20736c61736865642062792074686520676976656e20616d6f756e742e4163636f756e74496442616c616e636520416c6c2076616c696461746f72732068617665206265656e2072657761726465642062792074686520676976656e2062616c616e63652e5374616b696e672043757272656e74456c65637465645374616b696e6720426f6e6465645374616b696e672043757272656e7445726153746172745374616b696e67204e6f6d696e61746f72735374616b696e672056616c696461746f72735374616b696e67205374616b6572735374616b696e67204c65646765725374616b696e6720506179656568656164206f66205374616b696e67204e6f6d696e61746f72734c696e6b616765206973207570646174656420696e206361736520656e7472792069732072656d6f7665643b20697420616c7761797320706f696e747320746f206578697374696e67206b6579733b2071656468656164206f66205374616b696e672056616c696461746f72730000000000001c221100040000000000000020221100030000000000000000000000682211000f0000000000000000000000e02211000a00000000000000ec221100010000000000000000000000042311000e00000000000000000000007423110006000000000000007c231100010000000000000000000000942311001700000000000000000000004c24110011000000000000006480110000000000000000000000000060241100100000000000000000000000e02411000800000000000000e8241100010000000000000000000000002511000b000000000000000000000058251100080000000000000060251100010000000000000000000000782511000b0000000000000000000000d0251100050000000000000064801100000000000000000000000000d82511000b00000000000000000000003026110009000000000000003c261100010000000000000000000000542611000b0000000000000000000000ac2611000e00000000000000bc261100010000000000000000000000d42611000b00000000000000000000002c27110013000000000000004027110001000000000000000000000058271100010000000000000000000000602711000d000000000000006480110000000000000000000000000070271100050000000000000000000000982711000d0000000000000064801100000000000000000000000000a8271100060000000000000000000000d82711001100000000000000ec271100010000000000000000000000042811000100000000000000626f6e6400000000992a11000a00000000000000a32a110023000000000000000f3311000500000000000000143311001500000000000000492b110005000000000000004e2b1100110000006534110059000000be341100210000006480110000000000df34110054000000648011000000000033351100490000006480110000000000d52811000b0000007c351100350000004f34110008000000b13511001a0000006480110000000000cb3511005b0000002636110049000000f02811000c000000626f6e645f6578747261000000000000573411000e0000000000000014331100150000002933110059000000823311000d00000064801100000000008f33110054000000e3331100590000003c341100130000006480110000000000b2291100550000006480110000000000d52811000b000000072a11003a0000004f34110008000000f532110010000000f02811000c000000756e626f6e640000000000000f33110005000000000000001433110015000000202f110055000000752f110040000000b52f11004d0000006480110000000000023011005200000054301100300000006480110000000000843011004f000000d33011004f000000223111003f0000006480110000000000f42a110055000000648011000000000061311100260000006480110000000000d52811000b0000008731110050000000412a110026000000d731110059000000303211005c0000008c32110069000000f532110010000000053311000a00000077697468647261775f756e626f6e646564000000192d11004b0000006480110000000000642d11004d000000b12d1100130000006480110000000000f42a1100550000006480110000000000c42d11001b0000006480110000000000d52811000b000000df2d110055000000342e110051000000852e11003d000000c22e11005e000000672a110032000000f02811000c00000076616c696461746500000000f82c11000500000000000000fd2c11001c000000be2c11003a00000064801100000000007b291100370000006480110000000000f42a1100550000006480110000000000d52811000b000000072a11003a000000412a110026000000672a110032000000f02811000c0000006e6f6d696e617465000000008f2c11000700000000000000962c110028000000a62b11004400000064801100000000007b291100370000006480110000000000f42a1100550000006480110000000000d52811000b000000ea2b110049000000332c110026000000592c110036000000f02811000c0000006368696c6c0000005f2b11003200000064801100000000007b291100370000006480110000000000f42a1100550000006480110000000000d52811000b000000072a11003a000000912b110015000000672a110032000000f02811000c0000007365745f706179656500000000000000492b110005000000000000004e2b110011000000c62a11002e00000064801100000000007b291100370000006480110000000000f42a1100550000006480110000000000d52811000b000000072a11003a000000412a110026000000672a110032000000f02811000c0000007365745f636f6e74726f6c6c6572000000000000992a11000a00000000000000a32a110023000000572911002400000064801100000000007b291100370000006480110000000000b2291100550000006480110000000000d52811000b000000072a11003a000000412a110026000000672a110032000000f02811000c0000007365745f76616c696461746f725f636f756e7400000000004829110003000000000000004b2911000c0000002829110020000000666f7263655f6e6f5f65726173000000fc2811002c0000006480110000000000d52811000b000000e028110010000000f02811000c000000666f7263655f6e65775f6572610000005a28110053000000ad281100280000006480110000000000d52811000b000000e028110010000000f02811000c0000007365745f696e76756c6e657261626c6573000000000000003f2811000a0000000000000049281100110000000c2811003300000020536574207468652076616c696461746f72732077686f2063616e6e6f7420626520736c61736865642028696620616e79292e76616c696461746f72735665633c543a3a4163636f756e7449643e20466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f6620746865206e6578742073657373696f6e2e20416674657220746869732c2069742077696c6c20626520726573657420746f206e6f726d616c20286e6f6e2d666f7263656429206265686176696f75722e2023203c7765696768743e202d204e6f20617267756d656e74732e2023203c2f7765696768743e20466f72636520746865726520746f206265206e6f206e6577206572617320696e646566696e6974656c792e2054686520696465616c206e756d626572206f662076616c696461746f72732e6e6577436f6d706163743c7533323e202852652d297365742074686520636f6e74726f6c6c6572206f6620612073746173682e20456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c65722e202d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732e202d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e636f6e74726f6c6c65723c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f75726365202852652d2973657420746865207061796d656e742074617267657420666f72206120636f6e74726f6c6c65722e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e706179656552657761726444657374696e6174696f6e204465636c617265206e6f2064657369726520746f206569746865722076616c6964617465206f72206e6f6d696e6174652e202d20436f6e7461696e73206f6e6520726561642e204465636c617265207468652064657369726520746f206e6f6d696e6174652060746172676574736020666f7220746865206f726967696e20636f6e74726f6c6c65722e202d20546865207472616e73616374696f6e277320636f6d706c65786974792069732070726f706f7274696f6e616c20746f207468652073697a65206f66206074617267657473602c2077686963682069732063617070656420617420604d41585f4e4f4d494e4154494f4e53602e202d20426f74682074686520726561647320616e642077726974657320666f6c6c6f7720612073696d696c6172207061747465726e2e746172676574735665633c3c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263653e204465636c617265207468652064657369726520746f2076616c696461746520666f7220746865206f726967696e20636f6e74726f6c6c65722e707265667356616c696461746f7250726566733c42616c616e63654f663c543e3e2052656d6f766520616e7920756e6c6f636b6564206368756e6b732066726f6d207468652060756e6c6f636b696e67602071756575652066726f6d206f7572206d616e6167656d656e742e205468697320657373656e7469616c6c7920667265657320757020746861742062616c616e636520746f206265207573656420627920746865207374617368206163636f756e7420746f20646f2077686174657665722069742077616e74732e2053656520616c736f205b6043616c6c3a3a756e626f6e64605d2e202d20436f756c6420626520646570656e64656e74206f6e2074686520606f726967696e6020617267756d656e7420616e6420686f77206d7563682060756e6c6f636b696e6760206368756e6b732065786973742e2020497420696d706c6965732060636f6e736f6c69646174655f756e6c6f636b656460207768696368206c6f6f7073206f76657220604c65646765722e756e6c6f636b696e67602c2077686963682069732020696e6469726563746c7920757365722d636f6e74726f6c6c65642e20536565205b60756e626f6e64605d20666f72206d6f72652064657461696c2e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732c20796574207468652073697a65206f6620776869636820636f756c64206265206c61726765206261736564206f6e20606c6564676572602e205363686564756c65206120706f7274696f6e206f662074686520737461736820746f20626520756e6c6f636b656420726561647920666f72207472616e73666572206f75742061667465722074686520626f6e6420706572696f6420656e64732e2049662074686973206c656176657320616e20616d6f756e74206163746976656c7920626f6e646564206c657373207468616e20543a3a43757272656e63793a3a6578697374656e7469616c5f6465706f73697428292c207468656e20697420697320696e6372656173656420746f207468652066756c6c20616d6f756e742e204f6e63652074686520756e6c6f636b20706572696f6420697320646f6e652c20796f752063616e2063616c6c206077697468647261775f756e626f6e6465646020746f2061637475616c6c79206d6f7665207468652066756e6473206f7574206f66206d616e6167656d656e7420726561647920666f72207472616e736665722e204e6f206d6f7265207468616e2061206c696d69746564206e756d626572206f6620756e6c6f636b696e67206368756e6b73202873656520604d41585f554e4c4f434b494e475f4348554e4b5360292063616e20636f2d657869737473206174207468652073616d652074696d652e20496e207468617420636173652c205b6043616c6c3a3a77697468647261775f756e626f6e646564605d206e65656420746f2062652063616c6c656420666972737420746f2072656d6f766520736f6d65206f6620746865206368756e6b732028696620706f737369626c65292e2053656520616c736f205b6043616c6c3a3a77697468647261775f756e626f6e646564605d2e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204c696d697465642062757420706f74656e7469616c6c79206578706c6f697461626c6520636f6d706c65786974792e202d20456163682063616c6c20287265717569726573207468652072656d61696e646572206f662074686520626f6e6465642062616c616e636520746f2062652061626f766520606d696e696d756d5f62616c616e6365602920202077696c6c2063617573652061206e657720656e74727920746f20626520696e73657274656420696e746f206120766563746f722028604c65646765722e756e6c6f636b696e676029206b65707420696e2073746f726167652e202020546865206f6e6c792077617920746f20636c65616e207468652061666f72656d656e74696f6e65642073746f72616765206974656d20697320616c736f20757365722d636f6e74726f6c6c656420766961206077697468647261775f756e626f6e646564602e202d204f6e6520444220656e7472792e203c2f7765696768743e76616c7565436f6d706163743c42616c616e63654f663c543e3e2041646420736f6d6520657874726120616d6f756e742074686174206861766520617070656172656420696e207468652073746173682060667265655f62616c616e63656020696e746f207468652062616c616e636520757020666f72207374616b696e672e20557365207468697320696620746865726520617265206164646974696f6e616c2066756e647320696e20796f7572207374617368206163636f756e74207468617420796f75207769736820746f20626f6e642e20556e6c696b65205b60626f6e64605d206f72205b60756e626f6e64605d20746869732066756e6374696f6e20646f6573206e6f7420696d706f736520616e79206c696d69746174696f6e206f6e2074686520616d6f756e7420746861742063616e2062652061646465642e202d204f2831292e6d61785f6164646974696f6e616c2054616b6520746865206f726967696e206163636f756e74206173206120737461736820616e64206c6f636b207570206076616c756560206f66206974732062616c616e63652e2060636f6e74726f6c6c6572602077696c6c20626520746865206163636f756e74207468617420636f6e74726f6c732069742e206076616c756560206d757374206265206d6f7265207468616e2074686520606578697374656e7469616c5f6465706f7369746020646566696e656420696e207468652042616c616e636573206d6f64756c652e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20627920746865207374617368206163636f756e742e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204d6f64657261746520636f6d706c65786974792e202d20546872656520657874726120444220656e74726965732e204e4f54453a2054776f206f66207468652073746f726167652077726974657320286053656c663a3a626f6e646564602c206053656c663a3a7061796565602920617265205f6e657665725f20636c65616e656420756e6c6573732074686520606f726967696e602066616c6c732062656c6f77205f6578697374656e7469616c206465706f7369745f20616e6420676574732072656d6f76656420617320647573742e5374616b696e67000000000000003d11000e00000000000000000000000e3d11000300000000000000000000000000000000000000000000000000000000000000f8951100203f11000000000000000000143d1100010000000000000001000000000000001c3d11001500000000000000000000000e3d11000300000000000000000000000000000000000000000000000000000000000000f8951100343d11000000000000000000443d1100010000000000000001000000000000004c3d11000d0000000000000000000000492811001100000000000000000000000000000000000000000000000000000000000000f89511009c3e110000000000000000005c3d110003000000000000000100000000000000743d11000600000001010000000000007a3d11000c000000000000007a3d11000c00000000000000000000000000000000000000f8951100c03d11000000000000000000883d110001000000000000000000000000000000903d11000600000001010000000000007a3d11000c00000000000000963d11002900000000000000000000000000000000000000f8951100c03d11000000000000000000d03d110001000000000000000000000000000000d83d11000500000001010000000000007a3d11000c000000000000004e2b11001100000000000000000000000000000000000000f8951100e03d11000000000000000000f03d110001000000000000000100000000000000f83d11000a00000001010100000000007a3d11000c00000000000000fd2c11001c00000000000000000000000000000000000000f8951100043e11000000000000000000143e1100010000000000000001000000000000001c3e11000a00000001010100000000007a3d11000c00000000000000492811001100000000000000000000000000000000000000f89511009c3e11000000000000000000283e110001000000000000000100000000000000303e11000700000001010000000000007a3d11000c00000000000000373e11002400000000000000000000000000000000000000f89511005c3e110000000000000000006c3e1100040000000000000001000000000000008c3e11000e0000000000000000000000492811001100000000000000000000000000000000000000000000000000000000000000f89511009c3e11000000000000000000ac3e110001000000000000000100000000000000b43e11000a0000000000000000000000be3e11000800000000000000000000000000000000000000000000000000000000000000f8951100203f11000000000000000000c83e110001000000000000000100000000000000d03e11000f0000000000000000000000df3e11000b00000000000000000000000000000000000000000000000000000000000000f8951100ec3e11000000000000000000fc3e110001000000000000000100000000000000043f11001b0000000000000000000000c77911000c00000000000000000000000000000000000000000000000000000000000000f8951100203f11000000000000000000303f110001000000000000000100000000000000383f1100110000000000000000000000493f11000a00000000000000000000000000000000000000000000000000000000000000f8951100543f11000000000000000000643f1100010000000000000001000000000000006c3f1100090000000000000000000000753f11000c00000000000000000000000000000000000000000000000000000000000000f8951100843f11000000000000000000943f110003000000000000000100000000000000ac3f1100080000000000000000000000b43f11000700000000000000000000000000000000000000000000000000000000000000f8951100bc3f11000000000000000000cc3f110001000000000000000100000000000000d43f1100130000000000000000000000e73f11000700000000000000000000000000000000000000000000000000000000000000f8951100f03f110000000000000000000040110003000000000000000100000000000000184011000a0000000000000000000000224011001d00000000000000000000000000000000000000000000000000000000000000f89511008c40110000000000000000004040110001000000000000000100000000000000484011000f0000000101000000000000be3e11000800000000000000574011003200000000000000000000000000000000000000f89511008c40110000000000000000009c40110001000000000000000100000056616c696461746f72436f756e74753332000000964611002a0000004d696e696d756d56616c696461746f72436f756e74000000320000000000000001000000b90000004646110050000000496e76756c6e657261626c65730000007245110056000000c8451100530000001b4611002b000000426f6e646564543a3a4163636f756e744964000032451100400000004c65646765725374616b696e674c65646765723c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e0032000000000000000100000036000000e144110051000000506179656500000032000000000000000100000036000000a84411003900000056616c696461746f72730000320000000000000001000000ba00000057441100510000004e6f6d696e61746f72730000fe431100590000005374616b6572734578706f737572653c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e00320000000000000001000000bb000000414311005300000094431100460000006480110000000000da4311002400000043757272656e74456c6563746564000032000000000000000100000033000000024311003f00000043757272656e74457261457261496e6465780000eb4211001700000043757272656e7445726153746172744d6f6d656e744f663c543e00003200000000000000010000004f000000cd4211001e00000043757272656e74457261537461727453657373696f6e496e6465780032000000000000000100000035000000994211003400000043757272656e74457261526577617264734572615265776172647300320000000000000001000000bc0000005642110043000000536c6f745374616b6542616c616e63654f663c543e0000003200000000000000010000003d000000da4111004c00000064801100000000002642110030000000466f726365457261466f7263696e6700320000000000000001000000360000009341110047000000536c6173685265776172644672616374696f6e50657262696c6c0000320000000000000001000000bd0000001c4111003e00000064801100000000005a41110039000000426f6e646564457261735665633c28457261496e6465782c2053657373696f6e496e646578293e00d340110049000000457261536c6173684a6f75726e616c5665633c536c6173684a6f75726e616c456e7472793c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e3e00000032000000000000000100000033000000a44011002f00000020416c6c20736c617368657320746861742068617665206f6363757272656420696e206120676976656e206572612e2041206d617070696e672066726f6d207374696c6c2d626f6e646564206572617320746f207468652066697273742073657373696f6e20696e646578206f662074686174206572612e205468652070657263656e74616765206f662074686520736c617368207468617420697320646973747269627574656420746f207265706f72746572732e205468652072657374206f662074686520736c61736865642076616c75652069732068616e646c6564206279207468652060536c617368602e205472756520696620746865206e6578742073657373696f6e206368616e67652077696c6c2062652061206e657720657261207265676172646c657373206f6620696e6465782e2054686520616d6f756e74206f662062616c616e6365206163746976656c79206174207374616b6520666f7220656163682076616c696461746f7220736c6f742c2063757272656e746c792e2054686973206973207573656420746f20646572697665207265776172647320616e642070756e6973686d656e74732e205265776172647320666f72207468652063757272656e74206572612e205573696e6720696e6469636573206f662063757272656e7420656c6563746564207365742e205468652073657373696f6e20696e646578206174207768696368207468652063757272656e742065726120737461727465642e20546865207374617274206f66207468652063757272656e74206572612e205468652063757272656e742065726120696e6465782e205468652063757272656e746c7920656c65637465642076616c696461746f7220736574206b65796564206279207374617368206163636f756e742049442e204e6f6d696e61746f727320666f72206120706172746963756c6172206163636f756e74207468617420697320696e20616374696f6e207269676874206e6f772e20596f752063616e27742069746572617465207468726f7567682076616c696461746f727320686572652c2062757420796f752063616e2066696e64207468656d20696e207468652053657373696f6e206d6f64756c652e2054686973206973206b6579656420627920746865207374617368206163636f756e742e20546865206d61702066726f6d206e6f6d696e61746f72207374617368206b657920746f2074686520736574206f66207374617368206b657973206f6620616c6c2076616c696461746f727320746f206e6f6d696e6174652e20546865206d61702066726f6d202877616e6e616265292076616c696461746f72207374617368206b657920746f2074686520707265666572656e636573206f6620746861742076616c696461746f722e2057686572652074686520726577617264207061796d656e742073686f756c64206265206d6164652e204b657965642062792073746173682e204d61702066726f6d20616c6c2028756e6c6f636b6564292022636f6e74726f6c6c657222206163636f756e747320746f2074686520696e666f20726567617264696e6720746865207374616b696e672e204d61702066726f6d20616c6c206c6f636b65642022737461736822206163636f756e747320746f2074686520636f6e74726f6c6c6572206163636f756e742e20416e792076616c696461746f72732074686174206d6179206e6576657220626520736c6173686564206f7220666f726369626c79206b69636b65642e20497427732061205665632073696e63652074686579277265206561737920746f20696e697469616c697a6520616e642074686520706572666f726d616e636520686974206973206d696e696d616c2028776520657870656374206e6f206d6f7265207468616e20666f757220696e76756c6e657261626c65732920616e64207265737472696374656420746f20746573746e6574732e204d696e696d756d206e756d626572206f66207374616b696e67207061727469636970616e7473206265666f726520656d657267656e637920636f6e646974696f6e732061726520696d706f7365642e2054686520696465616c206e756d626572206f66207374616b696e67207061727469636970616e74732e00000000304711000e00000000000000c77911000c00000000000000f895110040471100000000000000000050471100010000000000000000000000584711000f00000000000000be3e11000800000000000000f895110068471100000000000000000078471100010000000000000053657373696f6e7350657245726100003200000000000000010000005c000000b94711001c000000426f6e64696e674475726174696f6e00320000000000000001000000be0000008047110039000000204e756d626572206f6620657261732074686174207374616b65642066756e6473206d7573742072656d61696e20626f6e64656420666f722e204e756d626572206f662073657373696f6e7320706572206572612e5374616b696e6720536c6f745374616b65000020491100190000004049110048000000bb0100002d0000005374616b696e6720457261536c6173684a6f75726e616c00bf0000002800000004000000c0000000c10000000000000000000000c200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f353231643738343037343731636237386539626266343731363066366161323330343761633439392f7372632f6c6962636f72652f6f70732f61726974682e72735374616b696e6720496e76756c6e657261626c65730000000474110028000000b849110042000000a6020000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f7374616b696e672f7372632f6c69622e72730000b849110042000000a602000001000000636f6e74726f6c6c657220616c72656164792070616972656463616e206e6f7420626f6e6420776974682076616c7565206c657373207468616e206d696e696d756d2062616c616e6365737461736820616c726561647920626f6e6465646e6f74206120636f6e74726f6c6c65726e6f74206120737461736863616e206e6f74207363686564756c65206d6f726520756e6c6f636b206368756e6b730a09090909090909096865616420697320736574207768656e20666972737420656c656d656e7420697320696e73657274656420616e6420756e736574207768656e206c61737420656c656d656e742069732072656d6f7665643b0a09090909090909096966206865616420697320536f6d65207468656e20697420706f696e747320746f206578697374696e67206b65793b207165640a09090909090909746172676574732063616e6e6f7420626520656d707479416c69766520636f6e7472616374206f7220746f6d6273746f6e6520616c726561647920657869737473626c6f636b2073697a65206c696d697420697320726561636865646f766572666c6f77206d756c7469706c79696e6720676173206c696d69742062792070726963654f6666656e636573205265706f7274730000004c110019000000204c110048000000bb0100002d000000000000000000000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f353231643738343037343731636237386539626266343731363066366161323330343761633439392f7372632f6c6962636f72652f6f70732f61726974682e7273616c726561647920626f72726f776564616c7265616479206d757461626c7920626f72726f776564320000000000000001000000c3000000320000000000000001000000c40000000474110028000000c84c11004300000055000000010000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f6f6666656e6365732f7372632f6c69622e727300144d11002a000000696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64653a200000484d1100230000005f5f5068616e746f6d4974656d2073686f756c64206e6576657220626520757365642e00c84c1100430000005500000001000000944d110033000000c74d11004b000000f600000005000000636f6e74726163742073756273797374656d20726573756c74696e6720696e20706f73697469766520696d62616c616e6365212f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f73726d6c2f636f6e7472616374732f7372632f6163636f756e745f64622e7273707265636f6e646974696f6e3a20616c6c20696d706f7274732073686f756c6420626520636865636b656420616761696e737420746865207369676e617475726573206f6620636f72726573706f6e64696e670a09090909090966756e6374696f6e7320646566696e65642062792060646566696e655f656e762160206d6163726f206279207468652075736572206f6620746865206d6163726f3b0a0909090909097369676e617475726573206f662074686573652066756e6374696f6e7320646566696e6564206279206024706172616d73603b0a09090909090963616c6c7320616c77617973206d616465207769746820617267756d656e7473207479706573206f662077686963682061726520646566696e65642062792074686520636f72726573706f6e64696e6720696d706f7274733b0a09090909090974687573207479706573206f6620617267756d656e74732073686f756c6420626520657175616c20746f2074797065206c69737420696e206024706172616d736020616e640a0909090909096c656e677468206f6620617267756d656e74206c69737420616e642024706172616d732073686f756c6420626520657175616c3b0a0909090909097468757320746869732063616e206e6576657220626520604e6f6e65603b0a0909090909097165643b0a09090909090953657373696f6e20486973746f726963616c53657373696f6e734f6666656e6365730000000030511100070000000101000000000000375111000d00000000000000445111003400000000000000000000000000000000000000f89511007851110000000000000000008851110001000000000000000000000000000000905111001600000002010100000000005b55110004000000000000005f5511000e00000000000000a65111001200000000000000f8951100b85111000000000000000000c851110001000000000000000100000000000000d05111001200000001010000000000005b5511000400000000000000e25111000700000000000000000000000000000000000000f8951100ec5111000000000000000000fc5111000600000000000000010000005265706f7274735265706f727449644f663c543e4f6666656e636544657461696c733c543a3a4163636f756e7449642c20543a3a4964656e74696669636174696f6e5475706c653e320000000000000001000000360000009553110052000000436f6e63757272656e745265706f727473496e6465785665633c5265706f727449644f663c543e3e320000000000000001000000330000004b5311004a0000005265706f72747342794b696e64496e6465785665633c75383e0000003200000000000000010000004e0000002c521100440000006480110000000000705211002f00000064801100000000009f52110052000000f15211005a00000020456e756d65726174657320616c6c207265706f727473206f662061206b696e6420616c6f6e672077697468207468652074696d6520746865792068617070656e65642e20416c6c207265706f7274732061726520736f72746564206279207468652074696d65206f66206f6666656e63652e204e6f74652074686174207468652061637475616c2074797065206f662074686973206d617070696e6720697320605665633c75383e602c207468697320697320626563617573652076616c756573206f6620646966666572656e7420747970657320617265206e6f7420737570706f7274656420617420746865206d6f6d656e7420736f2077652061726520646f696e6720746865206d616e75616c2073657269616c697a6174696f6e2e204120766563746f72206f66207265706f727473206f66207468652073616d65206b696e6420746861742068617070656e6564206174207468652073616d652074696d6520736c6f742e20546865207072696d61727920737472756374757265207468617420686f6c647320616c6c206f6666656e6365207265636f726473206b65796564206279207265706f7274206964656e746966696572732e72657475726e2074797065206572726f7276616c69646174696f6e206572726f72647572696e6720657865637574696f6e696d2d6f6e6c696e653a6f66666c696e4f6666656e63657320436f6e63757272656e745265706f727473496e6465784f6666656e636573205265706f72747342794b696e64496e64657800000000000090541100070000000000000098541100020000000000000000000000a854110002000000000000004f6666656e6365005b551100040000005f5511000e000000b8541100550000000d5511004e00000020546865726520697320616e206f6666656e6365207265706f72746564206f662074686520676976656e20606b696e64602068617070656e656420617420746865206073657373696f6e5f696e6465786020616e6420286b696e642d7370656369666963292074696d6520736c6f742e2054686973206576656e74206973206e6f74206465706f736974656420666f72206475706c696361746520736c61736865732e4b696e644f706171756554696d65536c6f7454726561737572792050726f706f73616c436f756e74547265617375727920417070726f76616c730000000000000001000000020000000400000008000000100000002000000044656d6f6372616379205075626c696350726f70436f756e7444656d6f6372616379205265666572656e64756d436f756e7444656d6f6372616379204e65787454616c6c7944656d6f6372616379204c6173745461626c656457617345787465726e616c3056110048000000a10a00000e00000000000000000000002f72757374632f353231643738343037343731636237386539626266343731363066366161323330343761633439392f7372632f6c6962636f72652f736c6963652f6d6f642e72735374616b696e672056616c696461746f72436f756e745374616b696e67204d696e696d756d56616c696461746f72436f756e745374616b696e672043757272656e744572615374616b696e672043757272656e74457261537461727453657373696f6e496e6465785374616b696e672043757272656e74457261526577617264735374616b696e6720466f7263654572615374616b696e6720536c6173685265776172644672616374696f6e5374616b696e6720426f6e64656445726173417574686f727368697020446964536574556e636c6573746f6f206d616e7920696e737472756374696f6e7300007c57110024000000757d1100170000004402000009000000547269656420746f20736872696e6b20746f2061206c61726765722063617061636974796578745f7365745f73746f726167656578745f6765745f73746f726167656578745f63616c6c6578745f6372656174656578745f72657475726e6578745f63616c6c65726578745f616464726573736578745f6761735f70726963656578745f6761735f6c6566746578745f62616c616e63656578745f76616c75655f7472616e736665727265646578745f72616e646f6d6578745f6e6f776578745f64697370617463685f63616c6c6578745f726573746f72655f746f6578745f736372617463685f73697a656578745f736372617463685f726561646578745f736372617463685f77726974656578745f6465706f7369745f6576656e746578745f7365745f72656e745f616c6c6f77616e63656578745f72656e745f616c6c6f77616e63656578745f7072696e746c6e6578745f626c6f636b5f6e756d626572436f6e7472616374204761735370656e74436f6e74726163742043757272656e745363686564756c65436f6e7472616374204163636f756e74436f756e7465724e6f6e2d656d7074792066756e6374696f6e20626f6479206578706563746564000000fe5911000f0000000d5a1100020000000f5a1100030000007059110030000000a05911005e0000007d00000005000000617373657274696f6e206661696c65643a20636f6e746578742e6672616d655f737461636b2e69735f656d70747928292f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7761736d692d76616c69646174696f6e2d302e312e302f7372632f66756e632e7273417420696e737472756374696f6e202840293a2052657475726e207479706573206c656e6774682073686f756c642062652030206f72203143616e2774206465636f6465207761736d20636f64654d6f64756c65206973206e6f742076616c69646d6f64756c65206465636c6172657320696e7465726e616c206d656d6f72796d756c7469706c65207461626c6573206465636c617265647461626c652065786365656473206d6178696d756d2073697a6520616c6c6f776564757365206f6620666c6f6174696e6720706f696e74207479706520696e2066756e6374696f6e20747970657320697320666f7262696464656e757365206f6620666c6f6174696e6720706f696e74207479706520696e206c6f63616c7320697320666f7262696464656e757365206f6620666c6f6174696e6720706f696e74207479706520696e20676c6f62616c7320697320666f7262696464656e67617320696e737472756d656e746174696f6e206661696c6564737461636b2068656967687420696e737472756d656e746174696f6e206661696c656463616c6c6465706c6f796465706c6f792066756e6374696f6e2069736e2774206578706f72746564756e6b6e6f776e206578706f72743a20657870656374696e67206f6e6c79206465706c6f7920616e642063616c6c2066756e6374696f6e7366756e6374696f6e206861732061206e6f6e2d6578697374656e7420747970656578706f72742072656665727320746f206e6f6e2d6578697374656e742066756e6374696f6e657870656374656420612066756e6374696f6e656e74727920706f696e7420706f696e747320746f20616e20696d706f727465642066756e6374696f6e656e74727920706f696e74206861732077726f6e67207369676e617475726563616c6c2066756e6374696f6e2069736e2774206578706f727465646572726f722073657269616c697a696e6720696e737472756d656e746564206d6f64756c658c5e11001e000000aa5e11001f00000066756e6374696f6e5f73656374696f6e5f6c656e20213d20303b2071656466756e6374696f6e5f73656374696f6e5f6c656e20213d20303b2066756e6374696f6e5f73656374696f6e5f6c656e203d3d20636f64655f73656374696f6e5f6c656e3b207165640000725e11001a0000004d5e11000a000000575e11001b00000073746172742066756e6374696f6e20657870656374656420746f20686176652074797065205b5d202d3e205b5d0000003c5e1100110000001c5e110020000000fc5d110020000000d45d1100280000007365676d656e74206f66667365742073686f756c642072657475726e20493332746f6f206d616e79206d656d6f727920726567696f6e7320696e20696e6465782073706163653a20746f6f206d616e79207461626c657320696e20696e6465782073706163653a20747279696e6720746f20696d706f7274206d757461626c6520676c6f62616c206475706c6963617465206578706f72742046756e6374696f6e20232072656164696e672f76616c69646174696f6e206572726f723a204d697373696e6720626f647920666f722066756e6374696f6e206c656e677468206f662066756e6374696f6e2073656374696f6e206973202c207768696c65206c656e206f6620636f64652073656374696f6e20697320000000e85e11001c000000045f11005a0000004d00000028000000ffffffff48617368207461626c65206361706163697479206f766572666c6f772f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f6861736862726f776e2d302e312e382f7372632f7261772f6d6f642e72736d616b655f746f705f6672616d655f706f6c796d6f72706869632069732063616c6c6564207769746820656d707479206672616d6520737461636b000000c50000000c00000004000000c6000000746869732066756e6374696f6e2063616e27742062652063616c6c6564207769746820656d707479206672616d6520737461636b4d6973706c6163656420656c736520696e737472756374696f6e000024611100470000006b61110005000000e8601100370000001f61110005000000b560110017000000ac60110009000000fe621100140000009460110018000000ac60110009000000fe62110014000000646011001d00000081601100130000004b95110001000000546f6f206c61726765206d656d6f727920616c69676e6d656e7420325e20286578706563746564206174206d6f737420547279696e6720746f2075706461746520676c6f62616c20206f66207479706520547279696e6720746f20757064617465206c6f63616c20416e79537065636966696300610000000400000004000000c70000004c6162656c7320696e2062725f7461626c6520706f696e747320746f20626c6f636b206f6620646966666572656e742074797065733a2020616e6420496620626c6f636b20776974686f757420656c736520726571756972656420746f2068617665204e6f526573756c7420626c6f636b20747970652e20427574206974206861732020747970658061110018000000986111000b000000556e657870656374656420737461636b20686569676874202c20657870656374656420547279696e6720746f2061636365737320706172656e74206672616d6520737461636b2076616c7565732e0000e061110017000000f76111001600000045787065637465642076616c7565206f66207479706520206f6e20746f70206f6620737461636b2e20476f74200000001862110007000000537461636b3a200000000100a26211002400000078621100060000007e6211000e0000008c62110016000000546211002400000078621100060000006d6178696d756d206d656d6f72792073697a65206d757374206265206174206d6f7374202070616765736d6178696d756d206c696d697420206973206c657373207468616e206d696e696d756d20696e697469616c206d656d6f72792073697a65206d757374206265206174206d6f7374200000d862110026000000fe62110014000000547279696e6720746f20696e697469616c697a65207661726961626c65206f6620747970652020776974682076616c7565206f66207479706520496e69742065787072657373696f6e2073686f756c6420616c776179732062652077697468206c656e67746820324e6f6e20636f6e7374616e74206f70636f646520696e20696e69742065787072a963110007000000bb63110022000000a963110007000000b06311000b00000045787072657373696f6e20646f65736e277420656e647320776974682060656e6460206f70636f6465476c6f62616c20206973206d757461626c6520646f65736e277420657869737473206f72206e6f742079657420646566696e6564000000f063110010000000006411000f0000004d656d6f727920617420696e6465782020646f65736e27742065786973747300206411000f000000006411000f0000005461626c6520617420696e6465782000d96b110012000000006411000f000000506411000e000000006411000f0000005479706520617420696e646578200000be64110010000000006411000f0000009064110010000000b06411000e0000009064110010000000a064110010000000457870656374656420676c6f62616c2020746f20626520696d6d757461626c6520746f206265206d757461626c65476c6f62616c20617420696e646578206e6f6e2d656d70747920737461636b2065787065637465640000f8641100200000001865110012000000747279696e6720746f206765742076616c756520617420706f736974696f6e20206f6e20737461636b206f662073697a6520636865636b656420636f75706c65206f66206c696e65732061626f7665005065110015000000657863656564656420737461636b206c696d697420000000610000000400000004000000c80000004c6f63616c732072616e6765206e6f7420696e2033322d6269742072616e6765b065110022000000d265110015000000e765110007000000547279696e6720746f20616363657373206c6f63616c207769746820696e64657820207768656e20746865726520617265206f6e6c7920206c6f63616c734672616d6569735f706f6c796d6f7270686963000000610000000400000004000000c9000000656e645f6172697479000000610000000400000004000000030000006272616e63685f617269747973746172745f6865696768744e6f2066756e6374696f6e2073656374696f6e4e6f20636f64652073656374696f6e4e6f20747970652073656374696f6e000000746911000a00000046756e6374696f6e206973206e6f7420666f756e6420696e2066756e632073656374696f6e46756e6374696f6e20626f647920666f722074686520696e6465782069736e277420666f756e64686911000c000000d06811000b000000737461636b206d757374206265206e6f6e2d656d70747900c56811000b0000007e68110006000000737461636b206f766572666c6f774172697479206f6620616c6c206a756d702d74617267657473206d75737420626520657175616c54797065206e6f7420666f756e64007768110007000000706711006c000000c8000000110000000000000000000000000000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e362e322f7372632f737461636b5f6865696768742f6d61785f6865696768742e72736d61785f686569676874707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768742f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e362e322f7372632f737461636b5f6865696768742f6d61785f6865696768742e72737472756e633a20707573683a20c068110005000000747279696e6720746f20706f70206d6f72652076616c756573207468616e20707573686564737461636b20756e646572666c6f77706f703a20756e726561636861626c65706f705f6672616d653a20636f6e74726f6c20737461636b20697320656d707479636f6e74726f6c20737461636b206f75742d6f662d626f756e647320691100480000009b0a00000a000000000000002f72757374632f353231643738343037343731636237386539626266343731363066366161323330343761633439392f7372632f6c6962636f72652f736c6963652f6d6f642e7273707573685f6672616d653a2066756e635f6964783a2066756e635f737461636b5f636f7374732069736e27742079657420636f6d70757465643b0a0909090944696420796f752063616c6c2060636f6d707574655f737461636b5f636f737473603f546869732073686f756c64206265206120696e646578206f66206120646566696e65642066756e6374696f6e44756520746f2076616c69646174696f6e20636f64652073656374696f6e2073686f756c642065786973747346756e6374696f6e20626f6479206973206f7574206f6620626f756e6473806a1100650000002301000017000000586a11002500000043616c6c20746f2066756e6374696f6e2074686174206f75742d6f662d626f756e64733a200000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e362e322f7372632f737461636b5f6865696768742f6d6f642e727366756e6374696f6e20696d706f727420636f756e74206973206e6f74207a65726f3b20696d706f72742073656374696f6e206d757374206578697374733b2071656466756e635f696478206973206c657373207468616e2066756e6374696f6e20696d706f72747320636f756e743b0a090909096e74682066756e6374696f6e20696d706f7274206d7573742062652060536f6d65603b0a09090909716564d96b110012000000eb6b11000f000000ac6b11000a000000b66b110014000000ca6b11000f0000005369676e61747572652020287370656369666965642062792066756e6320292069736e277420646566696e656446756e6374696f6e20617420696e64657820206973206e6f7420646566696e6564656e76676173106c11005800000088000000160000002f686f6d652f616e6472652f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e362e322f7372632f6761732e72737372632f6c6962616c6c6f632f7665632e727300946c11001c000000686c110013000000c704000009000000617373657274696f6e206661696c65643a20656e64203c3d206c656ec86c11001e000000686c110013000000b403000009000000617373657274696f6e206661696c65643a20696e646578203c3d206c656e0000610000000400000004000000ca000000bd6d110012000000cf6d11000c0000006066756e635f696478602073686f756c6420636f6d652066726f6d20606e6565645f7468756e6b73603b0a09090909606e6565645f7468756e6b736020697320706f70756c617465642077697468207468652073616d65206974656d73207468617420696e20607265706c6163656d656e745f6d6170603b0a090909097165644174207468697320706f696e7420616e20696e646578206d7573742062652061737369676e656420746f2065616368207468756e6b66756e6374696f6e207769746820696478202069736e277420666f756e644636345265696e74657270726574493634556e726561636861626c654e6f70426c6f636b00610000000400000004000000cb0000004c6f6f704966456c7365456e64427200610000000400000004000000030000004272496642725461626c6500610000000400000004000000cc00000052657475726e43616c6c43616c6c496e6469726563740000610000000400000004000000cd00000044726f7053656c6563744765744c6f63616c5365744c6f63616c5465654c6f63616c476574476c6f62616c536574476c6f62616c4933324c6f61644936344c6f61644633324c6f61644636344c6f61644933324c6f616438534933324c6f616438554933324c6f61643136534933324c6f61643136554936344c6f616438534936344c6f616438554936344c6f61643136534936344c6f61643136554936344c6f61643332534936344c6f616433325549333253746f726549363453746f726546333253746f726546363453746f726549333253746f72653849333253746f7265313649363453746f72653849363453746f7265313649363453746f7265333243757272656e744d656d6f727947726f774d656d6f7279493332436f6e737400610000000400000004000000ce000000493634436f6e7374610000000400000004000000cf000000463332436f6e7374463634436f6e73746100000004000000040000000600000049333245717a49333245714933324e654933324c74534933324c74554933324774534933324774554933324c65534933324c655549333247655349333247655549363445717a49363445714936344e654936344c74534936344c74554936344774534936344774554936344c65534936344c655549363447655349363447655546333245714633324e654633324c7446333247744633324c65463332476546363445714636344e654636344c7446363447744636344c654636344765493332436c7a49333243747a493332506f70636e744933324164644933325375624933324d756c493332446976534933324469765549333252656d5349333252656d55493332416e644933324f72493332586f7249333253686c4933325368725349333253687255493332526f746c493332526f7472493634436c7a49363443747a493634506f70636e744936344164644936345375624936344d756c493634446976534936344469765549363452656d5349363452656d55493634416e644936344f72493634586f7249363453686c4936345368725349363453687255493634526f746c493634526f74724633324162734633324e65674633324365696c463332466c6f6f724633325472756e634633324e656172657374463332537172744633324164644633325375624633324d756c4633324469764633324d696e4633324d6178463332436f70797369676e4636344162734636344e65674636344365696c463634466c6f6f724636345472756e634636344e656172657374463634537172744636344164644636345375624636344d756c4636344469764636344d696e4636344d6178463634436f70797369676e493332577261704936344933325472756e63534633324933325472756e63554633324933325472756e63534636344933325472756e6355463634493634457874656e6453493332493634457874656e64554933324936345472756e63534633324936345472756e63554633324936345472756e63534636344936345472756e6355463634463332436f6e7665727453493332463332436f6e7665727455493332463332436f6e7665727453493634463332436f6e766572745549363446333244656d6f7465463634463634436f6e7665727453493332463634436f6e7665727455493332463634436f6e7665727453493634463634436f6e766572745549363446363450726f6d6f74654633324933325265696e746572707265744633324936345265696e746572707265744636344633325265696e746572707265744933324e6f526573756c7456616c756500610000000400000004000000c7000000463634493332493634463332496e76616c696444617461547261696c696e6744617461556e6578706563746564456f66e07311000b000000492f4f204572726f723a200004741100280000002c741100500000008700000009000000696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64652f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d73616e64626f782f7372632f2e2e2f776974686f75745f7374642e727304741100280000002c7411005000000090000000090000004f6666636861696e206572726f723a207375626d697474696e67207472616e73616374696f6e206661696c6564214f6666636861696e206572726f723a206465636f64696e6720576f726b6572537461747573206661696c6564214f6666636861696e206572726f723a2065787472696e736963206372656174696f6e206661696c6564214f6666636861696e206572726f723a207369676e696e67206661696c6564214f6666636861696e206572726f723a206665746368696e67206e6574776f726b207374617465206661696c656421496d4f6e6c696e6520526563656976656448656172746265617473436f756e63696c20446573697265645365617473436f756e63696c20566f7465436f756e74436f756e63696c204e657874566f746572536574436f756e63696c20566f746572436f756e74436f756e63696c2043616e646964617465436f756e74000000000000687611000e000000000000007876110001000000000000000000000080761100010000000000000000000000887611000600000000000000648011000000000000000000000000009076110001000000000000000000000098761100070000000000000064801100000000000000000000000000a076110001000000000000004e6577417574686f72697469657300001b77110023000000f7761100240000005061757365640000d076110027000000526573756d656400a8761100280000002043757272656e7420617574686f726974792073657420686173206265656e20726573756d65642e2043757272656e7420617574686f726974792073657420686173206265656e207061757365642e204e657720617574686f726974792073657420686173206265656e206170706c6965642e5665633c28417574686f7269747949642c20417574686f72697479576569676874293e4772616e64706146696e616c69747920417574686f7269746965734772616e64706146696e616c6974792043757272656e7453657449644772616e64706146696e616c69747920536574496453657373696f6e54696d657374616d7020496e697469616c697a6564426162652045706f6368496e6465784261626520417574686f726974696573426162652045706f63685374617274536c6f74426162652043757272656e74536c6f7442616265205365636f6e64617279536c6f7473426162652050656e64696e675365636f6e64617279536c6f74734368616e6765426162652052616e646f6d6e65737342616265204e65787452616e646f6d6e65737342616265205365676d656e74496e6465784261626520556e646572436f6e737472756374696f6e4261626520496e697469616c697a656462616265736c6f74436f756c64206e6f74206465636f64652072657175657374656420696e686572656e742074797065214241424520696e686572656e742064617461206e6f7420666f756e6453657373696f6e2053746f72656452616e676553657373696f6e2043757272656e74496e64657853657373696f6e205175657565644368616e676564000000000000002c7911000a00000000000000387911000100000000000000000000004079110002000000000000004e657753657373696f6e0000c77911000c0000005079110055000000a579110022000000204e65772073657373696f6e206861732068617070656e65642e204e6f746520746861742074686520617267756d656e74206973207468652073657373696f6e20696e6465782c206e6f742074686520626c6f636b206e756d626572206173207468652074797065206d6967687420737567676573742e53657373696f6e496e64657800320000000000000001000000d0000000d1000000d2000000320000000000000001000000d0000000d1000000d200000074696d737461703054696d657374616d7020696e686572656e742064617461206973206e6f742070726f76696465642e496e76616c69642074696d657374616d7020696e686572656e74206461746120656e636f64696e672e54696d657374616d702044696455706461746500000000c87a1100100000000000000064801100000000000000000000000000d87a1100010000000000000000000000e07a11000f0000000000000064801100000000000000000000000000f07a1100010000000000000045787472696e736963537563636573730d7b11002500000045787472696e7369634661696c656400f87a11001500000020416e2065787472696e736963206661696c65642e20416e2065787472696e73696320636f6d706c65746564207375636365737366756c6c792e53797374656d2045787472696e736963436f756e7453797374656d20416c6c45787472696e7369637357656967687453797374656d20416c6c45787472696e736963734c656e53797374656d204e6578745765696768744d756c7469706c69657253797374656d2045787472696e7369634461746153797374656d204576656e74436f756e7448617368206e6f7420657175616c0000e07b110019000000007c1100500000005800000022000000617474656d707420746f20646976696465206279207a65726f000000000000002f686f6d652f616e6472652f576f726b62656e63682f706172697479746563682f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f67656e657269632f6572612e72736578745f6368696c645f73746f726167655f726f6f74206e657665722072657475726e73207533323a3a6d61785f76616c75653b2071656452756e74696d65206d656d6f7279206578686175737465642e2041626f7274696e670000c47c11002d000000f17c11000c000000fd7c110003000000617373657274696f6e206661696c65643a2060286c656674203d3d20726967687429600a20206c6566743a2060602c0a2072696768743a2060603a20087d11003400000064657374696e6174696f6e20616e6420736f7572636520736c69636573206861766520646966666572656e74206c656e6774687384801100180000005808000009000000647d110011000000757d110017000000f2020000050000006361706163697479206f766572666c6f777372632f6c6962616c6c6f632f7261775f7665632e7273007e1100460000006301000013000000610000000400000004000000d3000000d4000000d50000006120666f726d617474696e6720747261697420696d706c656d656e746174696f6e2072657475726e656420616e206572726f7200320000000000000001000000a700000000000000000000002f72757374632f353231643738343037343731636237386539626266343731363066366161323330343761633439392f7372632f6c6962636f72652f666d742f6d6f642e7273010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020202020202020202020202020202020202020202020202020202020203030303030303030303030303030303040404040400000000000000000000000000687f110020000000887f110012000000320000000000000001000000d6000000696e646578206f7574206f6620626f756e64733a20746865206c656e20697320206275742074686520696e64657820697320303030313032303330343035303630373038303931303131313231333134313531363137313831393230323132323233323432353236323732383239333033313332333333343335333633373338333934303431343234333434343534363437343834393530353135323533353435353536353735383539363036313632363336343635363636373638363937303731373237333734373537363737373837393830383138323833383438353836383738383839393039313932393339343935393639373938393900009c80110006000000a2801100220000008480110018000000170a0000050000007372632f6c6962636f72652f736c6963652f6d6f642e7273696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e67746820e480110016000000fa8011000d00000084801100180000001d0a000005000000736c69636520696e64657820737461727473206174202062757420656e6473206174206030785b2e2e2e5d00ce8111000b00000082941100160000000781110001000000b8811100160000000308000009000000609411000e0000006e9411000400000072941100100000000781110001000000b8811100160000000708000005000000209411002b0000004b941100150000007a01000015000000ce8111000b000000d981110026000000ff8111000800000007821100060000000781110001000000b88111001600000014080000050000007372632f6c6962636f72652f7374722f6d6f642e72736279746520696e64657820206973206e6f742061206368617220626f756e646172793b20697420697320696e7369646520202862797465732029206f6620600000005682110002000000408211001600000061040000110000004082110016000000550400002800000000000000000000007372632f6c6962636f72652f666d742f6d6f642e72732e2e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000f8030000000000000000000000000000000000000000000000000000000000000000feffffffffbfb6000000000000000000ff070000000000f8ffff0000010000000000000000000000c09f9f3d0000000002000000ffffff0700000000000000000000c0ff01000000000000f80f20008e11004a0000005090110000020000509211003a00000000010203040506070809080a0b0c0d0e0f10111213140215161718191a1b1c1d1e1f2002020202020202020202210202020202020202020202020202222324252602270228020202292a2b022c2d2e2f300202310202023202020202020202023302023402020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202023502360237020202020202020238023902020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202023a3b3c020202023d02023e3f4041424344454602020247020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202024802020202020202020202024902020202023b020001020202020302020202040205060202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020207020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020200010305050606030706080809110a1c0b190c140d120e0d0f0410031212130916011705180219031a071c021d011f1620032b042c022d0b2e01300331023201a702a902aa04ab08fa02fb05fd04fe03ff09ad78798b8da23057588b8c901c1ddd0e0f4b4cfbfc2e2f3f5c5d5fb5e2848d8e9192a9b1babbc5c6c9cadee4e5ff00041112293134373a3b3d494a5d848e92a9b1b4babbc6cacecfe4e500040d0e11122931343a3b4546494a5e646584919b9dc9cecf0d112945495764658d91a9b4babbc5c9dfe4e5f0040d1145496465808184b2bcbebfd5d7f0f183858ba4a6bebfc5c7cecfdadb4898bdcdc6cecf494e4f57595e5f898e8fb1b6b7bfc1c6c7d71116175b5cf6f7feff800d6d71dedf0e0f1f6e6f1c1d5f7d7eaeafbbbcfa16171e1f46474e4f585a5c5e7e7fb5c5d4d5dcf0f1f572738f747596972f5f262e2fa7afb7bfc7cfd7df9a409798308f1fc0c1ceff4e4f5a5b07080f10272feeef6e6f373d3f42459091feff536775c8c9d0d1d8d9e7feff00205f2282df048244081b04061181ac0e80ab351e1580e003190801042f043404070301070607110a500f1207550802041c0a090308030703020303030c0405030b06010e15053a0311070605100757070207150d500443032d03010411060f0c3a041d255f206d046a2580c80582b0031a0682fd035907150b1709140c140c6a060a061a0659072b05460a2c040c040103310b2c041a060b0380ac060a061f414c042d0374083c030f033c0738082b0582ff1118082f112d032010210f808c048297190b158894052f053b07020e180980b030740c80d61a0c0580ff0580b605240c9bc60ad23010848d033709815c1480b80880c73035040a06380846080c06740b1e035a0459098083181c0a16094808808a06aba40c170431a10481da26070c050580a511816d1078282a064c04808d0480be031b030f0d0006010103010402080809020a050b02100111041205131114021502170219041c051d0824016a036b02bc02d102d40cd509d602d702da01e005e102e802ee20f004f906fa020c273b3e4e4f8f9e9e9f060709363d3e56f3d0d104141836375657bd35cecfe01287898e9e040d0e11122931343a4546494a4e4f64655a5cb6b71b1ca8a9d8d909379091a8070a3b3e66698f926f5feeef5a629a9b2728559da0a1a3a4a7a8adbabcc4060b0c151d3a3f4551a6a7cccda007191a22253e3fc5c604202325262833383a484a4c50535556585a5c5e606365666b73787d7f8aa4aaafb0c0d00c72a3a4cbcc6e6f5e227b0503042d036504012f2e80821d03310f1c0424091e052b0544040e2a80aa06240424042808340b018090813709160a088098390363080930160521031b05014038044b052f040a070907402027040c0936033a051a07040c07504937330d33072e080a81261f808128082a808617094e041e0f430e19070a0647092709750b3f412a063b050a0651060105100305808b602048080a80a65e22450b0a060d1339070a362c041080c03c64530c0180a0451b4808531d398107460a1d03474937030e080a0639070a81361980c7320d839b66750b80c48abc842f8fd18247a1b98239072a040260260a460a28051382b05b654b0439071140041c97f80882f3a50d811f3103110408818c89046b050d03090710936080f60a73086e1746809a140c570919808781470385420f1585502b80d52d031a040281703a0501850080d7294c040a04028311444c3d80c23c06010455051b3402810e2c04640c560a0d035d033d391d0d2c040907020e06809a83d60a0d030b05740c59070c140c0438080a0628081e527703310380a60c14040305030d06856a000000e08d1100200000002700000019000000e08d1100200000002800000020000000e08d1100200000002a00000019000000e08d1100200000002b00000018000000e08d1100200000002c0000002000000000000000000000007372632f6c6962636f72652f756e69636f64652f626f6f6c5f747269652e72730000c0fbef3e00000000000e0000000000000000000000000000f8fffbffffff0700000000000014fe21fe000c00000002000000000000501e2080000c00004006000000000000108639020000002300be2100000c0000fc02000000000000d01e20c0000c0000000400000000000040012080000000000011000000000000c0c13d60000c0000000200000000000090443060000c00000003000000000000581e2080000c00000000845c8000000000000000000000f207807f000000000000000000000000f21f003f000000000000000000030000a002000000000000fe7fdfe0fffeffffff1f40000000000000000000000000e0fd66000000c301001e006420002000000000000000e00000000000001c0000001c0000000c0000000c00000000000000b03f40fe0f200000000000380000000000006000000000020000000000008701040e00008009000000000000407fe51ff89f000000000000ff7f0f0000000000f0170400000000f80f00030000003c3b00000000000040a303000000000000f0cf000000f7fffd211003fffffffffffffffb00100000000000000000ffffffff01000000000000800300000000000000008000000000ffffffff0000000000fc00000000000600000000000000000080f73f000000c0000000000000000000000300440800006000000030000000ffff038000000000c03f000080ff030000000000070000000000c833000000002000000000000000007e660008100000000000100000000000009dc1020000000030400000000000202100000000004000000000ffff0000ffff00000000000000000001000000020003000000000000000000000000000000000000000000000000000004000005000000000000000006000000000000000007000008090a000b0c0d0e0f000010111200001314151600001718191a1b001c0000001d0000000000001e1f202100000000002200230024252600000000270000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002829000000000000000000000000000000002a2b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000002d2e00002f0000000000000000000000000000000000000000000000000000000000003031320000000000000000000000000000000000000000003300000029000000000000340000000000000000000000000000000000000000000000350036000000000000000000000000000000000000000000000000000037380000383838390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000001000000000000000000c0076ef0000000000087000000006000000000000000f0000000c0ff01000000000002000000000000ff7f0000000000008003000000000078060700000080ef1f000000000000000800030000000000c07f001e000000000000000000000080d34000000080f8070000030000000000005801008000c01f1f0000000000000000ff5c00004000000000000000000000f9a50d000000000000000000000000803cb00100003000000000000000000000f8a70100000000000000000000000028bf00000000e0bc0f0000000000000080ff060000f00c01000000fe0700000000f87980007e0e0000000000fc7f03000000000000000000007fbf0000fcfffffc6d000000000000007eb4bf000000000000000000a3000000000000000000000018000000000000001f000000000000007f0000800000000000000080070000000000000000600000000000000000a0c307f8e70f0000003c00001c00000000000000ffffffffffff7ff8ffffffffff1f2000100000f8feff00007ffffff9db0700000000000000f0000000007f0000000000f00700000000000000000000ffffffffffffffffffffffffffffffffffff000063616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c75657372632f6c6962636f72652f6f7074696f6e2e7273626567696e203c3d20656e642028203c3d2029207768656e20736c6963696e672060206973206f7574206f6620626f756e6473206f66206066616c736574727565426f72726f774572726f72426f72726f774d75744572726f7270616e69636b6564206174200000f194110001000000f2941100030000006480110000000000f094110001000000f0941100010000003a27272c2000000064801100000000004b941100150000008e04000005000000648011000000000020951100020000003a20000034951100150000003c040000050000007372632f6c6962636f72652f726573756c742e72735b5d290a000000d70000000c00000004000000d8000000d9000000da0000002c0a2c20610000000400000004000000db000000dc000000dd00000020202020207b20207b0a207d7d28280a2c000000610000000400000004000000de000000610000000400000004000000df0000004e6f6e65536f6d65557466384572726f7276616c69645f75705f746f6572726f725f6c656e000000610000000400000004000000e00000004572726f720041f8abc6000b080000000000000000008fc003046e616d650186c003a405000e6578745f626c616b65325f323536011f6578745f6765745f616c6c6f63617465645f6368696c645f73746f7261676502176578745f636c6561725f6368696c645f73746f72616765030c6578745f74776f785f31323804116578745f636c6561725f73746f72616765050f6578745f7365745f73746f7261676506196578745f6765745f616c6c6f63617465645f73746f7261676507146578745f6765745f73746f726167655f696e746f08166578745f6b696c6c5f6368696c645f73746f72616765090e6578745f7072696e745f757466380a166578745f6368696c645f73746f726167655f726f6f740b236578745f626c616b65325f3235365f656e756d6572617465645f747269655f726f6f740c166578745f73616e64626f785f6d656d6f72795f6e65770d1b6578745f73616e64626f785f6d656d6f72795f74656172646f776e0e176578745f73616e64626f785f696e7374616e74696174650f126578745f73616e64626f785f696e766f6b65101d6578745f73616e64626f785f696e7374616e63655f74656172646f776e11126578745f737232353531395f76657269667912106578745f636c6561725f70726566697813106578745f73746f726167655f726f6f7414186578745f73746f726167655f6368616e6765735f726f6f7415126578745f656432353531395f76657269667916156578745f7365745f6368696c645f73746f72616765170d6578745f7072696e745f68657818106578745f69735f76616c696461746f7219156578745f6c6f63616c5f73746f726167655f6765741a216578745f6c6f63616c5f73746f726167655f636f6d706172655f616e645f7365741b116578745f6e6574776f726b5f73746174651c106578745f737232353531395f7369676e1d166578745f7375626d69745f7472616e73616374696f6e1e156578745f6c6f63616c5f73746f726167655f7365741f146578745f656432353531395f67656e657261746520146578745f737232353531395f67656e657261746521166578745f73616e64626f785f6d656d6f72795f67657422166578745f73616e64626f785f6d656d6f72795f73657423176578745f737232353531395f7075626c69635f6b657973240b6578745f74776f785f3634250a6578745f6d616c6c6f6326086578745f6672656527693c636f72653a3a697465723a3a61646170746572733a3a46696c7465724d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6834303430326438643933623061623231284b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6831326266373838623139663436343738290e5f5f727573745f6465616c6c6f632a30636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68646533343366643835666262636437382b7d7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72202851302c205230293e3a3a6465636f64653a3a68313861623562316237656662343132382c6b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68333331313037393737666239333938622d135f5f727573745f616c6c6f635f7a65726f65642e08727573745f6f6f6d2f48616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a616c6c6f636174655f696e3a3a7b7b636c6f737572657d7d3a3a68303238393136633161663461343735643036636f72653a3a736c6963653a3a736c6963655f696e6465785f6f726465725f6661696c3a3a686663656438386438386134396537363731543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6863303130383735366466666163366262320c5f5f727573745f616c6c6f633334616c6c6f633a3a7261775f7665633a3a63617061636974795f6f766572666c6f773a3a6835323966363538316535353336383065340e5f5f727573745f7265616c6c6f63352d616c6c6f633a3a7665633a3a5665633c543e3a3a72657461696e3a3a68316533613832356132363939666435383636636f72653a3a70616e69636b696e673a3a70616e69635f626f756e64735f636865636b3a3a686264626338353139646439353734353437443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a683238363630643833313633316566356638443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a683265386162623537373630353834353339443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68633939303331613636636136656164663a463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a68333737366130313266333631663637383b4b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a68663630666639303961616463613166653c543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68313331363439363538373332303932363d543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68313835633565303434393530363165363e543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68383837366664623066303535303730363f543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683839373936326530363433316264366240543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a686235396335333166313639616530356341543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a686239363639666237353764333264336142753c73725f7072696d6974697665733a3a67656e657269633a3a6865616465723a3a4865616465723c4e756d6265722c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a686131313664386630353864363563393943543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6863363230366338613934643538393638449f013c73725f7072696d6974697665733a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683664366431373662623366623663323045693c636f72653a3a697465723a3a61646170746572733a3a46696c7465724d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a68626638353430343538303264303131384668636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4d75743c413e20666f7220266d757420463e3a3a63616c6c5f6d75743a3a683166363230643861373864333735643847513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a683035343231633566623939653136646348513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a683737333662633330353130663062333149513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a68623637643838646638616234353965654a3d73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f65787465726e616c3a3a68666330626330653461336566353538344b3773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68396533333262326666633135353032634c4073726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6576656e745f696e64657865643a3a68323439666533386236303636303065394d3f73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a696e6a6563745f7265666572656e64756d3a3a68313638336161313937646536613838394e3b73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f7075626c69633a3a68313235383165333761633865363639324f7f6e6f64655f72756e74696d653a3a5f494d504c5f4445434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72206e6f64655f72756e74696d653a3a43616c6c3e3a3a6465636f64653a3a6834343339396563393231663734366636503873726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6465706f7369745f6f663a3a686334613865346130373866316539663551437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830316533333466306434653432653537523773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6839336436636365353964666635626335538c013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a756e726573657276653a3a6836323966383164313266626163323064542e636f72653a3a726573756c743a3a756e777261705f6661696c65643a3a6838666535316237643264396531613466553873726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a766f746572735f666f723a3a6832326137353533613233386462363739563573726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a766f74655f6f663a3a68393939393666646262353932663132655780017061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72202851302c205230293e3a3a656e636f64655f746f3a3a6831393461626234646364643061663061583d73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a64656c6567617465645f766f7465733a3a6834343134643334626232353432636134593773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68396231373437626363333266643961365a80023c73726d6c5f64656d6f63726163793a3a5f5f6c696e6b65645f6d61705f64657461696c735f666f725f64656c65676174696f6e735f646f5f6e6f745f7573653a3a456e756d657261746f723c532c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c28283c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c2073726d6c5f64656d6f63726163793a3a436f6e76696374696f6e292c2054293e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a68353436666662393362613963626364385b86013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a746f74616c5f62616c616e63653a3a68343336363631333463313166356234365c3e73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a636c6561725f7265666572656e64756d3a3a68323235616164356230653135653933335d3573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a6765743a3a68613830633538343966353865393038635e3d73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a7265666572656e64756d5f696e666f3a3a68306531393565643634623265613264325f82016e6f64655f72756e74696d653a3a5f494d504c5f454e434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206e6f64655f72756e74696d653a3a43616c6c3e3a3a656e636f64655f746f3a3a6865316562343962343966646162386333603c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6832386535336463366639313432386135613e73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6862303166646165326233616636613730626c3c73726d6c5f64656d6f63726163793a3a5f5f47657442797465537472756374426c61636b6c6973743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834353561316666653966663061323665636f3c73726d6c5f64656d6f63726163793a3a5f5f476574427974655374727563744e65787445787465726e616c3c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835313661653236386136313436366663646e3c73726d6c5f64656d6f63726163793a3a5f5f4765744279746553747275637444656c65676174696f6e733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a686437666465363561366666386566636165703c73726d6c5f64656d6f63726163793a3a5f5f47657442797465537472756374446973706174636851756575653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832313763343166363634653333613236666c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6831353838636265333766613462383632674773726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68373463663064636530376335613939386897013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4c61756e6368506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a683863396438623664313664613339633469a0013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a456d657267656e6379566f74696e67506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68343839396339616336656535373431656a99013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d4465706f73697444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68393330666665353162336235653966646b9a013c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a456e6163746d656e74506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68636662336539653336303562326365336c493c73726d6c5f64656d6f63726163793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68623831383532663531626238613566366d29636f72653a3a70616e69636b696e673a3a70616e69633a3a68616130643137343433666634343138656e443c6e6f64655f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68313433396433623835383934663961616f473c73726d6c5f696e64696365733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6838346539626661303330613733616265704a3c73726d6c5f62616c616e6365733a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a683735646466383939396665313066336271473c73726d6c5f7374616b696e673a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6835343838643161663965326262353137724c3c73726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a683233333930336634643932353861333173493c73726d6c5f656c656374696f6e733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6830343534626466623261363934623366744c3c73726d6c5f6d656d626572736869703a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a686261303261346666333761363666313675493c73726d6c5f636f6e7472616374733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a683662613530353033336134623062653276443c6e6f64655f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a683134333964336238353839346639616177493c73726d6c5f696d5f6f6e6c696e653a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a683133326362636234373137643639343078533c73726d6c5f617574686f726974795f646973636f766572793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a686362643537326434383333653330346179483c73726d6c5f6f6666656e6365733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68363164353730366534306534313361387a463c73726d6c5f73797374656d3a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68626438343533383136313231306432317b5d3c73726d6c5f64656d6f63726163793a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68326437383235646437666334373438397c323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68313330353630393638333231353764647d2d636f72653a3a70616e69636b696e673a3a70616e69635f666d743a3a68633732626433666639663862323165667e8a013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a726573657276653a3a68663239613031393232616631626533317f483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a68663132336632663765636563333839668001497061726974795f7363616c655f636f6465633a3a656e636f64655f617070656e643a3a657874726163745f6c656e6774685f646174613a3a68633465633662636666306265336665648101a8017375627374726174655f7072696d6974697665733a3a737232353531393a3a5f494d504c5f454e434f44455f464f525f5075626c69633a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72207375627374726174655f7072696d6974697665733a3a737232353531393a3a5075626c69633e3a3a656e636f64655f746f3a3a68356665373234613430363333393034308201703c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a683539613561396662653062613037386583013573726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3a3a646f5f766f74653a3a68346431633931613832343065343537348401b5013c73726d6c5f64656d6f63726163793a3a50726f78793c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6765743a3a68336161396463323966303764393034338501437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68643239396334373935643834656161378601ef013c73726d6c5f64656d6f63726163793a3a426c61636b6c6973743c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a486173682c283c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265722c20616c6c6f633a3a7665633a3a5665633c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e293e3e3a3a6765743a3a683238653736363139616435666436616487013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683536306634346232373166653439353388013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a68636564333739643432346338323565318901437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68633064343737326463646263353738318a01463c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68626532383036336664663231656531388b013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68343038373536633263306635353236638c01bb0173726d6c5f7374616b696e673a3a5f494d504c5f454e434f44455f464f525f5f5f4c696e6b616765466f724e6f6d696e61746f7273446f4e6f745573653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f7374616b696e673a3a5f5f4c696e6b616765466f724e6f6d696e61746f7273446f4e6f745573653c4b65793e3e3a3a656e636f64655f746f3a3a68346634396136323864343336326563388d018c013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a657874656e645f6c6f636b3a3a68613539316166383065363637383430638e01437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68383662383363316561323736333761618f0134636f72653a3a736c6963653a3a736c6963655f696e6465785f6c656e5f6661696c3a3a68313631313338646434626437633733369001443c636f72653a3a666d743a3a417267756d656e747320617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68343838663662363332623937663365349101303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683162336436343563356635333964613792012e636f72653a3a6f7074696f6e3a3a6578706563745f6661696c65643a3a6861666537356436376530633536663635930189013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7365745f6c6f636b3a3a68343764303164633831346161336432629401483c5b545d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68666137383665303263616636653264619501437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a683635623437396430626463306465386496016b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7536343e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a686461333434373364643037393361616697016c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68623832653761306464313335373437309801713c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68336635353635333065666139663963629901713c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c7536343e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68303834313961353633303231666666369a01303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68353635303932346161666434383930619b01723c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68623233653938396566373436616339359c01303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68383664663832326465313534633638619d01723c73725f7072696d6974697665733a3a67656e657269633a3a6469676573743a3a4469676573744974656d3c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a68336139393062643631396536366630389e01783c73726d6c5f696e64696365733a3a616464726573733a3a416464726573733c4163636f756e7449642c4163636f756e74496e6465783e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68336435653966306363656265313639659f017b3c73726d6c5f696e64696365733a3a616464726573733a3a416464726573733c4163636f756e7449642c4163636f756e74496e6465783e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6861663563623762333131383136666339a00189013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6465706f7369745f6372656174696e673a3a6838323431663535336163386634346339a1013573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a6765743a3a6834316662653539663562313033336163a2018d013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6d616b655f667265655f62616c616e63655f62653a3a6834383337343961613962636533633064a3013573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a6765743a3a6832383434373438643132323634366439a4017f3c73726d6c5f696e64696365733a3a4d6f64756c653c543e2061732073726d6c5f73797374656d3a3a4f6e4e65774163636f756e743c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6f6e5f6e65775f6163636f756e743a3a6865363933666663643034336665636366a5013f73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a7365745f667265655f62616c616e63653a3a6861373632643130333361353437393432a6013873726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a74616b653a3a6839656466393130616536316262643436a7013673726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6b696c6c5f73746173683a3a6836343136616134393933363861323730a8013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6865323464383863613663666236363365a901d5013c73726d6c5f73657373696f6e3a3a4e6578744b6579733c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a67656e657261746f723a3a53746f72616765446f75626c654d61703c616c6c6f633a3a7665633a3a5665633c75383e2c3c542061732073726d6c5f73657373696f6e3a3a54726169743e3a3a56616c696461746f7249642c3c542061732073726d6c5f73657373696f6e3a3a54726169743e3a3a4b6579733e3e3a3a6b65795f666f723a3a6839336564343964643439373036306639aa018d016e6f64655f72756e74696d653a3a5f494d504c5f4445434f44455f464f525f53657373696f6e4b6579733a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72206e6f64655f72756e74696d653a3a53657373696f6e4b6579733e3a3a6465636f64653a3a6837656434353338333166353532393235ab01f3013c73726d6c5f73657373696f6e3a3a4b65794f776e65723c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a67656e657261746f723a3a53746f72616765446f75626c654d61703c616c6c6f633a3a7665633a3a5665633c75383e2c287375627374726174655f7072696d6974697665733a3a63727970746f3a3a4b65795479706549642c20616c6c6f633a3a7665633a3a5665633c75383e292c3c542061732073726d6c5f73657373696f6e3a3a54726169743e3a3a56616c696461746f7249643e3e3a3a6b65795f666f723a3a6838356662366233353934326130623465ac01483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a72656d6f76653a3a6833306264386231616437656233333538ad0181013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a77697468647261773a3a6839346435366435643037323932346365ae018c013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a656e737572655f63616e5f77697468647261773a3a6834376134626538646166373163363864af013e73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a76657374696e675f62616c616e63653a3a6832646566383934376665303766623034b0013473726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6c6f636b733a3a6864663662353437383563386466663333b101483c5b543b205f5d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6833323464333833663137393837636236b201653c73726d6c5f62616c616e6365733a3a54616b65466565733c542c493e2061732073725f7072696d6974697665733a3a7472616974733a3a5369676e6564457874656e73696f6e3e3a3a76616c69646174653a3a6835323633653039323937613964396338b3013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830323332643265373037306334313039b4014b73725f7072696d6974697665733a3a7472616974733a3a4163636f756e744964436f6e76657273696f6e3a3a696e746f5f6163636f756e743a3a6834313836663836353337353363346665b5013573726d6c5f617574686f72736869703a3a4d6f64756c653c543e3a3a617574686f723a3a6836643136656531343735653630653761b6014e73725f7072696d6974697665733a3a67656e657269633a3a6469676573743a3a4469676573743c486173683e3a3a636f6e766572745f66697273743a3a6839643431313062313433363565303633b7014b73725f7072696d6974697665733a3a67656e657269633a3a6469676573743a3a4469676573744974656d3c486173683e3a3a7472795f746f3a3a6838313263333439613738666666343830b801437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6864626261376237663638383630626536b9013d73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6838383538376133343439313233313539ba013f73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6861386632626137383063366238373266bb016f3c73726d6c5f62616c616e6365733a3a5f5f476574427974655374727563744672656542616c616e63653c542c493e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830343565333532316261636636376330bc014373726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a7365745f72657365727665645f62616c616e63653a3a6837616137356264383861333465643131bd014873726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6836366133633666323732353337363234be0185013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a667265655f62616c616e63653a3a6865306566646366333734373138666430bf018e013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6465706f7369745f696e746f5f6578697374696e673a3a6837666532663932666232383430326233c0017e3c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a736c6173683a3a6863366164336264396166363561383065c101483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a6833633639313966346364636230633638c20191013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a736c6173685f72657365727665643a3a6833353862303531383961373466386136c301d5017375627374726174655f636f6e73656e7375735f626162655f7072696d6974697665733a3a6469676573743a3a5f494d504c5f4445434f44455f464f525f526177426162655072654469676573743a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72207375627374726174655f636f6e73656e7375735f626162655f7072696d6974697665733a3a6469676573743a3a526177426162655072654469676573743e3a3a6465636f64653a3a6862383064326639643437313266386666c40181013c73726d6c5f62616c616e6365733a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7472616e736665723a3a6836616434636263383739353063663834c501613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6834396362346336326435613339333532c601723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6861323738336566326234646132623933c701723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6862316137626231636339643733646664c8014b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6861353562633561383263656233336331c901613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6830313164623433646565373737396238ca014b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6834646431333338376131336364336331cb0148616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a6863616363333966353939343332386635cc012b616c6c6f633a3a736c6963653a3a6d657267655f736f72743a3a6862613932626637623632353538356463cd01613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6863666338376438356161346162313764ce01613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6861633332303038343936666264633862cf012d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6832623461333437363565633837376134d00134636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a6861386638653931313431363134613530d1012e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a6830353637653865383161346666343036d2013c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6830626532656436656362313730633235d3012d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6833343531633338666132346162613363d4013673726d6c5f626162653a3a4d6f64756c653c543e3a3a646f5f696e697469616c697a653a3a6838626535663539623566343339356161d5013573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a6765743a3a6865633632666665386561623465383038d60190013c73726d6c5f626162653a3a556e646572436f6e737472756374696f6e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c7533322c616c6c6f633a3a7665633a3a5665633c5b75383b205f5d3e3e3e3a3a6b65795f666f723a3a6838373936336135366530363863363065d7013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6833666362326131633834646262393563d8013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6832346532366638353763626565356433d901a0013c73726d6c5f696d5f6f6e6c696e653a3a5265636569766564486561727462656174732061732073726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a67656e657261746f723a3a53746f72616765446f75626c654d61703c7533322c7533322c616c6c6f633a3a7665633a3a5665633c75383e3e3e3a3a7072656669785f666f723a3a6839643166336261333661643764363339da014d73726d6c5f636f6e7472616374733a3a657865633a3a457865637574696f6e436f6e746578743c542c562c4c3e3a3a696e7374616e74696174653a3a6831306536363934386336383566626132db0181013c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6e74726163745f6578697374733a3a6863363436643835636134636639363466dc013173726d6c5f636f6e7472616374733a3a657865633a3a7472616e736665723a3a6834353036366265653862353039613066dd013973726d6c5f636f6e7472616374733a3a7761736d3a3a636f64655f63616368653a3a6c6f61643a3a6837613366613235366239386532343938de01593c73726d6c5f636f6e7472616374733a3a7761736d3a3a5761736d566d2061732073726d6c5f636f6e7472616374733a3a657865633a3a566d3c543e3e3a3a657865637574653a3a6834326335313065386234643965356333df01783c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6d6d69743a3a6830396630333830373063393939623830e0014f73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e3a3a7365745f62616c616e63653a3a6863643034386633616136353134663965e10130636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6833333231613531343839656638656566e2014673726d6c5f636f6e7472616374733a3a657865633a3a457865637574696f6e436f6e746578743c542c562c4c3e3a3a63616c6c3a3a6835306135653065316538353265393039e3014273726d6c5f636f6e7472616374733a3a72656e743a3a7472795f65766963745f6f725f616e645f7061795f72656e743a3a6831316431323431396136323433613538e4013c73726d6c5f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6830623263663630333730363064313931e5013e73726d6c5f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6836623665323037383262636338326635e601437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830633961306530316435323131633463e7013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6833313533323133303164316361663630e8013f7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a6831383136316636653964383863633138e9018b013c28412c20422c20432c20442c20452c20462c20472c20482c20492c204a2c204b2c204c2c204d2c204e2c204f2c20502c20512c20522c20532c2054292061732073725f7072696d6974697665733a3a7472616974733a3a4f6e46696e616c697a653c4e756d6265723e3e3a3a6f6e5f66696e616c697a653a3a6866643939303063636432343233653832ea013673726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a70726f706f73616c733a3a6839383437623433646166303731373966eb013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830646334663336343239373537313931ec013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6830643730633365366563393365383531ed013673726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6c6f673a3a6865336666636539393635336561343962ee01463c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6861613465646339663633366461326232ef013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6836373331656262366461666338323138f0013873726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a74616b653a3a6831653439303435366336636431356162f1013673726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a74616b653a3a6837393336323933336164333564326133f201673c73726d6c5f617574686f726974795f646973636f766572793a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6837386264363761336437373937613065f3013773726d6c5f626162653a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6838316537623762613933376464313339f4013973726d6c5f626162653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6863303165336535376539323537333735f5016c3c73726d6c5f626162653a3a5f5f476574427974655374727563745365636f6e64617279536c6f74733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834656666626461393739363437366333f6014273726d6c5f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6863633132336237386332613961303130f70197013c73726d6c5f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4578706563746564426c6f636b54696d6544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863333734316261663565656637373639f80193013c73726d6c5f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a45706f63684475726174696f6e44656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832636138323735393935643763666162f9013a73726d6c5f6772616e6470613a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6864393131613439303932313231376131fa013c73726d6c5f6772616e6470613a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6835336130366561373139353765353730fb01663c73726d6c5f6772616e6470613a3a5f5f4765744279746553747275637453746174653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864383064343134656433366462386139fc014473726d6c5f737570706f72743a3a7472616974733a3a5369676e6564496d62616c616e63653c422c503e3a3a6d657267653a3a6866663137393739303439643633393931fd013b73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6861373134363766363438323161353831fe013d73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6833333863656436636132653861636539ff01713c73726d6c5f656c656374696f6e733a3a5f5f4765744279746553747275637443616e646964617465436f756e743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a683264653865666630366161646565356180024673726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a686633376230656438643832383261323481028e013c73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4275726e44656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68646665643530326564303631336331618202870173725f7072696d6974697665733a3a5f494d504c5f454e434f44455f464f525f50657262696c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073725f7072696d6974697665733a3a50657262696c6c3e3a3a656e636f64653a3a6834343132376132613466376632303062830295013c73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5370656e64506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865326362333564646139396435343864840295013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e67426f6e6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866623731376530643366326465363933850296013c73726d6c5f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a50726f706f73616c426f6e6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a686565613136396461356434653333323286023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683935643238373038306335636535373687028c013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e2061732073725f7072696d6974697665733a3a7472616974733a3a4f6e496e697469616c697a653c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a683735623863663237323661323135643088023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683065633632323233616663633834623589023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68313161303864323137663435626639368a02437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68393736326133303264333230636437328b023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68663332666331646636636531663634668c024073726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a63616e6469646174655f7265675f696e666f3a3a68616562363165626439313964623737358d023873726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a616c6c5f766f746572733a3a68386266323731376138653732663465358e023a73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a617070726f76616c735f6f663a3a68613735633936643334633538613662328f02ab023c73726d6c5f656c656374696f6e733a3a566f746572496e666f4f663c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c73726d6c5f656c656374696f6e733a3a566f746572496e666f3c3c3c542061732073726d6c5f656c656374696f6e733a3a54726169743e3a3a43757272656e63792061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a42616c616e63653e3e3e3a3a6765743a3a68333330393033303132313239393332619002437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a683831316633616361663862653937313991023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6836656236336537666362393561613462920295013c73726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572735f736f727465643a3a683933633862323762656335353539663693023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68373765343564663262343233633766659402bc013c73726d6c5f656c656374696f6e733a3a566f746572733c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c7533322c616c6c6f633a3a7665633a3a5665633c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3e3e3a3a6765743a3a6864663966323963626664636365343737950280017061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72202851302c205230293e3a3a656e636f64655f746f3a3a68323036396637313761393639323035359602453c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a6765743a3a68653639663233386431366139663037619702437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68313531333561613839663034346534659802483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a68353864336232326235373266383737399902483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a72656d6f76653a3a68313430616664333534363238373462319a0230636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68303761323861653362633466323331339b02303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68336366656234363164363461343965619c02313c73747220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68373938323235666630353365313966649d023c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a68656338663863646162653766653431329e023e73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68636538643634363865373039333837399f024773726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6832643265323434356337613964306138a00299013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a564f5445525f5345545f53495a4544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865396136656534376362316231663838a10297013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e67506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835356338666233346533643361373062a2029e013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a496e6163746976654772616365506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865626538396633663062316330333136a30295013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4361727279436f756e7444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839306238623364306130663366346661a40294013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a566f74696e6746656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838393634643730646539326335383766a50298013c73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a43616e646964616379426f6e6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839653236626632323865633863636162a60249636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207573697a653e3a3a666d743a3a6839643839313230623134323164636361a7022f636f72653a3a666d743a3a6e756d3a3a696d703a3a666d745f7536343a3a6865323738346462306334626636626137a80235636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a6864366461363066643337346564373564a902a5013c73725f7072696d6974697665733a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e2061732073725f7072696d6974697665733a3a7472616974733a3a436865636b61626c653c4c6f6f6b75703e3e3a3a636865636b3a3a6862343935393063613464623838376466aa02b3013c73726d6c5f73797374656d3a3a426c6f636b486173683c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265722c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a486173683e3e3a3a6765743a3a6839356666343237303732353334643432ab023473726d6c5f696e64696365733a3a4d6f64756c653c543e3a3a656e756d5f7365743a3a6837656437323464393266646332373132ac02593c73725f7072696d6974697665733a3a416e795369676e61747572652061732073725f7072696d6974697665733a3a7472616974733a3a5665726966793e3a3a7665726966793a3a6834653334633762343834373762653135ad02437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6835643764666439306466333432633034ae024373726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6861646332343464643432366234646434af024e73726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6835383031333736663037353035343366b0029f013c73726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5265706f72744c6174656e637944656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838343837653732346566633831333661b1029c013c73726d6c5f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a57696e646f7753697a6544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833636438656435356665313434343639b2025d3c73726d6c5f656c656374696f6e733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6862356532623331316661333030643031b3023e73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a646f5f7365745f617070726f76616c733a3a6838363161396164613037326430346663b4023a73726d6c5f656c656374696f6e733a3a4d6f64756c653c543e3a3a72656d6f76655f766f7465723a3a6832616661666338633534643034336638b502683c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a73697a655f68696e743a3a6835616537373437323663666430636138b602633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6835666230323332643230333162623431b7023e636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a6e74683a3a6831343363336336333739663336326662b802406e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f73797374656d3a3a6865663763333532346335363338643637b902416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f696e64696365733a3a6837346432373363626366393034326236ba02426e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f62616c616e6365733a3a6862616536316530323133373334343732bb02416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7374616b696e673a3a6830366564373262363962353831666237bc02416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f73657373696f6e3a3a6831303461313661643833663433363162bd02436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f64656d6f63726163793a3a6838383339656164656530373732333335be024e6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f636f6c6c6563746976655f496e7374616e6365313a3a6862326430623863646463626130336337bf02436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f656c656374696f6e733a3a6831323031343732303762663263616337c0024e6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6d656d626572736869705f496e7374616e6365313a3a6830653764353231636238666339616235c102416e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6772616e6470613a3a6831636537313664306166626437326435c202426e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f74726561737572793a3a6830386562623634363434356535313336c302436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f636f6e7472616374733a3a6830393063356237383765656561326263c4023e6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f7375646f3a3a6866386464633837303831663630333434c502436e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f696d5f6f6e6c696e653a3a6863643162313837313663373964386537c602426e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6f6666656e6365733a3a6830613662353135633439316161373935c7024273726d6c5f636f6e7472616374733a3a7761736d3a3a707265706172653a3a707265706172655f636f6e74726163743a3a6862346264313238623831663430316631c802437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6863343131623133393330366463633762c9028a0173726d6c5f636f6c6c6563746976653a3a5f494d504c5f4445434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a6465636f64653a3a6862633863613332373763613466363032ca028b0173726d6c5f636f6e7472616374733a3a5f494d504c5f4445434f44455f464f525f5363686564756c653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f636f6e7472616374733a3a5363686564756c653e3a3a6465636f64653a3a6833353266646166386163363337353939cb028d0173726d6c5f636f6c6c6563746976653a3a5f494d504c5f454e434f44455f464f525f43616c6c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a656e636f64655f746f3a3a6831353435333833626139303564393066cc028e0173726d6c5f636f6e7472616374733a3a5f494d504c5f454e434f44455f464f525f5363686564756c653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6e7472616374733a3a5363686564756c653e3a3a656e636f64655f746f3a3a6864623838383538313633373666373631cd0241616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a7365617263683a3a7365617263685f747265653a3a6830653333663239303433663631333735ce025173725f696f3a3a696d703a3a3c696d706c2073725f696f3a3a53746f7261676541706920666f722028293e3a3a6f7264657265645f747269655f726f6f743a3a6830633966333964646664653065366433cf02663c73726d6c5f636f6e7472616374733a3a7761736d3a3a5761736d566d2061732073726d6c5f636f6e7472616374733a3a657865633a3a566d3c543e3e3a3a657865637574653a3a7b7b636c6f737572657d7d3a3a6837613866343135333237323366326362d0027d3c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6761733a3a6862346339343238363333613962636230d10289013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7365745f73746f726167653a3a6833623834313732333861643537363138d20289013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6765745f73746f726167653a3a6866343932663064646666396564373261d30282013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f63616c6c3a3a6838623066353732316336653633623263d40284013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6372656174653a3a6839336534663032353137616132383535d50284013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72657475726e3a3a6830333939376564623463653566633438d60284013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f63616c6c65723a3a6865363233623339666438353462313366d70285013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f616464726573733a3a6864386632323438636435326537343039d80287013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6761735f70726963653a3a6836376166346136653663343637663235d90286013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6761735f6c6566743a3a6861346366343764373132633165653039da0285013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f62616c616e63653a3a6839393434343465663439393037376464db028f013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f76616c75655f7472616e736665727265643a3a6861663865373438383838363031643436dc0284013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72616e646f6d3a3a6838323162313432323363376533306531dd0281013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6e6f773a3a6862636239623230663639656431316564de028b013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f64697370617463685f63616c6c3a3a6866333430633639626331396463303931df0288013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f726573746f72655f746f3a3a6862323739346434316532653139333938e0028a013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f73697a653a3a6839333762643336393961386633326532e1028a013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f726561643a3a6835623335353031623265376462343234e2028b013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f77726974653a3a6831313235616261363933633236396234e3028b013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6465706f7369745f6576656e743a3a6863303565613561653232303130356566e40290013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7365745f72656e745f616c6c6f77616e63653a3a6833326262353735303139646164636166e5028c013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72656e745f616c6c6f77616e63653a3a6831643535353863363565643137373438e60285013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7072696e746c6e3a3a6836323036333131646439356334393936e7028a013c73726d6c5f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732073726d6c5f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f626c6f636b5f6e756d6265723a3a6836363938363032396639333933303639e8023273725f73616e64626f783a3a696d703a3a64697370617463685f7468756e6b3a3a6830626665613138666231353662333135e902ad017375627374726174655f7072696d6974697665733a3a73616e64626f783a3a5f494d504c5f4445434f44455f464f525f547970656456616c75653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72207375627374726174655f7072696d6974697665733a3a73616e64626f783a3a547970656456616c75653e3a3a6465636f64653a3a6866656635303937613263383536613333ea0284016e6f64655f72756e74696d653a3a5f494d504c5f454e434f44455f464f525f4576656e743a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206e6f64655f72756e74696d653a3a4576656e743e3a3a656e636f64655f746f3a3a6838623537656362636633313265353037eb02a20173726d6c5f636f6c6c6563746976653a3a5f494d504c5f454e434f44455f464f525f5261774576656e743a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6c6c6563746976653a3a5261774576656e743c486173682c4163636f756e7449642c493e3e3a3a656e636f64655f746f3a3a6830616239333039656336323034313061ec024b3c5b543b205f5d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6837336334313166383630663365363461ed02653c6e6f64655f72756e74696d653a3a43616c6c2061732073725f7072696d6974697665733a3a776569676874733a3a4765744469737061746368496e666f3e3a3a6765745f64697370617463685f696e666f3a3a6865373565386364636265333630386635ee02583c6e6f64655f72756e74696d653a3a43616c6c2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6833313338333733396365393431663236ef02437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6832636130643662633263613766316266f0023973726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a7265776172645f62795f6964733a3a6836663939303631656466663335303064f1025c3c73726d6c5f6f6666656e6365733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6862393438616466613436623666363331f2023773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834346334343038356636323264656566f302437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6833663133656362623037646635343038f4025d3c73726d6c5f636f6e7472616374733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6836363362313032336533396434383864f50295013c73726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e2061732073726d6c5f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572735f736f727465643a3a6839613962656536656462636263306634f6024a73726d6c5f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733a3a7365745f6d656d626572735f736f727465643a3a6838306438303663646133653166616239f702603c73726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6861396635326165656331643563656337f802603c73726d6c5f636f6c6c6563746976653a3a43616c6c3c542c493e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6863343832343234643936316131343364f902c9023c73726d6c5f7374616b696e673a3a4c65646765723c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c73726d6c5f7374616b696e673a3a5374616b696e674c65646765723c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c3c542061732073726d6c5f7374616b696e673a3a54726169743e3a3a43757272656e63792061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a42616c616e63653e3e3e3a3a6765743a3a6861323935373736613766363664633034fa025b3c73726d6c5f7374616b696e673a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6863333237633534336336323562636437fb025b3c73726d6c5f696e64696365733a3a43616c6c3c543e2061732073725f7072696d6974697665733a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6837616339313066343033396465323430fc023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6836343163323437336562613362636335fd02b0017375627374726174655f7072696d6974697665733a3a73616e64626f783a3a5f494d504c5f454e434f44455f464f525f547970656456616c75653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72207375627374726174655f7072696d6974697665733a3a73616e64626f783a3a547970656456616c75653e3a3a656e636f64655f746f3a3a6866383633363031646639356139346565fe023a73726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6831313038353462383364623338653366ff023c73726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68353439396363626262666131656631628003703c73726d6c5f617574686f72736869703a3a5f5f47657442797465537472756374446964536574556e636c65733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a683131656632666235653732303835393981034573726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6831393764376333393239383430663461820399013c73726d6c5f73657373696f6e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a44454455505f4b45595f50524546495844656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a683436373363373137616662633061313983038c013c73726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a54776f783634436f6e6361742061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654861736865723e3a3a686173683a3a683131346663643830366530653033346384033573726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a6765743a3a6833636232633333616266323237366563850380017061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72202851302c205230293e3a3a656e636f64655f746f3a3a686134613131633233643563326562633986038a013c73726d6c5f73657373696f6e3a3a4d6f64756c653c543e2061732073725f7072696d6974697665733a3a7472616974733a3a4f6e496e697469616c697a653c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a686537333332653233306466366539333187033373726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a7374616b6572733a3a68323630386463613237303631643035338803c7013c73726d6c5f6f6666656e6365733a3a4d6f64756c653c543e2061732073725f7374616b696e675f7072696d6974697665733a3a6f6666656e63653a3a5265706f72744f6666656e63653c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c542061732073726d6c5f6f6666656e6365733a3a54726169743e3a3a4964656e74696669636174696f6e5475706c652c4f3e3e3a3a7265706f72745f6f6666656e63653a3a6861663938613230313234383732373761890386013c73726d6c5f7374616b696e673a3a4d6f64756c653c543e2061732073726d6c5f73657373696f6e3a3a4f6e53657373696f6e456e64696e673c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6f6e5f73657373696f6e5f656e64696e673a3a68326263316561663335653836323063328a03793c73726d6c5f6772616e6470613a3a536574496453657373696f6e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c7536342c7533323e3e3a3a6b65795f666f723a3a68613063393235383763386337613834358b033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68316264663033636633346533313565658c033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68366430633138393464333865633966628d033c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a68396333376437343436623665663839328e033d73726d6c5f617574686f72736869703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a68363262653734306365633432396361358f033f73726d6c5f617574686f72736869703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68626136323030666362393838346363369003437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a683331346132336334316433363539656191033c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6834666637616330383438646137653733920334636f72653a3a736c6963653a3a3c696d706c205b545d3e3a3a636f6e7461696e733a3a68333436643836343665376562303763399303930173726d6c5f73797374656d3a3a5f494d504c5f454e434f44455f464f525f4576656e745265636f72643a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f73797374656d3a3a4576656e745265636f72643c452c543e3e3a3a656e636f64655f746f3a3a6865346563326666343561393031356132940330636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68653730333131343961346164303638659503df013c73726d6c5f73797374656d3a3a4576656e74546f706963733c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a67656e657261746f723a3a53746f72616765446f75626c654d61703c28292c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a486173682c616c6c6f633a3a7665633a3a5665633c283c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265722c20753332293e3e3e3a3a7072656669785f666f723a3a686235396165663332326531386361366196033973726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a686538396135393737663236376565313697033b73726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68383337376333626664666432666161359803663c73726d6c5f73797374656d3a3a5f5f476574427974655374727563744576656e74733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68366331323363326661363765343830649903693c73726d6c5f73797374656d3a3a5f5f47657442797465537472756374426c6f636b486173683c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68343330343862356538346366613138629a036e3c73726d6c5f73797374656d3a3a5f5f4765744279746553747275637452616e646f6d4d6174657269616c3c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68306261643431313130333934323539659b034473726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68343364333665626537393132396266319c033173726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a72616e646f6d3a3a68656464356365663332656566316666619d033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68336634333139363734316666356139339e033373726d6c5f73797374656d3a3a4d6f64756c653c543e3a3a66696e616c697a653a3a68386165633832623665343164623863309f035373725f7072696d6974697665733a3a50657262696c6c3a3a66726f6d5f726174696f6e616c5f617070726f78696d6174696f6e3a3a7b7b636c6f737572657d7d3a3a6837323838353965643366653736653030a0035373725f7072696d6974697665733a3a50657262696c6c3a3a66726f6d5f726174696f6e616c5f617070726f78696d6174696f6e3a3a7b7b636c6f737572657d7d3a3a6835393731366437353530333665633565a1037173726d6c5f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65733e3a3a696e697469616c697a655f626c6f636b3a3a6839623433343636353436386234393863a203467061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a436f646553656374696f6e3a3a626f646965733a3a6837326431376666616439393932633932a3037973726d6c5f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65733e3a3a6170706c795f65787472696e7369635f776974685f6c656e3a3a6839613161663865363737353239393930a40389013c73726d6c5f73797374656d3a3a45787472696e736963446174612061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c7533322c616c6c6f633a3a7665633a3a5665633c75383e3e3e3a3a6b65795f666f723a3a6864383735373032363935636630666437a5033c73726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6862633636356435633466623937663033a6033e73726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6861653530613061666266366533636130a7034773726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6839636435633665306432346636356537a80398013c73726d6c5f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d506572696f6444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833333331306137633064646332396461a9033f73726d6c5f6d656d626572736869703a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6866643934666535643031616264666239aa034173726d6c5f6d656d626572736869703a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6835666230316232646139323231346236ab033773726d6c5f7375646f3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6862363339666435623038323666366465ac033973726d6c5f7375646f3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6831383535636663656561353635613661ad03613c73726d6c5f7375646f3a3a5f5f476574427974655374727563744b65793c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864363066633163383265613735316635ae033c73726d6c5f696e64696365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6830613930363866613562613032323966af03cc013c73726d6c5f636f6c6c6563746976653a3a566f74696e673c542c493e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a486173682c73726d6c5f636f6c6c6563746976653a3a566f7465733c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3e3a3a6765743a3a6835363236306232633365633435323539b0033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6864386363343831643532616339613437b1033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831396538376138393636366237643333b203cc013c73726d6c5f636f6c6c6563746976653a3a566f74696e673c542c493e2061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a486173682c73726d6c5f636f6c6c6563746976653a3a566f7465733c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3e3a3a6765743a3a6862383230666535323162376133393836b3033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831333037623939323332333034316262b4033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834373463353861616230373838663565b5033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6835363830653435366130333430313934b6033773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861396330663861613132646436306233b703483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a6839346238643866396361623062323732b8033f73726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6863666463363433663162343764633131b9034173726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6830663536623361326562376331613966ba034173726d6c5f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6866383438366232333135306364303562bb036a636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653c413e20666f7220266d757420463e3a3a63616c6c5f6f6e63653a3a6830616630663061346431643965393766bc03463c616c6c6f633a3a626f7865643a3a426f783c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6837383636313639323438373632363835bd0330636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6830303438336564353462363061373633be033c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6830646661363534356139373134636565bf033e73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6835396136393330353436643734646530c0036b3c73726d6c5f636f6e7472616374733a3a5f5f4765744279746553747275637447617350726963653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832333730623738303132373133376232c1036f3c73726d6c5f636f6e7472616374733a3a5f5f476574427974655374727563745072697374696e65436f64653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861623330376232303436663739363831c203723c73726d6c5f636f6e7472616374733a3a5f5f4765744279746553747275637443757272656e745363686564756c653c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837376465623331386463303565363464c3034773726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6866333265323838306464383862616131c40398013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426c6f636b4761734c696d697444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866333930393938303936383634636365c50397013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d617856616c756553697a6544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864343161663361376632633661643738c60393013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6178446570746844656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834323836316435306462646566386539c70396013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a43616c6c4261736546656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839396234383434356232303362353936c80396013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a436f6e747261637446656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861393335643334356237373734646231c9039d013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5472616e73616374696f6e4279746546656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861653436323837306630313531373536ca039a013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53757263686172676552657761726444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863393231333466383235663831366463cb039c013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a52656e744465706f7369744f666673657444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837666563613335643264383237666466cc0396013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a52656e744279746546656544656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864356432666236633933323334393066cd039c013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53746f7261676553697a654f666673657444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836633139303763303230383431343331ce039b013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a546f6d6273746f6e654465706f73697444656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838376661613835356166373735666565cf039e013c73726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5369676e6564436c61696d48616e646963617044656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839656138623831353731363862656433d003c40173726d6c5f636f6e7472616374733a3a5f494d504c5f454e434f44455f464f525f526177416c697665436f6e7472616374496e666f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073726d6c5f636f6e7472616374733a3a526177416c697665436f6e7472616374496e666f3c436f6465486173682c42616c616e63652c426c6f636b4e756d6265723e3e3a3a656e636f64655f746f3a3a6864316230393664313066356339336366d1034573726d6c5f636f6e7472616374733a3a7761736d3a3a707265706172653a3a436f6e74726163744d6f64756c653a3a6e65773a3a6839376633633530666139366536306133d20348616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a6830313061613735653430316230653732d3033c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a66726f6d5f6d6f64756c653a3a6838666432613635653336313565323938d403537061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c654275696c6465723c463e3a3a7265736f6c76655f747970655f7265663a3a6861303138623165343030336133303932d503a9017061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c6553636166666f6c643e20666f72207061726974795f7761736d3a3a656c656d656e74733a3a6d6f64756c653a3a4d6f64756c653e3a3a66726f6d3a3a6866326434646662656261343332613331d6033a707761736d5f7574696c733a3a72756c65733a3a496e737472756374696f6e547970653a3a6f703a3a6863333338613537333336393564646636d703507061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c654275696c6465723c463e3a3a707573685f66756e6374696f6e3a3a6835363362366137313162633739623766d80330636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6832323966646662313030363433616162d9033c707761736d5f7574696c733a3a737461636b5f6865696768743a3a696e6a6563745f6c696d697465723a3a6863623637613838363263343466613962da036b3c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6864613130656362356162306161336265db0391013c73726d6c5f636f6e7472616374733a3a54726965496446726f6d506172656e74436f756e7465723c543e2061732073726d6c5f636f6e7472616374733a3a54726965496447656e657261746f723c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a747269655f69643a3a6834386235646461316437383564386239dc03437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6836613461353836653932386636663238dd03f0013c73726d6c5f7374616b696e673a3a5f5f6c696e6b65645f6d61705f64657461696c735f666f725f6e6f6d696e61746f72735f646f5f6e6f745f7573653a3a456e756d657261746f723c532c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c28616c6c6f633a3a7665633a3a5665633c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e2c2054293e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6864306435343239623235303864366333de03d0023c73726d6c5f7374616b696e673a3a5f5f6c696e6b65645f6d61705f64657461696c735f666f725f76616c696461746f72735f646f5f6e6f745f7573653a3a456e756d657261746f723c532c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c2873726d6c5f7374616b696e673a3a56616c696461746f7250726566733c3c3c542061732073726d6c5f7374616b696e673a3a54726169743e3a3a43757272656e63792061732073726d6c5f737570706f72743a3a7472616974733a3a43757272656e63793c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a42616c616e63653e2c2054293e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6830373665626264326462303536653532df03483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a696e736572743a3a6839396330396538626161376237316634e0032f73726d6c5f636f6e7472616374733a3a6761733a3a6275795f6761733a3a6862613264363632353632396666333265e103743c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6d6d69743a3a6864323239396139363532356162393661e2033973726d6c5f636f6e7472616374733a3a6761733a3a726566756e645f756e757365645f6761733a3a6838313231626362653866396564343463e3033873726d6c5f636f6e7472616374733a3a4d6f64756c653c543e3a3a726573746f72655f746f3a3a6862333866616131356432373261303333e4030c436f72655f76657273696f6ee50312436f72655f657865637574655f626c6f636be6034173725f7072696d6974697665733a3a67656e657269633a3a656e636f64655f776974685f7665635f7072656669783a3a6863363538326633636461613932393732e70315436f72655f696e697469616c697a655f626c6f636be803114d657461646174615f6d65746164617461e903483c5b545d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6866653239373431336635303633656634ea03683c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6861366530646266663263623838363566eb03683c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6839366663666462326435373361663838ec031c426c6f636b4275696c6465725f6170706c795f65787472696e736963ed031b426c6f636b4275696c6465725f66696e616c697a655f626c6f636bee0320426c6f636b4275696c6465725f696e686572656e745f65787472696e73696373ef036f3c636f72653a3a697465723a3a61646170746572733a3a526573756c745368756e743c492c453e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a6838373335313834346430363132633062f0033873726d6c5f74696d657374616d703a3a657874726163745f696e686572656e745f646174613a3a6830343763623136303932653733303737f1031c426c6f636b4275696c6465725f636865636b5f696e686572656e7473f20318426c6f636b4275696c6465725f72616e646f6d5f73656564f3032b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6ef4035673725f7072696d6974697665733a3a7472616e73616374696f6e5f76616c69646974793a3a56616c69645472616e73616374696f6e3a3a636f6d62696e655f776974683a3a6832653539396365636661653534396164f503214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b6572f60380013c73726d6c5f696d5f6f6e6c696e653a3a737232353531393a3a6170705f737232353531393a3a5075626c6963206173207375627374726174655f6170706c69636174696f6e5f63727970746f3a3a7472616974733a3a52756e74696d654170705075626c69633e3a3a616c6c3a3a6838643936353331303232613466636564f703214772616e6470614170695f6772616e6470615f70656e64696e675f6368616e6765f803204772616e6470614170695f6772616e6470615f666f726365645f6368616e6765f9031e4772616e6470614170695f6772616e6470615f617574686f726974696573fa0314426162654170695f737461727475705f64617461fb030d426162654170695f65706f6368fc0322417574686f72697479446973636f766572794170695f617574686f726974795f6964fd0321417574686f72697479446973636f766572794170695f617574686f726974696573fe031a417574686f72697479446973636f766572794170695f7369676eff031c417574686f72697479446973636f766572794170695f76657269667980041d4163636f756e744e6f6e63654170695f6163636f756e745f6e6f6e636581042153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b657973820427636f72653a3a7374723a3a66726f6d5f757466383a3a68613238313832346465323264323836338304483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a72656d6f76653a3a68376364313136316433643430313530388404483c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e3e3a3a72656d6f76653a3a68313561323065366666323064613431378504437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a683733316431353861346534313765396486043a73726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a686537336131633661386535303634343287043c73726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68356337313133666231383463353464638804743c73726d6c5f7374616b696e673a3a5f5f47657442797465537472756374536c6173685265776172644672616374696f6e3c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68663936626638386661356663393565628904723c73726d6c5f7374616b696e673a3a5f5f4765744279746553747275637443757272656e74457261526577617264733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68633830383561363764643138313761618a04703c73726d6c5f7374616b696e673a3a5f5f4765744279746553747275637443757272656e7445726153746172743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68383233333866336262386133313037648b04683c73726d6c5f7374616b696e673a3a5f5f476574427974655374727563745374616b6572733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68336330646131656438316564366231358c046b3c73726d6c5f7374616b696e673a3a5f5f4765744279746553747275637456616c696461746f72733c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68663631373464663433656530376134338d04763c73726d6c5f7374616b696e673a3a5f5f476574427974655374727563744d696e696d756d56616c696461746f72436f756e743c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68313864383636346131666331663764358e043273726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a626f6e6465643a3a68373864626631313935343937366137348f044573726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6835373266633332353038386238383539900498013c73726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426f6e64696e674475726174696f6e44656661756c74427974654765747465723c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a683565356238656438376238633431613091049a0173726d6c5f7374616b696e673a3a5f494d504c5f4445434f44455f464f525f4578706f737572653a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073726d6c5f7374616b696e673a3a4578706f737572653c4163636f756e7449642c42616c616e63653e3e3a3a6465636f64653a3a686334316430333362393931373037656592043773726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a6d616b655f7061796f75743a3a68393333363061363538383439663430379304673c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a6834336565346237323330336338643434940444636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a73697a655f68696e743a3a683433373666353264626537353438363295043973726d6c5f7374616b696e673a3a4d6f64756c653c543e3a3a7570646174655f6c65646765723a3a6834373330333733393435303966653865960430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a683232643265333166343431643466643597043e636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a6e74683a3a68313662623162356539376530326138639804437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a683261666365333833353932383263366699046b3c636f72653a3a697465723a3a61646170746572733a3a526573756c745368756e743c492c453e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a68313034326332383634316234633036339a04793c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f62616c616e63653a3a68383138383235646563646264396665379b04793c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f73746f726167653a3a68323938663339386232656136643363669c047b3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f636f64655f686173683a3a68343539653239633837333836346139389d047d3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6e74726163745f6578697374733a3a68613963363834386231386230663965619e0480013c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f72656e745f616c6c6f77616e63653a3a68323864306235353633373738633262639f047d3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f73746f726167653a3a6863326532653237303030313732623332a00484013c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f72656e745f616c6c6f77616e63653a3a6862643330386661633839336532396663a1047d3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f62616c616e63653a3a6834313665623537666535376565306337a2047f3c73726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732073726d6c5f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f636f64655f686173683a3a6837653738666364643531396663396238a3043d73726d6c5f6f6666656e6365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6835633666373731346663373732373932a404743c73726d6c5f6f6666656e6365733a3a5f5f476574427974655374727563745265706f72747342794b696e64496e6465783c543e2061732073726d6c5f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861393666323639336565323938313434a50494013c73726d6c5f6f6666656e6365733a3a5265706f72747342794b696e64496e6465782061732073726d6c5f737570706f72743a3a73746f726167653a3a6861736865643a3a67656e657261746f723a3a53746f726167654d61703c5b75383b205f5d2c616c6c6f633a3a7665633a3a5665633c75383e3e3e3a3a6b65795f666f723a3a6862623463393138393164626637646431a604d4013c73726d6c5f6f6666656e6365733a3a436f6e63757272656e745265706f727473496e6465783c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a67656e657261746f723a3a53746f72616765446f75626c654d61703c5b75383b205f5d2c616c6c6f633a3a7665633a3a5665633c75383e2c616c6c6f633a3a7665633a3a5665633c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a486173683e3e3e3a3a6b65795f666f723a3a6864646232653238333731663031316466a704683c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e697445787072206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6834633435663463393933333264373731a8046b3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6835353261323637326535326466326335a9047d3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a436f756e7465644c6973745772697465723c492c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6834313533356532373638396532353931aa046f3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a566172496e743332206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6832316430303063336238646538646164ab046f3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a566172496e743634206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6836613334623833613936396131323961ac046c3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e697445787072206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6835366633316462653838333734636533ad046f3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6838663766626361363765356531396138ae04443c7061726974795f7761736d3a3a696f3a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6864633333356639356164646163373738af0425616c6c6f633a3a666d743a3a666f726d61743a3a6832373435663631663164633065323663b004793c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a436f756e7465644c6973743c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6833383766643035336438643236363039b1046b3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6834663036373131663835636339316233b204713c7061726974795f7761736d3a3a656c656d656e74733a3a696e6465785f6d61703a3a496e6465784d61703c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6864383365313966386439663466653034b3042c636f72653a3a666d743a3a466f726d61747465723a3a7061643a3a6865666362666265373861666239396631b404783c7061726974795f7761736d3a3a656c656d656e74733a3a696d706f72745f656e7472793a3a526573697a61626c654c696d697473206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6863306238626437303735303533383039b5047c3c7061726974795f7761736d3a3a656c656d656e74733a3a696d706f72745f656e7472793a3a526573697a61626c654c696d697473206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6864613031333966663231353535363263b60486017061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a3c696d706c207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a6520666f7220616c6c6f633a3a737472696e673a3a537472696e673e3a3a646573657269616c697a653a3a6861373937656662306434383332666433b704323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6834373331656463396533376466616435b804743c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a56617255696e743332206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6833323766373336383864383435303865b904713c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a437573746f6d53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6835643330333238613464306638636430ba046f3c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6838393462366537353466646463633531bb04457061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e5265616465723a3a6e65773a3a6862633434363636323130393932366533bc044e636f72653a3a666d743a3a6e756d3a3a696d703a3a3c696d706c20636f72653a3a666d743a3a446973706c617920666f72207533323e3a3a666d743a3a6834363064663934653535353264643834bd04397761736d695f76616c69646174696f6e3a3a76616c69646174655f6d656d6f72795f747970653a3a6832666133323562353066303263343838be04347761736d695f76616c69646174696f6e3a3a657870725f636f6e73745f747970653a3a6866323561616434326565366132346138bf04553c7061726974795f7761736d3a3a656c656d656e74733a3a74797065733a3a56616c75655479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830343833323662653239373861343232c0044a7761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a737465703a3a6830346231393732353531653436633264c104473c7761736d695f76616c69646174696f6e3a3a4572726f7220617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6861333530353037623239656363623466c204303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830313565323332376264666434373331c304416861736862726f776e3a3a7261773a3a5261775461626c653c543e3a3a7472795f776974685f63617061636974793a3a6833363731616638633235303437353938c4043e6861736862726f776e3a3a7261773a3a5261775461626c653c543e3a3a726573657276655f7265686173683a3a6830356135316561343937306437366661c504457061726974795f7761736d3a3a656c656d656e74733a3a7365676d656e743a3a446174615365676d656e743a3a76616c75653a3a6861636664323965353633386636656533c60437616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6835633831376566333833303132343930c7043b636f72653a3a736c6963653a3a3c696d706c205b545d3e3a3a636f70795f66726f6d5f736c6963653a3a6838303862316434303039356131396539c804347761736d695f76616c69646174696f6e3a3a66756e633a3a706f705f76616c75653a3a6831316663353438346535663763643062c904347761736d695f76616c69646174696f6e3a3a66756e633a3a706f705f6c6162656c3a3a6831616166633066333561633931663463ca04407761736d695f76616c69646174696f6e3a3a7574696c3a3a4c6f63616c733a3a747970655f6f665f6c6f63616c3a3a6835666630613833326362323430343035cb04543c7761736d695f76616c69646174696f6e3a3a66756e633a3a537461636b56616c75655479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6838666562383461343733313263616235cc04537761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f6c6f61643a3a6862373939313964353735336532333264cd04547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f73746f72653a3a6832323438323765306535383135363161ce04557761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f746573746f703a3a6833656538633366393632663462386531cf04547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f72656c6f703a3a6836623135333462323930646239353739d004537761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f756e6f703a3a6837336639646537333732313835663763d104547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f62696e6f703a3a6837313861653135633361653837613765d204547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f6376746f703a3a6838636235386436376166333966626433d304553c7061726974795f7761736d3a3a656c656d656e74733a3a74797065733a3a426c6f636b5479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6862383937373861363836663032383566d40439636f72653a3a666d743a3a6275696c646572733a3a44656275675475706c653a3a6669656c643a3a6835613035383437383532646236313939d50430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6837363431363361393164323763656461d604303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6839363533656162383933636662626163d704453c616c6c6f633a3a737472696e673a3a537472696e6720617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6833386561626262623163396366623637d80423636f72653a3a666d743a3a77726974653a3a6838353631336433636133336364636630d9044c3c7761736d695f76616c69646174696f6e3a3a737461636b3a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6866623933303463376331336563336137da04553c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6861323030363266393363363961343037db04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6831633437616134656339623138613037dc043a636f72653a3a666d743a3a6275696c646572733a3a44656275675374727563743a3a6669656c643a3a6861323831663239633130626537643737dd0441707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a636f6d707574653a3a6837636331303839353430623636643335de045a3c707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a4672616d6520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6835303639313435346664663136353731df0446707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a537461636b3a3a6672616d653a3a6861663430333035613439663032343930e004453c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c543e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6865333433316134363161393735326330e1044b707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a537461636b3a3a706f705f76616c7565733a3a6833326430316235666163613562623531e2043f707761736d5f7574696c733a3a737461636b5f6865696768743a3a7265736f6c76655f66756e635f747970653a3a6830613831303463386463666136663065e304593c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6866303361303538356162373336386165e404533c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a737065635f657874656e643a3a6861336338653864393166646466343236e504323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6861356563383462326238373935366632e604613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6865323935326432633766663164363239e704303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6837333834663039363533346436313861e804303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832363466366531663164313535646135e904303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6837353661653037643331323661636236ea04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6862303333356635353163326364373039eb04463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6866666338356635333438636639626264ec04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6839336266333633636235643238383262ed04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6863666234383263646436353835373938ee04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6865626233353561386537303331613238ef0409686173685f74657374f004383c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a656e61626c65643a3a6830346537653931313561643738656339f104343c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a6c6f673a3a6864666366613037313536373636653037f204363c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a666c7573683a3a6837343164623339623866393932316162f304323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6863333735373337356635613939656536f404323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6838323165646662373836636562636563f504323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6831373838633136343637366464303762f60411727573745f626567696e5f756e77696e64f7044e73725f696f3a3a696d703a3a6578743a3a65787465726e5f66756e6374696f6e735f686f73745f696d706c3a3a6578745f7072696e745f757466383a3a6865663532333966653863666630373564f80430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6832666662326362323731633930346636f9040a5f5f72675f616c6c6f63fa040c5f5f72675f6465616c6c6f63fb040c5f5f72675f7265616c6c6f63fc04115f5f72675f616c6c6f635f7a65726f6564fd0430636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6831363934653035363630383630623938fe043a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6862653063633736373034363330313733ff043b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a686136656461346266313363386433313780053a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68383537343030653532653338353234368105313c5420617320636f72653a3a616e793a3a416e793e3a3a747970655f69643a3a6865373363323638323362326261396231820543636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a77726974655f7072656669783a3a686339366631656539646465306633346383052e636f72653a3a7374723a3a736c6963655f6572726f725f6661696c3a3a683332393031366634336664306439376584054a3c636f72653a3a6f70733a3a72616e67653a3a52616e67653c4964783e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68303236336330613236303839616563318505323c6368617220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683963376331663232663333666534383986053d636f72653a3a756e69636f64653a3a626f6f6c5f747269653a3a426f6f6c547269653a3a6c6f6f6b75703a3a686530353530326362316439386335653487054e636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207573697a653e3a3a666d743a3a68396438393132306231343231646363612e32393234880534636f72653a3a666d743a3a417267756d656e7456313a3a73686f775f7573697a653a3a68663738656233626263646661303062368905453c636f72653a3a63656c6c3a3a426f72726f774572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68336637363731646366653538656630308a05483c636f72653a3a63656c6c3a3a426f72726f774d75744572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68366438356331653935316665396336648b05303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68613535643065313162396630373331318c052e636f72653a3a736c6963653a3a6d656d6368723a3a6d656d6368723a3a68623438306638313334323932373663658d058001636f72653a3a7374723a3a7472616974733a3a3c696d706c20636f72653a3a736c6963653a3a536c696365496e6465783c7374723e20666f7220636f72653a3a6f70733a3a72616e67653a3a52616e67653c7573697a653e3e3a3a696e6465783a3a7b7b636c6f737572657d7d3a3a68386636326364383630306361346433628e0530636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68303932393462626337383235366562388f05533c636f72653a3a666d743a3a6275696c646572733a3a5061644164617074657220617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a683339663031333835633134633861353090052f636f72653a3a666d743a3a57726974653a3a77726974655f636861723a3a686635613836353066666365363130363791052e636f72653a3a666d743a3a57726974653a3a77726974655f666d743a3a683230353432663636376136333538346192053a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a686664643662633163633933343633373093053b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a683734643033643934623064333435643494053a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68373039323461383535633439356437659505303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68623331396337633038323830336338369605303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68306531643161343031656430303463659705423c636f72653a3a7374723a3a557466384572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68643236633863306139616364663132349805303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683437323938326336306631343339306299053e3c636f72653a3a666d743a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68366234623961666232663633313266659a05066d656d7365749b05066d656d6370799c05076d656d6d6f76659d05066d656d636d709e05095f5f6173686c7469339f05095f5f6c736872746933a005085f5f6d756c746933a105095f5f75646976746933a205095f5f756d6f64746933a3050c5f5f756469766d6f6474693400550970726f64756365727302086c616e6775616765010452757374000c70726f6365737365642d62790105727573746325312e33392e302d6e696768746c79202835323164373834303720323031392d30382d323529", + "0x121725e2f949944d00a8c011c0db54ae07b84a6ca772adf3c65417345d91522d": "0x0000c16ff28623000000000000000000", + "0xc1bc13c775b3406279618b05c28523cb": "0x00", + "0xccea67b51b4fa33ecbff70a8977ad91d9c60d620f3ab5ac9626dea15cde023b7": "0x0f0000c16ff286230f0000c16ff2862300", + "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b6579737f325c981c2b001f5fe8c51cc7b89e50ebb1f60feb7ab3fa3bc79d6ab71d45cb": "0x9becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993326e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106", + "0x2b334d6ac6698775ed17edf8cd3cbd9dae56cead0d69cb54f6af6aaecba544d8": "0x0f0000c16ff286230f0000c16ff2862300", + "0x154ebcb2c318b2e1c23e43e65aea27cd1348c4c5157502d7669a31c7635019cc": "0x9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526", + "0x7e6064dc0e78ffebb59b3053826a9467": "0x109c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d1268655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0x633daafcb669e97549c1b9d65660881016f969040bc16171709159437c31294a": "0x0f0000c16ff286230f0000c16ff2862300", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b657973dc4036f96ca26a30da6d8637ca1431896c1069bf172c419e98dc08109e7b23b5": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", + "0x90e2849b965314409e8bc00011f3004f": "0x04000000", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797301dd273832961ca94116fd224019ea1370c0e3d27bebb1041b35651146d17832": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797399a2fc4b1339e668345bac7e1aadd1a834b90939a4ea40b64f30433a1d475817": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", + "0x125dc846383907f5846f72ce53ca0e4b": "0x00ca9a3b000000000000000000000000", + "0xdfa1667c116b77971ada377f9bd9c485a0566b8e477ae01969120423f2f124ea": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b657973d1ae046d940202772415992434f839d8c546542e3055143c430f7eec87f7cb69": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0x2d5205eddfc20f1a616c0391abb78a3920e823abe7ed33cfd7945dd1a1bf8651": "0x047374616b696e67200000c16ff28623000000000000000000ffffffff0e", "0x0c41b62474c49057a4476d0b96853c6d44e9c86c5fa130b0da3831c5eef546a0": "0x00", + "0x366a192e1ce90bf109f11cf4d4bdab1ce310d835c09411b1be3ad53814e33196": "0x000001547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", "0x87e6cbd186029472cea8c1748f99126b": "0x00000000", - "0xc1fdc3d212357bc2fa98f2a77b941f0c": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d6568655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde789c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", - "0x2d5205eddfc20f1a616c0391abb78a3920e823abe7ed33cfd7945dd1a1bf8651": "0x047374616b696e67200000c16ff28623000000000000000000ffffffff0e", - "0xdfa1667c116b77971ada377f9bd9c485a0566b8e477ae01969120423f2f124ea": "0x4545454545454545454545454545454545454545454545454545454545454545", - "0x637414312dac3b280120bf15b4f66cee": "0x00000000", - "0xf14d23a9d4492a1efc9194e257b3c3d9": "0x00000000", - "0x2dce29f1a768624dc5343063cb77f77d": "0x07000000", - "0x154ebcb2c318b2e1c23e43e65aea27cd1348c4c5157502d7669a31c7635019cc": "0x9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526", + "0xc63b8a0db7e72fd87c88d8dcf4777b883f86728613c57148c4e5cdceb05b7a1a": "0x0001f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26630168655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", + "0xfff675c76ad8a5dfbd7db9a4e80f7c0ece595ad1878d2b6fca6086b2483a055b": "0x0000c16ff28623000000000000000000", "0xbc3717660105a864bd63dcd430de64128d58bd0917fa8dd75aee827cf086e19c": "0x0000c16ff28623000000000000000000", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b6579730cd914acf7b89329ae59e8f7e3b8f1ee7a4f5f68d4749cca82814f2f5b1d6bbb": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797399a2fc4b1339e668345bac7e1aadd1a834b90939a4ea40b64f30433a1d475817": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", - "0xd437fe93b0bd0a5d67d30d85d010edc2": "0x40420f00", - "0xeecb67c20ca6cc8ba4d4434687f61309": "0x103919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef01000000000000005633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce44001000000000000007932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f01000000000000009becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993320100000000000000", + "0x3ae31af9a378162eb2736f26855c9ad8": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x040ff70c23416b89ce6afb75ee0d362e": "0x00000000", "0x3a65787472696e7369635f696e646578": "0x00000000", - "0xa5e869ecc1b914a6b0cf5f02b874f5eb90f1739fbd3edd01e5835d1517fd9f72": "0x781ead1e2fa9ccb74b44c19d29cb2a7a4b5be3972927ae98cd3877523976a276", - "0x4e62513de81454ce76df887573f7f98b101eb4585b1485a222b7db599f4e93e2": "0x047374616b696e67200000c16ff28623000000000000000000ffffffff0e", - "0x366a192e1ce90bf109f11cf4d4bdab1ce310d835c09411b1be3ad53814e33196": "0x0c000001547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", - "0x8b4621d5f16433d6024b5a31547c59ee24e749e051dbb4bc7e64502f2a4f62fb": "0x66bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f", - "0x9651d20f401bfac47731a01d6eba33b4": "0x00000000", - "0x7e6064dc0e78ffebb59b3053826a9467": "0x109c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d1268655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", - "0x75f6361fd25fec35714be80f2d9870af8c92e73cb6d299ba4774f5b0ad842275": "0x00", - "0x121725e2f949944d00a8c011c0db54ae07b84a6ca772adf3c65417345d91522d": "0x0000c16ff28623000000000000000000", - "0xf4adb4c4f708c4b753657373696f6e204e6578744b657973343a73657373696f6e3a6b65797394f72a73893fbd00b11fcce65a014cc5b9ff5066ec15aa6be068b4cabfe67fdb": "0x3919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f437800299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b657973d1ae046d940202772415992434f839d8c546542e3055143c430f7eec87f7cb69": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", - "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b6579732c1312343dce08149336968907c27cc602536aaf7a2b105d6fa07058a3803d31": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663" + "0xbde3e43a2a348359d103d64bc95928146bdd9ae3490e26da38d2e4d19c137507": "0x0000a0dec5adc9353600000000000000", + "0x72143961950b9317e15506626c4524c4": "0x1000299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106", + "0xa902f1f0ef97177b8df9f9fd413768e7": "0x00000000", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b6579730a299be621974fd19374a88f1dddd8442b21db25d2c923907dda6af815b657fe": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0xa978690c6b811e943721dbb6cb9b6246": "0x0000000000000000", + "0x68c8d2f39c4605e65218c22c5664917047e4900c797b7dd33999d94213c75049": "0x047374616b696e67200000c16ff28623000000000000000000ffffffff0e", + "0x7eb7a404bf7e3466c3f6c5914e25edfaab48b1e24fd29ea5a94deaaa1aba80e6": "0x0001547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65019c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", + "0xfd0cbba69a04d769ddcdbb15f5123c98041978f5241f33f78f62b48e3a02b740": "0x047374616b696e67200000c16ff28623000000000000000000ffffffff0e", + "0xbf18c0c65fb39f32ee7c8016685c0a6056f8f924192efb2655be9a692d0b03b6": "0x00", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b65797340944475c781bbdc9726766a78b1964888e039600b1c865c62586ab8f98c171e": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", + "0x8f9a319405d14f3953657373696f6e204b65794f776e6572343a73657373696f6e3a6b6579731143fa96e07eb73af3db3a1b057d18899f864e6fc5d2f905f9296ca641565564": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", + "0x8cb577756012d928f17362e0741f9f2c": "0x01000000", + "0xf186665804ca50670311307912458ce448d82cb96e7e4fe71df38c283a8720f4": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d120f0000c16ff286230f0000c16ff2862300" }, {} ] diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index 40f287445f..01cad95c46 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -283,7 +283,7 @@ mod tests { }; use node_primitives::DigestItem; use node_runtime::{BalancesCall, Call, UncheckedExtrinsic}; - use node_runtime::constants::{currency::CENTS, time::SLOT_DURATION}; + use node_runtime::constants::{currency::CENTS, time::{PRIMARY_PROBABILITY, SLOT_DURATION}}; use codec::{Encode, Decode}; use primitives::{ crypto::Pair as CryptoPair, blake2_256, @@ -404,7 +404,7 @@ mod tests { slot_num, &parent_header, &*service.client(), - (278, 1000), + PRIMARY_PROBABILITY, &keystore, ) { break babe_pre_digest; diff --git a/node/runtime/src/constants.rs b/node/runtime/src/constants.rs index 4108e66bd6..79d3dbd8eb 100644 --- a/node/runtime/src/constants.rs +++ b/node/runtime/src/constants.rs @@ -40,11 +40,19 @@ pub mod time { /// that are expressed in blocks. The rest of the code should use /// `SLOT_DURATION` instead (like the timestamp module for calculating the /// minimum period). + /// + /// If using BABE with secondary slots (default) then all of the slots will + /// always be assigned, in which case `MILLISECS_PER_BLOCK` and + /// `SLOT_DURATION` should have the same value. + /// /// - pub const MILLISECS_PER_BLOCK: Moment = 6000; + pub const MILLISECS_PER_BLOCK: Moment = 3000; pub const SECS_PER_BLOCK: Moment = MILLISECS_PER_BLOCK / 1000; - pub const SLOT_DURATION: Moment = 6000; + pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; + + // 1 in 4 blocks (on average, not counting collisions) will be primary BABE blocks. + pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 10 * MINUTES; pub const EPOCH_DURATION_IN_SLOTS: u64 = { diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index d23e3bb457..783881aac6 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -563,7 +563,7 @@ impl_runtime_apis! { babe_primitives::BabeConfiguration { median_required_blocks: 1000, slot_duration: Babe::slot_duration(), - c: (278, 1000), + c: PRIMARY_PROBABILITY, } } -- GitLab From a2a0eb5398d6223e531455b4c155ef053a4a3a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 28 Aug 2019 19:34:35 +0200 Subject: [PATCH 030/275] CheckEra affects longevity of transactions (#3507) * Add test. * Bump version. --- node/runtime/src/lib.rs | 2 +- srml/system/src/lib.rs | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 783881aac6..0360827e9a 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -80,7 +80,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 154, - impl_version: 154, + impl_version: 155, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index 2343af8bec..54aa3b282a 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -1020,7 +1020,7 @@ impl SignedExtension for CheckNonce { } } -/// Nonce check and increment to give replay protection for transactions. +/// Check for transaction mortality. #[derive(Encode, Decode, Clone, Eq, PartialEq)] pub struct CheckEra((Era, rstd::marker::PhantomData)); @@ -1045,6 +1045,21 @@ impl SignedExtension for CheckEra { type AdditionalSigned = T::Hash; type Pre = (); + fn validate( + &self, + _who: &Self::AccountId, + _call: &Self::Call, + _info: DispatchInfo, + _len: usize, + ) -> Result { + let current_u64 = >::block_number().saturated_into::(); + let valid_till = (self.0).0.death(current_u64); + Ok(ValidTransaction { + longevity: valid_till.saturating_sub(current_u64), + ..Default::default() + }) + } + fn additional_signed(&self) -> Result { let current_u64 = >::block_number().saturated_into::(); let n = (self.0).0.birth(current_u64).saturated_into::(); @@ -1478,4 +1493,23 @@ mod tests { assert!(CheckEra::::from(Era::mortal(4, 12)).additional_signed().is_ok()); }) } + + #[test] + fn signed_ext_check_era_should_change_longevity() { + with_externalities(&mut new_test_ext(), || { + let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal }; + let len = 0_usize; + let ext = ( + CheckWeight::(PhantomData), + CheckEra::::from(Era::mortal(16, 256)), + ); + System::set_block_number(17); + >::insert(16, H256::repeat_byte(1)); + + assert_eq!( + ext.validate(&1, CALL, normal, len).unwrap().longevity, + 15, + ); + }) + } } -- GitLab From a25a8425815c52e3591c12f28e0a7048943aada9 Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Wed, 28 Aug 2019 20:28:09 +0200 Subject: [PATCH 031/275] Codeowners, pt.2 (#3501) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add some more codeowners * Add more rules * Fixes * Update CODEOWNERS * Grandpa -> GRANDPA Co-Authored-By: André Silva * self.add() --- CODEOWNERS | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 6233b87b80..866f165223 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,4 +1,11 @@ -# Lists some code owners +# Lists some code owners. +# +# A codeowner just oversees some part of the codebase. If an owned file is changed then the +# corresponding codeowner receives a review request. An approval of the codeowner is +# not required for merging a PR though. +# +# **This is pretty much an experiment at the moment**. Feel free to remove yourself at any time if +# you do not want to receive review requests any longer. # # For details about syntax, see: # https://help.github.com/en/articles/about-code-owners @@ -11,5 +18,51 @@ # are more recognizable on GitHub, you can use them for mentioning unlike an email. # - The latest matching rule, if multiple, takes precedence. -/srml/contracts/ @pepyakin +# Wasm execution and the wasm side of Substrate Runtime Interface /core/executor/ @pepyakin +/core/sr-io/without_std.rs @pepyakin +/core/sr-std/without_std.rs @pepyakin + +# Sandboxing capability of Substrate Runtime +/core/sr-sandbox/ @pepyakin +/core/primitives/src/sandbox.rs @pepyakin + +# Transaction pool +/core/transaction-pool/ @tomusdrw + +# Offchain +/core/offchain/ @tomusdrw +/sr-io/src/offchain/ @tomusdrw + +# Everything that has RPC in it +/core/rpc/ @tomusdrw +/node/rpc/ @tomusdrw +/node/rpc-client/ @tomusdrw +/core/rpc-servers/ @tomusdrw + +# GRANDPA, BABE, consensus stuff +/srml/babe/ @andresilva @DemiMarie-parity +/srml/grandpa/ @andresilva @DemiMarie-parity +/core/finality-grandpa/ @andresilva @DemiMarie-parity +/core/consensus/babe/ @andresilva @DemiMarie-parity +/core/consensus/slots/ @andresilva @DemiMarie-parity + +# Contracts +/srml/contracts/ @pepyakin @thiolliere @jimpo +/srml/contracts/src/wasm/runtime.rs @Robbepop + +# Inflation points +/srml/staking/src/inflation.rs @thiolliere + +# NPoS and Governance +/srml/staking/ @kianenigma +/srml/election/ @kianenigma + +# End to end testing of substrate node +/node/executor/ @kianenigma + +# Transaction weight stuff +/core/sr-primitives/weights.rs @kianenigma + +# Support crates +/srml/support/ @thiolliere @kianenigma -- GitLab From 7e504ff5db29965a31c96cc2bb8df94a26964416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Wed, 28 Aug 2019 20:15:22 +0100 Subject: [PATCH 032/275] readme: update working flaming fir node commit hash (#3509) --- README.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.adoc b/README.adoc index 91c473c347..dbc3a5e616 100644 --- a/README.adoc +++ b/README.adoc @@ -333,13 +333,13 @@ Flaming Fir is the new testnet for Substrate master (2.0) to test the latest dev Since Flaming Fir is targeting the master branch we make absolutely no guarantees of stability and/or persistence of the network. We might reset the chain at any time if it is necessary to deploy new changes. Currently, the validators are running with a client built from `d013bd900`, if you build from this commit you should be able to successfully sync, later commits may not work as new breaking changes may be introduced in master. -Latest known working version: `d013bd900` +Latest known working version: `a2a0eb5398d6223e531455b4c155ef053a4a3a2b` [source, shell] ---- git clone https://github.com/paritytech/substrate.git cd substrate -git checkout -b flaming-fir d013bd900 +git checkout -b flaming-fir a2a0eb5398d6223e531455b4c155ef053a4a3a2b ---- You can run the tests if you like: -- GitLab From e34cbd16c38ff4325308ae7ecd9106dd14ae124c Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 29 Aug 2019 09:02:10 +0300 Subject: [PATCH 033/275] Use ranged changes trie configuration in CT functions (#3404) * CT config methods are accepting zero * intrduce && use configuration range in CT * Update core/client/db/src/lib.rs Co-Authored-By: cheme * full PR URI * updated next_max_level_digest_range comment * added skewed digest description * added comment for loop * call next_max_level_digest_range from prev_max_level_digest_block * more test cases * Update core/state-machine/src/changes_trie/surface_iterator.rs Co-Authored-By: cheme * updated comment --- core/client/db/src/lib.rs | 4 + core/client/src/client.rs | 28 +- core/client/src/in_mem.rs | 4 + core/client/src/light/fetcher.rs | 20 +- core/primitives/src/changes_trie.rs | 184 ++++++-- core/state-machine/src/changes_trie/build.rs | 334 ++++++++------ .../src/changes_trie/build_iterator.rs | 391 +++++++++++----- .../src/changes_trie/changes_iterator.rs | 418 +++++++++--------- core/state-machine/src/changes_trie/mod.rs | 46 +- core/state-machine/src/changes_trie/prune.rs | 4 +- .../state-machine/src/changes_trie/storage.rs | 32 +- .../src/changes_trie/surface_iterator.rs | 285 ++++++++++++ core/state-machine/src/lib.rs | 1 + 13 files changed, 1258 insertions(+), 493 deletions(-) create mode 100644 core/state-machine/src/changes_trie/surface_iterator.rs diff --git a/core/client/db/src/lib.rs b/core/client/db/src/lib.rs index 927359ecdf..a6301596ad 100644 --- a/core/client/db/src/lib.rs +++ b/core/client/db/src/lib.rs @@ -681,6 +681,10 @@ impl state_machine::ChangesTrieStorage> where Block: BlockT, { + fn as_roots_storage(&self) -> &dyn state_machine::ChangesTrieRootsStorage> { + self + } + fn get(&self, key: &H256, _prefix: Prefix) -> Result, String> { self.db.get(columns::CHANGES_TRIE, &key[..]) .map_err(|err| format!("{}", err)) diff --git a/core/client/src/client.rs b/core/client/src/client.rs index a57584575c..5b0cba3a40 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -43,7 +43,7 @@ use sr_primitives::{ use state_machine::{ DBValue, Backend as StateBackend, CodeExecutor, ChangesTrieAnchorBlockId, ExecutionStrategy, ExecutionManager, prove_read, prove_child_read, - ChangesTrieRootsStorage, ChangesTrieStorage, + ChangesTrieRootsStorage, ChangesTrieStorage, ChangesTrieConfigurationRange, key_changes, key_changes_proof, OverlayedChanges, NeverOffchainExt, }; use executor::{RuntimeVersion, RuntimeInfo}; @@ -554,8 +554,15 @@ impl Client where let last_number = self.backend.blockchain().expect_block_number_from_id(&last)?; let last_hash = self.backend.blockchain().expect_block_hash_from_id(&last)?; - key_changes::<_, Blake2Hasher, _>( - &config, + // FIXME: remove this in https://github.com/paritytech/substrate/pull/3201 + let config_range = ChangesTrieConfigurationRange { + config: &config, + zero: Zero::zero(), + end: None, + }; + + key_changes::( + config_range, &*storage, first, &ChangesTrieAnchorBlockId { @@ -632,6 +639,10 @@ impl Client where } impl<'a, Block: BlockT> ChangesTrieStorage> for AccessedRootsRecorder<'a, Block> { + fn as_roots_storage(&self) -> &dyn state_machine::ChangesTrieRootsStorage> { + self + } + fn get(&self, key: &H256, prefix: Prefix) -> Result, String> { self.storage.get(key, prefix) } @@ -651,13 +662,20 @@ impl Client where self.backend.blockchain().expect_block_number_from_id(&BlockId::Hash(max))?, ); + // FIXME: remove this in https://github.com/paritytech/substrate/pull/3201 + let config_range = ChangesTrieConfigurationRange { + config: &config, + zero: Zero::zero(), + end: None, + }; + // fetch key changes proof let first_number = self.backend.blockchain() .expect_block_number_from_id(&BlockId::Hash(first))?; let last_number = self.backend.blockchain() .expect_block_number_from_id(&BlockId::Hash(last))?; - let key_changes_proof = key_changes_proof::<_, Blake2Hasher, _>( - &config, + let key_changes_proof = key_changes_proof::( + config_range, &recording_storage, first_number, &ChangesTrieAnchorBlockId { diff --git a/core/client/src/in_mem.rs b/core/client/src/in_mem.rs index c43c4e3197..1a6881ea8d 100644 --- a/core/client/src/in_mem.rs +++ b/core/client/src/in_mem.rs @@ -758,6 +758,10 @@ impl state_machine::ChangesTrieStorage> for Change Block: BlockT, H: Hasher, { + fn as_roots_storage(&self) -> &dyn state_machine::ChangesTrieRootsStorage> { + self + } + fn get(&self, key: &H::Out, prefix: Prefix) -> Result, String> { self.0.get(key, prefix) } diff --git a/core/client/src/light/fetcher.rs b/core/client/src/light/fetcher.rs index 22d3e8fdb7..8502a19ba6 100644 --- a/core/client/src/light/fetcher.rs +++ b/core/client/src/light/fetcher.rs @@ -26,11 +26,14 @@ use codec::{Decode, Encode}; use primitives::{ChangesTrieConfiguration, convert_hash}; use sr_primitives::traits::{ Block as BlockT, Header as HeaderT, Hash, HashFor, NumberFor, - SimpleArithmetic, CheckedConversion, + SimpleArithmetic, CheckedConversion, Zero, }; -use state_machine::{CodeExecutor, ChangesTrieRootsStorage, ChangesTrieAnchorBlockId, +use state_machine::{ + CodeExecutor, ChangesTrieRootsStorage, + ChangesTrieAnchorBlockId, ChangesTrieConfigurationRange, TrieBackend, read_proof_check, key_changes_proof_check, - create_proof_check_backend_storage, read_child_proof_check}; + create_proof_check_backend_storage, read_child_proof_check, +}; use crate::cht; use crate::error::{Error as ClientError, Result as ClientResult}; @@ -283,9 +286,16 @@ impl, F> LightDataChecker( - &request.changes_trie_config, + key_changes_proof_check::( + changes_trie_config_range, &RootsStorage { roots: (request.tries_roots.0, &request.tries_roots.2), prev_roots: remote_roots, diff --git a/core/primitives/src/changes_trie.rs b/core/primitives/src/changes_trie.rs index fb7791f0a0..5e88485a03 100644 --- a/core/primitives/src/changes_trie.rs +++ b/core/primitives/src/changes_trie.rs @@ -39,19 +39,30 @@ pub struct ChangesTrieConfiguration { } impl ChangesTrieConfiguration { + /// Create new configuration given digest interval and levels. + pub fn new(digest_interval: u32, digest_levels: u32) -> Self { + Self { digest_interval, digest_levels } + } + /// Is digest build enabled? pub fn is_digest_build_enabled(&self) -> bool { self.digest_interval > 1 && self.digest_levels > 0 } /// Do we need to build digest at given block? - pub fn is_digest_build_required_at_block(&self, block: Number) -> bool + pub fn is_digest_build_required_at_block( + &self, + zero: Number, + block: Number, + ) -> bool where - Number: From + PartialEq + ::rstd::ops::Rem + Zero, + Number: From + PartialEq + + ::rstd::ops::Rem + ::rstd::ops::Sub + + ::rstd::cmp::PartialOrd + Zero, { - block != 0.into() + block > zero && self.is_digest_build_enabled() - && (block % self.digest_interval.into()).is_zero() + && ((block - zero) % self.digest_interval.into()).is_zero() } /// Returns max digest interval. One if digests are not created at all. @@ -71,6 +82,74 @@ impl ChangesTrieConfiguration { } } + /// Returns max level digest block number that has been created at block <= passed block number. + /// + /// Returns None if digests are not created at all. + pub fn prev_max_level_digest_block( + &self, + zero: Number, + block: Number, + ) -> Option + where + Number: Clone + From + PartialOrd + PartialEq + + ::rstd::ops::Add + ::rstd::ops::Sub + + ::rstd::ops::Div + ::rstd::ops::Mul + Zero, + { + if block <= zero { + return None; + } + + let (next_begin, next_end) = self.next_max_level_digest_range(zero.clone(), block.clone())?; + + // if 'next' digest includes our block, then it is a also a previous digest + if next_end == block { + return Some(block); + } + + // if previous digest ends at zero block, then there are no previous digest + let prev_end = next_begin - 1.into(); + if prev_end == zero { + None + } else { + Some(prev_end) + } + } + + /// Returns max level digest blocks range (inclusive) which includes passed block. + /// + /// Returns None if digests are not created at all. + /// It will return the first max-level digest if block is <= zero. + pub fn next_max_level_digest_range( + &self, + zero: Number, + mut block: Number, + ) -> Option<(Number, Number)> + where + Number: Clone + From + PartialOrd + PartialEq + + ::rstd::ops::Add + ::rstd::ops::Sub + + ::rstd::ops::Div + ::rstd::ops::Mul, + { + if !self.is_digest_build_enabled() { + return None; + } + + if block <= zero { + block = zero.clone() + 1.into(); + } + + let max_digest_interval: Number = self.max_digest_interval().into(); + let max_digests_since_zero = (block.clone() - zero.clone()) / max_digest_interval.clone(); + if max_digests_since_zero == 0.into() { + return Some((zero.clone() + 1.into(), zero + max_digest_interval)); + } + let last_max_digest_block = zero + max_digests_since_zero * max_digest_interval.clone(); + Some(if block == last_max_digest_block { + (block.clone() - max_digest_interval + 1.into(), block) + } else { + (last_max_digest_block.clone() + 1.into(), last_max_digest_block + max_digest_interval) + }) + } + /// Returns Some if digest must be built at given block number. /// The tuple is: /// ( @@ -78,20 +157,23 @@ impl ChangesTrieConfiguration { /// digest interval (in blocks) /// step between blocks we're interested in when digest is built /// ) - pub fn digest_level_at_block(&self, block: Number) -> Option<(u32, u32, u32)> + pub fn digest_level_at_block(&self, zero: Number, block: Number) -> Option<(u32, u32, u32)> where - Number: Clone + From + PartialEq + ::rstd::ops::Rem + Zero, + Number: Clone + From + PartialEq + + ::rstd::ops::Rem + ::rstd::ops::Sub + + ::rstd::cmp::PartialOrd + Zero, { - if !self.is_digest_build_required_at_block(block.clone()) { + if !self.is_digest_build_required_at_block(zero.clone(), block.clone()) { return None; } + let relative_block = block - zero; let mut digest_interval = self.digest_interval; let mut current_level = 1u32; let mut digest_step = 1u32; while current_level < self.digest_levels { let new_digest_interval = match digest_interval.checked_mul(self.digest_interval) { - Some(new_digest_interval) if (block.clone() % new_digest_interval.into()).is_zero() + Some(new_digest_interval) if (relative_block.clone() % new_digest_interval.into()).is_zero() => new_digest_interval, _ => break, }; @@ -131,31 +213,43 @@ mod tests { #[test] fn is_digest_build_required_at_block_works() { - assert!(!config(8, 4).is_digest_build_required_at_block(0u64)); - assert!(!config(8, 4).is_digest_build_required_at_block(1u64)); - assert!(!config(8, 4).is_digest_build_required_at_block(2u64)); - assert!(!config(8, 4).is_digest_build_required_at_block(4u64)); - assert!(config(8, 4).is_digest_build_required_at_block(8u64)); - assert!(!config(8, 4).is_digest_build_required_at_block(9u64)); - assert!(config(8, 4).is_digest_build_required_at_block(64u64)); - assert!(config(8, 4).is_digest_build_required_at_block(64u64)); - assert!(config(8, 4).is_digest_build_required_at_block(512u64)); - assert!(config(8, 4).is_digest_build_required_at_block(4096u64)); - assert!(!config(8, 4).is_digest_build_required_at_block(4103u64)); - assert!(config(8, 4).is_digest_build_required_at_block(4104u64)); - assert!(!config(8, 4).is_digest_build_required_at_block(4108u64)); + fn test_with_zero(zero: u64) { + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 0u64)); + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 1u64)); + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 2u64)); + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 4u64)); + assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 8u64)); + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 9u64)); + assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 64u64)); + assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 64u64)); + assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 512u64)); + assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 4096u64)); + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 4103u64)); + assert!(config(8, 4).is_digest_build_required_at_block(zero, zero + 4104u64)); + assert!(!config(8, 4).is_digest_build_required_at_block(zero, zero + 4108u64)); + } + + test_with_zero(0); + test_with_zero(8); + test_with_zero(17); } #[test] fn digest_level_at_block_works() { - assert_eq!(config(8, 4).digest_level_at_block(0u64), None); - assert_eq!(config(8, 4).digest_level_at_block(7u64), None); - assert_eq!(config(8, 4).digest_level_at_block(63u64), None); - assert_eq!(config(8, 4).digest_level_at_block(8u64), Some((1, 8, 1))); - assert_eq!(config(8, 4).digest_level_at_block(64u64), Some((2, 64, 8))); - assert_eq!(config(8, 4).digest_level_at_block(512u64), Some((3, 512, 64))); - assert_eq!(config(8, 4).digest_level_at_block(4096u64), Some((4, 4096, 512))); - assert_eq!(config(8, 4).digest_level_at_block(4112u64), Some((1, 8, 1))); + fn test_with_zero(zero: u64) { + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 0u64), None); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 7u64), None); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 63u64), None); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 8u64), Some((1, 8, 1))); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 64u64), Some((2, 64, 8))); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 512u64), Some((3, 512, 64))); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 4096u64), Some((4, 4096, 512))); + assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 4112u64), Some((1, 8, 1))); + } + + test_with_zero(0); + test_with_zero(8); + test_with_zero(17); } #[test] @@ -165,4 +259,36 @@ mod tests { assert_eq!(config(8, 4).max_digest_interval(), 4096); assert_eq!(config(::std::u32::MAX, 1024).max_digest_interval(), ::std::u32::MAX); } + + #[test] + fn next_max_level_digest_range_works() { + assert_eq!(config(0, 0).next_max_level_digest_range(0u64, 16), None); + assert_eq!(config(1, 1).next_max_level_digest_range(0u64, 16), None); + assert_eq!(config(2, 1).next_max_level_digest_range(0u64, 16), Some((15, 16))); + assert_eq!(config(4, 1).next_max_level_digest_range(0u64, 16), Some((13, 16))); + assert_eq!(config(32, 1).next_max_level_digest_range(0u64, 16), Some((1, 32))); + assert_eq!(config(2, 3).next_max_level_digest_range(0u64, 10), Some((9, 16))); + assert_eq!(config(2, 3).next_max_level_digest_range(0u64, 8), Some((1, 8))); + assert_eq!(config(2, 1).next_max_level_digest_range(1u64, 1), Some((2, 3))); + assert_eq!(config(2, 2).next_max_level_digest_range(7u64, 9), Some((8, 11))); + + assert_eq!(config(2, 2).next_max_level_digest_range(7u64, 5), Some((8, 11))); + } + + #[test] + fn prev_max_level_digest_block_works() { + assert_eq!(config(0, 0).prev_max_level_digest_block(0u64, 16), None); + assert_eq!(config(1, 1).prev_max_level_digest_block(0u64, 16), None); + assert_eq!(config(2, 1).prev_max_level_digest_block(0u64, 16), Some(16)); + assert_eq!(config(4, 1).prev_max_level_digest_block(0u64, 16), Some(16)); + assert_eq!(config(4, 2).prev_max_level_digest_block(0u64, 16), Some(16)); + assert_eq!(config(4, 2).prev_max_level_digest_block(0u64, 17), Some(16)); + assert_eq!(config(4, 2).prev_max_level_digest_block(0u64, 33), Some(32)); + assert_eq!(config(32, 1).prev_max_level_digest_block(0u64, 16), None); + assert_eq!(config(2, 3).prev_max_level_digest_block(0u64, 10), Some(8)); + assert_eq!(config(2, 3).prev_max_level_digest_block(0u64, 8), Some(8)); + assert_eq!(config(2, 2).prev_max_level_digest_block(7u64, 8), None); + + assert_eq!(config(2, 2).prev_max_level_digest_block(7u64, 5), None); + } } diff --git a/core/state-machine/src/changes_trie/build.rs b/core/state-machine/src/changes_trie/build.rs index e1e3f6a808..cc2185ee79 100644 --- a/core/state-machine/src/changes_trie/build.rs +++ b/core/state-machine/src/changes_trie/build.rs @@ -26,22 +26,21 @@ use crate::overlayed_changes::OverlayedChanges; use crate::trie_backend_essence::TrieBackendEssence; use crate::changes_trie::build_iterator::digest_build_iterator; use crate::changes_trie::input::{InputKey, InputPair, DigestIndex, ExtrinsicIndex}; -use crate::changes_trie::{AnchorBlockId, Configuration, Storage, BlockNumber}; +use crate::changes_trie::{AnchorBlockId, ConfigurationRange, Storage, BlockNumber}; /// Prepare input pairs for building a changes trie of given block. /// /// Returns Err if storage error has occurred OR if storage haven't returned /// required data. -pub fn prepare_input<'a, B, S, H, Number>( +pub fn prepare_input<'a, B, H, Number>( backend: &'a B, - storage: &'a S, - config: &'a Configuration, + storage: &'a dyn Storage, + config: ConfigurationRange<'a, Number>, changes: &'a OverlayedChanges, parent: &'a AnchorBlockId, ) -> Result> + 'a, String> where B: Backend, - S: Storage, H: Hasher + 'a, Number: BlockNumber, { @@ -50,7 +49,7 @@ pub fn prepare_input<'a, B, S, H, Number>( backend, &number, changes)?; - let digest_input = prepare_digest_input::<_, H, Number>( + let digest_input = prepare_digest_input::( parent, config, number, @@ -111,19 +110,27 @@ fn prepare_extrinsics_input<'a, B, H, Number>( } /// Prepare DigestIndex input pairs. -fn prepare_digest_input<'a, S, H, Number>( +fn prepare_digest_input<'a, H, Number>( parent: &'a AnchorBlockId, - config: &Configuration, + config: ConfigurationRange<'a, Number>, block: Number, - storage: &'a S + storage: &'a dyn Storage, ) -> Result> + 'a, String> where - S: Storage, H: Hasher, H::Out: 'a, Number: BlockNumber, { - digest_build_iterator(config, block.clone()) + let build_skewed_digest = config.end.as_ref() == Some(&block); + let block_for_digest = if build_skewed_digest { + config.config.next_max_level_digest_range(config.zero.clone(), block.clone()) + .map(|(_, end)| end) + .unwrap_or_else(|| block.clone()) + } else { + block.clone() + }; + + digest_build_iterator(config, block_for_digest) .try_fold(BTreeMap::new(), move |mut map, digest_build_block| { let trie_root = storage.root(parent, digest_build_block.clone())?; let trie_root = trie_root.ok_or_else(|| format!("No changes trie root for block {}", digest_build_block.clone()))?; @@ -177,11 +184,18 @@ mod test { use primitives::Blake2Hasher; use primitives::storage::well_known_keys::EXTRINSIC_INDEX; use crate::backend::InMemory; + use crate::changes_trie::Configuration; use crate::changes_trie::storage::InMemoryStorage; use crate::overlayed_changes::OverlayedValue; use super::*; - fn prepare_for_build() -> (InMemory, InMemoryStorage, OverlayedChanges) { + fn prepare_for_build(zero: u64) -> ( + InMemory, + InMemoryStorage, + OverlayedChanges, + Configuration, + ) { + let config = Configuration { digest_interval: 4, digest_levels: 2 }; let backend: InMemory<_> = vec![ (vec![100], vec![255]), (vec![101], vec![255]), @@ -191,38 +205,38 @@ mod test { (vec![105], vec![255]), ].into_iter().collect::<::std::collections::HashMap<_, _>>().into(); let storage = InMemoryStorage::with_inputs(vec![ - (1, vec![ - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 1, key: vec![100] }, vec![1, 3]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 1, key: vec![101] }, vec![0, 2]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 1, key: vec![105] }, vec![0, 2, 4]), + (zero + 1, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 1, key: vec![100] }, vec![1, 3]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 1, key: vec![101] }, vec![0, 2]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 1, key: vec![105] }, vec![0, 2, 4]), ]), - (2, vec![ - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 2, key: vec![102] }, vec![0]), + (zero + 2, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 2, key: vec![102] }, vec![0]), ]), - (3, vec![ - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 3, key: vec![100] }, vec![0]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 3, key: vec![105] }, vec![1]), + (zero + 3, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 3, key: vec![100] }, vec![0]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 3, key: vec![105] }, vec![1]), ]), - (4, vec![ - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![100] }, vec![0, 2, 3]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![101] }, vec![1]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![103] }, vec![0, 1]), - - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![100] }, vec![1, 3]), - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![101] }, vec![1]), - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![102] }, vec![2]), - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![105] }, vec![1, 3]), + (zero + 4, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![100] }, vec![0, 2, 3]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![101] }, vec![1]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![103] }, vec![0, 1]), + + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![100] }, vec![zero + 1, zero + 3]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![101] }, vec![zero + 1]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![102] }, vec![zero + 2]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![105] }, vec![zero + 1, zero + 3]), ]), - (5, Vec::new()), - (6, vec![ - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 6, key: vec![105] }, vec![2]), + (zero + 5, Vec::new()), + (zero + 6, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 6, key: vec![105] }, vec![2]), ]), - (7, Vec::new()), - (8, vec![ - InputPair::DigestIndex(DigestIndex { block: 8, key: vec![105] }, vec![6]), + (zero + 7, Vec::new()), + (zero + 8, vec![ + InputPair::DigestIndex(DigestIndex { block: zero + 8, key: vec![105] }, vec![zero + 6]), ]), - (9, Vec::new()), (10, Vec::new()), (11, Vec::new()), (12, Vec::new()), (13, Vec::new()), - (14, Vec::new()), (15, Vec::new()), + (zero + 9, Vec::new()), (zero + 10, Vec::new()), (zero + 11, Vec::new()), (zero + 12, Vec::new()), + (zero + 13, Vec::new()), (zero + 14, Vec::new()), (zero + 15, Vec::new()), ]); let changes = OverlayedChanges { prospective: vec![ @@ -249,108 +263,182 @@ mod test { extrinsics: Some(vec![1].into_iter().collect()) }), ].into_iter().collect(), - changes_trie_config: Some(Configuration { digest_interval: 4, digest_levels: 2 }), + changes_trie_config: Some(config.clone()), }; - (backend, storage, changes) + (backend, storage, changes, config) + } + + fn configuration_range<'a>(config: &'a Configuration, zero: u64) -> ConfigurationRange<'a, u64> { + ConfigurationRange { + config, + zero, + end: None, + } } #[test] fn build_changes_trie_nodes_on_non_digest_block() { - let (backend, storage, changes) = prepare_for_build(); - let config = changes.changes_trie_config.as_ref().unwrap(); - let parent = AnchorBlockId { hash: Default::default(), number: 4 }; - let changes_trie_nodes = prepare_input( - &backend, - &storage, - config, - &changes, - &parent, - ).unwrap(); - assert_eq!(changes_trie_nodes.collect::>>(), vec![ - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 5, key: vec![100] }, vec![0, 2, 3]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 5, key: vec![101] }, vec![1]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 5, key: vec![103] }, vec![0, 1]), - ]); + fn test_with_zero(zero: u64) { + let (backend, storage, changes, config) = prepare_for_build(zero); + let parent = AnchorBlockId { hash: Default::default(), number: zero + 4 }; + let changes_trie_nodes = prepare_input( + &backend, + &storage, + configuration_range(&config, zero), + &changes, + &parent, + ).unwrap(); + assert_eq!(changes_trie_nodes.collect::>>(), vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 5, key: vec![100] }, vec![0, 2, 3]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 5, key: vec![101] }, vec![1]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 5, key: vec![103] }, vec![0, 1]), + ]); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); } #[test] fn build_changes_trie_nodes_on_digest_block_l1() { - let (backend, storage, changes) = prepare_for_build(); - let config = changes.changes_trie_config.as_ref().unwrap(); - let parent = AnchorBlockId { hash: Default::default(), number: 3 }; - let changes_trie_nodes = prepare_input( - &backend, - &storage, - config, - &changes, - &parent, - ).unwrap(); - assert_eq!(changes_trie_nodes.collect::>>(), vec![ - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![100] }, vec![0, 2, 3]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![101] }, vec![1]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![103] }, vec![0, 1]), - - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![100] }, vec![1, 3]), - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![101] }, vec![1]), - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![102] }, vec![2]), - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![105] }, vec![1, 3]), - ]); + fn test_with_zero(zero: u64) { + let (backend, storage, changes, config) = prepare_for_build(zero); + let parent = AnchorBlockId { hash: Default::default(), number: zero + 3 }; + let changes_trie_nodes = prepare_input( + &backend, + &storage, + configuration_range(&config, zero), + &changes, + &parent, + ).unwrap(); + assert_eq!(changes_trie_nodes.collect::>>(), vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![100] }, vec![0, 2, 3]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![101] }, vec![1]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![103] }, vec![0, 1]), + + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![100] }, vec![zero + 1, zero + 3]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![101] }, vec![zero + 1]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![102] }, vec![zero + 2]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![105] }, vec![zero + 1, zero + 3]), + ]); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); } #[test] fn build_changes_trie_nodes_on_digest_block_l2() { - let (backend, storage, changes) = prepare_for_build(); - let config = changes.changes_trie_config.as_ref().unwrap(); - let parent = AnchorBlockId { hash: Default::default(), number: 15 }; - let changes_trie_nodes = prepare_input( - &backend, - &storage, - config, - &changes, - &parent, - ).unwrap(); - assert_eq!(changes_trie_nodes.collect::>>(), vec![ - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16, key: vec![100] }, vec![0, 2, 3]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16, key: vec![101] }, vec![1]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16, key: vec![103] }, vec![0, 1]), - - InputPair::DigestIndex(DigestIndex { block: 16, key: vec![100] }, vec![4]), - InputPair::DigestIndex(DigestIndex { block: 16, key: vec![101] }, vec![4]), - InputPair::DigestIndex(DigestIndex { block: 16, key: vec![102] }, vec![4]), - InputPair::DigestIndex(DigestIndex { block: 16, key: vec![103] }, vec![4]), - InputPair::DigestIndex(DigestIndex { block: 16, key: vec![105] }, vec![4, 8]), - ]); + fn test_with_zero(zero: u64) { + let (backend, storage, changes, config) = prepare_for_build(zero); + let parent = AnchorBlockId { hash: Default::default(), number: zero + 15 }; + let changes_trie_nodes = prepare_input( + &backend, + &storage, + configuration_range(&config, zero), + &changes, + &parent, + ).unwrap(); + assert_eq!(changes_trie_nodes.collect::>>(), vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 16, key: vec![100] }, vec![0, 2, 3]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 16, key: vec![101] }, vec![1]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 16, key: vec![103] }, vec![0, 1]), + + InputPair::DigestIndex(DigestIndex { block: zero + 16, key: vec![100] }, vec![zero + 4]), + InputPair::DigestIndex(DigestIndex { block: zero + 16, key: vec![101] }, vec![zero + 4]), + InputPair::DigestIndex(DigestIndex { block: zero + 16, key: vec![102] }, vec![zero + 4]), + InputPair::DigestIndex(DigestIndex { block: zero + 16, key: vec![103] }, vec![zero + 4]), + InputPair::DigestIndex(DigestIndex { block: zero + 16, key: vec![105] }, vec![zero + 4, zero + 8]), + ]); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); + } + + #[test] + fn build_changes_trie_nodes_on_skewed_digest_block() { + fn test_with_zero(zero: u64) { + let (backend, storage, changes, config) = prepare_for_build(zero); + let parent = AnchorBlockId { hash: Default::default(), number: zero + 10 }; + + let mut configuration_range = configuration_range(&config, zero); + let changes_trie_nodes = prepare_input( + &backend, + &storage, + configuration_range.clone(), + &changes, + &parent, + ).unwrap(); + assert_eq!(changes_trie_nodes.collect::>>(), vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 11, key: vec![100] }, vec![0, 2, 3]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 11, key: vec![101] }, vec![1]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 11, key: vec![103] }, vec![0, 1]), + ]); + + configuration_range.end = Some(zero + 11); + let changes_trie_nodes = prepare_input( + &backend, + &storage, + configuration_range, + &changes, + &parent, + ).unwrap(); + assert_eq!(changes_trie_nodes.collect::>>(), vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 11, key: vec![100] }, vec![0, 2, 3]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 11, key: vec![101] }, vec![1]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 11, key: vec![103] }, vec![0, 1]), + + InputPair::DigestIndex(DigestIndex { block: zero + 11, key: vec![100] }, vec![zero + 4]), + InputPair::DigestIndex(DigestIndex { block: zero + 11, key: vec![101] }, vec![zero + 4]), + InputPair::DigestIndex(DigestIndex { block: zero + 11, key: vec![102] }, vec![zero + 4]), + InputPair::DigestIndex(DigestIndex { block: zero + 11, key: vec![103] }, vec![zero + 4]), + InputPair::DigestIndex(DigestIndex { block: zero + 11, key: vec![105] }, vec![zero + 4, zero + 8]), + ]); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); } #[test] fn build_changes_trie_nodes_ignores_temporary_storage_values() { - let (backend, storage, mut changes) = prepare_for_build(); - - // 110: missing from backend, set to None in overlay - changes.prospective.top.insert(vec![110], OverlayedValue { - value: None, - extrinsics: Some(vec![1].into_iter().collect()) - }); - - let config = changes.changes_trie_config.as_ref().unwrap(); - let parent = AnchorBlockId { hash: Default::default(), number: 3 }; - let changes_trie_nodes = prepare_input( - &backend, - &storage, - config, - &changes, - &parent, - ).unwrap(); - assert_eq!(changes_trie_nodes.collect::>>(), vec![ - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![100] }, vec![0, 2, 3]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![101] }, vec![1]), - InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![103] }, vec![0, 1]), - - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![100] }, vec![1, 3]), - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![101] }, vec![1]), - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![102] }, vec![2]), - InputPair::DigestIndex(DigestIndex { block: 4, key: vec![105] }, vec![1, 3]), - ]); + fn test_with_zero(zero: u64) { + let (backend, storage, mut changes, config) = prepare_for_build(zero); + + // 110: missing from backend, set to None in overlay + changes.prospective.top.insert(vec![110], OverlayedValue { + value: None, + extrinsics: Some(vec![1].into_iter().collect()) + }); + + let parent = AnchorBlockId { hash: Default::default(), number: zero + 3 }; + let changes_trie_nodes = prepare_input( + &backend, + &storage, + configuration_range(&config, zero), + &changes, + &parent, + ).unwrap(); + assert_eq!(changes_trie_nodes.collect::>>(), vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![100] }, vec![0, 2, 3]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![101] }, vec![1]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![103] }, vec![0, 1]), + + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![100] }, vec![zero + 1, zero + 3]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![101] }, vec![zero + 1]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![102] }, vec![zero + 2]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![105] }, vec![zero + 1, zero + 3]), + ]); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); } } diff --git a/core/state-machine/src/changes_trie/build_iterator.rs b/core/state-machine/src/changes_trie/build_iterator.rs index f4fff28765..36b6dd1983 100644 --- a/core/state-machine/src/changes_trie/build_iterator.rs +++ b/core/state-machine/src/changes_trie/build_iterator.rs @@ -17,59 +17,73 @@ //! Structures and functions to return blocks whose changes are to be included //! in given block's changes trie. -use crate::changes_trie::{Configuration, BlockNumber}; +use num_traits::Zero; +use crate::changes_trie::{ConfigurationRange, BlockNumber}; /// Returns iterator of OTHER blocks that are required for inclusion into /// changes trie of given block. Blocks are guaranteed to be returned in /// ascending order. -pub fn digest_build_iterator( - config: &Configuration, +/// +/// Skewed digest is built IF block >= config.end. +pub fn digest_build_iterator<'a, Number: BlockNumber>( + config: ConfigurationRange<'a, Number>, block: Number, ) -> DigestBuildIterator { // prepare digest build parameters - let (_, _, digest_step) = match config.digest_level_at_block(block.clone()) { + let (_, _, digest_step) = match config.config.digest_level_at_block(config.zero, block.clone()) { Some((current_level, digest_interval, digest_step)) => (current_level, digest_interval, digest_step), None => return DigestBuildIterator::empty(), }; - DigestBuildIterator::new(block, config.digest_interval, digest_step) + DigestBuildIterator::new(block.clone(), config.end.unwrap_or(block), config.config.digest_interval, digest_step) } /// Changes trie build iterator that returns numbers of OTHER blocks that are /// required for inclusion into changes trie of given block. #[derive(Debug)] pub struct DigestBuildIterator { - /// Block we're building changes trie for. + /// Block we're building changes trie for. It could (logically) be a post-end block if we are creating + /// skewed digest. block: Number, - /// Interval for creation digest blocks. + /// Block that is a last block where current configuration is active. We have never yet created anything + /// after this block => digest that we're creating can't reference any blocks that are >= end. + end: Number, + /// Interval of L1 digest blocks. digest_interval: u32, - /// Max step of blocks range. + /// Max step that could be used when digest is created. max_step: u32, + + // Mutable data below: + /// Step of current blocks range. current_step: u32, /// Reverse step of current blocks range. current_step_reverse: u32, /// Current blocks range. current_range: Option>, + /// Last block that we have returned. + last_block: Option, } impl DigestBuildIterator { /// Create new digest build iterator. - pub fn new(block: Number, digest_interval: u32, max_step: u32) -> Self { + pub fn new(block: Number, end: Number, digest_interval: u32, max_step: u32) -> Self { DigestBuildIterator { block, + end, digest_interval, max_step, current_step: max_step, current_step_reverse: 0, current_range: None, + last_block: None, } } /// Create empty digest build iterator. pub fn empty() -> Self { - Self::new(0.into(), 0, 0) + Self::new(Zero::zero(), Zero::zero(), 0, 0) } } @@ -77,39 +91,44 @@ impl Iterator for DigestBuildIterator { type Item = Number; fn next(&mut self) -> Option { - if let Some(next) = self.current_range.as_mut().and_then(|iter| iter.next()) { - return Some(next); - } - - // we are safe to use non-checking mul/sub versions here because: - // DigestBuildIterator is created only by internal function that is checking - // that all multiplications/subtractions are safe within max_step limit - - let next_step_reverse = if self.current_step_reverse == 0 { - 1 - } else { - self.current_step_reverse * self.digest_interval - }; - if next_step_reverse > self.max_step { - return None; + // when we're building skewed digest, we might want to skip some blocks if + // they're not covered by current configuration + loop { + if let Some(next) = self.current_range.as_mut().and_then(|iter| iter.next()) { + if next < self.end { + self.last_block = Some(next.clone()); + return Some(next); + } + } + + // we are safe to use non-checking mul/sub versions here because: + // DigestBuildIterator is created only by internal function that is checking + // that all multiplications/subtractions are safe within max_step limit + + let next_step_reverse = if self.current_step_reverse == 0 { + 1 + } else { + self.current_step_reverse * self.digest_interval + }; + if next_step_reverse > self.max_step { + return None; + } + + self.current_step_reverse = next_step_reverse; + self.current_range = Some(BlocksRange::new( + match self.last_block.clone() { + Some(last_block) => last_block + self.current_step.into(), + None => self.block.clone() - (self.current_step * self.digest_interval - self.current_step).into(), + }, + self.block.clone(), + self.current_step.into(), + )); + + self.current_step = self.current_step / self.digest_interval; + if self.current_step == 0 { + self.current_step = 1; + } } - - self.current_step_reverse = next_step_reverse; - self.current_range = Some(BlocksRange::new( - self.block.clone() - (self.current_step * self.digest_interval - self.current_step).into(), - self.block.clone(), - self.current_step.into(), - )); - - self.current_step = self.current_step / self.digest_interval; - if self.current_step == 0 { - self.current_step = 1; - } - - Some(self.current_range.as_mut() - .expect("assigned one line above; qed") - .next() - .expect("X - I^(N+1) + I^N > X when X,I,N are > 1; qed")) } } @@ -147,102 +166,266 @@ impl Iterator for BlocksRange { #[cfg(test)] mod tests { + use crate::changes_trie::Configuration; use super::*; - fn digest_build_iterator(digest_interval: u32, digest_levels: u32, block: u64) -> DigestBuildIterator { - super::digest_build_iterator(&Configuration { digest_interval, digest_levels }, block) + fn digest_build_iterator( + digest_interval: u32, + digest_levels: u32, + zero: u64, + block: u64, + end: Option, + ) -> DigestBuildIterator { + super::digest_build_iterator( + ConfigurationRange { + config: &Configuration { + digest_interval, + digest_levels, + }, + zero, + end, + }, + block, + ) } - fn digest_build_iterator_basic(digest_interval: u32, digest_levels: u32, block: u64) -> (u64, u32, u32) { - let iter = digest_build_iterator(digest_interval, digest_levels, block); + fn digest_build_iterator_basic( + digest_interval: u32, + digest_levels: u32, + zero: u64, + block: u64, + ) -> (u64, u32, u32) { + let iter = digest_build_iterator(digest_interval, digest_levels, zero, block, None); (iter.block, iter.digest_interval, iter.max_step) } - fn digest_build_iterator_blocks(digest_interval: u32, digest_levels: u32, block: u64) -> Vec { - digest_build_iterator(digest_interval, digest_levels, block).collect() + fn digest_build_iterator_blocks( + digest_interval: u32, + digest_levels: u32, + zero: u64, + block: u64, + end: Option, + ) -> Vec { + digest_build_iterator(digest_interval, digest_levels, zero, block, end).collect() } #[test] fn suggest_digest_inclusion_returns_empty_iterator() { - let empty = (0, 0, 0); - assert_eq!(digest_build_iterator_basic(4, 16, 0), empty, "block is 0"); - assert_eq!(digest_build_iterator_basic(0, 16, 64), empty, "digest_interval is 0"); - assert_eq!(digest_build_iterator_basic(1, 16, 64), empty, "digest_interval is 1"); - assert_eq!(digest_build_iterator_basic(4, 0, 64), empty, "digest_levels is 0"); - assert_eq!(digest_build_iterator_basic(4, 16, 1), empty, "digest is not required for this block"); - assert_eq!(digest_build_iterator_basic(4, 16, 2), empty, "digest is not required for this block"); - assert_eq!(digest_build_iterator_basic(4, 16, 15), empty, "digest is not required for this block"); - assert_eq!(digest_build_iterator_basic(4, 16, 17), empty, "digest is not required for this block"); - assert_eq!(digest_build_iterator_basic( - ::std::u32::MAX / 2 + 1, - 16, - ::std::u64::MAX, - ), empty, "digest_interval * 2 is greater than u64::MAX"); + fn test_with_zero(zero: u64) { + let empty = (0, 0, 0); + assert_eq!(digest_build_iterator_basic(4, 16, zero, zero + 0), empty, "block is 0"); + assert_eq!(digest_build_iterator_basic(0, 16, zero, zero + 64), empty, "digest_interval is 0"); + assert_eq!(digest_build_iterator_basic(1, 16, zero, zero + 64), empty, "digest_interval is 1"); + assert_eq!(digest_build_iterator_basic(4, 0, zero, zero + 64), empty, "digest_levels is 0"); + assert_eq!( + digest_build_iterator_basic(4, 16, zero, zero + 1), + empty, + "digest is not required for this block", + ); + assert_eq!( + digest_build_iterator_basic(4, 16, zero, zero + 2), + empty, + "digest is not required for this block", + ); + assert_eq!( + digest_build_iterator_basic(4, 16, zero, zero + 15), + empty, + "digest is not required for this block", + ); + assert_eq!( + digest_build_iterator_basic(4, 16, zero, zero + 17), + empty, + "digest is not required for this block", + ); + assert_eq!(digest_build_iterator_basic( + ::std::u32::MAX / 2 + 1, + 16, + zero, + ::std::u64::MAX, + ), empty, "digest_interval * 2 is greater than u64::MAX"); + } + + test_with_zero(0); + test_with_zero(1); + test_with_zero(2); + test_with_zero(4); + test_with_zero(17); } #[test] fn suggest_digest_inclusion_returns_level1_iterator() { - assert_eq!(digest_build_iterator_basic(16, 1, 16), (16, 16, 1), "!(block % interval) && first digest level == block"); - assert_eq!(digest_build_iterator_basic(16, 1, 256), (256, 16, 1), "!(block % interval^2), but there's only 1 digest level"); - assert_eq!(digest_build_iterator_basic(16, 2, 32), (32, 16, 1), "second level digest is not required for this block"); - assert_eq!(digest_build_iterator_basic(16, 3, 4080), (4080, 16, 1), "second && third level digest are not required for this block"); + fn test_with_zero(zero: u64) { + assert_eq!( + digest_build_iterator_basic(16, 1, zero, zero + 16), + (zero + 16, 16, 1), + "!(block % interval) && first digest level == block", + ); + assert_eq!( + digest_build_iterator_basic(16, 1, zero, zero + 256), + (zero + 256, 16, 1), + "!(block % interval^2), but there's only 1 digest level", + ); + assert_eq!( + digest_build_iterator_basic(16, 2, zero, zero + 32), + (zero + 32, 16, 1), + "second level digest is not required for this block", + ); + assert_eq!( + digest_build_iterator_basic(16, 3, zero, zero + 4080), + (zero + 4080, 16, 1), + "second && third level digest are not required for this block", + ); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); } #[test] fn suggest_digest_inclusion_returns_level2_iterator() { - assert_eq!(digest_build_iterator_basic(16, 2, 256), (256, 16, 16), "second level digest"); - assert_eq!(digest_build_iterator_basic(16, 2, 4096), (4096, 16, 16), "!(block % interval^3), but there's only 2 digest levels"); + fn test_with_zero(zero: u64) { + assert_eq!( + digest_build_iterator_basic(16, 2, zero, zero + 256), + (zero + 256, 16, 16), + "second level digest", + ); + assert_eq!( + digest_build_iterator_basic(16, 2, zero, zero + 4096), + (zero + 4096, 16, 16), + "!(block % interval^3), but there's only 2 digest levels", + ); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); } #[test] fn suggest_digest_inclusion_returns_level3_iterator() { - assert_eq!(digest_build_iterator_basic(16, 3, 4096), (4096, 16, 256), "third level digest: beginning"); - assert_eq!(digest_build_iterator_basic(16, 3, 8192), (8192, 16, 256), "third level digest: next"); + fn test_with_zero(zero: u64) { + assert_eq!( + digest_build_iterator_basic(16, 3, zero, zero + 4096), + (zero + 4096, 16, 256), + "third level digest: beginning", + ); + assert_eq!( + digest_build_iterator_basic(16, 3, zero, zero + 8192), + (zero + 8192, 16, 256), + "third level digest: next", + ); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); } #[test] fn digest_iterator_returns_level1_blocks() { - assert_eq!(digest_build_iterator_blocks(16, 1, 16), - vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); - assert_eq!(digest_build_iterator_blocks(16, 1, 256), - vec![241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255]); - assert_eq!(digest_build_iterator_blocks(16, 2, 32), - vec![17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]); - assert_eq!(digest_build_iterator_blocks(16, 3, 4080), - vec![4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4076, 4077, 4078, 4079]); + fn test_with_zero(zero: u64) { + assert_eq!(digest_build_iterator_blocks(16, 1, zero, zero + 16, None), + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + .iter().map(|item| zero + item).collect::>()); + assert_eq!(digest_build_iterator_blocks(16, 1, zero, zero + 256, None), + [241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255] + .iter().map(|item| zero + item).collect::>()); + assert_eq!(digest_build_iterator_blocks(16, 2, zero, zero + 32, None), + [17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] + .iter().map(|item| zero + item).collect::>()); + assert_eq!(digest_build_iterator_blocks(16, 3, zero, zero + 4080, None), + [4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4076, 4077, 4078, 4079] + .iter().map(|item| zero + item).collect::>()); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); } #[test] fn digest_iterator_returns_level1_and_level2_blocks() { - assert_eq!(digest_build_iterator_blocks(16, 2, 256), - vec![ - // level2 points to previous 16-1 level1 digests: - 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, - // level2 is a level1 digest of 16-1 previous blocks: - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - ], - ); - assert_eq!(digest_build_iterator_blocks(16, 2, 4096), - vec![ - // level2 points to previous 16-1 level1 digests: - 3856, 3872, 3888, 3904, 3920, 3936, 3952, 3968, 3984, 4000, 4016, 4032, 4048, 4064, 4080, - // level2 is a level1 digest of 16-1 previous blocks: - 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4089, 4090, 4091, 4092, 4093, 4094, 4095, - ], - ); + fn test_with_zero(zero: u64) { + assert_eq!(digest_build_iterator_blocks(16, 2, zero, zero + 256, None), + [ + // level2 points to previous 16-1 level1 digests: + 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, + // level2 is a level1 digest of 16-1 previous blocks: + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, + ].iter().map(|item| zero + item).collect::>(), + ); + assert_eq!(digest_build_iterator_blocks(16, 2, zero, zero + 4096, None), + [ + // level2 points to previous 16-1 level1 digests: + 3856, 3872, 3888, 3904, 3920, 3936, 3952, 3968, 3984, 4000, 4016, 4032, 4048, 4064, 4080, + // level2 is a level1 digest of 16-1 previous blocks: + 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4089, 4090, 4091, 4092, 4093, 4094, 4095, + ].iter().map(|item| zero + item).collect::>(), + ); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); } #[test] fn digest_iterator_returns_level1_and_level2_and_level3_blocks() { - assert_eq!(digest_build_iterator_blocks(16, 3, 4096), - vec![ - // level3 points to previous 16-1 level2 digests: - 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, - // level3 points to previous 16-1 level1 digests: - 3856, 3872, 3888, 3904, 3920, 3936, 3952, 3968, 3984, 4000, 4016, 4032, 4048, 4064, 4080, - // level3 is a level1 digest of 16-1 previous blocks: - 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4089, 4090, 4091, 4092, 4093, 4094, 4095, - ], - ); + fn test_with_zero(zero: u64) { + assert_eq!(digest_build_iterator_blocks(16, 3, zero, zero + 4096, None), + [ + // level3 points to previous 16-1 level2 digests: + 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, + // level3 points to previous 16-1 level1 digests: + 3856, 3872, 3888, 3904, 3920, 3936, 3952, 3968, 3984, 4000, 4016, 4032, 4048, 4064, 4080, + // level3 is a level1 digest of 16-1 previous blocks: + 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4089, 4090, 4091, 4092, 4093, 4094, 4095, + ].iter().map(|item| zero + item).collect::>(), + ); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); + } + + #[test] + fn digest_iterator_returns_skewed_digest_blocks() { + fn test_with_zero(zero: u64) { + assert_eq!(digest_build_iterator_blocks(16, 3, zero, zero + 4096, Some(zero + 1338)), + [ + // level3 MUST point to previous 16-1 level2 digests, BUT there are only 5: + 256, 512, 768, 1024, 1280, + // level3 MUST point to previous 16-1 level1 digests, BUT there are only 3: + 1296, 1312, 1328, + // level3 MUST be a level1 digest of 16-1 previous blocks, BUT there are only 9: + 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, + ].iter().map(|item| zero + item).collect::>(), + ); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); + } + + #[test] + fn digest_iterator_returns_skewed_digest_blocks_skipping_level() { + fn test_with_zero(zero: u64) { + assert_eq!(digest_build_iterator_blocks(16, 3, zero, zero + 4096, Some(zero + 1284)), + [ + // level3 MUST point to previous 16-1 level2 digests, BUT there are only 5: + 256, 512, 768, 1024, 1280, + // level3 MUST point to previous 16-1 level1 digests, BUT there are NO ANY L1-digests: + // level3 MUST be a level1 digest of 16-1 previous blocks, BUT there are only 3: + 1281, 1282, 1283, + ].iter().map(|item| zero + item).collect::>(), + ); + } + + test_with_zero(0); + test_with_zero(16); + test_with_zero(17); } } diff --git a/core/state-machine/src/changes_trie/changes_iterator.rs b/core/state-machine/src/changes_trie/changes_iterator.rs index f7342cc60f..397bc89857 100644 --- a/core/state-machine/src/changes_trie/changes_iterator.rs +++ b/core/state-machine/src/changes_trie/changes_iterator.rs @@ -20,37 +20,44 @@ use std::cell::RefCell; use std::collections::VecDeque; use codec::{Decode, Encode}; -use hash_db::{HashDB, Hasher, EMPTY_PREFIX}; -use num_traits::One; -use trie::{Recorder, MemoryDB}; -use crate::changes_trie::{AnchorBlockId, Configuration, RootsStorage, Storage, BlockNumber}; +use hash_db::Hasher; +use num_traits::Zero; +use trie::Recorder; +use crate::changes_trie::{AnchorBlockId, ConfigurationRange, RootsStorage, Storage, BlockNumber}; use crate::changes_trie::input::{DigestIndex, ExtrinsicIndex, DigestIndexValue, ExtrinsicIndexValue}; use crate::changes_trie::storage::{TrieBackendAdapter, InMemoryStorage}; +use crate::changes_trie::surface_iterator::{surface_iterator, SurfaceIterator}; use crate::proving_backend::ProvingBackendEssence; use crate::trie_backend_essence::{TrieBackendEssence}; /// Return changes of given key at given blocks range. /// `max` is the number of best known block. /// Changes are returned in descending order (i.e. last block comes first). -pub fn key_changes<'a, S: Storage, H: Hasher, Number: BlockNumber>( - config: &'a Configuration, - storage: &'a S, +pub fn key_changes<'a, H: Hasher, Number: BlockNumber>( + config: ConfigurationRange<'a, Number>, + storage: &'a dyn Storage, begin: Number, end: &'a AnchorBlockId, max: Number, key: &'a [u8], -) -> Result, String> { +) -> Result, String> { // we can't query any roots before root let max = ::std::cmp::min(max.clone(), end.number.clone()); Ok(DrilldownIterator { essence: DrilldownIteratorEssence { key, - roots_storage: storage, + roots_storage: storage.as_roots_storage(), storage, begin: begin.clone(), end, - surface: surface_iterator(config, max, begin, end.number.clone())?, + config: config.clone(), + surface: surface_iterator( + config, + max, + begin, + end.number.clone(), + )?, extrinsics: Default::default(), blocks: Default::default(), @@ -62,9 +69,9 @@ pub fn key_changes<'a, S: Storage, H: Hasher, Number: BlockNumber>( /// Returns proof of changes of given key at given blocks range. /// `max` is the number of best known block. -pub fn key_changes_proof, H: Hasher, Number: BlockNumber>( - config: &Configuration, - storage: &S, +pub fn key_changes_proof<'a, H: Hasher, Number: BlockNumber>( + config: ConfigurationRange<'a, Number>, + storage: &dyn Storage, begin: Number, end: &AnchorBlockId, max: Number, @@ -76,11 +83,17 @@ pub fn key_changes_proof, H: Hasher, Number: BlockNumber>( let mut iter = ProvingDrilldownIterator { essence: DrilldownIteratorEssence { key, - roots_storage: storage.clone(), + roots_storage: storage.as_roots_storage(), storage, begin: begin.clone(), end, - surface: surface_iterator(config, max, begin, end.number.clone())?, + config: config.clone(), + surface: surface_iterator( + config, + max, + begin, + end.number.clone(), + )?, extrinsics: Default::default(), blocks: Default::default(), @@ -101,32 +114,53 @@ pub fn key_changes_proof, H: Hasher, Number: BlockNumber>( /// Check key changes proof and return changes of the key at given blocks range. /// `max` is the number of best known block. /// Changes are returned in descending order (i.e. last block comes first). -pub fn key_changes_proof_check, H: Hasher, Number: BlockNumber>( - config: &Configuration, - roots_storage: &S, +pub fn key_changes_proof_check<'a, H: Hasher, Number: BlockNumber>( + config: ConfigurationRange<'a, Number>, + roots_storage: &dyn RootsStorage, proof: Vec>, begin: Number, end: &AnchorBlockId, max: Number, key: &[u8] +) -> Result, String> { + key_changes_proof_check_with_db( + config, + roots_storage, + &InMemoryStorage::with_proof(proof), + begin, + end, + max, + key, + ) +} + +/// Similar to the `key_changes_proof_check` function, but works with prepared proof storage. +pub fn key_changes_proof_check_with_db<'a, H: Hasher, Number: BlockNumber>( + config: ConfigurationRange<'a, Number>, + roots_storage: &dyn RootsStorage, + proof_db: &InMemoryStorage, + begin: Number, + end: &AnchorBlockId, + max: Number, + key: &[u8] ) -> Result, String> { // we can't query any roots before root let max = ::std::cmp::min(max.clone(), end.number.clone()); - let mut proof_db = MemoryDB::::default(); - for item in proof { - proof_db.insert(EMPTY_PREFIX, &item); - } - - let proof_db = InMemoryStorage::with_db(proof_db); DrilldownIterator { essence: DrilldownIteratorEssence { key, roots_storage, - storage: &proof_db, + storage: proof_db, begin: begin.clone(), end, - surface: surface_iterator(config, max, begin, end.number.clone())?, + config: config.clone(), + surface: surface_iterator( + config, + max, + begin, + end.number.clone(), + )?, extrinsics: Default::default(), blocks: Default::default(), @@ -136,87 +170,37 @@ pub fn key_changes_proof_check, H: Hasher, Number: Bl }.collect() } -/// Surface iterator - only traverses top-level digests from given range and tries to find -/// all digest changes for the key. -pub struct SurfaceIterator<'a, Number: BlockNumber> { - config: &'a Configuration, - begin: Number, - max: Number, - current: Option, - current_begin: Number, - digest_step: u32, - digest_level: u32, -} - -impl<'a, Number: BlockNumber> Iterator for SurfaceIterator<'a, Number> { - type Item = Result<(Number, u32), String>; - - fn next(&mut self) -> Option { - let current = self.current.clone()?; - let digest_level = self.digest_level; - - if current < self.digest_step.into() { - self.current = None; - } - else { - let next = current.clone() - self.digest_step.into(); - if next.is_zero() || next < self.begin { - self.current = None; - } - else if next > self.current_begin { - self.current = Some(next); - } else { - let (current, current_begin, digest_step, digest_level) = match - lower_bound_max_digest(self.config, self.max.clone(), self.begin.clone(), next) { - Err(err) => return Some(Err(err)), - Ok(range) => range, - }; - - self.current = Some(current); - self.current_begin = current_begin; - self.digest_step = digest_step; - self.digest_level = digest_level; - } - } - - Some(Ok((current, digest_level))) - } -} - /// Drilldown iterator - receives 'digest points' from surface iterator and explores /// every point until extrinsic is found. -pub struct DrilldownIteratorEssence<'a, RS, S, H, Number> +pub struct DrilldownIteratorEssence<'a, H, Number> where - RS: 'a + RootsStorage, - S: 'a + Storage, H: Hasher, Number: BlockNumber, H::Out: 'a, { key: &'a [u8], - roots_storage: &'a RS, - storage: &'a S, + roots_storage: &'a dyn RootsStorage, + storage: &'a dyn Storage, begin: Number, end: &'a AnchorBlockId, + config: ConfigurationRange<'a, Number>, surface: SurfaceIterator<'a, Number>, extrinsics: VecDeque<(Number, u32)>, - blocks: VecDeque<(Number, u32)>, + blocks: VecDeque<(Number, Option)>, _hasher: ::std::marker::PhantomData, } -impl<'a, RS, S, H, Number> DrilldownIteratorEssence<'a, RS, S, H, Number> +impl<'a, H, Number> DrilldownIteratorEssence<'a, H, Number> where - RS: 'a + RootsStorage, - S: 'a + Storage, H: Hasher, Number: BlockNumber, H::Out: 'a, { pub fn next(&mut self, trie_reader: F) -> Option> where - F: FnMut(&S, H::Out, &[u8]) -> Result>, String>, + F: FnMut(&dyn Storage, H::Out, &[u8]) -> Result>, String>, { match self.do_next(trie_reader) { Ok(Some(res)) => Some(Ok(res)), @@ -227,7 +211,7 @@ impl<'a, RS, S, H, Number> DrilldownIteratorEssence<'a, RS, S, H, Number> fn do_next(&mut self, mut trie_reader: F) -> Result, String> where - F: FnMut(&S, H::Out, &[u8]) -> Result>, String>, + F: FnMut(&dyn Storage, H::Out, &[u8]) -> Result>, String>, { loop { if let Some((block, extrinsic)) = self.extrinsics.pop_front() { @@ -247,7 +231,7 @@ impl<'a, RS, S, H, Number> DrilldownIteratorEssence<'a, RS, S, H, Number> debug_assert!(block >= self.begin, "We shall not touch digests earlier than a range' begin"); if block <= self.end.number { let extrinsics_key = ExtrinsicIndex { block: block.clone(), key: self.key.to_vec() }.encode(); - let extrinsics = trie_reader(&self.storage, trie_root, &extrinsics_key); + let extrinsics = trie_reader(self.storage, trie_root, &extrinsics_key); if let Some(extrinsics) = extrinsics? { if let Ok(extrinsics) = ExtrinsicIndexValue::decode(&mut &extrinsics[..]) { self.extrinsics.extend(extrinsics.into_iter().rev().map(|e| (block.clone(), e))); @@ -256,17 +240,26 @@ impl<'a, RS, S, H, Number> DrilldownIteratorEssence<'a, RS, S, H, Number> } let blocks_key = DigestIndex { block: block.clone(), key: self.key.to_vec() }.encode(); - let blocks = trie_reader(&self.storage, trie_root, &blocks_key); + let blocks = trie_reader(self.storage, trie_root, &blocks_key); if let Some(blocks) = blocks? { if let Ok(blocks) = >::decode(&mut &blocks[..]) { // filter level0 blocks here because we tend to use digest blocks, // AND digest block changes could also include changes for out-of-range blocks let begin = self.begin.clone(); let end = self.end.number.clone(); + let config = self.config.clone(); self.blocks.extend(blocks.into_iter() .rev() - .filter(|b| level > 1 || (*b >= begin && *b <= end)) - .map(|b| (b, level - 1)) + .filter(|b| level.map(|level| level > 1).unwrap_or(true) || (*b >= begin && *b <= end)) + .map(|b| { + let prev_level = level + .map(|level| Some(level - 1)) + .unwrap_or_else(|| + Some(config.config.digest_level_at_block(config.zero.clone(), b.clone()) + .map(|(level, _, _)| level) + .unwrap_or_else(|| Zero::zero()))); + (b, prev_level) + }) ); } } @@ -284,19 +277,17 @@ impl<'a, RS, S, H, Number> DrilldownIteratorEssence<'a, RS, S, H, Number> } /// Exploring drilldown operator. -pub struct DrilldownIterator<'a, RS, S, H, Number> +pub struct DrilldownIterator<'a, H, Number> where Number: BlockNumber, H: Hasher, - S: 'a + Storage, - RS: 'a + RootsStorage, H::Out: 'a, { - essence: DrilldownIteratorEssence<'a, RS, S, H, Number>, + essence: DrilldownIteratorEssence<'a, H, Number>, } -impl<'a, RS: 'a + RootsStorage, S: Storage, H: Hasher, Number: BlockNumber> Iterator - for DrilldownIterator<'a, RS, S, H, Number> +impl<'a, H: Hasher, Number: BlockNumber> Iterator + for DrilldownIterator<'a, H, Number> { type Item = Result<(Number, u32), String>; @@ -307,24 +298,20 @@ impl<'a, RS: 'a + RootsStorage, S: Storage, H: Hasher, Num } /// Proving drilldown iterator. -struct ProvingDrilldownIterator<'a, RS, S, H, Number> +struct ProvingDrilldownIterator<'a, H, Number> where Number: BlockNumber, H: Hasher, - S: 'a + Storage, - RS: 'a + RootsStorage, H::Out: 'a, { - essence: DrilldownIteratorEssence<'a, RS, S, H, Number>, + essence: DrilldownIteratorEssence<'a, H, Number>, proof_recorder: RefCell>, } -impl<'a, RS, S, H, Number> ProvingDrilldownIterator<'a, RS, S, H, Number> +impl<'a, H, Number> ProvingDrilldownIterator<'a, H, Number> where Number: BlockNumber, H: Hasher, - S: 'a + Storage, - RS: 'a + RootsStorage, H::Out: 'a, { /// Consume the iterator, extracting the gathered proof in lexicographical order @@ -337,12 +324,10 @@ impl<'a, RS, S, H, Number> ProvingDrilldownIterator<'a, RS, S, H, Number> } } -impl<'a, RS, S, H, Number> Iterator for ProvingDrilldownIterator<'a, RS, S, H, Number> +impl<'a, H, Number> Iterator for ProvingDrilldownIterator<'a, H, Number> where Number: BlockNumber, H: Hasher, - S: 'a + Storage, - RS: 'a + RootsStorage, H::Out: 'a, { type Item = Result<(Number, u32), String>; @@ -358,90 +343,11 @@ impl<'a, RS, S, H, Number> Iterator for ProvingDrilldownIterator<'a, RS, S, H, N } } -/// Returns surface iterator for given range of blocks. -fn surface_iterator<'a, Number: BlockNumber>( - config: &'a Configuration, - max: Number, - begin: Number, - end: Number, -) -> Result, String> { - let (current, current_begin, digest_step, digest_level) = lower_bound_max_digest( - config, - max.clone(), - begin.clone(), - end, - )?; - Ok(SurfaceIterator { - config, - begin, - max, - current: Some(current), - current_begin, - digest_step, - digest_level, - }) -} - -/// Returns parameters of highest level digest block that includes the end of given range -/// and tends to include the whole range. -fn lower_bound_max_digest( - config: &Configuration, - max: Number, - begin: Number, - end: Number, -) -> Result<(Number, Number, u32, u32), String> { - if end > max || begin > end { - return Err("invalid changes range".into()); - } - - let mut digest_level = 0u32; - let mut digest_step = 1u32; - let mut digest_interval = 0u32; - let mut current = end.clone(); - let mut current_begin = begin.clone(); - if current_begin != current { - while digest_level != config.digest_levels { - let new_digest_level = digest_level + 1; - let new_digest_step = digest_step * config.digest_interval; - let new_digest_interval = config.digest_interval * { - if digest_interval == 0 { 1 } else { digest_interval } - }; - let new_digest_begin = ((current.clone() - One::one()) - / new_digest_interval.into()) * new_digest_interval.into(); - let new_digest_end = new_digest_begin.clone() + new_digest_interval.into(); - let new_current = new_digest_begin.clone() + new_digest_interval.into(); - - if new_digest_end > max { - if begin < new_digest_begin { - current_begin = new_digest_begin; - } - break; - } - - digest_level = new_digest_level; - digest_step = new_digest_step; - digest_interval = new_digest_interval; - current = new_current; - current_begin = new_digest_begin; - - if current_begin <= begin && new_digest_end >= end { - break; - } - } - } - - Ok(( - current, - current_begin, - digest_step, - digest_level, - )) -} - #[cfg(test)] mod tests { use std::iter::FromIterator; use primitives::Blake2Hasher; + use crate::changes_trie::Configuration; use crate::changes_trie::input::InputPair; use crate::changes_trie::storage::InMemoryStorage; use super::*; @@ -485,32 +391,75 @@ mod tests { (config, backend) } + fn configuration_range<'a>(config: &'a Configuration, zero: u64) -> ConfigurationRange<'a, u64> { + ConfigurationRange { + config, + zero, + end: None, + } + } + #[test] fn drilldown_iterator_works() { let (config, storage) = prepare_for_drilldown(); - let drilldown_result = key_changes::, Blake2Hasher, u64>( - &config, &storage, 0, &AnchorBlockId { hash: Default::default(), number: 16 }, 16, &[42]) - .and_then(Result::from_iter); + let drilldown_result = key_changes::( + configuration_range(&config, 0), + &storage, + 1, + &AnchorBlockId { hash: Default::default(), number: 16 }, + 16, + &[42], + ).and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![(8, 2), (8, 1), (6, 3), (3, 0)])); - let drilldown_result = key_changes::, Blake2Hasher, u64>( - &config, &storage, 0, &AnchorBlockId { hash: Default::default(), number: 2 }, 4, &[42]) - .and_then(Result::from_iter); + let drilldown_result = key_changes::( + configuration_range(&config, 0), + &storage, + 1, + &AnchorBlockId { hash: Default::default(), number: 2 }, + 4, + &[42], + ).and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![])); - let drilldown_result = key_changes::, Blake2Hasher, u64>( - &config, &storage, 0, &AnchorBlockId { hash: Default::default(), number: 3 }, 4, &[42]) - .and_then(Result::from_iter); + let drilldown_result = key_changes::( + configuration_range(&config, 0), + &storage, + 1, + &AnchorBlockId { hash: Default::default(), number: 3 }, + 4, + &[42], + ).and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![(3, 0)])); - let drilldown_result = key_changes::, Blake2Hasher, u64>( - &config, &storage, 7, &AnchorBlockId { hash: Default::default(), number: 8 }, 8, &[42]) - .and_then(Result::from_iter); + let drilldown_result = key_changes::( + configuration_range(&config, 0), + &storage, + 1, + &AnchorBlockId { hash: Default::default(), number: 7 }, + 7, + &[42], + ).and_then(Result::from_iter); + assert_eq!(drilldown_result, Ok(vec![(6, 3), (3, 0)])); + + let drilldown_result = key_changes::( + configuration_range(&config, 0), + &storage, + 7, + &AnchorBlockId { hash: Default::default(), number: 8 }, + 8, + &[42], + ).and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![(8, 2), (8, 1)])); - let drilldown_result = key_changes::, Blake2Hasher, u64>( - &config, &storage, 5, &AnchorBlockId { hash: Default::default(), number: 7 }, 8, &[42]) - .and_then(Result::from_iter); + let drilldown_result = key_changes::( + configuration_range(&config, 0), + &storage, + 5, + &AnchorBlockId { hash: Default::default(), number: 7 }, + 8, + &[42], + ).and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![(6, 3)])); } @@ -519,18 +468,35 @@ mod tests { let (config, storage) = prepare_for_drilldown(); storage.clear_storage(); - assert!(key_changes::, Blake2Hasher, u64>( - &config, &storage, 0, &AnchorBlockId { hash: Default::default(), number: 100 }, 1000, &[42]) - .and_then(|i| i.collect::, _>>()).is_err()); + assert!(key_changes::( + configuration_range(&config, 0), + &storage, + 1, + &AnchorBlockId { hash: Default::default(), number: 100 }, + 1000, + &[42], + ).and_then(|i| i.collect::, _>>()).is_err()); } #[test] fn drilldown_iterator_fails_when_range_is_invalid() { let (config, storage) = prepare_for_drilldown(); - assert!(key_changes::, Blake2Hasher, u64>( - &config, &storage, 0, &AnchorBlockId { hash: Default::default(), number: 100 }, 50, &[42]).is_err()); - assert!(key_changes::, Blake2Hasher, u64>( - &config, &storage, 20, &AnchorBlockId { hash: Default::default(), number: 10 }, 100, &[42]).is_err()); + assert!(key_changes::( + configuration_range(&config, 0), + &storage, + 1, + &AnchorBlockId { hash: Default::default(), number: 100 }, + 50, + &[42], + ).is_err()); + assert!(key_changes::( + configuration_range(&config, 0), + &storage, + 20, + &AnchorBlockId { hash: Default::default(), number: 10 }, + 100, + &[42], + ).is_err()); } @@ -540,20 +506,48 @@ mod tests { // create drilldown iterator that records all trie nodes during drilldown let (remote_config, remote_storage) = prepare_for_drilldown(); - let remote_proof = key_changes_proof::, Blake2Hasher, u64>( - &remote_config, &remote_storage, - 0, &AnchorBlockId { hash: Default::default(), number: 16 }, 16, &[42]).unwrap(); + let remote_proof = key_changes_proof::( + configuration_range(&remote_config, 0), &remote_storage, + 1, &AnchorBlockId { hash: Default::default(), number: 16 }, 16, &[42]).unwrap(); // happens on local light node: // create drilldown iterator that works the same, but only depends on trie let (local_config, local_storage) = prepare_for_drilldown(); local_storage.clear_storage(); - let local_result = key_changes_proof_check::, Blake2Hasher, u64>( - &local_config, &local_storage, remote_proof, - 0, &AnchorBlockId { hash: Default::default(), number: 16 }, 16, &[42]); + let local_result = key_changes_proof_check::( + configuration_range(&local_config, 0), &local_storage, remote_proof, + 1, &AnchorBlockId { hash: Default::default(), number: 16 }, 16, &[42]); // check that drilldown result is the same as if it was happening at the full node assert_eq!(local_result, Ok(vec![(8, 2), (8, 1), (6, 3), (3, 0)])); } + + #[test] + fn drilldown_iterator_works_with_skewed_digest() { + let config = Configuration { digest_interval: 4, digest_levels: 3 }; + let mut config_range = configuration_range(&config, 0); + config_range.end = Some(91); + + // when 4^3 deactivates at block 91: + // last L3 digest has been created at block#64 + // skewed digest covers: + // L2 digests at blocks: 80 + // L1 digests at blocks: 84, 88 + // regular blocks: 89, 90, 91 + let mut input = (1u64..92u64).map(|b| (b, vec![])).collect::>(); + // changed at block#63 and covered by L3 digest at block#64 + input[63 - 1].1.push(InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 63, key: vec![42] }, vec![0])); + input[64 - 1].1.push(InputPair::DigestIndex(DigestIndex { block: 64, key: vec![42] }, vec![63])); + // changed at block#79 and covered by L2 digest at block#80 + skewed digest at block#91 + input[79 - 1].1.push(InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 79, key: vec![42] }, vec![1])); + input[80 - 1].1.push(InputPair::DigestIndex(DigestIndex { block: 80, key: vec![42] }, vec![79])); + input[91 - 1].1.push(InputPair::DigestIndex(DigestIndex { block: 91, key: vec![42] }, vec![80])); + let storage = InMemoryStorage::with_inputs(input); + + let drilldown_result = key_changes::( + config_range, &storage, 1, &AnchorBlockId { hash: Default::default(), number: 91 }, 100_000u64, &[42]) + .and_then(Result::from_iter); + assert_eq!(drilldown_result, Ok(vec![(79, 1), (63, 0)])); + } } diff --git a/core/state-machine/src/changes_trie/mod.rs b/core/state-machine/src/changes_trie/mod.rs index b29a515d74..5a607cee01 100644 --- a/core/state-machine/src/changes_trie/mod.rs +++ b/core/state-machine/src/changes_trie/mod.rs @@ -32,6 +32,19 @@ //! the last N*digest_level-1 blocks (except for genesis block), mapping these keys //! to the set of lower-level digest blocks. //! +//! Changes trie configuration could change within a time. The range of blocks, where +//! configuration has been active, is given by two blocks: zero and end. Zero block is +//! the block where configuration has been set. But the first changes trie that uses +//! this configuration will be built at the block zero+1. If configuration deactivates +//! at some block, this will be the end block of the configuration. It is also the +//! zero block of the next configuration. +//! +//! If configuration has the end block, it also means that 'skewed digest' has/should +//! been built at that block. If this is the block where max-level digest should have +//! been created, than it is simply max-level digest of this configuration. Otherwise, +//! it is the digest that covers all blocks since last max-level digest block was +//! created. +//! //! Changes trie only contains the top level storage changes. Sub-level changes //! are propagated through its storage root on the top level storage. @@ -41,11 +54,16 @@ mod changes_iterator; mod input; mod prune; mod storage; +mod surface_iterator; pub use self::storage::InMemoryStorage; -pub use self::changes_iterator::{key_changes, key_changes_proof, key_changes_proof_check}; +pub use self::changes_iterator::{ + key_changes, key_changes_proof, + key_changes_proof_check, key_changes_proof_check_with_db, +}; pub use self::prune::{prune, oldest_non_pruned_trie}; +use std::convert::TryInto; use hash_db::{Hasher, Prefix}; use crate::backend::Backend; use num_traits::{One, Zero}; @@ -64,7 +82,7 @@ pub trait BlockNumber: Send + Sync + 'static + ::std::fmt::Display + Clone + - From + One + Zero + + From + TryInto + One + Zero + PartialEq + Ord + ::std::ops::Add + ::std::ops::Sub + ::std::ops::Mul + ::std::ops::Div + @@ -78,7 +96,7 @@ impl BlockNumber for T where T: Send + Sync + 'static + ::std::fmt::Display + Clone + - From + One + Zero + + From + TryInto + One + Zero + PartialEq + Ord + ::std::ops::Add + ::std::ops::Sub + ::std::ops::Mul + ::std::ops::Div + @@ -108,6 +126,8 @@ pub trait RootsStorage: Send + Sync { /// Changes trie storage. Provides access to trie roots and trie nodes. pub trait Storage: RootsStorage { + /// Casts from self reference to RootsStorage reference. + fn as_roots_storage(&self) -> &dyn RootsStorage; /// Get a trie node. fn get(&self, key: &H::Out, prefix: Prefix) -> Result, String>; } @@ -126,6 +146,17 @@ impl<'a, H: Hasher, N: BlockNumber> crate::TrieBackendStorage for TrieBackend /// Changes trie configuration. pub type Configuration = primitives::ChangesTrieConfiguration; +/// Blocks range where configuration has been constant. +#[derive(Clone)] +pub struct ConfigurationRange<'a, N> { + /// Active configuration. + pub config: &'a Configuration, + /// Zero block of this configuration. The configuration is active starting from the next block. + pub zero: N, + /// End block of this configuration. It is the last block where configuration has been active. + pub end: Option, +} + /// Compute the changes trie root and transaction for given block. /// Returns Err(()) if unknown `parent_hash` has been passed. /// Returns Ok(None) if there's no data to perform computation. @@ -144,11 +175,18 @@ pub fn build_changes_trie<'a, B: Backend, S: Storage, H: Hasher, N _ => return Ok(None), }; + // FIXME: remove this in https://github.com/paritytech/substrate/pull/3201 + let config = ConfigurationRange { + config, + zero: Zero::zero(), + end: None, + }; + // build_anchor error should not be considered fatal let parent = storage.build_anchor(parent_hash).map_err(|_| ())?; // storage errors are considered fatal (similar to situations when runtime fetches values from storage) - let input_pairs = prepare_input::(backend, storage, config, changes, &parent) + let input_pairs = prepare_input::(backend, storage, config, changes, &parent) .expect("changes trie: storage access is not allowed to fail within runtime"); let mut root = Default::default(); let mut mdb = MemoryDB::default(); diff --git a/core/state-machine/src/changes_trie/prune.rs b/core/state-machine/src/changes_trie/prune.rs index 08e7c02b8c..01d52b23ce 100644 --- a/core/state-machine/src/changes_trie/prune.rs +++ b/core/state-machine/src/changes_trie/prune.rs @@ -19,7 +19,7 @@ use hash_db::Hasher; use trie::Recorder; use log::warn; -use num_traits::One; +use num_traits::{One, Zero}; use crate::proving_backend::ProvingBackendEssence; use crate::trie_backend_essence::TrieBackendEssence; use crate::changes_trie::{AnchorBlockId, Configuration, Storage, BlockNumber}; @@ -110,7 +110,7 @@ fn pruning_range( // compute number of changes tries we actually want to keep let (prune_interval, blocks_to_keep) = if config.is_digest_build_enabled() { // we only CAN prune at block where max-level-digest is created - let max_digest_interval = match config.digest_level_at_block(block.clone()) { + let max_digest_interval = match config.digest_level_at_block(Zero::zero(), block.clone()) { Some((digest_level, digest_interval, _)) if digest_level == config.digest_levels => digest_interval, _ => return None, diff --git a/core/state-machine/src/changes_trie/storage.rs b/core/state-machine/src/changes_trie/storage.rs index bb2256235a..4cf7741763 100644 --- a/core/state-machine/src/changes_trie/storage.rs +++ b/core/state-machine/src/changes_trie/storage.rs @@ -17,7 +17,7 @@ //! Changes trie storage utilities. use std::collections::BTreeMap; -use hash_db::{Hasher, Prefix}; +use hash_db::{Hasher, Prefix, EMPTY_PREFIX}; use trie::DBValue; use trie::MemoryDB; use parking_lot::RwLock; @@ -37,8 +37,8 @@ pub struct InMemoryStorage { } /// Adapter for using changes trie storage as a TrieBackendEssence' storage. -pub struct TrieBackendAdapter<'a, H: Hasher, Number: BlockNumber, S: 'a + Storage> { - storage: &'a S, +pub struct TrieBackendAdapter<'a, H: Hasher, Number: BlockNumber> { + storage: &'a dyn Storage, _hasher: ::std::marker::PhantomData<(H, Number)>, } @@ -48,7 +48,7 @@ struct InMemoryStorageData { } impl InMemoryStorage { - /// Create the storage from given in-memory database. + /// Creates storage from given in-memory database. pub fn with_db(mdb: MemoryDB) -> Self { Self { data: RwLock::new(InMemoryStorageData { @@ -58,11 +58,22 @@ impl InMemoryStorage { } } - /// Create the storage with empty database. + /// Creates storage with empty database. pub fn new() -> Self { Self::with_db(Default::default()) } + /// Creates storage with given proof. + pub fn with_proof(proof: Vec>) -> Self { + use hash_db::HashDB; + + let mut proof_db = MemoryDB::::default(); + for item in proof { + proof_db.insert(EMPTY_PREFIX, &item); + } + Self::with_db(proof_db) + } + /// Create the storage with given blocks. pub fn with_blocks(blocks: Vec<(Number, H::Out)>) -> Self { Self { @@ -132,20 +143,23 @@ impl RootsStorage for InMemoryStorage } impl Storage for InMemoryStorage { + fn as_roots_storage(&self) -> &dyn RootsStorage { + self + } + fn get(&self, key: &H::Out, prefix: Prefix) -> Result, String> { MemoryDB::::get(&self.data.read().mdb, key, prefix) } } -impl<'a, H: Hasher, Number: BlockNumber, S: 'a + Storage> TrieBackendAdapter<'a, H, Number, S> { - pub fn new(storage: &'a S) -> Self { +impl<'a, H: Hasher, Number: BlockNumber> TrieBackendAdapter<'a, H, Number> { + pub fn new(storage: &'a dyn Storage) -> Self { Self { storage, _hasher: Default::default() } } } -impl<'a, H, Number, S> TrieBackendStorage for TrieBackendAdapter<'a, H, Number, S> +impl<'a, H, Number> TrieBackendStorage for TrieBackendAdapter<'a, H, Number> where - S: 'a + Storage, Number: BlockNumber, H: Hasher, { diff --git a/core/state-machine/src/changes_trie/surface_iterator.rs b/core/state-machine/src/changes_trie/surface_iterator.rs new file mode 100644 index 0000000000..f3583e2f57 --- /dev/null +++ b/core/state-machine/src/changes_trie/surface_iterator.rs @@ -0,0 +1,285 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! The best way to understand how this iterator works is to imagine some 2D terrain that have some mountains +//! (digest changes tries) and valleys (changes tries for regular blocks). There are gems (blocks) beneath the +//! terrain. Given the request to find all gems in the range [X1; X2] this iterator will return **minimal set** +//! of points at the terrain (mountains and valleys) inside this range that have to be drilled down to +//! search for gems. + +use num_traits::One; +use crate::changes_trie::{ConfigurationRange, BlockNumber}; + +/// Returns surface iterator for given range of blocks. +/// +/// `max` is the number of best block, known to caller. We can't access any changes tries +/// that are built after this block, even though we may have them built already. +pub fn surface_iterator<'a, Number: BlockNumber>( + config: ConfigurationRange<'a, Number>, + max: Number, + begin: Number, + end: Number, +) -> Result, String> { + let (current, current_begin, digest_step, digest_level) = lower_bound_max_digest( + config.clone(), + max.clone(), + begin.clone(), + end, + )?; + Ok(SurfaceIterator { + config, + begin, + max, + current: Some(current), + current_begin, + digest_step, + digest_level, + }) +} + +/// Surface iterator - only traverses top-level digests from given range and tries to find +/// all valid digest changes. +/// +/// Iterator item is the tuple of (last block of the current point + digest level of the current point). +/// Digest level is Some(0) when it is regular block, is Some(non-zero) when it is digest block and None +/// if it is skewed digest block. +pub struct SurfaceIterator<'a, Number: BlockNumber> { + config: ConfigurationRange<'a, Number>, + begin: Number, + max: Number, + current: Option, + current_begin: Number, + digest_step: u32, + digest_level: Option, +} + +impl<'a, Number: BlockNumber> Iterator for SurfaceIterator<'a, Number> { + type Item = Result<(Number, Option), String>; + + fn next(&mut self) -> Option { + let current = self.current.clone()?; + let digest_level = self.digest_level; + + if current < self.digest_step.into() { + self.current = None; + } else { + let next = current.clone() - self.digest_step.into(); + if next.is_zero() || next < self.begin { + self.current = None; + } else if next > self.current_begin { + self.current = Some(next); + } else { + let max_digest_interval = lower_bound_max_digest( + self.config.clone(), + self.max.clone(), + self.begin.clone(), + next, + ); + let (current, current_begin, digest_step, digest_level) = match max_digest_interval { + Err(err) => return Some(Err(err)), + Ok(range) => range, + }; + + self.current = Some(current); + self.current_begin = current_begin; + self.digest_step = digest_step; + self.digest_level = digest_level; + } + } + + Some(Ok((current, digest_level))) + } +} + +/// Returns parameters of highest level digest block that includes the end of given range +/// and tends to include the whole range. +fn lower_bound_max_digest<'a, Number: BlockNumber>( + config: ConfigurationRange<'a, Number>, + max: Number, + begin: Number, + end: Number, +) -> Result<(Number, Number, u32, Option), String> { + if end > max || begin > end { + return Err(format!("invalid changes range: {}..{}/{}", begin, end, max)); + } + if begin <= config.zero || config.end.as_ref().map(|config_end| end > *config_end).unwrap_or(false) { + return Err(format!("changes trie range is not covered by configuration: {}..{}/{}..{}", + begin, end, config.zero, match config.end.as_ref() { + Some(config_end) => format!("{}", config_end), + None => "None".into(), + })); + } + + let mut digest_level = 0u32; + let mut digest_step = 1u32; + let mut digest_interval = 0u32; + let mut current = end.clone(); + let mut current_begin = begin.clone(); + if current_begin != current { + while digest_level != config.config.digest_levels { + // try to use next level digest + let new_digest_level = digest_level + 1; + let new_digest_step = digest_step * config.config.digest_interval; + let new_digest_interval = config.config.digest_interval * { + if digest_interval == 0 { 1 } else { digest_interval } + }; + let new_digest_begin = config.zero.clone() + ((current.clone() - One::one() - config.zero.clone()) + / new_digest_interval.into()) * new_digest_interval.into(); + let new_digest_end = new_digest_begin.clone() + new_digest_interval.into(); + let new_current = new_digest_begin.clone() + new_digest_interval.into(); + + // check if we met skewed digest + if let Some(skewed_digest_end) = config.end.as_ref() { + if new_digest_end > *skewed_digest_end { + let skewed_digest_start = config.config.prev_max_level_digest_block( + config.zero.clone(), + skewed_digest_end.clone(), + ); + if let Some(skewed_digest_start) = skewed_digest_start { + let skewed_digest_range = (skewed_digest_end.clone() - skewed_digest_start.clone()) + .try_into().ok() + .expect("skewed digest range is always <= max level digest range;\ + max level digest range always fits u32; qed"); + return Ok(( + skewed_digest_end.clone(), + skewed_digest_start, + skewed_digest_range, + None, + )); + } + } + } + + // we can't use next level digest if it touches any unknown (> max) blocks + if new_digest_end > max { + if begin < new_digest_begin { + current_begin = new_digest_begin; + } + break; + } + + // we can (and will) use this digest + digest_level = new_digest_level; + digest_step = new_digest_step; + digest_interval = new_digest_interval; + current = new_current; + current_begin = new_digest_begin; + + // if current digest covers the whole range => no need to use next level digest + if current_begin <= begin && new_digest_end >= end { + break; + } + } + } + + Ok(( + current, + current_begin, + digest_step, + Some(digest_level), + )) +} + +#[cfg(test)] +mod tests { + use crate::changes_trie::{Configuration}; + use super::*; + + fn configuration_range<'a>(config: &'a Configuration, zero: u64) -> ConfigurationRange<'a, u64> { + ConfigurationRange { + config, + zero, + end: None, + } + } + + #[test] + fn lower_bound_max_digest_works() { + let config = Configuration { digest_interval: 4, digest_levels: 2 }; + + // when config activates at 0 + assert_eq!( + lower_bound_max_digest(configuration_range(&config, 0u64), 100_000u64, 20u64, 180u64).unwrap(), + (192, 176, 16, Some(2)), + ); + + // when config activates at 30 + assert_eq!( + lower_bound_max_digest(configuration_range(&config, 30u64), 100_000u64, 50u64, 210u64).unwrap(), + (222, 206, 16, Some(2)), + ); + } + + #[test] + fn surface_iterator_works() { + let config = Configuration { digest_interval: 4, digest_levels: 2 }; + + // when config activates at 0 + assert_eq!( + surface_iterator( + configuration_range(&config, 0u64), + 100_000u64, + 40u64, + 180u64, + ).unwrap().collect::>(), + vec![ + Ok((192, Some(2))), Ok((176, Some(2))), Ok((160, Some(2))), Ok((144, Some(2))), + Ok((128, Some(2))), Ok((112, Some(2))), Ok((96, Some(2))), Ok((80, Some(2))), + Ok((64, Some(2))), Ok((48, Some(2))), + ], + ); + + // when config activates at 30 + assert_eq!( + surface_iterator( + configuration_range(&config, 30u64), + 100_000u64, + 40u64, + 180u64, + ).unwrap().collect::>(), + vec![ + Ok((190, Some(2))), Ok((174, Some(2))), Ok((158, Some(2))), Ok((142, Some(2))), Ok((126, Some(2))), + Ok((110, Some(2))), Ok((94, Some(2))), Ok((78, Some(2))), Ok((62, Some(2))), Ok((46, Some(2))), + ], + ); + + // when config activates at 0 AND max block is before next digest + assert_eq!( + surface_iterator(configuration_range(&config, 0u64), 183u64, 40u64, 183u64).unwrap().collect::>(), + vec![ + Ok((183, Some(0))), Ok((182, Some(0))), Ok((181, Some(0))), Ok((180, Some(1))), + Ok((176, Some(2))), Ok((160, Some(2))), Ok((144, Some(2))), Ok((128, Some(2))), Ok((112, Some(2))), + Ok((96, Some(2))), Ok((80, Some(2))), Ok((64, Some(2))), Ok((48, Some(2))), + ], + ); + } + + #[test] + fn surface_iterator_works_with_skewed_digest() { + let config = Configuration { digest_interval: 4, digest_levels: 2 }; + let mut config_range = configuration_range(&config, 0u64); + + // when config activates at 0 AND ends at 170 + config_range.end = Some(170); + assert_eq!( + surface_iterator(config_range, 100_000u64, 40u64, 170u64).unwrap().collect::>(), + vec![ + Ok((170, None)), Ok((160, Some(2))), Ok((144, Some(2))), Ok((128, Some(2))), Ok((112, Some(2))), + Ok((96, Some(2))), Ok((80, Some(2))), Ok((64, Some(2))), Ok((48, Some(2))), + ], + ); + } +} diff --git a/core/state-machine/src/lib.rs b/core/state-machine/src/lib.rs index 8c2046e591..acc7c366b8 100644 --- a/core/state-machine/src/lib.rs +++ b/core/state-machine/src/lib.rs @@ -50,6 +50,7 @@ pub use changes_trie::{ Storage as ChangesTrieStorage, RootsStorage as ChangesTrieRootsStorage, InMemoryStorage as InMemoryChangesTrieStorage, + ConfigurationRange as ChangesTrieConfigurationRange, key_changes, key_changes_proof, key_changes_proof_check, prune as prune_changes_tries, oldest_non_pruned_trie as oldest_non_pruned_changes_trie -- GitLab From b14ce6de08ae219cee5587031446b74b1942627b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 29 Aug 2019 09:06:51 +0200 Subject: [PATCH 034/275] Make it easier to just rebuild the WASM files (#3510) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Adds `WASM_TARGET_DIRECTORY` env variable to `wasm-builder` * Create the `wasm-builder-runner`'s in a common workspace * Make `wasm-builder` trigger less rebuilds * Version up * Adds script for building only the WASM files * Apply suggestions from code review Co-Authored-By: André Silva Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> --- Cargo.lock | 22 +++---- README.adoc | 2 + core/executor/runtime-test/build.rs | 2 +- core/test-runtime/build.rs | 2 +- core/utils/wasm-builder-runner/Cargo.toml | 2 +- core/utils/wasm-builder-runner/src/lib.rs | 71 +++++++++++++++------ core/utils/wasm-builder/Cargo.toml | 6 +- core/utils/wasm-builder/src/lib.rs | 42 +++++++++--- core/utils/wasm-builder/src/wasm_project.rs | 58 ++++++++++++++--- node-template/runtime/build.rs | 2 +- node/runtime/build.rs | 2 +- scripts/build-only-wasm.sh | 29 +++++++++ 12 files changed, 182 insertions(+), 58 deletions(-) create mode 100755 scripts/build-only-wasm.sh diff --git a/Cargo.lock b/Cargo.lock index b1936f4177..6cb7232ecf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2467,7 +2467,7 @@ dependencies = [ "substrate-offchain-primitives 2.0.0", "substrate-primitives 2.0.0", "substrate-session 2.0.0", - "substrate-wasm-builder-runner 1.0.2", + "substrate-wasm-builder-runner 1.0.3", ] [[package]] @@ -2976,7 +2976,7 @@ name = "proc-macro-crate" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5020,7 +5020,7 @@ dependencies = [ "sr-sandbox 2.0.0", "sr-std 2.0.0", "substrate-primitives 2.0.0", - "substrate-wasm-builder-runner 1.0.2", + "substrate-wasm-builder-runner 1.0.3", ] [[package]] @@ -5201,7 +5201,7 @@ dependencies = [ "substrate-state-machine 2.0.0", "substrate-test-runtime-client 2.0.0", "substrate-trie 2.0.0", - "substrate-wasm-builder-runner 1.0.2", + "substrate-wasm-builder-runner 1.0.3", "trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5269,24 +5269,24 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" -version = "1.0.4" +version = "1.0.5" dependencies = [ "build-helper 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "substrate-wasm-builder-runner" version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "substrate-wasm-builder-runner" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" +version = "1.0.3" [[package]] name = "subtle" @@ -5643,7 +5643,7 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5727,7 +5727,7 @@ dependencies = [ "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6641,7 +6641,7 @@ dependencies = [ "checksum tokio-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "354b8cd83825b3c20217a9dc174d6a0c67441a2fae5c41bcb1ea6679f6ae0f7c" "checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92" "checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" -"checksum toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b8c96d7873fa7ef8bdeb3a9cda3ac48389b4154f32b9803b4bc26220b677b039" +"checksum toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724" "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" "checksum trie-bench 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3073600c543ed001319d7e092c46dfd8c245af1a218ec5c75eb01582660a2b3e" "checksum trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d0b62d27e8aa1c07414549ac872480ac82380bab39e730242ab08d82d7cc098a" diff --git a/README.adoc b/README.adoc index dbc3a5e616..4d8bc466f5 100644 --- a/README.adoc +++ b/README.adoc @@ -321,6 +321,8 @@ we support multiple environment variables: * `TRIGGER_WASM_BUILD` - Can be set to trigger a WASM build. On subsequent calls the value of the variable needs to change. As WASM builder instructs `cargo` to watch for file changes this environment variable should only be required in certain circumstances. +* `WASM_TARGET_DIRECTORY` - Will copy any build WASM binary to the given directory. The path needs + to be absolute. Each project can be skipped individually by using the environment variable `SKIP_PROJECT_NAME_WASM_BUILD`. Where `PROJECT_NAME` needs to be replaced by the name of the cargo project, e.g. `node-runtime` will diff --git a/core/executor/runtime-test/build.rs b/core/executor/runtime-test/build.rs index 86bc3ad7fa..3ebf28739b 100644 --- a/core/executor/runtime-test/build.rs +++ b/core/executor/runtime-test/build.rs @@ -21,7 +21,7 @@ fn main() { "wasm_binary.rs", WasmBuilderSource::CratesOrPath { path: "../../utils/wasm-builder", - version: "1.0.4", + version: "1.0.5", }, // This instructs LLD to export __heap_base as a global variable, which is used by the // external memory allocator. diff --git a/core/test-runtime/build.rs b/core/test-runtime/build.rs index e412123b94..041704f37d 100644 --- a/core/test-runtime/build.rs +++ b/core/test-runtime/build.rs @@ -21,7 +21,7 @@ fn main() { "wasm_binary.rs", WasmBuilderSource::CratesOrPath { path: "../utils/wasm-builder", - version: "1.0.4", + version: "1.0.5", }, // Note that we set the stack-size to 1MB explicitly even though it is set // to this value by default. This is because some of our tests (`restoration_of_globals`) diff --git a/core/utils/wasm-builder-runner/Cargo.toml b/core/utils/wasm-builder-runner/Cargo.toml index 4046b7e4e2..71cdbd2835 100644 --- a/core/utils/wasm-builder-runner/Cargo.toml +++ b/core/utils/wasm-builder-runner/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-wasm-builder-runner" -version = "1.0.2" +version = "1.0.3" authors = ["Parity Technologies "] description = "Runner for substrate-wasm-builder" edition = "2018" diff --git a/core/utils/wasm-builder-runner/src/lib.rs b/core/utils/wasm-builder-runner/src/lib.rs index 1558dbf220..1fee4a4fd7 100644 --- a/core/utils/wasm-builder-runner/src/lib.rs +++ b/core/utils/wasm-builder-runner/src/lib.rs @@ -30,9 +30,6 @@ use std::{env, process::{Command, self}, fs, path::{PathBuf, Path}}; /// Environment variable that tells us to skip building the WASM binary. const SKIP_BUILD_ENV: &str = "SKIP_WASM_BUILD"; -/// Environment variable to extend the `RUSTFLAGS` variable given to the WASM build. -const WASM_BUILD_RUSTFLAGS_ENV: &str = "WASM_BUILD_RUSTFLAGS"; - /// Environment variable that tells us to create a dummy WASM binary. /// /// This is useful for `cargo check` to speed-up the compilation. @@ -102,22 +99,8 @@ impl WasmBuilderSource { pub fn build_current_project_with_rustflags( file_name: &str, wasm_builder_source: WasmBuilderSource, - rustflags: &str, + default_rustflags: &str, ) { - let given_rustflags = env::var(WASM_BUILD_RUSTFLAGS_ENV).unwrap_or_default(); - env::set_var(WASM_BUILD_RUSTFLAGS_ENV, format!("{} {}", given_rustflags, rustflags)); - - build_current_project(file_name, wasm_builder_source) -} - -/// Build the currently built project as WASM binary. -/// -/// The current project is determined using the `CARGO_MANIFEST_DIR` environment variable. -/// -/// `file_name` - The name of the file being generated in the `OUT_DIR`. The file contains the -/// constant `WASM_BINARY` which contains the build wasm binary. -/// `wasm_builder_path` - Path to the wasm-builder project, relative to `CARGO_MANIFEST_DIR`. -pub fn build_current_project(file_name: &str, wasm_builder_source: WasmBuilderSource) { if check_skip_build() { // If we skip the build, we still want to make sure to be called when an env variable changes generate_rerun_if_changed_instructions(); @@ -133,12 +116,20 @@ pub fn build_current_project(file_name: &str, wasm_builder_source: WasmBuilderSo let cargo_toml_path = manifest_dir.join("Cargo.toml"); let out_dir = PathBuf::from(env::var("OUT_DIR").expect("`OUT_DIR` is set by cargo!")); let file_path = out_dir.join(file_name); - let project_folder = out_dir.join("wasm_build_runner"); + let project_name = env::var("CARGO_PKG_NAME").expect("`CARGO_PKG_NAME` is set by cargo!"); + let project_folder = get_workspace_root().join(project_name); if check_provide_dummy_wasm_binary() { provide_dummy_wasm_binary(&file_path); } else { - create_project(&project_folder, &file_path, &manifest_dir, wasm_builder_source, &cargo_toml_path); + create_project( + &project_folder, + &file_path, + &manifest_dir, + wasm_builder_source, + &cargo_toml_path, + default_rustflags, + ); run_project(&project_folder); } @@ -147,12 +138,43 @@ pub fn build_current_project(file_name: &str, wasm_builder_source: WasmBuilderSo generate_rerun_if_changed_instructions(); } +/// Build the currently built project as WASM binary. +/// +/// The current project is determined using the `CARGO_MANIFEST_DIR` environment variable. +/// +/// `file_name` - The name of the file being generated in the `OUT_DIR`. The file contains the +/// constant `WASM_BINARY` which contains the build wasm binary. +/// `wasm_builder_path` - Path to the wasm-builder project, relative to `CARGO_MANIFEST_DIR`. +pub fn build_current_project(file_name: &str, wasm_builder_source: WasmBuilderSource) { + build_current_project_with_rustflags(file_name, wasm_builder_source, ""); +} + +/// Returns the root path of the wasm-builder-runner workspace. +/// +/// The wasm-builder-runner workspace contains all wasm-builder-runner's projects. +fn get_workspace_root() -> PathBuf { + let out_dir_env = env::var("OUT_DIR").expect("`OUT_DIR` is set by cargo!"); + let mut out_dir = PathBuf::from(&out_dir_env); + + loop { + match out_dir.parent() { + Some(parent) if out_dir.ends_with("build") => return parent.join("wbuild-runner"), + _ => if !out_dir.pop() { + break; + } + } + } + + panic!("Could not find target dir in: {}", out_dir_env) +} + fn create_project( project_folder: &Path, file_path: &Path, manifest_dir: &Path, wasm_builder_source: WasmBuilderSource, cargo_toml_path: &Path, + default_rustflags: &str, ) { fs::create_dir_all(project_folder.join("src")) .expect("WASM build runner dir create can not fail; qed"); @@ -179,12 +201,19 @@ fn create_project( project_folder.join("src/main.rs"), format!( r#" + use substrate_wasm_builder::build_project_with_default_rustflags; + fn main() {{ - substrate_wasm_builder::build_project("{file_path}", "{cargo_toml_path}") + build_project_with_default_rustflags( + "{file_path}", + "{cargo_toml_path}", + "{default_rustflags}", + ) }} "#, file_path = replace_back_slashes(file_path.display()), cargo_toml_path = replace_back_slashes(cargo_toml_path.display()), + default_rustflags = default_rustflags, ) ).expect("WASM build runner `main.rs` writing can not fail; qed"); } diff --git a/core/utils/wasm-builder/Cargo.toml b/core/utils/wasm-builder/Cargo.toml index 44288dbcd2..97d4d2316a 100644 --- a/core/utils/wasm-builder/Cargo.toml +++ b/core/utils/wasm-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-wasm-builder" -version = "1.0.4" +version = "1.0.5" authors = ["Parity Technologies "] description = "Utility for building WASM binaries" edition = "2018" @@ -12,6 +12,6 @@ license = "GPL-3.0" build-helper = "0.1.1" cargo_metadata = "0.8" tempfile = "3.1.0" -toml = "0.5.1" -walkdir = "2.2.8" +toml = "0.5.3" +walkdir = "2.2.9" fs2 = "0.4.3" diff --git a/core/utils/wasm-builder/src/lib.rs b/core/utils/wasm-builder/src/lib.rs index 5bb0342c66..49b468f15f 100644 --- a/core/utils/wasm-builder/src/lib.rs +++ b/core/utils/wasm-builder/src/lib.rs @@ -66,6 +66,8 @@ //! needs to change. As WASM builder instructs `cargo` to watch for file changes //! this environment variable should only be required in certain circumstances. //! - `WASM_BUILD_RUSTFLAGS` - Extend `RUSTFLAGS` given to `cargo build` while building the WASM binary. +//! - `WASM_TARGET_DIRECTORY` - Will copy any build WASM binary to the given directory. The path needs +//! to be absolute. //! //! Each project can be skipped individually by using the environment variable `SKIP_PROJECT_NAME_WASM_BUILD`. //! Where `PROJECT_NAME` needs to be replaced by the name of the cargo project, e.g. `node-runtime` will @@ -96,6 +98,11 @@ const WASM_BUILD_TYPE_ENV: &str = "WASM_BUILD_TYPE"; /// Environment variable to extend the `RUSTFLAGS` variable given to the WASM build. const WASM_BUILD_RUSTFLAGS_ENV: &str = "WASM_BUILD_RUSTFLAGS"; +/// Environment variable to set the target directory to copy the final WASM binary. +/// +/// The directory needs to be an absolute path. +const WASM_TARGET_DIRECTORY: &str = "WASM_TARGET_DIRECTORY"; + /// Build the currently built project as WASM binary. /// /// The current project is determined by using the `CARGO_MANIFEST_DIR` environment variable. @@ -104,6 +111,22 @@ const WASM_BUILD_RUSTFLAGS_ENV: &str = "WASM_BUILD_RUSTFLAGS"; /// constant `WASM_BINARY`, which contains the built WASM binary. /// `cargo_manifest` - The path to the `Cargo.toml` of the project that should be built. pub fn build_project(file_name: &str, cargo_manifest: &str) { + build_project_with_default_rustflags(file_name, cargo_manifest, ""); +} + +/// Build the currently built project as WASM binary. +/// +/// The current project is determined by using the `CARGO_MANIFEST_DIR` environment variable. +/// +/// `file_name` - The name + path of the file being generated. The file contains the +/// constant `WASM_BINARY`, which contains the built WASM binary. +/// `cargo_manifest` - The path to the `Cargo.toml` of the project that should be built. +/// `default_rustflags` - Default `RUSTFLAGS` that will always be set for the build. +pub fn build_project_with_default_rustflags( + file_name: &str, + cargo_manifest: &str, + default_rustflags: &str, +) { if check_skip_build() { return; } @@ -123,10 +146,13 @@ pub fn build_project(file_name: &str, cargo_manifest: &str) { process::exit(1); } - let (wasm_binary, bloaty) = wasm_project::create_and_compile(&cargo_manifest); + let (wasm_binary, bloaty) = wasm_project::create_and_compile( + &cargo_manifest, + default_rustflags, + ); - create_out_file( - file_name, + write_file_if_changed( + file_name.into(), format!( r#" pub const WASM_BINARY: &[u8] = include_bytes!("{wasm_binary}"); @@ -143,11 +169,11 @@ fn check_skip_build() -> bool { env::var(SKIP_BUILD_ENV).is_ok() } -fn create_out_file(file_name: &str, content: String) { - fs::write( - file_name, - content - ).expect("Creating and writing can not fail; qed"); +/// Write to the given `file` if the `content` is different. +fn write_file_if_changed(file: PathBuf, content: String) { + if fs::read_to_string(&file).ok().as_ref() != Some(&content) { + fs::write(&file, content).expect(&format!("Writing `{}` can not fail!", file.display())); + } } /// Get a cargo command that compiles with nightly diff --git a/core/utils/wasm-builder/src/wasm_project.rs b/core/utils/wasm-builder/src/wasm_project.rs index 4bc908114c..feaaea1802 100644 --- a/core/utils/wasm-builder/src/wasm_project.rs +++ b/core/utils/wasm-builder/src/wasm_project.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +use crate::write_file_if_changed; + use std::{fs, path::{Path, PathBuf}, borrow::ToOwned, process::{Command, self}, env}; use toml::value::Table; @@ -75,7 +77,10 @@ impl Drop for WorkspaceLock { /// /// # Returns /// The path to the compact WASM binary and the bloaty WASM binary. -pub fn create_and_compile(cargo_manifest: &Path) -> (WasmBinary, WasmBinaryBloaty) { +pub fn create_and_compile( + cargo_manifest: &Path, + default_rustflags: &str, +) -> (WasmBinary, WasmBinaryBloaty) { let wasm_workspace_root = get_wasm_workspace_root(); let wasm_workspace = wasm_workspace_root.join("wbuild"); @@ -85,8 +90,14 @@ pub fn create_and_compile(cargo_manifest: &Path) -> (WasmBinary, WasmBinaryBloat let project = create_project(cargo_manifest, &wasm_workspace); create_wasm_workspace_project(&wasm_workspace); - build_project(&project); - let (wasm_binary, bloaty) = compact_wasm_file(&project, cargo_manifest, &wasm_workspace); + build_project(&project, default_rustflags); + let (wasm_binary, bloaty) = compact_wasm_file( + &project, + cargo_manifest, + &wasm_workspace, + ); + + copy_wasm_to_target_directory(cargo_manifest, &wasm_binary); generate_rerun_if_changed_instructions(cargo_manifest, &project, &wasm_workspace); @@ -122,6 +133,7 @@ fn find_cargo_lock(cargo_manifest: &Path) -> Option { cargo_manifest.display(), build_helper::out_dir().display() ); + None } @@ -203,7 +215,7 @@ fn create_project(cargo_manifest: &Path, wasm_workspace: &Path) -> PathBuf { fs::create_dir_all(project_folder.join("src")).expect("Wasm project dir create can not fail; qed"); - fs::write( + write_file_if_changed( project_folder.join("Cargo.toml"), format!( r#" @@ -223,12 +235,12 @@ fn create_project(cargo_manifest: &Path, wasm_workspace: &Path) -> PathBuf { crate_path = crate_path.display(), wasm_binary = wasm_binary, ) - ).expect("Project `Cargo.toml` writing can not fail; qed"); + ); - fs::write( + write_file_if_changed( project_folder.join("src/lib.rs"), - "#![no_std] pub use wasm_project::*;", - ).expect("Project `lib.rs` writing can not fail; qed"); + "#![no_std] pub use wasm_project::*;".into(), + ); if let Some(crate_lock_file) = find_cargo_lock(cargo_manifest) { // Use the `Cargo.lock` of the main project. @@ -257,12 +269,13 @@ fn is_release_build() -> bool { } /// Build the project to create the WASM binary. -fn build_project(project: &Path) { +fn build_project(project: &Path, default_rustflags: &str) { let manifest_path = project.join("Cargo.toml"); let mut build_cmd = crate::get_nightly_cargo().command(); let rustflags = format!( - "-C link-arg=--export-table {}", + "-C link-arg=--export-table {} {}", + default_rustflags, env::var(crate::WASM_BUILD_RUSTFLAGS_ENV).unwrap_or_default(), ); @@ -349,4 +362,29 @@ fn generate_rerun_if_changed_instructions( println!("cargo:rerun-if-env-changed={}", crate::SKIP_BUILD_ENV); println!("cargo:rerun-if-env-changed={}", crate::WASM_BUILD_TYPE_ENV); println!("cargo:rerun-if-env-changed={}", crate::WASM_BUILD_RUSTFLAGS_ENV); + println!("cargo:rerun-if-env-changed={}", crate::WASM_TARGET_DIRECTORY); +} + +/// Copy the WASM binary to the target directory set in `WASM_TARGET_DIRECTORY` environment variable. +/// If the variable is not set, this is a no-op. +fn copy_wasm_to_target_directory(cargo_manifest: &Path, wasm_binary: &WasmBinary) { + let target_dir = match env::var(crate::WASM_TARGET_DIRECTORY) { + Ok(path) => PathBuf::from(path), + Err(_) => return, + }; + + if !target_dir.is_absolute() { + panic!( + "Environment variable `{}` with `{}` is not an absolute path!", + crate::WASM_TARGET_DIRECTORY, + target_dir.display(), + ); + } + + fs::create_dir_all(&target_dir).expect("Creates `WASM_TARGET_DIRECTORY`."); + + fs::copy( + wasm_binary.wasm_binary_path(), + target_dir.join(format!("{}.wasm", get_wasm_binary_name(cargo_manifest))), + ).expect("Copies WASM binary to `WASM_TARGET_DIRECTORY`."); } diff --git a/node-template/runtime/build.rs b/node-template/runtime/build.rs index 7000c602e8..1ed109dd8e 100644 --- a/node-template/runtime/build.rs +++ b/node-template/runtime/build.rs @@ -19,7 +19,7 @@ use wasm_builder_runner::{build_current_project_with_rustflags, WasmBuilderSourc fn main() { build_current_project_with_rustflags( "wasm_binary.rs", - WasmBuilderSource::Crates("1.0.4"), + WasmBuilderSource::Crates("1.0.5"), // This instructs LLD to export __heap_base as a global variable, which is used by the // external memory allocator. "-Clink-arg=--export=__heap_base", diff --git a/node/runtime/build.rs b/node/runtime/build.rs index a5f22fd017..d5d6599eca 100644 --- a/node/runtime/build.rs +++ b/node/runtime/build.rs @@ -21,7 +21,7 @@ fn main() { "wasm_binary.rs", WasmBuilderSource::CratesOrPath { path: "../../core/utils/wasm-builder", - version: "1.0.4", + version: "1.0.5", }, // This instructs LLD to export __heap_base as a global variable, which is used by the // external memory allocator. diff --git a/scripts/build-only-wasm.sh b/scripts/build-only-wasm.sh new file mode 100755 index 0000000000..51e904edd5 --- /dev/null +++ b/scripts/build-only-wasm.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env sh + +# Script for building only the WASM binary of the given project. + +set -e + +PROJECT_ROOT=`git rev-parse --show-toplevel` + +if [ "$#" -lt 1 ]; then + echo "You need to pass the name of the crate you want to compile!" + exit 1 +fi + +WASM_BUILDER_RUNNER="$PROJECT_ROOT/target/release/wbuild-runner/$1" + +if [ -z "$2" ]; then + export WASM_TARGET_DIRECTORY=$(pwd) +else + export WASM_TARGET_DIRECTORY=$2 +fi + +if [ -d $WASM_BUILDER_RUNNER ]; then + export DEBUG=false + export OUT_DIR="$PROJECT_ROOT/target/release/build" + cargo run --release --manifest-path="$WASM_BUILDER_RUNNER/Cargo.toml" \ + | grep -vE "cargo:rerun-if-|Executing build command" \ +else + cargo build --release -p $1 +fi -- GitLab From 95fc4211c7feb4b1865f25a91141c8ab9ce4e886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 29 Aug 2019 10:32:55 +0200 Subject: [PATCH 035/275] Extract RPC definitions from RPC crate. (#3502) * Extract author API from the substrate-rpc crate. * Split out API from RPC. * Clean up naming. * Fix tests. * Shorten error translations. * Update Cargo.lock --- Cargo.lock | 27 +++- core/rpc/Cargo.toml | 26 ++-- core/rpc/api/Cargo.toml | 21 +++ core/rpc/{ => api}/src/author/error.rs | 10 +- core/rpc/{ => api}/src/author/hash.rs | 0 core/rpc/api/src/author/mod.rs | 87 +++++++++++ core/rpc/{ => api}/src/chain/error.rs | 8 +- core/rpc/api/src/chain/mod.rs | 89 +++++++++++ core/rpc/{ => api}/src/chain/number.rs | 2 - core/rpc/{ => api}/src/errors.rs | 7 +- core/rpc/api/src/helpers.rs | 31 ++++ core/rpc/api/src/lib.rs | 34 ++++ core/rpc/{ => api}/src/state/error.rs | 8 +- core/rpc/api/src/state/mod.rs | 143 +++++++++++++++++ core/rpc/{ => api}/src/subscriptions.rs | 4 +- core/rpc/{ => api}/src/system/error.rs | 2 +- core/rpc/{ => api}/src/system/helpers.rs | 0 core/rpc/api/src/system/mod.rs | 67 ++++++++ core/rpc/src/author/mod.rs | 71 +-------- core/rpc/src/chain/mod.rs | 90 ++--------- core/rpc/src/helpers.rs | 16 -- core/rpc/src/lib.rs | 12 +- core/rpc/src/metadata.rs | 4 +- core/rpc/src/state/mod.rs | 188 ++++++----------------- core/rpc/src/state/tests.rs | 2 +- core/rpc/src/system/mod.rs | 52 +------ core/rpc/src/system/tests.rs | 7 +- core/service/src/lib.rs | 4 +- 28 files changed, 612 insertions(+), 400 deletions(-) create mode 100644 core/rpc/api/Cargo.toml rename core/rpc/{ => api}/src/author/error.rs (96%) rename core/rpc/{ => api}/src/author/hash.rs (100%) create mode 100644 core/rpc/api/src/author/mod.rs rename core/rpc/{ => api}/src/chain/error.rs (90%) create mode 100644 core/rpc/api/src/chain/mod.rs rename core/rpc/{ => api}/src/chain/number.rs (98%) rename core/rpc/{ => api}/src/errors.rs (86%) create mode 100644 core/rpc/api/src/helpers.rs create mode 100644 core/rpc/api/src/lib.rs rename core/rpc/{ => api}/src/state/error.rs (92%) create mode 100644 core/rpc/api/src/state/mod.rs rename core/rpc/{ => api}/src/subscriptions.rs (97%) rename core/rpc/{ => api}/src/system/error.rs (98%) rename core/rpc/{ => api}/src/system/helpers.rs (100%) create mode 100644 core/rpc/api/src/system/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 6cb7232ecf..9b6926af8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4972,26 +4972,23 @@ name = "substrate-rpc" version = "2.0.0" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-pubsub 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-version 2.0.0", "substrate-client 2.0.0", + "substrate-executor 2.0.0", "substrate-keystore 2.0.0", "substrate-network 2.0.0", "substrate-primitives 2.0.0", + "substrate-rpc-api 2.0.0", "substrate-session 2.0.0", "substrate-state-machine 2.0.0", "substrate-test-runtime-client 2.0.0", @@ -4999,6 +4996,26 @@ dependencies = [ "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "substrate-rpc-api" +version = "2.0.0" +dependencies = [ + "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-version 2.0.0", + "substrate-primitives 2.0.0", + "substrate-transaction-graph 2.0.0", +] + [[package]] name = "substrate-rpc-servers" version = "2.0.0" diff --git a/core/rpc/Cargo.toml b/core/rpc/Cargo.toml index 234761708e..1cd423c88f 100644 --- a/core/rpc/Cargo.toml +++ b/core/rpc/Cargo.toml @@ -5,32 +5,28 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -derive_more = "0.14.0" -futures = "0.1" +api = { package = "substrate-rpc-api", path = "./api" } +client = { package = "substrate-client", path = "../client" } +codec = { package = "parity-scale-codec", version = "1.0.0" } futures03 = { package = "futures-preview", version = "0.3.0-alpha.17", features = ["compat"] } -jsonrpc-core = "13.1.0" -jsonrpc-core-client = "13.1.0" jsonrpc-pubsub = "13.1.0" -jsonrpc-derive = "13.1.0" log = "0.4" -parking_lot = "0.9.0" -codec = { package = "parity-scale-codec", version = "1.0.0" } -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -client = { package = "substrate-client", path = "../client" } -network = { package = "substrate-network", path = "../network" } primitives = { package = "substrate-primitives", path = "../primitives" } +rpc = { package = "jsonrpc-core", version = "13.0.0" } +runtime_version = { package = "sr-version", path = "../sr-version" } +serde_json = "1.0" session = { package = "substrate-session", path = "../session" } -state_machine = { package = "substrate-state-machine", path = "../state-machine" } -transaction_pool = { package = "substrate-transaction-pool", path = "../transaction-pool" } sr-primitives = { path = "../sr-primitives" } -runtime_version = { package = "sr-version", path = "../sr-version" } +state_machine = { package = "substrate-state-machine", path = "../state-machine" } +substrate-executor = { path = "../executor" } substrate-keystore = { path = "../keystore" } +transaction_pool = { package = "substrate-transaction-pool", path = "../transaction-pool" } [dev-dependencies] assert_matches = "1.1" futures = "0.1.17" +network = { package = "substrate-network", path = "../network" } +rustc-hex = "2.0" sr-io = { path = "../sr-io" } test-client = { package = "substrate-test-runtime-client", path = "../test-runtime/client" } -rustc-hex = "2.0" tokio = "0.1.17" diff --git a/core/rpc/api/Cargo.toml b/core/rpc/api/Cargo.toml new file mode 100644 index 0000000000..4b09f4f327 --- /dev/null +++ b/core/rpc/api/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "substrate-rpc-api" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.0.0" } +derive_more = "0.14.0" +futures03 = { package = "futures-preview", version = "0.3.0-alpha.17", features = ["compat"] } +jsonrpc-core = "13.0.0" +jsonrpc-core-client = "13.0.0" +jsonrpc-derive = "13.0.0" +jsonrpc-pubsub = "13.0.0" +log = "0.4" +parking_lot = "0.9.0" +primitives = { package = "substrate-primitives", path = "../../primitives" } +runtime_version = { package = "sr-version", path = "../../sr-version" } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +txpool = { package = "substrate-transaction-graph", path = "../../transaction-pool/graph" } diff --git a/core/rpc/src/author/error.rs b/core/rpc/api/src/author/error.rs similarity index 96% rename from core/rpc/src/author/error.rs rename to core/rpc/api/src/author/error.rs index 1ce707f0bb..0a71de5cb9 100644 --- a/core/rpc/src/author/error.rs +++ b/core/rpc/api/src/author/error.rs @@ -16,10 +16,8 @@ //! Authoring RPC module errors. -use client; -use transaction_pool::txpool; -use crate::rpc; use crate::errors; +use jsonrpc_core as rpc; /// Author RPC Result type. pub type Result = std::result::Result; @@ -28,8 +26,10 @@ pub type Result = std::result::Result; #[derive(Debug, derive_more::Display, derive_more::From)] pub enum Error { /// Client error. - Client(client::error::Error), + #[display(fmt="Client error: {}", _0)] + Client(Box), /// Transaction pool error, + #[display(fmt="Transaction pool error: {}", _0)] Pool(txpool::error::Error), /// Verification error #[display(fmt="Extrinsic verification error: {}", _0)] @@ -54,7 +54,7 @@ pub enum Error { impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { - Error::Client(ref err) => Some(err), + Error::Client(ref err) => Some(&**err), Error::Pool(ref err) => Some(err), Error::Verification(ref err) => Some(&**err), _ => None, diff --git a/core/rpc/src/author/hash.rs b/core/rpc/api/src/author/hash.rs similarity index 100% rename from core/rpc/src/author/hash.rs rename to core/rpc/api/src/author/hash.rs diff --git a/core/rpc/api/src/author/mod.rs b/core/rpc/api/src/author/mod.rs new file mode 100644 index 0000000000..3d5698880a --- /dev/null +++ b/core/rpc/api/src/author/mod.rs @@ -0,0 +1,87 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Substrate block-author/full-node API. + +pub mod error; +pub mod hash; + +use jsonrpc_derive::rpc; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use primitives::{ + Bytes +}; +use self::error::Result; +use txpool::watcher::Status; + +pub use self::gen_client::Client as AuthorClient; + +/// Substrate authoring RPC API +#[rpc] +pub trait AuthorApi { + /// RPC metadata + type Metadata; + + /// Submit hex-encoded extrinsic for inclusion in block. + #[rpc(name = "author_submitExtrinsic")] + fn submit_extrinsic(&self, extrinsic: Bytes) -> Result; + + /// Insert a key into the keystore. + #[rpc(name = "author_insertKey")] + fn insert_key(&self, + key_type: String, + suri: String, + maybe_public: Option + ) -> Result; + + /// Generate new session keys and returns the corresponding public keys. + #[rpc(name = "author_rotateKeys")] + fn rotate_keys(&self) -> Result; + + /// Returns all pending extrinsics, potentially grouped by sender. + #[rpc(name = "author_pendingExtrinsics")] + fn pending_extrinsics(&self) -> Result>; + + /// Remove given extrinsic from the pool and temporarily ban it to prevent reimporting. + #[rpc(name = "author_removeExtrinsic")] + fn remove_extrinsic(&self, + bytes_or_hash: Vec> + ) -> Result>; + + /// Submit an extrinsic to watch. + #[pubsub( + subscription = "author_extrinsicUpdate", + subscribe, + name = "author_submitAndWatchExtrinsic" + )] + fn watch_extrinsic(&self, + metadata: Self::Metadata, + subscriber: Subscriber>, + bytes: Bytes + ); + + /// Unsubscribe from extrinsic watching. + #[pubsub( + subscription = "author_extrinsicUpdate", + unsubscribe, + name = "author_unwatchExtrinsic" + )] + fn unwatch_extrinsic(&self, + metadata: Option, + id: SubscriptionId + ) -> Result; +} + diff --git a/core/rpc/src/chain/error.rs b/core/rpc/api/src/chain/error.rs similarity index 90% rename from core/rpc/src/chain/error.rs rename to core/rpc/api/src/chain/error.rs index ad63af9add..7c093789fa 100644 --- a/core/rpc/src/chain/error.rs +++ b/core/rpc/api/src/chain/error.rs @@ -17,9 +17,8 @@ //! Error helpers for Chain RPC module. -use client; -use crate::rpc; use crate::errors; +use jsonrpc_core as rpc; /// Chain RPC Result type. pub type Result = std::result::Result; @@ -28,7 +27,8 @@ pub type Result = std::result::Result; #[derive(Debug, derive_more::Display, derive_more::From)] pub enum Error { /// Client error. - Client(client::error::Error), + #[display(fmt="Client error: {}", _0)] + Client(Box), /// Other error type. Other(String), } @@ -36,7 +36,7 @@ pub enum Error { impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { - Error::Client(ref err) => Some(err), + Error::Client(ref err) => Some(&**err), _ => None, } } diff --git a/core/rpc/api/src/chain/mod.rs b/core/rpc/api/src/chain/mod.rs new file mode 100644 index 0000000000..6dc4a60e88 --- /dev/null +++ b/core/rpc/api/src/chain/mod.rs @@ -0,0 +1,89 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Substrate blockchain API. + +pub mod error; +pub mod number; + +use jsonrpc_core::Result as RpcResult; +use jsonrpc_core::futures::Future; +use jsonrpc_derive::rpc; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use self::error::Result; + +pub use self::gen_client::Client as ChainClient; + +/// Substrate blockchain API +#[rpc] +pub trait ChainApi { + /// RPC metadata + type Metadata; + + /// Get header of a relay chain block. + #[rpc(name = "chain_getHeader")] + fn header(&self, hash: Option) -> Result>; + + /// Get header and body of a relay chain block. + #[rpc(name = "chain_getBlock")] + fn block(&self, hash: Option) -> Result>; + + /// Get hash of the n-th block in the canon chain. + /// + /// By default returns latest block hash. + #[rpc(name = "chain_getBlockHash", alias("chain_getHead"))] + fn block_hash(&self, hash: Option>) -> Result>; + + /// Get hash of the last finalized block in the canon chain. + #[rpc(name = "chain_getFinalizedHead", alias("chain_getFinalisedHead"))] + fn finalized_head(&self) -> Result; + + /// New head subscription + #[pubsub( + subscription = "chain_newHead", + subscribe, + name = "chain_subscribeNewHeads", + alias("subscribe_newHead", "chain_subscribeNewHead") + )] + fn subscribe_new_heads(&self, metadata: Self::Metadata, subscriber: Subscriber

); + + /// Unsubscribe from new head subscription. + #[pubsub( + subscription = "chain_newHead", + unsubscribe, + name = "chain_unsubscribeNewHeads", + alias("unsubscribe_newHead", "chain_unsubscribeNewHead") + )] + fn unsubscribe_new_heads(&self, metadata: Option, id: SubscriptionId) -> RpcResult; + + /// New head subscription + #[pubsub( + subscription = "chain_finalizedHead", + subscribe, + name = "chain_subscribeFinalizedHeads", + alias("chain_subscribeFinalisedHeads") + )] + fn subscribe_finalized_heads(&self, metadata: Self::Metadata, subscriber: Subscriber
); + + /// Unsubscribe from new head subscription. + #[pubsub( + subscription = "chain_finalizedHead", + unsubscribe, + name = "chain_unsubscribeFinalizedHeads", + alias("chain_unsubscribeFinalisedHeads") + )] + fn unsubscribe_finalized_heads(&self, metadata: Option, id: SubscriptionId) -> RpcResult; +} diff --git a/core/rpc/src/chain/number.rs b/core/rpc/api/src/chain/number.rs similarity index 98% rename from core/rpc/src/chain/number.rs rename to core/rpc/api/src/chain/number.rs index df796d5e6d..0637e3decf 100644 --- a/core/rpc/src/chain/number.rs +++ b/core/rpc/api/src/chain/number.rs @@ -61,14 +61,12 @@ impl + From + Debug + PartialOrd> NumberOrHex } } -#[cfg(test)] impl From for NumberOrHex { fn from(n: u64) -> Self { NumberOrHex::Number(n) } } -#[cfg(test)] impl From for NumberOrHex { fn from(n: U256) -> Self { NumberOrHex::Hex(n) diff --git a/core/rpc/src/errors.rs b/core/rpc/api/src/errors.rs similarity index 86% rename from core/rpc/src/errors.rs rename to core/rpc/api/src/errors.rs index da910de762..984a1cd712 100644 --- a/core/rpc/src/errors.rs +++ b/core/rpc/api/src/errors.rs @@ -14,13 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use crate::rpc; use log::warn; -pub fn internal(e: E) -> rpc::Error { +pub fn internal(e: E) -> jsonrpc_core::Error { warn!("Unknown error: {:?}", e); - rpc::Error { - code: rpc::ErrorCode::InternalError, + jsonrpc_core::Error { + code: jsonrpc_core::ErrorCode::InternalError, message: "Unknown error occured".into(), data: Some(format!("{:?}", e).into()), } diff --git a/core/rpc/api/src/helpers.rs b/core/rpc/api/src/helpers.rs new file mode 100644 index 0000000000..d500a50a86 --- /dev/null +++ b/core/rpc/api/src/helpers.rs @@ -0,0 +1,31 @@ +// Copyright 2018-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use jsonrpc_core::futures::prelude::*; +use futures03::{channel::oneshot, compat::Compat}; + +/// Wraps around `oneshot::Receiver` and adjusts the error type to produce an internal error if the +/// sender gets dropped. +pub struct Receiver(pub Compat>); + +impl Future for Receiver { + type Item = T; + type Error = jsonrpc_core::Error; + + fn poll(&mut self) -> Poll { + self.0.poll().map_err(|_| jsonrpc_core::Error::internal_error()) + } +} diff --git a/core/rpc/api/src/lib.rs b/core/rpc/api/src/lib.rs new file mode 100644 index 0000000000..78fa58f14a --- /dev/null +++ b/core/rpc/api/src/lib.rs @@ -0,0 +1,34 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Substrate RPC interfaces. +//! +//! A collection of RPC methods and subscriptions supported by all substrate clients. + +#![warn(missing_docs)] + +mod errors; +mod helpers; +mod subscriptions; + +pub use jsonrpc_core::IoHandlerExtension as RpcExtension; +pub use subscriptions::Subscriptions; +pub use helpers::Receiver; + +pub mod author; +pub mod chain; +pub mod state; +pub mod system; diff --git a/core/rpc/src/state/error.rs b/core/rpc/api/src/state/error.rs similarity index 92% rename from core/rpc/src/state/error.rs rename to core/rpc/api/src/state/error.rs index 4b9d30b36b..f5e9112b94 100644 --- a/core/rpc/src/state/error.rs +++ b/core/rpc/api/src/state/error.rs @@ -16,9 +16,8 @@ //! State RPC errors. -use client; -use crate::rpc; use crate::errors; +use jsonrpc_core as rpc; /// State RPC Result type. pub type Result = std::result::Result; @@ -27,7 +26,8 @@ pub type Result = std::result::Result; #[derive(Debug, derive_more::Display, derive_more::From)] pub enum Error { /// Client error. - Client(client::error::Error), + #[display(fmt="Client error: {}", _0)] + Client(Box), /// Provided block range couldn't be resolved to a list of blocks. #[display(fmt = "Cannot resolve a block range ['{:?}' ... '{:?}]. {}", from, to, details)] InvalidBlockRange { @@ -43,7 +43,7 @@ pub enum Error { impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { - Error::Client(ref err) => Some(err), + Error::Client(ref err) => Some(&**err), _ => None, } } diff --git a/core/rpc/api/src/state/mod.rs b/core/rpc/api/src/state/mod.rs new file mode 100644 index 0000000000..f7cff7e397 --- /dev/null +++ b/core/rpc/api/src/state/mod.rs @@ -0,0 +1,143 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Substrate state API. + +pub mod error; + +use jsonrpc_core::Result as RpcResult; +use jsonrpc_core::futures::Future; +use jsonrpc_derive::rpc; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use primitives::Bytes; +use primitives::storage::{StorageKey, StorageData, StorageChangeSet}; +use runtime_version::RuntimeVersion; +use self::error::Result; + +pub use self::gen_client::Client as StateClient; + +/// Substrate state API +#[rpc] +pub trait StateApi { + /// RPC Metadata + type Metadata; + + /// Call a contract at a block's state. + #[rpc(name = "state_call", alias("state_callAt"))] + fn call(&self, name: String, bytes: Bytes, hash: Option) -> Result; + + /// Returns the keys with prefix, leave empty to get all the keys + #[rpc(name = "state_getKeys")] + fn storage_keys(&self, prefix: StorageKey, hash: Option) -> Result>; + + /// Returns a storage entry at a specific block's state. + #[rpc(name = "state_getStorage", alias("state_getStorageAt"))] + fn storage(&self, key: StorageKey, hash: Option) -> Result>; + + /// Returns the hash of a storage entry at a block's state. + #[rpc(name = "state_getStorageHash", alias("state_getStorageHashAt"))] + fn storage_hash(&self, key: StorageKey, hash: Option) -> Result>; + + /// Returns the size of a storage entry at a block's state. + #[rpc(name = "state_getStorageSize", alias("state_getStorageSizeAt"))] + fn storage_size(&self, key: StorageKey, hash: Option) -> Result>; + + /// Returns the keys with prefix from a child storage, leave empty to get all the keys + #[rpc(name = "state_getChildKeys")] + fn child_storage_keys( + &self, + child_storage_key: StorageKey, + prefix: StorageKey, + hash: Option + ) -> Result>; + + /// Returns a child storage entry at a specific block's state. + #[rpc(name = "state_getChildStorage")] + fn child_storage( + &self, + child_storage_key: StorageKey, + key: StorageKey, + hash: Option + ) -> Result>; + + /// Returns the hash of a child storage entry at a block's state. + #[rpc(name = "state_getChildStorageHash")] + fn child_storage_hash( + &self, + child_storage_key: StorageKey, + key: StorageKey, + hash: Option + ) -> Result>; + + /// Returns the size of a child storage entry at a block's state. + #[rpc(name = "state_getChildStorageSize")] + fn child_storage_size( + &self, + child_storage_key: StorageKey, + key: StorageKey, + hash: Option + ) -> Result>; + + /// Returns the runtime metadata as an opaque blob. + #[rpc(name = "state_getMetadata")] + fn metadata(&self, hash: Option) -> Result; + + /// Get the runtime version. + #[rpc(name = "state_getRuntimeVersion", alias("chain_getRuntimeVersion"))] + fn runtime_version(&self, hash: Option) -> Result; + + /// Query historical storage entries (by key) starting from a block given as the second parameter. + /// + /// NOTE This first returned result contains the initial state of storage for all keys. + /// Subsequent values in the vector represent changes to the previous state (diffs). + #[rpc(name = "state_queryStorage")] + fn query_storage( + &self, + keys: Vec, + block: Hash, + hash: Option + ) -> Result>>; + + /// New runtime version subscription + #[pubsub( + subscription = "state_runtimeVersion", + subscribe, + name = "state_subscribeRuntimeVersion", + alias("chain_subscribeRuntimeVersion") + )] + fn subscribe_runtime_version(&self, metadata: Self::Metadata, subscriber: Subscriber); + + /// Unsubscribe from runtime version subscription + #[pubsub( + subscription = "state_runtimeVersion", + unsubscribe, + name = "state_unsubscribeRuntimeVersion", + alias("chain_unsubscribeRuntimeVersion") + )] + fn unsubscribe_runtime_version(&self, metadata: Option, id: SubscriptionId) -> RpcResult; + + /// New storage subscription + #[pubsub(subscription = "state_storage", subscribe, name = "state_subscribeStorage")] + fn subscribe_storage( + &self, metadata: Self::Metadata, subscriber: Subscriber>, keys: Option> + ); + + /// Unsubscribe from storage subscription + #[pubsub(subscription = "state_storage", unsubscribe, name = "state_unsubscribeStorage")] + fn unsubscribe_storage( + &self, metadata: Option, id: SubscriptionId + ) -> RpcResult; +} diff --git a/core/rpc/src/subscriptions.rs b/core/rpc/api/src/subscriptions.rs similarity index 97% rename from core/rpc/src/subscriptions.rs rename to core/rpc/api/src/subscriptions.rs index 77df0c09fd..f284e0ef52 100644 --- a/core/rpc/src/subscriptions.rs +++ b/core/rpc/api/src/subscriptions.rs @@ -20,8 +20,8 @@ use std::sync::{Arc, atomic::{self, AtomicUsize}}; use log::{error, warn}; use jsonrpc_pubsub::{SubscriptionId, typed::{Sink, Subscriber}}; use parking_lot::Mutex; -use crate::rpc::futures::sync::oneshot; -use crate::rpc::futures::{Future, future}; +use jsonrpc_core::futures::sync::oneshot; +use jsonrpc_core::futures::{Future, future}; type Id = u64; diff --git a/core/rpc/src/system/error.rs b/core/rpc/api/src/system/error.rs similarity index 98% rename from core/rpc/src/system/error.rs rename to core/rpc/api/src/system/error.rs index bdd4cbe667..32b694e3ac 100644 --- a/core/rpc/src/system/error.rs +++ b/core/rpc/api/src/system/error.rs @@ -16,8 +16,8 @@ //! System RPC module errors. -use crate::rpc; use crate::system::helpers::Health; +use jsonrpc_core as rpc; /// System RPC Result type. pub type Result = std::result::Result; diff --git a/core/rpc/src/system/helpers.rs b/core/rpc/api/src/system/helpers.rs similarity index 100% rename from core/rpc/src/system/helpers.rs rename to core/rpc/api/src/system/helpers.rs diff --git a/core/rpc/api/src/system/mod.rs b/core/rpc/api/src/system/mod.rs new file mode 100644 index 0000000000..b5eacc5d61 --- /dev/null +++ b/core/rpc/api/src/system/mod.rs @@ -0,0 +1,67 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Substrate system API. + +pub mod error; +pub mod helpers; + +use crate::helpers::Receiver; +use jsonrpc_derive::rpc; + +use self::error::Result; + +pub use self::helpers::{Properties, SystemInfo, Health, PeerInfo}; +pub use self::gen_client::Client as SystemClient; + +/// Substrate system RPC API +#[rpc] +pub trait SystemApi { + /// Get the node's implementation name. Plain old string. + #[rpc(name = "system_name")] + fn system_name(&self) -> Result; + + /// Get the node implementation's version. Should be a semver string. + #[rpc(name = "system_version")] + fn system_version(&self) -> Result; + + /// Get the chain's type. Given as a string identifier. + #[rpc(name = "system_chain")] + fn system_chain(&self) -> Result; + + /// Get a custom set of properties as a JSON object, defined in the chain spec. + #[rpc(name = "system_properties")] + fn system_properties(&self) -> Result; + + /// Return health status of the node. + /// + /// Node is considered healthy if it is: + /// - connected to some peers (unless running in dev mode) + /// - not performing a major sync + #[rpc(name = "system_health", returns = "Health")] + fn system_health(&self) -> Receiver; + + /// Returns currently connected peers + #[rpc(name = "system_peers", returns = "Vec>")] + fn system_peers(&self) -> Receiver>>; + + /// Returns current state of the network. + /// + /// **Warning**: This API is not stable. + // TODO: make this stable and move structs https://github.com/paritytech/substrate/issues/1890 + #[rpc(name = "system_networkState", returns = "jsonrpc_core::Value")] + fn system_network_state(&self) -> Receiver; +} diff --git a/core/rpc/src/author/mod.rs b/core/rpc/src/author/mod.rs index 0290a534ea..4c72a96023 100644 --- a/core/rpc/src/author/mod.rs +++ b/core/rpc/src/author/mod.rs @@ -16,19 +16,15 @@ //! Substrate block-author/full-node API. -pub mod error; -pub mod hash; - #[cfg(test)] mod tests; use std::{sync::Arc, convert::TryInto}; use client::{self, Client}; -use crate::rpc::futures::{Sink, Future}; -use crate::subscriptions::Subscriptions; +use rpc::futures::{Sink, Future}; use futures03::{StreamExt as _, compat::Compat}; -use jsonrpc_derive::rpc; +use api::Subscriptions; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use log::warn; use codec::{Encode, Decode}; @@ -37,7 +33,6 @@ use primitives::{ traits::BareCryptoStorePtr, }; use sr_primitives::{generic, traits::{self, ProvideRuntimeApi}}; -use self::error::{Error, Result}; use transaction_pool::{ txpool::{ ChainApi as PoolChainApi, @@ -50,63 +45,9 @@ use transaction_pool::{ }; use session::SessionKeys; -pub use self::gen_client::Client as AuthorClient; - -/// Substrate authoring RPC API -#[rpc] -pub trait AuthorApi { - /// RPC metadata - type Metadata; - - /// Submit hex-encoded extrinsic for inclusion in block. - #[rpc(name = "author_submitExtrinsic")] - fn submit_extrinsic(&self, extrinsic: Bytes) -> Result; - - /// Insert a key into the keystore. - #[rpc(name = "author_insertKey")] - fn insert_key(&self, - key_type: String, - suri: String, - maybe_public: Option - ) -> Result; - - /// Generate new session keys and returns the corresponding public keys. - #[rpc(name = "author_rotateKeys")] - fn rotate_keys(&self) -> Result; - - /// Returns all pending extrinsics, potentially grouped by sender. - #[rpc(name = "author_pendingExtrinsics")] - fn pending_extrinsics(&self) -> Result>; - - /// Remove given extrinsic from the pool and temporarily ban it to prevent reimporting. - #[rpc(name = "author_removeExtrinsic")] - fn remove_extrinsic(&self, - bytes_or_hash: Vec> - ) -> Result>; - - /// Submit an extrinsic to watch. - #[pubsub( - subscription = "author_extrinsicUpdate", - subscribe, - name = "author_submitAndWatchExtrinsic" - )] - fn watch_extrinsic(&self, - metadata: Self::Metadata, - subscriber: Subscriber>, - bytes: Bytes - ); - - /// Unsubscribe from extrinsic watching. - #[pubsub( - subscription = "author_extrinsicUpdate", - unsubscribe, - name = "author_unwatchExtrinsic" - )] - fn unwatch_extrinsic(&self, - metadata: Option, - id: SubscriptionId - ) -> Result; -} +/// Re-export the API for backward compatibility. +pub use api::author::*; +use self::error::{Error, Result}; /// Authoring API pub struct Author where P: PoolChainApi + Sync + Send + 'static { @@ -183,7 +124,7 @@ impl AuthorApi, BlockHash

> for Author whe self.client.runtime_api().generate_session_keys( &generic::BlockId::Hash(best_block_hash), None, - ).map(Into::into).map_err(Into::into) + ).map(Into::into).map_err(|e| Error::Client(Box::new(e))) } fn submit_extrinsic(&self, ext: Bytes) -> Result> { diff --git a/core/rpc/src/chain/mod.rs b/core/rpc/src/chain/mod.rs index cb0235e13b..dde54f6278 100644 --- a/core/rpc/src/chain/mod.rs +++ b/core/rpc/src/chain/mod.rs @@ -16,9 +16,6 @@ //! Substrate blockchain API. -pub mod error; -pub mod number; - #[cfg(test)] mod tests; @@ -26,79 +23,17 @@ use std::sync::Arc; use futures03::{future, StreamExt as _, TryStreamExt as _}; use client::{self, Client, BlockchainEvents}; -use crate::rpc::Result as RpcResult; -use crate::rpc::futures::{stream, Future, Sink, Stream}; -use crate::subscriptions::Subscriptions; -use jsonrpc_derive::rpc; +use rpc::Result as RpcResult; +use rpc::futures::{stream, Future, Sink, Stream}; +use api::Subscriptions; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use log::warn; use primitives::{H256, Blake2Hasher}; use sr_primitives::generic::{BlockId, SignedBlock}; use sr_primitives::traits::{Block as BlockT, Header, NumberFor}; -use self::error::Result; - -pub use self::gen_client::Client as ChainClient; - -/// Substrate blockchain API -#[rpc] -pub trait ChainApi { - /// RPC metadata - type Metadata; - - /// Get header of a relay chain block. - #[rpc(name = "chain_getHeader")] - fn header(&self, hash: Option) -> Result>; - - /// Get header and body of a relay chain block. - #[rpc(name = "chain_getBlock")] - fn block(&self, hash: Option) -> Result>; - - /// Get hash of the n-th block in the canon chain. - /// - /// By default returns latest block hash. - #[rpc(name = "chain_getBlockHash", alias("chain_getHead"))] - fn block_hash(&self, hash: Option>) -> Result>; - - /// Get hash of the last finalized block in the canon chain. - #[rpc(name = "chain_getFinalizedHead", alias("chain_getFinalisedHead"))] - fn finalized_head(&self) -> Result; - - /// New head subscription - #[pubsub( - subscription = "chain_newHead", - subscribe, - name = "chain_subscribeNewHeads", - alias("subscribe_newHead", "chain_subscribeNewHead") - )] - fn subscribe_new_heads(&self, metadata: Self::Metadata, subscriber: Subscriber

); - - /// Unsubscribe from new head subscription. - #[pubsub( - subscription = "chain_newHead", - unsubscribe, - name = "chain_unsubscribeNewHeads", - alias("unsubscribe_newHead", "chain_unsubscribeNewHead") - )] - fn unsubscribe_new_heads(&self, metadata: Option, id: SubscriptionId) -> RpcResult; - - /// New head subscription - #[pubsub( - subscription = "chain_finalizedHead", - subscribe, - name = "chain_subscribeFinalizedHeads", - alias("chain_subscribeFinalisedHeads") - )] - fn subscribe_finalized_heads(&self, metadata: Self::Metadata, subscriber: Subscriber
); - - /// Unsubscribe from new head subscription. - #[pubsub( - subscription = "chain_finalizedHead", - unsubscribe, - name = "chain_unsubscribeFinalizedHeads", - alias("chain_unsubscribeFinalisedHeads") - )] - fn unsubscribe_finalized_heads(&self, metadata: Option, id: SubscriptionId) -> RpcResult; -} +use self::error::{Error, Result}; + +pub use api::chain::*; /// Chain API with subscriptions support. pub struct Chain { @@ -168,6 +103,10 @@ impl Chain where } } +fn client_error(err: client::error::Error) -> Error { + Error::Client(Box::new(err)) +} + impl ChainApi, Block::Hash, Block::Header, SignedBlock> for Chain where Block: BlockT + 'static, B: client::backend::Backend + Send + Sync + 'static, @@ -178,20 +117,23 @@ impl ChainApi, Block::Hash, Block::Header, Sig fn header(&self, hash: Option) -> Result> { let hash = self.unwrap_or_best(hash)?; - Ok(self.client.header(&BlockId::Hash(hash))?) + Ok(self.client.header(&BlockId::Hash(hash)).map_err(client_error)?) } fn block(&self, hash: Option) -> Result>> { let hash = self.unwrap_or_best(hash)?; - Ok(self.client.block(&BlockId::Hash(hash))?) + Ok(self.client.block(&BlockId::Hash(hash)).map_err(client_error)?) } fn block_hash(&self, number: Option>>) -> Result> { Ok(match number { None => Some(self.client.info().chain.best_hash), - Some(num_or_hex) => self.client.header(&BlockId::number(num_or_hex.to_number()?))?.map(|h| h.hash()), + Some(num_or_hex) => self.client + .header(&BlockId::number(num_or_hex.to_number()?)) + .map_err(client_error)? + .map(|h| h.hash()), }) } diff --git a/core/rpc/src/helpers.rs b/core/rpc/src/helpers.rs index 2c69ead76c..e579c743ac 100644 --- a/core/rpc/src/helpers.rs +++ b/core/rpc/src/helpers.rs @@ -14,22 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use futures::prelude::*; -use futures03::{channel::oneshot, compat::Compat}; - -/// Wraps around `oneshot::Receiver` and adjusts the error type to produce an internal error if the -/// sender gets dropped. -pub struct Receiver(pub Compat>); - -impl Future for Receiver { - type Item = T; - type Error = jsonrpc_core::Error; - - fn poll(&mut self) -> Poll { - self.0.poll().map_err(|_| jsonrpc_core::Error::internal_error()) - } -} - /// Unwraps the trailing parameter or falls back with the closure result. pub fn unwrap_or_else(or_else: F, optional: Option) -> Result where F: FnOnce() -> Result, diff --git a/core/rpc/src/lib.rs b/core/rpc/src/lib.rs index 7ca3fde01d..9ce9f82fda 100644 --- a/core/rpc/src/lib.rs +++ b/core/rpc/src/lib.rs @@ -14,22 +14,18 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Substrate RPC interfaces. +//! Substrate RPC implementation. //! -//! A collection of RPC methods and subscriptions supported by all substrate clients. +//! A core implementation of Substrate RPC interfaces. #![warn(missing_docs)] -mod errors; mod helpers; mod metadata; -mod subscriptions; -use jsonrpc_core as rpc; - -pub use metadata::Metadata; +pub use api::Subscriptions; +pub use self::metadata::Metadata; pub use rpc::IoHandlerExtension as RpcExtension; -pub use subscriptions::Subscriptions; pub mod author; pub mod chain; diff --git a/core/rpc/src/metadata.rs b/core/rpc/src/metadata.rs index 4567b8fabc..73bf583765 100644 --- a/core/rpc/src/metadata.rs +++ b/core/rpc/src/metadata.rs @@ -18,7 +18,7 @@ use std::sync::Arc; use jsonrpc_pubsub::{Session, PubSubMetadata}; -use crate::rpc::futures::sync::mpsc; +use rpc::futures::sync::mpsc; /// RPC Metadata. /// @@ -30,7 +30,7 @@ pub struct Metadata { session: Option>, } -impl crate::rpc::Metadata for Metadata {} +impl rpc::Metadata for Metadata {} impl PubSubMetadata for Metadata { fn session(&self) -> Option> { self.session.clone() diff --git a/core/rpc/src/state/mod.rs b/core/rpc/src/state/mod.rs index 0044ad77b8..8e44275f1e 100644 --- a/core/rpc/src/state/mod.rs +++ b/core/rpc/src/state/mod.rs @@ -16,8 +16,6 @@ //! Substrate state API. -pub mod error; - #[cfg(test)] mod tests; @@ -29,10 +27,9 @@ use std::{ use futures03::{future, StreamExt as _, TryStreamExt as _}; use client::{self, Client, CallExecutor, BlockchainEvents, runtime_api::Metadata}; -use crate::rpc::Result as RpcResult; -use crate::rpc::futures::{stream, Future, Sink, Stream}; -use crate::subscriptions::Subscriptions; -use jsonrpc_derive::rpc; +use rpc::Result as RpcResult; +use rpc::futures::{stream, Future, Sink, Stream}; +use api::Subscriptions; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use log::{warn, trace}; use primitives::hexdisplay::HexDisplay; @@ -44,123 +41,10 @@ use sr_primitives::traits::{ SaturatedConversion }; use runtime_version::RuntimeVersion; -use self::error::Result; +use self::error::{Error, Result}; use state_machine::{self, ExecutionStrategy}; -pub use self::gen_client::Client as StateClient; - -/// Substrate state API -#[rpc] -pub trait StateApi { - /// RPC Metadata - type Metadata; - - /// Call a contract at a block's state. - #[rpc(name = "state_call", alias("state_callAt"))] - fn call(&self, name: String, bytes: Bytes, hash: Option) -> Result; - - /// Returns the keys with prefix, leave empty to get all the keys - #[rpc(name = "state_getKeys")] - fn storage_keys(&self, prefix: StorageKey, hash: Option) -> Result>; - - /// Returns a storage entry at a specific block's state. - #[rpc(name = "state_getStorage", alias("state_getStorageAt"))] - fn storage(&self, key: StorageKey, hash: Option) -> Result>; - - /// Returns the hash of a storage entry at a block's state. - #[rpc(name = "state_getStorageHash", alias("state_getStorageHashAt"))] - fn storage_hash(&self, key: StorageKey, hash: Option) -> Result>; - - /// Returns the size of a storage entry at a block's state. - #[rpc(name = "state_getStorageSize", alias("state_getStorageSizeAt"))] - fn storage_size(&self, key: StorageKey, hash: Option) -> Result>; - - /// Returns the keys with prefix from a child storage, leave empty to get all the keys - #[rpc(name = "state_getChildKeys")] - fn child_storage_keys( - &self, - child_storage_key: StorageKey, - prefix: StorageKey, - hash: Option - ) -> Result>; - - /// Returns a child storage entry at a specific block's state. - #[rpc(name = "state_getChildStorage")] - fn child_storage( - &self, - child_storage_key: StorageKey, - key: StorageKey, - hash: Option - ) -> Result>; - - /// Returns the hash of a child storage entry at a block's state. - #[rpc(name = "state_getChildStorageHash")] - fn child_storage_hash( - &self, - child_storage_key: StorageKey, - key: StorageKey, - hash: Option - ) -> Result>; - - /// Returns the size of a child storage entry at a block's state. - #[rpc(name = "state_getChildStorageSize")] - fn child_storage_size( - &self, - child_storage_key: StorageKey, - key: StorageKey, - hash: Option - ) -> Result>; - - /// Returns the runtime metadata as an opaque blob. - #[rpc(name = "state_getMetadata")] - fn metadata(&self, hash: Option) -> Result; - - /// Get the runtime version. - #[rpc(name = "state_getRuntimeVersion", alias("chain_getRuntimeVersion"))] - fn runtime_version(&self, hash: Option) -> Result; - - /// Query historical storage entries (by key) starting from a block given as the second parameter. - /// - /// NOTE This first returned result contains the initial state of storage for all keys. - /// Subsequent values in the vector represent changes to the previous state (diffs). - #[rpc(name = "state_queryStorage")] - fn query_storage( - &self, - keys: Vec, - block: Hash, - hash: Option - ) -> Result>>; - - /// New runtime version subscription - #[pubsub( - subscription = "state_runtimeVersion", - subscribe, - name = "state_subscribeRuntimeVersion", - alias("chain_subscribeRuntimeVersion") - )] - fn subscribe_runtime_version(&self, metadata: Self::Metadata, subscriber: Subscriber); - - /// Unsubscribe from runtime version subscription - #[pubsub( - subscription = "state_runtimeVersion", - unsubscribe, - name = "state_unsubscribeRuntimeVersion", - alias("chain_unsubscribeRuntimeVersion") - )] - fn unsubscribe_runtime_version(&self, metadata: Option, id: SubscriptionId) -> RpcResult; - - /// New storage subscription - #[pubsub(subscription = "state_storage", subscribe, name = "state_subscribeStorage")] - fn subscribe_storage( - &self, metadata: Self::Metadata, subscriber: Subscriber>, keys: Option> - ); - - /// Unsubscribe from storage subscription - #[pubsub(subscription = "state_storage", unsubscribe, name = "state_unsubscribeStorage")] - fn unsubscribe_storage( - &self, metadata: Option, id: SubscriptionId - ) -> RpcResult; -} +pub use api::state::*; /// State API with subscriptions support. pub struct State { @@ -184,6 +68,10 @@ struct QueryStorageRange { pub filtered_range: Option>, } +fn client_err(err: client::error::Error) -> Error { + Error::Client(Box::new(err)) +} + impl State where Block: BlockT, B: client::backend::Backend, @@ -206,8 +94,8 @@ impl State where to: Option ) -> Result> { let to = self.unwrap_or_best(to)?; - let from_hdr = self.client.header(&BlockId::hash(from))?; - let to_hdr = self.client.header(&BlockId::hash(to))?; + let from_hdr = self.client.header(&BlockId::hash(from)).map_err(client_err)?; + let to_hdr = self.client.header(&BlockId::hash(to)).map_err(client_err)?; match (from_hdr, to_hdr) { (Some(ref from), Some(ref to)) if from.number() <= to.number() => { // check if we can get from `to` to `from` by going through parent_hashes. @@ -216,7 +104,10 @@ impl State where let mut blocks = vec![to.hash()]; let mut last = to.clone(); while *last.number() > from_number { - if let Some(hdr) = self.client.header(&BlockId::hash(*last.parent_hash()))? { + let hdr = self.client + .header(&BlockId::hash(*last.parent_hash())) + .map_err(client_err)?; + if let Some(hdr) = hdr { blocks.push(hdr.hash()); last = hdr; } else { @@ -238,7 +129,9 @@ impl State where blocks }; // check if we can filter blocks-with-changes from some (sub)range using changes tries - let changes_trie_range = self.client.max_key_changes_range(from_number, BlockId::Hash(to.hash()))?; + let changes_trie_range = self.client + .max_key_changes_range(from_number, BlockId::Hash(to.hash())) + .map_err(client_err)?; let filtered_range_begin = changes_trie_range.map(|(begin, _)| (begin - from_number).saturated_into::()); let (unfiltered_range, filtered_range) = split_range(blocks.len(), filtered_range_begin); Ok(QueryStorageRange { @@ -268,7 +161,8 @@ impl State where let id = BlockId::hash(block_hash); for key in keys { let (has_changed, data) = { - let curr_data = self.client.storage(&id, key)?; + let curr_data = self.client.storage(&id, key) + .map_err(client_err)?; match last_values.get(key) { Some(prev_data) => (curr_data != *prev_data, curr_data), None => (true, curr_data), @@ -305,14 +199,14 @@ impl State where for key in keys { let mut last_block = None; let mut last_value = last_values.get(key).cloned().unwrap_or_default(); - for (block, _) in self.client.key_changes(begin, end, key)?.into_iter().rev() { + for (block, _) in self.client.key_changes(begin, end, key).map_err(client_err)?.into_iter().rev() { if last_block == Some(block) { continue; } let block_hash = range.hashes[(block - range.first_number).saturated_into::()].clone(); let id = BlockId::Hash(block_hash); - let value_at_block = self.client.storage(&id, key)?; + let value_at_block = self.client.storage(&id, key).map_err(client_err)?; if last_value == value_at_block { continue; } @@ -360,26 +254,27 @@ impl StateApi for State where .call( &BlockId::Hash(block), &method, &data.0, ExecutionStrategy::NativeElseWasm, state_machine::NeverOffchainExt::new(), - )?; + ) + .map_err(client_err)?; Ok(Bytes(return_data)) } fn storage_keys(&self, key_prefix: StorageKey, block: Option) -> Result> { let block = self.unwrap_or_best(block)?; trace!(target: "rpc", "Querying storage keys at {:?}", block); - Ok(self.client.storage_keys(&BlockId::Hash(block), &key_prefix)?) + Ok(self.client.storage_keys(&BlockId::Hash(block), &key_prefix).map_err(client_err)?) } fn storage(&self, key: StorageKey, block: Option) -> Result> { let block = self.unwrap_or_best(block)?; trace!(target: "rpc", "Querying storage at {:?} for key {}", block, HexDisplay::from(&key.0)); - Ok(self.client.storage(&BlockId::Hash(block), &key)?) + Ok(self.client.storage(&BlockId::Hash(block), &key).map_err(client_err)?) } fn storage_hash(&self, key: StorageKey, block: Option) -> Result> { let block = self.unwrap_or_best(block)?; trace!(target: "rpc", "Querying storage hash at {:?} for key {}", block, HexDisplay::from(&key.0)); - Ok(self.client.storage_hash(&BlockId::Hash(block), &key)?) + Ok(self.client.storage_hash(&BlockId::Hash(block), &key).map_err(client_err)?) } fn storage_size(&self, key: StorageKey, block: Option) -> Result> { @@ -394,7 +289,10 @@ impl StateApi for State where ) -> Result> { let block = self.unwrap_or_best(block)?; trace!(target: "rpc", "Querying child storage at {:?} for key {}", block, HexDisplay::from(&key.0)); - Ok(self.client.child_storage(&BlockId::Hash(block), &child_storage_key, &key)?) + Ok(self.client + .child_storage(&BlockId::Hash(block), &child_storage_key, &key) + .map_err(client_err)? + ) } fn child_storage_keys( @@ -405,7 +303,10 @@ impl StateApi for State where ) -> Result> { let block = self.unwrap_or_best(block)?; trace!(target: "rpc", "Querying child storage keys at {:?}", block); - Ok(self.client.child_storage_keys(&BlockId::Hash(block), &child_storage_key, &key_prefix)?) + Ok(self.client + .child_storage_keys(&BlockId::Hash(block), &child_storage_key, &key_prefix) + .map_err(client_err)? + ) } fn child_storage_hash( @@ -420,7 +321,10 @@ impl StateApi for State where block, HexDisplay::from(&key.0), ); - Ok(self.client.child_storage_hash(&BlockId::Hash(block), &child_storage_key, &key)?) + Ok(self.client + .child_storage_hash(&BlockId::Hash(block), &child_storage_key, &key) + .map_err(client_err)? + ) } fn child_storage_size( @@ -434,7 +338,11 @@ impl StateApi for State where fn metadata(&self, block: Option) -> Result { let block = self.unwrap_or_best(block)?; - self.client.runtime_api().metadata(&BlockId::Hash(block)).map(Into::into).map_err(Into::into) + self.client + .runtime_api() + .metadata(&BlockId::Hash(block)) + .map(Into::into) + .map_err(client_err) } fn query_storage( @@ -464,7 +372,7 @@ impl StateApi for State where ) { Ok(stream) => stream, Err(err) => { - let _ = subscriber.reject(error::Error::from(err).into()); + let _ = subscriber.reject(client_err(err).into()); return; }, }; @@ -508,7 +416,7 @@ impl StateApi for State where fn runtime_version(&self, at: Option) -> Result { let at = self.unwrap_or_best(at)?; - Ok(self.client.runtime_version_at(&BlockId::Hash(at))?) + Ok(self.client.runtime_version_at(&BlockId::Hash(at)).map_err(client_err)?) } fn subscribe_runtime_version(&self, _meta: Self::Metadata, subscriber: Subscriber) { @@ -518,7 +426,7 @@ impl StateApi for State where ) { Ok(stream) => stream, Err(err) => { - let _ = subscriber.reject(error::Error::from(err).into()); + let _ = subscriber.reject(client_err(err).into()); return; } }; @@ -535,7 +443,7 @@ impl StateApi for State where let info = client.info(); let version = client .runtime_version_at(&BlockId::hash(info.chain.best_hash)) - .map_err(error::Error::from) + .map_err(client_err) .map_err(Into::into); if previous_version != version { previous_version = version.clone(); diff --git a/core/rpc/src/state/tests.rs b/core/rpc/src/state/tests.rs index 07e009d179..656abf56a9 100644 --- a/core/rpc/src/state/tests.rs +++ b/core/rpc/src/state/tests.rs @@ -90,7 +90,7 @@ fn should_call_contract() { assert_matches!( client.call("balanceOf".into(), Bytes(vec![1,2,3]), Some(genesis_hash).into()), - Err(Error::Client(client::error::Error::Execution(_))) + Err(Error::Client(_)) ) } diff --git a/core/rpc/src/system/mod.rs b/core/rpc/src/system/mod.rs index 9e347c6503..8eeff6758b 100644 --- a/core/rpc/src/system/mod.rs +++ b/core/rpc/src/system/mod.rs @@ -16,62 +16,18 @@ //! Substrate system API. -pub mod error; -pub mod helpers; - #[cfg(test)] mod tests; -use crate::helpers::Receiver; use futures03::{channel::{mpsc, oneshot}, compat::Compat}; -use jsonrpc_derive::rpc; -use network; +use api::Receiver; use sr_primitives::traits::{self, Header as HeaderT}; - use self::error::Result; +pub use api::system::*; pub use self::helpers::{Properties, SystemInfo, Health, PeerInfo}; pub use self::gen_client::Client as SystemClient; -/// Substrate system RPC API -#[rpc] -pub trait SystemApi { - /// Get the node's implementation name. Plain old string. - #[rpc(name = "system_name")] - fn system_name(&self) -> Result; - - /// Get the node implementation's version. Should be a semver string. - #[rpc(name = "system_version")] - fn system_version(&self) -> Result; - - /// Get the chain's type. Given as a string identifier. - #[rpc(name = "system_chain")] - fn system_chain(&self) -> Result; - - /// Get a custom set of properties as a JSON object, defined in the chain spec. - #[rpc(name = "system_properties")] - fn system_properties(&self) -> Result; - - /// Return health status of the node. - /// - /// Node is considered healthy if it is: - /// - connected to some peers (unless running in dev mode) - /// - not performing a major sync - #[rpc(name = "system_health", returns = "Health")] - fn system_health(&self) -> Receiver; - - /// Returns currently connected peers - #[rpc(name = "system_peers", returns = "Vec>")] - fn system_peers(&self) -> Receiver>>; - - /// Returns current state of the network. - /// - /// **Warning**: This API is not stable. - // TODO: make this stable and move structs https://github.com/paritytech/substrate/issues/1890 - #[rpc(name = "system_networkState", returns = "network::NetworkState")] - fn system_network_state(&self) -> Receiver; -} - /// System API implementation pub struct System { info: SystemInfo, @@ -85,7 +41,7 @@ pub enum Request { /// Must return information about the peers we are connected to. Peers(oneshot::Sender::Number>>>), /// Must return the state of the network. - NetworkState(oneshot::Sender), + NetworkState(oneshot::Sender), } impl System { @@ -133,7 +89,7 @@ impl SystemApi::Number> for Sy Receiver(Compat::new(rx)) } - fn system_network_state(&self) -> Receiver { + fn system_network_state(&self) -> Receiver { let (tx, rx) = oneshot::channel(); let _ = self.send_back.unbounded_send(Request::NetworkState(tx)); Receiver(Compat::new(rx)) diff --git a/core/rpc/src/system/tests.rs b/core/rpc/src/system/tests.rs index 70e8b4b95b..5b271af9ac 100644 --- a/core/rpc/src/system/tests.rs +++ b/core/rpc/src/system/tests.rs @@ -69,7 +69,7 @@ fn api>>(sync: T) -> System { let _ = sender.send(peers); } Request::NetworkState(sender) => { - let _ = sender.send(network::NetworkState { + let _ = sender.send(serde_json::to_value(&network::NetworkState { peer_id: String::new(), listened_addresses: Default::default(), external_addresses: Default::default(), @@ -78,7 +78,7 @@ fn api>>(sync: T) -> System { average_download_per_sec: 0, average_upload_per_sec: 0, peerset: serde_json::Value::Null, - }); + }).unwrap()); } }; @@ -206,8 +206,9 @@ fn system_peers() { #[test] fn system_network_state() { + let res = wait_receiver(api(None).system_network_state()); assert_eq!( - wait_receiver(api(None).system_network_state()), + serde_json::from_value::(res).unwrap(), network::NetworkState { peer_id: String::new(), listened_addresses: Default::default(), diff --git a/core/service/src/lib.rs b/core/service/src/lib.rs index 1362e86c21..a19121188a 100644 --- a/core/service/src/lib.rs +++ b/core/service/src/lib.rs @@ -725,7 +725,9 @@ fn build_network_future< ).collect()); } rpc::system::Request::NetworkState(sender) => { - let _ = sender.send(network.network_state()); + if let Some(network_state) = serde_json::to_value(&network.network_state()).ok() { + let _ = sender.send(network_state); + } } }; } -- GitLab From 7004308c475e34f7138aac6ce5407b1aa10a94f3 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Thu, 29 Aug 2019 11:07:49 +0200 Subject: [PATCH 036/275] Decouple Phragmen from Staking. (#3498) * Move phragmen to primitives * Improved docs * New crate. * Update lock. * Fix dependency. * Fix build. * Add basic testing and truth-value implementation with float types * Update srml/staking/src/lib.rs * Nits. * Bump. * Fix benchmarks. --- Cargo.lock | 10 + core/phragmen/Cargo.toml | 19 + core/phragmen/src/lib.rs | 714 ++++++++++++++++++++++++++++++++++ core/sr-primitives/src/lib.rs | 2 +- node/runtime/src/lib.rs | 2 +- srml/staking/Cargo.toml | 2 + srml/staking/src/benches.rs | 83 ++-- srml/staking/src/lib.rs | 121 +++--- srml/staking/src/mock.rs | 6 +- srml/staking/src/phragmen.rs | 393 ------------------- srml/staking/src/tests.rs | 12 +- 11 files changed, 848 insertions(+), 516 deletions(-) create mode 100644 core/phragmen/Cargo.toml create mode 100644 core/phragmen/src/lib.rs delete mode 100644 srml/staking/src/phragmen.rs diff --git a/Cargo.lock b/Cargo.lock index 9b6926af8c..7cdf58413b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4169,6 +4169,7 @@ dependencies = [ "srml-system 2.0.0", "srml-timestamp 2.0.0", "substrate-keyring 2.0.0", + "substrate-phragmen 2.0.0", "substrate-primitives 2.0.0", ] @@ -4931,6 +4932,15 @@ dependencies = [ "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "substrate-phragmen" +version = "2.0.0" +dependencies = [ + "sr-primitives 2.0.0", + "sr-std 2.0.0", + "srml-support 2.0.0", +] + [[package]] name = "substrate-primitives" version = "2.0.0" diff --git a/core/phragmen/Cargo.toml b/core/phragmen/Cargo.toml new file mode 100644 index 0000000000..335bddb401 --- /dev/null +++ b/core/phragmen/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "substrate-phragmen" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +sr-primitives = { path = "../sr-primitives", default-features = false } +rstd = { package = "sr-std", path = "../sr-std", default-features = false } + +[dev-dependencies] +support = { package = "srml-support", path = "../../srml/support" } + +[features] +default = ["std"] +std = [ + "rstd/std", + "sr-primitives/std", +] diff --git a/core/phragmen/src/lib.rs b/core/phragmen/src/lib.rs new file mode 100644 index 0000000000..459254370b --- /dev/null +++ b/core/phragmen/src/lib.rs @@ -0,0 +1,714 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Rust implementation of the Phragmén election algorithm. This is used in several SRML modules to +//! optimally distribute the weight of a set of voters among an elected set of candidates. In the +//! context of staking this is mapped to validators and nominators. +//! +//! The algorithm has two phases: +//! - Sequential phragmen: performed in [`elect`] function which is first pass of the distribution +//! The results are not optimal but the execution time is less. +//! - Equalize post-processing: tries to further distribute the weight fairly among candidates. +//! Incurs more execution time. +//! +//! The main objective of the assignments done by phragmen is to maximize the minimum backed +//! candidate in the elected set. +//! +//! Reference implementation: https://github.com/w3f/consensus +//! Further details: +//! https://research.web3.foundation/en/latest/polkadot/NPoS/4.%20Sequential%20Phragm%C3%A9n%E2%80%99s%20method/ + +#![cfg_attr(not(feature = "std"), no_std)] + +use rstd::{prelude::*, collections::btree_map::BTreeMap}; +use sr_primitives::PerU128; +use sr_primitives::traits::{Zero, Convert, Member, SimpleArithmetic}; + +/// Type used as the fraction. +type Fraction = PerU128; + +/// A type in which performing operations on balances and stakes of candidates and voters are safe. +/// +/// This module's functions expect a `Convert` type to convert all balances to u64. Hence, u128 is +/// a safe type for arithmetic operations over them. +/// +/// Balance types converted to `ExtendedBalance` are referred to as `Votes`. +pub type ExtendedBalance = u128; + +// this is only used while creating the candidate score. Due to reasons explained below +// The more accurate this is, the less likely we choose a wrong candidate. +// TODO: can be removed with proper use of per-things #2908 +const SCALE_FACTOR: ExtendedBalance = u32::max_value() as ExtendedBalance + 1; + +/// These are used to expose a fixed accuracy to the caller function. The bigger they are, +/// the more accurate we get, but the more likely it is for us to overflow. The case of overflow +/// is handled but accuracy will be lost. 32 or 16 are reasonable values. +// TODO: can be removed with proper use of per-things #2908 +pub const ACCURACY: ExtendedBalance = u32::max_value() as ExtendedBalance + 1; + +/// A candidate entity for phragmen election. +#[derive(Clone, Default)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct Candidate { + /// Identifier. + pub who: AccountId, + /// Intermediary value used to sort candidates. + pub score: Fraction, + /// Sum of the stake of this candidate based on received votes. + approval_stake: ExtendedBalance, + /// Flag for being elected. + elected: bool, +} + +/// A voter entity. +#[derive(Clone, Default)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct Voter { + /// Identifier. + who: AccountId, + /// List of candidates proposed by this voter. + edges: Vec>, + /// The stake of this voter. + budget: ExtendedBalance, + /// Incremented each time a candidate that this voter voted for has been elected. + load: Fraction, +} + +/// A candidate being backed by a voter. +#[derive(Clone, Default)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct Edge { + /// Identifier. + who: AccountId, + /// Load of this vote. + load: Fraction, + /// Index of the candidate stored in the 'candidates' vector. + candidate_index: usize, +} + +/// Means a particular `AccountId` was backed by a ratio of `ExtendedBalance / ACCURACY`. +pub type PhragmenAssignment = (AccountId, ExtendedBalance); + +/// Final result of the phragmen election. +pub struct PhragmenResult { + /// Just winners. + pub winners: Vec, + /// Individual assignments. for each tuple, the first elements is a voter and the second + /// is the list of candidates that it supports. + pub assignments: Vec<(AccountId, Vec>)> +} + +/// A structure to demonstrate the phragmen result from the perspective of the candidate, i.e. how +/// much support each candidate is receiving. +/// +/// This complements the [`PhragmenResult`] and is needed to run the equalize post-processing. +/// +/// This, at the current version, resembles the `Exposure` defined in the staking SRML module, yet +/// they do not necessarily have to be the same. +#[derive(Default)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct Support { + /// The amount of support as the effect of self-vote. + pub own: ExtendedBalance, + /// Total support. + pub total: ExtendedBalance, + /// Support from voters. + pub others: Vec>, +} + +/// A linkage from a candidate and its [`Support`]. +pub type SupportMap = BTreeMap>; + +/// Perform election based on Phragmén algorithm. +/// +/// Returns an `Option` the set of winners and their detailed support ratio from each voter if +/// enough candidates are provided. Returns `None` otherwise. +/// +/// * `candidate_count`: number of candidates to elect. +/// * `minimum_candidate_count`: minimum number of candidates to elect. If less candidates exist, +/// `None` is returned. +/// * `initial_candidates`: candidates list to be elected from. +/// * `initial_voters`: voters list. +/// * `stake_of`: something that can return the stake stake of a particular candidate or voter. +/// * `self_vote`. If true, then each candidate will automatically vote for themselves with the a +/// weight indicated by their stake. Note that when this is `true` candidates are filtered by +/// having at least some backed stake from themselves. +pub fn elect( + candidate_count: usize, + minimum_candidate_count: usize, + initial_candidates: Vec, + initial_voters: Vec<(AccountId, Vec)>, + stake_of: FS, + self_vote: bool, +) -> Option> where + AccountId: Default + Ord + Member, + Balance: Default + Copy + SimpleArithmetic, + for<'r> FS: Fn(&'r AccountId) -> Balance, + C: Convert + Convert, +{ + let to_votes = |b: Balance| + >::convert(b) as ExtendedBalance; + + // return structures + let mut elected_candidates: Vec; + let mut assigned: Vec<(AccountId, Vec>)>; + + // used to cache and access candidates index. + let mut c_idx_cache = BTreeMap::::new(); + + // voters list. + let num_voters = initial_candidates.len() + initial_voters.len(); + let mut voters: Vec> = Vec::with_capacity(num_voters); + + // collect candidates. self vote or filter might apply + let mut candidates = if self_vote { + // self vote. filter. + initial_candidates.into_iter().map(|who| { + let stake = stake_of(&who); + Candidate { who, approval_stake: to_votes(stake), ..Default::default() } + }) + .filter(|c| !c.approval_stake.is_zero()) + .enumerate() + .map(|(i, c)| { + voters.push(Voter { + who: c.who.clone(), + edges: vec![Edge { who: c.who.clone(), candidate_index: i, ..Default::default() }], + budget: c.approval_stake, + load: Fraction::zero(), + }); + c_idx_cache.insert(c.who.clone(), i); + c + }) + .collect::>>() + } else { + // no self vote. just collect. + initial_candidates.into_iter() + .enumerate() + .map(|(idx, who)| { + c_idx_cache.insert(who.clone(), idx); + Candidate { who, ..Default::default() } + }) + .collect::>>() + }; + + // early return if we don't have enough candidates + if candidates.len() < minimum_candidate_count { return None; } + + // collect voters. use `c_idx_cache` for fast access and aggregate `approval_stake` of + // candidates. + voters.extend(initial_voters.into_iter().map(|(who, votes)| { + let voter_stake = stake_of(&who); + let mut edges: Vec> = Vec::with_capacity(votes.len()); + for v in votes { + if let Some(idx) = c_idx_cache.get(&v) { + // This candidate is valid + already cached. + candidates[*idx].approval_stake = candidates[*idx].approval_stake + .saturating_add(to_votes(voter_stake)); + edges.push(Edge { who: v.clone(), candidate_index: *idx, ..Default::default() }); + } // else {} would be wrong votes. We don't really care about it. + } + Voter { + who, + edges: edges, + budget: to_votes(voter_stake), + load: Fraction::zero(), + } + })); + + + // we have already checked that we have more candidates than minimum_candidate_count. + // run phragmen. + let to_elect = candidate_count.min(candidates.len()); + elected_candidates = Vec::with_capacity(candidate_count); + assigned = Vec::with_capacity(candidate_count); + + // main election loop + for _round in 0..to_elect { + // loop 1: initialize score + for c in &mut candidates { + if !c.elected { + c.score = Fraction::from_xth(c.approval_stake); + } + } + // loop 2: increment score + for n in &voters { + for e in &n.edges { + let c = &mut candidates[e.candidate_index]; + if !c.elected && !c.approval_stake.is_zero() { + // Basic fixed-point shifting by 32. + // `n.budget.saturating_mul(SCALE_FACTOR)` will never saturate + // since n.budget cannot exceed u64,despite being stored in u128. yet, + // `*n.load / SCALE_FACTOR` might collapse to zero. Hence, 32 or 16 bits are + // better scale factors. Note that left-associativity in operators precedence is + // crucially important here. + let temp = + n.budget.saturating_mul(SCALE_FACTOR) / c.approval_stake + * (*n.load / SCALE_FACTOR); + c.score = Fraction::from_parts((*c.score).saturating_add(temp)); + } + } + } + + // loop 3: find the best + if let Some(winner) = candidates + .iter_mut() + .filter(|c| !c.elected) + .min_by_key(|c| *c.score) + { + // loop 3: update voter and edge load + winner.elected = true; + for n in &mut voters { + for e in &mut n.edges { + if e.who == winner.who { + e.load = Fraction::from_parts(*winner.score - *n.load); + n.load = winner.score; + } + } + } + + elected_candidates.push(winner.who.clone()); + } else { + break + } + } // end of all rounds + + // update backing stake of candidates and voters + for n in &mut voters { + let mut assignment = (n.who.clone(), vec![]); + for e in &mut n.edges { + if let Some(c) = elected_candidates.iter().cloned().find(|c| *c == e.who) { + if c != n.who { + let ratio = { + // Full support. No need to calculate. + if *n.load == *e.load { ACCURACY } + else { + // This should not saturate. Safest is to just check + if let Some(r) = ACCURACY.checked_mul(*e.load) { + r / n.load.max(1) + } else { + // Just a simple trick. + *e.load / (n.load.max(1) / ACCURACY) + } + } + }; + assignment.1.push((e.who.clone(), ratio)); + } + } + } + + if assignment.1.len() > 0 { + // To ensure an assertion indicating: no stake from the voter going to waste, we add + // a minimal post-processing to equally assign all of the leftover stake ratios. + let vote_count = assignment.1.len() as ExtendedBalance; + let l = assignment.1.len(); + let sum = assignment.1.iter().map(|a| a.1).sum::(); + let diff = ACCURACY.checked_sub(sum).unwrap_or(0); + let diff_per_vote= diff / vote_count; + + if diff_per_vote > 0 { + for i in 0..l { + assignment.1[i%l].1 = + assignment.1[i%l].1 + .saturating_add(diff_per_vote); + } + } + + // `remainder` is set to be less than maximum votes of a voter (currently 16). + // safe to cast it to usize. + let remainder = diff - diff_per_vote * vote_count; + for i in 0..remainder as usize { + assignment.1[i%l].1 = + assignment.1[i%l].1 + .saturating_add(1); + } + assigned.push(assignment); + } + } + + Some(PhragmenResult { + winners: elected_candidates, + assignments: assigned, + }) +} + +/// Performs equalize post-processing to the output of the election algorithm. This happens in +/// rounds. The number of rounds and the maximum diff-per-round tolerance can be tuned through input +/// parameters. +/// +/// No value is returned from the function and the `supports` parameter is updated. +/// +/// * `assignments`: exactly the same is the output of phragmen. +/// * `supports`: mutable reference to s `SupportMap`. This parameter is updated. +/// * `tolerance`: maximum difference that can occur before an early quite happens. +/// * `iterations`: maximum number of iterations that will be processed. +/// * `stake_of`: something that can return the stake stake of a particular candidate or voter. +pub fn equalize( + mut assignments: Vec<(AccountId, Vec>)>, + supports: &mut SupportMap, + tolerance: ExtendedBalance, + iterations: usize, + stake_of: FS, +) where + C: Convert + Convert, + for<'r> FS: Fn(&'r AccountId) -> Balance, + AccountId: Ord + Clone, +{ + // prepare the data for equalise + for _i in 0..iterations { + let mut max_diff = 0; + + for (voter, assignment) in assignments.iter_mut() { + let voter_budget = stake_of(&voter); + + let diff = do_equalize::<_, _, C>( + voter, + voter_budget, + assignment, + supports, + tolerance, + ); + if diff > max_diff { max_diff = diff; } + } + + if max_diff < tolerance { + break; + } + } +} + +/// actually perform equalize. same interface is `equalize`. Just called in loops with a check for +/// maximum difference. +fn do_equalize( + voter: &AccountId, + budget_balance: Balance, + elected_edges: &mut Vec<(AccountId, ExtendedBalance)>, + support_map: &mut SupportMap, + tolerance: ExtendedBalance +) -> ExtendedBalance where + C: Convert + Convert, + AccountId: Ord + Clone, +{ + let to_votes = |b: Balance| + >::convert(b) as ExtendedBalance; + let budget = to_votes(budget_balance); + + // Nothing to do. This voter had nothing useful. + // Defensive only. Assignment list should always be populated. + if elected_edges.is_empty() { return 0; } + + let stake_used = elected_edges + .iter() + .fold(0 as ExtendedBalance, |s, e| s.saturating_add(e.1)); + + let backed_stakes_iter = elected_edges + .iter() + .filter_map(|e| support_map.get(&e.0)) + .map(|e| e.total); + + let backing_backed_stake = elected_edges + .iter() + .filter(|e| e.1 > 0) + .filter_map(|e| support_map.get(&e.0)) + .map(|e| e.total) + .collect::>(); + + let mut difference; + if backing_backed_stake.len() > 0 { + let max_stake = backing_backed_stake + .iter() + .max() + .expect("vector with positive length will have a max; qed"); + let min_stake = backed_stakes_iter + .min() + .expect("iterator with positive length will have a min; qed"); + + difference = max_stake.saturating_sub(min_stake); + difference = difference.saturating_add(budget.saturating_sub(stake_used)); + if difference < tolerance { + return difference; + } + } else { + difference = budget; + } + + // Undo updates to support + elected_edges.iter_mut().for_each(|e| { + if let Some(support) = support_map.get_mut(&e.0) { + support.total = support.total.saturating_sub(e.1); + support.others.retain(|i_support| i_support.0 != *voter); + } + e.1 = 0; + }); + + elected_edges.sort_unstable_by_key(|e| + if let Some(e) = support_map.get(&e.0) { e.total } else { Zero::zero() } + ); + + let mut cumulative_stake: ExtendedBalance = 0; + let mut last_index = elected_edges.len() - 1; + elected_edges.iter_mut().enumerate().for_each(|(idx, e)| { + if let Some(support) = support_map.get_mut(&e.0) { + let stake: ExtendedBalance = support.total; + let stake_mul = stake.saturating_mul(idx as ExtendedBalance); + let stake_sub = stake_mul.saturating_sub(cumulative_stake); + if stake_sub > budget { + last_index = idx.checked_sub(1).unwrap_or(0); + return + } + cumulative_stake = cumulative_stake.saturating_add(stake); + } + }); + + let last_stake = elected_edges[last_index].1; + let split_ways = last_index + 1; + let excess = budget + .saturating_add(cumulative_stake) + .saturating_sub(last_stake.saturating_mul(split_ways as ExtendedBalance)); + elected_edges.iter_mut().take(split_ways).for_each(|e| { + if let Some(support) = support_map.get_mut(&e.0) { + e.1 = (excess / split_ways as ExtendedBalance) + .saturating_add(last_stake) + .saturating_sub(support.total); + support.total = support.total.saturating_add(e.1); + support.others.push((voter.clone(), e.1)); + } + }); + + difference +} + +#[cfg(test)] +mod tests { + use super::{elect, ACCURACY, PhragmenResult}; + use sr_primitives::traits::{Convert, Member, SaturatedConversion}; + use rstd::collections::btree_map::BTreeMap; + use support::assert_eq_uvec; + + pub struct C; + impl Convert for C { + fn convert(x: u64) -> u64 { x } + } + impl Convert for C { + fn convert(x: u128) -> u64 { x.saturated_into() } + } + + #[derive(Default, Debug)] + struct _Candidate { + who: AccountId, + score: f64, + approval_stake: f64, + elected: bool, + } + + #[derive(Default, Debug)] + struct _Voter { + who: AccountId, + edges: Vec<_Edge>, + budget: f64, + load: f64, + } + + #[derive(Default, Debug)] + struct _Edge { + who: AccountId, + load: f64, + candidate_index: usize, + } + + type _PhragmenAssignment = (AccountId, f64); + + #[derive(Debug)] + pub struct _PhragmenResult { + pub winners: Vec, + pub assignments: Vec<(AccountId, Vec<_PhragmenAssignment>)> + } + + pub fn elect_poc( + candidate_count: usize, + minimum_candidate_count: usize, + initial_candidates: Vec, + initial_voters: Vec<(AccountId, Vec)>, + stake_of: FS, + self_vote: bool, + ) -> Option<_PhragmenResult> where + AccountId: Default + Ord + Member + Copy, + for<'r> FS: Fn(&'r AccountId) -> u64, + { + let mut elected_candidates: Vec; + let mut assigned: Vec<(AccountId, Vec<_PhragmenAssignment>)>; + let mut c_idx_cache = BTreeMap::::new(); + let num_voters = initial_candidates.len() + initial_voters.len(); + let mut voters: Vec<_Voter> = Vec::with_capacity(num_voters); + + let mut candidates = if self_vote { + initial_candidates.into_iter().map(|who| { + let stake = stake_of(&who) as f64; + _Candidate { who, approval_stake: stake, ..Default::default() } + }) + .filter(|c| c.approval_stake != 0f64) + .enumerate() + .map(|(i, c)| { + let who = c.who; + voters.push(_Voter { + who: who.clone(), + edges: vec![ + _Edge { who: who.clone(), candidate_index: i, ..Default::default() } + ], + budget: c.approval_stake, + load: 0f64, + }); + c_idx_cache.insert(c.who.clone(), i); + c + }) + .collect::>>() + } else { + initial_candidates.into_iter() + .enumerate() + .map(|(idx, who)| { + c_idx_cache.insert(who.clone(), idx); + _Candidate { who, ..Default::default() } + }) + .collect::>>() + }; + + if candidates.len() < minimum_candidate_count { + return None; + } + + voters.extend(initial_voters.into_iter().map(|(who, votes)| { + let voter_stake = stake_of(&who) as f64; + let mut edges: Vec<_Edge> = Vec::with_capacity(votes.len()); + for v in votes { + if let Some(idx) = c_idx_cache.get(&v) { + candidates[*idx].approval_stake = candidates[*idx].approval_stake + voter_stake; + edges.push( + _Edge { who: v.clone(), candidate_index: *idx, ..Default::default() } + ); + } + } + _Voter { + who, + edges: edges, + budget: voter_stake, + load: 0f64, + } + })); + + let to_elect = candidate_count.min(candidates.len()); + elected_candidates = Vec::with_capacity(candidate_count); + assigned = Vec::with_capacity(candidate_count); + + for _round in 0..to_elect { + for c in &mut candidates { + if !c.elected { + c.score = 1.0 / c.approval_stake; + } + } + for n in &voters { + for e in &n.edges { + let c = &mut candidates[e.candidate_index]; + if !c.elected && !(c.approval_stake == 0f64) { + c.score += n.budget * n.load / c.approval_stake; + } + } + } + + if let Some(winner) = candidates + .iter_mut() + .filter(|c| !c.elected) + .min_by(|x, y| x.score.partial_cmp(&y.score).unwrap_or(rstd::cmp::Ordering::Equal)) + { + winner.elected = true; + for n in &mut voters { + for e in &mut n.edges { + if e.who == winner.who { + e.load = winner.score - n.load; + n.load = winner.score; + } + } + } + + elected_candidates.push(winner.who.clone()); + } else { + break + } + } + + for n in &mut voters { + let mut assignment = (n.who.clone(), vec![]); + for e in &mut n.edges { + if let Some(c) = elected_candidates.iter().cloned().find(|c| *c == e.who) { + if c != n.who { + let ratio = e.load / n.load; + assignment.1.push((e.who.clone(), ratio)); + } + } + } + assigned.push(assignment); + } + + Some(_PhragmenResult { + winners: elected_candidates, + assignments: assigned, + }) + } + + #[test] + fn float_poc_works() { + let candidates = vec![1, 2, 3]; + let voters = vec![ + (10, vec![1, 2]), + (20, vec![1, 3]), + (30, vec![2, 3]), + ]; + let stake_of = |x: &u64| { if *x >= 10 { *x } else { 0 }}; + let _PhragmenResult { winners, assignments } = + elect_poc(2, 2, candidates, voters, stake_of, false).unwrap(); + + assert_eq_uvec!(winners, vec![2, 3]); + assert_eq_uvec!( + assignments, + vec![ + (10, vec![(2, 1.0)]), + (20, vec![(3, 1.0)]), + (30, vec![(2, 0.5), (3, 0.5)]) + ] + ); + } + + #[test] + fn phragmen_works() { + let candidates = vec![1, 2, 3]; + let voters = vec![ + (10, vec![1, 2]), + (20, vec![1, 3]), + (30, vec![2, 3]), + ]; + let stake_of = |x: &u64| { if *x >= 10 { *x } else { 0 }}; + let PhragmenResult { winners, assignments } = + elect::<_, _, _, C>(2, 2, candidates, voters, stake_of, false).unwrap(); + + assert_eq_uvec!(winners, vec![2, 3]); + assert_eq_uvec!( + assignments, + vec![ + (10, vec![(2, ACCURACY)]), + (20, vec![(3, ACCURACY)]), + (30, vec![(2, ACCURACY/2), (3, ACCURACY/2)]) + ] + ); + } +} diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index a6a66b80d4..41dac41f79 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -40,13 +40,13 @@ pub use runtime_io::{StorageOverlay, ChildrenStorageOverlay}; use rstd::{prelude::*, ops, convert::{TryInto, TryFrom}}; use primitives::{crypto, ed25519, sr25519, hash::{H256, H512}}; use codec::{Encode, Decode, CompactAs}; +use traits::{SaturatedConversion, UniqueSaturatedInto, Saturating, Bounded, CheckedSub, CheckedAdd}; #[cfg(feature = "std")] pub mod testing; pub mod weights; pub mod traits; -use traits::{SaturatedConversion, UniqueSaturatedInto, Saturating, Bounded, CheckedSub, CheckedAdd}; pub mod generic; pub mod transaction_validity; diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 0360827e9a..a36801c44b 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -80,7 +80,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 154, - impl_version: 155, + impl_version: 156, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/staking/Cargo.toml b/srml/staking/Cargo.toml index d985730912..a29b4aa4b9 100644 --- a/srml/staking/Cargo.toml +++ b/srml/staking/Cargo.toml @@ -10,6 +10,7 @@ safe-mix = { version = "1.0", default-features = false} codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } substrate-keyring = { path = "../../core/keyring", optional = true } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } +phragmen = { package = "substrate-phragmen", path = "../../core/phragmen", default-features = false } runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } sr-staking-primitives = { path = "../../core/sr-staking-primitives", default-features = false } @@ -34,6 +35,7 @@ std = [ "substrate-keyring", "codec/std", "rstd/std", + "phragmen/std", "runtime_io/std", "srml-support/std", "sr-primitives/std", diff --git a/srml/staking/src/benches.rs b/srml/staking/src/benches.rs index 6e79ee70a4..e9c3667984 100644 --- a/srml/staking/src/benches.rs +++ b/srml/staking/src/benches.rs @@ -27,6 +27,7 @@ use test::Bencher; use runtime_io::with_externalities; use mock::*; use super::*; +use phragmen; use rand::{self, Rng}; const VALIDATORS: u64 = 1000; @@ -35,6 +36,8 @@ const EDGES: u64 = 2; const TO_ELECT: usize = 100; const STAKE: u64 = 1000; +type C = ::CurrencyToVote; + fn do_phragmen( b: &mut Bencher, num_vals: u64, @@ -42,7 +45,7 @@ fn do_phragmen( count: usize, votes_per: u64, eq_iters: usize, - eq_tolerance: u128, + _eq_tolerance: u128, ) { with_externalities(&mut ExtBuilder::default().nominate(false).build(), || { assert!(num_vals > votes_per); @@ -71,67 +74,55 @@ fn do_phragmen( }); b.iter(|| { - let r = phragmen::elect::( + let r = phragmen::elect::<_, _, _, ::CurrencyToVote>( count, 1_usize, - >::enumerate(), - >::enumerate(), - Staking::slashable_balance_of + >::enumerate().map(|(who, _)| who).collect::>(), + >::enumerate().collect(), + Staking::slashable_balance_of, + true, ).unwrap(); // Do the benchmarking with equalize. if eq_iters > 0 { - let elected_stashes = r.0; - let assignments = r.1; + let elected_stashes = r.winners; + let mut assignments = r.assignments; - let to_balance = |b: ExtendedBalance| - <::CurrencyToVote as Convert>::convert(b); let to_votes = |b: Balance| - <::CurrencyToVote as Convert>::convert(b) as ExtendedBalance; - let ratio_of = |b, p| (p as ExtendedBalance).saturating_mul(to_votes(b)) / ACCURACY; - - let assignments_with_stakes = assignments.into_iter().map(|(n, a)|( - n, - Staking::slashable_balance_of(&n), - a.into_iter().map(|(acc, r)| ( - acc.clone(), - r, - to_balance(ratio_of(Staking::slashable_balance_of(&n), r)), - )) - .collect::>>() - )).collect::>)>>(); - - let mut exposures = >::new(); + as Convert>::convert(b) as ExtendedBalance; + let ratio_of = |b, r: ExtendedBalance| r.saturating_mul(to_votes(b)) / ACCURACY; + + // Initialize the support of each candidate. + let mut supports = >::new(); elected_stashes - .into_iter() - .map(|e| (e, Staking::slashable_balance_of(&e))) + .iter() + .map(|e| (e, to_votes(Staking::slashable_balance_of(e)))) .for_each(|(e, s)| { - let item = Exposure { own: s, total: s, ..Default::default() }; - exposures.insert(e, item); + let item = Support { own: s, total: s, ..Default::default() }; + supports.insert(e.clone(), item); }); - for (n, _, assignment) in &assignments_with_stakes { - for (c, _, s) in assignment { - if let Some(expo) = exposures.get_mut(c) { - expo.total = expo.total.saturating_add(*s); - expo.others.push( IndividualExposure { who: n.clone(), value: *s } ); + for (n, assignment) in assignments.iter_mut() { + for (c, r) in assignment.iter_mut() { + let nominator_stake = Staking::slashable_balance_of(n); + let other_stake = ratio_of(nominator_stake, *r); + if let Some(support) = supports.get_mut(c) { + support.total = support.total.saturating_add(other_stake); + support.others.push((n.clone(), other_stake)); } + *r = other_stake; } } - let mut assignments_with_votes = assignments_with_stakes.into_iter() - .map(|a| ( - a.0, a.1, - a.2.into_iter() - .map(|e| (e.0, e.1, to_votes(e.2))) - .collect::>() - )) - .collect:: - )>>(); - equalize::(&mut assignments_with_votes, &mut exposures, eq_tolerance, eq_iters); + let tolerance = 0_u128; + let iterations = 2_usize; + phragmen::equalize::<_, _, ::CurrencyToVote, _>( + assignments, + &mut supports, + tolerance, + iterations, + Staking::slashable_balance_of, + ); } }) }) diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index 2e46d6b2b4..d0c60bfa46 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -254,7 +254,6 @@ mod mock; #[cfg(test)] mod tests; -mod phragmen; pub mod inflation; #[cfg(all(feature = "bench", test))] @@ -262,7 +261,7 @@ mod benches; #[cfg(feature = "std")] use runtime_io::with_storage; -use rstd::{prelude::*, result, collections::btree_map::BTreeMap}; +use rstd::{prelude::*, result}; use codec::{HasCompact, Encode, Decode}; use srml_support::{ StorageValue, StorageMap, EnumerableStorageMap, decl_module, decl_event, @@ -275,9 +274,10 @@ use session::{historical::OnSessionEnding, SelectInitialValidators}; use sr_primitives::Perbill; use sr_primitives::weights::SimpleDispatchInfo; use sr_primitives::traits::{ - Convert, Zero, One, StaticLookup, CheckedSub, Saturating, Bounded, - SimpleArithmetic, SaturatedConversion, + Convert, Zero, One, StaticLookup, CheckedSub, Saturating, Bounded, SimpleArithmetic, + SaturatedConversion, }; +use phragmen::{elect, equalize, Support, SupportMap, ExtendedBalance, ACCURACY}; use sr_staking_primitives::{ SessionIndex, CurrentElectedSet, offence::{OnOffenceHandler, OffenceDetails, Offence, ReportOffence}, @@ -286,8 +286,6 @@ use sr_staking_primitives::{ use sr_primitives::{Serialize, Deserialize}; use system::{ensure_signed, ensure_root}; -use phragmen::{elect, ACCURACY, ExtendedBalance, equalize}; - const DEFAULT_MINIMUM_VALIDATOR_COUNT: u32 = 4; const MAX_NOMINATIONS: usize = 16; const MAX_UNLOCKING_CHUNKS: usize = 32; @@ -458,13 +456,6 @@ type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; type MomentOf= <::Time as Time>::Moment; -type RawAssignment = (::AccountId, ExtendedBalance); -type Assignment = (::AccountId, ExtendedBalance, BalanceOf); -type ExpoMap = BTreeMap< - ::AccountId, - Exposure<::AccountId, BalanceOf> ->; - /// Means for interacting with a specialized version of the `session` trait. /// /// This is needed because `Staking` sets the `ValidatorIdOf` of the `session::Trait` @@ -512,7 +503,7 @@ pub trait Trait: system::Trait { /// This must fit into a `u64` but is allowed to be sensibly lossy. /// TODO: #1377 /// The backward convert should be removed as the new Phragmen API returns ratio. - /// The post-processing needs it but will be moved to off-chain. + /// The post-processing needs it but will be moved to off-chain. TODO: #2908 type CurrencyToVote: Convert, u64> + Convert>; /// Some tokens minted. @@ -1254,17 +1245,18 @@ impl Module { /// /// Returns the new `SlotStake` value and a set of newly selected _stash_ IDs. fn select_validators() -> (BalanceOf, Option>) { - let maybe_elected_set = elect::( + let maybe_phragmen_result = elect::<_, _, _, T::CurrencyToVote>( Self::validator_count() as usize, Self::minimum_validator_count().max(1) as usize, - >::enumerate(), - >::enumerate(), + >::enumerate().map(|(who, _)| who).collect::>(), + >::enumerate().collect(), Self::slashable_balance_of, + true, ); - if let Some(elected_set) = maybe_elected_set { - let elected_stashes = elected_set.0; - let assignments = elected_set.1; + if let Some(phragmen_result) = maybe_phragmen_result { + let elected_stashes = phragmen_result.winners; + let mut assignments = phragmen_result.assignments; // helper closure. let to_balance = |b: ExtendedBalance| @@ -1277,59 +1269,45 @@ impl Module { // to be properly multiplied by a ratio, which will lead to another value // less than u64 for sure. The result can then be safely passed to `to_balance`. // For now the backward convert is used. A simple `TryFrom` is also safe. - let ratio_of = |b, p| (p as ExtendedBalance).saturating_mul(to_votes(b)) / ACCURACY; - - // Compute the actual stake from nominator's ratio. - let assignments_with_stakes = assignments.iter().map(|(n, a)|( - n.clone(), - Self::slashable_balance_of(n), - a.iter().map(|(acc, r)| ( - acc.clone(), - *r, - to_balance(ratio_of(Self::slashable_balance_of(n), *r)), - )) - .collect::>>() - )).collect::, Vec>)>>(); - - // update elected candidate exposures. - let mut exposures = >::new(); + let ratio_of = |b, r: ExtendedBalance| r.saturating_mul(to_votes(b)) / ACCURACY; + + // Initialize the support of each candidate. + let mut supports = >::new(); elected_stashes .iter() - .map(|e| (e, Self::slashable_balance_of(e))) + .map(|e| (e, to_votes(Self::slashable_balance_of(e)))) .for_each(|(e, s)| { - let item = Exposure { own: s, total: s, ..Default::default() }; - exposures.insert(e.clone(), item); + let item = Support { own: s, total: s, ..Default::default() }; + supports.insert(e.clone(), item); }); - for (n, _, assignment) in &assignments_with_stakes { - for (c, _, s) in assignment { - if let Some(expo) = exposures.get_mut(c) { - // NOTE: simple example where this saturates: - // candidate with max_value stake. 1 nominator with max_value stake. - // Nuked. Sadly there is not much that we can do about this. - // See this test: phragmen_should_not_overflow_xxx() - expo.total = expo.total.saturating_add(*s); - expo.others.push( IndividualExposure { who: n.clone(), value: *s } ); + // convert the ratio in-place (and replace) to the balance but still in the extended + // balance type. + for (n, assignment) in assignments.iter_mut() { + for (c, r) in assignment.iter_mut() { + let nominator_stake = Self::slashable_balance_of(n); + let other_stake = ratio_of(nominator_stake, *r); + if let Some(support) = supports.get_mut(c) { + // This for an astronomically rich validator with more astronomically rich + // set of nominators, this might saturate. + support.total = support.total.saturating_add(other_stake); + support.others.push((n.clone(), other_stake)); } + // convert the ratio to extended balance + *r = other_stake; } } if cfg!(feature = "equalize") { let tolerance = 0_u128; let iterations = 2_usize; - let mut assignments_with_votes = assignments_with_stakes.iter() - .map(|a| ( - a.0.clone(), a.1, - a.2.iter() - .map(|e| (e.0.clone(), e.1, to_votes(e.2))) - .collect::>() - )) - .collect::, - Vec<(T::AccountId, ExtendedBalance, ExtendedBalance)> - )>>(); - equalize::(&mut assignments_with_votes, &mut exposures, tolerance, iterations); + equalize::<_, _, T::CurrencyToVote, _>( + assignments, + &mut supports, + tolerance, + iterations, + Self::slashable_balance_of, + ); } // Clear Stakers. @@ -1339,11 +1317,24 @@ impl Module { // Populate Stakers and figure out the minimum stake behind a slot. let mut slot_stake = BalanceOf::::max_value(); - for (c, e) in exposures.iter() { - if e.total < slot_stake { - slot_stake = e.total; + for (c, s) in supports.into_iter() { + // build `struct exposure` from `support` + let exposure = Exposure { + own: to_balance(s.own), + // This might reasonably saturate and we cannot do much about it. The sum of + // someone's stake might exceed the balance type if they have the maximum amount + // of balance and receive some support. This is super unlikely to happen, yet + // we simulate it in some tests. + total: to_balance(s.total), + others: s.others + .into_iter() + .map(|(who, value)| IndividualExposure { who, value: to_balance(value) }) + .collect::>>(), + }; + if exposure.total < slot_stake { + slot_stake = exposure.total; } - >::insert(c.clone(), e.clone()); + >::insert(c.clone(), exposure.clone()); } // Update slot stake. diff --git a/srml/staking/src/mock.rs b/srml/staking/src/mock.rs index aafe065118..2f2e81196c 100644 --- a/srml/staking/src/mock.rs +++ b/srml/staking/src/mock.rs @@ -18,7 +18,7 @@ use std::{collections::HashSet, cell::RefCell}; use sr_primitives::Perbill; -use sr_primitives::traits::{IdentityLookup, Convert, OpaqueKeys, OnInitialize}; +use sr_primitives::traits::{IdentityLookup, Convert, OpaqueKeys, OnInitialize, SaturatedConversion}; use sr_primitives::testing::{Header, UintAuthorityId}; use sr_staking_primitives::SessionIndex; use primitives::{H256, Blake2Hasher}; @@ -41,9 +41,7 @@ impl Convert for CurrencyToVoteHandler { fn convert(x: u64) -> u64 { x } } impl Convert for CurrencyToVoteHandler { - fn convert(x: u128) -> u64 { - x as u64 - } + fn convert(x: u128) -> u64 { x.saturated_into() } } thread_local! { diff --git a/srml/staking/src/phragmen.rs b/srml/staking/src/phragmen.rs deleted file mode 100644 index 14b8a3845f..0000000000 --- a/srml/staking/src/phragmen.rs +++ /dev/null @@ -1,393 +0,0 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Rust implementation of the Phragmén election algorithm. - -use rstd::{prelude::*, collections::btree_map::BTreeMap}; -use sr_primitives::{PerU128}; -use sr_primitives::traits::{Zero, Convert, Saturating}; -use crate::{BalanceOf, RawAssignment, ExpoMap, Trait, ValidatorPrefs, IndividualExposure}; - -type Fraction = PerU128; -/// Wrapper around the type used as the _safe_ wrapper around a `balance`. -pub type ExtendedBalance = u128; - -// this is only used while creating the candidate score. Due to reasons explained below -// The more accurate this is, the less likely we choose a wrong candidate. -const SCALE_FACTOR: ExtendedBalance = u32::max_value() as ExtendedBalance + 1; -/// These are used to expose a fixed accuracy to the caller function. The bigger they are, -/// the more accurate we get, but the more likely it is for us to overflow. The case of overflow -/// is handled but accuracy will be lost. 32 or 16 are reasonable values. -pub const ACCURACY: ExtendedBalance = u32::max_value() as ExtendedBalance + 1; - -/// Wrapper around validation candidates some metadata. -#[derive(Clone, Default)] -#[cfg_attr(feature = "std", derive(Debug))] -pub struct Candidate { - /// The validator's account - pub who: AccountId, - /// Intermediary value used to sort candidates. - pub score: Fraction, - /// Accumulator of the stake of this candidate based on received votes. - approval_stake: ExtendedBalance, - /// Flag for being elected. - elected: bool, -} - -/// Wrapper around the nomination info of a single nominator for a group of validators. -#[derive(Clone, Default)] -#[cfg_attr(feature = "std", derive(Debug))] -pub struct Nominator { - /// The nominator's account. - who: AccountId, - /// List of validators proposed by this nominator. - edges: Vec>, - /// the stake amount proposed by the nominator as a part of the vote. - budget: ExtendedBalance, - /// Incremented each time a nominee that this nominator voted for has been elected. - load: Fraction, -} - -/// Wrapper around a nominator vote and the load of that vote. -#[derive(Clone, Default)] -#[cfg_attr(feature = "std", derive(Debug))] -pub struct Edge { - /// Account being voted for - who: AccountId, - /// Load of this vote. - load: Fraction, - /// Equal to `edge.load / nom.load`. Stored only to be used with post-processing. - ratio: ExtendedBalance, - /// Index of the candidate stored in the 'candidates' vector. - candidate_index: usize, -} - -/// Perform election based on Phragmén algorithm. -/// -/// Reference implementation: https://github.com/w3f/consensus -/// -/// Returns an Option of elected candidates, if election is performed. -/// Returns None if not enough candidates exist. -/// -/// The returned Option is a tuple consisting of: -/// - The list of elected candidates. -/// - The list of nominators and their associated vote weights. -pub fn elect( - validator_count: usize, - minimum_validator_count: usize, - validator_iter: FV, - nominator_iter: FN, - slashable_balance_of: FS, -) -> Option<(Vec, Vec<(T::AccountId, Vec>)>)> where - FV: Iterator>)>, - FN: Iterator)>, - for <'r> FS: Fn(&'r T::AccountId) -> BalanceOf, -{ - let to_votes = |b: BalanceOf| , u64>>::convert(b) as ExtendedBalance; - - // return structures - let mut elected_candidates: Vec; - let mut assigned: Vec<(T::AccountId, Vec>)>; - let mut c_idx_cache = BTreeMap::::new(); - - // 1- Pre-process candidates and place them in a container, optimisation and add phantom votes. - // Candidates who have 0 stake => have no votes or all null-votes. Kick them out not. - let mut nominators: Vec> = - Vec::with_capacity(validator_iter.size_hint().0 + nominator_iter.size_hint().0); - let mut candidates = validator_iter.map(|(who, _)| { - let stash_balance = slashable_balance_of(&who); - (Candidate { who, ..Default::default() }, stash_balance) - }) - .filter_map(|(mut c, s)| { - c.approval_stake += to_votes(s); - if c.approval_stake.is_zero() { - None - } else { - Some((c, s)) - } - }) - .enumerate() - .map(|(idx, (c, s))| { - nominators.push(Nominator { - who: c.who.clone(), - edges: vec![ Edge { who: c.who.clone(), candidate_index: idx, ..Default::default() }], - budget: to_votes(s), - load: Fraction::zero(), - }); - c_idx_cache.insert(c.who.clone(), idx); - c - }) - .collect::>>(); - - // 2- Collect the nominators with the associated votes. - // Also collect approval stake along the way. - nominators.extend(nominator_iter.map(|(who, nominees)| { - let nominator_stake = slashable_balance_of(&who); - let mut edges: Vec> = Vec::with_capacity(nominees.len()); - for n in &nominees { - if let Some(idx) = c_idx_cache.get(n) { - // This candidate is valid + already cached. - candidates[*idx].approval_stake = candidates[*idx].approval_stake - .saturating_add(to_votes(nominator_stake)); - edges.push(Edge { who: n.clone(), candidate_index: *idx, ..Default::default() }); - } // else {} would be wrong votes. We don't really care about it. - } - Nominator { - who, - edges: edges, - budget: to_votes(nominator_stake), - load: Fraction::zero(), - } - })); - - // 4- If we have more candidates then needed, run Phragmén. - if candidates.len() >= minimum_validator_count { - let validator_count = validator_count.min(candidates.len()); - - elected_candidates = Vec::with_capacity(validator_count); - assigned = Vec::with_capacity(validator_count); - // Main election loop - for _round in 0..validator_count { - // Loop 1: initialize score - for c in &mut candidates { - if !c.elected { - c.score = Fraction::from_xth(c.approval_stake); - } - } - // Loop 2: increment score. - for n in &nominators { - for e in &n.edges { - let c = &mut candidates[e.candidate_index]; - if !c.elected && !c.approval_stake.is_zero() { - // Basic fixed-point shifting by 32. - // `n.budget.saturating_mul(SCALE_FACTOR)` will never saturate - // since n.budget cannot exceed u64,despite being stored in u128. yet, - // `*n.load / SCALE_FACTOR` might collapse to zero. Hence, 32 or 16 bits are better scale factors. - // Note that left-associativity in operators precedence is crucially important here. - let temp = - n.budget.saturating_mul(SCALE_FACTOR) / c.approval_stake - * (*n.load / SCALE_FACTOR); - c.score = Fraction::from_parts((*c.score).saturating_add(temp)); - } - } - } - - // Find the best - if let Some(winner) = candidates - .iter_mut() - .filter(|c| !c.elected) - .min_by_key(|c| *c.score) - { - // loop 3: update nominator and edge load - winner.elected = true; - for n in &mut nominators { - for e in &mut n.edges { - if e.who == winner.who { - e.load = Fraction::from_parts(*winner.score - *n.load); - n.load = winner.score; - } - } - } - - elected_candidates.push(winner.who.clone()); - } else { - break - } - } // end of all rounds - - // 4.1- Update backing stake of candidates and nominators - for n in &mut nominators { - let mut assignment = (n.who.clone(), vec![]); - for e in &mut n.edges { - if let Some(c) = elected_candidates.iter().find(|c| **c == e.who) { - if *c != n.who { - let ratio = { - // Full support. No need to calculate. - if *n.load == *e.load { ACCURACY } - else { - // This should not saturate. Safest is to just check - if let Some(r) = ACCURACY.checked_mul(*e.load) { - r / n.load.max(1) - } else { - // Just a simple trick. - *e.load / (n.load.max(1) / ACCURACY) - } - } - }; - e.ratio = ratio; - assignment.1.push((e.who.clone(), ratio)); - } - } - } - - if assignment.1.len() > 0 { - // To ensure an assertion indicating: no stake from the nominator going to waste, - // we add a minimal post-processing to equally assign all of the leftover stake ratios. - let vote_count = assignment.1.len() as ExtendedBalance; - let l = assignment.1.len(); - let sum = assignment.1.iter().map(|a| a.1).sum::(); - let diff = ACCURACY.checked_sub(sum).unwrap_or(0); - let diff_per_vote= diff / vote_count; - - if diff_per_vote > 0 { - for i in 0..l { - assignment.1[i%l].1 = - assignment.1[i%l].1 - .saturating_add(diff_per_vote); - } - } - - // `remainder` is set to be less than maximum votes of a nominator (currently 16). - // safe to cast it to usize. - let remainder = diff - diff_per_vote * vote_count; - for i in 0..remainder as usize { - assignment.1[i%l].1 = - assignment.1[i%l].1 - .saturating_add(1); - } - assigned.push(assignment); - } - } - - } else { - // if we have less than minimum, use the previous validator set. - return None - } - Some((elected_candidates, assigned)) -} - -/// Performs equalize post-processing to the output of the election algorithm -/// This function mutates the input parameters, most noticeably it updates the exposure of -/// the elected candidates. -/// -/// No value is returned from the function and the `expo_map` parameter is updated. -pub fn equalize( - assignments: &mut Vec<(T::AccountId, BalanceOf, Vec<(T::AccountId, ExtendedBalance, ExtendedBalance)>)>, - expo_map: &mut ExpoMap, - tolerance: ExtendedBalance, - iterations: usize, -) { - for _i in 0..iterations { - let mut max_diff = 0; - assignments.iter_mut().for_each(|(n, budget, assignment)| { - let diff = do_equalize::(&n, *budget, assignment, expo_map, tolerance); - if diff > max_diff { - max_diff = diff; - } - }); - if max_diff < tolerance { - break; - } - } -} - -fn do_equalize( - nominator: &T::AccountId, - budget_balance: BalanceOf, - elected_edges: &mut Vec<(T::AccountId, ExtendedBalance, ExtendedBalance)>, - expo_map: &mut ExpoMap, - tolerance: ExtendedBalance -) -> ExtendedBalance { - let to_votes = |b: BalanceOf| - , u64>>::convert(b) as ExtendedBalance; - let to_balance = |v: ExtendedBalance| - >>::convert(v); - let budget = to_votes(budget_balance); - - // Nothing to do. This nominator had nothing useful. - // Defensive only. Assignment list should always be populated. - if elected_edges.is_empty() { return 0; } - - let stake_used = elected_edges - .iter() - .fold(0 as ExtendedBalance, |s, e| s.saturating_add(e.2)); - - let backed_stakes_iter = elected_edges - .iter() - .filter_map(|e| expo_map.get(&e.0)) - .map(|e| to_votes(e.total)); - - let backing_backed_stake = elected_edges - .iter() - .filter(|e| e.2 > 0) - .filter_map(|e| expo_map.get(&e.0)) - .map(|e| to_votes(e.total)) - .collect::>(); - - let mut difference; - if backing_backed_stake.len() > 0 { - let max_stake = backing_backed_stake - .iter() - .max() - .expect("vector with positive length will have a max; qed"); - let min_stake = backed_stakes_iter - .min() - .expect("iterator with positive length will have a min; qed"); - - difference = max_stake.saturating_sub(min_stake); - difference = difference.saturating_add(budget.saturating_sub(stake_used)); - if difference < tolerance { - return difference; - } - } else { - difference = budget; - } - - // Undo updates to exposure - elected_edges.iter_mut().for_each(|e| { - if let Some(expo) = expo_map.get_mut(&e.0) { - expo.total = expo.total.saturating_sub(to_balance(e.2)); - expo.others.retain(|i_expo| i_expo.who != *nominator); - } - e.2 = 0; - }); - - elected_edges.sort_unstable_by_key(|e| - if let Some(e) = expo_map.get(&e.0) { e.total } else { Zero::zero() } - ); - - let mut cumulative_stake: ExtendedBalance = 0; - let mut last_index = elected_edges.len() - 1; - elected_edges.iter_mut().enumerate().for_each(|(idx, e)| { - if let Some(expo) = expo_map.get_mut(&e.0) { - let stake: ExtendedBalance = to_votes(expo.total); - let stake_mul = stake.saturating_mul(idx as ExtendedBalance); - let stake_sub = stake_mul.saturating_sub(cumulative_stake); - if stake_sub > budget { - last_index = idx.checked_sub(1).unwrap_or(0); - return - } - cumulative_stake = cumulative_stake.saturating_add(stake); - } - }); - - let last_stake = elected_edges[last_index].2; - let split_ways = last_index + 1; - let excess = budget - .saturating_add(cumulative_stake) - .saturating_sub(last_stake.saturating_mul(split_ways as ExtendedBalance)); - elected_edges.iter_mut().take(split_ways).for_each(|e| { - if let Some(expo) = expo_map.get_mut(&e.0) { - e.2 = (excess / split_ways as ExtendedBalance) - .saturating_add(last_stake) - .saturating_sub(to_votes(expo.total)); - expo.total = expo.total.saturating_add(to_balance(e.2)); - expo.others.push(IndividualExposure { who: nominator.clone(), value: to_balance(e.2)}); - } - }); - - difference -} diff --git a/srml/staking/src/tests.rs b/srml/staking/src/tests.rs index bbae3615c2..6e0eaf3b50 100644 --- a/srml/staking/src/tests.rs +++ b/srml/staking/src/tests.rs @@ -18,7 +18,6 @@ use super::*; use runtime_io::with_externalities; -use phragmen; use sr_primitives::traits::OnInitialize; use sr_staking_primitives::offence::{OffenceDetails, OnOffenceHandler}; use srml_support::{assert_ok, assert_noop, assert_eq_uvec, EnumerableStorageMap}; @@ -1429,19 +1428,20 @@ fn phragmen_poc_2_works() { assert_ok!(Staking::bond(Origin::signed(3), 4, 1000, RewardDestination::default())); assert_ok!(Staking::nominate(Origin::signed(4), vec![11, 31])); - let winners = phragmen::elect::( + let results = phragmen::elect::<_, _, _, ::CurrencyToVote>( 2, Staking::minimum_validator_count() as usize, - >::enumerate(), - >::enumerate(), + >::enumerate().map(|(who, _)| who).collect::>(), + >::enumerate().collect(), Staking::slashable_balance_of, + true, ); - let (winners, assignment) = winners.unwrap(); + let phragmen::PhragmenResult { winners, assignments } = results.unwrap(); // 10 and 30 must be the winners assert_eq!(winners, vec![11, 31]); - assert_eq!(assignment, vec![ + assert_eq!(assignments, vec![ (3, vec![(11, 2816371998), (31, 1478595298)]), (1, vec![(11, 4294967296)]), ]); -- GitLab From aceecfdf25288c93bfa834d04ebd578cab0bc867 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Thu, 29 Aug 2019 14:34:02 +0200 Subject: [PATCH 037/275] Simplify deposit_event declaration in decl_module (#3506) * simplify module deposit_event declaration * fix * bump version * fix * fix test * fix doc --- node-template/runtime/src/template.rs | 2 +- node/runtime/src/lib.rs | 2 +- srml/assets/src/lib.rs | 2 +- srml/balances/src/lib.rs | 2 +- srml/collective/src/lib.rs | 2 +- srml/contracts/src/lib.rs | 2 +- srml/democracy/src/lib.rs | 2 +- srml/elections/src/lib.rs | 2 +- srml/example/src/lib.rs | 2 +- srml/generic-asset/src/lib.rs | 2 +- srml/im-online/src/lib.rs | 2 +- srml/indices/src/lib.rs | 2 +- srml/membership/src/lib.rs | 2 +- srml/scored-pool/src/lib.rs | 2 +- srml/staking/src/lib.rs | 4 +- srml/sudo/src/lib.rs | 2 +- srml/support/src/dispatch.rs | 47 ++++--------------- srml/support/test/tests/instance.rs | 4 +- .../reserved_keyword/on_initialize.stderr | 2 +- srml/support/test/tests/system.rs | 9 ++-- srml/system/src/lib.rs | 12 ++--- srml/treasury/src/lib.rs | 2 +- 22 files changed, 43 insertions(+), 67 deletions(-) diff --git a/node-template/runtime/src/template.rs b/node-template/runtime/src/template.rs index 7f9d03fbb7..c1fa6f2d31 100644 --- a/node-template/runtime/src/template.rs +++ b/node-template/runtime/src/template.rs @@ -35,7 +35,7 @@ decl_module! { pub struct Module for enum Call where origin: T::Origin { // Initializing events // this is needed only if you are using events in your module - fn deposit_event() = default; + fn deposit_event() = default; // Just a dummy entry point. // function that can be called by the external world as an extrinsics call diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index a36801c44b..6fec9abe7a 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -80,7 +80,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 154, - impl_version: 156, + impl_version: 157, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/assets/src/lib.rs b/srml/assets/src/lib.rs index c8b24662be..a8268d1463 100644 --- a/srml/assets/src/lib.rs +++ b/srml/assets/src/lib.rs @@ -149,7 +149,7 @@ pub trait Trait: system::Trait { decl_module! { pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; /// Issue a new class of fungible assets. There are, and will only ever be, `total` /// such assets and they'll all belong to the `origin` initially. It will have an /// identifier `AssetId` instance: this will be specified in the `Issued` event. diff --git a/srml/balances/src/lib.rs b/srml/balances/src/lib.rs index 0c83897045..e37ce5c4de 100644 --- a/srml/balances/src/lib.rs +++ b/srml/balances/src/lib.rs @@ -413,7 +413,7 @@ decl_module! { /// The fee to be paid for making a transaction; the per-byte portion. const TransactionByteFee: T::Balance = T::TransactionByteFee::get(); - fn deposit_event() = default; + fn deposit_event() = default; /// Transfer some liquid free balance to another account. /// diff --git a/srml/collective/src/lib.rs b/srml/collective/src/lib.rs index 3828988015..ea616beb4b 100644 --- a/srml/collective/src/lib.rs +++ b/srml/collective/src/lib.rs @@ -138,7 +138,7 @@ decl_event!( // operational class. decl_module! { pub struct Module, I: Instance=DefaultInstance> for enum Call where origin: ::Origin { - fn deposit_event() = default; + fn deposit_event() = default; /// Set the collective's membership manually to `new_members`. Be nice to the chain and /// provide it pre-sorted. diff --git a/srml/contracts/src/lib.rs b/srml/contracts/src/lib.rs index f8485f848a..7618551298 100644 --- a/srml/contracts/src/lib.rs +++ b/srml/contracts/src/lib.rs @@ -504,7 +504,7 @@ decl_module! { /// default value is 10_000_000. const BlockGasLimit: Gas = T::BlockGasLimit::get(); - fn deposit_event() = default; + fn deposit_event() = default; /// Updates the schedule for metering contracts. /// diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index 4853d192c4..244d653662 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -354,7 +354,7 @@ decl_module! { /// Period in blocks where an external proposal may not be re-submitted after being vetoed. const CooloffPeriod: T::BlockNumber = T::CooloffPeriod::get(); - fn deposit_event() = default; + fn deposit_event() = default; /// Propose a sensitive action to be taken. /// diff --git a/srml/elections/src/lib.rs b/srml/elections/src/lib.rs index 9c49b9055b..63a4509acc 100644 --- a/srml/elections/src/lib.rs +++ b/srml/elections/src/lib.rs @@ -296,7 +296,7 @@ decl_module! { /// The chunk size of the approval vector. const APPROVAL_SET_SIZE: u32 = APPROVAL_SET_SIZE as u32; - fn deposit_event() = default; + fn deposit_event() = default; /// Set candidate approvals. Approval slots stay valid as long as candidates in those slots /// are registered. diff --git a/srml/example/src/lib.rs b/srml/example/src/lib.rs index 3de961f5cd..247be01239 100644 --- a/srml/example/src/lib.rs +++ b/srml/example/src/lib.rs @@ -363,7 +363,7 @@ decl_module! { /// It is also possible to provide a custom implementation. /// For non-generic events, the generic parameter just needs to be dropped, so that it /// looks like: `fn deposit_event() = default;`. - fn deposit_event() = default; + fn deposit_event() = default; /// This is your public interface. Be extremely careful. /// This is just a simple example of how to interact with the module from the external /// world. diff --git a/srml/generic-asset/src/lib.rs b/srml/generic-asset/src/lib.rs index 016e39127f..abd6e1302f 100644 --- a/srml/generic-asset/src/lib.rs +++ b/srml/generic-asset/src/lib.rs @@ -324,7 +324,7 @@ impl Into> for PermissionLatest for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; /// Create a new kind of asset. fn create(origin, options: AssetOptions) -> Result { diff --git a/srml/im-online/src/lib.rs b/srml/im-online/src/lib.rs index 06a350655b..fe604ca788 100644 --- a/srml/im-online/src/lib.rs +++ b/srml/im-online/src/lib.rs @@ -238,7 +238,7 @@ decl_storage! { decl_module! { pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; fn heartbeat( origin, diff --git a/srml/indices/src/lib.rs b/srml/indices/src/lib.rs index 5bf838f321..31e825d2c8 100644 --- a/srml/indices/src/lib.rs +++ b/srml/indices/src/lib.rs @@ -73,7 +73,7 @@ pub trait Trait: system::Trait { decl_module! { pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; } } diff --git a/srml/membership/src/lib.rs b/srml/membership/src/lib.rs index e36351ddbe..aed8b598f7 100644 --- a/srml/membership/src/lib.rs +++ b/srml/membership/src/lib.rs @@ -99,7 +99,7 @@ decl_module! { for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; /// Add a member `who` to the set. /// diff --git a/srml/scored-pool/src/lib.rs b/srml/scored-pool/src/lib.rs index 1348b73864..f2f5d426d9 100644 --- a/srml/scored-pool/src/lib.rs +++ b/srml/scored-pool/src/lib.rs @@ -228,7 +228,7 @@ decl_module! { for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; /// Every `Period` blocks the `Members` set is refreshed from the /// highest scoring members in the pool. diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index d0c60bfa46..e7824d36e0 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -674,7 +674,7 @@ decl_module! { /// Number of eras that staked funds must remain bonded for. const BondingDuration: EraIndex = T::BondingDuration::get(); - fn deposit_event() = default; + fn deposit_event() = default; fn on_finalize() { // Set the start of the first era. @@ -1595,7 +1595,7 @@ impl ReportOffence R::report_offence(reporters, offence) } else { >::deposit_event( - RawEvent::OldSlashingReportDiscarded(offence_session).into() + RawEvent::OldSlashingReportDiscarded(offence_session) ) } } diff --git a/srml/sudo/src/lib.rs b/srml/sudo/src/lib.rs index 65a15b4abf..d91f61bd2f 100644 --- a/srml/sudo/src/lib.rs +++ b/srml/sudo/src/lib.rs @@ -106,7 +106,7 @@ pub trait Trait: system::Trait { decl_module! { // Simple declaration of the `Module` type. Lets the macro know what it's working on. pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; /// Authenticates the sudo key and dispatches a function call with `Root` origin. /// diff --git a/srml/support/src/dispatch.rs b/srml/support/src/dispatch.rs index d77da619a9..86c21da67b 100644 --- a/srml/support/src/dispatch.rs +++ b/srml/support/src/dispatch.rs @@ -203,7 +203,7 @@ impl Parameter for T where T: Codec + Clone + Eq {} /// * `deposit_event`: Helper function for depositing an [event](https://docs.substrate.dev/docs/event-enum). /// The default behavior is to call `deposit_event` from the [System module](../srml_system/index.html). /// However, you can write your own implementation for events in your runtime. To use the default behavior, -/// add `fn deposit_event() = default;` to your `Module`. +/// add `fn deposit_event() = default;` to your `Module`. /// /// The following reserved functions also take the block number (with type `T::BlockNumber`) as an optional input: /// @@ -288,7 +288,7 @@ macro_rules! decl_module { { $( $constants:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* - $vis:vis fn deposit_event $(<$dpeg:ident $(, $dpeg_instance:ident)?>)* () = default; + $vis:vis fn deposit_event() = default; $($rest:tt)* ) => { $crate::decl_module!(@normalize @@ -296,7 +296,7 @@ macro_rules! decl_module { pub struct $mod_type<$trait_instance: $trait_name$(, I: $instantiable $(= $module_default_instance)?)?> for enum $call_type where origin: $origin_type, system = $system { $( $other_where_bounds )* } - { $vis fn deposit_event $(<$dpeg $(, $dpeg_instance)?>)* () = default; } + { $vis fn deposit_event() = default; } { $( $on_initialize )* } { $( $on_finalize )* } { $( $offchain )* } @@ -317,23 +317,11 @@ macro_rules! decl_module { { $( $constants:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* - $vis:vis fn deposit_event $(<$dpeg:ident $(, $dpeg_instance:ident)?>)* ( - $($param_name:ident : $param:ty),* - ) { $( $impl:tt )* } + $vis:vis fn deposit_event $($rest:tt)* ) => { - $crate::decl_module!(@normalize - $(#[$attr])* - pub struct $mod_type<$trait_instance: $trait_name$(, I: $instantiable $(= $module_default_instance)?)?> - for enum $call_type where origin: $origin_type, system = $system - { $( $other_where_bounds )* } - { $vis fn deposit_event $(<$dpeg $(, $dpeg_instance)?>)* ($( $param_name: $param ),* ) { $( $impl )* } } - { $( $on_initialize )* } - { $( $on_finalize )* } - { $( $offchain )* } - { $( $constants )* } - [ $( $dispatchables )* ] - $($rest)* + compile_error!( + "`deposit_event` function is reserved and must follow the syntax: `$vis:vis fn deposit_event() = default;`" ); }; (@normalize @@ -685,25 +673,10 @@ macro_rules! decl_module { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> $module<$trait_instance $(, $instance)?> where $( $other_where_bounds )* { - $vis fn deposit_event(event: Event$(<$event_trait_instance $(, $event_instance)?>)?) { - <$system::Module<$trait_instance>>::deposit_event( - <$trait_instance as $trait_name$(<$instance>)?>::Event::from(event).into() - ); - } - } - }; - - (@impl_deposit_event - $module:ident<$trait_instance:ident: $trait_name:ident$(, $instance:ident: $instantiable:path)?>; - $system:ident; - { $( $other_where_bounds:tt )* } - $vis:vis fn deposit_event($param:ident : $param_ty:ty) { $( $impl:tt )* } - ) => { - impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> $module<$trait_instance $(, $instance)?> - where $( $other_where_bounds )* - { - $vis fn deposit_event($param: $param_ty) { - $( $impl )* + $vis fn deposit_event( + event: impl Into<< $trait_instance as $trait_name $(<$instance>)? >::Event> + ) { + <$system::Module<$trait_instance>>::deposit_event(event.into()) } } }; diff --git a/srml/support/test/tests/instance.rs b/srml/support/test/tests/instance.rs index 440fb9e779..e9c660eea3 100644 --- a/srml/support/test/tests/instance.rs +++ b/srml/support/test/tests/instance.rs @@ -55,7 +55,7 @@ mod module1 { { fn offchain_worker() {} - fn deposit_event() = default; + fn deposit_event() = default; fn one(origin) { system::ensure_root(origin)?; @@ -132,7 +132,7 @@ mod module2 { pub struct Module, I: Instance=DefaultInstance> for enum Call where origin: ::Origin { - fn deposit_event() = default; + fn deposit_event() = default; } } diff --git a/srml/support/test/tests/reserved_keyword/on_initialize.stderr b/srml/support/test/tests/reserved_keyword/on_initialize.stderr index 04adefab3a..13c2ef8d2c 100644 --- a/srml/support/test/tests/reserved_keyword/on_initialize.stderr +++ b/srml/support/test/tests/reserved_keyword/on_initialize.stderr @@ -38,7 +38,7 @@ error: Invalid call fn name: `offchain_worker`, name is reserved and doesn't mat | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) -error: Invalid call fn name: `deposit_event`, name is reserved and doesn't match expected signature, please refer to `decl_module!` documentation to see the appropriate usage, or rename it to an unreserved keyword. +error: `deposit_event` function is reserved and must follow the syntax: `$vis:vis fn deposit_event() = default;` --> $DIR/on_initialize.rs:30:1 | 30 | reserved!(on_finalize on_initialize on_finalise on_initialise offchain_worker deposit_event); diff --git a/srml/support/test/tests/system.rs b/srml/support/test/tests/system.rs index 6483161211..9ea0b2bc76 100644 --- a/srml/support/test/tests/system.rs +++ b/srml/support/test/tests/system.rs @@ -12,8 +12,11 @@ pub trait Trait: 'static + Eq + Clone { srml_support::decl_module! { pub struct Module for enum Call where origin: T::Origin { - pub fn deposit_event(_event: T::Event) { - } + } +} + +impl Module { + pub fn deposit_event(_event: impl Into) { } } @@ -49,4 +52,4 @@ pub fn ensure_root(o: OuterOrigin) -> Result<(), &'stati where OuterOrigin: Into, OuterOrigin>> { o.into().map(|_| ()).map_err(|_| "bad origin: expected to be a root origin") -} \ No newline at end of file +} diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index 54aa3b282a..91959f43e4 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -246,11 +246,6 @@ pub type KeyValue = (Vec, Vec); decl_module! { pub struct Module for enum Call where origin: T::Origin { - /// Deposits an event into this block's event record. - pub fn deposit_event(event: T::Event) { - Self::deposit_event_indexed(&[], event); - } - /// A big dispatch that will disallow any other transaction to be included. // TODO: this must be preferable available for testing really (not possible at the moment). #[weight = SimpleDispatchInfo::MaxOperational] @@ -545,6 +540,11 @@ pub fn ensure_none(o: OuterOrigin) -> Result<(), &'stati } impl Module { + /// Deposits an event into this block's event record. + pub fn deposit_event(event: impl Into) { + Self::deposit_event_indexed(&[], event.into()); + } + /// Deposits an event into this block's event record adding this event /// to the corresponding topic indexes. /// @@ -815,7 +815,7 @@ impl Module { Self::deposit_event(match r { Ok(_) => Event::ExtrinsicSuccess, Err(_) => Event::ExtrinsicFailed, - }.into()); + }); let next_extrinsic_index = Self::extrinsic_index().unwrap_or_default() + 1u32; diff --git a/srml/treasury/src/lib.rs b/srml/treasury/src/lib.rs index 1e709b74a6..ef2b9e69fe 100644 --- a/srml/treasury/src/lib.rs +++ b/srml/treasury/src/lib.rs @@ -139,7 +139,7 @@ decl_module! { /// Percentage of spare funds (if any) that are burnt per spend period. const Burn: Permill = T::Burn::get(); - fn deposit_event() = default; + fn deposit_event() = default; /// Put forward a suggestion for spending. A deposit proportional to the value /// is reserved and slashed if the proposal is rejected. It is returned once the /// proposal is awarded. -- GitLab From 202886acb318edb9eb41719422992ba85bc3e786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 29 Aug 2019 16:11:26 +0200 Subject: [PATCH 038/275] Make public key mandatory in `insert_key` (#3512) --- README.adoc | 3 ++- core/rpc/api/src/author/mod.rs | 4 ++-- core/rpc/src/author/mod.rs | 21 +++------------------ core/rpc/src/author/tests.rs | 2 +- 4 files changed, 8 insertions(+), 22 deletions(-) diff --git a/README.adoc b/README.adoc index 4d8bc466f5..48ccc3ef91 100644 --- a/README.adoc +++ b/README.adoc @@ -406,11 +406,12 @@ https://github.com/paritytech/substrate/blob/master/core/primitives/src/crypto.r user can declare any key type. ``` -curl -H 'Content-Type: application/json' --data '{ "jsonrpc":"2.0", "method":"author_insertKey", "params":["KEY_TYPE", "SEED"],"id":1 }' localhost:9933 +curl -H 'Content-Type: application/json' --data '{ "jsonrpc":"2.0", "method":"author_insertKey", "params":["KEY_TYPE", "SEED", "PUBLIC"],"id":1 }' localhost:9933 ``` `KEY_TYPE` - needs to be replaced with the 4-character key type identifier. `SEED` - is the seed of the key. +`PUBLIC` - public key for the given key. == Documentation diff --git a/core/rpc/api/src/author/mod.rs b/core/rpc/api/src/author/mod.rs index 3d5698880a..e8314c5c5f 100644 --- a/core/rpc/api/src/author/mod.rs +++ b/core/rpc/api/src/author/mod.rs @@ -44,8 +44,8 @@ pub trait AuthorApi { fn insert_key(&self, key_type: String, suri: String, - maybe_public: Option - ) -> Result; + public: Bytes, + ) -> Result<()>; /// Generate new session keys and returns the corresponding public keys. #[rpc(name = "author_rotateKeys")] diff --git a/core/rpc/src/author/mod.rs b/core/rpc/src/author/mod.rs index 4c72a96023..78a8ff804f 100644 --- a/core/rpc/src/author/mod.rs +++ b/core/rpc/src/author/mod.rs @@ -94,29 +94,14 @@ impl AuthorApi, BlockHash

> for Author whe &self, key_type: String, suri: String, - maybe_public: Option, - ) -> Result { + public: Bytes, + ) -> Result<()> { let key_type = key_type.as_str().try_into().map_err(|_| Error::BadKeyType)?; let mut keystore = self.keystore.write(); let maybe_password = keystore.password(); - let public = match maybe_public { - Some(public) => public.0, - None => { - let maybe_public = match key_type { - key_types::BABE | key_types::SR25519 => - sr25519::Pair::from_string(&suri, maybe_password) - .map(|pair| pair.public().to_raw_vec()), - key_types::GRANDPA | key_types::ED25519 => - ed25519::Pair::from_string(&suri, maybe_password) - .map(|pair| pair.public().to_raw_vec()), - _ => Err(Error::UnsupportedKeyType)?, - }; - maybe_public.map_err(|_| Error::BadSeedPhrase)? - } - }; keystore.insert_unknown(key_type, &suri, &public[..]) .map_err(|_| Error::KeyStoreUnavailable)?; - Ok(public.into()) + Ok(()) } fn rotate_keys(&self) -> Result { diff --git a/core/rpc/src/author/tests.rs b/core/rpc/src/author/tests.rs index e7cf84c927..8e6243f40e 100644 --- a/core/rpc/src/author/tests.rs +++ b/core/rpc/src/author/tests.rs @@ -200,7 +200,7 @@ fn should_insert_key() { p.insert_key( String::from_utf8(key_types::ED25519.0.to_vec()).expect("Keytype is a valid string"), suri.to_string(), - Some(key_pair.public().0.to_vec().into()), + key_pair.public().0.to_vec().into(), ).expect("Insert key"); let store_key_pair = keystore.read() -- GitLab From 5345e935cd1f7a89d3feb2376caabc0a43c7d6aa Mon Sep 17 00:00:00 2001 From: gabriel klawitter Date: Thu, 29 Aug 2019 16:59:34 +0200 Subject: [PATCH 039/275] in order to make srml staking tests mandatory it is required to run on every pr (#3511) --- .gitlab-ci.yml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 872f916f4c..c25276dd10 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -44,7 +44,6 @@ variables: - cargo --version - sccache -s only: - - tags - master - /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 - schedules @@ -53,6 +52,13 @@ variables: tags: - linux-docker +.build-only: &build-only + only: + - master + - /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 + - web + + #### stage: test @@ -145,10 +151,6 @@ test-srml-staking: &test-srml-staking except: variables: - $DEPLOY_TAG - only: - changes: - - .gitlab-ci.yml - - srml/staking/* script: - cd srml/staking/ - time cargo test --release --verbose --no-default-features --features std @@ -214,11 +216,6 @@ check-web-wasm: - time cargo web build -p substrate-trie - sccache -s -.build-only: &build-only - only: - - master - - tags - - web #### stage: build @@ -525,6 +522,8 @@ deploy-ue1-tag: name: parity-prod-ue1 .validator-deploy: &validator-deploy + # script will fail if there is no artifacts/substrate/VERSION + <<: *build-only stage: flaming-fir dependencies: - build-linux-substrate -- GitLab From 3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Thu, 29 Aug 2019 17:04:46 +0200 Subject: [PATCH 040/275] `srml_support` storage reorganize (#3344) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * impl * file split * old comment * better error message * WIP * basti test works * comment * remove old files * impl swap for storage map * fix * fix and comment * code refactor * code refactor * code format * code refactor * fix * fix * fix * document generators * license * doc * doc * fmt Co-Authored-By: Bastian Köcher * some comment addressed * storage_items small refactor * fix storage_items * more precise returned type * fix * code fmt suggestion Co-Authored-By: Bastian Köcher * remove box allocation * bump version * rename function as behavior has changed * fix doc --- node/executor/src/lib.rs | 62 +- srml/aura/src/lib.rs | 10 +- srml/authority-discovery/src/lib.rs | 10 +- srml/babe/src/lib.rs | 10 +- srml/collective/src/lib.rs | 10 +- srml/democracy/src/lib.rs | 4 +- srml/elections/src/lib.rs | 2 +- srml/generic-asset/src/lib.rs | 9 +- srml/grandpa/src/lib.rs | 10 +- srml/im-online/src/lib.rs | 10 +- srml/membership/src/lib.rs | 15 +- srml/scored-pool/src/lib.rs | 47 +- srml/session/src/lib.rs | 55 +- srml/staking/src/lib.rs | 62 +- srml/staking/src/mock.rs | 2 +- srml/staking/src/tests.rs | 2 +- srml/support/procedural/src/lib.rs | 36 +- srml/support/procedural/src/storage/impls.rs | 649 ++---------------- .../procedural/src/storage/transformation.rs | 78 +-- srml/support/src/hashable.rs | 2 +- srml/support/src/lib.rs | 13 +- srml/support/src/metadata.rs | 2 +- srml/support/src/storage/child.rs | 106 +++ .../src/storage/generator/double_map.rs | 194 ++++++ .../src/storage/generator/linked_map.rs | 327 +++++++++ srml/support/src/storage/generator/map.rs | 167 +++++ srml/support/src/storage/generator/mod.rs | 32 + srml/support/src/storage/generator/value.rs | 156 +++++ .../src/storage/{hashed/mod.rs => hashed.rs} | 64 +- srml/support/src/storage/hashed/generator.rs | 419 ----------- srml/support/src/storage/mod.rs | 552 ++------------- srml/support/src/storage/storage_items.rs | 203 +++--- .../storage/{unhashed/mod.rs => unhashed.rs} | 4 +- .../support/src/storage/unhashed/generator.rs | 241 ------- srml/support/src/traits.rs | 10 - srml/support/test/tests/final_keys.rs | 2 +- srml/support/test/tests/instance.rs | 70 +- srml/system/src/lib.rs | 24 +- 38 files changed, 1469 insertions(+), 2202 deletions(-) create mode 100644 srml/support/src/storage/generator/double_map.rs create mode 100644 srml/support/src/storage/generator/linked_map.rs create mode 100644 srml/support/src/storage/generator/map.rs create mode 100644 srml/support/src/storage/generator/mod.rs create mode 100644 srml/support/src/storage/generator/value.rs rename srml/support/src/storage/{hashed/mod.rs => hashed.rs} (85%) delete mode 100644 srml/support/src/storage/hashed/generator.rs rename srml/support/src/storage/{unhashed/mod.rs => unhashed.rs} (98%) delete mode 100644 srml/support/src/storage/unhashed/generator.rs diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index eba744f62a..27b94df8b3 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -42,9 +42,7 @@ mod tests { use codec::{Encode, Decode, Joiner}; use runtime_support::{Hashable, StorageValue, StorageMap, assert_eq_error_rate, traits::Currency}; use state_machine::{CodeExecutor, Externalities, TestExternalities as CoreTestExternalities}; - use primitives::{ - twox_128, blake2_256, Blake2Hasher, NeverNativeValue, NativeOrEncoded, map - }; + use primitives::{Blake2Hasher, NeverNativeValue, NativeOrEncoded, map}; use sr_primitives::traits::{Header as HeaderT, Hash as HashT, Convert}; use sr_primitives::{ApplyOutcome, ApplyError, ApplyResult}; use sr_primitives::weights::{WeightMultiplier, GetDispatchInfo}; @@ -122,16 +120,16 @@ mod tests { #[test] fn panic_execution_with_foreign_code_gives_error() { let mut t = TestExternalities::::new_with_code(BLOATY_CODE, (map![ - blake2_256(&>::key_for(alice())).to_vec() => { + >::hashed_key_for(alice()) => { 69_u128.encode() }, - twox_128(>::key()).to_vec() => { + >::hashed_key().to_vec() => { 69_u128.encode() }, - twox_128(>::key()).to_vec() => { + >::hashed_key().to_vec() => { 0_u128.encode() }, - blake2_256(&>::key_for(0)).to_vec() => { + >::hashed_key_for(0) => { vec![0u8; 32] } ], map![])); @@ -158,16 +156,16 @@ mod tests { #[test] fn bad_extrinsic_with_native_equivalent_code_gives_error() { let mut t = TestExternalities::::new_with_code(COMPACT_CODE, (map![ - blake2_256(&>::key_for(alice())).to_vec() => { + >::hashed_key_for(alice()) => { 69_u128.encode() }, - twox_128(>::key()).to_vec() => { + >::hashed_key().to_vec() => { 69_u128.encode() }, - twox_128(>::key()).to_vec() => { + >::hashed_key().to_vec() => { 0_u128.encode() }, - blake2_256(&>::key_for(0)).to_vec() => { + >::hashed_key_for(0) => { vec![0u8; 32] } ], map![])); @@ -194,14 +192,14 @@ mod tests { #[test] fn successful_execution_with_native_equivalent_code_gives_ok() { let mut t = TestExternalities::::new_with_code(COMPACT_CODE, (map![ - blake2_256(&>::key_for(alice())).to_vec() => { + >::hashed_key_for(alice()) => { (111 * DOLLARS).encode() }, - twox_128(>::key()).to_vec() => { + >::hashed_key().to_vec() => { (111 * DOLLARS).encode() }, - twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32] + >::hashed_key().to_vec() => vec![0u8; 16], + >::hashed_key_for(0) => vec![0u8; 32] ], map![])); let r = executor().call::<_, NeverNativeValue, fn() -> _>( @@ -230,14 +228,14 @@ mod tests { #[test] fn successful_execution_with_foreign_code_gives_ok() { let mut t = TestExternalities::::new_with_code(BLOATY_CODE, (map![ - blake2_256(&>::key_for(alice())).to_vec() => { + >::hashed_key_for(alice()) => { (111 * DOLLARS).encode() }, - twox_128(>::key()).to_vec() => { + >::hashed_key().to_vec() => { (111 * DOLLARS).encode() }, - twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32] + >::hashed_key().to_vec() => vec![0u8; 16], + >::hashed_key_for(0) => vec![0u8; 32] ], map![])); let r = executor().call::<_, NeverNativeValue, fn() -> _>( @@ -749,14 +747,14 @@ mod tests { #[test] fn panic_execution_gives_error() { let mut t = TestExternalities::::new_with_code(BLOATY_CODE, (map![ - blake2_256(&>::key_for(alice())).to_vec() => { + >::hashed_key_for(alice()) => { 0_u128.encode() }, - twox_128(>::key()).to_vec() => { + >::hashed_key().to_vec() => { 0_u128.encode() }, - twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32] + >::hashed_key().to_vec() => vec![0u8; 16], + >::hashed_key_for(0) => vec![0u8; 32] ], map![])); let r = WasmExecutor::new() @@ -771,14 +769,14 @@ mod tests { #[test] fn successful_execution_gives_ok() { let mut t = TestExternalities::::new_with_code(COMPACT_CODE, (map![ - blake2_256(&>::key_for(alice())).to_vec() => { + >::hashed_key_for(alice()) => { (111 * DOLLARS).encode() }, - twox_128(>::key()).to_vec() => { + >::hashed_key().to_vec() => { (111 * DOLLARS).encode() }, - twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32] + >::hashed_key().to_vec() => vec![0u8; 16], + >::hashed_key_for(0) => vec![0u8; 32] ], map![])); let r = WasmExecutor::new() @@ -928,17 +926,17 @@ mod tests { // - 1 milldot based on current polkadot runtime. // (this baed on assigning 0.1 CENT to the cheapest tx with `weight = 100`) let mut t = TestExternalities::::new_with_code(COMPACT_CODE, (map![ - blake2_256(&>::key_for(alice())).to_vec() => { + >::hashed_key_for(alice()) => { (100 * DOLLARS).encode() }, - blake2_256(&>::key_for(bob())).to_vec() => { + >::hashed_key_for(bob()) => { (10 * DOLLARS).encode() }, - twox_128(>::key()).to_vec() => { + >::hashed_key().to_vec() => { (110 * DOLLARS).encode() }, - twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32] + >::hashed_key().to_vec() => vec![0u8; 16], + >::hashed_key_for(0) => vec![0u8; 32] ], map![])); let tip = 1_000_000; diff --git a/srml/aura/src/lib.rs b/srml/aura/src/lib.rs index 4df832912a..f3ce6a9e09 100644 --- a/srml/aura/src/lib.rs +++ b/srml/aura/src/lib.rs @@ -155,15 +155,7 @@ decl_storage! { } add_extra_genesis { config(authorities): Vec; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &GenesisConfig - | { - runtime_io::with_storage( - storage, - || Module::::initialize_authorities(&config.authorities), - ); - }) + build(|config| Module::::initialize_authorities(&config.authorities)) } } diff --git a/srml/authority-discovery/src/lib.rs b/srml/authority-discovery/src/lib.rs index ffcb6672c8..106f0cfa36 100644 --- a/srml/authority-discovery/src/lib.rs +++ b/srml/authority-discovery/src/lib.rs @@ -44,15 +44,7 @@ decl_storage! { } add_extra_genesis { config(keys): Vec>; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &GenesisConfig, - | { - sr_io::with_storage( - storage, - || Module::::initialize_keys(&config.keys), - ); - }) + build(|config| Module::::initialize_keys(&config.keys)) } } diff --git a/srml/babe/src/lib.rs b/srml/babe/src/lib.rs index 0f439d489e..e21f083eb6 100644 --- a/srml/babe/src/lib.rs +++ b/srml/babe/src/lib.rs @@ -187,15 +187,7 @@ decl_storage! { } add_extra_genesis { config(authorities): Vec<(AuthorityId, BabeAuthorityWeight)>; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &GenesisConfig - | { - runtime_io::with_storage( - storage, - || Module::::initialize_authorities(&config.authorities), - ); - }) + build(|config| Module::::initialize_authorities(&config.authorities)) } } diff --git a/srml/collective/src/lib.rs b/srml/collective/src/lib.rs index ea616beb4b..03f5362021 100644 --- a/srml/collective/src/lib.rs +++ b/srml/collective/src/lib.rs @@ -99,15 +99,7 @@ decl_storage! { add_extra_genesis { config(phantom): rstd::marker::PhantomData; config(members): Vec; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &Self, - | { - runtime_io::with_storage( - storage, - || Module::::initialize_members(&config.members), - ); - }) + build(|config| Module::::initialize_members(&config.members)) } } diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index 244d653662..f267763217 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -24,8 +24,8 @@ use sr_primitives::traits::{Zero, Bounded, CheckedMul, CheckedDiv, EnsureOrigin, use sr_primitives::weights::SimpleDispatchInfo; use codec::{Encode, Decode, Input, Output, Error}; use srml_support::{ - decl_module, decl_storage, decl_event, ensure, AppendableStorageMap, StorageValue, StorageMap, - Parameter, Dispatchable, EnumerableStorageMap, + decl_module, decl_storage, decl_event, ensure, StorageValue, StorageMap, StorageLinkedMap, + Parameter, Dispatchable, traits::{ Currency, ReservableCurrency, LockableCurrency, WithdrawReason, LockIdentifier, Get, OnFreeBalanceZero diff --git a/srml/elections/src/lib.rs b/srml/elections/src/lib.rs index 63a4509acc..c9aec6df4c 100644 --- a/srml/elections/src/lib.rs +++ b/srml/elections/src/lib.rs @@ -28,7 +28,7 @@ use sr_primitives::traits::{Zero, One, StaticLookup, Bounded, Saturating}; use sr_primitives::weights::SimpleDispatchInfo; use runtime_io::print; use srml_support::{ - StorageValue, StorageMap, AppendableStorageMap, DecodeLengthStorageMap, + StorageValue, StorageMap, dispatch::Result, decl_storage, decl_event, ensure, decl_module, traits::{ Currency, ExistenceRequirement, Get, LockableCurrency, LockIdentifier, diff --git a/srml/generic-asset/src/lib.rs b/srml/generic-asset/src/lib.rs index abd6e1302f..1f4c395d8d 100644 --- a/srml/generic-asset/src/lib.rs +++ b/srml/generic-asset/src/lib.rs @@ -478,15 +478,10 @@ decl_storage! { config(initial_balance): T::Balance; config(endowed_accounts): Vec; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &GenesisConfig| { + build(|config: &GenesisConfig| { config.assets.iter().for_each(|asset_id| { config.endowed_accounts.iter().for_each(|account_id| { - storage.0.insert( - >::key_for(asset_id, account_id), - ::encode(&config.initial_balance) - ); + >::insert(asset_id, account_id, &config.initial_balance); }); }); }); diff --git a/srml/grandpa/src/lib.rs b/srml/grandpa/src/lib.rs index 5fc354eab9..f5c025b174 100644 --- a/srml/grandpa/src/lib.rs +++ b/srml/grandpa/src/lib.rs @@ -162,15 +162,7 @@ decl_storage! { } add_extra_genesis { config(authorities): Vec<(AuthorityId, AuthorityWeight)>; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &GenesisConfig - | { - runtime_io::with_storage( - storage, - || Module::::initialize_authorities(&config.authorities), - ); - }) + build(|config| Module::::initialize_authorities(&config.authorities)) } } diff --git a/srml/im-online/src/lib.rs b/srml/im-online/src/lib.rs index fe604ca788..307c7169d1 100644 --- a/srml/im-online/src/lib.rs +++ b/srml/im-online/src/lib.rs @@ -223,15 +223,7 @@ decl_storage! { } add_extra_genesis { config(keys): Vec; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &GenesisConfig - | { - sr_io::with_storage( - storage, - || Module::::initialize_keys(&config.keys), - ); - }) + build(|config| Module::::initialize_keys(&config.keys)) } } diff --git a/srml/membership/src/lib.rs b/srml/membership/src/lib.rs index aed8b598f7..842d4090b1 100644 --- a/srml/membership/src/lib.rs +++ b/srml/membership/src/lib.rs @@ -62,16 +62,11 @@ decl_storage! { add_extra_genesis { config(members): Vec; config(phantom): sr_std::marker::PhantomData; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &Self, - | { - sr_io::with_storage(storage, || { - let mut members = config.members.clone(); - members.sort(); - T::MembershipInitialized::initialize_members(&members); - >::put(members); - }); + build(|config: &Self| { + let mut members = config.members.clone(); + members.sort(); + T::MembershipInitialized::initialize_members(&members); + >::put(members); }) } } diff --git a/srml/scored-pool/src/lib.rs b/srml/scored-pool/src/lib.rs index f2f5d426d9..f3ea075653 100644 --- a/srml/scored-pool/src/lib.rs +++ b/srml/scored-pool/src/lib.rs @@ -172,32 +172,27 @@ decl_storage! { add_extra_genesis { config(members): Vec; config(phantom): sr_std::marker::PhantomData; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &Self, - | { - sr_io::with_storage(storage, || { - let mut pool = config.pool.clone(); - - // reserve balance for each candidate in the pool. - // panicking here is ok, since this just happens one time, pre-genesis. - pool - .iter() - .for_each(|(who, _)| { - T::Currency::reserve(&who, T::CandidateDeposit::get()) - .expect("balance too low to create candidacy"); - >::insert(who, true); - }); - - /// Sorts the `Pool` by score in a descending order. Entities which - /// have a score of `None` are sorted to the beginning of the vec. - pool.sort_by_key(|(_, maybe_score)| - Reverse(maybe_score.unwrap_or_default()) - ); - - >::put(&pool); - >::refresh_members(pool, ChangeReceiver::MembershipInitialized); - }); + build(|config| { + let mut pool = config.pool.clone(); + + // reserve balance for each candidate in the pool. + // panicking here is ok, since this just happens one time, pre-genesis. + pool + .iter() + .for_each(|(who, _)| { + T::Currency::reserve(&who, T::CandidateDeposit::get()) + .expect("balance too low to create candidacy"); + >::insert(who, true); + }); + + /// Sorts the `Pool` by score in a descending order. Entities which + /// have a score of `None` are sorted to the beginning of the vec. + pool.sort_by_key(|(_, maybe_score)| + Reverse(maybe_score.unwrap_or_default()) + ); + + >::put(&pool); + >::refresh_members(pool, ChangeReceiver::MembershipInitialized); }) } } diff --git a/srml/session/src/lib.rs b/srml/session/src/lib.rs index c474962c65..58a60a9875 100644 --- a/srml/session/src/lib.rs +++ b/srml/session/src/lib.rs @@ -381,41 +381,36 @@ decl_storage! { } add_extra_genesis { config(keys): Vec<(T::ValidatorId, T::Keys)>; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &GenesisConfig - | { - runtime_io::with_storage(storage, || { - for (who, keys) in config.keys.iter().cloned() { - assert!( - >::load_keys(&who).is_none(), - "genesis config contained duplicate validator {:?}", who, - ); - - >::do_set_keys(&who, keys) - .expect("genesis config must not contain duplicates; qed"); - } + build(|config: &GenesisConfig| { + for (who, keys) in config.keys.iter().cloned() { + assert!( + >::load_keys(&who).is_none(), + "genesis config contained duplicate validator {:?}", who, + ); + + >::do_set_keys(&who, keys) + .expect("genesis config must not contain duplicates; qed"); + } - let initial_validators = T::SelectInitialValidators::select_initial_validators() - .unwrap_or_else(|| config.keys.iter().map(|(ref v, _)| v.clone()).collect()); + let initial_validators = T::SelectInitialValidators::select_initial_validators() + .unwrap_or_else(|| config.keys.iter().map(|(ref v, _)| v.clone()).collect()); - assert!(!initial_validators.is_empty(), "Empty validator set in genesis block!"); + assert!(!initial_validators.is_empty(), "Empty validator set in genesis block!"); - let queued_keys: Vec<_> = initial_validators - .iter() - .cloned() - .map(|v| ( - v.clone(), - >::load_keys(&v).unwrap_or_default(), - )) - .collect(); + let queued_keys: Vec<_> = initial_validators + .iter() + .cloned() + .map(|v| ( + v.clone(), + >::load_keys(&v).unwrap_or_default(), + )) + .collect(); - // Tell everyone about the genesis session keys - T::SessionHandler::on_genesis_session::(&queued_keys); + // Tell everyone about the genesis session keys + T::SessionHandler::on_genesis_session::(&queued_keys); - >::put(initial_validators); - >::put(queued_keys); - }); + >::put(initial_validators); + >::put(queued_keys); }); } } diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index e7824d36e0..8b268a8272 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -259,12 +259,10 @@ pub mod inflation; #[cfg(all(feature = "bench", test))] mod benches; -#[cfg(feature = "std")] -use runtime_io::with_storage; use rstd::{prelude::*, result}; use codec::{HasCompact, Encode, Decode}; use srml_support::{ - StorageValue, StorageMap, EnumerableStorageMap, decl_module, decl_event, + StorageValue, StorageMap, StorageLinkedMap, decl_module, decl_event, decl_storage, ensure, traits::{ Currency, OnFreeBalanceZero, OnDilution, LockIdentifier, LockableCurrency, WithdrawReasons, WithdrawReason, OnUnbalanced, Imbalance, Get, Time @@ -619,37 +617,33 @@ decl_storage! { add_extra_genesis { config(stakers): Vec<(T::AccountId, T::AccountId, BalanceOf, StakerStatus)>; - build(| - storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &GenesisConfig - | { - with_storage(storage, || { - for &(ref stash, ref controller, balance, ref status) in &config.stakers { - assert!( - T::Currency::free_balance(&stash) >= balance, - "Stash does not have enough balance to bond." - ); - let _ = >::bond( - T::Origin::from(Some(stash.clone()).into()), - T::Lookup::unlookup(controller.clone()), - balance, - RewardDestination::Staked - ); - let _ = match status { - StakerStatus::Validator => { - >::validate( - T::Origin::from(Some(controller.clone()).into()), - Default::default() - ) - }, StakerStatus::Nominator(votes) => { - >::nominate( - T::Origin::from(Some(controller.clone()).into()), - votes.iter().map(|l| {T::Lookup::unlookup(l.clone())}).collect() - ) - }, _ => Ok(()) - }; - } - }); + build(|config: &GenesisConfig| { + for &(ref stash, ref controller, balance, ref status) in &config.stakers { + assert!( + T::Currency::free_balance(&stash) >= balance, + "Stash does not have enough balance to bond." + ); + let _ = >::bond( + T::Origin::from(Some(stash.clone()).into()), + T::Lookup::unlookup(controller.clone()), + balance, + RewardDestination::Staked, + ); + let _ = match status { + StakerStatus::Validator => { + >::validate( + T::Origin::from(Some(controller.clone()).into()), + Default::default(), + ) + }, + StakerStatus::Nominator(votes) => { + >::nominate( + T::Origin::from(Some(controller.clone()).into()), + votes.iter().map(|l| T::Lookup::unlookup(l.clone())).collect(), + ) + }, _ => Ok(()) + }; + } }); } } diff --git a/srml/staking/src/mock.rs b/srml/staking/src/mock.rs index 2f2e81196c..b7948d12fe 100644 --- a/srml/staking/src/mock.rs +++ b/srml/staking/src/mock.rs @@ -23,7 +23,7 @@ use sr_primitives::testing::{Header, UintAuthorityId}; use sr_staking_primitives::SessionIndex; use primitives::{H256, Blake2Hasher}; use runtime_io; -use srml_support::{assert_ok, impl_outer_origin, parameter_types, EnumerableStorageMap}; +use srml_support::{assert_ok, impl_outer_origin, parameter_types, StorageLinkedMap}; use srml_support::traits::{Currency, Get, FindAuthor}; use crate::{ EraIndex, GenesisConfig, Module, Trait, StakerStatus, ValidatorPrefs, RewardDestination, diff --git a/srml/staking/src/tests.rs b/srml/staking/src/tests.rs index 6e0eaf3b50..bc6b92e2dc 100644 --- a/srml/staking/src/tests.rs +++ b/srml/staking/src/tests.rs @@ -20,7 +20,7 @@ use super::*; use runtime_io::with_externalities; use sr_primitives::traits::OnInitialize; use sr_staking_primitives::offence::{OffenceDetails, OnOffenceHandler}; -use srml_support::{assert_ok, assert_noop, assert_eq_uvec, EnumerableStorageMap}; +use srml_support::{assert_ok, assert_noop, assert_eq_uvec, StorageLinkedMap}; use mock::*; use srml_support::traits::{Currency, ReservableCurrency}; diff --git a/srml/support/procedural/src/lib.rs b/srml/support/procedural/src/lib.rs index 674b90458f..91e0aa2d4d 100644 --- a/srml/support/procedural/src/lib.rs +++ b/srml/support/procedural/src/lib.rs @@ -47,10 +47,29 @@ use proc_macro::TokenStream; /// /// Basic storage consists of a name and a type; supported types are: /// -/// * Value: `Foo: type`: Implements the [`StorageValue`](../srml_support/storage/trait.StorageValue.html) trait. +/// * Value: `Foo: type`: Implements the +/// [`StorageValue`](../srml_support/storage/trait.StorageValue.html) trait using the +/// [`StorageValue generator`](../srml_support/storage/generator/trait.StorageValue.html). +/// /// * Map: `Foo: map hasher($hash) type => type`: Implements the -/// [`StorageMap`](../srml_support/storage/trait.StorageMap.html) trait -/// with `$hash` representing a choice of hashing algorithms available in the +/// [`StorageMap`](../srml_support/storage/trait.StorageMap.html) trait using the +/// [`StorageMap generator`](../srml_support/storage/generator/trait.StorageMap.html). +/// +/// `$hash` representing a choice of hashing algorithms available in the +/// [`Hashable`](../srml_support/trait.Hashable.html) trait. +/// +/// `hasher($hash)` is optional and its default is `blake2_256`. +/// +/// /!\ Be careful with each key in the map that is inserted in the trie +/// `$hash(module_name ++ " " ++ storage_name ++ encoding(key))`. +/// If the keys are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as +/// `blake2_256` must be used. Otherwise, other values in storage can be compromised. +/// +/// * Linked map: `Foo: linked_map hasher($hash) type => type`: Implements the +/// [`StorageLinkedMap`](../srml_support/storage/trait.StorageLinkedMap.html) trait using the +/// [`StorageLinkedMap generator`](../srml_support/storage/generator/trait.StorageLinkedMap.html). +/// +/// `$hash` representing a choice of hashing algorithms available in the /// [`Hashable`](../srml_support/trait.Hashable.html) trait. /// /// `hasher($hash)` is optional and its default is `blake2_256`. @@ -60,12 +79,11 @@ use proc_macro::TokenStream; /// If the keys are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as /// `blake2_256` must be used. Otherwise, other values in storage can be compromised. /// -/// * Linked map: `Foo: linked_map hasher($hash) type => type`: Same as `Map` but also implements -/// the [`EnumerableStorageMap`](../srml_support/storage/trait.EnumerableStorageMap.html) trait. +/// * Double map: `Foo: double_map hasher($hash1) u32, $hash2(u32) => u32`: Implements the +/// [`StorageDoubleMap`](../srml_support/storage/trait.StorageDoubleMap.html) trait using the +/// [`StorageDoubleMap generator`](../srml_support/storage/generator/trait.StorageDoubleMap.html). /// -/// * Double map: `Foo: double_map hasher($hash) u32, $hash2(u32) => u32`: Implements the -/// [`StorageDoubleMap`](../srml_support/storage/trait.StorageDoubleMap.html) trait with -/// `$hash` and `$hash2` representing choices of hashing algorithms available in the +/// `$hash1` and `$hash2` representing choices of hashing algorithms available in the /// [`Hashable`](../srml_support/trait.Hashable.html) trait. /// /// `hasher($hash)` is optional and its default is `blake2_256`. @@ -126,7 +144,7 @@ use proc_macro::TokenStream; /// config(genesis_field): GenesisFieldType; /// config(genesis_field2): GenesisFieldType; /// ... -/// build(|_: &mut StorageOverlay, _: &mut ChildrenStorageOverlay, _: &GenesisConfig| { +/// build(|_: &Self| { /// // Modification of storage /// }) /// } diff --git a/srml/support/procedural/src/storage/impls.rs b/srml/support/procedural/src/storage/impls.rs index d67bc5a116..a5b91eda78 100644 --- a/srml/support/procedural/src/storage/impls.rs +++ b/srml/support/procedural/src/storage/impls.rs @@ -21,13 +21,23 @@ use proc_macro2::TokenStream as TokenStream2; use syn::Ident; use quote::quote; -pub fn option_unwrap(is_option: bool) -> TokenStream2 { +fn from_optional_value_to_query(is_option: bool, fielddefault: TokenStream2) -> TokenStream2 { if !is_option { // raw type case - quote!( unwrap_or_else ) + quote!( v.unwrap_or_else(|| #fielddefault ) ) } else { // Option<> type case - quote!( or_else ) + quote!( v.or_else(|| #fielddefault ) ) + } +} + +fn from_query_to_optional_value(is_option: bool) -> TokenStream2 { + if !is_option { + // raw type case + quote!( Some(v) ) + } else { + // Option<> type case + quote!( v ) } } @@ -43,8 +53,6 @@ pub(crate) struct Impls<'a, I: Iterator> { pub instance_opts: &'a InstanceOpts, pub type_infos: DeclStorageTypeInfos<'a>, pub fielddefault: TokenStream2, - pub default_delegator_ident: syn::Ident, - pub default_delegator_return: TokenStream2, pub prefix: String, pub cratename: &'a syn::Ident, pub name: &'a syn::Ident, @@ -62,8 +70,6 @@ impl<'a, I: Iterator> Impls<'a, I> { instance_opts, type_infos, fielddefault, - default_delegator_ident, - default_delegator_return, prefix, name, attrs, @@ -71,20 +77,9 @@ impl<'a, I: Iterator> Impls<'a, I> { .. } = self; let DeclStorageTypeInfos { typ, value_type, is_option, .. } = type_infos; - let option_simple_1 = option_unwrap(is_option); - let mutate_impl = if !is_option { - quote!{ - >::put(&val, storage) - } - } else { - quote!{ - match val { - Some(ref val) => >::put(&val, storage), - None => >::kill(storage), - } - } - }; + let from_optional_value_to_query = from_optional_value_to_query(is_option, fielddefault); + let from_query_to_optional_value = from_query_to_optional_value(is_option); let InstanceOpts { equal_default_instance, @@ -120,56 +115,26 @@ impl<'a, I: Iterator> Impls<'a, I> { // generator for value quote! { - #visibility struct #default_delegator_ident<#struct_trait>( - #scrate::rstd::marker::PhantomData<(#trait_and_instance)> - ) #where_clause; - impl<#impl_trait> #scrate::traits::StorageDefault<#typ> - for #default_delegator_ident<#trait_and_instance> #where_clause - { - fn default() -> Option<#typ> { - #default_delegator_return - } - } - #( #[ #attrs ] )* #visibility struct #name<#struct_trait>( #scrate::rstd::marker::PhantomData<(#trait_and_instance)> ) #where_clause; - impl<#impl_trait> #scrate::storage::hashed::generator::StorageValue<#typ> + impl<#impl_trait> #scrate::storage::generator::StorageValue<#typ> for #name<#trait_and_instance> #where_clause { type Query = #value_type; - type Default = #default_delegator_ident<#trait_and_instance>; - /// Get the storage key. - fn key() -> &'static [u8] { + fn unhashed_key() -> &'static [u8] { #final_prefix } - /// Load the value from the provided storage instance. - fn get>(storage: &S) -> Self::Query { - storage.get(>::key()) - .#option_simple_1(|| #fielddefault) - } - - /// Take a value from storage, removing it afterwards. - fn take>(storage: &mut S) -> Self::Query { - storage.take(>::key()) - .#option_simple_1(|| #fielddefault) + fn from_optional_value_to_query(v: Option<#typ>) -> Self::Query { + #from_optional_value_to_query } - /// Mutate the value under a key. - fn mutate(f: F, storage: &mut S) -> R - where - F: FnOnce(&mut Self::Query) -> R, - S: #scrate::HashedStorage<#scrate::Twox128>, - { - let mut val = >::get(storage); - - let ret = f(&mut val); - #mutate_impl ; - ret + fn from_query_to_optional_value(v: Self::Query) -> Option<#typ> { + #from_query_to_optional_value } } } @@ -184,8 +149,6 @@ impl<'a, I: Iterator> Impls<'a, I> { instance_opts, type_infos, fielddefault, - default_delegator_ident, - default_delegator_return, prefix, name, attrs, @@ -193,22 +156,9 @@ impl<'a, I: Iterator> Impls<'a, I> { .. } = self; let DeclStorageTypeInfos { typ, value_type, is_option, .. } = type_infos; - let option_simple_1 = option_unwrap(is_option); - - let as_map = quote!{ > }; - let mutate_impl = if !is_option { - quote!{ - #as_map::insert(key, &val, storage) - } - } else { - quote!{ - match val { - Some(ref val) => #as_map::insert(key, &val, storage), - None => #as_map::remove(key, storage), - } - } - }; + let from_optional_value_to_query = from_optional_value_to_query(is_option, fielddefault); + let from_query_to_optional_value = from_query_to_optional_value(is_option); let InstanceOpts { equal_default_instance, @@ -248,74 +198,29 @@ impl<'a, I: Iterator> Impls<'a, I> { // generator for map quote!{ - #visibility struct #default_delegator_ident<#struct_trait>( - #scrate::rstd::marker::PhantomData<(#trait_and_instance)> - ) #where_clause; - impl<#impl_trait> #scrate::traits::StorageDefault<#typ> - for #default_delegator_ident<#trait_and_instance> #where_clause - { - fn default() -> Option<#typ> { - #default_delegator_return - } - } - #( #[ #attrs ] )* #visibility struct #name<#struct_trait>( #scrate::rstd::marker::PhantomData<(#trait_and_instance)> ) #where_clause; - impl<#impl_trait> #scrate::storage::hashed::generator::StorageMap<#kty, #typ> + impl<#impl_trait> #scrate::storage::generator::StorageMap<#kty, #typ> for #name<#trait_and_instance> #where_clause { type Query = #value_type; type Hasher = #scrate::#hasher; - type Default = #default_delegator_ident<#trait_and_instance>; - /// Get the prefix key in storage. fn prefix() -> &'static [u8] { #final_prefix } - /// Get the storage key used to fetch a value corresponding to a specific key. - fn key_for(x: &#kty) -> #scrate::rstd::vec::Vec { - let mut key = #as_map::prefix().to_vec(); - #scrate::codec::Encode::encode_to(x, &mut key); - key - } - - /// Load the value associated with the given key from the map. - fn get>(key: &#kty, storage: &S) -> Self::Query { - let key = #as_map::key_for(key); - storage.get(&key[..]).#option_simple_1(|| #fielddefault) - } - - /// Take the value, reading and removing it. - fn take>(key: &#kty, storage: &mut S) -> Self::Query { - let key = #as_map::key_for(key); - storage.take(&key[..]).#option_simple_1(|| #fielddefault) + fn from_optional_value_to_query(v: Option<#typ>) -> Self::Query { + #from_optional_value_to_query } - /// Mutate the value under a key - fn mutate(key: &#kty, f: F, storage: &mut S) -> R - where - F: FnOnce(&mut Self::Query) -> R, - S: #scrate::HashedStorage<#scrate::#hasher>, - { - let mut val = #as_map::get(key, storage); - - let ret = f(&mut val); - #mutate_impl ; - ret + fn from_query_to_optional_value(v: Self::Query) -> Option<#typ> { + #from_query_to_optional_value } } - - impl<#impl_trait> #scrate::storage::hashed::generator::AppendableStorageMap<#kty, #typ> - for #name<#trait_and_instance> #where_clause - {} - - impl<#impl_trait> #scrate::storage::hashed::generator::DecodeLengthStorageMap<#kty, #typ> - for #name<#trait_and_instance> #where_clause - {} } } @@ -328,8 +233,6 @@ impl<'a, I: Iterator> Impls<'a, I> { instance_opts, type_infos, fielddefault, - default_delegator_ident, - default_delegator_return, prefix, name, attrs, @@ -365,421 +268,58 @@ impl<'a, I: Iterator> Impls<'a, I> { }; let DeclStorageTypeInfos { typ, value_type, is_option, .. } = type_infos; - let option_simple_1 = option_unwrap(is_option); - let name_lowercase = name.to_string().to_lowercase(); - let inner_module = Ident::new( - &format!("__linked_map_details_for_{}_do_not_use", name_lowercase), name.span() - ); - let linkage = Ident::new(&format!("__LinkageFor{}DoNotUse", name), name.span()); - let phantom_data = quote! { #scrate::rstd::marker::PhantomData }; - let as_map = quote!{ > }; - let put_or_insert = quote! { - match linkage { - Some(linkage) => storage.put(key_for, &(val, linkage)), - None => #as_map::insert(key, &val, storage), - } - }; - let mutate_impl = if !type_infos.is_option { - put_or_insert - } else { - quote! { - match val { - Some(ref val) => #put_or_insert, - None => #as_map::remove(key, storage), - } - } - }; - let mutate_map = if type_infos.is_option { - quote! { .map(|(data, linkage)| (Some(data), Some(linkage))) } - } else { - quote! { .map(|(data, linkage)| (data, Some(linkage))) } - }; + let from_optional_value_to_query = from_optional_value_to_query(is_option, fielddefault); + let from_query_to_optional_value = from_query_to_optional_value(is_option); let trait_required = ext::type_contains_ident(value_type, traitinstance) || ext::type_contains_ident(kty, traitinstance); - let (struct_trait, impl_trait, trait_and_instance) = if trait_required { + let (struct_trait, impl_trait, trait_and_instance, where_clause) = if trait_required { ( quote!(#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance), quote!(#traitinstance: #traittype, #instance #bound_instantiable), quote!(#traitinstance, #instance), + where_clause.clone(), ) } else { ( quote!(#instance #bound_instantiable #equal_default_instance), quote!(#instance #bound_instantiable), quote!(#instance), - ) - }; - - let (where_clause, trait_where_clause) = if trait_required { - ( - where_clause.clone(), - where_clause.clone().map(|mut wc| { - wc.predicates.push(syn::parse_quote!(#traitinstance: 'static)); - wc - }).or_else(|| syn::parse_quote!(where #traitinstance: 'static)), - ) - } else { - ( - None, None, ) }; // generator for linked map - let helpers = quote! { - /// Linkage data of an element (it's successor and predecessor) - #[derive(#scrate::codec::Encode, #scrate::codec::Decode)] - pub(crate) struct #linkage { - /// Previous element key in storage (None for the first element) - pub previous: Option, - /// Next element key in storage (None for the last element) - pub next: Option, - } - - mod #inner_module { - use super::*; - - /// Re-exported version of linkage to overcome proc-macro derivation issue. - pub(crate) use super::#linkage as Linkage; - - impl Default for Linkage { - fn default() -> Self { - Self { - previous: None, - next: None, - } - } - } - - /// A key-value pair iterator for enumerable map. - pub(crate) struct Enumerator<'a, S, K, V> { - pub storage: &'a S, - pub next: Option, - pub _data: #phantom_data, - } - - impl<'a, S: #scrate::HashedStorage<#scrate::#hasher>, #impl_trait> Iterator - for Enumerator<'a, S, #kty, (#typ, #trait_and_instance)> #where_clause - { - type Item = (#kty, #typ); - - fn next(&mut self) -> Option { - let next = self.next.take()?; - let key_for = - as #scrate::storage::hashed::generator::StorageMap<#kty, #typ>>::key_for(&next); - - let (val, linkage): (#typ, Linkage<#kty>) = self.storage.get(&*key_for) - .expect("previous/next only contain existing entires; we enumerate using next; entry exists; qed"); - self.next = linkage.next; - Some((next, val)) - } - } - - pub(crate) trait Utils<#struct_trait> { - /// Update linkage when this element is removed. - /// - /// Takes care of updating previous and next elements points - /// as well as updates head if the element is first or last. - fn remove_linkage>(linkage: Linkage<#kty>, storage: &mut S); - - /// Read the contained data and it's linkage. - fn read_with_linkage(storage: &S, key: &[u8]) -> Option<(#typ, Linkage<#kty>)> - where - S: #scrate::HashedStorage<#scrate::#hasher>; - - /// Generate linkage for newly inserted element. - /// - /// Takes care of updating head and previous head's pointer. - fn new_head_linkage>( - storage: &mut S, - key: &#kty, - ) -> Linkage<#kty>; - - /// Read current head pointer. - fn read_head>(storage: &S) -> Option<#kty>; - - /// Overwrite current head pointer. - /// - /// If `None` is given head is removed from storage. - fn write_head>(storage: &mut S, head: Option<&#kty>); - } - } - }; - - let structure = quote! { - #( #[ #attrs ] )* - #visibility struct #name<#struct_trait>(#phantom_data<(#trait_and_instance)>); - - impl<#impl_trait> self::#inner_module::Utils<#trait_and_instance> - for #name<#trait_and_instance> #where_clause - { - fn remove_linkage>( - linkage: self::#inner_module::Linkage<#kty>, - storage: &mut S, - ) { - use self::#inner_module::Utils; - - let next_key = linkage.next.as_ref().map(|x| #as_map::key_for(x)); - let prev_key = linkage.previous.as_ref().map(|x| #as_map::key_for(x)); - - if let Some(prev_key) = prev_key { - // Retrieve previous element and update `next` - let mut res = Self::read_with_linkage(storage, &*prev_key) - .expect("Linkage is updated in case entry is removed; it always points to existing keys; qed"); - res.1.next = linkage.next; - storage.put(&*prev_key, &res); - } else { - // we were first so let's update the head - Self::write_head(storage, linkage.next.as_ref()); - } - - if let Some(next_key) = next_key { - // Update previous of next element - let mut res = Self::read_with_linkage(storage, &*next_key) - .expect("Linkage is updated in case entry is removed; it always points to existing keys; qed"); - res.1.previous = linkage.previous; - storage.put(&*next_key, &res); - } - } - - fn read_with_linkage>( - storage: &S, - key: &[u8], - ) -> Option<(#typ, self::#inner_module::Linkage<#kty>)> { - storage.get(key) - } - - fn new_head_linkage>( - storage: &mut S, - key: &#kty, - ) -> self::#inner_module::Linkage<#kty> { - use self::#inner_module::Utils; - - if let Some(head) = Self::read_head(storage) { - // update previous head predecessor - { - let head_key = #as_map::key_for(&head); - let (data, linkage) = Self::read_with_linkage(storage, &*head_key).expect(r#" - head is set when first element is inserted and unset when last element is removed; - if head is Some then it points to existing key; qed - "#); - storage.put(&*head_key, &(data, self::#inner_module::Linkage { - next: linkage.next.as_ref(), - previous: Some(key), - })); - } - // update to current head - Self::write_head(storage, Some(key)); - // return linkage with pointer to previous head - let mut linkage = self::#inner_module::Linkage::default(); - linkage.next = Some(head); - linkage - } else { - // we are first - update the head and produce empty linkage - Self::write_head(storage, Some(key)); - self::#inner_module::Linkage::default() - } - } - - fn read_head>(storage: &S) -> Option<#kty> { - storage.get(#final_head_key) - } - - fn write_head>(storage: &mut S, head: Option<&#kty>) { - match head { - Some(head) => storage.put(#final_head_key, head), - None => storage.kill(#final_head_key), - } - } - } - }; - quote! { - #helpers - - #structure - - #visibility struct #default_delegator_ident<#struct_trait>( + #( #[ #attrs ] )* + #visibility struct #name<#struct_trait>( #scrate::rstd::marker::PhantomData<(#trait_and_instance)> ) #where_clause; - impl<#impl_trait> #scrate::traits::StorageDefault<#typ> - for #default_delegator_ident<#trait_and_instance> #where_clause - { - fn default() -> Option<#typ> { - #default_delegator_return - } - } - impl<#impl_trait> #scrate::storage::hashed::generator::StorageMap<#kty, #typ> + impl<#impl_trait> #scrate::storage::generator::StorageLinkedMap<#kty, #typ> for #name<#trait_and_instance> #where_clause { type Query = #value_type; type Hasher = #scrate::#hasher; - type Default = #default_delegator_ident<#trait_and_instance>; - /// Get the prefix key in storage. fn prefix() -> &'static [u8] { #final_prefix } - /// Get the storage key used to fetch a value corresponding to a specific key. - fn key_for(key: &#kty) -> #scrate::rstd::vec::Vec { - let mut key_for = #as_map::prefix().to_vec(); - #scrate::codec::Encode::encode_to(&key, &mut key_for); - key_for - } - - /// Load the value associated with the given key from the map. - fn get>(key: &#kty, storage: &S) -> Self::Query { - storage.get(&*#as_map::key_for(key)).#option_simple_1(|| #fielddefault) - } - - /// Take the value, reading and removing it. - fn take>(key: &#kty, storage: &mut S) -> Self::Query { - use self::#inner_module::Utils; - - let res: Option<(#typ, self::#inner_module::Linkage<#kty>)> = storage.take(&*#as_map::key_for(key)); - - res.map(|(d, l)| { - Self::remove_linkage(l, storage); - d - }).#option_simple_1(|| #fielddefault) - } - - /// Remove the value under a key. - fn remove>(key: &#kty, storage: &mut S) { - #as_map::take(key, storage); - } - - /// Store a value to be associated with the given key from the map. - fn insert>( - key: &#kty, - val: &#typ, - storage: &mut S, - ) { - use self::#inner_module::Utils; - - let key_for = &*#as_map::key_for(key); - let linkage = match Self::read_with_linkage(storage, key_for) { - // overwrite but reuse existing linkage - Some((_data, linkage)) => linkage, - // create new linkage - None => Self::new_head_linkage(storage, key), - }; - - storage.put(key_for, &(val, linkage)) - } - - /// Store a value under this key into the provided storage instance; this can take any reference - /// type that derefs to `T` (and has `Encode` implemented). - /// Store a value under this key into the provided storage instance. - fn insert_ref(key: &#kty, val: &Arg, storage: &mut S) - where - #typ: AsRef, - Arg: ?Sized + #scrate::codec::Encode, - S: #scrate::HashedStorage<#scrate::#hasher> - { - use self::#inner_module::Utils; - - let key_for = &*#as_map::key_for(key); - let linkage = match Self::read_with_linkage(storage, key_for) { - // overwrite but reuse existing linkage - Some((_data, linkage)) => linkage, - // create new linkage - None => Self::new_head_linkage(storage, key), - }; - - storage.put(key_for, &(val, linkage)) + fn final_head_key() -> &'static [u8] { + #final_head_key } - /// Mutate the value under a key - fn mutate(key: &#kty, f: F, storage: &mut S) -> R - where - F: FnOnce(&mut Self::Query) -> R, - S: #scrate::HashedStorage<#scrate::#hasher>, - { - use self::#inner_module::Utils; - - let key_for = &*#as_map::key_for(key); - let (mut val, linkage) = Self::read_with_linkage(storage, key_for) - #mutate_map - .unwrap_or_else(|| (#fielddefault, None)); - - let ret = f(&mut val); - #mutate_impl; - ret + fn from_optional_value_to_query(v: Option<#typ>) -> Self::Query { + #from_optional_value_to_query } - // Swap must be overriden not to break links. - fn swap>( - key1: &#kty, - key2: &#kty, - storage: &mut S, - ) { - use self::#inner_module::Utils; - - let final_key1 = &*#as_map::key_for(key1); - let final_key2 = &*#as_map::key_for(key2); - let full_value_1 = Self::read_with_linkage(storage, final_key1); - let full_value_2 = Self::read_with_linkage(storage, final_key2); - - match (full_value_1, full_value_2) { - // Just keep linkage in order and only swap values. - (Some((value1, linkage1)), Some((value2, linkage2))) => { - storage.put(final_key1, &(value2, linkage1)); - storage.put(final_key2, &(value1, linkage2)); - } - // Remove key and insert the new one. - (Some((value, linkage)), None) => { - #as_map::remove(key1, storage); - let linkage = Self::new_head_linkage(storage, key2); - storage.put(final_key2, &(value, linkage)); - } - // Remove key and insert the new one. - (None, Some((value, linkage))) => { - #as_map::remove(key2, storage); - let linkage = Self::new_head_linkage(storage, key1); - storage.put(final_key1, &(value, linkage)); - } - // No-op. - (None, None) => (), - } + fn from_query_to_optional_value(v: Self::Query) -> Option<#typ> { + #from_query_to_optional_value } } - - impl<#impl_trait> #scrate::storage::hashed::generator::EnumerableStorageMap<#kty, #typ> - for #name<#trait_and_instance> #trait_where_clause - { - fn head>(storage: &S) -> Option<#kty> { - use self::#inner_module::Utils; - - Self::read_head(storage) - } - - fn enumerate<'a, S>( - storage: &'a S - ) -> #scrate::rstd::boxed::Box + 'a> - where - S: #scrate::HashedStorage<#scrate::#hasher>, - #kty: 'a, - #typ: 'a, - { - use self::#inner_module::{Utils, Enumerator}; - - #scrate::rstd::boxed::Box::new(Enumerator { - next: Self::read_head(storage), - storage, - _data: #phantom_data::<(#typ, #trait_and_instance)>::default(), - }) - } - } - - impl<#impl_trait> #scrate::storage::hashed::generator::DecodeLengthStorageMap<#kty, #typ> - for #name<#trait_and_instance> #where_clause - {} } } @@ -806,29 +346,9 @@ impl<'a, I: Iterator> Impls<'a, I> { } = self; let DeclStorageTypeInfos { typ, value_type, is_option, .. } = type_infos; - let option_simple_1 = option_unwrap(is_option); - - let as_double_map = quote!{ - > - }; - let mutate_impl = if !is_option { - quote!{ - #as_double_map::insert(k1, k2, &val, storage) - } - } else { - quote!{ - match val { - Some(ref val) => #as_double_map::insert::( - k1, - k2, - val, - storage, - ), - None => #as_double_map::remove(k1, k2, storage), - } - } - }; + let from_optional_value_to_query = from_optional_value_to_query(is_option, fielddefault); + let from_query_to_optional_value = from_query_to_optional_value(is_option); let InstanceOpts { equal_default_instance, @@ -868,90 +388,29 @@ impl<'a, I: Iterator> Impls<'a, I> { // generator for double map quote!{ #( #[ #attrs ] )* - #visibility struct #name<#struct_trait> - (#scrate::rstd::marker::PhantomData<(#trait_and_instance)>); + #visibility struct #name<#struct_trait> ( + #scrate::rstd::marker::PhantomData<(#trait_and_instance)> + ) #where_clause; - impl<#impl_trait> #scrate::storage::unhashed::generator::StorageDoubleMap<#k1ty, #k2ty, #typ> + impl<#impl_trait> #scrate::storage::generator::StorageDoubleMap<#k1ty, #k2ty, #typ> for #name<#trait_and_instance> #where_clause { type Query = #value_type; - fn prefix_for(k1: &KArg1) -> #scrate::rstd::vec::Vec where - KArg1: ?Sized + #scrate::codec::Encode, - #k1ty: #scrate::rstd::borrow::Borrow, - { - use #scrate::storage::hashed::generator::StorageHasher; + type Hasher1 = #scrate::#hasher; - let mut key = #as_double_map::prefix().to_vec(); - #scrate::codec::Encode::encode_to(k1, &mut key); - #scrate::#hasher::hash(&key[..]).to_vec() - } + type Hasher2 = #scrate::#k2_hasher; - fn prefix() -> &'static [u8] { + fn key1_prefix() -> &'static [u8] { #final_prefix } - fn key_for( - k1: &KArg1, - k2: &KArg2, - ) -> #scrate::rstd::vec::Vec where - #k1ty: #scrate::rstd::borrow::Borrow, - #k2ty: #scrate::rstd::borrow::Borrow, - KArg1: ?Sized + #scrate::codec::Encode, - KArg2: ?Sized + #scrate::codec::Encode, - { - use #scrate::storage::hashed::generator::StorageHasher; - - let mut key = #as_double_map::prefix_for(k1); - #scrate::codec::Encode::using_encoded(k2, |e| key.extend(&#scrate::#k2_hasher::hash(e))); - key - } - - fn get( - k1: &KArg1, - k2: &KArg2, - storage: &S, - ) -> Self::Query where - #k1ty: #scrate::rstd::borrow::Borrow, - #k2ty: #scrate::rstd::borrow::Borrow, - KArg1: ?Sized + #scrate::codec::Encode, - KArg2: ?Sized + #scrate::codec::Encode, - { - let key = #as_double_map::key_for(k1, k2); - storage.get(&key).#option_simple_1(|| #fielddefault) - } - - fn take( - k1: &KArg1, - k2: &KArg2, - storage: &mut S, - ) -> Self::Query where - #k1ty: #scrate::rstd::borrow::Borrow, - #k2ty: #scrate::rstd::borrow::Borrow, - KArg1: ?Sized + #scrate::codec::Encode, - KArg2: ?Sized + #scrate::codec::Encode, - { - let key = #as_double_map::key_for(k1, k2); - storage.take(&key).#option_simple_1(|| #fielddefault) + fn from_optional_value_to_query(v: Option<#typ>) -> Self::Query { + #from_optional_value_to_query } - fn mutate( - k1: &KArg1, - k2: &KArg2, - f: F, - storage: &mut S, - ) -> R where - #k1ty: #scrate::rstd::borrow::Borrow, - #k2ty: #scrate::rstd::borrow::Borrow, - KArg1: ?Sized + #scrate::codec::Encode, - KArg2: ?Sized + #scrate::codec::Encode, - F: FnOnce(&mut Self::Query) -> R, - { - let mut val = #as_double_map::get(k1, k2, storage); - - let ret = f(&mut val); - #mutate_impl; - ret + fn from_query_to_optional_value(v: Self::Query) -> Option<#typ> { + #from_query_to_optional_value } } } diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index 039bf8c8f6..cb2c7e6ca9 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -330,11 +330,11 @@ fn decl_store_extra_genesis( let v = (#builder)(&self); < #name<#struct_trait #instance> as - #scrate::storage::hashed::generator::StorageValue<#typ> - >::put(&v, storage); + #scrate::storage::StorageValue<#typ> + >::put(&v); }} }, - DeclStorageTypeInfosKind::Map { key_type, .. } => { + DeclStorageTypeInfosKind::Map { key_type, is_linked, .. } => { let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) || ext::type_contains_ident(key_type, traitinstance) { @@ -344,13 +344,19 @@ fn decl_store_extra_genesis( quote!() }; + let map = if is_linked { + quote! { StorageLinkedMap } + } else { + quote! { StorageMap } + }; + quote!{{ let data = (#builder)(&self); data.into_iter().for_each(|(k, v)| { < #name<#struct_trait #instance> as - #scrate::storage::hashed::generator::StorageMap<#key_type, #typ> - >::insert(&k, &v, storage); + #scrate::storage::#map<#key_type, #typ> + >::insert(&k, &v); }); }} }, @@ -370,8 +376,8 @@ fn decl_store_extra_genesis( data.into_iter().for_each(|(k1, k2, v)| { < #name<#struct_trait #instance> as - #scrate::storage::unhashed::generator::StorageDoubleMap<#key1_type, #key2_type, #typ> - >::insert(&k1, &k2, &v, storage); + #scrate::storage::StorageDoubleMap<#key1_type, #key2_type, #typ> + >::insert(&k1, &k2, &v); }); }} }, @@ -380,7 +386,7 @@ fn decl_store_extra_genesis( } let mut has_scall = false; - let mut scall = quote!{ ( |_, _| {} ) }; + let mut scall = quote!{ let scall: fn(&Self) = |_| {}; scall }; let mut genesis_extrafields = TokenStream2::new(); let mut genesis_extrafields_default = TokenStream2::new(); @@ -418,14 +424,7 @@ fn decl_store_extra_genesis( assimilate_require_generic |= ext::expr_contains_ident(&expr.content, traitinstance); let content = &expr.content; scall = quote_spanned! { expr.span() => - let scall: fn( - &mut ( - #scrate::sr_primitives::StorageOverlay, - #scrate::sr_primitives::ChildrenStorageOverlay - ), - &Self - ) = #content; - scall + let scall: fn(&Self) = #content; scall }; has_scall = true; }, @@ -558,13 +557,13 @@ fn decl_store_extra_genesis( #scrate::sr_primitives::ChildrenStorageOverlay, ), ) -> std::result::Result<(), String> #fn_where_clause { - let storage = &mut tuple_storage.0; + #scrate::with_storage(tuple_storage, || { + #builders - #builders + #scall(&self); - #scall(tuple_storage, &self); - - Ok(()) + Ok(()) + }) } } @@ -771,17 +770,6 @@ fn decl_storage_items( // Propagate doc attributes. let attrs = attrs.inner.iter().filter_map(|a| a.parse_meta().ok()).filter(|m| m.name() == "doc"); - // create default value delegator - let default_delegator_ident = Ident::new( - &format!("{}{}", name.to_string(), "DefaultDelegator"), - proc_macro2::Span::call_site(), - ); - let default_delegator_return = if !type_infos.is_option { - quote! { Some(#fielddefault) } - } else { - quote! { #fielddefault } - }; - let i = impls::Impls { scrate, visibility, @@ -791,8 +779,6 @@ fn decl_storage_items( instance_opts, type_infos, fielddefault, - default_delegator_ident, - default_delegator_return, prefix: build_prefix(cratename, name), name, attrs, @@ -903,14 +889,14 @@ fn impl_store_fns( quote!{ #( #[ #attrs ] )* pub fn #get_fn() -> #value_type { - <#name<#struct_trait #instance> as - #scrate::storage::hashed::generator::StorageValue<#typ>> :: get( - &#scrate::storage::RuntimeStorage - ) + < + #name<#struct_trait #instance> as + #scrate::storage::StorageValue<#typ> + >::get() } } }, - DeclStorageTypeInfosKind::Map { key_type, .. } => { + DeclStorageTypeInfosKind::Map { key_type, is_linked, .. } => { let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) || ext::type_contains_ident(key_type, traitinstance) { @@ -919,13 +905,19 @@ fn impl_store_fns( quote!() }; + let map = if is_linked { + quote! { StorageLinkedMap } + } else { + quote! { StorageMap } + }; + quote!{ #( #[ #attrs ] )* pub fn #get_fn>(key: K) -> #value_type { < #name<#struct_trait #instance> as - #scrate::storage::hashed::generator::StorageMap<#key_type, #typ> - >::get(key.borrow(), &#scrate::storage::RuntimeStorage) + #scrate::storage::#map<#key_type, #typ> + >::get(key.borrow()) } } } @@ -949,8 +941,8 @@ fn impl_store_fns( { < #name<#struct_trait #instance> as - #scrate::storage::unhashed::generator::StorageDoubleMap<#key1_type, #key2_type, #typ> - >::get(k1, k2, &#scrate::storage::RuntimeStorage) + #scrate::storage::StorageDoubleMap<#key1_type, #key2_type, #typ> + >::get(k1, k2) } } } diff --git a/srml/support/src/hashable.rs b/srml/support/src/hashable.rs index b3ee2b3612..f0918cc358 100644 --- a/srml/support/src/hashable.rs +++ b/srml/support/src/hashable.rs @@ -18,7 +18,7 @@ use crate::codec::Codec; use runtime_io::{blake2_128, blake2_256, twox_128, twox_256}; -use crate::storage::hashed::generator::StorageHasher; +use crate::storage::hashed::StorageHasher; use crate::Twox64Concat; use crate::rstd::prelude::Vec; diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index 9ebd848fca..6795603ade 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -35,11 +35,11 @@ pub use codec; pub use once_cell; #[doc(hidden)] pub use paste; +#[cfg(feature = "std")] +#[doc(hidden)] +pub use runtime_io::with_storage; -pub use self::storage::hashed::generator::{ - HashedStorage, Twox256, Twox128, Blake2_256, Blake2_128, Twox64Concat -}; -pub use self::storage::unhashed::generator::UnhashedStorage; +pub use self::storage::hashed::{Twox256, Twox128, Blake2_256, Blake2_128, Twox64Concat}; #[macro_use] pub mod dispatch; @@ -61,10 +61,7 @@ pub mod unsigned; mod double_map; pub mod traits; -pub use self::storage::{ - StorageValue, StorageMap, EnumerableStorageMap, StorageDoubleMap, AppendableStorageMap, - DecodeLengthStorageMap, -}; +pub use self::storage::{StorageValue, StorageMap, StorageLinkedMap, StorageDoubleMap}; pub use self::hashable::Hashable; pub use self::dispatch::{Parameter, Dispatchable, Callable, IsSubType}; pub use self::double_map::StorageDoubleMapWithHasher; diff --git a/srml/support/src/metadata.rs b/srml/support/src/metadata.rs index 4bc1f906da..7ae5f7d193 100644 --- a/srml/support/src/metadata.rs +++ b/srml/support/src/metadata.rs @@ -324,7 +324,7 @@ mod tests { StorageMethod : Option; } add_extra_genesis { - build(|_, _| {}); + build(|_| {}); } } } diff --git a/srml/support/src/storage/child.rs b/srml/support/src/storage/child.rs index e69de29bb2..6000dd2f17 100644 --- a/srml/support/src/storage/child.rs +++ b/srml/support/src/storage/child.rs @@ -0,0 +1,106 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Operation on runtime child storages. +//! +//! This module is a currently only a variant of unhashed with additional `storage_key`. +//! Note that `storage_key` must be unique and strong (strong in the sense of being long enough to +//! avoid collision from a resistant hash function (which unique implies)). +// NOTE: could replace unhashed by having only one kind of storage (root being null storage key (storage_key can become Option<&[u8]>). + +use super::{Codec, Encode, Decode, Vec}; + +/// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. +pub fn get(storage_key: &[u8], key: &[u8]) -> Option { + runtime_io::child_storage(storage_key, key).map(|v| { + Decode::decode(&mut &v[..]).expect("storage is not null, therefore must be a valid type") + }) +} + +/// Return the value of the item in storage under `key`, or the type's default if there is no +/// explicit entry. +pub fn get_or_default(storage_key: &[u8], key: &[u8]) -> T { + get(storage_key, key).unwrap_or_else(Default::default) +} + +/// Return the value of the item in storage under `key`, or `default_value` if there is no +/// explicit entry. +pub fn get_or(storage_key: &[u8], key: &[u8], default_value: T) -> T { + get(storage_key, key).unwrap_or(default_value) +} + +/// Return the value of the item in storage under `key`, or `default_value()` if there is no +/// explicit entry. +pub fn get_or_else T>(storage_key: &[u8], key: &[u8], default_value: F) -> T { + get(storage_key, key).unwrap_or_else(default_value) +} + +/// Put `value` in storage under `key`. +pub fn put(storage_key: &[u8], key: &[u8], value: &T) { + value.using_encoded(|slice| runtime_io::set_child_storage(storage_key, key, slice)); +} + +/// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise. +pub fn take(storage_key: &[u8], key: &[u8]) -> Option { + let r = get(storage_key, key); + if r.is_some() { + kill(storage_key, key); + } + r +} + +/// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage, +/// the default for its type. +pub fn take_or_default(storage_key: &[u8], key: &[u8]) -> T { + take(storage_key, key).unwrap_or_else(Default::default) +} + +/// Return the value of the item in storage under `key`, or `default_value` if there is no +/// explicit entry. Ensure there is no explicit entry on return. +pub fn take_or(storage_key: &[u8],key: &[u8], default_value: T) -> T { + take(storage_key, key).unwrap_or(default_value) +} + +/// Return the value of the item in storage under `key`, or `default_value()` if there is no +/// explicit entry. Ensure there is no explicit entry on return. +pub fn take_or_else T>(storage_key: &[u8], key: &[u8], default_value: F) -> T { + take(storage_key, key).unwrap_or_else(default_value) +} + +/// Check to see if `key` has an explicit entry in storage. +pub fn exists(storage_key: &[u8], key: &[u8]) -> bool { + runtime_io::read_child_storage(storage_key, key, &mut [0;0][..], 0).is_some() +} + +/// Remove all `storage_key` key/values +pub fn kill_storage(storage_key: &[u8]) { + runtime_io::kill_child_storage(storage_key) +} + +/// Ensure `key` has no explicit entry in storage. +pub fn kill(storage_key: &[u8], key: &[u8]) { + runtime_io::clear_child_storage(storage_key, key); +} + +/// Get a Vec of bytes from storage. +pub fn get_raw(storage_key: &[u8], key: &[u8]) -> Option> { + runtime_io::child_storage(storage_key, key) +} + +/// Put a raw byte slice into storage. +pub fn put_raw(storage_key: &[u8], key: &[u8], value: &[u8]) { + runtime_io::set_child_storage(storage_key, key, value) +} diff --git a/srml/support/src/storage/generator/double_map.rs b/srml/support/src/storage/generator/double_map.rs new file mode 100644 index 0000000000..a1898c3b88 --- /dev/null +++ b/srml/support/src/storage/generator/double_map.rs @@ -0,0 +1,194 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use sr_std::prelude::*; +use codec::{Codec, Encode, EncodeAppend}; +use crate::{storage::{self, unhashed, hashed::StorageHasher}, rstd::borrow::Borrow}; + +/// Generator for `StorageDoubleMap` used by `decl_storage`. +/// +/// # Mapping of keys to a storage path +/// +/// The storage key (i.e. the key under which the `Value` will be stored) is created from two parts. +/// The first part is a hash of a concatenation of the `key1_prefix` and `Key1`. And the second part +/// is a hash of a `Key2`. +/// +/// Thus value for (key1, key2) is stored at `Hasher1(key1_prefix ++ key1) ++ Hasher2(key2)`. +/// +/// /!\ be careful while choosing the Hash, indeed malicious could craft second keys to lower the +/// trie. +pub trait StorageDoubleMap { + /// The type that get/take returns. + type Query; + + /// Hasher for the first key. + type Hasher1: StorageHasher; + + /// Hasher for the second key. + type Hasher2: StorageHasher; + + /// Get the prefix for first key. + fn key1_prefix() -> &'static [u8]; + + /// Convert an optional value retrieved from storage to the type queried. + fn from_optional_value_to_query(v: Option) -> Self::Query; + + /// Convert a query to an optional value into storage. + fn from_query_to_optional_value(v: Self::Query) -> Option; + + /// Generate the first part of the key used in top storage. + fn storage_double_map_final_key1(k1: &KArg1) -> ::Output + where + KArg1: ?Sized + Encode, + K1: Borrow, + { + let mut final_key1 = Self::key1_prefix().to_vec(); + k1.encode_to(&mut final_key1); + Self::Hasher1::hash(&final_key1) + } + + /// Generate the full key used in top storage. + fn storage_double_map_final_key(k1: &KArg1, k2: &KArg2) -> Vec + where + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, + K1: Borrow, + K2: Borrow, + { + let mut final_key = Self::storage_double_map_final_key1(k1).as_ref().to_vec(); + final_key.extend_from_slice(k2.using_encoded(Self::Hasher2::hash).as_ref()); + final_key + } +} + +impl storage::StorageDoubleMap for G +where + K1: Encode, + K2: Encode, + V: Codec, + G: StorageDoubleMap, +{ + type Query = G::Query; + + fn exists(k1: &KArg1, k2: &KArg2) -> bool + where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, + { + unhashed::exists(&Self::storage_double_map_final_key(k1, k2)) + } + + fn get(k1: &KArg1, k2: &KArg2) -> Self::Query + where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, + { + G::from_optional_value_to_query(unhashed::get(&Self::storage_double_map_final_key(k1, k2))) + } + + fn take(k1: &KArg1, k2: &KArg2) -> Self::Query + where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, + { + let final_key = Self::storage_double_map_final_key(k1, k2); + + let value = unhashed::take(&final_key); + G::from_optional_value_to_query(value) + } + + fn insert(k1: &KArg1, k2: &KArg2, val: &VArg) + where + K1: Borrow, + K2: Borrow, + V: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, + VArg: ?Sized + Encode, + { + unhashed::put(&Self::storage_double_map_final_key(k1, k2), &val.borrow()) + } + + fn remove(k1: &KArg1, k2: &KArg2) + where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, + { + unhashed::kill(&Self::storage_double_map_final_key(k1, k2)) + } + + fn remove_prefix(k1: &KArg1) where KArg1: ?Sized + Encode, K1: Borrow { + unhashed::kill_prefix(Self::storage_double_map_final_key1(k1).as_ref()) + } + + fn mutate(k1: &KArg1, k2: &KArg2, f: F) -> R + where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, + F: FnOnce(&mut Self::Query) -> R, + { + let mut val = G::get(k1, k2); + + let ret = f(&mut val); + match G::from_query_to_optional_value(val) { + Some(ref val) => G::insert(k1, k2, val), + None => G::remove(k1, k2), + } + ret + } + + fn append( + k1: &KArg1, + k2: &KArg2, + items: &[I], + ) -> Result<(), &'static str> + where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, + I: codec::Encode, + V: EncodeAppend, + { + let final_key = Self::storage_double_map_final_key(k1, k2); + + let encoded_value = unhashed::get_raw(&final_key) + .unwrap_or_else(|| { + match G::from_query_to_optional_value(G::from_optional_value_to_query(None)) { + Some(value) => value.encode(), + None => vec![], + } + }); + + let new_val = V::append( + encoded_value, + items, + ).map_err(|_| "Could not append given item")?; + unhashed::put_raw(&final_key, &new_val); + + Ok(()) + } +} diff --git a/srml/support/src/storage/generator/linked_map.rs b/srml/support/src/storage/generator/linked_map.rs new file mode 100644 index 0000000000..b087cf42f5 --- /dev/null +++ b/srml/support/src/storage/generator/linked_map.rs @@ -0,0 +1,327 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use codec::{Codec, Encode, Decode}; +use crate::{storage::{self, unhashed, hashed::StorageHasher}, traits::Len}; +use sr_std::{ + borrow::Borrow, + marker::PhantomData, +}; + +/// Generator for `StorageLinkedMap` used by `decl_storage`. +/// +/// For each key value is stored at `Hasher(prefix ++ key)` along with a linkage used for +/// enumeration. +pub trait StorageLinkedMap { + /// The type that get/take returns. + type Query; + + /// Hasher used to insert into storage. + type Hasher: StorageHasher; + + /// Prefix used to prepend each key. + fn prefix() -> &'static [u8]; + + /// Key used to store linked map head. + fn final_head_key() -> &'static [u8]; + + /// Convert an optionnal value retrieved from storage to the type queried. + fn from_optional_value_to_query(v: Option) -> Self::Query; + + /// Convert a query to an optionnal value into storage. + fn from_query_to_optional_value(v: Self::Query) -> Option; + + /// Generate the full key used in top storage. + fn storage_linked_map_final_key(key: KeyArg) -> ::Output + where + KeyArg: Borrow, + { + let mut final_key = Self::prefix().to_vec(); + key.borrow().encode_to(&mut final_key); + Self::Hasher::hash(&final_key) + } +} + +/// Linkage data of an element (it's successor and predecessor) +#[derive(Encode, Decode)] +pub struct Linkage { + /// Previous element key in storage (None for the first element) + pub previous: Option, + /// Next element key in storage (None for the last element) + pub next: Option, +} + +impl Default for Linkage { + fn default() -> Self { + Self { + previous: None, + next: None, + } + } +} + +/// A key-value pair iterator for enumerable map. +pub struct Enumerator> { + next: Option, + _phantom: PhantomData<(G, V)>, +} + +impl> Iterator for Enumerator { + type Item = (K, V); + + fn next(&mut self) -> Option { + let next = self.next.take()?; + let (val, linkage): (V, Linkage) = { + let next_full_key = G::storage_linked_map_final_key(&next); + unhashed::get(next_full_key.as_ref()) + .expect("previous/next only contain existing entires; + we enumerate using next; entry exists; qed") + }; + + self.next = linkage.next; + Some((next, val)) + } +} + +/// Update linkage when this element is removed. +/// +/// Takes care of updating previous and next elements points +/// as well as updates head if the element is first or last. +fn remove_linkage>(linkage: Linkage) { + let next_key = linkage.next.as_ref() + .map(G::storage_linked_map_final_key) + .map(|x| x.as_ref().to_vec()); + let prev_key = linkage.previous.as_ref() + .map(G::storage_linked_map_final_key) + .map(|x| x.as_ref().to_vec()); + + if let Some(prev_key) = prev_key { + // Retrieve previous element and update `next` + let mut res = read_with_linkage::<_, _, G>(prev_key.as_ref()) + .expect("Linkage is updated in case entry is removed; + it always points to existing keys; qed"); + res.1.next = linkage.next; + unhashed::put(prev_key.as_ref(), &res); + } else { + // we were first so let's update the head + write_head::<_, _, G>(linkage.next.as_ref()); + } + if let Some(next_key) = next_key { + // Update previous of next element + let mut res = read_with_linkage::<_, _, G>(next_key.as_ref()) + .expect("Linkage is updated in case entry is removed; + it always points to existing keys; qed"); + res.1.previous = linkage.previous; + unhashed::put(next_key.as_ref(), &res); + } +} + +/// Read the contained data and it's linkage. +fn read_with_linkage(key: &[u8]) -> Option<(V, Linkage)> +where + K: Codec, + V: Codec, + G: StorageLinkedMap +{ + unhashed::get(key) +} + +/// Generate linkage for newly inserted element. +/// +/// Takes care of updating head and previous head's pointer. +fn new_head_linkage(key: &K) -> Linkage +where + K: Codec, + V: Codec, + G: StorageLinkedMap +{ + if let Some(head) = read_head::<_, _, G>() { + // update previous head predecessor + { + let head_key = G::storage_linked_map_final_key(&head); + let (data, linkage) = read_with_linkage::<_, _, G>(head_key.as_ref()) + .expect("head is set when first element is inserted + and unset when last element is removed; + if head is Some then it points to existing key; qed"); + unhashed::put(head_key.as_ref(), &(data, Linkage { + next: linkage.next.as_ref(), + previous: Some(key), + })); + } + // update to current head + write_head::<_, _, G>(Some(key)); + // return linkage with pointer to previous head + let mut linkage = Linkage::default(); + linkage.next = Some(head); + linkage + } else { + // we are first - update the head and produce empty linkage + write_head::<_, _, G>(Some(key)); + Linkage::default() + } +} + +/// Read current head pointer. +fn read_head() -> Option +where + K: Codec, + V: Codec, + G: StorageLinkedMap +{ + unhashed::get(G::final_head_key()) +} + +/// Overwrite current head pointer. +/// +/// If `None` is given head is removed from storage. +fn write_head(head: Option<&K>) +where + K: Codec, + V: Codec, + G: StorageLinkedMap +{ + match head { + Some(head) => unhashed::put(G::final_head_key(), head), + None => unhashed::kill(G::final_head_key()), + } +} + +impl> storage::StorageLinkedMap for G { + type Query = G::Query; + + type Enumerator = Enumerator; + + fn exists>(key: KeyArg) -> bool { + unhashed::exists(Self::storage_linked_map_final_key(key).as_ref()) + } + + fn get>(key: KeyArg) -> Self::Query { + let val = unhashed::get(Self::storage_linked_map_final_key(key).as_ref()); + G::from_optional_value_to_query(val) + } + + fn swap, KeyArg2: Borrow>(key1: KeyArg1, key2: KeyArg2) { + let final_key1 = Self::storage_linked_map_final_key(key1.borrow()); + let final_key2 = Self::storage_linked_map_final_key(key2.borrow()); + let full_value_1 = read_with_linkage::<_, _, G>(final_key1.as_ref()); + let full_value_2 = read_with_linkage::<_, _, G>(final_key2.as_ref()); + + match (full_value_1, full_value_2) { + // Just keep linkage in order and only swap values. + (Some((value1, linkage1)), Some((value2, linkage2))) => { + unhashed::put(final_key1.as_ref(), &(value2, linkage1)); + unhashed::put(final_key2.as_ref(), &(value1, linkage2)); + } + // Remove key and insert the new one. + (Some((value, _linkage)), None) => { + Self::remove(key1); + let linkage = new_head_linkage::<_, _, G>(key2.borrow()); + unhashed::put(final_key2.as_ref(), &(value, linkage)); + } + // Remove key and insert the new one. + (None, Some((value, _linkage))) => { + Self::remove(key2); + let linkage = new_head_linkage::<_, _, G>(key1.borrow()); + unhashed::put(final_key1.as_ref(), &(value, linkage)); + } + // No-op. + (None, None) => (), + } + } + + fn insert, ValArg: Borrow>(key: KeyArg, val: ValArg) { + let final_key = Self::storage_linked_map_final_key(key.borrow()); + let linkage = match read_with_linkage::<_, _, G>(final_key.as_ref()) { + // overwrite but reuse existing linkage + Some((_data, linkage)) => linkage, + // create new linkage + None => new_head_linkage::<_, _, G>(key.borrow()), + }; + unhashed::put(final_key.as_ref(), &(val.borrow(), linkage)) + } + + fn insert_ref, ValArg: ?Sized + Encode>(key: KeyArg, val: &ValArg) + where + V: AsRef + { + let final_key = Self::storage_linked_map_final_key(key.borrow()); + let linkage = match read_with_linkage::<_, _, G>(final_key.as_ref()) { + // overwrite but reuse existing linkage + Some((_data, linkage)) => linkage, + // create new linkage + None => new_head_linkage::<_, _, G>(key.borrow()), + }; + unhashed::put(final_key.as_ref(), &(&val, &linkage)) + } + + fn remove>(key: KeyArg) { + G::take(key); + } + + fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R { + let final_key = Self::storage_linked_map_final_key(key.borrow()); + + let (mut val, _linkage) = read_with_linkage::<_, _, G>(final_key.as_ref()) + .map(|(data, linkage)| (G::from_optional_value_to_query(Some(data)), Some(linkage))) + .unwrap_or_else(|| (G::from_optional_value_to_query(None), None)); + + let ret = f(&mut val); + match G::from_query_to_optional_value(val) { + Some(ref val) => G::insert(key.borrow(), val), + None => G::remove(key.borrow()), + } + ret + } + + fn take>(key: KeyArg) -> Self::Query { + let final_key = Self::storage_linked_map_final_key(key); + + let full_value: Option<(V, Linkage)> = unhashed::take(final_key.as_ref()); + + let value = full_value.map(|(data, linkage)| { + remove_linkage::<_, _, G>(linkage); + data + }); + + G::from_optional_value_to_query(value) + } + + fn enumerate() -> Self::Enumerator { + Enumerator::<_, _, G> { + next: read_head::<_, _, G>(), + _phantom: Default::default(), + } + } + + fn head() -> Option { + read_head::<_, _, G>() + } + + fn decode_len>(key: KeyArg) -> Result + where V: codec::DecodeLength + Len + { + let key = Self::storage_linked_map_final_key(key); + if let Some(v) = unhashed::get_raw(key.as_ref()) { + ::len(&v).map_err(|e| e.what()) + } else { + let len = G::from_query_to_optional_value(G::from_optional_value_to_query(None)) + .map(|v| v.len()) + .unwrap_or(0); + + Ok(len) + } + } +} diff --git a/srml/support/src/storage/generator/map.rs b/srml/support/src/storage/generator/map.rs new file mode 100644 index 0000000000..1d660da3b4 --- /dev/null +++ b/srml/support/src/storage/generator/map.rs @@ -0,0 +1,167 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +#[cfg(not(feature = "std"))] +use sr_std::prelude::*; +use sr_std::borrow::Borrow; +use codec::{Codec, Encode}; +use crate::{storage::{self, unhashed, hashed::StorageHasher}, traits::Len}; + +/// Generator for `StorageMap` used by `decl_storage`. +/// +/// For each key value is stored at `Hasher(prefix ++ key)`. +pub trait StorageMap { + /// The type that get/take returns. + type Query; + + /// Hasher used to insert into storage. + type Hasher: StorageHasher; + + /// Prefix used to prepend each key. + fn prefix() -> &'static [u8]; + + /// Convert an optional value retrieved from storage to the type queried. + fn from_optional_value_to_query(v: Option) -> Self::Query; + + /// Convert a query to an optional value into storage. + fn from_query_to_optional_value(v: Self::Query) -> Option; + + /// Generate the full key used in top storage. + fn storage_map_final_key(key: KeyArg) -> ::Output + where + KeyArg: Borrow, + { + let mut final_key = Self::prefix().to_vec(); + key.borrow().encode_to(&mut final_key); + Self::Hasher::hash(&final_key) + } +} + +impl> storage::StorageMap for G { + type Query = G::Query; + + fn hashed_key_for>(key: KeyArg) -> Vec { + Self::storage_map_final_key(key).as_ref().to_vec() + } + + fn swap, KeyArg2: Borrow>(key1: KeyArg1, key2: KeyArg2) { + let k1 = Self::storage_map_final_key(key1); + let k2 = Self::storage_map_final_key(key2); + + let v1 = unhashed::get_raw(k1.as_ref()); + if let Some(val) = unhashed::get_raw(k2.as_ref()) { + unhashed::put_raw(k1.as_ref(), &val); + } else { + unhashed::kill(k1.as_ref()) + } + if let Some(val) = v1 { + unhashed::put_raw(k2.as_ref(), &val); + } else { + unhashed::kill(k2.as_ref()) + } + } + + fn exists>(key: KeyArg) -> bool { + unhashed::exists(Self::storage_map_final_key(key).as_ref()) + } + + fn get>(key: KeyArg) -> Self::Query { + G::from_optional_value_to_query(unhashed::get(Self::storage_map_final_key(key).as_ref())) + } + + fn insert, ValArg: Borrow>(key: KeyArg, val: ValArg) { + unhashed::put(Self::storage_map_final_key(key).as_ref(), &val.borrow()) + } + + fn insert_ref, ValArg: ?Sized + Encode>(key: KeyArg, val: &ValArg) + where V: AsRef + { + val.using_encoded(|b| unhashed::put_raw(Self::storage_map_final_key(key).as_ref(), b)) + } + + fn remove>(key: KeyArg) { + unhashed::kill(Self::storage_map_final_key(key).as_ref()) + } + + fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R { + let mut val = G::get(key.borrow()); + + let ret = f(&mut val); + match G::from_query_to_optional_value(val) { + Some(ref val) => G::insert(key, val), + None => G::remove(key), + } + ret + } + + fn take>(key: KeyArg) -> Self::Query { + let key = Self::storage_map_final_key(key); + let value = unhashed::take(key.as_ref()); + G::from_optional_value_to_query(value) + } + + fn append<'a, I, R, KeyArg>(key: KeyArg, items: R) -> Result<(), &'static str> + where + KeyArg: Borrow, + I: 'a + codec::Encode, + V: codec::EncodeAppend, + R: IntoIterator, + R::IntoIter: ExactSizeIterator, + { + let key = Self::storage_map_final_key(key); + let encoded_value = unhashed::get_raw(key.as_ref()) + .unwrap_or_else(|| { + match G::from_query_to_optional_value(G::from_optional_value_to_query(None)) { + Some(value) => value.encode(), + None => vec![], + } + }); + + let new_val = V::append( + encoded_value, + items, + ).map_err(|_| "Could not append given item")?; + unhashed::put_raw(key.as_ref(), &new_val); + Ok(()) + } + + fn append_or_insert<'a, I, R, KeyArg>(key: KeyArg, items: R) + where + KeyArg: Borrow, + I: 'a + codec::Encode + Clone, + V: codec::EncodeAppend + crate::rstd::iter::FromIterator, + R: IntoIterator + Clone, + R::IntoIter: ExactSizeIterator, + { + Self::append(key.borrow(), items.clone()) + .unwrap_or_else(|_| Self::insert(key, &items.into_iter().cloned().collect())); + } + + fn decode_len>(key: KeyArg) -> Result + where V: codec::DecodeLength + Len + { + let key = Self::storage_map_final_key(key); + if let Some(v) = unhashed::get_raw(key.as_ref()) { + ::len(&v).map_err(|e| e.what()) + } else { + let len = G::from_query_to_optional_value(G::from_optional_value_to_query(None)) + .map(|v| v.len()) + .unwrap_or(0); + + Ok(len) + } + } +} diff --git a/srml/support/src/storage/generator/mod.rs b/srml/support/src/storage/generator/mod.rs new file mode 100644 index 0000000000..a53ce7a831 --- /dev/null +++ b/srml/support/src/storage/generator/mod.rs @@ -0,0 +1,32 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Generators are a set of trait on which storage traits are implemented. +//! +//! (i.e. implementing the generator for StorageValue on a type will automatically derive the +//! implementation of StorageValue for this type). +//! +//! They are used by `decl_storage`. + +mod linked_map; +mod map; +mod double_map; +mod value; + +pub use linked_map::{StorageLinkedMap, Enumerator}; +pub use map::StorageMap; +pub use double_map::StorageDoubleMap; +pub use value::StorageValue; diff --git a/srml/support/src/storage/generator/value.rs b/srml/support/src/storage/generator/value.rs new file mode 100644 index 0000000000..32b4a195c8 --- /dev/null +++ b/srml/support/src/storage/generator/value.rs @@ -0,0 +1,156 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +#[cfg(not(feature = "std"))] +use sr_std::prelude::*; +use sr_std::{borrow::Borrow, iter::FromIterator}; +use codec::{Codec, Encode}; +use crate::{storage::{self, unhashed, hashed::{Twox128, StorageHasher}}, traits::Len}; + +/// Generator for `StorageValue` used by `decl_storage`. +/// +/// Value is stored at `Twox128(unhashed_key)`. +pub trait StorageValue { + /// The type that get/take returns. + type Query; + + /// Unhashed key used in storage + fn unhashed_key() -> &'static [u8]; + + /// Convert an optional value retrieved from storage to the type queried. + fn from_optional_value_to_query(v: Option) -> Self::Query; + + /// Convert a query to an optional value into storage. + fn from_query_to_optional_value(v: Self::Query) -> Option; + + /// Generate the full key used in top storage. + fn storage_value_final_key() -> [u8; 16] { + Twox128::hash(Self::unhashed_key()) + } +} + +impl> storage::StorageValue for G { + type Query = G::Query; + + fn hashed_key() -> [u8; 16] { + Self::storage_value_final_key() + } + + fn exists() -> bool { + unhashed::exists(&Self::storage_value_final_key()) + } + + fn get() -> Self::Query { + let value = unhashed::get(&Self::storage_value_final_key()); + G::from_optional_value_to_query(value) + } + + fn put>(val: Arg) { + unhashed::put(&Self::storage_value_final_key(), val.borrow()) + } + + fn put_ref(val: &Arg) where T: AsRef { + val.using_encoded(|b| unhashed::put_raw(&Self::storage_value_final_key(), b)) + } + + fn kill() { + unhashed::kill(&Self::storage_value_final_key()) + } + + fn mutate R>(f: F) -> R { + let mut val = G::get(); + + let ret = f(&mut val); + match G::from_query_to_optional_value(val) { + Some(ref val) => G::put(val), + None => G::kill(), + } + ret + } + + fn take() -> G::Query { + let key = Self::storage_value_final_key(); + let value = unhashed::get(&key); + if value.is_some() { + unhashed::kill(&key) + } + G::from_optional_value_to_query(value) + } + + /// Append the given items to the value in the storage. + /// + /// `T` is required to implement `codec::EncodeAppend`. + fn append<'a, I, R>(items: R) -> Result<(), &'static str> + where + I: 'a + codec::Encode, + T: codec::EncodeAppend, + R: IntoIterator, + R::IntoIter: ExactSizeIterator, + { + let key = Self::storage_value_final_key(); + let encoded_value = unhashed::get_raw(&key) + .unwrap_or_else(|| { + match G::from_query_to_optional_value(G::from_optional_value_to_query(None)) { + Some(value) => value.encode(), + None => vec![], + } + }); + + let new_val = T::append( + encoded_value, + items, + ).map_err(|_| "Could not append given item")?; + unhashed::put_raw(&key, &new_val); + Ok(()) + } + + /// Safely append the given items to the value in the storage. If a codec error occurs, then the + /// old (presumably corrupt) value is replaced with the given `items`. + /// + /// `T` is required to implement `codec::EncodeAppend`. + fn append_or_put<'a, I, R>(items: R) + where + I: 'a + codec::Encode + Clone, + T: codec::EncodeAppend + FromIterator, + R: IntoIterator + Clone, + R::IntoIter: ExactSizeIterator, + { + Self::append(items.clone()) + .unwrap_or_else(|_| Self::put(&items.into_iter().cloned().collect())); + } + + /// Read the length of the value in a fast way, without decoding the entire value. + /// + /// `T` is required to implement `Codec::DecodeLength`. + /// + /// Note that `0` is returned as the default value if no encoded value exists at the given key. + /// Therefore, this function cannot be used as a sign of _existence_. use the `::exists()` + /// function for this purpose. + fn decode_len() -> Result where T: codec::DecodeLength, T: Len { + let key = Self::storage_value_final_key(); + + // attempt to get the length directly. + if let Some(k) = unhashed::get_raw(&key) { + ::len(&k).map_err(|e| e.what()) + } else { + let len = G::from_query_to_optional_value(G::from_optional_value_to_query(None)) + .map(|v| v.len()) + .unwrap_or(0); + + Ok(len) + } + } +} diff --git a/srml/support/src/storage/hashed/mod.rs b/srml/support/src/storage/hashed.rs similarity index 85% rename from srml/support/src/storage/hashed/mod.rs rename to srml/support/src/storage/hashed.rs index 5ca718df8c..c125cc3479 100644 --- a/srml/support/src/storage/hashed/mod.rs +++ b/srml/support/src/storage/hashed.rs @@ -16,12 +16,72 @@ //! Operation on runtime storage using hashed keys. -pub mod generator; use super::unhashed; use crate::rstd::prelude::*; use crate::rstd::borrow::Borrow; -use runtime_io::{self, twox_128}; use crate::codec::{Codec, Encode, Decode, KeyedVec}; +use runtime_io::{self, twox_64, twox_128, blake2_128, twox_256, blake2_256}; + +/// Hasher to use to hash keys to insert to storage. +pub trait StorageHasher: 'static { + type Output: AsRef<[u8]>; + fn hash(x: &[u8]) -> Self::Output; +} + +/// Hash storage keys with `concat(twox64(key), key)` +pub struct Twox64Concat; +impl StorageHasher for Twox64Concat { + type Output = Vec; + fn hash(x: &[u8]) -> Vec { + twox_64(x) + .into_iter() + .chain(x.into_iter()) + .cloned() + .collect::>() + } +} + +#[test] +fn test_twox_64_concat() { + let r = Twox64Concat::hash(b"foo"); + assert_eq!(r.split_at(8), (&twox_128(b"foo")[..8], &b"foo"[..])) +} + +/// Hash storage keys with blake2 128 +pub struct Blake2_128; +impl StorageHasher for Blake2_128 { + type Output = [u8; 16]; + fn hash(x: &[u8]) -> [u8; 16] { + blake2_128(x) + } +} + +/// Hash storage keys with blake2 256 +pub struct Blake2_256; +impl StorageHasher for Blake2_256 { + type Output = [u8; 32]; + fn hash(x: &[u8]) -> [u8; 32] { + blake2_256(x) + } +} + +/// Hash storage keys with twox 128 +pub struct Twox128; +impl StorageHasher for Twox128 { + type Output = [u8; 16]; + fn hash(x: &[u8]) -> [u8; 16] { + twox_128(x) + } +} + +/// Hash storage keys with twox 256 +pub struct Twox256; +impl StorageHasher for Twox256 { + type Output = [u8; 32]; + fn hash(x: &[u8]) -> [u8; 32] { + twox_256(x) + } +} /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. pub fn get(hash: &HashFn, key: &[u8]) -> Option diff --git a/srml/support/src/storage/hashed/generator.rs b/srml/support/src/storage/hashed/generator.rs deleted file mode 100644 index 27b459e3ff..0000000000 --- a/srml/support/src/storage/hashed/generator.rs +++ /dev/null @@ -1,419 +0,0 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Abstract storage to use on HashedStorage trait. Please refer to the -//! [top level docs](../../index.html) for more detailed documentation about storage traits and functions. - -use crate::codec::{self, Encode}; -use crate::rstd::{prelude::{Vec, Box}, iter::FromIterator}; -#[cfg(feature = "std")] -use crate::storage::unhashed::generator::UnhashedStorage; -use crate::traits::{StorageDefault, Len}; -use runtime_io::{twox_64, twox_128, blake2_128, twox_256, blake2_256}; - -pub trait StorageHasher: 'static { - type Output: AsRef<[u8]>; - fn hash(x: &[u8]) -> Self::Output; -} - -/// Hash storage keys with `concat(twox64(key), key)` -pub struct Twox64Concat; -impl StorageHasher for Twox64Concat { - type Output = Vec; - fn hash(x: &[u8]) -> Vec { - twox_64(x) - .into_iter() - .chain(x.into_iter()) - .cloned() - .collect::>() - } -} - -#[test] -fn test_twox_64_concat() { - let r = Twox64Concat::hash(b"foo"); - assert_eq!(r.split_at(8), (&twox_128(b"foo")[..8], &b"foo"[..])) -} - -/// Hash storage keys with blake2 128 -pub struct Blake2_128; -impl StorageHasher for Blake2_128 { - type Output = [u8; 16]; - fn hash(x: &[u8]) -> [u8; 16] { - blake2_128(x) - } -} - -/// Hash storage keys with blake2 256 -pub struct Blake2_256; -impl StorageHasher for Blake2_256 { - type Output = [u8; 32]; - fn hash(x: &[u8]) -> [u8; 32] { - blake2_256(x) - } -} - -/// Hash storage keys with twox 128 -pub struct Twox128; -impl StorageHasher for Twox128 { - type Output = [u8; 16]; - fn hash(x: &[u8]) -> [u8; 16] { - twox_128(x) - } -} - -/// Hash storage keys with twox 256 -pub struct Twox256; -impl StorageHasher for Twox256 { - type Output = [u8; 32]; - fn hash(x: &[u8]) -> [u8; 32] { - twox_256(x) - } -} - -/// Abstraction around storage. -pub trait HashedStorage { - /// true if the key exists in storage. - fn exists(&self, key: &[u8]) -> bool; - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. - fn get(&self, key: &[u8]) -> Option; - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. Will panic if - /// it's not there. - fn require(&self, key: &[u8]) -> T { - self.get(key).expect("Required values must be in storage") - } - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. The type's - /// default is returned if it's not there. - fn get_or_default(&self, key: &[u8]) -> T { - self.get(key).unwrap_or_default() - } - - /// Put a value in under a key. - fn put(&mut self, key: &[u8], val: &T); - - /// Remove the bytes of a key from storage. - fn kill(&mut self, key: &[u8]); - - /// Take a value from storage, deleting it after reading. - fn take(&mut self, key: &[u8]) -> Option { - let value = self.get(key); - self.kill(key); - value - } - - /// Take a value from storage, deleting it after reading. - fn take_or_panic(&mut self, key: &[u8]) -> T { - self.take(key).expect("Required values must be in storage") - } - - /// Take a value from storage, deleting it after reading. - fn take_or_default(&mut self, key: &[u8]) -> T { - self.take(key).unwrap_or_default() - } - - /// Get a Vec of bytes from storage. - fn get_raw(&self, key: &[u8]) -> Option>; - - /// Put a raw byte slice into storage. - fn put_raw(&mut self, key: &[u8], value: &[u8]); -} - -// We use a construct like this during when genesis storage is being built. -#[cfg(feature = "std")] -impl HashedStorage for sr_primitives::StorageOverlay { - fn exists(&self, key: &[u8]) -> bool { - UnhashedStorage::exists(self, &H::hash(key).as_ref()) - } - - fn get(&self, key: &[u8]) -> Option { - UnhashedStorage::get(self, &H::hash(key).as_ref()) - } - - fn put(&mut self, key: &[u8], val: &T) { - UnhashedStorage::put(self, &H::hash(key).as_ref(), val) - } - - fn kill(&mut self, key: &[u8]) { - UnhashedStorage::kill(self, &H::hash(key).as_ref()) - } - - fn get_raw(&self, key: &[u8]) -> Option> { - UnhashedStorage::get_raw(self, &H::hash(key).as_ref()) - } - - fn put_raw(&mut self, key: &[u8], value: &[u8]) { - UnhashedStorage::put_raw(self, &H::hash(key).as_ref(), value) - } -} - -/// A strongly-typed value kept in storage. -pub trait StorageValue { - /// The type that get/take returns. - type Query; - /// Something that can provide the default value of this storage type. - type Default: StorageDefault; - - - /// Get the storage key. - fn key() -> &'static [u8]; - - /// true if the value is defined in storage. - fn exists>(storage: &S) -> bool { - storage.exists(Self::key()) - } - - /// Load the value from the provided storage instance. - fn get>(storage: &S) -> Self::Query; - - /// Take a value from storage, removing it afterwards. - fn take>(storage: &mut S) -> Self::Query; - - /// Store a value under this key into the provided storage instance. - fn put>(val: &T, storage: &mut S) { - storage.put(Self::key(), val) - } - - /// Store a value under this key into the provided storage instance; this can take any reference - /// type that derefs to `T` (and has `Encode` implemented). - /// Store a value under this key into the provided storage instance. - fn put_ref>(val: &Arg, storage: &mut S) where T: AsRef { - val.using_encoded(|b| storage.put_raw(Self::key(), b)) - } - - /// Mutate this value - fn mutate R, S: HashedStorage>(f: F, storage: &mut S) -> R; - - /// Clear the storage value. - fn kill>(storage: &mut S) { - storage.kill(Self::key()) - } - - /// Append the given items to the value in the storage. - /// - /// `T` is required to implement `codec::EncodeAppend`. - fn append<'a, S, I, R>( - items: R, - storage: &mut S, - ) -> Result<(), &'static str> where - S: HashedStorage, - I: 'a + codec::Encode, - T: codec::EncodeAppend, - R: IntoIterator, - R::IntoIter: ExactSizeIterator, - { - let new_val = ::append( - // if the key exists, directly append to it. - storage.get_raw(Self::key()).unwrap_or_else(|| { - // otherwise, try and read a proper __provided__ default. - Self::Default::default().map(|v| v.encode()) - // or just use the Rust's `default()` value. - .unwrap_or_default() - }), - items, - ).map_err(|_| "Could not append given item")?; - storage.put_raw(Self::key(), &new_val); - Ok(()) - } - - /// Safely append the given items to the value in the storage. If a codec error occurs, then the - /// old (presumably corrupt) value is replaced with the given `items`. - /// - /// `T` is required to implement `codec::EncodeAppend`. - fn append_or_put<'a, S, I, R>( - items: R, - storage: &mut S, - ) where - S: HashedStorage, - I: 'a + codec::Encode + Clone, - T: codec::EncodeAppend + FromIterator, - R: IntoIterator + Clone, - R::IntoIter: ExactSizeIterator, - { - Self::append(items.clone(), storage) - .unwrap_or_else(|_| Self::put(&items.into_iter().cloned().collect(), storage)); - } - - /// Read the length of the value in a fast way, without decoding the entire value. - /// - /// `T` is required to implement `Codec::DecodeLength`. - /// - /// Note that `0` is returned as the default value if no encoded value exists at the given key. - /// Therefore, this function cannot be used as a sign of _existence_. use the `::exists()` - /// function for this purpose. - fn decode_len>(storage: &mut S) -> Result - where T: codec::DecodeLength, T: Len - { - // attempt to get the length directly. - if let Some(k) = storage.get_raw(Self::key()) { - ::len(&k).map_err(|e| e.what()) - } else { - Ok(Self::Default::default().map(|v| v.len()).unwrap_or(0)) - } - } -} - -/// A strongly-typed map in storage. -pub trait StorageMap { - /// The type that get/take returns. - type Query; - /// Hasher type - type Hasher: StorageHasher; - /// Something that can provide the default value of this storage type. - type Default: StorageDefault; - - /// Get the prefix key in storage. - fn prefix() -> &'static [u8]; - - /// Get the storage key used to fetch a value corresponding to a specific key. - fn key_for(x: &K) -> Vec; - - /// true if the value is defined in storage. - fn exists>(key: &K, storage: &S) -> bool { - storage.exists(&Self::key_for(key)[..]) - } - - /// Load the value associated with the given key from the map. - fn get>(key: &K, storage: &S) -> Self::Query; - - /// Take the value under a key. - fn take>(key: &K, storage: &mut S) -> Self::Query; - - /// Swap the values of two keys. - fn swap>(key1: &K, key2: &K, storage: &mut S) { - let k1 = Self::key_for(key1); - let k2 = Self::key_for(key2); - let v1 = storage.get_raw(&k1[..]); - if let Some(val) = storage.get_raw(&k2[..]) { - storage.put_raw(&k1[..], &val[..]); - } else { - storage.kill(&k1[..]) - } - if let Some(val) = v1 { - storage.put_raw(&k2[..], &val[..]); - } else { - storage.kill(&k2[..]) - } - } - - /// Store a value to be associated with the given key from the map. - fn insert>(key: &K, val: &V, storage: &mut S) { - storage.put(&Self::key_for(key)[..], val); - } - - /// Store a value under this key into the provided storage instance; this can take any reference - /// type that derefs to `T` (and has `Encode` implemented). - /// Store a value under this key into the provided storage instance. - fn insert_ref>( - key: &K, - val: &Arg, - storage: &mut S - ) where V: AsRef { - val.using_encoded(|b| storage.put_raw(&Self::key_for(key)[..], b)) - } - - /// Remove the value under a key. - fn remove>(key: &K, storage: &mut S) { - storage.kill(&Self::key_for(key)[..]); - } - - /// Mutate the value under a key. - fn mutate R, S: HashedStorage>(key: &K, f: F, storage: &mut S) -> R; -} - -/// A `StorageMap` with enumerable entries. -pub trait EnumerableStorageMap: StorageMap { - /// Return current head element. - fn head>(storage: &S) -> Option; - - /// Enumerate all elements in the map. - fn enumerate<'a, S: HashedStorage>( - storage: &'a S - ) -> Box + 'a> where K: 'a, V: 'a; -} - -/// A `StorageMap` with appendable entries. -pub trait AppendableStorageMap: StorageMap { - /// Append the given items to the value in the storage. - /// - /// `V` is required to implement `codec::EncodeAppend`. - fn append<'a, S, I, R>( - key : &K, - items: R, - storage: &mut S, - ) -> Result<(), &'static str> where - S: HashedStorage, - I: 'a + codec::Encode, - V: codec::EncodeAppend, - R: IntoIterator + Clone, - R::IntoIter: ExactSizeIterator, - { - let k = Self::key_for(key); - let new_val = ::append( - storage.get_raw(&k[..]).unwrap_or_else(|| { - // otherwise, try and read a proper __provided__ default. - Self::Default::default().map(|v| v.encode()) - // or just use the default value. - .unwrap_or_default() - }), - items, - ).map_err(|_| "Could not append given item")?; - storage.put_raw(&k[..], &new_val); - Ok(()) - } - - /// Safely append the given items to the value in the storage. If a codec error occurs, then the - /// old (presumably corrupt) value is replaced with the given `items`. - /// - /// `T` is required to implement `codec::EncodeAppend`. - fn append_or_insert<'a, S, I, R>( - key : &K, - items: R, - storage: &mut S, - ) where - S: HashedStorage, - I: 'a + codec::Encode + Clone, - V: codec::EncodeAppend + crate::rstd::iter::FromIterator, - R: IntoIterator + Clone, - R::IntoIter: ExactSizeIterator, - { - Self::append(key, items.clone(), storage) - .unwrap_or_else(|_| Self::insert(key, &items.into_iter().cloned().collect(), storage)); - } -} - -/// A storage map with a decodable length. -pub trait DecodeLengthStorageMap: StorageMap { - /// Read the length of the value in a fast way, without decoding the entire value. - /// - /// `T` is required to implement `Codec::DecodeLength`. - /// - /// Note that `0` is returned as the default value if no encoded value exists at the given key. - /// Therefore, this function cannot be used as a sign of _existence_. use the `::exists()` - /// function for this purpose. - fn decode_len>(key: &K, storage: &mut S) -> Result - where V: codec::DecodeLength, V: Len - { - let k = Self::key_for(key); - if let Some(v) = storage.get_raw(&k[..]) { - ::len(&v).map_err(|e| e.what()) - } else { - Ok(Self::Default::default().map(|v| v.len()).unwrap_or(0)) - } - } -} diff --git a/srml/support/src/storage/mod.rs b/srml/support/src/storage/mod.rs index aa3faee878..1524cd234a 100644 --- a/srml/support/src/storage/mod.rs +++ b/srml/support/src/storage/mod.rs @@ -19,100 +19,22 @@ use crate::rstd::prelude::*; use crate::rstd::{borrow::Borrow, iter::FromIterator}; use codec::{Codec, Encode, Decode, KeyedVec, EncodeAppend}; -use hashed::generator::{HashedStorage, StorageHasher}; -use unhashed::generator::UnhashedStorage; -use crate::traits::{StorageDefault, Len}; +use crate::traits::Len; #[macro_use] pub mod storage_items; pub mod unhashed; pub mod hashed; - -/// The underlying runtime storage. -pub struct RuntimeStorage; - -impl HashedStorage for RuntimeStorage { - fn exists(&self, key: &[u8]) -> bool { - hashed::exists(&H::hash, key) - } - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. - fn get(&self, key: &[u8]) -> Option { - hashed::get(&H::hash, key) - } - - /// Put a value in under a key. - fn put(&mut self, key: &[u8], val: &T) { - hashed::put(&H::hash, key, val) - } - - /// Remove the bytes of a key from storage. - fn kill(&mut self, key: &[u8]) { - hashed::kill(&H::hash, key) - } - - /// Take a value from storage, deleting it after reading. - fn take(&mut self, key: &[u8]) -> Option { - hashed::take(&H::hash, key) - } - - fn get_raw(&self, key: &[u8]) -> Option> { - hashed::get_raw(&H::hash, key) - } - - fn put_raw(&mut self, key: &[u8], value: &[u8]) { - hashed::put_raw(&H::hash, key, value) - } -} - -impl UnhashedStorage for RuntimeStorage { - fn exists(&self, key: &[u8]) -> bool { - unhashed::exists(key) - } - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. - fn get(&self, key: &[u8]) -> Option { - unhashed::get(key) - } - - /// Put a value in under a key. - fn put(&mut self, key: &[u8], val: &T) { - unhashed::put(key, val) - } - - /// Remove the bytes of a key from storage. - fn kill(&mut self, key: &[u8]) { - unhashed::kill(key) - } - - /// Remove the bytes of a key from storage. - fn kill_prefix(&mut self, prefix: &[u8]) { - unhashed::kill_prefix(prefix) - } - - /// Take a value from storage, deleting it after reading. - fn take(&mut self, key: &[u8]) -> Option { - unhashed::take(key) - } - - fn get_raw(&self, key: &[u8]) -> Option> { - unhashed::get_raw(key) - } - - fn put_raw(&mut self, key: &[u8], value: &[u8]) { - unhashed::put_raw(key, value) - } -} +pub mod child; +pub mod generator; /// A trait for working with macro-generated storage values under the substrate storage API. pub trait StorageValue { /// The type that get/take return. type Query; - /// Something that can provide the default value of this storage type. - type Default: StorageDefault; /// Get the storage key. - fn key() -> &'static [u8]; + fn hashed_key() -> [u8; 16]; /// Does the value (explicitly) exist in storage? fn exists() -> bool; @@ -166,72 +88,16 @@ pub trait StorageValue { /// /// `T` is required to implement `Codec::DecodeLength`. fn decode_len() -> Result - where T: codec::DecodeLength, T: Len; -} - -impl StorageValue for U where U: hashed::generator::StorageValue { - type Query = U::Query; - type Default = U::Default; - - fn key() -> &'static [u8] { - >::key() - } - fn exists() -> bool { - U::exists(&RuntimeStorage) - } - fn get() -> Self::Query { - U::get(&RuntimeStorage) - } - fn put>(val: Arg) { - U::put(val.borrow(), &mut RuntimeStorage) - } - fn put_ref(val: &Arg) where T: AsRef { - U::put_ref(val, &mut RuntimeStorage) - } - fn mutate R>(f: F) -> R { - U::mutate(f, &mut RuntimeStorage) - } - fn kill() { - U::kill(&mut RuntimeStorage) - } - fn take() -> Self::Query { - U::take(&mut RuntimeStorage) - } - fn append<'a, I, R>(items: R) -> Result<(), &'static str> where - I: 'a + Encode, - T: EncodeAppend, - R: IntoIterator, - R::IntoIter: ExactSizeIterator, - { - U::append(items, &mut RuntimeStorage) - } - fn append_or_put<'a, I, R>(items: R) where - I: 'a + Encode + Clone, - T: EncodeAppend + FromIterator, - R: IntoIterator + Clone, - R::IntoIter: ExactSizeIterator, - { - U::append_or_put(items, &mut RuntimeStorage) - } - fn decode_len() -> Result - where T: codec::DecodeLength, T: Len - { - U::decode_len(&mut RuntimeStorage) - } + where T: codec::DecodeLength + Len; } /// A strongly-typed map in storage. pub trait StorageMap { /// The type that get/take return. type Query; - /// Something that can provide the default value of this storage type. - type Default: StorageDefault; - - /// Get the prefix key in storage. - fn prefix() -> &'static [u8]; /// Get the storage key used to fetch a value corresponding to a specific key. - fn key_for>(key: KeyArg) -> Vec; + fn hashed_key_for>(key: KeyArg) -> Vec; /// Does the value (explicitly) exist in storage? fn exists>(key: KeyArg) -> bool; @@ -257,190 +123,101 @@ pub trait StorageMap { /// Take the value under a key. fn take>(key: KeyArg) -> Self::Query; -} - -impl StorageMap for U where U: hashed::generator::StorageMap { - type Query = U::Query; - type Default = U::Default; - - fn prefix() -> &'static [u8] { - >::prefix() - } - - fn key_for>(key: KeyArg) -> Vec { - >::key_for(key.borrow()) - } - - fn exists>(key: KeyArg) -> bool { - U::exists(key.borrow(), &RuntimeStorage) - } - fn get>(key: KeyArg) -> Self::Query { - U::get(key.borrow(), &RuntimeStorage) - } - - fn swap, KeyArg2: Borrow>(key1: KeyArg1, key2: KeyArg2) { - U::swap(key1.borrow(), key2.borrow(), &mut RuntimeStorage) - } - - fn insert, ValArg: Borrow>(key: KeyArg, val: ValArg) { - U::insert(key.borrow(), val.borrow(), &mut RuntimeStorage) - } - - fn insert_ref, ValArg: ?Sized + Encode>(key: KeyArg, val: &ValArg) where V: AsRef { - U::insert_ref(key.borrow(), val, &mut RuntimeStorage) - } - - fn remove>(key: KeyArg) { - U::remove(key.borrow(), &mut RuntimeStorage) - } - - fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R { - U::mutate(key.borrow(), f, &mut RuntimeStorage) - } - - fn take>(key: KeyArg) -> Self::Query { - U::take(key.borrow(), &mut RuntimeStorage) - } -} - -/// A storage map with values that can be appended to. -pub trait AppendableStorageMap: StorageMap { - /// Append the given item to the value in the storage. + /// Append the given items to the value in the storage. /// - /// `T` is required to implement `codec::EncodeAppend`. - fn append<'a, KeyArg, I, R>( - key: KeyArg, - items: R, - ) -> Result<(), &'static str> where + /// `V` is required to implement `codec::EncodeAppend`. + fn append<'a, I, R, KeyArg>(key: KeyArg, items: R) -> Result<(), &'static str> + where KeyArg: Borrow, I: 'a + codec::Encode, - V: EncodeAppend, + V: codec::EncodeAppend, R: IntoIterator + Clone, R::IntoIter: ExactSizeIterator; - /// Append the given items to the value in the storage. + /// Safely append the given items to the value in the storage. If a codec error occurs, then the + /// old (presumably corrupt) value is replaced with the given `items`. /// /// `T` is required to implement `codec::EncodeAppend`. - /// - /// Upon any failure, it replaces `items` as the new value (assuming that the previous stored - /// data is simply corrupt and no longer usable). - /// - /// WARNING: use with care; if your use-case is not _exactly_ as what this function is doing, - /// you should use append and sensibly handle failure within the runtime code if it happens. - fn append_or_insert<'a, KeyArg, I, R>( - key: KeyArg, - items: R, - ) where + fn append_or_insert<'a, I, R, KeyArg>(key: KeyArg, items: R) + where KeyArg: Borrow, I: 'a + codec::Encode + Clone, - V: codec::EncodeAppend + FromIterator, + V: codec::EncodeAppend + crate::rstd::iter::FromIterator, R: IntoIterator + Clone, R::IntoIter: ExactSizeIterator; -} - -impl AppendableStorageMap for U - where U: hashed::generator::AppendableStorageMap -{ - fn append<'a, KeyArg, I, R>( - key: KeyArg, - items: R, - ) -> Result<(), &'static str> where - KeyArg: Borrow, - I: 'a + codec::Encode, - V: EncodeAppend, - R: IntoIterator + Clone, - R::IntoIter: ExactSizeIterator, - { - U::append(key.borrow(), items, &mut RuntimeStorage) - } - - fn append_or_insert<'a, KeyArg, I, R>( - key: KeyArg, - items: R, - ) where - KeyArg: Borrow, - I: 'a + codec::Encode + Clone, - V: codec::EncodeAppend + FromIterator, - R: IntoIterator + Clone, - R::IntoIter: ExactSizeIterator, - { - U::append_or_insert(key.borrow(), items, &mut RuntimeStorage) - } -} -/// A storage map with a decodable length. -pub trait DecodeLengthStorageMap: StorageMap { /// Read the length of the value in a fast way, without decoding the entire value. /// /// `T` is required to implement `Codec::DecodeLength`. /// - /// Has the same logic as [`StorageValue`](trait.StorageValue.html). + /// Note that `0` is returned as the default value if no encoded value exists at the given key. + /// Therefore, this function cannot be used as a sign of _existence_. use the `::exists()` + /// function for this purpose. fn decode_len>(key: KeyArg) -> Result - where V: codec::DecodeLength, V: Len; + where V: codec::DecodeLength + Len; } -impl DecodeLengthStorageMap for U - where U: hashed::generator::DecodeLengthStorageMap -{ - fn decode_len>(key: KeyArg) -> Result - where V: codec::DecodeLength, V: Len - { - U::decode_len(key.borrow(), &mut RuntimeStorage) - } -} - -/// A storage map that can be enumerated. +/// A strongly-typed linked map in storage. /// -/// Primarily useful for off-chain computations. -/// Runtime implementors should avoid enumerating storage entries on-chain. -pub trait EnumerableStorageMap: StorageMap { +/// Similar to `StorageMap` but allows to enumerate other elements and doesn't implement append. +pub trait StorageLinkedMap { + /// The type that get/take return. + type Query; + + /// The type that iterates over all `(key, value)`. + type Enumerator: Iterator; + + /// Does the value (explicitly) exist in storage? + fn exists>(key: KeyArg) -> bool; + + /// Load the value associated with the given key from the map. + fn get>(key: KeyArg) -> Self::Query; + + /// Swap the values of two keys. + fn swap, KeyArg2: Borrow>(key1: KeyArg1, key2: KeyArg2); + + /// Store a value to be associated with the given key from the map. + fn insert, ValArg: Borrow>(key: KeyArg, val: ValArg); + + /// Store a value under this key into the provided storage instance; this can take any reference + /// type that derefs to `T` (and has `Encode` implemented). + fn insert_ref, ValArg: ?Sized + Encode>(key: KeyArg, val: &ValArg) where V: AsRef; + + /// Remove the value under a key. + fn remove>(key: KeyArg); + + /// Mutate the value under a key. + fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R; + + /// Take the value under a key. + fn take>(key: KeyArg) -> Self::Query; + /// Return current head element. fn head() -> Option; /// Enumerate all elements in the map. - fn enumerate() -> Box> where K: 'static, V: 'static; -} + fn enumerate() -> Self::Enumerator; -impl EnumerableStorageMap for U - where U: hashed::generator::EnumerableStorageMap -{ - fn head() -> Option { - >::head(&RuntimeStorage) - } - - fn enumerate() -> Box> where K: 'static, V: 'static { - >::enumerate(&RuntimeStorage) - } + /// Read the length of the value in a fast way, without decoding the entire value. + /// + /// `T` is required to implement `Codec::DecodeLength`. + /// + /// Note that `0` is returned as the default value if no encoded value exists at the given key. + /// Therefore, this function cannot be used as a sign of _existence_. use the `::exists()` + /// function for this purpose. + fn decode_len>(key: KeyArg) -> Result + where V: codec::DecodeLength + Len; } /// An implementation of a map with a two keys. /// /// It provides an important ability to efficiently remove all entries /// that have a common first key. -/// -/// # Mapping of keys to a storage path -/// -/// The storage key (i.e. the key under which the `Value` will be stored) is created from two parts. -/// The first part is a hash of a concatenation of the `PREFIX` and `Key1`. And the second part -/// is a hash of a `Key2`. -/// -/// /!\ be careful while choosing the Hash, indeed malicious could craft second keys to lower the trie. pub trait StorageDoubleMap { /// The type that get/take returns. type Query; - fn prefix() -> &'static [u8]; - - fn key_for(k1: &KArg1, k2: &KArg2) -> Vec - where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode; - - fn prefix_for(k1: &KArg1) -> Vec where KArg1: ?Sized + Encode, K1: Borrow; - fn exists(k1: &KArg1, k2: &KArg2) -> bool where K1: Borrow, @@ -501,204 +278,3 @@ pub trait StorageDoubleMap { I: codec::Encode, V: EncodeAppend; } - -impl StorageDoubleMap for U -where - U: unhashed::generator::StorageDoubleMap -{ - type Query = U::Query; - - fn prefix() -> &'static [u8] { - >::prefix() - } - - fn key_for(k1: &KArg1, k2: &KArg2) -> Vec - where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - { - >::key_for(k1, k2) - } - - fn prefix_for(k1: &KArg1) -> Vec where KArg1: ?Sized + Encode, K1: Borrow { - >::prefix_for(k1) - } - - fn exists(k1: &KArg1, k2: &KArg2) -> bool - where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - { - U::exists(k1, k2, &RuntimeStorage) - } - - fn get(k1: &KArg1, k2: &KArg2) -> Self::Query - where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - { - U::get(k1, k2, &RuntimeStorage) - } - - fn take(k1: &KArg1, k2: &KArg2) -> Self::Query - where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - { - U::take(k1.borrow(), k2.borrow(), &mut RuntimeStorage) - } - - fn insert(k1: &KArg1, k2: &KArg2, val: &VArg) - where - K1: Borrow, - K2: Borrow, - V: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - VArg: ?Sized + Encode, - { - U::insert(k1, k2, val, &mut RuntimeStorage) - } - - fn remove(k1: &KArg1, k2: &KArg2) - where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - { - U::remove(k1, k2, &mut RuntimeStorage) - } - - fn remove_prefix(k1: &KArg1) where KArg1: ?Sized + Encode, K1: Borrow { - U::remove_prefix(k1, &mut RuntimeStorage) - } - - fn mutate(k1: &KArg1, k2: &KArg2, f: F) -> R - where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - F: FnOnce(&mut Self::Query) -> R - { - U::mutate(k1, k2, f, &mut RuntimeStorage) - } - - fn append( - k1: &KArg1, - k2: &KArg2, - items: &[I], - ) -> Result<(), &'static str> - where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - I: codec::Encode, - V: EncodeAppend, - { - U::append(k1, k2, items, &mut RuntimeStorage) - } -} - -/// child storage NOTE could replace unhashed by having only one kind of storage (root being null storage -/// key (storage_key can become Option<&[u8]>). -/// This module is a currently only a variant of unhashed with additional `storage_key`. -/// Note that `storage_key` must be unique and strong (strong in the sense of being long enough to -/// avoid collision from a resistant hash function (which unique implies)). -pub mod child { - use super::{Codec, Decode, Vec}; - - /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. - pub fn get(storage_key: &[u8], key: &[u8]) -> Option { - runtime_io::child_storage(storage_key, key).map(|v| { - Decode::decode(&mut &v[..]).expect("storage is not null, therefore must be a valid type") - }) - } - - /// Return the value of the item in storage under `key`, or the type's default if there is no - /// explicit entry. - pub fn get_or_default(storage_key: &[u8], key: &[u8]) -> T { - get(storage_key, key).unwrap_or_else(Default::default) - } - - /// Return the value of the item in storage under `key`, or `default_value` if there is no - /// explicit entry. - pub fn get_or(storage_key: &[u8], key: &[u8], default_value: T) -> T { - get(storage_key, key).unwrap_or(default_value) - } - - /// Return the value of the item in storage under `key`, or `default_value()` if there is no - /// explicit entry. - pub fn get_or_else T>(storage_key: &[u8], key: &[u8], default_value: F) -> T { - get(storage_key, key).unwrap_or_else(default_value) - } - - /// Put `value` in storage under `key`. - pub fn put(storage_key: &[u8], key: &[u8], value: &T) { - value.using_encoded(|slice| runtime_io::set_child_storage(storage_key, key, slice)); - } - - /// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise. - pub fn take(storage_key: &[u8], key: &[u8]) -> Option { - let r = get(storage_key, key); - if r.is_some() { - kill(storage_key, key); - } - r - } - - /// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage, - /// the default for its type. - pub fn take_or_default(storage_key: &[u8], key: &[u8]) -> T { - take(storage_key, key).unwrap_or_else(Default::default) - } - - /// Return the value of the item in storage under `key`, or `default_value` if there is no - /// explicit entry. Ensure there is no explicit entry on return. - pub fn take_or(storage_key: &[u8],key: &[u8], default_value: T) -> T { - take(storage_key, key).unwrap_or(default_value) - } - - /// Return the value of the item in storage under `key`, or `default_value()` if there is no - /// explicit entry. Ensure there is no explicit entry on return. - pub fn take_or_else T>(storage_key: &[u8], key: &[u8], default_value: F) -> T { - take(storage_key, key).unwrap_or_else(default_value) - } - - /// Check to see if `key` has an explicit entry in storage. - pub fn exists(storage_key: &[u8], key: &[u8]) -> bool { - runtime_io::read_child_storage(storage_key, key, &mut [0;0][..], 0).is_some() - } - - /// Remove all `storage_key` key/values - pub fn kill_storage(storage_key: &[u8]) { - runtime_io::kill_child_storage(storage_key) - } - - /// Ensure `key` has no explicit entry in storage. - pub fn kill(storage_key: &[u8], key: &[u8]) { - runtime_io::clear_child_storage(storage_key, key); - } - - /// Get a Vec of bytes from storage. - pub fn get_raw(storage_key: &[u8], key: &[u8]) -> Option> { - runtime_io::child_storage(storage_key, key) - } - - /// Put a raw byte slice into storage. - pub fn put_raw(storage_key: &[u8], key: &[u8], value: &[u8]) { - runtime_io::set_child_storage(storage_key, key, value) - } - - pub use super::unhashed::StorageVec; -} diff --git a/srml/support/src/storage/storage_items.rs b/srml/support/src/storage/storage_items.rs index a2a5c3229f..ac120c31e7 100644 --- a/srml/support/src/storage/storage_items.rs +++ b/srml/support/src/storage/storage_items.rs @@ -50,109 +50,127 @@ pub use crate::rstd::marker::PhantomData; #[doc(hidden)] pub use crate::rstd::boxed::Box; +#[doc(hidden)] +pub fn id(t: T) -> T { + t +} + +#[doc(hidden)] +pub use Some; + +#[doc(hidden)] +pub fn unwrap_or_default(t: Option) -> T { + t.unwrap_or_else(|| Default::default()) +} + +#[doc(hidden)] +pub fn require(t: Option) -> T { + t.expect("Required values must be in storage") +} + // FIXME #1466 Remove this in favor of `decl_storage` macro. /// Declares strongly-typed wrappers around codec-compatible types in storage. #[macro_export] macro_rules! storage_items { // simple values ($name:ident : $key:expr => $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!(() () (OPTION_TYPE Option<$ty>) (get) (take) $name: $key => $ty); + $crate::__storage_items_internal!(() () (OPTION_TYPE Option<$ty>) (id) (id) $name: $key => $ty); storage_items!($($t)*); }; (pub $name:ident : $key:expr => $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) () (OPTION_TYPE Option<$ty>) (get) (take) $name: $key => $ty); + $crate::__storage_items_internal!((pub) () (OPTION_TYPE Option<$ty>) (id) (id) $name: $key => $ty); storage_items!($($t)*); }; ($name:ident : $key:expr => default $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!(() () (RAW_TYPE $ty) (get_or_default) (take_or_default) $name: $key => $ty); + $crate::__storage_items_internal!(() () (RAW_TYPE $ty) (unwrap_or_default) (Some) $name: $key => $ty); storage_items!($($t)*); }; (pub $name:ident : $key:expr => default $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) () (RAW_TYPE $ty) (get_or_default) (take_or_default) $name: $key => $ty); + $crate::__storage_items_internal!((pub) () (RAW_TYPE $ty) (unwrap_or_default) (Some) $name: $key => $ty); storage_items!($($t)*); }; ($name:ident : $key:expr => required $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!(() () (RAW_TYPE $ty) (require) (take_or_panic) $name: $key => $ty); + $crate::__storage_items_internal!(() () (RAW_TYPE $ty) (require) (Some) $name: $key => $ty); storage_items!($($t)*); }; (pub $name:ident : $key:expr => required $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) () (RAW_TYPE $ty) (require) (take_or_panic) $name: $key => $ty); + $crate::__storage_items_internal!((pub) () (RAW_TYPE $ty) (require) (Some) $name: $key => $ty); storage_items!($($t)*); }; ($name:ident get($getfn:ident) : $key:expr => $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!(() ($getfn) (OPTION_TYPE Option<$ty>) (get) (take) $name: $key => $ty); + $crate::__storage_items_internal!(() ($getfn) (OPTION_TYPE Option<$ty>) (id) (id) $name: $key => $ty); storage_items!($($t)*); }; (pub $name:ident get($getfn:ident) : $key:expr => $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) ($getfn) (OPTION_TYPE Option<$ty>) (get) (take) $name: $key => $ty); + $crate::__storage_items_internal!((pub) ($getfn) (OPTION_TYPE Option<$ty>) (id) (id) $name: $key => $ty); storage_items!($($t)*); }; ($name:ident get($getfn:ident) : $key:expr => default $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!(() ($getfn) (RAW_TYPE $ty) (get_or_default) (take_or_default) $name: $key => $ty); + $crate::__storage_items_internal!(() ($getfn) (RAW_TYPE $ty) (unwrap_or_default) (Some) $name: $key => $ty); storage_items!($($t)*); }; (pub $name:ident get($getfn:ident) : $key:expr => default $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) ($getfn) (RAW_TYPE $ty) (get_or_default) (take_or_default) $name: $key => $ty); + $crate::__storage_items_internal!((pub) ($getfn) (RAW_TYPE $ty) (unwrap_or_default) (Some) $name: $key => $ty); storage_items!($($t)*); }; ($name:ident get($getfn:ident) : $key:expr => required $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!(() ($getfn) (RAW_TYPE $ty) (require) (take_or_panic) $name: $key => $ty); + $crate::__storage_items_internal!(() ($getfn) (RAW_TYPE $ty) (require) (Some) $name: $key => $ty); storage_items!($($t)*); }; (pub $name:ident get($getfn:ident) : $key:expr => required $ty:ty; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) ($getfn) (RAW_TYPE $ty) (require) (take_or_panic) $name: $key => $ty); + $crate::__storage_items_internal!((pub) ($getfn) (RAW_TYPE $ty) (require) (Some) $name: $key => $ty); storage_items!($($t)*); }; // maps ($name:ident : $prefix:expr => map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!(() () (OPTION_TYPE Option<$ty>) (get) (take) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!(() () (OPTION_TYPE Option<$ty>) (id) (id) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; (pub $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) () (OPTION_TYPE Option<$ty>) (get) (take) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!((pub) () (OPTION_TYPE Option<$ty>) (id) (id) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; ($name:ident : $prefix:expr => default map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!(() () (RAW_TYPE $ty) (get_or_default) (take_or_default) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!(() () (RAW_TYPE $ty) (unwrap_or_default) (Some) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; (pub $name:ident : $prefix:expr => default map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) () (RAW_TYPE $ty) (get_or_default) (take_or_default) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!((pub) () (RAW_TYPE $ty) (unwrap_or_default) (Some) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; ($name:ident : $prefix:expr => required map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!(() () (RAW_TYPE $ty) (require) (take_or_panic) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!(() () (RAW_TYPE $ty) (require) (Some) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; (pub $name:ident : $prefix:expr => required map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) () (RAW_TYPE $ty) (require) (take_or_panic) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!((pub) () (RAW_TYPE $ty) (require) (Some) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; ($name:ident get($getfn:ident) : $prefix:expr => map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!(() ($getfn) (OPTION_TYPE Option<$ty>) (get) (take) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!(() ($getfn) (OPTION_TYPE Option<$ty>) (id) (id) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; (pub $name:ident get($getfn:ident) : $prefix:expr => map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) ($getfn) (OPTION_TYPE Option<$ty>) (get) (take) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!((pub) ($getfn) (OPTION_TYPE Option<$ty>) (id) (id) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; ($name:ident get($getfn:ident) : $prefix:expr => default map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!(() ($getfn) (RAW_TYPE $ty) (get_or_default) (take_or_default) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!(() ($getfn) (RAW_TYPE $ty) (unwrap_or_default) (Some) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; (pub $name:ident get($getfn:ident) : $prefix:expr => default map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) ($getfn) (RAW_TYPE $ty) (get_or_default) (take_or_default) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!((pub) ($getfn) (RAW_TYPE $ty) (unwrap_or_default) (Some) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; ($name:ident get($getfn:ident) : $prefix:expr => required map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!(() ($getfn) (RAW_TYPE $ty) (require) (take_or_panic) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!(() ($getfn) (RAW_TYPE $ty) (require) (Some) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; (pub $name:ident get($getfn:ident) : $prefix:expr => required map [$kty:ty => $ty:ty]; $($t:tt)*) => { - $crate::__storage_items_internal!((pub) ($getfn) (RAW_TYPE $ty) (require) (take_or_panic) $name: $prefix => map [$kty => $ty]); + $crate::__storage_items_internal!((pub) ($getfn) (RAW_TYPE $ty) (require) (Some) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; @@ -163,110 +181,53 @@ macro_rules! storage_items { #[doc(hidden)] macro_rules! __storage_items_internal { // generator for values. - (($($vis:tt)*) ($get_fn:ident) ($wraptype:ident $gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $key:expr => $ty:ty) => { - $crate::__storage_items_internal!{ ($($vis)*) () ($wraptype $gettype) ($getter) ($taker) $name : $key => $ty } - pub fn $get_fn() -> $gettype { <$name as $crate::storage::hashed::generator::StorageValue<$ty>> :: get(&$crate::storage::RuntimeStorage) } + (($($vis:tt)*) ($get_fn:ident) ($wraptype:ident $gettype:ty) ($into_query:ident) ($into_opt_val:ident) $name:ident : $key:expr => $ty:ty) => { + $crate::__storage_items_internal!{ ($($vis)*) () ($wraptype $gettype) ($into_query) ($into_opt_val) $name : $key => $ty } + pub fn $get_fn() -> $gettype { <$name as $crate::storage::StorageValue<$ty>> :: get() } }; - (($($vis:tt)*) () ($wraptype:ident $gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $key:expr => $ty:ty) => { + (($($vis:tt)*) () ($wraptype:ident $gettype:ty) ($into_query:ident) ($into_opt_val:ident) $name:ident : $key:expr => $ty:ty) => { $($vis)* struct $name; - impl $crate::storage::hashed::generator::StorageValue<$ty> for $name { + impl $crate::storage::generator::StorageValue<$ty> for $name { type Query = $gettype; - type Default = (); - /// Get the storage key. - fn key() -> &'static [u8] { + fn unhashed_key() -> &'static [u8] { $key } - /// Load the value from the provided storage instance. - fn get>(storage: &S) -> Self::Query { - storage.$getter($key) + fn from_optional_value_to_query(v: Option<$ty>) -> Self::Query { + $crate::storage::storage_items::$into_query(v) } - /// Take a value from storage, removing it afterwards. - fn take>(storage: &mut S) -> Self::Query { - storage.$taker($key) - } - - /// Mutate this value. - fn mutate R, S: $crate::HashedStorage<$crate::Twox128>>(f: F, storage: &mut S) -> R { - let mut val = >::get(storage); - - let ret = f(&mut val); - - $crate::__handle_wrap_internal!($wraptype { - // raw type case - >::put(&val, storage) - } { - // Option<> type case - match val { - Some(ref val) => >::put(&val, storage), - None => >::kill(storage), - } - }); - - ret + fn from_query_to_optional_value(v: Self::Query) -> Option<$ty> { + $crate::storage::storage_items::$into_opt_val(v) } } }; // generator for maps. - (($($vis:tt)*) ($get_fn:ident) ($wraptype:ident $gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => { - $crate::__storage_items_internal!{ ($($vis)*) () ($wraptype $gettype) ($getter) ($taker) $name : $prefix => map [$kty => $ty] } - pub fn $get_fn>(key: K) -> $gettype { - <$name as $crate::storage::hashed::generator::StorageMap<$kty, $ty>> :: get(key.borrow(), &$crate::storage::RuntimeStorage) + (($($vis:tt)*) ($get_fn:ident) ($wraptype:ident $gettype:ty) ($into_query:ident) ($into_opt_val:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => { + $crate::__storage_items_internal!{ ($($vis)*) () ($wraptype $gettype) ($into_query) ($into_opt_val) $name : $prefix => map [$kty => $ty] } + pub fn $get_fn>(key: K) -> $gettype { + <$name as $crate::storage::StorageMap<$kty, $ty>> :: get(key.borrow()) } }; - (($($vis:tt)*) () ($wraptype:ident $gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => { + (($($vis:tt)*) () ($wraptype:ident $gettype:ty) ($into_query:ident) ($into_opt_val:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => { $($vis)* struct $name; - impl $crate::storage::hashed::generator::StorageMap<$kty, $ty> for $name { + impl $crate::storage::generator::StorageMap<$kty, $ty> for $name { type Query = $gettype; type Hasher = $crate::Blake2_256; - type Default = (); - /// Get the prefix key in storage. fn prefix() -> &'static [u8] { $prefix } - /// Get the storage key used to fetch a value corresponding to a specific key. - fn key_for(x: &$kty) -> $crate::rstd::vec::Vec { - let mut key = $prefix.to_vec(); - $crate::codec::Encode::encode_to(x, &mut key); - key - } - - /// Load the value associated with the given key from the map. - fn get>(key: &$kty, storage: &S) -> Self::Query { - let key = <$name as $crate::storage::hashed::generator::StorageMap<$kty, $ty>>::key_for(key); - storage.$getter(&key[..]) - } - - /// Take the value, reading and removing it. - fn take>(key: &$kty, storage: &mut S) -> Self::Query { - let key = <$name as $crate::storage::hashed::generator::StorageMap<$kty, $ty>>::key_for(key); - storage.$taker(&key[..]) + fn from_optional_value_to_query(v: Option<$ty>) -> Self::Query { + $crate::storage::storage_items::$into_query(v) } - /// Mutate the value under a key. - fn mutate R, S: $crate::HashedStorage>(key: &$kty, f: F, storage: &mut S) -> R { - let mut val = >::take(key, storage); - - let ret = f(&mut val); - - $crate::__handle_wrap_internal!($wraptype { - // raw type case - >::insert(key, &val, storage) - } { - // Option<> type case - match val { - Some(ref val) => >::insert(key, &val, storage), - None => >::remove(key, storage), - } - }); - - ret + fn from_query_to_optional_value(v: Self::Query) -> Option<$ty> { + $crate::storage::storage_items::$into_opt_val(v) } } }; @@ -292,12 +253,10 @@ macro_rules! __handle_wrap_internal { // Do not complain about unused `dispatch` and `dispatch_aux`. #[allow(dead_code)] mod tests { - use std::collections::HashMap; - use super::*; use crate::metadata::*; use crate::metadata::StorageHasher; use crate::rstd::marker::PhantomData; - use crate::storage::hashed::generator::*; + use crate::storage::{StorageValue, StorageMap}; storage_items! { Value: b"a" => u32; @@ -306,23 +265,25 @@ mod tests { #[test] fn value() { - let mut storage = HashMap::new(); - assert!(Value::get(&storage).is_none()); - Value::put(&100_000, &mut storage); - assert_eq!(Value::get(&storage), Some(100_000)); - Value::kill(&mut storage); - assert!(Value::get(&storage).is_none()); + runtime_io::with_storage(&mut Default::default(), || { + assert!(Value::get().is_none()); + Value::put(&100_000); + assert_eq!(Value::get(), Some(100_000)); + Value::kill(); + assert!(Value::get().is_none()); + }) } #[test] fn map() { - let mut storage = HashMap::new(); - assert!(Map::get(&5, &storage).is_none()); - Map::insert(&5, &[1; 32], &mut storage); - assert_eq!(Map::get(&5, &storage), Some([1; 32])); - assert_eq!(Map::take(&5, &mut storage), Some([1; 32])); - assert!(Map::get(&5, &storage).is_none()); - assert!(Map::get(&999, &storage).is_none()); + runtime_io::with_storage(&mut Default::default(), || { + assert!(Map::get(&5).is_none()); + Map::insert(&5, &[1; 32]); + assert_eq!(Map::get(&5), Some([1; 32])); + assert_eq!(Map::take(&5), Some([1; 32])); + assert!(Map::get(&5).is_none()); + assert!(Map::get(&999).is_none()); + }) } pub trait Trait { @@ -380,7 +341,7 @@ mod tests { COMPLEXTYPE3: ([u32;25]); } add_extra_genesis { - build(|_, _| {}); + build(|_| {}); } } @@ -756,7 +717,7 @@ mod test2 { add_extra_genesis { config(_marker) : ::std::marker::PhantomData; config(extra_field) : u32 = 32; - build(|_, _| {}); + build(|_| {}); } } @@ -797,7 +758,7 @@ mod test3 { #[cfg(test)] #[allow(dead_code)] mod test_append_and_len { - use crate::storage::{AppendableStorageMap, DecodeLengthStorageMap, StorageMap, StorageValue}; + use crate::storage::{StorageMap, StorageValue, StorageLinkedMap}; use runtime_io::{with_externalities, TestExternalities}; use codec::{Encode, Decode}; @@ -952,5 +913,3 @@ mod test_append_and_len { }); } } - - diff --git a/srml/support/src/storage/unhashed/mod.rs b/srml/support/src/storage/unhashed.rs similarity index 98% rename from srml/support/src/storage/unhashed/mod.rs rename to srml/support/src/storage/unhashed.rs index 5d086c36c4..3c6a5074bd 100644 --- a/srml/support/src/storage/unhashed/mod.rs +++ b/srml/support/src/storage/unhashed.rs @@ -14,13 +14,11 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Operation on unhashed runtime storage +//! Operation on unhashed runtime storage. use crate::rstd::borrow::Borrow; use super::{Codec, Encode, Decode, KeyedVec, Vec}; -pub mod generator; - /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. pub fn get(key: &[u8]) -> Option { runtime_io::storage(key).map(|val| { diff --git a/srml/support/src/storage/unhashed/generator.rs b/srml/support/src/storage/unhashed/generator.rs deleted file mode 100644 index a5385af8fb..0000000000 --- a/srml/support/src/storage/unhashed/generator.rs +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -use crate::codec::{self, Encode, EncodeAppend}; -use crate::rstd::{borrow::Borrow, vec::Vec}; - -/// Abstraction around storage with unhashed access. -pub trait UnhashedStorage { - /// true if the key exists in storage. - fn exists(&self, key: &[u8]) -> bool; - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. - fn get(&self, key: &[u8]) -> Option; - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. Will panic if - /// it's not there. - fn require(&self, key: &[u8]) -> T { - self.get(key).expect("Required values must be in storage") - } - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. The type's - /// default is returned if it's not there. - fn get_or_default(&self, key: &[u8]) -> T { - self.get(key).unwrap_or_default() - } - - /// Put a value in under a key. - fn put(&mut self, key: &[u8], val: &T); - - /// Remove the bytes of a key from storage. - fn kill(&mut self, key: &[u8]); - - /// Remove the bytes of a key from storage. - fn kill_prefix(&mut self, prefix: &[u8]); - - /// Take a value from storage, deleting it after reading. - fn take(&mut self, key: &[u8]) -> Option { - let value = self.get(key); - self.kill(key); - value - } - - /// Take a value from storage, deleting it after reading. - fn take_or_panic(&mut self, key: &[u8]) -> T { - self.take(key).expect("Required values must be in storage") - } - - /// Take a value from storage, deleting it after reading. - fn take_or_default(&mut self, key: &[u8]) -> T { - self.take(key).unwrap_or_default() - } - - /// Get a Vec of bytes from storage. - fn get_raw(&self, key: &[u8]) -> Option>; - - /// Put a raw byte slice into storage. - fn put_raw(&mut self, key: &[u8], value: &[u8]); -} - -// We use a construct like this during when genesis storage is being built. -#[cfg(feature = "std")] -impl UnhashedStorage for sr_primitives::StorageOverlay { - fn exists(&self, key: &[u8]) -> bool { - self.contains_key(key) - } - - fn get(&self, key: &[u8]) -> Option { - self.get(key) - .map(|x| codec::Decode::decode(&mut x.as_slice()).expect("Unable to decode expected type.")) - } - - fn put(&mut self, key: &[u8], val: &T) { - self.insert(key.to_vec(), codec::Encode::encode(val)); - } - - fn kill(&mut self, key: &[u8]) { - self.remove(key); - } - - fn kill_prefix(&mut self, prefix: &[u8]) { - self.retain(|key, _| { - !key.starts_with(prefix) - }) - } - - fn get_raw(&self, key: &[u8]) -> Option> { - self.get(key).cloned() - } - - fn put_raw(&mut self, key: &[u8], value: &[u8]) { - self.insert(key.to_vec(), value.to_vec()); - } -} - -/// An implementation of a map with a two keys. -/// -/// It provides an important ability to efficiently remove all entries -/// that have a common first key. -/// -/// # Mapping of keys to a storage path -/// -/// The storage key (i.e. the key under which the `Value` will be stored) is created from two parts. -/// The first part is a hash of a concatenation of the `PREFIX` and `Key1`. And the second part -/// is a hash of a `Key2`. -/// -/// /!\ be careful while choosing the Hash, indeed malicious could craft second keys to lower the trie. -pub trait StorageDoubleMap { - /// The type that get/take returns. - type Query; - - /// Get the prefix key in storage. - fn prefix() -> &'static [u8]; - - /// Get the storage key used to fetch a value corresponding to a specific key. - fn key_for( - k1: &KArg1, - k2: &KArg2, - ) -> Vec where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode; - - /// Get the storage prefix used to fetch keys corresponding to a specific key1. - fn prefix_for(k1: &KArg1) -> Vec where KArg1: ?Sized + Encode, K1: Borrow; - - /// true if the value is defined in storage. - fn exists( - k1: &KArg1, - k2: &KArg2, - storage: &S, - ) -> bool where K1: Borrow, K2: Borrow, KArg1: ?Sized + Encode, KArg2: ?Sized + Encode { - storage.exists(&Self::key_for(k1, k2)) - } - - /// Load the value associated with the given key from the map. - fn get( - k1: &KArg1, - k2: &KArg2, - storage: &S, - ) -> Self::Query where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode; - - /// Take the value under a key. - fn take( - k1: &KArg1, - k2: &KArg2, - storage: &mut S, - ) -> Self::Query where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode; - - /// Store a value to be associated with the given key from the map. - fn insert( - k1: &KArg1, - k2: &KArg2, - val: &VArg, - storage: &mut S, - ) where - K1: Borrow, - K2: Borrow, - V: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - VArg: ?Sized + Encode, - { - storage.put(&Self::key_for(k1, k2), val); - } - - /// Remove the value under a key. - fn remove( - k1: &KArg1, - k2: &KArg2, - storage: &mut S, - ) where K1: Borrow, K2: Borrow, KArg1: ?Sized + Encode, KArg2: ?Sized + Encode { - storage.kill(&Self::key_for(k1, k2)); - } - - /// Removes all entries that shares the `k1` as the first key. - fn remove_prefix( - k1: &KArg1, - storage: &mut S, - ) where KArg1: ?Sized + Encode, K1: Borrow { - storage.kill_prefix(&Self::prefix_for(k1)); - } - - /// Mutate the value under a key. - fn mutate( - k1: &KArg1, - k2: &KArg2, - f: F, - storage: &mut S, - ) -> R where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - F: FnOnce(&mut Self::Query) -> R; - - /// Append the given items to the value under the key specified. - fn append( - k1: &KArg1, - k2: &KArg2, - items: &[I], - storage: &mut S, - ) -> Result<(), &'static str> - where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - I: codec::Encode, - V: EncodeAppend, - { - let key = Self::key_for(k1, k2); - let new_val = ::append( - storage.get_raw(&key).unwrap_or_default(), - items, - ).map_err(|_| "Could not append given item")?; - storage.put_raw(&key, &new_val); - Ok(()) - } -} diff --git a/srml/support/src/traits.rs b/srml/support/src/traits.rs index a5e52f5f66..355f05992f 100644 --- a/srml/support/src/traits.rs +++ b/srml/support/src/traits.rs @@ -26,16 +26,6 @@ use crate::sr_primitives::ConsensusEngineId; use super::for_each_tuple; -/// A trait that can return the default value of a storage item. This must only ever be implemented -/// for a special delegator struct for each storage item -pub trait StorageDefault: Sized { - /// Return the default value of type `V`. `None`, if `V` does not have a proper default value. - fn default() -> Option; -} - -// FIXME #1466 This is needed for `storage_items!`. Should be removed once it is deprecated. -impl StorageDefault for () { fn default() -> Option { Some(Default::default()) } } - /// Anything that can have a `::len()` method. pub trait Len { /// Return the length of data type. diff --git a/srml/support/test/tests/final_keys.rs b/srml/support/test/tests/final_keys.rs index 9c770075c4..af8e01cc5f 100644 --- a/srml/support/test/tests/final_keys.rs +++ b/srml/support/test/tests/final_keys.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . use runtime_io::{with_externalities, Blake2Hasher}; -use srml_support::{StorageValue, StorageMap, StorageDoubleMap}; +use srml_support::{StorageValue, StorageMap, StorageLinkedMap, StorageDoubleMap}; use srml_support::storage::unhashed; use codec::{Encode, Decode}; diff --git a/srml/support/test/tests/instance.rs b/srml/support/test/tests/instance.rs index e9c660eea3..48af8926dd 100644 --- a/srml/support/test/tests/instance.rs +++ b/srml/support/test/tests/instance.rs @@ -23,11 +23,11 @@ use srml_support::{ DecodeDifferent, StorageMetadata, StorageEntryModifier, StorageEntryType, DefaultByteGetter, StorageEntryMetadata, StorageHasher }, + StorageValue, StorageMap, StorageLinkedMap, StorageDoubleMap, }; use inherents::{ ProvideInherent, InherentData, InherentIdentifier, RuntimeString, MakeFatalError }; -use srml_support::{StorageValue, StorageMap, StorageDoubleMap, EnumerableStorageMap}; use primitives::{H256, sr25519}; mod system; @@ -75,7 +75,7 @@ mod module1 { add_extra_genesis { config(test) : T::BlockNumber; - build(|_, config: &Self| { + build(|config: &Self| { println!("{}", config.test); }); } @@ -304,53 +304,27 @@ fn new_test_ext() -> runtime_io::TestExternalities { #[test] fn storage_instance_independance() { - with_externalities(&mut new_test_ext(), || { - let mut map = std::collections::btree_map::BTreeMap::new(); - for key in [ - module2::Value::::key().to_vec(), - module2::Value::::key().to_vec(), - module2::Value::::key().to_vec(), - module2::Value::::key().to_vec(), - module2::Map::::prefix().to_vec(), - module2::Map::::prefix().to_vec(), - module2::Map::::prefix().to_vec(), - module2::Map::::prefix().to_vec(), - module2::LinkedMap::::prefix().to_vec(), - module2::LinkedMap::::prefix().to_vec(), - module2::LinkedMap::::prefix().to_vec(), - module2::LinkedMap::::prefix().to_vec(), - module2::DoubleMap::::prefix().to_vec(), - module2::DoubleMap::::prefix().to_vec(), - module2::DoubleMap::::prefix().to_vec(), - module2::DoubleMap::::prefix().to_vec(), - module2::Map::::key_for(0), - module2::Map::::key_for(0).to_vec(), - module2::Map::::key_for(0).to_vec(), - module2::Map::::key_for(0).to_vec(), - module2::LinkedMap::::key_for(0), - module2::LinkedMap::::key_for(0).to_vec(), - module2::LinkedMap::::key_for(0).to_vec(), - module2::LinkedMap::::key_for(0).to_vec(), - module2::Map::::key_for(1), - module2::Map::::key_for(1).to_vec(), - module2::Map::::key_for(1).to_vec(), - module2::Map::::key_for(1).to_vec(), - module2::LinkedMap::::key_for(1), - module2::LinkedMap::::key_for(1).to_vec(), - module2::LinkedMap::::key_for(1).to_vec(), - module2::LinkedMap::::key_for(1).to_vec(), - module2::DoubleMap::::prefix_for(&1), - module2::DoubleMap::::prefix_for(&1).to_vec(), - module2::DoubleMap::::prefix_for(&1).to_vec(), - module2::DoubleMap::::prefix_for(&1).to_vec(), - module2::DoubleMap::::key_for(&1, &1), - module2::DoubleMap::::key_for(&1, &1).to_vec(), - module2::DoubleMap::::key_for(&1, &1).to_vec(), - module2::DoubleMap::::key_for(&1, &1).to_vec(), - ].iter() { - assert!(map.insert(key, ()).is_none()) - } + let mut storage = (std::collections::HashMap::new(), std::collections::HashMap::new()); + runtime_io::with_storage(&mut storage, || { + module2::Value::::put(0); + module2::Value::::put(0); + module2::Value::::put(0); + module2::Value::::put(0); + module2::Map::::insert(0, 0); + module2::Map::::insert(0, 0); + module2::Map::::insert(0, 0); + module2::Map::::insert(0, 0); + module2::LinkedMap::::insert(0, vec![]); + module2::LinkedMap::::insert(0, vec![]); + module2::LinkedMap::::insert(0, vec![]); + module2::LinkedMap::::insert(0, vec![]); + module2::DoubleMap::::insert(&0, &0, &0); + module2::DoubleMap::::insert(&0, &0, &0); + module2::DoubleMap::::insert(&0, &0, &0); + module2::DoubleMap::::insert(&0, &0, &0); }); + // 16 storage values + 4 linked_map head. + assert_eq!(storage.0.len(), 16 + 4); } #[test] diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index 91959f43e4..3fa4733ba0 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -116,7 +116,7 @@ use safe_mix::TripletMix; use codec::{Encode, Decode}; #[cfg(any(feature = "std", test))] -use runtime_io::{twox_128, TestExternalities, Blake2Hasher}; +use runtime_io::{TestExternalities, Blake2Hasher}; #[cfg(any(feature = "std", test))] use primitives::ChangesTrieConfiguration; @@ -425,19 +425,17 @@ decl_storage! { #[serde(with = "primitives::bytes")] config(code): Vec; - build( - |storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay), - config: &GenesisConfig| - { + build(|config: &GenesisConfig| { use codec::Encode; - storage.0.insert(well_known_keys::CODE.to_vec(), config.code.clone()); - storage.0.insert(well_known_keys::EXTRINSIC_INDEX.to_vec(), 0u32.encode()); + runtime_io::set_storage(well_known_keys::CODE, &config.code); + runtime_io::set_storage(well_known_keys::EXTRINSIC_INDEX, &0u32.encode()); if let Some(ref changes_trie_config) = config.changes_trie_config { - storage.0.insert( - well_known_keys::CHANGES_TRIE_CONFIG.to_vec(), - changes_trie_config.encode()); + runtime_io::set_storage( + well_known_keys::CHANGES_TRIE_CONFIG, + &changes_trie_config.encode(), + ); } }); } @@ -703,9 +701,9 @@ impl Module { #[cfg(any(feature = "std", test))] pub fn externalities() -> TestExternalities { TestExternalities::new((map![ - twox_128(&>::key_for(T::BlockNumber::zero())).to_vec() => [69u8; 32].encode(), - twox_128(>::key()).to_vec() => T::BlockNumber::one().encode(), - twox_128(>::key()).to_vec() => [69u8; 32].encode() + >::hashed_key_for(T::BlockNumber::zero()) => [69u8; 32].encode(), + >::hashed_key().to_vec() => T::BlockNumber::one().encode(), + >::hashed_key().to_vec() => [69u8; 32].encode() ], map![])) } -- GitLab From 500b1d527a40ff332dfa484b7e6e11494ba8b9f1 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Thu, 29 Aug 2019 17:43:04 +0200 Subject: [PATCH 041/275] rename (#3516) --- srml/assets/Cargo.toml | 2 +- srml/membership/Cargo.toml | 4 ++-- srml/membership/src/lib.rs | 6 +++--- srml/scored-pool/Cargo.toml | 4 ++-- srml/scored-pool/src/lib.rs | 6 +++--- srml/sudo/Cargo.toml | 4 ++-- srml/sudo/src/lib.rs | 2 +- srml/support/Cargo.toml | 4 ++-- srml/support/src/double_map.rs | 2 +- srml/support/src/lib.rs | 2 +- srml/support/src/storage/generator/double_map.rs | 2 +- srml/support/src/storage/generator/linked_map.rs | 2 +- srml/support/src/storage/generator/map.rs | 4 ++-- srml/support/src/storage/generator/value.rs | 4 ++-- 14 files changed, 24 insertions(+), 24 deletions(-) diff --git a/srml/assets/Cargo.toml b/srml/assets/Cargo.toml index 2badb46130..d5924cfdda 100644 --- a/srml/assets/Cargo.toml +++ b/srml/assets/Cargo.toml @@ -16,7 +16,7 @@ system = { package = "srml-system", path = "../system", default-features = false [dev-dependencies] primitives = { package = "substrate-primitives", path = "../../core/primitives" } -sr-std = { path = "../../core/sr-std" } +rstd = { package = "sr-std", path = "../../core/sr-std" } runtime_io = { package = "sr-io", path = "../../core/sr-io" } [features] diff --git a/srml/membership/Cargo.toml b/srml/membership/Cargo.toml index 5126f41f89..7c167bbf2c 100644 --- a/srml/membership/Cargo.toml +++ b/srml/membership/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" [dependencies] serde = { version = "1.0", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } -sr-std = { path = "../../core/sr-std", default-features = false } +rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-io = { path = "../../core/sr-io", default-features = false } srml-support = { path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } @@ -22,7 +22,7 @@ std = [ "serde", "codec/std", "sr-primitives/std", - "sr-std/std", + "rstd/std", "sr-io/std", "srml-support/std", "system/std", diff --git a/srml/membership/src/lib.rs b/srml/membership/src/lib.rs index 842d4090b1..76729d633d 100644 --- a/srml/membership/src/lib.rs +++ b/srml/membership/src/lib.rs @@ -22,7 +22,7 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -use sr_std::prelude::*; +use rstd::prelude::*; use srml_support::{ StorageValue, decl_module, decl_storage, decl_event, traits::{ChangeMembers, InitializeMembers}, }; @@ -61,7 +61,7 @@ decl_storage! { } add_extra_genesis { config(members): Vec; - config(phantom): sr_std::marker::PhantomData; + config(phantom): rstd::marker::PhantomData; build(|config: &Self| { let mut members = config.members.clone(); members.sort(); @@ -85,7 +85,7 @@ decl_event!( /// The membership was reset; see the transaction for who the new set is. MembersReset, /// Phantom member, never used. - Dummy(sr_std::marker::PhantomData<(AccountId, Event)>), + Dummy(rstd::marker::PhantomData<(AccountId, Event)>), } ); diff --git a/srml/scored-pool/Cargo.toml b/srml/scored-pool/Cargo.toml index 6494d363fa..032f28a750 100644 --- a/srml/scored-pool/Cargo.toml +++ b/srml/scored-pool/Cargo.toml @@ -9,7 +9,7 @@ codec = { package = "parity-scale-codec", version = "1.0.0", default-features = serde = { version = "1.0", optional = true } sr-io = { path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -sr-std = { path = "../../core/sr-std", default-features = false } +rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } srml-support = { path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } @@ -24,7 +24,7 @@ std = [ "serde", "sr-io/std", "sr-primitives/std", - "sr-std/std", + "rstd/std", "srml-support/std", "system/std", ] diff --git a/srml/scored-pool/src/lib.rs b/srml/scored-pool/src/lib.rs index f3ea075653..dc27b3bba9 100644 --- a/srml/scored-pool/src/lib.rs +++ b/srml/scored-pool/src/lib.rs @@ -89,7 +89,7 @@ mod mock; mod tests; use codec::{Encode, Decode}; -use sr_std::prelude::*; +use rstd::prelude::*; use srml_support::{ StorageValue, StorageMap, decl_module, decl_storage, decl_event, ensure, traits::{ChangeMembers, InitializeMembers, Currency, Get, ReservableCurrency}, @@ -171,7 +171,7 @@ decl_storage! { } add_extra_genesis { config(members): Vec; - config(phantom): sr_std::marker::PhantomData; + config(phantom): rstd::marker::PhantomData; build(|config| { let mut pool = config.pool.clone(); @@ -214,7 +214,7 @@ decl_event!( /// See the transaction for who. CandidateScored, /// Phantom member, never used. - Dummy(sr_std::marker::PhantomData<(AccountId, I)>), + Dummy(rstd::marker::PhantomData<(AccountId, I)>), } ); diff --git a/srml/sudo/Cargo.toml b/srml/sudo/Cargo.toml index d0e2d5dbc5..4ce20b0421 100644 --- a/srml/sudo/Cargo.toml +++ b/srml/sudo/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" [dependencies] serde = { version = "1.0", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -sr-std = { path = "../../core/sr-std", default-features = false } +rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-io = { path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } srml-support = { path = "../support", default-features = false } @@ -23,7 +23,7 @@ default = ["std"] std = [ "serde", "codec/std", - "sr-std/std", + "rstd/std", "sr-io/std", "sr-primitives/std", "srml-support/std", diff --git a/srml/sudo/src/lib.rs b/srml/sudo/src/lib.rs index d91f61bd2f..0a71d4d628 100644 --- a/srml/sudo/src/lib.rs +++ b/srml/sudo/src/lib.rs @@ -86,7 +86,7 @@ #![cfg_attr(not(feature = "std"), no_std)] -use sr_std::prelude::*; +use rstd::prelude::*; use sr_primitives::traits::StaticLookup; use sr_primitives::weights::SimpleDispatchInfo; use srml_support::{ diff --git a/srml/support/Cargo.toml b/srml/support/Cargo.toml index cf8c90993a..107a0683da 100644 --- a/srml/support/Cargo.toml +++ b/srml/support/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" serde = { version = "1.0", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.5", default-features = false, features = ["derive"] } srml-metadata = { path = "../metadata", default-features = false } -sr-std = { path = "../../core/sr-std", default-features = false } +rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } @@ -30,7 +30,7 @@ std = [ "serde", "runtime_io/std", "codec/std", - "sr-std/std", + "rstd/std", "sr-primitives/std", "srml-metadata/std", "inherents/std", diff --git a/srml/support/src/double_map.rs b/srml/support/src/double_map.rs index aec7f497a6..c3fea95a6c 100644 --- a/srml/support/src/double_map.rs +++ b/srml/support/src/double_map.rs @@ -19,7 +19,7 @@ use crate::rstd::prelude::*; use crate::codec::{Codec, Encode}; use crate::storage::unhashed; -use sr_std::borrow::Borrow; +use rstd::borrow::Borrow; /// An implementation of a map with a two keys. /// diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index 6795603ade..e7386930b9 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -27,7 +27,7 @@ extern crate bitmask; #[cfg(feature = "std")] pub use serde; #[doc(hidden)] -pub use sr_std as rstd; +pub use rstd; #[doc(hidden)] pub use codec; #[cfg(feature = "std")] diff --git a/srml/support/src/storage/generator/double_map.rs b/srml/support/src/storage/generator/double_map.rs index a1898c3b88..46361340ac 100644 --- a/srml/support/src/storage/generator/double_map.rs +++ b/srml/support/src/storage/generator/double_map.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use sr_std::prelude::*; +use rstd::prelude::*; use codec::{Codec, Encode, EncodeAppend}; use crate::{storage::{self, unhashed, hashed::StorageHasher}, rstd::borrow::Borrow}; diff --git a/srml/support/src/storage/generator/linked_map.rs b/srml/support/src/storage/generator/linked_map.rs index b087cf42f5..e1786d2120 100644 --- a/srml/support/src/storage/generator/linked_map.rs +++ b/srml/support/src/storage/generator/linked_map.rs @@ -16,7 +16,7 @@ use codec::{Codec, Encode, Decode}; use crate::{storage::{self, unhashed, hashed::StorageHasher}, traits::Len}; -use sr_std::{ +use rstd::{ borrow::Borrow, marker::PhantomData, }; diff --git a/srml/support/src/storage/generator/map.rs b/srml/support/src/storage/generator/map.rs index 1d660da3b4..48b8cc097f 100644 --- a/srml/support/src/storage/generator/map.rs +++ b/srml/support/src/storage/generator/map.rs @@ -15,8 +15,8 @@ // along with Substrate. If not, see . #[cfg(not(feature = "std"))] -use sr_std::prelude::*; -use sr_std::borrow::Borrow; +use rstd::prelude::*; +use rstd::borrow::Borrow; use codec::{Codec, Encode}; use crate::{storage::{self, unhashed, hashed::StorageHasher}, traits::Len}; diff --git a/srml/support/src/storage/generator/value.rs b/srml/support/src/storage/generator/value.rs index 32b4a195c8..69851db1a0 100644 --- a/srml/support/src/storage/generator/value.rs +++ b/srml/support/src/storage/generator/value.rs @@ -15,8 +15,8 @@ // along with Substrate. If not, see . #[cfg(not(feature = "std"))] -use sr_std::prelude::*; -use sr_std::{borrow::Borrow, iter::FromIterator}; +use rstd::prelude::*; +use rstd::{borrow::Borrow, iter::FromIterator}; use codec::{Codec, Encode}; use crate::{storage::{self, unhashed, hashed::{Twox128, StorageHasher}}, traits::Len}; -- GitLab From 409f5aa10a32a7b18f1c5a5eded97d24181865dc Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Fri, 30 Aug 2019 02:20:26 +0200 Subject: [PATCH 042/275] Remove `client.backend` (#2960) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * generalize tree_root to remove client.backend dependency * replace client.backend.blockchain.header with client.header * move used_state_cache_size into client info * Create intermediate Setup State. Fixes #1134 * remove client.backend from finality proof * update node-template * move memory backend into test helper mode * move test helper into client * starting the big refactor, remove unused functions * apply_finality * apply_finality * replacing more .backend from environment with client directly * remove .backend from grandpa by using traits * remove .backend from babe * remove .backend from tests where it is not needed * remove .backend from tests * fixing tests * fixing tests * fixing more tests * fixing tests * fix all forks test * fix style * fixing unnecessary allocation * remove old test. * fix service docs * apply suggestion * minor clean ups * turns out the test-helper features actually is being used! * fixing line length. * fix line length * minor cleaning * Apply suggestions from code review thanks, @Basti Co-Authored-By: Bastian Köcher * address grumbles * simplify finalize block on client * move block back into inner function * Apply suggestions from code review Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> * use as.ref instead of match * Update core/client/src/backend.rs Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> --- core/cli/src/informant.rs | 6 +- core/client/db/src/lib.rs | 34 ++- core/client/db/src/light.rs | 10 +- core/client/src/backend.rs | 60 +++- core/client/src/blockchain.rs | 14 +- core/client/src/client.rs | 308 +++++++++----------- core/client/src/in_mem.rs | 2 +- core/client/src/lib.rs | 2 +- core/consensus/aura/src/lib.rs | 17 +- core/consensus/babe/src/lib.rs | 9 +- core/consensus/babe/src/tests.rs | 11 +- core/finality-grandpa/src/environment.rs | 68 ++--- core/finality-grandpa/src/finality_proof.rs | 24 +- core/finality-grandpa/src/import.rs | 13 +- core/finality-grandpa/src/justification.rs | 4 +- core/finality-grandpa/src/lib.rs | 11 +- core/finality-grandpa/src/light_import.rs | 92 +++--- core/finality-grandpa/src/observer.rs | 6 +- core/finality-grandpa/src/tests.rs | 39 +-- core/network/src/chain.rs | 5 +- core/network/src/test/mod.rs | 119 +++++--- core/network/src/test/sync.rs | 51 ++-- core/rpc/src/chain/tests.rs | 4 +- core/service/src/builder.rs | 119 +++++--- core/service/src/lib.rs | 53 ++-- core/test-client/src/client_ext.rs | 4 +- core/test-client/src/lib.rs | 5 + core/test-runtime/client/src/lib.rs | 14 +- node-template/src/service.rs | 48 +-- node/cli/src/service.rs | 45 +-- 30 files changed, 626 insertions(+), 571 deletions(-) diff --git a/core/cli/src/informant.rs b/core/cli/src/informant.rs index 52a5f67c26..a5fe52c09a 100644 --- a/core/cli/src/informant.rs +++ b/core/cli/src/informant.rs @@ -16,7 +16,7 @@ //! Console informant. Prints sync progress and block events. Runs on the calling thread. -use client::{backend::Backend, BlockchainEvents}; +use client::BlockchainEvents; use futures::{Future, Stream}; use futures03::{StreamExt as _, TryStreamExt as _}; use log::{info, warn}; @@ -48,8 +48,8 @@ pub fn build(service: &impl AbstractService) -> impl Future( genesis_storage: S, execution_strategies: ExecutionStrategies, keystore: Option, -) -> Result< - client::Client, - client::LocalCallExecutor, E>, Block, RA>, client::error::Error +) -> Result<( + client::Client< + Backend, + client::LocalCallExecutor, E>, + Block, + RA, + >, + Arc>, + ), + client::error::Error, > where Block: BlockT, @@ -208,7 +215,10 @@ pub fn new_client( { let backend = Arc::new(Backend::new(settings, CANONICALIZATION_DELAY)?); let executor = client::LocalCallExecutor::new(backend.clone(), executor, keystore); - Ok(client::Client::new(backend, executor, genesis_storage, execution_strategies)?) + Ok(( + client::Client::new(backend.clone(), executor, genesis_storage, execution_strategies)?, + backend, + )) } pub(crate) mod columns { @@ -871,7 +881,9 @@ impl> Backend { // cannot find tree route with empty DB. if meta.best_hash != Default::default() { let tree_route = ::client::blockchain::tree_route( - &self.blockchain, + |id| self.blockchain.header(id)?.ok_or_else( + || client::error::Error::UnknownBlock(format!("{:?}", id)) + ), BlockId::Hash(meta.best_hash), BlockId::Hash(route_to), )?; @@ -2018,6 +2030,7 @@ mod tests { #[test] fn tree_route_works() { let backend = Backend::::new_test(1000, 100); + let blockchain = backend.blockchain(); let block0 = insert_header(&backend, 0, Default::default(), Vec::new(), Default::default()); // fork from genesis: 3 prong. @@ -2031,7 +2044,7 @@ mod tests { { let tree_route = ::client::blockchain::tree_route( - backend.blockchain(), + |id| blockchain.header(id)?.ok_or_else(|| client::error::Error::UnknownBlock(format!("{:?}", id))), BlockId::Hash(a3), BlockId::Hash(b2) ).unwrap(); @@ -2043,7 +2056,7 @@ mod tests { { let tree_route = ::client::blockchain::tree_route( - backend.blockchain(), + |id| blockchain.header(id)?.ok_or_else(|| client::error::Error::UnknownBlock(format!("{:?}", id))), BlockId::Hash(a1), BlockId::Hash(a3), ).unwrap(); @@ -2055,7 +2068,7 @@ mod tests { { let tree_route = ::client::blockchain::tree_route( - backend.blockchain(), + |id| blockchain.header(id)?.ok_or_else(|| client::error::Error::UnknownBlock(format!("{:?}", id))), BlockId::Hash(a3), BlockId::Hash(a1), ).unwrap(); @@ -2067,7 +2080,7 @@ mod tests { { let tree_route = ::client::blockchain::tree_route( - backend.blockchain(), + |id| blockchain.header(id)?.ok_or_else(|| client::error::Error::UnknownBlock(format!("{:?}", id))), BlockId::Hash(a2), BlockId::Hash(a2), ).unwrap(); @@ -2081,13 +2094,14 @@ mod tests { #[test] fn tree_route_child() { let backend = Backend::::new_test(1000, 100); + let blockchain = backend.blockchain(); let block0 = insert_header(&backend, 0, Default::default(), Vec::new(), Default::default()); let block1 = insert_header(&backend, 1, block0, Vec::new(), Default::default()); { let tree_route = ::client::blockchain::tree_route( - backend.blockchain(), + |id| blockchain.header(id)?.ok_or_else(|| client::error::Error::UnknownBlock(format!("{:?}", id))), BlockId::Hash(block0), BlockId::Hash(block1), ).unwrap(); diff --git a/core/client/db/src/light.rs b/core/client/db/src/light.rs index 86408a155d..2d100dad29 100644 --- a/core/client/db/src/light.rs +++ b/core/client/db/src/light.rs @@ -213,7 +213,7 @@ impl LightStorage { let meta = self.meta.read(); if meta.best_hash != Default::default() { let tree_route = ::client::blockchain::tree_route( - self, + |id| self.header(id)?.ok_or_else(|| client::error::Error::UnknownBlock(format!("{:?}", id))), BlockId::Hash(meta.best_hash), BlockId::Hash(route_to), )?; @@ -780,7 +780,7 @@ pub(crate) mod tests { { let tree_route = ::client::blockchain::tree_route( - &db, + |id| db.header(id)?.ok_or_else(|| client::error::Error::UnknownBlock(format!("{:?}", id))), BlockId::Hash(a3), BlockId::Hash(b2) ).unwrap(); @@ -792,7 +792,7 @@ pub(crate) mod tests { { let tree_route = ::client::blockchain::tree_route( - &db, + |id| db.header(id)?.ok_or_else(|| client::error::Error::UnknownBlock(format!("{:?}", id))), BlockId::Hash(a1), BlockId::Hash(a3), ).unwrap(); @@ -804,7 +804,7 @@ pub(crate) mod tests { { let tree_route = ::client::blockchain::tree_route( - &db, + |id| db.header(id)?.ok_or_else(|| client::error::Error::UnknownBlock(format!("{:?}", id))), BlockId::Hash(a3), BlockId::Hash(a1), ).unwrap(); @@ -816,7 +816,7 @@ pub(crate) mod tests { { let tree_route = ::client::blockchain::tree_route( - &db, + |id| db.header(id)?.ok_or_else(|| client::error::Error::UnknownBlock(format!("{:?}", id))), BlockId::Hash(a2), BlockId::Hash(a2), ).unwrap(); diff --git a/core/client/src/backend.rs b/core/client/src/backend.rs index 24b48c9b86..07bb6d6c91 100644 --- a/core/client/src/backend.rs +++ b/core/client/src/backend.rs @@ -23,7 +23,7 @@ use sr_primitives::{generic::BlockId, Justification, StorageOverlay, ChildrenSto use sr_primitives::traits::{Block as BlockT, NumberFor}; use state_machine::backend::Backend as StateBackend; use state_machine::ChangesTrieStorage as StateChangesTrieStorage; -use consensus::well_known_cache_keys; +use consensus::{well_known_cache_keys, BlockOrigin}; use hash_db::Hasher; use trie::MemoryDB; use parking_lot::Mutex; @@ -34,6 +34,25 @@ pub type StorageCollection = Vec<(Vec, Option>)>; /// In memory arrays of storage values for multiple child tries. pub type ChildStorageCollection = Vec<(Vec, StorageCollection)>; +/// Import operation wrapper +pub struct ClientImportOperation< + Block: BlockT, + H: Hasher, + B: Backend, +> { + pub(crate) op: B::BlockImportOperation, + pub(crate) notify_imported: Option<( + Block::Hash, + BlockOrigin, + Block::Header, + bool, + Option<( + StorageCollection, + ChildStorageCollection, + )>)>, + pub(crate) notify_finalized: Vec, +} + /// State of a new block. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum NewBlockState { @@ -105,6 +124,45 @@ pub trait BlockImportOperation where fn mark_head(&mut self, id: BlockId) -> error::Result<()>; } +/// Finalize Facilities +pub trait Finalizer, B: Backend> { + /// Mark all blocks up to given as finalized in operation. If a + /// justification is provided it is stored with the given finalized + /// block (any other finalized blocks are left unjustified). + /// + /// If the block being finalized is on a different fork from the current + /// best block the finalized block is set as best, this might be slightly + /// inaccurate (i.e. outdated). Usages that require determining an accurate + /// best block should use `SelectChain` instead of the client. + fn apply_finality( + &self, + operation: &mut ClientImportOperation, + id: BlockId, + justification: Option, + notify: bool, + ) -> error::Result<()>; + + + /// Finalize a block. This will implicitly finalize all blocks up to it and + /// fire finality notifications. + /// + /// If the block being finalized is on a different fork from the current + /// best block, the finalized block is set as best. This might be slightly + /// inaccurate (i.e. outdated). Usages that require determining an accurate + /// best block should use `SelectChain` instead of the client. + /// + /// Pass a flag to indicate whether finality notifications should be propagated. + /// This is usually tied to some synchronization state, where we don't send notifications + /// while performing major synchronization work. + fn finalize_block( + &self, + id: BlockId, + justification: Option, + notify: bool, + ) -> error::Result<()>; + +} + /// Provides access to an auxiliary database. pub trait AuxStore { /// Insert auxiliary data into key-value store. Deletions occur after insertions. diff --git a/core/client/src/blockchain.rs b/core/client/src/blockchain.rs index f4a4f8a4aa..9c9c915388 100644 --- a/core/client/src/blockchain.rs +++ b/core/client/src/blockchain.rs @@ -197,21 +197,11 @@ impl TreeRoute { } /// Compute a tree-route between two blocks. See tree-route docs for more details. -pub fn tree_route>( - backend: &Backend, +pub fn tree_route) -> Result<::Header>>( + load_header: F, from: BlockId, to: BlockId, ) -> Result> { - use sr_primitives::traits::Header; - - let load_header = |id: BlockId| { - match backend.header(id) { - Ok(Some(hdr)) => Ok(hdr), - Ok(None) => Err(Error::UnknownBlock(format!("Unknown block {:?}", id))), - Err(e) => Err(e), - } - }; - let mut from = load_header(from)?; let mut to = load_header(to)?; diff --git a/core/client/src/client.rs b/core/client/src/client.rs index 5b0cba3a40..41dae58970 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -61,7 +61,7 @@ use crate::{ }, backend::{ self, BlockImportOperation, PrunableStateChangesTrieStorage, - StorageCollection, ChildStorageCollection + ClientImportOperation, Finalizer, }, blockchain::{ self, Info as ChainInfo, Backend as ChainBackend, @@ -128,21 +128,6 @@ pub struct Client where Block: BlockT { _phantom: PhantomData, } -/// Client import operation, a wrapper for the backend. -pub struct ClientImportOperation, B: backend::Backend> { - op: B::BlockImportOperation, - notify_imported: Option<( - Block::Hash, - BlockOrigin, - Block::Header, - bool, - Option<( - StorageCollection, - ChildStorageCollection, - )>)>, - notify_finalized: Vec, -} - /// A source of blockchain events. pub trait BlockchainEvents { /// Get block import event stream. Not guaranteed to be fired for every @@ -183,6 +168,8 @@ pub trait ProvideUncles { pub struct ClientInfo { /// Best block hash. pub chain: ChainInfo, + /// State Cache Size currently used by the backend + pub used_state_cache_size: Option, } /// Block status. @@ -828,28 +815,9 @@ impl Client where result } - /// Set a block as best block. - pub fn set_head( - &self, - id: BlockId - ) -> error::Result<()> { - self.lock_import_and_run(|operation| { - self.apply_head(operation, id) - }) - } - - /// Set a block as best block, and apply it to an operation. - pub fn apply_head( - &self, - operation: &mut ClientImportOperation, - id: BlockId, - ) -> error::Result<()> { - operation.op.mark_head(id) - } - /// Apply a checked and validated block to an operation. If a justification is provided /// then `finalized` *must* be true. - pub fn apply_block( + fn apply_block( &self, operation: &mut ClientImportOperation, import_block: BlockImportParams, @@ -945,7 +913,7 @@ impl Client where // find tree route from last finalized to given block. let route_from_finalized = crate::blockchain::tree_route( - self.backend.blockchain(), + |id| self.header(&id)?.ok_or_else(|| Error::UnknownBlock(format!("{:?}", id))), BlockId::Hash(info.finalized_hash), BlockId::Hash(parent_hash), )?; @@ -1112,7 +1080,7 @@ impl Client where } let route_from_finalized = crate::blockchain::tree_route( - self.backend.blockchain(), + |id| self.header(&id)?.ok_or_else(|| Error::UnknownBlock(format!("{:?}", id))), BlockId::Hash(last_finalized), BlockId::Hash(block), )?; @@ -1125,7 +1093,7 @@ impl Client where } let route_from_best = crate::blockchain::tree_route( - self.backend.blockchain(), + |id| self.header(&id)?.ok_or_else(|| Error::UnknownBlock(format!("{:?}", id))), BlockId::Hash(best_block), BlockId::Hash(block), )?; @@ -1228,68 +1196,6 @@ impl Client where Ok(()) } - /// Apply auxiliary data insertion into an operation. - pub fn apply_aux< - 'a, - 'b: 'a, - 'c: 'a, - I: IntoIterator, - D: IntoIterator, - >( - &self, - operation: &mut ClientImportOperation, - insert: I, - delete: D - ) -> error::Result<()> { - operation.op.insert_aux( - insert.into_iter() - .map(|(k, v)| (k.to_vec(), Some(v.to_vec()))) - .chain(delete.into_iter().map(|k| (k.to_vec(), None))) - ) - } - - /// Mark all blocks up to given as finalized in operation. If a - /// justification is provided it is stored with the given finalized - /// block (any other finalized blocks are left unjustified). - /// - /// If the block being finalized is on a different fork from the current - /// best block the finalized block is set as best, this might be slightly - /// innacurate (i.e. outdated), usages that require determining an accurate - /// best block should use `SelectChain` instead of the client. - pub fn apply_finality( - &self, - operation: &mut ClientImportOperation, - id: BlockId, - justification: Option, - notify: bool, - ) -> error::Result<()> { - let last_best = self.backend.blockchain().info().best_hash; - let to_finalize_hash = self.backend.blockchain().expect_block_hash_from_id(&id)?; - self.apply_finality_with_block_hash(operation, to_finalize_hash, justification, last_best, notify) - } - - /// Finalize a block. This will implicitly finalize all blocks up to it and - /// fire finality notifications. - /// - /// If the block being finalized is on a different fork from the current - /// best block the finalized block is set as best, this might be slightly - /// innacurate (i.e. outdated), usages that require determining an accurate - /// best block should use `SelectChain` instead of the client. - /// - /// Pass a flag to indicate whether finality notifications should be propagated. - /// This is usually tied to some synchronization state, where we don't send notifications - /// while performing major synchronization work. - pub fn finalize_block(&self, id: BlockId, justification: Option, notify: bool) -> error::Result<()> { - self.lock_import_and_run(|operation| { - let last_best = self.backend.blockchain().info().best_hash; - let to_finalize_hash = self.backend.blockchain().expect_block_hash_from_id(&id)?; - self.apply_finality_with_block_hash(operation, to_finalize_hash, justification, last_best, notify) - }).map_err(|e| { - warn!("Block finalization error:\n{:?}", e); - e - }) - } - /// Attempts to revert the chain by `n` blocks. Returns the number of blocks that were /// successfully reverted. pub fn revert(&self, n: NumberFor) -> error::Result> { @@ -1301,6 +1207,7 @@ impl Client where let info = self.backend.blockchain().info(); ClientInfo { chain: info, + used_state_cache_size: self.backend.used_state_cache_size(), } } @@ -1359,7 +1266,7 @@ impl Client where let load_header = |id: Block::Hash| -> error::Result { match self.backend.blockchain().header(BlockId::Hash(id))? { Some(hdr) => Ok(hdr), - None => Err(Error::UnknownBlock(format!("Unknown block {:?}", id))), + None => Err(Error::UnknownBlock(format!("{:?}", id))), } }; @@ -1446,6 +1353,33 @@ impl ChainHeaderBackend for Client wher } } +impl ChainHeaderBackend for &Client where + B: backend::Backend, + E: CallExecutor + Send + Sync, + Block: BlockT, + RA: Send + Sync, +{ + fn header(&self, id: BlockId) -> error::Result> { + (**self).backend.blockchain().header(id) + } + + fn info(&self) -> blockchain::Info { + (**self).backend.blockchain().info() + } + + fn status(&self, id: BlockId) -> error::Result { + (**self).status(id) + } + + fn number(&self, hash: Block::Hash) -> error::Result::Header as HeaderT>::Number>> { + (**self).number(hash) + } + + fn hash(&self, number: NumberFor) -> error::Result> { + (**self).hash(number) + } +} + impl ProvideCache for Client where B: backend::Backend, Block: BlockT, @@ -1601,6 +1535,50 @@ impl consensus::BlockImport for Client } } +impl Finalizer for Client where + B: backend::Backend, + E: CallExecutor, + Block: BlockT, +{ + fn apply_finality( + &self, + operation: &mut ClientImportOperation, + id: BlockId, + justification: Option, + notify: bool, + ) -> error::Result<()> { + let last_best = self.backend.blockchain().info().best_hash; + let to_finalize_hash = self.backend.blockchain().expect_block_hash_from_id(&id)?; + self.apply_finality_with_block_hash(operation, to_finalize_hash, justification, last_best, notify) + } + + fn finalize_block(&self, id: BlockId, justification: Option, notify: bool) -> error::Result<()> { + self.lock_import_and_run(|operation| { + self.apply_finality(operation, id, justification, notify) + }) + } +} + +impl Finalizer for &Client where + B: backend::Backend, + E: CallExecutor, + Block: BlockT, +{ + fn apply_finality( + &self, + operation: &mut ClientImportOperation, + id: BlockId, + justification: Option, + notify: bool, + ) -> error::Result<()> { + (**self).apply_finality(operation, id, justification, notify) + } + + fn finalize_block(&self, id: BlockId, justification: Option, notify: bool) -> error::Result<()> { + (**self).finalize_block(id, justification, notify) + } +} + impl BlockchainEvents for Client where E: CallExecutor, @@ -1847,7 +1825,7 @@ impl backend::AuxStore for Client // layer, one can always use atomic operations to make sure // import is only locked once. self.lock_import_and_run(|operation| { - self.apply_aux(operation, insert, delete) + apply_aux(operation, insert, delete) }) } /// Query auxiliary data from key-value store. @@ -1856,6 +1834,49 @@ impl backend::AuxStore for Client } } + +impl backend::AuxStore for &Client + where + B: backend::Backend, + E: CallExecutor, + Block: BlockT, +{ + + fn insert_aux< + 'a, + 'b: 'a, + 'c: 'a, + I: IntoIterator, + D: IntoIterator, + >(&self, insert: I, delete: D) -> error::Result<()> { + (**self).insert_aux(insert, delete) + } + + fn get_aux(&self, key: &[u8]) -> error::Result>> { + (**self).get_aux(key) + } +} + +/// Helper function to apply auxiliary data insertion into an operation. +pub fn apply_aux<'a, 'b: 'a, 'c: 'a, B, Block, H, D, I>( + operation: &mut ClientImportOperation, + insert: I, + delete: D +) -> error::Result<()> +where + Block: BlockT, + H: Hasher, + B: backend::Backend, + I: IntoIterator, + D: IntoIterator, +{ + operation.op.insert_aux( + insert.into_iter() + .map(|(k, v)| (k.to_vec(), Some(v.to_vec()))) + .chain(delete.into_iter().map(|k| (k.to_vec(), None))) + ) +} + /// Utility methods for the client. pub mod utils { use super::*; @@ -1891,8 +1912,7 @@ pub mod utils { } let tree_route = blockchain::tree_route( - #[allow(deprecated)] - client.backend().blockchain(), + |id| client.header(&id)?.ok_or_else(|| Error::UnknownBlock(format!("{:?}", id))), BlockId::Hash(*hash), BlockId::Hash(*base), )?; @@ -1911,7 +1931,6 @@ pub(crate) mod tests { use consensus::{BlockOrigin, SelectChain}; use test_client::{ prelude::*, - client::backend::Backend as TestBackend, client_db::{Backend, DatabaseSettings, PruningMode}, runtime::{self, Block, Transfer, RuntimeApi, TestAPI}, }; @@ -2572,8 +2591,6 @@ pub(crate) mod tests { #[test] fn import_with_justification() { - use test_client::blockchain::Backend; - let client = test_client::new(); // G -> A1 @@ -2589,33 +2606,29 @@ pub(crate) mod tests { let a3 = client.new_block_at(&BlockId::Hash(a2.hash()), Default::default()).unwrap().bake().unwrap(); client.import_justified(BlockOrigin::Own, a3.clone(), justification.clone()).unwrap(); - #[allow(deprecated)] - let blockchain = client.backend().blockchain(); - assert_eq!( - blockchain.last_finalized().unwrap(), + client.info().chain.finalized_hash, a3.hash(), ); assert_eq!( - blockchain.justification(BlockId::Hash(a3.hash())).unwrap(), + client.justification(&BlockId::Hash(a3.hash())).unwrap(), Some(justification), ); assert_eq!( - blockchain.justification(BlockId::Hash(a1.hash())).unwrap(), + client.justification(&BlockId::Hash(a1.hash())).unwrap(), None, ); assert_eq!( - blockchain.justification(BlockId::Hash(a2.hash())).unwrap(), + client.justification(&BlockId::Hash(a2.hash())).unwrap(), None, ); } #[test] fn importing_diverged_finalized_block_should_trigger_reorg() { - use test_client::blockchain::HeaderBackend; let client = test_client::new(); @@ -2639,12 +2652,9 @@ pub(crate) mod tests { // create but don't import B1 just yet let b1 = b1.bake().unwrap(); - #[allow(deprecated)] - let blockchain = client.backend().blockchain(); - // A2 is the current best since it's the longest chain assert_eq!( - blockchain.info().best_hash, + client.info().chain.best_hash, a2.hash(), ); @@ -2653,19 +2663,18 @@ pub(crate) mod tests { client.import_justified(BlockOrigin::Own, b1.clone(), justification).unwrap(); assert_eq!( - blockchain.info().best_hash, + client.info().chain.best_hash, b1.hash(), ); assert_eq!( - blockchain.info().finalized_hash, + client.info().chain.finalized_hash, b1.hash(), ); } #[test] fn finalizing_diverged_block_should_trigger_reorg() { - use test_client::blockchain::HeaderBackend; let (client, select_chain) = TestClientBuilder::new().build_with_longest_chain(); @@ -2692,29 +2701,26 @@ pub(crate) mod tests { let b2 = client.new_block_at(&BlockId::Hash(b1.hash()), Default::default()).unwrap().bake().unwrap(); client.import(BlockOrigin::Own, b2.clone()).unwrap(); - #[allow(deprecated)] - let blockchain = client.backend().blockchain(); - // A2 is the current best since it's the longest chain assert_eq!( - blockchain.info().best_hash, + client.info().chain.best_hash, a2.hash(), ); // we finalize block B1 which is on a different branch from current best // which should trigger a re-org. - client.finalize_block(BlockId::Hash(b1.hash()), None, false).unwrap(); + client.finalize_block(BlockId::Hash(b1.hash()), None).unwrap(); // B1 should now be the latest finalized assert_eq!( - blockchain.info().finalized_hash, + client.info().chain.finalized_hash, b1.hash(), ); // and B1 should be the new best block (`finalize_block` as no way of // knowing about B2) assert_eq!( - blockchain.info().best_hash, + client.info().chain.best_hash, b1.hash(), ); @@ -2733,7 +2739,7 @@ pub(crate) mod tests { client.import(BlockOrigin::Own, b3.clone()).unwrap(); assert_eq!( - blockchain.info().best_hash, + client.info().chain.best_hash, b3.hash(), ); } @@ -2795,44 +2801,6 @@ pub(crate) mod tests { assert_eq!(980, current_balance()); } - #[test] - fn state_reverted_on_set_head() { - let _ = env_logger::try_init(); - let client = test_client::new(); - - let current_balance = || - client.runtime_api().balance_of( - &BlockId::number(client.info().chain.best_number), AccountKeyring::Alice.into() - ).unwrap(); - - // G -> A1 - // \ - // -> B1 - let mut a1 = client.new_block_at(&BlockId::Number(0), Default::default()).unwrap(); - a1.push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Bob.into(), - amount: 10, - nonce: 0, - }).unwrap(); - let a1 = a1.bake().unwrap(); - client.import(BlockOrigin::Own, a1.clone()).unwrap(); - - let mut b1 = client.new_block_at(&BlockId::Number(0), Default::default()).unwrap(); - b1.push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), - amount: 50, - nonce: 0, - }).unwrap(); - let b1 = b1.bake().unwrap(); - client.import(BlockOrigin::Own, b1.clone()).unwrap(); - assert_eq!(990, current_balance()); - // Set B1 as new best - client.set_head(BlockId::hash(b1.hash())).unwrap(); - assert_eq!(950, current_balance()); - } - #[test] fn doesnt_import_blocks_that_revert_finality() { let _ = env_logger::try_init(); @@ -2885,7 +2853,7 @@ pub(crate) mod tests { // we will finalize A2 which should make it impossible to import a new // B3 at the same height but that doesnt't include it - client.finalize_block(BlockId::Hash(a2.hash()), None, false).unwrap(); + client.finalize_block(BlockId::Hash(a2.hash()), None).unwrap(); let b3 = client.new_block_at(&BlockId::Hash(b2.hash()), Default::default()) .unwrap().bake().unwrap(); diff --git a/core/client/src/in_mem.rs b/core/client/src/in_mem.rs index 1a6881ea8d..f450ceebe2 100644 --- a/core/client/src/in_mem.rs +++ b/core/client/src/in_mem.rs @@ -223,7 +223,7 @@ impl Blockchain { None } else { let route = crate::blockchain::tree_route( - self, + |id| self.header(id)?.ok_or_else(|| error::Error::UnknownBlock(format!("{:?}", id))), BlockId::Hash(best_hash), BlockId::Hash(*header.parent_hash()), )?; diff --git a/core/client/src/lib.rs b/core/client/src/lib.rs index 99cbecbe89..1313b8b80e 100644 --- a/core/client/src/lib.rs +++ b/core/client/src/lib.rs @@ -116,7 +116,7 @@ pub use crate::client::{ BlockBody, BlockStatus, ImportNotifications, FinalityNotifications, BlockchainEvents, BlockImportNotification, Client, ClientInfo, ExecutionStrategies, FinalityNotification, LongestChain, BlockOf, ProvideUncles, - utils, + utils, apply_aux, }; #[cfg(feature = "std")] pub use crate::notifications::{StorageEventStream, StorageChangeSet}; diff --git a/core/consensus/aura/src/lib.rs b/core/consensus/aura/src/lib.rs index 406874eafb..a2cf9e83bd 100644 --- a/core/consensus/aura/src/lib.rs +++ b/core/consensus/aura/src/lib.rs @@ -680,7 +680,7 @@ mod tests { use parking_lot::Mutex; use tokio::runtime::current_thread; use keyring::sr25519::Keyring; - use client::{LongestChain, BlockchainEvents}; + use client::BlockchainEvents; use test_client; use aura_primitives::sr25519::AuthorityPair; @@ -744,7 +744,7 @@ mod tests { -> Self::Verifier { match client { - PeersClient::Full(client) => { + PeersClient::Full(client, _) => { let slot_duration = SlotDuration::get_or_compute(&*client) .expect("slot duration available"); let inherent_data_providers = InherentDataProviders::new(); @@ -761,7 +761,7 @@ mod tests { phantom: Default::default(), } }, - PeersClient::Light(_) => unreachable!("No (yet) tests for light client + Aura"), + PeersClient::Light(_, _) => unreachable!("No (yet) tests for light client + Aura"), } } @@ -796,18 +796,17 @@ mod tests { let mut runtime = current_thread::Runtime::new().unwrap(); let mut keystore_paths = Vec::new(); for (peer_id, key) in peers { + let mut net = net.lock(); + let peer = net.peer(*peer_id); + let client = peer.client().as_full().expect("full clients are created").clone(); + let select_chain = peer.select_chain().expect("full client has a select chain"); let keystore_path = tempfile::tempdir().expect("Creates keystore path"); let keystore = keystore::Store::open(keystore_path.path(), None).expect("Creates keystore."); keystore.write().insert_ephemeral_from_seed::(&key.to_seed()) .expect("Creates authority key"); keystore_paths.push(keystore_path); - - let client = net.lock().peer(*peer_id).client().as_full().expect("full clients are created").clone(); - #[allow(deprecated)] - let select_chain = LongestChain::new( - client.backend().clone(), - ); + let environ = DummyFactory(client.clone()); import_notifications.push( client.import_notification_stream() diff --git a/core/consensus/babe/src/lib.rs b/core/consensus/babe/src/lib.rs index 6d049dd6be..c9c80eb1e9 100644 --- a/core/consensus/babe/src/lib.rs +++ b/core/consensus/babe/src/lib.rs @@ -857,8 +857,7 @@ impl Verifier for BabeVerifier BlockImport for BabeBlockImport return Ok(ImportResult::AlreadyInChain), Ok(blockchain::BlockStatus::Unknown) => {}, Err(e) => return Err(ConsensusError::ClientImport(e.to_string()).into()), @@ -1496,8 +1494,7 @@ pub fn import_queue, I, RA, PRA, T>( transaction_pool, }; - #[allow(deprecated)] - let epoch_changes = aux_schema::load_epoch_changes(&**client.backend())?; + let epoch_changes = aux_schema::load_epoch_changes(&*client)?; let block_import = BabeBlockImport::new( client.clone(), diff --git a/core/consensus/babe/src/tests.rs b/core/consensus/babe/src/tests.rs index 8635473a59..2410cadbd5 100644 --- a/core/consensus/babe/src/tests.rs +++ b/core/consensus/babe/src/tests.rs @@ -22,7 +22,7 @@ use super::*; use babe_primitives::AuthorityPair; -use client::{LongestChain, block_builder::BlockBuilder}; +use client::block_builder::BlockBuilder; use consensus_common::NoNetwork as DummyOracle; use network::test::*; use network::test::{Block as TestBlock, PeersClient}; @@ -203,12 +203,16 @@ fn run_one_test() { let mut runtime = current_thread::Runtime::new().unwrap(); let mut keystore_paths = Vec::new(); for (peer_id, seed) in peers { + let mut net = net.lock(); + let peer = net.peer(*peer_id); + let client = peer.client().as_full().expect("Only full clients are used in tests").clone(); + let select_chain = peer.select_chain().expect("Full client has select_chain"); + let keystore_path = tempfile::tempdir().expect("Creates keystore path"); let keystore = keystore::Store::open(keystore_path.path(), None).expect("Creates keystore"); keystore.write().insert_ephemeral_from_seed::(seed).expect("Generates authority key"); keystore_paths.push(keystore_path); - let client = net.lock().peer(*peer_id).client().as_full().unwrap(); let environ = DummyFactory(client.clone()); import_notifications.push( client.import_notification_stream() @@ -223,9 +227,6 @@ fn run_one_test() { &inherent_data_providers, config.get() ).expect("Registers babe inherent data provider"); - #[allow(deprecated)] - let select_chain = LongestChain::new(client.backend().clone()); - runtime.spawn(start_babe(BabeParams { config, block_import: client.clone(), diff --git a/core/finality-grandpa/src/environment.rs b/core/finality-grandpa/src/environment.rs index c0474cb036..faabf705fb 100644 --- a/core/finality-grandpa/src/environment.rs +++ b/core/finality-grandpa/src/environment.rs @@ -26,8 +26,9 @@ use tokio_timer::Delay; use parking_lot::RwLock; use client::{ - backend::Backend, BlockchainEvents, CallExecutor, Client, error::Error as ClientError, - utils::is_descendent_of, + backend::Backend, apply_aux, BlockchainEvents, CallExecutor, + Client, error::Error as ClientError, utils::is_descendent_of, + blockchain::HeaderBackend, backend::Finalizer, }; use grandpa::{ BlockNumberOps, Equivocation, Error as GrandpaError, round::State as RoundState, @@ -498,8 +499,7 @@ pub(crate) fn ancestry, E, RA>( if base == block { return Err(GrandpaError::NotDescendent) } let tree_route_res = ::client::blockchain::tree_route( - #[allow(deprecated)] - client.backend().blockchain(), + |id| client.header(&id)?.ok_or(client::error::Error::UnknownBlock(format!("{:?}", id))), BlockId::Hash(block), BlockId::Hash(base), ); @@ -632,8 +632,7 @@ where current_rounds, }; - #[allow(deprecated)] - crate::aux_schema::write_voter_set_state(&**self.inner.backend(), &set_state)?; + crate::aux_schema::write_voter_set_state(&*self.inner, &set_state)?; Ok(Some(set_state)) })?; @@ -674,8 +673,7 @@ where current_rounds, }; - #[allow(deprecated)] - crate::aux_schema::write_voter_set_state(&**self.inner.backend(), &set_state)?; + crate::aux_schema::write_voter_set_state(&*self.inner, &set_state)?; Ok(Some(set_state)) })?; @@ -726,8 +724,7 @@ where current_rounds, }; - #[allow(deprecated)] - crate::aux_schema::write_voter_set_state(&**self.inner.backend(), &set_state)?; + crate::aux_schema::write_voter_set_state(&*self.inner, &set_state)?; Ok(Some(set_state)) })?; @@ -785,8 +782,7 @@ where current_rounds, }; - #[allow(deprecated)] - crate::aux_schema::write_voter_set_state(&**self.inner.backend(), &set_state)?; + crate::aux_schema::write_voter_set_state(&*self.inner, &set_state)?; Ok(Some(set_state)) })?; @@ -875,24 +871,15 @@ pub(crate) fn finalize_block, E, RA>( E: CallExecutor + Send + Sync, RA: Send + Sync, { - use client::blockchain::HeaderBackend; - - #[allow(deprecated)] - let blockchain = client.backend().blockchain(); - let info = blockchain.info(); - if number <= info.finalized_number && blockchain.hash(number)? == Some(hash) { - // We might have a race condition on finality, since we can finalize - // through either sync (import justification) or through grandpa gossip. - // so let's make sure that this finalization request is no longer stale. - // This can also happen after a forced change (triggered by the finality - // tracker when finality is stalled), since the voter will be restarted - // at the median last finalized block, which can be lower than the local - // best finalized block. - warn!(target: "afg", - "Re-finalized block #{:?} ({:?}) in the canonical chain, current best finalized is #{:?}", - hash, - number, - info.finalized_number, + let status = client.info().chain; + if number <= status.finalized_number && client.hash(number)? == Some(hash) { + // This can happen after a forced change (triggered by the finality tracker when finality is stalled), since + // the voter will be restarted at the median last finalized block, which can be lower than the local best + // finalized block. + warn!(target: "afg", "Re-finalized block #{:?} ({:?}) in the canonical chain, current best finalized is #{:?}", + hash, + number, + status.finalized_number, ); return Ok(()); @@ -929,7 +916,7 @@ pub(crate) fn finalize_block, E, RA>( let write_result = crate::aux_schema::update_consensus_changes( &*consensus_changes, - |insert| client.apply_aux(import_op, insert, &[]), + |insert| apply_aux(import_op, insert, &[]), ); if let Err(e) = write_result { @@ -1022,7 +1009,7 @@ pub(crate) fn finalize_block, E, RA>( let write_result = crate::aux_schema::update_authority_set::( &authority_set, new_authorities.as_ref(), - |insert| client.apply_aux(import_op, insert, &[]), + |insert| apply_aux(import_op, insert, &[]), ); if let Err(e) = write_result { @@ -1053,15 +1040,12 @@ pub(crate) fn finalize_block, E, RA>( /// Using the given base get the block at the given height on this chain. The /// target block must be an ancestor of base, therefore `height <= base.height`. -pub(crate) fn canonical_at_height, RA>( - client: &Client, +pub(crate) fn canonical_at_height, C: HeaderBackend>( + provider: C, base: (Block::Hash, NumberFor), base_is_canonical: bool, height: NumberFor, -) -> Result, ClientError> where - B: Backend, - E: CallExecutor + Send + Sync, -{ +) -> Result, ClientError> { if height > base.1 { return Ok(None); } @@ -1070,17 +1054,17 @@ pub(crate) fn canonical_at_height, RA>( if base_is_canonical { return Ok(Some(base.0)); } else { - return Ok(client.block_hash(height).unwrap_or(None)); + return Ok(provider.hash(height).unwrap_or(None)); } } else if base_is_canonical { - return Ok(client.block_hash(height).unwrap_or(None)); + return Ok(provider.hash(height).unwrap_or(None)); } let one = NumberFor::::one(); // start by getting _canonical_ block with number at parent position and then iterating // backwards by hash. - let mut current = match client.header(&BlockId::Number(base.1 - one))? { + let mut current = match provider.header(BlockId::Number(base.1 - one))? { Some(header) => header, _ => return Ok(None), }; @@ -1089,7 +1073,7 @@ pub(crate) fn canonical_at_height, RA>( let mut steps = base.1 - height - one; while steps > NumberFor::::zero() { - current = match client.header(&BlockId::Hash(*current.parent_hash()))? { + current = match provider.header(BlockId::Hash(*current.parent_hash()))? { Some(header) => header, _ => return Ok(None), }; diff --git a/core/finality-grandpa/src/finality_proof.rs b/core/finality-grandpa/src/finality_proof.rs index 6262ad74a7..4b84ede933 100644 --- a/core/finality-grandpa/src/finality_proof.rs +++ b/core/finality-grandpa/src/finality_proof.rs @@ -130,36 +130,31 @@ impl AuthoritySetForFinalityChecker for Arc, RA> { - client: Arc>, +pub struct FinalityProofProvider> { + backend: Arc, authority_provider: Arc>, } -impl, RA> FinalityProofProvider - where - B: Backend + Send + Sync + 'static, - E: CallExecutor + 'static + Clone + Send + Sync, - RA: Send + Sync, +impl> FinalityProofProvider + where B: Backend + Send + Sync + 'static { /// Create new finality proof provider using: /// - /// - client for accessing blockchain data; + /// - backend for accessing blockchain data; /// - authority_provider for calling and proving runtime methods. pub fn new( - client: Arc>, + backend: Arc, authority_provider: Arc>, ) -> Self { - FinalityProofProvider { client, authority_provider } + FinalityProofProvider { backend, authority_provider } } } -impl network::FinalityProofProvider for FinalityProofProvider +impl network::FinalityProofProvider for FinalityProofProvider where Block: BlockT, NumberFor: BlockNumberOps, B: Backend + Send + Sync + 'static, - E: CallExecutor + 'static + Clone + Send + Sync, - RA: Send + Sync, { fn prove_finality( &self, @@ -173,8 +168,7 @@ impl network::FinalityProofProvider for FinalityProofPro })?; match request { FinalityProofRequest::Original(request) => prove_finality::<_, _, GrandpaJustification>( - #[allow(deprecated)] - &*self.client.backend().blockchain(), + &*self.backend.blockchain(), &*self.authority_provider, request.authorities_set_id, request.last_finalized, diff --git a/core/finality-grandpa/src/import.rs b/core/finality-grandpa/src/import.rs index 7651f9a03d..d51d0ffd84 100644 --- a/core/finality-grandpa/src/import.rs +++ b/core/finality-grandpa/src/import.rs @@ -333,16 +333,10 @@ where // for the canon block the new authority set should start // with. we use the minimum between the median and the local // best finalized block. - - #[allow(deprecated)] - let best_finalized_number = self.inner.backend().blockchain().info() - .finalized_number; - + let best_finalized_number = self.inner.info().chain.finalized_number; let canon_number = best_finalized_number.min(median_last_finalized_number); - - #[allow(deprecated)] let canon_hash = - self.inner.backend().blockchain().header(BlockId::Number(canon_number)) + self.inner.header(&BlockId::Number(canon_number)) .map_err(|e| ConsensusError::ClientImport(e.to_string()))? .expect("the given block number is less or equal than the current best finalized number; \ current best finalized number must exist in chain; qed.") @@ -414,8 +408,7 @@ impl, RA, PRA, SC> BlockImport // early exit if block already in chain, otherwise the check for // authority changes will error when trying to re-import a change block - #[allow(deprecated)] - match self.inner.backend().blockchain().status(BlockId::Hash(hash)) { + match self.inner.status(BlockId::Hash(hash)) { Ok(blockchain::BlockStatus::InChain) => return Ok(ImportResult::AlreadyInChain), Ok(blockchain::BlockStatus::Unknown) => {}, Err(e) => return Err(ConsensusError::ClientImport(e.to_string()).into()), diff --git a/core/finality-grandpa/src/justification.rs b/core/finality-grandpa/src/justification.rs index a6554b1e90..b4de8ff058 100644 --- a/core/finality-grandpa/src/justification.rs +++ b/core/finality-grandpa/src/justification.rs @@ -18,7 +18,6 @@ use std::collections::{HashMap, HashSet}; use client::{CallExecutor, Client}; use client::backend::Backend; -use client::blockchain::HeaderBackend; use client::error::Error as ClientError; use codec::{Encode, Decode}; use grandpa::voter_set::VoterSet; @@ -71,8 +70,7 @@ impl> GrandpaJustification { loop { if current_hash == commit.target_hash { break; } - #[allow(deprecated)] - match client.backend().blockchain().header(BlockId::Hash(current_hash))? { + match client.header(&BlockId::Hash(current_hash))? { Some(current_header) => { if *current_header.number() <= commit.target_number { return error(); diff --git a/core/finality-grandpa/src/lib.rs b/core/finality-grandpa/src/lib.rs index d6f4d76847..36af66af22 100644 --- a/core/finality-grandpa/src/lib.rs +++ b/core/finality-grandpa/src/lib.rs @@ -359,8 +359,7 @@ where let genesis_hash = chain_info.chain.genesis_hash; let persistent_data = aux_schema::load_persistent( - #[allow(deprecated)] - &**client.backend(), + &*client, genesis_hash, >::zero(), || { @@ -452,7 +451,7 @@ fn register_finality_tracker_inherent_data_provider ?info.finalized_number, "finalized_hash" => ?info.finalized_hash, @@ -693,8 +692,7 @@ where (new.canon_hash, new.canon_number), ); - #[allow(deprecated)] - aux_schema::write_voter_set_state(&**self.env.inner.backend(), &set_state)?; + aux_schema::write_voter_set_state(&*self.env.inner, &set_state)?; Ok(Some(set_state)) })?; @@ -722,8 +720,7 @@ where let completed_rounds = voter_set_state.completed_rounds(); let set_state = VoterSetState::Paused { completed_rounds }; - #[allow(deprecated)] - aux_schema::write_voter_set_state(&**self.env.inner.backend(), &set_state)?; + aux_schema::write_voter_set_state(&*self.env.inner, &set_state)?; Ok(Some(set_state)) })?; diff --git a/core/finality-grandpa/src/light_import.rs b/core/finality-grandpa/src/light_import.rs index 4d5381f1cc..6c86c6b38d 100644 --- a/core/finality-grandpa/src/light_import.rs +++ b/core/finality-grandpa/src/light_import.rs @@ -21,7 +21,7 @@ use parking_lot::RwLock; use client::{ CallExecutor, Client, - backend::{AuxStore, Backend}, + backend::{AuxStore, Backend, Finalizer}, blockchain::HeaderBackend, error::Error as ClientError, }; @@ -54,6 +54,7 @@ const LIGHT_CONSENSUS_CHANGES_KEY: &[u8] = b"grandpa_consensus_changes"; /// Create light block importer. pub fn light_block_import, RA, PRA>( client: Arc>, + backend: Arc, authority_set_provider: Arc>, api: Arc, ) -> Result, ClientError> @@ -65,10 +66,10 @@ pub fn light_block_import, RA, PRA>( PRA::Api: GrandpaApi, { let info = client.info(); - #[allow(deprecated)] - let import_data = load_aux_import_data(info.chain.finalized_hash, &**client.backend(), api)?; + let import_data = load_aux_import_data(info.chain.finalized_hash, &*client, api)?; Ok(GrandpaLightBlockImport { client, + backend, authority_set_provider, data: Arc::new(RwLock::new(import_data)), }) @@ -81,6 +82,7 @@ pub fn light_block_import, RA, PRA>( /// - fetching finality proofs for blocks that are enacting consensus changes. pub struct GrandpaLightBlockImport, RA> { client: Arc>, + backend: Arc, authority_set_provider: Arc>, data: Arc>>, } @@ -89,6 +91,7 @@ impl, RA> Clone for GrandpaLightBlockImport Self { GrandpaLightBlockImport { client: self.client.clone(), + backend: self.backend.clone(), authority_set_provider: self.authority_set_provider.clone(), data: self.data.clone(), } @@ -131,7 +134,7 @@ impl, RA> BlockImport block: BlockImportParams, new_cache: HashMap>, ) -> Result { - do_import_block::<_, _, _, _, GrandpaJustification>( + do_import_block::<_, _, _, GrandpaJustification>( &*self.client, &mut *self.data.write(), block, new_cache ) } @@ -176,8 +179,9 @@ impl, RA> FinalityProofImport finality_proof: Vec, verifier: &mut dyn Verifier, ) -> Result<(Block::Hash, NumberFor), Self::Error> { - do_import_finality_proof::<_, _, _, _, GrandpaJustification>( + do_import_finality_proof::<_, _, _, GrandpaJustification>( &*self.client, + self.backend.clone(), &*self.authority_set_provider, &mut *self.data.write(), hash, @@ -227,16 +231,19 @@ impl> FinalityProofRequestBuilder for GrandpaFinalityPro } /// Try to import new block. -fn do_import_block, RA, J>( - mut client: &Client, +fn do_import_block, J>( + mut client: C, data: &mut LightImportData, mut block: BlockImportParams, new_cache: HashMap>, ) -> Result where + C: HeaderBackend + + AuxStore + + Finalizer + + BlockImport + + Clone, B: Backend + 'static, - E: CallExecutor + 'static + Clone + Send + Sync, - RA: Send + Sync, NumberFor: grandpa::BlockNumberOps, DigestFor: Encode, J: ProvableJustification, @@ -247,7 +254,7 @@ fn do_import_block, RA, J>( // we don't want to finalize on `inner.import_block` let justification = block.justification.take(); let enacts_consensus_change = !new_cache.is_empty(); - let import_result = BlockImport::import_block(&mut client, block, new_cache); + let import_result = client.import_block(block, new_cache); let mut imported_aux = match import_result { Ok(ImportResult::Imported(aux)) => aux, @@ -264,7 +271,7 @@ fn do_import_block, RA, J>( hash, ); - do_import_justification::<_, _, _, _, J>(client, data, hash, number, justification) + do_import_justification::<_, _, _, J>(client, data, hash, number, justification) }, None if enacts_consensus_change => { trace!( @@ -283,8 +290,9 @@ fn do_import_block, RA, J>( } /// Try to import finality proof. -fn do_import_finality_proof, RA, J>( - client: &Client, +fn do_import_finality_proof, J>( + client: C, + backend: Arc, authority_set_provider: &dyn AuthoritySetForFinalityChecker, data: &mut LightImportData, _hash: Block::Hash, @@ -293,9 +301,12 @@ fn do_import_finality_proof, RA, J>( verifier: &mut dyn Verifier, ) -> Result<(Block::Hash, NumberFor), ConsensusError> where + C: HeaderBackend + + AuxStore + + Finalizer + + BlockImport + + Clone, B: Backend + 'static, - E: CallExecutor + 'static + Clone + Send + Sync, - RA: Send + Sync, DigestFor: Encode, NumberFor: grandpa::BlockNumberOps, J: ProvableJustification, @@ -303,8 +314,7 @@ fn do_import_finality_proof, RA, J>( let authority_set_id = data.authority_set.set_id(); let authorities = data.authority_set.authorities(); let finality_effects = crate::finality_proof::check_finality_proof( - #[allow(deprecated)] - &*client.backend().blockchain(), + backend.blockchain(), authority_set_id, authorities, authority_set_provider, @@ -322,13 +332,12 @@ fn do_import_finality_proof, RA, J>( if let Some(authorities) = new_authorities { cache.insert(well_known_cache_keys::AUTHORITIES, authorities.encode()); } - do_import_block::<_, _, _, _, J>(client, data, block_to_import, cache)?; + do_import_block::<_, _, _, J>(client.clone(), data, block_to_import, cache)?; } // try to import latest justification let finalized_block_hash = finality_effects.block; - #[allow(deprecated)] - let finalized_block_number = client.backend().blockchain() + let finalized_block_number = backend.blockchain() .expect_block_number_from_id(&BlockId::Hash(finality_effects.block)) .map_err(|e| ConsensusError::ClientImport(e.to_string()))?; do_finalize_block( @@ -349,17 +358,19 @@ fn do_import_finality_proof, RA, J>( } /// Try to import justification. -fn do_import_justification, RA, J>( - client: &Client, +fn do_import_justification, J>( + client: C, data: &mut LightImportData, hash: Block::Hash, number: NumberFor, justification: Justification, ) -> Result where + C: HeaderBackend + + AuxStore + + Finalizer + + Clone, B: Backend + 'static, - E: CallExecutor + 'static + Clone + Send + Sync, - RA: Send + Sync, NumberFor: grandpa::BlockNumberOps, J: ProvableJustification, { @@ -418,17 +429,19 @@ fn do_import_justification, RA, J>( } /// Finalize the block. -fn do_finalize_block, RA>( - client: &Client, +fn do_finalize_block>( + client: C, data: &mut LightImportData, hash: Block::Hash, number: NumberFor, justification: Justification, ) -> Result where + C: HeaderBackend + + AuxStore + + Finalizer + + Clone, B: Backend + 'static, - E: CallExecutor + 'static + Clone + Send + Sync, - RA: Send + Sync, NumberFor: grandpa::BlockNumberOps, { // finalize the block @@ -439,7 +452,7 @@ fn do_finalize_block, RA>( // forget obsoleted consensus changes let consensus_finalization_res = data.consensus_changes - .finalize((number, hash), |at_height| canonical_at_height(&client, (hash, number), true, at_height)); + .finalize((number, hash), |at_height| canonical_at_height(client.clone(), (hash, number), true, at_height)); match consensus_finalization_res { Ok((true, _)) => require_insert_aux( &client, @@ -506,20 +519,14 @@ fn load_aux_import_data, PRA>( } /// Insert into aux store. If failed, return error && show inconsistency warning. -fn require_insert_aux, RA>( - client: &Client, +fn require_insert_aux( + store: &A, key: &[u8], value: &T, value_type: &str, -) -> Result<(), ConsensusError> - where - B: Backend + 'static, - E: CallExecutor + 'static + Clone + Send + Sync, -{ - #[allow(deprecated)] - let backend = &**client.backend(); +) -> Result<(), ConsensusError> { let encoded = value.encode(); - let update_res = Backend::insert_aux(backend, &[(key, &encoded[..])], &[]); + let update_res = store.insert_aux(&[(key, &encoded[..])], &[]); if let Err(error) = update_res { return Err(on_post_finalization_error(error, value_type)); } @@ -617,6 +624,7 @@ pub mod tests { /// Creates light block import that ignores justifications that came outside of finality proofs. pub fn light_block_import_without_justifications, RA, PRA>( client: Arc>, + backend: Arc, authority_set_provider: Arc>, api: Arc, ) -> Result, ClientError> @@ -627,14 +635,14 @@ pub mod tests { PRA: ProvideRuntimeApi, PRA::Api: GrandpaApi, { - light_block_import(client, authority_set_provider, api).map(NoJustificationsImport) + light_block_import(client, backend, authority_set_provider, api).map(NoJustificationsImport) } fn import_block( new_cache: HashMap>, justification: Option, ) -> ImportResult { - let client = test_client::new_light(); + let (client, _backend) = test_client::new_light(); let mut import_data = LightImportData { last_finalized: Default::default(), authority_set: LightAuthoritySet::genesis(vec![(AuthorityId::from_slice(&[1; 32]), 1)]), @@ -656,7 +664,7 @@ pub mod tests { auxiliary: Vec::new(), fork_choice: ForkChoiceStrategy::LongestChain, }; - do_import_block::<_, _, _, _, TestJustification>( + do_import_block::<_, _, _, TestJustification>( &client, &mut import_data, block, diff --git a/core/finality-grandpa/src/observer.rs b/core/finality-grandpa/src/observer.rs index 8a2d539f49..39eeafcb1b 100644 --- a/core/finality-grandpa/src/observer.rs +++ b/core/finality-grandpa/src/observer.rs @@ -301,8 +301,7 @@ where let completed_rounds = self.persistent_data.set_state.read().completed_rounds(); let set_state = VoterSetState::Paused { completed_rounds }; - #[allow(deprecated)] - crate::aux_schema::write_voter_set_state(&**self.client.backend(), &set_state)?; + crate::aux_schema::write_voter_set_state(&*self.client, &set_state)?; set_state }, @@ -315,8 +314,7 @@ where (new.canon_hash, new.canon_number), ); - #[allow(deprecated)] - crate::aux_schema::write_voter_set_state(&**self.client.backend(), &set_state)?; + crate::aux_schema::write_voter_set_state(&*self.client, &set_state)?; set_state }, diff --git a/core/finality-grandpa/src/tests.rs b/core/finality-grandpa/src/tests.rs index c82982e20d..f73cab97f8 100644 --- a/core/finality-grandpa/src/tests.rs +++ b/core/finality-grandpa/src/tests.rs @@ -112,21 +112,17 @@ impl TestNetFactory for GrandpaTestNet { ) { match client { - PeersClient::Full(ref client) => { - #[allow(deprecated)] - let select_chain = LongestChain::new( - client.backend().clone() - ); + PeersClient::Full(ref client, ref backend) => { let (import, link) = block_import( client.clone(), Arc::new(self.test_config.clone()), - select_chain, + LongestChain::new(backend.clone()), ).expect("Could not create block import for fresh peer."); let justification_import = Box::new(import.clone()); let block_import = Box::new(import); (block_import, Some(justification_import), None, None, Mutex::new(Some(link))) }, - PeersClient::Light(ref client) => { + PeersClient::Light(ref client, ref backend) => { use crate::light_import::tests::light_block_import_without_justifications; let authorities_provider = Arc::new(self.test_config.clone()); @@ -134,6 +130,7 @@ impl TestNetFactory for GrandpaTestNet { // => light clients will try to fetch finality proofs let import = light_block_import_without_justifications( client.clone(), + backend.clone(), authorities_provider, Arc::new(self.test_config.clone()) ).expect("Could not create block import for fresh peer."); @@ -150,11 +147,11 @@ impl TestNetFactory for GrandpaTestNet { client: PeersClient ) -> Option>> { match client { - PeersClient::Full(ref client) => { + PeersClient::Full(_, ref backend) => { let authorities_provider = Arc::new(self.test_config.clone()); - Some(Arc::new(FinalityProofProvider::new(client.clone(), authorities_provider))) + Some(Arc::new(FinalityProofProvider::new(backend.clone(), authorities_provider))) }, - PeersClient::Light(_) => None, + PeersClient::Light(_, _) => None, } } @@ -589,10 +586,7 @@ fn transition_3_voters_twice_1_full_observer() { assert_eq!(full_client.info().chain.best_number, 1, "Peer #{} failed to sync", i); - let set: AuthoritySet = crate::aux_schema::load_authorities( - #[allow(deprecated)] - &**full_client.backend() - ).unwrap(); + let set: AuthoritySet = crate::aux_schema::load_authorities(&*full_client).unwrap(); assert_eq!(set.current(), (0, make_ids(peers_a).as_slice())); assert_eq!(set.pending_changes().count(), 0); @@ -685,10 +679,7 @@ fn transition_3_voters_twice_1_full_observer() { .for_each(move |_| Ok(())) .map(move |()| { let full_client = client.as_full().expect("only full clients are used in test"); - let set: AuthoritySet = crate::aux_schema::load_authorities( - #[allow(deprecated)] - &**full_client.backend() - ).unwrap(); + let set: AuthoritySet = crate::aux_schema::load_authorities(&*full_client).unwrap(); assert_eq!(set.current(), (2, make_ids(peers_c).as_slice())); assert_eq!(set.pending_changes().count(), 0); @@ -963,10 +954,7 @@ fn force_change_to_new_set() { "Peer #{} failed to sync", i); let full_client = peer.client().as_full().expect("only full clients are used in test"); - let set: AuthoritySet = crate::aux_schema::load_authorities( - #[allow(deprecated)] - &**full_client.backend() - ).unwrap(); + let set: AuthoritySet = crate::aux_schema::load_authorities(&*full_client).unwrap(); assert_eq!(set.current(), (1, voters.as_slice())); assert_eq!(set.pending_changes().count(), 0); @@ -1099,7 +1087,9 @@ fn voter_persists_its_votes() { assert_eq!(net.peer(0).client().info().chain.best_number, 20, "Peer #{} failed to sync", 0); - let client = net.peer(0).client().clone(); + + let peer = net.peer(0); + let client = peer.client().clone(); let net = Arc::new(Mutex::new(net)); // channel between the voter and the main controller. @@ -1258,9 +1248,8 @@ fn voter_persists_its_votes() { }) .for_each(|_| Ok(())) .and_then(move |_| { - #[allow(deprecated)] let block_30_hash = - net.lock().peer(0).client().as_full().unwrap().backend().blockchain().hash(30).unwrap().unwrap(); + net.lock().peer(0).client().as_full().unwrap().hash(30).unwrap().unwrap(); // we restart alice's voter voter_tx.unbounded_send(()).unwrap(); diff --git a/core/network/src/chain.rs b/core/network/src/chain.rs index e857aa095c..a73d7e53e2 100644 --- a/core/network/src/chain.rs +++ b/core/network/src/chain.rs @@ -134,8 +134,9 @@ impl Client for SubstrateClient where } let tree_route = ::client::blockchain::tree_route( - #[allow(deprecated)] - self.backend().blockchain(), + |id| self.header(&id)?.ok_or_else(|| + client::error::Error::UnknownBlock(format!("{:?}", id)) + ), BlockId::Hash(*block), BlockId::Hash(*base), )?; diff --git a/core/network/src/test/mod.rs b/core/network/src/test/mod.rs index 091047394b..a025bd663a 100644 --- a/core/network/src/test/mod.rs +++ b/core/network/src/test/mod.rs @@ -27,10 +27,13 @@ use std::sync::Arc; use crate::config::build_multiaddr; use log::trace; use crate::chain::FinalityProofProvider; -use client::{self, ClientInfo, BlockchainEvents, BlockImportNotification, FinalityNotifications, FinalityNotification}; -use client::{in_mem::Backend as InMemoryBackend, error::Result as ClientResult}; +use client::{ + self, ClientInfo, BlockchainEvents, BlockImportNotification, FinalityNotifications, + FinalityNotification, LongestChain +}; +use client::error::Result as ClientResult; use client::block_builder::BlockBuilder; -use client::backend::AuxStore; +use client::backend::{AuxStore, Backend, Finalizer}; use crate::config::Roles; use consensus::import_queue::BasicQueue; use consensus::import_queue::{ @@ -45,7 +48,7 @@ use crate::{NetworkWorker, NetworkService, config::ProtocolId}; use crate::config::{NetworkConfiguration, TransportConfig, BoxFinalityProofRequestBuilder}; use libp2p::PeerId; use parking_lot::Mutex; -use primitives::{H256, Blake2Hasher}; +use primitives::H256; use crate::protocol::{Context, ProtocolConfig}; use sr_primitives::generic::{BlockId, OpaqueDigestItemId}; use sr_primitives::traits::{Block as BlockT, Header, NumberFor}; @@ -55,13 +58,14 @@ use crate::specialization::NetworkSpecialization; use test_client::{self, AccountKeyring}; pub use test_client::runtime::{Block, Extrinsic, Hash, Transfer}; -pub use test_client::TestClient; +pub use test_client::{TestClient, TestClientBuilder, TestClientBuilderExt}; type AuthorityId = babe_primitives::AuthorityId; #[cfg(any(test, feature = "test-helpers"))] /// A Verifier that accepts all blocks and passes them on with the configured /// finality to be imported. +#[derive(Clone)] pub struct PassThroughVerifier(pub bool); #[cfg(any(test, feature = "test-helpers"))] @@ -131,66 +135,57 @@ pub type PeersLightClient = #[derive(Clone)] pub enum PeersClient { - Full(Arc), - Light(Arc), + Full(Arc, Arc), + Light(Arc, Arc), } impl PeersClient { pub fn as_full(&self) -> Option> { match *self { - PeersClient::Full(ref client) => Some(client.clone()), + PeersClient::Full(ref client, ref _backend) => Some(client.clone()), _ => None, } } pub fn as_block_import(&self) -> BoxBlockImport { match *self { - PeersClient::Full(ref client) => Box::new(client.clone()) as _, - PeersClient::Light(ref client) => Box::new(client.clone()) as _, - } - } - - pub fn as_in_memory_backend(&self) -> InMemoryBackend { - #[allow(deprecated)] - match *self { - PeersClient::Full(ref client) => client.backend().as_in_memory(), - PeersClient::Light(_) => unimplemented!("TODO"), + PeersClient::Full(ref client, ref _backend) => Box::new(client.clone()) as _, + PeersClient::Light(ref client, ref _backend) => Box::new(client.clone()) as _, } } pub fn get_aux(&self, key: &[u8]) -> ClientResult>> { - #[allow(deprecated)] match *self { - PeersClient::Full(ref client) => client.backend().get_aux(key), - PeersClient::Light(ref client) => client.backend().get_aux(key), + PeersClient::Full(ref client, ref _backend) => client.get_aux(key), + PeersClient::Light(ref client, ref _backend) => client.get_aux(key), } } pub fn info(&self) -> ClientInfo { match *self { - PeersClient::Full(ref client) => client.info(), - PeersClient::Light(ref client) => client.info(), + PeersClient::Full(ref client, ref _backend) => client.info(), + PeersClient::Light(ref client, ref _backend) => client.info(), } } pub fn header(&self, block: &BlockId) -> ClientResult::Header>> { match *self { - PeersClient::Full(ref client) => client.header(block), - PeersClient::Light(ref client) => client.header(block), + PeersClient::Full(ref client, ref _backend) => client.header(block), + PeersClient::Light(ref client, ref _backend) => client.header(block), } } pub fn justification(&self, block: &BlockId) -> ClientResult> { match *self { - PeersClient::Full(ref client) => client.justification(block), - PeersClient::Light(ref client) => client.justification(block), + PeersClient::Full(ref client, ref _backend) => client.justification(block), + PeersClient::Light(ref client, ref _backend) => client.justification(block), } } pub fn finality_notification_stream(&self) -> FinalityNotifications { match *self { - PeersClient::Full(ref client) => client.finality_notification_stream(), - PeersClient::Light(ref client) => client.finality_notification_stream(), + PeersClient::Full(ref client, ref _backend) => client.finality_notification_stream(), + PeersClient::Light(ref client, ref _backend) => client.finality_notification_stream(), } } @@ -201,8 +196,8 @@ impl PeersClient { notify: bool ) -> ClientResult<()> { match *self { - PeersClient::Full(ref client) => client.finalize_block(id, justification, notify), - PeersClient::Light(ref client) => client.finalize_block(id, justification, notify), + PeersClient::Full(ref client, ref _backend) => client.finalize_block(id, justification, notify), + PeersClient::Light(ref client, ref _backend) => client.finalize_block(id, justification, notify), } } } @@ -216,6 +211,8 @@ pub struct Peer> { /// We keep a copy of the block_import so that we can invoke it for locally-generated blocks, /// instead of going through the import queue. block_import: Box>, + select_chain: Option>, + backend: Option>, network: NetworkWorker::Hash>, imported_blocks_stream: Box, Error = ()> + Send>, finality_notification_stream: Box, Error = ()> + Send>, @@ -227,6 +224,11 @@ impl> Peer { self.network.service().is_major_syncing() } + // Returns a clone of the local SelectChain, only available on full nodes + pub fn select_chain(&self) -> Option> { + self.select_chain.clone() + } + /// Returns the number of peers we're connected to. pub fn num_peers(&self) -> usize { self.network.num_connected_peers() @@ -342,6 +344,33 @@ impl> Peer { pub fn network_service(&self) -> &Arc::Hash>> { &self.network.service() } + + /// Test helper to compare the blockchain state of multiple (networked) + /// clients. + /// Potentially costly, as it creates in-memory copies of both blockchains in order + /// to compare them. If you have easier/softer checks that are sufficient, e.g. + /// by using .info(), you should probably use it instead of this. + pub fn blockchain_canon_equals(&self, other: &Self) -> bool { + if let (Some(mine), Some(others)) = (self.backend.clone(), other.backend.clone()) { + mine.as_in_memory().blockchain() + .canon_equals_to(others.as_in_memory().blockchain()) + } else { + false + } + } + + /// Count the current number of known blocks. Note that: + /// 1. this might be expensive as it creates an in-memory-copy of the chain + /// to count the blocks, thus if you have a different way of testing this + /// (e.g. `info.best_hash`) - use that. + /// 2. This is not always increasing nor accurate, as the + /// orphaned and proven-to-never-finalized blocks may be pruned at any time. + /// Therefore, this number can drop again. + pub fn blocks_count(&self) -> usize { + self.backend.as_ref().map( + |backend| backend.as_in_memory().blockchain().blocks_count() + ).unwrap_or(0) + } } pub struct EmptyTransactionPool; @@ -467,11 +496,14 @@ pub trait TestNetFactory: Sized { /// Add a full peer. fn add_full_peer(&mut self, config: &ProtocolConfig) { - let client = Arc::new(test_client::new()); - let verifier = self.make_verifier(PeersClient::Full(client.clone()), config); + let test_client_builder = TestClientBuilder::with_default_backend(); + let backend = test_client_builder.backend(); + let (c, longest_chain) = test_client_builder.build_with_longest_chain(); + let client = Arc::new(c); + let verifier = self.make_verifier(PeersClient::Full(client.clone(), backend.clone()), config); let verifier = VerifierAdapter(Arc::new(Mutex::new(Box::new(verifier) as Box<_>))); let (block_import, justification_import, finality_proof_import, finality_proof_request_builder, data) - = self.make_block_import(PeersClient::Full(client.clone())); + = self.make_block_import(PeersClient::Full(client.clone(), backend.clone())); let block_import = BlockImportAdapter(Arc::new(Mutex::new(block_import))); let import_queue = Box::new(BasicQueue::new( @@ -491,7 +523,7 @@ pub trait TestNetFactory: Sized { ..NetworkConfiguration::default() }, chain: client.clone(), - finality_proof_provider: self.make_finality_proof_provider(PeersClient::Full(client.clone())), + finality_proof_provider: self.make_finality_proof_provider(PeersClient::Full(client.clone(), backend.clone())), finality_proof_request_builder, on_demand: None, transaction_pool: Arc::new(EmptyTransactionPool), @@ -512,7 +544,9 @@ pub trait TestNetFactory: Sized { peers.push(Peer { data, - client: PeersClient::Full(client), + client: PeersClient::Full(client, backend.clone()), + select_chain: Some(longest_chain), + backend: Some(backend), imported_blocks_stream, finality_notification_stream, block_import: Box::new(block_import), @@ -527,11 +561,12 @@ pub trait TestNetFactory: Sized { let mut config = config.clone(); config.roles = Roles::LIGHT; - let client = Arc::new(test_client::new_light()); - let verifier = self.make_verifier(PeersClient::Light(client.clone()), &config); + let (c, backend) = test_client::new_light(); + let client = Arc::new(c); + let verifier = self.make_verifier(PeersClient::Light(client.clone(), backend.clone()), &config); let verifier = VerifierAdapter(Arc::new(Mutex::new(Box::new(verifier) as Box<_>))); let (block_import, justification_import, finality_proof_import, finality_proof_request_builder, data) - = self.make_block_import(PeersClient::Light(client.clone())); + = self.make_block_import(PeersClient::Light(client.clone(), backend.clone())); let block_import = BlockImportAdapter(Arc::new(Mutex::new(block_import))); let import_queue = Box::new(BasicQueue::new( @@ -551,7 +586,7 @@ pub trait TestNetFactory: Sized { ..NetworkConfiguration::default() }, chain: client.clone(), - finality_proof_provider: self.make_finality_proof_provider(PeersClient::Light(client.clone())), + finality_proof_provider: self.make_finality_proof_provider(PeersClient::Light(client.clone(), backend.clone())), finality_proof_request_builder, on_demand: None, transaction_pool: Arc::new(EmptyTransactionPool), @@ -573,8 +608,10 @@ pub trait TestNetFactory: Sized { peers.push(Peer { data, verifier, + select_chain: None, + backend: None, block_import: Box::new(block_import), - client: PeersClient::Light(client), + client: PeersClient::Light(client, backend), imported_blocks_stream, finality_notification_stream, network, diff --git a/core/network/src/test/sync.rs b/core/network/src/test/sync.rs index f3a8f0c8ea..6cba21c171 100644 --- a/core/network/src/test/sync.rs +++ b/core/network/src/test/sync.rs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use client::{backend::Backend, blockchain::HeaderBackend}; use crate::config::Roles; use consensus::BlockOrigin; use futures03::TryFutureExt as _; @@ -36,8 +35,8 @@ fn test_ancestor_search_when_common_is(n: usize) { net.peer(2).push_blocks(100, false); net.block_until_sync(&mut runtime); - assert!(net.peer(0).client.as_in_memory_backend().blockchain() - .canon_equals_to(net.peer(1).client.as_in_memory_backend().blockchain())); + let peer1 = &net.peers()[1]; + assert!(net.peers()[0].blockchain_canon_equals(peer1)); } #[test] @@ -156,8 +155,8 @@ fn sync_from_two_peers_works() { net.peer(1).push_blocks(100, false); net.peer(2).push_blocks(100, false); net.block_until_sync(&mut runtime); - assert!(net.peer(0).client.as_in_memory_backend().blockchain() - .equals_to(net.peer(1).client.as_in_memory_backend().blockchain())); + let peer1 = &net.peers()[1]; + assert!(net.peers()[0].blockchain_canon_equals(peer1)); assert!(!net.peer(0).is_major_syncing()); } @@ -170,8 +169,8 @@ fn sync_from_two_peers_with_ancestry_search_works() { net.peer(1).push_blocks(100, false); net.peer(2).push_blocks(100, false); net.block_until_sync(&mut runtime); - assert!(net.peer(0).client.as_in_memory_backend().blockchain() - .canon_equals_to(net.peer(1).client.as_in_memory_backend().blockchain())); + let peer1 = &net.peers()[1]; + assert!(net.peers()[0].blockchain_canon_equals(peer1)); } #[test] @@ -185,8 +184,8 @@ fn ancestry_search_works_when_backoff_is_one() { net.peer(2).push_blocks(2, false); net.block_until_sync(&mut runtime); - assert!(net.peer(0).client.as_in_memory_backend().blockchain() - .canon_equals_to(net.peer(1).client.as_in_memory_backend().blockchain())); + let peer1 = &net.peers()[1]; + assert!(net.peers()[0].blockchain_canon_equals(peer1)); } #[test] @@ -200,8 +199,8 @@ fn ancestry_search_works_when_ancestor_is_genesis() { net.peer(2).push_blocks(100, false); net.block_until_sync(&mut runtime); - assert!(net.peer(0).client.as_in_memory_backend().blockchain() - .canon_equals_to(net.peer(1).client.as_in_memory_backend().blockchain())); + let peer1 = &net.peers()[1]; + assert!(net.peers()[0].blockchain_canon_equals(peer1)); } #[test] @@ -226,8 +225,8 @@ fn sync_long_chain_works() { let mut net = TestNet::new(2); net.peer(1).push_blocks(500, false); net.block_until_sync(&mut runtime); - assert!(net.peer(0).client.as_in_memory_backend().blockchain() - .equals_to(net.peer(1).client.as_in_memory_backend().blockchain())); + let peer1 = &net.peers()[1]; + assert!(net.peers()[0].blockchain_canon_equals(peer1)); } #[test] @@ -238,8 +237,8 @@ fn sync_no_common_longer_chain_fails() { net.peer(0).push_blocks(20, true); net.peer(1).push_blocks(20, false); net.block_until_sync(&mut runtime); - assert!(!net.peer(0).client.as_in_memory_backend().blockchain() - .canon_equals_to(net.peer(1).client.as_in_memory_backend().blockchain())); + let peer1 = &net.peers()[1]; + assert!(!net.peers()[0].blockchain_canon_equals(peer1)); } #[test] @@ -334,11 +333,11 @@ fn sync_after_fork_works() { net.peer(2).push_blocks(1, false); // peer 1 has the best chain - let peer1_chain = net.peer(1).client.as_in_memory_backend().blockchain().clone(); net.block_until_sync(&mut runtime); - assert!(net.peer(0).client.as_in_memory_backend().blockchain().canon_equals_to(&peer1_chain)); - assert!(net.peer(1).client.as_in_memory_backend().blockchain().canon_equals_to(&peer1_chain)); - assert!(net.peer(2).client.as_in_memory_backend().blockchain().canon_equals_to(&peer1_chain)); + let peer1 = &net.peers()[1]; + assert!(net.peers()[0].blockchain_canon_equals(peer1)); + (net.peers()[1].blockchain_canon_equals(peer1)); + (net.peers()[2].blockchain_canon_equals(peer1)); } #[test] @@ -354,8 +353,8 @@ fn syncs_all_forks() { net.block_until_sync(&mut runtime); // Check that all peers have all of the blocks. - assert_eq!(9, net.peer(0).client.as_in_memory_backend().blockchain().blocks_count()); - assert_eq!(9, net.peer(1).client.as_in_memory_backend().blockchain().blocks_count()); + assert_eq!(9, net.peer(0).blocks_count()); + assert_eq!(9, net.peer(1).blocks_count()); } #[test] @@ -368,11 +367,11 @@ fn own_blocks_are_announced() { net.block_until_sync(&mut runtime); - assert_eq!(net.peer(0).client.as_in_memory_backend().blockchain().info().best_number, 1); - assert_eq!(net.peer(1).client.as_in_memory_backend().blockchain().info().best_number, 1); - let peer0_chain = net.peer(0).client.as_in_memory_backend().blockchain().clone(); - assert!(net.peer(1).client.as_in_memory_backend().blockchain().canon_equals_to(&peer0_chain)); - assert!(net.peer(2).client.as_in_memory_backend().blockchain().canon_equals_to(&peer0_chain)); + assert_eq!(net.peer(0).client.info().chain.best_number, 1); + assert_eq!(net.peer(1).client.info().chain.best_number, 1); + let peer0 = &net.peers()[0]; + assert!(net.peers()[1].blockchain_canon_equals(peer0)); + (net.peers()[2].blockchain_canon_equals(peer0)); } #[test] diff --git a/core/rpc/src/chain/tests.rs b/core/rpc/src/chain/tests.rs index 36157df71d..af00f220e4 100644 --- a/core/rpc/src/chain/tests.rs +++ b/core/rpc/src/chain/tests.rs @@ -183,7 +183,7 @@ fn should_return_finalized_hash() { ); // finalize - client.client.finalize_block(BlockId::number(1), None, true).unwrap(); + client.client.finalize_block(BlockId::number(1), None).unwrap(); assert_matches!( client.finalized_head(), Ok(ref x) if x == &client.client.block_hash(1).unwrap().unwrap() @@ -240,7 +240,7 @@ fn should_notify_about_finalized_block() { let builder = api.client.new_block(Default::default()).unwrap(); api.client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); - api.client.finalize_block(BlockId::number(1), None, true).unwrap(); + api.client.finalize_block(BlockId::number(1), None).unwrap(); } // assert initial head sent. diff --git a/core/service/src/builder.rs b/core/service/src/builder.rs index 3b079e549d..fbcfa0f09d 100644 --- a/core/service/src/builder.rs +++ b/core/service/src/builder.rs @@ -57,9 +57,12 @@ use transaction_pool::txpool::{self, ChainApi, Pool as TransactionPool}; /// The order in which the `with_*` methods are called doesn't matter, as the correct binding of /// generics is done when you call `build`. /// -pub struct ServiceBuilder { +pub struct ServiceBuilder +{ config: Configuration, client: Arc, + backend: Arc, keystore: Arc>, fetcher: Option, select_chain: Option, @@ -72,7 +75,7 @@ pub struct ServiceBuilder, } -impl ServiceBuilder<(), (), TCfg, TGen, (), (), (), (), (), (), (), (), ()> +impl ServiceBuilder<(), (), TCfg, TGen, (), (), (), (), (), (), (), (), (), ()> where TGen: Serialize + DeserializeOwned + BuildStorage { /// Start the service builder with a configuration. pub fn new_full, TRtApi, TExecDisp: NativeExecutionDispatch>( @@ -95,7 +98,8 @@ where TGen: Serialize + DeserializeOwned + BuildStorage { (), (), (), - () + (), + client_db::Backend, >, Error> { let keystore = Keystore::open(config.keystore_path.clone(), config.keystore_password.clone())?; @@ -110,17 +114,20 @@ where TGen: Serialize + DeserializeOwned + BuildStorage { let executor = NativeExecutor::::new(config.default_heap_pages); - let client = Arc::new(client_db::new_client( + let (client, backend) = client_db::new_client( db_settings, executor, &config.chain_spec, config.execution_strategies.clone(), Some(keystore.clone()), - )?); + )?; + + let client = Arc::new(client); Ok(ServiceBuilder { config, client, + backend, keystore, fetcher: None, select_chain: None, @@ -177,7 +184,8 @@ where TGen: Serialize + DeserializeOwned + BuildStorage { (), (), (), - () + (), + client::light::backend::Backend, network::OnDemand, Blake2Hasher>, >, Error> { let keystore = Keystore::open(config.keystore_path.clone(), config.keystore_password.clone())?; @@ -196,12 +204,13 @@ where TGen: Serialize + DeserializeOwned + BuildStorage { let light_blockchain = client::light::new_light_blockchain(db_storage); let fetch_checker = Arc::new(client::light::new_fetch_checker(light_blockchain.clone(), executor.clone())); let fetcher = Arc::new(network::OnDemand::new(fetch_checker)); - let client_backend = client::light::new_light_backend(light_blockchain, fetcher.clone()); - let client = client::light::new_light(client_backend, fetcher.clone(), &config.chain_spec, executor)?; + let backend = client::light::new_light_backend(light_blockchain, fetcher.clone()); + let client = client::light::new_light(backend.clone(), fetcher.clone(), &config.chain_spec, executor)?; Ok(ServiceBuilder { config, client: Arc::new(client), + backend, keystore, fetcher: Some(fetcher), select_chain: None, @@ -216,14 +225,19 @@ where TGen: Serialize + DeserializeOwned + BuildStorage { } } -impl - ServiceBuilder { +impl + ServiceBuilder { /// Returns a reference to the client that was stored in this builder. pub fn client(&self) -> &Arc { &self.client } + /// Returns a reference to the backend that was used in this builder. + pub fn backend(&self) -> &Arc { + &self.backend + } + /// Returns a reference to the select-chain that was stored in this builder. pub fn select_chain(&self) -> Option<&TSc> { self.select_chain.as_ref() @@ -231,15 +245,16 @@ impl( - mut self, - select_chain_builder: impl FnOnce(&mut Configuration, Arc) -> Result, Error> + self, + select_chain_builder: impl FnOnce(&Configuration, &Arc) -> Result, Error> ) -> Result, Error> { - let select_chain = select_chain_builder(&mut self.config, self.client.clone())?; + TNetP, TExPool, TRpc, Backend>, Error> { + let select_chain = select_chain_builder(&self.config, &self.backend)?; Ok(ServiceBuilder { config: self.config, client: self.client, + backend: self.backend, keystore: self.keystore, fetcher: self.fetcher, select_chain, @@ -256,22 +271,22 @@ impl( self, - builder: impl FnOnce(&mut Configuration, Arc) -> Result + builder: impl FnOnce(&Configuration, &Arc) -> Result ) -> Result, Error> { - self.with_opt_select_chain(|cfg, cl| builder(cfg, cl).map(Option::Some)) + TNetP, TExPool, TRpc, Backend>, Error> { + self.with_opt_select_chain(|cfg, b| builder(cfg, b).map(Option::Some)) } /// Defines which import queue to use. pub fn with_import_queue( - mut self, - builder: impl FnOnce(&mut Configuration, Arc, Option, Arc) + self, + builder: impl FnOnce(&Configuration, Arc, Option, Arc) -> Result ) -> Result, Error> + TNetP, TExPool, TRpc, Backend>, Error> where TSc: Clone { let import_queue = builder( - &mut self.config, + &self.config, self.client.clone(), self.select_chain.clone(), self.transaction_pool.clone() @@ -280,6 +295,7 @@ impl) -> Result ) -> Result, Error> { + UNetP, TExPool, TRpc, Backend>, Error> { let network_protocol = network_protocol_builder(&self.config)?; Ok(ServiceBuilder { config: self.config, client: self.client, + backend: self.backend, keystore: self.keystore, fetcher: self.fetcher, select_chain: self.select_chain, @@ -320,7 +337,7 @@ impl) -> Result>>, Error> + builder: impl FnOnce(Arc, Arc) -> Result>>, Error> ) -> Result>, + Arc>, TNetP, TExPool, - TRpc + TRpc, + Backend, >, Error> { - let finality_proof_provider = builder(self.client.clone())?; + let finality_proof_provider = builder(self.client.clone(), self.backend.clone())?; Ok(ServiceBuilder { config: self.config, client: self.client, + backend: self.backend, keystore: self.keystore, fetcher: self.fetcher, select_chain: self.select_chain, @@ -357,7 +376,7 @@ impl) -> Result>, Error> + build: impl FnOnce(Arc, Arc) -> Result>, Error> ) -> Result>, + Arc>, TNetP, TExPool, - TRpc + TRpc, + Backend, >, Error> { - self.with_opt_finality_proof_provider(|client| build(client).map(Option::Some)) + self.with_opt_finality_proof_provider(|client, backend| build(client, backend).map(Option::Some)) } /// Defines which import queue to use. pub fn with_import_queue_and_opt_fprb( - mut self, - builder: impl FnOnce(&mut Configuration, Arc, Option, Arc) + self, + builder: impl FnOnce(&Configuration, Arc, Arc, Option, Arc) -> Result<(UImpQu, Option), Error> ) -> Result, Error> + TNetP, TExPool, TRpc, Backend>, Error> where TSc: Clone { let (import_queue, fprb) = builder( - &mut self.config, + &self.config, self.client.clone(), + self.backend.clone(), self.select_chain.clone(), self.transaction_pool.clone() )?; @@ -394,6 +415,7 @@ impl( self, - builder: impl FnOnce(&mut Configuration, Arc, Option, Arc) + builder: impl FnOnce(&Configuration, Arc, Arc, Option, Arc) -> Result<(UImpQu, UFprb), Error> ) -> Result, Error> + TNetP, TExPool, TRpc, Backend>, Error> where TSc: Clone { - self.with_import_queue_and_opt_fprb(|cfg, cl, sc, tx| builder(cfg, cl, sc, tx).map(|(q, f)| (q, Some(f)))) + self.with_import_queue_and_opt_fprb(|cfg, cl, b, sc, tx| builder(cfg, cl, b, sc, tx).map(|(q, f)| (q, Some(f)))) } /// Defines which transaction pool to use. @@ -423,12 +445,13 @@ impl) -> Result ) -> Result, Error> { + TNetP, UExPool, TRpc, Backend>, Error> { let transaction_pool = transaction_pool_builder(self.config.transaction_pool.clone(), self.client.clone())?; Ok(ServiceBuilder { config: self.config, client: self.client, + backend: self.backend, keystore: self.keystore, fetcher: self.fetcher, select_chain: self.select_chain, @@ -447,12 +470,13 @@ impl, Arc) -> URpc ) -> Result, Error> { + TNetP, TExPool, URpc, Backend>, Error> { let rpc_extensions = rpc_ext_builder(self.client.clone(), self.transaction_pool.clone()); Ok(ServiceBuilder { config: self.config, client: self.client, + backend: self.backend, keystore: self.keystore, fetcher: self.fetcher, select_chain: self.select_chain, @@ -508,9 +532,9 @@ pub trait ServiceBuilderRevert { ) -> Result<(), Error>; } -impl +impl ServiceBuilderImport for ServiceBuilder, - TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc> + TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, Backend> where TBl: BlockT::Out>, TBackend: 'static + client::backend::Backend + Send, @@ -532,7 +556,7 @@ where impl ServiceBuilderExport for ServiceBuilder, - TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc> + TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TBackend> where TBl: BlockT::Out>, TBackend: 'static + client::backend::Backend + Send, @@ -555,7 +579,7 @@ where impl ServiceBuilderRevert for ServiceBuilder, - TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc> + TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TBackend> where TBl: BlockT::Out>, TBackend: 'static + client::backend::Backend + Send, @@ -583,10 +607,11 @@ ServiceBuilder< TSc, TImpQu, BoxFinalityProofRequestBuilder, - Arc>, + Arc>, TNetP, TransactionPool, - TRpc + TRpc, + TBackend > where Client: ProvideRuntimeApi, as ProvideRuntimeApi>::Api: @@ -608,7 +633,6 @@ ServiceBuilder< { /// Builds the service. pub fn build(self) -> Result, TBl, Client, TSc, @@ -629,6 +653,7 @@ ServiceBuilder< let ( client, fetcher, + backend, keystore, select_chain, import_queue, @@ -640,6 +665,7 @@ ServiceBuilder< ) = ( self.client, self.fetcher, + self.backend, self.keystore, self.select_chain, self.import_queue, @@ -657,6 +683,7 @@ ServiceBuilder< Ok(( client, fetcher, + backend, keystore, select_chain, import_queue, diff --git a/core/service/src/lib.rs b/core/service/src/lib.rs index a19121188a..ad359767b2 100644 --- a/core/service/src/lib.rs +++ b/core/service/src/lib.rs @@ -66,7 +66,7 @@ pub use futures::future::Executor; const DEFAULT_PROTOCOL_ID: &str = "sup"; /// Substrate service. -pub struct NewService { +pub struct NewService { client: Arc, select_chain: Option, network: Arc, @@ -91,8 +91,6 @@ pub struct NewService { /// If spawning a background task is not possible, we instead push the task into this `Vec`. /// The elements must then be polled manually. to_poll: Vec + Send>>, - /// Configuration of this Service - config: TCfg, rpc_handlers: rpc_servers::RpcHandler, _rpc: Box, _telemetry: Option, @@ -148,6 +146,7 @@ macro_rules! new_impl { let ( client, on_demand, + backend, keystore, select_chain, import_queue, @@ -156,7 +155,7 @@ macro_rules! new_impl { network_protocol, transaction_pool, rpc_extensions - ) = $build_components(&mut $config)?; + ) = $build_components(&$config)?; let import_queue = Box::new(import_queue); let chain_info = client.info().chain; @@ -206,8 +205,7 @@ macro_rules! new_impl { let network = network_mut.service().clone(); let network_status_sinks = Arc::new(Mutex::new(Vec::new())); - #[allow(deprecated)] - let offchain_storage = client.backend().offchain_storage(); + let offchain_storage = backend.offchain_storage(); let offchain_workers = match ($config.offchain_worker, offchain_storage) { (true, Some(db)) => { Some(Arc::new(offchain::OffchainWorkers::new(client.clone(), db))) @@ -301,9 +299,7 @@ macro_rules! new_impl { let bandwidth_download = net_status.average_download_per_sec; let bandwidth_upload = net_status.average_upload_per_sec; - #[allow(deprecated)] - let backend = (*client_).backend(); - let used_state_cache_size = match backend.used_state_cache_size(){ + let used_state_cache_size = match info.used_state_cache_size { Some(size) => size, None => 0, }; @@ -426,7 +422,6 @@ macro_rules! new_impl { to_spawn_tx, to_spawn_rx, to_poll: Vec::new(), - $config, rpc_handlers, _rpc: rpc, _telemetry: telemetry, @@ -451,8 +446,6 @@ pub trait AbstractService: 'static + Future + type CallExecutor: 'static + client::CallExecutor + Send + Sync + Clone; /// API that the runtime provides. type RuntimeApi: Send + Sync; - /// Configuration struct of the service. - type Config; /// Chain selection algorithm. type SelectChain: consensus_common::SelectChain; /// API of the transaction pool. @@ -463,12 +456,6 @@ pub trait AbstractService: 'static + Future + /// Get event stream for telemetry connection established events. fn telemetry_on_connect_stream(&self) -> mpsc::UnboundedReceiver<()>; - /// Returns the configuration passed on construction. - fn config(&self) -> &Self::Config; - - /// Returns the configuration passed on construction. - fn config_mut(&mut self) -> &mut Self::Config; - /// return a shared instance of Telemetry (if enabled) fn telemetry(&self) -> Option; @@ -516,10 +503,10 @@ pub trait AbstractService: 'static + Future + fn on_exit(&self) -> ::exit_future::Exit; } -impl AbstractService for - NewService, TSc, NetworkStatus, +impl AbstractService for + NewService, TSc, NetworkStatus, NetworkService, TransactionPool, TOc> -where TCfg: 'static + Send, +where TBl: BlockT, TBackend: 'static + client::backend::Backend, TExec: 'static + client::CallExecutor + Send + Sync + Clone, @@ -533,19 +520,10 @@ where TCfg: 'static + Send, type Backend = TBackend; type CallExecutor = TExec; type RuntimeApi = TRtApi; - type Config = TCfg; type SelectChain = TSc; type TransactionPoolApi = TExPoolApi; type NetworkSpecialization = TNetSpec; - fn config(&self) -> &Self::Config { - &self.config - } - - fn config_mut(&mut self) -> &mut Self::Config { - &mut self.config - } - fn telemetry_on_connect_stream(&self) -> mpsc::UnboundedReceiver<()> { let (sink, stream) = mpsc::unbounded(); self._telemetry_on_connect_sinks.lock().push(sink); @@ -611,8 +589,9 @@ where TCfg: 'static + Send, } } -impl Future for -NewService { +impl Future for + NewService +{ type Item = (); type Error = Error; @@ -643,8 +622,9 @@ NewService { } } -impl Executor + Send>> for -NewService { +impl Executor + Send>> for + NewService +{ fn execute( &self, future: Box + Send> @@ -787,8 +767,9 @@ pub struct NetworkStatus { pub average_upload_per_sec: u64, } -impl Drop for -NewService { +impl Drop for + NewService +{ fn drop(&mut self) { debug!(target: "service", "Substrate service shutdown"); if let Some(signal) = self.signal.take() { diff --git a/core/test-client/src/client_ext.rs b/core/test-client/src/client_ext.rs index b29a7db471..7d3d7301c5 100644 --- a/core/test-client/src/client_ext.rs +++ b/core/test-client/src/client_ext.rs @@ -16,7 +16,7 @@ //! Client extension for tests. -use client::{self, Client}; +use client::{self, Client, backend::Finalizer}; use consensus::{ BlockImportParams, BlockImport, BlockOrigin, Error as ConsensusError, ForkChoiceStrategy, @@ -126,7 +126,7 @@ impl ClientExt for Client id: BlockId, justification: Option, ) -> client::error::Result<()> { - self.finalize_block(id, justification, true) + Finalizer::finalize_block(self, id, justification, true) } fn genesis_hash(&self) -> ::Hash { diff --git a/core/test-client/src/lib.rs b/core/test-client/src/lib.rs index 79e1027b95..17e2670846 100644 --- a/core/test-client/src/lib.rs +++ b/core/test-client/src/lib.rs @@ -100,6 +100,11 @@ impl TestClientBuilder< let backend = Arc::new(Backend::new_test(std::u32::MAX, std::u64::MAX)); Self::with_backend(backend) } + + /// Give access to the underlying backend of these clients + pub fn backend(&self) -> Arc> { + self.backend.clone() + } } impl TestClientBuilder { diff --git a/core/test-runtime/client/src/lib.rs b/core/test-runtime/client/src/lib.rs index ad5badf8bf..767c862083 100644 --- a/core/test-runtime/client/src/lib.rs +++ b/core/test-runtime/client/src/lib.rs @@ -22,6 +22,7 @@ pub mod trait_tests; mod block_builder_ext; +use std::sync::Arc; pub use block_builder_ext::BlockBuilderExt; pub use generic_test_client::*; pub use runtime; @@ -228,8 +229,10 @@ pub fn new() -> Client { } /// Creates new light client instance used for tests. -pub fn new_light() -> client::Client { - use std::sync::Arc; +pub fn new_light() -> ( + client::Client, + Arc, +) { let storage = client_db::light::LightStorage::new_test(); let blockchain = Arc::new(client::light::blockchain::Blockchain::new(storage)); @@ -247,7 +250,10 @@ pub fn new_light() -> client::Client($config)? - .with_select_chain(|_config, client| { - #[allow(deprecated)] - Ok(substrate_client::LongestChain::new(client.backend().clone())) + .with_select_chain(|_config, backend| { + Ok(substrate_client::LongestChain::new(backend.clone())) })? .with_transaction_pool(|config, client| Ok(transaction_pool::txpool::Pool::new(config, transaction_pool::ChainApi::new(client))) @@ -81,11 +80,16 @@ pub fn new_full(config: Configuration Result { + let is_authority = config.roles.is_authority(); + let name = config.name.clone(); + let disable_grandpa = config.disable_grandpa; + let force_authoring = config.force_authoring; + let (builder, mut import_setup, inherent_data_providers, mut tasks_to_spawn) = new_full_start!(config); let service = builder.with_network_protocol(|_| Ok(NodeProtocol::new()))? - .with_finality_proof_provider(|client| - Ok(Arc::new(GrandpaFinalityProofProvider::new(client.clone(), client)) as _) + .with_finality_proof_provider(|client, backend| + Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, client)) as _) )? .build()?; @@ -104,7 +108,7 @@ pub fn new_full(config: Configuration(config: Configuration(config: Configuration { // start the lightweight GRANDPA observer service.spawn_task(Box::new(grandpa::run_grandpa_observer( - config, + grandpa_config, link_half, service.network(), service.on_exit(), @@ -155,8 +159,8 @@ pub fn new_full(config: Configuration { // start the full GRANDPA voter - let grandpa_config = grandpa::GrandpaParams { - config: config, + let voter_config = grandpa::GrandpaParams { + config: grandpa_config, link: link_half, network: service.network(), inherent_data_providers: inherent_data_providers.clone(), @@ -166,7 +170,7 @@ pub fn new_full(config: Configuration { grandpa::setup_disabled_grandpa( @@ -187,21 +191,19 @@ pub fn new_light(config: Configuration(config)? - .with_select_chain(|_config, client| { - #[allow(deprecated)] - Ok(LongestChain::new(client.backend().clone())) + .with_select_chain(|_config, backend| { + Ok(LongestChain::new(backend.clone())) })? .with_transaction_pool(|config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) )? - .with_import_queue_and_fprb(|_config, client, _select_chain, transaction_pool| { - #[allow(deprecated)] - let fetch_checker = client.backend().blockchain().fetcher() + .with_import_queue_and_fprb(|_config, client, backend, _select_chain, transaction_pool| { + let fetch_checker = backend.blockchain().fetcher() .upgrade() .map(|fetcher| fetcher.checker().clone()) .ok_or_else(|| "Trying to start light import queue without active fetch checker")?; let block_import = grandpa::light_block_import::<_, _, _, RuntimeApi, _>( - client.clone(), Arc::new(fetch_checker), client.clone() + client.clone(), backend, Arc::new(fetch_checker), client.clone() )?; let finality_proof_import = block_import.clone(); @@ -223,8 +225,8 @@ pub fn new_light(config: Configuration($config)? - .with_select_chain(|_config, client| { - #[allow(deprecated)] - Ok(client::LongestChain::new(client.backend().clone())) + .with_select_chain(|_config, backend| { + Ok(client::LongestChain::new(backend.clone())) })? .with_transaction_pool(|config, client| Ok(transaction_pool::txpool::Pool::new(config, transaction_pool::ChainApi::new(client))) @@ -105,11 +104,23 @@ macro_rules! new_full { ($config:expr) => {{ use futures::Future; + let ( + is_authority, + force_authoring, + name, + disable_grandpa + ) = ( + $config.roles.is_authority(), + $config.force_authoring, + $config.name.clone(), + $config.disable_grandpa + ); + let (builder, mut import_setup, inherent_data_providers, mut tasks_to_spawn) = new_full_start!($config); let service = builder.with_network_protocol(|_| Ok(crate::service::NodeProtocol::new()))? - .with_finality_proof_provider(|client| - Ok(Arc::new(grandpa::FinalityProofProvider::new(client.clone(), client)) as _) + .with_finality_proof_provider(|client, backend| + Ok(Arc::new(grandpa::FinalityProofProvider::new(backend, client)) as _) )? .build()?; @@ -125,7 +136,7 @@ macro_rules! new_full { ); } - if service.config().roles.is_authority() { + if is_authority { let proposer = substrate_basic_authorship::ProposerFactory { client: service.client(), transaction_pool: service.transaction_pool(), @@ -144,7 +155,7 @@ macro_rules! new_full { env: proposer, sync_oracle: service.network(), inherent_data_providers: inherent_data_providers.clone(), - force_authoring: service.config().force_authoring, + force_authoring: force_authoring, time_source: babe_link, }; @@ -157,11 +168,11 @@ macro_rules! new_full { // FIXME #1578 make this available through chainspec gossip_duration: std::time::Duration::from_millis(333), justification_period: 4096, - name: Some(service.config().name.clone()), + name: Some(name), keystore: Some(service.keystore()), }; - match (service.config().roles.is_authority(), service.config().disable_grandpa) { + match (is_authority, disable_grandpa) { (false, false) => { // start the lightweight GRANDPA observer service.spawn_task(Box::new(grandpa::run_grandpa_observer( @@ -211,21 +222,19 @@ pub fn new_light(config: Configuration(config)? - .with_select_chain(|_config, client| { - #[allow(deprecated)] - Ok(LongestChain::new(client.backend().clone())) + .with_select_chain(|_config, backend| { + Ok(LongestChain::new(backend.clone())) })? .with_transaction_pool(|config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) )? - .with_import_queue_and_fprb(|_config, client, _select_chain, transaction_pool| { - #[allow(deprecated)] - let fetch_checker = client.backend().blockchain().fetcher() + .with_import_queue_and_fprb(|_config, client, backend, _select_chain, transaction_pool| { + let fetch_checker = backend.blockchain().fetcher() .upgrade() .map(|fetcher| fetcher.checker().clone()) .ok_or_else(|| "Trying to start light import queue without active fetch checker")?; let block_import = grandpa::light_block_import::<_, _, _, RuntimeApi, _>( - client.clone(), Arc::new(fetch_checker), client.clone() + client.clone(), backend, Arc::new(fetch_checker), client.clone() )?; let finality_proof_import = block_import.clone(); @@ -248,8 +257,8 @@ pub fn new_light(config: Configuration Date: Sun, 1 Sep 2019 02:19:04 +0200 Subject: [PATCH 043/275] Submit (& sign) extrinsics from the runtime. (#3514) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Abstract constructing extrinsic and signing. * Initial impl of signer. * Implement get payload. * Clean up the code. * Improve docs. * Bump version. * Update core/sr-primitives/src/generic/unchecked_extrinsic.rs Co-Authored-By: Bastian Köcher * Fix tests & address grumbles. * Fix build. * Fix runtime tests. * Fix bound test. * Fix bound test. --- core/sr-primitives/src/generic/mod.rs | 2 +- .../src/generic/unchecked_extrinsic.rs | 82 +++++++++-- core/sr-primitives/src/lib.rs | 7 +- core/sr-primitives/src/testing.rs | 6 +- core/sr-primitives/src/traits.rs | 17 ++- core/test-runtime/src/lib.rs | 3 +- node/cli/src/service.rs | 16 ++- node/runtime/src/lib.rs | 63 +++++++- srml/authority-discovery/src/lib.rs | 6 +- srml/balances/src/lib.rs | 1 - srml/im-online/src/lib.rs | 27 ++-- srml/support/src/inherent.rs | 8 +- srml/system/src/lib.rs | 29 ++-- srml/system/src/offchain.rs | 135 ++++++++++++++++++ subkey/src/main.rs | 15 +- 15 files changed, 346 insertions(+), 71 deletions(-) create mode 100644 srml/system/src/offchain.rs diff --git a/core/sr-primitives/src/generic/mod.rs b/core/sr-primitives/src/generic/mod.rs index 1511753d2c..0138a15aee 100644 --- a/core/sr-primitives/src/generic/mod.rs +++ b/core/sr-primitives/src/generic/mod.rs @@ -27,7 +27,7 @@ mod digest; #[cfg(test)] mod tests; -pub use self::unchecked_extrinsic::UncheckedExtrinsic; +pub use self::unchecked_extrinsic::{UncheckedExtrinsic, SignedPayload}; pub use self::era::{Era, Phase}; pub use self::checked_extrinsic::CheckedExtrinsic; pub use self::header::Header; diff --git a/core/sr-primitives/src/generic/unchecked_extrinsic.rs b/core/sr-primitives/src/generic/unchecked_extrinsic.rs index cb9330cfaa..aebf80edc6 100644 --- a/core/sr-primitives/src/generic/unchecked_extrinsic.rs +++ b/core/sr-primitives/src/generic/unchecked_extrinsic.rs @@ -72,12 +72,22 @@ impl Extrinsic { type Call = Call; + type SignaturePayload = ( + Address, + Signature, + Extra, + ); + fn is_signed(&self) -> Option { Some(self.signature.is_some()) } - fn new_unsigned(function: Call) -> Option { - Some(UncheckedExtrinsic::new_unsigned(function)) + fn new(function: Call, signed_data: Option) -> Option { + Some(if let Some((address, signature, extra)) = signed_data { + UncheckedExtrinsic::new_signed(function, address, signature, extra) + } else { + UncheckedExtrinsic::new_unsigned(function) + }) } } @@ -98,21 +108,18 @@ where fn check(self, lookup: &Lookup) -> Result { Ok(match self.signature { Some((signed, signature, extra)) => { - let additional_signed = extra.additional_signed()?; - let raw_payload = (self.function, extra, additional_signed); let signed = lookup.lookup(signed)?; + let raw_payload = SignedPayload::new(self.function, extra)?; if !raw_payload.using_encoded(|payload| { - if payload.len() > 256 { - signature.verify(&blake2_256(payload)[..], &signed) - } else { - signature.verify(payload, &signed) - } + signature.verify(payload, &signed) }) { return Err(crate::BAD_SIGNATURE) } + + let (function, extra, _) = raw_payload.deconstruct(); CheckedExtrinsic { - signed: Some((signed, raw_payload.1)), - function: raw_payload.0, + signed: Some((signed, extra)), + function, } } None => CheckedExtrinsic { @@ -123,6 +130,59 @@ where } } +/// A payload that has been signed for an unchecked extrinsics. +/// +/// Note that the payload that we sign to produce unchecked extrinsic signature +/// is going to be different than the `SignaturePayload` - so the thing the extrinsic +/// actually contains. +pub struct SignedPayload(( + Call, + Extra, + Extra::AdditionalSigned, +)); + +impl SignedPayload where + Call: Encode, + Extra: SignedExtension, +{ + /// Create new `SignedPayload`. + /// + /// This function may fail if `additional_signed` of `Extra` is not available. + pub fn new(call: Call, extra: Extra) -> Result { + let additional_signed = extra.additional_signed()?; + let raw_payload = (call, extra, additional_signed); + Ok(Self(raw_payload)) + } + + /// Create new `SignedPayload` from raw components. + pub fn from_raw(call: Call, extra: Extra, additional_signed: Extra::AdditionalSigned) -> Self { + Self((call, extra, additional_signed)) + } + + /// Deconstruct the payload into it's components. + pub fn deconstruct(self) -> (Call, Extra, Extra::AdditionalSigned) { + self.0 + } +} + +impl Encode for SignedPayload where + Call: Encode, + Extra: SignedExtension, +{ + /// Get an encoded version of this payload. + /// + /// Payloads longer than 256 bytes are going to be `blake2_256`-hashed. + fn using_encoded R>(&self, f: F) -> R { + self.0.using_encoded(|payload| { + if payload.len() > 256 { + f(&blake2_256(payload)[..]) + } else { + f(payload) + } + }) + } +} + impl Decode for UncheckedExtrinsic where diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index 41dac41f79..454f1cdfb8 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -847,12 +847,7 @@ impl<'a> ::serde::Deserialize<'a> for OpaqueExtrinsic { impl traits::Extrinsic for OpaqueExtrinsic { type Call = (); - - fn is_signed(&self) -> Option { - None - } - - fn new_unsigned(_call: Self::Call) -> Option { None } + type SignaturePayload = (); } #[cfg(test)] diff --git a/core/sr-primitives/src/testing.rs b/core/sr-primitives/src/testing.rs index c91c8366c1..ed5ac7fa45 100644 --- a/core/sr-primitives/src/testing.rs +++ b/core/sr-primitives/src/testing.rs @@ -187,6 +187,7 @@ pub struct ExtrinsicWrapper(Xt); impl traits::Extrinsic for ExtrinsicWrapper { type Call = (); + type SignaturePayload = (); fn is_signed(&self) -> Option { None @@ -274,13 +275,14 @@ impl Checkable for TestXt traits::Extrinsic for TestXt { type Call = Call; + type SignaturePayload = (u64, Extra); fn is_signed(&self) -> Option { Some(self.0.is_some()) } - fn new_unsigned(_c: Call) -> Option { - None + fn new(c: Call, sig: Option) -> Option { + Some(TestXt(sig, c)) } } diff --git a/core/sr-primitives/src/traits.rs b/core/sr-primitives/src/traits.rs index 3dc1649e49..fe3d67268f 100644 --- a/core/sr-primitives/src/traits.rs +++ b/core/sr-primitives/src/traits.rs @@ -743,13 +743,24 @@ pub trait Extrinsic: Sized { /// The function call. type Call; + /// The payload we carry for signed extrinsics. + /// + /// Usually it will contain a `Signature` and + /// may include some additional data that are specific to signed + /// extrinsics. + type SignaturePayload; + /// Is this `Extrinsic` signed? /// If no information are available about signed/unsigned, `None` should be returned. fn is_signed(&self) -> Option { None } - /// New instance of an unsigned extrinsic aka "inherent". `None` if this is an opaque - /// extrinsic type. - fn new_unsigned(_call: Self::Call) -> Option { None } + /// Create new instance of the extrinsic. + /// + /// Extrinsics can be split into: + /// 1. Inherents (no signature; created by validators during block production) + /// 2. Unsigned Transactions (no signature; represent "system calls" or other special kinds of calls) + /// 3. Signed Transactions (with signature; a regular transactions with known origin) + fn new(_call: Self::Call, _signed_data: Option) -> Option { None } } /// Extract the hashing type for a block. diff --git a/core/test-runtime/src/lib.rs b/core/test-runtime/src/lib.rs index 55b6ad9b5f..f023fd89e1 100644 --- a/core/test-runtime/src/lib.rs +++ b/core/test-runtime/src/lib.rs @@ -141,6 +141,7 @@ impl BlindCheckable for Extrinsic { impl ExtrinsicT for Extrinsic { type Call = Extrinsic; + type SignaturePayload = (); fn is_signed(&self) -> Option { if let Extrinsic::IncludeData(_) = *self { @@ -150,7 +151,7 @@ impl ExtrinsicT for Extrinsic { } } - fn new_unsigned(call: Self::Call) -> Option { + fn new(call: Self::Call, _signature_payload: Option) -> Option { Some(call) } } diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index da78d74a87..bb1d77b285 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -298,7 +298,7 @@ mod tests { crypto::Pair as CryptoPair, blake2_256, sr25519::Public as AddressPublic, H256, }; - use sr_primitives::{generic::{BlockId, Era, Digest}, traits::Block, OpaqueExtrinsic}; + use sr_primitives::{generic::{BlockId, Era, Digest, SignedPayload}, traits::Block, OpaqueExtrinsic}; use timestamp; use finality_tracker; use keyring::AccountKeyring; @@ -471,15 +471,17 @@ mod tests { let check_weight = system::CheckWeight::new(); let take_fees = balances::TakeFees::from(0); let extra = (check_version, check_genesis, check_era, check_nonce, check_weight, take_fees); - - let raw_payload = (function, extra.clone(), version, genesis_hash, genesis_hash); - let signature = raw_payload.using_encoded(|payload| if payload.len() > 256 { - signer.sign(&blake2_256(payload)[..]) - } else { + let raw_payload = SignedPayload::from_raw( + function, + extra, + (version, genesis_hash, genesis_hash, (), (), ()) + ); + let signature = raw_payload.using_encoded(|payload| { signer.sign(payload) }); + let (function, extra, _) = raw_payload.deconstruct(); let xt = UncheckedExtrinsic::new_signed( - raw_payload.0, + function, from.into(), signature.into(), extra, diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 6fec9abe7a..5dc8d02ecc 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -39,7 +39,7 @@ use sr_primitives::{ApplyResult, impl_opaque_keys, generic, create_runtime_str, use sr_primitives::transaction_validity::TransactionValidity; use sr_primitives::weights::Weight; use sr_primitives::traits::{ - BlakeTwo256, Block as BlockT, DigestFor, NumberFor, StaticLookup, + self, BlakeTwo256, Block as BlockT, DigestFor, NumberFor, StaticLookup, SaturatedConversion, }; use version::RuntimeVersion; use elections::VoteIndex; @@ -48,6 +48,7 @@ use version::NativeVersion; use primitives::OpaqueMetadata; use grandpa::{AuthorityId as GrandpaId, AuthorityWeight as GrandpaWeight}; use im_online::sr25519::{AuthorityId as ImOnlineId}; +use system::offchain::TransactionSubmitter; #[cfg(any(feature = "std", test))] pub use sr_primitives::BuildStorage; @@ -80,7 +81,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 154, - impl_version: 157, + impl_version: 158, apis: RUNTIME_API_VERSIONS, }; @@ -392,11 +393,13 @@ impl sudo::Trait for Runtime { type Proposal = Call; } +type SubmitTransaction = TransactionSubmitter; + impl im_online::Trait for Runtime { type AuthorityId = ImOnlineId; type Call = Call; type Event = Event; - type UncheckedExtrinsic = UncheckedExtrinsic; + type SubmitTransaction = SubmitTransaction; type ReportUnresponsiveness = Offences; type CurrentElectedSet = staking::CurrentElectedStashAccounts; } @@ -424,6 +427,33 @@ impl finality_tracker::Trait for Runtime { type ReportLatency = ReportLatency; } +impl system::offchain::CreateTransaction for Runtime { + type Signature = Signature; + + fn create_transaction>( + call: Call, + account: AccountId, + index: Index, + ) -> Option<(Call, ::SignaturePayload)> { + let period = 1 << 8; + let current_block = System::block_number().saturated_into::(); + let tip = 0; + let extra: SignedExtra = ( + system::CheckVersion::::new(), + system::CheckGenesis::::new(), + system::CheckEra::::from(generic::Era::mortal(period, current_block)), + system::CheckNonce::::from(index), + system::CheckWeight::::new(), + balances::TakeFees::::from(tip), + ); + let raw_payload = SignedPayload::new(call, extra).ok()?; + let signature = F::sign(account.clone(), &raw_payload)?; + let address = Indices::unlookup(account); + let (call, extra, _) = raw_payload.deconstruct(); + Some((call, (address, signature, extra))) + } +} + construct_runtime!( pub enum Runtime where Block = Block, @@ -475,6 +505,8 @@ pub type SignedExtra = ( ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; +/// The payload being signed in transactions. +pub type SignedPayload = generic::SignedPayload; /// Extrinsic type that has already been checked. pub type CheckedExtrinsic = generic::CheckedExtrinsic; /// Executive: handles dispatch to the various modules. @@ -609,3 +641,28 @@ impl_runtime_apis! { } } } + +#[cfg(test)] +mod tests { + use super::*; + use sr_primitives::app_crypto::RuntimeAppPublic; + use system::offchain::SubmitSignedTransaction; + + fn is_submit_signed_transaction(_arg: T) where + T: SubmitSignedTransaction< + Runtime, + Call, + Extrinsic=UncheckedExtrinsic, + CreateTransaction=Runtime, + Signer=Signer, + >, + Signer: RuntimeAppPublic + From, + Signer::Signature: Into, + {} + + #[test] + fn validate_bounds() { + let x = SubmitTransaction::default(); + is_submit_signed_transaction(x); + } +} diff --git a/srml/authority-discovery/src/lib.rs b/srml/authority-discovery/src/lib.rs index 106f0cfa36..d52b225d2c 100644 --- a/srml/authority-discovery/src/lib.rs +++ b/srml/authority-discovery/src/lib.rs @@ -186,7 +186,11 @@ mod tests { type AuthorityId = AuthorityId; type Call = im_online::Call; type Event = (); - type UncheckedExtrinsic = UncheckedExtrinsic<(), im_online::Call, (), ()>; + type SubmitTransaction = system::offchain::TransactionSubmitter< + (), + im_online::Call, + UncheckedExtrinsic<(), im_online::Call, (), ()>, + >; type ReportUnresponsiveness = (); type CurrentElectedSet = DummyCurrentElectedSet; } diff --git a/srml/balances/src/lib.rs b/srml/balances/src/lib.rs index e37ce5c4de..289dfbf93f 100644 --- a/srml/balances/src/lib.rs +++ b/srml/balances/src/lib.rs @@ -1187,7 +1187,6 @@ pub struct TakeFees, I: Instance = DefaultInstance>(#[codec(compact) impl, I: Instance> TakeFees { /// utility constructor. Used only in client/factory code. - #[cfg(feature = "std")] pub fn from(fee: T::Balance) -> Self { Self(fee) } diff --git a/srml/im-online/src/lib.rs b/srml/im-online/src/lib.rs index 307c7169d1..701a9e753d 100644 --- a/srml/im-online/src/lib.rs +++ b/srml/im-online/src/lib.rs @@ -75,7 +75,7 @@ use session::historical::IdentificationTuple; use sr_io::Printable; use sr_primitives::{ Perbill, ApplyError, - traits::{Convert, Extrinsic as ExtrinsicT, Member}, + traits::{Convert, Member}, transaction_validity::{TransactionValidity, TransactionLongevity, ValidTransaction}, }; use sr_staking_primitives::{ @@ -87,11 +87,18 @@ use srml_support::{ Parameter, StorageValue, StorageDoubleMap, }; use system::ensure_none; +use system::offchain::SubmitUnsignedTransaction; pub mod sr25519 { mod app_sr25519 { use app_crypto::{app_crypto, key_types::IM_ONLINE, sr25519}; app_crypto!(sr25519, IM_ONLINE); + + impl From for sr_primitives::AnySignature { + fn from(sig: Signature) -> Self { + sr25519::Signature::from(sig).into() + } + } } /// An i'm online keypair using sr25519 as its crypto. @@ -109,6 +116,12 @@ pub mod ed25519 { mod app_ed25519 { use app_crypto::{app_crypto, key_types::IM_ONLINE, ed25519}; app_crypto!(ed25519, IM_ONLINE); + + impl From for sr_primitives::AnySignature { + fn from(sig: Signature) -> Self { + ed25519::Signature::from(sig).into() + } + } } /// An i'm online keypair using ed25519 as its crypto. @@ -141,7 +154,6 @@ struct WorkerStatus { // Error which may occur while executing the off-chain code. enum OffchainErr { DecodeWorkerStatus, - ExtrinsicCreation, FailedSigning, NetworkState, SubmitTransaction, @@ -151,7 +163,6 @@ impl Printable for OffchainErr { fn print(self) { match self { OffchainErr::DecodeWorkerStatus => print("Offchain error: decoding WorkerStatus failed!"), - OffchainErr::ExtrinsicCreation => print("Offchain error: extrinsic creation failed!"), OffchainErr::FailedSigning => print("Offchain error: signing failed!"), OffchainErr::NetworkState => print("Offchain error: fetching network state failed!"), OffchainErr::SubmitTransaction => print("Offchain error: submitting transaction failed!"), @@ -183,9 +194,8 @@ pub trait Trait: system::Trait + session::historical::Trait { /// A dispatchable call type. type Call: From>; - /// A extrinsic right from the external world. This is unchecked and so - /// can contain a signature. - type UncheckedExtrinsic: ExtrinsicT::Call> + Encode + Decode; + /// A transaction submitter. + type SubmitTransaction: SubmitUnsignedTransaction::Call>; /// A type that gives us the ability to submit unresponsiveness offence reports. type ReportUnresponsiveness: @@ -332,9 +342,8 @@ impl Module { let signature = key.sign(&heartbeat_data.encode()).ok_or(OffchainErr::FailedSigning)?; let call = Call::heartbeat(heartbeat_data, signature); - let ex = T::UncheckedExtrinsic::new_unsigned(call.into()) - .ok_or(OffchainErr::ExtrinsicCreation)?; - sr_io::submit_transaction(&ex).map_err(|_| OffchainErr::SubmitTransaction)?; + T::SubmitTransaction::submit_unsigned(call) + .map_err(|_| OffchainErr::SubmitTransaction)?; // once finished we set the worker status without comparing // if the existing value changed in the meantime. this is diff --git a/srml/support/src/inherent.rs b/srml/support/src/inherent.rs index 1b6d8fbdd7..935d3b4e74 100644 --- a/srml/support/src/inherent.rs +++ b/srml/support/src/inherent.rs @@ -55,14 +55,16 @@ macro_rules! impl_outer_inherent { fn create_extrinsics(&self) -> $crate::inherent::Vec<<$block as $crate::inherent::BlockT>::Extrinsic> { use $crate::inherent::ProvideInherent; + use $crate::inherent::Extrinsic; let mut inherents = Vec::new(); $( if let Some(inherent) = $module::create_inherent(self) { - inherents.push($uncheckedextrinsic::new_unsigned( - Call::$call(inherent)) - ); + inherents.push($uncheckedextrinsic::new( + Call::$call(inherent), + None, + ).expect("Runtime UncheckedExtrinsic is not Opaque, so it has to return `Some`; qed")); } )* diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index 3fa4733ba0..3b692d8df0 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -121,6 +121,8 @@ use runtime_io::{TestExternalities, Blake2Hasher}; #[cfg(any(feature = "std", test))] use primitives::ChangesTrieConfiguration; +pub mod offchain; + /// Handler for when a new account has been created. pub trait OnNewAccount { /// A new account `who` has been registered. @@ -441,7 +443,7 @@ decl_storage! { } } -pub struct EnsureRoot(::rstd::marker::PhantomData); +pub struct EnsureRoot(rstd::marker::PhantomData); impl< O: Into, O>> + From>, AccountId, @@ -455,7 +457,7 @@ impl< } } -pub struct EnsureSigned(::rstd::marker::PhantomData); +pub struct EnsureSigned(rstd::marker::PhantomData); impl< O: Into, O>> + From>, AccountId, @@ -469,7 +471,7 @@ impl< } } -pub struct EnsureSignedBy(::rstd::marker::PhantomData<(Who, AccountId)>); +pub struct EnsureSignedBy(rstd::marker::PhantomData<(Who, AccountId)>); impl< O: Into, O>> + From>, Who: Contains, @@ -484,7 +486,7 @@ impl< } } -pub struct EnsureNone(::rstd::marker::PhantomData); +pub struct EnsureNone(rstd::marker::PhantomData); impl< O: Into, O>> + From>, AccountId, @@ -498,7 +500,7 @@ impl< } } -pub struct EnsureNever(::rstd::marker::PhantomData); +pub struct EnsureNever(rstd::marker::PhantomData); impl EnsureOrigin for EnsureNever { type Success = T; fn try_origin(o: O) -> Result { @@ -892,8 +894,7 @@ impl CheckWeight { } } - /// Utility constructor for tests and client code. - #[cfg(feature = "std")] + /// Creates new `SignedExtension` to check weight of the extrinsic. pub fn new() -> Self { Self(PhantomData) } @@ -948,7 +949,6 @@ impl rstd::fmt::Debug for CheckWeight { #[derive(Encode, Decode, Clone, Eq, PartialEq)] pub struct CheckNonce(#[codec(compact)] T::Index); -#[cfg(feature = "std")] impl CheckNonce { /// utility constructor. Used only in client/factory code. pub fn from(nonce: T::Index) -> Self { @@ -1022,7 +1022,6 @@ impl SignedExtension for CheckNonce { #[derive(Encode, Decode, Clone, Eq, PartialEq)] pub struct CheckEra((Era, rstd::marker::PhantomData)); -#[cfg(feature = "std")] impl CheckEra { /// utility constructor. Used only in client/factory code. pub fn from(era: Era) -> Self { @@ -1077,10 +1076,10 @@ impl rstd::fmt::Debug for CheckGenesis { } } -#[cfg(feature = "std")] impl CheckGenesis { + /// Creates new `SignedExtension` to check genesis hash. pub fn new() -> Self { - Self(std::marker::PhantomData) + Self(rstd::marker::PhantomData) } } @@ -1106,10 +1105,10 @@ impl rstd::fmt::Debug for CheckVersion { } } -#[cfg(feature = "std")] impl CheckVersion { + /// Create new `SignedExtension` to check runtime version. pub fn new() -> Self { - Self(std::marker::PhantomData) + Self(rstd::marker::PhantomData) } } @@ -1124,10 +1123,10 @@ impl SignedExtension for CheckVersion { } } -pub struct ChainContext(::rstd::marker::PhantomData); +pub struct ChainContext(rstd::marker::PhantomData); impl Default for ChainContext { fn default() -> Self { - ChainContext(::rstd::marker::PhantomData) + ChainContext(rstd::marker::PhantomData) } } diff --git a/srml/system/src/offchain.rs b/srml/system/src/offchain.rs new file mode 100644 index 0000000000..d67598f64f --- /dev/null +++ b/srml/system/src/offchain.rs @@ -0,0 +1,135 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Module helpers for offchain calls. + +use codec::Encode; +use sr_primitives::app_crypto::RuntimeAppPublic; +use sr_primitives::traits::Extrinsic as ExtrinsicT; + +/// A trait responsible for signing a payload using given account. +pub trait Signer { + /// Sign any encodable payload with given account and produce a signature. + /// + /// Returns `Some` if signing succeeded and `None` in case the `account` couldn't be used. + fn sign(account: Account, payload: &Payload) -> Option; +} + +impl Signer for AppPublic where + AppPublic: RuntimeAppPublic + From, + AppPublic::Signature: Into, +{ + fn sign(account: Account, raw_payload: &Payload) -> Option { + raw_payload.using_encoded(|payload| { + AppPublic::from(account).sign(&payload).map(Into::into) + }) + } +} + +/// Creates runtime-specific signed transaction. +pub trait CreateTransaction { + type Signature; + + /// Attempt to create signed extrinsic data that encodes call from given account. + /// + /// Runtime implementation is free to construct the payload to sign and the signature + /// in any way it wants. + /// Returns `None` if signed extrinsic could not be created (either because signing failed + /// or because of any other runtime-specific reason). + fn create_transaction>( + call: Extrinsic::Call, + account: T::AccountId, + nonce: T::Index, + ) -> Option<(Extrinsic::Call, Extrinsic::SignaturePayload)>; +} + +/// A trait to sign and submit transactions in offchain calls. +pub trait SubmitSignedTransaction { + /// Unchecked extrinsic type. + type Extrinsic: ExtrinsicT + codec::Encode; + + /// A runtime-specific type to produce signed data for the extrinsic. + type CreateTransaction: CreateTransaction; + + /// A type used to sign transactions created using `CreateTransaction`. + type Signer: Signer< + T::AccountId, + >::Signature, + >; + + /// Sign given call and submit it to the transaction pool. + /// + /// Returns `Ok` if the transaction was submitted correctly + /// and `Err` if the key for given `id` was not found or the + /// transaction was rejected from the pool. + fn sign_and_submit(call: impl Into, id: T::AccountId) -> Result<(), ()> { + let call = call.into(); + let expected = >::account_nonce(&id); + let (call, signature_data) = Self::CreateTransaction + ::create_transaction::(call, id, expected) + .ok_or(())?; + let xt = Self::Extrinsic::new(call, Some(signature_data)).ok_or(())?; + runtime_io::submit_transaction(&xt) + } +} + +/// A trait to submit unsigned transactions in offchain calls. +pub trait SubmitUnsignedTransaction { + /// Unchecked extrinsic type. + type Extrinsic: ExtrinsicT + codec::Encode; + + /// Submit given call to the transaction pool as unsigned transaction. + /// + /// Returns `Ok` if the transaction was submitted correctly + /// and `Err` if transaction was rejected from the pool. + fn submit_unsigned(call: impl Into) -> Result<(), ()> { + let xt = Self::Extrinsic::new(call.into(), None).ok_or(())?; + runtime_io::submit_transaction(&xt) + } +} + +/// A default type used to submit transactions to the pool. +pub struct TransactionSubmitter { + _signer: rstd::marker::PhantomData<(S, C, E)>, +} + +impl Default for TransactionSubmitter { + fn default() -> Self { + Self { + _signer: Default::default(), + } + } +} + +/// A blanket implementation to simplify creation of transaction signer & submitter in the runtime. +impl SubmitSignedTransaction for TransactionSubmitter where + T: crate::Trait, + C: CreateTransaction, + S: Signer>::Signature>, + E: ExtrinsicT + codec::Encode, +{ + type Extrinsic = E; + type CreateTransaction = C; + type Signer = S; +} + +/// A blanket impl to use the same submitter for usigned transactions as well. +impl SubmitUnsignedTransaction for TransactionSubmitter where + T: crate::Trait, + E: ExtrinsicT + codec::Encode, +{ + type Extrinsic = E; +} diff --git a/subkey/src/main.rs b/subkey/src/main.rs index ba9d1a6cce..e0ac2cb8b6 100644 --- a/subkey/src/main.rs +++ b/subkey/src/main.rs @@ -29,7 +29,7 @@ use primitives::{ use codec::{Encode, Decode}; use sr_primitives::generic::Era; use node_primitives::{Balance, Index, Hash}; -use node_runtime::{Call, UncheckedExtrinsic, BalancesCall, Runtime}; +use node_runtime::{Call, UncheckedExtrinsic, SignedPayload, BalancesCall, Runtime, VERSION}; mod vanity; @@ -182,22 +182,21 @@ fn execute(matches: clap::ArgMatches) where println!("Using a genesis hash of {}", HexDisplay::from(&genesis_hash.as_ref())); - let raw_payload = ( + let raw_payload = SignedPayload::from_raw( function, extra(index, 0), - (&genesis_hash, &genesis_hash), + (VERSION.spec_version as u32, genesis_hash, genesis_hash, (), (), ()), ); - let signature = raw_payload.using_encoded(|payload| if payload.len() > 256 { - signer.sign(&blake2_256(payload)[..]) - } else { + let signature = raw_payload.using_encoded(|payload| { println!("Signing {}", HexDisplay::from(&payload)); signer.sign(payload) }); + let (function, extra, _) = raw_payload.deconstruct(); let extrinsic = UncheckedExtrinsic::new_signed( - raw_payload.0, + function, signer.public().into(), signature.into(), - extra(index, 0), + extra, ); println!("0x{}", hex::encode(&extrinsic.encode())); } -- GitLab From 39b9f07a1d114f91a4c913d10436cac502cdff9f Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Sun, 1 Sep 2019 02:19:31 +0200 Subject: [PATCH 044/275] Minimum balance (#3519) --- srml/contracts/src/exec.rs | 7 ++++ srml/contracts/src/wasm/mod.rs | 66 ++++++++++++++++++++++++++++++ srml/contracts/src/wasm/runtime.rs | 10 +++++ 3 files changed, 83 insertions(+) diff --git a/srml/contracts/src/exec.rs b/srml/contracts/src/exec.rs index 818a689f99..586ee3746b 100644 --- a/srml/contracts/src/exec.rs +++ b/srml/contracts/src/exec.rs @@ -154,6 +154,9 @@ pub trait Ext { /// Returns a reference to the timestamp of the current block fn now(&self) -> &MomentOf; + /// Returns the minimum balance that is required for creating an account. + fn minimum_balance(&self) -> BalanceOf; + /// Returns a random number for the current block with the given subject. fn random(&self, subject: &[u8]) -> SeedOf; @@ -766,6 +769,10 @@ where &self.timestamp } + fn minimum_balance(&self) -> BalanceOf { + self.ctx.config.existential_deposit + } + fn deposit_event(&mut self, topics: Vec, data: Vec) { self.ctx.deferred.push(DeferredAction::DepositEvent { topics, diff --git a/srml/contracts/src/wasm/mod.rs b/srml/contracts/src/wasm/mod.rs index 99578fee27..c623313824 100644 --- a/srml/contracts/src/wasm/mod.rs +++ b/srml/contracts/src/wasm/mod.rs @@ -282,6 +282,10 @@ mod tests { &1111 } + fn minimum_balance(&self) -> u64 { + 666 + } + fn random(&self, subject: &[u8]) -> H256 { H256::from_slice(subject) } @@ -364,6 +368,9 @@ mod tests { fn now(&self) -> &u64 { (**self).now() } + fn minimum_balance(&self) -> u64 { + (**self).minimum_balance() + } fn random(&self, subject: &[u8]) -> H256 { (**self).random(subject) } @@ -1176,6 +1183,65 @@ mod tests { ).unwrap(); } + const CODE_MINIMUM_BALANCE: &str = r#" +(module + (import "env" "ext_minimum_balance" (func $ext_minimum_balance)) + (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) + (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "env" "memory" (memory 1 1)) + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func (export "call") + (call $ext_minimum_balance) + + ;; assert $ext_scratch_size == 8 + (call $assert + (i32.eq + (call $ext_scratch_size) + (i32.const 8) + ) + ) + + ;; copy contents of the scratch buffer into the contract's memory. + (call $ext_scratch_read + (i32.const 8) ;; Pointer in memory to the place where to copy. + (i32.const 0) ;; Offset from the start of the scratch buffer. + (i32.const 8) ;; Count of bytes to copy. + ) + + ;; assert that contents of the buffer is equal to the i64 value of 666. + (call $assert + (i64.eq + (i64.load + (i32.const 8) + ) + (i64.const 666) + ) + ) + ) + (func (export "deploy")) +) +"#; + + #[test] + fn minimum_balance() { + let mut gas_meter = GasMeter::with_limit(50_000, 1); + let _ = execute( + CODE_MINIMUM_BALANCE, + vec![], + MockExt::default(), + &mut gas_meter, + ).unwrap(); + } + const CODE_RANDOM: &str = r#" (module (import "env" "ext_random" (func $ext_random (param i32 i32))) diff --git a/srml/contracts/src/wasm/runtime.rs b/srml/contracts/src/wasm/runtime.rs index c6ef1bb3f5..4baece3d91 100644 --- a/srml/contracts/src/wasm/runtime.rs +++ b/srml/contracts/src/wasm/runtime.rs @@ -611,6 +611,16 @@ define_env!(Env, , Ok(()) }, + // Stores the minimum balance (a.k.a. existential deposit) into the scratch buffer. + // + // The data is encoded as T::Balance. The current contents of the scratch buffer are + // overwritten. + ext_minimum_balance(ctx) => { + ctx.scratch_buf.clear(); + ctx.ext.minimum_balance().encode_to(&mut ctx.scratch_buf); + Ok(()) + }, + // Decodes the given buffer as a `T::Call` and adds it to the list // of to-be-dispatched calls. // -- GitLab From 447e6ea239b7b033c3c440b398d47c567f8874d6 Mon Sep 17 00:00:00 2001 From: cheme Date: Sun, 1 Sep 2019 02:19:54 +0200 Subject: [PATCH 045/275] Add missing child trie rpc on_custom_message handler (#3522) * missing on_custom for child read. * fix and complete, add test cases. * shorten line. * replace vecs of key value tuple with maps. --- core/client/src/genesis.rs | 11 +++-- core/client/src/light/fetcher.rs | 63 ++++++++++++++++++++++++++++- core/network/src/chain.rs | 13 ++++++ core/network/src/protocol.rs | 33 ++++++++++++++- core/rpc/src/state/tests.rs | 10 +++++ core/test-runtime/client/src/lib.rs | 37 ++++++++++++++++- core/test-runtime/src/genesismap.rs | 14 ++++--- 7 files changed, 167 insertions(+), 14 deletions(-) diff --git a/core/client/src/genesis.rs b/core/client/src/genesis.rs index 4791a34d17..88529114e2 100644 --- a/core/client/src/genesis.rs +++ b/core/client/src/genesis.rs @@ -48,7 +48,7 @@ mod tests { runtime::{Hash, Transfer, Block, BlockNumber, Header, Digest}, AccountKeyring, Sr25519Keyring, }; - use primitives::Blake2Hasher; + use primitives::{Blake2Hasher, map}; use hex::*; native_executor_instance!( @@ -152,7 +152,8 @@ mod tests { vec![AccountKeyring::One.into(), AccountKeyring::Two.into()], 1000, None, - vec![], + map![], + map![], ).genesis_map(); let genesis_hash = insert_genesis_block(&mut storage); @@ -181,7 +182,8 @@ mod tests { vec![AccountKeyring::One.into(), AccountKeyring::Two.into()], 1000, None, - vec![], + map![], + map![], ).genesis_map(); let genesis_hash = insert_genesis_block(&mut storage); @@ -210,7 +212,8 @@ mod tests { vec![AccountKeyring::One.into(), AccountKeyring::Two.into()], 68, None, - vec![], + map![], + map![], ).genesis_map(); let genesis_hash = insert_genesis_block(&mut storage); diff --git a/core/client/src/light/fetcher.rs b/core/client/src/light/fetcher.rs index 8502a19ba6..d09a189361 100644 --- a/core/client/src/light/fetcher.rs +++ b/core/client/src/light/fetcher.rs @@ -570,7 +570,8 @@ pub mod tests { let remote_block_id = BlockId::Number(0); let remote_block_hash = remote_client.block_hash(0).unwrap().unwrap(); let mut remote_block_header = remote_client.header(&remote_block_id).unwrap().unwrap(); - remote_block_header.state_root = remote_client.state_at(&remote_block_id).unwrap().storage_root(::std::iter::empty()).0.into(); + remote_block_header.state_root = remote_client.state_at(&remote_block_id).unwrap() + .storage_root(::std::iter::empty()).0.into(); // 'fetch' read proof from remote node let heap_pages = remote_client.storage(&remote_block_id, &StorageKey(well_known_keys::HEAP_PAGES.to_vec())) @@ -592,6 +593,46 @@ pub mod tests { (local_checker, remote_block_header, remote_read_proof, heap_pages) } + fn prepare_for_read_child_proof_check() -> (TestChecker, Header, Vec>, Vec) { + use test_client::DefaultTestClientBuilderExt; + use test_client::TestClientBuilderExt; + // prepare remote client + let remote_client = test_client::TestClientBuilder::new() + .add_extra_child_storage(b":child_storage:default:child1".to_vec(), b"key1".to_vec(), b"value1".to_vec()) + .build(); + let remote_block_id = BlockId::Number(0); + let remote_block_hash = remote_client.block_hash(0).unwrap().unwrap(); + let mut remote_block_header = remote_client.header(&remote_block_id).unwrap().unwrap(); + remote_block_header.state_root = remote_client.state_at(&remote_block_id).unwrap() + .storage_root(::std::iter::empty()).0.into(); + + // 'fetch' child read proof from remote node + let child_value = remote_client.child_storage( + &remote_block_id, + &StorageKey(b":child_storage:default:child1".to_vec()), + &StorageKey(b"key1".to_vec()), + ).unwrap().unwrap().0; + assert_eq!(b"value1"[..], child_value[..]); + let remote_read_proof = remote_client.read_child_proof( + &remote_block_id, + b":child_storage:default:child1", + b"key1", + ).unwrap(); + + // check locally + let local_storage = InMemoryBlockchain::::new(); + local_storage.insert( + remote_block_hash, + remote_block_header.clone(), + None, + None, + crate::backend::NewBlockState::Final, + ).unwrap(); + let local_executor = NativeExecutor::::new(None); + let local_checker = LightDataChecker::new(Arc::new(DummyBlockchain::new(DummyStorage::new())), local_executor); + (local_checker, remote_block_header, remote_read_proof, child_value) + } + fn prepare_for_header_proof_check(insert_cht: bool) -> (TestChecker, Hash, Header, Vec>) { // prepare remote client let remote_client = test_client::new(); @@ -638,6 +679,26 @@ pub mod tests { }, remote_read_proof).unwrap().unwrap()[0], heap_pages as u8); } + #[test] + fn storage_child_read_proof_is_generated_and_checked() { + let ( + local_checker, + remote_block_header, + remote_read_proof, + result, + ) = prepare_for_read_child_proof_check(); + assert_eq!((&local_checker as &dyn FetchChecker).check_read_child_proof( + &RemoteReadChildRequest::

{ + block: remote_block_header.hash(), + header: remote_block_header, + storage_key: b":child_storage:default:child1".to_vec(), + key: b"key1".to_vec(), + retry_count: None, + }, + remote_read_proof + ).unwrap().unwrap(), result); + } + #[test] fn header_proof_is_generated_and_checked() { let (local_checker, local_cht_root, remote_block_header, remote_header_proof) = prepare_for_header_proof_check(true); diff --git a/core/network/src/chain.rs b/core/network/src/chain.rs index a73d7e53e2..99068698be 100644 --- a/core/network/src/chain.rs +++ b/core/network/src/chain.rs @@ -51,6 +51,9 @@ pub trait Client: Send + Sync { /// Get storage read execution proof. fn read_proof(&self, block: &Block::Hash, key: &[u8]) -> Result>, Error>; + /// Get child storage read execution proof. + fn read_child_proof(&self, block: &Block::Hash, storage_key: &[u8], key: &[u8]) -> Result>, Error>; + /// Get method execution proof. fn execution_proof(&self, block: &Block::Hash, method: &str, data: &[u8]) -> Result<(Vec, Vec>), Error>; @@ -113,6 +116,16 @@ impl Client for SubstrateClient where (self as &SubstrateClient).read_proof(&BlockId::Hash(block.clone()), key) } + fn read_child_proof( + &self, + block: &Block::Hash, + storage_key: &[u8], + key: &[u8] + ) -> Result>, Error> { + (self as &SubstrateClient) + .read_child_proof(&BlockId::Hash(block.clone()), storage_key, key) + } + fn execution_proof(&self, block: &Block::Hash, method: &str, data: &[u8]) -> Result<(Vec, Vec>), Error> { (self as &SubstrateClient).execution_proof(&BlockId::Hash(block.clone()), method, data) } diff --git a/core/network/src/protocol.rs b/core/network/src/protocol.rs index b561322b5b..cbe6bc356c 100644 --- a/core/network/src/protocol.rs +++ b/core/network/src/protocol.rs @@ -547,7 +547,8 @@ impl, H: ExHashT> Protocol { self.on_finality_proof_request(who, request), GenericMessage::FinalityProofResponse(response) => return self.on_finality_proof_response(who, response), - GenericMessage::RemoteReadChildRequest(_) => {} + GenericMessage::RemoteReadChildRequest(request) => + self.on_remote_read_child_request(who, request), GenericMessage::Consensus(msg) => { if self.context_data.peers.get(&who).map_or(false, |peer| peer.info.protocol_version > 2) { self.consensus_gossip.on_incoming( @@ -1293,6 +1294,36 @@ impl, H: ExHashT> Protocol { ); } + fn on_remote_read_child_request( + &mut self, + who: PeerId, + request: message::RemoteReadChildRequest, + ) { + trace!(target: "sync", "Remote read child request {} from {} ({} {} at {})", + request.id, who, request.storage_key.to_hex::(), request.key.to_hex::(), request.block); + let proof = match self.context_data.chain.read_child_proof(&request.block, &request.storage_key, &request.key) { + Ok(proof) => proof, + Err(error) => { + trace!(target: "sync", "Remote read child request {} from {} ({} {} at {}) failed with: {}", + request.id, + who, + request.storage_key.to_hex::(), + request.key.to_hex::(), + request.block, + error + ); + Default::default() + } + }; + self.send_message( + who, + GenericMessage::RemoteReadResponse(message::RemoteReadResponse { + id: request.id, + proof, + }), + ); + } + fn on_remote_read_response( &mut self, who: PeerId, diff --git a/core/rpc/src/state/tests.rs b/core/rpc/src/state/tests.rs index 656abf56a9..0b581d166f 100644 --- a/core/rpc/src/state/tests.rs +++ b/core/rpc/src/state/tests.rs @@ -30,14 +30,18 @@ use test_client::{ fn should_return_storage() { const KEY: &[u8] = b":mock"; const VALUE: &[u8] = b"hello world"; + const STORAGE_KEY: &[u8] = b":child_storage:default:child"; + const CHILD_VALUE: &[u8] = b"hello world !"; let core = tokio::runtime::Runtime::new().unwrap(); let client = TestClientBuilder::new() .add_extra_storage(KEY.to_vec(), VALUE.to_vec()) + .add_extra_child_storage(STORAGE_KEY.to_vec(), KEY.to_vec(), CHILD_VALUE.to_vec()) .build(); let genesis_hash = client.genesis_hash(); let client = State::new(Arc::new(client), Subscriptions::new(Arc::new(core.executor()))); let key = StorageKey(KEY.to_vec()); + let storage_key = StorageKey(STORAGE_KEY.to_vec()); assert_eq!( client.storage(key.clone(), Some(genesis_hash).into()) @@ -52,6 +56,12 @@ fn should_return_storage() { client.storage_size(key.clone(), None).unwrap().unwrap() as usize, VALUE.len(), ); + assert_eq!( + client.child_storage(storage_key, key, Some(genesis_hash).into()) + .map(|x| x.map(|x| x.0.len())).unwrap().unwrap() as usize, + CHILD_VALUE.len(), + ); + } #[test] diff --git a/core/test-runtime/client/src/lib.rs b/core/test-runtime/client/src/lib.rs index 767c862083..aeed1e7ad4 100644 --- a/core/test-runtime/client/src/lib.rs +++ b/core/test-runtime/client/src/lib.rs @@ -23,6 +23,7 @@ pub mod trait_tests; mod block_builder_ext; use std::sync::Arc; +use std::collections::HashMap; pub use block_builder_ext::BlockBuilderExt; pub use generic_test_client::*; pub use runtime; @@ -97,7 +98,8 @@ pub type LightExecutor = client::light::call_executor::RemoteOrLocalCallExecutor pub struct GenesisParameters { support_changes_trie: bool, heap_pages_override: Option, - extra_storage: Vec<(Vec, Vec)>, + extra_storage: HashMap, Vec>, + child_extra_storage: HashMap, HashMap, Vec>>, } impl GenesisParameters { @@ -117,6 +119,7 @@ impl GenesisParameters { 1000, self.heap_pages_override, self.extra_storage.clone(), + self.child_extra_storage.clone(), ) } } @@ -184,6 +187,18 @@ pub trait TestClientBuilderExt: Sized { /// # Panics /// /// Panics if the key is empty. + fn add_extra_child_storage>, K: Into>, V: Into>>( + self, + storage_key: SK, + key: K, + value: V, + ) -> Self; + + /// Add an extra child value into the genesis storage. + /// + /// # Panics + /// + /// Panics if the key is empty. fn add_extra_storage>, V: Into>>(self, key: K, value: V) -> Self; /// Build the test client. @@ -214,10 +229,28 @@ impl TestClientBuilderExt for TestClientBuilder< fn add_extra_storage>, V: Into>>(mut self, key: K, value: V) -> Self { let key = key.into(); assert!(!key.is_empty()); - self.genesis_init_mut().extra_storage.push((key, value.into())); + self.genesis_init_mut().extra_storage.insert(key, value.into()); + self + } + + fn add_extra_child_storage>, K: Into>, V: Into>>( + mut self, + storage_key: SK, + key: K, + value: V, + ) -> Self { + let storage_key = storage_key.into(); + let key = key.into(); + assert!(!storage_key.is_empty()); + assert!(!key.is_empty()); + self.genesis_init_mut().child_extra_storage + .entry(storage_key) + .or_insert_with(Default::default) + .insert(key, value.into()); self } + fn build_with_longest_chain(self) -> (Client, client::LongestChain) { self.build_with_native_executor(None) } diff --git a/core/test-runtime/src/genesismap.rs b/core/test-runtime/src/genesismap.rs index c2dd49156d..34d7eecae0 100644 --- a/core/test-runtime/src/genesismap.rs +++ b/core/test-runtime/src/genesismap.rs @@ -30,7 +30,8 @@ pub struct GenesisConfig { balances: Vec<(AccountId, u64)>, heap_pages_override: Option, /// Additional storage key pairs that will be added to the genesis map. - extra_storage: Vec<(Vec, Vec)>, + extra_storage: HashMap, Vec>, + child_extra_storage: HashMap, HashMap, Vec>>, } impl GenesisConfig { @@ -40,7 +41,8 @@ impl GenesisConfig { endowed_accounts: Vec, balance: u64, heap_pages_override: Option, - extra_storage: Vec<(Vec, Vec)>, + extra_storage: HashMap, Vec>, + child_extra_storage: HashMap, HashMap, Vec>>, ) -> Self { GenesisConfig { changes_trie_config: match support_changes_trie { @@ -51,6 +53,7 @@ impl GenesisConfig { balances: endowed_accounts.into_iter().map(|a| (a, balance)).collect(), heap_pages_override, extra_storage, + child_extra_storage, } } @@ -75,10 +78,9 @@ impl GenesisConfig { } map.insert(twox_128(&b"sys:auth"[..])[..].to_vec(), self.authorities.encode()); // Finally, add the extra storage entries. - for (key, value) in self.extra_storage.iter().cloned() { - map.insert(key, value); - } - (map, Default::default()) + map.extend(self.extra_storage.clone().into_iter()); + + (map, self.child_extra_storage.clone()) } } -- GitLab From 0c08276bdbeac2e0f9bf1a5bc91b04271460e652 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Sun, 1 Sep 2019 03:20:10 +0300 Subject: [PATCH 046/275] Make chain && state RPCs async (#3480) * chain+state RPCs are async now * wrapped too long lines * create full/light RPC impls from service * use ordering * post-merge fix --- Cargo.lock | 2 + core/client/Cargo.toml | 6 +- core/client/src/backend.rs | 5 + core/client/src/client.rs | 2 +- core/client/src/in_mem.rs | 4 + core/client/src/light/backend.rs | 10 +- core/client/src/light/blockchain.rs | 112 +++- core/client/src/light/call_executor.rs | 2 +- core/client/src/light/fetcher.rs | 16 +- core/client/src/light/mod.rs | 4 +- core/client/src/notifications.rs | 20 +- core/rpc/Cargo.toml | 1 + core/rpc/api/src/chain/error.rs | 3 + core/rpc/api/src/chain/mod.rs | 6 +- core/rpc/api/src/state/error.rs | 3 + core/rpc/api/src/state/mod.rs | 26 +- core/rpc/src/chain/chain_full.rs | 79 +++ core/rpc/src/chain/chain_light.rs | 123 +++++ core/rpc/src/chain/mod.rs | 311 +++++++---- core/rpc/src/chain/tests.rs | 108 ++-- core/rpc/src/state/mod.rs | 699 +++++++++++-------------- core/rpc/src/state/state_full.rs | 389 ++++++++++++++ core/rpc/src/state/state_light.rs | 283 ++++++++++ core/rpc/src/state/tests.rs | 50 +- core/service/src/builder.rs | 273 +++++++--- core/service/src/lib.rs | 1 + 26 files changed, 1838 insertions(+), 700 deletions(-) create mode 100644 core/rpc/src/chain/chain_full.rs create mode 100644 core/rpc/src/chain/chain_light.rs create mode 100644 core/rpc/src/state/state_full.rs create mode 100644 core/rpc/src/state/state_light.rs diff --git a/Cargo.lock b/Cargo.lock index 7cdf58413b..b714f89359 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4494,6 +4494,7 @@ dependencies = [ "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4984,6 +4985,7 @@ dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-pubsub 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/core/client/Cargo.toml b/core/client/Cargo.toml index 9edb9b1c85..76daf1dc60 100644 --- a/core/client/Cargo.toml +++ b/core/client/Cargo.toml @@ -10,7 +10,8 @@ fnv = { version = "1.0", optional = true } log = { version = "0.4", optional = true } parking_lot = { version = "0.9.0", optional = true } hex = { package = "hex-literal", version = "0.2", optional = true } -futures-preview = { version = "=0.3.0-alpha.17", optional = true } +futures = { version = "0.1", optional = true } +futures03 = { package = "futures-preview", version = "=0.3.0-alpha.17", features = ["compat"], optional = true } consensus = { package = "substrate-consensus-common", path = "../consensus/common", optional = true } executor = { package = "substrate-executor", path = "../executor", optional = true } state-machine = { package = "substrate-state-machine", path = "../state-machine", optional = true } @@ -49,7 +50,8 @@ std = [ "fnv", "log", "hex", - "futures-preview", + "futures", + "futures03", "executor", "state-machine", "keyring", diff --git a/core/client/src/backend.rs b/core/client/src/backend.rs index 07bb6d6c91..a42fdcff24 100644 --- a/core/client/src/backend.rs +++ b/core/client/src/backend.rs @@ -16,8 +16,10 @@ //! Substrate Client data backend +use std::sync::Arc; use std::collections::HashMap; use crate::error; +use crate::light::blockchain::RemoteBlockchain; use primitives::ChangesTrieConfiguration; use sr_primitives::{generic::BlockId, Justification, StorageOverlay, ChildrenStorageOverlay}; use sr_primitives::traits::{Block as BlockT, NumberFor}; @@ -303,4 +305,7 @@ where { /// Returns true if the state for given block is available locally. fn is_local_state_available(&self, block: &BlockId) -> bool; + /// Returns reference to blockchain backend that either resolves blockchain data + /// locally, or prepares request to fetch that data from remote node. + fn remote_blockchain(&self) -> Arc>; } diff --git a/core/client/src/client.rs b/core/client/src/client.rs index 41dae58970..be11c5d4f2 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -21,7 +21,7 @@ use std::{ panic::UnwindSafe, result, cell::RefCell, rc::Rc, }; use log::{info, trace, warn}; -use futures::channel::mpsc; +use futures03::channel::mpsc; use parking_lot::{Mutex, RwLock}; use codec::{Encode, Decode}; use hash_db::{Hasher, Prefix}; diff --git a/core/client/src/in_mem.rs b/core/client/src/in_mem.rs index f450ceebe2..58bfa05a36 100644 --- a/core/client/src/in_mem.rs +++ b/core/client/src/in_mem.rs @@ -718,6 +718,10 @@ where .map(|num| num.is_zero()) .unwrap_or(false) } + + fn remote_blockchain(&self) -> Arc> { + unimplemented!() + } } /// Prunable in-memory changes trie storage. diff --git a/core/client/src/light/backend.rs b/core/client/src/light/backend.rs index 888c9d2033..b3dc6c2257 100644 --- a/core/client/src/light/backend.rs +++ b/core/client/src/light/backend.rs @@ -231,8 +231,8 @@ impl ClientBackend for Backend where impl RemoteBackend for Backend where Block: BlockT, - S: BlockchainStorage, - F: Fetcher, + S: BlockchainStorage + 'static, + F: Fetcher + 'static, H: Hasher, H::Out: Ord, { @@ -242,6 +242,10 @@ where .map(|num| num.is_zero()) .unwrap_or(false) } + + fn remote_blockchain(&self) -> Arc> { + self.blockchain.clone() + } } impl BlockImportOperation for ImportOperation @@ -358,7 +362,7 @@ where *self.cached_header.write() = Some(cached_header); } - futures::executor::block_on( + futures03::executor::block_on( self.fetcher.upgrade().ok_or(ClientError::NotAvailableOnLightClient)? .remote_read(RemoteReadRequest { block: self.block, diff --git a/core/client/src/light/blockchain.rs b/core/client/src/light/blockchain.rs index a2c2fe72ba..726d2abdc6 100644 --- a/core/client/src/light/blockchain.rs +++ b/core/client/src/light/blockchain.rs @@ -17,6 +17,7 @@ //! Light client blockchain backend. Only stores headers and justifications of recent //! blocks. CHT roots are stored for headers of ancient blocks. +use std::future::Future; use std::{sync::{Weak, Arc}, collections::HashMap}; use parking_lot::Mutex; @@ -72,6 +73,27 @@ pub trait Storage: AuxStore + BlockchainHeaderBackend { fn cache(&self) -> Option>>; } +/// Remote header. +#[derive(Debug)] +pub enum LocalOrRemote { + /// When data is available locally, it is returned. + Local(Data), + /// When data is unavailable locally, the request to fetch it from remote node is returned. + Remote(Request), + /// When data is unknown. + Unknown, +} + +/// Futures-based blockchain backend that either resolves blockchain data +/// locally, or fetches required data from remote node. +pub trait RemoteBlockchain: Send + Sync { + /// Get block header. + fn header(&self, id: BlockId) -> ClientResult, + >>; +} + /// Light client blockchain. pub struct Blockchain { fetcher: Mutex>, @@ -105,32 +127,10 @@ impl Blockchain { impl BlockchainHeaderBackend for Blockchain where Block: BlockT, S: Storage, F: Fetcher { fn header(&self, id: BlockId) -> ClientResult> { - match self.storage.header(id)? { - Some(header) => Ok(Some(header)), - None => { - let number = match id { - BlockId::Hash(hash) => match self.storage.number(hash)? { - Some(number) => number, - None => return Ok(None), - }, - BlockId::Number(number) => number, - }; - - // if the header is from future or genesis (we never prune genesis) => return - if number.is_zero() || self.storage.status(BlockId::Number(number))? == BlockStatus::Unknown { - return Ok(None); - } - - futures::executor::block_on( - self.fetcher().upgrade() - .ok_or(ClientError::NotAvailableOnLightClient)? - .remote_header(RemoteHeaderRequest { - cht_root: self.storage.header_cht_root(cht::size(), number)?, - block: number, - retry_count: None, - }) - ).map(Some) - } + match RemoteBlockchain::header(self, id)? { + LocalOrRemote::Local(header) => Ok(Some(header)), + LocalOrRemote::Remote(_) => Err(ClientError::NotAvailableOnLightClient), + LocalOrRemote::Unknown => Ok(None), } } @@ -153,12 +153,12 @@ impl BlockchainHeaderBackend for Blockchain where Bloc impl BlockchainBackend for Blockchain where Block: BlockT, S: Storage, F: Fetcher { fn body(&self, id: BlockId) -> ClientResult>> { - let header = match self.header(id)? { + let header = match BlockchainHeaderBackend::header(self, id)? { Some(header) => header, None => return Ok(None), }; - futures::executor::block_on( + futures03::executor::block_on( self.fetcher().upgrade().ok_or(ClientError::NotAvailableOnLightClient)? .remote_body(RemoteBodyRequest { header, @@ -194,6 +194,62 @@ impl, F, Block: BlockT> ProvideCache for Blockchain RemoteBlockchain for Blockchain + where + S: Storage, + F: Fetcher + Send + Sync, +{ + fn header(&self, id: BlockId) -> ClientResult, + >> { + // first, try to read header from local storage + if let Some(local_header) = self.storage.header(id)? { + return Ok(LocalOrRemote::Local(local_header)); + } + + // we need to know block number to check if it's a part of CHT + let number = match id { + BlockId::Hash(hash) => match self.storage.number(hash)? { + Some(number) => number, + None => return Ok(LocalOrRemote::Unknown), + }, + BlockId::Number(number) => number, + }; + + // if the header is genesis (never pruned), non-canonical, or from future => return + if number.is_zero() || self.storage.status(BlockId::Number(number))? == BlockStatus::Unknown { + return Ok(LocalOrRemote::Unknown); + } + + Ok(LocalOrRemote::Remote(RemoteHeaderRequest { + cht_root: self.storage.header_cht_root(cht::size(), number)?, + block: number, + retry_count: None, + })) + } +} + +/// Returns future that resolves header either locally, or remotely. +pub fn future_header>( + blockchain: &dyn RemoteBlockchain, + fetcher: &F, + id: BlockId, +) -> impl Future, ClientError>> { + use futures03::future::{ready, Either, FutureExt}; + + match blockchain.header(id) { + Ok(LocalOrRemote::Remote(request)) => Either::Left( + fetcher + .remote_header(request) + .then(|header| ready(header.map(Some))) + ), + Ok(LocalOrRemote::Unknown) => Either::Right(ready(Ok(None))), + Ok(LocalOrRemote::Local(local_header)) => Either::Right(ready(Ok(Some(local_header)))), + Err(err) => Either::Right(ready(Err(err))), + } +} + #[cfg(test)] pub mod tests { use std::collections::HashMap; diff --git a/core/client/src/light/call_executor.rs b/core/client/src/light/call_executor.rs index 746f36069d..f41c14fd42 100644 --- a/core/client/src/light/call_executor.rs +++ b/core/client/src/light/call_executor.rs @@ -99,7 +99,7 @@ where let block_hash = self.blockchain.expect_block_hash_from_id(id)?; let block_header = self.blockchain.expect_header(id.clone())?; - futures::executor::block_on(self.fetcher.remote_call(RemoteCallRequest { + futures03::executor::block_on(self.fetcher.remote_call(RemoteCallRequest { block: block_hash, header: block_header, method: method.into(), diff --git a/core/client/src/light/fetcher.rs b/core/client/src/light/fetcher.rs index d09a189361..c96d94424a 100644 --- a/core/client/src/light/fetcher.rs +++ b/core/client/src/light/fetcher.rs @@ -144,15 +144,15 @@ pub struct RemoteBodyRequest { /// is correct (see FetchedDataChecker) and return already checked data. pub trait Fetcher: Send + Sync { /// Remote header future. - type RemoteHeaderResult: Future>; + type RemoteHeaderResult: Future> + Send + 'static; /// Remote storage read future. - type RemoteReadResult: Future>, ClientError>>; + type RemoteReadResult: Future>, ClientError>> + Send + 'static; /// Remote call result future. - type RemoteCallResult: Future, ClientError>>; + type RemoteCallResult: Future, ClientError>> + Send + 'static; /// Remote changes result future. - type RemoteChangesResult: Future, u32)>, ClientError>>; + type RemoteChangesResult: Future, u32)>, ClientError>> + Send + 'static; /// Remote block body result future. - type RemoteBodyResult: Future, ClientError>>; + type RemoteBodyResult: Future, ClientError>> + Send + 'static; /// Fetch remote header. fn remote_header(&self, request: RemoteHeaderRequest) -> Self::RemoteHeaderResult; @@ -493,7 +493,7 @@ impl<'a, H, Number, Hash> ChangesTrieRootsStorage for RootsStorage<'a #[cfg(test)] pub mod tests { - use futures::future::Ready; + use futures03::future::Ready; use parking_lot::Mutex; use codec::Decode; use crate::client::tests::prepare_client_with_key_changes; @@ -521,7 +521,7 @@ pub mod tests { where E: std::convert::From<&'static str>, { - futures::future::ready(Err("Not implemented on test node".into())) + futures03::future::ready(Err("Not implemented on test node".into())) } impl Fetcher for OkCallFetcher { @@ -544,7 +544,7 @@ pub mod tests { } fn remote_call(&self, _request: RemoteCallRequest
) -> Self::RemoteCallResult { - futures::future::ready(Ok((*self.lock()).clone())) + futures03::future::ready(Ok((*self.lock()).clone())) } fn remote_changes(&self, _request: RemoteChangesRequest
) -> Self::RemoteChangesResult { diff --git a/core/client/src/light/mod.rs b/core/client/src/light/mod.rs index 89d3c60ddc..c53a2eef2b 100644 --- a/core/client/src/light/mod.rs +++ b/core/client/src/light/mod.rs @@ -67,8 +67,8 @@ pub fn new_light( >, B, RA>> where B: BlockT, - S: BlockchainStorage, - F: Fetcher, + S: BlockchainStorage + 'static, + F: Fetcher + 'static, GS: BuildStorage, E: CodeExecutor + RuntimeInfo, { diff --git a/core/client/src/notifications.rs b/core/client/src/notifications.rs index 0ddc4c72cd..37f90dcc0b 100644 --- a/core/client/src/notifications.rs +++ b/core/client/src/notifications.rs @@ -22,7 +22,7 @@ use std::{ }; use fnv::{FnvHashSet, FnvHashMap}; -use futures::channel::mpsc; +use futures03::channel::mpsc; use primitives::storage::{StorageKey, StorageData}; use sr_primitives::traits::Block as BlockT; @@ -347,7 +347,7 @@ mod tests { // given let mut notifications = StorageNotifications::::default(); let child_filter = [(StorageKey(vec![4]), None)]; - let mut recv = futures::executor::block_on_stream( + let mut recv = futures03::executor::block_on_stream( notifications.listen(None, Some(&child_filter[..])) ); @@ -382,13 +382,13 @@ mod tests { // given let mut notifications = StorageNotifications::::default(); let child_filter = [(StorageKey(vec![4]), Some(vec![StorageKey(vec![5])]))]; - let mut recv1 = futures::executor::block_on_stream( + let mut recv1 = futures03::executor::block_on_stream( notifications.listen(Some(&[StorageKey(vec![1])]), None) ); - let mut recv2 = futures::executor::block_on_stream( + let mut recv2 = futures03::executor::block_on_stream( notifications.listen(Some(&[StorageKey(vec![2])]), None) ); - let mut recv3 = futures::executor::block_on_stream( + let mut recv3 = futures03::executor::block_on_stream( notifications.listen(Some(&[]), Some(&child_filter)) ); @@ -429,16 +429,16 @@ mod tests { let mut notifications = StorageNotifications::::default(); { let child_filter = [(StorageKey(vec![4]), Some(vec![StorageKey(vec![5])]))]; - let _recv1 = futures::executor::block_on_stream( + let _recv1 = futures03::executor::block_on_stream( notifications.listen(Some(&[StorageKey(vec![1])]), None) ); - let _recv2 = futures::executor::block_on_stream( + let _recv2 = futures03::executor::block_on_stream( notifications.listen(Some(&[StorageKey(vec![2])]), None) ); - let _recv3 = futures::executor::block_on_stream( + let _recv3 = futures03::executor::block_on_stream( notifications.listen(None, None) ); - let _recv4 = futures::executor::block_on_stream( + let _recv4 = futures03::executor::block_on_stream( notifications.listen(None, Some(&child_filter)) ); assert_eq!(notifications.listeners.len(), 2); @@ -465,7 +465,7 @@ mod tests { // given let mut recv = { let mut notifications = StorageNotifications::::default(); - let recv = futures::executor::block_on_stream(notifications.listen(None, None)); + let recv = futures03::executor::block_on_stream(notifications.listen(None, None)); // when let changeset = vec![]; diff --git a/core/rpc/Cargo.toml b/core/rpc/Cargo.toml index 1cd423c88f..25f0a467ee 100644 --- a/core/rpc/Cargo.toml +++ b/core/rpc/Cargo.toml @@ -21,6 +21,7 @@ state_machine = { package = "substrate-state-machine", path = "../state-machine" substrate-executor = { path = "../executor" } substrate-keystore = { path = "../keystore" } transaction_pool = { package = "substrate-transaction-pool", path = "../transaction-pool" } +hash-db = { version = "0.15.0", default-features = false } [dev-dependencies] assert_matches = "1.1" diff --git a/core/rpc/api/src/chain/error.rs b/core/rpc/api/src/chain/error.rs index 7c093789fa..eccb7f4f1b 100644 --- a/core/rpc/api/src/chain/error.rs +++ b/core/rpc/api/src/chain/error.rs @@ -23,6 +23,9 @@ use jsonrpc_core as rpc; /// Chain RPC Result type. pub type Result = std::result::Result; +/// State RPC future Result type. +pub type FutureResult = Box + Send>; + /// Chain RPC errors. #[derive(Debug, derive_more::Display, derive_more::From)] pub enum Error { diff --git a/core/rpc/api/src/chain/mod.rs b/core/rpc/api/src/chain/mod.rs index 6dc4a60e88..c0076d5987 100644 --- a/core/rpc/api/src/chain/mod.rs +++ b/core/rpc/api/src/chain/mod.rs @@ -23,7 +23,7 @@ use jsonrpc_core::Result as RpcResult; use jsonrpc_core::futures::Future; use jsonrpc_derive::rpc; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; -use self::error::Result; +use self::error::{FutureResult, Result}; pub use self::gen_client::Client as ChainClient; @@ -35,11 +35,11 @@ pub trait ChainApi { /// Get header of a relay chain block. #[rpc(name = "chain_getHeader")] - fn header(&self, hash: Option) -> Result>; + fn header(&self, hash: Option) -> FutureResult>; /// Get header and body of a relay chain block. #[rpc(name = "chain_getBlock")] - fn block(&self, hash: Option) -> Result>; + fn block(&self, hash: Option) -> FutureResult>; /// Get hash of the n-th block in the canon chain. /// diff --git a/core/rpc/api/src/state/error.rs b/core/rpc/api/src/state/error.rs index f5e9112b94..553a06e896 100644 --- a/core/rpc/api/src/state/error.rs +++ b/core/rpc/api/src/state/error.rs @@ -22,6 +22,9 @@ use jsonrpc_core as rpc; /// State RPC Result type. pub type Result = std::result::Result; +/// State RPC future Result type. +pub type FutureResult = Box + Send>; + /// State RPC errors. #[derive(Debug, derive_more::Display, derive_more::From)] pub enum Error { diff --git a/core/rpc/api/src/state/mod.rs b/core/rpc/api/src/state/mod.rs index f7cff7e397..0d06092ca1 100644 --- a/core/rpc/api/src/state/mod.rs +++ b/core/rpc/api/src/state/mod.rs @@ -25,7 +25,7 @@ use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use primitives::Bytes; use primitives::storage::{StorageKey, StorageData, StorageChangeSet}; use runtime_version::RuntimeVersion; -use self::error::Result; +use self::error::FutureResult; pub use self::gen_client::Client as StateClient; @@ -37,23 +37,23 @@ pub trait StateApi { /// Call a contract at a block's state. #[rpc(name = "state_call", alias("state_callAt"))] - fn call(&self, name: String, bytes: Bytes, hash: Option) -> Result; + fn call(&self, name: String, bytes: Bytes, hash: Option) -> FutureResult; /// Returns the keys with prefix, leave empty to get all the keys #[rpc(name = "state_getKeys")] - fn storage_keys(&self, prefix: StorageKey, hash: Option) -> Result>; + fn storage_keys(&self, prefix: StorageKey, hash: Option) -> FutureResult>; /// Returns a storage entry at a specific block's state. #[rpc(name = "state_getStorage", alias("state_getStorageAt"))] - fn storage(&self, key: StorageKey, hash: Option) -> Result>; + fn storage(&self, key: StorageKey, hash: Option) -> FutureResult>; /// Returns the hash of a storage entry at a block's state. #[rpc(name = "state_getStorageHash", alias("state_getStorageHashAt"))] - fn storage_hash(&self, key: StorageKey, hash: Option) -> Result>; + fn storage_hash(&self, key: StorageKey, hash: Option) -> FutureResult>; /// Returns the size of a storage entry at a block's state. #[rpc(name = "state_getStorageSize", alias("state_getStorageSizeAt"))] - fn storage_size(&self, key: StorageKey, hash: Option) -> Result>; + fn storage_size(&self, key: StorageKey, hash: Option) -> FutureResult>; /// Returns the keys with prefix from a child storage, leave empty to get all the keys #[rpc(name = "state_getChildKeys")] @@ -62,7 +62,7 @@ pub trait StateApi { child_storage_key: StorageKey, prefix: StorageKey, hash: Option - ) -> Result>; + ) -> FutureResult>; /// Returns a child storage entry at a specific block's state. #[rpc(name = "state_getChildStorage")] @@ -71,7 +71,7 @@ pub trait StateApi { child_storage_key: StorageKey, key: StorageKey, hash: Option - ) -> Result>; + ) -> FutureResult>; /// Returns the hash of a child storage entry at a block's state. #[rpc(name = "state_getChildStorageHash")] @@ -80,7 +80,7 @@ pub trait StateApi { child_storage_key: StorageKey, key: StorageKey, hash: Option - ) -> Result>; + ) -> FutureResult>; /// Returns the size of a child storage entry at a block's state. #[rpc(name = "state_getChildStorageSize")] @@ -89,15 +89,15 @@ pub trait StateApi { child_storage_key: StorageKey, key: StorageKey, hash: Option - ) -> Result>; + ) -> FutureResult>; /// Returns the runtime metadata as an opaque blob. #[rpc(name = "state_getMetadata")] - fn metadata(&self, hash: Option) -> Result; + fn metadata(&self, hash: Option) -> FutureResult; /// Get the runtime version. #[rpc(name = "state_getRuntimeVersion", alias("chain_getRuntimeVersion"))] - fn runtime_version(&self, hash: Option) -> Result; + fn runtime_version(&self, hash: Option) -> FutureResult; /// Query historical storage entries (by key) starting from a block given as the second parameter. /// @@ -109,7 +109,7 @@ pub trait StateApi { keys: Vec, block: Hash, hash: Option - ) -> Result>>; + ) -> FutureResult>>; /// New runtime version subscription #[pubsub( diff --git a/core/rpc/src/chain/chain_full.rs b/core/rpc/src/chain/chain_full.rs new file mode 100644 index 0000000000..ad359a9300 --- /dev/null +++ b/core/rpc/src/chain/chain_full.rs @@ -0,0 +1,79 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Blockchain API backend for full nodes. + +use std::sync::Arc; +use rpc::futures::future::result; + +use api::Subscriptions; +use client::{backend::Backend, CallExecutor, Client}; +use primitives::{H256, Blake2Hasher}; +use sr_primitives::{ + generic::{BlockId, SignedBlock}, + traits::{Block as BlockT}, +}; + +use super::{ChainBackend, client_err, error::FutureResult}; + +/// Blockchain API backend for full nodes. Reads all the data from local database. +pub struct FullChain { + /// Substrate client. + client: Arc>, + /// Current subscriptions. + subscriptions: Subscriptions, +} + +impl FullChain { + /// Create new Chain API RPC handler. + pub fn new(client: Arc>, subscriptions: Subscriptions) -> Self { + Self { + client, + subscriptions, + } + } +} + +impl ChainBackend for FullChain where + Block: BlockT + 'static, + B: Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + 'static, + RA: Send + Sync + 'static, +{ + fn client(&self) -> &Arc> { + &self.client + } + + fn subscriptions(&self) -> &Subscriptions { + &self.subscriptions + } + + fn header(&self, hash: Option) -> FutureResult> { + Box::new(result(self.client + .header(&BlockId::Hash(self.unwrap_or_best(hash))) + .map_err(client_err) + )) + } + + fn block(&self, hash: Option) + -> FutureResult>> + { + Box::new(result(self.client + .block(&BlockId::Hash(self.unwrap_or_best(hash))) + .map_err(client_err) + )) + } +} diff --git a/core/rpc/src/chain/chain_light.rs b/core/rpc/src/chain/chain_light.rs new file mode 100644 index 0000000000..d969d6ca93 --- /dev/null +++ b/core/rpc/src/chain/chain_light.rs @@ -0,0 +1,123 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Blockchain API backend for light nodes. + +use std::sync::Arc; +use futures03::{future::ready, FutureExt, TryFutureExt}; +use rpc::futures::future::{result, Future, Either}; + +use api::Subscriptions; +use client::{ + self, Client, + light::{ + fetcher::{Fetcher, RemoteBodyRequest}, + blockchain::RemoteBlockchain, + }, +}; +use primitives::{H256, Blake2Hasher}; +use sr_primitives::{ + generic::{BlockId, SignedBlock}, + traits::{Block as BlockT}, +}; + +use super::{ChainBackend, client_err, error::FutureResult}; + +/// Blockchain API backend for light nodes. Reads all the data from local +/// database, if available, or fetches it from remote node otherwise. +pub struct LightChain { + /// Substrate client. + client: Arc>, + /// Current subscriptions. + subscriptions: Subscriptions, + /// Remote blockchain reference + remote_blockchain: Arc>, + /// Remote fetcher reference. + fetcher: Arc, +} + +impl> LightChain { + /// Create new Chain API RPC handler. + pub fn new( + client: Arc>, + subscriptions: Subscriptions, + remote_blockchain: Arc>, + fetcher: Arc, + ) -> Self { + Self { + client, + subscriptions, + remote_blockchain, + fetcher, + } + } +} + +impl ChainBackend for LightChain where + Block: BlockT + 'static, + B: client::backend::Backend + Send + Sync + 'static, + E: client::CallExecutor + Send + Sync + 'static, + RA: Send + Sync + 'static, + F: Fetcher + Send + Sync + 'static, +{ + fn client(&self) -> &Arc> { + &self.client + } + + fn subscriptions(&self) -> &Subscriptions { + &self.subscriptions + } + + fn header(&self, hash: Option) -> FutureResult> { + let hash = self.unwrap_or_best(hash); + + let fetcher = self.fetcher.clone(); + let maybe_header = client::light::blockchain::future_header( + &*self.remote_blockchain, + &*fetcher, + BlockId::Hash(hash), + ); + + Box::new(maybe_header.then(move |result| + ready(result.map_err(client_err)), + ).boxed().compat()) + } + + fn block(&self, hash: Option) + -> FutureResult>> + { + let fetcher = self.fetcher.clone(); + let block = self.header(hash) + .and_then(move |header| match header { + Some(header) => Either::A(fetcher + .remote_body(RemoteBodyRequest { + header: header.clone(), + retry_count: Default::default(), + }) + .boxed() + .compat() + .map(move |body| Some(SignedBlock { + block: Block::new(header, body), + justification: None, + })) + .map_err(client_err) + ), + None => Either::B(result(Ok(None))), + }); + + Box::new(block) + } +} diff --git a/core/rpc/src/chain/mod.rs b/core/rpc/src/chain/mod.rs index dde54f6278..4c59d227c2 100644 --- a/core/rpc/src/chain/mod.rs +++ b/core/rpc/src/chain/mod.rs @@ -16,95 +16,181 @@ //! Substrate blockchain API. +mod chain_full; +mod chain_light; + #[cfg(test)] mod tests; use std::sync::Arc; use futures03::{future, StreamExt as _, TryStreamExt as _}; +use log::warn; +use rpc::{ + Result as RpcResult, + futures::{stream, Future, Sink, Stream}, +}; -use client::{self, Client, BlockchainEvents}; -use rpc::Result as RpcResult; -use rpc::futures::{stream, Future, Sink, Stream}; use api::Subscriptions; +use client::{ + self, Client, BlockchainEvents, + light::{fetcher::Fetcher, blockchain::RemoteBlockchain}, +}; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; -use log::warn; use primitives::{H256, Blake2Hasher}; -use sr_primitives::generic::{BlockId, SignedBlock}; -use sr_primitives::traits::{Block as BlockT, Header, NumberFor}; -use self::error::{Error, Result}; +use sr_primitives::{ + generic::{BlockId, SignedBlock}, + traits::{Block as BlockT, Header, NumberFor}, +}; + +use self::error::{Result, Error, FutureResult}; pub use api::chain::*; -/// Chain API with subscriptions support. -pub struct Chain { - /// Substrate client. - client: Arc>, - /// Current subscriptions. - subscriptions: Subscriptions, -} +/// Blockchain backend API +trait ChainBackend: Send + Sync + 'static + where + Block: BlockT + 'static, + B: client::backend::Backend + Send + Sync + 'static, + E: client::CallExecutor + Send + Sync + 'static, +{ + /// Get client reference. + fn client(&self) -> &Arc>; -impl Chain { - /// Create new Chain API RPC handler. - pub fn new(client: Arc>, subscriptions: Subscriptions) -> Self { - Self { - client, - subscriptions, + /// Get subscriptions reference. + fn subscriptions(&self) -> &Subscriptions; + + /// Tries to unwrap passed block hash, or uses best block hash otherwise. + fn unwrap_or_best(&self, hash: Option) -> Block::Hash { + match hash.into() { + None => self.client().info().chain.best_hash, + Some(hash) => hash, } } -} -impl Chain where - Block: BlockT + 'static, - B: client::backend::Backend + Send + Sync + 'static, - E: client::CallExecutor + Send + Sync + 'static, - RA: Send + Sync + 'static -{ - fn unwrap_or_best(&self, hash: Option) -> Result { - Ok(match hash.into() { - None => self.client.info().chain.best_hash, - Some(hash) => hash, + /// Get header of a relay chain block. + fn header(&self, hash: Option) -> FutureResult>; + + /// Get header and body of a relay chain block. + fn block(&self, hash: Option) -> FutureResult>>; + + /// Get hash of the n-th block in the canon chain. + /// + /// By default returns latest block hash. + fn block_hash( + &self, + number: Option>>, + ) -> Result> { + Ok(match number { + None => Some(self.client().info().chain.best_hash), + Some(num_or_hex) => self.client() + .header(&BlockId::number(num_or_hex.to_number()?)) + .map_err(client_err)? + .map(|h| h.hash()), }) } - fn subscribe_headers( + /// Get hash of the last finalized block in the canon chain. + fn finalized_head(&self) -> Result { + Ok(self.client().info().chain.finalized_hash) + } + + /// New head subscription + fn subscribe_new_heads( &self, + _metadata: crate::metadata::Metadata, subscriber: Subscriber, - best_block_hash: G, - stream: F, - ) where - F: FnOnce() -> S, - G: FnOnce() -> Result>, - ERR: ::std::fmt::Debug, - S: Stream + Send + 'static, - { - self.subscriptions.add(subscriber, |sink| { - // send current head right at the start. - let header = best_block_hash() - .and_then(|hash| self.header(hash.into())) - .and_then(|header| { - header.ok_or_else(|| "Best header missing.".to_owned().into()) - }) - .map_err(Into::into); - - // send further subscriptions - let stream = stream() - .map(|res| Ok(res)) - .map_err(|e| warn!("Block notification stream error: {:?}", e)); - - sink - .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) - .send_all( - stream::iter_result(vec![Ok(header)]) - .chain(stream) - ) - // we ignore the resulting Stream (if the first stream is over we are unsubscribed) - .map(|_| ()) - }); + ) { + subscribe_headers( + self.client(), + self.subscriptions(), + subscriber, + || self.client().info().chain.best_hash, + || self.client().import_notification_stream() + .filter(|notification| future::ready(notification.is_new_best)) + .map(|notification| Ok::<_, ()>(notification.header)) + .compat(), + ) + } + + /// Unsubscribe from new head subscription. + fn unsubscribe_new_heads( + &self, + _metadata: Option, + id: SubscriptionId, + ) -> RpcResult { + Ok(self.subscriptions().cancel(id)) + } + + /// New head subscription + fn subscribe_finalized_heads( + &self, + _metadata: crate::metadata::Metadata, + subscriber: Subscriber, + ) { + subscribe_headers( + self.client(), + self.subscriptions(), + subscriber, + || self.client().info().chain.finalized_hash, + || self.client().finality_notification_stream() + .map(|notification| Ok::<_, ()>(notification.header)) + .compat(), + ) + } + + /// Unsubscribe from new head subscription. + fn unsubscribe_finalized_heads( + &self, + _metadata: Option, + id: SubscriptionId, + ) -> RpcResult { + Ok(self.subscriptions().cancel(id)) } } -fn client_error(err: client::error::Error) -> Error { - Error::Client(Box::new(err)) +/// Create new state API that works on full node. +pub fn new_full( + client: Arc>, + subscriptions: Subscriptions, +) -> Chain + where + Block: BlockT + 'static, + B: client::backend::Backend + Send + Sync + 'static, + E: client::CallExecutor + Send + Sync + 'static + Clone, + RA: Send + Sync + 'static, +{ + Chain { + backend: Box::new(self::chain_full::FullChain::new(client, subscriptions)), + } +} + +/// Create new state API that works on light node. +pub fn new_light>( + client: Arc>, + subscriptions: Subscriptions, + remote_blockchain: Arc>, + fetcher: Arc, +) -> Chain + where + Block: BlockT + 'static, + B: client::backend::Backend + Send + Sync + 'static, + E: client::CallExecutor + Send + Sync + 'static + Clone, + RA: Send + Sync + 'static, + F: Send + Sync + 'static, +{ + Chain { + backend: Box::new(self::chain_light::LightChain::new( + client, + subscriptions, + remote_blockchain, + fetcher, + )), + } +} + +/// Chain API with subscriptions support. +pub struct Chain { + backend: Box>, } impl ChainApi, Block::Hash, Block::Header, SignedBlock> for Chain where @@ -115,58 +201,81 @@ impl ChainApi, Block::Hash, Block::Header, Sig { type Metadata = crate::metadata::Metadata; - fn header(&self, hash: Option) -> Result> { - let hash = self.unwrap_or_best(hash)?; - Ok(self.client.header(&BlockId::Hash(hash)).map_err(client_error)?) + fn header(&self, hash: Option) -> FutureResult> { + self.backend.header(hash) } - fn block(&self, hash: Option) - -> Result>> + fn block(&self, hash: Option) -> FutureResult>> { - let hash = self.unwrap_or_best(hash)?; - Ok(self.client.block(&BlockId::Hash(hash)).map_err(client_error)?) + self.backend.block(hash) } fn block_hash(&self, number: Option>>) -> Result> { - Ok(match number { - None => Some(self.client.info().chain.best_hash), - Some(num_or_hex) => self.client - .header(&BlockId::number(num_or_hex.to_number()?)) - .map_err(client_error)? - .map(|h| h.hash()), - }) + self.backend.block_hash(number) } fn finalized_head(&self) -> Result { - Ok(self.client.info().chain.finalized_hash) + self.backend.finalized_head() } - fn subscribe_new_heads(&self, _metadata: Self::Metadata, subscriber: Subscriber) { - self.subscribe_headers( - subscriber, - || self.block_hash(None.into()), - || self.client.import_notification_stream() - .filter(|notification| future::ready(notification.is_new_best)) - .map(|notification| Ok::<_, ()>(notification.header)) - .compat(), - ) + fn subscribe_new_heads(&self, metadata: Self::Metadata, subscriber: Subscriber) { + self.backend.subscribe_new_heads(metadata, subscriber) } - fn unsubscribe_new_heads(&self, _metadata: Option, id: SubscriptionId) -> RpcResult { - Ok(self.subscriptions.cancel(id)) + fn unsubscribe_new_heads(&self, metadata: Option, id: SubscriptionId) -> RpcResult { + self.backend.unsubscribe_new_heads(metadata, id) } - fn subscribe_finalized_heads(&self, _meta: Self::Metadata, subscriber: Subscriber) { - self.subscribe_headers( - subscriber, - || Ok(Some(self.client.info().chain.finalized_hash)), - || self.client.finality_notification_stream() - .map(|notification| Ok::<_, ()>(notification.header)) - .compat(), - ) + fn subscribe_finalized_heads(&self, metadata: Self::Metadata, subscriber: Subscriber) { + self.backend.subscribe_finalized_heads(metadata, subscriber) } - fn unsubscribe_finalized_heads(&self, _metadata: Option, id: SubscriptionId) -> RpcResult { - Ok(self.subscriptions.cancel(id)) + fn unsubscribe_finalized_heads(&self, metadata: Option, id: SubscriptionId) -> RpcResult { + self.backend.unsubscribe_finalized_heads(metadata, id) } } + +/// Subscribe to new headers. +fn subscribe_headers( + client: &Arc>, + subscriptions: &Subscriptions, + subscriber: Subscriber, + best_block_hash: G, + stream: F, +) where + Block: BlockT + 'static, + B: client::backend::Backend + Send + Sync + 'static, + E: client::CallExecutor + Send + Sync + 'static, + F: FnOnce() -> S, + G: FnOnce() -> Block::Hash, + ERR: ::std::fmt::Debug, + S: Stream + Send + 'static, +{ + subscriptions.add(subscriber, |sink| { + // send current head right at the start. + let header = client.header(&BlockId::Hash(best_block_hash())) + .map_err(client_err) + .and_then(|header| { + header.ok_or_else(|| "Best header missing.".to_owned().into()) + }) + .map_err(Into::into); + + // send further subscriptions + let stream = stream() + .map(|res| Ok(res)) + .map_err(|e| warn!("Block notification stream error: {:?}", e)); + + sink + .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) + .send_all( + stream::iter_result(vec![Ok(header)]) + .chain(stream) + ) + // we ignore the resulting Stream (if the first stream is over we are unsubscribed) + .map(|_| ()) + }); +} + +fn client_err(err: client::error::Error) -> Error { + Error::Client(Box::new(err)) +} diff --git a/core/rpc/src/chain/tests.rs b/core/rpc/src/chain/tests.rs index af00f220e4..8b46befee6 100644 --- a/core/rpc/src/chain/tests.rs +++ b/core/rpc/src/chain/tests.rs @@ -27,13 +27,11 @@ fn should_return_header() { let core = ::tokio::runtime::Runtime::new().unwrap(); let remote = core.executor(); - let client = Chain { - client: Arc::new(test_client::new()), - subscriptions: Subscriptions::new(Arc::new(remote)), - }; + let client = Arc::new(test_client::new()); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); assert_matches!( - client.header(Some(client.client.genesis_hash()).into()), + api.header(Some(client.genesis_hash()).into()).wait(), Ok(Some(ref x)) if x == &Header { parent_hash: H256::from_low_u64_be(0), number: 0, @@ -44,7 +42,7 @@ fn should_return_header() { ); assert_matches!( - client.header(None.into()), + api.header(None.into()).wait(), Ok(Some(ref x)) if x == &Header { parent_hash: H256::from_low_u64_be(0), number: 0, @@ -55,7 +53,7 @@ fn should_return_header() { ); assert_matches!( - client.header(Some(H256::from_low_u64_be(5)).into()), + api.header(Some(H256::from_low_u64_be(5)).into()).wait(), Ok(None) ); } @@ -65,26 +63,24 @@ fn should_return_a_block() { let core = ::tokio::runtime::Runtime::new().unwrap(); let remote = core.executor(); - let api = Chain { - client: Arc::new(test_client::new()), - subscriptions: Subscriptions::new(Arc::new(remote)), - }; + let client = Arc::new(test_client::new()); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); - let block = api.client.new_block(Default::default()).unwrap().bake().unwrap(); + let block = client.new_block(Default::default()).unwrap().bake().unwrap(); let block_hash = block.hash(); - api.client.import(BlockOrigin::Own, block).unwrap(); + client.import(BlockOrigin::Own, block).unwrap(); // Genesis block is not justified assert_matches!( - api.block(Some(api.client.genesis_hash()).into()), + api.block(Some(client.genesis_hash()).into()).wait(), Ok(Some(SignedBlock { justification: None, .. })) ); assert_matches!( - api.block(Some(block_hash).into()), + api.block(Some(block_hash).into()).wait(), Ok(Some(ref x)) if x.block == Block { header: Header { - parent_hash: api.client.genesis_hash(), + parent_hash: client.genesis_hash(), number: 1, state_root: x.block.header.state_root.clone(), extrinsics_root: "03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314".parse().unwrap(), @@ -95,10 +91,10 @@ fn should_return_a_block() { ); assert_matches!( - api.block(None.into()), + api.block(None.into()).wait(), Ok(Some(ref x)) if x.block == Block { header: Header { - parent_hash: api.client.genesis_hash(), + parent_hash: client.genesis_hash(), number: 1, state_root: x.block.header.state_root.clone(), extrinsics_root: "03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314".parse().unwrap(), @@ -109,7 +105,7 @@ fn should_return_a_block() { ); assert_matches!( - api.block(Some(H256::from_low_u64_be(5)).into()), + api.block(Some(H256::from_low_u64_be(5)).into()).wait(), Ok(None) ); } @@ -119,40 +115,38 @@ fn should_return_block_hash() { let core = ::tokio::runtime::Runtime::new().unwrap(); let remote = core.executor(); - let client = Chain { - client: Arc::new(test_client::new()), - subscriptions: Subscriptions::new(Arc::new(remote)), - }; + let client = Arc::new(test_client::new()); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); assert_matches!( - client.block_hash(None.into()), - Ok(Some(ref x)) if x == &client.client.genesis_hash() + api.block_hash(None.into()), + Ok(Some(ref x)) if x == &client.genesis_hash() ); assert_matches!( - client.block_hash(Some(0u64.into()).into()), - Ok(Some(ref x)) if x == &client.client.genesis_hash() + api.block_hash(Some(0u64.into()).into()), + Ok(Some(ref x)) if x == &client.genesis_hash() ); assert_matches!( - client.block_hash(Some(1u64.into()).into()), + api.block_hash(Some(1u64.into()).into()), Ok(None) ); - let block = client.client.new_block(Default::default()).unwrap().bake().unwrap(); - client.client.import(BlockOrigin::Own, block.clone()).unwrap(); + let block = client.new_block(Default::default()).unwrap().bake().unwrap(); + client.import(BlockOrigin::Own, block.clone()).unwrap(); assert_matches!( - client.block_hash(Some(0u64.into()).into()), - Ok(Some(ref x)) if x == &client.client.genesis_hash() + api.block_hash(Some(0u64.into()).into()), + Ok(Some(ref x)) if x == &client.genesis_hash() ); assert_matches!( - client.block_hash(Some(1u64.into()).into()), + api.block_hash(Some(1u64.into()).into()), Ok(Some(ref x)) if x == &block.hash() ); assert_matches!( - client.block_hash(Some(::primitives::U256::from(1u64).into()).into()), + api.block_hash(Some(::primitives::U256::from(1u64).into()).into()), Ok(Some(ref x)) if x == &block.hash() ); } @@ -163,30 +157,28 @@ fn should_return_finalized_hash() { let core = ::tokio::runtime::Runtime::new().unwrap(); let remote = core.executor(); - let client = Chain { - client: Arc::new(test_client::new()), - subscriptions: Subscriptions::new(Arc::new(remote)), - }; + let client = Arc::new(test_client::new()); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); assert_matches!( - client.finalized_head(), - Ok(ref x) if x == &client.client.genesis_hash() + api.finalized_head(), + Ok(ref x) if x == &client.genesis_hash() ); // import new block - let builder = client.client.new_block(Default::default()).unwrap(); - client.client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); + let builder = client.new_block(Default::default()).unwrap(); + client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); // no finalization yet assert_matches!( - client.finalized_head(), - Ok(ref x) if x == &client.client.genesis_hash() + api.finalized_head(), + Ok(ref x) if x == &client.genesis_hash() ); // finalize - client.client.finalize_block(BlockId::number(1), None).unwrap(); + client.finalize_block(BlockId::number(1), None).unwrap(); assert_matches!( - client.finalized_head(), - Ok(ref x) if x == &client.client.block_hash(1).unwrap().unwrap() + api.finalized_head(), + Ok(ref x) if x == &client.block_hash(1).unwrap().unwrap() ); } @@ -197,18 +189,16 @@ fn should_notify_about_latest_block() { let (subscriber, id, transport) = Subscriber::new_test("test"); { - let api = Chain { - client: Arc::new(test_client::new()), - subscriptions: Subscriptions::new(Arc::new(remote)), - }; + let client = Arc::new(test_client::new()); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); api.subscribe_new_heads(Default::default(), subscriber); // assert id assigned assert_eq!(core.block_on(id), Ok(Ok(SubscriptionId::Number(1)))); - let builder = api.client.new_block(Default::default()).unwrap(); - api.client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); + let builder = client.new_block(Default::default()).unwrap(); + client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); } // assert initial head sent. @@ -228,19 +218,17 @@ fn should_notify_about_finalized_block() { let (subscriber, id, transport) = Subscriber::new_test("test"); { - let api = Chain { - client: Arc::new(test_client::new()), - subscriptions: Subscriptions::new(Arc::new(remote)), - }; + let client = Arc::new(test_client::new()); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); api.subscribe_finalized_heads(Default::default(), subscriber); // assert id assigned assert_eq!(core.block_on(id), Ok(Ok(SubscriptionId::Number(1)))); - let builder = api.client.new_block(Default::default()).unwrap(); - api.client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); - api.client.finalize_block(BlockId::number(1), None).unwrap(); + let builder = client.new_block(Default::default()).unwrap(); + client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); + client.finalize_block(BlockId::number(1), None).unwrap(); } // assert initial head sent. diff --git a/core/rpc/src/state/mod.rs b/core/rpc/src/state/mod.rs index 8e44275f1e..390f95ab41 100644 --- a/core/rpc/src/state/mod.rs +++ b/core/rpc/src/state/mod.rs @@ -16,357 +16,216 @@ //! Substrate state API. +mod state_full; +mod state_light; + #[cfg(test)] mod tests; -use std::{ - collections::{BTreeMap, HashMap}, - ops::Range, - sync::Arc, -}; +use std::sync::Arc; use futures03::{future, StreamExt as _, TryStreamExt as _}; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use log::warn; +use rpc::{ + Result as RpcResult, + futures::{stream, Future, Sink, Stream}, +}; -use client::{self, Client, CallExecutor, BlockchainEvents, runtime_api::Metadata}; -use rpc::Result as RpcResult; -use rpc::futures::{stream, Future, Sink, Stream}; use api::Subscriptions; -use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; -use log::{warn, trace}; -use primitives::hexdisplay::HexDisplay; -use primitives::storage::{self, StorageKey, StorageData, StorageChangeSet}; -use primitives::{H256, Blake2Hasher, Bytes}; -use sr_primitives::generic::BlockId; -use sr_primitives::traits::{ - Block as BlockT, Header, ProvideRuntimeApi, NumberFor, - SaturatedConversion +use client::{ + BlockchainEvents, Client, CallExecutor, + runtime_api::Metadata, + light::{blockchain::RemoteBlockchain, fetcher::Fetcher}, +}; +use primitives::{ + Blake2Hasher, Bytes, H256, + storage::{well_known_keys, StorageKey, StorageData, StorageChangeSet}, }; use runtime_version::RuntimeVersion; -use self::error::{Error, Result}; -use state_machine::{self, ExecutionStrategy}; - -pub use api::state::*; - -/// State API with subscriptions support. -pub struct State { - /// Substrate client. - client: Arc>, - /// Current subscriptions. - subscriptions: Subscriptions, -} +use sr_primitives::{ + generic::BlockId, + traits::{Block as BlockT, ProvideRuntimeApi}, +}; -/// Ranges to query in state_queryStorage. -struct QueryStorageRange { - /// Hashes of all the blocks in the range. - pub hashes: Vec, - /// Number of the first block in the range. - pub first_number: NumberFor, - /// Blocks subrange ([begin; end) indices within `hashes`) where we should read keys at - /// each state to get changes. - pub unfiltered_range: Range, - /// Blocks subrange ([begin; end) indices within `hashes`) where we could pre-filter - /// blocks-with-changes by using changes tries. - pub filtered_range: Option>, -} +use self::error::{Error, FutureResult}; -fn client_err(err: client::error::Error) -> Error { - Error::Client(Box::new(err)) -} +pub use api::state::*; -impl State where - Block: BlockT, - B: client::backend::Backend, - E: CallExecutor, +/// State backend API. +pub trait StateBackend: Send + Sync + 'static + where + Block: BlockT + 'static, + B: client::backend::Backend + Send + Sync + 'static, + E: client::CallExecutor + Send + Sync + 'static, + RA: Send + Sync + 'static, { - /// Create new State API RPC handler. - pub fn new(client: Arc>, subscriptions: Subscriptions) -> Self { - Self { - client, - subscriptions, - } - } + /// Get client reference. + fn client(&self) -> &Arc>; - /// Splits the `query_storage` block range into 'filtered' and 'unfiltered' subranges. - /// Blocks that contain changes within filtered subrange could be filtered using changes tries. - /// Blocks that contain changes within unfiltered subrange must be filtered manually. - fn split_query_storage_range( - &self, - from: Block::Hash, - to: Option - ) -> Result> { - let to = self.unwrap_or_best(to)?; - let from_hdr = self.client.header(&BlockId::hash(from)).map_err(client_err)?; - let to_hdr = self.client.header(&BlockId::hash(to)).map_err(client_err)?; - match (from_hdr, to_hdr) { - (Some(ref from), Some(ref to)) if from.number() <= to.number() => { - // check if we can get from `to` to `from` by going through parent_hashes. - let from_number = *from.number(); - let blocks = { - let mut blocks = vec![to.hash()]; - let mut last = to.clone(); - while *last.number() > from_number { - let hdr = self.client - .header(&BlockId::hash(*last.parent_hash())) - .map_err(client_err)?; - if let Some(hdr) = hdr { - blocks.push(hdr.hash()); - last = hdr; - } else { - return Err(invalid_block_range( - Some(from), - Some(to), - format!("Parent of {} ({}) not found", last.number(), last.hash()), - )) - } - } - if last.hash() != from.hash() { - return Err(invalid_block_range( - Some(from), - Some(to), - format!("Expected to reach `from`, got {} ({})", last.number(), last.hash()), - )) - } - blocks.reverse(); - blocks - }; - // check if we can filter blocks-with-changes from some (sub)range using changes tries - let changes_trie_range = self.client - .max_key_changes_range(from_number, BlockId::Hash(to.hash())) - .map_err(client_err)?; - let filtered_range_begin = changes_trie_range.map(|(begin, _)| (begin - from_number).saturated_into::()); - let (unfiltered_range, filtered_range) = split_range(blocks.len(), filtered_range_begin); - Ok(QueryStorageRange { - hashes: blocks, - first_number: from_number, - unfiltered_range, - filtered_range, - }) - }, - (from, to) => Err( - invalid_block_range(from.as_ref(), to.as_ref(), "Invalid range or unknown block".into()) - ), - } - } + /// Get subscriptions reference. + fn subscriptions(&self) -> &Subscriptions; - /// Iterates through range.unfiltered_range and check each block for changes of keys' values. - fn query_storage_unfiltered( + /// Call runtime method at given block. + fn call( &self, - range: &QueryStorageRange, - keys: &[StorageKey], - last_values: &mut HashMap>, - changes: &mut Vec>, - ) -> Result<()> { - for block in range.unfiltered_range.start..range.unfiltered_range.end { - let block_hash = range.hashes[block].clone(); - let mut block_changes = StorageChangeSet { block: block_hash.clone(), changes: Vec::new() }; - let id = BlockId::hash(block_hash); - for key in keys { - let (has_changed, data) = { - let curr_data = self.client.storage(&id, key) - .map_err(client_err)?; - match last_values.get(key) { - Some(prev_data) => (curr_data != *prev_data, curr_data), - None => (true, curr_data), - } - }; - if has_changed { - block_changes.changes.push((key.clone(), data.clone())); - } - last_values.insert(key.clone(), data); - } - if !block_changes.changes.is_empty() { - changes.push(block_changes); - } - } - Ok(()) - } + block: Option, + method: String, + call_data: Bytes, + ) -> FutureResult; - /// Iterates through all blocks that are changing keys within range.filtered_range and collects these changes. - fn query_storage_filtered( + /// Returns the keys with prefix, leave empty to get all the keys. + fn storage_keys( &self, - range: &QueryStorageRange, - keys: &[StorageKey], - last_values: &HashMap>, - changes: &mut Vec>, - ) -> Result<()> { - let (begin, end) = match range.filtered_range { - Some(ref filtered_range) => ( - range.first_number + filtered_range.start.saturated_into(), - BlockId::Hash(range.hashes[filtered_range.end - 1].clone()) - ), - None => return Ok(()), - }; - let mut changes_map: BTreeMap, StorageChangeSet> = BTreeMap::new(); - for key in keys { - let mut last_block = None; - let mut last_value = last_values.get(key).cloned().unwrap_or_default(); - for (block, _) in self.client.key_changes(begin, end, key).map_err(client_err)?.into_iter().rev() { - if last_block == Some(block) { - continue; - } - - let block_hash = range.hashes[(block - range.first_number).saturated_into::()].clone(); - let id = BlockId::Hash(block_hash); - let value_at_block = self.client.storage(&id, key).map_err(client_err)?; - if last_value == value_at_block { - continue; - } - - changes_map.entry(block) - .or_insert_with(|| StorageChangeSet { block: block_hash, changes: Vec::new() }) - .changes.push((key.clone(), value_at_block.clone())); - last_block = Some(block); - last_value = value_at_block; - } - } - if let Some(additional_capacity) = changes_map.len().checked_sub(changes.len()) { - changes.reserve(additional_capacity); - } - changes.extend(changes_map.into_iter().map(|(_, cs)| cs)); - Ok(()) - } -} + block: Option, + prefix: StorageKey, + ) -> FutureResult>; -impl State where - Block: BlockT, - B: client::backend::Backend, - E: CallExecutor, -{ - fn unwrap_or_best(&self, hash: Option) -> Result { - crate::helpers::unwrap_or_else(|| Ok(self.client.info().chain.best_hash), hash) - } -} - -impl StateApi for State where - Block: BlockT + 'static, - B: client::backend::Backend + Send + Sync + 'static, - E: CallExecutor + Send + Sync + 'static + Clone, - RA: Send + Sync + 'static, - Client: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: Metadata -{ - type Metadata = crate::metadata::Metadata; - - fn call(&self, method: String, data: Bytes, block: Option) -> Result { - let block = self.unwrap_or_best(block)?; - trace!(target: "rpc", "Calling runtime at {:?} for method {} ({})", block, method, HexDisplay::from(&data.0)); - let return_data = self.client - .executor() - .call( - &BlockId::Hash(block), - &method, &data.0, ExecutionStrategy::NativeElseWasm, state_machine::NeverOffchainExt::new(), - ) - .map_err(client_err)?; - Ok(Bytes(return_data)) - } - - fn storage_keys(&self, key_prefix: StorageKey, block: Option) -> Result> { - let block = self.unwrap_or_best(block)?; - trace!(target: "rpc", "Querying storage keys at {:?}", block); - Ok(self.client.storage_keys(&BlockId::Hash(block), &key_prefix).map_err(client_err)?) - } - - fn storage(&self, key: StorageKey, block: Option) -> Result> { - let block = self.unwrap_or_best(block)?; - trace!(target: "rpc", "Querying storage at {:?} for key {}", block, HexDisplay::from(&key.0)); - Ok(self.client.storage(&BlockId::Hash(block), &key).map_err(client_err)?) - } - - fn storage_hash(&self, key: StorageKey, block: Option) -> Result> { - let block = self.unwrap_or_best(block)?; - trace!(target: "rpc", "Querying storage hash at {:?} for key {}", block, HexDisplay::from(&key.0)); - Ok(self.client.storage_hash(&BlockId::Hash(block), &key).map_err(client_err)?) - } + /// Returns a storage entry at a specific block's state. + fn storage( + &self, + block: Option, + key: StorageKey, + ) -> FutureResult>; - fn storage_size(&self, key: StorageKey, block: Option) -> Result> { - Ok(self.storage(key, block)?.map(|x| x.0.len() as u64)) - } + /// Returns the hash of a storage entry at a block's state. + fn storage_hash( + &self, + block: Option, + key: StorageKey, + ) -> FutureResult>; - fn child_storage( + /// Returns the size of a storage entry at a block's state. + fn storage_size( &self, - child_storage_key: StorageKey, + block: Option, key: StorageKey, - block: Option - ) -> Result> { - let block = self.unwrap_or_best(block)?; - trace!(target: "rpc", "Querying child storage at {:?} for key {}", block, HexDisplay::from(&key.0)); - Ok(self.client - .child_storage(&BlockId::Hash(block), &child_storage_key, &key) - .map_err(client_err)? - ) + ) -> FutureResult> { + Box::new(self.storage(block, key) + .map(|x| x.map(|x| x.0.len() as u64))) } + /// Returns the keys with prefix from a child storage, leave empty to get all the keys fn child_storage_keys( &self, + block: Option, child_storage_key: StorageKey, - key_prefix: StorageKey, - block: Option - ) -> Result> { - let block = self.unwrap_or_best(block)?; - trace!(target: "rpc", "Querying child storage keys at {:?}", block); - Ok(self.client - .child_storage_keys(&BlockId::Hash(block), &child_storage_key, &key_prefix) - .map_err(client_err)? - ) - } + prefix: StorageKey, + ) -> FutureResult>; + /// Returns a child storage entry at a specific block's state. + fn child_storage( + &self, + block: Option, + child_storage_key: StorageKey, + key: StorageKey, + ) -> FutureResult>; + + /// Returns the hash of a child storage entry at a block's state. fn child_storage_hash( &self, + block: Option, child_storage_key: StorageKey, key: StorageKey, - block: Option - ) -> Result> { - let block = self.unwrap_or_best(block)?; - trace!( - target: "rpc", "Querying child storage hash at {:?} for key {}", - block, - HexDisplay::from(&key.0), - ); - Ok(self.client - .child_storage_hash(&BlockId::Hash(block), &child_storage_key, &key) - .map_err(client_err)? - ) - } + ) -> FutureResult>; + /// Returns the size of a child storage entry at a block's state. fn child_storage_size( &self, + block: Option, child_storage_key: StorageKey, key: StorageKey, - block: Option - ) -> Result> { - Ok(self.child_storage(child_storage_key, key, block)?.map(|x| x.0.len() as u64)) + ) -> FutureResult> { + Box::new(self.child_storage(block, child_storage_key, key) + .map(|x| x.map(|x| x.0.len() as u64))) } - fn metadata(&self, block: Option) -> Result { - let block = self.unwrap_or_best(block)?; - self.client - .runtime_api() - .metadata(&BlockId::Hash(block)) - .map(Into::into) - .map_err(client_err) - } + /// Returns the runtime metadata as an opaque blob. + fn metadata(&self, block: Option) -> FutureResult; + + /// Get the runtime version. + fn runtime_version(&self, block: Option) -> FutureResult; + /// Query historical storage entries (by key) starting from a block given as the second parameter. + /// + /// NOTE This first returned result contains the initial state of storage for all keys. + /// Subsequent values in the vector represent changes to the previous state (diffs). fn query_storage( &self, - keys: Vec, from: Block::Hash, - to: Option - ) -> Result>> { - let range = self.split_query_storage_range(from, to)?; - let mut changes = Vec::new(); - let mut last_values = HashMap::new(); - self.query_storage_unfiltered(&range, &keys, &mut last_values, &mut changes)?; - self.query_storage_filtered(&range, &keys, &last_values, &mut changes)?; - Ok(changes) + to: Option, + keys: Vec, + ) -> FutureResult>>; + + /// New runtime version subscription + fn subscribe_runtime_version( + &self, + _meta: crate::metadata::Metadata, + subscriber: Subscriber, + ) { + let stream = match self.client().storage_changes_notification_stream( + Some(&[StorageKey(well_known_keys::CODE.to_vec())]), + None, + ) { + Ok(stream) => stream, + Err(err) => { + let _ = subscriber.reject(Error::from(client_err(err)).into()); + return; + } + }; + + self.subscriptions().add(subscriber, |sink| { + let version = self.runtime_version(None.into()) + .map_err(Into::into) + .wait(); + + let client = self.client().clone(); + let mut previous_version = version.clone(); + + let stream = stream + .filter_map(move |_| { + let info = client.info(); + let version = client + .runtime_version_at(&BlockId::hash(info.chain.best_hash)) + .map_err(client_err) + .map_err(Into::into); + if previous_version != version { + previous_version = version.clone(); + future::ready(Some(Ok::<_, ()>(version))) + } else { + future::ready(None) + } + }) + .compat(); + + sink + .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) + .send_all( + stream::iter_result(vec![Ok(version)]) + .chain(stream) + ) + // we ignore the resulting Stream (if the first stream is over we are unsubscribed) + .map(|_| ()) + }); } + /// Unsubscribe from runtime version subscription + fn unsubscribe_runtime_version( + &self, + _meta: Option, + id: SubscriptionId, + ) -> RpcResult { + Ok(self.subscriptions().cancel(id)) + } + + /// New storage subscription fn subscribe_storage( &self, - _meta: Self::Metadata, + _meta: crate::metadata::Metadata, subscriber: Subscriber>, keys: Option> ) { let keys = Into::>>::into(keys); - let stream = match self.client.storage_changes_notification_stream( + let stream = match self.client().storage_changes_notification_stream( keys.as_ref().map(|x| &**x), None ) { @@ -380,18 +239,19 @@ impl StateApi for State where // initial values let initial = stream::iter_result(keys .map(|keys| { - let block = self.client.info().chain.best_hash; + let block = self.client().info().chain.best_hash; let changes = keys .into_iter() - .map(|key| self.storage(key.clone(), Some(block.clone()).into()) + .map(|key| self.storage(Some(block.clone()).into(), key.clone()) .map(|val| (key.clone(), val)) + .wait() .unwrap_or_else(|_| (key, None)) ) .collect(); vec![Ok(Ok(StorageChangeSet { block, changes }))] }).unwrap_or_default()); - self.subscriptions.add(subscriber, |sink| { + self.subscriptions().add(subscriber, |sink| { let stream = stream .map(|(block, changes)| Ok::<_, ()>(Ok(StorageChangeSet { block, @@ -410,96 +270,175 @@ impl StateApi for State where }) } - fn unsubscribe_storage(&self, _meta: Option, id: SubscriptionId) -> RpcResult { - Ok(self.subscriptions.cancel(id)) + /// Unsubscribe from storage subscription + fn unsubscribe_storage( + &self, + _meta: Option, + id: SubscriptionId, + ) -> RpcResult { + Ok(self.subscriptions().cancel(id)) } +} - fn runtime_version(&self, at: Option) -> Result { - let at = self.unwrap_or_best(at)?; - Ok(self.client.runtime_version_at(&BlockId::Hash(at)).map_err(client_err)?) +/// Create new state API that works on full node. +pub fn new_full( + client: Arc>, + subscriptions: Subscriptions, +) -> State + where + Block: BlockT + 'static, + B: client::backend::Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + 'static + Clone, + RA: Send + Sync + 'static, + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: Metadata, +{ + State { + backend: Box::new(self::state_full::FullState::new(client, subscriptions)), } +} - fn subscribe_runtime_version(&self, _meta: Self::Metadata, subscriber: Subscriber) { - let stream = match self.client.storage_changes_notification_stream( - Some(&[StorageKey(storage::well_known_keys::CODE.to_vec())]), - None, - ) { - Ok(stream) => stream, - Err(err) => { - let _ = subscriber.reject(client_err(err).into()); - return; - } - }; +/// Create new state API that works on light node. +pub fn new_light>( + client: Arc>, + subscriptions: Subscriptions, + remote_blockchain: Arc>, + fetcher: Arc, +) -> State + where + Block: BlockT + 'static, + B: client::backend::Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + 'static + Clone, + RA: Send + Sync + 'static, + F: Send + Sync + 'static, +{ + State { + backend: Box::new(self::state_light::LightState::new( + client, + subscriptions, + remote_blockchain, + fetcher, + )), + } +} - self.subscriptions.add(subscriber, |sink| { - let version = self.runtime_version(None.into()) - .map_err(Into::into); +/// State API with subscriptions support. +pub struct State { + backend: Box>, +} - let client = self.client.clone(); - let mut previous_version = version.clone(); +impl StateApi for State + where + Block: BlockT + 'static, + B: client::backend::Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + 'static + Clone, + RA: Send + Sync + 'static, +{ + type Metadata = crate::metadata::Metadata; - let stream = stream - .filter_map(move |_| { - let info = client.info(); - let version = client - .runtime_version_at(&BlockId::hash(info.chain.best_hash)) - .map_err(client_err) - .map_err(Into::into); - if previous_version != version { - previous_version = version.clone(); - future::ready(Some(Ok::<_, ()>(version))) - } else { - future::ready(None) - } - }) - .compat(); + fn call(&self, method: String, data: Bytes, block: Option) -> FutureResult { + self.backend.call(block, method, data) + } - sink - .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) - .send_all( - stream::iter_result(vec![Ok(version)]) - .chain(stream) - ) - // we ignore the resulting Stream (if the first stream is over we are unsubscribed) - .map(|_| ()) - }); + fn storage_keys( + &self, + key_prefix: StorageKey, + block: Option, + ) -> FutureResult> { + self.backend.storage_keys(block, key_prefix) } - fn unsubscribe_runtime_version(&self, _meta: Option, id: SubscriptionId) -> RpcResult { - Ok(self.subscriptions.cancel(id)) + fn storage(&self, key: StorageKey, block: Option) -> FutureResult> { + self.backend.storage(block, key) } -} -/// Splits passed range into two subranges where: -/// - first range has at least one element in it; -/// - second range (optionally) starts at given `middle` element. -pub(crate) fn split_range(size: usize, middle: Option) -> (Range, Option>) { - // check if we can filter blocks-with-changes from some (sub)range using changes tries - let range2_begin = match middle { - // some of required changes tries are pruned => use available tries - Some(middle) if middle != 0 => Some(middle), - // all required changes tries are available, but we still want values at first block - // => do 'unfiltered' read for the first block and 'filtered' for the rest - Some(_) if size > 1 => Some(1), - // range contains single element => do not use changes tries - Some(_) => None, - // changes tries are not available => do 'unfiltered' read for the whole range - None => None, - }; - let range1 = 0..range2_begin.unwrap_or(size); - let range2 = range2_begin.map(|begin| begin..size); - (range1, range2) -} + fn storage_hash(&self, key: StorageKey, block: Option) -> FutureResult> { + self.backend.storage_hash(block, key) + } + + fn storage_size(&self, key: StorageKey, block: Option) -> FutureResult> { + self.backend.storage_size(block, key) + } + + fn child_storage( + &self, + child_storage_key: StorageKey, + key: StorageKey, + block: Option + ) -> FutureResult> { + self.backend.child_storage(block, child_storage_key, key) + } + + fn child_storage_keys( + &self, + child_storage_key: StorageKey, + key_prefix: StorageKey, + block: Option + ) -> FutureResult> { + self.backend.child_storage_keys(block, child_storage_key, key_prefix) + } + + fn child_storage_hash( + &self, + child_storage_key: StorageKey, + key: StorageKey, + block: Option + ) -> FutureResult> { + self.backend.child_storage_hash(block, child_storage_key, key) + } + + fn child_storage_size( + &self, + child_storage_key: StorageKey, + key: StorageKey, + block: Option + ) -> FutureResult> { + self.backend.child_storage_size(block, child_storage_key, key) + } -fn invalid_block_range(from: Option<&H>, to: Option<&H>, reason: String) -> error::Error { - let to_string = |x: Option<&H>| match x { - None => "unknown hash".into(), - Some(h) => format!("{} ({})", h.number(), h.hash()), - }; + fn metadata(&self, block: Option) -> FutureResult { + self.backend.metadata(block) + } - error::Error::InvalidBlockRange { - from: to_string(from), - to: to_string(to), - details: reason, + fn query_storage( + &self, + keys: Vec, + from: Block::Hash, + to: Option + ) -> FutureResult>> { + self.backend.query_storage(from, to, keys) } + + fn subscribe_storage( + &self, + meta: Self::Metadata, + subscriber: Subscriber>, + keys: Option> + ) { + self.backend.subscribe_storage(meta, subscriber, keys); + } + + fn unsubscribe_storage(&self, meta: Option, id: SubscriptionId) -> RpcResult { + self.backend.unsubscribe_storage(meta, id) + } + + fn runtime_version(&self, at: Option) -> FutureResult { + self.backend.runtime_version(at) + } + + fn subscribe_runtime_version(&self, meta: Self::Metadata, subscriber: Subscriber) { + self.backend.subscribe_runtime_version(meta, subscriber); + } + + fn unsubscribe_runtime_version( + &self, + meta: Option, + id: SubscriptionId, + ) -> RpcResult { + self.backend.unsubscribe_runtime_version(meta, id) + } +} + +fn client_err(err: client::error::Error) -> Error { + Error::Client(Box::new(err)) } diff --git a/core/rpc/src/state/state_full.rs b/core/rpc/src/state/state_full.rs new file mode 100644 index 0000000000..1f780d3e11 --- /dev/null +++ b/core/rpc/src/state/state_full.rs @@ -0,0 +1,389 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! State API backend for full nodes. + +use std::collections::{BTreeMap, HashMap}; +use std::sync::Arc; +use std::ops::Range; +use rpc::futures::future::result; + +use api::Subscriptions; +use client::{ + Client, CallExecutor, runtime_api::Metadata, + backend::Backend, error::Result as ClientResult, +}; +use primitives::{ + H256, Blake2Hasher, Bytes, + storage::{StorageKey, StorageData, StorageChangeSet}, +}; +use runtime_version::RuntimeVersion; +use state_machine::{NeverOffchainExt, ExecutionStrategy}; +use sr_primitives::{ + generic::BlockId, + traits::{Block as BlockT, Header, NumberFor, ProvideRuntimeApi, SaturatedConversion}, +}; + +use super::{StateBackend, error::{FutureResult, Error, Result}, client_err}; + +/// Ranges to query in state_queryStorage. +struct QueryStorageRange { + /// Hashes of all the blocks in the range. + pub hashes: Vec, + /// Number of the first block in the range. + pub first_number: NumberFor, + /// Blocks subrange ([begin; end) indices within `hashes`) where we should read keys at + /// each state to get changes. + pub unfiltered_range: Range, + /// Blocks subrange ([begin; end) indices within `hashes`) where we could pre-filter + /// blocks-with-changes by using changes tries. + pub filtered_range: Option>, +} + +pub struct FullState { + client: Arc>, + subscriptions: Subscriptions, +} + +impl FullState + where + Block: BlockT + 'static, + B: Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + 'static + Clone, +{ + /// + pub fn new(client: Arc>, subscriptions: Subscriptions) -> Self { + Self { client, subscriptions } + } + + /// Returns given block hash or best block hash if None is passed. + fn block_or_best(&self, hash: Option) -> ClientResult { + crate::helpers::unwrap_or_else(|| Ok(self.client.info().chain.best_hash), hash) + } + + /// Splits the `query_storage` block range into 'filtered' and 'unfiltered' subranges. + /// Blocks that contain changes within filtered subrange could be filtered using changes tries. + /// Blocks that contain changes within unfiltered subrange must be filtered manually. + fn split_query_storage_range( + &self, + from: Block::Hash, + to: Option + ) -> Result> { + let to = self.block_or_best(to).map_err(client_err)?; + let from_hdr = self.client.header(&BlockId::hash(from)).map_err(client_err)?; + let to_hdr = self.client.header(&BlockId::hash(to)).map_err(client_err)?; + match (from_hdr, to_hdr) { + (Some(ref from), Some(ref to)) if from.number() <= to.number() => { + // check if we can get from `to` to `from` by going through parent_hashes. + let from_number = *from.number(); + let blocks = { + let mut blocks = vec![to.hash()]; + let mut last = to.clone(); + while *last.number() > from_number { + let hdr = self.client + .header(&BlockId::hash(*last.parent_hash())) + .map_err(client_err)?; + if let Some(hdr) = hdr { + blocks.push(hdr.hash()); + last = hdr; + } else { + return Err(invalid_block_range( + Some(from), + Some(to), + format!("Parent of {} ({}) not found", last.number(), last.hash()), + )) + } + } + if last.hash() != from.hash() { + return Err(invalid_block_range( + Some(from), + Some(to), + format!("Expected to reach `from`, got {} ({})", last.number(), last.hash()), + )) + } + blocks.reverse(); + blocks + }; + // check if we can filter blocks-with-changes from some (sub)range using changes tries + let changes_trie_range = self.client + .max_key_changes_range(from_number, BlockId::Hash(to.hash())) + .map_err(client_err)?; + let filtered_range_begin = changes_trie_range + .map(|(begin, _)| (begin - from_number).saturated_into::()); + let (unfiltered_range, filtered_range) = split_range(blocks.len(), filtered_range_begin); + Ok(QueryStorageRange { + hashes: blocks, + first_number: from_number, + unfiltered_range, + filtered_range, + }) + }, + (from, to) => Err( + invalid_block_range(from.as_ref(), to.as_ref(), "Invalid range or unknown block".into()) + ), + } + } + + /// Iterates through range.unfiltered_range and check each block for changes of keys' values. + fn query_storage_unfiltered( + &self, + range: &QueryStorageRange, + keys: &[StorageKey], + last_values: &mut HashMap>, + changes: &mut Vec>, + ) -> Result<()> { + for block in range.unfiltered_range.start..range.unfiltered_range.end { + let block_hash = range.hashes[block].clone(); + let mut block_changes = StorageChangeSet { block: block_hash.clone(), changes: Vec::new() }; + let id = BlockId::hash(block_hash); + for key in keys { + let (has_changed, data) = { + let curr_data = self.client.storage(&id, key).map_err(client_err)?; + match last_values.get(key) { + Some(prev_data) => (curr_data != *prev_data, curr_data), + None => (true, curr_data), + } + }; + if has_changed { + block_changes.changes.push((key.clone(), data.clone())); + } + last_values.insert(key.clone(), data); + } + if !block_changes.changes.is_empty() { + changes.push(block_changes); + } + } + Ok(()) + } + + /// Iterates through all blocks that are changing keys within range.filtered_range and collects these changes. + fn query_storage_filtered( + &self, + range: &QueryStorageRange, + keys: &[StorageKey], + last_values: &HashMap>, + changes: &mut Vec>, + ) -> Result<()> { + let (begin, end) = match range.filtered_range { + Some(ref filtered_range) => ( + range.first_number + filtered_range.start.saturated_into(), + BlockId::Hash(range.hashes[filtered_range.end - 1].clone()) + ), + None => return Ok(()), + }; + let mut changes_map: BTreeMap, StorageChangeSet> = BTreeMap::new(); + for key in keys { + let mut last_block = None; + let mut last_value = last_values.get(key).cloned().unwrap_or_default(); + let key_changes = self.client.key_changes(begin, end, key).map_err(client_err)?; + for (block, _) in key_changes.into_iter().rev() { + if last_block == Some(block) { + continue; + } + + let block_hash = range.hashes[(block - range.first_number).saturated_into::()].clone(); + let id = BlockId::Hash(block_hash); + let value_at_block = self.client.storage(&id, key).map_err(client_err)?; + if last_value == value_at_block { + continue; + } + + changes_map.entry(block) + .or_insert_with(|| StorageChangeSet { block: block_hash, changes: Vec::new() }) + .changes.push((key.clone(), value_at_block.clone())); + last_block = Some(block); + last_value = value_at_block; + } + } + if let Some(additional_capacity) = changes_map.len().checked_sub(changes.len()) { + changes.reserve(additional_capacity); + } + changes.extend(changes_map.into_iter().map(|(_, cs)| cs)); + Ok(()) + } +} + +impl StateBackend for FullState + where + Block: BlockT + 'static, + B: Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + 'static + Clone, + RA: Send + Sync + 'static, + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: Metadata, +{ + fn client(&self) -> &Arc> { + &self.client + } + + fn subscriptions(&self) -> &Subscriptions { + &self.subscriptions + } + + fn call( + &self, + block: Option, + method: String, + call_data: Bytes, + ) -> FutureResult { + Box::new(result( + self.block_or_best(block) + .and_then(|block| self.client.executor() + .call( + &BlockId::Hash(block), + &method, + &*call_data, + ExecutionStrategy::NativeElseWasm, + NeverOffchainExt::new(), + ) + .map(Into::into)) + .map_err(client_err))) + } + + fn storage_keys( + &self, + block: Option, + prefix: StorageKey, + ) -> FutureResult> { + Box::new(result( + self.block_or_best(block) + .and_then(|block| self.client.storage_keys(&BlockId::Hash(block), &prefix)) + .map_err(client_err))) + } + + fn storage( + &self, + block: Option, + key: StorageKey, + ) -> FutureResult> { + Box::new(result( + self.block_or_best(block) + .and_then(|block| self.client.storage(&BlockId::Hash(block), &key)) + .map_err(client_err))) + } + + fn storage_hash( + &self, + block: Option, + key: StorageKey, + ) -> FutureResult> { + Box::new(result( + self.block_or_best(block) + .and_then(|block| self.client.storage_hash(&BlockId::Hash(block), &key)) + .map_err(client_err))) + } + + fn child_storage_keys( + &self, + block: Option, + child_storage_key: StorageKey, + prefix: StorageKey, + ) -> FutureResult> { + Box::new(result( + self.block_or_best(block) + .and_then(|block| self.client.child_storage_keys(&BlockId::Hash(block), &child_storage_key, &prefix)) + .map_err(client_err))) + } + + fn child_storage( + &self, + block: Option, + child_storage_key: StorageKey, + key: StorageKey, + ) -> FutureResult> { + Box::new(result( + self.block_or_best(block) + .and_then(|block| self.client.child_storage(&BlockId::Hash(block), &child_storage_key, &key)) + .map_err(client_err))) + } + + fn child_storage_hash( + &self, + block: Option, + child_storage_key: StorageKey, + key: StorageKey, + ) -> FutureResult> { + Box::new(result( + self.block_or_best(block) + .and_then(|block| self.client.child_storage_hash(&BlockId::Hash(block), &child_storage_key, &key)) + .map_err(client_err))) + } + + fn metadata(&self, block: Option) -> FutureResult { + Box::new(result( + self.block_or_best(block) + .and_then(|block| self.client.runtime_api().metadata(&BlockId::Hash(block)).map(Into::into)) + .map_err(client_err))) + } + + fn runtime_version(&self, block: Option) -> FutureResult { + Box::new(result( + self.block_or_best(block) + .and_then(|block| self.client.runtime_version_at(&BlockId::Hash(block))) + .map_err(client_err))) + } + + fn query_storage( + &self, + from: Block::Hash, + to: Option, + keys: Vec, + ) -> FutureResult>> { + let call_fn = move || { + let range = self.split_query_storage_range(from, to)?; + let mut changes = Vec::new(); + let mut last_values = HashMap::new(); + self.query_storage_unfiltered(&range, &keys, &mut last_values, &mut changes)?; + self.query_storage_filtered(&range, &keys, &last_values, &mut changes)?; + Ok(changes) + }; + Box::new(result(call_fn())) + } +} + +/// Splits passed range into two subranges where: +/// - first range has at least one element in it; +/// - second range (optionally) starts at given `middle` element. +pub(crate) fn split_range(size: usize, middle: Option) -> (Range, Option>) { + // check if we can filter blocks-with-changes from some (sub)range using changes tries + let range2_begin = match middle { + // some of required changes tries are pruned => use available tries + Some(middle) if middle != 0 => Some(middle), + // all required changes tries are available, but we still want values at first block + // => do 'unfiltered' read for the first block and 'filtered' for the rest + Some(_) if size > 1 => Some(1), + // range contains single element => do not use changes tries + Some(_) => None, + // changes tries are not available => do 'unfiltered' read for the whole range + None => None, + }; + let range1 = 0..range2_begin.unwrap_or(size); + let range2 = range2_begin.map(|begin| begin..size); + (range1, range2) +} + +fn invalid_block_range(from: Option<&H>, to: Option<&H>, reason: String) -> Error { + let to_string = |x: Option<&H>| match x { + None => "unknown hash".into(), + Some(h) => format!("{} ({})", h.number(), h.hash()), + }; + + Error::InvalidBlockRange { + from: to_string(from), + to: to_string(to), + details: reason, + } +} diff --git a/core/rpc/src/state/state_light.rs b/core/rpc/src/state/state_light.rs new file mode 100644 index 0000000000..eb14b3fe7b --- /dev/null +++ b/core/rpc/src/state/state_light.rs @@ -0,0 +1,283 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! State API backend for light nodes. + +use std::sync::Arc; +use codec::Decode; +use futures03::{future::{ready, Either}, FutureExt, TryFutureExt}; +use hash_db::Hasher; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use rpc::{ + Result as RpcResult, + futures::future::{result, Future}, +}; + +use api::Subscriptions; +use client::{ + Client, CallExecutor, backend::Backend, + error::Error as ClientError, + light::{ + blockchain::{future_header, RemoteBlockchain}, + fetcher::{Fetcher, RemoteCallRequest, RemoteReadRequest, RemoteReadChildRequest}, + }, +}; +use primitives::{ + H256, Blake2Hasher, Bytes, OpaqueMetadata, + storage::{StorageKey, StorageData, StorageChangeSet}, +}; +use runtime_version::RuntimeVersion; +use sr_primitives::{ + generic::BlockId, + traits::{Block as BlockT, Header as HeaderT}, +}; + +use super::{StateBackend, error::{FutureResult, Error}, client_err}; + +pub struct LightState, B, E, RA> { + client: Arc>, + subscriptions: Subscriptions, + remote_blockchain: Arc>, + fetcher: Arc, +} + +impl + 'static, B, E, RA> LightState + where + Block: BlockT, + B: Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + 'static + Clone, + RA: Send + Sync + 'static, +{ + /// + pub fn new( + client: Arc>, + subscriptions: Subscriptions, + remote_blockchain: Arc>, + fetcher: Arc, + ) -> Self { + Self { client, subscriptions, remote_blockchain, fetcher, } + } + + /// Returns given block hash or best block hash if None is passed. + fn block_or_best(&self, hash: Option) -> Block::Hash { + hash.unwrap_or_else(|| self.client.info().chain.best_hash) + } + + /// Resolve header by hash. + fn resolve_header( + &self, + block: Option, + ) -> impl std::future::Future> { + let block = self.block_or_best(block); + let maybe_header = future_header( + &*self.remote_blockchain, + &*self.fetcher, + BlockId::Hash(block), + ); + + maybe_header.then(move |result| + ready(result.and_then(|maybe_header| + maybe_header.ok_or(ClientError::UnknownBlock(format!("{}", block))) + ).map_err(client_err)), + ) + } +} + +impl StateBackend for LightState + where + Block: BlockT, + B: Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + 'static + Clone, + RA: Send + Sync + 'static, + F: Fetcher + 'static +{ + fn client(&self) -> &Arc> { + &self.client + } + + fn subscriptions(&self) -> &Subscriptions { + &self.subscriptions + } + + fn call( + &self, + block: Option, + method: String, + call_data: Bytes, + ) -> FutureResult { + let fetcher = self.fetcher.clone(); + let call_result = self.resolve_header(block) + .then(move |result| match result { + Ok(header) => Either::Left(fetcher.remote_call(RemoteCallRequest { + block: header.hash(), + header, + method, + call_data: call_data.0, + retry_count: Default::default(), + }).then(|result| ready(result.map(Bytes).map_err(client_err)))), + Err(error) => Either::Right(ready(Err(error))), + }); + + Box::new(call_result.boxed().compat()) + } + + fn storage_keys( + &self, + _block: Option, + _prefix: StorageKey, + ) -> FutureResult> { + Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient)))) + } + + fn storage( + &self, + block: Option, + key: StorageKey, + ) -> FutureResult> { + let fetcher = self.fetcher.clone(); + let storage = self.resolve_header(block) + .then(move |result| match result { + Ok(header) => Either::Left(fetcher.remote_read(RemoteReadRequest { + block: header.hash(), + header, + key: key.0, + retry_count: Default::default(), + }).then(|result| ready(result.map(|data| data.map(StorageData)).map_err(client_err)))), + Err(error) => Either::Right(ready(Err(error))), + }); + + Box::new(storage.boxed().compat()) + } + + fn storage_hash( + &self, + block: Option, + key: StorageKey, + ) -> FutureResult> { + Box::new(self + .storage(block, key) + .and_then(|maybe_storage| + result(Ok(maybe_storage.map(|storage| Blake2Hasher::hash(&storage.0)))) + ) + ) + } + + fn child_storage_keys( + &self, + _block: Option, + _child_storage_key: StorageKey, + _prefix: StorageKey, + ) -> FutureResult> { + Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient)))) + } + + fn child_storage( + &self, + block: Option, + child_storage_key: StorageKey, + key: StorageKey, + ) -> FutureResult> { + let fetcher = self.fetcher.clone(); + let child_storage = self.resolve_header(block) + .then(move |result| match result { + Ok(header) => Either::Left(fetcher.remote_read_child(RemoteReadChildRequest { + block: header.hash(), + header, + storage_key: child_storage_key.0, + key: key.0, + retry_count: Default::default(), + }).then(|result| ready(result.map(|data| data.map(StorageData)).map_err(client_err)))), + Err(error) => Either::Right(ready(Err(error))), + }); + + Box::new(child_storage.boxed().compat()) + } + + fn child_storage_hash( + &self, + block: Option, + child_storage_key: StorageKey, + key: StorageKey, + ) -> FutureResult> { + Box::new(self + .child_storage(block, child_storage_key, key) + .and_then(|maybe_storage| + result(Ok(maybe_storage.map(|storage| Blake2Hasher::hash(&storage.0)))) + ) + ) + } + + fn metadata(&self, block: Option) -> FutureResult { + let metadata = self.call(block, "Metadata_metadata".into(), Bytes(Vec::new())) + .and_then(|metadata| OpaqueMetadata::decode(&mut &metadata.0[..]) + .map(Into::into) + .map_err(|decode_err| client_err(ClientError::CallResultDecode( + "Unable to decode metadata", + decode_err, + )))); + + Box::new(metadata) + } + + fn runtime_version(&self, block: Option) -> FutureResult { + let version = self.call(block, "Core_version".into(), Bytes(Vec::new())) + .and_then(|version| Decode::decode(&mut &version.0[..]) + .map_err(|_| client_err(ClientError::VersionInvalid)) + ); + + Box::new(version) + } + + fn query_storage( + &self, + _from: Block::Hash, + _to: Option, + _keys: Vec, + ) -> FutureResult>> { + Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient)))) + } + + fn subscribe_storage( + &self, + _meta: crate::metadata::Metadata, + _subscriber: Subscriber>, + _keys: Option> + ) { + } + + fn unsubscribe_storage( + &self, + _meta: Option, + _id: SubscriptionId, + ) -> RpcResult { + Ok(false) + } + + fn subscribe_runtime_version( + &self, + _meta: crate::metadata::Metadata, + _subscriber: Subscriber, + ) { + } + + fn unsubscribe_runtime_version( + &self, + _meta: Option, + _id: SubscriptionId, + ) -> RpcResult { + Ok(false) + } +} diff --git a/core/rpc/src/state/tests.rs b/core/rpc/src/state/tests.rs index 0b581d166f..f2a0c37b78 100644 --- a/core/rpc/src/state/tests.rs +++ b/core/rpc/src/state/tests.rs @@ -15,9 +15,12 @@ // along with Substrate. If not, see . use super::*; +use super::state_full::split_range; use self::error::Error; +use std::sync::Arc; use assert_matches::assert_matches; +use futures::stream::Stream; use primitives::storage::well_known_keys; use sr_io::blake2_256; use test_client::{ @@ -39,21 +42,22 @@ fn should_return_storage() { .add_extra_child_storage(STORAGE_KEY.to_vec(), KEY.to_vec(), CHILD_VALUE.to_vec()) .build(); let genesis_hash = client.genesis_hash(); - let client = State::new(Arc::new(client), Subscriptions::new(Arc::new(core.executor()))); + let client = new_full(Arc::new(client), Subscriptions::new(Arc::new(core.executor()))); let key = StorageKey(KEY.to_vec()); let storage_key = StorageKey(STORAGE_KEY.to_vec()); assert_eq!( - client.storage(key.clone(), Some(genesis_hash).into()) + client.storage(key.clone(), Some(genesis_hash).into()).wait() .map(|x| x.map(|x| x.0.len())).unwrap().unwrap() as usize, VALUE.len(), ); assert_matches!( - client.storage_hash(key.clone(), Some(genesis_hash).into()).map(|x| x.is_some()), + client.storage_hash(key.clone(), Some(genesis_hash).into()).wait() + .map(|x| x.is_some()), Ok(true) ); assert_eq!( - client.storage_size(key.clone(), None).unwrap().unwrap() as usize, + client.storage_size(key.clone(), None).wait().unwrap().unwrap() as usize, VALUE.len(), ); assert_eq!( @@ -71,22 +75,22 @@ fn should_return_child_storage() { .add_child_storage("test", "key", vec![42_u8]) .build()); let genesis_hash = client.genesis_hash(); - let client = State::new(client, Subscriptions::new(Arc::new(core.executor()))); + let client = new_full(client, Subscriptions::new(Arc::new(core.executor()))); let child_key = StorageKey(well_known_keys::CHILD_STORAGE_KEY_PREFIX.iter().chain(b"test").cloned().collect()); let key = StorageKey(b"key".to_vec()); assert_matches!( - client.child_storage(child_key.clone(), key.clone(), Some(genesis_hash).into()), + client.child_storage(child_key.clone(), key.clone(), Some(genesis_hash).into()).wait(), Ok(Some(StorageData(ref d))) if d[0] == 42 && d.len() == 1 ); assert_matches!( client.child_storage_hash(child_key.clone(), key.clone(), Some(genesis_hash).into()) - .map(|x| x.is_some()), + .wait().map(|x| x.is_some()), Ok(true) ); assert_matches!( - client.child_storage_size(child_key.clone(), key.clone(), None), + client.child_storage_size(child_key.clone(), key.clone(), None).wait(), Ok(Some(1)) ); } @@ -96,10 +100,10 @@ fn should_call_contract() { let core = tokio::runtime::Runtime::new().unwrap(); let client = Arc::new(test_client::new()); let genesis_hash = client.genesis_hash(); - let client = State::new(client, Subscriptions::new(Arc::new(core.executor()))); + let client = new_full(client, Subscriptions::new(Arc::new(core.executor()))); assert_matches!( - client.call("balanceOf".into(), Bytes(vec![1,2,3]), Some(genesis_hash).into()), + client.call("balanceOf".into(), Bytes(vec![1,2,3]), Some(genesis_hash).into()).wait(), Err(Error::Client(_)) ) } @@ -111,21 +115,22 @@ fn should_notify_about_storage_changes() { let (subscriber, id, transport) = Subscriber::new_test("test"); { - let api = State::new(Arc::new(test_client::new()), Subscriptions::new(Arc::new(remote))); + let client = Arc::new(test_client::new()); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); api.subscribe_storage(Default::default(), subscriber, None.into()); // assert id assigned assert_eq!(core.block_on(id), Ok(Ok(SubscriptionId::Number(1)))); - let mut builder = api.client.new_block(Default::default()).unwrap(); + let mut builder = client.new_block(Default::default()).unwrap(); builder.push_transfer(runtime::Transfer { from: AccountKeyring::Alice.into(), to: AccountKeyring::Ferdie.into(), amount: 42, nonce: 0, }).unwrap(); - api.client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); + client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); } // assert notification sent to transport @@ -142,7 +147,8 @@ fn should_send_initial_storage_changes_and_notifications() { let (subscriber, id, transport) = Subscriber::new_test("test"); { - let api = State::new(Arc::new(test_client::new()), Subscriptions::new(Arc::new(remote))); + let client = Arc::new(test_client::new()); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); let alice_balance_key = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Alice.into())); @@ -153,14 +159,14 @@ fn should_send_initial_storage_changes_and_notifications() { // assert id assigned assert_eq!(core.block_on(id), Ok(Ok(SubscriptionId::Number(1)))); - let mut builder = api.client.new_block(Default::default()).unwrap(); + let mut builder = client.new_block(Default::default()).unwrap(); builder.push_transfer(runtime::Transfer { from: AccountKeyring::Alice.into(), to: AccountKeyring::Ferdie.into(), amount: 42, nonce: 0, }).unwrap(); - api.client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); + client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); } // assert initial values sent to transport @@ -177,7 +183,7 @@ fn should_send_initial_storage_changes_and_notifications() { fn should_query_storage() { fn run_tests(client: Arc) { let core = tokio::runtime::Runtime::new().unwrap(); - let api = State::new(client.clone(), Subscriptions::new(Arc::new(core.executor()))); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(core.executor()))); let add_block = |nonce| { let mut builder = client.new_block(Default::default()).unwrap(); @@ -229,7 +235,7 @@ fn should_query_storage() { Some(block1_hash).into(), ); - assert_eq!(result.unwrap(), expected); + assert_eq!(result.wait().unwrap(), expected); // Query all changes let result = api.query_storage( @@ -246,7 +252,7 @@ fn should_query_storage() { (StorageKey(vec![5]), Some(StorageData(vec![1]))), ], }); - assert_eq!(result.unwrap(), expected); + assert_eq!(result.wait().unwrap(), expected); } run_tests(Arc::new(test_client::new())); @@ -268,7 +274,7 @@ fn should_return_runtime_version() { let core = tokio::runtime::Runtime::new().unwrap(); let client = Arc::new(test_client::new()); - let api = State::new(client.clone(), Subscriptions::new(Arc::new(core.executor()))); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(core.executor()))); let result = "{\"specName\":\"test\",\"implName\":\"parity-test\",\"authoringVersion\":1,\ \"specVersion\":1,\"implVersion\":1,\"apis\":[[\"0xdf6acb689907609b\",2],\ @@ -276,7 +282,7 @@ fn should_return_runtime_version() { [\"0xc6e9a76309f39b09\",1],[\"0xdd718d5cc53262d4\",1],[\"0xcbca25e39f142387\",1],\ [\"0xf78b278be53f454c\",1],[\"0xab3c0572291feb8b\",1]]}"; - let runtime_version = api.runtime_version(None.into()).unwrap(); + let runtime_version = api.runtime_version(None.into()).wait().unwrap(); let serialized = serde_json::to_string(&runtime_version).unwrap(); assert_eq!(serialized, result); @@ -291,7 +297,7 @@ fn should_notify_on_runtime_version_initially() { { let client = Arc::new(test_client::new()); - let api = State::new(client.clone(), Subscriptions::new(Arc::new(core.executor()))); + let api = new_full(client.clone(), Subscriptions::new(Arc::new(core.executor()))); api.subscribe_runtime_version(Default::default(), subscriber); diff --git a/core/service/src/builder.rs b/core/service/src/builder.rs index fbcfa0f09d..c675710e54 100644 --- a/core/service/src/builder.rs +++ b/core/service/src/builder.rs @@ -18,7 +18,10 @@ use crate::{NewService, NetworkStatus, NetworkState, error::{self, Error}, DEFAU use crate::{SpawnTaskHandle, start_rpc_servers, build_network_future, TransactionPoolAdapter}; use crate::TaskExecutor; use crate::config::Configuration; -use client::{BlockchainEvents, Client, runtime_api}; +use client::{ + BlockchainEvents, Client, runtime_api, + backend::RemoteBackend, light::blockchain::RemoteBlockchain, +}; use codec::{Decode, Encode, IoReader}; use consensus_common::import_queue::ImportQueue; use futures::{prelude::*, sync::mpsc}; @@ -58,7 +61,7 @@ use transaction_pool::txpool::{self, ChainApi, Pool as TransactionPool}; /// generics is done when you call `build`. /// pub struct ServiceBuilder + TNetP, TExPool, TRpc, TRpcB, Backend> { config: Configuration, client: Arc, @@ -72,10 +75,68 @@ pub struct ServiceBuilder, rpc_extensions: TRpc, + rpc_builder: TRpcB, marker: PhantomData<(TBl, TRtApi)>, } -impl ServiceBuilder<(), (), TCfg, TGen, (), (), (), (), (), (), (), (), (), ()> +/// Full client type. +type TFullClient = Client< + TFullBackend, + TFullCallExecutor, + TBl, + TRtApi, +>; + +/// Full client backend type. +type TFullBackend = client_db::Backend; + +/// Full client call executor type. +type TFullCallExecutor = client::LocalCallExecutor< + client_db::Backend, + NativeExecutor, +>; + +/// Light client type. +type TLightClient = Client< + TLightBackend, + TLightCallExecutor, + TBl, + TRtApi, +>; + +/// Light client backend type. +type TLightBackend = client::light::backend::Backend< + client_db::light::LightStorage, + network::OnDemand, + Blake2Hasher, +>; + +/// Light call executor type. +type TLightCallExecutor = client::light::call_executor::RemoteOrLocalCallExecutor< + TBl, + client::light::backend::Backend< + client_db::light::LightStorage, + network::OnDemand, + Blake2Hasher + >, + client::light::call_executor::RemoteCallExecutor< + client::light::blockchain::Blockchain< + client_db::light::LightStorage, + network::OnDemand + >, + network::OnDemand, + >, + client::LocalCallExecutor< + client::light::backend::Backend< + client_db::light::LightStorage, + network::OnDemand, + Blake2Hasher + >, + NativeExecutor + >, +>; + +impl ServiceBuilder<(), (), TCfg, TGen, (), (), (), (), (), (), (), (), (), (), ()> where TGen: Serialize + DeserializeOwned + BuildStorage { /// Start the service builder with a configuration. pub fn new_full, TRtApi, TExecDisp: NativeExecutionDispatch>( @@ -85,12 +146,7 @@ where TGen: Serialize + DeserializeOwned + BuildStorage { TRtApi, TCfg, TGen, - Client< - client_db::Backend, - client::LocalCallExecutor, NativeExecutor>, - TBl, - TRtApi - >, + TFullClient, Arc>, (), (), @@ -99,7 +155,8 @@ where TGen: Serialize + DeserializeOwned + BuildStorage { (), (), (), - client_db::Backend, + FullRpcBuilder, + TFullBackend, >, Error> { let keystore = Keystore::open(config.keystore_path.clone(), config.keystore_password.clone())?; @@ -124,6 +181,8 @@ where TGen: Serialize + DeserializeOwned + BuildStorage { let client = Arc::new(client); + let rpc_builder = FullRpcBuilder { client: client.clone() }; + Ok(ServiceBuilder { config, client, @@ -137,6 +196,7 @@ where TGen: Serialize + DeserializeOwned + BuildStorage { network_protocol: (), transaction_pool: Arc::new(()), rpc_extensions: Default::default(), + rpc_builder, marker: PhantomData, }) } @@ -149,34 +209,7 @@ where TGen: Serialize + DeserializeOwned + BuildStorage { TRtApi, TCfg, TGen, - Client< - client::light::backend::Backend, network::OnDemand, Blake2Hasher>, - client::light::call_executor::RemoteOrLocalCallExecutor< - TBl, - client::light::backend::Backend< - client_db::light::LightStorage, - network::OnDemand, - Blake2Hasher - >, - client::light::call_executor::RemoteCallExecutor< - client::light::blockchain::Blockchain< - client_db::light::LightStorage, - network::OnDemand - >, - network::OnDemand, - >, - client::LocalCallExecutor< - client::light::backend::Backend< - client_db::light::LightStorage, - network::OnDemand, - Blake2Hasher - >, - NativeExecutor - > - >, - TBl, - TRtApi - >, + TLightClient, Arc>, (), (), @@ -185,7 +218,8 @@ where TGen: Serialize + DeserializeOwned + BuildStorage { (), (), (), - client::light::backend::Backend, network::OnDemand, Blake2Hasher>, + LightRpcBuilder, + TLightBackend, >, Error> { let keystore = Keystore::open(config.keystore_path.clone(), config.keystore_password.clone())?; @@ -205,11 +239,22 @@ where TGen: Serialize + DeserializeOwned + BuildStorage { let fetch_checker = Arc::new(client::light::new_fetch_checker(light_blockchain.clone(), executor.clone())); let fetcher = Arc::new(network::OnDemand::new(fetch_checker)); let backend = client::light::new_light_backend(light_blockchain, fetcher.clone()); - let client = client::light::new_light(backend.clone(), fetcher.clone(), &config.chain_spec, executor)?; + let remote_blockchain = backend.remote_blockchain(); + let client = Arc::new(client::light::new_light( + backend.clone(), + fetcher.clone(), + &config.chain_spec, + executor, + )?); + let rpc_builder = LightRpcBuilder { + client: client.clone(), + remote_blockchain, + fetcher: fetcher.clone(), + }; Ok(ServiceBuilder { config, - client: Arc::new(client), + client, backend, keystore, fetcher: Some(fetcher), @@ -220,13 +265,15 @@ where TGen: Serialize + DeserializeOwned + BuildStorage { network_protocol: (), transaction_pool: Arc::new(()), rpc_extensions: Default::default(), + rpc_builder, marker: PhantomData, }) } } -impl - ServiceBuilder { +impl + ServiceBuilder { /// Returns a reference to the client that was stored in this builder. pub fn client(&self) -> &Arc { @@ -248,7 +295,7 @@ impl, &Arc) -> Result, Error> ) -> Result, Error> { + TNetP, TExPool, TRpc, TRpcB, Backend>, Error> { let select_chain = select_chain_builder(&self.config, &self.backend)?; Ok(ServiceBuilder { @@ -264,6 +311,7 @@ impl, &Arc) -> Result ) -> Result, Error> { + TNetP, TExPool, TRpc, TRpcB, Backend>, Error> { self.with_opt_select_chain(|cfg, b| builder(cfg, b).map(Option::Some)) } @@ -283,7 +331,7 @@ impl, Arc, Option, Arc) -> Result ) -> Result, Error> + TNetP, TExPool, TRpc, TRpcB, Backend>, Error> where TSc: Clone { let import_queue = builder( &self.config, @@ -305,6 +353,7 @@ impl) -> Result ) -> Result, Error> { + UNetP, TExPool, TRpc, TRpcB, Backend>, Error> { let network_protocol = network_protocol_builder(&self.config)?; Ok(ServiceBuilder { @@ -330,6 +379,7 @@ impl, Error> { let finality_proof_provider = builder(self.client.clone(), self.backend.clone())?; @@ -369,6 +420,7 @@ impl, Error> { self.with_opt_finality_proof_provider(|client, backend| build(client, backend).map(Option::Some)) @@ -402,7 +455,7 @@ impl, Arc, Arc, Option, Arc) -> Result<(UImpQu, Option), Error> ) -> Result, Error> + TNetP, TExPool, TRpc, TRpcB, Backend>, Error> where TSc: Clone { let (import_queue, fprb) = builder( &self.config, @@ -425,6 +478,7 @@ impl, Arc, Arc, Option, Arc) -> Result<(UImpQu, UFprb), Error> ) -> Result, Error> + TNetP, TExPool, TRpc, TRpcB, Backend>, Error> where TSc: Clone { self.with_import_queue_and_opt_fprb(|cfg, cl, b, sc, tx| builder(cfg, cl, b, sc, tx).map(|(q, f)| (q, Some(f)))) } @@ -445,7 +499,7 @@ impl) -> Result ) -> Result, Error> { + TNetP, UExPool, TRpc, TRpcB, Backend>, Error> { let transaction_pool = transaction_pool_builder(self.config.transaction_pool.clone(), self.client.clone())?; Ok(ServiceBuilder { @@ -461,6 +515,7 @@ impl, Arc) -> URpc ) -> Result, Error> { + TNetP, TExPool, URpc, TRpcB, Backend>, Error> { let rpc_extensions = rpc_ext_builder(self.client.clone(), self.transaction_pool.clone()); Ok(ServiceBuilder { @@ -486,11 +541,90 @@ impl { + /// Build chain RPC handler. + fn build_chain(&self, subscriptions: rpc::Subscriptions) -> rpc::chain::Chain; + /// Build state RPC handler. + fn build_state(&self, subscriptions: rpc::Subscriptions) -> rpc::state::State; +} + +/// RPC handlers builder for full nodes. +pub struct FullRpcBuilder { + client: Arc>, +} + +impl RpcBuilder, TFullCallExecutor, TRtApi> + for + FullRpcBuilder + where + TBl: BlockT, + TRtApi: 'static + Send + Sync, + TExecDisp: 'static + NativeExecutionDispatch, + TFullClient: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: runtime_api::Metadata, +{ + fn build_chain( + &self, + subscriptions: rpc::Subscriptions, + ) -> rpc::chain::Chain, TFullCallExecutor, TBl, TRtApi> { + rpc::chain::new_full(self.client.clone(), subscriptions) + } + + fn build_state( + &self, + subscriptions: rpc::Subscriptions, + ) -> rpc::state::State, TFullCallExecutor, TBl, TRtApi> { + rpc::state::new_full(self.client.clone(), subscriptions) + } +} + +/// RPC handlers builder for light nodes. +pub struct LightRpcBuilder, TRtApi, TExecDisp> { + client: Arc>, + remote_blockchain: Arc>, + fetcher: Arc>, +} + +impl RpcBuilder, TLightCallExecutor, TRtApi> + for + LightRpcBuilder + where + TBl: BlockT, + TRtApi: 'static + Send + Sync, + TExecDisp: 'static + NativeExecutionDispatch, +{ + fn build_chain( + &self, + subscriptions: rpc::Subscriptions, + ) -> rpc::chain::Chain, TLightCallExecutor, TBl, TRtApi> { + rpc::chain::new_light( + self.client.clone(), + subscriptions, + self.remote_blockchain.clone(), + self.fetcher.clone(), + ) + } + + fn build_state( + &self, + subscriptions: rpc::Subscriptions, + ) -> rpc::state::State, TLightCallExecutor, TBl, TRtApi> { + rpc::state::new_light( + self.client.clone(), + subscriptions, + self.remote_blockchain.clone(), + self.fetcher.clone(), + ) + } +} + /// Implemented on `ServiceBuilder`. Allows importing blocks once you have given all the required /// components to the builder. pub trait ServiceBuilderImport { @@ -532,9 +666,9 @@ pub trait ServiceBuilderRevert { ) -> Result<(), Error>; } -impl +impl ServiceBuilderImport for ServiceBuilder, - TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, Backend> + TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB, Backend> where TBl: BlockT::Out>, TBackend: 'static + client::backend::Backend + Send, @@ -554,9 +688,9 @@ where } } -impl +impl ServiceBuilderExport for ServiceBuilder, - TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TBackend> + TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB, TBackend> where TBl: BlockT::Out>, TBackend: 'static + client::backend::Backend + Send, @@ -577,9 +711,9 @@ where } } -impl +impl ServiceBuilderRevert for ServiceBuilder, - TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TBackend> + TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB, TBackend> where TBl: BlockT::Out>, TBackend: 'static + client::backend::Backend + Send, @@ -596,7 +730,7 @@ where } } -impl +impl ServiceBuilder< TBl, TRtApi, @@ -611,7 +745,8 @@ ServiceBuilder< TNetP, TransactionPool, TRpc, - TBackend + TRpcB, + TBackend, > where Client: ProvideRuntimeApi, as ProvideRuntimeApi>::Api: @@ -630,6 +765,7 @@ ServiceBuilder< TNetP: NetworkSpecialization, TExPoolApi: 'static + ChainApi::Hash>, TRpc: rpc::RpcExtension + Clone, + TRpcB: RpcBuilder, { /// Builds the service. pub fn build(self) -> Result( +pub(crate) fn start_rpc( + rpc_builder: &RpcB, client: Arc>, system_send_back: futures03::channel::mpsc::UnboundedSender>, rpc_system_info: SystemInfo, @@ -718,11 +857,13 @@ where runtime_api::Metadata + session::SessionKeys, Api: Send + Sync + 'static, Executor: client::CallExecutor + Send + Sync + Clone + 'static, - PoolApi: txpool::ChainApi + 'static { + PoolApi: txpool::ChainApi + 'static, + RpcB: RpcBuilder, +{ use rpc::{chain, state, author, system}; let subscriptions = rpc::Subscriptions::new(task_executor.clone()); - let chain = chain::Chain::new(client.clone(), subscriptions.clone()); - let state = state::State::new(client.clone(), subscriptions.clone()); + let chain = rpc_builder.build_chain(subscriptions.clone()); + let state = rpc_builder.build_state(subscriptions.clone()); let author = rpc::author::Author::new( client, transaction_pool, diff --git a/core/service/src/lib.rs b/core/service/src/lib.rs index ad359767b2..2056c8a2f2 100644 --- a/core/service/src/lib.rs +++ b/core/service/src/lib.rs @@ -345,6 +345,7 @@ macro_rules! new_impl { }; $start_rpc( client.clone(), + //light_components.clone(), system_rpc_tx.clone(), system_info.clone(), Arc::new(SpawnTaskHandle { sender: to_spawn_tx.clone() }), -- GitLab From fc3adc87dc806237eb7371c1d21055eea1702be0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sun, 1 Sep 2019 15:17:17 +0200 Subject: [PATCH 047/275] Fix tests compilation on master and remove warnings (#3525) --- core/rpc/src/author/mod.rs | 6 +----- core/rpc/src/author/tests.rs | 4 ++-- core/rpc/src/state/tests.rs | 8 +++++--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/core/rpc/src/author/mod.rs b/core/rpc/src/author/mod.rs index 78a8ff804f..50b5e30d57 100644 --- a/core/rpc/src/author/mod.rs +++ b/core/rpc/src/author/mod.rs @@ -28,10 +28,7 @@ use api::Subscriptions; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use log::warn; use codec::{Encode, Decode}; -use primitives::{ - Bytes, Blake2Hasher, H256, ed25519, sr25519, crypto::{Pair, Public, key_types}, - traits::BareCryptoStorePtr, -}; +use primitives::{Bytes, Blake2Hasher, H256, traits::BareCryptoStorePtr}; use sr_primitives::{generic, traits::{self, ProvideRuntimeApi}}; use transaction_pool::{ txpool::{ @@ -98,7 +95,6 @@ impl AuthorApi, BlockHash

> for Author whe ) -> Result<()> { let key_type = key_type.as_str().try_into().map_err(|_| Error::BadKeyType)?; let mut keystore = self.keystore.write(); - let maybe_password = keystore.password(); keystore.insert_unknown(key_type, &suri, &public[..]) .map_err(|_| Error::KeyStoreUnavailable)?; Ok(()) diff --git a/core/rpc/src/author/tests.rs b/core/rpc/src/author/tests.rs index 8e6243f40e..861b65bfe7 100644 --- a/core/rpc/src/author/tests.rs +++ b/core/rpc/src/author/tests.rs @@ -26,7 +26,7 @@ use transaction_pool::{ use futures::Stream; use primitives::{ H256, blake2_256, hexdisplay::HexDisplay, traits::BareCryptoStore, testing::KeyStore, - ed25519, crypto::key_types, + ed25519, crypto::{key_types, Pair}, }; use test_client::{ self, AccountKeyring, runtime::{Extrinsic, Transfer, SessionKeys}, DefaultTestClientBuilderExt, @@ -238,4 +238,4 @@ fn should_rotate_keys() { assert_eq!(session_keys.ed25519, ed25519_key_pair.public().into()); assert_eq!(session_keys.sr25519, sr25519_key_pair.public().into()); -} \ No newline at end of file +} diff --git a/core/rpc/src/state/tests.rs b/core/rpc/src/state/tests.rs index f2a0c37b78..ba1aac4cc3 100644 --- a/core/rpc/src/state/tests.rs +++ b/core/rpc/src/state/tests.rs @@ -36,7 +36,7 @@ fn should_return_storage() { const STORAGE_KEY: &[u8] = b":child_storage:default:child"; const CHILD_VALUE: &[u8] = b"hello world !"; - let core = tokio::runtime::Runtime::new().unwrap(); + let mut core = tokio::runtime::Runtime::new().unwrap(); let client = TestClientBuilder::new() .add_extra_storage(KEY.to_vec(), VALUE.to_vec()) .add_extra_child_storage(STORAGE_KEY.to_vec(), KEY.to_vec(), CHILD_VALUE.to_vec()) @@ -61,8 +61,10 @@ fn should_return_storage() { VALUE.len(), ); assert_eq!( - client.child_storage(storage_key, key, Some(genesis_hash).into()) - .map(|x| x.map(|x| x.0.len())).unwrap().unwrap() as usize, + core.block_on( + client.child_storage(storage_key, key, Some(genesis_hash).into()) + .map(|x| x.map(|x| x.0.len())) + ).unwrap().unwrap() as usize, CHILD_VALUE.len(), ); -- GitLab From 7276eeab7da8b78f007a99129aad6e89e9d588c7 Mon Sep 17 00:00:00 2001 From: cheme Date: Mon, 2 Sep 2019 11:10:42 +0200 Subject: [PATCH 048/275] Implement change trie for child trie. (#3122) * Initial implementation, some redundancy is awkward and there is some useless computation (but there is a pending pr for that). Next are tests. * Minimal tests and fix extend child. * implement iterator for change child trie. * prune child trie. * Fix pruning test. * bump spec version. * Avoid empty child trie (could also be checked before) * tabs. * Fix child digest overriding each others. * Restore doc deleted on merge. * Check correct child value on extrinsics build. * Revert runtime version update. --- core/client/db/src/lib.rs | 4 + core/client/db/src/storage_cache.rs | 4 + core/client/src/client.rs | 17 +- core/client/src/light/backend.rs | 13 + core/client/src/light/fetcher.rs | 14 +- core/network/src/chain.rs | 6 +- core/network/src/protocol.rs | 20 +- core/network/src/protocol/light_dispatch.rs | 7 +- core/network/src/protocol/message.rs | 2 + core/rpc/src/state/state_full.rs | 2 +- core/state-machine/src/backend.rs | 14 +- core/state-machine/src/changes_trie/build.rs | 309 +++++++++++++++--- .../src/changes_trie/changes_iterator.rs | 100 +++++- core/state-machine/src/changes_trie/input.rs | 39 +++ core/state-machine/src/changes_trie/mod.rs | 29 +- core/state-machine/src/changes_trie/prune.rs | 75 ++++- .../state-machine/src/changes_trie/storage.rs | 28 +- core/state-machine/src/ext.rs | 8 +- core/state-machine/src/overlayed_changes.rs | 77 +++-- core/state-machine/src/proving_backend.rs | 4 + core/state-machine/src/testing.rs | 12 +- core/state-machine/src/trie_backend.rs | 4 + .../state-machine/src/trie_backend_essence.rs | 24 +- 23 files changed, 672 insertions(+), 140 deletions(-) diff --git a/core/client/db/src/lib.rs b/core/client/db/src/lib.rs index d2a9d54e82..05a1dfc97e 100644 --- a/core/client/db/src/lib.rs +++ b/core/client/db/src/lib.rs @@ -137,6 +137,10 @@ impl StateBackend for RefTrackingState { self.state.for_keys_with_prefix(prefix, f) } + fn for_key_values_with_prefix(&self, prefix: &[u8], f: F) { + self.state.for_key_values_with_prefix(prefix, f) + } + fn for_keys_in_child_storage(&self, storage_key: &[u8], f: F) { self.state.for_keys_in_child_storage(storage_key, f) } diff --git a/core/client/db/src/storage_cache.rs b/core/client/db/src/storage_cache.rs index 8b3e81212e..09c0f71fdd 100644 --- a/core/client/db/src/storage_cache.rs +++ b/core/client/db/src/storage_cache.rs @@ -536,6 +536,10 @@ impl, B: BlockT> StateBackend for CachingState< self.state.for_keys_with_prefix(prefix, f) } + fn for_key_values_with_prefix(&self, prefix: &[u8], f: F) { + self.state.for_key_values_with_prefix(prefix, f) + } + fn for_keys_in_child_storage(&self, storage_key: &[u8], f: F) { self.state.for_keys_in_child_storage(storage_key, f) } diff --git a/core/client/src/client.rs b/core/client/src/client.rs index be11c5d4f2..3363424854 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -535,6 +535,7 @@ impl Client where &self, first: NumberFor, last: BlockId, + storage_key: Option<&StorageKey>, key: &StorageKey ) -> error::Result, u32)>> { let (config, storage) = self.require_changes_trie()?; @@ -557,6 +558,7 @@ impl Client where number: last_number, }, self.backend.blockchain().info().best_number, + storage_key.as_ref().map(|sk| sk.0.as_slice()), &key.0) .and_then(|r| r.map(|r| r.map(|(block, tx)| (block, tx))).collect::>()) .map_err(|err| error::Error::ChangesTrieAccessFailed(err)) @@ -574,13 +576,15 @@ impl Client where last: Block::Hash, min: Block::Hash, max: Block::Hash, - key: &StorageKey + storage_key: Option<&StorageKey>, + key: &StorageKey, ) -> error::Result> { self.key_changes_proof_with_cht_size( first, last, min, max, + storage_key, key, cht::size(), ) @@ -593,6 +597,7 @@ impl Client where last: Block::Hash, min: Block::Hash, max: Block::Hash, + storage_key: Option<&StorageKey>, key: &StorageKey, cht_size: NumberFor, ) -> error::Result> { @@ -670,7 +675,8 @@ impl Client where number: last_number, }, max_number, - &key.0 + storage_key.as_ref().map(|sk| sk.0.as_slice()), + &key.0, ) .map_err(|err| error::Error::from(error::Error::ChangesTrieAccessFailed(err)))?; @@ -2580,7 +2586,12 @@ pub(crate) mod tests { for (index, (begin, end, key, expected_result)) in test_cases.into_iter().enumerate() { let end = client.block_hash(end).unwrap().unwrap(); - let actual_result = client.key_changes(begin, BlockId::Hash(end), &StorageKey(key)).unwrap(); + let actual_result = client.key_changes( + begin, + BlockId::Hash(end), + None, + &StorageKey(key), + ).unwrap(); match actual_result == expected_result { true => (), false => panic!(format!("Failed test {}: actual = {:?}, expected = {:?}", diff --git a/core/client/src/light/backend.rs b/core/client/src/light/backend.rs index b3dc6c2257..7de922f145 100644 --- a/core/client/src/light/backend.rs +++ b/core/client/src/light/backend.rs @@ -381,6 +381,10 @@ where // whole state is not available on light node } + fn for_key_values_with_prefix(&self, _prefix: &[u8], _action: A) { + // whole state is not available on light node + } + fn for_keys_in_child_storage(&self, _storage_key: &[u8], _action: A) { // whole state is not available on light node } @@ -461,6 +465,15 @@ where } } + fn for_key_values_with_prefix(&self, prefix: &[u8], action: A) { + match *self { + OnDemandOrGenesisState::OnDemand(ref state) => + StateBackend::::for_key_values_with_prefix(state, prefix, action), + OnDemandOrGenesisState::Genesis(ref state) => state.for_key_values_with_prefix(prefix, action), + } + } + + fn for_keys_in_child_storage(&self, storage_key: &[u8], action: A) { match *self { OnDemandOrGenesisState::OnDemand(ref state) => diff --git a/core/client/src/light/fetcher.rs b/core/client/src/light/fetcher.rs index c96d94424a..205a3de476 100644 --- a/core/client/src/light/fetcher.rs +++ b/core/client/src/light/fetcher.rs @@ -110,6 +110,8 @@ pub struct RemoteChangesRequest { /// Known changes trie roots for the range of blocks [tries_roots.0..max_block]. /// Proofs for roots of ascendants of tries_roots.0 are provided by the remote node. pub tries_roots: (Header::Number, Header::Hash, Vec), + /// Optional Child Storage key to read. + pub storage_key: Option>, /// Storage key to read. pub key: Vec, /// Number of times to retry request. None means that default RETRY_COUNT is used. @@ -307,6 +309,7 @@ impl, F> LightDataChecker { @@ -854,6 +859,7 @@ pub mod tests { last_block: (end, end_hash), max_block: (max, max_hash), tries_roots: (begin, begin_hash, local_roots_range.clone()), + storage_key: None, key: key.0, retry_count: None, }; @@ -907,7 +913,7 @@ pub mod tests { let b3 = remote_client.block_hash_from_id(&BlockId::Number(3)).unwrap().unwrap(); let b4 = remote_client.block_hash_from_id(&BlockId::Number(4)).unwrap().unwrap(); let remote_proof = remote_client.key_changes_proof_with_cht_size( - b1, b4, b3, b4, &dave, 4 + b1, b4, b3, b4, None, &dave, 4 ).unwrap(); // fails when changes trie CHT is missing from the local db diff --git a/core/network/src/chain.rs b/core/network/src/chain.rs index 99068698be..a4767caf13 100644 --- a/core/network/src/chain.rs +++ b/core/network/src/chain.rs @@ -64,6 +64,7 @@ pub trait Client: Send + Sync { last: Block::Hash, min: Block::Hash, max: Block::Hash, + storage_key: Option<&StorageKey>, key: &StorageKey ) -> Result, Error>; @@ -136,9 +137,10 @@ impl Client for SubstrateClient where last: Block::Hash, min: Block::Hash, max: Block::Hash, - key: &StorageKey + storage_key: Option<&StorageKey>, + key: &StorageKey, ) -> Result, Error> { - (self as &SubstrateClient).key_changes_proof(first, last, min, max, key) + (self as &SubstrateClient).key_changes_proof(first, last, min, max, storage_key, key) } fn is_descendent_of(&self, base: &Block::Hash, block: &Block::Hash) -> Result { diff --git a/core/network/src/protocol.rs b/core/network/src/protocol.rs index cbe6bc356c..ee2849e1dd 100644 --- a/core/network/src/protocol.rs +++ b/core/network/src/protocol.rs @@ -226,7 +226,8 @@ impl<'a, B: BlockT> LightDispatchNetwork for LightDispatchIn<'a, B> { last: ::Hash, min: ::Hash, max: ::Hash, - key: Vec + storage_key: Option>, + key: Vec, ) { let message = message::generic::Message::RemoteChangesRequest(message::RemoteChangesRequest { id, @@ -234,6 +235,7 @@ impl<'a, B: BlockT> LightDispatchNetwork for LightDispatchIn<'a, B> { last, min, max, + storage_key, key, }); @@ -1385,24 +1387,34 @@ impl, H: ExHashT> Protocol { trace!(target: "sync", "Remote changes proof request {} from {} for key {} ({}..{})", request.id, who, - request.key.to_hex::(), + if let Some(sk) = request.storage_key.as_ref() { + format!("{} : {}", sk.to_hex::(), request.key.to_hex::()) + } else { + request.key.to_hex::() + }, request.first, request.last ); + let storage_key = request.storage_key.map(|sk| StorageKey(sk)); let key = StorageKey(request.key); let proof = match self.context_data.chain.key_changes_proof( request.first, request.last, request.min, request.max, - &key + storage_key.as_ref(), + &key, ) { Ok(proof) => proof, Err(error) => { trace!(target: "sync", "Remote changes proof request {} from {} for key {} ({}..{}) failed with: {}", request.id, who, - key.0.to_hex::(), + if let Some(sk) = storage_key { + format!("{} : {}", sk.0.to_hex::(), key.0.to_hex::()) + } else { + key.0.to_hex::() + }, request.first, request.last, error diff --git a/core/network/src/protocol/light_dispatch.rs b/core/network/src/protocol/light_dispatch.rs index e56ed3a08e..db7a55d742 100644 --- a/core/network/src/protocol/light_dispatch.rs +++ b/core/network/src/protocol/light_dispatch.rs @@ -84,7 +84,8 @@ pub trait LightDispatchNetwork { last: ::Hash, min: ::Hash, max: ::Hash, - key: Vec + storage_key: Option>, + key: Vec, ); /// Send to `who` a body request. @@ -629,6 +630,7 @@ impl Request { data.last_block.1.clone(), data.tries_roots.1.clone(), data.max_block.1.clone(), + data.storage_key.clone(), data.key.clone(), ), RequestData::RemoteBody(ref data, _) => @@ -785,7 +787,7 @@ pub mod tests { _: Vec) {} fn send_call_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: String, _: Vec) {} fn send_changes_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: ::Hash, - _: ::Hash, _: ::Hash, _: Vec) {} + _: ::Hash, _: ::Hash, _: Option>, _: Vec) {} fn send_body_request(&mut self, _: &PeerId, _: RequestId, _: BlockAttributes, _: FromBlock<::Hash, <::Header as HeaderT>::Number>, _: Option, _: Direction, _: Option) {} } @@ -1063,6 +1065,7 @@ pub mod tests { max_block: (100, Default::default()), tries_roots: (1, Default::default(), vec![]), key: vec![], + storage_key: None, retry_count: None, }, tx)); diff --git a/core/network/src/protocol/message.rs b/core/network/src/protocol/message.rs index 4110970f99..39bb94eb33 100644 --- a/core/network/src/protocol/message.rs +++ b/core/network/src/protocol/message.rs @@ -334,6 +334,8 @@ pub mod generic { pub min: H, /// Hash of the last block that we can use when querying changes. pub max: H, + /// Storage child node key which changes are requested. + pub storage_key: Option>, /// Storage key which changes are requested. pub key: Vec, } diff --git a/core/rpc/src/state/state_full.rs b/core/rpc/src/state/state_full.rs index 1f780d3e11..3115a525a8 100644 --- a/core/rpc/src/state/state_full.rs +++ b/core/rpc/src/state/state_full.rs @@ -188,7 +188,7 @@ impl FullState for key in keys { let mut last_block = None; let mut last_value = last_values.get(key).cloned().unwrap_or_default(); - let key_changes = self.client.key_changes(begin, end, key).map_err(client_err)?; + let key_changes = self.client.key_changes(begin, end, None, key).map_err(client_err)?; for (block, _) in key_changes.into_iter().rev() { if last_block == Some(block) { continue; diff --git a/core/state-machine/src/backend.rs b/core/state-machine/src/backend.rs index 0feb6e84d0..28ab61a5ed 100644 --- a/core/state-machine/src/backend.rs +++ b/core/state-machine/src/backend.rs @@ -72,7 +72,14 @@ pub trait Backend { /// Retrieve all entries keys which start with the given prefix and /// call `f` for each of those keys. - fn for_keys_with_prefix(&self, prefix: &[u8], f: F); + fn for_keys_with_prefix(&self, prefix: &[u8], mut f: F) { + self.for_key_values_with_prefix(prefix, |k, _v| f(k)) + } + + /// Retrieve all entries keys and values of which start with the given prefix and + /// call `f` for each of those keys. + fn for_key_values_with_prefix(&self, prefix: &[u8], f: F); + /// Retrieve all child entries keys which start with the given prefix and /// call `f` for each of those keys. @@ -321,6 +328,11 @@ impl Backend for InMemory { self.inner.get(&None).map(|map| map.keys().filter(|key| key.starts_with(prefix)).map(|k| &**k).for_each(f)); } + fn for_key_values_with_prefix(&self, prefix: &[u8], mut f: F) { + self.inner.get(&None).map(|map| map.iter().filter(|(key, _val)| key.starts_with(prefix)) + .for_each(|(k, v)| f(k, v))); + } + fn for_keys_in_child_storage(&self, storage_key: &[u8], mut f: F) { self.inner.get(&Some(storage_key.to_vec())).map(|map| map.keys().for_each(|k| f(&k))); } diff --git a/core/state-machine/src/changes_trie/build.rs b/core/state-machine/src/changes_trie/build.rs index cc2185ee79..e5f539f483 100644 --- a/core/state-machine/src/changes_trie/build.rs +++ b/core/state-machine/src/changes_trie/build.rs @@ -16,7 +16,7 @@ //! Structures and functions required to build changes trie for given block. -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; use std::collections::btree_map::Entry; use codec::Decode; use hash_db::Hasher; @@ -27,6 +27,7 @@ use crate::trie_backend_essence::TrieBackendEssence; use crate::changes_trie::build_iterator::digest_build_iterator; use crate::changes_trie::input::{InputKey, InputPair, DigestIndex, ExtrinsicIndex}; use crate::changes_trie::{AnchorBlockId, ConfigurationRange, Storage, BlockNumber}; +use crate::changes_trie::input::ChildIndex; /// Prepare input pairs for building a changes trie of given block. /// @@ -38,49 +39,121 @@ pub fn prepare_input<'a, B, H, Number>( config: ConfigurationRange<'a, Number>, changes: &'a OverlayedChanges, parent: &'a AnchorBlockId, -) -> Result> + 'a, String> +) -> Result<( + impl Iterator> + 'a, + Vec<(ChildIndex, impl Iterator> + 'a)>, + ), String> where B: Backend, H: Hasher + 'a, Number: BlockNumber, { let number = parent.number.clone() + One::one(); - let extrinsics_input = prepare_extrinsics_input( + let (extrinsics_input, children_extrinsics_input) = prepare_extrinsics_input( backend, &number, changes)?; - let digest_input = prepare_digest_input::( + let (digest_input, mut children_digest_input) = prepare_digest_input::( parent, config, - number, + &number, storage)?; - Ok(extrinsics_input.chain(digest_input)) -} + let mut children_digest = Vec::with_capacity(children_extrinsics_input.len()); + for (child_index, ext_iter) in children_extrinsics_input.into_iter() { + let dig_iter = children_digest_input.remove(&child_index); + children_digest.push(( + child_index, + Some(ext_iter).into_iter().flatten() + .chain(dig_iter.into_iter().flatten()), + )); + } + for (child_index, dig_iter) in children_digest_input.into_iter() { + children_digest.push(( + child_index, + None.into_iter().flatten() + .chain(Some(dig_iter).into_iter().flatten()), + )); + } + + Ok(( + extrinsics_input.chain(digest_input), + children_digest, + )) +} /// Prepare ExtrinsicIndex input pairs. fn prepare_extrinsics_input<'a, B, H, Number>( backend: &'a B, block: &Number, changes: &'a OverlayedChanges, +) -> Result<( + impl Iterator> + 'a, + BTreeMap, impl Iterator> + 'a>, + ), String> + where + B: Backend, + H: Hasher + 'a, + Number: BlockNumber, +{ + + let mut children_keys = BTreeSet::>::new(); + let mut children_result = BTreeMap::new(); + for (storage_key, _) in changes.prospective.children.iter() + .chain(changes.committed.children.iter()) { + children_keys.insert(storage_key.clone()); + } + for storage_key in children_keys { + let child_index = ChildIndex:: { + block: block.clone(), + storage_key: storage_key.clone(), + }; + + let iter = prepare_extrinsics_input_inner(backend, block, changes, Some(storage_key))?; + children_result.insert(child_index, iter); + } + + let top = prepare_extrinsics_input_inner(backend, block, changes, None)?; + + Ok((top, children_result)) +} + +fn prepare_extrinsics_input_inner<'a, B, H, Number>( + backend: &'a B, + block: &Number, + changes: &'a OverlayedChanges, + storage_key: Option>, ) -> Result> + 'a, String> where B: Backend, H: Hasher, Number: BlockNumber, { - changes.committed.top.iter() - .chain(changes.prospective.top.iter()) + let (committed, prospective) = if let Some(sk) = storage_key.as_ref() { + (changes.committed.children.get(sk), changes.prospective.children.get(sk)) + } else { + (Some(&changes.committed.top), Some(&changes.prospective.top)) + }; + committed.iter().flat_map(|c| c.iter()) + .chain(prospective.iter().flat_map(|c| c.iter())) .filter(|( _, v)| v.extrinsics.is_some()) .try_fold(BTreeMap::new(), |mut map: BTreeMap<&[u8], (ExtrinsicIndex, Vec)>, (k, v)| { match map.entry(k) { Entry::Vacant(entry) => { // ignore temporary values (values that have null value at the end of operation // AND are not in storage at the beginning of operation - if !changes.storage(k).map(|v| v.is_some()).unwrap_or_default() { - if !backend.exists_storage(k).map_err(|e| format!("{}", e))? { - return Ok(map); + if let Some(sk) = storage_key.as_ref() { + if !changes.child_storage(sk, k).map(|v| v.is_some()).unwrap_or_default() { + if !backend.exists_child_storage(sk, k).map_err(|e| format!("{}", e))? { + return Ok(map); + } + } + } else { + if !changes.storage(k).map(|v| v.is_some()).unwrap_or_default() { + if !backend.exists_storage(k).map_err(|e| format!("{}", e))? { + return Ok(map); + } } - } + }; let extrinsics = v.extrinsics.as_ref() .expect("filtered by filter() call above; qed") @@ -109,13 +182,17 @@ fn prepare_extrinsics_input<'a, B, H, Number>( .map(|pairs| pairs.into_iter().map(|(_, (k, v))| InputPair::ExtrinsicIndex(k, v))) } + /// Prepare DigestIndex input pairs. fn prepare_digest_input<'a, H, Number>( parent: &'a AnchorBlockId, config: ConfigurationRange<'a, Number>, - block: Number, + block: &Number, storage: &'a dyn Storage, -) -> Result> + 'a, String> +) -> Result<( + impl Iterator> + 'a, + BTreeMap, impl Iterator> + 'a>, + ), String> where H: Hasher, H::Out: 'a, @@ -131,15 +208,16 @@ fn prepare_digest_input<'a, H, Number>( }; digest_build_iterator(config, block_for_digest) - .try_fold(BTreeMap::new(), move |mut map, digest_build_block| { + .try_fold( + (BTreeMap::new(), BTreeMap::new()), + move |(mut map, mut child_map), digest_build_block| { + let extrinsic_prefix = ExtrinsicIndex::key_neutral_prefix(digest_build_block.clone()); + let digest_prefix = DigestIndex::key_neutral_prefix(digest_build_block.clone()); + let child_prefix = ChildIndex::key_neutral_prefix(digest_build_block.clone()); let trie_root = storage.root(parent, digest_build_block.clone())?; let trie_root = trie_root.ok_or_else(|| format!("No changes trie root for block {}", digest_build_block.clone()))?; - let trie_storage = TrieBackendEssence::<_, H>::new( - crate::changes_trie::TrieBackendStorageAdapter(storage), - trie_root, - ); - - let mut insert_to_map = |key: Vec| { + + let insert_to_map = |map: &mut BTreeMap<_,_>, key: Vec| { match map.entry(key.clone()) { Entry::Vacant(entry) => { entry.insert((DigestIndex { @@ -161,32 +239,74 @@ fn prepare_digest_input<'a, H, Number>( } }; - let extrinsic_prefix = ExtrinsicIndex::key_neutral_prefix(digest_build_block.clone()); - trie_storage.for_keys_with_prefix(&extrinsic_prefix, |key| - if let Ok(InputKey::ExtrinsicIndex::(trie_key)) = Decode::decode(&mut &key[..]) { - insert_to_map(trie_key.key); - }); + let mut children_roots = BTreeMap::, _>::new(); + { + let trie_storage = TrieBackendEssence::<_, H>::new( + crate::changes_trie::TrieBackendStorageAdapter(storage), + trie_root, + ); + + trie_storage.for_key_values_with_prefix(&child_prefix, |key, value| + if let Ok(InputKey::ChildIndex::(trie_key)) = Decode::decode(&mut &key[..]) { + if let Ok(value) = >::decode(&mut &value[..]) { + let mut trie_root = ::Out::default(); + trie_root.as_mut().copy_from_slice(&value[..]); + children_roots.insert(trie_key.storage_key, trie_root); + } + }); - let digest_prefix = DigestIndex::key_neutral_prefix(digest_build_block.clone()); - trie_storage.for_keys_with_prefix(&digest_prefix, |key| - if let Ok(InputKey::DigestIndex::(trie_key)) = Decode::decode(&mut &key[..]) { - insert_to_map(trie_key.key); - }); + trie_storage.for_keys_with_prefix(&extrinsic_prefix, |key| + if let Ok(InputKey::ExtrinsicIndex::(trie_key)) = Decode::decode(&mut &key[..]) { + insert_to_map(&mut map, trie_key.key); + }); + + trie_storage.for_keys_with_prefix(&digest_prefix, |key| + if let Ok(InputKey::DigestIndex::(trie_key)) = Decode::decode(&mut &key[..]) { + insert_to_map(&mut map, trie_key.key); + }); + } + + for (storage_key, trie_root) in children_roots.into_iter() { + let child_index = ChildIndex:: { + block: block.clone(), + storage_key, + }; + + let mut map = child_map.entry(child_index).or_insert_with(|| BTreeMap::, _>::new()); + let trie_storage = TrieBackendEssence::<_, H>::new( + crate::changes_trie::TrieBackendStorageAdapter(storage), + trie_root, + ); + trie_storage.for_keys_with_prefix(&extrinsic_prefix, |key| + if let Ok(InputKey::ExtrinsicIndex::(trie_key)) = Decode::decode(&mut &key[..]) { + insert_to_map(&mut map, trie_key.key); + }); + + trie_storage.for_keys_with_prefix(&digest_prefix, |key| + if let Ok(InputKey::DigestIndex::(trie_key)) = Decode::decode(&mut &key[..]) { + insert_to_map(&mut map, trie_key.key); + }); + } + Ok((map, child_map)) - Ok(map) }) - .map(|pairs| pairs.into_iter().map(|(_, (k, v))| InputPair::DigestIndex(k, v))) + + .map(|(pairs, child_pairs)| ( + pairs.into_iter().map(|(_, (k, v))| InputPair::DigestIndex(k, v)), + child_pairs.into_iter().map(|(sk, pairs)| + (sk, pairs.into_iter().map(|(_, (k, v))| InputPair::DigestIndex(k, v)))).collect(), + )) } #[cfg(test)] mod test { use codec::Encode; use primitives::Blake2Hasher; - use primitives::storage::well_known_keys::EXTRINSIC_INDEX; + use primitives::storage::well_known_keys::{EXTRINSIC_INDEX}; use crate::backend::InMemory; use crate::changes_trie::Configuration; use crate::changes_trie::storage::InMemoryStorage; - use crate::overlayed_changes::OverlayedValue; + use crate::overlayed_changes::{OverlayedValue, OverlayedChangeSet}; use super::*; fn prepare_for_build(zero: u64) -> ( @@ -204,6 +324,8 @@ mod test { (vec![104], vec![255]), (vec![105], vec![255]), ].into_iter().collect::<::std::collections::HashMap<_, _>>().into(); + let child_trie_key1 = b"1".to_vec(); + let child_trie_key2 = b"2".to_vec(); let storage = InMemoryStorage::with_inputs(vec![ (zero + 1, vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 1, key: vec![100] }, vec![1, 3]), @@ -237,9 +359,24 @@ mod test { ]), (zero + 9, Vec::new()), (zero + 10, Vec::new()), (zero + 11, Vec::new()), (zero + 12, Vec::new()), (zero + 13, Vec::new()), (zero + 14, Vec::new()), (zero + 15, Vec::new()), + ], vec![(child_trie_key1.clone(), vec![ + (zero + 1, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 1, key: vec![100] }, vec![1, 3]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 1, key: vec![101] }, vec![0, 2]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 1, key: vec![105] }, vec![0, 2, 4]), + ]), + (zero + 2, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 2, key: vec![102] }, vec![0]), + ]), + (zero + 4, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 2, key: vec![102] }, vec![0, 3]), + + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![102] }, vec![zero + 2]), + ]), + ]), ]); let changes = OverlayedChanges { - prospective: vec![ + prospective: OverlayedChangeSet { top: vec![ (vec![100], OverlayedValue { value: Some(vec![200]), extrinsics: Some(vec![0, 2].into_iter().collect()) @@ -249,7 +386,22 @@ mod test { extrinsics: Some(vec![0, 1].into_iter().collect()) }), ].into_iter().collect(), - committed: vec![ + children: vec![ + (child_trie_key1.clone(), vec![ + (vec![100], OverlayedValue { + value: Some(vec![200]), + extrinsics: Some(vec![0, 2].into_iter().collect()) + }) + ].into_iter().collect()), + (child_trie_key2, vec![ + (vec![100], OverlayedValue { + value: Some(vec![200]), + extrinsics: Some(vec![0, 2].into_iter().collect()) + }) + ].into_iter().collect()), + ].into_iter().collect() + }, + committed: OverlayedChangeSet { top: vec![ (EXTRINSIC_INDEX.to_vec(), OverlayedValue { value: Some(3u32.encode()), extrinsics: None, @@ -263,6 +415,15 @@ mod test { extrinsics: Some(vec![1].into_iter().collect()) }), ].into_iter().collect(), + children: vec![ + (child_trie_key1, vec![ + (vec![100], OverlayedValue { + value: Some(vec![202]), + extrinsics: Some(vec![3].into_iter().collect()) + }) + ].into_iter().collect()), + ].into_iter().collect(), + }, changes_trie_config: Some(config.clone()), }; @@ -289,11 +450,23 @@ mod test { &changes, &parent, ).unwrap(); - assert_eq!(changes_trie_nodes.collect::>>(), vec![ + assert_eq!(changes_trie_nodes.0.collect::>>(), vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 5, key: vec![100] }, vec![0, 2, 3]), InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 5, key: vec![101] }, vec![1]), InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 5, key: vec![103] }, vec![0, 1]), ]); + assert_eq!(changes_trie_nodes.1.into_iter() + .map(|(k,v)| (k, v.collect::>())).collect::>(), vec![ + (ChildIndex { block: zero + 5u64, storage_key: b"1".to_vec() }, + vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 5u64, key: vec![100] }, vec![0, 2, 3]), + ]), + (ChildIndex { block: zero + 5, storage_key: b"2".to_vec() }, + vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 5, key: vec![100] }, vec![0, 2]), + ]), + ]); + } test_with_zero(0); @@ -313,7 +486,7 @@ mod test { &changes, &parent, ).unwrap(); - assert_eq!(changes_trie_nodes.collect::>>(), vec![ + assert_eq!(changes_trie_nodes.0.collect::>>(), vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![100] }, vec![0, 2, 3]), InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![101] }, vec![1]), InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![103] }, vec![0, 1]), @@ -323,6 +496,23 @@ mod test { InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![102] }, vec![zero + 2]), InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![105] }, vec![zero + 1, zero + 3]), ]); + assert_eq!(changes_trie_nodes.1.into_iter() + .map(|(k,v)| (k, v.collect::>())).collect::>(), vec![ + (ChildIndex { block: zero + 4u64, storage_key: b"1".to_vec() }, + vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4u64, key: vec![100] }, vec![0, 2, 3]), + + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![100] }, vec![zero + 1]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![101] }, vec![zero + 1]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![102] }, vec![zero + 2]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![105] }, vec![zero + 1]), + ]), + (ChildIndex { block: zero + 4, storage_key: b"2".to_vec() }, + vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![100] }, vec![0, 2]), + ]), + ]); + } test_with_zero(0); @@ -342,7 +532,7 @@ mod test { &changes, &parent, ).unwrap(); - assert_eq!(changes_trie_nodes.collect::>>(), vec![ + assert_eq!(changes_trie_nodes.0.collect::>>(), vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 16, key: vec![100] }, vec![0, 2, 3]), InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 16, key: vec![101] }, vec![1]), InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 16, key: vec![103] }, vec![0, 1]), @@ -353,6 +543,20 @@ mod test { InputPair::DigestIndex(DigestIndex { block: zero + 16, key: vec![103] }, vec![zero + 4]), InputPair::DigestIndex(DigestIndex { block: zero + 16, key: vec![105] }, vec![zero + 4, zero + 8]), ]); + assert_eq!(changes_trie_nodes.1.into_iter() + .map(|(k,v)| (k, v.collect::>())).collect::>(), vec![ + (ChildIndex { block: zero + 16u64, storage_key: b"1".to_vec() }, + vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 16u64, key: vec![100] }, vec![0, 2, 3]), + + InputPair::DigestIndex(DigestIndex { block: zero + 16, key: vec![102] }, vec![zero + 4]), + ]), + (ChildIndex { block: zero + 16, storage_key: b"2".to_vec() }, + vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 16, key: vec![100] }, vec![0, 2]), + ]), + ]); + } test_with_zero(0); @@ -374,7 +578,7 @@ mod test { &changes, &parent, ).unwrap(); - assert_eq!(changes_trie_nodes.collect::>>(), vec![ + assert_eq!(changes_trie_nodes.0.collect::>>(), vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 11, key: vec![100] }, vec![0, 2, 3]), InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 11, key: vec![101] }, vec![1]), InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 11, key: vec![103] }, vec![0, 1]), @@ -388,7 +592,7 @@ mod test { &changes, &parent, ).unwrap(); - assert_eq!(changes_trie_nodes.collect::>>(), vec![ + assert_eq!(changes_trie_nodes.0.collect::>>(), vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 11, key: vec![100] }, vec![0, 2, 3]), InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 11, key: vec![101] }, vec![1]), InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 11, key: vec![103] }, vec![0, 1]), @@ -425,7 +629,7 @@ mod test { &changes, &parent, ).unwrap(); - assert_eq!(changes_trie_nodes.collect::>>(), vec![ + assert_eq!(changes_trie_nodes.0.collect::>>(), vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![100] }, vec![0, 2, 3]), InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![101] }, vec![1]), InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![103] }, vec![0, 1]), @@ -435,6 +639,23 @@ mod test { InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![102] }, vec![zero + 2]), InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![105] }, vec![zero + 1, zero + 3]), ]); + assert_eq!(changes_trie_nodes.1.into_iter() + .map(|(k,v)| (k, v.collect::>())).collect::>(), vec![ + (ChildIndex { block: zero + 4u64, storage_key: b"1".to_vec() }, + vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4u64, key: vec![100] }, vec![0, 2, 3]), + + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![100] }, vec![zero + 1]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![101] }, vec![zero + 1]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![102] }, vec![zero + 2]), + InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![105] }, vec![zero + 1]), + ]), + (ChildIndex { block: zero + 4, storage_key: b"2".to_vec() }, + vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![100] }, vec![0, 2]), + ]), + ]); + } test_with_zero(0); diff --git a/core/state-machine/src/changes_trie/changes_iterator.rs b/core/state-machine/src/changes_trie/changes_iterator.rs index 397bc89857..e8730a1bdd 100644 --- a/core/state-machine/src/changes_trie/changes_iterator.rs +++ b/core/state-machine/src/changes_trie/changes_iterator.rs @@ -26,6 +26,7 @@ use trie::Recorder; use crate::changes_trie::{AnchorBlockId, ConfigurationRange, RootsStorage, Storage, BlockNumber}; use crate::changes_trie::input::{DigestIndex, ExtrinsicIndex, DigestIndexValue, ExtrinsicIndexValue}; use crate::changes_trie::storage::{TrieBackendAdapter, InMemoryStorage}; +use crate::changes_trie::input::ChildIndex; use crate::changes_trie::surface_iterator::{surface_iterator, SurfaceIterator}; use crate::proving_backend::ProvingBackendEssence; use crate::trie_backend_essence::{TrieBackendEssence}; @@ -39,6 +40,7 @@ pub fn key_changes<'a, H: Hasher, Number: BlockNumber>( begin: Number, end: &'a AnchorBlockId, max: Number, + storage_key: Option<&'a [u8]>, key: &'a [u8], ) -> Result, String> { // we can't query any roots before root @@ -46,6 +48,7 @@ pub fn key_changes<'a, H: Hasher, Number: BlockNumber>( Ok(DrilldownIterator { essence: DrilldownIteratorEssence { + storage_key, key, roots_storage: storage.as_roots_storage(), storage, @@ -67,6 +70,7 @@ pub fn key_changes<'a, H: Hasher, Number: BlockNumber>( }) } + /// Returns proof of changes of given key at given blocks range. /// `max` is the number of best known block. pub fn key_changes_proof<'a, H: Hasher, Number: BlockNumber>( @@ -75,6 +79,7 @@ pub fn key_changes_proof<'a, H: Hasher, Number: BlockNumber>( begin: Number, end: &AnchorBlockId, max: Number, + storage_key: Option<&[u8]>, key: &[u8], ) -> Result>, String> { // we can't query any roots before root @@ -82,6 +87,7 @@ pub fn key_changes_proof<'a, H: Hasher, Number: BlockNumber>( let mut iter = ProvingDrilldownIterator { essence: DrilldownIteratorEssence { + storage_key, key, roots_storage: storage.as_roots_storage(), storage, @@ -121,6 +127,7 @@ pub fn key_changes_proof_check<'a, H: Hasher, Number: BlockNumber>( begin: Number, end: &AnchorBlockId, max: Number, + storage_key: Option<&[u8]>, key: &[u8] ) -> Result, String> { key_changes_proof_check_with_db( @@ -130,6 +137,7 @@ pub fn key_changes_proof_check<'a, H: Hasher, Number: BlockNumber>( begin, end, max, + storage_key, key, ) } @@ -142,6 +150,7 @@ pub fn key_changes_proof_check_with_db<'a, H: Hasher, Number: BlockNumber>( begin: Number, end: &AnchorBlockId, max: Number, + storage_key: Option<&[u8]>, key: &[u8] ) -> Result, String> { // we can't query any roots before root @@ -149,6 +158,7 @@ pub fn key_changes_proof_check_with_db<'a, H: Hasher, Number: BlockNumber>( DrilldownIterator { essence: DrilldownIteratorEssence { + storage_key, key, roots_storage, storage: proof_db, @@ -178,6 +188,7 @@ pub struct DrilldownIteratorEssence<'a, H, Number> Number: BlockNumber, H::Out: 'a, { + storage_key: Option<&'a [u8]>, key: &'a [u8], roots_storage: &'a dyn RootsStorage, storage: &'a dyn Storage, @@ -224,6 +235,25 @@ impl<'a, H, Number> DrilldownIteratorEssence<'a, H, Number> // AND trie roots for old blocks are known (both on full + light node) let trie_root = self.roots_storage.root(&self.end, block.clone())? .ok_or_else(|| format!("Changes trie root for block {} is not found", block.clone()))?; + let trie_root = if let Some(storage_key) = self.storage_key { + let child_key = ChildIndex { + block: block.clone(), + storage_key: storage_key.to_vec(), + }.encode(); + if let Some(trie_root) = trie_reader(self.storage, trie_root, &child_key)? + .and_then(|v| >::decode(&mut &v[..]).ok()) + .map(|v| { + let mut hash = H::Out::default(); + hash.as_mut().copy_from_slice(&v[..]); + hash + }) { + trie_root + } else { + continue; + } + } else { + trie_root + }; // only return extrinsics for blocks before self.max // most of blocks will be filtered out before pushing to `self.blocks` @@ -356,8 +386,10 @@ mod tests { let config = Configuration { digest_interval: 4, digest_levels: 2 }; let backend = InMemoryStorage::with_inputs(vec![ // digest: 1..4 => [(3, 0)] - (1, vec![]), - (2, vec![]), + (1, vec![ + ]), + (2, vec![ + ]), (3, vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 3, key: vec![42] }, vec![0]), ]), @@ -386,6 +418,19 @@ mod tests { (16, vec![ InputPair::DigestIndex(DigestIndex { block: 16, key: vec![42] }, vec![4, 8]), ]), + ], vec![(b"1".to_vec(), vec![ + (1, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 1, key: vec![42] }, vec![0]), + ]), + (2, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 2, key: vec![42] }, vec![3]), + ]), + (16, vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16, key: vec![42] }, vec![5]), + + InputPair::DigestIndex(DigestIndex { block: 16, key: vec![42] }, vec![2]), + ]), + ]), ]); (config, backend) @@ -408,6 +453,7 @@ mod tests { 1, &AnchorBlockId { hash: Default::default(), number: 16 }, 16, + None, &[42], ).and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![(8, 2), (8, 1), (6, 3), (3, 0)])); @@ -418,6 +464,7 @@ mod tests { 1, &AnchorBlockId { hash: Default::default(), number: 2 }, 4, + None, &[42], ).and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![])); @@ -428,6 +475,7 @@ mod tests { 1, &AnchorBlockId { hash: Default::default(), number: 3 }, 4, + None, &[42], ).and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![(3, 0)])); @@ -438,6 +486,7 @@ mod tests { 1, &AnchorBlockId { hash: Default::default(), number: 7 }, 7, + None, &[42], ).and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![(6, 3), (3, 0)])); @@ -448,6 +497,7 @@ mod tests { 7, &AnchorBlockId { hash: Default::default(), number: 8 }, 8, + None, &[42], ).and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![(8, 2), (8, 1)])); @@ -458,6 +508,7 @@ mod tests { 5, &AnchorBlockId { hash: Default::default(), number: 7 }, 8, + None, &[42], ).and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![(6, 3)])); @@ -474,6 +525,17 @@ mod tests { 1, &AnchorBlockId { hash: Default::default(), number: 100 }, 1000, + None, + &[42], + ).and_then(|i| i.collect::, _>>()).is_err()); + + assert!(key_changes::( + configuration_range(&config, 0), + &storage, + 1, + &AnchorBlockId { hash: Default::default(), number: 100 }, + 1000, + Some(&b"1"[..]), &[42], ).and_then(|i| i.collect::, _>>()).is_err()); } @@ -487,6 +549,7 @@ mod tests { 1, &AnchorBlockId { hash: Default::default(), number: 100 }, 50, + None, &[42], ).is_err()); assert!(key_changes::( @@ -495,6 +558,7 @@ mod tests { 20, &AnchorBlockId { hash: Default::default(), number: 10 }, 100, + None, &[42], ).is_err()); } @@ -507,8 +571,13 @@ mod tests { // create drilldown iterator that records all trie nodes during drilldown let (remote_config, remote_storage) = prepare_for_drilldown(); let remote_proof = key_changes_proof::( - configuration_range(&remote_config, 0), &remote_storage, - 1, &AnchorBlockId { hash: Default::default(), number: 16 }, 16, &[42]).unwrap(); + configuration_range(&remote_config, 0), &remote_storage, 1, + &AnchorBlockId { hash: Default::default(), number: 16 }, 16, None, &[42]).unwrap(); + + let (remote_config, remote_storage) = prepare_for_drilldown(); + let remote_proof_child = key_changes_proof::( + configuration_range(&remote_config, 0), &remote_storage, 1, + &AnchorBlockId { hash: Default::default(), number: 16 }, 16, Some(&b"1"[..]), &[42]).unwrap(); // happens on local light node: @@ -516,11 +585,18 @@ mod tests { let (local_config, local_storage) = prepare_for_drilldown(); local_storage.clear_storage(); let local_result = key_changes_proof_check::( - configuration_range(&local_config, 0), &local_storage, remote_proof, - 1, &AnchorBlockId { hash: Default::default(), number: 16 }, 16, &[42]); + configuration_range(&local_config, 0), &local_storage, remote_proof, 1, + &AnchorBlockId { hash: Default::default(), number: 16 }, 16, None, &[42]); + + let (local_config, local_storage) = prepare_for_drilldown(); + local_storage.clear_storage(); + let local_result_child = key_changes_proof_check::( + configuration_range(&local_config, 0), &local_storage, remote_proof_child, 1, + &AnchorBlockId { hash: Default::default(), number: 16 }, 16, Some(&b"1"[..]), &[42]); // check that drilldown result is the same as if it was happening at the full node assert_eq!(local_result, Ok(vec![(8, 2), (8, 1), (6, 3), (3, 0)])); + assert_eq!(local_result_child, Ok(vec![(16, 5), (2, 3)])); } #[test] @@ -543,11 +619,17 @@ mod tests { input[79 - 1].1.push(InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 79, key: vec![42] }, vec![1])); input[80 - 1].1.push(InputPair::DigestIndex(DigestIndex { block: 80, key: vec![42] }, vec![79])); input[91 - 1].1.push(InputPair::DigestIndex(DigestIndex { block: 91, key: vec![42] }, vec![80])); - let storage = InMemoryStorage::with_inputs(input); + let storage = InMemoryStorage::with_inputs(input, vec![]); let drilldown_result = key_changes::( - config_range, &storage, 1, &AnchorBlockId { hash: Default::default(), number: 91 }, 100_000u64, &[42]) - .and_then(Result::from_iter); + config_range, + &storage, + 1, + &AnchorBlockId { hash: Default::default(), number: 91 }, + 100_000u64, + None, + &[42], + ).and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![(79, 1), (63, 0)])); } } diff --git a/core/state-machine/src/changes_trie/input.rs b/core/state-machine/src/changes_trie/input.rs index 8da4f1a386..17f3b41b22 100644 --- a/core/state-machine/src/changes_trie/input.rs +++ b/core/state-machine/src/changes_trie/input.rs @@ -40,9 +40,22 @@ pub struct DigestIndex { pub key: Vec, } +/// Key of { childtrie key => Childchange trie } mapping. +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub struct ChildIndex { + /// Block at which this key has been inserted in the trie. + pub block: Number, + /// Storage key this node is responsible for. + pub storage_key: Vec, +} + /// Value of { changed key => block/digest block numbers } mapping. pub type DigestIndexValue = Vec; +/// Value of { changed key => block/digest block numbers } mapping. +/// That is the root of the child change trie. +pub type ChildIndexValue = Vec; + /// Single input pair of changes trie. #[derive(Clone, Debug, PartialEq, Eq)] pub enum InputPair { @@ -50,6 +63,8 @@ pub enum InputPair { ExtrinsicIndex(ExtrinsicIndex, ExtrinsicIndexValue), /// Element of { key => set of blocks/digest blocks where key has been changed } element mapping. DigestIndex(DigestIndex, DigestIndexValue), + /// Element of { childtrie key => Childchange trie } where key has been changed } element mapping. + ChildIndex(ChildIndex, ChildIndexValue), } /// Single input key of changes trie. @@ -59,6 +74,8 @@ pub enum InputKey { ExtrinsicIndex(ExtrinsicIndex), /// Key of { key => set of blocks/digest blocks where key has been changed } element mapping. DigestIndex(DigestIndex), + /// Key of { childtrie key => Childchange trie } where key has been changed } element mapping. + ChildIndex(ChildIndex), } impl Into<(Vec, Vec)> for InputPair { @@ -66,6 +83,7 @@ impl Into<(Vec, Vec)> for InputPair { match self { InputPair::ExtrinsicIndex(key, value) => (key.encode(), value.encode()), InputPair::DigestIndex(key, value) => (key.encode(), value.encode()), + InputPair::ChildIndex(key, value) => (key.encode(), value.encode()), } } } @@ -75,6 +93,7 @@ impl Into> for InputPair { match self { InputPair::ExtrinsicIndex(key, _) => InputKey::ExtrinsicIndex(key), InputPair::DigestIndex(key, _) => InputKey::DigestIndex(key), + InputPair::ChildIndex(key, _) => InputKey::ChildIndex(key), } } } @@ -114,6 +133,22 @@ impl Encode for DigestIndex { } } +impl ChildIndex { + pub fn key_neutral_prefix(block: Number) -> Vec { + let mut prefix = vec![3]; + prefix.extend(block.encode()); + prefix + } +} + +impl Encode for ChildIndex { + fn encode_to(&self, dest: &mut W) { + dest.push_byte(3); + self.block.encode_to(dest); + self.storage_key.encode_to(dest); + } +} + impl codec::EncodeLike for DigestIndex {} impl Decode for InputKey { @@ -127,6 +162,10 @@ impl Decode for InputKey { block: Decode::decode(input)?, key: Decode::decode(input)?, })), + 3 => Ok(InputKey::ChildIndex(ChildIndex { + block: Decode::decode(input)?, + storage_key: Decode::decode(input)?, + })), _ => Err("Invalid input key variant".into()), } } diff --git a/core/state-machine/src/changes_trie/mod.rs b/core/state-machine/src/changes_trie/mod.rs index 5a607cee01..41234b3428 100644 --- a/core/state-machine/src/changes_trie/mod.rs +++ b/core/state-machine/src/changes_trie/mod.rs @@ -186,13 +186,34 @@ pub fn build_changes_trie<'a, B: Backend, S: Storage, H: Hasher, N let parent = storage.build_anchor(parent_hash).map_err(|_| ())?; // storage errors are considered fatal (similar to situations when runtime fetches values from storage) - let input_pairs = prepare_input::(backend, storage, config, changes, &parent) - .expect("changes trie: storage access is not allowed to fail within runtime"); - let mut root = Default::default(); + let (input_pairs, child_input_pairs) = prepare_input::( + backend, + storage, + config, + changes, + &parent, + ).expect("changes trie: storage access is not allowed to fail within runtime"); let mut mdb = MemoryDB::default(); + let mut child_roots = Vec::with_capacity(child_input_pairs.len()); + for (child_index, input_pairs) in child_input_pairs { + let mut not_empty = false; + let mut root = Default::default(); + { + let mut trie = TrieDBMut::::new(&mut mdb, &mut root); + for (key, value) in input_pairs.map(Into::into) { + not_empty = true; + trie.insert(&key, &value) + .expect("changes trie: insertion to trie is not allowed to fail within runtime"); + } + } + if not_empty { + child_roots.push(input::InputPair::ChildIndex(child_index, root.as_ref().to_vec())); + } + } + let mut root = Default::default(); { let mut trie = TrieDBMut::::new(&mut mdb, &mut root); - for (key, value) in input_pairs.map(Into::into) { + for (key, value) in input_pairs.chain(child_roots.into_iter()).map(Into::into) { trie.insert(&key, &value) .expect("changes trie: insertion to trie is not allowed to fail within runtime"); } diff --git a/core/state-machine/src/changes_trie/prune.rs b/core/state-machine/src/changes_trie/prune.rs index 01d52b23ce..1dc7c3e6c0 100644 --- a/core/state-machine/src/changes_trie/prune.rs +++ b/core/state-machine/src/changes_trie/prune.rs @@ -24,6 +24,8 @@ use crate::proving_backend::ProvingBackendEssence; use crate::trie_backend_essence::TrieBackendEssence; use crate::changes_trie::{AnchorBlockId, Configuration, Storage, BlockNumber}; use crate::changes_trie::storage::TrieBackendAdapter; +use crate::changes_trie::input::{ChildIndex, InputKey}; +use codec::Decode; /// Get number of oldest block for which changes trie is not pruned /// given changes trie configuration, pruning parameter and number of @@ -54,6 +56,7 @@ pub fn prune, H: Hasher, Number: BlockNumber, F: FnMut(H:: current_block: &AnchorBlockId, mut remove_trie_node: F, ) { + // select range for pruning let (first, last) = match pruning_range(config, min_blocks_to_keep, current_block.number.clone()) { Some((first, last)) => (first, last), @@ -81,23 +84,55 @@ pub fn prune, H: Hasher, Number: BlockNumber, F: FnMut(H:: continue; }, }; - - // enumerate all changes trie' keys, recording all nodes that have been 'touched' - // (effectively - all changes trie nodes) - let mut proof_recorder: Recorder = Default::default(); - { - let mut trie = ProvingBackendEssence::<_, H> { - backend: &TrieBackendEssence::new(TrieBackendAdapter::new(storage), root), - proof_recorder: &mut proof_recorder, - }; - trie.record_all_keys(); + let children_roots = { + let trie_storage = TrieBackendEssence::<_, H>::new( + crate::changes_trie::TrieBackendStorageAdapter(storage), + root, + ); + let child_prefix = ChildIndex::key_neutral_prefix(block.clone()); + let mut children_roots = Vec::new(); + trie_storage.for_key_values_with_prefix(&child_prefix, |key, value| { + if let Ok(InputKey::ChildIndex::(_trie_key)) = Decode::decode(&mut &key[..]) { + if let Ok(value) = >::decode(&mut &value[..]) { + let mut trie_root = ::Out::default(); + trie_root.as_mut().copy_from_slice(&value[..]); + children_roots.push(trie_root); + } + } + }); + + children_roots + }; + for root in children_roots.into_iter() { + prune_trie(storage, root, &mut remove_trie_node); } - // all nodes of this changes trie should be pruned - remove_trie_node(root); - for node in proof_recorder.drain().into_iter().map(|n| n.hash) { - remove_trie_node(node); - } + prune_trie(storage, root, &mut remove_trie_node); + } +} + +// Prune a trie. +fn prune_trie, H: Hasher, Number: BlockNumber, F: FnMut(H::Out)>( + storage: &S, + root: H::Out, + remove_trie_node: &mut F, +) { + + // enumerate all changes trie' keys, recording all nodes that have been 'touched' + // (effectively - all changes trie nodes) + let mut proof_recorder: Recorder = Default::default(); + { + let mut trie = ProvingBackendEssence::<_, H> { + backend: &TrieBackendEssence::new(TrieBackendAdapter::new(storage), root), + proof_recorder: &mut proof_recorder, + }; + trie.record_all_keys(); + } + + // all nodes of this changes trie should be pruned + remove_trie_node(root); + for node in proof_recorder.drain().into_iter().map(|n| n.hash) { + remove_trie_node(node); } } @@ -169,6 +204,7 @@ mod tests { use primitives::Blake2Hasher; use crate::backend::insert_into_memory_db; use crate::changes_trie::storage::InMemoryStorage; + use codec::Encode; use super::*; fn config(interval: u32, levels: u32) -> Configuration { @@ -193,12 +229,19 @@ mod tests { #[test] fn prune_works() { fn prepare_storage() -> InMemoryStorage { + + let child_key = ChildIndex { block: 67u64, storage_key: b"1".to_vec() }.encode(); let mut mdb1 = MemoryDB::::default(); let root1 = insert_into_memory_db::(&mut mdb1, vec![(vec![10], vec![20])]).unwrap(); let mut mdb2 = MemoryDB::::default(); let root2 = insert_into_memory_db::(&mut mdb2, vec![(vec![11], vec![21]), (vec![12], vec![22])]).unwrap(); let mut mdb3 = MemoryDB::::default(); - let root3 = insert_into_memory_db::(&mut mdb3, vec![(vec![13], vec![23]), (vec![14], vec![24])]).unwrap(); + let ch_root3 = insert_into_memory_db::(&mut mdb3, vec![(vec![110], vec![120])]).unwrap(); + let root3 = insert_into_memory_db::(&mut mdb3, vec![ + (vec![13], vec![23]), + (vec![14], vec![24]), + (child_key, ch_root3.as_ref().encode()), + ]).unwrap(); let mut mdb4 = MemoryDB::::default(); let root4 = insert_into_memory_db::(&mut mdb4, vec![(vec![15], vec![25])]).unwrap(); let storage = InMemoryStorage::new(); diff --git a/core/state-machine/src/changes_trie/storage.rs b/core/state-machine/src/changes_trie/storage.rs index 4cf7741763..65287241c1 100644 --- a/core/state-machine/src/changes_trie/storage.rs +++ b/core/state-machine/src/changes_trie/storage.rs @@ -29,7 +29,7 @@ use std::collections::HashSet; #[cfg(test)] use crate::backend::insert_into_memory_db; #[cfg(test)] -use crate::changes_trie::input::InputPair; +use crate::changes_trie::input::{InputPair, ChildIndex}; /// In-memory implementation of changes trie storage. pub struct InMemoryStorage { @@ -85,10 +85,32 @@ impl InMemoryStorage { } #[cfg(test)] - pub fn with_inputs(inputs: Vec<(Number, Vec>)>) -> Self { + pub fn with_inputs( + mut top_inputs: Vec<(Number, Vec>)>, + children_inputs: Vec<(Vec, Vec<(Number, Vec>)>)>, + ) -> Self { let mut mdb = MemoryDB::default(); let mut roots = BTreeMap::new(); - for (block, pairs) in inputs { + for (storage_key, child_input) in children_inputs { + for (block, pairs) in child_input { + let root = insert_into_memory_db::(&mut mdb, pairs.into_iter().map(Into::into)); + + if let Some(root) = root { + let ix = if let Some(ix) = top_inputs.iter().position(|v| v.0 == block) { + ix + } else { + top_inputs.push((block.clone(), Default::default())); + top_inputs.len() - 1 + }; + top_inputs[ix].1.push(InputPair::ChildIndex( + ChildIndex { block: block.clone(), storage_key: storage_key.clone() }, + root.as_ref().to_vec(), + )); + } + } + } + + for (block, pairs) in top_inputs { let root = insert_into_memory_db::(&mut mdb, pairs.into_iter().map(Into::into)); if let Some(root) = root { roots.insert(block, root); diff --git a/core/state-machine/src/ext.rs b/core/state-machine/src/ext.rs index 896b07c647..8281f0f9c2 100644 --- a/core/state-machine/src/ext.rs +++ b/core/state-machine/src/ext.rs @@ -305,10 +305,10 @@ where let child_delta_iter = child_storage_keys.map(|storage_key| (storage_key.clone(), self.overlay.committed.children.get(storage_key) .into_iter() - .flat_map(|map| map.1.iter().map(|(k, v)| (k.clone(), v.clone()))) + .flat_map(|map| map.iter().map(|(k, v)| (k.clone(), v.value.clone()))) .chain(self.overlay.prospective.children.get(storage_key) .into_iter() - .flat_map(|map| map.1.iter().map(|(k, v)| (k.clone(), v.clone())))))); + .flat_map(|map| map.iter().map(|(k, v)| (k.clone(), v.value.clone())))))); // compute and memoize @@ -333,10 +333,10 @@ where let delta = self.overlay.committed.children.get(storage_key) .into_iter() - .flat_map(|map| map.1.iter().map(|(k, v)| (k.clone(), v.clone()))) + .flat_map(|map| map.iter().map(|(k, v)| (k.clone(), v.value.clone()))) .chain(self.overlay.prospective.children.get(storage_key) .into_iter() - .flat_map(|map| map.1.clone().into_iter())); + .flat_map(|map| map.clone().into_iter().map(|(k, v)| (k.clone(), v.value.clone())))); let root = self.backend.child_storage_root(storage_key, delta).0; diff --git a/core/state-machine/src/overlayed_changes.rs b/core/state-machine/src/overlayed_changes.rs index 9efafab20f..1dbf2a4352 100644 --- a/core/state-machine/src/overlayed_changes.rs +++ b/core/state-machine/src/overlayed_changes.rs @@ -55,7 +55,7 @@ pub struct OverlayedChangeSet { /// Top level storage changes. pub top: HashMap, OverlayedValue>, /// Child storage changes. - pub children: HashMap, (Option>, HashMap, Option>>)>, + pub children: HashMap, HashMap, OverlayedValue>>, } #[cfg(test)] @@ -117,14 +117,14 @@ impl OverlayedChanges { /// value has been set. pub fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Option> { if let Some(map) = self.prospective.children.get(storage_key) { - if let Some(val) = map.1.get(key) { - return Some(val.as_ref().map(AsRef::as_ref)); + if let Some(val) = map.get(key) { + return Some(val.value.as_ref().map(AsRef::as_ref)); } } if let Some(map) = self.committed.children.get(storage_key) { - if let Some(val) = map.1.get(key) { - return Some(val.as_ref().map(AsRef::as_ref)); + if let Some(val) = map.get(key) { + return Some(val.value.as_ref().map(AsRef::as_ref)); } } @@ -151,10 +151,11 @@ impl OverlayedChanges { pub(crate) fn set_child_storage(&mut self, storage_key: Vec, key: Vec, val: Option>) { let extrinsic_index = self.extrinsic_index(); let map_entry = self.prospective.children.entry(storage_key).or_default(); - map_entry.1.insert(key, val); + let entry = map_entry.entry(key).or_default(); + entry.value = val; if let Some(extrinsic) = extrinsic_index { - map_entry.0.get_or_insert_with(Default::default) + entry.extrinsics.get_or_insert_with(Default::default) .insert(extrinsic); } } @@ -169,16 +170,28 @@ impl OverlayedChanges { let extrinsic_index = self.extrinsic_index(); let map_entry = self.prospective.children.entry(storage_key.to_vec()).or_default(); - if let Some(extrinsic) = extrinsic_index { - map_entry.0.get_or_insert_with(Default::default) - .insert(extrinsic); - } + map_entry.values_mut().for_each(|e| { + if let Some(extrinsic) = extrinsic_index { + e.extrinsics.get_or_insert_with(Default::default) + .insert(extrinsic); + } - map_entry.1.values_mut().for_each(|e| *e = None); + e.value = None; + }); - if let Some((_, committed_map)) = self.committed.children.get(storage_key) { - for (key, _) in committed_map.iter() { - map_entry.1.insert(key.clone(), None); + if let Some(committed_map) = self.committed.children.get(storage_key) { + for (key, value) in committed_map.iter() { + if !map_entry.contains_key(key) { + map_entry.insert(key.clone(), OverlayedValue { + value: None, + extrinsics: extrinsic_index.map(|i| { + let mut e = value.extrinsics.clone() + .unwrap_or_else(|| BTreeSet::default()); + e.insert(i); + e + }), + }); + } } } } @@ -224,12 +237,12 @@ impl OverlayedChanges { let extrinsic_index = self.extrinsic_index(); let map_entry = self.prospective.children.entry(storage_key.to_vec()).or_default(); - for (key, entry) in map_entry.1.iter_mut() { + for (key, entry) in map_entry.iter_mut() { if key.starts_with(prefix) { - *entry = None; + entry.value = None; if let Some(extrinsic) = extrinsic_index { - map_entry.0.get_or_insert_with(Default::default) + entry.extrinsics.get_or_insert_with(Default::default) .insert(extrinsic); } } @@ -238,13 +251,13 @@ impl OverlayedChanges { if let Some(child_committed) = self.committed.children.get(storage_key) { // Then do the same with keys from commited changes. // NOTE that we are making changes in the prospective change set. - for key in child_committed.1.keys() { + for key in child_committed.keys() { if key.starts_with(prefix) { - let entry = map_entry.1.entry(key.clone()).or_default(); - *entry = None; + let entry = map_entry.entry(key.clone()).or_default(); + entry.value = None; if let Some(extrinsic) = extrinsic_index { - map_entry.0.get_or_insert_with(Default::default) + entry.extrinsics.get_or_insert_with(Default::default) .insert(extrinsic); } } @@ -271,13 +284,16 @@ impl OverlayedChanges { .extend(prospective_extrinsics); } } - for (storage_key, map) in self.prospective.children.drain() { - let entry = self.committed.children.entry(storage_key).or_default(); - entry.1.extend(map.1.iter().map(|(k, v)| (k.clone(), v.clone()))); - - if let Some(prospective_extrinsics) = map.0 { - entry.0.get_or_insert_with(Default::default) - .extend(prospective_extrinsics); + for (storage_key, mut map) in self.prospective.children.drain() { + let map_dest = self.committed.children.entry(storage_key).or_default(); + for (key, val) in map.drain() { + let entry = map_dest.entry(key).or_default(); + entry.value = val.value; + + if let Some(prospective_extrinsics) = val.extrinsics { + entry.extrinsics.get_or_insert_with(Default::default) + .extend(prospective_extrinsics); + } } } } @@ -293,7 +309,8 @@ impl OverlayedChanges { ){ assert!(self.prospective.is_empty()); (self.committed.top.into_iter().map(|(k, v)| (k, v.value)), - self.committed.children.into_iter().map(|(sk, v)| (sk, v.1.into_iter()))) + self.committed.children.into_iter() + .map(|(sk, v)| (sk, v.into_iter().map(|(k, v)| (k, v.value))))) } /// Inserts storage entry responsible for current extrinsic index. diff --git a/core/state-machine/src/proving_backend.rs b/core/state-machine/src/proving_backend.rs index 5e8f618c82..2b44aae778 100644 --- a/core/state-machine/src/proving_backend.rs +++ b/core/state-machine/src/proving_backend.rs @@ -174,6 +174,10 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> self.backend.for_keys_with_prefix(prefix, f) } + fn for_key_values_with_prefix(&self, prefix: &[u8], f: F) { + self.backend.for_key_values_with_prefix(prefix, f) + } + fn for_child_keys_with_prefix(&self, storage_key: &[u8], prefix: &[u8], f: F) { self.backend.for_child_keys_with_prefix(storage_key, prefix, f) } diff --git a/core/state-machine/src/testing.rs b/core/state-machine/src/testing.rs index 00a0208a1f..1065541e63 100644 --- a/core/state-machine/src/testing.rs +++ b/core/state-machine/src/testing.rs @@ -108,8 +108,8 @@ impl TestExternalities { let children = self.overlay.committed.children.clone().into_iter() .chain(self.overlay.prospective.children.clone().into_iter()) .flat_map(|(keyspace, map)| { - map.1.into_iter() - .map(|(k, v)| (Some(keyspace.clone()), k, v)) + map.into_iter() + .map(|(k, v)| (Some(keyspace.clone()), k, v.value)) .collect::>() }); @@ -236,10 +236,10 @@ impl Externalities for TestExternalities let child_delta_iter = child_storage_keys.map(|storage_key| (storage_key.clone(), self.overlay.committed.children.get(storage_key) .into_iter() - .flat_map(|map| map.1.iter().map(|(k, v)| (k.clone(), v.clone()))) + .flat_map(|map| map.iter().map(|(k, v)| (k.clone(), v.value.clone()))) .chain(self.overlay.prospective.children.get(storage_key) .into_iter() - .flat_map(|map| map.1.iter().map(|(k, v)| (k.clone(), v.clone())))))); + .flat_map(|map| map.iter().map(|(k, v)| (k.clone(), v.value.clone())))))); // compute and memoize @@ -255,10 +255,10 @@ impl Externalities for TestExternalities let (root, is_empty, _) = { let delta = self.overlay.committed.children.get(storage_key) .into_iter() - .flat_map(|map| map.1.iter().map(|(k, v)| (k.clone(), v.clone()))) + .flat_map(|map| map.clone().into_iter().map(|(k, v)| (k, v.value))) .chain(self.overlay.prospective.children.get(storage_key) .into_iter() - .flat_map(|map| map.1.clone().into_iter())); + .flat_map(|map| map.clone().into_iter().map(|(k, v)| (k, v.value)))); self.backend.child_storage_root(storage_key, delta) }; diff --git a/core/state-machine/src/trie_backend.rs b/core/state-machine/src/trie_backend.rs index 53c293b7ad..01e36a5810 100644 --- a/core/state-machine/src/trie_backend.rs +++ b/core/state-machine/src/trie_backend.rs @@ -78,6 +78,10 @@ impl, H: Hasher> Backend for TrieBackend where self.essence.for_keys_with_prefix(prefix, f) } + fn for_key_values_with_prefix(&self, prefix: &[u8], f: F) { + self.essence.for_key_values_with_prefix(prefix, f) + } + fn for_keys_in_child_storage(&self, storage_key: &[u8], f: F) { self.essence.for_keys_in_child_storage(storage_key, f) } diff --git a/core/state-machine/src/trie_backend_essence.rs b/core/state-machine/src/trie_backend_essence.rs index aeb265c2e2..5a54319634 100644 --- a/core/state-machine/src/trie_backend_essence.rs +++ b/core/state-machine/src/trie_backend_essence.rs @@ -119,7 +119,7 @@ impl, H: Hasher> TrieBackendEssence { } /// Execute given closure for all keys starting with prefix. - pub fn for_child_keys_with_prefix(&self, storage_key: &[u8], prefix: &[u8], f: F) { + pub fn for_child_keys_with_prefix(&self, storage_key: &[u8], prefix: &[u8], mut f: F) { let root_vec = match self.storage(storage_key) { Ok(v) => v.unwrap_or(default_child_trie_root::>(storage_key)), Err(e) => { @@ -130,16 +130,21 @@ impl, H: Hasher> TrieBackendEssence { let mut root = H::Out::default(); root.as_mut().copy_from_slice(&root_vec); - self.keys_with_prefix_inner(&root, prefix, f) + self.keys_values_with_prefix_inner(&root, prefix, |k, _v| f(k)) } /// Execute given closure for all keys starting with prefix. - pub fn for_keys_with_prefix(&self, prefix: &[u8], f: F) { - self.keys_with_prefix_inner(&self.root, prefix, f) + pub fn for_keys_with_prefix(&self, prefix: &[u8], mut f: F) { + self.keys_values_with_prefix_inner(&self.root, prefix, |k, _v| f(k)) } - fn keys_with_prefix_inner(&self, root: &H::Out, prefix: &[u8], mut f: F) { + fn keys_values_with_prefix_inner( + &self, + root: &H::Out, + prefix: &[u8], + mut f: F, + ) { let mut read_overlay = S::Overlay::default(); let eph = Ephemeral { storage: &self.storage, @@ -153,13 +158,13 @@ impl, H: Hasher> TrieBackendEssence { iter.seek(prefix)?; for x in iter { - let (key, _) = x?; + let (key, value) = x?; if !key.starts_with(prefix) { break; } - f(&key); + f(&key, &value); } Ok(()) @@ -170,6 +175,11 @@ impl, H: Hasher> TrieBackendEssence { } } + /// Execute given closure for all key and values starting with prefix. + pub fn for_key_values_with_prefix(&self, prefix: &[u8], f: F) { + self.keys_values_with_prefix_inner(&self.root, prefix, f) + } + } pub(crate) struct Ephemeral<'a, S: 'a + TrieBackendStorage, H: 'a + Hasher> { -- GitLab From 6f4d992b2a381908f8bc159b6b8e1e88c042ec4c Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Mon, 2 Sep 2019 13:21:01 +0200 Subject: [PATCH 049/275] Drive by docs fix re minimum_balance (#3528) --- node/runtime/src/lib.rs | 2 +- srml/staking/src/lib.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 5dc8d02ecc..03d11111f1 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -81,7 +81,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 154, - impl_version: 158, + impl_version: 159, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index 8b268a8272..c648cbf879 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -680,7 +680,7 @@ decl_module! { /// Take the origin account as a stash and lock up `value` of its balance. `controller` will /// be the account that controls it. /// - /// `value` must be more than the `existential_deposit` defined in the Balances module. + /// `value` must be more than the `minimum_balance` specified by `T::Currency`. /// /// The dispatch origin for this call must be _Signed_ by the stash account. /// @@ -759,7 +759,7 @@ decl_module! { /// Schedule a portion of the stash to be unlocked ready for transfer out after the bond /// period ends. If this leaves an amount actively bonded less than - /// T::Currency::existential_deposit(), then it is increased to the full amount. + /// T::Currency::minimum_balance(), then it is increased to the full amount. /// /// Once the unlock period is done, you can call `withdraw_unbonded` to actually move /// the funds out of management ready for transfer. -- GitLab From cff2be88d974a4de0e375d783e0e78aa790f0173 Mon Sep 17 00:00:00 2001 From: Caio Date: Mon, 2 Sep 2019 11:25:44 -0300 Subject: [PATCH 050/275] Typo (#3531) --- core/consensus/slots/src/lib.rs | 2 +- core/transaction-pool/graph/src/pool.rs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/core/consensus/slots/src/lib.rs b/core/consensus/slots/src/lib.rs index 2513071a9f..fd5163a374 100644 --- a/core/consensus/slots/src/lib.rs +++ b/core/consensus/slots/src/lib.rs @@ -52,7 +52,7 @@ pub trait SlotWorker { fn on_slot(&mut self, chain_head: B::Header, slot_info: SlotInfo) -> Self::OnSlot; } -/// A skeleton implementation for `SlotWorker` which tries to claim a slot at at +/// A skeleton implementation for `SlotWorker` which tries to claim a slot at /// its beginning and tries to produce a block if successfully claimed, timing /// out if block production takes too long. pub trait SimpleSlotWorker { diff --git a/core/transaction-pool/graph/src/pool.rs b/core/transaction-pool/graph/src/pool.rs index 07542afab0..fa09132d29 100644 --- a/core/transaction-pool/graph/src/pool.rs +++ b/core/transaction-pool/graph/src/pool.rs @@ -134,8 +134,7 @@ impl Pool { } else { Ok(base::Transaction { data: xt, - bytes - , + bytes, hash, priority: validity.priority, requires: validity.requires, -- GitLab From a91ba8424c31a368c0108309bd6c6c7696fde38c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 2 Sep 2019 16:45:51 +0200 Subject: [PATCH 051/275] Run `sr-api-macros` ui tests only with a stable compiler (#3529) --- Cargo.lock | 47 ++++++++++++++++++++++++++++ core/sr-api-macros/Cargo.toml | 1 + core/sr-api-macros/tests/trybuild.rs | 1 + 3 files changed, 49 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index b714f89359..825ac0f9b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2997,6 +2997,14 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "proc-macro2" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "protobuf" version = "2.8.0" @@ -3041,6 +3049,14 @@ dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "quote" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand" version = "0.3.23" @@ -3366,6 +3382,16 @@ dependencies = [ "webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rustversion" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rw-stream-sink" version = "0.1.2" @@ -3696,6 +3722,7 @@ dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustversion 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-version 2.0.0", "substrate-client 2.0.0", @@ -5337,6 +5364,16 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "syn" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "synstructure" version = "0.10.2" @@ -5849,6 +5886,11 @@ name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unsigned-varint" version = "0.2.2" @@ -6548,12 +6590,14 @@ dependencies = [ "checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" "checksum proc-macro-hack 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "982a35d1194084ba319d65c4a68d24ca28f5fdb5b8bc20899e4eef8641ea5178" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +"checksum proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "175a40b9cf564ce9bf050654633dbf339978706b8ead1a907bb970b63185dd95" "checksum protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8aefcec9f142b524d98fc81d07827743be89dd6586a1ba6ab21fa66a500b3fa5" "checksum pwasm-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "efb0dcbddbb600f47a7098d33762a00552c671992171637f5bb310b37fe1f0e4" "checksum quick-error 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb6ccf8db7bbcb9c2eae558db5ab4f3da1c2a87e4e597ed394726bc8ea6ca1d" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quickcheck 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9c35d9c36a562f37eca96e79f66d5fd56eefbc22560dacc4a864cabd2d277456" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" "checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" "checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" @@ -6589,6 +6633,7 @@ dependencies = [ "checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum rustls 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f271e3552cd835fa28c541c34a7e8fdd8cdff09d77fe4eb8f6c42e87a11b096e" +"checksum rustversion 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b48139cfc215c6cc70d43c6c555a59e723c3b5adb26a4cfa09f815a5ae5871e8" "checksum rw-stream-sink 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9cbe61c20455d3015b2bb7be39e1872310283b8e5a52f5b242b0ac7581fe78" "checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" "checksum safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347" @@ -6640,6 +6685,7 @@ dependencies = [ "checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" "checksum subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "01dca13cf6c3b179864ab3292bd794e757618d35a7766b7c46050c614ba00829" "checksum syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)" = "eadc09306ca51a40555dd6fc2b415538e9e18bc9f870e47b1a524a79fe2dcf5e" +"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf" "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" "checksum sysinfo 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c3e2cab189e59f72710e3dd5e1e0d5be0f6c5c999c326f2fdcdf3bf4483ec9fd" "checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" @@ -6691,6 +6737,7 @@ dependencies = [ "checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2c64cdf40b4a9645534a943668681bcb219faf51874d4b65d2e0abda1b10a2ab" "checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" diff --git a/core/sr-api-macros/Cargo.toml b/core/sr-api-macros/Cargo.toml index 3301b2fdc7..c025ad800e 100644 --- a/core/sr-api-macros/Cargo.toml +++ b/core/sr-api-macros/Cargo.toml @@ -25,6 +25,7 @@ criterion = "0.2" consensus_common = { package = "substrate-consensus-common", path = "../consensus/common" } codec = { package = "parity-scale-codec", version = "1.0.0" } trybuild = "1.0" +rustversion = "0.1" [[bench]] name = "bench" diff --git a/core/sr-api-macros/tests/trybuild.rs b/core/sr-api-macros/tests/trybuild.rs index 302dd7c087..9baea83196 100644 --- a/core/sr-api-macros/tests/trybuild.rs +++ b/core/sr-api-macros/tests/trybuild.rs @@ -1,5 +1,6 @@ use std::env; +#[rustversion::attr(not(stable), ignore)] #[test] fn ui() { // As trybuild is using `cargo check`, we don't need the real WASM binaries. -- GitLab From d2e7d660f8dbbb8f9753dfd231cef1c9b502c41c Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Mon, 2 Sep 2019 16:46:57 +0200 Subject: [PATCH 052/275] Removed superflous safety check (#3530) --- core/client/src/client.rs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/core/client/src/client.rs b/core/client/src/client.rs index 3363424854..eb07116690 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -917,19 +917,6 @@ impl Client where return Err(error::Error::NotInFinalizedChain); } - // find tree route from last finalized to given block. - let route_from_finalized = crate::blockchain::tree_route( - |id| self.header(&id)?.ok_or_else(|| Error::UnknownBlock(format!("{:?}", id))), - BlockId::Hash(info.finalized_hash), - BlockId::Hash(parent_hash), - )?; - - // the block being imported retracts the last finalized block, refusing to - // import. - if !route_from_finalized.retracted().is_empty() { - return Err(error::Error::NotInFinalizedChain); - } - // this is a fairly arbitrary choice of where to draw the line on making notifications, // but the general goal is to only make notifications when we are already fully synced // and get a new chain head. -- GitLab From 870b976bec729aaf26cc237df9fd764b8f7b9d7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 3 Sep 2019 15:13:32 +0200 Subject: [PATCH 053/275] Fix `build-only-wasm` script (#3536) --- scripts/build-only-wasm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build-only-wasm.sh b/scripts/build-only-wasm.sh index 51e904edd5..b6da3319c8 100755 --- a/scripts/build-only-wasm.sh +++ b/scripts/build-only-wasm.sh @@ -23,7 +23,7 @@ if [ -d $WASM_BUILDER_RUNNER ]; then export DEBUG=false export OUT_DIR="$PROJECT_ROOT/target/release/build" cargo run --release --manifest-path="$WASM_BUILDER_RUNNER/Cargo.toml" \ - | grep -vE "cargo:rerun-if-|Executing build command" \ + | grep -vE "cargo:rerun-if-|Executing build command" else cargo build --release -p $1 fi -- GitLab From 3278d648772f9f544cbad18b8ad7a784c3986ded Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Wed, 4 Sep 2019 14:44:28 +0200 Subject: [PATCH 054/275] Normalize Crate Names in SRML/Node Template (#3543) * Fix some instances of `runtime-io` * Patch a bunch * More patches for consistancy * more patch * Fix various build issues * Fix tests * Patch `srml-support-*` crates * Fix doc tests * Revert "Fix doc tests" This reverts commit ba2ec61da7acc36821a70e76a31a6a5bf13bbe95. * Revert "Patch `srml-support-*` crates" This reverts commit 9a6070450107dec17784ba34af4b871023f6dc81. * Missed one * Fix doc tests --- Cargo.lock | 1 - core/application-crypto/Cargo.toml | 4 ++-- core/application-crypto/src/ed25519.rs | 8 ++++---- core/application-crypto/src/sr25519.rs | 8 ++++---- srml/assets/Cargo.toml | 6 +++--- srml/assets/src/lib.rs | 4 ++-- srml/aura/Cargo.toml | 8 ++++---- srml/aura/src/lib.rs | 2 +- srml/aura/src/mock.rs | 2 +- srml/authority-discovery/Cargo.toml | 8 ++++---- srml/authority-discovery/src/lib.rs | 6 +++--- srml/authorship/Cargo.toml | 8 ++++---- srml/authorship/src/lib.rs | 8 ++++---- srml/babe/Cargo.toml | 8 ++++---- srml/babe/src/lib.rs | 2 +- srml/balances/Cargo.toml | 6 +++--- srml/balances/src/lib.rs | 12 +++++------ srml/balances/src/mock.rs | 4 ++-- srml/balances/src/tests.rs | 2 +- srml/collective/Cargo.toml | 8 ++++---- srml/collective/src/lib.rs | 6 +++--- srml/contracts/Cargo.toml | 4 ++-- srml/contracts/src/account_db.rs | 4 ++-- srml/contracts/src/exec.rs | 2 +- srml/contracts/src/gas.rs | 4 ++-- srml/contracts/src/lib.rs | 6 +++--- srml/contracts/src/rent.rs | 4 ++-- srml/contracts/src/tests.rs | 4 ++-- srml/contracts/src/wasm/code_cache.rs | 2 +- srml/council/src/lib.rs | 4 ++-- srml/democracy/Cargo.toml | 8 ++++---- srml/democracy/src/lib.rs | 6 +++--- srml/elections/Cargo.toml | 8 ++++---- srml/elections/src/lib.rs | 6 +++--- srml/example/Cargo.toml | 8 ++++---- srml/example/src/lib.rs | 10 +++++----- srml/executive/Cargo.toml | 8 ++++---- srml/executive/src/lib.rs | 6 +++--- srml/finality-tracker/Cargo.toml | 6 +++--- srml/finality-tracker/src/lib.rs | 10 +++++----- srml/generic-asset/Cargo.toml | 2 +- srml/grandpa/Cargo.toml | 7 +++---- srml/grandpa/src/lib.rs | 2 +- srml/grandpa/src/mock.rs | 2 +- srml/im-online/Cargo.toml | 8 ++++---- srml/im-online/src/lib.rs | 20 +++++++++---------- srml/indices/Cargo.toml | 4 ++-- srml/indices/src/lib.rs | 2 +- srml/indices/src/mock.rs | 2 +- srml/membership/Cargo.toml | 8 ++++---- srml/membership/src/lib.rs | 8 ++++---- srml/offences/Cargo.toml | 2 +- srml/scored-pool/Cargo.toml | 8 ++++---- srml/scored-pool/src/lib.rs | 4 ++-- srml/scored-pool/src/mock.rs | 4 ++-- srml/scored-pool/src/tests.rs | 4 ++-- srml/session/Cargo.toml | 6 +++--- srml/session/src/historical.rs | 8 ++++---- srml/session/src/lib.rs | 6 +++--- srml/session/src/mock.rs | 2 +- srml/staking/Cargo.toml | 8 ++++---- srml/staking/src/lib.rs | 4 ++-- srml/staking/src/mock.rs | 6 +++--- srml/staking/src/tests.rs | 4 ++-- srml/sudo/Cargo.toml | 10 ++++------ srml/sudo/src/lib.rs | 6 +++--- srml/support/Cargo.toml | 6 +++--- srml/support/procedural/Cargo.toml | 2 +- srml/support/procedural/tools/Cargo.toml | 2 +- srml/support/test/Cargo.toml | 8 ++++---- srml/support/test/src/lib.rs | 2 +- srml/support/test/tests/final_keys.rs | 8 ++++---- srml/support/test/tests/genesisconfig.rs | 4 ++-- srml/support/test/tests/instance.rs | 18 ++++++++--------- srml/support/test/tests/issue2219.rs | 12 +++++------ .../tests/reserved_keyword/on_initialize.rs | 6 +++--- srml/support/test/tests/system.rs | 6 +++--- srml/system/Cargo.toml | 8 ++++---- srml/system/benches/bench.rs | 4 ++-- srml/system/src/lib.rs | 6 +++--- srml/timestamp/Cargo.toml | 6 +++--- srml/timestamp/src/lib.rs | 8 ++++---- srml/treasury/Cargo.toml | 6 +++--- srml/treasury/src/lib.rs | 6 +++--- 84 files changed, 246 insertions(+), 250 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 825ac0f9b2..9a6afd5c11 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4210,7 +4210,6 @@ dependencies = [ "sr-primitives 2.0.0", "sr-std 2.0.0", "srml-support 2.0.0", - "srml-support-procedural 2.0.0", "srml-system 2.0.0", "substrate-primitives 2.0.0", ] diff --git a/core/application-crypto/Cargo.toml b/core/application-crypto/Cargo.toml index 6d39b12653..4e4f896f29 100644 --- a/core/application-crypto/Cargo.toml +++ b/core/application-crypto/Cargo.toml @@ -10,7 +10,7 @@ primitives = { package = "substrate-primitives", path = "../primitives", default codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } serde = { version = "1.0", optional = true, features = ["derive"] } rstd = { package = "sr-std", path = "../sr-std", default-features = false } -rio = { package = "sr-io", path = "../sr-io", default-features = false } +runtime-io = { package = "sr-io", path = "../sr-io", default-features = false } [dev-dependencies] test-client = { package = "substrate-test-runtime-client", path = "../test-runtime/client" } @@ -18,4 +18,4 @@ sr-primitives = { path = "../sr-primitives" } [features] default = [ "std" ] -std = [ "primitives/std", "codec/std", "serde", "rstd/std", "rio/std" ] +std = [ "primitives/std", "codec/std", "serde", "rstd/std", "runtime-io/std" ] diff --git a/core/application-crypto/src/ed25519.rs b/core/application-crypto/src/ed25519.rs index 6c5458492b..209743bd28 100644 --- a/core/application-crypto/src/ed25519.rs +++ b/core/application-crypto/src/ed25519.rs @@ -34,19 +34,19 @@ impl RuntimePublic for Public { type Signature = Signature; fn all(key_type: KeyTypeId) -> crate::Vec { - rio::ed25519_public_keys(key_type) + runtime_io::ed25519_public_keys(key_type) } fn generate_pair(key_type: KeyTypeId, seed: Option<&str>) -> Self { - rio::ed25519_generate(key_type, seed) + runtime_io::ed25519_generate(key_type, seed) } fn sign>(&self, key_type: KeyTypeId, msg: &M) -> Option { - rio::ed25519_sign(key_type, self, msg) + runtime_io::ed25519_sign(key_type, self, msg) } fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool { - rio::ed25519_verify(&signature, msg.as_ref(), self) + runtime_io::ed25519_verify(&signature, msg.as_ref(), self) } } diff --git a/core/application-crypto/src/sr25519.rs b/core/application-crypto/src/sr25519.rs index af112dc70e..e333208966 100644 --- a/core/application-crypto/src/sr25519.rs +++ b/core/application-crypto/src/sr25519.rs @@ -34,19 +34,19 @@ impl RuntimePublic for Public { type Signature = Signature; fn all(key_type: KeyTypeId) -> crate::Vec { - rio::sr25519_public_keys(key_type) + runtime_io::sr25519_public_keys(key_type) } fn generate_pair(key_type: KeyTypeId, seed: Option<&str>) -> Self { - rio::sr25519_generate(key_type, seed) + runtime_io::sr25519_generate(key_type, seed) } fn sign>(&self, key_type: KeyTypeId, msg: &M) -> Option { - rio::sr25519_sign(key_type, self, msg) + runtime_io::sr25519_sign(key_type, self, msg) } fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool { - rio::sr25519_verify(&signature, msg.as_ref(), self) + runtime_io::sr25519_verify(&signature, msg.as_ref(), self) } } diff --git a/srml/assets/Cargo.toml b/srml/assets/Cargo.toml index d5924cfdda..ea5973254e 100644 --- a/srml/assets/Cargo.toml +++ b/srml/assets/Cargo.toml @@ -10,14 +10,14 @@ codec = { package = "parity-scale-codec", version = "1.0.0", default-features = # Needed for various traits. In our case, `OnFinalize`. sr-primitives = { path = "../../core/sr-primitives", default-features = false } # Needed for type-safe access to storage DB. -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } # `system` module provides us with all sorts of useful stuff and macros depend on it being around. system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] primitives = { package = "substrate-primitives", path = "../../core/primitives" } rstd = { package = "sr-std", path = "../../core/sr-std" } -runtime_io = { package = "sr-io", path = "../../core/sr-io" } +runtime-io = { package = "sr-io", path = "../../core/sr-io" } [features] default = ["std"] @@ -25,6 +25,6 @@ std = [ "serde", "codec/std", "sr-primitives/std", - "srml-support/std", + "support/std", "system/std", ] diff --git a/srml/assets/src/lib.rs b/srml/assets/src/lib.rs index a8268d1463..33bf32503f 100644 --- a/srml/assets/src/lib.rs +++ b/srml/assets/src/lib.rs @@ -130,7 +130,7 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -use srml_support::{StorageValue, StorageMap, Parameter, decl_module, decl_event, decl_storage, ensure}; +use support::{StorageValue, StorageMap, Parameter, decl_module, decl_event, decl_storage, ensure}; use sr_primitives::traits::{Member, SimpleArithmetic, Zero, StaticLookup}; use system::ensure_signed; use sr_primitives::traits::One; @@ -240,7 +240,7 @@ mod tests { use super::*; use runtime_io::with_externalities; - use srml_support::{impl_outer_origin, assert_ok, assert_noop, parameter_types}; + use support::{impl_outer_origin, assert_ok, assert_noop, parameter_types}; use primitives::{H256, Blake2Hasher}; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. diff --git a/srml/aura/Cargo.toml b/srml/aura/Cargo.toml index 06a5a94635..961c178c34 100644 --- a/srml/aura/Cargo.toml +++ b/srml/aura/Cargo.toml @@ -13,8 +13,8 @@ rstd = { package = "sr-std", path = "../../core/sr-std", default-features = fals serde = { version = "1.0", optional = true } session = { package = "srml-session", path = "../session", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false, features = [ "wasm-nice-panic-message" ] } -srml-support = { path = "../support", default-features = false } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false, features = [ "wasm-nice-panic-message" ] } +support = { package = "srml-support", path = "../support", default-features = false } substrate-consensus-aura-primitives = { path = "../../core/consensus/aura/primitives", default-features = false} system = { package = "srml-system", path = "../system", default-features = false } timestamp = { package = "srml-timestamp", path = "../timestamp", default-features = false } @@ -29,12 +29,12 @@ std = [ "app-crypto/std", "codec/std", "inherents/std", - "runtime_io/std", + "runtime-io/std", "primitives/std", "rstd/std", "serde", "sr-primitives/std", - "srml-support/std", + "support/std", "substrate-consensus-aura-primitives/std", "system/std", "timestamp/std", diff --git a/srml/aura/src/lib.rs b/srml/aura/src/lib.rs index f3ce6a9e09..f2b6818a45 100644 --- a/srml/aura/src/lib.rs +++ b/srml/aura/src/lib.rs @@ -49,7 +49,7 @@ pub use timestamp; use rstd::{result, prelude::*}; use codec::{Encode, Decode}; -use srml_support::{ +use support::{ decl_storage, decl_module, Parameter, storage::StorageValue, traits::{Get, FindAuthor}, ConsensusEngineId, }; diff --git a/srml/aura/src/mock.rs b/srml/aura/src/mock.rs index 5861b11e07..6dc8953e88 100644 --- a/srml/aura/src/mock.rs +++ b/srml/aura/src/mock.rs @@ -24,7 +24,7 @@ use sr_primitives::{ traits::IdentityLookup, Perbill, testing::{Header, UintAuthorityId}, }; -use srml_support::{impl_outer_origin, parameter_types}; +use support::{impl_outer_origin, parameter_types}; use runtime_io; use primitives::{H256, Blake2Hasher}; diff --git a/srml/authority-discovery/Cargo.toml b/srml/authority-discovery/Cargo.toml index f4c2d4e2b0..0657348457 100644 --- a/srml/authority-discovery/Cargo.toml +++ b/srml/authority-discovery/Cargo.toml @@ -13,8 +13,8 @@ rstd = { package = "sr-std", path = "../../core/sr-std", default-features = fals serde = { version = "1.0", optional = true } session = { package = "srml-session", path = "../session", default-features = false } im-online = { package = "srml-im-online", path = "../im-online", default-features = false } -srml-support = { path = "../support", default-features = false } -sr-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] @@ -30,8 +30,8 @@ std = [ "serde", "session/std", "im-online/std", - "srml-support/std", - "sr-io/std", + "support/std", + "runtime-io/std", "system/std", "app-crypto/std", ] diff --git a/srml/authority-discovery/src/lib.rs b/srml/authority-discovery/src/lib.rs index d52b225d2c..76b0c93c4f 100644 --- a/srml/authority-discovery/src/lib.rs +++ b/srml/authority-discovery/src/lib.rs @@ -31,7 +31,7 @@ use app_crypto::RuntimeAppPublic; use codec::{Decode, Encode}; use rstd::prelude::*; -use srml_support::{decl_module, decl_storage, StorageValue}; +use support::{decl_module, decl_storage, StorageValue}; pub trait Trait: system::Trait + session::Trait + im_online::Trait {} @@ -132,13 +132,13 @@ mod tests { use app_crypto::Pair; use primitives::testing::KeyStore; use primitives::{crypto::key_types, sr25519, traits::BareCryptoStore, H256}; - use sr_io::{with_externalities, TestExternalities}; + use runtime_io::{with_externalities, TestExternalities}; use sr_primitives::generic::UncheckedExtrinsic; use sr_primitives::testing::{Header, UintAuthorityId}; use sr_primitives::traits::{ConvertInto, IdentityLookup, OpaqueKeys}; use sr_primitives::Perbill; use sr_staking_primitives::CurrentElectedSet; - use srml_support::{impl_outer_origin, parameter_types}; + use support::{impl_outer_origin, parameter_types}; type AuthorityDiscovery = Module; type SessionIndex = u32; diff --git a/srml/authorship/Cargo.toml b/srml/authorship/Cargo.toml index e7f7b0941b..db3cb133f4 100644 --- a/srml/authorship/Cargo.toml +++ b/srml/authorship/Cargo.toml @@ -11,9 +11,9 @@ codec = { package = "parity-scale-codec", version = "1.0.0", default-features = inherents = { package = "substrate-inherents", path = "../../core/inherents", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } [features] default = ["std"] @@ -23,7 +23,7 @@ std = [ "inherents/std", "sr-primitives/std", "rstd/std", - "srml-support/std", + "support/std", "system/std", - "runtime_io/std", + "runtime-io/std", ] diff --git a/srml/authorship/src/lib.rs b/srml/authorship/src/lib.rs index c71c26df02..e7055dddb8 100644 --- a/srml/authorship/src/lib.rs +++ b/srml/authorship/src/lib.rs @@ -22,9 +22,9 @@ use rstd::{result, prelude::*}; use rstd::collections::btree_set::BTreeSet; -use srml_support::{decl_module, decl_storage, for_each_tuple, StorageValue}; -use srml_support::traits::{FindAuthor, VerifySeal, Get}; -use srml_support::dispatch::Result as DispatchResult; +use support::{decl_module, decl_storage, for_each_tuple, StorageValue}; +use support::traits::{FindAuthor, VerifySeal, Get}; +use support::dispatch::Result as DispatchResult; use codec::{Encode, Decode}; use system::ensure_none; use sr_primitives::traits::{Header as HeaderT, One, Zero}; @@ -441,7 +441,7 @@ mod tests { use sr_primitives::testing::Header; use sr_primitives::generic::DigestItem; use sr_primitives::Perbill; - use srml_support::{parameter_types, impl_outer_origin, ConsensusEngineId}; + use support::{parameter_types, impl_outer_origin, ConsensusEngineId}; impl_outer_origin!{ pub enum Origin for Test {} diff --git a/srml/babe/Cargo.toml b/srml/babe/Cargo.toml index 039ccea3df..35828fdb1c 100644 --- a/srml/babe/Cargo.toml +++ b/srml/babe/Cargo.toml @@ -12,12 +12,12 @@ inherents = { package = "substrate-inherents", path = "../../core/inherents", de rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } sr-staking-primitives = { path = "../../core/sr-staking-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } timestamp = { package = "srml-timestamp", path = "../timestamp", default-features = false } session = { package = "srml-session", path = "../session", default-features = false } babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../core/consensus/babe/primitives", default-features = false } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false, features = [ "wasm-nice-panic-message" ] } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false, features = [ "wasm-nice-panic-message" ] } [dev-dependencies] lazy_static = "1.3.0" @@ -30,7 +30,7 @@ std = [ "serde", "codec/std", "rstd/std", - "srml-support/std", + "support/std", "sr-primitives/std", "sr-staking-primitives/std", "system/std", @@ -38,5 +38,5 @@ std = [ "inherents/std", "babe-primitives/std", "session/std", - "runtime_io/std", + "runtime-io/std", ] diff --git a/srml/babe/src/lib.rs b/srml/babe/src/lib.rs index e21f083eb6..17c405dc25 100644 --- a/srml/babe/src/lib.rs +++ b/srml/babe/src/lib.rs @@ -26,7 +26,7 @@ pub use timestamp; use rstd::{result, prelude::*}; -use srml_support::{decl_storage, decl_module, StorageValue, StorageMap, traits::FindAuthor, traits::Get}; +use support::{decl_storage, decl_module, StorageValue, StorageMap, traits::FindAuthor, traits::Get}; use timestamp::{OnTimestampSet}; use sr_primitives::{generic::DigestItem, ConsensusEngineId, Perbill}; use sr_primitives::traits::{IsMember, SaturatedConversion, Saturating, RandomnessBeacon}; diff --git a/srml/balances/Cargo.toml b/srml/balances/Cargo.toml index d3ac0c96b3..ca885de678 100644 --- a/srml/balances/Cargo.toml +++ b/srml/balances/Cargo.toml @@ -11,11 +11,11 @@ codec = { package = "parity-scale-codec", version = "1.0.0", default-features = substrate-keyring = { path = "../../core/keyring", optional = true } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } primitives = { package = "substrate-primitives", path = "../../core/primitives" } [features] @@ -26,7 +26,7 @@ std = [ "substrate-keyring", "codec/std", "rstd/std", - "srml-support/std", + "support/std", "sr-primitives/std", "system/std", ] diff --git a/srml/balances/src/lib.rs b/srml/balances/src/lib.rs index 289dfbf93f..80caa59f21 100644 --- a/srml/balances/src/lib.rs +++ b/srml/balances/src/lib.rs @@ -106,7 +106,7 @@ //! The Contract module uses the `Currency` trait to handle gas payment, and its types inherit from `Currency`: //! //! ``` -//! use srml_support::traits::Currency; +//! use support::traits::Currency; //! # pub trait Trait: system::Trait { //! # type Currency: Currency; //! # } @@ -120,14 +120,14 @@ //! The Staking module uses the `LockableCurrency` trait to lock a stash account's funds: //! //! ``` -//! use srml_support::traits::{WithdrawReasons, LockableCurrency}; +//! use support::traits::{WithdrawReasons, LockableCurrency}; //! use sr_primitives::traits::Bounded; //! pub trait Trait: system::Trait { //! type Currency: LockableCurrency; //! } //! # struct StakingLedger { //! # stash: ::AccountId, -//! # total: <::Currency as srml_support::traits::Currency<::AccountId>>::Balance, +//! # total: <::Currency as support::traits::Currency<::AccountId>>::Balance, //! # phantom: std::marker::PhantomData, //! # } //! # const STAKING_ID: [u8; 8] = *b"staking "; @@ -161,13 +161,13 @@ use rstd::prelude::*; use rstd::{cmp, result, mem}; use codec::{Codec, Encode, Decode}; -use srml_support::{StorageValue, StorageMap, Parameter, decl_event, decl_storage, decl_module}; -use srml_support::traits::{ +use support::{StorageValue, StorageMap, Parameter, decl_event, decl_storage, decl_module}; +use support::traits::{ UpdateBalanceOutcome, Currency, OnFreeBalanceZero, OnUnbalanced, WithdrawReason, WithdrawReasons, LockIdentifier, LockableCurrency, ExistenceRequirement, Imbalance, SignedImbalance, ReservableCurrency, Get, }; -use srml_support::dispatch::Result; +use support::dispatch::Result; use sr_primitives::traits::{ Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub, MaybeSerializeDebug, Saturating, Bounded, SignedExtension, SaturatedConversion, DispatchError, Convert, diff --git a/srml/balances/src/mock.rs b/srml/balances/src/mock.rs index a90c5d56b2..12a49fc90d 100644 --- a/srml/balances/src/mock.rs +++ b/srml/balances/src/mock.rs @@ -22,8 +22,8 @@ use sr_primitives::{Perbill, traits::{Convert, IdentityLookup}, testing::Header, weights::{DispatchInfo, Weight}}; use primitives::{H256, Blake2Hasher}; use runtime_io; -use srml_support::{impl_outer_origin, parameter_types}; -use srml_support::traits::Get; +use support::{impl_outer_origin, parameter_types}; +use support::traits::Get; use std::cell::RefCell; use crate::{GenesisConfig, Module, Trait}; diff --git a/srml/balances/src/tests.rs b/srml/balances/src/tests.rs index 1af3ce6ba0..777206910d 100644 --- a/srml/balances/src/tests.rs +++ b/srml/balances/src/tests.rs @@ -21,7 +21,7 @@ use super::*; use mock::{Balances, ExtBuilder, Runtime, System, info_from_weight, CALL}; use runtime_io::with_externalities; -use srml_support::{ +use support::{ assert_noop, assert_ok, assert_err, traits::{LockableCurrency, LockIdentifier, WithdrawReason, WithdrawReasons, Currency, ReservableCurrency} diff --git a/srml/collective/Cargo.toml b/srml/collective/Cargo.toml index 7aaba7c29f..dce2920a12 100644 --- a/srml/collective/Cargo.toml +++ b/srml/collective/Cargo.toml @@ -10,9 +10,9 @@ safe-mix = { version = "1.0", default-features = false} codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] @@ -27,8 +27,8 @@ std = [ "primitives/std", "rstd/std", "serde", - "runtime_io/std", - "srml-support/std", + "runtime-io/std", + "support/std", "sr-primitives/std", "system/std", ] diff --git a/srml/collective/src/lib.rs b/srml/collective/src/lib.rs index 03f5362021..24208f2697 100644 --- a/srml/collective/src/lib.rs +++ b/srml/collective/src/lib.rs @@ -27,7 +27,7 @@ use rstd::{prelude::*, result}; use primitives::u32_trait::Value as U32; use sr_primitives::traits::{Hash, EnsureOrigin}; use sr_primitives::weights::SimpleDispatchInfo; -use srml_support::{ +use support::{ dispatch::{Dispatchable, Parameter}, codec::{Encode, Decode}, traits::{ChangeMembers, InitializeMembers}, StorageValue, StorageMap, decl_module, decl_event, decl_storage, ensure, @@ -379,7 +379,7 @@ impl< #[cfg(test)] mod tests { use super::*; - use srml_support::{Hashable, assert_ok, assert_noop, parameter_types}; + use support::{Hashable, assert_ok, assert_noop, parameter_types}; use system::{EventRecord, Phase}; use hex_literal::hex; use runtime_io::with_externalities; @@ -427,7 +427,7 @@ mod tests { pub type Block = sr_primitives::generic::Block; pub type UncheckedExtrinsic = sr_primitives::generic::UncheckedExtrinsic; - srml_support::construct_runtime!( + support::construct_runtime!( pub enum Test where Block = Block, NodeBlock = Block, diff --git a/srml/contracts/Cargo.toml b/srml/contracts/Cargo.toml index a013571edf..13aa8d32de 100644 --- a/srml/contracts/Cargo.toml +++ b/srml/contracts/Cargo.toml @@ -15,7 +15,7 @@ sr-primitives = { path = "../../core/sr-primitives", default-features = false } runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sandbox = { package = "sr-sandbox", path = "../../core/sr-sandbox", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } timestamp = { package = "srml-timestamp", path = "../timestamp", default-features = false } @@ -39,7 +39,7 @@ std = [ "runtime-io/std", "rstd/std", "sandbox/std", - "srml-support/std", + "support/std", "system/std", "timestamp/std", "parity-wasm/std", diff --git a/srml/contracts/src/account_db.rs b/srml/contracts/src/account_db.rs index 9f8b29e0bd..6ce1dff22b 100644 --- a/srml/contracts/src/account_db.rs +++ b/srml/contracts/src/account_db.rs @@ -26,8 +26,8 @@ use rstd::collections::btree_map::{BTreeMap, Entry}; use rstd::prelude::*; use runtime_io::blake2_256; use sr_primitives::traits::{Bounded, Zero}; -use srml_support::traits::{Currency, Get, Imbalance, SignedImbalance, UpdateBalanceOutcome}; -use srml_support::{storage::child, StorageMap}; +use support::traits::{Currency, Get, Imbalance, SignedImbalance, UpdateBalanceOutcome}; +use support::{storage::child, StorageMap}; use system; // Note: we don't provide Option because we can't create diff --git a/srml/contracts/src/exec.rs b/srml/contracts/src/exec.rs index 586ee3746b..8308a9180c 100644 --- a/srml/contracts/src/exec.rs +++ b/srml/contracts/src/exec.rs @@ -22,7 +22,7 @@ use crate::rent; use rstd::prelude::*; use sr_primitives::traits::{Bounded, CheckedAdd, CheckedSub, Zero}; -use srml_support::traits::{WithdrawReason, Currency}; +use support::traits::{WithdrawReason, Currency}; use timestamp; pub type AccountIdOf = ::AccountId; diff --git a/srml/contracts/src/gas.rs b/srml/contracts/src/gas.rs index a5811e81a0..8e1ffbca0b 100644 --- a/srml/contracts/src/gas.rs +++ b/srml/contracts/src/gas.rs @@ -18,8 +18,8 @@ use crate::{GasSpent, Module, Trait, BalanceOf, NegativeImbalanceOf}; use rstd::convert::TryFrom; use sr_primitives::BLOCK_FULL; use sr_primitives::traits::{CheckedMul, Zero, SaturatedConversion, SimpleArithmetic, UniqueSaturatedInto}; -use srml_support::StorageValue; -use srml_support::traits::{Currency, ExistenceRequirement, Get, Imbalance, OnUnbalanced, WithdrawReason}; +use support::StorageValue; +use support::traits::{Currency, ExistenceRequirement, Get, Imbalance, OnUnbalanced, WithdrawReason}; #[cfg(test)] use std::{any::Any, fmt::Debug}; diff --git a/srml/contracts/src/lib.rs b/srml/contracts/src/lib.rs index 7618551298..37299d4488 100644 --- a/srml/contracts/src/lib.rs +++ b/srml/contracts/src/lib.rs @@ -103,12 +103,12 @@ use runtime_io::blake2_256; use sr_primitives::traits::{ Hash, StaticLookup, Zero, MaybeSerializeDebug, Member }; -use srml_support::dispatch::{Result, Dispatchable}; -use srml_support::{ +use support::dispatch::{Result, Dispatchable}; +use support::{ Parameter, StorageMap, StorageValue, decl_module, decl_event, decl_storage, storage::child, parameter_types, }; -use srml_support::traits::{OnFreeBalanceZero, OnUnbalanced, Currency, Get}; +use support::traits::{OnFreeBalanceZero, OnUnbalanced, Currency, Get}; use system::{ensure_signed, RawOrigin, ensure_root}; use primitives::storage::well_known_keys::CHILD_STORAGE_KEY_PREFIX; use timestamp; diff --git a/srml/contracts/src/rent.rs b/srml/contracts/src/rent.rs index fea6cdc7f3..776f804ee7 100644 --- a/srml/contracts/src/rent.rs +++ b/srml/contracts/src/rent.rs @@ -17,8 +17,8 @@ use crate::{BalanceOf, ContractInfo, ContractInfoOf, TombstoneContractInfo, Trait, AliveContractInfo}; use sr_primitives::traits::{Bounded, CheckedDiv, CheckedMul, Saturating, Zero, SaturatedConversion}; -use srml_support::traits::{Currency, ExistenceRequirement, Get, WithdrawReason}; -use srml_support::StorageMap; +use support::traits::{Currency, ExistenceRequirement, Get, WithdrawReason}; +use support::StorageMap; #[derive(PartialEq, Eq, Copy, Clone)] #[must_use] diff --git a/srml/contracts/src/tests.rs b/srml/contracts/src/tests.rs index 6ac1a50764..91c3e4f712 100644 --- a/srml/contracts/src/tests.rs +++ b/srml/contracts/src/tests.rs @@ -33,7 +33,7 @@ use runtime_io::with_externalities; use sr_primitives::testing::{Digest, DigestItem, Header, UintAuthorityId, H256}; use sr_primitives::traits::{BlakeTwo256, Hash, IdentityLookup}; use sr_primitives::{Perbill, BuildStorage}; -use srml_support::{ +use support::{ assert_ok, assert_err, impl_outer_dispatch, impl_outer_event, impl_outer_origin, parameter_types, storage::child, StorageMap, StorageValue, traits::{Currency, Get}, }; @@ -49,7 +49,7 @@ mod contract { // needs to give a name for the current crate. // This hack is required for `impl_outer_event!`. pub use super::super::*; - use srml_support::impl_outer_event; + use support::impl_outer_event; } impl_outer_event! { pub enum MetaEvent for Test { diff --git a/srml/contracts/src/wasm/code_cache.rs b/srml/contracts/src/wasm/code_cache.rs index 9e8fcab8c2..80fb3e18f6 100644 --- a/srml/contracts/src/wasm/code_cache.rs +++ b/srml/contracts/src/wasm/code_cache.rs @@ -31,7 +31,7 @@ use crate::wasm::{prepare, runtime::Env, PrefabWasmModule}; use crate::{CodeHash, CodeStorage, PristineCode, Schedule, Trait}; use rstd::prelude::*; use sr_primitives::traits::{Hash, Bounded}; -use srml_support::StorageMap; +use support::StorageMap; /// Gas metering token that used for charging storing code into the code storage. /// diff --git a/srml/council/src/lib.rs b/srml/council/src/lib.rs index 635d62fd2c..3ec76a15e1 100644 --- a/srml/council/src/lib.rs +++ b/srml/council/src/lib.rs @@ -39,8 +39,8 @@ mod tests { // These re-exports are here for a reason, edit with care pub use super::*; pub use runtime_io::with_externalities; - use srml_support::{impl_outer_origin, impl_outer_event, impl_outer_dispatch, parameter_types}; - use srml_support::traits::Get; + use support::{impl_outer_origin, impl_outer_event, impl_outer_dispatch, parameter_types}; + use support::traits::Get; pub use primitives::{H256, Blake2Hasher, u32_trait::{_1, _2, _3, _4}}; pub use sr_primitives::traits::{BlakeTwo256, IdentityLookup}; pub use sr_primitives::testing::{Digest, DigestItem, Header}; diff --git a/srml/democracy/Cargo.toml b/srml/democracy/Cargo.toml index b6341a8225..22f091e4d3 100644 --- a/srml/democracy/Cargo.toml +++ b/srml/democracy/Cargo.toml @@ -9,9 +9,9 @@ serde = { version = "1.0", optional = true, features = ["derive"] } safe-mix = { version = "1.0", default-features = false} codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] @@ -25,8 +25,8 @@ std = [ "safe-mix/std", "codec/std", "rstd/std", - "runtime_io/std", - "srml-support/std", + "runtime-io/std", + "support/std", "sr-primitives/std", "system/std", ] diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index f267763217..1fc694bece 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -23,7 +23,7 @@ use rstd::{result, convert::TryFrom}; use sr_primitives::traits::{Zero, Bounded, CheckedMul, CheckedDiv, EnsureOrigin, Hash}; use sr_primitives::weights::SimpleDispatchInfo; use codec::{Encode, Decode, Input, Output, Error}; -use srml_support::{ +use support::{ decl_module, decl_storage, decl_event, ensure, StorageValue, StorageMap, StorageLinkedMap, Parameter, Dispatchable, traits::{ @@ -31,7 +31,7 @@ use srml_support::{ OnFreeBalanceZero } }; -use srml_support::dispatch::Result; +use support::dispatch::Result; use system::{ensure_signed, ensure_root}; mod vote_threshold; @@ -970,7 +970,7 @@ impl OnFreeBalanceZero for Module { mod tests { use super::*; use runtime_io::with_externalities; - use srml_support::{ + use support::{ impl_outer_origin, impl_outer_dispatch, assert_noop, assert_ok, parameter_types, traits::Contains }; diff --git a/srml/elections/Cargo.toml b/srml/elections/Cargo.toml index d6043bb2d0..d479906737 100644 --- a/srml/elections/Cargo.toml +++ b/srml/elections/Cargo.toml @@ -10,9 +10,9 @@ safe-mix = { version = "1.0", default-features = false} codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] @@ -27,8 +27,8 @@ std = [ "primitives/std", "rstd/std", "serde", - "runtime_io/std", - "srml-support/std", + "runtime-io/std", + "support/std", "sr-primitives/std", "system/std", ] diff --git a/srml/elections/src/lib.rs b/srml/elections/src/lib.rs index c9aec6df4c..b14ffa9463 100644 --- a/srml/elections/src/lib.rs +++ b/srml/elections/src/lib.rs @@ -27,7 +27,7 @@ use rstd::prelude::*; use sr_primitives::traits::{Zero, One, StaticLookup, Bounded, Saturating}; use sr_primitives::weights::SimpleDispatchInfo; use runtime_io::print; -use srml_support::{ +use support::{ StorageValue, StorageMap, dispatch::Result, decl_storage, decl_event, ensure, decl_module, traits::{ @@ -1102,7 +1102,7 @@ impl Module { mod tests { use super::*; use std::cell::RefCell; - use srml_support::{assert_ok, assert_err, assert_noop, parameter_types}; + use support::{assert_ok, assert_err, assert_noop, parameter_types}; use runtime_io::with_externalities; use primitives::{H256, Blake2Hasher}; use sr_primitives::{ @@ -1227,7 +1227,7 @@ mod tests { pub type Block = sr_primitives::generic::Block; pub type UncheckedExtrinsic = sr_primitives::generic::UncheckedExtrinsic; - srml_support::construct_runtime!( + support::construct_runtime!( pub enum Test where Block = Block, NodeBlock = Block, diff --git a/srml/example/Cargo.toml b/srml/example/Cargo.toml index 73e280605a..30addfa727 100644 --- a/srml/example/Cargo.toml +++ b/srml/example/Cargo.toml @@ -7,12 +7,12 @@ edition = "2018" [dependencies] serde = { version = "1.0", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } balances = { package = "srml-balances", path = "../balances", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -rio = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } [dev-dependencies] primitives = { package = "substrate-primitives", path = "../../core/primitives" } @@ -23,9 +23,9 @@ std = [ "serde", "codec/std", "sr-primitives/std", - "srml-support/std", + "support/std", "system/std", "balances/std", - "rio/std", + "runtime-io/std", "rstd/std" ] diff --git a/srml/example/src/lib.rs b/srml/example/src/lib.rs index 247be01239..596defae04 100644 --- a/srml/example/src/lib.rs +++ b/srml/example/src/lib.rs @@ -254,7 +254,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use rstd::marker::PhantomData; -use srml_support::{StorageValue, dispatch::Result, decl_module, decl_storage, decl_event}; +use support::{StorageValue, dispatch::Result, decl_module, decl_storage, decl_event}; use system::{ensure_signed, ensure_root}; use codec::{Encode, Decode}; use sr_primitives::{ @@ -576,7 +576,7 @@ impl SignedExtension for WatchDummy { // check for `set_dummy` match call { Call::set_dummy(..) => { - rio::print("set_dummy was received."); + runtime_io::print("set_dummy was received."); let mut valid_tx = ValidTransaction::default(); valid_tx.priority = Bounded::max_value(); @@ -591,8 +591,8 @@ impl SignedExtension for WatchDummy { mod tests { use super::*; - use srml_support::{assert_ok, impl_outer_origin, parameter_types}; - use rio::with_externalities; + use support::{assert_ok, impl_outer_origin, parameter_types}; + use runtime_io::with_externalities; use primitives::{H256, Blake2Hasher}; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. @@ -662,7 +662,7 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. - fn new_test_ext() -> rio::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); // We use default for brevity, but you can configure as desired if needed. balances::GenesisConfig::::default().assimilate_storage(&mut t).unwrap(); diff --git a/srml/executive/Cargo.toml b/srml/executive/Cargo.toml index e398a95189..c937855148 100644 --- a/srml/executive/Cargo.toml +++ b/srml/executive/Cargo.toml @@ -8,9 +8,9 @@ edition = "2018" serde = { version = "1.0", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] @@ -23,10 +23,10 @@ balances = { package = "srml-balances", path = "../balances" } default = ["std"] std = [ "rstd/std", - "srml-support/std", + "support/std", "serde", "codec/std", "sr-primitives/std", - "runtime_io/std", + "runtime-io/std", "system/std", ] diff --git a/srml/executive/src/lib.rs b/srml/executive/src/lib.rs index d25cacf446..c6931af0a1 100644 --- a/srml/executive/src/lib.rs +++ b/srml/executive/src/lib.rs @@ -81,7 +81,7 @@ use sr_primitives::{generic::Digest, traits::{ self, Header, Zero, One, Checkable, Applyable, CheckEqual, OnFinalize, OnInitialize, NumberFor, Block as BlockT, OffchainWorker, ValidateUnsigned }}; -use srml_support::Dispatchable; +use support::Dispatchable; use codec::{Codec, Encode}; use system::{extrinsics_root, DigestOf}; use sr_primitives::{ApplyOutcome, ApplyError}; @@ -362,8 +362,8 @@ mod tests { use sr_primitives::weights::Weight; use sr_primitives::traits::{Header as HeaderT, BlakeTwo256, IdentityLookup, ConvertInto}; use sr_primitives::testing::{Digest, Header, Block}; - use srml_support::{impl_outer_event, impl_outer_origin, parameter_types}; - use srml_support::traits::{Currency, LockIdentifier, LockableCurrency, WithdrawReasons, WithdrawReason}; + use support::{impl_outer_event, impl_outer_origin, parameter_types}; + use support::traits::{Currency, LockIdentifier, LockableCurrency, WithdrawReasons, WithdrawReason}; use system; use hex_literal::hex; diff --git a/srml/finality-tracker/Cargo.toml b/srml/finality-tracker/Cargo.toml index 65ac540b6b..277c4039d2 100644 --- a/srml/finality-tracker/Cargo.toml +++ b/srml/finality-tracker/Cargo.toml @@ -10,12 +10,12 @@ codec = { package = "parity-scale-codec", version = "1.0.0", default-features = inherents = { package = "substrate-inherents", path = "../../core/inherents", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } srml-system = { path = "../system", default-features = false } [dev-dependencies] primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } -sr-io = { path = "../../core/sr-io", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } [features] default = ["std"] @@ -23,7 +23,7 @@ std = [ "serde/std", "codec/std", "rstd/std", - "srml-support/std", + "support/std", "sr-primitives/std", "srml-system/std", "inherents/std", diff --git a/srml/finality-tracker/src/lib.rs b/srml/finality-tracker/src/lib.rs index 1ed9d07dbb..340af3e4d3 100644 --- a/srml/finality-tracker/src/lib.rs +++ b/srml/finality-tracker/src/lib.rs @@ -22,12 +22,12 @@ use inherents::{ RuntimeString, InherentIdentifier, ProvideInherent, InherentData, MakeFatalError, }; -use srml_support::StorageValue; +use support::StorageValue; use sr_primitives::traits::{One, Zero, SaturatedConversion}; use rstd::{prelude::*, result, cmp, vec}; use codec::Decode; -use srml_support::{decl_module, decl_storage, for_each_tuple}; -use srml_support::traits::Get; +use support::{decl_module, decl_storage, for_each_tuple}; +use support::traits::Get; use srml_system::{ensure_none, Trait as SystemTrait}; #[cfg(feature = "std")] @@ -265,12 +265,12 @@ impl ProvideInherent for Module { mod tests { use super::*; - use sr_io::{with_externalities, TestExternalities}; + use runtime_io::{with_externalities, TestExternalities}; use primitives::H256; use sr_primitives::traits::{BlakeTwo256, IdentityLookup, OnFinalize, Header as HeaderT}; use sr_primitives::testing::Header; use sr_primitives::Perbill; - use srml_support::{assert_ok, impl_outer_origin, parameter_types}; + use support::{assert_ok, impl_outer_origin, parameter_types}; use srml_system as system; use std::cell::RefCell; diff --git a/srml/generic-asset/Cargo.toml b/srml/generic-asset/Cargo.toml index 65e21c3b11..cfe170dd7d 100644 --- a/srml/generic-asset/Cargo.toml +++ b/srml/generic-asset/Cargo.toml @@ -13,7 +13,7 @@ support = { package = "srml-support", path = "../support", default-features = fa system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] -runtime_io = { package = "sr-io", path = "../../core/sr-io" } +runtime-io ={ package = "sr-io", path = "../../core/sr-io" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } [features] diff --git a/srml/grandpa/Cargo.toml b/srml/grandpa/Cargo.toml index 71e43e8692..344139db20 100644 --- a/srml/grandpa/Cargo.toml +++ b/srml/grandpa/Cargo.toml @@ -10,16 +10,15 @@ codec = { package = "parity-scale-codec", version = "1.0.0", default-features = primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } substrate-finality-grandpa-primitives = { path = "../../core/finality-grandpa/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false, features = [ "wasm-nice-panic-message" ] } sr-primitives = { path = "../../core/sr-primitives", default-features = false } sr-staking-primitives = { path = "../../core/sr-staking-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } session = { package = "srml-session", path = "../session", default-features = false } finality-tracker = { package = "srml-finality-tracker", path = "../finality-tracker", default-features = false } [dev-dependencies] -runtime_io = { package = "sr-io", path = "../../core/sr-io" } +runtime-io ={ package = "sr-io", path = "../../core/sr-io" } [features] default = ["std"] @@ -29,7 +28,7 @@ std = [ "primitives/std", "substrate-finality-grandpa-primitives/std", "rstd/std", - "srml-support/std", + "support/std", "sr-primitives/std", "sr-staking-primitives/std", "system/std", diff --git a/srml/grandpa/src/lib.rs b/srml/grandpa/src/lib.rs index f5c025b174..b59d261e1d 100644 --- a/srml/grandpa/src/lib.rs +++ b/srml/grandpa/src/lib.rs @@ -32,7 +32,7 @@ pub use substrate_finality_grandpa_primitives as fg_primitives; use rstd::prelude::*; use codec::{self as codec, Encode, Decode, Error}; -use srml_support::{ +use support::{ decl_event, decl_storage, decl_module, dispatch::Result, storage::StorageValue, storage::StorageMap, }; diff --git a/srml/grandpa/src/mock.rs b/srml/grandpa/src/mock.rs index dd6ed766ce..126aa0569a 100644 --- a/srml/grandpa/src/mock.rs +++ b/srml/grandpa/src/mock.rs @@ -20,7 +20,7 @@ use sr_primitives::{Perbill, DigestItem, traits::IdentityLookup, testing::{Header, UintAuthorityId}}; use runtime_io; -use srml_support::{impl_outer_origin, impl_outer_event, parameter_types}; +use support::{impl_outer_origin, impl_outer_event, parameter_types}; use primitives::{H256, Blake2Hasher}; use codec::{Encode, Decode}; use crate::{AuthorityId, GenesisConfig, Trait, Module, ConsensusLog}; diff --git a/srml/im-online/Cargo.toml b/srml/im-online/Cargo.toml index 5f7514755b..3dc7da86f1 100644 --- a/srml/im-online/Cargo.toml +++ b/srml/im-online/Cargo.toml @@ -11,10 +11,10 @@ primitives = { package="substrate-primitives", path = "../../core/primitives", d rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } serde = { version = "1.0", optional = true } session = { package = "srml-session", path = "../session", default-features = false } -sr-io = { path = "../../core/sr-io", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } sr-staking-primitives = { path = "../../core/sr-staking-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [features] @@ -26,9 +26,9 @@ std = [ "rstd/std", "serde", "session/std", - "sr-io/std", + "runtime-io/std", "sr-primitives/std", "sr-staking-primitives/std", - "srml-support/std", + "support/std", "system/std", ] diff --git a/srml/im-online/src/lib.rs b/srml/im-online/src/lib.rs index 701a9e753d..d6ef6c2e9c 100644 --- a/srml/im-online/src/lib.rs +++ b/srml/im-online/src/lib.rs @@ -42,7 +42,7 @@ //! ## Usage //! //! ``` -//! use srml_support::{decl_module, dispatch::Result}; +//! use support::{decl_module, dispatch::Result}; //! use system::ensure_signed; //! use srml_im_online::{self as im_online}; //! @@ -72,7 +72,7 @@ use codec::{Encode, Decode}; use primitives::offchain::{OpaqueNetworkState, StorageKind}; use rstd::prelude::*; use session::historical::IdentificationTuple; -use sr_io::Printable; +use runtime_io::Printable; use sr_primitives::{ Perbill, ApplyError, traits::{Convert, Member}, @@ -82,7 +82,7 @@ use sr_staking_primitives::{ SessionIndex, CurrentElectedSet, offence::{ReportOffence, Offence, Kind}, }; -use srml_support::{ +use support::{ decl_module, decl_event, decl_storage, print, ensure, Parameter, StorageValue, StorageDoubleMap, }; @@ -277,7 +277,7 @@ decl_module! { // Runs after every block. fn offchain_worker(now: T::BlockNumber) { // Only send messages if we are a potential validator. - if sr_io::is_validator() { + if runtime_io::is_validator() { Self::offchain(now); } } @@ -332,7 +332,7 @@ impl Module { .map(|location| (index as u32, &local_keys[location])) }) { - let network_state = sr_io::network_state().map_err(|_| OffchainErr::NetworkState)?; + let network_state = runtime_io::network_state().map_err(|_| OffchainErr::NetworkState)?; let heartbeat_data = Heartbeat { block_number, network_state, @@ -362,7 +362,7 @@ impl Module { done, gossipping_at, }; - sr_io::local_storage_compare_and_set( + runtime_io::local_storage_compare_and_set( StorageKind::PERSISTENT, DB_KEY, curr_worker_status.as_ref().map(Vec::as_slice), @@ -378,7 +378,7 @@ impl Module { done, gossipping_at, }; - sr_io::local_storage_set( + runtime_io::local_storage_set( StorageKind::PERSISTENT, DB_KEY, &enc.encode()); } @@ -389,7 +389,7 @@ impl Module { now: T::BlockNumber, next_gossip: T::BlockNumber, ) -> Result<(Option>, bool), OffchainErr> { - let last_gossip = sr_io::local_storage_get(StorageKind::PERSISTENT, DB_KEY); + let last_gossip = runtime_io::local_storage_get(StorageKind::PERSISTENT, DB_KEY); match last_gossip { Some(last) => { let worker_status: WorkerStatus = Decode::decode(&mut &last[..]) @@ -486,10 +486,10 @@ impl session::OneSessionHandler for Module { } } -impl srml_support::unsigned::ValidateUnsigned for Module { +impl support::unsigned::ValidateUnsigned for Module { type Call = Call; - fn validate_unsigned(call: &Self::Call) -> srml_support::unsigned::TransactionValidity { + fn validate_unsigned(call: &Self::Call) -> support::unsigned::TransactionValidity { if let Call::heartbeat(heartbeat, signature) = call { if >::is_online_in_current_session(heartbeat.authority_index) { // we already received a heartbeat for this authority diff --git a/srml/indices/Cargo.toml b/srml/indices/Cargo.toml index 3cbf1d88de..31fea3cd01 100644 --- a/srml/indices/Cargo.toml +++ b/srml/indices/Cargo.toml @@ -13,7 +13,7 @@ rstd = { package = "sr-std", path = "../../core/sr-std", default-features = fals runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] @@ -29,7 +29,7 @@ std = [ "primitives/std", "rstd/std", "runtime-io/std", - "srml-support/std", + "support/std", "sr-primitives/std", "system/std", ] diff --git a/srml/indices/src/lib.rs b/srml/indices/src/lib.rs index 31e825d2c8..15921ffdf4 100644 --- a/srml/indices/src/lib.rs +++ b/srml/indices/src/lib.rs @@ -21,7 +21,7 @@ use rstd::{prelude::*, result, marker::PhantomData, convert::TryInto}; use codec::{Encode, Codec}; -use srml_support::{StorageValue, StorageMap, Parameter, decl_module, decl_event, decl_storage}; +use support::{StorageValue, StorageMap, Parameter, decl_module, decl_event, decl_storage}; use sr_primitives::traits::{One, SimpleArithmetic, StaticLookup, Member}; use system::{IsDeadAccount, OnNewAccount}; diff --git a/srml/indices/src/mock.rs b/srml/indices/src/mock.rs index e28416fd3a..65a0193b5a 100644 --- a/srml/indices/src/mock.rs +++ b/srml/indices/src/mock.rs @@ -23,7 +23,7 @@ use ref_thread_local::{ref_thread_local, RefThreadLocal}; use sr_primitives::testing::Header; use sr_primitives::Perbill; use primitives::{H256, Blake2Hasher}; -use srml_support::{impl_outer_origin, parameter_types}; +use support::{impl_outer_origin, parameter_types}; use {runtime_io, system}; use crate::{GenesisConfig, Module, Trait, IsDeadAccount, OnNewAccount, ResolveHint}; diff --git a/srml/membership/Cargo.toml b/srml/membership/Cargo.toml index 7c167bbf2c..3e822ff8ac 100644 --- a/srml/membership/Cargo.toml +++ b/srml/membership/Cargo.toml @@ -8,8 +8,8 @@ edition = "2018" serde = { version = "1.0", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -sr-io = { path = "../../core/sr-io", default-features = false } -srml-support = { path = "../support", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } @@ -23,7 +23,7 @@ std = [ "codec/std", "sr-primitives/std", "rstd/std", - "sr-io/std", - "srml-support/std", + "runtime-io/std", + "support/std", "system/std", ] diff --git a/srml/membership/src/lib.rs b/srml/membership/src/lib.rs index 76729d633d..66ff864057 100644 --- a/srml/membership/src/lib.rs +++ b/srml/membership/src/lib.rs @@ -23,7 +23,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use rstd::prelude::*; -use srml_support::{ +use support::{ StorageValue, decl_module, decl_storage, decl_event, traits::{ChangeMembers, InitializeMembers}, }; use system::ensure_root; @@ -192,8 +192,8 @@ mod tests { use super::*; use std::cell::RefCell; - use srml_support::{assert_ok, assert_noop, impl_outer_origin, parameter_types}; - use sr_io::with_externalities; + use support::{assert_ok, assert_noop, impl_outer_origin, parameter_types}; + use runtime_io::with_externalities; use primitives::{H256, Blake2Hasher}; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried. @@ -281,7 +281,7 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. - fn new_test_ext() -> sr_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); // We use default for brevity, but you can configure as desired if needed. GenesisConfig::{ diff --git a/srml/offences/Cargo.toml b/srml/offences/Cargo.toml index 4dd12413f6..39ca0f785e 100644 --- a/srml/offences/Cargo.toml +++ b/srml/offences/Cargo.toml @@ -15,7 +15,7 @@ support = { package = "srml-support", path = "../support", default-features = fa system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } substrate-primitives = { path = "../../core/primitives" } [features] diff --git a/srml/scored-pool/Cargo.toml b/srml/scored-pool/Cargo.toml index 032f28a750..77d614fc7e 100644 --- a/srml/scored-pool/Cargo.toml +++ b/srml/scored-pool/Cargo.toml @@ -7,10 +7,10 @@ edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } serde = { version = "1.0", optional = true } -sr-io = { path = "../../core/sr-io", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] @@ -22,9 +22,9 @@ default = ["std"] std = [ "codec/std", "serde", - "sr-io/std", + "runtime-io/std", "sr-primitives/std", "rstd/std", - "srml-support/std", + "support/std", "system/std", ] diff --git a/srml/scored-pool/src/lib.rs b/srml/scored-pool/src/lib.rs index dc27b3bba9..dabe9e8123 100644 --- a/srml/scored-pool/src/lib.rs +++ b/srml/scored-pool/src/lib.rs @@ -53,7 +53,7 @@ //! ## Usage //! //! ``` -//! use srml_support::{decl_module, dispatch::Result}; +//! use support::{decl_module, dispatch::Result}; //! use system::ensure_signed; //! use srml_scored_pool::{self as scored_pool}; //! @@ -90,7 +90,7 @@ mod tests; use codec::{Encode, Decode}; use rstd::prelude::*; -use srml_support::{ +use support::{ StorageValue, StorageMap, decl_module, decl_storage, decl_event, ensure, traits::{ChangeMembers, InitializeMembers, Currency, Get, ReservableCurrency}, }; diff --git a/srml/scored-pool/src/mock.rs b/srml/scored-pool/src/mock.rs index 86c8b0d8cf..fd14abd617 100644 --- a/srml/scored-pool/src/mock.rs +++ b/srml/scored-pool/src/mock.rs @@ -19,7 +19,7 @@ use super::*; use std::cell::RefCell; -use srml_support::{impl_outer_origin, parameter_types}; +use support::{impl_outer_origin, parameter_types}; use primitives::{H256, Blake2Hasher}; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried. @@ -132,7 +132,7 @@ impl Trait for Test { // This function basically just builds a genesis storage key/value store according to // our desired mockup. -pub fn new_test_ext() -> sr_io::TestExternalities { +pub fn new_test_ext() -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); // We use default for brevity, but you can configure as desired if needed. balances::GenesisConfig:: { diff --git a/srml/scored-pool/src/tests.rs b/srml/scored-pool/src/tests.rs index cec27e66cd..740e707ce0 100644 --- a/srml/scored-pool/src/tests.rs +++ b/srml/scored-pool/src/tests.rs @@ -19,8 +19,8 @@ use super::*; use mock::*; -use srml_support::{assert_ok, assert_noop}; -use sr_io::with_externalities; +use support::{assert_ok, assert_noop}; +use runtime_io::with_externalities; use sr_primitives::traits::OnInitialize; type ScoredPool = Module; diff --git a/srml/session/Cargo.toml b/srml/session/Cargo.toml index d016699765..c2e0732ed7 100644 --- a/srml/session/Cargo.toml +++ b/srml/session/Cargo.toml @@ -11,11 +11,11 @@ codec = { package = "parity-scale-codec", version = "1.0.0", default-features = rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } sr-staking-primitives = { path = "../../core/sr-staking-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } timestamp = { package = "srml-timestamp", path = "../timestamp", default-features = false } substrate-trie = { path = "../../core/trie", default-features = false, optional = true } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } [dev-dependencies] primitives = { package = "substrate-primitives", path = "../../core/primitives" } @@ -30,7 +30,7 @@ std = [ "safe-mix/std", "codec/std", "rstd/std", - "srml-support/std", + "support/std", "sr-primitives/std", "sr-staking-primitives/std", "timestamp/std", diff --git a/srml/session/src/historical.rs b/srml/session/src/historical.rs index 7e4686e923..82566295da 100644 --- a/srml/session/src/historical.rs +++ b/srml/session/src/historical.rs @@ -29,10 +29,10 @@ use rstd::prelude::*; use codec::{Encode, Decode}; use sr_primitives::KeyTypeId; use sr_primitives::traits::{Convert, OpaqueKeys, Hash as HashT}; -use srml_support::{ +use support::{ StorageValue, StorageMap, decl_module, decl_storage, }; -use srml_support::{Parameter, print}; +use support::{Parameter, print}; use substrate_trie::{MemoryDB, Trie, TrieMut, Recorder, EMPTY_PREFIX}; use substrate_trie::trie_types::{TrieDBMut, TrieDB}; use super::{SessionIndex, Module as SessionModule}; @@ -277,7 +277,7 @@ pub struct Proof { trie_nodes: Vec>, } -impl> srml_support::traits::KeyOwnerProofSystem<(KeyTypeId, D)> +impl> support::traits::KeyOwnerProofSystem<(KeyTypeId, D)> for Module { type Proof = Proof; @@ -321,7 +321,7 @@ mod tests { NEXT_VALIDATORS, force_new_session, set_next_validators, Test, System, Session, }; - use srml_support::traits::KeyOwnerProofSystem; + use support::traits::KeyOwnerProofSystem; type Historical = Module; diff --git a/srml/session/src/lib.rs b/srml/session/src/lib.rs index 58a60a9875..f7c9eee021 100644 --- a/srml/session/src/lib.rs +++ b/srml/session/src/lib.rs @@ -125,11 +125,11 @@ use sr_primitives::{KeyTypeId, AppKey}; use sr_primitives::weights::SimpleDispatchInfo; use sr_primitives::traits::{Convert, Zero, Member, OpaqueKeys}; use sr_staking_primitives::SessionIndex; -use srml_support::{ +use support::{ dispatch::Result, ConsensusEngineId, StorageValue, StorageDoubleMap, for_each_tuple, decl_module, decl_event, decl_storage, }; -use srml_support::{ensure, traits::{OnFreeBalanceZero, Get, FindAuthor}, Parameter}; +use support::{ensure, traits::{OnFreeBalanceZero, Get, FindAuthor}, Parameter}; use system::{self, ensure_signed}; #[cfg(test)] @@ -651,7 +651,7 @@ impl> FindAuthor #[cfg(test)] mod tests { use super::*; - use srml_support::assert_ok; + use support::assert_ok; use runtime_io::with_externalities; use primitives::{Blake2Hasher, crypto::key_types::DUMMY}; use sr_primitives::{ diff --git a/srml/session/src/mock.rs b/srml/session/src/mock.rs index 445076be65..fe9a4ee936 100644 --- a/srml/session/src/mock.rs +++ b/srml/session/src/mock.rs @@ -18,7 +18,7 @@ use super::*; use std::cell::RefCell; -use srml_support::{impl_outer_origin, parameter_types}; +use support::{impl_outer_origin, parameter_types}; use primitives::{crypto::key_types::DUMMY, H256}; use sr_primitives::{ Perbill, impl_opaque_keys, traits::{BlakeTwo256, IdentityLookup, ConvertInto}, diff --git a/srml/staking/Cargo.toml b/srml/staking/Cargo.toml index a29b4aa4b9..93de95caa2 100644 --- a/srml/staking/Cargo.toml +++ b/srml/staking/Cargo.toml @@ -11,10 +11,10 @@ codec = { package = "parity-scale-codec", version = "1.0.0", default-features = substrate-keyring = { path = "../../core/keyring", optional = true } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } phragmen = { package = "substrate-phragmen", path = "../../core/phragmen", default-features = false } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } sr-staking-primitives = { path = "../../core/sr-staking-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } session = { package = "srml-session", path = "../session", default-features = false, features = ["historical"] } authorship = { package = "srml-authorship", path = "../authorship", default-features = false } @@ -36,8 +36,8 @@ std = [ "codec/std", "rstd/std", "phragmen/std", - "runtime_io/std", - "srml-support/std", + "runtime-io/std", + "support/std", "sr-primitives/std", "sr-staking-primitives/std", "session/std", diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index c648cbf879..12cdd2f4e9 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -136,7 +136,7 @@ //! ### Example: Rewarding a validator by id. //! //! ``` -//! use srml_support::{decl_module, dispatch::Result}; +//! use support::{decl_module, dispatch::Result}; //! use system::ensure_signed; //! use srml_staking::{self as staking}; //! @@ -261,7 +261,7 @@ mod benches; use rstd::{prelude::*, result}; use codec::{HasCompact, Encode, Decode}; -use srml_support::{ +use support::{ StorageValue, StorageMap, StorageLinkedMap, decl_module, decl_event, decl_storage, ensure, traits::{ Currency, OnFreeBalanceZero, OnDilution, LockIdentifier, LockableCurrency, diff --git a/srml/staking/src/mock.rs b/srml/staking/src/mock.rs index b7948d12fe..94e2663b57 100644 --- a/srml/staking/src/mock.rs +++ b/srml/staking/src/mock.rs @@ -23,8 +23,8 @@ use sr_primitives::testing::{Header, UintAuthorityId}; use sr_staking_primitives::SessionIndex; use primitives::{H256, Blake2Hasher}; use runtime_io; -use srml_support::{assert_ok, impl_outer_origin, parameter_types, StorageLinkedMap}; -use srml_support::traits::{Currency, Get, FindAuthor}; +use support::{assert_ok, impl_outer_origin, parameter_types, StorageLinkedMap}; +use support::traits::{Currency, Get, FindAuthor}; use crate::{ EraIndex, GenesisConfig, Module, Trait, StakerStatus, ValidatorPrefs, RewardDestination, Nominators, inflation @@ -92,7 +92,7 @@ impl_outer_origin!{ pub struct Author11; impl FindAuthor for Author11 { fn find_author<'a, I>(_digests: I) -> Option - where I: 'a + IntoIterator + where I: 'a + IntoIterator { Some(11) } diff --git a/srml/staking/src/tests.rs b/srml/staking/src/tests.rs index bc6b92e2dc..c3f3922299 100644 --- a/srml/staking/src/tests.rs +++ b/srml/staking/src/tests.rs @@ -20,9 +20,9 @@ use super::*; use runtime_io::with_externalities; use sr_primitives::traits::OnInitialize; use sr_staking_primitives::offence::{OffenceDetails, OnOffenceHandler}; -use srml_support::{assert_ok, assert_noop, assert_eq_uvec, StorageLinkedMap}; +use support::{assert_ok, assert_noop, assert_eq_uvec, StorageLinkedMap}; use mock::*; -use srml_support::traits::{Currency, ReservableCurrency}; +use support::traits::{Currency, ReservableCurrency}; #[test] fn basic_setup_works() { diff --git a/srml/sudo/Cargo.toml b/srml/sudo/Cargo.toml index 4ce20b0421..6dad983d06 100644 --- a/srml/sudo/Cargo.toml +++ b/srml/sudo/Cargo.toml @@ -8,14 +8,12 @@ edition = "2018" serde = { version = "1.0", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -sr-io = { path = "../../core/sr-io", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } -srml-support-procedural = { path = "../support/procedural" } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] -sr-io = { path = "../../core/sr-io", default-features = false } primitives = { package = "substrate-primitives", path = "../../core/primitives" } [features] @@ -24,8 +22,8 @@ std = [ "serde", "codec/std", "rstd/std", - "sr-io/std", + "runtime-io/std", "sr-primitives/std", - "srml-support/std", + "support/std", "system/std", ] diff --git a/srml/sudo/src/lib.rs b/srml/sudo/src/lib.rs index 0a71d4d628..e933810237 100644 --- a/srml/sudo/src/lib.rs +++ b/srml/sudo/src/lib.rs @@ -51,7 +51,7 @@ //! This is an example of a module that exposes a privileged function: //! //! ``` -//! use srml_support::{decl_module, dispatch::Result}; +//! use support::{decl_module, dispatch::Result}; //! use system::ensure_root; //! //! pub trait Trait: system::Trait {} @@ -89,7 +89,7 @@ use rstd::prelude::*; use sr_primitives::traits::StaticLookup; use sr_primitives::weights::SimpleDispatchInfo; -use srml_support::{ +use support::{ StorageValue, Parameter, Dispatchable, decl_module, decl_event, decl_storage, ensure }; @@ -126,7 +126,7 @@ decl_module! { let res = match proposal.dispatch(system::RawOrigin::Root.into()) { Ok(_) => true, Err(e) => { - sr_io::print(e); + runtime_io::print(e); false } }; diff --git a/srml/support/Cargo.toml b/srml/support/Cargo.toml index 107a0683da..f1cdb69a65 100644 --- a/srml/support/Cargo.toml +++ b/srml/support/Cargo.toml @@ -9,11 +9,11 @@ serde = { version = "1.0", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.5", default-features = false, features = ["derive"] } srml-metadata = { path = "../metadata", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } inherents = { package = "substrate-inherents", path = "../../core/inherents", default-features = false } -srml-support-procedural = { path = "./procedural" } +srml-support-procedural = { package = "srml-support-procedural", path = "./procedural" } paste = "0.1" once_cell = { version = "0.1.6", default-features = false, optional = true } bitmask = { version = "0.5", default-features = false } @@ -28,7 +28,7 @@ std = [ "once_cell", "bitmask/std", "serde", - "runtime_io/std", + "runtime-io/std", "codec/std", "rstd/std", "sr-primitives/std", diff --git a/srml/support/procedural/Cargo.toml b/srml/support/procedural/Cargo.toml index fba706c17e..cb719583e2 100644 --- a/srml/support/procedural/Cargo.toml +++ b/srml/support/procedural/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" proc-macro = true [dependencies] -srml-support-procedural-tools = { path = "./tools" } +srml-support-procedural-tools = { package = "srml-support-procedural-tools", path = "./tools" } sr-api-macros = { path = "../../../core/sr-api-macros" } proc-macro2 = "0.4.27" diff --git a/srml/support/procedural/tools/Cargo.toml b/srml/support/procedural/tools/Cargo.toml index bb6d24def2..037636a2a0 100644 --- a/srml/support/procedural/tools/Cargo.toml +++ b/srml/support/procedural/tools/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -srml-support-procedural-tools-derive = { path = "./derive" } +srml-support-procedural-tools-derive = { package = "srml-support-procedural-tools-derive", path = "./derive" } proc-macro2 = "0.4.27" quote = { version = "0.6.12" } syn = { version = "0.15.30", features = ["full"] } diff --git a/srml/support/test/Cargo.toml b/srml/support/test/Cargo.toml index fa3a04d3bc..b0b21fb6a3 100644 --- a/srml/support/test/Cargo.toml +++ b/srml/support/test/Cargo.toml @@ -7,8 +7,8 @@ edition = "2018" [dependencies] serde = { version = "1.0", default-features = false, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -runtime_io = { package = "sr-io", path = "../../../core/sr-io", default-features = false } -srml-support = { version = "2", path = "../", default-features = false } +runtime-io ={ package = "sr-io", path = "../../../core/sr-io", default-features = false } +support = { package = "srml-support", version = "2", path = "../", default-features = false } inherents = { package = "substrate-inherents", path = "../../../core/inherents", default-features = false } primitives = { package = "substrate-primitives", path = "../../../core/primitives", default-features = false } trybuild = "1" @@ -19,8 +19,8 @@ default = ["std"] std = [ "serde/std", "codec/std", - "runtime_io/std", - "srml-support/std", + "runtime-io/std", + "support/std", "inherents/std", "primitives/std", ] diff --git a/srml/support/test/src/lib.rs b/srml/support/test/src/lib.rs index a7a869cf87..0e4ab93629 100644 --- a/srml/support/test/src/lib.rs +++ b/srml/support/test/src/lib.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Test crate for srml_support. Allow to make use of `srml_support::decl_storage`. +//! Test crate for srml_support. Allow to make use of `support::decl_storage`. //! See tests directory. #[test] diff --git a/srml/support/test/tests/final_keys.rs b/srml/support/test/tests/final_keys.rs index af8e01cc5f..73de126050 100644 --- a/srml/support/test/tests/final_keys.rs +++ b/srml/support/test/tests/final_keys.rs @@ -15,8 +15,8 @@ // along with Substrate. If not, see . use runtime_io::{with_externalities, Blake2Hasher}; -use srml_support::{StorageValue, StorageMap, StorageLinkedMap, StorageDoubleMap}; -use srml_support::storage::unhashed; +use support::{StorageValue, StorageMap, StorageLinkedMap, StorageDoubleMap}; +use support::storage::unhashed; use codec::{Encode, Decode}; pub trait Trait { @@ -24,11 +24,11 @@ pub trait Trait { type BlockNumber: Encode + Decode + Default + Clone; } -srml_support::decl_module! { +support::decl_module! { pub struct Module for enum Call where origin: T::Origin {} } -srml_support::decl_storage!{ +support::decl_storage!{ trait Store for Module as FinalKeys { pub Value config(value): u32; diff --git a/srml/support/test/tests/genesisconfig.rs b/srml/support/test/tests/genesisconfig.rs index 4a43eb137e..9d03d204dc 100644 --- a/srml/support/test/tests/genesisconfig.rs +++ b/srml/support/test/tests/genesisconfig.rs @@ -19,11 +19,11 @@ pub trait Trait { type Origin; } -srml_support::decl_module! { +support::decl_module! { pub struct Module for enum Call where origin: T::Origin {} } -srml_support::decl_storage! { +support::decl_storage! { trait Store for Module as Example { pub AppendableDM config(t): double_map u32, blake2_256(T::BlockNumber) => Vec; } diff --git a/srml/support/test/tests/instance.rs b/srml/support/test/tests/instance.rs index 48af8926dd..3370c0d201 100644 --- a/srml/support/test/tests/instance.rs +++ b/srml/support/test/tests/instance.rs @@ -16,7 +16,7 @@ #![recursion_limit="128"] use runtime_io::{with_externalities, Blake2Hasher}; -use srml_support::{ +use support::{ Parameter, traits::Get, parameter_types, sr_primitives::{generic, BuildStorage, traits::{BlakeTwo256, Block as _, Verify}}, metadata::{ @@ -48,7 +48,7 @@ mod module1 { type GenericType: Default + Clone + codec::Codec; } - srml_support::decl_module! { + support::decl_module! { pub struct Module, I: InstantiableThing> for enum Call where origin: ::Origin, T::BlockNumber: From @@ -64,7 +64,7 @@ mod module1 { } } - srml_support::decl_storage! { + support::decl_storage! { trait Store for Module, I: InstantiableThing> as Module1 where T::BlockNumber: From + std::fmt::Display { @@ -81,7 +81,7 @@ mod module1 { } } - srml_support::decl_event! { + support::decl_event! { pub enum Event where Phantom = std::marker::PhantomData { _Phantom(Phantom), AnotherVariant(u32), @@ -128,7 +128,7 @@ mod module2 { impl, I: Instance> Currency for Module {} - srml_support::decl_module! { + support::decl_module! { pub struct Module, I: Instance=DefaultInstance> for enum Call where origin: ::Origin { @@ -136,7 +136,7 @@ mod module2 { } } - srml_support::decl_storage! { + support::decl_storage! { trait Store for Module, I: Instance=DefaultInstance> as Module2 { pub Value config(value): T::Amount; pub Map config(map): map u64 => u64; @@ -145,7 +145,7 @@ mod module2 { } } - srml_support::decl_event! { + support::decl_event! { pub enum Event where Amount = >::Amount { Variant(Amount), } @@ -185,7 +185,7 @@ mod module3 { type Currency2: Currency; } - srml_support::decl_module! { + support::decl_module! { pub struct Module for enum Call where origin: ::Origin {} } } @@ -244,7 +244,7 @@ impl system::Trait for Runtime { type Event = Event; } -srml_support::construct_runtime!( +support::construct_runtime!( pub enum Runtime where Block = Block, NodeBlock = Block, diff --git a/srml/support/test/tests/issue2219.rs b/srml/support/test/tests/issue2219.rs index cb8b4cef09..28bd9463ff 100644 --- a/srml/support/test/tests/issue2219.rs +++ b/srml/support/test/tests/issue2219.rs @@ -14,9 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use srml_support::sr_primitives::generic; -use srml_support::sr_primitives::traits::{BlakeTwo256, Block as _, Verify}; -use srml_support::codec::{Encode, Decode}; +use support::sr_primitives::generic; +use support::sr_primitives::traits::{BlakeTwo256, Block as _, Verify}; +use support::codec::{Encode, Decode}; use primitives::{H256, sr25519}; use serde::{Serialize, Deserialize}; @@ -82,7 +82,7 @@ mod module { pub trait Trait: system::Trait {} - srml_support::decl_module! { + support::decl_module! { pub struct Module for enum Call where origin: T::Origin {} } @@ -99,7 +99,7 @@ mod module { } } - srml_support::decl_storage! { + support::decl_storage! { trait Store for Module as Actors { /// requirements to enter and maintain status in roles pub Parameters get(parameters) build(|config: &GenesisConfig| { @@ -164,7 +164,7 @@ impl system::Trait for Runtime { impl module::Trait for Runtime {} -srml_support::construct_runtime!( +support::construct_runtime!( pub enum Runtime where Block = Block, NodeBlock = Block, diff --git a/srml/support/test/tests/reserved_keyword/on_initialize.rs b/srml/support/test/tests/reserved_keyword/on_initialize.rs index 1934ae5ea1..f9604c9487 100644 --- a/srml/support/test/tests/reserved_keyword/on_initialize.rs +++ b/srml/support/test/tests/reserved_keyword/on_initialize.rs @@ -2,7 +2,7 @@ macro_rules! reserved { ($($reserved:ident)*) => { $( mod $reserved { - pub use srml_support::dispatch::Result; + pub use support::dispatch::Result; pub trait Trait { type Origin; @@ -10,14 +10,14 @@ macro_rules! reserved { } pub mod system { - use srml_support::dispatch::Result; + use support::dispatch::Result; pub fn ensure_root(_: R) -> Result { Ok(()) } } - srml_support::decl_module! { + support::decl_module! { pub struct Module for enum Call where origin: T::Origin { fn $reserved(_origin) -> Result { unreachable!() } } diff --git a/srml/support/test/tests/system.rs b/srml/support/test/tests/system.rs index 9ea0b2bc76..afeb0e0195 100644 --- a/srml/support/test/tests/system.rs +++ b/srml/support/test/tests/system.rs @@ -1,4 +1,4 @@ -use srml_support::codec::{Encode, Decode}; +use support::codec::{Encode, Decode}; pub trait Trait: 'static + Eq + Clone { type Origin: Into, Self::Origin>> @@ -10,7 +10,7 @@ pub trait Trait: 'static + Eq + Clone { type Event: From; } -srml_support::decl_module! { +support::decl_module! { pub struct Module for enum Call where origin: T::Origin { } } @@ -20,7 +20,7 @@ impl Module { } } -srml_support::decl_event!( +support::decl_event!( pub enum Event { ExtrinsicSuccess, ExtrinsicFailed, diff --git a/srml/system/Cargo.toml b/srml/system/Cargo.toml index fb2b5296c7..f6fd25c29f 100644 --- a/srml/system/Cargo.toml +++ b/srml/system/Cargo.toml @@ -10,10 +10,10 @@ safe-mix = { version = "1.0", default-features = false} codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } sr-version = { path = "../../core/sr-version", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } [dev-dependencies] criterion = "0.2" @@ -26,8 +26,8 @@ std = [ "codec/std", "primitives/std", "rstd/std", - "runtime_io/std", - "srml-support/std", + "runtime-io/std", + "support/std", "sr-primitives/std", "sr-version/std", ] diff --git a/srml/system/benches/bench.rs b/srml/system/benches/bench.rs index 3d10db557c..b050e80c48 100644 --- a/srml/system/benches/bench.rs +++ b/srml/system/benches/bench.rs @@ -16,7 +16,7 @@ use criterion::{Criterion, criterion_group, criterion_main, black_box}; use srml_system as system; -use srml_support::{decl_module, decl_event, impl_outer_origin, impl_outer_event}; +use support::{decl_module, decl_event, impl_outer_origin, impl_outer_event}; use runtime_io::{with_externalities, Blake2Hasher}; use primitives::H256; use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; @@ -51,7 +51,7 @@ impl_outer_event! { } } -srml_support::parameter_types! { +support::parameter_types! { pub const BlockHashCount: u64 = 250; pub const MaximumBlockWeight: u32 = 4 * 1024 * 1024; pub const MaximumBlockLength: u32 = 4 * 1024 * 1024; diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index 3b692d8df0..dab0c11fa5 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -68,7 +68,7 @@ //! ### Example - Get random seed and extrinsic count for the current block //! //! ``` -//! use srml_support::{decl_module, dispatch::Result}; +//! use support::{decl_module, dispatch::Result}; //! use srml_system::{self as system, ensure_signed}; //! //! pub trait Trait: system::Trait {} @@ -108,7 +108,7 @@ use sr_primitives::traits::{self, CheckEqual, SimpleArithmetic, Zero, SignedExte MaybeSerializeDebugButNotDeserialize, MaybeSerializeDebug, StaticLookup, One, Bounded, Lookup, }; use primitives::storage::well_known_keys; -use srml_support::{ +use support::{ storage, decl_module, decl_event, decl_storage, StorageDoubleMap, StorageValue, StorageMap, Parameter, for_each_tuple, traits::{Contains, Get} }; @@ -1144,7 +1144,7 @@ mod tests { use runtime_io::with_externalities; use primitives::H256; use sr_primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; - use srml_support::{impl_outer_origin, parameter_types}; + use support::{impl_outer_origin, parameter_types}; impl_outer_origin!{ pub enum Origin for Test where system = super {} diff --git a/srml/timestamp/Cargo.toml b/srml/timestamp/Cargo.toml index 9b066a1505..022e478e57 100644 --- a/srml/timestamp/Cargo.toml +++ b/srml/timestamp/Cargo.toml @@ -10,11 +10,11 @@ codec = { package = "parity-scale-codec", version = "1.0.0", default-features = rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } inherents = { package = "substrate-inherents", path = "../../core/inherents", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] -runtime_io = { package = "sr-io", path = "../../core/sr-io" } +runtime-io ={ package = "sr-io", path = "../../core/sr-io" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } [features] @@ -24,7 +24,7 @@ std = [ "codec/std", "rstd/std", "sr-primitives/std", - "srml-support/std", + "support/std", "serde", "system/std", ] diff --git a/srml/timestamp/src/lib.rs b/srml/timestamp/src/lib.rs index 1b03b5b9af..cf7792eaa4 100644 --- a/srml/timestamp/src/lib.rs +++ b/srml/timestamp/src/lib.rs @@ -61,7 +61,7 @@ //! ### Get current timestamp //! //! ``` -//! use srml_support::{decl_module, dispatch::Result}; +//! use support::{decl_module, dispatch::Result}; //! # use srml_timestamp as timestamp; //! use system::ensure_signed; //! @@ -96,8 +96,8 @@ use codec::Encode; use codec::Decode; #[cfg(feature = "std")] use inherents::ProvideInherentData; -use srml_support::{StorageValue, Parameter, decl_storage, decl_module, for_each_tuple}; -use srml_support::traits::{Time, Get}; +use support::{StorageValue, Parameter, decl_storage, decl_module, for_each_tuple}; +use support::traits::{Time, Get}; use sr_primitives::traits::{ SimpleArithmetic, Zero, SaturatedConversion, Scale }; @@ -338,7 +338,7 @@ impl Time for Module { mod tests { use super::*; - use srml_support::{impl_outer_origin, assert_ok, parameter_types}; + use support::{impl_outer_origin, assert_ok, parameter_types}; use runtime_io::{with_externalities, TestExternalities}; use primitives::H256; use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; diff --git a/srml/treasury/Cargo.toml b/srml/treasury/Cargo.toml index ae2681e11b..55ea6aef95 100644 --- a/srml/treasury/Cargo.toml +++ b/srml/treasury/Cargo.toml @@ -9,12 +9,12 @@ serde = { version = "1.0", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -srml-support = { path = "../support", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } balances = { package = "srml-balances", path = "../balances", default-features = false } [dev-dependencies] -runtime_io = { package = "sr-io", path = "../../core/sr-io" } +runtime-io ={ package = "sr-io", path = "../../core/sr-io" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } [features] @@ -24,7 +24,7 @@ std = [ "codec/std", "rstd/std", "sr-primitives/std", - "srml-support/std", + "support/std", "system/std", "balances/std", ] diff --git a/srml/treasury/src/lib.rs b/srml/treasury/src/lib.rs index ef2b9e69fe..0ee4919c5d 100644 --- a/srml/treasury/src/lib.rs +++ b/srml/treasury/src/lib.rs @@ -70,8 +70,8 @@ #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; use rstd::prelude::*; -use srml_support::{StorageValue, StorageMap, decl_module, decl_storage, decl_event, ensure, print}; -use srml_support::traits::{ +use support::{StorageValue, StorageMap, decl_module, decl_storage, decl_event, ensure, print}; +use support::traits::{ Currency, ExistenceRequirement, Get, Imbalance, OnDilution, OnUnbalanced, ReservableCurrency, WithdrawReason }; @@ -357,7 +357,7 @@ mod tests { use super::*; use runtime_io::with_externalities; - use srml_support::{assert_noop, assert_ok, impl_outer_origin, parameter_types}; + use support::{assert_noop, assert_ok, impl_outer_origin, parameter_types}; use primitives::{H256, Blake2Hasher}; use sr_primitives::{Perbill, traits::{BlakeTwo256, OnFinalize, IdentityLookup}, testing::Header}; -- GitLab From 26a802bb245417c21bea79cf0e64910bac464b45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 4 Sep 2019 15:30:26 +0200 Subject: [PATCH 055/275] Implement `TryInto` for outer events (#3549) * Implement `TryInto` for outer events * Remove invalid comment * Fix compilation --- srml/support/src/event.rs | 57 ++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/srml/support/src/event.rs b/srml/support/src/event.rs index 857f42f49e..eb5cc20635 100644 --- a/srml/support/src/event.rs +++ b/srml/support/src/event.rs @@ -452,31 +452,44 @@ macro_rules! impl_outer_event { $( $module_name:ident::Event $( <$generic_param:ident> )? $( { $generic_instance:ident } )?, )*; ) => { $crate::paste::item! { - // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. - #[derive(Clone, PartialEq, Eq, $crate::codec::Encode, $crate::codec::Decode)] - #[cfg_attr(feature = "std", derive(Debug))] - $(#[$attr])* - #[allow(non_camel_case_types)] - pub enum $name { - system($system::Event), - $( - [< $module_name $(_ $generic_instance )? >]( - $module_name::Event < $( $generic_param )? $(, $module_name::$generic_instance )? > - ), - )* - } - impl From<$system::Event> for $name { - fn from(x: $system::Event) -> Self { - $name::system(x) + #[derive(Clone, PartialEq, Eq, $crate::codec::Encode, $crate::codec::Decode)] + #[cfg_attr(feature = "std", derive(Debug))] + $(#[$attr])* + #[allow(non_camel_case_types)] + pub enum $name { + system($system::Event), + $( + [< $module_name $(_ $generic_instance )? >]( + $module_name::Event < $( $generic_param )? $(, $module_name::$generic_instance )? > + ), + )* } - } - $( - impl From<$module_name::Event < $( $generic_param, )? $( $module_name::$generic_instance )? >> for $name { - fn from(x: $module_name::Event < $( $generic_param, )? $( $module_name::$generic_instance )? >) -> Self { - $name::[< $module_name $(_ $generic_instance )? >](x) + impl From<$system::Event> for $name { + fn from(x: $system::Event) -> Self { + $name::system(x) } } - )* + $( + impl From<$module_name::Event < $( $generic_param, )? $( $module_name::$generic_instance )? >> for $name { + fn from(x: $module_name::Event < $( $generic_param, )? $( $module_name::$generic_instance )? >) -> Self { + $name::[< $module_name $(_ $generic_instance )? >](x) + } + } + impl $crate::rstd::convert::TryInto< + $module_name::Event < $( $generic_param, )? $( $module_name::$generic_instance )? > + > for $name { + type Error = (); + + fn try_into(self) -> $crate::rstd::result::Result< + $module_name::Event < $( $generic_param, )? $( $module_name::$generic_instance )? >, Self::Error + > { + match self { + Self::[< $module_name $(_ $generic_instance )? >](evt) => Ok(evt), + _ => Err(()), + } + } + } + )* } $crate::__impl_outer_event_json_metadata!( $runtime; -- GitLab From 5420de3face1349a97eb954ae71c5b0b940c31de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 4 Sep 2019 16:21:42 +0200 Subject: [PATCH 056/275] Custom runtime module errors (#3433) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * srml-system checks * wip * more modules compiles * node-runtime checks * build.sh passes * include dispatch error in failed event * revert some unnecessary changes * refactor based on comments * more compile error fixes * avoid unnecessary into * reorder code * fixes some tests * manually implement encode & decode to avoid i8 workaround * more test fixes * more fixes * more error fixes * Apply suggestions from code review Co-Authored-By: Tomasz Drwięga * address comments * test for DispatchError encoding * tyep alias for democracy * make error printable * line width * fix balances tests * fix executive test * fix system tests * bump version * ensure consistent method signature * Apply suggestions from code review Co-Authored-By: Gavin Wood * changes based on review * Add issue number for TODOs * fix * line width * fix test * Update core/sr-primitives/src/lib.rs Co-Authored-By: Bastian Köcher * Update core/sr-primitives/src/traits.rs Co-Authored-By: Bastian Köcher * Update srml/council/src/motions.rs Co-Authored-By: Bastian Köcher * Update srml/council/src/motions.rs Co-Authored-By: Bastian Köcher * update based on review * More concrete macro matching * fix test build issue * Update hex-literal dependency version. (#3141) * Update hex-literal dep version. * Update lock file. * Start to rework the new error handling * More work to get it back compiling * Start to fix after master merge * The great transaction error handling refactoring * Make `decl_error` errors convertible to `&'static str` * Make srml-executive build again * Fix `sr-primitives` tests * More fixes * Last round of fix ups * Fix build * Fix build * Apply suggestions from code review Co-Authored-By: Tomasz Drwięga * Rename some stuff * Fixes after master merge * Adds `CheckBlockGasLimit` signed extension * Remove debug stuff * Fix srml-balances test * Rename `InvalidIndex` to `CannotLookup` * Remove weird generic parameters * Rename function again * Fix import * Document the signed extension * Change from `Into` to `From` * Update srml/contracts/src/lib.rs Co-Authored-By: Sergei Pepyakin * Fix compilation * Update srml/contracts/src/lib.rs Co-Authored-By: Tomasz Drwięga * Update core/sr-primitives/src/transaction_validity.rs Co-Authored-By: Tomasz Drwięga * Remove unused code * Fix compilation * Some cleanups * Fix compile errors * Make `TransactionValidity` a `Result` * Apply suggestions from code review Co-Authored-By: Gavin Wood * Beautify the code a little bit and fix test * Make `CannotLookup` an inherent error declared by `decl_error!` * Adds some documentation * Make `ApplyOutcome` a result * Up the spec_version * Apply suggestions from code review Co-Authored-By: Gavin Wood Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> --- core/basic-authorship/src/basic_authorship.rs | 9 +- .../client/src/block_builder/block_builder.rs | 3 +- core/rpc/api/src/author/error.rs | 10 +- core/sr-io/src/lib.rs | 8 +- core/sr-io/with_std.rs | 8 +- core/sr-io/without_std.rs | 9 +- .../src/generic/checked_extrinsic.rs | 26 +-- .../src/generic/unchecked_extrinsic.rs | 55 ++--- core/sr-primitives/src/lib.rs | 156 ++++++++++---- core/sr-primitives/src/testing.rs | 25 ++- core/sr-primitives/src/traits.rs | 185 +++++++++-------- .../sr-primitives/src/transaction_validity.rs | 195 +++++++++++++----- core/test-runtime/src/lib.rs | 14 +- core/test-runtime/src/system.rs | 43 ++-- core/transaction-pool/graph/src/error.rs | 12 +- core/transaction-pool/graph/src/pool.rs | 25 ++- core/transaction-pool/src/tests.rs | 22 +- node-template/runtime/src/lib.rs | 3 +- node/cli/src/factory_impl.rs | 5 +- node/cli/src/service.rs | 12 +- node/executor/src/lib.rs | 24 ++- node/runtime/src/lib.rs | 10 +- node/testing/src/keyring.rs | 3 +- srml/balances/src/lib.rs | 40 ++-- srml/balances/src/tests.rs | 15 +- srml/contracts/src/gas.rs | 18 +- srml/contracts/src/lib.rs | 96 ++++++++- srml/contracts/src/tests.rs | 39 +++- srml/council/src/lib.rs | 4 + srml/democracy/src/lib.rs | 8 +- srml/elections/src/lib.rs | 4 +- srml/example/src/lib.rs | 25 ++- srml/executive/src/lib.rs | 170 ++++++--------- srml/grandpa/src/mock.rs | 4 +- srml/im-online/src/lib.rs | 25 +-- srml/indices/src/lib.rs | 10 +- srml/staking/src/lib.rs | 4 +- srml/staking/src/tests.rs | 10 +- srml/sudo/src/lib.rs | 9 +- srml/support/src/dispatch.rs | 175 ++++++++++++++-- srml/support/src/error.rs | 151 ++++++++++++++ srml/support/src/lib.rs | 15 +- srml/support/src/unsigned.rs | 7 +- srml/support/test/tests/system.rs | 7 + srml/system/src/lib.rs | 180 +++++++++------- subkey/src/main.rs | 3 +- 46 files changed, 1255 insertions(+), 626 deletions(-) create mode 100644 srml/support/src/error.rs diff --git a/core/basic-authorship/src/basic_authorship.rs b/core/basic-authorship/src/basic_authorship.rs index 2030f2be5a..ffc4d766c9 100644 --- a/core/basic-authorship/src/basic_authorship.rs +++ b/core/basic-authorship/src/basic_authorship.rs @@ -30,9 +30,10 @@ use inherents::InherentData; use log::{error, info, debug, trace}; use primitives::{H256, Blake2Hasher, ExecutionContext}; use sr_primitives::{ - traits::{Block as BlockT, Hash as HashT, Header as HeaderT, ProvideRuntimeApi, DigestFor, BlakeTwo256}, + traits::{ + Block as BlockT, Hash as HashT, Header as HeaderT, ProvideRuntimeApi, DigestFor, BlakeTwo256 + }, generic::BlockId, - ApplyError, }; use transaction_pool::txpool::{self, Pool as TransactionPool}; use substrate_telemetry::{telemetry, CONSENSUS_INFO}; @@ -170,7 +171,7 @@ impl Proposer, A> wh Ok(()) => { debug!("[{:?}] Pushed to the block.", pending.hash); } - Err(error::Error::ApplyExtrinsicFailed(ApplyError::FullBlock)) => { + Err(error::Error::ApplyExtrinsicFailed(e)) if e.exhausted_resources() => { if is_first { debug!("[{:?}] Invalid transaction: FullBlock on empty block", pending.hash); unqueue_invalid.push(pending.hash.clone()); @@ -178,7 +179,7 @@ impl Proposer, A> wh skipped += 1; debug!( "Block seems full, but will try {} more transactions before quitting.", - MAX_SKIPPED_TRANSACTIONS - skipped + MAX_SKIPPED_TRANSACTIONS - skipped, ); } else { debug!("Block is full, proceed with proposing."); diff --git a/core/client/src/block_builder/block_builder.rs b/core/client/src/block_builder/block_builder.rs index 22aac577e3..b6fae5068a 100644 --- a/core/client/src/block_builder/block_builder.rs +++ b/core/client/src/block_builder/block_builder.rs @@ -17,7 +17,6 @@ use super::api::BlockBuilder as BlockBuilderApi; use std::vec::Vec; use codec::Encode; -use sr_primitives::ApplyOutcome; use sr_primitives::generic::BlockId; use sr_primitives::traits::{ Header as HeaderT, Hash, Block as BlockT, One, HashFor, ProvideRuntimeApi, ApiRef, DigestFor, @@ -104,7 +103,7 @@ where ExecutionContext::BlockConstruction, xt.clone() )? { - Ok(ApplyOutcome::Success) | Ok(ApplyOutcome::Fail) => { + Ok(_) => { extrinsics.push(xt); Ok(()) } diff --git a/core/rpc/api/src/author/error.rs b/core/rpc/api/src/author/error.rs index 0a71de5cb9..727b58bd21 100644 --- a/core/rpc/api/src/author/error.rs +++ b/core/rpc/api/src/author/error.rs @@ -101,15 +101,15 @@ impl From for rpc::Error { message: format!("Verification Error: {}", e).into(), data: Some(format!("{:?}", e).into()), }, - Error::Pool(PoolError::InvalidTransaction(code)) => rpc::Error { + Error::Pool(PoolError::InvalidTransaction(e)) => rpc::Error { code: rpc::ErrorCode::ServerError(POOL_INVALID_TX), message: "Invalid Transaction".into(), - data: Some(code.into()), + data: serde_json::to_value(e).ok(), }, - Error::Pool(PoolError::UnknownTransactionValidity(code)) => rpc::Error { + Error::Pool(PoolError::UnknownTransaction(e)) => rpc::Error { code: rpc::ErrorCode::ServerError(POOL_UNKNOWN_VALIDITY), message: "Unknown Transaction Validity".into(), - data: Some(code.into()), + data: serde_json::to_value(e).ok(), }, Error::Pool(PoolError::TemporarilyBanned) => rpc::Error { code: rpc::ErrorCode::ServerError(POOL_TEMPORARILY_BANNED), @@ -133,7 +133,7 @@ impl From for rpc::Error { }, Error::Pool(PoolError::ImmediatelyDropped) => rpc::Error { code: rpc::ErrorCode::ServerError(POOL_IMMEDIATELY_DROPPED), - message: "Immediately Dropped" .into(), + message: "Immediately Dropped".into(), data: Some("The transaction couldn't enter the pool because of the limit".into()), }, Error::UnsupportedKeyType => rpc::Error { diff --git a/core/sr-io/src/lib.rs b/core/sr-io/src/lib.rs index b79c13fb12..de5c48f5fe 100644 --- a/core/sr-io/src/lib.rs +++ b/core/sr-io/src/lib.rs @@ -55,7 +55,13 @@ pub mod offchain; /// Trait for things which can be printed. pub trait Printable { /// Print the object. - fn print(self); + fn print(&self); +} + +impl Printable for u8 { + fn print(&self) { + u64::from(*self).print() + } } /// Converts a public trait definition into a private trait and set of public functions diff --git a/core/sr-io/with_std.rs b/core/sr-io/with_std.rs index 8e6a160cf2..acbeb8ce0e 100644 --- a/core/sr-io/with_std.rs +++ b/core/sr-io/with_std.rs @@ -479,19 +479,19 @@ pub fn with_storage R>( } impl<'a> Printable for &'a [u8] { - fn print(self) { - println!("Runtime: {}", HexDisplay::from(&self)); + fn print(&self) { + println!("Runtime: {}", HexDisplay::from(self)); } } impl<'a> Printable for &'a str { - fn print(self) { + fn print(&self) { println!("Runtime: {}", self); } } impl Printable for u64 { - fn print(self) { + fn print(&self) { println!("Runtime: {}", self); } } diff --git a/core/sr-io/without_std.rs b/core/sr-io/without_std.rs index c5f2ac483f..58aff2444e 100644 --- a/core/sr-io/without_std.rs +++ b/core/sr-io/without_std.rs @@ -1220,7 +1220,7 @@ unsafe fn from_raw_parts(ptr: *mut u8, len: u32) -> Option> { impl Api for () {} impl<'a> Printable for &'a [u8] { - fn print(self) { + fn print(&self) { unsafe { ext_print_hex.get()(self.as_ptr(), self.len() as u32); } @@ -1228,7 +1228,7 @@ impl<'a> Printable for &'a [u8] { } impl<'a> Printable for &'a str { - fn print(self) { + fn print(&self) { unsafe { ext_print_utf8.get()(self.as_ptr() as *const u8, self.len() as u32); } @@ -1236,7 +1236,8 @@ impl<'a> Printable for &'a str { } impl Printable for u64 { - fn print(self) { - unsafe { ext_print_num.get()(self); } + fn print(&self) { + unsafe { ext_print_num.get()(*self); } } } + diff --git a/core/sr-primitives/src/generic/checked_extrinsic.rs b/core/sr-primitives/src/generic/checked_extrinsic.rs index 08d7b10386..e8d41325c4 100644 --- a/core/sr-primitives/src/generic/checked_extrinsic.rs +++ b/core/sr-primitives/src/generic/checked_extrinsic.rs @@ -17,10 +17,8 @@ //! Generic implementation of an extrinsic that has passed the verification //! stage. -use rstd::result::Result; use crate::traits::{ - self, Member, MaybeDisplay, SignedExtension, DispatchError, Dispatchable, DispatchResult, - ValidateUnsigned + self, Member, MaybeDisplay, SignedExtension, Dispatchable, ValidateUnsigned, }; use crate::weights::{GetDispatchInfo, DispatchInfo}; use crate::transaction_validity::TransactionValidity; @@ -55,28 +53,24 @@ where self.signed.as_ref().map(|x| &x.0) } - fn validate>(&self, + fn validate>( + &self, info: DispatchInfo, len: usize, ) -> TransactionValidity { if let Some((ref id, ref extra)) = self.signed { - Extra::validate(extra, id, &self.function, info, len).into() + Extra::validate(extra, id, &self.function, info, len) } else { - match Extra::validate_unsigned(&self.function, info, len) { - Ok(extra) => match U::validate_unsigned(&self.function) { - TransactionValidity::Valid(v) => - TransactionValidity::Valid(v.combine_with(extra)), - x => x, - }, - x => x.into(), - } + let valid = Extra::validate_unsigned(&self.function, info, len)?; + Ok(valid.combine_with(U::validate_unsigned(&self.function)?)) } } - fn dispatch(self, + fn apply( + self, info: DispatchInfo, len: usize, - ) -> Result { + ) -> crate::ApplyResult { let (maybe_who, pre) = if let Some((id, extra)) = self.signed { let pre = Extra::pre_dispatch(extra, &id, &self.function, info, len)?; (Some(id), pre) @@ -86,7 +80,7 @@ where }; let res = self.function.dispatch(Origin::from(maybe_who)); Extra::post_dispatch(pre, info, len); - Ok(res) + Ok(res.map_err(Into::into)) } } diff --git a/core/sr-primitives/src/generic/unchecked_extrinsic.rs b/core/sr-primitives/src/generic/unchecked_extrinsic.rs index aebf80edc6..48614946d6 100644 --- a/core/sr-primitives/src/generic/unchecked_extrinsic.rs +++ b/core/sr-primitives/src/generic/unchecked_extrinsic.rs @@ -21,9 +21,11 @@ use std::fmt; use rstd::prelude::*; use runtime_io::blake2_256; -use crate::codec::{Decode, Encode, Input, Error}; -use crate::traits::{self, Member, MaybeDisplay, SignedExtension, Checkable, Extrinsic}; -use super::CheckedExtrinsic; +use codec::{Decode, Encode, Input, Error}; +use crate::{ + traits::{self, Member, MaybeDisplay, SignedExtension, Checkable, Extrinsic}, + generic::CheckedExtrinsic, transaction_validity::{TransactionValidityError, InvalidTransaction}, +}; const TRANSACTION_VERSION: u8 = 3; @@ -101,11 +103,11 @@ where Signature: Member + traits::Verify, Extra: SignedExtension, AccountId: Member + MaybeDisplay, - Lookup: traits::Lookup + Lookup: traits::Lookup, { type Checked = CheckedExtrinsic; - fn check(self, lookup: &Lookup) -> Result { + fn check(self, lookup: &Lookup) -> Result { Ok(match self.signature { Some((signed, signature, extra)) => { let signed = lookup.lookup(signed)?; @@ -113,7 +115,7 @@ where if !raw_payload.using_encoded(|payload| { signature.verify(payload, &signed) }) { - return Err(crate::BAD_SIGNATURE) + return Err(InvalidTransaction::BadProof.into()) } let (function, extra, _) = raw_payload.deconstruct(); @@ -136,9 +138,9 @@ where /// is going to be different than the `SignaturePayload` - so the thing the extrinsic /// actually contains. pub struct SignedPayload(( - Call, - Extra, - Extra::AdditionalSigned, + Call, + Extra, + Extra::AdditionalSigned, )); impl SignedPayload where @@ -148,7 +150,7 @@ impl SignedPayload where /// Create new `SignedPayload`. /// /// This function may fail if `additional_signed` of `Extra` is not available. - pub fn new(call: Call, extra: Extra) -> Result { + pub fn new(call: Call, extra: Extra) -> Result { let additional_signed = extra.additional_signed()?; let raw_payload = (call, extra, additional_signed); Ok(Self(raw_payload)) @@ -256,7 +258,12 @@ where Extra: SignedExtension, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "UncheckedExtrinsic({:?}, {:?})", self.signature.as_ref().map(|x| (&x.0, &x.2)), self.function) + write!( + f, + "UncheckedExtrinsic({:?}, {:?})", + self.signature.as_ref().map(|x| (&x.0, &x.2)), + self.function, + ) } } @@ -265,15 +272,10 @@ mod tests { use super::*; use runtime_io::blake2_256; use crate::codec::{Encode, Decode}; - use crate::traits::{SignedExtension, Lookup}; + use crate::traits::{SignedExtension, IdentityLookup}; use serde::{Serialize, Deserialize}; - struct TestContext; - impl Lookup for TestContext { - type Source = u64; - type Target = u64; - fn lookup(&self, s: u64) -> Result { Ok(s) } - } + type TestContext = IdentityLookup; #[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize, Encode, Decode)] struct TestSig(u64, Vec); @@ -298,7 +300,7 @@ mod tests { type AdditionalSigned = (); type Pre = (); - fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) } + fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } } type Ex = UncheckedExtrinsic; @@ -340,7 +342,7 @@ mod tests { fn unsigned_check_should_work() { let ux = Ex::new_unsigned(vec![0u8; 0]); assert!(!ux.is_signed().unwrap_or(false)); - assert!(>::check(ux, &TestContext).is_ok()); + assert!(>::check(ux, &Default::default()).is_ok()); } #[test] @@ -349,10 +351,13 @@ mod tests { vec![0u8; 0], TEST_ACCOUNT, TestSig(TEST_ACCOUNT, vec![0u8; 0]), - TestExtra + TestExtra, ); assert!(ux.is_signed().unwrap_or(false)); - assert_eq!(>::check(ux, &TestContext), Err(crate::BAD_SIGNATURE)); + assert_eq!( + >::check(ux, &Default::default()), + Err(InvalidTransaction::BadProof.into()), + ); } #[test] @@ -361,12 +366,12 @@ mod tests { vec![0u8; 0], TEST_ACCOUNT, TestSig(TEST_ACCOUNT, (vec![0u8; 0], TestExtra).encode()), - TestExtra + TestExtra, ); assert!(ux.is_signed().unwrap_or(false)); assert_eq!( - >::check(ux, &TestContext), - Ok(CEx { signed: Some((TEST_ACCOUNT, TestExtra)), function: vec![0u8; 0] }) + >::check(ux, &Default::default()), + Ok(CEx { signed: Some((TEST_ACCOUNT, TestExtra)), function: vec![0u8; 0] }), ); } diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index 454f1cdfb8..bcd54c660b 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -58,19 +58,6 @@ pub use generic::{DigestItem, Digest}; pub use primitives::crypto::{key_types, KeyTypeId, CryptoType}; pub use app_crypto::AppKey; -/// A message indicating an invalid signature in extrinsic. -pub const BAD_SIGNATURE: &str = "bad signature in extrinsic"; - -/// Full block error message. -/// -/// This allows modules to indicate that given transaction is potentially valid -/// in the future, but can't be executed in the current state. -/// Note this error should be returned early in the execution to prevent DoS, -/// cause the fees are not being paid if this error is returned. -/// -/// Example: block gas limit is reached (the transaction can be retried in the next block though). -pub const BLOCK_FULL: &str = "block size limit is reached"; - /// Justification type. pub type Justification = Vec; @@ -636,53 +623,111 @@ impl From for AnySignature { } } -#[derive(Eq, PartialEq, Clone, Copy, Decode)] +#[derive(Eq, PartialEq, Clone, Copy, Decode, Encode)] #[cfg_attr(feature = "std", derive(Debug, Serialize))] -#[repr(u8)] -/// Outcome of a valid extrinsic application. Capable of being sliced. -pub enum ApplyOutcome { - /// Successful application (extrinsic reported no issue). - Success = 0, - /// Failed application (extrinsic was probably a no-op other than fees). - Fail = 1, +/// Reason why an extrinsic couldn't be applied (i.e. invalid extrinsic). +pub enum ApplyError { + /// General error to do with the permissions of the sender. + NoPermission, + + /// General error to do with the state of the system in general. + BadState, + + /// Any error to do with the transaction validity. + Validity(transaction_validity::TransactionValidityError), } -impl codec::Encode for ApplyOutcome { - fn using_encoded R>(&self, f: F) -> R { - f(&[*self as u8]) +impl ApplyError { + /// Returns if the reason for the error was block resource exhaustion. + pub fn exhausted_resources(&self) -> bool { + match self { + Self::Validity(e) => e.exhausted_resources(), + _ => false, + } } } -impl codec::EncodeLike for ApplyOutcome {} - -#[derive(Eq, PartialEq, Clone, Copy, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize))] -#[repr(u8)] -/// Reason why an extrinsic couldn't be applied (i.e. invalid extrinsic). -pub enum ApplyError { - /// Bad signature. - BadSignature = 0, - /// Nonce too low. - Stale = 1, - /// Nonce too high. - Future = 2, - /// Sending account had too low a balance. - CantPay = 3, - /// Block is full, no more extrinsics can be applied. - FullBlock = 255, +impl From for &'static str { + fn from(err: ApplyError) -> &'static str { + match err { + ApplyError::NoPermission => "Transaction does not have required permissions", + ApplyError::BadState => "System state currently prevents this transaction", + ApplyError::Validity(v) => v.into(), + } + } } -impl codec::Encode for ApplyError { - fn using_encoded R>(&self, f: F) -> R { - f(&[*self as u8]) +impl From for ApplyError { + fn from(err: transaction_validity::TransactionValidityError) -> Self { + ApplyError::Validity(err) } } -impl codec::EncodeLike for ApplyError {} +/// The outcome of applying a transaction. +pub type ApplyOutcome = Result<(), DispatchError>; + +impl From for ApplyOutcome { + fn from(err: DispatchError) -> Self { + Err(err) + } +} /// Result from attempt to apply an extrinsic. pub type ApplyResult = Result; +#[derive(Eq, PartialEq, Clone, Copy, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug, Serialize))] +/// Reason why a dispatch call failed +pub struct DispatchError { + /// Module index, matching the metadata module index + pub module: Option, + /// Module specific error value + pub error: u8, + /// Optional error message. + #[codec(skip)] + pub message: Option<&'static str>, +} + +impl DispatchError { + /// Create a new instance of `DispatchError`. + pub fn new(module: Option, error: u8, message: Option<&'static str>) -> Self { + Self { + module, + error, + message, + } + } +} + +impl runtime_io::Printable for DispatchError { + fn print(&self) { + "DispatchError".print(); + if let Some(module) = self.module { + module.print(); + } + self.error.print(); + if let Some(msg) = self.message { + msg.print(); + } + } +} + +impl traits::ModuleDispatchError for &'static str { + fn as_u8(&self) -> u8 { + 0 + } + + fn as_str(&self) -> &'static str { + self + } +} + +impl From<&'static str> for DispatchError { + fn from(err: &'static str) -> DispatchError { + DispatchError::new(None, 0, Some(err)) + } +} + /// Verify a signature on an encoded value in a lazy manner. This can be /// an optimization if the signature scheme has an "unsigned" escape hash. pub fn verify_encoded_lazy(sig: &V, item: &T, signer: &V::Signer) -> bool { @@ -852,6 +897,7 @@ impl traits::Extrinsic for OpaqueExtrinsic { #[cfg(test)] mod tests { + use super::DispatchError; use crate::codec::{Encode, Decode}; use super::{Perbill, Permill}; @@ -967,6 +1013,26 @@ mod tests { ); } + #[test] + fn dispatch_error_encoding() { + let error = DispatchError { + module: Some(1), + error: 2, + message: Some("error message"), + }; + let encoded = error.encode(); + let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); + assert_eq!(encoded, vec![1, 1, 2]); + assert_eq!( + decoded, + DispatchError { + module: Some(1), + error: 2, + message: None, + }, + ); + } + #[test] fn per_bill_square() { const FIXTURES: &[(u32, u32)] = &[ diff --git a/core/sr-primitives/src/testing.rs b/core/sr-primitives/src/testing.rs index ed5ac7fa45..9c827d8a70 100644 --- a/core/sr-primitives/src/testing.rs +++ b/core/sr-primitives/src/testing.rs @@ -20,14 +20,14 @@ use serde::{Serialize, Serializer, Deserialize, de::Error as DeError, Deserializ use std::{fmt::Debug, ops::Deref, fmt}; use crate::codec::{Codec, Encode, Decode}; use crate::traits::{ - self, Checkable, Applyable, BlakeTwo256, OpaqueKeys, DispatchError, DispatchResult, - ValidateUnsigned, SignedExtension, Dispatchable, + self, Checkable, Applyable, BlakeTwo256, OpaqueKeys, ValidateUnsigned, + SignedExtension, Dispatchable, }; -use crate::{generic, KeyTypeId}; +use crate::{generic, KeyTypeId, ApplyResult}; use crate::weights::{GetDispatchInfo, DispatchInfo}; pub use primitives::H256; use primitives::{crypto::{CryptoType, Dummy, key_types, Public}, U256}; -use crate::transaction_validity::TransactionValidity; +use crate::transaction_validity::{TransactionValidity, TransactionValidityError}; /// Authority Id #[derive(Default, PartialEq, Eq, Clone, Encode, Decode, Debug, Hash, Serialize, Deserialize)] @@ -271,7 +271,7 @@ impl Debug for TestXt { impl Checkable for TestXt { type Checked = Self; - fn check(self, _: &Context) -> Result { Ok(self) } + fn check(self, _: &Context) -> Result { Ok(self) } } impl traits::Extrinsic for TestXt { type Call = Call; @@ -289,7 +289,7 @@ impl traits::Extrinsic for TestXt impl Applyable for TestXt where Call: 'static + Sized + Send + Sync + Clone + Eq + Codec + Debug + Dispatchable, Extra: SignedExtension, - Origin: From> + Origin: From>, { type AccountId = u64; type Call = Call; @@ -297,19 +297,21 @@ impl Applyable for TestXt where fn sender(&self) -> Option<&Self::AccountId> { self.0.as_ref().map(|x| &x.0) } /// Checks to see if this is a valid *transaction*. It returns information on it if so. - fn validate>(&self, + fn validate>( + &self, _info: DispatchInfo, _len: usize, ) -> TransactionValidity { - TransactionValidity::Valid(Default::default()) + Ok(Default::default()) } /// Executes all necessary logic needed prior to dispatch and deconstructs into function call, /// index and sender. - fn dispatch(self, + fn apply( + self, info: DispatchInfo, len: usize, - ) -> Result { + ) -> ApplyResult { let maybe_who = if let Some((who, extra)) = self.0 { Extra::pre_dispatch(extra, &who, &self.1, info, len)?; Some(who) @@ -317,7 +319,8 @@ impl Applyable for TestXt where Extra::pre_dispatch_unsigned(&self.1, info, len)?; None }; - Ok(self.1.dispatch(maybe_who.into())) + + Ok(self.1.dispatch(maybe_who.into()).map_err(Into::into)) } } diff --git a/core/sr-primitives/src/traits.rs b/core/sr-primitives/src/traits.rs index fe3d67268f..0ac40e9942 100644 --- a/core/sr-primitives/src/traits.rs +++ b/core/sr-primitives/src/traits.rs @@ -23,7 +23,9 @@ use runtime_io; #[cfg(feature = "std")] use serde::{Serialize, Deserialize, de::DeserializeOwned}; use primitives::{self, Hasher, Blake2Hasher}; use crate::codec::{Codec, Encode, Decode, HasCompact}; -use crate::transaction_validity::{ValidTransaction, TransactionValidity}; +use crate::transaction_validity::{ + ValidTransaction, TransactionValidity, TransactionValidityError, UnknownTransaction, +}; use crate::generic::{Digest, DigestItem}; use crate::weights::DispatchInfo; pub use integer_sqrt::IntegerSquareRoot; @@ -93,18 +95,44 @@ impl< } } +/// An error type that indicates that the origin is invalid. +#[derive(Encode, Decode)] +pub struct InvalidOrigin; + +impl From for &'static str { + fn from(_: InvalidOrigin) -> &'static str { + "Invalid origin" + } +} + /// Some sort of check on the origin is performed by this object. pub trait EnsureOrigin { /// A return type. type Success; /// Perform the origin check. - fn ensure_origin(o: OuterOrigin) -> result::Result { - Self::try_origin(o).map_err(|_| "Invalid origin") + fn ensure_origin(o: OuterOrigin) -> result::Result { + Self::try_origin(o).map_err(|_| InvalidOrigin) } /// Perform the origin check. fn try_origin(o: OuterOrigin) -> result::Result; } +/// An error that indicates that a lookup failed. +#[derive(Encode, Decode)] +pub struct LookupError; + +impl From for &'static str { + fn from(_: LookupError) -> &'static str { + "Can not lookup" + } +} + +impl From for TransactionValidityError { + fn from(_: LookupError) -> Self { + UnknownTransaction::CannotLookup.into() + } +} + /// Means of changing one type into another in a manner dependent on the source type. pub trait Lookup { /// Type to lookup from. @@ -112,7 +140,7 @@ pub trait Lookup { /// Type to lookup into. type Target; /// Attempt a lookup. - fn lookup(&self, s: Self::Source) -> result::Result; + fn lookup(&self, s: Self::Source) -> Result; } /// Means of changing one type into another in a manner dependent on the source type. @@ -124,7 +152,7 @@ pub trait StaticLookup { /// Type to lookup into. type Target; /// Attempt a lookup. - fn lookup(s: Self::Source) -> result::Result; + fn lookup(s: Self::Source) -> Result; /// Convert from Target back to Source. fn unlookup(t: Self::Target) -> Self::Source; } @@ -135,13 +163,14 @@ pub struct IdentityLookup(PhantomData); impl StaticLookup for IdentityLookup { type Source = T; type Target = T; - fn lookup(x: T) -> result::Result { Ok(x) } + fn lookup(x: T) -> Result { Ok(x) } fn unlookup(x: T) -> T { x } } + impl Lookup for IdentityLookup { type Source = T; type Target = T; - fn lookup(&self, x: T) -> result::Result { Ok(x) } + fn lookup(&self, x: T) -> Result { Ok(x) } } /// Extensible conversion trait. Generic over both source and destination types. @@ -781,7 +810,7 @@ pub trait Checkable: Sized { type Checked; /// Check self, given an instance of Context. - fn check(self, c: &Context) -> Result; + fn check(self, c: &Context) -> Result; } /// A "checkable" piece of information, used by the standard Substrate Executive in order to @@ -793,61 +822,21 @@ pub trait BlindCheckable: Sized { type Checked; /// Check self. - fn check(self) -> Result; + fn check(self) -> Result; } // Every `BlindCheckable` is also a `StaticCheckable` for arbitrary `Context`. impl Checkable for T { type Checked = ::Checked; - fn check(self, _c: &Context) -> Result { - BlindCheckable::check(self) - } -} - -/// An abstract error concerning an attempt to verify, check or dispatch the transaction. This -/// cannot be more concrete because it's designed to work reasonably well over a broad range of -/// possible transaction types. -#[cfg_attr(feature = "std", derive(PartialEq, Debug))] -pub enum DispatchError { - /// General error to do with the inability to pay some fees (e.g. account balance too low). - Payment, - - /// General error to do with the exhaustion of block resources. - Exhausted, - /// General error to do with the permissions of the sender. - NoPermission, - - /// General error to do with the state of the system in general. - BadState, - - /// General error to do with the transaction being outdated (e.g. nonce too low). - Stale, - - /// General error to do with the transaction not yet being valid (e.g. nonce too high). - Future, - - /// General error to do with the transaction's proofs (e.g. signature). - BadProof, -} - -impl From for i8 { - fn from(e: DispatchError) -> i8 { - match e { - DispatchError::Payment => -64, - DispatchError::Exhausted => -65, - DispatchError::NoPermission => -66, - DispatchError::BadState => -67, - DispatchError::Stale => -68, - DispatchError::Future => -69, - DispatchError::BadProof => -70, - } + fn check(self, _c: &Context) -> Result { + BlindCheckable::check(self) } } /// Result of a module function call; either nothing (functions are only called for "side effects") /// or an error message. -pub type DispatchResult = result::Result<(), &'static str>; +pub type DispatchResult = result::Result<(), Error>; /// A lazy call (module function and argument values) that can be executed via its `dispatch` /// method. @@ -858,15 +847,15 @@ pub trait Dispatchable { type Origin; /// ... type Trait; + /// The error type returned by this dispatchable. + type Error: Into; /// Actually dispatch this call and result the result of it. - fn dispatch(self, origin: Self::Origin) -> DispatchResult; + fn dispatch(self, origin: Self::Origin) -> DispatchResult; } /// Means by which a transaction may be extended. This type embodies both the data and the logic /// that should be additionally associated with the transaction. It should be plain old data. -pub trait SignedExtension: - Codec + MaybeDebug + Sync + Send + Clone + Eq + PartialEq -{ +pub trait SignedExtension: Codec + MaybeDebug + Sync + Send + Clone + Eq + PartialEq { /// The type which encodes the sender identity. type AccountId; @@ -882,7 +871,7 @@ pub trait SignedExtension: /// Construct any additional data that should be in the signed payload of the transaction. Can /// also perform any pre-signature-verification checks and return an error if needed. - fn additional_signed(&self) -> Result; + fn additional_signed(&self) -> Result; /// Validate a signed transaction for the transaction queue. /// @@ -899,8 +888,8 @@ pub trait SignedExtension: _call: &Self::Call, _info: DispatchInfo, _len: usize, - ) -> Result { - Ok(Default::default()) + ) -> TransactionValidity { + Ok(ValidTransaction::default()) } /// Do any pre-flight stuff for a signed transaction. @@ -917,8 +906,10 @@ pub trait SignedExtension: call: &Self::Call, info: DispatchInfo, len: usize, - ) -> Result { - self.validate(who, call, info, len).map(|_| Self::Pre::default()) + ) -> Result { + self.validate(who, call, info, len) + .map(|_| Self::Pre::default()) + .map_err(Into::into) } /// Validate an unsigned transaction for the transaction queue. @@ -936,7 +927,9 @@ pub trait SignedExtension: _call: &Self::Call, _info: DispatchInfo, _len: usize, - ) -> Result { Ok(Default::default()) } + ) -> TransactionValidity { + Ok(ValidTransaction::default()) + } /// Do any pre-flight stuff for a unsigned transaction. /// @@ -950,16 +943,25 @@ pub trait SignedExtension: call: &Self::Call, info: DispatchInfo, len: usize, - ) -> Result { - Self::validate_unsigned(call, info, len).map(|_| Self::Pre::default()) + ) -> Result { + Self::validate_unsigned(call, info, len) + .map(|_| Self::Pre::default()) + .map_err(Into::into) } /// Do any post-flight stuff for a transaction. - fn post_dispatch( - _pre: Self::Pre, - _info: DispatchInfo, - _len: usize, - ) { } + fn post_dispatch(_pre: Self::Pre, _info: DispatchInfo, _len: usize) { } +} + +/// An error that is returned by a dispatchable function of a module. +pub trait ModuleDispatchError { + /// Convert this error to an `u8`. + /// + /// The `u8` corresponds to the index of the variant in the error enum. + fn as_u8(&self) -> u8; + + /// Convert the error to a `&'static str`. + fn as_str(&self) -> &'static str; } macro_rules! tuple_impl_indexed { @@ -974,10 +976,10 @@ macro_rules! tuple_impl_indexed { > SignedExtension for ($($direct),+,) { type AccountId = AccountId; type Call = Call; - type AdditionalSigned = ($($direct::AdditionalSigned,)+); + type AdditionalSigned = ( $( $direct::AdditionalSigned, )+ ); type Pre = ($($direct::Pre,)+); - fn additional_signed(&self) -> Result { - Ok(( $(self.$index.additional_signed()?,)+ )) + fn additional_signed(&self) -> Result { + Ok(( $( self.$index.additional_signed()?, )+ )) } fn validate( &self, @@ -985,9 +987,16 @@ macro_rules! tuple_impl_indexed { call: &Self::Call, info: DispatchInfo, len: usize, - ) -> Result { - let aggregator = vec![$(<$direct as SignedExtension>::validate(&self.$index, who, call, info, len)?),+]; - Ok(aggregator.into_iter().fold(ValidTransaction::default(), |acc, a| acc.combine_with(a))) + ) -> TransactionValidity { + let aggregator = vec![ + $( <$direct as SignedExtension>::validate(&self.$index, who, call, info, len)? ),+ + ]; + Ok( + aggregator.into_iter().fold( + ValidTransaction::default(), + |acc, a| acc.combine_with(a), + ) + ) } fn pre_dispatch( self, @@ -995,22 +1004,28 @@ macro_rules! tuple_impl_indexed { call: &Self::Call, info: DispatchInfo, len: usize, - ) -> Result { + ) -> Result { Ok(($(self.$index.pre_dispatch(who, call, info, len)?,)+)) } fn validate_unsigned( call: &Self::Call, info: DispatchInfo, len: usize, - ) -> Result { - let aggregator = vec![$($direct::validate_unsigned(call, info, len)?),+]; - Ok(aggregator.into_iter().fold(ValidTransaction::default(), |acc, a| acc.combine_with(a))) + ) -> TransactionValidity { + let aggregator = vec![ $( $direct::validate_unsigned(call, info, len)? ),+ ]; + + Ok( + aggregator.into_iter().fold( + ValidTransaction::default(), + |acc, a| acc.combine_with(a), + ) + ) } fn pre_dispatch_unsigned( call: &Self::Call, info: DispatchInfo, len: usize, - ) -> Result { + ) -> Result { Ok(($($direct::pre_dispatch_unsigned(call, info, len)?,)+)) } fn post_dispatch( @@ -1047,7 +1062,7 @@ impl SignedExtension for () { type AdditionalSigned = (); type Call = (); type Pre = (); - fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) } + fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } } /// An "executable" piece of information, used by the standard Substrate Executive in order to @@ -1067,17 +1082,19 @@ pub trait Applyable: Sized + Send + Sync { fn sender(&self) -> Option<&Self::AccountId>; /// Checks to see if this is a valid *transaction*. It returns information on it if so. - fn validate>(&self, + fn validate>( + &self, info: DispatchInfo, len: usize, ) -> TransactionValidity; /// Executes all necessary logic needed prior to dispatch and deconstructs into function call, /// index and sender. - fn dispatch(self, + fn apply( + self, info: DispatchInfo, len: usize, - ) -> Result; + ) -> crate::ApplyResult; } /// Auxiliary wrapper that holds an api instance and binds it to the given lifetime. diff --git a/core/sr-primitives/src/transaction_validity.rs b/core/sr-primitives/src/transaction_validity.rs index 4d5d53baf1..eb6cf3bdbb 100644 --- a/core/sr-primitives/src/transaction_validity.rs +++ b/core/sr-primitives/src/transaction_validity.rs @@ -17,8 +17,7 @@ //! Transaction validity interface. use rstd::prelude::*; -use crate::codec::{Encode, Decode, Error}; -use crate::traits::DispatchError; +use crate::codec::{Encode, Decode}; /// Priority for a transaction. Additive. Higher is better. pub type TransactionPriority = u64; @@ -30,29 +29,151 @@ pub type TransactionLongevity = u64; /// Tag for a transaction. No two transactions with the same tag should be placed on-chain. pub type TransactionTag = Vec; -/// Information on a transaction's validity and, if valid, on how it relates to other transactions. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Debug))] -pub enum TransactionValidity { - /// Transaction is invalid. Details are described by the error code. - Invalid(i8), - /// Transaction is valid. - Valid(ValidTransaction), +/// An invalid transaction validity. +#[derive(Clone, PartialEq, Eq, Encode, Decode, Copy)] +#[cfg_attr(feature = "std", derive(Debug, serde::Serialize))] +pub enum InvalidTransaction { + /// The call of the transaction is not expected. + Call, + /// General error to do with the inability to pay some fees (e.g. account balance too low). + Payment, + /// General error to do with the transaction not yet being valid (e.g. nonce too high). + Future, + /// General error to do with the transaction being outdated (e.g. nonce too low). + Stale, + /// General error to do with the transaction's proofs (e.g. signature). + BadProof, + /// The transaction birth block is ancient. + AncientBirthBlock, + /// The transaction would exhaust the resources of current block. + /// + /// The transaction might be valid, but there are not enough resources left in the current block. + ExhaustsResources, + /// Any other custom invalid validity that is not covered by this enum. + Custom(u8), +} + +impl InvalidTransaction { + /// Returns if the reason for the invalidity was block resource exhaustion. + pub fn exhausted_resources(&self) -> bool { + match self { + Self::ExhaustsResources => true, + _ => false, + } + } +} + +impl From for &'static str { + fn from(invalid: InvalidTransaction) -> &'static str { + match invalid { + InvalidTransaction::Call => "Transaction call is not expected", + InvalidTransaction::Future => "Transaction will be valid in the future", + InvalidTransaction::Stale => "Transaction is outdated", + InvalidTransaction::BadProof => "Transaction has a bad signature", + InvalidTransaction::AncientBirthBlock => "Transaction has an ancient birth block", + InvalidTransaction::ExhaustsResources => + "Transaction would exhausts the block limits", + InvalidTransaction::Payment => + "Inability to pay some fees (e.g. account balance too low)", + InvalidTransaction::Custom(_) => "InvalidTransaction custom error", + } + } +} + +/// An unknown transaction validity. +#[derive(Clone, PartialEq, Eq, Encode, Decode, Copy)] +#[cfg_attr(feature = "std", derive(Debug, serde::Serialize))] +pub enum UnknownTransaction { + /// Could not lookup some information that is required to validate the transaction. + CannotLookup, + /// No validator found for the given unsigned transaction. + NoUnsignedValidator, + /// Any other custom unknown validity that is not covered by this enum. + Custom(u8), +} + +impl From for &'static str { + fn from(unknown: UnknownTransaction) -> &'static str { + match unknown { + UnknownTransaction::CannotLookup => + "Could not lookup information required to validate the transaction", + UnknownTransaction::NoUnsignedValidator => + "Could not find an unsigned validator for the unsigned transaction", + UnknownTransaction::Custom(_) => "UnknownTransaction custom error", + } + } +} + +/// Errors that can occur while checking the validity of a transaction. +#[derive(Clone, PartialEq, Eq, Encode, Decode, Copy)] +#[cfg_attr(feature = "std", derive(Debug, serde::Serialize))] +pub enum TransactionValidityError { + /// The transaction is invalid. + Invalid(InvalidTransaction), /// Transaction validity can't be determined. - Unknown(i8), + Unknown(UnknownTransaction), +} + +impl TransactionValidityError { + /// Returns `true` if the reason for the error was block resource exhaustion. + pub fn exhausted_resources(&self) -> bool { + match self { + Self::Invalid(e) => e.exhausted_resources(), + Self::Unknown(_) => false, + } + } } -impl From> for TransactionValidity { - fn from(r: Result) -> Self { - match r { - Ok(v) => TransactionValidity::Valid(v), - Err(e) => TransactionValidity::Invalid(e.into()), +impl From for &'static str { + fn from(err: TransactionValidityError) -> &'static str { + match err { + TransactionValidityError::Invalid(invalid) => invalid.into(), + TransactionValidityError::Unknown(unknown) => unknown.into(), } } } +impl From for TransactionValidityError { + fn from(err: InvalidTransaction) -> Self { + TransactionValidityError::Invalid(err) + } +} + +impl From for TransactionValidityError { + fn from(err: UnknownTransaction) -> Self { + TransactionValidityError::Unknown(err) + } +} + +impl From for crate::ApplyError { + fn from(invalid: InvalidTransaction) -> crate::ApplyError { + TransactionValidityError::from(invalid).into() + } +} + +impl From for crate::ApplyError { + fn from(unknown: UnknownTransaction) -> crate::ApplyError { + TransactionValidityError::from(unknown).into() + } +} + +/// Information on a transaction's validity and, if valid, on how it relates to other transactions. +pub type TransactionValidity = Result; + +impl Into for InvalidTransaction { + fn into(self) -> TransactionValidity { + Err(self.into()) + } +} + +impl Into for UnknownTransaction { + fn into(self) -> TransactionValidity { + Err(self.into()) + } +} + /// Information concerning a valid transaction. -#[derive(Clone, PartialEq, Eq, Encode)] +#[derive(Clone, PartialEq, Eq, Encode, Decode)] #[cfg_attr(feature = "std", derive(Debug))] pub struct ValidTransaction { /// Priority of the transaction. @@ -112,49 +233,13 @@ impl ValidTransaction { } } -impl Decode for TransactionValidity { - fn decode(value: &mut I) -> Result { - match value.read_byte()? { - 0 => Ok(TransactionValidity::Invalid(i8::decode(value)?)), - 1 => { - let priority = TransactionPriority::decode(value)?; - let requires = Vec::decode(value)?; - let provides = Vec::decode(value)?; - let longevity = TransactionLongevity::decode(value)?; - let propagate = bool::decode(value).unwrap_or(true); - - Ok(TransactionValidity::Valid(ValidTransaction { - priority, requires, provides, longevity, propagate, - })) - }, - 2 => Ok(TransactionValidity::Unknown(i8::decode(value)?)), - _ => Err("Invalid transaction validity variant".into()), - } - } -} - #[cfg(test)] mod tests { use super::*; - #[test] - fn should_decode_with_backward_compat() { - let old_encoding = vec![ - 1, 5, 0, 0, 0, 0, 0, 0, 0, 4, 16, 1, 2, 3, 4, 4, 12, 4, 5, 6, 42, 0, 0, 0, 0, 0, 0, 0 - ]; - - assert_eq!(TransactionValidity::decode(&mut &*old_encoding), Ok(TransactionValidity::Valid(ValidTransaction { - priority: 5, - requires: vec![vec![1, 2, 3, 4]], - provides: vec![vec![4, 5, 6]], - longevity: 42, - propagate: true, - }))); - } - #[test] fn should_encode_and_decode() { - let v = TransactionValidity::Valid(ValidTransaction { + let v: TransactionValidity = Ok(ValidTransaction { priority: 5, requires: vec![vec![1, 2, 3, 4]], provides: vec![vec![4, 5, 6]], @@ -165,7 +250,7 @@ mod tests { let encoded = v.encode(); assert_eq!( encoded, - vec![1, 5, 0, 0, 0, 0, 0, 0, 0, 4, 16, 1, 2, 3, 4, 4, 12, 4, 5, 6, 42, 0, 0, 0, 0, 0, 0, 0, 0] + vec![0, 5, 0, 0, 0, 0, 0, 0, 0, 4, 16, 1, 2, 3, 4, 4, 12, 4, 5, 6, 42, 0, 0, 0, 0, 0, 0, 0, 0] ); // decode back diff --git a/core/test-runtime/src/lib.rs b/core/test-runtime/src/lib.rs index f023fd89e1..ec7ed9670c 100644 --- a/core/test-runtime/src/lib.rs +++ b/core/test-runtime/src/lib.rs @@ -38,7 +38,9 @@ use substrate_client::{ }; use sr_primitives::{ ApplyResult, create_runtime_str, Perbill, impl_opaque_keys, - transaction_validity::{TransactionValidity, ValidTransaction}, + transaction_validity::{ + TransactionValidity, ValidTransaction, TransactionValidityError, InvalidTransaction, + }, traits::{ BlindCheckable, BlakeTwo256, Block as BlockT, Extrinsic as ExtrinsicT, GetNodeBlockType, GetRuntimeBlockType, Verify, IdentityLookup, @@ -123,17 +125,17 @@ impl serde::Serialize for Extrinsic { impl BlindCheckable for Extrinsic { type Checked = Self; - fn check(self) -> Result { + fn check(self) -> Result { match self { Extrinsic::AuthoritiesChange(new_auth) => Ok(Extrinsic::AuthoritiesChange(new_auth)), Extrinsic::Transfer(transfer, signature) => { if sr_primitives::verify_encoded_lazy(&signature, &transfer, &transfer.from) { Ok(Extrinsic::Transfer(transfer, signature)) } else { - Err(sr_primitives::BAD_SIGNATURE) + Err(InvalidTransaction::BadProof.into()) } }, - Extrinsic::IncludeData(_) => Err(sr_primitives::BAD_SIGNATURE), + Extrinsic::IncludeData(_) => Err(InvalidTransaction::BadProof.into()), Extrinsic::StorageChange(key, value) => Ok(Extrinsic::StorageChange(key, value)), } } @@ -478,7 +480,7 @@ cfg_if! { impl client_api::TaggedTransactionQueue for Runtime { fn validate_transaction(utx: ::Extrinsic) -> TransactionValidity { if let Extrinsic::IncludeData(data) = utx { - return TransactionValidity::Valid(ValidTransaction { + return Ok(ValidTransaction { priority: data.len() as u64, requires: vec![], provides: vec![data], @@ -662,7 +664,7 @@ cfg_if! { impl client_api::TaggedTransactionQueue for Runtime { fn validate_transaction(utx: ::Extrinsic) -> TransactionValidity { if let Extrinsic::IncludeData(data) = utx { - return TransactionValidity::Valid(ValidTransaction{ + return Ok(ValidTransaction{ priority: data.len() as u64, requires: vec![], provides: vec![data], diff --git a/core/test-runtime/src/system.rs b/core/test-runtime/src/system.rs index 63f9c0050b..f1288f8b28 100644 --- a/core/test-runtime/src/system.rs +++ b/core/test-runtime/src/system.rs @@ -21,12 +21,12 @@ use rstd::prelude::*; use runtime_io::{storage_root, ordered_trie_root, storage_changes_root, twox_128, blake2_256}; use runtime_support::storage::{self, StorageValue, StorageMap}; use runtime_support::storage_items; -use sr_primitives::traits::{Hash as HashT, BlakeTwo256, Header as _}; -use sr_primitives::generic; -use sr_primitives::{ApplyError, ApplyOutcome, ApplyResult}; -use sr_primitives::transaction_validity::{TransactionValidity, ValidTransaction}; +use sr_primitives::{ + traits::{Hash as HashT, BlakeTwo256, Header as _}, generic, ApplyError, ApplyResult, + transaction_validity::{TransactionValidity, ValidTransaction, InvalidTransaction}, +}; use codec::{KeyedVec, Encode}; -use super::{ +use crate::{ AccountId, BlockNumber, Extrinsic, Transfer, H256 as Hash, Block, Header, Digest, AuthorityId }; use primitives::{Blake2Hasher, storage::well_known_keys}; @@ -119,7 +119,7 @@ fn execute_block_with_state_root_handler( // execute transactions block.extrinsics.iter().enumerate().for_each(|(i, e)| { storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &(i as u32)); - execute_transaction_backend(e).unwrap_or_else(|_| panic!("Invalid transaction")); + let _ = execute_transaction_backend(e).unwrap_or_else(|_| panic!("Invalid transaction")); storage::unhashed::kill(well_known_keys::EXTRINSIC_INDEX); }); @@ -158,17 +158,17 @@ impl executive::ExecuteBlock for BlockExecutor { /// This doesn't attempt to validate anything regarding the block. pub fn validate_transaction(utx: Extrinsic) -> TransactionValidity { if check_signature(&utx).is_err() { - return TransactionValidity::Invalid(ApplyError::BadSignature as i8); + return InvalidTransaction::BadProof.into(); } let tx = utx.transfer(); let nonce_key = tx.from.to_keyed_vec(NONCE_OF); let expected_nonce: u64 = storage::hashed::get_or(&blake2_256, &nonce_key, 0); if tx.nonce < expected_nonce { - return TransactionValidity::Invalid(ApplyError::Stale as i8); + return InvalidTransaction::Stale.into(); } if tx.nonce > expected_nonce + 64 { - return TransactionValidity::Unknown(ApplyError::Future as i8); + return InvalidTransaction::Future.into(); } let hash = |from: &AccountId, nonce: u64| { @@ -188,7 +188,7 @@ pub fn validate_transaction(utx: Extrinsic) -> TransactionValidity { p }; - TransactionValidity::Valid(ValidTransaction { + Ok(ValidTransaction { priority: tx.amount, requires, provides, @@ -244,8 +244,7 @@ pub fn finalize_block() -> Header { #[inline(always)] fn check_signature(utx: &Extrinsic) -> Result<(), ApplyError> { use sr_primitives::traits::BlindCheckable; - utx.clone().check().map_err(|_| ApplyError::BadSignature)?; - Ok(()) + utx.clone().check().map_err(|_| InvalidTransaction::BadProof.into()).map(|_| ()) } fn execute_transaction_backend(utx: &Extrinsic) -> ApplyResult { @@ -253,7 +252,7 @@ fn execute_transaction_backend(utx: &Extrinsic) -> ApplyResult { match utx { Extrinsic::Transfer(ref transfer, _) => execute_transfer_backend(transfer), Extrinsic::AuthoritiesChange(ref new_auth) => execute_new_authorities_backend(new_auth), - Extrinsic::IncludeData(_) => Ok(ApplyOutcome::Success), + Extrinsic::IncludeData(_) => Ok(Ok(())), Extrinsic::StorageChange(key, value) => execute_storage_change(key, value.as_ref().map(|v| &**v)), } } @@ -263,7 +262,7 @@ fn execute_transfer_backend(tx: &Transfer) -> ApplyResult { let nonce_key = tx.from.to_keyed_vec(NONCE_OF); let expected_nonce: u64 = storage::hashed::get_or(&blake2_256, &nonce_key, 0); if !(tx.nonce == expected_nonce) { - return Err(ApplyError::Stale) + return Err(InvalidTransaction::Stale.into()); } // increment nonce in storage @@ -275,18 +274,18 @@ fn execute_transfer_backend(tx: &Transfer) -> ApplyResult { // enact transfer if !(tx.amount <= from_balance) { - return Err(ApplyError::CantPay) + return Err(InvalidTransaction::Payment.into()); } let to_balance_key = tx.to.to_keyed_vec(BALANCE_OF); let to_balance: u64 = storage::hashed::get_or(&blake2_256, &to_balance_key, 0); storage::hashed::put(&blake2_256, &from_balance_key, &(from_balance - tx.amount)); storage::hashed::put(&blake2_256, &to_balance_key, &(to_balance + tx.amount)); - Ok(ApplyOutcome::Success) + Ok(Ok(())) } fn execute_new_authorities_backend(new_authorities: &[AuthorityId]) -> ApplyResult { NewAuthorities::put(new_authorities.to_vec()); - Ok(ApplyOutcome::Success) + Ok(Ok(())) } fn execute_storage_change(key: &[u8], value: Option<&[u8]>) -> ApplyResult { @@ -294,7 +293,7 @@ fn execute_storage_change(key: &[u8], value: Option<&[u8]>) -> ApplyResult { Some(value) => storage::unhashed::put_raw(key, value), None => storage::unhashed::kill(key), } - Ok(ApplyOutcome::Success) + Ok(Ok(())) } #[cfg(feature = "std")] @@ -304,7 +303,7 @@ fn info_expect_equal_hash(given: &Hash, expected: &Hash) { println!( "Hash: given={}, expected={}", HexDisplay::from(given.as_fixed_bytes()), - HexDisplay::from(expected.as_fixed_bytes()) + HexDisplay::from(expected.as_fixed_bytes()), ); } } @@ -312,9 +311,9 @@ fn info_expect_equal_hash(given: &Hash, expected: &Hash) { #[cfg(not(feature = "std"))] fn info_expect_equal_hash(given: &Hash, expected: &Hash) { if given != expected { - ::runtime_io::print("Hash not equal"); - ::runtime_io::print(given.as_bytes()); - ::runtime_io::print(expected.as_bytes()); + runtime_io::print("Hash not equal"); + runtime_io::print(given.as_bytes()); + runtime_io::print(expected.as_bytes()); } } diff --git a/core/transaction-pool/graph/src/error.rs b/core/transaction-pool/graph/src/error.rs index ce457c0179..79006461c6 100644 --- a/core/transaction-pool/graph/src/error.rs +++ b/core/transaction-pool/graph/src/error.rs @@ -16,7 +16,9 @@ //! Transaction pool errors. -use sr_primitives::transaction_validity::TransactionPriority as Priority; +use sr_primitives::transaction_validity::{ + TransactionPriority as Priority, InvalidTransaction, UnknownTransaction, +}; /// Transaction pool result. pub type Result = std::result::Result; @@ -25,11 +27,11 @@ pub type Result = std::result::Result; #[derive(Debug, derive_more::Display, derive_more::From)] pub enum Error { /// Transaction is not verifiable yet, but might be in the future. - #[display(fmt="Unkown Transaction Validity. Error code: {}", _0)] - UnknownTransactionValidity(i8), + #[display(fmt="Unknown transaction validity: {:?}", _0)] + UnknownTransaction(UnknownTransaction), /// Transaction is invalid. - #[display(fmt="Invalid Transaction. Error Code: {}", _0)] - InvalidTransaction(i8), + #[display(fmt="Invalid transaction validity: {:?}", _0)] + InvalidTransaction(InvalidTransaction), /// The transaction validity returned no "provides" tag. /// /// Such transactions are not accepted to the pool, since we use those tags diff --git a/core/transaction-pool/graph/src/pool.rs b/core/transaction-pool/graph/src/pool.rs index fa09132d29..75a4bc4394 100644 --- a/core/transaction-pool/graph/src/pool.rs +++ b/core/transaction-pool/graph/src/pool.rs @@ -34,7 +34,7 @@ use parking_lot::{Mutex, RwLock}; use sr_primitives::{ generic::BlockId, traits::{self, SaturatedConversion}, - transaction_validity::{TransactionValidity, TransactionTag as Tag}, + transaction_validity::{TransactionValidity, TransactionTag as Tag, TransactionValidityError}, }; pub use crate::base_pool::Limit; @@ -129,7 +129,7 @@ impl Pool { } match self.api.validate_transaction(at, xt.clone())? { - TransactionValidity::Valid(validity) => if validity.provides.is_empty() { + Ok(validity) => if validity.provides.is_empty() { Err(error::Error::NoTagsProvided.into()) } else { Ok(base::Transaction { @@ -145,12 +145,12 @@ impl Pool { .saturating_add(validity.longevity), }) }, - TransactionValidity::Invalid(e) => { + Err(TransactionValidityError::Invalid(e)) => { Err(error::Error::InvalidTransaction(e).into()) }, - TransactionValidity::Unknown(e) => { + Err(TransactionValidityError::Unknown(e)) => { self.listener.write().invalid(&hash); - Err(error::Error::UnknownTransactionValidity(e).into()) + Err(error::Error::UnknownTransaction(e).into()) }, } }) @@ -244,7 +244,7 @@ impl Pool { None => { let validity = self.api.validate_transaction(parent, extrinsic.clone()); match validity { - Ok(TransactionValidity::Valid(mut validity)) => { + Ok(Ok(mut validity)) => { tags.append(&mut validity.provides); }, // silently ignore invalid extrinsics, @@ -453,7 +453,7 @@ fn fire_events( #[cfg(test)] mod tests { use super::*; - use sr_primitives::transaction_validity::ValidTransaction; + use sr_primitives::transaction_validity::{ValidTransaction, InvalidTransaction}; use codec::Encode; use test_runtime::{Block, Extrinsic, Transfer, H256, AccountId}; use assert_matches::assert_matches; @@ -472,8 +472,11 @@ mod tests { type Error = error::Error; /// Verify extrinsic at given block. - fn validate_transaction(&self, at: &BlockId, uxt: ExtrinsicFor) -> Result { - + fn validate_transaction( + &self, + at: &BlockId, + uxt: ExtrinsicFor, + ) -> Result { let block_number = self.block_id_to_number(at)?.unwrap(); let nonce = uxt.transfer().nonce; @@ -488,9 +491,9 @@ mod tests { } if nonce < block_number { - Ok(TransactionValidity::Invalid(0)) + Ok(InvalidTransaction::Stale.into()) } else { - Ok(TransactionValidity::Valid(ValidTransaction { + Ok(Ok(ValidTransaction { priority: 4, requires: if nonce > block_number { vec![vec![nonce as u8 - 1]] } else { vec![] }, provides: if nonce == INVALID_NONCE { vec![] } else { vec![vec![nonce as u8]] }, diff --git a/core/transaction-pool/src/tests.rs b/core/transaction-pool/src/tests.rs index 71ed988e5e..1661b7108b 100644 --- a/core/transaction-pool/src/tests.rs +++ b/core/transaction-pool/src/tests.rs @@ -39,7 +39,11 @@ impl txpool::ChainApi for TestApi { type Hash = Hash; type Error = error::Error; - fn validate_transaction(&self, at: &BlockId, uxt: txpool::ExtrinsicFor) -> error::Result { + fn validate_transaction( + &self, + at: &BlockId, + uxt: txpool::ExtrinsicFor, + ) -> error::Result { let expected = index(at); let requires = if expected == uxt.transfer().nonce { vec![] @@ -48,13 +52,15 @@ impl txpool::ChainApi for TestApi { }; let provides = vec![vec![uxt.transfer().nonce as u8]]; - Ok(TransactionValidity::Valid(ValidTransaction { - priority: 1, - requires, - provides, - longevity: 64, - propagate: true, - })) + Ok( + Ok(ValidTransaction { + priority: 1, + requires, + provides, + longevity: 64, + propagate: true, + }) + ) } fn block_id_to_number(&self, at: &BlockId) -> error::Result>> { diff --git a/node-template/runtime/src/lib.rs b/node-template/runtime/src/lib.rs index 6a73a47d36..487937eab0 100644 --- a/node-template/runtime/src/lib.rs +++ b/node-template/runtime/src/lib.rs @@ -235,7 +235,6 @@ impl balances::Trait for Runtime { type OnNewAccount = Indices; /// The ubiquitous event type. type Event = Event; - type TransactionPayment = (); type DustRemoval = (); type TransferPayment = (); @@ -268,7 +267,7 @@ construct_runtime!( Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)}, Grandpa: grandpa::{Module, Call, Storage, Config, Event}, Indices: indices::{default, Config}, - Balances: balances, + Balances: balances::{default, Error}, Sudo: sudo, // Used for the module template in `./template.rs` TemplateModule: template::{Module, Call, Storage, Event}, diff --git a/node/cli/src/factory_impl.rs b/node/cli/src/factory_impl.rs index e371aef8e0..c16a8af6f8 100644 --- a/node/cli/src/factory_impl.rs +++ b/node/cli/src/factory_impl.rs @@ -56,7 +56,8 @@ impl FactoryState { system::CheckEra::from(Era::mortal(256, phase)), system::CheckNonce::from(index), system::CheckWeight::new(), - balances::TakeFees::from(0) + balances::TakeFees::from(0), + Default::default(), ) } } @@ -147,7 +148,7 @@ impl RuntimeAdapter for FactoryState { (*amount).into() ) ) - }, key, (version, genesis_hash.clone(), prior_block_hash.clone(), (), (), ())) + }, key, (version, genesis_hash.clone(), prior_block_hash.clone(), (), (), (), ())) } fn inherent_extrinsics(&self) -> InherentData { diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index bb1d77b285..509de7a943 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -470,11 +470,19 @@ mod tests { let check_nonce = system::CheckNonce::from(index); let check_weight = system::CheckWeight::new(); let take_fees = balances::TakeFees::from(0); - let extra = (check_version, check_genesis, check_era, check_nonce, check_weight, take_fees); + let extra = ( + check_version, + check_genesis, + check_era, + check_nonce, + check_weight, + take_fees, + Default::default(), + ); let raw_payload = SignedPayload::from_raw( function, extra, - (version, genesis_hash, genesis_hash, (), (), ()) + (version, genesis_hash, genesis_hash, (), (), (), ()) ); let signature = raw_payload.using_encoded(|payload| { signer.sign(payload) diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index 27b94df8b3..fc0ca39049 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -43,16 +43,16 @@ mod tests { use runtime_support::{Hashable, StorageValue, StorageMap, assert_eq_error_rate, traits::Currency}; use state_machine::{CodeExecutor, Externalities, TestExternalities as CoreTestExternalities}; use primitives::{Blake2Hasher, NeverNativeValue, NativeOrEncoded, map}; - use sr_primitives::traits::{Header as HeaderT, Hash as HashT, Convert}; - use sr_primitives::{ApplyOutcome, ApplyError, ApplyResult}; - use sr_primitives::weights::{WeightMultiplier, GetDispatchInfo}; + use node_primitives::{Hash, BlockNumber, Balance}; + use sr_primitives::{ + traits::{Header as HeaderT, Hash as HashT, Convert}, ApplyOutcome, ApplyResult, + transaction_validity::InvalidTransaction, weights::{WeightMultiplier, GetDispatchInfo}, + }; use contracts::ContractAddressFor; use system::{EventRecord, Phase}; - use node_primitives::{Hash, BlockNumber, Balance}; use node_runtime::{ Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances, BuildStorage, - System, Event, - TransferFee, TransactionBaseFee, TransactionByteFee, + System, Event, TransferFee, TransactionBaseFee, TransactionByteFee, }; use node_runtime::constants::currency::*; use node_runtime::impls::WeightToFee; @@ -150,7 +150,7 @@ mod tests { None, ).0.unwrap(); let r = ApplyResult::decode(&mut &v.as_encoded()[..]).unwrap(); - assert_eq!(r, Err(ApplyError::CantPay)); + assert_eq!(r, Err(InvalidTransaction::Payment.into())); } #[test] @@ -186,7 +186,7 @@ mod tests { None, ).0.unwrap(); let r = ApplyResult::decode(&mut &v.as_encoded()[..]).unwrap(); - assert_eq!(r, Err(ApplyError::CantPay)); + assert_eq!(r, Err(InvalidTransaction::Payment.into())); } #[test] @@ -763,7 +763,7 @@ mod tests { let r = WasmExecutor::new() .call(&mut t, 8, COMPACT_CODE, "BlockBuilder_apply_extrinsic", &vec![].and(&xt())).unwrap(); let r = ApplyResult::decode(&mut &r[..]).unwrap(); - assert_eq!(r, Err(ApplyError::CantPay)); + assert_eq!(r, Err(InvalidTransaction::Payment.into())); } #[test] @@ -784,8 +784,10 @@ mod tests { assert!(r.is_ok()); let r = WasmExecutor::new() .call(&mut t, 8, COMPACT_CODE, "BlockBuilder_apply_extrinsic", &vec![].and(&xt())).unwrap(); - let r = ApplyResult::decode(&mut &r[..]).unwrap(); - assert_eq!(r, Ok(ApplyOutcome::Success)); + ApplyResult::decode(&mut &r[..]) + .unwrap() + .expect("Extrinsic could be applied") + .expect("Extrinsic did not fail"); runtime_io::with_externalities(&mut t, || { assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - 1 * transfer_fee(&xt())); diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 03d11111f1..46667db36f 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -80,8 +80,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 154, - impl_version: 159, + spec_version: 155, + impl_version: 155, apis: RUNTIME_API_VERSIONS, }; @@ -445,6 +445,7 @@ impl system::offchain::CreateTransaction for Runtim system::CheckNonce::::from(index), system::CheckWeight::::new(), balances::TakeFees::::from(tip), + Default::default(), ); let raw_payload = SignedPayload::new(call, extra).ok()?; let signature = F::sign(account.clone(), &raw_payload)?; @@ -465,7 +466,7 @@ construct_runtime!( Timestamp: timestamp::{Module, Call, Storage, Inherent}, Authorship: authorship::{Module, Call, Storage, Inherent}, Indices: indices, - Balances: balances, + Balances: balances::{default, Error}, Staking: staking::{default, OfflineWorker}, Session: session::{Module, Call, Storage, Event, Config}, Democracy: democracy::{Module, Call, Storage, Config, Event}, @@ -501,7 +502,8 @@ pub type SignedExtra = ( system::CheckEra, system::CheckNonce, system::CheckWeight, - balances::TakeFees + balances::TakeFees, + contracts::CheckBlockGasLimit, ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; diff --git a/node/testing/src/keyring.rs b/node/testing/src/keyring.rs index 12a3e7c2d4..0c6eb478cc 100644 --- a/node/testing/src/keyring.rs +++ b/node/testing/src/keyring.rs @@ -72,7 +72,8 @@ pub fn signed_extra(nonce: Index, extra_fee: Balance) -> SignedExtra { system::CheckEra::from(Era::mortal(256, 0)), system::CheckNonce::from(nonce), system::CheckWeight::new(), - balances::TakeFees::from(extra_fee) + balances::TakeFees::from(extra_fee), + Default::default(), ) } diff --git a/srml/balances/src/lib.rs b/srml/balances/src/lib.rs index 80caa59f21..b865efa92a 100644 --- a/srml/balances/src/lib.rs +++ b/srml/balances/src/lib.rs @@ -161,19 +161,26 @@ use rstd::prelude::*; use rstd::{cmp, result, mem}; use codec::{Codec, Encode, Decode}; -use support::{StorageValue, StorageMap, Parameter, decl_event, decl_storage, decl_module}; -use support::traits::{ - UpdateBalanceOutcome, Currency, OnFreeBalanceZero, OnUnbalanced, - WithdrawReason, WithdrawReasons, LockIdentifier, LockableCurrency, ExistenceRequirement, - Imbalance, SignedImbalance, ReservableCurrency, Get, +use support::{ + StorageValue, StorageMap, Parameter, decl_event, decl_storage, decl_module, + traits::{ + UpdateBalanceOutcome, Currency, OnFreeBalanceZero, OnUnbalanced, + WithdrawReason, WithdrawReasons, LockIdentifier, LockableCurrency, ExistenceRequirement, + Imbalance, SignedImbalance, ReservableCurrency, Get, + }, + dispatch::Result, }; -use support::dispatch::Result; -use sr_primitives::traits::{ - Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub, MaybeSerializeDebug, - Saturating, Bounded, SignedExtension, SaturatedConversion, DispatchError, Convert, +use sr_primitives::{ + transaction_validity::{ + TransactionPriority, ValidTransaction, InvalidTransaction, TransactionValidityError, + TransactionValidity, + }, + traits::{ + Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub, MaybeSerializeDebug, + Saturating, Bounded, SignedExtension, SaturatedConversion, Convert, + }, + weights::{DispatchInfo, SimpleDispatchInfo, Weight}, }; -use sr_primitives::transaction_validity::{TransactionPriority, ValidTransaction}; -use sr_primitives::weights::{DispatchInfo, SimpleDispatchInfo, Weight}; use system::{IsDeadAccount, OnNewAccount, ensure_signed, ensure_root}; mod mock; @@ -1235,7 +1242,7 @@ impl, I: Instance + Clone + Eq> SignedExtension for TakeFees { type Call = T::Call; type AdditionalSigned = (); type Pre = (); - fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) } + fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } fn validate( &self, @@ -1243,15 +1250,18 @@ impl, I: Instance + Clone + Eq> SignedExtension for TakeFees { _call: &Self::Call, info: DispatchInfo, len: usize, - ) -> rstd::result::Result { + ) -> TransactionValidity { // pay any fees. let fee = Self::compute_fee(len, info, self.0); - let imbalance = >::withdraw( + let imbalance = match >::withdraw( who, fee, WithdrawReason::TransactionPayment, ExistenceRequirement::KeepAlive, - ).map_err(|_| DispatchError::Payment)?; + ) { + Ok(imbalance) => imbalance, + Err(_) => return InvalidTransaction::Payment.into(), + }; T::TransactionPayment::on_unbalanced(imbalance); let mut r = ValidTransaction::default(); diff --git a/srml/balances/src/tests.rs b/srml/balances/src/tests.rs index 777206910d..8e9f6acdd8 100644 --- a/srml/balances/src/tests.rs +++ b/srml/balances/src/tests.rs @@ -232,7 +232,7 @@ fn default_indexing_on_new_accounts_should_not_work2() { // ext_deposit is 10, value is 9, not satisfies for ext_deposit assert_noop!( Balances::transfer(Some(1).into(), 5, 9), - "value too low to create account" + "value too low to create account", ); assert_eq!(Balances::is_dead_account(&5), true); // account 5 should not exist assert_eq!(Balances::free_balance(&1), 100); @@ -359,7 +359,7 @@ fn force_transfer_works() { let _ = Balances::deposit_creating(&1, 111); assert_noop!( Balances::force_transfer(Some(2).into(), 1, 2, 69), - "bad origin: expected to be a root origin" + "RequireRootOrigin", ); assert_ok!(Balances::force_transfer(RawOrigin::Root.into(), 1, 2, 69)); assert_eq!(Balances::total_balance(&1), 42); @@ -389,7 +389,10 @@ fn balance_transfer_when_reserved_should_not_work() { with_externalities(&mut ExtBuilder::default().build(), || { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 69)); - assert_noop!(Balances::transfer(Some(1).into(), 2, 69), "balance too low to send value"); + assert_noop!( + Balances::transfer(Some(1).into(), 2, 69), + "balance too low to send value", + ); }); } @@ -517,7 +520,7 @@ fn transferring_too_high_value_should_not_panic() { assert_err!( Balances::transfer(Some(1).into(), 2, u64::max_value()), - "destination balance too high to receive value" + "destination balance too high to receive value", ); assert_eq!(Balances::free_balance(&1), u64::max_value()); @@ -595,7 +598,7 @@ fn transfer_overflow_isnt_exploitable() { assert_err!( Balances::transfer(Some(1).into(), 5, evil_value), - "got overflow after adding a fee to value" + "got overflow after adding a fee to value", ); } ); @@ -680,7 +683,7 @@ fn unvested_balance_should_not_transfer() { assert_eq!(Balances::vesting_balance(&1), 45); assert_noop!( Balances::transfer(Some(1).into(), 2, 56), - "vesting balance too high to send value" + "vesting balance too high to send value", ); // Account 1 cannot send more than vested amount } ); diff --git a/srml/contracts/src/gas.rs b/srml/contracts/src/gas.rs index 8e1ffbca0b..08070916fb 100644 --- a/srml/contracts/src/gas.rs +++ b/srml/contracts/src/gas.rs @@ -16,10 +16,12 @@ use crate::{GasSpent, Module, Trait, BalanceOf, NegativeImbalanceOf}; use rstd::convert::TryFrom; -use sr_primitives::BLOCK_FULL; -use sr_primitives::traits::{CheckedMul, Zero, SaturatedConversion, SimpleArithmetic, UniqueSaturatedInto}; -use support::StorageValue; -use support::traits::{Currency, ExistenceRequirement, Get, Imbalance, OnUnbalanced, WithdrawReason}; +use sr_primitives::traits::{ + CheckedMul, Zero, SaturatedConversion, SimpleArithmetic, UniqueSaturatedInto, +}; +use support::{ + traits::{Currency, ExistenceRequirement, Imbalance, OnUnbalanced, WithdrawReason}, StorageValue, +}; #[cfg(test)] use std::{any::Any, fmt::Debug}; @@ -200,14 +202,6 @@ pub fn buy_gas( transactor: &T::AccountId, gas_limit: Gas, ) -> Result<(GasMeter, NegativeImbalanceOf), &'static str> { - // Check if the specified amount of gas is available in the current block. - // This cannot underflow since `gas_spent` is never greater than `T::BlockGasLimit`. - let gas_available = T::BlockGasLimit::get() - >::gas_spent(); - if gas_limit > gas_available { - // gas limit reached, revert the transaction and retry again in the future - return Err(BLOCK_FULL); - } - // Buy the specified amount of gas. let gas_price = >::gas_price(); let cost = if gas_price.is_zero() { diff --git a/srml/contracts/src/lib.rs b/srml/contracts/src/lib.rs index 37299d4488..74ad5867af 100644 --- a/srml/contracts/src/lib.rs +++ b/srml/contracts/src/lib.rs @@ -63,6 +63,15 @@ //! This creates a new smart contract account and calls its contract deploy handler to initialize the contract. //! * `call` - Makes a call to an account, optionally transferring some balance. //! +//! ### Signed Extensions +//! +//! The contracts module defines the following extension: +//! +//! - [`CheckBlockGasLimit`]: Ensures that the transaction does not exceeds the block gas limit. +//! +//! The signed extension needs to be added as signed extra to the transaction type to be used in the +//! runtime. +//! //! ## Usage //! //! The Contract module is a work in progress. The following examples show how this Contract module can be @@ -100,15 +109,19 @@ use primitives::crypto::UncheckedFrom; use rstd::{prelude::*, marker::PhantomData}; use codec::{Codec, Encode, Decode}; use runtime_io::blake2_256; -use sr_primitives::traits::{ - Hash, StaticLookup, Zero, MaybeSerializeDebug, Member +use sr_primitives::{ + traits::{Hash, StaticLookup, Zero, MaybeSerializeDebug, Member, SignedExtension}, + weights::DispatchInfo, + transaction_validity::{ + ValidTransaction, InvalidTransaction, TransactionValidity, TransactionValidityError, + }, }; use support::dispatch::{Result, Dispatchable}; use support::{ Parameter, StorageMap, StorageValue, decl_module, decl_event, decl_storage, storage::child, parameter_types, }; -use support::traits::{OnFreeBalanceZero, OnUnbalanced, Currency, Get}; +use support::{traits::{OnFreeBalanceZero, OnUnbalanced, Currency, Get}, IsSubType}; use system::{ensure_signed, RawOrigin, ensure_root}; use primitives::storage::well_known_keys::CHILD_STORAGE_KEY_PREFIX; use timestamp; @@ -321,7 +334,7 @@ pub trait Trait: timestamp::Trait { type Currency: Currency; /// The outer call dispatch type. - type Call: Parameter + Dispatchable::Origin>; + type Call: Parameter + Dispatchable::Origin> + IsSubType, Self>; /// The overarching event type. type Event: From> + Into<::Event>; @@ -597,15 +610,17 @@ decl_module! { /// the sender is not eligible for the reward. fn claim_surcharge(origin, dest: T::AccountId, aux_sender: Option) { let origin = origin.into(); - let (signed, rewarded) = match origin { - Ok(system::RawOrigin::Signed(ref account)) if aux_sender.is_none() => { + let (signed, rewarded) = match (origin, aux_sender) { + (Ok(system::RawOrigin::Signed(account)), None) => { (true, account) }, - Ok(system::RawOrigin::None) if aux_sender.is_some() => { - (false, aux_sender.as_ref().expect("checked above")) + (Ok(system::RawOrigin::None), Some(aux_sender)) => { + (false, aux_sender) }, - _ => return Err("Invalid surcharge claim: origin must be signed or \ - inherent and auxiliary sender only provided on inherent") + _ => return Err( + "Invalid surcharge claim: origin must be signed or \ + inherent and auxiliary sender only provided on inherent" + ), }; // Add some advantage for block producers (who send unsigned extrinsics) by @@ -619,7 +634,7 @@ decl_module! { // If poking the contract has lead to eviction of the contract, give out the rewards. if rent::try_evict::(&dest, handicap) == rent::RentOutcome::Evicted { - T::Currency::deposit_into_existing(rewarded, T::SurchargeReward::get())?; + T::Currency::deposit_into_existing(&rewarded, T::SurchargeReward::get())?; } } @@ -937,3 +952,62 @@ impl Default for Schedule { } } } + +/// `SignedExtension` that checks if a transaction would exhausts the block gas limit. +#[derive(Encode, Decode, Clone, Eq, PartialEq)] +pub struct CheckBlockGasLimit(PhantomData); + +impl Default for CheckBlockGasLimit { + fn default() -> Self { + Self(PhantomData) + } +} + +#[cfg(feature = "std")] +impl std::fmt::Debug for CheckBlockGasLimit { + fn fmt(&self, _: &mut std::fmt::Formatter) -> std::fmt::Result { + Ok(()) + } +} + +impl SignedExtension for CheckBlockGasLimit { + type AccountId = T::AccountId; + type Call = ::Call; + type AdditionalSigned = (); + type Pre = (); + + fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } + + fn validate( + &self, + _: &Self::AccountId, + call: &Self::Call, + _: DispatchInfo, + _: usize, + ) -> TransactionValidity { + let call = match call.is_sub_type() { + Some(call) => call, + None => return Ok(ValidTransaction::default()), + }; + + match call { + Call::claim_surcharge(_, _) | Call::update_schedule(_) => + Ok(ValidTransaction::default()), + Call::put_code(gas_limit, _) + | Call::call(_, _, gas_limit, _) + | Call::create(_, gas_limit, _, _) + => { + // Check if the specified amount of gas is available in the current block. + // This cannot underflow since `gas_spent` is never greater than `T::BlockGasLimit`. + let gas_available = T::BlockGasLimit::get() - >::gas_spent(); + if *gas_limit > gas_available { + // gas limit reached, revert the transaction and retry again in the future + InvalidTransaction::ExhaustsResources.into() + } else { + Ok(ValidTransaction::default()) + } + }, + Call::__PhantomItem(_, _) => unreachable!("Variant is never constructed"), + } + } +} diff --git a/srml/contracts/src/tests.rs b/srml/contracts/src/tests.rs index 91c3e4f712..f585eddb59 100644 --- a/srml/contracts/src/tests.rs +++ b/srml/contracts/src/tests.rs @@ -22,27 +22,27 @@ use crate::account_db::{AccountDb, DirectAccountDb, OverlayAccountDb}; use crate::{ BalanceOf, ComputeDispatchFee, ContractAddressFor, ContractInfo, ContractInfoOf, GenesisConfig, - Module, RawAliveContractInfo, RawEvent, Trait, TrieId, TrieIdFromParentCounter, - TrieIdGenerator, Schedule, + Module, RawAliveContractInfo, RawEvent, Trait, TrieId, TrieIdFromParentCounter, Schedule, + TrieIdGenerator, CheckBlockGasLimit, }; use assert_matches::assert_matches; use hex_literal::*; use codec::{Decode, Encode, KeyedVec}; use runtime_io; use runtime_io::with_externalities; -use sr_primitives::testing::{Digest, DigestItem, Header, UintAuthorityId, H256}; -use sr_primitives::traits::{BlakeTwo256, Hash, IdentityLookup}; -use sr_primitives::{Perbill, BuildStorage}; +use sr_primitives::{ + Perbill, BuildStorage, transaction_validity::{InvalidTransaction, ValidTransaction}, + traits::{BlakeTwo256, Hash, IdentityLookup, SignedExtension}, + weights::{DispatchInfo, DispatchClass}, + testing::{Digest, DigestItem, Header, UintAuthorityId, H256}, +}; use support::{ assert_ok, assert_err, impl_outer_dispatch, impl_outer_event, impl_outer_origin, parameter_types, storage::child, StorageMap, StorageValue, traits::{Currency, Get}, }; -use std::cell::RefCell; -use std::sync::atomic::{AtomicUsize, Ordering}; -use primitives::storage::well_known_keys; -use primitives::Blake2Hasher; +use std::{cell::RefCell, sync::atomic::{AtomicUsize, Ordering}}; +use primitives::{storage::well_known_keys, Blake2Hasher}; use system::{self, EventRecord, Phase}; -use {balances, wabt}; mod contract { // Re-export contents of the root. This basically @@ -2390,3 +2390,22 @@ fn cannot_self_destruct_in_constructor() { } ); } + +#[test] +fn check_block_gas_limit_works() { + with_externalities( + &mut ExtBuilder::default().block_gas_limit(50).build(), + || { + let info = DispatchInfo { weight: 100, class: DispatchClass::Normal }; + let check = CheckBlockGasLimit::(Default::default()); + let call: Call = crate::Call::put_code(1000, vec![]).into(); + + assert_eq!( + check.validate(&0, &call, info, 0), InvalidTransaction::ExhaustsResources.into(), + ); + + let call: Call = crate::Call::update_schedule(Default::default()).into(); + assert_eq!(check.validate(&0, &call, info, 0), Ok(Default::default())); + } + ); +} diff --git a/srml/council/src/lib.rs b/srml/council/src/lib.rs index 3ec76a15e1..aa27bcde21 100644 --- a/srml/council/src/lib.rs +++ b/srml/council/src/lib.rs @@ -62,6 +62,8 @@ mod tests { impl_outer_dispatch! { pub enum Call for Test where origin: Origin { + type Error = Error; + balances::Balances, democracy::Democracy, } @@ -115,6 +117,7 @@ mod tests { type Header = Header; type WeightMultiplierUpdate = (); type Event = Event; + type Error = Error; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; @@ -136,6 +139,7 @@ mod tests { type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); + type Error = Error; type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index 1fc694bece..2b74c44598 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -20,12 +20,14 @@ use rstd::prelude::*; use rstd::{result, convert::TryFrom}; -use sr_primitives::traits::{Zero, Bounded, CheckedMul, CheckedDiv, EnsureOrigin, Hash}; -use sr_primitives::weights::SimpleDispatchInfo; +use sr_primitives::{ + traits::{Zero, Bounded, CheckedMul, CheckedDiv, EnsureOrigin, Hash, Dispatchable}, + weights::SimpleDispatchInfo, +}; use codec::{Encode, Decode, Input, Output, Error}; use support::{ decl_module, decl_storage, decl_event, ensure, StorageValue, StorageMap, StorageLinkedMap, - Parameter, Dispatchable, + Parameter, traits::{ Currency, ReservableCurrency, LockableCurrency, WithdrawReason, LockIdentifier, Get, OnFreeBalanceZero diff --git a/srml/elections/src/lib.rs b/srml/elections/src/lib.rs index b14ffa9463..64b1e9e1db 100644 --- a/srml/elections/src/lib.rs +++ b/srml/elections/src/lib.rs @@ -504,7 +504,7 @@ decl_module! { let who = ensure_signed(origin)?; ensure!( !total.is_zero(), - "stake deposited to present winner and be added to leaderboard should be non-zero" + "stake deposited to present winner and be added to leaderboard should be non-zero", ); let candidate = T::Lookup::lookup(candidate)?; @@ -1234,7 +1234,7 @@ mod tests { UncheckedExtrinsic = UncheckedExtrinsic { System: system::{Module, Call, Event}, - Balances: balances::{Module, Call, Event, Config}, + Balances: balances::{Module, Call, Event, Config, Error}, Elections: elections::{Module, Call, Event, Config}, } ); diff --git a/srml/example/src/lib.rs b/srml/example/src/lib.rs index 596defae04..cfa3636e4d 100644 --- a/srml/example/src/lib.rs +++ b/srml/example/src/lib.rs @@ -258,9 +258,10 @@ use support::{StorageValue, dispatch::Result, decl_module, decl_storage, decl_ev use system::{ensure_signed, ensure_root}; use codec::{Encode, Decode}; use sr_primitives::{ - traits::{SignedExtension, DispatchError, Bounded}, - transaction_validity::ValidTransaction, - weights::{SimpleDispatchInfo, DispatchInfo}, + traits::{SignedExtension, Bounded}, weights::{SimpleDispatchInfo, DispatchInfo}, + transaction_validity::{ + ValidTransaction, TransactionValidityError, InvalidTransaction, TransactionValidity, + }, }; /// Our module's configuration trait. All our types and consts go in here. If the @@ -561,7 +562,7 @@ impl SignedExtension for WatchDummy { type AdditionalSigned = (); type Pre = (); - fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) } + fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } fn validate( &self, @@ -569,9 +570,11 @@ impl SignedExtension for WatchDummy { call: &Self::Call, _info: DispatchInfo, len: usize, - ) -> rstd::result::Result { + ) -> TransactionValidity { // if the transaction is too big, just drop it. - if len > 200 { return Err(DispatchError::Exhausted) } + if len > 200 { + return InvalidTransaction::ExhaustsResources.into() + } // check for `set_dummy` match call { @@ -582,7 +585,7 @@ impl SignedExtension for WatchDummy { valid_tx.priority = Bounded::max_value(); Ok(valid_tx) } - _ => Ok(Default::default()) + _ => Ok(Default::default()), } } } @@ -712,12 +715,14 @@ mod tests { let info = DispatchInfo::default(); assert_eq!( - WatchDummy::(PhantomData).validate(&1, &call, info, 150).unwrap().priority, - Bounded::max_value() + WatchDummy::(PhantomData).validate(&1, &call, info, 150) + .unwrap() + .priority, + Bounded::max_value(), ); assert_eq!( WatchDummy::(PhantomData).validate(&1, &call, info, 250), - Err(DispatchError::Exhausted) + InvalidTransaction::ExhaustsResources.into(), ); }) } diff --git a/srml/executive/src/lib.rs b/srml/executive/src/lib.rs index c6931af0a1..f3e8b63a28 100644 --- a/srml/executive/src/lib.rs +++ b/srml/executive/src/lib.rs @@ -59,13 +59,13 @@ //! # pub type Balances = u64; //! # pub type AllModules = u64; //! # pub enum Runtime {}; -//! # use sr_primitives::transaction_validity::TransactionValidity; +//! # use sr_primitives::transaction_validity::{TransactionValidity, UnknownTransaction}; //! # use sr_primitives::traits::ValidateUnsigned; //! # impl ValidateUnsigned for Runtime { //! # type Call = (); //! # //! # fn validate_unsigned(_call: &Self::Call) -> TransactionValidity { -//! # TransactionValidity::Invalid(0) +//! # UnknownTransaction::NoUnsignedValidator.into() //! # } //! # } //! /// Executive: handles dispatch to the various modules. @@ -74,50 +74,17 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::prelude::*; -use rstd::marker::PhantomData; -use rstd::result; -use sr_primitives::{generic::Digest, traits::{ - self, Header, Zero, One, Checkable, Applyable, CheckEqual, OnFinalize, - OnInitialize, NumberFor, Block as BlockT, OffchainWorker, ValidateUnsigned -}}; -use support::Dispatchable; +use rstd::{prelude::*, marker::PhantomData}; +use sr_primitives::{ + generic::Digest, ApplyResult, weights::GetDispatchInfo, + traits::{ + self, Header, Zero, One, Checkable, Applyable, CheckEqual, OnFinalize, OnInitialize, + NumberFor, Block as BlockT, OffchainWorker, ValidateUnsigned, Dispatchable + }, + transaction_validity::TransactionValidity, +}; use codec::{Codec, Encode}; use system::{extrinsics_root, DigestOf}; -use sr_primitives::{ApplyOutcome, ApplyError}; -use sr_primitives::transaction_validity::TransactionValidity; -use sr_primitives::weights::GetDispatchInfo; - -mod internal { - use sr_primitives::traits::DispatchError; - - pub enum ApplyError { - BadSignature(&'static str), - Stale, - Future, - CantPay, - FullBlock, - } - - pub enum ApplyOutcome { - Success, - Fail(&'static str), - } - - impl From for ApplyError { - fn from(d: DispatchError) -> Self { - match d { - DispatchError::Payment => ApplyError::CantPay, - DispatchError::Exhausted => ApplyError::FullBlock, - DispatchError::NoPermission => ApplyError::CantPay, - DispatchError::BadState => ApplyError::CantPay, - DispatchError::Stale => ApplyError::Stale, - DispatchError::Future => ApplyError::Future, - DispatchError::BadProof => ApplyError::BadSignature(""), - } - } - } -} /// Trait that can be used to execute a block. pub trait ExecuteBlock { @@ -239,30 +206,19 @@ where /// Apply extrinsic outside of the block execution function. /// This doesn't attempt to validate anything regarding the block, but it builds a list of uxt /// hashes. - pub fn apply_extrinsic(uxt: Block::Extrinsic) -> result::Result { + pub fn apply_extrinsic(uxt: Block::Extrinsic) -> ApplyResult { let encoded = uxt.encode(); let encoded_len = encoded.len(); - match Self::apply_extrinsic_with_len(uxt, encoded_len, Some(encoded)) { - Ok(internal::ApplyOutcome::Success) => Ok(ApplyOutcome::Success), - Ok(internal::ApplyOutcome::Fail(_)) => Ok(ApplyOutcome::Fail), - Err(internal::ApplyError::CantPay) => Err(ApplyError::CantPay), - Err(internal::ApplyError::BadSignature(_)) => Err(ApplyError::BadSignature), - Err(internal::ApplyError::Stale) => Err(ApplyError::Stale), - Err(internal::ApplyError::Future) => Err(ApplyError::Future), - Err(internal::ApplyError::FullBlock) => Err(ApplyError::FullBlock), - } + Self::apply_extrinsic_with_len(uxt, encoded_len, Some(encoded)) } /// Apply an extrinsic inside the block execution function. fn apply_extrinsic_no_note(uxt: Block::Extrinsic) { let l = uxt.encode().len(); match Self::apply_extrinsic_with_len(uxt, l, None) { - Ok(internal::ApplyOutcome::Success) => (), - Ok(internal::ApplyOutcome::Fail(e)) => runtime_io::print(e), - Err(internal::ApplyError::CantPay) => panic!("All extrinsics should have sender able to pay their fees"), - Err(internal::ApplyError::BadSignature(_)) => panic!("All extrinsics should be properly signed"), - Err(internal::ApplyError::Stale) | Err(internal::ApplyError::Future) => panic!("All extrinsics should have the correct nonce"), - Err(internal::ApplyError::FullBlock) => panic!("Extrinsics should not exceed block limit"), + Ok(Ok(())) => (), + Ok(Err(e)) => runtime_io::print(e), + Err(e) => { let err: &'static str = e.into(); panic!(err) }, } } @@ -271,9 +227,9 @@ where uxt: Block::Extrinsic, encoded_len: usize, to_note: Option>, - ) -> result::Result { + ) -> ApplyResult { // Verify that the signature is good. - let xt = uxt.check(&Default::default()).map_err(internal::ApplyError::BadSignature)?; + let xt = uxt.check(&Default::default())?; // We don't need to make sure to `note_extrinsic` only after we know it's going to be // executed to prevent it from leaking in storage since at this point, it will either @@ -286,15 +242,11 @@ where // Decode parameters and dispatch let dispatch_info = xt.get_dispatch_info(); - let r = Applyable::dispatch(xt, dispatch_info, encoded_len) - .map_err(internal::ApplyError::from)?; + let r = Applyable::apply(xt, dispatch_info, encoded_len)?; >::note_applied_extrinsic(&r, encoded_len as u32); - r.map(|_| internal::ApplyOutcome::Success).or_else(|e| match e { - sr_primitives::BLOCK_FULL => Err(internal::ApplyError::FullBlock), - e => Ok(internal::ApplyOutcome::Fail(e)) - }) + Ok(r) } fn final_checks(header: &System::Header) { @@ -324,21 +276,8 @@ where /// /// Changes made to storage should be discarded. pub fn validate_transaction(uxt: Block::Extrinsic) -> TransactionValidity { - // Note errors > 0 are from ApplyError - const UNKNOWN_ERROR: i8 = -127; - const INVALID_INDEX: i8 = -10; - let encoded_len = uxt.using_encoded(|d| d.len()); - let xt = match uxt.check(&Default::default()) { - // Checks out. Carry on. - Ok(xt) => xt, - // An unknown account index implies that the transaction may yet become valid. - Err("invalid account index") => return TransactionValidity::Unknown(INVALID_INDEX), - // Technically a bad signature could also imply an out-of-date account index, but - // that's more of an edge case. - Err(sr_primitives::BAD_SIGNATURE) => return TransactionValidity::Invalid(ApplyError::BadSignature as i8), - Err(_) => return TransactionValidity::Invalid(UNKNOWN_ERROR), - }; + let xt = uxt.check(&Default::default())?; let dispatch_info = xt.get_dispatch_info(); xt.validate::(dispatch_info, encoded_len) @@ -357,13 +296,15 @@ mod tests { use balances::Call; use runtime_io::with_externalities; use primitives::{H256, Blake2Hasher}; - use sr_primitives::generic::Era; - use sr_primitives::Perbill; - use sr_primitives::weights::Weight; - use sr_primitives::traits::{Header as HeaderT, BlakeTwo256, IdentityLookup, ConvertInto}; - use sr_primitives::testing::{Digest, Header, Block}; - use support::{impl_outer_event, impl_outer_origin, parameter_types}; - use support::traits::{Currency, LockIdentifier, LockableCurrency, WithdrawReasons, WithdrawReason}; + use sr_primitives::{ + generic::Era, Perbill, DispatchError, weights::Weight, testing::{Digest, Header, Block}, + traits::{Header as HeaderT, BlakeTwo256, IdentityLookup, ConvertInto}, + transaction_validity::{InvalidTransaction, UnknownTransaction}, ApplyError, + }; + use support::{ + impl_outer_event, impl_outer_origin, parameter_types, + traits::{Currency, LockIdentifier, LockableCurrency, WithdrawReasons, WithdrawReason}, + }; use system; use hex_literal::hex; @@ -432,8 +373,8 @@ mod tests { fn validate_unsigned(call: &Self::Call) -> TransactionValidity { match call { - Call::set_balance(_, _, _) => TransactionValidity::Valid(Default::default()), - _ => TransactionValidity::Invalid(0), + Call::set_balance(_, _, _) => Ok(Default::default()), + _ => UnknownTransaction::NoUnsignedValidator.into(), } } } @@ -479,7 +420,7 @@ mod tests { Digest::default(), )); let r = Executive::apply_extrinsic(xt); - assert_eq!(r, Ok(ApplyOutcome::Success)); + assert!(r.is_ok()); assert_eq!(>::total_balance(&1), 142 - 10 - weight); assert_eq!(>::total_balance(&2), 69); }); @@ -582,14 +523,19 @@ mod tests { assert_eq!(>::all_extrinsics_weight(), 0); for nonce in 0..=num_to_exhaust_block { - let xt = sr_primitives::testing::TestXt(sign_extra(1, nonce.into(), 0), Call::transfer::(33, 0)); + let xt = sr_primitives::testing::TestXt( + sign_extra(1, nonce.into(), 0), Call::transfer::(33, 0), + ); let res = Executive::apply_extrinsic(xt); if nonce != num_to_exhaust_block { - assert_eq!(res.unwrap(), ApplyOutcome::Success); - assert_eq!(>::all_extrinsics_weight(), encoded_len * (nonce + 1)); + assert!(res.is_ok()); + assert_eq!( + >::all_extrinsics_weight(), + encoded_len * (nonce + 1), + ); assert_eq!(>::extrinsic_index(), Some(nonce as u32 + 1)); } else { - assert_eq!(res, Err(ApplyError::FullBlock)); + assert_eq!(res, Err(InvalidTransaction::ExhaustsResources.into())); } } }); @@ -606,9 +552,9 @@ mod tests { assert_eq!(>::all_extrinsics_weight(), 0); assert_eq!(>::all_extrinsics_weight(), 0); - assert_eq!(Executive::apply_extrinsic(xt.clone()).unwrap(), ApplyOutcome::Success); - assert_eq!(Executive::apply_extrinsic(x1.clone()).unwrap(), ApplyOutcome::Success); - assert_eq!(Executive::apply_extrinsic(x2.clone()).unwrap(), ApplyOutcome::Success); + assert!(Executive::apply_extrinsic(xt.clone()).unwrap().is_ok()); + assert!(Executive::apply_extrinsic(x1.clone()).unwrap().is_ok()); + assert!(Executive::apply_extrinsic(x2.clone()).unwrap().is_ok()); // default weight for `TestXt` == encoded length. assert_eq!(>::all_extrinsics_weight(), (3 * len).into()); @@ -624,12 +570,18 @@ mod tests { #[test] fn validate_unsigned() { let xt = sr_primitives::testing::TestXt(None, Call::set_balance(33, 69, 69)); - let valid = TransactionValidity::Valid(Default::default()); let mut t = new_test_ext(1); with_externalities(&mut t, || { - assert_eq!(Executive::validate_transaction(xt.clone()), valid); - assert_eq!(Executive::apply_extrinsic(xt), Ok(ApplyOutcome::Fail)); + assert_eq!(Executive::validate_transaction(xt.clone()), Ok(Default::default())); + assert_eq!( + Executive::apply_extrinsic(xt), + Ok( + Err( + DispatchError { module: None, error: 0, message: Some("RequireRootOrigin") } + ) + ) + ); }); } @@ -657,11 +609,21 @@ mod tests { )); if lock == WithdrawReasons::except(WithdrawReason::TransactionPayment) { - assert_eq!(Executive::apply_extrinsic(xt).unwrap(), ApplyOutcome::Fail); + assert_eq!( + Executive::apply_extrinsic(xt).unwrap(), + Err(DispatchError { + module: None, + error: 0, + message: Some("account liquidity restrictions prevent withdrawal"), + }), + ); // but tx fee has been deducted. the transaction failed on transfer, not on fee. assert_eq!(>::total_balance(&1), 111 - 10 - weight); } else { - assert_eq!(Executive::apply_extrinsic(xt), Err(ApplyError::CantPay)); + assert_eq!( + Executive::apply_extrinsic(xt), + Err(ApplyError::Validity(InvalidTransaction::Payment.into())), + ); assert_eq!(>::total_balance(&1), 111); } }); diff --git a/srml/grandpa/src/mock.rs b/srml/grandpa/src/mock.rs index 126aa0569a..af2fedf42f 100644 --- a/srml/grandpa/src/mock.rs +++ b/srml/grandpa/src/mock.rs @@ -37,9 +37,9 @@ pub fn grandpa_log(log: ConsensusLog) -> DigestItem { // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, PartialEq, Eq, Debug, Decode, Encode)] pub struct Test; + impl Trait for Test { type Event = TestEvent; - } parameter_types! { pub const BlockHashCount: u64 = 250; @@ -53,7 +53,7 @@ impl system::Trait for Test { type BlockNumber = u64; type Call = (); type Hash = H256; - type Hashing = ::sr_primitives::traits::BlakeTwo256; + type Hashing = sr_primitives::traits::BlakeTwo256; type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; diff --git a/srml/im-online/src/lib.rs b/srml/im-online/src/lib.rs index d6ef6c2e9c..6106b1e45c 100644 --- a/srml/im-online/src/lib.rs +++ b/srml/im-online/src/lib.rs @@ -74,9 +74,10 @@ use rstd::prelude::*; use session::historical::IdentificationTuple; use runtime_io::Printable; use sr_primitives::{ - Perbill, ApplyError, - traits::{Convert, Member}, - transaction_validity::{TransactionValidity, TransactionLongevity, ValidTransaction}, + traits::{Convert, Member}, Perbill, + transaction_validity::{ + TransactionValidity, TransactionLongevity, ValidTransaction, InvalidTransaction, + }, }; use sr_staking_primitives::{ SessionIndex, CurrentElectedSet, @@ -160,7 +161,7 @@ enum OffchainErr { } impl Printable for OffchainErr { - fn print(self) { + fn print(&self) { match self { OffchainErr::DecodeWorkerStatus => print("Offchain error: decoding WorkerStatus failed!"), OffchainErr::FailedSigning => print("Offchain error: signing failed!"), @@ -489,24 +490,24 @@ impl session::OneSessionHandler for Module { impl support::unsigned::ValidateUnsigned for Module { type Call = Call; - fn validate_unsigned(call: &Self::Call) -> support::unsigned::TransactionValidity { + fn validate_unsigned(call: &Self::Call) -> TransactionValidity { if let Call::heartbeat(heartbeat, signature) = call { if >::is_online_in_current_session(heartbeat.authority_index) { // we already received a heartbeat for this authority - return TransactionValidity::Invalid(ApplyError::Stale as i8); + return InvalidTransaction::Stale.into(); } // check if session index from heartbeat is recent let current_session = >::current_index(); if heartbeat.session_index != current_session { - return TransactionValidity::Invalid(ApplyError::Stale as i8); + return InvalidTransaction::Stale.into(); } // verify that the incoming (unverified) pubkey is actually an authority id let keys = Keys::::get(); let authority_id = match keys.get(heartbeat.authority_index as usize) { Some(id) => id, - None => return TransactionValidity::Invalid(ApplyError::BadSignature as i8), + None => return InvalidTransaction::BadProof.into(), }; // check signature (this is expensive so we do it last). @@ -515,19 +516,19 @@ impl support::unsigned::ValidateUnsigned for Module { }); if !signature_valid { - return TransactionValidity::Invalid(ApplyError::BadSignature as i8); + return InvalidTransaction::BadProof.into(); } - return TransactionValidity::Valid(ValidTransaction { + Ok(ValidTransaction { priority: 0, requires: vec![], provides: vec![(current_session, authority_id).encode()], longevity: TransactionLongevity::max_value(), propagate: true, }) + } else { + InvalidTransaction::Call.into() } - - TransactionValidity::Invalid(0) } } diff --git a/srml/indices/src/lib.rs b/srml/indices/src/lib.rs index 15921ffdf4..7b8e1c0461 100644 --- a/srml/indices/src/lib.rs +++ b/srml/indices/src/lib.rs @@ -19,10 +19,10 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::{prelude::*, result, marker::PhantomData, convert::TryInto}; +use rstd::{prelude::*, marker::PhantomData, convert::TryInto}; use codec::{Encode, Codec}; use support::{StorageValue, StorageMap, Parameter, decl_module, decl_event, decl_storage}; -use sr_primitives::traits::{One, SimpleArithmetic, StaticLookup, Member}; +use sr_primitives::traits::{One, SimpleArithmetic, StaticLookup, Member, LookupError}; use system::{IsDeadAccount, OnNewAccount}; use self::address::Address as RawAddress; @@ -224,9 +224,11 @@ impl OnNewAccount for Module { impl StaticLookup for Module { type Source = address::Address; type Target = T::AccountId; - fn lookup(a: Self::Source) -> result::Result { - Self::lookup_address(a).ok_or("invalid account index") + + fn lookup(a: Self::Source) -> Result { + Self::lookup_address(a).ok_or(LookupError) } + fn unlookup(a: Self::Target) -> Self::Source { address::Address::Id(a) } diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index 12cdd2f4e9..0f8bc5c09a 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -882,8 +882,8 @@ decl_module! { ensure!(!targets.is_empty(), "targets cannot be empty"); let targets = targets.into_iter() .take(MAX_NOMINATIONS) - .map(T::Lookup::lookup) - .collect::, &'static str>>()?; + .map(|t| T::Lookup::lookup(t)) + .collect::, _>>()?; >::remove(stash); >::insert(stash, targets); diff --git a/srml/staking/src/tests.rs b/srml/staking/src/tests.rs index c3f3922299..34d95b60f2 100644 --- a/srml/staking/src/tests.rs +++ b/srml/staking/src/tests.rs @@ -748,7 +748,10 @@ fn cannot_transfer_staked_balance() { // Confirm account 11 (via controller 10) is totally staked assert_eq!(Staking::stakers(&11).total, 1000); // Confirm account 11 cannot transfer as a result - assert_noop!(Balances::transfer(Origin::signed(11), 20, 1), "account liquidity restrictions prevent withdrawal"); + assert_noop!( + Balances::transfer(Origin::signed(11), 20, 1), + "account liquidity restrictions prevent withdrawal", + ); // Give account 11 extra free balance let _ = Balances::make_free_balance_be(&11, 10000); @@ -774,7 +777,10 @@ fn cannot_transfer_staked_balance_2() { // Confirm account 21 (via controller 20) is totally staked assert_eq!(Staking::stakers(&21).total, 1000); // Confirm account 21 can transfer at most 1000 - assert_noop!(Balances::transfer(Origin::signed(21), 20, 1001), "account liquidity restrictions prevent withdrawal"); + assert_noop!( + Balances::transfer(Origin::signed(21), 20, 1001), + "account liquidity restrictions prevent withdrawal", + ); assert_ok!(Balances::transfer(Origin::signed(21), 20, 1000)); }); } diff --git a/srml/sudo/src/lib.rs b/srml/sudo/src/lib.rs index e933810237..845f1e4104 100644 --- a/srml/sudo/src/lib.rs +++ b/srml/sudo/src/lib.rs @@ -87,12 +87,10 @@ #![cfg_attr(not(feature = "std"), no_std)] use rstd::prelude::*; -use sr_primitives::traits::StaticLookup; -use sr_primitives::weights::SimpleDispatchInfo; -use support::{ - StorageValue, Parameter, Dispatchable, decl_module, decl_event, - decl_storage, ensure +use sr_primitives::{ + traits::{StaticLookup, Dispatchable}, weights::SimpleDispatchInfo, DispatchError, }; +use support::{StorageValue, Parameter, decl_module, decl_event, decl_storage, ensure}; use system::ensure_signed; pub trait Trait: system::Trait { @@ -126,6 +124,7 @@ decl_module! { let res = match proposal.dispatch(system::RawOrigin::Root.into()) { Ok(_) => true, Err(e) => { + let e: DispatchError = e.into(); runtime_io::print(e); false } diff --git a/srml/support/src/dispatch.rs b/srml/support/src/dispatch.rs index 86c21da67b..916cffdc34 100644 --- a/srml/support/src/dispatch.rs +++ b/srml/support/src/dispatch.rs @@ -25,18 +25,18 @@ pub use srml_metadata::{ FunctionMetadata, DecodeDifferent, DecodeDifferentArray, FunctionArgumentMetadata, ModuleConstantMetadata, DefaultByte, DefaultByteGetter, }; -pub use sr_primitives::weights::{SimpleDispatchInfo, GetDispatchInfo, DispatchInfo, WeighData, - ClassifyDispatch, - TransactionPriority +pub use sr_primitives::{ + weights::{ + SimpleDispatchInfo, GetDispatchInfo, DispatchInfo, WeighData, ClassifyDispatch, + TransactionPriority + }, traits::{Dispatchable, DispatchResult, ModuleDispatchError}, DispatchError }; -pub use sr_primitives::traits::{Dispatchable, DispatchResult}; /// A type that cannot be instantiated. pub enum Never {} -/// Result of a module function call; either nothing (functions are only called for "side effects") -/// or an error message. -pub type Result = DispatchResult; +/// Result with string error message. This exists for backward compatibility purpose. +pub type Result = DispatchResult<&'static str>; /// Serializable version of Dispatchable. /// This value can be used as a "function" in an extrinsic. @@ -239,6 +239,7 @@ macro_rules! decl_module { {} {} {} + {} [] $($t)* ); @@ -270,6 +271,7 @@ macro_rules! decl_module { {} {} {} + {} [] $($t)* ); @@ -286,6 +288,7 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* $vis:vis fn deposit_event() = default; @@ -301,6 +304,7 @@ macro_rules! decl_module { { $( $on_finalize )* } { $( $offchain )* } { $( $constants )* } + { $( $error_type )* } [ $( $dispatchables )* ] $($rest)* ); @@ -315,6 +319,7 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* $vis:vis fn deposit_event @@ -334,6 +339,7 @@ macro_rules! decl_module { {} { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* fn on_finalize($($param_name:ident : $param:ty),* ) { $( $impl:tt )* } @@ -349,6 +355,7 @@ macro_rules! decl_module { { fn on_finalize( $( $param_name : $param ),* ) { $( $impl )* } } { $( $offchain )* } { $( $constants )* } + { $( $error_type )* } [ $( $dispatchables )* ] $($rest)* ); @@ -363,6 +370,7 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* fn on_initialize($($param_name:ident : $param:ty),* ) { $( $impl:tt )* } @@ -378,6 +386,7 @@ macro_rules! decl_module { { $( $on_finalize )* } { $( $offchain )* } { $( $constants )* } + { $( $error_type )* } [ $( $dispatchables )* ] $($rest)* ); @@ -395,6 +404,7 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* fn offchain_worker($($param_name:ident : $param:ty),* ) { $( $impl:tt )* } @@ -412,6 +422,7 @@ macro_rules! decl_module { { $( $on_finalize )* } { fn offchain_worker( $( $param_name : $param ),* ) { $( $impl )* } } { $( $constants )* } + { $( $error_type )* } [ $( $dispatchables )* ] $($rest)* ); @@ -431,6 +442,7 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $( #[doc = $doc_attr:tt] )* const $name:ident: $ty:ty = $value:expr; @@ -453,11 +465,85 @@ macro_rules! decl_module { $( #[doc = $doc_attr ] )* $name: $ty = $value; } + { $( $error_type )* } [ $( $dispatchables )* ] $($rest)* ); }; + // Parse error type + (@normalize + $(#[$attr:meta])* + pub struct $mod_type:ident< + $trait_instance:ident: + $trait_name:ident$(, $instance:ident: $instantiable:path $(= $module_default_instance:path)?)? + > + for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident + { $( $other_where_bounds:tt )* } + { $( $deposit_event:tt )* } + { $( $on_initialize:tt )* } + { $( $on_finalize:tt )* } + { $( $offchain:tt )* } + { $( $constants:tt )* } + { } + [ $( $dispatchables:tt )* ] + $(#[doc = $doc_attr:tt])* + type Error = $error_type:ty; + $($rest:tt)* + ) => { + $crate::decl_module!(@normalize + $(#[$attr])* + pub struct $mod_type< + $trait_instance: $trait_name$(, $instance: $instantiable $(= $module_default_instance)?)? + > + for enum $call_type where origin: $origin_type, system = $system + { $( $other_where_bounds )* } + { $( $deposit_event )* } + { $( $on_initialize )* } + { $( $on_finalize )* } + { $( $offchain )* } + { $( $constants )* } + { $error_type } + [ $( $dispatchables )* ] + $($rest)* + ); + }; + // Add default Error if none supplied + (@normalize + $(#[$attr:meta])* + pub struct $mod_type:ident< + $trait_instance:ident: + $trait_name:ident$(, $instance:ident: $instantiable:path $(= $module_default_instance:path)?)? + > + for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident + { $( $other_where_bounds:tt )* } + { $( $deposit_event:tt )* } + { $( $on_initialize:tt )* } + { $( $on_finalize:tt )* } + { $( $offchain:tt )* } + { $( $constants:tt )* } + { } + [ $($t:tt)* ] + $($rest:tt)* + ) => { + $crate::decl_module!(@normalize + $(#[$attr])* + pub struct $mod_type< + $trait_instance: $trait_name$(, $instance: $instantiable $(= $module_default_instance)?)? + > + for enum $call_type where origin: $origin_type, system = $system + { $( $other_where_bounds )* } + { $( $deposit_event )* } + { $( $on_initialize )* } + { $( $on_finalize )* } + { $( $offchain )* } + { $( $constants )* } + { &'static str } + [ $($t)* ] + $($rest)* + ); + }; + // This puts the function statement into the [], decreasing `$rest` and moving toward finishing the parse. (@normalize $(#[$attr:meta])* @@ -472,6 +558,7 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $error_type:ty } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* #[weight = $weight:expr] @@ -492,6 +579,7 @@ macro_rules! decl_module { { $( $on_finalize )* } { $( $offchain )* } { $( $constants )* } + { $error_type } [ $( $dispatchables )* $(#[doc = $doc_attr])* @@ -518,6 +606,7 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* $fn_vis:vis fn $fn_name:ident( @@ -537,6 +626,7 @@ macro_rules! decl_module { { $( $on_finalize )* } { $( $offchain )* } { $( $constants )* } + { $( $error_type )* } [ $( $dispatchables )* ] $(#[doc = $doc_attr])* #[weight = $crate::dispatch::SimpleDispatchInfo::default()] @@ -557,6 +647,7 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* $(#[weight = $weight:expr])? @@ -581,6 +672,7 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* $(#[weight = $weight:expr])? @@ -605,6 +697,7 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* $(#[weight = $weight:expr])? @@ -630,6 +723,7 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] ) => { $crate::decl_module!(@imp @@ -644,6 +738,7 @@ macro_rules! decl_module { { $( $on_finalize )* } { $( $offchain )* } { $( $constants )* } + { $( $error_type )* } ); }; @@ -794,6 +889,7 @@ macro_rules! decl_module { (@impl_function $module:ident<$trait_instance:ident: $trait_name:ident$(, $instance:ident: $instantiable:path)?>; $origin_ty:ty; + $error_type:ty; $ignore:ident; $(#[doc = $doc_attr:tt])* $vis:vis fn $name:ident ( @@ -804,7 +900,7 @@ macro_rules! decl_module { #[allow(unreachable_code)] $vis fn $name( $origin: $origin_ty $(, $param: $param_ty )* - ) -> $crate::dispatch::Result { + ) -> $crate::dispatch::DispatchResult<$error_type> { { $( $impl )* } // May be unreachable. Ok(()) @@ -815,6 +911,7 @@ macro_rules! decl_module { (@impl_function $module:ident<$trait_instance:ident: $trait_name:ident$(, $instance:ident: $instantiable:path)?>; $origin_ty:ty; + $error_type:ty; $ignore:ident; $(#[doc = $doc_attr:tt])* $vis:vis fn $name:ident ( @@ -969,6 +1066,7 @@ macro_rules! decl_module { { $( $on_finalize:tt )* } { $( $offchain:tt )* } { $( $constants:tt )* } + { $error_type:ty } ) => { $crate::__check_reserved_fn_name! { $( $fn_name )* } @@ -1020,6 +1118,7 @@ macro_rules! decl_module { @impl_function $mod_type<$trait_instance: $trait_name $(, $fn_instance: $fn_instantiable)?>; $origin_type; + $error_type; $from; $(#[doc = $doc_attr])* $fn_vis fn $fn_name ( @@ -1150,7 +1249,8 @@ macro_rules! decl_module { { type Trait = $trait_instance; type Origin = $origin_type; - fn dispatch(self, _origin: Self::Origin) -> $crate::dispatch::Result { + type Error = $error_type; + fn dispatch(self, _origin: Self::Origin) -> $crate::dispatch::DispatchResult { match self { $( $call_type::$fn_name( $( $param_name ),* ) => { @@ -1177,8 +1277,8 @@ macro_rules! decl_module { #[doc(hidden)] pub fn dispatch>( d: D, - origin: D::Origin, - ) -> $crate::dispatch::Result { + origin: D::Origin + ) -> $crate::dispatch::DispatchResult { d.dispatch(origin) } } @@ -1234,9 +1334,19 @@ macro_rules! impl_outer_dispatch { impl $crate::dispatch::Dispatchable for $call_type { type Origin = $origin; type Trait = $call_type; - fn dispatch(self, origin: $origin) -> $crate::dispatch::Result { - match self { - $( $call_type::$camelcase(call) => call.dispatch(origin), )* + type Error = $crate::dispatch::DispatchError; + fn dispatch( + self, + origin: $origin, + ) -> $crate::dispatch::DispatchResult<$crate::dispatch::DispatchError> { + $crate::impl_outer_dispatch! { + @DISPATCH_MATCH + self + $call_type + origin + {} + 0; + $( $camelcase ),* } } } @@ -1258,6 +1368,43 @@ macro_rules! impl_outer_dispatch { } } )* + }; + (@DISPATCH_MATCH + $self:ident + $call_type:ident + $origin:ident + { $( $generated:tt )* } + $index:expr; + $name:ident + $( , $rest:ident )* + ) => { + $crate::impl_outer_dispatch! { + @DISPATCH_MATCH + $self + $call_type + $origin + { + $( $generated )* + $call_type::$name(call) => call.dispatch($origin).map_err(|e| { + let mut error: $crate::dispatch::DispatchError = e.into(); + error.module = Some($index); + error + }), + } + $index + 1; + $( $rest ),* + } + }; + (@DISPATCH_MATCH + $self:ident + $call_type:ident + $origin:ident + { $( $generated:tt )* } + $index:expr; + ) => { + match $self { + $( $generated )* + } } } diff --git a/srml/support/src/error.rs b/srml/support/src/error.rs new file mode 100644 index 0000000000..2f9d9379bf --- /dev/null +++ b/srml/support/src/error.rs @@ -0,0 +1,151 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Macro for declaring a module error. + +#[doc(hidden)] +pub use sr_primitives::traits::LookupError; + +/// Declare an error type for a runtime module. +/// +/// The generated error type inherently has the variants `Other` and `CannotLookup`. `Other` can +/// hold any `&'static str` error message and is present for convenience/backward compatibility. +/// The `CannotLookup` variant indicates that some lookup could not be done. For both variants the +/// error type implements `From<&'static str>` and `From` to make them usable with the +/// try operator. +/// +/// # Usage +/// +/// ``` +/// # use srml_support::decl_error; +/// decl_error! { +/// /// Errors that can occur in my module. +/// pub enum MyError { +/// /// Hey this is an error message that indicates bla. +/// MyCoolErrorMessage, +/// /// You are just not cool enough for my module! +/// YouAreNotCoolEnough, +/// } +/// } +/// ``` +/// +/// `decl_error!` supports only variants that do not hold any data. +#[macro_export] +macro_rules! decl_error { + ( + $(#[$attr:meta])* + pub enum $error:ident { + $( + $( #[$variant_attr:meta] )* + $name:ident + ),* + $(,)? + } + ) => { + #[derive(Clone, PartialEq, Eq)] + #[cfg_attr(feature = "std", derive(Debug))] + $(#[$attr])* + pub enum $error { + Other(&'static str), + CannotLookup, + $( + $(#[$variant_attr])* + $name + ),* + } + + impl $crate::dispatch::ModuleDispatchError for $error { + fn as_u8(&self) -> u8 { + $crate::decl_error! { + @GENERATE_AS_U8 + self + $error + {} + 2, + $( $name ),* + } + } + + fn as_str(&self) -> &'static str { + match self { + $error::Other(err) => err, + $error::CannotLookup => "Can not lookup", + $( + $error::$name => stringify!($name), + )* + } + } + } + + impl From<&'static str> for $error { + fn from(val: &'static str) -> $error { + $error::Other(val) + } + } + + impl From<$crate::error::LookupError> for $error { + fn from(_: $crate::error::LookupError) -> $error { + $error::CannotLookup + } + } + + impl From<$error> for &'static str { + fn from(err: $error) -> &'static str { + use $crate::dispatch::ModuleDispatchError; + err.as_str() + } + } + + impl Into<$crate::dispatch::DispatchError> for $error { + fn into(self) -> $crate::dispatch::DispatchError { + use $crate::dispatch::ModuleDispatchError; + $crate::dispatch::DispatchError::new(None, self.as_u8(), Some(self.as_str())) + } + } + }; + (@GENERATE_AS_U8 + $self:ident + $error:ident + { $( $generated:tt )* } + $index:expr, + $name:ident + $( , $rest:ident )* + ) => { + $crate::decl_error! { + @GENERATE_AS_U8 + $self + $error + { + $( $generated )* + $error::$name => $index, + } + $index + 1, + $( $rest ),* + } + }; + (@GENERATE_AS_U8 + $self:ident + $error:ident + { $( $generated:tt )* } + $index:expr, + ) => { + match $self { + $error::Other(_) => 0, + $error::CannotLookup => 1, + $( $generated )* + } + } +} diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index e7386930b9..b815e00b9d 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -58,14 +58,16 @@ mod runtime; pub mod inherent; #[macro_use] pub mod unsigned; +#[macro_use] +pub mod error; mod double_map; pub mod traits; pub use self::storage::{StorageValue, StorageMap, StorageLinkedMap, StorageDoubleMap}; pub use self::hashable::Hashable; -pub use self::dispatch::{Parameter, Dispatchable, Callable, IsSubType}; +pub use self::dispatch::{Parameter, Callable, IsSubType}; pub use self::double_map::StorageDoubleMapWithHasher; -pub use runtime_io::{print, storage_root}; +pub use runtime_io::{print, storage_root, Printable}; pub use sr_primitives::{self, ConsensusEngineId}; /// Macro for easily creating a new implementation of the `Get` trait. Use similarly to @@ -128,7 +130,7 @@ macro_rules! fail { /// Used as `ensure!(expression_to_ensure, expression_to_return_on_false)`. #[macro_export] macro_rules! ensure { - ( $x:expr, $y:expr ) => {{ + ( $x:expr, $y:expr $(,)? ) => {{ if !$x { $crate::fail!($y); } @@ -142,7 +144,10 @@ macro_rules! ensure { #[macro_export] #[cfg(feature = "std")] macro_rules! assert_noop { - ( $x:expr , $y:expr ) => { + ( + $x:expr, + $y:expr $(,)? + ) => { let h = $crate::storage_root(); $crate::assert_err!($x, $y); assert_eq!(h, $crate::storage_root()); @@ -159,7 +164,7 @@ macro_rules! assert_noop { #[macro_export] #[cfg(feature = "std")] macro_rules! assert_err { - ( $x:expr , $y:expr ) => { + ( $x:expr , $y:expr $(,)? ) => { assert_eq!($x, Err($y)); } } diff --git a/srml/support/src/unsigned.rs b/srml/support/src/unsigned.rs index 1c62dd0c58..4d2ceddd79 100644 --- a/srml/support/src/unsigned.rs +++ b/srml/support/src/unsigned.rs @@ -17,7 +17,7 @@ #[doc(hidden)] pub use crate::sr_primitives::traits::ValidateUnsigned; #[doc(hidden)] -pub use crate::sr_primitives::transaction_validity::TransactionValidity; +pub use crate::sr_primitives::transaction_validity::{TransactionValidity, UnknownTransaction}; #[doc(hidden)] pub use crate::sr_primitives::ApplyError; @@ -72,7 +72,7 @@ macro_rules! impl_outer_validate_unsigned { #[allow(unreachable_patterns)] match call { $( Call::$module(inner_call) => $module::validate_unsigned(inner_call), )* - _ => $crate::unsigned::TransactionValidity::Invalid($crate::unsigned::ApplyError::BadSignature as i8), + _ => $crate::unsigned::UnknownTransaction::NoUnsignedValidator.into(), } } } @@ -81,8 +81,7 @@ macro_rules! impl_outer_validate_unsigned { #[cfg(test)] mod test_empty_call { - pub enum Call { - } + pub enum Call {} #[allow(unused)] pub struct Runtime; diff --git a/srml/support/test/tests/system.rs b/srml/support/test/tests/system.rs index afeb0e0195..344a2bec73 100644 --- a/srml/support/test/tests/system.rs +++ b/srml/support/test/tests/system.rs @@ -27,6 +27,13 @@ support::decl_event!( } ); +support::decl_error! { + pub enum Error { + TestError, + AnotherError + } +} + /// Origin for the system module. #[derive(PartialEq, Eq, Clone)] #[cfg_attr(feature = "std", derive(Debug))] diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index dab0c11fa5..2f1d0ab9e0 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -95,22 +95,24 @@ use rstd::prelude::*; use rstd::map; use rstd::marker::PhantomData; use sr_version::RuntimeVersion; -use sr_primitives::generic::{self, Era}; -use sr_primitives::Perbill; -use sr_primitives::weights::{ - Weight, DispatchInfo, DispatchClass, WeightMultiplier, SimpleDispatchInfo -}; -use sr_primitives::transaction_validity::{ - ValidTransaction, TransactionPriority, TransactionLongevity -}; -use sr_primitives::traits::{self, CheckEqual, SimpleArithmetic, Zero, SignedExtension, Convert, - SimpleBitOps, Hash, Member, MaybeDisplay, EnsureOrigin, DispatchError, SaturatedConversion, - MaybeSerializeDebugButNotDeserialize, MaybeSerializeDebug, StaticLookup, One, Bounded, Lookup, +use sr_primitives::{ + generic::{self, Era}, Perbill, ApplyError, ApplyOutcome, DispatchError, + weights::{Weight, DispatchInfo, DispatchClass, WeightMultiplier, SimpleDispatchInfo}, + transaction_validity::{ + ValidTransaction, TransactionPriority, TransactionLongevity, TransactionValidityError, + InvalidTransaction, TransactionValidity, + }, + traits::{ + self, CheckEqual, SimpleArithmetic, Zero, SignedExtension, Convert, Lookup, LookupError, + SimpleBitOps, Hash, Member, MaybeDisplay, EnsureOrigin, SaturatedConversion, + MaybeSerializeDebugButNotDeserialize, MaybeSerializeDebug, StaticLookup, One, Bounded, + }, }; + use primitives::storage::well_known_keys; use support::{ storage, decl_module, decl_event, decl_storage, StorageDoubleMap, StorageValue, StorageMap, - Parameter, for_each_tuple, traits::{Contains, Get} + Parameter, for_each_tuple, traits::{Contains, Get}, decl_error, }; use safe_mix::TripletMix; use codec::{Encode, Decode}; @@ -248,6 +250,8 @@ pub type KeyValue = (Vec, Vec); decl_module! { pub struct Module for enum Call where origin: T::Origin { + type Error = Error; + /// A big dispatch that will disallow any other transaction to be included. // TODO: this must be preferable available for testing really (not possible at the moment). #[weight = SimpleDispatchInfo::MaxOperational] @@ -323,10 +327,21 @@ decl_event!( /// An extrinsic completed successfully. ExtrinsicSuccess, /// An extrinsic failed. - ExtrinsicFailed, + ExtrinsicFailed(DispatchError), } ); +decl_error! { + /// Error for the System module + pub enum Error { + BadSignature, + BlockFull, + RequireSignedOrigin, + RequireRootOrigin, + RequireNoOrigin, + } +} + /// Origin for the System module. #[derive(PartialEq, Eq, Clone)] #[cfg_attr(feature = "std", derive(Debug))] @@ -510,32 +525,32 @@ impl EnsureOrigin for EnsureNever { /// Ensure that the origin `o` represents a signed extrinsic (i.e. transaction). /// Returns `Ok` with the account that signed the extrinsic or an `Err` otherwise. -pub fn ensure_signed(o: OuterOrigin) -> Result +pub fn ensure_signed(o: OuterOrigin) -> Result where OuterOrigin: Into, OuterOrigin>> { match o.into() { Ok(RawOrigin::Signed(t)) => Ok(t), - _ => Err("bad origin: expected to be a signed origin"), + _ => Err(Error::RequireSignedOrigin), } } /// Ensure that the origin `o` represents the root. Returns `Ok` or an `Err` otherwise. -pub fn ensure_root(o: OuterOrigin) -> Result<(), &'static str> +pub fn ensure_root(o: OuterOrigin) -> Result<(), Error> where OuterOrigin: Into, OuterOrigin>> { match o.into() { Ok(RawOrigin::Root) => Ok(()), - _ => Err("bad origin: expected to be a root origin"), + _ => Err(Error::RequireRootOrigin), } } /// Ensure that the origin `o` represents an unsigned extrinsic. Returns `Ok` or an `Err` otherwise. -pub fn ensure_none(o: OuterOrigin) -> Result<(), &'static str> +pub fn ensure_none(o: OuterOrigin) -> Result<(), Error> where OuterOrigin: Into, OuterOrigin>> { match o.into() { Ok(RawOrigin::None) => Ok(()), - _ => Err("bad origin: expected to be no origin"), + _ => Err(Error::RequireNoOrigin), } } @@ -811,11 +826,13 @@ impl Module { } /// To be called immediately after an extrinsic has been applied. - pub fn note_applied_extrinsic(r: &Result<(), &'static str>, _encoded_len: u32) { - Self::deposit_event(match r { - Ok(_) => Event::ExtrinsicSuccess, - Err(_) => Event::ExtrinsicFailed, - }); + pub fn note_applied_extrinsic(r: &ApplyOutcome, _encoded_len: u32) { + Self::deposit_event( + match r { + Ok(()) => Event::ExtrinsicSuccess, + Err(err) => Event::ExtrinsicFailed(err.clone()), + } + ); let next_extrinsic_index = Self::extrinsic_index().unwrap_or_default() + 1u32; @@ -844,7 +861,6 @@ impl Module { pub struct CheckWeight(PhantomData); impl CheckWeight { - /// Get the quota ratio of each dispatch class type. This indicates that all operational /// dispatches can use the full capacity of any resource, while user-triggered ones can consume /// a portion. @@ -859,31 +875,33 @@ impl CheckWeight { /// Checks if the current extrinsic can fit into the block with respect to block weight limits. /// /// Upon successes, it returns the new block weight as a `Result`. - fn check_weight(info: DispatchInfo) -> Result { + fn check_weight(info: DispatchInfo) -> Result { let current_weight = Module::::all_extrinsics_weight(); let maximum_weight = T::MaximumBlockWeight::get(); let limit = Self::get_dispatch_limit_ratio(info.class) * maximum_weight; let added_weight = info.weight.min(limit); let next_weight = current_weight.saturating_add(added_weight); if next_weight > limit { - return Err(DispatchError::Exhausted) + Err(InvalidTransaction::ExhaustsResources.into()) + } else { + Ok(next_weight) } - Ok(next_weight) } /// Checks if the current extrinsic can fit into the block with respect to block length limits. /// /// Upon successes, it returns the new block length as a `Result`. - fn check_block_length(info: DispatchInfo, len: usize) -> Result { + fn check_block_length(info: DispatchInfo, len: usize) -> Result { let current_len = Module::::all_extrinsics_len(); let maximum_len = T::MaximumBlockLength::get(); let limit = Self::get_dispatch_limit_ratio(info.class) * maximum_len; let added_len = len as u32; let next_len = current_len.saturating_add(added_len); if next_len > limit { - return Err(DispatchError::Exhausted) + Err(InvalidTransaction::ExhaustsResources.into()) + } else { + Ok(next_len) } - Ok(next_len) } /// get the priority of an extrinsic denoted by `info`. @@ -906,7 +924,7 @@ impl SignedExtension for CheckWeight { type AdditionalSigned = (); type Pre = (); - fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) } + fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } fn pre_dispatch( self, @@ -914,7 +932,7 @@ impl SignedExtension for CheckWeight { _call: &Self::Call, info: DispatchInfo, len: usize, - ) -> Result<(), DispatchError> { + ) -> Result<(), ApplyError> { let next_len = Self::check_block_length(info, len)?; AllExtrinsicsLen::put(next_len); let next_weight = Self::check_weight(info)?; @@ -928,12 +946,18 @@ impl SignedExtension for CheckWeight { _call: &Self::Call, info: DispatchInfo, len: usize, - ) -> Result { + ) -> TransactionValidity { // There is no point in writing to storage here since changes are discarded. This basically - // discards any transaction which is bigger than the length or weight limit **alone**,which + // discards any transaction which is bigger than the length or weight limit **alone**, which // is a guarantee that it will fail in the pre-dispatch phase. - let _ = Self::check_block_length(info, len)?; - let _ = Self::check_weight(info)?; + if let Err(e) = Self::check_block_length(info, len) { + return Err(e); + } + + if let Err(e) = Self::check_weight(info) { + return Err(e); + } + Ok(ValidTransaction { priority: Self::get_priority(info), ..Default::default() }) } } @@ -969,7 +993,7 @@ impl SignedExtension for CheckNonce { type AdditionalSigned = (); type Pre = (); - fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) } + fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } fn pre_dispatch( self, @@ -977,13 +1001,18 @@ impl SignedExtension for CheckNonce { _call: &Self::Call, _info: DispatchInfo, _len: usize, - ) -> Result<(), DispatchError> { + ) -> Result<(), ApplyError> { let expected = >::get(who); if self.0 != expected { return Err( - if self.0 < expected { DispatchError::Stale } else { DispatchError::Future } + if self.0 < expected { + InvalidTransaction::Stale + } else { + InvalidTransaction::Future + }.into() ) } + >::insert(who, expected + T::Index::one()); Ok(()) } @@ -994,11 +1023,11 @@ impl SignedExtension for CheckNonce { _call: &Self::Call, info: DispatchInfo, _len: usize, - ) -> Result { + ) -> TransactionValidity { // check index let expected = >::get(who); if self.0 < expected { - return Err(DispatchError::Stale) + return InvalidTransaction::Stale.into() } let provides = vec![Encode::encode(&(who, self.0))]; @@ -1048,7 +1077,7 @@ impl SignedExtension for CheckEra { _call: &Self::Call, _info: DispatchInfo, _len: usize, - ) -> Result { + ) -> TransactionValidity { let current_u64 = >::block_number().saturated_into::(); let valid_till = (self.0).0.death(current_u64); Ok(ValidTransaction { @@ -1057,11 +1086,14 @@ impl SignedExtension for CheckEra { }) } - fn additional_signed(&self) -> Result { + fn additional_signed(&self) -> Result { let current_u64 = >::block_number().saturated_into::(); let n = (self.0).0.birth(current_u64).saturated_into::(); - if !>::exists(n) { Err("transaction birth block ancient")? } - Ok(>::block_hash(n)) + if !>::exists(n) { + Err(InvalidTransaction::AncientBirthBlock.into()) + } else { + Ok(>::block_hash(n)) + } } } @@ -1089,7 +1121,7 @@ impl SignedExtension for CheckGenesis { type AdditionalSigned = T::Hash; type Pre = (); - fn additional_signed(&self) -> Result { + fn additional_signed(&self) -> Result { Ok(>::block_hash(T::BlockNumber::zero())) } } @@ -1118,7 +1150,7 @@ impl SignedExtension for CheckVersion { type AdditionalSigned = u32; type Pre = (); - fn additional_signed(&self) -> Result { + fn additional_signed(&self) -> Result { Ok(>::runtime_version().spec_version) } } @@ -1133,7 +1165,8 @@ impl Default for ChainContext { impl Lookup for ChainContext { type Source = ::Source; type Target = ::Target; - fn lookup(&self, s: Self::Source) -> rstd::result::Result { + + fn lookup(&self, s: Self::Source) -> Result { ::lookup(s) } } @@ -1143,10 +1176,10 @@ mod tests { use super::*; use runtime_io::with_externalities; use primitives::H256; - use sr_primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; + use sr_primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header, DispatchError}; use support::{impl_outer_origin, parameter_types}; - impl_outer_origin!{ + impl_outer_origin! { pub enum Origin for Test where system = super {} } @@ -1183,7 +1216,7 @@ mod tests { fn from(e: Event) -> u16 { match e { Event::ExtrinsicSuccess => 100, - Event::ExtrinsicFailed => 101, + Event::ExtrinsicFailed(_) => 101, } } } @@ -1232,16 +1265,19 @@ mod tests { System::initialize(&2, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); System::deposit_event(42u16); System::note_applied_extrinsic(&Ok(()), 0); - System::note_applied_extrinsic(&Err(""), 0); + System::note_applied_extrinsic(&Err(DispatchError::new(Some(1), 2, None)), 0); System::note_finished_extrinsics(); System::deposit_event(3u16); System::finalize(); - assert_eq!(System::events(), vec![ - EventRecord { phase: Phase::ApplyExtrinsic(0), event: 42u16, topics: vec![] }, - EventRecord { phase: Phase::ApplyExtrinsic(0), event: 100u16, topics: vec![] }, - EventRecord { phase: Phase::ApplyExtrinsic(1), event: 101u16, topics: vec![] }, - EventRecord { phase: Phase::Finalization, event: 3u16, topics: vec![] } - ]); + assert_eq!( + System::events(), + vec![ + EventRecord { phase: Phase::ApplyExtrinsic(0), event: 42u16, topics: vec![] }, + EventRecord { phase: Phase::ApplyExtrinsic(0), event: 100u16, topics: vec![] }, + EventRecord { phase: Phase::ApplyExtrinsic(1), event: 101u16, topics: vec![] }, + EventRecord { phase: Phase::Finalization, event: 3u16, topics: vec![] } + ] + ); }); } @@ -1440,14 +1476,17 @@ mod tests { let op = DispatchInfo { weight: 100, class: DispatchClass::Operational }; let len = 0_usize; - assert_eq!( - CheckWeight::(PhantomData).validate(&1, CALL, normal, len).unwrap().priority, - 100, - ); - assert_eq!( - CheckWeight::(PhantomData).validate(&1, CALL, op, len).unwrap().priority, - Bounded::max_value(), - ); + let priority = CheckWeight::(PhantomData) + .validate(&1, CALL, normal, len) + .unwrap() + .priority; + assert_eq!(priority, 100); + + let priority = CheckWeight::(PhantomData) + .validate(&1, CALL, op, len) + .unwrap() + .priority; + assert_eq!(priority, Bounded::max_value()); }) } @@ -1481,7 +1520,7 @@ mod tests { // future assert_eq!( CheckEra::::from(Era::mortal(4, 2)).additional_signed().err().unwrap(), - "transaction birth block ancient" + InvalidTransaction::AncientBirthBlock.into(), ); // correct @@ -1503,10 +1542,7 @@ mod tests { System::set_block_number(17); >::insert(16, H256::repeat_byte(1)); - assert_eq!( - ext.validate(&1, CALL, normal, len).unwrap().longevity, - 15, - ); + assert_eq!(ext.validate(&1, CALL, normal, len).unwrap().longevity, 15); }) } } diff --git a/subkey/src/main.rs b/subkey/src/main.rs index e0ac2cb8b6..a68674513a 100644 --- a/subkey/src/main.rs +++ b/subkey/src/main.rs @@ -103,6 +103,7 @@ fn execute(matches: clap::ArgMatches) where system::CheckNonce::::from(i), system::CheckWeight::::new(), balances::TakeFees::::from(f), + Default::default(), ) }; let password = matches.value_of("password"); @@ -185,7 +186,7 @@ fn execute(matches: clap::ArgMatches) where let raw_payload = SignedPayload::from_raw( function, extra(index, 0), - (VERSION.spec_version as u32, genesis_hash, genesis_hash, (), (), ()), + (VERSION.spec_version as u32, genesis_hash, genesis_hash, (), (), (), ()), ); let signature = raw_payload.using_encoded(|payload| { println!("Signing {}", HexDisplay::from(&payload)); -- GitLab From ca02bee0f08ad1c682f0b84eb410d52a234e3b75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Wed, 4 Sep 2019 17:14:42 +0100 Subject: [PATCH 057/275] client: only report block import to telemetry if new best (#3548) * client: only report block import to telemetry if new best * grandpa: fix tests * consensus: derive Default for ImportedAux * network: fix test --- core/client/src/client.rs | 24 +++++++++++--------- core/consensus/common/src/block_import.rs | 27 +++++++++-------------- core/finality-grandpa/src/light_import.rs | 7 +++++- core/finality-grandpa/src/tests.rs | 2 ++ core/network/src/test/block_import.rs | 9 ++++++-- 5 files changed, 40 insertions(+), 29 deletions(-) diff --git a/core/client/src/client.rs b/core/client/src/client.rs index eb07116690..474c80dd2a 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -879,11 +879,15 @@ impl Client where fork_choice, ); - telemetry!(SUBSTRATE_INFO; "block.import"; - "height" => height, - "best" => ?hash, - "origin" => ?origin - ); + if let Ok(ImportResult::Imported(ref aux)) = result { + if aux.is_new_best { + telemetry!(SUBSTRATE_INFO; "block.import"; + "height" => height, + "best" => ?hash, + "origin" => ?origin + ); + } + } result } @@ -985,7 +989,7 @@ impl Client where operation.notify_imported = Some((hash, origin, import_headers.into_post(), is_new_best, storage_changes)); } - Ok(ImportResult::imported()) + Ok(ImportResult::imported(is_new_best)) } fn block_execution( @@ -1500,7 +1504,7 @@ impl<'a, B, E, Block, RA> consensus::BlockImport for &'a Client return Ok(ImportResult::KnownBad), } - Ok(ImportResult::imported()) + Ok(ImportResult::imported(false)) } } @@ -1528,7 +1532,7 @@ impl consensus::BlockImport for Client } } -impl Finalizer for Client where +impl Finalizer for Client where B: backend::Backend, E: CallExecutor, Block: BlockT, @@ -1552,7 +1556,7 @@ impl Finalizer for Client Finalizer for &Client where +impl Finalizer for &Client where B: backend::Backend, E: CallExecutor, Block: BlockT, @@ -1833,7 +1837,7 @@ impl backend::AuxStore for &Client B: backend::Backend, E: CallExecutor, Block: BlockT, -{ +{ fn insert_aux< 'a, diff --git a/core/consensus/common/src/block_import.rs b/core/consensus/common/src/block_import.rs index 1910a7e775..02f7979e9c 100644 --- a/core/consensus/common/src/block_import.rs +++ b/core/consensus/common/src/block_import.rs @@ -39,7 +39,7 @@ pub enum ImportResult { } /// Auxiliary data associated with an imported block result. -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, Default, PartialEq, Eq)] pub struct ImportedAux { /// Clear all pending justification requests. pub clear_justification_requests: bool, @@ -49,24 +49,19 @@ pub struct ImportedAux { pub bad_justification: bool, /// Request a finality proof for the given block. pub needs_finality_proof: bool, -} - -impl Default for ImportedAux { - fn default() -> ImportedAux { - ImportedAux { - clear_justification_requests: false, - needs_justification: false, - bad_justification: false, - needs_finality_proof: false, - } - } + /// Whether the block that was imported is the new best block. + pub is_new_best: bool, } impl ImportResult { - /// Returns default value for `ImportResult::Imported` with both - /// `clear_justification_requests` and `needs_justification` set to false. - pub fn imported() -> ImportResult { - ImportResult::Imported(ImportedAux::default()) + /// Returns default value for `ImportResult::Imported` with + /// `clear_justification_requests`, `needs_justification`, + /// `bad_justification` and `needs_finality_proof` set to false. + pub fn imported(is_new_best: bool) -> ImportResult { + let mut aux = ImportedAux::default(); + aux.is_new_best = is_new_best; + + ImportResult::Imported(aux) } } diff --git a/core/finality-grandpa/src/light_import.rs b/core/finality-grandpa/src/light_import.rs index 6c86c6b38d..f57bcaebed 100644 --- a/core/finality-grandpa/src/light_import.rs +++ b/core/finality-grandpa/src/light_import.rs @@ -467,7 +467,8 @@ fn do_finalize_block>( // update last finalized block reference data.last_finalized = hash; - Ok(ImportResult::imported()) + // we just finalized this block, so if we were importing it, it is now the new best + Ok(ImportResult::imported(true)) } /// Load light import aux data from the store. @@ -679,6 +680,7 @@ pub mod tests { needs_justification: false, bad_justification: false, needs_finality_proof: false, + is_new_best: true, })); } @@ -690,6 +692,7 @@ pub mod tests { needs_justification: false, bad_justification: false, needs_finality_proof: false, + is_new_best: true, })); } @@ -702,6 +705,7 @@ pub mod tests { needs_justification: false, bad_justification: false, needs_finality_proof: true, + is_new_best: true, })); } @@ -717,6 +721,7 @@ pub mod tests { needs_justification: false, bad_justification: false, needs_finality_proof: true, + is_new_best: false, }, )); } diff --git a/core/finality-grandpa/src/tests.rs b/core/finality-grandpa/src/tests.rs index f73cab97f8..9193dae71a 100644 --- a/core/finality-grandpa/src/tests.rs +++ b/core/finality-grandpa/src/tests.rs @@ -1006,6 +1006,7 @@ fn allows_reimporting_change_blocks() { clear_justification_requests: false, bad_justification: false, needs_finality_proof: false, + is_new_best: true, }), ); @@ -1054,6 +1055,7 @@ fn test_bad_justification() { needs_justification: true, clear_justification_requests: false, bad_justification: true, + is_new_best: true, ..Default::default() }), ); diff --git a/core/network/src/test/block_import.rs b/core/network/src/test/block_import.rs index ceb0451166..f2830548a5 100644 --- a/core/network/src/test/block_import.rs +++ b/core/network/src/test/block_import.rs @@ -16,8 +16,9 @@ //! Testing block import logic. +use consensus::ImportedAux; use consensus::import_queue::{ - import_single_block, IncomingBlock, BasicQueue, BlockImportError, BlockImportResult + import_single_block, BasicQueue, BlockImportError, BlockImportResult, IncomingBlock, }; use test_client::{self, prelude::*}; use test_client::runtime::{Block, Hash}; @@ -45,9 +46,13 @@ fn prepare_good_block() -> (TestClient, Hash, u64, PeerId, IncomingBlock) #[test] fn import_single_good_block_works() { let (_, _hash, number, peer_id, block) = prepare_good_block(); + + let mut expected_aux = ImportedAux::default(); + expected_aux.is_new_best = true; + match import_single_block(&mut test_client::new(), BlockOrigin::File, block, &mut PassThroughVerifier(true)) { Ok(BlockImportResult::ImportedUnknown(ref num, ref aux, ref org)) - if *num == number && *aux == Default::default() && *org == Some(peer_id) => {} + if *num == number && *aux == expected_aux && *org == Some(peer_id) => {} _ => panic!() } } -- GitLab From f6dc9f91615af798a378924cb12ebbf481515cf6 Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Wed, 4 Sep 2019 18:45:35 +0200 Subject: [PATCH 058/275] srml-contracts: Fix values used for state rent (#3550) * Fix units for srml-contracts * Bump node runtime version. --- node/runtime/src/lib.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 46667db36f..ded3fa483d 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -360,6 +360,10 @@ parameter_types! { pub const ContractTransactionBaseFee: Balance = 1 * CENTS; pub const ContractTransactionByteFee: Balance = 10 * MILLICENTS; pub const ContractFee: Balance = 1 * CENTS; + pub const TombstoneDeposit: Balance = 1 * DOLLARS; + pub const RentByteFee: Balance = 1 * DOLLARS; + pub const RentDepositOffset: Balance = 1000 * DOLLARS; + pub const SurchargeReward: Balance = 150 * DOLLARS; } impl contracts::Trait for Runtime { @@ -371,11 +375,11 @@ impl contracts::Trait for Runtime { type TrieIdGenerator = contracts::TrieIdFromParentCounter; type GasPayment = (); type SignedClaimHandicap = contracts::DefaultSignedClaimHandicap; - type TombstoneDeposit = contracts::DefaultTombstoneDeposit; + type TombstoneDeposit = TombstoneDeposit; type StorageSizeOffset = contracts::DefaultStorageSizeOffset; - type RentByteFee = contracts::DefaultRentByteFee; - type RentDepositOffset = contracts::DefaultRentDepositOffset; - type SurchargeReward = contracts::DefaultSurchargeReward; + type RentByteFee = RentByteFee; + type RentDepositOffset = RentDepositOffset; + type SurchargeReward = SurchargeReward; type TransferFee = ContractTransferFee; type CreationFee = ContractCreationFee; type TransactionBaseFee = ContractTransactionBaseFee; -- GitLab From ac6a2a783f0e1f4a814cf2add40275730cd41be1 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 5 Sep 2019 08:27:04 +0300 Subject: [PATCH 059/275] Changes tries build cache (#2933) * changes tries build cache added CT build cache test * fix lines width * fixed some grumbles * clear cache when: digests disabled, top-level or skewed digest is built * cached_changed_keys -> with_cached_changed_keys --- core/client/db/src/lib.rs | 36 ++- core/client/src/backend.rs | 5 +- core/client/src/call_executor.rs | 15 +- core/client/src/client.rs | 15 +- core/client/src/in_mem.rs | 16 +- core/client/src/light/backend.rs | 4 +- core/client/src/light/call_executor.rs | 9 +- core/client/src/light/fetcher.rs | 2 +- core/state-machine/src/changes_trie/build.rs | 129 +++++++-- .../src/changes_trie/build_cache.rs | 262 ++++++++++++++++++ core/state-machine/src/changes_trie/input.rs | 11 + core/state-machine/src/changes_trie/mod.rs | 125 ++++++++- .../state-machine/src/changes_trie/storage.rs | 23 +- core/state-machine/src/ext.rs | 13 +- core/state-machine/src/lib.rs | 19 +- core/state-machine/src/testing.rs | 2 +- 16 files changed, 620 insertions(+), 66 deletions(-) create mode 100644 core/state-machine/src/changes_trie/build_cache.rs diff --git a/core/client/db/src/lib.rs b/core/client/db/src/lib.rs index 05a1dfc97e..f5ece21fbb 100644 --- a/core/client/db/src/lib.rs +++ b/core/client/db/src/lib.rs @@ -36,7 +36,7 @@ mod utils; use std::sync::Arc; use std::path::PathBuf; use std::io; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use client::backend::NewBlockState; use client::blockchain::HeaderBackend; @@ -58,7 +58,7 @@ use sr_primitives::traits::{ }; use state_machine::backend::Backend as StateBackend; use executor::RuntimeInfo; -use state_machine::{CodeExecutor, DBValue}; +use state_machine::{CodeExecutor, DBValue, ChangesTrieTransaction, ChangesTrieCacheAction, ChangesTrieBuildCache}; use crate::utils::{Meta, db_err, meta_keys, read_db, block_id_to_lookup_key, read_meta}; use client::leaves::{LeafSet, FinalizationDisplaced}; use client::children; @@ -405,6 +405,7 @@ pub struct BlockImportOperation { storage_updates: StorageCollection, child_storage_updates: ChildStorageCollection, changes_trie_updates: MemoryDB, + changes_trie_cache_update: Option>>, pending_block: Option>, aux_ops: Vec<(Vec, Option>)>, finalized_blocks: Vec<(BlockId, Option)>, @@ -487,8 +488,12 @@ where Block: BlockT, Ok(root) } - fn update_changes_trie(&mut self, update: MemoryDB) -> Result<(), client::error::Error> { - self.changes_trie_updates = update; + fn update_changes_trie( + &mut self, + update: ChangesTrieTransaction>, + ) -> Result<(), client::error::Error> { + self.changes_trie_updates = update.0; + self.changes_trie_cache_update = Some(update.1); Ok(()) } @@ -565,6 +570,7 @@ pub struct DbChangesTrieStorage { db: Arc, meta: Arc, Block::Hash>>>, min_blocks_to_keep: Option, + cache: RwLock>>, _phantom: ::std::marker::PhantomData, } @@ -576,6 +582,11 @@ impl> DbChangesTrieStorage { } } + /// Commit changes into changes trie build cache. + pub fn commit_cache(&self, cache_update: ChangesTrieCacheAction>) { + self.cache.write().perform(cache_update); + } + /// Prune obsolete changes tries. pub fn prune( &self, @@ -699,6 +710,14 @@ where self } + fn with_cached_changed_keys( + &self, + root: &H256, + functor: &mut dyn FnMut(&HashMap>, HashSet>>), + ) -> bool { + self.cache.read().with_changed_keys(root, functor) + } + fn get(&self, key: &H256, _prefix: Prefix) -> Result, String> { self.db.get(columns::CHANGES_TRIE, &key[..]) .map_err(|err| format!("{}", err)) @@ -783,6 +802,7 @@ impl> Backend { db, meta, min_blocks_to_keep: if is_archive_pruning { None } else { Some(MIN_BLOCKS_TO_KEEP_CHANGES_TRIES_FOR) }, + cache: RwLock::new(ChangesTrieBuildCache::new()), _phantom: Default::default(), }; @@ -1098,7 +1118,6 @@ impl> Backend { self.changes_tries_storage.commit(&mut transaction, changes_trie_updates); let cache = operation.old_state.release(); // release state reference so that it can be finalized - if finalized { // TODO: ensure best chain contains this block. self.ensure_sequential_finalization(header, Some(last_finalized_hash))?; @@ -1155,6 +1174,10 @@ impl> Backend { let write_result = self.storage.db.write(transaction).map_err(db_err); + if let Some(changes_trie_cache_update) = operation.changes_trie_cache_update { + self.changes_tries_storage.commit_cache(changes_trie_cache_update); + } + if let Some((number, hash, enacted, retracted, displaced_leaf, is_best, mut cache)) = imported { if let Err(e) = write_result { let mut leaves = self.blockchain.leaves.write(); @@ -1288,6 +1311,7 @@ impl client::backend::Backend for Backend whe storage_updates: Default::default(), child_storage_updates: Default::default(), changes_trie_updates: MemoryDB::default(), + changes_trie_cache_update: None, aux_ops: Vec::new(), finalized_blocks: Vec::new(), set_head: None, @@ -1515,7 +1539,7 @@ mod tests { let mut op = backend.begin_operation().unwrap(); backend.begin_state_operation(&mut op, block_id).unwrap(); op.set_block_data(header, None, None, NewBlockState::Best).unwrap(); - op.update_changes_trie(changes_trie_update).unwrap(); + op.update_changes_trie((changes_trie_update, ChangesTrieCacheAction::Clear)).unwrap(); backend.commit_operation(op).unwrap(); header_hash diff --git a/core/client/src/backend.rs b/core/client/src/backend.rs index a42fdcff24..457a1b86ec 100644 --- a/core/client/src/backend.rs +++ b/core/client/src/backend.rs @@ -24,10 +24,9 @@ use primitives::ChangesTrieConfiguration; use sr_primitives::{generic::BlockId, Justification, StorageOverlay, ChildrenStorageOverlay}; use sr_primitives::traits::{Block as BlockT, NumberFor}; use state_machine::backend::Backend as StateBackend; -use state_machine::ChangesTrieStorage as StateChangesTrieStorage; +use state_machine::{ChangesTrieStorage as StateChangesTrieStorage, ChangesTrieTransaction}; use consensus::{well_known_cache_keys, BlockOrigin}; use hash_db::Hasher; -use trie::MemoryDB; use parking_lot::Mutex; /// In memory array of storage values. @@ -116,7 +115,7 @@ pub trait BlockImportOperation where child_update: ChildStorageCollection, ) -> error::Result<()>; /// Inject changes trie data into the database. - fn update_changes_trie(&mut self, update: MemoryDB) -> error::Result<()>; + fn update_changes_trie(&mut self, update: ChangesTrieTransaction>) -> error::Result<()>; /// Insert auxiliary keys. Values are `None` if should be deleted. fn insert_aux(&mut self, ops: I) -> error::Result<()> where I: IntoIterator, Option>)>; diff --git a/core/client/src/call_executor.rs b/core/client/src/call_executor.rs index e82bd9a22c..0556bc7bff 100644 --- a/core/client/src/call_executor.rs +++ b/core/client/src/call_executor.rs @@ -17,15 +17,15 @@ use std::{sync::Arc, cmp::Ord, panic::UnwindSafe, result, cell::RefCell, rc::Rc}; use codec::{Encode, Decode}; use sr_primitives::{ - generic::BlockId, traits::Block as BlockT, + generic::BlockId, traits::Block as BlockT, traits::NumberFor, }; use state_machine::{ self, OverlayedChanges, Ext, CodeExecutor, ExecutionManager, ExecutionStrategy, NeverOffchainExt, backend::Backend as _, + ChangesTrieTransaction, }; use executor::{RuntimeVersion, RuntimeInfo, NativeVersion}; use hash_db::Hasher; -use trie::MemoryDB; use primitives::{offchain, H256, Blake2Hasher, NativeOrEncoded, NeverNativeValue}; use crate::runtime_api::{ProofRecorder, InitializeBlock}; @@ -111,7 +111,14 @@ where manager: ExecutionManager, native_call: Option, side_effects_handler: Option<&mut O>, - ) -> Result<(NativeOrEncoded, (S::Transaction, H::Out), Option>), error::Error>; + ) -> Result< + ( + NativeOrEncoded, + (S::Transaction, H::Out), + Option>> + ), + error::Error, + >; /// Execute a call to a contract on top of given state, gathering execution proof. /// @@ -345,7 +352,7 @@ where ) -> error::Result<( NativeOrEncoded, (S::Transaction, ::Out), - Option>, + Option>>, )> { state_machine::new( state, diff --git a/core/client/src/client.rs b/core/client/src/client.rs index 474c80dd2a..50e962c8b5 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -43,7 +43,8 @@ use sr_primitives::{ use state_machine::{ DBValue, Backend as StateBackend, CodeExecutor, ChangesTrieAnchorBlockId, ExecutionStrategy, ExecutionManager, prove_read, prove_child_read, - ChangesTrieRootsStorage, ChangesTrieStorage, ChangesTrieConfigurationRange, + ChangesTrieRootsStorage, ChangesTrieStorage, + ChangesTrieTransaction, ChangesTrieConfigurationRange, key_changes, key_changes_proof, OverlayedChanges, NeverOffchainExt, }; use executor::{RuntimeVersion, RuntimeInfo}; @@ -86,7 +87,7 @@ type StorageUpdate = < >::BlockImportOperation as BlockImportOperation >::State as state_machine::Backend>::Transaction; -type ChangesUpdate = trie::MemoryDB; +type ChangesUpdate = ChangesTrieTransaction>; /// Execution strategies settings. #[derive(Debug, Clone)] @@ -635,6 +636,14 @@ impl Client where self } + fn with_cached_changed_keys( + &self, + root: &H256, + functor: &mut dyn FnMut(&HashMap>, HashSet>>), + ) -> bool { + self.storage.with_cached_changed_keys(root, functor) + } + fn get(&self, key: &H256, prefix: Prefix) -> Result, String> { self.storage.get(key, prefix) } @@ -1001,7 +1010,7 @@ impl Client where body: Option>, ) -> error::Result<( Option>, - Option>, + Option>>, Option<( Vec<(Vec, Option>)>, Vec<(Vec, Vec<(Vec, Option>)>)> diff --git a/core/client/src/in_mem.rs b/core/client/src/in_mem.rs index 58bfa05a36..3c6a1e18c0 100644 --- a/core/client/src/in_mem.rs +++ b/core/client/src/in_mem.rs @@ -16,7 +16,7 @@ //! In memory client backend -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::sync::Arc; use parking_lot::{RwLock, Mutex}; use primitives::{ChangesTrieConfiguration, storage::well_known_keys}; @@ -24,7 +24,7 @@ use sr_primitives::generic::{BlockId, DigestItem}; use sr_primitives::traits::{Block as BlockT, Header as HeaderT, Zero, NumberFor}; use sr_primitives::{Justification, StorageOverlay, ChildrenStorageOverlay}; use state_machine::backend::{Backend as StateBackend, InMemory}; -use state_machine::{self, InMemoryChangesTrieStorage, ChangesTrieAnchorBlockId}; +use state_machine::{self, InMemoryChangesTrieStorage, ChangesTrieAnchorBlockId, ChangesTrieTransaction}; use hash_db::{Hasher, Prefix}; use trie::MemoryDB; use consensus::well_known_cache_keys::Id as CacheKeyId; @@ -484,8 +484,8 @@ where Ok(()) } - fn update_changes_trie(&mut self, update: MemoryDB) -> error::Result<()> { - self.changes_trie_update = Some(update); + fn update_changes_trie(&mut self, update: ChangesTrieTransaction>) -> error::Result<()> { + self.changes_trie_update = Some(update.0); Ok(()) } @@ -766,6 +766,14 @@ impl state_machine::ChangesTrieStorage> for Change self } + fn with_cached_changed_keys( + &self, + _root: &H::Out, + _functor: &mut dyn FnMut(&HashMap>, HashSet>>), + ) -> bool { + false + } + fn get(&self, key: &H::Out, prefix: Prefix) -> Result, String> { self.0.get(key, prefix) } diff --git a/core/client/src/light/backend.rs b/core/client/src/light/backend.rs index 7de922f145..6b2f2f5c0a 100644 --- a/core/client/src/light/backend.rs +++ b/core/client/src/light/backend.rs @@ -22,7 +22,7 @@ use std::sync::{Arc, Weak}; use parking_lot::{RwLock, Mutex}; use sr_primitives::{generic::BlockId, Justification, StorageOverlay, ChildrenStorageOverlay}; -use state_machine::{Backend as StateBackend, TrieBackend, backend::InMemory as InMemoryState}; +use state_machine::{Backend as StateBackend, TrieBackend, backend::InMemory as InMemoryState, ChangesTrieTransaction}; use sr_primitives::traits::{Block as BlockT, NumberFor, Zero, Header}; use crate::in_mem::{self, check_genesis_storage}; use crate::backend::{ @@ -284,7 +284,7 @@ where Ok(()) } - fn update_changes_trie(&mut self, _update: MemoryDB) -> ClientResult<()> { + fn update_changes_trie(&mut self, _update: ChangesTrieTransaction>) -> ClientResult<()> { // we're not storing anything locally => ignore changes Ok(()) } diff --git a/core/client/src/light/call_executor.rs b/core/client/src/light/call_executor.rs index f41c14fd42..fd6ae68e8e 100644 --- a/core/client/src/light/call_executor.rs +++ b/core/client/src/light/call_executor.rs @@ -25,10 +25,10 @@ use std::{ use codec::{Encode, Decode}; use primitives::{offchain, H256, Blake2Hasher, convert_hash, NativeOrEncoded}; use sr_primitives::generic::BlockId; -use sr_primitives::traits::{One, Block as BlockT, Header as HeaderT}; +use sr_primitives::traits::{One, Block as BlockT, Header as HeaderT, NumberFor}; use state_machine::{ self, Backend as StateBackend, CodeExecutor, OverlayedChanges, - ExecutionStrategy, create_proof_check_backend, + ExecutionStrategy, ChangesTrieTransaction, create_proof_check_backend, execution_proof_check_on_trie_backend, ExecutionManager, NeverOffchainExt }; use hash_db::Hasher; @@ -40,7 +40,6 @@ use crate::call_executor::CallExecutor; use crate::error::{Error as ClientError, Result as ClientResult}; use crate::light::fetcher::{Fetcher, RemoteCallRequest}; use executor::{RuntimeVersion, NativeVersion}; -use trie::MemoryDB; /// Call executor that executes methods on remote node, querying execution proof /// and checking proof by re-executing locally. @@ -185,7 +184,7 @@ where ) -> ClientResult<( NativeOrEncoded, (S::Transaction, ::Out), - Option>, + Option>>, )> { Err(ClientError::NotAvailableOnLightClient.into()) } @@ -365,7 +364,7 @@ impl CallExecutor for ) -> ClientResult<( NativeOrEncoded, (S::Transaction, ::Out), - Option>, + Option>>, )> { // there's no actual way/need to specify native/wasm execution strategy on light node // => we can safely ignore passed values diff --git a/core/client/src/light/fetcher.rs b/core/client/src/light/fetcher.rs index 205a3de476..14a3c72b05 100644 --- a/core/client/src/light/fetcher.rs +++ b/core/client/src/light/fetcher.rs @@ -460,7 +460,7 @@ struct RootsStorage<'a, Number: SimpleArithmetic, Hash: 'a> { impl<'a, H, Number, Hash> ChangesTrieRootsStorage for RootsStorage<'a, Number, Hash> where H: Hasher, - Number: ::std::fmt::Display + Clone + SimpleArithmetic + Encode + Decode + Send + Sync + 'static, + Number: ::std::fmt::Display + ::std::hash::Hash + Clone + SimpleArithmetic + Encode + Decode + Send + Sync + 'static, Hash: 'a + Send + Sync + Clone + AsRef<[u8]>, { fn build_anchor( diff --git a/core/state-machine/src/changes_trie/build.rs b/core/state-machine/src/changes_trie/build.rs index e5f539f483..824bdd3542 100644 --- a/core/state-machine/src/changes_trie/build.rs +++ b/core/state-machine/src/changes_trie/build.rs @@ -33,7 +33,7 @@ use crate::changes_trie::input::ChildIndex; /// /// Returns Err if storage error has occurred OR if storage haven't returned /// required data. -pub fn prepare_input<'a, B, H, Number>( +pub(crate) fn prepare_input<'a, B, H, Number>( backend: &'a B, storage: &'a dyn Storage, config: ConfigurationRange<'a, Number>, @@ -42,6 +42,7 @@ pub fn prepare_input<'a, B, H, Number>( ) -> Result<( impl Iterator> + 'a, Vec<(ChildIndex, impl Iterator> + 'a)>, + Vec, ), String> where B: Backend, @@ -52,12 +53,14 @@ pub fn prepare_input<'a, B, H, Number>( let (extrinsics_input, children_extrinsics_input) = prepare_extrinsics_input( backend, &number, - changes)?; - let (digest_input, mut children_digest_input) = prepare_digest_input::( + changes, + )?; + let (digest_input, mut children_digest_input, digest_input_blocks) = prepare_digest_input::( parent, config, - &number, - storage)?; + number, + storage, + )?; let mut children_digest = Vec::with_capacity(children_extrinsics_input.len()); for (child_index, ext_iter) in children_extrinsics_input.into_iter() { @@ -79,6 +82,7 @@ pub fn prepare_input<'a, B, H, Number>( Ok(( extrinsics_input.chain(digest_input), children_digest, + digest_input_blocks, )) } /// Prepare ExtrinsicIndex input pairs. @@ -186,12 +190,13 @@ fn prepare_extrinsics_input_inner<'a, B, H, Number>( /// Prepare DigestIndex input pairs. fn prepare_digest_input<'a, H, Number>( parent: &'a AnchorBlockId, - config: ConfigurationRange<'a, Number>, - block: &Number, + config: ConfigurationRange, + block: Number, storage: &'a dyn Storage, ) -> Result<( impl Iterator> + 'a, BTreeMap, impl Iterator> + 'a>, + Vec, ), String> where H: Hasher, @@ -207,16 +212,16 @@ fn prepare_digest_input<'a, H, Number>( block.clone() }; - digest_build_iterator(config, block_for_digest) + let digest_input_blocks = digest_build_iterator(config, block_for_digest).collect::>(); + digest_input_blocks.clone().into_iter() .try_fold( - (BTreeMap::new(), BTreeMap::new()), - move |(mut map, mut child_map), digest_build_block| { + (BTreeMap::new(), BTreeMap::new()), move |(mut map, mut child_map), digest_build_block| { let extrinsic_prefix = ExtrinsicIndex::key_neutral_prefix(digest_build_block.clone()); let digest_prefix = DigestIndex::key_neutral_prefix(digest_build_block.clone()); let child_prefix = ChildIndex::key_neutral_prefix(digest_build_block.clone()); let trie_root = storage.root(parent, digest_build_block.clone())?; let trie_root = trie_root.ok_or_else(|| format!("No changes trie root for block {}", digest_build_block.clone()))?; - + let insert_to_map = |map: &mut BTreeMap<_,_>, key: Vec| { match map.entry(key.clone()) { Entry::Vacant(entry) => { @@ -239,6 +244,30 @@ fn prepare_digest_input<'a, H, Number>( } }; + // try to get all updated keys from cache + let populated_from_cache = storage.with_cached_changed_keys( + &trie_root, + &mut |changed_keys| { + for (storage_key, changed_keys) in changed_keys { + let map = match storage_key { + Some(storage_key) => child_map + .entry(ChildIndex:: { + block: block.clone(), + storage_key: storage_key.clone(), + }) + .or_default(), + None => &mut map, + }; + for changed_key in changed_keys.iter().cloned() { + insert_to_map(map, changed_key); + } + } + } + ); + if populated_from_cache { + return Ok((map, child_map)); + } + let mut children_roots = BTreeMap::, _>::new(); { let trie_storage = TrieBackendEssence::<_, H>::new( @@ -272,7 +301,7 @@ fn prepare_digest_input<'a, H, Number>( storage_key, }; - let mut map = child_map.entry(child_index).or_insert_with(|| BTreeMap::, _>::new()); + let mut map = child_map.entry(child_index).or_default(); let trie_storage = TrieBackendEssence::<_, H>::new( crate::changes_trie::TrieBackendStorageAdapter(storage), trie_root, @@ -288,13 +317,12 @@ fn prepare_digest_input<'a, H, Number>( }); } Ok((map, child_map)) - }) - .map(|(pairs, child_pairs)| ( pairs.into_iter().map(|(_, (k, v))| InputPair::DigestIndex(k, v)), child_pairs.into_iter().map(|(sk, pairs)| (sk, pairs.into_iter().map(|(_, (k, v))| InputPair::DigestIndex(k, v)))).collect(), + digest_input_blocks, )) } @@ -304,8 +332,8 @@ mod test { use primitives::Blake2Hasher; use primitives::storage::well_known_keys::{EXTRINSIC_INDEX}; use crate::backend::InMemory; - use crate::changes_trie::Configuration; - use crate::changes_trie::storage::InMemoryStorage; + use crate::changes_trie::{RootsStorage, Configuration, storage::InMemoryStorage}; + use crate::changes_trie::build_cache::{IncompleteCacheAction, IncompleteCachedBuildData}; use crate::overlayed_changes::{OverlayedValue, OverlayedChangeSet}; use super::*; @@ -662,4 +690,73 @@ mod test { test_with_zero(16); test_with_zero(17); } + + #[test] + fn cache_is_used_when_changes_trie_is_built() { + let (backend, mut storage, changes, _) = prepare_for_build(0); + let config = changes.changes_trie_config.as_ref().unwrap(); + let parent = AnchorBlockId { hash: Default::default(), number: 15 }; + + // override some actual values from storage with values from the cache + // + // top-level storage: + // (keys 100, 101, 103, 105 are now missing from block#4 => they do not appear + // in l2 digest at block 16) + // + // "1" child storage: + // key 102 is now missing from block#4 => it doesn't appear in l2 digest at block 16 + // (keys 103, 104) are now added to block#4 => they appear in l2 digest at block 16 + // + // "2" child storage: + // (keys 105, 106) are now added to block#4 => they appear in l2 digest at block 16 + let trie_root4 = storage.root(&parent, 4).unwrap().unwrap(); + let cached_data4 = IncompleteCacheAction::CacheBuildData(IncompleteCachedBuildData::new()) + .set_digest_input_blocks(vec![1, 2, 3]) + .insert(None, vec![vec![100], vec![102]].into_iter().collect()) + .insert(Some(b"1".to_vec()), vec![vec![103], vec![104]].into_iter().collect()) + .insert(Some(b"2".to_vec()), vec![vec![105], vec![106]].into_iter().collect()) + .complete(4, &trie_root4); + storage.cache_mut().perform(cached_data4); + + let (root_changes_trie_nodes, child_changes_tries_nodes, _) = prepare_input( + &backend, + &storage, + configuration_range(&config, 0), + &changes, + &parent, + ).unwrap(); + assert_eq!(root_changes_trie_nodes.collect::>>(), vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16, key: vec![100] }, vec![0, 2, 3]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16, key: vec![101] }, vec![1]), + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16, key: vec![103] }, vec![0, 1]), + + InputPair::DigestIndex(DigestIndex { block: 16, key: vec![100] }, vec![4]), + InputPair::DigestIndex(DigestIndex { block: 16, key: vec![102] }, vec![4]), + InputPair::DigestIndex(DigestIndex { block: 16, key: vec![105] }, vec![8]), + ]); + + let child_changes_tries_nodes = child_changes_tries_nodes + .into_iter() + .map(|(k, i)| (k, i.collect::>())) + .collect::>(); + assert_eq!( + child_changes_tries_nodes.get(&ChildIndex { block: 16u64, storage_key: b"1".to_vec() }).unwrap(), + &vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16u64, key: vec![100] }, vec![0, 2, 3]), + + InputPair::DigestIndex(DigestIndex { block: 16u64, key: vec![103] }, vec![4]), + InputPair::DigestIndex(DigestIndex { block: 16u64, key: vec![104] }, vec![4]), + ], + ); + assert_eq!( + child_changes_tries_nodes.get(&ChildIndex { block: 16u64, storage_key: b"2".to_vec() }).unwrap(), + &vec![ + InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16u64, key: vec![100] }, vec![0, 2]), + + InputPair::DigestIndex(DigestIndex { block: 16u64, key: vec![105] }, vec![4]), + InputPair::DigestIndex(DigestIndex { block: 16u64, key: vec![106] }, vec![4]), + ], + ); + + } } diff --git a/core/state-machine/src/changes_trie/build_cache.rs b/core/state-machine/src/changes_trie/build_cache.rs new file mode 100644 index 0000000000..f5c7c28b6b --- /dev/null +++ b/core/state-machine/src/changes_trie/build_cache.rs @@ -0,0 +1,262 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Changes tries build cache. + +use std::collections::{HashMap, HashSet}; + +/// Changes trie build cache. +/// +/// Helps to avoid read of changes tries from the database when digest trie +/// is built. It holds changed keys for every block (indexed by changes trie +/// root) that could be referenced by future digest items. For digest entries +/// it also holds keys covered by this digest. Entries for top level digests +/// are never created, because they'll never be used to build other digests. +/// +/// Entries are pruned from the cache once digest block that is using this entry +/// is inserted (because digest block will includes all keys from this entry). +/// When there's a fork, entries are pruned when first changes trie is inserted. +pub struct BuildCache { + /// Map of block (implies changes true) number => changes trie root. + roots_by_number: HashMap, + /// Map of changes trie root => set of storage keys that are in this trie. + /// The `Option>` in inner `HashMap` stands for the child storage key. + /// If it is `None`, then the `HashSet` contains keys changed in top-level storage. + /// If it is `Some`, then the `HashSet` contains keys changed in child storage, identified by the key. + changed_keys: HashMap>, HashSet>>>, +} + +/// The action to perform when block-with-changes-trie is imported. +#[derive(Debug, PartialEq)] +pub enum CacheAction { + /// Cache data that has been collected when CT has been built. + CacheBuildData(CachedBuildData), + /// Clear cache from all existing entries. + Clear, +} + +/// The data that has been cached during changes trie building. +#[derive(Debug, PartialEq)] +pub struct CachedBuildData { + block: N, + trie_root: H, + digest_input_blocks: Vec, + changed_keys: HashMap>, HashSet>>, +} + +/// The action to perform when block-with-changes-trie is imported. +#[derive(Debug, PartialEq)] +pub(crate) enum IncompleteCacheAction { + /// Cache data that has been collected when CT has been built. + CacheBuildData(IncompleteCachedBuildData), + /// Clear cache from all existing entries. + Clear, +} + +/// The data (without changes trie root) that has been cached during changes trie building. +#[derive(Debug, PartialEq)] +pub(crate) struct IncompleteCachedBuildData { + digest_input_blocks: Vec, + changed_keys: HashMap>, HashSet>>, +} + +impl BuildCache + where + N: Eq + ::std::hash::Hash, + H: Eq + ::std::hash::Hash + Clone, +{ + /// Create new changes trie build cache. + pub fn new() -> Self { + BuildCache { + roots_by_number: HashMap::new(), + changed_keys: HashMap::new(), + } + } + + /// Get cached changed keys for changes trie with given root. + pub fn get(&self, root: &H) -> Option<&HashMap>, HashSet>>> { + self.changed_keys.get(&root) + } + + /// Execute given functor with cached entry for given block. + /// Returns true if the functor has been called and false otherwise. + pub fn with_changed_keys( + &self, + root: &H, + functor: &mut dyn FnMut(&HashMap>, HashSet>>), + ) -> bool { + match self.changed_keys.get(&root) { + Some(changed_keys) => { + functor(changed_keys); + true + }, + None => false, + } + } + + /// Insert data into cache. + pub fn perform(&mut self, action: CacheAction) { + match action { + CacheAction::CacheBuildData(data) => { + self.roots_by_number.insert(data.block, data.trie_root.clone()); + self.changed_keys.insert(data.trie_root, data.changed_keys); + + for digest_input_block in data.digest_input_blocks { + let digest_input_block_hash = self.roots_by_number.remove(&digest_input_block); + if let Some(digest_input_block_hash) = digest_input_block_hash { + self.changed_keys.remove(&digest_input_block_hash); + } + } + }, + CacheAction::Clear => { + self.roots_by_number.clear(); + self.changed_keys.clear(); + }, + } + } +} + +impl IncompleteCacheAction { + /// Returns true if we need to collect changed keys for this action. + pub fn collects_changed_keys(&self) -> bool { + match *self { + IncompleteCacheAction::CacheBuildData(_) => true, + IncompleteCacheAction::Clear => false, + } + } + + /// Complete cache action with computed changes trie root. + pub(crate) fn complete(self, block: N, trie_root: &H) -> CacheAction { + match self { + IncompleteCacheAction::CacheBuildData(build_data) => + CacheAction::CacheBuildData(build_data.complete(block, trie_root.clone())), + IncompleteCacheAction::Clear => CacheAction::Clear, + } + } + + /// Set numbers of blocks that are superseded by this new entry. + /// + /// If/when this build data is committed to the cache, entries for these blocks + /// will be removed from the cache. + pub(crate) fn set_digest_input_blocks(self, digest_input_blocks: Vec) -> Self { + match self { + IncompleteCacheAction::CacheBuildData(build_data) => + IncompleteCacheAction::CacheBuildData(build_data.set_digest_input_blocks(digest_input_blocks)), + IncompleteCacheAction::Clear => IncompleteCacheAction::Clear, + } + } + + /// Insert changed keys of given storage into cached data. + pub(crate) fn insert( + self, + storage_key: Option>, + changed_keys: HashSet>, + ) -> Self { + match self { + IncompleteCacheAction::CacheBuildData(build_data) => + IncompleteCacheAction::CacheBuildData(build_data.insert(storage_key, changed_keys)), + IncompleteCacheAction::Clear => IncompleteCacheAction::Clear, + } + } +} + +impl IncompleteCachedBuildData { + /// Create new cached data. + pub(crate) fn new() -> Self { + IncompleteCachedBuildData { + digest_input_blocks: Vec::new(), + changed_keys: HashMap::new(), + } + } + + fn complete(self, block: N, trie_root: H) -> CachedBuildData { + CachedBuildData { + block, + trie_root, + digest_input_blocks: self.digest_input_blocks, + changed_keys: self.changed_keys, + } + } + + fn set_digest_input_blocks(mut self, digest_input_blocks: Vec) -> Self { + self.digest_input_blocks = digest_input_blocks; + self + } + + fn insert( + mut self, + storage_key: Option>, + changed_keys: HashSet>, + ) -> Self { + self.changed_keys.insert(storage_key, changed_keys); + self + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn updated_keys_are_stored_when_non_top_level_digest_is_built() { + let mut data = IncompleteCachedBuildData::::new(); + data = data.insert(None, vec![vec![1]].into_iter().collect()); + assert_eq!(data.changed_keys.len(), 1); + + let mut cache = BuildCache::new(); + cache.perform(CacheAction::CacheBuildData(data.complete(1, 1))); + assert_eq!(cache.changed_keys.len(), 1); + assert_eq!( + cache.get(&1).unwrap().clone(), + vec![(None, vec![vec![1]].into_iter().collect())].into_iter().collect(), + ); + } + + #[test] + fn obsolete_entries_are_purged_when_new_ct_is_built() { + let mut cache = BuildCache::::new(); + cache.perform(CacheAction::CacheBuildData(IncompleteCachedBuildData::new() + .insert(None, vec![vec![1]].into_iter().collect()) + .complete(1, 1))); + cache.perform(CacheAction::CacheBuildData(IncompleteCachedBuildData::new() + .insert(None, vec![vec![2]].into_iter().collect()) + .complete(2, 2))); + cache.perform(CacheAction::CacheBuildData(IncompleteCachedBuildData::new() + .insert(None, vec![vec![3]].into_iter().collect()) + .complete(3, 3))); + + assert_eq!(cache.changed_keys.len(), 3); + + cache.perform(CacheAction::CacheBuildData(IncompleteCachedBuildData::new() + .set_digest_input_blocks(vec![1, 2, 3]) + .complete(4, 4))); + + assert_eq!(cache.changed_keys.len(), 1); + + cache.perform(CacheAction::CacheBuildData(IncompleteCachedBuildData::new() + .insert(None, vec![vec![8]].into_iter().collect()) + .complete(8, 8))); + cache.perform(CacheAction::CacheBuildData(IncompleteCachedBuildData::new() + .insert(None, vec![vec![12]].into_iter().collect()) + .complete(12, 12))); + + assert_eq!(cache.changed_keys.len(), 3); + + cache.perform(CacheAction::Clear); + + assert_eq!(cache.changed_keys.len(), 0); + } +} \ No newline at end of file diff --git a/core/state-machine/src/changes_trie/input.rs b/core/state-machine/src/changes_trie/input.rs index 17f3b41b22..e0bcad18be 100644 --- a/core/state-machine/src/changes_trie/input.rs +++ b/core/state-machine/src/changes_trie/input.rs @@ -78,6 +78,17 @@ pub enum InputKey { ChildIndex(ChildIndex), } +impl InputPair { + /// Extract storage key that this pair corresponds to. + pub fn key(&self) -> Option<&[u8]> { + match *self { + InputPair::ExtrinsicIndex(ref key, _) => Some(&key.key), + InputPair::DigestIndex(ref key, _) => Some(&key.key), + InputPair::ChildIndex(_, _) => None, + } + } +} + impl Into<(Vec, Vec)> for InputPair { fn into(self) -> (Vec, Vec) { match self { diff --git a/core/state-machine/src/changes_trie/mod.rs b/core/state-machine/src/changes_trie/mod.rs index 41234b3428..f771fddf61 100644 --- a/core/state-machine/src/changes_trie/mod.rs +++ b/core/state-machine/src/changes_trie/mod.rs @@ -49,6 +49,7 @@ //! are propagated through its storage root on the top level storage. mod build; +mod build_cache; mod build_iterator; mod changes_iterator; mod input; @@ -56,6 +57,7 @@ mod prune; mod storage; mod surface_iterator; +pub use self::build_cache::{BuildCache, CachedBuildData, CacheAction}; pub use self::storage::InMemoryStorage; pub use self::changes_iterator::{ key_changes, key_changes_proof, @@ -63,6 +65,7 @@ pub use self::changes_iterator::{ }; pub use self::prune::{prune, oldest_non_pruned_trie}; +use std::collections::{HashMap, HashSet}; use std::convert::TryInto; use hash_db::{Hasher, Prefix}; use crate::backend::Backend; @@ -70,6 +73,7 @@ use num_traits::{One, Zero}; use codec::{Decode, Encode}; use primitives; use crate::changes_trie::build::prepare_input; +use crate::changes_trie::build_cache::{IncompleteCachedBuildData, IncompleteCacheAction}; use crate::overlayed_changes::OverlayedChanges; use trie::{MemoryDB, DBValue, TrieMut}; use trie::trie_types::TrieDBMut; @@ -84,6 +88,7 @@ pub trait BlockNumber: Clone + From + TryInto + One + Zero + PartialEq + Ord + + ::std::hash::Hash + ::std::ops::Add + ::std::ops::Sub + ::std::ops::Mul + ::std::ops::Div + ::std::ops::Rem + @@ -98,6 +103,7 @@ impl BlockNumber for T where T: Clone + From + TryInto + One + Zero + PartialEq + Ord + + ::std::hash::Hash + ::std::ops::Add + ::std::ops::Sub + ::std::ops::Mul + ::std::ops::Div + ::std::ops::Rem + @@ -128,6 +134,13 @@ pub trait RootsStorage: Send + Sync { pub trait Storage: RootsStorage { /// Casts from self reference to RootsStorage reference. fn as_roots_storage(&self) -> &dyn RootsStorage; + /// Execute given functor with cached entry for given trie root. + /// Returns true if the functor has been called (cache entry exists) and false otherwise. + fn with_cached_changed_keys( + &self, + root: &H::Out, + functor: &mut dyn FnMut(&HashMap>, HashSet>>), + ) -> bool; /// Get a trie node. fn get(&self, key: &H::Out, prefix: Prefix) -> Result, String>; } @@ -166,7 +179,7 @@ pub fn build_changes_trie<'a, B: Backend, S: Storage, H: Hasher, N storage: Option<&'a S>, changes: &OverlayedChanges, parent_hash: H::Out, -) -> Result, H::Out)>, ()> +) -> Result, H::Out, CacheAction)>, ()> where H::Out: Ord + 'static, { @@ -184,15 +197,22 @@ pub fn build_changes_trie<'a, B: Backend, S: Storage, H: Hasher, N // build_anchor error should not be considered fatal let parent = storage.build_anchor(parent_hash).map_err(|_| ())?; + let block = parent.number.clone() + One::one(); // storage errors are considered fatal (similar to situations when runtime fetches values from storage) - let (input_pairs, child_input_pairs) = prepare_input::( + let (input_pairs, child_input_pairs, digest_input_blocks) = prepare_input::( backend, storage, - config, + config.clone(), changes, &parent, ).expect("changes trie: storage access is not allowed to fail within runtime"); + + // prepare cached data + let mut cache_action = prepare_cached_build_data(config, block.clone()); + let needs_changed_keys = cache_action.collects_changed_keys(); + cache_action = cache_action.set_digest_input_blocks(digest_input_blocks); + let mut mdb = MemoryDB::default(); let mut child_roots = Vec::with_capacity(child_input_pairs.len()); for (child_index, input_pairs) in child_input_pairs { @@ -200,11 +220,24 @@ pub fn build_changes_trie<'a, B: Backend, S: Storage, H: Hasher, N let mut root = Default::default(); { let mut trie = TrieDBMut::::new(&mut mdb, &mut root); - for (key, value) in input_pairs.map(Into::into) { + let mut storage_changed_keys = HashSet::new(); + for input_pair in input_pairs { + if needs_changed_keys { + if let Some(key) = input_pair.key() { + storage_changed_keys.insert(key.to_vec()); + } + } + + let (key, value) = input_pair.into(); not_empty = true; trie.insert(&key, &value) .expect("changes trie: insertion to trie is not allowed to fail within runtime"); } + + cache_action = cache_action.insert( + Some(child_index.storage_key.clone()), + storage_changed_keys, + ); } if not_empty { child_roots.push(input::InputPair::ChildIndex(child_index, root.as_ref().to_vec())); @@ -213,11 +246,91 @@ pub fn build_changes_trie<'a, B: Backend, S: Storage, H: Hasher, N let mut root = Default::default(); { let mut trie = TrieDBMut::::new(&mut mdb, &mut root); - for (key, value) in input_pairs.chain(child_roots.into_iter()).map(Into::into) { + for (key, value) in child_roots.into_iter().map(Into::into) { + trie.insert(&key, &value) + .expect("changes trie: insertion to trie is not allowed to fail within runtime"); + } + + let mut storage_changed_keys = HashSet::new(); + for input_pair in input_pairs { + if needs_changed_keys { + if let Some(key) = input_pair.key() { + storage_changed_keys.insert(key.to_vec()); + } + } + + let (key, value) = input_pair.into(); trie.insert(&key, &value) .expect("changes trie: insertion to trie is not allowed to fail within runtime"); } + cache_action = cache_action.insert( + None, + storage_changed_keys, + ); + } + + let cache_action = cache_action.complete(block, &root); + Ok(Some((mdb, root, cache_action))) +} + +/// Prepare empty cached build data for given block. +fn prepare_cached_build_data( + config: ConfigurationRange, + block: Number, +) -> IncompleteCacheAction { + // when digests are not enabled in configuration, we do not need to cache anything + // because it'll never be used again for building other tries + // => let's clear the cache + if !config.config.is_digest_build_enabled() { + return IncompleteCacheAction::Clear; + } + + // when this is the last block where current configuration is active + // => let's clear the cache + if config.end.as_ref() == Some(&block) { + return IncompleteCacheAction::Clear; + } + + // we do not need to cache anything when top-level digest trie is created, because + // it'll never be used again for building other tries + // => let's clear the cache + match config.config.digest_level_at_block(config.zero.clone(), block) { + Some((digest_level, _, _)) if digest_level == config.config.digest_levels => IncompleteCacheAction::Clear, + _ => IncompleteCacheAction::CacheBuildData(IncompleteCachedBuildData::new()), + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn cache_is_cleared_when_digests_are_disabled() { + let config = Configuration { digest_interval: 0, digest_levels: 0 }; + let config_range = ConfigurationRange { zero: 0, end: None, config: &config }; + assert_eq!(prepare_cached_build_data(config_range, 8u32), IncompleteCacheAction::Clear); + } + + #[test] + fn build_data_is_cached_when_digests_are_enabled() { + let config = Configuration { digest_interval: 8, digest_levels: 2 }; + let config_range = ConfigurationRange { zero: 0, end: None, config: &config }; + assert!(prepare_cached_build_data(config_range.clone(), 4u32).collects_changed_keys()); + assert!(prepare_cached_build_data(config_range.clone(), 7u32).collects_changed_keys()); + assert!(prepare_cached_build_data(config_range, 8u32).collects_changed_keys()); } - Ok(Some((mdb, root))) + #[test] + fn cache_is_cleared_when_digests_are_enabled_and_top_level_digest_is_built() { + let config = Configuration { digest_interval: 8, digest_levels: 2 }; + let config_range = ConfigurationRange { zero: 0, end: None, config: &config }; + assert_eq!(prepare_cached_build_data(config_range, 64u32), IncompleteCacheAction::Clear); + } + + #[test] + fn cache_is_cleared_when_end_block_of_configuration_is_built() { + let config = Configuration { digest_interval: 8, digest_levels: 2 }; + let config_range = ConfigurationRange { zero: 0, end: Some(4u32), config: &config }; + assert_eq!(prepare_cached_build_data(config_range.clone(), 4u32), IncompleteCacheAction::Clear); + } } diff --git a/core/state-machine/src/changes_trie/storage.rs b/core/state-machine/src/changes_trie/storage.rs index 65287241c1..f8c556a46c 100644 --- a/core/state-machine/src/changes_trie/storage.rs +++ b/core/state-machine/src/changes_trie/storage.rs @@ -16,16 +16,14 @@ //! Changes trie storage utilities. -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashSet, HashMap}; use hash_db::{Hasher, Prefix, EMPTY_PREFIX}; use trie::DBValue; use trie::MemoryDB; use parking_lot::RwLock; -use crate::changes_trie::{RootsStorage, Storage, AnchorBlockId, BlockNumber}; +use crate::changes_trie::{BuildCache, RootsStorage, Storage, AnchorBlockId, BlockNumber}; use crate::trie_backend_essence::TrieBackendStorage; -#[cfg(test)] -use std::collections::HashSet; #[cfg(test)] use crate::backend::insert_into_memory_db; #[cfg(test)] @@ -34,6 +32,7 @@ use crate::changes_trie::input::{InputPair, ChildIndex}; /// In-memory implementation of changes trie storage. pub struct InMemoryStorage { data: RwLock>, + cache: BuildCache, } /// Adapter for using changes trie storage as a TrieBackendEssence' storage. @@ -55,6 +54,7 @@ impl InMemoryStorage { roots: BTreeMap::new(), mdb, }), + cache: BuildCache::new(), } } @@ -74,6 +74,11 @@ impl InMemoryStorage { Self::with_db(proof_db) } + /// Get mutable cache reference. + pub fn cache_mut(&mut self) -> &mut BuildCache { + &mut self.cache + } + /// Create the storage with given blocks. pub fn with_blocks(blocks: Vec<(Number, H::Out)>) -> Self { Self { @@ -81,6 +86,7 @@ impl InMemoryStorage { roots: blocks.into_iter().collect(), mdb: MemoryDB::default(), }), + cache: BuildCache::new(), } } @@ -122,6 +128,7 @@ impl InMemoryStorage { roots, mdb, }), + cache: BuildCache::new(), } } @@ -169,6 +176,14 @@ impl Storage for InMemoryStorage>, HashSet>>), + ) -> bool { + self.cache.with_changed_keys(root, functor) + } + fn get(&self, key: &H::Out, prefix: Prefix) -> Result, String> { MemoryDB::::get(&self.data.read().mdb, key, prefix) } diff --git a/core/state-machine/src/ext.rs b/core/state-machine/src/ext.rs index 8281f0f9c2..fde3ba2b01 100644 --- a/core/state-machine/src/ext.rs +++ b/core/state-machine/src/ext.rs @@ -19,7 +19,10 @@ use std::{error, fmt, cmp::Ord}; use log::warn; use crate::backend::Backend; -use crate::changes_trie::{Storage as ChangesTrieStorage, build_changes_trie}; +use crate::changes_trie::{ + Storage as ChangesTrieStorage, CacheAction as ChangesTrieCacheAction, + build_changes_trie, +}; use crate::{Externalities, OverlayedChanges, ChildStorageKey}; use hash_db::Hasher; use primitives::{offchain, storage::well_known_keys::is_child_storage_key, traits::BareCryptoStorePtr}; @@ -78,7 +81,7 @@ where /// This differs from `storage_transaction` behavior, because the moment when /// `storage_changes_root` is called matters + we need to remember additional /// data at this moment (block number). - changes_trie_transaction: Option<(MemoryDB, H::Out)>, + changes_trie_transaction: Option<(MemoryDB, H::Out, ChangesTrieCacheAction)>, /// Additional externalities for offchain workers. /// /// If None, some methods from the trait might not be supported. @@ -119,14 +122,14 @@ where } /// Get the transaction necessary to update the backend. - pub fn transaction(mut self) -> ((B::Transaction, H::Out), Option>) { + pub fn transaction(mut self) -> ((B::Transaction, H::Out), Option>) { let _ = self.storage_root(); let (storage_transaction, changes_trie_transaction) = ( self.storage_transaction .expect("storage_transaction always set after calling storage root; qed"), self.changes_trie_transaction - .map(|(tx, _)| tx), + .map(|(tx, _, cache)| (tx, cache)), ); ( @@ -355,7 +358,7 @@ where self.overlay, parent_hash, )?; - Ok(self.changes_trie_transaction.as_ref().map(|(_, root)| root.clone())) + Ok(self.changes_trie_transaction.as_ref().map(|(_, root, _)| root.clone())) } fn offchain(&mut self) -> Option<&mut dyn offchain::Externalities> { diff --git a/core/state-machine/src/lib.rs b/core/state-machine/src/lib.rs index acc7c366b8..70a7f3b146 100644 --- a/core/state-machine/src/lib.rs +++ b/core/state-machine/src/lib.rs @@ -50,10 +50,12 @@ pub use changes_trie::{ Storage as ChangesTrieStorage, RootsStorage as ChangesTrieRootsStorage, InMemoryStorage as InMemoryChangesTrieStorage, + BuildCache as ChangesTrieBuildCache, + CacheAction as ChangesTrieCacheAction, ConfigurationRange as ChangesTrieConfigurationRange, key_changes, key_changes_proof, key_changes_proof_check, prune as prune_changes_tries, - oldest_non_pruned_trie as oldest_non_pruned_changes_trie + oldest_non_pruned_trie as oldest_non_pruned_changes_trie, }; pub use overlayed_changes::OverlayedChanges; pub use proving_backend::{ @@ -63,6 +65,11 @@ pub use proving_backend::{ pub use trie_backend_essence::{TrieBackendStorage, Storage}; pub use trie_backend::TrieBackend; +/// Type of changes trie transaction. +pub type ChangesTrieTransaction = ( + MemoryDB, + ChangesTrieCacheAction<::Out, N>, +); /// A wrapper around a child storage key. /// @@ -513,7 +520,7 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where pub fn execute( &mut self, strategy: ExecutionStrategy, - ) -> Result<(Vec, (B::Transaction, H::Out), Option>), Box> { + ) -> Result<(Vec, (B::Transaction, H::Out), Option>), Box> { // We are not giving a native call and thus we are sure that the result can never be a native // value. self.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>( @@ -537,7 +544,7 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where CallResult, bool, Option<(B::Transaction, H::Out)>, - Option>, + Option>, ) where R: Decode + Encode + PartialEq, NC: FnOnce() -> result::Result + UnwindSafe, @@ -571,7 +578,7 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where mut native_call: Option, orig_prospective: OverlayedChangeSet, on_consensus_failure: Handler, - ) -> (CallResult, Option<(B::Transaction, H::Out)>, Option>) where + ) -> (CallResult, Option<(B::Transaction, H::Out)>, Option>) where R: Decode + Encode + PartialEq, NC: FnOnce() -> result::Result + UnwindSafe, Handler: FnOnce( @@ -602,7 +609,7 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where compute_tx: bool, mut native_call: Option, orig_prospective: OverlayedChangeSet, - ) -> (CallResult, Option<(B::Transaction, H::Out)>, Option>) where + ) -> (CallResult, Option<(B::Transaction, H::Out)>, Option>) where R: Decode + Encode + PartialEq, NC: FnOnce() -> result::Result + UnwindSafe, { @@ -633,7 +640,7 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where ) -> Result<( NativeOrEncoded, Option<(B::Transaction, H::Out)>, - Option> + Option>, ), Box> where R: Decode + Encode + PartialEq, NC: FnOnce() -> result::Result + UnwindSafe, diff --git a/core/state-machine/src/testing.rs b/core/state-machine/src/testing.rs index 1065541e63..a40026b271 100644 --- a/core/state-machine/src/testing.rs +++ b/core/state-machine/src/testing.rs @@ -276,7 +276,7 @@ impl Externalities for TestExternalities Some(&self.changes_trie_storage), &self.overlay, parent, - )?.map(|(_, root)| root)) + )?.map(|(_, root, _)| root)) } fn offchain(&mut self) -> Option<&mut dyn offchain::Externalities> { -- GitLab From 499a88ccfbf82d87b8c2c4f0e77f7607d16ef6cc Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Fri, 6 Sep 2019 13:39:55 +0200 Subject: [PATCH 060/275] Remove dead code in Staking (#3559) * Remove some dead code from staking * Fix var name. --- srml/staking/src/lib.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index 0f8bc5c09a..837d12960d 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -1001,8 +1001,8 @@ impl Module { /// The total balance that can be slashed from a validator controller account as of /// right now. - pub fn slashable_balance(who: &T::AccountId) -> BalanceOf { - Self::stakers(who).total + pub fn slashable_balance_of(stash: &T::AccountId) -> BalanceOf { + Self::bonded(stash).and_then(Self::ledger).map(|l| l.active).unwrap_or_default() } // MUTABLES (DANGEROUS) @@ -1231,10 +1231,6 @@ impl Module { maybe_new_validators } - fn slashable_balance_of(stash: &T::AccountId) -> BalanceOf { - Self::bonded(stash).and_then(Self::ledger).map(|l| l.active).unwrap_or_default() - } - /// Select a new validator set from the assembled stakers and their role preferences. /// /// Returns the new `SlotStake` value and a set of newly selected _stash_ IDs. -- GitLab From b9e1782485f8b6e260b372886c76f96fc6952057 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Fri, 6 Sep 2019 15:45:53 +0200 Subject: [PATCH 061/275] Consensus: Proof of Work (#3473) * consensus-pow: init primtives and verifier * consensus-pow: add total difficulty auxiliary * consensus-pow: implement total difficulty chain selection * consensus-pow: implement pow import queue * consensus-pow-primitives: add mine into PowApi * consensus-pow: implement mining * Update lock file * Style fixes No run-on expressions allowed. * consensus-pow: refactor register_pow_inherent_data_provider * consensus-pow: make PowApi::mine yieldable * consensus-pow: better mining loop * Add missing license header * consensus-pow-primitives: clarify the meaning of None for PowApi::verify * consensus-pow: changing total difficulty addition to use saturating add * consensus-pow: change mine-loop error to log on error! level * consensus-pow: allow inserting arbitrary preruntime digest for pow The preruntime digest can be intepreted by the runtime as the block author/coinbase. * Fix line width * More line width fixes * consensus-pow: separate difficulty, verify API This makes it more apparent that currently in PoW engine, `difficulty` should be input, not output. * srml-pow: implementation of average_span difficulty adjustment * srml-pow: basic blake2 algo example * srml-pow-average-span: make it not require genesis config * srml-pow: add support for authorship * Missing license headers * consensus-pow: PowAlgorithm trait generalization * Missing docs for consensus-pow * More docs * node-runtime: bump impl_version * Add rationale for difficulty type * consensus-pow: refactor aux_key * Update lock file * Update core/consensus/pow/src/lib.rs Co-Authored-By: Sergei Pepyakin * Update core/consensus/pow/src/lib.rs Co-Authored-By: Sergei Pepyakin * Update core/consensus/pow/src/lib.rs Co-Authored-By: Sergei Pepyakin * Update core/consensus/pow/src/lib.rs Co-Authored-By: Sergei Pepyakin * Update core/consensus/pow/src/lib.rs Co-Authored-By: Sergei Pepyakin * Update core/consensus/pow/src/lib.rs Co-Authored-By: Sergei Pepyakin * Update core/consensus/pow/src/lib.rs Co-Authored-By: Sergei Pepyakin * Update core/consensus/pow/primitives/src/lib.rs Co-Authored-By: Sergei Pepyakin * Update core/consensus/pow/primitives/src/lib.rs Co-Authored-By: Sergei Pepyakin * Remove PowRuntimeAlgorithm * block_id -> parent_block_id * Auxiliary data -> auxiliary storage data * Fix error message * Fix compile * Update core/consensus/pow/primitives/src/lib.rs Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> * Update core/consensus/pow/src/lib.rs Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> * Update core/consensus/pow/primitives/src/lib.rs Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> * Update core/consensus/pow/src/lib.rs Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> * Fix crate description * More docs * Address grumbles 1. Make preruntime Optional. 2. Add more docs on what is `preruntie` and `round`. 3. Replace `Default::default` with the approriate type. --- Cargo.lock | 26 ++ Cargo.toml | 1 + core/consensus/aura/primitives/Cargo.toml | 2 +- core/consensus/pow/Cargo.toml | 18 + core/consensus/pow/primitives/Cargo.toml | 21 ++ core/consensus/pow/primitives/src/lib.rs | 36 ++ core/consensus/pow/src/lib.rs | 417 ++++++++++++++++++++++ 7 files changed, 520 insertions(+), 1 deletion(-) create mode 100644 core/consensus/pow/Cargo.toml create mode 100644 core/consensus/pow/primitives/Cargo.toml create mode 100644 core/consensus/pow/primitives/src/lib.rs create mode 100644 core/consensus/pow/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 9a6afd5c11..b242c7337d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4689,6 +4689,32 @@ dependencies = [ "substrate-test-runtime-client 2.0.0", ] +[[package]] +name = "substrate-consensus-pow" +version = "2.0.0" +dependencies = [ + "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 2.0.0", + "srml-timestamp 2.0.0", + "substrate-client 2.0.0", + "substrate-consensus-common 2.0.0", + "substrate-consensus-pow-primitives 2.0.0", + "substrate-inherents 2.0.0", + "substrate-primitives 2.0.0", +] + +[[package]] +name = "substrate-consensus-pow-primitives" +version = "2.0.0" +dependencies = [ + "sr-primitives 2.0.0", + "sr-std 2.0.0", + "substrate-client 2.0.0", + "substrate-primitives 2.0.0", +] + [[package]] name = "substrate-consensus-rhd" version = "2.0.0" diff --git a/Cargo.toml b/Cargo.toml index 048bfb7629..aaa8c372fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ members = [ "core/consensus/rhd", "core/consensus/slots", "core/consensus/uncles", + "core/consensus/pow", "core/executor", "core/executor/runtime-test", "core/finality-grandpa", diff --git a/core/consensus/aura/primitives/Cargo.toml b/core/consensus/aura/primitives/Cargo.toml index ac2c2c791b..7fd3f3d05d 100644 --- a/core/consensus/aura/primitives/Cargo.toml +++ b/core/consensus/aura/primitives/Cargo.toml @@ -10,7 +10,7 @@ codec = { package = "parity-scale-codec", version = "1.0.0", default-features = substrate-client = { path = "../../../client", default-features = false } app-crypto = { package = "substrate-application-crypto", path = "../../../application-crypto", default-features = false } rstd = { package = "sr-std", path = "../../../sr-std", default-features = false } -sr-primitives = { path = "../../../sr-primitives", default-features = false } +sr-primitives = { path = "../../../sr-primitives", default-features = false } [features] default = ["std"] diff --git a/core/consensus/pow/Cargo.toml b/core/consensus/pow/Cargo.toml new file mode 100644 index 0000000000..5ddc0f478d --- /dev/null +++ b/core/consensus/pow/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "substrate-consensus-pow" +version = "2.0.0" +authors = ["Parity Technologies "] +description = "PoW consensus algorithm for substrate" +edition = "2018" + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } +primitives = { package = "substrate-primitives", path = "../../primitives" } +sr-primitives = { path = "../../sr-primitives" } +client = { package = "substrate-client", path = "../../client" } +srml-timestamp = { path = "../../../srml/timestamp" } +inherents = { package = "substrate-inherents", path = "../../inherents" } +pow-primitives = { package = "substrate-consensus-pow-primitives", path = "primitives" } +consensus-common = { package = "substrate-consensus-common", path = "../common" } +log = "0.4" +futures-preview = { version = "=0.3.0-alpha.17", features = ["compat"] } diff --git a/core/consensus/pow/primitives/Cargo.toml b/core/consensus/pow/primitives/Cargo.toml new file mode 100644 index 0000000000..a7e0d284b0 --- /dev/null +++ b/core/consensus/pow/primitives/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "substrate-consensus-pow-primitives" +version = "2.0.0" +authors = ["Parity Technologies "] +description = "Primitives for Aura consensus" +edition = "2018" + +[dependencies] +substrate-client = { path = "../../../client", default-features = false } +rstd = { package = "sr-std", path = "../../../sr-std", default-features = false } +sr-primitives = { path = "../../../sr-primitives", default-features = false } +primitives = { package = "substrate-primitives", path = "../../../primitives", default-features = false } + +[features] +default = ["std"] +std = [ + "rstd/std", + "substrate-client/std", + "sr-primitives/std", + "primitives/std", +] diff --git a/core/consensus/pow/primitives/src/lib.rs b/core/consensus/pow/primitives/src/lib.rs new file mode 100644 index 0000000000..807a7b2df2 --- /dev/null +++ b/core/consensus/pow/primitives/src/lib.rs @@ -0,0 +1,36 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Primitives for Substrate Proof-of-Work (PoW) consensus. + +#![cfg_attr(not(feature = "std"), no_std)] + +use rstd::vec::Vec; +use sr_primitives::ConsensusEngineId; + +/// The `ConsensusEngineId` of PoW. +pub const POW_ENGINE_ID: ConsensusEngineId = [b'p', b'o', b'w', b'_']; + +/// Type of difficulty. +/// +/// For runtime designed for Substrate, it's always possible to fit its total +/// difficulty range under `u128::max_value()` because it can be freely scaled +/// up or scaled down. Very few PoW chains use difficulty values +/// larger than `u128::max_value()`. +pub type Difficulty = u128; + +/// Type of seal. +pub type Seal = Vec; diff --git a/core/consensus/pow/src/lib.rs b/core/consensus/pow/src/lib.rs new file mode 100644 index 0000000000..343c7b14c6 --- /dev/null +++ b/core/consensus/pow/src/lib.rs @@ -0,0 +1,417 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Proof of work consensus for Substrate. +//! +//! To use this engine, you can need to have a struct that implements +//! `PowAlgorithm`. After that, pass an instance of the struct, along +//! with other necessary client references to `import_queue` to setup +//! the queue. Use the `start_mine` function for basic CPU mining. +//! +//! The auxiliary storage for PoW engine only stores the total difficulty. +//! For other storage requirements for particular PoW algorithm (such as +//! the actual difficulty for each particular blocks), you can take a client +//! reference in your `PowAlgorithm` implementation, and use a separate prefix +//! for the auxiliary storage. It is also possible to just use the runtime +//! as the storage, but it is not recommended as it won't work well with light +//! clients. + +use std::sync::Arc; +use std::thread; +use std::collections::HashMap; +use client::{ + BlockOf, blockchain::{HeaderBackend, ProvideCache}, + block_builder::api::BlockBuilder as BlockBuilderApi, backend::AuxStore, +}; +use sr_primitives::Justification; +use sr_primitives::generic::{BlockId, Digest, DigestItem}; +use sr_primitives::traits::{Block as BlockT, Header as HeaderT, ProvideRuntimeApi}; +use srml_timestamp::{TimestampInherentData, InherentError as TIError}; +use pow_primitives::{Difficulty, Seal, POW_ENGINE_ID}; +use primitives::H256; +use inherents::{InherentDataProviders, InherentData}; +use consensus_common::{ + BlockImportParams, BlockOrigin, ForkChoiceStrategy, + well_known_cache_keys::Id as CacheKeyId, Environment, Proposer, +}; +use consensus_common::import_queue::{BoxBlockImport, BasicQueue, Verifier}; +use codec::{Encode, Decode}; +use log::*; + +/// Auxiliary storage prefix for PoW engine. +pub const POW_AUX_PREFIX: [u8; 4] = *b"PoW:"; + +/// Get the auxiliary storage key used by engine to store total difficulty. +fn aux_key(hash: &H256) -> Vec { + POW_AUX_PREFIX.iter().chain(&hash[..]) + .cloned().collect::>() +} + +/// Auxiliary storage data for PoW. +#[derive(Encode, Decode, Clone, Debug, Default)] +pub struct PowAux { + /// Total difficulty. + pub total_difficulty: Difficulty, +} + +impl PowAux { + /// Read the auxiliary from client. + pub fn read(client: &C, hash: &H256) -> Result { + let key = aux_key(hash); + + match client.get_aux(&key).map_err(|e| format!("{:?}", e))? { + Some(bytes) => PowAux::decode(&mut &bytes[..]).map_err(|e| format!("{:?}", e)), + None => Ok(PowAux::default()), + } + } +} + +/// Algorithm used for proof of work. +pub trait PowAlgorithm { + /// Get the next block's difficulty. + fn difficulty(&self, parent: &BlockId) -> Result; + /// Verify proof of work against the given difficulty. + fn verify( + &self, + parent: &BlockId, + pre_hash: &H256, + seal: &Seal, + difficulty: Difficulty, + ) -> Result; + /// Mine a seal that satisfy the given difficulty. + fn mine( + &self, + parent: &BlockId, + pre_hash: &H256, + seed: &H256, + difficulty: Difficulty, + round: u32, + ) -> Result, String>; +} + +/// A verifier for PoW blocks. +pub struct PowVerifier { + client: Arc, + algorithm: Algorithm, + inherent_data_providers: inherents::InherentDataProviders, +} + +impl PowVerifier { + fn check_header>( + &self, + mut header: B::Header, + parent_block_id: BlockId, + ) -> Result<(B::Header, Difficulty, DigestItem), String> where + Algorithm: PowAlgorithm, + { + let hash = header.hash(); + + let (seal, inner_seal) = match header.digest_mut().pop() { + Some(DigestItem::Seal(id, seal)) => { + if id == POW_ENGINE_ID { + (DigestItem::Seal(id, seal.clone()), seal) + } else { + return Err(format!("Header uses the wrong engine {:?}", id)) + } + }, + _ => return Err(format!("Header {:?} is unsealed", hash)), + }; + + let pre_hash = header.hash(); + let difficulty = self.algorithm.difficulty(&parent_block_id)?; + + if !self.algorithm.verify( + &parent_block_id, + &pre_hash, + &inner_seal, + difficulty, + )? { + return Err("PoW validation error: invalid seal".into()); + } + + Ok((header, difficulty, seal)) + } + + fn check_inherents>( + &self, + block: B, + block_id: BlockId, + inherent_data: InherentData, + timestamp_now: u64, + ) -> Result<(), String> where + C: ProvideRuntimeApi, C::Api: BlockBuilderApi + { + const MAX_TIMESTAMP_DRIFT_SECS: u64 = 60; + + let inherent_res = self.client.runtime_api().check_inherents( + &block_id, + block, + inherent_data, + ).map_err(|e| format!("{:?}", e))?; + + if !inherent_res.ok() { + inherent_res + .into_errors() + .try_for_each(|(i, e)| match TIError::try_from(&i, &e) { + Some(TIError::ValidAtTimestamp(timestamp)) => { + if timestamp > timestamp_now + MAX_TIMESTAMP_DRIFT_SECS { + return Err("Rejecting block too far in future".into()); + } + + Ok(()) + }, + Some(TIError::Other(e)) => Err(e.into()), + None => Err(self.inherent_data_providers.error_to_string(&i, &e)), + }) + } else { + Ok(()) + } + } +} + +impl, C, Algorithm> Verifier for PowVerifier where + C: ProvideRuntimeApi + Send + Sync + HeaderBackend + AuxStore + ProvideCache + BlockOf, + C::Api: BlockBuilderApi, + Algorithm: PowAlgorithm + Send + Sync, +{ + fn verify( + &mut self, + origin: BlockOrigin, + header: B::Header, + justification: Option, + mut body: Option>, + ) -> Result<(BlockImportParams, Option)>>), String> { + let inherent_data = self.inherent_data_providers + .create_inherent_data().map_err(String::from)?; + let timestamp_now = inherent_data.timestamp_inherent_data().map_err(String::from)?; + + let best_hash = self.client.info().best_hash; + let hash = header.hash(); + let parent_hash = *header.parent_hash(); + let best_aux = PowAux::read(self.client.as_ref(), &best_hash)?; + let mut aux = PowAux::read(self.client.as_ref(), &parent_hash)?; + + let (checked_header, difficulty, seal) = self.check_header::( + header, + BlockId::Hash(parent_hash), + )?; + aux.total_difficulty = aux.total_difficulty.saturating_add(difficulty); + + if let Some(inner_body) = body.take() { + let block = B::new(checked_header.clone(), inner_body); + + self.check_inherents( + block.clone(), + BlockId::Hash(parent_hash), + inherent_data, + timestamp_now + )?; + + let (_, inner_body) = block.deconstruct(); + body = Some(inner_body); + } + let key = aux_key(&hash); + let import_block = BlockImportParams { + origin, + header: checked_header, + post_digests: vec![seal], + body, + finalized: false, + justification, + auxiliary: vec![(key, Some(aux.encode()))], + fork_choice: ForkChoiceStrategy::Custom(aux.total_difficulty > best_aux.total_difficulty), + }; + + Ok((import_block, None)) + } +} + +/// Register the PoW inherent data provider, if not registered already. +fn register_pow_inherent_data_provider( + inherent_data_providers: &InherentDataProviders, +) -> Result<(), consensus_common::Error> { + if !inherent_data_providers.has_provider(&srml_timestamp::INHERENT_IDENTIFIER) { + inherent_data_providers + .register_provider(srml_timestamp::InherentDataProvider) + .map_err(Into::into) + .map_err(consensus_common::Error::InherentData) + } else { + Ok(()) + } +} + +/// The PoW import queue type. +pub type PowImportQueue = BasicQueue; + +/// Import queue for PoW engine. +pub fn import_queue( + block_import: BoxBlockImport, + client: Arc, + algorithm: Algorithm, + inherent_data_providers: InherentDataProviders, +) -> Result, consensus_common::Error> where + B: BlockT, + C: ProvideRuntimeApi + HeaderBackend + BlockOf + ProvideCache + AuxStore, + C: Send + Sync + AuxStore + 'static, + C::Api: BlockBuilderApi, + Algorithm: PowAlgorithm + Send + Sync + 'static, +{ + register_pow_inherent_data_provider(&inherent_data_providers)?; + + let verifier = PowVerifier { + client: client.clone(), + algorithm, + inherent_data_providers, + }; + + Ok(BasicQueue::new( + verifier, + block_import, + None, + None + )) +} + +/// Start the background mining thread for PoW. Note that because PoW mining +/// is CPU-intensive, it is not possible to use an async future to define this. +/// However, it's not recommended to use background threads in the rest of the +/// codebase. +/// +/// `preruntime` is a parameter that allows a custom additional pre-runtime +/// digest to be inserted for blocks being built. This can encode authorship +/// information, or just be a graffiti. `round` is for number of rounds the +/// CPU miner runs each time. This parameter should be tweaked so that each +/// mining round is within sub-second time. +pub fn start_mine, C, Algorithm, E>( + mut block_import: BoxBlockImport, + client: Arc, + algorithm: Algorithm, + mut env: E, + preruntime: Option>, + round: u32, + inherent_data_providers: inherents::InherentDataProviders, +) where + C: HeaderBackend + AuxStore + 'static, + Algorithm: PowAlgorithm + Send + Sync + 'static, + E: Environment + Send + Sync + 'static, + E::Error: std::fmt::Debug, +{ + if let Err(_) = register_pow_inherent_data_provider(&inherent_data_providers) { + warn!("Registering inherent data provider for timestamp failed"); + } + + thread::spawn(move || { + loop { + match mine_loop( + &mut block_import, + client.as_ref(), + &algorithm, + &mut env, + preruntime.as_ref(), + round, + &inherent_data_providers + ) { + Ok(()) => (), + Err(e) => error!( + "Mining block failed with {:?}. Sleep for 1 second before restarting...", + e + ), + } + + std::thread::sleep(std::time::Duration::new(1, 0)); + } + }); +} + +fn mine_loop, C, Algorithm, E>( + block_import: &mut BoxBlockImport, + client: &C, + algorithm: &Algorithm, + env: &mut E, + preruntime: Option<&Vec>, + round: u32, + inherent_data_providers: &inherents::InherentDataProviders, +) -> Result<(), String> where + C: HeaderBackend + AuxStore, + Algorithm: PowAlgorithm, + E: Environment, + E::Error: std::fmt::Debug, +{ + 'outer: loop { + let best_hash = client.info().best_hash; + let best_header = client.header(BlockId::Hash(best_hash)) + .map_err(|e| format!("Fetching best header failed: {:?}", e))? + .ok_or("Best header does not exist")?; + let mut aux = PowAux::read(client, &best_hash)?; + let mut proposer = env.init(&best_header).map_err(|e| format!("{:?}", e))?; + + let inherent_data = inherent_data_providers + .create_inherent_data().map_err(String::from)?; + let mut inherent_digest = Digest::default(); + if let Some(preruntime) = &preruntime { + inherent_digest.push(DigestItem::PreRuntime(POW_ENGINE_ID, preruntime.to_vec())); + } + let block = futures::executor::block_on(proposer.propose( + inherent_data, + inherent_digest, + std::time::Duration::new(0, 0) + )).map_err(|e| format!("Block proposing error: {:?}", e))?; + + let (header, body) = block.deconstruct(); + let seed = H256::random(); + let (difficulty, seal) = { + loop { + let difficulty = algorithm.difficulty( + &BlockId::Hash(best_hash), + )?; + + let seal = algorithm.mine( + &BlockId::Hash(best_hash), + &header.hash(), + &seed, + difficulty, + round, + )?; + + if let Some(seal) = seal { + break (difficulty, seal) + } + + if best_hash != client.info().best_hash { + continue 'outer + } + } + }; + + aux.total_difficulty = aux.total_difficulty.saturating_add(difficulty); + let hash = header.hash(); + + let key = aux_key(&hash); + let import_block = BlockImportParams { + origin: BlockOrigin::Own, + header, + justification: None, + post_digests: vec![DigestItem::Seal(POW_ENGINE_ID, seal)], + body: Some(body), + finalized: false, + auxiliary: vec![(key, Some(aux.encode()))], + fork_choice: ForkChoiceStrategy::Custom(true), + }; + + block_import.import_block(import_block, HashMap::default()) + .map_err(|e| format!("Error with block built on {:?}: {:?}", best_hash, e))?; + } +} -- GitLab From 7fc21ceafbd01f3fadff7d1ebd51b7c6ba9f86ac Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 6 Sep 2019 17:43:03 +0200 Subject: [PATCH 062/275] core/authority-discovery: Enable authorities to discover each other (#3452) With the *authority-discovery* module an authoritative node makes itself discoverable and is able to discover other authorities. Once discovered, a node can directly connect to other authorities instead of multi-hop gossiping information. 1. **Making itself discoverable** 1. Retrieve its external addresses 2. Adds its network peer id to the addresses 3. Sign the above 4. Put the signature and the addresses on the libp2p Kademlia DHT 2. **Discovering other authorities** 1. Retrieve the current set of authorities 2. Start DHT queries for the ids of the authorities 3. Validate the signatures of the retrieved key value pairs 4. Add the retrieved external addresses as ~reserved~ priority nodes to the peerset * node/runtime: Add authority-discovery as session handler The srml/authority-discovery module implements the OneSessionHandler in order to keep its authority set in sync. This commit adds the module to the set of session handlers. * core/network: Make network worker return Dht events on poll Instead of network worker implement the Future trait, have it implement the Stream interface returning Dht events. For now these events are ignored in build_network_future but will be used by the core/authority-discovery module in subsequent commits. * *: Add scaffolding and integration for core/authority-discovery module * core/authority-discovery: Implement module logic itself --- Cargo.lock | 102 +++ Cargo.toml | 1 + core/authority-discovery/Cargo.toml | 32 + core/authority-discovery/build.rs | 3 + .../authority-discovery/primitives/src/lib.rs | 20 +- core/authority-discovery/src/error.rs | 47 ++ core/authority-discovery/src/lib.rs | 698 ++++++++++++++++++ core/authority-discovery/src/schema/dht.proto | 14 + core/network/src/lib.rs | 1 + core/network/src/protocol/event.rs | 2 + core/network/src/service.rs | 13 +- core/service/Cargo.toml | 2 + core/service/src/builder.rs | 43 +- core/service/src/lib.rs | 30 +- node/cli/Cargo.toml | 3 +- node/cli/src/service.rs | 17 + node/runtime/src/lib.rs | 38 +- srml/authority-discovery/src/lib.rs | 35 +- srml/im-online/src/lib.rs | 2 +- 19 files changed, 1041 insertions(+), 62 deletions(-) create mode 100644 core/authority-discovery/Cargo.toml create mode 100644 core/authority-discovery/build.rs create mode 100644 core/authority-discovery/src/error.rs create mode 100644 core/authority-discovery/src/lib.rs create mode 100644 core/authority-discovery/src/schema/dht.proto diff --git a/Cargo.lock b/Cargo.lock index b242c7337d..335932c595 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -876,6 +876,11 @@ dependencies = [ "static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "fixedbitset" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "flate2" version = "1.0.9" @@ -2236,6 +2241,11 @@ dependencies = [ "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "multimap" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "multistream-select" version = "0.5.1" @@ -2324,6 +2334,7 @@ dependencies = [ "srml-system 2.0.0", "srml-timestamp 2.0.0", "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-authority-discovery 2.0.0", "substrate-basic-authorship 2.0.0", "substrate-cli 2.0.0", "substrate-client 2.0.0", @@ -2934,6 +2945,14 @@ name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "petgraph" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "pin-utils" version = "0.1.0-alpha.4" @@ -3005,6 +3024,54 @@ dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "prost" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "prost-build" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "multimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "prost-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "prost-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "protobuf" version = "2.8.0" @@ -4440,6 +4507,32 @@ dependencies = [ "substrate-test-runtime-client 2.0.0", ] +[[package]] +name = "substrate-authority-discovery" +version = "2.0.0" +dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-build 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 2.0.0", + "substrate-authority-discovery-primitives 2.0.0", + "substrate-client 2.0.0", + "substrate-keystore 2.0.0", + "substrate-network 2.0.0", + "substrate-peerset 2.0.0", + "substrate-primitives 2.0.0", + "substrate-test-runtime-client 2.0.0", + "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "substrate-authority-discovery-primitives" version = "2.0.0" @@ -5134,6 +5227,8 @@ dependencies = [ "sr-io 2.0.0", "sr-primitives 2.0.0", "substrate-application-crypto 2.0.0", + "substrate-authority-discovery 2.0.0", + "substrate-authority-discovery-primitives 2.0.0", "substrate-client 2.0.0", "substrate-client-db 2.0.0", "substrate-consensus-babe-primitives 2.0.0", @@ -6433,6 +6528,7 @@ dependencies = [ "checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" "checksum finality-grandpa 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9681c1f75941ea47584573dd2bc10558b2067d460612945887e00744e43393be" "checksum fixed-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "516877b7b9a1cc2d0293cbce23cd6203f0edbfd4090e6ca4489fecb5aa73050e" +"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" "checksum flate2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "550934ad4808d5d39365e5d61727309bf18b3b02c6c56b729cb92e7dd84bc3d8" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" @@ -6561,6 +6657,7 @@ dependencies = [ "checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +"checksum multimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb04b9f127583ed176e163fb9ec6f3e793b87e21deedd5734a69386a18a0151" "checksum multistream-select 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e8f3cb4c93f2d79811fc11fa01faab99d8b7b8cbe024b602c27434ff2b08a59d" "checksum names 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef320dab323286b50fb5cdda23f61c796a72a89998ab565ca32525c5c556f2da" "checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" @@ -6607,6 +6704,7 @@ dependencies = [ "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" "checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" "checksum pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c1d2cfa5a714db3b5f24f0915e74fcdf91d09d496ba61329705dda7774d2af" "checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" @@ -6616,6 +6714,10 @@ dependencies = [ "checksum proc-macro-hack 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "982a35d1194084ba319d65c4a68d24ca28f5fdb5b8bc20899e4eef8641ea5178" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "175a40b9cf564ce9bf050654633dbf339978706b8ead1a907bb970b63185dd95" +"checksum prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96d14b1c185652833d24aaad41c5832b0be5616a590227c1fbff57c616754b23" +"checksum prost-build 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb788126ea840817128183f8f603dce02cb7aea25c2a0b764359d8e20010702e" +"checksum prost-derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e7dc378b94ac374644181a2247cebf59a6ec1c88b49ac77f3a94b86b79d0e11" +"checksum prost-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1de482a366941c8d56d19b650fac09ca08508f2a696119ee7513ad590c8bac6f" "checksum protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8aefcec9f142b524d98fc81d07827743be89dd6586a1ba6ab21fa66a500b3fa5" "checksum pwasm-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "efb0dcbddbb600f47a7098d33762a00552c671992171637f5bb310b37fe1f0e4" "checksum quick-error 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb6ccf8db7bbcb9c2eae558db5ab4f3da1c2a87e4e597ed394726bc8ea6ca1d" diff --git a/Cargo.toml b/Cargo.toml index aaa8c372fb..29f5307610 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,6 +64,7 @@ members = [ "core/utils/fork-tree", "core/utils/wasm-builder", "core/utils/wasm-builder-runner", + "core/authority-discovery", "srml/support", "srml/support/procedural", "srml/support/procedural/tools", diff --git a/core/authority-discovery/Cargo.toml b/core/authority-discovery/Cargo.toml new file mode 100644 index 0000000000..ac7f8ac368 --- /dev/null +++ b/core/authority-discovery/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "substrate-authority-discovery" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" +build = "build.rs" + +[build-dependencies] +prost-build = "0.5" + +[dependencies] +authority-discovery-primitives = { package = "substrate-authority-discovery-primitives", path = "./primitives", default-features = false } +bytes = "0.4" +client = { package = "substrate-client", path = "../../core/client" } +codec = { package = "parity-scale-codec", default-features = false, version = "1.0.3" } +derive_more = "0.14.0" +futures = "0.1" +keystore = { package = "substrate-keystore", path = "../../core/keystore" } +libp2p = { version = "0.12.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] } +log = "0.4" +network = { package = "substrate-network", path = "../../core/network" } +primitives = { package = "substrate-primitives", path = "../primitives" } +prost = "0.5" +serde_json = "1.0" +sr-primitives = { path = "../../core/sr-primitives" } +tokio-timer = "0.2" + +[dev-dependencies] +parking_lot = { version = "0.9.0" } +peerset = { package = "substrate-peerset", path = "../../core/peerset" } +test-client = { package = "substrate-test-runtime-client", path = "../../core/test-runtime/client" } +tokio = { version = "0.1"} diff --git a/core/authority-discovery/build.rs b/core/authority-discovery/build.rs new file mode 100644 index 0000000000..ed632575f3 --- /dev/null +++ b/core/authority-discovery/build.rs @@ -0,0 +1,3 @@ +fn main() { + prost_build::compile_protos(&["src/schema/dht.proto"], &["src/schema"]).unwrap(); +} diff --git a/core/authority-discovery/primitives/src/lib.rs b/core/authority-discovery/primitives/src/lib.rs index 556b758aa6..13da4de020 100644 --- a/core/authority-discovery/primitives/src/lib.rs +++ b/core/authority-discovery/primitives/src/lib.rs @@ -19,9 +19,15 @@ #![cfg_attr(not(feature = "std"), no_std)] use client::decl_runtime_apis; -use codec::Codec; use rstd::vec::Vec; +#[derive(codec::Encode, codec::Decode, Eq, PartialEq, Clone)] +#[cfg_attr(feature = "std", derive(Debug, Hash))] +pub struct Signature(pub Vec); +#[derive(codec::Encode, codec::Decode, Eq, PartialEq, Clone)] +#[cfg_attr(feature = "std", derive(Debug, Hash))] +pub struct AuthorityId(pub Vec); + decl_runtime_apis! { /// The authority discovery api. /// @@ -29,21 +35,15 @@ decl_runtime_apis! { /// own authority identifier, to retrieve identifiers of the current authority /// set, as well as sign and verify Kademlia Dht external address payloads /// from and to other authorities. - pub trait AuthorityDiscoveryApi { - /// Returns own authority identifier iff it is part of the current authority - /// set, otherwise this function returns None. The restriction might be - /// softened in the future in case a consumer needs to learn own authority - /// identifier. - fn authority_id() -> Option; - + pub trait AuthorityDiscoveryApi { /// Retrieve authority identifiers of the current authority set. fn authorities() -> Vec; /// Sign the given payload with the private key corresponding to the given authority id. - fn sign(payload: Vec, authority_id: AuthorityId) -> Option>; + fn sign(payload: &Vec) -> Option<(Signature, AuthorityId)>; /// Verify the given signature for the given payload with the given /// authority identifier. - fn verify(payload: Vec, signature: Vec, authority_id: AuthorityId) -> bool; + fn verify(payload: &Vec, signature: &Signature, authority_id: &AuthorityId) -> bool; } } diff --git a/core/authority-discovery/src/error.rs b/core/authority-discovery/src/error.rs new file mode 100644 index 0000000000..e8c1ad9705 --- /dev/null +++ b/core/authority-discovery/src/error.rs @@ -0,0 +1,47 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Authority discovery errors. + +/// AuthorityDiscovery Result. +pub type Result = std::result::Result; + +/// Error type for the authority discovery module. +#[derive(Debug, derive_more::Display, derive_more::From)] +pub enum Error { + /// Failed to verify a dht payload with the given signature. + VerifyingDhtPayload, + /// Failed to hash the authority id to be used as a dht key. + HashingAuthorityId(libp2p::core::multiaddr::multihash::EncodeError), + /// Failed calling into the Substrate runtime. + CallingRuntime(client::error::Error), + /// Failed signing the dht payload via the Substrate runtime. + SigningDhtPayload, + /// From the Dht we only get the hashed authority id. In order to retrieve the actual authority id and to ensure it + /// is actually an authority, we match the hash against the hash of the authority id of all other authorities. This + /// error is the result of the above failing. + MatchingHashedAuthorityIdWithAuthorityId, + /// Failed to set the authority discovery peerset priority group in the peerset module. + SettingPeersetPriorityGroup(String), + /// Failed to encode a dht payload. + Encoding(prost::EncodeError), + /// Failed to decode a dht payload. + Decoding(prost::DecodeError), + /// Failed to parse a libp2p multi address. + ParsingMultiaddress(libp2p::core::multiaddr::Error), + /// Tokio timer error. + PollingTokioTimer(tokio_timer::Error) +} diff --git a/core/authority-discovery/src/lib.rs b/core/authority-discovery/src/lib.rs new file mode 100644 index 0000000000..987169ead9 --- /dev/null +++ b/core/authority-discovery/src/lib.rs @@ -0,0 +1,698 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +#![warn(missing_docs)] + +//! Substrate authority discovery. +//! +//! This crate enables Substrate authorities to directly connect to other authorities. [`AuthorityDiscovery`] implements +//! the Future trait. By polling [`AuthorityDiscovery`] an authority: +//! +//! +//! 1. **Makes itself discoverable** +//! +//! 1. Retrieves its external addresses. +//! +//! 2. Adds its network peer id to the addresses. +//! +//! 3. Signs the above. +//! +//! 4. Puts the signature and the addresses on the libp2p Kademlia DHT. +//! +//! +//! 2. **Discovers other authorities** +//! +//! 1. Retrieves the current set of authorities. +//! +//! 2. Starts DHT queries for the ids of the authorities. +//! +//! 3. Validates the signatures of the retrieved key value pairs. +//! +//! 4. Adds the retrieved external addresses as priority nodes to the peerset. + +use authority_discovery_primitives::{AuthorityDiscoveryApi, AuthorityId, Signature}; +use client::blockchain::HeaderBackend; +use error::{Error, Result}; +use futures::{prelude::*, sync::mpsc::Receiver}; +use log::{debug, error, log_enabled, warn}; +use network::specialization::NetworkSpecialization; +use network::{DhtEvent, ExHashT}; +use prost::Message; +use sr_primitives::generic::BlockId; +use sr_primitives::traits::{Block as BlockT, ProvideRuntimeApi}; +use std::collections::{HashMap, HashSet}; +use std::convert::TryInto; +use std::iter::FromIterator; +use std::marker::PhantomData; +use std::sync::Arc; +use std::time::{Duration, Instant}; + +mod error; +/// Dht payload schemas generated from Protobuf definitions via Prost crate in build.rs. +mod schema { + include!(concat!(env!("OUT_DIR"), "/authority_discovery.rs")); +} + +/// An `AuthorityDiscovery` makes a given authority discoverable and discovers other authorities. +pub struct AuthorityDiscovery +where + Block: BlockT + 'static, + Network: NetworkProvider, + Client: ProvideRuntimeApi + Send + Sync + 'static + HeaderBackend, + ::Api: AuthorityDiscoveryApi, +{ + client: Arc, + + network: Arc, + /// Channel we receive Dht events on. + dht_event_rx: Receiver, + + /// Interval to be proactive, publishing own addresses. + publish_interval: tokio_timer::Interval, + /// Interval on which to query for addresses of other authorities. + query_interval: tokio_timer::Interval, + + /// The network peerset interface for priority groups lets us only set an entire group, but we retrieve the + /// addresses of other authorities one by one from the network. To use the peerset interface we need to cache the + /// addresses and always overwrite the entire peerset priority group. To ensure this map doesn't grow indefinitely + /// `purge_old_authorities_from_cache` function is called each time we add a new entry. + address_cache: HashMap>, + + phantom: PhantomData, +} + +impl AuthorityDiscovery +where + Block: BlockT + 'static, + Network: NetworkProvider, + Client: ProvideRuntimeApi + Send + Sync + 'static + HeaderBackend, + ::Api: AuthorityDiscoveryApi, +{ + /// Return a new authority discovery. + pub fn new( + client: Arc, + network: Arc, + dht_event_rx: futures::sync::mpsc::Receiver, + ) -> AuthorityDiscovery { + // Kademlia's default time-to-live for Dht records is 36h, republishing records every 24h. Given that a node + // could restart at any point in time, one can not depend on the republishing process, thus publishing own + // external addresses should happen on an interval < 36h. + let publish_interval = + tokio_timer::Interval::new(Instant::now(), Duration::from_secs(12 * 60 * 60)); + + // External addresses of other authorities can change at any given point in time. The interval on which to query + // for external addresses of other authorities is a trade off between efficiency and performance. + let query_interval = + tokio_timer::Interval::new(Instant::now(), Duration::from_secs(10 * 60)); + + let address_cache = HashMap::new(); + + AuthorityDiscovery { + client, + network, + dht_event_rx, + publish_interval, + query_interval, + address_cache, + phantom: PhantomData, + } + } + + fn publish_own_ext_addresses(&mut self) -> Result<()> { + let id = BlockId::hash(self.client.info().best_hash); + + let addresses = self + .network + .external_addresses() + .into_iter() + .map(|a| { + a.with(libp2p::core::multiaddr::Protocol::P2p( + self.network.local_peer_id().into(), + )) + }) + .map(|a| a.to_vec()) + .collect(); + + let mut serialized_addresses = vec![]; + schema::AuthorityAddresses { addresses } + .encode(&mut serialized_addresses) + .map_err(Error::Encoding)?; + + let (signature, authority_id) = self + .client + .runtime_api() + .sign(&id, &serialized_addresses) + .map_err(Error::CallingRuntime)? + .ok_or(Error::SigningDhtPayload)?; + + let mut signed_addresses = vec![]; + schema::SignedAuthorityAddresses { + addresses: serialized_addresses, + signature: signature.0, + } + .encode(&mut signed_addresses) + .map_err(Error::Encoding)?; + + self.network.put_value( + hash_authority_id(authority_id.0.as_ref())?, + signed_addresses, + ); + + Ok(()) + } + + fn request_addresses_of_others(&mut self) -> Result<()> { + let id = BlockId::hash(self.client.info().best_hash); + + let authorities = self + .client + .runtime_api() + .authorities(&id) + .map_err(Error::CallingRuntime)?; + + for authority_id in authorities.iter() { + self.network + .get_value(&hash_authority_id(authority_id.0.as_ref())?); + } + + Ok(()) + } + + fn handle_dht_events(&mut self) -> Result<()> { + while let Ok(Async::Ready(Some(event))) = self.dht_event_rx.poll() { + match event { + DhtEvent::ValueFound(v) => { + if log_enabled!(log::Level::Debug) { + let hashes = v.iter().map(|(hash, _value)| hash.clone()); + debug!(target: "sub-authority-discovery", "Value for hash '{:?}' found on Dht.", hashes); + } + + self.handle_dht_value_found_event(v)?; + } + DhtEvent::ValueNotFound(hash) => { + warn!(target: "sub-authority-discovery", "Value for hash '{:?}' not found on Dht.", hash) + } + DhtEvent::ValuePut(hash) => { + debug!(target: "sub-authority-discovery", "Successfully put hash '{:?}' on Dht.", hash) + } + DhtEvent::ValuePutFailed(hash) => { + warn!(target: "sub-authority-discovery", "Failed to put hash '{:?}' on Dht.", hash) + } + } + } + + Ok(()) + } + + fn handle_dht_value_found_event( + &mut self, + values: Vec<(libp2p::kad::record::Key, Vec)>, + ) -> Result<()> { + debug!(target: "sub-authority-discovery", "Got Dht value from network."); + + let id = BlockId::hash(self.client.info().best_hash); + + // From the Dht we only get the hashed authority id. In order to retrieve the actual authority id and to ensure + // it is actually an authority, we match the hash against the hash of the authority id of all other authorities. + let authorities = self.client.runtime_api().authorities(&id)?; + self.purge_old_authorities_from_cache(&authorities); + + let authorities = authorities + .into_iter() + .map(|a| hash_authority_id(a.0.as_ref()).map(|h| (h, a))) + .collect::>>()?; + + for (key, value) in values.iter() { + // Check if the event origins from an authority in the current authority set. + let authority_id: &AuthorityId = authorities + .get(key) + .ok_or(Error::MatchingHashedAuthorityIdWithAuthorityId)?; + + let schema::SignedAuthorityAddresses { + signature, + addresses, + } = schema::SignedAuthorityAddresses::decode(value).map_err(Error::Decoding)?; + let signature = Signature(signature); + + let is_verified = self + .client + .runtime_api() + .verify(&id, &addresses, &signature, &authority_id.clone()) + .map_err(Error::CallingRuntime)?; + + if !is_verified { + return Err(Error::VerifyingDhtPayload); + } + + let addresses: Vec = schema::AuthorityAddresses::decode(addresses) + .map(|a| a.addresses) + .map_err(Error::Decoding)? + .into_iter() + .map(|a| a.try_into()) + .collect::>() + .map_err(Error::ParsingMultiaddress)?; + + self.address_cache.insert(authority_id.clone(), addresses); + } + + // Let's update the peerset priority group with the all the addresses we have in our cache. + + let addresses = HashSet::from_iter( + self.address_cache + .iter() + .map(|(_peer_id, addresses)| addresses.clone()) + .flatten(), + ); + + debug!(target: "sub-authority-discovery", "Applying priority group {:#?} to peerset.", addresses); + self.network + .set_priority_group("authorities".to_string(), addresses) + .map_err(Error::SettingPeersetPriorityGroup)?; + + Ok(()) + } + + fn purge_old_authorities_from_cache(&mut self, current_authorities: &Vec) { + self.address_cache + .retain(|peer_id, _addresses| current_authorities.contains(peer_id)) + } +} + +impl futures::Future for AuthorityDiscovery +where + Block: BlockT + 'static, + Network: NetworkProvider, + Client: ProvideRuntimeApi + Send + Sync + 'static + HeaderBackend, + ::Api: AuthorityDiscoveryApi, +{ + type Item = (); + type Error = (); + + fn poll(&mut self) -> futures::Poll { + let mut inner = || -> Result<()> { + // Process incoming events before triggering new ones. + self.handle_dht_events()?; + + if let Async::Ready(_) = self + .publish_interval + .poll() + .map_err(Error::PollingTokioTimer)? + { + // Make sure to call interval.poll until it returns Async::NotReady once. Otherwise, in case one of the + // function calls within this block do a `return`, we don't call `interval.poll` again and thereby the + // underlying Tokio task is never registered with Tokio's Reactor to be woken up on the next interval + // tick. + while let Async::Ready(_) = self + .publish_interval + .poll() + .map_err(Error::PollingTokioTimer)? + {} + + self.publish_own_ext_addresses()?; + } + + if let Async::Ready(_) = self + .query_interval + .poll() + .map_err(Error::PollingTokioTimer)? + { + // Make sure to call interval.poll until it returns Async::NotReady once. Otherwise, in case one of the + // function calls within this block do a `return`, we don't call `interval.poll` again and thereby the + // underlying Tokio task is never registered with Tokio's Reactor to be woken up on the next interval + // tick. + while let Async::Ready(_) = self + .query_interval + .poll() + .map_err(Error::PollingTokioTimer)? + {} + + self.request_addresses_of_others()?; + } + + Ok(()) + }; + + match inner() { + Ok(()) => {} + Err(e) => error!(target: "sub-authority-discovery", "Poll failure: {:?}", e), + }; + + // Make sure to always return NotReady as this is a long running task with the same lifetime as the node itself. + Ok(futures::Async::NotReady) + } +} + +/// NetworkProvider provides AuthorityDiscovery with all necessary hooks into the underlying Substrate networking. Using +/// this trait abstraction instead of NetworkService directly is necessary to unit test AuthorityDiscovery. +pub trait NetworkProvider { + /// Returns the local external addresses. + fn external_addresses(&self) -> Vec; + + /// Returns the network identity of the node. + fn local_peer_id(&self) -> libp2p::PeerId; + + /// Modify a peerset priority group. + fn set_priority_group( + &self, + group_id: String, + peers: HashSet, + ) -> std::result::Result<(), String>; + + /// Start putting a value in the Dht. + fn put_value(&self, key: libp2p::kad::record::Key, value: Vec); + + /// Start getting a value from the Dht. + fn get_value(&self, key: &libp2p::kad::record::Key); +} + +impl NetworkProvider for network::NetworkService +where + B: BlockT + 'static, + S: NetworkSpecialization, + H: ExHashT, +{ + fn external_addresses(&self) -> Vec { + self.external_addresses() + } + fn local_peer_id(&self) -> libp2p::PeerId { + self.local_peer_id() + } + fn set_priority_group( + &self, + group_id: String, + peers: HashSet, + ) -> std::result::Result<(), String> { + self.set_priority_group(group_id, peers) + } + fn put_value(&self, key: libp2p::kad::record::Key, value: Vec) { + self.put_value(key, value) + } + fn get_value(&self, key: &libp2p::kad::record::Key) { + self.get_value(key) + } +} + +fn hash_authority_id(id: &[u8]) -> Result { + libp2p::multihash::encode(libp2p::multihash::Hash::SHA2256, id) + .map(|k| libp2p::kad::record::Key::new(&k)) + .map_err(Error::HashingAuthorityId) +} + +#[cfg(test)] +mod tests { + use super::*; + use client::runtime_api::{ApiExt, Core, RuntimeVersion}; + use futures::future::poll_fn; + use primitives::{ExecutionContext, NativeOrEncoded}; + use sr_primitives::traits::Zero; + use sr_primitives::traits::{ApiRef, Block as BlockT, NumberFor, ProvideRuntimeApi}; + use std::sync::{Arc, Mutex}; + use test_client::runtime::Block; + use tokio::runtime::current_thread; + + #[derive(Clone)] + struct TestApi {} + + impl ProvideRuntimeApi for TestApi { + type Api = RuntimeApi; + + fn runtime_api<'a>(&'a self) -> ApiRef<'a, Self::Api> { + RuntimeApi {}.into() + } + } + + /// Blockchain database header backend. Does not perform any validation. + impl HeaderBackend for TestApi { + fn header( + &self, + _id: BlockId, + ) -> std::result::Result, client::error::Error> { + Ok(None) + } + + fn info(&self) -> client::blockchain::Info { + client::blockchain::Info { + best_hash: Default::default(), + best_number: Zero::zero(), + finalized_hash: Default::default(), + finalized_number: Zero::zero(), + genesis_hash: Default::default(), + } + } + + fn status( + &self, + _id: BlockId, + ) -> std::result::Result { + Ok(client::blockchain::BlockStatus::Unknown) + } + + fn number( + &self, + _hash: Block::Hash, + ) -> std::result::Result>, client::error::Error> { + Ok(None) + } + + fn hash( + &self, + _number: NumberFor, + ) -> std::result::Result, client::error::Error> { + Ok(None) + } + } + + struct RuntimeApi {} + + impl Core for RuntimeApi { + fn Core_version_runtime_api_impl( + &self, + _: &BlockId, + _: ExecutionContext, + _: Option<()>, + _: Vec, + ) -> std::result::Result, client::error::Error> { + unimplemented!("Not required for testing!") + } + + fn Core_execute_block_runtime_api_impl( + &self, + _: &BlockId, + _: ExecutionContext, + _: Option<(Block)>, + _: Vec, + ) -> std::result::Result, client::error::Error> { + unimplemented!("Not required for testing!") + } + + fn Core_initialize_block_runtime_api_impl( + &self, + _: &BlockId, + _: ExecutionContext, + _: Option<&::Header>, + _: Vec, + ) -> std::result::Result, client::error::Error> { + unimplemented!("Not required for testing!") + } + } + + impl ApiExt for RuntimeApi { + fn map_api_result std::result::Result, R, E>( + &self, + _: F, + ) -> std::result::Result { + unimplemented!("Not required for testing!") + } + + fn runtime_version_at( + &self, + _: &BlockId, + ) -> std::result::Result { + unimplemented!("Not required for testing!") + } + + fn record_proof(&mut self) { + unimplemented!("Not required for testing!") + } + + fn extract_proof(&mut self) -> Option>> { + unimplemented!("Not required for testing!") + } + } + + impl AuthorityDiscoveryApi for RuntimeApi { + fn AuthorityDiscoveryApi_authorities_runtime_api_impl( + &self, + _: &BlockId, + _: ExecutionContext, + _: Option<()>, + _: Vec, + ) -> std::result::Result>, client::error::Error> { + return Ok(NativeOrEncoded::Native(vec![ + AuthorityId("test-authority-id-1".as_bytes().to_vec()), + AuthorityId("test-authority-id-2".as_bytes().to_vec()), + ])); + } + fn AuthorityDiscoveryApi_sign_runtime_api_impl( + &self, + _: &BlockId, + _: ExecutionContext, + _: Option<&std::vec::Vec>, + _: Vec, + ) -> std::result::Result< + NativeOrEncoded>, + client::error::Error, + > { + return Ok(NativeOrEncoded::Native(Some(( + Signature("test-signature-1".as_bytes().to_vec()), + AuthorityId("test-authority-id-1".as_bytes().to_vec()), + )))); + } + fn AuthorityDiscoveryApi_verify_runtime_api_impl( + &self, + _: &BlockId, + _: ExecutionContext, + args: Option<(&Vec, &Signature, &AuthorityId)>, + _: Vec, + ) -> std::result::Result, client::error::Error> { + if *args.unwrap().1 == Signature("test-signature-1".as_bytes().to_vec()) { + return Ok(NativeOrEncoded::Native(true)); + } + return Ok(NativeOrEncoded::Native(false)); + } + } + + #[derive(Default)] + struct TestNetwork { + // Whenever functions on `TestNetwork` are called, the function arguments are added to the vectors below. + pub put_value_call: Arc)>>>, + pub get_value_call: Arc>>, + pub set_priority_group_call: Arc)>>>, + } + + impl NetworkProvider for TestNetwork { + fn external_addresses(&self) -> Vec { + vec![] + } + fn local_peer_id(&self) -> libp2p::PeerId { + libp2p::PeerId::random() + } + fn set_priority_group( + &self, + group_id: String, + peers: HashSet, + ) -> std::result::Result<(), String> { + self.set_priority_group_call + .lock() + .unwrap() + .push((group_id, peers)); + Ok(()) + } + fn put_value(&self, key: libp2p::kad::record::Key, value: Vec) { + self.put_value_call.lock().unwrap().push((key, value)); + } + fn get_value(&self, key: &libp2p::kad::record::Key) { + self.get_value_call.lock().unwrap().push(key.clone()); + } + } + + #[test] + fn publish_own_ext_addresses_puts_record_on_dht() { + let (_dht_event_tx, dht_event_rx) = futures::sync::mpsc::channel(1000); + let test_api = Arc::new(TestApi {}); + let network: Arc = Arc::new(Default::default()); + + let mut authority_discovery = + AuthorityDiscovery::new(test_api, network.clone(), dht_event_rx); + + authority_discovery.publish_own_ext_addresses().unwrap(); + + // Expect authority discovery to put a new record onto the dht. + assert_eq!(network.put_value_call.lock().unwrap().len(), 1); + } + + #[test] + fn request_addresses_of_others_triggers_dht_get_query() { + let (_dht_event_tx, dht_event_rx) = futures::sync::mpsc::channel(1000); + let test_api = Arc::new(TestApi {}); + let network: Arc = Arc::new(Default::default()); + + let mut authority_discovery = + AuthorityDiscovery::new(test_api, network.clone(), dht_event_rx); + + authority_discovery.request_addresses_of_others().unwrap(); + + // Expect authority discovery to request new records from the dht. + assert_eq!(network.get_value_call.lock().unwrap().len(), 2); + } + + #[test] + fn handle_dht_events_with_value_found_should_call_set_priority_group() { + // Create authority discovery. + + let (mut dht_event_tx, dht_event_rx) = futures::sync::mpsc::channel(1000); + let test_api = Arc::new(TestApi {}); + let network: Arc = Arc::new(Default::default()); + + let mut authority_discovery = + AuthorityDiscovery::new(test_api, network.clone(), dht_event_rx); + + // Create sample dht event. + + let authority_id_1 = hash_authority_id("test-authority-id-1".as_bytes()).unwrap(); + let address_1: libp2p::Multiaddr = "/ip6/2001:db8::".parse().unwrap(); + + let mut serialized_addresses = vec![]; + schema::AuthorityAddresses { + addresses: vec![address_1.to_vec()], + } + .encode(&mut serialized_addresses) + .unwrap(); + + let mut signed_addresses = vec![]; + schema::SignedAuthorityAddresses { + addresses: serialized_addresses, + signature: "test-signature-1".as_bytes().to_vec(), + } + .encode(&mut signed_addresses) + .unwrap(); + + let dht_event = network::DhtEvent::ValueFound(vec![(authority_id_1, signed_addresses)]); + dht_event_tx.try_send(dht_event).unwrap(); + + // Make authority discovery handle the event. + + let f = || { + authority_discovery.handle_dht_events().unwrap(); + + // Expect authority discovery to set the priority set. + assert_eq!(network.set_priority_group_call.lock().unwrap().len(), 1); + + assert_eq!( + network.set_priority_group_call.lock().unwrap()[0], + ( + "authorities".to_string(), + HashSet::from_iter(vec![address_1.clone()].into_iter()) + ) + ); + + Ok(Async::Ready(())) + }; + + let mut runtime = current_thread::Runtime::new().unwrap(); + runtime.block_on(poll_fn::<(), (), _>(f)).unwrap(); + } +} diff --git a/core/authority-discovery/src/schema/dht.proto b/core/authority-discovery/src/schema/dht.proto new file mode 100644 index 0000000000..9dbe9d559f --- /dev/null +++ b/core/authority-discovery/src/schema/dht.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package authority_discovery; + +// First we need to serialize the addresses in order to be able to sign them. +message AuthorityAddresses { + repeated bytes addresses = 1; +} + +// Then we need to serialize addresses and signature to send them over the wire. +message SignedAuthorityAddresses { + bytes addresses = 1; + bytes signature = 2; +} diff --git a/core/network/src/lib.rs b/core/network/src/lib.rs index e797ffb208..7e9fd51a41 100644 --- a/core/network/src/lib.rs +++ b/core/network/src/lib.rs @@ -192,6 +192,7 @@ pub use service::{ NetworkStateInfo, }; pub use protocol::{PeerInfo, Context, consensus_gossip, message, specialization}; +pub use protocol::event::{Event, DhtEvent}; pub use protocol::sync::SyncState; pub use libp2p::{Multiaddr, PeerId}; #[doc(inline)] diff --git a/core/network/src/protocol/event.rs b/core/network/src/protocol/event.rs index c0c26da515..c8bee5588c 100644 --- a/core/network/src/protocol/event.rs +++ b/core/network/src/protocol/event.rs @@ -20,6 +20,7 @@ use libp2p::kad::record::Key; /// Events generated by DHT as a response to get_value and put_value requests. +#[derive(Debug, Clone)] pub enum DhtEvent { /// The value was found. ValueFound(Vec<(Key, Vec)>), @@ -35,6 +36,7 @@ pub enum DhtEvent { } /// Type for events generated by networking layer. +#[derive(Debug, Clone)] pub enum Event { /// Event generated by a DHT. Dht(DhtEvent), diff --git a/core/network/src/service.rs b/core/network/src/service.rs index c3f773e232..ac6bd1ac05 100644 --- a/core/network/src/service.rs +++ b/core/network/src/service.rs @@ -612,11 +612,11 @@ pub struct NetworkWorker, H: Ex light_client_rqs: Option>>, } -impl, H: ExHashT> Future for NetworkWorker { - type Item = (); +impl, H: ExHashT> Stream for NetworkWorker { + type Item = Event; type Error = io::Error; - fn poll(&mut self) -> Poll { + fn poll(&mut self) -> Poll, Self::Error> { // Poll the import queue for actions to perform. let _ = futures03::future::poll_fn(|cx| { self.import_queue.poll_actions(cx, &mut NetworkLink { @@ -636,7 +636,7 @@ impl, H: ExHashT> Future for Ne // Process the next message coming from the `NetworkService`. let msg = match self.from_worker.poll() { Ok(Async::Ready(Some(msg))) => msg, - Ok(Async::Ready(None)) | Err(_) => return Ok(Async::Ready(())), + Ok(Async::Ready(None)) | Err(_) => return Ok(Async::Ready(None)), Ok(Async::NotReady) => break, }; @@ -677,8 +677,9 @@ impl, H: ExHashT> Future for Ne Ok(Async::Ready(Some(BehaviourOut::SubstrateAction(outcome)))) => outcome, Ok(Async::Ready(Some(BehaviourOut::Dht(ev)))) => { self.network_service.user_protocol_mut() - .on_event(Event::Dht(ev)); - CustomMessageOutcome::None + .on_event(Event::Dht(ev.clone())); + + return Ok(Async::Ready(Some(Event::Dht(ev)))); }, Ok(Async::Ready(None)) => CustomMessageOutcome::None, Err(err) => { diff --git a/core/service/Cargo.toml b/core/service/Cargo.toml index 7afd59ebc0..7f17d83931 100644 --- a/core/service/Cargo.toml +++ b/core/service/Cargo.toml @@ -31,12 +31,14 @@ client = { package = "substrate-client", path = "../../core/client" } client_db = { package = "substrate-client-db", path = "../../core/client/db", features = ["kvdb-rocksdb"] } codec = { package = "parity-scale-codec", version = "1.0.0" } substrate-executor = { path = "../../core/executor" } +substrate-authority-discovery = { path = "../../core/authority-discovery"} transaction_pool = { package = "substrate-transaction-pool", path = "../../core/transaction-pool" } rpc-servers = { package = "substrate-rpc-servers", path = "../../core/rpc-servers" } rpc = { package = "substrate-rpc", path = "../../core/rpc" } tel = { package = "substrate-telemetry", path = "../../core/telemetry" } offchain = { package = "substrate-offchain", path = "../../core/offchain" } parity-multiaddr = { package = "parity-multiaddr", version = "0.5.0" } +authority-discovery-primitives = { package = "substrate-authority-discovery-primitives", path = "../authority-discovery/primitives", default-features = false } [dev-dependencies] substrate-test-runtime-client = { path = "../test-runtime/client" } diff --git a/core/service/src/builder.rs b/core/service/src/builder.rs index c675710e54..53cec940d7 100644 --- a/core/service/src/builder.rs +++ b/core/service/src/builder.rs @@ -28,7 +28,7 @@ use futures::{prelude::*, sync::mpsc}; use futures03::{FutureExt as _, compat::Compat, StreamExt as _, TryStreamExt as _}; use keystore::{Store as Keystore, KeyStorePtr}; use log::{info, warn}; -use network::{FinalityProofProvider, OnDemand, NetworkService, NetworkStateInfo}; +use network::{FinalityProofProvider, OnDemand, NetworkService, NetworkStateInfo, DhtEvent}; use network::{config::BoxFinalityProofRequestBuilder, specialization::NetworkSpecialization}; use parking_lot::{Mutex, RwLock}; use primitives::{Blake2Hasher, H256, Hasher}; @@ -76,6 +76,7 @@ pub struct ServiceBuilder, rpc_extensions: TRpc, rpc_builder: TRpcB, + dht_event_tx: Option>, marker: PhantomData<(TBl, TRtApi)>, } @@ -197,6 +198,7 @@ where TGen: Serialize + DeserializeOwned + BuildStorage { transaction_pool: Arc::new(()), rpc_extensions: Default::default(), rpc_builder, + dht_event_tx: None, marker: PhantomData, }) } @@ -266,6 +268,7 @@ where TGen: Serialize + DeserializeOwned + BuildStorage { transaction_pool: Arc::new(()), rpc_extensions: Default::default(), rpc_builder, + dht_event_tx: None, marker: PhantomData, }) } @@ -312,6 +315,7 @@ impl, + ) -> Result, Error> { + Ok(ServiceBuilder { + config: self.config, + client: self.client, + backend: self.backend, + keystore: self.keystore, + fetcher: self.fetcher, + select_chain: self.select_chain, + import_queue: self.import_queue, + finality_proof_request_builder: self.finality_proof_request_builder, + finality_proof_provider: self.finality_proof_provider, + network_protocol: self.network_protocol, + transaction_pool: self.transaction_pool, + rpc_extensions: self.rpc_extensions, + rpc_builder: self.rpc_builder, + dht_event_tx: Some(dht_event_tx), + marker: self.marker, + }) + } } /// RPC handlers builder. @@ -798,6 +834,7 @@ ServiceBuilder< network_protocol, transaction_pool, rpc_extensions, + dht_event_tx, rpc_builder, ) = ( self.client, @@ -811,6 +848,7 @@ ServiceBuilder< self.network_protocol, self.transaction_pool, self.rpc_extensions, + self.dht_event_tx, self.rpc_builder, ); @@ -829,7 +867,8 @@ ServiceBuilder< finality_proof_provider, network_protocol, transaction_pool, - rpc_extensions + rpc_extensions, + dht_event_tx, )) }, |h, c, tx| maintain_transaction_pool(h, c, tx), diff --git a/core/service/src/lib.rs b/core/service/src/lib.rs index 2056c8a2f2..9fc305560f 100644 --- a/core/service/src/lib.rs +++ b/core/service/src/lib.rs @@ -39,7 +39,7 @@ use client::{runtime_api::BlockT, Client}; use exit_future::Signal; use futures::prelude::*; use futures03::stream::{StreamExt as _, TryStreamExt as _}; -use network::{NetworkService, NetworkState, specialization::NetworkSpecialization}; +use network::{NetworkService, NetworkState, specialization::NetworkSpecialization, Event, DhtEvent}; use log::{log, warn, debug, error, Level}; use codec::{Encode, Decode}; use primitives::{Blake2Hasher, H256}; @@ -154,7 +154,8 @@ macro_rules! new_impl { finality_proof_provider, network_protocol, transaction_pool, - rpc_extensions + rpc_extensions, + dht_event_tx, ) = $build_components(&$config)?; let import_queue = Box::new(import_queue); let chain_info = client.info().chain; @@ -357,12 +358,14 @@ macro_rules! new_impl { let rpc_handlers = gen_handler(); let rpc = start_rpc_servers(&$config, gen_handler)?; + let _ = to_spawn_tx.unbounded_send(Box::new(build_network_future( network_mut, client.clone(), network_status_sinks.clone(), system_rpc_rx, - has_bootnodes + has_bootnodes, + dht_event_tx, ) .map_err(|_| ()) .select(exit.clone()) @@ -653,6 +656,7 @@ fn build_network_future< status_sinks: Arc, NetworkState)>>>>, rpc_rx: futures03::channel::mpsc::UnboundedReceiver>, should_have_peers: bool, + dht_event_tx: Option>, ) -> impl Future { // Compatibility shim while we're transitionning to stable Futures. // See https://github.com/paritytech/substrate/issues/3099 @@ -730,11 +734,21 @@ fn build_network_future< } // Main network polling. - match network.poll() { - Ok(Async::NotReady) => {} - Err(err) => warn!(target: "service", "Error in network: {:?}", err), - Ok(Async::Ready(())) => warn!(target: "service", "Network service finished"), - } + while let Ok(Async::Ready(Some(Event::Dht(event)))) = network.poll().map_err(|err| { + warn!(target: "service", "Error in network: {:?}", err); + }) { + // Given that core/authority-discovery is the only upper stack consumer of Dht events at the moment, all Dht + // events are being passed on to the authority-discovery module. In the future there might be multiple + // consumers of these events. In that case this would need to be refactored to properly dispatch the events, + // e.g. via a subscriber model. + if let Some(Err(e)) = dht_event_tx.as_ref().map(|c| c.clone().try_send(event)) { + if e.is_full() { + warn!(target: "service", "Dht event channel to authority discovery is full, dropping event."); + } else if e.is_disconnected() { + warn!(target: "service", "Dht event channel to authority discovery is disconnected, dropping event."); + } + } + }; // Now some diagnostic for performances. let polling_dur = before_polling.elapsed(); diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index 1f35f7b86b..c28a517639 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -46,7 +46,8 @@ system = { package = "srml-system", path = "../../srml/system" } balances = { package = "srml-balances", path = "../../srml/balances" } support = { package = "srml-support", path = "../../srml/support", default-features = false } im_online = { package = "srml-im-online", path = "../../srml/im-online", default-features = false } -authority-discovery = { package = "srml-authority-discovery", path = "../../srml/authority-discovery", default-features = false } +sr-authority-discovery = { package = "srml-authority-discovery", path = "../../srml/authority-discovery", default-features = false } +authority-discovery = { package = "substrate-authority-discovery", path = "../../core/authority-discovery"} [dev-dependencies] keystore = { package = "substrate-keystore", path = "../../core/keystore" } diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index 509de7a943..8522ce6d12 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -103,6 +103,8 @@ macro_rules! new_full_start { macro_rules! new_full { ($config:expr) => {{ use futures::Future; + use futures::sync::mpsc; + use network::DhtEvent; let ( is_authority, @@ -118,10 +120,18 @@ macro_rules! new_full { let (builder, mut import_setup, inherent_data_providers, mut tasks_to_spawn) = new_full_start!($config); + // Dht event channel from the network to the authority discovery module. Use bounded channel to ensure + // back-pressure. Authority discovery is triggering one event per authority within the current authority set. + // This estimates the authority set size to be somewhere below 10 000 thereby setting the channel buffer size to + // 10 000. + let (dht_event_tx, dht_event_rx) = + mpsc::channel::(10000); + let service = builder.with_network_protocol(|_| Ok(crate::service::NodeProtocol::new()))? .with_finality_proof_provider(|client, backend| Ok(Arc::new(grandpa::FinalityProofProvider::new(backend, client)) as _) )? + .with_dht_event_tx(dht_event_tx)? .build()?; let (block_import, link_half, babe_link) = import_setup.take() @@ -162,6 +172,13 @@ macro_rules! new_full { let babe = babe::start_babe(babe_config)?; let select = babe.select(service.on_exit()).then(|_| Ok(())); service.spawn_task(Box::new(select)); + + let authority_discovery = authority_discovery::AuthorityDiscovery::new( + service.client(), + service.network(), + dht_event_rx, + ); + service.spawn_task(Box::new(authority_discovery)); } let config = grandpa::Config { diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index ded3fa483d..9d7ae5d9df 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -47,7 +47,9 @@ use elections::VoteIndex; use version::NativeVersion; use primitives::OpaqueMetadata; use grandpa::{AuthorityId as GrandpaId, AuthorityWeight as GrandpaWeight}; -use im_online::sr25519::{AuthorityId as ImOnlineId}; +use im_online::sr25519::{AuthorityId as ImOnlineId, AuthoritySignature as ImOnlineSignature}; +use authority_discovery_primitives::{AuthorityId as EncodedAuthorityId, Signature as EncodedSignature}; +use codec::{Encode, Decode}; use system::offchain::TransactionSubmitter; #[cfg(any(feature = "std", test))] @@ -191,7 +193,7 @@ impl authorship::Trait for Runtime { type EventHandler = Staking; } -type SessionHandlers = (Grandpa, Babe, ImOnline); +type SessionHandlers = (Grandpa, Babe, ImOnline, AuthorityDiscovery); impl_opaque_keys! { pub struct SessionKeys { @@ -617,20 +619,32 @@ impl_runtime_apis! { } } - impl authority_discovery_primitives::AuthorityDiscoveryApi for Runtime { - fn authority_id() -> Option { - AuthorityDiscovery::authority_id() - } - fn authorities() -> Vec { - AuthorityDiscovery::authorities() + impl authority_discovery_primitives::AuthorityDiscoveryApi for Runtime { + fn authorities() -> Vec { + AuthorityDiscovery::authorities().into_iter() + .map(|id| id.encode()) + .map(EncodedAuthorityId) + .collect() } - fn sign(payload: Vec, authority_id: ImOnlineId) -> Option> { - AuthorityDiscovery::sign(payload, authority_id) + fn sign(payload: &Vec) -> Option<(EncodedSignature, EncodedAuthorityId)> { + AuthorityDiscovery::sign(payload).map(|(sig, id)| { + (EncodedSignature(sig.encode()), EncodedAuthorityId(id.encode())) + }) } - fn verify(payload: Vec, signature: Vec, public_key: ImOnlineId) -> bool { - AuthorityDiscovery::verify(payload, signature, public_key) + fn verify(payload: &Vec, signature: &EncodedSignature, authority_id: &EncodedAuthorityId) -> bool { + let signature = match ImOnlineSignature::decode(&mut &signature.0[..]) { + Ok(s) => s, + _ => return false, + }; + + let authority_id = match ImOnlineId::decode(&mut &authority_id.0[..]) { + Ok(id) => id, + _ => return false, + }; + + AuthorityDiscovery::verify(payload, signature, authority_id) } } diff --git a/srml/authority-discovery/src/lib.rs b/srml/authority-discovery/src/lib.rs index 76b0c93c4f..1c46822dfe 100644 --- a/srml/authority-discovery/src/lib.rs +++ b/srml/authority-discovery/src/lib.rs @@ -29,13 +29,14 @@ #![cfg_attr(not(feature = "std"), no_std)] use app_crypto::RuntimeAppPublic; -use codec::{Decode, Encode}; use rstd::prelude::*; use support::{decl_module, decl_storage, StorageValue}; pub trait Trait: system::Trait + session::Trait + im_online::Trait {} type AuthorityIdFor = ::AuthorityId; +type AuthoritySignatureFor = + <::AuthorityId as RuntimeAppPublic>::Signature; decl_storage! { trait Store for Module as AuthorityDiscovery { @@ -58,7 +59,7 @@ impl Module { /// set, otherwise this function returns None. The restriction might be /// softened in the future in case a consumer needs to learn own authority /// identifier. - pub fn authority_id() -> Option> { + fn authority_id() -> Option> { let authorities = Keys::::get(); let local_keys = >::all(); @@ -78,20 +79,19 @@ impl Module { } /// Sign the given payload with the private key corresponding to the given authority id. - pub fn sign(payload: Vec, authority_id: AuthorityIdFor) -> Option> { - authority_id.sign(&payload).map(|s| s.encode()) + pub fn sign(payload: &Vec) -> Option<(AuthoritySignatureFor, AuthorityIdFor)> { + let authority_id = Module::::authority_id()?; + authority_id.sign(payload).map(|s| (s, authority_id)) } /// Verify the given signature for the given payload with the given /// authority identifier. pub fn verify( - payload: Vec, - signature: Vec, + payload: &Vec, + signature: AuthoritySignatureFor, authority_id: AuthorityIdFor, ) -> bool { - as RuntimeAppPublic>::Signature::decode(&mut &signature[..]) - .map(|s| authority_id.verify(&payload, &s)) - .unwrap_or(false) + authority_id.verify(payload, &signature) } fn initialize_keys(keys: &[AuthorityIdFor]) { @@ -158,10 +158,7 @@ mod tests { pub struct TestOnSessionEnding; impl session::OnSessionEnding for TestOnSessionEnding { - fn on_session_ending( - _: SessionIndex, - _: SessionIndex, - ) -> Option> { + fn on_session_ending(_: SessionIndex, _: SessionIndex) -> Option> { None } } @@ -351,19 +348,13 @@ mod tests { externalities.set_keystore(key_store); with_externalities(&mut externalities, || { - let authority_id = AuthorityDiscovery::authority_id().expect("authority id"); let payload = String::from("test payload").into_bytes(); - let sig = - AuthorityDiscovery::sign(payload.clone(), authority_id.clone()).expect("signature"); + let (sig, authority_id) = AuthorityDiscovery::sign(&payload).expect("signature"); - assert!(AuthorityDiscovery::verify( - payload, - sig.clone(), - authority_id.clone() - )); + assert!(AuthorityDiscovery::verify(&payload, sig.clone(), authority_id.clone(),)); assert!(!AuthorityDiscovery::verify( - String::from("other payload").into_bytes(), + &String::from("other payload").into_bytes(), sig, authority_id )) diff --git a/srml/im-online/src/lib.rs b/srml/im-online/src/lib.rs index 6106b1e45c..3fd57a2e24 100644 --- a/srml/im-online/src/lib.rs +++ b/srml/im-online/src/lib.rs @@ -67,7 +67,7 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -use app_crypto::{AppPublic, RuntimeAppPublic}; +use app_crypto::{AppPublic, RuntimeAppPublic, AppSignature}; use codec::{Encode, Decode}; use primitives::offchain::{OpaqueNetworkState, StorageKind}; use rstd::prelude::*; -- GitLab From 43c4ef5d8932badc4c90554f06b134547961a80e Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Fri, 6 Sep 2019 19:41:29 +0200 Subject: [PATCH 063/275] Better testing for lock types in staking/democracy. (#3565) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Better testing for lock types in staking/democracy. * Update docs. * Update srml/executive/src/lib.rs Co-Authored-By: Bastian Köcher * Update srml/executive/src/lib.rs Co-Authored-By: Bastian Köcher * Fix test --- srml/executive/src/lib.rs | 61 +++++++++++++++++++++----------------- srml/staking/src/tests.rs | 2 +- srml/support/src/traits.rs | 10 +++++++ 3 files changed, 44 insertions(+), 29 deletions(-) diff --git a/srml/executive/src/lib.rs b/srml/executive/src/lib.rs index f3e8b63a28..ff0fc32e9b 100644 --- a/srml/executive/src/lib.rs +++ b/srml/executive/src/lib.rs @@ -293,21 +293,24 @@ where #[cfg(test)] mod tests { use super::*; - use balances::Call; use runtime_io::with_externalities; use primitives::{H256, Blake2Hasher}; use sr_primitives::{ generic::Era, Perbill, DispatchError, weights::Weight, testing::{Digest, Header, Block}, - traits::{Header as HeaderT, BlakeTwo256, IdentityLookup, ConvertInto}, + traits::{Bounded, Header as HeaderT, BlakeTwo256, IdentityLookup, ConvertInto}, transaction_validity::{InvalidTransaction, UnknownTransaction}, ApplyError, }; use support::{ - impl_outer_event, impl_outer_origin, parameter_types, + impl_outer_event, impl_outer_origin, parameter_types, impl_outer_dispatch, traits::{Currency, LockIdentifier, LockableCurrency, WithdrawReasons, WithdrawReason}, }; - use system; + use system::Call as SystemCall; + use balances::Call as BalancesCall; use hex_literal::hex; + type System = system::Module; + type Balances = balances::Module; + impl_outer_origin! { pub enum Origin for Runtime { } } @@ -317,6 +320,12 @@ mod tests { balances, } } + impl_outer_dispatch! { + pub enum Call for Runtime where origin: Origin { + system::System, + balances::Balances, + } + } // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, Eq, PartialEq)] @@ -330,7 +339,7 @@ mod tests { impl system::Trait for Runtime { type Origin = Origin; type Index = u64; - type Call = Call; + type Call = Call; type BlockNumber = u64; type Hash = primitives::H256; type Hashing = BlakeTwo256; @@ -369,11 +378,11 @@ mod tests { } impl ValidateUnsigned for Runtime { - type Call = Call; + type Call = Call; fn validate_unsigned(call: &Self::Call) -> TransactionValidity { match call { - Call::set_balance(_, _, _) => Ok(Default::default()), + Call::Balances(BalancesCall::set_balance(_, _, _)) => Ok(Default::default()), _ => UnknownTransaction::NoUnsignedValidator.into(), } } @@ -385,7 +394,7 @@ mod tests { system::CheckWeight, balances::TakeFees ); - type TestXt = sr_primitives::testing::TestXt, SignedExtra>; + type TestXt = sr_primitives::testing::TestXt; type Executive = super::Executive, system::ChainContext, Runtime, ()>; fn extra(nonce: u64, fee: u64) -> SignedExtra { @@ -408,7 +417,7 @@ mod tests { balances: vec![(1, 211)], vesting: vec![], }.assimilate_storage(&mut t).unwrap(); - let xt = sr_primitives::testing::TestXt(sign_extra(1, 0, 0), Call::transfer(2, 69)); + let xt = sr_primitives::testing::TestXt(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(2, 69))); let weight = xt.get_dispatch_info().weight as u64; let mut t = runtime_io::TestExternalities::::new(t); with_externalities(&mut t, || { @@ -489,7 +498,7 @@ mod tests { fn bad_extrinsic_not_inserted() { let mut t = new_test_ext(1); // bad nonce check! - let xt = sr_primitives::testing::TestXt(sign_extra(1, 30, 0), Call::transfer(33, 69)); + let xt = sr_primitives::testing::TestXt(sign_extra(1, 30, 0), Call::Balances(BalancesCall::transfer(33, 69))); with_externalities(&mut t, || { Executive::initialize_block(&Header::new( 1, @@ -507,7 +516,7 @@ mod tests { fn block_weight_limit_enforced() { let mut t = new_test_ext(10000); // given: TestXt uses the encoded len as fixed Len: - let xt = sr_primitives::testing::TestXt(sign_extra(1, 0, 0), Call::transfer::(33, 0)); + let xt = sr_primitives::testing::TestXt(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(33, 0))); let encoded = xt.encode(); let encoded_len = encoded.len() as Weight; let limit = AvailableBlockRatio::get() * MaximumBlockWeight::get(); @@ -524,7 +533,7 @@ mod tests { for nonce in 0..=num_to_exhaust_block { let xt = sr_primitives::testing::TestXt( - sign_extra(1, nonce.into(), 0), Call::transfer::(33, 0), + sign_extra(1, nonce.into(), 0), Call::Balances(BalancesCall::transfer(33, 0)), ); let res = Executive::apply_extrinsic(xt); if nonce != num_to_exhaust_block { @@ -543,9 +552,9 @@ mod tests { #[test] fn block_weight_and_size_is_stored_per_tx() { - let xt = sr_primitives::testing::TestXt(sign_extra(1, 0, 0), Call::transfer(33, 0)); - let x1 = sr_primitives::testing::TestXt(sign_extra(1, 1, 0), Call::transfer(33, 0)); - let x2 = sr_primitives::testing::TestXt(sign_extra(1, 2, 0), Call::transfer(33, 0)); + let xt = sr_primitives::testing::TestXt(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(33, 0))); + let x1 = sr_primitives::testing::TestXt(sign_extra(1, 1, 0), Call::Balances(BalancesCall::transfer(33, 0))); + let x2 = sr_primitives::testing::TestXt(sign_extra(1, 2, 0), Call::Balances(BalancesCall::transfer(33, 0))); let len = xt.clone().encode().len() as u32; let mut t = new_test_ext(1); with_externalities(&mut t, || { @@ -569,7 +578,7 @@ mod tests { #[test] fn validate_unsigned() { - let xt = sr_primitives::testing::TestXt(None, Call::set_balance(33, 69, 69)); + let xt = sr_primitives::testing::TestXt(None, Call::Balances(BalancesCall::set_balance(33, 69, 69))); let mut t = new_test_ext(1); with_externalities(&mut t, || { @@ -578,7 +587,7 @@ mod tests { Executive::apply_extrinsic(xt), Ok( Err( - DispatchError { module: None, error: 0, message: Some("RequireRootOrigin") } + DispatchError { module: Some(1), error: 0, message: Some("RequireRootOrigin") } ) ) ); @@ -595,10 +604,13 @@ mod tests { id, &1, 110, - 10, + Bounded::max_value(), lock, ); - let xt = sr_primitives::testing::TestXt(sign_extra(1, 0, 0), Call::transfer(2, 10)); + let xt = sr_primitives::testing::TestXt( + sign_extra(1, 0, 0), + Call::System(SystemCall::remark(vec![1u8])), + ); let weight = xt.get_dispatch_info().weight as u64; Executive::initialize_block(&Header::new( 1, @@ -609,15 +621,8 @@ mod tests { )); if lock == WithdrawReasons::except(WithdrawReason::TransactionPayment) { - assert_eq!( - Executive::apply_extrinsic(xt).unwrap(), - Err(DispatchError { - module: None, - error: 0, - message: Some("account liquidity restrictions prevent withdrawal"), - }), - ); - // but tx fee has been deducted. the transaction failed on transfer, not on fee. + assert!(Executive::apply_extrinsic(xt).unwrap().is_ok()); + // tx fee has been deducted. assert_eq!(>::total_balance(&1), 111 - 10 - weight); } else { assert_eq!( diff --git a/srml/staking/src/tests.rs b/srml/staking/src/tests.rs index 34d95b60f2..3a42ead68a 100644 --- a/srml/staking/src/tests.rs +++ b/srml/staking/src/tests.rs @@ -1562,7 +1562,7 @@ fn bond_with_no_staked_value() { .nominate(false) .minimum_validator_count(1) .build(), || { - // Can't bond with 1 + // Can't bond with 1 assert_noop!( Staking::bond(Origin::signed(1), 2, 1, RewardDestination::Controller), "can not bond with value less than minimum balance" diff --git a/srml/support/src/traits.rs b/srml/support/src/traits.rs index 355f05992f..4ce94bb341 100644 --- a/srml/support/src/traits.rs +++ b/srml/support/src/traits.rs @@ -639,6 +639,16 @@ pub trait Time { impl WithdrawReasons { /// Choose all variants except for `one`. + /// + /// ```rust + /// # use srml_support::traits::{WithdrawReason, WithdrawReasons}; + /// # fn main() { + /// assert_eq!( + /// WithdrawReason::Fee | WithdrawReason::Transfer | WithdrawReason::Reserve, + /// WithdrawReasons::except(WithdrawReason::TransactionPayment), + /// ); + /// # } + /// ``` pub fn except(one: WithdrawReason) -> WithdrawReasons { let mut mask = Self::all(); mask.toggle(one); -- GitLab From e169b372784fa9a493c377b2c385baa79e18a750 Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Fri, 6 Sep 2019 21:30:43 +0200 Subject: [PATCH 064/275] Add transactions from retracted blocks back to the pool (#3562) * Add transactions from retracted blocks back to the pool * Line width * Reverse retracted --- core/basic-authorship/src/basic_authorship.rs | 2 +- core/client/src/backend.rs | 19 ++--- core/client/src/client.rs | 49 ++++++++----- core/finality-grandpa/src/until_imported.rs | 1 + core/service/src/builder.rs | 70 ++++++++++++++++++- core/service/src/lib.rs | 1 + core/transaction-pool/graph/src/pool.rs | 10 +-- 7 files changed, 118 insertions(+), 34 deletions(-) diff --git a/core/basic-authorship/src/basic_authorship.rs b/core/basic-authorship/src/basic_authorship.rs index ffc4d766c9..59b12ba1e4 100644 --- a/core/basic-authorship/src/basic_authorship.rs +++ b/core/basic-authorship/src/basic_authorship.rs @@ -250,7 +250,7 @@ mod tests { let chain_api = transaction_pool::ChainApi::new(client.clone()); let txpool = Arc::new(TransactionPool::new(Default::default(), chain_api)); - txpool.submit_at(&BlockId::number(0), vec![extrinsic(0), extrinsic(1)]).unwrap(); + txpool.submit_at(&BlockId::number(0), vec![extrinsic(0), extrinsic(1)], false).unwrap(); let mut proposer_factory = ProposerFactory { client: client.clone(), diff --git a/core/client/src/backend.rs b/core/client/src/backend.rs index 457a1b86ec..ad683ebac1 100644 --- a/core/client/src/backend.rs +++ b/core/client/src/backend.rs @@ -35,6 +35,15 @@ pub type StorageCollection = Vec<(Vec, Option>)>; /// In memory arrays of storage values for multiple child tries. pub type ChildStorageCollection = Vec<(Vec, StorageCollection)>; +pub(crate) struct ImportSummary { + pub(crate) hash: Block::Hash, + pub(crate) origin: BlockOrigin, + pub(crate) header: Block::Header, + pub(crate) is_new_best: bool, + pub(crate) storage_changes: Option<(StorageCollection, ChildStorageCollection)>, + pub(crate) retracted: Vec, +} + /// Import operation wrapper pub struct ClientImportOperation< Block: BlockT, @@ -42,15 +51,7 @@ pub struct ClientImportOperation< B: Backend, > { pub(crate) op: B::BlockImportOperation, - pub(crate) notify_imported: Option<( - Block::Hash, - BlockOrigin, - Block::Header, - bool, - Option<( - StorageCollection, - ChildStorageCollection, - )>)>, + pub(crate) notify_imported: Option>, pub(crate) notify_finalized: Vec, } diff --git a/core/client/src/client.rs b/core/client/src/client.rs index 50e962c8b5..90cdff9fa8 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -62,7 +62,7 @@ use crate::{ }, backend::{ self, BlockImportOperation, PrunableStateChangesTrieStorage, - ClientImportOperation, Finalizer, + ClientImportOperation, Finalizer, ImportSummary, }, blockchain::{ self, Info as ChainInfo, Backend as ChainBackend, @@ -199,6 +199,8 @@ pub struct BlockImportNotification { pub header: Block::Header, /// Is this the new best block. pub is_new_best: bool, + /// List of retracted blocks ordered by block number. + pub retracted: Vec, } /// Summary of a finalized block. @@ -968,6 +970,17 @@ impl Client where crate::backend::NewBlockState::Normal }; + let retracted = if is_new_best { + let route_from_best = crate::blockchain::tree_route( + |id| self.header(&id)?.ok_or_else(|| Error::UnknownBlock(format!("{:?}", id))), + BlockId::Hash(info.best_hash), + BlockId::Hash(parent_hash), + )?; + route_from_best.retracted().iter().rev().map(|e| e.hash.clone()).collect() + } else { + Vec::default() + }; + trace!("Imported {}, (#{}), best={}, origin={:?}", hash, import_headers.post().number(), is_new_best, origin); operation.op.set_block_data( @@ -995,7 +1008,14 @@ impl Client where operation.notify_finalized.push(hash); } - operation.notify_imported = Some((hash, origin, import_headers.into_post(), is_new_best, storage_changes)); + operation.notify_imported = Some(ImportSummary { + hash, + origin, + header: import_headers.into_post(), + is_new_best, + storage_changes, + retracted, + }) } Ok(ImportResult::imported(is_new_best)) @@ -1167,33 +1187,24 @@ impl Client where fn notify_imported( &self, - notify_import: ( - Block::Hash, BlockOrigin, - Block::Header, - bool, - Option<( - Vec<(Vec, Option>)>, - Vec<(Vec, Vec<(Vec, Option>)>)>, - ) - >), + notify_import: ImportSummary, ) -> error::Result<()> { - let (hash, origin, header, is_new_best, storage_changes) = notify_import; - - if let Some(storage_changes) = storage_changes { + if let Some(storage_changes) = notify_import.storage_changes { // TODO [ToDr] How to handle re-orgs? Should we re-emit all storage changes? self.storage_notifications.lock() .trigger( - &hash, + ¬ify_import.hash, storage_changes.0.into_iter(), storage_changes.1.into_iter().map(|(sk, v)| (sk, v.into_iter())), ); } let notification = BlockImportNotification:: { - hash, - origin, - header, - is_new_best, + hash: notify_import.hash, + origin: notify_import.origin, + header: notify_import.header, + is_new_best: notify_import.is_new_best, + retracted: notify_import.retracted, }; self.import_notification_sinks.lock() diff --git a/core/finality-grandpa/src/until_imported.rs b/core/finality-grandpa/src/until_imported.rs index af797c99ab..4232bfacdf 100644 --- a/core/finality-grandpa/src/until_imported.rs +++ b/core/finality-grandpa/src/until_imported.rs @@ -472,6 +472,7 @@ mod tests { origin: BlockOrigin::File, header, is_new_best: false, + retracted: vec![], }).unwrap(); } } diff --git a/core/service/src/builder.rs b/core/service/src/builder.rs index 53cec940d7..1540eeac9c 100644 --- a/core/service/src/builder.rs +++ b/core/service/src/builder.rs @@ -871,7 +871,7 @@ ServiceBuilder< dht_event_tx, )) }, - |h, c, tx| maintain_transaction_pool(h, c, tx), + |h, c, tx, r| maintain_transaction_pool(h, c, tx, r), |n, o, p, ns, v| offchain_workers(n, o, p, ns, v), |c, ssb, si, te, tp, ext, ks| start_rpc(&rpc_builder, c, ssb, si, te, tp, ext, ks), ) @@ -924,6 +924,7 @@ pub(crate) fn maintain_transaction_pool( id: &BlockId, client: &Client, transaction_pool: &TransactionPool, + retracted: &[Block::Hash], ) -> error::Result<()> where Block: BlockT::Out>, Backend: client::backend::Backend, @@ -932,6 +933,16 @@ pub(crate) fn maintain_transaction_pool( Executor: client::CallExecutor, PoolApi: txpool::ChainApi, { + // Put transactions from retracted blocks back into the pool. + for r in retracted { + if let Some(block) = client.block(&BlockId::hash(*r))? { + let extrinsics = block.block.extrinsics(); + if let Err(e) = transaction_pool.submit_at(id, extrinsics.iter().cloned(), true) { + warn!("Error re-submitting transactions: {:?}", e); + } + } + } + // Avoid calling into runtime if there is nothing to prune from the pool anyway. if transaction_pool.status().is_empty() { return Ok(()) @@ -1007,10 +1018,67 @@ mod tests { &id, &client, &pool, + &[] ).unwrap(); // then assert_eq!(pool.status().ready, 0); assert_eq!(pool.status().future, 0); } + + #[test] + fn should_add_reverted_transactions_to_the_pool() { + let (client, longest_chain) = TestClientBuilder::new().build_with_longest_chain(); + let client = Arc::new(client); + let pool = TransactionPool::new(Default::default(), ::transaction_pool::ChainApi::new(client.clone())); + let transaction = Transfer { + amount: 5, + nonce: 0, + from: AccountKeyring::Alice.into(), + to: Default::default(), + }.into_signed_tx(); + let best = longest_chain.best_chain().unwrap(); + + // store the transaction in the pool + pool.submit_one(&BlockId::hash(best.hash()), transaction.clone()).unwrap(); + + // import the block + let mut builder = client.new_block(Default::default()).unwrap(); + builder.push(transaction.clone()).unwrap(); + let block = builder.bake().unwrap(); + let block1_hash = block.header().hash(); + let id = BlockId::hash(block1_hash.clone()); + client.import(BlockOrigin::Own, block).unwrap(); + + // fire notification - this should clean up the queue + assert_eq!(pool.status().ready, 1); + maintain_transaction_pool( + &id, + &client, + &pool, + &[] + ).unwrap(); + + // then + assert_eq!(pool.status().ready, 0); + assert_eq!(pool.status().future, 0); + + // import second block + let builder = client.new_block_at(&BlockId::hash(best.hash()), Default::default()).unwrap(); + let block = builder.bake().unwrap(); + let id = BlockId::hash(block.header().hash()); + client.import(BlockOrigin::Own, block).unwrap(); + + // fire notification - this should add the transaction back to the pool. + maintain_transaction_pool( + &id, + &client, + &pool, + &[block1_hash] + ).unwrap(); + + // then + assert_eq!(pool.status().ready, 1); + assert_eq!(pool.status().future, 0); + } } diff --git a/core/service/src/lib.rs b/core/service/src/lib.rs index 9fc305560f..48d5069701 100644 --- a/core/service/src/lib.rs +++ b/core/service/src/lib.rs @@ -238,6 +238,7 @@ macro_rules! new_impl { &BlockId::hash(notification.hash), &*client, &*txpool, + ¬ification.retracted, ).map_err(|e| warn!("Pool error processing new block: {:?}", e))?; } diff --git a/core/transaction-pool/graph/src/pool.rs b/core/transaction-pool/graph/src/pool.rs index 75a4bc4394..389892101e 100644 --- a/core/transaction-pool/graph/src/pool.rs +++ b/core/transaction-pool/graph/src/pool.rs @@ -114,7 +114,9 @@ pub struct Pool { impl Pool { /// Imports a bunch of unverified extrinsics to the pool - pub fn submit_at(&self, at: &BlockId, xts: T) -> Result, B::Error>>, B::Error> where + pub fn submit_at(&self, at: &BlockId, xts: T, force: bool) + -> Result, B::Error>>, B::Error> + where T: IntoIterator> { let block_number = self.api.block_id_to_number(at)? @@ -124,7 +126,7 @@ impl Pool { .into_iter() .map(|xt| -> Result<_, B::Error> { let (hash, bytes) = self.api.hash_and_length(&xt); - if self.rotator.is_banned(&hash) { + if !force && self.rotator.is_banned(&hash) { return Err(error::Error::TemporarilyBanned.into()) } @@ -207,7 +209,7 @@ impl Pool { /// Imports one unverified extrinsic to the pool pub fn submit_one(&self, at: &BlockId, xt: ExtrinsicFor) -> Result, B::Error> { - Ok(self.submit_at(at, ::std::iter::once(xt))?.pop().expect("One extrinsic passed; one result returned; qed")?) + Ok(self.submit_at(at, ::std::iter::once(xt), false)?.pop().expect("One extrinsic passed; one result returned; qed")?) } /// Import a single extrinsic and starts to watch their progress in the pool. @@ -306,7 +308,7 @@ impl Pool { // try to re-submit pruned transactions since some of them might be still valid. // note that `known_imported_hashes` will be rejected here due to temporary ban. let hashes = status.pruned.iter().map(|tx| tx.hash.clone()).collect::>(); - let results = self.submit_at(at, status.pruned.into_iter().map(|tx| tx.data.clone()))?; + let results = self.submit_at(at, status.pruned.into_iter().map(|tx| tx.data.clone()), false)?; // Collect the hashes of transactions that now became invalid (meaning that they are successfully pruned). let hashes = results.into_iter().enumerate().filter_map(|(idx, r)| match r.map_err(error::IntoPoolError::into_pool_error) { -- GitLab From a66536cf302a78bb603368e98cc6516cb345ab83 Mon Sep 17 00:00:00 2001 From: Caio Date: Fri, 6 Sep 2019 16:31:37 -0300 Subject: [PATCH 065/275] Implement `Maybe*` marker traits using a declarative macro (#3557) Although simple, the current `Maybe*` trait implementations are based on a manual approach that uses some code duplication. Now this duplication is removed using a declarative macro. Tested locally, the modification don't seem to affect building times. --- core/sr-primitives/src/traits.rs | 96 +++++++++++--------------------- 1 file changed, 31 insertions(+), 65 deletions(-) diff --git a/core/sr-primitives/src/traits.rs b/core/sr-primitives/src/traits.rs index 0ac40e9942..bbcb46be3d 100644 --- a/core/sr-primitives/src/traits.rs +++ b/core/sr-primitives/src/traits.rs @@ -590,77 +590,43 @@ impl CheckEqual for super::generic::DigestItem MaybeSerializeDebugButNotDeserialize for T {} - -/// A type that implements Serialize and Debug when in std environment. -#[cfg(not(feature = "std"))] -pub trait MaybeSerializeDebugButNotDeserialize {} -#[cfg(not(feature = "std"))] -impl MaybeSerializeDebugButNotDeserialize for T {} - -/// A type that implements Serialize when in std environment. -#[cfg(feature = "std")] -pub trait MaybeSerialize: Serialize {} -#[cfg(feature = "std")] -impl MaybeSerialize for T {} - -/// A type that implements Serialize when in std environment. -#[cfg(not(feature = "std"))] -pub trait MaybeSerialize {} -#[cfg(not(feature = "std"))] -impl MaybeSerialize for T {} - -/// A type that implements Serialize, DeserializeOwned and Debug when in std environment. -#[cfg(feature = "std")] -pub trait MaybeSerializeDebug: Serialize + DeserializeOwned + Debug {} -#[cfg(feature = "std")] -impl MaybeSerializeDebug for T {} +macro_rules! impl_maybe_marker { + ( $( $(#[$doc:meta])+ $trait_name:ident: $($trait_bound:path),+ );+ ) => { + $( + $(#[$doc])+ + #[cfg(feature = "std")] + pub trait $trait_name: $($trait_bound +)+ {} + #[cfg(feature = "std")] + impl $trait_name for T {} + + $(#[$doc])+ + #[cfg(not(feature = "std"))] + pub trait $trait_name {} + #[cfg(not(feature = "std"))] + impl $trait_name for T {} + )+ + } +} -/// A type that implements Serialize, DeserializeOwned and Debug when in std environment. -#[cfg(not(feature = "std"))] -pub trait MaybeSerializeDebug {} -#[cfg(not(feature = "std"))] -impl MaybeSerializeDebug for T {} +impl_maybe_marker!( + /// A type that implements Debug when in std environment. + MaybeDebug: Debug; -/// A type that implements Debug when in std environment. -#[cfg(feature = "std")] -pub trait MaybeDebug: Debug {} -#[cfg(feature = "std")] -impl MaybeDebug for T {} + /// A type that implements Display when in std environment. + MaybeDisplay: Display; -/// A type that implements Debug when in std environment. -#[cfg(not(feature = "std"))] -pub trait MaybeDebug {} -#[cfg(not(feature = "std"))] -impl MaybeDebug for T {} + /// A type that implements Hash when in std environment. + MaybeHash: ::rstd::hash::Hash; -/// A type that implements Display when in std environment. -#[cfg(feature = "std")] -pub trait MaybeDisplay: Display {} -#[cfg(feature = "std")] -impl MaybeDisplay for T {} - -/// A type that implements Display when in std environment. -#[cfg(not(feature = "std"))] -pub trait MaybeDisplay {} -#[cfg(not(feature = "std"))] -impl MaybeDisplay for T {} + /// A type that implements Serialize when in std environment. + MaybeSerialize: Serialize; -/// A type that implements Hash when in std environment. -#[cfg(feature = "std")] -pub trait MaybeHash: ::rstd::hash::Hash {} -#[cfg(feature = "std")] -impl MaybeHash for T {} + /// A type that implements Serialize, DeserializeOwned and Debug when in std environment. + MaybeSerializeDebug: Debug, DeserializeOwned, Serialize; -/// A type that implements Hash when in std environment. -#[cfg(not(feature = "std"))] -pub trait MaybeHash {} -#[cfg(not(feature = "std"))] -impl MaybeHash for T {} + /// A type that implements Serialize and Debug when in std environment. + MaybeSerializeDebugButNotDeserialize: Debug, Serialize +); /// A type that provides a randomness beacon. pub trait RandomnessBeacon { -- GitLab From 17e389db83c23e1ed5a0b3f4eb066cc55811c884 Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Fri, 6 Sep 2019 23:08:08 +0200 Subject: [PATCH 066/275] Update docs for the wasm executor crate (#3569) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Grammar. * Update docs for wasm executor. * Update core/executor/src/lib.rs Co-Authored-By: André Silva --- core/executor/src/lib.rs | 19 ++++++++++--------- core/executor/src/native_executor.rs | 8 ++++++-- core/executor/src/wasm_executor.rs | 5 ++++- core/executor/src/wasm_utils.rs | 2 +- core/state-machine/src/lib.rs | 4 ++-- 5 files changed, 23 insertions(+), 15 deletions(-) diff --git a/core/executor/src/lib.rs b/core/executor/src/lib.rs index 065de451c1..684200519e 100644 --- a/core/executor/src/lib.rs +++ b/core/executor/src/lib.rs @@ -14,16 +14,17 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Temporary crate for contracts implementations. +//! A crate that provides means of executing/dispatching calls into the runtime. //! -//! This will be replaced with WASM contracts stored on-chain. -//! ** NOTE *** -//! This is entirely deprecated with the idea of a single-module Wasm module for state transition. -//! The dispatch table should be replaced with the specific functions needed: -//! - execute_block(bytes) -//! - init_block(PrevBlock?) -> InProgressBlock -//! - add_transaction(InProgressBlock) -> InProgressBlock -//! It is left as is for now as it might be removed before this is ever done. +//! There are a few responsibilities of this crate at the moment: +//! +//! - It provides an implementation of a common entrypoint for calling into the runtime, both +//! wasm and compiled. +//! - It defines the environment for the wasm execution, namely the host functions that are to be +//! provided into the wasm runtime module. +//! - It also provides the required infrastructure for executing the current wasm runtime (specified +//! by the current value of `:code` in the provided externalities), i.e. interfacing with +//! wasm engine used, instance cache. #![warn(missing_docs)] #![recursion_limit="128"] diff --git a/core/executor/src/native_executor.rs b/core/executor/src/native_executor.rs index 1ebf7f3146..616b9f8c6d 100644 --- a/core/executor/src/native_executor.rs +++ b/core/executor/src/native_executor.rs @@ -47,9 +47,13 @@ pub fn with_native_environment(ext: &mut dyn Externalities, ::runtime_io::with_externalities(ext, move || safe_call(f)) } -/// Delegate for dispatching a CodeExecutor call to native code. +/// Delegate for dispatching a CodeExecutor call. +/// +/// By dispatching we mean that we execute a runtime function specified by it's name. pub trait NativeExecutionDispatch: Send + Sync { - /// Dispatch a method and input data to be executed natively. + /// Dispatch a method in the runtime. + /// + /// If the method with the specified name doesn't exist then `Err` is returned. fn dispatch(ext: &mut dyn Externalities, method: &str, data: &[u8]) -> Result>; /// Provide native runtime version. diff --git a/core/executor/src/wasm_executor.rs b/core/executor/src/wasm_executor.rs index b22fe3d363..d8fd41ab7f 100644 --- a/core/executor/src/wasm_executor.rs +++ b/core/executor/src/wasm_executor.rs @@ -14,7 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Rust implementation of Substrate contracts. +//! Wasm interface module. +//! +//! This module defines and implements the wasm part of Substrate Host Interface and provides +//! an interface for calling into the wasm runtime. use std::{collections::HashMap, convert::TryFrom, str}; use tiny_keccak; diff --git a/core/executor/src/wasm_utils.rs b/core/executor/src/wasm_utils.rs index 80ef376df5..8f38499321 100644 --- a/core/executor/src/wasm_utils.rs +++ b/core/executor/src/wasm_utils.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Rust implementation of Substrate contracts. +//! Utilities for defining the wasm host environment. use wasmi::{ValueType, RuntimeValue}; use wasmi::nan_preserving_float::{F32, F64}; diff --git a/core/state-machine/src/lib.rs b/core/state-machine/src/lib.rs index 70a7f3b146..0ffac5e688 100644 --- a/core/state-machine/src/lib.rs +++ b/core/state-machine/src/lib.rs @@ -226,10 +226,10 @@ pub trait Externalities { /// Clear an entire child storage. fn kill_child_storage(&mut self, storage_key: ChildStorageKey); - /// Clear storage entries which keys are start with the given prefix. + /// Clear storage entries which keys start with the given prefix. fn clear_prefix(&mut self, prefix: &[u8]); - /// Clear child storage entries which keys are start with the given prefix. + /// Clear child storage entries which keys start with the given prefix. fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]); /// Set or clear a storage entry (`key`) of current contract being called (effective immediately). -- GitLab From 3bc7b0baa019e48d783fd9a0fae4210c330ca173 Mon Sep 17 00:00:00 2001 From: Xiliang Chen Date: Sat, 7 Sep 2019 22:53:11 +1200 Subject: [PATCH 067/275] Fix node template build issue (#3570) * fix unused var warning * fix node-tempalte build issue --- core/authority-discovery/Cargo.toml | 2 +- node-template/src/service.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/authority-discovery/Cargo.toml b/core/authority-discovery/Cargo.toml index ac7f8ac368..cb24a43fdb 100644 --- a/core/authority-discovery/Cargo.toml +++ b/core/authority-discovery/Cargo.toml @@ -9,7 +9,7 @@ build = "build.rs" prost-build = "0.5" [dependencies] -authority-discovery-primitives = { package = "substrate-authority-discovery-primitives", path = "./primitives", default-features = false } +authority-discovery-primitives = { package = "substrate-authority-discovery-primitives", path = "./primitives" } bytes = "0.4" client = { package = "substrate-client", path = "../../core/client" } codec = { package = "parity-scale-codec", default-features = false, version = "1.0.3" } diff --git a/node-template/src/service.rs b/node-template/src/service.rs index 5b53a646d3..e3c3c670a0 100644 --- a/node-template/src/service.rs +++ b/node-template/src/service.rs @@ -6,7 +6,7 @@ use substrate_client::LongestChain; use babe::{import_queue, start_babe, Config}; use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; use futures::prelude::*; -use node_template_runtime::{self, GenesisConfig, opaque::Block, RuntimeApi, WASM_BINARY}; +use node_template_runtime::{self, GenesisConfig, opaque::Block, RuntimeApi}; use substrate_service::{error::{Error as ServiceError}, AbstractService, Configuration, ServiceBuilder}; use transaction_pool::{self, txpool::{Pool as TransactionPool}}; use inherents::InherentDataProviders; -- GitLab From 9b08e7ff938a45dbec7fcdb854063202e2b0cb48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Mon, 9 Sep 2019 06:28:35 +0100 Subject: [PATCH 068/275] grandpa: don't require justification of consensus changes on full node (#3540) * grandpa: don't request justification for consensus changes on full node * sync: finalize justification/finality proof requests in-order * sync: ignore result of try_finalize_root on justification import --- core/finality-grandpa/src/import.rs | 4 ++-- core/network/src/protocol/sync.rs | 7 +------ core/network/src/protocol/sync/extra_requests.rs | 2 +- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/core/finality-grandpa/src/import.rs b/core/finality-grandpa/src/import.rs index d51d0ffd84..d1ad57baa4 100644 --- a/core/finality-grandpa/src/import.rs +++ b/core/finality-grandpa/src/import.rs @@ -497,6 +497,8 @@ impl, RA, PRA, SC> BlockImport "Imported unjustified block #{} that enacts authority set change, waiting for finality for enactment.", number, ); + + imported_aux.needs_justification = true; } // we have imported block with consensus data changes, but without justification @@ -504,8 +506,6 @@ impl, RA, PRA, SC> BlockImport if enacts_consensus_change { self.consensus_changes.lock().note_change((number, hash)); } - - imported_aux.needs_justification = true; } } diff --git a/core/network/src/protocol/sync.rs b/core/network/src/protocol/sync.rs index 625d9a840a..5963ebf0f2 100644 --- a/core/network/src/protocol/sync.rs +++ b/core/network/src/protocol/sync.rs @@ -815,12 +815,7 @@ impl ChainSync { /// with or without errors. pub fn on_justification_import(&mut self, hash: B::Hash, number: NumberFor, success: bool) { let finalization_result = if success { Ok((hash, number)) } else { Err(()) }; - if !self.extra_justifications.try_finalize_root((hash, number), finalization_result, true) { - debug!(target: "sync", "Got justification import result for unknown justification {:?} {:?} request.", - hash, - number, - ) - } + self.extra_justifications.try_finalize_root((hash, number), finalization_result, true); self.is_idle = false; } diff --git a/core/network/src/protocol/sync/extra_requests.rs b/core/network/src/protocol/sync/extra_requests.rs index 9bc94d402c..6f9103d38d 100644 --- a/core/network/src/protocol/sync/extra_requests.rs +++ b/core/network/src/protocol/sync/extra_requests.rs @@ -138,7 +138,7 @@ impl ExtraRequests { } if best_finalized_number > self.best_seen_finalized_number { - match self.tree.finalize_with_ancestors( + match self.tree.finalize( best_finalized_hash, best_finalized_number, &is_descendent_of, -- GitLab From fb8769b6046edd04a02d3a9a6af199728af62f41 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 9 Sep 2019 16:22:58 +0300 Subject: [PATCH 069/275] finalize -> finalize_with_ancestors (#3576) --- .../src/protocol/sync/extra_requests.rs | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/core/network/src/protocol/sync/extra_requests.rs b/core/network/src/protocol/sync/extra_requests.rs index 6f9103d38d..28ed5fed9f 100644 --- a/core/network/src/protocol/sync/extra_requests.rs +++ b/core/network/src/protocol/sync/extra_requests.rs @@ -138,7 +138,10 @@ impl ExtraRequests { } if best_finalized_number > self.best_seen_finalized_number { - match self.tree.finalize( + // normally we'll receive finality notifications for every block => finalize would be enough + // but if many blocks are finalized at once, some notifications may be omitted + // => let's use finalize_with_ancestors here + match self.tree.finalize_with_ancestors( best_finalized_hash, best_finalized_number, &is_descendent_of, @@ -437,6 +440,26 @@ mod tests { assert_eq!(finality_proofs.pending_requests.iter().collect::>(), Vec::<&(Hash, u64)>::new()); } + #[test] + fn anecstor_roots_are_finalized_when_finality_notification_is_missed() { + let mut finality_proofs = ExtraRequests::::new(); + + let hash4 = [4; 32].into(); + let hash5 = [5; 32].into(); + + fn is_descendent_of(base: &Hash, target: &Hash) -> Result { + Ok(target[0] >= base[0]) + } + + // schedule request for #4 + finality_proofs.schedule((hash4, 4), is_descendent_of); + + // receive finality notification for #5 (missing notification for #4!!!) + finality_proofs.importing_requests.insert((hash4, 5)); + finality_proofs.on_block_finalized(&hash5, 5, is_descendent_of).unwrap(); + assert_eq!(finality_proofs.tree.roots().count(), 0); + } + // Some Arbitrary instances to allow easy construction of random peer sets: #[derive(Debug, Clone)] -- GitLab From 563ef3eb2675bd7d1af66cbe1e4d5f5cee366b8a Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Tue, 10 Sep 2019 10:21:46 +0200 Subject: [PATCH 070/275] Add section regarding polkadot PRs. (#3579) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add section regarding polkadot PRs. * Also add the comment in the PR template * Apply suggestions from code review Co-Authored-By: Bastian Köcher Co-Authored-By: Robert Habermeier * Rephrase Step 1, add command --- CONTRIBUTING.adoc | 15 +++++++++++++++ PULL_REQUEST_TEMPLATE.md | 1 + 2 files changed, 16 insertions(+) diff --git a/CONTRIBUTING.adoc b/CONTRIBUTING.adoc index b797e72e82..9b39b11b00 100644 --- a/CONTRIBUTING.adoc +++ b/CONTRIBUTING.adoc @@ -45,6 +45,21 @@ When reviewing a pull request, the end-goal is to suggest useful changes to the . There exists a somewhat cleaner/better/faster way of accomplishing the same feature/fix. . It does not fit well with some other contributors' longer-term vision for the project. +=== Updating Polkadot as well + +If your PR changes the external APIs or interfaces used by Polkadot, **a corresponding PR on Polkadot must** be submitted as well. If you tagged the PR with `breaksapi` or `breaksconsensus` this is most certainly the case, in all other cases check for it by running step 1. + +To update a corresponding Polkadot PR: + +0. Pull lastet Polkadot master (or clone it, if you haven't yet). +1. Replace `polkadot-master` in all `Cargo.toml` with the name of the PR-branch - e.g. by running `find . -name "Cargo.toml" -exec sed -i "s/polkadot-master/PR_BRANCH/g" {}` (and to your repo, if the branch is not on mainline); Commit this change. +2. Make the changes required to pass the build again. +3. Submit all this as a PR against the Polkadot Repo, link that new PR in the existing substrate PR for reference +4. Wait for reviews on both +5. Once both PRs have been green lit, merge the Substrate PR into master and sync the changes onto the `polkadot-master` on mainline (push it). Now revert that first commit in your Polkadot PR, reverting the name back to `polkadot-master`, push and wait for the CI to confirm all is fine. Then merge the Polkadot PR. + +As there might be multiple pending PRs that might conflict with one another, a) you should not merge the substrate PR until the Polkadot PR has also been reviewed and b) both should be merged pretty quickly after another to not block others. + == Helping out We use https://github.com/paritytech/substrate/labels[labels] to manage PRs and issues and communicate state of a PR. Please familiarize yourself with them. Furthermore we are organizing issues in https://github.com/paritytech/substrate/milestones[milestones]. Best way to get started is to a pick a ticket from the current milestone tagged https://github.com/paritytech/substrate/issues?q=is%3Aissue+is%3Aopen+label%3AQ2-easy[`easy`] or https://github.com/paritytech/substrate/issues?q=is%3Aissue+is%3Aopen+label%3AQ3-medium[`medium`] and get going or https://github.com/paritytech/substrate/issues?q=is%3Aissue+is%3Aopen+label%3AX1-mentor[`mentor`] and get in contact with the mentor offering their support on that larger task. diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 9b368f3f04..9755fa0e40 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -15,6 +15,7 @@ Before you submitting, please check that: - Any panickers have a proof or removed. - [ ] You bumped the runtime version if there are breaking changes in the **runtime**. - [ ] You updated any rustdocs which may have changed +- [ ] Has the PR altered the external API or interfaces used by Polkadot? Do you have the corresponding Polkadot PR ready? After you've read this notice feel free to remove it. Thank you! -- GitLab From 317a46d8e3c9808c2266c01671d3b6622fbaa4f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 10 Sep 2019 12:05:54 +0200 Subject: [PATCH 071/275] Augment every task spawned by Service with `on_exit` (#3581) * Augment every task spawned by Service with `on_exit` * Add CI test that the node exits --- .gitlab-ci.yml | 7 +++++++ ci/check_for_exit.sh | 16 ++++++++++++++++ core/service/src/lib.rs | 17 +++++++++++------ node/cli/src/service.rs | 16 ++++------------ 4 files changed, 38 insertions(+), 18 deletions(-) create mode 100755 ci/check_for_exit.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c25276dd10..b67d5eb648 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -216,6 +216,13 @@ check-web-wasm: - time cargo web build -p substrate-trie - sccache -s +node-exits: + stage: test + <<: *docker-env + except: + - /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 + script: + - ./ci/check_for_exit.sh #### stage: build diff --git a/ci/check_for_exit.sh b/ci/check_for_exit.sh new file mode 100755 index 0000000000..c5a54eb83b --- /dev/null +++ b/ci/check_for_exit.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +# Script that checks that a node exits after `SIGINT` was send. + +set -e + +cargo build --release +./target/release/substrate --dev & +PID=$! + +# Let the chain running for 60 seconds +sleep 60 + +# Send `SIGINT` and give the process 30 seconds to end +kill -INT $PID +timeout 30 tail --pid=$PID -f /dev/null diff --git a/core/service/src/lib.rs b/core/service/src/lib.rs index 48d5069701..a8900eedd9 100644 --- a/core/service/src/lib.rs +++ b/core/service/src/lib.rs @@ -111,13 +111,15 @@ pub type TaskExecutor = Arc + #[derive(Clone)] pub struct SpawnTaskHandle { sender: mpsc::UnboundedSender + Send>>, + on_exit: exit_future::Exit, } impl Executor + Send>> for SpawnTaskHandle { fn execute( &self, - future: Box + Send> + future: Box + Send>, ) -> Result<(), futures::future::ExecuteError + Send>>> { + let future = Box::new(future.select(self.on_exit.clone()).then(|_| Ok(()))); if let Err(err) = self.sender.unbounded_send(future) { let kind = futures::future::ExecuteErrorKind::Shutdown; Err(futures::future::ExecuteError::new(kind, err.into_inner())) @@ -350,7 +352,7 @@ macro_rules! new_impl { //light_components.clone(), system_rpc_tx.clone(), system_info.clone(), - Arc::new(SpawnTaskHandle { sender: to_spawn_tx.clone() }), + Arc::new(SpawnTaskHandle { sender: to_spawn_tx.clone(), on_exit: exit.clone() }), transaction_pool.clone(), rpc_extensions.clone(), keystore.clone(), @@ -544,22 +546,25 @@ where } fn spawn_task(&self, task: impl Future + Send + 'static) { + let task = task.select(self.on_exit()).then(|_| Ok(())); let _ = self.to_spawn_tx.unbounded_send(Box::new(task)); } fn spawn_essential_task(&self, task: impl Future + Send + 'static) { let essential_failed = self.essential_failed.clone(); - let essential_task = Box::new(task.map_err(move |_| { + let essential_task = task.map_err(move |_| { error!("Essential task failed. Shutting down service."); essential_failed.store(true, Ordering::Relaxed); - })); + }); + let task = essential_task.select(self.on_exit()).then(|_| Ok(())); - let _ = self.to_spawn_tx.unbounded_send(essential_task); + let _ = self.to_spawn_tx.unbounded_send(Box::new(task)); } fn spawn_task_handle(&self) -> SpawnTaskHandle { SpawnTaskHandle { sender: self.to_spawn_tx.clone(), + on_exit: self.on_exit(), } } @@ -589,7 +594,7 @@ where self.transaction_pool.clone() } - fn on_exit(&self) -> ::exit_future::Exit { + fn on_exit(&self) -> exit_future::Exit { self.exit.clone() } } diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index 8522ce6d12..c6ad072ef5 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -102,7 +102,6 @@ macro_rules! new_full_start { /// concrete types instead. macro_rules! new_full { ($config:expr) => {{ - use futures::Future; use futures::sync::mpsc; use network::DhtEvent; @@ -118,7 +117,7 @@ macro_rules! new_full { $config.disable_grandpa ); - let (builder, mut import_setup, inherent_data_providers, mut tasks_to_spawn) = new_full_start!($config); + let (builder, mut import_setup, inherent_data_providers, tasks_to_spawn) = new_full_start!($config); // Dht event channel from the network to the authority discovery module. Use bounded channel to ensure // back-pressure. Authority discovery is triggering one event per authority within the current authority set. @@ -138,13 +137,7 @@ macro_rules! new_full { .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); // spawn any futures that were created in the previous setup steps - for task in tasks_to_spawn.drain(..) { - service.spawn_task( - task.select(service.on_exit()) - .map(|_| ()) - .map_err(|_| ()) - ); - } + tasks_to_spawn.into_iter().for_each(|t| service.spawn_task(t)); if is_authority { let proposer = substrate_basic_authorship::ProposerFactory { @@ -170,15 +163,14 @@ macro_rules! new_full { }; let babe = babe::start_babe(babe_config)?; - let select = babe.select(service.on_exit()).then(|_| Ok(())); - service.spawn_task(Box::new(select)); + service.spawn_essential_task(babe); let authority_discovery = authority_discovery::AuthorityDiscovery::new( service.client(), service.network(), dht_event_rx, ); - service.spawn_task(Box::new(authority_discovery)); + service.spawn_task(authority_discovery); } let config = grandpa::Config { -- GitLab From 58ddde4d794e1e3181d3d43301886d43b8c69ae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 10 Sep 2019 16:07:25 +0200 Subject: [PATCH 072/275] First step for generating host externals out of the function definition in `sr-io` (#3567) * Adds new wrapper traits for wasm executor * Add new crate `substrate-wasm-interface` Thew new crate holds types and traits for the communicating between the wasm runtime and the host. * Rewrite externals with new macro etc * Fix vec initialization * Make executor tests working * Remove unused code + warnings * Introduce `Pointer` and `WordSize` for working with wasm * Fix tests and compilation * Fix compilation * Apply suggestions from code review Co-Authored-By: Sergei Pepyakin * Review feedback * Remove unused conversions * Make each host function its own struct `HostFunctions` now just returns these function structs. Each function can be executed by using one of the function structs. The inherent host functions are now moved to the "normal" host functions. * Remove byteorder * Add floating point types * Make pointer interface more safe * Add type alias for wasm-interface Result * More review comments --- Cargo.lock | 9 +- Cargo.toml | 3 +- core/executor/Cargo.toml | 2 +- core/executor/src/allocator.rs | 62 +- core/executor/src/error.rs | 9 +- core/executor/src/lib.rs | 2 + core/executor/src/sandbox.rs | 20 +- core/executor/src/wasm_executor.rs | 2410 +++++++++++----------- core/executor/src/wasm_runtimes_cache.rs | 18 +- core/executor/src/wasm_utils.rs | 264 +-- core/sr-io/src/lib.rs | 2 +- core/sr-io/with_std.rs | 4 +- core/sr-io/without_std.rs | 7 +- core/sr-std/without_std.rs | 4 +- core/test-runtime/src/lib.rs | 4 +- core/wasm-interface/Cargo.toml | 8 + core/wasm-interface/src/lib.rs | 324 +++ core/wasm-interface/src/wasmi_impl.rs | 79 + node-template/src/service.rs | 2 +- srml/system/src/offchain.rs | 4 +- 20 files changed, 1795 insertions(+), 1442 deletions(-) create mode 100644 core/wasm-interface/Cargo.toml create mode 100644 core/wasm-interface/src/lib.rs create mode 100644 core/wasm-interface/src/wasmi_impl.rs diff --git a/Cargo.lock b/Cargo.lock index 335932c595..5b09589be9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4868,7 +4868,6 @@ name = "substrate-executor" version = "2.0.0" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4887,6 +4886,7 @@ dependencies = [ "substrate-serializer 2.0.0", "substrate-state-machine 2.0.0", "substrate-trie 2.0.0", + "substrate-wasm-interface 2.0.0", "tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "wasmi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5464,6 +5464,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "substrate-wasm-builder-runner" version = "1.0.3" +[[package]] +name = "substrate-wasm-interface" +version = "2.0.0" +dependencies = [ + "wasmi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "subtle" version = "1.0.0" diff --git a/Cargo.toml b/Cargo.toml index 29f5307610..1920587440 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ vergen = "3" [workspace] members = [ + "core/authority-discovery", "core/application-crypto", "core/cli", "core/client", @@ -64,7 +65,7 @@ members = [ "core/utils/fork-tree", "core/utils/wasm-builder", "core/utils/wasm-builder-runner", - "core/authority-discovery", + "core/wasm-interface", "srml/support", "srml/support/procedural", "srml/support/procedural/tools", diff --git a/core/executor/Cargo.toml b/core/executor/Cargo.toml index a4707fb89e..a62a969d21 100644 --- a/core/executor/Cargo.toml +++ b/core/executor/Cargo.toml @@ -14,9 +14,9 @@ serializer = { package = "substrate-serializer", path = "../serializer" } state_machine = { package = "substrate-state-machine", path = "../state-machine" } runtime_version = { package = "sr-version", path = "../sr-version" } panic-handler = { package = "substrate-panic-handler", path = "../panic-handler" } +wasm-interface = { package = "substrate-wasm-interface", path = "../wasm-interface" } wasmi = "0.5.0" parity-wasm = "0.31" -byteorder = "1.3" lazy_static = "1.3" parking_lot = "0.9.0" log = "0.4" diff --git a/core/executor/src/allocator.rs b/core/executor/src/allocator.rs index 4cc8174f70..024af84768 100644 --- a/core/executor/src/allocator.rs +++ b/core/executor/src/allocator.rs @@ -19,8 +19,8 @@ use crate::error::{Error, Result}; use log::trace; -use wasmi::MemoryRef; -use wasmi::memory_units::Bytes; +use wasmi::{MemoryRef, memory_units::Bytes}; +use wasm_interface::{Pointer, WordSize}; // The pointers need to be aligned to 8 bytes. const ALIGNMENT: u32 = 8; @@ -79,7 +79,7 @@ impl FreeingBumpHeapAllocator { /// Gets requested number of bytes to allocate and returns a pointer. /// The maximum size which can be allocated at once is 16 MiB. - pub fn allocate(&mut self, size: u32) -> Result { + pub fn allocate(&mut self, size: WordSize) -> Result> { if size > MAX_POSSIBLE_ALLOCATION { return Err(Error::RequestedAllocationTooLarge); } @@ -95,7 +95,7 @@ impl FreeingBumpHeapAllocator { // Something from the free list let item = self.heads[list_index]; let four_bytes = self.get_heap_4bytes(item)?; - self.heads[list_index] = FreeingBumpHeapAllocator::le_bytes_to_u32(four_bytes); + self.heads[list_index] = Self::le_bytes_to_u32(four_bytes); item + 8 } else { // Nothing to be freed. Bump. @@ -109,12 +109,12 @@ impl FreeingBumpHeapAllocator { self.total_size = self.total_size + item_size + 8; trace!(target: "wasm-heap", "Heap size is {} bytes after allocation", self.total_size); - Ok(self.ptr_offset + ptr) + Ok(Pointer::new(self.ptr_offset + ptr)) } /// Deallocates the space which was allocated for a pointer. - pub fn deallocate(&mut self, ptr: u32) -> Result<()> { - let ptr = ptr - self.ptr_offset; + pub fn deallocate(&mut self, ptr: Pointer) -> Result<()> { + let ptr = u32::from(ptr) - self.ptr_offset; if ptr < 8 { return Err(error("Invalid pointer for deallocation")); } @@ -125,10 +125,10 @@ impl FreeingBumpHeapAllocator { self.heads[list_index] = ptr - 8; let mut slice = self.get_heap_4bytes(ptr - 8)?; - FreeingBumpHeapAllocator::write_u32_into_le_bytes(tail, &mut slice); + Self::write_u32_into_le_bytes(tail, &mut slice); self.set_heap_4bytes(ptr - 8, slice)?; - let item_size = FreeingBumpHeapAllocator::get_item_size_from_index(list_index); + let item_size = Self::get_item_size_from_index(list_index); self.total_size = self.total_size.checked_sub(item_size as u32 + 8) .ok_or_else(|| error("Unable to subtract from total heap size without overflow"))?; trace!(target: "wasm-heap", "Heap size is {} bytes after deallocation", self.total_size); @@ -147,8 +147,7 @@ impl FreeingBumpHeapAllocator { } fn write_u32_into_le_bytes(bytes: u32, slice: &mut [u8]) { - let bytes: [u8; 4] = unsafe { std::mem::transmute::(bytes.to_le()) }; - for i in 0..4 { slice[i] = bytes[i]; } + slice[..4].copy_from_slice(&bytes.to_le_bytes()); } fn get_item_size_from_index(index: usize) -> usize { @@ -175,7 +174,6 @@ impl FreeingBumpHeapAllocator { fn set_heap_4bytes(&mut self, ptr: u32, value: [u8; 4]) -> Result<()> { self.heap.set(self.ptr_offset + ptr, &value).map_err(Into::into) } - } #[cfg(test)] @@ -186,6 +184,11 @@ mod tests { const PAGE_SIZE: u32 = 65536; + /// Makes a pointer out of the given address. + fn to_pointer(address: u32) -> Pointer { + Pointer::new(address) + } + #[test] fn should_allocate_properly() { // given @@ -196,7 +199,7 @@ mod tests { let ptr = heap.allocate(1).unwrap(); // then - assert_eq!(ptr, 8); + assert_eq!(ptr, to_pointer(8)); } #[test] @@ -211,7 +214,7 @@ mod tests { // then // the pointer must start at the next multiple of 8 from 13 // + the prefix of 8 bytes. - assert_eq!(ptr, 24); + assert_eq!(ptr, to_pointer(24)); } #[test] @@ -227,14 +230,14 @@ mod tests { // then // a prefix of 8 bytes is prepended to each pointer - assert_eq!(ptr1, 8); + assert_eq!(ptr1, to_pointer(8)); // the prefix of 8 bytes + the content of ptr1 padded to the lowest possible // item size of 8 bytes + the prefix of ptr1 - assert_eq!(ptr2, 24); + assert_eq!(ptr2, to_pointer(24)); // ptr2 + its content of 16 bytes + the prefix of 8 bytes - assert_eq!(ptr3, 24 + 16 + 8); + assert_eq!(ptr3, to_pointer(24 + 16 + 8)); } #[test] @@ -244,11 +247,11 @@ mod tests { let mut heap = FreeingBumpHeapAllocator::new(mem, 0); let ptr1 = heap.allocate(1).unwrap(); // the prefix of 8 bytes is prepended to the pointer - assert_eq!(ptr1, 8); + assert_eq!(ptr1, to_pointer(8)); let ptr2 = heap.allocate(1).unwrap(); // the prefix of 8 bytes + the content of ptr 1 is prepended to the pointer - assert_eq!(ptr2, 24); + assert_eq!(ptr2, to_pointer(24)); // when heap.deallocate(ptr2).unwrap(); @@ -256,7 +259,7 @@ mod tests { // then // then the heads table should contain a pointer to the // prefix of ptr2 in the leftmost entry - assert_eq!(heap.heads[0], ptr2 - 8); + assert_eq!(heap.heads[0], u32::from(ptr2) - 8); } #[test] @@ -268,13 +271,13 @@ mod tests { let ptr1 = heap.allocate(1).unwrap(); // the prefix of 8 bytes is prepended to the pointer - assert_eq!(ptr1, padded_offset + 8); + assert_eq!(ptr1, to_pointer(padded_offset + 8)); let ptr2 = heap.allocate(9).unwrap(); // the padded_offset + the previously allocated ptr (8 bytes prefix + // 8 bytes content) + the prefix of 8 bytes which is prepended to the // current pointer - assert_eq!(ptr2, padded_offset + 16 + 8); + assert_eq!(ptr2, to_pointer(padded_offset + 16 + 8)); // when heap.deallocate(ptr2).unwrap(); @@ -282,7 +285,7 @@ mod tests { // then // should have re-allocated - assert_eq!(ptr3, padded_offset + 16 + 8); + assert_eq!(ptr3, to_pointer(padded_offset + 16 + 8)); assert_eq!(heap.heads, [0; N]); } @@ -302,15 +305,12 @@ mod tests { heap.deallocate(ptr3).unwrap(); // then - let mut expected = [0; N]; - expected[0] = ptr3 - 8; - assert_eq!(heap.heads, expected); + assert_eq!(heap.heads[0], u32::from(ptr3) - 8); let ptr4 = heap.allocate(8).unwrap(); assert_eq!(ptr4, ptr3); - expected[0] = ptr2 - 8; - assert_eq!(heap.heads, expected); + assert_eq!(heap.heads[0], u32::from(ptr2) - 8); } #[test] @@ -338,7 +338,7 @@ mod tests { let mem = MemoryInstance::alloc(Pages(1), Some(Pages(1))).unwrap(); let mut heap = FreeingBumpHeapAllocator::new(mem, 0); let ptr1 = heap.allocate((PAGE_SIZE / 2) - 8).unwrap(); - assert_eq!(ptr1, 8); + assert_eq!(ptr1, to_pointer(8)); // when let ptr2 = heap.allocate(PAGE_SIZE / 2); @@ -365,7 +365,7 @@ mod tests { let ptr = heap.allocate(MAX_POSSIBLE_ALLOCATION).unwrap(); // then - assert_eq!(ptr, 8); + assert_eq!(ptr, to_pointer(8)); } #[test] @@ -409,7 +409,7 @@ mod tests { // when let ptr = heap.allocate(42).unwrap(); - assert_eq!(ptr, 16 + 8); + assert_eq!(ptr, to_pointer(16 + 8)); heap.deallocate(ptr).unwrap(); // then diff --git a/core/executor/src/error.rs b/core/executor/src/error.rs index 9bfa05ff5f..967d074ec9 100644 --- a/core/executor/src/error.rs +++ b/core/executor/src/error.rs @@ -66,7 +66,7 @@ pub enum Error { #[display(fmt="The runtime has the `start` function")] RuntimeHasStartFn, /// Some other error occurred - Other(&'static str), + Other(String), /// Some error occurred in the allocator #[display(fmt="Error in allocator: {}", _0)] Allocator(&'static str), @@ -76,6 +76,9 @@ pub enum Error { /// Someone tried to allocate more memory than the allowed maximum per allocation. #[display(fmt="Requested allocation size is too large")] RequestedAllocationTooLarge, + /// Executing the given function failed with the given error. + #[display(fmt="Function execution failed with: {}", _0)] + FunctionExecution(String), } impl std::error::Error for Error { @@ -93,8 +96,8 @@ impl state_machine::Error for Error {} impl wasmi::HostError for Error {} -impl From<&'static str> for Error { - fn from(err: &'static str) -> Error { +impl From for Error { + fn from(err: String) -> Error { Error::Other(err) } } diff --git a/core/executor/src/lib.rs b/core/executor/src/lib.rs index 684200519e..d4bed6964e 100644 --- a/core/executor/src/lib.rs +++ b/core/executor/src/lib.rs @@ -48,6 +48,8 @@ pub use runtime_version::{RuntimeVersion, NativeVersion}; pub use codec::Codec; #[doc(hidden)] pub use primitives::Blake2Hasher; +#[doc(hidden)] +pub use wasm_interface; /// Provides runtime information. pub trait RuntimeInfo { diff --git a/core/executor/src/sandbox.rs b/core/executor/src/sandbox.rs index 6687738abc..2c38499ec8 100644 --- a/core/executor/src/sandbox.rs +++ b/core/executor/src/sandbox.rs @@ -26,6 +26,7 @@ use wasmi::{ Externals, FuncRef, ImportResolver, MemoryInstance, MemoryRef, Module, ModuleInstance, ModuleRef, RuntimeArgs, RuntimeValue, Trap, TrapKind, memory_units::Pages, }; +use wasm_interface::{Pointer, WordSize}; /// Index of a function inside the supervisor. /// @@ -150,7 +151,7 @@ pub trait SandboxCapabilities { /// Returns `Err` if allocation not possible or errors during heap management. /// /// Returns pointer to the allocated block. - fn allocate(&mut self, len: u32) -> Result; + fn allocate(&mut self, len: WordSize) -> Result>; /// Deallocate space specified by the pointer that was previously returned by [`allocate`]. /// @@ -159,21 +160,21 @@ pub trait SandboxCapabilities { /// Returns `Err` if deallocation not possible or because of errors in heap management. /// /// [`allocate`]: #tymethod.allocate - fn deallocate(&mut self, ptr: u32) -> Result<()>; + fn deallocate(&mut self, ptr: Pointer) -> Result<()>; /// Write `data` into the supervisor memory at offset specified by `ptr`. /// /// # Errors /// /// Returns `Err` if `ptr + data.len()` is out of bounds. - fn write_memory(&mut self, ptr: u32, data: &[u8]) -> Result<()>; + fn write_memory(&mut self, ptr: Pointer, data: &[u8]) -> Result<()>; /// Read `len` bytes from the supervisor memory. /// /// # Errors /// /// Returns `Err` if `ptr + len` is out of bounds. - fn read_memory(&self, ptr: u32, len: u32) -> Result>; + fn read_memory(&self, ptr: Pointer, len: WordSize) -> Result>; } /// Implementation of [`Externals`] that allows execution of guest module with @@ -187,7 +188,7 @@ pub struct GuestExternals<'a, FE: SandboxCapabilities + Externals + 'a> { } fn trap(msg: &'static str) -> Trap { - TrapKind::Host(Box::new(Error::Other(msg))).into() + TrapKind::Host(Box::new(Error::Other(msg.into()))).into() } fn deserialize_result(serialized_result: &[u8]) -> std::result::Result, Trap> { @@ -243,7 +244,7 @@ impl<'a, FE: SandboxCapabilities + Externals + 'a> Externals for GuestExternals< let result = ::wasmi::FuncInstance::invoke( &dispatch_thunk, &[ - RuntimeValue::I32(invoke_args_ptr as i32), + RuntimeValue::I32(u32::from(invoke_args_ptr) as i32), RuntimeValue::I32(invoke_args_data.len() as i32), RuntimeValue::I32(state as i32), RuntimeValue::I32(func_idx.0 as i32), @@ -260,7 +261,7 @@ impl<'a, FE: SandboxCapabilities + Externals + 'a> Externals for GuestExternals< let v = v as u64; let ptr = (v as u64 >> 32) as u32; let len = (v & 0xFFFFFFFF) as u32; - (ptr, len) + (Pointer::new(ptr), len) } Ok(_) => return Err(trap("Supervisor function returned unexpected result!")), Err(_) => return Err(trap("Supervisor function trapped!")), @@ -643,7 +644,10 @@ mod tests { if let Err(err) = res { assert_eq!( format!("{}", err), - format!("{}", wasmi::Error::Trap(Error::AllocatorOutOfSpace.into())) + format!( + "{}", + wasmi::Error::Trap(Error::FunctionExecution("AllocatorOutOfSpace".into()).into()), + ), ); } } diff --git a/core/executor/src/wasm_executor.rs b/core/executor/src/wasm_executor.rs index d8fd41ab7f..25f1f969b8 100644 --- a/core/executor/src/wasm_executor.rs +++ b/core/executor/src/wasm_executor.rs @@ -19,7 +19,7 @@ //! This module defines and implements the wasm part of Substrate Host Interface and provides //! an interface for calling into the wasm runtime. -use std::{collections::HashMap, convert::TryFrom, str}; +use std::{convert::TryFrom, str}; use tiny_keccak; use secp256k1; @@ -27,92 +27,238 @@ use wasmi::{ Module, ModuleInstance, MemoryInstance, MemoryRef, TableRef, ImportsBuilder, ModuleRef, memory_units::Pages, RuntimeValue::{I32, I64, self}, }; -use state_machine::{Externalities, ChildStorageKey}; +use state_machine::Externalities; use crate::error::{Error, Result}; -use codec::Encode; +use codec::{Encode, Decode}; use primitives::{ blake2_128, blake2_256, twox_64, twox_128, twox_256, ed25519, sr25519, Pair, crypto::KeyTypeId, - offchain, hexdisplay::HexDisplay, sandbox as sandbox_primitives, H256, Blake2Hasher, + offchain, hexdisplay::HexDisplay, sandbox as sandbox_primitives, Blake2Hasher, }; use trie::{TrieConfiguration, trie_types::Layout}; use crate::sandbox; use crate::allocator; use log::trace; +use wasm_interface::{ + FunctionContext, HostFunctions, Pointer, WordSize, Sandbox, MemoryId, PointerType, + Result as WResult, +}; #[cfg(feature="wasm-extern-trace")] macro_rules! debug_trace { ( $( $x:tt )* ) => ( trace!( $( $x )* ) ) } + #[cfg(not(feature="wasm-extern-trace"))] macro_rules! debug_trace { ( $( $x:tt )* ) => () } -struct FunctionExecutor<'e, E: Externalities + 'e> { +struct FunctionExecutor { sandbox_store: sandbox::Store, heap: allocator::FreeingBumpHeapAllocator, memory: MemoryRef, table: Option, - ext: &'e mut E, - hash_lookup: HashMap, Vec>, } -impl<'e, E: Externalities> FunctionExecutor<'e, E> { - fn new(m: MemoryRef, heap_base: u32, t: Option, e: &'e mut E) -> Result { +impl FunctionExecutor { + fn new(m: MemoryRef, heap_base: u32, t: Option) -> Result { Ok(FunctionExecutor { sandbox_store: sandbox::Store::new(), heap: allocator::FreeingBumpHeapAllocator::new(m.clone(), heap_base), memory: m, table: t, - ext: e, - hash_lookup: HashMap::new(), }) } } -impl<'e, E: Externalities> sandbox::SandboxCapabilities for FunctionExecutor<'e, E> { +impl sandbox::SandboxCapabilities for FunctionExecutor { fn store(&self) -> &sandbox::Store { &self.sandbox_store } fn store_mut(&mut self) -> &mut sandbox::Store { &mut self.sandbox_store } - fn allocate(&mut self, len: u32) -> Result { + fn allocate(&mut self, len: WordSize) -> Result> { self.heap.allocate(len) } - fn deallocate(&mut self, ptr: u32) -> Result<()> { + fn deallocate(&mut self, ptr: Pointer) -> Result<()> { self.heap.deallocate(ptr) } - fn write_memory(&mut self, ptr: u32, data: &[u8]) -> Result<()> { - self.memory.set(ptr, data).map_err(Into::into) + fn write_memory(&mut self, ptr: Pointer, data: &[u8]) -> Result<()> { + self.memory.set(ptr.into(), data).map_err(Into::into) } - fn read_memory(&self, ptr: u32, len: u32) -> Result> { - self.memory.get(ptr, len as usize).map_err(Into::into) + fn read_memory(&self, ptr: Pointer, len: WordSize) -> Result> { + self.memory.get(ptr.into(), len as usize).map_err(Into::into) } } -trait WritePrimitive { - fn write_primitive(&self, offset: u32, t: T) -> Result<()>; +impl FunctionContext for FunctionExecutor { + fn read_memory_into(&self, address: Pointer, dest: &mut [u8]) -> WResult<()> { + self.memory.get_into(address.into(), dest).map_err(|e| format!("{:?}", e)) + } + + fn write_memory(&mut self, address: Pointer, data: &[u8]) -> WResult<()> { + self.memory.set(address.into(), data).map_err(|e| format!("{:?}", e)) + } + + fn allocate_memory(&mut self, size: WordSize) -> WResult> { + self.heap.allocate(size).map_err(|e| format!("{:?}", e)) + } + + fn deallocate_memory(&mut self, ptr: Pointer) -> WResult<()> { + self.heap.deallocate(ptr).map_err(|e| format!("{:?}", e)) + } + + fn sandbox(&mut self) -> &mut dyn Sandbox { + self + } } -impl WritePrimitive for MemoryInstance { - fn write_primitive(&self, offset: u32, t: u32) -> Result<()> { - use byteorder::{LittleEndian, ByteOrder}; - let mut r = [0u8; 4]; - LittleEndian::write_u32(&mut r, t); - self.set(offset, &r).map_err(Into::into) +impl Sandbox for FunctionExecutor { + fn memory_get( + &self, + memory_id: MemoryId, + offset: WordSize, + buf_ptr: Pointer, + buf_len: WordSize, + ) -> WResult { + let sandboxed_memory = self.sandbox_store.memory(memory_id).map_err(|e| format!("{:?}", e))?; + + match MemoryInstance::transfer( + &sandboxed_memory, + offset as usize, + &self.memory, + buf_ptr.into(), + buf_len as usize, + ) { + Ok(()) => Ok(sandbox_primitives::ERR_OK), + Err(_) => Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS), + } + } + + fn memory_set( + &mut self, + memory_id: MemoryId, + offset: WordSize, + val_ptr: Pointer, + val_len: WordSize, + ) -> WResult { + let sandboxed_memory = self.sandbox_store.memory(memory_id).map_err(|e| format!("{:?}", e))?; + + match MemoryInstance::transfer( + &self.memory, + val_ptr.into(), + &sandboxed_memory, + offset as usize, + val_len as usize, + ) { + Ok(()) => Ok(sandbox_primitives::ERR_OK), + Err(_) => Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS), + } + } + + fn memory_teardown(&mut self, memory_id: MemoryId) -> WResult<()> { + self.sandbox_store.memory_teardown(memory_id).map_err(|e| format!("{:?}", e)) + } + + fn memory_new( + &mut self, + initial: u32, + maximum: u32, + ) -> WResult { + self.sandbox_store.new_memory(initial, maximum).map_err(|e| format!("{:?}", e)) + } + + fn invoke( + &mut self, + instance_id: u32, + export_name: &str, + args: &[u8], + return_val: Pointer, + return_val_len: WordSize, + state: u32, + ) -> WResult { + trace!(target: "sr-sandbox", "invoke, instance_idx={}", instance_id); + + // Deserialize arguments and convert them into wasmi types. + let args = Vec::::decode(&mut &args[..]) + .map_err(|_| "Can't decode serialized arguments for the invocation")? + .into_iter() + .map(Into::into) + .collect::>(); + + let instance = self.sandbox_store.instance(instance_id).map_err(|e| format!("{:?}", e))?; + let result = instance.invoke(export_name, &args, self, state); + + match result { + Ok(None) => Ok(sandbox_primitives::ERR_OK), + Ok(Some(val)) => { + // Serialize return value and write it back into the memory. + sandbox_primitives::ReturnValue::Value(val.into()).using_encoded(|val| { + if val.len() > return_val_len as usize { + Err("Return value buffer is too small")?; + } + self.write_memory(return_val, val).map_err(|_| "Return value buffer is OOB")?; + Ok(sandbox_primitives::ERR_OK) + }) + } + Err(_) => Ok(sandbox_primitives::ERR_EXECUTION), + } + } + + fn instance_teardown(&mut self, instance_id: u32) -> WResult<()> { + self.sandbox_store.instance_teardown(instance_id).map_err(|e| format!("{:?}", e)) + } + + fn instance_new( + &mut self, + dispatch_thunk_id: u32, + wasm: &[u8], + raw_env_def: &[u8], + state: u32, + ) -> WResult { + // Extract a dispatch thunk from instance's table by the specified index. + let dispatch_thunk = { + let table = self.table.as_ref() + .ok_or_else(|| "Runtime doesn't have a table; sandbox is unavailable")?; + table.get(dispatch_thunk_id) + .map_err(|_| "dispatch_thunk_idx is out of the table bounds")? + .ok_or_else(|| "dispatch_thunk_idx points on an empty table entry")? + .clone() + }; + + let instance_idx_or_err_code = + match sandbox::instantiate(self, dispatch_thunk, wasm, raw_env_def, state) { + Ok(instance_idx) => instance_idx, + Err(sandbox::InstantiationError::StartTrapped) => + sandbox_primitives::ERR_EXECUTION, + Err(_) => sandbox_primitives::ERR_MODULE, + }; + + Ok(instance_idx_or_err_code as u32) + } +} + +trait WritePrimitive { + fn write_primitive(&mut self, ptr: Pointer, t: T) -> WResult<()>; +} + +impl WritePrimitive for &mut dyn FunctionContext { + fn write_primitive(&mut self, ptr: Pointer, t: u32) -> WResult<()> { + let r = t.to_le_bytes(); + self.write_memory(ptr.cast(), &r) } } -trait ReadPrimitive { - fn read_primitive(&self, offset: u32) -> Result; +trait ReadPrimitive { + fn read_primitive(&self, offset: Pointer) -> WResult; } -impl ReadPrimitive for MemoryInstance { - fn read_primitive(&self, offset: u32) -> Result { - use byteorder::{LittleEndian, ByteOrder}; - let result = self.get(offset, 4)?; - Ok(LittleEndian::read_u32(&result)) +impl ReadPrimitive for &mut dyn FunctionContext { + fn read_primitive(&self, ptr: Pointer) -> WResult { + let mut r = [0u8; 4]; + self.read_memory_into(ptr.cast(), &mut r)?; + Ok(u32::from_le_bytes(r)) } } @@ -124,1201 +270,1066 @@ fn deadline_to_timestamp(deadline: u64) -> Option { } } -impl_function_executor!(this: FunctionExecutor<'e, E>, - ext_print_utf8(utf8_data: *const u8, utf8_len: u32) => { - if let Ok(utf8) = this.memory.get(utf8_data, utf8_len as usize) { - if let Ok(message) = String::from_utf8(utf8) { - println!("{}", message); +impl FunctionExecutor { + fn resolver() -> &'static dyn wasmi::ModuleImportResolver { + struct Resolver; + impl wasmi::ModuleImportResolver for Resolver { + fn resolve_func(&self, name: &str, signature: &wasmi::Signature) + -> std::result::Result + { + let signature = wasm_interface::Signature::from(signature); + + if let Some((index, func)) = SubstrateExternals::functions().iter() + .enumerate() + .find(|f| name == f.1.name()) + { + if signature == func.signature() { + Ok(wasmi::FuncInstance::alloc_host(signature.into(), index)) + } else { + Err(wasmi::Error::Instantiation( + format!( + "Invalid signature for function `{}` expected `{:?}`, got `{:?}`", + func.name(), + signature, + func.signature(), + ) + )) + } + } else { + Err(wasmi::Error::Instantiation( + format!("Export {} not found", name), + )) + } } } - Ok(()) - }, - ext_print_hex(data: *const u8, len: u32) => { - if let Ok(hex) = this.memory.get(data, len as usize) { - println!("{}", HexDisplay::from(&hex)); - } - Ok(()) - }, - ext_print_num(number: u64) => { - println!("{}", number); - Ok(()) - }, - ext_malloc(size: usize) -> *mut u8 => { - let r = this.heap.allocate(size)?; - debug_trace!(target: "sr-io", "malloc {} bytes at {}", size, r); - Ok(r) - }, - ext_free(addr: *mut u8) => { - this.heap.deallocate(addr)?; - debug_trace!(target: "sr-io", "free {}", addr); - Ok(()) - }, - ext_set_storage(key_data: *const u8, key_len: u32, value_data: *const u8, value_len: u32) => { - let key = this.memory.get(key_data, key_len as usize) - .map_err(|_| "Invalid attempt to determine key in ext_set_storage")?; - let value = this.memory.get(value_data, value_len as usize) - .map_err(|_| "Invalid attempt to determine value in ext_set_storage")?; - if let Some(_preimage) = this.hash_lookup.get(&key) { - debug_trace!( - target: "wasm-trace", - "*** Setting storage: %{} -> {} [k={}]", - primitives::hexdisplay::ascii_format(&_preimage), - HexDisplay::from(&value), - HexDisplay::from(&key), - ); - } else { - debug_trace!( - target: "wasm-trace", - "*** Setting storage: {} -> {} [k={}]", - primitives::hexdisplay::ascii_format(&key), - HexDisplay::from(&value), - HexDisplay::from(&key), - ); + &Resolver + } +} + +impl wasmi::Externals for FunctionExecutor { + fn invoke_index(&mut self, index: usize, args: wasmi::RuntimeArgs) + -> std::result::Result, wasmi::Trap> + { + let mut args = args.as_ref().iter().copied().map(Into::into); + let function = SubstrateExternals::functions().get(index).ok_or_else(|| + Error::from( + format!("Could not find host function with index: {}", index), + ) + )?; + + function.execute(self, &mut args) + .map_err(Error::FunctionExecution) + .map_err(wasmi::Trap::from) + .map(|v| v.map(Into::into)) + } +} +struct SubstrateExternals; + +impl_wasm_host_interface! { + impl SubstrateExternals where context { + ext_malloc(size: WordSize) -> Pointer { + let r = context.allocate_memory(size)?; + debug_trace!(target: "sr-io", "malloc {} bytes at {}", size, r); + Ok(r) } - this.ext.set_storage(key, value); - Ok(()) - }, - ext_set_child_storage( - storage_key_data: *const u8, - storage_key_len: u32, - key_data: *const u8, - key_len: u32, - value_data: *const u8, - value_len: u32 - ) => { - let storage_key = this.memory.get(storage_key_data, storage_key_len as usize) - .map_err(|_| "Invalid attempt to determine storage_key in ext_set_child_storage")?; - let key = this.memory.get(key_data, key_len as usize) - .map_err(|_| "Invalid attempt to determine key in ext_set_child_storage")?; - let value = this.memory.get(value_data, value_len as usize) - .map_err(|_| "Invalid attempt to determine value in ext_set_child_storage")?; - if let Some(_preimage) = this.hash_lookup.get(&key) { - debug_trace!( - target: "wasm-trace", "*** Setting child storage: {} -> %{} -> {} [k={}]", - primitives::hexdisplay::ascii_format(&storage_key), - primitives::hexdisplay::ascii_format(&_preimage), - HexDisplay::from(&value), - HexDisplay::from(&key) - ); - } else { - debug_trace!( - target: "wasm-trace", "*** Setting child storage: {} -> {} -> {} [k={}]", - primitives::hexdisplay::ascii_format(&storage_key), - primitives::hexdisplay::ascii_format(&key), - HexDisplay::from(&value), - HexDisplay::from(&key) - ); + + ext_free(addr: Pointer) { + context.deallocate_memory(addr)?; + debug_trace!(target: "sr-io", "free {}", addr); + Ok(()) + } + + ext_sandbox_instantiate( + dispatch_thunk_idx: u32, + wasm_ptr: Pointer, + wasm_len: WordSize, + imports_ptr: Pointer, + imports_len: WordSize, + state: u32, + ) -> u32 { + let wasm = context.read_memory(wasm_ptr, wasm_len) + .map_err(|_| "OOB while ext_sandbox_instantiate: wasm")?; + let raw_env_def = context.read_memory(imports_ptr, imports_len) + .map_err(|_| "OOB while ext_sandbox_instantiate: imports")?; + + context.sandbox().instance_new(dispatch_thunk_idx, &wasm, &raw_env_def, state) + } + + ext_sandbox_instance_teardown(instance_idx: u32) { + context.sandbox().instance_teardown(instance_idx) + } + + ext_sandbox_invoke( + instance_idx: u32, + export_ptr: Pointer, + export_len: WordSize, + args_ptr: Pointer, + args_len: WordSize, + return_val_ptr: Pointer, + return_val_len: WordSize, + state: u32, + ) -> u32 { + let export = context.read_memory(export_ptr, export_len) + .map_err(|_| "OOB while ext_sandbox_invoke: export") + .and_then(|b| + String::from_utf8(b) + .map_err(|_| "Export name should be a valid utf-8 sequence") + )?; + + // Deserialize arguments and convert them into wasmi types. + let serialized_args = context.read_memory(args_ptr, args_len) + .map_err(|_| "OOB while ext_sandbox_invoke: args")?; + + context.sandbox().invoke( + instance_idx, + &export, + &serialized_args, + return_val_ptr, + return_val_len, + state, + ) + } + + ext_sandbox_memory_new(initial: WordSize, maximum: WordSize) -> u32 { + context.sandbox().memory_new(initial, maximum) + } + + ext_sandbox_memory_get( + memory_idx: u32, + offset: WordSize, + buf_ptr: Pointer, + buf_len: WordSize, + ) -> u32 { + context.sandbox().memory_get(memory_idx, offset, buf_ptr, buf_len) + } + + ext_sandbox_memory_set( + memory_idx: u32, + offset: WordSize, + val_ptr: Pointer, + val_len: WordSize, + ) -> u32 { + context.sandbox().memory_set(memory_idx, offset, val_ptr, val_len) + } + + ext_sandbox_memory_teardown(memory_idx: u32) { + context.sandbox().memory_teardown(memory_idx) + } + + ext_print_utf8(utf8_data: Pointer, utf8_len: WordSize) { + if let Ok(utf8) = context.read_memory(utf8_data, utf8_len) { + if let Ok(message) = String::from_utf8(utf8) { + println!("{}", message); + } + } + Ok(()) + } + + ext_print_hex(data: Pointer, len: WordSize) { + if let Ok(hex) = context.read_memory(data, len) { + println!("{}", HexDisplay::from(&hex)); + } + Ok(()) + } + + ext_print_num(number: u64) { + println!("{}", number); + Ok(()) + } + + ext_set_storage( + key_data: Pointer, + key_len: WordSize, + value_data: Pointer, + value_len: WordSize, + ) { + let key = context.read_memory(key_data, key_len) + .map_err(|_| "Invalid attempt to determine key in ext_set_storage")?; + let value = context.read_memory(value_data, value_len) + .map_err(|_| "Invalid attempt to determine value in ext_set_storage")?; + runtime_io::set_storage(&key, &value); + Ok(()) + } + + ext_set_child_storage( + storage_key_data: Pointer, + storage_key_len: WordSize, + key_data: Pointer, + key_len: WordSize, + value_data: Pointer, + value_len: WordSize, + ) { + let storage_key = context.read_memory(storage_key_data, storage_key_len) + .map_err(|_| "Invalid attempt to determine storage_key in ext_set_child_storage")?; + let key = context.read_memory(key_data, key_len) + .map_err(|_| "Invalid attempt to determine key in ext_set_child_storage")?; + let value = context.read_memory(value_data, value_len) + .map_err(|_| "Invalid attempt to determine value in ext_set_child_storage")?; + + runtime_io::set_child_storage(&storage_key, &key, &value); + Ok(()) + } + + ext_clear_child_storage( + storage_key_data: Pointer, + storage_key_len: WordSize, + key_data: Pointer, + key_len: WordSize, + ) { + let storage_key = context.read_memory(storage_key_data, storage_key_len) + .map_err(|_| "Invalid attempt to determine storage_key in ext_clear_child_storage")?; + let key = context.read_memory(key_data, key_len) + .map_err(|_| "Invalid attempt to determine key in ext_clear_child_storage")?; + + runtime_io::clear_child_storage(&storage_key, &key); + Ok(()) + } + + ext_clear_storage(key_data: Pointer, key_len: WordSize) { + let key = context.read_memory(key_data, key_len) + .map_err(|_| "Invalid attempt to determine key in ext_clear_storage")?; + runtime_io::clear_storage(&key); + Ok(()) + } + + ext_exists_storage(key_data: Pointer, key_len: WordSize) -> u32 { + let key = context.read_memory(key_data, key_len) + .map_err(|_| "Invalid attempt to determine key in ext_exists_storage")?; + Ok(if runtime_io::exists_storage(&key) { 1 } else { 0 }) + } + + ext_exists_child_storage( + storage_key_data: Pointer, + storage_key_len: WordSize, + key_data: Pointer, + key_len: WordSize, + ) -> u32 { + let storage_key = context.read_memory(storage_key_data, storage_key_len) + .map_err(|_| "Invalid attempt to determine storage_key in ext_exists_child_storage")?; + let key = context.read_memory(key_data, key_len) + .map_err(|_| "Invalid attempt to determine key in ext_exists_child_storage")?; + + Ok(if runtime_io::exists_child_storage(&storage_key, &key) { 1 } else { 0 }) } - let storage_key = ChildStorageKey::from_vec(storage_key) - .ok_or_else(|| "ext_set_child_storage: child storage key is invalid")?; - this.ext.set_child_storage(storage_key, key, value); - Ok(()) - }, - ext_clear_child_storage( - storage_key_data: *const u8, - storage_key_len: u32, - key_data: *const u8, - key_len: u32 - ) => { - let storage_key = this.memory.get( - storage_key_data, - storage_key_len as usize - ).map_err(|_| "Invalid attempt to determine storage_key in ext_clear_child_storage")?; - let key = this.memory.get(key_data, key_len as usize) - .map_err(|_| "Invalid attempt to determine key in ext_clear_child_storage")?; - debug_trace!( - target: "wasm-trace", "*** Clearing child storage: {} -> {} [k={}]", - primitives::hexdisplay::ascii_format(&storage_key), - if let Some(_preimage) = this.hash_lookup.get(&key) { - format!("%{}", primitives::hexdisplay::ascii_format(&_preimage)) + + ext_clear_prefix(prefix_data: Pointer, prefix_len: WordSize) { + let prefix = context.read_memory(prefix_data, prefix_len) + .map_err(|_| "Invalid attempt to determine prefix in ext_clear_prefix")?; + runtime_io::clear_prefix(&prefix); + Ok(()) + } + + ext_clear_child_prefix( + storage_key_data: Pointer, + storage_key_len: WordSize, + prefix_data: Pointer, + prefix_len: WordSize, + ) { + let storage_key = context.read_memory(storage_key_data, storage_key_len) + .map_err(|_| "Invalid attempt to determine storage_key in ext_clear_child_prefix")?; + let prefix = context.read_memory(prefix_data, prefix_len) + .map_err(|_| "Invalid attempt to determine prefix in ext_clear_child_prefix")?; + runtime_io::clear_child_prefix(&storage_key, &prefix); + + Ok(()) + } + + ext_kill_child_storage(storage_key_data: Pointer, storage_key_len: WordSize) { + let storage_key = context.read_memory(storage_key_data, storage_key_len) + .map_err(|_| "Invalid attempt to determine storage_key in ext_kill_child_storage")?; + runtime_io::kill_child_storage(&storage_key); + + Ok(()) + } + + ext_get_allocated_storage( + key_data: Pointer, + key_len: WordSize, + written_out: Pointer, + ) -> Pointer { + let key = context.read_memory(key_data, key_len) + .map_err(|_| "Invalid attempt to determine key in ext_get_allocated_storage")?; + let maybe_value = runtime_io::storage(&key); + + if let Some(value) = maybe_value { + let offset = context.allocate_memory(value.len() as u32)?; + context.write_memory(offset, &value) + .map_err(|_| "Invalid attempt to set memory in ext_get_allocated_storage")?; + context.write_primitive(written_out, value.len() as u32) + .map_err(|_| "Invalid attempt to write written_out in ext_get_allocated_storage")?; + Ok(offset) } else { - format!(" {}", primitives::hexdisplay::ascii_format(&key)) - }, - HexDisplay::from(&key) - ); - let storage_key = ChildStorageKey::from_vec(storage_key) - .ok_or_else(|| "ext_clear_child_storage: child storage key is not valid")?; - - this.ext.clear_child_storage(storage_key, &key); - Ok(()) - }, - ext_clear_storage(key_data: *const u8, key_len: u32) => { - let key = this.memory.get(key_data, key_len as usize) - .map_err(|_| "Invalid attempt to determine key in ext_clear_storage")?; - debug_trace!( - target: "wasm-trace", "*** Clearing storage: {} [k={}]", - if let Some(_preimage) = this.hash_lookup.get(&key) { - format!("%{}", ::primitives::hexdisplay::ascii_format(&_preimage)) + context.write_primitive(written_out, u32::max_value()) + .map_err(|_| "Invalid attempt to write failed written_out in ext_get_allocated_storage")?; + Ok(Pointer::null()) + } + } + + ext_get_allocated_child_storage( + storage_key_data: Pointer, + storage_key_len: WordSize, + key_data: Pointer, + key_len: WordSize, + written_out: Pointer, + ) -> Pointer { + let storage_key = context.read_memory(storage_key_data, storage_key_len) + .map_err(|_| "Invalid attempt to determine storage_key in ext_get_allocated_child_storage")?; + let key = context.read_memory(key_data, key_len) + .map_err(|_| "Invalid attempt to determine key in ext_get_allocated_child_storage")?; + + let maybe_value = runtime_io::child_storage(&storage_key, &key); + + if let Some(value) = maybe_value { + let offset = context.allocate_memory(value.len() as u32)?; + context.write_memory(offset, &value) + .map_err(|_| "Invalid attempt to set memory in ext_get_allocated_child_storage")?; + context.write_primitive(written_out, value.len() as u32) + .map_err(|_| "Invalid attempt to write written_out in ext_get_allocated_child_storage")?; + Ok(offset) } else { - format!(" {}", ::primitives::hexdisplay::ascii_format(&key)) - }, - HexDisplay::from(&key) - ); - this.ext.clear_storage(&key); - Ok(()) - }, - ext_exists_storage(key_data: *const u8, key_len: u32) -> u32 => { - let key = this.memory.get(key_data, key_len as usize) - .map_err(|_| "Invalid attempt to determine key in ext_exists_storage")?; - Ok(if this.ext.exists_storage(&key) { 1 } else { 0 }) - }, - ext_exists_child_storage( - storage_key_data: *const u8, - storage_key_len: u32, - key_data: *const u8, - key_len: u32 - ) -> u32 => { - let storage_key = this.memory.get( - storage_key_data, - storage_key_len as usize - ).map_err(|_| "Invalid attempt to determine storage_key in ext_exists_child_storage")?; - let key = this.memory.get(key_data, key_len as usize) - .map_err(|_| "Invalid attempt to determine key in ext_exists_child_storage")?; - let storage_key = ChildStorageKey::from_vec(storage_key) - .ok_or_else(|| "ext_exists_child_storage: child storage key is not valid")?; - Ok(if this.ext.exists_child_storage(storage_key, &key) { 1 } else { 0 }) - }, - ext_clear_prefix(prefix_data: *const u8, prefix_len: u32) => { - let prefix = this.memory.get(prefix_data, prefix_len as usize) - .map_err(|_| "Invalid attempt to determine prefix in ext_clear_prefix")?; - this.ext.clear_prefix(&prefix); - Ok(()) - }, - ext_clear_child_prefix( - storage_key_data: *const u8, - storage_key_len: u32, - prefix_data: *const u8, - prefix_len: u32 - ) => { - let storage_key = this.memory.get( - storage_key_data, - storage_key_len as usize - ).map_err(|_| "Invalid attempt to determine storage_key in ext_clear_child_prefix")?; - let storage_key = ChildStorageKey::from_vec(storage_key) - .ok_or_else(|| "ext_clear_child_prefix: child storage key is not valid")?; - let prefix = this.memory.get(prefix_data, prefix_len as usize) - .map_err(|_| "Invalid attempt to determine prefix in ext_clear_child_prefix")?; - this.ext.clear_child_prefix(storage_key, &prefix); - Ok(()) - }, - ext_kill_child_storage(storage_key_data: *const u8, storage_key_len: u32) => { - let storage_key = this.memory.get( - storage_key_data, - storage_key_len as usize - ).map_err(|_| "Invalid attempt to determine storage_key in ext_kill_child_storage")?; - let storage_key = ChildStorageKey::from_vec(storage_key) - .ok_or_else(|| "ext_exists_child_storage: child storage key is not valid")?; - this.ext.kill_child_storage(storage_key); - Ok(()) - }, - // return 0 and place u32::max_value() into written_out if no value exists for the key. - ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8 => { - let key = this.memory.get( - key_data, - key_len as usize - ).map_err(|_| "Invalid attempt to determine key in ext_get_allocated_storage")?; - let maybe_value = this.ext.storage(&key); - - debug_trace!( - target: "wasm-trace", "*** Getting storage: {} == {} [k={}]", - if let Some(_preimage) = this.hash_lookup.get(&key) { - format!("%{}", ::primitives::hexdisplay::ascii_format(&_preimage)) + context.write_primitive(written_out, u32::max_value()) + .map_err(|_| "Invalid attempt to write failed written_out in ext_get_allocated_child_storage")?; + Ok(Pointer::null()) + } + } + + ext_get_storage_into( + key_data: Pointer, + key_len: WordSize, + value_data: Pointer, + value_len: WordSize, + value_offset: WordSize, + ) -> WordSize { + let key = context.read_memory(key_data, key_len) + .map_err(|_| "Invalid attempt to get key in ext_get_storage_into")?; + let maybe_value = runtime_io::storage(&key); + + if let Some(value) = maybe_value { + let value = &value[value_offset as usize..]; + let written = std::cmp::min(value_len as usize, value.len()); + context.write_memory(value_data, &value[..written]) + .map_err(|_| "Invalid attempt to set value in ext_get_storage_into")?; + Ok(value.len() as u32) } else { - format!(" {}", ::primitives::hexdisplay::ascii_format(&key)) - }, - if let Some(ref b) = maybe_value { - &format!("{}", HexDisplay::from(b)) + Ok(u32::max_value()) + } + } + + ext_get_child_storage_into( + storage_key_data: Pointer, + storage_key_len: WordSize, + key_data: Pointer, + key_len: WordSize, + value_data: Pointer, + value_len: WordSize, + value_offset: WordSize, + ) -> WordSize { + let storage_key = context.read_memory(storage_key_data, storage_key_len) + .map_err(|_| "Invalid attempt to determine storage_key in ext_get_child_storage_into")?; + let key = context.read_memory(key_data, key_len) + .map_err(|_| "Invalid attempt to get key in ext_get_child_storage_into")?; + + let maybe_value = runtime_io::child_storage(&storage_key, &key); + + if let Some(value) = maybe_value { + let value = &value[value_offset as usize..]; + let written = std::cmp::min(value_len as usize, value.len()); + context.write_memory(value_data, &value[..written]) + .map_err(|_| "Invalid attempt to set value in ext_get_child_storage_into")?; + Ok(value.len() as u32) } else { - "" - }, - HexDisplay::from(&key), - ); + Ok(u32::max_value()) + } + } + + ext_storage_root(result: Pointer) { + let r = runtime_io::storage_root(); + context.write_memory(result, r.as_ref()) + .map_err(|_| "Invalid attempt to set memory in ext_storage_root")?; + Ok(()) + } - if let Some(value) = maybe_value { - let offset = this.heap.allocate(value.len() as u32)? as u32; - this.memory.set(offset, &value) - .map_err(|_| "Invalid attempt to set memory in ext_get_allocated_storage")?; - this.memory.write_primitive(written_out, value.len() as u32) - .map_err(|_| "Invalid attempt to write written_out in ext_get_allocated_storage")?; + ext_child_storage_root( + storage_key_data: Pointer, + storage_key_len: WordSize, + written_out: Pointer, + ) -> Pointer { + let storage_key = context.read_memory(storage_key_data, storage_key_len) + .map_err(|_| "Invalid attempt to determine storage_key in ext_child_storage_root")?; + let value = runtime_io::child_storage_root(&storage_key); + + let offset = context.allocate_memory(value.len() as u32)?; + context.write_memory(offset, &value) + .map_err(|_| "Invalid attempt to set memory in ext_child_storage_root")?; + context.write_primitive(written_out, value.len() as u32) + .map_err(|_| "Invalid attempt to write written_out in ext_child_storage_root")?; Ok(offset) - } else { - this.memory.write_primitive(written_out, u32::max_value()) - .map_err(|_| "Invalid attempt to write failed written_out in ext_get_allocated_storage")?; - Ok(0) } - }, - // return 0 and place u32::max_value() into written_out if no value exists for the key. - ext_get_allocated_child_storage( - storage_key_data: *const u8, - storage_key_len: u32, - key_data: *const u8, - key_len: u32, - written_out: *mut u32 - ) -> *mut u8 => { - let storage_key = this.memory.get( - storage_key_data, - storage_key_len as usize - ).map_err(|_| "Invalid attempt to determine storage_key in ext_get_allocated_child_storage")?; - let key = this.memory.get( - key_data, - key_len as usize - ).map_err(|_| "Invalid attempt to determine key in ext_get_allocated_child_storage")?; - - let maybe_value = { - let storage_key = ChildStorageKey::from_slice(&storage_key) - .ok_or_else(|| "ext_get_allocated_child_storage: child storage key is not valid")?; - this.ext.child_storage(storage_key, &key) - }; - debug_trace!( - target: "wasm-trace", "*** Getting child storage: {} -> {} == {} [k={}]", - primitives::hexdisplay::ascii_format(&storage_key), - if let Some(_preimage) = this.hash_lookup.get(&key) { - format!("%{}", ::primitives::hexdisplay::ascii_format(&_preimage)) + ext_storage_changes_root( + parent_hash_data: Pointer, + _len: WordSize, + result: Pointer, + ) -> u32 { + let mut parent_hash = [0u8; 32]; + context.read_memory_into(parent_hash_data, &mut parent_hash[..]) + .map_err(|_| "Invalid attempt to get parent_hash in ext_storage_changes_root")?; + let r = runtime_io::storage_changes_root(parent_hash); + + if let Some(r) = r { + context.write_memory(result, &r[..]) + .map_err(|_| "Invalid attempt to set memory in ext_storage_changes_root")?; + Ok(1) } else { - format!(" {}", ::primitives::hexdisplay::ascii_format(&key)) - }, - if let Some(ref b) = maybe_value { - &format!("{}", HexDisplay::from(b)) + Ok(0) + } + } + + ext_blake2_256_enumerated_trie_root( + values_data: Pointer, + lens_data: Pointer, + lens_len: WordSize, + result: Pointer, + ) { + let values = (0..lens_len) + .map(|i| context.read_primitive(lens_data.offset(i).ok_or("Pointer overflow")?)) + .collect::, _>>()? + .into_iter() + .scan(0u32, |acc, v| { let o = *acc; *acc += v; Some((o, v)) }) + .map(|(offset, len)| + context.read_memory(values_data.offset(offset).ok_or("Pointer overflow")?, len) + .map_err(|_| + "Invalid attempt to get memory in ext_blake2_256_enumerated_trie_root" + ) + ) + .collect::, _>>()?; + let r = Layout::::ordered_trie_root(values.into_iter()); + context.write_memory(result, &r[..]) + .map_err(|_| "Invalid attempt to set memory in ext_blake2_256_enumerated_trie_root")?; + Ok(()) + } + + ext_chain_id() -> u64 { + Ok(runtime_io::chain_id()) + } + + ext_twox_64(data: Pointer, len: WordSize, out: Pointer) { + let result: [u8; 8] = if len == 0 { + let hashed = twox_64(&[0u8; 0]); + hashed } else { - "" - }, - HexDisplay::from(&key), - ); + let key = context.read_memory(data, len) + .map_err(|_| "Invalid attempt to get key in ext_twox_64")?; + let hashed_key = twox_64(&key); + hashed_key + }; - if let Some(value) = maybe_value { - let offset = this.heap.allocate(value.len() as u32)? as u32; - this.memory.set(offset, &value) - .map_err(|_| "Invalid attempt to set memory in ext_get_allocated_child_storage")?; - this.memory.write_primitive(written_out, value.len() as u32) - .map_err(|_| "Invalid attempt to write written_out in ext_get_allocated_child_storage")?; - Ok(offset) - } else { - this.memory.write_primitive(written_out, u32::max_value()) - .map_err(|_| "Invalid attempt to write failed written_out in ext_get_allocated_child_storage")?; - Ok(0) + context.write_memory(out, &result) + .map_err(|_| "Invalid attempt to set result in ext_twox_64")?; + Ok(()) } - }, - // return u32::max_value() if no value exists for the key. - ext_get_storage_into( - key_data: *const u8, - key_len: u32, - value_data: *mut u8, - value_len: u32, - value_offset: u32 - ) -> u32 => { - let key = this.memory.get(key_data, key_len as usize) - .map_err(|_| "Invalid attempt to get key in ext_get_storage_into")?; - let maybe_value = this.ext.storage(&key); - debug_trace!( - target: "wasm-trace", "*** Getting storage: {} == {} [k={}]", - if let Some(_preimage) = this.hash_lookup.get(&key) { - format!("%{}", primitives::hexdisplay::ascii_format(&_preimage)) + + ext_twox_128(data: Pointer, len: WordSize, out: Pointer) { + let result: [u8; 16] = if len == 0 { + let hashed = twox_128(&[0u8; 0]); + hashed } else { - format!(" {}", primitives::hexdisplay::ascii_format(&key)) - }, - if let Some(ref b) = maybe_value { - &format!("{}", HexDisplay::from(b)) + let key = context.read_memory(data, len) + .map_err(|_| "Invalid attempt to get key in ext_twox_128")?; + let hashed_key = twox_128(&key); + hashed_key + }; + + context.write_memory(out, &result) + .map_err(|_| "Invalid attempt to set result in ext_twox_128")?; + Ok(()) + } + + ext_twox_256(data: Pointer, len: WordSize, out: Pointer) { + let result: [u8; 32] = if len == 0 { + twox_256(&[0u8; 0]) } else { - "" - }, - HexDisplay::from(&key), - ); + let mem = context.read_memory(data, len) + .map_err(|_| "Invalid attempt to get data in ext_twox_256")?; + twox_256(&mem) + }; + context.write_memory(out, &result) + .map_err(|_| "Invalid attempt to set result in ext_twox_256")?; + Ok(()) + } - if let Some(value) = maybe_value { - let value = &value[value_offset as usize..]; - let written = std::cmp::min(value_len as usize, value.len()); - this.memory.set(value_data, &value[..written]) - .map_err(|_| "Invalid attempt to set value in ext_get_storage_into")?; - Ok(value.len() as u32) - } else { - Ok(u32::max_value()) - } - }, - // return u32::max_value() if no value exists for the key. - ext_get_child_storage_into( - storage_key_data: *const u8, - storage_key_len: u32, - key_data: *const u8, - key_len: u32, - value_data: *mut u8, - value_len: u32, - value_offset: u32 - ) -> u32 => { - let storage_key = this.memory.get( - storage_key_data, - storage_key_len as usize - ).map_err(|_| "Invalid attempt to determine storage_key in ext_get_child_storage_into")?; - let key = this.memory.get( - key_data, - key_len as usize - ).map_err(|_| "Invalid attempt to get key in ext_get_child_storage_into")?; - - let maybe_value = { - let storage_key = ChildStorageKey::from_slice(&*storage_key) - .ok_or_else(|| "ext_get_child_storage_into: child storage key is not valid")?; - this.ext.child_storage(storage_key, &key) - }; - debug_trace!( - target: "wasm-trace", "*** Getting storage: {} -> {} == {} [k={}]", - primitives::hexdisplay::ascii_format(&storage_key), - if let Some(_preimage) = this.hash_lookup.get(&key) { - format!("%{}", ::primitives::hexdisplay::ascii_format(&_preimage)) + ext_blake2_128(data: Pointer, len: WordSize, out: Pointer) { + let result: [u8; 16] = if len == 0 { + let hashed = blake2_128(&[0u8; 0]); + hashed } else { - format!(" {}", ::primitives::hexdisplay::ascii_format(&key)) - }, - if let Some(ref b) = maybe_value { - &format!("{}", HexDisplay::from(b)) + let key = context.read_memory(data, len) + .map_err(|_| "Invalid attempt to get key in ext_blake2_128")?; + let hashed_key = blake2_128(&key); + hashed_key + }; + + context.write_memory(out, &result) + .map_err(|_| "Invalid attempt to set result in ext_blake2_128")?; + Ok(()) + } + + ext_blake2_256(data: Pointer, len: WordSize, out: Pointer) { + let result: [u8; 32] = if len == 0 { + blake2_256(&[0u8; 0]) } else { - "" - }, - HexDisplay::from(&key), - ); + let mem = context.read_memory(data, len) + .map_err(|_| "Invalid attempt to get data in ext_blake2_256")?; + blake2_256(&mem) + }; + context.write_memory(out, &result) + .map_err(|_| "Invalid attempt to set result in ext_blake2_256")?; + Ok(()) + } - if let Some(value) = maybe_value { - let value = &value[value_offset as usize..]; - let written = std::cmp::min(value_len as usize, value.len()); - this.memory.set(value_data, &value[..written]) - .map_err(|_| "Invalid attempt to set value in ext_get_child_storage_into")?; - Ok(value.len() as u32) - } else { - Ok(u32::max_value()) - } - }, - ext_storage_root(result: *mut u8) => { - let r = this.ext.storage_root(); - this.memory.set(result, r.as_ref()) - .map_err(|_| "Invalid attempt to set memory in ext_storage_root")?; - Ok(()) - }, - ext_child_storage_root( - storage_key_data: *const u8, - storage_key_len: u32, - written_out: *mut u32 - ) -> *mut u8 => { - let storage_key = this.memory.get(storage_key_data, storage_key_len as usize) - .map_err(|_| "Invalid attempt to determine storage_key in ext_child_storage_root")?; - let storage_key = ChildStorageKey::from_slice(&*storage_key) - .ok_or_else(|| "ext_child_storage_root: child storage key is not valid")?; - let value = this.ext.child_storage_root(storage_key); - - let offset = this.heap.allocate(value.len() as u32)? as u32; - this.memory.set(offset, &value) - .map_err(|_| "Invalid attempt to set memory in ext_child_storage_root")?; - this.memory.write_primitive(written_out, value.len() as u32) - .map_err(|_| "Invalid attempt to write written_out in ext_child_storage_root")?; - Ok(offset) - }, - ext_storage_changes_root(parent_hash_data: *const u8, parent_hash_len: u32, result: *mut u8) -> u32 => { - let mut parent_hash = H256::default(); - if parent_hash_len != parent_hash.as_ref().len() as u32 { - return Err("Invalid parent_hash_len in ext_storage_changes_root".into()); - } - let raw_parent_hash = this.memory.get(parent_hash_data, parent_hash_len as usize) - .map_err(|_| "Invalid attempt to get parent_hash in ext_storage_changes_root")?; - parent_hash.as_mut().copy_from_slice(&raw_parent_hash[..]); - let r = this.ext.storage_changes_root(parent_hash) - .map_err(|_| "Invaid parent_hash passed to ext_storage_changes_root")?; - if let Some(r) = r { - this.memory.set(result, &r[..]) - .map_err(|_| "Invalid attempt to set memory in ext_storage_changes_root")?; - Ok(1) - } else { - Ok(0) + ext_keccak_256(data: Pointer, len: WordSize, out: Pointer) { + let result: [u8; 32] = if len == 0 { + tiny_keccak::keccak256(&[0u8; 0]) + } else { + let mem = context.read_memory(data, len) + .map_err(|_| "Invalid attempt to get data in ext_keccak_256")?; + tiny_keccak::keccak256(&mem) + }; + context.write_memory(out, &result) + .map_err(|_| "Invalid attempt to set result in ext_keccak_256")?; + Ok(()) } - }, - ext_blake2_256_enumerated_trie_root( - values_data: *const u8, - lens_data: *const u32, - lens_len: u32, - result: *mut u8 - ) => { - let values = (0..lens_len) - .map(|i| this.memory.read_primitive(lens_data + i * 4)) - .collect::>>()? - .into_iter() - .scan(0u32, |acc, v| { let o = *acc; *acc += v; Some((o, v)) }) - .map(|(offset, len)| - this.memory.get(values_data + offset, len as usize) - .map_err(|_| - Error::from( - "Invalid attempt to get memory in ext_blake2_256_enumerated_trie_root" - ) - ) - ) - .collect::>>()?; - let r = Layout::::ordered_trie_root(values.into_iter()); - this.memory.set(result, &r[..]) - .map_err(|_| "Invalid attempt to set memory in ext_blake2_256_enumerated_trie_root")?; - Ok(()) - }, - ext_chain_id() -> u64 => { - Ok(this.ext.chain_id()) - }, - ext_twox_64(data: *const u8, len: u32, out: *mut u8) => { - let result: [u8; 8] = if len == 0 { - let hashed = twox_64(&[0u8; 0]); - debug_trace!(target: "xxhash", "XXhash: '' -> {}", HexDisplay::from(&hashed)); - this.hash_lookup.insert(hashed.to_vec(), vec![]); - hashed - } else { - let key = this.memory.get(data, len as usize) - .map_err(|_| "Invalid attempt to get key in ext_twox_64")?; - let hashed_key = twox_64(&key); - - debug_trace!( - target: "xxhash", "XXhash: {} -> {}", - if let Ok(_skey) = str::from_utf8(&key) { - _skey - } else { - &format!("{}", HexDisplay::from(&key)) + + ext_ed25519_public_keys(id_data: Pointer, result_len: Pointer) -> Pointer { + let mut id = [0u8; 4]; + context.read_memory_into(id_data, &mut id[..]) + .map_err(|_| "Invalid attempt to get id in ext_ed25519_public_keys")?; + let key_type = KeyTypeId(id); + + let keys = runtime_io::ed25519_public_keys(key_type).encode(); + + let len = keys.len() as u32; + let offset = context.allocate_memory(len)?; + + context.write_memory(offset, keys.as_ref()) + .map_err(|_| "Invalid attempt to set memory in ext_ed25519_public_keys")?; + context.write_primitive(result_len, len) + .map_err(|_| "Invalid attempt to write result_len in ext_ed25519_public_keys")?; + + Ok(offset) + } + + ext_ed25519_verify( + msg_data: Pointer, + msg_len: WordSize, + sig_data: Pointer, + pubkey_data: Pointer, + ) -> u32 { + let mut sig = [0u8; 64]; + context.read_memory_into(sig_data, &mut sig[..]) + .map_err(|_| "Invalid attempt to get signature in ext_ed25519_verify")?; + let mut pubkey = [0u8; 32]; + context.read_memory_into(pubkey_data, &mut pubkey[..]) + .map_err(|_| "Invalid attempt to get pubkey in ext_ed25519_verify")?; + let msg = context.read_memory(msg_data, msg_len) + .map_err(|_| "Invalid attempt to get message in ext_ed25519_verify")?; + + Ok(if ed25519::Pair::verify_weak(&sig, &msg, &pubkey) { + 0 + } else { + 1 + }) + } + + ext_ed25519_generate( + id_data: Pointer, + seed: Pointer, + seed_len: WordSize, + out: Pointer, + ) { + let mut id = [0u8; 4]; + context.read_memory_into(id_data, &mut id[..]) + .map_err(|_| "Invalid attempt to get id in ext_ed25519_generate")?; + let key_type = KeyTypeId(id); + + let seed = if seed_len == 0 { + None + } else { + Some( + context.read_memory(seed, seed_len) + .map_err(|_| "Invalid attempt to get seed in ext_ed25519_generate")? + ) + }; + + let seed = seed.as_ref() + .map(|seed| + std::str::from_utf8(&seed) + .map_err(|_| "Seed not a valid utf8 string in ext_sr25119_generate") + ).transpose()?; + + let pubkey = runtime_io::ed25519_generate(key_type, seed); + + context.write_memory(out, pubkey.as_ref()) + .map_err(|_| "Invalid attempt to set out in ext_ed25519_generate".into()) + } + + ext_ed25519_sign( + id_data: Pointer, + pubkey_data: Pointer, + msg_data: Pointer, + msg_len: WordSize, + out: Pointer, + ) -> u32 { + let mut id = [0u8; 4]; + context.read_memory_into(id_data, &mut id[..]) + .map_err(|_| "Invalid attempt to get id in ext_ed25519_sign")?; + let key_type = KeyTypeId(id); + + let mut pubkey = [0u8; 32]; + context.read_memory_into(pubkey_data, &mut pubkey[..]) + .map_err(|_| "Invalid attempt to get pubkey in ext_ed25519_sign")?; + + let msg = context.read_memory(msg_data, msg_len) + .map_err(|_| "Invalid attempt to get message in ext_ed25519_sign")?; + + let pub_key = ed25519::Public::try_from(pubkey.as_ref()) + .map_err(|_| "Invalid `ed25519` public key")?; + + let signature = runtime_io::ed25519_sign(key_type, &pub_key, &msg); + + match signature { + Some(signature) => { + context.write_memory(out, signature.as_ref()) + .map_err(|_| "Invalid attempt to set out in ext_ed25519_sign")?; + Ok(0) }, - HexDisplay::from(&hashed_key), - ); + None => Ok(1), + } + } - this.hash_lookup.insert(hashed_key.to_vec(), key); - hashed_key - }; + ext_sr25519_public_keys(id_data: Pointer, result_len: Pointer) -> Pointer { + let mut id = [0u8; 4]; + context.read_memory_into(id_data, &mut id[..]) + .map_err(|_| "Invalid attempt to get id in ext_sr25519_public_keys")?; + let key_type = KeyTypeId(id); - this.memory.set(out, &result).map_err(|_| "Invalid attempt to set result in ext_twox_64")?; - Ok(()) - }, - ext_twox_128(data: *const u8, len: u32, out: *mut u8) => { - let result: [u8; 16] = if len == 0 { - let hashed = twox_128(&[0u8; 0]); - debug_trace!(target: "xxhash", "XXhash: '' -> {}", HexDisplay::from(&hashed)); - this.hash_lookup.insert(hashed.to_vec(), vec![]); - hashed - } else { - let key = this.memory.get(data, len as usize) - .map_err(|_| "Invalid attempt to get key in ext_twox_128")?; - let hashed_key = twox_128(&key); - debug_trace!( - target: "xxhash", "XXhash: {} -> {}", - &if let Ok(_skey) = str::from_utf8(&key) { - *_skey - } else { - format!("{}", HexDisplay::from(&key)) + let keys = runtime_io::sr25519_public_keys(key_type).encode(); + + let len = keys.len() as u32; + let offset = context.allocate_memory(len)?; + + context.write_memory(offset, keys.as_ref()) + .map_err(|_| "Invalid attempt to set memory in ext_sr25519_public_keys")?; + context.write_primitive(result_len, len) + .map_err(|_| "Invalid attempt to write result_len in ext_sr25519_public_keys")?; + + Ok(offset) + } + + ext_sr25519_verify( + msg_data: Pointer, + msg_len: WordSize, + sig_data: Pointer, + pubkey_data: Pointer, + ) -> u32 { + let mut sig = [0u8; 64]; + context.read_memory_into(sig_data, &mut sig[..]) + .map_err(|_| "Invalid attempt to get signature in ext_sr25519_verify")?; + let mut pubkey = [0u8; 32]; + context.read_memory_into(pubkey_data, &mut pubkey[..]) + .map_err(|_| "Invalid attempt to get pubkey in ext_sr25519_verify")?; + let msg = context.read_memory(msg_data, msg_len) + .map_err(|_| "Invalid attempt to get message in ext_sr25519_verify")?; + + Ok(if sr25519::Pair::verify_weak(&sig, &msg, &pubkey) { + 0 + } else { + 1 + }) + } + + ext_sr25519_generate( + id_data: Pointer, + seed: Pointer, + seed_len: WordSize, + out: Pointer, + ) { + let mut id = [0u8; 4]; + context.read_memory_into(id_data, &mut id[..]) + .map_err(|_| "Invalid attempt to get id in ext_sr25519_generate")?; + let key_type = KeyTypeId(id); + let seed = if seed_len == 0 { + None + } else { + Some( + context.read_memory(seed, seed_len) + .map_err(|_| "Invalid attempt to get seed in ext_sr25519_generate")? + ) + }; + + let seed = seed.as_ref() + .map(|seed| + std::str::from_utf8(&seed) + .map_err(|_| "Seed not a valid utf8 string in ext_sr25119_generate") + ) + .transpose()?; + + let pubkey = runtime_io::sr25519_generate(key_type, seed); + + context.write_memory(out, pubkey.as_ref()) + .map_err(|_| "Invalid attempt to set out in ext_sr25519_generate".into()) + } + + ext_sr25519_sign( + id_data: Pointer, + pubkey_data: Pointer, + msg_data: Pointer, + msg_len: WordSize, + out: Pointer, + ) -> u32 { + let mut id = [0u8; 4]; + context.read_memory_into(id_data, &mut id[..]) + .map_err(|_| "Invalid attempt to get id in ext_sr25519_sign")?; + let key_type = KeyTypeId(id); + + let mut pubkey = [0u8; 32]; + context.read_memory_into(pubkey_data, &mut pubkey[..]) + .map_err(|_| "Invalid attempt to get pubkey in ext_sr25519_sign")?; + + let msg = context.read_memory(msg_data, msg_len) + .map_err(|_| "Invalid attempt to get message in ext_sr25519_sign")?; + + let pub_key = sr25519::Public::try_from(pubkey.as_ref()) + .map_err(|_| "Invalid `sr25519` public key")?; + + let signature = runtime_io::sr25519_sign(key_type, &pub_key, &msg); + + match signature { + Some(signature) => { + context.write_memory(out, signature.as_ref()) + .map_err(|_| "Invalid attempt to set out in ext_sr25519_sign")?; + Ok(0) }, - HexDisplay::from(&hashed_key), - ); - this.hash_lookup.insert(hashed_key.to_vec(), key); - hashed_key - }; + None => Ok(1), + } + } - this.memory.set(out, &result) - .map_err(|_| "Invalid attempt to set result in ext_twox_128")?; - Ok(()) - }, - ext_twox_256(data: *const u8, len: u32, out: *mut u8) => { - let result: [u8; 32] = if len == 0 { - twox_256(&[0u8; 0]) - } else { - let mem = this.memory.get(data, len as usize) - .map_err(|_| "Invalid attempt to get data in ext_twox_256")?; - twox_256(&mem) - }; - this.memory.set(out, &result).map_err(|_| "Invalid attempt to set result in ext_twox_256")?; - Ok(()) - }, - ext_blake2_128(data: *const u8, len: u32, out: *mut u8) => { - let result: [u8; 16] = if len == 0 { - let hashed = blake2_128(&[0u8; 0]); - this.hash_lookup.insert(hashed.to_vec(), vec![]); - hashed - } else { - let key = this.memory.get(data, len as usize) - .map_err(|_| "Invalid attempt to get key in ext_blake2_128")?; - let hashed_key = blake2_128(&key); - this.hash_lookup.insert(hashed_key.to_vec(), key); - hashed_key - }; + ext_secp256k1_ecdsa_recover( + msg_data: Pointer, + sig_data: Pointer, + pubkey_data: Pointer, + ) -> u32 { + let mut sig = [0u8; 65]; + context.read_memory_into(sig_data, &mut sig[..]) + .map_err(|_| "Invalid attempt to get signature in ext_secp256k1_ecdsa_recover")?; + let rs = match secp256k1::Signature::parse_slice(&sig[0..64]) { + Ok(rs) => rs, + _ => return Ok(1), + }; - this.memory.set(out, &result) - .map_err(|_| "Invalid attempt to set result in ext_blake2_128")?; - Ok(()) - }, - ext_blake2_256(data: *const u8, len: u32, out: *mut u8) => { - let result: [u8; 32] = if len == 0 { - blake2_256(&[0u8; 0]) - } else { - let mem = this.memory.get(data, len as usize) - .map_err(|_| "Invalid attempt to get data in ext_blake2_256")?; - blake2_256(&mem) - }; - this.memory.set(out, &result).map_err(|_| "Invalid attempt to set result in ext_blake2_256")?; - Ok(()) - }, - ext_keccak_256(data: *const u8, len: u32, out: *mut u8) => { - let result: [u8; 32] = if len == 0 { - tiny_keccak::keccak256(&[0u8; 0]) - } else { - let mem = this.memory.get(data, len as usize) - .map_err(|_| "Invalid attempt to get data in ext_keccak_256")?; - tiny_keccak::keccak256(&mem) - }; - this.memory.set(out, &result).map_err(|_| "Invalid attempt to set result in ext_keccak_256")?; - Ok(()) - }, - ext_ed25519_public_keys(id_data: *const u8, result_len: *mut u32) -> *mut u8 => { - let mut id = [0u8; 4]; - this.memory.get_into(id_data, &mut id[..]) - .map_err(|_| "Invalid attempt to get id in ext_ed25519_public_keys")?; - let key_type = KeyTypeId(id); - - let keys = this.ext - .keystore() - .ok_or("No `keystore` associated for the current context!")? - .read() - .ed25519_public_keys(key_type) - .encode(); - - let len = keys.len() as u32; - let offset = this.heap.allocate(len)? as u32; - - this.memory.set(offset, keys.as_ref()) - .map_err(|_| "Invalid attempt to set memory in ext_ed25519_public_keys")?; - this.memory.write_primitive(result_len, len) - .map_err(|_| "Invalid attempt to write result_len in ext_ed25519_public_keys")?; - - Ok(offset) - }, - ext_ed25519_verify( - msg_data: *const u8, - msg_len: u32, - sig_data: *const u8, - pubkey_data: *const u8, - ) -> u32 => { - let mut sig = [0u8; 64]; - this.memory.get_into(sig_data, &mut sig[..]) - .map_err(|_| "Invalid attempt to get signature in ext_ed25519_verify")?; - let mut pubkey = [0u8; 32]; - this.memory.get_into(pubkey_data, &mut pubkey[..]) - .map_err(|_| "Invalid attempt to get pubkey in ext_ed25519_verify")?; - let msg = this.memory.get(msg_data, msg_len as usize) - .map_err(|_| "Invalid attempt to get message in ext_ed25519_verify")?; - - Ok(if ed25519::Pair::verify_weak(&sig, &msg, &pubkey) { - 0 - } else { - 5 - }) - }, - ext_ed25519_generate(id_data: *const u8, seed: *const u8, seed_len: u32, out: *mut u8) => { - let mut id = [0u8; 4]; - this.memory.get_into(id_data, &mut id[..]) - .map_err(|_| "Invalid attempt to get id in ext_ed25519_generate")?; - let key_type = KeyTypeId(id); - - let seed = if seed_len == 0 { - None - } else { - Some( - this.memory.get(seed, seed_len as usize) - .map_err(|_| "Invalid attempt to get seed in ext_ed25519_generate")? - ) - }; + let recovery_id = if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as u8; + let v = match secp256k1::RecoveryId::parse(recovery_id) { + Ok(v) => v, + _ => return Ok(2), + }; - let seed = seed.as_ref() - .map(|seed| - std::str::from_utf8(&seed) - .map_err(|_| "Seed not a valid utf8 string in ext_sr25119_generate") - ).transpose()?; - - let pubkey = this.ext - .keystore() - .ok_or("No `keystore` associated for the current context!")? - .write() - .ed25519_generate_new(key_type, seed) - .map_err(|_| "`ed25519` key generation failed")?; - - this.memory.set(out, pubkey.as_ref()) - .map_err(|_| "Invalid attempt to set out in ext_ed25519_generate".into()) - }, - ext_ed25519_sign( - id_data: *const u8, - pubkey_data: *const u8, - msg_data: *const u8, - msg_len: u32, - out: *mut u8, - ) -> u32 => { - let mut id = [0u8; 4]; - this.memory.get_into(id_data, &mut id[..]) - .map_err(|_| "Invalid attempt to get id in ext_ed25519_sign")?; - let key_type = KeyTypeId(id); - - let mut pubkey = [0u8; 32]; - this.memory.get_into(pubkey_data, &mut pubkey[..]) - .map_err(|_| "Invalid attempt to get pubkey in ext_ed25519_sign")?; - - let msg = this.memory.get(msg_data, msg_len as usize) - .map_err(|_| "Invalid attempt to get message in ext_ed25519_sign")?; - - let pub_key = ed25519::Public::try_from(pubkey.as_ref()) - .map_err(|_| "Invalid `ed25519` public key")?; - - let signature = this.ext - .keystore() - .ok_or("No `keystore` associated for the current context!")? - .read() - .ed25519_key_pair(key_type, &pub_key) - .map(|k| k.sign(msg.as_ref())); - - match signature { - Some(signature) => { - this.memory - .set(out, signature.as_ref()) - .map_err(|_| "Invalid attempt to set out in ext_ed25519_sign")?; - Ok(0) - }, - None => Ok(1), - } - }, - ext_sr25519_public_keys(id_data: *const u8, result_len: *mut u32) -> *mut u8 => { - let mut id = [0u8; 4]; - this.memory.get_into(id_data, &mut id[..]) - .map_err(|_| "Invalid attempt to get id in ext_sr25519_public_keys")?; - let key_type = KeyTypeId(id); - - let keys = this.ext - .keystore() - .ok_or("No `keystore` associated for the current context!")? - .read() - .sr25519_public_keys(key_type) - .encode(); - - let len = keys.len() as u32; - let offset = this.heap.allocate(len)? as u32; - - this.memory.set(offset, keys.as_ref()) - .map_err(|_| "Invalid attempt to set memory in ext_sr25519_public_keys")?; - this.memory.write_primitive(result_len, len) - .map_err(|_| "Invalid attempt to write result_len in ext_sr25519_public_keys")?; - - Ok(offset) - }, - ext_sr25519_verify( - msg_data: *const u8, - msg_len: u32, - sig_data: *const u8, - pubkey_data: *const u8, - ) -> u32 => { - let mut sig = [0u8; 64]; - this.memory.get_into(sig_data, &mut sig[..]) - .map_err(|_| "Invalid attempt to get signature in ext_sr25519_verify")?; - let mut pubkey = [0u8; 32]; - this.memory.get_into(pubkey_data, &mut pubkey[..]) - .map_err(|_| "Invalid attempt to get pubkey in ext_sr25519_verify")?; - let msg = this.memory.get(msg_data, msg_len as usize) - .map_err(|_| "Invalid attempt to get message in ext_sr25519_verify")?; - - Ok(if sr25519::Pair::verify_weak(&sig, &msg, &pubkey) { - 0 - } else { - 5 - }) - }, - ext_sr25519_generate(id_data: *const u8, seed: *const u8, seed_len: u32, out: *mut u8) => { - let mut id = [0u8; 4]; - this.memory.get_into(id_data, &mut id[..]) - .map_err(|_| "Invalid attempt to get id in ext_sr25519_generate")?; - let key_type = KeyTypeId(id); - let seed = if seed_len == 0 { - None - } else { - Some( - this.memory.get(seed, seed_len as usize) - .map_err(|_| "Invalid attempt to get seed in ext_sr25519_generate")? - ) - }; + let mut msg = [0u8; 32]; + context.read_memory_into(msg_data, &mut msg[..]) + .map_err(|_| "Invalid attempt to get message in ext_secp256k1_ecdsa_recover")?; - let seed = seed.as_ref() - .map(|seed| - std::str::from_utf8(&seed) - .map_err(|_| "Seed not a valid utf8 string in ext_sr25119_generate") - ) - .transpose()?; - - let pubkey = this.ext - .keystore() - .ok_or("No `keystore` associated for the current context!")? - .write() - .sr25519_generate_new(key_type, seed) - .map_err(|_| "`sr25519` key generation failed")?; - - this.memory.set(out, pubkey.as_ref()) - .map_err(|_| "Invalid attempt to set out in ext_sr25519_generate".into()) - }, - ext_sr25519_sign( - id_data: *const u8, - pubkey_data: *const u8, - msg_data: *const u8, - msg_len: u32, - out: *mut u8, - ) -> u32 => { - let mut id = [0u8; 4]; - this.memory.get_into(id_data, &mut id[..]) - .map_err(|_| "Invalid attempt to get id in ext_sr25519_sign")?; - let key_type = KeyTypeId(id); - - let mut pubkey = [0u8; 32]; - this.memory.get_into(pubkey_data, &mut pubkey[..]) - .map_err(|_| "Invalid attempt to get pubkey in ext_sr25519_sign")?; - - let msg = this.memory.get(msg_data, msg_len as usize) - .map_err(|_| "Invalid attempt to get message in ext_sr25519_sign")?; - - let pub_key = sr25519::Public::try_from(pubkey.as_ref()) - .map_err(|_| "Invalid `sr25519` public key")?; - - let signature = this.ext - .keystore() - .ok_or("No `keystore` associated for the current context!")? - .read() - .sr25519_key_pair(key_type, &pub_key) - .map(|k| k.sign(msg.as_ref())); - - match signature { - Some(signature) => { - this.memory.set(out, signature.as_ref()) - .map_err(|_| "Invalid attempt to set out in ext_sr25519_sign")?; - Ok(0) - }, - None => Ok(1), - } - }, - ext_secp256k1_ecdsa_recover(msg_data: *const u8, sig_data: *const u8, pubkey_data: *mut u8) -> u32 => { - let mut sig = [0u8; 65]; - this.memory.get_into(sig_data, &mut sig[..]) - .map_err(|_| "Invalid attempt to get signature in ext_secp256k1_ecdsa_recover")?; - let rs = match secp256k1::Signature::parse_slice(&sig[0..64]) { - Ok(rs) => rs, - _ => return Ok(1), - }; - let v = match secp256k1::RecoveryId::parse(if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as u8) { - Ok(v) => v, - _ => return Ok(2), - }; + let pubkey = match secp256k1::recover(&secp256k1::Message::parse(&msg), &rs, &v) { + Ok(pk) => pk, + _ => return Ok(3), + }; + context.write_memory(pubkey_data, &pubkey.serialize()[1..65]) + .map_err(|_| "Invalid attempt to set pubkey in ext_secp256k1_ecdsa_recover")?; - let mut msg = [0u8; 32]; - this.memory.get_into(msg_data, &mut msg[..]) - .map_err(|_| "Invalid attempt to get message in ext_secp256k1_ecdsa_recover")?; + Ok(0) + } - let pubkey = match secp256k1::recover(&secp256k1::Message::parse(&msg), &rs, &v) { - Ok(pk) => pk, - _ => return Ok(3), - }; + ext_is_validator() -> u32 { + if runtime_io::is_validator() { Ok(1) } else { Ok(0) } + } - this.memory.set(pubkey_data, &pubkey.serialize()[1..65]) - .map_err(|_| "Invalid attempt to set pubkey in ext_secp256k1_ecdsa_recover")?; - - Ok(0) - }, - ext_is_validator() -> u32 => { - this.ext.offchain() - .map(|o| if o.is_validator() { 1 } else { 0 }) - .ok_or("Calling unavailable API ext_is_validator: wasm".into()) - }, - ext_submit_transaction(msg_data: *const u8, len: u32) -> u32 => { - let extrinsic = this.memory.get(msg_data, len as usize) - .map_err(|_| "OOB while ext_submit_transaction: wasm")?; - - let res = this.ext.offchain() - .map(|api| api.submit_transaction(extrinsic)) - .ok_or_else(|| "Calling unavailable API ext_submit_transaction: wasm")?; - - Ok(if res.is_ok() { 0 } else { 1 }) - }, - ext_network_state(written_out: *mut u32) -> *mut u8 => { - let res = this.ext.offchain() - .map(|api| api.network_state()) - .ok_or_else(|| "Calling unavailable API ext_network_state: wasm")?; - - let encoded = res.encode(); - let len = encoded.len() as u32; - let offset = this.heap.allocate(len)? as u32; - this.memory.set(offset, &encoded) - .map_err(|_| "Invalid attempt to set memory in ext_network_state")?; - - this.memory.write_primitive(written_out, len) - .map_err(|_| "Invalid attempt to write written_out in ext_network_state")?; - - Ok(offset) - }, - ext_timestamp() -> u64 => { - let timestamp = this.ext.offchain() - .map(|api| api.timestamp()) - .ok_or_else(|| "Calling unavailable API ext_timestamp: wasm")?; - Ok(timestamp.unix_millis()) - }, - ext_sleep_until(deadline: u64) => { - this.ext.offchain() - .map(|api| api.sleep_until(offchain::Timestamp::from_unix_millis(deadline))) - .ok_or_else(|| "Calling unavailable API ext_sleep_until: wasm")?; - Ok(()) - }, - ext_random_seed(seed_data: *mut u8) => { - // NOTE the runtime as assumptions about seed size. - let seed: [u8; 32] = this.ext.offchain() - .map(|api| api.random_seed()) - .ok_or_else(|| "Calling unavailable API ext_random_seed: wasm")?; - - this.memory.set(seed_data, &seed) - .map_err(|_| "Invalid attempt to set value in ext_random_seed")?; - Ok(()) - }, - ext_local_storage_set(kind: u32, key: *const u8, key_len: u32, value: *const u8, value_len: u32) => { - let kind = offchain::StorageKind::try_from(kind) - .map_err(|_| "storage kind OOB while ext_local_storage_set: wasm")?; - let key = this.memory.get(key, key_len as usize) - .map_err(|_| "OOB while ext_local_storage_set: wasm")?; - let value = this.memory.get(value, value_len as usize) - .map_err(|_| "OOB while ext_local_storage_set: wasm")?; - - this.ext.offchain() - .map(|api| api.local_storage_set(kind, &key, &value)) - .ok_or_else(|| "Calling unavailable API ext_local_storage_set: wasm")?; - - Ok(()) - }, - ext_local_storage_get(kind: u32, key: *const u8, key_len: u32, value_len: *mut u32) -> *mut u8 => { - let kind = offchain::StorageKind::try_from(kind) - .map_err(|_| "storage kind OOB while ext_local_storage_get: wasm")?; - let key = this.memory.get(key, key_len as usize) - .map_err(|_| "OOB while ext_local_storage_get: wasm")?; - - let maybe_value = this.ext.offchain() - .map(|api| api.local_storage_get(kind, &key)) - .ok_or_else(|| "Calling unavailable API ext_local_storage_get: wasm")?; - - let (offset, len) = if let Some(value) = maybe_value { - let offset = this.heap.allocate(value.len() as u32)? as u32; - this.memory.set(offset, &value) - .map_err(|_| "Invalid attempt to set memory in ext_local_storage_get")?; - (offset, value.len() as u32) - } else { - (0, u32::max_value()) - }; + ext_submit_transaction(msg_data: Pointer, len: WordSize) -> u32 { + let extrinsic = context.read_memory(msg_data, len) + .map_err(|_| "OOB while ext_submit_transaction: wasm")?; + + let res = runtime_io::submit_transaction(extrinsic); + + Ok(if res.is_ok() { 0 } else { 1 }) + } + + ext_network_state(written_out: Pointer) -> Pointer { + let res = runtime_io::network_state(); + + let encoded = res.encode(); + let len = encoded.len() as u32; + let offset = context.allocate_memory(len)?; + context.write_memory(offset, &encoded) + .map_err(|_| "Invalid attempt to set memory in ext_network_state")?; + + context.write_primitive(written_out, len) + .map_err(|_| "Invalid attempt to write written_out in ext_network_state")?; + + Ok(offset) + } + + ext_timestamp() -> u64 { + Ok(runtime_io::timestamp().unix_millis()) + } + + ext_sleep_until(deadline: u64) { + runtime_io::sleep_until(offchain::Timestamp::from_unix_millis(deadline)); + Ok(()) + } + + ext_random_seed(seed_data: Pointer) { + // NOTE the runtime as assumptions about seed size. + let seed = runtime_io::random_seed(); + + context.write_memory(seed_data, &seed) + .map_err(|_| "Invalid attempt to set value in ext_random_seed")?; + Ok(()) + } + + ext_local_storage_set( + kind: u32, + key: Pointer, + key_len: WordSize, + value: Pointer, + value_len: WordSize, + ) { + let kind = offchain::StorageKind::try_from(kind) + .map_err(|_| "storage kind OOB while ext_local_storage_set: wasm")?; + let key = context.read_memory(key, key_len) + .map_err(|_| "OOB while ext_local_storage_set: wasm")?; + let value = context.read_memory(value, value_len) + .map_err(|_| "OOB while ext_local_storage_set: wasm")?; - this.memory.write_primitive(value_len, len) - .map_err(|_| "Invalid attempt to write value_len in ext_local_storage_get")?; - - Ok(offset) - }, - ext_local_storage_compare_and_set( - kind: u32, - key: *const u8, - key_len: u32, - old_value: *const u8, - old_value_len: u32, - new_value: *const u8, - new_value_len: u32 - ) -> u32 => { - let kind = offchain::StorageKind::try_from(kind) - .map_err(|_| "storage kind OOB while ext_local_storage_compare_and_set: wasm")?; - let key = this.memory.get(key, key_len as usize) - .map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")?; - let new_value = this.memory.get(new_value, new_value_len as usize) - .map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")?; - - let res = { - if old_value_len == u32::max_value() { - this.ext.offchain() - .map(|api| api.local_storage_compare_and_set(kind, &key, None, &new_value)) - .ok_or_else(|| "Calling unavailable API ext_local_storage_compare_and_set: wasm")? + runtime_io::local_storage_set(kind, &key, &value); + + Ok(()) + } + + ext_local_storage_get( + kind: u32, + key: Pointer, + key_len: WordSize, + value_len: Pointer, + ) -> Pointer { + let kind = offchain::StorageKind::try_from(kind) + .map_err(|_| "storage kind OOB while ext_local_storage_get: wasm")?; + let key = context.read_memory(key, key_len) + .map_err(|_| "OOB while ext_local_storage_get: wasm")?; + + let maybe_value = runtime_io::local_storage_get(kind, &key); + + let (offset, len) = if let Some(value) = maybe_value { + let offset = context.allocate_memory(value.len() as u32)?; + context.write_memory(offset, &value) + .map_err(|_| "Invalid attempt to set memory in ext_local_storage_get")?; + (offset, value.len() as u32) + } else { + (Pointer::null(), u32::max_value()) + }; + + context.write_primitive(value_len, len) + .map_err(|_| "Invalid attempt to write value_len in ext_local_storage_get")?; + + Ok(offset) + } + + ext_local_storage_compare_and_set( + kind: u32, + key: Pointer, + key_len: WordSize, + old_value: Pointer, + old_value_len: WordSize, + new_value: Pointer, + new_value_len: WordSize, + ) -> u32 { + let kind = offchain::StorageKind::try_from(kind) + .map_err(|_| "storage kind OOB while ext_local_storage_compare_and_set: wasm")?; + let key = context.read_memory(key, key_len) + .map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")?; + let new_value = context.read_memory(new_value, new_value_len) + .map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")?; + + let old_value = if old_value_len == u32::max_value() { + None } else { - let v = this.memory.get(old_value, old_value_len as usize) - .map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")?; - this.ext.offchain() - .map(|api| api.local_storage_compare_and_set(kind, &key, Some(v.as_slice()), &new_value)) - .ok_or_else(|| "Calling unavailable API ext_local_storage_compare_and_set: wasm")? + Some( + context.read_memory(old_value, old_value_len) + .map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")? + ) + }; + + let res = runtime_io::local_storage_compare_and_set( + kind, + &key, + old_value.as_ref().map(|v| v.as_ref()), + &new_value, + ); + + Ok(if res { 0 } else { 1 }) + } + + ext_http_request_start( + method: Pointer, + method_len: WordSize, + url: Pointer, + url_len: WordSize, + meta: Pointer, + meta_len: WordSize, + ) -> u32 { + let method = context.read_memory(method, method_len) + .map_err(|_| "OOB while ext_http_request_start: wasm")?; + let url = context.read_memory(url, url_len) + .map_err(|_| "OOB while ext_http_request_start: wasm")?; + let meta = context.read_memory(meta, meta_len) + .map_err(|_| "OOB while ext_http_request_start: wasm")?; + + let method_str = str::from_utf8(&method) + .map_err(|_| "invalid str while ext_http_request_start: wasm")?; + let url_str = str::from_utf8(&url) + .map_err(|_| "invalid str while ext_http_request_start: wasm")?; + + let id = runtime_io::http_request_start(method_str, url_str, &meta); + + if let Ok(id) = id { + Ok(id.into()) + } else { + Ok(u32::max_value()) } - }; + } - Ok(if res { 0 } else { 1 }) - }, - ext_http_request_start( - method: *const u8, - method_len: u32, - url: *const u8, - url_len: u32, - meta: *const u8, - meta_len: u32 - ) -> u32 => { - let method = this.memory.get(method, method_len as usize) - .map_err(|_| "OOB while ext_http_request_start: wasm")?; - let url = this.memory.get(url, url_len as usize) - .map_err(|_| "OOB while ext_http_request_start: wasm")?; - let meta = this.memory.get(meta, meta_len as usize) - .map_err(|_| "OOB while ext_http_request_start: wasm")?; - - let method_str = str::from_utf8(&method) - .map_err(|_| "invalid str while ext_http_request_start: wasm")?; - let url_str = str::from_utf8(&url) - .map_err(|_| "invalid str while ext_http_request_start: wasm")?; - - let id = this.ext.offchain() - .map(|api| api.http_request_start(method_str, url_str, &*meta)) - .ok_or_else(|| "Calling unavailable API ext_http_request_start: wasm")?; - - if let Ok(id) = id { - Ok(id.into()) - } else { - Ok(u32::max_value()) - } - }, - ext_http_request_add_header( - request_id: u32, - name: *const u8, - name_len: u32, - value: *const u8, - value_len: u32 - ) -> u32 => { - let name = this.memory.get(name, name_len as usize) - .map_err(|_| "OOB while ext_http_request_add_header: wasm")?; - let value = this.memory.get(value, value_len as usize) - .map_err(|_| "OOB while ext_http_request_add_header: wasm")?; - - let name_str = str::from_utf8(&name) - .map_err(|_| "Invalid str while ext_http_request_add_header: wasm")?; - let value_str = str::from_utf8(&value) - .map_err(|_| "Invalid str while ext_http_request_add_header: wasm")?; - - let res = this.ext.offchain() - .map(|api| api.http_request_add_header( - offchain::HttpRequestId(request_id as u16), - &name_str, - &value_str, - )) - .ok_or_else(|| "Calling unavailable API ext_http_request_add_header: wasm")?; - - Ok(if res.is_ok() { 0 } else { 1 }) - }, - ext_http_request_write_body( - request_id: u32, - chunk: *const u8, - chunk_len: u32, - deadline: u64 - ) -> u32 => { - let chunk = this.memory.get(chunk, chunk_len as usize) - .map_err(|_| "OOB while ext_http_request_write_body: wasm")?; - - let res = this.ext.offchain() - .map(|api| api.http_request_write_body( + ext_http_request_add_header( + request_id: u32, + name: Pointer, + name_len: WordSize, + value: Pointer, + value_len: WordSize, + ) -> u32 { + let name = context.read_memory(name, name_len) + .map_err(|_| "OOB while ext_http_request_add_header: wasm")?; + let value = context.read_memory(value, value_len) + .map_err(|_| "OOB while ext_http_request_add_header: wasm")?; + + let name_str = str::from_utf8(&name) + .map_err(|_| "Invalid str while ext_http_request_add_header: wasm")?; + let value_str = str::from_utf8(&value) + .map_err(|_| "Invalid str while ext_http_request_add_header: wasm")?; + + let res = runtime_io::http_request_add_header( offchain::HttpRequestId(request_id as u16), - &chunk, - deadline_to_timestamp(deadline) - )) - .ok_or_else(|| "Calling unavailable API ext_http_request_write_body: wasm")?; + name_str, + value_str, + ); - Ok(match res { - Ok(()) => 0, - Err(e) => e.into(), - }) - }, - ext_http_response_wait( - ids: *const u32, - ids_len: u32, - statuses: *mut u32, - deadline: u64 - ) => { - let ids = (0..ids_len) - .map(|i| - this.memory.read_primitive(ids + i * 4) - .map(|id: u32| offchain::HttpRequestId(id as u16)) - .map_err(|_| "OOB while ext_http_response_wait: wasm") - ) - .collect::<::std::result::Result, _>>()?; + Ok(if res.is_ok() { 0 } else { 1 }) + } - let res = this.ext.offchain() - .map(|api| api.http_response_wait(&ids, deadline_to_timestamp(deadline))) - .ok_or_else(|| "Calling unavailable API ext_http_response_wait: wasm")? - .into_iter() - .map(|status| status.into()) - .enumerate() - // make sure to take up to `ids_len` to avoid exceeding the mem. - .take(ids_len as usize); - - for (i, status) in res { - this.memory.write_primitive(statuses + i as u32 * 4, status) - .map_err(|_| "Invalid attempt to set memory in ext_http_response_wait")?; - } - - Ok(()) - }, - ext_http_response_headers( - request_id: u32, - written_out: *mut u32 - ) -> *mut u8 => { - use codec::Encode; - - let headers = this.ext.offchain() - .map(|api| api.http_response_headers(offchain::HttpRequestId(request_id as u16))) - .ok_or_else(|| "Calling unavailable API ext_http_response_headers: wasm")?; - - let encoded = headers.encode(); - let len = encoded.len() as u32; - let offset = this.heap.allocate(len)? as u32; - this.memory.set(offset, &encoded) - .map_err(|_| "Invalid attempt to set memory in ext_http_response_headers")?; - this.memory.write_primitive(written_out, len) - .map_err(|_| "Invalid attempt to write written_out in ext_http_response_headers")?; - - Ok(offset) - }, - ext_http_response_read_body( - request_id: u32, - buffer: *mut u8, - buffer_len: u32, - deadline: u64 - ) -> u32 => { - let mut internal_buffer = Vec::with_capacity(buffer_len as usize); - internal_buffer.resize(buffer_len as usize, 0); - - let res = this.ext.offchain() - .map(|api| api.http_response_read_body( + ext_http_request_write_body( + request_id: u32, + chunk: Pointer, + chunk_len: WordSize, + deadline: u64, + ) -> u32 { + let chunk = context.read_memory(chunk, chunk_len) + .map_err(|_| "OOB while ext_http_request_write_body: wasm")?; + + let res = runtime_io::http_request_write_body( offchain::HttpRequestId(request_id as u16), - &mut internal_buffer, + &chunk, deadline_to_timestamp(deadline), - )) - .ok_or_else(|| "Calling unavailable API ext_http_response_read_body: wasm")?; + ); - Ok(match res { - Ok(read) => { - this.memory.set(buffer, &internal_buffer[..read]) - .map_err(|_| "Invalid attempt to set memory in ext_http_response_read_body")?; + Ok(match res { + Ok(()) => 0, + Err(e) => e.into(), + }) + } - read as u32 - }, - Err(err) => { - u32::max_value() - u32::from(err) + 1 + ext_http_response_wait( + ids: Pointer, + ids_len: WordSize, + statuses: Pointer, + deadline: u64, + ) { + let ids = (0..ids_len) + .map(|i| + context.read_primitive(ids.offset(i).ok_or("Point overflow")?) + .map(|id: u32| offchain::HttpRequestId(id as u16)) + .map_err(|_| "OOB while ext_http_response_wait: wasm") + ) + .collect::, _>>()?; + + let res = runtime_io::http_response_wait(&ids, deadline_to_timestamp(deadline)) + .into_iter() + .map(|status| u32::from(status)) + .enumerate() + // make sure to take up to `ids_len` to avoid exceeding the mem. + .take(ids_len as usize); + + for (i, status) in res { + context.write_primitive(statuses.offset(i as u32).ok_or("Point overflow")?, status) + .map_err(|_| "Invalid attempt to set memory in ext_http_response_wait")?; } - }) - }, - ext_sandbox_instantiate( - dispatch_thunk_idx: usize, - wasm_ptr: *const u8, - wasm_len: usize, - imports_ptr: *const u8, - imports_len: usize, - state: usize - ) -> u32 => { - let wasm = this.memory.get(wasm_ptr, wasm_len as usize) - .map_err(|_| "OOB while ext_sandbox_instantiate: wasm")?; - let raw_env_def = this.memory.get(imports_ptr, imports_len as usize) - .map_err(|_| "OOB while ext_sandbox_instantiate: imports")?; - // Extract a dispatch thunk from instance's table by the specified index. - let dispatch_thunk = { - let table = this.table.as_ref() - .ok_or_else(|| "Runtime doesn't have a table; sandbox is unavailable")?; - table.get(dispatch_thunk_idx) - .map_err(|_| "dispatch_thunk_idx is out of the table bounds")? - .ok_or_else(|| "dispatch_thunk_idx points on an empty table entry")? - .clone() - }; + Ok(()) + } - let instance_idx_or_err_code = - match sandbox::instantiate(this, dispatch_thunk, &wasm, &raw_env_def, state) { - Ok(instance_idx) => instance_idx, - Err(sandbox::InstantiationError::StartTrapped) => sandbox_primitives::ERR_EXECUTION, - Err(_) => sandbox_primitives::ERR_MODULE, - }; + ext_http_response_headers( + request_id: u32, + written_out: Pointer, + ) -> Pointer { + use codec::Encode; - Ok(instance_idx_or_err_code as u32) - }, - ext_sandbox_instance_teardown(instance_idx: u32) => { - this.sandbox_store.instance_teardown(instance_idx)?; - Ok(()) - }, - ext_sandbox_invoke( - instance_idx: u32, - export_ptr: *const u8, - export_len: usize, - args_ptr: *const u8, - args_len: usize, - return_val_ptr: *const u8, - return_val_len: usize, - state: usize - ) -> u32 => { - use codec::{Decode, Encode}; - - trace!(target: "sr-sandbox", "invoke, instance_idx={}", instance_idx); - let export = this.memory.get(export_ptr, export_len as usize) - .map_err(|_| "OOB while ext_sandbox_invoke: export") - .and_then(|b| - String::from_utf8(b) - .map_err(|_| "Export name should be a valid utf-8 sequence") - )?; + let headers = runtime_io::http_response_headers(offchain::HttpRequestId(request_id as u16)); - // Deserialize arguments and convert them into wasmi types. - let serialized_args = this.memory.get(args_ptr, args_len as usize) - .map_err(|_| "OOB while ext_sandbox_invoke: args")?; - let args = Vec::::decode(&mut &serialized_args[..]) - .map_err(|_| "Can't decode serialized arguments for the invocation")? - .into_iter() - .map(Into::into) - .collect::>(); + let encoded = headers.encode(); + let len = encoded.len() as u32; + let offset = context.allocate_memory(len)?; - let instance = this.sandbox_store.instance(instance_idx)?; - let result = instance.invoke(&export, &args, this, state); + context.write_memory(offset, &encoded) + .map_err(|_| "Invalid attempt to set memory in ext_http_response_headers")?; + context.write_primitive(written_out, len) + .map_err(|_| "Invalid attempt to write written_out in ext_http_response_headers")?; - match result { - Ok(None) => Ok(sandbox_primitives::ERR_OK), - Ok(Some(val)) => { - // Serialize return value and write it back into the memory. - sandbox_primitives::ReturnValue::Value(val.into()).using_encoded(|val| { - if val.len() > return_val_len as usize { - Err("Return value buffer is too small")?; - } - this.memory - .set(return_val_ptr, val) - .map_err(|_| "Return value buffer is OOB")?; - Ok(sandbox_primitives::ERR_OK) - }) - } - Err(_) => Ok(sandbox_primitives::ERR_EXECUTION), + Ok(offset) } - }, - ext_sandbox_memory_new(initial: u32, maximum: u32) -> u32 => { - let mem_idx = this.sandbox_store.new_memory(initial, maximum)?; - Ok(mem_idx) - }, - ext_sandbox_memory_get(memory_idx: u32, offset: u32, buf_ptr: *mut u8, buf_len: u32) -> u32 => { - let sandboxed_memory = this.sandbox_store.memory(memory_idx)?; - match MemoryInstance::transfer( - &sandboxed_memory, - offset as usize, - &this.memory, - buf_ptr as usize, - buf_len as usize, - ) { - Ok(()) => Ok(sandbox_primitives::ERR_OK), - Err(_) => Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS), - } - }, - ext_sandbox_memory_set(memory_idx: u32, offset: u32, val_ptr: *const u8, val_len: u32) -> u32 => { - let sandboxed_memory = this.sandbox_store.memory(memory_idx)?; + ext_http_response_read_body( + request_id: u32, + buffer: Pointer, + buffer_len: WordSize, + deadline: u64, + ) -> WordSize { + let mut internal_buffer = Vec::with_capacity(buffer_len as usize); + internal_buffer.resize(buffer_len as usize, 0); - match MemoryInstance::transfer( - &this.memory, - val_ptr as usize, - &sandboxed_memory, - offset as usize, - val_len as usize, - ) { - Ok(()) => Ok(sandbox_primitives::ERR_OK), - Err(_) => Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS), + let res = runtime_io::http_response_read_body( + offchain::HttpRequestId(request_id as u16), + &mut internal_buffer, + deadline_to_timestamp(deadline), + ); + + Ok(match res { + Ok(read) => { + context.write_memory(buffer, &internal_buffer[..read]) + .map_err(|_| "Invalid attempt to set memory in ext_http_response_read_body")?; + + read as u32 + }, + Err(err) => { + u32::max_value() - u32::from(err) + 1 + } + }) } - }, - ext_sandbox_memory_teardown(memory_idx: u32) => { - this.sandbox_store.memory_teardown(memory_idx)?; - Ok(()) - }, - => <'e, E: Externalities + 'e> -); + } +} /// Wasm rust executor for contracts. /// @@ -1327,7 +1338,6 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, pub struct WasmExecutor; impl WasmExecutor { - /// Create a new instance. pub fn new() -> Self { WasmExecutor @@ -1346,8 +1356,9 @@ impl WasmExecutor { method: &str, data: &[u8], ) -> Result> { - let module = ::wasmi::Module::from_buffer(code)?; - let module = Self::instantiate_module::(heap_pages, &module)?; + let module = wasmi::Module::from_buffer(code)?; + let module = Self::instantiate_module(heap_pages, &module)?; + self.call_in_wasm_module(ext, &module, method, data) } @@ -1369,7 +1380,8 @@ impl WasmExecutor { filter_result: FR, ) -> Result { let module = wasmi::Module::from_buffer(code)?; - let module = Self::instantiate_module::(heap_pages, &module)?; + let module = Self::instantiate_module(heap_pages, &module)?; + self.call_in_wasm_module_with_custom_signature( ext, &module, @@ -1398,10 +1410,10 @@ impl WasmExecutor { .ok_or_else(|| Error::HeapBaseNotFoundOrInvalid)? .get(); - Ok(match heap_base_val { - wasmi::RuntimeValue::I32(v) => v as u32, - _ => return Err(Error::HeapBaseNotFoundOrInvalid), - }) + match heap_base_val { + wasmi::RuntimeValue::I32(v) => Ok(v as u32), + _ => Err(Error::HeapBaseNotFoundOrInvalid), + } } /// Call a given method in the given wasm-module runtime. @@ -1454,34 +1466,40 @@ impl WasmExecutor { .and_then(|e| e.as_table().cloned()); let heap_base = Self::get_heap_base(module_instance)?; - let mut fec = FunctionExecutor::new(memory.clone(), heap_base, table, ext)?; + let mut fec = FunctionExecutor::new( + memory.clone(), + heap_base, + table, + )?; + let parameters = create_parameters(&mut |data: &[u8]| { - let offset = fec.heap.allocate(data.len() as u32)?; - memory.set(offset, &data)?; - Ok(offset) + let offset = fec.allocate_memory(data.len() as u32)?; + fec.write_memory(offset, data).map(|_| offset.into()).map_err(Into::into) })?; - let result = module_instance.invoke_export( - method, - ¶meters, - &mut fec + let result = runtime_io::with_externalities( + ext, + || module_instance.invoke_export(method, ¶meters, &mut fec), ); - let result = match result { + + match result { Ok(val) => match filter_result(val, &memory)? { Some(val) => Ok(val), None => Err(Error::InvalidReturn), }, Err(e) => { - trace!(target: "wasm-executor", "Failed to execute code with {} pages", memory.current_size().0); + trace!( + target: "wasm-executor", + "Failed to execute code with {} pages", + memory.current_size().0 + ); Err(e.into()) }, - }; - - result + } } /// Prepare module instance - pub fn instantiate_module>( + pub fn instantiate_module( heap_pages: usize, module: &Module, ) -> Result { @@ -1489,7 +1507,7 @@ impl WasmExecutor { let intermediate_instance = ModuleInstance::new( module, &ImportsBuilder::new() - .with_resolver("env", FunctionExecutor::::resolver()) + .with_resolver("env", FunctionExecutor::resolver()) )?; // Verify that the module has the heap base global variable. @@ -1622,11 +1640,11 @@ mod tests { let test_code = WASM_BINARY; assert_eq!( WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_twox_256", &[]).unwrap(), - hex!("99e9d85137db46ef4bbea33613baafd56f963c64b1f3685a4eb4abd67ff6203a") + hex!("99e9d85137db46ef4bbea33613baafd56f963c64b1f3685a4eb4abd67ff6203a"), ); assert_eq!( WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_twox_256", b"Hello world!").unwrap(), - hex!("b27dfd7f223f177f2a13647b533599af0c07f68bda23d96d059da2b451a35a74") + hex!("b27dfd7f223f177f2a13647b533599af0c07f68bda23d96d059da2b451a35a74"), ); } diff --git a/core/executor/src/wasm_runtimes_cache.rs b/core/executor/src/wasm_runtimes_cache.rs index 57845f8126..fd0ab91503 100644 --- a/core/executor/src/wasm_runtimes_cache.rs +++ b/core/executor/src/wasm_runtimes_cache.rs @@ -282,7 +282,11 @@ impl RuntimesCache { }, Entry::Vacant(v) => { trace!(target: "runtimes_cache", "no instance found in cache, creating now."); - let result = Self::create_wasm_instance(wasm_executor, ext, heap_pages); + let result = Self::create_wasm_instance( + wasm_executor, + ext, + heap_pages, + ); if let Err(ref err) = result { warn!(target: "runtimes_cache", "cannot create a runtime: {:?}", err); } @@ -305,10 +309,10 @@ impl RuntimesCache { // // A return of this error actually indicates that there is a problem in logic, since // we just loaded and validated the `module` above. - let data_segments = extract_data_segments(&code).ok_or(CacheError::CantDeserializeWasm)?; + let data_segments = extract_data_segments(&code)?; // Instantiate this module. - let instance = WasmExecutor::instantiate_module::(heap_pages as usize, &module) + let instance = WasmExecutor::instantiate_module(heap_pages as usize, &module) .map_err(CacheError::Instantiation)?; // Take state snapshot before executing anything. @@ -335,12 +339,14 @@ impl RuntimesCache { /// Extract the data segments from the given wasm code. /// /// Returns `Err` if the given wasm code cannot be deserialized. -fn extract_data_segments(wasm_code: &[u8]) -> Option> { - let raw_module: RawModule = deserialize_buffer(wasm_code).ok()?; +fn extract_data_segments(wasm_code: &[u8]) -> Result, CacheError> { + let raw_module: RawModule = deserialize_buffer(wasm_code) + .map_err(|_| CacheError::CantDeserializeWasm)?; + let segments = raw_module .data_section() .map(|ds| ds.entries()) .unwrap_or(&[]) .to_vec(); - Some(segments) + Ok(segments) } diff --git a/core/executor/src/wasm_utils.rs b/core/executor/src/wasm_utils.rs index 8f38499321..b217350ac6 100644 --- a/core/executor/src/wasm_utils.rs +++ b/core/executor/src/wasm_utils.rs @@ -16,129 +16,94 @@ //! Utilities for defining the wasm host environment. -use wasmi::{ValueType, RuntimeValue}; -use wasmi::nan_preserving_float::{F32, F64}; - -pub trait ConvertibleToWasm { - const VALUE_TYPE: ValueType; - type NativeType; fn to_runtime_value(self) -> RuntimeValue; -} - -impl ConvertibleToWasm for i32 { - type NativeType = i32; - const VALUE_TYPE: ValueType = ValueType::I32; - fn to_runtime_value(self) -> RuntimeValue { RuntimeValue::I32(self) } -} - -impl ConvertibleToWasm for u32 { - type NativeType = u32; - const VALUE_TYPE: ValueType = ValueType::I32; - fn to_runtime_value(self) -> RuntimeValue { RuntimeValue::I32(self as i32) } -} - -impl ConvertibleToWasm for i64 { - type NativeType = i64; - const VALUE_TYPE: ValueType = ValueType::I64; - fn to_runtime_value(self) -> RuntimeValue { RuntimeValue::I64(self) } -} - -impl ConvertibleToWasm for u64 { - type NativeType = u64; - const VALUE_TYPE: ValueType = ValueType::I64; - fn to_runtime_value(self) -> RuntimeValue { RuntimeValue::I64(self as i64) } -} - -impl ConvertibleToWasm for F32 { - type NativeType = F32; - const VALUE_TYPE: ValueType = ValueType::F32; - fn to_runtime_value(self) -> RuntimeValue { RuntimeValue::F32(self) } -} - -impl ConvertibleToWasm for F64 { - type NativeType = F64; - const VALUE_TYPE: ValueType = ValueType::F64; - fn to_runtime_value(self) -> RuntimeValue { RuntimeValue::F64(self) } -} - -impl ConvertibleToWasm for isize { - type NativeType = i32; - const VALUE_TYPE: ValueType = ValueType::I32; - fn to_runtime_value(self) -> RuntimeValue { RuntimeValue::I32(self as i32) } -} - -impl ConvertibleToWasm for usize { - type NativeType = u32; - const VALUE_TYPE: ValueType = ValueType::I32; - fn to_runtime_value(self) -> RuntimeValue { RuntimeValue::I32(self as u32 as i32) } -} - -impl ConvertibleToWasm for *const T { - type NativeType = u32; - const VALUE_TYPE: ValueType = ValueType::I32; - fn to_runtime_value(self) -> RuntimeValue { RuntimeValue::I32(self as isize as i32) } -} - -impl ConvertibleToWasm for *mut T { - type NativeType = u32; - const VALUE_TYPE: ValueType = ValueType::I32; - fn to_runtime_value(self) -> RuntimeValue { RuntimeValue::I32(self as isize as i32) } -} - /// Converts arguments into respective WASM types. #[macro_export] macro_rules! convert_args { () => ([]); - ( $( $t:ty ),* ) => ( [ $( { use $crate::wasm_utils::ConvertibleToWasm; <$t>::VALUE_TYPE }, )* ] ); + ( $( $t:ty ),* ) => ( [ $( <$t as $crate::wasm_interface::IntoValue>::VALUE_TYPE, )* ] ); } /// Generates a WASM signature for given list of parameters. #[macro_export] macro_rules! gen_signature { ( ( $( $params: ty ),* ) ) => ( - { - $crate::wasmi::Signature::new(&convert_args!($($params),*)[..], None) + $crate::wasm_interface::Signature { + args: std::borrow::Cow::Borrowed(&convert_args!( $( $params ),* )[..]), + return_value: None, } ); - - ( ( $( $params: ty ),* ) -> $returns: ty ) => ( - { - $crate::wasmi::Signature::new(&convert_args!($($params),*)[..], Some({ - use $crate::wasm_utils::ConvertibleToWasm; <$returns>::VALUE_TYPE - })) + ( ( $( $params: ty ),* ) -> $returns:ty ) => ( + $crate::wasm_interface::Signature { + args: std::borrow::Cow::Borrowed(&convert_args!( $( $params ),* )[..]), + return_value: Some(<$returns as $crate::wasm_interface::IntoValue>::VALUE_TYPE), } ); } -macro_rules! resolve_fn { - (@iter $index:expr, $sig_var:ident, $name_var:ident) => (); - (@iter $index:expr, $sig_var:ident, $name_var:ident $name:ident ( $( $params:ty ),* ) $( -> $returns:ty )* => $($tail:tt)* ) => ( - if $name_var == stringify!($name) { - let signature = gen_signature!( ( $( $params ),* ) $( -> $returns )* ); - if $sig_var != &signature { - return Err($crate::wasmi::Error::Instantiation( - format!("Export {} has different signature {:?}", $name_var, $sig_var), - )); +macro_rules! gen_functions { + (@INTERNAL + { $( $generated:tt )* } + $context:ident, + ) => ( + &[ $( $generated )* ] + ); + (@INTERNAL + { $( $generated:tt )* } + $context:ident, + $name:ident ( $( $names:ident: $params:ty ),* ) $( -> $returns:ty )? { $( $body:tt )* } + $( $tail:tt )* + ) => ( + gen_functions! { + @INTERNAL + { + $( $generated )* + { + struct $name; + + #[allow(unused)] + impl $crate::wasm_interface::Function for $name { + fn name(&self) -> &str { + stringify!($name) + } + fn signature(&self) -> $crate::wasm_interface::Signature { + gen_signature!( ( $( $params ),* ) $( -> $returns )? ) + } + fn execute( + &self, + context: &mut dyn $crate::wasm_interface::FunctionContext, + args: &mut dyn Iterator, + ) -> ::std::result::Result, String> { + let mut $context = context; + marshall! { + args, + ( $( $names : $params ),* ) $( -> $returns )? => { $( $body )* } + } + } + } + + &$name as &dyn $crate::wasm_interface::Function + }, } - return Ok($crate::wasmi::FuncInstance::alloc_host(signature, $index)); + $context, + $( $tail )* } - resolve_fn!(@iter $index + 1, $sig_var, $name_var $($tail)*) ); - ($sig_var:ident, $name_var:ident, $($tail:tt)* ) => ( - resolve_fn!(@iter 0, $sig_var, $name_var $($tail)*); + ( $context:ident, $( $tail:tt )* ) => ( + gen_functions!(@INTERNAL {} $context, $($tail)*); ); } /// Converts the list of arguments coming from WASM into their native types. #[macro_export] macro_rules! unmarshall_args { - ( $body:tt, $objectname:ident, $args_iter:ident, $( $names:ident : $params:ty ),*) => ({ + ( $body:tt, $args_iter:ident, $( $names:ident : $params:ty ),*) => ({ $( - let $names : <$params as $crate::wasm_utils::ConvertibleToWasm>::NativeType = + let $names : $params = $args_iter.next() - .and_then(|rt_val| rt_val.try_into()) + .and_then(|val| <$params as $crate::wasm_interface::TryFromValue>::try_from_value(val)) .expect( - "`$args_iter` comes from an argument of Externals::invoke_index; + "`$args_iter` comes from an argument of Externals::execute_function; args to an external call always matches the signature of the external; external signatures are built with count and types and in order defined by `$params`; here, we iterating on `$params`; @@ -160,7 +125,7 @@ macro_rules! unmarshall_args { #[inline(always)] pub fn constrain_closure(f: F) -> F where - F: FnOnce() -> Result + F: FnOnce() -> Result { f } @@ -168,103 +133,40 @@ where /// Pass the list of parameters by converting them to respective WASM types. #[macro_export] macro_rules! marshall { - ( $args_iter:ident, $objectname:ident, ( $( $names:ident : $params:ty ),* ) -> $returns:ty => $body:tt ) => ({ - let body = $crate::wasm_utils::constrain_closure::< - <$returns as $crate::wasm_utils::ConvertibleToWasm>::NativeType, _ - >(|| { - unmarshall_args!($body, $objectname, $args_iter, $( $names : $params ),*) + ( $args_iter:ident, ( $( $names:ident : $params:ty ),* ) -> $returns:ty => $body:tt ) => ({ + let body = $crate::wasm_utils::constrain_closure::<$returns, _>(|| { + unmarshall_args!($body, $args_iter, $( $names : $params ),*) }); - let r = body().map_err(wasmi::Trap::from)?; - return Ok(Some({ use $crate::wasm_utils::ConvertibleToWasm; r.to_runtime_value() })) + let r = body()?; + return Ok(Some($crate::wasm_interface::IntoValue::into_value(r))) }); - ( $args_iter:ident, $objectname:ident, ( $( $names:ident : $params:ty ),* ) => $body:tt ) => ({ + ( $args_iter:ident, ( $( $names:ident : $params:ty ),* ) => $body:tt ) => ({ let body = $crate::wasm_utils::constrain_closure::<(), _>(|| { - unmarshall_args!($body, $objectname, $args_iter, $( $names : $params ),*) + unmarshall_args!($body, $args_iter, $( $names : $params ),*) }); - body().map_err(wasmi::Trap::from)?; + body()?; return Ok(None) }) } -macro_rules! dispatch_fn { - ( @iter $index:expr, $index_ident:ident, $objectname:ident, $args_iter:ident) => { - // `$index` comes from an argument of Externals::invoke_index; - // externals are always invoked with index given by resolve_fn! at resolve time; - // For each next function resolve_fn! gives new index, starting from 0; - // Both dispatch_fn! and resolve_fn! are called with the same list of functions; - // qed; - panic!("fn with index {} is undefined", $index); - }; - - (@iter - $index:expr, - $index_ident:ident, - $objectname:ident, - $args_iter:ident, - $name:ident ( $( $names:ident : $params:ty ),* ) $( -> $returns:ty )* => $body:tt $($tail:tt)* - ) => ( - if $index_ident == $index { - { marshall!($args_iter, $objectname, ( $( $names : $params ),* ) $( -> $returns )* => $body) } - } - dispatch_fn!( @iter $index + 1, $index_ident, $objectname, $args_iter $($tail)*) - ); - - ( $index_ident:ident, $objectname:ident, $args_iter:ident, $($tail:tt)* ) => ( - dispatch_fn!( @iter 0, $index_ident, $objectname, $args_iter, $($tail)*); - ); -} - -/// Implements `wasmi::Externals` trait and `Resolver` for given struct. +/// Implements the wasm host interface for the given type. #[macro_export] -macro_rules! impl_function_executor { +macro_rules! impl_wasm_host_interface { ( - $objectname:ident : $structname:ty, - $( - $name:ident - ( $( $names:ident : $params:ty ),* $(,)? ) - $( -> $returns:ty )? => { $( $body:tt )* }, - )* - => $( $pre:tt )+ - ) => ( - impl $( $pre ) + $structname { - #[allow(unused)] - fn resolver() -> &'static dyn $crate::wasmi::ModuleImportResolver { - struct Resolver; - impl $crate::wasmi::ModuleImportResolver for Resolver { - fn resolve_func( - &self, - name: &str, - signature: &$crate::wasmi::Signature - ) -> std::result::Result<$crate::wasmi::FuncRef, $crate::wasmi::Error> { - resolve_fn!( - signature, - name, - $( $name( $( $params ),* ) $( -> $returns )? => )* - ); - - Err($crate::wasmi::Error::Instantiation( - format!("Export {} not found", name), - )) - } - } - &Resolver - } + impl $interface_name:ident where $context:ident { + $( + $name:ident($( $names:ident : $params:ty ),* $(,)? ) $( -> $returns:ty )? + { $( $body:tt )* } + )* } - - impl $( $pre ) + $crate::wasmi::Externals for $structname { - fn invoke_index( - &mut self, - index: usize, - args: $crate::wasmi::RuntimeArgs, - ) -> std::result::Result, $crate::wasmi::Trap> { - let $objectname = self; - let mut args = args.as_ref().iter(); - dispatch_fn! { - index, - $objectname, - args, - $( $name( $( $names : $params ),* ) $( -> $returns )? => { $( $body )* } ),* - }; + ) => ( + impl $crate::wasm_interface::HostFunctions for $interface_name { + #[allow(non_camel_case_types)] + fn functions() -> &'static [&'static dyn $crate::wasm_interface::Function] { + gen_functions!( + $context, + $( $name( $( $names: $params ),* ) $( -> $returns )? { $( $body )* } )* + ) } } ); diff --git a/core/sr-io/src/lib.rs b/core/sr-io/src/lib.rs index de5c48f5fe..642b3e4881 100644 --- a/core/sr-io/src/lib.rs +++ b/core/sr-io/src/lib.rs @@ -279,7 +279,7 @@ export_api! { /// Submit transaction to the pool. /// /// The transaction will end up in the pool. - fn submit_transaction(data: &T) -> Result<(), ()>; + fn submit_transaction(data: Vec) -> Result<(), ()>; /// Returns information about the local node's network state. fn network_state() -> Result; diff --git a/core/sr-io/with_std.rs b/core/sr-io/with_std.rs index acbeb8ce0e..cee17a5bdd 100644 --- a/core/sr-io/with_std.rs +++ b/core/sr-io/with_std.rs @@ -334,9 +334,9 @@ impl OffchainApi for () { }, "is_validator can be called only in the offchain worker context") } - fn submit_transaction(data: &T) -> Result<(), ()> { + fn submit_transaction(data: Vec) -> Result<(), ()> { with_offchain(|ext| { - ext.submit_transaction(codec::Encode::encode(data)) + ext.submit_transaction(data) }, "submit_transaction can be called only in the offchain worker context") } diff --git a/core/sr-io/without_std.rs b/core/sr-io/without_std.rs index 58aff2444e..d6ad3e1434 100644 --- a/core/sr-io/without_std.rs +++ b/core/sr-io/without_std.rs @@ -47,7 +47,7 @@ pub fn panic(info: &PanicInfo) -> ! { #[cfg(not(feature = "no_oom"))] #[alloc_error_handler] -pub extern fn oom(_: ::core::alloc::Layout) -> ! { +pub extern fn oom(_: core::alloc::Layout) -> ! { static OOM_MSG: &str = "Runtime memory exhausted. Aborting"; unsafe { @@ -980,10 +980,9 @@ impl OffchainApi for () { unsafe { ext_is_validator.get()() == 1 } } - fn submit_transaction(data: &T) -> Result<(), ()> { - let encoded_data = codec::Encode::encode(data); + fn submit_transaction(data: Vec) -> Result<(), ()> { let ret = unsafe { - ext_submit_transaction.get()(encoded_data.as_ptr(), encoded_data.len() as u32) + ext_submit_transaction.get()(data.as_ptr(), data.len() as u32) }; if ret == 0 { diff --git a/core/sr-std/without_std.rs b/core/sr-std/without_std.rs index 327e271049..845ea79aa4 100755 --- a/core/sr-std/without_std.rs +++ b/core/sr-std/without_std.rs @@ -19,7 +19,7 @@ pub extern crate alloc; extern "C" { - fn ext_malloc(size: usize) -> *mut u8; + fn ext_malloc(size: u32) -> *mut u8; fn ext_free(ptr: *mut u8); } @@ -37,7 +37,7 @@ mod __impl { unsafe impl GlobalAlloc for WasmAllocator { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - super::ext_malloc(layout.size()) as *mut u8 + super::ext_malloc(layout.size() as u32) as *mut u8 } unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { diff --git a/core/test-runtime/src/lib.rs b/core/test-runtime/src/lib.rs index ec7ed9670c..aa0b57ec92 100644 --- a/core/test-runtime/src/lib.rs +++ b/core/test-runtime/src/lib.rs @@ -629,7 +629,7 @@ cfg_if! { impl offchain_primitives::OffchainWorkerApi for Runtime { fn offchain_worker(block: u64) { let ex = Extrinsic::IncludeData(block.encode()); - runtime_io::submit_transaction(&ex).unwrap(); + runtime_io::submit_transaction(ex.encode()).unwrap(); } } @@ -844,7 +844,7 @@ cfg_if! { impl offchain_primitives::OffchainWorkerApi for Runtime { fn offchain_worker(block: u64) { let ex = Extrinsic::IncludeData(block.encode()); - runtime_io::submit_transaction(&ex).unwrap() + runtime_io::submit_transaction(ex.encode()).unwrap() } } diff --git a/core/wasm-interface/Cargo.toml b/core/wasm-interface/Cargo.toml new file mode 100644 index 0000000000..c388b32930 --- /dev/null +++ b/core/wasm-interface/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "substrate-wasm-interface" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +wasmi = "0.5.0" diff --git a/core/wasm-interface/src/lib.rs b/core/wasm-interface/src/lib.rs new file mode 100644 index 0000000000..b3cbde556e --- /dev/null +++ b/core/wasm-interface/src/lib.rs @@ -0,0 +1,324 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Types and traits for interfacing between the host and the wasm runtime. + +use std::{borrow::Cow, marker::PhantomData, mem, iter::Iterator, result}; + +mod wasmi_impl; + +/// Result type used by traits in this crate. +pub type Result = result::Result; + +/// Value types supported by Substrate on the boundary between host/Wasm. +#[derive(Copy, Clone, PartialEq, Debug, Eq)] +pub enum ValueType { + /// An `i32` value type. + I32, + /// An `i64` value type. + I64, + /// An `f32` value type. + F32, + /// An `f64` value type. + F64, +} + +/// Values supported by Substrate on the boundary between host/Wasm. +#[derive(PartialEq, Debug, Clone, Copy)] +pub enum Value { + /// An `i32` value. + I32(i32), + /// An `i64` value. + I64(i64), + /// An nan-preserving `f32` value. + F32(u32), + /// An nan-preserving `f64` value. + F64(u64), +} + +/// Provides `Sealed` trait to prevent implementing trait `PointerType` outside of this crate. +mod private { + pub trait Sealed {} + + impl Sealed for u8 {} + impl Sealed for u16 {} + impl Sealed for u32 {} + impl Sealed for u64 {} +} + +/// Something that can be wrapped in a wasm `Pointer`. +/// +/// This trait is sealed. +pub trait PointerType: Sized { + /// The size of the type in wasm. + const SIZE: u32 = mem::size_of::() as u32; +} + +impl PointerType for u8 {} +impl PointerType for u16 {} +impl PointerType for u32 {} +impl PointerType for u64 {} + +/// Type to represent a pointer in wasm at the host. +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub struct Pointer { + ptr: u32, + _marker: PhantomData, +} + +impl Pointer { + /// Create a new instance of `Self`. + pub fn new(ptr: u32) -> Self { + Self { + ptr, + _marker: Default::default(), + } + } + + /// Calculate the offset from this pointer. + /// + /// `offset` is in units of `T`. So, `3` means `3 * mem::size_of::()` as offset to the pointer. + /// + /// Returns an `Option` to respect that the pointer could probably overflow. + pub fn offset(self, offset: u32) -> Option { + offset.checked_mul(T::SIZE).and_then(|o| self.ptr.checked_add(o)).map(|ptr| { + Self { + ptr, + _marker: Default::default(), + } + }) + } + + /// Create a null pointer. + pub fn null() -> Self { + Self::new(0) + } + + /// Cast this pointer of type `T` to a pointer of type `R`. + pub fn cast(self) -> Pointer { + Pointer::new(self.ptr) + } +} + +impl From> for u32 { + fn from(ptr: Pointer) -> Self { + ptr.ptr + } +} + +impl From> for usize { + fn from(ptr: Pointer) -> Self { + ptr.ptr as _ + } +} + +impl IntoValue for Pointer { + const VALUE_TYPE: ValueType = ValueType::I32; + fn into_value(self) -> Value { Value::I32(self.ptr as _) } +} + +impl TryFromValue for Pointer { + fn try_from_value(val: Value) -> Option { + match val { + Value::I32(val) => Some(Self::new(val as _)), + _ => None, + } + } +} + +/// The word size used in wasm. Normally known as `usize` in Rust. +pub type WordSize = u32; + +/// The Signature of a function +#[derive(Eq, PartialEq, Debug, Clone)] +pub struct Signature { + /// The arguments of a function. + pub args: Cow<'static, [ValueType]>, + /// The optional return value of a function. + pub return_value: Option, +} + +impl Signature { + /// Create a new instance of `Signature`. + pub fn new>>(args: T, return_value: Option) -> Self { + Self { + args: args.into(), + return_value, + } + } + + /// Create a new instance of `Signature` with the given `args` and without any return value. + pub fn new_with_args>>(args: T) -> Self { + Self { + args: args.into(), + return_value: None, + } + } + +} + +/// Something that provides a function implementation on the host for a wasm function. +pub trait Function { + /// Returns the name of this function. + fn name(&self) -> &str; + /// Returns the signature of this function. + fn signature(&self) -> Signature; + /// Execute this function with the given arguments. + fn execute( + &self, + context: &mut dyn FunctionContext, + args: &mut dyn Iterator, + ) -> Result>; +} + +/// Context used by `Function` to interact with the allocator and the memory of the wasm instance. +pub trait FunctionContext { + /// Read memory from `address` into a vector. + fn read_memory(&self, address: Pointer, size: WordSize) -> Result> { + let mut vec = Vec::with_capacity(size as usize); + vec.resize(size as usize, 0); + self.read_memory_into(address, &mut vec)?; + Ok(vec) + } + /// Read memory into the given `dest` buffer from `address`. + fn read_memory_into(&self, address: Pointer, dest: &mut [u8]) -> Result<()>; + /// Write the given data at `address` into the memory. + fn write_memory(&mut self, address: Pointer, data: &[u8]) -> Result<()>; + /// Allocate a memory instance of `size` bytes. + fn allocate_memory(&mut self, size: WordSize) -> Result>; + /// Deallocate a given memory instance. + fn deallocate_memory(&mut self, ptr: Pointer) -> Result<()>; + /// Provides access to the sandbox. + fn sandbox(&mut self) -> &mut dyn Sandbox; +} + +/// Sandbox memory identifier. +pub type MemoryId = u32; + +/// Something that provides access to the sandbox. +pub trait Sandbox { + /// Get sandbox memory from the `memory_id` instance at `offset` into the given buffer. + fn memory_get( + &self, + memory_id: MemoryId, + offset: WordSize, + buf_ptr: Pointer, + buf_len: WordSize, + ) -> Result; + /// Set sandbox memory from the given value. + fn memory_set( + &mut self, + memory_id: MemoryId, + offset: WordSize, + val_ptr: Pointer, + val_len: WordSize, + ) -> Result; + /// Delete a memory instance. + fn memory_teardown(&mut self, memory_id: MemoryId) -> Result<()>; + /// Create a new memory instance with the given `initial` size and the `maximum` size. + /// The size is given in wasm pages. + fn memory_new(&mut self, initial: u32, maximum: u32) -> Result; + /// Invoke an exported function by a name. + fn invoke( + &mut self, + instance_id: u32, + export_name: &str, + args: &[u8], + return_val: Pointer, + return_val_len: WordSize, + state: u32, + ) -> Result; + /// Delete a sandbox instance. + fn instance_teardown(&mut self, instance_id: u32) -> Result<()>; + /// Create a new sandbox instance. + fn instance_new( + &mut self, + dispatch_thunk_id: u32, + wasm: &[u8], + raw_env_def: &[u8], + state: u32, + ) -> Result; +} + +/// Something that provides implementations for host functions. +pub trait HostFunctions { + /// Returns all host functions. + fn functions() -> &'static [&'static dyn Function]; +} + +/// Something that can be converted into a wasm compatible `Value`. +pub trait IntoValue { + /// The type of the value in wasm. + const VALUE_TYPE: ValueType; + + /// Convert `self` into a wasm `Value`. + fn into_value(self) -> Value; +} + +/// Something that can may be created from a wasm `Value`. +pub trait TryFromValue: Sized { + /// Try to convert the given `Value` into `Self`. + fn try_from_value(val: Value) -> Option; +} + +macro_rules! impl_into_and_from_value { + ( + $( + $type:ty, $( < $gen:ident >, )? $value_variant:ident, + )* + ) => { + $( + impl $( <$gen> )? IntoValue for $type { + const VALUE_TYPE: ValueType = ValueType::$value_variant; + fn into_value(self) -> Value { Value::$value_variant(self as _) } + } + + impl $( <$gen> )? TryFromValue for $type { + fn try_from_value(val: Value) -> Option { + match val { + Value::$value_variant(val) => Some(val as _), + _ => None, + } + } + } + )* + } +} + +impl_into_and_from_value! { + u32, I32, + i32, I32, + u64, I64, + i64, I64, +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn pointer_offset_works() { + let ptr = Pointer::::null(); + + assert_eq!(ptr.offset(10).unwrap(), Pointer::new(40)); + assert_eq!(ptr.offset(32).unwrap(), Pointer::new(128)); + + let ptr = Pointer::::null(); + + assert_eq!(ptr.offset(10).unwrap(), Pointer::new(80)); + assert_eq!(ptr.offset(32).unwrap(), Pointer::new(256)); + } +} diff --git a/core/wasm-interface/src/wasmi_impl.rs b/core/wasm-interface/src/wasmi_impl.rs new file mode 100644 index 0000000000..be9b724d29 --- /dev/null +++ b/core/wasm-interface/src/wasmi_impl.rs @@ -0,0 +1,79 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Implementation of conversions between Substrate and wasmi types. + +use crate::{Value, ValueType, Signature}; + +impl From for wasmi::RuntimeValue { + fn from(value: Value) -> Self { + match value { + Value::I32(val) => Self::I32(val), + Value::I64(val) => Self::I64(val), + Value::F32(val) => Self::F32(val.into()), + Value::F64(val) => Self::F64(val.into()), + } + } +} + +impl From for Value { + fn from(value: wasmi::RuntimeValue) -> Self { + match value { + wasmi::RuntimeValue::I32(val) => Self::I32(val), + wasmi::RuntimeValue::I64(val) => Self::I64(val), + wasmi::RuntimeValue::F32(val) => Self::F32(val.into()), + wasmi::RuntimeValue::F64(val) => Self::F64(val.into()), + } + } +} + +impl From for wasmi::ValueType { + fn from(value: ValueType) -> Self { + match value { + ValueType::I32 => Self::I32, + ValueType::I64 => Self::I64, + ValueType::F32 => Self::F32, + ValueType::F64 => Self::F64, + } + } +} + +impl From for ValueType { + fn from(value: wasmi::ValueType) -> Self { + match value { + wasmi::ValueType::I32 => Self::I32, + wasmi::ValueType::I64 => Self::I64, + wasmi::ValueType::F32 => Self::F32, + wasmi::ValueType::F64 => Self::F64, + } + } +} + +impl From for wasmi::Signature { + fn from(sig: Signature) -> Self { + let args = sig.args.iter().map(|a| (*a).into()).collect::>(); + wasmi::Signature::new(args, sig.return_value.map(Into::into)) + } +} + +impl From<&wasmi::Signature> for Signature { + fn from(sig: &wasmi::Signature) -> Self { + Signature::new( + sig.params().into_iter().copied().map(Into::into).collect::>(), + sig.return_type().map(Into::into), + ) + } +} diff --git a/node-template/src/service.rs b/node-template/src/service.rs index e3c3c670a0..310b8f44a7 100644 --- a/node-template/src/service.rs +++ b/node-template/src/service.rs @@ -18,7 +18,7 @@ pub use substrate_executor::NativeExecutor; native_executor_instance!( pub Executor, node_template_runtime::api::dispatch, - node_template_runtime::native_version + node_template_runtime::native_version, ); construct_simple_protocol! { diff --git a/srml/system/src/offchain.rs b/srml/system/src/offchain.rs index d67598f64f..e234c74c08 100644 --- a/srml/system/src/offchain.rs +++ b/srml/system/src/offchain.rs @@ -82,7 +82,7 @@ pub trait SubmitSignedTransaction { ::create_transaction::(call, id, expected) .ok_or(())?; let xt = Self::Extrinsic::new(call, Some(signature_data)).ok_or(())?; - runtime_io::submit_transaction(&xt) + runtime_io::submit_transaction(xt.encode()) } } @@ -97,7 +97,7 @@ pub trait SubmitUnsignedTransaction { /// and `Err` if transaction was rejected from the pool. fn submit_unsigned(call: impl Into) -> Result<(), ()> { let xt = Self::Extrinsic::new(call.into(), None).ok_or(())?; - runtime_io::submit_transaction(&xt) + runtime_io::submit_transaction(xt.encode()) } } -- GitLab From e18ab47db60a06100b5bde7bed407571d949e6c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 10 Sep 2019 16:15:32 +0200 Subject: [PATCH 073/275] Don't initialize block for offchain workers. (#3578) --- core/offchain/primitives/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/core/offchain/primitives/src/lib.rs b/core/offchain/primitives/src/lib.rs index d51239483a..dda08ae43f 100644 --- a/core/offchain/primitives/src/lib.rs +++ b/core/offchain/primitives/src/lib.rs @@ -26,6 +26,7 @@ decl_runtime_apis! { /// The offchain worker api. pub trait OffchainWorkerApi { /// Starts the off-chain task for given block number. + #[skip_initialize_block] fn offchain_worker(number: NumberFor); } } -- GitLab From c768a7e4c70eccf77f62ca16980c6c0b5aece443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 10 Sep 2019 17:00:00 +0200 Subject: [PATCH 074/275] Cleanup of the `state-machine` crate (#3524) * Start refactoring state-machine crate * More improvement to state-machine * Fix tests compilation on master and remove warnings * Fix compilation * Apply suggestions from code review Co-Authored-By: Sergei Pepyakin * Update core/state-machine/src/basic.rs Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> * Line width * Update core/primitives/src/storage.rs Co-Authored-By: Benjamin Kampmann * Update core/state-machine/src/error.rs Co-Authored-By: Benjamin Kampmann * Review feedback --- core/client/db/src/lib.rs | 10 +- core/client/src/backend.rs | 2 +- core/client/src/call_executor.rs | 18 +- core/client/src/client.rs | 16 +- core/client/src/error.rs | 4 +- core/client/src/genesis.rs | 35 +- core/client/src/lib.rs | 2 +- core/client/src/light/call_executor.rs | 28 +- core/client/src/light/fetcher.rs | 9 +- core/client/src/light/mod.rs | 3 +- core/executor/Cargo.toml | 2 +- core/executor/src/error.rs | 3 - core/executor/src/lib.rs | 3 +- core/executor/src/native_executor.rs | 7 +- core/executor/src/wasm_executor.rs | 4 +- core/executor/src/wasm_runtimes_cache.rs | 8 +- core/finality-grandpa/src/finality_proof.rs | 11 +- core/primitives/src/child_storage_key.rs | 68 ++ core/primitives/src/lib.rs | 1 + core/primitives/src/offchain.rs | 106 +++ core/primitives/src/storage.rs | 18 + core/primitives/src/traits.rs | 137 +++- core/rpc/src/state/state_full.rs | 4 +- core/sr-io/with_std.rs | 7 +- core/sr-io/without_std.rs | 1 - core/sr-std/without_std.rs | 6 +- core/state-machine/src/backend.rs | 66 +- core/state-machine/src/basic.rs | 30 +- core/state-machine/src/error.rs | 47 ++ core/state-machine/src/ext.rs | 33 +- core/state-machine/src/lib.rs | 674 ++++++-------------- core/state-machine/src/overlayed_changes.rs | 9 +- core/state-machine/src/proving_backend.rs | 20 +- core/state-machine/src/testing.rs | 27 +- core/state-machine/src/trie_backend.rs | 2 - core/trie/src/lib.rs | 19 - node/executor/src/lib.rs | 15 +- 37 files changed, 781 insertions(+), 674 deletions(-) create mode 100644 core/primitives/src/child_storage_key.rs create mode 100644 core/state-machine/src/error.rs diff --git a/core/client/db/src/lib.rs b/core/client/db/src/lib.rs index f5ece21fbb..722309b415 100644 --- a/core/client/db/src/lib.rs +++ b/core/client/db/src/lib.rs @@ -47,18 +47,20 @@ use hash_db::{Hasher, Prefix}; use kvdb::{KeyValueDB, DBTransaction}; use trie::{MemoryDB, PrefixedMemoryDB, prefixed_key}; use parking_lot::{Mutex, RwLock}; -use primitives::{H256, Blake2Hasher, ChangesTrieConfiguration, convert_hash}; +use primitives::{H256, Blake2Hasher, ChangesTrieConfiguration, convert_hash, traits::CodeExecutor}; use primitives::storage::well_known_keys; use sr_primitives::{ generic::{BlockId, DigestItem}, Justification, StorageOverlay, ChildrenStorageOverlay, - BuildStorage + BuildStorage, }; use sr_primitives::traits::{ Block as BlockT, Header as HeaderT, NumberFor, Zero, One, SaturatedConversion }; -use state_machine::backend::Backend as StateBackend; use executor::RuntimeInfo; -use state_machine::{CodeExecutor, DBValue, ChangesTrieTransaction, ChangesTrieCacheAction, ChangesTrieBuildCache}; +use state_machine::{ + DBValue, ChangesTrieTransaction, ChangesTrieCacheAction, ChangesTrieBuildCache, + backend::Backend as StateBackend, +}; use crate::utils::{Meta, db_err, meta_keys, read_db, block_id_to_lookup_key, read_meta}; use client::leaves::{LeafSet, FinalizationDisplaced}; use client::children; diff --git a/core/client/src/backend.rs b/core/client/src/backend.rs index ad683ebac1..e7b5045336 100644 --- a/core/client/src/backend.rs +++ b/core/client/src/backend.rs @@ -144,7 +144,7 @@ pub trait Finalizer, B: Backend error::Result<()>; - + /// Finalize a block. This will implicitly finalize all blocks up to it and /// fire finality notifications. /// diff --git a/core/client/src/call_executor.rs b/core/client/src/call_executor.rs index 0556bc7bff..b49a58a0e5 100644 --- a/core/client/src/call_executor.rs +++ b/core/client/src/call_executor.rs @@ -20,13 +20,15 @@ use sr_primitives::{ generic::BlockId, traits::Block as BlockT, traits::NumberFor, }; use state_machine::{ - self, OverlayedChanges, Ext, CodeExecutor, ExecutionManager, - ExecutionStrategy, NeverOffchainExt, backend::Backend as _, - ChangesTrieTransaction, + self, OverlayedChanges, Ext, ExecutionManager, StateMachine, ExecutionStrategy, + backend::Backend as _, ChangesTrieTransaction, }; use executor::{RuntimeVersion, RuntimeInfo, NativeVersion}; use hash_db::Hasher; -use primitives::{offchain, H256, Blake2Hasher, NativeOrEncoded, NeverNativeValue}; +use primitives::{ + offchain::{self, NeverOffchainExt}, H256, Blake2Hasher, NativeOrEncoded, NeverNativeValue, + traits::CodeExecutor, +}; use crate::runtime_api::{ProofRecorder, InitializeBlock}; use crate::backend; @@ -204,7 +206,7 @@ where ) -> error::Result> { let mut changes = OverlayedChanges::default(); let state = self.backend.state_at(*id)?; - let return_data = state_machine::new( + let return_data = StateMachine::new( &state, self.backend.changes_trie_storage(), side_effects_handler, @@ -277,7 +279,7 @@ where recorder.clone() ); - state_machine::new( + StateMachine::new( &backend, self.backend.changes_trie_storage(), side_effects_handler, @@ -295,7 +297,7 @@ where .map(|(result, _, _)| result) .map_err(Into::into) } - None => state_machine::new( + None => StateMachine::new( &state, self.backend.changes_trie_storage(), side_effects_handler, @@ -354,7 +356,7 @@ where (S::Transaction, ::Out), Option>>, )> { - state_machine::new( + StateMachine::new( state, self.backend.changes_trie_storage(), side_effects_handler, diff --git a/core/client/src/client.rs b/core/client/src/client.rs index 90cdff9fa8..c7df30d8ae 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -26,10 +26,9 @@ use parking_lot::{Mutex, RwLock}; use codec::{Encode, Decode}; use hash_db::{Hasher, Prefix}; use primitives::{ - Blake2Hasher, H256, ChangesTrieConfiguration, convert_hash, - NeverNativeValue, ExecutionContext, NativeOrEncoded, - storage::{StorageKey, StorageData, well_known_keys}, - offchain, + Blake2Hasher, H256, ChangesTrieConfiguration, convert_hash, NeverNativeValue, ExecutionContext, + NativeOrEncoded, storage::{StorageKey, StorageData, well_known_keys}, + offchain::{NeverOffchainExt, self}, traits::CodeExecutor, }; use substrate_telemetry::{telemetry, SUBSTRATE_INFO}; use sr_primitives::{ @@ -41,11 +40,10 @@ use sr_primitives::{ }, }; use state_machine::{ - DBValue, Backend as StateBackend, CodeExecutor, ChangesTrieAnchorBlockId, - ExecutionStrategy, ExecutionManager, prove_read, prove_child_read, - ChangesTrieRootsStorage, ChangesTrieStorage, - ChangesTrieTransaction, ChangesTrieConfigurationRange, - key_changes, key_changes_proof, OverlayedChanges, NeverOffchainExt, + DBValue, Backend as StateBackend, ChangesTrieAnchorBlockId, ExecutionStrategy, ExecutionManager, + prove_read, prove_child_read, ChangesTrieRootsStorage, ChangesTrieStorage, + ChangesTrieTransaction, ChangesTrieConfigurationRange, key_changes, key_changes_proof, + OverlayedChanges, }; use executor::{RuntimeVersion, RuntimeInfo}; use consensus::{ diff --git a/core/client/src/error.rs b/core/client/src/error.rs index 6f087df9de..922d122b42 100644 --- a/core/client/src/error.rs +++ b/core/client/src/error.rs @@ -131,9 +131,7 @@ impl Error { } /// Chain a state error. - pub fn from_state(e: Box) -> Self { + pub fn from_state(e: Box) -> Self { Error::Execution(e) } } - -impl state_machine::Error for Error {} diff --git a/core/client/src/genesis.rs b/core/client/src/genesis.rs index 88529114e2..2f31462955 100644 --- a/core/client/src/genesis.rs +++ b/core/client/src/genesis.rs @@ -24,7 +24,10 @@ pub fn construct_genesis_block< > ( state_root: Block::Hash ) -> Block { - let extrinsics_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root(::std::iter::empty::<(&[u8], &[u8])>()); + let extrinsics_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( + std::iter::empty::<(&[u8], &[u8])>(), + ); + Block::new( <::Header as HeaderT>::new( Zero::zero(), @@ -41,14 +44,16 @@ pub fn construct_genesis_block< mod tests { use codec::{Encode, Decode, Joiner}; use executor::native_executor_instance; - use state_machine::{self, OverlayedChanges, ExecutionStrategy, InMemoryChangesTrieStorage}; + use state_machine::{ + StateMachine, OverlayedChanges, ExecutionStrategy, InMemoryChangesTrieStorage, + }; use state_machine::backend::InMemory; use test_client::{ runtime::genesismap::{GenesisConfig, insert_genesis_block}, runtime::{Hash, Transfer, Block, BlockNumber, Header, Digest}, AccountKeyring, Sr25519Keyring, }; - use primitives::{Blake2Hasher, map}; + use primitives::{Blake2Hasher, map, offchain::NeverOffchainExt}; use hex::*; native_executor_instance!( @@ -85,10 +90,10 @@ mod tests { let hash = header.hash(); let mut overlay = OverlayedChanges::default(); - state_machine::new( + StateMachine::new( backend, Some(&InMemoryChangesTrieStorage::<_, u64>::new()), - state_machine::NeverOffchainExt::new(), + NeverOffchainExt::new(), &mut overlay, &executor(), "Core_initialize_block", @@ -99,10 +104,10 @@ mod tests { ).unwrap(); for tx in transactions.iter() { - state_machine::new( + StateMachine::new( backend, Some(&InMemoryChangesTrieStorage::<_, u64>::new()), - state_machine::NeverOffchainExt::new(), + NeverOffchainExt::new(), &mut overlay, &executor(), "BlockBuilder_apply_extrinsic", @@ -113,10 +118,10 @@ mod tests { ).unwrap(); } - let (ret_data, _, _) = state_machine::new( + let (ret_data, _, _) = StateMachine::new( backend, Some(&InMemoryChangesTrieStorage::<_, u64>::new()), - state_machine::NeverOffchainExt::new(), + NeverOffchainExt::new(), &mut overlay, &executor(), "BlockBuilder_finalize_block", @@ -161,10 +166,10 @@ mod tests { let (b1data, _b1hash) = block1(genesis_hash, &backend); let mut overlay = OverlayedChanges::default(); - let _ = state_machine::new( + let _ = StateMachine::new( &backend, Some(&InMemoryChangesTrieStorage::<_, u64>::new()), - state_machine::NeverOffchainExt::new(), + NeverOffchainExt::new(), &mut overlay, &executor(), "Core_execute_block", @@ -191,10 +196,10 @@ mod tests { let (b1data, _b1hash) = block1(genesis_hash, &backend); let mut overlay = OverlayedChanges::default(); - let _ = state_machine::new( + let _ = StateMachine::new( &backend, Some(&InMemoryChangesTrieStorage::<_, u64>::new()), - state_machine::NeverOffchainExt::new(), + NeverOffchainExt::new(), &mut overlay, &executor(), "Core_execute_block", @@ -221,10 +226,10 @@ mod tests { let (b1data, _b1hash) = block1(genesis_hash, &backend); let mut overlay = OverlayedChanges::default(); - let r = state_machine::new( + let r = StateMachine::new( &backend, Some(&InMemoryChangesTrieStorage::<_, u64>::new()), - state_machine::NeverOffchainExt::new(), + NeverOffchainExt::new(), &mut overlay, &executor(), "Core_execute_block", diff --git a/core/client/src/lib.rs b/core/client/src/lib.rs index 1313b8b80e..3919b3970f 100644 --- a/core/client/src/lib.rs +++ b/core/client/src/lib.rs @@ -121,7 +121,7 @@ pub use crate::client::{ #[cfg(feature = "std")] pub use crate::notifications::{StorageEventStream, StorageChangeSet}; #[cfg(feature = "std")] -pub use state_machine::{ExecutionStrategy, NeverOffchainExt}; +pub use state_machine::ExecutionStrategy; #[cfg(feature = "std")] pub use crate::leaves::LeafSet; diff --git a/core/client/src/light/call_executor.rs b/core/client/src/light/call_executor.rs index fd6ae68e8e..370b6054e6 100644 --- a/core/client/src/light/call_executor.rs +++ b/core/client/src/light/call_executor.rs @@ -23,13 +23,15 @@ use std::{ }; use codec::{Encode, Decode}; -use primitives::{offchain, H256, Blake2Hasher, convert_hash, NativeOrEncoded}; +use primitives::{ + offchain::{self, NeverOffchainExt}, H256, Blake2Hasher, convert_hash, NativeOrEncoded, + traits::CodeExecutor, +}; use sr_primitives::generic::BlockId; use sr_primitives::traits::{One, Block as BlockT, Header as HeaderT, NumberFor}; use state_machine::{ - self, Backend as StateBackend, CodeExecutor, OverlayedChanges, - ExecutionStrategy, ChangesTrieTransaction, create_proof_check_backend, - execution_proof_check_on_trie_backend, ExecutionManager, NeverOffchainExt + self, Backend as StateBackend, OverlayedChanges, ExecutionStrategy, create_proof_check_backend, + execution_proof_check_on_trie_backend, ExecutionManager, ChangesTrieTransaction, }; use hash_db::Hasher; @@ -451,7 +453,7 @@ pub fn prove_execution( pub fn check_execution_proof( executor: &E, request: &RemoteCallRequest

, - remote_proof: Vec> + remote_proof: Vec>, ) -> ClientResult> where Header: HeaderT, @@ -482,16 +484,14 @@ pub fn check_execution_proof( )?; // execute method - let local_result = execution_proof_check_on_trie_backend::( + execution_proof_check_on_trie_backend::( &trie_backend, &mut changes, executor, &request.method, &request.call_data, None, - )?; - - Ok(local_result) + ).map_err(Into::into) } #[cfg(test)] @@ -568,8 +568,14 @@ mod tests { backend.blockchain().insert(hash0, header0, None, None, NewBlockState::Final).unwrap(); backend.blockchain().insert(hash1, header1, None, None, NewBlockState::Final).unwrap(); - let local_executor = RemoteCallExecutor::new(Arc::new(backend.blockchain().clone()), Arc::new(OkCallFetcher::new(vec![1]))); - let remote_executor = RemoteCallExecutor::new(Arc::new(backend.blockchain().clone()), Arc::new(OkCallFetcher::new(vec![2]))); + let local_executor = RemoteCallExecutor::new( + Arc::new(backend.blockchain().clone()), + Arc::new(OkCallFetcher::new(vec![1])), + ); + let remote_executor = RemoteCallExecutor::new( + Arc::new(backend.blockchain().clone()), + Arc::new(OkCallFetcher::new(vec![2])), + ); let remote_or_local = RemoteOrLocalCallExecutor::new(backend, remote_executor, local_executor); assert_eq!( remote_or_local.call( diff --git a/core/client/src/light/fetcher.rs b/core/client/src/light/fetcher.rs index 14a3c72b05..6ac637f3fa 100644 --- a/core/client/src/light/fetcher.rs +++ b/core/client/src/light/fetcher.rs @@ -23,16 +23,15 @@ use std::future::Future; use hash_db::{HashDB, Hasher, EMPTY_PREFIX}; use codec::{Decode, Encode}; -use primitives::{ChangesTrieConfiguration, convert_hash}; +use primitives::{ChangesTrieConfiguration, convert_hash, traits::CodeExecutor}; use sr_primitives::traits::{ Block as BlockT, Header as HeaderT, Hash, HashFor, NumberFor, SimpleArithmetic, CheckedConversion, Zero, }; use state_machine::{ - CodeExecutor, ChangesTrieRootsStorage, - ChangesTrieAnchorBlockId, ChangesTrieConfigurationRange, - TrieBackend, read_proof_check, key_changes_proof_check, - create_proof_check_backend_storage, read_child_proof_check, + ChangesTrieRootsStorage, ChangesTrieAnchorBlockId, ChangesTrieConfigurationRange, + TrieBackend, read_proof_check, key_changes_proof_check, create_proof_check_backend_storage, + read_child_proof_check, }; use crate::cht; diff --git a/core/client/src/light/mod.rs b/core/client/src/light/mod.rs index c53a2eef2b..08e14ad8f3 100644 --- a/core/client/src/light/mod.rs +++ b/core/client/src/light/mod.rs @@ -24,10 +24,9 @@ pub mod fetcher; use std::sync::Arc; use executor::RuntimeInfo; -use primitives::{H256, Blake2Hasher}; +use primitives::{H256, Blake2Hasher, traits::CodeExecutor}; use sr_primitives::BuildStorage; use sr_primitives::traits::Block as BlockT; -use state_machine::CodeExecutor; use crate::call_executor::LocalCallExecutor; use crate::client::Client; diff --git a/core/executor/Cargo.toml b/core/executor/Cargo.toml index a62a969d21..3d8f047322 100644 --- a/core/executor/Cargo.toml +++ b/core/executor/Cargo.toml @@ -11,7 +11,6 @@ runtime_io = { package = "sr-io", path = "../sr-io" } primitives = { package = "substrate-primitives", path = "../primitives" } trie = { package = "substrate-trie", path = "../trie" } serializer = { package = "substrate-serializer", path = "../serializer" } -state_machine = { package = "substrate-state-machine", path = "../state-machine" } runtime_version = { package = "sr-version", path = "../sr-version" } panic-handler = { package = "substrate-panic-handler", path = "../panic-handler" } wasm-interface = { package = "substrate-wasm-interface", path = "../wasm-interface" } @@ -30,6 +29,7 @@ hex-literal = "0.2.0" runtime-test = { package = "substrate-runtime-test", path = "runtime-test" } substrate-client = { path = "../client" } substrate-offchain = { path = "../offchain/" } +state_machine = { package = "substrate-state-machine", path = "../state-machine" } [features] default = [] diff --git a/core/executor/src/error.rs b/core/executor/src/error.rs index 967d074ec9..d6bf6b8b84 100644 --- a/core/executor/src/error.rs +++ b/core/executor/src/error.rs @@ -16,7 +16,6 @@ //! Rust executor possible errors. -use state_machine; use serializer; use wasmi; @@ -92,8 +91,6 @@ impl std::error::Error for Error { } } -impl state_machine::Error for Error {} - impl wasmi::HostError for Error {} impl From for Error { diff --git a/core/executor/src/lib.rs b/core/executor/src/lib.rs index d4bed6964e..b5c5027951 100644 --- a/core/executor/src/lib.rs +++ b/core/executor/src/lib.rs @@ -43,11 +43,10 @@ pub use wasmi; pub use wasm_executor::WasmExecutor; pub use native_executor::{with_native_environment, NativeExecutor, NativeExecutionDispatch}; pub use wasm_runtimes_cache::RuntimesCache; -pub use state_machine::Externalities; pub use runtime_version::{RuntimeVersion, NativeVersion}; pub use codec::Codec; #[doc(hidden)] -pub use primitives::Blake2Hasher; +pub use primitives::{Blake2Hasher, traits::Externalities}; #[doc(hidden)] pub use wasm_interface; diff --git a/core/executor/src/native_executor.rs b/core/executor/src/native_executor.rs index 616b9f8c6d..3de795fc27 100644 --- a/core/executor/src/native_executor.rs +++ b/core/executor/src/native_executor.rs @@ -16,12 +16,11 @@ use std::{result, cell::RefCell, panic::UnwindSafe}; use crate::error::{Error, Result}; -use state_machine::{CodeExecutor, Externalities}; use crate::wasm_executor::WasmExecutor; use runtime_version::{NativeVersion, RuntimeVersion}; use codec::{Decode, Encode}; use crate::RuntimeInfo; -use primitives::{Blake2Hasher, NativeOrEncoded}; +use primitives::{Blake2Hasher, NativeOrEncoded, traits::{CodeExecutor, Externalities}}; use log::{trace, warn}; use crate::RuntimesCache; @@ -35,7 +34,7 @@ fn safe_call(f: F) -> Result { // Substrate uses custom panic hook that terminates process on panic. Disable termination for the native call. let _guard = panic_handler::AbortGuard::force_unwind(); - ::std::panic::catch_unwind(f).map_err(|_| Error::Runtime) + std::panic::catch_unwind(f).map_err(|_| Error::Runtime) } /// Set up the externalities and safe calling environment to execute calls to a native runtime. @@ -44,7 +43,7 @@ fn safe_call(f: F) -> Result pub fn with_native_environment(ext: &mut dyn Externalities, f: F) -> Result where F: UnwindSafe + FnOnce() -> U { - ::runtime_io::with_externalities(ext, move || safe_call(f)) + runtime_io::with_externalities(ext, move || safe_call(f)) } /// Delegate for dispatching a CodeExecutor call. diff --git a/core/executor/src/wasm_executor.rs b/core/executor/src/wasm_executor.rs index 25f1f969b8..4baa547ab8 100644 --- a/core/executor/src/wasm_executor.rs +++ b/core/executor/src/wasm_executor.rs @@ -27,12 +27,12 @@ use wasmi::{ Module, ModuleInstance, MemoryInstance, MemoryRef, TableRef, ImportsBuilder, ModuleRef, memory_units::Pages, RuntimeValue::{I32, I64, self}, }; -use state_machine::Externalities; use crate::error::{Error, Result}; use codec::{Encode, Decode}; use primitives::{ blake2_128, blake2_256, twox_64, twox_128, twox_256, ed25519, sr25519, Pair, crypto::KeyTypeId, - offchain, hexdisplay::HexDisplay, sandbox as sandbox_primitives, Blake2Hasher, + offchain, hexdisplay::HexDisplay, sandbox as sandbox_primitives, H256, Blake2Hasher, + traits::Externalities, child_storage_key::ChildStorageKey, }; use trie::{TrieConfiguration, trie_types::Layout}; use crate::sandbox; diff --git a/core/executor/src/wasm_runtimes_cache.rs b/core/executor/src/wasm_runtimes_cache.rs index fd0ab91503..fb207dc18b 100644 --- a/core/executor/src/wasm_runtimes_cache.rs +++ b/core/executor/src/wasm_runtimes_cache.rs @@ -21,13 +21,9 @@ use crate::wasm_executor::WasmExecutor; use log::{trace, warn}; use codec::Decode; use parity_wasm::elements::{deserialize_buffer, DataSegment, Instruction, Module as RawModule}; -use primitives::storage::well_known_keys; -use primitives::Blake2Hasher; +use primitives::{storage::well_known_keys, Blake2Hasher, traits::Externalities}; use runtime_version::RuntimeVersion; -use state_machine::Externalities; -use std::collections::hash_map::{Entry, HashMap}; -use std::mem; -use std::rc::Rc; +use std::{collections::hash_map::{Entry, HashMap}, mem, rc::Rc}; use wasmi::{Module as WasmModule, ModuleRef as WasmModuleInstanceRef, RuntimeValue}; #[derive(Debug)] diff --git a/core/finality-grandpa/src/finality_proof.rs b/core/finality-grandpa/src/finality_proof.rs index 4b84ede933..bae6c8ebc0 100644 --- a/core/finality-grandpa/src/finality_proof.rs +++ b/core/finality-grandpa/src/finality_proof.rs @@ -40,16 +40,15 @@ use log::{trace, warn}; use client::{ backend::Backend, blockchain::Backend as BlockchainBackend, CallExecutor, Client, error::{Error as ClientError, Result as ClientResult}, - light::fetcher::{FetchChecker, RemoteCallRequest}, - ExecutionStrategy, NeverOffchainExt, + light::fetcher::{FetchChecker, RemoteCallRequest}, ExecutionStrategy, }; use codec::{Encode, Decode}; use grandpa::BlockNumberOps; -use sr_primitives::{Justification, generic::BlockId}; -use sr_primitives::traits::{ - NumberFor, Block as BlockT, Header as HeaderT, One, +use sr_primitives::{ + Justification, generic::BlockId, + traits::{NumberFor, Block as BlockT, Header as HeaderT, One}, }; -use primitives::{H256, Blake2Hasher}; +use primitives::{H256, Blake2Hasher, offchain::NeverOffchainExt}; use substrate_telemetry::{telemetry, CONSENSUS_INFO}; use fg_primitives::AuthorityId; diff --git a/core/primitives/src/child_storage_key.rs b/core/primitives/src/child_storage_key.rs new file mode 100644 index 0000000000..eba34c1ef9 --- /dev/null +++ b/core/primitives/src/child_storage_key.rs @@ -0,0 +1,68 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Provides a wrapper around a child storage key. + +use crate::storage::well_known_keys::is_child_trie_key_valid; +use rstd::{borrow::Cow, vec::Vec}; + +/// A wrapper around a child storage key. +/// +/// This wrapper ensures that the child storage key is correct and properly used. It is +/// impossible to create an instance of this struct without providing a correct `storage_key`. +pub struct ChildStorageKey<'a> { + storage_key: Cow<'a, [u8]>, +} + +impl<'a> ChildStorageKey<'a> { + fn new(storage_key: Cow<'a, [u8]>) -> Option { + if is_child_trie_key_valid(&storage_key) { + Some(ChildStorageKey { storage_key }) + } else { + None + } + } + + /// Create a new `ChildStorageKey` from a vector. + /// + /// `storage_key` need to start with `:child_storage:default:` + /// See `is_child_trie_key_valid` for more details. + pub fn from_vec(key: Vec) -> Option { + Self::new(Cow::Owned(key)) + } + + /// Create a new `ChildStorageKey` from a slice. + /// + /// `storage_key` need to start with `:child_storage:default:` + /// See `is_child_trie_key_valid` for more details. + pub fn from_slice(key: &'a [u8]) -> Option { + Self::new(Cow::Borrowed(key)) + } + + /// Get access to the byte representation of the storage key. + /// + /// This key is guaranteed to be correct. + pub fn as_ref(&self) -> &[u8] { + &*self.storage_key + } + + /// Destruct this instance into an owned vector that represents the storage key. + /// + /// This key is guaranteed to be correct. + pub fn into_owned(self) -> Vec { + self.storage_key.into_owned() + } +} diff --git a/core/primitives/src/lib.rs b/core/primitives/src/lib.rs index 5c918e4964..144aa7b997 100644 --- a/core/primitives/src/lib.rs +++ b/core/primitives/src/lib.rs @@ -54,6 +54,7 @@ pub mod crypto; pub mod u32_trait; +pub mod child_storage_key; pub mod ed25519; pub mod sr25519; pub mod hash; diff --git a/core/primitives/src/offchain.rs b/core/primitives/src/offchain.rs index 6f024c5c02..c9e78d48e1 100644 --- a/core/primitives/src/offchain.rs +++ b/core/primitives/src/offchain.rs @@ -663,6 +663,112 @@ impl Externalities for LimitedExternalities { } } +/// An implementation of offchain extensions that should never be triggered. +pub enum NeverOffchainExt {} + +impl NeverOffchainExt { + /// Create new offchain extensions. + pub fn new<'a>() -> Option<&'a mut Self> { + None + } +} + +impl Externalities for NeverOffchainExt { + fn is_validator(&self) -> bool { + unreachable!() + } + + fn submit_transaction(&mut self, _extrinsic: Vec) -> Result<(), ()> { + unreachable!() + } + + fn network_state( + &self, + ) -> Result { + unreachable!() + } + + fn timestamp(&mut self) -> Timestamp { + unreachable!() + } + + fn sleep_until(&mut self, _deadline: Timestamp) { + unreachable!() + } + + fn random_seed(&mut self) -> [u8; 32] { + unreachable!() + } + + fn local_storage_set(&mut self, _kind: StorageKind, _key: &[u8], _value: &[u8]) { + unreachable!() + } + + fn local_storage_compare_and_set( + &mut self, + _kind: StorageKind, + _key: &[u8], + _old_value: Option<&[u8]>, + _new_value: &[u8], + ) -> bool { + unreachable!() + } + + fn local_storage_get(&mut self, _kind: StorageKind, _key: &[u8]) -> Option> { + unreachable!() + } + + fn http_request_start( + &mut self, + _method: &str, + _uri: &str, + _meta: &[u8] + ) -> Result { + unreachable!() + } + + fn http_request_add_header( + &mut self, + _request_id: HttpRequestId, + _name: &str, + _value: &str + ) -> Result<(), ()> { + unreachable!() + } + + fn http_request_write_body( + &mut self, + _request_id: HttpRequestId, + _chunk: &[u8], + _deadline: Option + ) -> Result<(), HttpError> { + unreachable!() + } + + fn http_response_wait( + &mut self, + _ids: &[HttpRequestId], + _deadline: Option + ) -> Vec { + unreachable!() + } + + fn http_response_headers( + &mut self, + _request_id: HttpRequestId + ) -> Vec<(Vec, Vec)> { + unreachable!() + } + + fn http_response_read_body( + &mut self, + _request_id: HttpRequestId, + _buffer: &mut [u8], + _deadline: Option + ) -> Result { + unreachable!() + } +} #[cfg(test)] mod tests { diff --git a/core/primitives/src/storage.rs b/core/primitives/src/storage.rs index 8fdb7bdcc4..14c49bfaa9 100644 --- a/core/primitives/src/storage.rs +++ b/core/primitives/src/storage.rs @@ -75,4 +75,22 @@ pub mod well_known_keys { // Other code might depend on this, so be careful changing this. key.starts_with(CHILD_STORAGE_KEY_PREFIX) } + + /// Determine whether a child trie key is valid. + /// + /// For now, the only valid child trie keys are those starting with `:child_storage:default:`. + /// + /// `child_trie_root` and `child_delta_trie_root` can panic if invalid value is provided to them. + pub fn is_child_trie_key_valid(storage_key: &[u8]) -> bool { + let has_right_prefix = storage_key.starts_with(b":child_storage:default:"); + if has_right_prefix { + // This is an attempt to catch a change of `is_child_storage_key`, which + // just checks if the key has prefix `:child_storage:` at the moment of writing. + debug_assert!( + is_child_storage_key(&storage_key), + "`is_child_trie_key_valid` is a subset of `is_child_storage_key`", + ); + } + has_right_prefix + } } diff --git a/core/primitives/src/traits.rs b/core/primitives/src/traits.rs index 8e2f0c0213..0274c44ace 100644 --- a/core/primitives/src/traits.rs +++ b/core/primitives/src/traits.rs @@ -17,7 +17,11 @@ //! Shareable Substrate traits. #[cfg(feature = "std")] -use crate::{crypto::KeyTypeId, ed25519, sr25519}; +use crate::{crypto::KeyTypeId, ed25519, sr25519, child_storage_key::ChildStorageKey}; +#[cfg(feature = "std")] +use std::{fmt::{Debug, Display}, panic::UnwindSafe}; +#[cfg(feature = "std")] +use hash_db::Hasher; /// Something that generates, stores and provides access to keys. #[cfg(feature = "std")] @@ -68,3 +72,134 @@ pub trait BareCryptoStore: Send + Sync { /// A pointer to the key store. #[cfg(feature = "std")] pub type BareCryptoStorePtr = std::sync::Arc>; + +/// Externalities: pinned to specific active address. +#[cfg(feature = "std")] +pub trait Externalities { + /// Read runtime storage. + fn storage(&self, key: &[u8]) -> Option>; + + /// Get storage value hash. This may be optimized for large values. + fn storage_hash(&self, key: &[u8]) -> Option { + self.storage(key).map(|v| H::hash(&v)) + } + + /// Get child storage value hash. This may be optimized for large values. + fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { + self.child_storage(storage_key, key).map(|v| H::hash(&v)) + } + + /// Read original runtime storage, ignoring any overlayed changes. + fn original_storage(&self, key: &[u8]) -> Option>; + + /// Read original runtime child storage, ignoring any overlayed changes. + fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option>; + + /// Get original storage value hash, ignoring any overlayed changes. + /// This may be optimized for large values. + fn original_storage_hash(&self, key: &[u8]) -> Option { + self.original_storage(key).map(|v| H::hash(&v)) + } + + /// Get original child storage value hash, ignoring any overlayed changes. + /// This may be optimized for large values. + fn original_child_storage_hash( + &self, + storage_key: ChildStorageKey, + key: &[u8], + ) -> Option { + self.original_child_storage(storage_key, key).map(|v| H::hash(&v)) + } + + /// Read child runtime storage. + fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option>; + + /// Set storage entry `key` of current contract being called (effective immediately). + fn set_storage(&mut self, key: Vec, value: Vec) { + self.place_storage(key, Some(value)); + } + + /// Set child storage entry `key` of current contract being called (effective immediately). + fn set_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Vec) { + self.place_child_storage(storage_key, key, Some(value)) + } + + /// Clear a storage entry (`key`) of current contract being called (effective immediately). + fn clear_storage(&mut self, key: &[u8]) { + self.place_storage(key.to_vec(), None); + } + + /// Clear a child storage entry (`key`) of current contract being called (effective immediately). + fn clear_child_storage(&mut self, storage_key: ChildStorageKey, key: &[u8]) { + self.place_child_storage(storage_key, key.to_vec(), None) + } + + /// Whether a storage entry exists. + fn exists_storage(&self, key: &[u8]) -> bool { + self.storage(key).is_some() + } + + /// Whether a child storage entry exists. + fn exists_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> bool { + self.child_storage(storage_key, key).is_some() + } + + /// Clear an entire child storage. + fn kill_child_storage(&mut self, storage_key: ChildStorageKey); + + /// Clear storage entries which keys are start with the given prefix. + fn clear_prefix(&mut self, prefix: &[u8]); + + /// Clear child storage entries which keys are start with the given prefix. + fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]); + + /// Set or clear a storage entry (`key`) of current contract being called (effective immediately). + fn place_storage(&mut self, key: Vec, value: Option>); + + /// Set or clear a child storage entry. Return whether the operation succeeds. + fn place_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Option>); + + /// Get the identity of the chain. + fn chain_id(&self) -> u64; + + /// Get the trie root of the current storage map. This will also update all child storage keys + /// in the top-level storage map. + fn storage_root(&mut self) -> H::Out where H::Out: Ord; + + /// Get the trie root of a child storage map. This will also update the value of the child + /// storage keys in the top-level storage map. + /// If the storage root equals the default hash as defined by the trie, the key in the top-level + /// storage map will be removed. + fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec; + + /// Get the change trie root of the current storage overlay at a block with given parent. + fn storage_changes_root(&mut self, parent: H::Out) -> Result, ()> where H::Out: Ord; + + /// Returns offchain externalities extension if present. + fn offchain(&mut self) -> Option<&mut dyn crate::offchain::Externalities>; + + /// Returns the keystore. + fn keystore(&self) -> Option; +} + +/// Code execution engine. +#[cfg(feature = "std")] +pub trait CodeExecutor: Sized + Send + Sync { + /// Externalities error type. + type Error: Display + Debug + Send + 'static; + + /// Call a given method in the runtime. Returns a tuple of the result (either the output data + /// or an execution error) together with a `bool`, which is true if native execution was used. + fn call< + E: Externalities, + R: codec::Codec + PartialEq, + NC: FnOnce() -> Result + UnwindSafe, + >( + &self, + ext: &mut E, + method: &str, + data: &[u8], + use_native: bool, + native_call: Option, + ) -> (Result, Self::Error>, bool); +} diff --git a/core/rpc/src/state/state_full.rs b/core/rpc/src/state/state_full.rs index 3115a525a8..8b3dcd3d69 100644 --- a/core/rpc/src/state/state_full.rs +++ b/core/rpc/src/state/state_full.rs @@ -27,11 +27,11 @@ use client::{ backend::Backend, error::Result as ClientResult, }; use primitives::{ - H256, Blake2Hasher, Bytes, + H256, Blake2Hasher, Bytes, offchain::NeverOffchainExt, storage::{StorageKey, StorageData, StorageChangeSet}, }; use runtime_version::RuntimeVersion; -use state_machine::{NeverOffchainExt, ExecutionStrategy}; +use state_machine::ExecutionStrategy; use sr_primitives::{ generic::BlockId, traits::{Block as BlockT, Header, NumberFor, ProvideRuntimeApi, SaturatedConversion}, diff --git a/core/sr-io/with_std.rs b/core/sr-io/with_std.rs index cee17a5bdd..ca2a2554c3 100644 --- a/core/sr-io/with_std.rs +++ b/core/sr-io/with_std.rs @@ -16,12 +16,11 @@ use primitives::{ blake2_128, blake2_256, twox_128, twox_256, twox_64, ed25519, Blake2Hasher, sr25519, Pair, + traits::Externalities, child_storage_key::ChildStorageKey, }; // Switch to this after PoC-3 // pub use primitives::BlakeHasher; -pub use substrate_state_machine::{ - Externalities, BasicExternalities, TestExternalities, ChildStorageKey, -}; +pub use substrate_state_machine::{BasicExternalities, TestExternalities}; use environmental::environmental; use primitives::{offchain, hexdisplay::HexDisplay, H256}; @@ -40,7 +39,7 @@ impl HasherBounds for T {} /// /// Panicking here is aligned with what the `without_std` environment would do /// in the case of an invalid child storage key. -fn child_storage_key_or_panic(storage_key: &[u8]) -> ChildStorageKey { +fn child_storage_key_or_panic(storage_key: &[u8]) -> ChildStorageKey { match ChildStorageKey::from_slice(storage_key) { Some(storage_key) => storage_key, None => panic!("child storage key is invalid"), diff --git a/core/sr-io/without_std.rs b/core/sr-io/without_std.rs index d6ad3e1434..f7b0ce9b02 100644 --- a/core/sr-io/without_std.rs +++ b/core/sr-io/without_std.rs @@ -1239,4 +1239,3 @@ impl Printable for u64 { unsafe { ext_print_num.get()(*self); } } } - diff --git a/core/sr-std/without_std.rs b/core/sr-std/without_std.rs index 845ea79aa4..ed9eea6c31 100755 --- a/core/sr-std/without_std.rs +++ b/core/sr-std/without_std.rs @@ -49,7 +49,6 @@ mod __impl { pub use alloc::boxed; pub use alloc::rc; pub use alloc::vec; -pub use core::borrow; pub use core::cell; pub use core::clone; pub use core::cmp; @@ -76,3 +75,8 @@ pub mod collections { pub use alloc::collections::btree_set; pub use alloc::collections::vec_deque; } + +pub mod borrow { + pub use core::borrow::*; + pub use alloc::borrow::*; +} diff --git a/core/state-machine/src/backend.rs b/core/state-machine/src/backend.rs index 28ab61a5ed..86d415de1c 100644 --- a/core/state-machine/src/backend.rs +++ b/core/state-machine/src/backend.rs @@ -16,16 +16,15 @@ //! State machine backends. These manage the code and storage of contracts. -use std::{error, fmt}; -use std::cmp::Ord; -use std::collections::HashMap; -use std::marker::PhantomData; +use std::{error, fmt, cmp::Ord, collections::HashMap, marker::PhantomData}; use log::warn; use hash_db::Hasher; use crate::trie_backend::TrieBackend; use crate::trie_backend_essence::TrieBackendStorage; -use trie::{TrieMut, MemoryDB, child_trie_root, default_child_trie_root, TrieConfiguration}; -use trie::trie_types::{TrieDBMut, Layout}; +use trie::{ + TrieMut, MemoryDB, child_trie_root, default_child_trie_root, TrieConfiguration, + trie_types::{TrieDBMut, Layout}, +}; /// A state backend is used to read state data and can have changes committed /// to it. @@ -119,7 +118,9 @@ pub trait Backend { } /// Try convert into trie backend. - fn as_trie_backend(&mut self) -> Option<&TrieBackend>; + fn as_trie_backend(&mut self) -> Option<&TrieBackend> { + None + } /// Calculate the storage root, with given delta over what is already stored /// in the backend, and produce a "transaction" that can be used to commit. @@ -154,7 +155,56 @@ pub trait Backend { txs.consolidate(parent_txs); (root, txs) } +} + +impl<'a, T: Backend, H: Hasher> Backend for &'a T { + type Error = T::Error; + type Transaction = T::Transaction; + type TrieBackendStorage = T::TrieBackendStorage; + + fn storage(&self, key: &[u8]) -> Result>, Self::Error> { + (*self).storage(key) + } + + fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Result>, Self::Error> { + (*self).child_storage(storage_key, key) + } + + fn for_keys_in_child_storage(&self, storage_key: &[u8], f: F) { + (*self).for_keys_in_child_storage(storage_key, f) + } + + fn for_keys_with_prefix(&self, prefix: &[u8], f: F) { + (*self).for_keys_with_prefix(prefix, f) + } + + fn for_child_keys_with_prefix(&self, storage_key: &[u8], prefix: &[u8], f: F) { + (*self).for_child_keys_with_prefix(storage_key, prefix, f) + } + fn storage_root(&self, delta: I) -> (H::Out, Self::Transaction) + where + I: IntoIterator, Option>)>, + H::Out: Ord, + { + (*self).storage_root(delta) + } + + fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (Vec, bool, Self::Transaction) + where + I: IntoIterator, Option>)>, + H::Out: Ord, + { + (*self).child_storage_root(storage_key, delta) + } + + fn pairs(&self) -> Vec<(Vec, Vec)> { + (*self).pairs() + } + + fn for_key_values_with_prefix(&self, prefix: &[u8], f: F) { + (*self).for_key_values_with_prefix(prefix, f); + } } /// Trait that allows consolidate two transactions together. @@ -298,8 +348,6 @@ impl From>, Vec, Option>)>> for InMem } } -impl super::Error for Void {} - impl InMemory { /// child storage key iterator pub fn child_storage_keys(&self) -> impl Iterator { diff --git a/core/state-machine/src/basic.rs b/core/state-machine/src/basic.rs index 1d36a0ddad..e45af45c9f 100644 --- a/core/state-machine/src/basic.rs +++ b/core/state-machine/src/basic.rs @@ -22,9 +22,10 @@ use crate::backend::{Backend, InMemory}; use hash_db::Hasher; use trie::{TrieConfiguration, default_child_trie_root}; use trie::trie_types::Layout; -use primitives::offchain; -use primitives::storage::well_known_keys::is_child_storage_key; -use super::{ChildStorageKey, Externalities}; +use primitives::{ + storage::well_known_keys::is_child_storage_key, child_storage_key::ChildStorageKey, offchain, + traits::Externalities, +}; use log::warn; /// Simple HashMap-based Externalities impl. @@ -35,7 +36,6 @@ pub struct BasicExternalities { } impl BasicExternalities { - /// Create a new instance of `BasicExternalities` pub fn new( top: HashMap, Vec>, @@ -97,11 +97,11 @@ impl Externalities for BasicExternalities where H::Out: Ord { Externalities::::storage(self, key) } - fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { + fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { self.children.get(storage_key.as_ref()).and_then(|child| child.get(key)).cloned() } - fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { + fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { Externalities::::child_storage(self, storage_key, key) } @@ -119,9 +119,9 @@ impl Externalities for BasicExternalities where H::Out: Ord { fn place_child_storage( &mut self, - storage_key: ChildStorageKey, + storage_key: ChildStorageKey, key: Vec, - value: Option> + value: Option>, ) { let child_map = self.children.entry(storage_key.into_owned()).or_default(); if let Some(value) = value { @@ -131,7 +131,7 @@ impl Externalities for BasicExternalities where H::Out: Ord { } } - fn kill_child_storage(&mut self, storage_key: ChildStorageKey) { + fn kill_child_storage(&mut self, storage_key: ChildStorageKey) { self.children.remove(storage_key.as_ref()); } @@ -147,7 +147,7 @@ impl Externalities for BasicExternalities where H::Out: Ord { self.top.retain(|key, _| !key.starts_with(prefix)); } - fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]) { + fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]) { if let Some(child) = self.children.get_mut(storage_key.as_ref()) { child.retain(|key, _| !key.starts_with(prefix)); } @@ -163,9 +163,10 @@ impl Externalities for BasicExternalities where H::Out: Ord { // type of child trie support. let empty_hash = default_child_trie_root::>(&[]); for storage_key in keys { - let child_root = self.child_storage_root( - ChildStorageKey::::from_slice(storage_key.as_slice()) - .expect("Map only feed by valid keys; qed") + let child_root = Externalities::::child_storage_root( + self, + ChildStorageKey::from_slice(storage_key.as_slice()) + .expect("Map only feed by valid keys; qed"), ); if &empty_hash[..] == &child_root[..] { top.remove(&storage_key); @@ -173,10 +174,11 @@ impl Externalities for BasicExternalities where H::Out: Ord { top.insert(storage_key, child_root); } } + Layout::::trie_root(self.top.clone()) } - fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { + fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { if let Some(child) = self.children.get(storage_key.as_ref()) { let delta = child.clone().into_iter().map(|(k, v)| (k, Some(v))); diff --git a/core/state-machine/src/error.rs b/core/state-machine/src/error.rs new file mode 100644 index 0000000000..6e6ce99585 --- /dev/null +++ b/core/state-machine/src/error.rs @@ -0,0 +1,47 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +/// State Machine Errors + +use std::fmt; + +/// State Machine Error bound. +/// +/// This should reflect Wasm error type bound for future compatibility. +pub trait Error: 'static + fmt::Debug + fmt::Display + Send {} + +impl Error for T {} + +/// Externalities Error. +/// +/// Externalities are not really allowed to have errors, since it's assumed that dependent code +/// would not be executed unless externalities were available. This is included for completeness, +/// and as a transition away from the pre-existing framework. +#[derive(Debug, Eq, PartialEq)] +pub enum ExecutionError { + /// Backend error. + Backend(String), + /// The entry `:code` doesn't exist in storage so there's no way we can execute anything. + CodeEntryDoesNotExist, + /// Backend is incompatible with execution proof generation process. + UnableToGenerateProof, + /// Invalid execution proof. + InvalidProof, +} + +impl fmt::Display for ExecutionError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Externalities Error") } +} diff --git a/core/state-machine/src/ext.rs b/core/state-machine/src/ext.rs index fde3ba2b01..129ed96ab9 100644 --- a/core/state-machine/src/ext.rs +++ b/core/state-machine/src/ext.rs @@ -18,14 +18,17 @@ use std::{error, fmt, cmp::Ord}; use log::warn; -use crate::backend::Backend; -use crate::changes_trie::{ - Storage as ChangesTrieStorage, CacheAction as ChangesTrieCacheAction, - build_changes_trie, +use crate::{ + backend::Backend, OverlayedChanges, + changes_trie::{ + Storage as ChangesTrieStorage, CacheAction as ChangesTrieCacheAction, build_changes_trie, + }, }; -use crate::{Externalities, OverlayedChanges, ChildStorageKey}; use hash_db::Hasher; -use primitives::{offchain, storage::well_known_keys::is_child_storage_key, traits::BareCryptoStorePtr}; +use primitives::{ + offchain, storage::well_known_keys::is_child_storage_key, + traits::{BareCryptoStorePtr, Externalities}, child_storage_key::ChildStorageKey, +}; use trie::{MemoryDB, default_child_trie_root}; use trie::trie_types::Layout; @@ -201,24 +204,24 @@ where self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL) } - fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { + fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { let _guard = panic_handler::AbortGuard::force_abort(); self.overlay.child_storage(storage_key.as_ref(), key).map(|x| x.map(|x| x.to_vec())).unwrap_or_else(|| self.backend.child_storage(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL)) } - fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { + fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { let _guard = panic_handler::AbortGuard::force_abort(); self.overlay.child_storage(storage_key.as_ref(), key).map(|x| x.map(|x| H::hash(x))).unwrap_or_else(|| self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL)) } - fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { + fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { let _guard = panic_handler::AbortGuard::force_abort(); self.backend.child_storage(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL) } - fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { + fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { let _guard = panic_handler::AbortGuard::force_abort(); self.backend.child_storage_hash(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL) } @@ -231,7 +234,7 @@ where } } - fn exists_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> bool { + fn exists_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> bool { let _guard = panic_handler::AbortGuard::force_abort(); match self.overlay.child_storage(storage_key.as_ref(), key) { @@ -251,14 +254,14 @@ where self.overlay.set_storage(key, value); } - fn place_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Option>) { + fn place_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Option>) { let _guard = panic_handler::AbortGuard::force_abort(); self.mark_dirty(); self.overlay.set_child_storage(storage_key.into_owned(), key, value); } - fn kill_child_storage(&mut self, storage_key: ChildStorageKey) { + fn kill_child_storage(&mut self, storage_key: ChildStorageKey) { let _guard = panic_handler::AbortGuard::force_abort(); self.mark_dirty(); @@ -282,7 +285,7 @@ where }); } - fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]) { + fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]) { let _guard = panic_handler::AbortGuard::force_abort(); self.mark_dirty(); @@ -323,7 +326,7 @@ where root } - fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { + fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { let _guard = panic_handler::AbortGuard::force_abort(); if self.storage_transaction.is_some() { self diff --git a/core/state-machine/src/lib.rs b/core/state-machine/src/lib.rs index 0ffac5e688..41d9b092bd 100644 --- a/core/state-machine/src/lib.rs +++ b/core/state-machine/src/lib.rs @@ -19,17 +19,17 @@ #![warn(missing_docs)] use std::{fmt, panic::UnwindSafe, result, marker::PhantomData}; -use std::borrow::Cow; use log::warn; use hash_db::Hasher; use codec::{Decode, Encode}; use primitives::{ - storage::well_known_keys, NativeOrEncoded, NeverNativeValue, offchain, - traits::BareCryptoStorePtr, + storage::well_known_keys, NativeOrEncoded, NeverNativeValue, offchain::{self, NeverOffchainExt}, + traits::{BareCryptoStorePtr, CodeExecutor}, }; pub mod backend; mod changes_trie; +mod error; mod ext; mod testing; mod basic; @@ -64,6 +64,11 @@ pub use proving_backend::{ }; pub use trie_backend_essence::{TrieBackendStorage, Storage}; pub use trie_backend::TrieBackend; +pub use error::{Error, ExecutionError}; + +type CallResult = Result, E>; + +type DefaultHandler = fn(CallResult, CallResult) -> CallResult; /// Type of changes trie transaction. pub type ChangesTrieTransaction = ( @@ -71,321 +76,6 @@ pub type ChangesTrieTransaction = ( ChangesTrieCacheAction<::Out, N>, ); -/// A wrapper around a child storage key. -/// -/// This wrapper ensures that the child storage key is correct and properly used. It is -/// impossible to create an instance of this struct without providing a correct `storage_key`. -pub struct ChildStorageKey<'a, H: Hasher> { - storage_key: Cow<'a, [u8]>, - _hasher: PhantomData, -} - -impl<'a, H: Hasher> ChildStorageKey<'a, H> { - fn new(storage_key: Cow<'a, [u8]>) -> Option { - if !trie::is_child_trie_key_valid::>(&storage_key) { - return None; - } - - Some(ChildStorageKey { - storage_key, - _hasher: PhantomData, - }) - } - - /// Create a new `ChildStorageKey` from a vector. - /// - /// `storage_key` has should start with `:child_storage:default:` - /// See `is_child_trie_key_valid` for more details. - pub fn from_vec(key: Vec) -> Option { - Self::new(Cow::Owned(key)) - } - - /// Create a new `ChildStorageKey` from a slice. - /// - /// `storage_key` has should start with `:child_storage:default:` - /// See `is_child_trie_key_valid` for more details. - pub fn from_slice(key: &'a [u8]) -> Option { - Self::new(Cow::Borrowed(key)) - } - - /// Get access to the byte representation of the storage key. - /// - /// This key is guaranteed to be correct. - pub fn as_ref(&self) -> &[u8] { - &*self.storage_key - } - - /// Destruct this instance into an owned vector that represents the storage key. - /// - /// This key is guaranteed to be correct. - pub fn into_owned(self) -> Vec { - self.storage_key.into_owned() - } -} - -/// State Machine Error bound. -/// -/// This should reflect WASM error type bound for future compatibility. -pub trait Error: 'static + fmt::Debug + fmt::Display + Send {} - -impl Error for ExecutionError {} - -/// Externalities Error. -/// -/// Externalities are not really allowed to have errors, since it's assumed that dependent code -/// would not be executed unless externalities were available. This is included for completeness, -/// and as a transition away from the pre-existing framework. -#[derive(Debug, Eq, PartialEq)] -pub enum ExecutionError { - /// Backend error. - Backend(String), - /// The entry `:code` doesn't exist in storage so there's no way we can execute anything. - CodeEntryDoesNotExist, - /// Backend is incompatible with execution proof generation process. - UnableToGenerateProof, - /// Invalid execution proof. - InvalidProof, -} - -impl fmt::Display for ExecutionError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Externalities Error") } -} - -type CallResult = Result, E>; - -/// Externalities: pinned to specific active address. -pub trait Externalities { - /// Read runtime storage. - fn storage(&self, key: &[u8]) -> Option>; - - /// Get storage value hash. This may be optimized for large values. - fn storage_hash(&self, key: &[u8]) -> Option { - self.storage(key).map(|v| H::hash(&v)) - } - - /// Get child storage value hash. This may be optimized for large values. - fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { - self.child_storage(storage_key, key).map(|v| H::hash(&v)) - } - - /// Read original runtime storage, ignoring any overlayed changes. - fn original_storage(&self, key: &[u8]) -> Option>; - - /// Read original runtime child storage, ignoring any overlayed changes. - fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option>; - - /// Get original storage value hash, ignoring any overlayed changes. - /// This may be optimized for large values. - fn original_storage_hash(&self, key: &[u8]) -> Option { - self.original_storage(key).map(|v| H::hash(&v)) - } - - /// Get original child storage value hash, ignoring any overlayed changes. - /// This may be optimized for large values. - fn original_child_storage_hash( - &self, - storage_key: ChildStorageKey, - key: &[u8], - ) -> Option { - self.original_child_storage(storage_key, key).map(|v| H::hash(&v)) - } - - /// Read child runtime storage. - fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option>; - - /// Set storage entry `key` of current contract being called (effective immediately). - fn set_storage(&mut self, key: Vec, value: Vec) { - self.place_storage(key, Some(value)); - } - - /// Set child storage entry `key` of current contract being called (effective immediately). - fn set_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Vec) { - self.place_child_storage(storage_key, key, Some(value)) - } - - /// Clear a storage entry (`key`) of current contract being called (effective immediately). - fn clear_storage(&mut self, key: &[u8]) { - self.place_storage(key.to_vec(), None); - } - - /// Clear a child storage entry (`key`) of current contract being called (effective immediately). - fn clear_child_storage(&mut self, storage_key: ChildStorageKey, key: &[u8]) { - self.place_child_storage(storage_key, key.to_vec(), None) - } - - /// Whether a storage entry exists. - fn exists_storage(&self, key: &[u8]) -> bool { - self.storage(key).is_some() - } - - /// Whether a child storage entry exists. - fn exists_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> bool { - self.child_storage(storage_key, key).is_some() - } - - /// Clear an entire child storage. - fn kill_child_storage(&mut self, storage_key: ChildStorageKey); - - /// Clear storage entries which keys start with the given prefix. - fn clear_prefix(&mut self, prefix: &[u8]); - - /// Clear child storage entries which keys start with the given prefix. - fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]); - - /// Set or clear a storage entry (`key`) of current contract being called (effective immediately). - fn place_storage(&mut self, key: Vec, value: Option>); - - /// Set or clear a child storage entry. Return whether the operation succeeds. - fn place_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Option>); - - /// Get the identity of the chain. - fn chain_id(&self) -> u64; - - /// Get the trie root of the current storage map. This will also update all child storage keys in the top-level storage map. - fn storage_root(&mut self) -> H::Out where H::Out: Ord; - - /// Get the trie root of a child storage map. This will also update the value of the child - /// storage keys in the top-level storage map. - /// If the storage root equals the default hash as defined by the trie, the key in the top-level - /// storage map will be removed. - fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec; - - /// Get the change trie root of the current storage overlay at a block with given parent. - fn storage_changes_root(&mut self, parent: H::Out) -> Result, ()> where H::Out: Ord; - - /// Returns offchain externalities extension if present. - fn offchain(&mut self) -> Option<&mut dyn offchain::Externalities>; - - /// Returns the keystore. - fn keystore(&self) -> Option; -} - -/// An implementation of offchain extensions that should never be triggered. -pub enum NeverOffchainExt {} - -impl NeverOffchainExt { - /// Create new offchain extensions. - pub fn new<'a>() -> Option<&'a mut Self> { - None - } -} - -impl offchain::Externalities for NeverOffchainExt { - fn is_validator(&self) -> bool { - unreachable!() - } - - fn submit_transaction(&mut self, _extrinsic: Vec) -> Result<(), ()> { - unreachable!() - } - - fn network_state( - &self, - ) -> Result { - unreachable!() - } - - fn timestamp(&mut self) -> offchain::Timestamp { - unreachable!() - } - - fn sleep_until(&mut self, _deadline: offchain::Timestamp) { - unreachable!() - } - - fn random_seed(&mut self) -> [u8; 32] { - unreachable!() - } - - fn local_storage_set(&mut self, _kind: offchain::StorageKind, _key: &[u8], _value: &[u8]) { - unreachable!() - } - - fn local_storage_compare_and_set( - &mut self, - _kind: offchain::StorageKind, - _key: &[u8], - _old_value: Option<&[u8]>, - _new_value: &[u8], - ) -> bool { - unreachable!() - } - - fn local_storage_get(&mut self, _kind: offchain::StorageKind, _key: &[u8]) -> Option> { - unreachable!() - } - - fn http_request_start( - &mut self, - _method: &str, - _uri: &str, - _meta: &[u8] - ) -> Result { - unreachable!() - } - - fn http_request_add_header( - &mut self, - _request_id: offchain::HttpRequestId, - _name: &str, - _value: &str - ) -> Result<(), ()> { - unreachable!() - } - - fn http_request_write_body( - &mut self, - _request_id: offchain::HttpRequestId, - _chunk: &[u8], - _deadline: Option - ) -> Result<(), offchain::HttpError> { - unreachable!() - } - - fn http_response_wait( - &mut self, - _ids: &[offchain::HttpRequestId], - _deadline: Option - ) -> Vec { - unreachable!() - } - - fn http_response_headers( - &mut self, - _request_id: offchain::HttpRequestId - ) -> Vec<(Vec, Vec)> { - unreachable!() - } - - fn http_response_read_body( - &mut self, - _request_id: offchain::HttpRequestId, - _buffer: &mut [u8], - _deadline: Option - ) -> Result { - unreachable!() - } -} - -/// Code execution engine. -pub trait CodeExecutor: Sized + Send + Sync { - /// Externalities error type. - type Error: Error; - - /// Call a given method in the runtime. Returns a tuple of the result (either the output data - /// or an execution error) together with a `bool`, which is true if native execution was used. - fn call< - E: Externalities, R: Encode + Decode + PartialEq, NC: FnOnce() -> result::Result + UnwindSafe - >( - &self, - ext: &mut E, - method: &str, - data: &[u8], - use_native: bool, - native_call: Option, - ) -> (CallResult, bool); -} - /// Strategy for executing a call into the runtime. #[derive(Copy, Clone, Eq, PartialEq, Debug)] pub enum ExecutionStrategy { @@ -399,11 +89,6 @@ pub enum ExecutionStrategy { NativeElseWasm, } -type DefaultHandler = fn( - CallResult, - CallResult, -) -> CallResult; - /// Like `ExecutionStrategy` only it also stores a handler in case of consensus failure. #[derive(Clone)] pub enum ExecutionManager { @@ -430,7 +115,9 @@ impl<'a, F> From<&'a ExecutionManager> for ExecutionStrategy { impl ExecutionStrategy { /// Gets the corresponding manager for the execution strategy. - pub fn get_manager(self) -> ExecutionManager> { + pub fn get_manager( + self, + ) -> ExecutionManager> { match self { ExecutionStrategy::AlwaysWasm => ExecutionManager::AlwaysWasm, ExecutionStrategy::NativeWhenPossible => ExecutionManager::NativeWhenPossible, @@ -447,49 +134,14 @@ impl ExecutionStrategy { } } - -/// Evaluate to ExecutionManager::NativeWhenPossible, without having to figure out the type. -pub fn native_when_possible() -> ExecutionManager> { - ExecutionManager::NativeWhenPossible -} - /// Evaluate to ExecutionManager::NativeElseWasm, without having to figure out the type. pub fn native_else_wasm() -> ExecutionManager> { ExecutionManager::NativeElseWasm } -/// Evaluate to ExecutionManager::NativeWhenPossible, without having to figure out the type. -pub fn always_wasm() -> ExecutionManager> { - ExecutionManager::AlwaysWasm -} - -/// Creates new substrate state machine. -pub fn new<'a, H, N, B, T, O, Exec>( - backend: &'a B, - changes_trie_storage: Option<&'a T>, - offchain_ext: Option<&'a mut O>, - overlay: &'a mut OverlayedChanges, - exec: &'a Exec, - method: &'a str, - call_data: &'a [u8], - keystore: Option, -) -> StateMachine<'a, H, N, B, T, O, Exec> { - StateMachine { - backend, - changes_trie_storage, - offchain_ext, - overlay, - exec, - method, - call_data, - keystore, - _hasher: PhantomData, - } -} - /// The substrate state machine. -pub struct StateMachine<'a, H, N, B, T, O, Exec> { - backend: &'a B, +pub struct StateMachine<'a, B, H, N, T, O, Exec> { + backend: B, changes_trie_storage: Option<&'a T>, offchain_ext: Option<&'a mut O>, overlay: &'a mut OverlayedChanges, @@ -500,7 +152,7 @@ pub struct StateMachine<'a, H, N, B, T, O, Exec> { _hasher: PhantomData<(H, N)>, } -impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where +impl<'a, B, H, N, T, O, Exec> StateMachine<'a, B, H, N, T, O, Exec> where H: Hasher, Exec: CodeExecutor, B: Backend, @@ -509,6 +161,30 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where H::Out: Ord + 'static, N: crate::changes_trie::BlockNumber, { + /// Creates new substrate state machine. + pub fn new( + backend: B, + changes_trie_storage: Option<&'a T>, + offchain_ext: Option<&'a mut O>, + overlay: &'a mut OverlayedChanges, + exec: &'a Exec, + method: &'a str, + call_data: &'a [u8], + keystore: Option, + ) -> Self { + Self { + backend, + changes_trie_storage, + offchain_ext, + overlay, + exec, + method, + call_data, + keystore, + _hasher: PhantomData, + } + } + /// Execute a call using the given state backend, overlayed changes, and call executor. /// Produces a state-backend-specific "transaction" which can be used to apply the changes /// to the backing store, such as the disk. @@ -551,7 +227,7 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where { let mut externalities = ext::Ext::new( self.overlay, - self.backend, + &self.backend, self.changes_trie_storage, self.offchain_ext.as_mut().map(|x| &mut **x), self.keystore.clone(), @@ -586,11 +262,19 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where CallResult ) -> CallResult { - let (result, was_native, storage_delta, changes_delta) = self.execute_aux(compute_tx, true, native_call.take()); + let (result, was_native, storage_delta, changes_delta) = self.execute_aux( + compute_tx, + true, + native_call.take(), + ); if was_native { self.overlay.prospective = orig_prospective.clone(); - let (wasm_result, _, wasm_storage_delta, wasm_changes_delta) = self.execute_aux(compute_tx, false, native_call); + let (wasm_result, _, wasm_storage_delta, wasm_changes_delta) = self.execute_aux( + compute_tx, + false, + native_call, + ); if (result.is_ok() && wasm_result.is_ok() && result.as_ref().ok() == wasm_result.as_ref().ok()) @@ -613,13 +297,21 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where R: Decode + Encode + PartialEq, NC: FnOnce() -> result::Result + UnwindSafe, { - let (result, was_native, storage_delta, changes_delta) = self.execute_aux(compute_tx, true, native_call.take()); + let (result, was_native, storage_delta, changes_delta) = self.execute_aux( + compute_tx, + true, + native_call.take(), + ); if !was_native || result.is_ok() { (result, storage_delta, changes_delta) } else { self.overlay.prospective = orig_prospective.clone(); - let (wasm_result, _, wasm_storage_delta, wasm_changes_delta) = self.execute_aux(compute_tx, false, native_call); + let (wasm_result, _, wasm_storage_delta, wasm_changes_delta) = self.execute_aux( + compute_tx, + false, + native_call, + ); (wasm_result, wasm_storage_delta, wasm_changes_delta) } } @@ -646,7 +338,7 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where NC: FnOnce() -> result::Result + UnwindSafe, Handler: FnOnce( CallResult, - CallResult + CallResult, ) -> CallResult { // read changes trie configuration. The reason why we're doing it here instead of the @@ -654,8 +346,7 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where // proof-of-execution on light clients. And the proof is recorded by the backend which // is created after OverlayedChanges - let backend = self.backend.clone(); - let init_overlay = |overlay: &mut OverlayedChanges, final_check: bool| { + let init_overlay = |overlay: &mut OverlayedChanges, final_check: bool, backend: &B| { let changes_trie_config = try_read_overlay_value( overlay, backend, @@ -663,32 +354,41 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where )?; set_changes_trie_config(overlay, changes_trie_config, final_check) }; - init_overlay(self.overlay, false)?; + init_overlay(self.overlay, false, &self.backend)?; let result = { let orig_prospective = self.overlay.prospective.clone(); let (result, storage_delta, changes_delta) = match manager { ExecutionManager::Both(on_consensus_failure) => { - self.execute_call_with_both_strategy(compute_tx, native_call.take(), orig_prospective, on_consensus_failure) + self.execute_call_with_both_strategy( + compute_tx, + native_call.take(), + orig_prospective, + on_consensus_failure, + ) }, ExecutionManager::NativeElseWasm => { - self.execute_call_with_native_else_wasm_strategy(compute_tx, native_call.take(), orig_prospective) + self.execute_call_with_native_else_wasm_strategy( + compute_tx, + native_call.take(), + orig_prospective, + ) }, ExecutionManager::AlwaysWasm => { - let (result, _, storage_delta, changes_delta) = self.execute_aux(compute_tx, false, native_call); - (result, storage_delta, changes_delta) + let res = self.execute_aux(compute_tx, false, native_call); + (res.0, res.2, res.3) }, ExecutionManager::NativeWhenPossible => { - let (result, _was_native, storage_delta, changes_delta) = self.execute_aux(compute_tx, true, native_call); - (result, storage_delta, changes_delta) + let res = self.execute_aux(compute_tx, true, native_call); + (res.0, res.2, res.3) }, }; result.map(move |out| (out, storage_delta, changes_delta)) }; if result.is_ok() { - init_overlay(self.overlay, true)?; + init_overlay(self.overlay, true, &self.backend)?; } result.map_err(|e| Box::new(e) as _) @@ -739,23 +439,16 @@ where H::Out: Ord + 'static, { let proving_backend = proving_backend::ProvingBackend::new(trie_backend); - let mut sm = StateMachine { - backend: &proving_backend, - changes_trie_storage: None as Option<&changes_trie::InMemoryStorage>, - offchain_ext: NeverOffchainExt::new(), - overlay, - exec, - method, - call_data, - keystore, - _hasher: PhantomData, - }; + let mut sm = StateMachine::<_, H, _, InMemoryChangesTrieStorage, _, Exec>::new( + proving_backend, None, NeverOffchainExt::new(), overlay, exec, method, call_data, keystore, + ); + let (result, _, _) = sm.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>( native_else_wasm(), false, None, )?; - let proof = proving_backend.extract_proof(); + let proof = sm.backend.extract_proof(); Ok((result.into_encoded(), proof)) } @@ -792,17 +485,10 @@ where Exec: CodeExecutor, H::Out: Ord + 'static, { - let mut sm = StateMachine { - backend: trie_backend, - changes_trie_storage: None as Option<&changes_trie::InMemoryStorage>, - offchain_ext: NeverOffchainExt::new(), - overlay, - exec, - method, - call_data, - keystore, - _hasher: PhantomData, - }; + let mut sm = StateMachine::<_, H, _, InMemoryChangesTrieStorage, _, Exec>::new( + trie_backend, None, NeverOffchainExt::new(), overlay, exec, method, call_data, keystore, + ); + sm.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>( native_else_wasm(), false, @@ -818,11 +504,11 @@ pub fn prove_read( where B: Backend, H: Hasher, - H::Out: Ord + H::Out: Ord, { let trie_backend = backend.as_trie_backend() .ok_or_else( - ||Box::new(ExecutionError::UnableToGenerateProof) as Box + || Box::new(ExecutionError::UnableToGenerateProof) as Box )?; prove_read_on_trie_backend(trie_backend, key) } @@ -836,14 +522,13 @@ pub fn prove_child_read( where B: Backend, H: Hasher, - H::Out: Ord + H::Out: Ord, { let trie_backend = backend.as_trie_backend() .ok_or_else(|| Box::new(ExecutionError::UnableToGenerateProof) as Box)?; prove_child_read_on_trie_backend(trie_backend, storage_key, key) } - /// Generate storage read proof on pre-created trie backend. pub fn prove_read_on_trie_backend( trie_backend: &TrieBackend, @@ -852,7 +537,7 @@ pub fn prove_read_on_trie_backend( where S: trie_backend_essence::TrieBackendStorage, H: Hasher, - H::Out: Ord + H::Out: Ord, { let proving_backend = proving_backend::ProvingBackend::<_, H>::new(trie_backend); let result = proving_backend.storage(key).map_err(|e| Box::new(e) as Box)?; @@ -868,10 +553,11 @@ pub fn prove_child_read_on_trie_backend( where S: trie_backend_essence::TrieBackendStorage, H: Hasher, - H::Out: Ord + H::Out: Ord, { let proving_backend = proving_backend::ProvingBackend::<_, H>::new(trie_backend); - let result = proving_backend.child_storage(storage_key, key).map_err(|e| Box::new(e) as Box)?; + let result = proving_backend.child_storage(storage_key, key) + .map_err(|e| Box::new(e) as Box)?; Ok((result, proving_backend.extract_proof())) } @@ -883,7 +569,7 @@ pub fn read_proof_check( ) -> Result>, Box> where H: Hasher, - H::Out: Ord + H::Out: Ord, { let proving_backend = create_proof_check_backend::(root, proof)?; read_proof_check_on_proving_backend(&proving_backend, key) @@ -898,13 +584,12 @@ pub fn read_child_proof_check( ) -> Result>, Box> where H: Hasher, - H::Out: Ord + H::Out: Ord, { let proving_backend = create_proof_check_backend::(root, proof)?; read_child_proof_check_on_proving_backend(&proving_backend, storage_key, key) } - /// Check storage read proof on pre-created proving backend. pub fn read_proof_check_on_proving_backend( proving_backend: &TrieBackend, H>, @@ -912,7 +597,7 @@ pub fn read_proof_check_on_proving_backend( ) -> Result>, Box> where H: Hasher, - H::Out: Ord + H::Out: Ord, { proving_backend.storage(key).map_err(|e| Box::new(e) as Box) } @@ -925,14 +610,14 @@ pub fn read_child_proof_check_on_proving_backend( ) -> Result>, Box> where H: Hasher, - H::Out: Ord + H::Out: Ord, { proving_backend.child_storage(storage_key, key).map_err(|e| Box::new(e) as Box) } /// Sets overlayed changes' changes trie configuration. Returns error if configuration /// differs from previous OR config decode has failed. -pub(crate) fn set_changes_trie_config( +fn set_changes_trie_config( overlay: &mut OverlayedChanges, config: Option>, final_check: bool, @@ -956,12 +641,10 @@ pub(crate) fn set_changes_trie_config( } /// Reads storage value from overlay or from the backend. -fn try_read_overlay_value(overlay: &OverlayedChanges, backend: &B, key: &[u8]) - -> Result>, Box> -where - H: Hasher, - B: Backend, -{ +fn try_read_overlay_value( + overlay: &OverlayedChanges, + backend: &B, key: &[u8], +) -> Result>, Box> where H: Hasher, B: Backend { match overlay.storage(key).map(|x| x.map(|x| x.to_vec())) { Some(value) => Ok(value), None => backend @@ -982,7 +665,7 @@ mod tests { InMemoryStorage as InMemoryChangesTrieStorage, Configuration as ChangesTrieConfig, }; - use primitives::{Blake2Hasher, map}; + use primitives::{Blake2Hasher, map, traits::Externalities, child_storage_key::ChildStorageKey}; struct DummyCodeExecutor { change_changes_trie_config: bool, @@ -1034,15 +717,17 @@ mod tests { } } - impl Error for u8 {} - #[test] fn execute_works() { - assert_eq!(new( - &trie_backend::tests::test_trie(), - Some(&InMemoryChangesTrieStorage::::new()), + let backend = trie_backend::tests::test_trie(); + let mut overlayed_changes = Default::default(); + let changes_trie_storage = InMemoryChangesTrieStorage::::new(); + + let mut state_machine = StateMachine::new( + backend, + Some(&changes_trie_storage), NeverOffchainExt::new(), - &mut Default::default(), + &mut overlayed_changes, &DummyCodeExecutor { change_changes_trie_config: false, native_available: true, @@ -1052,19 +737,26 @@ mod tests { "test", &[], None, - ).execute( - ExecutionStrategy::NativeWhenPossible - ).unwrap().0, vec![66]); + ); + + assert_eq!( + state_machine.execute(ExecutionStrategy::NativeWhenPossible).unwrap().0, + vec![66], + ); } #[test] fn execute_works_with_native_else_wasm() { - assert_eq!(new( - &trie_backend::tests::test_trie(), - Some(&InMemoryChangesTrieStorage::::new()), + let backend = trie_backend::tests::test_trie(); + let mut overlayed_changes = Default::default(); + let changes_trie_storage = InMemoryChangesTrieStorage::::new(); + + let mut state_machine = StateMachine::new( + backend, + Some(&changes_trie_storage), NeverOffchainExt::new(), - &mut Default::default(), + &mut overlayed_changes, &DummyCodeExecutor { change_changes_trie_config: false, native_available: true, @@ -1074,19 +766,23 @@ mod tests { "test", &[], None, - ).execute( - ExecutionStrategy::NativeElseWasm - ).unwrap().0, vec![66]); + ); + + assert_eq!(state_machine.execute(ExecutionStrategy::NativeElseWasm).unwrap().0, vec![66]); } #[test] fn dual_execution_strategy_detects_consensus_failure() { let mut consensus_failed = false; - assert!(new( - &trie_backend::tests::test_trie(), - Some(&InMemoryChangesTrieStorage::::new()), + let backend = trie_backend::tests::test_trie(); + let mut overlayed_changes = Default::default(); + let changes_trie_storage = InMemoryChangesTrieStorage::::new(); + + let mut state_machine = StateMachine::new( + backend, + Some(&changes_trie_storage), NeverOffchainExt::new(), - &mut Default::default(), + &mut overlayed_changes, &DummyCodeExecutor { change_changes_trie_config: false, native_available: true, @@ -1096,14 +792,18 @@ mod tests { "test", &[], None, - ).execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>( - ExecutionManager::Both(|we, _ne| { - consensus_failed = true; - we - }), - true, - None, - ).is_err()); + ); + + assert!( + state_machine.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>( + ExecutionManager::Both(|we, _ne| { + consensus_failed = true; + we + }), + true, + None, + ).is_err() + ); assert!(consensus_failed); } @@ -1276,47 +976,51 @@ mod tests { #[test] fn cannot_change_changes_trie_config() { - assert!( - new( - &trie_backend::tests::test_trie(), - Some(&InMemoryChangesTrieStorage::::new()), - NeverOffchainExt::new(), - &mut Default::default(), - &DummyCodeExecutor { - change_changes_trie_config: true, - native_available: false, - native_succeeds: true, - fallback_succeeds: true, - }, - "test", - &[], - None, - ) - .execute(ExecutionStrategy::NativeWhenPossible) - .is_err() + let backend = trie_backend::tests::test_trie(); + let mut overlayed_changes = Default::default(); + let changes_trie_storage = InMemoryChangesTrieStorage::::new(); + + let mut state_machine = StateMachine::new( + backend, + Some(&changes_trie_storage), + NeverOffchainExt::new(), + &mut overlayed_changes, + &DummyCodeExecutor { + change_changes_trie_config: true, + native_available: false, + native_succeeds: true, + fallback_succeeds: true, + }, + "test", + &[], + None, ); + + assert!(state_machine.execute(ExecutionStrategy::NativeWhenPossible).is_err()); } #[test] fn cannot_change_changes_trie_config_with_native_else_wasm() { - assert!( - new( - &trie_backend::tests::test_trie(), - Some(&InMemoryChangesTrieStorage::::new()), - NeverOffchainExt::new(), - &mut Default::default(), - &DummyCodeExecutor { - change_changes_trie_config: true, - native_available: false, - native_succeeds: true, - fallback_succeeds: true, - }, - "test", - &[], - None, - ) - .execute(ExecutionStrategy::NativeElseWasm) - .is_err() + let backend = trie_backend::tests::test_trie(); + let mut overlayed_changes = Default::default(); + let changes_trie_storage = InMemoryChangesTrieStorage::::new(); + + let mut state_machine = StateMachine::new( + backend, + Some(&changes_trie_storage), + NeverOffchainExt::new(), + &mut overlayed_changes, + &DummyCodeExecutor { + change_changes_trie_config: true, + native_available: false, + native_succeeds: true, + fallback_succeeds: true, + }, + "test", + &[], + None, ); + + assert!(state_machine.execute(ExecutionStrategy::NativeElseWasm).is_err()); } } diff --git a/core/state-machine/src/overlayed_changes.rs b/core/state-machine/src/overlayed_changes.rs index 1dbf2a4352..a4952ddf73 100644 --- a/core/state-machine/src/overlayed_changes.rs +++ b/core/state-machine/src/overlayed_changes.rs @@ -16,7 +16,8 @@ //! The overlayed changes to state. -#[cfg(test)] use std::iter::FromIterator; +#[cfg(test)] +use std::iter::FromIterator; use std::collections::{HashMap, BTreeSet}; use codec::Decode; use crate::changes_trie::{NO_EXTRINSIC_INDEX, Configuration as ChangesTrieConfig}; @@ -350,12 +351,12 @@ impl From>> for OverlayedValue { #[cfg(test)] mod tests { use hex_literal::hex; - use primitives::{Blake2Hasher, H256}; - use primitives::storage::well_known_keys::EXTRINSIC_INDEX; + use primitives::{ + Blake2Hasher, H256, traits::Externalities, storage::well_known_keys::EXTRINSIC_INDEX, + }; use crate::backend::InMemory; use crate::changes_trie::InMemoryStorage as InMemoryChangesTrieStorage; use crate::ext::Ext; - use crate::Externalities; use super::*; fn strip_extrinsic_index(map: &HashMap, OverlayedValue>) -> HashMap, OverlayedValue> { diff --git a/core/state-machine/src/proving_backend.rs b/core/state-machine/src/proving_backend.rs index 2b44aae778..64ec7de81b 100644 --- a/core/state-machine/src/proving_backend.rs +++ b/core/state-machine/src/proving_backend.rs @@ -128,9 +128,8 @@ impl<'a, S: 'a + TrieBackendStorage, H: 'a + Hasher> ProvingBackend<'a, S, H> } } - /// Consume the backend, extracting the gathered proof in lexicographical order - /// by value. - pub fn extract_proof(self) -> Vec> { + /// Consume the backend, extracting the gathered proof in lexicographical order by value. + pub fn extract_proof(&self) -> Vec> { self.proof_recorder .borrow_mut() .drain() @@ -207,10 +206,6 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> { self.backend.child_storage_root(storage_key, delta) } - - fn as_trie_backend(&mut self) -> Option<&TrieBackend> { - None - } } /// Create proof check backend. @@ -249,8 +244,7 @@ mod tests { use crate::backend::{InMemory}; use crate::trie_backend::tests::test_trie; use super::*; - use primitives::{Blake2Hasher}; - use crate::ChildStorageKey; + use primitives::{Blake2Hasher, child_storage_key::ChildStorageKey}; fn test_proving<'a>( trie_backend: &'a TrieBackend,Blake2Hasher>, @@ -315,12 +309,8 @@ mod tests { #[test] fn proof_recorded_and_checked_with_child() { - let subtrie1 = ChildStorageKey::::from_slice( - b":child_storage:default:sub1" - ).unwrap(); - let subtrie2 = ChildStorageKey::::from_slice( - b":child_storage:default:sub2" - ).unwrap(); + let subtrie1 = ChildStorageKey::from_slice(b":child_storage:default:sub1").unwrap(); + let subtrie2 = ChildStorageKey::from_slice(b":child_storage:default:sub2").unwrap(); let own1 = subtrie1.into_owned(); let own2 = subtrie2.into_owned(); let contents = (0..64).map(|i| (None, vec![i], Some(vec![i]))) diff --git a/core/state-machine/src/testing.rs b/core/state-machine/src/testing.rs index a40026b271..2ee2268c0e 100644 --- a/core/state-machine/src/testing.rs +++ b/core/state-machine/src/testing.rs @@ -18,17 +18,18 @@ use std::collections::{HashMap}; use hash_db::Hasher; -use crate::backend::{InMemory, Backend}; -use primitives::storage::well_known_keys::is_child_storage_key; -use crate::changes_trie::{ - build_changes_trie, InMemoryStorage as ChangesTrieInMemoryStorage, - BlockNumber as ChangesTrieBlockNumber, +use crate::{ + backend::{InMemory, Backend}, OverlayedChanges, + changes_trie::{ + build_changes_trie, InMemoryStorage as ChangesTrieInMemoryStorage, + BlockNumber as ChangesTrieBlockNumber, + }, }; use primitives::{ - storage::well_known_keys::{CHANGES_TRIE_CONFIG, CODE, HEAP_PAGES}, traits::BareCryptoStorePtr, offchain + storage::well_known_keys::{CHANGES_TRIE_CONFIG, CODE, HEAP_PAGES, is_child_storage_key}, + traits::{BareCryptoStorePtr, Externalities}, offchain, child_storage_key::ChildStorageKey, }; use codec::Encode; -use super::{ChildStorageKey, Externalities, OverlayedChanges}; const EXT_NOT_ALLOWED_TO_FAIL: &str = "Externalities not allowed to fail within runtime"; @@ -156,7 +157,7 @@ impl Externalities for TestExternalities self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL) } - fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { + fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { self.overlay .child_storage(storage_key.as_ref(), key) .map(|x| x.map(|x| x.to_vec())) @@ -166,7 +167,7 @@ impl Externalities for TestExternalities ) } - fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { + fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { self.backend .child_storage(storage_key.as_ref(), key) .map(|x| x.map(|x| x.to_vec())) @@ -183,14 +184,14 @@ impl Externalities for TestExternalities fn place_child_storage( &mut self, - storage_key: ChildStorageKey, + storage_key: ChildStorageKey, key: Vec, value: Option> ) { self.overlay.set_child_storage(storage_key.into_owned(), key, value); } - fn kill_child_storage(&mut self, storage_key: ChildStorageKey) { + fn kill_child_storage(&mut self, storage_key: ChildStorageKey) { let backend = &self.backend; let overlay = &mut self.overlay; @@ -214,7 +215,7 @@ impl Externalities for TestExternalities }); } - fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]) { + fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]) { self.overlay.clear_child_prefix(storage_key.as_ref(), prefix); @@ -249,7 +250,7 @@ impl Externalities for TestExternalities } - fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { + fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { let storage_key = storage_key.as_ref(); let (root, is_empty, _) = { diff --git a/core/state-machine/src/trie_backend.rs b/core/state-machine/src/trie_backend.rs index 01e36a5810..105e20c9b7 100644 --- a/core/state-machine/src/trie_backend.rs +++ b/core/state-machine/src/trie_backend.rs @@ -57,8 +57,6 @@ impl, H: Hasher> TrieBackend { } } -impl super::Error for String {} - impl, H: Hasher> Backend for TrieBackend where H::Out: Ord, { diff --git a/core/trie/src/lib.rs b/core/trie/src/lib.rs index e526a27ebe..3cc85731d8 100644 --- a/core/trie/src/lib.rs +++ b/core/trie/src/lib.rs @@ -166,25 +166,6 @@ pub fn read_trie_value_with< Ok(TrieDB::::new(&*db, root)?.get_with(key, query).map(|x| x.map(|val| val.to_vec()))?) } -/// Determine whether a child trie key is valid. -/// -/// For now, the only valid child trie key is `:child_storage:default:`. -/// -/// `child_trie_root` and `child_delta_trie_root` can panic if invalid value is provided to them. -pub fn is_child_trie_key_valid(storage_key: &[u8]) -> bool { - use primitives::storage::well_known_keys; - let has_right_prefix = storage_key.starts_with(b":child_storage:default:"); - if has_right_prefix { - // This is an attempt to catch a change of `is_child_storage_key`, which - // just checks if the key has prefix `:child_storage:` at the moment of writing. - debug_assert!( - well_known_keys::is_child_storage_key(&storage_key), - "`is_child_trie_key_valid` is a subset of `is_child_storage_key`", - ); - } - has_right_prefix -} - /// Determine the default child trie root. pub fn default_child_trie_root(_storage_key: &[u8]) -> Vec { L::trie_root::<_, Vec, Vec>(core::iter::empty()).as_ref().iter().cloned().collect() diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index fc0ca39049..1fef4bba7a 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -40,10 +40,13 @@ mod tests { use runtime_io; use substrate_executor::WasmExecutor; use codec::{Encode, Decode, Joiner}; - use runtime_support::{Hashable, StorageValue, StorageMap, assert_eq_error_rate, traits::Currency}; - use state_machine::{CodeExecutor, Externalities, TestExternalities as CoreTestExternalities}; - use primitives::{Blake2Hasher, NeverNativeValue, NativeOrEncoded, map}; - use node_primitives::{Hash, BlockNumber, Balance}; + use runtime_support::{ + Hashable, StorageValue, StorageMap, assert_eq_error_rate, traits::Currency, + }; + use state_machine::TestExternalities as CoreTestExternalities; + use primitives::{ + Blake2Hasher, NeverNativeValue, NativeOrEncoded, map, traits::{CodeExecutor, Externalities}, + }; use sr_primitives::{ traits::{Header as HeaderT, Hash as HashT, Convert}, ApplyOutcome, ApplyResult, transaction_validity::InvalidTransaction, weights::{WeightMultiplier, GetDispatchInfo}, @@ -53,9 +56,9 @@ mod tests { use node_runtime::{ Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances, BuildStorage, System, Event, TransferFee, TransactionBaseFee, TransactionByteFee, + constants::currency::*, impls::WeightToFee, }; - use node_runtime::constants::currency::*; - use node_runtime::impls::WeightToFee; + use node_primitives::{Balance, Hash, BlockNumber}; use node_testing::keyring::*; use wabt; -- GitLab From 12896e9c8df1ffdadb2f385b5c463185a7bef68b Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 11 Sep 2019 10:27:32 +0300 Subject: [PATCH 075/275] Never panic during execution proof check (#3504) * do not panic during execution proof check * Update core/state-machine/src/lib.rs Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> * Update core/state-machine/src/lib.rs Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> * Update core/state-machine/src/lib.rs Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> * BackendTrustLevel enum * up runtime version * Update core/state-machine/src/lib.rs Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> * Update core/state-machine/src/lib.rs Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> * fixed some grumbles * Update core/state-machine/src/testing.rs Co-Authored-By: Gavin Wood * Update core/state-machine/src/lib.rs Co-Authored-By: Gavin Wood * mov where * spaces -> tabs (to restart build) --- Cargo.lock | 1 + core/client/Cargo.toml | 1 + core/client/src/client.rs | 4 +- core/client/src/light/call_executor.rs | 84 +++++++++++++++-- core/consensus/aura/src/lib.rs | 2 +- core/consensus/babe/src/tests.rs | 2 +- core/executor/src/wasm_executor.rs | 89 +++++++++++++++---- core/network/src/config.rs | 28 +++--- core/network/src/test/mod.rs | 2 +- core/panic-handler/src/lib.rs | 51 ++++++++--- core/rpc/api/src/author/mod.rs | 1 - core/state-machine/src/changes_trie/build.rs | 4 +- .../state-machine/src/changes_trie/storage.rs | 2 +- core/state-machine/src/ext.rs | 6 +- core/state-machine/src/lib.rs | 41 +++++++-- core/state-machine/src/testing.rs | 9 +- node/executor/src/lib.rs | 3 +- node/runtime/src/lib.rs | 2 +- 18 files changed, 254 insertions(+), 78 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5b09589be9..59028fbc61 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4630,6 +4630,7 @@ dependencies = [ "substrate-executor 2.0.0", "substrate-inherents 2.0.0", "substrate-keyring 2.0.0", + "substrate-panic-handler 2.0.0", "substrate-primitives 2.0.0", "substrate-state-machine 2.0.0", "substrate-telemetry 2.0.0", diff --git a/core/client/Cargo.toml b/core/client/Cargo.toml index 76daf1dc60..3fc7407a7c 100644 --- a/core/client/Cargo.toml +++ b/core/client/Cargo.toml @@ -33,6 +33,7 @@ env_logger = "0.6" tempfile = "3.1" test-client = { package = "substrate-test-runtime-client", path = "../test-runtime/client" } kvdb-memorydb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" } +panic-handler = { package = "substrate-panic-handler", path = "../panic-handler" } [features] default = ["std"] diff --git a/core/client/src/client.rs b/core/client/src/client.rs index c7df30d8ae..63d30b45e3 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -43,7 +43,7 @@ use state_machine::{ DBValue, Backend as StateBackend, ChangesTrieAnchorBlockId, ExecutionStrategy, ExecutionManager, prove_read, prove_child_read, ChangesTrieRootsStorage, ChangesTrieStorage, ChangesTrieTransaction, ChangesTrieConfigurationRange, key_changes, key_changes_proof, - OverlayedChanges, + OverlayedChanges, BackendTrustLevel, }; use executor::{RuntimeVersion, RuntimeInfo}; use consensus::{ @@ -1043,7 +1043,7 @@ impl Client where let get_execution_manager = |execution_strategy: ExecutionStrategy| { match execution_strategy { ExecutionStrategy::NativeElseWasm => ExecutionManager::NativeElseWasm, - ExecutionStrategy::AlwaysWasm => ExecutionManager::AlwaysWasm, + ExecutionStrategy::AlwaysWasm => ExecutionManager::AlwaysWasm(BackendTrustLevel::Trusted), ExecutionStrategy::NativeWhenPossible => ExecutionManager::NativeWhenPossible, ExecutionStrategy::Both => ExecutionManager::Both(|wasm_result, native_result| { let header = import_headers.post(); diff --git a/core/client/src/light/call_executor.rs b/core/client/src/light/call_executor.rs index 370b6054e6..ab7b5b0a10 100644 --- a/core/client/src/light/call_executor.rs +++ b/core/client/src/light/call_executor.rs @@ -460,6 +460,32 @@ pub fn check_execution_proof( E: CodeExecutor, H: Hasher, H::Out: Ord + 'static, +{ + check_execution_proof_with_make_header( + executor, + request, + remote_proof, + |header|
::new( + *header.number() + One::one(), + Default::default(), + Default::default(), + header.hash(), + Default::default(), + ), + ) +} + +fn check_execution_proof_with_make_header Header>( + executor: &E, + request: &RemoteCallRequest
, + remote_proof: Vec>, + make_next_header: MakeNextHeader, +) -> ClientResult> + where + Header: HeaderT, + E: CodeExecutor, + H: Hasher, + H::Out: Ord + 'static, { let local_state_root = request.header.state_root(); let root: H::Out = convert_hash(&local_state_root); @@ -467,19 +493,13 @@ pub fn check_execution_proof( // prepare execution environment + check preparation proof let mut changes = OverlayedChanges::default(); let trie_backend = create_proof_check_backend(root, remote_proof)?; - let next_block =
::new( - *request.header.number() + One::one(), - Default::default(), - Default::default(), - request.header.hash(), - Default::default(), - ); + let next_header = make_next_header(&request.header); execution_proof_check_on_trie_backend::( &trie_backend, &mut changes, executor, "Core_initialize_block", - &next_block.encode(), + &next_header.encode(), None, )?; @@ -530,6 +550,43 @@ mod tests { (remote_result, local_result) } + fn execute_with_proof_failure(remote_client: &TestClient, at: u64, method: &'static str) { + let remote_block_id = BlockId::Number(at); + let remote_header = remote_client.header(&remote_block_id).unwrap().unwrap(); + + // 'fetch' execution proof from remote node + let (_, remote_execution_proof) = remote_client.execution_proof( + &remote_block_id, + method, + &[] + ).unwrap(); + + // check remote execution proof locally + let local_executor = NativeExecutor::::new(None); + let execution_result = check_execution_proof_with_make_header( + &local_executor, + &RemoteCallRequest { + block: test_client::runtime::Hash::default(), + header: remote_header, + method: method.into(), + call_data: vec![], + retry_count: None, + }, + remote_execution_proof, + |header|
::new( + at + 1, + Default::default(), + Default::default(), + header.hash(), + header.digest().clone(), // this makes next header wrong + ), + ); + match execution_result { + Err(crate::error::Error::Execution(_)) => (), + _ => panic!("Unexpected execution result: {:?}", execution_result), + } + } + // prepare remote client let remote_client = test_client::new(); for i in 1u32..3u32 { @@ -546,15 +603,24 @@ mod tests { let (remote, local) = execute(&remote_client, 0, "Core_version"); assert_eq!(remote, local); + let (remote, local) = execute(&remote_client, 2, "Core_version"); + assert_eq!(remote, local); + // check method that requires environment let (_, block) = execute(&remote_client, 0, "BlockBuilder_finalize_block"); let local_block: Header = Decode::decode(&mut &block[..]).unwrap(); assert_eq!(local_block.number, 1); - // check method that requires environment let (_, block) = execute(&remote_client, 2, "BlockBuilder_finalize_block"); let local_block: Header = Decode::decode(&mut &block[..]).unwrap(); assert_eq!(local_block.number, 3); + + // check that proof check doesn't panic even if proof is incorrect AND no panic handler is set + execute_with_proof_failure(&remote_client, 2, "Core_version"); + + // check that proof check doesn't panic even if proof is incorrect AND panic handler is set + panic_handler::set("TEST"); + execute_with_proof_failure(&remote_client, 2, "Core_version"); } #[test] diff --git a/core/consensus/aura/src/lib.rs b/core/consensus/aura/src/lib.rs index a2cf9e83bd..fd0ab30c9a 100644 --- a/core/consensus/aura/src/lib.rs +++ b/core/consensus/aura/src/lib.rs @@ -806,7 +806,7 @@ mod tests { keystore.write().insert_ephemeral_from_seed::(&key.to_seed()) .expect("Creates authority key"); keystore_paths.push(keystore_path); - + let environ = DummyFactory(client.clone()); import_notifications.push( client.import_notification_stream() diff --git a/core/consensus/babe/src/tests.rs b/core/consensus/babe/src/tests.rs index 2410cadbd5..7274cc1230 100644 --- a/core/consensus/babe/src/tests.rs +++ b/core/consensus/babe/src/tests.rs @@ -207,7 +207,7 @@ fn run_one_test() { let peer = net.peer(*peer_id); let client = peer.client().as_full().expect("Only full clients are used in tests").clone(); let select_chain = peer.select_chain().expect("Full client has select_chain"); - + let keystore_path = tempfile::tempdir().expect("Creates keystore path"); let keystore = keystore::Store::open(keystore_path.path(), None).expect("Creates keystore"); keystore.write().insert_ephemeral_from_seed::(seed).expect("Generates authority key"); diff --git a/core/executor/src/wasm_executor.rs b/core/executor/src/wasm_executor.rs index 4baa547ab8..1cef4b7cb1 100644 --- a/core/executor/src/wasm_executor.rs +++ b/core/executor/src/wasm_executor.rs @@ -19,7 +19,7 @@ //! This module defines and implements the wasm part of Substrate Host Interface and provides //! an interface for calling into the wasm runtime. -use std::{convert::TryFrom, str}; +use std::{convert::TryFrom, str, panic}; use tiny_keccak; use secp256k1; @@ -31,8 +31,8 @@ use crate::error::{Error, Result}; use codec::{Encode, Decode}; use primitives::{ blake2_128, blake2_256, twox_64, twox_128, twox_256, ed25519, sr25519, Pair, crypto::KeyTypeId, - offchain, hexdisplay::HexDisplay, sandbox as sandbox_primitives, H256, Blake2Hasher, - traits::Externalities, child_storage_key::ChildStorageKey, + offchain, hexdisplay::HexDisplay, sandbox as sandbox_primitives, Blake2Hasher, + traits::Externalities, }; use trie::{TrieConfiguration, trie_types::Layout}; use crate::sandbox; @@ -447,7 +447,9 @@ impl_wasm_host_interface! { .map_err(|_| "Invalid attempt to determine key in ext_set_storage")?; let value = context.read_memory(value_data, value_len) .map_err(|_| "Invalid attempt to determine value in ext_set_storage")?; - runtime_io::set_storage(&key, &value); + with_external_storage(move || + Ok(runtime_io::set_storage(&key, &value)) + )?; Ok(()) } @@ -466,7 +468,9 @@ impl_wasm_host_interface! { let value = context.read_memory(value_data, value_len) .map_err(|_| "Invalid attempt to determine value in ext_set_child_storage")?; - runtime_io::set_child_storage(&storage_key, &key, &value); + with_external_storage(move || + Ok(runtime_io::set_child_storage(&storage_key, &key, &value)) + )?; Ok(()) } @@ -481,21 +485,27 @@ impl_wasm_host_interface! { let key = context.read_memory(key_data, key_len) .map_err(|_| "Invalid attempt to determine key in ext_clear_child_storage")?; - runtime_io::clear_child_storage(&storage_key, &key); + with_external_storage(move || + Ok(runtime_io::clear_child_storage(&storage_key, &key)) + )?; Ok(()) } ext_clear_storage(key_data: Pointer, key_len: WordSize) { let key = context.read_memory(key_data, key_len) .map_err(|_| "Invalid attempt to determine key in ext_clear_storage")?; - runtime_io::clear_storage(&key); + with_external_storage(move || + Ok(runtime_io::clear_storage(&key)) + )?; Ok(()) } ext_exists_storage(key_data: Pointer, key_len: WordSize) -> u32 { let key = context.read_memory(key_data, key_len) .map_err(|_| "Invalid attempt to determine key in ext_exists_storage")?; - Ok(if runtime_io::exists_storage(&key) { 1 } else { 0 }) + with_external_storage(move || + Ok(if runtime_io::exists_storage(&key) { 1 } else { 0 }) + ) } ext_exists_child_storage( @@ -509,13 +519,17 @@ impl_wasm_host_interface! { let key = context.read_memory(key_data, key_len) .map_err(|_| "Invalid attempt to determine key in ext_exists_child_storage")?; - Ok(if runtime_io::exists_child_storage(&storage_key, &key) { 1 } else { 0 }) + with_external_storage(move || + Ok(if runtime_io::exists_child_storage(&storage_key, &key) { 1 } else { 0 }) + ) } ext_clear_prefix(prefix_data: Pointer, prefix_len: WordSize) { let prefix = context.read_memory(prefix_data, prefix_len) .map_err(|_| "Invalid attempt to determine prefix in ext_clear_prefix")?; - runtime_io::clear_prefix(&prefix); + with_external_storage(move || + Ok(runtime_io::clear_prefix(&prefix)) + )?; Ok(()) } @@ -529,7 +543,9 @@ impl_wasm_host_interface! { .map_err(|_| "Invalid attempt to determine storage_key in ext_clear_child_prefix")?; let prefix = context.read_memory(prefix_data, prefix_len) .map_err(|_| "Invalid attempt to determine prefix in ext_clear_child_prefix")?; - runtime_io::clear_child_prefix(&storage_key, &prefix); + with_external_storage(move || + Ok(runtime_io::clear_child_prefix(&storage_key, &prefix)) + )?; Ok(()) } @@ -537,7 +553,9 @@ impl_wasm_host_interface! { ext_kill_child_storage(storage_key_data: Pointer, storage_key_len: WordSize) { let storage_key = context.read_memory(storage_key_data, storage_key_len) .map_err(|_| "Invalid attempt to determine storage_key in ext_kill_child_storage")?; - runtime_io::kill_child_storage(&storage_key); + with_external_storage(move || + Ok(runtime_io::kill_child_storage(&storage_key)) + )?; Ok(()) } @@ -549,7 +567,9 @@ impl_wasm_host_interface! { ) -> Pointer { let key = context.read_memory(key_data, key_len) .map_err(|_| "Invalid attempt to determine key in ext_get_allocated_storage")?; - let maybe_value = runtime_io::storage(&key); + let maybe_value = with_external_storage(move || + Ok(runtime_io::storage(&key)) + )?; if let Some(value) = maybe_value { let offset = context.allocate_memory(value.len() as u32)?; @@ -577,7 +597,9 @@ impl_wasm_host_interface! { let key = context.read_memory(key_data, key_len) .map_err(|_| "Invalid attempt to determine key in ext_get_allocated_child_storage")?; - let maybe_value = runtime_io::child_storage(&storage_key, &key); + let maybe_value = with_external_storage(move || + Ok(runtime_io::child_storage(&storage_key, &key)) + )?; if let Some(value) = maybe_value { let offset = context.allocate_memory(value.len() as u32)?; @@ -602,7 +624,9 @@ impl_wasm_host_interface! { ) -> WordSize { let key = context.read_memory(key_data, key_len) .map_err(|_| "Invalid attempt to get key in ext_get_storage_into")?; - let maybe_value = runtime_io::storage(&key); + let maybe_value = with_external_storage(move || + Ok(runtime_io::storage(&key)) + )?; if let Some(value) = maybe_value { let value = &value[value_offset as usize..]; @@ -629,7 +653,9 @@ impl_wasm_host_interface! { let key = context.read_memory(key_data, key_len) .map_err(|_| "Invalid attempt to get key in ext_get_child_storage_into")?; - let maybe_value = runtime_io::child_storage(&storage_key, &key); + let maybe_value = with_external_storage(move || + Ok(runtime_io::child_storage(&storage_key, &key)) + )?; if let Some(value) = maybe_value { let value = &value[value_offset as usize..]; @@ -643,7 +669,9 @@ impl_wasm_host_interface! { } ext_storage_root(result: Pointer) { - let r = runtime_io::storage_root(); + let r = with_external_storage(move || + Ok(runtime_io::storage_root()) + )?; context.write_memory(result, r.as_ref()) .map_err(|_| "Invalid attempt to set memory in ext_storage_root")?; Ok(()) @@ -656,7 +684,9 @@ impl_wasm_host_interface! { ) -> Pointer { let storage_key = context.read_memory(storage_key_data, storage_key_len) .map_err(|_| "Invalid attempt to determine storage_key in ext_child_storage_root")?; - let value = runtime_io::child_storage_root(&storage_key); + let value = with_external_storage(move || + Ok(runtime_io::child_storage_root(&storage_key)) + )?; let offset = context.allocate_memory(value.len() as u32)?; context.write_memory(offset, &value) @@ -674,7 +704,9 @@ impl_wasm_host_interface! { let mut parent_hash = [0u8; 32]; context.read_memory_into(parent_hash_data, &mut parent_hash[..]) .map_err(|_| "Invalid attempt to get parent_hash in ext_storage_changes_root")?; - let r = runtime_io::storage_changes_root(parent_hash); + let r = with_external_storage(move || + Ok(runtime_io::storage_changes_root(parent_hash)) + )?; if let Some(r) = r { context.write_memory(result, &r[..]) @@ -1331,6 +1363,25 @@ impl_wasm_host_interface! { } } +/// Execute closure that access external storage. +/// +/// All panics that happen within closure are captured and transformed into +/// runtime error. This requires special panic handler mode to be enabled +/// during the call (see `panic_handler::AbortGuard::never_abort`). +/// If this mode isn't enabled, then all panics within externalities are +/// leading to process abort. +fn with_external_storage(f: F) -> std::result::Result + where + F: panic::UnwindSafe + FnOnce() -> Result +{ + // it is safe beause basic methods of StorageExternalities are guaranteed to touch only + // its internal state + we should discard it on error + panic::catch_unwind(move || f()) + .map_err(|_| Error::Runtime) + .and_then(|result| result) + .map_err(|err| format!("{}", err)) +} + /// Wasm rust executor for contracts. /// /// Executes the provided code in a sandboxed wasm runtime. diff --git a/core/network/src/config.rs b/core/network/src/config.rs index 46bb8aeff4..7392a4aaf7 100644 --- a/core/network/src/config.rs +++ b/core/network/src/config.rs @@ -205,23 +205,23 @@ pub enum ParseErr { } impl fmt::Display for ParseErr { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - ParseErr::MultiaddrParse(err) => write!(f, "{}", err), - ParseErr::InvalidPeerId => write!(f, "Peer id at the end of the address is invalid"), - ParseErr::PeerIdMissing => write!(f, "Peer id is missing from the address"), - } - } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ParseErr::MultiaddrParse(err) => write!(f, "{}", err), + ParseErr::InvalidPeerId => write!(f, "Peer id at the end of the address is invalid"), + ParseErr::PeerIdMissing => write!(f, "Peer id is missing from the address"), + } + } } impl std::error::Error for ParseErr { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match self { - ParseErr::MultiaddrParse(err) => Some(err), - ParseErr::InvalidPeerId => None, - ParseErr::PeerIdMissing => None, - } - } + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + ParseErr::MultiaddrParse(err) => Some(err), + ParseErr::InvalidPeerId => None, + ParseErr::PeerIdMissing => None, + } + } } impl From for ParseErr { diff --git a/core/network/src/test/mod.rs b/core/network/src/test/mod.rs index a025bd663a..f6c866d76d 100644 --- a/core/network/src/test/mod.rs +++ b/core/network/src/test/mod.rs @@ -348,7 +348,7 @@ impl> Peer { /// Test helper to compare the blockchain state of multiple (networked) /// clients. /// Potentially costly, as it creates in-memory copies of both blockchains in order - /// to compare them. If you have easier/softer checks that are sufficient, e.g. + /// to compare them. If you have easier/softer checks that are sufficient, e.g. /// by using .info(), you should probably use it instead of this. pub fn blockchain_canon_equals(&self, other: &Self) -> bool { if let (Some(mine), Some(others)) = (self.backend.clone(), other.backend.clone()) { diff --git a/core/panic-handler/src/lib.rs b/core/panic-handler/src/lib.rs index 287ff72a6a..2c04700e96 100644 --- a/core/panic-handler/src/lib.rs +++ b/core/panic-handler/src/lib.rs @@ -31,7 +31,18 @@ use std::cell::Cell; use std::thread; thread_local! { - static ABORT: Cell = Cell::new(true); + static ON_PANIC: Cell = Cell::new(OnPanic::Abort); +} + +/// Panic action. +#[derive(Debug, Clone, Copy, PartialEq)] +enum OnPanic { + /// Abort when panic occurs. + Abort, + /// Unwind when panic occurs. + Unwind, + /// Always unwind even if someone changes strategy to Abort afterwards. + NeverAbort, } /// Set the panic hook. @@ -52,10 +63,13 @@ This is a bug. Please report it at: ")} /// Set aborting flag. Returns previous value of the flag. -fn set_abort(enabled: bool) -> bool { - ABORT.with(|flag| { - let prev = flag.get(); - flag.set(enabled); +fn set_abort(on_panic: OnPanic) -> OnPanic { + ON_PANIC.with(|val| { + let prev = val.get(); + match prev { + OnPanic::Abort | OnPanic::Unwind => val.set(on_panic), + OnPanic::NeverAbort => (), + } prev }) } @@ -69,7 +83,7 @@ fn set_abort(enabled: bool) -> bool { /// > the `AbortGuard` on the stack and let it destroy itself naturally. pub struct AbortGuard { /// Value that was in `ABORT` before we created this guard. - previous_val: bool, + previous_val: OnPanic, /// Marker so that `AbortGuard` doesn't implement `Send`. _not_send: PhantomData> } @@ -79,7 +93,7 @@ impl AbortGuard { /// unwind the stack (unless another guard is created afterwards). pub fn force_unwind() -> AbortGuard { AbortGuard { - previous_val: set_abort(false), + previous_val: set_abort(OnPanic::Unwind), _not_send: PhantomData } } @@ -88,7 +102,16 @@ impl AbortGuard { /// abort the process (unless another guard is created afterwards). pub fn force_abort() -> AbortGuard { AbortGuard { - previous_val: set_abort(true), + previous_val: set_abort(OnPanic::Abort), + _not_send: PhantomData + } + } + + /// Create a new guard. While the guard is alive, panics that happen in the current thread will + /// **never** abort the process (even if `AbortGuard::force_abort()` guard will be created afterwards). + pub fn never_abort() -> AbortGuard { + AbortGuard { + previous_val: set_abort(OnPanic::NeverAbort), _not_send: PhantomData } } @@ -133,8 +156,8 @@ fn panic_hook(info: &PanicInfo, report_url: &'static str) { ); let _ = writeln!(stderr, ABOUT_PANIC!(), report_url); - ABORT.with(|flag| { - if flag.get() { + ON_PANIC.with(|val| { + if val.get() == OnPanic::Abort { ::std::process::exit(1); } }) @@ -150,4 +173,12 @@ mod tests { let _guard = AbortGuard::force_unwind(); ::std::panic::catch_unwind(|| panic!()).ok(); } + + #[test] + fn does_not_abort_after_never_abort() { + set("test"); + let _guard = AbortGuard::never_abort(); + let _guard = AbortGuard::force_abort(); + std::panic::catch_unwind(|| panic!()).ok(); + } } diff --git a/core/rpc/api/src/author/mod.rs b/core/rpc/api/src/author/mod.rs index e8314c5c5f..5cde56995a 100644 --- a/core/rpc/api/src/author/mod.rs +++ b/core/rpc/api/src/author/mod.rs @@ -84,4 +84,3 @@ pub trait AuthorApi { id: SubscriptionId ) -> Result; } - diff --git a/core/state-machine/src/changes_trie/build.rs b/core/state-machine/src/changes_trie/build.rs index 824bdd3542..10c38a41e2 100644 --- a/core/state-machine/src/changes_trie/build.rs +++ b/core/state-machine/src/changes_trie/build.rs @@ -111,7 +111,7 @@ fn prepare_extrinsics_input<'a, B, H, Number>( block: block.clone(), storage_key: storage_key.clone(), }; - + let iter = prepare_extrinsics_input_inner(backend, block, changes, Some(storage_key))?; children_result.insert(child_index, iter); } @@ -120,7 +120,7 @@ fn prepare_extrinsics_input<'a, B, H, Number>( Ok((top, children_result)) } - + fn prepare_extrinsics_input_inner<'a, B, H, Number>( backend: &'a B, block: &Number, diff --git a/core/state-machine/src/changes_trie/storage.rs b/core/state-machine/src/changes_trie/storage.rs index f8c556a46c..a82477bdc3 100644 --- a/core/state-machine/src/changes_trie/storage.rs +++ b/core/state-machine/src/changes_trie/storage.rs @@ -100,7 +100,7 @@ impl InMemoryStorage { for (storage_key, child_input) in children_inputs { for (block, pairs) in child_input { let root = insert_into_memory_db::(&mut mdb, pairs.into_iter().map(Into::into)); - + if let Some(root) = root { let ix = if let Some(ix) = top_inputs.iter().position(|v| v.0 == block) { ix diff --git a/core/state-machine/src/ext.rs b/core/state-machine/src/ext.rs index 129ed96ab9..6ce5b12085 100644 --- a/core/state-machine/src/ext.rs +++ b/core/state-machine/src/ext.rs @@ -174,13 +174,12 @@ where } impl<'a, B, T, H, N, O> Externalities for Ext<'a, H, N, B, T, O> -where - H: Hasher, +where H: Hasher, B: 'a + Backend, T: 'a + ChangesTrieStorage, - O: 'a + offchain::Externalities, H::Out: Ord + 'static, N: crate::changes_trie::BlockNumber, + O: 'a + offchain::Externalities, { fn storage(&self, key: &[u8]) -> Option> { let _guard = panic_handler::AbortGuard::force_abort(); @@ -371,6 +370,7 @@ where fn keystore(&self) -> Option { self.keystore.clone() } + } #[cfg(test)] diff --git a/core/state-machine/src/lib.rs b/core/state-machine/src/lib.rs index 41d9b092bd..4008ec7c23 100644 --- a/core/state-machine/src/lib.rs +++ b/core/state-machine/src/lib.rs @@ -89,13 +89,26 @@ pub enum ExecutionStrategy { NativeElseWasm, } +/// Storage backend trust level. +#[derive(Debug, Clone)] +pub enum BackendTrustLevel { + /// Panics from trusted backends are considered justified, and never caught. + Trusted, + /// Panics from untrusted backend are caught and interpreted as runtime error. + /// Untrusted backend may be missing some parts of the trie, so panics are not considered + /// fatal. + Untrusted, +} + /// Like `ExecutionStrategy` only it also stores a handler in case of consensus failure. #[derive(Clone)] pub enum ExecutionManager { /// Execute with the native equivalent if it is compatible with the given wasm module; otherwise fall back to the wasm. NativeWhenPossible, - /// Use the given wasm module. - AlwaysWasm, + /// Use the given wasm module. The backend on which code is executed code could be + /// trusted to provide all storage or not (i.e. the light client cannot be trusted to provide + /// for all storage queries since the storage entries it has come from an external node). + AlwaysWasm(BackendTrustLevel), /// Run with both the wasm and the native variant (if compatible). Call `F` in the case of any discrepency. Both(F), /// First native, then if that fails or is not possible, wasm. @@ -106,7 +119,7 @@ impl<'a, F> From<&'a ExecutionManager> for ExecutionStrategy { fn from(s: &'a ExecutionManager) -> Self { match *s { ExecutionManager::NativeWhenPossible => ExecutionStrategy::NativeWhenPossible, - ExecutionManager::AlwaysWasm => ExecutionStrategy::AlwaysWasm, + ExecutionManager::AlwaysWasm(_) => ExecutionStrategy::AlwaysWasm, ExecutionManager::NativeElseWasm => ExecutionStrategy::NativeElseWasm, ExecutionManager::Both(_) => ExecutionStrategy::Both, } @@ -119,7 +132,7 @@ impl ExecutionStrategy { self, ) -> ExecutionManager> { match self { - ExecutionStrategy::AlwaysWasm => ExecutionManager::AlwaysWasm, + ExecutionStrategy::AlwaysWasm => ExecutionManager::AlwaysWasm(BackendTrustLevel::Trusted), ExecutionStrategy::NativeWhenPossible => ExecutionManager::NativeWhenPossible, ExecutionStrategy::NativeElseWasm => ExecutionManager::NativeElseWasm, ExecutionStrategy::Both => ExecutionManager::Both(|wasm_result, native_result| { @@ -139,6 +152,16 @@ pub fn native_else_wasm() -> ExecutionManager ExecutionManager::NativeElseWasm } +/// Evaluate to ExecutionManager::AlwaysWasm with trusted backend, without having to figure out the type. +fn always_wasm() -> ExecutionManager> { + ExecutionManager::AlwaysWasm(BackendTrustLevel::Trusted) +} + +/// Evaluate ExecutionManager::AlwaysWasm with untrusted backend, without having to figure out the type. +fn always_untrusted_wasm() -> ExecutionManager> { + ExecutionManager::AlwaysWasm(BackendTrustLevel::Untrusted) +} + /// The substrate state machine. pub struct StateMachine<'a, B, H, N, T, O, Exec> { backend: B, @@ -375,7 +398,11 @@ impl<'a, B, H, N, T, O, Exec> StateMachine<'a, B, H, N, T, O, Exec> where orig_prospective, ) }, - ExecutionManager::AlwaysWasm => { + ExecutionManager::AlwaysWasm(trust_level) => { + let _abort_guard = match trust_level { + BackendTrustLevel::Trusted => None, + BackendTrustLevel::Untrusted => Some(panic_handler::AbortGuard::never_abort()), + }; let res = self.execute_aux(compute_tx, false, native_call); (res.0, res.2, res.3) }, @@ -444,7 +471,7 @@ where ); let (result, _, _) = sm.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>( - native_else_wasm(), + always_wasm(), false, None, )?; @@ -490,7 +517,7 @@ where ); sm.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>( - native_else_wasm(), + always_untrusted_wasm(), false, None, ).map(|(result, _, _)| result.into_encoded()) diff --git a/core/state-machine/src/testing.rs b/core/state-machine/src/testing.rs index 2ee2268c0e..160f7d2a47 100644 --- a/core/state-machine/src/testing.rs +++ b/core/state-machine/src/testing.rs @@ -142,11 +142,10 @@ impl From for TestExternalit } } -impl Externalities for TestExternalities - where - H: Hasher, - N: ChangesTrieBlockNumber, - H::Out: Ord + 'static +impl Externalities for TestExternalities where + H: Hasher, + N: ChangesTrieBlockNumber, + H::Out: Ord + 'static, { fn storage(&self, key: &[u8]) -> Option> { self.overlay.storage(key).map(|x| x.map(|x| x.to_vec())).unwrap_or_else(|| diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index 1fef4bba7a..41d7b834b0 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -45,7 +45,8 @@ mod tests { }; use state_machine::TestExternalities as CoreTestExternalities; use primitives::{ - Blake2Hasher, NeverNativeValue, NativeOrEncoded, map, traits::{CodeExecutor, Externalities}, + Blake2Hasher, NeverNativeValue, NativeOrEncoded, map, + traits::{CodeExecutor, Externalities}, }; use sr_primitives::{ traits::{Header as HeaderT, Hash as HashT, Convert}, ApplyOutcome, ApplyResult, diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 9d7ae5d9df..16a4b551cb 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 155, - impl_version: 155, + impl_version: 156, apis: RUNTIME_API_VERSIONS, }; -- GitLab From 1990cfc3024b8e6dd07921cbc0ca9cef333aa12d Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Wed, 11 Sep 2019 09:42:31 +0200 Subject: [PATCH 076/275] Use `--release` for running a Substrate dev node (#3591) * Use `--release` for running a Substrate dev node Otherwise users may run into block production time problems. * Update README.adoc --- README.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.adoc b/README.adoc index 48ccc3ef91..f700a554ce 100644 --- a/README.adoc +++ b/README.adoc @@ -277,9 +277,9 @@ Or just run the tests of a specific package (i.e. `cargo test -p srml-assets`) You can start a development chain with: [source, shell] -cargo run \-- --dev +cargo run --release -- --dev -Detailed logs may be shown by running the node with the following environment variables set: `RUST_LOG=debug RUST_BACKTRACE=1 cargo run \-- --dev`. +Detailed logs may be shown by running the node with the following environment variables set: `RUST_LOG=debug RUST_BACKTRACE=1 cargo run --release \-- --dev`. If you want to see the multi-node consensus algorithm in action locally, then you can create a local testnet with two validator nodes for Alice and Bob, who are the initial authorities of the genesis chain specification that have been endowed with a testnet DOTs. We'll give each node a name and expose them so they are listed on link:https://telemetry.polkadot.io/#/Local%20Testnet[Telemetry]. You'll need two terminal windows open. -- GitLab From 1fe6aaea4404558ef3b83486c6ebcd850010a9d0 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Wed, 11 Sep 2019 15:11:08 +0200 Subject: [PATCH 077/275] Fixes NPoS reward, along with tests, cleanups & docs corrections (#3595) * Minor cleanups and tests * Add another test * fix * Fix tests * Fix tests * Update srml/staking/src/tests.rs Co-Authored-By: thiolliere --- node/runtime/Cargo.toml | 34 +++++----- node/runtime/src/lib.rs | 2 +- srml/staking/src/inflation.rs | 68 ++++++++++++++----- srml/staking/src/lib.rs | 40 +++++++----- srml/staking/src/mock.rs | 12 ++-- srml/staking/src/tests.rs | 120 ++++++++++++++++++---------------- 6 files changed, 161 insertions(+), 115 deletions(-) diff --git a/node/runtime/Cargo.toml b/node/runtime/Cargo.toml index 9424788e2f..755c4afe84 100644 --- a/node/runtime/Cargo.toml +++ b/node/runtime/Cargo.toml @@ -6,45 +6,47 @@ edition = "2018" build = "build.rs" [dependencies] +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } integer-sqrt = { version = "0.1.2" } +rustc-hex = { version = "2.0", optional = true } safe-mix = { version = "1.0", default-features = false } -codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } +serde = { version = "1.0", optional = true } + +authority-discovery-primitives = { package = "substrate-authority-discovery-primitives", path = "../../core/authority-discovery/primitives", default-features = false } +babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../core/consensus/babe/primitives", default-features = false } client = { package = "substrate-client", path = "../../core/client", default-features = false } +node-primitives = { path = "../primitives", default-features = false } +offchain-primitives = { package = "substrate-offchain-primitives", path = "../../core/offchain/primitives", default-features = false } +primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } sr-staking-primitives = { path = "../../core/sr-staking-primitives", default-features = false } -offchain-primitives = { package = "substrate-offchain-primitives", path = "../../core/offchain/primitives", default-features = false } -authority-discovery-primitives = { package = "substrate-authority-discovery-primitives", path = "../../core/authority-discovery/primitives", default-features = false } +substrate-keyring = { path = "../../core/keyring", optional = true } +substrate-session = { path = "../../core/session", default-features = false } version = { package = "sr-version", path = "../../core/sr-version", default-features = false } -support = { package = "srml-support", path = "../../srml/support", default-features = false } + +authority-discovery = { package = "srml-authority-discovery", path = "../../srml/authority-discovery", default-features = false } authorship = { package = "srml-authorship", path = "../../srml/authorship", default-features = false } babe = { package = "srml-babe", path = "../../srml/babe", default-features = false } -babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../core/consensus/babe/primitives", default-features = false } balances = { package = "srml-balances", path = "../../srml/balances", default-features = false } -contracts = { package = "srml-contracts", path = "../../srml/contracts", default-features = false } collective = { package = "srml-collective", path = "../../srml/collective", default-features = false } +contracts = { package = "srml-contracts", path = "../../srml/contracts", default-features = false } democracy = { package = "srml-democracy", path = "../../srml/democracy", default-features = false } elections = { package = "srml-elections", path = "../../srml/elections", default-features = false } executive = { package = "srml-executive", path = "../../srml/executive", default-features = false } finality-tracker = { package = "srml-finality-tracker", path = "../../srml/finality-tracker", default-features = false } grandpa = { package = "srml-grandpa", path = "../../srml/grandpa", default-features = false } +im-online = { package = "srml-im-online", path = "../../srml/im-online", default-features = false } indices = { package = "srml-indices", path = "../../srml/indices", default-features = false } membership = { package = "srml-membership", path = "../../srml/membership", default-features = false } +offences = { package = "srml-offences", path = "../../srml/offences", default-features = false } session = { package = "srml-session", path = "../../srml/session", default-features = false, features = ["historical"] } staking = { package = "srml-staking", path = "../../srml/staking", default-features = false } +sudo = { package = "srml-sudo", path = "../../srml/sudo", default-features = false } +support = { package = "srml-support", path = "../../srml/support", default-features = false } system = { package = "srml-system", path = "../../srml/system", default-features = false } timestamp = { package = "srml-timestamp", path = "../../srml/timestamp", default-features = false } treasury = { package = "srml-treasury", path = "../../srml/treasury", default-features = false } -sudo = { package = "srml-sudo", path = "../../srml/sudo", default-features = false } -im-online = { package = "srml-im-online", path = "../../srml/im-online", default-features = false } -authority-discovery = { package = "srml-authority-discovery", path = "../../srml/authority-discovery", default-features = false } -offences = { package = "srml-offences", path = "../../srml/offences", default-features = false } -node-primitives = { path = "../primitives", default-features = false } -rustc-hex = { version = "2.0", optional = true } -serde = { version = "1.0", optional = true } -substrate-keyring = { path = "../../core/keyring", optional = true } -substrate-session = { path = "../../core/session", default-features = false } [build-dependencies] wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.2", path = "../../core/utils/wasm-builder-runner" } diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 16a4b551cb..4a1df077c4 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -82,7 +82,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 155, + spec_version: 156, impl_version: 156, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/staking/src/inflation.rs b/srml/staking/src/inflation.rs index 80065886d7..d39e16471b 100644 --- a/srml/staking/src/inflation.rs +++ b/srml/staking/src/inflation.rs @@ -97,8 +97,7 @@ struct PiecewiseLinear { impl PiecewiseLinear { /// Compute `f(n/d)*d`. This is useful to avoid loss of precision. - fn calculate_for_fraction_times_denominator(&self, n: N, d: N) -> N - where + fn calculate_for_fraction_times_denominator(&self, n: N, d: N) -> N where N: SimpleArithmetic + Clone { let part = self.pieces.iter() @@ -145,11 +144,10 @@ const I_NPOS: PiecewiseLinear = PiecewiseLinear { ] }; -/// Second per year for the Julian year (365.25 days). -const SECOND_PER_YEAR: u32 = 3600*24*36525/100; - /// The total payout to all validators (and their nominators) per era. /// +/// `era_duration` is expressed in millisecond. +/// /// Named P_NPoS in the [paper](http://research.web3.foundation/en/latest/polkadot/Token%20Ec /// onomics/#inflation-model). /// @@ -157,13 +155,14 @@ const SECOND_PER_YEAR: u32 = 3600*24*36525/100; /// i.e. `P_NPoS(x) = I_NPoS(x) * current_total_token * era_duration / year_duration` /// /// I_NPoS is the desired yearly inflation rate for nominated proof of stake. -pub fn compute_total_payout(npos_token_staked: N, total_tokens: N, era_duration: N) -> N -where +pub fn compute_total_payout(npos_token_staked: N, total_tokens: N, era_duration: u64) -> N where N: SimpleArithmetic + Clone { - let year_duration: N = SECOND_PER_YEAR.into(); - I_NPOS.calculate_for_fraction_times_denominator(npos_token_staked, total_tokens) - * era_duration / year_duration + // Milliseconds per year for the Julian year (365.25 days). + const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100; + + Perbill::from_rational_approximation(era_duration as u64, MILLISECONDS_PER_YEAR) + * I_NPOS.calculate_for_fraction_times_denominator(npos_token_staked, total_tokens) } #[allow(non_upper_case_globals, non_snake_case)] // To stick with paper notations @@ -182,12 +181,12 @@ mod test_inflation { fn new(x0: f64, y0: f64, x1: f64, y1: f64) -> Self { LinearFloat { a: (y1 - y0) / (x1 - x0), - b: (x0*y1 - x1*y0) / (x0 - x1), + b: (x0 * y1 - x1 * y0) / (x0 - x1), } } fn compute(&self, x: f64) -> f64 { - self.a*x + self.b + self.a * x + self.b } } @@ -204,12 +203,12 @@ mod test_inflation { // Left part from `x_ideal` fn I_left(x: f64) -> f64 { - I_0 + x * (i_ideal - I_0/x_ideal) + I_0 + x * (i_ideal - I_0 / x_ideal) } // Right part from `x_ideal` fn I_right(x: f64) -> f64 { - I_0 + (i_ideal*x_ideal - I_0) * 2_f64.powf((x_ideal-x)/d) + I_0 + (i_ideal * x_ideal - I_0) * 2_f64.powf((x_ideal - x) / d) } // Definition of I_NPoS in float @@ -221,6 +220,41 @@ mod test_inflation { } } + #[test] + fn npos_curve_is_sensible() { + const YEAR: u64 = 365 * 24 * 60 * 60 * 1000; + //super::I_NPOS.calculate_for_fraction_times_denominator(25, 100) + assert_eq!(super::compute_total_payout(0, 100_000u64, YEAR), 2_498); + assert_eq!(super::compute_total_payout(5_000, 100_000u64, YEAR), 3_247); + assert_eq!(super::compute_total_payout(25_000, 100_000u64, YEAR), 6_245); + assert_eq!(super::compute_total_payout(40_000, 100_000u64, YEAR), 8_494); + assert_eq!(super::compute_total_payout(50_000, 100_000u64, YEAR), 9_993); + assert_eq!(super::compute_total_payout(60_000, 100_000u64, YEAR), 4_380); + assert_eq!(super::compute_total_payout(75_000, 100_000u64, YEAR), 2_735); + assert_eq!(super::compute_total_payout(95_000, 100_000u64, YEAR), 2_518); + assert_eq!(super::compute_total_payout(100_000, 100_000u64, YEAR), 2_505); + + const DAY: u64 = 24 * 60 * 60 * 1000; + assert_eq!(super::compute_total_payout(25_000, 100_000u64, DAY), 17); + assert_eq!(super::compute_total_payout(50_000, 100_000u64, DAY), 27); + assert_eq!(super::compute_total_payout(75_000, 100_000u64, DAY), 7); + + const SIX_HOURS: u64 = 6 * 60 * 60 * 1000; + assert_eq!(super::compute_total_payout(25_000, 100_000u64, SIX_HOURS), 4); + assert_eq!(super::compute_total_payout(50_000, 100_000u64, SIX_HOURS), 6); + assert_eq!(super::compute_total_payout(75_000, 100_000u64, SIX_HOURS), 1); + + const HOUR: u64 = 60 * 60 * 1000; + assert_eq!( + super::compute_total_payout( + 2_500_000_000_000_000_000_000_000_000u128, + 5_000_000_000_000_000_000_000_000_000u128, + HOUR + ), + 57_038_500_000_000_000_000_000 + ); + } + // Compute approximation of I_NPoS into piecewise linear function fn I_NPoS_points() -> super::PiecewiseLinear { let mut points = vec![]; @@ -265,7 +299,7 @@ mod test_inflation { // Test error is not overflowed // Quick test on one point - if (I_right((x0 + next_x1)/2.0) - (y0 + next_y1)/2.0).abs() > GEN_ERROR { + if (I_right((x0 + next_x1) / 2.0) - (y0 + next_y1) / 2.0).abs() > GEN_ERROR { error_overflowed = true; } @@ -298,7 +332,7 @@ mod test_inflation { let pieces: Vec<(u32, super::Linear)> = (0..points.len()-1) .map(|i| { let p0 = points[i]; - let p1 = points[i+1]; + let p1 = points[i + 1]; let linear = LinearFloat::new(p0.0, p0.1, p1.0, p1.1); @@ -333,7 +367,7 @@ mod test_inflation { } /// This test ensure that i_npos piecewise linear approximation is close to the actual function. - /// It does compare the result from a computation in integer of different capcity and in f64. + /// It does compare the result from a computation in integer of different capacity and in f64. #[test] fn i_npos_precision() { const STEP_PRECISION: f64 = 0.000_001; diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index 837d12960d..3a77e89223 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -292,24 +292,27 @@ const STAKING_ID: LockIdentifier = *b"staking "; /// Counter for the number of eras that have passed. pub type EraIndex = u32; +/// Counter for the number of "reward" points earned by a given validator. +pub type Points = u32; + /// Reward points of an era. Used to split era total payout between validators. #[derive(Encode, Decode, Default)] -pub struct EraRewards { +pub struct EraPoints { /// Total number of points. Equals the sum of reward points for each validator. - total: u32, - /// Reward at one index correspond to reward for validator in current_elected of this index. - /// Thus this reward vec is only valid for one elected set. - rewards: Vec, + total: Points, + /// The reward points earned by a given validator. The index of this vec corresponds to the + /// index into the current validator set. + individual: Vec, } -impl EraRewards { +impl EraPoints { /// Add the reward to the validator at the given index. Index must be valid /// (i.e. `index < current_elected.len()`). fn add_points_to_index(&mut self, index: u32, points: u32) { if let Some(new_total) = self.total.checked_add(points) { self.total = new_total; - self.rewards.resize((index as usize + 1).max(self.rewards.len()), 0); - self.rewards[index as usize] += points; // Addition is less than total + self.individual.resize((index as usize + 1).max(self.individual.len()), 0); + self.individual[index as usize] += points; // Addition is less than total } } } @@ -590,7 +593,7 @@ decl_storage! { pub CurrentEraStartSessionIndex get(current_era_start_session_index): SessionIndex; /// Rewards for the current era. Using indices of current elected set. - CurrentEraRewards get(current_era_reward): EraRewards; + CurrentEraPointsEarned get(current_era_reward): EraPoints; /// The amount of balance actively at stake for each validator slot, currently. /// @@ -1161,7 +1164,7 @@ impl Module { /// get a chance to set their session keys. fn new_era(start_session_index: SessionIndex) -> Option> { // Payout - let rewards = CurrentEraRewards::take(); + let points = CurrentEraPointsEarned::take(); let now = T::Time::now(); let previous_era_start = >::mutate(|v| { rstd::mem::replace(v, now) @@ -1176,21 +1179,22 @@ impl Module { let total_payout = inflation::compute_total_payout( total_rewarded_stake.clone(), T::Currency::total_issuance(), - // Era of duration more than u32::MAX is rewarded as u32::MAX. - >::from(era_duration.saturated_into::()), + // Duration of era; more than u64::MAX is rewarded as u64::MAX. + era_duration.saturated_into::(), ); let mut total_imbalance = >::zero(); - let total_points = rewards.total; - for (v, points) in validators.iter().zip(rewards.rewards.into_iter()) { - if points != 0 { - let reward = multiply_by_rational(total_payout, points, total_points); + for (v, p) in validators.iter().zip(points.individual.into_iter()) { + if p != 0 { + let reward = multiply_by_rational(total_payout, p, points.total); total_imbalance.subsume(Self::reward_validator(v, reward)); } } let total_reward = total_imbalance.peek(); + // assert!(total_reward <= total_payout) + Self::deposit_event(RawEvent::Reward(total_reward)); T::Reward::on_unbalanced(total_imbalance); T::OnRewardMinted::on_dilution(total_reward, total_rewarded_stake); @@ -1376,7 +1380,7 @@ impl Module { /// COMPLEXITY: Complexity is `number_of_validator_to_reward x current_elected_len`. /// If you need to reward lots of validator consider using `reward_by_indices`. pub fn reward_by_ids(validators_points: impl IntoIterator) { - CurrentEraRewards::mutate(|rewards| { + CurrentEraPointsEarned::mutate(|rewards| { let current_elected = >::current_elected(); for (validator, points) in validators_points.into_iter() { if let Some(index) = current_elected.iter() @@ -1396,7 +1400,7 @@ impl Module { // TODO: This can be optimised once #3302 is implemented. let current_elected_len = >::current_elected().len() as u32; - CurrentEraRewards::mutate(|rewards| { + CurrentEraPointsEarned::mutate(|rewards| { for (validator_index, points) in validators_points.into_iter() { if validator_index < current_elected_len { rewards.add_points_to_index(validator_index, points); diff --git a/srml/staking/src/mock.rs b/srml/staking/src/mock.rs index 94e2663b57..ace06ed771 100644 --- a/srml/staking/src/mock.rs +++ b/srml/staking/src/mock.rs @@ -391,16 +391,16 @@ pub fn assert_is_stash(acc: u64) { pub fn bond_validator(acc: u64, val: u64) { // a = controller // a + 1 = stash - let _ = Balances::make_free_balance_be(&(acc+1), val); - assert_ok!(Staking::bond(Origin::signed(acc+1), acc, val, RewardDestination::Controller)); + let _ = Balances::make_free_balance_be(&(acc + 1), val); + assert_ok!(Staking::bond(Origin::signed(acc + 1), acc, val, RewardDestination::Controller)); assert_ok!(Staking::validate(Origin::signed(acc), ValidatorPrefs::default())); } pub fn bond_nominator(acc: u64, val: u64, target: Vec) { // a = controller // a + 1 = stash - let _ = Balances::make_free_balance_be(&(acc+1), val); - assert_ok!(Staking::bond(Origin::signed(acc+1), acc, val, RewardDestination::Controller)); + let _ = Balances::make_free_balance_be(&(acc + 1), val); + assert_ok!(Staking::bond(Origin::signed(acc + 1), acc, val, RewardDestination::Controller)); assert_ok!(Staking::nominate(Origin::signed(acc), target)); } @@ -414,7 +414,7 @@ pub fn start_session(session_index: SessionIndex) { let session_index = session_index + 1; for i in Session::current_index()..session_index { System::set_block_number((i + 1).into()); - Timestamp::set_timestamp(System::block_number()); + Timestamp::set_timestamp(System::block_number() * 1000); Session::on_initialize(System::block_number()); } @@ -428,7 +428,7 @@ pub fn start_era(era_index: EraIndex) { pub fn current_total_payout_for_duration(duration: u64) -> u64 { let res = inflation::compute_total_payout( - >::slot_stake()*2, + >::slot_stake() * 2, Balances::total_issuance(), duration, ); diff --git a/srml/staking/src/tests.rs b/srml/staking/src/tests.rs index 3a42ead68a..2f3f94bfbf 100644 --- a/srml/staking/src/tests.rs +++ b/srml/staking/src/tests.rs @@ -132,7 +132,7 @@ fn rewards_should_work() { // Init some balances let _ = Balances::make_free_balance_be(&2, 500); - let delay = 1; + let delay = 1000; let init_balance_2 = Balances::total_balance(&2); let init_balance_10 = Balances::total_balance(&10); let init_balance_11 = Balances::total_balance(&11); @@ -160,7 +160,7 @@ fn rewards_should_work() { let mut block = 3; // Block 3 => Session 1 => Era 0 System::set_block_number(block); - Timestamp::set_timestamp(block*5); // on time. + Timestamp::set_timestamp(block * 5000); // on time. Session::on_initialize(System::block_number()); assert_eq!(Staking::current_era(), 0); assert_eq!(Session::current_index(), 1); @@ -172,7 +172,7 @@ fn rewards_should_work() { >::reward_by_ids(vec![(1001, 10_000)]); // Compute total payout now for whole duration as other parameter won't change - let total_payout = current_total_payout_for_duration(9 * 5); + let total_payout = current_total_payout_for_duration(9 * 5 * 1000); assert!(total_payout > 10); // Test is meaningful if reward something // No reward yet @@ -182,21 +182,21 @@ fn rewards_should_work() { block = 6; // Block 6 => Session 2 => Era 0 System::set_block_number(block); - Timestamp::set_timestamp(block*5 + delay); // a little late. + Timestamp::set_timestamp(block * 5000 + delay); // a little late. Session::on_initialize(System::block_number()); assert_eq!(Staking::current_era(), 0); assert_eq!(Session::current_index(), 2); block = 9; // Block 9 => Session 3 => Era 1 System::set_block_number(block); - Timestamp::set_timestamp(block*5); // back to being on time. no delays + Timestamp::set_timestamp(block * 5000); // back to being on time. no delays Session::on_initialize(System::block_number()); assert_eq!(Staking::current_era(), 1); assert_eq!(Session::current_index(), 3); - // 11 validator has 2/3 of the total rewards and half half for it and its nominator - assert_eq!(Balances::total_balance(&2), init_balance_2 + total_payout/3); - assert_eq!(Balances::total_balance(&10), init_balance_10 + total_payout/3); + // 11 validator has 2 / 3 of the total rewards and half half for it and its nominator + assert_eq!(Balances::total_balance(&2), init_balance_2 + total_payout / 3); + assert_eq!(Balances::total_balance(&10), init_balance_10 + total_payout / 3); assert_eq!(Balances::total_balance(&11), init_balance_11); }); } @@ -216,7 +216,7 @@ fn multi_era_reward_should_work() { assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller)); // Compute now as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3); + let total_payout_0 = current_total_payout_for_duration(3000); assert!(total_payout_0 > 10); // Test is meaningfull if reward something dbg!(>::slot_stake()); >::reward_by_ids(vec![(11, 1)]); @@ -231,7 +231,7 @@ fn multi_era_reward_should_work() { start_session(4); - let total_payout_1 = current_total_payout_for_duration(3); + let total_payout_1 = current_total_payout_for_duration(3000); assert!(total_payout_1 > 10); // Test is meaningfull if reward something >::reward_by_ids(vec![(11, 101)]); @@ -436,7 +436,7 @@ fn nominating_and_rewards_should_work() { assert_ok!(Staking::nominate(Origin::signed(4), vec![11, 21, 41])); // the total reward for era 0 - let total_payout_0 = current_total_payout_for_duration(3); + let total_payout_0 = current_total_payout_for_duration(3000); assert!(total_payout_0 > 100); // Test is meaningfull if reward something >::reward_by_ids(vec![(41, 1)]); >::reward_by_ids(vec![(31, 1)]); @@ -449,8 +449,8 @@ fn nominating_and_rewards_should_work() { assert_eq_uvec!(validator_controllers(), vec![20, 10]); // OLD validators must have already received some rewards. - assert_eq!(Balances::total_balance(&40), 1 + total_payout_0/2); - assert_eq!(Balances::total_balance(&30), 1 + total_payout_0/2); + assert_eq!(Balances::total_balance(&40), 1 + total_payout_0 / 2); + assert_eq!(Balances::total_balance(&30), 1 + total_payout_0 / 2); // ------ check the staked value of all parties. @@ -511,7 +511,7 @@ fn nominating_and_rewards_should_work() { assert_eq!(Staking::stakers(41).total, 0); // the total reward for era 1 - let total_payout_1 = current_total_payout_for_duration(3); + let total_payout_1 = current_total_payout_for_duration(3000); assert!(total_payout_1 > 100); // Test is meaningfull if reward something >::reward_by_ids(vec![(41, 10)]); // must be no-op >::reward_by_ids(vec![(31, 10)]); // must be no-op @@ -523,28 +523,34 @@ fn nominating_and_rewards_should_work() { // nothing else will happen, era ends and rewards are paid again, // it is expected that nominators will also be paid. See below - let payout_for_10 = total_payout_1/3; - let payout_for_20 = 2*total_payout_1/3; + let payout_for_10 = total_payout_1 / 3; + let payout_for_20 = 2 * total_payout_1 / 3; if cfg!(feature = "equalize") { - // Nominator 2: has [400/2000 ~ 1/5 from 10] + [600/2000 ~ 3/10 from 20]'s reward. - assert_eq!(Balances::total_balance(&2), initial_balance + payout_for_10/5 + payout_for_20*3/10 - 1); - // Nominator 4: has [400/2000 ~ 1/5 from 20] + [600/2000 ~ 3/10 from 10]'s reward. - assert_eq!(Balances::total_balance(&4), initial_balance + payout_for_20/5 + payout_for_10*3/10); + // Nominator 2: has [400 / 2000 ~ 1 / 5 from 10] + [600 / 2000 ~ 3 / 10 from 20]'s reward. + assert_eq!(Balances::total_balance(&2), initial_balance + payout_for_10 / 5 + payout_for_20 * 3 / 10); + // Nominator 4: has [400 / 2000 ~ 1 / 5 from 20] + [600 / 2000 ~ 3 / 10 from 10]'s reward. + assert_eq!(Balances::total_balance(&4), initial_balance + payout_for_20 / 5 + payout_for_10 * 3 / 10); // Validator 10: got 1000 / 2000 external stake. - assert_eq!(Balances::total_balance(&10), initial_balance + payout_for_10/2); + assert_eq!(Balances::total_balance(&10), initial_balance + payout_for_10 / 2); // Validator 20: got 1000 / 2000 external stake. - assert_eq!(Balances::total_balance(&20), initial_balance + payout_for_20/2); + assert_eq!(Balances::total_balance(&20), initial_balance + payout_for_20 / 2); } else { - // Nominator 2: has [400/1800 ~ 2/9 from 10] + [600/2200 ~ 3/11 from 20]'s reward. ==> 2/9 + 3/11 - assert_eq!(Balances::total_balance(&2), initial_balance + (2*payout_for_10/9 + 3*payout_for_20/11) - 2); - // Nominator 4: has [400/1800 ~ 2/9 from 10] + [600/2200 ~ 3/11 from 20]'s reward. ==> 2/9 + 3/11 - assert_eq!(Balances::total_balance(&4), initial_balance + (2*payout_for_10/9 + 3*payout_for_20/11) - 2); - - // Validator 10: got 800 / 1800 external stake => 8/18 =? 4/9 => Validator's share = 5/9 - assert_eq!(Balances::total_balance(&10), initial_balance + 5*payout_for_10/9 - 1); - // Validator 20: got 1200 / 2200 external stake => 12/22 =? 6/11 => Validator's share = 5/11 - assert_eq!(Balances::total_balance(&20), initial_balance + 5*payout_for_20/11); + // Nominator 2: has [400 / 1800 ~ 2 / 9 from 10] + [600 / 2200 ~ 3 / 11 from 20]'s reward. ==> 2 / 9 + 3 / 11 + assert_eq!( + Balances::total_balance(&2), + initial_balance + (2 * payout_for_10 / 9 + 3 * payout_for_20 / 11) - 2 + ); + // Nominator 4: has [400 / 1800 ~ 2 / 9 from 10] + [600 / 2200 ~ 3 / 11 from 20]'s reward. ==> 2 / 9 + 3 / 11 + assert_eq!( + Balances::total_balance(&4), + initial_balance + (2 * payout_for_10 / 9 + 3 * payout_for_20 / 11) - 2 + ); + + // Validator 10: got 800 / 1800 external stake => 8 / 18 =? 4 / 9 => Validator's share = 5 / 9 + assert_eq!(Balances::total_balance(&10), initial_balance + 5*payout_for_10 / 9 - 1); + // Validator 20: got 1200 / 2200 external stake => 12 / 22 =? 6 / 11 => Validator's share = 5 / 11 + assert_eq!(Balances::total_balance(&20), initial_balance + 5*payout_for_20 / 11 + 1); } check_exposure_all(); @@ -576,7 +582,7 @@ fn nominators_also_get_slashed() { assert_ok!(Staking::bond(Origin::signed(1), 2, nominator_stake, RewardDestination::default())); assert_ok!(Staking::nominate(Origin::signed(2), vec![20, 10])); - let total_payout = current_total_payout_for_duration(3); + let total_payout = current_total_payout_for_duration(3000); assert!(total_payout > 100); // Test is meaningfull if reward something >::reward_by_ids(vec![(11, 1)]); @@ -824,7 +830,7 @@ fn reward_destination_works() { })); // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3); + let total_payout_0 = current_total_payout_for_duration(3000); assert!(total_payout_0 > 100); // Test is meaningfull if reward something >::reward_by_ids(vec![(11, 1)]); @@ -846,7 +852,7 @@ fn reward_destination_works() { >::insert(&11, RewardDestination::Stash); // Compute total payout now for whole duration as other parameter won't change - let total_payout_1 = current_total_payout_for_duration(3); + let total_payout_1 = current_total_payout_for_duration(3000); assert!(total_payout_1 > 100); // Test is meaningfull if reward something >::reward_by_ids(vec![(11, 1)]); @@ -873,7 +879,7 @@ fn reward_destination_works() { assert_eq!(Balances::free_balance(&10), 1); // Compute total payout now for whole duration as other parameter won't change - let total_payout_2 = current_total_payout_for_duration(3); + let total_payout_2 = current_total_payout_for_duration(3000); assert!(total_payout_2 > 100); // Test is meaningfull if reward something >::reward_by_ids(vec![(11, 1)]); @@ -926,7 +932,7 @@ fn validator_payment_prefs_work() { }); // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3); + let total_payout_0 = current_total_payout_for_duration(3000); assert!(total_payout_0 > 100); // Test is meaningfull if reward something >::reward_by_ids(vec![(11, 1)]); @@ -935,11 +941,11 @@ fn validator_payment_prefs_work() { // whats left to be shared is the sum of 3 rounds minus the validator's cut. let shared_cut = total_payout_0 - validator_cut; // Validator's payee is Staked account, 11, reward will be paid here. - assert_eq!(Balances::total_balance(&11), stash_initial_balance + shared_cut/2 + validator_cut); + assert_eq!(Balances::total_balance(&11), stash_initial_balance + shared_cut / 2 + validator_cut); // Controller account will not get any reward. assert_eq!(Balances::total_balance(&10), 1); // Rest of the reward will be shared and paid to the nominator in stake. - assert_eq!(Balances::total_balance(&2), 500 + shared_cut/2); + assert_eq!(Balances::total_balance(&2), 500 + shared_cut / 2); check_exposure_all(); check_nominator_all(); @@ -1140,7 +1146,7 @@ fn slot_stake_is_least_staked_validator_and_exposure_defines_maximum_punishment( >::insert(&20, StakingLedger { stash: 22, total: 69, active: 69, unlocking: vec![] }); // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3); + let total_payout_0 = current_total_payout_for_duration(3000); assert!(total_payout_0 > 100); // Test is meaningfull if reward something >::reward_by_ids(vec![(11, 1)]); >::reward_by_ids(vec![(21, 1)]); @@ -1149,14 +1155,14 @@ fn slot_stake_is_least_staked_validator_and_exposure_defines_maximum_punishment( start_era(1); // -- new balances + reward - assert_eq!(Staking::stakers(&11).total, 1000 + total_payout_0/2); - assert_eq!(Staking::stakers(&21).total, 69 + total_payout_0/2); + assert_eq!(Staking::stakers(&11).total, 1000 + total_payout_0 / 2); + assert_eq!(Staking::stakers(&21).total, 69 + total_payout_0 / 2); let _11_balance = Balances::free_balance(&11); - assert_eq!(_11_balance, 1000 + total_payout_0/2); + assert_eq!(_11_balance, 1000 + total_payout_0 / 2); // -- slot stake should also be updated. - assert_eq!(Staking::slot_stake(), 69 + total_payout_0/2); + assert_eq!(Staking::slot_stake(), 69 + total_payout_0 / 2); check_exposure_all(); check_nominator_all(); @@ -1621,7 +1627,7 @@ fn bond_with_little_staked_value_bounded_by_slot_stake() { assert_ok!(Staking::bond(Origin::signed(1), 2, 1, RewardDestination::Controller)); assert_ok!(Staking::validate(Origin::signed(2), ValidatorPrefs::default())); - let total_payout_0 = current_total_payout_for_duration(3); + let total_payout_0 = current_total_payout_for_duration(3000); assert!(total_payout_0 > 100); // Test is meaningfull if reward something reward_all_elected(); start_era(1); @@ -1632,11 +1638,11 @@ fn bond_with_little_staked_value_bounded_by_slot_stake() { assert_eq!(Staking::slot_stake(), 1); // Old ones are rewarded. - assert_eq!(Balances::free_balance(&10), init_balance_10 + total_payout_0/3); + assert_eq!(Balances::free_balance(&10), init_balance_10 + total_payout_0 / 3); // no rewards paid to 2. This was initial election. assert_eq!(Balances::free_balance(&2), init_balance_2); - let total_payout_1 = current_total_payout_for_duration(3); + let total_payout_1 = current_total_payout_for_duration(3000); assert!(total_payout_1 > 100); // Test is meaningfull if reward something reward_all_elected(); start_era(2); @@ -1644,8 +1650,8 @@ fn bond_with_little_staked_value_bounded_by_slot_stake() { assert_eq_uvec!(validator_controllers(), vec![20, 10, 2]); assert_eq!(Staking::slot_stake(), 1); - assert_eq!(Balances::free_balance(&2), init_balance_2 + total_payout_1/3); - assert_eq!(Balances::free_balance(&10), init_balance_10 + total_payout_0/3 + total_payout_1/3); + assert_eq!(Balances::free_balance(&2), init_balance_2 + total_payout_1 / 3); + assert_eq!(Balances::free_balance(&10), init_balance_10 + total_payout_0 / 3 + total_payout_1 / 3); check_exposure_all(); check_nominator_all(); }); @@ -1750,8 +1756,8 @@ fn phragmen_should_not_overflow_validators() { bond_validator(2, u64::max_value()); bond_validator(4, u64::max_value()); - bond_nominator(6, u64::max_value()/2, vec![3, 5]); - bond_nominator(8, u64::max_value()/2, vec![3, 5]); + bond_nominator(6, u64::max_value() / 2, vec![3, 5]); + bond_nominator(8, u64::max_value() / 2, vec![3, 5]); start_era(1); @@ -1773,8 +1779,8 @@ fn phragmen_should_not_overflow_nominators() { let _ = Staking::chill(Origin::signed(10)); let _ = Staking::chill(Origin::signed(20)); - bond_validator(2, u64::max_value()/2); - bond_validator(4, u64::max_value()/2); + bond_validator(2, u64::max_value() / 2); + bond_validator(4, u64::max_value() / 2); bond_nominator(6, u64::max_value(), vec![3, 5]); bond_nominator(8, u64::max_value(), vec![3, 5]); @@ -1943,9 +1949,9 @@ fn reward_from_authorship_event_handler_works() { assert_eq!(>::get(), vec![21, 11]); // 21 is rewarded as an uncle producer - // 11 is rewarded as a block procuder and uncle referencer and uncle producer - assert_eq!(CurrentEraRewards::get().rewards, vec![1, 20+2*3 + 1]); - assert_eq!(CurrentEraRewards::get().total, 28); + // 11 is rewarded as a block producer and uncle referencer and uncle producer + assert_eq!(CurrentEraPointsEarned::get().individual, vec![1, 20 + 2 * 3 + 1]); + assert_eq!(CurrentEraPointsEarned::get().total, 28); }) } @@ -1972,8 +1978,8 @@ fn add_reward_points_fns_works() { (11, 1), ]); - assert_eq!(CurrentEraRewards::get().rewards, vec![2, 4]); - assert_eq!(CurrentEraRewards::get().total, 6); + assert_eq!(CurrentEraPointsEarned::get().individual, vec![2, 4]); + assert_eq!(CurrentEraPointsEarned::get().total, 6); }) } -- GitLab From 0702c23b9755e9d5364aa966a54d3995cdbbbe87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Wed, 11 Sep 2019 17:08:15 +0100 Subject: [PATCH 078/275] grandpa: use periodic neighbor packet sender (#3594) --- .../finality-grandpa/src/communication/mod.rs | 36 +++++++++---------- .../src/communication/periodic.rs | 21 +++++++++-- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/core/finality-grandpa/src/communication/mod.rs b/core/finality-grandpa/src/communication/mod.rs index 732c14c1a9..ea78c3ea9d 100644 --- a/core/finality-grandpa/src/communication/mod.rs +++ b/core/finality-grandpa/src/communication/mod.rs @@ -328,18 +328,12 @@ impl> NetworkBridge { self.validator.note_set( set_id, voters.voters().iter().map(|(v, _)| v.clone()).collect(), - |to, neighbor| self.service.send_message( - to, - GossipMessage::::from(neighbor).encode() - ), + |to, neighbor| self.neighbor_sender.send(to, neighbor), ); self.validator.note_round( round, - |to, neighbor| self.service.send_message( - to, - GossipMessage::::from(neighbor).encode() - ), + |to, neighbor| self.neighbor_sender.send(to, neighbor), ); } @@ -455,18 +449,25 @@ impl> NetworkBridge { self.validator.note_set( set_id, voters.voters().iter().map(|(v, _)| v.clone()).collect(), - |to, neighbor| self.service.send_message(to, GossipMessage::::from(neighbor).encode()), + |to, neighbor| self.neighbor_sender.send(to, neighbor), ); let service = self.service.clone(); let topic = global_topic::(set_id.0); - let incoming = incoming_global(service, topic, voters, self.validator.clone()); + let incoming = incoming_global( + service, + topic, + voters, + self.validator.clone(), + self.neighbor_sender.clone(), + ); let outgoing = CommitsOut::::new( self.service.clone(), set_id.0, is_voter, self.validator.clone(), + self.neighbor_sender.clone(), ); let outgoing = outgoing.with(|out| { @@ -483,6 +484,7 @@ fn incoming_global>( topic: B::Hash, voters: Arc>, gossip_validator: Arc>, + neighbor_sender: periodic::NeighborPacketSender, ) -> impl Stream, Error = Error> { let process_commit = move | msg: FullCommitMessage, @@ -520,6 +522,7 @@ fn incoming_global>( let finalized_number = commit.target_number; let gossip_validator = gossip_validator.clone(); let service = service.clone(); + let neighbor_sender = neighbor_sender.clone(); let cb = move |outcome| match outcome { voter::CommitProcessingOutcome::Good(_) => { // if it checks out, gossip it. not accounting for @@ -527,10 +530,7 @@ fn incoming_global>( // finalized number. gossip_validator.note_commit_finalized( finalized_number, - |to, neighbor_msg| service.send_message( - to, - GossipMessage::::from(neighbor_msg).encode(), - ), + |to, neighbor| neighbor_sender.send(to, neighbor), ); service.gossip_message(topic, notification.message.clone(), false); @@ -915,6 +915,7 @@ struct CommitsOut> { set_id: SetId, is_voter: bool, gossip_validator: Arc>, + neighbor_sender: periodic::NeighborPacketSender, } impl> CommitsOut { @@ -924,12 +925,14 @@ impl> CommitsOut { set_id: SetIdNumber, is_voter: bool, gossip_validator: Arc>, + neighbor_sender: periodic::NeighborPacketSender, ) -> Self { CommitsOut { network, set_id: SetId(set_id), is_voter, gossip_validator, + neighbor_sender, } } } @@ -972,10 +975,7 @@ impl> Sink for CommitsOut { // before gossiping self.gossip_validator.note_commit_finalized( commit.target_number, - |to, neighbor| self.network.send_message( - to, - GossipMessage::::from(neighbor).encode(), - ), + |to, neighbor| self.neighbor_sender.send(to, neighbor), ); self.network.gossip_message(topic, message.encode(), false); diff --git a/core/finality-grandpa/src/communication/periodic.rs b/core/finality-grandpa/src/communication/periodic.rs index 7265fe34a2..54383bb63d 100644 --- a/core/finality-grandpa/src/communication/periodic.rs +++ b/core/finality-grandpa/src/communication/periodic.rs @@ -22,7 +22,7 @@ use futures::sync::mpsc; use sr_primitives::traits::{NumberFor, Block as BlockT}; use network::PeerId; use tokio_timer::Delay; -use log::warn; +use log::{debug, warn}; use codec::Encode; use std::time::{Instant, Duration}; @@ -35,7 +35,22 @@ fn rebroadcast_instant() -> Instant { } /// A sender used to send neighbor packets to a background job. -pub(super) type NeighborPacketSender = mpsc::UnboundedSender<(Vec, NeighborPacket>)>; +#[derive(Clone)] +pub(super) struct NeighborPacketSender( + mpsc::UnboundedSender<(Vec, NeighborPacket>)> +); + +impl NeighborPacketSender { + pub fn send( + &self, + who: Vec, + neighbor_packet: NeighborPacket>, + ) { + if let Err(err) = self.0.unbounded_send((who, neighbor_packet)) { + debug!(target: "afg", "Failed to send neighbor packet: {:?}", err); + } + } +} /// Does the work of sending neighbor packets, asynchronously. /// @@ -89,5 +104,5 @@ pub(super) fn neighbor_packet_worker(net: N) -> ( } }); - (work, tx) + (work, NeighborPacketSender(tx)) } -- GitLab From 8ad7811f126a8a4c449e1a581c8e4f710e1a199e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 11 Sep 2019 19:10:02 +0200 Subject: [PATCH 079/275] Switch to new proc-macro crate for implementing traits for tuples (#3598) * Switch to new proc-macro crate for implementing traits for tuples * Switch back to stable `Cargo.lock` format * Reduce tuple number to match rusts default implementation --- Cargo.lock | 28 ++++- core/sr-primitives/Cargo.toml | 1 + core/sr-primitives/src/traits.rs | 197 ++++++++++--------------------- srml/authorship/Cargo.toml | 1 + srml/authorship/src/lib.rs | 27 +---- srml/finality-tracker/Cargo.toml | 1 + srml/finality-tracker/src/lib.rs | 21 +--- srml/session/Cargo.toml | 1 + srml/session/src/lib.rs | 89 ++++++-------- srml/support/Cargo.toml | 1 + srml/support/src/lib.rs | 15 --- srml/support/src/traits.rs | 21 +--- srml/system/Cargo.toml | 1 + srml/system/src/lib.rs | 21 +--- srml/timestamp/Cargo.toml | 1 + srml/timestamp/src/lib.rs | 21 +--- 16 files changed, 140 insertions(+), 307 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 59028fbc61..4954c736a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1379,6 +1379,16 @@ dependencies = [ "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "impl-trait-for-tuples" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "indexmap" version = "1.0.2" @@ -3018,7 +3028,7 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3121,7 +3131,7 @@ name = "quote" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3454,7 +3464,7 @@ name = "rustversion" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3822,6 +3832,7 @@ dependencies = [ name = "sr-primitives" version = "2.0.0" dependencies = [ + "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3934,6 +3945,7 @@ dependencies = [ name = "srml-authorship" version = "0.1.0" dependencies = [ + "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4092,6 +4104,7 @@ dependencies = [ name = "srml-finality-tracker" version = "2.0.0" dependencies = [ + "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4228,6 +4241,7 @@ dependencies = [ name = "srml-session" version = "2.0.0" dependencies = [ + "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4286,6 +4300,7 @@ name = "srml-support" version = "2.0.0" dependencies = [ "bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4351,6 +4366,7 @@ name = "srml-system" version = "2.0.0" dependencies = [ "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4366,6 +4382,7 @@ dependencies = [ name = "srml-timestamp" version = "2.0.0" dependencies = [ + "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -5497,7 +5514,7 @@ name = "syn" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6591,6 +6608,7 @@ dependencies = [ "checksum impl-codec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "78c441b3d2b5e24b407161e76d482b7bbd29b5da357707839ac40d95152f031f" "checksum impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5158079de9d4158e0ce1de3ae0bd7be03904efc40b3d7dd8b8c301cbf6b52b56" "checksum impl-serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d26be4b97d738552ea423f76c4f681012ff06c3fa36fa968656b3679f60b4a1" +"checksum impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3a9213bd15aa3f974ed007e12e520c435af21e0bb9b016c0874f05eec30034cf" "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" "checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" "checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" @@ -6721,7 +6739,7 @@ dependencies = [ "checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" "checksum proc-macro-hack 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "982a35d1194084ba319d65c4a68d24ca28f5fdb5b8bc20899e4eef8641ea5178" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -"checksum proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "175a40b9cf564ce9bf050654633dbf339978706b8ead1a907bb970b63185dd95" +"checksum proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e98a83a9f9b331f54b924e68a66acb1bb35cb01fb0a23645139967abefb697e8" "checksum prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96d14b1c185652833d24aaad41c5832b0be5616a590227c1fbff57c616754b23" "checksum prost-build 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb788126ea840817128183f8f603dce02cb7aea25c2a0b764359d8e20010702e" "checksum prost-derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e7dc378b94ac374644181a2247cebf59a6ec1c88b49ac77f3a94b86b79d0e11" diff --git a/core/sr-primitives/Cargo.toml b/core/sr-primitives/Cargo.toml index d3510e6baa..19db46e8a2 100644 --- a/core/sr-primitives/Cargo.toml +++ b/core/sr-primitives/Cargo.toml @@ -16,6 +16,7 @@ runtime_io = { package = "sr-io", path = "../sr-io", default-features = false } log = { version = "0.4", optional = true } paste = { version = "0.1"} rand = { version = "0.7.0", optional = true } +impl-trait-for-tuples = "0.1" [dev-dependencies] serde_json = "1.0" diff --git a/core/sr-primitives/src/traits.rs b/core/sr-primitives/src/traits.rs index bbcb46be3d..080b7bc948 100644 --- a/core/sr-primitives/src/traits.rs +++ b/core/sr-primitives/src/traits.rs @@ -19,8 +19,10 @@ use rstd::prelude::*; use rstd::{self, result, marker::PhantomData, convert::{TryFrom, TryInto}}; use runtime_io; -#[cfg(feature = "std")] use std::fmt::{Debug, Display}; -#[cfg(feature = "std")] use serde::{Serialize, Deserialize, de::DeserializeOwned}; +#[cfg(feature = "std")] +use std::fmt::{Debug, Display}; +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize, de::DeserializeOwned}; use primitives::{self, Hasher, Blake2Hasher}; use crate::codec::{Codec, Encode, Decode, HasCompact}; use crate::transaction_validity::{ @@ -38,6 +40,7 @@ use rstd::ops::{ RemAssign, Shl, Shr }; use crate::AppKey; +use impl_trait_for_tuples::impl_for_tuples; /// A lazy value. pub trait Lazy { @@ -404,22 +407,20 @@ impl { /// The block is being finalized. Implement to have something happen. fn on_finalize(_n: BlockNumber) {} } -impl OnFinalize for () {} - /// The block initialization trait. Implementing this lets you express what should happen /// for your module when the block is beginning (right before the first extrinsic is executed). +#[impl_for_tuples(30)] pub trait OnInitialize { /// The block is being initialized. Implement to have something happen. fn on_initialize(_n: BlockNumber) {} } -impl OnInitialize for () {} - /// Off-chain computation trait. /// /// Implementing this trait on a module allows you to perform long-running tasks @@ -428,6 +429,7 @@ impl OnInitialize for () {} /// /// NOTE: This function runs off-chain, so it can access the block state, /// but cannot preform any alterations. +#[impl_for_tuples(30)] pub trait OffchainWorker { /// This function is being called on every block. /// @@ -436,47 +438,6 @@ pub trait OffchainWorker { fn generate_extrinsics(_n: BlockNumber) {} } -impl OffchainWorker for () {} - -macro_rules! tuple_impl { - ($first:ident, $($rest:ident,)+) => { - tuple_impl!([$first] [$first] [$($rest)+]); - }; - ([$($direct:ident)+] [$($reverse:ident)+] []) => { - impl< - Number: Copy, - $($direct: OnFinalize),+ - > OnFinalize for ($($direct),+,) { - fn on_finalize(n: Number) { - $($reverse::on_finalize(n);)+ - } - } - impl< - Number: Copy, - $($direct: OnInitialize),+ - > OnInitialize for ($($direct),+,) { - fn on_initialize(n: Number) { - $($direct::on_initialize(n);)+ - } - } - impl< - Number: Copy, - $($direct: OffchainWorker),+ - > OffchainWorker for ($($direct),+,) { - fn generate_extrinsics(n: Number) { - $($direct::generate_extrinsics(n);)+ - } - } - }; - ([$($direct:ident)+] [$($reverse:ident)+] [$first:ident $($rest:ident)*]) => { - tuple_impl!([$($direct)+] [$($reverse)+] []); - tuple_impl!([$($direct)+ $first] [$first $($reverse)+] [$($rest)*]); - }; -} - -#[allow(non_snake_case)] -tuple_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,); - /// Abstraction around hashing pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq { // Stupid bug in the Rust compiler believes derived // traits must be fulfilled by all type parameters. @@ -930,96 +891,62 @@ pub trait ModuleDispatchError { fn as_str(&self) -> &'static str; } -macro_rules! tuple_impl_indexed { - ($first:ident, $($rest:ident,)+ ; $first_index:tt, $($rest_index:tt,)+) => { - tuple_impl_indexed!([$first] [$($rest)+] ; [$first_index,] [$($rest_index,)+]); - }; - ([$($direct:ident)+] ; [$($index:tt,)+]) => { - impl< - AccountId, - Call, - $($direct: SignedExtension),+ - > SignedExtension for ($($direct),+,) { - type AccountId = AccountId; - type Call = Call; - type AdditionalSigned = ( $( $direct::AdditionalSigned, )+ ); - type Pre = ($($direct::Pre,)+); - fn additional_signed(&self) -> Result { - Ok(( $( self.$index.additional_signed()?, )+ )) - } - fn validate( - &self, - who: &Self::AccountId, - call: &Self::Call, - info: DispatchInfo, - len: usize, - ) -> TransactionValidity { - let aggregator = vec![ - $( <$direct as SignedExtension>::validate(&self.$index, who, call, info, len)? ),+ - ]; - Ok( - aggregator.into_iter().fold( - ValidTransaction::default(), - |acc, a| acc.combine_with(a), - ) - ) - } - fn pre_dispatch( - self, - who: &Self::AccountId, - call: &Self::Call, - info: DispatchInfo, - len: usize, - ) -> Result { - Ok(($(self.$index.pre_dispatch(who, call, info, len)?,)+)) - } - fn validate_unsigned( - call: &Self::Call, - info: DispatchInfo, - len: usize, - ) -> TransactionValidity { - let aggregator = vec![ $( $direct::validate_unsigned(call, info, len)? ),+ ]; - - Ok( - aggregator.into_iter().fold( - ValidTransaction::default(), - |acc, a| acc.combine_with(a), - ) - ) - } - fn pre_dispatch_unsigned( - call: &Self::Call, - info: DispatchInfo, - len: usize, - ) -> Result { - Ok(($($direct::pre_dispatch_unsigned(call, info, len)?,)+)) - } - fn post_dispatch( - pre: Self::Pre, - info: DispatchInfo, - len: usize, - ) { - $($direct::post_dispatch(pre.$index, info, len);)+ - } - } +#[impl_for_tuples(1, 12)] +impl SignedExtension for Tuple { + for_tuples!( where #( Tuple: SignedExtension )* ); + type AccountId = AccountId; + type Call = Call; + for_tuples!( type AdditionalSigned = ( #( Tuple::AdditionalSigned ),* ); ); + for_tuples!( type Pre = ( #( Tuple::Pre ),* ); ); - }; - ([$($direct:ident)+] [] ; [$($index:tt,)+] []) => { - tuple_impl_indexed!([$($direct)+] ; [$($index,)+]); - }; - ( - [$($direct:ident)+] [$first:ident $($rest:ident)*] - ; - [$($index:tt,)+] [$first_index:tt, $($rest_index:tt,)*] - ) => { - tuple_impl_indexed!([$($direct)+] ; [$($index,)+]); - tuple_impl_indexed!([$($direct)+ $first] [$($rest)*] ; [$($index,)+ $first_index,] [$($rest_index,)*]); - }; -} + fn additional_signed(&self) -> Result { + Ok(for_tuples!( ( #( Tuple.additional_signed()? ),* ) )) + } + + fn validate( + &self, + who: &Self::AccountId, + call: &Self::Call, + info: DispatchInfo, + len: usize, + ) -> TransactionValidity { + let valid = ValidTransaction::default(); + for_tuples!( #( let valid = valid.combine_with(Tuple.validate(who, call, info, len)?); )* ); + Ok(valid) + } + + fn pre_dispatch(self, who: &Self::AccountId, call: &Self::Call, info: DispatchInfo, len: usize) + -> Result + { + Ok(for_tuples!( ( #( Tuple.pre_dispatch(who, call, info, len)? ),* ) )) + } + + fn validate_unsigned( + call: &Self::Call, + info: DispatchInfo, + len: usize, + ) -> TransactionValidity { + let valid = ValidTransaction::default(); + for_tuples!( #( let valid = valid.combine_with(Tuple::validate_unsigned(call, info, len)?); )* ); + Ok(valid) + } -// TODO: merge this into `tuple_impl` once codec supports `trait Codec` for longer tuple lengths. #3152 -#[allow(non_snake_case)] -tuple_impl_indexed!(A, B, C, D, E, F, G, H, I, J, ; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,); + fn pre_dispatch_unsigned( + call: &Self::Call, + info: DispatchInfo, + len: usize, + ) -> Result { + Ok(for_tuples!( ( #( Tuple::pre_dispatch_unsigned(call, info, len)? ),* ) )) + } + + fn post_dispatch( + pre: Self::Pre, + info: DispatchInfo, + len: usize, + ) { + for_tuples!( #( Tuple::post_dispatch(pre.Tuple, info, len); )* ) + } +} /// Only for bare bone testing when you don't care about signed extensions at all. #[cfg(feature = "std")] diff --git a/srml/authorship/Cargo.toml b/srml/authorship/Cargo.toml index db3cb133f4..7bb2af2632 100644 --- a/srml/authorship/Cargo.toml +++ b/srml/authorship/Cargo.toml @@ -14,6 +14,7 @@ sr-primitives = { path = "../../core/sr-primitives", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } +impl-trait-for-tuples = "0.1" [features] default = ["std"] diff --git a/srml/authorship/src/lib.rs b/srml/authorship/src/lib.rs index e7055dddb8..f8a2ad1ed1 100644 --- a/srml/authorship/src/lib.rs +++ b/srml/authorship/src/lib.rs @@ -22,7 +22,7 @@ use rstd::{result, prelude::*}; use rstd::collections::btree_set::BTreeSet; -use support::{decl_module, decl_storage, for_each_tuple, StorageValue}; +use support::{decl_module, decl_storage, StorageValue}; use support::traits::{FindAuthor, VerifySeal, Get}; use support::dispatch::Result as DispatchResult; use codec::{Encode, Decode}; @@ -112,6 +112,7 @@ pub trait Trait: system::Trait { /// An event handler for the authorship module. There is a dummy implementation /// for `()`, which does nothing. +#[impl_trait_for_tuples::impl_for_tuples(30)] pub trait EventHandler { /// Note that the given account ID is the author of the current block. fn note_author(author: Author); @@ -121,30 +122,6 @@ pub trait EventHandler { fn note_uncle(author: Author, age: BlockNumber); } -macro_rules! impl_event_handler { - () => ( - impl EventHandler for () { - fn note_author(_author: A) { } - fn note_uncle(_author: A, _age: B) { } - } - ); - - ( $($t:ident)* ) => { - impl),*> - EventHandler for ($($t,)*) - { - fn note_author(author: Author) { - $($t::note_author(author.clone());)* - } - fn note_uncle(author: Author, age: BlockNumber) { - $($t::note_uncle(author.clone(), age.clone());)* - } - } - } -} - -for_each_tuple!(impl_event_handler); - /// Additional filtering on uncles that pass preliminary ancestry checks. /// /// This should do work such as checking seals diff --git a/srml/finality-tracker/Cargo.toml b/srml/finality-tracker/Cargo.toml index 277c4039d2..ba6c5b7c8f 100644 --- a/srml/finality-tracker/Cargo.toml +++ b/srml/finality-tracker/Cargo.toml @@ -12,6 +12,7 @@ rstd = { package = "sr-std", path = "../../core/sr-std", default-features = fals sr-primitives = { path = "../../core/sr-primitives", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } srml-system = { path = "../system", default-features = false } +impl-trait-for-tuples = "0.1" [dev-dependencies] primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } diff --git a/srml/finality-tracker/src/lib.rs b/srml/finality-tracker/src/lib.rs index 340af3e4d3..1f90927f7d 100644 --- a/srml/finality-tracker/src/lib.rs +++ b/srml/finality-tracker/src/lib.rs @@ -26,7 +26,7 @@ use support::StorageValue; use sr_primitives::traits::{One, Zero, SaturatedConversion}; use rstd::{prelude::*, result, cmp, vec}; use codec::Decode; -use support::{decl_module, decl_storage, for_each_tuple}; +use support::{decl_module, decl_storage}; use support::traits::Get; use srml_system::{ensure_none, Trait as SystemTrait}; @@ -214,30 +214,13 @@ impl Module { } /// Called when finalization stalled at a given number. +#[impl_trait_for_tuples::impl_for_tuples(30)] pub trait OnFinalizationStalled { /// The parameter here is how many more blocks to wait before applying /// changes triggered by finality stalling. fn on_stalled(further_wait: N, median: N); } -macro_rules! impl_on_stalled { - () => ( - impl OnFinalizationStalled for () { - fn on_stalled(_: N, _: N) {} - } - ); - - ( $($t:ident)* ) => { - impl),*> OnFinalizationStalled for ($($t,)*) { - fn on_stalled(further_wait: NUM, median: NUM) { - $($t::on_stalled(further_wait.clone(), median.clone());)* - } - } - } -} - -for_each_tuple!(impl_on_stalled); - impl ProvideInherent for Module { type Call = Call; type Error = MakeFatalError<()>; diff --git a/srml/session/Cargo.toml b/srml/session/Cargo.toml index c2e0732ed7..2e7f5eda80 100644 --- a/srml/session/Cargo.toml +++ b/srml/session/Cargo.toml @@ -16,6 +16,7 @@ system = { package = "srml-system", path = "../system", default-features = false timestamp = { package = "srml-timestamp", path = "../timestamp", default-features = false } substrate-trie = { path = "../../core/trie", default-features = false, optional = true } runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } +impl-trait-for-tuples = "0.1" [dev-dependencies] primitives = { package = "substrate-primitives", path = "../../core/primitives" } diff --git a/srml/session/src/lib.rs b/srml/session/src/lib.rs index f7c9eee021..63566fd881 100644 --- a/srml/session/src/lib.rs +++ b/srml/session/src/lib.rs @@ -126,8 +126,8 @@ use sr_primitives::weights::SimpleDispatchInfo; use sr_primitives::traits::{Convert, Zero, Member, OpaqueKeys}; use sr_staking_primitives::SessionIndex; use support::{ - dispatch::Result, ConsensusEngineId, StorageValue, StorageDoubleMap, for_each_tuple, - decl_module, decl_event, decl_storage, + dispatch::Result, ConsensusEngineId, StorageValue, StorageDoubleMap, decl_module, decl_event, + decl_storage, }; use support::{ensure, traits::{OnFreeBalanceZero, Get, FindAuthor}, Parameter}; use system::{self, ensure_signed}; @@ -251,62 +251,51 @@ pub trait OneSessionHandler { /// A validator got disabled. Act accordingly until a new session begins. fn on_disabled(_validator_index: usize); - } -macro_rules! impl_session_handlers { - () => ( - impl SessionHandler for () { - fn on_genesis_session(_: &[(AId, Ks)]) {} - fn on_new_session(_: bool, _: &[(AId, Ks)], _: &[(AId, Ks)]) {} - fn on_before_session_ending() {} - fn on_disabled(_: usize) {} - } - ); +#[impl_trait_for_tuples::impl_for_tuples(30)] +#[tuple_types_no_default_trait_bound] +impl SessionHandler for Tuple { + for_tuples!( where #( Tuple: OneSessionHandler )* ); - ( $($t:ident)* ) => { - impl ),*> SessionHandler for ( $( $t , )* ) { - fn on_genesis_session(validators: &[(AId, Ks)]) { - $( - let our_keys: Box> = Box::new(validators.iter() - .map(|k| (&k.0, k.1.get::<$t::Key>(<$t::Key as AppKey>::ID) - .unwrap_or_default()))); + fn on_genesis_session(validators: &[(AId, Ks)]) { + for_tuples!( + #( + let our_keys: Box> = Box::new(validators.iter() + .map(|k| (&k.0, k.1.get::(::ID) + .unwrap_or_default()))); - $t::on_genesis_session(our_keys); - )* - } - fn on_new_session( - changed: bool, - validators: &[(AId, Ks)], - queued_validators: &[(AId, Ks)], - ) { - $( - let our_keys: Box> = Box::new(validators.iter() - .map(|k| (&k.0, k.1.get::<$t::Key>(<$t::Key as AppKey>::ID) - .unwrap_or_default()))); - let queued_keys: Box> = Box::new(queued_validators.iter() - .map(|k| (&k.0, k.1.get::<$t::Key>(<$t::Key as AppKey>::ID) - .unwrap_or_default()))); - $t::on_new_session(changed, our_keys, queued_keys); - )* - } + Tuple::on_genesis_session(our_keys); + )* + ) + } - fn on_before_session_ending() { - $( - $t::on_before_session_ending(); - )* - } + fn on_new_session( + changed: bool, + validators: &[(AId, Ks)], + queued_validators: &[(AId, Ks)], + ) { + for_tuples!( + #( + let our_keys: Box> = Box::new(validators.iter() + .map(|k| (&k.0, k.1.get::(::ID) + .unwrap_or_default()))); + let queued_keys: Box> = Box::new(queued_validators.iter() + .map(|k| (&k.0, k.1.get::(::ID) + .unwrap_or_default()))); + Tuple::on_new_session(changed, our_keys, queued_keys); + )* + ) + } - fn on_disabled(i: usize) { - $( - $t::on_disabled(i); - )* - } - } + fn on_before_session_ending() { + for_tuples!( #( Tuple::on_before_session_ending(); )* ) } -} -for_each_tuple!(impl_session_handlers); + fn on_disabled(i: usize) { + for_tuples!( #( Tuple::on_disabled(i); )* ) + } +} /// Handler for selecting the genesis validator set. pub trait SelectInitialValidators { diff --git a/srml/support/Cargo.toml b/srml/support/Cargo.toml index f1cdb69a65..7a3e0d26e4 100644 --- a/srml/support/Cargo.toml +++ b/srml/support/Cargo.toml @@ -17,6 +17,7 @@ srml-support-procedural = { package = "srml-support-procedural", path = "./proce paste = "0.1" once_cell = { version = "0.1.6", default-features = false, optional = true } bitmask = { version = "0.5", default-features = false } +impl-trait-for-tuples = "0.1" [dev-dependencies] pretty_assertions = "0.6.1" diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index b815e00b9d..13fb69990e 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -266,21 +266,6 @@ pub enum Void {} #[doc(hidden)] pub use serde::{Serialize, Deserialize}; -/// Programatically create derivations for tuples of up to 19 elements. You provide a second macro -/// which is called once per tuple size, along with a number of identifiers, one for each element -/// of the tuple. -#[macro_export] -macro_rules! for_each_tuple { - ($m:ident) => { - for_each_tuple! { @IMPL $m !! A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, } - }; - (@IMPL $m:ident !!) => { $m! { } }; - (@IMPL $m:ident !! $h:ident, $($t:ident,)*) => { - $m! { $h $($t)* } - for_each_tuple! { @IMPL $m !! $($t,)* } - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/srml/support/src/traits.rs b/srml/support/src/traits.rs index 4ce94bb341..8eeb10c374 100644 --- a/srml/support/src/traits.rs +++ b/srml/support/src/traits.rs @@ -24,8 +24,6 @@ use primitives::u32_trait::Value as U32; use crate::sr_primitives::traits::{MaybeSerializeDebug, SimpleArithmetic, Saturating}; use crate::sr_primitives::ConsensusEngineId; -use super::for_each_tuple; - /// Anything that can have a `::len()` method. pub trait Len { /// Return the length of data type. @@ -63,29 +61,12 @@ impl> Contains for T { } /// The account with the given id was killed. +#[impl_trait_for_tuples::impl_for_tuples(30)] pub trait OnFreeBalanceZero { /// The account was the given id was killed. fn on_free_balance_zero(who: &AccountId); } -macro_rules! impl_on_free_balance_zero { - () => ( - impl OnFreeBalanceZero for () { - fn on_free_balance_zero(_: &AccountId) {} - } - ); - - ( $($t:ident)* ) => { - impl),*> OnFreeBalanceZero for ($($t,)*) { - fn on_free_balance_zero(who: &AccountId) { - $($t::on_free_balance_zero(who);)* - } - } - } -} - -for_each_tuple!(impl_on_free_balance_zero); - /// Trait for a hook to get called when some balance has been minted, causing dilution. pub trait OnDilution { /// Some `portion` of the total balance just "grew" by `minted`. `portion` is the pre-growth diff --git a/srml/system/Cargo.toml b/srml/system/Cargo.toml index f6fd25c29f..fd8ae735a9 100644 --- a/srml/system/Cargo.toml +++ b/srml/system/Cargo.toml @@ -14,6 +14,7 @@ runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = f sr-primitives = { path = "../../core/sr-primitives", default-features = false } sr-version = { path = "../../core/sr-version", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } +impl-trait-for-tuples = "0.1" [dev-dependencies] criterion = "0.2" diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index 2f1d0ab9e0..02a7002806 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -112,7 +112,7 @@ use sr_primitives::{ use primitives::storage::well_known_keys; use support::{ storage, decl_module, decl_event, decl_storage, StorageDoubleMap, StorageValue, StorageMap, - Parameter, for_each_tuple, traits::{Contains, Get}, decl_error, + Parameter, traits::{Contains, Get}, decl_error, }; use safe_mix::TripletMix; use codec::{Encode, Decode}; @@ -126,29 +126,12 @@ use primitives::ChangesTrieConfiguration; pub mod offchain; /// Handler for when a new account has been created. +#[impl_trait_for_tuples::impl_for_tuples(30)] pub trait OnNewAccount { /// A new account `who` has been registered. fn on_new_account(who: &AccountId); } -macro_rules! impl_on_new_account { - () => ( - impl OnNewAccount for () { - fn on_new_account(_: &AccountId) {} - } - ); - - ( $($t:ident)* ) => { - impl),*> OnNewAccount for ($($t,)*) { - fn on_new_account(who: &AccountId) { - $($t::on_new_account(who);)* - } - } - } -} - -for_each_tuple!(impl_on_new_account); - /// Determiner to say whether a given account is unused. pub trait IsDeadAccount { /// Is the given account dead? diff --git a/srml/timestamp/Cargo.toml b/srml/timestamp/Cargo.toml index 022e478e57..00eaf7d7f8 100644 --- a/srml/timestamp/Cargo.toml +++ b/srml/timestamp/Cargo.toml @@ -12,6 +12,7 @@ sr-primitives = { path = "../../core/sr-primitives", default-features = false } inherents = { package = "substrate-inherents", path = "../../core/inherents", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } +impl-trait-for-tuples = "0.1" [dev-dependencies] runtime-io ={ package = "sr-io", path = "../../core/sr-io" } diff --git a/srml/timestamp/src/lib.rs b/srml/timestamp/src/lib.rs index cf7792eaa4..919e2a75ab 100644 --- a/srml/timestamp/src/lib.rs +++ b/srml/timestamp/src/lib.rs @@ -96,7 +96,7 @@ use codec::Encode; use codec::Decode; #[cfg(feature = "std")] use inherents::ProvideInherentData; -use support::{StorageValue, Parameter, decl_storage, decl_module, for_each_tuple}; +use support::{StorageValue, Parameter, decl_storage, decl_module}; use support::traits::{Time, Get}; use sr_primitives::traits::{ SimpleArithmetic, Zero, SaturatedConversion, Scale @@ -183,28 +183,11 @@ impl ProvideInherentData for InherentDataProvider { } /// A trait which is called when the timestamp is set. +#[impl_trait_for_tuples::impl_for_tuples(30)] pub trait OnTimestampSet { fn on_timestamp_set(moment: Moment); } -macro_rules! impl_timestamp_set { - () => ( - impl OnTimestampSet for () { - fn on_timestamp_set(_: Moment) {} - } - ); - - ( $($t:ident)* ) => { - impl),*> OnTimestampSet for ($($t,)*) { - fn on_timestamp_set(moment: Moment) { - $($t::on_timestamp_set(moment);)* - } - } - } -} - -for_each_tuple!(impl_timestamp_set); - /// The module configuration trait pub trait Trait: system::Trait { /// Type used for expressing timestamp. -- GitLab From 15a4c405714380440f3239cd14948b1e3577367a Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Wed, 11 Sep 2019 19:37:19 +0200 Subject: [PATCH 080/275] read_storage panics (#3589) * Add a failing test case * Actual fix * read_child_storage, fix wasm side * Bump the impl version. * Alternative (#3597) * Update with_std.rs * Update with_std.rs * Update wasm_executor.rs * Update wasm_executor.rs * Update with_std.rs * Update wasm_executor.rs --- core/executor/src/wasm_executor.rs | 14 +++---- core/sr-io/with_std.rs | 12 +++--- core/test-runtime/src/lib.rs | 65 ++++++++++++++++++++++++++++++ node/runtime/src/lib.rs | 2 +- 4 files changed, 79 insertions(+), 14 deletions(-) diff --git a/core/executor/src/wasm_executor.rs b/core/executor/src/wasm_executor.rs index 1cef4b7cb1..38b8d8eff1 100644 --- a/core/executor/src/wasm_executor.rs +++ b/core/executor/src/wasm_executor.rs @@ -629,9 +629,9 @@ impl_wasm_host_interface! { )?; if let Some(value) = maybe_value { - let value = &value[value_offset as usize..]; - let written = std::cmp::min(value_len as usize, value.len()); - context.write_memory(value_data, &value[..written]) + let data = &value[value.len().min(value_offset as usize)..]; + let written = std::cmp::min(value_len as usize, data.len()); + context.write_memory(value_data, &data[..written]) .map_err(|_| "Invalid attempt to set value in ext_get_storage_into")?; Ok(value.len() as u32) } else { @@ -658,10 +658,10 @@ impl_wasm_host_interface! { )?; if let Some(value) = maybe_value { - let value = &value[value_offset as usize..]; - let written = std::cmp::min(value_len as usize, value.len()); - context.write_memory(value_data, &value[..written]) - .map_err(|_| "Invalid attempt to set value in ext_get_child_storage_into")?; + let data = &value[value.len().min(value_offset as usize)..]; + let written = std::cmp::min(value_len as usize, data.len()); + context.write_memory(value_data, &data[..written]) + .map_err(|_| "Invalid attempt to get value in ext_get_child_storage_into")?; Ok(value.len() as u32) } else { Ok(u32::max_value()) diff --git a/core/sr-io/with_std.rs b/core/sr-io/with_std.rs index ca2a2554c3..41baf29532 100644 --- a/core/sr-io/with_std.rs +++ b/core/sr-io/with_std.rs @@ -54,9 +54,9 @@ impl StorageApi for () { fn read_storage(key: &[u8], value_out: &mut [u8], value_offset: usize) -> Option { ext::with(|ext| ext.storage(key).map(|value| { - let value = &value[value_offset..]; - let written = std::cmp::min(value.len(), value_out.len()); - value_out[..written].copy_from_slice(&value[..written]); + let data = &value[value_offset.min(value.len())..]; + let written = std::cmp::min(data.len(), value_out.len()); + value_out[..written].copy_from_slice(&data[..written]); value.len() })).expect("read_storage cannot be called outside of an Externalities-provided environment.") } @@ -85,9 +85,9 @@ impl StorageApi for () { let storage_key = child_storage_key_or_panic(storage_key); ext.child_storage(storage_key, key) .map(|value| { - let value = &value[value_offset..]; - let written = std::cmp::min(value.len(), value_out.len()); - value_out[..written].copy_from_slice(&value[..written]); + let data = &value[value_offset.min(value.len())..]; + let written = std::cmp::min(data.len(), value_out.len()); + value_out[..written].copy_from_slice(&data[..written]); value.len() }) }) diff --git a/core/test-runtime/src/lib.rs b/core/test-runtime/src/lib.rs index aa0b57ec92..88a246b094 100644 --- a/core/test-runtime/src/lib.rs +++ b/core/test-runtime/src/lib.rs @@ -280,6 +280,8 @@ cfg_if! { /// /// Returns the signature generated for the message `sr25519`. fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic); + /// Run various tests against storage. + fn test_storage(); } } } else { @@ -322,6 +324,8 @@ cfg_if! { /// /// Returns the signature generated for the message `sr25519`. fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic); + /// Run various tests against storage. + fn test_storage(); } } } @@ -590,6 +594,11 @@ cfg_if! { fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic) { test_sr25519_crypto() } + + fn test_storage() { + test_read_storage(); + test_read_child_storage(); + } } impl aura_primitives::AuraApi for Runtime { @@ -805,6 +814,11 @@ cfg_if! { fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic) { test_sr25519_crypto() } + + fn test_storage() { + test_read_storage(); + test_read_child_storage(); + } } impl aura_primitives::AuraApi for Runtime { @@ -887,6 +901,46 @@ fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic) { (signature, public0) } +fn test_read_storage() { + const KEY: &[u8] = b":read_storage"; + runtime_io::set_storage(KEY, b"test"); + + let mut v = [0u8; 4]; + let r = runtime_io::read_storage( + KEY, + &mut v, + 0 + ); + assert_eq!(r, Some(4)); + assert_eq!(&v, b"test"); + + let mut v = [0u8; 4]; + let r = runtime_io::read_storage(KEY, &mut v, 8); + assert_eq!(r, Some(4)); + assert_eq!(&v, &[0, 0, 0, 0]); +} + +fn test_read_child_storage() { + const CHILD_KEY: &[u8] = b":child_storage:default:read_child_storage"; + const KEY: &[u8] = b":read_child_storage"; + runtime_io::set_child_storage(CHILD_KEY, KEY, b"test"); + + let mut v = [0u8; 4]; + let r = runtime_io::read_child_storage( + CHILD_KEY, + KEY, + &mut v, + 0 + ); + assert_eq!(r, Some(4)); + assert_eq!(&v, b"test"); + + let mut v = [0u8; 4]; + let r = runtime_io::read_child_storage(CHILD_KEY, KEY, &mut v, 8); + assert_eq!(r, Some(4)); + assert_eq!(&v, &[0, 0, 0, 0]); +} + #[cfg(test)] mod tests { use substrate_test_runtime_client::{ @@ -981,4 +1035,15 @@ mod tests { let ret = runtime_api.vec_with_capacity(&new_block_id, 1048576); assert!(ret.is_ok()); } + + #[test] + fn test_storage() { + let client = TestClientBuilder::new() + .set_execution_strategy(ExecutionStrategy::Both) + .build(); + let runtime_api = client.runtime_api(); + let block_id = BlockId::Number(client.info().chain.best_number); + + runtime_api.test_storage(&block_id).unwrap(); + } } diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 4a1df077c4..72a533ada8 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 156, - impl_version: 156, + impl_version: 157, apis: RUNTIME_API_VERSIONS, }; -- GitLab From c8e1120944fa0a547ea84ba5907ad878e7203dfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Thu, 12 Sep 2019 00:03:10 +0100 Subject: [PATCH 081/275] grandpa: fix race condition (#3542) * grandpa: ignore result of voter command send * grandpa: avoid race condition on environment::finalize_block --- core/finality-grandpa/src/environment.rs | 8 +++++--- core/finality-grandpa/src/import.rs | 5 ++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/core/finality-grandpa/src/environment.rs b/core/finality-grandpa/src/environment.rs index faabf705fb..27d398ca3e 100644 --- a/core/finality-grandpa/src/environment.rs +++ b/core/finality-grandpa/src/environment.rs @@ -871,6 +871,11 @@ pub(crate) fn finalize_block, E, RA>( E: CallExecutor + Send + Sync, RA: Send + Sync, { + // NOTE: lock must be held through writing to DB to avoid race. this lock + // also implicitly synchronizes the check for last finalized number + // below. + let mut authority_set = authority_set.inner().write(); + let status = client.info().chain; if number <= status.finalized_number && client.hash(number)? == Some(hash) { // This can happen after a forced change (triggered by the finality tracker when finality is stalled), since @@ -885,9 +890,6 @@ pub(crate) fn finalize_block, E, RA>( return Ok(()); } - // lock must be held through writing to DB to avoid race - let mut authority_set = authority_set.inner().write(); - // FIXME #1483: clone only when changed let old_authority_set = authority_set.clone(); // holds the old consensus changes in case it is changed below, needed for diff --git a/core/finality-grandpa/src/import.rs b/core/finality-grandpa/src/import.rs index d1ad57baa4..e72914b7c2 100644 --- a/core/finality-grandpa/src/import.rs +++ b/core/finality-grandpa/src/import.rs @@ -590,9 +590,8 @@ where info!(target: "finality", "Imported justification for block #{} that triggers \ command {}, signaling voter.", number, command); - if let Err(e) = self.send_voter_commands.unbounded_send(command) { - return Err(ConsensusError::ClientImport(e.to_string()).into()); - } + // send the command to the voter + let _ = self.send_voter_commands.unbounded_send(command); }, Err(CommandOrError::Error(e)) => { return Err(match e { -- GitLab From 1e48f40718d20aa64fd06cb8ecebd6e58c555514 Mon Sep 17 00:00:00 2001 From: Xiliang Chen Date: Thu, 12 Sep 2019 20:21:21 +1200 Subject: [PATCH 082/275] fix inconsistency in block time (#3603) --- node-template/runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node-template/runtime/src/lib.rs b/node-template/runtime/src/lib.rs index 487937eab0..fa4d022d17 100644 --- a/node-template/runtime/src/lib.rs +++ b/node-template/runtime/src/lib.rs @@ -208,7 +208,7 @@ impl indices::Trait for Runtime { } parameter_types! { - pub const MinimumPeriod: u64 = 5000; + pub const MinimumPeriod: u64 = SLOT_DURATION / 2; } impl timestamp::Trait for Runtime { -- GitLab From 042b26d3cac2f9b91ec3a83605fb9c049e31d995 Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Thu, 12 Sep 2019 13:30:10 +0200 Subject: [PATCH 083/275] Add an RPC method for calling a contract. (#3563) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Sketch * Some work on docs. * Doc improvements. * More docs. * Some more docs. * Yet another comment. * Bump impl_version. * Accept the block hash * Use NumberOrHex * Update node/rpc/src/contracts.rs Co-Authored-By: Tomasz Drwięga * Move rpc/primitives --- Cargo.lock | 11 ++ Cargo.toml | 1 + core/rpc/Cargo.toml | 1 + core/rpc/api/Cargo.toml | 1 + core/rpc/api/src/chain/mod.rs | 2 +- core/rpc/primitives/Cargo.toml | 9 ++ core/rpc/primitives/src/lib.rs | 21 ++++ .../src/chain => primitives/src}/number.rs | 0 core/rpc/src/chain/mod.rs | 1 + node/cli/src/service.rs | 10 +- node/primitives/src/lib.rs | 38 ++++++ node/rpc/Cargo.toml | 1 + node/rpc/src/accounts.rs | 4 +- node/rpc/src/contracts.rs | 116 ++++++++++++++++++ node/rpc/src/lib.rs | 8 ++ node/runtime/src/lib.rs | 29 ++++- srml/contracts/src/exec.rs | 12 +- srml/contracts/src/lib.rs | 41 +++++-- 18 files changed, 279 insertions(+), 27 deletions(-) create mode 100644 core/rpc/primitives/Cargo.toml create mode 100644 core/rpc/primitives/src/lib.rs rename core/rpc/{api/src/chain => primitives/src}/number.rs (100%) create mode 100644 node/rpc/src/contracts.rs diff --git a/Cargo.lock b/Cargo.lock index 4954c736a6..0d257d6dd0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2429,6 +2429,7 @@ dependencies = [ "substrate-client 2.0.0", "substrate-keyring 2.0.0", "substrate-primitives 2.0.0", + "substrate-rpc-primitives 2.0.0", "substrate-transaction-pool 2.0.0", ] @@ -5164,6 +5165,7 @@ dependencies = [ "substrate-network 2.0.0", "substrate-primitives 2.0.0", "substrate-rpc-api 2.0.0", + "substrate-rpc-primitives 2.0.0", "substrate-session 2.0.0", "substrate-state-machine 2.0.0", "substrate-test-runtime-client 2.0.0", @@ -5188,9 +5190,18 @@ dependencies = [ "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "sr-version 2.0.0", "substrate-primitives 2.0.0", + "substrate-rpc-primitives 2.0.0", "substrate-transaction-graph 2.0.0", ] +[[package]] +name = "substrate-rpc-primitives" +version = "2.0.0" +dependencies = [ + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-primitives 2.0.0", +] + [[package]] name = "substrate-rpc-servers" version = "2.0.0" diff --git a/Cargo.toml b/Cargo.toml index 1920587440..bc9fd128ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ members = [ "core/panic-handler", "core/primitives", "core/rpc", + "core/rpc/primitives", "core/rpc-servers", "core/serializer", "core/service", diff --git a/core/rpc/Cargo.toml b/core/rpc/Cargo.toml index 25f0a467ee..5bf74cf42e 100644 --- a/core/rpc/Cargo.toml +++ b/core/rpc/Cargo.toml @@ -17,6 +17,7 @@ runtime_version = { package = "sr-version", path = "../sr-version" } serde_json = "1.0" session = { package = "substrate-session", path = "../session" } sr-primitives = { path = "../sr-primitives" } +rpc-primitives = { package = "substrate-rpc-primitives", path = "primitives" } state_machine = { package = "substrate-state-machine", path = "../state-machine" } substrate-executor = { path = "../executor" } substrate-keystore = { path = "../keystore" } diff --git a/core/rpc/api/Cargo.toml b/core/rpc/api/Cargo.toml index 4b09f4f327..4b2eb613db 100644 --- a/core/rpc/api/Cargo.toml +++ b/core/rpc/api/Cargo.toml @@ -19,3 +19,4 @@ runtime_version = { package = "sr-version", path = "../../sr-version" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" txpool = { package = "substrate-transaction-graph", path = "../../transaction-pool/graph" } +rpc-primitives = { package = "substrate-rpc-primitives", path = "../../rpc/primitives" } diff --git a/core/rpc/api/src/chain/mod.rs b/core/rpc/api/src/chain/mod.rs index c0076d5987..73f4388236 100644 --- a/core/rpc/api/src/chain/mod.rs +++ b/core/rpc/api/src/chain/mod.rs @@ -17,12 +17,12 @@ //! Substrate blockchain API. pub mod error; -pub mod number; use jsonrpc_core::Result as RpcResult; use jsonrpc_core::futures::Future; use jsonrpc_derive::rpc; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use rpc_primitives::number; use self::error::{FutureResult, Result}; pub use self::gen_client::Client as ChainClient; diff --git a/core/rpc/primitives/Cargo.toml b/core/rpc/primitives/Cargo.toml new file mode 100644 index 0000000000..fab94a86ba --- /dev/null +++ b/core/rpc/primitives/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "substrate-rpc-primitives" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +serde = { version = "1.0", features = ["derive"] } +primitives = { package = "substrate-primitives", path = "../../primitives" } diff --git a/core/rpc/primitives/src/lib.rs b/core/rpc/primitives/src/lib.rs new file mode 100644 index 0000000000..667b1b1b4b --- /dev/null +++ b/core/rpc/primitives/src/lib.rs @@ -0,0 +1,21 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Substrate RPC primitives and utilities. + +#![warn(missing_docs)] + +pub mod number; diff --git a/core/rpc/api/src/chain/number.rs b/core/rpc/primitives/src/number.rs similarity index 100% rename from core/rpc/api/src/chain/number.rs rename to core/rpc/primitives/src/number.rs diff --git a/core/rpc/src/chain/mod.rs b/core/rpc/src/chain/mod.rs index 4c59d227c2..61ecf96711 100644 --- a/core/rpc/src/chain/mod.rs +++ b/core/rpc/src/chain/mod.rs @@ -37,6 +37,7 @@ use client::{ }; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use primitives::{H256, Blake2Hasher}; +use rpc_primitives::number; use sr_primitives::{ generic::{BlockId, SignedBlock}, traits::{Block as BlockT, Header, NumberFor}, diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index c6ad072ef5..ca6b249484 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -270,11 +270,17 @@ pub fn new_light(config: Configuration; /// Opaque, encoded, unchecked extrinsic. pub type UncheckedExtrinsic = OpaqueExtrinsic; +/// A result of execution of a contract. +#[derive(Eq, PartialEq, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +pub enum ContractExecResult { + /// The contract returned successfully. + /// + /// There is a status code and, optionally, some data returned by the contract. + Success { + /// Status code returned by the contract. + status: u8, + /// Output data returned by the contract. + /// + /// Can be empty. + data: Vec, + }, + /// The contract execution either trapped or returned an error. + Error, +} + client::decl_runtime_apis! { /// The API to query account account nonce (aka index). pub trait AccountNonceApi { /// Get current account nonce of given `AccountId`. fn account_nonce(account: AccountId) -> Index; } + + /// The API to interact with contracts without using executive. + pub trait ContractsApi { + /// Perform a call from a specified account to a given contract. + /// + /// See the contracts' `call` dispatchable function for more details. + fn call( + origin: AccountId, + dest: AccountId, + value: Balance, + gas_limit: u64, + input_data: Vec, + ) -> ContractExecResult; + } } diff --git a/node/rpc/Cargo.toml b/node/rpc/Cargo.toml index 55371daad6..3485357053 100644 --- a/node/rpc/Cargo.toml +++ b/node/rpc/Cargo.toml @@ -17,6 +17,7 @@ codec = { package = "parity-scale-codec", version = "1.0.0" } serde = { version = "1.0", features = ["derive"] } sr-primitives = { path = "../../core/sr-primitives" } substrate-primitives = { path = "../../core/primitives" } +rpc-primitives = { package = "substrate-rpc-primitives", path = "../../core/rpc/primitives" } transaction_pool = { package = "substrate-transaction-pool", path = "../../core/transaction-pool" } [dev-dependencies] diff --git a/node/rpc/src/accounts.rs b/node/rpc/src/accounts.rs index 09d4a51442..9586b8b389 100644 --- a/node/rpc/src/accounts.rs +++ b/node/rpc/src/accounts.rs @@ -31,8 +31,6 @@ use transaction_pool::txpool::{self, Pool}; pub use self::gen_client::Client as AccountsClient; -const RUNTIME_ERROR: i64 = 1; - /// Accounts RPC methods. #[rpc] pub trait AccountsApi { @@ -75,7 +73,7 @@ where let at = BlockId::hash(best); let nonce = api.account_nonce(&at, account.clone()).map_err(|e| Error { - code: ErrorCode::ServerError(RUNTIME_ERROR), + code: ErrorCode::ServerError(crate::constants::RUNTIME_ERROR), message: "Unable to query nonce.".into(), data: Some(format!("{:?}", e).into()), })?; diff --git a/node/rpc/src/contracts.rs b/node/rpc/src/contracts.rs new file mode 100644 index 0000000000..3da2478dab --- /dev/null +++ b/node/rpc/src/contracts.rs @@ -0,0 +1,116 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Node-specific RPC methods for interaction with contracts. + +use std::sync::Arc; + +use serde::{Serialize, Deserialize}; +use client::blockchain::HeaderBackend; +use jsonrpc_core::{Error, ErrorCode, Result}; +use jsonrpc_derive::rpc; +use node_primitives::{ + AccountId, Balance, Block, BlockId, ContractExecResult, ContractsApi as ContractsRuntimeApi, +}; +use sr_primitives::traits::{ + self, + Block as BlockT, +}; +use rpc_primitives::number; + +/// A struct that encodes RPC parameters required for a call to a smart-contract. +#[derive(Serialize, Deserialize)] +#[serde(rename_all="camelCase")] +#[serde(deny_unknown_fields)] +pub struct CallRequest { + origin: AccountId, + dest: AccountId, + value: Balance, + gas_limit: number::NumberOrHex, + input_data: Vec, +} + +/// Contracts RPC methods. +#[rpc] +pub trait ContractsApi { + /// Executes a call to a contract. + /// + /// This call is performed locally without submitting any transactions. Thus executing this + /// won't change any state. Nonetheless, the calling state-changing contracts is still possible. + /// + /// This method is useful for calling getter-like methods on contracts. + #[rpc(name = "contracts_call")] + fn call( + &self, + call_request: CallRequest, + at: Option, + ) -> Result; +} + +/// An implementation of contract specific RPC methods. +pub struct Contracts { + client: Arc, +} + +impl Contracts { + /// Create new `Contracts` with the given reference to the client. + pub fn new(client: Arc) -> Self { + Contracts { client } + } +} + +impl ContractsApi<::Hash> for Contracts +where + C: Send + Sync + 'static, + C: traits::ProvideRuntimeApi, + C: HeaderBackend, + C::Api: ContractsRuntimeApi, +{ + fn call( + &self, + call_request: CallRequest, + at: Option<::Hash>, + ) -> Result { + let api = self.client.runtime_api(); + let at = BlockId::hash(at.unwrap_or_else(|| + // If the block hash is not supplied assume the best block. + self.client.info().best_hash + )); + + let CallRequest { + origin, + dest, + value, + gas_limit, + input_data + } = call_request; + let gas_limit = gas_limit.to_number().map_err(|e| Error { + code: ErrorCode::InvalidParams, + message: e, + data: None, + })?; + + let exec_result = api + .call(&at, origin, dest, value, gas_limit, input_data) + .map_err(|e| Error { + code: ErrorCode::ServerError(crate::constants::RUNTIME_ERROR), + message: "Runtime trapped while executing a contract.".into(), + data: Some(format!("{:?}", e).into()), + })?; + + Ok(exec_result) + } +} diff --git a/node/rpc/src/lib.rs b/node/rpc/src/lib.rs index e25424397d..0d23c40a34 100644 --- a/node/rpc/src/lib.rs +++ b/node/rpc/src/lib.rs @@ -30,3 +30,11 @@ #![warn(missing_docs)] pub mod accounts; +pub mod contracts; + +mod constants { + /// A status code indicating an error happened while trying to call into the runtime. + /// + /// This typically means that the runtime trapped. + pub const RUNTIME_ERROR: i64 = 1; +} diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 72a533ada8..0a30e09f5e 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -27,7 +27,7 @@ use support::{ use primitives::u32_trait::{_1, _2, _3, _4}; use node_primitives::{ AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, - Moment, Signature, + Moment, Signature, ContractExecResult, }; use babe::{AuthorityId as BabeId}; use grandpa::fg_primitives::{self, ScheduledChange}; @@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 156, - impl_version: 157, + impl_version: 158, apis: RUNTIME_API_VERSIONS, }; @@ -654,6 +654,31 @@ impl_runtime_apis! { } } + impl node_primitives::ContractsApi for Runtime { + fn call( + origin: AccountId, + dest: AccountId, + value: Balance, + gas_limit: u64, + input_data: Vec, + ) -> ContractExecResult { + let exec_result = Contracts::bare_call( + origin, + dest.into(), + value, + gas_limit, + input_data, + ); + match exec_result { + Ok(v) => ContractExecResult::Success { + status: v.status, + data: v.data, + }, + Err(_) => ContractExecResult::Error, + } + } + } + impl substrate_session::SessionKeys for Runtime { fn generate_session_keys(seed: Option>) -> Vec { let seed = seed.as_ref().map(|s| rstd::str::from_utf8(&s).expect("Seed is an utf8 string")); diff --git a/srml/contracts/src/exec.rs b/srml/contracts/src/exec.rs index 8308a9180c..5f871f519e 100644 --- a/srml/contracts/src/exec.rs +++ b/srml/contracts/src/exec.rs @@ -75,11 +75,12 @@ pub type ExecResult = Result; /// wrap the error string into an ExecutionError with the provided buffer and return from the /// enclosing function. This macro is used instead of .map_err(..)? in order to avoid taking /// ownership of buffer unless there is an error. +#[macro_export] macro_rules! try_or_exec_error { ($e:expr, $buffer:expr) => { match $e { Ok(val) => val, - Err(reason) => return Err(ExecError { reason, buffer: $buffer }), + Err(reason) => return Err($crate::exec::ExecError { reason, buffer: $buffer }), } } } @@ -191,15 +192,6 @@ pub trait Loader { fn load_main(&self, code_hash: &CodeHash) -> Result; } -/// Struct that records a request to deposit an event with a list of topics. -#[cfg_attr(any(feature = "std", test), derive(Debug, PartialEq, Eq))] -pub struct IndexedEvent { - /// A list of topics this event will be deposited with. - pub topics: Vec, - /// The event to deposit. - pub event: Event, -} - /// A trait that represent a virtual machine. /// /// You can view a virtual machine as something that takes code, an input data buffer, diff --git a/srml/contracts/src/lib.rs b/srml/contracts/src/lib.rs index 74ad5867af..ef4ccab721 100644 --- a/srml/contracts/src/lib.rs +++ b/srml/contracts/src/lib.rs @@ -98,11 +98,13 @@ mod rent; #[cfg(test)] mod tests; -use crate::exec::{ExecutionContext, ExecResult}; +use crate::exec::ExecutionContext; use crate::account_db::{AccountDb, DirectAccountDb}; -pub use crate::gas::{Gas, GasMeter}; use crate::wasm::{WasmLoader, WasmVm}; +pub use crate::gas::{Gas, GasMeter}; +pub use crate::exec::{ExecResult, ExecReturnValue, ExecError, StatusCode}; + #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; use primitives::crypto::UncheckedFrom; @@ -573,9 +575,9 @@ decl_module! { let origin = ensure_signed(origin)?; let dest = T::Lookup::lookup(dest)?; - Self::execute_wasm(origin, gas_limit, |ctx, gas_meter| { - ctx.call(dest, value, gas_meter, data) - }) + Self::bare_call(origin, dest, value, gas_limit, data) + .map(|_| ()) + .map_err(|e| e.reason) } /// Creates a new contract from the `codehash` generated by `put_code`, optionally transferring some balance. @@ -601,6 +603,8 @@ decl_module! { ctx.instantiate(endowment, gas_meter, &code_hash, data) .map(|(_address, output)| output) }) + .map(|_| ()) + .map_err(|e| e.reason) } /// Allows block producers to claim a small reward for evicting a contract. If a block producer @@ -645,16 +649,37 @@ decl_module! { } impl Module { + /// Perform a call to a specified contract. + /// + /// This function is similar to `Self::call`, but doesn't perform any lookups and better + /// suitable for calling directly from Rust. + pub fn bare_call( + origin: T::AccountId, + dest: T::AccountId, + value: BalanceOf, + gas_limit: Gas, + input_data: Vec, + ) -> ExecResult { + Self::execute_wasm(origin, gas_limit, |ctx, gas_meter| { + ctx.call(dest, value, gas_meter, input_data) + }) + } + fn execute_wasm( origin: T::AccountId, gas_limit: Gas, func: impl FnOnce(&mut ExecutionContext, &mut GasMeter) -> ExecResult - ) -> Result { + ) -> ExecResult { // Pay for the gas upfront. // // NOTE: it is very important to avoid any state changes before // paying for the gas. - let (mut gas_meter, imbalance) = gas::buy_gas::(&origin, gas_limit)?; + let (mut gas_meter, imbalance) = + try_or_exec_error!( + gas::buy_gas::(&origin, gas_limit), + // We don't have a spare buffer here in the first place, so create a new empty one. + Vec::new() + ); let cfg = Config::preload(); let vm = WasmVm::new(&cfg.schedule); @@ -705,8 +730,6 @@ impl Module { }); result - .map(|_| ()) - .map_err(|e| e.reason) } fn restore_to( -- GitLab From ed441c4bb07b51d08eafec9f59d48112f05c3515 Mon Sep 17 00:00:00 2001 From: Marcio Diaz Date: Thu, 12 Sep 2019 15:42:35 +0200 Subject: [PATCH 084/275] Fix subkey does not verify with pubkey (#3547) * Decode hex * Remove log * Some refactoring to help with testing * Add own functions for sign and verify. * Add sign test * Sign-verify test * Generate-sign-verify test for both cryptos * Add aliases * Print signature * More refactoring * Update sign-transaction as transfer * Simplify transfer and sign-transaction * main to top file * rename read_input_message to read_message_from_stdin * More refactoring * Add read_required_parameter * Add format seed * More refactoring * format code * add print_extrinsic * Remove 0x from print * fix naming * Fix readme * Remove rustfmt * Remove commented test * Fix import nits --- subkey/README.adoc | 4 +- subkey/src/main.rs | 533 ++++++++++++++++++++++++++++--------------- subkey/src/vanity.rs | 57 +++-- 3 files changed, 387 insertions(+), 207 deletions(-) diff --git a/subkey/README.adoc b/subkey/README.adoc index 52770e78ec..07533a002f 100644 --- a/subkey/README.adoc +++ b/subkey/README.adoc @@ -31,7 +31,7 @@ OUTPUT: `subkey` expects a message to come in on STDIN, one way to sign a message would look like this: ```bash -echo | subkey sign +echo -n | subkey sign OUTPUT: a69da4a6ccbf81dbbbfad235fa12cf8528c18012b991ae89214de8d20d29c1280576ced6eb38b7406d1b7e03231df6dd4a5257546ddad13259356e1c3adfb509 @@ -40,7 +40,7 @@ a69da4a6ccbf81dbbbfad235fa12cf8528c18012b991ae89214de8d20d29c1280576ced6eb38b740 === Verifying a signature ```bash -echo | subkey verify
+echo -n | subkey verify
OUTPUT: Signature verifies correctly. diff --git a/subkey/src/main.rs b/subkey/src/main.rs index a68674513a..c112dfa1b4 100644 --- a/subkey/src/main.rs +++ b/subkey/src/main.rs @@ -18,54 +18,69 @@ #[cfg(feature = "bench")] extern crate test; -use std::{str::FromStr, io::{stdin, Read}, convert::TryInto}; +use bip39::{Language, Mnemonic, MnemonicType}; +use clap::{load_yaml, App, ArgMatches}; +use codec::{Decode, Encode}; use hex_literal::hex; -use clap::load_yaml; -use bip39::{Mnemonic, Language, MnemonicType}; +use node_primitives::{Balance, Hash, Index}; +use node_runtime::{BalancesCall, Call, Runtime, SignedPayload, UncheckedExtrinsic, VERSION}; use primitives::{ - ed25519, sr25519, hexdisplay::HexDisplay, Pair, Public, blake2_256, - crypto::{Ss58Codec, set_default_ss58_version, Ss58AddressFormat} + crypto::{set_default_ss58_version, Ss58AddressFormat, Ss58Codec}, + ed25519, sr25519, Pair, Public, H256, hexdisplay::HexDisplay, }; -use codec::{Encode, Decode}; use sr_primitives::generic::Era; -use node_primitives::{Balance, Index, Hash}; -use node_runtime::{Call, UncheckedExtrinsic, SignedPayload, BalancesCall, Runtime, VERSION}; +use std::{ + convert::TryInto, + io::{stdin, Read}, + str::FromStr, +}; mod vanity; -trait Crypto { - type Pair: Pair; +trait Crypto: Sized { + type Pair: Pair; type Public: Public + Ss58Codec + AsRef<[u8]> + std::hash::Hash; fn pair_from_suri(suri: &str, password: Option<&str>) -> Self::Pair { Self::Pair::from_string(suri, password).expect("Invalid phrase") } - fn ss58_from_pair(pair: &Self::Pair) -> String { pair.public().to_ss58check() } - fn public_from_pair(pair: &Self::Pair) -> Vec { pair.public().as_ref().to_owned() } + fn ss58_from_pair(pair: &Self::Pair) -> String { + pair.public().to_ss58check() + } + fn public_from_pair(pair: &Self::Pair) -> Self::Public { + pair.public() + } fn print_from_uri( uri: &str, password: Option<&str>, network_override: Option, - ) where ::Public: Sized + Ss58Codec + AsRef<[u8]> { + ) where + ::Public: PublicT, + { if let Ok((pair, seed)) = Self::Pair::from_phrase(uri, password) { - println!("Secret phrase `{}` is account:\n Secret seed: 0x{}\n Public key (hex): 0x{}\n Address (SS58): {}", + let public_key = Self::public_from_pair(&pair); + println!("Secret phrase `{}` is account:\n Secret seed: {}\n Public key (hex): {}\n Address (SS58): {}", uri, - HexDisplay::from(&seed.as_ref()), - HexDisplay::from(&Self::public_from_pair(&pair)), + format_seed::(seed), + format_public_key::(public_key), Self::ss58_from_pair(&pair) ); } else if let Ok(pair) = Self::Pair::from_string(uri, password) { - println!("Secret Key URI `{}` is account:\n Public key (hex): 0x{}\n Address (SS58): {}", + let public_key = Self::public_from_pair(&pair); + println!( + "Secret Key URI `{}` is account:\n Public key (hex): {}\n Address (SS58): {}", uri, - HexDisplay::from(&Self::public_from_pair(&pair)), + format_public_key::(public_key), Self::ss58_from_pair(&pair) ); - } else if let Ok((public, v)) = ::Public::from_string_with_version(uri) { + } else if let Ok((public_key, v)) = + ::Public::from_string_with_version(uri) + { let v = network_override.unwrap_or(v); - println!("Public Key URI `{}` is account:\n Network ID/version: {}\n Public key (hex): 0x{}\n Address (SS58): {}", + println!("Public Key URI `{}` is account:\n Network ID/version: {}\n Public key (hex): {}\n Address (SS58): {}", uri, String::from(v), - HexDisplay::from(&public.as_ref()), - public.to_ss58check_with_version(v) + format_public_key::(public_key.clone()), + public_key.to_ss58check_with_version(v) ); } else { println!("Invalid phrase/URI given"); @@ -91,216 +106,360 @@ impl Crypto for Sr25519 { type Public = sr25519::Public; } -fn execute(matches: clap::ArgMatches) where - <::Pair as Pair>::Signature: AsRef<[u8]> + AsMut<[u8]> + Default, - <::Pair as Pair>::Public: Sized + AsRef<[u8]> + Ss58Codec, +type SignatureOf = <::Pair as Pair>::Signature; +type PublicOf = <::Pair as Pair>::Public; +type SeedOf = <::Pair as Pair>::Seed; + +trait SignatureT: AsRef<[u8]> + AsMut<[u8]> + Default {} +trait PublicT: Sized + AsRef<[u8]> + Ss58Codec {} + +impl SignatureT for sr25519::Signature {} +impl SignatureT for ed25519::Signature {} +impl PublicT for sr25519::Public {} +impl PublicT for ed25519::Public {} + +fn main() { + let yaml = load_yaml!("cli.yml"); + let matches = App::from_yaml(yaml) + .version(env!("CARGO_PKG_VERSION")) + .get_matches(); + + if matches.is_present("ed25519") { + execute::(matches) + } else { + execute::(matches) + } +} + +fn execute(matches: ArgMatches) +where + SignatureOf: SignatureT, + PublicOf: PublicT, { - let extra = |i: Index, f: Balance| { - ( - system::CheckVersion::::new(), - system::CheckGenesis::::new(), - system::CheckEra::::from(Era::Immortal), - system::CheckNonce::::from(i), - system::CheckWeight::::new(), - balances::TakeFees::::from(f), - Default::default(), - ) - }; let password = matches.value_of("password"); - let maybe_network: Option = matches.value_of("network") - .map(|network| network.try_into() + let maybe_network: Option = matches.value_of("network").map(|network| { + network + .try_into() .expect("Invalid network name: must be polkadot/substrate/kusama") - ); + }); if let Some(network) = maybe_network { set_default_ss58_version(network); } match matches.subcommand() { ("generate", Some(matches)) => { - // create a new randomly generated mnemonic phrase - let words = matches.value_of("words") - .map(|x| usize::from_str(x).expect("Invalid number given for --words")) - .map(|x| MnemonicType::for_word_count(x) - .expect("Invalid number of words given for phrase: must be 12/15/18/21/24") - ).unwrap_or(MnemonicType::Words12); - let mnemonic = Mnemonic::new(words, Language::English); + let mnemonic = generate_mnemonic(matches); C::print_from_uri(mnemonic.phrase(), password, maybe_network); } ("inspect", Some(matches)) => { - let uri = matches.value_of("uri") + let uri = matches + .value_of("uri") .expect("URI parameter is required; thus it can't be None; qed"); C::print_from_uri(uri, password, maybe_network); } - ("vanity", Some(matches)) => { - let desired: String = matches.value_of("pattern").map(str::to_string).unwrap_or_default(); - let result = vanity::generate_key::(&desired).expect("Key generation failed"); - C::print_from_uri( - &format!("0x{}", HexDisplay::from(&result.seed.as_ref())), - None, - maybe_network - ); - } ("sign", Some(matches)) => { - let suri = matches.value_of("suri") - .expect("secret URI parameter is required; thus it can't be None; qed"); - let pair = C::pair_from_suri(suri, password); - let mut message = vec![]; - stdin().lock().read_to_end(&mut message).expect("Error reading from stdin"); - if matches.is_present("hex") { - message = hex::decode(&message).expect("Invalid hex in message"); + let should_decode = matches.is_present("hex"); + let message = read_message_from_stdin(should_decode); + let signature = do_sign::(matches, message, password); + println!("{}", signature); + } + ("verify", Some(matches)) => { + let should_decode = matches.is_present("hex"); + let message = read_message_from_stdin(should_decode); + let is_valid_signature = do_verify::(matches, message, password); + if is_valid_signature { + println!("Signature verifies correctly."); + } else { + println!("Signature invalid."); } - let sig = pair.sign(&message); - println!("{}", hex::encode(&sig)); + } + ("vanity", Some(matches)) => { + let desired: String = matches + .value_of("pattern") + .map(str::to_string) + .unwrap_or_default(); + let result = vanity::generate_key::(&desired).expect("Key generation failed"); + let formated_seed = format_seed::(result.seed); + C::print_from_uri(&formated_seed, None, maybe_network); } ("transfer", Some(matches)) => { - let signer = matches.value_of("from") - .expect("parameter is required; thus it can't be None; qed"); - let signer = Sr25519::pair_from_suri(signer, password); - - let to = matches.value_of("to") - .expect("parameter is required; thus it can't be None; qed"); - let to = sr25519::Public::from_string(to).ok().or_else(|| - sr25519::Pair::from_string(to, password).ok().map(|p| p.public()) - ).expect("Invalid 'to' URI; expecting either a secret URI or a public URI."); - - let amount = matches.value_of("amount") - .expect("parameter is required; thus it can't be None; qed"); - let amount = str::parse::(amount) - .expect("Invalid 'amount' parameter; expecting an integer."); - - let index = matches.value_of("index") - .expect("parameter is required; thus it can't be None; qed"); - let index = str::parse::(index) - .expect("Invalid 'index' parameter; expecting an integer."); + let signer = read_pair::(matches.value_of("from"), password); + let index = read_required_parameter::(matches, "index"); + let genesis_hash = read_genesis_hash(matches); + let to = read_public_key::(matches.value_of("to"), password); + let amount = read_required_parameter::(matches, "amount"); let function = Call::Balances(BalancesCall::transfer(to.into(), amount)); - let genesis_hash: Hash = match matches.value_of("genesis").unwrap_or("alex") { - "elm" => hex!["10c08714a10c7da78f40a60f6f732cf0dba97acfb5e2035445b032386157d5c3"].into(), - "alex" => hex!["dcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b"].into(), - h => hex::decode(h).ok().and_then(|x| Decode::decode(&mut &x[..]).ok()) - .expect("Invalid genesis hash or unrecognised chain identifier"), - }; + let extrinsic = create_extrinsic(function, index, signer, genesis_hash); - println!("Using a genesis hash of {}", HexDisplay::from(&genesis_hash.as_ref())); - - let raw_payload = SignedPayload::from_raw( - function, - extra(index, 0), - (VERSION.spec_version as u32, genesis_hash, genesis_hash, (), (), (), ()), - ); - let signature = raw_payload.using_encoded(|payload| { - println!("Signing {}", HexDisplay::from(&payload)); - signer.sign(payload) - }); - let (function, extra, _) = raw_payload.deconstruct(); - let extrinsic = UncheckedExtrinsic::new_signed( - function, - signer.public().into(), - signature.into(), - extra, - ); - println!("0x{}", hex::encode(&extrinsic.encode())); + print_extrinsic(extrinsic); } ("sign-transaction", Some(matches)) => { - let s = matches.value_of("suri") - .expect("secret URI parameter is required; thus it can't be None; qed"); - let signer = Sr25519::pair_from_suri(s, password); - - let index = matches.value_of("nonce") - .expect("nonce is required; thus it can't be None; qed"); - let index = str::parse::(index) - .expect("Invalid 'nonce' parameter; expecting an integer."); - - let call = matches.value_of("call") - .expect("call is required; thus it can't be None; qed"); - let function: Call = hex::decode(&call).ok() - .and_then(|x| Decode::decode(&mut &x[..]).ok()).unwrap(); - - let genesis_hash: Hash = match matches.value_of("genesis").unwrap_or("alex") { - "elm" => hex!["10c08714a10c7da78f40a60f6f732cf0dba97acfb5e2035445b032386157d5c3"].into(), - "alex" => hex!["dcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b"].into(), - h => hex::decode(h).ok().and_then(|x| Decode::decode(&mut &x[..]).ok()) - .expect("Invalid genesis hash or unrecognised chain identifier"), - }; - - println!("Using a genesis hash of {}", HexDisplay::from(&genesis_hash.as_ref())); - - let raw_payload = ( - function, - extra(index, 0), - (&genesis_hash, &genesis_hash), - ); - let signature = raw_payload.using_encoded(|payload| - if payload.len() > 256 { - signer.sign(&blake2_256(payload)[..]) - } else { - signer.sign(payload) - } - ); + let signer = read_pair::(matches.value_of("suri"), password); + let index = read_required_parameter::(matches, "nonce"); + let genesis_hash = read_genesis_hash(matches); - let extrinsic = UncheckedExtrinsic::new_signed( - raw_payload.0, - signer.public().into(), - signature.into(), - extra(index, 0), - ); + let call = matches.value_of("call").expect("call is required; qed"); + let function: Call = hex::decode(&call) + .ok() + .and_then(|x| Decode::decode(&mut &x[..]).ok()) + .unwrap(); - println!("0x{}", hex::encode(&extrinsic.encode())); - } - ("verify", Some(matches)) => { - let sig_data = matches.value_of("sig") - .expect("signature parameter is required; thus it can't be None; qed"); - let mut sig = <::Pair as Pair>::Signature::default(); - let sig_data = hex::decode(sig_data).expect("signature is invalid hex"); - if sig_data.len() != sig.as_ref().len() { - panic!("signature is an invalid length. {} bytes is not the expected value of {} bytes", sig_data.len(), sig.as_ref().len()); - } - sig.as_mut().copy_from_slice(&sig_data); - let uri = matches.value_of("uri") - .expect("public uri parameter is required; thus it can't be None; qed"); - let pubkey = <::Pair as Pair>::Public::from_string(uri).ok().or_else(|| - ::Pair::from_string(uri, password).ok().map(|p| p.public()) - ).expect("Invalid URI; expecting either a secret URI or a public URI."); - let mut message = vec![]; - stdin().lock().read_to_end(&mut message).expect("Error reading from stdin"); - if matches.is_present("hex") { - message = hex::decode(&message).expect("Invalid hex in message"); - } - if <::Pair as Pair>::verify(&sig, &message, &pubkey) { - println!("Signature verifies correctly.") - } else { - println!("Signature invalid.") - } + let extrinsic = create_extrinsic(function, index, signer, genesis_hash); + + print_extrinsic(extrinsic); } _ => print_usage(&matches), } } -fn main() { - let yaml = load_yaml!("cli.yml"); - let matches = clap::App::from_yaml(yaml) - .version(env!("CARGO_PKG_VERSION")) - .get_matches(); +/// Creates a new randomly generated mnemonic phrase. +fn generate_mnemonic(matches: &ArgMatches) -> Mnemonic { + let words = matches + .value_of("words") + .map(|x| usize::from_str(x).expect("Invalid number given for --words")) + .map(|x| { + MnemonicType::for_word_count(x) + .expect("Invalid number of words given for phrase: must be 12/15/18/21/24") + }) + .unwrap_or(MnemonicType::Words12); + Mnemonic::new(words, Language::English) +} - if matches.is_present("ed25519") { - execute::(matches) +fn do_sign(matches: &ArgMatches, message: Vec, password: Option<&str>) -> String +where + SignatureOf: SignatureT, + PublicOf: PublicT, +{ + let pair = read_pair::(matches.value_of("suri"), password); + let signature = pair.sign(&message); + format_signature::(&signature) +} + +fn do_verify(matches: &ArgMatches, message: Vec, password: Option<&str>) -> bool +where + SignatureOf: SignatureT, + PublicOf: PublicT, +{ + let signature = read_signature::(matches); + let pubkey = read_public_key::(matches.value_of("uri"), password); + <::Pair as Pair>::verify(&signature, &message, &pubkey) +} + +fn read_message_from_stdin(should_decode: bool) -> Vec { + let mut message = vec![]; + stdin() + .lock() + .read_to_end(&mut message) + .expect("Error reading from stdin"); + if should_decode { + message = hex::decode(&message).expect("Invalid hex in message"); + } + message +} + +fn read_required_parameter(matches: &ArgMatches, name: &str) -> T +where + ::Err: std::fmt::Debug, +{ + let str_value = matches + .value_of(name) + .expect("parameter is required; thus it can't be None; qed"); + str::parse::(str_value).expect("Invalid 'nonce' parameter; expecting an integer.") +} + +fn read_genesis_hash(matches: &ArgMatches) -> H256 { + let genesis_hash: Hash = match matches.value_of("genesis").unwrap_or("alex") { + "elm" => hex!["10c08714a10c7da78f40a60f6f732cf0dba97acfb5e2035445b032386157d5c3"].into(), + "alex" => hex!["dcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b"].into(), + h => hex::decode(h) + .ok() + .and_then(|x| Decode::decode(&mut &x[..]).ok()) + .expect("Invalid genesis hash or unrecognised chain identifier"), + }; + println!( + "Using a genesis hash of {}", + HexDisplay::from(&genesis_hash.as_ref()) + ); + genesis_hash +} + +fn read_signature(matches: &ArgMatches) -> SignatureOf +where + SignatureOf: SignatureT, + PublicOf: PublicT, +{ + let sig_data = matches + .value_of("sig") + .expect("signature parameter is required; thus it can't be None; qed"); + let mut signature = <::Pair as Pair>::Signature::default(); + let sig_data = hex::decode(sig_data).expect("signature is invalid hex"); + if sig_data.len() != signature.as_ref().len() { + panic!( + "signature has an invalid length. read {} bytes, expected {} bytes", + sig_data.len(), + signature.as_ref().len(), + ); + } + signature.as_mut().copy_from_slice(&sig_data); + signature +} + +fn read_public_key(matched_uri: Option<&str>, password: Option<&str>) -> PublicOf +where + SignatureOf: SignatureT, + PublicOf: PublicT, +{ + let uri = matched_uri.expect("parameter is required; thus it can't be None; qed"); + let uri = if uri.starts_with("0x") { + &uri[2..] } else { - execute::(matches) + uri + }; + if let Ok(pubkey_vec) = hex::decode(uri) { + ::Public::from_slice(pubkey_vec.as_slice()) + } else { + ::Pair::from_string(uri, password) + .ok() + .map(|p| p.public()) + .expect("Invalid URI; expecting either a secret URI or a public URI.") } } -fn print_usage(matches: &clap::ArgMatches) { +fn read_pair( + matched_suri: Option<&str>, + password: Option<&str>, +) -> ::Pair +where + SignatureOf: SignatureT, + PublicOf: PublicT, +{ + let suri = matched_suri.expect("parameter is required; thus it can't be None; qed"); + C::pair_from_suri(suri, password) +} + +fn format_signature(signature: &SignatureOf) -> String { + format!("{}", hex::encode(signature)) +} + +fn format_seed(seed: SeedOf) -> String { + format!("0x{}", HexDisplay::from(&seed.as_ref())) +} + +fn format_public_key(public_key: PublicOf) -> String { + format!("0x{}", HexDisplay::from(&public_key.as_ref())) +} + +fn create_extrinsic( + function: Call, + index: Index, + signer: ::Pair, + genesis_hash: H256, +) -> UncheckedExtrinsic { + let extra = |i: Index, f: Balance| { + ( + system::CheckVersion::::new(), + system::CheckGenesis::::new(), + system::CheckEra::::from(Era::Immortal), + system::CheckNonce::::from(i), + system::CheckWeight::::new(), + balances::TakeFees::::from(f), + Default::default(), + ) + }; + let raw_payload = SignedPayload::from_raw( + function, + extra(index, 0), + ( + VERSION.spec_version as u32, + genesis_hash, + genesis_hash, + (), + (), + (), + (), + ), + ); + let signature = raw_payload.using_encoded(|payload| signer.sign(payload)); + let (function, extra, _) = raw_payload.deconstruct(); + + UncheckedExtrinsic::new_signed( + function, + signer.public().into(), + signature.into(), + extra, + ) +} + +fn print_extrinsic(extrinsic: UncheckedExtrinsic) { + println!("0x{}", hex::encode(&extrinsic.encode())); +} + +fn print_usage(matches: &ArgMatches) { println!("{}", matches.usage()); } #[cfg(test)] mod tests { - use super::{Hash, Decode}; + use super::*; + + fn test_generate_sign_verify() + where + SignatureOf: SignatureT, + PublicOf: PublicT, + { + let yaml = load_yaml!("cli.yml"); + let app = App::from_yaml(yaml); + let password = None; + + // Generate public key and seed. + let arg_vec = vec!["subkey", "generate"]; + + let matches = app.clone().get_matches_from(arg_vec); + let matches = matches.subcommand().1.unwrap(); + let mnemonic = generate_mnemonic(matches); + + let (pair, seed) = + <::Pair as Pair>::from_phrase(mnemonic.phrase(), password) + .unwrap(); + let public_key = CryptoType::public_from_pair(&pair); + let public_key = format_public_key::(public_key); + let seed = format_seed::(seed); + + // Sign a message using previous seed. + let arg_vec = vec!["subkey", "sign", &seed[..]]; + + let matches = app.get_matches_from(arg_vec); + let matches = matches.subcommand().1.unwrap(); + let message = "Blah Blah\n".as_bytes().to_vec(); + let signature = do_sign::(matches, message.clone(), password); + + // Verify the previous signature. + let arg_vec = vec!["subkey", "verify", &signature[..], &public_key[..]]; + + let matches = App::from_yaml(yaml).get_matches_from(arg_vec); + let matches = matches.subcommand().1.unwrap(); + assert!(do_verify::(matches, message, password)); + } + + #[test] + fn generate_sign_verify_should_work_for_ed25519() { + test_generate_sign_verify::(); + } + + #[test] + fn generate_sign_verify_should_work_for_sr25519() { + test_generate_sign_verify::(); + } + #[test] fn should_work() { let s = "0123456789012345678901234567890123456789012345678901234567890123"; - let d1: Hash = hex::decode(s).ok().and_then(|x| Decode::decode(&mut &x[..]).ok()).unwrap(); + let d1: Hash = hex::decode(s) + .ok() + .and_then(|x| Decode::decode(&mut &x[..]).ok()) + .unwrap(); let d2: Hash = { let mut gh: [u8; 32] = Default::default(); diff --git a/subkey/src/vanity.rs b/subkey/src/vanity.rs index 988055c67c..ea30f7413e 100644 --- a/subkey/src/vanity.rs +++ b/subkey/src/vanity.rs @@ -14,15 +14,15 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use rand::{rngs::OsRng, RngCore}; use super::Crypto; use primitives::Pair; +use rand::{rngs::OsRng, RngCore}; fn good_waypoint(done: u64) -> u64 { match done { - 0 ..= 1_000_000 => 100_000, - 0 ..= 10_000_000 => 1_000_000, - 0 ..= 100_000_000 => 10_000_000, + 0..=1_000_000 => 100_000, + 0..=10_000_000 => 1_000_000, + 0..=100_000_000 => 10_000_000, _ => 100_000_000, } } @@ -30,8 +30,13 @@ fn good_waypoint(done: u64) -> u64 { fn next_seed(seed: &mut [u8]) { for i in 0..seed.len() { match seed[i] { - 255 => { seed[i] = 0; } - _ => { seed[i] += 1; break; } + 255 => { + seed[i] = 0; + } + _ => { + seed[i] += 1; + break; + } } } } @@ -101,15 +106,20 @@ pub(super) fn generate_key(desired: &str) -> Result, &str> #[cfg(test)] mod tests { - use super::*; use super::super::Ed25519; - use primitives::{Pair, crypto::Ss58Codec}; + use super::*; + use primitives::{crypto::Ss58Codec, Pair}; #[cfg(feature = "bench")] use test::Bencher; #[test] fn test_generation_with_single_char() { - assert!(generate_key::("j").unwrap().pair.public().to_ss58check().contains("j")); + assert!(generate_key::("j") + .unwrap() + .pair + .public() + .to_ss58check() + .contains("j")); } #[test] @@ -120,34 +130,45 @@ mod tests { #[test] fn test_score_100() { - let score = calculate_score("Polkadot", "5PolkadotwHY5k9GpdTgpqs9xjuNvtv8EcwCFpEeyEf3KHim"); + let score = calculate_score( + "Polkadot", + "5PolkadotwHY5k9GpdTgpqs9xjuNvtv8EcwCFpEeyEf3KHim", + ); assert_eq!(score, 430); } #[test] fn test_score_50_2() { // 50% for the position + 50% for the size - assert_eq!(calculate_score("Polkadot", "5PolkXXXXwHY5k9GpdTgpqs9xjuNvtv8EcwCFpEeyEf3KHim"), 238); + assert_eq!( + calculate_score( + "Polkadot", + "5PolkXXXXwHY5k9GpdTgpqs9xjuNvtv8EcwCFpEeyEf3KHim" + ), + 238 + ); } #[test] fn test_score_0() { - assert_eq!(calculate_score("Polkadot", "5GUWv4bLCchGUHJrzULXnh4JgXsMpTKRnjuXTY7Qo1Kh9uYK"), 0); + assert_eq!( + calculate_score( + "Polkadot", + "5GUWv4bLCchGUHJrzULXnh4JgXsMpTKRnjuXTY7Qo1Kh9uYK" + ), + 0 + ); } #[cfg(feature = "bench")] #[bench] fn bench_paranoiac(b: &mut Bencher) { - b.iter(|| { - generate_key("polk") - }); + b.iter(|| generate_key("polk")); } #[cfg(feature = "bench")] #[bench] fn bench_not_paranoiac(b: &mut Bencher) { - b.iter(|| { - generate_key("polk") - }); + b.iter(|| generate_key("polk")); } } -- GitLab From 6c896311436231b248f9a0a3055efdca265766d3 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Thu, 12 Sep 2019 16:47:03 +0200 Subject: [PATCH 085/275] Sudo can dispatch from an account (#3604) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Sudo can dispatch from an account. * Fix * Bump runtime. * Update srml/sudo/src/lib.rs Co-Authored-By: Bastian Köcher --- node/runtime/src/lib.rs | 4 ++-- srml/sudo/src/lib.rs | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 0a30e09f5e..562dea598f 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -82,8 +82,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 156, - impl_version: 158, + spec_version: 157, + impl_version: 157, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/sudo/src/lib.rs b/srml/sudo/src/lib.rs index 845f1e4104..7d80851719 100644 --- a/srml/sudo/src/lib.rs +++ b/srml/sudo/src/lib.rs @@ -113,9 +113,10 @@ decl_module! { /// # /// - O(1). /// - Limited storage reads. - /// - No DB writes. + /// - One DB write (event). + /// - Unknown weight of derivative `proposal` execution. /// # - #[weight = SimpleDispatchInfo::FixedOperational(1_000_000)] + #[weight = SimpleDispatchInfo::FreeOperational] fn sudo(origin, proposal: Box) { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; @@ -151,6 +152,37 @@ decl_module! { Self::deposit_event(RawEvent::KeyChanged(Self::key())); >::put(new); } + + /// Authenticates the sudo key and dispatches a function call with `Signed` origin from + /// a given account. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// # + /// - O(1). + /// - Limited storage reads. + /// - One DB write (event). + /// - Unknown weight of derivative `proposal` execution. + /// # + #[weight = SimpleDispatchInfo::FixedOperational(0)] + fn sudo_as(origin, who: ::Source, proposal: Box) { + // This is a public call, so we ensure that the origin is some signed account. + let sender = ensure_signed(origin)?; + ensure!(sender == Self::key(), "only the current sudo key can sudo"); + + let who = T::Lookup::lookup(who)?; + + let res = match proposal.dispatch(system::RawOrigin::Signed(who).into()) { + Ok(_) => true, + Err(e) => { + let e: DispatchError = e.into(); + runtime_io::print(e); + false + } + }; + + Self::deposit_event(RawEvent::SudoAsDone(res)); + } } } @@ -160,6 +192,8 @@ decl_event!( Sudid(bool), /// The sudoer just switched identity; the old key is supplied. KeyChanged(AccountId), + /// A sudo just took place. + SudoAsDone(bool), } ); -- GitLab From a0dd5e8e0eadfcae6ed6183c78de43ee70e70db1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Thu, 12 Sep 2019 16:12:04 +0100 Subject: [PATCH 086/275] grandpa: reannounce voted blocks periodically (#3602) * grandpa: reannounce latest voted blocks periodically * grandpa: add test for background block announcement * grandpa: configurable delay for background block announcer * grandpa: nits --- .../finality-grandpa/src/communication/mod.rs | 15 +- .../src/communication/periodic.rs | 159 +++++++++++++++++- .../src/communication/tests.rs | 76 +++++++++ 3 files changed, 240 insertions(+), 10 deletions(-) diff --git a/core/finality-grandpa/src/communication/mod.rs b/core/finality-grandpa/src/communication/mod.rs index ea78c3ea9d..7185e93208 100644 --- a/core/finality-grandpa/src/communication/mod.rs +++ b/core/finality-grandpa/src/communication/mod.rs @@ -233,6 +233,7 @@ pub(crate) struct NetworkBridge> { service: N, validator: Arc>, neighbor_sender: periodic::NeighborPacketSender, + announce_sender: periodic::BlockAnnounceSender, } impl> NetworkBridge { @@ -299,9 +300,10 @@ impl> NetworkBridge { } let (rebroadcast_job, neighbor_sender) = periodic::neighbor_packet_worker(service.clone()); + let (announce_job, announce_sender) = periodic::block_announce_worker(service.clone()); let reporting_job = report_stream.consume(service.clone()); - let bridge = NetworkBridge { service, validator, neighbor_sender }; + let bridge = NetworkBridge { service, validator, neighbor_sender, announce_sender }; let startup_work = futures::future::lazy(move || { // lazily spawn these jobs onto their own tasks. the lazy future has access @@ -309,6 +311,8 @@ impl> NetworkBridge { let mut executor = tokio_executor::DefaultExecutor::current(); executor.spawn(Box::new(rebroadcast_job.select(on_exit.clone()).then(|_| Ok(())))) .expect("failed to spawn grandpa rebroadcast job task"); + executor.spawn(Box::new(announce_job.select(on_exit.clone()).then(|_| Ok(())))) + .expect("failed to spawn grandpa block announce job task"); executor.spawn(Box::new(reporting_job.select(on_exit.clone()).then(|_| Ok(())))) .expect("failed to spawn grandpa reporting job task"); Ok(()) @@ -424,6 +428,7 @@ impl> NetworkBridge { network: self.service.clone(), locals, sender: tx, + announce_sender: self.announce_sender.clone(), has_voted, }; @@ -616,6 +621,7 @@ impl> Clone for NetworkBridge { service: self.service.clone(), validator: Arc::clone(&self.validator), neighbor_sender: self.neighbor_sender.clone(), + announce_sender: self.announce_sender.clone(), } } } @@ -662,6 +668,7 @@ struct OutgoingMessages> { set_id: SetIdNumber, locals: Option<(AuthorityPair, AuthorityId)>, sender: mpsc::UnboundedSender>, + announce_sender: periodic::BlockAnnounceSender, network: N, has_voted: HasVoted, } @@ -719,10 +726,10 @@ impl> Sink for OutgoingMessages "block" => ?target_hash, "round" => ?self.round, "set_id" => ?self.set_id, ); - // announce our block hash to peers and propagate the - // message. - self.network.announce(target_hash); + // send the target block hash to the background block announcer + self.announce_sender.send(target_hash); + // propagate the message to peers let topic = round_topic::(self.round, self.set_id); self.network.gossip_message(topic, message.encode(), false); diff --git a/core/finality-grandpa/src/communication/periodic.rs b/core/finality-grandpa/src/communication/periodic.rs index 54383bb63d..333178dec2 100644 --- a/core/finality-grandpa/src/communication/periodic.rs +++ b/core/finality-grandpa/src/communication/periodic.rs @@ -16,20 +16,27 @@ //! Periodic rebroadcast of neighbor packets. -use super::{gossip::{NeighborPacket, GossipMessage}, Network}; +use std::collections::VecDeque; +use std::time::{Instant, Duration}; + +use codec::Encode; use futures::prelude::*; use futures::sync::mpsc; -use sr_primitives::traits::{NumberFor, Block as BlockT}; -use network::PeerId; -use tokio_timer::Delay; use log::{debug, warn}; -use codec::Encode; +use tokio_timer::Delay; -use std::time::{Instant, Duration}; +use network::PeerId; +use sr_primitives::traits::{NumberFor, Block as BlockT}; +use super::{gossip::{NeighborPacket, GossipMessage}, Network}; // how often to rebroadcast, if no other const REBROADCAST_AFTER: Duration = Duration::from_secs(2 * 60); +/// The number of block hashes that we have previously voted on that we should +/// keep around for announcement. The current value should be enough for 3 +/// rounds assuming we have prevoted and precommited on different blocks. +const LATEST_VOTED_BLOCKS_TO_ANNOUNCE: usize = 6; + fn rebroadcast_instant() -> Instant { Instant::now() + REBROADCAST_AFTER } @@ -41,6 +48,7 @@ pub(super) struct NeighborPacketSender( ); impl NeighborPacketSender { + /// Send a neighbor packet for the background worker to gossip to peers. pub fn send( &self, who: Vec, @@ -106,3 +114,142 @@ pub(super) fn neighbor_packet_worker(net: N) -> ( (work, NeighborPacketSender(tx)) } + +/// A background worker for performing block announcements. +struct BlockAnnouncer { + net: N, + block_rx: mpsc::UnboundedReceiver, + latest_voted_blocks: VecDeque, + reannounce_after: Duration, + delay: Delay, +} + +/// A background worker for announcing block hashes to peers. The worker keeps +/// track of `LATEST_VOTED_BLOCKS_TO_ANNOUNCE` and periodically announces these +/// blocks to all peers if no new blocks to announce are noted (i.e. presumably +/// GRANDPA progress is stalled). +pub(super) fn block_announce_worker>(net: N) -> ( + impl Future, + BlockAnnounceSender, +) { + block_announce_worker_aux(net, REBROADCAST_AFTER) +} + +#[cfg(test)] +pub(super) fn block_announce_worker_with_delay>( + net: N, + reannounce_after: Duration, +) -> ( + impl Future, + BlockAnnounceSender, +) { + block_announce_worker_aux(net, reannounce_after) +} + +fn block_announce_worker_aux>( + net: N, + reannounce_after: Duration, +) -> ( + impl Future, + BlockAnnounceSender, +) { + let latest_voted_blocks = VecDeque::with_capacity(LATEST_VOTED_BLOCKS_TO_ANNOUNCE); + + let (block_tx, block_rx) = mpsc::unbounded(); + + let announcer = BlockAnnouncer { + net, + block_rx, + latest_voted_blocks, + reannounce_after, + delay: Delay::new(Instant::now() + reannounce_after), + }; + + (announcer, BlockAnnounceSender(block_tx)) +} + + +impl BlockAnnouncer { + fn note_block(&mut self, block: B::Hash) -> bool { + if !self.latest_voted_blocks.contains(&block) { + if self.latest_voted_blocks.len() >= LATEST_VOTED_BLOCKS_TO_ANNOUNCE { + self.latest_voted_blocks.pop_front(); + } + + self.latest_voted_blocks.push_back(block); + + true + } else { + false + } + } + + fn reset_delay(&mut self) { + self.delay.reset(Instant::now() + self.reannounce_after); + } +} + +impl> Future for BlockAnnouncer { + type Item = (); + type Error = (); + + fn poll(&mut self) -> Poll { + // note any new blocks to announce and announce them + loop { + match self.block_rx.poll().expect("unbounded receivers do not error; qed") { + Async::Ready(None) => return Ok(Async::Ready(())), + Async::Ready(Some(block)) => { + if self.note_block(block) { + self.net.announce(block); + self.reset_delay(); + } + }, + Async::NotReady => break, + } + } + + // check the reannouncement delay timer, has to be done in a loop + // because it needs to be polled after re-scheduling. + loop { + match self.delay.poll() { + Err(e) => { + warn!(target: "afg", "Error in periodic block announcer timer: {:?}", e); + self.reset_delay(); + }, + // after the delay fires announce all blocks that we have + // stored. note that this only happens if we don't receive any + // new blocks above for the duration of `reannounce_after`. + Ok(Async::Ready(())) => { + self.reset_delay(); + + debug!( + target: "afg", + "Re-announcing latest voted blocks due to lack of progress: {:?}", + self.latest_voted_blocks, + ); + + for block in self.latest_voted_blocks.iter() { + self.net.announce(*block); + } + }, + Ok(Async::NotReady) => return Ok(Async::NotReady), + } + } + } +} + +/// A sender used to send block hashes to announce to a background job. +#[derive(Clone)] +pub(super) struct BlockAnnounceSender(mpsc::UnboundedSender); + +impl BlockAnnounceSender { + /// Send a block hash for the background worker to announce. + pub fn send( + &self, + block: B::Hash, + ) { + if let Err(err) = self.0.unbounded_send(block) { + debug!(target: "afg", "Failed to send block to background announcer: {:?}", err); + } + } +} diff --git a/core/finality-grandpa/src/communication/tests.rs b/core/finality-grandpa/src/communication/tests.rs index b537c29dca..28de0e538c 100644 --- a/core/finality-grandpa/src/communication/tests.rs +++ b/core/finality-grandpa/src/communication/tests.rs @@ -498,3 +498,79 @@ fn peer_with_higher_view_leads_to_catch_up_request() { current_thread::block_on_all(test).unwrap(); } + +#[test] +fn periodically_reannounce_voted_blocks_on_stall() { + use futures::try_ready; + use std::collections::HashSet; + use std::sync::Arc; + use std::time::Duration; + use parking_lot::Mutex; + + let (tester, net) = make_test_network(); + let (announce_worker, announce_sender) = super::periodic::block_announce_worker_with_delay( + net, + Duration::from_secs(1), + ); + + let hashes = Arc::new(Mutex::new(Vec::new())); + + fn wait_all(tester: Tester, hashes: &[Hash]) -> impl Future { + struct WaitAll { + remaining_hashes: Arc>>, + events_fut: Box>, + } + + impl Future for WaitAll { + type Item = Tester; + type Error = (); + + fn poll(&mut self) -> Poll { + let tester = try_ready!(self.events_fut.poll()); + + if self.remaining_hashes.lock().is_empty() { + return Ok(Async::Ready(tester)); + } + + let remaining_hashes = self.remaining_hashes.clone(); + self.events_fut = Box::new(tester.filter_network_events(move |event| match event { + Event::Announce(h) => + remaining_hashes.lock().remove(&h) || panic!("unexpected announce"), + _ => false, + })); + + self.poll() + } + } + + WaitAll { + remaining_hashes: Arc::new(Mutex::new(hashes.iter().cloned().collect())), + events_fut: Box::new(futures::future::ok(tester)), + } + } + + let test = tester + .and_then(move |tester| { + current_thread::spawn(announce_worker); + Ok(tester) + }) + .and_then(|tester| { + // announce 12 blocks + for _ in 0..=12 { + let hash = Hash::random(); + hashes.lock().push(hash); + announce_sender.send(hash); + } + + // we should see an event for each of those announcements + wait_all(tester, &hashes.lock()) + }) + .and_then(|tester| { + // after a period of inactivity we should see the last + // `LATEST_VOTED_BLOCKS_TO_ANNOUNCE` being rebroadcast + wait_all(tester, &hashes.lock()[7..=12]) + }); + + let mut runtime = current_thread::Runtime::new().unwrap(); + runtime.block_on(test).unwrap(); +} -- GitLab From 8426cf1ad15ffad5ae2fd98b7dfb0f19df6b724a Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 12 Sep 2019 18:13:26 +0300 Subject: [PATCH 087/275] Make light client backend only work with locally available data (#3538) * removing fetcher dependency from light backend * fix compilation --- core/client/src/light/backend.rs | 232 ++++---------- core/client/src/light/blockchain.rs | 55 +--- core/client/src/light/call_executor.rs | 408 +++++++++---------------- core/client/src/light/fetcher.rs | 12 +- core/client/src/light/mod.rs | 33 +- core/service/src/builder.rs | 46 +-- core/test-client/src/lib.rs | 1 - core/test-runtime/client/src/lib.rs | 27 +- node-template/src/service.rs | 5 +- node/cli/src/service.rs | 5 +- 10 files changed, 264 insertions(+), 560 deletions(-) diff --git a/core/client/src/light/backend.rs b/core/client/src/light/backend.rs index 6b2f2f5c0a..336e4cba70 100644 --- a/core/client/src/light/backend.rs +++ b/core/client/src/light/backend.rs @@ -18,7 +18,7 @@ //! Everything else is requested from full nodes on demand. use std::collections::HashMap; -use std::sync::{Arc, Weak}; +use std::sync::Arc; use parking_lot::{RwLock, Mutex}; use sr_primitives::{generic::BlockId, Justification, StorageOverlay, ChildrenStorageOverlay}; @@ -32,7 +32,6 @@ use crate::backend::{ use crate::blockchain::HeaderBackend as BlockchainHeaderBackend; use crate::error::{Error as ClientError, Result as ClientResult}; use crate::light::blockchain::{Blockchain, Storage as BlockchainStorage}; -use crate::light::fetcher::{Fetcher, RemoteReadRequest}; use hash_db::Hasher; use trie::MemoryDB; use consensus::well_known_cache_keys; @@ -40,14 +39,14 @@ use consensus::well_known_cache_keys; const IN_MEMORY_EXPECT_PROOF: &str = "InMemory state backend has Void error type and always succeeds; qed"; /// Light client backend. -pub struct Backend { - blockchain: Arc>, +pub struct Backend { + blockchain: Arc>, genesis_state: RwLock>>, import_lock: Mutex<()>, } /// Light block (header and justification) import operation. -pub struct ImportOperation { +pub struct ImportOperation { header: Option, cache: HashMap>, leaf_state: NewBlockState, @@ -55,28 +54,21 @@ pub struct ImportOperation { finalized_blocks: Vec>, set_head: Option>, storage_update: Option>, - _phantom: ::std::marker::PhantomData<(S, F)>, + _phantom: ::std::marker::PhantomData<(S)>, } -/// On-demand state. -pub struct OnDemandState { - fetcher: Weak, - blockchain: Weak>, - block: Block::Hash, - cached_header: RwLock>, -} - -/// On-demand or in-memory genesis state. -pub enum OnDemandOrGenesisState { - /// On-demand state - storage values are fetched from remote nodes. - OnDemand(OnDemandState), +/// Either in-memory genesis state, or locally-unavailable state. +pub enum GenesisOrUnavailableState { /// Genesis state - storage values are stored in-memory. Genesis(InMemoryState), + /// We know that state exists, but all calls will fail with error, because it + /// isn't locally available. + Unavailable, } -impl Backend { +impl Backend { /// Create new light backend. - pub fn new(blockchain: Arc>) -> Self { + pub fn new(blockchain: Arc>) -> Self { Self { blockchain, genesis_state: RwLock::new(None), @@ -85,12 +77,12 @@ impl Backend { } /// Get shared blockchain reference. - pub fn blockchain(&self) -> &Arc> { + pub fn blockchain(&self) -> &Arc> { &self.blockchain } } -impl AuxStore for Backend { +impl AuxStore for Backend { fn insert_aux< 'a, 'b: 'a, @@ -106,16 +98,15 @@ impl AuxStore for Backend { } } -impl ClientBackend for Backend where +impl ClientBackend for Backend where Block: BlockT, S: BlockchainStorage, - F: Fetcher, H: Hasher, H::Out: Ord, { - type BlockImportOperation = ImportOperation; - type Blockchain = Blockchain; - type State = OnDemandOrGenesisState; + type BlockImportOperation = ImportOperation; + type Blockchain = Blockchain; + type State = GenesisOrUnavailableState; type ChangesTrieStorage = in_mem::ChangesTrieStorage; type OffchainStorage = in_mem::OffchainStorage; @@ -183,7 +174,7 @@ impl ClientBackend for Backend where self.blockchain.storage().finalize_header(block) } - fn blockchain(&self) -> &Blockchain { + fn blockchain(&self) -> &Blockchain { &self.blockchain } @@ -205,22 +196,17 @@ impl ClientBackend for Backend where // special case for genesis block if block_number.is_zero() { if let Some(genesis_state) = self.genesis_state.read().clone() { - return Ok(OnDemandOrGenesisState::Genesis(genesis_state)); + return Ok(GenesisOrUnavailableState::Genesis(genesis_state)); } } - // else create on-demand state - let block_hash = self.blockchain.expect_block_hash_from_id(&block)?; - Ok(OnDemandOrGenesisState::OnDemand(OnDemandState { - fetcher: self.blockchain.fetcher(), - blockchain: Arc::downgrade(&self.blockchain), - block: block_hash, - cached_header: RwLock::new(None), - })) + // else return unavailable state. We do not return error here, because error + // would mean that we do not know this state at all. But we know that it exists + Ok(GenesisOrUnavailableState::Unavailable) } fn revert(&self, _n: NumberFor) -> ClientResult> { - Err(ClientError::NotAvailableOnLightClient.into()) + Err(ClientError::NotAvailableOnLightClient) } fn get_import_lock(&self) -> &Mutex<()> { @@ -228,11 +214,10 @@ impl ClientBackend for Backend where } } -impl RemoteBackend for Backend +impl RemoteBackend for Backend where Block: BlockT, S: BlockchainStorage + 'static, - F: Fetcher + 'static, H: Hasher, H::Out: Ord, { @@ -248,15 +233,14 @@ where } } -impl BlockImportOperation for ImportOperation +impl BlockImportOperation for ImportOperation where Block: BlockT, - F: Fetcher, S: BlockchainStorage, H: Hasher, H::Out: Ord, { - type State = OnDemandOrGenesisState; + type State = GenesisOrUnavailableState; fn state(&self) -> ClientResult> { // None means 'locally-stateless' backend @@ -341,99 +325,9 @@ where } } -impl StateBackend for OnDemandState -where - Block: BlockT, - S: BlockchainStorage, - F: Fetcher, - H: Hasher, -{ - type Error = ClientError; - type Transaction = (); - type TrieBackendStorage = MemoryDB; - - fn storage(&self, key: &[u8]) -> ClientResult>> { - let mut header = self.cached_header.read().clone(); - if header.is_none() { - let cached_header = self.blockchain.upgrade() - .ok_or_else(|| ClientError::UnknownBlock(format!("{}", self.block))) - .and_then(|blockchain| blockchain.expect_header(BlockId::Hash(self.block)))?; - header = Some(cached_header.clone()); - *self.cached_header.write() = Some(cached_header); - } - - futures03::executor::block_on( - self.fetcher.upgrade().ok_or(ClientError::NotAvailableOnLightClient)? - .remote_read(RemoteReadRequest { - block: self.block, - header: header.expect("if block above guarantees that header is_some(); qed"), - key: key.to_vec(), - retry_count: None, - }) - ) - } - - fn child_storage(&self, _storage_key: &[u8], _key: &[u8]) -> ClientResult>> { - Err(ClientError::NotAvailableOnLightClient.into()) - } - - fn for_keys_with_prefix(&self, _prefix: &[u8], _action: A) { - // whole state is not available on light node - } - - fn for_key_values_with_prefix(&self, _prefix: &[u8], _action: A) { - // whole state is not available on light node - } - - fn for_keys_in_child_storage(&self, _storage_key: &[u8], _action: A) { - // whole state is not available on light node - } - - fn for_child_keys_with_prefix( - &self, - _storage_key: &[u8], - _prefix: &[u8], - _action: A, - ) { - // whole state is not available on light node - } - - fn storage_root(&self, _delta: I) -> (H::Out, Self::Transaction) - where - I: IntoIterator, Option>)> - { - (H::Out::default(), ()) - } - - fn child_storage_root(&self, _key: &[u8], _delta: I) -> (Vec, bool, Self::Transaction) +impl StateBackend for GenesisOrUnavailableState where - I: IntoIterator, Option>)> - { - (H::Out::default().as_ref().to_vec(), true, ()) - } - - fn pairs(&self) -> Vec<(Vec, Vec)> { - // whole state is not available on light node - Vec::new() - } - - fn keys(&self, _prefix: &[u8]) -> Vec> { - // whole state is not available on light node - Vec::new() - } - - fn as_trie_backend(&mut self) -> Option<&TrieBackend> { - None - } -} - -impl StateBackend for OnDemandOrGenesisState -where - Block: BlockT, - F: Fetcher, - S: BlockchainStorage, - H: Hasher, - H::Out: Ord, + H::Out: Ord, { type Error = ClientError; type Transaction = (); @@ -441,44 +335,39 @@ where fn storage(&self, key: &[u8]) -> ClientResult>> { match *self { - OnDemandOrGenesisState::OnDemand(ref state) => - StateBackend::::storage(state, key), - OnDemandOrGenesisState::Genesis(ref state) => + GenesisOrUnavailableState::Genesis(ref state) => Ok(state.storage(key).expect(IN_MEMORY_EXPECT_PROOF)), + GenesisOrUnavailableState::Unavailable => Err(ClientError::NotAvailableOnLightClient), } } fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> ClientResult>> { match *self { - OnDemandOrGenesisState::OnDemand(ref state) => - StateBackend::::child_storage(state, storage_key, key), - OnDemandOrGenesisState::Genesis(ref state) => + GenesisOrUnavailableState::Genesis(ref state) => Ok(state.child_storage(storage_key, key).expect(IN_MEMORY_EXPECT_PROOF)), + GenesisOrUnavailableState::Unavailable => Err(ClientError::NotAvailableOnLightClient), } } fn for_keys_with_prefix(&self, prefix: &[u8], action: A) { match *self { - OnDemandOrGenesisState::OnDemand(ref state) => - StateBackend::::for_keys_with_prefix(state, prefix, action), - OnDemandOrGenesisState::Genesis(ref state) => state.for_keys_with_prefix(prefix, action), + GenesisOrUnavailableState::Genesis(ref state) => state.for_keys_with_prefix(prefix, action), + GenesisOrUnavailableState::Unavailable => (), } } fn for_key_values_with_prefix(&self, prefix: &[u8], action: A) { match *self { - OnDemandOrGenesisState::OnDemand(ref state) => - StateBackend::::for_key_values_with_prefix(state, prefix, action), - OnDemandOrGenesisState::Genesis(ref state) => state.for_key_values_with_prefix(prefix, action), + GenesisOrUnavailableState::Genesis(ref state) => state.for_key_values_with_prefix(prefix, action), + GenesisOrUnavailableState::Unavailable => (), } } fn for_keys_in_child_storage(&self, storage_key: &[u8], action: A) { match *self { - OnDemandOrGenesisState::OnDemand(ref state) => - StateBackend::::for_keys_in_child_storage(state, storage_key, action), - OnDemandOrGenesisState::Genesis(ref state) => state.for_keys_in_child_storage(storage_key, action), + GenesisOrUnavailableState::Genesis(ref state) => state.for_keys_in_child_storage(storage_key, action), + GenesisOrUnavailableState::Unavailable => (), } } @@ -489,10 +378,9 @@ where action: A, ) { match *self { - OnDemandOrGenesisState::OnDemand(ref state) => - StateBackend::::for_child_keys_with_prefix(state, storage_key, prefix, action), - OnDemandOrGenesisState::Genesis(ref state) => + GenesisOrUnavailableState::Genesis(ref state) => state.for_child_keys_with_prefix(storage_key, prefix, action), + GenesisOrUnavailableState::Unavailable => (), } } @@ -501,12 +389,9 @@ where I: IntoIterator, Option>)> { match *self { - OnDemandOrGenesisState::OnDemand(ref state) => - StateBackend::::storage_root(state, delta), - OnDemandOrGenesisState::Genesis(ref state) => { - let (root, _) = state.storage_root(delta); - (root, ()) - }, + GenesisOrUnavailableState::Genesis(ref state) => + (state.storage_root(delta).0, ()), + GenesisOrUnavailableState::Unavailable => (H::Out::default(), ()), } } @@ -515,35 +400,32 @@ where I: IntoIterator, Option>)> { match *self { - OnDemandOrGenesisState::OnDemand(ref state) => - StateBackend::::child_storage_root(state, key, delta), - OnDemandOrGenesisState::Genesis(ref state) => { + GenesisOrUnavailableState::Genesis(ref state) => { let (root, is_equal, _) = state.child_storage_root(key, delta); (root, is_equal, ()) }, + GenesisOrUnavailableState::Unavailable => (H::Out::default().as_ref().to_vec(), true, ()), } } fn pairs(&self) -> Vec<(Vec, Vec)> { match *self { - OnDemandOrGenesisState::OnDemand(ref state) => - StateBackend::::pairs(state), - OnDemandOrGenesisState::Genesis(ref state) => state.pairs(), + GenesisOrUnavailableState::Genesis(ref state) => state.pairs(), + GenesisOrUnavailableState::Unavailable => Vec::new(), } } fn keys(&self, prefix: &[u8]) -> Vec> { match *self { - OnDemandOrGenesisState::OnDemand(ref state) => - StateBackend::::keys(state, prefix), - OnDemandOrGenesisState::Genesis(ref state) => state.keys(prefix), + GenesisOrUnavailableState::Genesis(ref state) => state.keys(prefix), + GenesisOrUnavailableState::Unavailable => Vec::new(), } } fn as_trie_backend(&mut self) -> Option<&TrieBackend> { match self { - OnDemandOrGenesisState::OnDemand(ref mut state) => state.as_trie_backend(), - OnDemandOrGenesisState::Genesis(ref mut state) => state.as_trie_backend(), + GenesisOrUnavailableState::Genesis(ref mut state) => state.as_trie_backend(), + GenesisOrUnavailableState::Unavailable => None, } } } @@ -561,24 +443,24 @@ mod tests { let def = Default::default(); let header0 = test_client::runtime::Header::new(0, def, def, def, Default::default()); - let backend: Backend<_, _, Blake2Hasher> = Backend::new(Arc::new(DummyBlockchain::new(DummyStorage::new()))); + let backend: Backend<_, Blake2Hasher> = Backend::new(Arc::new(DummyBlockchain::new(DummyStorage::new()))); let mut op = backend.begin_operation().unwrap(); op.set_block_data(header0, None, None, NewBlockState::Final).unwrap(); op.reset_storage(Default::default(), Default::default()).unwrap(); backend.commit_operation(op).unwrap(); match backend.state_at(BlockId::Number(0)).unwrap() { - OnDemandOrGenesisState::Genesis(_) => (), + GenesisOrUnavailableState::Genesis(_) => (), _ => panic!("unexpected state"), } } #[test] - fn remote_state_is_created_when_genesis_state_is_inavailable() { - let backend: Backend<_, _, Blake2Hasher> = Backend::new(Arc::new(DummyBlockchain::new(DummyStorage::new()))); + fn unavailable_state_is_created_when_genesis_state_is_unavailable() { + let backend: Backend<_, Blake2Hasher> = Backend::new(Arc::new(DummyBlockchain::new(DummyStorage::new()))); match backend.state_at(BlockId::Number(0)).unwrap() { - OnDemandOrGenesisState::OnDemand(_) => (), + GenesisOrUnavailableState::Unavailable => (), _ => panic!("unexpected state"), } } diff --git a/core/client/src/light/blockchain.rs b/core/client/src/light/blockchain.rs index 726d2abdc6..1e1a7669a0 100644 --- a/core/client/src/light/blockchain.rs +++ b/core/client/src/light/blockchain.rs @@ -18,8 +18,7 @@ //! blocks. CHT roots are stored for headers of ancient blocks. use std::future::Future; -use std::{sync::{Weak, Arc}, collections::HashMap}; -use parking_lot::Mutex; +use std::{sync::Arc, collections::HashMap}; use sr_primitives::{Justification, generic::BlockId}; use sr_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero}; @@ -30,7 +29,7 @@ use crate::blockchain::{Backend as BlockchainBackend, BlockStatus, Cache as Bloc HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo, ProvideCache}; use crate::cht; use crate::error::{Error as ClientError, Result as ClientResult}; -use crate::light::fetcher::{Fetcher, RemoteBodyRequest, RemoteHeaderRequest}; +use crate::light::fetcher::{Fetcher, RemoteHeaderRequest}; /// Light client blockchain storage. pub trait Storage: AuxStore + BlockchainHeaderBackend { @@ -95,37 +94,25 @@ pub trait RemoteBlockchain: Send + Sync { } /// Light client blockchain. -pub struct Blockchain { - fetcher: Mutex>, +pub struct Blockchain { storage: S, } -impl Blockchain { +impl Blockchain { /// Create new light blockchain backed with given storage. pub fn new(storage: S) -> Self { Self { - fetcher: Mutex::new(Default::default()), storage, } } - /// Sets fetcher reference. - pub fn set_fetcher(&self, fetcher: Weak) { - *self.fetcher.lock() = fetcher; - } - - /// Get fetcher weak reference. - pub fn fetcher(&self) -> Weak { - self.fetcher.lock().clone() - } - /// Get storage reference. pub fn storage(&self) -> &S { &self.storage } } -impl BlockchainHeaderBackend for Blockchain where Block: BlockT, S: Storage, F: Fetcher { +impl BlockchainHeaderBackend for Blockchain where Block: BlockT, S: Storage { fn header(&self, id: BlockId) -> ClientResult> { match RemoteBlockchain::header(self, id)? { LocalOrRemote::Local(header) => Ok(Some(header)), @@ -151,24 +138,13 @@ impl BlockchainHeaderBackend for Blockchain where Bloc } } -impl BlockchainBackend for Blockchain where Block: BlockT, S: Storage, F: Fetcher { - fn body(&self, id: BlockId) -> ClientResult>> { - let header = match BlockchainHeaderBackend::header(self, id)? { - Some(header) => header, - None => return Ok(None), - }; - - futures03::executor::block_on( - self.fetcher().upgrade().ok_or(ClientError::NotAvailableOnLightClient)? - .remote_body(RemoteBodyRequest { - header, - retry_count: None, - }) - ).map(Some) +impl BlockchainBackend for Blockchain where Block: BlockT, S: Storage { + fn body(&self, _id: BlockId) -> ClientResult>> { + Err(ClientError::NotAvailableOnLightClient) } fn justification(&self, _id: BlockId) -> ClientResult> { - Ok(None) + Err(ClientError::NotAvailableOnLightClient) } fn last_finalized(&self) -> ClientResult { @@ -180,24 +156,23 @@ impl BlockchainBackend for Blockchain where Block: Blo } fn leaves(&self) -> ClientResult> { - unimplemented!() + Err(ClientError::NotAvailableOnLightClient) } fn children(&self, _parent_hash: Block::Hash) -> ClientResult> { - unimplemented!() + Err(ClientError::NotAvailableOnLightClient) } } -impl, F, Block: BlockT> ProvideCache for Blockchain { +impl, Block: BlockT> ProvideCache for Blockchain { fn cache(&self) -> Option>> { self.storage.cache() } } -impl RemoteBlockchain for Blockchain +impl RemoteBlockchain for Blockchain where S: Storage, - F: Fetcher + Send + Sync, { fn header(&self, id: BlockId) -> ClientResult>( #[cfg(test)] pub mod tests { use std::collections::HashMap; + use parking_lot::Mutex; use test_client::runtime::{Hash, Block, Header}; use crate::blockchain::Info; - use crate::light::fetcher::tests::OkCallFetcher; use super::*; - pub type DummyBlockchain = Blockchain; + pub type DummyBlockchain = Blockchain; pub struct DummyStorage { pub changes_tries_cht_roots: HashMap, diff --git a/core/client/src/light/call_executor.rs b/core/client/src/light/call_executor.rs index ab7b5b0a10..a06b48a641 100644 --- a/core/client/src/light/call_executor.rs +++ b/core/client/src/light/call_executor.rs @@ -14,17 +14,16 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Light client call executor. Executes methods on remote full nodes, fetching -//! execution proof and checking it locally. +//! Methods that light client could use to execute runtime calls. use std::{ collections::HashSet, sync::Arc, panic::UnwindSafe, result, - marker::PhantomData, cell::RefCell, rc::Rc, + cell::RefCell, rc::Rc, }; use codec::{Encode, Decode}; use primitives::{ - offchain::{self, NeverOffchainExt}, H256, Blake2Hasher, convert_hash, NativeOrEncoded, + offchain, H256, Blake2Hasher, convert_hash, NativeOrEncoded, traits::CodeExecutor, }; use sr_primitives::generic::BlockId; @@ -37,211 +36,40 @@ use hash_db::Hasher; use crate::runtime_api::{ProofRecorder, InitializeBlock}; use crate::backend::RemoteBackend; -use crate::blockchain::Backend as ChainBackend; use crate::call_executor::CallExecutor; use crate::error::{Error as ClientError, Result as ClientResult}; -use crate::light::fetcher::{Fetcher, RemoteCallRequest}; +use crate::light::fetcher::RemoteCallRequest; use executor::{RuntimeVersion, NativeVersion}; -/// Call executor that executes methods on remote node, querying execution proof -/// and checking proof by re-executing locally. -pub struct RemoteCallExecutor { - blockchain: Arc, - fetcher: Arc, -} - -/// Remote or local call executor. +/// Call executor that is able to execute calls only on genesis state. /// -/// Calls are executed locally if state is available locally. Otherwise, calls -/// are redirected to remote call executor. -pub struct RemoteOrLocalCallExecutor, B, R, L> { +/// Trying to execute call on non-genesis state leads to error. +pub struct GenesisCallExecutor { backend: Arc, - remote: R, local: L, - _block: PhantomData, } -impl Clone for RemoteCallExecutor { - fn clone(&self) -> Self { - RemoteCallExecutor { - blockchain: self.blockchain.clone(), - fetcher: self.fetcher.clone(), - } - } -} - -impl RemoteCallExecutor { - /// Creates new instance of remote call executor. - pub fn new(blockchain: Arc, fetcher: Arc) -> Self { - RemoteCallExecutor { blockchain, fetcher } - } -} - -impl CallExecutor for RemoteCallExecutor -where - Block: BlockT, - B: ChainBackend, - F: Fetcher, - Block::Hash: Ord, -{ - type Error = ClientError; - - fn call< - O: offchain::Externalities, - >( - &self, - id: &BlockId, - method: &str, - call_data: &[u8], - _strategy: ExecutionStrategy, - _side_effects_handler: Option<&mut O>, - ) -> ClientResult> - { - let block_hash = self.blockchain.expect_block_hash_from_id(id)?; - let block_header = self.blockchain.expect_header(id.clone())?; - - futures03::executor::block_on(self.fetcher.remote_call(RemoteCallRequest { - block: block_hash, - header: block_header, - method: method.into(), - call_data: call_data.to_vec(), - retry_count: None, - })) - } - - fn contextual_call< - 'a, - O: offchain::Externalities, - IB: Fn() -> ClientResult<()>, - EM: Fn( - Result, Self::Error>, - Result, Self::Error> - ) -> Result, Self::Error>, - R: Encode + Decode + PartialEq, - NC, - >( - &self, - _initialize_block_fn: IB, - at: &BlockId, - method: &str, - call_data: &[u8], - changes: &RefCell, - initialize_block: InitializeBlock<'a, Block>, - execution_manager: ExecutionManager, - _native_call: Option, - side_effects_handler: Option<&mut O>, - _recorder: &Option>>>, - _enable_keystore: bool, - ) -> ClientResult> where ExecutionManager: Clone { - let block_initialized = match initialize_block { - InitializeBlock::Do(ref init_block) => { - init_block.borrow().is_some() - }, - InitializeBlock::Skip => false, - }; - - // it is only possible to execute contextual call if changes are empty - if !changes.borrow().is_empty() || block_initialized { - return Err(ClientError::NotAvailableOnLightClient.into()); - } - - self.call( - at, - method, - call_data, - (&execution_manager).into(), - side_effects_handler, - ).map(NativeOrEncoded::Encoded) - } - - fn runtime_version(&self, id: &BlockId) -> ClientResult { - let call_result = self.call( - id, - "Core_version", - &[], - ExecutionStrategy::NativeElseWasm, - NeverOffchainExt::new() - )?; - RuntimeVersion::decode(&mut call_result.as_slice()) - .map_err(|_| ClientError::VersionInvalid.into()) - } - - fn call_at_state< - O: offchain::Externalities, - S: StateBackend, - FF: FnOnce( - Result, Self::Error>, - Result, Self::Error> - ) -> Result, Self::Error>, - R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result, - >(&self, - _state: &S, - _changes: &mut OverlayedChanges, - _method: &str, - _call_data: &[u8], - _m: ExecutionManager, - _native_call: Option, - _side_effects_handler: Option<&mut O>, - ) -> ClientResult<( - NativeOrEncoded, - (S::Transaction, ::Out), - Option>>, - )> { - Err(ClientError::NotAvailableOnLightClient.into()) - } - - fn prove_at_trie_state>( - &self, - _state: &state_machine::TrieBackend, - _changes: &mut OverlayedChanges, - _method: &str, - _call_data: &[u8] - ) -> ClientResult<(Vec, Vec>)> { - Err(ClientError::NotAvailableOnLightClient.into()) - } - - fn native_runtime_version(&self) -> Option<&NativeVersion> { - None +impl GenesisCallExecutor { + /// Create new genesis call executor. + pub fn new(backend: Arc, local: L) -> Self { + Self { backend, local } } } -impl Clone for RemoteOrLocalCallExecutor - where - Block: BlockT, - B: RemoteBackend, - R: CallExecutor + Clone, - L: CallExecutor + Clone, -{ +impl Clone for GenesisCallExecutor { fn clone(&self) -> Self { - RemoteOrLocalCallExecutor { + GenesisCallExecutor { backend: self.backend.clone(), - remote: self.remote.clone(), local: self.local.clone(), - _block: Default::default(), } } } -impl RemoteOrLocalCallExecutor +impl CallExecutor for + GenesisCallExecutor where Block: BlockT, B: RemoteBackend, - Remote: CallExecutor, - Local: CallExecutor, -{ - /// Creates new instance of remote/local call executor. - pub fn new(backend: Arc, remote: Remote, local: Local) -> Self { - RemoteOrLocalCallExecutor { backend, remote, local, _block: Default::default(), } - } -} - -impl CallExecutor for - RemoteOrLocalCallExecutor - where - Block: BlockT, - B: RemoteBackend, - Remote: CallExecutor, Local: CallExecutor, { type Error = ClientError; @@ -258,7 +86,7 @@ impl CallExecutor for ) -> ClientResult> { match self.backend.is_local_state_available(id) { true => self.local.call(id, method, call_data, strategy, side_effects_handler), - false => self.remote.call(id, method, call_data, strategy, side_effects_handler), + false => Err(ClientError::NotAvailableOnLightClient), } } @@ -313,36 +141,14 @@ impl CallExecutor for recorder, enable_keystore, ).map_err(|e| ClientError::Execution(Box::new(e.to_string()))), - false => CallExecutor::contextual_call::< - _, - _, - fn( - Result, Remote::Error>, - Result, Remote::Error>, - ) -> Result, Remote::Error>, - _, - NC - >( - &self.remote, - initialize_block_fn, - at, - method, - call_data, - changes, - initialize_block, - ExecutionManager::NativeWhenPossible, - native_call, - side_effects_handler, - recorder, - enable_keystore, - ).map_err(|e| ClientError::Execution(Box::new(e.to_string()))), + false => Err(ClientError::NotAvailableOnLightClient), } } fn runtime_version(&self, id: &BlockId) -> ClientResult { match self.backend.is_local_state_available(id) { true => self.local.runtime_version(id), - false => self.remote.runtime_version(id), + false => Err(ClientError::NotAvailableOnLightClient), } } @@ -356,50 +162,29 @@ impl CallExecutor for R: Encode + Decode + PartialEq, NC: FnOnce() -> result::Result + UnwindSafe, >(&self, - state: &S, - changes: &mut OverlayedChanges, - method: &str, - call_data: &[u8], + _state: &S, + _changes: &mut OverlayedChanges, + _method: &str, + _call_data: &[u8], _manager: ExecutionManager, - native_call: Option, - side_effects_handler: Option<&mut O>, + _native_call: Option, + _side_effects_handler: Option<&mut O>, ) -> ClientResult<( NativeOrEncoded, (S::Transaction, ::Out), Option>>, )> { - // there's no actual way/need to specify native/wasm execution strategy on light node - // => we can safely ignore passed values - - CallExecutor::call_at_state::< - _, - _, - fn( - Result, Remote::Error>, - Result, Remote::Error>, - ) -> Result, Remote::Error>, - _, - NC - >( - &self.remote, - state, - changes, - method, - call_data, - ExecutionManager::NativeWhenPossible, - native_call, - side_effects_handler, - ).map_err(|e| ClientError::Execution(Box::new(e.to_string()))) + Err(ClientError::NotAvailableOnLightClient) } fn prove_at_trie_state>( &self, - state: &state_machine::TrieBackend, - changes: &mut OverlayedChanges, - method: &str, - call_data: &[u8] + _state: &state_machine::TrieBackend, + _changes: &mut OverlayedChanges, + _method: &str, + _call_data: &[u8] ) -> ClientResult<(Vec, Vec>)> { - self.remote.prove_at_trie_state(state, changes, method, call_data) + Err(ClientError::NotAvailableOnLightClient) } fn native_runtime_version(&self) -> Option<&NativeVersion> { @@ -517,13 +302,103 @@ fn check_execution_proof_with_make_header for DummyCallExecutor { + type Error = ClientError; + + fn call( + &self, + _id: &BlockId, + _method: &str, + _call_data: &[u8], + _strategy: ExecutionStrategy, + _side_effects_handler: Option<&mut O>, + ) -> Result, ClientError> { + Ok(vec![42]) + } + + fn contextual_call< + 'a, + O: offchain::Externalities, + IB: Fn() -> ClientResult<()>, + EM: Fn( + Result, Self::Error>, + Result, Self::Error> + ) -> Result, Self::Error>, + R: Encode + Decode + PartialEq, + NC: FnOnce() -> result::Result + UnwindSafe, + >( + &self, + _initialize_block_fn: IB, + _at: &BlockId, + _method: &str, + _call_data: &[u8], + _changes: &RefCell, + _initialize_block: InitializeBlock<'a, Block>, + _execution_manager: ExecutionManager, + _native_call: Option, + _side_effects_handler: Option<&mut O>, + _proof_recorder: &Option>>>, + _enable_keystore: bool, + ) -> ClientResult> where ExecutionManager: Clone { + unreachable!() + } + + fn runtime_version(&self, _id: &BlockId) -> Result { + unreachable!() + } + + fn call_at_state< + O: offchain::Externalities, + S: state_machine::Backend, + F: FnOnce( + Result, Self::Error>, + Result, Self::Error> + ) -> Result, Self::Error>, + R: Encode + Decode + PartialEq, + NC: FnOnce() -> result::Result + UnwindSafe, + >(&self, + _state: &S, + _overlay: &mut OverlayedChanges, + _method: &str, + _call_data: &[u8], + _manager: ExecutionManager, + _native_call: Option, + _side_effects_handler: Option<&mut O>, + ) -> Result< + ( + NativeOrEncoded, + (S::Transaction, H256), + Option>>, + ), + ClientError, + > { + unreachable!() + } + + fn prove_at_trie_state>( + &self, + _trie_state: &state_machine::TrieBackend, + _overlay: &mut OverlayedChanges, + _method: &str, + _call_data: &[u8] + ) -> Result<(Vec, Vec>), ClientError> { + unreachable!() + } + + fn native_runtime_version(&self) -> Option<&NativeVersion> { + unreachable!() + } + } + #[test] fn execution_proof_is_generated_and_checked() { fn execute(remote_client: &TestClient, at: u64, method: &'static str) -> (Vec, Vec) { @@ -624,8 +499,8 @@ mod tests { } #[test] - fn code_is_executed_locally_or_remotely() { - let backend = Arc::new(InMemBackend::new()); + fn code_is_executed_at_genesis_only() { + let backend = Arc::new(InMemBackend::::new()); let def = H256::default(); let header0 = test_client::runtime::Header::new(0, def, def, def, Default::default()); let hash0 = header0.hash(); @@ -634,34 +509,29 @@ mod tests { backend.blockchain().insert(hash0, header0, None, None, NewBlockState::Final).unwrap(); backend.blockchain().insert(hash1, header1, None, None, NewBlockState::Final).unwrap(); - let local_executor = RemoteCallExecutor::new( - Arc::new(backend.blockchain().clone()), - Arc::new(OkCallFetcher::new(vec![1])), - ); - let remote_executor = RemoteCallExecutor::new( - Arc::new(backend.blockchain().clone()), - Arc::new(OkCallFetcher::new(vec![2])), - ); - let remote_or_local = RemoteOrLocalCallExecutor::new(backend, remote_executor, local_executor); + let genesis_executor = GenesisCallExecutor::new(backend, DummyCallExecutor); assert_eq!( - remote_or_local.call( + genesis_executor.call( &BlockId::Number(0), "test_method", &[], ExecutionStrategy::NativeElseWasm, NeverOffchainExt::new(), ).unwrap(), - vec![1], + vec![42], ); - assert_eq!( - remote_or_local.call( - &BlockId::Number(1), - "test_method", - &[], - ExecutionStrategy::NativeElseWasm, - NeverOffchainExt::new(), - ).unwrap(), - vec![2], + + let call_on_unavailable = genesis_executor.call( + &BlockId::Number(1), + "test_method", + &[], + ExecutionStrategy::NativeElseWasm, + NeverOffchainExt::new(), ); + + match call_on_unavailable { + Err(ClientError::NotAvailableOnLightClient) => (), + _ => unreachable!("unexpected result: {:?}", call_on_unavailable), + } } } diff --git a/core/client/src/light/fetcher.rs b/core/client/src/light/fetcher.rs index 6ac637f3fa..c25092c32c 100644 --- a/core/client/src/light/fetcher.rs +++ b/core/client/src/light/fetcher.rs @@ -221,15 +221,15 @@ pub trait FetchChecker: Send + Sync { } /// Remote data checker. -pub struct LightDataChecker, F> { - blockchain: Arc>, +pub struct LightDataChecker> { + blockchain: Arc>, executor: E, _hasher: PhantomData<(B, H)>, } -impl, F> LightDataChecker { +impl> LightDataChecker { /// Create new light data checker. - pub fn new(blockchain: Arc>, executor: E) -> Self { + pub fn new(blockchain: Arc>, executor: E) -> Self { Self { blockchain, executor, _hasher: PhantomData } @@ -367,14 +367,13 @@ impl, F> LightDataChecker FetchChecker for LightDataChecker +impl FetchChecker for LightDataChecker where Block: BlockT, E: CodeExecutor, H: Hasher, H::Out: Ord + 'static, S: BlockchainStorage, - F: Send + Sync, { fn check_header_proof( &self, @@ -563,7 +562,6 @@ pub mod tests { Blake2Hasher, Block, DummyStorage, - OkCallFetcher, >; fn prepare_for_read_proof_check() -> (TestChecker, Header, Vec>, u32) { diff --git a/core/client/src/light/mod.rs b/core/client/src/light/mod.rs index 08e14ad8f3..03b7dcff85 100644 --- a/core/client/src/light/mod.rs +++ b/core/client/src/light/mod.rs @@ -33,55 +33,48 @@ use crate::client::Client; use crate::error::Result as ClientResult; use crate::light::backend::Backend; use crate::light::blockchain::{Blockchain, Storage as BlockchainStorage}; -use crate::light::call_executor::{RemoteCallExecutor, RemoteOrLocalCallExecutor}; -use crate::light::fetcher::{Fetcher, LightDataChecker}; +use crate::light::call_executor::GenesisCallExecutor; +use crate::light::fetcher::LightDataChecker; /// Create an instance of light client blockchain backend. -pub fn new_light_blockchain, F>(storage: S) -> Arc> { +pub fn new_light_blockchain>(storage: S) -> Arc> { Arc::new(Blockchain::new(storage)) } /// Create an instance of light client backend. -pub fn new_light_backend(blockchain: Arc>, fetcher: Arc) -> Arc> +pub fn new_light_backend(blockchain: Arc>) -> Arc> where B: BlockT, S: BlockchainStorage, - F: Fetcher, { - blockchain.set_fetcher(Arc::downgrade(&fetcher)); Arc::new(Backend::new(blockchain)) } /// Create an instance of light client. -pub fn new_light( - backend: Arc>, - fetcher: Arc, +pub fn new_light( + backend: Arc>, genesis_storage: GS, code_executor: E, -) -> ClientResult, RemoteOrLocalCallExecutor< - B, - Backend, - RemoteCallExecutor, F>, - LocalCallExecutor, E> +) -> ClientResult, GenesisCallExecutor< + Backend, + LocalCallExecutor, E> >, B, RA>> where B: BlockT, S: BlockchainStorage + 'static, - F: Fetcher + 'static, GS: BuildStorage, E: CodeExecutor + RuntimeInfo, { - let remote_executor = RemoteCallExecutor::new(backend.blockchain().clone(), fetcher); let local_executor = LocalCallExecutor::new(backend.clone(), code_executor, None); - let executor = RemoteOrLocalCallExecutor::new(backend.clone(), remote_executor, local_executor); + let executor = GenesisCallExecutor::new(backend.clone(), local_executor); Client::new(backend, executor, genesis_storage, Default::default()) } /// Create an instance of fetch data checker. -pub fn new_fetch_checker, F>( - blockchain: Arc>, +pub fn new_fetch_checker>( + blockchain: Arc>, executor: E, -) -> LightDataChecker +) -> LightDataChecker where E: CodeExecutor, { diff --git a/core/service/src/builder.rs b/core/service/src/builder.rs index 1540eeac9c..458c72a74f 100644 --- a/core/service/src/builder.rs +++ b/core/service/src/builder.rs @@ -108,29 +108,18 @@ type TLightClient = Client< /// Light client backend type. type TLightBackend = client::light::backend::Backend< client_db::light::LightStorage, - network::OnDemand, Blake2Hasher, >; /// Light call executor type. -type TLightCallExecutor = client::light::call_executor::RemoteOrLocalCallExecutor< - TBl, +type TLightCallExecutor = client::light::call_executor::GenesisCallExecutor< client::light::backend::Backend< client_db::light::LightStorage, - network::OnDemand, Blake2Hasher >, - client::light::call_executor::RemoteCallExecutor< - client::light::blockchain::Blockchain< - client_db::light::LightStorage, - network::OnDemand - >, - network::OnDemand, - >, client::LocalCallExecutor< client::light::backend::Backend< client_db::light::LightStorage, - network::OnDemand, Blake2Hasher >, NativeExecutor @@ -240,11 +229,10 @@ where TGen: Serialize + DeserializeOwned + BuildStorage { let light_blockchain = client::light::new_light_blockchain(db_storage); let fetch_checker = Arc::new(client::light::new_fetch_checker(light_blockchain.clone(), executor.clone())); let fetcher = Arc::new(network::OnDemand::new(fetch_checker)); - let backend = client::light::new_light_backend(light_blockchain, fetcher.clone()); + let backend = client::light::new_light_backend(light_blockchain); let remote_blockchain = backend.remote_blockchain(); let client = Arc::new(client::light::new_light( backend.clone(), - fetcher.clone(), &config.chain_spec, executor, )?); @@ -459,15 +447,22 @@ impl( self, - builder: impl FnOnce(&Configuration, Arc, Arc, Option, Arc) - -> Result<(UImpQu, Option), Error> + builder: impl FnOnce( + &Configuration, + Arc, + Arc, + Option, + Option, + Arc, + ) -> Result<(UImpQu, Option), Error> ) -> Result, Error> - where TSc: Clone { + where TSc: Clone, TFchr: Clone { let (import_queue, fprb) = builder( &self.config, self.client.clone(), self.backend.clone(), + self.fetcher.clone(), self.select_chain.clone(), self.transaction_pool.clone() )?; @@ -494,12 +489,21 @@ impl( self, - builder: impl FnOnce(&Configuration, Arc, Arc, Option, Arc) - -> Result<(UImpQu, UFprb), Error> + builder: impl FnOnce( + &Configuration, + Arc, + Arc, + Option, + Option, + Arc, + ) -> Result<(UImpQu, UFprb), Error> ) -> Result, Error> - where TSc: Clone { - self.with_import_queue_and_opt_fprb(|cfg, cl, b, sc, tx| builder(cfg, cl, b, sc, tx).map(|(q, f)| (q, Some(f)))) + where TSc: Clone, TFchr: Clone { + self.with_import_queue_and_opt_fprb(|cfg, cl, b, f, sc, tx| + builder(cfg, cl, b, f, sc, tx) + .map(|(q, f)| (q, Some(f))) + ) } /// Defines which transaction pool to use. diff --git a/core/test-client/src/lib.rs b/core/test-client/src/lib.rs index 17e2670846..3ae999f1f1 100644 --- a/core/test-client/src/lib.rs +++ b/core/test-client/src/lib.rs @@ -47,7 +47,6 @@ use client::LocalCallExecutor; /// Test client light database backend. pub type LightBackend = client::light::backend::Backend< client_db::light::LightStorage, - LightFetcher, Blake2Hasher, >; diff --git a/core/test-runtime/client/src/lib.rs b/core/test-runtime/client/src/lib.rs index aeed1e7ad4..229fcbdaf9 100644 --- a/core/test-runtime/client/src/lib.rs +++ b/core/test-runtime/client/src/lib.rs @@ -73,20 +73,11 @@ pub type Executor = client::LocalCallExecutor< pub type LightBackend = generic_test_client::LightBackend; /// Test client light executor. -pub type LightExecutor = client::light::call_executor::RemoteOrLocalCallExecutor< - runtime::Block, +pub type LightExecutor = client::light::call_executor::GenesisCallExecutor< LightBackend, - client::light::call_executor::RemoteCallExecutor< - client::light::blockchain::Blockchain< - client_db::light::LightStorage, - LightFetcher - >, - LightFetcher - >, client::LocalCallExecutor< client::light::backend::Backend< client_db::light::LightStorage, - LightFetcher, Blake2Hasher >, NativeExecutor @@ -271,22 +262,16 @@ pub fn new_light() -> ( let blockchain = Arc::new(client::light::blockchain::Blockchain::new(storage)); let backend = Arc::new(LightBackend::new(blockchain.clone())); let executor = NativeExecutor::new(None); - let fetcher = Arc::new(LightFetcher); - let remote_call_executor = client::light::call_executor::RemoteCallExecutor::new( - blockchain.clone(), - fetcher, - ); let local_call_executor = client::LocalCallExecutor::new(backend.clone(), executor, None); let call_executor = LightExecutor::new( backend.clone(), - remote_call_executor, local_call_executor, ); - (TestClientBuilder::with_backend(backend.clone()) - .build_with_executor(call_executor) - .0, - backend, + ( + TestClientBuilder::with_backend(backend.clone()) + .build_with_executor(call_executor) + .0, + backend, ) - } diff --git a/node-template/src/service.rs b/node-template/src/service.rs index 310b8f44a7..f4ab3f4000 100644 --- a/node-template/src/service.rs +++ b/node-template/src/service.rs @@ -197,9 +197,8 @@ pub fn new_light(config: Configuration( diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index ca6b249484..f3ce9baa2e 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -237,9 +237,8 @@ pub fn new_light(config: Configuration( -- GitLab From 9ffe3b0f875efd54d8ed82ef97d9f573cfeb83db Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Thu, 12 Sep 2019 17:52:26 +0200 Subject: [PATCH 088/275] Print version when panic (#3608) * Print version when panic * Fix tests. --- core/cli/src/lib.rs | 6 +++--- core/client/src/light/call_executor.rs | 2 +- core/panic-handler/src/lib.rs | 17 ++++++++++++----- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/core/cli/src/lib.rs b/core/cli/src/lib.rs index 6e9955ca1a..1fa4cabd63 100644 --- a/core/cli/src/lib.rs +++ b/core/cli/src/lib.rs @@ -77,7 +77,7 @@ const NODE_KEY_ED25519_FILE: &str = "secret_ed25519"; /// Executable version. Used to pass version information from the root crate. pub struct VersionInfo { - /// Implemtation name. + /// Implementaiton name. pub name: &'static str, /// Implementation version. pub version: &'static str, @@ -191,13 +191,13 @@ where I: IntoIterator, ::Item: Into + Clone, { - panic_handler::set(version.support_url); - let full_version = service::config::full_version_from_strs( version.version, version.commit ); + panic_handler::set(version.support_url, &full_version); + let matches = CoreParams::::clap() .name(version.executable_name) .author(version.author) diff --git a/core/client/src/light/call_executor.rs b/core/client/src/light/call_executor.rs index a06b48a641..2c9c1f2995 100644 --- a/core/client/src/light/call_executor.rs +++ b/core/client/src/light/call_executor.rs @@ -494,7 +494,7 @@ mod tests { execute_with_proof_failure(&remote_client, 2, "Core_version"); // check that proof check doesn't panic even if proof is incorrect AND panic handler is set - panic_handler::set("TEST"); + panic_handler::set("TEST", "1.2.3"); execute_with_proof_failure(&remote_client, 2, "Core_version"); } diff --git a/core/panic-handler/src/lib.rs b/core/panic-handler/src/lib.rs index 2c04700e96..1df05120c1 100644 --- a/core/panic-handler/src/lib.rs +++ b/core/panic-handler/src/lib.rs @@ -51,8 +51,13 @@ enum OnPanic { /// /// The `bug_url` parameter is an invitation for users to visit that URL to submit a bug report /// in the case where a panic happens. -pub fn set(bug_url: &'static str) { - panic::set_hook(Box::new(move |c| panic_hook(c, bug_url))); +pub fn set(bug_url: &'static str, version: &str) { + panic::set_hook(Box::new({ + let version = version.to_string(); + move |c| { + panic_hook(c, bug_url, &version) + } + })); } macro_rules! ABOUT_PANIC { @@ -124,7 +129,7 @@ impl Drop for AbortGuard { } /// Function being called when a panic happens. -fn panic_hook(info: &PanicInfo, report_url: &'static str) { +fn panic_hook(info: &PanicInfo, report_url: &'static str, version: &str) { let location = info.location(); let file = location.as_ref().map(|l| l.file()).unwrap_or(""); let line = location.as_ref().map(|l| l.line()).unwrap_or(0); @@ -147,6 +152,8 @@ fn panic_hook(info: &PanicInfo, report_url: &'static str) { let _ = writeln!(stderr, ""); let _ = writeln!(stderr, "===================="); let _ = writeln!(stderr, ""); + let _ = writeln!(stderr, "Version: {}", version); + let _ = writeln!(stderr, ""); let _ = writeln!(stderr, "{:?}", backtrace); let _ = writeln!(stderr, ""); let _ = writeln!( @@ -169,14 +176,14 @@ mod tests { #[test] fn does_not_abort() { - set("test"); + set("test", "1.2.3"); let _guard = AbortGuard::force_unwind(); ::std::panic::catch_unwind(|| panic!()).ok(); } #[test] fn does_not_abort_after_never_abort() { - set("test"); + set("test", "1.2.3"); let _guard = AbortGuard::never_abort(); let _guard = AbortGuard::force_abort(); std::panic::catch_unwind(|| panic!()).ok(); -- GitLab From ac392322f1f1505ea2e9487d6d80a9bb0563ecff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 12 Sep 2019 21:59:18 +0200 Subject: [PATCH 089/275] Implement support for `patch` section in wasm-builder (#3599) * Implement support for `patch` section in wasm-builder * Update core/utils/wasm-builder/src/wasm_project.rs * Support patch by path * Go down to the actual data --- Cargo.lock | 2 +- core/executor/runtime-test/build.rs | 2 +- core/test-runtime/build.rs | 2 +- core/utils/wasm-builder/Cargo.toml | 2 +- core/utils/wasm-builder/src/wasm_project.rs | 77 ++++++++++++++++----- node-template/runtime/build.rs | 2 +- node/runtime/build.rs | 2 +- 7 files changed, 65 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0d257d6dd0..c1c6311395 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5474,7 +5474,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" -version = "1.0.5" +version = "1.0.6" dependencies = [ "build-helper 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/core/executor/runtime-test/build.rs b/core/executor/runtime-test/build.rs index 3ebf28739b..fd4749b34c 100644 --- a/core/executor/runtime-test/build.rs +++ b/core/executor/runtime-test/build.rs @@ -21,7 +21,7 @@ fn main() { "wasm_binary.rs", WasmBuilderSource::CratesOrPath { path: "../../utils/wasm-builder", - version: "1.0.5", + version: "1.0.6", }, // This instructs LLD to export __heap_base as a global variable, which is used by the // external memory allocator. diff --git a/core/test-runtime/build.rs b/core/test-runtime/build.rs index 041704f37d..cdf1d17819 100644 --- a/core/test-runtime/build.rs +++ b/core/test-runtime/build.rs @@ -21,7 +21,7 @@ fn main() { "wasm_binary.rs", WasmBuilderSource::CratesOrPath { path: "../utils/wasm-builder", - version: "1.0.5", + version: "1.0.6", }, // Note that we set the stack-size to 1MB explicitly even though it is set // to this value by default. This is because some of our tests (`restoration_of_globals`) diff --git a/core/utils/wasm-builder/Cargo.toml b/core/utils/wasm-builder/Cargo.toml index 97d4d2316a..ccc1d0cf3a 100644 --- a/core/utils/wasm-builder/Cargo.toml +++ b/core/utils/wasm-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-wasm-builder" -version = "1.0.5" +version = "1.0.6" authors = ["Parity Technologies "] description = "Utility for building WASM binaries" edition = "2018" diff --git a/core/utils/wasm-builder/src/wasm_project.rs b/core/utils/wasm-builder/src/wasm_project.rs index feaaea1802..a098234750 100644 --- a/core/utils/wasm-builder/src/wasm_project.rs +++ b/core/utils/wasm-builder/src/wasm_project.rs @@ -88,7 +88,7 @@ pub fn create_and_compile( let _lock = WorkspaceLock::new(&wasm_workspace_root); let project = create_project(cargo_manifest, &wasm_workspace); - create_wasm_workspace_project(&wasm_workspace); + create_wasm_workspace_project(&wasm_workspace, cargo_manifest); build_project(&project, default_rustflags); let (wasm_binary, bloaty) = compact_wasm_file( @@ -172,7 +172,7 @@ fn get_wasm_workspace_root() -> PathBuf { panic!("Could not find target dir in: {}", build_helper::out_dir().display()) } -fn create_wasm_workspace_project(wasm_workspace: &Path) { +fn create_wasm_workspace_project(wasm_workspace: &Path, cargo_manifest: &Path) { let members = WalkDir::new(wasm_workspace) .min_depth(1) .max_depth(1) @@ -181,25 +181,66 @@ fn create_wasm_workspace_project(wasm_workspace: &Path) { .map(|d| d.into_path()) .filter(|p| p.is_dir() && !p.ends_with("target")) .filter_map(|p| p.file_name().map(|f| f.to_owned()).and_then(|s| s.into_string().ok())) - .map(|s| format!("\"{}\", ", s)) - .collect::(); + .collect::>(); + + let crate_metadata = MetadataCommand::new() + .manifest_path(cargo_manifest) + .exec() + .expect("`cargo metadata` can not fail on project `Cargo.toml`; qed"); + let workspace_root_path = crate_metadata.workspace_root; + + let mut workspace_toml: Table = toml::from_str( + &fs::read_to_string( + workspace_root_path.join("Cargo.toml"), + ).expect("Workspace root `Cargo.toml` exists; qed") + ).expect("Workspace root `Cargo.toml` is a valid toml file; qed"); + + let mut wasm_workspace_toml = Table::new(); + + // Add `profile` with release and dev + let mut release_profile = Table::new(); + release_profile.insert("panic".into(), "abort".into()); + release_profile.insert("lto".into(), true.into()); + + let mut dev_profile = Table::new(); + dev_profile.insert("panic".into(), "abort".into()); + + let mut profile = Table::new(); + profile.insert("release".into(), release_profile.into()); + profile.insert("dev".into(), dev_profile.into()); + + wasm_workspace_toml.insert("profile".into(), profile.into()); + + // Add `workspace` with members + let mut workspace = Table::new(); + workspace.insert("members".into(), members.into()); + + wasm_workspace_toml.insert("workspace".into(), workspace.into()); + + // Add patch section from the project root `Cargo.toml` + if let Some(mut patch) = workspace_toml.remove("patch").and_then(|p| p.try_into::().ok()) { + // Iterate over all patches and make the patch path absolute from the workspace root path. + patch.iter_mut() + .filter_map(|p| + p.1.as_table_mut().map(|t| t.iter_mut().filter_map(|t| t.1.as_table_mut())) + ) + .flatten() + .for_each(|p| + p.iter_mut() + .filter(|(k, _)| k == &"path") + .for_each(|(_, v)| { + if let Some(path) = v.as_str() { + *v = workspace_root_path.join(path).display().to_string().into(); + } + }) + ); + + wasm_workspace_toml.insert("patch".into(), patch.into()); + } fs::write( wasm_workspace.join("Cargo.toml"), - format!( - r#" - [profile.release] - panic = "abort" - lto = true - - [profile.dev] - panic = "abort" - - [workspace] - members = [ {members} ] - "#, - members = members, - ) + toml::to_string_pretty(&wasm_workspace_toml).expect("Wasm workspace toml is valid; qed"), ).expect("WASM workspace `Cargo.toml` writing can not fail; qed"); } diff --git a/node-template/runtime/build.rs b/node-template/runtime/build.rs index 1ed109dd8e..6feac76e8b 100644 --- a/node-template/runtime/build.rs +++ b/node-template/runtime/build.rs @@ -19,7 +19,7 @@ use wasm_builder_runner::{build_current_project_with_rustflags, WasmBuilderSourc fn main() { build_current_project_with_rustflags( "wasm_binary.rs", - WasmBuilderSource::Crates("1.0.5"), + WasmBuilderSource::Crates("1.0.6"), // This instructs LLD to export __heap_base as a global variable, which is used by the // external memory allocator. "-Clink-arg=--export=__heap_base", diff --git a/node/runtime/build.rs b/node/runtime/build.rs index d5d6599eca..62dfe2ff39 100644 --- a/node/runtime/build.rs +++ b/node/runtime/build.rs @@ -21,7 +21,7 @@ fn main() { "wasm_binary.rs", WasmBuilderSource::CratesOrPath { path: "../../core/utils/wasm-builder", - version: "1.0.5", + version: "1.0.6", }, // This instructs LLD to export __heap_base as a global variable, which is used by the // external memory allocator. -- GitLab From f47734dc5575aaebcbce511435fecf4b1746f66d Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Fri, 13 Sep 2019 08:41:33 +0200 Subject: [PATCH 090/275] Move phragmen benchmarks out of Staking (#3588) * Move phragmen benches to.. phragmen. * Move some basic phragmen tests to.. phragmen. * Line-width * Add phragmen equ implementation as flot * Add phragmen equ implementation as flot * Add mock and test file. --- .gitlab-ci.yml | 2 +- Cargo.lock | 3 +- core/phragmen/Cargo.toml | 2 + .../phragmen/benches/phragmen.rs | 194 ++++---- core/phragmen/src/lib.rs | 228 +--------- core/phragmen/src/mock.rs | 419 ++++++++++++++++++ core/phragmen/src/tests.rs | 135 ++++++ srml/staking/Cargo.toml | 2 - srml/staking/src/lib.rs | 12 +- srml/staking/src/tests.rs | 54 +-- 10 files changed, 669 insertions(+), 382 deletions(-) rename srml/staking/src/benches.rs => core/phragmen/benches/phragmen.rs (53%) create mode 100644 core/phragmen/src/mock.rs create mode 100644 core/phragmen/src/tests.rs diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b67d5eb648..60a75d5db4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -101,7 +101,7 @@ cargo-check-benches: stage: test <<: *docker-env script: - - BUILD_DUMMY_WASM_BINARY=1 time cargo check --benches --all + - BUILD_DUMMY_WASM_BINARY=1 time cargo +nightly check --benches --all - sccache -s diff --git a/Cargo.lock b/Cargo.lock index c1c6311395..f53a4a1acc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4264,7 +4264,6 @@ name = "srml-staking" version = "2.0.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -5101,6 +5100,8 @@ dependencies = [ name = "substrate-phragmen" version = "2.0.0" dependencies = [ + "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", "srml-support 2.0.0", diff --git a/core/phragmen/Cargo.toml b/core/phragmen/Cargo.toml index 335bddb401..52f061b862 100644 --- a/core/phragmen/Cargo.toml +++ b/core/phragmen/Cargo.toml @@ -9,7 +9,9 @@ sr-primitives = { path = "../sr-primitives", default-features = false } rstd = { package = "sr-std", path = "../sr-std", default-features = false } [dev-dependencies] +runtime-io ={ package = "sr-io", path = "../sr-io" } support = { package = "srml-support", path = "../../srml/support" } +rand = "0.7.0" [features] default = ["std"] diff --git a/srml/staking/src/benches.rs b/core/phragmen/benches/phragmen.rs similarity index 53% rename from srml/staking/src/benches.rs rename to core/phragmen/benches/phragmen.rs index e9c3667984..dfe56aafd8 100644 --- a/srml/staking/src/benches.rs +++ b/core/phragmen/benches/phragmen.rs @@ -16,27 +16,35 @@ //! Note that execution times will not be accurate in an absolute scale, since //! - Everything is executed in the context of `TestExternalities` //! - Everything is executed in native environment. -//! -//! Run using: -//! -//! ```zsh -//! cargo bench --features bench --color always -//! ``` +#![feature(test)] + +extern crate test; use test::Bencher; -use runtime_io::with_externalities; -use mock::*; -use super::*; -use phragmen; + use rand::{self, Rng}; +extern crate substrate_phragmen as phragmen; +use phragmen::{Support, SupportMap, ACCURACY}; + +use std::collections::BTreeMap; +use sr_primitives::traits::{Convert, SaturatedConversion}; const VALIDATORS: u64 = 1000; const NOMINATORS: u64 = 10_000; const EDGES: u64 = 2; const TO_ELECT: usize = 100; -const STAKE: u64 = 1000; +const STAKE: Balance = 1000; -type C = ::CurrencyToVote; +type Balance = u128; +type AccountId = u64; + +pub struct TestCurrencyToVote; +impl Convert for TestCurrencyToVote { + fn convert(x: Balance) -> u64 { x.saturated_into() } +} +impl Convert for TestCurrencyToVote { + fn convert(x: u128) -> Balance { x.saturated_into() } +} fn do_phragmen( b: &mut Bencher, @@ -47,84 +55,89 @@ fn do_phragmen( eq_iters: usize, _eq_tolerance: u128, ) { - with_externalities(&mut ExtBuilder::default().nominate(false).build(), || { - assert!(num_vals > votes_per); - let rr = |a, b| rand::thread_rng().gen_range(a as usize, b as usize) as u64; - - // prefix to distinguish the validator and nominator account ranges. - let np = 10_000; - - (1 ..= 2*num_vals) - .step_by(2) - .for_each(|acc| bond_validator(acc, STAKE + rr(10, 50))); - - (np ..= (np + 2*num_noms)) - .step_by(2) - .for_each(|acc| { - let mut stashes_to_vote = (1 ..= 2*num_vals) - .step_by(2) - .map(|ctrl| ctrl + 1) - .collect::>(); - let votes = (0 .. votes_per) - .map(|_| { - stashes_to_vote.remove(rr(0, stashes_to_vote.len()) as usize) - }) - .collect::>(); - bond_nominator(acc, STAKE + rr(10, 50), votes); - }); - - b.iter(|| { - let r = phragmen::elect::<_, _, _, ::CurrencyToVote>( - count, - 1_usize, - >::enumerate().map(|(who, _)| who).collect::>(), - >::enumerate().collect(), - Staking::slashable_balance_of, - true, - ).unwrap(); - - // Do the benchmarking with equalize. - if eq_iters > 0 { - let elected_stashes = r.winners; - let mut assignments = r.assignments; - - let to_votes = |b: Balance| - as Convert>::convert(b) as ExtendedBalance; - let ratio_of = |b, r: ExtendedBalance| r.saturating_mul(to_votes(b)) / ACCURACY; - - // Initialize the support of each candidate. - let mut supports = >::new(); - elected_stashes - .iter() - .map(|e| (e, to_votes(Staking::slashable_balance_of(e)))) - .for_each(|(e, s)| { - let item = Support { own: s, total: s, ..Default::default() }; - supports.insert(e.clone(), item); - }); - - for (n, assignment) in assignments.iter_mut() { - for (c, r) in assignment.iter_mut() { - let nominator_stake = Staking::slashable_balance_of(n); - let other_stake = ratio_of(nominator_stake, *r); - if let Some(support) = supports.get_mut(c) { - support.total = support.total.saturating_add(other_stake); - support.others.push((n.clone(), other_stake)); - } - *r = other_stake; + assert!(num_vals > votes_per); + let rr = |a, b| rand::thread_rng().gen_range(a as usize, b as usize) as Balance; + + // prefix to distinguish the validator and nominator account ranges. + let np = 10_000; + + let mut candidates = vec![]; + let mut voters = vec![]; + let mut slashable_balance_of: BTreeMap = BTreeMap::new(); + + (1 ..= num_vals) + .for_each(|acc| { + candidates.push(acc); + slashable_balance_of.insert(acc, STAKE + rr(10, 50)); + }); + + (np ..= (np + num_noms)) + .for_each(|acc| { + let mut stashes_to_vote = candidates.clone(); + let votes = (0 .. votes_per) + .map(|_| { + stashes_to_vote.remove(rr(0, stashes_to_vote.len()) as usize) + }) + .collect::>(); + voters.push((acc, votes)); + slashable_balance_of.insert(acc, STAKE + rr(10, 50)); + }); + + let slashable_balance = |who: &AccountId| -> Balance { + *slashable_balance_of.get(who).unwrap() + }; + + b.iter(|| { + let r = phragmen::elect::( + count, + 1_usize, + candidates.clone(), + voters.clone(), + slashable_balance, + true, + ).unwrap(); + + // Do the benchmarking with equalize. + if eq_iters > 0 { + let elected_stashes = r.winners; + let mut assignments = r.assignments; + + let to_votes = |b: Balance| + >::convert(b) as u128; + let ratio_of = |b, r: u128| r.saturating_mul(to_votes(b)) / ACCURACY; + + // Initialize the support of each candidate. + let mut supports = >::new(); + elected_stashes + .iter() + .map(|e| (e, to_votes(slashable_balance(e)))) + .for_each(|(e, s)| { + let item = Support { own: s, total: s, ..Default::default() }; + supports.insert(e.clone(), item); + }); + + for (n, assignment) in assignments.iter_mut() { + for (c, r) in assignment.iter_mut() { + let nominator_stake = slashable_balance(n); + let other_stake = ratio_of(nominator_stake, *r); + if let Some(support) = supports.get_mut(c) { + support.total = support.total.saturating_add(other_stake); + support.others.push((n.clone(), other_stake)); } + *r = other_stake; } - - let tolerance = 0_u128; - let iterations = 2_usize; - phragmen::equalize::<_, _, ::CurrencyToVote, _>( - assignments, - &mut supports, - tolerance, - iterations, - Staking::slashable_balance_of, - ); } - }) + + let tolerance = 0_u128; + let iterations = 2_usize; + phragmen::equalize::<_, _, _, TestCurrencyToVote>( + assignments, + &mut supports, + tolerance, + iterations, + slashable_balance, + ); + } }) } @@ -134,11 +147,10 @@ macro_rules! phragmen_benches { #[bench] fn $name(b: &mut Bencher) { let (v, n, t, e, eq_iter, eq_tol) = $tup; - println!(""); + println!("----------------------"); println!( - r#" -++ Benchmark: {} Validators // {} Nominators // {} Edges-per-nominator // {} total edges // -electing {} // Equalize: {} iterations -- {} tolerance"#, + "++ Benchmark: {} Validators // {} Nominators // {} Edges-per-nominator // {} \ + total edges // electing {} // Equalize: {} iterations -- {} tolerance", v, n, e, e * n, t, eq_iter, eq_tol, ); do_phragmen(b, v, n, t, e, eq_iter, eq_tol); diff --git a/core/phragmen/src/lib.rs b/core/phragmen/src/lib.rs index 459254370b..da3e923424 100644 --- a/core/phragmen/src/lib.rs +++ b/core/phragmen/src/lib.rs @@ -37,6 +37,9 @@ use rstd::{prelude::*, collections::btree_map::BTreeMap}; use sr_primitives::PerU128; use sr_primitives::traits::{Zero, Convert, Member, SimpleArithmetic}; +mod mock; +mod tests; + /// Type used as the fraction. type Fraction = PerU128; @@ -355,7 +358,7 @@ pub fn elect( /// * `tolerance`: maximum difference that can occur before an early quite happens. /// * `iterations`: maximum number of iterations that will be processed. /// * `stake_of`: something that can return the stake stake of a particular candidate or voter. -pub fn equalize( +pub fn equalize( mut assignments: Vec<(AccountId, Vec>)>, supports: &mut SupportMap, tolerance: ExtendedBalance, @@ -489,226 +492,3 @@ fn do_equalize( difference } - -#[cfg(test)] -mod tests { - use super::{elect, ACCURACY, PhragmenResult}; - use sr_primitives::traits::{Convert, Member, SaturatedConversion}; - use rstd::collections::btree_map::BTreeMap; - use support::assert_eq_uvec; - - pub struct C; - impl Convert for C { - fn convert(x: u64) -> u64 { x } - } - impl Convert for C { - fn convert(x: u128) -> u64 { x.saturated_into() } - } - - #[derive(Default, Debug)] - struct _Candidate { - who: AccountId, - score: f64, - approval_stake: f64, - elected: bool, - } - - #[derive(Default, Debug)] - struct _Voter { - who: AccountId, - edges: Vec<_Edge>, - budget: f64, - load: f64, - } - - #[derive(Default, Debug)] - struct _Edge { - who: AccountId, - load: f64, - candidate_index: usize, - } - - type _PhragmenAssignment = (AccountId, f64); - - #[derive(Debug)] - pub struct _PhragmenResult { - pub winners: Vec, - pub assignments: Vec<(AccountId, Vec<_PhragmenAssignment>)> - } - - pub fn elect_poc( - candidate_count: usize, - minimum_candidate_count: usize, - initial_candidates: Vec, - initial_voters: Vec<(AccountId, Vec)>, - stake_of: FS, - self_vote: bool, - ) -> Option<_PhragmenResult> where - AccountId: Default + Ord + Member + Copy, - for<'r> FS: Fn(&'r AccountId) -> u64, - { - let mut elected_candidates: Vec; - let mut assigned: Vec<(AccountId, Vec<_PhragmenAssignment>)>; - let mut c_idx_cache = BTreeMap::::new(); - let num_voters = initial_candidates.len() + initial_voters.len(); - let mut voters: Vec<_Voter> = Vec::with_capacity(num_voters); - - let mut candidates = if self_vote { - initial_candidates.into_iter().map(|who| { - let stake = stake_of(&who) as f64; - _Candidate { who, approval_stake: stake, ..Default::default() } - }) - .filter(|c| c.approval_stake != 0f64) - .enumerate() - .map(|(i, c)| { - let who = c.who; - voters.push(_Voter { - who: who.clone(), - edges: vec![ - _Edge { who: who.clone(), candidate_index: i, ..Default::default() } - ], - budget: c.approval_stake, - load: 0f64, - }); - c_idx_cache.insert(c.who.clone(), i); - c - }) - .collect::>>() - } else { - initial_candidates.into_iter() - .enumerate() - .map(|(idx, who)| { - c_idx_cache.insert(who.clone(), idx); - _Candidate { who, ..Default::default() } - }) - .collect::>>() - }; - - if candidates.len() < minimum_candidate_count { - return None; - } - - voters.extend(initial_voters.into_iter().map(|(who, votes)| { - let voter_stake = stake_of(&who) as f64; - let mut edges: Vec<_Edge> = Vec::with_capacity(votes.len()); - for v in votes { - if let Some(idx) = c_idx_cache.get(&v) { - candidates[*idx].approval_stake = candidates[*idx].approval_stake + voter_stake; - edges.push( - _Edge { who: v.clone(), candidate_index: *idx, ..Default::default() } - ); - } - } - _Voter { - who, - edges: edges, - budget: voter_stake, - load: 0f64, - } - })); - - let to_elect = candidate_count.min(candidates.len()); - elected_candidates = Vec::with_capacity(candidate_count); - assigned = Vec::with_capacity(candidate_count); - - for _round in 0..to_elect { - for c in &mut candidates { - if !c.elected { - c.score = 1.0 / c.approval_stake; - } - } - for n in &voters { - for e in &n.edges { - let c = &mut candidates[e.candidate_index]; - if !c.elected && !(c.approval_stake == 0f64) { - c.score += n.budget * n.load / c.approval_stake; - } - } - } - - if let Some(winner) = candidates - .iter_mut() - .filter(|c| !c.elected) - .min_by(|x, y| x.score.partial_cmp(&y.score).unwrap_or(rstd::cmp::Ordering::Equal)) - { - winner.elected = true; - for n in &mut voters { - for e in &mut n.edges { - if e.who == winner.who { - e.load = winner.score - n.load; - n.load = winner.score; - } - } - } - - elected_candidates.push(winner.who.clone()); - } else { - break - } - } - - for n in &mut voters { - let mut assignment = (n.who.clone(), vec![]); - for e in &mut n.edges { - if let Some(c) = elected_candidates.iter().cloned().find(|c| *c == e.who) { - if c != n.who { - let ratio = e.load / n.load; - assignment.1.push((e.who.clone(), ratio)); - } - } - } - assigned.push(assignment); - } - - Some(_PhragmenResult { - winners: elected_candidates, - assignments: assigned, - }) - } - - #[test] - fn float_poc_works() { - let candidates = vec![1, 2, 3]; - let voters = vec![ - (10, vec![1, 2]), - (20, vec![1, 3]), - (30, vec![2, 3]), - ]; - let stake_of = |x: &u64| { if *x >= 10 { *x } else { 0 }}; - let _PhragmenResult { winners, assignments } = - elect_poc(2, 2, candidates, voters, stake_of, false).unwrap(); - - assert_eq_uvec!(winners, vec![2, 3]); - assert_eq_uvec!( - assignments, - vec![ - (10, vec![(2, 1.0)]), - (20, vec![(3, 1.0)]), - (30, vec![(2, 0.5), (3, 0.5)]) - ] - ); - } - - #[test] - fn phragmen_works() { - let candidates = vec![1, 2, 3]; - let voters = vec![ - (10, vec![1, 2]), - (20, vec![1, 3]), - (30, vec![2, 3]), - ]; - let stake_of = |x: &u64| { if *x >= 10 { *x } else { 0 }}; - let PhragmenResult { winners, assignments } = - elect::<_, _, _, C>(2, 2, candidates, voters, stake_of, false).unwrap(); - - assert_eq_uvec!(winners, vec![2, 3]); - assert_eq_uvec!( - assignments, - vec![ - (10, vec![(2, ACCURACY)]), - (20, vec![(3, ACCURACY)]), - (30, vec![(2, ACCURACY/2), (3, ACCURACY/2)]) - ] - ); - } -} diff --git a/core/phragmen/src/mock.rs b/core/phragmen/src/mock.rs new file mode 100644 index 0000000000..659ff9dacb --- /dev/null +++ b/core/phragmen/src/mock.rs @@ -0,0 +1,419 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Mock file for phragmen. + +#![cfg(test)] + +use crate::{elect, ACCURACY, PhragmenResult}; +use sr_primitives::traits::{Convert, Member, SaturatedConversion}; +use rstd::collections::btree_map::BTreeMap; +use support::assert_eq_error_rate; + +pub(crate) struct TestCurrencyToVote; +impl Convert for TestCurrencyToVote { + fn convert(x: Balance) -> u64 { x.saturated_into() } +} +impl Convert for TestCurrencyToVote { + fn convert(x: u128) -> Balance { x } +} + +#[derive(Default, Debug)] +pub(crate) struct _Candidate { + who: A, + score: f64, + approval_stake: f64, + elected: bool, +} + +#[derive(Default, Debug)] +pub(crate) struct _Voter { + who: A, + edges: Vec<_Edge>, + budget: f64, + load: f64, +} + +#[derive(Default, Debug)] +pub(crate) struct _Edge { + who: A, + load: f64, + candidate_index: usize, +} + +#[derive(Default, Debug, PartialEq)] +pub(crate) struct _Support { + pub own: f64, + pub total: f64, + pub others: Vec<_PhragmenAssignment>, +} + +pub(crate) type _PhragmenAssignment = (A, f64); +pub(crate) type _SupportMap = BTreeMap>; + +pub(crate) type Balance = u128; +pub(crate) type AccountId = u64; + +#[derive(Debug, Clone)] +pub(crate) struct _PhragmenResult { + pub winners: Vec, + pub assignments: Vec<(A, Vec<_PhragmenAssignment>)> +} + +pub(crate) fn elect_float( + candidate_count: usize, + minimum_candidate_count: usize, + initial_candidates: Vec, + initial_voters: Vec<(A, Vec)>, + stake_of: FS, + self_vote: bool, +) -> Option<_PhragmenResult> where + A: Default + Ord + Member + Copy, + for<'r> FS: Fn(&'r A) -> Balance, +{ + let mut elected_candidates: Vec; + let mut assigned: Vec<(A, Vec<_PhragmenAssignment>)>; + let mut c_idx_cache = BTreeMap::::new(); + let num_voters = initial_candidates.len() + initial_voters.len(); + let mut voters: Vec<_Voter> = Vec::with_capacity(num_voters); + + let mut candidates = if self_vote { + initial_candidates.into_iter().map(|who| { + let stake = stake_of(&who) as f64; + _Candidate { who, approval_stake: stake, ..Default::default() } + }) + .filter(|c| c.approval_stake != 0f64) + .enumerate() + .map(|(i, c)| { + let who = c.who; + voters.push(_Voter { + who: who.clone(), + edges: vec![ + _Edge { who: who.clone(), candidate_index: i, ..Default::default() } + ], + budget: c.approval_stake, + load: 0f64, + }); + c_idx_cache.insert(c.who.clone(), i); + c + }) + .collect::>>() + } else { + initial_candidates.into_iter() + .enumerate() + .map(|(idx, who)| { + c_idx_cache.insert(who.clone(), idx); + _Candidate { who, ..Default::default() } + }) + .collect::>>() + }; + + if candidates.len() < minimum_candidate_count { + return None; + } + + voters.extend(initial_voters.into_iter().map(|(who, votes)| { + let voter_stake = stake_of(&who) as f64; + let mut edges: Vec<_Edge> = Vec::with_capacity(votes.len()); + for v in votes { + if let Some(idx) = c_idx_cache.get(&v) { + candidates[*idx].approval_stake = candidates[*idx].approval_stake + voter_stake; + edges.push( + _Edge { who: v.clone(), candidate_index: *idx, ..Default::default() } + ); + } + } + _Voter { + who, + edges: edges, + budget: voter_stake, + load: 0f64, + } + })); + + let to_elect = candidate_count.min(candidates.len()); + elected_candidates = Vec::with_capacity(candidate_count); + assigned = Vec::with_capacity(candidate_count); + + for _round in 0..to_elect { + for c in &mut candidates { + if !c.elected { + c.score = 1.0 / c.approval_stake; + } + } + for n in &voters { + for e in &n.edges { + let c = &mut candidates[e.candidate_index]; + if !c.elected && !(c.approval_stake == 0f64) { + c.score += n.budget * n.load / c.approval_stake; + } + } + } + + if let Some(winner) = candidates + .iter_mut() + .filter(|c| !c.elected) + .min_by(|x, y| x.score.partial_cmp(&y.score).unwrap_or(rstd::cmp::Ordering::Equal)) + { + winner.elected = true; + for n in &mut voters { + for e in &mut n.edges { + if e.who == winner.who { + e.load = winner.score - n.load; + n.load = winner.score; + } + } + } + + elected_candidates.push(winner.who.clone()); + } else { + break + } + } + + for n in &mut voters { + let mut assignment = (n.who.clone(), vec![]); + for e in &mut n.edges { + if let Some(c) = elected_candidates.iter().cloned().find(|c| *c == e.who) { + if c != n.who { + let ratio = e.load / n.load; + assignment.1.push((e.who.clone(), ratio)); + } + } + } + if assignment.1.len() > 0 { + assigned.push(assignment); + } + } + + Some(_PhragmenResult { + winners: elected_candidates, + assignments: assigned, + }) +} + +pub(crate) fn equalize_float( + mut assignments: Vec<(A, Vec<_PhragmenAssignment>)>, + supports: &mut _SupportMap, + tolerance: f64, + iterations: usize, + stake_of: FS, +) where + for<'r> FS: Fn(&'r A) -> Balance, + A: Ord + Clone + std::fmt::Debug, +{ + for _i in 0..iterations { + let mut max_diff = 0.0; + for (voter, assignment) in assignments.iter_mut() { + let voter_budget = stake_of(&voter); + let diff = do_equalize_float( + voter, + voter_budget, + assignment, + supports, + tolerance, + ); + if diff > max_diff { max_diff = diff; } + } + + if max_diff < tolerance { + break; + } + } +} + +pub(crate) fn do_equalize_float( + voter: &A, + budget_balance: Balance, + elected_edges: &mut Vec<_PhragmenAssignment>, + support_map: &mut _SupportMap, + tolerance: f64 +) -> f64 where + A: Ord + Clone, +{ + let budget = budget_balance as f64; + if elected_edges.is_empty() { return 0.0; } + + let stake_used = elected_edges + .iter() + .fold(0.0, |s, e| s + e.1); + + let backed_stakes_iter = elected_edges + .iter() + .filter_map(|e| support_map.get(&e.0)) + .map(|e| e.total); + + let backing_backed_stake = elected_edges + .iter() + .filter(|e| e.1 > 0.0) + .filter_map(|e| support_map.get(&e.0)) + .map(|e| e.total) + .collect::>(); + + let mut difference; + if backing_backed_stake.len() > 0 { + let max_stake = backing_backed_stake + .iter() + .max_by(|x, y| x.partial_cmp(&y).unwrap_or(rstd::cmp::Ordering::Equal)) + .expect("vector with positive length will have a max; qed"); + let min_stake = backed_stakes_iter + .min_by(|x, y| x.partial_cmp(&y).unwrap_or(rstd::cmp::Ordering::Equal)) + .expect("iterator with positive length will have a min; qed"); + + difference = max_stake - min_stake; + difference = difference + budget - stake_used; + if difference < tolerance { + return difference; + } + } else { + difference = budget; + } + + // Undo updates to support + elected_edges.iter_mut().for_each(|e| { + if let Some(support) = support_map.get_mut(&e.0) { + support.total = support.total - e.1; + support.others.retain(|i_support| i_support.0 != *voter); + } + e.1 = 0.0; + }); + + // todo: rewrite. + elected_edges.sort_unstable_by(|x, y| + if let Some(x) = support_map.get(&x.0) { + if let Some(y) = support_map.get(&y.0) { + x.total.partial_cmp(&y.total).unwrap_or(rstd::cmp::Ordering::Equal) + } else { + rstd::cmp::Ordering::Equal + } + } else { + rstd::cmp::Ordering::Equal + } + ); + + let mut cumulative_stake = 0.0; + let mut last_index = elected_edges.len() - 1; + elected_edges.iter_mut().enumerate().for_each(|(idx, e)| { + if let Some(support) = support_map.get_mut(&e.0) { + let stake = support.total; + let stake_mul = stake * (idx as f64); + let stake_sub = stake_mul - cumulative_stake; + if stake_sub > budget { + last_index = idx.checked_sub(1).unwrap_or(0); + return + } + cumulative_stake = cumulative_stake + stake; + } + }); + + let last_stake = elected_edges[last_index].1; + let split_ways = last_index + 1; + let excess = budget + cumulative_stake - last_stake * (split_ways as f64); + elected_edges.iter_mut().take(split_ways).for_each(|e| { + if let Some(support) = support_map.get_mut(&e.0) { + e.1 = excess / (split_ways as f64) + last_stake - support.total; + support.total = support.total + e.1; + support.others.push((voter.clone(), e.1)); + } + }); + + difference +} + + +pub(crate) fn create_stake_of(stakes: &[(AccountId, Balance)]) + -> Box Balance> +{ + let mut storage = BTreeMap::::new(); + stakes.iter().for_each(|s| { storage.insert(s.0, s.1); }); + let stake_of = move |who: &AccountId| -> Balance { storage.get(who).unwrap().to_owned() }; + Box::new(stake_of) +} + +pub(crate) fn run_and_compare( + candidates: Vec, + voters: Vec<(AccountId, Vec)>, + stake_of: Box Balance>, + to_elect: usize, + min_to_elect: usize, + self_vote: bool, +) { + // run fixed point code. + let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>( + to_elect, + min_to_elect, + candidates.clone(), + voters.clone(), + &stake_of, + self_vote, + ).unwrap(); + + // run float poc code. + let truth_value = elect_float( + to_elect, + min_to_elect, + candidates, + voters, + &stake_of, + self_vote, + ).unwrap(); + + assert_eq!(winners, truth_value.winners); + + for (nominator, assigned) in assignments.clone() { + if let Some(float_assignments) = truth_value.assignments.iter().find(|x| x.0 == nominator) { + for (candidate, ratio) in assigned { + if let Some(float_assignment) = float_assignments.1.iter().find(|x| x.0 == candidate ) { + assert_eq_error_rate!((float_assignment.1 * ACCURACY as f64).round() as u128, ratio, 1); + } else { + panic!("candidate mismatch. This should never happen.") + } + } + } else { + panic!("nominator mismatch. This should never happen.") + } + } +} + +pub(crate) fn build_support_map( + result: &mut _PhragmenResult, + stake_of: FS, +) -> _SupportMap + where for<'r> FS: Fn(&'r AccountId) -> Balance +{ + let mut supports = <_SupportMap>::new(); + result.winners + .iter() + .map(|e| (e, stake_of(e) as f64)) + .for_each(|(e, s)| { + let item = _Support { own: s, total: s, ..Default::default() }; + supports.insert(e.clone(), item); + }); + + for (n, assignment) in result.assignments.iter_mut() { + for (c, r) in assignment.iter_mut() { + let nominator_stake = stake_of(n) as f64; + let other_stake = nominator_stake * *r; + if let Some(support) = supports.get_mut(c) { + support.total = support.total + other_stake; + support.others.push((n.clone(), other_stake)); + } + *r = other_stake; + } + } + + supports +} diff --git a/core/phragmen/src/tests.rs b/core/phragmen/src/tests.rs new file mode 100644 index 0000000000..5a8cddb984 --- /dev/null +++ b/core/phragmen/src/tests.rs @@ -0,0 +1,135 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Tests for phragmen. + +#![cfg(test)] + +use crate::mock::*; +use crate::{elect, ACCURACY, PhragmenResult}; +use support::assert_eq_uvec; + +#[test] +fn float_phragmen_poc_works() { + let candidates = vec![1, 2, 3]; + let voters = vec![ + (10, vec![1, 2]), + (20, vec![1, 3]), + (30, vec![2, 3]), + ]; + let stake_of = create_stake_of(&[(10, 10), (20, 20), (30, 30), (1, 0), (2, 0), (3, 0)]); + let mut phragmen_result = elect_float(2, 2, candidates, voters, &stake_of, false).unwrap(); + let winners = phragmen_result.clone().winners; + let assignments = phragmen_result.clone().assignments; + + assert_eq_uvec!(winners, vec![2, 3]); + assert_eq_uvec!( + assignments, + vec![ + (10, vec![(2, 1.0)]), + (20, vec![(3, 1.0)]), + (30, vec![(2, 0.5), (3, 0.5)]), + ] + ); + + let mut support_map = build_support_map(&mut phragmen_result, &stake_of); + + assert_eq!( + support_map.get(&2).unwrap(), + &_Support { own: 0.0, total: 25.0, others: vec![(10u64, 10.0), (30u64, 15.0)]} + ); + assert_eq!( + support_map.get(&3).unwrap(), + &_Support { own: 0.0, total: 35.0, others: vec![(20u64, 20.0), (30u64, 15.0)]} + ); + + equalize_float(phragmen_result.assignments, &mut support_map, 0.0, 2, stake_of); + + assert_eq!( + support_map.get(&2).unwrap(), + &_Support { own: 0.0, total: 30.0, others: vec![(10u64, 10.0), (30u64, 20.0)]} + ); + assert_eq!( + support_map.get(&3).unwrap(), + &_Support { own: 0.0, total: 30.0, others: vec![(20u64, 20.0), (30u64, 10.0)]} + ); +} + +#[test] +fn phragmen_poc_works() { + let candidates = vec![1, 2, 3]; + let voters = vec![ + (10, vec![1, 2]), + (20, vec![1, 3]), + (30, vec![2, 3]), + ]; + + let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>( + 2, + 2, + candidates, + voters, + create_stake_of(&[(10, 10), (20, 20), (30, 30)]), + false, + ).unwrap(); + + assert_eq_uvec!(winners, vec![2, 3]); + assert_eq_uvec!( + assignments, + vec![ + (10, vec![(2, ACCURACY)]), + (20, vec![(3, ACCURACY)]), + (30, vec![(2, ACCURACY/2), (3, ACCURACY/2)]), + ] + ); +} + +#[test] +fn phragmen_poc_2_works() { + let candidates = vec![10, 20, 30]; + let voters = vec![ + (2, vec![10, 20, 30]), + (4, vec![10, 20, 40]), + ]; + let stake_of = create_stake_of(&[ + (10, 1000), + (20, 1000), + (30, 1000), + (40, 1000), + (2, 500), + (4, 500), + ]); + + run_and_compare(candidates, voters, stake_of, 2, 2, true); +} + +#[test] +fn phragmen_poc_3_works() { + let candidates = vec![10, 20, 30]; + let voters = vec![ + (2, vec![10, 20, 30]), + (4, vec![10, 20, 40]), + ]; + let stake_of = create_stake_of(&[ + (10, 1000), + (20, 1000), + (30, 1000), + (2, 50), + (4, 1000), + ]); + + run_and_compare(candidates, voters, stake_of, 2, 2, true); +} diff --git a/srml/staking/Cargo.toml b/srml/staking/Cargo.toml index 93de95caa2..092bcfda8e 100644 --- a/srml/staking/Cargo.toml +++ b/srml/staking/Cargo.toml @@ -23,11 +23,9 @@ authorship = { package = "srml-authorship", path = "../authorship", default-feat primitives = { package = "substrate-primitives", path = "../../core/primitives" } balances = { package = "srml-balances", path = "../balances" } timestamp = { package = "srml-timestamp", path = "../timestamp" } -rand = "0.6.5" [features] equalize = [] -bench = [] default = ["std", "equalize"] std = [ "serde", diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index 3a77e89223..dbd265b263 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -243,22 +243,14 @@ #![recursion_limit="128"] #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(all(feature = "bench", test), feature(test))] -#[cfg(all(feature = "bench", test))] -extern crate test; - -#[cfg(any(feature = "bench", test))] +#[cfg(test)] mod mock; - #[cfg(test)] mod tests; pub mod inflation; -#[cfg(all(feature = "bench", test))] -mod benches; - use rstd::{prelude::*, result}; use codec::{HasCompact, Encode, Decode}; use support::{ @@ -1295,7 +1287,7 @@ impl Module { if cfg!(feature = "equalize") { let tolerance = 0_u128; let iterations = 2_usize; - equalize::<_, _, T::CurrencyToVote, _>( + equalize::<_, _, _, T::CurrencyToVote>( assignments, &mut supports, tolerance, diff --git a/srml/staking/src/tests.rs b/srml/staking/src/tests.rs index 2f3f94bfbf..d754cd8500 100644 --- a/srml/staking/src/tests.rs +++ b/srml/staking/src/tests.rs @@ -1307,7 +1307,7 @@ fn phragmen_poc_works() { // 40 has load 0 and supported // 40 with stake 0 - // Sequential Phragmén with post processing gives + // Sequential Phragmén with post processing gives // 10 is elected with stake 1500.0 and score 0.0005 // 20 is elected with stake 1500.0 and score 0.00075 // @@ -1410,58 +1410,6 @@ fn phragmen_poc_works() { }); } -#[test] -fn phragmen_poc_2_works() { - // tests the encapsulated phragmen::elect function. - // Votes [ - // ('10', 1000, ['10']), - // ('20', 1000, ['20']), - // ('30', 1000, ['30']), - // ('2', 50, ['10', '20']), - // ('4', 1000, ['10', '30']) - // ] - // Sequential Phragmén gives - // 10 is elected with stake 1705.7377049180327 and score 0.0004878048780487805 - // 30 is elected with stake 1344.2622950819673 and score 0.0007439024390243903 - with_externalities(&mut ExtBuilder::default().nominate(false).build(), || { - // initial setup of 10 and 20, both validators - assert_eq_uvec!(validator_controllers(), vec![20, 10]); - - // Bond [30, 31] as the third validator - assert_ok!(Staking::bond_extra(Origin::signed(31), 999)); - assert_ok!(Staking::validate(Origin::signed(30), ValidatorPrefs::default())); - - // bond [2,1](A), [4,3](B), as 2 nominators - for i in &[1, 3] { let _ = Balances::deposit_creating(i, 2000); } - - assert_ok!(Staking::bond(Origin::signed(1), 2, 50, RewardDestination::default())); - assert_ok!(Staking::nominate(Origin::signed(2), vec![11, 21])); - - assert_ok!(Staking::bond(Origin::signed(3), 4, 1000, RewardDestination::default())); - assert_ok!(Staking::nominate(Origin::signed(4), vec![11, 31])); - - let results = phragmen::elect::<_, _, _, ::CurrencyToVote>( - 2, - Staking::minimum_validator_count() as usize, - >::enumerate().map(|(who, _)| who).collect::>(), - >::enumerate().collect(), - Staking::slashable_balance_of, - true, - ); - - let phragmen::PhragmenResult { winners, assignments } = results.unwrap(); - - // 10 and 30 must be the winners - assert_eq!(winners, vec![11, 31]); - assert_eq!(assignments, vec![ - (3, vec![(11, 2816371998), (31, 1478595298)]), - (1, vec![(11, 4294967296)]), - ]); - check_exposure_all(); - check_nominator_all(); - }) -} - #[test] fn switching_roles() { // Test that it should be possible to switch between roles (nominator, validator, idle) with minimal overhead. -- GitLab From 2fc627d4abdf223d56e90aa0394cc63fda35a4f7 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Fri, 13 Sep 2019 08:52:52 +0200 Subject: [PATCH 091/275] Fix Staking and Democracy locking (#3606) * Fix locking. * Some reformattings. * Fix build. * Fix doc comment. * Bump. --- node/runtime/src/lib.rs | 4 +- srml/elections/src/lib.rs | 2009 +++-------------------------------- srml/elections/src/mock.rs | 294 +++++ srml/elections/src/tests.rs | 1664 +++++++++++++++++++++++++++++ srml/im-online/src/lib.rs | 2 +- srml/staking/src/lib.rs | 4 +- 6 files changed, 2091 insertions(+), 1886 deletions(-) create mode 100644 srml/elections/src/mock.rs create mode 100644 srml/elections/src/tests.rs diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 562dea598f..05f5798836 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 157, - impl_version: 157, + impl_version: 158, apis: RUNTIME_API_VERSIONS, }; @@ -293,6 +293,7 @@ parameter_types! { pub const CandidacyBond: Balance = 10 * DOLLARS; pub const VotingBond: Balance = 1 * DOLLARS; pub const VotingFee: Balance = 2 * DOLLARS; + pub const MinimumVotingLock: Balance = 1 * DOLLARS; pub const PresentSlashPerVoter: Balance = 1 * CENTS; pub const CarryCount: u32 = 6; // one additional vote should go by before an inactive voter can be reaped. @@ -312,6 +313,7 @@ impl elections::Trait for Runtime { type CandidacyBond = CandidacyBond; type VotingBond = VotingBond; type VotingFee = VotingFee; + type MinimumVotingLock = MinimumVotingLock; type PresentSlashPerVoter = PresentSlashPerVoter; type CarryCount = CarryCount; type InactiveGracePeriod = InactiveGracePeriod; diff --git a/srml/elections/src/lib.rs b/srml/elections/src/lib.rs index 64b1e9e1db..2ebdbade0c 100644 --- a/srml/elections/src/lib.rs +++ b/srml/elections/src/lib.rs @@ -38,6 +38,9 @@ use support::{ use codec::{Encode, Decode}; use system::{self, ensure_signed, ensure_root}; +mod mock; +mod tests; + // no polynomial attacks: // // all unbonded public operations should be constant time. @@ -126,19 +129,23 @@ pub enum CellStatus { const MODULE_ID: LockIdentifier = *b"py/elect"; +/// Number of voters grouped in one chunk. pub const VOTER_SET_SIZE: usize = 64; +/// NUmber of approvals grouped in one chunk. pub const APPROVAL_SET_SIZE: usize = 8; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +/// Index used to access chunks. type SetIndex = u32; +/// Index used to count voting rounds. pub type VoteIndex = u32; - -// all three must be in sync. +/// Underlying data type of the approvals. type ApprovalFlag = u32; -pub const APPROVAL_FLAG_LEN: usize = 32; +/// Number of approval flags that can fit into [`ApprovalFlag`] type. +const APPROVAL_FLAG_LEN: usize = 32; pub trait Trait: system::Trait { type Event: From> + Into<::Event>; @@ -174,6 +181,9 @@ pub trait Trait: system::Trait { /// _hole_ index and replace it. type VotingFee: Get>; + /// Minimum about that can be used as the locked value for voting. + type MinimumVotingLock: Get>; + /// The punishment, per voter, if you provide an invalid presentation. A /// reasonable default value is 1. type PresentSlashPerVoter: Get>; @@ -202,6 +212,7 @@ pub trait Trait: system::Trait { decl_storage! { trait Store for Module as Council { // ---- parameters + /// How long to give each top candidate to present themselves after the vote ends. pub PresentationDuration get(presentation_duration) config(): T::BlockNumber; /// How long each position is active for. @@ -210,23 +221,24 @@ decl_storage! { pub DesiredSeats get(desired_seats) config(): u32; // ---- permanent state (always relevant, changes only at the finalization of voting) - /// The current membership. When there's a vote going on, this should still be used for executive - /// matters. The block number (second element in the tuple) is the block that their position is - /// active until (calculated by the sum of the block number when the member was elected - /// and their term duration). + + /// The current membership. When there's a vote going on, this should still be used for + /// executive matters. The block number (second element in the tuple) is the block that + /// their position is active until (calculated by the sum of the block number when the + /// member was elected and their term duration). pub Members get(members) config(): Vec<(T::AccountId, T::BlockNumber)>; /// The total number of vote rounds that have happened or are in progress. pub VoteCount get(vote_index): VoteIndex; // ---- persistent state (always relevant, changes constantly) - /// A list of votes for each voter. The votes are stored as numeric values and parsed in a bit-wise manner. - /// - /// In order to get a human-readable representation (`Vec`), use [`all_approvals_of`]. - /// - /// Furthermore, each vector of scalars is chunked with the cap of `APPROVAL_SET_SIZE`. + + // A list of votes for each voter. The votes are stored as numeric values and parsed in a + // bit-wise manner. In order to get a human-readable representation (`Vec`), use + // [`all_approvals_of`]. Furthermore, each vector of scalars is chunked with the cap of + // `APPROVAL_SET_SIZE`. pub ApprovalsOf get(approvals_of): map (T::AccountId, SetIndex) => Vec; - /// The vote index and list slot that the candidate `who` was registered or `None` if they are not - /// currently registered. + /// The vote index and list slot that the candidate `who` was registered or `None` if they + /// are not currently registered. pub RegisterInfoOf get(candidate_reg_info): map T::AccountId => Option<(VoteIndex, u32)>; /// Basic information about a voter. pub VoterInfoOf get(voter_info): map T::AccountId => Option>>; @@ -242,11 +254,13 @@ decl_storage! { pub CandidateCount get(candidate_count): u32; // ---- temporary state (only relevant during finalization/presentation) + /// The accounts holding the seats that will become free on the next tally. pub NextFinalize get(next_finalize): Option<(T::BlockNumber, u32, Vec)>; - /// Get the leaderboard if we're in the presentation phase. The first element is the weight of each entry; - /// It may be the direct summed approval stakes, or a weighted version of it. - pub Leaderboard get(leaderboard): Option, T::AccountId)> >; // ORDERED low -> high + /// Get the leaderboard if we're in the presentation phase. The first element is the weight + /// of each entry; It may be the direct summed approval stakes, or a weighted version of it. + /// Sorted from low to high. + pub Leaderboard get(leaderboard): Option, T::AccountId)> >; /// Who is able to vote for whom. Value is the fund-holding account, key is the /// vote-transaction-sending account. @@ -284,6 +298,9 @@ decl_module! { /// is 1000. const VotingPeriod: T::BlockNumber = T::VotingPeriod::get(); + /// Minimum about that can be used as the locked value for voting. + const MinimumVotingLock: BalanceOf = T::MinimumVotingLock::get(); + /// Decay factor of weight when being accumulated. It should typically be set to /// __at least__ `membership_size -1` to keep the collective secure. /// When set to `N`, it indicates `(1/N)^t` of staked is decayed at weight @@ -301,21 +318,21 @@ decl_module! { /// Set candidate approvals. Approval slots stay valid as long as candidates in those slots /// are registered. /// - /// Locks the total balance of caller indefinitely. - /// Only [`retract_voter`] or [`reap_inactive_voter`] can unlock the balance. + /// Locks `value` from the balance of `origin` indefinitely. Only [`retract_voter`] or + /// [`reap_inactive_voter`] can unlock the balance. /// /// `hint` argument is interpreted differently based on: - /// - if `origin` is setting approvals for the first time: The index will be checked - /// for being a valid _hole_ in the voter list. + /// - if `origin` is setting approvals for the first time: The index will be checked for + /// being a valid _hole_ in the voter list. /// - if the hint is correctly pointing to a hole, no fee is deducted from `origin`. - /// - Otherwise, the call will succeed but the index is ignored and simply a push to the last chunk - /// with free space happens. If the new push causes a new chunk to be created, a fee indicated by - /// [`VotingFee`] is deducted. + /// - Otherwise, the call will succeed but the index is ignored and simply a push to the + /// last chunk with free space happens. If the new push causes a new chunk to be + /// created, a fee indicated by [`VotingFee`] is deducted. /// - if `origin` is already a voter: the index __must__ be valid and point to the correct - /// position of the `origin` in the current voters list. + /// position of the `origin` in the current voters list. /// - /// Note that any trailing `false` votes in `votes` is ignored; In approval voting, not voting for a candidate - /// and voting false, are equal. + /// Note that any trailing `false` votes in `votes` is ignored; In approval voting, not + /// voting for a candidate and voting false, are equal. /// /// # /// - O(1). @@ -323,13 +340,19 @@ decl_module! { /// - Argument `votes` is limited in length to number of candidates. /// # #[weight = SimpleDispatchInfo::FixedNormal(2_500_000)] - fn set_approvals(origin, votes: Vec, #[compact] index: VoteIndex, hint: SetIndex) -> Result { + fn set_approvals( + origin, + votes: Vec, + #[compact] index: VoteIndex, + hint: SetIndex, + value: BalanceOf + ) -> Result { let who = ensure_signed(origin)?; - Self::do_set_approvals(who, votes, index, hint) + Self::do_set_approvals(who, votes, index, hint, value) } - /// Set candidate approvals from a proxy. Approval slots stay valid as long as candidates in those slots - /// are registered. + /// Set candidate approvals from a proxy. Approval slots stay valid as long as candidates in + /// those slots are registered. /// /// # /// - Same as `set_approvals` with one additional storage read. @@ -338,15 +361,16 @@ decl_module! { fn proxy_set_approvals(origin, votes: Vec, #[compact] index: VoteIndex, - hint: SetIndex + hint: SetIndex, + value: BalanceOf ) -> Result { let who = Self::proxy(ensure_signed(origin)?).ok_or("not a proxy")?; - Self::do_set_approvals(who, votes, index, hint) + Self::do_set_approvals(who, votes, index, hint, value) } /// Remove a voter. For it not to be a bond-consuming no-op, all approved candidate indices - /// must now be either unregistered or registered to a candidate that registered the slot after - /// the voter gave their last approval set. + /// must now be either unregistered or registered to a candidate that registered the slot + /// after the voter gave their last approval set. /// /// Both indices must be provided as explained in [`voter_at`] function. /// @@ -370,7 +394,8 @@ decl_module! { ensure!(!Self::presentation_active(), "cannot reap during presentation period"); ensure!(Self::voter_info(&reporter).is_some(), "reporter must be a voter"); - let info = Self::voter_info(&who).ok_or("target for inactivity cleanup must be active")?; + let info = Self::voter_info(&who) + .ok_or("target for inactivity cleanup must be active")?; let last_active = info.last_active; ensure!(assumed_vote_index == Self::vote_index(), "vote index not current"); @@ -409,8 +434,8 @@ decl_module! { ); if valid { - // This only fails if `reporter` doesn't exist, which it clearly must do since its the origin. - // Still, it's no more harmful to propagate any error at this point. + // This only fails if `reporter` doesn't exist, which it clearly must do since its + // the origin. Still, it's no more harmful to propagate any error at this point. T::Currency::repatriate_reserved(&who, &reporter, T::VotingBond::get())?; Self::deposit_event(RawEvent::VoterReaped(who, reporter)); } else { @@ -486,9 +511,10 @@ decl_module! { CandidateCount::put(count as u32 + 1); } - /// Claim that `signed` is one of the top Self::carry_count() + current_vote().1 candidates. - /// Only works if the `block_number >= current_vote().0` and `< current_vote().0 + presentation_duration()` - /// `signed` should have at least + /// Claim that `candidate` is one of the top `carry_count + desired_seats` candidates. Only + /// works iff the presentation period is active. `candidate` should have at least collected + /// some non-zero `total` votes and `origin` must have enough funds to pay for a potential + /// slash. /// /// # /// - O(voters) compute. @@ -509,7 +535,8 @@ decl_module! { let candidate = T::Lookup::lookup(candidate)?; ensure!(index == Self::vote_index(), "index not current"); - let (_, _, expiring) = Self::next_finalize().ok_or("cannot present outside of presentation period")?; + let (_, _, expiring) = Self::next_finalize() + .ok_or("cannot present outside of presentation period")?; let bad_presentation_punishment = T::PresentSlashPerVoter::get() * BalanceOf::::from(Self::voter_count() as u32); @@ -518,11 +545,15 @@ decl_module! { "presenter must have sufficient slashable funds" ); - let mut leaderboard = Self::leaderboard().ok_or("leaderboard must exist while present phase active")?; + let mut leaderboard = Self::leaderboard() + .ok_or("leaderboard must exist while present phase active")?; ensure!(total > leaderboard[0].0, "candidate not worthy of leaderboard"); if let Some(p) = Self::members().iter().position(|&(ref c, _)| c == &candidate) { - ensure!(p < expiring.len(), "candidate must not form a duplicated member if elected"); + ensure!( + p < expiring.len(), + "candidate must not form a duplicated member if elected" + ); } let voters = Self::all_voters(); @@ -671,8 +702,8 @@ impl Module { } else { // next tally begins once enough members expire to bring members below desired. if desired_seats <= coming { - // the entire amount of desired seats is less than those new members - we'll have - // to wait until they expire. + // the entire amount of desired seats is less than those new members - we'll + // have to wait until they expire. Some(next_possible + Self::term_duration()) } else { Some(c[c.len() - (desired_seats - coming) as usize].1) @@ -713,19 +744,33 @@ impl Module { /// Actually do the voting. /// /// The voter index must be provided as explained in [`voter_at`] function. - fn do_set_approvals(who: T::AccountId, votes: Vec, index: VoteIndex, hint: SetIndex) -> Result { + fn do_set_approvals( + who: T::AccountId, + votes: Vec, + index: VoteIndex, + hint: SetIndex, + value: BalanceOf, + ) -> Result { let candidates_len = ::Candidates::decode_len().unwrap_or(0_usize); ensure!(!Self::presentation_active(), "no approval changes during presentation period"); ensure!(index == Self::vote_index(), "incorrect vote index"); - ensure!(!candidates_len.is_zero(), "amount of candidates to receive approval votes should be non-zero"); - // Prevent a vote from voters that provide a list of votes that exceeds the candidates length - // since otherwise an attacker may be able to submit a very long list of `votes` that far exceeds - // the amount of candidates and waste more computation than a reasonable voting bond would cover. - ensure!(candidates_len >= votes.len(), "amount of candidate votes cannot exceed amount of candidates"); + ensure!( + !candidates_len.is_zero(), + "amount of candidates to receive approval votes should be non-zero" + ); + // Prevent a vote from voters that provide a list of votes that exceeds the candidates + // length since otherwise an attacker may be able to submit a very long list of `votes` that + // far exceeds the amount of candidates and waste more computation than a reasonable voting + // bond would cover. + ensure!( + candidates_len >= votes.len(), + "amount of candidate votes cannot exceed amount of candidates" + ); + ensure!(value >= T::MinimumVotingLock::get(), "locked value must be more than limit"); // Amount to be locked up. - let mut locked_balance = T::Currency::total_balance(&who); + let mut locked_balance = value.min(T::Currency::total_balance(&who)); let mut pot_to_set = Zero::zero(); let hint = hint as usize; @@ -785,7 +830,7 @@ impl Module { &who, locked_balance, T::BlockNumber::max_value(), - WithdrawReasons::except(WithdrawReason::TransactionPayment), + WithdrawReasons::all(), ); >::insert( @@ -807,11 +852,14 @@ impl Module { let members = Self::members(); let desired_seats = Self::desired_seats() as usize; let number = >::block_number(); - let expiring = members.iter().take_while(|i| i.1 <= number).map(|i| i.0.clone()).collect::>(); + let expiring = + members.iter().take_while(|i| i.1 <= number).map(|i| i.0.clone()).collect::>(); let retaining_seats = members.len() - expiring.len(); if retaining_seats < desired_seats { let empty_seats = desired_seats - retaining_seats; - >::put((number + Self::presentation_duration(), empty_seats as u32, expiring)); + >::put( + (number + Self::presentation_duration(), empty_seats as u32, expiring) + ); // initialize leaderboard. let leaderboard_size = empty_seats + T::CarryCount::get() as usize; @@ -821,14 +869,16 @@ impl Module { } } - /// Finalize the vote, removing each of the `removals` and inserting `seats` of the most approved - /// candidates in their place. If the total number of members is less than the desired membership - /// a new vote is started. - /// Clears all presented candidates, returning the bond of the elected ones. + /// Finalize the vote, removing each of the `removals` and inserting `seats` of the most + /// approved candidates in their place. If the total number of members is less than the desired + /// membership a new vote is started. Clears all presented candidates, returning the bond of the + /// elected ones. fn finalize_tally() -> Result { let (_, coming, expiring): (T::BlockNumber, u32, Vec) = - >::take().ok_or("finalize can only be called after a tally is started.")?; - let leaderboard: Vec<(BalanceOf, T::AccountId)> = >::take().unwrap_or_default(); + >::take() + .ok_or("finalize can only be called after a tally is started.")?; + let leaderboard: Vec<(BalanceOf, T::AccountId)> = >::take() + .unwrap_or_default(); let new_expiry = >::block_number() + Self::term_duration(); // return bond to winners. @@ -898,9 +948,11 @@ impl Module { } } // discard any superfluous slots. - if let Some(last_index) = new_candidates.iter().rposition(|c| *c != T::AccountId::default()) { - new_candidates.truncate(last_index + 1); - } + if let Some(last_index) = new_candidates + .iter() + .rposition(|c| *c != T::AccountId::default()) { + new_candidates.truncate(last_index + 1); + } Self::deposit_event(RawEvent::TallyFinalized(incoming, outgoing)); @@ -954,8 +1006,8 @@ impl Module { } } - /// A more sophisticated version of `voter_at`. Will be kept separate as most often it is an overdue - /// compared to `voter_at`. Only used when setting approvals. + /// A more sophisticated version of `voter_at`. Will be kept separate as most often it is an + /// overdue compared to `voter_at`. Only used when setting approvals. fn cell_status(set_index: SetIndex, vec_index: usize) -> CellStatus { let set = Self::voters(set_index); if vec_index < set.len() { @@ -975,13 +1027,15 @@ impl Module { approvals_flag_vec .chunks(APPROVAL_SET_SIZE) .enumerate() - .for_each(|(index, slice)| >::insert((who.clone(), index as SetIndex), slice.to_vec())); + .for_each(|(index, slice)| >::insert( + (who.clone(), index as SetIndex), slice.to_vec()) + ); } /// shorthand for fetching a specific approval of a voter at a specific (global) index. /// - /// Using this function to read a vote is preferred as it reads `APPROVAL_SET_SIZE` items of type - /// `ApprovalFlag` from storage at most; not all of them. + /// Using this function to read a vote is preferred as it reads `APPROVAL_SET_SIZE` items of + /// type `ApprovalFlag` from storage at most; not all of them. /// /// Note that false is returned in case of no-vote or an explicit `false`. fn approvals_of_at(who: &T::AccountId, index: usize) -> bool { @@ -1035,7 +1089,9 @@ impl Module { let mut result = Vec::with_capacity(chunk.len()); if chunk.is_empty() { return vec![] } chunk.into_iter() - .map(|num| (0..APPROVAL_FLAG_LEN).map(|bit| Self::bit_at(num, bit)).collect::>()) + .map(|num| + (0..APPROVAL_FLAG_LEN).map(|bit| Self::bit_at(num, bit)).collect::>() + ) .for_each(|c| { let last_approve = match c.iter().rposition(|n| *n) { Some(index) => index + 1, @@ -1097,1814 +1153,3 @@ impl Module { r } } - -#[cfg(test)] -mod tests { - use super::*; - use std::cell::RefCell; - use support::{assert_ok, assert_err, assert_noop, parameter_types}; - use runtime_io::with_externalities; - use primitives::{H256, Blake2Hasher}; - use sr_primitives::{ - Perbill, traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, testing::Header, BuildStorage - }; - use crate as elections; - - parameter_types! { - pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); - } - impl system::Trait for Test { - type Origin = Origin; - type Index = u64; - type BlockNumber = u64; - type Call = (); - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; - type Header = Header; - type Event = Event; - type WeightMultiplierUpdate = (); - type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; - type Version = (); - } - parameter_types! { - pub const ExistentialDeposit: u64 = 0; - pub const TransferFee: u64 = 0; - pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 0; - pub const TransactionByteFee: u64 = 0; - } - impl balances::Trait for Test { - type Balance = u64; - type OnNewAccount = (); - type OnFreeBalanceZero = (); - type Event = Event; - type TransactionPayment = (); - type TransferPayment = (); - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type TransferFee = TransferFee; - type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = (); - } - parameter_types! { - pub const CandidacyBond: u64 = 3; - pub const CarryCount: u32 = 2; - pub const InactiveGracePeriod: u32 = 1; - pub const VotingPeriod: u64 = 4; - } - - thread_local! { - static VOTER_BOND: RefCell = RefCell::new(0); - static VOTING_FEE: RefCell = RefCell::new(0); - static PRESENT_SLASH_PER_VOTER: RefCell = RefCell::new(0); - static DECAY_RATIO: RefCell = RefCell::new(0); - static MEMBERS: RefCell> = RefCell::new(vec![]); - } - - pub struct VotingBond; - impl Get for VotingBond { - fn get() -> u64 { VOTER_BOND.with(|v| *v.borrow()) } - } - - pub struct VotingFee; - impl Get for VotingFee { - fn get() -> u64 { VOTING_FEE.with(|v| *v.borrow()) } - } - - pub struct PresentSlashPerVoter; - impl Get for PresentSlashPerVoter { - fn get() -> u64 { PRESENT_SLASH_PER_VOTER.with(|v| *v.borrow()) } - } - - pub struct DecayRatio; - impl Get for DecayRatio { - fn get() -> u32 { DECAY_RATIO.with(|v| *v.borrow()) } - } - - pub struct TestChangeMembers; - impl ChangeMembers for TestChangeMembers { - fn change_members_sorted(incoming: &[u64], outgoing: &[u64], new: &[u64]) { - let mut old_plus_incoming = MEMBERS.with(|m| m.borrow().to_vec()); - old_plus_incoming.extend_from_slice(incoming); - old_plus_incoming.sort(); - let mut new_plus_outgoing = new.to_vec(); - new_plus_outgoing.extend_from_slice(outgoing); - new_plus_outgoing.sort(); - assert_eq!(old_plus_incoming, new_plus_outgoing); - - MEMBERS.with(|m| *m.borrow_mut() = new.to_vec()); - } - } - - impl Trait for Test { - type Event = Event; - type Currency = Balances; - type BadPresentation = (); - type BadReaper = (); - type BadVoterIndex = (); - type LoserCandidate = (); - type ChangeMembers = TestChangeMembers; - type CandidacyBond = CandidacyBond; - type VotingBond = VotingBond; - type VotingFee = VotingFee; - type PresentSlashPerVoter = PresentSlashPerVoter; - type CarryCount = CarryCount; - type InactiveGracePeriod = InactiveGracePeriod; - type VotingPeriod = VotingPeriod; - type DecayRatio = DecayRatio; - } - - pub type Block = sr_primitives::generic::Block; - pub type UncheckedExtrinsic = sr_primitives::generic::UncheckedExtrinsic; - - support::construct_runtime!( - pub enum Test where - Block = Block, - NodeBlock = Block, - UncheckedExtrinsic = UncheckedExtrinsic - { - System: system::{Module, Call, Event}, - Balances: balances::{Module, Call, Event, Config, Error}, - Elections: elections::{Module, Call, Event, Config}, - } - ); - - pub struct ExtBuilder { - balance_factor: u64, - decay_ratio: u32, - desired_seats: u32, - voting_fee: u64, - voter_bond: u64, - bad_presentation_punishment: u64, - } - - impl Default for ExtBuilder { - fn default() -> Self { - Self { - balance_factor: 1, - decay_ratio: 24, - desired_seats: 2, - voting_fee: 0, - voter_bond: 0, - bad_presentation_punishment: 1, - } - } - } - - impl ExtBuilder { - pub fn balance_factor(mut self, factor: u64) -> Self { - self.balance_factor = factor; - self - } - pub fn decay_ratio(mut self, ratio: u32) -> Self { - self.decay_ratio = ratio; - self - } - pub fn voting_fee(mut self, fee: u64) -> Self { - self.voting_fee = fee; - self - } - pub fn bad_presentation_punishment(mut self, fee: u64) -> Self { - self.bad_presentation_punishment = fee; - self - } - pub fn voter_bond(mut self, fee: u64) -> Self { - self.voter_bond = fee; - self - } - pub fn desired_seats(mut self, seats: u32) -> Self { - self.desired_seats = seats; - self - } - pub fn build(self) -> runtime_io::TestExternalities { - VOTER_BOND.with(|v| *v.borrow_mut() = self.voter_bond); - VOTING_FEE.with(|v| *v.borrow_mut() = self.voting_fee); - PRESENT_SLASH_PER_VOTER.with(|v| *v.borrow_mut() = self.bad_presentation_punishment); - DECAY_RATIO.with(|v| *v.borrow_mut() = self.decay_ratio); - GenesisConfig { - balances: Some(balances::GenesisConfig::{ - balances: vec![ - (1, 10 * self.balance_factor), - (2, 20 * self.balance_factor), - (3, 30 * self.balance_factor), - (4, 40 * self.balance_factor), - (5, 50 * self.balance_factor), - (6, 60 * self.balance_factor) - ], - vesting: vec![], - }), - elections: Some(elections::GenesisConfig::{ - members: vec![], - desired_seats: self.desired_seats, - presentation_duration: 2, - term_duration: 5, - }), - }.build_storage().unwrap().into() - } - } - - fn voter_ids() -> Vec { - Elections::all_voters().iter().map(|v| v.unwrap_or(0) ).collect::>() - } - - fn vote(i: u64, l: usize) { - let _ = Balances::make_free_balance_be(&i, 20); - assert_ok!(Elections::set_approvals(Origin::signed(i), (0..l).map(|_| true).collect::>(), 0, 0)); - } - - fn vote_at(i: u64, l: usize, index: VoteIndex) { - let _ = Balances::make_free_balance_be(&i, 20); - assert_ok!(Elections::set_approvals(Origin::signed(i), (0..l).map(|_| true).collect::>(), 0, index)); - } - - fn create_candidate(i: u64, index: u32) { - let _ = Balances::make_free_balance_be(&i, 20); - assert_ok!(Elections::submit_candidacy(Origin::signed(i), index)); - } - - fn bond() -> u64 { - ::VotingBond::get() - } - - fn balances(who: &u64) -> (u64, u64) { - (Balances::free_balance(who), Balances::reserved_balance(who)) - } - - #[test] - fn bool_to_flag_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - assert_eq!(Elections::bool_to_flag(vec![]), vec![]); - assert_eq!(Elections::bool_to_flag(vec![false]), vec![0]); - assert_eq!(Elections::bool_to_flag(vec![true]), vec![1]); - assert_eq!(Elections::bool_to_flag(vec![true, true, true, true]), vec![15]); - assert_eq!(Elections::bool_to_flag(vec![true, true, true, true, true]), vec![15 + 16]); - - let set_1 = vec![ - true, false, false, false, // 0x1 - false, true, true, true, // 0xE - ]; - assert_eq!( - Elections::bool_to_flag(set_1.clone()), - vec![0x00_00_00_E1_u32] - ); - assert_eq!( - Elections::flag_to_bool(vec![0x00_00_00_E1_u32]), - set_1 - ); - - let set_2 = vec![ - false, false, false, true, // 0x8 - false, true, false, true, // 0xA - ]; - assert_eq!( - Elections::bool_to_flag(set_2.clone()), - vec![0x00_00_00_A8_u32] - ); - assert_eq!( - Elections::flag_to_bool(vec![0x00_00_00_A8_u32]), - set_2 - ); - - let mut rhs = (0..100/APPROVAL_FLAG_LEN).map(|_| 0xFFFFFFFF_u32).collect::>(); - // NOTE: this might be need change based on `APPROVAL_FLAG_LEN`. - rhs.extend(vec![0x00_00_00_0F]); - assert_eq!( - Elections::bool_to_flag((0..100).map(|_| true).collect()), - rhs - ) - }) - } - - #[test] - fn params_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - assert_eq!(Elections::next_vote_from(1), 4); - assert_eq!(Elections::next_vote_from(4), 4); - assert_eq!(Elections::next_vote_from(5), 8); - assert_eq!(Elections::vote_index(), 0); - assert_eq!(Elections::presentation_duration(), 2); - assert_eq!(Elections::term_duration(), 5); - assert_eq!(Elections::desired_seats(), 2); - - assert_eq!(Elections::members(), vec![]); - assert_eq!(Elections::next_tally(), Some(4)); - assert_eq!(Elections::presentation_active(), false); - assert_eq!(Elections::next_finalize(), None); - - assert_eq!(Elections::candidates(), Vec::::new()); - assert_eq!(Elections::is_a_candidate(&1), false); - assert_eq!(Elections::candidate_reg_info(1), None); - - assert_eq!(Elections::voters(0), Vec::>::new()); - assert_eq!(Elections::voter_info(1), None); - assert_eq!(Elections::all_approvals_of(&1), vec![]); - }); - } - - #[test] - fn voter_set_growth_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); - - // create 65. 64 (set0) + 1 (set1) - (1..=63).for_each(|i| vote(i, 2)); - assert_eq!(Elections::next_nonfull_voter_set(), 0); - vote(64, 2); - assert_eq!(Elections::next_nonfull_voter_set(), 1); - vote(65, 2); - - let set1 = Elections::voters(0); - let set2 = Elections::voters(1); - - assert_eq!(set1.len(), 64); - assert_eq!(set2.len(), 1); - - assert_eq!(set1[0], Some(1)); - assert_eq!(set1[10], Some(11)); - assert_eq!(set2[0], Some(65)); - }) - } - - #[test] - fn voter_set_reclaim_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); - - (1..=129).for_each(|i| vote(i, 2)); - assert_eq!(Elections::next_nonfull_voter_set(), 2); - - assert_ok!(Elections::retract_voter(Origin::signed(11), 10)); - - assert_ok!(Elections::retract_voter(Origin::signed(66), 65)); - assert_ok!(Elections::retract_voter(Origin::signed(67), 66)); - - // length does not show it but holes do exist. - assert_eq!(Elections::voters(0).len(), 64); - assert_eq!(Elections::voters(1).len(), 64); - assert_eq!(Elections::voters(2).len(), 1); - - assert_eq!(Elections::voters(0)[10], None); - assert_eq!(Elections::voters(1)[1], None); - assert_eq!(Elections::voters(1)[2], None); - // Next set with capacity is 2. - assert_eq!(Elections::next_nonfull_voter_set(), 2); - - // But we can fill a hole. - vote_at(130, 2, 10); - - // Nothing added to set 2. A hole was filled. - assert_eq!(Elections::voters(0).len(), 64); - assert_eq!(Elections::voters(1).len(), 64); - assert_eq!(Elections::voters(2).len(), 1); - - // and the next two (scheduled) to the second set. - assert_eq!(Elections::next_nonfull_voter_set(), 2); - }) - } - - #[test] - fn approvals_set_growth_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - // create candidates and voters. - (1..=250).for_each(|i| create_candidate(i, (i-1) as u32)); - (1..=250).for_each(|i| vote(i, i as usize)); - - // all approvals of should return the exact expected vector. - assert_eq!(Elections::all_approvals_of(&180), (0..180).map(|_| true).collect::>()); - - assert_eq!(Elections::all_approvals_of(&32), (0..32).map(|_| true).collect::>()); - assert_eq!(Elections::all_approvals_of(&8), (0..8).map(|_| true).collect::>()); - assert_eq!(Elections::all_approvals_of(&64), (0..64).map(|_| true).collect::>()); - assert_eq!(Elections::all_approvals_of(&65), (0..65).map(|_| true).collect::>()); - assert_eq!(Elections::all_approvals_of(&63), (0..63).map(|_| true).collect::>()); - - // NOTE: assuming that APPROVAL_SET_SIZE is more or less small-ish. Might fail otherwise. - let full_sets = (180 / APPROVAL_FLAG_LEN) / APPROVAL_SET_SIZE; - let left_over = (180 / APPROVAL_FLAG_LEN) / APPROVAL_SET_SIZE; - let rem = 180 % APPROVAL_FLAG_LEN; - - // grab and check the last full set, if it exists. - if full_sets > 0 { - assert_eq!( - Elections::approvals_of((180, (full_sets-1) as SetIndex )), - Elections::bool_to_flag((0..APPROVAL_SET_SIZE * APPROVAL_FLAG_LEN).map(|_| true).collect::>()) - ); - } - - // grab and check the last, half-empty, set. - if left_over > 0 { - assert_eq!( - Elections::approvals_of((180, full_sets as SetIndex)), - Elections::bool_to_flag((0..left_over * APPROVAL_FLAG_LEN + rem).map(|_| true).collect::>()) - ); - } - }) - } - - - #[test] - fn cell_status_works() { - with_externalities(&mut ExtBuilder::default().build(), || { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); - - (1..=63).for_each(|i| vote(i, 2)); - - assert_ok!(Elections::retract_voter(Origin::signed(11), 10)); - assert_ok!(Elections::retract_voter(Origin::signed(21), 20)); - - assert_eq!(Elections::cell_status(0, 10), CellStatus::Hole); - assert_eq!(Elections::cell_status(0, 0), CellStatus::Occupied); - assert_eq!(Elections::cell_status(0, 20), CellStatus::Hole); - assert_eq!(Elections::cell_status(0, 63), CellStatus::Head); - assert_eq!(Elections::cell_status(1, 0), CellStatus::Head); - assert_eq!(Elections::cell_status(1, 10), CellStatus::Head); - }) - } - - #[test] - fn initial_set_approvals_ignores_voter_index() { - with_externalities(&mut ExtBuilder::default().build(), || { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - - // Last argument is essentially irrelevant. You might get or miss a tip. - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![true], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 5)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 0, 100)); - - // indices are more or less ignored. all is pushed. - assert_eq!(voter_ids(), vec![3, 4, 5]); - }) - } - - #[test] - fn bad_approval_index_slashes_voters_and_bond_reduces_stake() { - with_externalities(&mut ExtBuilder::default().voting_fee(5).voter_bond(2).build(), || { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); - - (1..=63).for_each(|i| vote(i, 2)); - assert_eq!(Balances::free_balance(&1), 20 - 5 - 2); // -5 fee -2 bond - assert_eq!(Balances::free_balance(&10), 20 - 2); - assert_eq!(Balances::free_balance(&60), 20 - 2); - - // still no fee - vote(64, 2); - assert_eq!(Balances::free_balance(&64), 20 - 2); // -2 bond - assert_eq!( - Elections::voter_info(&64).unwrap(), - VoterInfo { last_win: 0, last_active: 0, stake: 20, pot:0 } - ); - - assert_eq!(Elections::next_nonfull_voter_set(), 1); - - // now we charge the next voter. - vote(65, 2); - assert_eq!(Balances::free_balance(&65), 20 - 5 - 2); - assert_eq!( - Elections::voter_info(&65).unwrap(), - VoterInfo { last_win: 0, last_active: 0, stake: 15, pot:0 } - ); - }); - } - - #[test] - fn subsequent_set_approvals_checks_voter_index() { - with_externalities(&mut ExtBuilder::default().build(), || { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![true], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 5)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 0, 100)); - - // invalid index - assert_noop!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 5), "invalid voter index"); - // wrong index - assert_noop!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 0), "wrong voter index"); - // correct - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 1)); - }) - } - - #[test] - fn voter_index_does_not_take_holes_into_account() { - with_externalities(&mut ExtBuilder::default().build(), || { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); - - // create 65. 64 (set0) + 1 (set1) - (1..=65).for_each(|i| vote(i, 2)); - - // account 65 has global index 65. - assert_eq!(Elections::voter_at(64).unwrap(), 65); - - assert_ok!(Elections::retract_voter(Origin::signed(1), 0)); - assert_ok!(Elections::retract_voter(Origin::signed(2), 1)); - - // still the same. These holes are in some other set. - assert_eq!(Elections::voter_at(64).unwrap(), 65); - // proof: can submit a new approval with the old index. - assert_noop!(Elections::set_approvals(Origin::signed(65), vec![false, true], 0, 64 - 2), "wrong voter index"); - assert_ok!(Elections::set_approvals(Origin::signed(65), vec![false, true], 0, 64)); - }) - } - - #[test] - fn simple_candidate_submission_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - assert_eq!(Elections::candidates(), Vec::::new()); - assert_eq!(Elections::candidate_reg_info(1), None); - assert_eq!(Elections::candidate_reg_info(2), None); - assert_eq!(Elections::is_a_candidate(&1), false); - assert_eq!(Elections::is_a_candidate(&2), false); - - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_eq!(Elections::candidates(), vec![1]); - assert_eq!(Elections::candidate_reg_info(1), Some((0, 0))); - assert_eq!(Elections::candidate_reg_info(2), None); - assert_eq!(Elections::is_a_candidate(&1), true); - assert_eq!(Elections::is_a_candidate(&2), false); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_eq!(Elections::candidates(), vec![1, 2]); - assert_eq!(Elections::candidate_reg_info(1), Some((0, 0))); - assert_eq!(Elections::candidate_reg_info(2), Some((0, 1))); - assert_eq!(Elections::is_a_candidate(&1), true); - assert_eq!(Elections::is_a_candidate(&2), true); - }); - } - - fn new_test_ext_with_candidate_holes() -> runtime_io::TestExternalities { - let mut t = ExtBuilder::default().build(); - with_externalities(&mut t, || { - >::put(vec![0, 0, 1]); - CandidateCount::put(1); - >::insert(1, (0, 2)); - }); - t - } - - #[test] - fn candidate_submission_using_free_slot_should_work() { - let mut t = new_test_ext_with_candidate_holes(); - - with_externalities(&mut t, || { - System::set_block_number(1); - assert_eq!(Elections::candidates(), vec![0, 0, 1]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_eq!(Elections::candidates(), vec![0, 2, 1]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); - assert_eq!(Elections::candidates(), vec![3, 2, 1]); - }); - } - - #[test] - fn candidate_submission_using_alternative_free_slot_should_work() { - let mut t = new_test_ext_with_candidate_holes(); - - with_externalities(&mut t, || { - System::set_block_number(1); - assert_eq!(Elections::candidates(), vec![0, 0, 1]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_eq!(Elections::candidates(), vec![2, 0, 1]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); - assert_eq!(Elections::candidates(), vec![2, 3, 1]); - }); - } - - #[test] - fn candidate_submission_not_using_free_slot_should_not_work() { - let mut t = new_test_ext_with_candidate_holes(); - - with_externalities(&mut t, || { - System::set_block_number(1); - assert_noop!(Elections::submit_candidacy(Origin::signed(4), 3), "invalid candidate slot"); - }); - } - - #[test] - fn bad_candidate_slot_submission_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - assert_eq!(Elections::candidates(), Vec::::new()); - assert_noop!(Elections::submit_candidacy(Origin::signed(1), 1), "invalid candidate slot"); - }); - } - - #[test] - fn non_free_candidate_slot_submission_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - assert_eq!(Elections::candidates(), Vec::::new()); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_eq!(Elections::candidates(), vec![1]); - assert_noop!(Elections::submit_candidacy(Origin::signed(2), 0), "invalid candidate slot"); - }); - } - - #[test] - fn dupe_candidate_submission_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - assert_eq!(Elections::candidates(), Vec::::new()); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_eq!(Elections::candidates(), vec![1]); - assert_noop!(Elections::submit_candidacy(Origin::signed(1), 1), "duplicate candidate submission"); - }); - } - - #[test] - fn poor_candidate_submission_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - assert_eq!(Elections::candidates(), Vec::::new()); - assert_noop!(Elections::submit_candidacy(Origin::signed(7), 0), "candidate has not enough funds"); - }); - } - - #[test] - fn balance_should_lock_to_the_maximum() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - assert_eq!(Elections::candidates(), Vec::::new()); - assert_eq!(Balances::free_balance(&2), 20); - - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - - assert_eq!(Balances::free_balance(&2), 20 - bond() ); - assert_noop!(Balances::reserve(&2, 1), "account liquidity restrictions prevent withdrawal"); // locked. - - // deposit a bit more. - let _ = Balances::deposit_creating(&2, 100); - assert_ok!(Balances::reserve(&2, 1)); // locked but now has enough. - - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - assert_noop!(Balances::reserve(&2, 1), "account liquidity restrictions prevent withdrawal"); // locked. - assert_eq!(Balances::locks(&2).len(), 1); - assert_eq!(Balances::locks(&2)[0].amount, 100 + 20); - - assert_ok!(Elections::retract_voter(Origin::signed(2), 0)); - - assert_eq!(Balances::locks(&2).len(), 0); - assert_eq!(Balances::free_balance(&2), 120 - 1); // 1 ok call to .reserve() happened. - assert_ok!(Balances::reserve(&2, 1)); // unlocked. - }); - } - - #[test] - fn balance_should_lock_on_submit_approvals_unlock_on_retract() { - with_externalities(&mut ExtBuilder::default().voter_bond(8).voting_fee(0).build(), || { - System::set_block_number(1); - assert_eq!(Elections::candidates(), Vec::::new()); - assert_eq!(Balances::free_balance(&2), 20); - - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - - assert_eq!(Balances::free_balance(&2), 12); // 20 - 8 (bond) - assert_noop!(Balances::reserve(&2, 10), "account liquidity restrictions prevent withdrawal"); // locked. - - assert_ok!(Elections::retract_voter(Origin::signed(2), 0)); - - assert_eq!(Balances::free_balance(&2), 20); - assert_ok!(Balances::reserve(&2, 10)); // unlocked. - }); - } - - #[test] - fn accumulating_weight_and_decaying_should_work() { - with_externalities(&mut ExtBuilder::default().balance_factor(10).build(), || { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 2)); - - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![false, false, true], 0, 0)); - - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert!(Elections::presentation_active()); - - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100, 0), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100, 1), (500, 5), (600, 6)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 11), (5, 11)]); - assert_eq!(Elections::voter_info(6).unwrap(), VoterInfo { last_win: 1, last_active: 0, stake: 600, pot: 0}); - assert_eq!(Elections::voter_info(5).unwrap(), VoterInfo { last_win: 1, last_active: 0, stake: 500, pot: 0}); - assert_eq!(Elections::voter_info(1).unwrap(), VoterInfo { last_win: 0, last_active: 0, stake: 100, pot: 0}); - - System::set_block_number(12); - // retract needed to unlock approval funds => submit candidacy again. - assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); - assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 1, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 1, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(14); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 1), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 1), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100 + Elections::get_offset(100, 1), 1), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100 + 96, 1), (500, 5), (600, 6)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 19), (5, 19)]); - assert_eq!( - Elections::voter_info(6).unwrap(), - VoterInfo { last_win: 2, last_active: 1, stake: 600, pot:0 } - ); - assert_eq!(Elections::voter_info(5).unwrap(), VoterInfo { last_win: 2, last_active: 1, stake: 500, pot:0 }); - assert_eq!(Elections::voter_info(1).unwrap(), VoterInfo { last_win: 0, last_active: 0, stake: 100, pot:0 }); - - System::set_block_number(20); - assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); - assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 2, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 2, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(22); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 2), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 2), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100 + Elections::get_offset(100, 2), 2), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100 + 96 + 93, 1), (500, 5), (600, 6)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 27), (5, 27)]); - assert_eq!( - Elections::voter_info(6).unwrap(), - VoterInfo { last_win: 3, last_active: 2, stake: 600, pot: 0} - ); - assert_eq!(Elections::voter_info(5).unwrap(), VoterInfo { last_win: 3, last_active: 2, stake: 500, pot: 0}); - assert_eq!(Elections::voter_info(1).unwrap(), VoterInfo { last_win: 0, last_active: 0, stake: 100, pot: 0}); - - - System::set_block_number(28); - assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); - assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 3, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 3, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(30); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 3), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 3), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100 + Elections::get_offset(100, 3), 3), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100 + 96 + 93 + 90, 1), (500, 5), (600, 6)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 35), (5, 35)]); - assert_eq!( - Elections::voter_info(6).unwrap(), - VoterInfo { last_win: 4, last_active: 3, stake: 600, pot: 0} - ); - assert_eq!(Elections::voter_info(5).unwrap(), VoterInfo { last_win: 4, last_active: 3, stake: 500, pot: 0}); - assert_eq!(Elections::voter_info(1).unwrap(), VoterInfo { last_win: 0, last_active: 0, stake: 100, pot: 0}); - }) - } - - #[test] - fn winning_resets_accumulated_pot() { - with_externalities(&mut ExtBuilder::default().balance_factor(10).build(), || { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 3)); - - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, true, false, false], 0, 1)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true, true], 0, 2)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(4), 4, 400, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(3), 3, 300, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(2), 2, 300, 0), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(300, 2), (300, 3), (400, 4), (600, 6)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 11), (4, 11)]); - - System::set_block_number(12); - assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); - assert_ok!(Elections::retract_voter(Origin::signed(4), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false, false], 1, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, true, false, false], 1, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(14); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 1), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(4), 4, 400, 1), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(3), 3, 300 + Elections::get_offset(300, 1), 1), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(2), 2, 300 + Elections::get_offset(300, 1), 1), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(400, 4), (588, 2), (588, 3), (600, 6)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 19), (3, 19)]); - - System::set_block_number(20); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(22); - // 2 will not get re-elected with 300 + 288, instead just 300. - // because one of 3's candidates (3) won in previous round - // 4 on the other hand will get extra weight since it was unlucky. - assert_eq!(Elections::present_winner(Origin::signed(3), 2, 300, 2), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(4), 4, 400 + Elections::get_offset(400, 1), 2), Ok(())); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(4, 27), (2, 27)]); - }) - } - - #[test] - fn resubmitting_approvals_stores_pot() { - with_externalities(&mut ExtBuilder::default() - .voter_bond(0) - .voting_fee(0) - .balance_factor(10) - .build(), - || { System::set_block_number(4); - assert!(!Elections::presentation_active()); - - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 2)); - - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 0, 1)); - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![false, false, true], 0, 2)); - - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert!(Elections::presentation_active()); - - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100, 0), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100, 1), (500, 5), (600, 6)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 11), (5, 11)]); - - System::set_block_number(12); - assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); - assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 1, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 1, 1)); - // give 1 some new high balance - let _ = Balances::make_free_balance_be(&1, 997); - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![false, false, true], 1, 2)); - assert_eq!(Elections::voter_info(1).unwrap(), - VoterInfo { - stake: 1000, // 997 + 3 which is candidacy bond. - pot: Elections::get_offset(100, 1), - last_active: 1, - last_win: 1, - } - ); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 11), (5, 11)]); - - System::set_block_number(14); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 1), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 1), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(1), 1, 1000 + 96 /* pot */, 1), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (500, 5), (600, 6), (1096, 1)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(1, 19), (6, 19)]); - }) - } - - #[test] - fn get_offset_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - assert_eq!(Elections::get_offset(100, 0), 0); - assert_eq!(Elections::get_offset(100, 1), 96); - assert_eq!(Elections::get_offset(100, 2), 96 + 93); - assert_eq!(Elections::get_offset(100, 3), 96 + 93 + 90); - assert_eq!(Elections::get_offset(100, 4), 96 + 93 + 90 + 87); - // limit - assert_eq!(Elections::get_offset(100, 1000), 100 * 24); - - assert_eq!(Elections::get_offset(50_000_000_000, 0), 0); - assert_eq!(Elections::get_offset(50_000_000_000, 1), 48_000_000_000); - assert_eq!(Elections::get_offset(50_000_000_000, 2), 48_000_000_000 + 46_080_000_000); - assert_eq!(Elections::get_offset(50_000_000_000, 3), 48_000_000_000 + 46_080_000_000 + 44_236_800_000); - assert_eq!( - Elections::get_offset(50_000_000_000, 4), - 48_000_000_000 + 46_080_000_000 + 44_236_800_000 + 42_467_328_000 - ); - // limit - assert_eq!(Elections::get_offset(50_000_000_000, 1000), 50_000_000_000 * 24); - }) - } - - #[test] - fn get_offset_with_zero_decay() { - with_externalities(&mut ExtBuilder::default().decay_ratio(0).build(), || { - assert_eq!(Elections::get_offset(100, 0), 0); - assert_eq!(Elections::get_offset(100, 1), 0); - assert_eq!(Elections::get_offset(100, 2), 0); - assert_eq!(Elections::get_offset(100, 3), 0); - // limit - assert_eq!(Elections::get_offset(100, 1000), 0); - }) - } - - #[test] - fn voting_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 1)); - - assert_eq!(Elections::all_approvals_of(&1), vec![true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true]); - assert_eq!(voter_ids(), vec![1, 4]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true, true], 0, 2)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, true, true], 0, 3)); - - assert_eq!(Elections::all_approvals_of(&1), vec![true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true]); - assert_eq!(Elections::all_approvals_of(&2), vec![false, true, true]); - assert_eq!(Elections::all_approvals_of(&3), vec![false, true, true]); - - assert_eq!(voter_ids(), vec![1, 4, 2, 3]); - }); - } - - #[test] - fn proxy_voting_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - - >::insert(11, 1); - >::insert(12, 2); - >::insert(13, 3); - >::insert(14, 4); - assert_ok!(Elections::proxy_set_approvals(Origin::signed(11), vec![true], 0, 0)); - assert_ok!(Elections::proxy_set_approvals(Origin::signed(14), vec![true], 0, 1)); - - assert_eq!(Elections::all_approvals_of(&1), vec![true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true]); - assert_eq!(voter_ids(), vec![1, 4]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - - assert_ok!(Elections::proxy_set_approvals(Origin::signed(12), vec![false, true, true], 0, 2)); - assert_ok!(Elections::proxy_set_approvals(Origin::signed(13), vec![false, true, true], 0, 3)); - - assert_eq!(Elections::all_approvals_of(&1), vec![true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true]); - assert_eq!(Elections::all_approvals_of(&2), vec![false, true, true]); - assert_eq!(Elections::all_approvals_of(&3), vec![false, true, true]); - - assert_eq!(voter_ids(), vec![1, 4, 2, 3]); - }); - } - - #[test] - fn setting_any_approval_vote_count_without_any_candidate_count_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - - assert_eq!(Elections::candidates().len(), 0); - - assert_noop!( - Elections::set_approvals(Origin::signed(4), vec![], 0, 0), - "amount of candidates to receive approval votes should be non-zero" - ); - }); - } - - #[test] - fn setting_an_approval_vote_count_more_than_candidate_count_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_eq!(Elections::candidates().len(), 1); - - assert_noop!( - Elections::set_approvals(Origin::signed(4),vec![true, true], 0, 0), - "amount of candidate votes cannot exceed amount of candidates" - ); - }); - } - - #[test] - fn resubmitting_voting_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 0)); - - assert_eq!(Elections::all_approvals_of(&4), vec![true]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_eq!(Elections::candidates().len(), 3); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true, false, true], 0, 0)); - - assert_eq!(Elections::all_approvals_of(&4), vec![true, false, true]); - }); - } - - #[test] - fn retracting_voter_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_eq!(Elections::candidates().len(), 3); - - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true, true], 0, 1)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, true, true], 0, 2)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true, false, true], 0, 3)); - - assert_eq!(voter_ids(), vec![1, 2, 3, 4]); - assert_eq!(Elections::all_approvals_of(&1), vec![true]); - assert_eq!(Elections::all_approvals_of(&2), vec![false, true, true]); - assert_eq!(Elections::all_approvals_of(&3), vec![false, true, true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true, false, true]); - - assert_ok!(Elections::retract_voter(Origin::signed(1), 0)); - - assert_eq!(voter_ids(), vec![0, 2, 3, 4]); - assert_eq!(Elections::all_approvals_of(&1), Vec::::new()); - assert_eq!(Elections::all_approvals_of(&2), vec![false, true, true]); - assert_eq!(Elections::all_approvals_of(&3), vec![false, true, true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true, false, true]); - - assert_ok!(Elections::retract_voter(Origin::signed(2), 1)); - - assert_eq!(voter_ids(), vec![0, 0, 3, 4]); - assert_eq!(Elections::all_approvals_of(&1), Vec::::new()); - assert_eq!(Elections::all_approvals_of(&2), Vec::::new()); - assert_eq!(Elections::all_approvals_of(&3), vec![false, true, true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true, false, true]); - - assert_ok!(Elections::retract_voter(Origin::signed(3), 2)); - - assert_eq!(voter_ids(), vec![0, 0, 0, 4]); - assert_eq!(Elections::all_approvals_of(&1), Vec::::new()); - assert_eq!(Elections::all_approvals_of(&2), Vec::::new()); - assert_eq!(Elections::all_approvals_of(&3), Vec::::new()); - assert_eq!(Elections::all_approvals_of(&4), vec![true, false, true]); - }); - } - - #[test] - fn invalid_retraction_index_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - assert_eq!(voter_ids(), vec![1, 2]); - assert_noop!(Elections::retract_voter(Origin::signed(1), 1), "retraction index mismatch"); - }); - } - - #[test] - fn overflow_retraction_index_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0)); - assert_noop!(Elections::retract_voter(Origin::signed(1), 1), "retraction index invalid"); - }); - } - - #[test] - fn non_voter_retraction_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(1); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0)); - assert_noop!(Elections::retract_voter(Origin::signed(2), 0), "cannot retract non-voter"); - }); - } - - #[test] - fn approval_storage_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); - - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![], 0, 0)); - - assert_eq!(Elections::all_approvals_of(&2), vec![true]); - // NOTE: these two are stored in mem differently though. - assert_eq!(Elections::all_approvals_of(&3), vec![]); - assert_eq!(Elections::all_approvals_of(&4), vec![]); - - assert_eq!(Elections::approvals_of((3, 0)), vec![0]); - assert_eq!(Elections::approvals_of((4, 0)), vec![]); - }); - } - - #[test] - fn simple_tally_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0)); - assert_eq!(voter_ids(), vec![2, 5]); - assert_eq!(Elections::all_approvals_of(&2), vec![true]); - assert_eq!(Elections::all_approvals_of(&5), vec![false, true]); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(4), 2, 20, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(4), 5, 50, 0), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (0, 0), (20, 2), (50, 5)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert!(!Elections::presentation_active()); - assert_eq!(Elections::members(), vec![(5, 11), (2, 11)]); - - assert!(!Elections::is_a_candidate(&2)); - assert!(!Elections::is_a_candidate(&5)); - assert_eq!(Elections::vote_index(), 1); - assert_eq!(Elections::voter_info(2), Some(VoterInfo { last_win: 1, last_active: 0, stake: 20, pot: 0 })); - assert_eq!(Elections::voter_info(5), Some(VoterInfo { last_win: 1, last_active: 0, stake: 50, pot: 0 })); - }); - } - - #[test] - fn seats_should_be_released() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(4), 2, 20, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(4), 5, 50, 0), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (0, 0), (20, 2), (50, 5)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(5, 11), (2, 11)]); - let mut current = System::block_number(); - let free_block; - loop { - current += 1; - System::set_block_number(current); - assert_ok!(Elections::end_block(System::block_number())); - if Elections::members().len() == 0 { - free_block = current; - break; - } - } - // 11 + 2 which is the next voting period. - assert_eq!(free_block, 14); - }); - } - - #[test] - fn presentations_with_zero_staked_deposit_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_noop!( - Elections::present_winner(Origin::signed(4), 2, 0, 0), - "stake deposited to present winner and be added to leaderboard should be non-zero" - ); - }); - } - - #[test] - fn double_presentations_should_be_punished() { - with_externalities(&mut ExtBuilder::default().build(), || { - assert!(Balances::can_slash(&4, 10)); - - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); - assert_eq!(Elections::present_winner(Origin::signed(4), 5, 50, 0), Err("duplicate presentation")); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(5, 11), (2, 11)]); - assert_eq!(Balances::total_balance(&4), 38); - }); - } - - #[test] - fn retracting_inactive_voter_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - assert_ok!(Elections::reap_inactive_voter(Origin::signed(5), - (voter_ids().iter().position(|&i| i == 5).unwrap() as u32).into(), - 2, (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2 - )); - - assert_eq!(voter_ids(), vec![0, 5]); - assert_eq!(Elections::all_approvals_of(&2).len(), 0); - assert_eq!(Balances::total_balance(&2), 20); - assert_eq!(Balances::total_balance(&5), 50); - }); - } - - #[test] - fn presenting_for_double_election_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_eq!(Elections::submit_candidacy(Origin::signed(2), 0), Ok(())); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - // NOTE: This is now mandatory to disable the lock - assert_ok!(Elections::retract_voter(Origin::signed(2), 0)); - assert_eq!(Elections::submit_candidacy(Origin::signed(2), 0), Ok(())); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 1, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_noop!( - Elections::present_winner(Origin::signed(4), 2, 20, 1), - "candidate must not form a duplicated member if elected" - ); - }); - } - - #[test] - fn retracting_inactive_voter_with_other_candidates_in_slots_should_work() { - with_externalities(&mut ExtBuilder::default().voter_bond(2).build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(11); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - - assert_ok!(Elections::reap_inactive_voter(Origin::signed(5), - (voter_ids().iter().position(|&i| i == 5).unwrap() as u32).into(), - 2, (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2 - )); - - assert_eq!(voter_ids(), vec![0, 5]); - assert_eq!(Elections::all_approvals_of(&2).len(), 0); - }); - } - - #[test] - fn retracting_inactive_voter_with_bad_reporter_index_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - assert_noop!(Elections::reap_inactive_voter(Origin::signed(2), - 42, - 2, (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2 - ), "invalid reporter index"); - }); - } - - #[test] - fn retracting_inactive_voter_with_bad_target_index_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - assert_noop!(Elections::reap_inactive_voter(Origin::signed(2), - (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2, 42, - 2 - ), "invalid target index"); - }); - } - - #[test] - fn attempting_to_retract_active_voter_should_slash_reporter() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 2)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 3)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false, false, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, true, false, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, false, true, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, false, false, true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::set_desired_seats(Origin::ROOT, 3)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20 + Elections::get_offset(20, 1), 1)); - assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30 + Elections::get_offset(30, 1), 1)); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::vote_index(), 2); - assert_eq!(::InactiveGracePeriod::get(), 1); - assert_eq!(::VotingPeriod::get(), 4); - assert_eq!(Elections::voter_info(4), Some(VoterInfo { last_win: 1, last_active: 0, stake: 40, pot: 0 })); - - assert_ok!(Elections::reap_inactive_voter(Origin::signed(4), - (voter_ids().iter().position(|&i| i == 4).unwrap() as u32).into(), - 2, - (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2 - )); - - assert_eq!(voter_ids(), vec![2, 3, 0, 5]); - assert_eq!(Elections::all_approvals_of(&4).len(), 0); - assert_eq!(Balances::total_balance(&4), 40); - }); - } - - #[test] - fn attempting_to_retract_inactive_voter_by_nonvoter_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - assert_noop!(Elections::reap_inactive_voter(Origin::signed(4), - 0, - 2, (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2 - ), "reporter must be a voter"); - }); - } - - #[test] - fn presenting_loser_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, false, false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 4)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 1, 60, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); - - assert_eq!(Elections::leaderboard(), Some(vec![ - (30, 3), - (40, 4), - (50, 5), - (60, 1) - ])); - - assert_noop!(Elections::present_winner(Origin::signed(4), 2, 20, 0), "candidate not worthy of leaderboard"); - }); - } - - #[test] - fn presenting_loser_first_should_not_matter() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, false, false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 4)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 1, 60, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); - - assert_eq!(Elections::leaderboard(), Some(vec![ - (30, 3), - (40, 4), - (50, 5), - (60, 1) - ])); - }); - } - - #[test] - fn present_outside_of_presentation_period_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - assert_noop!( - Elections::present_winner(Origin::signed(5), 5, 1, 0), - "cannot present outside of presentation period" - ); - }); - } - - #[test] - fn present_with_invalid_vote_index_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_noop!(Elections::present_winner(Origin::signed(4), 2, 20, 1), "index not current"); - }); - } - - #[test] - fn present_when_presenter_is_poor_should_not_work() { - let test_present = |p| { - with_externalities(&mut ExtBuilder::default() - .voting_fee(5) - .voter_bond(2) - .bad_presentation_punishment(p) - .build(), - || { - System::set_block_number(4); - let _ = Balances::make_free_balance_be(&1, 15); - assert!(!Elections::presentation_active()); - - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); // -3 - assert_eq!(Balances::free_balance(&1), 12); - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0)); // -2 -5 - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_eq!(Balances::free_balance(&1), 5); - assert_eq!(Balances::reserved_balance(&1), 5); - if p > 5 { - assert_noop!(Elections::present_winner( - Origin::signed(1), 1, 10, 0), - "presenter must have sufficient slashable funds" - ); - } else { - assert_ok!(Elections::present_winner(Origin::signed(1), 1, 10, 0)); - } - }); - }; - test_present(4); - test_present(6); - } - - #[test] - fn invalid_present_tally_should_slash() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - assert_eq!(Balances::total_balance(&4), 40); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_err!(Elections::present_winner(Origin::signed(4), 2, 80, 0), "incorrect total"); - - assert_eq!(Balances::total_balance(&4), 38); - }); - } - - #[test] - fn runners_up_should_be_kept() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, false, false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 4)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0, 0)); - - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert!(Elections::presentation_active()); - assert_ok!(Elections::present_winner(Origin::signed(4), 1, 60, 0)); - // leaderboard length is the empty seats plus the carry count (i.e. 5 + 2), where those - // to be carried are the lowest and stored in lowest indices - assert_eq!(Elections::leaderboard(), Some(vec![ - (0, 0), - (0, 0), - (0, 0), - (60, 1) - ])); - assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); - assert_eq!(Elections::leaderboard(), Some(vec![ - (30, 3), - (40, 4), - (50, 5), - (60, 1) - ])); - - assert_ok!(Elections::end_block(System::block_number())); - - assert!(!Elections::presentation_active()); - assert_eq!(Elections::members(), vec![(1, 11), (5, 11)]); - - assert!(!Elections::is_a_candidate(&1)); - assert!(!Elections::is_a_candidate(&5)); - assert!(!Elections::is_a_candidate(&2)); - assert!(Elections::is_a_candidate(&3)); - assert!(Elections::is_a_candidate(&4)); - assert_eq!(Elections::vote_index(), 1); - assert_eq!(Elections::voter_info(2), Some(VoterInfo { last_win: 0, last_active: 0, stake: 20, pot: 0 })); - assert_eq!(Elections::voter_info(3), Some(VoterInfo { last_win: 0, last_active: 0, stake: 30, pot: 0 })); - assert_eq!(Elections::voter_info(4), Some(VoterInfo { last_win: 0, last_active: 0, stake: 40, pot: 0 })); - assert_eq!(Elections::voter_info(5), Some(VoterInfo { last_win: 1, last_active: 0, stake: 50, pot: 0 })); - assert_eq!(Elections::voter_info(6), Some(VoterInfo { last_win: 1, last_active: 0, stake: 60, pot: 0 })); - assert_eq!(Elections::candidate_reg_info(3), Some((0, 2))); - assert_eq!(Elections::candidate_reg_info(4), Some((0, 3))); - }); - } - - #[test] - fn second_tally_should_use_runners_up() { - with_externalities(&mut ExtBuilder::default().build(), || { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, false, false, true], 0, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 4)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 1, 60, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![false, false, true, false], 1, 0)); - assert_ok!(Elections::set_desired_seats(Origin::ROOT, 3)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30 + Elections::get_offset(30, 1) + 60, 1)); - assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40 + Elections::get_offset(40, 1), 1)); - assert_ok!(Elections::end_block(System::block_number())); - - assert!(!Elections::presentation_active()); - assert_eq!(Elections::members(), vec![(1, 11), (5, 11), (3, 15)]); - - assert!(!Elections::is_a_candidate(&1)); - assert!(!Elections::is_a_candidate(&2)); - assert!(!Elections::is_a_candidate(&3)); - assert!(!Elections::is_a_candidate(&5)); - assert!(Elections::is_a_candidate(&4)); - assert_eq!(Elections::vote_index(), 2); - assert_eq!(Elections::voter_info(2), Some( VoterInfo { last_win: 0, last_active: 0, stake: 20, pot: 0})); - assert_eq!(Elections::voter_info(3), Some( VoterInfo { last_win: 2, last_active: 0, stake: 30, pot: 0})); - assert_eq!(Elections::voter_info(4), Some( VoterInfo { last_win: 0, last_active: 0, stake: 40, pot: 0})); - assert_eq!(Elections::voter_info(5), Some( VoterInfo { last_win: 1, last_active: 0, stake: 50, pot: 0})); - assert_eq!( - Elections::voter_info(6), - Some(VoterInfo { last_win: 2, last_active: 1, stake: 60, pot: 0}) - ); - - assert_eq!(Elections::candidate_reg_info(4), Some((0, 3))); - }); - } - - #[test] - fn loser_candidates_bond_gets_slashed() { - with_externalities(&mut ExtBuilder::default().desired_seats(1).build(), || { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); - - assert_eq!(balances(&2), (17, 3)); - - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 0, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![false, true, true, true], 0, 0)); - - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(4), 4, 10, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(3), 3, 10, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(2), 2, 10, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(1), 1, 50, 0), Ok(())); - - - // winner + carry - assert_eq!(Elections::leaderboard(), Some(vec![(10, 3), (10, 4), (50, 1)])); - assert_ok!(Elections::end_block(System::block_number())); - assert!(!Elections::presentation_active()); - assert_eq!(Elections::members(), vec![(1, 11)]); - - // account 2 is not a runner up or in leaderboard. - assert_eq!(balances(&2), (17, 0)); - }); - } -} diff --git a/srml/elections/src/mock.rs b/srml/elections/src/mock.rs new file mode 100644 index 0000000000..161da35e6a --- /dev/null +++ b/srml/elections/src/mock.rs @@ -0,0 +1,294 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Mock file for election module. + +#![cfg(test)] + +use std::cell::RefCell; +use support::{ + StorageValue, StorageMap, parameter_types, assert_ok, + traits::{Get, ChangeMembers, Currency} +}; +use runtime_io::with_externalities; +use primitives::{H256, Blake2Hasher}; +use sr_primitives::{ + Perbill, BuildStorage, + testing::Header, + traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, +}; +use crate as elections; + + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); +} +impl system::Trait for Test { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = (); + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type WeightMultiplierUpdate = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); +} + +parameter_types! { + pub const ExistentialDeposit: u64 = 0; + pub const TransferFee: u64 = 0; + pub const CreationFee: u64 = 0; + pub const TransactionBaseFee: u64 = 0; + pub const TransactionByteFee: u64 = 0; +} +impl balances::Trait for Test { + type Balance = u64; + type OnNewAccount = (); + type OnFreeBalanceZero = (); + type Event = Event; + type TransactionPayment = (); + type TransferPayment = (); + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type TransferFee = TransferFee; + type CreationFee = CreationFee; + type TransactionBaseFee = TransactionBaseFee; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = (); +} + +parameter_types! { + pub const CandidacyBond: u64 = 3; + pub const CarryCount: u32 = 2; + pub const InactiveGracePeriod: u32 = 1; + pub const VotingPeriod: u64 = 4; + pub const MinimumVotingLock: u64 = 5; +} + +thread_local! { + static VOTER_BOND: RefCell = RefCell::new(0); + static VOTING_FEE: RefCell = RefCell::new(0); + static PRESENT_SLASH_PER_VOTER: RefCell = RefCell::new(0); + static DECAY_RATIO: RefCell = RefCell::new(0); + static MEMBERS: RefCell> = RefCell::new(vec![]); +} + +pub struct VotingBond; +impl Get for VotingBond { + fn get() -> u64 { VOTER_BOND.with(|v| *v.borrow()) } +} + +pub struct VotingFee; +impl Get for VotingFee { + fn get() -> u64 { VOTING_FEE.with(|v| *v.borrow()) } +} + +pub struct PresentSlashPerVoter; +impl Get for PresentSlashPerVoter { + fn get() -> u64 { PRESENT_SLASH_PER_VOTER.with(|v| *v.borrow()) } +} + +pub struct DecayRatio; +impl Get for DecayRatio { + fn get() -> u32 { DECAY_RATIO.with(|v| *v.borrow()) } +} + +pub struct TestChangeMembers; +impl ChangeMembers for TestChangeMembers { + fn change_members_sorted(incoming: &[u64], outgoing: &[u64], new: &[u64]) { + let mut old_plus_incoming = MEMBERS.with(|m| m.borrow().to_vec()); + old_plus_incoming.extend_from_slice(incoming); + old_plus_incoming.sort(); + let mut new_plus_outgoing = new.to_vec(); + new_plus_outgoing.extend_from_slice(outgoing); + new_plus_outgoing.sort(); + assert_eq!(old_plus_incoming, new_plus_outgoing); + + MEMBERS.with(|m| *m.borrow_mut() = new.to_vec()); + } +} + +impl elections::Trait for Test { + type Event = Event; + type Currency = Balances; + type BadPresentation = (); + type BadReaper = (); + type BadVoterIndex = (); + type LoserCandidate = (); + type ChangeMembers = TestChangeMembers; + type CandidacyBond = CandidacyBond; + type VotingBond = VotingBond; + type VotingFee = VotingFee; + type MinimumVotingLock = MinimumVotingLock; + type PresentSlashPerVoter = PresentSlashPerVoter; + type CarryCount = CarryCount; + type InactiveGracePeriod = InactiveGracePeriod; + type VotingPeriod = VotingPeriod; + type DecayRatio = DecayRatio; +} + +pub type Block = sr_primitives::generic::Block; +pub type UncheckedExtrinsic = sr_primitives::generic::UncheckedExtrinsic; + +support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: system::{Module, Call, Event}, + Balances: balances::{Module, Call, Event, Config, Error}, + Elections: elections::{Module, Call, Event, Config}, + } +); + +pub struct ExtBuilder { + balance_factor: u64, + decay_ratio: u32, + desired_seats: u32, + voting_fee: u64, + voter_bond: u64, + bad_presentation_punishment: u64, +} + +impl Default for ExtBuilder { + fn default() -> Self { + Self { + balance_factor: 1, + decay_ratio: 24, + desired_seats: 2, + voting_fee: 0, + voter_bond: 0, + bad_presentation_punishment: 1, + } + } +} + +impl ExtBuilder { + pub fn balance_factor(mut self, factor: u64) -> Self { + self.balance_factor = factor; + self + } + pub fn decay_ratio(mut self, ratio: u32) -> Self { + self.decay_ratio = ratio; + self + } + pub fn voting_fee(mut self, fee: u64) -> Self { + self.voting_fee = fee; + self + } + pub fn bad_presentation_punishment(mut self, fee: u64) -> Self { + self.bad_presentation_punishment = fee; + self + } + pub fn voter_bond(mut self, fee: u64) -> Self { + self.voter_bond = fee; + self + } + pub fn desired_seats(mut self, seats: u32) -> Self { + self.desired_seats = seats; + self + } + pub fn build(self) -> runtime_io::TestExternalities { + VOTER_BOND.with(|v| *v.borrow_mut() = self.voter_bond); + VOTING_FEE.with(|v| *v.borrow_mut() = self.voting_fee); + PRESENT_SLASH_PER_VOTER.with(|v| *v.borrow_mut() = self.bad_presentation_punishment); + DECAY_RATIO.with(|v| *v.borrow_mut() = self.decay_ratio); + GenesisConfig { + balances: Some(balances::GenesisConfig::{ + balances: vec![ + (1, 10 * self.balance_factor), + (2, 20 * self.balance_factor), + (3, 30 * self.balance_factor), + (4, 40 * self.balance_factor), + (5, 50 * self.balance_factor), + (6, 60 * self.balance_factor) + ], + vesting: vec![], + }), + elections: Some(elections::GenesisConfig::{ + members: vec![], + desired_seats: self.desired_seats, + presentation_duration: 2, + term_duration: 5, + }), + }.build_storage().unwrap().into() + } +} + +pub(crate) fn voter_ids() -> Vec { + Elections::all_voters().iter().map(|v| v.unwrap_or(0) ).collect::>() +} + +pub(crate) fn vote(i: u64, l: usize) { + let _ = Balances::make_free_balance_be(&i, 20); + assert_ok!( + Elections::set_approvals( + Origin::signed(i), + (0..l).map(|_| true).collect::>(), + 0, + 0, + 20, + ) + ); +} + +pub(crate) fn vote_at(i: u64, l: usize, index: elections::VoteIndex) { + let _ = Balances::make_free_balance_be(&i, 20); + assert_ok!( + Elections::set_approvals( + Origin::signed(i), + (0..l).map(|_| true).collect::>(), + 0, + index, + 20, + ) + ); +} + +pub(crate) fn create_candidate(i: u64, index: u32) { + let _ = Balances::make_free_balance_be(&i, 20); + assert_ok!(Elections::submit_candidacy(Origin::signed(i), index)); +} + +pub(crate) fn balances(who: &u64) -> (u64, u64) { + (Balances::free_balance(who), Balances::reserved_balance(who)) +} + +pub(crate) fn locks(who: &u64) -> Vec { + Balances::locks(who).iter().map(|l| l.amount).collect::>() +} + +pub(crate) fn new_test_ext_with_candidate_holes() -> runtime_io::TestExternalities { + let mut t = ExtBuilder::default().build(); + with_externalities(&mut t, || { + >::put(vec![0, 0, 1]); + elections::CandidateCount::put(1); + >::insert(1, (0, 2)); + }); + t +} diff --git a/srml/elections/src/tests.rs b/srml/elections/src/tests.rs new file mode 100644 index 0000000000..c6f4f9a0b3 --- /dev/null +++ b/srml/elections/src/tests.rs @@ -0,0 +1,1664 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Tests for election module. + +#![cfg(test)] + +use crate::mock::*; +use crate::*; + +use support::{assert_ok, assert_err, assert_noop}; +use runtime_io::with_externalities; + +#[test] +fn params_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + assert_eq!(Elections::next_vote_from(1), 4); + assert_eq!(Elections::next_vote_from(4), 4); + assert_eq!(Elections::next_vote_from(5), 8); + assert_eq!(Elections::vote_index(), 0); + assert_eq!(Elections::presentation_duration(), 2); + assert_eq!(Elections::term_duration(), 5); + assert_eq!(Elections::desired_seats(), 2); + + assert_eq!(Elections::members(), vec![]); + assert_eq!(Elections::next_tally(), Some(4)); + assert_eq!(Elections::presentation_active(), false); + assert_eq!(Elections::next_finalize(), None); + + assert_eq!(Elections::candidates(), Vec::::new()); + assert_eq!(Elections::is_a_candidate(&1), false); + assert_eq!(Elections::candidate_reg_info(1), None); + + assert_eq!(Elections::voters(0), Vec::>::new()); + assert_eq!(Elections::voter_info(1), None); + assert_eq!(Elections::all_approvals_of(&1), vec![]); + }); +} + +#[test] +fn chunking_bool_to_flag_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(Elections::bool_to_flag(vec![]), vec![]); + assert_eq!(Elections::bool_to_flag(vec![false]), vec![0]); + assert_eq!(Elections::bool_to_flag(vec![true]), vec![1]); + assert_eq!(Elections::bool_to_flag(vec![true, true, true, true]), vec![15]); + assert_eq!(Elections::bool_to_flag(vec![true, true, true, true, true]), vec![15 + 16]); + + let set_1 = vec![ + true, false, false, false, // 0x1 + false, true, true, true, // 0xE + ]; + assert_eq!( + Elections::bool_to_flag(set_1.clone()), + vec![0x00_00_00_E1_u32] + ); + assert_eq!( + Elections::flag_to_bool(vec![0x00_00_00_E1_u32]), + set_1 + ); + + let set_2 = vec![ + false, false, false, true, // 0x8 + false, true, false, true, // 0xA + ]; + assert_eq!( + Elections::bool_to_flag(set_2.clone()), + vec![0x00_00_00_A8_u32] + ); + assert_eq!( + Elections::flag_to_bool(vec![0x00_00_00_A8_u32]), + set_2 + ); + + let mut rhs = (0..100/APPROVAL_FLAG_LEN).map(|_| 0xFFFFFFFF_u32).collect::>(); + // NOTE: this might be need change based on `APPROVAL_FLAG_LEN`. + rhs.extend(vec![0x00_00_00_0F]); + assert_eq!( + Elections::bool_to_flag((0..100).map(|_| true).collect()), + rhs + ) + }) +} + +#[test] +fn chunking_voter_set_growth_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + + // create 65. 64 (set0) + 1 (set1) + (1..=63).for_each(|i| vote(i, 0)); + assert_eq!(Elections::next_nonfull_voter_set(), 0); + vote(64, 0); + assert_eq!(Elections::next_nonfull_voter_set(), 1); + vote(65, 0); + + let set1 = Elections::voters(0); + let set2 = Elections::voters(1); + + assert_eq!(set1.len(), 64); + assert_eq!(set2.len(), 1); + + assert_eq!(set1[0], Some(1)); + assert_eq!(set1[10], Some(11)); + assert_eq!(set2[0], Some(65)); + }) +} + +#[test] +fn chunking_voter_set_reclaim_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + + (1..=129).for_each(|i| vote(i, 0)); + assert_eq!(Elections::next_nonfull_voter_set(), 2); + + assert_ok!(Elections::retract_voter(Origin::signed(11), 10)); + + assert_ok!(Elections::retract_voter(Origin::signed(66), 65)); + assert_ok!(Elections::retract_voter(Origin::signed(67), 66)); + + // length does not show it but holes do exist. + assert_eq!(Elections::voters(0).len(), 64); + assert_eq!(Elections::voters(1).len(), 64); + assert_eq!(Elections::voters(2).len(), 1); + + assert_eq!(Elections::voters(0)[10], None); + assert_eq!(Elections::voters(1)[1], None); + assert_eq!(Elections::voters(1)[2], None); + // Next set with capacity is 2. + assert_eq!(Elections::next_nonfull_voter_set(), 2); + + // But we can fill a hole. + vote_at(130, 0, 10); + + // Nothing added to set 2. A hole was filled. + assert_eq!(Elections::voters(0).len(), 64); + assert_eq!(Elections::voters(1).len(), 64); + assert_eq!(Elections::voters(2).len(), 1); + + // and the next two (scheduled) to the second set. + assert_eq!(Elections::next_nonfull_voter_set(), 2); + }) +} + +#[test] +fn chunking_approvals_set_growth_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + // create candidates and voters. + (1..=250).for_each(|i| create_candidate(i, (i-1) as u32)); + (1..=250).for_each(|i| vote(i, i as usize)); + + // all approvals of should return the exact expected vector. + assert_eq!( + Elections::all_approvals_of(&180), + (0..180).map(|_| true).collect::>() + ); + assert_eq!( + Elections::all_approvals_of(&32), + (0..32).map(|_| true).collect::>() + ); + assert_eq!( + Elections::all_approvals_of(&8), + (0..8).map(|_| true).collect::>() + ); + assert_eq!( + Elections::all_approvals_of(&64), + (0..64).map(|_| true).collect::>() + ); + assert_eq!( + Elections::all_approvals_of(&65), + (0..65).map(|_| true).collect::>() + ); + assert_eq!( + Elections::all_approvals_of(&63), + (0..63).map(|_| true).collect::>() + ); + + // NOTE: assuming that APPROVAL_SET_SIZE is more or less small-ish. Might fail otherwise. + let full_sets = (180 / APPROVAL_FLAG_LEN) / APPROVAL_SET_SIZE; + let left_over = (180 / APPROVAL_FLAG_LEN) / APPROVAL_SET_SIZE; + let rem = 180 % APPROVAL_FLAG_LEN; + + // grab and check the last full set, if it exists. + if full_sets > 0 { + assert_eq!( + Elections::approvals_of((180, (full_sets-1) as SetIndex )), + Elections::bool_to_flag( + (0..APPROVAL_SET_SIZE * APPROVAL_FLAG_LEN) + .map(|_| true).collect::>() + ) + ); + } + + // grab and check the last, half-empty, set. + if left_over > 0 { + assert_eq!( + Elections::approvals_of((180, full_sets as SetIndex)), + Elections::bool_to_flag( + (0..left_over * APPROVAL_FLAG_LEN + rem) + .map(|_| true).collect::>() + ) + ); + } + }) +} + +#[test] +fn chunking_cell_status_works() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + + (1..=63).for_each(|i| vote(i, 0)); + + assert_ok!(Elections::retract_voter(Origin::signed(11), 10)); + assert_ok!(Elections::retract_voter(Origin::signed(21), 20)); + + assert_eq!(Elections::cell_status(0, 10), CellStatus::Hole); + assert_eq!(Elections::cell_status(0, 0), CellStatus::Occupied); + assert_eq!(Elections::cell_status(0, 20), CellStatus::Hole); + assert_eq!(Elections::cell_status(0, 63), CellStatus::Head); + assert_eq!(Elections::cell_status(1, 0), CellStatus::Head); + assert_eq!(Elections::cell_status(1, 10), CellStatus::Head); + }) +} + +#[test] +fn chunking_voter_index_does_not_take_holes_into_account() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + + // create 65. 64 (set0) + 1 (set1) + (1..=65).for_each(|i| vote(i, 0)); + + // account 65 has global index 65. + assert_eq!(Elections::voter_at(64).unwrap(), 65); + + assert_ok!(Elections::retract_voter(Origin::signed(1), 0)); + assert_ok!(Elections::retract_voter(Origin::signed(2), 1)); + + // still the same. These holes are in some other set. + assert_eq!(Elections::voter_at(64).unwrap(), 65); + // proof: can submit a new approval with the old index. + assert_noop!( + Elections::set_approvals(Origin::signed(65), vec![], 0, 64 - 2, 10), + "wrong voter index" + ); + assert_ok!(Elections::set_approvals(Origin::signed(65), vec![], 0, 64, 10)); + }) +} + +#[test] +fn chunking_approval_storage_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); + + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0, 20)); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false], 0, 0, 30)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![], 0, 0, 40)); + + assert_eq!(Elections::all_approvals_of(&2), vec![true]); + // NOTE: these two are stored in mem differently though. + assert_eq!(Elections::all_approvals_of(&3), vec![]); + assert_eq!(Elections::all_approvals_of(&4), vec![]); + + assert_eq!(Elections::approvals_of((3, 0)), vec![0]); + assert_eq!(Elections::approvals_of((4, 0)), vec![]); + }); +} + +#[test] +fn voting_initial_set_approvals_ignores_voter_index() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + + // Last argument is essentially irrelevant. You might get or miss a tip. + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![], 0, 0, 30)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![], 0, 5, 40)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![], 0, 100, 50)); + + // indices are more or less ignored. all is pushed. + assert_eq!(voter_ids(), vec![3, 4, 5]); + }) +} +#[test] +fn voting_bad_approval_index_slashes_voters_and_bond_reduces_stake() { + with_externalities(&mut ExtBuilder::default().voting_fee(5).voter_bond(2).build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + + (1..=63).for_each(|i| vote(i, 0)); + assert_eq!(balances(&1), (13, 2)); + assert_eq!(balances(&10), (18, 2)); + assert_eq!(balances(&60), (18, 2)); + + // still no fee + vote(64, 0); + assert_eq!(balances(&64), (18, 2)); + assert_eq!( + Elections::voter_info(&64).unwrap(), + VoterInfo { last_win: 0, last_active: 0, stake: 20, pot:0 } + ); + + assert_eq!(Elections::next_nonfull_voter_set(), 1); + + // now we charge the next voter. + vote(65, 0); + assert_eq!(balances(&65), (13, 2)); + assert_eq!( + Elections::voter_info(&65).unwrap(), + VoterInfo { last_win: 0, last_active: 0, stake: 15, pot:0 } + ); + }); +} + +#[test] +fn voting_subsequent_set_approvals_checks_voter_index() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![], 0, 0, 30)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![], 0, 5, 40)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![], 0, 100, 50)); + + // invalid index + assert_noop!( + Elections::set_approvals(Origin::signed(4), vec![true], 0, 5, 40), + "invalid voter index" + ); + // wrong index + assert_noop!( + Elections::set_approvals(Origin::signed(4), vec![true], 0, 0, 40), + "wrong voter index" + ); + // correct + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 1, 40)); + }) +} + +#[test] +fn voting_cannot_lock_less_than_limit() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + + assert_noop!( + Elections::set_approvals(Origin::signed(3), vec![], 0, 0, 4), + "locked value must be more than limit", + ); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![], 0, 0, 5)); + }); +} + +#[test] +fn voting_locking_more_than_total_balance_is_moot() { + with_externalities(&mut ExtBuilder::default().voter_bond(2).build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + + assert_eq!(balances(&3), (30, 0)); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![], 0, 0, 35)); + + assert_eq!(balances(&3), (28, 2)); + assert_eq!( + Elections::voter_info(&3).unwrap(), + VoterInfo { last_win: 0, last_active: 0, stake: 30, pot:0 } + ); + }); +} + +#[test] +fn voting_locking_stake_and_reserving_bond_works() { + with_externalities(&mut ExtBuilder::default().voter_bond(2).build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + + assert_eq!(balances(&2), (20, 0)); + assert_eq!(locks(&2), vec![]); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![], 0, 0, 15)); + assert_eq!(balances(&2), (18, 2)); + assert_eq!(locks(&2), vec![15]); + + // deposit a bit more. + let _ = Balances::make_free_balance_be(&2, 100); + + // change vote + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 70)); + assert_eq!(balances(&2), (100, 2)); + assert_eq!(locks(&2), vec![70]); + + assert_ok!(Elections::retract_voter(Origin::signed(2), 0)); + + assert_eq!(balances(&2), (102, 0)); + assert_eq!(locks(&2), vec![]); + }); +} + +#[test] +fn voting_without_any_candidate_count_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + + assert_eq!(Elections::candidates().len(), 0); + + assert_noop!( + Elections::set_approvals(Origin::signed(4), vec![], 0, 0, 40), + "amount of candidates to receive approval votes should be non-zero" + ); + }); +} + +#[test] +fn voting_setting_an_approval_vote_count_more_than_candidate_count_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + assert_eq!(Elections::candidates().len(), 1); + + assert_noop!( + Elections::set_approvals(Origin::signed(4),vec![true, true], 0, 0, 40), + "amount of candidate votes cannot exceed amount of candidates" + ); + }); +} + +#[test] +fn voting_resubmitting_approvals_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 0, 40)); + + assert_eq!(Elections::all_approvals_of(&4), vec![true]); + + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); + assert_eq!(Elections::candidates().len(), 3); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true, false, true], 0, 0, 40)); + + assert_eq!(Elections::all_approvals_of(&4), vec![true, false, true]); + }); +} + +#[test] +fn voting_retracting_voter_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + assert_eq!(Elections::candidates().len(), 1); + + assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 10)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 1, 20)); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![true], 0, 2, 30)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 3, 40)); + + assert_eq!(voter_ids(), vec![1, 2, 3, 4]); + assert_eq!(Elections::all_approvals_of(&1), vec![true]); + assert_eq!(Elections::all_approvals_of(&2), vec![true]); + assert_eq!(Elections::all_approvals_of(&3), vec![true]); + assert_eq!(Elections::all_approvals_of(&4), vec![true]); + + assert_ok!(Elections::retract_voter(Origin::signed(1), 0)); + + assert_eq!(voter_ids(), vec![0, 2, 3, 4]); + assert_eq!(Elections::all_approvals_of(&1), Vec::::new()); + assert_eq!(Elections::all_approvals_of(&2), vec![true]); + assert_eq!(Elections::all_approvals_of(&3), vec![true]); + assert_eq!(Elections::all_approvals_of(&4), vec![true]); + + assert_ok!(Elections::retract_voter(Origin::signed(2), 1)); + + assert_eq!(voter_ids(), vec![0, 0, 3, 4]); + assert_eq!(Elections::all_approvals_of(&1), Vec::::new()); + assert_eq!(Elections::all_approvals_of(&2), Vec::::new()); + assert_eq!(Elections::all_approvals_of(&3), vec![true]); + assert_eq!(Elections::all_approvals_of(&4), vec![true]); + + assert_ok!(Elections::retract_voter(Origin::signed(3), 2)); + + assert_eq!(voter_ids(), vec![0, 0, 0, 4]); + assert_eq!(Elections::all_approvals_of(&1), Vec::::new()); + assert_eq!(Elections::all_approvals_of(&2), Vec::::new()); + assert_eq!(Elections::all_approvals_of(&3), Vec::::new()); + assert_eq!(Elections::all_approvals_of(&4), vec![true]); + }); +} + +#[test] +fn voting_invalid_retraction_index_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); + + assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 10)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); + assert_eq!(voter_ids(), vec![1, 2]); + assert_noop!(Elections::retract_voter(Origin::signed(1), 1), "retraction index mismatch"); + }); +} + +#[test] +fn voting_overflow_retraction_index_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); + + assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 10)); + assert_noop!(Elections::retract_voter(Origin::signed(1), 1), "retraction index invalid"); + }); +} + +#[test] +fn voting_non_voter_retraction_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); + + assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 10)); + assert_noop!(Elections::retract_voter(Origin::signed(2), 0), "cannot retract non-voter"); + }); +} + +#[test] +fn retracting_inactive_voter_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(8); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(10); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); + assert_ok!(Elections::end_block(System::block_number())); + + assert_ok!(Elections::reap_inactive_voter(Origin::signed(5), + (voter_ids().iter().position(|&i| i == 5).unwrap() as u32).into(), + 2, (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), + 2 + )); + + assert_eq!(voter_ids(), vec![0, 5]); + assert_eq!(Elections::all_approvals_of(&2).len(), 0); + assert_eq!(Balances::total_balance(&2), 20); + assert_eq!(Balances::total_balance(&5), 50); + }); +} + +#[test] +fn retracting_inactive_voter_with_other_candidates_in_slots_should_work() { + with_externalities(&mut ExtBuilder::default().voter_bond(2).build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(8); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(10); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(11); + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); + + assert_ok!(Elections::reap_inactive_voter(Origin::signed(5), + (voter_ids().iter().position(|&i| i == 5).unwrap() as u32).into(), + 2, (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), + 2 + )); + + assert_eq!(voter_ids(), vec![0, 5]); + assert_eq!(Elections::all_approvals_of(&2).len(), 0); + }); +} + +#[test] +fn retracting_inactive_voter_with_bad_reporter_index_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(8); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(10); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); + assert_ok!(Elections::end_block(System::block_number())); + + assert_noop!(Elections::reap_inactive_voter(Origin::signed(2), + 42, + 2, (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), + 2 + ), "invalid reporter index"); + }); +} + +#[test] +fn retracting_inactive_voter_with_bad_target_index_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(8); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(10); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); + assert_ok!(Elections::end_block(System::block_number())); + + assert_noop!(Elections::reap_inactive_voter(Origin::signed(2), + (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), + 2, 42, + 2 + ), "invalid target index"); + }); +} + +#[test] +fn retracting_active_voter_should_slash_reporter() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(4), 2)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 3)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false, false, false], 0, 0, 20)); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, true, false, false], 0, 0, 30)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, false, true, false], 0, 0, 40)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, false, false, true], 0, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(8); + assert_ok!(Elections::set_desired_seats(Origin::ROOT, 3)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(10); + assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20 + Elections::get_offset(20, 1), 1)); + assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30 + Elections::get_offset(30, 1), 1)); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::vote_index(), 2); + assert_eq!(::InactiveGracePeriod::get(), 1); + assert_eq!(::VotingPeriod::get(), 4); + assert_eq!(Elections::voter_info(4), Some(VoterInfo { last_win: 1, last_active: 0, stake: 40, pot: 0 })); + + assert_ok!(Elections::reap_inactive_voter(Origin::signed(4), + (voter_ids().iter().position(|&i| i == 4).unwrap() as u32).into(), + 2, + (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), + 2 + )); + + assert_eq!(voter_ids(), vec![2, 3, 0, 5]); + assert_eq!(Elections::all_approvals_of(&4).len(), 0); + assert_eq!(Balances::total_balance(&4), 40); + }); +} + +#[test] +fn retracting_inactive_voter_by_nonvoter_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(8); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(10); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); + assert_ok!(Elections::end_block(System::block_number())); + + assert_noop!(Elections::reap_inactive_voter(Origin::signed(4), + 0, + 2, (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), + 2 + ), "reporter must be a voter"); + }); +} + +#[test] +fn candidacy_simple_candidate_submission_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + assert_eq!(Elections::candidates(), Vec::::new()); + assert_eq!(Elections::candidate_reg_info(1), None); + assert_eq!(Elections::candidate_reg_info(2), None); + assert_eq!(Elections::is_a_candidate(&1), false); + assert_eq!(Elections::is_a_candidate(&2), false); + + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); + assert_eq!(Elections::candidates(), vec![1]); + assert_eq!(Elections::candidate_reg_info(1), Some((0, 0))); + assert_eq!(Elections::candidate_reg_info(2), None); + assert_eq!(Elections::is_a_candidate(&1), true); + assert_eq!(Elections::is_a_candidate(&2), false); + + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); + assert_eq!(Elections::candidates(), vec![1, 2]); + assert_eq!(Elections::candidate_reg_info(1), Some((0, 0))); + assert_eq!(Elections::candidate_reg_info(2), Some((0, 1))); + assert_eq!(Elections::is_a_candidate(&1), true); + assert_eq!(Elections::is_a_candidate(&2), true); + }); +} + +#[test] +fn candidacy_submission_using_free_slot_should_work() { + let mut t = new_test_ext_with_candidate_holes(); + + with_externalities(&mut t, || { + System::set_block_number(1); + assert_eq!(Elections::candidates(), vec![0, 0, 1]); + + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); + assert_eq!(Elections::candidates(), vec![0, 2, 1]); + + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); + assert_eq!(Elections::candidates(), vec![3, 2, 1]); + }); +} + +#[test] +fn candidacy_submission_using_alternative_free_slot_should_work() { + let mut t = new_test_ext_with_candidate_holes(); + + with_externalities(&mut t, || { + System::set_block_number(1); + assert_eq!(Elections::candidates(), vec![0, 0, 1]); + + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_eq!(Elections::candidates(), vec![2, 0, 1]); + + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); + assert_eq!(Elections::candidates(), vec![2, 3, 1]); + }); +} + +#[test] +fn candidacy_submission_not_using_free_slot_should_not_work() { + let mut t = new_test_ext_with_candidate_holes(); + + with_externalities(&mut t, || { + System::set_block_number(1); + assert_noop!( + Elections::submit_candidacy(Origin::signed(4), 3), + "invalid candidate slot" + ); + }); +} + +#[test] +fn candidacy_bad_candidate_slot_submission_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + assert_eq!(Elections::candidates(), Vec::::new()); + assert_noop!( + Elections::submit_candidacy(Origin::signed(1), 1), + "invalid candidate slot" + ); + }); +} + +#[test] +fn candidacy_non_free_candidate_slot_submission_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + assert_eq!(Elections::candidates(), Vec::::new()); + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); + assert_eq!(Elections::candidates(), vec![1]); + assert_noop!( + Elections::submit_candidacy(Origin::signed(2), 0), + "invalid candidate slot" + ); + }); +} + +#[test] +fn candidacy_dupe_candidate_submission_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + assert_eq!(Elections::candidates(), Vec::::new()); + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); + assert_eq!(Elections::candidates(), vec![1]); + assert_noop!( + Elections::submit_candidacy(Origin::signed(1), 1), + "duplicate candidate submission" + ); + }); +} + +#[test] +fn candidacy_poor_candidate_submission_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + assert_eq!(Elections::candidates(), Vec::::new()); + assert_noop!( + Elections::submit_candidacy(Origin::signed(7), 0), + "candidate has not enough funds" + ); + }); +} + +#[test] +fn election_voting_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + + assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 10)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 1, 40)); + + assert_eq!(Elections::all_approvals_of(&1), vec![true]); + assert_eq!(Elections::all_approvals_of(&4), vec![true]); + assert_eq!(voter_ids(), vec![1, 4]); + + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); + + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true, true], 0, 2, 20)); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, true, true], 0, 3, 30)); + + assert_eq!(Elections::all_approvals_of(&1), vec![true]); + assert_eq!(Elections::all_approvals_of(&4), vec![true]); + assert_eq!(Elections::all_approvals_of(&2), vec![false, true, true]); + assert_eq!(Elections::all_approvals_of(&3), vec![false, true, true]); + + assert_eq!(voter_ids(), vec![1, 4, 2, 3]); + }); +} + +#[test] +fn election_proxy_voting_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); + + >::insert(11, 1); + >::insert(12, 2); + >::insert(13, 3); + >::insert(14, 4); + assert_ok!( + Elections::proxy_set_approvals(Origin::signed(11), vec![true], 0, 0, 10) + ); + assert_ok!( + Elections::proxy_set_approvals(Origin::signed(14), vec![true], 0, 1, 40) + ); + + assert_eq!(Elections::all_approvals_of(&1), vec![true]); + assert_eq!(Elections::all_approvals_of(&4), vec![true]); + assert_eq!(voter_ids(), vec![1, 4]); + + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); + + assert_ok!( + Elections::proxy_set_approvals(Origin::signed(12), vec![false, true], 0, 2, 20) + ); + assert_ok!( + Elections::proxy_set_approvals(Origin::signed(13), vec![false, true], 0, 3, 30) + ); + + assert_eq!(Elections::all_approvals_of(&1), vec![true]); + assert_eq!(Elections::all_approvals_of(&4), vec![true]); + assert_eq!(Elections::all_approvals_of(&2), vec![false, true]); + assert_eq!(Elections::all_approvals_of(&3), vec![false, true]); + + assert_eq!(voter_ids(), vec![1, 4, 2, 3]); + }); +} + +#[test] +fn election_simple_tally_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert!(!Elections::presentation_active()); + + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0, 50)); + assert_eq!(voter_ids(), vec![2, 5]); + assert_eq!(Elections::all_approvals_of(&2), vec![true]); + assert_eq!(Elections::all_approvals_of(&5), vec![false, true]); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert!(Elections::presentation_active()); + assert_eq!(Elections::present_winner(Origin::signed(4), 2, 20, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(4), 5, 50, 0), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (0, 0), (20, 2), (50, 5)])); + assert_ok!(Elections::end_block(System::block_number())); + + assert!(!Elections::presentation_active()); + assert_eq!(Elections::members(), vec![(5, 11), (2, 11)]); + + assert!(!Elections::is_a_candidate(&2)); + assert!(!Elections::is_a_candidate(&5)); + assert_eq!(Elections::vote_index(), 1); + assert_eq!( + Elections::voter_info(2), + Some(VoterInfo { last_win: 1, last_active: 0, stake: 20, pot: 0 }) + ); + assert_eq!( + Elections::voter_info(5), + Some(VoterInfo { last_win: 1, last_active: 0, stake: 50, pot: 0 }) + ); + }); +} + +#[test] +fn election_seats_should_be_released() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0, 20)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert!(Elections::presentation_active()); + assert_eq!(Elections::present_winner(Origin::signed(4), 2, 20, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(4), 5, 50, 0), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (0, 0), (20, 2), (50, 5)])); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(5, 11), (2, 11)]); + let mut current = System::block_number(); + let free_block; + loop { + current += 1; + System::set_block_number(current); + assert_ok!(Elections::end_block(System::block_number())); + if Elections::members().len() == 0 { + free_block = current; + break; + } + } + // 11 + 2 which is the next voting period. + assert_eq!(free_block, 14); + }); +} + +#[test] +fn election_presentations_with_zero_staked_deposit_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_noop!( + Elections::present_winner(Origin::signed(4), 2, 0, 0), + "stake deposited to present winner and be added to leaderboard should be non-zero" + ); + }); +} + +#[test] +fn election_double_presentations_should_be_punished() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert!(Balances::can_slash(&4, 10)); + + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0, 20)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); + assert_eq!(Elections::present_winner(Origin::signed(4), 5, 50, 0), Err("duplicate presentation")); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(5, 11), (2, 11)]); + assert_eq!(Balances::total_balance(&4), 38); + }); +} + +#[test] +fn election_presenting_for_double_election_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_eq!(Elections::submit_candidacy(Origin::signed(2), 0), Ok(())); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(8); + // NOTE: This is now mandatory to disable the lock + assert_ok!(Elections::retract_voter(Origin::signed(2), 0)); + assert_eq!(Elections::submit_candidacy(Origin::signed(2), 0), Ok(())); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 1, 0, 20)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(10); + assert_noop!( + Elections::present_winner(Origin::signed(4), 2, 20, 1), + "candidate must not form a duplicated member if elected" + ); + }); +} + +#[test] +fn election_presenting_loser_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0, 60)); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true], 0, 0, 20)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true], 0, 0, 30)); + assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, false, false, true], 0, 0, 40)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 4)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 1, 60, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); + + assert_eq!(Elections::leaderboard(), Some(vec![ + (30, 3), + (40, 4), + (50, 5), + (60, 1) + ])); + + assert_noop!(Elections::present_winner(Origin::signed(4), 2, 20, 0), "candidate not worthy of leaderboard"); + }); +} + +#[test] +fn election_presenting_loser_first_should_not_matter() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0, 60)); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true], 0, 0, 20)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true], 0, 0, 30)); + assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, false, false, true], 0, 0, 40)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 4)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 1, 60, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); + + assert_eq!(Elections::leaderboard(), Some(vec![ + (30, 3), + (40, 4), + (50, 5), + (60, 1) + ])); + }); +} + +#[test] +fn election_present_outside_of_presentation_period_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert!(!Elections::presentation_active()); + assert_noop!( + Elections::present_winner(Origin::signed(5), 5, 1, 0), + "cannot present outside of presentation period" + ); + }); +} + +#[test] +fn election_present_with_invalid_vote_index_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0, 20)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_noop!(Elections::present_winner(Origin::signed(4), 2, 20, 1), "index not current"); + }); +} + +#[test] +fn election_present_when_presenter_is_poor_should_not_work() { + let test_present = |p| { + with_externalities(&mut ExtBuilder::default() + .voting_fee(5) + .voter_bond(2) + .bad_presentation_punishment(p) + .build(), + || { + System::set_block_number(4); + let _ = Balances::make_free_balance_be(&1, 15); + assert!(!Elections::presentation_active()); + + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); // -3 + assert_eq!(Balances::free_balance(&1), 12); + assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 15)); // -2 -5 + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_eq!(Balances::free_balance(&1), 5); + assert_eq!(Balances::reserved_balance(&1), 5); + if p > 5 { + assert_noop!(Elections::present_winner( + Origin::signed(1), 1, 10, 0), + "presenter must have sufficient slashable funds" + ); + } else { + assert_ok!(Elections::present_winner(Origin::signed(1), 1, 10, 0)); + } + }); + }; + test_present(4); + test_present(6); +} + +#[test] +fn election_invalid_present_tally_should_slash() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert!(!Elections::presentation_active()); + assert_eq!(Balances::total_balance(&4), 40); + + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0, 20)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_err!(Elections::present_winner(Origin::signed(4), 2, 80, 0), "incorrect total"); + + assert_eq!(Balances::total_balance(&4), 38); + }); +} + +#[test] +fn election_runners_up_should_be_kept() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert!(!Elections::presentation_active()); + + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0, 60)); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true], 0, 0, 20)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true], 0, 0, 30)); + assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, false, false, true], 0, 0, 40)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 4)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0, 0, 50)); + + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert!(Elections::presentation_active()); + assert_ok!(Elections::present_winner(Origin::signed(4), 1, 60, 0)); + // leaderboard length is the empty seats plus the carry count (i.e. 5 + 2), where those + // to be carried are the lowest and stored in lowest indices + assert_eq!(Elections::leaderboard(), Some(vec![ + (0, 0), + (0, 0), + (0, 0), + (60, 1) + ])); + assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); + assert_eq!(Elections::leaderboard(), Some(vec![ + (30, 3), + (40, 4), + (50, 5), + (60, 1) + ])); + + assert_ok!(Elections::end_block(System::block_number())); + + assert!(!Elections::presentation_active()); + assert_eq!(Elections::members(), vec![(1, 11), (5, 11)]); + + assert!(!Elections::is_a_candidate(&1)); + assert!(!Elections::is_a_candidate(&5)); + assert!(!Elections::is_a_candidate(&2)); + assert!(Elections::is_a_candidate(&3)); + assert!(Elections::is_a_candidate(&4)); + assert_eq!(Elections::vote_index(), 1); + assert_eq!(Elections::voter_info(2), Some(VoterInfo { last_win: 0, last_active: 0, stake: 20, pot: 0 })); + assert_eq!(Elections::voter_info(3), Some(VoterInfo { last_win: 0, last_active: 0, stake: 30, pot: 0 })); + assert_eq!(Elections::voter_info(4), Some(VoterInfo { last_win: 0, last_active: 0, stake: 40, pot: 0 })); + assert_eq!(Elections::voter_info(5), Some(VoterInfo { last_win: 1, last_active: 0, stake: 50, pot: 0 })); + assert_eq!(Elections::voter_info(6), Some(VoterInfo { last_win: 1, last_active: 0, stake: 60, pot: 0 })); + assert_eq!(Elections::candidate_reg_info(3), Some((0, 2))); + assert_eq!(Elections::candidate_reg_info(4), Some((0, 3))); + }); +} + +#[test] +fn election_second_tally_should_use_runners_up() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(4); + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0, 60)); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true], 0, 0, 20)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true], 0, 0, 30)); + assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, false, false, true], 0, 0, 40)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 4)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0, 0, 50)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_ok!(Elections::present_winner(Origin::signed(4), 1, 60, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); + assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(8); + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![false, false, true, false], 1, 0, 60)); + assert_ok!(Elections::set_desired_seats(Origin::ROOT, 3)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(10); + assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30 + Elections::get_offset(30, 1) + 60, 1)); + assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40 + Elections::get_offset(40, 1), 1)); + assert_ok!(Elections::end_block(System::block_number())); + + assert!(!Elections::presentation_active()); + assert_eq!(Elections::members(), vec![(1, 11), (5, 11), (3, 15)]); + + assert!(!Elections::is_a_candidate(&1)); + assert!(!Elections::is_a_candidate(&2)); + assert!(!Elections::is_a_candidate(&3)); + assert!(!Elections::is_a_candidate(&5)); + assert!(Elections::is_a_candidate(&4)); + assert_eq!(Elections::vote_index(), 2); + assert_eq!(Elections::voter_info(2), Some( VoterInfo { last_win: 0, last_active: 0, stake: 20, pot: 0})); + assert_eq!(Elections::voter_info(3), Some( VoterInfo { last_win: 2, last_active: 0, stake: 30, pot: 0})); + assert_eq!(Elections::voter_info(4), Some( VoterInfo { last_win: 0, last_active: 0, stake: 40, pot: 0})); + assert_eq!(Elections::voter_info(5), Some( VoterInfo { last_win: 1, last_active: 0, stake: 50, pot: 0})); + assert_eq!( + Elections::voter_info(6), + Some(VoterInfo { last_win: 2, last_active: 1, stake: 60, pot: 0}) + ); + + assert_eq!(Elections::candidate_reg_info(4), Some((0, 3))); + }); +} + +#[test] +fn election_loser_candidates_bond_gets_slashed() { + with_externalities(&mut ExtBuilder::default().desired_seats(1).build(), || { + System::set_block_number(4); + assert!(!Elections::presentation_active()); + + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); + assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); + + assert_eq!(balances(&2), (17, 3)); + + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 0, 0, 50)); + assert_ok!( + Elections::set_approvals(Origin::signed(1), vec![false, true, true, true], 0, 0, 10) + ); + + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert!(Elections::presentation_active()); + assert_eq!(Elections::present_winner(Origin::signed(4), 4, 10, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(3), 3, 10, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(2), 2, 10, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(1), 1, 50, 0), Ok(())); + + + // winner + carry + assert_eq!(Elections::leaderboard(), Some(vec![(10, 3), (10, 4), (50, 1)])); + assert_ok!(Elections::end_block(System::block_number())); + assert!(!Elections::presentation_active()); + assert_eq!(Elections::members(), vec![(1, 11)]); + + // account 2 is not a runner up or in leaderboard. + assert_eq!(balances(&2), (17, 0)); + }); +} + +#[test] +fn pot_accumulating_weight_and_decaying_should_work() { + with_externalities(&mut ExtBuilder::default().balance_factor(10).build(), || { + System::set_block_number(4); + assert!(!Elections::presentation_active()); + + assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 2)); + + assert_ok!( + Elections::set_approvals(Origin::signed(6), vec![true, false, false], 0, 0, 600) + ); + assert_ok!( + Elections::set_approvals(Origin::signed(5), vec![false, true, false], 0, 0, 500) + ); + assert_ok!( + Elections::set_approvals(Origin::signed(1), vec![false, false, true], 0, 0, 100) + ); + + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert!(Elections::presentation_active()); + + assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100, 0), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100, 1), (500, 5), (600, 6)])); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(6, 11), (5, 11)]); + assert_eq!( + Elections::voter_info(6).unwrap(), + VoterInfo { last_win: 1, last_active: 0, stake: 600, pot: 0}, + ); + assert_eq!( + Elections::voter_info(5).unwrap(), + VoterInfo { last_win: 1, last_active: 0, stake: 500, pot: 0}, + ); + assert_eq!( + Elections::voter_info(1).unwrap(), + VoterInfo { last_win: 0, last_active: 0, stake: 100, pot: 0}, + ); + + System::set_block_number(12); + // retract needed to unlock approval funds => submit candidacy again. + assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); + assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!( + Elections::set_approvals(Origin::signed(6), vec![true, false, false], 1, 0, 600) + ); + assert_ok!( + Elections::set_approvals(Origin::signed(5), vec![false, true, false], 1, 1, 500) + ); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(14); + assert!(Elections::presentation_active()); + assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 1), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 1), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100 + Elections::get_offset(100, 1), 1), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100 + 96, 1), (500, 5), (600, 6)])); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(6, 19), (5, 19)]); + assert_eq!( + Elections::voter_info(6).unwrap(), + VoterInfo { last_win: 2, last_active: 1, stake: 600, pot:0 } + ); + assert_eq!(Elections::voter_info(5).unwrap(), VoterInfo { last_win: 2, last_active: 1, stake: 500, pot:0 }); + assert_eq!(Elections::voter_info(1).unwrap(), VoterInfo { last_win: 0, last_active: 0, stake: 100, pot:0 }); + + System::set_block_number(20); + assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); + assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 2, 0, 600)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 2, 1, 500)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(22); + assert!(Elections::presentation_active()); + assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 2), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 2), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100 + Elections::get_offset(100, 2), 2), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100 + 96 + 93, 1), (500, 5), (600, 6)])); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(6, 27), (5, 27)]); + assert_eq!( + Elections::voter_info(6).unwrap(), + VoterInfo { last_win: 3, last_active: 2, stake: 600, pot: 0} + ); + assert_eq!(Elections::voter_info(5).unwrap(), VoterInfo { last_win: 3, last_active: 2, stake: 500, pot: 0}); + assert_eq!(Elections::voter_info(1).unwrap(), VoterInfo { last_win: 0, last_active: 0, stake: 100, pot: 0}); + + + System::set_block_number(28); + assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); + assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 3, 0, 600)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 3, 1, 500)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(30); + assert!(Elections::presentation_active()); + assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 3), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 3), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100 + Elections::get_offset(100, 3), 3), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100 + 96 + 93 + 90, 1), (500, 5), (600, 6)])); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(6, 35), (5, 35)]); + assert_eq!( + Elections::voter_info(6).unwrap(), + VoterInfo { last_win: 4, last_active: 3, stake: 600, pot: 0} + ); + assert_eq!(Elections::voter_info(5).unwrap(), VoterInfo { last_win: 4, last_active: 3, stake: 500, pot: 0}); + assert_eq!(Elections::voter_info(1).unwrap(), VoterInfo { last_win: 0, last_active: 0, stake: 100, pot: 0}); + }) +} + +#[test] +fn pot_winning_resets_accumulated_pot() { + with_externalities(&mut ExtBuilder::default().balance_factor(10).build(), || { + System::set_block_number(4); + assert!(!Elections::presentation_active()); + + assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(4), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); + assert_ok!(Elections::submit_candidacy(Origin::signed(2), 3)); + + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false, false], 0, 0, 600)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, true, false, false], 0, 1, 400)); + assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true, true], 0, 2, 300)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert!(Elections::presentation_active()); + assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(4), 4, 400, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(3), 3, 300, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(2), 2, 300, 0), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(300, 2), (300, 3), (400, 4), (600, 6)])); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(6, 11), (4, 11)]); + + System::set_block_number(12); + assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); + assert_ok!(Elections::retract_voter(Origin::signed(4), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(4), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false, false], 1, 0, 600)); + assert_ok!(Elections::set_approvals(Origin::signed(4), vec![false, true, false, false], 1, 1, 400)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(14); + assert!(Elections::presentation_active()); + assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 1), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(4), 4, 400, 1), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(3), 3, 300 + Elections::get_offset(300, 1), 1), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(2), 2, 300 + Elections::get_offset(300, 1), 1), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(400, 4), (588, 2), (588, 3), (600, 6)])); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(6, 19), (3, 19)]); + + System::set_block_number(20); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(22); + // 2 will not get re-elected with 300 + 288, instead just 300. + // because one of 3's candidates (3) won in previous round + // 4 on the other hand will get extra weight since it was unlucky. + assert_eq!(Elections::present_winner(Origin::signed(3), 2, 300, 2), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(4), 4, 400 + Elections::get_offset(400, 1), 2), Ok(())); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(4, 27), (2, 27)]); + }) +} + +#[test] +fn pot_resubmitting_approvals_stores_pot() { + with_externalities(&mut ExtBuilder::default() + .voter_bond(0) + .voting_fee(0) + .balance_factor(10) + .build(), + || { System::set_block_number(4); + assert!(!Elections::presentation_active()); + + assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 2)); + + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 0, 0, 600)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 0, 1, 500)); + assert_ok!(Elections::set_approvals(Origin::signed(1), vec![false, false, true], 0, 2, 100)); + + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert!(Elections::presentation_active()); + + assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100, 0), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100, 1), (500, 5), (600, 6)])); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(6, 11), (5, 11)]); + + System::set_block_number(12); + assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); + assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 1, 0, 600)); + assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 1, 1, 500)); + // give 1 some new high balance + let _ = Balances::make_free_balance_be(&1, 997); + assert_ok!(Elections::set_approvals(Origin::signed(1), vec![false, false, true], 1, 2, 1000)); + assert_eq!(Elections::voter_info(1).unwrap(), + VoterInfo { + stake: 1000, // 997 + 3 which is candidacy bond. + pot: Elections::get_offset(100, 1), + last_active: 1, + last_win: 1, + } + ); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(6, 11), (5, 11)]); + + System::set_block_number(14); + assert!(Elections::presentation_active()); + assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 1), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 1), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(1), 1, 1000 + 96 /* pot */, 1), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (500, 5), (600, 6), (1096, 1)])); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![(1, 19), (6, 19)]); + }) +} + +#[test] +fn pot_get_offset_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(Elections::get_offset(100, 0), 0); + assert_eq!(Elections::get_offset(100, 1), 96); + assert_eq!(Elections::get_offset(100, 2), 96 + 93); + assert_eq!(Elections::get_offset(100, 3), 96 + 93 + 90); + assert_eq!(Elections::get_offset(100, 4), 96 + 93 + 90 + 87); + // limit + assert_eq!(Elections::get_offset(100, 1000), 100 * 24); + + assert_eq!(Elections::get_offset(50_000_000_000, 0), 0); + assert_eq!(Elections::get_offset(50_000_000_000, 1), 48_000_000_000); + assert_eq!(Elections::get_offset(50_000_000_000, 2), 48_000_000_000 + 46_080_000_000); + assert_eq!(Elections::get_offset(50_000_000_000, 3), 48_000_000_000 + 46_080_000_000 + 44_236_800_000); + assert_eq!( + Elections::get_offset(50_000_000_000, 4), + 48_000_000_000 + 46_080_000_000 + 44_236_800_000 + 42_467_328_000 + ); + // limit + assert_eq!(Elections::get_offset(50_000_000_000, 1000), 50_000_000_000 * 24); + }) +} + +#[test] +fn pot_get_offset_with_zero_decay() { + with_externalities(&mut ExtBuilder::default().decay_ratio(0).build(), || { + assert_eq!(Elections::get_offset(100, 0), 0); + assert_eq!(Elections::get_offset(100, 1), 0); + assert_eq!(Elections::get_offset(100, 2), 0); + assert_eq!(Elections::get_offset(100, 3), 0); + // limit + assert_eq!(Elections::get_offset(100, 1000), 0); + }) +} diff --git a/srml/im-online/src/lib.rs b/srml/im-online/src/lib.rs index 3fd57a2e24..6106b1e45c 100644 --- a/srml/im-online/src/lib.rs +++ b/srml/im-online/src/lib.rs @@ -67,7 +67,7 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -use app_crypto::{AppPublic, RuntimeAppPublic, AppSignature}; +use app_crypto::{AppPublic, RuntimeAppPublic}; use codec::{Encode, Decode}; use primitives::offchain::{OpaqueNetworkState, StorageKind}; use rstd::prelude::*; diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index dbd265b263..2d70aaeb39 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -257,7 +257,7 @@ use support::{ StorageValue, StorageMap, StorageLinkedMap, decl_module, decl_event, decl_storage, ensure, traits::{ Currency, OnFreeBalanceZero, OnDilution, LockIdentifier, LockableCurrency, - WithdrawReasons, WithdrawReason, OnUnbalanced, Imbalance, Get, Time + WithdrawReasons, OnUnbalanced, Imbalance, Get, Time } }; use session::{historical::OnSessionEnding, SelectInitialValidators}; @@ -1013,7 +1013,7 @@ impl Module { &ledger.stash, ledger.total, T::BlockNumber::max_value(), - WithdrawReasons::except(WithdrawReason::TransactionPayment), + WithdrawReasons::all(), ); >::insert(controller, ledger); } -- GitLab From 1a59e8ced54756081688011fd773f9a915cf2f18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 13 Sep 2019 14:55:33 +0200 Subject: [PATCH 092/275] Fix tracking validator set in ImOnline (#3596) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Use session::validators instead of staking::current_elected * Basic test framework. * Initialize validators, attempt to heartbeat. * Use dummy crypto for im-online testing. * Remove printlns. * Finish test, make it invalid. * Add reporting test. * Finalize the test. * Remove dumbness. * Updates. * Update AuRa * Update srml/im-online/src/tests.rs Co-Authored-By: Bastian Köcher * Derive Ord * Add some more tests. * Remove stray todo. * Bump runtime version. * Bump impl-trait-for-tuples. * Enforce new version of trait-for-tuples. --- Cargo.lock | 20 +-- core/application-crypto/src/lib.rs | 1 + core/application-crypto/src/traits.rs | 5 +- core/authority-discovery/Cargo.toml | 1 - core/offchain/src/testing.rs | 13 +- core/primitives/src/offchain.rs | 2 +- core/sr-primitives/Cargo.toml | 2 +- core/sr-primitives/src/lib.rs | 2 +- core/sr-primitives/src/testing.rs | 55 ++++--- core/sr-primitives/src/traits.rs | 2 +- core/sr-staking-primitives/src/lib.rs | 9 -- node/runtime/src/lib.rs | 3 +- srml/aura/src/lib.rs | 4 +- srml/authority-discovery/src/lib.rs | 9 -- srml/authorship/Cargo.toml | 2 +- srml/finality-tracker/Cargo.toml | 2 +- srml/im-online/Cargo.toml | 3 + srml/im-online/src/lib.rs | 80 ++++------ srml/im-online/src/mock.rs | 162 +++++++++++++++++++ srml/im-online/src/tests.rs | 218 ++++++++++++++++++++++++++ srml/session/Cargo.toml | 2 +- srml/session/src/lib.rs | 10 +- srml/staking/src/lib.rs | 11 +- srml/support/Cargo.toml | 2 +- srml/system/Cargo.toml | 2 +- srml/timestamp/Cargo.toml | 2 +- 26 files changed, 492 insertions(+), 132 deletions(-) create mode 100644 srml/im-online/src/mock.rs create mode 100644 srml/im-online/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index f53a4a1acc..6eefaabce9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1381,7 +1381,7 @@ dependencies = [ [[package]] name = "impl-trait-for-tuples" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3833,7 +3833,7 @@ dependencies = [ name = "sr-primitives" version = "2.0.0" dependencies = [ - "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3946,7 +3946,7 @@ dependencies = [ name = "srml-authorship" version = "0.1.0" dependencies = [ - "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4105,7 +4105,7 @@ dependencies = [ name = "srml-finality-tracker" version = "2.0.0" dependencies = [ - "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4163,6 +4163,7 @@ dependencies = [ "srml-support 2.0.0", "srml-system 2.0.0", "substrate-application-crypto 2.0.0", + "substrate-offchain 2.0.0", "substrate-primitives 2.0.0", ] @@ -4242,7 +4243,7 @@ dependencies = [ name = "srml-session" version = "2.0.0" dependencies = [ - "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4300,7 +4301,7 @@ name = "srml-support" version = "2.0.0" dependencies = [ "bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4366,7 +4367,7 @@ name = "srml-system" version = "2.0.0" dependencies = [ "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4382,7 +4383,7 @@ dependencies = [ name = "srml-timestamp" version = "2.0.0" dependencies = [ - "impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4541,7 +4542,6 @@ dependencies = [ "sr-primitives 2.0.0", "substrate-authority-discovery-primitives 2.0.0", "substrate-client 2.0.0", - "substrate-keystore 2.0.0", "substrate-network 2.0.0", "substrate-peerset 2.0.0", "substrate-primitives 2.0.0", @@ -6620,7 +6620,7 @@ dependencies = [ "checksum impl-codec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "78c441b3d2b5e24b407161e76d482b7bbd29b5da357707839ac40d95152f031f" "checksum impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5158079de9d4158e0ce1de3ae0bd7be03904efc40b3d7dd8b8c301cbf6b52b56" "checksum impl-serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d26be4b97d738552ea423f76c4f681012ff06c3fa36fa968656b3679f60b4a1" -"checksum impl-trait-for-tuples 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3a9213bd15aa3f974ed007e12e520c435af21e0bb9b016c0874f05eec30034cf" +"checksum impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0df44cb13008e863c3d80788d5f4cb0f94d09b31bb0190a8ecc05151b2ac8a" "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" "checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" "checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" diff --git a/core/application-crypto/src/lib.rs b/core/application-crypto/src/lib.rs index d9bff822ee..e3366a461a 100644 --- a/core/application-crypto/src/lib.rs +++ b/core/application-crypto/src/lib.rs @@ -213,6 +213,7 @@ macro_rules! app_crypto { } impl $crate::RuntimeAppPublic for Public where $public: $crate::RuntimePublic { + const ID: $crate::KeyTypeId = $key_type; type Signature = Signature; fn all() -> $crate::Vec { diff --git a/core/application-crypto/src/traits.rs b/core/application-crypto/src/traits.rs index 323c9c3e54..aad076bd90 100644 --- a/core/application-crypto/src/traits.rs +++ b/core/application-crypto/src/traits.rs @@ -96,7 +96,10 @@ pub trait RuntimePublic: Sized { } /// A runtime interface for an application's public key. -pub trait RuntimeAppPublic: Sized { +pub trait RuntimeAppPublic: Sized { + /// An identifier for this application-specific key type. + const ID: KeyTypeId; + /// The signature that will be generated when signing with the corresponding private key. type Signature: Codec + MaybeDebugHash + Eq + PartialEq + Clone; diff --git a/core/authority-discovery/Cargo.toml b/core/authority-discovery/Cargo.toml index cb24a43fdb..f544854b5b 100644 --- a/core/authority-discovery/Cargo.toml +++ b/core/authority-discovery/Cargo.toml @@ -15,7 +15,6 @@ client = { package = "substrate-client", path = "../../core/client" } codec = { package = "parity-scale-codec", default-features = false, version = "1.0.3" } derive_more = "0.14.0" futures = "0.1" -keystore = { package = "substrate-keystore", path = "../../core/keystore" } libp2p = { version = "0.12.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] } log = "0.4" network = { package = "substrate-network", path = "../../core/network" } diff --git a/core/offchain/src/testing.rs b/core/offchain/src/testing.rs index 8724ca7546..496feb4b63 100644 --- a/core/offchain/src/testing.rs +++ b/core/offchain/src/testing.rs @@ -67,6 +67,8 @@ pub struct State { pub persistent_storage: client::in_mem::OffchainStorage, /// Local storage pub local_storage: client::in_mem::OffchainStorage, + /// A vector of transactions submitted from the runtime. + pub transactions: Vec>, } impl State { @@ -138,12 +140,17 @@ impl offchain::Externalities for TestOffchainExt { unimplemented!("not needed in tests so far") } - fn submit_transaction(&mut self, _ex: Vec) -> Result<(), ()> { - unimplemented!("not needed in tests so far") + fn submit_transaction(&mut self, ex: Vec) -> Result<(), ()> { + let mut state = self.0.write(); + state.transactions.push(ex); + Ok(()) } fn network_state(&self) -> Result { - unimplemented!("not needed in tests so far") + Ok(OpaqueNetworkState { + peer_id: Default::default(), + external_addresses: vec![], + }) } fn timestamp(&mut self) -> Timestamp { diff --git a/core/primitives/src/offchain.rs b/core/primitives/src/offchain.rs index c9e78d48e1..6403a20dbd 100644 --- a/core/primitives/src/offchain.rs +++ b/core/primitives/src/offchain.rs @@ -160,7 +160,7 @@ pub struct OpaqueNetworkState { } /// Simple blob to hold a `PeerId` without committing to its format. -#[derive(Clone, Eq, PartialEq, Encode, Decode)] +#[derive(Default, Clone, Eq, PartialEq, Encode, Decode)] #[cfg_attr(feature = "std", derive(Debug))] pub struct OpaquePeerId(pub Vec); diff --git a/core/sr-primitives/Cargo.toml b/core/sr-primitives/Cargo.toml index 19db46e8a2..5369674dca 100644 --- a/core/sr-primitives/Cargo.toml +++ b/core/sr-primitives/Cargo.toml @@ -16,7 +16,7 @@ runtime_io = { package = "sr-io", path = "../sr-io", default-features = false } log = { version = "0.4", optional = true } paste = { version = "0.1"} rand = { version = "0.7.0", optional = true } -impl-trait-for-tuples = "0.1" +impl-trait-for-tuples = "0.1.1" [dev-dependencies] serde_json = "1.0" diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index bcd54c660b..f3d3eabfcb 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -56,7 +56,7 @@ pub use generic::{DigestItem, Digest}; /// Re-export this since it's part of the API of this crate. pub use primitives::crypto::{key_types, KeyTypeId, CryptoType}; -pub use app_crypto::AppKey; +pub use app_crypto::RuntimeAppPublic; /// Justification type. pub type Justification = Vec; diff --git a/core/sr-primitives/src/testing.rs b/core/sr-primitives/src/testing.rs index 9c827d8a70..2284921cb3 100644 --- a/core/sr-primitives/src/testing.rs +++ b/core/sr-primitives/src/testing.rs @@ -17,7 +17,7 @@ //! Testing utilities. use serde::{Serialize, Serializer, Deserialize, de::Error as DeError, Deserializer}; -use std::{fmt::Debug, ops::Deref, fmt}; +use std::{fmt::Debug, ops::Deref, fmt, cell::RefCell}; use crate::codec::{Codec, Encode, Decode}; use crate::traits::{ self, Checkable, Applyable, BlakeTwo256, OpaqueKeys, ValidateUnsigned, @@ -30,9 +30,15 @@ use primitives::{crypto::{CryptoType, Dummy, key_types, Public}, U256}; use crate::transaction_validity::{TransactionValidity, TransactionValidityError}; /// Authority Id -#[derive(Default, PartialEq, Eq, Clone, Encode, Decode, Debug, Hash, Serialize, Deserialize)] +#[derive(Default, PartialEq, Eq, Clone, Encode, Decode, Debug, Hash, Serialize, Deserialize, PartialOrd, Ord)] pub struct UintAuthorityId(pub u64); +impl From for UintAuthorityId { + fn from(id: u64) -> Self { + UintAuthorityId(id) + } +} + impl UintAuthorityId { /// Convert this authority id into a public key. pub fn to_public_key(&self) -> T { @@ -47,34 +53,44 @@ impl CryptoType for UintAuthorityId { impl AsRef<[u8]> for UintAuthorityId { fn as_ref(&self) -> &[u8] { + // Unsafe, i know, but it's test code and it's just there because it's really convenient to + // keep `UintAuthorityId` as a u64 under the hood. unsafe { std::slice::from_raw_parts(&self.0 as *const u64 as *const _, std::mem::size_of::()) } } } +thread_local! { + /// A list of all UintAuthorityId keys returned to the runtime. + static ALL_KEYS: RefCell> = RefCell::new(vec![]); +} + +impl UintAuthorityId { + /// Set the list of keys returned by the runtime call for all keys of that type. + pub fn set_all_keys>(keys: impl IntoIterator) { + ALL_KEYS.with(|l| *l.borrow_mut() = keys.into_iter().map(Into::into).collect()) + } +} + impl app_crypto::RuntimeAppPublic for UintAuthorityId { + const ID: KeyTypeId = key_types::DUMMY; + type Signature = u64; fn all() -> Vec { - unimplemented!("`all()` not available for `UintAuthorityId`.") + ALL_KEYS.with(|l| l.borrow().clone()) } - #[cfg(feature = "std")] fn generate_pair(_: Option<&str>) -> Self { use rand::RngCore; UintAuthorityId(rand::thread_rng().next_u64()) } - #[cfg(not(feature = "std"))] - fn generate_pair(_: Option<&str>) -> Self { - unimplemented!("`generate_pair` not implemented for `UIntAuthorityId` on `no_std`.") - } - fn sign>(&self, msg: &M) -> Option { let mut signature = [0u8; 8]; msg.as_ref().iter() - .chain(rstd::iter::repeat(&42u8)) + .chain(std::iter::repeat(&42u8)) .take(8) .enumerate() .for_each(|(i, v)| { signature[i] = *v; }); @@ -85,7 +101,7 @@ impl app_crypto::RuntimeAppPublic for UintAuthorityId { fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool { let mut msg_signature = [0u8; 8]; msg.as_ref().iter() - .chain(rstd::iter::repeat(&42)) + .chain(std::iter::repeat(&42)) .take(8) .enumerate() .for_each(|(i, v)| { msg_signature[i] = *v; }); @@ -97,19 +113,16 @@ impl app_crypto::RuntimeAppPublic for UintAuthorityId { impl OpaqueKeys for UintAuthorityId { type KeyTypeIds = std::iter::Cloned>; - fn key_ids() -> Self::KeyTypeIds { [key_types::DUMMY].iter().cloned() } - // Unsafe, i know, but it's test code and it's just there because it's really convenient to - // keep `UintAuthorityId` as a u64 under the hood. + fn key_ids() -> Self::KeyTypeIds { + [key_types::DUMMY].iter().cloned() + } + fn get_raw(&self, _: KeyTypeId) -> &[u8] { - unsafe { - std::slice::from_raw_parts( - &self.0 as *const _ as *const u8, - std::mem::size_of::(), - ) - } + self.as_ref() } + fn get(&self, _: KeyTypeId) -> Option { - self.0.using_encoded(|mut x| T::decode(&mut x)).ok() + self.using_encoded(|mut x| T::decode(&mut x)).ok() } } diff --git a/core/sr-primitives/src/traits.rs b/core/sr-primitives/src/traits.rs index 080b7bc948..0479f9401c 100644 --- a/core/sr-primitives/src/traits.rs +++ b/core/sr-primitives/src/traits.rs @@ -39,7 +39,7 @@ use rstd::ops::{ Add, Sub, Mul, Div, Rem, AddAssign, SubAssign, MulAssign, DivAssign, RemAssign, Shl, Shr }; -use crate::AppKey; +use app_crypto::AppKey; use impl_trait_for_tuples::impl_for_tuples; /// A lazy value. diff --git a/core/sr-staking-primitives/src/lib.rs b/core/sr-staking-primitives/src/lib.rs index 63a5eb2927..182307cb47 100644 --- a/core/sr-staking-primitives/src/lib.rs +++ b/core/sr-staking-primitives/src/lib.rs @@ -17,16 +17,7 @@ //! A crate which contains primitives that are useful for implementation that uses staking //! approaches in general. Definitions related to sessions, slashing, etc go here. -use rstd::vec::Vec; - pub mod offence; /// Simple index type with which we can count sessions. pub type SessionIndex = u32; - -/// A trait for getting the currently elected validator set without coupling to the module that -/// provides this information. -pub trait CurrentElectedSet { - /// Returns the validator ids for the currently elected validator set. - fn current_elected_set() -> Vec; -} diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 05f5798836..bc2d6201b7 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 157, - impl_version: 158, + impl_version: 159, apis: RUNTIME_API_VERSIONS, }; @@ -409,7 +409,6 @@ impl im_online::Trait for Runtime { type Event = Event; type SubmitTransaction = SubmitTransaction; type ReportUnresponsiveness = Offences; - type CurrentElectedSet = staking::CurrentElectedStashAccounts; } impl offences::Trait for Runtime { diff --git a/srml/aura/src/lib.rs b/srml/aura/src/lib.rs index f2b6818a45..0cca231ae1 100644 --- a/srml/aura/src/lib.rs +++ b/srml/aura/src/lib.rs @@ -53,8 +53,8 @@ use support::{ decl_storage, decl_module, Parameter, storage::StorageValue, traits::{Get, FindAuthor}, ConsensusEngineId, }; -use app_crypto::AppPublic; use sr_primitives::{ + RuntimeAppPublic, traits::{SaturatedConversion, Saturating, Zero, Member, IsMember}, generic::DigestItem, }; use timestamp::OnTimestampSet; @@ -142,7 +142,7 @@ impl ProvideInherentData for InherentDataProvider { pub trait Trait: timestamp::Trait { /// The identifier type for an authority. - type AuthorityId: Member + Parameter + AppPublic + Default; + type AuthorityId: Member + Parameter + RuntimeAppPublic + Default; } decl_storage! { diff --git a/srml/authority-discovery/src/lib.rs b/srml/authority-discovery/src/lib.rs index 1c46822dfe..372a48cc7f 100644 --- a/srml/authority-discovery/src/lib.rs +++ b/srml/authority-discovery/src/lib.rs @@ -137,7 +137,6 @@ mod tests { use sr_primitives::testing::{Header, UintAuthorityId}; use sr_primitives::traits::{ConvertInto, IdentityLookup, OpaqueKeys}; use sr_primitives::Perbill; - use sr_staking_primitives::CurrentElectedSet; use support::{impl_outer_origin, parameter_types}; type AuthorityDiscovery = Module; @@ -149,13 +148,6 @@ mod tests { type AuthorityId = im_online::sr25519::AuthorityId; - pub struct DummyCurrentElectedSet(std::marker::PhantomData); - impl CurrentElectedSet for DummyCurrentElectedSet { - fn current_elected_set() -> Vec { - vec![] - } - } - pub struct TestOnSessionEnding; impl session::OnSessionEnding for TestOnSessionEnding { fn on_session_ending(_: SessionIndex, _: SessionIndex) -> Option> { @@ -189,7 +181,6 @@ mod tests { UncheckedExtrinsic<(), im_online::Call, (), ()>, >; type ReportUnresponsiveness = (); - type CurrentElectedSet = DummyCurrentElectedSet; } pub type BlockNumber = u64; diff --git a/srml/authorship/Cargo.toml b/srml/authorship/Cargo.toml index 7bb2af2632..03c7fb9d07 100644 --- a/srml/authorship/Cargo.toml +++ b/srml/authorship/Cargo.toml @@ -14,7 +14,7 @@ sr-primitives = { path = "../../core/sr-primitives", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } -impl-trait-for-tuples = "0.1" +impl-trait-for-tuples = "0.1.1" [features] default = ["std"] diff --git a/srml/finality-tracker/Cargo.toml b/srml/finality-tracker/Cargo.toml index ba6c5b7c8f..6e9cf12f74 100644 --- a/srml/finality-tracker/Cargo.toml +++ b/srml/finality-tracker/Cargo.toml @@ -12,7 +12,7 @@ rstd = { package = "sr-std", path = "../../core/sr-std", default-features = fals sr-primitives = { path = "../../core/sr-primitives", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } srml-system = { path = "../system", default-features = false } -impl-trait-for-tuples = "0.1" +impl-trait-for-tuples = "0.1.1" [dev-dependencies] primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } diff --git a/srml/im-online/Cargo.toml b/srml/im-online/Cargo.toml index 3dc7da86f1..9dc44f38ba 100644 --- a/srml/im-online/Cargo.toml +++ b/srml/im-online/Cargo.toml @@ -17,6 +17,9 @@ sr-staking-primitives = { path = "../../core/sr-staking-primitives", default-fea support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } +[dev-dependencies] +offchain = { package = "substrate-offchain", path = "../../core/offchain" } + [features] default = ["std", "session/historical"] std = [ diff --git a/srml/im-online/src/lib.rs b/srml/im-online/src/lib.rs index 6106b1e45c..5daa39299d 100644 --- a/srml/im-online/src/lib.rs +++ b/srml/im-online/src/lib.rs @@ -67,7 +67,10 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -use app_crypto::{AppPublic, RuntimeAppPublic}; +mod mock; +mod tests; + +use app_crypto::RuntimeAppPublic; use codec::{Encode, Decode}; use primitives::offchain::{OpaqueNetworkState, StorageKind}; use rstd::prelude::*; @@ -80,7 +83,7 @@ use sr_primitives::{ }, }; use sr_staking_primitives::{ - SessionIndex, CurrentElectedSet, + SessionIndex, offence::{ReportOffence, Offence, Kind}, }; use support::{ @@ -136,15 +139,15 @@ pub mod ed25519 { pub type AuthorityId = app_ed25519::Public; } -// The local storage database key under which the worker progress status -// is tracked. +/// The local storage database key under which the worker progress status +/// is tracked. const DB_KEY: &[u8] = b"srml/im-online-worker-status"; -// It's important to persist the worker state, since e.g. the -// server could be restarted while starting the gossip process, but before -// finishing it. With every execution of the off-chain worker we check -// if we need to recover and resume gossipping or if there is already -// another off-chain worker in the process of gossipping. +/// It's important to persist the worker state, since e.g. the +/// server could be restarted while starting the gossip process, but before +/// finishing it. With every execution of the off-chain worker we check +/// if we need to recover and resume gossipping or if there is already +/// another off-chain worker in the process of gossipping. #[derive(Encode, Decode, Clone, PartialEq, Eq)] #[cfg_attr(feature = "std", derive(Debug))] struct WorkerStatus { @@ -152,7 +155,8 @@ struct WorkerStatus { gossipping_at: BlockNumber, } -// Error which may occur while executing the off-chain code. +/// Error which may occur while executing the off-chain code. +#[cfg_attr(feature = "std", derive(Debug))] enum OffchainErr { DecodeWorkerStatus, FailedSigning, @@ -187,7 +191,7 @@ pub struct Heartbeat pub trait Trait: system::Trait + session::historical::Trait { /// The identifier type for an authority. - type AuthorityId: Member + Parameter + AppPublic + RuntimeAppPublic + Default; + type AuthorityId: Member + Parameter + RuntimeAppPublic + Default + Ord; /// The overarching event type. type Event: From> + Into<::Event>; @@ -205,9 +209,6 @@ pub trait Trait: system::Trait + session::historical::Trait { IdentificationTuple, UnresponsivenessOffence>, >; - - /// A type that returns a validator id from the current elected set of the era. - type CurrentElectedSet: CurrentElectedSet<::ValidatorId>; } decl_event!( @@ -272,6 +273,10 @@ decl_module! { &heartbeat.authority_index, &network_state ); + } else if exists { + Err("Duplicated heartbeat.")? + } else { + Err("Non existent public key.")? } } @@ -293,7 +298,7 @@ impl Module { ::exists(¤t_session, &authority_index) } - fn offchain(now: T::BlockNumber) { + pub(crate) fn offchain(now: T::BlockNumber) { let next_gossip = >::get(); let check = Self::check_not_yet_gossipped(now, next_gossip); let (curr_worker_status, not_yet_gossipped) = match check { @@ -450,19 +455,16 @@ impl session::OneSessionHandler for Module { let current_session = >::current_index(); let keys = Keys::::get(); - let current_elected = T::CurrentElectedSet::current_elected_set(); + let current_validators = >::validators(); - // The invariant is that these two are of the same length. - // TODO: What to do: Uncomment, ignore, a third option? - // assert_eq!(keys.len(), current_elected.len()); - - for (auth_idx, validator_id) in current_elected.into_iter().enumerate() { + for (auth_idx, validator_id) in current_validators.into_iter().enumerate() { let auth_idx = auth_idx as u32; - if !::exists(¤t_session, &auth_idx) { + let exists = ::exists(¤t_session, &auth_idx); + if !exists { let full_identification = T::FullIdentificationOf::convert(validator_id.clone()) .expect( - "we got the validator_id from current_elected; - current_elected is set of currently elected validators; + "we got the validator_id from current_validators; + current_validators is set of currently acting validators; the mapping between the validator id and its full identification should be valid; thus `FullIdentificationOf::convert` can't return `None`; qed", @@ -472,6 +474,10 @@ impl session::OneSessionHandler for Module { } } + if unresponsive.is_empty() { + return; + } + let validator_set_count = keys.len() as u32; let offence = UnresponsivenessOffence { session_index: current_session, @@ -533,6 +539,7 @@ impl support::unsigned::ValidateUnsigned for Module { } /// An offence that is filed if a validator didn't send a heartbeat message. +#[cfg_attr(feature = "std", derive(Clone, Debug, PartialEq, Eq))] pub struct UnresponsivenessOffence { /// The current session index in which we report the unresponsive validators. /// @@ -577,28 +584,3 @@ impl Offence for UnresponsivenessOffence { Perbill::from_parts(p as u32) } } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_unresponsiveness_slash_fraction() { - // A single case of unresponsiveness is not slashed. - assert_eq!( - UnresponsivenessOffence::<()>::slash_fraction(1, 50), - Perbill::zero(), - ); - - assert_eq!( - UnresponsivenessOffence::<()>::slash_fraction(3, 50), - Perbill::from_parts(6000000), // 0.6% - ); - - // One third offline should be punished around 5%. - assert_eq!( - UnresponsivenessOffence::<()>::slash_fraction(17, 50), - Perbill::from_parts(48000000), // 4.8% - ); - } -} diff --git a/srml/im-online/src/mock.rs b/srml/im-online/src/mock.rs new file mode 100644 index 0000000000..ba1a7a7d0a --- /dev/null +++ b/srml/im-online/src/mock.rs @@ -0,0 +1,162 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Test utilities + +#![cfg(test)] + +use std::cell::RefCell; + +use crate::{Module, Trait}; +use sr_primitives::Perbill; +use sr_staking_primitives::{SessionIndex, offence::ReportOffence}; +use sr_primitives::testing::{Header, UintAuthorityId, TestXt}; +use sr_primitives::traits::{IdentityLookup, BlakeTwo256, ConvertInto}; +use primitives::{H256, Blake2Hasher}; +use support::{impl_outer_origin, impl_outer_dispatch, parameter_types}; +use {runtime_io, system}; + +impl_outer_origin!{ + pub enum Origin for Runtime {} +} + +impl_outer_dispatch! { + pub enum Call for Runtime where origin: Origin { + imonline::ImOnline, + } +} + +thread_local! { + pub static VALIDATORS: RefCell>> = RefCell::new(Some(vec![1, 2, 3])); +} + +pub struct TestOnSessionEnding; +impl session::OnSessionEnding for TestOnSessionEnding { + fn on_session_ending(_ending_index: SessionIndex, _will_apply_at: SessionIndex) + -> Option> + { + VALIDATORS.with(|l| l.borrow_mut().take()) + } +} + +impl session::historical::OnSessionEnding for TestOnSessionEnding { + fn on_session_ending(_ending_index: SessionIndex, _will_apply_at: SessionIndex) + -> Option<(Vec, Vec<(u64, u64)>)> + { + VALIDATORS.with(|l| l + .borrow_mut() + .take() + .map(|validators| { + let full_identification = validators.iter().map(|v| (*v, *v)).collect(); + (validators, full_identification) + }) + ) + } +} + +/// An extrinsic type used for tests. +pub type Extrinsic = TestXt; +type SubmitTransaction = system::offchain::TransactionSubmitter<(), Call, Extrinsic>; +type IdentificationTuple = (u64, u64); +type Offence = crate::UnresponsivenessOffence; + +thread_local! { + pub static OFFENCES: RefCell, Offence)>> = RefCell::new(vec![]); +} + +/// A mock offence report handler. +pub struct OffenceHandler; +impl ReportOffence for OffenceHandler { + fn report_offence(reporters: Vec, offence: Offence) { + OFFENCES.with(|l| l.borrow_mut().push((reporters, offence))); + } +} + +pub fn new_test_ext() -> runtime_io::TestExternalities { + let t = system::GenesisConfig::default().build_storage::().unwrap(); + t.into() +} + + +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct Runtime; + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); +} + +impl system::Trait for Runtime { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = Call; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type WeightMultiplierUpdate = (); + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); +} + +parameter_types! { + pub const Period: u64 = 1; + pub const Offset: u64 = 0; +} + +impl session::Trait for Runtime { + type ShouldEndSession = session::PeriodicSessions; + type OnSessionEnding = session::historical::NoteHistoricalRoot; + type SessionHandler = (ImOnline, ); + type ValidatorId = u64; + type ValidatorIdOf = ConvertInto; + type Keys = UintAuthorityId; + type Event = (); + type SelectInitialValidators = (); +} + +impl session::historical::Trait for Runtime { + type FullIdentification = u64; + type FullIdentificationOf = ConvertInto; +} + +impl Trait for Runtime { + type AuthorityId = UintAuthorityId; + type Event = (); + type Call = Call; + type SubmitTransaction = SubmitTransaction; + type ReportUnresponsiveness = OffenceHandler; +} + +/// Im Online module. +pub type ImOnline = Module; +pub type System = system::Module; +pub type Session = session::Module; + +pub fn advance_session() { + let now = System::block_number(); + System::set_block_number(now + 1); + Session::rotate_session(); + assert_eq!(Session::current_index(), (now / Period::get()) as u32); +} diff --git a/srml/im-online/src/tests.rs b/srml/im-online/src/tests.rs new file mode 100644 index 0000000000..4f6702780f --- /dev/null +++ b/srml/im-online/src/tests.rs @@ -0,0 +1,218 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Tests for the im-online module. + +#![cfg(test)] + +use super::*; +use crate::mock::*; +use offchain::testing::TestOffchainExt; +use primitives::offchain::OpaquePeerId; +use runtime_io::with_externalities; +use support::{dispatch, assert_noop}; +use sr_primitives::testing::UintAuthorityId; + + +#[test] +fn test_unresponsiveness_slash_fraction() { + // A single case of unresponsiveness is not slashed. + assert_eq!( + UnresponsivenessOffence::<()>::slash_fraction(1, 50), + Perbill::zero(), + ); + + assert_eq!( + UnresponsivenessOffence::<()>::slash_fraction(3, 50), + Perbill::from_parts(6000000), // 0.6% + ); + + // One third offline should be punished around 5%. + assert_eq!( + UnresponsivenessOffence::<()>::slash_fraction(17, 50), + Perbill::from_parts(48000000), // 4.8% + ); +} + +#[test] +fn should_report_offline_validators() { + with_externalities(&mut new_test_ext(), || { + // given + let block = 1; + System::set_block_number(block); + // buffer new validators + Session::rotate_session(); + // enact the change and buffer another one + let validators = vec![1, 2, 3, 4, 5, 6]; + VALIDATORS.with(|l| *l.borrow_mut() = Some(validators.clone())); + Session::rotate_session(); + + // when + // we end current session and start the next one + Session::rotate_session(); + + // then + let offences = OFFENCES.with(|l| l.replace(vec![])); + assert_eq!(offences, vec![ + (vec![], UnresponsivenessOffence { + session_index: 2, + validator_set_count: 3, + offenders: vec![ + (1, 1), + (2, 2), + (3, 3), + ], + }) + ]); + + // should not report when heartbeat is sent + for (idx, v) in validators.into_iter().take(4).enumerate() { + let _ = heartbeat(block, 3, idx as u32, v.into()).unwrap(); + } + Session::rotate_session(); + + // then + let offences = OFFENCES.with(|l| l.replace(vec![])); + assert_eq!(offences, vec![ + (vec![], UnresponsivenessOffence { + session_index: 3, + validator_set_count: 6, + offenders: vec![ + (5, 5), + (6, 6), + ], + }) + ]); + }); +} + +fn heartbeat( + block_number: u64, + session_index: u32, + authority_index: u32, + id: UintAuthorityId, +) -> dispatch::Result { + let heartbeat = Heartbeat { + block_number, + network_state: OpaqueNetworkState { + peer_id: OpaquePeerId(vec![1]), + external_addresses: vec![], + }, + session_index, + authority_index, + }; + let signature = id.sign(&heartbeat.encode()).unwrap(); + + ImOnline::heartbeat( + Origin::system(system::RawOrigin::None), + heartbeat, + signature + ) +} + +#[test] +fn should_mark_online_validator_when_heartbeat_is_received() { + with_externalities(&mut new_test_ext(), || { + advance_session(); + // given + VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 3, 4, 5, 6])); + assert_eq!(Session::validators(), Vec::::new()); + // enact the change and buffer another one + advance_session(); + + assert_eq!(Session::current_index(), 2); + assert_eq!(Session::validators(), vec![1, 2, 3]); + + assert!(!ImOnline::is_online_in_current_session(0)); + assert!(!ImOnline::is_online_in_current_session(1)); + assert!(!ImOnline::is_online_in_current_session(2)); + + // when + let _ = heartbeat(1, 2, 0, 1.into()).unwrap(); + + // then + assert!(ImOnline::is_online_in_current_session(0)); + assert!(!ImOnline::is_online_in_current_session(1)); + assert!(!ImOnline::is_online_in_current_session(2)); + + // and when + let _ = heartbeat(1, 2, 2, 3.into()).unwrap(); + + // then + assert!(ImOnline::is_online_in_current_session(0)); + assert!(!ImOnline::is_online_in_current_session(1)); + assert!(ImOnline::is_online_in_current_session(2)); + }); +} + +#[test] +fn late_heartbeat_should_fail() { + with_externalities(&mut new_test_ext(), || { + advance_session(); + // given + VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 4, 4, 5, 6])); + assert_eq!(Session::validators(), Vec::::new()); + // enact the change and buffer another one + advance_session(); + + assert_eq!(Session::current_index(), 2); + assert_eq!(Session::validators(), vec![1, 2, 3]); + + // when + assert_noop!(heartbeat(1, 3, 0, 1.into()), "Outdated heartbeat received."); + assert_noop!(heartbeat(1, 1, 0, 1.into()), "Outdated heartbeat received."); + }); +} + +#[test] +fn should_generate_heartbeats() { + let mut ext = new_test_ext(); + let (offchain, state) = TestOffchainExt::new(); + ext.set_offchain_externalities(offchain); + + with_externalities(&mut ext, || { + // given + let block = 1; + System::set_block_number(block); + // buffer new validators + Session::rotate_session(); + // enact the change and buffer another one + VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 3, 4, 5, 6])); + Session::rotate_session(); + + // when + UintAuthorityId::set_all_keys(vec![0, 1, 2]); + ImOnline::offchain(2); + + // then + let transaction = state.write().transactions.pop().unwrap(); + // All validators have `0` as their session key, so we generate 3 transactions. + assert_eq!(state.read().transactions.len(), 2); + // check stuff about the transaction. + let ex: Extrinsic = Decode::decode(&mut &*transaction).unwrap(); + let heartbeat = match ex.1 { + crate::mock::Call::ImOnline(crate::Call::heartbeat(h, _)) => h, + e => panic!("Unexpected call: {:?}", e), + }; + + assert_eq!(heartbeat, Heartbeat { + block_number: 2, + network_state: runtime_io::network_state().unwrap(), + session_index: 2, + authority_index: 2, + }); + }); +} diff --git a/srml/session/Cargo.toml b/srml/session/Cargo.toml index 2e7f5eda80..cd58095815 100644 --- a/srml/session/Cargo.toml +++ b/srml/session/Cargo.toml @@ -16,7 +16,7 @@ system = { package = "srml-system", path = "../system", default-features = false timestamp = { package = "srml-timestamp", path = "../timestamp", default-features = false } substrate-trie = { path = "../../core/trie", default-features = false, optional = true } runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } -impl-trait-for-tuples = "0.1" +impl-trait-for-tuples = "0.1.1" [dev-dependencies] primitives = { package = "substrate-primitives", path = "../../core/primitives" } diff --git a/srml/session/src/lib.rs b/srml/session/src/lib.rs index 63566fd881..8edb80e8cb 100644 --- a/srml/session/src/lib.rs +++ b/srml/session/src/lib.rs @@ -121,7 +121,7 @@ use rstd::{prelude::*, marker::PhantomData, ops::{Sub, Rem}}; use codec::Decode; -use sr_primitives::{KeyTypeId, AppKey}; +use sr_primitives::{KeyTypeId, RuntimeAppPublic}; use sr_primitives::weights::SimpleDispatchInfo; use sr_primitives::traits::{Convert, Zero, Member, OpaqueKeys}; use sr_staking_primitives::SessionIndex; @@ -222,7 +222,7 @@ pub trait SessionHandler { /// A session handler for specific key type. pub trait OneSessionHandler { /// The key type expected. - type Key: Decode + Default + AppKey; + type Key: Decode + Default + RuntimeAppPublic; fn on_genesis_session<'a, I: 'a>(validators: I) where I: Iterator, ValidatorId: 'a; @@ -262,7 +262,7 @@ impl SessionHandler for Tuple { for_tuples!( #( let our_keys: Box> = Box::new(validators.iter() - .map(|k| (&k.0, k.1.get::(::ID) + .map(|k| (&k.0, k.1.get::(::ID) .unwrap_or_default()))); Tuple::on_genesis_session(our_keys); @@ -278,10 +278,10 @@ impl SessionHandler for Tuple { for_tuples!( #( let our_keys: Box> = Box::new(validators.iter() - .map(|k| (&k.0, k.1.get::(::ID) + .map(|k| (&k.0, k.1.get::(::ID) .unwrap_or_default()))); let queued_keys: Box> = Box::new(queued_validators.iter() - .map(|k| (&k.0, k.1.get::(::ID) + .map(|k| (&k.0, k.1.get::(::ID) .unwrap_or_default()))); Tuple::on_new_session(changed, our_keys, queued_keys); )* diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index 2d70aaeb39..7f371a3c7b 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -269,7 +269,7 @@ use sr_primitives::traits::{ }; use phragmen::{elect, equalize, Support, SupportMap, ExtendedBalance, ACCURACY}; use sr_staking_primitives::{ - SessionIndex, CurrentElectedSet, + SessionIndex, offence::{OnOffenceHandler, OffenceDetails, Offence, ReportOffence}, }; #[cfg(feature = "std")] @@ -1586,12 +1586,3 @@ impl ReportOffence } } } - -/// Returns the currently elected validator set represented by their stash accounts. -pub struct CurrentElectedStashAccounts(rstd::marker::PhantomData); - -impl CurrentElectedSet for CurrentElectedStashAccounts { - fn current_elected_set() -> Vec { - >::current_elected() - } -} diff --git a/srml/support/Cargo.toml b/srml/support/Cargo.toml index 7a3e0d26e4..731c6b1c45 100644 --- a/srml/support/Cargo.toml +++ b/srml/support/Cargo.toml @@ -17,7 +17,7 @@ srml-support-procedural = { package = "srml-support-procedural", path = "./proce paste = "0.1" once_cell = { version = "0.1.6", default-features = false, optional = true } bitmask = { version = "0.5", default-features = false } -impl-trait-for-tuples = "0.1" +impl-trait-for-tuples = "0.1.1" [dev-dependencies] pretty_assertions = "0.6.1" diff --git a/srml/system/Cargo.toml b/srml/system/Cargo.toml index fd8ae735a9..344e59dd49 100644 --- a/srml/system/Cargo.toml +++ b/srml/system/Cargo.toml @@ -14,7 +14,7 @@ runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = f sr-primitives = { path = "../../core/sr-primitives", default-features = false } sr-version = { path = "../../core/sr-version", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } -impl-trait-for-tuples = "0.1" +impl-trait-for-tuples = "0.1.1" [dev-dependencies] criterion = "0.2" diff --git a/srml/timestamp/Cargo.toml b/srml/timestamp/Cargo.toml index 00eaf7d7f8..6a30ad69d0 100644 --- a/srml/timestamp/Cargo.toml +++ b/srml/timestamp/Cargo.toml @@ -12,7 +12,7 @@ sr-primitives = { path = "../../core/sr-primitives", default-features = false } inherents = { package = "substrate-inherents", path = "../../core/inherents", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } -impl-trait-for-tuples = "0.1" +impl-trait-for-tuples = "0.1.1" [dev-dependencies] runtime-io ={ package = "sr-io", path = "../../core/sr-io" } -- GitLab From ddb8512a68a6cddf5089e0618553660b916f03fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Fri, 13 Sep 2019 15:47:15 +0200 Subject: [PATCH 093/275] Fixes for allocator + factory + misc improvements (#3534) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Clear up import/export misunderstandings * Fetch minimum period from runtime * Remove unnecessary comment This variable is already fetched from the runtime in the line below. * Fix bug in factory The `best_block_id` stayed the same, it was always the genesis hash. This resulted in the factory failing after 4096 blocks, since `client/db` discards hashes (in this case the genesis hash) after 4096 blocks from the database. * Fix tense in error message * Improve allocator documentation * Fix bug in allocator Under certain circumstances an invalid pointer was returned: when the `ptr` was calculated as equal to the `max_heap_size`. This is an invalid pointer since there is no access allowed after the heap limit. The way to provoke this was to repeatedly allocate with sizes which were previously not allocated and immediately deallocate right afterwards. What this did was to increment the `bumper` with each allocation, whilst keeping the `total_size` of the heap `0`. If this repeated allocation/deallocation scheme resulted in `max_heap_size == ptr` the `ptr` was still returned. The allocator only checked if the `total_size` was still within the `max_heap_size` limits, and not if the resulting `ptr` was still within the valid heap region. This commit introduces a check to validate if the calculated `ptr` is within the heap. * Add test for zero byte allocation and document behavior * Improve code readability by introducing a const * Fix error message in test * Apply suggestions from code review Co-Authored-By: Bastian Köcher * Fix code review suggestions * Replace early return with assertion * Remove test for zero size allocations * Shorten test code * Shorten comment * Make bump() return Result * Add comment for bump() * Remove ambiguous comment * Replace value with const * Use proof for panic message * Fix merge * Add comment regarding minimum allocation size --- core/cli/src/params.rs | 4 +- core/executor/src/allocator.rs | 187 ++++++++++++++++------ core/executor/src/error.rs | 4 +- node/cli/src/factory_impl.rs | 11 +- test-utils/transaction-factory/src/lib.rs | 3 +- 5 files changed, 147 insertions(+), 62 deletions(-) diff --git a/core/cli/src/params.rs b/core/cli/src/params.rs index 0f58527287..d27976b22e 100644 --- a/core/cli/src/params.rs +++ b/core/cli/src/params.rs @@ -705,7 +705,9 @@ impl StructOpt for CoreParams where ) .subcommand( ExportBlocksCmd::augment_clap(SubCommand::with_name("export-blocks")) - .about("Export blocks to a file.") + .about("Export blocks to a file. This file can only be re-imported \ + if it is in binary format (not JSON!)." + ) ) .subcommand( ImportBlocksCmd::augment_clap(SubCommand::with_name("import-blocks")) diff --git a/core/executor/src/allocator.rs b/core/executor/src/allocator.rs index 024af84768..d326b96622 100644 --- a/core/executor/src/allocator.rs +++ b/core/executor/src/allocator.rs @@ -15,14 +15,45 @@ // along with Substrate. If not, see . //! This module implements a freeing-bump allocator. -//! See more details at https://github.com/paritytech/substrate/issues/1615. +//! +//! The algorithm is as follows: +//! We store `N` linked list heads, where `N` is the total number of sizes +//! of allocations to support. A simple set is powers of two from 8 bytes +//! to 16,777,216 bytes (2^3 - 2^24 inclusive), resulting in `N = 22`: +//! +//! ```ignore +//! let mut heads [u64; N] = [0; N]; +//! fn size(n: u64) -> u64 { 8 << n } +//! let mut bumper = 0; +//! fn bump(n: u64) -> u64 { let res = bumper; bumper += n; res } +//! ``` +//! +//! We assume there is a slab of heap to be allocated: +//! +//! ```ignore +//! let mut heap = [0u8; HEAP_SIZE]; +//! ``` +//! +//! Whenever we allocate, we select the lowest linked list item size that +//! will fit the allocation (i.e. the next highest power of two). +//! We then check to see if the linked list is empty. If empty, we use +//! the bump allocator to get the allocation with an extra 8 bytes +//! preceding it. We initialise those preceding 8 bytes to identify the +//! list to which it belongs (e.g. `0x__ffffffffffffff` where `__` is the +//! linked list index). If it is not empty, we unlink the first item from +//! the linked list and then reset the 8 preceding bytes so they now record +//! the identity of the linked list. +//! +//! To deallocate we use the preceding 8 bytes of the allocation to knit +//! back the allocation into the linked list from the head. use crate::error::{Error, Result}; use log::trace; use wasmi::{MemoryRef, memory_units::Bytes}; use wasm_interface::{Pointer, WordSize}; -// The pointers need to be aligned to 8 bytes. +// The pointers need to be aligned to 8 bytes. This is because the +// maximum value type handled by wasm32 is u64. const ALIGNMENT: u32 = 8; // The pointer returned by `allocate()` needs to fulfill the alignment @@ -32,6 +63,11 @@ const ALIGNMENT: u32 = 8; // index) and then a subsequent item of 2^x bytes, where x = [3..24]. const N: usize = 22; const MAX_POSSIBLE_ALLOCATION: u32 = 16777216; // 2^24 bytes +const MIN_POSSIBLE_ALLOCATION: u32 = 8; + +// Each pointer is prefixed with 8 bytes, which identify the list index +// to which it belongs. +const PREFIX_SIZE: u32 = 8; pub struct FreeingBumpHeapAllocator { bumper: u32, @@ -79,14 +115,17 @@ impl FreeingBumpHeapAllocator { /// Gets requested number of bytes to allocate and returns a pointer. /// The maximum size which can be allocated at once is 16 MiB. + /// There is no minimum size, but whatever size is passed into + /// this function is rounded to the next power of two. If the requested + /// size is below 8 bytes it will be rounded up to 8 bytes. pub fn allocate(&mut self, size: WordSize) -> Result> { if size > MAX_POSSIBLE_ALLOCATION { return Err(Error::RequestedAllocationTooLarge); } - let size = size.max(8); + let size = size.max(MIN_POSSIBLE_ALLOCATION); let item_size = size.next_power_of_two(); - if item_size + 8 + self.total_size > self.max_heap_size { + if item_size + PREFIX_SIZE + self.total_size > self.max_heap_size { return Err(Error::AllocatorOutOfSpace); } @@ -94,19 +133,27 @@ impl FreeingBumpHeapAllocator { let ptr: u32 = if self.heads[list_index] != 0 { // Something from the free list let item = self.heads[list_index]; + let ptr = item + PREFIX_SIZE; + assert!( + ptr + item_size <= self.max_heap_size, + "Pointer is looked up in list of free entries, into which + only valid values are inserted; qed" + ); + let four_bytes = self.get_heap_4bytes(item)?; self.heads[list_index] = Self::le_bytes_to_u32(four_bytes); - item + 8 + ptr } else { // Nothing to be freed. Bump. - self.bump(item_size + 8) + 8 + self.bump(item_size)? + PREFIX_SIZE }; - (1..8).try_for_each(|i| self.set_heap(ptr - i, 255))?; + // Reset prefix + (1..PREFIX_SIZE).try_for_each(|i| self.set_heap(ptr - i, 255))?; - self.set_heap(ptr - 8, list_index as u8)?; + self.set_heap(ptr - PREFIX_SIZE, list_index as u8)?; - self.total_size = self.total_size + item_size + 8; + self.total_size = self.total_size + item_size + PREFIX_SIZE; trace!(target: "wasm-heap", "Heap size is {} bytes after allocation", self.total_size); Ok(Pointer::new(self.ptr_offset + ptr)) @@ -115,31 +162,42 @@ impl FreeingBumpHeapAllocator { /// Deallocates the space which was allocated for a pointer. pub fn deallocate(&mut self, ptr: Pointer) -> Result<()> { let ptr = u32::from(ptr) - self.ptr_offset; - if ptr < 8 { + if ptr < PREFIX_SIZE { return Err(error("Invalid pointer for deallocation")); } - let list_index = usize::from(self.get_heap_byte(ptr - 8)?); - (1..8).try_for_each(|i| self.get_heap_byte(ptr - i).map(|byte| assert!(byte == 255)))?; + let list_index = usize::from(self.get_heap_byte(ptr - PREFIX_SIZE)?); + (1..PREFIX_SIZE).try_for_each(|i| + self.get_heap_byte(ptr - i).map(|byte| assert!(byte == 255)) + )?; let tail = self.heads[list_index]; - self.heads[list_index] = ptr - 8; + self.heads[list_index] = ptr - PREFIX_SIZE; - let mut slice = self.get_heap_4bytes(ptr - 8)?; + let mut slice = self.get_heap_4bytes(ptr - PREFIX_SIZE)?; Self::write_u32_into_le_bytes(tail, &mut slice); - self.set_heap_4bytes(ptr - 8, slice)?; + self.set_heap_4bytes(ptr - PREFIX_SIZE, slice)?; let item_size = Self::get_item_size_from_index(list_index); - self.total_size = self.total_size.checked_sub(item_size as u32 + 8) + self.total_size = self.total_size.checked_sub(item_size as u32 + PREFIX_SIZE) .ok_or_else(|| error("Unable to subtract from total heap size without overflow"))?; trace!(target: "wasm-heap", "Heap size is {} bytes after deallocation", self.total_size); Ok(()) } - fn bump(&mut self, n: u32) -> u32 { + /// Increases the `bumper` by `item_size + PREFIX_SIZE`. + /// + /// Returns the `bumper` from before the increase. + /// Returns an `Error::AllocatorOutOfSpace` if the operation + /// would exhaust the heap. + fn bump(&mut self, item_size: u32) -> Result { + if self.bumper + PREFIX_SIZE + item_size > self.max_heap_size { + return Err(Error::AllocatorOutOfSpace); + } + let res = self.bumper; - self.bumper += n; - res + self.bumper += item_size + PREFIX_SIZE; + Ok(res) } fn le_bytes_to_u32(arr: [u8; 4]) -> u32 { @@ -199,7 +257,8 @@ mod tests { let ptr = heap.allocate(1).unwrap(); // then - assert_eq!(ptr, to_pointer(8)); + // returned pointer must start right after `PREFIX_SIZE` + assert_eq!(ptr, to_pointer(PREFIX_SIZE)); } #[test] @@ -230,14 +289,14 @@ mod tests { // then // a prefix of 8 bytes is prepended to each pointer - assert_eq!(ptr1, to_pointer(8)); + assert_eq!(ptr1, to_pointer(PREFIX_SIZE)); // the prefix of 8 bytes + the content of ptr1 padded to the lowest possible // item size of 8 bytes + the prefix of ptr1 assert_eq!(ptr2, to_pointer(24)); // ptr2 + its content of 16 bytes + the prefix of 8 bytes - assert_eq!(ptr3, to_pointer(24 + 16 + 8)); + assert_eq!(ptr3, to_pointer(24 + 16 + PREFIX_SIZE)); } #[test] @@ -247,7 +306,7 @@ mod tests { let mut heap = FreeingBumpHeapAllocator::new(mem, 0); let ptr1 = heap.allocate(1).unwrap(); // the prefix of 8 bytes is prepended to the pointer - assert_eq!(ptr1, to_pointer(8)); + assert_eq!(ptr1, to_pointer(PREFIX_SIZE)); let ptr2 = heap.allocate(1).unwrap(); // the prefix of 8 bytes + the content of ptr 1 is prepended to the pointer @@ -259,7 +318,7 @@ mod tests { // then // then the heads table should contain a pointer to the // prefix of ptr2 in the leftmost entry - assert_eq!(heap.heads[0], u32::from(ptr2) - 8); + assert_eq!(heap.heads[0], u32::from(ptr2) - PREFIX_SIZE); } #[test] @@ -271,13 +330,13 @@ mod tests { let ptr1 = heap.allocate(1).unwrap(); // the prefix of 8 bytes is prepended to the pointer - assert_eq!(ptr1, to_pointer(padded_offset + 8)); + assert_eq!(ptr1, to_pointer(padded_offset + PREFIX_SIZE)); let ptr2 = heap.allocate(9).unwrap(); // the padded_offset + the previously allocated ptr (8 bytes prefix + // 8 bytes content) + the prefix of 8 bytes which is prepended to the // current pointer - assert_eq!(ptr2, to_pointer(padded_offset + 16 + 8)); + assert_eq!(ptr2, to_pointer(padded_offset + 16 + PREFIX_SIZE)); // when heap.deallocate(ptr2).unwrap(); @@ -285,7 +344,7 @@ mod tests { // then // should have re-allocated - assert_eq!(ptr3, to_pointer(padded_offset + 16 + 8)); + assert_eq!(ptr3, to_pointer(padded_offset + 16 + PREFIX_SIZE)); assert_eq!(heap.heads, [0; N]); } @@ -305,12 +364,12 @@ mod tests { heap.deallocate(ptr3).unwrap(); // then - assert_eq!(heap.heads[0], u32::from(ptr3) - 8); + assert_eq!(heap.heads[0], u32::from(ptr3) - PREFIX_SIZE); let ptr4 = heap.allocate(8).unwrap(); assert_eq!(ptr4, ptr3); - assert_eq!(heap.heads[0], u32::from(ptr2) - 8); + assert_eq!(heap.heads[0], u32::from(ptr2) - PREFIX_SIZE); } #[test] @@ -323,12 +382,9 @@ mod tests { let ptr = heap.allocate(PAGE_SIZE - 13); // then - assert_eq!(ptr.is_err(), true); - if let Err(err) = ptr { - match err { - Error::AllocatorOutOfSpace => {}, - _ => panic!("Expected out of space error"), - } + match ptr.unwrap_err() { + Error::AllocatorOutOfSpace => {}, + e => panic!("Expected allocator out of space error, got: {:?}", e), } } @@ -337,20 +393,17 @@ mod tests { // given let mem = MemoryInstance::alloc(Pages(1), Some(Pages(1))).unwrap(); let mut heap = FreeingBumpHeapAllocator::new(mem, 0); - let ptr1 = heap.allocate((PAGE_SIZE / 2) - 8).unwrap(); - assert_eq!(ptr1, to_pointer(8)); + let ptr1 = heap.allocate((PAGE_SIZE / 2) - PREFIX_SIZE).unwrap(); + assert_eq!(ptr1, to_pointer(PREFIX_SIZE)); // when let ptr2 = heap.allocate(PAGE_SIZE / 2); // then // there is no room for another half page incl. its 8 byte prefix - assert_eq!(ptr2.is_err(), true); - if let Err(err) = ptr2 { - match err { - Error::AllocatorOutOfSpace => {}, - _ => panic!("Expected out of space error"), - } + match ptr2.unwrap_err() { + Error::AllocatorOutOfSpace => {}, + e => panic!("Expected allocator out of space error, got: {:?}", e), } } @@ -365,7 +418,7 @@ mod tests { let ptr = heap.allocate(MAX_POSSIBLE_ALLOCATION).unwrap(); // then - assert_eq!(ptr, to_pointer(8)); + assert_eq!(ptr, to_pointer(PREFIX_SIZE)); } #[test] @@ -378,12 +431,42 @@ mod tests { let ptr = heap.allocate(MAX_POSSIBLE_ALLOCATION + 1); // then - assert_eq!(ptr.is_err(), true); - if let Err(err) = ptr { - match err { - Error::RequestedAllocationTooLarge => {}, - e => panic!("Expected out of space error, got: {:?}", e), - } + match ptr.unwrap_err() { + Error::RequestedAllocationTooLarge => {}, + e => panic!("Expected allocation size too large error, got: {:?}", e), + } + } + + #[test] + fn should_return_error_when_bumper_greater_than_heap_size() { + // given + let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); + let mut heap = FreeingBumpHeapAllocator::new(mem, 0); + heap.max_heap_size = 64; + + let ptr1 = heap.allocate(32).unwrap(); + assert_eq!(ptr1, to_pointer(PREFIX_SIZE)); + heap.deallocate(ptr1).expect("failed freeing ptr1"); + assert_eq!(heap.total_size, 0); + assert_eq!(heap.bumper, 40); + + let ptr2 = heap.allocate(16).unwrap(); + assert_eq!(ptr2, to_pointer(48)); + heap.deallocate(ptr2).expect("failed freeing ptr2"); + assert_eq!(heap.total_size, 0); + assert_eq!(heap.bumper, 64); + + // when + // the `bumper` value is equal to `max_heap_size` here and any + // further allocation which would increment the bumper must fail. + // we try to allocate 8 bytes here, which will increment the + // bumper since no 8 byte item has been allocated+freed before. + let ptr = heap.allocate(8); + + // then + match ptr.unwrap_err() { + Error::AllocatorOutOfSpace => {}, + e => panic!("Expected allocator out of space error, got: {:?}", e), } } @@ -398,7 +481,7 @@ mod tests { heap.allocate(9).unwrap(); // then - assert_eq!(heap.total_size, 8 + 16); + assert_eq!(heap.total_size, PREFIX_SIZE + 16); } #[test] @@ -409,7 +492,7 @@ mod tests { // when let ptr = heap.allocate(42).unwrap(); - assert_eq!(ptr, to_pointer(16 + 8)); + assert_eq!(ptr, to_pointer(16 + PREFIX_SIZE)); heap.deallocate(ptr).unwrap(); // then diff --git a/core/executor/src/error.rs b/core/executor/src/error.rs index d6bf6b8b84..c5148241ee 100644 --- a/core/executor/src/error.rs +++ b/core/executor/src/error.rs @@ -69,8 +69,8 @@ pub enum Error { /// Some error occurred in the allocator #[display(fmt="Error in allocator: {}", _0)] Allocator(&'static str), - /// The allocator run out of space. - #[display(fmt="Allocator run out of space")] + /// The allocator ran out of space. + #[display(fmt="Allocator ran out of space")] AllocatorOutOfSpace, /// Someone tried to allocate more memory than the allowed maximum per allocation. #[display(fmt="Requested allocation size is too large")] diff --git a/node/cli/src/factory_impl.rs b/node/cli/src/factory_impl.rs index c16a8af6f8..827b8e308c 100644 --- a/node/cli/src/factory_impl.rs +++ b/node/cli/src/factory_impl.rs @@ -23,7 +23,10 @@ use rand::rngs::StdRng; use codec::{Encode, Decode}; use keyring::sr25519::Keyring; -use node_runtime::{Call, CheckedExtrinsic, UncheckedExtrinsic, SignedExtra, BalancesCall, ExistentialDeposit}; +use node_runtime::{ + Call, CheckedExtrinsic, UncheckedExtrinsic, SignedExtra, BalancesCall, ExistentialDeposit, + MinimumPeriod, +}; use primitives::{sr25519, crypto::Pair}; use sr_primitives::{generic::Era, traits::{Block as BlockT, Header as HeaderT, SignedExtension}}; use transaction_factory::RuntimeAdapter; @@ -32,9 +35,6 @@ use inherents::InherentData; use timestamp; use finality_tracker; -// TODO get via api: ::MinimumPeriod::get(). See #2587. -const MINIMUM_PERIOD: u64 = 99; - pub struct FactoryState { block_no: N, @@ -152,7 +152,7 @@ impl RuntimeAdapter for FactoryState { } fn inherent_extrinsics(&self) -> InherentData { - let timestamp = self.block_no as u64 * MINIMUM_PERIOD; + let timestamp = (self.block_no as u64 + 1) * MinimumPeriod::get(); let mut inherent = InherentData::new(); inherent.put_data(timestamp::INHERENT_IDENTIFIER, ×tamp) @@ -163,7 +163,6 @@ impl RuntimeAdapter for FactoryState { } fn minimum_balance() -> Self::Balance { - // TODO get correct amount via api. See #2587. ExistentialDeposit::get() } diff --git a/test-utils/transaction-factory/src/lib.rs b/test-utils/transaction-factory/src/lib.rs index 5d63f906a7..067c75c3fc 100644 --- a/test-utils/transaction-factory/src/lib.rs +++ b/test-utils/transaction-factory/src/lib.rs @@ -116,7 +116,7 @@ where let best_header: Result<::Header, cli::error::Error> = select_chain.best_chain().map_err(|e| format!("{:?}", e).into()); let mut best_hash = best_header?.hash(); - let best_block_id = BlockId::::hash(best_hash); + let mut best_block_id = BlockId::::hash(best_hash); let version = client.runtime_version_at(&best_block_id)?.spec_version; let genesis_hash = client.block_hash(Zero::zero())? .expect("Genesis block always exists; qed").into(); @@ -140,6 +140,7 @@ where ), } { best_hash = block.header().hash(); + best_block_id = BlockId::::hash(best_hash); import_block(&client, block); info!("Imported block at {}", factory_state.block_no()); -- GitLab From ea2644a235f4b189c8029b9c9eac9d4df64ee91e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 13 Sep 2019 16:39:50 +0200 Subject: [PATCH 094/275] Clean up sr-io (#3609) * Move trait `Printable` into `sr-primitives` * Cleanup runtime io trie_root interfaces * Remove last generic bits from sr-io interface * Fix srml-sudo after master merge * Fix benchmarks * Runtime bump --- Cargo.lock | 1 + core/application-crypto/src/ed25519.rs | 2 +- core/application-crypto/src/sr25519.rs | 2 +- core/client/db/src/lib.rs | 2 +- .../client/src/block_builder/block_builder.rs | 2 +- core/client/src/genesis.rs | 2 +- core/client/src/light/fetcher.rs | 4 +- core/executor/runtime-test/Cargo.toml | 1 + core/executor/runtime-test/src/lib.rs | 17 +- core/executor/src/wasm_executor.rs | 10 +- core/sr-io/src/lib.rs | 81 ++----- core/sr-io/with_std.rs | 82 +++---- core/sr-io/without_std.rs | 156 +++++------- core/sr-primitives/src/lib.rs | 7 +- core/sr-primitives/src/traits.rs | 227 ++++++++++-------- core/test-runtime/client/src/lib.rs | 4 +- core/test-runtime/src/genesismap.rs | 5 +- core/test-runtime/src/lib.rs | 2 +- core/test-runtime/src/system.rs | 16 +- core/trie/src/lib.rs | 6 +- node/executor/src/lib.rs | 2 +- node/runtime/src/lib.rs | 4 +- srml/contracts/src/wasm/runtime.rs | 2 +- srml/democracy/src/lib.rs | 2 +- srml/elections/src/lib.rs | 6 +- srml/example/src/lib.rs | 2 +- srml/executive/src/lib.rs | 2 +- srml/im-online/src/lib.rs | 3 +- srml/sudo/src/lib.rs | 4 +- srml/support/src/lib.rs | 7 +- srml/support/test/tests/final_keys.rs | 3 +- srml/support/test/tests/instance.rs | 4 +- srml/system/benches/bench.rs | 4 +- srml/system/src/lib.rs | 7 +- 34 files changed, 309 insertions(+), 372 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6eefaabce9..d526d6f65f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5221,6 +5221,7 @@ name = "substrate-runtime-test" version = "2.0.0" dependencies = [ "sr-io 2.0.0", + "sr-primitives 2.0.0", "sr-sandbox 2.0.0", "sr-std 2.0.0", "substrate-primitives 2.0.0", diff --git a/core/application-crypto/src/ed25519.rs b/core/application-crypto/src/ed25519.rs index 209743bd28..a1aef4a328 100644 --- a/core/application-crypto/src/ed25519.rs +++ b/core/application-crypto/src/ed25519.rs @@ -42,7 +42,7 @@ impl RuntimePublic for Public { } fn sign>(&self, key_type: KeyTypeId, msg: &M) -> Option { - runtime_io::ed25519_sign(key_type, self, msg) + runtime_io::ed25519_sign(key_type, self, msg.as_ref()) } fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool { diff --git a/core/application-crypto/src/sr25519.rs b/core/application-crypto/src/sr25519.rs index e333208966..c3cc9df267 100644 --- a/core/application-crypto/src/sr25519.rs +++ b/core/application-crypto/src/sr25519.rs @@ -42,7 +42,7 @@ impl RuntimePublic for Public { } fn sign>(&self, key_type: KeyTypeId, msg: &M) -> Option { - runtime_io::sr25519_sign(key_type, self, msg) + runtime_io::sr25519_sign(key_type, self, msg.as_ref()) } fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool { diff --git a/core/client/db/src/lib.rs b/core/client/db/src/lib.rs index 722309b415..4acb178506 100644 --- a/core/client/db/src/lib.rs +++ b/core/client/db/src/lib.rs @@ -1527,7 +1527,7 @@ mod tests { let header = Header { number, parent_hash, - state_root: BlakeTwo256::trie_root::<_, &[u8], &[u8]>(Vec::new()), + state_root: BlakeTwo256::trie_root(Vec::new()), digest, extrinsics_root, }; diff --git a/core/client/src/block_builder/block_builder.rs b/core/client/src/block_builder/block_builder.rs index b6fae5068a..08711469e9 100644 --- a/core/client/src/block_builder/block_builder.rs +++ b/core/client/src/block_builder/block_builder.rs @@ -128,7 +128,7 @@ where debug_assert_eq!( self.header.extrinsics_root().clone(), HashFor::::ordered_trie_root( - self.extrinsics.iter().map(Encode::encode) + self.extrinsics.iter().map(Encode::encode).collect(), ), ); diff --git a/core/client/src/genesis.rs b/core/client/src/genesis.rs index 2f31462955..796d1417f2 100644 --- a/core/client/src/genesis.rs +++ b/core/client/src/genesis.rs @@ -25,7 +25,7 @@ pub fn construct_genesis_block< state_root: Block::Hash ) -> Block { let extrinsics_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( - std::iter::empty::<(&[u8], &[u8])>(), + Vec::new(), ); Block::new( diff --git a/core/client/src/light/fetcher.rs b/core/client/src/light/fetcher.rs index c25092c32c..068534c5f6 100644 --- a/core/client/src/light/fetcher.rs +++ b/core/client/src/light/fetcher.rs @@ -436,7 +436,9 @@ impl FetchChecker for LightDataChecker body: Vec ) -> ClientResult> { // TODO: #2621 - let extrinsics_root = HashFor::::ordered_trie_root(body.iter().map(Encode::encode)); + let extrinsics_root = HashFor::::ordered_trie_root( + body.iter().map(Encode::encode).collect(), + ); if *request.header.extrinsics_root() == extrinsics_root { Ok(body) } else { diff --git a/core/executor/runtime-test/Cargo.toml b/core/executor/runtime-test/Cargo.toml index 28a0ed2b87..fcdacd98ca 100644 --- a/core/executor/runtime-test/Cargo.toml +++ b/core/executor/runtime-test/Cargo.toml @@ -10,6 +10,7 @@ rstd = { package = "sr-std", path = "../../sr-std", default-features = false } runtime_io = { package = "sr-io", path = "../../sr-io", default-features = false } sandbox = { package = "sr-sandbox", path = "../../sr-sandbox", default-features = false } primitives = { package = "substrate-primitives", path = "../../primitives", default-features = false } +sr-primitives = { package = "sr-primitives", path = "../../sr-primitives", default-features = false } [build-dependencies] wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.2", path = "../../utils/wasm-builder-runner" } diff --git a/core/executor/runtime-test/src/lib.rs b/core/executor/runtime-test/src/lib.rs index 5e276a8814..35f3191ffd 100644 --- a/core/executor/runtime-test/src/lib.rs +++ b/core/executor/runtime-test/src/lib.rs @@ -8,9 +8,10 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); use rstd::{vec::Vec, slice, vec}; use runtime_io::{ - set_storage, storage, clear_prefix, print, blake2_128, blake2_256, - twox_128, twox_256, ed25519_verify, sr25519_verify, ordered_trie_root + set_storage, storage, clear_prefix, blake2_128, blake2_256, + twox_128, twox_256, ed25519_verify, sr25519_verify, }; +use sr_primitives::{print, traits::{BlakeTwo256, Hash}}; use primitives::{ed25519, sr25519}; macro_rules! impl_stubs { @@ -94,12 +95,12 @@ impl_stubs!( [sr25519_verify(&sr25519::Signature(sig), &msg[..], &sr25519::Public(pubkey)) as u8].to_vec() }, test_ordered_trie_root => |_| { - ordered_trie_root::( - &[ - &b"zero"[..], - &b"one"[..], - &b"two"[..], - ] + BlakeTwo256::ordered_trie_root( + vec![ + b"zero"[..].into(), + b"one"[..].into(), + b"two"[..].into(), + ], ).as_ref().to_vec() }, test_sandbox => |code: &[u8]| { diff --git a/core/executor/src/wasm_executor.rs b/core/executor/src/wasm_executor.rs index 38b8d8eff1..cc7d5d9344 100644 --- a/core/executor/src/wasm_executor.rs +++ b/core/executor/src/wasm_executor.rs @@ -31,7 +31,7 @@ use crate::error::{Error, Result}; use codec::{Encode, Decode}; use primitives::{ blake2_128, blake2_256, twox_64, twox_128, twox_256, ed25519, sr25519, Pair, crypto::KeyTypeId, - offchain, hexdisplay::HexDisplay, sandbox as sandbox_primitives, Blake2Hasher, + offchain, sandbox as sandbox_primitives, Blake2Hasher, traits::Externalities, }; use trie::{TrieConfiguration, trie_types::Layout}; @@ -418,22 +418,20 @@ impl_wasm_host_interface! { ext_print_utf8(utf8_data: Pointer, utf8_len: WordSize) { if let Ok(utf8) = context.read_memory(utf8_data, utf8_len) { - if let Ok(message) = String::from_utf8(utf8) { - println!("{}", message); - } + runtime_io::print_utf8(&utf8); } Ok(()) } ext_print_hex(data: Pointer, len: WordSize) { if let Ok(hex) = context.read_memory(data, len) { - println!("{}", HexDisplay::from(&hex)); + runtime_io::print_hex(&hex); } Ok(()) } ext_print_num(number: u64) { - println!("{}", number); + runtime_io::print_num(number); Ok(()) } diff --git a/core/sr-io/src/lib.rs b/core/sr-io/src/lib.rs index 642b3e4881..aee9e23909 100644 --- a/core/sr-io/src/lib.rs +++ b/core/sr-io/src/lib.rs @@ -29,12 +29,8 @@ use hash_db::Hasher; use rstd::vec::Vec; -#[doc(hidden)] -pub use codec; - -pub use primitives::Blake2Hasher; use primitives::{ - crypto::KeyTypeId, ed25519, sr25519, + crypto::KeyTypeId, ed25519, sr25519, H256, offchain::{ Timestamp, HttpRequestId, HttpRequestStatus, HttpError, StorageKind, OpaqueNetworkState, }, @@ -52,18 +48,6 @@ pub enum EcdsaVerifyError { pub mod offchain; -/// Trait for things which can be printed. -pub trait Printable { - /// Print the object. - fn print(&self); -} - -impl Printable for u8 { - fn print(&self) { - u64::from(*self).print() - } -} - /// Converts a public trait definition into a private trait and set of public functions /// that assume the trait is implemented for `()` for ease of calling. macro_rules! export_api { @@ -73,7 +57,6 @@ macro_rules! export_api { $( $( #[$attr:meta] )* fn $name:ident - $(< $( $g_name:ident $( : $g_ty:path )? ),+ >)? ( $( $arg:ident : $arg_ty:ty ),* $(,)? ) $( -> $ret:ty )? $( where $( $w_name:path : $w_ty:path ),+ )?; @@ -84,18 +67,18 @@ macro_rules! export_api { pub(crate) trait $trait_name { $( $( #[$attr] )* - fn $name $(< $( $g_name $( : $g_ty )? ),+ >)? ( $($arg : $arg_ty ),* ) $( -> $ret )? + fn $name ( $($arg : $arg_ty ),* ) $( -> $ret )? $( where $( $w_name : $w_ty ),+ )?; )* } $( $( #[$attr] )* - pub fn $name $(< $( $g_name $( : $g_ty )? ),+ >)? ( $($arg : $arg_ty ),* ) $( -> $ret )? + pub fn $name ( $($arg : $arg_ty ),* ) $( -> $ret )? $( where $( $w_name : $w_ty ),+ )? { #[allow(deprecated)] - <()>:: $name $(::< $( $g_name ),+ > )? ( $( $arg ),* ) + <()>:: $name ( $( $arg ),* ) } )* } @@ -160,26 +143,10 @@ export_api! { fn storage_changes_root(parent_hash: [u8; 32]) -> Option<[u8; 32]>; /// A trie root formed from the iterated items. - fn trie_root(input: I) -> H::Out - where - I: IntoIterator, - A: AsRef<[u8]>, - A: Ord, - B: AsRef<[u8]>, - H: Hasher, - H: self::imp::HasherBounds, - H::Out: Ord - ; + fn blake2_256_trie_root(input: Vec<(Vec, Vec)>) -> H256; /// A trie root formed from the enumerated items. - fn ordered_trie_root(input: I) -> H::Out - where - I: IntoIterator, - A: AsRef<[u8]>, - H: Hasher, - H: self::imp::HasherBounds, - H::Out: Ord - ; + fn blake2_256_ordered_trie_root(input: Vec>) -> H256; } } @@ -188,12 +155,12 @@ export_api! { /// The current relay chain identifier. fn chain_id() -> u64; - /// Print a printable value. - fn print(value: T) - where - T: Printable, - T: Sized - ; + /// Print a number. + fn print_num(val: u64); + /// Print any valid `utf8` buffer. + fn print_utf8(utf8: &[u8]); + /// Print any `u8` slice as hex. + fn print_hex(data: &[u8]); } } @@ -209,10 +176,10 @@ export_api! { /// key type in the keystore. /// /// Returns the raw signature. - fn ed25519_sign>( + fn ed25519_sign( id: KeyTypeId, pubkey: &ed25519::Public, - msg: &M, + msg: &[u8], ) -> Option; /// Verify an ed25519 signature. /// @@ -229,10 +196,10 @@ export_api! { /// key type in the keystore. /// /// Returns the raw signature. - fn sr25519_sign>( + fn sr25519_sign( id: KeyTypeId, pubkey: &sr25519::Public, - msg: &M, + msg: &[u8], ) -> Option; /// Verify an sr25519 signature. /// @@ -315,7 +282,7 @@ export_api! { kind: StorageKind, key: &[u8], old_value: Option<&[u8]>, - new_value: &[u8] + new_value: &[u8], ) -> bool; /// Gets a value from the local storage. @@ -332,14 +299,14 @@ export_api! { fn http_request_start( method: &str, uri: &str, - meta: &[u8] + meta: &[u8], ) -> Result; /// Append header to the request. fn http_request_add_header( request_id: HttpRequestId, name: &str, - value: &str + value: &str, ) -> Result<(), ()>; /// Write a chunk of request body. @@ -351,7 +318,7 @@ export_api! { fn http_request_write_body( request_id: HttpRequestId, chunk: &[u8], - deadline: Option + deadline: Option, ) -> Result<(), HttpError>; /// Block and wait for the responses for given requests. @@ -363,16 +330,14 @@ export_api! { /// Passing `None` as deadline blocks forever. fn http_response_wait( ids: &[HttpRequestId], - deadline: Option + deadline: Option, ) -> Vec; /// Read all response headers. /// /// Returns a vector of pairs `(HeaderKey, HeaderValue)`. /// NOTE response headers have to be read before response body. - fn http_response_headers( - request_id: HttpRequestId - ) -> Vec<(Vec, Vec)>; + fn http_response_headers(request_id: HttpRequestId) -> Vec<(Vec, Vec)>; /// Read a chunk of body response to given buffer. /// @@ -385,7 +350,7 @@ export_api! { fn http_response_read_body( request_id: HttpRequestId, buffer: &mut [u8], - deadline: Option + deadline: Option, ) -> Result; } } diff --git a/core/sr-io/with_std.rs b/core/sr-io/with_std.rs index 41baf29532..f93194bb47 100644 --- a/core/sr-io/with_std.rs +++ b/core/sr-io/with_std.rs @@ -15,15 +15,14 @@ // along with Substrate. If not, see . use primitives::{ - blake2_128, blake2_256, twox_128, twox_256, twox_64, ed25519, Blake2Hasher, sr25519, Pair, - traits::Externalities, child_storage_key::ChildStorageKey, + blake2_128, blake2_256, twox_128, twox_256, twox_64, ed25519, Blake2Hasher, sr25519, Pair, H256, + traits::Externalities, child_storage_key::ChildStorageKey, hexdisplay::HexDisplay, offchain, }; // Switch to this after PoC-3 // pub use primitives::BlakeHasher; pub use substrate_state_machine::{BasicExternalities, TestExternalities}; use environmental::environmental; -use primitives::{offchain, hexdisplay::HexDisplay, H256}; use trie::{TrieConfiguration, trie_types::Layout}; use std::{collections::HashMap, convert::TryFrom}; @@ -166,25 +165,12 @@ impl StorageApi for () { ).unwrap_or(Ok(None)).expect("Invalid parent hash passed to storage_changes_root") } - fn trie_root(input: I) -> H::Out - where - I: IntoIterator, - A: AsRef<[u8]> + Ord, - B: AsRef<[u8]>, - H: Hasher, - H::Out: Ord, - { - Layout::::trie_root(input) + fn blake2_256_trie_root(input: Vec<(Vec, Vec)>) -> H256 { + Layout::::trie_root(input) } - fn ordered_trie_root(input: I) -> H::Out - where - I: IntoIterator, - A: AsRef<[u8]>, - H: Hasher, - H::Out: Ord, - { - Layout::::ordered_trie_root(input) + fn blake2_256_ordered_trie_root(input: Vec>) -> H256 { + Layout::::ordered_trie_root(input) } } @@ -195,8 +181,18 @@ impl OtherApi for () { ).unwrap_or(0) } - fn print(value: T) { - value.print() + fn print_num(val: u64) { + println!("{}", val); + } + + fn print_utf8(utf8: &[u8]) { + if let Ok(data) = std::str::from_utf8(utf8) { + println!("{}", data) + } + } + + fn print_hex(data: &[u8]) { + println!("{}", HexDisplay::from(&data)); } } @@ -220,10 +216,10 @@ impl CryptoApi for () { }).expect("`ed25519_generate` cannot be called outside of an Externalities-provided environment.") } - fn ed25519_sign>( + fn ed25519_sign( id: KeyTypeId, pubkey: &ed25519::Public, - msg: &M, + msg: &[u8], ) -> Option { let pub_key = ed25519::Public::try_from(pubkey.as_ref()).ok()?; @@ -232,7 +228,7 @@ impl CryptoApi for () { .expect("No `keystore` associated for the current context!") .read() .ed25519_key_pair(id, &pub_key) - .map(|k| k.sign(msg.as_ref())) + .map(|k| k.sign(msg)) }).expect("`ed25519_sign` cannot be called outside of an Externalities-provided environment.") } @@ -259,10 +255,10 @@ impl CryptoApi for () { }).expect("`sr25519_generate` cannot be called outside of an Externalities-provided environment.") } - fn sr25519_sign>( + fn sr25519_sign( id: KeyTypeId, pubkey: &sr25519::Public, - msg: &M, + msg: &[u8], ) -> Option { let pub_key = sr25519::Public::try_from(pubkey.as_ref()).ok()?; @@ -271,7 +267,7 @@ impl CryptoApi for () { .expect("No `keystore` associated for the current context!") .read() .sr25519_key_pair(id, &pub_key) - .map(|k| k.sign(msg.as_ref())) + .map(|k| k.sign(msg)) }).expect("`sr25519_sign` cannot be called outside of an Externalities-provided environment.") } @@ -389,7 +385,7 @@ impl OffchainApi for () { fn http_request_start( method: &str, uri: &str, - meta: &[u8] + meta: &[u8], ) -> Result { with_offchain(|ext| { ext.http_request_start(method, uri, meta) @@ -399,7 +395,7 @@ impl OffchainApi for () { fn http_request_add_header( request_id: offchain::HttpRequestId, name: &str, - value: &str + value: &str, ) -> Result<(), ()> { with_offchain(|ext| { ext.http_request_add_header(request_id, name, value) @@ -409,7 +405,7 @@ impl OffchainApi for () { fn http_request_write_body( request_id: offchain::HttpRequestId, chunk: &[u8], - deadline: Option + deadline: Option, ) -> Result<(), offchain::HttpError> { with_offchain(|ext| { ext.http_request_write_body(request_id, chunk, deadline) @@ -418,7 +414,7 @@ impl OffchainApi for () { fn http_response_wait( ids: &[offchain::HttpRequestId], - deadline: Option + deadline: Option, ) -> Vec { with_offchain(|ext| { ext.http_response_wait(ids, deadline) @@ -426,7 +422,7 @@ impl OffchainApi for () { } fn http_response_headers( - request_id: offchain::HttpRequestId + request_id: offchain::HttpRequestId, ) -> Vec<(Vec, Vec)> { with_offchain(|ext| { ext.http_response_headers(request_id) @@ -436,7 +432,7 @@ impl OffchainApi for () { fn http_response_read_body( request_id: offchain::HttpRequestId, buffer: &mut [u8], - deadline: Option + deadline: Option, ) -> Result { with_offchain(|ext| { ext.http_response_read_body(request_id, buffer, deadline) @@ -477,24 +473,6 @@ pub fn with_storage R>( r } -impl<'a> Printable for &'a [u8] { - fn print(&self) { - println!("Runtime: {}", HexDisplay::from(self)); - } -} - -impl<'a> Printable for &'a str { - fn print(&self) { - println!("Runtime: {}", self); - } -} - -impl Printable for u64 { - fn print(&self) { - println!("Runtime: {}", self); - } -} - #[cfg(test)] mod std_tests { use super::*; diff --git a/core/sr-io/without_std.rs b/core/sr-io/without_std.rs index f7b0ce9b02..6803b41ebd 100644 --- a/core/sr-io/without_std.rs +++ b/core/sr-io/without_std.rs @@ -126,44 +126,6 @@ pub mod ext { } } - /// Ensures we use the right crypto when calling into native - pub trait ExternTrieCrypto: Hasher { - /// A trie root formed from the enumerated items. - fn ordered_trie_root< - A: AsRef<[u8]>, - I: IntoIterator - >(values: I) -> Self::Out; - } - - /// Additional bounds for Hasher trait for without_std. - pub trait HasherBounds: ExternTrieCrypto {} - impl HasherBounds for T {} - - // Ensures we use a Blake2_256-flavored Hasher when calling into native - impl ExternTrieCrypto for Blake2Hasher { - fn ordered_trie_root< - A: AsRef<[u8]>, - I: IntoIterator - >(items: I) -> Self::Out { - let mut values = Vec::new(); - let mut lengths = Vec::new(); - for v in items.into_iter() { - values.extend_from_slice(v.as_ref()); - lengths.push((v.as_ref().len() as u32).to_le()); - } - let mut result: [u8; 32] = Default::default(); - unsafe { - ext_blake2_256_enumerated_trie_root.get()( - values.as_ptr(), - lengths.as_ptr(), - lengths.len() as u32, - result.as_mut_ptr() - ); - } - result.into() - } - } - /// Declare extern functions macro_rules! extern_functions { ( @@ -228,7 +190,7 @@ pub mod ext { storage_key_data: *const u8, storage_key_len: u32, prefix_data: *const u8, - prefix_len: u32 + prefix_len: u32, ); /// Gets the value of the given key from storage. /// @@ -255,7 +217,7 @@ pub mod ext { key_len: u32, value_data: *mut u8, value_len: u32, - value_offset: u32 + value_offset: u32, ) -> u32; /// Gets the trie root of the storage. fn ext_storage_root(result: *mut u8); @@ -266,7 +228,10 @@ pub mod ext { /// - `1` if the change trie root was found. /// - `0` if the change trie root was not found. fn ext_storage_changes_root( - parent_hash_data: *const u8, parent_hash_len: u32, result: *mut u8) -> u32; + parent_hash_data: *const u8, + parent_hash_len: u32, + result: *mut u8, + ) -> u32; /// A child storage function. /// @@ -279,7 +244,7 @@ pub mod ext { key_data: *const u8, key_len: u32, value_data: *const u8, - value_len: u32 + value_len: u32, ); /// A child storage function. /// @@ -290,7 +255,7 @@ pub mod ext { storage_key_data: *const u8, storage_key_len: u32, key_data: *const u8, - key_len: u32 + key_len: u32, ); /// A child storage function. /// @@ -301,7 +266,7 @@ pub mod ext { storage_key_data: *const u8, storage_key_len: u32, key_data: *const u8, - key_len: u32 + key_len: u32, ) -> u32; /// A child storage function. /// @@ -319,7 +284,7 @@ pub mod ext { storage_key_len: u32, key_data: *const u8, key_len: u32, - written_out: *mut u32 + written_out: *mut u32, ) -> *mut u8; /// A child storage function. /// @@ -333,7 +298,7 @@ pub mod ext { key_len: u32, value_data: *mut u8, value_len: u32, - value_offset: u32 + value_offset: u32, ) -> u32; /// Commits all changes and calculates the child-storage root. /// @@ -498,7 +463,7 @@ pub mod ext { old_value: *const u8, old_value_len: u32, new_value: *const u8, - new_value_len: u32 + new_value_len: u32, ) -> u32; /// Read a value from local storage. @@ -526,7 +491,7 @@ pub mod ext { url: *const u8, url_len: u32, meta: *const u8, - meta_len: u32 + meta_len: u32, ) -> u32; /// Add a header to the request. @@ -540,7 +505,7 @@ pub mod ext { name: *const u8, name_len: u32, value: *const u8, - value_len: u32 + value_len: u32, ) -> u32; /// Write a chunk of request body. @@ -556,7 +521,7 @@ pub mod ext { request_id: u32, chunk: *const u8, chunk_len: u32, - deadline: u64 + deadline: u64, ) -> u32; /// Block and wait for the responses for given requests. @@ -570,7 +535,7 @@ pub mod ext { ids: *const u32, ids_len: u32, statuses: *mut u32, - deadline: u64 + deadline: u64, ); /// Read all response headers. @@ -583,7 +548,7 @@ pub mod ext { /// - In case invalid `id` is passed it returns a pointer to parity-encoded empty vector. fn ext_http_response_headers( id: u32, - written_out: *mut u32 + written_out: *mut u32, ) -> *mut u8; /// Read a chunk of body response to given buffer. @@ -605,7 +570,7 @@ pub mod ext { id: u32, buffer: *mut u8, buffer_len: u32, - deadline: u64 + deadline: u64, ) -> u32; } } @@ -777,21 +742,28 @@ impl StorageApi for () { } } - fn trie_root< - H: Hasher + ExternTrieCrypto, - I: IntoIterator, - A: AsRef<[u8]> + Ord, - B: AsRef<[u8]>, - >(_input: I) -> H::Out { + + fn blake2_256_trie_root(input: Vec<(Vec, Vec)>) -> H256 { unimplemented!() } - fn ordered_trie_root< - H: Hasher + ExternTrieCrypto, - I: IntoIterator, - A: AsRef<[u8]> - >(values: I) -> H::Out { - H::ordered_trie_root(values) + fn blake2_256_ordered_trie_root(input: Vec>) -> H256 { + let mut values = Vec::new(); + let mut lengths = Vec::new(); + for v in input { + values.extend_from_slice(&v); + lengths.push((v.len() as u32).to_le()); + } + let mut result: [u8; 32] = Default::default(); + unsafe { + ext_blake2_256_enumerated_trie_root.get()( + values.as_ptr(), + lengths.as_ptr(), + lengths.len() as u32, + result.as_mut_ptr(), + ); + } + result.into() } } @@ -802,10 +774,23 @@ impl OtherApi for () { } } - fn print(value: T) { - value.print() + fn print_num(val: u64) { + unsafe { + ext_print_num.get()(val); + } } + fn print_utf8(utf8: &[u8]) { + unsafe { + ext_print_utf8.get()(utf8.as_ptr(), utf8.len() as u32); + } + } + + fn print_hex(data: &[u8]) { + unsafe { + ext_print_hex.get()(data.as_ptr(), data.len() as u32); + } + } } impl HashingApi for () { @@ -876,18 +861,18 @@ impl CryptoApi for () { ed25519::Public(res) } - fn ed25519_sign>( + fn ed25519_sign( id: KeyTypeId, pubkey: &ed25519::Public, - msg: &M, + msg: &[u8], ) -> Option { let mut res = [0u8; 64]; let success = unsafe { ext_ed25519_sign.get()( id.0.as_ptr(), pubkey.0.as_ptr(), - msg.as_ref().as_ptr(), - msg.as_ref().len() as u32, + msg.as_ptr(), + msg.len() as u32, res.as_mut_ptr(), ) == 0 }; @@ -927,18 +912,18 @@ impl CryptoApi for () { sr25519::Public(res) } - fn sr25519_sign>( + fn sr25519_sign( id: KeyTypeId, pubkey: &sr25519::Public, - msg: &M, + msg: &[u8], ) -> Option { let mut res = [0u8; 64]; let success = unsafe { ext_sr25519_sign.get()( id.0.as_ptr(), pubkey.0.as_ptr(), - msg.as_ref().as_ptr(), - msg.as_ref().len() as u32, + msg.as_ptr(), + msg.len() as u32, res.as_mut_ptr(), ) == 0 }; @@ -1218,24 +1203,3 @@ unsafe fn from_raw_parts(ptr: *mut u8, len: u32) -> Option> { impl Api for () {} -impl<'a> Printable for &'a [u8] { - fn print(&self) { - unsafe { - ext_print_hex.get()(self.as_ptr(), self.len() as u32); - } - } -} - -impl<'a> Printable for &'a str { - fn print(&self) { - unsafe { - ext_print_utf8.get()(self.as_ptr() as *const u8, self.len() as u32); - } - } -} - -impl Printable for u64 { - fn print(&self) { - unsafe { ext_print_num.get()(*self); } - } -} diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index f3d3eabfcb..c3f47f29c4 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -699,7 +699,7 @@ impl DispatchError { } } -impl runtime_io::Printable for DispatchError { +impl traits::Printable for DispatchError { fn print(&self) { "DispatchError".print(); if let Some(module) = self.module { @@ -895,6 +895,11 @@ impl traits::Extrinsic for OpaqueExtrinsic { type SignaturePayload = (); } +/// Print something that implements `Printable` from the runtime. +pub fn print(print: impl traits::Printable) { + print.print(); +} + #[cfg(test)] mod tests { use super::DispatchError; diff --git a/core/sr-primitives/src/traits.rs b/core/sr-primitives/src/traits.rs index 0479f9401c..a2bc5bc6dc 100644 --- a/core/sr-primitives/src/traits.rs +++ b/core/sr-primitives/src/traits.rs @@ -439,8 +439,9 @@ pub trait OffchainWorker { } /// Abstraction around hashing -pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq { // Stupid bug in the Rust compiler believes derived - // traits must be fulfilled by all type parameters. +// Stupid bug in the Rust compiler believes derived +// traits must be fulfilled by all type parameters. +pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq { /// The hash type produced. type Output: Member + MaybeSerializeDebug + rstd::hash::Hash + AsRef<[u8]> + AsMut<[u8]> + Copy + Default + Encode + Decode; @@ -456,18 +457,11 @@ pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq { // Stup Encode::using_encoded(s, Self::hash) } - /// Iterator-based version of `ordered_trie_root`. - fn ordered_trie_root< - I: IntoIterator, - A: AsRef<[u8]> - >(input: I) -> Self::Output; + /// The ordered Patricia tree root of the given `input`. + fn ordered_trie_root(input: Vec>) -> Self::Output; - /// The Patricia tree root of the given mapping as an iterator. - fn trie_root< - I: IntoIterator, - A: AsRef<[u8]> + Ord, - B: AsRef<[u8]> - >(input: I) -> Self::Output; + /// The Patricia tree root of the given mapping. + fn trie_root(input: Vec<(Vec, Vec)>) -> Self::Output; /// Acquire the global storage root. fn storage_root() -> Self::Output; @@ -487,22 +481,19 @@ impl Hash for BlakeTwo256 { fn hash(s: &[u8]) -> Self::Output { runtime_io::blake2_256(s).into() } - fn trie_root< - I: IntoIterator, - A: AsRef<[u8]> + Ord, - B: AsRef<[u8]> - >(input: I) -> Self::Output { - runtime_io::trie_root::(input).into() + + fn trie_root(input: Vec<(Vec, Vec)>) -> Self::Output { + runtime_io::blake2_256_trie_root(input) } - fn ordered_trie_root< - I: IntoIterator, - A: AsRef<[u8]> - >(input: I) -> Self::Output { - runtime_io::ordered_trie_root::(input).into() + + fn ordered_trie_root(input: Vec>) -> Self::Output { + runtime_io::blake2_256_ordered_trie_root(input) } + fn storage_root() -> Self::Output { runtime_io::storage_root().into() } + fn storage_changes_root(parent_hash: Self::Output) -> Option { runtime_io::storage_changes_root(parent_hash.into()).map(Into::into) } @@ -519,16 +510,20 @@ impl CheckEqual for primitives::H256 { fn check_equal(&self, other: &Self) { use primitives::hexdisplay::HexDisplay; if self != other { - println!("Hash: given={}, expected={}", HexDisplay::from(self.as_fixed_bytes()), HexDisplay::from(other.as_fixed_bytes())); + println!( + "Hash: given={}, expected={}", + HexDisplay::from(self.as_fixed_bytes()), + HexDisplay::from(other.as_fixed_bytes()), + ); } } #[cfg(not(feature = "std"))] fn check_equal(&self, other: &Self) { if self != other { - runtime_io::print("Hash not equal"); - runtime_io::print(self.as_bytes()); - runtime_io::print(other.as_bytes()); + "Hash not equal".print(); + self.as_bytes().print(); + other.as_bytes().print(); } } } @@ -544,9 +539,9 @@ impl CheckEqual for super::generic::DigestItem AccountIdConver } } -#[cfg(test)] -mod tests { - use super::AccountIdConversion; - use crate::codec::{Encode, Decode, Input}; - - #[derive(Encode, Decode, Default, PartialEq, Debug)] - struct U32Value(u32); - impl super::TypeId for U32Value { - const TYPE_ID: [u8; 4] = [0x0d, 0xf0, 0xfe, 0xca]; - } - // cafef00d - - #[derive(Encode, Decode, Default, PartialEq, Debug)] - struct U16Value(u16); - impl super::TypeId for U16Value { - const TYPE_ID: [u8; 4] = [0xfe, 0xca, 0x0d, 0xf0]; - } - // f00dcafe - - type AccountId = u64; - - #[test] - fn into_account_should_work() { - let r: AccountId = U32Value::into_account(&U32Value(0xdeadbeef)); - assert_eq!(r, 0x_deadbeef_cafef00d); - } - - #[test] - fn try_from_account_should_work() { - let r = U32Value::try_from_account(&0x_deadbeef_cafef00d_u64); - assert_eq!(r.unwrap(), U32Value(0xdeadbeef)); - } - - #[test] - fn into_account_with_fill_should_work() { - let r: AccountId = U16Value::into_account(&U16Value(0xc0da)); - assert_eq!(r, 0x_0000_c0da_f00dcafe); - } - - #[test] - fn try_from_account_with_fill_should_work() { - let r = U16Value::try_from_account(&0x0000_c0da_f00dcafe_u64); - assert_eq!(r.unwrap(), U16Value(0xc0da)); - } - - #[test] - fn bad_try_from_account_should_fail() { - let r = U16Value::try_from_account(&0x0000_c0de_baadcafe_u64); - assert!(r.is_none()); - let r = U16Value::try_from_account(&0x0100_c0da_f00dcafe_u64); - assert!(r.is_none()); - } - - #[test] - fn trailing_zero_should_work() { - let mut t = super::TrailingZeroInput(&[1, 2, 3]); - assert_eq!(t.remaining_len(), Ok(None)); - let mut buffer = [0u8; 2]; - assert_eq!(t.read(&mut buffer), Ok(())); - assert_eq!(t.remaining_len(), Ok(None)); - assert_eq!(buffer, [1, 2]); - assert_eq!(t.read(&mut buffer), Ok(())); - assert_eq!(t.remaining_len(), Ok(None)); - assert_eq!(buffer, [3, 0]); - assert_eq!(t.read(&mut buffer), Ok(())); - assert_eq!(t.remaining_len(), Ok(None)); - assert_eq!(buffer, [0, 0]); - } -} - /// Calls a given macro a number of times with a set of fixed params and an incrementing numeral. /// e.g. /// ```nocompile @@ -1318,3 +1243,103 @@ macro_rules! impl_opaque_keys { } }; } + +/// Trait for things which can be printed from the runtime. +pub trait Printable { + /// Print the object. + fn print(&self); +} + +impl Printable for u8 { + fn print(&self) { + u64::from(*self).print() + } +} + +impl Printable for &[u8] { + fn print(&self) { + runtime_io::print_hex(self); + } +} + +impl Printable for &str { + fn print(&self) { + runtime_io::print_utf8(self.as_bytes()); + } +} + +impl Printable for u64 { + fn print(&self) { + runtime_io::print_num(*self); + } +} + +#[cfg(test)] +mod tests { + use super::AccountIdConversion; + use crate::codec::{Encode, Decode, Input}; + + #[derive(Encode, Decode, Default, PartialEq, Debug)] + struct U32Value(u32); + impl super::TypeId for U32Value { + const TYPE_ID: [u8; 4] = [0x0d, 0xf0, 0xfe, 0xca]; + } + // cafef00d + + #[derive(Encode, Decode, Default, PartialEq, Debug)] + struct U16Value(u16); + impl super::TypeId for U16Value { + const TYPE_ID: [u8; 4] = [0xfe, 0xca, 0x0d, 0xf0]; + } + // f00dcafe + + type AccountId = u64; + + #[test] + fn into_account_should_work() { + let r: AccountId = U32Value::into_account(&U32Value(0xdeadbeef)); + assert_eq!(r, 0x_deadbeef_cafef00d); + } + + #[test] + fn try_from_account_should_work() { + let r = U32Value::try_from_account(&0x_deadbeef_cafef00d_u64); + assert_eq!(r.unwrap(), U32Value(0xdeadbeef)); + } + + #[test] + fn into_account_with_fill_should_work() { + let r: AccountId = U16Value::into_account(&U16Value(0xc0da)); + assert_eq!(r, 0x_0000_c0da_f00dcafe); + } + + #[test] + fn try_from_account_with_fill_should_work() { + let r = U16Value::try_from_account(&0x0000_c0da_f00dcafe_u64); + assert_eq!(r.unwrap(), U16Value(0xc0da)); + } + + #[test] + fn bad_try_from_account_should_fail() { + let r = U16Value::try_from_account(&0x0000_c0de_baadcafe_u64); + assert!(r.is_none()); + let r = U16Value::try_from_account(&0x0100_c0da_f00dcafe_u64); + assert!(r.is_none()); + } + + #[test] + fn trailing_zero_should_work() { + let mut t = super::TrailingZeroInput(&[1, 2, 3]); + assert_eq!(t.remaining_len(), Ok(None)); + let mut buffer = [0u8; 2]; + assert_eq!(t.read(&mut buffer), Ok(())); + assert_eq!(t.remaining_len(), Ok(None)); + assert_eq!(buffer, [1, 2]); + assert_eq!(t.read(&mut buffer), Ok(())); + assert_eq!(t.remaining_len(), Ok(None)); + assert_eq!(buffer, [3, 0]); + assert_eq!(t.read(&mut buffer), Ok(())); + assert_eq!(t.remaining_len(), Ok(None)); + assert_eq!(buffer, [0, 0]); + } +} diff --git a/core/test-runtime/client/src/lib.rs b/core/test-runtime/client/src/lib.rs index 229fcbdaf9..d2cf704fdf 100644 --- a/core/test-runtime/client/src/lib.rs +++ b/core/test-runtime/client/src/lib.rs @@ -122,12 +122,12 @@ impl generic_test_client::GenesisInit for GenesisParameters { let child_roots = storage.1.iter().map(|(sk, child_map)| { let state_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( - child_map.clone().into_iter() + child_map.clone().into_iter().collect() ); (sk.clone(), state_root.encode()) }); let state_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( - storage.0.clone().into_iter().chain(child_roots) + storage.0.clone().into_iter().chain(child_roots).collect() ); let block: runtime::Block = client::genesis::construct_genesis_block(state_root); storage.0.extend(additional_storage_with_genesis(&block)); diff --git a/core/test-runtime/src/genesismap.rs b/core/test-runtime/src/genesismap.rs index 34d7eecae0..a3abf235ff 100644 --- a/core/test-runtime/src/genesismap.rs +++ b/core/test-runtime/src/genesismap.rs @@ -90,15 +90,14 @@ pub fn insert_genesis_block( HashMap, HashMap, Vec>>, ) ) -> primitives::hash::H256 { - let child_roots = storage.1.iter().map(|(sk, child_map)| { let state_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( - child_map.clone().into_iter() + child_map.clone().into_iter().collect(), ); (sk.clone(), state_root.encode()) }); let state_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( - storage.0.clone().into_iter().chain(child_roots) + storage.0.clone().into_iter().chain(child_roots).collect() ); let block: crate::Block = substrate_client::genesis::construct_genesis_block(state_root); let genesis_hash = block.header.hash(); diff --git a/core/test-runtime/src/lib.rs b/core/test-runtime/src/lib.rs index 88a246b094..c3b05b53d4 100644 --- a/core/test-runtime/src/lib.rs +++ b/core/test-runtime/src/lib.rs @@ -188,7 +188,7 @@ pub type Header = sr_primitives::generic::Header; /// Run whatever tests we have. pub fn run_tests(mut input: &[u8]) -> Vec { - use runtime_io::print; + use sr_primitives::print; print("run_tests..."); let block = Block::decode(&mut input).unwrap(); diff --git a/core/test-runtime/src/system.rs b/core/test-runtime/src/system.rs index f1288f8b28..e61e72f3a0 100644 --- a/core/test-runtime/src/system.rs +++ b/core/test-runtime/src/system.rs @@ -18,7 +18,7 @@ //! and depositing logs. use rstd::prelude::*; -use runtime_io::{storage_root, ordered_trie_root, storage_changes_root, twox_128, blake2_256}; +use runtime_io::{storage_root, storage_changes_root, twox_128, blake2_256}; use runtime_support::storage::{self, StorageValue, StorageMap}; use runtime_support::storage_items; use sr_primitives::{ @@ -29,7 +29,7 @@ use codec::{KeyedVec, Encode}; use crate::{ AccountId, BlockNumber, Extrinsic, Transfer, H256 as Hash, Block, Header, Digest, AuthorityId }; -use primitives::{Blake2Hasher, storage::well_known_keys}; +use primitives::storage::well_known_keys; const NONCE_OF: &[u8] = b"nonce:"; const BALANCE_OF: &[u8] = b"balance:"; @@ -101,8 +101,7 @@ fn execute_block_with_state_root_handler( // check transaction trie root represents the transactions. let txs = block.extrinsics.iter().map(Encode::encode).collect::>(); - let txs = txs.iter().map(Vec::as_slice).collect::>(); - let txs_root = ordered_trie_root::(&txs).into(); + let txs_root = BlakeTwo256::ordered_trie_root(txs); info_expect_equal_hash(&txs_root, &header.extrinsics_root); if let Mode::Overwrite = mode { header.extrinsics_root = txs_root; @@ -211,8 +210,7 @@ pub fn execute_transaction(utx: Extrinsic) -> ApplyResult { pub fn finalize_block() -> Header { let extrinsic_index: u32 = storage::unhashed::take(well_known_keys::EXTRINSIC_INDEX).unwrap(); let txs: Vec<_> = (0..extrinsic_index).map(ExtrinsicData::take).collect(); - let txs = txs.iter().map(Vec::as_slice).collect::>(); - let extrinsics_root = ordered_trie_root::(&txs).into(); + let extrinsics_root = BlakeTwo256::ordered_trie_root(txs).into(); let number = ::take().expect("Number is set by `initialize_block`"); let parent_hash = ::take(); let mut digest = ::take().expect("StorageDigest is set by `initialize_block`"); @@ -311,9 +309,9 @@ fn info_expect_equal_hash(given: &Hash, expected: &Hash) { #[cfg(not(feature = "std"))] fn info_expect_equal_hash(given: &Hash, expected: &Hash) { if given != expected { - runtime_io::print("Hash not equal"); - runtime_io::print(given.as_bytes()); - runtime_io::print(expected.as_bytes()); + sr_primitives::print("Hash not equal"); + sr_primitives::print(given.as_bytes()); + sr_primitives::print(expected.as_bytes()); } } diff --git a/core/trie/src/lib.rs b/core/trie/src/lib.rs index 3cc85731d8..eab05bab28 100644 --- a/core/trie/src/lib.rs +++ b/core/trie/src/lib.rs @@ -33,15 +33,15 @@ pub use trie_stream::TrieStream; /// The Substrate format implementation of `NodeCodec`. pub use node_codec::NodeCodec; /// Various re-exports from the `trie-db` crate. -pub use trie_db::{Trie, TrieMut, DBValue, Recorder, CError, - Query, TrieLayout, TrieConfiguration, nibble_ops}; +pub use trie_db::{ + Trie, TrieMut, DBValue, Recorder, CError, Query, TrieLayout, TrieConfiguration, nibble_ops, +}; /// Various re-exports from the `memory-db` crate. pub use memory_db::KeyFunction; pub use memory_db::prefixed_key; /// Various re-exports from the `hash-db` crate. pub use hash_db::{HashDB as HashDBT, EMPTY_PREFIX}; - #[derive(Default)] /// substrate trie layout pub struct Layout(rstd::marker::PhantomData); diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index 41d7b834b0..e399b5c02e 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -49,7 +49,7 @@ mod tests { traits::{CodeExecutor, Externalities}, }; use sr_primitives::{ - traits::{Header as HeaderT, Hash as HashT, Convert}, ApplyOutcome, ApplyResult, + traits::{Header as HeaderT, Hash as HashT, Convert}, ApplyResult, transaction_validity::InvalidTransaction, weights::{WeightMultiplier, GetDispatchInfo}, }; use contracts::ContractAddressFor; diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index bc2d6201b7..13140ad44c 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -82,8 +82,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 157, - impl_version: 159, + spec_version: 158, + impl_version: 158, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/contracts/src/wasm/runtime.rs b/srml/contracts/src/wasm/runtime.rs index 4baece3d91..573132cf31 100644 --- a/srml/contracts/src/wasm/runtime.rs +++ b/srml/contracts/src/wasm/runtime.rs @@ -822,7 +822,7 @@ define_env!(Env, , ext_println(ctx, str_ptr: u32, str_len: u32) => { let data = read_sandbox_memory(ctx, str_ptr, str_len)?; if let Ok(utf8) = core::str::from_utf8(&data) { - runtime_io::print(utf8); + sr_primitives::print(utf8); } Ok(()) }, diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index 2b74c44598..585ffde14d 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -562,7 +562,7 @@ decl_module! { fn on_initialize(n: T::BlockNumber) { if let Err(e) = Self::end_block(n) { - runtime_io::print(e); + sr_primitives::print(e); } } diff --git a/srml/elections/src/lib.rs b/srml/elections/src/lib.rs index 2ebdbade0c..1cd3258cf7 100644 --- a/srml/elections/src/lib.rs +++ b/srml/elections/src/lib.rs @@ -24,9 +24,9 @@ #![recursion_limit="128"] use rstd::prelude::*; -use sr_primitives::traits::{Zero, One, StaticLookup, Bounded, Saturating}; -use sr_primitives::weights::SimpleDispatchInfo; -use runtime_io::print; +use sr_primitives::{ + print, traits::{Zero, One, StaticLookup, Bounded, Saturating}, weights::SimpleDispatchInfo, +}; use support::{ StorageValue, StorageMap, dispatch::Result, decl_storage, decl_event, ensure, decl_module, diff --git a/srml/example/src/lib.rs b/srml/example/src/lib.rs index cfa3636e4d..ff797557f5 100644 --- a/srml/example/src/lib.rs +++ b/srml/example/src/lib.rs @@ -579,7 +579,7 @@ impl SignedExtension for WatchDummy { // check for `set_dummy` match call { Call::set_dummy(..) => { - runtime_io::print("set_dummy was received."); + sr_primitives::print("set_dummy was received."); let mut valid_tx = ValidTransaction::default(); valid_tx.priority = Bounded::max_value(); diff --git a/srml/executive/src/lib.rs b/srml/executive/src/lib.rs index ff0fc32e9b..ad9cb7bf80 100644 --- a/srml/executive/src/lib.rs +++ b/srml/executive/src/lib.rs @@ -217,7 +217,7 @@ where let l = uxt.encode().len(); match Self::apply_extrinsic_with_len(uxt, l, None) { Ok(Ok(())) => (), - Ok(Err(e)) => runtime_io::print(e), + Ok(Err(e)) => sr_primitives::print(e), Err(e) => { let err: &'static str = e.into(); panic!(err) }, } } diff --git a/srml/im-online/src/lib.rs b/srml/im-online/src/lib.rs index 5daa39299d..7da88836f3 100644 --- a/srml/im-online/src/lib.rs +++ b/srml/im-online/src/lib.rs @@ -75,9 +75,8 @@ use codec::{Encode, Decode}; use primitives::offchain::{OpaqueNetworkState, StorageKind}; use rstd::prelude::*; use session::historical::IdentificationTuple; -use runtime_io::Printable; use sr_primitives::{ - traits::{Convert, Member}, Perbill, + traits::{Convert, Member, Printable}, Perbill, transaction_validity::{ TransactionValidity, TransactionLongevity, ValidTransaction, InvalidTransaction, }, diff --git a/srml/sudo/src/lib.rs b/srml/sudo/src/lib.rs index 7d80851719..2a733ccb2e 100644 --- a/srml/sudo/src/lib.rs +++ b/srml/sudo/src/lib.rs @@ -126,7 +126,7 @@ decl_module! { Ok(_) => true, Err(e) => { let e: DispatchError = e.into(); - runtime_io::print(e); + sr_primitives::print(e); false } }; @@ -176,7 +176,7 @@ decl_module! { Ok(_) => true, Err(e) => { let e: DispatchError = e.into(); - runtime_io::print(e); + sr_primitives::print(e); false } }; diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index 13fb69990e..6935b4508d 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -67,8 +67,8 @@ pub use self::storage::{StorageValue, StorageMap, StorageLinkedMap, StorageDoubl pub use self::hashable::Hashable; pub use self::dispatch::{Parameter, Callable, IsSubType}; pub use self::double_map::StorageDoubleMapWithHasher; -pub use runtime_io::{print, storage_root, Printable}; -pub use sr_primitives::{self, ConsensusEngineId}; +pub use runtime_io::storage_root; +pub use sr_primitives::{self, ConsensusEngineId, print, traits::Printable}; /// Macro for easily creating a new implementation of the `Get` trait. Use similarly to /// how you would declare a `const`: @@ -270,7 +270,8 @@ pub use serde::{Serialize, Deserialize}; mod tests { use super::*; use codec::Codec; - use runtime_io::{with_externalities, Blake2Hasher}; + use runtime_io::with_externalities; + use primitives::Blake2Hasher; pub use srml_metadata::{ DecodeDifferent, StorageEntryMetadata, StorageMetadata, StorageEntryType, StorageEntryModifier, DefaultByte, DefaultByteGetter, StorageHasher diff --git a/srml/support/test/tests/final_keys.rs b/srml/support/test/tests/final_keys.rs index 73de126050..dfa363b582 100644 --- a/srml/support/test/tests/final_keys.rs +++ b/srml/support/test/tests/final_keys.rs @@ -14,7 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use runtime_io::{with_externalities, Blake2Hasher}; +use runtime_io::with_externalities; +use primitives::Blake2Hasher; use support::{StorageValue, StorageMap, StorageLinkedMap, StorageDoubleMap}; use support::storage::unhashed; use codec::{Encode, Decode}; diff --git a/srml/support/test/tests/instance.rs b/srml/support/test/tests/instance.rs index 3370c0d201..0662689379 100644 --- a/srml/support/test/tests/instance.rs +++ b/srml/support/test/tests/instance.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . #![recursion_limit="128"] -use runtime_io::{with_externalities, Blake2Hasher}; +use runtime_io::with_externalities; use support::{ Parameter, traits::Get, parameter_types, sr_primitives::{generic, BuildStorage, traits::{BlakeTwo256, Block as _, Verify}}, @@ -28,7 +28,7 @@ use support::{ use inherents::{ ProvideInherent, InherentData, InherentIdentifier, RuntimeString, MakeFatalError }; -use primitives::{H256, sr25519}; +use primitives::{H256, sr25519, Blake2Hasher}; mod system; diff --git a/srml/system/benches/bench.rs b/srml/system/benches/bench.rs index b050e80c48..b24e52f457 100644 --- a/srml/system/benches/bench.rs +++ b/srml/system/benches/bench.rs @@ -17,8 +17,8 @@ use criterion::{Criterion, criterion_group, criterion_main, black_box}; use srml_system as system; use support::{decl_module, decl_event, impl_outer_origin, impl_outer_event}; -use runtime_io::{with_externalities, Blake2Hasher}; -use primitives::H256; +use runtime_io::with_externalities; +use primitives::{H256, Blake2Hasher}; use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; mod module { diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index 02a7002806..9bacbd6887 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -118,10 +118,10 @@ use safe_mix::TripletMix; use codec::{Encode, Decode}; #[cfg(any(feature = "std", test))] -use runtime_io::{TestExternalities, Blake2Hasher}; +use runtime_io::TestExternalities; #[cfg(any(feature = "std", test))] -use primitives::ChangesTrieConfiguration; +use primitives::{ChangesTrieConfiguration, Blake2Hasher}; pub mod offchain; @@ -151,8 +151,7 @@ pub fn extrinsics_root(extrinsics: &[E]) -> H::Output /// Compute the trie root of a list of extrinsics. pub fn extrinsics_data_root(xts: Vec>) -> H::Output { - let xts = xts.iter().map(Vec::as_slice).collect::>(); - H::ordered_trie_root(&xts) + H::ordered_trie_root(xts) } pub trait Trait: 'static + Eq + Clone { -- GitLab From 6d48cce29aa7bcb8c11070a400179f1188a7f620 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 13 Sep 2019 21:19:04 +0200 Subject: [PATCH 095/275] RPC call to get all RPC methods (#3613) * Add meta rpc_methods call. * Sort methods. * Bump runtime. * Change format a bit to support versioning. --- Cargo.lock | 83 +++++++++++++++++++------------------ core/rpc-servers/Cargo.toml | 9 ++-- core/rpc-servers/src/lib.rs | 13 ++++++ core/rpc/api/Cargo.toml | 8 ++-- core/service/src/builder.rs | 30 ++++---------- node/cli/Cargo.toml | 2 +- node/rpc/Cargo.toml | 8 ++-- node/runtime/src/lib.rs | 2 +- 8 files changed, 79 insertions(+), 76 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d526d6f65f..68a2e1bf41 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1441,14 +1441,14 @@ dependencies = [ [[package]] name = "jsonrpc-client-transports" -version = "13.1.0" +version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1459,7 +1459,7 @@ dependencies = [ [[package]] name = "jsonrpc-core" -version = "13.1.0" +version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1471,15 +1471,15 @@ dependencies = [ [[package]] name = "jsonrpc-core-client" -version = "13.1.0" +version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-client-transports 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-client-transports 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-derive" -version = "13.1.0" +version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1490,12 +1490,12 @@ dependencies = [ [[package]] name = "jsonrpc-http-server" -version = "13.1.0" +version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1504,10 +1504,10 @@ dependencies = [ [[package]] name = "jsonrpc-pubsub" -version = "13.1.0" +version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1515,12 +1515,12 @@ dependencies = [ [[package]] name = "jsonrpc-server-utils" -version = "13.1.0" +version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1531,11 +1531,11 @@ dependencies = [ [[package]] name = "jsonrpc-ws-server" -version = "13.1.0" +version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2324,7 +2324,7 @@ dependencies = [ "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "node-executor 2.0.0", "node-primitives 2.0.0", @@ -2415,10 +2415,10 @@ name = "node-rpc" version = "2.0.0" dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", "node-runtime 2.0.0", @@ -2440,7 +2440,7 @@ dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", "substrate-rpc 2.0.0", @@ -5151,8 +5151,8 @@ dependencies = [ "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5180,10 +5180,10 @@ version = "2.0.0" dependencies = [ "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5207,12 +5207,13 @@ dependencies = [ name = "substrate-rpc-servers" version = "2.0.0" dependencies = [ - "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-http-server 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-ws-server 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-http-server 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-ws-server 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", ] @@ -6630,14 +6631,14 @@ dependencies = [ "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum js-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)" = "da3ea71161651a4cd97d999b2da139109c537b15ab33abc8ae4ead38deac8a03" -"checksum jsonrpc-client-transports 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "39577db48b004cffb4c5b8e5c9b993c177c52599ecbee88711e815acf65144db" -"checksum jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd42951eb35079520ee29b7efbac654d85821b397ef88c8151600ef7e2d00217" -"checksum jsonrpc-core-client 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f047c10738edee7c3c6acf5241a0ce33df32ef9230c1a7fb03e4a77ee72c992f" -"checksum jsonrpc-derive 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29f9149f785deaae92a4c834a9a1a83a4313b8cfedccf15362cd4cf039a64501" -"checksum jsonrpc-http-server 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4edd28922653d79e4f6c0f5d0a1034a4edbc5f9cf6cad8ec85e2a685713e3708" -"checksum jsonrpc-pubsub 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2c08b444cc0ed70263798834343d0ac875e664257df8079160f23ac1ea79446" -"checksum jsonrpc-server-utils 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44561bfdd31401bad790527f1e951dde144f2341ddc3e1b859d32945e1a34eff" -"checksum jsonrpc-ws-server 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d230ff76a8e4a3fb068aab6ba23d0c4e7d6e3b41bca524daa33988b04b065265" +"checksum jsonrpc-client-transports 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dbf2466adbf6d5b4e618857f22be40b1e1cc6ed79d72751324358f6b539b06d" +"checksum jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91d767c183a7e58618a609499d359ce3820700b3ebb4823a18c343b4a2a41a0d" +"checksum jsonrpc-core-client 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "161dc223549fa6fe4a4eda675de2d1d3cff5a7164e5c031cdf1e22c734700f8b" +"checksum jsonrpc-derive 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4a76285ebba4515680fbfe4b62498ccb2a932384c8732eed68351b02fb7ae475" +"checksum jsonrpc-http-server 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "601fcc7bec888c7cbc7fd124d3d6744d72c0ebb540eca6fe2261b71f9cff6320" +"checksum jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "64e0fb0664d8ce287e826940dafbb45379443c595bdd71d93655f3c8f25fd992" +"checksum jsonrpc-server-utils 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4d415f51d016a4682878e19dd03e8c0b61cd4394912d7cd3dc48d4f19f061a4e" +"checksum jsonrpc-ws-server 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4699433c1ac006d7df178b4c29c191e5bb6d81e2dca18c5c804a094592900101" "checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" "checksum keccak-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3468207deea1359a0e921591ae9b4c928733d94eb9d6a2eeda994cfd59f42cf8" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" diff --git a/core/rpc-servers/Cargo.toml b/core/rpc-servers/Cargo.toml index d4befd52e9..f5c5da0339 100644 --- a/core/rpc-servers/Cargo.toml +++ b/core/rpc-servers/Cargo.toml @@ -5,12 +5,13 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -jsonrpc-core = "13.1.0" -pubsub = { package = "jsonrpc-pubsub", version = "13.1.0" } +jsonrpc-core = "13.2.0" +pubsub = { package = "jsonrpc-pubsub", version = "13.2.0" } log = "0.4" serde = "1.0" +serde_json = "1.0" sr-primitives = { path = "../sr-primitives" } [target.'cfg(not(target_os = "unknown"))'.dependencies] -http = { package = "jsonrpc-http-server", version = "13.1.0" } -ws = { package = "jsonrpc-ws-server", version = "13.1.0" } +http = { package = "jsonrpc-http-server", version = "13.2.0" } +ws = { package = "jsonrpc-ws-server", version = "13.2.0" } diff --git a/core/rpc-servers/src/lib.rs b/core/rpc-servers/src/lib.rs index 05d24a2302..a23b4a0899 100644 --- a/core/rpc-servers/src/lib.rs +++ b/core/rpc-servers/src/lib.rs @@ -40,6 +40,19 @@ pub fn rpc_handler( ) -> RpcHandler { let mut io = pubsub::PubSubHandler::default(); extension.augment(&mut io); + + // add an endpoint to list all available methods. + let mut methods = io.iter().map(|x| x.0.clone()).collect::>(); + io.add_method("rpc_methods", { + methods.sort(); + let methods = serde_json::to_value(&methods) + .expect("Serialization of Vec is infallible; qed"); + + move |_| Ok(serde_json::json!({ + "version": 1, + "methods": methods.clone(), + })) + }); io } diff --git a/core/rpc/api/Cargo.toml b/core/rpc/api/Cargo.toml index 4b2eb613db..cc40ff39b2 100644 --- a/core/rpc/api/Cargo.toml +++ b/core/rpc/api/Cargo.toml @@ -8,10 +8,10 @@ edition = "2018" codec = { package = "parity-scale-codec", version = "1.0.0" } derive_more = "0.14.0" futures03 = { package = "futures-preview", version = "0.3.0-alpha.17", features = ["compat"] } -jsonrpc-core = "13.0.0" -jsonrpc-core-client = "13.0.0" -jsonrpc-derive = "13.0.0" -jsonrpc-pubsub = "13.0.0" +jsonrpc-core = "13.2.0" +jsonrpc-core-client = "13.2.0" +jsonrpc-derive = "13.2.0" +jsonrpc-pubsub = "13.2.0" log = "0.4" parking_lot = "0.9.0" primitives = { package = "substrate-primitives", path = "../../primitives" } diff --git a/core/service/src/builder.rs b/core/service/src/builder.rs index 458c72a74f..e6d2cdc89a 100644 --- a/core/service/src/builder.rs +++ b/core/service/src/builder.rs @@ -821,12 +821,9 @@ ServiceBuilder< TBl >, >, Error> { - let mut config = self.config; - session::generate_initial_session_keys( - self.client.clone(), - config.dev_key_seed.clone().map(|s| vec![s]).unwrap_or_default() - )?; - let ( + let ServiceBuilder { + marker: _, + mut config, client, fetcher, backend, @@ -840,21 +837,12 @@ ServiceBuilder< rpc_extensions, dht_event_tx, rpc_builder, - ) = ( - self.client, - self.fetcher, - self.backend, - self.keystore, - self.select_chain, - self.import_queue, - self.finality_proof_request_builder, - self.finality_proof_provider, - self.network_protocol, - self.transaction_pool, - self.rpc_extensions, - self.dht_event_tx, - self.rpc_builder, - ); + } = self; + + session::generate_initial_session_keys( + client.clone(), + config.dev_key_seed.clone().map(|s| vec![s]).unwrap_or_default() + )?; new_impl!( TBl, diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index c28a517639..68232800f2 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -11,7 +11,7 @@ log = "0.4" tokio = "0.1.7" futures = "0.1" exit-future = "0.1" -jsonrpc-core = "13.1.0" +jsonrpc-core = "13.2.0" cli = { package = "substrate-cli", path = "../../core/cli" } codec = { package = "parity-scale-codec", version = "1.0.0" } sr-io = { path = "../../core/sr-io" } diff --git a/node/rpc/Cargo.toml b/node/rpc/Cargo.toml index 3485357053..1bf7bae384 100644 --- a/node/rpc/Cargo.toml +++ b/node/rpc/Cargo.toml @@ -6,10 +6,10 @@ edition = "2018" [dependencies] client = { package = "substrate-client", path = "../../core/client" } -jsonrpc-core = "13.1.0" -jsonrpc-core-client = "13.1.0" -jsonrpc-derive = "13.1.0" -jsonrpc-pubsub = "13.1.0" +jsonrpc-core = "13.2.0" +jsonrpc-core-client = "13.2.0" +jsonrpc-derive = "13.2.0" +jsonrpc-pubsub = "13.2.0" keyring = { package = "substrate-keyring", path = "../../core/keyring" } log = "0.4" node-primitives = { path = "../primitives" } diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 13140ad44c..a5eb080f5d 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 158, - impl_version: 158, + impl_version: 159, apis: RUNTIME_API_VERSIONS, }; -- GitLab From 203e2c23b51bf23f778b3afee16465e6dca04cf2 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 16 Sep 2019 13:30:21 +0300 Subject: [PATCH 096/275] Fetching multiple remote values using single message (#3612) * multiple remote values in single message * keys_str: String ->keys_str: closure --- core/client/src/cht.rs | 46 ++++--- core/client/src/client.rs | 20 +-- core/client/src/light/fetcher.rs | 48 ++++---- core/network/src/chain.rs | 17 ++- core/network/src/on_demand_layer.rs | 3 +- core/network/src/protocol.rs | 48 ++++++-- core/network/src/protocol/light_dispatch.rs | 63 +++++++--- core/network/src/protocol/message.rs | 4 +- core/rpc/src/state/state_light.rs | 22 +++- core/state-machine/src/lib.rs | 130 +++++++++++++------- core/test-client/src/lib.rs | 58 +-------- 11 files changed, 271 insertions(+), 188 deletions(-) diff --git a/core/client/src/cht.rs b/core/client/src/cht.rs index 37462851a9..63a5b39c26 100644 --- a/core/client/src/cht.rs +++ b/core/client/src/cht.rs @@ -23,8 +23,6 @@ //! root has. A correct proof implies that the claimed block is identical to the one //! we discarded. -use std::collections::HashSet; - use hash_db; use codec::Encode; use trie; @@ -105,15 +103,10 @@ pub fn build_proof( let mut storage = InMemoryState::::default().update(transaction); let trie_storage = storage.as_trie_backend() .expect("InMemoryState::as_trie_backend always returns Some; qed"); - let mut total_proof = HashSet::new(); - for block in blocks.into_iter() { - debug_assert_eq!(block_to_cht_number(cht_size, block), Some(cht_num)); - - let (value, proof) = prove_read_on_trie_backend(trie_storage, &encode_cht_key(block))?; - assert!(value.is_some(), "we have just built trie that includes the value for block"); - total_proof.extend(proof); - } - Ok(total_proof.into_iter().collect()) + prove_read_on_trie_backend( + trie_storage, + blocks.into_iter().map(|number| encode_cht_key(number)), + ).map_err(ClientError::Execution) } /// Check CHT-based header proof. @@ -128,9 +121,21 @@ pub fn check_proof( Hasher: hash_db::Hasher, Hasher::Out: Ord, { - do_check_proof::(local_root, local_number, remote_hash, move |local_root, local_cht_key| - read_proof_check::(local_root, remote_proof, - local_cht_key).map_err(|e| ClientError::from(e))) + do_check_proof::( + local_root, + local_number, + remote_hash, + move |local_root, local_cht_key| + read_proof_check::( + local_root, + remote_proof, + ::std::iter::once(local_cht_key), + ) + .map(|mut map| map + .remove(local_cht_key) + .expect("checked proof of local_cht_key; qed")) + .map_err(|e| ClientError::from(e)), + ) } /// Check CHT-based header proof on pre-created proving backend. @@ -145,9 +150,16 @@ pub fn check_proof_on_proving_backend( Hasher: hash_db::Hasher, Hasher::Out: Ord, { - do_check_proof::(local_root, local_number, remote_hash, |_, local_cht_key| - read_proof_check_on_proving_backend::( - proving_backend, local_cht_key).map_err(|e| ClientError::from(e))) + do_check_proof::( + local_root, + local_number, + remote_hash, + |_, local_cht_key| + read_proof_check_on_proving_backend::( + proving_backend, + local_cht_key, + ).map_err(|e| ClientError::from(e)), + ) } /// Check CHT-based header proof using passed checker function. diff --git a/core/client/src/client.rs b/core/client/src/client.rs index 63d30b45e3..d0a53802fa 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -436,24 +436,28 @@ impl Client where } /// Reads storage value at a given block + key, returning read proof. - pub fn read_proof(&self, id: &BlockId, key: &[u8]) -> error::Result>> { + pub fn read_proof(&self, id: &BlockId, keys: I) -> error::Result>> where + I: IntoIterator, + I::Item: AsRef<[u8]>, + { self.state_at(id) - .and_then(|state| prove_read(state, key) - .map(|(_, proof)| proof) + .and_then(|state| prove_read(state, keys) .map_err(Into::into)) } /// Reads child storage value at a given block + storage_key + key, returning /// read proof. - pub fn read_child_proof( + pub fn read_child_proof( &self, id: &BlockId, storage_key: &[u8], - key: &[u8] - ) -> error::Result>> { + keys: I, + ) -> error::Result>> where + I: IntoIterator, + I::Item: AsRef<[u8]>, + { self.state_at(id) - .and_then(|state| prove_child_read(state, storage_key, key) - .map(|(_, proof)| proof) + .and_then(|state| prove_child_read(state, storage_key, keys) .map_err(Into::into)) } diff --git a/core/client/src/light/fetcher.rs b/core/client/src/light/fetcher.rs index 068534c5f6..3c4387209a 100644 --- a/core/client/src/light/fetcher.rs +++ b/core/client/src/light/fetcher.rs @@ -17,7 +17,7 @@ //! Light client data fetcher. Fetches requested data from remote full nodes. use std::sync::Arc; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashMap}; use std::marker::PhantomData; use std::future::Future; @@ -73,7 +73,7 @@ pub struct RemoteReadRequest { /// Header of block at which read is performed. pub header: Header, /// Storage key to read. - pub key: Vec, + pub keys: Vec>, /// Number of times to retry request. None means that default RETRY_COUNT is used. pub retry_count: Option, } @@ -88,7 +88,7 @@ pub struct RemoteReadChildRequest { /// Storage key for child. pub storage_key: Vec, /// Child storage key to read. - pub key: Vec, + pub keys: Vec>, /// Number of times to retry request. None means that default RETRY_COUNT is used. pub retry_count: Option, } @@ -147,7 +147,7 @@ pub trait Fetcher: Send + Sync { /// Remote header future. type RemoteHeaderResult: Future> + Send + 'static; /// Remote storage read future. - type RemoteReadResult: Future>, ClientError>> + Send + 'static; + type RemoteReadResult: Future, Option>>, ClientError>> + Send + 'static; /// Remote call result future. type RemoteCallResult: Future, ClientError>> + Send + 'static; /// Remote changes result future. @@ -193,13 +193,13 @@ pub trait FetchChecker: Send + Sync { &self, request: &RemoteReadRequest, remote_proof: Vec> - ) -> ClientResult>>; + ) -> ClientResult, Option>>>; /// Check remote storage read proof. fn check_read_child_proof( &self, request: &RemoteReadChildRequest, remote_proof: Vec> - ) -> ClientResult>>; + ) -> ClientResult, Option>>>; /// Check remote method execution proof. fn check_execution_proof( &self, @@ -395,23 +395,26 @@ impl FetchChecker for LightDataChecker fn check_read_proof( &self, request: &RemoteReadRequest, - remote_proof: Vec> - ) -> ClientResult>> { - read_proof_check::(convert_hash(request.header.state_root()), remote_proof, &request.key) - .map_err(Into::into) + remote_proof: Vec>, + ) -> ClientResult, Option>>> { + read_proof_check::( + convert_hash(request.header.state_root()), + remote_proof, + request.keys.iter(), + ).map_err(Into::into) } fn check_read_child_proof( &self, request: &RemoteReadChildRequest, remote_proof: Vec> - ) -> ClientResult>> { - read_child_proof_check::( + ) -> ClientResult, Option>>> { + read_child_proof_check::( convert_hash(request.header.state_root()), remote_proof, &request.storage_key, - &request.key) - .map_err(Into::into) + request.keys.iter(), + ).map_err(Into::into) } fn check_execution_proof( @@ -529,7 +532,7 @@ pub mod tests { impl Fetcher for OkCallFetcher { type RemoteHeaderResult = Ready>; - type RemoteReadResult = Ready>, ClientError>>; + type RemoteReadResult = Ready, Option>>, ClientError>>; type RemoteCallResult = Ready, ClientError>>; type RemoteChangesResult = Ready, u32)>, ClientError>>; type RemoteBodyResult = Ready, ClientError>>; @@ -579,7 +582,10 @@ pub mod tests { let heap_pages = remote_client.storage(&remote_block_id, &StorageKey(well_known_keys::HEAP_PAGES.to_vec())) .unwrap() .and_then(|v| Decode::decode(&mut &v.0[..]).ok()).unwrap(); - let remote_read_proof = remote_client.read_proof(&remote_block_id, well_known_keys::HEAP_PAGES).unwrap(); + let remote_read_proof = remote_client.read_proof( + &remote_block_id, + &[well_known_keys::HEAP_PAGES], + ).unwrap(); // check remote read proof locally let local_storage = InMemoryBlockchain::::new(); @@ -618,7 +624,7 @@ pub mod tests { let remote_read_proof = remote_client.read_child_proof( &remote_block_id, b":child_storage:default:child1", - b"key1", + &[b"key1"], ).unwrap(); // check locally @@ -676,9 +682,9 @@ pub mod tests { assert_eq!((&local_checker as &dyn FetchChecker).check_read_proof(&RemoteReadRequest::
{ block: remote_block_header.hash(), header: remote_block_header, - key: well_known_keys::HEAP_PAGES.to_vec(), + keys: vec![well_known_keys::HEAP_PAGES.to_vec()], retry_count: None, - }, remote_read_proof).unwrap().unwrap()[0], heap_pages as u8); + }, remote_read_proof).unwrap().remove(well_known_keys::HEAP_PAGES).unwrap().unwrap()[0], heap_pages as u8); } #[test] @@ -694,11 +700,11 @@ pub mod tests { block: remote_block_header.hash(), header: remote_block_header, storage_key: b":child_storage:default:child1".to_vec(), - key: b"key1".to_vec(), + keys: vec![b"key1".to_vec()], retry_count: None, }, remote_read_proof - ).unwrap().unwrap(), result); + ).unwrap().remove(b"key1".as_ref()).unwrap().unwrap(), result); } #[test] diff --git a/core/network/src/chain.rs b/core/network/src/chain.rs index a4767caf13..b7465685ae 100644 --- a/core/network/src/chain.rs +++ b/core/network/src/chain.rs @@ -49,10 +49,15 @@ pub trait Client: Send + Sync { fn header_proof(&self, block_number: ::Number) -> Result<(Block::Header, Vec>), Error>; /// Get storage read execution proof. - fn read_proof(&self, block: &Block::Hash, key: &[u8]) -> Result>, Error>; + fn read_proof(&self, block: &Block::Hash, keys: &[Vec]) -> Result>, Error>; /// Get child storage read execution proof. - fn read_child_proof(&self, block: &Block::Hash, storage_key: &[u8], key: &[u8]) -> Result>, Error>; + fn read_child_proof( + &self, + block: &Block::Hash, + storage_key: &[u8], + keys: &[Vec], + ) -> Result>, Error>; /// Get method execution proof. fn execution_proof(&self, block: &Block::Hash, method: &str, data: &[u8]) -> Result<(Vec, Vec>), Error>; @@ -113,18 +118,18 @@ impl Client for SubstrateClient where (self as &SubstrateClient).header_proof(&BlockId::Number(block_number)) } - fn read_proof(&self, block: &Block::Hash, key: &[u8]) -> Result>, Error> { - (self as &SubstrateClient).read_proof(&BlockId::Hash(block.clone()), key) + fn read_proof(&self, block: &Block::Hash, keys: &[Vec]) -> Result>, Error> { + (self as &SubstrateClient).read_proof(&BlockId::Hash(block.clone()), keys) } fn read_child_proof( &self, block: &Block::Hash, storage_key: &[u8], - key: &[u8] + keys: &[Vec], ) -> Result>, Error> { (self as &SubstrateClient) - .read_child_proof(&BlockId::Hash(block.clone()), storage_key, key) + .read_child_proof(&BlockId::Hash(block.clone()), storage_key, keys) } fn execution_proof(&self, block: &Block::Hash, method: &str, data: &[u8]) -> Result<(Vec, Vec>), Error> { diff --git a/core/network/src/on_demand_layer.rs b/core/network/src/on_demand_layer.rs index 818230eea5..cdcb99a25f 100644 --- a/core/network/src/on_demand_layer.rs +++ b/core/network/src/on_demand_layer.rs @@ -17,6 +17,7 @@ //! On-demand requests service. use crate::protocol::light_dispatch::RequestData; +use std::collections::HashMap; use std::sync::Arc; use futures::{prelude::*, sync::mpsc, sync::oneshot}; use futures03::compat::{Compat01As03, Future01CompatExt as _}; @@ -84,7 +85,7 @@ impl Fetcher for OnDemand where B::Header: HeaderT, { type RemoteHeaderResult = Compat01As03>; - type RemoteReadResult = Compat01As03>>>; + type RemoteReadResult = Compat01As03, Option>>>>; type RemoteCallResult = Compat01As03>>; type RemoteChangesResult = Compat01As03, u32)>>>; type RemoteBodyResult = Compat01As03>>; diff --git a/core/network/src/protocol.rs b/core/network/src/protocol.rs index ee2849e1dd..6dab5a2a54 100644 --- a/core/network/src/protocol.rs +++ b/core/network/src/protocol.rs @@ -172,11 +172,17 @@ impl<'a, B: BlockT> LightDispatchNetwork for LightDispatchIn<'a, B> { self.behaviour.send_packet(who, message) } - fn send_read_request(&mut self, who: &PeerId, id: RequestId, block: ::Hash, key: Vec) { + fn send_read_request( + &mut self, + who: &PeerId, + id: RequestId, + block: ::Hash, + keys: Vec>, + ) { let message = message::generic::Message::RemoteReadRequest(message::RemoteReadRequest { id, block, - key, + keys, }); self.behaviour.send_packet(who, message) @@ -188,13 +194,13 @@ impl<'a, B: BlockT> LightDispatchNetwork for LightDispatchIn<'a, B> { id: RequestId, block: ::Hash, storage_key: Vec, - key: Vec + keys: Vec>, ) { let message = message::generic::Message::RemoteReadChildRequest(message::RemoteReadChildRequest { id, block, storage_key, - key, + keys, }); self.behaviour.send_packet(who, message) @@ -1272,15 +1278,24 @@ impl, H: ExHashT> Protocol { who: PeerId, request: message::RemoteReadRequest, ) { + let keys_str = || match request.keys.len() { + 1 => request.keys[0].to_hex::(), + _ => format!( + "{}..{}", + request.keys[0].to_hex::(), + request.keys[request.keys.len() - 1].to_hex::(), + ), + }; + trace!(target: "sync", "Remote read request {} from {} ({} at {})", - request.id, who, request.key.to_hex::(), request.block); - let proof = match self.context_data.chain.read_proof(&request.block, &request.key) { + request.id, who, keys_str(), request.block); + let proof = match self.context_data.chain.read_proof(&request.block, &request.keys) { Ok(proof) => proof, Err(error) => { trace!(target: "sync", "Remote read request {} from {} ({} at {}) failed with: {}", request.id, who, - request.key.to_hex::(), + keys_str(), request.block, error ); @@ -1301,16 +1316,29 @@ impl, H: ExHashT> Protocol { who: PeerId, request: message::RemoteReadChildRequest, ) { + let keys_str = || match request.keys.len() { + 1 => request.keys[0].to_hex::(), + _ => format!( + "{}..{}", + request.keys[0].to_hex::(), + request.keys[request.keys.len() - 1].to_hex::(), + ), + }; + trace!(target: "sync", "Remote read child request {} from {} ({} {} at {})", - request.id, who, request.storage_key.to_hex::(), request.key.to_hex::(), request.block); - let proof = match self.context_data.chain.read_child_proof(&request.block, &request.storage_key, &request.key) { + request.id, who, request.storage_key.to_hex::(), keys_str(), request.block); + let proof = match self.context_data.chain.read_child_proof( + &request.block, + &request.storage_key, + &request.keys, + ) { Ok(proof) => proof, Err(error) => { trace!(target: "sync", "Remote read child request {} from {} ({} {} at {}) failed with: {}", request.id, who, request.storage_key.to_hex::(), - request.key.to_hex::(), + keys_str(), request.block, error ); diff --git a/core/network/src/protocol/light_dispatch.rs b/core/network/src/protocol/light_dispatch.rs index db7a55d742..33ff23c909 100644 --- a/core/network/src/protocol/light_dispatch.rs +++ b/core/network/src/protocol/light_dispatch.rs @@ -53,7 +53,13 @@ pub trait LightDispatchNetwork { fn send_header_request(&mut self, who: &PeerId, id: RequestId, block: <::Header as HeaderT>::Number); /// Send to `who` a read request. - fn send_read_request(&mut self, who: &PeerId, id: RequestId, block: ::Hash, key: Vec); + fn send_read_request( + &mut self, + who: &PeerId, + id: RequestId, + block: ::Hash, + keys: Vec>, + ); /// Send to `who` a child read request. fn send_read_child_request( @@ -62,7 +68,7 @@ pub trait LightDispatchNetwork { id: RequestId, block: ::Hash, storage_key: Vec, - key: Vec + keys: Vec>, ); /// Send to `who` a call request. @@ -135,10 +141,13 @@ struct Request { pub(crate) enum RequestData { RemoteBody(RemoteBodyRequest, OneShotSender, ClientError>>), RemoteHeader(RemoteHeaderRequest, OneShotSender>), - RemoteRead(RemoteReadRequest, OneShotSender>, ClientError>>), + RemoteRead( + RemoteReadRequest, + OneShotSender, Option>>, ClientError>>, + ), RemoteReadChild( RemoteReadChildRequest, - OneShotSender>, ClientError>> + OneShotSender, Option>>, ClientError>> ), RemoteCall(RemoteCallRequest, OneShotSender, ClientError>>), RemoteChanges( @@ -174,7 +183,7 @@ impl FetchChecker for AlwaysBadChecker { &self, _request: &RemoteReadRequest, _remote_proof: Vec> - ) -> Result>, ClientError> { + ) -> Result,Option>>, ClientError> { Err(ClientError::Msg("AlwaysBadChecker".into())) } @@ -182,7 +191,7 @@ impl FetchChecker for AlwaysBadChecker { &self, _request: &RemoteReadChildRequest, _remote_proof: Vec> - ) -> Result>, ClientError> { + ) -> Result, Option>>, ClientError> { Err(ClientError::Msg("AlwaysBadChecker".into())) } @@ -604,7 +613,7 @@ impl Request { peer, self.id, data.block, - data.key.clone(), + data.keys.clone(), ), RequestData::RemoteReadChild(ref data, _) => out.send_read_child_request( @@ -612,7 +621,7 @@ impl Request { self.id, data.block, data.storage_key.clone(), - data.key.clone(), + data.keys.clone(), ), RequestData::RemoteCall(ref data, _) => out.send_call_request( @@ -663,7 +672,7 @@ impl RequestData { #[cfg(test)] pub mod tests { - use std::collections::HashSet; + use std::collections::{HashMap, HashSet}; use std::sync::Arc; use std::time::Instant; use futures::{Future, sync::oneshot}; @@ -693,20 +702,34 @@ pub mod tests { } } - fn check_read_proof(&self, _: &RemoteReadRequest
, _: Vec>) -> ClientResult>> { + fn check_read_proof( + &self, + request: &RemoteReadRequest
, + _: Vec>, + ) -> ClientResult, Option>>> { match self.ok { - true => Ok(Some(vec![42])), + true => Ok(request.keys + .iter() + .cloned() + .map(|k| (k, Some(vec![42]))) + .collect() + ), false => Err(ClientError::Backend("Test error".into())), } } fn check_read_child_proof( &self, - _: &RemoteReadChildRequest
, + request: &RemoteReadChildRequest
, _: Vec> - ) -> ClientResult>> { + ) -> ClientResult, Option>>> { match self.ok { - true => Ok(Some(vec![42])), + true => Ok(request.keys + .iter() + .cloned() + .map(|k| (k, Some(vec![42]))) + .collect() + ), false => Err(ClientError::Backend("Test error".into())), } } @@ -782,9 +805,9 @@ pub mod tests { self.disconnected_peers.insert(who.clone()); } fn send_header_request(&mut self, _: &PeerId, _: RequestId, _: <::Header as HeaderT>::Number) {} - fn send_read_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: Vec) {} + fn send_read_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: Vec>) {} fn send_read_child_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: Vec, - _: Vec) {} + _: Vec>) {} fn send_call_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: String, _: Vec) {} fn send_changes_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: ::Hash, _: ::Hash, _: ::Hash, _: Option>, _: Vec) {} @@ -984,7 +1007,7 @@ pub mod tests { light_dispatch.add_request(&mut network_interface, RequestData::RemoteRead(RemoteReadRequest { header: dummy_header(), block: Default::default(), - key: b":key".to_vec(), + keys: vec![b":key".to_vec()], retry_count: None, }, tx)); @@ -992,7 +1015,7 @@ pub mod tests { id: 0, proof: vec![vec![2]], }); - assert_eq!(response.wait().unwrap().unwrap(), Some(vec![42])); + assert_eq!(response.wait().unwrap().unwrap().remove(b":key".as_ref()).unwrap(), Some(vec![42])); } #[test] @@ -1007,7 +1030,7 @@ pub mod tests { header: dummy_header(), block: Default::default(), storage_key: b":child_storage:sub".to_vec(), - key: b":key".to_vec(), + keys: vec![b":key".to_vec()], retry_count: None, }, tx)); @@ -1016,7 +1039,7 @@ pub mod tests { id: 0, proof: vec![vec![2]], }); - assert_eq!(response.wait().unwrap().unwrap(), Some(vec![42])); + assert_eq!(response.wait().unwrap().unwrap().remove(b":key".as_ref()).unwrap(), Some(vec![42])); } #[test] diff --git a/core/network/src/protocol/message.rs b/core/network/src/protocol/message.rs index 39bb94eb33..cb02845735 100644 --- a/core/network/src/protocol/message.rs +++ b/core/network/src/protocol/message.rs @@ -284,7 +284,7 @@ pub mod generic { /// Block at which to perform call. pub block: H, /// Storage key. - pub key: Vec, + pub keys: Vec>, } #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] @@ -297,7 +297,7 @@ pub mod generic { /// Child Storage key. pub storage_key: Vec, /// Storage key. - pub key: Vec, + pub keys: Vec>, } #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] diff --git a/core/rpc/src/state/state_light.rs b/core/rpc/src/state/state_light.rs index eb14b3fe7b..456992db66 100644 --- a/core/rpc/src/state/state_light.rs +++ b/core/rpc/src/state/state_light.rs @@ -153,9 +153,16 @@ impl StateBackend for LightState Either::Left(fetcher.remote_read(RemoteReadRequest { block: header.hash(), header, - key: key.0, + keys: vec![key.0.clone()], retry_count: Default::default(), - }).then(|result| ready(result.map(|data| data.map(StorageData)).map_err(client_err)))), + }).then(move |result| ready(result + .map(|mut data| data + .remove(&key.0) + .expect("successful result has entry for all keys; qed") + .map(StorageData) + ) + .map_err(client_err) + ))), Err(error) => Either::Right(ready(Err(error))), }); @@ -197,9 +204,16 @@ impl StateBackend for LightState Either::Right(ready(Err(error))), }); diff --git a/core/state-machine/src/lib.rs b/core/state-machine/src/lib.rs index 4008ec7c23..7b9dc6ac84 100644 --- a/core/state-machine/src/lib.rs +++ b/core/state-machine/src/lib.rs @@ -18,7 +18,10 @@ #![warn(missing_docs)] -use std::{fmt, panic::UnwindSafe, result, marker::PhantomData}; +use std::{ + fmt, result, collections::HashMap, + marker::PhantomData, panic::UnwindSafe, +}; use log::warn; use hash_db::Hasher; use codec::{Decode, Encode}; @@ -524,97 +527,130 @@ where } /// Generate storage read proof. -pub fn prove_read( +pub fn prove_read( mut backend: B, - key: &[u8] -) -> Result<(Option>, Vec>), Box> + keys: I, +) -> Result>, Box> where B: Backend, H: Hasher, H::Out: Ord, + I: IntoIterator, + I::Item: AsRef<[u8]>, { let trie_backend = backend.as_trie_backend() .ok_or_else( || Box::new(ExecutionError::UnableToGenerateProof) as Box )?; - prove_read_on_trie_backend(trie_backend, key) + prove_read_on_trie_backend(trie_backend, keys) } /// Generate child storage read proof. -pub fn prove_child_read( +pub fn prove_child_read( mut backend: B, storage_key: &[u8], - key: &[u8], -) -> Result<(Option>, Vec>), Box> + keys: I, +) -> Result>, Box> where B: Backend, H: Hasher, H::Out: Ord, + I: IntoIterator, + I::Item: AsRef<[u8]>, { let trie_backend = backend.as_trie_backend() .ok_or_else(|| Box::new(ExecutionError::UnableToGenerateProof) as Box)?; - prove_child_read_on_trie_backend(trie_backend, storage_key, key) + prove_child_read_on_trie_backend(trie_backend, storage_key, keys) } /// Generate storage read proof on pre-created trie backend. -pub fn prove_read_on_trie_backend( +pub fn prove_read_on_trie_backend( trie_backend: &TrieBackend, - key: &[u8] -) -> Result<(Option>, Vec>), Box> + keys: I, +) -> Result>, Box> where S: trie_backend_essence::TrieBackendStorage, H: Hasher, H::Out: Ord, + I: IntoIterator, + I::Item: AsRef<[u8]>, { let proving_backend = proving_backend::ProvingBackend::<_, H>::new(trie_backend); - let result = proving_backend.storage(key).map_err(|e| Box::new(e) as Box)?; - Ok((result, proving_backend.extract_proof())) + for key in keys.into_iter() { + proving_backend + .storage(key.as_ref()) + .map_err(|e| Box::new(e) as Box)?; + } + Ok(proving_backend.extract_proof()) } /// Generate storage read proof on pre-created trie backend. -pub fn prove_child_read_on_trie_backend( +pub fn prove_child_read_on_trie_backend( trie_backend: &TrieBackend, storage_key: &[u8], - key: &[u8] -) -> Result<(Option>, Vec>), Box> + keys: I, +) -> Result>, Box> where S: trie_backend_essence::TrieBackendStorage, H: Hasher, H::Out: Ord, + I: IntoIterator, + I::Item: AsRef<[u8]>, { let proving_backend = proving_backend::ProvingBackend::<_, H>::new(trie_backend); - let result = proving_backend.child_storage(storage_key, key) - .map_err(|e| Box::new(e) as Box)?; - Ok((result, proving_backend.extract_proof())) + for key in keys.into_iter() { + proving_backend + .child_storage(storage_key, key.as_ref()) + .map_err(|e| Box::new(e) as Box)?; + } + Ok(proving_backend.extract_proof()) } /// Check storage read proof, generated by `prove_read` call. -pub fn read_proof_check( +pub fn read_proof_check( root: H::Out, proof: Vec>, - key: &[u8], -) -> Result>, Box> + keys: I, +) -> Result, Option>>, Box> where H: Hasher, H::Out: Ord, + I: IntoIterator, + I::Item: AsRef<[u8]>, { let proving_backend = create_proof_check_backend::(root, proof)?; - read_proof_check_on_proving_backend(&proving_backend, key) + let mut result = HashMap::new(); + for key in keys.into_iter() { + let value = read_proof_check_on_proving_backend(&proving_backend, key.as_ref())?; + result.insert(key.as_ref().to_vec(), value); + } + Ok(result) } /// Check child storage read proof, generated by `prove_child_read` call. -pub fn read_child_proof_check( +pub fn read_child_proof_check( root: H::Out, proof: Vec>, storage_key: &[u8], - key: &[u8], -) -> Result>, Box> + keys: I, +) -> Result, Option>>, Box> where H: Hasher, H::Out: Ord, + I: IntoIterator, + I::Item: AsRef<[u8]>, { let proving_backend = create_proof_check_backend::(root, proof)?; - read_child_proof_check_on_proving_backend(&proving_backend, storage_key, key) + let mut result = HashMap::new(); + for key in keys.into_iter() { + let value = read_child_proof_check_on_proving_backend( + &proving_backend, + storage_key, + key.as_ref(), + )?; + result.insert(key.as_ref().to_vec(), value); + } + Ok(result) } /// Check storage read proof on pre-created proving backend. @@ -963,20 +999,23 @@ mod tests { // fetch read proof from 'remote' full node let remote_backend = trie_backend::tests::test_trie(); let remote_root = remote_backend.storage_root(::std::iter::empty()).0; - let remote_proof = prove_read(remote_backend, b"value2").unwrap().1; + let remote_proof = prove_read(remote_backend, &[b"value2"]).unwrap(); // check proof locally - let local_result1 = read_proof_check::( + let local_result1 = read_proof_check::( remote_root, remote_proof.clone(), - b"value2" + &[b"value2"], ).unwrap(); - let local_result2 = read_proof_check::( + let local_result2 = read_proof_check::( remote_root, remote_proof.clone(), - &[0xff] + &[&[0xff]], ).is_ok(); // check that results are correct - assert_eq!(local_result1, Some(vec![24])); + assert_eq!( + local_result1.into_iter().collect::>(), + vec![(b"value2".to_vec(), Some(vec![24]))], + ); assert_eq!(local_result2, false); // on child trie let remote_backend = trie_backend::tests::test_trie(); @@ -984,21 +1023,28 @@ mod tests { let remote_proof = prove_child_read( remote_backend, b":child_storage:default:sub1", - b"value3" - ).unwrap().1; - let local_result1 = read_child_proof_check::( + &[b"value3"], + ).unwrap(); + let local_result1 = read_child_proof_check::( remote_root, remote_proof.clone(), - b":child_storage:default:sub1",b"value3" + b":child_storage:default:sub1", + &[b"value3"], ).unwrap(); - let local_result2 = read_child_proof_check::( + let local_result2 = read_child_proof_check::( remote_root, remote_proof.clone(), b":child_storage:default:sub1", - b"value2" + &[b"value2"], ).unwrap(); - assert_eq!(local_result1, Some(vec![142])); - assert_eq!(local_result2, None); + assert_eq!( + local_result1.into_iter().collect::>(), + vec![(b"value3".to_vec(), Some(vec![142]))], + ); + assert_eq!( + local_result2.into_iter().collect::>(), + vec![(b"value2".to_vec(), None)], + ); } #[test] diff --git a/core/test-client/src/lib.rs b/core/test-client/src/lib.rs index 3ae999f1f1..3ce5bec4fb 100644 --- a/core/test-client/src/lib.rs +++ b/core/test-client/src/lib.rs @@ -36,12 +36,9 @@ pub use state_machine::ExecutionStrategy; use std::sync::Arc; use std::collections::HashMap; -use futures::future::Ready; use hash_db::Hasher; use primitives::storage::well_known_keys; -use sr_primitives::traits::{ - Block as BlockT, NumberFor -}; +use sr_primitives::traits::Block as BlockT; use client::LocalCallExecutor; /// Test client light database backend. @@ -50,9 +47,6 @@ pub type LightBackend = client::light::backend::Backend< Blake2Hasher, >; -/// Test client light fetcher. -pub struct LightFetcher; - /// A genesis storage initialisation trait. pub trait GenesisInit: Default { /// Construct genesis storage. @@ -231,53 +225,3 @@ impl TestClientBuilder< self.build_with_executor(executor) } } - -impl client::light::fetcher::Fetcher for LightFetcher { - type RemoteHeaderResult = Ready>; - type RemoteReadResult = Ready>, client::error::Error>>; - type RemoteCallResult = Ready, client::error::Error>>; - type RemoteChangesResult = Ready, u32)>, client::error::Error>>; - type RemoteBodyResult = Ready, client::error::Error>>; - - fn remote_header( - &self, - _request: client::light::fetcher::RemoteHeaderRequest, - ) -> Self::RemoteHeaderResult { - unimplemented!("not (yet) used in tests") - } - - fn remote_read( - &self, - _request: client::light::fetcher::RemoteReadRequest, - ) -> Self::RemoteReadResult { - unimplemented!("not (yet) used in tests") - } - - fn remote_read_child( - &self, - _request: client::light::fetcher::RemoteReadChildRequest, - ) -> Self::RemoteReadResult { - unimplemented!("not (yet) used in tests") - } - - fn remote_call( - &self, - _request: client::light::fetcher::RemoteCallRequest, - ) -> Self::RemoteCallResult { - unimplemented!("not (yet) used in tests") - } - - fn remote_changes( - &self, - _request: client::light::fetcher::RemoteChangesRequest, - ) -> Self::RemoteChangesResult { - unimplemented!("not (yet) used in tests") - } - - fn remote_body( - &self, - _request: client::light::fetcher::RemoteBodyRequest, - ) -> Self::RemoteBodyResult { - unimplemented!("not (yet) used in tests") - } -} -- GitLab From 3781a7c21ef275afc64d28aff8fefc847a559e88 Mon Sep 17 00:00:00 2001 From: Weiliang Li Date: Tue, 17 Sep 2019 18:16:22 +0900 Subject: [PATCH 097/275] Update mod.rs (#3625) Add `import_notification_stream` for test client --- core/network/src/test/mod.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/network/src/test/mod.rs b/core/network/src/test/mod.rs index f6c866d76d..b6a6103071 100644 --- a/core/network/src/test/mod.rs +++ b/core/network/src/test/mod.rs @@ -28,7 +28,7 @@ use crate::config::build_multiaddr; use log::trace; use crate::chain::FinalityProofProvider; use client::{ - self, ClientInfo, BlockchainEvents, BlockImportNotification, FinalityNotifications, + self, ClientInfo, BlockchainEvents, BlockImportNotification, FinalityNotifications, ImportNotifications, FinalityNotification, LongestChain }; use client::error::Result as ClientResult; @@ -189,6 +189,13 @@ impl PeersClient { } } + pub fn import_notification_stream(&self) -> ImportNotifications{ + match *self { + PeersClient::Full(ref client, ref _backend) => client.import_notification_stream(), + PeersClient::Light(ref client, ref _backend) => client.import_notification_stream(), + } + } + pub fn finalize_block( &self, id: BlockId, -- GitLab From a06c020d102ef8ce55615ebe4edc00c74819178e Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Tue, 17 Sep 2019 11:19:46 +0200 Subject: [PATCH 098/275] Send block status with announcement (#3607) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Send block status with announcement * Fixed tests * Whitespace Co-Authored-By: Gavin Wood * Additional comment * Update comment Co-Authored-By: André Silva --- core/network/src/protocol.rs | 56 ++++++++++++++++++---------- core/network/src/protocol/message.rs | 39 ++++++++++++++++++- core/network/src/protocol/sync.rs | 10 +++-- core/network/src/service.rs | 4 +- core/network/src/test/mod.rs | 4 +- core/service/src/lib.rs | 2 +- 6 files changed, 85 insertions(+), 30 deletions(-) diff --git a/core/network/src/protocol.rs b/core/network/src/protocol.rs index 6dab5a2a54..ea993bdce0 100644 --- a/core/network/src/protocol.rs +++ b/core/network/src/protocol.rs @@ -64,9 +64,9 @@ const TICK_TIMEOUT: time::Duration = time::Duration::from_millis(1100); const PROPAGATE_TIMEOUT: time::Duration = time::Duration::from_millis(2900); /// Current protocol version. -pub(crate) const CURRENT_VERSION: u32 = 3; +pub(crate) const CURRENT_VERSION: u32 = 4; /// Lowest version we support -pub(crate) const MIN_VERSION: u32 = 2; +pub(crate) const MIN_VERSION: u32 = 3; // Maximum allowed entries in `BlockResponse` const MAX_BLOCK_DATA_RESPONSE: u32 = 128; @@ -1028,14 +1028,33 @@ impl, H: ExHashT> Protocol { return; } - let hash = header.hash(); + let is_best = self.context_data.chain.info().chain.best_hash == hash; + debug!(target: "sync", "Reannouncing block {:?}", hash); + self.send_announcement(&header, is_best, true) + } - let message = GenericMessage::BlockAnnounce(message::BlockAnnounce { header: header.clone() }); + fn send_announcement(&mut self, header: &B::Header, is_best: bool, force: bool) { + let hash = header.hash(); for (who, ref mut peer) in self.context_data.peers.iter_mut() { - trace!(target: "sync", "Reannouncing block {:?} to {}", hash, who); - peer.known_blocks.insert(hash); - self.behaviour.send_packet(who, message.clone()) + trace!(target: "sync", "Announcing block {:?} to {}", hash, who); + let inserted = peer.known_blocks.insert(hash); + if inserted || force { + let message = GenericMessage::BlockAnnounce(message::BlockAnnounce { + header: header.clone(), + state: if peer.info.protocol_version >= 4 { + if is_best { + Some(message::BlockState::Best) + } else { + Some(message::BlockState::Normal) + } + } else { + None + } + }); + + self.behaviour.send_packet(who, message) + } } } @@ -1072,7 +1091,12 @@ impl, H: ExHashT> Protocol { peerset: self.peerset_handle.clone(), }, who.clone(), *header.number()); - match self.sync.on_block_announce(who.clone(), hash, &header) { + let is_their_best = match announce.state.unwrap_or(message::BlockState::Best) { + message::BlockState::Best => true, + message::BlockState::Normal => false, + }; + + match self.sync.on_block_announce(who.clone(), hash, &header, is_their_best) { sync::OnBlockAnnounce::Request(peer, req) => { self.send_message(peer, GenericMessage::BlockRequest(req)); return CustomMessageOutcome::None @@ -1132,8 +1156,10 @@ impl, H: ExHashT> Protocol { /// Call this when a block has been imported in the import queue and we should announce it on /// the network. - pub fn on_block_imported(&mut self, hash: B::Hash, header: &B::Header) { - self.sync.update_chain_info(header); + pub fn on_block_imported(&mut self, hash: B::Hash, header: &B::Header, is_best: bool) { + if is_best { + self.sync.update_chain_info(header); + } self.specialization.on_block_imported( &mut ProtocolContext::new(&mut self.context_data, &mut self.behaviour, &self.peerset_handle), hash.clone(), @@ -1146,15 +1172,7 @@ impl, H: ExHashT> Protocol { } // send out block announcements - - let message = GenericMessage::BlockAnnounce(message::BlockAnnounce { header: header.clone() }); - - for (who, ref mut peer) in self.context_data.peers.iter_mut() { - if peer.known_blocks.insert(hash.clone()) { - trace!(target: "sync", "Announcing block {:?} to {}", hash, who); - self.behaviour.send_packet(who, message.clone()) - } - } + self.send_announcement(&header, is_best, false); } /// Call this when a block has been finalized. The sync layer may have some additional diff --git a/core/network/src/protocol/message.rs b/core/network/src/protocol/message.rs index cb02845735..2faa68a4e2 100644 --- a/core/network/src/protocol/message.rs +++ b/core/network/src/protocol/message.rs @@ -107,6 +107,15 @@ pub enum Direction { Descending = 1, } +/// Block state in the chain. +#[derive(Debug, PartialEq, Eq, Clone, Copy, Encode, Decode)] +pub enum BlockState { + /// Block is not part of the best chain. + Normal, + /// Latest best block. + Best, +} + /// Remote call response. #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] pub struct RemoteCallResponse { @@ -127,12 +136,13 @@ pub struct RemoteReadResponse { /// Generic types. pub mod generic { - use codec::{Encode, Decode}; + use codec::{Encode, Decode, Input, Output}; use sr_primitives::Justification; use crate::config::Roles; use super::{ RemoteReadResponse, Transactions, Direction, RequestId, BlockAttributes, RemoteCallResponse, ConsensusEngineId, + BlockState, }; /// Consensus is mostly opaque to us #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] @@ -257,10 +267,35 @@ pub mod generic { } /// Announce a new complete relay chain block on the network. - #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] + #[derive(Debug, PartialEq, Eq, Clone)] pub struct BlockAnnounce { /// New block header. pub header: H, + /// Block state. TODO: Remove `Option` and custom encoding when v4 becomes common. + pub state: Option, + } + + // Custom Encode/Decode impl to maintain backwards compatibility with v3. + // This assumes that the packet contains nothing but the announcement message. + // TODO: Get rid of it once protocol v4 is common. + impl Encode for BlockAnnounce { + fn encode_to(&self, dest: &mut T) { + self.header.encode_to(dest); + if let Some(state) = &self.state { + state.encode_to(dest); + } + } + } + + impl Decode for BlockAnnounce { + fn decode(input: &mut I) -> Result { + let header = H::decode(input)?; + let state = BlockState::decode(input).ok(); + Ok(BlockAnnounce { + header, + state, + }) + } } #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] diff --git a/core/network/src/protocol/sync.rs b/core/network/src/protocol/sync.rs index 5963ebf0f2..52e88034a3 100644 --- a/core/network/src/protocol/sync.rs +++ b/core/network/src/protocol/sync.rs @@ -885,7 +885,9 @@ impl ChainSync { /// header (call `on_block_data`). The network request isn't sent /// in this case. Both hash and header is passed as an optimization /// to avoid rehashing the header. - pub fn on_block_announce(&mut self, who: PeerId, hash: B::Hash, header: &B::Header) -> OnBlockAnnounce { + pub fn on_block_announce(&mut self, who: PeerId, hash: B::Hash, header: &B::Header, is_best: bool) + -> OnBlockAnnounce + { let number = *header.number(); debug!(target: "sync", "Received block announcement with number {:?}", number); if number.is_zero() { @@ -907,7 +909,7 @@ impl ChainSync { peer.recently_announced.pop_front(); } peer.recently_announced.push_back(hash.clone()); - if number > peer.best_number { + if is_best && number > peer.best_number { // update their best block peer.best_number = number; peer.best_hash = hash; @@ -915,9 +917,9 @@ impl ChainSync { if let PeerSyncState::AncestorSearch(_, _) = peer.state { return OnBlockAnnounce::Nothing } - // We assume that the announced block is the latest they have seen, and so our common number + // If the announced block is the best they have seen, our common number // is either one further ahead or it's the one they just announced, if we know about it. - if known { + if known && is_best { peer.common_number = number } else if header.parent_hash() == &self.best_queued_hash || known_parent { peer.common_number = number - One::one(); diff --git a/core/network/src/service.rs b/core/network/src/service.rs index ac6bd1ac05..a1cba0395e 100644 --- a/core/network/src/service.rs +++ b/core/network/src/service.rs @@ -297,8 +297,8 @@ impl, H: ExHashT> NetworkWorker } /// You must call this when a new block is imported by the client. - pub fn on_block_imported(&mut self, hash: B::Hash, header: B::Header) { - self.network_service.user_protocol_mut().on_block_imported(hash, &header); + pub fn on_block_imported(&mut self, hash: B::Hash, header: B::Header, is_best: bool) { + self.network_service.user_protocol_mut().on_block_imported(hash, &header, is_best); } /// You must call this when a new block is finalized by the client. diff --git a/core/network/src/test/mod.rs b/core/network/src/test/mod.rs index b6a6103071..5fd67acd1b 100644 --- a/core/network/src/test/mod.rs +++ b/core/network/src/test/mod.rs @@ -300,7 +300,7 @@ impl> Peer { Default::default() }; self.block_import.import_block(import_block, cache).expect("block_import failed"); - self.network.on_block_imported(hash, header); + self.network.on_block_imported(hash, header, true); at = hash; } @@ -662,7 +662,7 @@ pub trait TestNetFactory: Sized { // We poll `imported_blocks_stream`. while let Ok(Async::Ready(Some(notification))) = peer.imported_blocks_stream.poll() { - peer.network.on_block_imported(notification.hash, notification.header); + peer.network.on_block_imported(notification.hash, notification.header, true); } // We poll `finality_notification_stream`, but we only take the last event. diff --git a/core/service/src/lib.rs b/core/service/src/lib.rs index a8900eedd9..431776b31e 100644 --- a/core/service/src/lib.rs +++ b/core/service/src/lib.rs @@ -682,7 +682,7 @@ fn build_network_future< // We poll `imported_blocks_stream`. while let Ok(Async::Ready(Some(notification))) = imported_blocks_stream.poll() { - network.on_block_imported(notification.hash, notification.header); + network.on_block_imported(notification.hash, notification.header, notification.is_new_best); } // We poll `finality_notification_stream`, but we only take the last event. -- GitLab From 0b60638e2909d50dbc417da00163dda7abcfce30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 17 Sep 2019 11:28:32 +0200 Subject: [PATCH 099/275] Enable nice wasm panic messages by default (#3619) By accident it was already enabled in master for quite some time. To make sure that we don't blow up the wasm binary size, I compiled the binary with the feature enabled and disabled. With nice panic messages enabled, the binary size increases by 908 bytes. Given the value that this feature brings, I think it is okay to have these panic messages enabled by default. --- core/sr-io/Cargo.toml | 1 - core/sr-io/without_std.rs | 15 ++------------- srml/aura/Cargo.toml | 2 +- srml/babe/Cargo.toml | 2 +- 4 files changed, 4 insertions(+), 16 deletions(-) diff --git a/core/sr-io/Cargo.toml b/core/sr-io/Cargo.toml index f3122f0e30..7382cfb002 100644 --- a/core/sr-io/Cargo.toml +++ b/core/sr-io/Cargo.toml @@ -37,6 +37,5 @@ std = [ ] nightly = [] strict = [] -wasm-nice-panic-message = [] no_panic_handler = [] no_oom = [] diff --git a/core/sr-io/without_std.rs b/core/sr-io/without_std.rs index 6803b41ebd..0ff1702f90 100644 --- a/core/sr-io/without_std.rs +++ b/core/sr-io/without_std.rs @@ -28,19 +28,8 @@ use codec::Decode; #[no_mangle] pub fn panic(info: &PanicInfo) -> ! { unsafe { - #[cfg(feature = "wasm-nice-panic-message")] - { - let message = rstd::alloc::format!("{}", info); - extern_functions_host_impl::ext_print_utf8(message.as_ptr() as *const u8, message.len() as u32); - } - #[cfg(not(feature = "wasm-nice-panic-message"))] - { - if let Some(loc) = info.location() { - extern_functions_host_impl::ext_print_utf8(loc.file().as_ptr() as *const u8, loc.file().len() as u32); - extern_functions_host_impl::ext_print_num(loc.line() as u64); - extern_functions_host_impl::ext_print_num(loc.column() as u64); - } - } + let message = rstd::alloc::format!("{}", info); + extern_functions_host_impl::ext_print_utf8(message.as_ptr() as *const u8, message.len() as u32); intrinsics::abort() } } diff --git a/srml/aura/Cargo.toml b/srml/aura/Cargo.toml index 961c178c34..d7d6f8c9cf 100644 --- a/srml/aura/Cargo.toml +++ b/srml/aura/Cargo.toml @@ -13,7 +13,7 @@ rstd = { package = "sr-std", path = "../../core/sr-std", default-features = fals serde = { version = "1.0", optional = true } session = { package = "srml-session", path = "../session", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false, features = [ "wasm-nice-panic-message" ] } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } substrate-consensus-aura-primitives = { path = "../../core/consensus/aura/primitives", default-features = false} system = { package = "srml-system", path = "../system", default-features = false } diff --git a/srml/babe/Cargo.toml b/srml/babe/Cargo.toml index 35828fdb1c..3819bb14c7 100644 --- a/srml/babe/Cargo.toml +++ b/srml/babe/Cargo.toml @@ -17,7 +17,7 @@ system = { package = "srml-system", path = "../system", default-features = false timestamp = { package = "srml-timestamp", path = "../timestamp", default-features = false } session = { package = "srml-session", path = "../session", default-features = false } babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../core/consensus/babe/primitives", default-features = false } -runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false, features = [ "wasm-nice-panic-message" ] } +runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } [dev-dependencies] lazy_static = "1.3.0" -- GitLab From da319b2621f221ba35de2af94dc50b9dab6b1968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 17 Sep 2019 13:06:36 +0200 Subject: [PATCH 100/275] Fix missing `contracts` RPC on a full node. (#3622) * Add contracts RPC to full node. * Instantiate both RPC extensions for light & full. --- node/cli/src/service.rs | 28 ++++++---------------------- node/rpc/src/lib.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index f3ce9baa2e..b1d1348069 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -44,6 +44,7 @@ construct_simple_protocol! { /// be able to perform chain operations. macro_rules! new_full_start { ($config:expr) => {{ + type RpcExtension = jsonrpc_core::IoHandler; let mut import_setup = None; let inherent_data_providers = inherents::InherentDataProviders::new(); let mut tasks_to_spawn = Vec::new(); @@ -82,14 +83,8 @@ macro_rules! new_full_start { Ok(import_queue) })? - .with_rpc_extensions(|client, pool| { - use node_rpc::accounts::{Accounts, AccountsApi}; - - let mut io = jsonrpc_core::IoHandler::::default(); - io.extend_with( - AccountsApi::to_delegate(Accounts::new(client, pool)) - ); - io + .with_rpc_extensions(|client, pool| -> RpcExtension { + node_rpc::create(client, pool) })?; (builder, import_setup, inherent_data_providers, tasks_to_spawn) @@ -227,6 +222,7 @@ pub fn new_light(config: Configuration Result { use futures::Future; + type RpcExtension = jsonrpc_core::IoHandler; let inherent_data_providers = InherentDataProviders::new(); let mut tasks_to_spawn = Vec::new(); @@ -268,20 +264,8 @@ pub fn new_light(config: Configuration RpcExtension { + node_rpc::create(client, pool) })? .build()?; diff --git a/node/rpc/src/lib.rs b/node/rpc/src/lib.rs index 0d23c40a34..43f723f796 100644 --- a/node/rpc/src/lib.rs +++ b/node/rpc/src/lib.rs @@ -29,6 +29,12 @@ #![warn(missing_docs)] +use std::sync::Arc; + +use node_primitives::{Block, AccountNonceApi, ContractsApi}; +use sr_primitives::traits::ProvideRuntimeApi; +use transaction_pool::txpool::{ChainApi, Pool}; + pub mod accounts; pub mod contracts; @@ -38,3 +44,27 @@ mod constants { /// This typically means that the runtime trapped. pub const RUNTIME_ERROR: i64 = 1; } + +/// Instantiate all RPC extensions. +pub fn create(client: Arc, pool: Arc>) -> jsonrpc_core::IoHandler where + C: ProvideRuntimeApi, + C: client::blockchain::HeaderBackend, + C: Send + Sync + 'static, + C::Api: AccountNonceApi + ContractsApi, + P: ChainApi + Sync + Send + 'static, + M: jsonrpc_core::Metadata + Default, +{ + use self::{ + accounts::{Accounts, AccountsApi}, + contracts::{Contracts, ContractsApi}, + }; + + let mut io = jsonrpc_core::IoHandler::default(); + io.extend_with( + AccountsApi::to_delegate(Accounts::new(client.clone(), pool)) + ); + io.extend_with( + ContractsApi::to_delegate(Contracts::new(client)) + ); + io +} -- GitLab From 204e10f4805bd6b373ef0e5337697ec24d597f97 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 17 Sep 2019 13:32:52 +0200 Subject: [PATCH 101/275] Suggest `--release` compilation (#3627) --- core/consensus/slots/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/consensus/slots/src/lib.rs b/core/consensus/slots/src/lib.rs index fd5163a374..8e80a656e1 100644 --- a/core/consensus/slots/src/lib.rs +++ b/core/consensus/slots/src/lib.rs @@ -208,6 +208,9 @@ pub trait SimpleSlotWorker { let slot_after_building = SignedDuration::default().slot_now(slot_duration); if slot_after_building != slot_number { info!("Discarding proposal for slot {}; block production took too long", slot_number); + // If the node was compiled with debug, tell the user to use release optimizations. + #[cfg(debug_assertions)] + info!("Recompile your node in `--release` mode to mitigate this problem."); telemetry!(CONSENSUS_INFO; "slots.discarding_proposal_took_too_long"; "slot" => slot_number, ); -- GitLab From 80a80953311aad10719a471c5ccebdf5406a2e37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 17 Sep 2019 14:39:40 +0200 Subject: [PATCH 102/275] Properly detect debug build in slots (#3630) `debug-assertions` can also be enabled in for release builds. This introduces a new build-script that extracts the build type from the `PROFILE` env variable and sets the `build_type` cfg. --- core/consensus/slots/Cargo.toml | 1 + core/consensus/slots/build.rs | 23 +++++++++++++++++++++++ core/consensus/slots/src/lib.rs | 4 ++-- 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 core/consensus/slots/build.rs diff --git a/core/consensus/slots/Cargo.toml b/core/consensus/slots/Cargo.toml index 4203da9d7d..71d9a2cb5b 100644 --- a/core/consensus/slots/Cargo.toml +++ b/core/consensus/slots/Cargo.toml @@ -4,6 +4,7 @@ version = "2.0.0" authors = ["Parity Technologies "] description = "Generic slots-based utilities for consensus" edition = "2018" +build = "build.rs" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0" } diff --git a/core/consensus/slots/build.rs b/core/consensus/slots/build.rs new file mode 100644 index 0000000000..36730271c7 --- /dev/null +++ b/core/consensus/slots/build.rs @@ -0,0 +1,23 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use std::env; + +fn main() { + if let Ok(profile) = env::var("PROFILE") { + println!("cargo:rustc-cfg=build_type=\"{}\"", profile); + } +} diff --git a/core/consensus/slots/src/lib.rs b/core/consensus/slots/src/lib.rs index 8e80a656e1..fadb311f7d 100644 --- a/core/consensus/slots/src/lib.rs +++ b/core/consensus/slots/src/lib.rs @@ -209,7 +209,7 @@ pub trait SimpleSlotWorker { if slot_after_building != slot_number { info!("Discarding proposal for slot {}; block production took too long", slot_number); // If the node was compiled with debug, tell the user to use release optimizations. - #[cfg(debug_assertions)] + #[cfg(build_type="debug")] info!("Recompile your node in `--release` mode to mitigate this problem."); telemetry!(CONSENSUS_INFO; "slots.discarding_proposal_took_too_long"; "slot" => slot_number, @@ -397,7 +397,7 @@ impl SlotDuration { Some(v) => ::decode(&mut &v[..]) .map(SlotDuration) .map_err(|_| { - ::client::error::Error::Backend({ + client::error::Error::Backend({ error!(target: "slots", "slot duration kept in invalid format"); format!("slot duration kept in invalid format") }) -- GitLab From 188480de4727f11bae126d706fc188b1435082dd Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Tue, 17 Sep 2019 20:42:15 +0200 Subject: [PATCH 103/275] Storage tracing (#3614) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Storage tracing * Whitepsaces Co-Authored-By: Sergei Pepyakin * Apply suggestions from code review Co-Authored-By: Bastian Köcher * Update Cargo.lock --- Cargo.lock | 25 ++-- core/client/db/src/lib.rs | 6 + core/client/db/src/storage_cache.rs | 6 + core/client/src/light/backend.rs | 9 ++ core/primitives/src/hexdisplay.rs | 21 ++- core/primitives/src/lib.rs | 2 +- core/state-machine/Cargo.toml | 1 + core/state-machine/src/backend.rs | 8 +- core/state-machine/src/ext.rs | 159 +++++++++++++++++++--- core/state-machine/src/lib.rs | 15 +- core/state-machine/src/proving_backend.rs | 6 + core/state-machine/src/trie_backend.rs | 6 + 12 files changed, 223 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 68a2e1bf41..4ae6d38280 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -473,7 +473,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-hack 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3188,13 +3188,13 @@ dependencies = [ [[package]] name = "rand" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3213,7 +3213,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3231,7 +3231,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rand_core" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3250,7 +3250,7 @@ name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3840,7 +3840,7 @@ dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "primitive-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -5054,7 +5054,7 @@ dependencies = [ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", "substrate-client-db 2.0.0", @@ -5100,7 +5100,7 @@ dependencies = [ name = "substrate-phragmen" version = "2.0.0" dependencies = [ - "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -5333,6 +5333,7 @@ dependencies = [ "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-panic-handler 2.0.0", "substrate-primitives 2.0.0", "substrate-trie 2.0.0", @@ -5582,7 +5583,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6769,12 +6770,12 @@ dependencies = [ "checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" "checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c" +"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" "checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" -"checksum rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "615e683324e75af5d43d8f7a39ffe3ee4a9dc42c5c701167a71dc59c3a493aca" +"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" "checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" "checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" diff --git a/core/client/db/src/lib.rs b/core/client/db/src/lib.rs index 4acb178506..1a0b2331d3 100644 --- a/core/client/db/src/lib.rs +++ b/core/client/db/src/lib.rs @@ -110,6 +110,12 @@ impl Drop for RefTrackingState { } } +impl std::fmt::Debug for RefTrackingState { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Block {:?}", self.parent_hash) + } +} + impl StateBackend for RefTrackingState { type Error = >::Error; type Transaction = >::Transaction; diff --git a/core/client/db/src/storage_cache.rs b/core/client/db/src/storage_cache.rs index 09c0f71fdd..af8c9e379c 100644 --- a/core/client/db/src/storage_cache.rs +++ b/core/client/db/src/storage_cache.rs @@ -285,6 +285,12 @@ pub struct CachingState, B: BlockT> { pub cache: CacheChanges } +impl, B: BlockT> std::fmt::Debug for CachingState { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Block {:?}", self.cache.parent_hash) + } +} + impl CacheChanges { /// Propagate local cache into the shared cache and synchronize /// the shared cache with the best block state. diff --git a/core/client/src/light/backend.rs b/core/client/src/light/backend.rs index 336e4cba70..5f44c03e21 100644 --- a/core/client/src/light/backend.rs +++ b/core/client/src/light/backend.rs @@ -325,6 +325,15 @@ where } } +impl std::fmt::Debug for GenesisOrUnavailableState { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + GenesisOrUnavailableState::Genesis(ref state) => state.fmt(f), + GenesisOrUnavailableState::Unavailable => write!(f, "Unavailable"), + } + } +} + impl StateBackend for GenesisOrUnavailableState where H::Out: Ord, diff --git a/core/primitives/src/hexdisplay.rs b/core/primitives/src/hexdisplay.rs index cd2b6c18cb..87be587a7d 100644 --- a/core/primitives/src/hexdisplay.rs +++ b/core/primitives/src/hexdisplay.rs @@ -21,28 +21,37 @@ pub struct HexDisplay<'a>(&'a [u8]); impl<'a> HexDisplay<'a> { /// Create new instance that will display `d` as a hex string when displayed. - pub fn from(d: &'a dyn AsBytesRef) -> Self { HexDisplay(d.as_bytes_ref()) } + pub fn from(d: &'a R) -> Self { HexDisplay(d.as_bytes_ref()) } } impl<'a> ::core::fmt::Display for HexDisplay<'a> { - fn fmt(&self, fmtr: &mut ::core::fmt::Formatter) -> Result<(), ::core::fmt::Error> { + fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> { if self.0.len() < 1027 { for byte in self.0 { - fmtr.write_fmt(format_args!("{:02x}", byte))?; + f.write_fmt(format_args!("{:02x}", byte))?; } } else { for byte in &self.0[0..512] { - fmtr.write_fmt(format_args!("{:02x}", byte))?; + f.write_fmt(format_args!("{:02x}", byte))?; } - fmtr.write_str("...")?; + f.write_str("...")?; for byte in &self.0[self.0.len() - 512..] { - fmtr.write_fmt(format_args!("{:02x}", byte))?; + f.write_fmt(format_args!("{:02x}", byte))?; } } Ok(()) } } +impl<'a> core::fmt::Debug for HexDisplay<'a> { + fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> { + for byte in self.0 { + f.write_fmt(format_args!("{:02x}", byte))?; + } + Ok(()) + } +} + /// Simple trait to transform various types to `&[u8]` pub trait AsBytesRef { /// Transform `self` into `&[u8]`. diff --git a/core/primitives/src/lib.rs b/core/primitives/src/lib.rs index 144aa7b997..8086c9832a 100644 --- a/core/primitives/src/lib.rs +++ b/core/primitives/src/lib.rs @@ -159,7 +159,7 @@ pub enum NativeOrEncoded { #[cfg(feature = "std")] impl ::std::fmt::Debug for NativeOrEncoded { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - self.as_encoded().as_ref().fmt(f) + hexdisplay::HexDisplay::from(&self.as_encoded().as_ref()).fmt(f) } } diff --git a/core/state-machine/Cargo.toml b/core/state-machine/Cargo.toml index 94aff8b078..d9fb592bab 100644 --- a/core/state-machine/Cargo.toml +++ b/core/state-machine/Cargo.toml @@ -16,6 +16,7 @@ primitives = { package = "substrate-primitives", path = "../primitives" } panic-handler = { package = "substrate-panic-handler", path = "../panic-handler" } codec = { package = "parity-scale-codec", version = "1.0.0" } num-traits = "0.2" +rand = "0.7.1" [dev-dependencies] hex-literal = "0.2.0" diff --git a/core/state-machine/src/backend.rs b/core/state-machine/src/backend.rs index 86d415de1c..e2f398ef7c 100644 --- a/core/state-machine/src/backend.rs +++ b/core/state-machine/src/backend.rs @@ -30,7 +30,7 @@ use trie::{ /// to it. /// /// The clone operation (if implemented) should be cheap. -pub trait Backend { +pub trait Backend: std::fmt::Debug { /// An error type when fetching data is not possible. type Error: super::Error; @@ -254,6 +254,12 @@ pub struct InMemory { _hasher: PhantomData, } +impl std::fmt::Debug for InMemory { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "InMemory ({} values)", self.inner.len()) + } +} + impl Default for InMemory { fn default() -> Self { InMemory { diff --git a/core/state-machine/src/ext.rs b/core/state-machine/src/ext.rs index 6ce5b12085..c4a2bd7f63 100644 --- a/core/state-machine/src/ext.rs +++ b/core/state-machine/src/ext.rs @@ -17,7 +17,7 @@ //! Concrete externalities implementation. use std::{error, fmt, cmp::Ord}; -use log::warn; +use log::{warn, trace}; use crate::{ backend::Backend, OverlayedChanges, changes_trie::{ @@ -28,6 +28,7 @@ use hash_db::Hasher; use primitives::{ offchain, storage::well_known_keys::is_child_storage_key, traits::{BareCryptoStorePtr, Externalities}, child_storage_key::ChildStorageKey, + hexdisplay::HexDisplay, }; use trie::{MemoryDB, default_child_trie_root}; use trie::trie_types::Layout; @@ -91,6 +92,8 @@ where offchain_externalities: Option<&'a mut O>, /// The keystore that manages the keys of the node. keystore: Option, + /// Pseudo-unique id used for tracing. + pub id: u16, /// Dummy usage of N arg. _phantom: ::std::marker::PhantomData, } @@ -120,6 +123,7 @@ where changes_trie_transaction: None, offchain_externalities, keystore, + id: rand::random(), _phantom: Default::default(), } } @@ -183,66 +187,137 @@ where H: Hasher, { fn storage(&self, key: &[u8]) -> Option> { let _guard = panic_handler::AbortGuard::force_abort(); - self.overlay.storage(key).map(|x| x.map(|x| x.to_vec())).unwrap_or_else(|| - self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL)) + let result = self.overlay.storage(key).map(|x| x.map(|x| x.to_vec())).unwrap_or_else(|| + self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL)); + trace!(target: "state-trace", "{:04x}: Get {}={:?}", + self.id, + HexDisplay::from(&key), + result.as_ref().map(HexDisplay::from) + ); + result } fn storage_hash(&self, key: &[u8]) -> Option { let _guard = panic_handler::AbortGuard::force_abort(); - self.overlay.storage(key).map(|x| x.map(|x| H::hash(x))).unwrap_or_else(|| - self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL)) + let result = self.overlay.storage(key).map(|x| x.map(|x| H::hash(x))).unwrap_or_else(|| + self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL)); + trace!(target: "state-trace", "{:04x}: Hash {}={:?}", + self.id, + HexDisplay::from(&key), + result, + ); + result } fn original_storage(&self, key: &[u8]) -> Option> { let _guard = panic_handler::AbortGuard::force_abort(); - self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL) + let result = self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL); + trace!(target: "state-trace", "{:04x}: GetOriginal {}={:?}", + self.id, + HexDisplay::from(&key), + result.as_ref().map(HexDisplay::from) + ); + result } fn original_storage_hash(&self, key: &[u8]) -> Option { let _guard = panic_handler::AbortGuard::force_abort(); - self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL) + let result = self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL); + trace!(target: "state-trace", "{:04x}: GetOriginalHash {}={:?}", + self.id, + HexDisplay::from(&key), + result, + ); + result } fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { let _guard = panic_handler::AbortGuard::force_abort(); - self.overlay.child_storage(storage_key.as_ref(), key).map(|x| x.map(|x| x.to_vec())).unwrap_or_else(|| - self.backend.child_storage(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL)) + let result = self.overlay.child_storage(storage_key.as_ref(), key).map(|x| x.map(|x| x.to_vec())).unwrap_or_else(|| + self.backend.child_storage(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL)); + trace!(target: "state-trace", "{:04x}: GetChild({}) {}={:?}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&key), + result.as_ref().map(HexDisplay::from) + ); + result } fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { let _guard = panic_handler::AbortGuard::force_abort(); - self.overlay.child_storage(storage_key.as_ref(), key).map(|x| x.map(|x| H::hash(x))).unwrap_or_else(|| - self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL)) + let result = self.overlay.child_storage(storage_key.as_ref(), key).map(|x| x.map(|x| H::hash(x))).unwrap_or_else(|| + self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL)); + trace!(target: "state-trace", "{:04x}: ChildHash({}) {}={:?}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&key), + result, + ); + result } fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { let _guard = panic_handler::AbortGuard::force_abort(); - self.backend.child_storage(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL) + let result = self.backend.child_storage(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL); + trace!(target: "state-trace", "{:04x}: ChildOriginal({}) {}={:?}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&key), + result.as_ref().map(HexDisplay::from), + ); + result } fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { let _guard = panic_handler::AbortGuard::force_abort(); - self.backend.child_storage_hash(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL) + let result = self.backend.child_storage_hash(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL); + trace!(target: "state-trace", "{}: ChildHashOriginal({}) {}={:?}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&key), + result, + ); + result } fn exists_storage(&self, key: &[u8]) -> bool { let _guard = panic_handler::AbortGuard::force_abort(); - match self.overlay.storage(key) { + let result = match self.overlay.storage(key) { Some(x) => x.is_some(), _ => self.backend.exists_storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL), - } + }; + trace!(target: "state-trace", "{:04x}: Exists {}={:?}", + self.id, + HexDisplay::from(&key), + result, + ); + result + } fn exists_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> bool { let _guard = panic_handler::AbortGuard::force_abort(); - match self.overlay.child_storage(storage_key.as_ref(), key) { + let result = match self.overlay.child_storage(storage_key.as_ref(), key) { Some(x) => x.is_some(), _ => self.backend.exists_child_storage(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL), - } + }; + trace!(target: "state-trace", "{:04x}: ChildExists({}) {}={:?}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&key), + result, + ); + result } fn place_storage(&mut self, key: Vec, value: Option>) { + trace!(target: "state-trace", "{:04x}: Put {}={:?}", + self.id, + HexDisplay::from(&key), + value.as_ref().map(HexDisplay::from) + ); let _guard = panic_handler::AbortGuard::force_abort(); if is_child_storage_key(&key) { warn!(target: "trie", "Refuse to directly set child storage key"); @@ -254,6 +329,12 @@ where H: Hasher, } fn place_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Option>) { + trace!(target: "state-trace", "{:04x}: PutChild({}) {}={:?}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&key), + value.as_ref().map(HexDisplay::from) + ); let _guard = panic_handler::AbortGuard::force_abort(); self.mark_dirty(); @@ -261,6 +342,10 @@ where H: Hasher, } fn kill_child_storage(&mut self, storage_key: ChildStorageKey) { + trace!(target: "state-trace", "{:04x}: KillChild({})", + self.id, + HexDisplay::from(&storage_key.as_ref()), + ); let _guard = panic_handler::AbortGuard::force_abort(); self.mark_dirty(); @@ -271,6 +356,10 @@ where H: Hasher, } fn clear_prefix(&mut self, prefix: &[u8]) { + trace!(target: "state-trace", "{:04x}: ClearPrefix {}", + self.id, + HexDisplay::from(&prefix), + ); let _guard = panic_handler::AbortGuard::force_abort(); if is_child_storage_key(prefix) { warn!(target: "trie", "Refuse to directly clear prefix that is part of child storage key"); @@ -285,6 +374,11 @@ where H: Hasher, } fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]) { + trace!(target: "state-trace", "{:04x}: ClearChildPrefix({}) {}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&prefix), + ); let _guard = panic_handler::AbortGuard::force_abort(); self.mark_dirty(); @@ -301,6 +395,10 @@ where H: Hasher, fn storage_root(&mut self) -> H::Out { let _guard = panic_handler::AbortGuard::force_abort(); if let Some((_, ref root)) = self.storage_transaction { + trace!(target: "state-trace", "{:04x}: Root (cached) {}", + self.id, + HexDisplay::from(&root.as_ref()), + ); return root.clone(); } @@ -322,17 +420,27 @@ where H: Hasher, let (root, transaction) = self.backend.full_storage_root(delta, child_delta_iter); self.storage_transaction = Some((transaction, root)); + trace!(target: "state-trace", "{:04x}: Root {}", + self.id, + HexDisplay::from(&root.as_ref()), + ); root } fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { let _guard = panic_handler::AbortGuard::force_abort(); if self.storage_transaction.is_some() { - self + let root = self .storage(storage_key.as_ref()) .unwrap_or( default_child_trie_root::>(storage_key.as_ref()) - ) + ); + trace!(target: "state-trace", "{:04x}: ChildRoot({}) (cached) {}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&root.as_ref()), + ); + root } else { let storage_key = storage_key.as_ref(); @@ -347,6 +455,11 @@ where H: Hasher, self.overlay.set_storage(storage_key.to_vec(), Some(root.to_vec())); + trace!(target: "state-trace", "{:04x}: ChildRoot({}) {}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&root.as_ref()), + ); root } @@ -360,7 +473,13 @@ where H: Hasher, self.overlay, parent_hash, )?; - Ok(self.changes_trie_transaction.as_ref().map(|(_, root, _)| root.clone())) + let result = Ok(self.changes_trie_transaction.as_ref().map(|(_, root, _)| root.clone())); + trace!(target: "state-trace", "{:04x}: ChangesRoot({}) {:?}", + self.id, + HexDisplay::from(&parent_hash.as_ref()), + result, + ); + result } fn offchain(&mut self) -> Option<&mut dyn offchain::Externalities> { diff --git a/core/state-machine/src/lib.rs b/core/state-machine/src/lib.rs index 7b9dc6ac84..92dd813b89 100644 --- a/core/state-machine/src/lib.rs +++ b/core/state-machine/src/lib.rs @@ -22,12 +22,13 @@ use std::{ fmt, result, collections::HashMap, marker::PhantomData, panic::UnwindSafe, }; -use log::warn; +use log::{warn, trace}; use hash_db::Hasher; use codec::{Decode, Encode}; use primitives::{ storage::well_known_keys, NativeOrEncoded, NeverNativeValue, offchain::{self, NeverOffchainExt}, traits::{BareCryptoStorePtr, CodeExecutor}, + hexdisplay::HexDisplay, }; pub mod backend; @@ -258,6 +259,13 @@ impl<'a, B, H, N, T, O, Exec> StateMachine<'a, B, H, N, T, O, Exec> where self.offchain_ext.as_mut().map(|x| &mut **x), self.keystore.clone(), ); + let id = externalities.id; + trace!(target: "state-trace", "{:04x}: Call {} at {:?}. Input={:?}", + id, + self.method, + self.backend, + HexDisplay::from(&self.call_data), + ); let (result, was_native) = self.exec.call( &mut externalities, self.method, @@ -271,6 +279,11 @@ impl<'a, B, H, N, T, O, Exec> StateMachine<'a, B, H, N, T, O, Exec> where } else { (None, None) }; + trace!(target: "state-trace", "{:04x}: Return. Native={:?}, Result={:?}", + id, + was_native, + result, + ); (result, was_native, storage_delta, changes_delta) } diff --git a/core/state-machine/src/proving_backend.rs b/core/state-machine/src/proving_backend.rs index 64ec7de81b..3908f62eaa 100644 --- a/core/state-machine/src/proving_backend.rs +++ b/core/state-machine/src/proving_backend.rs @@ -139,6 +139,12 @@ impl<'a, S: 'a + TrieBackendStorage, H: 'a + Hasher> ProvingBackend<'a, S, H> } } +impl<'a, S: 'a + TrieBackendStorage, H: 'a + Hasher> std::fmt::Debug for ProvingBackend<'a, S, H> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "ProvingBackend") + } +} + impl<'a, S, H> Backend for ProvingBackend<'a, S, H> where S: 'a + TrieBackendStorage, diff --git a/core/state-machine/src/trie_backend.rs b/core/state-machine/src/trie_backend.rs index 105e20c9b7..ce5773c0b7 100644 --- a/core/state-machine/src/trie_backend.rs +++ b/core/state-machine/src/trie_backend.rs @@ -57,6 +57,12 @@ impl, H: Hasher> TrieBackend { } } +impl, H: Hasher> std::fmt::Debug for TrieBackend { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "TrieBackend") + } +} + impl, H: Hasher> Backend for TrieBackend where H::Out: Ord, { -- GitLab From 5c9a84a12ffd96b3002d282190e808efdd89c1f8 Mon Sep 17 00:00:00 2001 From: Ashley Date: Wed, 18 Sep 2019 22:27:59 +1200 Subject: [PATCH 104/275] Update parity-wasm to 0.40 (#3631) * updated direct dependencies to parity-wasm * fixed tests and incremented impl_version of the runtime * update wasmi to 0.5.1 in sr-sandbox, bringing all parity-wasm deps up to 0.40 --- Cargo.lock | 44 +++++++++++------------- core/executor/Cargo.toml | 2 +- core/executor/src/wasm_runtimes_cache.rs | 7 +++- core/sr-sandbox/Cargo.toml | 2 +- node/runtime/src/lib.rs | 2 +- srml/contracts/Cargo.toml | 6 ++-- srml/contracts/src/wasm/mod.rs | 10 ++---- 7 files changed, 35 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4ae6d38280..1e38076a7c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2795,11 +2795,8 @@ dependencies = [ [[package]] name = "parity-wasm" -version = "0.31.3" +version = "0.40.2" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "parking_lot" @@ -3090,12 +3087,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "pwasm-utils" -version = "0.6.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.40.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3859,7 +3856,7 @@ dependencies = [ "sr-std 2.0.0", "substrate-primitives 2.0.0", "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4020,8 +4017,8 @@ dependencies = [ "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", - "pwasm-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.40.2 (registry+https://github.com/rust-lang/crates.io-index)", + "pwasm-utils 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4033,7 +4030,7 @@ dependencies = [ "srml-timestamp 2.0.0", "substrate-primitives 2.0.0", "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi-validation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmi-validation 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4892,7 +4889,7 @@ dependencies = [ "libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.40.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-version 2.0.0", @@ -4907,7 +4904,7 @@ dependencies = [ "substrate-wasm-interface 2.0.0", "tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5139,7 +5136,7 @@ dependencies = [ "substrate-serializer 2.0.0", "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "twox-hash 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5501,7 +5498,7 @@ version = "1.0.3" name = "substrate-wasm-interface" version = "2.0.0" dependencies = [ - "wasmi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6249,24 +6246,23 @@ dependencies = [ [[package]] name = "wasmi" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi-validation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.40.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmi-validation 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasmi-validation" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.40.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6728,7 +6724,7 @@ dependencies = [ "checksum parity-scale-codec-derive 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a81f3cd93ed368a8e41c4e79538e99ca6e8f536096de23e3a0bc3e782093ce28" "checksum parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" "checksum parity-util-mem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2005637ccf93dbb60c85081ccaaf3f945f573da48dcc79f27f9646caa3ec1dc" -"checksum parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "511379a8194230c2395d2f5fa627a5a7e108a9f976656ce723ae68fca4097bfc" +"checksum parity-wasm 0.40.2 (registry+https://github.com/rust-lang/crates.io-index)" = "49d1e33551976be5345d2ecbfe995830719746c7f0902f0880a13d40e215f851" "checksum parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4d05f1349491390b1730afba60bb20d55761bef489a954546b58b4b34e1e2ac" "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" @@ -6760,7 +6756,7 @@ dependencies = [ "checksum prost-derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e7dc378b94ac374644181a2247cebf59a6ec1c88b49ac77f3a94b86b79d0e11" "checksum prost-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1de482a366941c8d56d19b650fac09ca08508f2a696119ee7513ad590c8bac6f" "checksum protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8aefcec9f142b524d98fc81d07827743be89dd6586a1ba6ab21fa66a500b3fa5" -"checksum pwasm-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "efb0dcbddbb600f47a7098d33762a00552c671992171637f5bb310b37fe1f0e4" +"checksum pwasm-utils 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d473123ba135028544926f7aa6f34058d8bc6f120c4fcd3777f84af724280b3" "checksum quick-error 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb6ccf8db7bbcb9c2eae558db5ab4f3da1c2a87e4e597ed394726bc8ea6ca1d" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quickcheck 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9c35d9c36a562f37eca96e79f66d5fd56eefbc22560dacc4a864cabd2d277456" @@ -6928,8 +6924,8 @@ dependencies = [ "checksum wasm-bindgen-shared 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "d9c2d4d4756b2e46d3a5422e06277d02e4d3e1d62d138b76a4c681e925743623" "checksum wasm-bindgen-webidl 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "24e47859b4eba3d3b9a5c2c299f9d6f8d0b613671315f6f0c5c7f835e524b36a" "checksum wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3d6101df9a5987df809216bdda7289f52b58128e6b6a6546e9ee3e6b632b4921" -"checksum wasmi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48437c526d40a6a593c50c5367dac825b8d6a04411013e866eca66123fb56faa" -"checksum wasmi-validation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab380192444b3e8522ae79c0a1976e42a82920916ccdfbce3def89f456ea33f3" +"checksum wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f31d26deb2d9a37e6cfed420edce3ed604eab49735ba89035e13c98f9a528313" +"checksum wasmi-validation 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6bc0356e3df56e639fc7f7d8a99741915531e27ed735d911ed83d7e1339c8188" "checksum web-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)" = "86d515d2f713d3a6ab198031d2181b7540f8e319e4637ec2d4a41a208335ef29" "checksum webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4f7e1cd7900a3a6b65a3e8780c51a3e6b59c0e2c55c6dc69578c288d69f7d082" "checksum webpki-roots 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c10fa4212003ba19a564f25cd8ab572c6791f99a03cc219c13ed35ccab00de0e" diff --git a/core/executor/Cargo.toml b/core/executor/Cargo.toml index 3d8f047322..77f07faa33 100644 --- a/core/executor/Cargo.toml +++ b/core/executor/Cargo.toml @@ -15,7 +15,7 @@ runtime_version = { package = "sr-version", path = "../sr-version" } panic-handler = { package = "substrate-panic-handler", path = "../panic-handler" } wasm-interface = { package = "substrate-wasm-interface", path = "../wasm-interface" } wasmi = "0.5.0" -parity-wasm = "0.31" +parity-wasm = "0.40.1" lazy_static = "1.3" parking_lot = "0.9.0" log = "0.4" diff --git a/core/executor/src/wasm_runtimes_cache.rs b/core/executor/src/wasm_runtimes_cache.rs index fb207dc18b..a615660777 100644 --- a/core/executor/src/wasm_runtimes_cache.rs +++ b/core/executor/src/wasm_runtimes_cache.rs @@ -99,7 +99,12 @@ impl StateSnapshot { // anyway. let contents = mem::replace(segment.value_mut(), vec![]); - let init_expr = segment.offset().code(); + let init_expr = match segment.offset() { + Some(offset) => offset.code(), + // Return if the segment is passive + None => return None + }; + // [op, End] if init_expr.len() != 2 { return None; diff --git a/core/sr-sandbox/Cargo.toml b/core/sr-sandbox/Cargo.toml index da80b2f213..2185ab4adc 100755 --- a/core/sr-sandbox/Cargo.toml +++ b/core/sr-sandbox/Cargo.toml @@ -9,7 +9,7 @@ edition = "2018" rustc_version = "0.2" [dependencies] -wasmi = { version = "0.5.0", optional = true } +wasmi = { version = "0.5.1", optional = true } primitives = { package = "substrate-primitives", path = "../primitives", default-features = false } rstd = { package = "sr-std", path = "../sr-std", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index a5eb080f5d..94497de0ac 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 158, - impl_version: 159, + impl_version: 160, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/contracts/Cargo.toml b/srml/contracts/Cargo.toml index 13aa8d32de..1fc05772fb 100644 --- a/srml/contracts/Cargo.toml +++ b/srml/contracts/Cargo.toml @@ -6,10 +6,10 @@ edition = "2018" [dependencies] serde = { version = "1.0", optional = true, features = ["derive"] } -pwasm-utils = { version = "0.6.1", default-features = false } +pwasm-utils = { version = "0.11.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -parity-wasm = { version = "0.31", default-features = false } -wasmi-validation = { version = "0.1", default-features = false } +parity-wasm = { version = "0.40", default-features = false } +wasmi-validation = { version = "0.2", default-features = false } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } diff --git a/srml/contracts/src/wasm/mod.rs b/srml/contracts/src/wasm/mod.rs index c623313824..9d48738ed1 100644 --- a/srml/contracts/src/wasm/mod.rs +++ b/srml/contracts/src/wasm/mod.rs @@ -471,7 +471,7 @@ mod tests { to: 9, value: 6, data: vec![1, 2, 3, 4], - gas_left: 49970, + gas_left: 49971, }] ); } @@ -533,7 +533,7 @@ mod tests { code_hash: [0x11; 32].into(), endowment: 3, data: vec![1, 2, 3, 4], - gas_left: 49946, + gas_left: 49947, }] ); } @@ -1359,11 +1359,7 @@ mod tests { vec![0x00, 0x01, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe5, 0x14, 0x00]) ]); - assert_eq!(gas_meter.gas_left(), 50_000 - - 6 // Explicit - - 13 - 1 - 1 // Deposit event - - (13 + 33) // read memory - ); + assert_eq!(gas_meter.gas_left(), 49934); } const CODE_DEPOSIT_EVENT_MAX_TOPICS: &str = r#" -- GitLab From 320fdb2053ca6cbe780f3c94ce9d6c4c9b351265 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Wed, 18 Sep 2019 13:24:08 +0200 Subject: [PATCH 105/275] From for u64 (#3638) * Add from impl for uint authority * Undo change to cargo. --- core/sr-primitives/src/testing.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/sr-primitives/src/testing.rs b/core/sr-primitives/src/testing.rs index 2284921cb3..198870f8c4 100644 --- a/core/sr-primitives/src/testing.rs +++ b/core/sr-primitives/src/testing.rs @@ -39,6 +39,12 @@ impl From for UintAuthorityId { } } +impl From for u64 { + fn from(id: UintAuthorityId) -> u64 { + id.0 + } +} + impl UintAuthorityId { /// Convert this authority id into a public key. pub fn to_public_key(&self) -> T { -- GitLab From e8d8b0bcb8f497ab9c15e91cde56ed94cade815a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 18 Sep 2019 13:52:18 +0200 Subject: [PATCH 106/275] Make `wasm-builder` check for `rust-lld` (#3635) * Make `wasm-builder` check for `rust-lld` * Update README.adoc Co-Authored-By: Ricardo Rius <9488369+riusricardo@users.noreply.github.com> --- README.adoc | 5 ++++ core/utils/wasm-builder/src/prerequisites.rs | 29 ++++++++++++-------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/README.adoc b/README.adoc index f700a554ce..39b0912b7d 100644 --- a/README.adoc +++ b/README.adoc @@ -193,6 +193,11 @@ You will also need to install the following packages: [source, shell] sudo apt install cmake pkg-config libssl-dev git clang libclang-dev +- Linux on ARM: +`rust-lld` is required for linking wasm, but is missing on non Tier 1 platforms. +So, use this https://github.com/Plume-org/Plume/blob/master/script/wasm-deps.sh[script] +to build `lld` and create the symlink `/usr/bin/rust-lld` to the build binary. + - Mac: [source, shell] brew install cmake pkg-config openssl git llvm diff --git a/core/utils/wasm-builder/src/prerequisites.rs b/core/utils/wasm-builder/src/prerequisites.rs index 52ff40887c..eeac6df33e 100644 --- a/core/utils/wasm-builder/src/prerequisites.rs +++ b/core/utils/wasm-builder/src/prerequisites.rs @@ -36,11 +36,7 @@ pub fn check() -> Option<&'static str> { return Some("`wasm-gc` not installed, please install it!") } - if !check_wasm_toolchain_installed() { - return Some("Rust WASM toolchain not installed, please install it!") - } - - None + check_wasm_toolchain_installed() } fn check_nightly_installed() -> bool { @@ -48,7 +44,7 @@ fn check_nightly_installed() -> bool { command.is_nightly() } -fn check_wasm_toolchain_installed() -> bool { +fn check_wasm_toolchain_installed() -> Option<&'static str> { let temp = tempdir().expect("Creating temp dir does not fail; qed"); fs::create_dir_all(temp.path().join("src")).expect("Creating src dir does not fail; qed"); @@ -72,13 +68,24 @@ fn check_wasm_toolchain_installed() -> bool { fs::write(&test_file, "pub fn test() {}") .expect("Writing to the test file does not fail; qed"); + let err_msg = "Rust WASM toolchain not installed, please install it!"; let manifest_path = manifest_path.display().to_string(); crate::get_nightly_cargo() .command() .args(&["build", "--target=wasm32-unknown-unknown", "--manifest-path", &manifest_path]) - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .status() - .map(|s| s.success()) - .unwrap_or(false) + .output() + .map_err(|_| err_msg) + .and_then(|s| + if s.status.success() { + Ok(()) + } else { + match String::from_utf8(s.stderr) { + Ok(ref err) if err.contains("linker `rust-lld` not found") => { + Err("`rust-lld` not found, please install it!") + }, + _ => Err(err_msg) + } + } + ) + .err() } -- GitLab From 99dc2bee035c5a2fe1b203f84de0a5dc5edb51af Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 18 Sep 2019 22:00:44 +0200 Subject: [PATCH 107/275] Remove the no_std feature from the WASM builder (#3640) * Remove the no_std feature from the WASM builder * Address review * More fixing * Address review again * Fix missing Cargo.lock --- Cargo.lock | 10 +++++----- core/executor/runtime-test/Cargo.toml | 1 - core/executor/runtime-test/build.rs | 2 +- core/test-runtime/Cargo.toml | 1 - core/test-runtime/build.rs | 2 +- core/utils/wasm-builder/Cargo.toml | 2 +- core/utils/wasm-builder/README.md | 3 --- core/utils/wasm-builder/src/lib.rs | 3 --- core/utils/wasm-builder/src/wasm_project.rs | 2 +- node-template/runtime/Cargo.toml | 1 - node-template/runtime/build.rs | 2 +- node/runtime/Cargo.toml | 3 --- node/runtime/build.rs | 2 +- srml/contracts/Cargo.toml | 3 --- 14 files changed, 11 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1e38076a7c..021f164b78 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2548,7 +2548,7 @@ dependencies = [ "substrate-offchain-primitives 2.0.0", "substrate-primitives 2.0.0", "substrate-session 2.0.0", - "substrate-wasm-builder-runner 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-wasm-builder-runner 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5475,7 +5475,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" -version = "1.0.6" +version = "1.0.7" dependencies = [ "build-helper 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5487,12 +5487,12 @@ dependencies = [ [[package]] name = "substrate-wasm-builder-runner" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" +version = "1.0.3" [[package]] name = "substrate-wasm-builder-runner" version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "substrate-wasm-interface" @@ -6845,7 +6845,7 @@ dependencies = [ "checksum strum 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d1c33039533f051704951680f1adfd468fd37ac46816ded0d9ee068e60f05f" "checksum strum_macros 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "47cd23f5c7dee395a00fa20135e2ec0fffcdfa151c56182966d7a3261343432e" "checksum substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3be511be555a3633e71739a79e4ddff6a6aaa6579fa6114182a51d72c3eb93c5" -"checksum substrate-wasm-builder-runner 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f52ecbff6cc3d6e5c6401828e15937b680f459d6803ce238f01fe615bc40d071" +"checksum substrate-wasm-builder-runner 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af21b27fad38b212c1919f700cb0def33c88cde14d22e0d1b17d4521f4eb8b40" "checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" "checksum subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "01dca13cf6c3b179864ab3292bd794e757618d35a7766b7c46050c614ba00829" "checksum syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)" = "eadc09306ca51a40555dd6fc2b415538e9e18bc9f870e47b1a524a79fe2dcf5e" diff --git a/core/executor/runtime-test/Cargo.toml b/core/executor/runtime-test/Cargo.toml index fcdacd98ca..2d4e58b8d4 100644 --- a/core/executor/runtime-test/Cargo.toml +++ b/core/executor/runtime-test/Cargo.toml @@ -18,4 +18,3 @@ wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1. [features] default = [ "std" ] std = [] -no_std = [] diff --git a/core/executor/runtime-test/build.rs b/core/executor/runtime-test/build.rs index fd4749b34c..136dc79398 100644 --- a/core/executor/runtime-test/build.rs +++ b/core/executor/runtime-test/build.rs @@ -21,7 +21,7 @@ fn main() { "wasm_binary.rs", WasmBuilderSource::CratesOrPath { path: "../../utils/wasm-builder", - version: "1.0.6", + version: "1.0.7", }, // This instructs LLD to export __heap_base as a global variable, which is used by the // external memory allocator. diff --git a/core/test-runtime/Cargo.toml b/core/test-runtime/Cargo.toml index 56c9915192..2f66d4471f 100644 --- a/core/test-runtime/Cargo.toml +++ b/core/test-runtime/Cargo.toml @@ -44,7 +44,6 @@ wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1. default = [ "std", ] -no_std = [] std = [ "log", "serde", diff --git a/core/test-runtime/build.rs b/core/test-runtime/build.rs index cdf1d17819..2e2d1fc93e 100644 --- a/core/test-runtime/build.rs +++ b/core/test-runtime/build.rs @@ -21,7 +21,7 @@ fn main() { "wasm_binary.rs", WasmBuilderSource::CratesOrPath { path: "../utils/wasm-builder", - version: "1.0.6", + version: "1.0.7", }, // Note that we set the stack-size to 1MB explicitly even though it is set // to this value by default. This is because some of our tests (`restoration_of_globals`) diff --git a/core/utils/wasm-builder/Cargo.toml b/core/utils/wasm-builder/Cargo.toml index ccc1d0cf3a..b74877a5d4 100644 --- a/core/utils/wasm-builder/Cargo.toml +++ b/core/utils/wasm-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-wasm-builder" -version = "1.0.6" +version = "1.0.7" authors = ["Parity Technologies "] description = "Utility for building WASM binaries" edition = "2018" diff --git a/core/utils/wasm-builder/README.md b/core/utils/wasm-builder/README.md index 8a8c67d6a8..0f3d933a2f 100644 --- a/core/utils/wasm-builder/README.md +++ b/core/utils/wasm-builder/README.md @@ -9,7 +9,6 @@ A project that should be compiled as a WASM binary needs to: 1. Add a `build.rs` file. 2. Add `substrate-wasm-builder-runner` as dependency into `build-dependencies`. -3. Add a feature called `no-std`. The `build.rs` file needs to contain the following code: @@ -26,8 +25,6 @@ fn main() { } ``` -The `no-std` feature will be enabled by WASM builder while compiling your project to WASM. - As the final step, you need to add the following to your project: ```rust diff --git a/core/utils/wasm-builder/src/lib.rs b/core/utils/wasm-builder/src/lib.rs index 49b468f15f..6f7687f446 100644 --- a/core/utils/wasm-builder/src/lib.rs +++ b/core/utils/wasm-builder/src/lib.rs @@ -25,7 +25,6 @@ //! //! 1. Add a `build.rs` file. //! 2. Add `substrate-wasm-builder-runner` as dependency into `build-dependencies`. -//! 3. Add a feature called `no-std`. //! //! The `build.rs` file needs to contain the following code: //! @@ -42,8 +41,6 @@ //! } //! ``` //! -//! The `no-std` feature will be enabled by WASM builder while compiling your project to WASM. -//! //! As the final step, you need to add the following to your project: //! //! ```ignore diff --git a/core/utils/wasm-builder/src/wasm_project.rs b/core/utils/wasm-builder/src/wasm_project.rs index a098234750..afe6faa070 100644 --- a/core/utils/wasm-builder/src/wasm_project.rs +++ b/core/utils/wasm-builder/src/wasm_project.rs @@ -270,7 +270,7 @@ fn create_project(cargo_manifest: &Path, wasm_workspace: &Path) -> PathBuf { crate-type = ["cdylib"] [dependencies] - wasm_project = {{ package = "{crate_name}", path = "{crate_path}", default-features = false, features = [ "no_std" ] }} + wasm_project = {{ package = "{crate_name}", path = "{crate_path}", default-features = false }} "#, crate_name = crate_name, crate_path = crate_path.display(), diff --git a/node-template/runtime/Cargo.toml b/node-template/runtime/Cargo.toml index 986feeb38c..44545d5780 100644 --- a/node-template/runtime/Cargo.toml +++ b/node-template/runtime/Cargo.toml @@ -55,4 +55,3 @@ std = [ "offchain-primitives/std", "substrate-session/std", ] -no_std = [] diff --git a/node-template/runtime/build.rs b/node-template/runtime/build.rs index 6feac76e8b..ddbeefa112 100644 --- a/node-template/runtime/build.rs +++ b/node-template/runtime/build.rs @@ -19,7 +19,7 @@ use wasm_builder_runner::{build_current_project_with_rustflags, WasmBuilderSourc fn main() { build_current_project_with_rustflags( "wasm_binary.rs", - WasmBuilderSource::Crates("1.0.6"), + WasmBuilderSource::Crates("1.0.7"), // This instructs LLD to export __heap_base as a global variable, which is used by the // external memory allocator. "-Clink-arg=--export=__heap_base", diff --git a/node/runtime/Cargo.toml b/node/runtime/Cargo.toml index 755c4afe84..554d9561a3 100644 --- a/node/runtime/Cargo.toml +++ b/node/runtime/Cargo.toml @@ -53,9 +53,6 @@ wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1. [features] default = ["std"] -no_std = [ - "contracts/core", -] std = [ "authority-discovery-primitives/std", "authority-discovery/std", diff --git a/node/runtime/build.rs b/node/runtime/build.rs index 62dfe2ff39..7311fb90ce 100644 --- a/node/runtime/build.rs +++ b/node/runtime/build.rs @@ -21,7 +21,7 @@ fn main() { "wasm_binary.rs", WasmBuilderSource::CratesOrPath { path: "../../core/utils/wasm-builder", - version: "1.0.6", + version: "1.0.7", }, // This instructs LLD to export __heap_base as a global variable, which is used by the // external memory allocator. diff --git a/srml/contracts/Cargo.toml b/srml/contracts/Cargo.toml index 1fc05772fb..de6ee96197 100644 --- a/srml/contracts/Cargo.toml +++ b/srml/contracts/Cargo.toml @@ -28,9 +28,6 @@ hex = "0.3" [features] default = ["std"] -core = [ - "wasmi-validation/core", -] std = [ "serde", "codec/std", -- GitLab From 5a2be8bd56ed5d9dc787fb3b9a76ce10ced4704b Mon Sep 17 00:00:00 2001 From: Talha Cross <47772477+soc1c@users.noreply.github.com> Date: Thu, 19 Sep 2019 08:34:41 +0200 Subject: [PATCH 108/275] core, subkey: allow to read Polkadot, Kusama, and Dothereum address types (#3643) * core/primitives: set dothereum address type to 4 * subkey: add dothereum to network prefix * core/primitives: set dothereum address type to 20 * core/primitives: update comment * core/primitives: set default address to Dothereum * Revert "core/primitives: set default address to Dothereum" This reverts commit 2fc95490c89390eb26f200cb314435b1e9ff83e8. * core/primitives: allow to parse different default address types --- core/primitives/src/crypto.rs | 15 ++++++++++++++- subkey/src/cli.yml | 2 +- subkey/src/main.rs | 4 ++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/core/primitives/src/crypto.rs b/core/primitives/src/crypto.rs index 0adf50e160..5887866735 100644 --- a/core/primitives/src/crypto.rs +++ b/core/primitives/src/crypto.rs @@ -261,6 +261,9 @@ pub trait Ss58Codec: Sized { Self::from_ss58check_with_version(s) .and_then(|(r, v)| match v { Ss58AddressFormat::SubstrateAccountDirect => Ok(r), + Ss58AddressFormat::PolkadotAccountDirect => Ok(r), + Ss58AddressFormat::KusamaAccountDirect => Ok(r), + Ss58AddressFormat::DothereumAccountDirect => Ok(r), v if v == *DEFAULT_VERSION.lock() => Ok(r), _ => Err(PublicError::UnknownVersion), }) @@ -273,6 +276,9 @@ pub trait Ss58Codec: Sized { Self::from_string_with_version(s) .and_then(|(r, v)| match v { Ss58AddressFormat::SubstrateAccountDirect => Ok(r), + Ss58AddressFormat::PolkadotAccountDirect => Ok(r), + Ss58AddressFormat::KusamaAccountDirect => Ok(r), + Ss58AddressFormat::DothereumAccountDirect => Ok(r), v if v == *DEFAULT_VERSION.lock() => Ok(r), _ => Err(PublicError::UnknownVersion), }) @@ -327,6 +333,8 @@ pub enum Ss58AddressFormat { PolkadotAccountDirect, /// Kusama Relay-chain, direct checksum, standard account (*25519). KusamaAccountDirect, + /// Dothereum Para-chain, direct checksum, standard account (*25519). + DothereumAccountDirect, /// Use a manually provided numeric value. Custom(u8), } @@ -338,6 +346,7 @@ impl From for u8 { Ss58AddressFormat::SubstrateAccountDirect => 42, Ss58AddressFormat::PolkadotAccountDirect => 0, Ss58AddressFormat::KusamaAccountDirect => 2, + Ss58AddressFormat::DothereumAccountDirect => 20, Ss58AddressFormat::Custom(n) => n, } } @@ -351,6 +360,7 @@ impl TryFrom for Ss58AddressFormat { 42 => Ok(Ss58AddressFormat::SubstrateAccountDirect), 0 => Ok(Ss58AddressFormat::PolkadotAccountDirect), 2 => Ok(Ss58AddressFormat::KusamaAccountDirect), + 20 => Ok(Ss58AddressFormat::DothereumAccountDirect), _ => Err(()), } } @@ -364,6 +374,7 @@ impl<'a> TryFrom<&'a str> for Ss58AddressFormat { "substrate" => Ok(Ss58AddressFormat::SubstrateAccountDirect), "polkadot" => Ok(Ss58AddressFormat::PolkadotAccountDirect), "kusama" => Ok(Ss58AddressFormat::KusamaAccountDirect), + "dothereum" => Ok(Ss58AddressFormat::DothereumAccountDirect), a => a.parse::().map(Ss58AddressFormat::Custom).map_err(|_| ()), } } @@ -376,6 +387,7 @@ impl From for String { Ss58AddressFormat::SubstrateAccountDirect => "substrate".into(), Ss58AddressFormat::PolkadotAccountDirect => "polkadot".into(), Ss58AddressFormat::KusamaAccountDirect => "kusama".into(), + Ss58AddressFormat::DothereumAccountDirect => "dothereum".into(), Ss58AddressFormat::Custom(x) => x.to_string(), } } @@ -387,7 +399,8 @@ impl From for String { /// /// Current known "versions" are: /// - 0 direct (payload) checksum for 32-byte *25519 Polkadot addresses. -/// - 2 direct (payload) checksum for 32-byte *25519 Polkadot Milestone 'K' addresses. +/// - 2 direct (payload) checksum for 32-byte *25519 Kusama addresses. +/// - 20 direct (payload) checksum for 32-byte *25519 Dothereum addresses. /// - 42 direct (payload) checksum for 32-byte *25519 addresses on any Substrate-based network. #[cfg(feature = "std")] pub fn set_default_ss58_version(version: Ss58AddressFormat) { diff --git a/subkey/src/cli.yml b/subkey/src/cli.yml index b4f99f8743..aa6c6d4a57 100644 --- a/subkey/src/cli.yml +++ b/subkey/src/cli.yml @@ -23,7 +23,7 @@ args: long: network takes_value: true required: false - help: Specify a network. One of substrate (default), polkadot and kusama. + help: Specify a network. One of substrate (default), polkadot, kusama, or dothereum. subcommands: - generate: about: Generate a random account diff --git a/subkey/src/main.rs b/subkey/src/main.rs index c112dfa1b4..973502b3d6 100644 --- a/subkey/src/main.rs +++ b/subkey/src/main.rs @@ -140,7 +140,7 @@ where let maybe_network: Option = matches.value_of("network").map(|network| { network .try_into() - .expect("Invalid network name: must be polkadot/substrate/kusama") + .expect("Invalid network name: must be polkadot/substrate/kusama/dothereum") }); if let Some(network) = maybe_network { set_default_ss58_version(network); @@ -382,7 +382,7 @@ fn create_extrinsic( ); let signature = raw_payload.using_encoded(|payload| signer.sign(payload)); let (function, extra, _) = raw_payload.deconstruct(); - + UncheckedExtrinsic::new_signed( function, signer.public().into(), -- GitLab From e8334c27de178bab6d589e5875cedc1fb95ca29a Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Thu, 19 Sep 2019 12:04:02 +0200 Subject: [PATCH 109/275] srml-module: Phragmen election (#3364) * phragmen election module. * Add new files. * Some doc update * Update weights. * bump and a few nits. * Performance improvement. * Master.into() * Update srml/elections-phragmen/src/lib.rs Co-Authored-By: Gavin Wood * Fix build * Some fixes. * Fix build. * Proper outgoing and runner-up managment. * Bit more sensical weight values. * Update srml/elections-phragmen/src/lib.rs * Update srml/elections-phragmen/src/lib.rs Co-Authored-By: Gavin Wood * Update srml/elections-phragmen/src/lib.rs Co-Authored-By: Gavin Wood * Update srml/elections-phragmen/src/lib.rs Co-Authored-By: Gavin Wood * fix lock file * Fix build. * Remove runner-ups * Some refactors. * Add support for reporting voters. * Fix member check. * Remove equlize.rs * Update srml/elections-phragmen/src/lib.rs * Update srml/elections-phragmen/src/lib.rs * Update srml/elections-phragmen/src/lib.rs Co-Authored-By: Gavin Wood * Update srml/elections-phragmen/src/lib.rs Co-Authored-By: Gavin Wood * Bring back runner ups. * use decode_len * Better weight values. * Update bogus doc * Bump. * Update srml/elections-phragmen/src/lib.rs Co-Authored-By: Gavin Wood * Review comments. * One more test * Fix tests * Fix build * .. and fix benchmarks. * Update srml/elections-phragmen/src/lib.rs * Version bump --- Cargo.lock | 66 +- Cargo.toml | 1 + core/phragmen/benches/phragmen.rs | 2 +- core/phragmen/src/lib.rs | 14 +- core/phragmen/src/mock.rs | 10 +- core/phragmen/src/tests.rs | 4 +- node/runtime/src/lib.rs | 4 +- srml/elections-phragmen/Cargo.toml | 34 + srml/elections-phragmen/src/lib.rs | 1606 ++++++++++++++++++++++++++++ srml/elections/src/lib.rs | 1 - srml/staking/src/lib.rs | 5 +- srml/support/src/traits.rs | 13 +- 12 files changed, 1715 insertions(+), 45 deletions(-) create mode 100644 srml/elections-phragmen/Cargo.toml create mode 100644 srml/elections-phragmen/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 021f164b78..c420e94106 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1702,7 +1702,7 @@ dependencies = [ "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1856,7 +1856,7 @@ dependencies = [ "snow 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2163,7 +2163,7 @@ dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3113,7 +3113,7 @@ dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3173,7 +3173,7 @@ dependencies = [ "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3218,12 +3218,12 @@ name = "rand_core" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand_core" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -3264,7 +3264,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3276,7 +3276,7 @@ dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3287,7 +3287,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3514,17 +3514,18 @@ dependencies = [ [[package]] name = "schnorrkel" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "curve25519-dalek 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "merlin 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3750,7 +3751,7 @@ dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4066,6 +4067,23 @@ dependencies = [ "substrate-primitives 2.0.0", ] +[[package]] +name = "srml-elections-phragmen" +version = "2.0.0" +dependencies = [ + "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 2.0.0", + "sr-primitives 2.0.0", + "sr-std 2.0.0", + "srml-balances 2.0.0", + "srml-support 2.0.0", + "srml-system 2.0.0", + "substrate-phragmen 2.0.0", + "substrate-primitives 2.0.0", +] + [[package]] name = "srml-example" version = "2.0.0" @@ -4581,7 +4599,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "schnorrkel 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4740,7 +4758,7 @@ dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "schnorrkel 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-version 2.0.0", @@ -4770,7 +4788,7 @@ name = "substrate-consensus-babe-primitives" version = "2.0.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "schnorrkel 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", "substrate-application-crypto 2.0.0", @@ -5033,7 +5051,7 @@ dependencies = [ "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5128,7 +5146,7 @@ dependencies = [ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "schnorrkel 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", @@ -5137,7 +5155,7 @@ dependencies = [ "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "twox-hash 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6445,7 +6463,7 @@ dependencies = [ [[package]] name = "zeroize" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "zeroize_derive 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6770,7 +6788,7 @@ dependencies = [ "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" "checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" "checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" "checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" @@ -6804,7 +6822,7 @@ dependencies = [ "checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" "checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" "checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339" -"checksum schnorrkel 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "77e8d6a92f49a53f21b71c090a5559bf45c469071ebe556aebaf2dca3abc5cb5" +"checksum schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "eacd8381b3c37840c9c9f40472af529e49975bdcbc24f83c31059fd6539023d3" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" "checksum sct 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f5adf8fbd58e1b1b52699dc8bed2630faecb6d8c7bee77d009d6bbe4af569b9" @@ -6945,5 +6963,5 @@ dependencies = [ "checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" "checksum yamux 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "01bd67889938c48f0049fc60a77341039e6c3eaf16cb7693e6ead7c0ba701295" -"checksum zeroize 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4177936c03b5a349c1b8e4509c46add268e66bc66fe92663729fa0570fe4f213" +"checksum zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "45af6a010d13e4cf5b54c94ba5a2b2eba5596b9e46bf5875612d332a1f2b3f86" "checksum zeroize_derive 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afd1469e4bbca3b96606d26ba6e9bd6d3aed3b1299c82b92ec94377d22d78dbc" diff --git a/Cargo.toml b/Cargo.toml index bc9fd128ff..6bec85759b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -80,6 +80,7 @@ members = [ "srml/collective", "srml/democracy", "srml/elections", + "srml/elections-phragmen", "srml/example", "srml/executive", "srml/finality-tracker", diff --git a/core/phragmen/benches/phragmen.rs b/core/phragmen/benches/phragmen.rs index dfe56aafd8..ecbf235bab 100644 --- a/core/phragmen/benches/phragmen.rs +++ b/core/phragmen/benches/phragmen.rs @@ -110,7 +110,7 @@ fn do_phragmen( let mut supports = >::new(); elected_stashes .iter() - .map(|e| (e, to_votes(slashable_balance(e)))) + .map(|(e, _)| (e, to_votes(slashable_balance(e)))) .for_each(|(e, s)| { let item = Support { own: s, total: s, ..Default::default() }; supports.insert(e.clone(), item); diff --git a/core/phragmen/src/lib.rs b/core/phragmen/src/lib.rs index da3e923424..2d4580d2e0 100644 --- a/core/phragmen/src/lib.rs +++ b/core/phragmen/src/lib.rs @@ -106,9 +106,11 @@ pub struct Edge { pub type PhragmenAssignment = (AccountId, ExtendedBalance); /// Final result of the phragmen election. +#[cfg_attr(feature = "std", derive(Debug))] pub struct PhragmenResult { - /// Just winners. - pub winners: Vec, + /// Just winners zipped with their approval stake. Note that the approval stake is merely the + /// sub of their received stake and could be used for very basic sorting and approval voting. + pub winners: Vec<(AccountId, ExtendedBalance)>, /// Individual assignments. for each tuple, the first elements is a voter and the second /// is the list of candidates that it supports. pub assignments: Vec<(AccountId, Vec>)> @@ -166,7 +168,7 @@ pub fn elect( >::convert(b) as ExtendedBalance; // return structures - let mut elected_candidates: Vec; + let mut elected_candidates: Vec<(AccountId, ExtendedBalance)>; let mut assigned: Vec<(AccountId, Vec>)>; // used to cache and access candidates index. @@ -282,7 +284,7 @@ pub fn elect( } } - elected_candidates.push(winner.who.clone()); + elected_candidates.push((winner.who.clone(), winner.approval_stake)); } else { break } @@ -292,8 +294,8 @@ pub fn elect( for n in &mut voters { let mut assignment = (n.who.clone(), vec![]); for e in &mut n.edges { - if let Some(c) = elected_candidates.iter().cloned().find(|c| *c == e.who) { - if c != n.who { + if let Some(c) = elected_candidates.iter().cloned().find(|(c, _)| *c == e.who) { + if c.0 != n.who { let ratio = { // Full support. No need to calculate. if *n.load == *e.load { ACCURACY } diff --git a/core/phragmen/src/mock.rs b/core/phragmen/src/mock.rs index 659ff9dacb..e4f220affc 100644 --- a/core/phragmen/src/mock.rs +++ b/core/phragmen/src/mock.rs @@ -69,7 +69,7 @@ pub(crate) type AccountId = u64; #[derive(Debug, Clone)] pub(crate) struct _PhragmenResult { - pub winners: Vec, + pub winners: Vec<(A, Balance)>, pub assignments: Vec<(A, Vec<_PhragmenAssignment>)> } @@ -84,7 +84,7 @@ pub(crate) fn elect_float( A: Default + Ord + Member + Copy, for<'r> FS: Fn(&'r A) -> Balance, { - let mut elected_candidates: Vec; + let mut elected_candidates: Vec<(A, Balance)>; let mut assigned: Vec<(A, Vec<_PhragmenAssignment>)>; let mut c_idx_cache = BTreeMap::::new(); let num_voters = initial_candidates.len() + initial_voters.len(); @@ -178,7 +178,7 @@ pub(crate) fn elect_float( } } - elected_candidates.push(winner.who.clone()); + elected_candidates.push((winner.who.clone(), winner.approval_stake as Balance)); } else { break } @@ -187,7 +187,7 @@ pub(crate) fn elect_float( for n in &mut voters { let mut assignment = (n.who.clone(), vec![]); for e in &mut n.edges { - if let Some(c) = elected_candidates.iter().cloned().find(|c| *c == e.who) { + if let Some(c) = elected_candidates.iter().cloned().map(|(c, _)| c).find(|c| *c == e.who) { if c != n.who { let ratio = e.load / n.load; assignment.1.push((e.who.clone(), ratio)); @@ -397,7 +397,7 @@ pub(crate) fn build_support_map( let mut supports = <_SupportMap>::new(); result.winners .iter() - .map(|e| (e, stake_of(e) as f64)) + .map(|(e, _)| (e, stake_of(e) as f64)) .for_each(|(e, s)| { let item = _Support { own: s, total: s, ..Default::default() }; supports.insert(e.clone(), item); diff --git a/core/phragmen/src/tests.rs b/core/phragmen/src/tests.rs index 5a8cddb984..750adb49ce 100644 --- a/core/phragmen/src/tests.rs +++ b/core/phragmen/src/tests.rs @@ -35,7 +35,7 @@ fn float_phragmen_poc_works() { let winners = phragmen_result.clone().winners; let assignments = phragmen_result.clone().assignments; - assert_eq_uvec!(winners, vec![2, 3]); + assert_eq_uvec!(winners, vec![(2, 40), (3, 50)]); assert_eq_uvec!( assignments, vec![ @@ -86,7 +86,7 @@ fn phragmen_poc_works() { false, ).unwrap(); - assert_eq_uvec!(winners, vec![2, 3]); + assert_eq_uvec!(winners, vec![(2, 40), (3, 50)]); assert_eq_uvec!( assignments, vec![ diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 94497de0ac..0c1a229ab2 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -82,8 +82,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 158, - impl_version: 160, + spec_version: 159, + impl_version: 159, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/elections-phragmen/Cargo.toml b/srml/elections-phragmen/Cargo.toml new file mode 100644 index 0000000000..0faa429d75 --- /dev/null +++ b/srml/elections-phragmen/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "srml-elections-phragmen" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +serde = { version = "1.0", optional = true } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } +runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } +sr-primitives = { path = "../../core/sr-primitives", default-features = false } +phragmen = { package = "substrate-phragmen", path = "../../core/phragmen", default-features = false } +srml-support = { path = "../support", default-features = false } +system = { package = "srml-system", path = "../system", default-features = false } +rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } + +[dev-dependencies] +hex-literal = "0.2.0" +balances = { package = "srml-balances", path = "../balances" } + +[features] +default = ["std"] +std = [ + "codec/std", + "primitives/std", + "serde", + "runtime_io/std", + "srml-support/std", + "sr-primitives/std", + "phragmen/std", + "system/std", + "rstd/std", +] diff --git a/srml/elections-phragmen/src/lib.rs b/srml/elections-phragmen/src/lib.rs new file mode 100644 index 0000000000..6b0c773ec9 --- /dev/null +++ b/srml/elections-phragmen/src/lib.rs @@ -0,0 +1,1606 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! # Phragmen Election Module. +//! +//! An election module based on sequential phragmen. +//! +//! ### Term and Round +//! +//! The election happens in _rounds_: every `N` blocks, all previous members are retired and a new +//! set is elected (which may or may not have an intersection with the previous set). Each round +//! lasts for some number of blocks defined by `TermDuration` storage item. The words _term_ and +//! _round_ can be used interchangeably in this context. +//! +//! `TermDuration` might change during a round. This can shorten or extend the length of the round. +//! The next election round's block number is never stored but rather always checked on the fly. +//! Based on the current block number and `TermDuration`, the condition `BlockNumber % TermDuration +//! == 0` being satisfied will always trigger a new election round. +//! +//! ### Voting +//! +//! Voters can vote for any set of the candidates by providing a list of account ids. Invalid votes +//! (voting for non-candidates) are ignored during election. Yet, a voter _might_ vote for a future +//! candidate. Voters reserve a bond as they vote. Each vote defines a `value`. This amount is +//! locked from the account of the voter and indicates the weight of the vote. Voters can update +//! their votes at any time by calling `vote()` again. This keeps the bond untouched but can +//! optionally change the locked `value`. After a round, votes are kept and might still be valid for +//! further rounds. A voter is responsible for calling `remove_voter` once they are done to have +//! their bond back and remove the lock. +//! +//! Voters also report other voters as being defunct to earn their bond. A voter is defunct once all +//! of the candidates that they have voted for are neither a valid candidate anymore nor a member. +//! Upon reporting, if the target voter is actually defunct, the reporter will be rewarded by the +//! voting bond of the target. The target will lose their bond and get removed. If the target is not +//! defunct, the reporter is slashed and removed. To prevent being reported, voters should manually +//! submit a `remove_voter()` as soon as they are in the defunct state. +//! +//! ### Candidacy and Members +//! +//! Candidates also reserve a bond as they submit candidacy. A candidate cannot take their candidacy +//! back. A candidate can end up in one of the below situations: +//! - **Winner**: A winner is kept as a _member_. They must still have a bond in reserve and they +//! are automatically counted as a candidate for the next election. +//! - **Loser**: Any of the candidate who are not a winner are left as losers. A loser might be an +//! _outgoing member_, meaning that they are an active member who failed to keep their spot. In +//! this case, the outgoing member will get their bond back. Otherwise, the bond is slashed from +//! the loser candidate. +//! - **Runner-up**: Runners-up are the best candidates immediately after the winners. The number +//! of runners_up to keep is configurable. Runners-up are used, in order that they are elected, +//! as replacements when a candidate is kicked by `remove_member()`. +//! +//! Note that with the members being the default candidates for the next round and votes persisting +//! in storage, the election system is entirely stable given no further input. This means that if +//! the system has a particular set of candidates `C` and voters `V` that lead to a set of members +//! `M` being elected, as long as `V` and `C` don't remove their candidacy and votes, `M` will keep +//! being re-elected at the end of each round. +//! +//! ### Module Information +//! +//! - [`election_phragmen::Trait`](./trait.Trait.html) +//! - [`Call`](./enum.Call.html) +//! - [`Module`](./struct.Module.html) + +#![cfg_attr(not(feature = "std"), no_std)] + +use sr_primitives::{print, traits::{Zero, StaticLookup, Bounded, Convert}}; +use sr_primitives::weights::SimpleDispatchInfo; +use srml_support::{ + StorageValue, StorageMap, StorageLinkedMap, + decl_storage, decl_event, ensure, decl_module, dispatch, + traits::{ + Currency, Get, LockableCurrency, LockIdentifier, ReservableCurrency, WithdrawReasons, + ChangeMembers, OnUnbalanced, + } +}; +use system::{self, ensure_signed, ensure_root}; + +const MODULE_ID: LockIdentifier = *b"phrelect"; + +/// The maximum votes allowed per voter. +pub const MAXIMUM_VOTE: usize = 16; + +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type NegativeImbalanceOf = + <::Currency as Currency<::AccountId>>::NegativeImbalance; + +pub trait Trait: system::Trait { + /// The overarching event type.c + type Event: From> + Into<::Event>; + + /// The currency that people are electing with. + type Currency: + LockableCurrency + + ReservableCurrency; + + /// What to do when the members change. + type ChangeMembers: ChangeMembers; + + /// Convert a balance into a number used for election calculation. + /// This must fit into a `u64` but is allowed to be sensibly lossy. + type CurrencyToVote: Convert, u64> + Convert>; + + /// How much should be locked up in order to submit one's candidacy. + type CandidacyBond: Get>; + + /// How much should be locked up in order to be able to submit votes. + type VotingBond: Get>; + + /// Handler for the unbalanced reduction when a candidate has lost (and is not a runner-up) + type LoserCandidate: OnUnbalanced>; + + /// Handler for the unbalanced reduction when a reporter has submitted a bad defunct report. + type BadReport: OnUnbalanced>; + + /// Handler for the unbalanced reduction when a member has been kicked. + type KickedMember: OnUnbalanced>; +} + +decl_storage! { + trait Store for Module as PhragmenElection { + // ---- parameters + /// Number of members to elect. + pub DesiredMembers get(desired_members) config(): u32; + /// Number of runners_up to keep. + pub DesiredRunnersUp get(desired_runners_up) config(): u32; + /// How long each seat is kept. This defines the next block number at which an election + /// round will happen. + pub TermDuration get(term_duration) config(): T::BlockNumber; + + // ---- State + /// The current elected membership. Sorted based on account id. + pub Members get(members) config(): Vec; + /// The current runners_up. Sorted based on low to high merit (worse to best runner). + pub RunnersUp get(runners_up): Vec; + /// The total number of vote rounds that have happened, excluding the upcoming one. + pub ElectionRounds get(election_rounds): u32 = Zero::zero(); + + /// Votes of a particular voter, with the round index of the votes. + pub VotesOf get(votes_of): linked_map T::AccountId => Vec; + /// Locked stake of a voter. + pub StakeOf get(stake_of): map T::AccountId => BalanceOf; + + /// The present candidate list. Sorted based on account id. A current member can never enter + /// this vector and is always implicitly assumed to be a candidate. + pub Candidates get(candidates): Vec; + } +} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + fn deposit_event() = default; + + const CandidacyBond: BalanceOf = T::CandidacyBond::get(); + const VotingBond: BalanceOf = T::VotingBond::get(); + + /// Vote for a set of candidates for the upcoming round of election. + /// + /// The `votes` should: + /// - not be empty. + /// - be less than the number of candidates. + /// + /// Upon voting, `value` units of `who`'s balance is locked and a bond amount is reserved. + /// It is the responsibility of the caller to not place all of their balance into the lock + /// and keep some for further transactions. + /// + /// # + /// #### State + /// Reads: O(1) + /// Writes: O(V) given `V` votes. V is bounded by 16. + /// # + #[weight = SimpleDispatchInfo::FixedNormal(100_000)] + fn vote(origin, votes: Vec, value: BalanceOf) { + let who = ensure_signed(origin)?; + + let candidates_count = >::decode_len().unwrap_or(0) as usize; + let members_count = >::decode_len().unwrap_or(0) as usize; + // addition is valid: candidates and members never overlap. + let allowed_votes = candidates_count + members_count; + + ensure!(!allowed_votes.is_zero(), "cannot vote when no candidates or members exist"); + ensure!(votes.len() <= allowed_votes, "cannot vote more than candidates"); + ensure!(votes.len() <= MAXIMUM_VOTE, "cannot vote more than maximum allowed"); + + ensure!(!votes.is_empty(), "must vote for at least one candidate."); + ensure!( + value > T::Currency::minimum_balance(), + "cannot vote with stake less than minimum balance" + ); + + if !Self::is_voter(&who) { + // first time voter. Reserve bond. + T::Currency::reserve(&who, T::VotingBond::get()) + .map_err(|_| "voter can not pay voting bond")?; + } + // Amount to be locked up. + let locked_balance = value.min(T::Currency::total_balance(&who)); + + // lock + T::Currency::set_lock( + MODULE_ID, + &who, + locked_balance, + T::BlockNumber::max_value(), + WithdrawReasons::all(), + ); + >::insert(&who, locked_balance); + >::insert(&who, votes); + } + + /// Remove `origin` as a voter. This removes the lock and returns the bond. + /// + /// # + /// #### State + /// Reads: O(1) + /// Writes: O(1) + /// # + #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + fn remove_voter(origin) { + let who = ensure_signed(origin)?; + + ensure!(Self::is_voter(&who), "must be a voter"); + + Self::do_remove_voter(&who, true); + } + + /// Report `target` for being an defunct voter. In case of a valid report, the reporter is + /// rewarded by the bond amount of `target`. Otherwise, the reporter itself is removed and + /// their bond is slashed. + /// + /// A defunct voter is defined to be: + /// - a voter whose current submitted votes are all invalid. i.e. all of them are no + /// longer a candidate nor an active member. + /// + /// # + /// #### State + /// Reads: O(NLogM) given M current candidates and N votes for `target`. + /// Writes: O(1) + /// # + #[weight = SimpleDispatchInfo::FixedNormal(1_000_000)] + fn report_defunct_voter(origin, target: ::Source) { + let reporter = ensure_signed(origin)?; + let target = T::Lookup::lookup(target)?; + + ensure!(reporter != target, "cannot report self"); + ensure!(Self::is_voter(&reporter), "reporter must be a voter"); + + // Checking if someone is a candidate and a member here is O(LogN), making the whole + // function O(MLonN) with N candidates in total and M of them being voted by `target`. + // We could easily add another mapping to be able to check if someone is a candidate in + // `O(1)` but that would make the process of removing candidates at the end of each + // round slightly harder. Note that for now we have a bound of number of votes (`N`). + let valid = Self::is_defunct_voter(&target); + if valid { + // reporter will get the voting bond of the target + T::Currency::repatriate_reserved(&target, &reporter, T::VotingBond::get())?; + // remove the target. They are defunct. + Self::do_remove_voter(&target, false); + } else { + // slash the bond of the reporter. + let imbalance = T::Currency::slash_reserved(&reporter, T::VotingBond::get()).0; + T::BadReport::on_unbalanced(imbalance); + // remove the reporter. + Self::do_remove_voter(&reporter, false); + } + Self::deposit_event(RawEvent::VoterReported(target, reporter, valid)); + } + + + /// Submit oneself for candidacy. + /// + /// A candidate will either: + /// - Lose at the end of the term and forfeit their deposit. + /// - Win and become a member. Members will eventually get their stash back. + /// - Become a runner-up. Runners-ups are reserved members in case one gets forcefully + /// removed. + /// + /// # + /// #### State + /// Reads: O(LogN) Given N candidates. + /// Writes: O(1) + /// # + #[weight = SimpleDispatchInfo::FixedNormal(500_000)] + fn submit_candidacy(origin) { + let who = ensure_signed(origin)?; + + let is_candidate = Self::is_candidate(&who); + ensure!(is_candidate.is_err(), "duplicate candidate submission"); + // assured to be an error, error always contains the index. + let index = is_candidate.unwrap_err(); + + ensure!(!Self::is_member(&who), "member cannot re-submit candidacy"); + + T::Currency::reserve(&who, T::CandidacyBond::get()) + .map_err(|_| "candidate does not have enough funds")?; + + >::mutate(|c| c.insert(index, who)); + } + + /// Set the desired member count. Changes will be effective at the beginning of next round. + /// + /// # + /// #### State + /// Reads: O(1) + /// Writes: O(1) + /// # + #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + fn set_desired_member_count(origin, #[compact] count: u32) { + ensure_root(origin)?; + DesiredMembers::put(count); + } + + /// Remove a particular member from the set. This is effective immediately. + /// + /// If a runner-up is available, then the best runner-up will be removed and replaces the + /// outgoing member. Otherwise, a new phragmen round is started. + /// + /// Note that this does not affect the designated block number of the next election. + /// + /// # + /// #### State + /// Reads: O(do_phragmen) + /// Writes: O(do_phragmen) + /// # + #[weight = SimpleDispatchInfo::FixedOperational(2_000_000)] + fn remove_member(origin, who: ::Source) { + ensure_root(origin)?; + let who = T::Lookup::lookup(who)?; + + let mut members = Self::members(); + if let Ok(index) = members.binary_search(&who) { + // remove, slash, emit event. + members.remove(index); + let (imbalance, _) = T::Currency::slash_reserved(&who, T::CandidacyBond::get()); + T::KickedMember::on_unbalanced(imbalance); + Self::deposit_event(RawEvent::MemberKicked(who.clone())); + + let mut runners_up = Self::runners_up(); + if let Some(replacement) = runners_up.pop() { + // replace the outgoing with the best runner up. + if let Err(index) = members.binary_search(&replacement) { + members.insert(index, replacement.clone()); + ElectionRounds::mutate(|v| *v += 1); + T::ChangeMembers::change_members_sorted(&[replacement], &[who], &members); + } + // else it would mean that the runner up was already a member. This cannot + // happen. If it does, not much that we can do about it. + + >::put(members); + >::put(runners_up); + } else { + // update `Members` storage -- `do_phragmen` adds this to the candidate list. + >::put(members); + // trigger a new phragmen. grab a cup of coffee. This might take a while. + Self::do_phragmen(); + } + } + } + + /// Set the duration of each term. This will affect the next election's block number. + /// + /// # + /// #### State + /// Reads: O(1) + /// Writes: O(1) + /// # + #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + fn set_term_duration(origin, #[compact] count: T::BlockNumber) { + ensure_root(origin)?; + >::put(count); + } + + /// What to do at the end of each block. Checks if an election needs to happen or not. + fn on_initialize(n: T::BlockNumber) { + if let Err(e) = Self::end_block(n) { + print("Guru meditation"); + print(e); + } + } + } +} + +decl_event!( + pub enum Event where ::AccountId { + /// A new term with new members. This indicates that enough candidates existed, not that + /// enough have has been elected. The inner value must be examined for this purpose. + NewTerm(Vec), + /// No (or not enough) candidates existed for this round. + EmptyTerm, + /// A member has been removed. This should always be followed by either `NewTerm` ot + /// `EmptyTerm`. + MemberKicked(AccountId), + /// A voter (first element) was reported (byt the second element) with the the report being + /// successful or not (third element). + VoterReported(AccountId, AccountId, bool), + } +); + +impl Module { + /// Check if `who` is a candidate. It returns the insert index if the element does not exists as + /// an error. + /// + /// State: O(LogN) given N candidates. + fn is_candidate(who: &T::AccountId) -> Result<(), usize> { + Self::candidates().binary_search(who).map(|_| ()) + } + + /// Check if `who` is a voter. It may or may not be a _current_ one. + /// + /// State: O(1). + fn is_voter(who: &T::AccountId) -> bool { + >::exists(who) + } + + /// Check if `who` is currently an active member. + /// + /// Limited number of members. Binary search. Constant time factor. O(1) + fn is_member(who: &T::AccountId) -> bool { + Self::members().binary_search(who).is_ok() + } + + /// Check if `who` is a defunct voter. + /// + /// Note that false is returned if `who` is not a voter at all. + /// + /// O(NLogM) with M candidates and `who` having voted for `N` of them. + fn is_defunct_voter(who: &T::AccountId) -> bool { + if Self::is_voter(who) { + Self::votes_of(who) + .iter() + .all(|v| !Self::is_member(v) && !Self::is_candidate(v).is_ok()) + } else { + false + } + } + + /// Remove a certain someone as a voter. + /// + /// This will clean always clean the storage associated with the voter, and remove the balance + /// lock. Optionally, it would also return the reserved voting bond if indicated by `unreserve`. + fn do_remove_voter(who: &T::AccountId, unreserve: bool) { + // remove storage and lock. + >::remove(who); + >::remove(who); + T::Currency::remove_lock(MODULE_ID, who); + + if unreserve { + T::Currency::unreserve(who, T::VotingBond::get()); + } + } + + /// The locked stake of a voter. + fn locked_stake_of(who: &T::AccountId) -> BalanceOf { + Self::stake_of(who) + } + + /// Check there's nothing to do this block. + /// + /// Runs phragmen election and cleans all the previous candidate state. The voter state is NOT + /// cleaned and voters must themselves submit a transaction to retract. + fn end_block(block_number: T::BlockNumber) -> dispatch::Result { + if (block_number % Self::term_duration()).is_zero() { + Self::do_phragmen(); + } + Ok(()) + } + + /// Run the phragmen election with all required side processes and state updates. + /// + /// Calls the appropriate `ChangeMembers` function variant internally. + /// + /// # + /// #### State + /// Reads: O(C + V*E) where C = candidates, V voters and E votes per voter exits. + /// Writes: O(M + R) with M desired members and R runners_up. + /// # + fn do_phragmen() { + let desired_seats = Self::desired_members() as usize; + let desired_runners_up = Self::desired_runners_up() as usize; + let num_to_elect = desired_runners_up + desired_seats; + + let mut candidates = Self::candidates(); + // candidates who explicitly called `submit_candidacy`. Only these folks are at the risk of + // losing their bond. + let mut exposed_candidates = candidates.clone(); + // current members are always a candidate for the next round as well. + // this is guaranteed to not create any duplicates. + candidates.append(&mut Self::members()); + // previous runners_up are also always candidates for the next round. + candidates.append(&mut Self::runners_up()); + // and exposed to being an outgoing in case they are no longer elected. + exposed_candidates.append(&mut Self::runners_up()); + + let voters_and_votes = >::enumerate() + .map(|(v, i)| (v, i)) + .collect::)>>(); + let maybe_phragmen_result = phragmen::elect::<_, _, _, T::CurrencyToVote>( + num_to_elect, + 0, + candidates, + voters_and_votes, + Self::locked_stake_of, + false, + ); + + let mut to_release_bond: Vec = Vec::with_capacity(desired_seats); + let old_members = >::take(); + if let Some(phragmen_result) = maybe_phragmen_result { + // filter out those who had literally no votes at all. + // AUDIT/NOTE: the need to do this is because all candidates, even those who have no + // vote are still considered by phragmen and when good candidates are scarce, then these + // cheap ones might get elected. We might actually want to remove the filter and allow + // zero-voted candidates to also make it to the membership set. + let new_set_with_approval = phragmen_result.winners; + let new_set = new_set_with_approval + .into_iter() + .filter_map(|(m, a)| if a.is_zero() { None } else { Some(m) } ) + .collect::>(); + + // split new set into winners and runner ups. + let split_point = desired_seats.min(new_set.len()); + let mut new_members = (&new_set[..split_point]).to_vec(); + let runners_up = &new_set[split_point..] + .into_iter() + .cloned() + .rev() + .collect::>(); + + // sort and save the members. + new_members.sort(); + >::put(new_members.clone()); + + // save the runners as-is + >::put(runners_up); + + // report member changes. We compute diff because we need the outgoing list. + let (incoming, outgoing) = T::ChangeMembers::compute_members_diff( + &new_members, + &old_members + ); + T::ChangeMembers::change_members_sorted( + &incoming, + &outgoing.clone(), + &new_members + ); + + // unlike exposed_candidates, these are members who were in the list and no longer + // exist. They must get their bond back. + to_release_bond = outgoing.to_vec(); + + // Burn loser bond. members list is sorted. O(NLogM) (N candidates, M members) + // runner up list is not sorted. O(K*N) given K runner ups. Overall: O(NLogM + N*K) + exposed_candidates.into_iter().for_each(|c| { + // any candidate who is not a member and not a runner up. + if new_members.binary_search(&c).is_err() && !runners_up.contains(&c) + { + let (imbalance, _) = T::Currency::slash_reserved(&c, T::CandidacyBond::get()); + T::LoserCandidate::on_unbalanced(imbalance); + } + }); + Self::deposit_event(RawEvent::NewTerm(new_members.to_vec())); + } else { + Self::deposit_event(RawEvent::EmptyTerm); + } + + // unreserve the bond of all the outgoings. + to_release_bond.iter().for_each(|m| { + T::Currency::unreserve(&m, T::CandidacyBond::get()); + }); + + // clean candidates. + >::kill(); + + ElectionRounds::mutate(|v| *v += 1); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::cell::RefCell; + use srml_support::{assert_ok, assert_noop, parameter_types, assert_eq_uvec}; + use runtime_io::with_externalities; + use primitives::{H256, Blake2Hasher}; + use sr_primitives::{Perbill, testing::Header, BuildStorage, + traits::{BlakeTwo256, IdentityLookup, Block as BlockT} + }; + use crate as elections; + + parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + } + + impl system::Trait for Test { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = (); + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type WeightMultiplierUpdate = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + } + + parameter_types! { + pub const ExistentialDeposit: u64 = 1; + pub const TransferFee: u64 = 0; + pub const CreationFee: u64 = 0; + pub const TransactionBaseFee: u64 = 0; + pub const TransactionByteFee: u64 = 0; + } + + impl balances::Trait for Test { + type Balance = u64; + type OnNewAccount = (); + type OnFreeBalanceZero = (); + type Event = Event; + type TransactionPayment = (); + type TransferPayment = (); + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type TransferFee = TransferFee; + type CreationFee = CreationFee; + type TransactionBaseFee = TransactionBaseFee; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = (); + } + + parameter_types! { + pub const CandidacyBond: u64 = 3; + } + + thread_local! { + static VOTING_BOND: RefCell = RefCell::new(2); + static MEMBERS: RefCell> = RefCell::new(vec![]); + } + + pub struct VotingBond; + impl Get for VotingBond { + fn get() -> u64 { VOTING_BOND.with(|v| *v.borrow()) } + } + + pub struct TestChangeMembers; + impl ChangeMembers for TestChangeMembers { + fn change_members_sorted(_: &[u64], _: &[u64], _: &[u64]) {} + } + + /// Simple structure that exposes how u64 currency can be represented as... u64. + pub struct CurrencyToVoteHandler; + impl Convert for CurrencyToVoteHandler { + fn convert(x: u64) -> u64 { x } + } + impl Convert for CurrencyToVoteHandler { + fn convert(x: u128) -> u64 { + x as u64 + } + } + + impl Trait for Test { + type Event = Event; + type Currency = Balances; + type CurrencyToVote = CurrencyToVoteHandler; + type ChangeMembers = TestChangeMembers; + type CandidacyBond = CandidacyBond; + type VotingBond = VotingBond; + type LoserCandidate = (); + type KickedMember = (); + type BadReport = (); + } + + pub type Block = sr_primitives::generic::Block; + pub type UncheckedExtrinsic = sr_primitives::generic::UncheckedExtrinsic; + + srml_support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: system::{Module, Call, Event}, + Balances: balances::{Module, Call, Event, Config}, + Elections: elections::{Module, Call, Event, Config}, + } + ); + + pub struct ExtBuilder { + balance_factor: u64, + voter_bond: u64, + desired_runners_up: u32, + } + + impl Default for ExtBuilder { + fn default() -> Self { + Self { + balance_factor: 1, + voter_bond: 2, + desired_runners_up: 0, + } + } + } + + impl ExtBuilder { + pub fn voter_bond(mut self, fee: u64) -> Self { + self.voter_bond = fee; + self + } + pub fn desired_runners_up(mut self, count: u32) -> Self { + self.desired_runners_up = count; + self + } + pub fn build(self) -> runtime_io::TestExternalities { + VOTING_BOND.with(|v| *v.borrow_mut() = self.voter_bond); + GenesisConfig { + balances: Some(balances::GenesisConfig::{ + balances: vec![ + (1, 10 * self.balance_factor), + (2, 20 * self.balance_factor), + (3, 30 * self.balance_factor), + (4, 40 * self.balance_factor), + (5, 50 * self.balance_factor), + (6, 60 * self.balance_factor) + ], + vesting: vec![], + }), + elections: Some(elections::GenesisConfig::{ + members: vec![], + desired_members: 2, + desired_runners_up: self.desired_runners_up, + term_duration: 5, + }), + }.build_storage().unwrap().into() + } + } + + fn all_voters() -> Vec { + >::enumerate().map(|(v, _)| v).collect::>() + } + + fn balances(who: &u64) -> (u64, u64) { + (Balances::free_balance(who), Balances::reserved_balance(who)) + } + + fn has_lock(who: &u64) -> u64 { + let lock = Balances::locks(who)[0].clone(); + assert_eq!(lock.id, MODULE_ID); + lock.amount + } + + #[test] + fn params_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + System::set_block_number(1); + assert_eq!(Elections::desired_members(), 2); + assert_eq!(Elections::term_duration(), 5); + assert_eq!(Elections::election_rounds(), 0); + + assert_eq!(Elections::members(), vec![]); + assert_eq!(Elections::runners_up(), vec![]); + + assert_eq!(Elections::candidates(), vec![]); + assert_eq!(>::decode_len().unwrap(), 0); + assert!(Elections::is_candidate(&1).is_err()); + + assert_eq!(all_voters(), vec![]); + assert_eq!(Elections::votes_of(&1), vec![]); + }); + } + + #[test] + fn simple_candidate_submission_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(Elections::candidates(), Vec::::new()); + assert!(Elections::is_candidate(&1).is_err()); + assert!(Elections::is_candidate(&2).is_err()); + + assert_eq!(balances(&1), (10, 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(1))); + assert_eq!(balances(&1), (7, 3)); + + assert_eq!(Elections::candidates(), vec![1]); + + assert!(Elections::is_candidate(&1).is_ok()); + assert!(Elections::is_candidate(&2).is_err()); + + assert_eq!(balances(&2), (20, 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + assert_eq!(balances(&2), (17, 3)); + + assert_eq!(Elections::candidates(), vec![1, 2]); + + assert!(Elections::is_candidate(&1).is_ok()); + assert!(Elections::is_candidate(&2).is_ok()); + }); + } + + #[test] + fn simple_candidate_submission_with_no_votes_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(Elections::candidates(), Vec::::new()); + + assert_ok!(Elections::submit_candidacy(Origin::signed(1))); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + + assert!(Elections::is_candidate(&1).is_ok()); + assert!(Elections::is_candidate(&2).is_ok()); + assert_eq!(Elections::candidates(), vec![1, 2]); + + assert_eq!(Elections::members(), vec![]); + assert_eq!(Elections::runners_up(), vec![]); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert!(Elections::is_candidate(&1).is_err()); + assert!(Elections::is_candidate(&2).is_err()); + assert_eq!(Elections::candidates(), vec![]); + + assert_eq!(Elections::members(), vec![]); + assert_eq!(Elections::runners_up(), vec![]); + }); + } + + #[test] + fn dupe_candidate_submission_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(Elections::candidates(), Vec::::new()); + assert_ok!(Elections::submit_candidacy(Origin::signed(1))); + assert_eq!(Elections::candidates(), vec![1]); + assert_noop!( + Elections::submit_candidacy(Origin::signed(1)), + "duplicate candidate submission" + ); + }); + } + + #[test] + fn member_candidacy_submission_should_not_work() { + // critically important to make sure that outgoing candidates and losers are not mixed up. + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![5]); + assert_eq!(Elections::runners_up(), vec![]); + assert_eq!(Elections::candidates(), vec![]); + + assert_noop!( + Elections::submit_candidacy(Origin::signed(5)), + "member cannot re-submit candidacy" + ); + }); + } + + #[test] + fn poor_candidate_submission_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(Elections::candidates(), Vec::::new()); + assert_noop!( + Elections::submit_candidacy(Origin::signed(7)), + "candidate does not have enough funds" + ); + }); + } + + #[test] + fn simple_voting_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(Elections::candidates(), Vec::::new()); + assert_eq!(balances(&2), (20, 0)); + + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); + + assert_eq!(balances(&2), (18, 2)); + assert_eq!(has_lock(&2), 20); + }); + } + + #[test] + fn can_vote_with_custom_stake() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(Elections::candidates(), Vec::::new()); + assert_eq!(balances(&2), (20, 0)); + + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::vote(Origin::signed(2), vec![5], 12)); + + assert_eq!(balances(&2), (18, 2)); + assert_eq!(has_lock(&2), 12); + }); + } + + #[test] + fn can_update_votes_and_stake() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(balances(&2), (20, 0)); + + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); + + assert_eq!(balances(&2), (18, 2)); + assert_eq!(has_lock(&2), 20); + assert_eq!(Elections::stake_of(2), 20); + + // can update; different stake; different lock and reserve. + assert_ok!(Elections::vote(Origin::signed(2), vec![5, 4], 15)); + assert_eq!(balances(&2), (18, 2)); + assert_eq!(has_lock(&2), 15); + assert_eq!(Elections::stake_of(2), 15); + }); + } + + #[test] + fn cannot_vote_for_no_candidate() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_noop!( + Elections::vote(Origin::signed(2), vec![], 20), + "cannot vote when no candidates or members exist" + ); + }); + } + + #[test] + fn can_vote_for_old_members_even_when_no_new_candidates() { + // let allowed_votes = candidates_count as usize + Self::members().len() + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![4, 5], 20)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![4, 5]); + assert_eq!(Elections::candidates(), vec![]); + + assert_ok!(Elections::vote(Origin::signed(3), vec![4, 5], 10)); + }); + } + + #[test] + fn cannot_vote_for_more_than_candidates() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + assert_noop!( + Elections::vote(Origin::signed(2), vec![10, 20, 30], 20), + "cannot vote more than candidates" + ); + }); + } + + #[test] + fn cannot_vote_for_less_than_ed() { + with_externalities(&mut ExtBuilder::default().voter_bond(8).build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + assert_noop!( + Elections::vote(Origin::signed(2), vec![4], 1), + "cannot vote with stake less than minimum balance" + ); + }) + } + + #[test] + fn can_vote_for_more_than_total_balance_but_moot() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![4, 5], 30)); + // you can lie but won't get away with it. + assert_eq!(Elections::stake_of(2), 20); + assert_eq!(has_lock(&2), 20); + }); + } + + #[test] + fn remove_voter_should_work() { + with_externalities(&mut ExtBuilder::default().voter_bond(8).build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); + assert_ok!(Elections::vote(Origin::signed(3), vec![5], 30)); + + assert_eq_uvec!(all_voters(), vec![2, 3]); + assert_eq!(Elections::stake_of(2), 20); + assert_eq!(Elections::stake_of(3), 30); + assert_eq!(Elections::votes_of(2), vec![5]); + assert_eq!(Elections::votes_of(3), vec![5]); + + assert_ok!(Elections::remove_voter(Origin::signed(2))); + + assert_eq_uvec!(all_voters(), vec![3]); + assert_eq!(Elections::votes_of(2), vec![]); + assert_eq!(Elections::stake_of(2), 0); + + assert_eq!(balances(&2), (20, 0)); + assert_eq!(Balances::locks(&2).len(), 0); + }); + } + + #[test] + fn non_voter_remove_should_not_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_noop!(Elections::remove_voter(Origin::signed(3)), "must be a voter"); + }); + } + + #[test] + fn dupe_remove_should_fail() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); + + assert_ok!(Elections::remove_voter(Origin::signed(2))); + assert_eq!(all_voters(), vec![]); + + assert_noop!(Elections::remove_voter(Origin::signed(2)), "must be a voter"); + }); + } + + #[test] + fn removed_voter_should_not_be_counted() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + + assert_ok!(Elections::remove_voter(Origin::signed(4))); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![3, 5]); + }); + } + + #[test] + fn reporter_must_be_voter() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_noop!( + Elections::report_defunct_voter(Origin::signed(1), 2), + "reporter must be a voter", + ); + }); + } + + #[test] + fn can_detect_defunct_voter() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(2), vec![4, 5], 20)); + // will be soon a defunct voter. + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![4, 5]); + assert_eq!(Elections::candidates(), vec![]); + + // all of them have a member that they voted for. + assert_eq!(Elections::is_defunct_voter(&5), false); + assert_eq!(Elections::is_defunct_voter(&4), false); + assert_eq!(Elections::is_defunct_voter(&2), false); + + // defunct + assert_eq!(Elections::is_defunct_voter(&3), true); + + assert_ok!(Elections::submit_candidacy(Origin::signed(1))); + assert_ok!(Elections::vote(Origin::signed(1), vec![1], 10)); + + // has a candidate voted for. + assert_eq!(Elections::is_defunct_voter(&1), false); + + }); + } + + #[test] + fn report_voter_should_work_and_earn_reward() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(2), vec![4, 5], 20)); + // will be soon a defunct voter. + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![4, 5]); + assert_eq!(Elections::candidates(), vec![]); + + assert_eq!(balances(&3), (28, 2)); + assert_eq!(balances(&5), (45, 5)); + + assert_ok!(Elections::report_defunct_voter(Origin::signed(5), 3)); + assert_eq!( + System::events()[1].event, + Event::elections(RawEvent::VoterReported(3, 5, true)) + ); + + assert_eq!(balances(&3), (28, 0)); + assert_eq!(balances(&5), (47, 5)); + }); + } + + #[test] + fn report_voter_should_slash_when_bad_report() { + with_externalities(&mut ExtBuilder::default().build(), || { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![4, 5]); + assert_eq!(Elections::candidates(), vec![]); + + assert_eq!(balances(&4), (35, 5)); + assert_eq!(balances(&5), (45, 5)); + + assert_ok!(Elections::report_defunct_voter(Origin::signed(5), 4)); + assert_eq!( + System::events()[1].event, + Event::elections(RawEvent::VoterReported(4, 5, false)) + ); + + assert_eq!(balances(&4), (35, 5)); + assert_eq!(balances(&5), (45, 3)); + }); + }); + } + + + #[test] + fn simple_voting_rounds_should_work() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 15)); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + + assert_eq_uvec!(all_voters(), vec![2, 3, 4]); + + assert_eq!(Elections::votes_of(2), vec![5]); + assert_eq!(Elections::votes_of(3), vec![3]); + assert_eq!(Elections::votes_of(4), vec![4]); + + assert_eq!(Elections::candidates(), vec![3, 4, 5]); + assert_eq!(>::decode_len().unwrap(), 3); + + assert_eq!(Elections::election_rounds(), 0); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![3, 5]); + assert_eq!(Elections::runners_up(), vec![]); + assert_eq_uvec!(all_voters(), vec![2, 3, 4]); + assert_eq!(Elections::candidates(), vec![]); + assert_eq!(>::decode_len().unwrap(), 0); + + assert_eq!(Elections::election_rounds(), 1); + }); + } + + #[test] + fn defunct_voter_will_be_counted() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + + // This guy's vote is pointless for this round. + assert_ok!(Elections::vote(Origin::signed(3), vec![4], 30)); + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![5]); + assert_eq!(Elections::election_rounds(), 1); + + // but now it has a valid target. + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + System::set_block_number(10); + assert_ok!(Elections::end_block(System::block_number())); + + // candidate 4 is affected by an old vote. + assert_eq!(Elections::members(), vec![4, 5]); + assert_eq!(Elections::election_rounds(), 2); + assert_eq_uvec!(all_voters(), vec![3, 5]); + }); + } + + #[test] + fn only_desired_seats_are_chosen() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::election_rounds(), 1); + assert_eq!(Elections::members(), vec![4, 5]); + }); + } + + #[test] + fn phragmen_should_not_self_vote() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::candidates(), vec![]); + assert_eq!(Elections::election_rounds(), 1); + assert_eq!(Elections::members(), vec![]); + }); + } + + #[test] + fn runners_up_should_be_kept() { + with_externalities(&mut ExtBuilder::default().desired_runners_up(2).build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![3], 20)); + assert_ok!(Elections::vote(Origin::signed(3), vec![2], 30)); + assert_ok!(Elections::vote(Origin::signed(4), vec![5], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![4], 50)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + // sorted based on account id. + assert_eq!(Elections::members(), vec![4, 5]); + // sorted based on merit (least -> most) + assert_eq!(Elections::runners_up(), vec![3, 2]); + + // runner ups are still locked. + assert_eq!(balances(&4), (35, 5)); + assert_eq!(balances(&5), (45, 5)); + assert_eq!(balances(&3), (25, 5)); + }); + } + + #[test] + fn runners_up_should_be_next_candidates() { + with_externalities(&mut ExtBuilder::default().desired_runners_up(2).build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members(), vec![4, 5]); + assert_eq!(Elections::runners_up(), vec![2, 3]); + + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 15)); + + System::set_block_number(10); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members(), vec![3, 4]); + assert_eq!(Elections::runners_up(), vec![5, 2]); + }); + } + + #[test] + fn runners_up_lose_bond_once_outgoing() { + with_externalities(&mut ExtBuilder::default().desired_runners_up(1).build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members(), vec![4, 5]); + + assert_eq!(Elections::runners_up(), vec![2]); + assert_eq!(balances(&2), (15, 5)); + + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + + System::set_block_number(10); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members(), vec![4, 5]); + + assert_eq!(Elections::runners_up(), vec![3]); + assert_eq!(balances(&3), (25, 5)); + assert_eq!(balances(&2), (15, 2)); + }); + } + + #[test] + fn current_members_are_always_implicitly_next_candidate() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![4, 5]); + assert_eq!(Elections::election_rounds(), 1); + + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + + assert_ok!(Elections::remove_voter(Origin::signed(4))); + + // 5 will persist as candidates despite not being in the list. + assert_eq!(Elections::candidates(), vec![2, 3]); + + System::set_block_number(10); + assert_ok!(Elections::end_block(System::block_number())); + + // 4 removed; 5 and 3 are the new best. + assert_eq!(Elections::members(), vec![3, 5]); + }); + } + + #[test] + fn election_state_is_uninterrupted() { + // what I mean by uninterrupted: + // given no input or stimulants the same members are re-elected. + with_externalities(&mut ExtBuilder::default().desired_runners_up(2).build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + + let check_at_block = |b: u32| { + System::set_block_number(b.into()); + assert_ok!(Elections::end_block(System::block_number())); + // we keep re-electing the same folks. + assert_eq!(Elections::members(), vec![4, 5]); + assert_eq!(Elections::runners_up(), vec![2, 3]); + // no new candidates but old members and runners-up are always added. + assert_eq!(Elections::candidates(), vec![]); + assert_eq!(Elections::election_rounds(), b / 5); + assert_eq_uvec!(all_voters(), vec![2, 3, 4, 5]); + }; + + // this state will always persist when no further input is given. + check_at_block(5); + check_at_block(10); + check_at_block(15); + check_at_block(20); + }); + } + + #[test] + fn remove_members_triggers_election() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members(), vec![4, 5]); + assert_eq!(Elections::election_rounds(), 1); + + // a new candidate + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + + assert_ok!(Elections::remove_member(Origin::ROOT, 4)); + + assert_eq!(balances(&4), (35, 2)); // slashed + assert_eq!(Elections::election_rounds(), 2); // new election round + assert_eq!(Elections::members(), vec![3, 5]); // new members + }); + } + + #[test] + fn seats_should_be_released_when_no_vote() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![3], 20)); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + + assert_eq!(>::decode_len().unwrap(), 3); + + assert_eq!(Elections::election_rounds(), 0); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members(), vec![3, 5]); + assert_eq!(Elections::election_rounds(), 1); + + assert_ok!(Elections::remove_voter(Origin::signed(2))); + assert_ok!(Elections::remove_voter(Origin::signed(3))); + assert_ok!(Elections::remove_voter(Origin::signed(4))); + assert_ok!(Elections::remove_voter(Origin::signed(5))); + + // meanwhile, no one cares to become a candidate again. + System::set_block_number(10); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members(), vec![]); + assert_eq!(Elections::election_rounds(), 2); + }); + } + + #[test] + fn outgoing_will_get_the_bond_back() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_eq!(balances(&5), (50, 0)); + + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_eq!(balances(&5), (47, 3)); + + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_eq!(balances(&5), (45, 5)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members(), vec![5]); + + assert_ok!(Elections::remove_voter(Origin::signed(5))); + assert_eq!(balances(&5), (47, 3)); + + System::set_block_number(10); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members(), vec![]); + + assert_eq!(balances(&5), (50, 0)); + }); + } + + #[test] + fn losers_will_lose_the_bond() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + + assert_ok!(Elections::vote(Origin::signed(4), vec![5], 40)); + + assert_eq!(balances(&5), (47, 3)); + assert_eq!(balances(&3), (27, 3)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![5]); + + // winner + assert_eq!(balances(&5), (47, 3)); + // loser + assert_eq!(balances(&3), (27, 0)); + }); + } + + #[test] + fn incoming_outgoing_are_reported() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members(), vec![4, 5]); + + assert_ok!(Elections::submit_candidacy(Origin::signed(1))); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + + // 5 will change their vote and becomes an `outgoing` + assert_ok!(Elections::vote(Origin::signed(5), vec![4], 8)); + // 4 will stay in the set + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + // 3 will become a winner + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + // these two are losers. + assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + assert_ok!(Elections::vote(Origin::signed(1), vec![1], 10)); + + System::set_block_number(10); + assert_ok!(Elections::end_block(System::block_number())); + + // 3, 4 are new members, must still be bonded, nothing slashed. + assert_eq!(Elections::members(), vec![3, 4]); + assert_eq!(balances(&3), (25, 5)); + assert_eq!(balances(&4), (35, 5)); + + // 1 is a loser, slashed by 3. + assert_eq!(balances(&1), (5, 2)); + + // 5 is an outgoing loser, it will get their bond back. + assert_eq!(balances(&5), (48, 2)); + + assert_eq!(System::events()[0].event, Event::elections(RawEvent::NewTerm(vec![4, 5]))); + }) + } + + #[test] + fn invalid_votes_are_moot() { + with_externalities(&mut ExtBuilder::default().build(), || { + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![10], 50)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq_uvec!(Elections::members(), vec![3, 4]); + assert_eq!(Elections::election_rounds(), 1); + }); + } +} diff --git a/srml/elections/src/lib.rs b/srml/elections/src/lib.rs index 1cd3258cf7..3aff5d4b2e 100644 --- a/srml/elections/src/lib.rs +++ b/srml/elections/src/lib.rs @@ -1054,7 +1054,6 @@ impl Module { /// Return true of the bit `n` of scalar `x` is set to `1` and false otherwise. fn bit_at(x: ApprovalFlag, n: usize) -> bool { if n < APPROVAL_FLAG_LEN { - // x & ( APPROVAL_FLAG_MASK >> n ) != 0 x & ( 1 << n ) != 0 } else { false diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index 7f371a3c7b..831629f5f2 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -1241,7 +1241,7 @@ impl Module { ); if let Some(phragmen_result) = maybe_phragmen_result { - let elected_stashes = phragmen_result.winners; + let elected_stashes = phragmen_result.winners.iter().map(|(s, _)| s.clone()).collect::>(); let mut assignments = phragmen_result.assignments; // helper closure. @@ -1284,7 +1284,8 @@ impl Module { } } - if cfg!(feature = "equalize") { + #[cfg(feature = "equalize")] + { let tolerance = 0_u128; let iterations = 2_usize; equalize::<_, _, _, T::CurrencyToVote>( diff --git a/srml/support/src/traits.rs b/srml/support/src/traits.rs index 8eeb10c374..905486dddf 100644 --- a/srml/support/src/traits.rs +++ b/srml/support/src/traits.rs @@ -659,6 +659,16 @@ pub trait ChangeMembers { /// Set the new members; they **must already be sorted**. This will compute the diff and use it to /// call `change_members_sorted`. fn set_members_sorted(new_members: &[AccountId], old_members: &[AccountId]) { + let (incoming, outgoing) = Self::compute_members_diff(new_members, old_members); + Self::change_members_sorted(&incoming[..], &outgoing[..], &new_members); + } + + /// Set the new members; they **must already be sorted**. This will compute the diff and use it to + /// call `change_members_sorted`. + fn compute_members_diff( + new_members: &[AccountId], + old_members: &[AccountId] + ) -> (Vec, Vec) { let mut old_iter = old_members.iter(); let mut new_iter = new_members.iter(); let mut incoming = Vec::new(); @@ -686,8 +696,7 @@ pub trait ChangeMembers { } } } - - Self::change_members_sorted(&incoming[..], &outgoing[..], &new_members); + (incoming, outgoing) } } -- GitLab From d320249e1740c2e02ecd8fcbc5b4dee48d5e18ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 19 Sep 2019 12:04:48 +0200 Subject: [PATCH 110/275] Force new era only if 1/3 validators is disabled. (#3533) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Force new era only when over third validators is disabled. * Update srml/session/src/lib.rs Co-Authored-By: Bastian Köcher * Update srml/staking/src/lib.rs Co-Authored-By: Bastian Köcher * Parametrize the threshold. * Bump runtime version. * Update node/runtime/src/lib.rs * Fix build. * Fix im-online test. --- node/runtime/src/lib.rs | 4 ++ srml/authority-discovery/src/lib.rs | 5 +++ srml/im-online/src/mock.rs | 5 +++ srml/session/src/lib.rs | 69 ++++++++++++++++++++++++++--- srml/session/src/mock.rs | 5 +++ srml/staking/src/lib.rs | 17 ++++--- srml/staking/src/mock.rs | 2 + 7 files changed, 95 insertions(+), 12 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 0c1a229ab2..f6955d2bd0 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -211,6 +211,9 @@ impl_opaque_keys! { // `SessionKeys`. // TODO: Introduce some structure to tie these together to make it a bit less of a footgun. This // should be easy, since OneSessionHandler trait provides the `Key` as an associated type. #2858 +parameter_types! { + pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17); +} impl session::Trait for Runtime { type OnSessionEnding = Staking; @@ -221,6 +224,7 @@ impl session::Trait for Runtime { type ValidatorId = AccountId; type ValidatorIdOf = staking::StashOf; type SelectInitialValidators = Staking; + type DisabledValidatorsThreshold = DisabledValidatorsThreshold; } impl session::historical::Trait for Runtime { diff --git a/srml/authority-discovery/src/lib.rs b/srml/authority-discovery/src/lib.rs index 372a48cc7f..8032b46be4 100644 --- a/srml/authority-discovery/src/lib.rs +++ b/srml/authority-discovery/src/lib.rs @@ -155,6 +155,10 @@ mod tests { } } + parameter_types! { + pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(33); + } + impl session::Trait for Test { type OnSessionEnding = TestOnSessionEnding; type Keys = UintAuthorityId; @@ -164,6 +168,7 @@ mod tests { type ValidatorId = AuthorityId; type ValidatorIdOf = ConvertInto; type SelectInitialValidators = (); + type DisabledValidatorsThreshold = DisabledValidatorsThreshold; } impl session::historical::Trait for Test { diff --git a/srml/im-online/src/mock.rs b/srml/im-online/src/mock.rs index ba1a7a7d0a..a7b669ddb8 100644 --- a/srml/im-online/src/mock.rs +++ b/srml/im-online/src/mock.rs @@ -125,6 +125,10 @@ parameter_types! { pub const Offset: u64 = 0; } +parameter_types! { + pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(33); +} + impl session::Trait for Runtime { type ShouldEndSession = session::PeriodicSessions; type OnSessionEnding = session::historical::NoteHistoricalRoot; @@ -134,6 +138,7 @@ impl session::Trait for Runtime { type Keys = UintAuthorityId; type Event = (); type SelectInitialValidators = (); + type DisabledValidatorsThreshold = DisabledValidatorsThreshold; } impl session::historical::Trait for Runtime { diff --git a/srml/session/src/lib.rs b/srml/session/src/lib.rs index 8edb80e8cb..1494f88413 100644 --- a/srml/session/src/lib.rs +++ b/srml/session/src/lib.rs @@ -121,7 +121,7 @@ use rstd::{prelude::*, marker::PhantomData, ops::{Sub, Rem}}; use codec::Decode; -use sr_primitives::{KeyTypeId, RuntimeAppPublic}; +use sr_primitives::{KeyTypeId, Perbill, RuntimeAppPublic}; use sr_primitives::weights::SimpleDispatchInfo; use sr_primitives::traits::{Convert, Zero, Member, OpaqueKeys}; use sr_staking_primitives::SessionIndex; @@ -334,6 +334,12 @@ pub trait Trait: system::Trait { /// The keys. type Keys: OpaqueKeys + Member + Parameter + Default; + /// The fraction of validators set that is safe to be disabled. + /// + /// After the threshold is reached `disabled` method starts to return true, + /// which in combination with `srml_staking` forces a new era. + type DisabledValidatorsThreshold: Get; + /// Select initial validators. type SelectInitialValidators: SelectInitialValidators; } @@ -356,6 +362,11 @@ decl_storage! { /// will be used to determine the validator's session keys. QueuedKeys get(queued_keys): Vec<(T::ValidatorId, T::Keys)>; + /// Indices of disabled validators. + /// + /// The set is cleared when `on_session_ending` returns a new set of identities. + DisabledValidators get(disabled_validators): Vec; + /// The next session keys for a validator. /// /// The first key is always `DEDUP_KEY_PREFIX` to have all the data in the same branch of @@ -475,6 +486,11 @@ impl Module { .collect::>(); >::put(&validators); + if changed { + // reset disabled validators + DisabledValidators::take(); + } + let applied_at = session_index + 2; // Get next validator set. @@ -539,13 +555,36 @@ impl Module { } /// Disable the validator of index `i`. - pub fn disable_index(i: usize) { - T::SessionHandler::on_disabled(i); + /// + /// Returns `true` if this causes a `DisabledValidatorsThreshold` of validators + /// to be already disabled. + pub fn disable_index(i: usize) -> bool { + let (fire_event, threshold_reached) = DisabledValidators::mutate(|disabled| { + let i = i as u32; + if let Err(index) = disabled.binary_search(&i) { + let count = >::decode_len().unwrap_or(0) as u32; + let threshold = T::DisabledValidatorsThreshold::get() * count; + disabled.insert(index, i); + (true, disabled.len() as u32 > threshold) + } else { + (false, false) + } + }); + + if fire_event { + T::SessionHandler::on_disabled(i); + } + + threshold_reached } - /// Disable the validator identified by `c`. (If using with the staking module, this would be - /// their *stash* account.) - pub fn disable(c: &T::ValidatorId) -> rstd::result::Result<(), ()> { + /// Disable the validator identified by `c`. (If using with the staking module, + /// this would be their *stash* account.) + /// + /// Returns `Ok(true)` if more than `DisabledValidatorsThreshold` validators in current + /// session is already disabled. + /// If used with the staking module it allows to force a new era in such case. + pub fn disable(c: &T::ValidatorId) -> rstd::result::Result { Self::validators().iter().position(|i| i == c).map(Self::disable_index).ok_or(()) } @@ -924,4 +963,22 @@ mod tests { ); }); } + + #[test] + fn return_true_if_more_than_third_is_disabled() { + with_externalities(&mut new_test_ext(), || { + set_next_validators(vec![1, 2, 3, 4, 5, 6, 7]); + force_new_session(); + initialize_block(1); + // apply the new validator set + force_new_session(); + initialize_block(2); + + assert_eq!(Session::disable_index(0), false); + assert_eq!(Session::disable_index(1), false); + assert_eq!(Session::disable_index(2), true); + assert_eq!(Session::disable_index(3), true); + }); + + } } diff --git a/srml/session/src/mock.rs b/srml/session/src/mock.rs index fe9a4ee936..736d3fa4da 100644 --- a/srml/session/src/mock.rs +++ b/srml/session/src/mock.rs @@ -183,6 +183,10 @@ impl timestamp::Trait for Test { type MinimumPeriod = MinimumPeriod; } +parameter_types! { + pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(33); +} + impl Trait for Test { type ShouldEndSession = TestShouldEndSession; #[cfg(feature = "historical")] @@ -195,6 +199,7 @@ impl Trait for Test { type Keys = MockSessionKeys; type Event = (); type SelectInitialValidators = (); + type DisabledValidatorsThreshold = DisabledValidatorsThreshold; } #[cfg(feature = "historical")] diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index 831629f5f2..3f88b67875 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -454,7 +454,11 @@ type MomentOf= <::Time as Time>::Moment; /// This is needed because `Staking` sets the `ValidatorIdOf` of the `session::Trait` pub trait SessionInterface: system::Trait { /// Disable a given validator by stash ID. - fn disable_validator(validator: &AccountId) -> Result<(), ()>; + /// + /// Returns `true` if new era should be forced at the end of this session. + /// This allows preventing a situation where there is too many validators + /// disabled and block production stalls. + fn disable_validator(validator: &AccountId) -> Result; /// Get the validators from session. fn validators() -> Vec; /// Prune historical session tries up to but not including the given index. @@ -472,7 +476,7 @@ impl SessionInterface<::AccountId> for T where T::SelectInitialValidators: session::SelectInitialValidators<::AccountId>, T::ValidatorIdOf: Convert<::AccountId, Option<::AccountId>> { - fn disable_validator(validator: &::AccountId) -> Result<(), ()> { + fn disable_validator(validator: &::AccountId) -> Result { >::disable(validator) } @@ -1531,10 +1535,11 @@ impl OnOffenceHandler; @@ -160,6 +161,7 @@ impl session::Trait for Test { type ValidatorId = AccountId; type ValidatorIdOf = crate::StashOf; type SelectInitialValidators = Staking; + type DisabledValidatorsThreshold = DisabledValidatorsThreshold; } impl session::historical::Trait for Test { -- GitLab From 37bc8c5459b29f3db3b8ed2d7f44b5398e1e1f3c Mon Sep 17 00:00:00 2001 From: Ashley Date: Thu, 19 Sep 2019 23:06:11 +1200 Subject: [PATCH 111/275] srml-contract: Rename Contract::create to instantiate (#3645) * Rename Contract::create to Contract::instantiate * Rename some documentation items * fixed node executor test * bumped impl_version * increased spec_version --- node/executor/src/lib.rs | 2 +- srml/contracts/COMPLEXITY.md | 4 ++-- srml/contracts/src/lib.rs | 8 ++++---- srml/contracts/src/tests.rs | 38 ++++++++++++++++++------------------ 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index e399b5c02e..bcff17683e 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -673,7 +673,7 @@ mod tests { CheckedExtrinsic { signed: Some((charlie(), signed_extra(1, 0))), function: Call::Contracts( - contracts::Call::create::(1 * DOLLARS, 10_000, transfer_ch, Vec::new()) + contracts::Call::instantiate::(1 * DOLLARS, 10_000, transfer_ch, Vec::new()) ), }, CheckedExtrinsic { diff --git a/srml/contracts/COMPLEXITY.md b/srml/contracts/COMPLEXITY.md index c582de4264..55aa8f60b4 100644 --- a/srml/contracts/COMPLEXITY.md +++ b/srml/contracts/COMPLEXITY.md @@ -317,13 +317,13 @@ It consists of the following steps: 1. Loading `init_code` buffer from the sandbox memory (see sandboxing memory get) and then decoding it. 2. Loading `value` buffer from the sandbox memory and then decoding it. 3. Loading `input_data` buffer from the sandbox memory. -4. Invoking `create` executive function. +4. Invoking `instantiate` executive function. Loading of `value` buffer should be charged. This is because the size of the buffer is specified by the calling code, even though marshaled representation is, essentially, of constant size. This can be fixed by assigning an upper bound for size for `Balance`. Loading `init_code` and `input_data` should be charged in any case. -**complexity**: All complexity comes from loading buffers and executing `create` executive function. The former component is proportional to the sizes of `init_code`, `value` and `input_data` buffers. The latter component completely depends on the complexity of `create` executive function and also dominated by it. +**complexity**: All complexity comes from loading buffers and executing `instantiate` executive function. The former component is proportional to the sizes of `init_code`, `value` and `input_data` buffers. The latter component completely depends on the complexity of `instantiate` executive function and also dominated by it. ## ext_return diff --git a/srml/contracts/src/lib.rs b/srml/contracts/src/lib.rs index ef4ccab721..1a369c1122 100644 --- a/srml/contracts/src/lib.rs +++ b/srml/contracts/src/lib.rs @@ -59,7 +59,7 @@ //! ### Dispatchable functions //! //! * `put_code` - Stores the given binary Wasm code into the chain's storage and returns its `code_hash`. -//! * `create` - Deploys a new contract from the given `code_hash`, optionally transferring some balance. +//! * `instantiate` - Deploys a new contract from the given `code_hash`, optionally transferring some balance. //! This creates a new smart contract account and calls its contract deploy handler to initialize the contract. //! * `call` - Makes a call to an account, optionally transferring some balance. //! @@ -590,7 +590,7 @@ decl_module! { /// after the execution is saved as the `code` of the account. That code will be invoked /// upon any call received by this account. /// - The contract is initialized. - pub fn create( + pub fn instantiate( origin, #[compact] endowment: BalanceOf, #[compact] gas_limit: Gas, @@ -812,7 +812,7 @@ decl_event! { ::AccountId, ::Hash { - /// Transfer happened `from` to `to` with given `value` as part of a `call` or `create`. + /// Transfer happened `from` to `to` with given `value` as part of a `call` or `instantiate`. Transfer(AccountId, AccountId, Balance), /// Contract deployed by address at the specified address. @@ -1018,7 +1018,7 @@ impl SignedExtension for CheckBlockGasLimit { Ok(ValidTransaction::default()), Call::put_code(gas_limit, _) | Call::call(_, _, gas_limit, _) - | Call::create(_, gas_limit, _, _) + | Call::instantiate(_, gas_limit, _, _) => { // Check if the specified amount of gas is available in the current block. // This cannot underflow since `gas_spent` is never greater than `T::BlockGasLimit`. diff --git a/srml/contracts/src/tests.rs b/srml/contracts/src/tests.rs index f585eddb59..fd016ec67c 100644 --- a/srml/contracts/src/tests.rs +++ b/srml/contracts/src/tests.rs @@ -425,7 +425,7 @@ fn instantiate_and_call_and_deposit_event() { assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); // Check at the end to get hash on error easily - let creation = Contract::create( + let creation = Contract::instantiate( Origin::signed(ALICE), 100, 100_000, @@ -522,7 +522,7 @@ fn dispatch_call() { }, ]); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 100, 100_000, @@ -643,7 +643,7 @@ fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { }, ]); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 100, 100_000, @@ -859,7 +859,7 @@ fn storage_size() { // Create Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 30_000, 100_000, code_hash.into(), @@ -889,7 +889,7 @@ fn deduct_blocks() { // Create Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 30_000, 100_000, code_hash.into(), @@ -986,7 +986,7 @@ fn claim_surcharge(blocks: u64, trigger_call: impl Fn() -> bool, removes: bool) // Create Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 100, 100_000, code_hash.into(), @@ -1022,7 +1022,7 @@ fn removals(trigger_call: impl Fn() -> bool) { // Create Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 100, 100_000, code_hash.into(), @@ -1061,7 +1061,7 @@ fn removals(trigger_call: impl Fn() -> bool) { // Create Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 1_000, 100_000, code_hash.into(), @@ -1099,7 +1099,7 @@ fn removals(trigger_call: impl Fn() -> bool) { // Create Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 50+Balances::minimum_balance(), 100_000, code_hash.into(), @@ -1146,7 +1146,7 @@ fn call_removed_contract() { // Create Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 100, 100_000, code_hash.into(), @@ -1234,7 +1234,7 @@ fn default_rent_allowance_on_create() { // Create Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 30_000, 100_000, @@ -1374,7 +1374,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: // Create an account with address `BOB` with code `CODE_SET_RENT`. // The input parameter sets the rent allowance to 0. - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 30_000, 100_000, @@ -1411,7 +1411,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: /// Note that we can't use `ALICE` for creating `DJANGO` so we create yet another /// account `CHARLIE` and create `DJANGO` with it. Balances::deposit_creating(&CHARLIE, 1_000_000); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(CHARLIE), 30_000, 100_000, @@ -1537,7 +1537,7 @@ fn storage_max_value_limit() { // Create Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 30_000, 100_000, @@ -1906,7 +1906,7 @@ fn deploy_and_call_other_contract() { assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, callee_wasm)); assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, caller_wasm)); - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 100_000, 100_000, @@ -2036,7 +2036,7 @@ fn self_destruct_by_draining_balance() { assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); // Instantiate the BOB contract. - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 100_000, 100_000, @@ -2075,7 +2075,7 @@ fn cannot_self_destruct_while_live() { assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); // Instantiate the BOB contract. - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 100_000, 100_000, @@ -2280,7 +2280,7 @@ fn destroy_contract_and_transfer_funds() { // This deploys the BOB contract, which in turn deploys the CHARLIE contract during // construction. - assert_ok!(Contract::create( + assert_ok!(Contract::instantiate( Origin::signed(ALICE), 200_000, 100_000, @@ -2378,7 +2378,7 @@ fn cannot_self_destruct_in_constructor() { // Fail to instantiate the BOB contract since its final balance is below existential // deposit. assert_err!( - Contract::create( + Contract::instantiate( Origin::signed(ALICE), 100_000, 100_000, -- GitLab From 13fc71c681cc9a3cc911c32c7890b52885092969 Mon Sep 17 00:00:00 2001 From: Weiliang Li Date: Thu, 19 Sep 2019 23:49:24 +0900 Subject: [PATCH 112/275] fn import_block -> fn block_import_params in SimpleSlotWorker (#3647) --- core/consensus/aura/src/lib.rs | 6 +++--- core/consensus/babe/src/lib.rs | 6 +++--- core/consensus/slots/src/lib.rs | 12 ++++++------ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/core/consensus/aura/src/lib.rs b/core/consensus/aura/src/lib.rs index fd0ab30c9a..585fbc522f 100644 --- a/core/consensus/aura/src/lib.rs +++ b/core/consensus/aura/src/lib.rs @@ -245,7 +245,7 @@ impl slots::SimpleSlotWorker for AuraWorker Box Box, @@ -541,7 +541,7 @@ impl Verifier for AuraVerifier where _ => None, }); - let import_block = BlockImportParams { + let block_import_params = BlockImportParams { origin, header: pre_header, post_digests: vec![seal], @@ -552,7 +552,7 @@ impl Verifier for AuraVerifier where fork_choice: ForkChoiceStrategy::LongestChain, }; - Ok((import_block, maybe_keys)) + Ok((block_import_params, maybe_keys)) } CheckedHeader::Deferred(a, b) => { debug!(target: "aura", "Checking {:?} failed; {:?}, {:?}.", hash, a, b); diff --git a/core/consensus/babe/src/lib.rs b/core/consensus/babe/src/lib.rs index c9c80eb1e9..acb66038de 100644 --- a/core/consensus/babe/src/lib.rs +++ b/core/consensus/babe/src/lib.rs @@ -324,7 +324,7 @@ impl slots::SimpleSlotWorker for BabeWorker Box Box, @@ -879,7 +879,7 @@ impl Verifier for BabeVerifier Verifier for BabeVerifier { debug!(target: "babe", "Checking {:?} failed; {:?}, {:?}.", hash, a, b); diff --git a/core/consensus/slots/src/lib.rs b/core/consensus/slots/src/lib.rs index fadb311f7d..bcceb62bb6 100644 --- a/core/consensus/slots/src/lib.rs +++ b/core/consensus/slots/src/lib.rs @@ -95,7 +95,7 @@ pub trait SimpleSlotWorker { fn pre_digest_data(&self, slot_number: u64, claim: &Self::Claim) -> Vec>; /// Returns a function which produces a `BlockImportParams`. - fn import_block(&self) -> Box Box, @@ -198,7 +198,7 @@ pub trait SimpleSlotWorker { futures::future::Either::Right((Err(err), _)) => Err(err), }); - let import_block = self.import_block(); + let block_import_params_maker = self.block_import_params(); let block_import = self.block_import(); let logging_target = self.logging_target(); @@ -223,7 +223,7 @@ pub trait SimpleSlotWorker { let header_hash = header.hash(); let parent_hash = header.parent_hash().clone(); - let import_block = import_block( + let block_import_params = block_import_params_maker( header, &header_hash, body, @@ -232,17 +232,17 @@ pub trait SimpleSlotWorker { info!("Pre-sealed block for proposal at {}. Hash now {:?}, previously {:?}.", header_num, - import_block.post_header().hash(), + block_import_params.post_header().hash(), header_hash, ); telemetry!(CONSENSUS_INFO; "slots.pre_sealed_block"; "header_num" => ?header_num, - "hash_now" => ?import_block.post_header().hash(), + "hash_now" => ?block_import_params.post_header().hash(), "hash_previously" => ?header_hash, ); - if let Err(err) = block_import.lock().import_block(import_block, Default::default()) { + if let Err(err) = block_import.lock().import_block(block_import_params, Default::default()) { warn!(target: logging_target, "Error with block built on {:?}: {:?}", parent_hash, -- GitLab From c3ac647f21e519f7f409e1319ad9b2da979ba7f9 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 20 Sep 2019 09:49:15 +0300 Subject: [PATCH 113/275] Blockchain cache pruning strategy (#3395) * blockchain cache pruning strategy * added some internal docs to cache_pruning_strategy * Update core/client/db/src/cache/mod.rs Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> --- core/client/db/src/cache/list_cache.rs | 145 +++++++++++++--------- core/client/db/src/cache/mod.rs | 21 +++- core/client/db/src/lib.rs | 3 +- core/client/db/src/light.rs | 8 +- core/client/src/backend.rs | 3 +- core/client/src/blockchain.rs | 16 ++- core/client/src/client.rs | 2 +- core/client/src/in_mem.rs | 3 +- core/client/src/lib.rs | 2 + core/client/src/light/backend.rs | 3 +- core/client/src/light/blockchain.rs | 8 +- core/consensus/aura/src/lib.rs | 3 +- core/consensus/babe/src/lib.rs | 4 +- core/consensus/common/src/block_import.rs | 7 +- core/consensus/common/src/import_queue.rs | 5 +- core/consensus/common/src/lib.rs | 12 -- core/consensus/pow/src/lib.rs | 3 +- core/finality-grandpa/src/import.rs | 4 +- core/finality-grandpa/src/light_import.rs | 3 +- core/network/src/test/mod.rs | 10 +- 20 files changed, 161 insertions(+), 104 deletions(-) diff --git a/core/client/db/src/cache/list_cache.rs b/core/client/db/src/cache/list_cache.rs index 188012e78f..9095b80fb6 100644 --- a/core/client/db/src/cache/list_cache.rs +++ b/core/client/db/src/cache/list_cache.rs @@ -52,12 +52,21 @@ use crate::cache::{CacheItemT, ComplexBlockId, EntryType}; use crate::cache::list_entry::{Entry, StorageEntry}; use crate::cache::list_storage::{Storage, StorageTransaction, Metadata}; +/// Pruning strategy. +#[derive(Debug, Clone, Copy)] +pub enum PruningStrategy { + /// Prune entries when they're too far behind best finalized block. + ByDepth(N), + /// Do not prune old entries at all. + NeverPrune, +} + /// List-based cache. pub struct ListCache> { /// Cache storage. storage: S, - /// Prune depth. - prune_depth: NumberFor, + /// Pruning strategy. + pruning_strategy: PruningStrategy>, /// Best finalized block. best_finalized_block: ComplexBlockId, /// Best finalized entry (if exists). @@ -107,7 +116,11 @@ pub enum ForkAppendResult { impl> ListCache { /// Create new db list cache entry. - pub fn new(storage: S, prune_depth: NumberFor, best_finalized_block: ComplexBlockId) -> Self { + pub fn new( + storage: S, + pruning_strategy: PruningStrategy>, + best_finalized_block: ComplexBlockId, + ) -> Self { let (best_finalized_entry, unfinalized) = storage.read_meta() .and_then(|meta| read_forks(&storage, meta)) .unwrap_or_else(|error| { @@ -117,7 +130,7 @@ impl> ListCache ListCache { storage, - prune_depth, + pruning_strategy, best_finalized_block, best_finalized_entry, unfinalized, @@ -362,9 +375,14 @@ impl> ListCache tx: &mut Tx, block: &ComplexBlockId ) { + let prune_depth = match self.pruning_strategy { + PruningStrategy::ByDepth(prune_depth) => prune_depth, + PruningStrategy::NeverPrune => return, + }; + let mut do_pruning = || -> ClientResult<()> { // calculate last ancient block number - let ancient_block = match block.number.checked_sub(&self.prune_depth) { + let ancient_block = match block.number.checked_sub(&prune_depth) { Some(number) => match self.storage.read_id(number)? { Some(hash) => ComplexBlockId::new(hash, number), None => return Ok(()), @@ -669,7 +687,7 @@ pub mod tests { // when block is earlier than best finalized block AND it is not finalized // --- 50 --- // ----------> [100] - assert_eq!(ListCache::<_, u64, _>::new(DummyStorage::new(), 1024, test_id(100)) + assert_eq!(ListCache::<_, u64, _>::new(DummyStorage::new(), PruningStrategy::ByDepth(1024), test_id(100)) .value_at_block(&test_id(50)).unwrap(), None); // when block is earlier than best finalized block AND it is finalized AND value is some // [30] ---- 50 ---> [100] @@ -679,7 +697,7 @@ pub mod tests { .with_id(50, H256::from_low_u64_be(50)) .with_entry(test_id(100), StorageEntry { prev_valid_from: Some(test_id(30)), value: 100 }) .with_entry(test_id(30), StorageEntry { prev_valid_from: None, value: 30 }), - 1024, test_id(100) + PruningStrategy::ByDepth(1024), test_id(100) ).value_at_block(&test_id(50)).unwrap(), Some((test_id(30), Some(test_id(100)), 30))); // when block is the best finalized block AND value is some // ---> [100] @@ -689,7 +707,7 @@ pub mod tests { .with_id(100, H256::from_low_u64_be(100)) .with_entry(test_id(100), StorageEntry { prev_valid_from: Some(test_id(30)), value: 100 }) .with_entry(test_id(30), StorageEntry { prev_valid_from: None, value: 30 }), - 1024, test_id(100) + PruningStrategy::ByDepth(1024), test_id(100) ).value_at_block(&test_id(100)).unwrap(), Some((test_id(100), None, 100))); // when block is parallel to the best finalized block // ---- 100 @@ -700,7 +718,7 @@ pub mod tests { .with_id(50, H256::from_low_u64_be(50)) .with_entry(test_id(100), StorageEntry { prev_valid_from: Some(test_id(30)), value: 100 }) .with_entry(test_id(30), StorageEntry { prev_valid_from: None, value: 30 }), - 1024, test_id(100) + PruningStrategy::ByDepth(1024), test_id(100) ).value_at_block(&ComplexBlockId::new(H256::from_low_u64_be(2), 100)).unwrap(), None); // when block is later than last finalized block AND there are no forks AND finalized value is Some @@ -710,7 +728,7 @@ pub mod tests { .with_meta(Some(test_id(100)), Vec::new()) .with_id(50, H256::from_low_u64_be(50)) .with_entry(test_id(100), StorageEntry { prev_valid_from: Some(test_id(30)), value: 100 }), - 1024, test_id(100) + PruningStrategy::ByDepth(1024), test_id(100) ).value_at_block(&test_id(200)).unwrap(), Some((test_id(100), None, 100))); // when block is later than last finalized block AND there are no matching forks @@ -726,7 +744,7 @@ pub mod tests { .with_header(test_header(3)) .with_header(test_header(4)) .with_header(fork_header(0, 2, 3)), - 1024, test_id(2) + PruningStrategy::ByDepth(1024), test_id(2) ).value_at_block(&fork_id(0, 2, 3)).unwrap(), Some((correct_id(2), None, 2))); // when block is later than last finalized block AND there are no matching forks // AND block is not connected to finalized block @@ -743,7 +761,7 @@ pub mod tests { .with_header(test_header(4)) .with_header(fork_header(0, 1, 3)) .with_header(fork_header(0, 1, 2)), - 1024, test_id(2) + PruningStrategy::ByDepth(1024), test_id(2) ).value_at_block(&fork_id(0, 1, 3)).unwrap(), None); // when block is later than last finalized block AND it appends to unfinalized fork from the end @@ -756,7 +774,7 @@ pub mod tests { .with_entry(correct_id(4), StorageEntry { prev_valid_from: Some(correct_id(2)), value: 4 }) .with_header(test_header(4)) .with_header(test_header(5)), - 1024, test_id(2) + PruningStrategy::ByDepth(1024), test_id(2) ).value_at_block(&correct_id(5)).unwrap(), Some((correct_id(4), None, 4))); // when block is later than last finalized block AND it does not fits unfinalized fork // AND it is connected to the finalized block AND finalized value is Some @@ -771,7 +789,7 @@ pub mod tests { .with_header(test_header(3)) .with_header(test_header(4)) .with_header(fork_header(0, 2, 3)), - 1024, test_id(2) + PruningStrategy::ByDepth(1024), test_id(2) ).value_at_block(&fork_id(0, 2, 3)).unwrap(), Some((correct_id(2), None, 2))); } @@ -781,7 +799,7 @@ pub mod tests { let fin = EntryType::Final; // when trying to insert block < finalized number - assert!(ListCache::new(DummyStorage::new(), 1024, test_id(100)) + assert!(ListCache::new(DummyStorage::new(), PruningStrategy::ByDepth(1024), test_id(100)) .on_block_insert( &mut DummyTransaction::new(), test_id(49), @@ -790,7 +808,7 @@ pub mod tests { nfin, ).unwrap().is_none()); // when trying to insert block @ finalized number - assert!(ListCache::new(DummyStorage::new(), 1024, test_id(100)) + assert!(ListCache::new(DummyStorage::new(), PruningStrategy::ByDepth(1024), test_id(100)) .on_block_insert( &mut DummyTransaction::new(), test_id(99), @@ -805,7 +823,7 @@ pub mod tests { DummyStorage::new() .with_meta(None, vec![test_id(4)]) .with_entry(test_id(4), StorageEntry { prev_valid_from: None, value: 4 }), - 1024, test_id(2) + PruningStrategy::ByDepth(1024), test_id(2) ); cache.unfinalized[0].best_block = Some(test_id(4)); let mut tx = DummyTransaction::new(); @@ -830,7 +848,7 @@ pub mod tests { .with_meta(None, vec![correct_id(4)]) .with_entry(correct_id(4), StorageEntry { prev_valid_from: None, value: 4 }) .with_header(test_header(4)), - 1024, test_id(2) + PruningStrategy::ByDepth(1024), test_id(2) ); let mut tx = DummyTransaction::new(); assert_eq!(cache.on_block_insert(&mut tx, correct_id(4), correct_id(5), Some(4), nfin).unwrap(), @@ -856,7 +874,7 @@ pub mod tests { .with_header(test_header(2)) .with_header(test_header(3)) .with_header(test_header(4)), - 1024, correct_id(2) + PruningStrategy::ByDepth(1024), correct_id(2) ); let mut tx = DummyTransaction::new(); assert_eq!(cache.on_block_insert(&mut tx, correct_id(3), fork_id(0, 3, 4), Some(14), nfin).unwrap(), @@ -871,7 +889,7 @@ pub mod tests { DummyStorage::new() .with_meta(Some(correct_id(2)), vec![]) .with_entry(correct_id(2), StorageEntry { prev_valid_from: None, value: 2 }), - 1024, correct_id(2) + PruningStrategy::ByDepth(1024), correct_id(2) ); let mut tx = DummyTransaction::new(); assert_eq!(cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(2), nfin).unwrap(), None); @@ -884,7 +902,7 @@ pub mod tests { DummyStorage::new() .with_meta(Some(correct_id(2)), vec![]) .with_entry(correct_id(2), StorageEntry { prev_valid_from: None, value: 2 }), - 1024, correct_id(2) + PruningStrategy::ByDepth(1024), correct_id(2) ); let mut tx = DummyTransaction::new(); assert_eq!(cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(3), nfin).unwrap(), @@ -894,7 +912,7 @@ pub mod tests { assert_eq!(*tx.updated_meta(), Some(Metadata { finalized: Some(correct_id(2)), unfinalized: vec![correct_id(3)] })); // when inserting finalized entry AND there are no previous finalized entries - let cache = ListCache::new(DummyStorage::new(), 1024, correct_id(2)); + let cache = ListCache::new(DummyStorage::new(), PruningStrategy::ByDepth(1024), correct_id(2)); let mut tx = DummyTransaction::new(); assert_eq!( cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(3), fin).unwrap(), @@ -912,7 +930,7 @@ pub mod tests { DummyStorage::new() .with_meta(Some(correct_id(2)), vec![]) .with_entry(correct_id(2), StorageEntry { prev_valid_from: None, value: 2 }), - 1024, correct_id(2) + PruningStrategy::ByDepth(1024), correct_id(2) ); let mut tx = DummyTransaction::new(); assert_eq!(cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(2), fin).unwrap(), @@ -940,7 +958,7 @@ pub mod tests { .with_meta(Some(correct_id(2)), vec![fork_id(0, 1, 3)]) .with_entry(correct_id(2), StorageEntry { prev_valid_from: None, value: 2 }) .with_entry(fork_id(0, 1, 3), StorageEntry { prev_valid_from: None, value: 13 }), - 1024, correct_id(2) + PruningStrategy::ByDepth(1024), correct_id(2) ); let mut tx = DummyTransaction::new(); assert_eq!(cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(2), fin).unwrap(), @@ -955,7 +973,7 @@ pub mod tests { .with_meta(Some(correct_id(2)), vec![correct_id(5)]) .with_entry(correct_id(2), StorageEntry { prev_valid_from: None, value: 2 }) .with_entry(correct_id(5), StorageEntry { prev_valid_from: Some(correct_id(2)), value: 5 }), - 1024, correct_id(2) + PruningStrategy::ByDepth(1024), correct_id(2) ); let mut tx = DummyTransaction::new(); assert_eq!(cache.on_block_finalize(&mut tx, correct_id(2), correct_id(3)).unwrap(), @@ -969,7 +987,7 @@ pub mod tests { .with_meta(Some(correct_id(2)), vec![correct_id(5)]) .with_entry(correct_id(2), StorageEntry { prev_valid_from: None, value: 2 }) .with_entry(correct_id(5), StorageEntry { prev_valid_from: Some(correct_id(2)), value: 5 }), - 1024, correct_id(4) + PruningStrategy::ByDepth(1024), correct_id(4) ); let mut tx = DummyTransaction::new(); assert_eq!( @@ -989,7 +1007,7 @@ pub mod tests { .with_meta(Some(correct_id(2)), vec![fork_id(0, 1, 3)]) .with_entry(correct_id(2), StorageEntry { prev_valid_from: None, value: 2 }) .with_entry(fork_id(0, 1, 3), StorageEntry { prev_valid_from: None, value: 13 }), - 1024, correct_id(2) + PruningStrategy::ByDepth(1024), correct_id(2) ); let mut tx = DummyTransaction::new(); assert_eq!(cache.on_block_finalize(&mut tx, correct_id(2), correct_id(3)).unwrap(), @@ -1004,7 +1022,7 @@ pub mod tests { .with_entry(correct_id(2), StorageEntry { prev_valid_from: None, value: 2 }) .with_entry(correct_id(5), StorageEntry { prev_valid_from: Some(correct_id(2)), value: 5 }) .with_entry(correct_id(6), StorageEntry { prev_valid_from: Some(correct_id(5)), value: 6 }), - 1024, correct_id(2) + PruningStrategy::ByDepth(1024), correct_id(2) ); // when new block is appended to unfinalized fork @@ -1043,7 +1061,7 @@ pub mod tests { .with_header(test_header(3)) .with_header(test_header(4)) .with_header(test_header(5)), - 1024, correct_id(0) + PruningStrategy::ByDepth(1024), correct_id(0) ).find_unfinalized_fork(&correct_id(4)).unwrap().unwrap().head.valid_from, correct_id(5)); // --- [2] ---------------> [5] // ----------> [3] ---> 4 @@ -1060,7 +1078,7 @@ pub mod tests { .with_header(fork_header(0, 1, 2)) .with_header(fork_header(0, 1, 3)) .with_header(fork_header(0, 1, 4)), - 1024, correct_id(0) + PruningStrategy::ByDepth(1024), correct_id(0) ).find_unfinalized_fork(&fork_id(0, 1, 4)).unwrap().unwrap().head.valid_from, fork_id(0, 1, 3)); // --- [2] ---------------> [5] // ----------> [3] @@ -1080,7 +1098,7 @@ pub mod tests { .with_header(fork_header(1, 1, 2)) .with_header(fork_header(1, 1, 3)) .with_header(fork_header(1, 1, 4)), - 1024, correct_id(0) + PruningStrategy::ByDepth(1024), correct_id(0) ).find_unfinalized_fork(&fork_id(1, 1, 4)).unwrap().is_none()); } @@ -1341,32 +1359,45 @@ pub mod tests { } #[test] - fn ancient_entries_are_pruned() { - let cache = ListCache::new(DummyStorage::new() - .with_id(10, H256::from_low_u64_be(10)) - .with_id(20, H256::from_low_u64_be(20)) - .with_id(30, H256::from_low_u64_be(30)) - .with_entry(test_id(10), StorageEntry { prev_valid_from: None, value: 10 }) - .with_entry(test_id(20), StorageEntry { prev_valid_from: Some(test_id(10)), value: 20 }) - .with_entry(test_id(30), StorageEntry { prev_valid_from: Some(test_id(20)), value: 30 }), - 10, test_id(9)); - let mut tx = DummyTransaction::new(); + fn ancient_entries_are_pruned_when_pruning_enabled() { + fn do_test(strategy: PruningStrategy) { + let cache = ListCache::new(DummyStorage::new() + .with_id(10, H256::from_low_u64_be(10)) + .with_id(20, H256::from_low_u64_be(20)) + .with_id(30, H256::from_low_u64_be(30)) + .with_entry(test_id(10), StorageEntry { prev_valid_from: None, value: 10 }) + .with_entry(test_id(20), StorageEntry { prev_valid_from: Some(test_id(10)), value: 20 }) + .with_entry(test_id(30), StorageEntry { prev_valid_from: Some(test_id(20)), value: 30 }), + strategy, test_id(9)); + let mut tx = DummyTransaction::new(); + + // when finalizing entry #10: no entries pruned + cache.prune_finalized_entries(&mut tx, &test_id(10)); + assert!(tx.removed_entries().is_empty()); + assert!(tx.inserted_entries().is_empty()); + // when finalizing entry #19: no entries pruned + cache.prune_finalized_entries(&mut tx, &test_id(19)); + assert!(tx.removed_entries().is_empty()); + assert!(tx.inserted_entries().is_empty()); + // when finalizing entry #20: no entries pruned + cache.prune_finalized_entries(&mut tx, &test_id(20)); + assert!(tx.removed_entries().is_empty()); + assert!(tx.inserted_entries().is_empty()); + // when finalizing entry #30: entry 10 pruned + entry 20 is truncated (if pruning is enabled) + cache.prune_finalized_entries(&mut tx, &test_id(30)); + match strategy { + PruningStrategy::NeverPrune => { + assert!(tx.removed_entries().is_empty()); + assert!(tx.inserted_entries().is_empty()); + }, + PruningStrategy::ByDepth(_) => { + assert_eq!(*tx.removed_entries(), vec![test_id(10).hash].into_iter().collect()); + assert_eq!(*tx.inserted_entries(), vec![test_id(20).hash].into_iter().collect()); + }, + } + } - // when finalizing entry #10: no entries pruned - cache.prune_finalized_entries(&mut tx, &test_id(10)); - assert!(tx.removed_entries().is_empty()); - assert!(tx.inserted_entries().is_empty()); - // when finalizing entry #19: no entries pruned - cache.prune_finalized_entries(&mut tx, &test_id(19)); - assert!(tx.removed_entries().is_empty()); - assert!(tx.inserted_entries().is_empty()); - // when finalizing entry #20: no entries pruned - cache.prune_finalized_entries(&mut tx, &test_id(20)); - assert!(tx.removed_entries().is_empty()); - assert!(tx.inserted_entries().is_empty()); - // when finalizing entry #30: entry 10 pruned + entry 20 is truncated - cache.prune_finalized_entries(&mut tx, &test_id(30)); - assert_eq!(*tx.removed_entries(), vec![test_id(10).hash].into_iter().collect()); - assert_eq!(*tx.inserted_entries(), vec![test_id(20).hash].into_iter().collect()); + do_test(PruningStrategy::ByDepth(10)); + do_test(PruningStrategy::NeverPrune) } } diff --git a/core/client/db/src/cache/mod.rs b/core/client/db/src/cache/mod.rs index f53eb54ca0..6f7d1bf47d 100644 --- a/core/client/db/src/cache/mod.rs +++ b/core/client/db/src/cache/mod.rs @@ -21,15 +21,14 @@ use parking_lot::RwLock; use kvdb::{KeyValueDB, DBTransaction}; -use client::blockchain::Cache as BlockchainCache; +use client::blockchain::{well_known_cache_keys::{self, Id as CacheKeyId}, Cache as BlockchainCache}; use client::error::Result as ClientResult; use codec::{Encode, Decode}; use sr_primitives::generic::BlockId; use sr_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero}; -use consensus_common::well_known_cache_keys::Id as CacheKeyId; use crate::utils::{self, COLUMN_META, db_err}; -use self::list_cache::ListCache; +use self::list_cache::{ListCache, PruningStrategy}; mod list_cache; mod list_entry; @@ -166,7 +165,7 @@ fn get_cache_helper<'a, Block: BlockT>( cache, }, ), - PRUNE_DEPTH.into(), + cache_pruning_strategy(name), best_finalized_block.clone(), ) }) @@ -335,3 +334,17 @@ impl BlockchainCache for DbCacheSync { } } +/// Get pruning strategy for given cache. +fn cache_pruning_strategy>(cache: CacheKeyId) -> PruningStrategy { + // the cache is mostly used to store data from consensus engines + // this kind of data is only required for non-finalized blocks + // => by default we prune finalized cached entries + + match cache { + // we need to keep changes tries configurations forever (or at least until changes tries, + // that were built using this configuration, are pruned) to make it possible to refer + // to old changes tries + well_known_cache_keys::CHANGES_TRIE_CONFIG => PruningStrategy::NeverPrune, + _ => PruningStrategy::ByDepth(PRUNE_DEPTH.into()), + } +} diff --git a/core/client/db/src/lib.rs b/core/client/db/src/lib.rs index 1a0b2331d3..62cc8027c2 100644 --- a/core/client/db/src/lib.rs +++ b/core/client/db/src/lib.rs @@ -39,7 +39,7 @@ use std::io; use std::collections::{HashMap, HashSet}; use client::backend::NewBlockState; -use client::blockchain::HeaderBackend; +use client::blockchain::{well_known_cache_keys, HeaderBackend}; use client::ExecutionStrategies; use client::backend::{StorageCollection, ChildStorageCollection}; use codec::{Decode, Encode}; @@ -65,7 +65,6 @@ use crate::utils::{Meta, db_err, meta_keys, read_db, block_id_to_lookup_key, rea use client::leaves::{LeafSet, FinalizationDisplaced}; use client::children; use state_db::StateDb; -use consensus_common::well_known_cache_keys; use crate::storage_cache::{CachingState, SharedCache, new_shared_cache}; use log::{trace, debug, warn}; pub use state_db::PruningMode; diff --git a/core/client/db/src/light.rs b/core/client/db/src/light.rs index 2d100dad29..07f805495c 100644 --- a/core/client/db/src/light.rs +++ b/core/client/db/src/light.rs @@ -23,8 +23,11 @@ use parking_lot::RwLock; use kvdb::{KeyValueDB, DBTransaction}; use client::backend::{AuxStore, NewBlockState}; -use client::blockchain::{BlockStatus, Cache as BlockchainCache, - HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo}; +use client::blockchain::{ + BlockStatus, Cache as BlockchainCache, + HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo, + well_known_cache_keys, +}; use client::cht; use client::error::{Error as ClientError, Result as ClientResult}; use client::light::blockchain::Storage as LightBlockchainStorage; @@ -32,7 +35,6 @@ use codec::{Decode, Encode}; use primitives::Blake2Hasher; use sr_primitives::generic::{DigestItem, BlockId}; use sr_primitives::traits::{Block as BlockT, Header as HeaderT, Zero, One, NumberFor}; -use consensus_common::well_known_cache_keys; use crate::cache::{DbCacheSync, DbCache, ComplexBlockId, EntryType as CacheEntryType}; use crate::utils::{self, meta_keys, Meta, db_err, read_db, block_id_to_lookup_key, read_meta}; use crate::DatabaseSettings; diff --git a/core/client/src/backend.rs b/core/client/src/backend.rs index e7b5045336..9b6d9ce58f 100644 --- a/core/client/src/backend.rs +++ b/core/client/src/backend.rs @@ -25,7 +25,8 @@ use sr_primitives::{generic::BlockId, Justification, StorageOverlay, ChildrenSto use sr_primitives::traits::{Block as BlockT, NumberFor}; use state_machine::backend::Backend as StateBackend; use state_machine::{ChangesTrieStorage as StateChangesTrieStorage, ChangesTrieTransaction}; -use consensus::{well_known_cache_keys, BlockOrigin}; +use crate::blockchain::well_known_cache_keys; +use consensus::BlockOrigin; use hash_db::Hasher; use parking_lot::Mutex; diff --git a/core/client/src/blockchain.rs b/core/client/src/blockchain.rs index 9c9c915388..a6edb8505a 100644 --- a/core/client/src/blockchain.rs +++ b/core/client/src/blockchain.rs @@ -21,7 +21,6 @@ use std::sync::Arc; use sr_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor}; use sr_primitives::generic::BlockId; use sr_primitives::Justification; -use consensus::well_known_cache_keys; use crate::error::{Error, Result}; @@ -254,3 +253,18 @@ pub fn tree_route) -> Result< { block: StoredBlock, diff --git a/core/client/src/lib.rs b/core/client/src/lib.rs index 3919b3970f..636a1e4df6 100644 --- a/core/client/src/lib.rs +++ b/core/client/src/lib.rs @@ -124,6 +124,8 @@ pub use crate::notifications::{StorageEventStream, StorageChangeSet}; pub use state_machine::ExecutionStrategy; #[cfg(feature = "std")] pub use crate::leaves::LeafSet; +#[cfg(feature = "std")] +pub use crate::blockchain::well_known_cache_keys; #[doc(inline)] pub use sr_api_macros::{decl_runtime_apis, impl_runtime_apis}; diff --git a/core/client/src/light/backend.rs b/core/client/src/light/backend.rs index 5f44c03e21..300d140630 100644 --- a/core/client/src/light/backend.rs +++ b/core/client/src/light/backend.rs @@ -29,12 +29,11 @@ use crate::backend::{ AuxStore, Backend as ClientBackend, BlockImportOperation, RemoteBackend, NewBlockState, StorageCollection, ChildStorageCollection, }; -use crate::blockchain::HeaderBackend as BlockchainHeaderBackend; +use crate::blockchain::{HeaderBackend as BlockchainHeaderBackend, well_known_cache_keys}; use crate::error::{Error as ClientError, Result as ClientResult}; use crate::light::blockchain::{Blockchain, Storage as BlockchainStorage}; use hash_db::Hasher; use trie::MemoryDB; -use consensus::well_known_cache_keys; const IN_MEMORY_EXPECT_PROOF: &str = "InMemory state backend has Void error type and always succeeds; qed"; diff --git a/core/client/src/light/blockchain.rs b/core/client/src/light/blockchain.rs index 1e1a7669a0..8fef351b7c 100644 --- a/core/client/src/light/blockchain.rs +++ b/core/client/src/light/blockchain.rs @@ -22,11 +22,13 @@ use std::{sync::Arc, collections::HashMap}; use sr_primitives::{Justification, generic::BlockId}; use sr_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero}; -use consensus::well_known_cache_keys; use crate::backend::{AuxStore, NewBlockState}; -use crate::blockchain::{Backend as BlockchainBackend, BlockStatus, Cache as BlockchainCache, - HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo, ProvideCache}; +use crate::blockchain::{ + Backend as BlockchainBackend, BlockStatus, Cache as BlockchainCache, + HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo, ProvideCache, + well_known_cache_keys, +}; use crate::cht; use crate::error::{Error as ClientError, Result as ClientResult}; use crate::light::fetcher::{Fetcher, RemoteHeaderRequest}; diff --git a/core/consensus/aura/src/lib.rs b/core/consensus/aura/src/lib.rs index 585fbc522f..3c60128dd3 100644 --- a/core/consensus/aura/src/lib.rs +++ b/core/consensus/aura/src/lib.rs @@ -33,7 +33,7 @@ use std::{sync::Arc, time::Duration, thread, marker::PhantomData, hash::Hash, fm use codec::{Encode, Decode, Codec}; use consensus_common::{self, BlockImport, Environment, Proposer, ForkChoiceStrategy, BlockImportParams, BlockOrigin, Error as ConsensusError, - SelectChain, well_known_cache_keys::{self, Id as CacheKeyId} + SelectChain, }; use consensus_common::import_queue::{ Verifier, BasicQueue, BoxBlockImport, BoxJustificationImport, BoxFinalityProofImport, @@ -41,6 +41,7 @@ use consensus_common::import_queue::{ use client::{ block_builder::api::BlockBuilder as BlockBuilderApi, blockchain::ProvideCache, runtime_api::ApiExt, error::Result as CResult, backend::AuxStore, BlockOf, + well_known_cache_keys::{self, Id as CacheKeyId}, }; use sr_primitives::{generic::{BlockId, OpaqueDigestItemId}, Justification}; diff --git a/core/consensus/babe/src/lib.rs b/core/consensus/babe/src/lib.rs index acb66038de..7816f81d47 100644 --- a/core/consensus/babe/src/lib.rs +++ b/core/consensus/babe/src/lib.rs @@ -65,7 +65,6 @@ use consensus_common::ImportResult; use consensus_common::import_queue::{ BoxJustificationImport, BoxFinalityProofImport, }; -use consensus_common::well_known_cache_keys::Id as CacheKeyId; use sr_primitives::{generic::{BlockId, OpaqueDigestItemId}, Justification}; use sr_primitives::traits::{ Block as BlockT, Header, DigestItemFor, NumberFor, ProvideRuntimeApi, @@ -96,7 +95,7 @@ use srml_babe::{ BabeInherentData, timestamp::{TimestampInherentData, InherentType as TimestampInherent} }; -use consensus_common::{SelectChain, well_known_cache_keys}; +use consensus_common::SelectChain; use consensus_common::import_queue::{Verifier, BasicQueue}; use client::{ block_builder::api::BlockBuilder as BlockBuilderApi, @@ -104,6 +103,7 @@ use client::{ runtime_api::ApiExt, error::Result as ClientResult, backend::{AuxStore, Backend}, ProvideUncles, utils::is_descendent_of, + well_known_cache_keys::{self, Id as CacheKeyId}, }; use fork_tree::ForkTree; use slots::{CheckedHeader, check_equivocation}; diff --git a/core/consensus/common/src/block_import.rs b/core/consensus/common/src/block_import.rs index 02f7979e9c..bcafb352cd 100644 --- a/core/consensus/common/src/block_import.rs +++ b/core/consensus/common/src/block_import.rs @@ -21,9 +21,8 @@ use sr_primitives::Justification; use std::borrow::Cow; use std::collections::HashMap; use std::sync::Arc; -use crate::well_known_cache_keys; -use crate::import_queue::Verifier; +use crate::import_queue::{Verifier, CacheKeyId}; /// Block import result. #[derive(Debug, PartialEq, Eq)] @@ -182,7 +181,7 @@ pub trait BlockImport { fn import_block( &mut self, block: BlockImportParams, - cache: HashMap>, + cache: HashMap>, ) -> Result; } @@ -202,7 +201,7 @@ where for<'r> &'r T: BlockImport fn import_block( &mut self, block: BlockImportParams, - cache: HashMap>, + cache: HashMap>, ) -> Result { (&**self).import_block(block, cache) } diff --git a/core/consensus/common/src/import_queue.rs b/core/consensus/common/src/import_queue.rs index f4febb5e23..533df2b179 100644 --- a/core/consensus/common/src/import_queue.rs +++ b/core/consensus/common/src/import_queue.rs @@ -27,7 +27,7 @@ use std::collections::HashMap; use sr_primitives::{Justification, traits::{Block as BlockT, Header as _, NumberFor}}; -use crate::{error::Error as ConsensusError, well_known_cache_keys::Id as CacheKeyId}; +use crate::error::Error as ConsensusError; use crate::block_import::{ BlockImport, BlockOrigin, BlockImportParams, ImportedAux, JustificationImport, ImportResult, FinalityProofImport, @@ -65,6 +65,9 @@ pub struct IncomingBlock { pub origin: Option, } +/// Type of keys in the blockchain cache that consensus module could use for its needs. +pub type CacheKeyId = [u8; 4]; + /// Verify a justification of a block pub trait Verifier: Send + Sync { /// Verify the given data and return the BlockImportParams and an optional diff --git a/core/consensus/common/src/lib.rs b/core/consensus/common/src/lib.rs index 3fd0a0c694..a79bd157e2 100644 --- a/core/consensus/common/src/lib.rs +++ b/core/consensus/common/src/lib.rs @@ -117,15 +117,3 @@ where T: ?Sized, for<'r> &'r T: SyncOracle <&T>::is_offline(&mut &**self) } } - -/// A list of all well known keys in the cache. -pub mod well_known_cache_keys { - /// The type representing cache keys. - pub type Id = [u8; 4]; - - /// A list of authorities. - pub const AUTHORITIES: Id = *b"auth"; - - /// Current Epoch data. - pub const EPOCH: Id = *b"epch"; -} diff --git a/core/consensus/pow/src/lib.rs b/core/consensus/pow/src/lib.rs index 343c7b14c6..8bc0d3593a 100644 --- a/core/consensus/pow/src/lib.rs +++ b/core/consensus/pow/src/lib.rs @@ -35,6 +35,7 @@ use std::collections::HashMap; use client::{ BlockOf, blockchain::{HeaderBackend, ProvideCache}, block_builder::api::BlockBuilder as BlockBuilderApi, backend::AuxStore, + well_known_cache_keys::Id as CacheKeyId, }; use sr_primitives::Justification; use sr_primitives::generic::{BlockId, Digest, DigestItem}; @@ -45,7 +46,7 @@ use primitives::H256; use inherents::{InherentDataProviders, InherentData}; use consensus_common::{ BlockImportParams, BlockOrigin, ForkChoiceStrategy, - well_known_cache_keys::Id as CacheKeyId, Environment, Proposer, + Environment, Proposer, }; use consensus_common::import_queue::{BoxBlockImport, BasicQueue, Verifier}; use codec::{Encode, Decode}; diff --git a/core/finality-grandpa/src/import.rs b/core/finality-grandpa/src/import.rs index e72914b7c2..8f7124b3d3 100644 --- a/core/finality-grandpa/src/import.rs +++ b/core/finality-grandpa/src/import.rs @@ -21,14 +21,14 @@ use codec::Encode; use futures::sync::mpsc; use parking_lot::RwLockWriteGuard; -use client::{blockchain, CallExecutor, Client}; +use client::{blockchain, CallExecutor, Client, well_known_cache_keys}; use client::blockchain::HeaderBackend; use client::backend::Backend; use client::runtime_api::ApiExt; use client::utils::is_descendent_of; use consensus_common::{ BlockImport, Error as ConsensusError, - BlockImportParams, ImportResult, JustificationImport, well_known_cache_keys, + BlockImportParams, ImportResult, JustificationImport, SelectChain, }; use fg_primitives::GrandpaApi; diff --git a/core/finality-grandpa/src/light_import.rs b/core/finality-grandpa/src/light_import.rs index f57bcaebed..053daa81a8 100644 --- a/core/finality-grandpa/src/light_import.rs +++ b/core/finality-grandpa/src/light_import.rs @@ -24,10 +24,11 @@ use client::{ backend::{AuxStore, Backend, Finalizer}, blockchain::HeaderBackend, error::Error as ClientError, + well_known_cache_keys, }; use codec::{Encode, Decode}; use consensus_common::{ - import_queue::Verifier, well_known_cache_keys, + import_queue::Verifier, BlockOrigin, BlockImport, FinalityProofImport, BlockImportParams, ImportResult, ImportedAux, Error as ConsensusError, }; diff --git a/core/network/src/test/mod.rs b/core/network/src/test/mod.rs index 5fd67acd1b..8cceeeaae6 100644 --- a/core/network/src/test/mod.rs +++ b/core/network/src/test/mod.rs @@ -28,10 +28,12 @@ use crate::config::build_multiaddr; use log::trace; use crate::chain::FinalityProofProvider; use client::{ - self, ClientInfo, BlockchainEvents, BlockImportNotification, FinalityNotifications, ImportNotifications, - FinalityNotification, LongestChain + self, ClientInfo, BlockchainEvents, BlockImportNotification, + FinalityNotifications, ImportNotifications, + FinalityNotification, LongestChain, + error::Result as ClientResult, + well_known_cache_keys::{self, Id as CacheKeyId}, }; -use client::error::Result as ClientResult; use client::block_builder::BlockBuilder; use client::backend::{AuxStore, Backend, Finalizer}; use crate::config::Roles; @@ -40,7 +42,7 @@ use consensus::import_queue::{ BoxBlockImport, BoxJustificationImport, Verifier, BoxFinalityProofImport, }; use consensus::block_import::{BlockImport, ImportResult}; -use consensus::{Error as ConsensusError, well_known_cache_keys::{self, Id as CacheKeyId}}; +use consensus::Error as ConsensusError; use consensus::{BlockOrigin, ForkChoiceStrategy, BlockImportParams, JustificationImport}; use futures::prelude::*; use futures03::{StreamExt as _, TryStreamExt as _}; -- GitLab From 8d30872dec7b17e120c810024d7a71edc810ae4c Mon Sep 17 00:00:00 2001 From: Ashley Date: Fri, 20 Sep 2019 20:53:03 +1200 Subject: [PATCH 114/275] Finish off srml-contract create -> instantiate renamings (#3649) * Finish off srml-contract create -> instantiate renamings * bumped spec_version --- srml/contracts/COMPLEXITY.md | 6 +++--- srml/contracts/src/lib.rs | 4 ++-- srml/contracts/src/tests.rs | 12 ++++++------ srml/contracts/src/wasm/mod.rs | 6 +++--- srml/contracts/src/wasm/runtime.rs | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/srml/contracts/COMPLEXITY.md b/srml/contracts/COMPLEXITY.md index 55aa8f60b4..1e306038ef 100644 --- a/srml/contracts/COMPLEXITY.md +++ b/srml/contracts/COMPLEXITY.md @@ -223,9 +223,9 @@ Finally, all changes are `commit`-ted into the underlying overlay. The complexit - Only for the first invocation of the contract: up to 5 DB reads and one DB write as well as logic executed by `ensure_can_withdraw`, `withdraw`, `make_free_balance_be`. - On top of that for every invocation: Up to 5 DB reads. DB read of the code is of dynamic size. There can also be up to 2 DB writes (if flushed to the storage). Additionally, if the source account removal takes place a DB write will be performed per one storage entry that the account has. -## Create +## Instantiate -This function takes the code of the constructor and input data. Creation of a contract consists of the following steps: +This function takes the code of the constructor and input data. Instantiation of a contract consists of the following steps: 1. Initialization of the execution context. 2. Calling `DetermineContractAddress` hook to determine an address for the contract, @@ -303,7 +303,7 @@ Loading `input_data` should be charged in any case. **complexity**: All complexity comes from loading buffers and executing `call` executive function. The former component is proportional to the sizes of `callee`, `value` and `input_data` buffers. The latter component completely depends on the complexity of `call` executive function, and also dominated by it. -## ext_create +## ext_instantiate This function receives the following arguments: diff --git a/srml/contracts/src/lib.rs b/srml/contracts/src/lib.rs index 1a369c1122..615f6c8b99 100644 --- a/srml/contracts/src/lib.rs +++ b/srml/contracts/src/lib.rs @@ -580,9 +580,9 @@ decl_module! { .map_err(|e| e.reason) } - /// Creates a new contract from the `codehash` generated by `put_code`, optionally transferring some balance. + /// Instantiates a new contract from the `codehash` generated by `put_code`, optionally transferring some balance. /// - /// Creation is executed as follows: + /// Instantiation is executed as follows: /// /// - The destination address is computed based on the sender and hash of the code. /// - The smart-contract account is created at the computed address. diff --git a/srml/contracts/src/tests.rs b/srml/contracts/src/tests.rs index fd016ec67c..fc58a51d95 100644 --- a/srml/contracts/src/tests.rs +++ b/srml/contracts/src/tests.rs @@ -1621,7 +1621,7 @@ const CODE_CALLER_CONTRACT: &str = r#" (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) (import "env" "ext_balance" (func $ext_balance)) (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "ext_create" (func $ext_create (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "env" "ext_instantiate" (func $ext_instantiate (param i32 i32 i64 i32 i32 i32 i32) (result i32))) (import "env" "ext_println" (func $ext_println (param i32 i32))) (import "env" "memory" (memory 1 1)) @@ -1677,7 +1677,7 @@ const CODE_CALLER_CONTRACT: &str = r#" ;; Fail to deploy the contract since it returns a non-zero exit status. (set_local $exit_code - (call $ext_create + (call $ext_instantiate (i32.const 24) ;; Pointer to the code hash. (i32.const 32) ;; Length of the code hash. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. @@ -1705,7 +1705,7 @@ const CODE_CALLER_CONTRACT: &str = r#" ;; Fail to deploy the contract due to insufficient gas. (set_local $exit_code - (call $ext_create + (call $ext_instantiate (i32.const 24) ;; Pointer to the code hash. (i32.const 32) ;; Length of the code hash. (i64.const 200) ;; How much gas to devote for the execution. @@ -1733,7 +1733,7 @@ const CODE_CALLER_CONTRACT: &str = r#" ;; Deploy the contract successfully. (set_local $exit_code - (call $ext_create + (call $ext_instantiate (i32.const 24) ;; Pointer to the code hash. (i32.const 32) ;; Length of the code hash. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. @@ -2118,7 +2118,7 @@ const CODE_DESTROY_AND_TRANSFER: &str = r#" (import "env" "ext_get_storage" (func $ext_get_storage (param i32) (result i32))) (import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32 i32))) (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "ext_create" (func $ext_create (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "env" "ext_instantiate" (func $ext_instantiate (param i32 i32 i64 i32 i32 i32 i32) (result i32))) (import "env" "memory" (memory 1 1)) (func $assert (param i32) @@ -2149,7 +2149,7 @@ const CODE_DESTROY_AND_TRANSFER: &str = r#" ;; Deploy the contract with the provided code hash. (call $assert (i32.eq - (call $ext_create + (call $ext_instantiate (i32.const 48) ;; Pointer to the code hash. (i32.const 32) ;; Length of the code hash. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. diff --git a/srml/contracts/src/wasm/mod.rs b/srml/contracts/src/wasm/mod.rs index 9d48738ed1..68ea126338 100644 --- a/srml/contracts/src/wasm/mod.rs +++ b/srml/contracts/src/wasm/mod.rs @@ -478,7 +478,7 @@ mod tests { const CODE_CREATE: &str = r#" (module - ;; ext_create( + ;; ext_instantiate( ;; code_ptr: u32, ;; code_len: u32, ;; gas: u64, @@ -487,11 +487,11 @@ mod tests { ;; input_data_ptr: u32, ;; input_data_len: u32, ;; ) -> u32 - (import "env" "ext_create" (func $ext_create (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "env" "ext_instantiate" (func $ext_instantiate (param i32 i32 i64 i32 i32 i32 i32) (result i32))) (import "env" "memory" (memory 1 1)) (func (export "call") (drop - (call $ext_create + (call $ext_instantiate (i32.const 16) ;; Pointer to `code_hash` (i32.const 32) ;; Length of `code_hash` (i64.const 0) ;; How much gas to devote for the execution. 0 = all. diff --git a/srml/contracts/src/wasm/runtime.rs b/srml/contracts/src/wasm/runtime.rs index 573132cf31..beab043ce2 100644 --- a/srml/contracts/src/wasm/runtime.rs +++ b/srml/contracts/src/wasm/runtime.rs @@ -29,7 +29,7 @@ use rstd::mem; use codec::{Decode, Encode}; use sr_primitives::traits::{Bounded, SaturatedConversion}; -/// The value returned from ext_call and ext_create contract external functions if the call or +/// The value returned from ext_call and ext_instantiate contract external functions if the call or /// instantiation traps. This value is chosen as if the execution does not trap, the return value /// will always be an 8-bit integer, so 0x0100 is the smallest value that could not be returned. const TRAP_RETURN_CODE: u32 = 0x0100; @@ -456,7 +456,7 @@ define_env!(Env, , // - value_len: length of the value buffer. // - input_data_ptr: a pointer to a buffer to be used as input data to the initializer code. // - input_data_len: length of the input data buffer. - ext_create( + ext_instantiate( ctx, code_hash_ptr: u32, code_hash_len: u32, -- GitLab From c12e1d1f6ed7f59f58e30310078c6c6553ceb780 Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Fri, 20 Sep 2019 15:26:14 +0200 Subject: [PATCH 115/275] Use `ThreadPool::spawn_ok()` instead of `ThreadPool::spawn()` (#3656) * Bump futures-timer to v0.3 * Bump futures-preview to v0.3.0-alpha.18 * Replace ThreadPoll::spawn() with ThreadPoll::spawn_ok() --- Cargo.lock | 117 +++++++++--------- core/basic-authorship/Cargo.toml | 2 +- core/cli/Cargo.toml | 2 +- core/client/Cargo.toml | 2 +- core/consensus/aura/Cargo.toml | 4 +- core/consensus/babe/Cargo.toml | 4 +- core/consensus/common/Cargo.toml | 4 +- .../common/src/import_queue/basic_queue.rs | 6 +- core/consensus/pow/Cargo.toml | 2 +- core/consensus/slots/Cargo.toml | 4 +- core/finality-grandpa/Cargo.toml | 2 +- core/network/Cargo.toml | 4 +- core/offchain/Cargo.toml | 4 +- core/peerset/Cargo.toml | 2 +- core/rpc/Cargo.toml | 2 +- core/rpc/api/Cargo.toml | 2 +- core/service/Cargo.toml | 2 +- core/telemetry/Cargo.toml | 4 +- core/test-client/Cargo.toml | 2 +- core/transaction-pool/graph/Cargo.toml | 2 +- node/cli/Cargo.toml | 2 +- 21 files changed, 86 insertions(+), 89 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c420e94106..c861209f68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -966,16 +966,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-channel-preview" -version = "0.3.0-alpha.17" +version = "0.3.0-alpha.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-core-preview" -version = "0.3.0-alpha.17" +version = "0.3.0-alpha.18" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -989,60 +989,59 @@ dependencies = [ [[package]] name = "futures-executor-preview" -version = "0.3.0-alpha.17" +version = "0.3.0-alpha.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-channel-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-io-preview" -version = "0.3.0-alpha.17" +version = "0.3.0-alpha.18" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-preview" -version = "0.3.0-alpha.17" +version = "0.3.0-alpha.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-channel-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-executor-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-executor-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-io-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-sink-preview" -version = "0.3.0-alpha.17" +version = "0.3.0-alpha.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-timer" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-util-preview" -version = "0.3.0-alpha.17" +version = "0.3.0-alpha.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-channel-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-io-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2322,7 +2321,7 @@ version = "2.0.0" dependencies = [ "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4579,7 +4578,7 @@ dependencies = [ name = "substrate-basic-authorship" version = "2.0.0" dependencies = [ - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -4616,7 +4615,7 @@ dependencies = [ "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "names 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4646,7 +4645,7 @@ dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", @@ -4702,8 +4701,8 @@ version = "2.0.0" dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4748,8 +4747,8 @@ dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "fork-tree 2.0.0", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "merlin 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4801,8 +4800,8 @@ name = "substrate-consensus-common" version = "2.0.0" dependencies = [ "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4819,7 +4818,7 @@ dependencies = [ name = "substrate-consensus-pow" version = "2.0.0" dependencies = [ - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -4869,8 +4868,8 @@ dependencies = [ name = "substrate-consensus-slots" version = "2.0.0" dependencies = [ - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4933,7 +4932,7 @@ dependencies = [ "finality-grandpa 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "fork-tree 2.0.0", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5019,8 +5018,8 @@ dependencies = [ "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "fork-tree 2.0.0", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5062,8 +5061,8 @@ dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5102,7 +5101,7 @@ dependencies = [ name = "substrate-peerset" version = "2.0.0" dependencies = [ - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5164,7 +5163,7 @@ version = "2.0.0" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5194,7 +5193,7 @@ name = "substrate-rpc-api" version = "2.0.0" dependencies = [ "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core-client 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-derive 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5259,7 +5258,7 @@ dependencies = [ "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "node-executor 2.0.0", @@ -5362,8 +5361,8 @@ version = "2.0.0" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5381,7 +5380,7 @@ dependencies = [ name = "substrate-test-client" version = "2.0.0" dependencies = [ - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -5447,7 +5446,7 @@ dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6593,15 +6592,15 @@ dependencies = [ "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "45dc39533a6cae6da2b56da48edae506bb767ec07370f86f70fc062e9d435869" -"checksum futures-channel-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "21c71ed547606de08e9ae744bb3c6d80f5627527ef31ecf2a7210d0e67bc8fae" -"checksum futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "4b141ccf9b7601ef987f36f1c0d9522f76df3bba1cf2e63bfacccc044c4558f5" +"checksum futures-channel-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "f477fd0292c4a4ae77044454e7f2b413207942ad405f759bb0b4698b7ace5b12" +"checksum futures-core-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "4a2f26f774b81b3847dcda0c81bd4b6313acfb4f69e5a0390c7cb12c058953e9" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" -"checksum futures-executor-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "87ba260fe51080ba37f063ad5b0732c4ff1f737ea18dcb67833d282cdc2c6f14" -"checksum futures-io-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "082e402605fcb8b1ae1e5ba7d7fdfd3e31ef510e2a8367dd92927bb41ae41b3a" -"checksum futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "bf25f91c8a9a1f64c451e91b43ba269ed359b9f52d35ed4b3ce3f9c842435867" -"checksum futures-sink-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "4309a25a1069a1f3c10647b227b9afe6722b67a030d3f00a9cbdc171fc038de4" -"checksum futures-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb4a32e84935678650944c6ebd0d912db46405d37bf94f1a058435c5080abcb1" -"checksum futures-util-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "af8198c48b222f02326940ce2b3aa9e6e91a32886eeaad7ca3b8e4c70daa3f4e" +"checksum futures-executor-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "80705612926df8a1bc05f0057e77460e29318801f988bf7d803a734cf54e7528" +"checksum futures-io-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "ee7de0c1c9ed23f9457b0437fec7663ce64d9cc3c906597e714e529377b5ddd1" +"checksum futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "efa8f90c4fb2328e381f8adfd4255b4a2b696f77d1c63a3dee6700b564c4e4b5" +"checksum futures-sink-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "e9b65a2481863d1b78e094a07e9c0eed458cc7dc6e72b22b7138b8a67d924859" +"checksum futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f9eb554aa23143abc64ec4d0016f038caf53bb7cbc3d91490835c54edc96550" +"checksum futures-util-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "7df53daff1e98cc024bf2720f3ceb0414d96fbb0a94f3cad3a5c3bf3be1d261c" "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" "checksum generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fceb69994e330afed50c93524be68c42fa898c2d9fd4ee8da03bd7363acd26f2" diff --git a/core/basic-authorship/Cargo.toml b/core/basic-authorship/Cargo.toml index 003eb79349..a819592601 100644 --- a/core/basic-authorship/Cargo.toml +++ b/core/basic-authorship/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] log = "0.4" -futures-preview = "=0.3.0-alpha.17" +futures-preview = "0.3.0-alpha.18" codec = { package = "parity-scale-codec", version = "1.0.0" } sr-primitives = { path = "../../core/sr-primitives" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } diff --git a/core/cli/Cargo.toml b/core/cli/Cargo.toml index a5af736226..b33c48fbd1 100644 --- a/core/cli/Cargo.toml +++ b/core/cli/Cargo.toml @@ -18,7 +18,7 @@ lazy_static = "1.3" app_dirs = "1.2" tokio = "0.1.7" futures = "0.1.17" -futures03 = { package = "futures-preview", version = "=0.3.0-alpha.17", features = ["compat"] } +futures03 = { package = "futures-preview", version = "0.3.0-alpha.18", features = ["compat"] } fdlimit = "0.1" exit-future = "0.1" serde_json = "1.0" diff --git a/core/client/Cargo.toml b/core/client/Cargo.toml index 3fc7407a7c..7fcd291f50 100644 --- a/core/client/Cargo.toml +++ b/core/client/Cargo.toml @@ -11,7 +11,7 @@ log = { version = "0.4", optional = true } parking_lot = { version = "0.9.0", optional = true } hex = { package = "hex-literal", version = "0.2", optional = true } futures = { version = "0.1", optional = true } -futures03 = { package = "futures-preview", version = "=0.3.0-alpha.17", features = ["compat"], optional = true } +futures03 = { package = "futures-preview", version = "0.3.0-alpha.18", features = ["compat"], optional = true } consensus = { package = "substrate-consensus-common", path = "../consensus/common", optional = true } executor = { package = "substrate-executor", path = "../executor", optional = true } state-machine = { package = "substrate-state-machine", path = "../state-machine", optional = true } diff --git a/core/consensus/aura/Cargo.toml b/core/consensus/aura/Cargo.toml index d6ce48841b..c3aaeb3d56 100644 --- a/core/consensus/aura/Cargo.toml +++ b/core/consensus/aura/Cargo.toml @@ -21,9 +21,9 @@ substrate-telemetry = { path = "../../telemetry" } keystore = { package = "substrate-keystore", path = "../../keystore" } consensus_common = { package = "substrate-consensus-common", path = "../common" } sr-primitives = { path = "../../sr-primitives" } -futures-preview = { version = "=0.3.0-alpha.17", features = ["compat"] } +futures-preview = { version = "0.3.0-alpha.18", features = ["compat"] } futures01 = { package = "futures", version = "0.1" } -futures-timer = "0.2.1" +futures-timer = "0.3" parking_lot = "0.9.0" log = "0.4" diff --git a/core/consensus/babe/Cargo.toml b/core/consensus/babe/Cargo.toml index 9490887ba3..4ab5e27054 100644 --- a/core/consensus/babe/Cargo.toml +++ b/core/consensus/babe/Cargo.toml @@ -26,9 +26,9 @@ uncles = { package = "substrate-consensus-uncles", path = "../uncles" } slots = { package = "substrate-consensus-slots", path = "../slots" } sr-primitives = { path = "../../sr-primitives" } fork-tree = { path = "../../utils/fork-tree" } -futures-preview = { version = "=0.3.0-alpha.17", features = ["compat"] } +futures-preview = { version = "0.3.0-alpha.18", features = ["compat"] } futures01 = { package = "futures", version = "0.1" } -futures-timer = "0.2.1" +futures-timer = "0.3" parking_lot = "0.9.0" log = "0.4.6" schnorrkel = { version = "0.8.4", features = ["preaudit_deprecated"] } diff --git a/core/consensus/common/Cargo.toml b/core/consensus/common/Cargo.toml index 32930d5d7b..e75c4c695e 100644 --- a/core/consensus/common/Cargo.toml +++ b/core/consensus/common/Cargo.toml @@ -11,8 +11,8 @@ libp2p = { version = "0.12.0", default-features = false } log = "0.4" primitives = { package = "substrate-primitives", path= "../../primitives" } inherents = { package = "substrate-inherents", path = "../../inherents" } -futures-preview = "=0.3.0-alpha.17" -futures-timer = "0.2.1" +futures-preview = "0.3.0-alpha.18" +futures-timer = "0.3" rstd = { package = "sr-std", path = "../../sr-std" } runtime_version = { package = "sr-version", path = "../../sr-version" } sr-primitives = { path = "../../sr-primitives" } diff --git a/core/consensus/common/src/import_queue/basic_queue.rs b/core/consensus/common/src/import_queue/basic_queue.rs index da6dcd0293..2ab6d0c5e3 100644 --- a/core/consensus/common/src/import_queue/basic_queue.rs +++ b/core/consensus/common/src/import_queue/basic_queue.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . use std::{mem, pin::Pin, time::Duration}; -use futures::{prelude::*, channel::mpsc, task::SpawnExt as _, task::Context, task::Poll}; +use futures::{prelude::*, channel::mpsc, task::Context, task::Poll}; use futures_timer::Delay; use sr_primitives::{Justification, traits::{Block as BlockT, Header as HeaderT, NumberFor}}; @@ -70,9 +70,7 @@ impl BasicQueue { let manual_poll; if let Some(pool) = &mut pool { - // TODO: this expect() can be removed once - // https://github.com/rust-lang-nursery/futures-rs/pull/1750 is merged and deployed - pool.spawn(future).expect("ThreadPool can never fail to spawn tasks; QED"); + pool.spawn_ok(future); manual_poll = None; } else { manual_poll = Some(Box::pin(future) as Pin>); diff --git a/core/consensus/pow/Cargo.toml b/core/consensus/pow/Cargo.toml index 5ddc0f478d..f5bb3a4ea8 100644 --- a/core/consensus/pow/Cargo.toml +++ b/core/consensus/pow/Cargo.toml @@ -15,4 +15,4 @@ inherents = { package = "substrate-inherents", path = "../../inherents" } pow-primitives = { package = "substrate-consensus-pow-primitives", path = "primitives" } consensus-common = { package = "substrate-consensus-common", path = "../common" } log = "0.4" -futures-preview = { version = "=0.3.0-alpha.17", features = ["compat"] } +futures-preview = { version = "0.3.0-alpha.18", features = ["compat"] } diff --git a/core/consensus/slots/Cargo.toml b/core/consensus/slots/Cargo.toml index 71d9a2cb5b..03c62c7245 100644 --- a/core/consensus/slots/Cargo.toml +++ b/core/consensus/slots/Cargo.toml @@ -14,8 +14,8 @@ sr-primitives = { path = "../../sr-primitives" } substrate-telemetry = { path = "../../telemetry" } consensus_common = { package = "substrate-consensus-common", path = "../common" } inherents = { package = "substrate-inherents", path = "../../inherents" } -futures-preview = "=0.3.0-alpha.17" -futures-timer = "0.2.1" +futures-preview = "0.3.0-alpha.18" +futures-timer = "0.3" parking_lot = "0.9.0" log = "0.4" diff --git a/core/finality-grandpa/Cargo.toml b/core/finality-grandpa/Cargo.toml index 393ee45db5..f2e1dd490b 100644 --- a/core/finality-grandpa/Cargo.toml +++ b/core/finality-grandpa/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" [dependencies] fork-tree = { path = "../../core/utils/fork-tree" } futures = "0.1" -futures03 = { package = "futures-preview", version = "=0.3.0-alpha.17", features = ["compat"] } +futures03 = { package = "futures-preview", version = "0.3.0-alpha.18", features = ["compat"] } log = "0.4" parking_lot = "0.9.0" tokio-executor = "0.1.7" diff --git a/core/network/Cargo.toml b/core/network/Cargo.toml index 00dc04254d..9a0a4fc678 100644 --- a/core/network/Cargo.toml +++ b/core/network/Cargo.toml @@ -15,8 +15,8 @@ parking_lot = "0.9.0" bitflags = "1.0" fnv = "1.0" futures = "0.1.17" -futures03 = { package = "futures-preview", version = "=0.3.0-alpha.17", features = ["compat"] } -futures-timer = "0.2.1" +futures03 = { package = "futures-preview", version = "0.3.0-alpha.18", features = ["compat"] } +futures-timer = "0.3" linked-hash-map = "0.5" linked_hash_set = "0.1.3" lru-cache = "0.1.1" diff --git a/core/offchain/Cargo.toml b/core/offchain/Cargo.toml index 691fdea91c..867f80f6d2 100644 --- a/core/offchain/Cargo.toml +++ b/core/offchain/Cargo.toml @@ -11,8 +11,8 @@ bytes = "0.4" client = { package = "substrate-client", path = "../../core/client" } fnv = "1.0" futures01 = { package = "futures", version = "0.1" } -futures-preview = "=0.3.0-alpha.17" -futures-timer = "0.2.1" +futures-preview = "0.3.0-alpha.18" +futures-timer = "0.3" hyper = "0.12.33" hyper-tls = "0.3.2" log = "0.4" diff --git a/core/peerset/Cargo.toml b/core/peerset/Cargo.toml index 1bd9d3f17b..c2c92b8b1a 100644 --- a/core/peerset/Cargo.toml +++ b/core/peerset/Cargo.toml @@ -8,7 +8,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -futures-preview = "=0.3.0-alpha.17" +futures-preview = "0.3.0-alpha.18" libp2p = { version = "0.12.0", default-features = false } linked-hash-map = "0.5" log = "0.4" diff --git a/core/rpc/Cargo.toml b/core/rpc/Cargo.toml index 5bf74cf42e..215cf02a8c 100644 --- a/core/rpc/Cargo.toml +++ b/core/rpc/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" api = { package = "substrate-rpc-api", path = "./api" } client = { package = "substrate-client", path = "../client" } codec = { package = "parity-scale-codec", version = "1.0.0" } -futures03 = { package = "futures-preview", version = "0.3.0-alpha.17", features = ["compat"] } +futures03 = { package = "futures-preview", version = "0.3.0-alpha.18", features = ["compat"] } jsonrpc-pubsub = "13.1.0" log = "0.4" primitives = { package = "substrate-primitives", path = "../primitives" } diff --git a/core/rpc/api/Cargo.toml b/core/rpc/api/Cargo.toml index cc40ff39b2..e4114147d6 100644 --- a/core/rpc/api/Cargo.toml +++ b/core/rpc/api/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0" } derive_more = "0.14.0" -futures03 = { package = "futures-preview", version = "0.3.0-alpha.17", features = ["compat"] } +futures03 = { package = "futures-preview", version = "0.3.0-alpha.18", features = ["compat"] } jsonrpc-core = "13.2.0" jsonrpc-core-client = "13.2.0" jsonrpc-derive = "13.2.0" diff --git a/core/service/Cargo.toml b/core/service/Cargo.toml index 7f17d83931..75d49b1f1e 100644 --- a/core/service/Cargo.toml +++ b/core/service/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" [dependencies] derive_more = "0.14.0" futures = "0.1.17" -futures03 = { package = "futures-preview", version = "=0.3.0-alpha.17", features = ["compat"] } +futures03 = { package = "futures-preview", version = "0.3.0-alpha.18", features = ["compat"] } parking_lot = "0.9.0" lazy_static = "1.0" log = "0.4" diff --git a/core/telemetry/Cargo.toml b/core/telemetry/Cargo.toml index 1afc4fd40c..2dcb394f0e 100644 --- a/core/telemetry/Cargo.toml +++ b/core/telemetry/Cargo.toml @@ -9,8 +9,8 @@ edition = "2018" bytes = "0.4" parking_lot = "0.9.0" futures01 = { package = "futures", version = "0.1" } -futures-preview = { version = "=0.3.0-alpha.17", features = ["compat"] } -futures-timer = "0.2.1" +futures-preview = { version = "0.3.0-alpha.18", features = ["compat"] } +futures-timer = "0.3" libp2p = { version = "0.12.0", default-features = false, features = ["libp2p-websocket"] } log = "0.4" rand = "0.6" diff --git a/core/test-client/Cargo.toml b/core/test-client/Cargo.toml index 58e2857cf3..1281bd07d0 100644 --- a/core/test-client/Cargo.toml +++ b/core/test-client/Cargo.toml @@ -9,7 +9,7 @@ client = { package = "substrate-client", path = "../client" } client-db = { package = "substrate-client-db", path = "../client/db", features = ["test-helpers"] } consensus = { package = "substrate-consensus-common", path = "../consensus/common" } executor = { package = "substrate-executor", path = "../executor" } -futures-preview = "=0.3.0-alpha.17" +futures-preview = "0.3.0-alpha.18" hash-db = "0.15.2" keyring = { package = "substrate-keyring", path = "../keyring" } codec = { package = "parity-scale-codec", version = "1.0.0" } diff --git a/core/transaction-pool/graph/Cargo.toml b/core/transaction-pool/graph/Cargo.toml index a19f3aaccc..2e15e2ac25 100644 --- a/core/transaction-pool/graph/Cargo.toml +++ b/core/transaction-pool/graph/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] derive_more = "0.14.0" -futures-preview = "=0.3.0-alpha.17" +futures-preview = "0.3.0-alpha.18" log = "0.4" parking_lot = "0.9.0" serde = { version = "1.0", features = ["derive"] } diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index 68232800f2..933ee0c046 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -54,7 +54,7 @@ keystore = { package = "substrate-keystore", path = "../../core/keystore" } babe = { package = "substrate-consensus-babe", path = "../../core/consensus/babe", features = ["test-helpers"] } consensus-common = { package = "substrate-consensus-common", path = "../../core/consensus/common" } service-test = { package = "substrate-service-test", path = "../../core/service/test" } -futures03 = { package = "futures-preview", version = "=0.3.0-alpha.17" } +futures03 = { package = "futures-preview", version = "0.3.0-alpha.18" } tempfile = "3.1" [build-dependencies] -- GitLab From b29720e90810e47822b3dbd94d1dc3f8ea82d0d7 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Fri, 20 Sep 2019 18:44:19 +0200 Subject: [PATCH 116/275] find best_containing even if best chain is shorter (#3657) --- core/client/src/client.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/client/src/client.rs b/core/client/src/client.rs index f418b79127..acba5fa824 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -1704,10 +1704,10 @@ where let info = self.backend.blockchain().info(); - let canon_hash = self.backend.blockchain().hash(*target_header.number())? - .ok_or_else(|| error::Error::from(format!("failed to get hash for block number {}", target_header.number())))?; + // this can be `None` if the best chain is shorter than the target header. + let maybe_canon_hash = self.backend.blockchain().hash(*target_header.number())?; - if canon_hash == target_hash { + if maybe_canon_hash.as_ref() == Some(&target_hash) { // if a `max_number` is given we try to fetch the block at the // given depth, if it doesn't exist or `max_number` is not // provided, we continue to search from all leaves below. -- GitLab From de90fe7f4cd807141c4275a04138f6222f1359e8 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Sat, 21 Sep 2019 06:47:10 +0200 Subject: [PATCH 117/275] Make staking inflation curve configurable. (#3644) * Draft for new design of NPoS rewards * finish code * fix test * add tests * improve log test * version bump * Update srml/staking/reward-curve/Cargo.toml Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * u128 -> u64 * make conversion to smaller type safe * Update core/sr-primitives/src/curve.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- Cargo.lock | 30 +- Cargo.toml | 2 + core/sr-primitives/src/curve.rs | 164 +++++++++ core/sr-primitives/src/lib.rs | 1 + node/runtime/Cargo.toml | 1 + node/runtime/src/lib.rs | 23 +- srml/staking/Cargo.toml | 1 + srml/staking/reward-curve/Cargo.toml | 18 + srml/staking/reward-curve/src/lib.rs | 414 ++++++++++++++++++++++ srml/staking/reward-curve/src/log.rs | 70 ++++ srml/staking/reward-curve/test/Cargo.toml | 9 + srml/staking/reward-curve/test/src/lib.rs | 44 +++ srml/staking/src/inflation.rs | 405 ++------------------- srml/staking/src/lib.rs | 17 +- srml/staking/src/mock.rs | 14 + 15 files changed, 834 insertions(+), 379 deletions(-) create mode 100644 core/sr-primitives/src/curve.rs create mode 100644 srml/staking/reward-curve/Cargo.toml create mode 100644 srml/staking/reward-curve/src/lib.rs create mode 100644 srml/staking/reward-curve/src/log.rs create mode 100644 srml/staking/reward-curve/test/Cargo.toml create mode 100644 srml/staking/reward-curve/test/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index c861209f68..c852d480ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2476,6 +2476,7 @@ dependencies = [ "srml-offences 1.0.0", "srml-session 2.0.0", "srml-staking 2.0.0", + "srml-staking-reward-curve 2.0.0", "srml-sudo 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", @@ -2599,9 +2600,10 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2621,7 +2623,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4288,6 +4290,7 @@ dependencies = [ "srml-authorship 0.1.0", "srml-balances 2.0.0", "srml-session 2.0.0", + "srml-staking-reward-curve 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", @@ -4296,6 +4299,25 @@ dependencies = [ "substrate-primitives 2.0.0", ] +[[package]] +name = "srml-staking-reward-curve" +version = "2.0.0" +dependencies = [ + "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 2.0.0", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "srml-staking-reward-curve-test" +version = "2.0.0" +dependencies = [ + "sr-primitives 2.0.0", + "srml-staking-reward-curve 2.0.0", +] + [[package]] name = "srml-sudo" version = "2.0.0" @@ -4751,7 +4773,7 @@ dependencies = [ "futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "merlin 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6720,7 +6742,7 @@ dependencies = [ "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" "checksum nohash-hasher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d138afcce92d219ccb6eb53d9b1e8a96ac0d633cfd3c53cd9856d96d1741bb8" "checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" -"checksum num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "57450397855d951f1a41305e54851b1a7b8f5d2e349543a02a2effe25459f718" +"checksum num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9c3f34cdd24f334cb265d9bf8bfa8a241920d026916785747a92f0e55541a1a" "checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" "checksum num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2885278d5fe2adc2f75ced642d52d879bffaceb5a2e0b1d4309ffdfb239b454" "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" diff --git a/Cargo.toml b/Cargo.toml index 6bec85759b..684363c227 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -95,6 +95,8 @@ members = [ "srml/scored-pool", "srml/session", "srml/staking", + "srml/staking/reward-curve", + "srml/staking/reward-curve/test", "srml/sudo", "srml/system", "srml/timestamp", diff --git a/core/sr-primitives/src/curve.rs b/core/sr-primitives/src/curve.rs new file mode 100644 index 0000000000..447c57ee32 --- /dev/null +++ b/core/sr-primitives/src/curve.rs @@ -0,0 +1,164 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Provides some utilities to define a piecewise linear function. + +use crate::{Perbill, traits::{SimpleArithmetic, SaturatedConversion}}; +use core::ops::Sub; + +/// Piecewise Linear function in [0, 1] -> [0, 1]. +#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq)] +pub struct PiecewiseLinear<'a> { + /// Array of points. Must be in order from the lowest abscissas to the highest. + pub points: &'a [(Perbill, Perbill)] +} + +fn abs_sub + Clone>(a: N, b: N) -> N where { + a.clone().max(b.clone()) - a.min(b) +} + +impl<'a> PiecewiseLinear<'a> { + /// Compute `f(n/d)*d` with `n <= d`. This is useful to avoid loss of precision. + pub fn calculate_for_fraction_times_denominator(&self, n: N, d: N) -> N where + N: SimpleArithmetic + Clone + { + let n = n.min(d.clone()); + + if self.points.len() == 0 { + return N::zero() + } + + let next_point_index = self.points.iter() + .position(|p| n < p.0 * d.clone()); + + let (prev, next) = if let Some(next_point_index) = next_point_index { + if let Some(previous_point_index) = next_point_index.checked_sub(1) { + (self.points[previous_point_index], self.points[next_point_index]) + } else { + // There is no previous points, take first point ordinate + return self.points.first().map(|p| p.1).unwrap_or_else(Perbill::zero) * d + } + } else { + // There is no next points, take last point ordinate + return self.points.last().map(|p| p.1).unwrap_or_else(Perbill::zero) * d + }; + + let delta_y = multiply_by_rational_saturating( + abs_sub(n.clone(), prev.0 * d.clone()), + abs_sub(next.1.into_parts(), prev.1.into_parts()), + // Must not saturate as prev abscissa > next abscissa + next.0.into_parts().saturating_sub(prev.0.into_parts()), + ); + + // If both substration are same sign then result is positive + if (n > prev.0 * d.clone()) == (next.1.into_parts() > prev.1.into_parts()) { + (prev.1 * d).saturating_add(delta_y) + // Otherwise result is negative + } else { + (prev.1 * d).saturating_sub(delta_y) + } + } +} + +// Compute value * p / q. +// This is guaranteed not to overflow on whatever values nor lose precision. +// `q` must be superior to zero. +fn multiply_by_rational_saturating(value: N, p: u32, q: u32) -> N + where N: SimpleArithmetic + Clone +{ + let q = q.max(1); + + // Mul can saturate if p > q + let result_divisor_part = (value.clone() / q.into()).saturating_mul(p.into()); + + let result_remainder_part = { + let rem = value % q.into(); + + // Fits into u32 because q is u32 and remainder < q + let rem_u32 = rem.saturated_into::(); + + // Multiplication fits into u64 as both term are u32 + let rem_part = rem_u32 as u64 * p as u64 / q as u64; + + // Can saturate if p > q + rem_part.saturated_into::() + }; + + // Can saturate if p > q + result_divisor_part.saturating_add(result_remainder_part) +} + +#[test] +fn test_multiply_by_rational_saturating() { + use std::convert::TryInto; + + let div = 100u32; + for value in 0..=div { + for p in 0..=div { + for q in 1..=div { + let value: u64 = (value as u128 * u64::max_value() as u128 / div as u128) + .try_into().unwrap(); + let p = (p as u64 * u32::max_value() as u64 / div as u64) + .try_into().unwrap(); + let q = (q as u64 * u32::max_value() as u64 / div as u64) + .try_into().unwrap(); + + assert_eq!( + multiply_by_rational_saturating(value, p, q), + (value as u128 * p as u128 / q as u128) + .try_into().unwrap_or(u64::max_value()) + ); + } + } + } +} + +#[test] +fn test_calculate_for_fraction_times_denominator() { + use std::convert::TryInto; + + let curve = PiecewiseLinear { + points: &[ + (Perbill::from_parts(0_000_000_000), Perbill::from_parts(0_500_000_000)), + (Perbill::from_parts(0_500_000_000), Perbill::from_parts(1_000_000_000)), + (Perbill::from_parts(1_000_000_000), Perbill::from_parts(0_000_000_000)), + ] + }; + + pub fn formal_calculate_for_fraction_times_denominator(n: u64, d: u64) -> u64 { + if n <= Perbill::from_parts(0_500_000_000) * d.clone() { + n + d / 2 + } else { + (d as u128 * 2 - n as u128 * 2).try_into().unwrap() + } + } + + let div = 100u32; + for d in 0..=div { + for n in 0..=d { + let d: u64 = (d as u128 * u64::max_value() as u128 / div as u128) + .try_into().unwrap(); + let n: u64 = (n as u128 * u64::max_value() as u128 / div as u128) + .try_into().unwrap(); + + let res = curve.calculate_for_fraction_times_denominator(n, d); + let expected = formal_calculate_for_fraction_times_denominator(n, d); + + assert!(abs_sub(res, expected) <= 1); + } + } +} diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index c3f47f29c4..81e73033b2 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -47,6 +47,7 @@ pub mod testing; pub mod weights; pub mod traits; +pub mod curve; pub mod generic; pub mod transaction_validity; diff --git a/node/runtime/Cargo.toml b/node/runtime/Cargo.toml index 554d9561a3..8b1f775cea 100644 --- a/node/runtime/Cargo.toml +++ b/node/runtime/Cargo.toml @@ -42,6 +42,7 @@ membership = { package = "srml-membership", path = "../../srml/membership", defa offences = { package = "srml-offences", path = "../../srml/offences", default-features = false } session = { package = "srml-session", path = "../../srml/session", default-features = false, features = ["historical"] } staking = { package = "srml-staking", path = "../../srml/staking", default-features = false } +srml-staking-reward-curve = { path = "../../srml/staking/reward-curve"} sudo = { package = "srml-sudo", path = "../../srml/sudo", default-features = false } support = { package = "srml-support", path = "../../srml/support", default-features = false } system = { package = "srml-system", path = "../../srml/system", default-features = false } diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index f6955d2bd0..bee5e7fc22 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -35,7 +35,10 @@ use client::{ block_builder::api::{self as block_builder_api, InherentData, CheckInherentsResult}, runtime_api as client_api, impl_runtime_apis }; -use sr_primitives::{ApplyResult, impl_opaque_keys, generic, create_runtime_str, key_types}; +use sr_primitives::{ + Permill, Perbill, ApplyResult, impl_opaque_keys, generic, create_runtime_str, key_types +}; +use sr_primitives::curve::PiecewiseLinear; use sr_primitives::transaction_validity::TransactionValidity; use sr_primitives::weights::Weight; use sr_primitives::traits::{ @@ -57,7 +60,6 @@ pub use sr_primitives::BuildStorage; pub use timestamp::Call as TimestampCall; pub use balances::Call as BalancesCall; pub use contracts::Gas; -pub use sr_primitives::{Permill, Perbill}; pub use support::StorageValue; pub use staking::StakerStatus; @@ -82,8 +84,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 159, - impl_version: 159, + spec_version: 160, + impl_version: 160, apis: RUNTIME_API_VERSIONS, }; @@ -232,9 +234,21 @@ impl session::historical::Trait for Runtime { type FullIdentificationOf = staking::ExposureOf; } +srml_staking_reward_curve::build! { + const REWARD_CURVE: PiecewiseLinear<'static> = curve!( + min_inflation: 0_025_000, + max_inflation: 0_100_000, + ideal_stake: 0_500_000, + falloff: 0_050_000, + max_piece_count: 40, + test_precision: 0_005_000, + ); +} + parameter_types! { pub const SessionsPerEra: sr_staking_primitives::SessionIndex = 6; pub const BondingDuration: staking::EraIndex = 24 * 28; + pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE; } impl staking::Trait for Runtime { @@ -248,6 +262,7 @@ impl staking::Trait for Runtime { type SessionsPerEra = SessionsPerEra; type BondingDuration = BondingDuration; type SessionInterface = Self; + type RewardCurve = RewardCurve; } parameter_types! { diff --git a/srml/staking/Cargo.toml b/srml/staking/Cargo.toml index 092bcfda8e..3700d84c09 100644 --- a/srml/staking/Cargo.toml +++ b/srml/staking/Cargo.toml @@ -23,6 +23,7 @@ authorship = { package = "srml-authorship", path = "../authorship", default-feat primitives = { package = "substrate-primitives", path = "../../core/primitives" } balances = { package = "srml-balances", path = "../balances" } timestamp = { package = "srml-timestamp", path = "../timestamp" } +srml-staking-reward-curve = { path = "../staking/reward-curve"} [features] equalize = [] diff --git a/srml/staking/reward-curve/Cargo.toml b/srml/staking/reward-curve/Cargo.toml new file mode 100644 index 0000000000..4e254e9512 --- /dev/null +++ b/srml/staking/reward-curve/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "srml-staking-reward-curve" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[lib] +proc-macro = true + +[dependencies] +# sr-api-macros = { path = "../../../core/sr-api-macros" } +syn = { version = "1.0", features = [ "full", "visit" ] } +quote = "1.0" +proc-macro2 = "1.0" +proc-macro-crate = "0.1.3" + +[dev-dependencies] +sr-primitives = { path = "../../../core/sr-primitives" } diff --git a/srml/staking/reward-curve/src/lib.rs b/srml/staking/reward-curve/src/lib.rs new file mode 100644 index 0000000000..9ed319be7f --- /dev/null +++ b/srml/staking/reward-curve/src/lib.rs @@ -0,0 +1,414 @@ +extern crate proc_macro; + +mod log; + +use log::log2; +use proc_macro::TokenStream; +use proc_macro2::{TokenStream as TokenStream2, Span}; +use proc_macro_crate::crate_name; +use quote::{quote, ToTokens}; +use std::convert::TryInto; +use syn::parse::{Parse, ParseStream}; + +/// Accepts a number of expressions to create a instance of PiecewiseLinear which represents the +/// NPoS curve (as detailed +/// [here](http://research.web3.foundation/en/latest/polkadot/Token%20Economics/#inflation-model)) +/// for those parameters. Parameters are: +/// - `min_inflation`: the minimal amount to be rewarded between validators, expressed as a fraction +/// of total issuance. Known as `I_0` in the literature. +/// Expressed in millionth, must be between 0 and 1_000_000. +/// +/// - `max_inflation`: the maximum amount to be rewarded between validators, expressed as a fraction +/// of total issuance. This is attained only when `ideal_stake` is achieved. +/// Expressed in millionth, must be between min_inflation and 1_000_000. +/// +/// - `ideal_stake`: the fraction of total issued tokens that should be actively staked behind +/// validators. Known as `x_ideal` in the literature. +/// Expressed in millionth, must be between 0_100_000 and 0_900_000. +/// +/// - `falloff`: Known as `decay_rate` in the literature. A co-efficient dictating the strength of +/// the global incentivisation to get the `ideal_stake`. A higher number results in less typical +/// inflation at the cost of greater volatility for validators. +/// Expressed in millionth, must be between 0 and 1_000_000. +/// +/// - `max_piece_count`: The maximum number of pieces in the curve. A greater number uses more +/// resources but results in higher accuracy. +/// Must be between 2 and 1_000. +/// +/// - `test_precision`: The maximum error allowed in the generated test. +/// Expressed in millionth, must be between 0 and 1_000_000. +/// +/// # Example +/// +/// ``` +/// # fn main() {} +/// use sr_primitives::curve::PiecewiseLinear; +/// +/// srml_staking_reward_curve::build! { +/// const I_NPOS: PiecewiseLinear<'static> = curve!( +/// min_inflation: 0_025_000, +/// max_inflation: 0_100_000, +/// ideal_stake: 0_500_000, +/// falloff: 0_050_000, +/// max_piece_count: 40, +/// test_precision: 0_005_000, +/// ); +/// } +/// ``` +#[proc_macro] +pub fn build(input: TokenStream) -> TokenStream { + let input = syn::parse_macro_input!(input as INposInput); + + let points = compute_points(&input); + + let declaration = generate_piecewise_linear(points); + let test_module = generate_test_module(&input); + + let imports = match crate_name("sr-primitives") { + Ok(sr_primitives) => { + let ident = syn::Ident::new(&sr_primitives, Span::call_site()); + quote!( extern crate #ident as _sr_primitives; ) + }, + Err(e) => syn::Error::new(Span::call_site(), &e).to_compile_error(), + }; + + let const_name = input.ident; + let const_type = input.typ; + + quote!( + const #const_name: #const_type = { + #imports + #declaration + }; + #test_module + ).into() +} + +const MILLION: u32 = 1_000_000; + +mod keyword { + syn::custom_keyword!(curve); + syn::custom_keyword!(min_inflation); + syn::custom_keyword!(max_inflation); + syn::custom_keyword!(ideal_stake); + syn::custom_keyword!(falloff); + syn::custom_keyword!(max_piece_count); + syn::custom_keyword!(test_precision); +} + +struct INposInput { + ident: syn::Ident, + typ: syn::Type, + min_inflation: u32, + ideal_stake: u32, + max_inflation: u32, + falloff: u32, + max_piece_count: u32, + test_precision: u32, +} + +struct Bounds { + min: u32, + min_strict: bool, + max: u32, + max_strict: bool, +} + +impl Bounds { + fn check(&self, value: u32) -> bool { + let wrong = (self.min_strict && value <= self.min) + || (!self.min_strict && value < self.min) + || (self.max_strict && value >= self.max) + || (!self.max_strict && value > self.max); + + !wrong + } +} + +impl core::fmt::Display for Bounds { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!( + f, + "{}{:07}; {:07}{}", + if self.min_strict { "]" } else { "[" }, + self.min, + self.max, + if self.max_strict { "[" } else { "]" }, + ) + } +} + +fn parse_field(input: ParseStream, bounds: Bounds) + -> syn::Result +{ + ::parse(&input)?; + ::parse(&input)?; + let value_lit = syn::LitInt::parse(&input)?; + let value: u32 = value_lit.base10_parse()?; + if !bounds.check(value) { + return Err(syn::Error::new(value_lit.span(), format!( + "Invalid {}: {}, must be in {}", Token::default().to_token_stream(), value, bounds, + ))); + } + + Ok(value) +} + +impl Parse for INposInput { + fn parse(input: ParseStream) -> syn::Result { + let args_input; + + ::parse(&input)?; + let ident = ::parse(&input)?; + ::parse(&input)?; + let typ = ::parse(&input)?; + ::parse(&input)?; + ::parse(&input)?; + ::parse(&input)?; + syn::parenthesized!(args_input in input); + ::parse(&input)?; + + if !input.is_empty() { + return Err(input.error("expected end of input stream, no token expected")); + } + + let min_inflation = parse_field::(&args_input, Bounds { + min: 0, + min_strict: true, + max: 1_000_000, + max_strict: false, + })?; + ::parse(&args_input)?; + let max_inflation = parse_field::(&args_input, Bounds { + min: min_inflation, + min_strict: true, + max: 1_000_000, + max_strict: false, + })?; + ::parse(&args_input)?; + let ideal_stake = parse_field::(&args_input, Bounds { + min: 0_100_000, + min_strict: false, + max: 0_900_000, + max_strict: false, + })?; + ::parse(&args_input)?; + let falloff = parse_field::(&args_input, Bounds { + min: 0_010_000, + min_strict: false, + max: 1_000_000, + max_strict: false, + })?; + ::parse(&args_input)?; + let max_piece_count = parse_field::(&args_input, Bounds { + min: 2, + min_strict: false, + max: 1_000, + max_strict: false, + })?; + ::parse(&args_input)?; + let test_precision = parse_field::(&args_input, Bounds { + min: 0, + min_strict: false, + max: 1_000_000, + max_strict: false, + })?; + >::parse(&args_input)?; + + if !args_input.is_empty() { + return Err(args_input.error("expected end of input stream, no token expected")); + } + + Ok(Self { + ident, + typ, + min_inflation, + ideal_stake, + max_inflation, + falloff, + max_piece_count, + test_precision, + }) + } +} + +struct INPoS { + i_0: u32, + i_ideal_times_x_ideal: u32, + i_ideal: u32, + x_ideal: u32, + d: u32, +} + +impl INPoS { + fn from_input(input: &INposInput) -> Self { + INPoS { + i_0: input.min_inflation, + i_ideal: (input.max_inflation as u64 * MILLION as u64 / input.ideal_stake as u64) + .try_into().unwrap(), + i_ideal_times_x_ideal: input.max_inflation, + x_ideal: input.ideal_stake, + d: input.falloff, + } + } + + fn compute_opposite_after_x_ideal(&self, y: u32) -> u32 { + if y == self.i_0 { + return u32::max_value(); + } + let log = log2(self.i_ideal_times_x_ideal - self.i_0, y - self.i_0); + + let term: u32 = ((self.d as u64 * log as u64) / 1_000_000).try_into().unwrap(); + + self.x_ideal + term + } +} + +fn compute_points(input: &INposInput) -> Vec<(u32, u32)> { + let inpos = INPoS::from_input(input); + + let mut points = vec![]; + points.push((0, inpos.i_0)); + points.push((inpos.x_ideal, inpos.i_ideal_times_x_ideal)); + + // For each point p: (next_p.0 - p.0) < segment_lenght && (next_p.1 - p.1) < segment_lenght. + // This ensures that the total number of segment doesn't overflow max_piece_count. + let max_length = (input.max_inflation - input.min_inflation + 1_000_000 - inpos.x_ideal) + / (input.max_piece_count - 1); + + let mut delta_y = max_length; + let mut y = input.max_inflation; + + while delta_y != 0 { + let next_y = y - delta_y; + + if next_y <= input.min_inflation { + delta_y = delta_y.saturating_sub(1); + continue + } + + let next_x = inpos.compute_opposite_after_x_ideal(next_y); + + if (next_x - points.last().unwrap().0) > max_length { + delta_y = delta_y.saturating_sub(1); + continue + } + + if next_x >= 1_000_000 { + let prev = points.last().unwrap(); + // Compute the y corresponding to x=1_000_000 using the this point and the previous one. + + let delta_y: u32 = ( + (next_x - 1_000_000) as u64 + * (prev.1 - next_y) as u64 + / (next_x - prev.0) as u64 + ).try_into().unwrap(); + + let y = next_y + delta_y; + + points.push((1_000_000, y)); + return points; + } + points.push((next_x, next_y)); + y = next_y; + } + + points.push((1_000_000, inpos.i_0)); + + points +} + +fn generate_piecewise_linear(points: Vec<(u32, u32)>) -> TokenStream2 { + let mut points_tokens = quote!(); + + for (x, y) in points { + let error = || panic!(format!( + "Generated reward curve approximation doesn't fit into [0, 1] -> [0, 1] \ + because of point: + x = {:07} per million + y = {:07} per million", + x, y + )); + + let x_perbill = x.checked_mul(1_000).unwrap_or_else(error); + let y_perbill = y.checked_mul(1_000).unwrap_or_else(error); + + points_tokens.extend(quote!( + ( + _sr_primitives::Perbill::from_const_parts(#x_perbill), + _sr_primitives::Perbill::from_const_parts(#y_perbill), + ), + )); + } + + quote!( + _sr_primitives::curve::PiecewiseLinear::<'static> { + points: & [ #points_tokens ], + } + ) +} + +fn generate_test_module(input: &INposInput) -> TokenStream2 { + let inpos = INPoS::from_input(input); + + let ident = &input.ident; + let precision = input.test_precision; + let i_0 = inpos.i_0 as f64/ MILLION as f64; + let i_ideal_times_x_ideal = inpos.i_ideal_times_x_ideal as f64 / MILLION as f64; + let i_ideal = inpos.i_ideal as f64 / MILLION as f64; + let x_ideal = inpos.x_ideal as f64 / MILLION as f64; + let d = inpos.d as f64 / MILLION as f64; + let max_piece_count = input.max_piece_count; + + quote!( + #[cfg(test)] + mod __srml_staking_reward_curve_test_module { + fn i_npos(x: f64) -> f64 { + if x <= #x_ideal { + #i_0 + x * (#i_ideal - #i_0 / #x_ideal) + } else { + #i_0 + (#i_ideal_times_x_ideal - #i_0) * 2_f64.powf((#x_ideal - x) / #d) + } + } + + const MILLION: u32 = 1_000_000; + + #[test] + fn reward_curve_precision() { + for &base in [MILLION, u32::max_value()].into_iter() { + let number_of_check = 100_000.min(base); + for check_index in 0..=number_of_check { + let i = (check_index as u64 * base as u64 / number_of_check as u64) as u32; + let x = i as f64 / base as f64; + let float_res = (i_npos(x) * base as f64).round() as u32; + let int_res = super::#ident.calculate_for_fraction_times_denominator(i, base); + let err = ( + (float_res.max(int_res) - float_res.min(int_res)) as u64 + * MILLION as u64 + / float_res as u64 + ) as u32; + if err > #precision { + panic!(format!("\n\ + Generated reward curve approximation differ from real one:\n\t\ + for i = {} and base = {}, f(i/base) * base = {},\n\t\ + but approximation = {},\n\t\ + err = {:07} millionth,\n\t\ + try increase the number of segment: {} or the test_error: {}.\n", + i, base, float_res, int_res, err, #max_piece_count, #precision + )); + } + } + } + } + + #[test] + fn reward_curve_piece_count() { + assert!( + super::#ident.points.len() as u32 - 1 <= #max_piece_count, + "Generated reward curve approximation is invalid: \ + has more points than specified, please fill an issue." + ); + } + } + ).into() +} diff --git a/srml/staking/reward-curve/src/log.rs b/srml/staking/reward-curve/src/log.rs new file mode 100644 index 0000000000..1079591a6c --- /dev/null +++ b/srml/staking/reward-curve/src/log.rs @@ -0,0 +1,70 @@ +use std::convert::TryInto; + +/// Return Per-million value. +pub fn log2(p: u32, q: u32) -> u32 { + assert!(p >= q); + assert!(p <= u32::max_value()/2); + + // This restriction should not be mandatory. But function is only tested and used for this. + assert!(p <= 1_000_000); + assert!(q <= 1_000_000); + + if p == q { + return 0 + } + + let mut n = 0u32; + while !(p >= 2u32.pow(n)*q) || !(p < 2u32.pow(n+1)*q) { + n += 1; + } + assert!(p < 2u32.pow(n+1) * q); + + let y_num: u32 = (p - 2u32.pow(n) * q).try_into().unwrap(); + let y_den: u32 = (p + 2u32.pow(n) * q).try_into().unwrap(); + + let _2_div_ln_2 = 2_885_390u32; + + let taylor_term = |k: u32| -> u32 { + if k == 0 { + (_2_div_ln_2 as u128 * (y_num as u128).pow(1) / (y_den as u128).pow(1)) + .try_into().unwrap() + } else { + let mut res = _2_div_ln_2 as u128 * (y_num as u128).pow(3) / (y_den as u128).pow(3); + for _ in 1..k { + res = res * (y_num as u128).pow(2) / (y_den as u128).pow(2); + } + res /= 2 * k as u128 + 1; + + res.try_into().unwrap() + } + }; + + let mut res = n * 1_000_000u32; + let mut k = 0; + loop { + let term = taylor_term(k); + if term == 0 { + break + } + + res += term; + k += 1; + } + + res +} + +#[test] +fn test_log() { + let div = 1_000; + for p in 0..=div { + for q in 1..=p { + let p: u32 = (1_000_000 as u64 * p as u64 / div as u64).try_into().unwrap(); + let q: u32 = (1_000_000 as u64 * q as u64 / div as u64).try_into().unwrap(); + + let res = - (log2(p, q) as i64); + let expected = ((q as f64 / p as f64).log(2.0) * 1_000_000 as f64).round() as i64; + assert!((res - expected).abs() <= 6); + } + } +} diff --git a/srml/staking/reward-curve/test/Cargo.toml b/srml/staking/reward-curve/test/Cargo.toml new file mode 100644 index 0000000000..5c9ffb3cf7 --- /dev/null +++ b/srml/staking/reward-curve/test/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "srml-staking-reward-curve-test" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +srml-staking-reward-curve = { path = ".." } +sr-primitives = { path = "../../../../core/sr-primitives" } diff --git a/srml/staking/reward-curve/test/src/lib.rs b/srml/staking/reward-curve/test/src/lib.rs new file mode 100644 index 0000000000..55a3b7d383 --- /dev/null +++ b/srml/staking/reward-curve/test/src/lib.rs @@ -0,0 +1,44 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Test crate for srml-staking-reward-curve. Allows to test for procedural macro. +//! See tests directory. + +mod test_small_falloff { + srml_staking_reward_curve::build! { + const REWARD_CURVE: sr_primitives::curve::PiecewiseLinear<'static> = curve!( + min_inflation: 0_020_000, + max_inflation: 0_200_000, + ideal_stake: 0_600_000, + falloff: 0_010_000, + max_piece_count: 200, + test_precision: 0_005_000, + ); + } +} + +mod test_big_falloff { + srml_staking_reward_curve::build! { + const REWARD_CURVE: sr_primitives::curve::PiecewiseLinear<'static> = curve!( + min_inflation: 0_100_000, + max_inflation: 0_400_000, + ideal_stake: 0_400_000, + falloff: 1_000_000, + max_piece_count: 40, + test_precision: 0_005_000, + ); + } +} diff --git a/srml/staking/src/inflation.rs b/srml/staking/src/inflation.rs index d39e16471b..a1d45b3db1 100644 --- a/srml/staking/src/inflation.rs +++ b/srml/staking/src/inflation.rs @@ -18,235 +18,71 @@ //! the total payout for the era given the era duration and the staking rate in NPoS. //! The staking rate in NPoS is the total amount of tokens staked by nominators and validators, //! divided by the total token supply. -//! -//! This payout is computed from the desired yearly inflation `I_NPoS`. -//! -//! `I_NPoS` is defined as such: -//! -//! let's introduce some constant: -//! * `I0` represents a tight upper-bound on our estimate of the operational costs of all -//! validators, expressed as a fraction of the total token supply. I_NPoS must be always -//! superior or equal to this value. -//! * `x_ideal` the ideal staking rate in NPoS. -//! * `i_ideal` the ideal yearly interest rate: the ideal total yearly amount of tokens minted to -//! pay all validators and nominators for NPoS, divided by the total amount of tokens staked by -//! them. `i(x) = I(x)/x` and `i(x_ideal) = i_deal` -//! * `d` decay rate. -//! -//! We define I_NPoS as a linear function from 0 to `x_ideal` and an exponential decrease after -//! `x_ideal` to 1. We choose exponential decrease for `I_NPoS` because this implies an exponential -//! decrease for the yearly interest rate as well, and we want the interest rate to fall sharply -//! beyond `x_ideal` to avoid illiquidity. -//! -//! Function is defined as such: -//! ```nocompile -//! for 0 < x < x_ideal: I_NPoS(x) = I0 + x*(i_ideal - I0/x_ideal) -//! for x_ideal < x < 1: I_NPoS(x) = I0 + (i_ideal*x_ideal - I0)*2^((x_ideal-x)/d) -//! ``` -//! -//! Thus we have the following properties: -//! * `I_NPoS > I0` -//! * `I_NPoS(0) = I0` -//! * `I_NPoS(x_ideal) = max(I_NPoS) = x_ideal*i_ideal` -//! * `i(x)` is monotone decreasing -//! -//! More details can be found [here](http://research.web3.foundation/en/latest/polkadot/Token%20Eco -//! nomics/#inflation-model) - -use sr_primitives::{Perbill, traits::SimpleArithmetic}; - -/// Linear function truncated to positive part `y = max(0, b [+ or -] a*x)` for `P_NPoS` usage. -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -struct Linear { - // Negate the `a*x` term. - negative_a: bool, - // Per-billion representation of `a`, the x coefficient. - a: u32, - // Per-billion representation of `b`, the intercept. - b: u32, -} - -impl Linear { - /// Compute `f(n/d)*d`. This is useful to avoid loss of precision. - fn calculate_for_fraction_times_denominator(&self, n: N, d: N) -> N - where - N: SimpleArithmetic + Clone - { - if self.negative_a { - (Perbill::from_parts(self.b) * d).saturating_sub(Perbill::from_parts(self.a) * n) - } else { - (Perbill::from_parts(self.b) * d).saturating_add(Perbill::from_parts(self.a) * n) - } - } -} - -/// Piecewise Linear function for `P_NPoS` usage -#[derive(Debug, PartialEq, Eq)] -struct PiecewiseLinear { - /// Array of tuples of an abscissa in a per-billion representation and a linear function. - /// - /// Abscissas in the array must be in order from the lowest to the highest. - /// - /// The array defines a piecewise linear function as such: - /// * the n-th segment starts at the abscissa of the n-th element until the abscissa of the - /// n-th + 1 element, and is defined by the linear function of the n-th element - /// * last segment doesn't end - pieces: [(u32, Linear); 20], -} - -impl PiecewiseLinear { - /// Compute `f(n/d)*d`. This is useful to avoid loss of precision. - fn calculate_for_fraction_times_denominator(&self, n: N, d: N) -> N where - N: SimpleArithmetic + Clone - { - let part = self.pieces.iter() - .take_while(|(abscissa, _)| n > Perbill::from_parts(*abscissa) * d.clone()) - .last() - .unwrap_or(&self.pieces[0]); - - part.1.calculate_for_fraction_times_denominator(n, d) - } -} - -/// Piecewise linear approximation of `I_NPoS`. -/// -/// Using the constants: -/// * `I_0` = 0.025; -/// * `i_ideal` = 0.2; -/// * `x_ideal` = 0.5; -/// * `d` = 0.05; -/// -/// This approximation is tested to be close to real one by an error less than 1% see -/// `i_npos_precision` test. -const I_NPOS: PiecewiseLinear = PiecewiseLinear { - pieces: [ - (0, Linear { negative_a: false, a: 150000000, b: 25000000 }), - (500000000, Linear { negative_a: true, a: 986493987, b: 593246993 }), - (507648979, Linear { negative_a: true, a: 884661327, b: 541551747 }), - (515726279, Linear { negative_a: true, a: 788373842, b: 491893761 }), - (524282719, Linear { negative_a: true, a: 697631517, b: 444319128 }), - (533378749, Linear { negative_a: true, a: 612434341, b: 398876765 }), - (543087019, Linear { negative_a: true, a: 532782338, b: 355618796 }), - (553495919, Linear { negative_a: true, a: 458675508, b: 314600968 }), - (564714479, Linear { negative_a: true, a: 390113843, b: 275883203 }), - (576879339, Linear { negative_a: true, a: 327097341, b: 239530285 }), - (590164929, Linear { negative_a: true, a: 269626004, b: 205612717 }), - (604798839, Linear { negative_a: true, a: 217699848, b: 174207838 }), - (621085859, Linear { negative_a: true, a: 171318873, b: 145401271 }), - (639447429, Linear { negative_a: true, a: 130483080, b: 119288928 }), - (660489879, Linear { negative_a: true, a: 95192479, b: 95979842 }), - (685131379, Linear { negative_a: true, a: 65447076, b: 75600334 }), - (714860569, Linear { negative_a: true, a: 41246910, b: 58300589 }), - (752334749, Linear { negative_a: true, a: 22592084, b: 44265915 }), - (803047659, Linear { negative_a: true, a: 9482996, b: 33738693 }), - (881691659, Linear { negative_a: true, a: 2572702, b: 27645944 }) - ] -}; +use sr_primitives::{Perbill, traits::SimpleArithmetic, curve::PiecewiseLinear}; /// The total payout to all validators (and their nominators) per era. /// -/// `era_duration` is expressed in millisecond. -/// -/// Named P_NPoS in the [paper](http://research.web3.foundation/en/latest/polkadot/Token%20Ec -/// onomics/#inflation-model). +/// Defined as such: +/// `payout = yearly_inflation(npos_token_staked / total_tokens) * total_tokans / era_per_year` /// -/// For x the staking rate in NPoS: `P_NPoS(x) = I_NPoS(x) * current_total_token / era_per_year` -/// i.e. `P_NPoS(x) = I_NPoS(x) * current_total_token * era_duration / year_duration` -/// -/// I_NPoS is the desired yearly inflation rate for nominated proof of stake. -pub fn compute_total_payout(npos_token_staked: N, total_tokens: N, era_duration: u64) -> N where - N: SimpleArithmetic + Clone +/// `era_duration` is expressed in millisecond. +pub fn compute_total_payout( + yearly_inflation: &PiecewiseLinear<'static>, + npos_token_staked: N, + total_tokens: N, + era_duration: u64 +) -> N where N: SimpleArithmetic + Clone { // Milliseconds per year for the Julian year (365.25 days). const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100; Perbill::from_rational_approximation(era_duration as u64, MILLISECONDS_PER_YEAR) - * I_NPOS.calculate_for_fraction_times_denominator(npos_token_staked, total_tokens) + * yearly_inflation.calculate_for_fraction_times_denominator(npos_token_staked, total_tokens) } -#[allow(non_upper_case_globals, non_snake_case)] // To stick with paper notations #[cfg(test)] -mod test_inflation { - use std::convert::TryInto; - - // Function `y = a*x + b` using float used for testing precision of Linear - #[derive(Debug)] - struct LinearFloat { - a: f64, - b: f64, - } - - impl LinearFloat { - fn new(x0: f64, y0: f64, x1: f64, y1: f64) -> Self { - LinearFloat { - a: (y1 - y0) / (x1 - x0), - b: (x0 * y1 - x1 * y0) / (x0 - x1), - } - } - - fn compute(&self, x: f64) -> f64 { - self.a * x + self.b - } - } - - #[test] - fn linear_float_works() { - assert_eq!(LinearFloat::new(1.0, 2.0, 4.0, 3.0).compute(7.0), 4.0); - } - - // Constants defined in paper - const I_0: f64 = 0.025; - const i_ideal: f64 = 0.2; - const x_ideal: f64 = 0.5; - const d: f64 = 0.05; - - // Left part from `x_ideal` - fn I_left(x: f64) -> f64 { - I_0 + x * (i_ideal - I_0 / x_ideal) - } - - // Right part from `x_ideal` - fn I_right(x: f64) -> f64 { - I_0 + (i_ideal * x_ideal - I_0) * 2_f64.powf((x_ideal - x) / d) - } - - // Definition of I_NPoS in float - fn I_full(x: f64) -> f64 { - if x <= x_ideal { - I_left(x) - } else { - I_right(x) - } +mod test { + use sr_primitives::curve::PiecewiseLinear; + + srml_staking_reward_curve::build! { + const I_NPOS: PiecewiseLinear<'static> = curve!( + min_inflation: 0_025_000, + max_inflation: 0_100_000, + ideal_stake: 0_500_000, + falloff: 0_050_000, + max_piece_count: 40, + test_precision: 0_005_000, + ); } #[test] fn npos_curve_is_sensible() { const YEAR: u64 = 365 * 24 * 60 * 60 * 1000; - //super::I_NPOS.calculate_for_fraction_times_denominator(25, 100) - assert_eq!(super::compute_total_payout(0, 100_000u64, YEAR), 2_498); - assert_eq!(super::compute_total_payout(5_000, 100_000u64, YEAR), 3_247); - assert_eq!(super::compute_total_payout(25_000, 100_000u64, YEAR), 6_245); - assert_eq!(super::compute_total_payout(40_000, 100_000u64, YEAR), 8_494); - assert_eq!(super::compute_total_payout(50_000, 100_000u64, YEAR), 9_993); - assert_eq!(super::compute_total_payout(60_000, 100_000u64, YEAR), 4_380); - assert_eq!(super::compute_total_payout(75_000, 100_000u64, YEAR), 2_735); - assert_eq!(super::compute_total_payout(95_000, 100_000u64, YEAR), 2_518); - assert_eq!(super::compute_total_payout(100_000, 100_000u64, YEAR), 2_505); + assert_eq!(super::compute_total_payout(&I_NPOS, 0, 100_000u64, YEAR), 2_498); + assert_eq!(super::compute_total_payout(&I_NPOS, 5_000, 100_000u64, YEAR), 3_247); + assert_eq!(super::compute_total_payout(&I_NPOS, 25_000, 100_000u64, YEAR), 6_245); + assert_eq!(super::compute_total_payout(&I_NPOS, 40_000, 100_000u64, YEAR), 8_494); + assert_eq!(super::compute_total_payout(&I_NPOS, 50_000, 100_000u64, YEAR), 9_993); + assert_eq!(super::compute_total_payout(&I_NPOS, 60_000, 100_000u64, YEAR), 4_379); + assert_eq!(super::compute_total_payout(&I_NPOS, 75_000, 100_000u64, YEAR), 2_733); + assert_eq!(super::compute_total_payout(&I_NPOS, 95_000, 100_000u64, YEAR), 2_513); + assert_eq!(super::compute_total_payout(&I_NPOS, 100_000, 100_000u64, YEAR), 2_505); const DAY: u64 = 24 * 60 * 60 * 1000; - assert_eq!(super::compute_total_payout(25_000, 100_000u64, DAY), 17); - assert_eq!(super::compute_total_payout(50_000, 100_000u64, DAY), 27); - assert_eq!(super::compute_total_payout(75_000, 100_000u64, DAY), 7); + assert_eq!(super::compute_total_payout(&I_NPOS, 25_000, 100_000u64, DAY), 17); + assert_eq!(super::compute_total_payout(&I_NPOS, 50_000, 100_000u64, DAY), 27); + assert_eq!(super::compute_total_payout(&I_NPOS, 75_000, 100_000u64, DAY), 7); const SIX_HOURS: u64 = 6 * 60 * 60 * 1000; - assert_eq!(super::compute_total_payout(25_000, 100_000u64, SIX_HOURS), 4); - assert_eq!(super::compute_total_payout(50_000, 100_000u64, SIX_HOURS), 6); - assert_eq!(super::compute_total_payout(75_000, 100_000u64, SIX_HOURS), 1); + assert_eq!(super::compute_total_payout(&I_NPOS, 25_000, 100_000u64, SIX_HOURS), 4); + assert_eq!(super::compute_total_payout(&I_NPOS, 50_000, 100_000u64, SIX_HOURS), 6); + assert_eq!(super::compute_total_payout(&I_NPOS, 75_000, 100_000u64, SIX_HOURS), 1); const HOUR: u64 = 60 * 60 * 1000; assert_eq!( super::compute_total_payout( + &I_NPOS, 2_500_000_000_000_000_000_000_000_000u128, 5_000_000_000_000_000_000_000_000_000u128, HOUR @@ -254,167 +90,4 @@ mod test_inflation { 57_038_500_000_000_000_000_000 ); } - - // Compute approximation of I_NPoS into piecewise linear function - fn I_NPoS_points() -> super::PiecewiseLinear { - let mut points = vec![]; - - // Points for left part - points.push((0.0, I_0)); - points.push((x_ideal, I_left(x_ideal))); - - // Approximation for right part. - // - // We start from x_ideal (x0) and we try to find the next point (x1) for which the linear - // approximation of (x0, x1) doesn't deviate from float definition by an error of - // GEN_ERROR. - - // When computing deviation between linear approximation and float definition we iterate - // over all points with this step precision. - const STEP_PRECISION: f64 = 0.000_000_1; - // Max error used for generating points. - const GEN_ERROR: f64 = 0.000_1; - - let mut x0: f64 = x_ideal; - let mut x1: f64 = x0; - - // This is just a step used to find next x1: - // if x1 + step result in a not enought precise approximation we reduce step and try again. - // we stop as soon as step is less than STEP_PRECISION. - let mut step: f64 = 0.1; - - loop { - let next_x1 = x1 + step; - - if next_x1 >= 1.0 { - points.push((1.0, I_right(1.0))); - break; - } - - let y0 = I_right(x0); - let next_y1 = I_right(next_x1); - - let mut error_overflowed = false; - - // Test error is not overflowed - - // Quick test on one point - if (I_right((x0 + next_x1) / 2.0) - (y0 + next_y1) / 2.0).abs() > GEN_ERROR { - error_overflowed = true; - } - - // Long test on all points - if !error_overflowed { - let linear = LinearFloat::new(x0, y0, next_x1, next_y1); - let mut cursor = x0; - while cursor < x1 { - if (I_right(cursor) - linear.compute(cursor)).abs() > GEN_ERROR { - error_overflowed = true; - } - cursor += STEP_PRECISION; - } - } - - if error_overflowed { - if step <= STEP_PRECISION { - points.push((x1, I_right(x1))); - x0 = x1; - step = 0.1; - } else { - step /= 10.0; - } - } else { - x1 = next_x1; - } - } - - // Convert points to piecewise linear definition - let pieces: Vec<(u32, super::Linear)> = (0..points.len()-1) - .map(|i| { - let p0 = points[i]; - let p1 = points[i + 1]; - - let linear = LinearFloat::new(p0.0, p0.1, p1.0, p1.1); - - // Needed if we want to use a Perbill later - assert!(linear.a.abs() <= 1.0); - // Needed if we want to use a Perbill later - assert!(linear.b.abs() <= 1.0); - // Needed to stick with our restrictive definition of linear - assert!(linear.b.signum() == 1.0); - - ( - (p0.0 * 1_000_000_000.0) as u32, - super::Linear { - negative_a: linear.a.signum() < 0.0, - a: (linear.a.abs() * 1_000_000_000.0) as u32, - b: (linear.b.abs() * 1_000_000_000.0) as u32, - } - ) - }) - .collect(); - - println!("Generated pieces: {:?}", pieces); - assert_eq!(pieces.len(), 20); - - super::PiecewiseLinear { pieces: (&pieces[..]).try_into().unwrap() } - } - - /// This test is only useful to generate a new set of points for the definition of I_NPoS. - #[test] - fn generate_I_NPOS() { - assert_eq!(super::I_NPOS, I_NPoS_points()); - } - - /// This test ensure that i_npos piecewise linear approximation is close to the actual function. - /// It does compare the result from a computation in integer of different capacity and in f64. - #[test] - fn i_npos_precision() { - const STEP_PRECISION: f64 = 0.000_001; - const ERROR: f64 = 0.000_2; - - macro_rules! test_for_value { - ($($total_token:expr => $type:ty,)*) => { - let mut x = 0.1; - while x <= 1.0 { - let expected = I_full(x); - $({ - let result = super::I_NPOS.calculate_for_fraction_times_denominator( - (x * $total_token as f64) as $type, - $total_token, - ) as f64; - let expected = expected * $total_token as f64; - let error = (ERROR * $total_token as f64).max(2.0); - - let diff = (result - expected).abs(); - if diff >= error { - println!("total_token: {}", $total_token); - println!("x: {}", x); - println!("diff: {}", diff); - println!("error: {}", error); - panic!("error overflowed"); - } - })* - x += STEP_PRECISION - } - } - } - - test_for_value!( - 1_000u32 => u32, - 1_000_000u32 => u32, - 1_000_000_000u32 => u32, - 1_000_000_000_000u64 => u64, - 1_000_000_000_000_000u64 => u64, - 1_000_000_000_000_000_000u64 => u64, - 1_000_000_000_000_000_000_000u128 => u128, - 1_000_000_000_000_000_000_000_000u128 => u128, - 1_000_000_000_000_000_000_000_000_000u128 => u128, - 1_000_000_000_000_000_000_000_000_000_000u128 => u128, - 1_000_000_000_000_000_000_000_000_000_000_000_000u128 => u128, - u32::max_value() => u32, - u64::max_value() => u64, - u128::max_value() => u128, - ); - } } diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index 3f88b67875..c450e142af 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -261,11 +261,14 @@ use support::{ } }; use session::{historical::OnSessionEnding, SelectInitialValidators}; -use sr_primitives::Perbill; -use sr_primitives::weights::SimpleDispatchInfo; -use sr_primitives::traits::{ - Convert, Zero, One, StaticLookup, CheckedSub, Saturating, Bounded, SimpleArithmetic, - SaturatedConversion, +use sr_primitives::{ + Perbill, + curve::PiecewiseLinear, + weights::SimpleDispatchInfo, + traits::{ + Convert, Zero, One, StaticLookup, CheckedSub, Saturating, Bounded, SimpleArithmetic, + SaturatedConversion, + } }; use phragmen::{elect, equalize, Support, SupportMap, ExtendedBalance, ACCURACY}; use sr_staking_primitives::{ @@ -523,6 +526,9 @@ pub trait Trait: system::Trait { /// Interface for interacting with a session module. type SessionInterface: self::SessionInterface; + + /// The NPoS reward curve to use. + type RewardCurve: Get<&'static PiecewiseLinear<'static>>; } /// Mode of era-forcing. @@ -1173,6 +1179,7 @@ impl Module { let total_rewarded_stake = Self::slot_stake() * validator_len; let total_payout = inflation::compute_total_payout( + &T::RewardCurve::get(), total_rewarded_stake.clone(), T::Currency::total_issuance(), // Duration of era; more than u64::MAX is rewarded as u64::MAX. diff --git a/srml/staking/src/mock.rs b/srml/staking/src/mock.rs index 747ee64470..ba1645e6d7 100644 --- a/srml/staking/src/mock.rs +++ b/srml/staking/src/mock.rs @@ -18,6 +18,7 @@ use std::{collections::HashSet, cell::RefCell}; use sr_primitives::Perbill; +use sr_primitives::curve::PiecewiseLinear; use sr_primitives::traits::{IdentityLookup, Convert, OpaqueKeys, OnInitialize, SaturatedConversion}; use sr_primitives::testing::{Header, UintAuthorityId}; use sr_staking_primitives::SessionIndex; @@ -182,9 +183,20 @@ impl timestamp::Trait for Test { type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; } +srml_staking_reward_curve::build! { + const I_NPOS: PiecewiseLinear<'static> = curve!( + min_inflation: 0_025_000, + max_inflation: 0_100_000, + ideal_stake: 0_500_000, + falloff: 0_050_000, + max_piece_count: 40, + test_precision: 0_005_000, + ); +} parameter_types! { pub const SessionsPerEra: SessionIndex = 3; pub const BondingDuration: EraIndex = 3; + pub const RewardCurve: &'static PiecewiseLinear<'static> = &I_NPOS; } impl Trait for Test { type Currency = balances::Module; @@ -197,6 +209,7 @@ impl Trait for Test { type SessionsPerEra = SessionsPerEra; type BondingDuration = BondingDuration; type SessionInterface = Self; + type RewardCurve = RewardCurve; } pub struct ExtBuilder { @@ -430,6 +443,7 @@ pub fn start_era(era_index: EraIndex) { pub fn current_total_payout_for_duration(duration: u64) -> u64 { let res = inflation::compute_total_payout( + ::RewardCurve::get(), >::slot_stake() * 2, Balances::total_issuance(), duration, -- GitLab From a2df800227c6cf11cdb1a642de22ccfea56bf899 Mon Sep 17 00:00:00 2001 From: Joshy Orndorff Date: Fri, 20 Sep 2019 20:48:03 -0800 Subject: [PATCH 118/275] Remove unused key types sr25 and ed25 (#3659) * Remove unused key types sr25 and ed25. * Restore in specific files to fix build. * Fix runtime tests * Fix keystore test * Revert typo * Move keytypes to primitives/src/testing.rs * More missed items. * Getting close now. * Fix example in documentation. * Update core/application-crypto/src/ed25519.rs * Update core/application-crypto/src/sr25519.rs * Bump impl version. --- core/application-crypto/src/ed25519.rs | 13 ++++++++++--- core/application-crypto/src/sr25519.rs | 13 ++++++++++--- core/keystore/src/lib.rs | 6 +++--- core/primitives/src/crypto.rs | 4 ---- core/primitives/src/testing.rs | 21 +++++++++++++++------ core/rpc/src/author/tests.rs | 12 ++++++------ core/sr-primitives/src/traits.rs | 7 ++++--- core/test-runtime/src/lib.rs | 15 +++++++++++---- node/runtime/src/lib.rs | 2 +- 9 files changed, 60 insertions(+), 33 deletions(-) diff --git a/core/application-crypto/src/ed25519.rs b/core/application-crypto/src/ed25519.rs index a1aef4a328..d5c4fd7bad 100644 --- a/core/application-crypto/src/ed25519.rs +++ b/core/application-crypto/src/ed25519.rs @@ -21,7 +21,7 @@ use crate::{RuntimePublic, KeyTypeId}; pub use primitives::ed25519::*; mod app { - use crate::key_types::ED25519; + use primitives::testing::ED25519; crate::app_crypto!(super, ED25519); } @@ -53,7 +53,14 @@ impl RuntimePublic for Public { #[cfg(test)] mod tests { use sr_primitives::{generic::BlockId, traits::ProvideRuntimeApi}; - use primitives::{testing::KeyStore, crypto::Pair, traits::BareCryptoStore as _}; + use primitives::{ + testing::{ + KeyStore, + ED25519, + }, + crypto::Pair, + traits::BareCryptoStore as _, + }; use test_client::{ TestClientBuilder, DefaultTestClientBuilderExt, TestClientBuilderExt, runtime::{TestAPI, app_crypto::ed25519::{AppPair, AppPublic}}, @@ -67,7 +74,7 @@ mod tests { .test_ed25519_crypto(&BlockId::Number(0)) .expect("Tests `ed25519` crypto."); - let key_pair = keystore.read().ed25519_key_pair(crate::key_types::ED25519, &public.as_ref()) + let key_pair = keystore.read().ed25519_key_pair(ED25519, &public.as_ref()) .expect("There should be at a `ed25519` key in the keystore for the given public key."); assert!(AppPair::verify(&signature, "ed25519", &AppPublic::from(key_pair.public()))); diff --git a/core/application-crypto/src/sr25519.rs b/core/application-crypto/src/sr25519.rs index c3cc9df267..93565a628f 100644 --- a/core/application-crypto/src/sr25519.rs +++ b/core/application-crypto/src/sr25519.rs @@ -21,7 +21,7 @@ use crate::{RuntimePublic, KeyTypeId}; pub use primitives::sr25519::*; mod app { - use crate::key_types::SR25519; + use primitives::testing::SR25519; crate::app_crypto!(super, SR25519); } @@ -53,7 +53,14 @@ impl RuntimePublic for Public { #[cfg(test)] mod tests { use sr_primitives::{generic::BlockId, traits::ProvideRuntimeApi}; - use primitives::{testing::KeyStore, crypto::Pair, traits::BareCryptoStore as _}; + use primitives::{ + testing::{ + KeyStore, + SR25519, + }, + crypto::Pair, + traits::BareCryptoStore as _, + }; use test_client::{ TestClientBuilder, DefaultTestClientBuilderExt, TestClientBuilderExt, runtime::{TestAPI, app_crypto::sr25519::{AppPair, AppPublic}}, @@ -67,7 +74,7 @@ mod tests { .test_sr25519_crypto(&BlockId::Number(0)) .expect("Tests `sr25519` crypto."); - let key_pair = keystore.read().sr25519_key_pair(crate::key_types::SR25519, public.as_ref()) + let key_pair = keystore.read().sr25519_key_pair(SR25519, public.as_ref()) .expect("There should be at a `sr25519` key in the keystore for the given public key."); assert!(AppPair::verify(&signature, "sr25519", &AppPublic::from(key_pair.public()))); diff --git a/core/keystore/src/lib.rs b/core/keystore/src/lib.rs index 9125ddbda6..c86e9f8b88 100644 --- a/core/keystore/src/lib.rs +++ b/core/keystore/src/lib.rs @@ -318,7 +318,7 @@ impl BareCryptoStore for Store { mod tests { use super::*; use tempdir::TempDir; - use primitives::crypto::{Ss58Codec, key_types}; + use primitives::{testing::{SR25519}, crypto::{Ss58Codec}}; #[test] fn basic_store() { @@ -410,14 +410,14 @@ mod tests { let key_pair = sr25519::AppPair::from_string(secret_uri, None).expect("Generates key pair"); store.write().insert_unknown( - key_types::SR25519, + SR25519, secret_uri, key_pair.public().as_ref(), ).expect("Inserts unknown key"); let store_key_pair = store.read().key_pair_by_type::( &key_pair.public(), - key_types::SR25519, + SR25519, ).expect("Gets key pair from keystore"); assert_eq!(key_pair.public(), store_key_pair.public()); diff --git a/core/primitives/src/crypto.rs b/core/primitives/src/crypto.rs index 5887866735..e2838315d1 100644 --- a/core/primitives/src/crypto.rs +++ b/core/primitives/src/crypto.rs @@ -780,10 +780,6 @@ impl<'a> TryFrom<&'a str> for KeyTypeId { pub mod key_types { use super::KeyTypeId; - /// Key type for generic S/R 25519 key. - pub const SR25519: KeyTypeId = KeyTypeId(*b"sr25"); - /// Key type for generic Ed25519 key. - pub const ED25519: KeyTypeId = KeyTypeId(*b"ed25"); /// Key type for Babe module, build-in. pub const BABE: KeyTypeId = KeyTypeId(*b"babe"); /// Key type for Grandpa module, build-in. diff --git a/core/primitives/src/testing.rs b/core/primitives/src/testing.rs index 932c8b9cb1..ccfc36af73 100644 --- a/core/primitives/src/testing.rs +++ b/core/primitives/src/testing.rs @@ -17,7 +17,14 @@ //! Types that should only be used for testing! #[cfg(feature = "std")] -use crate::{ed25519, sr25519, crypto::{Public, Pair, KeyTypeId}}; +use crate::{ed25519, sr25519, crypto::{Public, Pair}}; +use crate::crypto::KeyTypeId; // No idea why this import had to move from + // the previous line, but now the compiler is happy + +/// Key type for generic Ed25519 key. +pub const ED25519: KeyTypeId = KeyTypeId(*b"ed25"); +/// Key type for generic Sr 25519 key. +pub const SR25519: KeyTypeId = KeyTypeId(*b"sr25"); /// A keystore implementation usable in tests. #[cfg(feature = "std")] @@ -126,18 +133,20 @@ impl crate::traits::BareCryptoStore for KeyStore { #[cfg(test)] mod tests { use super::*; - use crate::{sr25519, crypto::key_types, traits::BareCryptoStore}; + use crate::{sr25519, traits::BareCryptoStore}; + use crate::testing::{ED25519, SR25519}; + #[test] fn store_key_and_extract() { let store = KeyStore::new(); let public = store.write() - .ed25519_generate_new(key_types::ED25519, None) + .ed25519_generate_new(ED25519, None) .expect("Genrates key"); let store_key_pair = store.read() - .ed25519_key_pair(key_types::ED25519, &public) + .ed25519_key_pair(ED25519, &public) .expect("Key should exists in store"); assert_eq!(public, store_key_pair.public()); @@ -151,13 +160,13 @@ mod tests { let key_pair = sr25519::Pair::from_string(secret_uri, None).expect("Generates key pair"); store.write().insert_unknown( - key_types::SR25519, + SR25519, secret_uri, key_pair.public().as_ref(), ).expect("Inserts unknown key"); let store_key_pair = store.read().sr25519_key_pair( - key_types::SR25519, + SR25519, &key_pair.public(), ).expect("Gets key pair from keystore"); diff --git a/core/rpc/src/author/tests.rs b/core/rpc/src/author/tests.rs index 861b65bfe7..1f652aec64 100644 --- a/core/rpc/src/author/tests.rs +++ b/core/rpc/src/author/tests.rs @@ -25,8 +25,8 @@ use transaction_pool::{ }; use futures::Stream; use primitives::{ - H256, blake2_256, hexdisplay::HexDisplay, traits::BareCryptoStore, testing::KeyStore, - ed25519, crypto::{key_types, Pair}, + H256, blake2_256, hexdisplay::HexDisplay, traits::BareCryptoStore, + testing::{ED25519, SR25519, KeyStore}, ed25519, crypto::Pair }; use test_client::{ self, AccountKeyring, runtime::{Extrinsic, Transfer, SessionKeys}, DefaultTestClientBuilderExt, @@ -198,13 +198,13 @@ fn should_insert_key() { let suri = "//Alice"; let key_pair = ed25519::Pair::from_string(suri, None).expect("Generates keypair"); p.insert_key( - String::from_utf8(key_types::ED25519.0.to_vec()).expect("Keytype is a valid string"), + String::from_utf8(ED25519.0.to_vec()).expect("Keytype is a valid string"), suri.to_string(), key_pair.public().0.to_vec().into(), ).expect("Insert key"); let store_key_pair = keystore.read() - .ed25519_key_pair(key_types::ED25519, &key_pair.public()).expect("Key exists in store"); + .ed25519_key_pair(ED25519, &key_pair.public()).expect("Key exists in store"); assert_eq!(key_pair.public(), store_key_pair.public()); } @@ -227,12 +227,12 @@ fn should_rotate_keys() { .expect("SessionKeys decode successfully"); let ed25519_key_pair = keystore.read().ed25519_key_pair( - key_types::ED25519, + ED25519, &session_keys.ed25519.clone().into(), ).expect("ed25519 key exists in store"); let sr25519_key_pair = keystore.read().sr25519_key_pair( - key_types::SR25519, + SR25519, &session_keys.sr25519.clone().into(), ).expect("sr25519 key exists in store"); diff --git a/core/sr-primitives/src/traits.rs b/core/sr-primitives/src/traits.rs index a2bc5bc6dc..de200bdf55 100644 --- a/core/sr-primitives/src/traits.rs +++ b/core/sr-primitives/src/traits.rs @@ -1180,13 +1180,14 @@ macro_rules! count { /// just the bytes of the key. /// /// ```rust -/// use sr_primitives::{impl_opaque_keys, key_types, KeyTypeId, app_crypto::{sr25519, ed25519}}; +/// use sr_primitives::{impl_opaque_keys, KeyTypeId, app_crypto::{sr25519, ed25519}}; +/// use primitives::testing::{SR25519, ED25519}; /// /// impl_opaque_keys! { /// pub struct Keys { -/// #[id(key_types::ED25519)] +/// #[id(ED25519)] /// pub ed25519: ed25519::AppPublic, -/// #[id(key_types::SR25519)] +/// #[id(SR25519)] /// pub sr25519: sr25519::AppPublic, /// } /// } diff --git a/core/test-runtime/src/lib.rs b/core/test-runtime/src/lib.rs index c3b05b53d4..815f43c3db 100644 --- a/core/test-runtime/src/lib.rs +++ b/core/test-runtime/src/lib.rs @@ -25,7 +25,14 @@ pub mod system; use rstd::{prelude::*, marker::PhantomData}; use codec::{Encode, Decode, Input, Error}; -use primitives::{Blake2Hasher, OpaqueMetadata}; +use primitives::{ + Blake2Hasher, + OpaqueMetadata, + testing::{ + ED25519, + SR25519, + } +}; use app_crypto::{ed25519, sr25519, RuntimeAppPublic}; pub use app_crypto; use trie_db::{TrieMut, Trie}; @@ -47,7 +54,7 @@ use sr_primitives::{ }, }; use runtime_version::RuntimeVersion; -pub use primitives::{hash::H256, crypto::key_types}; +pub use primitives::{hash::H256}; #[cfg(any(feature = "std", test))] use runtime_version::NativeVersion; use runtime_support::{impl_outer_origin, parameter_types}; @@ -446,9 +453,9 @@ fn code_using_trie() -> u64 { impl_opaque_keys! { pub struct SessionKeys { - #[id(key_types::ED25519)] + #[id(ED25519)] pub ed25519: ed25519::AppPublic, - #[id(key_types::SR25519)] + #[id(SR25519)] pub sr25519: sr25519::AppPublic, } } diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index bee5e7fc22..70bc1a00af 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -85,7 +85,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 160, - impl_version: 160, + impl_version: 161, apis: RUNTIME_API_VERSIONS, }; -- GitLab From 4117bb9ff5536ae632056e77219789151e0f6aed Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Sat, 21 Sep 2019 19:50:37 +0800 Subject: [PATCH 119/275] Only submit signed extrinsics back to pool when retracting block (#3660) * Only submit signed extrinsics back to pool when retracting block * Fix import --- core/service/src/builder.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/core/service/src/builder.rs b/core/service/src/builder.rs index e6d2cdc89a..aeafe9e82b 100644 --- a/core/service/src/builder.rs +++ b/core/service/src/builder.rs @@ -34,7 +34,9 @@ use parking_lot::{Mutex, RwLock}; use primitives::{Blake2Hasher, H256, Hasher}; use rpc::{self, system::SystemInfo}; use sr_primitives::{BuildStorage, generic::BlockId}; -use sr_primitives::traits::{Block as BlockT, ProvideRuntimeApi, NumberFor, One, Zero, Header, SaturatedConversion}; +use sr_primitives::traits::{ + Block as BlockT, Extrinsic, ProvideRuntimeApi, NumberFor, One, Zero, Header, SaturatedConversion +}; use substrate_executor::{NativeExecutor, NativeExecutionDispatch}; use serde::{Serialize, de::DeserializeOwned}; use std::{io::{Read, Write, Seek}, marker::PhantomData, sync::Arc, sync::atomic::AtomicBool}; @@ -929,7 +931,13 @@ pub(crate) fn maintain_transaction_pool( for r in retracted { if let Some(block) = client.block(&BlockId::hash(*r))? { let extrinsics = block.block.extrinsics(); - if let Err(e) = transaction_pool.submit_at(id, extrinsics.iter().cloned(), true) { + if let Err(e) = transaction_pool.submit_at( + id, + extrinsics.iter().filter(|e| { + e.is_signed().unwrap_or(false) + }).cloned(), + true + ) { warn!("Error re-submitting transactions: {:?}", e); } } -- GitLab From bbe90e31ed2fd71dc037fc385dae32584d2b1ce8 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Mon, 23 Sep 2019 00:12:30 +0200 Subject: [PATCH 120/275] improve justification docs --- core/sr-primitives/src/lib.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index 81e73033b2..4d3bfb2c92 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -59,7 +59,13 @@ pub use generic::{DigestItem, Digest}; pub use primitives::crypto::{key_types, KeyTypeId, CryptoType}; pub use app_crypto::RuntimeAppPublic; -/// Justification type. +/// An abstraction over justification for a block's validity under a consensus algorithm. +/// +/// Essentially a finality proof. The exact formulation will vary between consensus +/// algorithms. In the case where there are multiple valid proofs, inclusion within +/// the block itself would allow swapping justifications to change the block's hash +/// (and thus fork the chain). Sending a `Justification` alongside a block instead +/// bypasses this problem. pub type Justification = Vec; use traits::{Verify, Lazy}; -- GitLab From f570abe2e471e0f56d224e508ae343c116e8b6c4 Mon Sep 17 00:00:00 2001 From: Ashley Date: Mon, 23 Sep 2019 21:32:44 +1200 Subject: [PATCH 121/275] Rename more things related to contract instantiation (#3664) * Rename more things related to contract instantiation * rename `creator_ch` * Fix node runtime * fix contracts tests * Little fix --- node/runtime/src/lib.rs | 4 +- srml/contracts/COMPLEXITY.md | 10 ++-- srml/contracts/src/account_db.rs | 8 ++-- srml/contracts/src/exec.rs | 68 +++++++++++++-------------- srml/contracts/src/lib.rs | 75 +++++++++++++++--------------- srml/contracts/src/tests.rs | 22 ++++----- srml/contracts/src/wasm/mod.rs | 18 +++---- srml/contracts/src/wasm/runtime.rs | 26 ++++++----- 8 files changed, 117 insertions(+), 114 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 70bc1a00af..23f4d3845a 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -84,7 +84,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 160, + spec_version: 161, impl_version: 161, apis: RUNTIME_API_VERSIONS, }; @@ -409,7 +409,7 @@ impl contracts::Trait for Runtime { type TransactionByteFee = ContractTransactionByteFee; type ContractFee = ContractFee; type CallBaseFee = contracts::DefaultCallBaseFee; - type CreateBaseFee = contracts::DefaultCreateBaseFee; + type InstantiateBaseFee = contracts::DefaultInstantiateBaseFee; type MaxDepth = contracts::DefaultMaxDepth; type MaxValueSize = contracts::DefaultMaxValueSize; type BlockGasLimit = contracts::DefaultBlockGasLimit; diff --git a/srml/contracts/COMPLEXITY.md b/srml/contracts/COMPLEXITY.md index 1e306038ef..a29127f778 100644 --- a/srml/contracts/COMPLEXITY.md +++ b/srml/contracts/COMPLEXITY.md @@ -123,7 +123,7 @@ While these functions only modify the local `Map`, if changes made by them are c **complexity**: Each lookup has a logarithmical computing time to the number of already inserted entries. No additional memory is required. -## create_contract +## instantiate_contract Calls `contract_exists` and if it doesn't exist, do not modify the local `Map` similarly to `set_rent_allowance`. @@ -174,7 +174,7 @@ Assuming marshaled size of a balance value is of the constant size we can neglec ## Initialization -Before a call or create can be performed the execution context must be initialized. +Before a call or instantiate can be performed the execution context must be initialized. For the first call or instantiation in the handling of an extrinsic, this involves two calls: @@ -213,7 +213,7 @@ and on top of that at most once per block: - `kill_child_storage` - mutation of `ContractInfoOf` -Loading code most likely will trigger a DB read, since the code is immutable and therefore will not get into the cache (unless a suicide removes it, or it has been created in the same call chain). +Loading code most likely will trigger a DB read, since the code is immutable and therefore will not get into the cache (unless a suicide removes it, or it has been instantiated in the same call chain). Also, `transfer` can make up to 2 DB reads and up to 2 DB writes (if flushed to the storage) in the standard case. If removal of the source account takes place then it will additionally perform a DB write per one storage entry that the account has. @@ -229,9 +229,9 @@ This function takes the code of the constructor and input data. Instantiation of 1. Initialization of the execution context. 2. Calling `DetermineContractAddress` hook to determine an address for the contract, -3. `transfer`-ing funds between self and the newly created contract. +3. `transfer`-ing funds between self and the newly instantiated contract. 4. Executing the constructor code. This will yield the final code of the code. -5. Storing the code for the newly created contract in the overlay. +5. Storing the code for the newly instantiated contract in the overlay. 6. Committing overlayed changed to the underlying `AccountDb`. **Note** that the complexity of executing the constructor code should be considered separately. diff --git a/srml/contracts/src/account_db.rs b/srml/contracts/src/account_db.rs index 6ce1dff22b..50bd1fd40e 100644 --- a/srml/contracts/src/account_db.rs +++ b/srml/contracts/src/account_db.rs @@ -37,7 +37,7 @@ pub struct ChangeEntry { /// If Some(_), then the account balance is modified to the value. If None and `reset` is false, /// the balance unmodified. If None and `reset` is true, the balance is reset to 0. balance: Option>, - /// If Some(_), then a contract is created with the code hash. If None and `reset` is false, + /// If Some(_), then a contract is instantiated with the code hash. If None and `reset` is false, /// then the contract code is unmodified. If None and `reset` is true, the contract is deleted. code_hash: Option>, /// If Some(_), then the rent allowance is set to the value. If None and `reset` is false, then @@ -189,7 +189,7 @@ impl AccountDb for DirectAccountDb { last_write: None, } } - // New contract is being created. + // New contract is being instantiated. (_, None, Some(code_hash)) => { AliveContractInfo:: { code_hash, @@ -200,7 +200,7 @@ impl AccountDb for DirectAccountDb { last_write: None, } } - // There is no existing at the address nor a new one to be created. + // There is no existing at the address nor a new one to be instantiated. (_, None, None) => continue, }; @@ -278,7 +278,7 @@ impl<'a, T: Trait> OverlayAccountDb<'a, T> { } /// Return an error if contract already exists (either if it is alive or tombstone) - pub fn create_contract( + pub fn instantiate_contract( &mut self, account: &T::AccountId, code_hash: CodeHash, diff --git a/srml/contracts/src/exec.rs b/srml/contracts/src/exec.rs index 5f871f519e..65fe89ed34 100644 --- a/srml/contracts/src/exec.rs +++ b/srml/contracts/src/exec.rs @@ -421,7 +421,7 @@ where ) -> Result<(T::AccountId, ExecReturnValue), ExecError> { if self.depth == self.config.max_depth as usize { return Err(ExecError { - reason: "reached maximum depth, cannot create", + reason: "reached maximum depth, cannot instantiate", buffer: input_data, }); } @@ -448,7 +448,7 @@ where let output = self.with_nested_context(dest.clone(), dest_trie_id, |nested| { try_or_exec_error!( - nested.overlay.create_contract(&dest, code_hash.clone()), + nested.overlay.instantiate_contract(&dest, code_hash.clone()), input_data ); @@ -941,7 +941,7 @@ mod tests { with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.create_contract(&BOB, exec_ch).unwrap(); + ctx.overlay.instantiate_contract(&BOB, exec_ch).unwrap(); assert_matches!( ctx.call(BOB, value, &mut gas_meter, data), @@ -1041,7 +1041,7 @@ mod tests { with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.create_contract(&BOB, return_ch).unwrap(); + ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap(); ctx.overlay.set_balance(&origin, 100); ctx.overlay.set_balance(&dest, 0); @@ -1064,7 +1064,7 @@ mod tests { let dest = BOB; // This test sends 50 units of currency to a non-existent account. - // This should create lead to creation of a new account thus + // This should lead to creation of a new account thus // a fee should be charged. with_externalities( &mut ExtBuilder::default().existential_deposit(15).build(), @@ -1123,7 +1123,7 @@ mod tests { ); // This test sends 50 units of currency as an endownment to a newly - // created contract. + // instantiated contract. with_externalities( &mut ExtBuilder::default().existential_deposit(15).build(), || { @@ -1202,7 +1202,7 @@ mod tests { with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.create_contract(&BOB, return_ch).unwrap(); + ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap(); let result = ctx.call( dest, @@ -1233,7 +1233,7 @@ mod tests { with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.create_contract(&BOB, return_ch).unwrap(); + ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap(); let result = ctx.call( dest, @@ -1261,7 +1261,7 @@ mod tests { with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.create_contract(&BOB, input_data_ch).unwrap(); + ctx.overlay.instantiate_contract(&BOB, input_data_ch).unwrap(); let result = ctx.call( BOB, @@ -1330,7 +1330,7 @@ mod tests { with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.create_contract(&BOB, recurse_ch).unwrap(); + ctx.overlay.instantiate_contract(&BOB, recurse_ch).unwrap(); let result = ctx.call( BOB, @@ -1375,8 +1375,8 @@ mod tests { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.create_contract(&dest, bob_ch).unwrap(); - ctx.overlay.create_contract(&CHARLIE, charlie_ch).unwrap(); + ctx.overlay.instantiate_contract(&dest, bob_ch).unwrap(); + ctx.overlay.instantiate_contract(&CHARLIE, charlie_ch).unwrap(); let result = ctx.call( dest, @@ -1416,8 +1416,8 @@ mod tests { with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.create_contract(&BOB, bob_ch).unwrap(); - ctx.overlay.create_contract(&CHARLIE, charlie_ch).unwrap(); + ctx.overlay.instantiate_contract(&BOB, bob_ch).unwrap(); + ctx.overlay.instantiate_contract(&CHARLIE, charlie_ch).unwrap(); let result = ctx.call( BOB, @@ -1472,7 +1472,7 @@ mod tests { let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); ctx.overlay.set_balance(&ALICE, 1000); - let created_contract_address = assert_matches!( + let instantiated_contract_address = assert_matches!( ctx.instantiate( 100, &mut GasMeter::::with_limit(10000, 1), @@ -1484,14 +1484,14 @@ mod tests { // Check that the newly created account has the expected code hash and // there are instantiation event. - assert_eq!(ctx.overlay.get_code_hash(&created_contract_address).unwrap(), dummy_ch); + assert_eq!(ctx.overlay.get_code_hash(&instantiated_contract_address).unwrap(), dummy_ch); assert_eq!(&ctx.events(), &[ DeferredAction::DepositEvent { - event: RawEvent::Transfer(ALICE, created_contract_address, 100), + event: RawEvent::Transfer(ALICE, instantiated_contract_address, 100), topics: Vec::new(), }, DeferredAction::DepositEvent { - event: RawEvent::Instantiated(ALICE, created_contract_address), + event: RawEvent::Instantiated(ALICE, instantiated_contract_address), topics: Vec::new(), } ]); @@ -1515,7 +1515,7 @@ mod tests { let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); ctx.overlay.set_balance(&ALICE, 1000); - let created_contract_address = assert_matches!( + let instantiated_contract_address = assert_matches!( ctx.instantiate( 100, &mut GasMeter::::with_limit(10000, 1), @@ -1526,7 +1526,7 @@ mod tests { ); // Check that the account has not been created. - assert!(ctx.overlay.get_code_hash(&created_contract_address).is_none()); + assert!(ctx.overlay.get_code_hash(&instantiated_contract_address).is_none()); assert!(ctx.events().is_empty()); } ); @@ -1538,12 +1538,12 @@ mod tests { let mut loader = MockLoader::empty(); let dummy_ch = loader.insert(|_| exec_success()); - let created_contract_address = Rc::new(RefCell::new(None::)); - let creator_ch = loader.insert({ + let instantiated_contract_address = Rc::new(RefCell::new(None::)); + let instantiator_ch = loader.insert({ let dummy_ch = dummy_ch.clone(); - let created_contract_address = Rc::clone(&created_contract_address); + let instantiated_contract_address = Rc::clone(&instantiated_contract_address); move |ctx| { - // Instantiate a contract and save it's address in `created_contract_address`. + // Instantiate a contract and save it's address in `instantiated_contract_address`. let (address, output) = ctx.ext.instantiate( &dummy_ch, 15u64, @@ -1551,7 +1551,7 @@ mod tests { vec![] ).unwrap(); - *created_contract_address.borrow_mut() = address.into(); + *instantiated_contract_address.borrow_mut() = address.into(); Ok(output) } }); @@ -1562,29 +1562,29 @@ mod tests { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); ctx.overlay.set_balance(&ALICE, 1000); - ctx.overlay.create_contract(&BOB, creator_ch).unwrap(); + ctx.overlay.instantiate_contract(&BOB, instantiator_ch).unwrap(); assert_matches!( ctx.call(BOB, 20, &mut GasMeter::::with_limit(1000, 1), vec![]), Ok(_) ); - let created_contract_address = created_contract_address.borrow().as_ref().unwrap().clone(); + let instantiated_contract_address = instantiated_contract_address.borrow().as_ref().unwrap().clone(); // Check that the newly created account has the expected code hash and // there are instantiation event. - assert_eq!(ctx.overlay.get_code_hash(&created_contract_address).unwrap(), dummy_ch); + assert_eq!(ctx.overlay.get_code_hash(&instantiated_contract_address).unwrap(), dummy_ch); assert_eq!(&ctx.events(), &[ DeferredAction::DepositEvent { event: RawEvent::Transfer(ALICE, BOB, 20), topics: Vec::new(), }, DeferredAction::DepositEvent { - event: RawEvent::Transfer(BOB, created_contract_address, 15), + event: RawEvent::Transfer(BOB, instantiated_contract_address, 15), topics: Vec::new(), }, DeferredAction::DepositEvent { - event: RawEvent::Instantiated(BOB, created_contract_address), + event: RawEvent::Instantiated(BOB, instantiated_contract_address), topics: Vec::new(), }, ]); @@ -1600,10 +1600,10 @@ mod tests { let dummy_ch = loader.insert( |_| Err(ExecError { reason: "It's a trap!", buffer: Vec::new() }) ); - let creator_ch = loader.insert({ + let instantiator_ch = loader.insert({ let dummy_ch = dummy_ch.clone(); move |ctx| { - // Instantiate a contract and save it's address in `created_contract_address`. + // Instantiate a contract and save it's address in `instantiated_contract_address`. assert_matches!( ctx.ext.instantiate( &dummy_ch, @@ -1624,14 +1624,14 @@ mod tests { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); ctx.overlay.set_balance(&ALICE, 1000); - ctx.overlay.create_contract(&BOB, creator_ch).unwrap(); + ctx.overlay.instantiate_contract(&BOB, instantiator_ch).unwrap(); assert_matches!( ctx.call(BOB, 20, &mut GasMeter::::with_limit(1000, 1), vec![]), Ok(_) ); - // The contract wasn't created so we don't expect to see an instantiation + // The contract wasn't instantiated so we don't expect to see an instantiation // event here. assert_eq!(&ctx.events(), &[ DeferredAction::DepositEvent { diff --git a/srml/contracts/src/lib.rs b/srml/contracts/src/lib.rs index 615f6c8b99..6ee93dfb0f 100644 --- a/srml/contracts/src/lib.rs +++ b/srml/contracts/src/lib.rs @@ -25,14 +25,14 @@ //! //! This module extends accounts based on the `Currency` trait to have smart-contract functionality. It can //! be used with other modules that implement accounts based on `Currency`. These "smart-contract accounts" -//! have the ability to create smart-contracts and make calls to other contract and non-contract accounts. +//! have the ability to instantiate smart-contracts and make calls to other contract and non-contract accounts. //! //! The smart-contract code is stored once in a `code_cache`, and later retrievable via its `code_hash`. //! This means that multiple smart-contracts can be instantiated from the same `code_cache`, without replicating //! the code each time. //! //! When a smart-contract is called, its associated code is retrieved via the code hash and gets executed. -//! This call can alter the storage entries of the smart-contract account, create new smart-contracts, +//! This call can alter the storage entries of the smart-contract account, instantiate new smart-contracts, //! or call other smart-contracts. //! //! Finally, when an account is reaped, its associated code and storage of the smart-contract account @@ -60,7 +60,8 @@ //! //! * `put_code` - Stores the given binary Wasm code into the chain's storage and returns its `code_hash`. //! * `instantiate` - Deploys a new contract from the given `code_hash`, optionally transferring some balance. -//! This creates a new smart contract account and calls its contract deploy handler to initialize the contract. +//! This instantiates a new smart contract account and calls its contract deploy handler to +//! initialize the contract. //! * `call` - Makes a call to an account, optionally transferring some balance. //! //! ### Signed Extensions @@ -74,8 +75,8 @@ //! //! ## Usage //! -//! The Contract module is a work in progress. The following examples show how this Contract module can be -//! used to create and call contracts. +//! The Contract module is a work in progress. The following examples show how this Contract module +//! can be used to instantiate and call contracts. //! //! * [`ink`](https://github.com/paritytech/ink) is //! an [`eDSL`](https://wiki.haskell.org/Embedded_domain_specific_language) that enables writing @@ -298,37 +299,37 @@ pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; parameter_types! { - /// A resonable default value for [`Trait::SignedClaimedHandicap`]. + /// A reasonable default value for [`Trait::SignedClaimedHandicap`]. pub const DefaultSignedClaimHandicap: u32 = 2; - /// A resonable default value for [`Trait::TombstoneDeposit`]. + /// A reasonable default value for [`Trait::TombstoneDeposit`]. pub const DefaultTombstoneDeposit: u32 = 16; - /// A resonable default value for [`Trait::StorageSizeOffset`]. + /// A reasonable default value for [`Trait::StorageSizeOffset`]. pub const DefaultStorageSizeOffset: u32 = 8; - /// A resonable default value for [`Trait::RentByteFee`]. + /// A reasonable default value for [`Trait::RentByteFee`]. pub const DefaultRentByteFee: u32 = 4; - /// A resonable default value for [`Trait::RentDepositOffset`]. + /// A reasonable default value for [`Trait::RentDepositOffset`]. pub const DefaultRentDepositOffset: u32 = 1000; - /// A resonable default value for [`Trait::SurchargeReward`]. + /// A reasonable default value for [`Trait::SurchargeReward`]. pub const DefaultSurchargeReward: u32 = 150; - /// A resonable default value for [`Trait::TransferFee`]. + /// A reasonable default value for [`Trait::TransferFee`]. pub const DefaultTransferFee: u32 = 0; - /// A resonable default value for [`Trait::CreationFee`]. - pub const DefaultCreationFee: u32 = 0; - /// A resonable default value for [`Trait::TransactionBaseFee`]. + /// A reasonable default value for [`Trait::InstantiationFee`]. + pub const DefaultInstantiationFee: u32 = 0; + /// A reasonable default value for [`Trait::TransactionBaseFee`]. pub const DefaultTransactionBaseFee: u32 = 0; - /// A resonable default value for [`Trait::TransactionByteFee`]. + /// A reasonable default value for [`Trait::TransactionByteFee`]. pub const DefaultTransactionByteFee: u32 = 0; - /// A resonable default value for [`Trait::ContractFee`]. + /// A reasonable default value for [`Trait::ContractFee`]. pub const DefaultContractFee: u32 = 21; - /// A resonable default value for [`Trait::CallBaseFee`]. + /// A reasonable default value for [`Trait::CallBaseFee`]. pub const DefaultCallBaseFee: u32 = 1000; - /// A resonable default value for [`Trait::CreateBaseFee`]. - pub const DefaultCreateBaseFee: u32 = 1000; - /// A resonable default value for [`Trait::MaxDepth`]. + /// A reasonable default value for [`Trait::InstantiateBaseFee`]. + pub const DefaultInstantiateBaseFee: u32 = 1000; + /// A reasonable default value for [`Trait::MaxDepth`]. pub const DefaultMaxDepth: u32 = 1024; - /// A resonable default value for [`Trait::MaxValueSize`]. + /// A reasonable default value for [`Trait::MaxValueSize`]. pub const DefaultMaxValueSize: u32 = 16_384; - /// A resonable default value for [`Trait::BlockGasLimit`]. + /// A reasonable default value for [`Trait::BlockGasLimit`]. pub const DefaultBlockGasLimit: u32 = 10_000_000; } @@ -341,13 +342,13 @@ pub trait Trait: timestamp::Trait { /// The overarching event type. type Event: From> + Into<::Event>; - /// A function type to get the contract address given the creator. + /// A function type to get the contract address given the instantiator. type DetermineContractAddress: ContractAddressFor, Self::AccountId>; /// A function type that computes the fee for dispatching the given `Call`. /// - /// It is recommended (though not required) for this function to return a fee that would be taken - /// by the Executive module for regular dispatch. + /// It is recommended (though not required) for this function to return a fee that would be + /// taken by the Executive module for regular dispatch. type ComputeDispatchFee: ComputeDispatchFee<::Call, BalanceOf>; /// trie id generator @@ -365,7 +366,7 @@ pub trait Trait: timestamp::Trait { /// The minimum amount required to generate a tombstone. type TombstoneDeposit: Get>; - /// Size of a contract at the time of creation. This is a simple way to ensure + /// Size of a contract at the time of instantiation. This is a simple way to ensure /// that empty contracts eventually gets deleted. type StorageSizeOffset: Get; @@ -397,16 +398,16 @@ pub trait Trait: timestamp::Trait { /// The fee to be paid for making a transaction; the per-byte portion. type TransactionByteFee: Get>; - /// The fee required to create a contract instance. + /// The fee required to instantiate a contract instance. type ContractFee: Get>; /// The base fee charged for calling into a contract. type CallBaseFee: Get; - /// The base fee charged for creating a contract. - type CreateBaseFee: Get; + /// The base fee charged for instantiating a contract. + type InstantiateBaseFee: Get; - /// The maximum nesting level of a call/create stack. + /// The maximum nesting level of a call/instantiate stack. type MaxDepth: Get; /// The maximum size of a storage value in bytes. @@ -464,8 +465,8 @@ decl_module! { /// The minimum amount required to generate a tombstone. const TombstoneDeposit: BalanceOf = T::TombstoneDeposit::get(); - /// Size of a contract at the time of creation. This is a simple way to ensure - /// that empty contracts eventually gets deleted. + /// Size of a contract at the time of instantiaion. This is a simple way to ensure that + /// empty contracts eventually gets deleted. const StorageSizeOffset: u32 = T::StorageSizeOffset::get(); /// Price of a byte of storage per one block interval. Should be greater than 0. @@ -496,7 +497,7 @@ decl_module! { /// The fee to be paid for making a transaction; the per-byte portion. const TransactionByteFee: BalanceOf = T::TransactionByteFee::get(); - /// The fee required to create a contract instance. A reasonable default value + /// The fee required to instantiate a contract instance. A reasonable default value /// is 21. const ContractFee: BalanceOf = T::ContractFee::get(); @@ -504,11 +505,11 @@ decl_module! { /// value is 135. const CallBaseFee: Gas = T::CallBaseFee::get(); - /// The base fee charged for creating a contract. A reasonable default value + /// The base fee charged for instantiating a contract. A reasonable default value /// is 175. - const CreateBaseFee: Gas = T::CreateBaseFee::get(); + const InstantiateBaseFee: Gas = T::InstantiateBaseFee::get(); - /// The maximum nesting level of a call/create stack. A reasonable default + /// The maximum nesting level of a call/instantiate stack. A reasonable default /// value is 100. const MaxDepth: u32 = T::MaxDepth::get(); diff --git a/srml/contracts/src/tests.rs b/srml/contracts/src/tests.rs index fc58a51d95..2dfdce33eb 100644 --- a/srml/contracts/src/tests.rs +++ b/srml/contracts/src/tests.rs @@ -69,7 +69,7 @@ impl_outer_dispatch! { thread_local! { static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); static TRANSFER_FEE: RefCell = RefCell::new(0); - static CREATION_FEE: RefCell = RefCell::new(0); + static INSTANTIATION_FEE: RefCell = RefCell::new(0); static BLOCK_GAS_LIMIT: RefCell = RefCell::new(0); } @@ -85,7 +85,7 @@ impl Get for TransferFee { pub struct CreationFee; impl Get for CreationFee { - fn get() -> u64 { CREATION_FEE.with(|v| *v.borrow()) } + fn get() -> u64 { INSTANTIATION_FEE.with(|v| *v.borrow()) } } pub struct BlockGasLimit; @@ -155,7 +155,7 @@ parameter_types! { pub const TransactionByteFee: u64 = 6; pub const ContractFee: u64 = 21; pub const CallBaseFee: u64 = 135; - pub const CreateBaseFee: u64 = 175; + pub const InstantiateBaseFee: u64 = 175; pub const MaxDepth: u32 = 100; pub const MaxValueSize: u32 = 16_384; } @@ -179,7 +179,7 @@ impl Trait for Test { type TransactionByteFee = TransactionByteFee; type ContractFee = ContractFee; type CallBaseFee = CallBaseFee; - type CreateBaseFee = CreateBaseFee; + type InstantiateBaseFee = InstantiateBaseFee; type MaxDepth = MaxDepth; type MaxValueSize = MaxValueSize; type BlockGasLimit = BlockGasLimit; @@ -233,7 +233,7 @@ pub struct ExtBuilder { gas_price: u64, block_gas_limit: u64, transfer_fee: u64, - creation_fee: u64, + instantiation_fee: u64, } impl Default for ExtBuilder { fn default() -> Self { @@ -242,7 +242,7 @@ impl Default for ExtBuilder { gas_price: 2, block_gas_limit: 100_000_000, transfer_fee: 0, - creation_fee: 0, + instantiation_fee: 0, } } } @@ -263,14 +263,14 @@ impl ExtBuilder { self.transfer_fee = transfer_fee; self } - pub fn creation_fee(mut self, creation_fee: u64) -> Self { - self.creation_fee = creation_fee; + pub fn instantiation_fee(mut self, instantiation_fee: u64) -> Self { + self.instantiation_fee = instantiation_fee; self } pub fn set_associated_consts(&self) { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); TRANSFER_FEE.with(|v| *v.borrow_mut() = self.transfer_fee); - CREATION_FEE.with(|v| *v.borrow_mut() = self.creation_fee); + INSTANTIATION_FEE.with(|v| *v.borrow_mut() = self.instantiation_fee); BLOCK_GAS_LIMIT.with(|v| *v.borrow_mut() = self.block_gas_limit); } pub fn build(self) -> runtime_io::TestExternalities { @@ -651,7 +651,7 @@ fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { vec![], )); - // Call the newly created contract. The contract is expected to dispatch a call + // Call the newly instantiated contract. The contract is expected to dispatch a call // and then trap. assert_err!( Contract::call( @@ -1225,7 +1225,7 @@ const CODE_CHECK_DEFAULT_RENT_ALLOWANCE: &str = r#" "#; #[test] -fn default_rent_allowance_on_create() { +fn default_rent_allowance_on_instantiate() { let (wasm, code_hash) = compile_module::(CODE_CHECK_DEFAULT_RENT_ALLOWANCE).unwrap(); with_externalities( diff --git a/srml/contracts/src/wasm/mod.rs b/srml/contracts/src/wasm/mod.rs index 68ea126338..4fa9412bc1 100644 --- a/srml/contracts/src/wasm/mod.rs +++ b/srml/contracts/src/wasm/mod.rs @@ -173,7 +173,7 @@ mod tests { } #[derive(Debug, PartialEq, Eq)] - struct CreateEntry { + struct InstantiateEntry { code_hash: H256, endowment: u64, data: Vec, @@ -192,7 +192,7 @@ mod tests { pub struct MockExt { storage: HashMap>, rent_allowance: u64, - creates: Vec, + instantiates: Vec, transfers: Vec, dispatches: Vec, restores: Vec, @@ -220,7 +220,7 @@ mod tests { gas_meter: &mut GasMeter, data: Vec, ) -> Result<(u64, ExecReturnValue), ExecError> { - self.creates.push(CreateEntry { + self.instantiates.push(InstantiateEntry { code_hash: code_hash.clone(), endowment, data: data.to_vec(), @@ -476,7 +476,7 @@ mod tests { ); } - const CODE_CREATE: &str = r#" + const CODE_INSTANTIATE: &str = r#" (module ;; ext_instantiate( ;; code_ptr: u32, @@ -507,7 +507,7 @@ mod tests { ;; Amount of value to transfer. ;; Represented by u64 (8 bytes long) in little endian. (data (i32.const 4) "\03\00\00\00\00\00\00\00") - ;; Input data to pass to the contract being created. + ;; Input data to pass to the contract being instantiated. (data (i32.const 12) "\01\02\03\04") ;; Hash of code. (data (i32.const 16) @@ -518,18 +518,18 @@ mod tests { "#; #[test] - fn contract_create() { + fn contract_instantiate() { let mut mock_ext = MockExt::default(); let _ = execute( - CODE_CREATE, + CODE_INSTANTIATE, vec![], &mut mock_ext, &mut GasMeter::with_limit(50_000, 1), ).unwrap(); assert_eq!( - &mock_ext.creates, - &[CreateEntry { + &mock_ext.instantiates, + &[InstantiateEntry { code_hash: [0x11; 32].into(), endowment: 3, data: vec![1, 2, 3, 4], diff --git a/srml/contracts/src/wasm/runtime.rs b/srml/contracts/src/wasm/runtime.rs index beab043ce2..28117eaa7c 100644 --- a/srml/contracts/src/wasm/runtime.rs +++ b/srml/contracts/src/wasm/runtime.rs @@ -432,11 +432,12 @@ define_env!(Env, , // by the code hash. // // If the constructor runs to completion, then this returns the status code that the newly - // created contract returns on exit in the bottom 8 bits of the return value. The top 24 bits - // are 0s. A status code of 0 indicates success, and any other code indicates a failure. On - // failure, any state changes made by the called contract are reverted and the contract is not - // instantiated. On a success status, the scratch buffer is filled with the encoded address of - // the newly created contract. In the case of a failure status, the scratch buffer is cleared. + // instantiated contract returns on exit in the bottom 8 bits of the return value. The top 24 + // bits are 0s. A status code of 0 indicates success, and any other code indicates a failure. + // On failure, any state changes made by the called contract are reverted and the contract is + // not instantiated. On a success status, the scratch buffer is filled with the encoded address + // of the newly instantiated contract. In the case of a failure status, the scratch buffer is + // cleared. // // If the contract traps during execution or otherwise fails to complete successfully, then // this function clears the scratch buffer and returns 0x0100. As with a failure status, any @@ -445,8 +446,9 @@ define_env!(Env, , // This function creates an account and executes initializer code. After the execution, // the returned buffer is saved as the code of the created account. // - // Returns 0 on the successful contract creation and puts the address of the created contract - // into the scratch buffer. Otherwise, returns non-zero value and clears the scratch buffer. + // Returns 0 on the successful contract instantiation and puts the address of the instantiated + // contract into the scratch buffer. Otherwise, returns non-zero value and clears the scratch + // buffer. // // - code_hash_ptr: a pointer to the buffer that contains the initializer code. // - code_hash_len: length of the initializer code buffer. @@ -535,9 +537,9 @@ define_env!(Env, , // Stores the address of the caller into the scratch buffer. // - // If this is a top-level call (i.e. initiated by an extrinsic) the origin address of the extrinsic - // will be returned. Otherwise, if this call is initiated by another contract then the address - // of the contract will be returned. + // If this is a top-level call (i.e. initiated by an extrinsic) the origin address of the + // extrinsic will be returned. Otherwise, if this call is initiated by another contract then the + // address of the contract will be returned. ext_caller(ctx) => { ctx.scratch_buf.clear(); ctx.ext.caller().encode_to(&mut ctx.scratch_buf); @@ -717,8 +719,8 @@ define_env!(Env, , Ok(ctx.scratch_buf.len() as u32) }, - // Copy data from the scratch buffer starting from `offset` with length `len` into the contract memory. - // The region at which the data should be put is specified by `dest_ptr`. + // Copy data from the scratch buffer starting from `offset` with length `len` into the contract + // memory. The region at which the data should be put is specified by `dest_ptr`. // // In order to get size of the scratch buffer use `ext_scratch_size`. At the start of contract // execution, the scratch buffer is filled with the input data. Whenever a contract calls -- GitLab From 9abf27c318e42dee5a8fad23c3670441fc6afb64 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Mon, 23 Sep 2019 14:11:24 +0200 Subject: [PATCH 122/275] Refactor reward curve (#3668) * move test in tests dir * comment * refactor --- Cargo.toml | 1 - srml/staking/reward-curve/Cargo.toml | 1 - srml/staking/reward-curve/src/lib.rs | 2 ++ srml/staking/reward-curve/test/Cargo.toml | 9 --------- .../reward-curve/{test/src/lib.rs => tests/test.rs} | 0 5 files changed, 2 insertions(+), 11 deletions(-) delete mode 100644 srml/staking/reward-curve/test/Cargo.toml rename srml/staking/reward-curve/{test/src/lib.rs => tests/test.rs} (100%) diff --git a/Cargo.toml b/Cargo.toml index 684363c227..20a104b6a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -96,7 +96,6 @@ members = [ "srml/session", "srml/staking", "srml/staking/reward-curve", - "srml/staking/reward-curve/test", "srml/sudo", "srml/system", "srml/timestamp", diff --git a/srml/staking/reward-curve/Cargo.toml b/srml/staking/reward-curve/Cargo.toml index 4e254e9512..19deeae72e 100644 --- a/srml/staking/reward-curve/Cargo.toml +++ b/srml/staking/reward-curve/Cargo.toml @@ -8,7 +8,6 @@ edition = "2018" proc-macro = true [dependencies] -# sr-api-macros = { path = "../../../core/sr-api-macros" } syn = { version = "1.0", features = [ "full", "visit" ] } quote = "1.0" proc-macro2 = "1.0" diff --git a/srml/staking/reward-curve/src/lib.rs b/srml/staking/reward-curve/src/lib.rs index 9ed319be7f..637ba10b9e 100644 --- a/srml/staking/reward-curve/src/lib.rs +++ b/srml/staking/reward-curve/src/lib.rs @@ -279,6 +279,8 @@ fn compute_points(input: &INposInput) -> Vec<(u32, u32)> { let mut delta_y = max_length; let mut y = input.max_inflation; + // The algorithm divide the curve in segment with vertical len and horizontal len less + // than `max_length`. This is not very accurate in case of very consequent steep. while delta_y != 0 { let next_y = y - delta_y; diff --git a/srml/staking/reward-curve/test/Cargo.toml b/srml/staking/reward-curve/test/Cargo.toml deleted file mode 100644 index 5c9ffb3cf7..0000000000 --- a/srml/staking/reward-curve/test/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "srml-staking-reward-curve-test" -version = "2.0.0" -authors = ["Parity Technologies "] -edition = "2018" - -[dependencies] -srml-staking-reward-curve = { path = ".." } -sr-primitives = { path = "../../../../core/sr-primitives" } diff --git a/srml/staking/reward-curve/test/src/lib.rs b/srml/staking/reward-curve/tests/test.rs similarity index 100% rename from srml/staking/reward-curve/test/src/lib.rs rename to srml/staking/reward-curve/tests/test.rs -- GitLab From 426c26b8bddfcdbaf8d29f45b128e0864b57de1c Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Mon, 23 Sep 2019 16:03:05 +0200 Subject: [PATCH 123/275] Fixing BABE epochs to change between blocks (#3583) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * always fetch epoch from runtime * node integration tests don't test light nodes * give stand-in full node a FULL role * rejig babe APIs * introduce next-epoch-descriptor type * overhaul srml-BABE epoch logic * ensure VRF outputs end up in the right epoch-randomness * rewrite `do_initialize` to remove unnecessary loop * begin accounting for next epoch in epoch function * slots passes header to epoch_data * pass slot_number to SlotWorker::epoch_data * begin extracting epoch-change logic into its own module * aux methods for block weight * aux methods for genesis configuration * comment-out most, refactor header-check pipeline * mostly flesh out verifier again * reinstantiate babe BlockImport implementation * reinstate import-queue instantiation * reintroduce slot-worker implementation * reinstate pretty much all the rest * move fork-choice logic to BlockImport * fix some, but not all errors * patch test-runtime * make is_descendent of slightly more generic * get skeleton compiling when passing is_descendent_of * make descendent-of-builder more succinct * restore ordering of authority_index / slot_number * start fiddling with tests * fix warnings * improve initialization architecture and handle genesis * tests use correct block-import * fix BABE tests * fix some compiler errors * fix node-cli compilation * all crates compile * bump runtime versions and fix some warnings * tweak fork-tree search implementation * do backtracking search in fork-tree * node-cli integration tests now work * fix broken assumption in test_connectivity * babe tests fail for the right reasons. * test genesis epoch logic for epoch_changes * test that epochs can change between blocks * First BABE SRML test * Testing infrastructure for BABE Also includes a trivial additional test. * Apply suggestions from code review Co-Authored-By: Bastian Köcher * A little more test progress * More work on BABE testing * Try to get the tests working * Implement `UintAuthorityId`-based test mocks * Fix compilation errors * Adjust to upstream changes * Block numbers are ignored in BABE epoch calculation * authority_index() should ignore invalid authorities * Fix compile error * Add tests that session transitions happen * Check if BABE produces logs It currently does not. * Fix test suite This was really nasty, due to a type confusion that showed up as an off-by-1 buffer error. * Add additional tests Most of these were derived from the current output, so they are only useful to guard against regressions. * Make the tests more readable Also bump impl_version. * Fix excessive line width * Remove unused imports * Update srml/babe/src/lib.rs Co-Authored-By: André Silva * try to fix imports * Fix build errors in test suite * tests did not pass * Try to get at least one digest to be output Currently, the code emits either no digests (if I don’t call `Session::rotate_session()` or two digests (if I do), which is wrong. * More tests They still don’t work, but this should help debugging. * fix silly error * Don’t even try to compile a broken test * remove broken check_epoch test and add one for genesis epoch * Check that the length of the pre-digests is correct * Bump `impl_version` * use epoch_for_descendent_of even for genesis * account for competing block 1s * finish srml-babe docs Co-Authored-By: André Silva * address grumbles --- Cargo.lock | 2 + core/client/src/client.rs | 26 +- core/consensus/aura/src/lib.rs | 6 +- core/consensus/babe/primitives/src/digest.rs | 63 +- core/consensus/babe/primitives/src/lib.rs | 77 +- core/consensus/babe/src/aux_schema.rs | 36 +- core/consensus/babe/src/epoch_changes.rs | 637 ++++++++++++ core/consensus/babe/src/lib.rs | 968 +++++++++---------- core/consensus/babe/src/tests.rs | 381 ++++++-- core/consensus/common/src/block_import.rs | 29 +- core/consensus/common/src/import_queue.rs | 1 + core/consensus/slots/src/lib.rs | 10 +- core/finality-grandpa/src/environment.rs | 2 +- core/finality-grandpa/src/import.rs | 2 +- core/finality-grandpa/src/tests.rs | 7 +- core/network/src/test/mod.rs | 50 +- core/phragmen/benches/phragmen.rs | 2 +- core/service/src/chain_ops.rs | 5 +- core/service/test/src/lib.rs | 49 +- core/sr-io/src/lib.rs | 1 - core/sr-io/with_std.rs | 1 + core/sr-io/without_std.rs | 4 +- core/sr-primitives/src/testing.rs | 2 +- core/test-runtime/src/lib.rs | 42 +- core/utils/fork-tree/src/lib.rs | 75 +- node-template/runtime/src/lib.rs | 16 +- node-template/src/service.rs | 75 +- node/cli/src/chain_spec.rs | 10 +- node/cli/src/service.rs | 141 +-- node/runtime/src/lib.rs | 24 +- srml/babe/Cargo.toml | 2 + srml/babe/src/lib.rs | 178 ++-- srml/babe/src/mock.rs | 112 +++ srml/babe/src/tests.rs | 127 +++ 34 files changed, 2171 insertions(+), 992 deletions(-) create mode 100644 core/consensus/babe/src/epoch_changes.rs create mode 100644 srml/babe/src/mock.rs create mode 100644 srml/babe/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index c852d480ed..793f117991 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3969,6 +3969,7 @@ dependencies = [ "sr-primitives 2.0.0", "sr-staking-primitives 2.0.0", "sr-std 2.0.0", + "sr-version 2.0.0", "srml-session 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", @@ -3976,6 +3977,7 @@ dependencies = [ "substrate-consensus-babe-primitives 2.0.0", "substrate-inherents 2.0.0", "substrate-primitives 2.0.0", + "substrate-test-runtime 2.0.0", ] [[package]] diff --git a/core/client/src/client.rs b/core/client/src/client.rs index acba5fa824..5203c72303 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -1482,6 +1482,9 @@ impl CallRuntimeAt for Client where } } +/// NOTE: only use this implementation when you are sure there are NO consensus-level BlockImport +/// objects. Otherwise, importing blocks directly into the client would be bypassing +/// important verification work. impl<'a, B, E, Block, RA> consensus::BlockImport for &'a Client where B: backend::Backend, E: CallExecutor + Clone + Send + Sync, @@ -1491,6 +1494,13 @@ impl<'a, B, E, Block, RA> consensus::BlockImport for &'a Client, @@ -1899,8 +1909,9 @@ where /// Utility methods for the client. pub mod utils { use super::*; - use crate::{backend::Backend, blockchain, error}; + use crate::{blockchain, error}; use primitives::H256; + use std::borrow::Borrow; /// Returns a function for checking block ancestry, the returned function will /// return `true` if the given hash (second parameter) is a descendent of the @@ -1908,16 +1919,17 @@ pub mod utils { /// represent the current block `hash` and its `parent hash`, if given the /// function that's returned will assume that `hash` isn't part of the local DB /// yet, and all searches in the DB will instead reference the parent. - pub fn is_descendent_of<'a, B, E, Block: BlockT, RA>( - client: &'a Client, - current: Option<(&'a H256, &'a H256)>, + pub fn is_descendent_of<'a, Block: BlockT, T, H: Borrow + 'a>( + client: &'a T, + current: Option<(H, H)>, ) -> impl Fn(&H256, &H256) -> Result + 'a - where B: Backend, - E: CallExecutor + Send + Sync, + where T: ChainHeaderBackend, { move |base, hash| { if base == hash { return Ok(false); } + let current = current.as_ref().map(|(c, p)| (c.borrow(), p.borrow())); + let mut hash = hash; if let Some((current_hash, current_parent_hash)) = current { if base == current_hash { return Ok(false); } @@ -1931,7 +1943,7 @@ pub mod utils { } let tree_route = blockchain::tree_route( - |id| client.header(&id)?.ok_or_else(|| Error::UnknownBlock(format!("{:?}", id))), + |id| client.header(id)?.ok_or_else(|| Error::UnknownBlock(format!("{:?}", id))), BlockId::Hash(*hash), BlockId::Hash(*base), )?; diff --git a/core/consensus/aura/src/lib.rs b/core/consensus/aura/src/lib.rs index 3c60128dd3..a61eb6da72 100644 --- a/core/consensus/aura/src/lib.rs +++ b/core/consensus/aura/src/lib.rs @@ -218,8 +218,8 @@ impl slots::SimpleSlotWorker for AuraWorker Result { - authorities(self.client.as_ref(), &BlockId::Hash(*block)) + fn epoch_data(&self, header: &B::Header, _slot_number: u64) -> Result { + authorities(self.client.as_ref(), &BlockId::Hash(header.hash())) } fn authorities_len(&self, epoch_data: &Self::EpochData) -> usize { @@ -741,7 +741,7 @@ mod tests { } } - fn make_verifier(&self, client: PeersClient, _cfg: &ProtocolConfig) + fn make_verifier(&self, client: PeersClient, _cfg: &ProtocolConfig, _peer_data: &()) -> Self::Verifier { match client { diff --git a/core/consensus/babe/primitives/src/digest.rs b/core/consensus/babe/primitives/src/digest.rs index 427c4fec57..3f275ecdb6 100644 --- a/core/consensus/babe/primitives/src/digest.rs +++ b/core/consensus/babe/primitives/src/digest.rs @@ -17,12 +17,10 @@ //! Private implementation details of BABE digests. #[cfg(feature = "std")] -use super::AuthoritySignature; -#[cfg(feature = "std")] -use super::{BABE_ENGINE_ID, Epoch}; +use super::{BABE_ENGINE_ID, AuthoritySignature}; #[cfg(not(feature = "std"))] use super::{VRF_OUTPUT_LENGTH, VRF_PROOF_LENGTH}; -use super::{AuthorityIndex, BabeBlockWeight, SlotNumber}; +use super::{AuthorityId, AuthorityIndex, SlotNumber, BabeAuthorityWeight}; #[cfg(feature = "std")] use sr_primitives::{DigestItem, generic::OpaqueDigestItemId}; #[cfg(feature = "std")] @@ -35,6 +33,8 @@ use schnorrkel::{ SignatureError, errors::MultiSignatureStage, vrf::{VRFProof, VRFOutput, VRF_OUTPUT_LENGTH, VRF_PROOF_LENGTH} }; +use rstd::vec::Vec; + /// A BABE pre-runtime digest. This contains all data required to validate a /// block and for the BABE runtime module. Slots can be assigned to a primary @@ -52,8 +52,6 @@ pub enum BabePreDigest { authority_index: super::AuthorityIndex, /// Slot number slot_number: SlotNumber, - /// Chain weight (measured in number of Primary blocks) - weight: BabeBlockWeight, }, /// A secondary deterministic slot assignment. Secondary { @@ -61,8 +59,6 @@ pub enum BabePreDigest { authority_index: super::AuthorityIndex, /// Slot number slot_number: SlotNumber, - /// Chain weight (measured in number of Primary blocks) - weight: BabeBlockWeight, }, } @@ -84,11 +80,12 @@ impl BabePreDigest { } } - /// Returns the weight of the pre digest. - pub fn weight(&self) -> BabeBlockWeight { + /// Returns the weight _added_ by this digest, not the cumulative weight + /// of the chain. + pub fn added_weight(&self) -> crate::BabeBlockWeight { match self { - BabePreDigest::Primary { weight, .. } => *weight, - BabePreDigest::Secondary { weight, .. } => *weight, + BabePreDigest::Primary { .. } => 1, + BabePreDigest::Secondary { .. } => 0, } } } @@ -100,26 +97,29 @@ pub const BABE_VRF_PREFIX: &'static [u8] = b"substrate-babe-vrf"; #[derive(Copy, Clone, Encode, Decode)] pub enum RawBabePreDigest { /// A primary VRF-based slot assignment. + #[codec(index = "1")] Primary { /// Authority index authority_index: AuthorityIndex, /// Slot number slot_number: SlotNumber, - /// Chain weight (measured in number of Primary blocks) - weight: BabeBlockWeight, /// VRF output vrf_output: [u8; VRF_OUTPUT_LENGTH], /// VRF proof vrf_proof: [u8; VRF_PROOF_LENGTH], }, /// A secondary deterministic slot assignment. + #[codec(index = "2")] Secondary { /// Authority index + /// + /// This is not strictly-speaking necessary, since the secondary slots + /// are assigned based on slot number and epoch randomness. But including + /// it makes things easier for higher-level users of the chain data to + /// be aware of the author of a secondary-slot block. authority_index: AuthorityIndex, /// Slot number slot_number: SlotNumber, - /// Chain weight (measured in number of Primary blocks) - weight: BabeBlockWeight, }, } @@ -142,25 +142,21 @@ impl Encode for BabePreDigest { vrf_proof, authority_index, slot_number, - weight, } => { RawBabePreDigest::Primary { vrf_output: *vrf_output.as_bytes(), vrf_proof: vrf_proof.to_bytes(), authority_index: *authority_index, slot_number: *slot_number, - weight: *weight, } }, BabePreDigest::Secondary { authority_index, slot_number, - weight, } => { RawBabePreDigest::Secondary { authority_index: *authority_index, slot_number: *slot_number, - weight: *weight, } }, }; @@ -176,7 +172,7 @@ impl codec::EncodeLike for BabePreDigest {} impl Decode for BabePreDigest { fn decode(i: &mut R) -> Result { let pre_digest = match Decode::decode(i)? { - RawBabePreDigest::Primary { vrf_output, vrf_proof, authority_index, slot_number, weight } => { + RawBabePreDigest::Primary { vrf_output, vrf_proof, authority_index, slot_number } => { // Verify (at compile time) that the sizes in babe_primitives are correct let _: [u8; super::VRF_OUTPUT_LENGTH] = vrf_output; let _: [u8; super::VRF_PROOF_LENGTH] = vrf_proof; @@ -186,11 +182,10 @@ impl Decode for BabePreDigest { vrf_output: VRFOutput::from_bytes(&vrf_output).map_err(convert_error)?, authority_index, slot_number, - weight, } }, - RawBabePreDigest::Secondary { authority_index, slot_number, weight } => { - BabePreDigest::Secondary { authority_index, slot_number, weight } + RawBabePreDigest::Secondary { authority_index, slot_number } => { + BabePreDigest::Secondary { authority_index, slot_number } }, }; @@ -198,6 +193,18 @@ impl Decode for BabePreDigest { } } +/// Information about the next epoch. This is broadcast in the first block +/// of the epoch. +#[derive(Decode, Encode, Default, PartialEq, Eq, Clone)] +#[cfg_attr(any(feature = "std", test), derive(Debug))] +pub struct NextEpochDescriptor { + /// The authorities. + pub authorities: Vec<(AuthorityId, BabeAuthorityWeight)>, + + /// The value of randomness to use for the slot-assignment. + pub randomness: [u8; VRF_OUTPUT_LENGTH], +} + /// A digest item which is usable with BABE consensus. #[cfg(feature = "std")] pub trait CompatibleDigestItem: Sized { @@ -214,7 +221,7 @@ pub trait CompatibleDigestItem: Sized { fn as_babe_seal(&self) -> Option; /// If this item is a BABE epoch, return it. - fn as_babe_epoch(&self) -> Option; + fn as_next_epoch_descriptor(&self) -> Option; } #[cfg(feature = "std")] @@ -237,8 +244,12 @@ impl CompatibleDigestItem for DigestItem where self.try_to(OpaqueDigestItemId::Seal(&BABE_ENGINE_ID)) } - fn as_babe_epoch(&self) -> Option { + fn as_next_epoch_descriptor(&self) -> Option { self.try_to(OpaqueDigestItemId::Consensus(&BABE_ENGINE_ID)) + .and_then(|x: super::ConsensusLog| match x { + super::ConsensusLog::NextEpochData(n) => Some(n), + _ => None, + }) } } diff --git a/core/consensus/babe/primitives/src/lib.rs b/core/consensus/babe/primitives/src/lib.rs index 09ac2f2012..1293b7c8ba 100644 --- a/core/consensus/babe/primitives/src/lib.rs +++ b/core/consensus/babe/primitives/src/lib.rs @@ -28,7 +28,7 @@ use substrate_client::decl_runtime_apis; #[cfg(feature = "std")] pub use digest::{BabePreDigest, CompatibleDigestItem}; -pub use digest::{BABE_VRF_PREFIX, RawBabePreDigest}; +pub use digest::{BABE_VRF_PREFIX, RawBabePreDigest, NextEpochDescriptor}; mod app { use app_crypto::{app_crypto, key_types::BABE, sr25519}; @@ -59,6 +59,11 @@ pub const VRF_PROOF_LENGTH: usize = 64; /// The length of the public key pub const PUBLIC_KEY_LENGTH: usize = 32; +/// How many blocks to wait before running the median algorithm for relative time +/// This will not vary from chain to chain as it is not dependent on slot duration +/// or epoch length. +pub const MEDIAN_ALGORITHM_CARDINALITY: usize = 1200; // arbitrary suggestion by w3f-research. + /// The index of an authority. pub type AuthorityIndex = u32; @@ -80,33 +85,50 @@ pub struct Epoch { /// The epoch index pub epoch_index: u64, /// The starting slot of the epoch, - pub start_slot: u64, + pub start_slot: SlotNumber, /// The duration of this epoch pub duration: SlotNumber, /// The authorities and their weights pub authorities: Vec<(AuthorityId, BabeAuthorityWeight)>, /// Randomness for this epoch pub randomness: [u8; VRF_OUTPUT_LENGTH], - /// Whether secondary slot assignments should be used during the epoch. - pub secondary_slots: bool, +} + +impl Epoch { + /// "increment" the epoch, with given descriptor for the next. + pub fn increment(&self, descriptor: NextEpochDescriptor) -> Epoch { + Epoch { + epoch_index: self.epoch_index + 1, + start_slot: self.start_slot + self.duration, + duration: self.duration, + authorities: descriptor.authorities, + randomness: descriptor.randomness, + } + } + + /// Produce the "end slot" of the epoch. This is NOT inclusive to the epoch, + // i.e. the slots covered by the epoch are `self.start_slot .. self.end_slot()`. + pub fn end_slot(&self) -> SlotNumber { + self.start_slot + self.duration + } } /// An consensus log item for BABE. #[derive(Decode, Encode, Clone, PartialEq, Eq)] pub enum ConsensusLog { - /// The epoch has changed. This provides information about the - /// epoch _after_ next: what slot number it will start at, who are the authorities (and their weights) - /// and the next epoch randomness. The information for the _next_ epoch should already - /// be available. + /// The epoch has changed. This provides information about the _next_ + /// epoch - information about the _current_ epoch (i.e. the one we've just + /// entered) should already be available earlier in the chain. #[codec(index = "1")] - NextEpochData(Epoch), + NextEpochData(NextEpochDescriptor), /// Disable the authority with given index. #[codec(index = "2")] OnDisabled(AuthorityIndex), } /// Configuration data used by the BABE consensus engine. -#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug, Encode, Decode)] +#[derive(Clone, PartialEq, Eq, Encode, Decode)] +#[cfg_attr(any(feature = "std", test), derive(Debug))] pub struct BabeConfiguration { /// The slot duration in milliseconds for BABE. Currently, only /// the value provided by this type at genesis will be used. @@ -114,35 +136,35 @@ pub struct BabeConfiguration { /// Dynamic slot duration may be supported in the future. pub slot_duration: u64, + /// The duration of epochs in slots. + pub epoch_length: SlotNumber, + /// A constant value that is used in the threshold calculation formula. - /// Expressed as a fraction where the first member of the tuple is the - /// numerator and the second is the denominator. The fraction should + /// Expressed as a rational where the first member of the tuple is the + /// numerator and the second is the denominator. The rational should /// represent a value between 0 and 1. /// In the threshold formula calculation, `1 - c` represents the probability /// of a slot being empty. pub c: (u64, u64), - /// The minimum number of blocks that must be received before running the - /// median algorithm to compute the offset between the on-chain time and the - /// local time. Currently, only the value provided by this type at genesis - /// will be used, but this is subject to change. - /// - /// Blocks less than `self.median_required_blocks` must be generated by an - /// *initial validator* ― that is, a node that was a validator at genesis. - pub median_required_blocks: u64, + /// The authorities for the genesis epoch. + pub genesis_authorities: Vec<(AuthorityId, BabeAuthorityWeight)>, + + /// The randomness for the genesis epoch. + pub randomness: [u8; VRF_OUTPUT_LENGTH], + + /// Whether this chain should run with secondary slots, which are assigned + /// in round-robin manner. + pub secondary_slots: bool, } #[cfg(feature = "std")] impl slots::SlotData for BabeConfiguration { - /// Return the slot duration in milliseconds for BABE. Currently, only - /// the value provided by this type at genesis will be used. - /// - /// Dynamic slot duration may be supported in the future. fn slot_duration(&self) -> u64 { self.slot_duration } - const SLOT_KEY: &'static [u8] = b"babe_bootstrap_data"; + const SLOT_KEY: &'static [u8] = b"babe_configuration"; } decl_runtime_apis! { @@ -152,9 +174,6 @@ decl_runtime_apis! { /// only the value provided by this type at genesis will be used. /// /// Dynamic configuration may be supported in the future. - fn startup_data() -> BabeConfiguration; - - /// Get the current epoch data for Babe. - fn epoch() -> Epoch; + fn configuration() -> BabeConfiguration; } } diff --git a/core/consensus/babe/src/aux_schema.rs b/core/consensus/babe/src/aux_schema.rs index ac90b4ce52..67f61050fa 100644 --- a/core/consensus/babe/src/aux_schema.rs +++ b/core/consensus/babe/src/aux_schema.rs @@ -22,11 +22,16 @@ use codec::{Decode, Encode}; use client::backend::AuxStore; use client::error::{Result as ClientResult, Error as ClientError}; use sr_primitives::traits::Block as BlockT; +use babe_primitives::BabeBlockWeight; -use super::{EpochChanges, SharedEpochChanges}; +use super::{epoch_changes::EpochChangesFor, SharedEpochChanges}; const BABE_EPOCH_CHANGES: &[u8] = b"babe_epoch_changes"; +fn block_weight_key(block_hash: H) -> Vec { + (b"block_weight", block_hash).encode() +} + fn load_decode(backend: &B, key: &[u8]) -> ClientResult> where B: AuxStore, @@ -45,7 +50,7 @@ fn load_decode(backend: &B, key: &[u8]) -> ClientResult> pub(crate) fn load_epoch_changes( backend: &B, ) -> ClientResult> { - let epoch_changes = load_decode::<_, EpochChanges>(backend, BABE_EPOCH_CHANGES)? + let epoch_changes = load_decode::<_, EpochChangesFor>(backend, BABE_EPOCH_CHANGES)? .map(Into::into) .unwrap_or_else(|| { info!(target: "babe", @@ -59,7 +64,7 @@ pub(crate) fn load_epoch_changes( /// Update the epoch changes on disk after a change. pub(crate) fn write_epoch_changes( - epoch_changes: &EpochChanges, + epoch_changes: &EpochChangesFor, write_aux: F, ) -> R where F: FnOnce(&[(&'static [u8], &[u8])]) -> R, @@ -69,3 +74,28 @@ pub(crate) fn write_epoch_changes( &[(BABE_EPOCH_CHANGES, encoded_epoch_changes.as_slice())], ) } + +/// Write the cumulative chain-weight of a block ot aux storage. +pub(crate) fn write_block_weight( + block_hash: H, + block_weight: &BabeBlockWeight, + write_aux: F, +) -> R where + F: FnOnce(&[(Vec, &[u8])]) -> R, +{ + + let key = block_weight_key(block_hash); + block_weight.using_encoded(|s| + write_aux( + &[(key, s)], + ) + ) +} + +/// Load the cumulative chain-weight associated with a block. +pub(crate) fn load_block_weight( + backend: &B, + block_hash: H, +) -> ClientResult> { + load_decode(backend, block_weight_key(block_hash).as_slice()) +} diff --git a/core/consensus/babe/src/epoch_changes.rs b/core/consensus/babe/src/epoch_changes.rs new file mode 100644 index 0000000000..0dbad245e6 --- /dev/null +++ b/core/consensus/babe/src/epoch_changes.rs @@ -0,0 +1,637 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Handling epoch changes in BABE. +//! +//! This exposes the `SharedEpochChanges`, which is a wrapper around a +//! persistent DAG superimposed over the forks of the blockchain. + +use std::sync::Arc; +use babe_primitives::{Epoch, SlotNumber, NextEpochDescriptor}; +use fork_tree::ForkTree; +use parking_lot::{Mutex, MutexGuard}; +use sr_primitives::traits::{Block as BlockT, NumberFor, One, Zero}; +use codec::{Encode, Decode}; +use client::error::Error as ClientError; +use client::utils as client_utils; +use client::blockchain::HeaderBackend; +use primitives::H256; +use std::ops::Add; + +/// A builder for `is_descendent_of` functions. +pub trait IsDescendentOfBuilder { + /// The error returned by the function. + type Error: std::error::Error; + /// A function that can tell you if the second parameter is a descendent of + /// the first. + type IsDescendentOf: Fn(&Hash, &Hash) -> Result; + + /// Build an `is_descendent_of` function. + /// + /// The `current` parameter can be `Some` with the details a fresh block whose + /// details aren't yet stored, but its parent is. + /// + /// The format of `current` when `Some` is `(current, current_parent)`. + fn build_is_descendent_of(&self, current: Option<(Hash, Hash)>) + -> Self::IsDescendentOf; +} + +/// Produce a descendent query object given the client. +pub(crate) fn descendent_query(client: &H) -> HeaderBackendDescendentBuilder<&H, Block> { + HeaderBackendDescendentBuilder(client, std::marker::PhantomData) +} + +/// Wrapper to get around unconstrained type errors when implementing +/// `IsDescendentOfBuilder` for header backends. +pub(crate) struct HeaderBackendDescendentBuilder(H, std::marker::PhantomData); + +// TODO: relying on Hash = H256 is awful. +// https://github.com/paritytech/substrate/issues/3624 +impl<'a, H, Block> IsDescendentOfBuilder + for HeaderBackendDescendentBuilder<&'a H, Block> where + H: HeaderBackend, + Block: BlockT, +{ + type Error = ClientError; + type IsDescendentOf = Box Result + 'a>; + + fn build_is_descendent_of(&self, current: Option<(H256, H256)>) + -> Self::IsDescendentOf + { + Box::new(client_utils::is_descendent_of(self.0, current)) + } +} + +/// An unimported genesis epoch. +pub struct UnimportedGenesis(Epoch); + +/// The viable epoch under which a block can be verified. +/// +/// If this is the first non-genesis block in the chain, then it will +/// hold an `UnimportedGenesis` epoch. +pub enum ViableEpoch { + Genesis(UnimportedGenesis), + Regular(Epoch), +} + +impl From for ViableEpoch { + fn from(epoch: Epoch) -> ViableEpoch { + ViableEpoch::Regular(epoch) + } +} + +impl AsRef for ViableEpoch { + fn as_ref(&self) -> &Epoch { + match *self { + ViableEpoch::Genesis(UnimportedGenesis(ref e)) => e, + ViableEpoch::Regular(ref e) => e, + } + } +} + +impl ViableEpoch { + /// Extract the underlying epoch, disregarding the fact that a genesis + /// epoch may be unimported. + pub fn into_inner(self) -> Epoch { + match self { + ViableEpoch::Genesis(UnimportedGenesis(e)) => e, + ViableEpoch::Regular(e) => e, + } + } + + /// Increment the epoch, yielding an `IncrementedEpoch` to be imported + /// into the fork-tree. + pub fn increment(&self, next_descriptor: NextEpochDescriptor) -> IncrementedEpoch { + let next = self.as_ref().increment(next_descriptor); + let to_persist = match *self { + ViableEpoch::Genesis(UnimportedGenesis(ref epoch_0)) => + PersistedEpoch::Genesis(epoch_0.clone(), next), + ViableEpoch::Regular(_) => PersistedEpoch::Regular(next), + }; + + IncrementedEpoch(to_persist) + } +} + +/// The datatype encoded on disk. +// This really shouldn't be public, but the encode/decode derives force it to be. +#[derive(Clone, Encode, Decode)] +pub enum PersistedEpoch { + // epoch_0, epoch_1, + Genesis(Epoch, Epoch), + // epoch_n + Regular(Epoch), +} + +/// A fresh, incremented epoch to import into the underlying fork-tree. +/// +/// Create this with `ViableEpoch::increment`. +#[must_use = "Freshly-incremented epoch must be imported with `EpochChanges::import`"] +pub struct IncrementedEpoch(PersistedEpoch); + +impl AsRef for IncrementedEpoch { + fn as_ref(&self) -> &Epoch { + match self.0 { + PersistedEpoch::Genesis(_, ref epoch_1) => epoch_1, + PersistedEpoch::Regular(ref epoch_n) => epoch_n, + } + } +} + +/// Tree of all epoch changes across all *seen* forks. Data stored in tree is +/// the hash and block number of the block signaling the epoch change, and the +/// epoch that was signalled at that block. +/// +/// BABE special-cases the first epoch, epoch_0, by saying that it starts at +/// slot number of the first block in the chain. When bootstrapping a chain, +/// there can be multiple competing block #1s, so we have to ensure that the overlayed +/// DAG doesn't get confused. +/// +/// The first block of every epoch should be producing a descriptor for the next +/// epoch - this is checked in higher-level code. So the first block of epoch_0 contains +/// a descriptor for epoch_1. We special-case these and bundle them together in the +/// same DAG entry, pinned to a specific block #1. +/// +/// Further epochs (epoch_2, ..., epoch_n) each get their own entry. +#[derive(Clone, Encode, Decode)] +pub struct EpochChanges { + inner: ForkTree, +} + +// create a fake header hash which hasn't been included in the chain. +fn fake_head_hash + AsMut<[u8]> + Clone>(parent_hash: &H) -> H { + let mut h = parent_hash.clone(); + // dirty trick: flip the first bit of the parent hash to create a hash + // which has not been in the chain before (assuming a strong hash function). + h.as_mut()[0] ^= 0b10000000; + h +} + +impl EpochChanges where + Hash: PartialEq + AsRef<[u8]> + AsMut<[u8]> + Copy, + Number: Ord + One + Zero + Add + Copy, +{ + /// Create a new epoch-change tracker. + fn new() -> Self { + EpochChanges { inner: ForkTree::new() } + } + + /// Prune out finalized epochs, except for the ancestor of the finalized block. + pub fn prune_finalized>( + &mut self, + descendent_of_builder: D, + _hash: &Hash, + _number: Number, + ) -> Result<(), fork_tree::Error> { + let _is_descendent_of = descendent_of_builder + .build_is_descendent_of(None); + + // TODO: + // https://github.com/paritytech/substrate/issues/3651 + // + // prune any epochs which could not be _live_ as of the children of the + // finalized block. + // i.e. re-root the fork tree to the oldest ancestor of (hash, number) + // where epoch.end_slot() >= slot(hash) + + Ok(()) + } + + /// Finds the epoch for a child of the given block, assuming the given slot number. + /// + /// If the returned epoch is an `UnimportedGenesis` epoch, it should be imported into the + /// tree. + pub fn epoch_for_child_of, G>( + &self, + descendent_of_builder: D, + parent_hash: &Hash, + parent_number: Number, + slot_number: SlotNumber, + make_genesis: G, + ) -> Result, fork_tree::Error> + where G: FnOnce(SlotNumber) -> Epoch + { + // find_node_where will give you the node in the fork-tree which is an ancestor + // of the `parent_hash` by default. if the last epoch was signalled at the parent_hash, + // then it won't be returned. we need to create a new fake chain head hash which + // "descends" from our parent-hash. + let fake_head_hash = fake_head_hash(parent_hash); + + let is_descendent_of = descendent_of_builder + .build_is_descendent_of(Some((fake_head_hash, *parent_hash))); + + if parent_number == Zero::zero() { + // need to insert the genesis epoch. + let genesis_epoch = make_genesis(slot_number); + return Ok(Some(ViableEpoch::Genesis(UnimportedGenesis(genesis_epoch)))); + } + + // We want to find the deepest node in the tree which is an ancestor + // of our block and where the start slot of the epoch was before the + // slot of our block. The genesis special-case doesn't need to look + // at epoch_1 -- all we're doing here is figuring out which node + // we need. + let predicate = |epoch: &PersistedEpoch| match *epoch { + PersistedEpoch::Genesis(ref epoch_0, _) => + epoch_0.start_slot <= slot_number, + PersistedEpoch::Regular(ref epoch_n) => + epoch_n.start_slot <= slot_number, + }; + + self.inner.find_node_where( + &fake_head_hash, + &(parent_number + One::one()), + &is_descendent_of, + &predicate, + ) + .map(|n| n.map(|node| ViableEpoch::Regular(match node.data { + // Ok, we found our node. + // and here we figure out which of the internal epochs + // of a genesis node to use based on their start slot. + PersistedEpoch::Genesis(ref epoch_0, ref epoch_1) => + if epoch_1.start_slot <= slot_number { + epoch_1.clone() + } else { + epoch_0.clone() + }, + PersistedEpoch::Regular(ref epoch_n) => epoch_n.clone(), + }))) + } + + /// Import a new epoch-change, signalled at the given block. + /// + /// This assumes that the given block is prospective (i.e. has not been + /// imported yet), but its parent has. This is why the parent hash needs + /// to be provided. + pub fn import>( + &mut self, + descendent_of_builder: D, + hash: Hash, + number: Number, + parent_hash: Hash, + epoch: IncrementedEpoch, + ) -> Result<(), fork_tree::Error> { + let is_descendent_of = descendent_of_builder + .build_is_descendent_of(Some((hash, parent_hash))); + + let res = self.inner.import( + hash, + number, + epoch.0, + &is_descendent_of, + ); + + match res { + Ok(_) | Err(fork_tree::Error::Duplicate) => Ok(()), + Err(e) => Err(e), + } + } +} + +/// Type alias to produce the epoch-changes tree from a block type. +pub type EpochChangesFor = EpochChanges<::Hash, NumberFor>; + +/// A shared epoch changes tree. +#[derive(Clone)] +pub struct SharedEpochChanges { + inner: Arc>>, +} + +impl SharedEpochChanges { + /// Create a new instance of the `SharedEpochChanges`. + pub fn new() -> Self { + SharedEpochChanges { + inner: Arc::new(Mutex::new(EpochChanges::<_, _>::new())) + } + } + + /// Lock the shared epoch changes, + pub fn lock(&self) -> MutexGuard> { + self.inner.lock() + } +} + +impl From> for SharedEpochChanges { + fn from(epoch_changes: EpochChangesFor) -> Self { + SharedEpochChanges { + inner: Arc::new(Mutex::new(epoch_changes)) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[derive(Debug, PartialEq)] + pub struct TestError; + + impl std::fmt::Display for TestError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "TestError") + } + } + + impl std::error::Error for TestError {} + + impl<'a, F: 'a , H: 'a + PartialEq + std::fmt::Debug> IsDescendentOfBuilder for &'a F + where F: Fn(&H, &H) -> Result + { + type Error = TestError; + type IsDescendentOf = Box Result + 'a>; + + fn build_is_descendent_of(&self, current: Option<(H, H)>) + -> Self::IsDescendentOf + { + let f = *self; + Box::new(move |base, head| { + let mut head = head; + + if let Some((ref c_head, ref c_parent)) = current { + if head == c_head { + if base == c_parent { + return Ok(true); + } else { + head = c_parent; + } + } + } + + f(base, head) + }) + } + } + + type Hash = [u8; 1]; + + #[test] + fn genesis_epoch_is_created_but_not_imported() { + // + // A - B + // \ + // — C + // + let is_descendent_of = |base: &Hash, block: &Hash| -> Result { + match (base, *block) { + (b"A", b) => Ok(b == *b"B" || b == *b"C" || b == *b"D"), + (b"B", b) | (b"C", b) => Ok(b == *b"D"), + (b"0", _) => Ok(true), + _ => Ok(false), + } + }; + + let make_genesis = |slot| Epoch { + epoch_index: 0, + start_slot: slot, + duration: 100, + authorities: Vec::new(), + randomness: [0; 32], + }; + + let epoch_changes = EpochChanges::new(); + let genesis_epoch = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"0", + 0, + 10101, + &make_genesis, + ).unwrap().unwrap(); + + match genesis_epoch { + ViableEpoch::Genesis(_) => {}, + _ => panic!("should be unimported genesis"), + }; + assert_eq!(genesis_epoch.as_ref(), &make_genesis(10101)); + + let genesis_epoch_2 = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"0", + 0, + 10102, + &make_genesis, + ).unwrap().unwrap(); + + match genesis_epoch_2 { + ViableEpoch::Genesis(_) => {}, + _ => panic!("should be unimported genesis"), + }; + assert_eq!(genesis_epoch_2.as_ref(), &make_genesis(10102)); + } + + #[test] + fn epoch_changes_between_blocks() { + // + // A - B + // \ + // — C + // + let is_descendent_of = |base: &Hash, block: &Hash| -> Result { + match (base, *block) { + (b"A", b) => Ok(b == *b"B" || b == *b"C" || b == *b"D"), + (b"B", b) | (b"C", b) => Ok(b == *b"D"), + (b"0", _) => Ok(true), + _ => Ok(false), + } + }; + + let make_genesis = |slot| Epoch { + epoch_index: 0, + start_slot: slot, + duration: 100, + authorities: Vec::new(), + randomness: [0; 32], + }; + + let mut epoch_changes = EpochChanges::new(); + let genesis_epoch = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"0", + 0, + 100, + &make_genesis, + ).unwrap().unwrap(); + + assert_eq!(genesis_epoch.as_ref(), &make_genesis(100)); + + let import_epoch_1 = genesis_epoch.increment(NextEpochDescriptor { + authorities: Vec::new(), + randomness: [1; 32], + }); + let epoch_1 = import_epoch_1.as_ref().clone(); + + epoch_changes.import( + &is_descendent_of, + *b"A", + 1, + *b"0", + import_epoch_1, + ).unwrap(); + let genesis_epoch = genesis_epoch.into_inner(); + + assert!(is_descendent_of(b"0", b"A").unwrap()); + + let end_slot = genesis_epoch.end_slot(); + assert_eq!(end_slot, epoch_1.start_slot); + + { + // x is still within the genesis epoch. + let x = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"A", + 1, + end_slot - 1, + &make_genesis, + ).unwrap().unwrap().into_inner(); + + assert_eq!(x, genesis_epoch); + } + + { + // x is now at the next epoch, because the block is now at the + // start slot of epoch 1. + let x = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"A", + 1, + end_slot, + &make_genesis, + ).unwrap().unwrap().into_inner(); + + assert_eq!(x, epoch_1); + } + + { + // x is now at the next epoch, because the block is now after + // start slot of epoch 1. + let x = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"A", + 1, + epoch_1.end_slot() - 1, + &make_genesis, + ).unwrap().unwrap().into_inner(); + + assert_eq!(x, epoch_1); + } + } + + #[test] + fn two_block_ones_dont_conflict() { + // X - Y + // / + // 0 - A - B + // + let is_descendent_of = |base: &Hash, block: &Hash| -> Result { + match (base, *block) { + (b"A", b) => Ok(b == *b"B"), + (b"X", b) => Ok(b == *b"Y"), + (b"0", _) => Ok(true), + _ => Ok(false), + } + }; + + let duration = 100; + + let make_genesis = |slot| Epoch { + epoch_index: 0, + start_slot: slot, + duration, + authorities: Vec::new(), + randomness: [0; 32], + }; + + let mut epoch_changes = EpochChanges::new(); + let next_descriptor = NextEpochDescriptor { + authorities: Vec::new(), + randomness: [0; 32], + }; + + // insert genesis epoch for A + { + let genesis_epoch_a = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"0", + 0, + 100, + &make_genesis, + ).unwrap().unwrap(); + + epoch_changes.import( + &is_descendent_of, + *b"A", + 1, + *b"0", + genesis_epoch_a.increment(next_descriptor.clone()), + ).unwrap(); + + } + + // insert genesis epoch for X + { + let genesis_epoch_x = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"0", + 0, + 1000, + &make_genesis, + ).unwrap().unwrap(); + + epoch_changes.import( + &is_descendent_of, + *b"X", + 1, + *b"0", + genesis_epoch_x.increment(next_descriptor.clone()), + ).unwrap(); + } + + // now check that the genesis epochs for our respective block 1s + // respect the chain structure. + { + let epoch_for_a_child = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"A", + 1, + 101, + &make_genesis, + ).unwrap().unwrap(); + + assert_eq!(epoch_for_a_child.into_inner(), make_genesis(100)); + + let epoch_for_x_child = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"X", + 1, + 1001, + &make_genesis, + ).unwrap().unwrap(); + + assert_eq!(epoch_for_x_child.into_inner(), make_genesis(1000)); + + let epoch_for_x_child_before_genesis = epoch_changes.epoch_for_child_of( + &is_descendent_of, + b"X", + 1, + 101, + &make_genesis, + ).unwrap(); + + // even though there is a genesis epoch at that slot, it's not in + // this chain. + assert!(epoch_for_x_child_before_genesis.is_none()); + } + } +} diff --git a/core/consensus/babe/src/lib.rs b/core/consensus/babe/src/lib.rs index 7816f81d47..58e6c77cc3 100644 --- a/core/consensus/babe/src/lib.rs +++ b/core/consensus/babe/src/lib.rs @@ -56,7 +56,8 @@ //! An in-depth description and analysis of the protocol can be found here: //! -#![forbid(unsafe_code, missing_docs)] +#![forbid(unsafe_code)] +#![warn(missing_docs)] pub use babe_primitives::*; pub use consensus_common::SyncOracle; use std::{collections::HashMap, sync::Arc, u64, pin::Pin, time::{Instant, Duration}}; @@ -67,12 +68,12 @@ use consensus_common::import_queue::{ }; use sr_primitives::{generic::{BlockId, OpaqueDigestItemId}, Justification}; use sr_primitives::traits::{ - Block as BlockT, Header, DigestItemFor, NumberFor, ProvideRuntimeApi, + Block as BlockT, Header, DigestItemFor, ProvideRuntimeApi, Zero, }; use keystore::KeyStorePtr; -use codec::{Decode, Encode}; -use parking_lot::{Mutex, MutexGuard}; +use codec::Encode; +use parking_lot::Mutex; use primitives::{blake2_256, Blake2Hasher, H256, Pair, Public, U256}; use merlin::Transcript; use inherents::{InherentDataProviders, InherentData}; @@ -96,43 +97,62 @@ use srml_babe::{ timestamp::{TimestampInherentData, InherentType as TimestampInherent} }; use consensus_common::SelectChain; -use consensus_common::import_queue::{Verifier, BasicQueue}; +use consensus_common::import_queue::{Verifier, BasicQueue, CacheKeyId}; use client::{ block_builder::api::BlockBuilder as BlockBuilderApi, blockchain::{self, HeaderBackend, ProvideCache}, BlockchainEvents, CallExecutor, Client, - runtime_api::ApiExt, error::Result as ClientResult, backend::{AuxStore, Backend}, + error::Result as ClientResult, backend::{AuxStore, Backend}, ProvideUncles, - utils::is_descendent_of, - well_known_cache_keys::{self, Id as CacheKeyId}, }; -use fork_tree::ForkTree; use slots::{CheckedHeader, check_equivocation}; use futures::prelude::*; -use futures01::Stream as _; -use log::{error, warn, debug, info, trace}; +use log::{warn, debug, info, trace}; use slots::{SlotWorker, SlotData, SlotInfo, SlotCompatible}; +use epoch_changes::descendent_query; mod aux_schema; +mod epoch_changes; #[cfg(test)] mod tests; -pub use babe_primitives::{AuthorityId, AuthorityPair, AuthoritySignature}; +pub use babe_primitives::{ + AuthorityId, AuthorityPair, AuthoritySignature, Epoch, NextEpochDescriptor, +}; +pub use epoch_changes::{EpochChanges, SharedEpochChanges}; + +macro_rules! babe_err { + ($($i: expr),+) => { + { + debug!(target: "babe", $($i),+); + format!($($i),+) + } + }; +} + +macro_rules! babe_info { + ($($i: expr),+) => { + { + info!(target: "babe", $($i),+); + format!($($i),+) + } + }; +} /// A slot duration. Create with `get_or_compute`. // FIXME: Once Rust has higher-kinded types, the duplication between this // and `super::babe::Config` can be eliminated. // https://github.com/paritytech/substrate/issues/2434 +#[derive(Clone)] pub struct Config(slots::SlotDuration); impl Config { /// Either fetch the slot duration from disk or compute it from the genesis /// state. - pub fn get_or_compute(client: &C) -> ClientResult - where + pub fn get_or_compute(client: &C) -> ClientResult where C: AuxStore + ProvideRuntimeApi, C::Api: BabeApi, { trace!(target: "babe", "Getting slot duration"); - match slots::SlotDuration::get_or_compute(client, |a, b| a.startup_data(b)).map(Self) { + match slots::SlotDuration::get_or_compute(client, |a, b| a.configuration(b)).map(Self) { Ok(s) => Ok(s), Err(s) => { warn!(target: "babe", "Failed to get slot duration"); @@ -141,37 +161,29 @@ impl Config { } } - /// Get the slot duration in milliseconds. - pub fn get(&self) -> u64 { - self.0.slot_duration - } - - /// Retrieve the threshold calculation constant `c`. - pub fn c(&self) -> (u64, u64) { - self.0.c + /// Create the genesis epoch (epoch #0). This is defined to start at the slot of + /// the first block, so that has to be provided. + pub fn genesis_epoch(&self, slot_number: SlotNumber) -> Epoch { + Epoch { + epoch_index: 0, + start_slot: slot_number, + duration: self.epoch_length, + authorities: self.genesis_authorities.clone(), + randomness: self.randomness.clone(), + } } } -impl SlotCompatible for BabeLink { - fn extract_timestamp_and_slot( - &self, - data: &InherentData, - ) -> Result<(TimestampInherent, u64, std::time::Duration), consensus_common::Error> { - trace!(target: "babe", "extract timestamp"); - data.timestamp_inherent_data() - .and_then(|t| data.babe_inherent_data().map(|a| (t, a))) - .map_err(Into::into) - .map_err(consensus_common::Error::InherentData) - .map(|(x, y)| (x, y, self.0.lock().0.take().unwrap_or_default())) +impl std::ops::Deref for Config { + type Target = BabeConfiguration; + + fn deref(&self) -> &BabeConfiguration { + &*self.0 } } /// Parameters for BABE. -pub struct BabeParams { - /// The configuration for BABE. Includes the slot duration, threshold, and - /// other parameters. - pub config: Config, - +pub struct BabeParams { /// The keystore that manages the keys of the node. pub keystore: KeyStorePtr, @@ -181,12 +193,14 @@ pub struct BabeParams { /// The SelectChain Strategy pub select_chain: SC, - /// A block importer - pub block_import: I, - - /// The environment + /// The environment we are producing blocks for. pub env: E, + /// The underlying block-import object to supply our produced blocks to. + /// This must be a `BabeBlockImport` or a wrapper of it, otherwise + /// critical consensus logic will be omitted. + pub block_import: I, + /// A sync oracle pub sync_oracle: SO, @@ -197,80 +211,104 @@ pub struct BabeParams { pub force_authoring: bool, /// The source of timestamps for relative slots - pub time_source: BabeLink, + pub babe_link: BabeLink, } /// Start the babe worker. The returned future should be run in a tokio runtime. -pub fn start_babe(BabeParams { - config, - client, +pub fn start_babe(BabeParams { keystore, + client, select_chain, - block_import, env, + block_import, sync_oracle, inherent_data_providers, force_authoring, - time_source, -}: BabeParams) -> Result< + babe_link, +}: BabeParams) -> Result< impl futures01::Future, consensus_common::Error, > where - B: BlockT, - C: ProvideRuntimeApi + ProvideCache + ProvideUncles + Send + Sync + 'static, + B: BlockT, + C: ProvideRuntimeApi + ProvideCache + ProvideUncles + BlockchainEvents + + HeaderBackend + Send + Sync + 'static, C::Api: BabeApi, SC: SelectChain + 'static, E: Environment + Send + Sync, E::Proposer: Proposer, >::Create: Unpin + Send + 'static, - H: Header, - I: BlockImport + Send + Sync + 'static, + I: BlockImport + Send + Sync + 'static, Error: std::error::Error + Send + From<::consensus_common::Error> + From + 'static, SO: SyncOracle + Send + Sync + Clone, { + let config = babe_link.config; let worker = BabeWorker { client: client.clone(), block_import: Arc::new(Mutex::new(block_import)), env, sync_oracle: sync_oracle.clone(), force_authoring, - c: config.c(), keystore, + epoch_changes: babe_link.epoch_changes.clone(), + config: config.clone(), }; - register_babe_inherent_data_provider(&inherent_data_providers, config.0.slot_duration())?; + + register_babe_inherent_data_provider(&inherent_data_providers, config.slot_duration())?; uncles::register_uncles_inherent_data_provider( client.clone(), select_chain.clone(), &inherent_data_providers, )?; - Ok(slots::start_slot_worker( + + let epoch_changes = babe_link.epoch_changes.clone(); + let pruning_task = client.finality_notification_stream() + .for_each(move |notification| { + // TODO: supply is-descendent-of and maybe write to disk _now_ + // as opposed to waiting for the next epoch? + let res = epoch_changes.lock().prune_finalized( + descendent_query(&*client), + ¬ification.hash, + *notification.header.number(), + ); + + if let Err(e) = res { + babe_err!("Could not prune expired epoch changes: {:?}", e); + } + + future::ready(()) + }); + + babe_info!("Starting BABE Authorship worker"); + let slot_worker = slots::start_slot_worker( config.0, select_chain, worker, sync_oracle, inherent_data_providers, - time_source, - ).map(|()| Ok::<(), ()>(())).compat()) + babe_link.time_source, + ).map(|_| ()); + + Ok(future::select(slot_worker, pruning_task).map(|_| Ok::<(), ()>(())).compat()) } -struct BabeWorker { +struct BabeWorker { client: Arc, block_import: Arc>, env: E, sync_oracle: SO, force_authoring: bool, - c: (u64, u64), keystore: KeyStorePtr, + epoch_changes: SharedEpochChanges, + config: Config, } -impl slots::SimpleSlotWorker for BabeWorker where - B: BlockT, - C: ProvideRuntimeApi + ProvideCache, +impl slots::SimpleSlotWorker for BabeWorker where + B: BlockT, + C: ProvideRuntimeApi + ProvideCache + HeaderBackend, C::Api: BabeApi, E: Environment, E::Proposer: Proposer, >::Create: Unpin + Send + 'static, - H: Header, I: BlockImport + Send + Sync + 'static, SO: SyncOracle + Send + Clone, Error: std::error::Error + Send + From<::consensus_common::Error> + From + 'static, @@ -289,8 +327,16 @@ impl slots::SimpleSlotWorker for BabeWorker Result { - epoch_from_runtime(self.client.as_ref(), &BlockId::Hash(*block)) + fn epoch_data(&self, parent: &B::Header, slot_number: u64) -> Result { + self.epoch_changes.lock().epoch_for_child_of( + descendent_query(&*self.client), + &parent.hash(), + parent.number().clone(), + slot_number, + |slot| self.config.genesis_epoch(slot) + ) + .map_err(|e| ConsensusError::ChainLookup(format!("{:?}", e)))? + .map(|e| e.into_inner()) .ok_or(consensus_common::Error::InvalidAuthoritiesSet) } @@ -300,22 +346,23 @@ impl slots::SimpleSlotWorker for BabeWorker Option { - let parent_weight = { - let pre_digest = find_pre_digest::(&header).ok()?; - pre_digest.weight() - }; - - claim_slot( + debug!(target: "babe", "Attempting to claim slot {}", slot_number); + let s = claim_slot( slot_number, - parent_weight, epoch_data, - self.c, + &*self.config, &self.keystore, - ) + ); + + if let Some(_) = s { + debug!(target: "babe", "Claimed slot {}", slot_number); + } + + s } fn pre_digest_data(&self, _slot_number: u64, claim: &Self::Claim) -> Vec> { @@ -336,9 +383,6 @@ impl slots::SimpleSlotWorker for BabeWorker as CompatibleDigestItem>::babe_seal(signature); - // When we building our own blocks we always author on top of the - // current best according to `SelectChain`, therefore our own block - // proposal should always become the new best. BlockImportParams { origin: BlockOrigin::Own, header, @@ -346,8 +390,11 @@ impl slots::SimpleSlotWorker for BabeWorker slots::SimpleSlotWorker for BabeWorker SlotWorker for BabeWorker where - B: BlockT, - C: ProvideRuntimeApi + ProvideCache + Send + Sync, +impl SlotWorker for BabeWorker where + B: BlockT, + C: ProvideRuntimeApi + ProvideCache + HeaderBackend + Send + Sync, C::Api: BabeApi, E: Environment + Send + Sync, E::Proposer: Proposer, >::Create: Unpin + Send + 'static, - H: Header, I: BlockImport + Send + Sync + 'static, SO: SyncOracle + Send + Sync + Clone, Error: std::error::Error + Send + From<::consensus_common::Error> + From + 'static, @@ -386,14 +432,6 @@ impl SlotWorker for BabeWorker where } } -macro_rules! babe_err { - ($($i: expr),+) => { - { debug!(target: "babe", $($i),+) - ; format!($($i),+) - } - }; -} - /// Extract the BABE pre digest from the given header. Pre-runtime digests are /// mandatory, the function will return `Err` if none is found. fn find_pre_digest(header: &B::Header) -> Result @@ -405,7 +443,6 @@ fn find_pre_digest(header: &B::Header) -> Result(header: &B::Header) -> Result(header: &B::Header) -> Result, String> +fn find_next_epoch_digest(header: &B::Header) + -> Result, String> where DigestItemFor: CompatibleDigestItem, { let mut epoch_digest: Option<_> = None; @@ -439,6 +477,26 @@ fn find_next_epoch_digest(header: &B::Header) -> Result Ok(epoch_digest) } +struct VerificationParams<'a, B: 'a + BlockT> { + /// the header being verified. + header: B::Header, + /// the pre-digest of the header being verified. this is optional - if prior + /// verification code had to read it, it can be included here to avoid duplicate + /// work. + pre_digest: Option, + /// the slot number of the current time. + slot_now: SlotNumber, + /// epoch descriptor of the epoch this block _should_ be under, if it's valid. + epoch: &'a Epoch, + /// genesis config of this BABE chain. + config: &'a Config, +} + +struct VerifiedHeaderInfo { + pre_digest: DigestItemFor, + seal: DigestItemFor, +} + /// Check a header has been signed by the right key. If the slot is too far in /// the future, an error will be returned. If successful, returns the pre-header /// and the digest item containing the seal. @@ -450,23 +508,23 @@ fn find_next_epoch_digest(header: &B::Header) -> Result /// /// The given header can either be from a primary or secondary slot assignment, /// with each having different validation logic. -// FIXME #1018 needs misbehavior types. The `transaction_pool` parameter will be -// used to submit such misbehavior reports. -fn check_header( - mut header: B::Header, - parent_header: B::Header, - slot_now: u64, - authorities: &[(AuthorityId, BabeAuthorityWeight)], +fn check_header( + params: VerificationParams, client: &C, - randomness: [u8; 32], - epoch_index: u64, - secondary_slots: bool, - c: (u64, u64), - _transaction_pool: Option<&T>, -) -> Result, DigestItemFor)>, String> where +) -> Result>, String> where DigestItemFor: CompatibleDigestItem, - T: Send + Sync + 'static, { + let VerificationParams { + mut header, + pre_digest, + slot_now, + epoch, + config, + } = params; + + let authorities = &epoch.authorities; + let pre_digest = pre_digest.map(Ok).unwrap_or_else(|| find_pre_digest::(&header))?; + trace!(target: "babe", "Checking header"); let seal = match header.digest_mut().pop() { Some(x) => x, @@ -481,8 +539,6 @@ fn check_header( // and that's what we sign let pre_hash = header.hash(); - let pre_digest = find_pre_digest::(&header)?; - if pre_digest.slot_number() > slot_now { header.digest_mut().push(seal); return Ok(CheckedHeader::Deferred(header, pre_digest.slot_number())); @@ -492,40 +548,30 @@ fn check_header( return Err(babe_err!("Slot author not found")); } - let parent_weight = { - let parent_pre_digest = find_pre_digest::(&parent_header)?; - parent_pre_digest.weight() - }; - match &pre_digest { - BabePreDigest::Primary { vrf_output, vrf_proof, authority_index, slot_number, weight } => { + BabePreDigest::Primary { vrf_output, vrf_proof, authority_index, slot_number } => { debug!(target: "babe", "Verifying Primary block"); - let digest = (vrf_output, vrf_proof, *authority_index, *slot_number, *weight); + let digest = (vrf_output, vrf_proof, *authority_index, *slot_number); check_primary_header::( pre_hash, digest, sig, - parent_weight, - authorities, - randomness, - epoch_index, - c, + &epoch, + config.c, )?; }, - BabePreDigest::Secondary { authority_index, slot_number, weight } if secondary_slots => { + BabePreDigest::Secondary { authority_index, slot_number } if config.secondary_slots => { debug!(target: "babe", "Verifying Secondary block"); - let digest = (*authority_index, *slot_number, *weight); + let digest = (*authority_index, *slot_number); check_secondary_header::( pre_hash, digest, sig, - parent_weight, - &authorities, - randomness, + &epoch, )?; }, _ => { @@ -544,17 +590,20 @@ fn check_header( &header, author, ).map_err(|e| e.to_string())? { - info!( + babe_info!( "Slot author {:?} is equivocating at slot {} with headers {:?} and {:?}", author, pre_digest.slot_number(), equivocation_proof.fst_header().hash(), - equivocation_proof.snd_header().hash(), + equivocation_proof.snd_header().hash() ); } - let pre_digest = CompatibleDigestItem::babe_pre_digest(pre_digest); - Ok(CheckedHeader::Checked(header, (pre_digest, seal))) + let info = VerifiedHeaderInfo { + pre_digest: CompatibleDigestItem::babe_pre_digest(pre_digest), + seal, + }; + Ok(CheckedHeader::Checked(header, info)) } /// Check a primary slot proposal header. We validate that the given header is @@ -563,29 +612,23 @@ fn check_header( /// its parent since it is a primary block. fn check_primary_header( pre_hash: B::Hash, - pre_digest: (&VRFOutput, &VRFProof, AuthorityIndex, SlotNumber, BabeBlockWeight), + pre_digest: (&VRFOutput, &VRFProof, AuthorityIndex, SlotNumber), signature: AuthoritySignature, - parent_weight: BabeBlockWeight, - authorities: &[(AuthorityId, BabeAuthorityWeight)], - randomness: [u8; 32], - epoch_index: u64, + epoch: &Epoch, c: (u64, u64), ) -> Result<(), String> where DigestItemFor: CompatibleDigestItem, { - let (vrf_output, vrf_proof, authority_index, slot_number, weight) = pre_digest; - if weight != parent_weight + 1 { - return Err("Invalid weight: should increase with Primary block.".into()); - } + let (vrf_output, vrf_proof, authority_index, slot_number) = pre_digest; - let author = &authorities[authority_index as usize].0; + let author = &epoch.authorities[authority_index as usize].0; if AuthorityPair::verify(&signature, pre_hash, &author) { let (inout, _) = { let transcript = make_transcript( - &randomness, + &epoch.randomness, slot_number, - epoch_index, + epoch.epoch_index, ); schnorrkel::PublicKey::from_bytes(author.as_slice()).and_then(|p| { @@ -595,7 +638,12 @@ fn check_primary_header( })? }; - let threshold = calculate_primary_threshold(c, authorities, authority_index as usize); + let threshold = calculate_primary_threshold( + c, + &epoch.authorities, + authority_index as usize, + ); + if !check_primary_threshold(&inout, threshold) { return Err(babe_err!("VRF verification of block by author {:?} failed: \ threshold {} exceeded", author, threshold)); @@ -613,27 +661,21 @@ fn check_primary_header( /// compared to its parent since it is a secondary block. fn check_secondary_header( pre_hash: B::Hash, - pre_digest: (AuthorityIndex, SlotNumber, BabeBlockWeight), + pre_digest: (AuthorityIndex, SlotNumber), signature: AuthoritySignature, - parent_weight: BabeBlockWeight, - authorities: &[(AuthorityId, BabeAuthorityWeight)], - randomness: [u8; 32], + epoch: &Epoch, ) -> Result<(), String> { - let (authority_index, slot_number, weight) = pre_digest; - - if weight != parent_weight { - return Err("Invalid weight: Should stay the same with secondary block.".into()); - } + let (authority_index, slot_number) = pre_digest; // check the signature is valid under the expected authority and // chain state. let expected_author = secondary_slot_author( slot_number, - authorities, - randomness, + &epoch.authorities, + epoch.randomness, ).ok_or_else(|| "No secondary author expected.".to_string())?; - let author = &authorities[authority_index as usize].0; + let author = &epoch.authorities[authority_index as usize].0; if expected_author != author { let msg = format!("Invalid author: Expected secondary author: {:?}, got: {:?}.", @@ -651,21 +693,42 @@ fn check_secondary_header( } } +#[derive(Default, Clone)] +struct TimeSource(Arc, Vec<(Instant, u64)>)>>); + +impl SlotCompatible for TimeSource { + fn extract_timestamp_and_slot( + &self, + data: &InherentData, + ) -> Result<(TimestampInherent, u64, std::time::Duration), consensus_common::Error> { + trace!(target: "babe", "extract timestamp"); + data.timestamp_inherent_data() + .and_then(|t| data.babe_inherent_data().map(|a| (t, a))) + .map_err(Into::into) + .map_err(consensus_common::Error::InherentData) + .map(|(x, y)| (x, y, self.0.lock().0.take().unwrap_or_default())) + } +} + /// State that must be shared between the import queue and the authoring logic. -#[derive(Default, Clone, Debug)] -pub struct BabeLink(Arc, Vec<(Instant, u64)>)>>); +#[derive(Clone)] +pub struct BabeLink { + time_source: TimeSource, + epoch_changes: SharedEpochChanges, + config: Config, +} /// A verifier for Babe blocks. -pub struct BabeVerifier { +pub struct BabeVerifier { client: Arc>, api: Arc, inherent_data_providers: inherents::InherentDataProviders, config: Config, - time_source: BabeLink, - transaction_pool: Option>, + epoch_changes: SharedEpochChanges, + time_source: TimeSource, } -impl BabeVerifier { +impl BabeVerifier { fn check_inherents( &self, block: Block, @@ -704,7 +767,7 @@ fn median_algorithm( if num_timestamps as u64 >= median_required_blocks && median_required_blocks > 0 { let mut new_list: Vec<_> = time_source.1.iter().map(|&(t, sl)| { let offset: u128 = u128::from(slot_duration) - .checked_mul(1_000_000u128) // self.config.get() returns *milliseconds* + .checked_mul(1_000_000u128) // self.config.slot_duration returns milliseconds .and_then(|x| { x.checked_mul(u128::from(slot_number).saturating_sub(u128::from(sl))) }) @@ -735,14 +798,13 @@ fn median_algorithm( } } -impl Verifier for BabeVerifier where +impl Verifier for BabeVerifier where Block: BlockT, B: Backend + 'static, E: CallExecutor + 'static + Clone + Send + Sync, RA: Send + Sync, PRA: ProvideRuntimeApi + Send + Sync + AuxStore + ProvideCache, PRA::Api: BlockBuilderApi + BabeApi, - T: Send + Sync + 'static, { fn verify( &mut self, @@ -772,59 +834,38 @@ impl Verifier for BabeVerifier( - header.clone(), - parent_header.clone(), - slot_now + 1, - &authorities, - &self.api, - randomness, - epoch_index, - secondary_slots, - self.config.c(), - self.transaction_pool.as_ref().map(|x| &**x), - ); - - // if we have failed to check header using (presumably) current epoch AND we're probably in the next epoch - // => check using next epoch - // (this is only possible on the light client at epoch#0) - if epoch_index == 0 && checked_header.is_err() { - if let Some(Epoch { authorities, randomness, epoch_index, .. }) = maybe_next_epoch { - let checked_header_next = check_header::( - header, - parent_header, - slot_now + 1, - &authorities, - &self.api, - randomness, - epoch_index, - secondary_slots, - self.config.c(), - self.transaction_pool.as_ref().map(|x| &**x), - ); + let pre_digest = find_pre_digest::(&header)?; + let epoch = { + let epoch_changes = self.epoch_changes.lock(); + epoch_changes.epoch_for_child_of( + descendent_query(&*self.client), + &parent_hash, + parent_header.number().clone(), + pre_digest.slot_number(), + |slot| self.config.genesis_epoch(slot), + ) + .map_err(|e| format!("{:?}", e))? + .ok_or_else(|| format!("Could not fetch epoch at {:?}", parent_hash))? + }; - match checked_header_next { - Ok(checked_header_next) => checked_header = Ok(checked_header_next), - Err(_) => (), - } - } - } + // We add one to the current slot to allow for some small drift. + // FIXME #1019 in the future, alter this queue to allow deferring of headers + let v_params = VerificationParams { + header, + pre_digest: Some(pre_digest.clone()), + slot_now: slot_now + 1, + epoch: epoch.as_ref(), + config: &self.config, + }; + let checked_header = check_header::(v_params, &self.api)?; - let checked_header = checked_header?; match checked_header { - CheckedHeader::Checked(pre_header, (pre_digest, seal)) => { - let babe_pre_digest = pre_digest.as_babe_pre_digest() + CheckedHeader::Checked(pre_header, verified_info) => { + let babe_pre_digest = verified_info.pre_digest.as_babe_pre_digest() .expect("check_header always returns a pre-digest digest item; qed"); let slot_number = babe_pre_digest.slot_number(); @@ -852,42 +893,18 @@ impl Verifier for BabeVerifier ?pre_header); - // The fork choice rule is that we pick the heaviest chain (i.e. - // more primary blocks), if there's a tie we go with the longest - // chain. - let new_best = { - let (last_best, last_best_number) = { - let info = self.client.info().chain; - (info.best_hash, info.best_number) - }; - - let best_header = self.client.header(&BlockId::Hash(last_best)) - .map_err(|_| "Failed fetching best header")? - .expect("parent_header must be imported; qed"); - - let best_weight = find_pre_digest::(&best_header) - .map(|babe_pre_digest| babe_pre_digest.weight())?; - - let new_weight = babe_pre_digest.weight(); - - if new_weight > best_weight { - true - } else if new_weight == best_weight { - *pre_header.number() > last_best_number - } else { - false - } - }; - let block_import_params = BlockImportParams { origin, header: pre_header, - post_digests: vec![seal], + post_digests: vec![verified_info.seal], body, finalized: false, justification, auxiliary: Vec::new(), - fork_choice: ForkChoiceStrategy::Custom(new_best), + // TODO: block-import handles fork choice and this shouldn't even have the + // option to specify one. + // https://github.com/paritytech/substrate/issues/3623 + fork_choice: ForkChoiceStrategy::LongestChain, }; Ok((block_import_params, Default::default())) @@ -903,77 +920,6 @@ impl Verifier for BabeVerifier (Epoch, Option) { - match self { - MaybeSpanEpoch::Genesis(epoch0, epoch1) => (epoch0, Some(epoch1)), - MaybeSpanEpoch::Regular(epoch) => (epoch, None), - } - } - - #[cfg(test)] - pub fn into_regular(self) -> Option { - match self { - MaybeSpanEpoch::Regular(epoch) => Some(epoch), - _ => None, - } - } -} - -/// Extract current epoch data from cache and fallback to querying the runtime -/// if the cache isn't populated. -fn epoch(client: &C, at: &BlockId) -> Result where - B: BlockT, - C: ProvideRuntimeApi + ProvideCache, - C::Api: BabeApi, -{ - epoch_from_cache(client, at) - .or_else(|| epoch_from_runtime(client, at).map(MaybeSpanEpoch::Regular)) - .ok_or(consensus_common::Error::InvalidAuthoritiesSet) -} - -/// Extract current epoch data from cache. -fn epoch_from_cache(client: &C, at: &BlockId) -> Option where - B: BlockT, - C: ProvideCache, -{ - // the epoch that is BABE-valid at the block is not the epoch that is cache-valid at the block - // we need to go back for maximum two steps - client.cache() - .and_then(|cache| cache - .get_at(&well_known_cache_keys::EPOCH, at) - .and_then(|(_, _, v)| Decode::decode(&mut &v[..]).ok())) -} - -/// Extract current epoch from runtime. -fn epoch_from_runtime(client: &C, at: &BlockId) -> Option where - B: BlockT, - C: ProvideRuntimeApi, - C::Api: BabeApi, -{ - if client.runtime_api().has_api::>(at).unwrap_or(false) { - let s = BabeApi::epoch(&*client.runtime_api(), at).ok()?; - if s.authorities.is_empty() { - error!("No authorities!"); - None - } else { - Some(s) - } - } else { - error!("bad api!"); - None - } -} - /// The BABE import queue type. pub type BabeImportQueue = BasicQueue; @@ -1050,17 +996,15 @@ fn calculate_primary_threshold( /// claim a secondary slot. fn claim_slot( slot_number: SlotNumber, - parent_weight: BabeBlockWeight, epoch: &Epoch, - c: (u64, u64), + config: &BabeConfiguration, keystore: &KeyStorePtr, ) -> Option<(BabePreDigest, AuthorityPair)> { - claim_primary_slot(slot_number, parent_weight, epoch, c, keystore) + claim_primary_slot(slot_number, epoch, config.c, keystore) .or_else(|| { - if epoch.secondary_slots { + if config.secondary_slots { claim_secondary_slot( slot_number, - parent_weight, &epoch.authorities, keystore, epoch.randomness, @@ -1077,7 +1021,6 @@ fn claim_slot( /// so it returns `Some(_)`. Otherwise, it returns `None`. fn claim_primary_slot( slot_number: SlotNumber, - parent_weight: BabeBlockWeight, epoch: &Epoch, c: (u64, u64), keystore: &KeyStorePtr, @@ -1107,7 +1050,6 @@ fn claim_primary_slot( vrf_output: s.0.to_output(), vrf_proof: s.1, authority_index: authority_index as u32, - weight: parent_weight + 1, } }); @@ -1149,7 +1091,6 @@ fn secondary_slot_author( /// to propose. fn claim_secondary_slot( slot_number: SlotNumber, - parent_weight: BabeBlockWeight, authorities: &[(AuthorityId, BabeAuthorityWeight)], keystore: &KeyStorePtr, randomness: [u8; 32], @@ -1176,7 +1117,6 @@ fn claim_secondary_slot( let pre_digest = BabePreDigest::Secondary { slot_number, authority_index: authority_index as u32, - weight: parent_weight, }; return Some((pre_digest, pair)); @@ -1186,76 +1126,6 @@ fn claim_secondary_slot( None } -fn initialize_authorities_cache(client: &C) -> Result<(), ConsensusError> where - B: BlockT, - C: ProvideRuntimeApi + ProvideCache, - C::Api: BabeApi, -{ - // no cache => no initialization - let cache = match client.cache() { - Some(cache) => cache, - None => return Ok(()), - }; - - // check if we already have initialized the cache - let genesis_id = BlockId::Number(Zero::zero()); - let genesis_epoch: Option = cache - .get_at(&well_known_cache_keys::EPOCH, &genesis_id) - .and_then(|(_, _, v)| Decode::decode(&mut &v[..]).ok()); - if genesis_epoch.is_some() { - return Ok(()); - } - - let map_err = |error| consensus_common::Error::from(consensus_common::Error::ClientImport( - format!( - "Error initializing authorities cache: {}", - error, - ))); - - let epoch0 = epoch_from_runtime(client, &genesis_id).ok_or(consensus_common::Error::InvalidAuthoritiesSet)?; - let mut epoch1 = epoch0.clone(); - epoch1.epoch_index = 1; - - let genesis_epoch = MaybeSpanEpoch::Genesis(epoch0, epoch1); - cache.initialize(&well_known_cache_keys::EPOCH, genesis_epoch.encode()) - .map_err(map_err) -} - -/// Tree of all epoch changes across all *seen* forks. Data stored in tree is -/// the hash and block number of the block signaling the epoch change, and the -/// epoch that was signalled at that block. -type EpochChanges = ForkTree< - ::Hash, - NumberFor, - Epoch, ->; - -/// A shared epoch changes tree. -#[derive(Clone)] -struct SharedEpochChanges { - inner: Arc>>, -} - -impl SharedEpochChanges { - fn new() -> Self { - SharedEpochChanges { - inner: Arc::new(Mutex::new(EpochChanges::::new())) - } - } - - fn lock(&self) -> MutexGuard> { - self.inner.lock() - } -} - -impl From> for SharedEpochChanges { - fn from(epoch_changes: EpochChanges) -> Self { - SharedEpochChanges { - inner: Arc::new(Mutex::new(epoch_changes)) - } - } -} - /// A block-import handler for BABE. /// /// This scans each imported block for epoch change signals. The signals are @@ -1269,6 +1139,7 @@ pub struct BabeBlockImport { client: Arc>, api: Arc, epoch_changes: SharedEpochChanges, + config: Config, } impl Clone for BabeBlockImport { @@ -1278,6 +1149,7 @@ impl Clone for BabeBlockImport BabeBlockImport { api: Arc, epoch_changes: SharedEpochChanges, block_import: I, + config: Config, ) -> Self { BabeBlockImport { client, api, inner: block_import, epoch_changes, + config, } } } @@ -1313,7 +1187,7 @@ impl BlockImport for BabeBlockImport, - mut new_cache: HashMap>, + new_cache: HashMap>, ) -> Result { let hash = block.post_header().hash(); let number = block.header.number().clone(); @@ -1326,63 +1200,79 @@ impl BlockImport for BabeBlockImport return Err(ConsensusError::ClientImport(e.to_string()).into()), } - let slot_number = { - let pre_digest = find_pre_digest::(&block.header) - .expect("valid babe headers must contain a predigest; \ - header has been already verified; qed"); - pre_digest.slot_number() - }; - - // returns a function for checking whether a block is a descendent of another - // consistent with querying client directly after importing the block. - let parent_hash = *block.header.parent_hash(); - let is_descendent_of = is_descendent_of(&self.client, Some((&hash, &parent_hash))); + let pre_digest = find_pre_digest::(&block.header) + .expect("valid babe headers must contain a predigest; \ + header has been already verified; qed"); + let slot_number = pre_digest.slot_number(); - // check if there's any epoch change expected to happen at this slot let mut epoch_changes = self.epoch_changes.lock(); - let enacted_epoch = epoch_changes.find_node_where( - &hash, - &number, - &is_descendent_of, - &|epoch| epoch.start_slot <= slot_number, - ).map_err(|e| ConsensusError::from(ConsensusError::ClientImport(e.to_string())))?; - - let check_roots = || -> Result { - // this can only happen when the chain starts, since there's no - // epoch change at genesis. afterwards every time we expect an epoch - // change it means we will import another one. - for (root, _, _) in epoch_changes.roots() { - let is_descendent_of = is_descendent_of(root, &hash) - .map_err(|e| { - ConsensusError::from(ConsensusError::ClientImport(e.to_string())) - })?; - - if is_descendent_of { - return Ok(false); - } - } - Ok(true) + // check if there's any epoch change expected to happen at this slot. + // `epoch` is the epoch to verify the block under, and `first_in_epoch` is true + // if this is the first block in its chain for that epoch. + // + // also provides the total weight of the chain, including the imported block. + let (epoch, first_in_epoch, parent_weight) = { + let parent_hash = *block.header.parent_hash(); + let parent_header = self.client.header(&BlockId::Hash(parent_hash)) + .map_err(|e| ConsensusError::ChainLookup(e.to_string()))? + .ok_or_else(|| ConsensusError::ChainLookup(babe_err!( + "Parent ({}) of {} unavailable. Cannot import", + parent_hash, + hash + )))?; + + let parent_slot = find_pre_digest::(&parent_header) + .map(|d| d.slot_number()) + .expect("parent is non-genesis; valid BABE headers contain a pre-digest; \ + header has already been verified; qed"); + + let parent_weight = if *parent_header.number() == Zero::zero() { + 0 + } else { + aux_schema::load_block_weight(&*self.client, parent_hash) + .map_err(|e| ConsensusError::ClientImport(e.to_string()))? + .ok_or_else(|| ConsensusError::ClientImport( + babe_err!("Parent block of {} has no associated weight", hash) + ))? + }; + + let epoch = epoch_changes.epoch_for_child_of( + descendent_query(&*self.client), + &parent_hash, + *parent_header.number(), + slot_number, + |slot| self.config.genesis_epoch(slot), + ) + .map_err(|e: fork_tree::Error| ConsensusError::ChainLookup( + babe_err!("Could not look up epoch: {:?}", e) + ))? + .ok_or_else(|| ConsensusError::ClientImport( + babe_err!("Block {} is not valid under any epoch.", hash) + ))?; + + let first_in_epoch = parent_slot < epoch.as_ref().start_slot; + (epoch, first_in_epoch, parent_weight) }; - let expected_epoch_change = enacted_epoch.is_some(); + let total_weight = parent_weight + pre_digest.added_weight(); + + // search for this all the time so we can reject unexpected announcements. let next_epoch_digest = find_next_epoch_digest::(&block.header) .map_err(|e| ConsensusError::from(ConsensusError::ClientImport(e.to_string())))?; - match (expected_epoch_change, next_epoch_digest.is_some()) { + match (first_in_epoch, next_epoch_digest.is_some()) { (true, true) => {}, (false, false) => {}, (true, false) => { return Err( ConsensusError::ClientImport( - "Expected epoch change to happen by this block".into(), + babe_err!("Expected epoch change to happen at {:?}, s{}", hash, slot_number), ) ); }, (false, true) => { - if !check_roots()? { - return Err(ConsensusError::ClientImport("Unexpected epoch change".into())); - } + return Err(ConsensusError::ClientImport("Unexpected epoch change".into())); }, } @@ -1390,37 +1280,31 @@ impl BlockImport for BabeBlockImport= start slot {}).", + epoch.as_ref().epoch_index, hash, slot_number, epoch.as_ref().start_slot); + babe_info!("Next epoch starts at slot {}", next_epoch.as_ref().start_slot); + // track the epoch change in the fork tree - epoch_changes.import( + let res = epoch_changes.import( + descendent_query(&*self.client), hash, number, + *block.header.parent_hash(), next_epoch, - &is_descendent_of, - ).map_err(|e| ConsensusError::from(ConsensusError::ClientImport(e.to_string())))?; + ); + + + if let Err(e) = res { + let err = ConsensusError::ClientImport(format!("{:?}", e)); + babe_err!("Failed to launch next epoch: {:?}", e); + *epoch_changes = old_epoch_changes.expect("set `Some` above and not taken; qed"); + return Err(err); + } crate::aux_schema::write_epoch_changes::( &*epoch_changes, @@ -1430,6 +1314,44 @@ impl BlockImport for BabeBlockImport last_best_weight { + true + } else if total_weight == last_best_weight { + number > last_best_number + } else { + false + }) + }; + let import_result = self.inner.import_block(block, new_cache); // revert to the original epoch changes in case there's an error @@ -1452,81 +1374,80 @@ impl BlockImport for BabeBlockImport, I, RA, PRA>( + config: Config, + wrapped_block_import: I, + client: Arc>, + api: Arc, +) -> ClientResult<(BabeBlockImport, BabeLink)> where + B: Backend, + E: CallExecutor, +{ + let epoch_changes = aux_schema::load_epoch_changes(&*client)?; + let link = BabeLink { + epoch_changes: epoch_changes.clone(), + time_source: Default::default(), + config: config.clone(), + }; + + let import = BabeBlockImport::new( + client, + api, + epoch_changes, + wrapped_block_import, + config, + ); + + Ok((import, link)) +} + +/// Start an import queue for the BABE consensus algorithm. +/// +/// This method returns the import queue, some data that needs to be passed to the block authoring +/// logic (`BabeLink`), and a future that must be run to /// completion and is responsible for listening to finality notifications and /// pruning the epoch changes tree. -pub fn import_queue, I, RA, PRA, T>( - config: Config, +/// +/// The block import object provided must be the `BabeBlockImport` or a wrapper +/// of it, otherwise crucial import logic will be omitted. +pub fn import_queue, I, RA, PRA>( + babe_link: BabeLink, block_import: I, justification_import: Option>, finality_proof_import: Option>, client: Arc>, api: Arc, inherent_data_providers: InherentDataProviders, - transaction_pool: Option>, -) -> ClientResult<( - BabeImportQueue, - BabeLink, - BabeBlockImport, - impl futures01::Future, -)> where +) -> ClientResult> where B: Backend + 'static, - I: BlockImport + Clone + Send + Sync + 'static, - I::Error: Into, + I: BlockImport + Send + Sync + 'static, E: CallExecutor + Clone + Send + Sync + 'static, RA: Send + Sync + 'static, PRA: ProvideRuntimeApi + ProvideCache + Send + Sync + AuxStore + 'static, PRA::Api: BlockBuilderApi + BabeApi, - T: Send + Sync + 'static, { - register_babe_inherent_data_provider(&inherent_data_providers, config.get())?; - initialize_authorities_cache(&*api)?; + register_babe_inherent_data_provider(&inherent_data_providers, babe_link.config.slot_duration)?; let verifier = BabeVerifier { client: client.clone(), - api: api.clone(), + api, inherent_data_providers, - time_source: Default::default(), - config, - transaction_pool, + config: babe_link.config, + epoch_changes: babe_link.epoch_changes, + time_source: babe_link.time_source, }; - let epoch_changes = aux_schema::load_epoch_changes(&*client)?; - - let block_import = BabeBlockImport::new( - client.clone(), - api, - epoch_changes.clone(), - block_import, - ); - - let pruning_task = client.finality_notification_stream() - .map(|v| Ok::<_, ()>(v)).compat() - .for_each(move |notification| { - let is_descendent_of = is_descendent_of(&client, None); - epoch_changes.lock().prune( - ¬ification.hash, - *notification.header.number(), - &is_descendent_of, - ).map_err(|e| { - debug!(target: "babe", "Error pruning epoch changes fork tree: {:?}", e) - })?; - - Ok(()) - }); - - let timestamp_core = verifier.time_source.clone(); - let queue = BasicQueue::new( + Ok(BasicQueue::new( verifier, - Box::new(block_import.clone()), + Box::new(block_import), justification_import, finality_proof_import, - ); - - Ok((queue, timestamp_core, block_import, pruning_task)) + )) } /// BABE test helpers. Utility methods for manually authoring blocks. @@ -1540,26 +1461,25 @@ pub mod test_helpers { slot_number: u64, parent: &B::Header, client: &C, - c: (u64, u64), keystore: &KeyStorePtr, + link: &BabeLink, ) -> Option where - B: BlockT, - C: ProvideRuntimeApi + ProvideCache, + B: BlockT, + C: ProvideRuntimeApi + ProvideCache + HeaderBackend, C::Api: BabeApi, { - let epoch = match epoch(client, &BlockId::Hash(parent.hash())).unwrap() { - MaybeSpanEpoch::Regular(epoch) => epoch, - _ => unreachable!("it is always Regular epoch on full nodes"), - }; - - let weight = find_pre_digest::(parent).ok() - .map(|d| d.weight())?; + let epoch = link.epoch_changes.lock().epoch_for_child_of( + descendent_query(client), + &parent.hash(), + parent.number().clone(), + slot_number, + |slot| link.config.genesis_epoch(slot), + ).unwrap().unwrap(); super::claim_slot( slot_number, - weight, - &epoch, - c, + epoch.as_ref(), + &link.config, keystore, ).map(|(digest, _)| digest) } diff --git a/core/consensus/babe/src/tests.rs b/core/consensus/babe/src/tests.rs index 7274cc1230..70c7738dec 100644 --- a/core/consensus/babe/src/tests.rs +++ b/core/consensus/babe/src/tests.rs @@ -21,19 +21,22 @@ #![allow(deprecated)] use super::*; -use babe_primitives::AuthorityPair; +use babe_primitives::{AuthorityPair, SlotNumber}; use client::block_builder::BlockBuilder; use consensus_common::NoNetwork as DummyOracle; +use consensus_common::import_queue::{ + BoxBlockImport, BoxJustificationImport, BoxFinalityProofImport, +}; use network::test::*; use network::test::{Block as TestBlock, PeersClient}; +use network::config::BoxFinalityProofRequestBuilder; use sr_primitives::{generic::DigestItem, traits::{Block as BlockT, DigestFor}}; use network::config::ProtocolConfig; use tokio::runtime::current_thread; -use keyring::sr25519::Keyring; use client::BlockchainEvents; use test_client; use log::debug; -use std::{time::Duration, borrow::Borrow, cell::RefCell}; +use std::{time::Duration, cell::RefCell}; type Item = DigestItem; @@ -46,8 +49,28 @@ type TestClient = client::Client< test_client::runtime::RuntimeApi, >; -struct DummyFactory(Arc); -struct DummyProposer(u64, Arc); +#[derive(Copy, Clone, PartialEq)] +enum Stage { + PreSeal, + PostSeal, +} + +type Mutator = Arc; + +#[derive(Clone)] +struct DummyFactory { + client: Arc, + epoch_changes: crate::SharedEpochChanges, + config: Config, + mutator: Mutator, +} + +struct DummyProposer { + factory: DummyFactory, + parent_hash: Hash, + parent_number: u64, + parent_slot: SlotNumber, +} impl Environment for DummyFactory { type Proposer = DummyProposer; @@ -56,7 +79,69 @@ impl Environment for DummyFactory { fn init(&mut self, parent_header: &::Header) -> Result { - Ok(DummyProposer(parent_header.number + 1, self.0.clone())) + + let parent_slot = crate::find_pre_digest::(parent_header) + .expect("parent header has a pre-digest") + .slot_number(); + + Ok(DummyProposer { + factory: self.clone(), + parent_hash: parent_header.hash(), + parent_number: *parent_header.number(), + parent_slot, + }) + } +} + +impl DummyProposer { + fn propose_with(&mut self, pre_digests: DigestFor) + -> future::Ready> + { + let block_builder = self.factory.client.new_block_at( + &BlockId::Hash(self.parent_hash), + pre_digests, + ).unwrap(); + let mut block = match block_builder.bake().map_err(|e| e.into()) { + Ok(b) => b, + Err(e) => return future::ready(Err(e)), + }; + + let this_slot = crate::find_pre_digest::(block.header()) + .expect("baked block has valid pre-digest") + .slot_number(); + + // figure out if we should add a consensus digest, since the test runtime + // doesn't. + let epoch_changes = self.factory.epoch_changes.lock(); + let epoch = epoch_changes.epoch_for_child_of( + descendent_query(&*self.factory.client), + &self.parent_hash, + self.parent_number, + this_slot, + |slot| self.factory.config.genesis_epoch(slot), + ) + .expect("client has data to find epoch") + .expect("can compute epoch for baked block") + .into_inner(); + + let first_in_epoch = self.parent_slot < epoch.start_slot; + if first_in_epoch { + // push a `Consensus` digest signalling next change. + // we just reuse the same randomness and authorities as the prior + // epoch. this will break when we add light client support, since + // that will re-check the randomness logic off-chain. + let digest_data = ConsensusLog::NextEpochData(NextEpochDescriptor { + authorities: epoch.authorities.clone(), + randomness: epoch.randomness.clone(), + }).encode(); + let digest = DigestItem::Consensus(BABE_ENGINE_ID, digest_data); + block.header.digest_mut().push(digest) + } + + // mutate the block header according to the mutator. + (self.factory.mutator)(&mut block.header, Stage::PreSeal); + + future::ready(Ok(block)) } } @@ -67,21 +152,42 @@ impl Proposer for DummyProposer { fn propose( &mut self, _: InherentData, - digests: DigestFor, + pre_digests: DigestFor, _: Duration, ) -> Self::Create { - future::ready(self.1.new_block(digests).unwrap().bake().map_err(|e| e.into())) + self.propose_with(pre_digests) } } -type Mutator = Arc Fn(&'r mut TestHeader) + Send + Sync>; - thread_local! { - static MUTATOR: RefCell = RefCell::new(Arc::new(|_|())); + static MUTATOR: RefCell = RefCell::new(Arc::new(|_, _|())); +} + +#[derive(Clone)] +struct PanickingBlockImport(B); + +impl> BlockImport for PanickingBlockImport { + type Error = B::Error; + + fn import_block( + &mut self, + block: BlockImportParams, + new_cache: HashMap>, + ) -> Result { + Ok(self.0.import_block(block, new_cache).expect("importing block failed")) + } + + fn check_block( + &mut self, + hash: Hash, + parent_hash: Hash, + ) -> Result { + Ok(self.0.check_block(hash, parent_hash).expect("checking block failed")) + } } pub struct BabeTestNet { - peers: Vec>, + peers: Vec, DummySpecialization>>, } type TestHeader = ::Header; @@ -94,7 +200,6 @@ pub struct TestVerifier { TestBlock, test_client::runtime::RuntimeApi, PeersFullClient, - (), >, mutator: Mutator, } @@ -110,16 +215,22 @@ impl Verifier for TestVerifier { justification: Option, body: Option>, ) -> Result<(BlockImportParams, Option)>>), String> { - let cb: &(dyn Fn(&mut TestHeader) + Send + Sync) = self.mutator.borrow(); - cb(&mut header); + // apply post-sealing mutations (i.e. stripping seal, if desired). + (self.mutator)(&mut header, Stage::PostSeal); Ok(self.inner.verify(origin, header, justification, body).expect("verification failed!")) } } +pub struct PeerData { + link: BabeLink, + inherent_data_providers: InherentDataProviders, + block_import: Mutex>>, +} + impl TestNetFactory for BabeTestNet { type Specialization = DummySpecialization; type Verifier = TestVerifier; - type PeerData = (); + type PeerData = Option; /// Create new test network with peers and given config. fn from_config(_config: &ProtocolConfig) -> Self { @@ -129,31 +240,62 @@ impl TestNetFactory for BabeTestNet { } } - /// KLUDGE: this function gets the mutator from thread-local storage. - fn make_verifier(&self, client: PeersClient, _cfg: &ProtocolConfig) + fn make_block_import(&self, client: PeersClient) + -> ( + BoxBlockImport, + Option>, + Option>, + Option>, + Option, + ) + { + let client = client.as_full().expect("only full clients are tested"); + let inherent_data_providers = InherentDataProviders::new(); + + let config = Config::get_or_compute(&*client).expect("config available"); + let (block_import, link) = crate::block_import( + config, + client.clone(), + client.clone(), + client.clone(), + ).expect("can initialize block-import"); + + let block_import = PanickingBlockImport(block_import); + + let data_block_import = Mutex::new(Some(Box::new(block_import.clone()) as BoxBlockImport<_>)); + ( + Box::new(block_import), + None, + None, + None, + Some(PeerData { link, inherent_data_providers, block_import: data_block_import }), + ) + } + + fn make_verifier( + &self, + client: PeersClient, + _cfg: &ProtocolConfig, + maybe_link: &Option, + ) -> Self::Verifier { let client = client.as_full().expect("only full clients are used in test"); trace!(target: "babe", "Creating a verifier"); - let config = Config::get_or_compute(&*client) - .expect("slot duration available"); - let inherent_data_providers = InherentDataProviders::new(); - register_babe_inherent_data_provider( - &inherent_data_providers, - config.get() - ).expect("Registers babe inherent data provider"); - trace!(target: "babe", "Provider registered"); + + // ensure block import and verifier are linked correctly. + let data = maybe_link.as_ref().expect("babe link always provided to verifier instantiation"); TestVerifier { inner: BabeVerifier { client: client.clone(), api: client, - inherent_data_providers, - config, - time_source: Default::default(), - transaction_pool : Default::default(), + inherent_data_providers: data.inherent_data_providers.clone(), + config: data.link.config.clone(), + epoch_changes: data.link.epoch_changes.clone(), + time_source: data.link.time_source.clone(), }, - mutator: MUTATOR.with(|s| s.borrow().clone()), + mutator: MUTATOR.with(|m| m.borrow().clone()), } } @@ -188,8 +330,13 @@ fn rejects_empty_block() { }) } -fn run_one_test() { +fn run_one_test( + mutator: impl Fn(&mut TestHeader, Stage) + Send + Sync + 'static, +) { let _ = env_logger::try_init(); + let mutator = Arc::new(mutator) as Mutator; + + MUTATOR.with(|m| *m.borrow_mut() = mutator.clone()); let net = BabeTestNet::new(3); let peers = &[ @@ -202,6 +349,7 @@ fn run_one_test() { let mut import_notifications = Vec::new(); let mut runtime = current_thread::Runtime::new().unwrap(); let mut keystore_paths = Vec::new(); + for (peer_id, seed) in peers { let mut net = net.lock(); let peer = net.peer(*peer_id); @@ -213,30 +361,46 @@ fn run_one_test() { keystore.write().insert_ephemeral_from_seed::(seed).expect("Generates authority key"); keystore_paths.push(keystore_path); - let environ = DummyFactory(client.clone()); + let mut got_own = false; + let mut got_other = false; + + let data = peer.data.as_ref().expect("babe link set up during initialization"); + + let environ = DummyFactory { + client: client.clone(), + config: data.link.config.clone(), + epoch_changes: data.link.epoch_changes.clone(), + mutator: mutator.clone(), + }; + import_notifications.push( + // run each future until we get one of our own blocks with number higher than 5 + // that was produced locally. client.import_notification_stream() - .take_while(|n| future::ready(!(n.origin != BlockOrigin::Own && n.header.number() < &5))) - .for_each(move |_| future::ready(())) + .take_while(move |n| future::ready(n.header.number() < &5 || { + if n.origin == BlockOrigin::Own { + got_own = true; + } else { + got_other = true; + } + + // continue until we have at least one block of our own + // and one of another peer. + !(got_own && got_other) + })) + .for_each(|_| future::ready(()) ) ); - let config = Config::get_or_compute(&*client).expect("slot duration available"); - - let inherent_data_providers = InherentDataProviders::new(); - register_babe_inherent_data_provider( - &inherent_data_providers, config.get() - ).expect("Registers babe inherent data provider"); runtime.spawn(start_babe(BabeParams { - config, - block_import: client.clone(), + block_import: data.block_import.lock().take().expect("import set up during init"), select_chain, client, env: environ, sync_oracle: DummyOracle, - inherent_data_providers, + inherent_data_providers: data.inherent_data_providers.clone(), force_authoring: false, - time_source: Default::default(), + babe_link: data.link.clone(), keystore, }).expect("Starts babe")); } @@ -251,45 +415,41 @@ fn run_one_test() { } #[test] -fn authoring_blocks() { run_one_test() } +fn authoring_blocks() { + run_one_test(|_, _| ()) +} #[test] #[should_panic] fn rejects_missing_inherent_digest() { - MUTATOR.with(|s| *s.borrow_mut() = Arc::new(move |header: &mut TestHeader| { + run_one_test(|header: &mut TestHeader, stage| { let v = std::mem::replace(&mut header.digest_mut().logs, vec![]); header.digest_mut().logs = v.into_iter() - .filter(|v| v.as_babe_pre_digest().is_none()) + .filter(|v| stage == Stage::PostSeal || v.as_babe_pre_digest().is_none()) .collect() - })); - run_one_test() + }) } #[test] #[should_panic] fn rejects_missing_seals() { - MUTATOR.with(|s| *s.borrow_mut() = Arc::new(move |header: &mut TestHeader| { + run_one_test(|header: &mut TestHeader, stage| { let v = std::mem::replace(&mut header.digest_mut().logs, vec![]); header.digest_mut().logs = v.into_iter() - .filter(|v| v.as_babe_seal().is_none()) + .filter(|v| stage == Stage::PreSeal || v.as_babe_seal().is_none()) .collect() - })); - run_one_test() + }) } -// TODO: this test assumes that the test runtime will trigger epoch changes -// which isn't the case since it doesn't include the session module. #[test] #[should_panic] -#[ignore] fn rejects_missing_consensus_digests() { - MUTATOR.with(|s| *s.borrow_mut() = Arc::new(move |header: &mut TestHeader| { + run_one_test(|header: &mut TestHeader, stage| { let v = std::mem::replace(&mut header.digest_mut().logs, vec![]); header.digest_mut().logs = v.into_iter() - .filter(|v| v.as_babe_epoch().is_none()) + .filter(|v| stage == Stage::PostSeal || v.as_next_epoch_descriptor().is_none()) .collect() - })); - run_one_test() + }); } #[test] @@ -326,28 +486,34 @@ fn can_author_block() { .expect("Generates authority pair"); let mut i = 0; - let mut epoch = Epoch { + let epoch = Epoch { start_slot: 0, authorities: vec![(pair.public(), 1)], randomness: [0; 32], epoch_index: 1, duration: 100, - secondary_slots: true, }; - let parent_weight = 0; + let mut config = crate::BabeConfiguration { + slot_duration: 1000, + epoch_length: 100, + c: (3, 10), + genesis_authorities: Vec::new(), + randomness: [0; 32], + secondary_slots: true, + }; // with secondary slots enabled it should never be empty - match claim_slot(i, parent_weight, &epoch, (3, 10), &keystore) { + match claim_slot(i, &epoch, &config, &keystore) { None => i += 1, Some(s) => debug!(target: "babe", "Authored block {:?}", s.0), } // otherwise with only vrf-based primary slots we might need to try a couple // of times. - epoch.secondary_slots = false; + config.secondary_slots = false; loop { - match claim_slot(i, parent_weight, &epoch, (3, 10), &keystore) { + match claim_slot(i, &epoch, &config, &keystore) { None => i += 1, Some(s) => { debug!(target: "babe", "Authored block {:?}", s.0); @@ -358,14 +524,75 @@ fn can_author_block() { } #[test] -fn authorities_call_works() { - let _ = env_logger::try_init(); - let client = test_client::new(); - - assert_eq!(client.info().chain.best_number, 0); - assert_eq!(epoch(&client, &BlockId::Number(0)).unwrap().into_regular().unwrap().authorities, vec![ - (Keyring::Alice.public().into(), 1), - (Keyring::Bob.public().into(), 1), - (Keyring::Charlie.public().into(), 1), - ]); +fn importing_block_one_sets_genesis_epoch() { + let mut net = BabeTestNet::new(1); + + let peer = net.peer(0); + let data = peer.data.as_ref().expect("babe link set up during initialization"); + let client = peer.client().as_full().expect("Only full clients are used in tests").clone(); + + let mut environ = DummyFactory { + client: client.clone(), + config: data.link.config.clone(), + epoch_changes: data.link.epoch_changes.clone(), + mutator: Arc::new(|_, _| ()), + }; + + let genesis_header = client.header(&BlockId::Number(0)).unwrap().unwrap(); + + let mut proposer = environ.init(&genesis_header).unwrap(); + let babe_claim = Item::babe_pre_digest(babe_primitives::BabePreDigest::Secondary { + authority_index: 0, + slot_number: 999, + }); + let pre_digest = sr_primitives::generic::Digest { logs: vec![babe_claim] }; + + let genesis_epoch = data.link.config.genesis_epoch(999); + + let mut block = futures::executor::block_on(proposer.propose_with(pre_digest)).unwrap(); + + // seal by alice. + let seal = { + // sign the pre-sealed hash of the block and then + // add it to a digest item. + let pair = AuthorityPair::from_seed(&[1; 32]); + let pre_hash = block.header.hash(); + let signature = pair.sign(pre_hash.as_ref()); + Item::babe_seal(signature) + }; + + let post_hash = { + block.header.digest_mut().push(seal.clone()); + let h = block.header.hash(); + block.header.digest_mut().pop(); + h + }; + assert_eq!(*block.header.number(), 1); + let (header, body) = block.deconstruct(); + + let post_digests = vec![seal]; + let mut block_import = data.block_import.lock().take().expect("import set up during init"); + block_import.import_block( + BlockImportParams { + origin: BlockOrigin::Own, + header, + justification: None, + post_digests, + body: Some(body), + finalized: false, + auxiliary: Vec::new(), + fork_choice: ForkChoiceStrategy::LongestChain, + }, + Default::default(), + ).unwrap(); + + let epoch_changes = data.link.epoch_changes.lock(); + let epoch_for_second_block = epoch_changes.epoch_for_child_of( + descendent_query(&*client), + &post_hash, + 1, + 1000, + |slot| data.link.config.genesis_epoch(slot), + ).unwrap().unwrap().into_inner(); + assert_eq!(epoch_for_second_block, genesis_epoch); } diff --git a/core/consensus/common/src/block_import.rs b/core/consensus/common/src/block_import.rs index bcafb352cd..4024322911 100644 --- a/core/consensus/common/src/block_import.rs +++ b/core/consensus/common/src/block_import.rs @@ -120,7 +120,8 @@ pub struct BlockImportParams { /// Contains a list of key-value pairs. If values are `None`, the keys /// will be deleted. pub auxiliary: Vec<(Vec, Option>)>, - /// Fork choice strategy of this import. + /// Fork choice strategy of this import. This should only be set by a + /// synchronous import, otherwise it may race against other imports. pub fork_choice: ForkChoiceStrategy, } @@ -185,7 +186,31 @@ pub trait BlockImport { ) -> Result; } -impl BlockImport for Arc +impl BlockImport for crate::import_queue::BoxBlockImport { + type Error = crate::error::Error; + + /// Check block preconditions. + fn check_block( + &mut self, + hash: B::Hash, + parent_hash: B::Hash, + ) -> Result { + (**self).check_block(hash, parent_hash) + } + + /// Import a block. + /// + /// Cached data can be accessed through the blockchain cache. + fn import_block( + &mut self, + block: BlockImportParams, + cache: HashMap>, + ) -> Result { + (**self).import_block(block, cache) + } +} + +impl BlockImport for Arc where for<'r> &'r T: BlockImport { type Error = E; diff --git a/core/consensus/common/src/import_queue.rs b/core/consensus/common/src/import_queue.rs index 533df2b179..07d6297acc 100644 --- a/core/consensus/common/src/import_queue.rs +++ b/core/consensus/common/src/import_queue.rs @@ -105,6 +105,7 @@ pub trait ImportQueue: Send { number: NumberFor, finality_proof: Vec ); + /// Polls for actions to perform on the network. /// /// This method should behave in a way similar to `Future::poll`. It can register the current diff --git a/core/consensus/slots/src/lib.rs b/core/consensus/slots/src/lib.rs index bcceb62bb6..fd86a0f277 100644 --- a/core/consensus/slots/src/lib.rs +++ b/core/consensus/slots/src/lib.rs @@ -77,8 +77,9 @@ pub trait SimpleSlotWorker { /// A handle to a `BlockImport`. fn block_import(&self) -> Arc>; - /// Returns the epoch data necessary for authoring. - fn epoch_data(&self, block: &B::Hash) -> Result; + /// Returns the epoch data necessary for authoring. For time-dependent epochs, + /// use the provided slot number as a canonical source of time. + fn epoch_data(&self, header: &B::Header, slot_number: u64) -> Result; /// Returns the number of authorities given the epoch data. fn authorities_len(&self, epoch_data: &Self::EpochData) -> usize; @@ -120,7 +121,7 @@ pub trait SimpleSlotWorker { let (timestamp, slot_number, slot_duration) = (slot_info.timestamp, slot_info.number, slot_info.duration); - let epoch_data = match self.epoch_data(&chain_head.hash()) { + let epoch_data = match self.epoch_data(&chain_head, slot_number) { Ok(epoch_data) => epoch_data, Err(err) => { warn!("Unable to fetch epoch data at block {:?}: {:?}", chain_head.hash(), err); @@ -359,7 +360,8 @@ impl SlotData for u64 { } /// A slot duration. Create with `get_or_compute`. -// The internal member should stay private here. +// The internal member should stay private here to maintain invariants of +// `get_or_compute`. #[derive(Clone, Copy, Debug, Encode, Decode, Hash, PartialOrd, Ord, PartialEq, Eq)] pub struct SlotDuration(T); diff --git a/core/finality-grandpa/src/environment.rs b/core/finality-grandpa/src/environment.rs index 27d398ca3e..502d201b94 100644 --- a/core/finality-grandpa/src/environment.rs +++ b/core/finality-grandpa/src/environment.rs @@ -906,7 +906,7 @@ pub(crate) fn finalize_block, E, RA>( let status = authority_set.apply_standard_changes( hash, number, - &is_descendent_of(client, None), + &is_descendent_of::<_, _, Block::Hash>(client, None), ).map_err(|e| Error::Safety(e.to_string()))?; // check if this is this is the first finalization of some consensus changes diff --git a/core/finality-grandpa/src/import.rs b/core/finality-grandpa/src/import.rs index 8f7124b3d3..46b32d999d 100644 --- a/core/finality-grandpa/src/import.rs +++ b/core/finality-grandpa/src/import.rs @@ -294,7 +294,7 @@ where // returns a function for checking whether a block is a descendent of another // consistent with querying client directly after importing the block. let parent_hash = *block.header.parent_hash(); - let is_descendent_of = is_descendent_of(&self.inner, Some((&hash, &parent_hash))); + let is_descendent_of = is_descendent_of(&*self.inner, Some((&hash, &parent_hash))); let mut guard = InnerGuard { guard: Some(self.authority_set.inner().write()), diff --git a/core/finality-grandpa/src/tests.rs b/core/finality-grandpa/src/tests.rs index 9193dae71a..f6f28e705d 100644 --- a/core/finality-grandpa/src/tests.rs +++ b/core/finality-grandpa/src/tests.rs @@ -98,7 +98,12 @@ impl TestNetFactory for GrandpaTestNet { } } - fn make_verifier(&self, _client: PeersClient, _cfg: &ProtocolConfig) -> Self::Verifier { + fn make_verifier( + &self, + _client: PeersClient, + _cfg: &ProtocolConfig, + _: &PeerData, + ) -> Self::Verifier { PassThroughVerifier(false) // use non-instant finality. } diff --git a/core/network/src/test/mod.rs b/core/network/src/test/mod.rs index 8cceeeaae6..276bce9f39 100644 --- a/core/network/src/test/mod.rs +++ b/core/network/src/test/mod.rs @@ -461,7 +461,12 @@ pub trait TestNetFactory: Sized { /// These two need to be implemented! fn from_config(config: &ProtocolConfig) -> Self; - fn make_verifier(&self, client: PeersClient, config: &ProtocolConfig) -> Self::Verifier; + fn make_verifier( + &self, + client: PeersClient, + config: &ProtocolConfig, + peer_data: &Self::PeerData, + ) -> Self::Verifier; /// Get reference to peer. fn peer(&mut self, i: usize) -> &mut Peer; @@ -509,12 +514,23 @@ pub trait TestNetFactory: Sized { let backend = test_client_builder.backend(); let (c, longest_chain) = test_client_builder.build_with_longest_chain(); let client = Arc::new(c); - let verifier = self.make_verifier(PeersClient::Full(client.clone(), backend.clone()), config); - let verifier = VerifierAdapter(Arc::new(Mutex::new(Box::new(verifier) as Box<_>))); - let (block_import, justification_import, finality_proof_import, finality_proof_request_builder, data) - = self.make_block_import(PeersClient::Full(client.clone(), backend.clone())); + + let ( + block_import, + justification_import, + finality_proof_import, + finality_proof_request_builder, + data, + ) = self.make_block_import(PeersClient::Full(client.clone(), backend.clone())); let block_import = BlockImportAdapter(Arc::new(Mutex::new(block_import))); + let verifier = self.make_verifier( + PeersClient::Full(client.clone(), backend.clone()), + config, + &data, + ); + let verifier = VerifierAdapter(Arc::new(Mutex::new(Box::new(verifier) as Box<_>))); + let import_queue = Box::new(BasicQueue::new( verifier.clone(), Box::new(block_import.clone()), @@ -572,12 +588,22 @@ pub trait TestNetFactory: Sized { let (c, backend) = test_client::new_light(); let client = Arc::new(c); - let verifier = self.make_verifier(PeersClient::Light(client.clone(), backend.clone()), &config); - let verifier = VerifierAdapter(Arc::new(Mutex::new(Box::new(verifier) as Box<_>))); - let (block_import, justification_import, finality_proof_import, finality_proof_request_builder, data) - = self.make_block_import(PeersClient::Light(client.clone(), backend.clone())); + let ( + block_import, + justification_import, + finality_proof_import, + finality_proof_request_builder, + data, + ) = self.make_block_import(PeersClient::Light(client.clone(), backend.clone())); let block_import = BlockImportAdapter(Arc::new(Mutex::new(block_import))); + let verifier = self.make_verifier( + PeersClient::Light(client.clone(), backend.clone()), + &config, + &data, + ); + let verifier = VerifierAdapter(Arc::new(Mutex::new(Box::new(verifier) as Box<_>))); + let import_queue = Box::new(BasicQueue::new( verifier.clone(), Box::new(block_import.clone()), @@ -696,7 +722,7 @@ impl TestNetFactory for TestNet { } } - fn make_verifier(&self, _client: PeersClient, _config: &ProtocolConfig) + fn make_verifier(&self, _client: PeersClient, _config: &ProtocolConfig, _peer_data: &()) -> Self::Verifier { PassThroughVerifier(false) @@ -742,8 +768,8 @@ impl TestNetFactory for JustificationTestNet { JustificationTestNet(TestNet::from_config(config)) } - fn make_verifier(&self, client: PeersClient, config: &ProtocolConfig) -> Self::Verifier { - self.0.make_verifier(client, config) + fn make_verifier(&self, client: PeersClient, config: &ProtocolConfig, peer_data: &()) -> Self::Verifier { + self.0.make_verifier(client, config, peer_data) } fn peer(&mut self, i: usize) -> &mut Peer { diff --git a/core/phragmen/benches/phragmen.rs b/core/phragmen/benches/phragmen.rs index ecbf235bab..ae1daac468 100644 --- a/core/phragmen/benches/phragmen.rs +++ b/core/phragmen/benches/phragmen.rs @@ -16,7 +16,7 @@ //! Note that execution times will not be accurate in an absolute scale, since //! - Everything is executed in the context of `TestExternalities` //! - Everything is executed in native environment. - +#![cfg(feature = "bench")] #![feature(test)] extern crate test; diff --git a/core/service/src/chain_ops.rs b/core/service/src/chain_ops.rs index 3a3677798b..06390e80bd 100644 --- a/core/service/src/chain_ops.rs +++ b/core/service/src/chain_ops.rs @@ -20,6 +20,7 @@ use crate::RuntimeGenesis; use crate::error; use crate::chain_spec::ChainSpec; +/// Defines the logic for an operation exporting blocks within a range. #[macro_export] macro_rules! export_blocks { ($client:ident, $exit:ident, $output:ident, $from:ident, $to:ident, $json:ident) => {{ @@ -36,7 +37,7 @@ macro_rules! export_blocks { } let (exit_send, exit_recv) = std::sync::mpsc::channel(); - ::std::thread::spawn(move || { + std::thread::spawn(move || { let _ = $exit.wait(); let _ = exit_send.send(()); }); @@ -75,6 +76,7 @@ macro_rules! export_blocks { }} } +/// Defines the logic for an operation importing blocks from some known import. #[macro_export] macro_rules! import_blocks { ($block:ty, $client:ident, $queue:ident, $exit:ident, $input:ident) => {{ @@ -203,6 +205,7 @@ macro_rules! import_blocks { }} } +/// Revert the chain some number of blocks. #[macro_export] macro_rules! revert_chain { ($client:ident, $blocks:ident) => {{ diff --git a/core/service/test/src/lib.rs b/core/service/test/src/lib.rs index 870f287bff..6e096ec35c 100644 --- a/core/service/test/src/lib.rs +++ b/core/service/test/src/lib.rs @@ -20,7 +20,6 @@ use std::iter; use std::sync::{Arc, Mutex, MutexGuard}; use std::net::Ipv4Addr; use std::time::Duration; -use std::collections::HashMap; use log::info; use futures::{Future, Stream, Poll}; use tempdir::TempDir; @@ -36,7 +35,6 @@ use service::{ use network::{multiaddr, Multiaddr}; use network::config::{NetworkConfiguration, TransportConfig, NodeKeyConfig, Secret, NonReservedPeerMode}; use sr_primitives::{generic::BlockId, traits::Block as BlockT}; -use consensus::{BlockImportParams, BlockImport}; /// Maximum duration of single wait call. const MAX_WAIT_TIME: Duration = Duration::from_secs(60 * 3); @@ -276,7 +274,13 @@ impl TestNet where } } -pub fn connectivity(spec: ChainSpec, full_builder: Fb, light_builder: Lb) where +pub fn connectivity( + spec: ChainSpec, + full_builder: Fb, + light_builder: Lb, + light_node_interconnectivity: bool, // should normally be false, unless the light nodes + // aren't actually light. +) where Fb: Fn(Configuration<(), G>) -> Result, F: AbstractService, Lb: Fn(Configuration<(), G>) -> Result, @@ -284,6 +288,14 @@ pub fn connectivity(spec: ChainSpec, full_builder: Fb, light { const NUM_FULL_NODES: usize = 5; const NUM_LIGHT_NODES: usize = 5; + + let expected_full_connections = NUM_FULL_NODES - 1 + NUM_LIGHT_NODES; + let expected_light_connections = if light_node_interconnectivity { + expected_full_connections + } else { + NUM_FULL_NODES + }; + { let temp = TempDir::new("substrate-connectivity-test").expect("Error creating test dir"); let runtime = { @@ -307,11 +319,14 @@ pub fn connectivity(spec: ChainSpec, full_builder: Fb, light service.get().network().add_reserved_peer(first_address.to_string()) .expect("Error adding reserved peer"); } + network.run_until_all_full( - |_index, service| service.get().network().num_connected() == NUM_FULL_NODES - 1 - + NUM_LIGHT_NODES, - |_index, service| service.get().network().num_connected() == NUM_FULL_NODES, + move |_index, service| service.get().network().num_connected() + == expected_full_connections, + move |_index, service| service.get().network().num_connected() + == expected_light_connections, ); + network.runtime }; @@ -350,10 +365,12 @@ pub fn connectivity(spec: ChainSpec, full_builder: Fb, light address = node_id.clone(); } } + network.run_until_all_full( - |_index, service| service.get().network().num_connected() == NUM_FULL_NODES - 1 - + NUM_LIGHT_NODES, - |_index, service| service.get().network().num_connected() == NUM_FULL_NODES, + move |_index, service| service.get().network().num_connected() + == expected_full_connections, + move |_index, service| service.get().network().num_connected() + == expected_light_connections, ); } temp.close().expect("Error removing temp dir"); @@ -364,14 +381,14 @@ pub fn sync( spec: ChainSpec, full_builder: Fb, light_builder: Lb, - mut block_factory: B, + mut make_block_and_import: B, mut extrinsic_factory: E ) where Fb: Fn(Configuration<(), G>) -> Result<(F, U), Error>, F: AbstractService, Lb: Fn(Configuration<(), G>) -> Result, L: AbstractService, - B: FnMut(&F, &U) -> BlockImportParams, + B: FnMut(&F, &mut U), E: FnMut(&F, &U) -> ::Extrinsic, U: Clone + Send + 'static, { @@ -392,15 +409,13 @@ pub fn sync( ); info!("Checking block sync"); let first_address = { - let first_service = &network.full_nodes[0].1; - let first_user_data = &network.full_nodes[0].2; - let mut client = first_service.get().client(); + let &mut (_, ref first_service, ref mut first_user_data, _) = &mut network.full_nodes[0]; for i in 0 .. NUM_BLOCKS { if i % 128 == 0 { - info!("Generating #{}", i); + info!("Generating #{}", i + 1); } - let import_data = block_factory(&first_service.get(), first_user_data); - client.import_block(import_data, HashMap::new()).expect("Error importing test block"); + + make_block_and_import(&first_service.get(), first_user_data); } network.full_nodes[0].3.clone() }; diff --git a/core/sr-io/src/lib.rs b/core/sr-io/src/lib.rs index aee9e23909..06114c02a3 100644 --- a/core/sr-io/src/lib.rs +++ b/core/sr-io/src/lib.rs @@ -26,7 +26,6 @@ #![cfg_attr(feature = "std", doc = "Substrate runtime standard library as compiled when linked with Rust's standard library.")] #![cfg_attr(not(feature = "std"), doc = "Substrate's runtime standard library as compiled without Rust's standard library.")] -use hash_db::Hasher; use rstd::vec::Vec; use primitives::{ diff --git a/core/sr-io/with_std.rs b/core/sr-io/with_std.rs index f93194bb47..919f4a913a 100644 --- a/core/sr-io/with_std.rs +++ b/core/sr-io/with_std.rs @@ -17,6 +17,7 @@ use primitives::{ blake2_128, blake2_256, twox_128, twox_256, twox_64, ed25519, Blake2Hasher, sr25519, Pair, H256, traits::Externalities, child_storage_key::ChildStorageKey, hexdisplay::HexDisplay, offchain, + Hasher, }; // Switch to this after PoC-3 // pub use primitives::BlakeHasher; diff --git a/core/sr-io/without_std.rs b/core/sr-io/without_std.rs index 0ff1702f90..ad5ed77d70 100644 --- a/core/sr-io/without_std.rs +++ b/core/sr-io/without_std.rs @@ -20,7 +20,7 @@ pub use rstd::{mem, slice}; use core::{intrinsics, panic::PanicInfo}; use rstd::{vec::Vec, cell::Cell, convert::TryInto}; -use primitives::{offchain, Blake2Hasher}; +use primitives::offchain; use codec::Decode; #[cfg(not(feature = "no_panic_handler"))] @@ -732,7 +732,7 @@ impl StorageApi for () { } - fn blake2_256_trie_root(input: Vec<(Vec, Vec)>) -> H256 { + fn blake2_256_trie_root(_input: Vec<(Vec, Vec)>) -> H256 { unimplemented!() } diff --git a/core/sr-primitives/src/testing.rs b/core/sr-primitives/src/testing.rs index 198870f8c4..5391735576 100644 --- a/core/sr-primitives/src/testing.rs +++ b/core/sr-primitives/src/testing.rs @@ -25,7 +25,7 @@ use crate::traits::{ }; use crate::{generic, KeyTypeId, ApplyResult}; use crate::weights::{GetDispatchInfo, DispatchInfo}; -pub use primitives::H256; +pub use primitives::{H256, sr25519}; use primitives::{crypto::{CryptoType, Dummy, key_types, Public}, U256}; use crate::transaction_validity::{TransactionValidity, TransactionValidityError}; diff --git a/core/test-runtime/src/lib.rs b/core/test-runtime/src/lib.rs index 815f43c3db..ff9826acae 100644 --- a/core/test-runtime/src/lib.rs +++ b/core/test-runtime/src/lib.rs @@ -619,25 +619,15 @@ cfg_if! { } impl babe_primitives::BabeApi for Runtime { - fn startup_data() -> babe_primitives::BabeConfiguration { + fn configuration() -> babe_primitives::BabeConfiguration { babe_primitives::BabeConfiguration { - median_required_blocks: 0, - slot_duration: 3000, + slot_duration: 1000, + epoch_length: EpochDuration::get(), c: (3, 10), - } - } - - fn epoch() -> babe_primitives::Epoch { - let authorities = system::authorities(); - let authorities: Vec<_> = authorities.into_iter().map(|x|(x, 1)).collect(); - - babe_primitives::Epoch { - start_slot: >::epoch_start_slot(), - authorities, + genesis_authorities: system::authorities() + .into_iter().map(|x|(x, 1)).collect(), randomness: >::randomness(), - epoch_index: >::epoch_index(), - duration: EpochDuration::get(), - secondary_slots: >::secondary_slots().0, + secondary_slots: true, } } } @@ -839,25 +829,15 @@ cfg_if! { } impl babe_primitives::BabeApi for Runtime { - fn startup_data() -> babe_primitives::BabeConfiguration { + fn configuration() -> babe_primitives::BabeConfiguration { babe_primitives::BabeConfiguration { - median_required_blocks: 0, slot_duration: 1000, + epoch_length: EpochDuration::get(), c: (3, 10), - } - } - - fn epoch() -> babe_primitives::Epoch { - let authorities = system::authorities(); - let authorities: Vec<_> = authorities.into_iter().map(|x|(x, 1)).collect(); - - babe_primitives::Epoch { - start_slot: >::epoch_start_slot(), - authorities, + genesis_authorities: system::authorities() + .into_iter().map(|x|(x, 1)).collect(), randomness: >::randomness(), - epoch_index: >::epoch_index(), - duration: EpochDuration::get(), - secondary_slots: >::secondary_slots().0, + secondary_slots: true, } } } diff --git a/core/utils/fork-tree/src/lib.rs b/core/utils/fork-tree/src/lib.rs index 42646b6521..4299918755 100644 --- a/core/utils/fork-tree/src/lib.rs +++ b/core/utils/fork-tree/src/lib.rs @@ -153,6 +153,8 @@ impl ForkTree where /// should return `true` if the second hash (target) is a descendent of the /// first hash (base). This method assumes that nodes in the same branch are /// imported in order. + /// + /// Returns `true` if the imported node is a root. pub fn import( &mut self, mut hash: H, @@ -208,7 +210,7 @@ impl ForkTree where self.node_iter().map(|node| (&node.hash, &node.number, &node.data)) } - /// Find a node in the tree that is the lowest ancestor of the given + /// Find a node in the tree that is the deepest ancestor of the given /// block hash and which passes the given predicate. The given function /// `is_descendent_of` should return `true` if the second hash (target) /// is a descendent of the first hash (base). @@ -228,8 +230,8 @@ impl ForkTree where let node = root.find_node_where(hash, number, is_descendent_of, predicate)?; // found the node, early exit - if let Some(node) = node { - return Ok(node); + if let FindOutcome::Found(node) = node { + return Ok(Some(node)); } } @@ -510,6 +512,17 @@ impl ForkTree where mod node_implementation { use super::*; + /// The outcome of a search within a node. + pub enum FindOutcome { + // this is the node we were looking for. + Found(T), + // not the node we're looking for. contains a flag indicating + // whether the node was a descendent. true implies the predicate failed. + Failure(bool), + // Abort search. + Abort, + } + #[derive(Clone, Debug, Decode, Encode, PartialEq)] pub struct Node { pub hash: H, @@ -560,9 +573,10 @@ mod node_implementation { } } - /// Find a node in the tree that is the lowest ancestor of the given - /// block hash and which passes the given predicate. The given function - /// `is_descendent_of` should return `true` if the second hash (target) + /// Find a node in the tree that is the deepest ancestor of the given + /// block hash which also passes the given predicate, backtracking + /// when the predicate fails. + /// The given function `is_descendent_of` should return `true` if the second hash (target) /// is a descendent of the first hash (base). // FIXME: it would be useful if this returned a mutable reference but // rustc can't deal with lifetimes properly. an option would be to try @@ -573,23 +587,32 @@ mod node_implementation { number: &N, is_descendent_of: &F, predicate: &P, - ) -> Result>>, Error> + ) -> Result>, Error> where E: std::error::Error, F: Fn(&H, &H) -> Result, P: Fn(&V) -> bool, { // stop searching this branch if *number < self.number { - return Ok(None); + return Ok(FindOutcome::Failure(false)); } + let mut known_descendent_of = false; + // continue depth-first search through all children for node in self.children.iter() { - let node = node.find_node_where(hash, number, is_descendent_of, predicate)?; - // found node, early exit - if node.is_some() { - return Ok(node); + match node.find_node_where(hash, number, is_descendent_of, predicate)? { + FindOutcome::Abort => return Ok(FindOutcome::Abort), + FindOutcome::Found(x) => return Ok(FindOutcome::Found(x)), + FindOutcome::Failure(true) => { + // if the block was a descendent of this child, + // then it cannot be a descendent of any others, + // so we don't search them. + known_descendent_of = true; + break; + }, + FindOutcome::Failure(false) => {}, } } @@ -597,24 +620,23 @@ mod node_implementation { // searching for is a descendent of this node then we will stop the // search here, since there aren't any more children and we found // the correct node so we don't want to backtrack. - if is_descendent_of(&self.hash, hash)? { + let is_descendent_of = known_descendent_of || is_descendent_of(&self.hash, hash)?; + if is_descendent_of { // if the predicate passes we return the node if predicate(&self.data) { - Ok(Some(Some(self))) - - // otherwise we stop the search returning `None` - } else { - Ok(Some(None)) + return Ok(FindOutcome::Found(self)); } - } else { - Ok(None) } + + // otherwise, tell our ancestor that we failed, and whether + // the block was a descendent. + Ok(FindOutcome::Failure(is_descendent_of)) } } } // Workaround for: https://github.com/rust-lang/rust/issues/34537 -use node_implementation::Node; +use node_implementation::{Node, FindOutcome}; struct ForkTreeIterator<'a, H, N, V> { stack: Vec<&'a Node>, @@ -1197,7 +1219,7 @@ mod test { } #[test] - fn find_node_doesnt_backtrack_after_finding_highest_descending_node() { + fn find_node_backtracks_after_finding_highest_descending_node() { let mut tree = ForkTree::new(); // @@ -1215,11 +1237,12 @@ mod test { }; tree.import("A", 1, 1, &is_descendent_of).unwrap(); - tree.import("B", 2, 4, &is_descendent_of).unwrap(); + tree.import("B", 2, 2, &is_descendent_of).unwrap(); tree.import("C", 2, 4, &is_descendent_of).unwrap(); - // when searching the tree we reach both node `B` and `C`, but the - // predicate doesn't pass. still, we should not backtrack to node `A`. + // when searching the tree we reach node `C`, but the + // predicate doesn't pass. we should backtrack to `B`, but not to `A`, + // since "B" fulfills the predicate. let node = tree.find_node_where( &"D", &3, @@ -1227,6 +1250,6 @@ mod test { &|data| *data < 3, ).unwrap(); - assert_eq!(node, None); + assert_eq!(node.unwrap().hash, "B"); } } diff --git a/node-template/runtime/src/lib.rs b/node-template/runtime/src/lib.rs index fa4d022d17..f736d9c62d 100644 --- a/node-template/runtime/src/lib.rs +++ b/node-template/runtime/src/lib.rs @@ -374,27 +374,19 @@ impl_runtime_apis! { } impl babe_primitives::BabeApi for Runtime { - fn startup_data() -> babe_primitives::BabeConfiguration { + fn configuration() -> babe_primitives::BabeConfiguration { // The choice of `c` parameter (where `1 - c` represents the // probability of a slot being empty), is done in accordance to the // slot duration and expected target block time, for safely // resisting network delays of maximum two seconds. // babe_primitives::BabeConfiguration { - median_required_blocks: 1000, slot_duration: Babe::slot_duration(), + epoch_length: EpochDuration::get(), c: PRIMARY_PROBABILITY, - } - } - - fn epoch() -> babe_primitives::Epoch { - babe_primitives::Epoch { - start_slot: Babe::epoch_start_slot(), - authorities: Babe::authorities(), - epoch_index: Babe::epoch_index(), + genesis_authorities: Babe::authorities(), randomness: Babe::randomness(), - duration: EpochDuration::get(), - secondary_slots: Babe::secondary_slots().0, + secondary_slots: true, } } } diff --git a/node-template/src/service.rs b/node-template/src/service.rs index f4ab3f4000..c26959d302 100644 --- a/node-template/src/service.rs +++ b/node-template/src/service.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use std::time::Duration; use substrate_client::LongestChain; -use babe::{import_queue, start_babe, Config}; +use babe; use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; use futures::prelude::*; use node_template_runtime::{self, GenesisConfig, opaque::Block, RuntimeApi}; @@ -34,7 +34,6 @@ macro_rules! new_full_start { ($config:expr) => {{ let mut import_setup = None; let inherent_data_providers = inherents::InherentDataProviders::new(); - let mut tasks_to_spawn = None; let builder = substrate_service::ServiceBuilder::new_full::< node_template_runtime::opaque::Block, node_template_runtime::RuntimeApi, crate::service::Executor @@ -45,33 +44,38 @@ macro_rules! new_full_start { .with_transaction_pool(|config, client| Ok(transaction_pool::txpool::Pool::new(config, transaction_pool::ChainApi::new(client))) )? - .with_import_queue(|_config, client, mut select_chain, transaction_pool| { + .with_import_queue(|_config, client, mut select_chain, _transaction_pool| { let select_chain = select_chain.take() .ok_or_else(|| substrate_service::Error::SelectChainRequired)?; - let (block_import, link_half) = + let (grandpa_block_import, grandpa_link) = grandpa::block_import::<_, _, _, node_template_runtime::RuntimeApi, _, _>( client.clone(), client.clone(), select_chain )?; - let justification_import = block_import.clone(); + let justification_import = grandpa_block_import.clone(); - let (import_queue, babe_link, babe_block_import, pruning_task) = babe::import_queue( + let (babe_block_import, babe_link) = babe::block_import( babe::Config::get_or_compute(&*client)?, - block_import, + grandpa_block_import, + client.clone(), + client.clone(), + )?; + + let import_queue = babe::import_queue( + babe_link.clone(), + babe_block_import.clone(), Some(Box::new(justification_import)), None, client.clone(), client, inherent_data_providers.clone(), - Some(transaction_pool) )?; - import_setup = Some((babe_block_import.clone(), link_half, babe_link)); - tasks_to_spawn = Some(vec![Box::new(pruning_task)]); + import_setup = Some((babe_block_import, grandpa_link, babe_link)); Ok(import_queue) })?; - (builder, import_setup, inherent_data_providers, tasks_to_spawn) + (builder, import_setup, inherent_data_providers) }} } @@ -85,7 +89,7 @@ pub fn new_full(config: Configuration(config: Configuration(config: Configuration(config: Configuration(config: Configuration(config: Configuration( + let grandpa_block_import = grandpa::light_block_import::<_, _, _, RuntimeApi, _>( client.clone(), backend, Arc::new(fetch_checker), client.clone() )?; - let finality_proof_import = block_import.clone(); + let finality_proof_import = grandpa_block_import.clone(); let finality_proof_request_builder = finality_proof_import.create_finality_proof_request_builder(); - // FIXME: pruning task isn't started since light client doesn't do `AuthoritySetup`. - let (import_queue, ..) = import_queue( - Config::get_or_compute(&*client)?, - block_import, + let (babe_block_import, babe_link) = babe::block_import( + babe::Config::get_or_compute(&*client)?, + grandpa_block_import, + client.clone(), + client.clone(), + )?; + + let import_queue = babe::import_queue( + babe_link.clone(), + babe_block_import, None, Some(Box::new(finality_proof_import)), client.clone(), client, inherent_data_providers.clone(), - Some(transaction_pool) )?; Ok((import_queue, finality_proof_request_builder)) diff --git a/node/cli/src/chain_spec.rs b/node/cli/src/chain_spec.rs index 00bcb25776..47de737614 100644 --- a/node/cli/src/chain_spec.rs +++ b/node/cli/src/chain_spec.rs @@ -350,7 +350,8 @@ pub fn local_testnet_config() -> ChainSpec { #[cfg(test)] pub(crate) mod tests { use super::*; - use crate::service::{new_full, new_light}; + use crate::service::new_full; + use substrate_service::Roles; use service_test; fn local_testnet_genesis_instant_single() -> GenesisConfig { @@ -398,7 +399,12 @@ pub(crate) mod tests { service_test::connectivity( integration_test_config_with_two_authorities(), |config| new_full(config), - |config| new_light(config), + |mut config| { + // light nodes are unsupported + config.roles = Roles::FULL; + new_full(config) + }, + true, ); } } diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index b1d1348069..06c88f3d58 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -20,7 +20,7 @@ use std::sync::Arc; -use babe::{import_queue, Config}; +use babe; use client::{self, LongestChain}; use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; use node_executor; @@ -47,7 +47,6 @@ macro_rules! new_full_start { type RpcExtension = jsonrpc_core::IoHandler; let mut import_setup = None; let inherent_data_providers = inherents::InherentDataProviders::new(); - let mut tasks_to_spawn = Vec::new(); let builder = substrate_service::ServiceBuilder::new_full::< node_primitives::Block, node_runtime::RuntimeApi, node_executor::Executor @@ -58,36 +57,40 @@ macro_rules! new_full_start { .with_transaction_pool(|config, client| Ok(transaction_pool::txpool::Pool::new(config, transaction_pool::ChainApi::new(client))) )? - .with_import_queue(|_config, client, mut select_chain, transaction_pool| { + .with_import_queue(|_config, client, mut select_chain, _transaction_pool| { let select_chain = select_chain.take() .ok_or_else(|| substrate_service::Error::SelectChainRequired)?; - let (block_import, link_half) = + let (grandpa_block_import, grandpa_link) = grandpa::block_import::<_, _, _, node_runtime::RuntimeApi, _, _>( client.clone(), client.clone(), select_chain )?; - let justification_import = block_import.clone(); + let justification_import = grandpa_block_import.clone(); - let (import_queue, babe_link, babe_block_import, pruning_task) = babe::import_queue( + let (block_import, babe_link) = babe::block_import( babe::Config::get_or_compute(&*client)?, - block_import, + grandpa_block_import, + client.clone(), + client.clone(), + )?; + + let import_queue = babe::import_queue( + babe_link.clone(), + block_import.clone(), Some(Box::new(justification_import)), None, client.clone(), client, inherent_data_providers.clone(), - Some(transaction_pool) )?; - import_setup = Some((babe_block_import.clone(), link_half, babe_link)); - tasks_to_spawn.push(Box::new(pruning_task)); - + import_setup = Some((block_import, grandpa_link, babe_link)); Ok(import_queue) })? .with_rpc_extensions(|client, pool| -> RpcExtension { node_rpc::create(client, pool) })?; - (builder, import_setup, inherent_data_providers, tasks_to_spawn) + (builder, import_setup, inherent_data_providers) }} } @@ -96,7 +99,7 @@ macro_rules! new_full_start { /// We need to use a macro because the test suit doesn't work with an opaque service. It expects /// concrete types instead. macro_rules! new_full { - ($config:expr) => {{ + ($config:expr, $with_startup_data: expr) => {{ use futures::sync::mpsc; use network::DhtEvent; @@ -112,7 +115,7 @@ macro_rules! new_full { $config.disable_grandpa ); - let (builder, mut import_setup, inherent_data_providers, tasks_to_spawn) = new_full_start!($config); + let (builder, mut import_setup, inherent_data_providers) = new_full_start!($config); // Dht event channel from the network to the authority discovery module. Use bounded channel to ensure // back-pressure. Authority discovery is triggering one event per authority within the current authority set. @@ -128,11 +131,10 @@ macro_rules! new_full { .with_dht_event_tx(dht_event_tx)? .build()?; - let (block_import, link_half, babe_link) = import_setup.take() + let (block_import, grandpa_link, babe_link) = import_setup.take() .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); - // spawn any futures that were created in the previous setup steps - tasks_to_spawn.into_iter().for_each(|t| service.spawn_task(t)); + ($with_startup_data)(&block_import, &babe_link); if is_authority { let proposer = substrate_basic_authorship::ProposerFactory { @@ -145,16 +147,15 @@ macro_rules! new_full { .ok_or(substrate_service::Error::SelectChainRequired)?; let babe_config = babe::BabeParams { - config: babe::Config::get_or_compute(&*client)?, keystore: service.keystore(), client, select_chain, - block_import, env: proposer, + block_import, sync_oracle: service.network(), inherent_data_providers: inherent_data_providers.clone(), - force_authoring: force_authoring, - time_source: babe_link, + force_authoring, + babe_link, }; let babe = babe::start_babe(babe_config)?; @@ -181,7 +182,7 @@ macro_rules! new_full { // start the lightweight GRANDPA observer service.spawn_task(Box::new(grandpa::run_grandpa_observer( config, - link_half, + grandpa_link, service.network(), service.on_exit(), )?)); @@ -190,7 +191,7 @@ macro_rules! new_full { // start the full GRANDPA voter let grandpa_config = grandpa::GrandpaParams { config: config, - link: link_half, + link: grandpa_link, network: service.network(), inherent_data_providers: inherent_data_providers.clone(), on_exit: service.on_exit(), @@ -208,6 +209,9 @@ macro_rules! new_full { } Ok((service, inherent_data_providers)) + }}; + ($config:expr) => {{ + new_full!($config, |_, _| {}) }} } @@ -220,11 +224,8 @@ pub fn new_full(config: Configuration(config: Configuration) -> Result { - use futures::Future; - type RpcExtension = jsonrpc_core::IoHandler; let inherent_data_providers = InherentDataProviders::new(); - let mut tasks_to_spawn = Vec::new(); let service = ServiceBuilder::new_light::(config)? .with_select_chain(|_config, backend| { @@ -233,31 +234,35 @@ pub fn new_light(config: Configuration( + let grandpa_block_import = grandpa::light_block_import::<_, _, _, RuntimeApi, _>( client.clone(), backend, Arc::new(fetch_checker), client.clone() )?; - let finality_proof_import = block_import.clone(); + let finality_proof_import = grandpa_block_import.clone(); let finality_proof_request_builder = finality_proof_import.create_finality_proof_request_builder(); - let (import_queue, _, _, pruning_task) = import_queue( - Config::get_or_compute(&*client)?, - block_import, + let (babe_block_import, babe_link) = babe::block_import( + babe::Config::get_or_compute(&*client)?, + grandpa_block_import, + client.clone(), + client.clone(), + )?; + + let import_queue = babe::import_queue( + babe_link, + babe_block_import, None, Some(Box::new(finality_proof_import)), client.clone(), client, inherent_data_providers.clone(), - Some(transaction_pool) )?; - tasks_to_spawn.push(Box::new(pruning_task)); - Ok((import_queue, finality_proof_request_builder)) })? .with_network_protocol(|_| Ok(NodeProtocol::new()))? @@ -269,15 +274,6 @@ pub fn new_light(config: Configuration, + babe_link: &babe::BabeLink, + | { + setup_handles = Some((block_import.clone(), babe_link.clone())); + }).map(move |(node, x)| (node, (x, setup_handles.unwrap()))) + }, + |mut config| { + // light nodes are unsupported + config.roles = Roles::FULL; + new_full(config) + }, + |service, &mut (ref inherent_data_providers, (ref mut block_import, ref babe_link))| { let mut inherent_data = inherent_data_providers .create_inherent_data() .expect("Creates inherent data."); @@ -411,8 +427,8 @@ mod tests { slot_num, &parent_header, &*service.client(), - PRIMARY_PROBABILITY, &keystore, + &babe_link, ) { break babe_pre_digest; } @@ -440,7 +456,7 @@ mod tests { ); slot_num += 1; - BlockImportParams { + let params = BlockImportParams { origin: BlockOrigin::File, header: new_header, justification: None, @@ -449,7 +465,10 @@ mod tests { finalized: true, auxiliary: Vec::new(), fork_choice: ForkChoiceStrategy::LongestChain, - } + }; + + block_import.import_block(params, Default::default()) + .expect("error importing test block"); }, |service, _| { let amount = 5 * CENTS; @@ -506,7 +525,11 @@ mod tests { service_test::consensus( crate::chain_spec::tests::integration_test_config_with_two_authorities(), |config| new_full(config), - |config| new_light(config), + |mut config| { + // light nodes are unsupported + config.roles = Roles::FULL; + new_full(config) + }, vec![ "//Alice".into(), "//Bob".into(), diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 23f4d3845a..642040f9bb 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -29,7 +29,7 @@ use node_primitives::{ AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, Moment, Signature, ContractExecResult, }; -use babe::{AuthorityId as BabeId}; +use babe_primitives::{AuthorityId as BabeId}; use grandpa::fg_primitives::{self, ScheduledChange}; use client::{ block_builder::api::{self as block_builder_api, InherentData, CheckInherentsResult}, @@ -84,8 +84,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 161, - impl_version: 161, + spec_version: 162, + impl_version: 162, apis: RUNTIME_API_VERSIONS, }; @@ -223,7 +223,7 @@ impl session::Trait for Runtime { type ShouldEndSession = Babe; type Event = Event; type Keys = SessionKeys; - type ValidatorId = AccountId; + type ValidatorId = ::AccountId; type ValidatorIdOf = staking::StashOf; type SelectInitialValidators = Staking; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; @@ -614,27 +614,19 @@ impl_runtime_apis! { } impl babe_primitives::BabeApi for Runtime { - fn startup_data() -> babe_primitives::BabeConfiguration { + fn configuration() -> babe_primitives::BabeConfiguration { // The choice of `c` parameter (where `1 - c` represents the // probability of a slot being empty), is done in accordance to the // slot duration and expected target block time, for safely // resisting network delays of maximum two seconds. // babe_primitives::BabeConfiguration { - median_required_blocks: 1000, slot_duration: Babe::slot_duration(), + epoch_length: EpochDuration::get(), c: PRIMARY_PROBABILITY, - } - } - - fn epoch() -> babe_primitives::Epoch { - babe_primitives::Epoch { - start_slot: Babe::epoch_start_slot(), - authorities: Babe::authorities(), - epoch_index: Babe::epoch_index(), + genesis_authorities: Babe::authorities(), randomness: Babe::randomness(), - duration: EpochDuration::get(), - secondary_slots: Babe::secondary_slots().0, + secondary_slots: true, } } } diff --git a/srml/babe/Cargo.toml b/srml/babe/Cargo.toml index 3819bb14c7..1cce838685 100644 --- a/srml/babe/Cargo.toml +++ b/srml/babe/Cargo.toml @@ -22,7 +22,9 @@ runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = f [dev-dependencies] lazy_static = "1.3.0" parking_lot = "0.9.0" +sr-version = { path = "../../core/sr-version", default-features = false } primitives = { package = "substrate-primitives", path = "../../core/primitives" } +test-runtime = { package = "substrate-test-runtime", path = "../../core/test-runtime" } [features] default = ["std"] diff --git a/srml/babe/src/lib.rs b/srml/babe/src/lib.rs index 17c405dc25..a08ccd1888 100644 --- a/srml/babe/src/lib.rs +++ b/srml/babe/src/lib.rs @@ -18,32 +18,36 @@ //! from VRF outputs and manages epoch transitions. #![cfg_attr(not(feature = "std"), no_std)] -#![forbid(unused_must_use, unsafe_code, unused_variables)] - -// TODO: @marcio uncomment this when BabeEquivocation is integrated. -// #![forbid(dead_code)] - +#![forbid(unused_must_use, unsafe_code, unused_variables, unused_must_use)] +#![deny(unused_imports)] pub use timestamp; use rstd::{result, prelude::*}; use support::{decl_storage, decl_module, StorageValue, StorageMap, traits::FindAuthor, traits::Get}; -use timestamp::{OnTimestampSet}; +use timestamp::OnTimestampSet; use sr_primitives::{generic::DigestItem, ConsensusEngineId, Perbill}; use sr_primitives::traits::{IsMember, SaturatedConversion, Saturating, RandomnessBeacon}; use sr_staking_primitives::{ SessionIndex, offence::{Offence, Kind}, }; -use sr_primitives::weights::SimpleDispatchInfo; #[cfg(feature = "std")] use timestamp::TimestampInherentData; use codec::{Encode, Decode}; use inherents::{RuntimeString, InherentIdentifier, InherentData, ProvideInherent, MakeFatalError}; #[cfg(feature = "std")] use inherents::{InherentDataProviders, ProvideInherentData}; -use babe_primitives::{BABE_ENGINE_ID, ConsensusLog, BabeAuthorityWeight, Epoch, RawBabePreDigest}; +use babe_primitives::{ + BABE_ENGINE_ID, ConsensusLog, BabeAuthorityWeight, NextEpochDescriptor, RawBabePreDigest, + SlotNumber, +}; pub use babe_primitives::{AuthorityId, VRF_OUTPUT_LENGTH, PUBLIC_KEY_LENGTH}; -use system::ensure_root; + +#[cfg(all(feature = "std", test))] +mod tests; + +#[cfg(all(feature = "std", test))] +mod mock; /// The BABE inherent identifier. pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"babeslot"; @@ -118,7 +122,7 @@ impl ProvideInherentData for InherentDataProvider { } pub trait Trait: timestamp::Trait { - type EpochDuration: Get; + type EpochDuration: Get; type ExpectedBlockTime: Get; } @@ -127,6 +131,8 @@ pub const RANDOMNESS_LENGTH: usize = 32; const UNDER_CONSTRUCTION_SEGMENT_LENGTH: usize = 256; +type MaybeVrf = Option<[u8; 32 /* VRF_OUTPUT_LENGTH */]>; + decl_storage! { trait Store for Module as Babe { /// Current epoch index. @@ -135,22 +141,13 @@ decl_storage! { /// Current epoch authorities. pub Authorities get(authorities): Vec<(AuthorityId, BabeAuthorityWeight)>; - /// Slot at which the current epoch started. It is possible that no - /// block was authored at the given slot and the epoch change was - /// signalled later than this. - pub EpochStartSlot get(epoch_start_slot): u64; + /// The slot at which the first epoch actually started. This is 0 + /// until the first block of the chain. + pub GenesisSlot get(genesis_slot): u64; /// Current slot number. pub CurrentSlot get(current_slot): u64; - /// Whether secondary slots are enabled in case the VRF-based slot is - /// empty for the current epoch and the next epoch, respectively. - pub SecondarySlots get(secondary_slots): (bool, bool) = (true, true); - - /// Pending change to enable/disable secondary slots which will be - /// triggered at `current_epoch + 2`. - pub PendingSecondarySlotsChange get(pending_secondary_slots_change): Option = None; - /// The epoch randomness for the *current* epoch. /// /// # Security @@ -181,9 +178,9 @@ decl_storage! { SegmentIndex build(|_| 0): u32; UnderConstruction: map u32 => Vec<[u8; 32 /* VRF_OUTPUT_LENGTH */]>; - /// Temporary value (cleared at block finalization) which is true + /// Temporary value (cleared at block finalization) which is `Some` /// if per-block initialization has already been called for current block. - Initialized get(initialized): Option; + Initialized get(initialized): Option; } add_extra_genesis { config(authorities): Vec<(AuthorityId, BabeAuthorityWeight)>; @@ -212,20 +209,13 @@ decl_module! { /// Block finalization fn on_finalize() { - Initialized::kill(); - } - - /// Sets a pending change to enable / disable secondary slot assignment. - /// The pending change will be set at the end of the current epoch and - /// will be enacted at `current_epoch + 2`. - #[weight = SimpleDispatchInfo::FixedOperational(10_000)] - fn set_pending_secondary_slots_change(origin, change: Option) { - ensure_root(origin)?; - match change { - Some(change) => PendingSecondarySlotsChange::put(change), - None => { - PendingSecondarySlotsChange::take(); - }, + // at the end of the block, we can safely include the new VRF output + // from this block into the under-construction randomness. If we've determined + // that this block was the first in a new epoch, the changeover logic has + // already occurred at this point, so the under-construction randomness + // will only contain outputs from the right epoch. + if let Some(Some(vrf_output)) = Initialized::take() { + Self::deposit_vrf_output(&vrf_output); } } } @@ -269,15 +259,25 @@ impl IsMember for Module { } impl session::ShouldEndSession for Module { - fn should_end_session(_: T::BlockNumber) -> bool { + fn should_end_session(now: T::BlockNumber) -> bool { // it might be (and it is in current implementation) that session module is calling // should_end_session() from it's own on_initialize() handler // => because session on_initialize() is called earlier than ours, let's ensure // that we have synced with digest before checking if session should be ended Self::do_initialize(); - let diff = CurrentSlot::get().saturating_sub(EpochStartSlot::get()); - diff >= T::EpochDuration::get() + // The session has technically ended during the passage of time + // between this block and the last, but we have to "end" the session now, + // since there is no earlier possible block we could have done it. + // + // The exception is for block 1: the genesis has slot 0, so we treat + // epoch 0 as having started at the slot of block 1. We want to use + // the same randomness and validator set as signalled in the genesis, + // so we don't rotate the session. + now != sr_primitives::traits::One::one() && { + let diff = CurrentSlot::get().saturating_sub(Self::current_epoch_start()); + diff >= T::EpochDuration::get() + } } } @@ -336,15 +336,18 @@ impl Module { ::MinimumPeriod::get().saturating_mul(2.into()) } + // finds the start slot of the current epoch. only guaranteed to + // give correct results after `do_initialize` of the first block + // in the chain (as its result is based off of `GenesisSlot`). + fn current_epoch_start() -> SlotNumber { + (EpochIndex::get() * T::EpochDuration::get()) + GenesisSlot::get() + } + fn deposit_consensus(new: U) { let log: DigestItem = DigestItem::Consensus(BABE_ENGINE_ID, new.encode()); >::deposit_log(log.into()) } - fn get_inherent_digests() -> system::DigestOf { - >::digest() - } - fn deposit_vrf_output(vrf_output: &[u8; VRF_OUTPUT_LENGTH]) { let segment_idx = ::get(); let mut segment = ::get(&segment_idx); @@ -363,13 +366,12 @@ impl Module { fn do_initialize() { // since do_initialize can be called twice (if session module is present) // => let's ensure that we only modify the storage once per block - let initialized = Self::initialized().unwrap_or(false); + let initialized = Self::initialized().is_some(); if initialized { return; } - Initialized::put(true); - for digest in Self::get_inherent_digests() + let maybe_pre_digest = >::digest() .logs .iter() .filter_map(|s| s.as_pre_runtime()) @@ -378,19 +380,40 @@ impl Module { } else { None }) - { - if EpochStartSlot::get() == 0 { - EpochStartSlot::put(digest.slot_number()); + .next(); + + let maybe_vrf = maybe_pre_digest.and_then(|digest| { + // on the first non-zero block (i.e. block #1) + // this is where the first epoch (epoch #0) actually starts. + // we need to adjust internal storage accordingly. + if GenesisSlot::get() == 0 { + GenesisSlot::put(digest.slot_number()); + debug_assert_ne!(GenesisSlot::get(), 0); + + // deposit a log because this is the first block in epoch #0 + // we use the same values as genesis because we haven't collected any + // randomness yet. + let next = NextEpochDescriptor { + authorities: Self::authorities(), + randomness: Self::randomness(), + }; + + Self::deposit_consensus(ConsensusLog::NextEpochData(next)) } CurrentSlot::put(digest.slot_number()); if let RawBabePreDigest::Primary { vrf_output, .. } = digest { - Self::deposit_vrf_output(&vrf_output); + // place the VRF output into the `Initialized` storage item + // and it'll be put onto the under-construction randomness + // later, once we've decided which epoch this block is in. + Some(vrf_output) + } else { + None } + }); - return; - } + Initialized::put(maybe_vrf); } /// Call this function exactly once when an epoch changes, to update the @@ -437,7 +460,12 @@ impl session::OneSessionHandler for Module { fn on_new_session<'a, I: 'a>(_changed: bool, validators: I, queued_validators: I) where I: Iterator { - Self::do_initialize(); + // PRECONDITION: `should_end_session` has done initialization and is guaranteed + // by the session module to be called before this. + #[cfg(debug_assertions)] + { + assert!(Self::initialized().is_some()) + } // Update epoch index let epoch_index = EpochIndex::get() @@ -453,21 +481,6 @@ impl session::OneSessionHandler for Module { Authorities::put(authorities); - // Update epoch start slot. - let now = CurrentSlot::get(); - EpochStartSlot::mutate(|previous| { - loop { - // on the first epoch we must account for skipping at least one - // whole epoch, in case the first block is authored with a slot - // number far in the past. - if now.saturating_sub(*previous) < T::EpochDuration::get() { - break; - } - - *previous = previous.saturating_add(T::EpochDuration::get()); - } - }); - // Update epoch randomness. let next_epoch_index = epoch_index .checked_add(1) @@ -484,34 +497,11 @@ impl session::OneSessionHandler for Module { (k, 1) }).collect::>(); - let next_epoch_start_slot = EpochStartSlot::get().saturating_add(T::EpochDuration::get()); let next_randomness = NextRandomness::get(); - // Update any pending secondary slots change - let mut secondary_slots = SecondarySlots::get(); - - // change for E + 1 now becomes change at E - secondary_slots.0 = secondary_slots.1; - - if let Some(change) = PendingSecondarySlotsChange::take() { - // if there's a pending change schedule it for E + 1 - secondary_slots.1 = change; - } else { - // otherwise E + 1 will have the same value as E - secondary_slots.1 = secondary_slots.0; - } - - SecondarySlots::mutate(|secondary| { - *secondary = secondary_slots; - }); - - let next = Epoch { - epoch_index: next_epoch_index, - start_slot: next_epoch_start_slot, - duration: T::EpochDuration::get(), + let next = NextEpochDescriptor { authorities: next_authorities, randomness: next_randomness, - secondary_slots: secondary_slots.1, }; Self::deposit_consensus(ConsensusLog::NextEpochData(next)) diff --git a/srml/babe/src/mock.rs b/srml/babe/src/mock.rs new file mode 100644 index 0000000000..741f08fc08 --- /dev/null +++ b/srml/babe/src/mock.rs @@ -0,0 +1,112 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Test utilities +#![allow(dead_code, unused_imports)] + +use super::{Trait, Module, GenesisConfig}; +use babe_primitives::AuthorityId; +use sr_primitives::{ + traits::IdentityLookup, Perbill, + testing::{Header, UintAuthorityId}, + impl_opaque_keys, key_types::DUMMY, +}; +use sr_version::RuntimeVersion; +use support::{impl_outer_origin, parameter_types}; +use runtime_io; +use primitives::{H256, Blake2Hasher}; + +impl_outer_origin!{ + pub enum Origin for Test {} +} + +type DummyValidatorId = u64; + +// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct Test; + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub const MinimumPeriod: u64 = 1; + pub const EpochDuration: u64 = 3; + pub const ExpectedBlockTime: u64 = 1; + pub const Version: RuntimeVersion = test_runtime::VERSION; + pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(16); +} + +impl system::Trait for Test { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = (); + type Hash = H256; + type Version = Version; + type Hashing = sr_primitives::traits::BlakeTwo256; + type AccountId = DummyValidatorId; + type Lookup = IdentityLookup; + type Header = Header; + type WeightMultiplierUpdate = (); + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type AvailableBlockRatio = AvailableBlockRatio; + type MaximumBlockLength = MaximumBlockLength; +} + +impl_opaque_keys! { + pub struct MockSessionKeys { + #[id(DUMMY)] + pub dummy: UintAuthorityId, + } +} + +impl session::Trait for Test { + type Event = (); + type ValidatorId = ::AccountId; + type ShouldEndSession = Babe; + type SessionHandler = (Babe,Babe,); + type OnSessionEnding = (); + type ValidatorIdOf = (); + type SelectInitialValidators = (); + type Keys = MockSessionKeys; + type DisabledValidatorsThreshold = DisabledValidatorsThreshold; +} + +impl timestamp::Trait for Test { + type Moment = u64; + type OnTimestampSet = Babe; + type MinimumPeriod = MinimumPeriod; +} + +impl Trait for Test { + type EpochDuration = EpochDuration; + type ExpectedBlockTime = ExpectedBlockTime; +} + +pub fn new_test_ext(authorities: Vec) -> runtime_io::TestExternalities { + let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + GenesisConfig { + authorities: authorities.into_iter().map(|a| (UintAuthorityId(a).to_public_key(), 1)).collect(), + }.assimilate_storage::(&mut t).unwrap(); + t.into() +} + +pub type System = system::Module; +pub type Babe = Module; diff --git a/srml/babe/src/tests.rs b/srml/babe/src/tests.rs new file mode 100644 index 0000000000..ef449485b7 --- /dev/null +++ b/srml/babe/src/tests.rs @@ -0,0 +1,127 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Consensus extension module tests for BABE consensus. + +use super::*; +use runtime_io::with_externalities; +use mock::{new_test_ext, Babe, Test}; +use sr_primitives::{traits::OnFinalize, testing::{Digest, DigestItem}}; +use session::ShouldEndSession; + +const EMPTY_RANDOMNESS: [u8; 32] = [ + 74, 25, 49, 128, 53, 97, 244, 49, + 222, 202, 176, 2, 231, 66, 95, 10, + 133, 49, 213, 228, 86, 161, 164, 127, + 217, 153, 138, 37, 48, 192, 248, 0, +]; + +fn make_pre_digest( + authority_index: babe_primitives::AuthorityIndex, + slot_number: babe_primitives::SlotNumber, + vrf_output: [u8; babe_primitives::VRF_OUTPUT_LENGTH], + vrf_proof: [u8; babe_primitives::VRF_PROOF_LENGTH], +) -> Digest { + let digest_data = babe_primitives::RawBabePreDigest::Primary { + authority_index, + slot_number, + vrf_output, + vrf_proof, + }; + let log = DigestItem::PreRuntime(babe_primitives::BABE_ENGINE_ID, digest_data.encode()); + Digest { logs: vec![log] } +} + +#[test] +fn empty_randomness_is_correct() { + let s = compute_randomness([0; RANDOMNESS_LENGTH], 0, std::iter::empty(), None); + assert_eq!(s, EMPTY_RANDOMNESS); +} + +#[test] +fn initial_values() { + with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { + assert_eq!(Babe::authorities().len(), 4) + }) +} + +#[test] +fn check_module() { + with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { + assert!(!Babe::should_end_session(0), "Genesis does not change sessions"); + assert!(!Babe::should_end_session(200000), + "BABE does not include the block number in epoch calculations"); + }) +} + +type System = system::Module; + +#[test] +fn first_block_epoch_zero_start() { + with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { + let genesis_slot = 100; + let first_vrf = [1; 32]; + let pre_digest = make_pre_digest( + 0, + genesis_slot, + first_vrf, + [0xff; 64], + ); + + assert_eq!(Babe::genesis_slot(), 0); + System::initialize(&1, &Default::default(), &Default::default(), &pre_digest); + + // see implementation of the function for details why: we issue an + // epoch-change digest but don't do it via the normal session mechanism. + assert!(!Babe::should_end_session(1)); + assert_eq!(Babe::genesis_slot(), genesis_slot); + assert_eq!(Babe::current_slot(), genesis_slot); + assert_eq!(Babe::epoch_index(), 0); + + Babe::on_finalize(1); + let header = System::finalize(); + + assert_eq!(SegmentIndex::get(), 0); + assert_eq!(UnderConstruction::get(0), vec![first_vrf]); + assert_eq!(Babe::randomness(), [0; 32]); + assert_eq!(NextRandomness::get(), [0; 32]); + + assert_eq!(header.digest.logs.len(), 2); + assert_eq!(pre_digest.logs.len(), 1); + assert_eq!(header.digest.logs[0], pre_digest.logs[0]); + + let authorities = Babe::authorities(); + let consensus_log = babe_primitives::ConsensusLog::NextEpochData( + babe_primitives::NextEpochDescriptor { + authorities, + randomness: Babe::randomness(), + } + ); + let consensus_digest = DigestItem::Consensus(BABE_ENGINE_ID, consensus_log.encode()); + + // first epoch descriptor has same info as last. + assert_eq!(header.digest.logs[1], consensus_digest.clone()) + }) +} + +#[test] +fn authority_index() { + with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { + assert_eq!( + Babe::find_author((&[(BABE_ENGINE_ID, &[][..])]).into_iter().cloned()), None, + "Trivially invalid authorities are ignored") + }) +} -- GitLab From 7b1d822446982013fa5b7ad5caff35ca84f8b7d0 Mon Sep 17 00:00:00 2001 From: Jim Posen Date: Mon, 23 Sep 2019 17:38:51 +0200 Subject: [PATCH 124/275] Decouple node-executor structures from wasmi (#3610) * executor: Support non-Wasmi sandbox supervisor environments. * node-executor: Tests don't reference WasmExecutor directly. * executor: Simplify encoding of heap metadata. * executor: Decouple allocator from wasmi::MemoryRef. --- core/executor/src/allocator.rs | 280 ++++++++++++++--------------- core/executor/src/sandbox.rs | 125 +++++++------ core/executor/src/wasm_executor.rs | 56 +++++- node/executor/src/lib.rs | 87 +++++++-- 4 files changed, 324 insertions(+), 224 deletions(-) diff --git a/core/executor/src/allocator.rs b/core/executor/src/allocator.rs index d326b96622..403cf92e20 100644 --- a/core/executor/src/allocator.rs +++ b/core/executor/src/allocator.rs @@ -39,8 +39,7 @@ //! We then check to see if the linked list is empty. If empty, we use //! the bump allocator to get the allocation with an extra 8 bytes //! preceding it. We initialise those preceding 8 bytes to identify the -//! list to which it belongs (e.g. `0x__ffffffffffffff` where `__` is the -//! linked list index). If it is not empty, we unlink the first item from +//! list to which it belongs. If it is not empty, we unlink the first item from //! the linked list and then reset the 8 preceding bytes so they now record //! the identity of the linked list. //! @@ -49,7 +48,8 @@ use crate::error::{Error, Result}; use log::trace; -use wasmi::{MemoryRef, memory_units::Bytes}; +use std::convert::{TryFrom, TryInto}; +use std::ops::Range; use wasm_interface::{Pointer, WordSize}; // The pointers need to be aligned to 8 bytes. This is because the @@ -72,8 +72,6 @@ const PREFIX_SIZE: u32 = 8; pub struct FreeingBumpHeapAllocator { bumper: u32, heads: [u32; N], - heap: MemoryRef, - max_heap_size: u32, ptr_offset: u32, total_size: u32, } @@ -89,26 +87,15 @@ impl FreeingBumpHeapAllocator { /// /// # Arguments /// - /// - `mem` - reference to the linear memory instance on which this allocator operates. /// - `heap_base` - the offset from the beginning of the linear memory where the heap starts. - pub fn new(mem: MemoryRef, heap_base: u32) -> Self { - let current_size: Bytes = mem.current_size().into(); - let current_size = current_size.0 as u32; - - let mut ptr_offset = heap_base; - let padding = ptr_offset % ALIGNMENT; - if padding != 0 { - ptr_offset += ALIGNMENT - padding; - } - - let heap_size = current_size - ptr_offset; + pub fn new(heap_base: u32) -> Self { + // ptr_offset is the next alignment boundary on or after heap_base. + let ptr_offset = (heap_base + ALIGNMENT - 1) / ALIGNMENT * ALIGNMENT; FreeingBumpHeapAllocator { bumper: 0, heads: [0; N], - heap: mem, - max_heap_size: heap_size, - ptr_offset: ptr_offset, + ptr_offset, total_size: 0, } } @@ -118,14 +105,23 @@ impl FreeingBumpHeapAllocator { /// There is no minimum size, but whatever size is passed into /// this function is rounded to the next power of two. If the requested /// size is below 8 bytes it will be rounded up to 8 bytes. - pub fn allocate(&mut self, size: WordSize) -> Result> { + /// + /// # Arguments + /// + /// - `mem` - a slice representing the linear memory on which this allocator operates. + /// - `size` - size in bytes of the allocation request + pub fn allocate(&mut self, mem: &mut [u8], size: WordSize) -> Result> { + let mem_size = u32::try_from(mem.len()) + .expect("size of Wasm linear memory is <2^32"); + let max_heap_size = mem_size - self.ptr_offset; + if size > MAX_POSSIBLE_ALLOCATION { return Err(Error::RequestedAllocationTooLarge); } let size = size.max(MIN_POSSIBLE_ALLOCATION); let item_size = size.next_power_of_two(); - if item_size + PREFIX_SIZE + self.total_size > self.max_heap_size { + if item_size + PREFIX_SIZE + self.total_size > max_heap_size { return Err(Error::AllocatorOutOfSpace); } @@ -135,23 +131,21 @@ impl FreeingBumpHeapAllocator { let item = self.heads[list_index]; let ptr = item + PREFIX_SIZE; assert!( - ptr + item_size <= self.max_heap_size, + ptr + item_size <= max_heap_size, "Pointer is looked up in list of free entries, into which only valid values are inserted; qed" ); - let four_bytes = self.get_heap_4bytes(item)?; - self.heads[list_index] = Self::le_bytes_to_u32(four_bytes); + self.heads[list_index] = self.get_heap_u64(mem, item)? + .try_into() + .map_err(|_| error("read invalid free list pointer"))?; ptr } else { // Nothing to be freed. Bump. - self.bump(item_size)? + PREFIX_SIZE + self.bump(item_size, max_heap_size)? + PREFIX_SIZE }; - // Reset prefix - (1..PREFIX_SIZE).try_for_each(|i| self.set_heap(ptr - i, 255))?; - - self.set_heap(ptr - PREFIX_SIZE, list_index as u8)?; + self.set_heap_u64(mem, ptr - PREFIX_SIZE, list_index as u64)?; self.total_size = self.total_size + item_size + PREFIX_SIZE; trace!(target: "wasm-heap", "Heap size is {} bytes after allocation", self.total_size); @@ -160,23 +154,26 @@ impl FreeingBumpHeapAllocator { } /// Deallocates the space which was allocated for a pointer. - pub fn deallocate(&mut self, ptr: Pointer) -> Result<()> { + /// + /// # Arguments + /// + /// - `mem` - a slice representing the linear memory on which this allocator operates. + /// - `ptr` - pointer to the allocated chunk + pub fn deallocate(&mut self, mem: &mut [u8], ptr: Pointer) -> Result<()> { let ptr = u32::from(ptr) - self.ptr_offset; if ptr < PREFIX_SIZE { return Err(error("Invalid pointer for deallocation")); } - let list_index = usize::from(self.get_heap_byte(ptr - PREFIX_SIZE)?); - (1..PREFIX_SIZE).try_for_each(|i| - self.get_heap_byte(ptr - i).map(|byte| assert!(byte == 255)) - )?; - let tail = self.heads[list_index]; + let list_index: usize = self.get_heap_u64(mem, ptr - PREFIX_SIZE)? + .try_into() + .map_err(|_| error("read invalid list index"))?; + if list_index > self.heads.len() { + return Err(error("read invalid list index")); + } + self.set_heap_u64(mem, ptr - PREFIX_SIZE, self.heads[list_index] as u64)?; self.heads[list_index] = ptr - PREFIX_SIZE; - let mut slice = self.get_heap_4bytes(ptr - PREFIX_SIZE)?; - Self::write_u32_into_le_bytes(tail, &mut slice); - self.set_heap_4bytes(ptr - PREFIX_SIZE, slice)?; - let item_size = Self::get_item_size_from_index(list_index); self.total_size = self.total_size.checked_sub(item_size as u32 + PREFIX_SIZE) .ok_or_else(|| error("Unable to subtract from total heap size without overflow"))?; @@ -190,8 +187,8 @@ impl FreeingBumpHeapAllocator { /// Returns the `bumper` from before the increase. /// Returns an `Error::AllocatorOutOfSpace` if the operation /// would exhaust the heap. - fn bump(&mut self, item_size: u32) -> Result { - if self.bumper + PREFIX_SIZE + item_size > self.max_heap_size { + fn bump(&mut self, item_size: u32, max_heap_size: u32) -> Result { + if self.bumper + PREFIX_SIZE + item_size > max_heap_size { return Err(Error::AllocatorOutOfSpace); } @@ -200,45 +197,48 @@ impl FreeingBumpHeapAllocator { Ok(res) } - fn le_bytes_to_u32(arr: [u8; 4]) -> u32 { - u32::from_le_bytes(arr) - } - - fn write_u32_into_le_bytes(bytes: u32, slice: &mut [u8]) { - slice[..4].copy_from_slice(&bytes.to_le_bytes()); - } - fn get_item_size_from_index(index: usize) -> usize { // we shift 1 by three places, since the first possible item size is 8 1 << 3 << index } - fn get_heap_4bytes(&mut self, ptr: u32) -> Result<[u8; 4]> { - let mut arr = [0u8; 4]; - self.heap.get_into(self.ptr_offset + ptr, &mut arr)?; - Ok(arr) - } - - fn get_heap_byte(&mut self, ptr: u32) -> Result { - let mut arr = [0u8; 1]; - self.heap.get_into(self.ptr_offset + ptr, &mut arr)?; - Ok(arr[0]) + // Read a u64 from the heap in LE form. Used to read heap allocation prefixes. + fn get_heap_u64(&self, heap: &[u8], offset: u32) -> Result { + let range = self.heap_range(offset, 8, heap.len()) + .ok_or_else(|| error("read out of heap bounds"))?; + let bytes = heap[range].try_into() + .expect("[u8] slice of length 8 must be convertible to [u8; 8]"); + Ok(u64::from_le_bytes(bytes)) } - fn set_heap(&mut self, ptr: u32, value: u8) -> Result<()> { - self.heap.set(self.ptr_offset + ptr, &[value]).map_err(Into::into) + // Write a u64 to the heap in LE form. Used to write heap allocation prefixes. + fn set_heap_u64(&self, heap: &mut [u8], offset: u32, val: u64) -> Result<()> { + let range = self.heap_range(offset, 8, heap.len()) + .ok_or_else(|| error("write out of heap bounds"))?; + let bytes = val.to_le_bytes(); + &mut heap[range].copy_from_slice(&bytes[..]); + Ok(()) } - fn set_heap_4bytes(&mut self, ptr: u32, value: [u8; 4]) -> Result<()> { - self.heap.set(self.ptr_offset + ptr, &value).map_err(Into::into) + fn heap_range(&self, offset: u32, length: u32, heap_len: usize) -> Option> { + let start = offset + .checked_add(self.ptr_offset)? + as usize; + let end = offset + .checked_add(self.ptr_offset)? + .checked_add(length)? + as usize; + if end <= heap_len { + Some(start..end) + } else { + None + } } } #[cfg(test)] mod tests { use super::*; - use wasmi::MemoryInstance; - use wasmi::memory_units::*; const PAGE_SIZE: u32 = 65536; @@ -250,11 +250,11 @@ mod tests { #[test] fn should_allocate_properly() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 0); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(0); // when - let ptr = heap.allocate(1).unwrap(); + let ptr = heap.allocate(&mut mem[..], 1).unwrap(); // then // returned pointer must start right after `PREFIX_SIZE` @@ -264,11 +264,11 @@ mod tests { #[test] fn should_always_align_pointers_to_multiples_of_8() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 13); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(13); // when - let ptr = heap.allocate(1).unwrap(); + let ptr = heap.allocate(&mut mem[..], 1).unwrap(); // then // the pointer must start at the next multiple of 8 from 13 @@ -279,13 +279,13 @@ mod tests { #[test] fn should_increment_pointers_properly() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 0); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(0); // when - let ptr1 = heap.allocate(1).unwrap(); - let ptr2 = heap.allocate(9).unwrap(); - let ptr3 = heap.allocate(1).unwrap(); + let ptr1 = heap.allocate(&mut mem[..], 1).unwrap(); + let ptr2 = heap.allocate(&mut mem[..], 9).unwrap(); + let ptr3 = heap.allocate(&mut mem[..], 1).unwrap(); // then // a prefix of 8 bytes is prepended to each pointer @@ -302,18 +302,18 @@ mod tests { #[test] fn should_free_properly() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 0); - let ptr1 = heap.allocate(1).unwrap(); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(0); + let ptr1 = heap.allocate(&mut mem[..], 1).unwrap(); // the prefix of 8 bytes is prepended to the pointer assert_eq!(ptr1, to_pointer(PREFIX_SIZE)); - let ptr2 = heap.allocate(1).unwrap(); + let ptr2 = heap.allocate(&mut mem[..], 1).unwrap(); // the prefix of 8 bytes + the content of ptr 1 is prepended to the pointer assert_eq!(ptr2, to_pointer(24)); // when - heap.deallocate(ptr2).unwrap(); + heap.deallocate(&mut mem[..], ptr2).unwrap(); // then // then the heads table should contain a pointer to the @@ -324,23 +324,23 @@ mod tests { #[test] fn should_deallocate_and_reallocate_properly() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); + let mut mem = [0u8; PAGE_SIZE as usize]; let padded_offset = 16; - let mut heap = FreeingBumpHeapAllocator::new(mem, 13); + let mut heap = FreeingBumpHeapAllocator::new(13); - let ptr1 = heap.allocate(1).unwrap(); + let ptr1 = heap.allocate(&mut mem[..], 1).unwrap(); // the prefix of 8 bytes is prepended to the pointer assert_eq!(ptr1, to_pointer(padded_offset + PREFIX_SIZE)); - let ptr2 = heap.allocate(9).unwrap(); + let ptr2 = heap.allocate(&mut mem[..], 9).unwrap(); // the padded_offset + the previously allocated ptr (8 bytes prefix + // 8 bytes content) + the prefix of 8 bytes which is prepended to the // current pointer assert_eq!(ptr2, to_pointer(padded_offset + 16 + PREFIX_SIZE)); // when - heap.deallocate(ptr2).unwrap(); - let ptr3 = heap.allocate(9).unwrap(); + heap.deallocate(&mut mem[..], ptr2).unwrap(); + let ptr3 = heap.allocate(&mut mem[..], 9).unwrap(); // then // should have re-allocated @@ -351,22 +351,22 @@ mod tests { #[test] fn should_build_linked_list_of_free_areas_properly() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 0); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(0); - let ptr1 = heap.allocate(8).unwrap(); - let ptr2 = heap.allocate(8).unwrap(); - let ptr3 = heap.allocate(8).unwrap(); + let ptr1 = heap.allocate(&mut mem[..], 8).unwrap(); + let ptr2 = heap.allocate(&mut mem[..], 8).unwrap(); + let ptr3 = heap.allocate(&mut mem[..], 8).unwrap(); // when - heap.deallocate(ptr1).unwrap(); - heap.deallocate(ptr2).unwrap(); - heap.deallocate(ptr3).unwrap(); + heap.deallocate(&mut mem[..], ptr1).unwrap(); + heap.deallocate(&mut mem[..], ptr2).unwrap(); + heap.deallocate(&mut mem[..], ptr3).unwrap(); // then assert_eq!(heap.heads[0], u32::from(ptr3) - PREFIX_SIZE); - let ptr4 = heap.allocate(8).unwrap(); + let ptr4 = heap.allocate(&mut mem[..], 8).unwrap(); assert_eq!(ptr4, ptr3); assert_eq!(heap.heads[0], u32::from(ptr2) - PREFIX_SIZE); @@ -375,11 +375,11 @@ mod tests { #[test] fn should_not_allocate_if_too_large() { // given - let mem = MemoryInstance::alloc(Pages(1), Some(Pages(1))).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 13); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(13); // when - let ptr = heap.allocate(PAGE_SIZE - 13); + let ptr = heap.allocate(&mut mem[..], PAGE_SIZE - 13); // then match ptr.unwrap_err() { @@ -391,13 +391,13 @@ mod tests { #[test] fn should_not_allocate_if_full() { // given - let mem = MemoryInstance::alloc(Pages(1), Some(Pages(1))).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 0); - let ptr1 = heap.allocate((PAGE_SIZE / 2) - PREFIX_SIZE).unwrap(); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(0); + let ptr1 = heap.allocate(&mut mem[..], (PAGE_SIZE / 2) - PREFIX_SIZE).unwrap(); assert_eq!(ptr1, to_pointer(PREFIX_SIZE)); // when - let ptr2 = heap.allocate(PAGE_SIZE / 2); + let ptr2 = heap.allocate(&mut mem[..], PAGE_SIZE / 2); // then // there is no room for another half page incl. its 8 byte prefix @@ -410,12 +410,11 @@ mod tests { #[test] fn should_allocate_max_possible_allocation_size() { // given - let pages_needed = (MAX_POSSIBLE_ALLOCATION as usize / PAGE_SIZE as usize) + 1; - let mem = MemoryInstance::alloc(Pages(pages_needed), Some(Pages(pages_needed))).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 0); + let mut mem = vec![0u8; (MAX_POSSIBLE_ALLOCATION + PAGE_SIZE) as usize]; + let mut heap = FreeingBumpHeapAllocator::new(0); // when - let ptr = heap.allocate(MAX_POSSIBLE_ALLOCATION).unwrap(); + let ptr = heap.allocate(&mut mem[..], MAX_POSSIBLE_ALLOCATION).unwrap(); // then assert_eq!(ptr, to_pointer(PREFIX_SIZE)); @@ -424,11 +423,11 @@ mod tests { #[test] fn should_not_allocate_if_requested_size_too_large() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 0); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(0); // when - let ptr = heap.allocate(MAX_POSSIBLE_ALLOCATION + 1); + let ptr = heap.allocate(&mut mem[..], MAX_POSSIBLE_ALLOCATION + 1); // then match ptr.unwrap_err() { @@ -440,19 +439,18 @@ mod tests { #[test] fn should_return_error_when_bumper_greater_than_heap_size() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 0); - heap.max_heap_size = 64; + let mut mem = [0u8; 64]; + let mut heap = FreeingBumpHeapAllocator::new(0); - let ptr1 = heap.allocate(32).unwrap(); + let ptr1 = heap.allocate(&mut mem[..], 32).unwrap(); assert_eq!(ptr1, to_pointer(PREFIX_SIZE)); - heap.deallocate(ptr1).expect("failed freeing ptr1"); + heap.deallocate(&mut mem[..], ptr1).expect("failed freeing ptr1"); assert_eq!(heap.total_size, 0); assert_eq!(heap.bumper, 40); - let ptr2 = heap.allocate(16).unwrap(); + let ptr2 = heap.allocate(&mut mem[..], 16).unwrap(); assert_eq!(ptr2, to_pointer(48)); - heap.deallocate(ptr2).expect("failed freeing ptr2"); + heap.deallocate(&mut mem[..], ptr2).expect("failed freeing ptr2"); assert_eq!(heap.total_size, 0); assert_eq!(heap.bumper, 64); @@ -461,7 +459,7 @@ mod tests { // further allocation which would increment the bumper must fail. // we try to allocate 8 bytes here, which will increment the // bumper since no 8 byte item has been allocated+freed before. - let ptr = heap.allocate(8); + let ptr = heap.allocate(&mut mem[..], 8); // then match ptr.unwrap_err() { @@ -473,12 +471,12 @@ mod tests { #[test] fn should_include_prefixes_in_total_heap_size() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 1); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(1); // when // an item size of 16 must be used then - heap.allocate(9).unwrap(); + heap.allocate(&mut mem[..], 9).unwrap(); // then assert_eq!(heap.total_size, PREFIX_SIZE + 16); @@ -487,13 +485,13 @@ mod tests { #[test] fn should_calculate_total_heap_size_to_zero() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 13); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(13); // when - let ptr = heap.allocate(42).unwrap(); + let ptr = heap.allocate(&mut mem[..], 42).unwrap(); assert_eq!(ptr, to_pointer(16 + PREFIX_SIZE)); - heap.deallocate(ptr).unwrap(); + heap.deallocate(&mut mem[..], ptr).unwrap(); // then assert_eq!(heap.total_size, 0); @@ -502,13 +500,13 @@ mod tests { #[test] fn should_calculate_total_size_of_zero() { // given - let mem = MemoryInstance::alloc(Pages(1), None).unwrap(); - let mut heap = FreeingBumpHeapAllocator::new(mem, 19); + let mut mem = [0u8; PAGE_SIZE as usize]; + let mut heap = FreeingBumpHeapAllocator::new(19); // when for _ in 1..10 { - let ptr = heap.allocate(42).unwrap(); - heap.deallocate(ptr).unwrap(); + let ptr = heap.allocate(&mut mem[..], 42).unwrap(); + heap.deallocate(&mut mem[..], ptr).unwrap(); } // then @@ -516,27 +514,17 @@ mod tests { } #[test] - fn should_write_u32_correctly_into_le() { - // given - let mut heap = vec![0; 5]; - - // when - FreeingBumpHeapAllocator::write_u32_into_le_bytes(1, &mut heap[0..4]); - - // then - assert_eq!(heap, [1, 0, 0, 0, 0]); - } - - #[test] - fn should_write_u32_max_correctly_into_le() { + fn should_read_and_write_u64_correctly() { // given - let mut heap = vec![0; 5]; + let mut mem = [0u8; PAGE_SIZE as usize]; + let heap = FreeingBumpHeapAllocator::new(16); // when - FreeingBumpHeapAllocator::write_u32_into_le_bytes(u32::max_value(), &mut heap[0..4]); + heap.set_heap_u64(&mut mem[..], 40, 4480113).unwrap(); // then - assert_eq!(heap, [255, 255, 255, 255, 0]); + let value = heap.get_heap_u64(&mut mem[..], 40).unwrap(); + assert_eq!(value, 4480113); } #[test] diff --git a/core/executor/src/sandbox.rs b/core/executor/src/sandbox.rs index 2c38499ec8..f09c246679 100644 --- a/core/executor/src/sandbox.rs +++ b/core/executor/src/sandbox.rs @@ -23,7 +23,7 @@ use std::{collections::HashMap, rc::Rc}; use codec::{Decode, Encode}; use primitives::sandbox as sandbox_primitives; use wasmi::{ - Externals, FuncRef, ImportResolver, MemoryInstance, MemoryRef, Module, ModuleInstance, + Externals, ImportResolver, MemoryInstance, MemoryRef, Module, ModuleInstance, ModuleRef, RuntimeArgs, RuntimeValue, Trap, TrapKind, memory_units::Pages, }; use wasm_interface::{Pointer, WordSize}; @@ -33,7 +33,13 @@ use wasm_interface::{Pointer, WordSize}; /// This is a typically an index in the default table of the supervisor, however /// the exact meaning of this index is depends on the implementation of dispatch function. #[derive(Copy, Clone, Debug, PartialEq)] -struct SupervisorFuncIndex(usize); +pub struct SupervisorFuncIndex(usize); + +impl From for usize { + fn from(index: SupervisorFuncIndex) -> Self { + index.0 + } +} /// Index of a function within guest index space. /// @@ -73,7 +79,7 @@ impl ImportResolver for Imports { module_name: &str, field_name: &str, signature: &::wasmi::Signature, - ) -> std::result::Result { + ) -> std::result::Result { let key = ( module_name.as_bytes().to_owned(), field_name.as_bytes().to_owned(), @@ -138,11 +144,14 @@ impl ImportResolver for Imports { /// /// Note that this functions are only called in the `supervisor` context. pub trait SandboxCapabilities { + /// Represents a function reference into the supervisor environment. + type SupervisorFuncRef; + /// Returns a reference to an associated sandbox `Store`. - fn store(&self) -> &Store; + fn store(&self) -> &Store; /// Returns a mutable reference to an associated sandbox `Store`. - fn store_mut(&mut self) -> &mut Store; + fn store_mut(&mut self) -> &mut Store; /// Allocate space of the specified length in the supervisor memory. /// @@ -175,15 +184,37 @@ pub trait SandboxCapabilities { /// /// Returns `Err` if `ptr + len` is out of bounds. fn read_memory(&self, ptr: Pointer, len: WordSize) -> Result>; + + /// Invoke a function in the supervisor environment. + /// + /// This first invokes the dispatch_thunk function, passing in the function index of the + /// desired function to call and serialized arguments. The thunk calls the desired function + /// with the deserialized arguments, then serializes the result into memory and returns + /// reference. The pointer to and length of the result in linear memory is encoded into an i64, + /// with the upper 32 bits representing the pointer and the lower 32 bits representing the + /// length. + /// + /// # Errors + /// + /// Returns `Err` if the dispatch_thunk function has an incorrect signature or traps during + /// execution. + fn invoke( + &mut self, + dispatch_thunk: &Self::SupervisorFuncRef, + invoke_args_ptr: Pointer, + invoke_args_len: WordSize, + state: u32, + func_idx: SupervisorFuncIndex, + ) -> Result; } /// Implementation of [`Externals`] that allows execution of guest module with /// [externals][`Externals`] that might refer functions defined by supervisor. /// /// [`Externals`]: ../../wasmi/trait.Externals.html -pub struct GuestExternals<'a, FE: SandboxCapabilities + Externals + 'a> { +pub struct GuestExternals<'a, FE: SandboxCapabilities + 'a> { supervisor_externals: &'a mut FE, - sandbox_instance: &'a SandboxInstance, + sandbox_instance: &'a SandboxInstance, state: u32, } @@ -205,7 +236,7 @@ fn deserialize_result(serialized_result: &[u8]) -> std::result::Result Externals for GuestExternals<'a, FE> { +impl<'a, FE: SandboxCapabilities + 'a> Externals for GuestExternals<'a, FE> { fn invoke_index( &mut self, index: usize, @@ -214,7 +245,6 @@ impl<'a, FE: SandboxCapabilities + Externals + 'a> Externals for GuestExternals< // Make `index` typesafe again. let index = GuestFuncIndex(index); - let dispatch_thunk = self.sandbox_instance.dispatch_thunk.clone(); let func_idx = self.sandbox_instance .guest_to_supervisor_mapping .func_by_guest_index(index) @@ -237,34 +267,26 @@ impl<'a, FE: SandboxCapabilities + Externals + 'a> Externals for GuestExternals< // Move serialized arguments inside the memory and invoke dispatch thunk and // then free allocated memory. - let invoke_args_ptr = self.supervisor_externals - .allocate(invoke_args_data.len() as u32)?; - self.supervisor_externals - .write_memory(invoke_args_ptr, &invoke_args_data)?; - let result = ::wasmi::FuncInstance::invoke( - &dispatch_thunk, - &[ - RuntimeValue::I32(u32::from(invoke_args_ptr) as i32), - RuntimeValue::I32(invoke_args_data.len() as i32), - RuntimeValue::I32(state as i32), - RuntimeValue::I32(func_idx.0 as i32), - ], - self.supervisor_externals, - ); + let invoke_args_len = invoke_args_data.len() as WordSize; + let invoke_args_ptr = self.supervisor_externals.allocate(invoke_args_len)?; + self.supervisor_externals.write_memory(invoke_args_ptr, &invoke_args_data)?; + let result = self.supervisor_externals.invoke( + &self.sandbox_instance.dispatch_thunk, + invoke_args_ptr, + invoke_args_len, + state, + func_idx, + )?; self.supervisor_externals.deallocate(invoke_args_ptr)?; // dispatch_thunk returns pointer to serialized arguments. - let (serialized_result_val_ptr, serialized_result_val_len) = match result { - // Unpack pointer and len of the serialized result data. - Ok(Some(RuntimeValue::I64(v))) => { - // Cast to u64 to use zero-extension. - let v = v as u64; - let ptr = (v as u64 >> 32) as u32; - let len = (v & 0xFFFFFFFF) as u32; - (Pointer::new(ptr), len) - } - Ok(_) => return Err(trap("Supervisor function returned unexpected result!")), - Err(_) => return Err(trap("Supervisor function trapped!")), + // Unpack pointer and len of the serialized result data. + let (serialized_result_val_ptr, serialized_result_val_len) = { + // Cast to u64 to use zero-extension. + let v = result as u64; + let ptr = (v as u64 >> 32) as u32; + let len = (v & 0xFFFFFFFF) as u32; + (Pointer::new(ptr), len) }; let serialized_result_val = self.supervisor_externals @@ -272,21 +294,18 @@ impl<'a, FE: SandboxCapabilities + Externals + 'a> Externals for GuestExternals< self.supervisor_externals .deallocate(serialized_result_val_ptr)?; - // We do not have to check the signature here, because it's automatically - // checked by wasmi. - deserialize_result(&serialized_result_val) } } fn with_guest_externals( supervisor_externals: &mut FE, - sandbox_instance: &SandboxInstance, + sandbox_instance: &SandboxInstance, state: u32, f: F, ) -> R where - FE: SandboxCapabilities + Externals, + FE: SandboxCapabilities, F: FnOnce(&mut GuestExternals) -> R, { let mut guest_externals = GuestExternals { @@ -308,14 +327,16 @@ where /// it's required to provide supervisor externals: it will be used to execute /// code in the supervisor context. /// +/// This is generic over a supervisor function reference type. +/// /// [`invoke`]: #method.invoke -pub struct SandboxInstance { +pub struct SandboxInstance { instance: ModuleRef, - dispatch_thunk: FuncRef, + dispatch_thunk: FR, guest_to_supervisor_mapping: GuestToSupervisorFunctionMapping, } -impl SandboxInstance { +impl SandboxInstance { /// Invoke an exported function by a name. /// /// `supervisor_externals` is required to execute the implementations @@ -323,7 +344,7 @@ impl SandboxInstance { /// /// The `state` parameter can be used to provide custom data for /// these syscall implementations. - pub fn invoke( + pub fn invoke>( &self, export_name: &str, args: &[RuntimeValue], @@ -412,9 +433,9 @@ fn decode_environment_definition( /// - Module in `wasm` is invalid or couldn't be instantiated. /// /// [`EnvironmentDefinition`]: ../../sandbox/struct.EnvironmentDefinition.html -pub fn instantiate( +pub fn instantiate( supervisor_externals: &mut FE, - dispatch_thunk: FuncRef, + dispatch_thunk: FE::SupervisorFuncRef, wasm: &[u8], raw_env_def: &[u8], state: u32, @@ -453,15 +474,17 @@ pub fn instantiate( } /// This struct keeps track of all sandboxed components. -pub struct Store { +/// +/// This is generic over a supervisor function reference type. +pub struct Store { // Memories and instances are `Some` untill torndown. - instances: Vec>>, + instances: Vec>>>, memories: Vec>, } -impl Store { +impl Store { /// Create a new empty sandbox store. - pub fn new() -> Store { + pub fn new() -> Self { Store { instances: Vec::new(), memories: Vec::new(), @@ -497,7 +520,7 @@ impl Store { /// /// Returns `Err` If `instance_idx` isn't a valid index of an instance or /// instance is already torndown. - pub fn instance(&self, instance_idx: u32) -> Result> { + pub fn instance(&self, instance_idx: u32) -> Result>> { self.instances .get(instance_idx as usize) .cloned() @@ -553,7 +576,7 @@ impl Store { } } - fn register_sandbox_instance(&mut self, sandbox_instance: Rc) -> u32 { + fn register_sandbox_instance(&mut self, sandbox_instance: Rc>) -> u32 { let instance_idx = self.instances.len(); self.instances.push(Some(sandbox_instance)); instance_idx as u32 diff --git a/core/executor/src/wasm_executor.rs b/core/executor/src/wasm_executor.rs index cc7d5d9344..9f8d678d1a 100644 --- a/core/executor/src/wasm_executor.rs +++ b/core/executor/src/wasm_executor.rs @@ -54,7 +54,7 @@ macro_rules! debug_trace { } struct FunctionExecutor { - sandbox_store: sandbox::Store, + sandbox_store: sandbox::Store, heap: allocator::FreeingBumpHeapAllocator, memory: MemoryRef, table: Option, @@ -64,7 +64,7 @@ impl FunctionExecutor { fn new(m: MemoryRef, heap_base: u32, t: Option) -> Result { Ok(FunctionExecutor { sandbox_store: sandbox::Store::new(), - heap: allocator::FreeingBumpHeapAllocator::new(m.clone(), heap_base), + heap: allocator::FreeingBumpHeapAllocator::new(heap_base), memory: m, table: t, }) @@ -72,17 +72,25 @@ impl FunctionExecutor { } impl sandbox::SandboxCapabilities for FunctionExecutor { - fn store(&self) -> &sandbox::Store { + type SupervisorFuncRef = wasmi::FuncRef; + + fn store(&self) -> &sandbox::Store { &self.sandbox_store } - fn store_mut(&mut self) -> &mut sandbox::Store { + fn store_mut(&mut self) -> &mut sandbox::Store { &mut self.sandbox_store } fn allocate(&mut self, len: WordSize) -> Result> { - self.heap.allocate(len) + let heap = &mut self.heap; + self.memory.with_direct_access_mut(|mem| { + heap.allocate(mem, len) + }) } fn deallocate(&mut self, ptr: Pointer) -> Result<()> { - self.heap.deallocate(ptr) + let heap = &mut self.heap; + self.memory.with_direct_access_mut(|mem| { + heap.deallocate(mem, ptr) + }) } fn write_memory(&mut self, ptr: Pointer, data: &[u8]) -> Result<()> { self.memory.set(ptr.into(), data).map_err(Into::into) @@ -90,6 +98,32 @@ impl sandbox::SandboxCapabilities for FunctionExecutor { fn read_memory(&self, ptr: Pointer, len: WordSize) -> Result> { self.memory.get(ptr.into(), len as usize).map_err(Into::into) } + + fn invoke( + &mut self, + dispatch_thunk: &Self::SupervisorFuncRef, + invoke_args_ptr: Pointer, + invoke_args_len: WordSize, + state: u32, + func_idx: sandbox::SupervisorFuncIndex, + ) -> Result + { + let result = wasmi::FuncInstance::invoke( + dispatch_thunk, + &[ + RuntimeValue::I32(u32::from(invoke_args_ptr) as i32), + RuntimeValue::I32(invoke_args_len as i32), + RuntimeValue::I32(state as i32), + RuntimeValue::I32(usize::from(func_idx) as i32), + ], + self, + ); + match result { + Ok(Some(RuntimeValue::I64(val))) => Ok(val), + Ok(_) => return Err("Supervisor function returned unexpected result!".into()), + Err(err) => Err(Error::Trap(err)), + } + } } impl FunctionContext for FunctionExecutor { @@ -102,11 +136,17 @@ impl FunctionContext for FunctionExecutor { } fn allocate_memory(&mut self, size: WordSize) -> WResult> { - self.heap.allocate(size).map_err(|e| format!("{:?}", e)) + let heap = &mut self.heap; + self.memory.with_direct_access_mut(|mem| { + heap.allocate(mem, size).map_err(|e| format!("{:?}", e)) + }) } fn deallocate_memory(&mut self, ptr: Pointer) -> WResult<()> { - self.heap.deallocate(ptr).map_err(|e| format!("{:?}", e)) + let heap = &mut self.heap; + self.memory.with_direct_access_mut(|mem| { + heap.deallocate(mem, ptr).map_err(|e| format!("{:?}", e)) + }) } fn sandbox(&mut self) -> &mut dyn Sandbox { diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index bcff17683e..6c4fdc5897 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -38,7 +38,6 @@ mod tests { use super::Executor; use {balances, contracts, indices, system, timestamp}; use runtime_io; - use substrate_executor::WasmExecutor; use codec::{Encode, Decode, Joiner}; use runtime_support::{ Hashable, StorageValue, StorageMap, assert_eq_error_rate, traits::Currency, @@ -46,7 +45,7 @@ mod tests { use state_machine::TestExternalities as CoreTestExternalities; use primitives::{ Blake2Hasher, NeverNativeValue, NativeOrEncoded, map, - traits::{CodeExecutor, Externalities}, + traits::{CodeExecutor, Externalities}, storage::well_known_keys, }; use sr_primitives::{ traits::{Header as HeaderT, Hash as HashT, Convert}, ApplyResult, @@ -121,6 +120,10 @@ mod tests { substrate_executor::NativeExecutor::new(None) } + fn set_heap_pages>(ext: &mut E, heap_pages: u64) { + ext.place_storage(well_known_keys::HEAP_PAGES.to_vec(), Some(heap_pages.encode())); + } + #[test] fn panic_execution_with_foreign_code_gives_error() { let mut t = TestExternalities::::new_with_code(BLOATY_CODE, (map![ @@ -529,14 +532,26 @@ mod tests { let (block1, block2) = blocks(); - WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block1.0).unwrap(); + executor().call::<_, NeverNativeValue, fn() -> _>( + &mut t, + "Core_execute_block", + &block1.0, + false, + None, + ).0.unwrap(); runtime_io::with_externalities(&mut t, || { assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); assert_eq!(Balances::total_balance(&bob()), 169 * DOLLARS); }); - WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block2.0).unwrap(); + executor().call::<_, NeverNativeValue, fn() -> _>( + &mut t, + "Core_execute_block", + &block2.0, + false, + None, + ).0.unwrap(); runtime_io::with_externalities(&mut t, || { assert_eq_error_rate!( @@ -692,7 +707,13 @@ mod tests { let mut t = new_test_ext(COMPACT_CODE, false); - WasmExecutor::new().call(&mut t, 8, COMPACT_CODE,"Core_execute_block", &b.0).unwrap(); + executor().call::<_, NeverNativeValue, fn() -> _>( + &mut t, + "Core_execute_block", + &b.0, + false, + None, + ).0.unwrap(); runtime_io::with_externalities(&mut t, || { // Verify that the contract constructor worked well and code of TRANSFER contract is actually deployed. @@ -710,13 +731,15 @@ mod tests { fn wasm_big_block_import_fails() { let mut t = new_test_ext(COMPACT_CODE, false); - let result = WasmExecutor::new().call( + set_heap_pages(&mut t, 4); + + let result = executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, - 4, - COMPACT_CODE, "Core_execute_block", - &block_with_size(42, 0, 120_000).0 - ); + &block_with_size(42, 0, 120_000).0, + false, + None, + ).0; assert!(result.is_err()); // Err(Wasmi(Trap(Trap { kind: Host(AllocatorOutOfSpace) }))) } @@ -761,11 +784,21 @@ mod tests { >::hashed_key_for(0) => vec![0u8; 32] ], map![])); - let r = WasmExecutor::new() - .call(&mut t, 8, COMPACT_CODE, "Core_initialize_block", &vec![].and(&from_block_number(1u32))); + let r = executor().call::<_, NeverNativeValue, fn() -> _>( + &mut t, + "Core_initialize_block", + &vec![].and(&from_block_number(1u32)), + false, + None, + ).0; assert!(r.is_ok()); - let r = WasmExecutor::new() - .call(&mut t, 8, COMPACT_CODE, "BlockBuilder_apply_extrinsic", &vec![].and(&xt())).unwrap(); + let r = executor().call::<_, NeverNativeValue, fn() -> _>( + &mut t, + "BlockBuilder_apply_extrinsic", + &vec![].and(&xt()), + false, + None, + ).0.unwrap().into_encoded(); let r = ApplyResult::decode(&mut &r[..]).unwrap(); assert_eq!(r, Err(InvalidTransaction::Payment.into())); } @@ -783,11 +816,21 @@ mod tests { >::hashed_key_for(0) => vec![0u8; 32] ], map![])); - let r = WasmExecutor::new() - .call(&mut t, 8, COMPACT_CODE, "Core_initialize_block", &vec![].and(&from_block_number(1u32))); + let r = executor().call::<_, NeverNativeValue, fn() -> _>( + &mut t, + "Core_initialize_block", + &vec![].and(&from_block_number(1u32)), + false, + None, + ).0; assert!(r.is_ok()); - let r = WasmExecutor::new() - .call(&mut t, 8, COMPACT_CODE, "BlockBuilder_apply_extrinsic", &vec![].and(&xt())).unwrap(); + let r = executor().call::<_, NeverNativeValue, fn() -> _>( + &mut t, + "BlockBuilder_apply_extrinsic", + &vec![].and(&xt()), + false, + None, + ).0.unwrap().into_encoded(); ApplyResult::decode(&mut &r[..]) .unwrap() .expect("Extrinsic could be applied") @@ -822,7 +865,13 @@ mod tests { let block1 = changes_trie_block(); let mut t = new_test_ext(COMPACT_CODE, true); - WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block1.0).unwrap(); + executor().call::<_, NeverNativeValue, fn() -> _>( + &mut t, + "Core_execute_block", + &block1.0, + false, + None, + ).0.unwrap(); assert!(t.storage_changes_root(GENESIS_HASH.into()).unwrap().is_some()); } -- GitLab From 4b0652f57f78fc216d1c983dc5cdb9120d7235fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Mon, 23 Sep 2019 17:48:09 +0200 Subject: [PATCH 125/275] Send local GRANDPA authority id to telemetry (#3646) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix indentation There is a space between the tabs. * Send local GRANDPA authority id to telemetry * Update core/finality-grandpa/src/lib.rs Co-Authored-By: Bastian Köcher * Generalize authority_id() * Shorten code * Do not send unfinalized authority sets to telemetry `update_authority_set()` is called from, among others, import side. These updates only track a pending change and may or may not happen, hence it's wrong to send this set to telemetry (which would assume that this is the current, finalized authority set). * Send current authority set and local authority id on set change --- core/finality-grandpa/src/aux_schema.rs | 12 ----- core/finality-grandpa/src/lib.rs | 61 +++++++++++++++++++++---- 2 files changed, 51 insertions(+), 22 deletions(-) diff --git a/core/finality-grandpa/src/aux_schema.rs b/core/finality-grandpa/src/aux_schema.rs index 599604c1d3..a2b05a0cd6 100644 --- a/core/finality-grandpa/src/aux_schema.rs +++ b/core/finality-grandpa/src/aux_schema.rs @@ -25,7 +25,6 @@ use fork_tree::ForkTree; use grandpa::round::State as RoundState; use sr_primitives::traits::{Block as BlockT, NumberFor}; use log::{info, warn}; -use substrate_telemetry::{telemetry, CONSENSUS_INFO}; use fg_primitives::{AuthorityId, AuthorityWeight, SetId, RoundNumber}; use crate::authorities::{AuthoritySet, SharedAuthoritySet, PendingChange, DelayKind}; @@ -376,17 +375,6 @@ pub(crate) fn update_authority_set( let encoded_set = set.encode(); if let Some(new_set) = new_set { - telemetry!(CONSENSUS_INFO; "afg.authority_set"; - "hash" => ?new_set.canon_hash, - "number" => ?new_set.canon_number, - "authority_set_id" => ?new_set.set_id, - "authorities" => { - let authorities: Vec = - new_set.authorities.iter().map(|(id, _)| format!("{}", id)).collect(); - format!("{:?}", authorities) - } - ); - // we also overwrite the "last completed round" entry with a blank slate // because from the perspective of the finality gadget, the chain has // reset. diff --git a/core/finality-grandpa/src/lib.rs b/core/finality-grandpa/src/lib.rs index 36af66af22..7f71bfadb3 100644 --- a/core/finality-grandpa/src/lib.rs +++ b/core/finality-grandpa/src/lib.rs @@ -68,7 +68,7 @@ use fg_primitives::{GrandpaApi, AuthorityPair}; use keystore::KeyStorePtr; use inherents::InherentDataProviders; use consensus_common::SelectChain; -use primitives::{H256, Blake2Hasher}; +use primitives::{H256, Blake2Hasher, Pair}; use substrate_telemetry::{telemetry, CONSENSUS_INFO, CONSENSUS_DEBUG, CONSENSUS_WARN}; use serde_json; @@ -523,20 +523,25 @@ pub fn run_grandpa_voter, N, RA, SC, X>( register_finality_tracker_inherent_data_provider(client.clone(), &inherent_data_providers)?; + let conf = config.clone(); let telemetry_task = if let Some(telemetry_on_connect) = telemetry_on_connect { let authorities = persistent_data.authority_set.clone(); let events = telemetry_on_connect .for_each(move |_| { + let curr = authorities.current_authorities(); + let mut auths = curr.voters().into_iter().map(|(p, _)| p); + let maybe_authority_id = authority_id(&mut auths, &conf.keystore) + .unwrap_or(Default::default()); + telemetry!(CONSENSUS_INFO; "afg.authority_set"; - "authority_set_id" => ?authorities.set_id(), - "authorities" => { - let curr = authorities.current_authorities(); - let voters = curr.voters(); - let authorities: Vec = - voters.iter().map(|(id, _)| id.to_string()).collect(); + "authority_id" => maybe_authority_id.to_string(), + "authority_set_id" => ?authorities.set_id(), + "authorities" => { + let authorities: Vec = curr.voters() + .iter().map(|(id, _)| id.to_string()).collect(); serde_json::to_string(&authorities) .expect("authorities is always at least an empty vector; elements are always of type string") - } + } ); Ok(()) }) @@ -632,10 +637,26 @@ where "name" => ?self.env.config.name(), "set_id" => ?self.env.set_id ); + let chain_info = self.env.inner.info(); + + let maybe_authority_id = is_voter(&self.env.voters, &self.env.config.keystore) + .map(|ap| ap.public()) + .unwrap_or(Default::default()); + telemetry!(CONSENSUS_INFO; "afg.authority_set"; + "number" => ?chain_info.chain.finalized_number, + "hash" => ?chain_info.chain.finalized_hash, + "authority_id" => maybe_authority_id.to_string(), + "authority_set_id" => ?self.env.set_id, + "authorities" => { + let authorities: Vec = self.env.voters.voters() + .iter().map(|(id, _)| id.to_string()).collect(); + serde_json::to_string(&authorities) + .expect("authorities is always at least an empty vector; elements are always of type string") + }, + ); + match &*self.env.voter_set_state.read() { VoterSetState::Live { completed_rounds, .. } => { - let chain_info = self.env.inner.info(); - let last_finalized = ( chain_info.chain.finalized_hash, chain_info.chain.finalized_number, @@ -842,3 +863,23 @@ fn is_voter( None => None, } } + +/// Returns the authority id of this node, if available. +fn authority_id<'a, I>( + authorities: &mut I, + keystore: &Option, +) -> Option where + I: Iterator, +{ + match keystore { + Some(keystore) => { + authorities + .find_map(|p| { + keystore.read().key_pair::(&p) + .ok() + .map(|ap| ap.public()) + }) + } + None => None, + } +} -- GitLab From 1f1580032a297d0e3e7a3d603ec068317f2cc948 Mon Sep 17 00:00:00 2001 From: Ashley Date: Tue, 24 Sep 2019 08:37:53 +1200 Subject: [PATCH 126/275] use pdqselect for median_algorithm selection (#3636) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * use pdqselect for median_algorithm selection instead of sorting the whole vec * Make use of pqdselect clearer Co-Authored-By: André Silva * Make use of pqdselect clearer Co-Authored-By: André Silva --- Cargo.lock | 7 +++++++ core/consensus/babe/Cargo.toml | 1 + core/consensus/babe/src/lib.rs | 4 ++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 793f117991..ce82be57b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2939,6 +2939,11 @@ dependencies = [ "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "pdqselect" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "peeking_take_while" version = "0.1.2" @@ -4780,6 +4785,7 @@ dependencies = [ "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pdqselect 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -6779,6 +6785,7 @@ dependencies = [ "checksum paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4a4a1c555c6505821f9d58b8779d0f630a6b7e4e1be24ba718610acf01fa79" "checksum paste-impl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "26e796e623b8b257215f27e6c80a5478856cae305f5b59810ff9acdaa34570e6" "checksum pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" +"checksum pdqselect 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ec91767ecc0a0bbe558ce8c9da33c068066c57ecc8bb8477ef8c1ad3ef77c27" "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" diff --git a/core/consensus/babe/Cargo.toml b/core/consensus/babe/Cargo.toml index 4ab5e27054..a6d1833b29 100644 --- a/core/consensus/babe/Cargo.toml +++ b/core/consensus/babe/Cargo.toml @@ -34,6 +34,7 @@ log = "0.4.6" schnorrkel = { version = "0.8.4", features = ["preaudit_deprecated"] } rand = "0.6.5" merlin = "1.0.3" +pdqselect = "0.1.0" [dev-dependencies] keyring = { package = "substrate-keyring", path = "../../keyring" } diff --git a/core/consensus/babe/src/lib.rs b/core/consensus/babe/src/lib.rs index 58e6c77cc3..b495561213 100644 --- a/core/consensus/babe/src/lib.rs +++ b/core/consensus/babe/src/lib.rs @@ -780,8 +780,8 @@ fn median_algorithm( t + Duration::new(secs, nanos) }).collect(); - // FIXME #2926: use a selection algorithm instead of a full sorting algorithm. - new_list.sort_unstable(); + // Use a partial sort to move the median timestamp to the middle of the list + pdqselect::select(&mut new_list, num_timestamps / 2); let &median = new_list .get(num_timestamps / 2) -- GitLab From 7da9f2eb6cbb732a31a37f9bfb2543d1dc78f298 Mon Sep 17 00:00:00 2001 From: Ashley Date: Tue, 24 Sep 2019 17:31:06 +1200 Subject: [PATCH 127/275] Move `best_containing` from `Client` to `blockchain::Backend` (#3655) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Move best_containing from Client to Backend * Add comma for clearer diffs Co-Authored-By: André Silva --- core/client/src/blockchain.rs | 119 +++++++++++++++++++++++++++++++++ core/client/src/client.rs | 122 ++-------------------------------- 2 files changed, 123 insertions(+), 118 deletions(-) diff --git a/core/client/src/blockchain.rs b/core/client/src/blockchain.rs index a6edb8505a..7cf510faf9 100644 --- a/core/client/src/blockchain.rs +++ b/core/client/src/blockchain.rs @@ -21,6 +21,8 @@ use std::sync::Arc; use sr_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor}; use sr_primitives::generic::BlockId; use sr_primitives::Justification; +use log::warn; +use parking_lot::Mutex; use crate::error::{Error, Result}; @@ -89,6 +91,123 @@ pub trait Backend: HeaderBackend { /// Return hashes of all blocks that are children of the block with `parent_hash`. fn children(&self, parent_hash: Block::Hash) -> Result>; + + /// Get the most recent block hash of the best (longest) chains + /// that contain block with the given `target_hash`. + /// + /// The search space is always limited to blocks which are in the finalized + /// chain or descendents of it. + /// + /// If `maybe_max_block_number` is `Some(max_block_number)` + /// the search is limited to block `numbers <= max_block_number`. + /// in other words as if there were no blocks greater `max_block_number`. + /// Returns `Ok(None)` if `target_hash` is not found in search space. + /// TODO: document time complexity of this, see [#1444](https://github.com/paritytech/substrate/issues/1444) + fn best_containing( + &self, + target_hash: Block::Hash, + maybe_max_number: Option>, + import_lock: &Mutex<()>, + ) -> Result> { + let target_header = { + match self.header(BlockId::Hash(target_hash))? { + Some(x) => x, + // target not in blockchain + None => { return Ok(None); }, + } + }; + + if let Some(max_number) = maybe_max_number { + // target outside search range + if target_header.number() > &max_number { + return Ok(None); + } + } + + let leaves = { + // ensure no blocks are imported during this code block. + // an import could trigger a reorg which could change the canonical chain. + // we depend on the canonical chain staying the same during this code block. + let _import_guard = import_lock.lock(); + + let info = self.info(); + + // this can be `None` if the best chain is shorter than the target header. + let maybe_canon_hash = self.hash(*target_header.number())?; + + if maybe_canon_hash.as_ref() == Some(&target_hash) { + // if a `max_number` is given we try to fetch the block at the + // given depth, if it doesn't exist or `max_number` is not + // provided, we continue to search from all leaves below. + if let Some(max_number) = maybe_max_number { + if let Some(header) = self.hash(max_number)? { + return Ok(Some(header)); + } + } + } else if info.finalized_number >= *target_header.number() { + // header is on a dead fork. + return Ok(None); + } + + self.leaves()? + }; + + // for each chain. longest chain first. shortest last + for leaf_hash in leaves { + // start at the leaf + let mut current_hash = leaf_hash; + + // if search is not restricted then the leaf is the best + let mut best_hash = leaf_hash; + + // go backwards entering the search space + // waiting until we are <= max_number + if let Some(max_number) = maybe_max_number { + loop { + let current_header = self.header(BlockId::Hash(current_hash.clone()))? + .ok_or_else(|| Error::from(format!("failed to get header for hash {}", current_hash)))?; + + if current_header.number() <= &max_number { + best_hash = current_header.hash(); + break; + } + + current_hash = *current_header.parent_hash(); + } + } + + // go backwards through the chain (via parent links) + loop { + // until we find target + if current_hash == target_hash { + return Ok(Some(best_hash)); + } + + let current_header = self.header(BlockId::Hash(current_hash.clone()))? + .ok_or_else(|| Error::from(format!("failed to get header for hash {}", current_hash)))?; + + // stop search in this chain once we go below the target's block number + if current_header.number() < target_header.number() { + break; + } + + current_hash = *current_header.parent_hash(); + } + } + + // header may be on a dead fork -- the only leaves that are considered are + // those which can still be finalized. + // + // FIXME #1558 only issue this warning when not on a dead fork + warn!( + "Block {:?} exists in chain but not found when following all \ + leaves backwards. Number limit = {:?}", + target_hash, + maybe_max_number, + ); + + Ok(None) + } } /// Provides access to the optional cache. diff --git a/core/client/src/client.rs b/core/client/src/client.rs index 5203c72303..32af79a4bf 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -1668,129 +1668,14 @@ where fn best_block_header(&self) -> error::Result<::Header> { let info = self.backend.blockchain().info(); - let best_hash = self.best_containing(info.best_hash, None)? + let import_lock = self.backend.get_import_lock(); + let best_hash = self.backend.blockchain().best_containing(info.best_hash, None, import_lock)? .unwrap_or(info.best_hash); Ok(self.backend.blockchain().header(BlockId::Hash(best_hash))? .expect("given block hash was fetched from block in db; qed")) } - /// Get the most recent block hash of the best (longest) chains - /// that contain block with the given `target_hash`. - /// - /// The search space is always limited to blocks which are in the finalized - /// chain or descendents of it. - /// - /// If `maybe_max_block_number` is `Some(max_block_number)` - /// the search is limited to block `numbers <= max_block_number`. - /// in other words as if there were no blocks greater `max_block_number`. - /// Returns `Ok(None)` if `target_hash` is not found in search space. - /// TODO: document time complexity of this, see [#1444](https://github.com/paritytech/substrate/issues/1444) - fn best_containing( - &self, - target_hash: Block::Hash, - maybe_max_number: Option> - ) -> error::Result> { - let target_header = { - match self.backend.blockchain().header(BlockId::Hash(target_hash))? { - Some(x) => x, - // target not in blockchain - None => { return Ok(None); }, - } - }; - - if let Some(max_number) = maybe_max_number { - // target outside search range - if target_header.number() > &max_number { - return Ok(None); - } - } - - let leaves = { - // ensure no blocks are imported during this code block. - // an import could trigger a reorg which could change the canonical chain. - // we depend on the canonical chain staying the same during this code block. - let _import_lock = self.backend.get_import_lock().lock(); - - let info = self.backend.blockchain().info(); - - // this can be `None` if the best chain is shorter than the target header. - let maybe_canon_hash = self.backend.blockchain().hash(*target_header.number())?; - - if maybe_canon_hash.as_ref() == Some(&target_hash) { - // if a `max_number` is given we try to fetch the block at the - // given depth, if it doesn't exist or `max_number` is not - // provided, we continue to search from all leaves below. - if let Some(max_number) = maybe_max_number { - if let Some(header) = self.backend.blockchain().hash(max_number)? { - return Ok(Some(header)); - } - } - } else if info.finalized_number >= *target_header.number() { - // header is on a dead fork. - return Ok(None); - } - - self.backend.blockchain().leaves()? - }; - - // for each chain. longest chain first. shortest last - for leaf_hash in leaves { - // start at the leaf - let mut current_hash = leaf_hash; - - // if search is not restricted then the leaf is the best - let mut best_hash = leaf_hash; - - // go backwards entering the search space - // waiting until we are <= max_number - if let Some(max_number) = maybe_max_number { - loop { - let current_header = self.backend.blockchain().header(BlockId::Hash(current_hash.clone()))? - .ok_or_else(|| error::Error::from(format!("failed to get header for hash {}", current_hash)))?; - - if current_header.number() <= &max_number { - best_hash = current_header.hash(); - break; - } - - current_hash = *current_header.parent_hash(); - } - } - - // go backwards through the chain (via parent links) - loop { - // until we find target - if current_hash == target_hash { - return Ok(Some(best_hash)); - } - - let current_header = self.backend.blockchain().header(BlockId::Hash(current_hash.clone()))? - .ok_or_else(|| error::Error::from(format!("failed to get header for hash {}", current_hash)))?; - - // stop search in this chain once we go below the target's block number - if current_header.number() < target_header.number() { - break; - } - - current_hash = *current_header.parent_hash(); - } - } - - // header may be on a dead fork -- the only leaves that are considered are - // those which can still be finalized. - // - // FIXME #1558 only issue this warning when not on a dead fork - warn!( - "Block {:?} exists in chain but not found when following all \ - leaves backwards. Number limit = {:?}", - target_hash, - maybe_max_number, - ); - - Ok(None) - } - fn leaves(&self) -> Result::Hash>, error::Error> { self.backend.blockchain().leaves() } @@ -1819,7 +1704,8 @@ where target_hash: Block::Hash, maybe_max_number: Option> ) -> Result, ConsensusError> { - LongestChain::best_containing(self, target_hash, maybe_max_number) + let import_lock = self.backend.get_import_lock(); + self.backend.blockchain().best_containing(target_hash, maybe_max_number, import_lock) .map_err(|e| ConsensusError::ChainLookup(e.to_string()).into()) } } -- GitLab From fdbb64e0aa902526e9ec195af99067dcc85f729e Mon Sep 17 00:00:00 2001 From: Ashley Date: Tue, 24 Sep 2019 20:05:15 +1200 Subject: [PATCH 128/275] Change `decl_storage!` to import the storage traits automatically (#3674) * decl_storage imports needed traits * bump impl_version * Update srml/system/src/lib.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update srml/system/src/lib.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- node/runtime/src/lib.rs | 2 +- srml/assets/src/lib.rs | 2 +- srml/aura/src/lib.rs | 2 +- srml/authority-discovery/src/lib.rs | 2 +- srml/authorship/src/lib.rs | 2 +- srml/babe/src/lib.rs | 2 +- srml/balances/src/lib.rs | 2 +- srml/collective/src/lib.rs | 2 +- srml/contracts/src/lib.rs | 2 +- srml/democracy/src/lib.rs | 2 +- srml/elections-phragmen/src/lib.rs | 1 - srml/elections/src/lib.rs | 1 - srml/example/src/lib.rs | 2 +- srml/finality-tracker/src/lib.rs | 1 - srml/grandpa/src/lib.rs | 1 - srml/im-online/src/lib.rs | 3 +-- srml/indices/src/lib.rs | 2 +- srml/membership/src/lib.rs | 2 +- srml/offences/src/lib.rs | 2 +- srml/session/src/historical.rs | 4 +--- srml/session/src/lib.rs | 2 +- srml/staking/src/lib.rs | 4 ++-- srml/support/procedural/src/storage/transformation.rs | 7 +++++++ srml/support/test/tests/final_keys.rs | 1 - srml/system/src/lib.rs | 4 ++-- srml/timestamp/src/lib.rs | 2 +- srml/treasury/src/lib.rs | 2 +- 27 files changed, 30 insertions(+), 31 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 642040f9bb..ada735314b 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -85,7 +85,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 162, - impl_version: 162, + impl_version: 163, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/assets/src/lib.rs b/srml/assets/src/lib.rs index 33bf32503f..bde5f7d538 100644 --- a/srml/assets/src/lib.rs +++ b/srml/assets/src/lib.rs @@ -130,7 +130,7 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -use support::{StorageValue, StorageMap, Parameter, decl_module, decl_event, decl_storage, ensure}; +use support::{Parameter, decl_module, decl_event, decl_storage, ensure}; use sr_primitives::traits::{Member, SimpleArithmetic, Zero, StaticLookup}; use system::ensure_signed; use sr_primitives::traits::One; diff --git a/srml/aura/src/lib.rs b/srml/aura/src/lib.rs index 0cca231ae1..65d1508810 100644 --- a/srml/aura/src/lib.rs +++ b/srml/aura/src/lib.rs @@ -50,7 +50,7 @@ pub use timestamp; use rstd::{result, prelude::*}; use codec::{Encode, Decode}; use support::{ - decl_storage, decl_module, Parameter, storage::StorageValue, traits::{Get, FindAuthor}, + decl_storage, decl_module, Parameter, traits::{Get, FindAuthor}, ConsensusEngineId, }; use sr_primitives::{ diff --git a/srml/authority-discovery/src/lib.rs b/srml/authority-discovery/src/lib.rs index 8032b46be4..7a4a104f1c 100644 --- a/srml/authority-discovery/src/lib.rs +++ b/srml/authority-discovery/src/lib.rs @@ -30,7 +30,7 @@ use app_crypto::RuntimeAppPublic; use rstd::prelude::*; -use support::{decl_module, decl_storage, StorageValue}; +use support::{decl_module, decl_storage}; pub trait Trait: system::Trait + session::Trait + im_online::Trait {} diff --git a/srml/authorship/src/lib.rs b/srml/authorship/src/lib.rs index f8a2ad1ed1..490774c734 100644 --- a/srml/authorship/src/lib.rs +++ b/srml/authorship/src/lib.rs @@ -22,7 +22,7 @@ use rstd::{result, prelude::*}; use rstd::collections::btree_set::BTreeSet; -use support::{decl_module, decl_storage, StorageValue}; +use support::{decl_module, decl_storage}; use support::traits::{FindAuthor, VerifySeal, Get}; use support::dispatch::Result as DispatchResult; use codec::{Encode, Decode}; diff --git a/srml/babe/src/lib.rs b/srml/babe/src/lib.rs index a08ccd1888..aa0165f9f8 100644 --- a/srml/babe/src/lib.rs +++ b/srml/babe/src/lib.rs @@ -23,7 +23,7 @@ pub use timestamp; use rstd::{result, prelude::*}; -use support::{decl_storage, decl_module, StorageValue, StorageMap, traits::FindAuthor, traits::Get}; +use support::{decl_storage, decl_module, traits::FindAuthor, traits::Get}; use timestamp::OnTimestampSet; use sr_primitives::{generic::DigestItem, ConsensusEngineId, Perbill}; use sr_primitives::traits::{IsMember, SaturatedConversion, Saturating, RandomnessBeacon}; diff --git a/srml/balances/src/lib.rs b/srml/balances/src/lib.rs index b865efa92a..03e32e1ddf 100644 --- a/srml/balances/src/lib.rs +++ b/srml/balances/src/lib.rs @@ -162,7 +162,7 @@ use rstd::prelude::*; use rstd::{cmp, result, mem}; use codec::{Codec, Encode, Decode}; use support::{ - StorageValue, StorageMap, Parameter, decl_event, decl_storage, decl_module, + StorageValue, Parameter, decl_event, decl_storage, decl_module, traits::{ UpdateBalanceOutcome, Currency, OnFreeBalanceZero, OnUnbalanced, WithdrawReason, WithdrawReasons, LockIdentifier, LockableCurrency, ExistenceRequirement, diff --git a/srml/collective/src/lib.rs b/srml/collective/src/lib.rs index 24208f2697..f4e5ef50f0 100644 --- a/srml/collective/src/lib.rs +++ b/srml/collective/src/lib.rs @@ -29,7 +29,7 @@ use sr_primitives::traits::{Hash, EnsureOrigin}; use sr_primitives::weights::SimpleDispatchInfo; use support::{ dispatch::{Dispatchable, Parameter}, codec::{Encode, Decode}, - traits::{ChangeMembers, InitializeMembers}, StorageValue, StorageMap, decl_module, decl_event, + traits::{ChangeMembers, InitializeMembers}, decl_module, decl_event, decl_storage, ensure, }; use system::{self, ensure_signed, ensure_root}; diff --git a/srml/contracts/src/lib.rs b/srml/contracts/src/lib.rs index 6ee93dfb0f..8343f39bc7 100644 --- a/srml/contracts/src/lib.rs +++ b/srml/contracts/src/lib.rs @@ -121,7 +121,7 @@ use sr_primitives::{ }; use support::dispatch::{Result, Dispatchable}; use support::{ - Parameter, StorageMap, StorageValue, decl_module, decl_event, decl_storage, storage::child, + Parameter, decl_module, decl_event, decl_storage, storage::child, parameter_types, }; use support::{traits::{OnFreeBalanceZero, OnUnbalanced, Currency, Get}, IsSubType}; diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index 585ffde14d..2c6187e582 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -26,7 +26,7 @@ use sr_primitives::{ }; use codec::{Encode, Decode, Input, Output, Error}; use support::{ - decl_module, decl_storage, decl_event, ensure, StorageValue, StorageMap, StorageLinkedMap, + decl_module, decl_storage, decl_event, ensure, Parameter, traits::{ Currency, ReservableCurrency, LockableCurrency, WithdrawReason, LockIdentifier, Get, diff --git a/srml/elections-phragmen/src/lib.rs b/srml/elections-phragmen/src/lib.rs index 6b0c773ec9..42bec61fe1 100644 --- a/srml/elections-phragmen/src/lib.rs +++ b/srml/elections-phragmen/src/lib.rs @@ -79,7 +79,6 @@ use sr_primitives::{print, traits::{Zero, StaticLookup, Bounded, Convert}}; use sr_primitives::weights::SimpleDispatchInfo; use srml_support::{ - StorageValue, StorageMap, StorageLinkedMap, decl_storage, decl_event, ensure, decl_module, dispatch, traits::{ Currency, Get, LockableCurrency, LockIdentifier, ReservableCurrency, WithdrawReasons, diff --git a/srml/elections/src/lib.rs b/srml/elections/src/lib.rs index 3aff5d4b2e..1c4e012b5b 100644 --- a/srml/elections/src/lib.rs +++ b/srml/elections/src/lib.rs @@ -28,7 +28,6 @@ use sr_primitives::{ print, traits::{Zero, One, StaticLookup, Bounded, Saturating}, weights::SimpleDispatchInfo, }; use support::{ - StorageValue, StorageMap, dispatch::Result, decl_storage, decl_event, ensure, decl_module, traits::{ Currency, ExistenceRequirement, Get, LockableCurrency, LockIdentifier, diff --git a/srml/example/src/lib.rs b/srml/example/src/lib.rs index ff797557f5..fe16fb7d6e 100644 --- a/srml/example/src/lib.rs +++ b/srml/example/src/lib.rs @@ -254,7 +254,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use rstd::marker::PhantomData; -use support::{StorageValue, dispatch::Result, decl_module, decl_storage, decl_event}; +use support::{dispatch::Result, decl_module, decl_storage, decl_event}; use system::{ensure_signed, ensure_root}; use codec::{Encode, Decode}; use sr_primitives::{ diff --git a/srml/finality-tracker/src/lib.rs b/srml/finality-tracker/src/lib.rs index 1f90927f7d..1bf9754b0a 100644 --- a/srml/finality-tracker/src/lib.rs +++ b/srml/finality-tracker/src/lib.rs @@ -22,7 +22,6 @@ use inherents::{ RuntimeString, InherentIdentifier, ProvideInherent, InherentData, MakeFatalError, }; -use support::StorageValue; use sr_primitives::traits::{One, Zero, SaturatedConversion}; use rstd::{prelude::*, result, cmp, vec}; use codec::Decode; diff --git a/srml/grandpa/src/lib.rs b/srml/grandpa/src/lib.rs index b59d261e1d..42641fb376 100644 --- a/srml/grandpa/src/lib.rs +++ b/srml/grandpa/src/lib.rs @@ -34,7 +34,6 @@ use rstd::prelude::*; use codec::{self as codec, Encode, Decode, Error}; use support::{ decl_event, decl_storage, decl_module, dispatch::Result, - storage::StorageValue, storage::StorageMap, }; use sr_primitives::{ generic::{DigestItem, OpaqueDigestItemId}, traits::Zero, diff --git a/srml/im-online/src/lib.rs b/srml/im-online/src/lib.rs index 7da88836f3..b09b24df5f 100644 --- a/srml/im-online/src/lib.rs +++ b/srml/im-online/src/lib.rs @@ -86,8 +86,7 @@ use sr_staking_primitives::{ offence::{ReportOffence, Offence, Kind}, }; use support::{ - decl_module, decl_event, decl_storage, print, ensure, - Parameter, StorageValue, StorageDoubleMap, + decl_module, decl_event, decl_storage, print, ensure, Parameter }; use system::ensure_none; use system::offchain::SubmitUnsignedTransaction; diff --git a/srml/indices/src/lib.rs b/srml/indices/src/lib.rs index 7b8e1c0461..be5016c40e 100644 --- a/srml/indices/src/lib.rs +++ b/srml/indices/src/lib.rs @@ -21,7 +21,7 @@ use rstd::{prelude::*, marker::PhantomData, convert::TryInto}; use codec::{Encode, Codec}; -use support::{StorageValue, StorageMap, Parameter, decl_module, decl_event, decl_storage}; +use support::{Parameter, decl_module, decl_event, decl_storage}; use sr_primitives::traits::{One, SimpleArithmetic, StaticLookup, Member, LookupError}; use system::{IsDeadAccount, OnNewAccount}; diff --git a/srml/membership/src/lib.rs b/srml/membership/src/lib.rs index 66ff864057..87e9268bd9 100644 --- a/srml/membership/src/lib.rs +++ b/srml/membership/src/lib.rs @@ -24,7 +24,7 @@ use rstd::prelude::*; use support::{ - StorageValue, decl_module, decl_storage, decl_event, traits::{ChangeMembers, InitializeMembers}, + decl_module, decl_storage, decl_event, traits::{ChangeMembers, InitializeMembers}, }; use system::ensure_root; use sr_primitives::{traits::EnsureOrigin, weights::SimpleDispatchInfo}; diff --git a/srml/offences/src/lib.rs b/srml/offences/src/lib.rs index a89efa2f83..5c1d04d0c0 100644 --- a/srml/offences/src/lib.rs +++ b/srml/offences/src/lib.rs @@ -29,7 +29,7 @@ use rstd::{ collections::btree_set::BTreeSet, }; use support::{ - StorageMap, StorageDoubleMap, decl_module, decl_event, decl_storage, Parameter, + decl_module, decl_event, decl_storage, Parameter, }; use sr_primitives::{ Perbill, diff --git a/srml/session/src/historical.rs b/srml/session/src/historical.rs index 82566295da..24821a0393 100644 --- a/srml/session/src/historical.rs +++ b/srml/session/src/historical.rs @@ -29,9 +29,7 @@ use rstd::prelude::*; use codec::{Encode, Decode}; use sr_primitives::KeyTypeId; use sr_primitives::traits::{Convert, OpaqueKeys, Hash as HashT}; -use support::{ - StorageValue, StorageMap, decl_module, decl_storage, -}; +use support::{decl_module, decl_storage}; use support::{Parameter, print}; use substrate_trie::{MemoryDB, Trie, TrieMut, Recorder, EMPTY_PREFIX}; use substrate_trie::trie_types::{TrieDBMut, TrieDB}; diff --git a/srml/session/src/lib.rs b/srml/session/src/lib.rs index 1494f88413..992d24d6b6 100644 --- a/srml/session/src/lib.rs +++ b/srml/session/src/lib.rs @@ -126,7 +126,7 @@ use sr_primitives::weights::SimpleDispatchInfo; use sr_primitives::traits::{Convert, Zero, Member, OpaqueKeys}; use sr_staking_primitives::SessionIndex; use support::{ - dispatch::Result, ConsensusEngineId, StorageValue, StorageDoubleMap, decl_module, decl_event, + dispatch::Result, ConsensusEngineId, decl_module, decl_event, decl_storage, }; use support::{ensure, traits::{OnFreeBalanceZero, Get, FindAuthor}, Parameter}; diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index c450e142af..bb7368affc 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -254,8 +254,8 @@ pub mod inflation; use rstd::{prelude::*, result}; use codec::{HasCompact, Encode, Decode}; use support::{ - StorageValue, StorageMap, StorageLinkedMap, decl_module, decl_event, - decl_storage, ensure, traits::{ + decl_module, decl_event, decl_storage, ensure, + traits::{ Currency, OnFreeBalanceZero, OnDilution, LockIdentifier, LockableCurrency, WithdrawReasons, OnUnbalanced, Imbalance, Get, Time } diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index cb2c7e6ca9..73954522b1 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -155,6 +155,13 @@ pub fn decl_storage_impl(input: TokenStream) -> TokenStream { } = instance_opts; let expanded = quote! { + use #scrate::{ + StorageValue as _, + StorageMap as _, + StorageLinkedMap as _, + StorageDoubleMap as _ + }; + #scrate_decl #decl_storage_items #visibility trait #storetype { diff --git a/srml/support/test/tests/final_keys.rs b/srml/support/test/tests/final_keys.rs index dfa363b582..8c26ad1843 100644 --- a/srml/support/test/tests/final_keys.rs +++ b/srml/support/test/tests/final_keys.rs @@ -16,7 +16,6 @@ use runtime_io::with_externalities; use primitives::Blake2Hasher; -use support::{StorageValue, StorageMap, StorageLinkedMap, StorageDoubleMap}; use support::storage::unhashed; use codec::{Encode, Decode}; diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index 9bacbd6887..ecbfb598df 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -111,8 +111,8 @@ use sr_primitives::{ use primitives::storage::well_known_keys; use support::{ - storage, decl_module, decl_event, decl_storage, StorageDoubleMap, StorageValue, StorageMap, - Parameter, traits::{Contains, Get}, decl_error, + decl_module, decl_event, decl_storage, decl_error, storage, Parameter, + traits::{Contains, Get}, }; use safe_mix::TripletMix; use codec::{Encode, Decode}; diff --git a/srml/timestamp/src/lib.rs b/srml/timestamp/src/lib.rs index 919e2a75ab..4af0de8bd1 100644 --- a/srml/timestamp/src/lib.rs +++ b/srml/timestamp/src/lib.rs @@ -96,7 +96,7 @@ use codec::Encode; use codec::Decode; #[cfg(feature = "std")] use inherents::ProvideInherentData; -use support::{StorageValue, Parameter, decl_storage, decl_module}; +use support::{Parameter, decl_storage, decl_module}; use support::traits::{Time, Get}; use sr_primitives::traits::{ SimpleArithmetic, Zero, SaturatedConversion, Scale diff --git a/srml/treasury/src/lib.rs b/srml/treasury/src/lib.rs index 0ee4919c5d..0fd561fca0 100644 --- a/srml/treasury/src/lib.rs +++ b/srml/treasury/src/lib.rs @@ -70,7 +70,7 @@ #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; use rstd::prelude::*; -use support::{StorageValue, StorageMap, decl_module, decl_storage, decl_event, ensure, print}; +use support::{decl_module, decl_storage, decl_event, ensure, print}; use support::traits::{ Currency, ExistenceRequirement, Get, Imbalance, OnDilution, OnUnbalanced, ReservableCurrency, WithdrawReason -- GitLab From 5098710c15df00df162def0b3b4f5aeb95c5dd7d Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Tue, 24 Sep 2019 10:45:44 +0200 Subject: [PATCH 129/275] fix #2177: port GRANDPA node-side code to use Consensus digests (#3669) * fix #2177: port GRANDPA node-side code to use Consensus digests * bump runtime version * fix service compilation * document change precedence rules --- Cargo.lock | 8 -- core/finality-grandpa/primitives/src/lib.rs | 48 +------ core/finality-grandpa/src/import.rs | 146 +++++++++----------- core/finality-grandpa/src/lib.rs | 5 +- core/finality-grandpa/src/tests.rs | 139 ++++++++----------- node-template/runtime/src/lib.rs | 16 +-- node-template/src/service.rs | 2 +- node/cli/src/service.rs | 2 +- node/runtime/src/lib.rs | 16 +-- srml/grandpa/src/lib.rs | 3 + 10 files changed, 138 insertions(+), 247 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ce82be57b2..f4780648d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4317,14 +4317,6 @@ dependencies = [ "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "srml-staking-reward-curve-test" -version = "2.0.0" -dependencies = [ - "sr-primitives 2.0.0", - "srml-staking-reward-curve 2.0.0", -] - [[package]] name = "srml-sudo" version = "2.0.0" diff --git a/core/finality-grandpa/primitives/src/lib.rs b/core/finality-grandpa/primitives/src/lib.rs index 1f103a548d..384319a298 100644 --- a/core/finality-grandpa/primitives/src/lib.rs +++ b/core/finality-grandpa/primitives/src/lib.rs @@ -24,7 +24,7 @@ extern crate alloc; #[cfg(feature = "std")] use serde::Serialize; use codec::{Encode, Decode, Codec}; -use sr_primitives::{ConsensusEngineId, traits::{DigestFor, NumberFor}}; +use sr_primitives::ConsensusEngineId; use client::decl_runtime_apis; use rstd::vec::Vec; @@ -74,8 +74,9 @@ pub struct ScheduledChange { pub enum ConsensusLog { /// Schedule an authority set change. /// - /// Precedence towards earlier or later digest items can be given - /// based on the rules of the chain. + /// The earliest digest of this type in a single block will be respected, + /// provided that there is no `ForcedChange` digest. If there is, then the + /// `ForcedChange` will take precedence. /// /// No change should be scheduled if one is already and the delay has not /// passed completely. @@ -90,8 +91,8 @@ pub enum ConsensusLog { /// Forced changes are applied after a delay of _imported_ blocks, /// while pending changes are applied after a delay of _finalized_ blocks. /// - /// Precedence towards earlier or later digest items can be given - /// based on the rules of the chain. + /// The earliest digest of this type in a single block will be respected, + /// with others ignored. /// /// No change should be scheduled if one is already and the delay has not /// passed completely. @@ -165,43 +166,6 @@ decl_runtime_apis! { /// The consensus protocol will coordinate the handoff externally. #[api_version(2)] pub trait GrandpaApi { - /// Check a digest for pending changes. - /// Return `None` if there are no pending changes. - /// - /// Precedence towards earlier or later digest items can be given - /// based on the rules of the chain. - /// - /// No change should be scheduled if one is already and the delay has not - /// passed completely. - /// - /// This should be a pure function: i.e. as long as the runtime can interpret - /// the digest type it should return the same result regardless of the current - /// state. - fn grandpa_pending_change(digest: &DigestFor) - -> Option>>; - - /// Check a digest for forced changes. - /// Return `None` if there are no forced changes. Otherwise, return a - /// tuple containing the pending change and the median last finalized - /// block number at the time the change was signaled. - /// - /// Added in version 2. - /// - /// Forced changes are applied after a delay of _imported_ blocks, - /// while pending changes are applied after a delay of _finalized_ blocks. - /// - /// Precedence towards earlier or later digest items can be given - /// based on the rules of the chain. - /// - /// No change should be scheduled if one is already and the delay has not - /// passed completely. - /// - /// This should be a pure function: i.e. as long as the runtime can interpret - /// the digest type it should return the same result regardless of the current - /// state. - fn grandpa_forced_change(digest: &DigestFor) - -> Option<(NumberFor, ScheduledChange>)>; - /// Get the current GRANDPA authorities and weights. This should not change except /// for when changes are scheduled and the corresponding delay has passed. /// diff --git a/core/finality-grandpa/src/import.rs b/core/finality-grandpa/src/import.rs index 46b32d999d..906b87b87e 100644 --- a/core/finality-grandpa/src/import.rs +++ b/core/finality-grandpa/src/import.rs @@ -24,19 +24,17 @@ use parking_lot::RwLockWriteGuard; use client::{blockchain, CallExecutor, Client, well_known_cache_keys}; use client::blockchain::HeaderBackend; use client::backend::Backend; -use client::runtime_api::ApiExt; use client::utils::is_descendent_of; use consensus_common::{ BlockImport, Error as ConsensusError, BlockImportParams, ImportResult, JustificationImport, SelectChain, }; -use fg_primitives::GrandpaApi; +use fg_primitives::{GRANDPA_ENGINE_ID, ScheduledChange, ConsensusLog}; use sr_primitives::Justification; -use sr_primitives::generic::BlockId; +use sr_primitives::generic::{BlockId, OpaqueDigestItemId}; use sr_primitives::traits::{ - Block as BlockT, DigestFor, - Header as HeaderT, NumberFor, ProvideRuntimeApi, + Block as BlockT, DigestFor, Header as HeaderT, NumberFor, }; use primitives::{H256, Blake2Hasher}; @@ -55,17 +53,16 @@ use crate::justification::GrandpaJustification; /// /// When using GRANDPA, the block import worker should be using this block import /// object. -pub struct GrandpaBlockImport, RA, PRA, SC> { +pub struct GrandpaBlockImport, RA, SC> { inner: Arc>, select_chain: SC, authority_set: SharedAuthoritySet>, send_voter_commands: mpsc::UnboundedSender>>, consensus_changes: SharedConsensusChanges>, - api: Arc, } -impl, RA, PRA, SC: Clone> Clone for - GrandpaBlockImport +impl, RA, SC: Clone> Clone for + GrandpaBlockImport { fn clone(&self) -> Self { GrandpaBlockImport { @@ -74,20 +71,17 @@ impl, RA, PRA, SC: Clone> Clone for authority_set: self.authority_set.clone(), send_voter_commands: self.send_voter_commands.clone(), consensus_changes: self.consensus_changes.clone(), - api: self.api.clone(), } } } -impl, RA, PRA, SC> JustificationImport - for GrandpaBlockImport where +impl, RA, SC> JustificationImport + for GrandpaBlockImport where NumberFor: grandpa::BlockNumberOps, B: Backend + 'static, E: CallExecutor + 'static + Clone + Send + Sync, DigestFor: Encode, RA: Send + Sync, - PRA: ProvideRuntimeApi, - PRA::Api: GrandpaApi, SC: SelectChain, { type Error = ConsensusError; @@ -174,75 +168,69 @@ impl<'a, Block: 'a + BlockT> Drop for PendingSetChanges<'a, Block> { } } -impl, RA, PRA, SC> - GrandpaBlockImport +fn find_scheduled_change(header: &B::Header) + -> Option>> +{ + let id = OpaqueDigestItemId::Consensus(&GRANDPA_ENGINE_ID); + + let filter_log = |log: ConsensusLog>| match log { + ConsensusLog::ScheduledChange(change) => Some(change), + _ => None, + }; + + // find the first consensus digest with the right ID which converts to + // the right kind of consensus log. + header.digest().convert_first(|l| l.try_to(id).and_then(filter_log)) +} + +fn find_forced_change(header: &B::Header) + -> Option<(NumberFor, ScheduledChange>)> +{ + let id = OpaqueDigestItemId::Consensus(&GRANDPA_ENGINE_ID); + + let filter_log = |log: ConsensusLog>| match log { + ConsensusLog::ForcedChange(delay, change) => Some((delay, change)), + _ => None, + }; + + // find the first consensus digest with the right ID which converts to + // the right kind of consensus log. + header.digest().convert_first(|l| l.try_to(id).and_then(filter_log)) +} + +impl, RA, SC> + GrandpaBlockImport where NumberFor: grandpa::BlockNumberOps, B: Backend + 'static, E: CallExecutor + 'static + Clone + Send + Sync, DigestFor: Encode, RA: Send + Sync, - PRA: ProvideRuntimeApi, - PRA::Api: GrandpaApi, { // check for a new authority set change. fn check_new_change(&self, header: &Block::Header, hash: Block::Hash) - -> Result>>, ConsensusError> + -> Option>> { - let at = BlockId::hash(*header.parent_hash()); - let digest = header.digest(); - - let api = self.api.runtime_api(); - // check for forced change. - { - let maybe_change = api.grandpa_forced_change( - &at, - digest, - ); - - match maybe_change { - Err(e) => match api.has_api_with::, _>(&at, |v| v >= 2) { - Err(e) => return Err(ConsensusError::ClientImport(e.to_string()).into()), - Ok(true) => { - // API version is high enough to support forced changes - // but got error, so it is legitimate. - return Err(ConsensusError::ClientImport(e.to_string()).into()) - }, - Ok(false) => { - // API version isn't high enough to support forced changes - }, - }, - Ok(None) => {}, - Ok(Some((median_last_finalized, change))) => return Ok(Some(PendingChange { - next_authorities: change.next_authorities, - delay: change.delay, - canon_height: *header.number(), - canon_hash: hash, - delay_kind: DelayKind::Best { median_last_finalized }, - })), - } + if let Some((median_last_finalized, change)) = find_forced_change::(header) { + return Some(PendingChange { + next_authorities: change.next_authorities, + delay: change.delay, + canon_height: *header.number(), + canon_hash: hash, + delay_kind: DelayKind::Best { median_last_finalized }, + }); } // check normal scheduled change. - { - let maybe_change = api.grandpa_pending_change( - &at, - digest, - ); - - match maybe_change { - Err(e) => Err(ConsensusError::ClientImport(e.to_string()).into()), - Ok(Some(change)) => Ok(Some(PendingChange { - next_authorities: change.next_authorities, - delay: change.delay, - canon_height: *header.number(), - canon_hash: hash, - delay_kind: DelayKind::Finalized, - })), - Ok(None) => Ok(None), - } - } + let change = find_scheduled_change::(header)?; + Some(PendingChange { + next_authorities: change.next_authorities, + delay: change.delay, + canon_height: *header.number(), + canon_hash: hash, + delay_kind: DelayKind::Finalized, + }) } fn make_authorities_changes<'a>(&'a self, block: &mut BlockImportParams, hash: Block::Hash) @@ -289,7 +277,7 @@ where let maybe_change = self.check_new_change( &block.header, hash, - )?; + ); // returns a function for checking whether a block is a descendent of another // consistent with querying client directly after importing the block. @@ -388,15 +376,13 @@ where } } -impl, RA, PRA, SC> BlockImport - for GrandpaBlockImport where +impl, RA, SC> BlockImport + for GrandpaBlockImport where NumberFor: grandpa::BlockNumberOps, B: Backend + 'static, E: CallExecutor + 'static + Clone + Send + Sync, DigestFor: Encode, RA: Send + Sync, - PRA: ProvideRuntimeApi, - PRA::Api: GrandpaApi, { type Error = ConsensusError; @@ -521,8 +507,8 @@ impl, RA, PRA, SC> BlockImport } } -impl, RA, PRA, SC> - GrandpaBlockImport +impl, RA, SC> + GrandpaBlockImport { pub(crate) fn new( inner: Arc>, @@ -530,21 +516,19 @@ impl, RA, PRA, SC> authority_set: SharedAuthoritySet>, send_voter_commands: mpsc::UnboundedSender>>, consensus_changes: SharedConsensusChanges>, - api: Arc, - ) -> GrandpaBlockImport { + ) -> GrandpaBlockImport { GrandpaBlockImport { inner, select_chain, authority_set, send_voter_commands, consensus_changes, - api, } } } -impl, RA, PRA, SC> - GrandpaBlockImport +impl, RA, SC> + GrandpaBlockImport where NumberFor: grandpa::BlockNumberOps, B: Backend + 'static, diff --git a/core/finality-grandpa/src/lib.rs b/core/finality-grandpa/src/lib.rs index 7f71bfadb3..abf6476e98 100644 --- a/core/finality-grandpa/src/lib.rs +++ b/core/finality-grandpa/src/lib.rs @@ -339,10 +339,10 @@ pub struct LinkHalf, RA, SC> { /// to it. pub fn block_import, RA, PRA, SC>( client: Arc>, - api: Arc, + api: &PRA, select_chain: SC, ) -> Result<( - GrandpaBlockImport, + GrandpaBlockImport, LinkHalf ), ClientError> where @@ -381,7 +381,6 @@ where persistent_data.authority_set.clone(), voter_commands_tx, persistent_data.consensus_changes.clone(), - api, ), LinkHalf { client, diff --git a/core/finality-grandpa/src/tests.rs b/core/finality-grandpa/src/tests.rs index f6f28e705d..1957ab5c4f 100644 --- a/core/finality-grandpa/src/tests.rs +++ b/core/finality-grandpa/src/tests.rs @@ -37,9 +37,9 @@ use std::collections::{HashMap, HashSet}; use std::result; use codec::Decode; use sr_primitives::traits::{ApiRef, ProvideRuntimeApi, Header as HeaderT}; -use sr_primitives::generic::BlockId; +use sr_primitives::generic::{BlockId, DigestItem}; use primitives::{NativeOrEncoded, ExecutionContext, crypto::Public}; -use fg_primitives::AuthorityId; +use fg_primitives::{GRANDPA_ENGINE_ID, AuthorityId}; use authorities::AuthoritySet; use finality_proof::{FinalityProofProvider, AuthoritySetForFinalityProver, AuthoritySetForFinalityChecker}; @@ -120,7 +120,7 @@ impl TestNetFactory for GrandpaTestNet { PeersClient::Full(ref client, ref backend) => { let (import, link) = block_import( client.clone(), - Arc::new(self.test_config.clone()), + &self.test_config, LongestChain::new(backend.clone()), ).expect("Could not create block import for fresh peer."); let justification_import = Box::new(import.clone()); @@ -188,16 +188,12 @@ impl Future for Exit { #[derive(Default, Clone)] pub(crate) struct TestApi { genesis_authorities: Vec<(AuthorityId, u64)>, - scheduled_changes: Arc>>>, - forced_changes: Arc)>>>, } impl TestApi { pub fn new(genesis_authorities: Vec<(AuthorityId, u64)>) -> Self { TestApi { genesis_authorities, - scheduled_changes: Arc::new(Mutex::new(HashMap::new())), - forced_changes: Arc::new(Mutex::new(HashMap::new())), } } } @@ -277,41 +273,6 @@ impl GrandpaApi for RuntimeApi { ) -> Result>> { Ok(self.inner.genesis_authorities.clone()).map(NativeOrEncoded::Native) } - - fn GrandpaApi_grandpa_pending_change_runtime_api_impl( - &self, - at: &BlockId, - _: ExecutionContext, - _: Option<(&DigestFor)>, - _: Vec, - ) -> Result>>>> { - let parent_hash = match at { - &BlockId::Hash(at) => at, - _ => panic!("not requested by block hash!!"), - }; - - // we take only scheduled changes at given block number where there are no - // extrinsics. - Ok(self.inner.scheduled_changes.lock().get(&parent_hash).map(|c| c.clone())).map(NativeOrEncoded::Native) - } - - fn GrandpaApi_grandpa_forced_change_runtime_api_impl( - &self, - at: &BlockId, - _: ExecutionContext, - _: Option<(&DigestFor)>, - _: Vec, - ) - -> Result, ScheduledChange>)>>> { - let parent_hash = match at { - &BlockId::Hash(at) => at, - _ => panic!("not requested by block hash!!"), - }; - - // we take only scheduled changes at given block number where there are no - // extrinsics. - Ok(self.inner.forced_changes.lock().get(&parent_hash).map(|c| c.clone())).map(NativeOrEncoded::Native) - } } impl AuthoritySetForFinalityProver for TestApi { @@ -453,6 +414,24 @@ fn run_to_completion( run_to_completion_with(runtime, blocks, net, peers, |_| None) } +fn add_scheduled_change(block: &mut Block, change: ScheduledChange) { + block.header.digest_mut().push(DigestItem::Consensus( + GRANDPA_ENGINE_ID, + fg_primitives::ConsensusLog::ScheduledChange(change).encode(), + )); +} + +fn add_forced_change( + block: &mut Block, + median_last_finalized: BlockNumber, + change: ScheduledChange, +) { + block.header.digest_mut().push(DigestItem::Consensus( + GRANDPA_ENGINE_ID, + fg_primitives::ConsensusLog::ForcedChange(median_last_finalized, change).encode(), + )); +} + #[test] fn finalize_3_voters_no_observers() { let _ = env_logger::try_init(); @@ -578,7 +557,6 @@ fn transition_3_voters_twice_1_full_observer() { let genesis_voters = make_ids(peers_a); let api = TestApi::new(genesis_voters); - let transitions = api.scheduled_changes.clone(); let net = Arc::new(Mutex::new(GrandpaTestNet::new(api, 8))); let mut runtime = current_thread::Runtime::new().unwrap(); @@ -600,10 +578,6 @@ fn transition_3_voters_twice_1_full_observer() { { let net = net.clone(); let client = net.lock().peers[0].client().clone(); - let transitions = transitions.clone(); - let add_transition = move |parent_hash, change| { - transitions.lock().insert(parent_hash, change); - }; let peers_c = peers_c.clone(); // wait for blocks to be finalized before generating new ones @@ -619,8 +593,8 @@ fn transition_3_voters_twice_1_full_observer() { 14 => { // generate transition at block 15, applied at 20. net.lock().peer(0).generate_blocks(1, BlockOrigin::File, |builder| { - let block = builder.bake().unwrap(); - add_transition(*block.header.parent_hash(), ScheduledChange { + let mut block = builder.bake().unwrap(); + add_scheduled_change(&mut block, ScheduledChange { next_authorities: make_ids(peers_b), delay: 4, }); @@ -633,8 +607,8 @@ fn transition_3_voters_twice_1_full_observer() { // at block 21 we do another transition, but this time instant. // add more until we have 30. net.lock().peer(0).generate_blocks(1, BlockOrigin::File, |builder| { - let block = builder.bake().unwrap(); - add_transition(*block.header.parent_hash(), ScheduledChange { + let mut block = builder.bake().unwrap(); + add_scheduled_change(&mut block, ScheduledChange { next_authorities: make_ids(&peers_c), delay: 0, }); @@ -783,7 +757,6 @@ fn sync_justifications_on_change_blocks() { // 4 peers, 3 of them are authorities and participate in grandpa let api = TestApi::new(voters); - let transitions = api.scheduled_changes.clone(); let mut net = GrandpaTestNet::new(api, 4); // add 20 blocks @@ -791,8 +764,8 @@ fn sync_justifications_on_change_blocks() { // at block 21 we do add a transition which is instant net.peer(0).generate_blocks(1, BlockOrigin::File, |builder| { - let block = builder.bake().unwrap(); - transitions.lock().insert(*block.header.parent_hash(), ScheduledChange { + let mut block = builder.bake().unwrap(); + add_scheduled_change(&mut block, ScheduledChange { next_authorities: make_ids(peers_b), delay: 0, }); @@ -845,7 +818,6 @@ fn finalizes_multiple_pending_changes_in_order() { // 6 peers, 3 of them are authorities and participate in grandpa from genesis let api = TestApi::new(genesis_voters); - let transitions = api.scheduled_changes.clone(); let mut net = GrandpaTestNet::new(api, 6); // add 20 blocks @@ -853,8 +825,8 @@ fn finalizes_multiple_pending_changes_in_order() { // at block 21 we do add a transition which is instant net.peer(0).generate_blocks(1, BlockOrigin::File, |builder| { - let block = builder.bake().unwrap(); - transitions.lock().insert(*block.header.parent_hash(), ScheduledChange { + let mut block = builder.bake().unwrap(); + add_scheduled_change(&mut block, ScheduledChange { next_authorities: make_ids(peers_b), delay: 0, }); @@ -866,8 +838,8 @@ fn finalizes_multiple_pending_changes_in_order() { // at block 26 we add another which is enacted at block 30 net.peer(0).generate_blocks(1, BlockOrigin::File, |builder| { - let block = builder.bake().unwrap(); - transitions.lock().insert(*block.header.parent_hash(), ScheduledChange { + let mut block = builder.bake().unwrap(); + add_scheduled_change(&mut block, ScheduledChange { next_authorities: make_ids(peers_c), delay: 4, }); @@ -929,27 +901,26 @@ fn force_change_to_new_set() { let api = TestApi::new(make_ids(genesis_authorities)); let voters = make_ids(peers_a); - let normal_transitions = api.scheduled_changes.clone(); - let forced_transitions = api.forced_changes.clone(); let net = GrandpaTestNet::new(api, 3); let net = Arc::new(Mutex::new(net)); - net.lock().peer(0).push_blocks(1, false); + net.lock().peer(0).generate_blocks(1, BlockOrigin::File, |builder| { + let mut block = builder.bake().unwrap(); - { // add a forced transition at block 12. - let parent_hash = net.lock().peer(0).client().info().chain.best_hash; - forced_transitions.lock().insert(parent_hash, (0, ScheduledChange { + add_forced_change(&mut block, 0, ScheduledChange { next_authorities: voters.clone(), delay: 10, - })); + }); // add a normal transition too to ensure that forced changes take priority. - normal_transitions.lock().insert(parent_hash, ScheduledChange { + add_scheduled_change(&mut block, ScheduledChange { next_authorities: make_ids(genesis_authorities), delay: 5, }); - } + + block + }); net.lock().peer(0).push_blocks(25, false); net.lock().block_until_sync(&mut runtime); @@ -984,8 +955,8 @@ fn allows_reimporting_change_blocks() { let full_client = client.as_full().unwrap(); let builder = full_client.new_block_at(&BlockId::Number(0), Default::default()).unwrap(); - let block = builder.bake().unwrap(); - api.scheduled_changes.lock().insert(*block.header.parent_hash(), ScheduledChange { + let mut block = builder.bake().unwrap(); + add_scheduled_change(&mut block, ScheduledChange { next_authorities: make_ids(peers_b), delay: 0, }); @@ -1034,8 +1005,9 @@ fn test_bad_justification() { let full_client = client.as_full().expect("only full clients are used in test"); let builder = full_client.new_block_at(&BlockId::Number(0), Default::default()).unwrap(); - let block = builder.bake().unwrap(); - api.scheduled_changes.lock().insert(*block.header.parent_hash(), ScheduledChange { + let mut block = builder.bake().unwrap(); + + add_scheduled_change(&mut block, ScheduledChange { next_authorities: make_ids(peers_b), delay: 0, }); @@ -1413,20 +1385,21 @@ fn empty_finality_proof_is_returned_to_light_client_when_authority_set_is_differ let api = TestApi::new(make_ids(&genesis_authorities)); let voters = make_ids(peers_a); - let forced_transitions = api.forced_changes.clone(); let net = GrandpaTestNet::new(api, 3); let net = Arc::new(Mutex::new(net)); - net.lock().peer(0).push_blocks(1, false); // best is #1 - - // add a forced transition at block 5. - if FORCE_CHANGE { - let parent_hash = net.lock().peer(0).client().info().chain.best_hash; - forced_transitions.lock().insert(parent_hash, (0, ScheduledChange { - next_authorities: voters.clone(), - delay: 3, - })); - } + // best is #1 + net.lock().peer(0).generate_blocks(1, BlockOrigin::File, |builder| { + // add a forced transition at block 5. + let mut block = builder.bake().unwrap(); + if FORCE_CHANGE { + add_forced_change(&mut block, 0, ScheduledChange { + next_authorities: voters.clone(), + delay: 3, + }); + } + block + }); // ensure block#10 enacts authorities set change => justification is generated // normally it will reach light client, but because of the forced change, it will not diff --git a/node-template/runtime/src/lib.rs b/node-template/runtime/src/lib.rs index f736d9c62d..6b2b335d68 100644 --- a/node-template/runtime/src/lib.rs +++ b/node-template/runtime/src/lib.rs @@ -14,11 +14,11 @@ use sr_primitives::{ ApplyResult, transaction_validity::TransactionValidity, generic, create_runtime_str, impl_opaque_keys, AnySignature }; -use sr_primitives::traits::{NumberFor, BlakeTwo256, Block as BlockT, DigestFor, StaticLookup, Verify, ConvertInto}; +use sr_primitives::traits::{NumberFor, BlakeTwo256, Block as BlockT, StaticLookup, Verify, ConvertInto}; use sr_primitives::weights::Weight; use babe::{AuthorityId as BabeId}; use grandpa::{AuthorityId as GrandpaId, AuthorityWeight as GrandpaWeight}; -use grandpa::fg_primitives::{self, ScheduledChange}; +use grandpa::fg_primitives; use client::{ block_builder::api::{CheckInherentsResult, InherentData, self as block_builder_api}, runtime_api as client_api, impl_runtime_apis @@ -356,18 +356,6 @@ impl_runtime_apis! { } impl fg_primitives::GrandpaApi for Runtime { - fn grandpa_pending_change(digest: &DigestFor) - -> Option>> - { - Grandpa::pending_change(digest) - } - - fn grandpa_forced_change(digest: &DigestFor) - -> Option<(NumberFor, ScheduledChange>)> - { - Grandpa::forced_change(digest) - } - fn grandpa_authorities() -> Vec<(GrandpaId, GrandpaWeight)> { Grandpa::grandpa_authorities() } diff --git a/node-template/src/service.rs b/node-template/src/service.rs index c26959d302..b625ff1109 100644 --- a/node-template/src/service.rs +++ b/node-template/src/service.rs @@ -49,7 +49,7 @@ macro_rules! new_full_start { .ok_or_else(|| substrate_service::Error::SelectChainRequired)?; let (grandpa_block_import, grandpa_link) = grandpa::block_import::<_, _, _, node_template_runtime::RuntimeApi, _, _>( - client.clone(), client.clone(), select_chain + client.clone(), &*client, select_chain )?; let justification_import = grandpa_block_import.clone(); diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index 06c88f3d58..7deec59979 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -62,7 +62,7 @@ macro_rules! new_full_start { .ok_or_else(|| substrate_service::Error::SelectChainRequired)?; let (grandpa_block_import, grandpa_link) = grandpa::block_import::<_, _, _, node_runtime::RuntimeApi, _, _>( - client.clone(), client.clone(), select_chain + client.clone(), &*client, select_chain )?; let justification_import = grandpa_block_import.clone(); diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index ada735314b..0bec78fe1f 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -30,7 +30,7 @@ use node_primitives::{ Moment, Signature, ContractExecResult, }; use babe_primitives::{AuthorityId as BabeId}; -use grandpa::fg_primitives::{self, ScheduledChange}; +use grandpa::fg_primitives; use client::{ block_builder::api::{self as block_builder_api, InherentData, CheckInherentsResult}, runtime_api as client_api, impl_runtime_apis @@ -42,7 +42,7 @@ use sr_primitives::curve::PiecewiseLinear; use sr_primitives::transaction_validity::TransactionValidity; use sr_primitives::weights::Weight; use sr_primitives::traits::{ - self, BlakeTwo256, Block as BlockT, DigestFor, NumberFor, StaticLookup, SaturatedConversion, + self, BlakeTwo256, Block as BlockT, NumberFor, StaticLookup, SaturatedConversion, }; use version::RuntimeVersion; use elections::VoteIndex; @@ -596,18 +596,6 @@ impl_runtime_apis! { } impl fg_primitives::GrandpaApi for Runtime { - fn grandpa_pending_change(digest: &DigestFor) - -> Option>> - { - Grandpa::pending_change(digest) - } - - fn grandpa_forced_change(digest: &DigestFor) - -> Option<(NumberFor, ScheduledChange>)> - { - Grandpa::forced_change(digest) - } - fn grandpa_authorities() -> Vec<(GrandpaId, GrandpaWeight)> { Grandpa::grandpa_authorities() } diff --git a/srml/grandpa/src/lib.rs b/srml/grandpa/src/lib.rs index 42641fb376..599dc0886f 100644 --- a/srml/grandpa/src/lib.rs +++ b/srml/grandpa/src/lib.rs @@ -246,6 +246,8 @@ impl Module { Authorities::get() } + /// Schedule GRANDPA to pause starting in the given number of blocks. + /// Cannot be done when already paused. pub fn schedule_pause(in_blocks: T::BlockNumber) -> Result { if let StoredState::Live = >::get() { let scheduled_at = >::block_number(); @@ -261,6 +263,7 @@ impl Module { } } + /// Schedule a resume of GRANDPA after pausing. pub fn schedule_resume(in_blocks: T::BlockNumber) -> Result { if let StoredState::Paused = >::get() { let scheduled_at = >::block_number(); -- GitLab From 7a7d641b40b9f9791406d04bd4fc7be2d190fa7b Mon Sep 17 00:00:00 2001 From: Toralf Wittner Date: Tue, 24 Sep 2019 10:48:21 +0200 Subject: [PATCH 130/275] Add block announce validator. (#3346) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add `BlockAnnounceValidator` trait. * Add associated data to block announcement. * Make tests compile. * Move validator into `sync.rs`. * Smaller changes. * Update core/network/src/protocol.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update core/network/src/protocol.rs Co-Authored-By: Bastian Köcher * Update core/network/src/test/sync.rs Co-Authored-By: Bastian Köcher * Formatting. * Remove assoc. data from `BlockImportNotification`. * Use `Option>` for associated data. * Update core/network/src/protocol/sync.rs Co-Authored-By: Bastian Köcher * Fix type error. --- core/client/src/client.rs | 32 ++++----- core/client/src/lib.rs | 2 +- core/consensus/common/src/block_validation.rs | 66 +++++++++++++++++++ core/consensus/common/src/lib.rs | 16 +++++ .../finality-grandpa/src/communication/mod.rs | 8 +-- .../src/communication/periodic.rs | 17 ++--- .../src/communication/tests.rs | 4 +- core/network/src/chain.rs | 4 +- core/network/src/config.rs | 5 +- core/network/src/protocol.rs | 60 +++++++++-------- core/network/src/protocol/message.rs | 7 ++ core/network/src/protocol/sync.rs | 33 ++++++++-- core/network/src/service.rs | 19 +++--- core/network/src/test/mod.rs | 13 ++-- core/network/src/test/sync.rs | 4 +- core/service/src/lib.rs | 6 +- 16 files changed, 207 insertions(+), 89 deletions(-) create mode 100644 core/consensus/common/src/block_validation.rs diff --git a/core/client/src/client.rs b/core/client/src/client.rs index 32af79a4bf..50bbe1efbc 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -47,7 +47,7 @@ use state_machine::{ }; use executor::{RuntimeVersion, RuntimeInfo}; use consensus::{ - Error as ConsensusError, BlockImportParams, + Error as ConsensusError, BlockStatus, BlockImportParams, ImportResult, BlockOrigin, ForkChoiceStrategy, SelectChain, self, }; @@ -171,21 +171,6 @@ pub struct ClientInfo { pub used_state_cache_size: Option, } -/// Block status. -#[derive(Debug, PartialEq, Eq)] -pub enum BlockStatus { - /// Added to the import queue. - Queued, - /// Already in the blockchain and the state is available. - InChainWithState, - /// In the blockchain, but the state is not available. - InChainPruned, - /// Block or parent is known to be bad. - KnownBad, - /// Not in the queue or the blockchain. - Unknown, -} - /// Summary of an imported block #[derive(Clone, Debug)] pub struct BlockImportNotification { @@ -1187,10 +1172,7 @@ impl Client where Ok(()) } - fn notify_imported( - &self, - notify_import: ImportSummary, - ) -> error::Result<()> { + fn notify_imported(&self, notify_import: ImportSummary) -> error::Result<()> { if let Some(storage_changes) = notify_import.storage_changes { // TODO [ToDr] How to handle re-orgs? Should we re-emit all storage changes? self.storage_notifications.lock() @@ -1839,6 +1821,16 @@ pub mod utils { } } +impl consensus::block_validation::Chain for Client + where BE: backend::Backend, + E: CallExecutor, + B: BlockT +{ + fn block_status(&self, id: &BlockId) -> Result> { + Client::block_status(self, id).map_err(|e| Box::new(e) as Box<_>) + } +} + #[cfg(test)] pub(crate) mod tests { use std::collections::HashMap; diff --git a/core/client/src/lib.rs b/core/client/src/lib.rs index 636a1e4df6..b56c6a5706 100644 --- a/core/client/src/lib.rs +++ b/core/client/src/lib.rs @@ -113,7 +113,7 @@ pub use crate::call_executor::{CallExecutor, LocalCallExecutor}; pub use crate::client::{ new_with_backend, new_in_mem, - BlockBody, BlockStatus, ImportNotifications, FinalityNotifications, BlockchainEvents, + BlockBody, ImportNotifications, FinalityNotifications, BlockchainEvents, BlockImportNotification, Client, ClientInfo, ExecutionStrategies, FinalityNotification, LongestChain, BlockOf, ProvideUncles, utils, apply_aux, diff --git a/core/consensus/common/src/block_validation.rs b/core/consensus/common/src/block_validation.rs new file mode 100644 index 0000000000..be181b05c6 --- /dev/null +++ b/core/consensus/common/src/block_validation.rs @@ -0,0 +1,66 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. +// +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Block announcement validation. + +use crate::BlockStatus; +use sr_primitives::{generic::BlockId, traits::Block}; +use std::{error::Error, sync::Arc}; + +/// A type which provides access to chain information. +pub trait Chain { + /// Retrieve the status of the block denoted by the given [`BlockId`]. + fn block_status(&self, id: &BlockId) -> Result>; +} + +impl, B: Block> Chain for Arc { + fn block_status(&self, id: &BlockId) -> Result> { + (&**self).block_status(id) + } +} + +/// Result of `BlockAnnounceValidator::validate`. +#[derive(Debug, PartialEq, Eq)] +pub enum Validation { + /// Valid block announcement. + Success, + /// Invalid block announcement. + Failure, +} + +/// Type which checks incoming block announcements. +pub trait BlockAnnounceValidator { + /// Validate the announced header and its associated data. + fn validate(&mut self, header: &B::Header, data: &[u8]) -> Result>; +} + +/// Default implementation of `BlockAnnounceValidator`. +#[derive(Debug)] +pub struct DefaultBlockAnnounceValidator { + chain: C +} + +impl DefaultBlockAnnounceValidator { + pub fn new(chain: C) -> Self { + Self { chain } + } +} + +impl> BlockAnnounceValidator for DefaultBlockAnnounceValidator { + fn validate(&mut self, _h: &B::Header, _d: &[u8]) -> Result> { + Ok(Validation::Success) + } +} diff --git a/core/consensus/common/src/lib.rs b/core/consensus/common/src/lib.rs index a79bd157e2..d0f42d8b33 100644 --- a/core/consensus/common/src/lib.rs +++ b/core/consensus/common/src/lib.rs @@ -35,6 +35,7 @@ use sr_primitives::traits::{Block as BlockT, DigestFor}; use futures::prelude::*; pub use inherents::InherentData; +pub mod block_validation; pub mod offline_tracker; pub mod error; pub mod block_import; @@ -52,6 +53,21 @@ pub use block_import::{ }; pub use select_chain::SelectChain; +/// Block status. +#[derive(Debug, PartialEq, Eq)] +pub enum BlockStatus { + /// Added to the import queue. + Queued, + /// Already in the blockchain and the state is available. + InChainWithState, + /// In the blockchain, but the state is not available. + InChainPruned, + /// Block or parent is known to be bad. + KnownBad, + /// Not in the queue or the blockchain. + Unknown, +} + /// Environment producer for a Consensus instance. Creates proposer instance and communication streams. pub trait Environment { /// The proposer type this creates. diff --git a/core/finality-grandpa/src/communication/mod.rs b/core/finality-grandpa/src/communication/mod.rs index 7185e93208..652c33c026 100644 --- a/core/finality-grandpa/src/communication/mod.rs +++ b/core/finality-grandpa/src/communication/mod.rs @@ -127,7 +127,7 @@ pub trait Network: Clone + Send + 'static { fn report(&self, who: network::PeerId, cost_benefit: i32); /// Inform peers that a block with given hash should be downloaded. - fn announce(&self, block: Block::Hash); + fn announce(&self, block: Block::Hash, associated_data: Vec); } /// Create a unique topic for a round and set-id combo. @@ -197,8 +197,8 @@ impl Network for Arc> where self.report_peer(who, cost_benefit) } - fn announce(&self, block: B::Hash) { - self.announce_block(block) + fn announce(&self, block: B::Hash, associated_data: Vec) { + self.announce_block(block, associated_data) } } @@ -727,7 +727,7 @@ impl> Sink for OutgoingMessages ); // send the target block hash to the background block announcer - self.announce_sender.send(target_hash); + self.announce_sender.send(target_hash, Vec::new()); // propagate the message to peers let topic = round_topic::(self.round, self.set_id); diff --git a/core/finality-grandpa/src/communication/periodic.rs b/core/finality-grandpa/src/communication/periodic.rs index 333178dec2..81c18891d0 100644 --- a/core/finality-grandpa/src/communication/periodic.rs +++ b/core/finality-grandpa/src/communication/periodic.rs @@ -118,7 +118,7 @@ pub(super) fn neighbor_packet_worker(net: N) -> ( /// A background worker for performing block announcements. struct BlockAnnouncer { net: N, - block_rx: mpsc::UnboundedReceiver, + block_rx: mpsc::UnboundedReceiver<(B::Hash, Vec)>, latest_voted_blocks: VecDeque, reannounce_after: Duration, delay: Delay, @@ -199,8 +199,8 @@ impl> Future for BlockAnnouncer { match self.block_rx.poll().expect("unbounded receivers do not error; qed") { Async::Ready(None) => return Ok(Async::Ready(())), Async::Ready(Some(block)) => { - if self.note_block(block) { - self.net.announce(block); + if self.note_block(block.0) { + self.net.announce(block.0, block.1); self.reset_delay(); } }, @@ -229,7 +229,7 @@ impl> Future for BlockAnnouncer { ); for block in self.latest_voted_blocks.iter() { - self.net.announce(*block); + self.net.announce(*block, Vec::new()); } }, Ok(Async::NotReady) => return Ok(Async::NotReady), @@ -240,15 +240,12 @@ impl> Future for BlockAnnouncer { /// A sender used to send block hashes to announce to a background job. #[derive(Clone)] -pub(super) struct BlockAnnounceSender(mpsc::UnboundedSender); +pub(super) struct BlockAnnounceSender(mpsc::UnboundedSender<(B::Hash, Vec)>); impl BlockAnnounceSender { /// Send a block hash for the background worker to announce. - pub fn send( - &self, - block: B::Hash, - ) { - if let Err(err) = self.0.unbounded_send(block) { + pub fn send(&self, block: B::Hash, associated_data: Vec) { + if let Err(err) = self.0.unbounded_send((block, associated_data)) { debug!(target: "afg", "Failed to send block to background announcer: {:?}", err); } } diff --git a/core/finality-grandpa/src/communication/tests.rs b/core/finality-grandpa/src/communication/tests.rs index 28de0e538c..6215e30b80 100644 --- a/core/finality-grandpa/src/communication/tests.rs +++ b/core/finality-grandpa/src/communication/tests.rs @@ -88,7 +88,7 @@ impl super::Network for TestNetwork { } /// Inform peers that a block with given hash should be downloaded. - fn announce(&self, block: Hash) { + fn announce(&self, block: Hash, _associated_data: Vec) { let _ = self.sender.unbounded_send(Event::Announce(block)); } } @@ -559,7 +559,7 @@ fn periodically_reannounce_voted_blocks_on_stall() { for _ in 0..=12 { let hash = Hash::random(); hashes.lock().push(hash); - announce_sender.send(hash); + announce_sender.send(hash, Vec::new()); } // we should see an event for each of those announcements diff --git a/core/network/src/chain.rs b/core/network/src/chain.rs index b7465685ae..d23068179f 100644 --- a/core/network/src/chain.rs +++ b/core/network/src/chain.rs @@ -16,10 +16,10 @@ //! Blockchain access trait -use client::{self, Client as SubstrateClient, ClientInfo, BlockStatus, CallExecutor}; +use client::{self, Client as SubstrateClient, ClientInfo, CallExecutor}; use client::error::Error; use client::light::fetcher::ChangesProof; -use consensus::{BlockImport, Error as ConsensusError}; +use consensus::{BlockImport, BlockStatus, Error as ConsensusError}; use sr_primitives::traits::{Block as BlockT, Header as HeaderT}; use sr_primitives::generic::{BlockId}; use sr_primitives::Justification; diff --git a/core/network/src/config.rs b/core/network/src/config.rs index 7392a4aaf7..0582fcb300 100644 --- a/core/network/src/config.rs +++ b/core/network/src/config.rs @@ -26,7 +26,7 @@ use crate::chain::{Client, FinalityProofProvider}; use crate::on_demand_layer::OnDemand; use crate::service::{ExHashT, TransactionPool}; use bitflags::bitflags; -use consensus::import_queue::ImportQueue; +use consensus::{block_validation::BlockAnnounceValidator, import_queue::ImportQueue}; use sr_primitives::traits::{Block as BlockT}; use std::sync::Arc; use libp2p::identity::{Keypair, secp256k1, ed25519}; @@ -80,6 +80,9 @@ pub struct Params { /// Customization of the network. Use this to plug additional networking capabilities. pub specialization: S, + + /// Type to check incoming block announcements. + pub block_announce_validator: Box + Send> } bitflags! { diff --git a/core/network/src/protocol.rs b/core/network/src/protocol.rs index ea993bdce0..b2cea2cd5c 100644 --- a/core/network/src/protocol.rs +++ b/core/network/src/protocol.rs @@ -23,14 +23,17 @@ use libp2p::core::{ConnectedPoint, nodes::Substream, muxing::StreamMuxerBox}; use libp2p::swarm::{ProtocolsHandler, IntoProtocolsHandler}; use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use primitives::storage::StorageKey; -use consensus::{import_queue::IncomingBlock, import_queue::Origin, BlockOrigin}; +use consensus::{ + BlockOrigin, + block_validation::BlockAnnounceValidator, + import_queue::{BlockImportResult, BlockImportError, IncomingBlock, Origin} +}; use sr_primitives::{generic::BlockId, ConsensusEngineId, Justification}; use sr_primitives::traits::{ Block as BlockT, Header as HeaderT, NumberFor, One, Zero, CheckedSub, SaturatedConversion }; -use consensus::import_queue::{BlockImportResult, BlockImportError}; -use message::{BlockAttributes, Direction, FromBlock, Message, RequestId}; +use message::{BlockAnnounce, BlockAttributes, Direction, FromBlock, Message, RequestId}; use message::generic::{Message as GenericMessage, ConsensusMessage}; use event::Event; use consensus_gossip::{ConsensusGossip, MessageRecipient as GossipMessageRecipient}; @@ -366,9 +369,16 @@ impl, H: ExHashT> Protocol { finality_proof_request_builder: Option>, protocol_id: ProtocolId, peerset_config: peerset::PeersetConfig, + block_announce_validator: Box + Send> ) -> error::Result<(Protocol, peerset::PeersetHandle)> { let info = chain.info(); - let sync = ChainSync::new(config.roles, chain.clone(), &info, finality_proof_request_builder); + let sync = ChainSync::new( + config.roles, + chain.clone(), + &info, + finality_proof_request_builder, + block_announce_validator, + ); let (peerset, peerset_handle) = peerset::Peerset::from_config(peerset_config); let versions = &((MIN_VERSION as u8)..=(CURRENT_VERSION as u8)).collect::>(); let behaviour = LegacyProto::new(protocol_id, versions, peerset); @@ -376,7 +386,7 @@ impl, H: ExHashT> Protocol { let protocol = Protocol { tick_timeout: Box::new(futures_timer::Interval::new(TICK_TIMEOUT).map(|v| Ok::<_, ()>(v)).compat()), propagate_timeout: Box::new(futures_timer::Interval::new(PROPAGATE_TIMEOUT).map(|v| Ok::<_, ()>(v)).compat()), - config: config, + config, context_data: ContextData { peers: HashMap::new(), chain, @@ -384,7 +394,7 @@ impl, H: ExHashT> Protocol { light_dispatch: LightDispatch::new(checker), genesis_hash: info.chain.genesis_hash, sync, - specialization: specialization, + specialization, consensus_gossip: ConsensusGossip::new(), handshaking_peers: HashMap::new(), transaction_pool, @@ -1010,7 +1020,7 @@ impl, H: ExHashT> Protocol { /// /// In chain-based consensus, we often need to make sure non-best forks are /// at least temporarily synced. - pub fn announce_block(&mut self, hash: B::Hash) { + pub fn announce_block(&mut self, hash: B::Hash, data: Vec) { let header = match self.context_data.chain.header(&BlockId::Hash(hash)) { Ok(Some(header)) => header, Ok(None) => { @@ -1030,10 +1040,10 @@ impl, H: ExHashT> Protocol { let is_best = self.context_data.chain.info().chain.best_hash == hash; debug!(target: "sync", "Reannouncing block {:?}", hash); - self.send_announcement(&header, is_best, true) + self.send_announcement(&header, data, is_best, true) } - fn send_announcement(&mut self, header: &B::Header, is_best: bool, force: bool) { + fn send_announcement(&mut self, header: &B::Header, data: Vec, is_best: bool, force: bool) { let hash = header.hash(); for (who, ref mut peer) in self.context_data.peers.iter_mut() { @@ -1050,7 +1060,12 @@ impl, H: ExHashT> Protocol { } } else { None - } + }, + data: if peer.info.protocol_version >= 4 { + Some(data.clone()) + } else { + None + }, }); self.behaviour.send_packet(who, message) @@ -1074,29 +1089,22 @@ impl, H: ExHashT> Protocol { self.send_message(who, GenericMessage::Status(status)) } - fn on_block_announce( - &mut self, - who: PeerId, - announce: message::BlockAnnounce - ) -> CustomMessageOutcome { - let header = announce.header; - let hash = header.hash(); - { - if let Some(ref mut peer) = self.context_data.peers.get_mut(&who) { - peer.known_blocks.insert(hash.clone()); - } + fn on_block_announce(&mut self, who: PeerId, announce: BlockAnnounce) -> CustomMessageOutcome { + let hash = announce.header.hash(); + if let Some(ref mut peer) = self.context_data.peers.get_mut(&who) { + peer.known_blocks.insert(hash.clone()); } self.light_dispatch.update_best_number(LightDispatchIn { behaviour: &mut self.behaviour, peerset: self.peerset_handle.clone(), - }, who.clone(), *header.number()); + }, who.clone(), *announce.header.number()); let is_their_best = match announce.state.unwrap_or(message::BlockState::Best) { message::BlockState::Best => true, message::BlockState::Normal => false, }; - match self.sync.on_block_announce(who.clone(), hash, &header, is_their_best) { + match self.sync.on_block_announce(who.clone(), hash, &announce, is_their_best) { sync::OnBlockAnnounce::Request(peer, req) => { self.send_message(peer, GenericMessage::BlockRequest(req)); return CustomMessageOutcome::None @@ -1131,7 +1139,7 @@ impl, H: ExHashT> Protocol { blocks: vec![ message::generic::BlockData { hash: hash, - header: Some(header), + header: Some(announce.header), body: None, receipt: None, message_queue: None, @@ -1156,7 +1164,7 @@ impl, H: ExHashT> Protocol { /// Call this when a block has been imported in the import queue and we should announce it on /// the network. - pub fn on_block_imported(&mut self, hash: B::Hash, header: &B::Header, is_best: bool) { + pub fn on_block_imported(&mut self, hash: B::Hash, header: &B::Header, data: Vec, is_best: bool) { if is_best { self.sync.update_chain_info(header); } @@ -1172,7 +1180,7 @@ impl, H: ExHashT> Protocol { } // send out block announcements - self.send_announcement(&header, is_best, false); + self.send_announcement(header, data, is_best, false); } /// Call this when a block has been finalized. The sync layer may have some additional diff --git a/core/network/src/protocol/message.rs b/core/network/src/protocol/message.rs index 2faa68a4e2..6560ed0f13 100644 --- a/core/network/src/protocol/message.rs +++ b/core/network/src/protocol/message.rs @@ -273,6 +273,8 @@ pub mod generic { pub header: H, /// Block state. TODO: Remove `Option` and custom encoding when v4 becomes common. pub state: Option, + /// Data associated with this block announcement, e.g. a candidate message. + pub data: Option>, } // Custom Encode/Decode impl to maintain backwards compatibility with v3. @@ -284,6 +286,9 @@ pub mod generic { if let Some(state) = &self.state { state.encode_to(dest); } + if let Some(data) = &self.data { + data.encode_to(dest) + } } } @@ -291,9 +296,11 @@ pub mod generic { fn decode(input: &mut I) -> Result { let header = H::decode(input)?; let state = BlockState::decode(input).ok(); + let data = Vec::decode(input).ok(); Ok(BlockAnnounce { header, state, + data, }) } } diff --git a/core/network/src/protocol/sync.rs b/core/network/src/protocol/sync.rs index 52e88034a3..cf7d899d6d 100644 --- a/core/network/src/protocol/sync.rs +++ b/core/network/src/protocol/sync.rs @@ -28,11 +28,15 @@ //! use blocks::BlockCollection; -use client::{BlockStatus, ClientInfo, error::Error as ClientError}; -use consensus::{BlockOrigin, import_queue::{IncomingBlock, BlockImportResult, BlockImportError}}; +use client::{ClientInfo, error::Error as ClientError}; +use consensus::{BlockOrigin, BlockStatus, + block_validation::{BlockAnnounceValidator, Validation}, + import_queue::{IncomingBlock, BlockImportResult, BlockImportError} +}; use crate::{ config::{Roles, BoxFinalityProofRequestBuilder}, - message::{self, generic::FinalityProofRequest, BlockAttributes, BlockRequest, BlockResponse, FinalityProofResponse}, + message::{self, generic::FinalityProofRequest, BlockAnnounce, BlockAttributes, BlockRequest, BlockResponse, + FinalityProofResponse}, protocol }; use either::Either; @@ -122,6 +126,8 @@ pub struct ChainSync { request_builder: Option>, /// A flag that caches idle state with no pending requests. is_idle: bool, + /// A type to check incoming block announcements. + block_announce_validator: Box + Send> } /// All the data we have about a Peer that we are trying to sync with @@ -271,7 +277,8 @@ impl ChainSync { role: Roles, client: Arc>, info: &ClientInfo, - request_builder: Option> + request_builder: Option>, + block_announce_validator: Box + Send> ) -> Self { let mut required_block_attributes = BlockAttributes::HEADER | BlockAttributes::JUSTIFICATION; @@ -293,6 +300,7 @@ impl ChainSync { best_importing_number: Zero::zero(), request_builder, is_idle: false, + block_announce_validator, } } @@ -885,9 +893,10 @@ impl ChainSync { /// header (call `on_block_data`). The network request isn't sent /// in this case. Both hash and header is passed as an optimization /// to avoid rehashing the header. - pub fn on_block_announce(&mut self, who: PeerId, hash: B::Hash, header: &B::Header, is_best: bool) + pub fn on_block_announce(&mut self, who: PeerId, hash: B::Hash, announce: &BlockAnnounce, is_best: bool) -> OnBlockAnnounce { + let header = &announce.header; let number = *header.number(); debug!(target: "sync", "Received block announcement with number {:?}", number); if number.is_zero() { @@ -932,6 +941,20 @@ impl ChainSync { return OnBlockAnnounce::Nothing } + // Let external validator check the block announcement. + let assoc_data = announce.data.as_ref().map_or(&[][..], |v| v.as_slice()); + match self.block_announce_validator.validate(&header, assoc_data) { + Ok(Validation::Success) => (), + Ok(Validation::Failure) => { + debug!(target: "sync", "block announcement validation of block {} from {} failed", hash, who); + return OnBlockAnnounce::Nothing + } + Err(e) => { + error!(target: "sync", "block announcement validation errored: {}", e); + return OnBlockAnnounce::Nothing + } + } + // stale block case let requires_additional_data = !self.role.is_light(); if number <= self.best_queued_number { diff --git a/core/network/src/service.rs b/core/network/src/service.rs index a1cba0395e..3ca7bffdb4 100644 --- a/core/network/src/service.rs +++ b/core/network/src/service.rs @@ -113,9 +113,7 @@ impl, H: ExHashT> NetworkWorker /// Returns a `NetworkWorker` that implements `Future` and must be regularly polled in order /// for the network processing to advance. From it, you can extract a `NetworkService` using /// `worker.service()`. The `NetworkService` can be shared through the codebase. - pub fn new( - params: Params, - ) -> Result, Error> { + pub fn new(params: Params) -> Result, Error> { let (to_worker, from_worker) = mpsc::unbounded(); if let Some(ref path) = params.network_config.net_config_path { @@ -178,6 +176,7 @@ impl, H: ExHashT> NetworkWorker params.finality_proof_request_builder, params.protocol_id, peerset_config, + params.block_announce_validator )?; // Build the swarm. @@ -297,8 +296,8 @@ impl, H: ExHashT> NetworkWorker } /// You must call this when a new block is imported by the client. - pub fn on_block_imported(&mut self, hash: B::Hash, header: B::Header, is_best: bool) { - self.network_service.user_protocol_mut().on_block_imported(hash, &header, is_best); + pub fn on_block_imported(&mut self, hash: B::Hash, header: B::Header, data: Vec, is_best: bool) { + self.network_service.user_protocol_mut().on_block_imported(hash, &header, data, is_best); } /// You must call this when a new block is finalized by the client. @@ -394,8 +393,8 @@ impl, H: ExHashT> NetworkServic /// /// In chain-based consensus, we often need to make sure non-best forks are /// at least temporarily synced. This function forces such an announcement. - pub fn announce_block(&self, hash: B::Hash) { - let _ = self.to_worker.unbounded_send(ServerToWorkerMsg::AnnounceBlock(hash)); + pub fn announce_block(&self, hash: B::Hash, data: Vec) { + let _ = self.to_worker.unbounded_send(ServerToWorkerMsg::AnnounceBlock(hash, data)); } /// Send a consensus message through the gossip @@ -580,7 +579,7 @@ impl NetworkStateInfo for NetworkService enum ServerToWorkerMsg> { PropagateExtrinsics, RequestJustification(B::Hash, NumberFor), - AnnounceBlock(B::Hash), + AnnounceBlock(B::Hash, Vec), ExecuteWithSpec(Box) + Send>), ExecuteWithGossip(Box, &mut dyn Context) + Send>), GossipConsensusMessage(B::Hash, ConsensusEngineId, Vec, GossipMessageRecipient), @@ -653,8 +652,8 @@ impl, H: ExHashT> Stream for Ne } ServerToWorkerMsg::GossipConsensusMessage(topic, engine_id, message, recipient) => self.network_service.user_protocol_mut().gossip_consensus_message(topic, engine_id, message, recipient), - ServerToWorkerMsg::AnnounceBlock(hash) => - self.network_service.user_protocol_mut().announce_block(hash), + ServerToWorkerMsg::AnnounceBlock(hash, data) => + self.network_service.user_protocol_mut().announce_block(hash, data), ServerToWorkerMsg::RequestJustification(hash, number) => self.network_service.user_protocol_mut().request_justification(&hash, number), ServerToWorkerMsg::PropagateExtrinsics => diff --git a/core/network/src/test/mod.rs b/core/network/src/test/mod.rs index 276bce9f39..ddc86b6e95 100644 --- a/core/network/src/test/mod.rs +++ b/core/network/src/test/mod.rs @@ -37,6 +37,7 @@ use client::{ use client::block_builder::BlockBuilder; use client::backend::{AuxStore, Backend, Finalizer}; use crate::config::Roles; +use consensus::block_validation::DefaultBlockAnnounceValidator; use consensus::import_queue::BasicQueue; use consensus::import_queue::{ BoxBlockImport, BoxJustificationImport, Verifier, BoxFinalityProofImport, @@ -254,8 +255,8 @@ impl> Peer { } /// Announces an important block on the network. - pub fn announce_block(&self, hash: ::Hash) { - self.network.service().announce_block(hash); + pub fn announce_block(&self, hash: ::Hash, data: Vec) { + self.network.service().announce_block(hash, data); } /// Add blocks to the peer -- edit the block before adding @@ -302,11 +303,11 @@ impl> Peer { Default::default() }; self.block_import.import_block(import_block, cache).expect("block_import failed"); - self.network.on_block_imported(hash, header, true); + self.network.on_block_imported(hash, header, Vec::new(), true); at = hash; } - self.network.service().announce_block(at.clone()); + self.network.service().announce_block(at.clone(), Vec::new()); at } @@ -555,6 +556,7 @@ pub trait TestNetFactory: Sized { protocol_id: ProtocolId::from(&b"test-protocol-name"[..]), import_queue, specialization: self::SpecializationFactory::create(), + block_announce_validator: Box::new(DefaultBlockAnnounceValidator::new(client.clone())) }).unwrap(); self.mut_peers(|peers| { @@ -628,6 +630,7 @@ pub trait TestNetFactory: Sized { protocol_id: ProtocolId::from(&b"test-protocol-name"[..]), import_queue, specialization: self::SpecializationFactory::create(), + block_announce_validator: Box::new(DefaultBlockAnnounceValidator::new(client.clone())) }).unwrap(); self.mut_peers(|peers| { @@ -690,7 +693,7 @@ pub trait TestNetFactory: Sized { // We poll `imported_blocks_stream`. while let Ok(Async::Ready(Some(notification))) = peer.imported_blocks_stream.poll() { - peer.network.on_block_imported(notification.hash, notification.header, true); + peer.network.on_block_imported(notification.hash, notification.header, Vec::new(), true); } // We poll `finality_notification_stream`, but we only take the last event. diff --git a/core/network/src/test/sync.rs b/core/network/src/test/sync.rs index 6cba21c171..d50190f657 100644 --- a/core/network/src/test/sync.rs +++ b/core/network/src/test/sync.rs @@ -444,7 +444,7 @@ fn can_sync_small_non_best_forks() { assert!(net.peer(0).client().header(&BlockId::Hash(small_hash)).unwrap().is_some()); assert!(!net.peer(1).client().header(&BlockId::Hash(small_hash)).unwrap().is_some()); - net.peer(0).announce_block(small_hash); + net.peer(0).announce_block(small_hash, Vec::new()); // after announcing, peer 1 downloads the block. @@ -499,7 +499,7 @@ fn light_peer_imports_header_from_announce() { let mut runtime = current_thread::Runtime::new().unwrap(); fn import_with_announce(net: &mut TestNet, runtime: &mut current_thread::Runtime, hash: H256) { - net.peer(0).announce_block(hash); + net.peer(0).announce_block(hash, Vec::new()); runtime.block_on(futures::future::poll_fn::<(), (), _>(|| { net.poll(); diff --git a/core/service/src/lib.rs b/core/service/src/lib.rs index 431776b31e..cf84df3ef6 100644 --- a/core/service/src/lib.rs +++ b/core/service/src/lib.rs @@ -190,6 +190,9 @@ macro_rules! new_impl { network::config::ProtocolId::from(protocol_id_full) }; + let block_announce_validator = + Box::new(consensus_common::block_validation::DefaultBlockAnnounceValidator::new(client.clone())); + let network_params = network::config::Params { roles: $config.roles, network_config: $config.network.clone(), @@ -201,6 +204,7 @@ macro_rules! new_impl { import_queue, protocol_id, specialization: network_protocol, + block_announce_validator, }; let has_bootnodes = !network_params.network_config.boot_nodes.is_empty(); @@ -682,7 +686,7 @@ fn build_network_future< // We poll `imported_blocks_stream`. while let Ok(Async::Ready(Some(notification))) = imported_blocks_stream.poll() { - network.on_block_imported(notification.hash, notification.header, notification.is_new_best); + network.on_block_imported(notification.hash, notification.header, Vec::new(), notification.is_new_best); } // We poll `finality_notification_stream`, but we only take the last event. -- GitLab From 58da1c760ef00ff44875d6cada668c31313b3059 Mon Sep 17 00:00:00 2001 From: Toralf Wittner Date: Tue, 24 Sep 2019 13:53:16 +0200 Subject: [PATCH 131/275] Fix invalid debug assertion. (#3663) The current `debug_assert_eq` is clearly wrong as the code handles zero response blocks. What should have been expressed is that we expect 0 or 1 response blocks. --- core/network/src/protocol/sync.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/network/src/protocol/sync.rs b/core/network/src/protocol/sync.rs index cf7d899d6d..59ad48b225 100644 --- a/core/network/src/protocol/sync.rs +++ b/core/network/src/protocol/sync.rs @@ -667,7 +667,7 @@ impl ChainSync { peer.state = PeerSyncState::Available; // We only request one justification at a time - debug_assert_eq!(1, response.blocks.len()); + debug_assert!(response.blocks.len() < 2); if let Some(block) = response.blocks.into_iter().next() { if hash != block.hash { -- GitLab From e0d486d617cbe24f0c91cd6aa0dfcfb6c4e4dcc2 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 24 Sep 2019 17:46:41 +0200 Subject: [PATCH 132/275] Fix head not hashed (#3680) * fix head not hashed * bump version --- node/runtime/src/lib.rs | 2 +- srml/support/procedural/src/storage/impls.rs | 10 +++++----- srml/support/src/storage/generator/linked_map.rs | 13 +++++++++---- srml/support/src/storage/storage_items.rs | 2 +- srml/support/test/tests/final_keys.rs | 4 ++++ 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 0bec78fe1f..962f3c9c73 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -84,7 +84,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 162, + spec_version: 163, impl_version: 163, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/support/procedural/src/storage/impls.rs b/srml/support/procedural/src/storage/impls.rs index a5b91eda78..ee6fa9a164 100644 --- a/srml/support/procedural/src/storage/impls.rs +++ b/srml/support/procedural/src/storage/impls.rs @@ -257,14 +257,14 @@ impl<'a, I: Iterator> Impls<'a, I> { }; // make sure to use different prefix for head and elements. - let final_head_key = if let Some(instance) = instance { + let head_key = if let Some(instance) = instance { let const_name = Ident::new( &format!("{}{}", HEAD_KEY_FOR, name.to_string()), proc_macro2::Span::call_site() ); quote!{ #instance::#const_name.as_bytes() } } else { - let final_head_key = format!("head of {}", prefix); - quote!{ #final_head_key.as_bytes() } + let head_key = format!("head of {}", prefix); + quote!{ #head_key.as_bytes() } }; let DeclStorageTypeInfos { typ, value_type, is_option, .. } = type_infos; @@ -308,8 +308,8 @@ impl<'a, I: Iterator> Impls<'a, I> { #final_prefix } - fn final_head_key() -> &'static [u8] { - #final_head_key + fn head_key() -> &'static [u8] { + #head_key } fn from_optional_value_to_query(v: Option<#typ>) -> Self::Query { diff --git a/srml/support/src/storage/generator/linked_map.rs b/srml/support/src/storage/generator/linked_map.rs index e1786d2120..2c69df4364 100644 --- a/srml/support/src/storage/generator/linked_map.rs +++ b/srml/support/src/storage/generator/linked_map.rs @@ -36,7 +36,7 @@ pub trait StorageLinkedMap { fn prefix() -> &'static [u8]; /// Key used to store linked map head. - fn final_head_key() -> &'static [u8]; + fn head_key() -> &'static [u8]; /// Convert an optionnal value retrieved from storage to the type queried. fn from_optional_value_to_query(v: Option) -> Self::Query; @@ -53,6 +53,11 @@ pub trait StorageLinkedMap { key.borrow().encode_to(&mut final_key); Self::Hasher::hash(&final_key) } + + /// Generate the hashed key for head + fn storage_linked_map_final_head_key() -> ::Output { + Self::Hasher::hash(Self::head_key()) + } } /// Linkage data of an element (it's successor and predecessor) @@ -181,7 +186,7 @@ where V: Codec, G: StorageLinkedMap { - unhashed::get(G::final_head_key()) + unhashed::get(G::storage_linked_map_final_head_key().as_ref()) } /// Overwrite current head pointer. @@ -194,8 +199,8 @@ where G: StorageLinkedMap { match head { - Some(head) => unhashed::put(G::final_head_key(), head), - None => unhashed::kill(G::final_head_key()), + Some(head) => unhashed::put(G::storage_linked_map_final_head_key().as_ref(), head), + None => unhashed::kill(G::storage_linked_map_final_head_key().as_ref()), } } diff --git a/srml/support/src/storage/storage_items.rs b/srml/support/src/storage/storage_items.rs index ac120c31e7..3abb390ab5 100644 --- a/srml/support/src/storage/storage_items.rs +++ b/srml/support/src/storage/storage_items.rs @@ -758,7 +758,7 @@ mod test3 { #[cfg(test)] #[allow(dead_code)] mod test_append_and_len { - use crate::storage::{StorageMap, StorageValue, StorageLinkedMap}; + use crate::storage::{StorageMap, StorageValue}; use runtime_io::{with_externalities, TestExternalities}; use codec::{Encode, Decode}; diff --git a/srml/support/test/tests/final_keys.rs b/srml/support/test/tests/final_keys.rs index 8c26ad1843..d53e0aa139 100644 --- a/srml/support/test/tests/final_keys.rs +++ b/srml/support/test/tests/final_keys.rs @@ -72,10 +72,14 @@ fn final_keys() { k.extend(1u32.encode()); assert_eq!(unhashed::get::(&runtime_io::twox_128(&k)), Some(2u32)); + let head = b"head of FinalKeys LinkedMap".to_vec(); + assert_eq!(unhashed::get::(&runtime_io::blake2_256(&head)), None); + LinkedMap::insert(1, 2); let mut k = b"FinalKeys LinkedMap".to_vec(); k.extend(1u32.encode()); assert_eq!(unhashed::get::(&runtime_io::blake2_256(&k)), Some(2u32)); + assert_eq!(unhashed::get::(&runtime_io::blake2_256(&head)), Some(1u32)); LinkedMap2::insert(1, 2); let mut k = b"FinalKeys LinkedMap2".to_vec(); -- GitLab From 7d7e74fb77b6bee2ce9d6ebafcae09caff2d0e50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Tue, 24 Sep 2019 18:47:06 +0100 Subject: [PATCH 133/275] node: update flaming fir (#3681) * node: reduce grandpa justification period to 512 blocks * node: update flaming fir chainspec --- node-template/src/service.rs | 2 +- node/cli/res/flaming-fir.json | 137 +++++++++++++++++----------------- node/cli/src/service.rs | 2 +- 3 files changed, 71 insertions(+), 70 deletions(-) diff --git a/node-template/src/service.rs b/node-template/src/service.rs index b625ff1109..843ccb7ee3 100644 --- a/node-template/src/service.rs +++ b/node-template/src/service.rs @@ -134,7 +134,7 @@ pub fn new_full(config: Configuration Date: Wed, 25 Sep 2019 19:34:31 +1200 Subject: [PATCH 134/275] Change `decl_storage!` to forbid default value for `Option` types (#3682) * Forbid default values for Option types in decl_storage! * fix test errors * bump impl_version --- node-template/runtime/src/template.rs | 2 +- node/runtime/src/lib.rs | 2 +- srml/staking/src/tests.rs | 2 +- .../procedural/src/storage/transformation.rs | 15 +++++++-- srml/support/src/storage/storage_items.rs | 31 ++++++------------- 5 files changed, 24 insertions(+), 28 deletions(-) diff --git a/node-template/runtime/src/template.rs b/node-template/runtime/src/template.rs index c1fa6f2d31..5a4225e63a 100644 --- a/node-template/runtime/src/template.rs +++ b/node-template/runtime/src/template.rs @@ -8,7 +8,7 @@ /// For more guidance on Substrate modules, see the example module /// https://github.com/paritytech/substrate/blob/master/srml/example/src/lib.rs -use support::{decl_module, decl_storage, decl_event, StorageValue, dispatch::Result}; +use support::{decl_module, decl_storage, decl_event, dispatch::Result}; use system::ensure_signed; /// The module's configuration trait. diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 962f3c9c73..306521b2cf 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -85,7 +85,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 163, - impl_version: 163, + impl_version: 164, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/staking/src/tests.rs b/srml/staking/src/tests.rs index d754cd8500..1d0beb6029 100644 --- a/srml/staking/src/tests.rs +++ b/srml/staking/src/tests.rs @@ -20,7 +20,7 @@ use super::*; use runtime_io::with_externalities; use sr_primitives::traits::OnInitialize; use sr_staking_primitives::offence::{OffenceDetails, OnOffenceHandler}; -use support::{assert_ok, assert_noop, assert_eq_uvec, StorageLinkedMap}; +use support::{assert_ok, assert_noop, assert_eq_uvec}; use mock::*; use support::traits::{Currency, ReservableCurrency}; diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index 73954522b1..4fc8f67c42 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -122,7 +122,7 @@ pub fn decl_storage_impl(input: TokenStream) -> TokenStream { &cratename, &storage_lines, &where_clause, - ); + ).unwrap_or_else(|err| err.to_compile_error()); let decl_store_items = decl_store_items( &storage_lines, @@ -637,7 +637,7 @@ fn decl_storage_items( cratename: &Ident, storage_lines: &ext::Punctuated, where_clause: &Option, -) -> TokenStream2 { +) -> syn::Result { let mut impls = TokenStream2::new(); let InstanceOpts { @@ -768,6 +768,14 @@ fn decl_storage_items( } = sline; let type_infos = get_type_infos(storage_type); + + if type_infos.is_option && default_value.inner.is_some() { + return Err(syn::Error::new_spanned( + default_value, + "Default values for Option types are not supported" + )); + } + let fielddefault = default_value.inner .as_ref() .map(|d| &d.expr) @@ -808,7 +816,8 @@ fn decl_storage_items( }; impls.extend(implementation) } - impls + + Ok(impls) } fn decl_store_items(storage_lines: &ext::Punctuated) -> TokenStream2 { diff --git a/srml/support/src/storage/storage_items.rs b/srml/support/src/storage/storage_items.rs index 3abb390ab5..b00134dbfe 100644 --- a/srml/support/src/storage/storage_items.rs +++ b/srml/support/src/storage/storage_items.rs @@ -300,10 +300,10 @@ mod tests { // non-getters: pub / $default /// Hello, this is doc! - U32 : Option = Some(3); + U32 : Option; pub PUBU32 : Option; - U32MYDEF : Option = None; - pub PUBU32MYDEF : Option = Some(3); + U32MYDEF : Option; + pub PUBU32MYDEF : Option; // getters: pub / $default // we need at least one type which uses T, otherwise GenesisConfig will complain. @@ -311,17 +311,17 @@ mod tests { pub PUBGETU32 get(pub_u32_getter) build(|config: &GenesisConfig| config.u32_getter_with_config): u32; GETU32WITHCONFIG get(u32_getter_with_config) config(): u32; pub PUBGETU32WITHCONFIG get(pub_u32_getter_with_config) config(): u32; - GETU32MYDEF get(u32_getter_mydef): Option = Some(4); + GETU32MYDEF get(u32_getter_mydef): Option; pub PUBGETU32MYDEF get(pub_u32_getter_mydef) config(): u32 = 3; GETU32WITHCONFIGMYDEF get(u32_getter_with_config_mydef) config(): u32 = 2; pub PUBGETU32WITHCONFIGMYDEF get(pub_u32_getter_with_config_mydef) config(): u32 = 1; - PUBGETU32WITHCONFIGMYDEFOPT get(pub_u32_getter_with_config_mydef_opt) config(): Option = Some(100); + PUBGETU32WITHCONFIGMYDEFOPT get(pub_u32_getter_with_config_mydef_opt) config(): Option; // map non-getters: pub / $default MAPU32 : map u32 => Option; pub PUBMAPU32 : map u32 => Option; - MAPU32MYDEF : map u32 => Option = None; - pub PUBMAPU32MYDEF : map u32 => Option = Some("hello".into()); + MAPU32MYDEF : map u32 => Option; + pub PUBMAPU32MYDEF : map u32 => Option; // map getters: pub / $default GETMAPU32 get(map_u32_getter): map u32 => String; @@ -332,7 +332,7 @@ mod tests { // linked map LINKEDMAPU32 : linked_map u32 => Option; - pub PUBLINKEDMAPU32MYDEF : linked_map u32 => Option = Some("hello".into()); + pub PUBLINKEDMAPU32MYDEF : linked_map u32 => Option; GETLINKEDMAPU32 get(linked_map_u32_getter): linked_map u32 => String; pub PUBGETLINKEDMAPU32MYDEF get(pub_linked_map_u32_getter_mydef): linked_map u32 => String = "pubmap".into(); @@ -688,7 +688,7 @@ mod tests { assert_eq!(config.pub_u32_getter_mydef, 3u32); assert_eq!(config.u32_getter_with_config_mydef, 2u32); assert_eq!(config.pub_u32_getter_with_config_mydef, 1u32); - assert_eq!(config.pub_u32_getter_with_config_mydef_opt, 100u32); + assert_eq!(config.pub_u32_getter_with_config_mydef_opt, 0u32); } } @@ -781,17 +781,14 @@ mod test_append_and_len { JustVec: Vec; JustVecWithDefault: Vec = vec![6, 9]; OptionVec: Option>; - OptionVecWithDefault: Option> = Some(vec![6, 9]); MapVec: map u32 => Vec; MapVecWithDefault: map u32 => Vec = vec![6, 9]; OptionMapVec: map u32 => Option>; - OptionMapVecWithDefault: map u32 => Option> = Some(vec![6, 9]); LinkedMapVec: linked_map u32 => Vec; LinkedMapVecWithDefault: linked_map u32 => Vec = vec![6, 9]; OptionLinkedMapVec: linked_map u32 => Option>; - OptionLinkedMapVecWithDefault: linked_map u32 => Option> = Some(vec![6, 9]); } } @@ -805,7 +802,6 @@ mod test_append_and_len { #[test] fn default_for_option() { with_externalities(&mut TestExternalities::default(), || { - assert_eq!(OptionVecWithDefault::get(), Some(vec![6, 9])); assert_eq!(OptionVec::get(), None); assert_eq!(JustVec::get(), vec![]); }); @@ -882,9 +878,6 @@ mod test_append_and_len { assert_eq!(OptionVec::get(), None); assert_eq!(OptionVec::decode_len(), Ok(0)); - assert_eq!(OptionVecWithDefault::get(), Some(vec![6, 9])); - assert_eq!(OptionVecWithDefault::decode_len(), Ok(2)); - // map assert_eq!(MapVec::get(0), vec![]); assert_eq!(MapVec::decode_len(0), Ok(0)); @@ -895,9 +888,6 @@ mod test_append_and_len { assert_eq!(OptionMapVec::get(0), None); assert_eq!(OptionMapVec::decode_len(0), Ok(0)); - assert_eq!(OptionMapVecWithDefault::get(0), Some(vec![6, 9])); - assert_eq!(OptionMapVecWithDefault::decode_len(0), Ok(2)); - // linked map assert_eq!(LinkedMapVec::get(0), vec![]); assert_eq!(LinkedMapVec::decode_len(0), Ok(0)); @@ -907,9 +897,6 @@ mod test_append_and_len { assert_eq!(OptionLinkedMapVec::get(0), None); assert_eq!(OptionLinkedMapVec::decode_len(0), Ok(0)); - - assert_eq!(OptionLinkedMapVecWithDefault::get(0), Some(vec![6, 9])); - assert_eq!(OptionLinkedMapVecWithDefault::decode_len(0), Ok(2)); }); } } -- GitLab From a2c77063547c768e56622339343f1607214afdfb Mon Sep 17 00:00:00 2001 From: Toralf Wittner Date: Wed, 25 Sep 2019 09:35:45 +0200 Subject: [PATCH 135/275] Remove `debug_assert!`ion. (#3678) --- core/network/src/protocol/sync.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/network/src/protocol/sync.rs b/core/network/src/protocol/sync.rs index 59ad48b225..6a2a207abc 100644 --- a/core/network/src/protocol/sync.rs +++ b/core/network/src/protocol/sync.rs @@ -667,8 +667,6 @@ impl ChainSync { peer.state = PeerSyncState::Available; // We only request one justification at a time - debug_assert!(response.blocks.len() < 2); - if let Some(block) = response.blocks.into_iter().next() { if hash != block.hash { info!( -- GitLab From dcfba440dab6e73efee868866cc10dccf56ea2e1 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Wed, 25 Sep 2019 09:36:24 +0200 Subject: [PATCH 136/275] Document how to get head of linked map. (#3679) * Document how to get head of linked map. * Update srml/support/procedural/src/lib.rs Co-Authored-By: thiolliere * Update srml/support/procedural/src/lib.rs Co-Authored-By: thiolliere --- srml/support/procedural/src/lib.rs | 11 +++++++++++ srml/support/src/storage/generator/mod.rs | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/srml/support/procedural/src/lib.rs b/srml/support/procedural/src/lib.rs index 91e0aa2d4d..ea6a8a7995 100644 --- a/srml/support/procedural/src/lib.rs +++ b/srml/support/procedural/src/lib.rs @@ -79,6 +79,17 @@ use proc_macro::TokenStream; /// If the keys are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as /// `blake2_256` must be used. Otherwise, other values in storage can be compromised. /// +/// Once read from the trie (e.g. through an RPC call), a tuple of `(T, Linkage)` is returned, +/// where `T` is the value and `K` is the key type of the mapping. +/// [`Linkage`](../srml_support/storage/generator/struct.Linkage.html) is a pointer to the +/// previous and the next element. +/// +/// Each linked map has a special key in the trie that can be queried and it can be particularly +/// useful to query all items: `"head of " ++ module_name ++ " " ++ storage_name`). This will +/// return a key `K` that can be later on used with the aforementioned `$hash(module_name ++ " " +/// ++ storage_name ++ encoding(K))` to fetch the head. For consequent elements, the +/// [`Linkage`](../srml_support/storage/generator/struct.Linkage.html) can be used. +/// /// * Double map: `Foo: double_map hasher($hash1) u32, $hash2(u32) => u32`: Implements the /// [`StorageDoubleMap`](../srml_support/storage/trait.StorageDoubleMap.html) trait using the /// [`StorageDoubleMap generator`](../srml_support/storage/generator/trait.StorageDoubleMap.html). diff --git a/srml/support/src/storage/generator/mod.rs b/srml/support/src/storage/generator/mod.rs index a53ce7a831..ab7616158a 100644 --- a/srml/support/src/storage/generator/mod.rs +++ b/srml/support/src/storage/generator/mod.rs @@ -26,7 +26,7 @@ mod map; mod double_map; mod value; -pub use linked_map::{StorageLinkedMap, Enumerator}; +pub use linked_map::{StorageLinkedMap, Enumerator, Linkage}; pub use map::StorageMap; pub use double_map::StorageDoubleMap; pub use value::StorageValue; -- GitLab From 759ecfcaad312a8325b135761f7b4720dda96bc0 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Wed, 25 Sep 2019 11:21:05 +0200 Subject: [PATCH 137/275] Refactor: fixed point arithmetic for SRML. (#3456) * Macro-ify perthings. * Refactor fixed64 * Half-workign phragmen refactor. * Finalize phragmen refactor. * Fix creation of perquintill * Fix build errors * Line-width * Fix more build errors. * Line-width * Fix offence test * Resolve all TODOs. * Apply suggestions from code review Co-Authored-By: Gavin Wood Co-Authored-By: thiolliere * Fix most of the review comments. * Updates to multiply by rational * Fxi build * Fix abs issue with Fixed64 * Fix tests and improvements. * Fix build * Remove more tests from staking. * Review comments. * Add fuzzing stuff. * Better fuzzing * Better doc. * Bump. * Master.into() * A bit more hardening. * Final nits. * Update lock * Fix indent. * Revert lock file. * Bump. --- core/phragmen/benches/phragmen.rs | 34 +- core/phragmen/src/lib.rs | 146 +-- core/phragmen/src/mock.rs | 27 +- core/phragmen/src/tests.rs | 224 +++- core/sr-primitives/Cargo.toml | 1 + core/sr-primitives/src/curve.rs | 6 +- core/sr-primitives/src/lib.rs | 531 +-------- core/sr-primitives/src/sr_arithmetic.rs | 1373 +++++++++++++++++++++++ core/sr-primitives/src/weights.rs | 2 +- node/executor/src/lib.rs | 3 +- node/runtime/src/lib.rs | 2 +- srml/im-online/src/lib.rs | 10 +- srml/offences/src/lib.rs | 11 +- srml/staking/reward-curve/src/lib.rs | 4 +- srml/staking/src/inflation.rs | 9 +- srml/staking/src/lib.rs | 87 +- srml/staking/src/mock.rs | 4 +- srml/staking/src/tests.rs | 359 ++---- srml/support/src/lib.rs | 31 - 19 files changed, 1906 insertions(+), 958 deletions(-) create mode 100644 core/sr-primitives/src/sr_arithmetic.rs diff --git a/core/phragmen/benches/phragmen.rs b/core/phragmen/benches/phragmen.rs index ae1daac468..fec849ab93 100644 --- a/core/phragmen/benches/phragmen.rs +++ b/core/phragmen/benches/phragmen.rs @@ -24,7 +24,7 @@ use test::Bencher; use rand::{self, Rng}; extern crate substrate_phragmen as phragmen; -use phragmen::{Support, SupportMap, ACCURACY}; +use phragmen::{Support, SupportMap, PhragmenStakedAssignment}; use std::collections::BTreeMap; use sr_primitives::traits::{Convert, SaturatedConversion}; @@ -100,11 +100,10 @@ fn do_phragmen( // Do the benchmarking with equalize. if eq_iters > 0 { let elected_stashes = r.winners; - let mut assignments = r.assignments; + let assignments = r.assignments; let to_votes = |b: Balance| >::convert(b) as u128; - let ratio_of = |b, r: u128| r.saturating_mul(to_votes(b)) / ACCURACY; // Initialize the support of each candidate. let mut supports = >::new(); @@ -116,22 +115,37 @@ fn do_phragmen( supports.insert(e.clone(), item); }); - for (n, assignment) in assignments.iter_mut() { - for (c, r) in assignment.iter_mut() { - let nominator_stake = slashable_balance(n); - let other_stake = ratio_of(nominator_stake, *r); + // build support struct. + for (n, assignment) in assignments.iter() { + for (c, per_thing) in assignment.iter() { + let nominator_stake = to_votes(slashable_balance(n)); + let other_stake = *per_thing * nominator_stake; if let Some(support) = supports.get_mut(c) { support.total = support.total.saturating_add(other_stake); support.others.push((n.clone(), other_stake)); } - *r = other_stake; } } + let mut staked_assignments + : Vec<(AccountId, Vec>)> + = Vec::with_capacity(assignments.len()); + for (n, assignment) in assignments.iter() { + let mut staked_assignment + : Vec> + = Vec::with_capacity(assignment.len()); + for (c, per_thing) in assignment.iter() { + let nominator_stake = to_votes(slashable_balance(n)); + let other_stake = *per_thing * nominator_stake; + staked_assignment.push((c.clone(), other_stake)); + } + staked_assignments.push((n.clone(), staked_assignment)); + } + let tolerance = 0_u128; let iterations = 2_usize; - phragmen::equalize::<_, _, _, TestCurrencyToVote>( - assignments, + phragmen::equalize::<_, _, TestCurrencyToVote, _>( + staked_assignments, &mut supports, tolerance, iterations, diff --git a/core/phragmen/src/lib.rs b/core/phragmen/src/lib.rs index 2d4580d2e0..8ea3d55552 100644 --- a/core/phragmen/src/lib.rs +++ b/core/phragmen/src/lib.rs @@ -34,15 +34,12 @@ #![cfg_attr(not(feature = "std"), no_std)] use rstd::{prelude::*, collections::btree_map::BTreeMap}; -use sr_primitives::PerU128; -use sr_primitives::traits::{Zero, Convert, Member, SimpleArithmetic}; +use sr_primitives::{helpers_128bit::multiply_by_rational_best_effort, Perbill, Rational128}; +use sr_primitives::traits::{Zero, Convert, Member, SimpleArithmetic, Saturating}; mod mock; mod tests; -/// Type used as the fraction. -type Fraction = PerU128; - /// A type in which performing operations on balances and stakes of candidates and voters are safe. /// /// This module's functions expect a `Convert` type to convert all balances to u64. Hence, u128 is @@ -51,16 +48,10 @@ type Fraction = PerU128; /// Balance types converted to `ExtendedBalance` are referred to as `Votes`. pub type ExtendedBalance = u128; -// this is only used while creating the candidate score. Due to reasons explained below -// The more accurate this is, the less likely we choose a wrong candidate. -// TODO: can be removed with proper use of per-things #2908 -const SCALE_FACTOR: ExtendedBalance = u32::max_value() as ExtendedBalance + 1; - -/// These are used to expose a fixed accuracy to the caller function. The bigger they are, -/// the more accurate we get, but the more likely it is for us to overflow. The case of overflow -/// is handled but accuracy will be lost. 32 or 16 are reasonable values. -// TODO: can be removed with proper use of per-things #2908 -pub const ACCURACY: ExtendedBalance = u32::max_value() as ExtendedBalance + 1; +/// The denominator used for loads. Since votes are collected as u64, the smallest ratio that we +/// might collect is `1/approval_stake` where approval stake is the sum of votes. Hence, some number +/// bigger than u64::max_value() is needed. For maximum accuracy we simply use u128; +const DEN: u128 = u128::max_value(); /// A candidate entity for phragmen election. #[derive(Clone, Default)] @@ -69,7 +60,7 @@ pub struct Candidate { /// Identifier. pub who: AccountId, /// Intermediary value used to sort candidates. - pub score: Fraction, + pub score: Rational128, /// Sum of the stake of this candidate based on received votes. approval_stake: ExtendedBalance, /// Flag for being elected. @@ -87,7 +78,7 @@ pub struct Voter { /// The stake of this voter. budget: ExtendedBalance, /// Incremented each time a candidate that this voter voted for has been elected. - load: Fraction, + load: Rational128, } /// A candidate being backed by a voter. @@ -97,13 +88,16 @@ pub struct Edge { /// Identifier. who: AccountId, /// Load of this vote. - load: Fraction, + load: Rational128, /// Index of the candidate stored in the 'candidates' vector. candidate_index: usize, } -/// Means a particular `AccountId` was backed by a ratio of `ExtendedBalance / ACCURACY`. -pub type PhragmenAssignment = (AccountId, ExtendedBalance); +/// Means a particular `AccountId` was backed by `Perbill`th of a nominator's stake. +pub type PhragmenAssignment = (AccountId, Perbill); + +/// Means a particular `AccountId` was backed by `ExtendedBalance` of a nominator's stake. +pub type PhragmenStakedAssignment = (AccountId, ExtendedBalance); /// Final result of the phragmen election. #[cfg_attr(feature = "std", derive(Debug))] @@ -131,7 +125,7 @@ pub struct Support { /// Total support. pub total: ExtendedBalance, /// Support from voters. - pub others: Vec>, + pub others: Vec>, } /// A linkage from a candidate and its [`Support`]. @@ -164,8 +158,7 @@ pub fn elect( for<'r> FS: Fn(&'r AccountId) -> Balance, C: Convert + Convert, { - let to_votes = |b: Balance| - >::convert(b) as ExtendedBalance; + let to_votes = |b: Balance| >::convert(b) as ExtendedBalance; // return structures let mut elected_candidates: Vec<(AccountId, ExtendedBalance)>; @@ -192,7 +185,7 @@ pub fn elect( who: c.who.clone(), edges: vec![Edge { who: c.who.clone(), candidate_index: i, ..Default::default() }], budget: c.approval_stake, - load: Fraction::zero(), + load: Rational128::zero(), }); c_idx_cache.insert(c.who.clone(), i); c @@ -229,7 +222,7 @@ pub fn elect( who, edges: edges, budget: to_votes(voter_stake), - load: Fraction::zero(), + load: Rational128::zero(), } })); @@ -245,24 +238,29 @@ pub fn elect( // loop 1: initialize score for c in &mut candidates { if !c.elected { - c.score = Fraction::from_xth(c.approval_stake); + // 1 / approval_stake == (DEN / approval_stake) / DEN. If approval_stake is zero, + // then the ratio should be as large as possible, essentially `infinity`. + if c.approval_stake.is_zero() { + c.score = Rational128::from_unchecked(DEN, 0); + } else { + c.score = Rational128::from(DEN / c.approval_stake, DEN); + } } } + // loop 2: increment score for n in &voters { for e in &n.edges { let c = &mut candidates[e.candidate_index]; if !c.elected && !c.approval_stake.is_zero() { - // Basic fixed-point shifting by 32. - // `n.budget.saturating_mul(SCALE_FACTOR)` will never saturate - // since n.budget cannot exceed u64,despite being stored in u128. yet, - // `*n.load / SCALE_FACTOR` might collapse to zero. Hence, 32 or 16 bits are - // better scale factors. Note that left-associativity in operators precedence is - // crucially important here. - let temp = - n.budget.saturating_mul(SCALE_FACTOR) / c.approval_stake - * (*n.load / SCALE_FACTOR); - c.score = Fraction::from_parts((*c.score).saturating_add(temp)); + let temp_n = multiply_by_rational_best_effort( + n.load.n(), + n.budget, + c.approval_stake, + ); + let temp_d = n.load.d(); + let temp = Rational128::from(temp_n, temp_d); + c.score = c.score.lazy_saturating_add(temp); } } } @@ -271,14 +269,14 @@ pub fn elect( if let Some(winner) = candidates .iter_mut() .filter(|c| !c.elected) - .min_by_key(|c| *c.score) + .min_by_key(|c| c.score) { // loop 3: update voter and edge load winner.elected = true; for n in &mut voters { for e in &mut n.edges { if e.who == winner.who { - e.load = Fraction::from_parts(*winner.score - *n.load); + e.load = winner.score.lazy_saturating_sub(n.load); n.load = winner.score; } } @@ -296,48 +294,64 @@ pub fn elect( for e in &mut n.edges { if let Some(c) = elected_candidates.iter().cloned().find(|(c, _)| *c == e.who) { if c.0 != n.who { - let ratio = { - // Full support. No need to calculate. - if *n.load == *e.load { ACCURACY } - else { - // This should not saturate. Safest is to just check - if let Some(r) = ACCURACY.checked_mul(*e.load) { - r / n.load.max(1) + let per_bill_parts = + { + if n.load == e.load { + // Full support. No need to calculate. + Perbill::accuracy().into() + } else { + if e.load.d() == n.load.d() { + // return e.load / n.load. + let desired_scale: u128 = Perbill::accuracy().into(); + multiply_by_rational_best_effort( + desired_scale, + e.load.n(), + n.load.n(), + ) } else { - // Just a simple trick. - *e.load / (n.load.max(1) / ACCURACY) + // defensive only. Both edge and nominator loads are built from + // scores, hence MUST have the same denominator. + Zero::zero() } } }; - assignment.1.push((e.who.clone(), ratio)); + // safer to .min() inside as well to argue as u32 is safe. + let per_thing = Perbill::from_parts( + per_bill_parts.min(Perbill::accuracy().into()) as u32 + ); + assignment.1.push((e.who.clone(), per_thing)); } } } if assignment.1.len() > 0 { - // To ensure an assertion indicating: no stake from the voter going to waste, we add - // a minimal post-processing to equally assign all of the leftover stake ratios. - let vote_count = assignment.1.len() as ExtendedBalance; - let l = assignment.1.len(); - let sum = assignment.1.iter().map(|a| a.1).sum::(); - let diff = ACCURACY.checked_sub(sum).unwrap_or(0); - let diff_per_vote= diff / vote_count; + // To ensure an assertion indicating: no stake from the nominator going to waste, + // we add a minimal post-processing to equally assign all of the leftover stake ratios. + let vote_count = assignment.1.len() as u32; + let len = assignment.1.len(); + let sum = assignment.1.iter() + .map(|a| a.1.deconstruct()) + .sum::(); + let accuracy = Perbill::accuracy(); + let diff = accuracy.checked_sub(sum).unwrap_or(0); + let diff_per_vote = (diff / vote_count).min(accuracy); if diff_per_vote > 0 { - for i in 0..l { - assignment.1[i%l].1 = - assignment.1[i%l].1 - .saturating_add(diff_per_vote); + for i in 0..len { + let current_ratio = assignment.1[i % len].1; + let next_ratio = current_ratio + .saturating_add(Perbill::from_parts(diff_per_vote)); + assignment.1[i % len].1 = next_ratio; } } - // `remainder` is set to be less than maximum votes of a voter (currently 16). + // `remainder` is set to be less than maximum votes of a nominator (currently 16). // safe to cast it to usize. let remainder = diff - diff_per_vote * vote_count; for i in 0..remainder as usize { - assignment.1[i%l].1 = - assignment.1[i%l].1 - .saturating_add(1); + let current_ratio = assignment.1[i % len].1; + let next_ratio = current_ratio.saturating_add(Perbill::from_parts(1)); + assignment.1[i % len].1 = next_ratio; } assigned.push(assignment); } @@ -360,8 +374,8 @@ pub fn elect( /// * `tolerance`: maximum difference that can occur before an early quite happens. /// * `iterations`: maximum number of iterations that will be processed. /// * `stake_of`: something that can return the stake stake of a particular candidate or voter. -pub fn equalize( - mut assignments: Vec<(AccountId, Vec>)>, +pub fn equalize( + mut assignments: Vec<(AccountId, Vec>)>, supports: &mut SupportMap, tolerance: ExtendedBalance, iterations: usize, @@ -399,7 +413,7 @@ pub fn equalize( fn do_equalize( voter: &AccountId, budget_balance: Balance, - elected_edges: &mut Vec<(AccountId, ExtendedBalance)>, + elected_edges: &mut Vec>, support_map: &mut SupportMap, tolerance: ExtendedBalance ) -> ExtendedBalance where diff --git a/core/phragmen/src/mock.rs b/core/phragmen/src/mock.rs index e4f220affc..ee4e1eb4bb 100644 --- a/core/phragmen/src/mock.rs +++ b/core/phragmen/src/mock.rs @@ -18,10 +18,12 @@ #![cfg(test)] -use crate::{elect, ACCURACY, PhragmenResult}; -use sr_primitives::traits::{Convert, Member, SaturatedConversion}; +use crate::{elect, PhragmenResult, PhragmenAssignment}; +use sr_primitives::{ + assert_eq_error_rate, Perbill, + traits::{Convert, Member, SaturatedConversion} +}; use rstd::collections::btree_map::BTreeMap; -use support::assert_eq_error_rate; pub(crate) struct TestCurrencyToVote; impl Convert for TestCurrencyToVote { @@ -343,6 +345,14 @@ pub(crate) fn create_stake_of(stakes: &[(AccountId, Balance)]) Box::new(stake_of) } + +pub fn check_assignments(assignments: Vec<(AccountId, Vec>)>) { + for (_, a) in assignments { + let sum: u32 = a.iter().map(|(_, p)| p.deconstruct()).sum(); + assert_eq_error_rate!(sum, Perbill::accuracy(), 5); + } +} + pub(crate) fn run_and_compare( candidates: Vec, voters: Vec<(AccountId, Vec)>, @@ -375,9 +385,13 @@ pub(crate) fn run_and_compare( for (nominator, assigned) in assignments.clone() { if let Some(float_assignments) = truth_value.assignments.iter().find(|x| x.0 == nominator) { - for (candidate, ratio) in assigned { + for (candidate, per_thingy) in assigned { if let Some(float_assignment) = float_assignments.1.iter().find(|x| x.0 == candidate ) { - assert_eq_error_rate!((float_assignment.1 * ACCURACY as f64).round() as u128, ratio, 1); + assert_eq_error_rate!( + Perbill::from_fraction(float_assignment.1).deconstruct(), + per_thingy.deconstruct(), + 1, + ); } else { panic!("candidate mismatch. This should never happen.") } @@ -386,6 +400,8 @@ pub(crate) fn run_and_compare( panic!("nominator mismatch. This should never happen.") } } + + check_assignments(assignments); } pub(crate) fn build_support_map( @@ -414,6 +430,5 @@ pub(crate) fn build_support_map( *r = other_stake; } } - supports } diff --git a/core/phragmen/src/tests.rs b/core/phragmen/src/tests.rs index 750adb49ce..d3c5b1168c 100644 --- a/core/phragmen/src/tests.rs +++ b/core/phragmen/src/tests.rs @@ -19,8 +19,9 @@ #![cfg(test)] use crate::mock::*; -use crate::{elect, ACCURACY, PhragmenResult}; +use crate::{elect, PhragmenResult}; use support::assert_eq_uvec; +use sr_primitives::Perbill; #[test] fn float_phragmen_poc_works() { @@ -90,9 +91,9 @@ fn phragmen_poc_works() { assert_eq_uvec!( assignments, vec![ - (10, vec![(2, ACCURACY)]), - (20, vec![(3, ACCURACY)]), - (30, vec![(2, ACCURACY/2), (3, ACCURACY/2)]), + (10, vec![(2, Perbill::from_percent(100))]), + (20, vec![(3, Perbill::from_percent(100))]), + (30, vec![(2, Perbill::from_percent(100/2)), (3, Perbill::from_percent(100/2))]), ] ); } @@ -133,3 +134,218 @@ fn phragmen_poc_3_works() { run_and_compare(candidates, voters, stake_of, 2, 2, true); } + +#[test] +fn phragmen_accuracy_on_large_scale_only_validators() { + // because of this particular situation we had per_u128 and now rational128. In practice, a + // candidate can have the maximum amount of tokens, and also supported by the maximum. + let candidates = vec![1, 2, 3, 4, 5]; + let stake_of = create_stake_of(&[ + (1, (u64::max_value() - 1).into()), + (2, (u64::max_value() - 4).into()), + (3, (u64::max_value() - 5).into()), + (4, (u64::max_value() - 3).into()), + (5, (u64::max_value() - 2).into()), + ]); + + let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>( + 2, + 2, + candidates, + vec![], + stake_of, + true, + ).unwrap(); + + assert_eq_uvec!(winners, vec![(1, 18446744073709551614u128), (5, 18446744073709551613u128)]); + assert_eq!(assignments.len(), 0); + check_assignments(assignments); +} + +#[test] +fn phragmen_accuracy_on_large_scale_validators_and_nominators() { + let candidates = vec![1, 2, 3, 4, 5]; + let voters = vec![ + (13, vec![1, 3, 5]), + (14, vec![2, 4]), + ]; + let stake_of = create_stake_of(&[ + (1, (u64::max_value() - 1).into()), + (2, (u64::max_value() - 4).into()), + (3, (u64::max_value() - 5).into()), + (4, (u64::max_value() - 3).into()), + (5, (u64::max_value() - 2).into()), + (13, (u64::max_value() - 10).into()), + (14, u64::max_value().into()), + ]); + + let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>( + 2, + 2, + candidates, + voters, + stake_of, + true, + ).unwrap(); + + assert_eq_uvec!(winners, vec![(2, 36893488147419103226u128), (1, 36893488147419103219u128)]); + assert_eq!( + assignments, + vec![(13, vec![(1, Perbill::one())]), (14, vec![(2, Perbill::one())])] + ); + check_assignments(assignments); +} + +#[test] +fn phragmen_accuracy_on_small_scale_self_vote() { + let candidates = vec![40, 10, 20, 30]; + let voters = vec![]; + let stake_of = create_stake_of(&[ + (40, 0), + (10, 1), + (20, 2), + (30, 1), + ]); + + let PhragmenResult { winners, assignments: _ } = elect::<_, _, _, TestCurrencyToVote>( + 3, + 3, + candidates, + voters, + stake_of, + true, + ).unwrap(); + + assert_eq_uvec!(winners, vec![(20, 2), (10, 1), (30, 1)]); +} + +#[test] +fn phragmen_accuracy_on_small_scale_no_self_vote() { + let candidates = vec![40, 10, 20, 30]; + let voters = vec![ + (1, vec![10]), + (2, vec![20]), + (3, vec![30]), + (4, vec![40]), + ]; + let stake_of = create_stake_of(&[ + (40, 1000), // don't care + (10, 1000), // don't care + (20, 1000), // don't care + (30, 1000), // don't care + (4, 0), + (1, 1), + (2, 2), + (3, 1), + ]); + + let PhragmenResult { winners, assignments: _ } = elect::<_, _, _, TestCurrencyToVote>( + 3, + 3, + candidates, + voters, + stake_of, + false, + ).unwrap(); + + assert_eq_uvec!(winners, vec![(20, 2), (10, 1), (30, 1)]); +} + +#[test] +fn phragmen_large_scale_test() { + let candidates = vec![2, 4, 6, 8, 10, 12, 14, 16 ,18, 20, 22, 24]; + let voters = vec![ + (50, vec![2, 4, 6, 8, 10, 12, 14, 16 ,18, 20, 22, 24]), + ]; + let stake_of = create_stake_of(&[ + (2, 1), + (4, 100), + (6, 1000000), + (8, 100000000001000), + (10, 100000000002000), + (12, 100000000003000), + (14, 400000000000000), + (16, 400000000001000), + (18, 18000000000000000), + (20, 20000000000000000), + (22, 500000000000100000), + (24, 500000000000200000), + (50, 990000000000000000), + ]); + + let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>( + 2, + 2, + candidates, + voters, + stake_of, + true, + ).unwrap(); + + assert_eq_uvec!(winners, vec![(24, 1490000000000200000u128), (22, 1490000000000100000u128)]); + check_assignments(assignments); +} + +#[test] +fn phragmen_large_scale_test_2() { + let nom_budget: u64 = 1_000_000_000_000_000_000; + let c_budget: u64 = 4_000_000; + + let candidates = vec![2, 4]; + let voters = vec![(50, vec![2, 4])]; + + let stake_of = create_stake_of(&[ + (2, c_budget.into()), + (4, c_budget.into()), + (50, nom_budget.into()), + ]); + + let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>( + 2, + 2, + candidates, + voters, + stake_of, + true, + ).unwrap(); + + assert_eq_uvec!(winners, vec![(2, 1000000000004000000u128), (4, 1000000000004000000u128)]); + assert_eq!( + assignments, + vec![(50, vec![(2, Perbill::from_parts(500000001)), (4, Perbill::from_parts(499999999))])], + ); + check_assignments(assignments); +} + +#[test] +fn phragmen_linear_equalize() { + let candidates = vec![11, 21, 31, 41, 51, 61, 71]; + let voters = vec![ + (2, vec![11]), + (4, vec![11, 21]), + (6, vec![21, 31]), + (8, vec![31, 41]), + (110, vec![41, 51]), + (120, vec![51, 61]), + (130, vec![61, 71]), + ]; + let stake_of = create_stake_of(&[ + (11, 1000), + (21, 1000), + (31, 1000), + (41, 1000), + (51, 1000), + (61, 1000), + (71, 1000), + + (2, 2000), + (4, 1000), + (6, 1000), + (8, 1000), + (110, 1000), + (120, 1000), + (130, 1000), + ]); + + run_and_compare(candidates, voters, stake_of, 2, 2, true); +} diff --git a/core/sr-primitives/Cargo.toml b/core/sr-primitives/Cargo.toml index 5369674dca..db1819c3e6 100644 --- a/core/sr-primitives/Cargo.toml +++ b/core/sr-primitives/Cargo.toml @@ -21,6 +21,7 @@ impl-trait-for-tuples = "0.1.1" [dev-dependencies] serde_json = "1.0" primitive-types = "0.5.0" +rand = "0.7.2" [features] default = ["std"] diff --git a/core/sr-primitives/src/curve.rs b/core/sr-primitives/src/curve.rs index 447c57ee32..dc6316bd47 100644 --- a/core/sr-primitives/src/curve.rs +++ b/core/sr-primitives/src/curve.rs @@ -59,13 +59,13 @@ impl<'a> PiecewiseLinear<'a> { let delta_y = multiply_by_rational_saturating( abs_sub(n.clone(), prev.0 * d.clone()), - abs_sub(next.1.into_parts(), prev.1.into_parts()), + abs_sub(next.1.deconstruct(), prev.1.deconstruct()), // Must not saturate as prev abscissa > next abscissa - next.0.into_parts().saturating_sub(prev.0.into_parts()), + next.0.deconstruct().saturating_sub(prev.0.deconstruct()), ); // If both substration are same sign then result is positive - if (n > prev.0 * d.clone()) == (next.1.into_parts() > prev.1.into_parts()) { + if (n > prev.0 * d.clone()) == (next.1.deconstruct() > prev.1.deconstruct()) { (prev.1 * d).saturating_add(delta_y) // Otherwise result is negative } else { diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index 4d3bfb2c92..ddb935867e 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -17,7 +17,6 @@ //! Runtime Modules shared primitive types. #![warn(missing_docs)] - #![cfg_attr(not(feature = "std"), no_std)] #[doc(hidden)] @@ -37,10 +36,10 @@ pub use app_crypto; #[cfg(feature = "std")] pub use runtime_io::{StorageOverlay, ChildrenStorageOverlay}; -use rstd::{prelude::*, ops, convert::{TryInto, TryFrom}}; +use rstd::prelude::*; +use rstd::convert::TryFrom; use primitives::{crypto, ed25519, sr25519, hash::{H256, H512}}; -use codec::{Encode, Decode, CompactAs}; -use traits::{SaturatedConversion, UniqueSaturatedInto, Saturating, Bounded, CheckedSub, CheckedAdd}; +use codec::{Encode, Decode}; #[cfg(feature = "std")] pub mod testing; @@ -51,6 +50,7 @@ pub mod curve; pub mod generic; pub mod transaction_validity; +pub mod sr_arithmetic; /// Re-export these since they're only "kind of" generic. pub use generic::{DigestItem, Digest}; @@ -59,6 +59,14 @@ pub use generic::{DigestItem, Digest}; pub use primitives::crypto::{key_types, KeyTypeId, CryptoType}; pub use app_crypto::RuntimeAppPublic; +/// Re-export arithmetic stuff. +pub use sr_arithmetic::{ + Perquintill, Perbill, Permill, Percent, + Rational128, Fixed64 +}; +/// Re-export 128 bit helpers from sr_arithmetic +pub use sr_arithmetic::helpers_128bit; + /// An abstraction over justification for a block's validity under a consensus algorithm. /// /// Essentially a finality proof. The exact formulation will vary between consensus @@ -152,360 +160,6 @@ impl BuildStorage for (StorageOverlay, ChildrenStorageOverlay) { /// Consensus engine unique ID. pub type ConsensusEngineId = [u8; 4]; -/// Permill is parts-per-million (i.e. after multiplying by this, divide by 1000000). -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Ord, PartialOrd))] -#[derive(Encode, Decode, CompactAs, Default, Copy, Clone, PartialEq, Eq)] -pub struct Permill(u32); - -impl Permill { - /// Nothing. - pub fn zero() -> Self { Self(0) } - - /// `true` if this is nothing. - pub fn is_zero(&self) -> bool { self.0 == 0 } - - /// Everything. - pub fn one() -> Self { Self(1_000_000) } - - /// create a new raw instance. This can be called at compile time. - pub const fn from_const_parts(parts: u32) -> Self { - Self([parts, 1_000_000][(parts > 1_000_000) as usize]) - } - - /// From an explicitly defined number of parts per maximum of the type. - pub fn from_parts(parts: u32) -> Self { Self::from_const_parts(parts) } - - /// Converts from a percent. Equal to `x / 100`. - pub const fn from_percent(x: u32) -> Self { Self([x, 100][(x > 100) as usize] * 10_000) } - - /// Converts a fraction into `Permill`. - #[cfg(feature = "std")] - pub fn from_fraction(x: f64) -> Self { Self((x * 1_000_000.0) as u32) } - - /// Approximate the fraction `p/q` into a per million fraction - pub fn from_rational_approximation(p: N, q: N) -> Self - where N: traits::SimpleArithmetic + Clone - { - let p = p.min(q.clone()); - let factor = (q.clone() / 1_000_000u32.into()).max(1u32.into()); - - // Conversion can't overflow as p < q so ( p / (q/million)) < million - let p_reduce: u32 = (p / factor.clone()).try_into().unwrap_or_else(|_| panic!()); - let q_reduce: u32 = (q / factor.clone()).try_into().unwrap_or_else(|_| panic!()); - let part = p_reduce as u64 * 1_000_000u64 / q_reduce as u64; - - Permill(part as u32) - } -} - -impl ops::Mul for Permill -where - N: Clone + From + UniqueSaturatedInto + ops::Rem - + ops::Div + ops::Mul + ops::Add, -{ - type Output = N; - fn mul(self, b: N) -> Self::Output { - let million: N = 1_000_000.into(); - let part: N = self.0.into(); - - let rem_multiplied_divided = { - let rem = b.clone().rem(million.clone()); - - // `rem` is inferior to one million, thus it fits into u32 - let rem_u32 = rem.saturated_into::(); - - // `self` and `rem` are inferior to one million, thus the product is less than 10^12 - // and fits into u64 - let rem_multiplied_u64 = rem_u32 as u64 * self.0 as u64; - - // `rem_multiplied_u64` is less than 10^12 therefore divided by a million it fits into - // u32 - let rem_multiplied_divided_u32 = (rem_multiplied_u64 / 1_000_000) as u32; - - // `rem_multiplied_divided` is inferior to b, thus it can be converted back to N type - rem_multiplied_divided_u32.into() - }; - - (b / million) * part + rem_multiplied_divided - } -} - -#[cfg(feature = "std")] -impl From for Permill { - fn from(x: f64) -> Permill { - Permill::from_fraction(x) - } -} - -#[cfg(feature = "std")] -impl From for Permill { - fn from(x: f32) -> Permill { - Permill::from_fraction(x as f64) - } -} - -/// Perbill is parts-per-billion. It stores a value between 0 and 1 in fixed point and -/// provides a means to multiply some other value by that. -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -#[derive(Encode, Decode, CompactAs, Default, Copy, Clone, PartialEq, Eq, Ord, PartialOrd)] -pub struct Perbill(u32); - -impl Perbill { - /// Nothing. - pub fn zero() -> Self { Self(0) } - - /// `true` if this is nothing. - pub fn is_zero(&self) -> bool { self.0 == 0 } - - /// Everything. - pub fn one() -> Self { Self(1_000_000_000) } - - /// create a new raw instance. This can be called at compile time. - pub const fn from_const_parts(parts: u32) -> Self { - Self([parts, 1_000_000_000][(parts > 1_000_000_000) as usize]) - } - - /// From an explicitly defined number of parts per maximum of the type. - pub fn from_parts(parts: u32) -> Self { Self::from_const_parts(parts) } - - /// Converts from a percent. Equal to `x / 100`. - pub const fn from_percent(x: u32) -> Self { Self([x, 100][(x > 100) as usize] * 10_000_000) } - - /// Construct new instance where `x` is in millionths. Value equivalent to `x / 1,000,000`. - pub fn from_millionths(x: u32) -> Self { Self(x.min(1_000_000) * 1000) } - - #[cfg(feature = "std")] - /// Construct new instance whose value is equal to `x` (between 0 and 1). - pub fn from_fraction(x: f64) -> Self { Self((x.max(0.0).min(1.0) * 1_000_000_000.0) as u32) } - - /// Approximate the fraction `p/q` into a per billion fraction - pub fn from_rational_approximation(p: N, q: N) -> Self - where N: traits::SimpleArithmetic + Clone - { - let p = p.min(q.clone()); - let factor = (q.clone() / 1_000_000_000u32.into()).max(1u32.into()); - - // Conversion can't overflow as p < q so ( p / (q/billion)) < billion - let p_reduce: u32 = (p / factor.clone()).try_into().unwrap_or_else(|_| panic!()); - let q_reduce: u32 = (q / factor.clone()).try_into().unwrap_or_else(|_| panic!()); - let part = p_reduce as u64 * 1_000_000_000u64 / q_reduce as u64; - - Perbill(part as u32) - } - - /// Return the product of multiplication of this value by itself. - pub fn square(self) -> Self { - let p: u64 = self.0 as u64 * self.0 as u64; - let q: u64 = 1_000_000_000 * 1_000_000_000; - Self::from_rational_approximation(p, q) - } - - /// Take out the raw parts-per-billions. - pub fn into_parts(self) -> u32 { - self.0 - } -} - -impl ops::Mul for Perbill -where - N: Clone + From + UniqueSaturatedInto + ops::Rem - + ops::Div + ops::Mul + ops::Add, -{ - type Output = N; - fn mul(self, b: N) -> Self::Output { - let billion: N = 1_000_000_000.into(); - let part: N = self.0.into(); - - let rem_multiplied_divided = { - let rem = b.clone().rem(billion.clone()); - - // `rem` is inferior to one billion, thus it fits into u32 - let rem_u32 = rem.saturated_into::(); - - // `self` and `rem` are inferior to one billion, thus the product is less than 10^18 - // and fits into u64 - let rem_multiplied_u64 = rem_u32 as u64 * self.0 as u64; - - // `rem_multiplied_u64` is less than 10^18 therefore divided by a billion it fits into - // u32 - let rem_multiplied_divided_u32 = (rem_multiplied_u64 / 1_000_000_000) as u32; - - // `rem_multiplied_divided` is inferior to b, thus it can be converted back to N type - rem_multiplied_divided_u32.into() - }; - - (b / billion) * part + rem_multiplied_divided - } -} - -#[cfg(feature = "std")] -impl From for Perbill { - fn from(x: f64) -> Perbill { - Perbill::from_fraction(x) - } -} - -#[cfg(feature = "std")] -impl From for Perbill { - fn from(x: f32) -> Perbill { - Perbill::from_fraction(x as f64) - } -} - -/// A fixed point number by the scale of 1 billion. -/// -/// cannot hold a value larger than +-`9223372036854775807 / 1_000_000_000` (~9 billion). -#[cfg_attr(feature = "std", derive(Debug))] -#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct Fixed64(i64); - -/// The maximum value of the `Fixed64` type -const DIV: i64 = 1_000_000_000; - -impl Fixed64 { - /// creates self from a natural number. - /// - /// Note that this might be lossy. - pub fn from_natural(int: i64) -> Self { - Self(int.saturating_mul(DIV)) - } - - /// Return the accuracy of the type. Given that this function returns the value `X`, it means - /// that an instance composed of `X` parts (`Fixed64::from_parts(X)`) is equal to `1`. - pub fn accuracy() -> i64 { - DIV - } - - /// creates self from a rational number. Equal to `n/d`. - /// - /// Note that this might be lossy. - pub fn from_rational(n: i64, d: u64) -> Self { - Self((n as i128 * DIV as i128 / (d as i128).max(1)).try_into().unwrap_or(Bounded::max_value())) - } - - /// Performs a saturated multiply and accumulate. - /// - /// Returns a saturated `n + (self * n)`. - /// TODO: generalize this to any weight type. #3189 - pub fn saturated_multiply_accumulate(&self, int: u32) -> u32 { - let parts = self.0; - let positive = parts > 0; - - // natural parts might overflow. - let natural_parts = self.clone().saturated_into::(); - // fractional parts can always fit into u32. - let perbill_parts = (parts.abs() % DIV) as u32; - - let n = int.saturating_mul(natural_parts); - let p = Perbill::from_parts(perbill_parts) * int; - // everything that needs to be either added or subtracted from the original weight. - let excess = n.saturating_add(p); - - if positive { - int.saturating_add(excess) - } else { - int.saturating_sub(excess) - } - } - - /// Raw constructor. Equal to `parts / 1_000_000_000`. - pub fn from_parts(parts: i64) -> Self { - Self(parts) - } -} - -impl UniqueSaturatedInto for Fixed64 { - /// Note that the maximum value of Fixed64 might be more than what can fit in u32. This is hence, - /// expected to be lossy. - fn unique_saturated_into(self) -> u32 { - (self.0.abs() / DIV).try_into().unwrap_or(Bounded::max_value()) - } -} - -impl Saturating for Fixed64 { - fn saturating_add(self, rhs: Self) -> Self { - Self(self.0.saturating_add(rhs.0)) - } - fn saturating_mul(self, rhs: Self) -> Self { - Self(self.0.saturating_mul(rhs.0) / DIV) - } - fn saturating_sub(self, rhs: Self) -> Self { - Self(self.0.saturating_sub(rhs.0)) - } -} - -/// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait -/// for safe addition. -impl ops::Add for Fixed64 { - type Output = Self; - - fn add(self, rhs: Self) -> Self::Output { - Self(self.0 + rhs.0) - } -} - -/// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait -/// for safe subtraction. -impl ops::Sub for Fixed64 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self::Output { - Self(self.0 - rhs.0) - } -} - -impl CheckedSub for Fixed64 { - fn checked_sub(&self, rhs: &Self) -> Option { - if let Some(v) = self.0.checked_sub(rhs.0) { - Some(Self(v)) - } else { - None - } - } -} - -impl CheckedAdd for Fixed64 { - fn checked_add(&self, rhs: &Self) -> Option { - if let Some(v) = self.0.checked_add(rhs.0) { - Some(Self(v)) - } else { - None - } - } -} - -/// PerU128 is parts-per-u128-max-value. It stores a value between 0 and 1 in fixed point. -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -#[derive(Encode, Decode, CompactAs, Default, Copy, Clone, PartialEq, Eq)] -pub struct PerU128(u128); - -const U128: u128 = u128::max_value(); - -impl PerU128 { - /// Nothing. - pub fn zero() -> Self { Self(0) } - - /// `true` if this is nothing. - pub fn is_zero(&self) -> bool { self.0 == 0 } - - /// Everything. - pub fn one() -> Self { Self(U128) } - - /// From an explicitly defined number of parts per maximum of the type. - pub fn from_parts(x: u128) -> Self { Self(x) } - - /// Construct new instance where `x` is denominator and the nominator is 1. - pub fn from_xth(x: u128) -> Self { Self(U128/x.max(1)) } -} - -impl ::rstd::ops::Deref for PerU128 { - type Target = u128; - - fn deref(&self) -> &u128 { - &self.0 - } -} - /// Signature verify that can work with any known signature types.. #[derive(Eq, PartialEq, Clone, Encode, Decode)] #[cfg_attr(feature = "std", derive(Debug))] @@ -869,6 +523,37 @@ macro_rules! impl_outer_config { } } +/// Checks that `$x` is equal to `$y` with an error rate of `$error`. +/// +/// # Example +/// +/// ```rust +/// # fn main() { +/// sr_primitives::assert_eq_error_rate!(10, 10, 0); +/// sr_primitives::assert_eq_error_rate!(10, 11, 1); +/// sr_primitives::assert_eq_error_rate!(12, 10, 2); +/// # } +/// ``` +/// +/// ```rust,should_panic +/// # fn main() { +/// sr_primitives::assert_eq_error_rate!(12, 10, 1); +/// # } +/// ``` +#[macro_export] +#[cfg(feature = "std")] +macro_rules! assert_eq_error_rate { + ($x:expr, $y:expr, $error:expr $(,)?) => { + assert!( + ($x) >= (($y) - ($error)) && ($x) <= (($y) + ($error)), + "{:?} != {:?} (with error rate {:?})", + $x, + $y, + $error, + ); + }; +} + /// Simple blob to hold an extrinsic without committing to its format and ensure it is serialized /// correctly. #[derive(PartialEq, Eq, Clone, Default, Encode, Decode)] @@ -909,41 +594,8 @@ pub fn print(print: impl traits::Printable) { #[cfg(test)] mod tests { - use super::DispatchError; - use crate::codec::{Encode, Decode}; - use super::{Perbill, Permill}; - - macro_rules! per_thing_upper_test { - ($num_type:tt, $per:tt) => { - // multiplication from all sort of from_percent - assert_eq!($per::from_percent(100) * $num_type::max_value(), $num_type::max_value()); - assert_eq!( - $per::from_percent(99) * $num_type::max_value(), - ((Into::::into($num_type::max_value()) * 99u32) / 100u32).as_u128() as $num_type - ); - assert_eq!($per::from_percent(50) * $num_type::max_value(), $num_type::max_value() / 2); - assert_eq!($per::from_percent(1) * $num_type::max_value(), $num_type::max_value() / 100); - assert_eq!($per::from_percent(0) * $num_type::max_value(), 0); - - // multiplication with bounds - assert_eq!($per::one() * $num_type::max_value(), $num_type::max_value()); - assert_eq!($per::zero() * $num_type::max_value(), 0); - - // from_rational_approximation - assert_eq!( - $per::from_rational_approximation(u128::max_value() - 1, u128::max_value()), - $per::one(), - ); - assert_eq!( - $per::from_rational_approximation(u128::max_value()/3, u128::max_value()), - $per::from_parts($per::one().0/3), - ); - assert_eq!( - $per::from_rational_approximation(1, u128::max_value()), - $per::zero(), - ); - } - } + use crate::DispatchError; + use codec::{Encode, Decode}; #[test] fn opaque_extrinsic_serialization() { @@ -951,80 +603,6 @@ mod tests { assert_eq!(serde_json::to_string(&ex).unwrap(), "\"0x1001020304\"".to_owned()); } - #[test] - fn compact_permill_perbill_encoding() { - let tests = [(0u32, 1usize), (63, 1), (64, 2), (16383, 2), (16384, 4), (1073741823, 4), (1073741824, 5), (u32::max_value(), 5)]; - for &(n, l) in &tests { - let compact: crate::codec::Compact = Permill(n).into(); - let encoded = compact.encode(); - assert_eq!(encoded.len(), l); - let decoded = >::decode(&mut & encoded[..]).unwrap(); - let permill: Permill = decoded.into(); - assert_eq!(permill, Permill(n)); - - let compact: crate::codec::Compact = Perbill(n).into(); - let encoded = compact.encode(); - assert_eq!(encoded.len(), l); - let decoded = >::decode(&mut & encoded[..]).unwrap(); - let perbill: Perbill = decoded.into(); - assert_eq!(perbill, Perbill(n)); - } - } - - #[derive(Encode, Decode, PartialEq, Eq, Debug)] - struct WithCompact { - data: T, - } - - #[test] - fn test_has_compact_permill() { - let data = WithCompact { data: Permill(1) }; - let encoded = data.encode(); - assert_eq!(data, WithCompact::::decode(&mut &encoded[..]).unwrap()); - } - - #[test] - fn test_has_compact_perbill() { - let data = WithCompact { data: Perbill(1) }; - let encoded = data.encode(); - assert_eq!(data, WithCompact::::decode(&mut &encoded[..]).unwrap()); - } - - #[test] - fn per_things_should_work() { - use super::{Perbill, Permill}; - use primitive_types::U256; - - per_thing_upper_test!(u32, Perbill); - per_thing_upper_test!(u64, Perbill); - per_thing_upper_test!(u128, Perbill); - - per_thing_upper_test!(u32, Permill); - per_thing_upper_test!(u64, Permill); - per_thing_upper_test!(u128, Permill); - - } - - #[test] - fn per_things_operate_in_output_type() { - assert_eq!(Perbill::one() * 255_u64, 255); - } - - #[test] - fn per_things_one_minus_one_part() { - use primitive_types::U256; - - assert_eq!( - Perbill::from_parts(999_999_999) * std::u128::MAX, - ((Into::::into(std::u128::MAX) * 999_999_999u32) / 1_000_000_000u32).as_u128() - ); - - assert_eq!( - Permill::from_parts(999_999) * std::u128::MAX, - ((Into::::into(std::u128::MAX) * 999_999u32) / 1_000_000u32).as_u128() - ); - } - #[test] fn dispatch_error_encoding() { let error = DispatchError { @@ -1044,23 +622,4 @@ mod tests { }, ); } - - #[test] - fn per_bill_square() { - const FIXTURES: &[(u32, u32)] = &[ - (0, 0), - (1250000, 1562), // (0.00125, 0.000001562) - (255300000, 65178090), // (0.2553, 0.06517809) - (500000000, 250000000), // (0.5, 0.25) - (999995000, 999990000), // (0.999995, 0.999990000, but ideally 0.99999000002) - (1000000000, 1000000000), - ]; - - for &(x, r) in FIXTURES { - assert_eq!( - Perbill::from_parts(x).square(), - Perbill::from_parts(r), - ); - } - } } diff --git a/core/sr-primitives/src/sr_arithmetic.rs b/core/sr-primitives/src/sr_arithmetic.rs new file mode 100644 index 0000000000..20a7f51c1f --- /dev/null +++ b/core/sr-primitives/src/sr_arithmetic.rs @@ -0,0 +1,1373 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Minimal fixed point arithmetic primitives and types for runtime. + +#[cfg(feature = "std")] +use crate::serde::{Serialize, Deserialize}; + +use rstd::{ + ops, prelude::*, + convert::{TryInto, TryFrom}, + cmp::Ordering, +}; +use codec::{Encode, Decode}; +use crate::traits::{ + SaturatedConversion, CheckedSub, CheckedAdd, Bounded, UniqueSaturatedInto, Saturating, Zero, +}; + +macro_rules! implement_per_thing { + ($name:ident, $test_mod:ident, [$($test_units:tt),+], $max:tt, $type:ty, $upper_type:ty, $title:expr $(,)?) => { + /// A fixed point representation of a number between in the range [0, 1]. + /// + #[doc = $title] + #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Ord, PartialOrd))] + #[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq)] + pub struct $name($type); + + impl $name { + /// Nothing. + pub fn zero() -> Self { Self(0) } + + /// `true` if this is nothing. + pub fn is_zero(&self) -> bool { self.0 == 0 } + + /// Everything. + pub fn one() -> Self { Self($max) } + + /// Consume self and deconstruct into a raw numeric type. + pub fn deconstruct(self) -> $type { self.0 } + + /// Return the scale at which this per-thing is working. + pub const fn accuracy() -> $type { $max } + + /// From an explicitly defined number of parts per maximum of the type. + /// + /// This can be called at compile time. + pub const fn from_parts(parts: $type) -> Self { + Self([parts, $max][(parts > $max) as usize]) + } + + /// Converts from a percent. Equal to `x / 100`. + /// + /// This can be created at compile time. + pub const fn from_percent(x: $type) -> Self { + Self([x, 100][(x > 100) as usize] * ($max / 100)) + } + + /// Return the product of multiplication of this value by itself. + pub fn square(self) -> Self { + // both can be safely casted and multiplied. + let p: $upper_type = self.0 as $upper_type * self.0 as $upper_type; + let q: $upper_type = $max as $upper_type * $max as $upper_type; + Self::from_rational_approximation(p, q) + } + + /// Converts a fraction into `Permill`. + #[cfg(feature = "std")] + pub fn from_fraction(x: f64) -> Self { Self((x * ($max as f64)) as $type) } + + /// Approximate the fraction `p/q` into a per-thing fraction. This will never overflow. + /// + /// The computation of this approximation is performed in the generic type `N`. Given + /// `M` as the data type that can hold the maximum value of this per-thing (e.g. u32 for + /// perbill), this can only work if `N == M` or `N: From + TryInto`. + pub fn from_rational_approximation(p: N, q: N) -> Self + where N: Clone + Ord + From<$type> + TryInto<$type> + ops::Div + { + // q cannot be zero. + let q = q.max((1 as $type).into()); + // p should not be bigger than q. + let p = p.min(q.clone()); + + let factor = (q.clone() / $max.into()).max((1 as $type).into()); + + // q cannot overflow: (q / (q/$max)) < 2 * $max. p < q hence p also cannot overflow. + // this implies that $type must be able to fit 2 * $max. + let q_reduce: $type = (q / factor.clone()) + .try_into() + .map_err(|_| "Failed to convert") + .expect( + "q / (q/$max) < (2 * $max). Macro prevents any type being created that \ + does not satisfy this; qed" + ); + let p_reduce: $type = (p / factor.clone()) + .try_into() + .map_err(|_| "Failed to convert") + .expect( + "q / (q/$max) < (2 * $max). Macro prevents any type being created that \ + does not satisfy this; qed" + ); + + // `p_reduced` and `q_reduced` are withing $type. Mul by another $max will always + // fit in $upper_type. This is guaranteed by the macro tests. + let part = + p_reduce as $upper_type + * ($max as $upper_type) + / q_reduce as $upper_type; + + $name(part as $type) + } + } + + impl Saturating for $name { + fn saturating_add(self, rhs: Self) -> Self { + // defensive-only: since `$max * 2 < $type::max_value()`, this can never overflow. + Self::from_parts(self.0.saturating_add(rhs.0)) + } + fn saturating_sub(self, rhs: Self) -> Self { + Self::from_parts(self.0.saturating_sub(rhs.0)) + } + fn saturating_mul(self, rhs: Self) -> Self { + let a = self.0 as $upper_type; + let b = rhs.0 as $upper_type; + let m = $max as $upper_type; + let parts = a * b / m; + // This will always fit into $type. + Self::from_parts(parts as $type) + } + } + + impl ops::Div for $name { + type Output = Self; + + fn div(self, rhs: Self) -> Self::Output { + let p = self.0; + let q = rhs.0; + Self::from_rational_approximation(p, q) + } + } + + /// Overflow-prune multiplication. + /// + /// tailored to be used with a balance type. + impl ops::Mul for $name + where + N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem + + ops::Div + ops::Mul + ops::Add, + { + type Output = N; + fn mul(self, b: N) -> Self::Output { + let maximum: N = $max.into(); + let upper_max: $upper_type = $max.into(); + let part: N = self.0.into(); + + let rem_multiplied_divided = { + let rem = b.clone().rem(maximum.clone()); + + // `rem_sized` is inferior to $max, thus it fits into $type. This is assured by + // a test. + let rem_sized = rem.saturated_into::<$type>(); + + // `self` and `rem_sized` are inferior to $max, thus the product is less than + // $max^2 and fits into $upper_type. This is assured by a test. + let rem_multiplied_upper = rem_sized as $upper_type * self.0 as $upper_type; + + // `rem_multiplied_upper` is less than $max^2 therefore divided by $max it fits + // in $type. remember that $type always fits $max. + let mut rem_multiplied_divided_sized = + (rem_multiplied_upper / upper_max) as $type; + // fix a tiny rounding error + if rem_multiplied_upper % upper_max > upper_max / 2 { + rem_multiplied_divided_sized += 1; + } + + // `rem_multiplied_divided_sized` is inferior to b, thus it can be converted + // back to N type + rem_multiplied_divided_sized.into() + }; + + (b / maximum) * part + rem_multiplied_divided + } + } + + impl codec::CompactAs for $name { + type As = $type; + fn encode_as(&self) -> &$type { + &self.0 + } + fn decode_from(x: $type) -> Self { + Self(x) + } + } + + impl From> for $name { + fn from(x: codec::Compact<$name>) -> Self { + x.0 + } + } + + #[cfg(test)] + mod $test_mod { + use codec::{Encode, Decode}; + use super::{$name, Saturating}; + use crate::{assert_eq_error_rate, traits::Zero}; + + + #[test] + fn macro_expanded_correctly() { + // needed for the `from_percent` to work. + assert!($max >= 100); + assert!($max % 100 == 0); + + // needed for `from_rational_approximation` + assert!(2 * $max < <$type>::max_value()); + assert!(($max as $upper_type) < <$upper_type>::max_value()); + + // for something like percent they can be the same. + assert!((<$type>::max_value() as $upper_type) <= <$upper_type>::max_value()); + assert!(($max as $upper_type).checked_mul($max.into()).is_some()); + } + + #[derive(Encode, Decode, PartialEq, Eq, Debug)] + struct WithCompact { + data: T, + } + + #[test] + fn has_compact() { + let data = WithCompact { data: $name(1) }; + let encoded = data.encode(); + assert_eq!(data, WithCompact::<$name>::decode(&mut &encoded[..]).unwrap()); + } + + #[test] + fn compact_encoding() { + let tests = [ + // assume all per_things have the size u8 at least. + (0 as $type, 1usize), + (1 as $type, 1usize), + (63, 1), + (64, 2), + (65, 2), + (<$type>::max_value(), <$type>::max_value().encode().len() + 1) + ]; + for &(n, l) in &tests { + let compact: crate::codec::Compact<$name> = $name(n).into(); + let encoded = compact.encode(); + assert_eq!(encoded.len(), l); + let decoded = >::decode(&mut & encoded[..]) + .unwrap(); + let per_thingy: $name = decoded.into(); + assert_eq!(per_thingy, $name(n)); + } + } + + #[test] + fn per_thing_api_works() { + // some really basic stuff + assert_eq!($name::zero(), $name::from_parts(Zero::zero())); + assert_eq!($name::one(), $name::from_parts($max)); + assert_eq!($name::accuracy(), $max); + assert_eq!($name::from_percent(0), $name::from_parts(Zero::zero())); + assert_eq!($name::from_percent(10), $name::from_parts($max / 10)); + assert_eq!($name::from_percent(100), $name::from_parts($max)); + } + + macro_rules! per_thing_mul_test { + ($num_type:tt) => { + // multiplication from all sort of from_percent + assert_eq!( + $name::from_percent(100) * $num_type::max_value(), + $num_type::max_value() + ); + assert_eq_error_rate!( + $name::from_percent(99) * $num_type::max_value(), + ((Into::::into($num_type::max_value()) * 99u32) / 100u32).as_u128() as $num_type, + 1, + ); + assert_eq!( + $name::from_percent(50) * $num_type::max_value(), + $num_type::max_value() / 2, + ); + assert_eq_error_rate!( + $name::from_percent(1) * $num_type::max_value(), + $num_type::max_value() / 100, + 1, + ); + assert_eq!($name::from_percent(0) * $num_type::max_value(), 0); + + // // multiplication with bounds + assert_eq!($name::one() * $num_type::max_value(), $num_type::max_value()); + assert_eq!($name::zero() * $num_type::max_value(), 0); + } + } + + #[test] + fn per_thing_mul_works() { + use primitive_types::U256; + + // accuracy test + assert_eq!($name::from_rational_approximation(1 as $type, 3) * 30 as $type, 10); + + $(per_thing_mul_test!($test_units);)* + } + + #[test] + fn per_thing_mul_rounds_to_nearest_number() { + assert_eq!($name::from_percent(33) * 10u64, 3); + assert_eq!($name::from_percent(34) * 10u64, 3); + assert_eq!($name::from_percent(35) * 10u64, 3); + assert_eq!($name::from_percent(36) * 10u64, 4); + assert_eq!($name::from_percent(36) * 10u64, 4); + } + + #[test] + fn per_thing_multiplication_with_large_number() { + use primitive_types::U256; + let max_minus_one = $max - 1; + assert_eq_error_rate!( + $name::from_parts(max_minus_one) * std::u128::MAX, + ((Into::::into(std::u128::MAX) * max_minus_one) / $max).as_u128(), + 1, + ); + } + + macro_rules! per_thing_from_rationale_approx_test { + ($num_type:tt) => { + // within accuracy boundary + assert_eq!( + $name::from_rational_approximation(1 as $num_type, 0), + $name::one(), + ); + assert_eq!( + $name::from_rational_approximation(1 as $num_type, 1), + $name::one(), + ); + assert_eq_error_rate!( + $name::from_rational_approximation(1 as $num_type, 3).0, + $name::from_parts($max / 3).0, + 2 + ); + assert_eq!( + $name::from_rational_approximation(1 as $num_type, 10), + $name::from_percent(10), + ); + assert_eq!( + $name::from_rational_approximation(1 as $num_type, 4), + $name::from_percent(25), + ); + assert_eq!( + $name::from_rational_approximation(1 as $num_type, 4), + $name::from_rational_approximation(2 as $num_type, 8), + ); + // no accurate anymore but won't overflow. + assert_eq!( + $name::from_rational_approximation( + $num_type::max_value() - 1, + $num_type::max_value() + ), + $name::one(), + ); + assert_eq_error_rate!( + $name::from_rational_approximation( + $num_type::max_value() / 3, + $num_type::max_value() + ).0, + $name::from_parts($max / 3).0, + 2 + ); + assert_eq!( + $name::from_rational_approximation(1, $num_type::max_value()), + $name::zero(), + ); + }; + } + + #[test] + fn per_thing_from_rationale_approx_works() { + // This is just to make sure something like Percent which _might_ get built from a + // u8 does not overflow in the context of this test. + let max_value = $max as $upper_type; + // almost at the edge + assert_eq!( + $name::from_rational_approximation($max - 1, $max + 1), + $name::from_parts($max - 2), + ); + assert_eq!( + $name::from_rational_approximation(1, $max-1), + $name::from_parts(1), + ); + assert_eq!( + $name::from_rational_approximation(1, $max), + $name::from_parts(1), + ); + assert_eq!( + $name::from_rational_approximation(2, 2 * $max - 1), + $name::from_parts(1), + ); + assert_eq!( + $name::from_rational_approximation(1, $max+1), + $name::zero(), + ); + assert_eq!( + $name::from_rational_approximation(3 * max_value / 2, 3 * max_value), + $name::from_percent(50), + ); + $(per_thing_from_rationale_approx_test!($test_units);)* + } + + #[test] + fn per_things_mul_operates_in_output_type() { + // assert_eq!($name::from_percent(50) * 100u32, 50u32); + assert_eq!($name::from_percent(50) * 100u64, 50u64); + assert_eq!($name::from_percent(50) * 100u128, 50u128); + } + + #[test] + fn per_thing_saturating_op_works() { + assert_eq!( + $name::from_percent(50).saturating_add($name::from_percent(40)), + $name::from_percent(90) + ); + assert_eq!( + $name::from_percent(50).saturating_add($name::from_percent(50)), + $name::from_percent(100) + ); + assert_eq!( + $name::from_percent(60).saturating_add($name::from_percent(50)), + $name::from_percent(100) + ); + + assert_eq!( + $name::from_percent(60).saturating_sub($name::from_percent(50)), + $name::from_percent(10) + ); + assert_eq!( + $name::from_percent(60).saturating_sub($name::from_percent(60)), + $name::from_percent(0) + ); + assert_eq!( + $name::from_percent(60).saturating_sub($name::from_percent(70)), + $name::from_percent(0) + ); + + assert_eq!( + $name::from_percent(50).saturating_mul($name::from_percent(50)), + $name::from_percent(25) + ); + assert_eq!( + $name::from_percent(20).saturating_mul($name::from_percent(20)), + $name::from_percent(4) + ); + assert_eq!( + $name::from_percent(10).saturating_mul($name::from_percent(10)), + $name::from_percent(1) + ); + } + + #[test] + fn per_thing_square_works() { + assert_eq!($name::from_percent(100).square(), $name::from_percent(100)); + assert_eq!($name::from_percent(50).square(), $name::from_percent(25)); + assert_eq!($name::from_percent(10).square(), $name::from_percent(1)); + assert_eq!( + $name::from_percent(2).square(), + $name::from_parts((4 * ($max as $upper_type) / 100 / 100) as $type) + ); + } + + #[test] + fn per_things_div_works() { + // normal + assert_eq!($name::from_percent(10) / $name::from_percent(20), + $name::from_percent(50) + ); + assert_eq!($name::from_percent(10) / $name::from_percent(10), + $name::from_percent(100) + ); + assert_eq!($name::from_percent(10) / $name::from_percent(0), + $name::from_percent(100) + ); + + // will not overflow + assert_eq!($name::from_percent(10) / $name::from_percent(5), + $name::from_percent(100) + ); + assert_eq!($name::from_percent(100) / $name::from_percent(50), + $name::from_percent(100) + ); + } + } + }; +} + +implement_per_thing!( + Percent, + test_per_cent, + [u32, u64, u128], + 100u8, + u8, + u16, + "_Percent_", +); +implement_per_thing!( + Permill, + test_permill, + [u32, u64, u128], + 1_000_000u32, + u32, + u64, + "_Parts per Million_", +); +implement_per_thing!( + Perbill, + test_perbill, + [u32, u64, u128], + 1_000_000_000u32, + u32, + u64, + "_Parts per Billion_", +); +implement_per_thing!( + Perquintill, + test_perquintill, + [u64, u128], + 1_000_000_000_000_000_000u64, + u64, + u128, + "_Parts per Quintillion_", +); + +/// An unsigned fixed point number. Can hold any value in the range [-9_223_372_036, 9_223_372_036] +/// with fixed point accuracy of one billion. +#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct Fixed64(i64); + +/// The accuracy of the `Fixed64` type. +const DIV: i64 = 1_000_000_000; + +impl Fixed64 { + /// creates self from a natural number. + /// + /// Note that this might be lossy. + pub fn from_natural(int: i64) -> Self { + Self(int.saturating_mul(DIV)) + } + + /// Return the accuracy of the type. Given that this function returns the value `X`, it means + /// that an instance composed of `X` parts (`Fixed64::from_parts(X)`) is equal to `1`. + pub fn accuracy() -> i64 { + DIV + } + + /// Raw constructor. Equal to `parts / 1_000_000_000`. + pub fn from_parts(parts: i64) -> Self { + Self(parts) + } + + /// creates self from a rational number. Equal to `n/d`. + /// + /// Note that this might be lossy. + pub fn from_rational(n: i64, d: u64) -> Self { + Self( + ((n as i128).saturating_mul(DIV as i128) / (d as i128).max(1)) + .try_into() + .unwrap_or(Bounded::max_value()) + ) + } + + /// Performs a saturated multiply and accumulate by unsigned number. + /// + /// Returns a saturated `int + (self * int)`. + pub fn saturated_multiply_accumulate(&self, int: N) -> N + where + N: TryFrom + From + UniqueSaturatedInto + Bounded + Clone + Saturating + + ops::Rem + ops::Div + ops::Mul + + ops::Add, + { + let div = DIV as u64; + let positive = self.0 > 0; + // safe to convert as absolute value. + let parts = self.0.checked_abs().map(|v| v as u64).unwrap_or(i64::max_value() as u64 + 1); + + + // will always fit. + let natural_parts = parts / div; + // might saturate. + let natural_parts: N = natural_parts.saturated_into(); + // fractional parts can always fit into u32. + let perbill_parts = (parts % div) as u32; + + let n = int.clone().saturating_mul(natural_parts); + let p = Perbill::from_parts(perbill_parts) * int.clone(); + + // everything that needs to be either added or subtracted from the original weight. + let excess = n.saturating_add(p); + + if positive { + int.saturating_add(excess) + } else { + int.saturating_sub(excess) + } + } +} + +impl Saturating for Fixed64 { + fn saturating_add(self, rhs: Self) -> Self { + Self(self.0.saturating_add(rhs.0)) + } + fn saturating_mul(self, rhs: Self) -> Self { + Self(self.0.saturating_mul(rhs.0) / DIV) + } + fn saturating_sub(self, rhs: Self) -> Self { + Self(self.0.saturating_sub(rhs.0)) + } +} + +/// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait +/// for safe addition. +impl ops::Add for Fixed64 { + type Output = Self; + + fn add(self, rhs: Self) -> Self::Output { + Self(self.0 + rhs.0) + } +} + +/// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait +/// for safe subtraction. +impl ops::Sub for Fixed64 { + type Output = Self; + + fn sub(self, rhs: Self) -> Self::Output { + Self(self.0 - rhs.0) + } +} + +impl CheckedSub for Fixed64 { + fn checked_sub(&self, rhs: &Self) -> Option { + if let Some(v) = self.0.checked_sub(rhs.0) { + Some(Self(v)) + } else { + None + } + } +} + +impl CheckedAdd for Fixed64 { + fn checked_add(&self, rhs: &Self) -> Option { + if let Some(v) = self.0.checked_add(rhs.0) { + Some(Self(v)) + } else { + None + } + } +} + +/// Some helper functions to work with 128bit numbers. Note that the functionality provided here is +/// only sensible to use with 128bit numbers because for smaller sizes, you can always rely on +/// assumptions of a bigger type (u128) being available, or simply create a per-thing and use the +/// multiplication implementation provided there. +pub mod helpers_128bit { + use super::Perquintill; + use crate::traits::Zero; + use rstd::cmp::{min, max}; + + const ERROR: &'static str = "can not accurately multiply by rational in this type"; + + /// Helper gcd function used in Rational128 implementation. + pub fn gcd(a: u128, b: u128) -> u128 { + match ((a, b), (a & 1, b & 1)) { + ((x, y), _) if x == y => y, + ((0, x), _) | ((x, 0), _) => x, + ((x, y), (0, 1)) | ((y, x), (1, 0)) => gcd(x >> 1, y), + ((x, y), (0, 0)) => gcd(x >> 1, y >> 1) << 1, + ((x, y), (1, 1)) => { + let (x, y) = (min(x, y), max(x, y)); + gcd((y - x) >> 1, x) + }, + _ => unreachable!(), + } + } + + /// Safely and accurately compute `a * b / c`. The approach is: + /// - Simply try `a * b / c`. + /// - Else, swap the operations (divide first) if `a > c` (division is possible) and `b <= c` + /// (overflow cannot happen) + /// - At any point, given an overflow or accuracy loss, return an Error. + /// + /// Invariant: c must be greater than or equal to 1. + /// This might not return Ok even if `b < c`. + pub fn multiply_by_rational(a: u128, b: u128, c: u128) -> Result { + if a.is_zero() || b.is_zero() { return Ok(Zero::zero()); } + + // invariant: C cannot be zero. + let c = c.max(1); + + // a and b are interchangeable by definition in this function. It always helps to assume the + // bigger of which is being multiplied by a `0 < b/c < 1`. Hence, a should be the bigger and + // b the smaller one. + let t = a; + let a = a.max(b); + let b = t.min(b); + + if let Some(x) = a.checked_mul(b) { + // This is the safest way to go. Try it. + Ok(x / c) + } else if a > c { + // if it can be safely swapped and it is a fraction, then swap. + let q = a / c; + let r = a % c; + let r_additional = multiply_by_rational(r, b, c)?; + + let q_part = q.checked_mul(b) + .ok_or(ERROR)?; + let result = q_part.checked_add(r_additional) + .ok_or(ERROR)?; + Ok(result) + } else { + Err(ERROR) + } + } + + /// Performs [`multiply_by_rational`]. In case of failure, if `b < c` it tries to approximate + /// the ratio into a perquintillion and return a lossy result. Otherwise, a best effort approach + /// of shifting both b and c is performed until multiply_by_rational can work. + /// + /// This function can very well be lossy and as the name suggests, perform a best effort in the + /// scope of u128 numbers. In case `b > c` and overflow happens, `a` is returned. + /// + /// c must be greater than or equal to 1. + pub fn multiply_by_rational_best_effort(a: u128, b: u128, c: u128) -> u128 { + if a.is_zero() || b.is_zero() { return Zero::zero(); } + let c = c.max(1); + + // unwrap the loop once. This favours performance over readability. + multiply_by_rational(a, b, c).unwrap_or_else(|_| { + if b <= c { + let per_thing = Perquintill::from_rational_approximation(b, c); + per_thing * a + } else { + let mut shift = 1; + let mut shifted_b = b.checked_shr(shift).unwrap_or(0); + let mut shifted_c = c.checked_shr(shift).unwrap_or(0); + + loop { + if shifted_b.is_zero() || shifted_c.is_zero() { + break a + } + match multiply_by_rational(a, shifted_b, shifted_c) { + Ok(r) => break r, + Err(_) => { + shift = shift + 1; + // by the time we reach here, b >= 1 && c >= 1. Before panic, they have + // to be zero which is prevented to happen by the break. + shifted_b = b.checked_shr(shift) + .expect( + "b >= 1 && c >= 1; break prevents them from ever being zero; \ + panic can only happen after either is zero; qed" + ); + shifted_c = c.checked_shr(shift) + .expect( + "b >= 1 && c >= 1; break prevents them from ever being zero; \ + panic can only happen after either is zero; qed" + ); + } + } + } + } + }) + } +} + +/// A wrapper for any rational number with a 128 bit numerator and denominator. +#[derive(Clone, Copy, Default, Eq)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct Rational128(u128, u128); + +impl Rational128 { + /// Nothing. + pub fn zero() -> Self { + Self(0, 1) + } + + /// If it is zero or not + pub fn is_zero(&self) -> bool { + self.0.is_zero() + } + + /// Build from a raw `n/d`. + pub fn from(n: u128, d: u128) -> Self { + Self(n, d.max(1)) + } + + /// Build from a raw `n/d`. This could lead to / 0 if not properly handled. + pub fn from_unchecked(n: u128, d: u128) -> Self { + Self(n, d) + } + + /// Return the numerator. + pub fn n(&self) -> u128 { + self.0 + } + + /// Return the denominator. + pub fn d(&self) -> u128 { + self.1 + } + + /// Convert `self` to a similar rational number where denominator is the given `den`. + // + /// This only returns if the result is accurate. `Err` is returned if the result cannot be + /// accurately calculated. + pub fn to_den(self, den: u128) -> Result { + if den == self.1 { + Ok(self) + } else { + if den > self.1 { + let n = helpers_128bit::multiply_by_rational(self.0, den, self.1)?; + Ok(Self(n, den)) + } else { + let div = self.1 / den; + Ok(Self(self.0 / div.max(1), den)) + } + } + } + + /// Get the least common divisor of `self` and `other`. + /// + /// This only returns if the result is accurate. `Err` is returned if the result cannot be + /// accurately calculated. + pub fn lcm(&self, other: &Self) -> Result { + // this should be tested better: two large numbers that are almost the same. + if self.1 == other.1 { return Ok(self.1) } + let g = helpers_128bit::gcd(self.1, other.1); + helpers_128bit::multiply_by_rational(self.1 , other.1, g) + } + + /// A saturating add that assumes `self` and `other` have the same denominator. + pub fn lazy_saturating_add(self, other: Self) -> Self { + if other.is_zero() { + self + } else { + Self(self.0.saturating_add(other.0) ,self.1) + } + } + + /// A saturating subtraction that assumes `self` and `other` have the same denominator. + pub fn lazy_saturating_sub(self, other: Self) -> Self { + if other.is_zero() { + self + } else { + Self(self.0.saturating_sub(other.0) ,self.1) + } + } + + /// Addition. Simply tries to unify the denominators and add the numerators. + /// + /// Overflow might happen during any of the steps. Error is returned in such cases. + pub fn checked_add(self, other: Self) -> Result { + let lcm = self.lcm(&other)?; + let self_scaled = self.to_den(lcm)?; + let other_scaled = other.to_den(lcm)?; + let n = self_scaled.0.checked_add(other_scaled.0) + .ok_or("overflow while adding numerators")?; + Ok(Self(n, self_scaled.1)) + } + + /// Subtraction. Simply tries to unify the denominators and subtract the numerators. + /// + /// Overflow might happen during any of the steps. None is returned in such cases. + pub fn checked_sub(self, other: Self) -> Result { + let lcm = self.lcm(&other)?; + let self_scaled = self.to_den(lcm)?; + let other_scaled = other.to_den(lcm)?; + + let n = self_scaled.0.checked_sub(other_scaled.0) + .ok_or("overflow while subtracting numerators")?; + Ok(Self(n, self_scaled.1)) + } +} + +impl PartialOrd for Rational128 { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +/// Note that this implementation can very well be lossy. TODO #3670 +impl Ord for Rational128 { + fn cmp(&self, other: &Self) -> Ordering { + // handle some edge cases. + if self.1 == other.1 { + self.0.cmp(&other.0) + } else if self.1.is_zero() { + Ordering::Greater + } else if other.1.is_zero() { + Ordering::Less + } else { + // general lossy case + let saturated_lcm = helpers_128bit::multiply_by_rational_best_effort( + self.1, + other.1, + helpers_128bit::gcd(self.1, other.1) + ); + let self_scaled = self.to_den(saturated_lcm) + .unwrap_or(Self(Bounded::max_value(), self.1)); + let other_scaled = other.to_den(saturated_lcm) + .unwrap_or(Self(Bounded::max_value(), other.1)); + self_scaled.n().cmp(&other_scaled.n()) + } + } +} + +/// Note that this implementation can very well be lossy. TODO #3670 +impl PartialEq for Rational128 { + fn eq(&self, other: &Self) -> bool { + // handle some edge cases. + if self.1 == other.1 { + self.0.eq(&other.0) + } else { + // general lossy case + let saturated_lcm = helpers_128bit::multiply_by_rational_best_effort( + self.1, + other.1, + helpers_128bit::gcd(self.1, other.1) + ); + let self_scaled = self.to_den(saturated_lcm) + .unwrap_or(Self(Bounded::max_value(), self.1)); + let other_scaled = other.to_den(saturated_lcm) + .unwrap_or(Self(Bounded::max_value(), other.1)); + self_scaled.n().eq(&other_scaled.n()) + } + } +} + + +#[cfg(test)] +mod test_rational128 { + use super::*; + use super::helpers_128bit::*; + use crate::assert_eq_error_rate; + use rand::Rng; + + const MAX128: u128 = u128::max_value(); + const MAX64: u128 = u64::max_value() as u128; + const MAX64_2: u128 = 2 * u64::max_value() as u128; + + fn r(p: u128, q: u128) -> Rational128 { + Rational128(p, q) + } + + fn mul_div(a: u128, b: u128, c: u128) -> u128 { + use primitive_types::U256; + if a.is_zero() { return Zero::zero(); } + let c = c.max(1); + + // e for extended + let ae: U256 = a.into(); + let be: U256 = b.into(); + let ce: U256 = c.into(); + + let r = ae * be / ce; + if r > u128::max_value().into() { + a + } else { + r.as_u128() + } + } + + #[test] + fn truth_value_function_works() { + assert_eq!( + mul_div(2u128.pow(100), 8, 4), + 2u128.pow(101) + ); + assert_eq!( + mul_div(2u128.pow(100), 4, 8), + 2u128.pow(99) + ); + + // and it returns a if result cannot fit + assert_eq!(mul_div(MAX128 - 10, 2, 1), MAX128 - 10); + } + + #[test] + fn to_denom_works() { + // simple up and down + assert_eq!(r(1, 5).to_den(10), Ok(r(2, 10))); + assert_eq!(r(4, 10).to_den(5), Ok(r(2, 5))); + + // up and down with large numbers + assert_eq!(r(MAX128 - 10, MAX128).to_den(10), Ok(r(9, 10))); + assert_eq!(r(MAX128 / 2, MAX128).to_den(10), Ok(r(5, 10))); + + // large to perbill. This is very well needed for phragmen. + assert_eq!( + r(MAX128 / 2, MAX128).to_den(1000_000_000), + Ok(r(500_000_000, 1000_000_000)) + ); + + // large to large + assert_eq!(r(MAX128 / 2, MAX128).to_den(MAX128/2), Ok(r(MAX128/4, MAX128/2))); + } + + #[test] + fn gdc_works() { + assert_eq!(gcd(10, 5), 5); + assert_eq!(gcd(7, 22), 1); + } + + #[test] + fn lcm_works() { + // simple stuff + assert_eq!(r(3, 10).lcm(&r(4, 15)).unwrap(), 30); + assert_eq!(r(5, 30).lcm(&r(1, 7)).unwrap(), 210); + assert_eq!(r(5, 30).lcm(&r(1, 10)).unwrap(), 30); + + // large numbers + assert_eq!( + r(1_000_000_000, MAX128).lcm(&r(7_000_000_000, MAX128-1)), + Err("can not accurately multiply by rational in this type"), + ); + assert_eq!( + r(1_000_000_000, MAX64).lcm(&r(7_000_000_000, MAX64-1)), + Ok(340282366920938463408034375210639556610), + ); + assert!(340282366920938463408034375210639556610 < MAX128); + assert!(340282366920938463408034375210639556610 == MAX64 * (MAX64 - 1)); + } + + #[test] + fn add_works() { + // works + assert_eq!(r(3, 10).checked_add(r(1, 10)).unwrap(), r(2, 5)); + assert_eq!(r(3, 10).checked_add(r(3, 7)).unwrap(), r(51, 70)); + + // errors + assert_eq!( + r(1, MAX128).checked_add(r(1, MAX128-1)), + Err("can not accurately multiply by rational in this type"), + ); + assert_eq!( + r(7, MAX128).checked_add(r(MAX128, MAX128)), + Err("overflow while adding numerators"), + ); + assert_eq!( + r(MAX128, MAX128).checked_add(r(MAX128, MAX128)), + Err("overflow while adding numerators"), + ); + } + + #[test] + fn sub_works() { + // works + assert_eq!(r(3, 10).checked_sub(r(1, 10)).unwrap(), r(1, 5)); + assert_eq!(r(6, 10).checked_sub(r(3, 7)).unwrap(), r(12, 70)); + + // errors + assert_eq!( + r(2, MAX128).checked_sub(r(1, MAX128-1)), + Err("can not accurately multiply by rational in this type"), + ); + assert_eq!( + r(7, MAX128).checked_sub(r(MAX128, MAX128)), + Err("overflow while subtracting numerators"), + ); + assert_eq!( + r(1, 10).checked_sub(r(2,10)), + Err("overflow while subtracting numerators"), + ); + } + + #[test] + fn ordering_and_eq_works() { + assert!(r(1, 2) > r(1, 3)); + assert!(r(1, 2) > r(2, 6)); + + assert!(r(1, 2) < r(6, 6)); + assert!(r(2, 1) > r(2, 6)); + + assert!(r(5, 10) == r(1, 2)); + assert!(r(1, 2) == r(1, 2)); + + assert!(r(1, 1490000000000200000) > r(1, 1490000000000200001)); + } + + #[test] + fn multiply_by_rational_works() { + assert_eq!(multiply_by_rational(7, 2, 3).unwrap(), 7 * 2 / 3); + assert_eq!(multiply_by_rational(7, 20, 30).unwrap(), 7 * 2 / 3); + assert_eq!(multiply_by_rational(20, 7, 30).unwrap(), 7 * 2 / 3); + + // computed with swap + assert_eq!( + // MAX128 % 3 == 0 + multiply_by_rational(MAX128, 2, 3).unwrap(), + MAX128 / 3 * 2, + ); + assert_eq!( + // MAX128 % 7 == 3 + multiply_by_rational(MAX128, 5, 7).unwrap(), + (MAX128 / 7 * 5) + (3 * 5 / 7), + ); + assert_eq!( + // MAX128 % 7 == 3 + multiply_by_rational(MAX128, 11 , 13).unwrap(), + (MAX128 / 13 * 11) + (8 * 11 / 13), + ); + assert_eq!( + // MAX128 % 1000 == 455 + multiply_by_rational(MAX128, 555, 1000).unwrap(), + (MAX128 / 1000 * 555) + (455 * 555 / 1000), + ); + + assert_eq!( + multiply_by_rational(2 * MAX64 - 1, MAX64, MAX64).unwrap(), + 2 * MAX64 - 1, + ); + assert_eq!( + multiply_by_rational(2 * MAX64 - 1, MAX64 - 1, MAX64).unwrap(), + 2 * MAX64 - 3, + ); + + + assert_eq!( + multiply_by_rational(MAX64 + 100, MAX64_2, MAX64_2 / 2).unwrap(), + (MAX64 + 100) * 2, + ); + assert_eq!( + multiply_by_rational(MAX64 + 100, MAX64_2 / 100, MAX64_2 / 200).unwrap(), + (MAX64 + 100) * 2, + ); + + // fails to compute. have to use the greedy, lossy version here + assert!(multiply_by_rational(2u128.pow(66) - 1, 2u128.pow(65) - 1, 2u128.pow(65)).is_err()); + assert!(multiply_by_rational(1_000_000_000, MAX128 / 8, MAX128 / 2).is_err()); + } + + #[test] + fn multiply_by_rational_a_b_are_interchangeable() { + assert_eq!( + multiply_by_rational(10, MAX128, MAX128 / 2), + Ok(20), + ); + assert_eq!( + multiply_by_rational(MAX128, 10, MAX128 / 2), + Ok(20), + ); + } + + #[test] + fn multiply_by_rational_best_effort_works() { + assert_eq_error_rate!( + multiply_by_rational_best_effort(MAX64 + 100, MAX64_2, MAX64_2 / 2), + (MAX64 + 100) * 2, + 10, + ); + assert_eq_error_rate!( + multiply_by_rational_best_effort(MAX64 + 100, MAX64_2 * 100, MAX64_2 * 100 / 2), + (MAX64 + 100) * 2, + 10, + ); + assert_eq_error_rate!( + multiply_by_rational_best_effort(2u128.pow(66) - 1, 2u128.pow(65) - 1, 2u128.pow(65)), + mul_div(2u128.pow(66) - 1, 2u128.pow(65) - 1, 2u128.pow(65)), + 10, + ); + assert_eq_error_rate!( + multiply_by_rational_best_effort(1_000_000_000, MAX128 / 8, MAX128 / 2), + 1_000_000_000 / 4, + 10, + ); + + assert_eq!( + multiply_by_rational_best_effort(MAX128, MAX128 - 1, MAX128), + MAX128, + ); + + assert_eq!( + multiply_by_rational_best_effort(MAX64, MAX128 / 2, MAX128), + MAX64 / 2, + ); + } + + fn do_fuzz_multiply_by_rational( + iters: usize, + bits: u32, + maximum_error: u128, + do_print: bool, + bounded: bool, + mul_fn: F, + ) where F: Fn(u128, u128, u128) -> u128 { + let mut rng = rand::thread_rng(); + let mut average_diff = 0.0; + let upper_bound = 2u128.pow(bits); + + for _ in 0..iters { + let a = rng.gen_range(0u128, upper_bound); + let c = rng.gen_range(0u128, upper_bound); + let b = rng.gen_range( + 0u128, + if bounded { c } else { upper_bound } + ); + + let a: u128 = a.into(); + let b: u128 = b.into(); + let c: u128 = c.into(); + + let truth = mul_div(a, b, c); + let result = mul_fn(a, b, c); + let diff = truth.max(result) - truth.min(result); + let loss_ratio = diff as f64 / truth as f64; + average_diff += loss_ratio; + + if do_print && diff > maximum_error { + println!("++ Computed with more loss than expected: {} * {} / {}", a, b, c); + println!("++ Expected {}", truth); + println!("+++++++ Got {}", result); + } + } + + // print report + println!( + "## Fuzzed with {} numbers. Average error was {}", + iters, + average_diff / (iters as f64), + ); + } + + #[test] + fn fuzz_multiply_by_rational_best_effort_32() { + let f = |a, b, c| multiply_by_rational_best_effort(a, b, c); + println!("\nInvariant: b < c"); + do_fuzz_multiply_by_rational(1_000_000, 32, 0, false, true, f); + println!("every possibility"); + do_fuzz_multiply_by_rational(1_000_000, 32, 0, false, false, f); + } + + #[test] + fn fuzz_multiply_by_rational_best_effort_64() { + let f = |a, b, c| multiply_by_rational_best_effort(a, b, c); + println!("\nInvariant: b < c"); + do_fuzz_multiply_by_rational(1_000_000, 64, 0, false, true, f); + println!("every possibility"); + do_fuzz_multiply_by_rational(1_000_000, 64, 0, false, false, f); + } + + #[test] + fn fuzz_multiply_by_rational_best_effort_96() { + let f = |a, b, c| multiply_by_rational_best_effort(a, b, c); + // println!("\nInvariant: b < c"); + // do_fuzz_multiply_by_rational(1_000_000, 96, 0, false, true, f); + println!("every possibility"); + // do_fuzz_multiply_by_rational(1_000_000, 96, 0, false, false, f); + do_fuzz_multiply_by_rational(10, 96, 0, true, false, f); + } + + #[test] + fn fuzz_multiply_by_rational_best_effort_128() { + let f = |a, b, c| multiply_by_rational_best_effort(a, b, c); + println!("\nInvariant: b < c"); + do_fuzz_multiply_by_rational(1_000_000, 127, 0, false, true, f); + println!("every possibility"); + do_fuzz_multiply_by_rational(1_000_000, 127, 0, false, false, f); + } + + #[test] + fn fuzz_multiply_by_rational_32() { + // if Err just return the truth value. We don't care about such cases. The point of this + // fuzzing is to make sure: if `multiply_by_rational` returns `Ok`, it must be 100% accurate + // returning `Err` is fine. + let f = |a, b, c| multiply_by_rational(a, b, c).unwrap_or(mul_div(a, b, c)); + println!("\nInvariant: b < c"); + do_fuzz_multiply_by_rational(1_000_000, 32, 0, false, true, f); + println!("every possibility"); + do_fuzz_multiply_by_rational(1_000_000, 32, 0, false, false, f); + } + + #[test] + fn fuzz_multiply_by_rational_64() { + let f = |a, b, c| multiply_by_rational(a, b, c).unwrap_or(mul_div(a, b, c)); + println!("\nInvariant: b < c"); + do_fuzz_multiply_by_rational(1_000_000, 64, 0, false, true, f); + println!("every possibility"); + do_fuzz_multiply_by_rational(1_000_000, 64, 0, false, false, f); + } + + #[test] + fn fuzz_multiply_by_rational_96() { + let f = |a, b, c| multiply_by_rational(a, b, c).unwrap_or(mul_div(a, b, c)); + println!("\nInvariant: b < c"); + do_fuzz_multiply_by_rational(1_000_000, 96, 0, false, true, f); + println!("every possibility"); + do_fuzz_multiply_by_rational(1_000_000, 96, 0, false, false, f); + } + + #[test] + fn fuzz_multiply_by_rational_128() { + let f = |a, b, c| multiply_by_rational(a, b, c).unwrap_or(mul_div(a, b, c)); + println!("\nInvariant: b < c"); + do_fuzz_multiply_by_rational(1_000_000, 127, 0, false, true, f); + println!("every possibility"); + do_fuzz_multiply_by_rational(1_000_000, 127, 0, false, false, f); + } +} + + +#[cfg(test)] +mod tests_fixed64 { + use super::*; + + fn max() -> Fixed64 { + Fixed64::from_parts(i64::max_value()) + } + + #[test] + fn fixed64_semantics() { + assert_eq!(Fixed64::from_rational(5, 2).0, 5 * 1_000_000_000 / 2); + assert_eq!(Fixed64::from_rational(5, 2), Fixed64::from_rational(10, 4)); + assert_eq!(Fixed64::from_rational(5, 0), Fixed64::from_rational(5, 1)); + + // biggest value that can be created. + assert_ne!(max(), Fixed64::from_natural(9_223_372_036)); + assert_eq!(max(), Fixed64::from_natural(9_223_372_037)); + } + + macro_rules! saturating_mul_acc_test { + ($num_type:tt) => { + assert_eq!( + Fixed64::from_rational(100, 1).saturated_multiply_accumulate(10 as $num_type), + 1010, + ); + assert_eq!( + Fixed64::from_rational(100, 2).saturated_multiply_accumulate(10 as $num_type), + 510, + ); + assert_eq!( + Fixed64::from_rational(100, 3).saturated_multiply_accumulate(0 as $num_type), + 0, + ); + assert_eq!( + Fixed64::from_rational(5, 1).saturated_multiply_accumulate($num_type::max_value()), + $num_type::max_value() + ); + assert_eq!( + max().saturated_multiply_accumulate($num_type::max_value()), + $num_type::max_value() + ); + } + } + + #[test] + fn fixed64_multiply_accumulate_works() { + saturating_mul_acc_test!(u32); + saturating_mul_acc_test!(u64); + saturating_mul_acc_test!(u128); + } +} diff --git a/core/sr-primitives/src/weights.rs b/core/sr-primitives/src/weights.rs index 45ac59e0d5..28f1b2fe0c 100644 --- a/core/sr-primitives/src/weights.rs +++ b/core/sr-primitives/src/weights.rs @@ -188,7 +188,7 @@ impl WeightMultiplier { /// build self from raw parts per billion. #[cfg(feature = "std")] pub fn from_parts(parts: i64) -> Self { - Self(Fixed64(parts)) + Self(Fixed64::from_parts(parts)) } /// build self from a fixed64 value. diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index 6c4fdc5897..864b51d6c7 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -40,7 +40,7 @@ mod tests { use runtime_io; use codec::{Encode, Decode, Joiner}; use runtime_support::{ - Hashable, StorageValue, StorageMap, assert_eq_error_rate, traits::Currency, + Hashable, StorageValue, StorageMap, traits::Currency, }; use state_machine::TestExternalities as CoreTestExternalities; use primitives::{ @@ -48,6 +48,7 @@ mod tests { traits::{CodeExecutor, Externalities}, storage::well_known_keys, }; use sr_primitives::{ + assert_eq_error_rate, traits::{Header as HeaderT, Hash as HashT, Convert}, ApplyResult, transaction_validity::InvalidTransaction, weights::{WeightMultiplier, GetDispatchInfo}, }; diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 306521b2cf..cc3a886e97 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -84,7 +84,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 163, + spec_version: 164, impl_version: 164, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/im-online/src/lib.rs b/srml/im-online/src/lib.rs index b09b24df5f..611a2aaa16 100644 --- a/srml/im-online/src/lib.rs +++ b/srml/im-online/src/lib.rs @@ -76,7 +76,7 @@ use primitives::offchain::{OpaqueNetworkState, StorageKind}; use rstd::prelude::*; use session::historical::IdentificationTuple; use sr_primitives::{ - traits::{Convert, Member, Printable}, Perbill, + traits::{Convert, Member, Printable, Saturating}, Perbill, transaction_validity::{ TransactionValidity, TransactionLongevity, ValidTransaction, InvalidTransaction, }, @@ -573,12 +573,6 @@ impl Offence for UnresponsivenessOffence { fn slash_fraction(offenders: u32, validator_set_count: u32) -> Perbill { // the formula is min((3 * (k - 1)) / n, 1) * 0.05 let x = Perbill::from_rational_approximation(3 * (offenders - 1), validator_set_count); - - // _ * 0.05 - // For now, Perbill doesn't support multiplication other than an integer so we perform - // a manual scaling. - // TODO: #3189 should fix this. - let p = (x.into_parts() as u64 * 50_000_000u64) / 1_000_000_000u64; - Perbill::from_parts(p as u32) + x.saturating_mul(Perbill::from_percent(5)) } } diff --git a/srml/offences/src/lib.rs b/srml/offences/src/lib.rs index 5c1d04d0c0..801b8b5fca 100644 --- a/srml/offences/src/lib.rs +++ b/srml/offences/src/lib.rs @@ -33,7 +33,7 @@ use support::{ }; use sr_primitives::{ Perbill, - traits::Hash, + traits::{Hash, Saturating}, }; use sr_staking_primitives::{ offence::{Offence, ReportOffence, Kind, OnOffenceHandler, OffenceDetails}, @@ -131,12 +131,9 @@ where offenders_count.saturating_sub(previous_offenders_count), validator_set_count, ); - let numerator = new_fraction - .into_parts() - .saturating_sub(previous_fraction.into_parts()); - let denominator = - Perbill::from_parts(Perbill::one().into_parts() - previous_fraction.into_parts()); - Perbill::from_parts(denominator * numerator) + let numerator = new_fraction.saturating_sub(previous_fraction); + let denominator = Perbill::one().saturating_sub(previous_fraction); + denominator.saturating_mul(numerator) } else { new_fraction.clone() }; diff --git a/srml/staking/reward-curve/src/lib.rs b/srml/staking/reward-curve/src/lib.rs index 637ba10b9e..7e1f1e6aa9 100644 --- a/srml/staking/reward-curve/src/lib.rs +++ b/srml/staking/reward-curve/src/lib.rs @@ -337,8 +337,8 @@ fn generate_piecewise_linear(points: Vec<(u32, u32)>) -> TokenStream2 { points_tokens.extend(quote!( ( - _sr_primitives::Perbill::from_const_parts(#x_perbill), - _sr_primitives::Perbill::from_const_parts(#y_perbill), + _sr_primitives::Perbill::from_parts(#x_perbill), + _sr_primitives::Perbill::from_parts(#y_perbill), ), )); } diff --git a/srml/staking/src/inflation.rs b/srml/staking/src/inflation.rs index a1d45b3db1..89326b92c0 100644 --- a/srml/staking/src/inflation.rs +++ b/srml/staking/src/inflation.rs @@ -59,9 +59,10 @@ mod test { #[test] fn npos_curve_is_sensible() { const YEAR: u64 = 365 * 24 * 60 * 60 * 1000; + //super::I_NPOS.calculate_for_fraction_times_denominator(25, 100) assert_eq!(super::compute_total_payout(&I_NPOS, 0, 100_000u64, YEAR), 2_498); - assert_eq!(super::compute_total_payout(&I_NPOS, 5_000, 100_000u64, YEAR), 3_247); - assert_eq!(super::compute_total_payout(&I_NPOS, 25_000, 100_000u64, YEAR), 6_245); + assert_eq!(super::compute_total_payout(&I_NPOS, 5_000, 100_000u64, YEAR), 3_248); + assert_eq!(super::compute_total_payout(&I_NPOS, 25_000, 100_000u64, YEAR), 6_246); assert_eq!(super::compute_total_payout(&I_NPOS, 40_000, 100_000u64, YEAR), 8_494); assert_eq!(super::compute_total_payout(&I_NPOS, 50_000, 100_000u64, YEAR), 9_993); assert_eq!(super::compute_total_payout(&I_NPOS, 60_000, 100_000u64, YEAR), 4_379); @@ -76,8 +77,8 @@ mod test { const SIX_HOURS: u64 = 6 * 60 * 60 * 1000; assert_eq!(super::compute_total_payout(&I_NPOS, 25_000, 100_000u64, SIX_HOURS), 4); - assert_eq!(super::compute_total_payout(&I_NPOS, 50_000, 100_000u64, SIX_HOURS), 6); - assert_eq!(super::compute_total_payout(&I_NPOS, 75_000, 100_000u64, SIX_HOURS), 1); + assert_eq!(super::compute_total_payout(&I_NPOS, 50_000, 100_000u64, SIX_HOURS), 7); + assert_eq!(super::compute_total_payout(&I_NPOS, 75_000, 100_000u64, SIX_HOURS), 2); const HOUR: u64 = 60 * 60 * 1000; assert_eq!( diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index bb7368affc..4c73b64bd4 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -270,7 +270,6 @@ use sr_primitives::{ SaturatedConversion, } }; -use phragmen::{elect, equalize, Support, SupportMap, ExtendedBalance, ACCURACY}; use sr_staking_primitives::{ SessionIndex, offence::{OnOffenceHandler, OffenceDetails, Offence, ReportOffence}, @@ -279,6 +278,8 @@ use sr_staking_primitives::{ use sr_primitives::{Serialize, Deserialize}; use system::{ensure_signed, ensure_root}; +use phragmen::{elect, equalize, ExtendedBalance, Support, SupportMap, PhragmenStakedAssignment}; + const DEFAULT_MINIMUM_VALIDATOR_COUNT: u32 = 4; const MAX_NOMINATIONS: usize = 16; const MAX_UNLOCKING_CHUNKS: usize = 32; @@ -1190,7 +1191,7 @@ impl Module { for (v, p) in validators.iter().zip(points.individual.into_iter()) { if p != 0 { - let reward = multiply_by_rational(total_payout, p, points.total); + let reward = Perbill::from_rational_approximation(p, points.total) * total_payout; total_imbalance.subsume(Self::reward_validator(v, reward)); } } @@ -1252,21 +1253,15 @@ impl Module { ); if let Some(phragmen_result) = maybe_phragmen_result { - let elected_stashes = phragmen_result.winners.iter().map(|(s, _)| s.clone()).collect::>(); - let mut assignments = phragmen_result.assignments; + let elected_stashes = phragmen_result.winners.iter() + .map(|(s, _)| s.clone()) + .collect::>(); + let assignments = phragmen_result.assignments; - // helper closure. - let to_balance = |b: ExtendedBalance| - >>::convert(b); let to_votes = |b: BalanceOf| , u64>>::convert(b) as ExtendedBalance; - - // The return value of this is safe to be converted to u64. - // The original balance, `b` is within the scope of u64. It is just extended to u128 - // to be properly multiplied by a ratio, which will lead to another value - // less than u64 for sure. The result can then be safely passed to `to_balance`. - // For now the backward convert is used. A simple `TryFrom` is also safe. - let ratio_of = |b, r: ExtendedBalance| r.saturating_mul(to_votes(b)) / ACCURACY; + let to_balance = |e: ExtendedBalance| + >>::convert(e); // Initialize the support of each candidate. let mut supports = >::new(); @@ -1278,29 +1273,42 @@ impl Module { supports.insert(e.clone(), item); }); - // convert the ratio in-place (and replace) to the balance but still in the extended - // balance type. - for (n, assignment) in assignments.iter_mut() { - for (c, r) in assignment.iter_mut() { - let nominator_stake = Self::slashable_balance_of(n); - let other_stake = ratio_of(nominator_stake, *r); + // build support struct. + for (n, assignment) in assignments.iter() { + for (c, per_thing) in assignment.iter() { + let nominator_stake = to_votes(Self::slashable_balance_of(n)); + // AUDIT: it is crucially important for the `Mul` implementation of all + // per-things to be sound. + let other_stake = *per_thing * nominator_stake; if let Some(support) = supports.get_mut(c) { - // This for an astronomically rich validator with more astronomically rich + // For an astronomically rich validator with more astronomically rich // set of nominators, this might saturate. support.total = support.total.saturating_add(other_stake); support.others.push((n.clone(), other_stake)); } - // convert the ratio to extended balance - *r = other_stake; } } - #[cfg(feature = "equalize")] - { + if cfg!(feature = "equalize") { + let mut staked_assignments + : Vec<(T::AccountId, Vec>)> + = Vec::with_capacity(assignments.len()); + for (n, assignment) in assignments.iter() { + let mut staked_assignment + : Vec> + = Vec::with_capacity(assignment.len()); + for (c, per_thing) in assignment.iter() { + let nominator_stake = to_votes(Self::slashable_balance_of(n)); + let other_stake = *per_thing * nominator_stake; + staked_assignment.push((c.clone(), other_stake)); + } + staked_assignments.push((n.clone(), staked_assignment)); + } + let tolerance = 0_u128; let iterations = 2_usize; - equalize::<_, _, _, T::CurrencyToVote>( - assignments, + equalize::<_, _, T::CurrencyToVote, _>( + staked_assignments, &mut supports, tolerance, iterations, @@ -1450,31 +1458,6 @@ impl authorship::EventHandler(value: N, num: u32, den: u32) -> N - where N: SimpleArithmetic + Clone -{ - let num = num.min(den); - - let result_divisor_part = value.clone() / den.into() * num.into(); - - let result_remainder_part = { - let rem = value % den.into(); - - // Fits into u32 because den is u32 and remainder < den - let rem_u32 = rem.saturated_into::(); - - // Multiplication fits into u64 as both term are u32 - let rem_part = rem_u32 as u64 * num as u64 / den as u64; - - // Result fits into u32 as num < total_points - (rem_part as u32).into() - }; - - result_divisor_part + result_remainder_part -} - /// A `Convert` implementation that finds the stash of the given controller account, /// if any. pub struct StashOf(rstd::marker::PhantomData); diff --git a/srml/staking/src/mock.rs b/srml/staking/src/mock.rs index ba1645e6d7..8263e159c1 100644 --- a/srml/staking/src/mock.rs +++ b/srml/staking/src/mock.rs @@ -151,7 +151,7 @@ parameter_types! { pub const Period: BlockNumber = 1; pub const Offset: BlockNumber = 0; pub const UncleGenerations: u64 = 0; - pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(33); + pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(25); } impl session::Trait for Test { type OnSessionEnding = session::historical::NoteHistoricalRoot; @@ -396,7 +396,7 @@ pub fn check_nominator_exposure(stash: u64) { pub fn assert_total_expo(stash: u64, val: u64) { let expo = Staking::stakers(&stash); - assert_eq!(expo.total, val); + assert_eq!(expo.total, val, "total exposure mismatch {:?} != {:?}", expo.total, val); } pub fn assert_is_stash(acc: u64) { diff --git a/srml/staking/src/tests.rs b/srml/staking/src/tests.rs index 1d0beb6029..6b51fb9b3f 100644 --- a/srml/staking/src/tests.rs +++ b/srml/staking/src/tests.rs @@ -17,11 +17,11 @@ //! Tests for the module. use super::*; +use mock::*; use runtime_io::with_externalities; -use sr_primitives::traits::OnInitialize; +use sr_primitives::{assert_eq_error_rate, traits::OnInitialize}; use sr_staking_primitives::offence::{OffenceDetails, OnOffenceHandler}; use support::{assert_ok, assert_noop, assert_eq_uvec}; -use mock::*; use support::traits::{Currency, ReservableCurrency}; #[test] @@ -30,14 +30,23 @@ fn basic_setup_works() { with_externalities(&mut ExtBuilder::default() .build(), || { - assert_eq!(Staking::bonded(&11), Some(10)); // Account 11 is stashed and locked, and account 10 is the controller - assert_eq!(Staking::bonded(&21), Some(20)); // Account 21 is stashed and locked, and account 20 is the controller - assert_eq!(Staking::bonded(&1), None); // Account 1 is not a stashed + // Account 11 is stashed and locked, and account 10 is the controller + assert_eq!(Staking::bonded(&11), Some(10)); + // Account 21 is stashed and locked, and account 20 is the controller + assert_eq!(Staking::bonded(&21), Some(20)); + // Account 1 is not a stashed + assert_eq!(Staking::bonded(&1), None); // Account 10 controls the stash from account 11, which is 100 * balance_factor units - assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, total: 1000, active: 1000, unlocking: vec![] })); + assert_eq!( + Staking::ledger(&10), + Some(StakingLedger { stash: 11, total: 1000, active: 1000, unlocking: vec![] }) + ); // Account 20 controls the stash from account 21, which is 200 * balance_factor units - assert_eq!(Staking::ledger(&20), Some(StakingLedger { stash: 21, total: 1000, active: 1000, unlocking: vec![] })); + assert_eq!( + Staking::ledger(&20), + Some(StakingLedger { stash: 21, total: 1000, active: 1000, unlocking: vec![] }) + ); // Account 1 does not control any stash assert_eq!(Staking::ledger(&1), None); @@ -48,8 +57,10 @@ fn basic_setup_works() { (11, ValidatorPrefs::default()) ]); - // Account 100 is the default nominator - assert_eq!(Staking::ledger(100), Some(StakingLedger { stash: 101, total: 500, active: 500, unlocking: vec![] })); + assert_eq!( + Staking::ledger(100), + Some(StakingLedger { stash: 101, total: 500, active: 500, unlocking: vec![] }) + ); assert_eq!(Staking::nominators(101), vec![11, 21]); if cfg!(feature = "equalize") { @@ -194,9 +205,9 @@ fn rewards_should_work() { assert_eq!(Staking::current_era(), 1); assert_eq!(Session::current_index(), 3); - // 11 validator has 2 / 3 of the total rewards and half half for it and its nominator - assert_eq!(Balances::total_balance(&2), init_balance_2 + total_payout / 3); - assert_eq!(Balances::total_balance(&10), init_balance_10 + total_payout / 3); + // 11 validator has 2/3 of the total rewards and half half for it and its nominator + assert_eq_error_rate!(Balances::total_balance(&2), init_balance_2 + total_payout / 3, 1); + assert_eq_error_rate!(Balances::total_balance(&10), init_balance_10 + total_payout / 3, 1); assert_eq!(Balances::total_balance(&11), init_balance_11); }); } @@ -338,8 +349,6 @@ fn less_than_needed_candidates_works() { #[test] fn no_candidate_emergency_condition() { - // Test the situation where the number of validators are less than `ValidatorCount` and less than - // The expected behavior is to choose all candidates from the previous era. with_externalities(&mut ExtBuilder::default() .minimum_validator_count(10) .validator_count(15) @@ -373,7 +382,6 @@ fn no_candidate_emergency_condition() { fn nominating_and_rewards_should_work() { // PHRAGMEN OUTPUT: running this test with the reference impl gives: // - // Votes [('10', 1000, ['10']), ('20', 1000, ['20']), ('30', 1000, ['30']), ('40', 1000, ['40']), ('2', 1000, ['10', '20', '30']), ('4', 1000, ['10', '20', '40'])] // Sequential Phragmén gives // 10 is elected with stake 2200.0 and score 0.0003333333333333333 // 20 is elected with stake 1800.0 and score 0.0005555555555555556 @@ -457,11 +465,11 @@ fn nominating_and_rewards_should_work() { if cfg!(feature = "equalize") { // total expo of 10, with 1200 coming from nominators (externals), according to phragmen. assert_eq!(Staking::stakers(11).own, 1000); - assert_eq!(Staking::stakers(11).total, 1000 + 999); + assert_eq_error_rate!(Staking::stakers(11).total, 1000 + 1000, 2); // 2 and 4 supported 10, each with stake 600, according to phragmen. assert_eq!( Staking::stakers(11).others.iter().map(|e| e.value).collect::>>(), - vec![599, 400] + vec![600, 400] ); assert_eq!( Staking::stakers(11).others.iter().map(|e| e.who).collect::>(), @@ -469,11 +477,11 @@ fn nominating_and_rewards_should_work() { ); // total expo of 20, with 500 coming from nominators (externals), according to phragmen. assert_eq!(Staking::stakers(21).own, 1000); - assert_eq!(Staking::stakers(21).total, 1000 + 999); + assert_eq_error_rate!(Staking::stakers(21).total, 1000 + 1000, 2); // 2 and 4 supported 20, each with stake 250, according to phragmen. assert_eq!( Staking::stakers(21).others.iter().map(|e| e.value).collect::>>(), - vec![400, 599] + vec![400, 600] ); assert_eq!( Staking::stakers(21).others.iter().map(|e| e.who).collect::>(), @@ -494,11 +502,11 @@ fn nominating_and_rewards_should_work() { ); // total expo of 20, with 500 coming from nominators (externals), according to phragmen. assert_eq!(Staking::stakers(21).own, 1000); - assert_eq!(Staking::stakers(21).total, 1000 + 1198); + assert_eq_error_rate!(Staking::stakers(21).total, 1000 + 1200, 2); // 2 and 4 supported 20, each with stake 250, according to phragmen. assert_eq!( Staking::stakers(21).others.iter().map(|e| e.value).collect::>>(), - vec![599, 599] + vec![600, 600] ); assert_eq!( Staking::stakers(21).others.iter().map(|e| e.who).collect::>(), @@ -527,30 +535,56 @@ fn nominating_and_rewards_should_work() { let payout_for_20 = 2 * total_payout_1 / 3; if cfg!(feature = "equalize") { // Nominator 2: has [400 / 2000 ~ 1 / 5 from 10] + [600 / 2000 ~ 3 / 10 from 20]'s reward. - assert_eq!(Balances::total_balance(&2), initial_balance + payout_for_10 / 5 + payout_for_20 * 3 / 10); + assert_eq_error_rate!( + Balances::total_balance(&2), + initial_balance + payout_for_10 / 5 + payout_for_20 * 3 / 10, + 2, + ); // Nominator 4: has [400 / 2000 ~ 1 / 5 from 20] + [600 / 2000 ~ 3 / 10 from 10]'s reward. - assert_eq!(Balances::total_balance(&4), initial_balance + payout_for_20 / 5 + payout_for_10 * 3 / 10); + assert_eq_error_rate!( + Balances::total_balance(&4), + initial_balance + payout_for_20 / 5 + payout_for_10 * 3 / 10, + 2, + ); // Validator 10: got 1000 / 2000 external stake. - assert_eq!(Balances::total_balance(&10), initial_balance + payout_for_10 / 2); + assert_eq_error_rate!( + Balances::total_balance(&10), + initial_balance + payout_for_10 / 2, + 1, + ); // Validator 20: got 1000 / 2000 external stake. - assert_eq!(Balances::total_balance(&20), initial_balance + payout_for_20 / 2); + assert_eq_error_rate!( + Balances::total_balance(&20), + initial_balance + payout_for_20 / 2, + 1, + ); } else { - // Nominator 2: has [400 / 1800 ~ 2 / 9 from 10] + [600 / 2200 ~ 3 / 11 from 20]'s reward. ==> 2 / 9 + 3 / 11 - assert_eq!( + // Nominator 2: has [400/1800 ~ 2/9 from 10] + [600/2200 ~ 3/11 from 20]'s reward. ==> 2/9 + 3/11 + assert_eq_error_rate!( Balances::total_balance(&2), - initial_balance + (2 * payout_for_10 / 9 + 3 * payout_for_20 / 11) - 2 + initial_balance + (2 * payout_for_10 / 9 + 3 * payout_for_20 / 11), + 1, ); - // Nominator 4: has [400 / 1800 ~ 2 / 9 from 10] + [600 / 2200 ~ 3 / 11 from 20]'s reward. ==> 2 / 9 + 3 / 11 - assert_eq!( + // Nominator 4: has [400/1800 ~ 2/9 from 10] + [600/2200 ~ 3/11 from 20]'s reward. ==> 2/9 + 3/11 + assert_eq_error_rate!( Balances::total_balance(&4), - initial_balance + (2 * payout_for_10 / 9 + 3 * payout_for_20 / 11) - 2 + initial_balance + (2 * payout_for_10 / 9 + 3 * payout_for_20 / 11), + 1, ); - // Validator 10: got 800 / 1800 external stake => 8 / 18 =? 4 / 9 => Validator's share = 5 / 9 - assert_eq!(Balances::total_balance(&10), initial_balance + 5*payout_for_10 / 9 - 1); - // Validator 20: got 1200 / 2200 external stake => 12 / 22 =? 6 / 11 => Validator's share = 5 / 11 - assert_eq!(Balances::total_balance(&20), initial_balance + 5*payout_for_20 / 11 + 1); + // Validator 10: got 800 / 1800 external stake => 8/18 =? 4/9 => Validator's share = 5/9 + assert_eq_error_rate!( + Balances::total_balance(&10), + initial_balance + 5 * payout_for_10 / 9, + 1, + ); + // Validator 20: got 1200 / 2200 external stake => 12/22 =? 6/11 => Validator's share = 5/11 + assert_eq_error_rate!( + Balances::total_balance(&20), + initial_balance + 5 * payout_for_20 / 11, + 1, + ); } check_exposure_all(); @@ -655,9 +689,15 @@ fn double_controlling_should_fail() { || { let arbitrary_value = 5; // 2 = controller, 1 stashed => ok - assert_ok!(Staking::bond(Origin::signed(1), 2, arbitrary_value, RewardDestination::default())); + assert_ok!( + Staking::bond(Origin::signed(1), 2, arbitrary_value, + RewardDestination::default()) + ); // 2 = controller, 3 stashed (Note that 2 is reused.) => no-op - assert_noop!(Staking::bond(Origin::signed(3), 2, arbitrary_value, RewardDestination::default()), "controller already paired"); + assert_noop!( + Staking::bond(Origin::signed(3), 2, arbitrary_value, RewardDestination::default()), + "controller already paired" + ); }); } @@ -1278,137 +1318,6 @@ fn on_free_balance_zero_stash_removes_nominator() { }); } -#[test] -fn phragmen_poc_works() { - // Tests the POC test of the phragmen, mentioned in the paper and reference implementation. - // Initial votes: - // Votes [ - // ('2', 500, ['10', '20', '30']), - // ('4', 500, ['10', '20', '40']), - // ('10', 1000, ['10']), - // ('20', 1000, ['20']), - // ('30', 1000, ['30']), - // ('40', 1000, ['40'])] - // - // Sequential Phragmén gives - // 10 is elected with stake 1666.6666666666665 and score 0.0005 - // 20 is elected with stake 1333.3333333333333 and score 0.00075 - - // 2 has load 0.00075 and supported - // 10 with stake 333.3333333333333 20 with stake 166.66666666666666 30 with stake 0.0 - // 4 has load 0.00075 and supported - // 10 with stake 333.3333333333333 20 with stake 166.66666666666666 40 with stake 0.0 - // 10 has load 0.0005 and supported - // 10 with stake 1000.0 - // 20 has load 0.00075 and supported - // 20 with stake 1000.0 - // 30 has load 0 and supported - // 30 with stake 0 - // 40 has load 0 and supported - // 40 with stake 0 - - // Sequential Phragmén with post processing gives - // 10 is elected with stake 1500.0 and score 0.0005 - // 20 is elected with stake 1500.0 and score 0.00075 - // - // 10 has load 0.0005 and supported - // 10 with stake 1000.0 - // 20 has load 0.00075 and supported - // 20 with stake 1000.0 - // 30 has load 0 and supported - // 30 with stake 0 - // 40 has load 0 and supported - // 40 with stake 0 - // 2 has load 0.00075 and supported - // 10 with stake 166.66666666666674 20 with stake 333.33333333333326 30 with stake 0 - // 4 has load 0.00075 and supported - // 10 with stake 333.3333333333333 20 with stake 166.66666666666666 40 with stake 0.0 - with_externalities(&mut ExtBuilder::default() - .nominate(false) - .validator_pool(true) - .build(), - || { - // We don't really care about this. At this point everything is even. - assert_eq_uvec!(validator_controllers(), vec![40, 30]); - - // Set payees to Controller - assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller)); - assert_ok!(Staking::set_payee(Origin::signed(20), RewardDestination::Controller)); - assert_ok!(Staking::set_payee(Origin::signed(30), RewardDestination::Controller)); - assert_ok!(Staking::set_payee(Origin::signed(40), RewardDestination::Controller)); - - // no one is a nominator - assert_eq!(>::enumerate().count(), 0 as usize); - - // bond [2,1] / [4,3] a nominator - let _ = Balances::deposit_creating(&1, 1000); - let _ = Balances::deposit_creating(&3, 1000); - - assert_ok!(Staking::bond(Origin::signed(1), 2, 500, RewardDestination::default())); - assert_ok!(Staking::nominate(Origin::signed(2), vec![11, 21, 31])); - - assert_ok!(Staking::bond(Origin::signed(3), 4, 500, RewardDestination::default())); - assert_ok!(Staking::nominate(Origin::signed(4), vec![11, 21, 41])); - - // New era => election algorithm will trigger - start_era(1); - - assert_eq_uvec!(validator_controllers(), vec![20, 10]); - - assert_eq!(Staking::stakers(11).own, 1000); - assert_eq!(Staking::stakers(21).own, 1000); - - if cfg!(feature = "equalize") { - assert_eq!(Staking::stakers(11).total, 1000 + 499); - assert_eq!(Staking::stakers(21).total, 1000 + 499); - } else { - assert_eq!(Staking::stakers(11).total, 1000 + 332); - assert_eq!(Staking::stakers(21).total, 1000 + 666); - } - - // Nominator's stake distribution. - assert_eq!(Staking::stakers(11).others.iter().map(|e| e.who).collect::>>(), vec![3, 1]); - assert_eq!(Staking::stakers(21).others.iter().map(|e| e.who).collect::>>(), vec![3, 1]); - - if cfg!(feature = "equalize") { - assert_eq_uvec!( - Staking::stakers(11).others.iter().map(|e| e.value).collect::>>(), - vec![333, 166] - ); - assert_eq!( - Staking::stakers(11).others.iter().map(|e| e.value).sum::>(), - 499 - ); - assert_eq_uvec!( - Staking::stakers(21).others.iter().map(|e| e.value).collect::>>(), - vec![333, 166] - ); - assert_eq!( - Staking::stakers(21).others.iter().map(|e| e.value).sum::>(), - 499 - ); - } else { - assert_eq_uvec!( - Staking::stakers(11).others.iter().map(|e| e.value).collect::>>(), - vec![166, 166] - ); - assert_eq!( - Staking::stakers(11).others.iter().map(|e| e.value).sum::>(), - 332 - ); - assert_eq_uvec!( - Staking::stakers(21).others.iter().map(|e| e.value).collect::>>(), - vec![333, 333] - ); - assert_eq!( - Staking::stakers(21).others.iter().map(|e| e.value).sum::>(), - 666 - ); - } - check_exposure_all(); - check_nominator_all(); - }); -} #[test] fn switching_roles() { @@ -1638,13 +1547,13 @@ fn phragmen_linear_worse_case_equalize() { assert_eq_uvec!(validator_controllers(), vec![10, 60, 40, 20, 50, 30, 70]); - assert_eq!(Staking::stakers(11).total, 3000); - assert_eq!(Staking::stakers(21).total, 2254); - assert_eq!(Staking::stakers(31).total, 2254); - assert_eq!(Staking::stakers(41).total, 1926); - assert_eq!(Staking::stakers(51).total, 1871); - assert_eq!(Staking::stakers(61).total, 1892); - assert_eq!(Staking::stakers(71).total, 1799); + assert_eq_error_rate!(Staking::stakers(11).total, 3000, 2); + assert_eq_error_rate!(Staking::stakers(21).total, 2255, 2); + assert_eq_error_rate!(Staking::stakers(31).total, 2255, 2); + assert_eq_error_rate!(Staking::stakers(41).total, 1925, 2); + assert_eq_error_rate!(Staking::stakers(51).total, 1870, 2); + assert_eq_error_rate!(Staking::stakers(61).total, 1890, 2); + assert_eq_error_rate!(Staking::stakers(71).total, 1800, 2); check_exposure_all(); check_nominator_all(); @@ -1652,7 +1561,7 @@ fn phragmen_linear_worse_case_equalize() { } #[test] -fn phragmen_chooses_correct_number_of_validators() { +fn new_era_elects_correct_number_of_validators() { with_externalities(&mut ExtBuilder::default() .nominate(true) .validator_pool(true) @@ -1672,26 +1581,6 @@ fn phragmen_chooses_correct_number_of_validators() { }) } - -#[test] -fn phragmen_score_should_be_accurate_on_large_stakes() { - with_externalities(&mut ExtBuilder::default() - .nominate(false) - .build(), - || { - bond_validator(2, u64::max_value()); - bond_validator(4, u64::max_value()); - bond_validator(6, u64::max_value()-1); - bond_validator(8, u64::max_value()-2); - - start_era(1); - - assert_eq!(validator_controllers(), vec![4, 2]); - check_exposure_all(); - check_nominator_all(); - }) -} - #[test] fn phragmen_should_not_overflow_validators() { with_externalities(&mut ExtBuilder::default() @@ -1765,84 +1654,6 @@ fn phragmen_should_not_overflow_ultimate() { }) } - -#[test] -fn phragmen_large_scale_test() { - with_externalities(&mut ExtBuilder::default() - .nominate(false) - .minimum_validator_count(1) - .validator_count(20) - .build(), - || { - let _ = Staking::chill(Origin::signed(10)); - let _ = Staking::chill(Origin::signed(20)); - let _ = Staking::chill(Origin::signed(30)); - let prefix = 200; - - bond_validator(prefix + 2, 1); - bond_validator(prefix + 4, 100); - bond_validator(prefix + 6, 1000000); - bond_validator(prefix + 8, 100000000001000); - bond_validator(prefix + 10, 100000000002000); - bond_validator(prefix + 12, 100000000003000); - bond_validator(prefix + 14, 400000000000000); - bond_validator(prefix + 16, 400000000001000); - bond_validator(prefix + 18, 18000000000000000); - bond_validator(prefix + 20, 20000000000000000); - bond_validator(prefix + 22, 500000000000100000); - bond_validator(prefix + 24, 500000000000200000); - - bond_nominator(50, 990000000000000000, vec![ - prefix + 3, - prefix + 5, - prefix + 7, - prefix + 9, - prefix + 11, - prefix + 13, - prefix + 15, - prefix + 17, - prefix + 19, - prefix + 21, - prefix + 23, - prefix + 25] - ); - - start_era(1); - - check_exposure_all(); - check_nominator_all(); - }) -} - -#[test] -fn phragmen_large_scale_test_2() { - with_externalities(&mut ExtBuilder::default() - .nominate(false) - .minimum_validator_count(1) - .validator_count(2) - .build(), - || { - let _ = Staking::chill(Origin::signed(10)); - let _ = Staking::chill(Origin::signed(20)); - let nom_budget: u64 = 1_000_000_000_000_000_000; - let c_budget: u64 = 4_000_000; - - bond_validator(2, c_budget as u64); - bond_validator(4, c_budget as u64); - - bond_nominator(50, nom_budget, vec![3, 5]); - - start_era(1); - - // Each exposure => total == own + sum(others) - check_exposure_all(); - check_nominator_all(); - - assert_total_expo(3, nom_budget / 2 + c_budget); - assert_total_expo(5, nom_budget / 2 + c_budget); - }) -} - #[test] fn reward_validator_slashing_validator_doesnt_overflow() { with_externalities(&mut ExtBuilder::default() diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index 6935b4508d..1b8dc11f60 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -225,37 +225,6 @@ macro_rules! __assert_eq_uvec { } } -/// Checks that `$x` is equal to `$y` with an error rate of `$error`. -/// -/// # Example -/// -/// ```rust -/// # fn main() { -/// srml_support::assert_eq_error_rate!(10, 10, 0); -/// srml_support::assert_eq_error_rate!(10, 11, 1); -/// srml_support::assert_eq_error_rate!(12, 10, 2); -/// # } -/// ``` -/// -/// ```rust,should_panic -/// # fn main() { -/// srml_support::assert_eq_error_rate!(12, 10, 1); -/// # } -/// ``` -#[macro_export] -#[cfg(feature = "std")] -macro_rules! assert_eq_error_rate { - ($x:expr, $y:expr, $error:expr) => { - assert!( - ($x) >= (($y) - ($error)) && ($x) <= (($y) + ($error)), - "{:?} != {:?} (with error rate {:?})", - $x, - $y, - $error, - ); - }; -} - /// The void type - it cannot exist. // Oh rust, you crack me up... #[derive(Clone, Eq, PartialEq)] -- GitLab From 1d46eb3fbad19b6928a1dc9b8ffd75121a439c21 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Wed, 25 Sep 2019 16:43:11 +0200 Subject: [PATCH 138/275] Fix Phragmen equalize loop. (#3693) * Fix phragmen loop * Bump. --- core/phragmen/src/lib.rs | 10 ++++++---- node/runtime/src/lib.rs | 2 +- srml/staking/src/lib.rs | 3 +-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/core/phragmen/src/lib.rs b/core/phragmen/src/lib.rs index 8ea3d55552..5295d0f422 100644 --- a/core/phragmen/src/lib.rs +++ b/core/phragmen/src/lib.rs @@ -478,18 +478,20 @@ fn do_equalize( let mut cumulative_stake: ExtendedBalance = 0; let mut last_index = elected_edges.len() - 1; - elected_edges.iter_mut().enumerate().for_each(|(idx, e)| { + let mut idx = 0usize; + for e in &mut elected_edges[..] { if let Some(support) = support_map.get_mut(&e.0) { - let stake: ExtendedBalance = support.total; + let stake = support.total; let stake_mul = stake.saturating_mul(idx as ExtendedBalance); let stake_sub = stake_mul.saturating_sub(cumulative_stake); if stake_sub > budget { last_index = idx.checked_sub(1).unwrap_or(0); - return + break; } cumulative_stake = cumulative_stake.saturating_add(stake); } - }); + idx += 1; + } let last_stake = elected_edges[last_index].1; let split_ways = last_index + 1; diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index cc3a886e97..e7cc09b84f 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -85,7 +85,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 164, - impl_version: 164, + impl_version: 165, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index 4c73b64bd4..e82188a463 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -266,8 +266,7 @@ use sr_primitives::{ curve::PiecewiseLinear, weights::SimpleDispatchInfo, traits::{ - Convert, Zero, One, StaticLookup, CheckedSub, Saturating, Bounded, SimpleArithmetic, - SaturatedConversion, + Convert, Zero, One, StaticLookup, CheckedSub, Saturating, Bounded, SaturatedConversion, } }; use sr_staking_primitives::{ -- GitLab From 7da90cb8e24f7423383d52139ff7fea5bfa7e620 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 25 Sep 2019 22:38:29 +0200 Subject: [PATCH 139/275] Fix linkedmap instance head of (#3690) --- node/runtime/src/lib.rs | 2 +- .../procedural/src/storage/transformation.rs | 14 +- srml/support/test/tests/final_keys.rs | 212 ++++++++++++++---- 3 files changed, 175 insertions(+), 53 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index e7cc09b84f..0c1576e1da 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -84,7 +84,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 164, + spec_version: 165, impl_version: 165, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index 4fc8f67c42..83f62d97fc 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -600,15 +600,15 @@ fn create_and_impl_instance( instance_prefix: &str, ident: &Ident, doc: &TokenStream2, - const_names: &[(Ident, String)], + const_names: &[(Ident, String, String)], scrate: &TokenStream2, instantiable: &Ident, cratename: &Ident, ) -> TokenStream2 { let mut const_impls = TokenStream2::new(); - for (const_name, partial_const_value) in const_names { - let const_value = format!("{}{}", instance_prefix, partial_const_value); + for (const_name, const_value_prefix, const_value_suffix) in const_names { + let const_value = format!("{}{}{}", const_value_prefix, instance_prefix, const_value_suffix); const_impls.extend(quote! { const #const_name: &'static str = #const_value; }); @@ -666,15 +666,13 @@ fn decl_storage_items( let const_name = syn::Ident::new( &format!("{}{}", impls::PREFIX_FOR, name.to_string()), proc_macro2::Span::call_site() ); - let partial_const_value = prefix.clone(); - const_names.push((const_name, partial_const_value)); + const_names.push((const_name, String::new(), prefix.clone())); if let DeclStorageTypeInfosKind::Map { is_linked: true, .. } = type_infos.kind { let const_name = syn::Ident::new( &format!("{}{}", impls::HEAD_KEY_FOR, name.to_string()), proc_macro2::Span::call_site() ); - let partial_const_value = format!("head of {}", prefix); - const_names.push((const_name, partial_const_value)); + const_names.push((const_name, "head of ".into(), prefix)); } } @@ -685,7 +683,7 @@ fn decl_storage_items( // Declare Instance trait { let mut const_impls = TokenStream2::new(); - for (const_name, _) in &const_names { + for (const_name, ..) in &const_names { const_impls.extend(quote! { const #const_name: &'static str; }); diff --git a/srml/support/test/tests/final_keys.rs b/srml/support/test/tests/final_keys.rs index d53e0aa139..fdd41b04fe 100644 --- a/srml/support/test/tests/final_keys.rs +++ b/srml/support/test/tests/final_keys.rs @@ -14,87 +14,211 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use runtime_io::with_externalities; -use primitives::Blake2Hasher; +use runtime_io::with_storage; use support::storage::unhashed; -use codec::{Encode, Decode}; +use codec::Encode; +use support::{StorageDoubleMap, StorageLinkedMap, StorageMap, StorageValue}; -pub trait Trait { - type Origin; - type BlockNumber: Encode + Decode + Default + Clone; -} +mod no_instance { + use codec::{Encode, Decode}; -support::decl_module! { - pub struct Module for enum Call where origin: T::Origin {} -} + pub trait Trait { + type Origin; + type BlockNumber: Encode + Decode + Default + Clone; + } + + support::decl_module! { + pub struct Module for enum Call where origin: T::Origin {} + } -support::decl_storage!{ - trait Store for Module as FinalKeys { - pub Value config(value): u32; + support::decl_storage!{ + trait Store for Module as FinalKeysNone { + pub Value config(value): u32; - pub Map: map u32 => u32; - pub Map2: map hasher(twox_128) u32 => u32; + pub Map: map u32 => u32; + pub Map2: map hasher(twox_128) u32 => u32; - pub LinkedMap: linked_map u32 => u32; - pub LinkedMap2: linked_map hasher(twox_128) u32 => u32; + pub LinkedMap: linked_map u32 => u32; + pub LinkedMap2: linked_map hasher(twox_128) u32 => u32; - pub DoubleMap: double_map u32, blake2_256(u32) => u32; - pub DoubleMap2: double_map hasher(twox_128) u32, blake2_128(u32) => u32; + pub DoubleMap: double_map u32, blake2_256(u32) => u32; + pub DoubleMap2: double_map hasher(twox_128) u32, blake2_128(u32) => u32; - pub Foo get(foo) config(): Option; - pub Foo2 get(foo2) config(): double_map u32, blake2_256(T::BlockNumber) => Option; + pub TestGenericValue get(test_generic_value) config(): Option; + pub TestGenericDoubleMap get(foo2) config(test_generic_double_map): + double_map u32, blake2_256(T::BlockNumber) => Option; + } } } -struct Test; -impl Trait for Test { - type BlockNumber = u32; - type Origin = u32; +mod instance { + pub trait Trait: super::no_instance::Trait {} + + support::decl_module! { + pub struct Module, I: Instantiable = DefaultInstance> + for enum Call where origin: T::Origin {} + } + + support::decl_storage!{ + trait Store for Module, I: Instantiable = DefaultInstance> + as FinalKeysSome + { + pub Value config(value): u32; + + pub Map: map u32 => u32; + pub Map2: map hasher(twox_128) u32 => u32; + + pub LinkedMap: linked_map u32 => u32; + pub LinkedMap2: linked_map hasher(twox_128) u32 => u32; + + pub DoubleMap: double_map u32, blake2_256(u32) => u32; + pub DoubleMap2: double_map hasher(twox_128) u32, blake2_128(u32) => u32; + + pub TestGenericValue get(test_generic_value) config(): Option; + pub TestGenericDoubleMap get(foo2) config(test_generic_double_map): + double_map u32, blake2_256(T::BlockNumber) => Option; + } + add_extra_genesis { + // See `decl_storage` limitation. + config(phantom): core::marker::PhantomData; + } + } } -fn new_test_ext() -> runtime_io::TestExternalities { - GenesisConfig::::default().build_storage().unwrap().into() +#[test] +fn final_keys_no_instance() { + with_storage(&mut Default::default(), || { + no_instance::Value::put(1); + assert_eq!(unhashed::get::(&runtime_io::twox_128(b"FinalKeysNone Value")), Some(1u32)); + + no_instance::Map::insert(1, 2); + let mut k = b"FinalKeysNone Map".to_vec(); + k.extend(1u32.encode()); + assert_eq!(unhashed::get::(&runtime_io::blake2_256(&k)), Some(2u32)); + + no_instance::Map2::insert(1, 2); + let mut k = b"FinalKeysNone Map2".to_vec(); + k.extend(1u32.encode()); + assert_eq!(unhashed::get::(&runtime_io::twox_128(&k)), Some(2u32)); + + let head = b"head of FinalKeysNone LinkedMap".to_vec(); + assert_eq!(unhashed::get::(&runtime_io::blake2_256(&head)), None); + + no_instance::LinkedMap::insert(1, 2); + let mut k = b"FinalKeysNone LinkedMap".to_vec(); + k.extend(1u32.encode()); + assert_eq!(unhashed::get::(&runtime_io::blake2_256(&k)), Some(2u32)); + assert_eq!(unhashed::get::(&runtime_io::blake2_256(&head)), Some(1u32)); + + no_instance::LinkedMap2::insert(1, 2); + let mut k = b"FinalKeysNone LinkedMap2".to_vec(); + k.extend(1u32.encode()); + assert_eq!(unhashed::get::(&runtime_io::twox_128(&k)), Some(2u32)); + + no_instance::DoubleMap::insert(&1, &2, &3); + let mut k = b"FinalKeysNone DoubleMap".to_vec(); + k.extend(1u32.encode()); + let mut k = runtime_io::blake2_256(&k).to_vec(); + k.extend(&runtime_io::blake2_256(&2u32.encode())); + assert_eq!(unhashed::get::(&k), Some(3u32)); + + no_instance::DoubleMap2::insert(&1, &2, &3); + let mut k = b"FinalKeysNone DoubleMap2".to_vec(); + k.extend(1u32.encode()); + let mut k = runtime_io::twox_128(&k).to_vec(); + k.extend(&runtime_io::blake2_128(&2u32.encode())); + assert_eq!(unhashed::get::(&k), Some(3u32)); + }); } #[test] -fn final_keys() { - with_externalities(&mut new_test_ext(), || { - Value::put(1); - assert_eq!(unhashed::get::(&runtime_io::twox_128(b"FinalKeys Value")), Some(1u32)); +fn final_keys_default_instance() { + with_storage(&mut Default::default(), || { + >::put(1); + assert_eq!(unhashed::get::(&runtime_io::twox_128(b"FinalKeysSome Value")), Some(1u32)); + + >::insert(1, 2); + let mut k = b"FinalKeysSome Map".to_vec(); + k.extend(1u32.encode()); + assert_eq!(unhashed::get::(&runtime_io::blake2_256(&k)), Some(2u32)); + + >::insert(1, 2); + let mut k = b"FinalKeysSome Map2".to_vec(); + k.extend(1u32.encode()); + assert_eq!(unhashed::get::(&runtime_io::twox_128(&k)), Some(2u32)); + + let head = b"head of FinalKeysSome LinkedMap".to_vec(); + assert_eq!(unhashed::get::(&runtime_io::blake2_256(&head)), None); + + >::insert(1, 2); + let mut k = b"FinalKeysSome LinkedMap".to_vec(); + k.extend(1u32.encode()); + assert_eq!(unhashed::get::(&runtime_io::blake2_256(&k)), Some(2u32)); + assert_eq!(unhashed::get::(&runtime_io::blake2_256(&head)), Some(1u32)); - Map::insert(1, 2); - let mut k = b"FinalKeys Map".to_vec(); +< instance::LinkedMap2>::insert(1, 2); + let mut k = b"FinalKeysSome LinkedMap2".to_vec(); + k.extend(1u32.encode()); + assert_eq!(unhashed::get::(&runtime_io::twox_128(&k)), Some(2u32)); + + >::insert(&1, &2, &3); + let mut k = b"FinalKeysSome DoubleMap".to_vec(); + k.extend(1u32.encode()); + let mut k = runtime_io::blake2_256(&k).to_vec(); + k.extend(&runtime_io::blake2_256(&2u32.encode())); + assert_eq!(unhashed::get::(&k), Some(3u32)); + + >::insert(&1, &2, &3); + let mut k = b"FinalKeysSome DoubleMap2".to_vec(); + k.extend(1u32.encode()); + let mut k = runtime_io::twox_128(&k).to_vec(); + k.extend(&runtime_io::blake2_128(&2u32.encode())); + assert_eq!(unhashed::get::(&k), Some(3u32)); + }); +} + +#[test] +fn final_keys_instance_2() { + with_storage(&mut Default::default(), || { + >::put(1); + assert_eq!( + unhashed::get::(&runtime_io::twox_128(b"Instance2FinalKeysSome Value")), + Some(1u32) + ); + + >::insert(1, 2); + let mut k = b"Instance2FinalKeysSome Map".to_vec(); k.extend(1u32.encode()); assert_eq!(unhashed::get::(&runtime_io::blake2_256(&k)), Some(2u32)); - Map2::insert(1, 2); - let mut k = b"FinalKeys Map2".to_vec(); + >::insert(1, 2); + let mut k = b"Instance2FinalKeysSome Map2".to_vec(); k.extend(1u32.encode()); assert_eq!(unhashed::get::(&runtime_io::twox_128(&k)), Some(2u32)); - let head = b"head of FinalKeys LinkedMap".to_vec(); + let head = b"head of Instance2FinalKeysSome LinkedMap".to_vec(); assert_eq!(unhashed::get::(&runtime_io::blake2_256(&head)), None); - LinkedMap::insert(1, 2); - let mut k = b"FinalKeys LinkedMap".to_vec(); + >::insert(1, 2); + let mut k = b"Instance2FinalKeysSome LinkedMap".to_vec(); k.extend(1u32.encode()); assert_eq!(unhashed::get::(&runtime_io::blake2_256(&k)), Some(2u32)); assert_eq!(unhashed::get::(&runtime_io::blake2_256(&head)), Some(1u32)); - LinkedMap2::insert(1, 2); - let mut k = b"FinalKeys LinkedMap2".to_vec(); + >::insert(1, 2); + let mut k = b"Instance2FinalKeysSome LinkedMap2".to_vec(); k.extend(1u32.encode()); assert_eq!(unhashed::get::(&runtime_io::twox_128(&k)), Some(2u32)); - DoubleMap::insert(&1, &2, &3); - let mut k = b"FinalKeys DoubleMap".to_vec(); + >::insert(&1, &2, &3); + let mut k = b"Instance2FinalKeysSome DoubleMap".to_vec(); k.extend(1u32.encode()); let mut k = runtime_io::blake2_256(&k).to_vec(); k.extend(&runtime_io::blake2_256(&2u32.encode())); assert_eq!(unhashed::get::(&k), Some(3u32)); - DoubleMap2::insert(&1, &2, &3); - let mut k = b"FinalKeys DoubleMap2".to_vec(); + >::insert(&1, &2, &3); + let mut k = b"Instance2FinalKeysSome DoubleMap2".to_vec(); k.extend(1u32.encode()); let mut k = runtime_io::twox_128(&k).to_vec(); k.extend(&runtime_io::blake2_128(&2u32.encode())); -- GitLab From cb1a068f65f777b11d0b42945e4df6aba93d9bff Mon Sep 17 00:00:00 2001 From: Ashley Date: Thu, 26 Sep 2019 19:36:58 +1200 Subject: [PATCH 140/275] Random seed API for offchain workers (#3694) * Add random_seed impl for offchain api * switch to rand::random --- core/offchain/src/api.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/core/offchain/src/api.rs b/core/offchain/src/api.rs index 0057dfd273..62b73f28d6 100644 --- a/core/offchain/src/api.rs +++ b/core/offchain/src/api.rs @@ -101,7 +101,7 @@ where } fn random_seed(&mut self) -> [u8; 32] { - unavailable_yet("random_seed") + rand::random() } fn local_storage_set(&mut self, kind: StorageKind, key: &[u8], value: &[u8]) { @@ -466,4 +466,13 @@ mod tests { // then assert_eq!(state, converted_back_state); } + + #[test] + fn should_get_random_seed() { + // given + let mut api = offchain_api().0; + let seed = api.random_seed(); + // then + assert_ne!(seed, [0; 32]); + } } -- GitLab From 429380ea7d109bce29d6aba2c66f33e79c61ea11 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Thu, 26 Sep 2019 11:44:52 +0200 Subject: [PATCH 141/275] Improve storage doc (#3691) * doc * fix * Apply suggestions from code review Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * complete suggestion --- srml/support/procedural/src/lib.rs | 54 +++++++++---------- .../src/storage/generator/double_map.rs | 14 +++-- .../src/storage/generator/linked_map.rs | 22 +++++++- srml/support/src/storage/generator/map.rs | 10 +++- srml/support/src/storage/generator/value.rs | 5 +- 5 files changed, 70 insertions(+), 35 deletions(-) diff --git a/srml/support/procedural/src/lib.rs b/srml/support/procedural/src/lib.rs index ea6a8a7995..a9cfa8d30d 100644 --- a/srml/support/procedural/src/lib.rs +++ b/srml/support/procedural/src/lib.rs @@ -44,12 +44,18 @@ use proc_macro::TokenStream; /// with `Store` a (pub) trait generated associating each storage item to the `Module` and /// `as Example` setting the prefix used for storage items of this module. `Example` must be unique: /// another module with the same name and the same inner storage item name will conflict. +/// `Example` is called the module prefix. +/// +/// note: For instantiable modules the module prefix is prepended with instance +/// prefix. Instance prefix is "" for default instance and "Instance$n" for instance number $n. +/// Thus, instance 3 of module Example has a module prefix of `Instance3Example` /// /// Basic storage consists of a name and a type; supported types are: /// /// * Value: `Foo: type`: Implements the /// [`StorageValue`](../srml_support/storage/trait.StorageValue.html) trait using the /// [`StorageValue generator`](../srml_support/storage/generator/trait.StorageValue.html). +/// The generator `unhashed_key` is `$module_prefix ++ " " ++ $storage_name` /// /// * Map: `Foo: map hasher($hash) type => type`: Implements the /// [`StorageMap`](../srml_support/storage/trait.StorageMap.html) trait using the @@ -58,12 +64,12 @@ use proc_macro::TokenStream; /// `$hash` representing a choice of hashing algorithms available in the /// [`Hashable`](../srml_support/trait.Hashable.html) trait. /// -/// `hasher($hash)` is optional and its default is `blake2_256`. +/// `hasher($hash)` is optional and its default is `blake2_256`. One should use another hasher +/// with care, see generator documentation. /// -/// /!\ Be careful with each key in the map that is inserted in the trie -/// `$hash(module_name ++ " " ++ storage_name ++ encoding(key))`. -/// If the keys are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as -/// `blake2_256` must be used. Otherwise, other values in storage can be compromised. +/// The generator is implemented with: +/// * `prefix`: `$module_prefix ++ " " ++ $storage_name` +/// * `Hasher`: $hash /// /// * Linked map: `Foo: linked_map hasher($hash) type => type`: Implements the /// [`StorageLinkedMap`](../srml_support/storage/trait.StorageLinkedMap.html) trait using the @@ -72,39 +78,26 @@ use proc_macro::TokenStream; /// `$hash` representing a choice of hashing algorithms available in the /// [`Hashable`](../srml_support/trait.Hashable.html) trait. /// -/// `hasher($hash)` is optional and its default is `blake2_256`. -/// -/// /!\ Be careful with each key in the map that is inserted in the trie -/// `$hash(module_name ++ " " ++ storage_name ++ encoding(key))`. -/// If the keys are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as -/// `blake2_256` must be used. Otherwise, other values in storage can be compromised. +/// `hasher($hash)` is optional and its default is `blake2_256`. One should use another hasher +/// with care, see generator documentation. /// -/// Once read from the trie (e.g. through an RPC call), a tuple of `(T, Linkage)` is returned, -/// where `T` is the value and `K` is the key type of the mapping. -/// [`Linkage`](../srml_support/storage/generator/struct.Linkage.html) is a pointer to the -/// previous and the next element. -/// -/// Each linked map has a special key in the trie that can be queried and it can be particularly -/// useful to query all items: `"head of " ++ module_name ++ " " ++ storage_name`). This will -/// return a key `K` that can be later on used with the aforementioned `$hash(module_name ++ " " -/// ++ storage_name ++ encoding(K))` to fetch the head. For consequent elements, the -/// [`Linkage`](../srml_support/storage/generator/struct.Linkage.html) can be used. +/// The generator is implemented with: +/// * `prefix`: `$module_prefix ++ " " ++ $storage_name` +/// * `head_key`: `"head of " ++ $module_prefix ++ " " ++ $storage_name` +/// * `Hasher`: $hash /// /// * Double map: `Foo: double_map hasher($hash1) u32, $hash2(u32) => u32`: Implements the /// [`StorageDoubleMap`](../srml_support/storage/trait.StorageDoubleMap.html) trait using the /// [`StorageDoubleMap generator`](../srml_support/storage/generator/trait.StorageDoubleMap.html). /// /// `$hash1` and `$hash2` representing choices of hashing algorithms available in the -/// [`Hashable`](../srml_support/trait.Hashable.html) trait. +/// [`Hashable`](../srml_support/trait.Hashable.html) trait. They must be choosen with care, see +/// generator documentation. /// /// `hasher($hash)` is optional and its default is `blake2_256`. /// -/// /!\ Be careful with each key pair in the double map that is inserted in the trie. -/// The final key is calculated as follows: -/// -/// ```nocompile -/// $hash(module_name ++ " " ++ storage_name ++ encoding(first_key)) ++ $hash2(encoding(second_key)) -/// ``` +/// `hasher($hash)` is optional and its default is `blake2_256`. One should use another hasher +/// with care, see generator documentation. /// /// If the first key is untrusted, a cryptographic `hasher` such as `blake2_256` must be used. /// Otherwise, other values of all storage items can be compromised. @@ -112,6 +105,11 @@ use proc_macro::TokenStream; /// If the second key is untrusted, a cryptographic `hasher` such as `blake2_256` must be used. /// Otherwise, other items in storage with the same first key can be compromised. /// +/// The generator is implemented with: +/// * `key1_prefix`: `$module_prefix ++ " " ++ $storage_name` +/// * `Hasher1`: $hash1 +/// * `Hasher2`: $hash2 +/// /// Supported hashers (ordered from least to best security): /// /// * `twox_64_concat` - TwoX with 64bit + key concatenated. diff --git a/srml/support/src/storage/generator/double_map.rs b/srml/support/src/storage/generator/double_map.rs index 46361340ac..b41fe47422 100644 --- a/srml/support/src/storage/generator/double_map.rs +++ b/srml/support/src/storage/generator/double_map.rs @@ -26,10 +26,18 @@ use crate::{storage::{self, unhashed, hashed::StorageHasher}, rstd::borrow::Borr /// The first part is a hash of a concatenation of the `key1_prefix` and `Key1`. And the second part /// is a hash of a `Key2`. /// -/// Thus value for (key1, key2) is stored at `Hasher1(key1_prefix ++ key1) ++ Hasher2(key2)`. +/// Thus value for (key1, key2) is stored at: +/// ```nocompile +/// Hasher1(key1_prefix ++ key1) ++ Hasher2(key2) +/// ``` /// -/// /!\ be careful while choosing the Hash, indeed malicious could craft second keys to lower the -/// trie. +/// # Warning +/// +/// If the key1s are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as +/// `blake2_256` must be used for Hasher1. Otherwise, other values in storage can be compromised. +/// If the key2s are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as +/// `blake2_256` must be used for Hasher2. Otherwise, other items in storage with the same first +/// key can be compromised. pub trait StorageDoubleMap { /// The type that get/take returns. type Query; diff --git a/srml/support/src/storage/generator/linked_map.rs b/srml/support/src/storage/generator/linked_map.rs index 2c69df4364..d11c025afb 100644 --- a/srml/support/src/storage/generator/linked_map.rs +++ b/srml/support/src/storage/generator/linked_map.rs @@ -23,8 +23,26 @@ use rstd::{ /// Generator for `StorageLinkedMap` used by `decl_storage`. /// -/// For each key value is stored at `Hasher(prefix ++ key)` along with a linkage used for -/// enumeration. +/// # Mapping of keys to a storage path +/// +/// The key for the head of the map is stored at one fixed path: +/// ```nocompile +/// Hasher(head_key) +/// ``` +/// +/// For each key, the value stored under that key is appended with a +/// [`Linkage`](struct.Linkage.html) (which hold previous and next key) at the path: +/// ```nocompile +/// Hasher(prefix ++ key) +/// ``` +/// +/// Enumeration is done by getting the head of the linked map and then iterating getting the +/// value and linkage stored at the key until the found linkage has no next key. +/// +/// # Warning +/// +/// If the keys are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as +/// `blake2_256` must be used. Otherwise, other values in storage can be compromised. pub trait StorageLinkedMap { /// The type that get/take returns. type Query; diff --git a/srml/support/src/storage/generator/map.rs b/srml/support/src/storage/generator/map.rs index 48b8cc097f..f5b22fc19a 100644 --- a/srml/support/src/storage/generator/map.rs +++ b/srml/support/src/storage/generator/map.rs @@ -22,7 +22,15 @@ use crate::{storage::{self, unhashed, hashed::StorageHasher}, traits::Len}; /// Generator for `StorageMap` used by `decl_storage`. /// -/// For each key value is stored at `Hasher(prefix ++ key)`. +/// For each key value is stored at: +/// ```nocompile +/// Hasher(prefix ++ key) +/// ``` +/// +/// # Warning +/// +/// If the keys are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as +/// `blake2_256` must be used. Otherwise, other values in storage can be compromised. pub trait StorageMap { /// The type that get/take returns. type Query; diff --git a/srml/support/src/storage/generator/value.rs b/srml/support/src/storage/generator/value.rs index 69851db1a0..2f632d94d3 100644 --- a/srml/support/src/storage/generator/value.rs +++ b/srml/support/src/storage/generator/value.rs @@ -22,7 +22,10 @@ use crate::{storage::{self, unhashed, hashed::{Twox128, StorageHasher}}, traits: /// Generator for `StorageValue` used by `decl_storage`. /// -/// Value is stored at `Twox128(unhashed_key)`. +/// Value is stored at: +/// ```nocompile +/// Twox128(unhashed_key) +/// ``` pub trait StorageValue { /// The type that get/take returns. type Query; -- GitLab From 3015ae94b7b48d115f836af8724526ab77a4d040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Thu, 26 Sep 2019 18:23:01 +0100 Subject: [PATCH 142/275] grandpa: send authority id to telemetry when starting new voter (#3705) --- core/finality-grandpa/src/lib.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/core/finality-grandpa/src/lib.rs b/core/finality-grandpa/src/lib.rs index abf6476e98..4dc93c381f 100644 --- a/core/finality-grandpa/src/lib.rs +++ b/core/finality-grandpa/src/lib.rs @@ -632,19 +632,22 @@ where /// has changed (e.g. as signalled by a voter command). fn rebuild_voter(&mut self) { debug!(target: "afg", "{}: Starting new voter with set ID {}", self.env.config.name(), self.env.set_id); + + let authority_id = is_voter(&self.env.voters, &self.env.config.keystore) + .map(|ap| ap.public()) + .unwrap_or(Default::default()); + telemetry!(CONSENSUS_DEBUG; "afg.starting_new_voter"; - "name" => ?self.env.config.name(), "set_id" => ?self.env.set_id + "name" => ?self.env.config.name(), + "set_id" => ?self.env.set_id, + "authority_id" => authority_id.to_string(), ); let chain_info = self.env.inner.info(); - - let maybe_authority_id = is_voter(&self.env.voters, &self.env.config.keystore) - .map(|ap| ap.public()) - .unwrap_or(Default::default()); telemetry!(CONSENSUS_INFO; "afg.authority_set"; "number" => ?chain_info.chain.finalized_number, "hash" => ?chain_info.chain.finalized_hash, - "authority_id" => maybe_authority_id.to_string(), + "authority_id" => authority_id.to_string(), "authority_set_id" => ?self.env.set_id, "authorities" => { let authorities: Vec = self.env.voters.voters() -- GitLab From 7d3f3a63c8bc51ecf3d1d3d95afac42376517320 Mon Sep 17 00:00:00 2001 From: Caio Date: Thu, 26 Sep 2019 17:21:12 -0300 Subject: [PATCH 143/275] Pointer does not implement Display (#3707) Instead, use `Debug` for `debug_trace!` --- core/executor/src/wasm_executor.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/executor/src/wasm_executor.rs b/core/executor/src/wasm_executor.rs index 9f8d678d1a..bfd33f0f16 100644 --- a/core/executor/src/wasm_executor.rs +++ b/core/executor/src/wasm_executor.rs @@ -369,13 +369,13 @@ impl_wasm_host_interface! { impl SubstrateExternals where context { ext_malloc(size: WordSize) -> Pointer { let r = context.allocate_memory(size)?; - debug_trace!(target: "sr-io", "malloc {} bytes at {}", size, r); + debug_trace!(target: "sr-io", "malloc {} bytes at {:?}", size, r); Ok(r) } ext_free(addr: Pointer) { context.deallocate_memory(addr)?; - debug_trace!(target: "sr-io", "free {}", addr); + debug_trace!(target: "sr-io", "free {:?}", addr); Ok(()) } -- GitLab From f843fdc0265c9244866b34124a9b8b342d69c462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 26 Sep 2019 23:02:30 +0200 Subject: [PATCH 144/275] Make `TestOffchainExt` panic on unknown requests (#3710) * Make `TestOffchainExt` panic on unknown requests * Fix test --- core/executor/src/wasm_executor.rs | 2 +- core/offchain/src/testing.rs | 22 +++++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/core/executor/src/wasm_executor.rs b/core/executor/src/wasm_executor.rs index bfd33f0f16..afdbe57640 100644 --- a/core/executor/src/wasm_executor.rs +++ b/core/executor/src/wasm_executor.rs @@ -1842,7 +1842,7 @@ mod tests { body: vec![1, 2, 3, 4], headers: vec![("X-Auth".to_owned(), "test".to_owned())], sent: true, - response: vec![1, 2, 3], + response: Some(vec![1, 2, 3]), response_headers: vec![("X-Auth".to_owned(), "hello".to_owned())], ..Default::default() }, diff --git a/core/offchain/src/testing.rs b/core/offchain/src/testing.rs index 496feb4b63..e1cc7f71a3 100644 --- a/core/offchain/src/testing.rs +++ b/core/offchain/src/testing.rs @@ -48,7 +48,7 @@ pub struct PendingRequest { /// Has the request been sent already. pub sent: bool, /// Response body - pub response: Vec, + pub response: Option>, /// Number of bytes already read from the response body. pub read: usize, /// Response headers @@ -89,7 +89,7 @@ impl State { *req, expected, ); - req.response = response.into(); + req.response = Some(response.into()); req.response_headers = response_headers.into_iter().collect(); } } @@ -97,7 +97,7 @@ impl State { fn fulfill_expected(&mut self, id: u16) { if let Some(mut req) = self.expected_requests.remove(&RequestId(id)) { - let response = std::mem::replace(&mut req.response, vec![]); + let response = req.response.take().expect("Response checked while added."); let headers = std::mem::replace(&mut req.response_headers, vec![]); self.fulfill_pending_request(id, req, response, headers); } @@ -110,6 +110,9 @@ impl State { /// Expected request has to be fulfilled before this struct is dropped, /// the `response` and `response_headers` fields will be used to return results to the callers. pub fn expect_request(&mut self, id: u16, expected: PendingRequest) { + if expected.response.is_none() { + panic!("Expected request needs to have a response."); + } self.expected_requests.insert(RequestId(id), expected); } } @@ -254,7 +257,8 @@ impl offchain::Externalities for TestOffchainExt { let state = self.0.read(); ids.iter().map(|id| match state.requests.get(id) { - Some(req) if req.response.is_empty() => RequestStatus::DeadlineReached, + Some(req) if req.response.is_none() => + panic!("No `response` provided for request with id: {:?}", id), None => RequestStatus::Invalid, _ => RequestStatus::Finished(200), }).collect() @@ -281,13 +285,17 @@ impl offchain::Externalities for TestOffchainExt { ) -> Result { let mut state = self.0.write(); if let Some(req) = state.requests.get_mut(&request_id) { - if req.read >= req.response.len() { + let response = req.response + .as_mut() + .expect(&format!("No response provided for request: {:?}", request_id)); + + if req.read >= response.len() { // Remove the pending request as per spec. state.requests.remove(&request_id); Ok(0) } else { - let read = std::cmp::min(buffer.len(), req.response[req.read..].len()); - buffer[0..read].copy_from_slice(&req.response[req.read..read]); + let read = std::cmp::min(buffer.len(), response[req.read..].len()); + buffer[0..read].copy_from_slice(&response[req.read..read]); req.read += read; Ok(read) } -- GitLab From 6c2df4a49039f054625f4f8d4cbdd5a6b20b1766 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Fri, 27 Sep 2019 15:48:29 +0800 Subject: [PATCH 145/275] Update libsecp256k1 dep to 0.3.0 (#3711) * Update libsecp256k1 dep to 0.3.0 * Bump impl_version --- Cargo.lock | 39 ++++++++++++++++++++++++++++++++------- core/executor/Cargo.toml | 2 +- core/sr-io/Cargo.toml | 2 +- node/runtime/src/lib.rs | 2 +- 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f4780648d6..c2cbee8e22 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1058,7 +1058,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1066,7 +1066,7 @@ name = "generic-array" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1240,6 +1240,16 @@ dependencies = [ "hmac 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hmac-drbg" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", + "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "http" version = "0.1.17" @@ -2032,7 +2042,20 @@ dependencies = [ "hmac-drbg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libsecp256k1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hmac-drbg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3822,7 +3845,7 @@ version = "2.0.0" dependencies = [ "environmental 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libsecp256k1 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", @@ -4925,7 +4948,7 @@ dependencies = [ "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libsecp256k1 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.40.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6017,7 +6040,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "typenum" -version = "1.10.0" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -6646,6 +6669,7 @@ dependencies = [ "checksum hmac 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a13f4163aa0c5ca1be584aace0e2212b2e41be5478218d4f657f5f778b2ae2a" "checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" "checksum hmac-drbg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4fe727d41d2eec0a6574d887914347e5ff96a3b87177817e2a9820c5c87fecc2" +"checksum hmac-drbg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" "checksum http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "eed324f0f0daf6ec10c474f150505af2c143f251722bf9dbd1261bd1f2ee2c1a" "checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" @@ -6709,6 +6733,7 @@ dependencies = [ "checksum libp2p-yamux 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a37bed07c8ee0ceeecdfb90d703aa6b1cec99a69b4157e5f7f2c03acacbfca15" "checksum librocksdb-sys 5.18.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d19778314deaa7048f2ea7d07b8aa12e1c227acebe975a37eeab6d2f8c74e41b" "checksum libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "688e8d65e495567c2c35ea0001b26b9debf0b4ea11f8cccc954233b75fc3428a" +"checksum libsecp256k1 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf0a4113e7b18b72b9b65d5b35335d99865ef059034426e4b85ad63adddf996" "checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" "checksum linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7c91c4c7bbeb4f2f7c4e5be11e6a05bd6830bc37249c47ce1ad86ad453ff9c" @@ -6931,7 +6956,7 @@ dependencies = [ "checksum twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d261e83e727c8e2dbb75dacac67c36e35db36a958ee504f2164fc052434e1" "checksum twox-hash 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7834480552ffc48e1930ceddd701f47d2234319d80b7bcbbe2fe7202933c101" "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" -"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" +"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" "checksum ucd-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa9b3b49edd3468c0e6565d85783f51af95212b6fa3986a5500954f00b460874" "checksum uint 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5375d2c574f89adad4108ad525c93e39669853a602560bf5ed4ca9943b10799" "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" diff --git a/core/executor/Cargo.toml b/core/executor/Cargo.toml index 77f07faa33..dade16a935 100644 --- a/core/executor/Cargo.toml +++ b/core/executor/Cargo.toml @@ -19,7 +19,7 @@ parity-wasm = "0.40.1" lazy_static = "1.3" parking_lot = "0.9.0" log = "0.4" -libsecp256k1 = "0.2.1" +libsecp256k1 = "0.3" tiny-keccak = "1.4.2" [dev-dependencies] diff --git a/core/sr-io/Cargo.toml b/core/sr-io/Cargo.toml index 7382cfb002..a529c1e757 100644 --- a/core/sr-io/Cargo.toml +++ b/core/sr-io/Cargo.toml @@ -13,7 +13,7 @@ rstd = { package = "sr-std", path = "../sr-std", default-features = false } primitives = { package = "substrate-primitives", path = "../primitives", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } hash-db = { version = "0.15.2", default-features = false } -libsecp256k1 = { version = "0.2.1", optional = true } +libsecp256k1 = { version = "0.3", optional = true } tiny-keccak = { version = "1.4.2", optional = true } environmental = { version = "1.0.1", optional = true } substrate-state-machine = { path = "../state-machine", optional = true } diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 0c1576e1da..337e1ac358 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -85,7 +85,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 165, - impl_version: 165, + impl_version: 166, apis: RUNTIME_API_VERSIONS, }; -- GitLab From c3c4047991199a495f09573aa814cc5d2227c38b Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 27 Sep 2019 12:43:25 +0300 Subject: [PATCH 146/275] Enable runtime_api for Substrate service (#3709) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * added new_full_concrete for service * line width fix * Update node/cli/src/service.rs Co-Authored-By: Bastian Köcher * Update node/cli/src/service.rs Co-Authored-By: Bastian Köcher * Update node/cli/src/service.rs Co-Authored-By: Bastian Köcher * replaced new_full * empty * added backticks to pass ci --- Cargo.lock | 2 + .../tests/ui/declaring_old_block.stderr | 2 +- ...aring_own_block_with_different_name.stderr | 2 +- node/cli/Cargo.toml | 3 ++ node/cli/src/service.rs | 42 ++++++++++++++++++- 5 files changed, 48 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c2cbee8e22..d36c73c8c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2370,6 +2370,7 @@ dependencies = [ "substrate-basic-authorship 2.0.0", "substrate-cli 2.0.0", "substrate-client 2.0.0", + "substrate-client-db 2.0.0", "substrate-consensus-babe 2.0.0", "substrate-consensus-babe-primitives 2.0.0", "substrate-consensus-common 2.0.0", @@ -2379,6 +2380,7 @@ dependencies = [ "substrate-keyring 2.0.0", "substrate-keystore 2.0.0", "substrate-network 2.0.0", + "substrate-offchain 2.0.0", "substrate-primitives 2.0.0", "substrate-rpc 2.0.0", "substrate-service 2.0.0", diff --git a/core/sr-api-macros/tests/ui/declaring_old_block.stderr b/core/sr-api-macros/tests/ui/declaring_old_block.stderr index 181aa2a3ca..999a50cc96 100644 --- a/core/sr-api-macros/tests/ui/declaring_old_block.stderr +++ b/core/sr-api-macros/tests/ui/declaring_old_block.stderr @@ -16,4 +16,4 @@ warning: unused import: `sr_primitives::traits::Block as BlockT` 1 | use sr_primitives::traits::Block as BlockT; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: #[warn(unused_imports)] on by default + = note: `#[warn(unused_imports)]` on by default diff --git a/core/sr-api-macros/tests/ui/declaring_own_block_with_different_name.stderr b/core/sr-api-macros/tests/ui/declaring_own_block_with_different_name.stderr index a591d0448c..ec033f2e09 100644 --- a/core/sr-api-macros/tests/ui/declaring_own_block_with_different_name.stderr +++ b/core/sr-api-macros/tests/ui/declaring_own_block_with_different_name.stderr @@ -10,4 +10,4 @@ warning: unused import: `sr_primitives::traits::Block as BlockT` 1 | use sr_primitives::traits::Block as BlockT; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: #[warn(unused_imports)] on by default + = note: `#[warn(unused_imports)]` on by default diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index 933ee0c046..39ebcb321d 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -48,6 +48,9 @@ support = { package = "srml-support", path = "../../srml/support", default-featu im_online = { package = "srml-im-online", path = "../../srml/im-online", default-features = false } sr-authority-discovery = { package = "srml-authority-discovery", path = "../../srml/authority-discovery", default-features = false } authority-discovery = { package = "substrate-authority-discovery", path = "../../core/authority-discovery"} +client_db = { package = "substrate-client-db", path = "../../core/client/db", features = ["kvdb-rocksdb"] } +offchain = { package = "substrate-offchain", path = "../../core/offchain" } + [dev-dependencies] keystore = { package = "substrate-keystore", path = "../../core/keystore" } diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index 58d94119b5..4a5f7eab86 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -33,6 +33,16 @@ use transaction_pool::{self, txpool::{Pool as TransactionPool}}; use inherents::InherentDataProviders; use network::construct_simple_protocol; +use substrate_service::{NewService, NetworkStatus}; +use client::{Client, LocalCallExecutor}; +use client_db::Backend; +use sr_primitives::traits::Block as BlockT; +use node_executor::NativeExecutor; +use network::NetworkService; +use offchain::OffchainWorkers; +use transaction_pool::ChainApi; +use primitives::Blake2Hasher; + construct_simple_protocol! { /// Demo protocol attachment for substrate. pub struct NodeProtocol where Block = Block { } @@ -215,9 +225,39 @@ macro_rules! new_full { }} } +#[allow(dead_code)] +type ConcreteBlock = node_primitives::Block; +#[allow(dead_code)] +type ConcreteClient = + Client< + Backend, + LocalCallExecutor, + NativeExecutor>, + ConcreteBlock, + node_runtime::RuntimeApi + >; +#[allow(dead_code)] +type ConcreteBackend = Backend; + /// Builds a new service for a full client. pub fn new_full(config: Configuration) --> Result { +-> Result< + NewService< + ConcreteBlock, + ConcreteClient, + LongestChain, + NetworkStatus, + NetworkService::Hash>, + TransactionPool>, + OffchainWorkers< + ConcreteClient, + >::OffchainStorage, + ConcreteBlock, + > + >, + ServiceError, +> +{ new_full!(config).map(|(service, _)| service) } -- GitLab From aa049e65ae8ab2e8e6fc2bad01c5cd2b75af7df8 Mon Sep 17 00:00:00 2001 From: Coenen Benjamin Date: Fri, 27 Sep 2019 11:46:53 +0200 Subject: [PATCH 147/275] create some vectors with initial capacities (#3701) Signed-off-by: Benjamin Coenen --- core/client/db/src/lib.rs | 28 +++++++++++++--------------- core/phragmen/benches/phragmen.rs | 4 ++-- core/sr-io/without_std.rs | 4 ++-- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/core/client/db/src/lib.rs b/core/client/db/src/lib.rs index 62cc8027c2..daf0f47889 100644 --- a/core/client/db/src/lib.rs +++ b/core/client/db/src/lib.rs @@ -1048,24 +1048,22 @@ impl> Backend { operation.apply_aux(&mut transaction); - let mut meta_updates = Vec::new(); + let mut meta_updates = Vec::with_capacity(operation.finalized_blocks.len()); let mut last_finalized_hash = self.blockchain.meta.read().finalized_hash; - if !operation.finalized_blocks.is_empty() { - for (block, justification) in operation.finalized_blocks { - let block_hash = self.blockchain.expect_block_hash_from_id(&block)?; - let block_header = self.blockchain.expect_header(BlockId::Hash(block_hash))?; + for (block, justification) in operation.finalized_blocks { + let block_hash = self.blockchain.expect_block_hash_from_id(&block)?; + let block_header = self.blockchain.expect_header(BlockId::Hash(block_hash))?; - meta_updates.push(self.finalize_block_with_transaction( - &mut transaction, - &block_hash, - &block_header, - Some(last_finalized_hash), - justification, - &mut finalization_displaced_leaves, - )?); - last_finalized_hash = block_hash; - } + meta_updates.push(self.finalize_block_with_transaction( + &mut transaction, + &block_hash, + &block_header, + Some(last_finalized_hash), + justification, + &mut finalization_displaced_leaves, + )?); + last_finalized_hash = block_hash; } let imported = if let Some(pending_block) = operation.pending_block { diff --git a/core/phragmen/benches/phragmen.rs b/core/phragmen/benches/phragmen.rs index fec849ab93..b73811b33f 100644 --- a/core/phragmen/benches/phragmen.rs +++ b/core/phragmen/benches/phragmen.rs @@ -61,8 +61,7 @@ fn do_phragmen( // prefix to distinguish the validator and nominator account ranges. let np = 10_000; - let mut candidates = vec![]; - let mut voters = vec![]; + let mut candidates = Vec::with_capacity(num_vals as usize); let mut slashable_balance_of: BTreeMap = BTreeMap::new(); (1 ..= num_vals) @@ -71,6 +70,7 @@ fn do_phragmen( slashable_balance_of.insert(acc, STAKE + rr(10, 50)); }); + let mut voters = Vec::with_capacity(num_noms as usize); (np ..= (np + num_noms)) .for_each(|acc| { let mut stashes_to_vote = candidates.clone(); diff --git a/core/sr-io/without_std.rs b/core/sr-io/without_std.rs index ad5ed77d70..95087b0c48 100644 --- a/core/sr-io/without_std.rs +++ b/core/sr-io/without_std.rs @@ -737,8 +737,8 @@ impl StorageApi for () { } fn blake2_256_ordered_trie_root(input: Vec>) -> H256 { - let mut values = Vec::new(); - let mut lengths = Vec::new(); + let mut values = Vec::with_capacity(input.len()); + let mut lengths = Vec::with_capacity(input.len()); for v in input { values.extend_from_slice(&v); lengths.push((v.len() as u32).to_le()); -- GitLab From f8559f20b2f5ef3c820deefdd78db45770083b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 27 Sep 2019 12:08:11 +0200 Subject: [PATCH 148/275] Support trailing commas in `decl_module` (#3712) --- srml/support/src/dispatch.rs | 24 +++++++++++------------ srml/support/src/storage/storage_items.rs | 1 - 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/srml/support/src/dispatch.rs b/srml/support/src/dispatch.rs index 916cffdc34..b7b142ea19 100644 --- a/srml/support/src/dispatch.rs +++ b/srml/support/src/dispatch.rs @@ -342,7 +342,7 @@ macro_rules! decl_module { { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* - fn on_finalize($($param_name:ident : $param:ty),* ) { $( $impl:tt )* } + fn on_finalize( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* } $($rest:tt)* ) => { $crate::decl_module!(@normalize @@ -373,7 +373,7 @@ macro_rules! decl_module { { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* - fn on_initialize($($param_name:ident : $param:ty),* ) { $( $impl:tt )* } + fn on_initialize( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* } $($rest:tt)* ) => { $crate::decl_module!(@normalize @@ -407,7 +407,7 @@ macro_rules! decl_module { { $( $error_type:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* - fn offchain_worker($($param_name:ident : $param:ty),* ) { $( $impl:tt )* } + fn offchain_worker( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* } $($rest:tt)* ) => { $crate::decl_module!(@normalize @@ -563,7 +563,7 @@ macro_rules! decl_module { $(#[doc = $doc_attr:tt])* #[weight = $weight:expr] $fn_vis:vis fn $fn_name:ident( - $origin:ident $(, $(#[$codec_attr:ident])* $param_name:ident : $param:ty)* + $origin:ident $( , $(#[$codec_attr:ident])* $param_name:ident : $param:ty )* $(,)? ) $( -> $result:ty )* { $( $impl:tt )* } $($rest:tt)* ) => { @@ -610,7 +610,7 @@ macro_rules! decl_module { [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* $fn_vis:vis fn $fn_name:ident( - $from:ident $(, $(#[$codec_attr:ident])* $param_name:ident : $param:ty)* + $from:ident $( , $( #[$codec_attr:ident] )* $param_name:ident : $param:ty )* $(,)? ) $( -> $result:ty )* { $( $impl:tt )* } $($rest:tt)* ) => { @@ -652,7 +652,7 @@ macro_rules! decl_module { $(#[doc = $doc_attr:tt])* $(#[weight = $weight:expr])? $fn_vis:vis fn $fn_name:ident( - $origin:ident : T::Origin $(, $(#[$codec_attr:ident])* $param_name:ident : $param:ty)* + $origin:ident : T::Origin $( , $( #[$codec_attr:ident] )* $param_name:ident : $param:ty )* $(,)? ) $( -> $result:ty )* { $( $impl:tt )* } $($rest:tt)* ) => { @@ -677,7 +677,7 @@ macro_rules! decl_module { $(#[doc = $doc_attr:tt])* $(#[weight = $weight:expr])? $fn_vis:vis fn $fn_name:ident( - origin : $origin:ty $(, $(#[$codec_attr:ident])* $param_name:ident : $param:ty)* + origin : $origin:ty $( , $( #[$codec_attr:ident] )* $param_name:ident : $param:ty )* $(,)? ) $( -> $result:ty )* { $( $impl:tt )* } $($rest:tt)* ) => { @@ -702,7 +702,7 @@ macro_rules! decl_module { $(#[doc = $doc_attr:tt])* $(#[weight = $weight:expr])? $fn_vis:vis fn $fn_name:ident( - $( $(#[$codec_attr:ident])* $param_name:ident : $param:ty),* + $( $(#[$codec_attr:ident])* $param_name:ident : $param:ty ),* $(,)? ) $( -> $result:ty )* { $( $impl:tt )* } $($rest:tt)* ) => { @@ -1730,19 +1730,19 @@ mod tests { pub struct Module for enum Call where origin: T::Origin, T::AccountId: From { /// Hi, this is a comment. fn aux_0(_origin) -> Result { unreachable!() } - fn aux_1(_origin, #[compact] _data: u32) -> Result { unreachable!() } + fn aux_1(_origin, #[compact] _data: u32,) -> Result { unreachable!() } fn aux_2(_origin, _data: i32, _data2: String) -> Result { unreachable!() } #[weight = SimpleDispatchInfo::FixedNormal(3)] fn aux_3(_origin) -> Result { unreachable!() } fn aux_4(_origin, _data: i32) -> Result { unreachable!() } - fn aux_5(_origin, _data: i32, #[compact] _data2: u32) -> Result { unreachable!() } + fn aux_5(_origin, _data: i32, #[compact] _data2: u32,) -> Result { unreachable!() } - fn on_initialize(n: T::BlockNumber) { if n.into() == 42 { panic!("on_initialize") } } + fn on_initialize(n: T::BlockNumber,) { if n.into() == 42 { panic!("on_initialize") } } fn on_finalize(n: T::BlockNumber) { if n.into() == 42 { panic!("on_finalize") } } fn offchain_worker() {} #[weight = SimpleDispatchInfo::FixedOperational(5)] - fn operational(_origin) { unreachable!() } + fn operational(_origin,) { unreachable!() } } } diff --git a/srml/support/src/storage/storage_items.rs b/srml/support/src/storage/storage_items.rs index b00134dbfe..d93152bb9a 100644 --- a/srml/support/src/storage/storage_items.rs +++ b/srml/support/src/storage/storage_items.rs @@ -256,7 +256,6 @@ mod tests { use crate::metadata::*; use crate::metadata::StorageHasher; use crate::rstd::marker::PhantomData; - use crate::storage::{StorageValue, StorageMap}; storage_items! { Value: b"a" => u32; -- GitLab From 35bbdc61a5a8bea545558c9873460e383d2b572e Mon Sep 17 00:00:00 2001 From: thiolliere Date: Fri, 27 Sep 2019 14:39:14 +0200 Subject: [PATCH 149/275] Refactor srml-support/storage (#3702) * refactor * fix * remove unused vec storages * address comment --- srml/support/src/double_map.rs | 140 ------------- srml/support/src/hash.rs | 114 ++++++++++ srml/support/src/hashable.rs | 50 ----- srml/support/src/lib.rs | 11 +- .../src/storage/generator/double_map.rs | 3 +- .../src/storage/generator/linked_map.rs | 2 +- srml/support/src/storage/generator/map.rs | 2 +- srml/support/src/storage/generator/value.rs | 2 +- srml/support/src/storage/hashed.rs | 195 +----------------- srml/support/src/storage/mod.rs | 2 +- srml/support/src/storage/unhashed.rs | 55 +---- srml/support/src/traits.rs | 10 +- 12 files changed, 133 insertions(+), 453 deletions(-) delete mode 100644 srml/support/src/double_map.rs create mode 100644 srml/support/src/hash.rs delete mode 100644 srml/support/src/hashable.rs diff --git a/srml/support/src/double_map.rs b/srml/support/src/double_map.rs deleted file mode 100644 index c3fea95a6c..0000000000 --- a/srml/support/src/double_map.rs +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright 2017-2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! An implementation of double map backed by storage. - -use crate::rstd::prelude::*; -use crate::codec::{Codec, Encode}; -use crate::storage::unhashed; -use rstd::borrow::Borrow; - -/// An implementation of a map with a two keys. -/// -/// It provides an important ability to efficiently remove all entries -/// that have a common first key. -/// -/// # Mapping of keys to a storage path -/// -/// The storage key (i.e. the key under which the `Value` will be stored) is created from two parts. -/// The first part is a hash of a concatenation of the `PREFIX` and `Key1`. And the second part -/// is a hash of a `Key2`. -/// -/// Hasher are implemented in derive_key* methods. -pub trait StorageDoubleMapWithHasher { - type Key1: Encode; - type Key2: Encode; - type Value: Codec + Default; - - const PREFIX: &'static [u8]; - - /// Insert an entry into this map. - fn insert(k1: &Q, k2: &R, val: Self::Value) - where - Self::Key1: Borrow, - Self::Key2: Borrow, - Q: Codec, - R: Codec - { - unhashed::put(&Self::full_key(k1, k2)[..], &val); - } - - /// Remove an entry from this map. - fn remove(k1: &Q, k2: &R) - where - Self::Key1: Borrow, - Self::Key2: Borrow, - Q: Codec, - R: Codec - { - unhashed::kill(&Self::full_key(k1, k2)[..]); - } - - /// Get an entry from this map. - /// - /// If there is no entry stored under the given keys, returns `None`. - fn get(k1: &Q, k2: &R) -> Option - where - Self::Key1: Borrow, - Self::Key2: Borrow, - Q: Codec, - R: Codec - { - unhashed::get(&Self::full_key(k1, k2)[..]) - } - - /// Returns `true` if value under the specified keys exists. - fn exists(k1: &Q, k2: &R) -> bool - where - Self::Key1: Borrow, - Self::Key2: Borrow, - Q: Codec, - R: Codec - { - unhashed::exists(&Self::full_key(k1, k2)[..]) - } - - /// Removes all entries that shares the `k1` as the first key. - fn remove_prefix(k1: &Q) - where - Self::Key1: Borrow, - Q: Codec - { - unhashed::kill_prefix(&Self::derive_key1(Self::encode_key1(k1))) - } - - /// Encode key1 into Vec and prepend a prefix - fn encode_key1(key: &Q) -> Vec - where - Self::Key1: Borrow, - Q: Codec - { - let mut raw_prefix = Vec::new(); - raw_prefix.extend(Self::PREFIX); - key.encode_to(&mut raw_prefix); - raw_prefix - } - - /// Encode key2 into Vec - fn encode_key2(key: &R) -> Vec - where - Self::Key2: Borrow, - R: Codec - { - Encode::encode(&key) - } - - /// Derive the first part of the key - fn derive_key1(key1_data: Vec) -> Vec; - - /// Derive the remaining part of the key - fn derive_key2(key2_data: Vec) -> Vec; - - /// Returns a compound key that consist of the two parts: (prefix, `k1`) and `k2`. - /// The first part is hashed and then concatenated with a hash of `k2`. - fn full_key(k1: &Q, k2: &R) -> Vec - where - Self::Key1: Borrow, - Self::Key2: Borrow, - Q: Codec, - R: Codec - { - let key1_data = Self::encode_key1(k1); - let key2_data = Self::encode_key2(k2); - let mut key = Self::derive_key1(key1_data); - key.extend(Self::derive_key2(key2_data)); - key - } -} diff --git a/srml/support/src/hash.rs b/srml/support/src/hash.rs new file mode 100644 index 0000000000..3775ebc26b --- /dev/null +++ b/srml/support/src/hash.rs @@ -0,0 +1,114 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Hash utilities. + +use codec::Codec; +use rstd::prelude::Vec; +use runtime_io::{blake2_128, blake2_256, twox_64, twox_128, twox_256}; + +// This trait must be kept coherent with srml-support-procedural HasherKind usage +pub trait Hashable: Sized { + fn blake2_128(&self) -> [u8; 16]; + fn blake2_256(&self) -> [u8; 32]; + fn twox_128(&self) -> [u8; 16]; + fn twox_256(&self) -> [u8; 32]; + fn twox_64_concat(&self) -> Vec; +} + +impl Hashable for T { + fn blake2_128(&self) -> [u8; 16] { + self.using_encoded(blake2_128) + } + fn blake2_256(&self) -> [u8; 32] { + self.using_encoded(blake2_256) + } + fn twox_128(&self) -> [u8; 16] { + self.using_encoded(twox_128) + } + fn twox_256(&self) -> [u8; 32] { + self.using_encoded(twox_256) + } + fn twox_64_concat(&self) -> Vec { + self.using_encoded(Twox64Concat::hash) + } +} + +/// Hasher to use to hash keys to insert to storage. +pub trait StorageHasher: 'static { + type Output: AsRef<[u8]>; + fn hash(x: &[u8]) -> Self::Output; +} + +/// Hash storage keys with `concat(twox64(key), key)` +pub struct Twox64Concat; +impl StorageHasher for Twox64Concat { + type Output = Vec; + fn hash(x: &[u8]) -> Vec { + twox_64(x) + .into_iter() + .chain(x.into_iter()) + .cloned() + .collect::>() + } +} + +/// Hash storage keys with blake2 128 +pub struct Blake2_128; +impl StorageHasher for Blake2_128 { + type Output = [u8; 16]; + fn hash(x: &[u8]) -> [u8; 16] { + blake2_128(x) + } +} + +/// Hash storage keys with blake2 256 +pub struct Blake2_256; +impl StorageHasher for Blake2_256 { + type Output = [u8; 32]; + fn hash(x: &[u8]) -> [u8; 32] { + blake2_256(x) + } +} + +/// Hash storage keys with twox 128 +pub struct Twox128; +impl StorageHasher for Twox128 { + type Output = [u8; 16]; + fn hash(x: &[u8]) -> [u8; 16] { + twox_128(x) + } +} + +/// Hash storage keys with twox 256 +pub struct Twox256; +impl StorageHasher for Twox256 { + type Output = [u8; 32]; + fn hash(x: &[u8]) -> [u8; 32] { + twox_256(x) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_twox_64_concat() { + let r = Twox64Concat::hash(b"foo"); + assert_eq!(r.split_at(8), (&twox_128(b"foo")[..8], &b"foo"[..])) + } +} diff --git a/srml/support/src/hashable.rs b/srml/support/src/hashable.rs deleted file mode 100644 index f0918cc358..0000000000 --- a/srml/support/src/hashable.rs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2017-2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Hashable trait. - -use crate::codec::Codec; -use runtime_io::{blake2_128, blake2_256, twox_128, twox_256}; -use crate::storage::hashed::StorageHasher; -use crate::Twox64Concat; -use crate::rstd::prelude::Vec; - -// This trait must be kept coherent with srml-support-procedural HasherKind usage -pub trait Hashable: Sized { - fn blake2_128(&self) -> [u8; 16]; - fn blake2_256(&self) -> [u8; 32]; - fn twox_128(&self) -> [u8; 16]; - fn twox_256(&self) -> [u8; 32]; - fn twox_64_concat(&self) -> Vec; -} - -impl Hashable for T { - fn blake2_128(&self) -> [u8; 16] { - self.using_encoded(blake2_128) - } - fn blake2_256(&self) -> [u8; 32] { - self.using_encoded(blake2_256) - } - fn twox_128(&self) -> [u8; 16] { - self.using_encoded(twox_128) - } - fn twox_256(&self) -> [u8; 32] { - self.using_encoded(twox_256) - } - fn twox_64_concat(&self) -> Vec { - self.using_encoded(Twox64Concat::hash) - } -} diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index 1b8dc11f60..711f4cbcfd 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -38,14 +38,14 @@ pub use paste; #[cfg(feature = "std")] #[doc(hidden)] pub use runtime_io::with_storage; - -pub use self::storage::hashed::{Twox256, Twox128, Blake2_256, Blake2_128, Twox64Concat}; +#[doc(hidden)] +pub use runtime_io::storage_root; #[macro_use] pub mod dispatch; #[macro_use] pub mod storage; -mod hashable; +mod hash; #[macro_use] pub mod event; #[macro_use] @@ -60,14 +60,11 @@ pub mod inherent; pub mod unsigned; #[macro_use] pub mod error; -mod double_map; pub mod traits; +pub use self::hash::{Twox256, Twox128, Blake2_256, Blake2_128, Twox64Concat, Hashable}; pub use self::storage::{StorageValue, StorageMap, StorageLinkedMap, StorageDoubleMap}; -pub use self::hashable::Hashable; pub use self::dispatch::{Parameter, Callable, IsSubType}; -pub use self::double_map::StorageDoubleMapWithHasher; -pub use runtime_io::storage_root; pub use sr_primitives::{self, ConsensusEngineId, print, traits::Printable}; /// Macro for easily creating a new implementation of the `Get` trait. Use similarly to diff --git a/srml/support/src/storage/generator/double_map.rs b/srml/support/src/storage/generator/double_map.rs index b41fe47422..3282c2074f 100644 --- a/srml/support/src/storage/generator/double_map.rs +++ b/srml/support/src/storage/generator/double_map.rs @@ -15,8 +15,9 @@ // along with Substrate. If not, see . use rstd::prelude::*; +use rstd::borrow::Borrow; use codec::{Codec, Encode, EncodeAppend}; -use crate::{storage::{self, unhashed, hashed::StorageHasher}, rstd::borrow::Borrow}; +use crate::{storage::{self, unhashed}, hash::StorageHasher}; /// Generator for `StorageDoubleMap` used by `decl_storage`. /// diff --git a/srml/support/src/storage/generator/linked_map.rs b/srml/support/src/storage/generator/linked_map.rs index d11c025afb..d2476de587 100644 --- a/srml/support/src/storage/generator/linked_map.rs +++ b/srml/support/src/storage/generator/linked_map.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . use codec::{Codec, Encode, Decode}; -use crate::{storage::{self, unhashed, hashed::StorageHasher}, traits::Len}; +use crate::{storage::{self, unhashed}, hash::StorageHasher, traits::Len}; use rstd::{ borrow::Borrow, marker::PhantomData, diff --git a/srml/support/src/storage/generator/map.rs b/srml/support/src/storage/generator/map.rs index f5b22fc19a..cc060cf1ec 100644 --- a/srml/support/src/storage/generator/map.rs +++ b/srml/support/src/storage/generator/map.rs @@ -18,7 +18,7 @@ use rstd::prelude::*; use rstd::borrow::Borrow; use codec::{Codec, Encode}; -use crate::{storage::{self, unhashed, hashed::StorageHasher}, traits::Len}; +use crate::{storage::{self, unhashed}, hash::StorageHasher, traits::Len}; /// Generator for `StorageMap` used by `decl_storage`. /// diff --git a/srml/support/src/storage/generator/value.rs b/srml/support/src/storage/generator/value.rs index 2f632d94d3..c595d85290 100644 --- a/srml/support/src/storage/generator/value.rs +++ b/srml/support/src/storage/generator/value.rs @@ -18,7 +18,7 @@ use rstd::prelude::*; use rstd::{borrow::Borrow, iter::FromIterator}; use codec::{Codec, Encode}; -use crate::{storage::{self, unhashed, hashed::{Twox128, StorageHasher}}, traits::Len}; +use crate::{storage::{self, unhashed}, hash::{Twox128, StorageHasher}, traits::Len}; /// Generator for `StorageValue` used by `decl_storage`. /// diff --git a/srml/support/src/storage/hashed.rs b/srml/support/src/storage/hashed.rs index c125cc3479..2eca8f5bca 100644 --- a/srml/support/src/storage/hashed.rs +++ b/srml/support/src/storage/hashed.rs @@ -17,71 +17,8 @@ //! Operation on runtime storage using hashed keys. use super::unhashed; -use crate::rstd::prelude::*; -use crate::rstd::borrow::Borrow; -use crate::codec::{Codec, Encode, Decode, KeyedVec}; -use runtime_io::{self, twox_64, twox_128, blake2_128, twox_256, blake2_256}; - -/// Hasher to use to hash keys to insert to storage. -pub trait StorageHasher: 'static { - type Output: AsRef<[u8]>; - fn hash(x: &[u8]) -> Self::Output; -} - -/// Hash storage keys with `concat(twox64(key), key)` -pub struct Twox64Concat; -impl StorageHasher for Twox64Concat { - type Output = Vec; - fn hash(x: &[u8]) -> Vec { - twox_64(x) - .into_iter() - .chain(x.into_iter()) - .cloned() - .collect::>() - } -} - -#[test] -fn test_twox_64_concat() { - let r = Twox64Concat::hash(b"foo"); - assert_eq!(r.split_at(8), (&twox_128(b"foo")[..8], &b"foo"[..])) -} - -/// Hash storage keys with blake2 128 -pub struct Blake2_128; -impl StorageHasher for Blake2_128 { - type Output = [u8; 16]; - fn hash(x: &[u8]) -> [u8; 16] { - blake2_128(x) - } -} - -/// Hash storage keys with blake2 256 -pub struct Blake2_256; -impl StorageHasher for Blake2_256 { - type Output = [u8; 32]; - fn hash(x: &[u8]) -> [u8; 32] { - blake2_256(x) - } -} - -/// Hash storage keys with twox 128 -pub struct Twox128; -impl StorageHasher for Twox128 { - type Output = [u8; 16]; - fn hash(x: &[u8]) -> [u8; 16] { - twox_128(x) - } -} - -/// Hash storage keys with twox 256 -pub struct Twox256; -impl StorageHasher for Twox256 { - type Output = [u8; 32]; - fn hash(x: &[u8]) -> [u8; 32] { - twox_256(x) - } -} +use rstd::prelude::*; +use codec::{Encode, Decode}; /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. pub fn get(hash: &HashFn, key: &[u8]) -> Option @@ -216,131 +153,3 @@ where { unhashed::put_raw(&hash(key).as_ref(), value) } - -/// A trait to conveniently store a vector of storable data. -/// -/// It uses twox_128 hasher. Final keys in trie are `twox_128(concatenation(PREFIX,count))` -pub trait StorageVec { - type Item: Default + Sized + Codec; - const PREFIX: &'static [u8]; - - /// Get the current set of items. - fn items() -> Vec { - (0..Self::count()).into_iter().map(Self::item).collect() - } - - /// Set the current set of items. - fn set_items(items: I) - where - I: IntoIterator, - T: Borrow, - { - let mut count: u32 = 0; - - for i in items.into_iter() { - put(&twox_128, &count.to_keyed_vec(Self::PREFIX), i.borrow()); - count = count.checked_add(1).expect("exceeded runtime storage capacity"); - } - - Self::set_count(count); - } - - /// Push an item. - fn push(item: &Self::Item) { - let len = Self::count(); - put(&twox_128, &len.to_keyed_vec(Self::PREFIX), item); - Self::set_count(len + 1); - } - - fn set_item(index: u32, item: &Self::Item) { - if index < Self::count() { - put(&twox_128, &index.to_keyed_vec(Self::PREFIX), item); - } - } - - fn clear_item(index: u32) { - if index < Self::count() { - kill(&twox_128, &index.to_keyed_vec(Self::PREFIX)); - } - } - - fn item(index: u32) -> Self::Item { - get_or_default(&twox_128, &index.to_keyed_vec(Self::PREFIX)) - } - - fn set_count(count: u32) { - (count..Self::count()).for_each(Self::clear_item); - put(&twox_128, &b"len".to_keyed_vec(Self::PREFIX), &count); - } - - fn count() -> u32 { - get_or_default(&twox_128, &b"len".to_keyed_vec(Self::PREFIX)) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use runtime_io::{twox_128, TestExternalities, with_externalities}; - - #[test] - fn integers_can_be_stored() { - let mut t = TestExternalities::default(); - with_externalities(&mut t, || { - let x = 69u32; - put(&twox_128, b":test", &x); - let y: u32 = get(&twox_128, b":test").unwrap(); - assert_eq!(x, y); - }); - with_externalities(&mut t, || { - let x = 69426942i64; - put(&twox_128, b":test", &x); - let y: i64 = get(&twox_128, b":test").unwrap(); - assert_eq!(x, y); - }); - } - - #[test] - fn bools_can_be_stored() { - let mut t = TestExternalities::default(); - with_externalities(&mut t, || { - let x = true; - put(&twox_128, b":test", &x); - let y: bool = get(&twox_128, b":test").unwrap(); - assert_eq!(x, y); - }); - - with_externalities(&mut t, || { - let x = false; - put(&twox_128, b":test", &x); - let y: bool = get(&twox_128, b":test").unwrap(); - assert_eq!(x, y); - }); - } - - #[test] - fn vecs_can_be_retrieved() { - let mut t = TestExternalities::default(); - with_externalities(&mut t, || { - runtime_io::set_storage(&twox_128(b":test"), b"\x2cHello world"); - let x = b"Hello world".to_vec(); - let y = get::, _, _>(&twox_128, b":test").unwrap(); - assert_eq!(x, y); - }); - } - - #[test] - fn vecs_can_be_stored() { - let mut t = TestExternalities::default(); - let x = b"Hello world".to_vec(); - - with_externalities(&mut t, || { - put(&twox_128, b":test", &x); - }); - - with_externalities(&mut t, || { - let y: Vec = get(&twox_128, b":test").unwrap(); - assert_eq!(x, y); - }); - } -} diff --git a/srml/support/src/storage/mod.rs b/srml/support/src/storage/mod.rs index 1524cd234a..3e3c889cde 100644 --- a/srml/support/src/storage/mod.rs +++ b/srml/support/src/storage/mod.rs @@ -18,7 +18,7 @@ use crate::rstd::prelude::*; use crate::rstd::{borrow::Borrow, iter::FromIterator}; -use codec::{Codec, Encode, Decode, KeyedVec, EncodeAppend}; +use codec::{Codec, Encode, Decode, EncodeAppend}; use crate::traits::Len; #[macro_use] diff --git a/srml/support/src/storage/unhashed.rs b/srml/support/src/storage/unhashed.rs index 3c6a5074bd..d3cf346ace 100644 --- a/srml/support/src/storage/unhashed.rs +++ b/srml/support/src/storage/unhashed.rs @@ -16,8 +16,7 @@ //! Operation on unhashed runtime storage. -use crate::rstd::borrow::Borrow; -use super::{Codec, Encode, Decode, KeyedVec, Vec}; +use super::{Encode, Decode, Vec}; /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. pub fn get(key: &[u8]) -> Option { @@ -100,55 +99,3 @@ pub fn get_raw(key: &[u8]) -> Option> { pub fn put_raw(key: &[u8], value: &[u8]) { runtime_io::set_storage(key, value) } - -/// A trait to conveniently store a vector of storable data. -pub trait StorageVec { - type Item: Default + Sized + Codec; - const PREFIX: &'static [u8]; - - /// Get the current set of items. - fn items() -> Vec { - (0..Self::count()).into_iter().map(Self::item).collect() - } - - /// Set the current set of items. - fn set_items(items: I) - where - I: IntoIterator, - T: Borrow, - { - let mut count: u32 = 0; - - for i in items.into_iter() { - put(&count.to_keyed_vec(Self::PREFIX), i.borrow()); - count = count.checked_add(1).expect("exceeded runtime storage capacity"); - } - - Self::set_count(count); - } - - fn set_item(index: u32, item: &Self::Item) { - if index < Self::count() { - put(&index.to_keyed_vec(Self::PREFIX), item); - } - } - - fn clear_item(index: u32) { - if index < Self::count() { - kill(&index.to_keyed_vec(Self::PREFIX)); - } - } - - fn item(index: u32) -> Self::Item { - get_or_default(&index.to_keyed_vec(Self::PREFIX)) - } - - fn set_count(count: u32) { - (count..Self::count()).for_each(Self::clear_item); - put(&b"len".to_keyed_vec(Self::PREFIX), &count); - } - - fn count() -> u32 { - get_or_default(&b"len".to_keyed_vec(Self::PREFIX)) - } -} diff --git a/srml/support/src/traits.rs b/srml/support/src/traits.rs index 905486dddf..655df596d0 100644 --- a/srml/support/src/traits.rs +++ b/srml/support/src/traits.rs @@ -18,11 +18,13 @@ //! //! NOTE: If you're looking for `parameter_types`, it has moved in to the top-level module. -use crate::rstd::{prelude::*, result, marker::PhantomData, ops::Div}; -use crate::codec::{Codec, Encode, Decode}; +use rstd::{prelude::*, result, marker::PhantomData, ops::Div}; +use codec::{Codec, Encode, Decode}; use primitives::u32_trait::Value as U32; -use crate::sr_primitives::traits::{MaybeSerializeDebug, SimpleArithmetic, Saturating}; -use crate::sr_primitives::ConsensusEngineId; +use sr_primitives::{ + ConsensusEngineId, + traits::{MaybeSerializeDebug, SimpleArithmetic, Saturating}, +}; /// Anything that can have a `::len()` method. pub trait Len { -- GitLab From 276838ab6a10627ae346d3ac024021bf225c2392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Sat, 28 Sep 2019 12:14:08 +0100 Subject: [PATCH 150/275] cli: clean up flag descriptions (#3715) --- core/cli/src/params.rs | 98 ++++++++++++++++++++++++++---------------- 1 file changed, 62 insertions(+), 36 deletions(-) diff --git a/core/cli/src/params.rs b/core/cli/src/params.rs index d27976b22e..faa5b5dfa3 100644 --- a/core/cli/src/params.rs +++ b/core/cli/src/params.rs @@ -58,11 +58,11 @@ arg_enum! { /// Shared parameters used by all `CoreParams`. #[derive(Debug, StructOpt, Clone)] pub struct SharedParams { - /// Specify the chain specification (one of dev, local or staging) + /// Specify the chain specification (one of dev, local or staging). #[structopt(long = "chain", value_name = "CHAIN_SPEC")] pub chain: Option, - /// Specify the development chain + /// Specify the development chain. #[structopt(long = "dev")] pub dev: bool, @@ -70,7 +70,7 @@ pub struct SharedParams { #[structopt(long = "base-path", short = "d", value_name = "PATH", parse(from_os_str))] pub base_path: Option, - /// Sets a custom logging filter + /// Sets a custom logging filter. #[structopt(short = "l", long = "log", value_name = "LOG_PATTERN")] pub log: Option, } @@ -84,32 +84,36 @@ impl GetLogFilter for SharedParams { /// Parameters used to create the network configuration. #[derive(Debug, StructOpt, Clone)] pub struct NetworkConfigurationParams { - /// Specify a list of bootnodes + /// Specify a list of bootnodes. #[structopt(long = "bootnodes", value_name = "URL")] pub bootnodes: Vec, - /// Specify a list of reserved node addresses + /// Specify a list of reserved node addresses. #[structopt(long = "reserved-nodes", value_name = "URL")] pub reserved_nodes: Vec, - /// Listen on this multiaddress + /// Listen on this multiaddress. #[structopt(long = "listen-addr", value_name = "LISTEN_ADDR")] pub listen_addr: Vec, - /// Specify p2p protocol TCP port. Only used if --listen-addr is not specified. + /// Specify p2p protocol TCP port. + /// + /// Only used if --listen-addr is not specified. #[structopt(long = "port", value_name = "PORT")] pub port: Option, - /// Specify the number of outgoing connections we're trying to maintain + /// Specify the number of outgoing connections we're trying to maintain. #[structopt(long = "out-peers", value_name = "OUT_PEERS", default_value = "25")] pub out_peers: u32, - /// Specify the maximum number of incoming connections we're accepting + /// Specify the maximum number of incoming connections we're accepting. #[structopt(long = "in-peers", value_name = "IN_PEERS", default_value = "25")] pub in_peers: u32, - /// By default, the network will use mDNS to discover other nodes on the local network. This - /// disables it. Automatically implied when using --dev. + /// Disable mDNS discovery. + /// + /// By default, the network will use mDNS to discover other nodes on the + /// local network. This disables it. Automatically implied when using --dev. #[structopt(long = "no-mdns")] pub no_mdns: bool, @@ -209,7 +213,7 @@ pub struct TransactionPoolParams { #[structopt(long = "pool-limit", value_name = "COUNT", default_value = "512")] pub pool_limit: usize, /// Maximum number of kilobytes of all transactions stored in the pool. - #[structopt(long = "pool-kbytes", value_name = "COUNT", default_value="10240")] + #[structopt(long = "pool-kbytes", value_name = "COUNT", default_value = "10240")] pub pool_kbytes: usize, } @@ -298,39 +302,43 @@ pub struct ExecutionStrategies { /// The `run` command used to run a node. #[derive(Debug, StructOpt, Clone)] pub struct RunCmd { - /// Enable validator mode + /// Enable validator mode. #[structopt(long = "validator")] pub validator: bool, - /// Disable GRANDPA voter when running in validator mode, otherwise disables the GRANDPA observer + /// Disable GRANDPA voter when running in validator mode, otherwise disables the GRANDPA observer. #[structopt(long = "no-grandpa")] pub no_grandpa: bool, - /// Experimental: Run in light client mode + /// Experimental: Run in light client mode. #[structopt(long = "light")] pub light: bool, - /// Limit the memory the database cache can use + /// Limit the memory the database cache can use. #[structopt(long = "db-cache", value_name = "MiB")] pub database_cache_size: Option, - /// Specify the state cache size + /// Specify the state cache size. #[structopt(long = "state-cache-size", value_name = "Bytes", default_value = "67108864")] pub state_cache_size: usize, - /// Listen to all RPC interfaces (default is local) + /// Listen to all RPC interfaces. + /// + /// Default is local. #[structopt(long = "rpc-external")] pub rpc_external: bool, - /// Listen to all Websocket interfaces (default is local) + /// Listen to all Websocket interfaces. + /// + /// Default is local. #[structopt(long = "ws-external")] pub ws_external: bool, - /// Specify HTTP RPC server TCP port + /// Specify HTTP RPC server TCP port. #[structopt(long = "rpc-port", value_name = "PORT")] pub rpc_port: Option, - /// Specify WebSockets RPC server TCP port + /// Specify WebSockets RPC server TCP port. #[structopt(long = "ws-port", value_name = "PORT")] pub ws_port: Option, @@ -339,33 +347,45 @@ pub struct RunCmd { pub ws_max_connections: Option, /// Specify browser Origins allowed to access the HTTP & WS RPC servers. - /// It's a comma-separated list of origins (protocol://domain or special `null` value). - /// Value of `all` will disable origin validation. - /// Default is to allow localhost, https://polkadot.js.org and https://substrate-ui.parity.io origins. - /// When running in --dev mode the default is to allow all origins. + /// + /// A comma-separated list of origins (protocol://domain or special `null` + /// value). Value of `all` will disable origin validation. Default is to + /// allow localhost, https://polkadot.js.org and + /// https://substrate-ui.parity.io origins. When running in --dev mode the + /// default is to allow all origins. #[structopt(long = "rpc-cors", value_name = "ORIGINS", parse(try_from_str = "parse_cors"))] pub rpc_cors: Option, - /// Specify the pruning mode, a number of blocks to keep or 'archive'. Default is 256. + /// Specify the pruning mode, a number of blocks to keep or 'archive'. + /// + /// Default is 256. #[structopt(long = "pruning", value_name = "PRUNING_MODE")] pub pruning: Option, - /// The human-readable name for this node, as reported to the telemetry server, if enabled + /// The human-readable name for this node. + /// + /// The node name will be reported to the telemetry server, if enabled. #[structopt(long = "name", value_name = "NAME")] pub name: Option, - /// Disable connecting to the Substrate telemetry server (telemetry is on by default on global chains). + /// Disable connecting to the Substrate telemetry server. + /// + /// Telemetry is on by default on global chains. #[structopt(long = "no-telemetry")] pub no_telemetry: bool, - /// The URL of the telemetry server to connect to. This flag can be passed multiple times - /// as a mean to specify multiple telemetry endpoints. Verbosity levels range from 0-9, with - /// 0 denoting the least verbosity. If no verbosity level is specified the default is 0. + /// The URL of the telemetry server to connect to. + /// + /// This flag can be passed multiple times as a mean to specify multiple + /// telemetry endpoints. Verbosity levels range from 0-9, with 0 denoting + /// the least verbosity. If no verbosity level is specified the default is + /// 0. #[structopt(long = "telemetry-url", value_name = "URL VERBOSITY", parse(try_from_str = "parse_telemetry_endpoints"))] pub telemetry_endpoints: Vec<(String, u8)>, - /// Should execute offchain workers on every block. By default it's only enabled for nodes that are authoring new - /// blocks. + /// Should execute offchain workers on every block. + /// + /// By default it's only enabled for nodes that are authoring new blocks. #[structopt( long = "offchain-worker", value_name = "ENABLED", @@ -584,11 +604,15 @@ pub struct ExportBlocksCmd { #[structopt(parse(from_os_str))] pub output: Option, - /// Specify starting block number. 1 by default. + /// Specify starting block number. + /// + /// Default is 1. #[structopt(long = "from", value_name = "BLOCK")] pub from: Option, - /// Specify last block number. Best block by default. + /// Specify last block number. + /// + /// Default is best block. #[structopt(long = "to", value_name = "BLOCK")] pub to: Option, @@ -610,7 +634,9 @@ pub struct ImportBlocksCmd { #[structopt(parse(from_os_str))] pub input: Option, - /// The default number of 64KB pages to ever allocate for Wasm execution. Don't alter this unless you know what you're doing. + /// The default number of 64KB pages to ever allocate for Wasm execution. + /// + /// Don't alter this unless you know what you're doing. #[structopt(long = "default-heap-pages", value_name = "COUNT")] pub default_heap_pages: Option, -- GitLab From 5f4dfed02961862233a547d13610f6238042861a Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Sat, 28 Sep 2019 13:14:28 +0200 Subject: [PATCH 151/275] Add a comment on the features. (#3714) --- core/sr-io/Cargo.toml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/sr-io/Cargo.toml b/core/sr-io/Cargo.toml index a529c1e757..08a526f4e6 100644 --- a/core/sr-io/Cargo.toml +++ b/core/sr-io/Cargo.toml @@ -37,5 +37,10 @@ std = [ ] nightly = [] strict = [] + +# These two features are used for `no_std` builds for the environments which already provides +# `#[panic_handler]` and `#[alloc_error_handler]`. +# +# For the regular wasm runtime builds those are not used. no_panic_handler = [] no_oom = [] -- GitLab From da044c562c921ec483199f5b3126071b6dd0d2f4 Mon Sep 17 00:00:00 2001 From: Talha Cross <47772477+soc1c@users.noreply.github.com> Date: Sat, 28 Sep 2019 13:14:49 +0200 Subject: [PATCH 152/275] docs: add security policy (#3713) --- SECURITY.md | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..c5a3f35fdd --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,101 @@ +# Security Policy + +Parity Technologies is committed to resolving security vulnerabilities in our software quickly and carefully. We take the necessary steps to minimize risk, provide timely information, and deliver vulnerability fixes and mitigations required to address security issues. + +## Reporting a Vulnerability + +Security vulnerabilities in Parity software should be reported by email to security@parity.io. If you think your report might be eligible for the Parity Bug Bounty Program, your email should be send to bugbounty@parity.io. + +Your report should include the following: + +- your name +- description of the vulnerability +- attack scenario (if any) +- components +- reproduction +- other details + +Try to include as much information in your report as you can, including a description of the vulnerability, its potential impact, and steps for reproducing it. Be sure to use a descriptive subject line. + +You'll receive a response to your email within two business days indicating the next steps in handling your report. We encourage finders to use encrypted communication channels to protect the confidentiality of vulnerability reports. You can encrypt your report using our public key. This key is [on MIT's key server](https://pgp.mit.edu/pks/lookup?op=get&search=0x5D0F03018D07DE73) server and reproduced below. + +After the initial reply to your report, our team will endeavor to keep you informed of the progress being made towards a fix. These updates will be sent at least every five business days. + +Thank you for taking the time to responsibly disclose any vulnerabilities you find. + +## Responsible Investigation and Reporting + +Responsible investigation and reporting includes, but isn't limited to, the following: + +- Don't violate the privacy of other users, destroy data, etc. +- Don’t defraud or harm Parity Technologies Ltd or its users during your research; you should make a good faith effort to not interrupt or degrade our services. +- Don't target our physical security measures, or attempt to use social engineering, spam, distributed denial of service (DDOS) attacks, etc. +- Initially report the bug only to us and not to anyone else. +- Give us a reasonable amount of time to fix the bug before disclosing it to anyone else, and give us adequate written warning before disclosing it to anyone else. +- In general, please investigate and report bugs in a way that makes a reasonable, good faith effort not to be disruptive or harmful to us or our users. Otherwise your actions might be interpreted as an attack rather than an effort to be helpful. + +## Bug Bounty Program + +Our Bug Bounty Program allows us to recognise and reward members of the Parity community for helping us find and address significant bugs, in accordance with the terms of the Parity Bug Bounty Program. A detailed description on eligibility, rewards, legal information and terms & conditions for contributors can be found on [our website](https://paritytech.io/bug-bounty.html). + + + + + + +## Plaintext PGP Key + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBF0vHwQBEADKui4qAo4bzdzRhMm+uhUpYGf8jjjmET3zJ8kKQIpp6JTsV+HJ +6m1We0QYeMRXoOYH1xVHBf2zNCuHS0nSQdUCQA7SHWsPB05STa2hvlR7fSdQnCCp +gnLOJWXvvedlRDIAhvqI6cwLdUlXgVSKEwrwmrpiBhh4NxI3qX+LyIa+Ovkchu2S +d/YCnE4GqojSGRfJYiGwe2N+sF7OfaoKhQuTrtdDExHrMU4cWnTXW2wyxTr4xkj9 +jS2WeLVZWflvkDHT8JD9N6jNxBVEF/Qvjk83zI0kCOzkhek8x+YUgfLq3/rHOYbX +3pW21ccHYPacHjHWvKE+xRebjeEhJ4KxKHfCVjQcxybwDBqDka1AniZt4CQ7UORf +MU/ue2oSZ9nNg0uMdb/0AbQPZ04OlMcYPAPWzFL08nVPox9wT9uqlL6JtcOeC90h +oOeDmfgwmjMmdwWTRgt9qQjcbgXzVvuAzIGbzj1X3MdLspWdHs/d2+US4nji1TkN +oYIW7vE+xkd3aB+NZunIlm9Rwd/0mSgDg+DaNa5KceOLhq0/qKgcXC/RRU29I8II +tusRoR/oesGJGYTjh4k6PJkG+nvDPsoQrwYT44bhnniS1xYkxWYXF99JFI7LgMdD +e1SgKeIDVpvm873k82E6arp5655Wod1XOjaXBggCwFp84eKcEZEN+1qEWwARAQAB +tClQYXJpdHkgU2VjdXJpdHkgVGVhbSA8c2VjdXJpdHlAcGFyaXR5LmlvPokCVAQT +AQoAPhYhBJ1LK264+XFW0ZZpqf8IEtSRuWeYBQJdLx8EAhsDBQkDwmcABQsJCAcC +BhUKCQgLAgQWAgMBAh4BAheAAAoJEP8IEtSRuWeYL84QAI6NwnwS561DWYYRAd4y +ocGPr3CnwFSt1GjkSkRy3B+tMhzexBg1y7EbLRUefIrO4LwOlywtRk8tTRGgEI4i +5xRLHbOkeolfgCFSpOj5d8cMKCt5HEIv18hsv6dkrzlSYA5NLX/GRBEh3F/0sGny +vCXapfxa1cx72sU7631JBK7t2Tf+MfwxdfyFZ9TI9WdtP5AfVjgTkIVkEDFcZPTc +n3CYXqTYFIBCNUD8LP4iTi3xUt7pTGJQQoFT8l15nJCgzRYQ+tXpoTRlf+/LtXmw +6iidPV87E06jHdK9666rBouIabAtx7i0/4kwo+bSZ8DiSKRUaehiHGd212HSEmdF +jxquWE4pEzoUowYznhSIfR+WWIqRBHxEYarP4m98Hi+VXZ7Fw1ytzO8+BAKnLXnj +2W2+T9qJks5gqVEoaWNnqpvya6JA11QZvZ0w7Om2carDc2ILNm2Xx9J0mRUye8P0 +KxcgqJuKNGFtugebQAsXagkxOKsdKna1PlDlxEfTf6AgI3ST8qSiMAwaaIMB/REF +VKUapGoslQX4tOCjibI2pzEgE//D8NAaSVu2A9+BUcFERdZRxsI7fydIXNeZ2R46 +N2qfW+DP3YR/14QgdRxDItEavUoE1vByRXwIufKAkVemOZzIoFXKFsDeXwqTVW5i +6CXu6OddZ3QHDiT9TEbRny4QuQINBF0vKCwBEACnP5J7LEGbpxNBrPvGdxZUo0YA +U8RgeKDRPxJTvMo27V1IPZGaKRCRq8LBfg/eHhqZhQ7SLJBjBljd8kuT5dHDBTRe +jE1UIOhmnlSlrEJjAmpVO08irlGpq1o+8mGcvkBsR0poCVjeNeSnwYfRnR+c3GK5 +Er6/JRqfN4mJvnEC9/Pbm6C7ql6YLKxC3yqzF97JL5brbbuozrW7nixY/yAI8619 +VlBIMP7PAUbGcnSQyuV5b/Wr2Sgr6NJclnNSLjh2U9/Du6w/0tDGlMBts8HjRnWJ +BXbkTdQKCTaqgK68kTKSiN1/x+lynxHC2AavMpH/08Kopg2ZCzJowMKIgcB+4Z/I +DJKZWHWKumhaZMGXcWgzgcByog9IpamuROEZFJNEUAFf7YIncEckPSif4looiOdS +VurKZGvYXXaGSsZbGgHxI5CWu7ZxMdLBLvtOcCYmRQrG+g/h+PGU5BT0bNAfNTkm +V3/n1B/TWbpWRmB3AwT2emQivXHkaubGI0VivhaO43AuI9JWoqiMqFtxbuTeoxwD +xlu2Dzcp0v+AR4T5cIG9D5/+yiPc25aIY7cIKxuNFHIDL4td5fwSGC7vU6998PIG +2Y48TGBnw7zpEfDfMayqAeBjX0YU6PTNsvS5O6bP3j4ojTOUYD7Z8QdCvgISDID3 +WMGAdmSwmCRvsQ/OJwARAQABiQI8BBgBCgAmFiEEnUsrbrj5cVbRlmmp/wgS1JG5 +Z5gFAl0vKCwCGwwFCQB2pwAACgkQ/wgS1JG5Z5hdbw//ZqR+JcWm59NUIHjauETJ +sYDYhcAfa3txTacRn5uPz/TQiTd7wZ82+G8Et0ZnpEHy6eWyBqHpG0hiPhFBzxjY +nhjHl8jJeyo2mQIVJhzkL58BHBZk8WM2TlaU7VxZ6TYOmP2y3qf6FD6mCcrQ4Fml +E9f0lyVUoI/5Zs9oF0izRk8vkwaY3UvLM7XEY6nM8GnFG8kaiZMYmx26Zo7Uz31G +7EGGZFsrVDXfNhSJyz79Gyn+Lx9jOTdoR0sH/THYIIosE83awMGE6jKeuDYTbVWu ++ZtHQef+pRteki3wvNLJK+kC1y3BtHqDJS9Lqx0s8SCiVozlC+fZfC9hCtU7bXJK +0UJZ4qjSvj6whzfaNgOZAqJpmwgOnd8W/3YJk1DwUeX98FcU38MR23SOkx2EDdDE +77Kdu62vTs/tLmOTuyKBvYPaHaYulYjQTxurG+o8vhHtaL87ARvuq+83dj+nO5z3 +5O9vkcVJYWjOEnJe7ZvCTxeLJehpCmHIbyUuDx5P24MWVbyXOxIlxNxTqlub5GlW +rQF6Qsa/0k9TRk7Htbct6fAA0/VahJS0g096MrTH8AxBXDNE8lIoNeGikVlaxK9Z +S+aannlWYIJymZ4FygIPPaRlzhAoXBuJd8OaR5giC7dS1xquxKOiQEXTGsLeGFaI +BZYiIhW7GG4ozvKDqyNm4eg= +=yKcB +-----END PGP PUBLIC KEY BLOCK----- +``` -- GitLab From 4f850d35bcf70577b2fb895a5c81dc02e8faa848 Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Sat, 28 Sep 2019 14:02:36 +0200 Subject: [PATCH 153/275] Explicit sync API for downloading important, possibly orphaned, forks (#3633) * Explicit sync API * Keep sync requests * Don't request the finalized block we already have * Dropping requests & docs * Renamed a function --- core/network/src/protocol.rs | 7 +++ core/network/src/protocol/sync.rs | 96 ++++++++++++++++++++++++++++++- core/network/src/service.rs | 15 +++++ core/network/src/test/mod.rs | 10 ++++ core/network/src/test/sync.rs | 56 ++++++++++++++++++ 5 files changed, 183 insertions(+), 1 deletion(-) diff --git a/core/network/src/protocol.rs b/core/network/src/protocol.rs index b2cea2cd5c..ef581a6e43 100644 --- a/core/network/src/protocol.rs +++ b/core/network/src/protocol.rs @@ -1236,6 +1236,13 @@ impl, H: ExHashT> Protocol { self.sync.request_justification(&hash, number) } + /// Request syncing for the given block from given set of peers. + /// Uses `protocol` to queue a new block download request and tries to dispatch all pending + /// requests. + pub fn set_sync_fork_request(&mut self, peers: Vec, hash: &B::Hash, number: NumberFor) { + self.sync.set_sync_fork_request(peers, hash, number) + } + /// A batch of blocks have been processed, with or without errors. /// Call this when a batch of blocks have been processed by the importqueue, with or without /// errors. diff --git a/core/network/src/protocol/sync.rs b/core/network/src/protocol/sync.rs index 6a2a207abc..39927792be 100644 --- a/core/network/src/protocol/sync.rs +++ b/core/network/src/protocol/sync.rs @@ -123,7 +123,10 @@ pub struct ChainSync { queue_blocks: HashSet, /// The best block number that we are currently importing. best_importing_number: NumberFor, + /// Finality proof handler. request_builder: Option>, + /// Explicit sync requests. + sync_requests: HashMap>, /// A flag that caches idle state with no pending requests. is_idle: bool, /// A type to check incoming block announcements. @@ -157,6 +160,11 @@ pub struct PeerInfo { pub best_number: NumberFor } +struct SyncRequest { + number: NumberFor, + peers: HashSet, +} + /// The state of syncing between a Peer and ourselves. /// /// Generally two categories, "busy" or `Available`. If busy, the enum @@ -299,6 +307,7 @@ impl ChainSync { queue_blocks: Default::default(), best_importing_number: Zero::zero(), request_builder, + sync_requests: Default::default(), is_idle: false, block_announce_validator, } @@ -449,6 +458,51 @@ impl ChainSync { }) } + /// Request syncing for the given block from given set of peers. + // The implementation is similar to on_block_announce with unknown parent hash. + pub fn set_sync_fork_request(&mut self, peers: Vec, hash: &B::Hash, number: NumberFor) { + if peers.is_empty() { + if let Some(_) = self.sync_requests.remove(hash) { + debug!(target: "sync", "Cleared sync request for block {:?} with {:?}", hash, peers); + } + return; + } + debug!(target: "sync", "Explicit sync request for block {:?} with {:?}", hash, peers); + if self.is_known(&hash) { + debug!(target: "sync", "Refusing to sync known hash {:?}", hash); + return; + } + + let block_status = self.client.block_status(&BlockId::Number(number - One::one())) + .unwrap_or(BlockStatus::Unknown); + if block_status == BlockStatus::InChainPruned { + trace!(target: "sync", "Refusing to sync ancient block {:?}", hash); + return; + } + + self.is_idle = false; + for peer_id in &peers { + if let Some(peer) = self.peers.get_mut(peer_id) { + if let PeerSyncState::AncestorSearch(_, _) = peer.state { + continue; + } + + if number > peer.best_number { + peer.best_number = number; + peer.best_hash = hash.clone(); + } + } + } + + self.sync_requests + .entry(hash.clone()) + .or_insert_with(|| SyncRequest { + number, + peers: Default::default(), + }) + .peers.extend(peers); + } + /// Get an iterator over all scheduled justification requests. pub fn justification_requests(&mut self) -> impl Iterator)> + '_ { let peers = &mut self.peers; @@ -508,13 +562,21 @@ impl ChainSync { } let blocks = &mut self.blocks; let attrs = &self.required_block_attributes; + let sync_requests = &self.sync_requests; let mut have_requests = false; + let last_finalized = self.client.info().chain.finalized_number; + let best_queued = self.best_queued_number; let iter = self.peers.iter_mut().filter_map(move |(id, peer)| { if !peer.state.is_available() { trace!(target: "sync", "Peer {} is busy", id); return None } - if let Some((range, req)) = peer_block_request(id, peer, blocks, attrs) { + if let Some((hash, req)) = explicit_sync_request(id, sync_requests, best_queued, last_finalized, attrs) { + trace!(target: "sync", "Downloading explicitly requested block {:?} from {}", hash, id); + peer.state = PeerSyncState::DownloadingStale(hash); + have_requests = true; + Some((id.clone(), req)) + } else if let Some((range, req)) = peer_block_request(id, peer, blocks, attrs) { peer.state = PeerSyncState::DownloadingNew(range.start); trace!(target: "sync", "New block request for {}", id); have_requests = true; @@ -860,6 +922,9 @@ impl ChainSync { self.best_queued_number = number; self.best_queued_hash = *hash; } + if let Some(_) = self.sync_requests.remove(&hash) { + trace!(target: "sync", "Completed explicit sync request {:?}", hash); + } // Update common blocks for (n, peer) in self.peers.iter_mut() { if let PeerSyncState::AncestorSearch(_, _) = peer.state { @@ -1232,3 +1297,32 @@ fn peer_block_request( None } } + +/// Get pending explicit sync request for a peer. +fn explicit_sync_request( + id: &PeerId, + requests: &HashMap>, + best_num: NumberFor, + finalized: NumberFor, + attributes: &message::BlockAttributes, +) -> Option<(B::Hash, BlockRequest)> +{ + for (hash, r) in requests { + if !r.peers.contains(id) { + continue + } + if r.number <= best_num { + trace!(target: "sync", "Downloading requested fork {:?} from {}", hash, id); + return Some((hash.clone(), message::generic::BlockRequest { + id: 0, + fields: attributes.clone(), + from: message::FromBlock::Hash(hash.clone()), + to: None, + direction: message::Direction::Descending, + max: Some((r.number - finalized).saturated_into::()), // up to the last finalized block + })) + } + } + None +} + diff --git a/core/network/src/service.rs b/core/network/src/service.rs index 3ca7bffdb4..2cf949116f 100644 --- a/core/network/src/service.rs +++ b/core/network/src/service.rs @@ -496,6 +496,18 @@ impl, H: ExHashT> NetworkServic Ok(()) } + /// Configure an explicit fork sync request. + /// Note that this function should not be used for recent blocks. + /// Sync should be able to download all the recent forks normally. + /// `set_sync_fork_request` should only be used if external code detects that there's + /// a stale fork missing. + /// Passing empty `peers` set effectively removes the sync request. + pub fn set_sync_fork_request(&self, peers: Vec, hash: B::Hash, number: NumberFor) { + let _ = self + .to_worker + .unbounded_send(ServerToWorkerMsg::SyncFork(peers, hash, number)); + } + /// Modify a peerset priority group. pub fn set_priority_group(&self, group_id: String, peers: HashSet) -> Result<(), String> { let peers = peers.into_iter().map(|p| { @@ -586,6 +598,7 @@ enum ServerToWorkerMsg> { GetValue(record::Key), PutValue(record::Key, Vec), AddKnownAddress(PeerId, Multiaddr), + SyncFork(Vec, B::Hash, NumberFor), } /// Main network worker. Must be polled in order for the network to advance. @@ -664,6 +677,8 @@ impl, H: ExHashT> Stream for Ne self.network_service.put_value(key, value), ServerToWorkerMsg::AddKnownAddress(peer_id, addr) => self.network_service.add_known_address(peer_id, addr), + ServerToWorkerMsg::SyncFork(peer_ids, hash, number) => + self.network_service.user_protocol_mut().set_sync_fork_request(peer_ids, &hash, number), } } diff --git a/core/network/src/test/mod.rs b/core/network/src/test/mod.rs index ddc86b6e95..302ef78d7d 100644 --- a/core/network/src/test/mod.rs +++ b/core/network/src/test/mod.rs @@ -229,6 +229,11 @@ pub struct Peer> { } impl> Peer { + /// Get this peer ID. + pub fn id(&self) -> PeerId { + self.network.service().local_peer_id() + } + /// Returns true if we're major syncing. pub fn is_major_syncing(&self) -> bool { self.network.service().is_major_syncing() @@ -259,6 +264,11 @@ impl> Peer { self.network.service().announce_block(hash, data); } + /// Request explicit fork sync. + pub fn set_sync_fork_request(&self, peers: Vec, hash: ::Hash, number: NumberFor) { + self.network.service().set_sync_fork_request(peers, hash, number); + } + /// Add blocks to the peer -- edit the block before adding pub fn generate_blocks(&mut self, count: usize, origin: BlockOrigin, edit_block: F) -> H256 where F: FnMut(BlockBuilder) -> Block diff --git a/core/network/src/test/sync.rs b/core/network/src/test/sync.rs index d50190f657..3d8e57cad0 100644 --- a/core/network/src/test/sync.rs +++ b/core/network/src/test/sync.rs @@ -526,3 +526,59 @@ fn light_peer_imports_header_from_announce() { let known_stale_hash = net.peer(0).push_blocks_at(BlockId::Number(0), 1, true); import_with_announce(&mut net, &mut runtime, known_stale_hash); } + +#[test] +fn can_sync_explicit_forks() { + let _ = ::env_logger::try_init(); + let mut runtime = current_thread::Runtime::new().unwrap(); + let mut net = TestNet::new(2); + net.peer(0).push_blocks(30, false); + net.peer(1).push_blocks(30, false); + + // small fork + reorg on peer 1. + net.peer(0).push_blocks_at(BlockId::Number(30), 2, true); + let small_hash = net.peer(0).client().info().chain.best_hash; + let small_number = net.peer(0).client().info().chain.best_number; + net.peer(0).push_blocks_at(BlockId::Number(30), 10, false); + assert_eq!(net.peer(0).client().info().chain.best_number, 40); + + // peer 1 only ever had the long fork. + net.peer(1).push_blocks(10, false); + assert_eq!(net.peer(1).client().info().chain.best_number, 40); + + assert!(net.peer(0).client().header(&BlockId::Hash(small_hash)).unwrap().is_some()); + assert!(net.peer(1).client().header(&BlockId::Hash(small_hash)).unwrap().is_none()); + + // poll until the two nodes connect, otherwise announcing the block will not work + runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> { + net.poll(); + if net.peer(0).num_peers() == 0 || net.peer(1).num_peers() == 0 { + Ok(Async::NotReady) + } else { + Ok(Async::Ready(())) + } + })).unwrap(); + + // synchronization: 0 synced to longer chain and 1 didn't sync to small chain. + + assert_eq!(net.peer(0).client().info().chain.best_number, 40); + + assert!(net.peer(0).client().header(&BlockId::Hash(small_hash)).unwrap().is_some()); + assert!(!net.peer(1).client().header(&BlockId::Hash(small_hash)).unwrap().is_some()); + + // request explicit sync + let first_peer_id = net.peer(0).id(); + net.peer(1).set_sync_fork_request(vec![first_peer_id], small_hash, small_number); + + // peer 1 downloads the block. + runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> { + net.poll(); + + assert!(net.peer(0).client().header(&BlockId::Hash(small_hash)).unwrap().is_some()); + if net.peer(1).client().header(&BlockId::Hash(small_hash)).unwrap().is_none() { + return Ok(Async::NotReady) + } + Ok(Async::Ready(())) + })).unwrap(); +} + -- GitLab From a1836be4934cb333522f55944431096431515474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Sat, 28 Sep 2019 18:04:46 +0100 Subject: [PATCH 154/275] peerset: fix reserved nodes (#3706) * peerset: fix handling of reserved only peering mode * core: add cli parameter to enable reserved nodes only * peerset: fix tests * peerset: add test for priority only mode * core: fix reserved only cli flag description * peerset: extend docs on set_priority_only --- core/cli/src/lib.rs | 3 +- core/cli/src/params.rs | 7 +++ core/peerset/src/lib.rs | 6 ++- core/peerset/src/peersstate.rs | 99 ++++++++++++++++++++++++++++++---- 4 files changed, 103 insertions(+), 12 deletions(-) diff --git a/core/cli/src/lib.rs b/core/cli/src/lib.rs index 1fa4cabd63..9aa5373f09 100644 --- a/core/cli/src/lib.rs +++ b/core/cli/src/lib.rs @@ -550,7 +550,8 @@ fn fill_network_configuration( ); config.net_config_path = config.config_path.clone(); config.reserved_nodes.extend(cli.reserved_nodes.into_iter()); - if !config.reserved_nodes.is_empty() { + + if cli.reserved_only { config.non_reserved_mode = NonReservedPeerMode::Deny; } diff --git a/core/cli/src/params.rs b/core/cli/src/params.rs index faa5b5dfa3..f95ff40eea 100644 --- a/core/cli/src/params.rs +++ b/core/cli/src/params.rs @@ -92,6 +92,13 @@ pub struct NetworkConfigurationParams { #[structopt(long = "reserved-nodes", value_name = "URL")] pub reserved_nodes: Vec, + /// Whether to only allow connections to/from reserved nodes. + /// + /// If you are a validator your node might still connect to other validator + /// nodes regardless of whether they are defined as reserved nodes. + #[structopt(long = "reserved-only")] + pub reserved_only: bool, + /// Listen on this multiaddress. #[structopt(long = "listen-addr", value_name = "LISTEN_ADDR")] pub listen_addr: Vec, diff --git a/core/peerset/src/lib.rs b/core/peerset/src/lib.rs index c7c7850f16..a243fd00bd 100644 --- a/core/peerset/src/lib.rs +++ b/core/peerset/src/lib.rs @@ -178,7 +178,7 @@ impl Peerset { }; let mut peerset = Peerset { - data: peersstate::PeersState::new(config.in_peers, config.out_peers), + data: peersstate::PeersState::new(config.in_peers, config.out_peers, config.reserved_only), tx, rx, reserved_only: config.reserved_only, @@ -224,9 +224,11 @@ impl Peerset { } fn on_set_reserved_only(&mut self, reserved_only: bool) { - // Disconnect non-reserved nodes. self.reserved_only = reserved_only; + self.data.set_priority_only(reserved_only); + if self.reserved_only { + // Disconnect non-reserved nodes. let reserved = self.data.get_priority_group(RESERVED_NODES).unwrap_or_default(); for peer_id in self.data.connected_peers().cloned().collect::>().into_iter() { let peer = self.data.peer(&peer_id).into_connected() diff --git a/core/peerset/src/peersstate.rs b/core/peerset/src/peersstate.rs index e02d630404..57dfc50d34 100644 --- a/core/peerset/src/peersstate.rs +++ b/core/peerset/src/peersstate.rs @@ -50,6 +50,9 @@ pub struct PeersState { /// Priority groups. Each group is identified by a string ID and contains a set of peer IDs. priority_nodes: HashMap>, + + /// Only allow connections to/from peers in a priority group. + priority_only: bool, } /// State of a single node that we know about. @@ -96,7 +99,7 @@ impl ConnectionState { impl PeersState { /// Builds a new empty `PeersState`. - pub fn new(in_peers: u32, out_peers: u32) -> Self { + pub fn new(in_peers: u32, out_peers: u32, priority_only: bool) -> Self { PeersState { nodes: HashMap::new(), num_in: 0, @@ -104,6 +107,7 @@ impl PeersState { max_in: in_peers, max_out: out_peers, priority_nodes: HashMap::new(), + priority_only, } } @@ -220,9 +224,15 @@ impl PeersState { /// Sets the peer as connected with an outgoing connection. fn try_outgoing(&mut self, peer_id: &PeerId) -> bool { + let is_priority = self.is_priority(peer_id); + + // We are only accepting connections from priority nodes. + if !is_priority && self.priority_only { + return false; + } + // Note that it is possible for num_out to be strictly superior to the max, in case we were // connected to reserved node then marked them as not reserved. - let is_priority = self.is_priority(peer_id); if self.num_out >= self.max_out && !is_priority { return false; } @@ -245,6 +255,12 @@ impl PeersState { /// Note that reserved nodes don't count towards the number of slots. fn try_accept_incoming(&mut self, peer_id: &PeerId) -> bool { let is_priority = self.is_priority(peer_id); + + // We are only accepting connections from priority nodes. + if !is_priority && self.priority_only { + return false; + } + // Note that it is possible for num_in to be strictly superior to the max, in case we were // connected to reserved node then marked them as not reserved. if self.num_in >= self.max_in && !is_priority { @@ -315,6 +331,15 @@ impl PeersState { self.priority_nodes.get(group_id).cloned() } + /// Set whether to only allow connections to/from peers in a priority group. + /// Calling this method does not affect any existing connection, e.g. + /// enabling priority only will not disconnect from any non-priority peers + /// we are already connected to, only future incoming/outgoing connection + /// attempts will be affected. + pub fn set_priority_only(&mut self, priority: bool) { + self.priority_only = priority; + } + /// Check that node is any priority group. fn is_priority(&self, peer_id: &PeerId) -> bool { self.priority_nodes.iter().any(|(_, group)| group.contains(peer_id)) @@ -527,7 +552,7 @@ mod tests { #[test] fn full_slots_in() { - let mut peers_state = PeersState::new(1, 1); + let mut peers_state = PeersState::new(1, 1, false); let id1 = PeerId::random(); let id2 = PeerId::random(); @@ -542,7 +567,7 @@ mod tests { #[test] fn priority_node_doesnt_use_slot() { - let mut peers_state = PeersState::new(1, 1); + let mut peers_state = PeersState::new(1, 1, false); let id1 = PeerId::random(); let id2 = PeerId::random(); @@ -558,7 +583,7 @@ mod tests { #[test] fn disconnecting_frees_slot() { - let mut peers_state = PeersState::new(1, 1); + let mut peers_state = PeersState::new(1, 1, false); let id1 = PeerId::random(); let id2 = PeerId::random(); @@ -570,7 +595,7 @@ mod tests { #[test] fn priority_not_connected_peer() { - let mut peers_state = PeersState::new(25, 25); + let mut peers_state = PeersState::new(25, 25, false); let id1 = PeerId::random(); let id2 = PeerId::random(); @@ -589,7 +614,7 @@ mod tests { #[test] fn highest_not_connected_peer() { - let mut peers_state = PeersState::new(25, 25); + let mut peers_state = PeersState::new(25, 25, false); let id1 = PeerId::random(); let id2 = PeerId::random(); @@ -610,7 +635,7 @@ mod tests { #[test] fn disconnect_priority_doesnt_panic() { - let mut peers_state = PeersState::new(1, 1); + let mut peers_state = PeersState::new(1, 1, false); let id = PeerId::random(); peers_state.set_priority_group("test", vec![id.clone()].into_iter().collect()); let peer = peers_state.peer(&id).into_not_connected().unwrap().try_outgoing().unwrap(); @@ -619,7 +644,7 @@ mod tests { #[test] fn multiple_priority_groups_slot_count() { - let mut peers_state = PeersState::new(1, 1); + let mut peers_state = PeersState::new(1, 1, false); let id = PeerId::random(); if let Peer::Unknown(p) = peers_state.peer(&id) { @@ -636,4 +661,60 @@ mod tests { peers_state.set_priority_group("test2", vec![].into_iter().collect()); assert_eq!(peers_state.num_in, 1); } + + #[test] + fn priority_only_mode_ignores_drops_unknown_nodes() { + // test whether connection to/from given peer is allowed + let test_connection = |peers_state: &mut PeersState, id| { + if let Peer::Unknown(p) = peers_state.peer(id) { + p.discover(); + } + + let incoming = if let Peer::NotConnected(p) = peers_state.peer(id) { + p.try_accept_incoming().is_ok() + } else { + panic!() + }; + + if incoming { + peers_state.peer(id).into_connected().map(|p| p.disconnect()); + } + + let outgoing = if let Peer::NotConnected(p) = peers_state.peer(id) { + p.try_outgoing().is_ok() + } else { + panic!() + }; + + if outgoing { + peers_state.peer(id).into_connected().map(|p| p.disconnect()); + } + + incoming || outgoing + }; + + let mut peers_state = PeersState::new(1, 1, true); + let id = PeerId::random(); + + // this is an unknown peer and our peer state is set to only allow + // priority peers so any connection attempt should be denied. + assert!(!test_connection(&mut peers_state, &id)); + + // disabling priority only mode should allow the connection to go + // through. + peers_state.set_priority_only(false); + assert!(test_connection(&mut peers_state, &id)); + + // re-enabling it we should again deny connections from the peer. + peers_state.set_priority_only(true); + assert!(!test_connection(&mut peers_state, &id)); + + // but if we add the peer to a priority group it should be accepted. + peers_state.set_priority_group("TEST_GROUP", vec![id.clone()].into_iter().collect()); + assert!(test_connection(&mut peers_state, &id)); + + // and removing it will cause the connection to once again be denied. + peers_state.remove_from_priority_group("TEST_GROUP", &id); + assert!(!test_connection(&mut peers_state, &id)); + } } -- GitLab From d1401df7453abb0e0a93870d45b5a9e8019d77d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Sat, 28 Sep 2019 19:05:36 +0200 Subject: [PATCH 155/275] ChainSpec extensions (#3692) * Add some chainspec tests and make sure we validate it. * Manual implementation of Extension + Forks definitions. * Move chain spec to separate crate. * Allow using ChainSpec with extensions. * Renames. * Implement Extension derive. * Implement Extension for Forks. * Support specifying fork blocks. * make for_blocks work * Support forks correctly. * Add a bunch of docs. * Make fork blocks optional. * Add missing docs. * Fix build. * Use struct for check_block params. * Fix tests? * Clean up. --- Cargo.lock | 163 ++++---- Cargo.toml | 2 + core/chain-spec/Cargo.toml | 17 + core/chain-spec/derive/Cargo.toml | 17 + core/chain-spec/derive/src/impls.rs | 191 +++++++++ core/chain-spec/derive/src/lib.rs | 39 ++ core/chain-spec/res/chain_spec.json | 31 ++ core/chain-spec/res/chain_spec2.json | 32 ++ .../{service => chain-spec}/src/chain_spec.rs | 167 +++++--- core/chain-spec/src/extension.rs | 363 ++++++++++++++++++ core/chain-spec/src/lib.rs | 124 ++++++ core/cli/src/lib.rs | 123 +++--- core/client/db/src/lib.rs | 5 +- core/client/src/client.rs | 35 +- core/client/src/lib.rs | 5 +- core/client/src/light/mod.rs | 2 +- core/consensus/babe/src/lib.rs | 7 +- core/consensus/babe/src/tests.rs | 7 +- core/consensus/common/src/block_import.rs | 25 +- core/consensus/common/src/import_queue.rs | 9 +- core/consensus/common/src/lib.rs | 2 +- core/finality-grandpa/src/import.rs | 15 +- core/finality-grandpa/src/light_import.rs | 12 +- core/network/src/test/mod.rs | 9 +- core/service/Cargo.toml | 3 +- core/service/src/builder.rs | 89 +++-- core/service/src/chain_ops.rs | 8 +- core/service/src/config.rs | 16 +- core/service/src/lib.rs | 23 +- core/service/test/src/lib.rs | 65 ++-- core/telemetry/src/lib.rs | 2 +- core/test-client/src/lib.rs | 1 + node-template/src/cli.rs | 13 +- node/cli/Cargo.toml | 3 +- node/cli/src/chain_spec.rs | 52 ++- node/cli/src/lib.rs | 16 +- node/cli/src/service.rs | 7 +- node/runtime/src/lib.rs | 2 +- test-utils/chain-spec-builder/src/main.rs | 2 +- 39 files changed, 1368 insertions(+), 336 deletions(-) create mode 100644 core/chain-spec/Cargo.toml create mode 100644 core/chain-spec/derive/Cargo.toml create mode 100644 core/chain-spec/derive/src/impls.rs create mode 100644 core/chain-spec/derive/src/lib.rs create mode 100644 core/chain-spec/res/chain_spec.json create mode 100644 core/chain-spec/res/chain_spec2.json rename core/{service => chain-spec}/src/chain_spec.rs (64%) create mode 100644 core/chain-spec/src/extension.rs create mode 100644 core/chain-spec/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index d36c73c8c4..0787d7faec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -285,7 +285,7 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -357,7 +357,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -522,7 +522,7 @@ dependencies = [ "rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -627,7 +627,7 @@ dependencies = [ "csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -797,7 +797,7 @@ name = "erased-serde" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1377,7 +1377,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1385,7 +1385,7 @@ name = "impl-serde" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1459,7 +1459,7 @@ dependencies = [ "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1473,7 +1473,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1519,7 +1519,7 @@ dependencies = [ "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2354,6 +2354,7 @@ dependencies = [ "node-runtime 2.0.0", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "srml-authority-discovery 0.1.0", @@ -2368,6 +2369,7 @@ dependencies = [ "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-authority-discovery 2.0.0", "substrate-basic-authorship 2.0.0", + "substrate-chain-spec 2.0.0", "substrate-cli 2.0.0", "substrate-client 2.0.0", "substrate-client-db 2.0.0", @@ -2426,7 +2428,7 @@ version = "2.0.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", "substrate-client 2.0.0", @@ -2448,7 +2450,7 @@ dependencies = [ "node-runtime 2.0.0", "node-testing 2.0.0", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", "substrate-keyring 2.0.0", @@ -2479,7 +2481,7 @@ dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-staking-primitives 2.0.0", "sr-std 2.0.0", @@ -2554,7 +2556,7 @@ version = "2.0.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -2762,7 +2764,7 @@ dependencies = [ "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2790,7 +2792,7 @@ dependencies = [ "bitvec 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "byte-slice-cast 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec-derive 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3611,7 +3613,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3626,7 +3628,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.97" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3649,7 +3651,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3743,7 +3745,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3870,7 +3872,7 @@ dependencies = [ "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "primitive-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-std 2.0.0", @@ -3913,7 +3915,7 @@ version = "2.0.0" dependencies = [ "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", ] @@ -3923,7 +3925,7 @@ name = "srml-assets" version = "2.0.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -3939,7 +3941,7 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -3958,7 +3960,7 @@ name = "srml-authority-discovery" version = "0.1.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-staking-primitives 2.0.0", @@ -3994,7 +3996,7 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-staking-primitives 2.0.0", @@ -4016,7 +4018,7 @@ version = "2.0.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4033,7 +4035,7 @@ dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4053,7 +4055,7 @@ dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.40.2 (registry+https://github.com/rust-lang/crates.io-index)", "pwasm-utils 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-sandbox 2.0.0", @@ -4073,7 +4075,7 @@ version = "2.0.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4090,7 +4092,7 @@ dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4106,7 +4108,7 @@ version = "2.0.0" dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4122,7 +4124,7 @@ name = "srml-example" version = "2.0.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4138,7 +4140,7 @@ version = "2.0.0" dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4155,7 +4157,7 @@ version = "2.0.0" dependencies = [ "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4170,7 +4172,7 @@ name = "srml-generic-asset" version = "2.0.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4184,7 +4186,7 @@ name = "srml-grandpa" version = "2.0.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-staking-primitives 2.0.0", @@ -4202,7 +4204,7 @@ name = "srml-im-online" version = "0.1.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-staking-primitives 2.0.0", @@ -4222,7 +4224,7 @@ dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4237,7 +4239,7 @@ name = "srml-membership" version = "2.0.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4251,7 +4253,7 @@ name = "srml-metadata" version = "2.0.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", "substrate-primitives 2.0.0", ] @@ -4261,7 +4263,7 @@ name = "srml-offences" version = "1.0.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-staking-primitives 2.0.0", @@ -4277,7 +4279,7 @@ name = "srml-scored-pool" version = "1.0.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4295,7 +4297,7 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-staking-primitives 2.0.0", @@ -4314,7 +4316,7 @@ version = "2.0.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-staking-primitives 2.0.0", @@ -4347,7 +4349,7 @@ name = "srml-sudo" version = "2.0.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4366,7 +4368,7 @@ dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4414,7 +4416,7 @@ version = "2.0.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "srml-support 2.0.0", "substrate-inherents 2.0.0", @@ -4430,7 +4432,7 @@ dependencies = [ "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4445,7 +4447,7 @@ version = "2.0.0" dependencies = [ "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4460,7 +4462,7 @@ name = "srml-treasury" version = "2.0.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4577,7 +4579,7 @@ name = "substrate-application-crypto" version = "2.0.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4648,6 +4650,30 @@ dependencies = [ "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "substrate-chain-spec" +version = "2.0.0" +dependencies = [ + "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 2.0.0", + "substrate-chain-spec-derive 2.0.0", + "substrate-network 2.0.0", + "substrate-primitives 2.0.0", + "substrate-telemetry 2.0.0", +] + +[[package]] +name = "substrate-chain-spec-derive" +version = "2.0.0" +dependencies = [ + "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "substrate-cli" version = "2.0.0" @@ -5009,7 +5035,7 @@ name = "substrate-finality-grandpa-primitives" version = "2.0.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", "substrate-application-crypto 2.0.0", @@ -5077,7 +5103,7 @@ dependencies = [ "quickcheck 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "slog_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5193,7 +5219,7 @@ dependencies = [ "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", "substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5248,7 +5274,7 @@ dependencies = [ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "sr-version 2.0.0", "substrate-primitives 2.0.0", @@ -5260,7 +5286,7 @@ dependencies = [ name = "substrate-rpc-primitives" version = "2.0.0" dependencies = [ - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-primitives 2.0.0", ] @@ -5273,7 +5299,7 @@ dependencies = [ "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-ws-server 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", ] @@ -5294,7 +5320,7 @@ dependencies = [ name = "substrate-serializer" version = "2.0.0" dependencies = [ - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5314,7 +5340,7 @@ dependencies = [ "parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -5322,6 +5348,7 @@ dependencies = [ "substrate-application-crypto 2.0.0", "substrate-authority-discovery 2.0.0", "substrate-authority-discovery-primitives 2.0.0", + "substrate-chain-spec 2.0.0", "substrate-client 2.0.0", "substrate-client-db 2.0.0", "substrate-consensus-babe-primitives 2.0.0", @@ -5414,7 +5441,7 @@ dependencies = [ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "slog-async 2.3.0 (git+https://github.com/paritytech/slog-async)", "slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5448,7 +5475,7 @@ dependencies = [ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -5497,7 +5524,7 @@ dependencies = [ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-primitives 2.0.0", "substrate-test-runtime 2.0.0", @@ -5711,7 +5738,7 @@ name = "tinytemplate" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5933,7 +5960,7 @@ name = "toml" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6011,7 +6038,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6186,7 +6213,7 @@ name = "wabt" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "wabt-sys 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6881,7 +6908,7 @@ dependencies = [ "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0eddf2e8f50ced781f288c19f18621fa72a3779e3cb58dbf23b07469b0abeb4" -"checksum serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)" = "d46b3dfedb19360a74316866cef04687cd4d6a70df8e6a506c63512790769b72" +"checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd" "checksum serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)" = "c22a0820adfe2f257b098714323563dd06426502abbbce4f51b72ef544c5027f" "checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704" "checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68" diff --git a/Cargo.toml b/Cargo.toml index 20a104b6a1..75f86e7761 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,8 @@ vergen = "3" members = [ "core/authority-discovery", "core/application-crypto", + "core/chain-spec", + "core/chain-spec/derive", "core/cli", "core/client", "core/client/db", diff --git a/core/chain-spec/Cargo.toml b/core/chain-spec/Cargo.toml new file mode 100644 index 0000000000..d3111b094d --- /dev/null +++ b/core/chain-spec/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "substrate-chain-spec" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +chain-spec-derive = { package = "substrate-chain-spec-derive", path = "./derive" } +impl-trait-for-tuples = "0.1.1" +network = { package = "substrate-network", path = "../../core/network" } +primitives = { package = "substrate-primitives", path = "../primitives" } +serde = { version = "1.0.101", features = ["derive"] } +serde_json = "1.0.40" +sr-primitives = { path = "../../core/sr-primitives" } +tel = { package = "substrate-telemetry", path = "../../core/telemetry" } + +[dev-dependencies] diff --git a/core/chain-spec/derive/Cargo.toml b/core/chain-spec/derive/Cargo.toml new file mode 100644 index 0000000000..fab6cd5d1d --- /dev/null +++ b/core/chain-spec/derive/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "substrate-chain-spec-derive" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[lib] +proc-macro = true + +[dependencies] +proc-macro-crate = "0.1.3" +proc-macro2 = "1.0.1" +quote = "1.0.2" +syn = "1.0.5" + +[dev-dependencies] + diff --git a/core/chain-spec/derive/src/impls.rs b/core/chain-spec/derive/src/impls.rs new file mode 100644 index 0000000000..fe6e963286 --- /dev/null +++ b/core/chain-spec/derive/src/impls.rs @@ -0,0 +1,191 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use proc_macro2::{Span, TokenStream}; +use quote::quote; +use syn::{DeriveInput, Ident, Error}; +use proc_macro_crate::crate_name; + +const CRATE_NAME: &str = "substrate-chain-spec"; +const ATTRIBUTE_NAME: &str = "forks"; + +/// Implements `Extension's` `Group` accessor. +/// +/// The struct that derives this implementation will be usable within the `ChainSpec` file. +/// The derive implements a by-type accessor method. +pub fn extension_derive(ast: &DeriveInput) -> proc_macro::TokenStream { + derive(ast, |crate_name, name, generics: &syn::Generics, field_names, field_types, fields| { + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let forks = fields.named.iter().find_map(|f| { + if f.attrs.iter().any(|attr| attr.path.is_ident(ATTRIBUTE_NAME)) { + let typ = &f.ty; + Some(quote! { #typ }) + } else { + None + } + }).unwrap_or_else(|| quote! { #crate_name::NoExtension }); + + quote! { + impl #impl_generics #crate_name::Extension for #name #ty_generics #where_clause { + type Forks = #forks; + + fn get(&self) -> Option<&T> { + use std::any::{Any, TypeId}; + + match TypeId::of::() { + #( x if x == TypeId::of::<#field_types>() => Any::downcast_ref(&self.#field_names) ),*, + _ => None, + } + } + } + } + }) +} + + +/// Implements required traits and creates `Fork` structs for `ChainSpec` custom parameter group. +pub fn group_derive(ast: &DeriveInput) -> proc_macro::TokenStream { + derive(ast, |crate_name, name, generics: &syn::Generics, field_names, field_types, _fields| { + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let fork_name = Ident::new(&format!("{}Fork", name), Span::call_site()); + + let fork_fields = generate_fork_fields(&crate_name, &field_names, &field_types); + let to_fork = generate_base_to_fork(&fork_name, &field_names); + let combine_with = generate_combine_with(&field_names); + let to_base = generate_fork_to_base(name, &field_names); + + quote! { + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecExtension)] + pub struct #fork_name #ty_generics #where_clause { + #fork_fields + } + + impl #impl_generics #crate_name::Group for #name #ty_generics #where_clause { + type Fork = #fork_name #ty_generics; + + fn to_fork(self) -> Self::Fork { + use #crate_name::Group; + #to_fork + } + } + + impl #impl_generics #crate_name::Fork for #fork_name #ty_generics #where_clause { + type Base = #name #ty_generics; + + fn combine_with(&mut self, other: Self) { + use #crate_name::Fork; + #combine_with + } + + fn to_base(self) -> Option { + use #crate_name::Fork; + #to_base + } + } + } + }) +} + +pub fn derive( + ast: &DeriveInput, + derive: impl Fn( + &Ident, &Ident, &syn::Generics, Vec<&Ident>, Vec<&syn::Type>, &syn::FieldsNamed, + ) -> TokenStream, +) -> proc_macro::TokenStream { + let err = || { + let err = Error::new( + Span::call_site(), + "ChainSpecGroup is only avaible for structs with named fields." + ).to_compile_error(); + quote!( #err ).into() + }; + + let data = match &ast.data { + syn::Data::Struct(ref data) => data, + _ => return err(), + }; + + let fields = match &data.fields { + syn::Fields::Named(ref named) => named, + _ => return err(), + }; + + const PROOF: &str = "CARGO_PKG_NAME always defined when compiling; qed"; + let name = &ast.ident; + let crate_name = match crate_name(CRATE_NAME) { + Ok(chain_spec_name) => chain_spec_name, + Err(e) => if std::env::var("CARGO_PKG_NAME").expect(PROOF) == CRATE_NAME { + // we return the name of the crate here instead of `crate` to support doc tests. + CRATE_NAME.replace("-", "_") + } else { + let err = Error::new(Span::call_site(), &e).to_compile_error(); + return quote!( #err ).into() + }, + }; + let crate_name = Ident::new(&crate_name, Span::call_site()); + let field_names = fields.named.iter().flat_map(|x| x.ident.as_ref()).collect::>(); + let field_types = fields.named.iter().map(|x| &x.ty).collect::>(); + + derive(&crate_name, name, &ast.generics, field_names, field_types, fields).into() +} + +fn generate_fork_fields( + crate_name: &Ident, + names: &[&Ident], + types: &[&syn::Type], +) -> TokenStream { + let crate_name = std::iter::repeat(crate_name); + quote! { + #( pub #names: Option<<#types as #crate_name::Group>::Fork>, )* + } +} + +fn generate_base_to_fork( + fork_name: &Ident, + names: &[&Ident], +) -> TokenStream { + let names2 = names.to_vec(); + + quote!{ + #fork_name { + #( #names: Some(self.#names2.to_fork()), )* + } + } +} + +fn generate_combine_with( + names: &[&Ident], +) -> TokenStream { + let names2 = names.to_vec(); + + quote!{ + #( self.#names.combine_with(other.#names2); )* + } +} + +fn generate_fork_to_base( + fork: &Ident, + names: &[&Ident], +) -> TokenStream { + let names2 = names.to_vec(); + + quote!{ + Some(#fork { + #( #names: self.#names2?.to_base()?, )* + }) + } +} + diff --git a/core/chain-spec/derive/src/lib.rs b/core/chain-spec/derive/src/lib.rs new file mode 100644 index 0000000000..bcd50c1021 --- /dev/null +++ b/core/chain-spec/derive/src/lib.rs @@ -0,0 +1,39 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Macros to derive chain spec extension traits implementation. + +extern crate proc_macro; + +mod impls; + +use proc_macro::TokenStream; + +#[proc_macro_derive(ChainSpecGroup)] +pub fn group_derive(input: TokenStream) -> TokenStream { + match syn::parse(input) { + Ok(ast) => impls::group_derive(&ast), + Err(e) => e.to_compile_error().into(), + } +} + +#[proc_macro_derive(ChainSpecExtension, attributes(forks))] +pub fn extensions_derive(input: TokenStream) -> TokenStream { + match syn::parse(input) { + Ok(ast) => impls::extension_derive(&ast), + Err(e) => e.to_compile_error().into(), + } +} diff --git a/core/chain-spec/res/chain_spec.json b/core/chain-spec/res/chain_spec.json new file mode 100644 index 0000000000..673f35d507 --- /dev/null +++ b/core/chain-spec/res/chain_spec.json @@ -0,0 +1,31 @@ +{ + "name": "Flaming Fir", + "id": "flaming-fir", + "properties": { + "tokenDecimals": 15, + "tokenSymbol": "FIR" + }, + "bootNodes": [ + "/ip4/35.246.224.91/tcp/30333/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV", + "/ip4/35.246.224.91/tcp/30334/ws/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV", + "/ip4/35.246.210.11/tcp/30333/p2p/QmWv9Ww7znzgLFyCzf21SR6tUKXrmHCZH9KhebeH4gyE9f", + "/ip4/35.246.210.11/tcp/30334/ws/p2p/QmWv9Ww7znzgLFyCzf21SR6tUKXrmHCZH9KhebeH4gyE9f", + "/ip4/35.198.110.45/tcp/30333/p2p/QmTtcYKJho9vFmqtMA548QBSmLbmwAkBSiEKK3kWKfb6bJ", + "/ip4/35.198.110.45/tcp/30334/ws/p2p/QmTtcYKJho9vFmqtMA548QBSmLbmwAkBSiEKK3kWKfb6bJ", + "/ip4/35.198.114.154/tcp/30333/p2p/QmQJmDorK9c8KjMF5PdWiH2WGUXyzJtgTeJ55S5gggdju6", + "/ip4/35.198.114.154/tcp/30334/ws/p2p/QmQJmDorK9c8KjMF5PdWiH2WGUXyzJtgTeJ55S5gggdju6" + ], + "telemetryEndpoints": [ + ["wss://telemetry.polkadot.io/submit/", 0] + ], + "protocolId": "fir", + "consensusEngine": null, + "genesis": { + "raw": [ + { + "0xb2029f8665aac509629f2d28cea790a3": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26633919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f437800299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d655633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde787932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d129becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993326e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106" + }, + {} + ] + } +} diff --git a/core/chain-spec/res/chain_spec2.json b/core/chain-spec/res/chain_spec2.json new file mode 100644 index 0000000000..950a7fc827 --- /dev/null +++ b/core/chain-spec/res/chain_spec2.json @@ -0,0 +1,32 @@ +{ + "name": "Flaming Fir", + "id": "flaming-fir", + "properties": { + "tokenDecimals": 15, + "tokenSymbol": "FIR" + }, + "bootNodes": [ + "/ip4/35.246.224.91/tcp/30333/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV", + "/ip4/35.246.224.91/tcp/30334/ws/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV", + "/ip4/35.246.210.11/tcp/30333/p2p/QmWv9Ww7znzgLFyCzf21SR6tUKXrmHCZH9KhebeH4gyE9f", + "/ip4/35.246.210.11/tcp/30334/ws/p2p/QmWv9Ww7znzgLFyCzf21SR6tUKXrmHCZH9KhebeH4gyE9f", + "/ip4/35.198.110.45/tcp/30333/p2p/QmTtcYKJho9vFmqtMA548QBSmLbmwAkBSiEKK3kWKfb6bJ", + "/ip4/35.198.110.45/tcp/30334/ws/p2p/QmTtcYKJho9vFmqtMA548QBSmLbmwAkBSiEKK3kWKfb6bJ", + "/ip4/35.198.114.154/tcp/30333/p2p/QmQJmDorK9c8KjMF5PdWiH2WGUXyzJtgTeJ55S5gggdju6", + "/ip4/35.198.114.154/tcp/30334/ws/p2p/QmQJmDorK9c8KjMF5PdWiH2WGUXyzJtgTeJ55S5gggdju6" + ], + "telemetryEndpoints": [ + ["wss://telemetry.polkadot.io/submit/", 0] + ], + "protocolId": "fir", + "consensusEngine": null, + "myProperty": "Test Extension", + "genesis": { + "raw": [ + { + "0xb2029f8665aac509629f2d28cea790a3": "0x10f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26633919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f437800299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d655633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde787932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d129becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993326e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106" + }, + {} + ] + } +} diff --git a/core/service/src/chain_spec.rs b/core/chain-spec/src/chain_spec.rs similarity index 64% rename from core/service/src/chain_spec.rs rename to core/chain-spec/src/chain_spec.rs index 8b35b0bac9..b4c57f1e03 100644 --- a/core/service/src/chain_spec.rs +++ b/core/chain-spec/src/chain_spec.rs @@ -53,14 +53,15 @@ impl GenesisSource { match self { GenesisSource::File(path) => { - let file = File::open(path).map_err(|e| format!("Error opening spec file: {}", e))?; - let genesis: GenesisContainer = - json::from_reader(file).map_err(|e| format!("Error parsing spec file: {}", e))?; + let file = File::open(path) + .map_err(|e| format!("Error opening spec file: {}", e))?; + let genesis: GenesisContainer = json::from_reader(file) + .map_err(|e| format!("Error parsing spec file: {}", e))?; Ok(genesis.genesis) }, GenesisSource::Binary(buf) => { - let genesis: GenesisContainer = - json::from_reader(buf.as_ref()).map_err(|e| format!("Error parsing embedded file: {}", e))?; + let genesis: GenesisContainer = json::from_reader(buf.as_ref()) + .map_err(|e| format!("Error parsing embedded file: {}", e))?; Ok(genesis.genesis) }, GenesisSource::Factory(f) => Ok(Genesis::Runtime(f())), @@ -68,7 +69,7 @@ impl GenesisSource { } } -impl<'a, G: RuntimeGenesis> BuildStorage for &'a ChainSpec { +impl<'a, G: RuntimeGenesis, E> BuildStorage for &'a ChainSpec { fn build_storage(self) -> Result<(StorageOverlay, ChildrenStorageOverlay), String> { match self.genesis.resolve()? { Genesis::Runtime(gc) => gc.build_storage(), @@ -82,7 +83,10 @@ impl<'a, G: RuntimeGenesis> BuildStorage for &'a ChainSpec { } } - fn assimilate_storage(self, _: &mut (StorageOverlay, ChildrenStorageOverlay)) -> Result<(), String> { + fn assimilate_storage( + self, + _: &mut (StorageOverlay, ChildrenStorageOverlay) + ) -> Result<(), String> { Err("`assimilate_storage` not implemented for `ChainSpec`.".into()) } } @@ -98,28 +102,39 @@ enum Genesis { ), } -#[derive(Serialize, Deserialize, Clone)] +#[derive(Serialize, Deserialize, Clone, Debug)] #[serde(rename_all = "camelCase")] -struct ChainSpecFile { +#[serde(deny_unknown_fields)] +struct ChainSpecFile { pub name: String, pub id: String, pub boot_nodes: Vec, pub telemetry_endpoints: Option, pub protocol_id: Option, - pub consensus_engine: Option, pub properties: Option, + #[serde(flatten)] + pub extensions: E, + // Never used, left only for backward compatibility. + consensus_engine: (), + #[serde(skip_serializing)] + genesis: serde::de::IgnoredAny, } /// Arbitrary properties defined in chain spec as a JSON object pub type Properties = json::map::Map; +/// A type denoting empty extensions. +/// +/// We use `Option` here since `()` is not flattenable by serde. +pub type NoExtension = Option<()>; + /// A configuration of a chain. Can be used to build a genesis block. -pub struct ChainSpec { - spec: ChainSpecFile, +pub struct ChainSpec { + spec: ChainSpecFile, genesis: GenesisSource, } -impl Clone for ChainSpec { +impl Clone for ChainSpec { fn clone(&self) -> Self { ChainSpec { spec: self.spec.clone(), @@ -128,7 +143,7 @@ impl Clone for ChainSpec { } } -impl ChainSpec { +impl ChainSpec { /// A list of bootnode addresses. pub fn boot_nodes(&self) -> &[String] { &self.spec.boot_nodes @@ -154,14 +169,10 @@ impl ChainSpec { self.spec.protocol_id.as_ref().map(String::as_str) } - /// Name of the consensus engine. - pub fn consensus_engine(&self) -> Option<&str> { - self.spec.consensus_engine.as_ref().map(String::as_str) - } - /// Additional loosly-typed properties of the chain. + /// + /// Returns an empty JSON object if 'properties' not defined in config pub fn properties(&self) -> Properties { - // Return an empty JSON object if 'properties' not defined in config self.spec.properties.as_ref().unwrap_or(&json::map::Map::new()).clone() } @@ -170,24 +181,9 @@ impl ChainSpec { self.spec.boot_nodes.push(addr.to_string()) } - /// Parse json content into a `ChainSpec` - pub fn from_json_bytes(json: impl Into>) -> Result { - let json = json.into(); - let spec = json::from_slice(json.as_ref()).map_err(|e| format!("Error parsing spec file: {}", e))?; - Ok(ChainSpec { - spec, - genesis: GenesisSource::Binary(json), - }) - } - - /// Parse json file into a `ChainSpec` - pub fn from_json_file(path: PathBuf) -> Result { - let file = File::open(&path).map_err(|e| format!("Error opening spec file: {}", e))?; - let spec = json::from_reader(file).map_err(|e| format!("Error parsing spec file: {}", e))?; - Ok(ChainSpec { - spec, - genesis: GenesisSource::File(path), - }) + /// Returns a reference to defined chain spec extensions. + pub fn extensions(&self) -> &E { + &self.spec.extensions } /// Create hardcoded spec. @@ -198,19 +194,21 @@ impl ChainSpec { boot_nodes: Vec, telemetry_endpoints: Option, protocol_id: Option<&str>, - consensus_engine: Option<&str>, properties: Option, - ) -> Self - { + extensions: E, + ) -> Self { let spec = ChainSpecFile { name: name.to_owned(), id: id.to_owned(), boot_nodes: boot_nodes, telemetry_endpoints, protocol_id: protocol_id.map(str::to_owned), - consensus_engine: consensus_engine.map(str::to_owned), properties, + extensions, + consensus_engine: (), + genesis: Default::default(), }; + ChainSpec { spec, genesis: GenesisSource::Factory(constructor), @@ -218,13 +216,38 @@ impl ChainSpec { } } -impl ChainSpec { +impl ChainSpec { + /// Parse json content into a `ChainSpec` + pub fn from_json_bytes(json: impl Into>) -> Result { + let json = json.into(); + let spec = json::from_slice(json.as_ref()) + .map_err(|e| format!("Error parsing spec file: {}", e))?; + Ok(ChainSpec { + spec, + genesis: GenesisSource::Binary(json), + }) + } + + /// Parse json file into a `ChainSpec` + pub fn from_json_file(path: PathBuf) -> Result { + let file = File::open(&path) + .map_err(|e| format!("Error opening spec file: {}", e))?; + let spec = json::from_reader(file) + .map_err(|e| format!("Error parsing spec file: {}", e))?; + Ok(ChainSpec { + spec, + genesis: GenesisSource::File(path), + }) + } +} + +impl ChainSpec { /// Dump to json string. pub fn to_json(self, raw: bool) -> Result { #[derive(Serialize, Deserialize)] - struct Container { + struct Container { #[serde(flatten)] - spec: ChainSpecFile, + spec: ChainSpecFile, genesis: Genesis, }; @@ -251,6 +274,58 @@ impl ChainSpec { spec: self.spec, genesis, }; - json::to_string_pretty(&spec).map_err(|e| format!("Error generating spec json: {}", e)) + json::to_string_pretty(&spec) + .map_err(|e| format!("Error generating spec json: {}", e)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[derive(Debug, Serialize, Deserialize)] + struct Genesis(HashMap); + + impl BuildStorage for Genesis { + fn assimilate_storage( + self, + storage: &mut (StorageOverlay, ChildrenStorageOverlay), + ) -> Result<(), String> { + storage.0.extend( + self.0.into_iter().map(|(a, b)| (a.into_bytes(), b.into_bytes())) + ); + Ok(()) + } + } + + type TestSpec = ChainSpec; + + #[test] + fn should_deserailize_example_chain_spec() { + let spec1 = TestSpec::from_json_bytes(Cow::Owned( + include_bytes!("../res/chain_spec.json").to_vec() + )).unwrap(); + let spec2 = TestSpec::from_json_file( + PathBuf::from("./res/chain_spec.json") + ).unwrap(); + + assert_eq!(spec1.to_json(false), spec2.to_json(false)); + } + + #[derive(Debug, Serialize, Deserialize)] + #[serde(rename_all = "camelCase")] + struct Extension1 { + my_property: String, + } + + type TestSpec2 = ChainSpec; + + #[test] + fn should_deserialize_chain_spec_with_extensions() { + let spec = TestSpec2::from_json_bytes(Cow::Owned( + include_bytes!("../res/chain_spec2.json").to_vec() + )).unwrap(); + + assert_eq!(spec.extensions().my_property, "Test Extension"); } } diff --git a/core/chain-spec/src/extension.rs b/core/chain-spec/src/extension.rs new file mode 100644 index 0000000000..bf98ced04d --- /dev/null +++ b/core/chain-spec/src/extension.rs @@ -0,0 +1,363 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Chain Spec extensions helpers. + +use std::fmt::Debug; +use std::collections::BTreeMap; + +use serde::{Serialize, Deserialize, de::DeserializeOwned}; + +/// A `ChainSpec` extension. +/// +/// This trait is implemented automatically by `ChainSpecGroup` macro. +pub trait Group: Clone + Sized { + /// An associated type containing fork definition. + type Fork: Fork; + + /// Convert to fork type. + fn to_fork(self) -> Self::Fork; +} + +/// A `ChainSpec` extension fork definition. +/// +/// Basically should look the same as `Group`, but +/// all parameters are optional. This allows changing +/// only one parameter as part of the fork. +/// The forks can be combined (summed up) to specify +/// a complete set of parameters +pub trait Fork: Serialize + DeserializeOwned + Clone + Sized { + /// A base `Group` type. + type Base: Group; + + /// Combine with another struct. + /// + /// All parameters set in `other` should override the + /// ones in the current struct. + fn combine_with(&mut self, other: Self); + + /// Attempt to convert to the base type if all parameters are set. + fn to_base(self) -> Option; +} + +macro_rules! impl_trivial { + () => {}; + ($A : ty) => { + impl_trivial!($A ,); + }; + ($A : ty , $( $B : ty ),*) => { + impl_trivial!($( $B ),*); + + impl Group for $A { + type Fork = $A; + + fn to_fork(self) -> Self::Fork { + self + } + } + + impl Fork for $A { + type Base = $A; + + fn combine_with(&mut self, other: Self) { + *self = other; + } + + fn to_base(self) -> Option { + Some(self) + } + } + } +} + +impl_trivial!((), u8, u16, u32, u64, usize, String, Vec); + +impl Group for Option { + type Fork = Option; + + fn to_fork(self) -> Self::Fork { + self.map(|a| a.to_fork()) + } +} + +impl Fork for Option { + type Base = Option; + + fn combine_with(&mut self, other: Self) { + *self = match (self.take(), other) { + (Some(mut a), Some(b)) => { + a.combine_with(b); + Some(a) + }, + (a, b) => a.or(b), + }; + } + + fn to_base(self) -> Option { + self.map(|x| x.to_base()) + } +} + +/// A collection of `ChainSpec` extensions. +/// +/// This type can be passed around and allows the core +/// modules to request a strongly-typed, but optional configuration. +pub trait Extension: Serialize + DeserializeOwned + Clone { + type Forks: IsForks; + + /// Get an extension of specific type. + fn get(&self) -> Option<&T>; + + /// Get forkable extensions of specific type. + fn forks(&self) -> Option> where + BlockNumber: Ord + Clone + 'static, + T: Group + 'static, + ::Extension: Extension, + <::Extension as Group>::Fork: Extension, + { + self.get::::Extension>>()? + .for_type() + } +} + +impl Extension for crate::NoExtension { + type Forks = Self; + + fn get(&self) -> Option<&T> { None } +} + +pub trait IsForks { + type BlockNumber: Ord + 'static; + type Extension: Group + 'static; +} + +impl IsForks for Option<()> { + type BlockNumber = u64; + type Extension = Self; +} + +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[serde(deny_unknown_fields)] +pub struct Forks { + forks: BTreeMap, + #[serde(flatten)] + base: T, +} + +impl Default for Forks { + fn default() -> Self { + Self { + base: Default::default(), + forks: Default::default(), + } + } +} + +impl Forks where + T::Fork: Debug, +{ + /// Create new fork definition given the base and the forks. + pub fn new(base: T, forks: BTreeMap) -> Self { + Self { base, forks } + } + + /// Return a set of parameters for `Group` including all forks up to `block` (inclusive). + pub fn at_block(&self, block: B) -> T { + let mut start = self.base.clone().to_fork(); + + for (_, fork) in self.forks.range(..=block) { + start.combine_with(fork.clone()); + } + + start + .to_base() + .expect("We start from the `base` object, so it's always fully initialized; qed") + } +} + +impl IsForks for Forks where + B: Ord + 'static, + T: Group + 'static, +{ + type BlockNumber = B; + type Extension = T; +} + +impl Forks where + T::Fork: Extension, +{ + /// Get forks definition for a subset of this extension. + /// + /// Returns the `Forks` struct, but limited to a particular type + /// within the extension. + pub fn for_type(&self) -> Option> where + X: Group + 'static, + { + let base = self.base.get::()?.clone(); + let forks = self.forks.iter().filter_map(|(k, v)| { + Some((k.clone(), v.get::>()?.clone()?)) + }).collect(); + + Some(Forks { + base, + forks, + }) + } +} + +impl Extension for Forks where + B: Serialize + DeserializeOwned + Ord + Clone + 'static, + E: Extension + Group + 'static, +{ + type Forks = Self; + + fn get(&self) -> Option<&T> { + use std::any::{TypeId, Any}; + + match TypeId::of::() { + x if x == TypeId::of::() => Any::downcast_ref(&self.base), + _ => self.base.get(), + } + } + + fn forks(&self) -> Option> where + BlockNumber: Ord + Clone + 'static, + T: Group + 'static, + ::Extension: Extension, + <::Extension as Group>::Fork: Extension, + { + use std::any::{TypeId, Any}; + + if TypeId::of::() == TypeId::of::() { + Any::downcast_ref(&self.for_type::()?).cloned() + } else { + self.get::::Extension>>()? + .for_type() + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use chain_spec_derive::{ChainSpecGroup, ChainSpecExtension}; + // Make the proc macro work for tests and doc tests. + use crate as substrate_chain_spec; + + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup)] + #[serde(deny_unknown_fields)] + pub struct Extension1 { + pub test: u64, + } + + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup)] + #[serde(deny_unknown_fields)] + pub struct Extension2 { + pub test: u8, + } + + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)] + #[serde(deny_unknown_fields)] + pub struct Extensions { + pub ext1: Extension1, + pub ext2: Extension2, + } + + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecExtension)] + #[serde(deny_unknown_fields)] + pub struct Ext2 { + #[serde(flatten)] + ext1: Extension1, + #[forks] + forkable: Forks, + } + + #[test] + fn forks_should_work_correctly() { + use super::Extension as _ ; + + let ext: Ext2 = serde_json::from_str(r#" +{ + "test": 11, + "forkable": { + "ext1": { + "test": 15 + }, + "ext2": { + "test": 123 + }, + "forks": { + "1": { + "ext1": { "test": 5 } + }, + "2": { + "ext2": { "test": 5 } + }, + "5": { + "ext2": { "test": 1 } + } + } + } +} + "#).unwrap(); + + assert_eq!(ext.get::(), Some(&Extension1 { + test: 11 + })); + + // get forks definition + let forks = ext.get::>().unwrap(); + assert_eq!(forks.at_block(0), Extensions { + ext1: Extension1 { test: 15 }, + ext2: Extension2 { test: 123 }, + }); + assert_eq!(forks.at_block(1), Extensions { + ext1: Extension1 { test: 5 }, + ext2: Extension2 { test: 123 }, + }); + assert_eq!(forks.at_block(2), Extensions { + ext1: Extension1 { test: 5 }, + ext2: Extension2 { test: 5 }, + }); + assert_eq!(forks.at_block(4), Extensions { + ext1: Extension1 { test: 5 }, + ext2: Extension2 { test: 5 }, + }); + assert_eq!(forks.at_block(5), Extensions { + ext1: Extension1 { test: 5 }, + ext2: Extension2 { test: 1 }, + }); + assert_eq!(forks.at_block(10), Extensions { + ext1: Extension1 { test: 5 }, + ext2: Extension2 { test: 1 }, + }); + assert!(forks.at_block(10).get::().is_some()); + + // filter forks for `Extension2` + let ext2 = forks.for_type::().unwrap(); + assert_eq!(ext2.at_block(0), Extension2 { test: 123 }); + assert_eq!(ext2.at_block(2), Extension2 { test: 5 }); + assert_eq!(ext2.at_block(10), Extension2 { test: 1 }); + + // make sure that it can return forks correctly + let ext2_2 = forks.forks::().unwrap(); + assert_eq!(ext2, ext2_2); + + // also ext should be able to return forks correctly: + let ext2_3 = ext.forks::().unwrap(); + assert_eq!(ext2_2, ext2_3); + } +} diff --git a/core/chain-spec/src/lib.rs b/core/chain-spec/src/lib.rs new file mode 100644 index 0000000000..88184b9706 --- /dev/null +++ b/core/chain-spec/src/lib.rs @@ -0,0 +1,124 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Substrate chain configurations. +//! +//! This crate contains structs and utilities to declare +//! a runtime-specific configuration file (a.k.a chain spec). +//! +//! Basic chain spec type containing all required parameters is +//! [`ChainSpec`](./struct.ChainSpec.html). It can be extended with +//! additional options that contain configuration specific to your chain. +//! Usually the extension is going to be an amalgamate of types exposed +//! by Substrate core modules. To allow the core modules to retrieve +//! their configuration from your extension you should use `ChainSpecExtension` +//! macro exposed by this crate. +//! +//! ```rust +//! use std::collections::HashMap; +//! use serde::{Serialize, Deserialize}; +//! use substrate_chain_spec::{ChainSpec, ChainSpecExtension}; +//! +//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecExtension)] +//! pub struct MyExtension { +//! pub known_blocks: HashMap, +//! } +//! +//! pub type MyChainSpec = ChainSpec; +//! ``` +//! +//! Some parameters may require different values depending on the +//! current blockchain height (a.k.a. forks). You can use `ChainSpecGroup` +//! macro and provided [`Forks`](./struct.Forks.html) structure to put +//! such parameters to your chain spec. +//! This will allow to override a single parameter starting at specific +//! block number. +//! +//! ```rust +//! use serde::{Serialize, Deserialize}; +//! use substrate_chain_spec::{Forks, ChainSpec, ChainSpecGroup, ChainSpecExtension}; +//! +//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup)] +//! pub struct ClientParams { +//! max_block_size: usize, +//! max_extrinsic_size: usize, +//! } +//! +//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup)] +//! pub struct PoolParams { +//! max_transaction_size: usize, +//! } +//! +//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)] +//! pub struct Extension { +//! pub client: ClientParams, +//! pub pool: PoolParams, +//! } +//! +//! pub type BlockNumber = u64; +//! +//! /// A chain spec supporting forkable `ClientParams`. +//! pub type MyChainSpec1 = ChainSpec>; +//! +//! /// A chain spec supporting forkable `Extension`. +//! pub type MyChainSpec2 = ChainSpec>; +//! ``` +//! +//! It's also possible to have a set of parameters that is allowed to change +//! with block numbers (i.e. is forkable), and another set that is not subject to changes. +//! This is also possible by declaring an extension that contains `Forks` within it. +//! +//! +//! ```rust +//! use serde::{Serialize, Deserialize}; +//! use substrate_chain_spec::{Forks, ChainSpec, ChainSpecGroup, ChainSpecExtension}; +//! +//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup)] +//! pub struct ClientParams { +//! max_block_size: usize, +//! max_extrinsic_size: usize, +//! } +//! +//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup)] +//! pub struct PoolParams { +//! max_transaction_size: usize, +//! } +//! +//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecExtension)] +//! pub struct Extension { +//! pub client: ClientParams, +//! #[forks] +//! pub pool: Forks, +//! } +//! +//! pub type MyChainSpec = ChainSpec; +//! ``` + + +mod chain_spec; +mod extension; + +pub use chain_spec::{ChainSpec, Properties, NoExtension}; +pub use extension::{Group, Fork, Forks, Extension}; +pub use chain_spec_derive::{ChainSpecExtension, ChainSpecGroup}; + +use serde::{Serialize, de::DeserializeOwned}; +use sr_primitives::BuildStorage; + +/// A set of traits for the runtime genesis config. +pub trait RuntimeGenesis: Serialize + DeserializeOwned + BuildStorage {} +impl RuntimeGenesis for T {} + diff --git a/core/cli/src/lib.rs b/core/cli/src/lib.rs index 9aa5373f09..7d5593f2cd 100644 --- a/core/cli/src/lib.rs +++ b/core/cli/src/lib.rs @@ -30,11 +30,14 @@ use client::ExecutionStrategies; use service::{ config::Configuration, ServiceBuilderExport, ServiceBuilderImport, ServiceBuilderRevert, - RuntimeGenesis, PruningMode, ChainSpec, + RuntimeGenesis, ChainSpecExtension, PruningMode, ChainSpec, }; use network::{ - self, multiaddr::Protocol, - config::{NetworkConfiguration, TransportConfig, NonReservedPeerMode, NodeKeyConfig, build_multiaddr}, + self, + multiaddr::Protocol, + config::{ + NetworkConfiguration, TransportConfig, NonReservedPeerMode, NodeKeyConfig, build_multiaddr + }, }; use primitives::H256; @@ -121,8 +124,10 @@ fn generate_node_name() -> String { result } -fn load_spec(cli: &SharedParams, factory: F) -> error::Result> - where G: RuntimeGenesis, F: FnOnce(&str) -> Result>, String>, +fn load_spec(cli: &SharedParams, factory: F) -> error::Result> where + G: RuntimeGenesis, + E: ChainSpecExtension, + F: FnOnce(&str) -> Result>, String>, { let chain_key = get_chain_key(cli); let spec = match factory(&chain_key)? { @@ -263,20 +268,23 @@ pub struct ParseAndPrepareRun<'a, RP> { impl<'a, RP> ParseAndPrepareRun<'a, RP> { /// Runs the command and runs the main client. - pub fn run( + pub fn run( self, spec_factory: S, - exit: E, + exit: Exit, run_service: RS, ) -> error::Result<()> - where S: FnOnce(&str) -> Result>, String>, + where S: FnOnce(&str) -> Result>, String>, RP: StructOpt + Clone, C: Default, G: RuntimeGenesis, - E: IntoExit, - RS: FnOnce(E, RunCmd, RP, Configuration) -> Result<(), String> + E: ChainSpecExtension, + Exit: IntoExit, + RS: FnOnce(Exit, RunCmd, RP, Configuration) -> Result<(), String> { - let config = create_run_node_config(self.params.left.clone(), spec_factory, self.impl_name, self.version)?; + let config = create_run_node_config( + self.params.left.clone(), spec_factory, self.impl_name, self.version + )?; run_service(exit, self.params.left, self.params.right, config).map_err(Into::into) } @@ -290,12 +298,13 @@ pub struct ParseAndPrepareBuildSpec<'a> { impl<'a> ParseAndPrepareBuildSpec<'a> { /// Runs the command and build the chain specs. - pub fn run( + pub fn run( self, spec_factory: S - ) -> error::Result<()> - where S: FnOnce(&str) -> Result>, String>, - G: RuntimeGenesis + ) -> error::Result<()> where + S: FnOnce(&str) -> Result>, String>, + G: RuntimeGenesis, + E: ChainSpecExtension, { info!("Building chain spec"); let raw_output = self.params.raw; @@ -317,18 +326,19 @@ pub struct ParseAndPrepareExport<'a> { impl<'a> ParseAndPrepareExport<'a> { /// Runs the command and exports from the chain. - pub fn run_with_builder( + pub fn run_with_builder( self, builder: F, spec_factory: S, - exit: E, + exit: Exit, ) -> error::Result<()> - where S: FnOnce(&str) -> Result>, String>, - F: FnOnce(Configuration) -> Result, + where S: FnOnce(&str) -> Result>, String>, + F: FnOnce(Configuration) -> Result, B: ServiceBuilderExport, C: Default, G: RuntimeGenesis, - E: IntoExit + E: ChainSpecExtension, + Exit: IntoExit { let config = create_config_with_db_path(spec_factory, &self.params.shared_params, self.version)?; @@ -355,18 +365,19 @@ pub struct ParseAndPrepareImport<'a> { impl<'a> ParseAndPrepareImport<'a> { /// Runs the command and imports to the chain. - pub fn run_with_builder( + pub fn run_with_builder( self, builder: F, spec_factory: S, - exit: E, + exit: Exit, ) -> error::Result<()> - where S: FnOnce(&str) -> Result>, String>, - F: FnOnce(Configuration) -> Result, + where S: FnOnce(&str) -> Result>, String>, + F: FnOnce(Configuration) -> Result, B: ServiceBuilderImport, C: Default, G: RuntimeGenesis, - E: IntoExit + E: ChainSpecExtension, + Exit: IntoExit { let mut config = create_config_with_db_path(spec_factory, &self.params.shared_params, self.version)?; config.execution_strategies = ExecutionStrategies { @@ -398,14 +409,17 @@ pub struct ParseAndPreparePurge<'a> { impl<'a> ParseAndPreparePurge<'a> { /// Runs the command and purges the chain. - pub fn run( + pub fn run( self, spec_factory: S - ) -> error::Result<()> - where S: FnOnce(&str) -> Result>, String>, - G: RuntimeGenesis + ) -> error::Result<()> where + S: FnOnce(&str) -> Result>, String>, + G: RuntimeGenesis, + E: ChainSpecExtension, { - let config = create_config_with_db_path::<(), _, _>(spec_factory, &self.params.shared_params, self.version)?; + let config = create_config_with_db_path::<(), _, _, _>( + spec_factory, &self.params.shared_params, self.version + )?; let db_path = config.database_path; if !self.params.yes { @@ -447,17 +461,21 @@ pub struct ParseAndPrepareRevert<'a> { impl<'a> ParseAndPrepareRevert<'a> { /// Runs the command and reverts the chain. - pub fn run_with_builder( + pub fn run_with_builder( self, builder: F, spec_factory: S - ) -> error::Result<()> - where S: FnOnce(&str) -> Result>, String>, - F: FnOnce(Configuration) -> Result, + ) -> error::Result<()> where + S: FnOnce(&str) -> Result>, String>, + F: FnOnce(Configuration) -> Result, B: ServiceBuilderRevert, C: Default, - G: RuntimeGenesis { - let config = create_config_with_db_path(spec_factory, &self.params.shared_params, self.version)?; + G: RuntimeGenesis, + E: ChainSpecExtension, + { + let config = create_config_with_db_path( + spec_factory, &self.params.shared_params, self.version + )?; let blocks = self.params.num; builder(config)?.revert_chain(blocks.into())?; Ok(()) @@ -519,8 +537,8 @@ fn parse_ed25519_secret(hex: &String) -> error::Result( - options: &mut Configuration, +fn fill_transaction_pool_configuration( + options: &mut Configuration, params: TransactionPoolParams, ) -> error::Result<()> { // ready queue @@ -595,8 +613,8 @@ fn input_keystore_password() -> Result { } /// Fill the password field of the given config instance. -fn fill_config_keystore_password( - config: &mut service::Configuration, +fn fill_config_keystore_password( + config: &mut service::Configuration, cli: &RunCmd, ) -> Result<(), String> { config.keystore_password = if cli.password_interactive { @@ -612,13 +630,14 @@ fn fill_config_keystore_password( Ok(()) } -fn create_run_node_config( +fn create_run_node_config( cli: RunCmd, spec_factory: S, impl_name: &'static str, version: &VersionInfo -) -> error::Result> +) -> error::Result> where C: Default, G: RuntimeGenesis, - S: FnOnce(&str) -> Result>, String>, + E: ChainSpecExtension, + S: FnOnce(&str) -> Result>, String>, { let spec = load_spec(&cli.shared_params, spec_factory)?; let mut config = service::Configuration::default_with_spec(spec.clone()); @@ -657,8 +676,8 @@ where config.pruning = match cli.pruning { Some(ref s) if s == "archive" => PruningMode::ArchiveAll, None => PruningMode::default(), - Some(s) => PruningMode::keep_blocks( - s.parse().map_err(|_| error::Error::Input("Invalid pruning mode specified".to_string()))? + Some(s) => PruningMode::keep_blocks(s.parse() + .map_err(|_| error::Error::Input("Invalid pruning mode specified".to_string()))? ), }; @@ -756,13 +775,14 @@ where // 9803-9874 Unassigned // 9926-9949 Unassigned -fn with_default_boot_node( - spec: &mut ChainSpec, +fn with_default_boot_node( + spec: &mut ChainSpec, cli: BuildSpecCmd, version: &VersionInfo, ) -> error::Result<()> where - G: RuntimeGenesis + G: RuntimeGenesis, + E: ChainSpecExtension, { if spec.boot_nodes().is_empty() { let base_path = base_path(&cli.shared_params, version); @@ -781,13 +801,14 @@ where } /// Creates a configuration including the database path. -pub fn create_config_with_db_path( +pub fn create_config_with_db_path( spec_factory: S, cli: &SharedParams, version: &VersionInfo, -) -> error::Result> +) -> error::Result> where C: Default, G: RuntimeGenesis, - S: FnOnce(&str) -> Result>, String>, + E: ChainSpecExtension, + S: FnOnce(&str) -> Result>, String>, { let spec = load_spec(cli, spec_factory)?; let base_path = base_path(cli, version); diff --git a/core/client/db/src/lib.rs b/core/client/db/src/lib.rs index daf0f47889..728858e2d6 100644 --- a/core/client/db/src/lib.rs +++ b/core/client/db/src/lib.rs @@ -40,7 +40,7 @@ use std::collections::{HashMap, HashSet}; use client::backend::NewBlockState; use client::blockchain::{well_known_cache_keys, HeaderBackend}; -use client::ExecutionStrategies; +use client::{ForkBlocks, ExecutionStrategies}; use client::backend::{StorageCollection, ChildStorageCollection}; use codec::{Decode, Encode}; use hash_db::{Hasher, Prefix}; @@ -206,6 +206,7 @@ pub fn new_client( settings: DatabaseSettings, executor: E, genesis_storage: S, + fork_blocks: ForkBlocks, execution_strategies: ExecutionStrategies, keystore: Option, ) -> Result<( @@ -227,7 +228,7 @@ pub fn new_client( let backend = Arc::new(Backend::new(settings, CANONICALIZATION_DELAY)?); let executor = client::LocalCallExecutor::new(backend.clone(), executor, keystore); Ok(( - client::Client::new(backend.clone(), executor, genesis_storage, execution_strategies)?, + client::Client::new(backend.clone(), executor, genesis_storage, fork_blocks, execution_strategies)?, backend, )) } diff --git a/core/client/src/client.rs b/core/client/src/client.rs index 50bbe1efbc..8b7d2dc995 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -47,7 +47,7 @@ use state_machine::{ }; use executor::{RuntimeVersion, RuntimeInfo}; use consensus::{ - Error as ConsensusError, BlockStatus, BlockImportParams, + Error as ConsensusError, BlockStatus, BlockImportParams, BlockCheckParams, ImportResult, BlockOrigin, ForkChoiceStrategy, SelectChain, self, }; @@ -87,6 +87,11 @@ type StorageUpdate = < >::State as state_machine::Backend>::Transaction; type ChangesUpdate = ChangesTrieTransaction>; +/// Expected hashes of blocks at given heights. +/// +/// This may be used as chain spec extension to filter out known, unwanted forks. +pub type ForkBlocks = Option, ::Hash>>; + /// Execution strategies settings. #[derive(Debug, Clone)] pub struct ExecutionStrategies { @@ -123,6 +128,7 @@ pub struct Client where Block: BlockT { finality_notification_sinks: Mutex>>>, // holds the block hash currently being imported. TODO: replace this with block queue importing_block: RwLock>, + fork_blocks: ForkBlocks, execution_strategies: ExecutionStrategies, _phantom: PhantomData, } @@ -263,7 +269,7 @@ pub fn new_with_backend( B: backend::LocalBackend { let call_executor = LocalCallExecutor::new(backend.clone(), executor, keystore); - Client::new(backend, call_executor, build_genesis_storage, Default::default()) + Client::new(backend, call_executor, build_genesis_storage, Default::default(), Default::default()) } /// Figure out the block type for a given type (for now, just a `Client`). @@ -290,6 +296,7 @@ impl Client where backend: Arc, executor: E, build_genesis_storage: S, + fork_blocks: ForkBlocks, execution_strategies: ExecutionStrategies ) -> error::Result { if backend.blockchain().header(BlockId::Number(Zero::zero()))?.is_none() { @@ -318,6 +325,7 @@ impl Client where import_notification_sinks: Default::default(), finality_notification_sinks: Default::default(), importing_block: Default::default(), + fork_blocks, execution_strategies, _phantom: Default::default(), }) @@ -1499,9 +1507,22 @@ impl<'a, B, E, Block, RA> consensus::BlockImport for &'a Client, ) -> Result { + let BlockCheckParams { hash, number, parent_hash } = block; + + if let Some(h) = self.fork_blocks.as_ref().and_then(|x| x.get(&number)) { + if &hash != h { + trace!( + "Rejecting block from known invalid fork. Got {:?}, expected: {:?} at height {}", + hash, + h, + number + ); + return Ok(ImportResult::KnownBad); + } + } + match self.block_status(&BlockId::Hash(parent_hash)) .map_err(|e| ConsensusError::ClientImport(e.to_string()))? { @@ -1518,6 +1539,7 @@ impl<'a, B, E, Block, RA> consensus::BlockImport for &'a Client return Ok(ImportResult::KnownBad), } + Ok(ImportResult::imported(false)) } } @@ -1539,10 +1561,9 @@ impl consensus::BlockImport for Client fn check_block( &mut self, - hash: Block::Hash, - parent_hash: Block::Hash, + block: BlockCheckParams, ) -> Result { - (&*self).check_block(hash, parent_hash) + (&*self).check_block(block) } } diff --git a/core/client/src/lib.rs b/core/client/src/lib.rs index b56c6a5706..70c9b75926 100644 --- a/core/client/src/lib.rs +++ b/core/client/src/lib.rs @@ -67,7 +67,8 @@ //! ), //! // This parameter provides the storage for the chain genesis. //! <(StorageOverlay, ChildrenStorageOverlay)>::default(), -//! Default::default() +//! Default::default(), +//! Default::default(), //! ); //! ``` //! @@ -115,7 +116,7 @@ pub use crate::client::{ new_in_mem, BlockBody, ImportNotifications, FinalityNotifications, BlockchainEvents, BlockImportNotification, Client, ClientInfo, ExecutionStrategies, FinalityNotification, - LongestChain, BlockOf, ProvideUncles, + LongestChain, BlockOf, ProvideUncles, ForkBlocks, utils, apply_aux, }; #[cfg(feature = "std")] diff --git a/core/client/src/light/mod.rs b/core/client/src/light/mod.rs index 03b7dcff85..c9d2e6040b 100644 --- a/core/client/src/light/mod.rs +++ b/core/client/src/light/mod.rs @@ -67,7 +67,7 @@ pub fn new_light( { let local_executor = LocalCallExecutor::new(backend.clone(), code_executor, None); let executor = GenesisCallExecutor::new(backend.clone(), local_executor); - Client::new(backend, executor, genesis_storage, Default::default()) + Client::new(backend, executor, genesis_storage, Default::default(), Default::default()) } /// Create an instance of fetch data checker. diff --git a/core/consensus/babe/src/lib.rs b/core/consensus/babe/src/lib.rs index b495561213..800caf9d2b 100644 --- a/core/consensus/babe/src/lib.rs +++ b/core/consensus/babe/src/lib.rs @@ -89,7 +89,7 @@ use schnorrkel::{ }, }; use consensus_common::{ - self, BlockImport, Environment, Proposer, + self, BlockImport, Environment, Proposer, BlockCheckParams, ForkChoiceStrategy, BlockImportParams, BlockOrigin, Error as ConsensusError, }; use srml_babe::{ @@ -1367,10 +1367,9 @@ impl BlockImport for BabeBlockImport, ) -> Result { - self.inner.check_block(hash, parent_hash).map_err(Into::into) + self.inner.check_block(block).map_err(Into::into) } } diff --git a/core/consensus/babe/src/tests.rs b/core/consensus/babe/src/tests.rs index 70c7738dec..85c3101e5e 100644 --- a/core/consensus/babe/src/tests.rs +++ b/core/consensus/babe/src/tests.rs @@ -30,7 +30,7 @@ use consensus_common::import_queue::{ use network::test::*; use network::test::{Block as TestBlock, PeersClient}; use network::config::BoxFinalityProofRequestBuilder; -use sr_primitives::{generic::DigestItem, traits::{Block as BlockT, DigestFor}}; +use sr_primitives::{generic::DigestItem, traits::{Block as BlockT, DigestFor, NumberFor}}; use network::config::ProtocolConfig; use tokio::runtime::current_thread; use client::BlockchainEvents; @@ -179,10 +179,9 @@ impl> BlockImport for PanickingBlockImport< fn check_block( &mut self, - hash: Hash, - parent_hash: Hash, + block: BlockCheckParams, ) -> Result { - Ok(self.0.check_block(hash, parent_hash).expect("checking block failed")) + Ok(self.0.check_block(block).expect("checking block failed")) } } diff --git a/core/consensus/common/src/block_import.rs b/core/consensus/common/src/block_import.rs index 4024322911..4342ee38df 100644 --- a/core/consensus/common/src/block_import.rs +++ b/core/consensus/common/src/block_import.rs @@ -90,7 +90,17 @@ pub enum ForkChoiceStrategy { Custom(bool), } -/// Data required to import a Block +/// Data required to check validity of a Block. +pub struct BlockCheckParams { + /// Hash of the block that we verify. + pub hash: Block::Hash, + /// Block number of the block that we verify. + pub number: NumberFor, + /// Parent hash of the block that we verify. + pub parent_hash: Block::Hash, +} + +/// Data required to import a Block. pub struct BlockImportParams { /// Origin of the Block pub origin: BlockOrigin, @@ -172,8 +182,7 @@ pub trait BlockImport { /// Check block preconditions. fn check_block( &mut self, - hash: B::Hash, - parent_hash: B::Hash, + block: BlockCheckParams, ) -> Result; /// Import a block. @@ -192,10 +201,9 @@ impl BlockImport for crate::import_queue::BoxBlockImport { /// Check block preconditions. fn check_block( &mut self, - hash: B::Hash, - parent_hash: B::Hash, + block: BlockCheckParams, ) -> Result { - (**self).check_block(hash, parent_hash) + (**self).check_block(block) } /// Import a block. @@ -217,10 +225,9 @@ where for<'r> &'r T: BlockImport fn check_block( &mut self, - hash: B::Hash, - parent_hash: B::Hash, + block: BlockCheckParams, ) -> Result { - (&**self).check_block(hash, parent_hash) + (&**self).check_block(block) } fn import_block( diff --git a/core/consensus/common/src/import_queue.rs b/core/consensus/common/src/import_queue.rs index 07d6297acc..dc1678fcf1 100644 --- a/core/consensus/common/src/import_queue.rs +++ b/core/consensus/common/src/import_queue.rs @@ -30,7 +30,7 @@ use sr_primitives::{Justification, traits::{Block as BlockT, Header as _, Number use crate::error::Error as ConsensusError; use crate::block_import::{ BlockImport, BlockOrigin, BlockImportParams, ImportedAux, JustificationImport, ImportResult, - FinalityProofImport, + BlockCheckParams, FinalityProofImport, }; pub use basic_queue::BasicQueue; @@ -194,7 +194,7 @@ pub fn import_single_block>( let number = header.number().clone(); let hash = header.hash(); - let parent = header.parent_hash().clone(); + let parent_hash = header.parent_hash().clone(); let import_error = |e| { match e { @@ -204,7 +204,7 @@ pub fn import_single_block>( }, Ok(ImportResult::Imported(aux)) => Ok(BlockImportResult::ImportedUnknown(number, aux, peer.clone())), Ok(ImportResult::UnknownParent) => { - debug!(target: "sync", "Block with unknown parent {}: {:?}, parent: {:?}", number, hash, parent); + debug!(target: "sync", "Block with unknown parent {}: {:?}, parent: {:?}", number, hash, parent_hash); Err(BlockImportError::UnknownParent) }, Ok(ImportResult::KnownBad) => { @@ -217,8 +217,7 @@ pub fn import_single_block>( } } }; - - match import_error(import_handle.check_block(hash, parent))? { + match import_error(import_handle.check_block(BlockCheckParams { hash, number, parent_hash }))? { BlockImportResult::ImportedUnknown { .. } => (), r => return Ok(r), // Any other successful result means that the block is already imported. } diff --git a/core/consensus/common/src/lib.rs b/core/consensus/common/src/lib.rs index d0f42d8b33..154ea7bb52 100644 --- a/core/consensus/common/src/lib.rs +++ b/core/consensus/common/src/lib.rs @@ -48,7 +48,7 @@ const MAX_BLOCK_SIZE: usize = 4 * 1024 * 1024 + 512; pub use self::error::Error; pub use block_import::{ - BlockImport, BlockOrigin, ForkChoiceStrategy, ImportedAux, BlockImportParams, ImportResult, + BlockImport, BlockOrigin, ForkChoiceStrategy, ImportedAux, BlockImportParams, BlockCheckParams, ImportResult, JustificationImport, FinalityProofImport, }; pub use select_chain::SelectChain; diff --git a/core/finality-grandpa/src/import.rs b/core/finality-grandpa/src/import.rs index 906b87b87e..758f6f18db 100644 --- a/core/finality-grandpa/src/import.rs +++ b/core/finality-grandpa/src/import.rs @@ -27,7 +27,7 @@ use client::backend::Backend; use client::utils::is_descendent_of; use consensus_common::{ BlockImport, Error as ConsensusError, - BlockImportParams, ImportResult, JustificationImport, + BlockCheckParams, BlockImportParams, ImportResult, JustificationImport, SelectChain, }; use fg_primitives::{GRANDPA_ENGINE_ID, ScheduledChange, ConsensusLog}; @@ -386,9 +386,11 @@ impl, RA, SC> BlockImport { type Error = ConsensusError; - fn import_block(&mut self, mut block: BlockImportParams, new_cache: HashMap>) - -> Result - { + fn import_block( + &mut self, + mut block: BlockImportParams, + new_cache: HashMap>, + ) -> Result { let hash = block.post_header().hash(); let number = block.header.number().clone(); @@ -500,10 +502,9 @@ impl, RA, SC> BlockImport fn check_block( &mut self, - hash: Block::Hash, - parent_hash: Block::Hash, + block: BlockCheckParams, ) -> Result { - self.inner.check_block(hash, parent_hash) + self.inner.check_block(block) } } diff --git a/core/finality-grandpa/src/light_import.rs b/core/finality-grandpa/src/light_import.rs index 053daa81a8..30af3a06d3 100644 --- a/core/finality-grandpa/src/light_import.rs +++ b/core/finality-grandpa/src/light_import.rs @@ -30,7 +30,7 @@ use codec::{Encode, Decode}; use consensus_common::{ import_queue::Verifier, BlockOrigin, BlockImport, FinalityProofImport, BlockImportParams, ImportResult, ImportedAux, - Error as ConsensusError, + BlockCheckParams, Error as ConsensusError, }; use network::config::{BoxFinalityProofRequestBuilder, FinalityProofRequestBuilder}; use sr_primitives::Justification; @@ -142,10 +142,9 @@ impl, RA> BlockImport fn check_block( &mut self, - hash: Block::Hash, - parent_hash: Block::Hash, + block: BlockCheckParams, ) -> Result { - self.client.check_block(hash, parent_hash) + self.client.check_block(block) } } @@ -591,10 +590,9 @@ pub mod tests { fn check_block( &mut self, - hash: Block::Hash, - parent_hash: Block::Hash, + block: BlockCheckParams, ) -> Result { - self.0.check_block(hash, parent_hash) + self.0.check_block(block) } } diff --git a/core/network/src/test/mod.rs b/core/network/src/test/mod.rs index 302ef78d7d..920636810b 100644 --- a/core/network/src/test/mod.rs +++ b/core/network/src/test/mod.rs @@ -44,7 +44,7 @@ use consensus::import_queue::{ }; use consensus::block_import::{BlockImport, ImportResult}; use consensus::Error as ConsensusError; -use consensus::{BlockOrigin, ForkChoiceStrategy, BlockImportParams, JustificationImport}; +use consensus::{BlockOrigin, ForkChoiceStrategy, BlockImportParams, BlockCheckParams, JustificationImport}; use futures::prelude::*; use futures03::{StreamExt as _, TryStreamExt as _}; use crate::{NetworkWorker, NetworkService, config::ProtocolId}; @@ -431,8 +431,11 @@ impl Clone for BlockImportAdapter { impl> BlockImport for BlockImportAdapter { type Error = T::Error; - fn check_block(&mut self, hash: Hash, parent_hash: Hash) -> Result { - self.0.lock().check_block(hash, parent_hash) + fn check_block( + &mut self, + block: BlockCheckParams, + ) -> Result { + self.0.lock().check_block(block) } fn import_block( diff --git a/core/service/Cargo.toml b/core/service/Cargo.toml index 75d49b1f1e..e0982c58ae 100644 --- a/core/service/Cargo.toml +++ b/core/service/Cargo.toml @@ -15,7 +15,7 @@ slog = {version = "^2", features = ["nested-values"]} tokio-executor = "0.1.7" tokio-timer = "0.2" exit-future = "0.1" -serde = { version = "1.0", features = ["derive"] } +serde = { version = "1.0" } serde_json = "1.0" sysinfo = "0.9.0" target_info = "0.1" @@ -27,6 +27,7 @@ session = { package = "substrate-session", path = "../session" } app-crypto = { package = "substrate-application-crypto", path = "../application-crypto" } consensus_common = { package = "substrate-consensus-common", path = "../../core/consensus/common" } network = { package = "substrate-network", path = "../../core/network" } +chain-spec = { package = "substrate-chain-spec", path = "../chain-spec" } client = { package = "substrate-client", path = "../../core/client" } client_db = { package = "substrate-client-db", path = "../../core/client/db", features = ["kvdb-rocksdb"] } codec = { package = "parity-scale-codec", version = "1.0.0" } diff --git a/core/service/src/builder.rs b/core/service/src/builder.rs index aeafe9e82b..3317ab23cd 100644 --- a/core/service/src/builder.rs +++ b/core/service/src/builder.rs @@ -22,6 +22,7 @@ use client::{ BlockchainEvents, Client, runtime_api, backend::RemoteBackend, light::blockchain::RemoteBlockchain, }; +use chain_spec::{RuntimeGenesis, Extension}; use codec::{Decode, Encode, IoReader}; use consensus_common::import_queue::ImportQueue; use futures::{prelude::*, sync::mpsc}; @@ -33,12 +34,11 @@ use network::{config::BoxFinalityProofRequestBuilder, specialization::NetworkSpe use parking_lot::{Mutex, RwLock}; use primitives::{Blake2Hasher, H256, Hasher}; use rpc::{self, system::SystemInfo}; -use sr_primitives::{BuildStorage, generic::BlockId}; +use sr_primitives::generic::BlockId; use sr_primitives::traits::{ Block as BlockT, Extrinsic, ProvideRuntimeApi, NumberFor, One, Zero, Header, SaturatedConversion }; use substrate_executor::{NativeExecutor, NativeExecutionDispatch}; -use serde::{Serialize, de::DeserializeOwned}; use std::{io::{Read, Write, Seek}, marker::PhantomData, sync::Arc, sync::atomic::AtomicBool}; use sysinfo::{get_current_pid, ProcessExt, System, SystemExt}; use tel::{telemetry, SUBSTRATE_INFO}; @@ -62,10 +62,10 @@ use transaction_pool::txpool::{self, ChainApi, Pool as TransactionPool}; /// The order in which the `with_*` methods are called doesn't matter, as the correct binding of /// generics is done when you call `build`. /// -pub struct ServiceBuilder { - config: Configuration, + config: Configuration, client: Arc, backend: Arc, keystore: Arc>, @@ -128,16 +128,17 @@ type TLightCallExecutor = client::light::call_executor::GenesisC >, >; -impl ServiceBuilder<(), (), TCfg, TGen, (), (), (), (), (), (), (), (), (), (), ()> -where TGen: Serialize + DeserializeOwned + BuildStorage { +impl ServiceBuilder<(), (), TCfg, TGen, TCSExt, (), (), (), (), (), (), (), (), (), (), ()> +where TGen: RuntimeGenesis, TCSExt: Extension { /// Start the service builder with a configuration. pub fn new_full, TRtApi, TExecDisp: NativeExecutionDispatch>( - config: Configuration + config: Configuration ) -> Result, Arc>, (), @@ -163,10 +164,17 @@ where TGen: Serialize + DeserializeOwned + BuildStorage { let executor = NativeExecutor::::new(config.default_heap_pages); + let fork_blocks = config.chain_spec + .extensions() + .get::>() + .cloned() + .unwrap_or_default(); + let (client, backend) = client_db::new_client( db_settings, executor, &config.chain_spec, + fork_blocks, config.execution_strategies.clone(), Some(keystore.clone()), )?; @@ -196,12 +204,13 @@ where TGen: Serialize + DeserializeOwned + BuildStorage { /// Start the service builder with a configuration. pub fn new_light, TRtApi, TExecDisp: NativeExecutionDispatch + 'static>( - config: Configuration + config: Configuration ) -> Result, Arc>, (), @@ -264,8 +273,8 @@ where TGen: Serialize + DeserializeOwned + BuildStorage { } } -impl - ServiceBuilder + ServiceBuilder { /// Returns a reference to the client that was stored in this builder. @@ -286,8 +295,10 @@ impl( self, - select_chain_builder: impl FnOnce(&Configuration, &Arc) -> Result, Error> - ) -> Result, &Arc + ) -> Result, Error> + ) -> Result, Error> { let select_chain = select_chain_builder(&self.config, &self.backend)?; @@ -313,8 +324,8 @@ impl( self, - builder: impl FnOnce(&Configuration, &Arc) -> Result - ) -> Result, &Arc) -> Result + ) -> Result, Error> { self.with_opt_select_chain(|cfg, b| builder(cfg, b).map(Option::Some)) } @@ -322,9 +333,9 @@ impl( self, - builder: impl FnOnce(&Configuration, Arc, Option, Arc) + builder: impl FnOnce(&Configuration, Arc, Option, Arc) -> Result - ) -> Result Result, Error> where TSc: Clone { let import_queue = builder( @@ -356,8 +367,8 @@ impl( self, - network_protocol_builder: impl FnOnce(&Configuration) -> Result - ) -> Result) -> Result + ) -> Result, Error> { let network_protocol = network_protocol_builder(&self.config)?; @@ -389,6 +400,7 @@ impl( self, builder: impl FnOnce( - &Configuration, + &Configuration, Arc, Arc, Option, Option, Arc, ) -> Result<(UImpQu, Option), Error> - ) -> Result Result, Error> where TSc: Clone, TFchr: Clone { let (import_queue, fprb) = builder( @@ -492,14 +505,14 @@ impl( self, builder: impl FnOnce( - &Configuration, + &Configuration, Arc, Arc, Option, Option, Arc, ) -> Result<(UImpQu, UFprb), Error> - ) -> Result Result, Error> where TSc: Clone, TFchr: Clone { self.with_import_queue_and_opt_fprb(|cfg, cl, b, f, sc, tx| @@ -512,7 +525,7 @@ impl( self, transaction_pool_builder: impl FnOnce(transaction_pool::txpool::Options, Arc) -> Result - ) -> Result Result, Error> { let transaction_pool = transaction_pool_builder(self.config.transaction_pool.clone(), self.client.clone())?; @@ -539,7 +552,7 @@ impl( self, rpc_ext_builder: impl FnOnce(Arc, Arc) -> URpc - ) -> Result Result, Error> { let rpc_extensions = rpc_ext_builder(self.client.clone(), self.transaction_pool.clone()); @@ -567,7 +580,7 @@ impl, - ) -> Result Result, Error> { Ok(ServiceBuilder { config: self.config, @@ -708,10 +721,14 @@ pub trait ServiceBuilderRevert { ) -> Result<(), Error>; } -impl - ServiceBuilderImport for ServiceBuilder, - TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB, Backend> -where +impl< + TBl, TRtApi, TCfg, TGen, TCSExt, TBackend, + TExec, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, + TExPool, TRpc, TRpcB, Backend +> ServiceBuilderImport for ServiceBuilder< + TBl, TRtApi, TCfg, TGen, TCSExt, Client, + TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB, Backend +> where TBl: BlockT::Out>, TBackend: 'static + client::backend::Backend + Send, TExec: 'static + client::CallExecutor + Send + Sync + Clone, @@ -730,8 +747,8 @@ where } } -impl - ServiceBuilderExport for ServiceBuilder, +impl + ServiceBuilderExport for ServiceBuilder, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB, TBackend> where TBl: BlockT::Out>, @@ -753,8 +770,8 @@ where } } -impl - ServiceBuilderRevert for ServiceBuilder, +impl + ServiceBuilderRevert for ServiceBuilder, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB, TBackend> where TBl: BlockT::Out>, @@ -772,12 +789,13 @@ where } } -impl +impl ServiceBuilder< TBl, TRtApi, TCfg, TGen, + TCSExt, Client, Arc>, TSc, @@ -799,7 +817,8 @@ ServiceBuilder< TBl: BlockT::Out>, TRtApi: 'static + Send + Sync, TCfg: Default, - TGen: Serialize + DeserializeOwned + BuildStorage, + TGen: RuntimeGenesis, + TCSExt: Extension, TBackend: 'static + client::backend::Backend + Send, TExec: 'static + client::CallExecutor + Send + Sync + Clone, TSc: Clone, diff --git a/core/service/src/chain_ops.rs b/core/service/src/chain_ops.rs index 06390e80bd..f82dac1913 100644 --- a/core/service/src/chain_ops.rs +++ b/core/service/src/chain_ops.rs @@ -16,9 +16,8 @@ //! Chain utilities. -use crate::RuntimeGenesis; use crate::error; -use crate::chain_spec::ChainSpec; +use chain_spec::{ChainSpec, RuntimeGenesis, Extension}; /// Defines the logic for an operation exporting blocks within a range. #[macro_export] @@ -222,8 +221,9 @@ macro_rules! revert_chain { } /// Build a chain spec json -pub fn build_spec(spec: ChainSpec, raw: bool) -> error::Result - where G: RuntimeGenesis, +pub fn build_spec(spec: ChainSpec, raw: bool) -> error::Result where + G: RuntimeGenesis, + E: Extension, { Ok(spec.to_json(raw)?) } diff --git a/core/service/src/config.rs b/core/service/src/config.rs index 97eba357e3..c4690e53f7 100644 --- a/core/service/src/config.rs +++ b/core/service/src/config.rs @@ -22,16 +22,14 @@ pub use network::config::{ExtTransport, NetworkConfiguration, Roles}; use std::{path::PathBuf, net::SocketAddr}; use transaction_pool; -use crate::chain_spec::ChainSpec; +use chain_spec::{ChainSpec, RuntimeGenesis, Extension, NoExtension}; use primitives::crypto::Protected; -use sr_primitives::BuildStorage; -use serde::{Serialize, de::DeserializeOwned}; use target_info::Target; use tel::TelemetryEndpoints; /// Service configuration. #[derive(Clone)] -pub struct Configuration { +pub struct Configuration { /// Implementation name pub impl_name: &'static str, /// Implementation version @@ -57,7 +55,7 @@ pub struct Configuration { /// Pruning settings. pub pruning: PruningMode, /// Chain configuration. - pub chain_spec: ChainSpec, + pub chain_spec: ChainSpec, /// Custom configuration. pub custom: C, /// Node name. @@ -95,9 +93,13 @@ pub struct Configuration { pub dev_key_seed: Option, } -impl Configuration { +impl Configuration where + C: Default, + G: RuntimeGenesis, + E: Extension, +{ /// Create default config for given chain spec. - pub fn default_with_spec(chain_spec: ChainSpec) -> Self { + pub fn default_with_spec(chain_spec: ChainSpec) -> Self { let mut configuration = Configuration { impl_name: "parity-substrate", impl_version: "0.0.0", diff --git a/core/service/src/lib.rs b/core/service/src/lib.rs index cf84df3ef6..72ee2d8511 100644 --- a/core/service/src/lib.rs +++ b/core/service/src/lib.rs @@ -19,7 +19,6 @@ #![warn(missing_docs)] -mod chain_spec; pub mod config; #[macro_use] pub mod chain_ops; @@ -31,7 +30,6 @@ use std::net::SocketAddr; use std::collections::HashMap; use std::sync::atomic::{AtomicBool, Ordering}; use std::time::{Duration, Instant}; -use serde::{Serialize, de::DeserializeOwned}; use futures::sync::mpsc; use parking_lot::Mutex; @@ -43,14 +41,13 @@ use network::{NetworkService, NetworkState, specialization::NetworkSpecializatio use log::{log, warn, debug, error, Level}; use codec::{Encode, Decode}; use primitives::{Blake2Hasher, H256}; -use sr_primitives::BuildStorage; use sr_primitives::generic::BlockId; use sr_primitives::traits::NumberFor; pub use self::error::Error; pub use self::builder::{ServiceBuilder, ServiceBuilderExport, ServiceBuilderImport, ServiceBuilderRevert}; pub use config::{Configuration, Roles, PruningMode}; -pub use chain_spec::{ChainSpec, Properties}; +pub use chain_spec::{ChainSpec, Properties, RuntimeGenesis, Extension as ChainSpecExtension}; pub use transaction_pool::txpool::{ self, Pool as TransactionPool, Options as TransactionPoolOptions, ChainApi, IntoPoolError }; @@ -100,10 +97,6 @@ pub struct NewService { marker: PhantomData, } -/// A set of traits for the runtime genesis config. -pub trait RuntimeGenesis: Serialize + DeserializeOwned + BuildStorage {} -impl RuntimeGenesis for T {} - /// Alias for a an implementation of `futures::future::Executor`. pub type TaskExecutor = Arc + Send>> + Send + Sync>; @@ -349,7 +342,7 @@ macro_rules! new_impl { chain_name: $config.chain_spec.name().into(), impl_name: $config.impl_name.into(), impl_version: $config.impl_version.into(), - properties: $config.chain_spec.properties(), + properties: $config.chain_spec.properties().clone(), }; $start_rpc( client.clone(), @@ -805,8 +798,8 @@ impl Drop for /// Starts RPC servers that run in their own thread, and returns an opaque object that keeps them alive. #[cfg(not(target_os = "unknown"))] -fn start_rpc_servers rpc_servers::RpcHandler>( - config: &Configuration, +fn start_rpc_servers rpc_servers::RpcHandler>( + config: &Configuration, mut gen_handler: H ) -> Result, error::Error> { fn maybe_start_server(address: Option, mut start: F) -> Result, io::Error> @@ -846,8 +839,8 @@ fn start_rpc_servers rpc_servers::RpcHandler> /// Starts RPC servers that run in their own thread, and returns an opaque object that keeps them alive. #[cfg(target_os = "unknown")] -fn start_rpc_servers components::RpcHandler>( - _: &Configuration, +fn start_rpc_servers components::RpcHandler>( + _: &Configuration, _: H ) -> Result, error::Error> { Ok(Box::new(())) @@ -888,7 +881,7 @@ fn transactions_to_propagate(pool: &TransactionPool) where PoolApi: ChainApi, B: BlockT, - H: std::hash::Hash + Eq + sr_primitives::traits::Member + serde::Serialize, + H: std::hash::Hash + Eq + sr_primitives::traits::Member + sr_primitives::traits::MaybeSerialize, E: txpool::error::IntoPoolError + From, { pool.ready() @@ -907,7 +900,7 @@ where C: network::ClientHandle + Send + Sync, PoolApi: ChainApi, B: BlockT, - H: std::hash::Hash + Eq + sr_primitives::traits::Member + serde::Serialize, + H: std::hash::Hash + Eq + sr_primitives::traits::Member + sr_primitives::traits::MaybeSerialize, E: txpool::error::IntoPoolError + From, { fn transactions(&self) -> Vec<(H, ::Extrinsic)> { diff --git a/core/service/test/src/lib.rs b/core/service/test/src/lib.rs index 6e096ec35c..0540210b40 100644 --- a/core/service/test/src/lib.rs +++ b/core/service/test/src/lib.rs @@ -39,12 +39,12 @@ use sr_primitives::{generic::BlockId, traits::Block as BlockT}; /// Maximum duration of single wait call. const MAX_WAIT_TIME: Duration = Duration::from_secs(60 * 3); -struct TestNet { +struct TestNet { runtime: Runtime, authority_nodes: Vec<(usize, SyncService, U, Multiaddr)>, full_nodes: Vec<(usize, SyncService, U, Multiaddr)>, light_nodes: Vec<(usize, SyncService, Multiaddr)>, - chain_spec: ChainSpec, + chain_spec: ChainSpec, base_port: u16, nodes: usize, } @@ -79,7 +79,7 @@ impl> Future for SyncService { } } -impl TestNet +impl TestNet where F: Send + 'static, L: Send +'static, U: Clone + Send + 'static { pub fn run_until_all_full( @@ -124,14 +124,14 @@ where F: Send + 'static, L: Send +'static, U: Clone + Send + 'static } } -fn node_config ( +fn node_config ( index: usize, - spec: &ChainSpec, + spec: &ChainSpec, role: Roles, key_seed: Option, base_port: u16, root: &TempDir, -) -> Configuration<(), G> +) -> Configuration<(), G, E> { let root = root.path().join(format!("node-{}", index)); @@ -193,18 +193,22 @@ fn node_config ( } } -impl TestNet where +impl TestNet where F: AbstractService, L: AbstractService, + E: Clone, { fn new( temp: &TempDir, - spec: ChainSpec, - full: impl Iterator) -> Result<(F, U), Error>>, - light: impl Iterator) -> Result>, - authorities: impl Iterator) -> Result<(F, U), Error>)>, + spec: ChainSpec, + full: impl Iterator) -> Result<(F, U), Error>>, + light: impl Iterator) -> Result>, + authorities: impl Iterator) -> Result<(F, U), Error> + )>, base_port: u16 - ) -> TestNet { + ) -> TestNet { let _ = env_logger::try_init(); fdlimit::raise_fd_limit(); let runtime = Runtime::new().expect("Error creating tokio runtime"); @@ -224,9 +228,9 @@ impl TestNet where fn insert_nodes( &mut self, temp: &TempDir, - full: impl Iterator) -> Result<(F, U), Error>>, - light: impl Iterator) -> Result>, - authorities: impl Iterator) -> Result<(F, U), Error>)> + full: impl Iterator) -> Result<(F, U), Error>>, + light: impl Iterator) -> Result>, + authorities: impl Iterator) -> Result<(F, U), Error>)> ) { let executor = self.runtime.executor(); @@ -274,16 +278,17 @@ impl TestNet where } } -pub fn connectivity( - spec: ChainSpec, +pub fn connectivity( + spec: ChainSpec, full_builder: Fb, light_builder: Lb, light_node_interconnectivity: bool, // should normally be false, unless the light nodes // aren't actually light. ) where - Fb: Fn(Configuration<(), G>) -> Result, + E: Clone, + Fb: Fn(Configuration<(), G, E>) -> Result, F: AbstractService, - Lb: Fn(Configuration<(), G>) -> Result, + Lb: Fn(Configuration<(), G, E>) -> Result, L: AbstractService, { const NUM_FULL_NODES: usize = 5; @@ -377,20 +382,21 @@ pub fn connectivity( } } -pub fn sync( - spec: ChainSpec, +pub fn sync( + spec: ChainSpec, full_builder: Fb, light_builder: Lb, mut make_block_and_import: B, - mut extrinsic_factory: E + mut extrinsic_factory: ExF ) where - Fb: Fn(Configuration<(), G>) -> Result<(F, U), Error>, + Fb: Fn(Configuration<(), G, E>) -> Result<(F, U), Error>, F: AbstractService, - Lb: Fn(Configuration<(), G>) -> Result, + Lb: Fn(Configuration<(), G, E>) -> Result, L: AbstractService, B: FnMut(&F, &mut U), - E: FnMut(&F, &U) -> ::Extrinsic, + ExF: FnMut(&F, &U) -> ::Extrinsic, U: Clone + Send + 'static, + E: Clone, { const NUM_FULL_NODES: usize = 10; // FIXME: BABE light client support is currently not working. @@ -446,16 +452,17 @@ pub fn sync( ); } -pub fn consensus( - spec: ChainSpec, +pub fn consensus( + spec: ChainSpec, full_builder: Fb, light_builder: Lb, authorities: impl IntoIterator ) where - Fb: Fn(Configuration<(), G>) -> Result, + Fb: Fn(Configuration<(), G, E>) -> Result, F: AbstractService, - Lb: Fn(Configuration<(), G>) -> Result, + Lb: Fn(Configuration<(), G, E>) -> Result, L: AbstractService, + E: Clone, { const NUM_FULL_NODES: usize = 10; const NUM_LIGHT_NODES: usize = 10; diff --git a/core/telemetry/src/lib.rs b/core/telemetry/src/lib.rs index 71a86defb6..768fc2df84 100644 --- a/core/telemetry/src/lib.rs +++ b/core/telemetry/src/lib.rs @@ -92,7 +92,7 @@ pub struct TelemetryConfig { /// maximum verbosity level. /// /// The URL string can be either a URL or a multiaddress. -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct TelemetryEndpoints(Vec<(String, u8)>); impl TelemetryEndpoints { diff --git a/core/test-client/src/lib.rs b/core/test-client/src/lib.rs index 3ce5bec4fb..a2baf11be2 100644 --- a/core/test-client/src/lib.rs +++ b/core/test-client/src/lib.rs @@ -187,6 +187,7 @@ impl TestClientBuilder self.backend.clone(), executor, storage, + Default::default(), self.execution_strategies, ).expect("Creates new client"); diff --git a/node-template/src/cli.rs b/node-template/src/cli.rs index f6edbb2cc3..6a0b0dd706 100644 --- a/node-template/src/cli.rs +++ b/node-template/src/cli.rs @@ -4,7 +4,7 @@ use std::cell::RefCell; use tokio::runtime::Runtime; pub use substrate_cli::{VersionInfo, IntoExit, error}; use substrate_cli::{informant, parse_and_prepare, ParseAndPrepare, NoCustom}; -use substrate_service::{AbstractService, Roles as ServiceRoles}; +use substrate_service::{AbstractService, Roles as ServiceRoles, Configuration}; use crate::chain_spec; use log::info; @@ -14,9 +14,10 @@ pub fn run(args: I, exit: E, version: VersionInfo) -> error::Result<()> T: Into + Clone, E: IntoExit, { + type Config = Configuration<(), T>; match parse_and_prepare::(&version, "substrate-node", args) { - ParseAndPrepare::Run(cmd) => cmd.run::<(), _, _, _, _>(load_spec, exit, - |exit, _cli_args, _custom_args, config| { + ParseAndPrepare::Run(cmd) => cmd.run(load_spec, exit, + |exit, _cli_args, _custom_args, config: Config<_>| { info!("{}", version.name); info!(" version {}", config.full_version()); info!(" by {}, 2017, 2018", version.author); @@ -38,12 +39,12 @@ pub fn run(args: I, exit: E, version: VersionInfo) -> error::Result<()> }.map_err(|e| format!("{:?}", e)) }), ParseAndPrepare::BuildSpec(cmd) => cmd.run(load_spec), - ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder::<(), _, _, _, _, _>(|config| + ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder(|config: Config<_>| Ok(new_full_start!(config).0), load_spec, exit), - ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder::<(), _, _, _, _, _>(|config| + ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder(|config: Config<_>| Ok(new_full_start!(config).0), load_spec, exit), ParseAndPrepare::PurgeChain(cmd) => cmd.run(load_spec), - ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder::<(), _, _, _, _>(|config| + ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder(|config: Config<_>| Ok(new_full_start!(config).0), load_spec), ParseAndPrepare::CustomCommand(_) => Ok(()) }?; diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index 39ebcb321d..86c7200560 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -25,6 +25,7 @@ hex-literal = "0.2" substrate-rpc = { package = "substrate-rpc", path = "../../core/rpc" } substrate-basic-authorship = { path = "../../core/basic-authorship" } substrate-service = { path = "../../core/service" } +chain-spec = { package = "substrate-chain-spec", path = "../../core/chain-spec" } transaction_pool = { package = "substrate-transaction-pool", path = "../../core/transaction-pool" } network = { package = "substrate-network", path = "../../core/network" } babe = { package = "substrate-consensus-babe", path = "../../core/consensus/babe" } @@ -48,10 +49,10 @@ support = { package = "srml-support", path = "../../srml/support", default-featu im_online = { package = "srml-im-online", path = "../../srml/im-online", default-features = false } sr-authority-discovery = { package = "srml-authority-discovery", path = "../../srml/authority-discovery", default-features = false } authority-discovery = { package = "substrate-authority-discovery", path = "../../core/authority-discovery"} +serde = { version = "1.0", features = [ "derive" ] } client_db = { package = "substrate-client-db", path = "../../core/client/db", features = ["kvdb-rocksdb"] } offchain = { package = "substrate-offchain", path = "../../core/offchain" } - [dev-dependencies] keystore = { package = "substrate-keystore", path = "../../core/keystore" } babe = { package = "substrate-consensus-babe", path = "../../core/consensus/babe", features = ["test-helpers"] } diff --git a/node/cli/src/chain_spec.rs b/node/cli/src/chain_spec.rs index 47de737614..905e867436 100644 --- a/node/cli/src/chain_spec.rs +++ b/node/cli/src/chain_spec.rs @@ -16,15 +16,16 @@ //! Substrate chain configurations. +use chain_spec::ChainSpecExtension; use primitives::{Pair, Public, crypto::UncheckedInto}; -pub use node_primitives::{AccountId, Balance}; +use serde::{Serialize, Deserialize}; use node_runtime::{ AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig, DemocracyConfig, ElectionsConfig, GrandpaConfig, ImOnlineConfig, IndicesConfig, SessionConfig, SessionKeys, StakerStatus, StakingConfig, SudoConfig, SystemConfig, TechnicalCommitteeConfig, WASM_BINARY, }; +use node_runtime::Block; use node_runtime::constants::{time::*, currency::*}; -pub use node_runtime::GenesisConfig; use substrate_service; use hex_literal::hex; use substrate_telemetry::TelemetryEndpoints; @@ -33,11 +34,26 @@ use babe_primitives::{AuthorityId as BabeId}; use im_online::sr25519::{AuthorityId as ImOnlineId}; use sr_primitives::Perbill; +pub use node_primitives::{AccountId, Balance}; +pub use node_runtime::GenesisConfig; + const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; -/// Specialized `ChainSpec`. -pub type ChainSpec = substrate_service::ChainSpec; +/// Node `ChainSpec` extensions. +/// +/// Additional parameters for some Substrate core modules, +/// customizable from the chain spec. +#[derive(Default, Clone, Serialize, Deserialize, ChainSpecExtension)] +pub struct Extensions { + /// Block numbers with known hashes. + pub fork_blocks: client::ForkBlocks, +} +/// Specialized `ChainSpec`. +pub type ChainSpec = substrate_service::ChainSpec< + GenesisConfig, + Extensions, +>; /// Flaming Fir testnet generator pub fn flaming_fir_config() -> Result { ChainSpec::from_json_bytes(&include_bytes!("../res/flaming-fir.json")[..]) @@ -191,7 +207,7 @@ pub fn staging_testnet_config() -> ChainSpec { Some(TelemetryEndpoints::new(vec![(STAGING_TELEMETRY_URL.to_string(), 0)])), None, None, - None, + Default::default(), ) } @@ -327,7 +343,16 @@ fn development_config_genesis() -> GenesisConfig { /// Development config (single validator Alice) pub fn development_config() -> ChainSpec { - ChainSpec::from_genesis("Development", "dev", development_config_genesis, vec![], None, None, None, None) + ChainSpec::from_genesis( + "Development", + "dev", + development_config_genesis, + vec![], + None, + None, + None, + Default::default(), + ) } fn local_testnet_genesis() -> GenesisConfig { @@ -344,7 +369,16 @@ fn local_testnet_genesis() -> GenesisConfig { /// Local testnet config (multivalidator Alice + Bob) pub fn local_testnet_config() -> ChainSpec { - ChainSpec::from_genesis("Local Testnet", "local_testnet", local_testnet_genesis, vec![], None, None, None, None) + ChainSpec::from_genesis( + "Local Testnet", + "local_testnet", + local_testnet_genesis, + vec![], + None, + None, + None, + Default::default(), + ) } #[cfg(test)] @@ -375,7 +409,7 @@ pub(crate) mod tests { None, None, None, - None, + Default::default(), ) } @@ -389,7 +423,7 @@ pub(crate) mod tests { None, None, None, - None, + Default::default(), ) } diff --git a/node/cli/src/lib.rs b/node/cli/src/lib.rs index b7679be176..a4deed37c1 100644 --- a/node/cli/src/lib.rs +++ b/node/cli/src/lib.rs @@ -28,7 +28,7 @@ mod factory_impl; use tokio::prelude::Future; use tokio::runtime::{Builder as RuntimeBuilder, Runtime}; pub use cli::{VersionInfo, IntoExit, NoCustom, SharedParams, ExecutionStrategyParam}; -use substrate_service::{AbstractService, Roles as ServiceRoles}; +use substrate_service::{AbstractService, Roles as ServiceRoles, Configuration}; use log::info; use structopt::{StructOpt, clap::App}; use cli::{AugmentClap, GetLogFilter, parse_and_prepare, ParseAndPrepare}; @@ -158,9 +158,11 @@ pub fn run(args: I, exit: E, version: cli::VersionInfo) -> error::Resul T: Into + Clone, E: IntoExit, { + type Config = Configuration<(), A, B>; + match parse_and_prepare::(&version, "substrate-node", args) { - ParseAndPrepare::Run(cmd) => cmd.run::<(), _, _, _, _>(load_spec, exit, - |exit, _cli_args, _custom_args, config| { + ParseAndPrepare::Run(cmd) => cmd.run(load_spec, exit, + |exit, _cli_args, _custom_args, config: Config<_, _>| { info!("{}", version.name); info!(" version {}", config.full_version()); info!(" by Parity Technologies, 2017-2019"); @@ -183,15 +185,15 @@ pub fn run(args: I, exit: E, version: cli::VersionInfo) -> error::Resul }.map_err(|e| format!("{:?}", e)) }), ParseAndPrepare::BuildSpec(cmd) => cmd.run(load_spec), - ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder::<(), _, _, _, _, _>(|config| + ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder(|config: Config<_, _>| Ok(new_full_start!(config).0), load_spec, exit), - ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder::<(), _, _, _, _, _>(|config| + ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder(|config: Config<_, _>| Ok(new_full_start!(config).0), load_spec, exit), ParseAndPrepare::PurgeChain(cmd) => cmd.run(load_spec), - ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder::<(), _, _, _, _>(|config| + ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder(|config: Config<_, _>| Ok(new_full_start!(config).0), load_spec), ParseAndPrepare::CustomCommand(CustomSubcommands::Factory(cli_args)) => { - let mut config = cli::create_config_with_db_path::<(), _, _>( + let mut config: Config<_, _> = cli::create_config_with_db_path( load_spec, &cli_args.shared_params, &version, diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index 4a5f7eab86..5b22a058de 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -239,8 +239,11 @@ type ConcreteClient = #[allow(dead_code)] type ConcreteBackend = Backend; +/// A specialized configuration object for setting up the node.. +pub type NodeConfiguration = Configuration; + /// Builds a new service for a full client. -pub fn new_full(config: Configuration) +pub fn new_full(config: NodeConfiguration) -> Result< NewService< ConcreteBlock, @@ -262,7 +265,7 @@ pub fn new_full(config: Configuration(config: Configuration) +pub fn new_light(config: NodeConfiguration) -> Result { type RpcExtension = jsonrpc_core::IoHandler; let inherent_data_providers = InherentDataProviders::new(); diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 337e1ac358..627f4b6731 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -85,7 +85,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 165, - impl_version: 166, + impl_version: 167, apis: RUNTIME_API_VERSIONS, }; diff --git a/test-utils/chain-spec-builder/src/main.rs b/test-utils/chain-spec-builder/src/main.rs index 13b4cc38a1..8f59c73493 100644 --- a/test-utils/chain-spec-builder/src/main.rs +++ b/test-utils/chain-spec-builder/src/main.rs @@ -38,7 +38,7 @@ fn generate_chain_spec() -> String { None, None, None, - None, + Default::default(), ); build_spec(chain_spec, false).unwrap() } -- GitLab From e84f6158b383880ba5fc86cb62c9fea10f5f3071 Mon Sep 17 00:00:00 2001 From: Xiliang Chen Date: Sun, 29 Sep 2019 06:07:21 +1300 Subject: [PATCH 156/275] refactor contracts to use Time trait (#3717) * refactor contracts to use Time trait * bump version --- node/runtime/src/lib.rs | 1 + srml/contracts/Cargo.toml | 3 +-- srml/contracts/src/exec.rs | 13 ++++++------- srml/contracts/src/lib.rs | 6 +++--- srml/contracts/src/tests.rs | 2 ++ 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 627f4b6731..a8999576a7 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -391,6 +391,7 @@ parameter_types! { impl contracts::Trait for Runtime { type Currency = Balances; + type Time = Timestamp; type Call = Call; type Event = Event; type DetermineContractAddress = contracts::SimpleAddressDeterminator; diff --git a/srml/contracts/Cargo.toml b/srml/contracts/Cargo.toml index de6ee96197..646dcd8b5b 100644 --- a/srml/contracts/Cargo.toml +++ b/srml/contracts/Cargo.toml @@ -17,13 +17,13 @@ rstd = { package = "sr-std", path = "../../core/sr-std", default-features = fals sandbox = { package = "sr-sandbox", path = "../../core/sr-sandbox", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } -timestamp = { package = "srml-timestamp", path = "../timestamp", default-features = false } [dev-dependencies] wabt = "~0.7.4" assert_matches = "1.1" hex-literal = "0.2.0" balances = { package = "srml-balances", path = "../balances" } +timestamp = { package = "srml-timestamp", path = "../timestamp" } hex = "0.3" [features] @@ -38,7 +38,6 @@ std = [ "sandbox/std", "support/std", "system/std", - "timestamp/std", "parity-wasm/std", "pwasm-utils/std", "wasmi-validation/std", diff --git a/srml/contracts/src/exec.rs b/srml/contracts/src/exec.rs index 65fe89ed34..94343c5fb9 100644 --- a/srml/contracts/src/exec.rs +++ b/srml/contracts/src/exec.rs @@ -22,12 +22,11 @@ use crate::rent; use rstd::prelude::*; use sr_primitives::traits::{Bounded, CheckedAdd, CheckedSub, Zero}; -use support::traits::{WithdrawReason, Currency}; -use timestamp; +use support::traits::{WithdrawReason, Currency, Time}; pub type AccountIdOf = ::AccountId; pub type CallOf = ::Call; -pub type MomentOf = ::Moment; +pub type MomentOf = <::Time as Time>::Moment; pub type SeedOf = ::Hash; pub type BlockNumberOf = ::BlockNumber; @@ -271,7 +270,7 @@ pub struct ExecutionContext<'a, T: Trait + 'a, V, L> { pub config: &'a Config, pub vm: &'a V, pub loader: &'a L, - pub timestamp: T::Moment, + pub timestamp: MomentOf, pub block_number: T::BlockNumber, } @@ -296,7 +295,7 @@ where config: &cfg, vm: &vm, loader: &loader, - timestamp: >::now(), + timestamp: T::Time::now(), block_number: >::block_number(), } } @@ -665,7 +664,7 @@ struct CallContext<'a, 'b: 'a, T: Trait + 'b, V: Vm + 'b, L: Loader> { ctx: &'a mut ExecutionContext<'b, T, V, L>, caller: T::AccountId, value_transferred: BalanceOf, - timestamp: T::Moment, + timestamp: MomentOf, block_number: T::BlockNumber, } @@ -757,7 +756,7 @@ where system::Module::::random(subject) } - fn now(&self) -> &T::Moment { + fn now(&self) -> &MomentOf { &self.timestamp } diff --git a/srml/contracts/src/lib.rs b/srml/contracts/src/lib.rs index 8343f39bc7..918d0838c4 100644 --- a/srml/contracts/src/lib.rs +++ b/srml/contracts/src/lib.rs @@ -124,10 +124,9 @@ use support::{ Parameter, decl_module, decl_event, decl_storage, storage::child, parameter_types, }; -use support::{traits::{OnFreeBalanceZero, OnUnbalanced, Currency, Get}, IsSubType}; +use support::{traits::{OnFreeBalanceZero, OnUnbalanced, Currency, Get, Time}, IsSubType}; use system::{ensure_signed, RawOrigin, ensure_root}; use primitives::storage::well_known_keys::CHILD_STORAGE_KEY_PREFIX; -use timestamp; pub type CodeHash = ::Hash; pub type TrieId = Vec; @@ -333,8 +332,9 @@ parameter_types! { pub const DefaultBlockGasLimit: u32 = 10_000_000; } -pub trait Trait: timestamp::Trait { +pub trait Trait: system::Trait { type Currency: Currency; + type Time: Time; /// The outer call dispatch type. type Call: Parameter + Dispatchable::Origin> + IsSubType, Self>; diff --git a/srml/contracts/src/tests.rs b/srml/contracts/src/tests.rs index 2dfdce33eb..f2ef8a275d 100644 --- a/srml/contracts/src/tests.rs +++ b/srml/contracts/src/tests.rs @@ -161,6 +161,7 @@ parameter_types! { } impl Trait for Test { type Currency = Balances; + type Time = Timestamp; type Call = Call; type DetermineContractAddress = DummyContractAddressFor; type Event = MetaEvent; @@ -186,6 +187,7 @@ impl Trait for Test { } type Balances = balances::Module; +type Timestamp = timestamp::Module; type Contract = Module; type System = system::Module; -- GitLab From 4af0fe7c37203a32bc6fab3c6372dc1b085382b6 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 30 Sep 2019 16:51:28 +0200 Subject: [PATCH 157/275] core/sr-api-macros/Cargo.toml: Pin protobuf version (#3723) * Cargo.toml: Pin protobuf version The protobuf crate introduced a breaking change within its semver minor update from 2.8.1 to 2.9.0. This commit ensures Substrate uses anything within the 2.8 minor releases. * Cargo.lock: Update * core/sr-api-macros/Cargo.toml: Pin protobuf version The protobuf crate introduced a breaking change within its semver minor update from 2.8.1 to 2.9.0. This commit ensures Substrate uses anything within the 2.8 minor releases. * Revert "Cargo.toml: Pin protobuf version" This reverts commit 4e293c741c5c4510cb1a347c444d1876d65ddb1e. * core/sr-api-macros/Cargo.toml: Pin protobuf within dev-dependencies * core/sr-api-macros/Cargo.toml: Add comment and link to Githu issue --- Cargo.lock | 1 + core/sr-api-macros/Cargo.toml | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 0787d7faec..f3a76716ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3830,6 +3830,7 @@ dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "rustversion 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", diff --git a/core/sr-api-macros/Cargo.toml b/core/sr-api-macros/Cargo.toml index c025ad800e..1bfa920a0c 100644 --- a/core/sr-api-macros/Cargo.toml +++ b/core/sr-api-macros/Cargo.toml @@ -26,6 +26,11 @@ consensus_common = { package = "substrate-consensus-common", path = "../consensu codec = { package = "parity-scale-codec", version = "1.0.0" } trybuild = "1.0" rustversion = "0.1" +# The protobuf crate introduced a breaking change within its semver minor update +# from 2.8.1 to 2.9.0. The dependency bound below ensures sr-api-macros uses +# anything within the 2.8 minor releases. Remove once +# https://github.com/stepancheg/rust-protobuf/issues/453 is resolved. +protobuf = "~2.8.0" [[bench]] name = "bench" -- GitLab From 111def9e2e144e93546059f6adb1c6d6de92a0b0 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Mon, 30 Sep 2019 18:02:54 +0200 Subject: [PATCH 158/275] Revert "core/sr-api-macros/Cargo.toml: Pin protobuf version (#3723)" (#3726) This reverts commit 4af0fe7c37203a32bc6fab3c6372dc1b085382b6. --- Cargo.lock | 1 - core/sr-api-macros/Cargo.toml | 5 ----- 2 files changed, 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f3a76716ae..0787d7faec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3830,7 +3830,6 @@ dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "rustversion 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", diff --git a/core/sr-api-macros/Cargo.toml b/core/sr-api-macros/Cargo.toml index 1bfa920a0c..c025ad800e 100644 --- a/core/sr-api-macros/Cargo.toml +++ b/core/sr-api-macros/Cargo.toml @@ -26,11 +26,6 @@ consensus_common = { package = "substrate-consensus-common", path = "../consensu codec = { package = "parity-scale-codec", version = "1.0.0" } trybuild = "1.0" rustversion = "0.1" -# The protobuf crate introduced a breaking change within its semver minor update -# from 2.8.1 to 2.9.0. The dependency bound below ensures sr-api-macros uses -# anything within the 2.8 minor releases. Remove once -# https://github.com/stepancheg/rust-protobuf/issues/453 is resolved. -protobuf = "~2.8.0" [[bench]] name = "bench" -- GitLab From 9d3a3cfac12b37f1d7434e00c65dba84ae88b278 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 30 Sep 2019 18:03:13 +0200 Subject: [PATCH 159/275] Give more information why conversion between native and runtime failed (#3720) * Give more information why conversion between native and runtime failed This adds the SCALE error description to the error when the conversion between native and runtime failed. * Fixes tests --- core/client/src/call_executor.rs | 8 ++++---- core/client/src/client.rs | 2 +- core/client/src/light/call_executor.rs | 8 ++++---- core/client/src/runtime_api.rs | 2 +- core/executor/src/native_executor.rs | 2 +- core/primitives/src/traits.rs | 2 +- core/sr-api-macros/src/decl_runtime_apis.rs | 12 ++++++------ core/sr-api-macros/src/impl_runtime_apis.rs | 2 +- core/sr-api-macros/tests/runtime_calls.rs | 5 ++++- core/state-machine/src/lib.rs | 10 +++++----- 10 files changed, 28 insertions(+), 25 deletions(-) diff --git a/core/client/src/call_executor.rs b/core/client/src/call_executor.rs index b49a58a0e5..ebb882709d 100644 --- a/core/client/src/call_executor.rs +++ b/core/client/src/call_executor.rs @@ -72,7 +72,7 @@ where Result, Self::Error> ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, >( &self, initialize_block_fn: IB, @@ -104,7 +104,7 @@ where Result, Self::Error> ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, >(&self, state: &S, overlay: &mut OverlayedChanges, @@ -234,7 +234,7 @@ where Result, Self::Error> ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, >( &self, initialize_block_fn: IB, @@ -342,7 +342,7 @@ where Result, Self::Error> ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, >(&self, state: &S, changes: &mut OverlayedChanges, diff --git a/core/client/src/client.rs b/core/client/src/client.rs index 8b7d2dc995..595aa0e9c7 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -1419,7 +1419,7 @@ impl CallRuntimeAt for Client where fn call_api_at< 'a, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, C: CoreApi, >( &self, diff --git a/core/client/src/light/call_executor.rs b/core/client/src/light/call_executor.rs index 2c9c1f2995..ec182cca11 100644 --- a/core/client/src/light/call_executor.rs +++ b/core/client/src/light/call_executor.rs @@ -99,7 +99,7 @@ impl CallExecutor for Result, Self::Error> ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, >( &self, initialize_block_fn: IB, @@ -160,7 +160,7 @@ impl CallExecutor for Result, Self::Error> ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, >(&self, _state: &S, _changes: &mut OverlayedChanges, @@ -334,7 +334,7 @@ mod tests { Result, Self::Error> ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, >( &self, _initialize_block_fn: IB, @@ -364,7 +364,7 @@ mod tests { Result, Self::Error> ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, >(&self, _state: &S, _overlay: &mut OverlayedChanges, diff --git a/core/client/src/runtime_api.rs b/core/client/src/runtime_api.rs index ed5c9fad48..a5700951e9 100644 --- a/core/client/src/runtime_api.rs +++ b/core/client/src/runtime_api.rs @@ -136,7 +136,7 @@ pub trait CallRuntimeAt { fn call_api_at< 'a, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, C: Core, >( &self, diff --git a/core/executor/src/native_executor.rs b/core/executor/src/native_executor.rs index 3de795fc27..cdf0be7f76 100644 --- a/core/executor/src/native_executor.rs +++ b/core/executor/src/native_executor.rs @@ -126,7 +126,7 @@ impl CodeExecutor for NativeExecutor, R:Decode + Encode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe + NC: FnOnce() -> result::Result + UnwindSafe >( &self, ext: &mut E, diff --git a/core/primitives/src/traits.rs b/core/primitives/src/traits.rs index 0274c44ace..b173d8512c 100644 --- a/core/primitives/src/traits.rs +++ b/core/primitives/src/traits.rs @@ -193,7 +193,7 @@ pub trait CodeExecutor: Sized + Send + Sync { fn call< E: Externalities, R: codec::Codec + PartialEq, - NC: FnOnce() -> Result + UnwindSafe, + NC: FnOnce() -> Result + UnwindSafe, >( &self, ext: &mut E, diff --git a/core/sr-api-macros/src/decl_runtime_apis.rs b/core/sr-api-macros/src/decl_runtime_apis.rs index 0e69c2b76d..12639bd1c1 100644 --- a/core/sr-api-macros/src/decl_runtime_apis.rs +++ b/core/sr-api-macros/src/decl_runtime_apis.rs @@ -188,11 +188,11 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result { fn convert_between_block_types ( input: &I, error_desc: &'static str, - ) -> ::std::result::Result + ) -> std::result::Result { ::decode( - &mut &#crate_::runtime_api::Encode::encode(input)[..] - ).map_err(|_| error_desc) + &mut &#crate_::runtime_api::Encode::encode(input)[..], + ).map_err(|e| format!("{} {}", error_desc, e.what())) } )); @@ -203,13 +203,13 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result { let fn_name = generate_native_call_generator_fn_name(&fn_.ident); let output = return_type_replace_block_with_node_block(fn_.decl.output.clone()); let output_ty = return_type_extract_type(&output); - let output = quote!( ::std::result::Result<#output_ty, &'static str> ); + let output = quote!( std::result::Result<#output_ty, String> ); // Every type that is using the `Block` generic parameter, we need to encode/decode, // to make it compatible between the runtime/node. let conversions = params.iter().filter(|v| type_is_using_block(&v.1)).map(|(n, t, _)| { let name_str = format!( - "Could not convert parameter `{}` between node and runtime!", quote!(#n) + "Could not convert parameter `{}` between node and runtime:", quote!(#n) ); quote!( let #n: #t = convert_between_block_types(&#n, #name_str)?; @@ -398,7 +398,7 @@ fn generate_call_api_at_calls(decl: &ItemTrait) -> Result { #[cfg(any(feature = "std", test))] pub fn #fn_name< R: #crate_::runtime_api::Encode + #crate_::runtime_api::Decode + PartialEq, - NC: FnOnce() -> ::std::result::Result + ::std::panic::UnwindSafe, + NC: FnOnce() -> std::result::Result + std::panic::UnwindSafe, Block: #crate_::runtime_api::BlockT, T: #crate_::runtime_api::CallRuntimeAt, C: #crate_::runtime_api::Core, diff --git a/core/sr-api-macros/src/impl_runtime_apis.rs b/core/sr-api-macros/src/impl_runtime_apis.rs index 973fa0558a..fb154aa112 100644 --- a/core/sr-api-macros/src/impl_runtime_apis.rs +++ b/core/sr-api-macros/src/impl_runtime_apis.rs @@ -282,7 +282,7 @@ fn generate_runtime_api_base_structures(impls: &[ItemImpl]) -> Result> #crate_::runtime_api::ApiExt<#block> for RuntimeApiImpl { - fn map_api_result ::std::result::Result, R, E>( + fn map_api_result std::result::Result, R, E>( &self, map_call: F ) -> ::std::result::Result where Self: Sized { diff --git a/core/sr-api-macros/tests/runtime_calls.rs b/core/sr-api-macros/tests/runtime_calls.rs index 6b79e52ee2..f33a9e257a 100644 --- a/core/sr-api-macros/tests/runtime_calls.rs +++ b/core/sr-api-macros/tests/runtime_calls.rs @@ -50,7 +50,10 @@ fn calling_wasm_runtime_function() { } #[test] -#[should_panic(expected = "Could not convert parameter `param` between node and runtime!")] +#[should_panic( + expected = + "Could not convert parameter `param` between node and runtime: DecodeFails always fails" +)] fn calling_native_runtime_function_with_non_decodable_parameter() { let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::NativeWhenPossible).build(); let runtime_api = client.runtime_api(); diff --git a/core/state-machine/src/lib.rs b/core/state-machine/src/lib.rs index 92dd813b89..5220b4b31d 100644 --- a/core/state-machine/src/lib.rs +++ b/core/state-machine/src/lib.rs @@ -250,7 +250,7 @@ impl<'a, B, H, N, T, O, Exec> StateMachine<'a, B, H, N, T, O, Exec> where Option>, ) where R: Decode + Encode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, { let mut externalities = ext::Ext::new( self.overlay, @@ -295,7 +295,7 @@ impl<'a, B, H, N, T, O, Exec> StateMachine<'a, B, H, N, T, O, Exec> where on_consensus_failure: Handler, ) -> (CallResult, Option<(B::Transaction, H::Out)>, Option>) where R: Decode + Encode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, Handler: FnOnce( CallResult, CallResult @@ -334,7 +334,7 @@ impl<'a, B, H, N, T, O, Exec> StateMachine<'a, B, H, N, T, O, Exec> where orig_prospective: OverlayedChangeSet, ) -> (CallResult, Option<(B::Transaction, H::Out)>, Option>) where R: Decode + Encode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, { let (result, was_native, storage_delta, changes_delta) = self.execute_aux( compute_tx, @@ -374,7 +374,7 @@ impl<'a, B, H, N, T, O, Exec> StateMachine<'a, B, H, N, T, O, Exec> where Option>, ), Box> where R: Decode + Encode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, Handler: FnOnce( CallResult, CallResult, @@ -753,7 +753,7 @@ mod tests { impl CodeExecutor for DummyCodeExecutor { type Error = u8; - fn call, R: Encode + Decode + PartialEq, NC: FnOnce() -> result::Result>( + fn call, R: Encode + Decode + PartialEq, NC: FnOnce() -> result::Result>( &self, ext: &mut E, _method: &str, -- GitLab From 00ac65fca22652807e578326ad9f2fe6b169390a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Mon, 30 Sep 2019 17:03:40 +0100 Subject: [PATCH 160/275] srml: im-online: fix received heartbeats pruning (#3724) * srml: im-online: fix pruning of received heartbeats * srml: im-online: add test for received heartbeats pruning * srml: im-online: remove unused variables from test * node: bump spec_version --- node/runtime/src/lib.rs | 4 ++-- srml/im-online/src/lib.rs | 7 ++++--- srml/im-online/src/tests.rs | 29 +++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index a8999576a7..c731427033 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -84,8 +84,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 165, - impl_version: 167, + spec_version: 166, + impl_version: 166, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/im-online/src/lib.rs b/srml/im-online/src/lib.rs index 611a2aaa16..1a09349701 100644 --- a/srml/im-online/src/lib.rs +++ b/srml/im-online/src/lib.rs @@ -437,9 +437,6 @@ impl session::OneSessionHandler for Module { fn on_new_session<'a, I: 'a>(_changed: bool, validators: I, _queued_validators: I) where I: Iterator { - // Reset heartbeats - ::remove_prefix(&>::current_index()); - // Tell the offchain worker to start making the next session's heartbeats. >::put(>::block_number()); @@ -484,6 +481,10 @@ impl session::OneSessionHandler for Module { }; T::ReportUnresponsiveness::report_offence(vec![], offence); + + // Remove all received heartbeats from the current session, they have + // already been processed and won't be needed anymore. + ::remove_prefix(&>::current_index()); } fn on_disabled(_i: usize) { diff --git a/srml/im-online/src/tests.rs b/srml/im-online/src/tests.rs index 4f6702780f..c6405c34fa 100644 --- a/srml/im-online/src/tests.rs +++ b/srml/im-online/src/tests.rs @@ -216,3 +216,32 @@ fn should_generate_heartbeats() { }); }); } + +#[test] +fn should_cleanup_received_heartbeats_on_session_end() { + with_externalities(&mut new_test_ext(), || { + advance_session(); + + VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 3])); + assert_eq!(Session::validators(), Vec::::new()); + + // enact the change and buffer another one + advance_session(); + + assert_eq!(Session::current_index(), 2); + assert_eq!(Session::validators(), vec![1, 2, 3]); + + // send an heartbeat from authority id 0 at session 2 + let _ = heartbeat(1, 2, 0, 1.into()).unwrap(); + + // the heartbeat is stored + assert!(!ImOnline::received_heartbeats(&2, &0).is_empty()); + + advance_session(); + + // after the session has ended we have already processed the heartbeat + // message, so any messages received on the previous session should have + // been pruned. + assert!(ImOnline::received_heartbeats(&2, &0).is_empty()); + }); +} -- GitLab From 559f57011ccd5b54dac8ac5af4c6af6c256ebb6c Mon Sep 17 00:00:00 2001 From: Ashley Date: Tue, 1 Oct 2019 17:42:11 +1300 Subject: [PATCH 161/275] Add an Error type to Aura (#3688) * Add an Error type to Aura * Add Cargo.lock * AuRa -> Aura Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- Cargo.lock | 1 + core/consensus/aura/Cargo.toml | 1 + core/consensus/aura/src/lib.rs | 67 ++++++++++++++++++++++------------ 3 files changed, 45 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0787d7faec..27066afe3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4771,6 +4771,7 @@ dependencies = [ name = "substrate-consensus-aura" version = "2.0.0" dependencies = [ + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/core/consensus/aura/Cargo.toml b/core/consensus/aura/Cargo.toml index c3aaeb3d56..724b720f4f 100644 --- a/core/consensus/aura/Cargo.toml +++ b/core/consensus/aura/Cargo.toml @@ -26,6 +26,7 @@ futures01 = { package = "futures", version = "0.1" } futures-timer = "0.3" parking_lot = "0.9.0" log = "0.4" +derive_more = "0.15.0" [dev-dependencies] keyring = { package = "substrate-keyring", path = "../../keyring" } diff --git a/core/consensus/aura/src/lib.rs b/core/consensus/aura/src/lib.rs index a61eb6da72..eb2d1dba20 100644 --- a/core/consensus/aura/src/lib.rs +++ b/core/consensus/aura/src/lib.rs @@ -48,7 +48,7 @@ use sr_primitives::{generic::{BlockId, OpaqueDigestItemId}, Justification}; use sr_primitives::traits::{Block as BlockT, Header, DigestItemFor, ProvideRuntimeApi, Zero, Member}; use primitives::crypto::Pair; -use inherents::{InherentDataProviders, InherentData}; +use inherents::{InherentDataProviders, InherentData, RuntimeString}; use futures::prelude::*; use parking_lot::Mutex; @@ -308,16 +308,33 @@ impl SlotWorker for AuraWorker { - { - debug!(target: "aura", $( $i ),+); - format!($( $i ),+) - } - }; +fn aura_err(error: Error) -> Error { + debug!(target: "aura", "{}", error); + error +} + +#[derive(derive_more::Display)] +enum Error { + #[display(fmt = "Multiple Aura pre-runtime headers")] + MultipleHeaders, + #[display(fmt = "No Aura pre-runtime digest found")] + NoDigestFound, + #[display(fmt = "Header {:?} is unsealed", _0)] + HeaderUnsealed(B::Hash), + #[display(fmt = "Header {:?} has a bad seal", _0)] + HeaderBadSeal(B::Hash), + #[display(fmt = "Slot Author not found")] + SlotAuthorNotFound, + #[display(fmt = "Bad signature on {:?}", _0)] + BadSignature(B::Hash), + #[display(fmt = "Rejecting block too far in future")] + TooFarInFuture, + Client(client::error::Error), + DataProvider(String), + Runtime(RuntimeString) } -fn find_pre_digest(header: &B::Header) -> Result +fn find_pre_digest(header: &B::Header) -> Result> where DigestItemFor: CompatibleDigestItem

, P::Signature: Decode, P::Public: Encode + Decode + PartialEq + Clone, @@ -326,12 +343,12 @@ fn find_pre_digest(header: &B::Header) -> Result Err(aura_err!("Multiple AuRa pre-runtime headers, rejecting!"))?, + (Some(_), true) => Err(aura_err(Error::MultipleHeaders))?, (None, _) => trace!(target: "aura", "Ignoring digest not meant for us"), (s, false) => pre_digest = s, } } - pre_digest.ok_or_else(|| aura_err!("No AuRa pre-runtime digest found")) + pre_digest.ok_or_else(|| aura_err(Error::NoDigestFound)) } /// check a header has been signed by the right key. If the slot is too far in the future, an error will be returned. @@ -348,7 +365,7 @@ fn check_header( hash: B::Hash, authorities: &[AuthorityId

], _transaction_pool: Option<&T>, -) -> Result)>, String> where +) -> Result)>, Error> where DigestItemFor: CompatibleDigestItem

, P::Signature: Decode, C: client::backend::AuxStore, @@ -357,11 +374,11 @@ fn check_header( { let seal = match header.digest_mut().pop() { Some(x) => x, - None => return Err(format!("Header {:?} is unsealed", hash)), + None => return Err(Error::HeaderUnsealed(hash)), }; let sig = seal.as_aura_seal().ok_or_else(|| { - aura_err!("Header {:?} has a bad seal", hash) + aura_err(Error::HeaderBadSeal(hash)) })?; let slot_num = find_pre_digest::(&header)?; @@ -373,7 +390,7 @@ fn check_header( // check the signature is valid under the expected authority and // chain state. let expected_author = match slot_author::

> for Author whe ).map(Into::into).map_err(|e| Error::Client(Box::new(e))) } - fn submit_extrinsic(&self, ext: Bytes) -> Result> { - let xt = Decode::decode(&mut &ext[..])?; + fn submit_extrinsic(&self, ext: Bytes) -> FutureResult> { + let xt = match Decode::decode(&mut &ext[..]) { + Ok(xt) => xt, + Err(err) => return Box::new(result(Err(err.into()))), + }; let best_block_hash = self.client.info().chain.best_hash; - self.pool + Box::new(self.pool .submit_one(&generic::BlockId::hash(best_block_hash), xt) + .compat() .map_err(|e| e.into_pool_error() .map(Into::into) - .unwrap_or_else(|e| error::Error::Verification(Box::new(e)).into()) - ) + .unwrap_or_else(|e| error::Error::Verification(Box::new(e)).into())) + ) } fn pending_extrinsics(&self) -> Result> { @@ -151,17 +160,20 @@ impl AuthorApi, BlockHash

> for Author whe ) { let submit = || -> Result<_> { let best_block_hash = self.client.info().chain.best_hash; - let dxt = <

::Block as traits::Block>::Extrinsic::decode(&mut &xt[..])?; - self.pool + let dxt = <

::Block as traits::Block>::Extrinsic::decode(&mut &xt[..]) + .map_err(error::Error::from)?; + Ok(self.pool .submit_and_watch(&generic::BlockId::hash(best_block_hash), dxt) + .boxed() + .compat() .map_err(|e| e.into_pool_error() - .map(Into::into) + .map(error::Error::from) .unwrap_or_else(|e| error::Error::Verification(Box::new(e)).into()) - ) + )) }; - let watcher = match submit() { - Ok(watcher) => watcher, + let future_watcher = match submit() { + Ok(future_watcher) => future_watcher, Err(err) => { // reject the subscriber (ignore errors - we don't care if subscriber is no longer there). let _ = subscriber.reject(err.into()); @@ -169,12 +181,23 @@ impl AuthorApi, BlockHash

> for Author whe }, }; + // make 'future' watcher be a future with output = stream of watcher events + let future_watcher = future_watcher + .map_err(|err| { warn!("Failed to submit extrinsic: {}", err); }) + .map(|watcher| Compat::new(watcher.into_stream().map(|v| Ok::<_, ()>(Ok(v))))); + + // convert a 'future' watcher into the stream with single element = stream of watcher events + let watcher_stream = future_watcher.into_stream(); + + // and now flatten the 'watcher_stream' so that we'll have the stream with watcher events + let watcher_stream = watcher_stream.flatten(); + self.subscriptions.add(subscriber, move |sink| { sink .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) - .send_all(Compat::new(watcher.into_stream().map(|v| Ok::<_, ()>(Ok(v))))) + .send_all(watcher_stream) .map(|_| ()) - }) + }); } fn unwatch_extrinsic(&self, _metadata: Option, id: SubscriptionId) -> Result { diff --git a/core/rpc/src/author/tests.rs b/core/rpc/src/author/tests.rs index 1f652aec64..57d3929d92 100644 --- a/core/rpc/src/author/tests.rs +++ b/core/rpc/src/author/tests.rs @@ -21,9 +21,8 @@ use assert_matches::assert_matches; use codec::Encode; use transaction_pool::{ txpool::Pool, - ChainApi, + FullChainApi, }; -use futures::Stream; use primitives::{ H256, blake2_256, hexdisplay::HexDisplay, traits::BareCryptoStore, testing::{ED25519, SR25519, KeyStore}, ed25519, crypto::Pair @@ -51,7 +50,7 @@ fn submit_transaction_should_not_cause_error() { let keystore = KeyStore::new(); let p = Author { client: client.clone(), - pool: Arc::new(Pool::new(Default::default(), ChainApi::new(client))), + pool: Arc::new(Pool::new(Default::default(), FullChainApi::new(client))), subscriptions: Subscriptions::new(Arc::new(runtime.executor())), keystore: keystore.clone(), }; @@ -59,11 +58,11 @@ fn submit_transaction_should_not_cause_error() { let h: H256 = blake2_256(&xt).into(); assert_matches!( - AuthorApi::submit_extrinsic(&p, xt.clone().into()), + AuthorApi::submit_extrinsic(&p, xt.clone().into()).wait(), Ok(h2) if h == h2 ); assert!( - AuthorApi::submit_extrinsic(&p, xt.into()).is_err() + AuthorApi::submit_extrinsic(&p, xt.into()).wait().is_err() ); } @@ -74,7 +73,7 @@ fn submit_rich_transaction_should_not_cause_error() { let keystore = KeyStore::new(); let p = Author { client: client.clone(), - pool: Arc::new(Pool::new(Default::default(), ChainApi::new(client.clone()))), + pool: Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone()))), subscriptions: Subscriptions::new(Arc::new(runtime.executor())), keystore: keystore.clone(), }; @@ -82,11 +81,11 @@ fn submit_rich_transaction_should_not_cause_error() { let h: H256 = blake2_256(&xt).into(); assert_matches!( - AuthorApi::submit_extrinsic(&p, xt.clone().into()), + AuthorApi::submit_extrinsic(&p, xt.clone().into()).wait(), Ok(h2) if h == h2 ); assert!( - AuthorApi::submit_extrinsic(&p, xt.into()).is_err() + AuthorApi::submit_extrinsic(&p, xt.into()).wait().is_err() ); } @@ -95,7 +94,7 @@ fn should_watch_extrinsic() { //given let mut runtime = runtime::Runtime::new().unwrap(); let client = Arc::new(test_client::new()); - let pool = Arc::new(Pool::new(Default::default(), ChainApi::new(client.clone()))); + let pool = Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone()))); let keystore = KeyStore::new(); let p = Author { client, @@ -120,7 +119,7 @@ fn should_watch_extrinsic() { }; tx.into_signed_tx() }; - AuthorApi::submit_extrinsic(&p, replacement.encode().into()).unwrap(); + AuthorApi::submit_extrinsic(&p, replacement.encode().into()).wait().unwrap(); let (res, data) = runtime.block_on(data.into_future()).unwrap(); assert_eq!( res, @@ -137,7 +136,7 @@ fn should_watch_extrinsic() { fn should_return_pending_extrinsics() { let runtime = runtime::Runtime::new().unwrap(); let client = Arc::new(test_client::new()); - let pool = Arc::new(Pool::new(Default::default(), ChainApi::new(client.clone()))); + let pool = Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone()))); let keystore = KeyStore::new(); let p = Author { client, @@ -146,7 +145,7 @@ fn should_return_pending_extrinsics() { keystore: keystore.clone(), }; let ex = uxt(AccountKeyring::Alice, 0); - AuthorApi::submit_extrinsic(&p, ex.encode().into()).unwrap(); + AuthorApi::submit_extrinsic(&p, ex.encode().into()).wait().unwrap(); assert_matches!( p.pending_extrinsics(), Ok(ref expected) if *expected == vec![Bytes(ex.encode())] @@ -157,7 +156,7 @@ fn should_return_pending_extrinsics() { fn should_remove_extrinsics() { let runtime = runtime::Runtime::new().unwrap(); let client = Arc::new(test_client::new()); - let pool = Arc::new(Pool::new(Default::default(), ChainApi::new(client.clone()))); + let pool = Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone()))); let keystore = KeyStore::new(); let p = Author { client, @@ -166,11 +165,11 @@ fn should_remove_extrinsics() { keystore: keystore.clone(), }; let ex1 = uxt(AccountKeyring::Alice, 0); - p.submit_extrinsic(ex1.encode().into()).unwrap(); + p.submit_extrinsic(ex1.encode().into()).wait().unwrap(); let ex2 = uxt(AccountKeyring::Alice, 1); - p.submit_extrinsic(ex2.encode().into()).unwrap(); + p.submit_extrinsic(ex2.encode().into()).wait().unwrap(); let ex3 = uxt(AccountKeyring::Bob, 0); - let hash3 = p.submit_extrinsic(ex3.encode().into()).unwrap(); + let hash3 = p.submit_extrinsic(ex3.encode().into()).wait().unwrap(); assert_eq!(pool.status().ready, 3); // now remove all 3 @@ -190,7 +189,7 @@ fn should_insert_key() { let keystore = KeyStore::new(); let p = Author { client: client.clone(), - pool: Arc::new(Pool::new(Default::default(), ChainApi::new(client))), + pool: Arc::new(Pool::new(Default::default(), FullChainApi::new(client))), subscriptions: Subscriptions::new(Arc::new(runtime.executor())), keystore: keystore.clone(), }; @@ -216,7 +215,7 @@ fn should_rotate_keys() { let client = Arc::new(test_client::TestClientBuilder::new().set_keystore(keystore.clone()).build()); let p = Author { client: client.clone(), - pool: Arc::new(Pool::new(Default::default(), ChainApi::new(client))), + pool: Arc::new(Pool::new(Default::default(), FullChainApi::new(client))), subscriptions: Subscriptions::new(Arc::new(runtime.executor())), keystore: keystore.clone(), }; diff --git a/core/service/src/builder.rs b/core/service/src/builder.rs index 3317ab23cd..f0860de1c1 100644 --- a/core/service/src/builder.rs +++ b/core/service/src/builder.rs @@ -26,7 +26,12 @@ use chain_spec::{RuntimeGenesis, Extension}; use codec::{Decode, Encode, IoReader}; use consensus_common::import_queue::ImportQueue; use futures::{prelude::*, sync::mpsc}; -use futures03::{FutureExt as _, compat::Compat, StreamExt as _, TryStreamExt as _}; +use futures03::{ + compat::Compat, + future::ready, + FutureExt as _, TryFutureExt as _, + StreamExt as _, TryStreamExt as _, +}; use keystore::{Store as Keystore, KeyStorePtr}; use log::{info, warn}; use network::{FinalityProofProvider, OnDemand, NetworkService, NetworkStateInfo, DhtEvent}; @@ -913,7 +918,7 @@ where RpcB: RpcBuilder, { use rpc::{chain, state, author, system}; - let subscriptions = rpc::Subscriptions::new(task_executor.clone()); + let subscriptions = rpc::Subscriptions::new(task_executor); let chain = rpc_builder.build_chain(subscriptions.clone()); let state = rpc_builder.build_state(subscriptions.clone()); let author = rpc::author::Author::new( @@ -935,45 +940,54 @@ where pub(crate) fn maintain_transaction_pool( id: &BlockId, - client: &Client, + client: &Arc>, transaction_pool: &TransactionPool, retracted: &[Block::Hash], -) -> error::Result<()> where +) -> error::Result + Send>> where Block: BlockT::Out>, - Backend: client::backend::Backend, + Backend: 'static + client::backend::Backend, Client: ProvideRuntimeApi, as ProvideRuntimeApi>::Api: runtime_api::TaggedTransactionQueue, - Executor: client::CallExecutor, - PoolApi: txpool::ChainApi, + Executor: 'static + client::CallExecutor, + PoolApi: 'static + txpool::ChainApi, + Api: 'static, { // Put transactions from retracted blocks back into the pool. - for r in retracted { - if let Some(block) = client.block(&BlockId::hash(*r))? { - let extrinsics = block.block.extrinsics(); - if let Err(e) = transaction_pool.submit_at( - id, - extrinsics.iter().filter(|e| { - e.is_signed().unwrap_or(false) - }).cloned(), - true - ) { + let client_copy = client.clone(); + let retracted_transactions = retracted.to_vec().into_iter() + .filter_map(move |hash| client_copy.block(&BlockId::hash(hash)).ok().unwrap_or(None)) + .flat_map(|block| block.block.deconstruct().1.into_iter()) + .filter(|tx| tx.is_signed().unwrap_or(false)); + let resubmit_future = transaction_pool + .submit_at(id, retracted_transactions, true) + .then(|resubmit_result| ready(match resubmit_result { + Ok(_) => Ok(()), + Err(e) => { warn!("Error re-submitting transactions: {:?}", e); + Ok(()) } - } - } + })) + .compat(); // Avoid calling into runtime if there is nothing to prune from the pool anyway. if transaction_pool.status().is_empty() { - return Ok(()) - } - - if let Some(block) = client.block(id)? { - let parent_id = BlockId::hash(*block.block.header().parent_hash()); - let extrinsics = block.block.extrinsics(); - transaction_pool.prune(id, &parent_id, extrinsics).map_err(|e| format!("{:?}", e))?; + return Ok(Box::new(resubmit_future)) } - Ok(()) + let block = client.block(id)?; + Ok(match block { + Some(block) => { + let parent_id = BlockId::hash(*block.block.header().parent_hash()); + let prune_future = transaction_pool + .prune(id, &parent_id, block.block.extrinsics()) + .boxed() + .compat() + .map_err(|e| { format!("{:?}", e); }); + + Box::new(resubmit_future.and_then(|_| prune_future)) + }, + None => Box::new(resubmit_future), + }) } pub(crate) fn offchain_workers( @@ -1005,6 +1019,7 @@ where #[cfg(test)] mod tests { use super::*; + use futures03::executor::block_on; use consensus_common::{BlockOrigin, SelectChain}; use substrate_test_runtime_client::{prelude::*, runtime::Transfer}; @@ -1012,7 +1027,7 @@ mod tests { fn should_remove_transactions_from_the_pool() { let (client, longest_chain) = TestClientBuilder::new().build_with_longest_chain(); let client = Arc::new(client); - let pool = TransactionPool::new(Default::default(), ::transaction_pool::ChainApi::new(client.clone())); + let pool = TransactionPool::new(Default::default(), ::transaction_pool::FullChainApi::new(client.clone())); let transaction = Transfer { amount: 5, nonce: 0, @@ -1022,7 +1037,7 @@ mod tests { let best = longest_chain.best_chain().unwrap(); // store the transaction in the pool - pool.submit_one(&BlockId::hash(best.hash()), transaction.clone()).unwrap(); + block_on(pool.submit_one(&BlockId::hash(best.hash()), transaction.clone())).unwrap(); // import the block let mut builder = client.new_block(Default::default()).unwrap(); @@ -1038,7 +1053,7 @@ mod tests { &client, &pool, &[] - ).unwrap(); + ).unwrap().wait().unwrap(); // then assert_eq!(pool.status().ready, 0); @@ -1049,7 +1064,7 @@ mod tests { fn should_add_reverted_transactions_to_the_pool() { let (client, longest_chain) = TestClientBuilder::new().build_with_longest_chain(); let client = Arc::new(client); - let pool = TransactionPool::new(Default::default(), ::transaction_pool::ChainApi::new(client.clone())); + let pool = TransactionPool::new(Default::default(), ::transaction_pool::FullChainApi::new(client.clone())); let transaction = Transfer { amount: 5, nonce: 0, @@ -1059,7 +1074,7 @@ mod tests { let best = longest_chain.best_chain().unwrap(); // store the transaction in the pool - pool.submit_one(&BlockId::hash(best.hash()), transaction.clone()).unwrap(); + block_on(pool.submit_one(&BlockId::hash(best.hash()), transaction.clone())).unwrap(); // import the block let mut builder = client.new_block(Default::default()).unwrap(); @@ -1076,7 +1091,7 @@ mod tests { &client, &pool, &[] - ).unwrap(); + ).unwrap().wait().unwrap(); // then assert_eq!(pool.status().ready, 0); @@ -1094,7 +1109,7 @@ mod tests { &client, &pool, &[block1_hash] - ).unwrap(); + ).unwrap().wait().unwrap(); // then assert_eq!(pool.status().ready, 1); diff --git a/core/service/src/lib.rs b/core/service/src/lib.rs index 72ee2d8511..afe5bad8f5 100644 --- a/core/service/src/lib.rs +++ b/core/service/src/lib.rs @@ -36,8 +36,14 @@ use parking_lot::Mutex; use client::{runtime_api::BlockT, Client}; use exit_future::Signal; use futures::prelude::*; -use futures03::stream::{StreamExt as _, TryStreamExt as _}; -use network::{NetworkService, NetworkState, specialization::NetworkSpecialization, Event, DhtEvent}; +use futures03::{ + future::{ready, FutureExt as _, TryFutureExt as _}, + stream::{StreamExt as _, TryStreamExt as _}, +}; +use network::{ + NetworkService, NetworkState, specialization::NetworkSpecialization, + Event, DhtEvent, PeerId, ReportHandle, +}; use log::{log, warn, debug, error, Level}; use codec::{Encode, Decode}; use primitives::{Blake2Hasher, H256}; @@ -168,6 +174,7 @@ macro_rules! new_impl { imports_external_transactions: !$config.roles.is_light(), pool: transaction_pool.clone(), client: client.clone(), + executor: Arc::new(SpawnTaskHandle { sender: to_spawn_tx.clone(), on_exit: exit.clone() }), }); let protocol_id = { @@ -233,12 +240,13 @@ macro_rules! new_impl { let txpool = txpool.upgrade(); if let (Some(txpool), Some(client)) = (txpool.as_ref(), wclient.upgrade()) { - $maintain_transaction_pool( + let future = $maintain_transaction_pool( &BlockId::hash(notification.hash), - &*client, + &client, &*txpool, ¬ification.retracted, ).map_err(|e| warn!("Pool error processing new block: {:?}", e))?; + let _ = to_spawn_tx_.unbounded_send(future); } let offchain = offchain.as_ref().and_then(|o| o.upgrade()); @@ -871,6 +879,7 @@ pub struct TransactionPoolAdapter { imports_external_transactions: bool, pool: Arc

, client: Arc, + executor: TaskExecutor, } /// Get transactions for propagation. @@ -898,7 +907,7 @@ impl network::TransactionPool for TransactionPoolAdapter> where C: network::ClientHandle + Send + Sync, - PoolApi: ChainApi, + PoolApi: 'static + ChainApi, B: BlockT, H: std::hash::Hash + Eq + sr_primitives::traits::Member + sr_primitives::traits::MaybeSerialize, E: txpool::error::IntoPoolError + From, @@ -907,38 +916,40 @@ where transactions_to_propagate(&self.pool) } - fn import(&self, transaction: &::Extrinsic) -> Option { + fn hash_of(&self, transaction: &B::Extrinsic) -> H { + self.pool.hash_of(transaction) + } + + fn import(&self, report_handle: ReportHandle, who: PeerId, reputation_change: i32, transaction: B::Extrinsic) { if !self.imports_external_transactions { debug!("Transaction rejected"); - return None; + return; } let encoded = transaction.encode(); match Decode::decode(&mut &encoded[..]) { Ok(uxt) => { let best_block_id = BlockId::hash(self.client.info().chain.best_hash); - match self.pool.submit_one(&best_block_id, uxt) { - Ok(hash) => Some(hash), - Err(e) => match e.into_pool_error() { - Ok(txpool::error::Error::AlreadyImported(hash)) => { - hash.downcast::().ok() - .map(|x| x.as_ref().clone()) - }, - Ok(e) => { - debug!("Error adding transaction to the pool: {:?}", e); - None - }, - Err(e) => { - debug!("Error converting pool error: {:?}", e); - None - }, - } + let import_future = self.pool.submit_one(&best_block_id, uxt); + let import_future = import_future + .then(move |import_result| { + match import_result { + Ok(_) => report_handle.report_peer(who, reputation_change), + Err(e) => match e.into_pool_error() { + Ok(txpool::error::Error::AlreadyImported(_)) => (), + Ok(e) => debug!("Error adding transaction to the pool: {:?}", e), + Err(e) => debug!("Error converting pool error: {:?}", e), + } + } + ready(Ok(())) + }) + .compat(); + + if let Err(e) = self.executor.execute(Box::new(import_future)) { + warn!("Error scheduling extrinsic import: {:?}", e); } } - Err(e) => { - debug!("Error decoding transaction {}", e); - None - } + Err(e) => debug!("Error decoding transaction {}", e), } } @@ -950,6 +961,7 @@ where #[cfg(test)] mod tests { use super::*; + use futures03::executor::block_on; use consensus_common::SelectChain; use sr_primitives::traits::BlindCheckable; use substrate_test_runtime_client::{prelude::*, runtime::{Extrinsic, Transfer}}; @@ -961,7 +973,7 @@ mod tests { let client = Arc::new(client); let pool = Arc::new(TransactionPool::new( Default::default(), - transaction_pool::ChainApi::new(client.clone()) + transaction_pool::FullChainApi::new(client.clone()) )); let best = longest_chain.best_chain().unwrap(); let transaction = Transfer { @@ -970,8 +982,8 @@ mod tests { from: AccountKeyring::Alice.into(), to: Default::default(), }.into_signed_tx(); - pool.submit_one(&BlockId::hash(best.hash()), transaction.clone()).unwrap(); - pool.submit_one(&BlockId::hash(best.hash()), Extrinsic::IncludeData(vec![1])).unwrap(); + block_on(pool.submit_one(&BlockId::hash(best.hash()), transaction.clone())).unwrap(); + block_on(pool.submit_one(&BlockId::hash(best.hash()), Extrinsic::IncludeData(vec![1]))).unwrap(); assert_eq!(pool.status().ready, 2); // when diff --git a/core/service/test/Cargo.toml b/core/service/test/Cargo.toml index aa3dddfc18..459e079c85 100644 --- a/core/service/test/Cargo.toml +++ b/core/service/test/Cargo.toml @@ -8,6 +8,7 @@ edition = "2018" tempdir = "0.3" tokio = "0.1.7" futures = "0.1" +futures03 = { package = "futures-preview", version = "=0.3.0-alpha.18", features = ["compat"] } log = "0.4" env_logger = "0.6" fdlimit = "0.1" diff --git a/core/service/test/src/lib.rs b/core/service/test/src/lib.rs index 0540210b40..2d064f965b 100644 --- a/core/service/test/src/lib.rs +++ b/core/service/test/src/lib.rs @@ -445,7 +445,7 @@ pub fn sync( let first_user_data = &network.full_nodes[0].2; let best_block = BlockId::number(first_service.get().client().info().chain.best_number); let extrinsic = extrinsic_factory(&first_service.get(), first_user_data); - first_service.get().transaction_pool().submit_one(&best_block, extrinsic).unwrap(); + futures03::executor::block_on(first_service.get().transaction_pool().submit_one(&best_block, extrinsic)).unwrap(); network.run_until_all_full( |_index, service| service.get().transaction_pool().ready().count() == 1, |_index, _service| true, diff --git a/core/transaction-pool/Cargo.toml b/core/transaction-pool/Cargo.toml index 5e9973b6dc..e55070f06e 100644 --- a/core/transaction-pool/Cargo.toml +++ b/core/transaction-pool/Cargo.toml @@ -6,6 +6,7 @@ edition = "2018" [dependencies] derive_more = "0.14.0" +futures-preview = "=0.3.0-alpha.18" log = "0.4" codec = { package = "parity-scale-codec", version = "1.0.0" } parking_lot = "0.9.0" diff --git a/core/transaction-pool/graph/src/lib.rs b/core/transaction-pool/graph/src/lib.rs index ea890a5cd0..715e60874b 100644 --- a/core/transaction-pool/graph/src/lib.rs +++ b/core/transaction-pool/graph/src/lib.rs @@ -29,6 +29,7 @@ mod listener; mod pool; mod ready; mod rotator; +mod validated_pool; pub mod base_pool; pub mod error; @@ -36,4 +37,8 @@ pub mod watcher; pub use self::error::IntoPoolError; pub use self::base_pool::{Transaction, Status}; -pub use self::pool::{Pool, Options, ChainApi, EventStream, ExtrinsicFor, BlockHash, ExHash, NumberFor, TransactionFor}; +pub use self::pool::{ + Pool, + Options, ChainApi, EventStream, ExtrinsicFor, + BlockHash, ExHash, NumberFor, TransactionFor, +}; diff --git a/core/transaction-pool/graph/src/pool.rs b/core/transaction-pool/graph/src/pool.rs index 389892101e..53b2a62cbe 100644 --- a/core/transaction-pool/graph/src/pool.rs +++ b/core/transaction-pool/graph/src/pool.rs @@ -15,29 +15,27 @@ // along with Substrate. If not, see . use std::{ - collections::{HashSet, HashMap}, hash, + collections::HashMap, sync::Arc, - time, }; use crate::base_pool as base; use crate::error; -use crate::listener::Listener; -use crate::rotator::PoolRotator; use crate::watcher::Watcher; use serde::Serialize; -use log::debug; -use futures::channel::mpsc; -use parking_lot::{Mutex, RwLock}; +use futures::{ + Future, FutureExt, + channel::mpsc, + future::{Either, ready, join_all}, +}; use sr_primitives::{ generic::BlockId, traits::{self, SaturatedConversion}, transaction_validity::{TransactionValidity, TransactionTag as Tag, TransactionValidityError}, }; - -pub use crate::base_pool::Limit; +use crate::validated_pool::{ValidatedPool, ValidatedTransaction}; /// Modification notification event stream type; pub type EventStream = mpsc::UnboundedReceiver<()>; @@ -52,6 +50,12 @@ pub type ExtrinsicFor = <::Block as traits::Block>::Extrinsic; pub type NumberFor = traits::NumberFor<::Block>; /// A type of transaction stored in the pool pub type TransactionFor = Arc, ExtrinsicFor>>; +/// A type of validated transaction stored in the pool. +pub type ValidatedTransactionFor = ValidatedTransaction< + ExHash, + ExtrinsicFor, + ::Error, +>; /// Concrete extrinsic validation and query logic. pub trait ChainApi: Send + Sync { @@ -61,9 +65,15 @@ pub trait ChainApi: Send + Sync { type Hash: hash::Hash + Eq + traits::Member + Serialize; /// Error type. type Error: From + error::IntoPoolError; + /// Validate transaction future. + type ValidationFuture: Future> + Send; /// Verify extrinsic at given block. - fn validate_transaction(&self, at: &BlockId, uxt: ExtrinsicFor) -> Result; + fn validate_transaction( + &self, + at: &BlockId, + uxt: ExtrinsicFor, + ) -> Self::ValidationFuture; /// Returns a block number given the block id. fn block_id_to_number(&self, at: &BlockId) -> Result>, Self::Error>; @@ -79,19 +89,19 @@ pub trait ChainApi: Send + Sync { #[derive(Debug, Clone)] pub struct Options { /// Ready queue limits. - pub ready: Limit, + pub ready: base::Limit, /// Future queue limits. - pub future: Limit, + pub future: base::Limit, } impl Default for Options { fn default() -> Self { Options { - ready: Limit { + ready: base::Limit { count: 512, total_bytes: 10 * 1024 * 1024, }, - future: Limit { + future: base::Limit { count: 128, total_bytes: 1 * 1024 * 1024, }, @@ -99,125 +109,60 @@ impl Default for Options { } } -/// Extrinsics pool. +/// Extrinsics pool that performs validation. pub struct Pool { - api: B, - options: Options, - listener: RwLock, BlockHash>>, - pool: RwLock, - ExtrinsicFor, - >>, - import_notification_sinks: Mutex>>, - rotator: PoolRotator>, + validated_pool: Arc>, } impl Pool { + /// Create a new transaction pool. + pub fn new(options: Options, api: B) -> Self { + Pool { + validated_pool: Arc::new(ValidatedPool::new(options, api)), + } + } + /// Imports a bunch of unverified extrinsics to the pool pub fn submit_at(&self, at: &BlockId, xts: T, force: bool) - -> Result, B::Error>>, B::Error> + -> impl Future, B::Error>>, B::Error>> where T: IntoIterator> { - let block_number = self.api.block_id_to_number(at)? - .ok_or_else(|| error::Error::InvalidBlockId(format!("{:?}", at)).into())?; - - let results = xts - .into_iter() - .map(|xt| -> Result<_, B::Error> { - let (hash, bytes) = self.api.hash_and_length(&xt); - if !force && self.rotator.is_banned(&hash) { - return Err(error::Error::TemporarilyBanned.into()) - } - - match self.api.validate_transaction(at, xt.clone())? { - Ok(validity) => if validity.provides.is_empty() { - Err(error::Error::NoTagsProvided.into()) - } else { - Ok(base::Transaction { - data: xt, - bytes, - hash, - priority: validity.priority, - requires: validity.requires, - provides: validity.provides, - propagate: validity.propagate, - valid_till: block_number - .saturated_into::() - .saturating_add(validity.longevity), - }) - }, - Err(TransactionValidityError::Invalid(e)) => { - Err(error::Error::InvalidTransaction(e).into()) - }, - Err(TransactionValidityError::Unknown(e)) => { - self.listener.write().invalid(&hash); - Err(error::Error::UnknownTransaction(e).into()) - }, - } - }) - .map(|tx| { - let imported = self.pool.write().import(tx?)?; - - if let base::Imported::Ready { .. } = imported { - self.import_notification_sinks.lock().retain(|sink| sink.unbounded_send(()).is_ok()); - } - - let mut listener = self.listener.write(); - fire_events(&mut *listener, &imported); - Ok(imported.hash().clone()) - }) - .collect::>(); - - let removed = self.enforce_limits(); - - Ok(results.into_iter().map(|res| match res { - Ok(ref hash) if removed.contains(hash) => Err(error::Error::ImmediatelyDropped.into()), - other => other, - }).collect()) - } - - fn enforce_limits(&self) -> HashSet> { - let status = self.pool.read().status(); - let ready_limit = &self.options.ready; - let future_limit = &self.options.future; - - debug!(target: "txpool", "Pool Status: {:?}", status); - - if ready_limit.is_exceeded(status.ready, status.ready_bytes) - || future_limit.is_exceeded(status.future, status.future_bytes) { - // clean up the pool - let removed = { - let mut pool = self.pool.write(); - let removed = pool.enforce_limits(ready_limit, future_limit) - .into_iter().map(|x| x.hash.clone()).collect::>(); - // ban all removed transactions - self.rotator.ban(&std::time::Instant::now(), removed.iter().map(|x| x.clone())); - removed - }; - // run notifications - let mut listener = self.listener.write(); - for h in &removed { - listener.dropped(h, None); - } - - removed - } else { - Default::default() - } + let validated_pool = self.validated_pool.clone(); + self.verify(at, xts, force) + .map(move |validated_transactions| validated_transactions + .map(|validated_transactions| validated_pool.submit(validated_transactions))) } /// Imports one unverified extrinsic to the pool - pub fn submit_one(&self, at: &BlockId, xt: ExtrinsicFor) -> Result, B::Error> { - Ok(self.submit_at(at, ::std::iter::once(xt), false)?.pop().expect("One extrinsic passed; one result returned; qed")?) + pub fn submit_one( + &self, + at: &BlockId, + xt: ExtrinsicFor, + ) -> impl Future, B::Error>> { + self.submit_at(at, std::iter::once(xt), false) + .map(|import_result| import_result.and_then(|mut import_result| import_result + .pop() + .expect("One extrinsic passed; one result returned; qed") + )) } /// Import a single extrinsic and starts to watch their progress in the pool. - pub fn submit_and_watch(&self, at: &BlockId, xt: ExtrinsicFor) -> Result, BlockHash>, B::Error> { - let hash = self.api.hash_and_length(&xt).0; - let watcher = self.listener.write().create_watcher(hash); - self.submit_one(at, xt)?; - Ok(watcher) + pub fn submit_and_watch( + &self, + at: &BlockId, + xt: ExtrinsicFor, + ) -> impl Future, BlockHash>, B::Error>> { + let block_number = match self.resolve_block_number(at) { + Ok(block_number) => block_number, + Err(err) => return Either::Left(ready(Err(err))) + }; + + let validated_pool = self.validated_pool.clone(); + Either::Right( + self.verify_one(at, block_number, xt, false) + .map(move |validated_transactions| validated_pool.submit_and_watch(validated_transactions)) + ) } /// Prunes ready transactions. @@ -226,41 +171,46 @@ impl Pool { /// To perform pruning we need the tags that each extrinsic provides and to avoid calling /// into runtime too often we first lookup all extrinsics that are in the pool and get /// their provided tags from there. Otherwise we query the runtime at the `parent` block. - pub fn prune(&self, at: &BlockId, parent: &BlockId, extrinsics: &[ExtrinsicFor]) -> Result<(), B::Error> { - let mut tags = Vec::with_capacity(extrinsics.len()); + pub fn prune( + &self, + at: &BlockId, + parent: &BlockId, + extrinsics: &[ExtrinsicFor], + ) -> impl Future> { // Get details of all extrinsics that are already in the pool - let hashes = extrinsics.iter().map(|extrinsic| self.api.hash_and_length(extrinsic).0).collect::>(); - let in_pool = self.pool.read().by_hash(&hashes); - { - // Zip the ones from the pool with the full list (we get pairs `(Extrinsic, Option)`) - let all = extrinsics.iter().zip(in_pool.iter()); - - for (extrinsic, existing_in_pool) in all { - match *existing_in_pool { + let (in_pool_hashes, in_pool_tags) = self.validated_pool.extrinsics_tags(extrinsics); + + // Zip the ones from the pool with the full list (we get pairs `(Extrinsic, Option>)`) + let all = extrinsics.iter().zip(in_pool_tags.into_iter()); + + // Prepare future that collect tags for all extrinsics + let future_tags = join_all(all + .map(|(extrinsic, in_pool_tags)| + match in_pool_tags { // reuse the tags for extrinsics that were found in the pool - Some(ref transaction) => { - tags.extend(transaction.provides.iter().cloned()); - }, + Some(tags) => Either::Left( + ready(tags) + ), // if it's not found in the pool query the runtime at parent block // to get validity info and tags that the extrinsic provides. - None => { - let validity = self.api.validate_transaction(parent, extrinsic.clone()); - match validity { - Ok(Ok(mut validity)) => { - tags.append(&mut validity.provides); - }, + None => Either::Right(self.validated_pool.api().validate_transaction(parent, extrinsic.clone()) + .then(|validity| ready(match validity { + Ok(Ok(validity)) => validity.provides, // silently ignore invalid extrinsics, // cause they might just be inherent - _ => {} - } - }, + _ => Vec::new(), + }))), } - } - } - - self.prune_tags(at, tags, in_pool.into_iter().filter_map(|x| x).map(|x| x.hash.clone()))?; - - Ok(()) + )); + + // Prune transactions by tags + let at = at.clone(); + let self_clone = self.clone(); + future_tags.then(move |tags| self_clone.prune_tags( + &at, + tags.into_iter().flat_map(|tags| tags), + in_pool_hashes, + )) } /// Prunes ready transactions that provide given list of tags. @@ -273,6 +223,9 @@ impl Pool { /// 1. Provide that tag directly /// 2. Are a dependency of pruned transaction. /// + /// Returns transactions that have been removed from the pool and must be reverified + /// before reinserting to the pool. + /// /// By removing predecessor transactions as well we might actually end up /// pruning too much, so all removed transactions are reverified against /// the runtime (`validate_transaction`) to make sure they are invalid. @@ -286,200 +239,183 @@ impl Pool { at: &BlockId, tags: impl IntoIterator, known_imported_hashes: impl IntoIterator> + Clone, - ) -> Result<(), B::Error> { - // Perform tag-based pruning in the base pool - let status = self.pool.write().prune_tags(tags); - // Notify event listeners of all transactions - // that were promoted to `Ready` or were dropped. - { - let mut listener = self.listener.write(); - for promoted in &status.promoted { - fire_events(&mut *listener, promoted); - } - for f in &status.failed { - listener.dropped(f, None); - } - } - // make sure that we don't revalidate extrinsics that were part of the recently + ) -> impl Future> { + // Prune all transactions that provide given tags + let prune_status = match self.validated_pool.prune_tags(tags) { + Ok(prune_status) => prune_status, + Err(e) => return Either::Left(ready(Err(e))), + }; + + // Make sure that we don't revalidate extrinsics that were part of the recently // imported block. This is especially important for UTXO-like chains cause the // inputs are pruned so such transaction would go to future again. - self.rotator.ban(&std::time::Instant::now(), known_imported_hashes.clone().into_iter()); + self.validated_pool.ban(&std::time::Instant::now(), known_imported_hashes.clone().into_iter()); - // try to re-submit pruned transactions since some of them might be still valid. + // Try to re-validate pruned transactions since some of them might be still valid. // note that `known_imported_hashes` will be rejected here due to temporary ban. - let hashes = status.pruned.iter().map(|tx| tx.hash.clone()).collect::>(); - let results = self.submit_at(at, status.pruned.into_iter().map(|tx| tx.data.clone()), false)?; - - // Collect the hashes of transactions that now became invalid (meaning that they are successfully pruned). - let hashes = results.into_iter().enumerate().filter_map(|(idx, r)| match r.map_err(error::IntoPoolError::into_pool_error) { - Err(Ok(error::Error::InvalidTransaction(_))) => Some(hashes[idx].clone()), - _ => None, - }); - // Fire `pruned` notifications for collected hashes and make sure to include - // `known_imported_hashes` since they were just imported as part of the block. - let hashes = hashes.chain(known_imported_hashes.into_iter()); - { - let header_hash = self.api.block_id_to_hash(at)? - .ok_or_else(|| error::Error::InvalidBlockId(format!("{:?}", at)).into())?; - let mut listener = self.listener.write(); - for h in hashes { - listener.pruned(header_hash, &h); - } - } - // perform regular cleanup of old transactions in the pool - // and update temporary bans. - self.clear_stale(at)?; - Ok(()) - } - - /// Removes stale transactions from the pool. - /// - /// Stale transactions are transaction beyond their longevity period. - /// Note this function does not remove transactions that are already included in the chain. - /// See `prune_tags` if you want this. - pub fn clear_stale(&self, at: &BlockId) -> Result<(), B::Error> { - let block_number = self.api.block_id_to_number(at)? - .ok_or_else(|| error::Error::InvalidBlockId(format!("{:?}", at)).into())? - .saturated_into::(); - let now = time::Instant::now(); - let to_remove = { - self.ready() - .filter(|tx| self.rotator.ban_if_stale(&now, block_number, &tx)) - .map(|tx| tx.hash.clone()) - .collect::>() - }; - let futures_to_remove: Vec> = { - let p = self.pool.read(); - let mut hashes = Vec::new(); - for tx in p.futures() { - if self.rotator.ban_if_stale(&now, block_number, &tx) { - hashes.push(tx.hash.clone()); - } - } - hashes - }; - // removing old transactions - self.remove_invalid(&to_remove); - self.remove_invalid(&futures_to_remove); - // clear banned transactions timeouts - self.rotator.clear_timeouts(&now); - - Ok(()) - } - - /// Create a new transaction pool. - pub fn new(options: Options, api: B) -> Self { - Pool { - api, - options, - listener: Default::default(), - pool: Default::default(), - import_notification_sinks: Default::default(), - rotator: Default::default(), - } + let pruned_hashes = prune_status.pruned.iter().map(|tx| tx.hash.clone()).collect::>(); + let pruned_transactions = prune_status.pruned.into_iter().map(|tx| tx.data.clone()); + let reverify_future = self.verify(at, pruned_transactions, false); + + // And finally - submit reverified transactions back to the pool + let at = at.clone(); + let validated_pool = self.validated_pool.clone(); + Either::Right(reverify_future.then(move |reverified_transactions| + ready(reverified_transactions.and_then(|reverified_transactions| + validated_pool.resubmit_pruned( + &at, + known_imported_hashes, + pruned_hashes, + reverified_transactions, + )) + ))) } /// Return an event stream of transactions imported to the pool. pub fn import_notification_stream(&self) -> EventStream { - let (sink, stream) = mpsc::unbounded(); - self.import_notification_sinks.lock().push(sink); - stream + self.validated_pool.import_notification_stream() } /// Invoked when extrinsics are broadcasted. pub fn on_broadcasted(&self, propagated: HashMap, Vec>) { - let mut listener = self.listener.write(); - for (hash, peers) in propagated.into_iter() { - listener.broadcasted(&hash, peers); - } + self.validated_pool.on_broadcasted(propagated) } /// Remove from the pool. pub fn remove_invalid(&self, hashes: &[ExHash]) -> Vec> { - // temporarily ban invalid transactions - debug!(target: "txpool", "Banning invalid transactions: {:?}", hashes); - self.rotator.ban(&time::Instant::now(), hashes.iter().cloned()); - - let invalid = self.pool.write().remove_invalid(hashes); - - let mut listener = self.listener.write(); - for tx in &invalid { - listener.invalid(&tx.hash); - } - - invalid + self.validated_pool.remove_invalid(hashes) } /// Get an iterator for ready transactions ordered by priority pub fn ready(&self) -> impl Iterator> { - self.pool.read().ready() + self.validated_pool.ready() } /// Returns pool status. pub fn status(&self) -> base::Status { - self.pool.read().status() + self.validated_pool.status() } /// Returns transaction hash pub fn hash_of(&self, xt: &ExtrinsicFor) -> ExHash { - self.api.hash_and_length(xt).0 + self.validated_pool.api().hash_and_length(xt).0 + } + + /// Resolves block number by id. + fn resolve_block_number(&self, at: &BlockId) -> Result, B::Error> { + self.validated_pool.api().block_id_to_number(at) + .and_then(|number| number.ok_or_else(|| + error::Error::InvalidBlockId(format!("{:?}", at)).into())) + } + + /// Returns future that validates a bunch of transactions at given block. + fn verify( + &self, + at: &BlockId, + xts: impl IntoIterator>, + force: bool, + ) -> impl Future>, B::Error>> { + // we need a block number to compute tx validity + let block_number = match self.resolve_block_number(at) { + Ok(block_number) => block_number, + Err(err) => return Either::Left(ready(Err(err))), + }; + + // for each xt, prepare a validation future + let validation_futures = xts.into_iter().map(move |xt| + self.verify_one(at, block_number, xt, force) + ); + + // make single validation future that waits all until all extrinsics are validated + Either::Right(join_all(validation_futures).then(|x| ready(Ok(x)))) + } + + /// Returns future that validates single transaction at given block. + fn verify_one( + &self, + block_id: &BlockId, + block_number: NumberFor, + xt: ExtrinsicFor, + force: bool, + ) -> impl Future> { + let (hash, bytes) = self.validated_pool.api().hash_and_length(&xt); + if !force && self.validated_pool.is_banned(&hash) { + return Either::Left(ready(ValidatedTransaction::Invalid(error::Error::TemporarilyBanned.into()))) + } + + Either::Right(self.validated_pool.api().validate_transaction(block_id, xt.clone()) + .then(move |validation_result| ready(match validation_result { + Ok(validity) => match validity { + Ok(validity) => if validity.provides.is_empty() { + ValidatedTransaction::Invalid(error::Error::NoTagsProvided.into()) + } else { + ValidatedTransaction::Valid(base::Transaction { + data: xt, + bytes, + hash, + priority: validity.priority, + requires: validity.requires, + provides: validity.provides, + propagate: validity.propagate, + valid_till: block_number + .saturated_into::() + .saturating_add(validity.longevity), + }) + }, + Err(TransactionValidityError::Invalid(e)) => + ValidatedTransaction::Invalid(error::Error::InvalidTransaction(e).into()), + Err(TransactionValidityError::Unknown(e)) => + ValidatedTransaction::Unknown(hash, error::Error::UnknownTransaction(e).into()), + }, + Err(e) => ValidatedTransaction::Invalid(e), + }))) } } -fn fire_events( - listener: &mut Listener, - imported: &base::Imported, -) where - H: hash::Hash + Eq + traits::Member + Serialize, - H2: Clone, -{ - match *imported { - base::Imported::Ready { ref promoted, ref failed, ref removed, ref hash } => { - listener.ready(hash, None); - for f in failed { - listener.invalid(f); - } - for r in removed { - listener.dropped(&r.hash, Some(hash)); - } - for p in promoted { - listener.ready(p, None); - } - }, - base::Imported::Future { ref hash } => { - listener.future(hash) - }, +impl Clone for Pool { + fn clone(&self) -> Self { + Self { + validated_pool: self.validated_pool.clone(), + } } } #[cfg(test)] mod tests { + use std::{ + collections::HashMap, + time::Instant, + }; + use parking_lot::Mutex; + use futures::executor::block_on; use super::*; use sr_primitives::transaction_validity::{ValidTransaction, InvalidTransaction}; use codec::Encode; use test_runtime::{Block, Extrinsic, Transfer, H256, AccountId}; use assert_matches::assert_matches; + use crate::base_pool::Limit; use crate::watcher; const INVALID_NONCE: u64 = 254; - #[derive(Debug, Default)] + #[derive(Clone, Debug, Default)] struct TestApi { - delay: Mutex>>, + delay: Arc>>>, } impl ChainApi for TestApi { type Block = Block; type Hash = u64; type Error = error::Error; + type ValidationFuture = futures::future::Ready>; /// Verify extrinsic at given block. fn validate_transaction( &self, at: &BlockId, uxt: ExtrinsicFor, - ) -> Result { - let block_number = self.block_id_to_number(at)?.unwrap(); + ) -> Self::ValidationFuture { + let block_number = self.block_id_to_number(at).unwrap().unwrap(); let nonce = uxt.transfer().nonce; // This is used to control the test flow. @@ -492,7 +428,7 @@ mod tests { } } - if nonce < block_number { + futures::future::ready(if nonce < block_number { Ok(InvalidTransaction::Stale.into()) } else { Ok(Ok(ValidTransaction { @@ -502,7 +438,7 @@ mod tests { longevity: 3, propagate: true, })) - } + }) } /// Returns a block number given the block id. @@ -546,12 +482,12 @@ mod tests { let pool = pool(); // when - let hash = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let hash = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 0, - })).unwrap(); + }))).unwrap(); // then assert_eq!(pool.ready().map(|v| v.hash).collect::>(), vec![hash]); @@ -569,8 +505,8 @@ mod tests { }); // when - pool.rotator.ban(&time::Instant::now(), vec![pool.hash_of(&uxt)]); - let res = pool.submit_one(&BlockId::Number(0), uxt); + pool.validated_pool.rotator().ban(&Instant::now(), vec![pool.hash_of(&uxt)]); + let res = block_on(pool.submit_one(&BlockId::Number(0), uxt)); assert_eq!(pool.status().ready, 0); assert_eq!(pool.status().future, 0); @@ -586,25 +522,25 @@ mod tests { let stream = pool.import_notification_stream(); // when - let _hash = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let _hash = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 0, - })).unwrap(); - let _hash = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + }))).unwrap(); + let _hash = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 1, - })).unwrap(); + }))).unwrap(); // future doesn't count - let _hash = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let _hash = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 3, - })).unwrap(); + }))).unwrap(); assert_eq!(pool.status().ready, 2); assert_eq!(pool.status().future, 1); @@ -622,54 +558,54 @@ mod tests { fn should_clear_stale_transactions() { // given let pool = pool(); - let hash1 = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let hash1 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 0, - })).unwrap(); - let hash2 = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + }))).unwrap(); + let hash2 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 1, - })).unwrap(); - let hash3 = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + }))).unwrap(); + let hash3 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 3, - })).unwrap(); + }))).unwrap(); // when - pool.clear_stale(&BlockId::Number(5)).unwrap(); + pool.validated_pool.clear_stale(&BlockId::Number(5)).unwrap(); // then assert_eq!(pool.ready().count(), 0); assert_eq!(pool.status().future, 0); assert_eq!(pool.status().ready, 0); // make sure they are temporarily banned as well - assert!(pool.rotator.is_banned(&hash1)); - assert!(pool.rotator.is_banned(&hash2)); - assert!(pool.rotator.is_banned(&hash3)); + assert!(pool.validated_pool.rotator().is_banned(&hash1)); + assert!(pool.validated_pool.rotator().is_banned(&hash2)); + assert!(pool.validated_pool.rotator().is_banned(&hash3)); } #[test] fn should_ban_mined_transactions() { // given let pool = pool(); - let hash1 = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let hash1 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 0, - })).unwrap(); + }))).unwrap(); // when - pool.prune_tags(&BlockId::Number(1), vec![vec![0]], vec![hash1.clone()]).unwrap(); + block_on(pool.prune_tags(&BlockId::Number(1), vec![vec![0]], vec![hash1.clone()])).unwrap(); // then - assert!(pool.rotator.is_banned(&hash1)); + assert!(pool.validated_pool.rotator().is_banned(&hash1)); } #[test] @@ -684,26 +620,26 @@ mod tests { future: limit.clone(), }, TestApi::default()); - let hash1 = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let hash1 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 1, - })).unwrap(); + }))).unwrap(); assert_eq!(pool.status().future, 1); // when - let hash2 = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let hash2 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(2)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 10, - })).unwrap(); + }))).unwrap(); // then assert_eq!(pool.status().future, 1); - assert!(pool.rotator.is_banned(&hash1)); - assert!(!pool.rotator.is_banned(&hash2)); + assert!(pool.validated_pool.rotator().is_banned(&hash1)); + assert!(!pool.validated_pool.rotator().is_banned(&hash2)); } #[test] @@ -719,12 +655,12 @@ mod tests { }, TestApi::default()); // when - pool.submit_one(&BlockId::Number(0), uxt(Transfer { + block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 1, - })).unwrap_err(); + }))).unwrap_err(); // then assert_eq!(pool.status().ready, 0); @@ -737,12 +673,12 @@ mod tests { let pool = pool(); // when - let err = pool.submit_one(&BlockId::Number(0), uxt(Transfer { + let err = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: INVALID_NONCE, - })).unwrap_err(); + }))).unwrap_err(); // then assert_eq!(pool.status().ready, 0); @@ -757,17 +693,17 @@ mod tests { fn should_trigger_ready_and_finalized() { // given let pool = pool(); - let watcher = pool.submit_and_watch(&BlockId::Number(0), uxt(Transfer { + let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 0, - })).unwrap(); + }))).unwrap(); assert_eq!(pool.status().ready, 1); assert_eq!(pool.status().future, 0); // when - pool.prune_tags(&BlockId::Number(2), vec![vec![0u8]], vec![]).unwrap(); + block_on(pool.prune_tags(&BlockId::Number(2), vec![vec![0u8]], vec![])).unwrap(); assert_eq!(pool.status().ready, 0); assert_eq!(pool.status().future, 0); @@ -782,17 +718,17 @@ mod tests { fn should_trigger_ready_and_finalized_when_pruning_via_hash() { // given let pool = pool(); - let watcher = pool.submit_and_watch(&BlockId::Number(0), uxt(Transfer { + let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 0, - })).unwrap(); + }))).unwrap(); assert_eq!(pool.status().ready, 1); assert_eq!(pool.status().future, 0); // when - pool.prune_tags(&BlockId::Number(2), vec![vec![0u8]], vec![2u64]).unwrap(); + block_on(pool.prune_tags(&BlockId::Number(2), vec![vec![0u8]], vec![2u64])).unwrap(); assert_eq!(pool.status().ready, 0); assert_eq!(pool.status().future, 0); @@ -807,22 +743,22 @@ mod tests { fn should_trigger_future_and_ready_after_promoted() { // given let pool = pool(); - let watcher = pool.submit_and_watch(&BlockId::Number(0), uxt(Transfer { + let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 1, - })).unwrap(); + }))).unwrap(); assert_eq!(pool.status().ready, 0); assert_eq!(pool.status().future, 1); // when - pool.submit_one(&BlockId::Number(0), uxt(Transfer { + block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 0, - })).unwrap(); + }))).unwrap(); assert_eq!(pool.status().ready, 2); // then @@ -841,11 +777,11 @@ mod tests { amount: 5, nonce: 0, }); - let watcher = pool.submit_and_watch(&BlockId::Number(0), uxt).unwrap(); + let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), uxt)).unwrap(); assert_eq!(pool.status().ready, 1); // when - pool.remove_invalid(&[*watcher.hash()]); + pool.validated_pool.remove_invalid(&[*watcher.hash()]); // then @@ -865,7 +801,7 @@ mod tests { amount: 5, nonce: 0, }); - let watcher = pool.submit_and_watch(&BlockId::Number(0), uxt).unwrap(); + let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), uxt)).unwrap(); assert_eq!(pool.status().ready, 1); // when @@ -899,7 +835,7 @@ mod tests { amount: 5, nonce: 0, }); - let watcher = pool.submit_and_watch(&BlockId::Number(0), xt).unwrap(); + let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), xt)).unwrap(); assert_eq!(pool.status().ready, 1); // when @@ -909,7 +845,7 @@ mod tests { amount: 4, nonce: 1, }); - pool.submit_one(&BlockId::Number(1), xt).unwrap(); + block_on(pool.submit_one(&BlockId::Number(1), xt)).unwrap(); assert_eq!(pool.status().ready, 1); // then @@ -925,7 +861,7 @@ mod tests { let (ready, is_ready) = std::sync::mpsc::sync_channel(0); let (tx, rx) = std::sync::mpsc::sync_channel(1); let mut api = TestApi::default(); - api.delay = Mutex::new(rx.into()); + api.delay = Arc::new(Mutex::new(rx.into())); let pool = Arc::new(Pool::new(Default::default(), api)); // when @@ -939,7 +875,7 @@ mod tests { // This transaction should go to future, since we use `nonce: 1` let pool2 = pool.clone(); std::thread::spawn(move || { - pool2.submit_one(&BlockId::Number(0), xt).unwrap(); + block_on(pool2.submit_one(&BlockId::Number(0), xt)).unwrap(); ready.send(()).unwrap(); }); @@ -953,11 +889,11 @@ mod tests { }); // The tag the above transaction provides (TestApi is using just nonce as u8) let provides = vec![0_u8]; - pool.submit_one(&BlockId::Number(0), xt).unwrap(); + block_on(pool.submit_one(&BlockId::Number(0), xt)).unwrap(); assert_eq!(pool.status().ready, 1); // Now block import happens before the second transaction is able to finish verification. - pool.prune_tags(&BlockId::Number(1), vec![provides], vec![]).unwrap(); + block_on(pool.prune_tags(&BlockId::Number(1), vec![provides], vec![])).unwrap(); assert_eq!(pool.status().ready, 0); diff --git a/core/transaction-pool/graph/src/validated_pool.rs b/core/transaction-pool/graph/src/validated_pool.rs new file mode 100644 index 0000000000..9bf1012628 --- /dev/null +++ b/core/transaction-pool/graph/src/validated_pool.rs @@ -0,0 +1,371 @@ +// Copyright 2018-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use std::{ + collections::{HashSet, HashMap}, + hash, + time, +}; + +use crate::base_pool as base; +use crate::error; +use crate::listener::Listener; +use crate::rotator::PoolRotator; +use crate::watcher::Watcher; +use serde::Serialize; +use log::debug; + +use futures::channel::mpsc; +use parking_lot::{Mutex, RwLock}; +use sr_primitives::{ + generic::BlockId, + traits::{self, SaturatedConversion}, + transaction_validity::TransactionTag as Tag, +}; + +use crate::base_pool::PruneStatus; +use crate::pool::{EventStream, Options, ChainApi, BlockHash, ExHash, ExtrinsicFor, TransactionFor}; + +/// Pre-validated transaction. Validated pool only accepts transactions wrapped in this enum. +#[derive(Debug)] +pub enum ValidatedTransaction { + /// Transaction that has been validated successfully. + Valid(base::Transaction), + /// Transaction that is invalid. + Invalid(Error), + /// Transaction which validity can't be determined. + /// + /// We're notifying watchers about failure, if 'unknown' transaction is submitted. + Unknown(Hash, Error), +} + +/// A type of validated transaction stored in the pool. +pub type ValidatedTransactionFor = ValidatedTransaction< + ExHash, + ExtrinsicFor, + ::Error, +>; + +/// Pool that deals with validated transactions. +pub(crate) struct ValidatedPool { + api: B, + options: Options, + listener: RwLock, BlockHash>>, + pool: RwLock, + ExtrinsicFor, + >>, + import_notification_sinks: Mutex>>, + rotator: PoolRotator>, +} + +impl ValidatedPool { + /// Create a new transaction pool. + pub fn new(options: Options, api: B) -> Self { + ValidatedPool { + api, + options, + listener: Default::default(), + pool: Default::default(), + import_notification_sinks: Default::default(), + rotator: Default::default(), + } + } + + /// Bans given set of hashes. + pub fn ban(&self, now: &std::time::Instant, hashes: impl IntoIterator>) { + self.rotator.ban(now, hashes) + } + + /// Returns true if transaction with given hash is currently banned from the pool. + pub fn is_banned(&self, hash: &ExHash) -> bool { + self.rotator.is_banned(hash) + } + + /// Imports a bunch of pre-validated transactions to the pool. + pub fn submit(&self, txs: T) -> Vec, B::Error>> where + T: IntoIterator> + { + let results = txs.into_iter() + .map(|validated_tx| self.submit_one(validated_tx)) + .collect::>(); + + let removed = self.enforce_limits(); + + results.into_iter().map(|res| match res { + Ok(ref hash) if removed.contains(hash) => Err(error::Error::ImmediatelyDropped.into()), + other => other, + }).collect() + } + + /// Submit single pre-validated transaction to the pool. + fn submit_one(&self, tx: ValidatedTransactionFor) -> Result, B::Error> { + match tx { + ValidatedTransaction::Valid(tx) => { + let imported = self.pool.write().import(tx)?; + + if let base::Imported::Ready { .. } = imported { + self.import_notification_sinks.lock().retain(|sink| sink.unbounded_send(()).is_ok()); + } + + let mut listener = self.listener.write(); + fire_events(&mut *listener, &imported); + Ok(imported.hash().clone()) + } + ValidatedTransaction::Invalid(err) => Err(err.into()), + ValidatedTransaction::Unknown(hash, err) => { + self.listener.write().invalid(&hash); + Err(err.into()) + } + } + } + + fn enforce_limits(&self) -> HashSet> { + let status = self.pool.read().status(); + let ready_limit = &self.options.ready; + let future_limit = &self.options.future; + + debug!(target: "txpool", "Pool Status: {:?}", status); + + if ready_limit.is_exceeded(status.ready, status.ready_bytes) + || future_limit.is_exceeded(status.future, status.future_bytes) { + // clean up the pool + let removed = { + let mut pool = self.pool.write(); + let removed = pool.enforce_limits(ready_limit, future_limit) + .into_iter().map(|x| x.hash.clone()).collect::>(); + // ban all removed transactions + self.rotator.ban(&std::time::Instant::now(), removed.iter().map(|x| x.clone())); + removed + }; + // run notifications + let mut listener = self.listener.write(); + for h in &removed { + listener.dropped(h, None); + } + + removed + } else { + Default::default() + } + } + + /// Import a single extrinsic and starts to watch their progress in the pool. + pub fn submit_and_watch( + &self, + tx: ValidatedTransactionFor, + ) -> Result, BlockHash>, B::Error> { + match tx { + ValidatedTransaction::Valid(tx) => { + let hash = self.api.hash_and_length(&tx.data).0; + let watcher = self.listener.write().create_watcher(hash); + self.submit(std::iter::once(ValidatedTransaction::Valid(tx))) + .pop() + .expect("One extrinsic passed; one result returned; qed") + .map(|_| watcher) + }, + ValidatedTransaction::Invalid(err) => Err(err.into()), + ValidatedTransaction::Unknown(_, err) => Err(err.into()), + } + } + + /// For each extrinsic, returns tags that it provides (if known), or None (if it is unknown). + pub fn extrinsics_tags(&self, extrinsics: &[ExtrinsicFor]) -> (Vec>, Vec>>) { + let hashes = extrinsics.iter().map(|extrinsic| self.api.hash_and_length(extrinsic).0).collect::>(); + let in_pool = self.pool.read().by_hash(&hashes); + ( + hashes, + in_pool.into_iter() + .map(|existing_in_pool| existing_in_pool + .map(|transaction| transaction.provides.iter().cloned() + .collect())) + .collect(), + ) + } + + /// Prunes ready transactions that provide given list of tags. + pub fn prune_tags( + &self, + tags: impl IntoIterator, + ) -> Result, ExtrinsicFor>, B::Error> { + // Perform tag-based pruning in the base pool + let status = self.pool.write().prune_tags(tags); + // Notify event listeners of all transactions + // that were promoted to `Ready` or were dropped. + { + let mut listener = self.listener.write(); + for promoted in &status.promoted { + fire_events(&mut *listener, promoted); + } + for f in &status.failed { + listener.dropped(f, None); + } + } + + Ok(status) + } + + /// Resubmit transactions that have been revalidated after prune_tags call. + pub fn resubmit_pruned( + &self, + at: &BlockId, + known_imported_hashes: impl IntoIterator> + Clone, + pruned_hashes: Vec>, + pruned_xts: Vec>, + ) -> Result<(), B::Error> { + debug_assert_eq!(pruned_hashes.len(), pruned_xts.len()); + + // Resubmit pruned transactions + let results = self.submit(pruned_xts); + + // Collect the hashes of transactions that now became invalid (meaning that they are successfully pruned). + let hashes = results + .into_iter() + .enumerate() + .filter_map(|(idx, r)| match r.map_err(error::IntoPoolError::into_pool_error) { + Err(Ok(error::Error::InvalidTransaction(_))) => Some(pruned_hashes[idx].clone()), + _ => None, + }); + // Fire `pruned` notifications for collected hashes and make sure to include + // `known_imported_hashes` since they were just imported as part of the block. + let hashes = hashes.chain(known_imported_hashes.into_iter()); + { + let header_hash = self.api.block_id_to_hash(at)? + .ok_or_else(|| error::Error::InvalidBlockId(format!("{:?}", at)).into())?; + let mut listener = self.listener.write(); + for h in hashes { + listener.pruned(header_hash, &h); + } + } + // perform regular cleanup of old transactions in the pool + // and update temporary bans. + self.clear_stale(at)?; + Ok(()) + } + + /// Removes stale transactions from the pool. + /// + /// Stale transactions are transaction beyond their longevity period. + /// Note this function does not remove transactions that are already included in the chain. + /// See `prune_tags` if you want this. + pub fn clear_stale(&self, at: &BlockId) -> Result<(), B::Error> { + let block_number = self.api.block_id_to_number(at)? + .ok_or_else(|| error::Error::InvalidBlockId(format!("{:?}", at)).into())? + .saturated_into::(); + let now = time::Instant::now(); + let to_remove = { + self.ready() + .filter(|tx| self.rotator.ban_if_stale(&now, block_number, &tx)) + .map(|tx| tx.hash.clone()) + .collect::>() + }; + let futures_to_remove: Vec> = { + let p = self.pool.read(); + let mut hashes = Vec::new(); + for tx in p.futures() { + if self.rotator.ban_if_stale(&now, block_number, &tx) { + hashes.push(tx.hash.clone()); + } + } + hashes + }; + // removing old transactions + self.remove_invalid(&to_remove); + self.remove_invalid(&futures_to_remove); + // clear banned transactions timeouts + self.rotator.clear_timeouts(&now); + + Ok(()) + } + + /// Get rotator reference. + #[cfg(test)] + pub fn rotator(&self) -> &PoolRotator> { + &self.rotator + } + + /// Get api reference. + pub fn api(&self) -> &B { + &self.api + } + + /// Return an event stream of transactions imported to the pool. + pub fn import_notification_stream(&self) -> EventStream { + let (sink, stream) = mpsc::unbounded(); + self.import_notification_sinks.lock().push(sink); + stream + } + + /// Invoked when extrinsics are broadcasted. + pub fn on_broadcasted(&self, propagated: HashMap, Vec>) { + let mut listener = self.listener.write(); + for (hash, peers) in propagated.into_iter() { + listener.broadcasted(&hash, peers); + } + } + + /// Remove from the pool. + pub fn remove_invalid(&self, hashes: &[ExHash]) -> Vec> { + // temporarily ban invalid transactions + debug!(target: "txpool", "Banning invalid transactions: {:?}", hashes); + self.rotator.ban(&time::Instant::now(), hashes.iter().cloned()); + + let invalid = self.pool.write().remove_invalid(hashes); + + let mut listener = self.listener.write(); + for tx in &invalid { + listener.invalid(&tx.hash); + } + + invalid + } + + /// Get an iterator for ready transactions ordered by priority + pub fn ready(&self) -> impl Iterator> { + self.pool.read().ready() + } + + /// Returns pool status. + pub fn status(&self) -> base::Status { + self.pool.read().status() + } +} + +fn fire_events( + listener: &mut Listener, + imported: &base::Imported, +) where + H: hash::Hash + Eq + traits::Member + Serialize, + H2: Clone, +{ + match *imported { + base::Imported::Ready { ref promoted, ref failed, ref removed, ref hash } => { + listener.ready(hash, None); + for f in failed { + listener.invalid(f); + } + for r in removed { + listener.dropped(&r.hash, Some(hash)); + } + for p in promoted { + listener.ready(p, None); + } + }, + base::Imported::Future { ref hash } => { + listener.future(hash) + }, + } +} diff --git a/core/transaction-pool/src/api.rs b/core/transaction-pool/src/api.rs index c0c4c787a5..96403bd3f8 100644 --- a/core/transaction-pool/src/api.rs +++ b/core/transaction-pool/src/api.rs @@ -37,24 +37,24 @@ use sr_primitives::{ use crate::error; /// The transaction pool logic -pub struct ChainApi { +pub struct FullChainApi { client: Arc, _marker: PhantomData, } -impl ChainApi where +impl FullChainApi where Block: traits::Block, T: traits::ProvideRuntimeApi + HeaderBackend { /// Create new transaction pool logic. pub fn new(client: Arc) -> Self { - ChainApi { + FullChainApi { client, _marker: Default::default() } } } -impl txpool::ChainApi for ChainApi where +impl txpool::ChainApi for FullChainApi where Block: traits::Block, T: traits::ProvideRuntimeApi + HeaderBackend, T::Api: TaggedTransactionQueue @@ -62,9 +62,14 @@ impl txpool::ChainApi for ChainApi where type Block = Block; type Hash = H256; type Error = error::Error; + type ValidationFuture = futures::future::Ready>; - fn validate_transaction(&self, at: &BlockId, uxt: txpool::ExtrinsicFor) -> error::Result { - Ok(self.client.runtime_api().validate_transaction(at, uxt)?) + fn validate_transaction( + &self, + at: &BlockId, + uxt: txpool::ExtrinsicFor, + ) -> Self::ValidationFuture { + futures::future::ready(self.client.runtime_api().validate_transaction(at, uxt).map_err(Into::into)) } fn block_id_to_number(&self, at: &BlockId) -> error::Result>> { diff --git a/core/transaction-pool/src/lib.rs b/core/transaction-pool/src/lib.rs index 1899c601b2..6938166299 100644 --- a/core/transaction-pool/src/lib.rs +++ b/core/transaction-pool/src/lib.rs @@ -25,5 +25,5 @@ mod tests; pub mod error; -pub use api::ChainApi; +pub use api::FullChainApi; pub use txpool; diff --git a/core/transaction-pool/src/tests.rs b/core/transaction-pool/src/tests.rs index 1661b7108b..d1ad27dd26 100644 --- a/core/transaction-pool/src/tests.rs +++ b/core/transaction-pool/src/tests.rs @@ -18,6 +18,7 @@ use super::*; use codec::Encode; +use futures::executor::block_on; use txpool::{self, Pool}; use test_client::{runtime::{AccountId, Block, Hash, Index, Extrinsic, Transfer}, AccountKeyring::{self, *}}; use sr_primitives::{ @@ -38,12 +39,13 @@ impl txpool::ChainApi for TestApi { type Block = Block; type Hash = Hash; type Error = error::Error; + type ValidationFuture = futures::future::Ready>; fn validate_transaction( &self, at: &BlockId, uxt: txpool::ExtrinsicFor, - ) -> error::Result { + ) -> Self::ValidationFuture { let expected = index(at); let requires = if expected == uxt.transfer().nonce { vec![] @@ -52,7 +54,7 @@ impl txpool::ChainApi for TestApi { }; let provides = vec![vec![uxt.transfer().nonce as u8]]; - Ok( + futures::future::ready(Ok( Ok(ValidTransaction { priority: 1, requires, @@ -60,7 +62,7 @@ impl txpool::ChainApi for TestApi { longevity: 64, propagate: true, }) - ) + )) } fn block_id_to_number(&self, at: &BlockId) -> error::Result>> { @@ -111,7 +113,7 @@ fn pool() -> Pool { fn submission_should_work() { let pool = pool(); assert_eq!(209, index(&BlockId::number(0))); - pool.submit_one(&BlockId::number(0), uxt(Alice, 209)).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap(); let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209]); @@ -120,8 +122,8 @@ fn submission_should_work() { #[test] fn multiple_submission_should_work() { let pool = pool(); - pool.submit_one(&BlockId::number(0), uxt(Alice, 209)).unwrap(); - pool.submit_one(&BlockId::number(0), uxt(Alice, 210)).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 210))).unwrap(); let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209, 210]); @@ -130,7 +132,7 @@ fn multiple_submission_should_work() { #[test] fn early_nonce_should_be_culled() { let pool = pool(); - pool.submit_one(&BlockId::number(0), uxt(Alice, 208)).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 208))).unwrap(); let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, Vec::::new()); @@ -140,11 +142,11 @@ fn early_nonce_should_be_culled() { fn late_nonce_should_be_queued() { let pool = pool(); - pool.submit_one(&BlockId::number(0), uxt(Alice, 210)).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 210))).unwrap(); let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, Vec::::new()); - pool.submit_one(&BlockId::number(0), uxt(Alice, 209)).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap(); let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209, 210]); } @@ -152,13 +154,13 @@ fn late_nonce_should_be_queued() { #[test] fn prune_tags_should_work() { let pool = pool(); - pool.submit_one(&BlockId::number(0), uxt(Alice, 209)).unwrap(); - pool.submit_one(&BlockId::number(0), uxt(Alice, 210)).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 210))).unwrap(); let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209, 210]); - pool.prune_tags(&BlockId::number(1), vec![vec![209]], vec![]).unwrap(); + block_on(pool.prune_tags(&BlockId::number(1), vec![vec![209]], vec![])).unwrap(); let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![210]); @@ -168,14 +170,14 @@ fn prune_tags_should_work() { fn should_ban_invalid_transactions() { let pool = pool(); let uxt = uxt(Alice, 209); - let hash = pool.submit_one(&BlockId::number(0), uxt.clone()).unwrap(); + let hash = block_on(pool.submit_one(&BlockId::number(0), uxt.clone())).unwrap(); pool.remove_invalid(&[hash]); - pool.submit_one(&BlockId::number(0), uxt.clone()).unwrap_err(); + block_on(pool.submit_one(&BlockId::number(0), uxt.clone())).unwrap_err(); // when let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, Vec::::new()); // then - pool.submit_one(&BlockId::number(0), uxt.clone()).unwrap_err(); + block_on(pool.submit_one(&BlockId::number(0), uxt.clone())).unwrap_err(); } diff --git a/node-template/src/service.rs b/node-template/src/service.rs index 843ccb7ee3..24b22082c5 100644 --- a/node-template/src/service.rs +++ b/node-template/src/service.rs @@ -42,7 +42,7 @@ macro_rules! new_full_start { Ok(substrate_client::LongestChain::new(backend.clone())) })? .with_transaction_pool(|config, client| - Ok(transaction_pool::txpool::Pool::new(config, transaction_pool::ChainApi::new(client))) + Ok(transaction_pool::txpool::Pool::new(config, transaction_pool::FullChainApi::new(client))) )? .with_import_queue(|_config, client, mut select_chain, _transaction_pool| { let select_chain = select_chain.take() @@ -187,7 +187,7 @@ pub fn new_light(config: Configuration(config: NodeConfiguration) LongestChain, NetworkStatus, NetworkService::Hash>, - TransactionPool>, + TransactionPool>, OffchainWorkers< ConcreteClient, >::OffchainStorage, @@ -275,7 +274,7 @@ pub fn new_light(config: NodeConfiguration) Ok(LongestChain::new(backend.clone())) })? .with_transaction_pool(|config, client| - Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) + Ok(TransactionPool::new(config, transaction_pool::FullChainApi::new(client))) )? .with_import_queue_and_fprb(|_config, client, backend, fetcher, _select_chain, _tx_pool| { let fetch_checker = fetcher diff --git a/node/rpc/Cargo.toml b/node/rpc/Cargo.toml index 1bf7bae384..c2cee10b3a 100644 --- a/node/rpc/Cargo.toml +++ b/node/rpc/Cargo.toml @@ -24,3 +24,4 @@ transaction_pool = { package = "substrate-transaction-pool", path = "../../core/ node-testing = { path = "../testing" } node-runtime = { path = "../runtime" } env_logger = "0.6" +futures03 = { package = "futures-preview", version = "=0.3.0-alpha.18" } diff --git a/node/rpc/src/accounts.rs b/node/rpc/src/accounts.rs index 9586b8b389..6c8e60736a 100644 --- a/node/rpc/src/accounts.rs +++ b/node/rpc/src/accounts.rs @@ -111,6 +111,7 @@ where mod tests { use super::*; + use futures03::executor::block_on; use node_runtime::{CheckedExtrinsic, Call, TimestampCall}; use codec::Decode; use node_testing::{ @@ -125,7 +126,7 @@ mod tests { // given let _ = env_logger::try_init(); let client = Arc::new(TestClientBuilder::new().build()); - let pool = Arc::new(Pool::new(Default::default(), transaction_pool::ChainApi::new(client.clone()))); + let pool = Arc::new(Pool::new(Default::default(), transaction_pool::FullChainApi::new(client.clone()))); let new_transaction = |extra| { let ex = CheckedExtrinsic { @@ -139,9 +140,9 @@ mod tests { }; // Populate the pool let ext0 = new_transaction(signed_extra(0, 0)); - pool.submit_one(&BlockId::number(0), ext0).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), ext0)).unwrap(); let ext1 = new_transaction(signed_extra(1, 0)); - pool.submit_one(&BlockId::number(0), ext1).unwrap(); + block_on(pool.submit_one(&BlockId::number(0), ext1)).unwrap(); let accounts = Accounts::new(client, pool); -- GitLab From 7fc0a91e8c82f5d55f44f1ad142d87f62b9112f9 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 1 Oct 2019 12:28:19 +0200 Subject: [PATCH 164/275] srml/authority-discovery: Abstract session key type (#3698) * srml/authority-discovery: Abstract session key type Previously `srml/authority-discovery` dependet on the `srml/im-online` session key type directly. With this patch `srml/authority-discovery` is generic over the session key type it is going to use, as long as it implements the RuntimeAppPublic trait. With this patch one can use the `srml/authority-discovery` module without the `srml/im-online` module. Next to the above, this patch configures `node/runtime` to use the babe session keys for the authority discovery module. * srml/authority-discovery: Fix line length * srml/authority-discovery/Cargo: Move babe to dev-dependencies * node/runtime: Bump implementation version * srml/authority-discovery: Add doc comment for authority discovery Trait --- Cargo.lock | 2 +- node/runtime/src/lib.rs | 16 ++++--- srml/authority-discovery/Cargo.toml | 15 +++--- srml/authority-discovery/src/lib.rs | 73 ++++++++++++++--------------- 4 files changed, 53 insertions(+), 53 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 41e8e69013..1d9d2f01b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3966,11 +3966,11 @@ dependencies = [ "sr-primitives 2.0.0", "sr-staking-primitives 2.0.0", "sr-std 2.0.0", - "srml-im-online 0.1.0", "srml-session 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", "substrate-application-crypto 2.0.0", + "substrate-consensus-babe-primitives 2.0.0", "substrate-primitives 2.0.0", ] diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index b7bb26ee00..87bf313ac4 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -29,7 +29,7 @@ use node_primitives::{ AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, Moment, Signature, ContractExecResult, }; -use babe_primitives::{AuthorityId as BabeId}; +use babe_primitives::{AuthorityId as BabeId, AuthoritySignature as BabeSignature}; use grandpa::fg_primitives; use client::{ block_builder::api::{self as block_builder_api, InherentData, CheckInherentsResult}, @@ -50,7 +50,7 @@ use elections::VoteIndex; use version::NativeVersion; use primitives::OpaqueMetadata; use grandpa::{AuthorityId as GrandpaId, AuthorityWeight as GrandpaWeight}; -use im_online::sr25519::{AuthorityId as ImOnlineId, AuthoritySignature as ImOnlineSignature}; +use im_online::sr25519::{AuthorityId as ImOnlineId}; use authority_discovery_primitives::{AuthorityId as EncodedAuthorityId, Signature as EncodedSignature}; use codec::{Encode, Decode}; use system::offchain::TransactionSubmitter; @@ -84,8 +84,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 167, - impl_version: 167, + spec_version: 168, + impl_version: 168, apis: RUNTIME_API_VERSIONS, }; @@ -437,7 +437,9 @@ impl offences::Trait for Runtime { type OnOffenceHandler = Staking; } -impl authority_discovery::Trait for Runtime {} +impl authority_discovery::Trait for Runtime { + type AuthorityId = BabeId; +} impl grandpa::Trait for Runtime { type Event = Event; @@ -635,12 +637,12 @@ impl_runtime_apis! { } fn verify(payload: &Vec, signature: &EncodedSignature, authority_id: &EncodedAuthorityId) -> bool { - let signature = match ImOnlineSignature::decode(&mut &signature.0[..]) { + let signature = match BabeSignature::decode(&mut &signature.0[..]) { Ok(s) => s, _ => return false, }; - let authority_id = match ImOnlineId::decode(&mut &authority_id.0[..]) { + let authority_id = match BabeId::decode(&mut &authority_id.0[..]) { Ok(id) => id, _ => return false, }; diff --git a/srml/authority-discovery/Cargo.toml b/srml/authority-discovery/Cargo.toml index 0657348457..e9647984ed 100644 --- a/srml/authority-discovery/Cargo.toml +++ b/srml/authority-discovery/Cargo.toml @@ -5,33 +5,32 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] +app-crypto = { package = "substrate-application-crypto", path = "../../core/application-crypto", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -sr-primitives = { path = "../../core/sr-primitives", default-features = false } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } -app-crypto = { package = "substrate-application-crypto", path = "../../core/application-crypto", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } serde = { version = "1.0", optional = true } session = { package = "srml-session", path = "../session", default-features = false } -im-online = { package = "srml-im-online", path = "../im-online", default-features = false } +sr-primitives = { path = "../../core/sr-primitives", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } -runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] +babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../core/consensus/babe/primitives", default-features = false } sr-staking-primitives = { path = "../../core/sr-staking-primitives", default-features = false } [features] default = ["std"] std = [ + "app-crypto/std", "codec/std", - "sr-primitives/std", "primitives/std", "rstd/std", + "runtime-io/std", "serde", "session/std", - "im-online/std", + "sr-primitives/std", "support/std", - "runtime-io/std", "system/std", - "app-crypto/std", ] diff --git a/srml/authority-discovery/src/lib.rs b/srml/authority-discovery/src/lib.rs index 7a4a104f1c..4f759ba38a 100644 --- a/srml/authority-discovery/src/lib.rs +++ b/srml/authority-discovery/src/lib.rs @@ -22,29 +22,29 @@ //! //! ## Dependencies //! -//! This module depends on the [I’m online module](../srml_im_online/index.html) -//! using its session key. +//! This module depends on an externally defined session key type, specified via +//! `Trait::AuthorityId` in the respective node runtime implementation. // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] use app_crypto::RuntimeAppPublic; +use codec::{Decode, Encode}; use rstd::prelude::*; use support::{decl_module, decl_storage}; -pub trait Trait: system::Trait + session::Trait + im_online::Trait {} - -type AuthorityIdFor = ::AuthorityId; -type AuthoritySignatureFor = - <::AuthorityId as RuntimeAppPublic>::Signature; +/// The module's config trait. +pub trait Trait: system::Trait + session::Trait { + type AuthorityId: RuntimeAppPublic + Default + Decode + Encode + PartialEq; +} decl_storage! { trait Store for Module as AuthorityDiscovery { /// The current set of keys that may issue a heartbeat. - Keys get(keys): Vec>; + Keys get(keys): Vec; } add_extra_genesis { - config(keys): Vec>; + config(keys): Vec; build(|config| Module::::initialize_keys(&config.keys)) } } @@ -59,10 +59,10 @@ impl Module { /// set, otherwise this function returns None. The restriction might be /// softened in the future in case a consumer needs to learn own authority /// identifier. - fn authority_id() -> Option> { + fn authority_id() -> Option { let authorities = Keys::::get(); - let local_keys = >::all(); + let local_keys = T::AuthorityId::all(); authorities.into_iter().find_map(|authority| { if local_keys.contains(&authority) { @@ -74,12 +74,17 @@ impl Module { } /// Retrieve authority identifiers of the current authority set. - pub fn authorities() -> Vec> { + pub fn authorities() -> Vec { Keys::::get() } /// Sign the given payload with the private key corresponding to the given authority id. - pub fn sign(payload: &Vec) -> Option<(AuthoritySignatureFor, AuthorityIdFor)> { + pub fn sign( + payload: &Vec, + ) -> Option<( + <::AuthorityId as RuntimeAppPublic>::Signature, + T::AuthorityId, + )> { let authority_id = Module::::authority_id()?; authority_id.sign(payload).map(|s| (s, authority_id)) } @@ -88,13 +93,13 @@ impl Module { /// authority identifier. pub fn verify( payload: &Vec, - signature: AuthoritySignatureFor, - authority_id: AuthorityIdFor, + signature: <::AuthorityId as RuntimeAppPublic>::Signature, + authority_id: T::AuthorityId, ) -> bool { authority_id.verify(payload, &signature) } - fn initialize_keys(keys: &[AuthorityIdFor]) { + fn initialize_keys(keys: &[T::AuthorityId]) { if !keys.is_empty() { assert!(Keys::::get().is_empty(), "Keys are already initialized!"); Keys::::put_ref(keys); @@ -103,7 +108,7 @@ impl Module { } impl session::OneSessionHandler for Module { - type Key = AuthorityIdFor; + type Key = T::AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) where @@ -144,9 +149,11 @@ mod tests { #[derive(Clone, Eq, PartialEq)] pub struct Test; - impl Trait for Test {} + impl Trait for Test { + type AuthorityId = babe_primitives::AuthorityId; + } - type AuthorityId = im_online::sr25519::AuthorityId; + type AuthorityId = babe_primitives::AuthorityId; pub struct TestOnSessionEnding; impl session::OnSessionEnding for TestOnSessionEnding { @@ -176,18 +183,6 @@ mod tests { type FullIdentificationOf = (); } - impl im_online::Trait for Test { - type AuthorityId = AuthorityId; - type Call = im_online::Call; - type Event = (); - type SubmitTransaction = system::offchain::TransactionSubmitter< - (), - im_online::Call, - UncheckedExtrinsic<(), im_online::Call, (), ()>, - >; - type ReportUnresponsiveness = (); - } - pub type BlockNumber = u64; parameter_types! { @@ -243,13 +238,13 @@ mod tests { let key_store = KeyStore::new(); key_store .write() - .sr25519_generate_new(key_types::IM_ONLINE, None) + .sr25519_generate_new(key_types::BABE, None) .expect("Generates key."); // Retrieve key to later check if we got the right one. let public_key = key_store .read() - .sr25519_public_keys(key_types::IM_ONLINE) + .sr25519_public_keys(key_types::BABE) .pop() .unwrap(); let authority_id = AuthorityId::from(public_key); @@ -283,7 +278,7 @@ mod tests { let key_store = KeyStore::new(); key_store .write() - .sr25519_generate_new(key_types::IM_ONLINE, None) + .sr25519_generate_new(key_types::BABE, None) .expect("Generates key."); // Build genesis. @@ -317,13 +312,13 @@ mod tests { let key_store = KeyStore::new(); key_store .write() - .sr25519_generate_new(key_types::IM_ONLINE, None) + .sr25519_generate_new(key_types::BABE, None) .expect("Generates key."); // Retrieve key to later check if we got the right one. let public_key = key_store .read() - .sr25519_public_keys(key_types::IM_ONLINE) + .sr25519_public_keys(key_types::BABE) .pop() .unwrap(); let authority_id = AuthorityId::from(public_key); @@ -347,7 +342,11 @@ mod tests { let payload = String::from("test payload").into_bytes(); let (sig, authority_id) = AuthorityDiscovery::sign(&payload).expect("signature"); - assert!(AuthorityDiscovery::verify(&payload, sig.clone(), authority_id.clone(),)); + assert!(AuthorityDiscovery::verify( + &payload, + sig.clone(), + authority_id.clone(), + )); assert!(!AuthorityDiscovery::verify( &String::from("other payload").into_bytes(), -- GitLab From a61b592a85e78ef51a7f33125cf3c3ed22cc6bbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 1 Oct 2019 17:00:22 +0200 Subject: [PATCH 165/275] Let `construct_runtime!` generate `ALL_MODULES` as nested tuples (#3732) So, instead of: `type ALL_MODULES = (Module1, Module2, Module3)`; Generate it like this: `type ALL_MODULES = ((Module1, Module2), Module3,);` This should make `construct_runtime!` support an "unlimited" number of modules. --- srml/sudo/src/lib.rs | 2 +- srml/support/src/runtime.rs | 30 +++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/srml/sudo/src/lib.rs b/srml/sudo/src/lib.rs index 2a733ccb2e..c4e13eefe2 100644 --- a/srml/sudo/src/lib.rs +++ b/srml/sudo/src/lib.rs @@ -90,7 +90,7 @@ use rstd::prelude::*; use sr_primitives::{ traits::{StaticLookup, Dispatchable}, weights::SimpleDispatchInfo, DispatchError, }; -use support::{StorageValue, Parameter, decl_module, decl_event, decl_storage, ensure}; +use support::{Parameter, decl_module, decl_event, decl_storage, ensure}; use system::ensure_signed; pub trait Trait: system::Trait { diff --git a/srml/support/src/runtime.rs b/srml/support/src/runtime.rs index 6c5eccb125..491252ce70 100644 --- a/srml/support/src/runtime.rs +++ b/srml/support/src/runtime.rs @@ -220,6 +220,7 @@ macro_rules! construct_runtime { $runtime; ; {}; + {}; $( $name: $module:: $( < $module_instance >:: )? { $( $modules ),* }, )* @@ -434,6 +435,7 @@ macro_rules! __decl_all_modules { $runtime:ident; ; { $( $parsed:tt )* }; + { $( $parsed_nested:tt )* }; System: $module:ident::{ Module $(, $modules:ident )* }, $( $rest:tt )* ) => { @@ -441,6 +443,26 @@ macro_rules! __decl_all_modules { $runtime; $module; { $( $parsed )* }; + { $( $parsed_nested )* }; + $( $rest )* + ); + }; + ( + $runtime:ident; + $( $system:ident )?; + { $( $parsed:tt )* }; + {}; + $name:ident: $module:ident:: $( < $module_instance:ident >:: )? { Module $(, $modules:ident )* }, + $( $rest:tt )* + ) => { + $crate::__decl_all_modules!( + $runtime; + $( $system )?; + { + $( $parsed )* + $module::$name $(<$module_instance>)?, + }; + { $name }; $( $rest )* ); }; @@ -448,6 +470,7 @@ macro_rules! __decl_all_modules { $runtime:ident; $( $system:ident )?; { $( $parsed:tt )* }; + { $( $parsed_nested:tt )* }; $name:ident: $module:ident:: $( < $module_instance:ident >:: )? { Module $(, $modules:ident )* }, $( $rest:tt )* ) => { @@ -458,6 +481,7 @@ macro_rules! __decl_all_modules { $( $parsed )* $module::$name $(<$module_instance>)?, }; + { ( $( $parsed_nested )*, $name, ) }; $( $rest )* ); }; @@ -465,6 +489,7 @@ macro_rules! __decl_all_modules { $runtime:ident; $( $system:ident )?; { $( $parsed:tt )* }; + { $( $parsed_nested:tt )* }; $name:ident: $module:ident:: $( < $module_instance:ident >:: )? { $ignore:ident $(, $modules:ident )* }, $( $rest:tt )* ) => { @@ -472,6 +497,7 @@ macro_rules! __decl_all_modules { $runtime; $( $system )?; { $( $parsed )* }; + { $( $parsed_nested )* }; $name: $module::{ $( $modules ),* }, $( $rest )* ); @@ -487,6 +513,7 @@ macro_rules! __decl_all_modules { $runtime; $( $system )?; { $( $parsed )* }; + { $( $parsed_nested )* }; $( $rest )* ); }; @@ -494,12 +521,13 @@ macro_rules! __decl_all_modules { $runtime:ident; $system:ident; { $( $parsed_module:ident :: $parsed_name:ident $(<$instance:ident>)? ,)*}; + { $( $parsed_nested:tt )* }; ) => { pub type System = system::Module<$runtime>; $( pub type $parsed_name = $parsed_module::Module<$runtime $(, $parsed_module::$instance )?>; )* - type AllModules = ( $( $parsed_name, )* ); + type AllModules = ( $( $parsed_nested )* ); } } -- GitLab From dd1460dd3546d3d9ee1af98faebca24d73545158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Tue, 1 Oct 2019 16:42:11 +0100 Subject: [PATCH 166/275] grandpa: add identifier to UntilImported logging message (#3735) * grandpa: add identifier to UntilImported logging * grandpa: fix tests --- core/finality-grandpa/src/environment.rs | 1 + core/finality-grandpa/src/lib.rs | 1 + core/finality-grandpa/src/until_imported.rs | 8 +++++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/core/finality-grandpa/src/environment.rs b/core/finality-grandpa/src/environment.rs index 502d201b94..5e3abb3ac7 100644 --- a/core/finality-grandpa/src/environment.rs +++ b/core/finality-grandpa/src/environment.rs @@ -587,6 +587,7 @@ where self.inner.import_notification_stream(), self.inner.clone(), incoming, + "round", ).map_err(Into::into)); // schedule network message cleanup when sink drops. diff --git a/core/finality-grandpa/src/lib.rs b/core/finality-grandpa/src/lib.rs index 4dc93c381f..e4b71acbec 100644 --- a/core/finality-grandpa/src/lib.rs +++ b/core/finality-grandpa/src/lib.rs @@ -427,6 +427,7 @@ fn global_communication, B, E, N, RA>( client.import_notification_stream(), client.clone(), global_in, + "global", ); let global_in = global_in.map_err(CommandOrError::from); diff --git a/core/finality-grandpa/src/until_imported.rs b/core/finality-grandpa/src/until_imported.rs index 4232bfacdf..b8568c1f85 100644 --- a/core/finality-grandpa/src/until_imported.rs +++ b/core/finality-grandpa/src/until_imported.rs @@ -71,6 +71,7 @@ pub(crate) struct UntilImported, check_pending: Interval, pending: HashMap)>, + identifier: &'static str, } impl UntilImported @@ -81,6 +82,7 @@ impl UntilImported import_notifications: ImportNotifications, status_check: Status, stream: I, + identifier: &'static str, ) -> Self { // how often to check if pending messages that are waiting for blocks to be // imported can be checked. @@ -101,6 +103,7 @@ impl UntilImported ready: VecDeque::new(), check_pending, pending: HashMap::new(), + identifier, } } } @@ -170,8 +173,9 @@ impl Stream for UntilImported if Instant::now() <= next_log { debug!( target: "afg", - "Waiting to import block {} before {} votes can be imported. \ + "Waiting to import block {} before {} {} messages can be imported. \ Possible fork?", + self.identifier, block_hash, v.len(), ); @@ -533,6 +537,7 @@ mod tests { import_notifications, block_status, global_rx.map_err(|_| panic!("should never error")), + "global", ); global_tx.unbounded_send(msg).unwrap(); @@ -558,6 +563,7 @@ mod tests { import_notifications, block_status, global_rx.map_err(|_| panic!("should never error")), + "global", ); global_tx.unbounded_send(msg).unwrap(); -- GitLab From db417ffda057dc314c0fb4e1ef1b197e07b31fa1 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 1 Oct 2019 19:45:24 +0200 Subject: [PATCH 167/275] Use EncodeLike for storages traits (#3676) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * impl * patch * lock * some refactor * some avoided copy * new api without ref for doublemap * fix * version bump * fix * point to incoming release * use codec latest * bumpd impl version * fix unused * fix * Update srml/support/src/storage/mod.rs Co-Authored-By: Bastian Köcher --- Cargo.lock | 196 ++++++++--------- core/primitives/Cargo.toml | 2 +- core/sr-primitives/Cargo.toml | 2 +- .../src/generic/unchecked_extrinsic.rs | 17 +- node/runtime/src/lib.rs | 2 +- srml/assets/src/lib.rs | 4 +- srml/aura/src/lib.rs | 2 +- srml/authority-discovery/src/lib.rs | 6 +- srml/babe/src/lib.rs | 4 +- srml/collective/src/lib.rs | 4 +- srml/contracts/src/wasm/code_cache.rs | 2 +- srml/democracy/src/lib.rs | 18 +- srml/elections-phragmen/src/lib.rs | 2 +- srml/elections/src/lib.rs | 6 +- srml/grandpa/src/lib.rs | 2 +- srml/im-online/src/lib.rs | 2 +- srml/scored-pool/src/lib.rs | 4 +- srml/session/src/lib.rs | 6 +- srml/staking/src/lib.rs | 4 +- srml/support/Cargo.toml | 2 +- .../procedural/src/storage/transformation.rs | 18 +- srml/support/src/dispatch.rs | 10 +- srml/support/src/lib.rs | 4 +- srml/support/src/storage/child.rs | 3 +- .../src/storage/generator/double_map.rs | 124 +++++------ .../src/storage/generator/linked_map.rs | 143 ++++++------ srml/support/src/storage/generator/map.rs | 71 +++--- srml/support/src/storage/generator/value.rs | 43 ++-- srml/support/src/storage/mod.rs | 203 +++++++++--------- srml/support/src/storage/storage_items.rs | 15 +- srml/support/src/storage/unhashed.rs | 3 +- srml/support/src/traits.rs | 8 +- srml/support/test/tests/final_keys.rs | 4 +- srml/support/test/tests/genesisconfig.rs | 2 +- srml/support/test/tests/instance.rs | 12 +- srml/support/test/tests/system.rs | 6 +- 36 files changed, 490 insertions(+), 466 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1d9d2f01b9..af05d52d2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -860,7 +860,7 @@ dependencies = [ "hashmap_core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -917,7 +917,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "fork-tree" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1365,10 +1365,10 @@ dependencies = [ [[package]] name = "impl-codec" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1382,7 +1382,7 @@ dependencies = [ [[package]] name = "impl-serde" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2352,7 +2352,7 @@ dependencies = [ "node-primitives 2.0.0", "node-rpc 2.0.0", "node-runtime 2.0.0", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -2401,7 +2401,7 @@ dependencies = [ "node-primitives 2.0.0", "node-runtime 2.0.0", "node-testing 2.0.0", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "srml-balances 2.0.0", @@ -2426,7 +2426,7 @@ dependencies = [ name = "node-primitives" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -2450,7 +2450,7 @@ dependencies = [ "node-primitives 2.0.0", "node-runtime 2.0.0", "node-testing 2.0.0", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", @@ -2479,7 +2479,7 @@ version = "2.0.0" dependencies = [ "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2530,7 +2530,7 @@ dependencies = [ "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "node-template-runtime 2.0.0", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "substrate-basic-authorship 2.0.0", @@ -2555,7 +2555,7 @@ dependencies = [ name = "node-template-runtime" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -2586,7 +2586,7 @@ dependencies = [ "node-executor 2.0.0", "node-primitives 2.0.0", "node-runtime 2.0.0", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "srml-balances 2.0.0", @@ -2786,19 +2786,19 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "bitvec 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "byte-slice-cast 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec-derive 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec-derive 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parity-scale-codec-derive" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3023,12 +3023,12 @@ dependencies = [ [[package]] name = "primitive-types" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fixed-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-codec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-codec 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "uint 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3425,7 +3425,7 @@ dependencies = [ "error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3828,7 +3828,7 @@ version = "2.0.0" dependencies = [ "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3851,7 +3851,7 @@ dependencies = [ "environmental 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "libsecp256k1 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", "substrate-offchain 2.0.0", @@ -3869,9 +3869,9 @@ dependencies = [ "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3886,7 +3886,7 @@ name = "sr-sandbox" version = "2.0.0" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", "substrate-primitives 2.0.0", @@ -3898,7 +3898,7 @@ dependencies = [ name = "sr-staking-primitives" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", ] @@ -3915,7 +3915,7 @@ name = "sr-version" version = "2.0.0" dependencies = [ "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -3925,7 +3925,7 @@ dependencies = [ name = "srml-assets" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -3940,7 +3940,7 @@ name = "srml-aura" version = "2.0.0" dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -3960,7 +3960,7 @@ dependencies = [ name = "srml-authority-discovery" version = "0.1.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -3979,7 +3979,7 @@ name = "srml-authorship" version = "0.1.0" dependencies = [ "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -3995,7 +3995,7 @@ version = "2.0.0" dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4017,7 +4017,7 @@ dependencies = [ name = "srml-balances" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4034,7 +4034,7 @@ name = "srml-collective" version = "2.0.0" dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4053,7 +4053,7 @@ dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.40.2 (registry+https://github.com/rust-lang/crates.io-index)", "pwasm-utils 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4074,7 +4074,7 @@ dependencies = [ name = "srml-democracy" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4091,7 +4091,7 @@ name = "srml-elections" version = "2.0.0" dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4108,7 +4108,7 @@ name = "srml-elections-phragmen" version = "2.0.0" dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4124,7 +4124,7 @@ dependencies = [ name = "srml-example" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4140,7 +4140,7 @@ name = "srml-executive" version = "2.0.0" dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4157,7 +4157,7 @@ name = "srml-finality-tracker" version = "2.0.0" dependencies = [ "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4172,7 +4172,7 @@ dependencies = [ name = "srml-generic-asset" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4186,7 +4186,7 @@ dependencies = [ name = "srml-grandpa" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4204,7 +4204,7 @@ dependencies = [ name = "srml-im-online" version = "0.1.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4222,7 +4222,7 @@ dependencies = [ name = "srml-indices" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4239,7 +4239,7 @@ dependencies = [ name = "srml-membership" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4253,7 +4253,7 @@ dependencies = [ name = "srml-metadata" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", "substrate-primitives 2.0.0", @@ -4263,7 +4263,7 @@ dependencies = [ name = "srml-offences" version = "1.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4279,7 +4279,7 @@ dependencies = [ name = "srml-scored-pool" version = "1.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4296,7 +4296,7 @@ version = "2.0.0" dependencies = [ "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4315,7 +4315,7 @@ dependencies = [ name = "srml-staking" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4349,7 +4349,7 @@ dependencies = [ name = "srml-sudo" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4366,7 +4366,7 @@ dependencies = [ "bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4415,7 +4415,7 @@ dependencies = [ name = "srml-support-test" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4431,7 +4431,7 @@ version = "2.0.0" dependencies = [ "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4447,7 +4447,7 @@ name = "srml-timestamp" version = "2.0.0" dependencies = [ "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4462,7 +4462,7 @@ dependencies = [ name = "srml-treasury" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4554,7 +4554,7 @@ dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", "node-runtime 2.0.0", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -4579,7 +4579,7 @@ dependencies = [ name = "substrate-application-crypto" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4597,7 +4597,7 @@ dependencies = [ "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "prost-build 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4617,7 +4617,7 @@ dependencies = [ name = "substrate-authority-discovery-primitives" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", "substrate-client 2.0.0", @@ -4629,7 +4629,7 @@ version = "2.0.0" dependencies = [ "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", "substrate-consensus-common 2.0.0", @@ -4724,7 +4724,7 @@ dependencies = [ "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", "kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-api-macros 2.0.0", "sr-primitives 2.0.0", @@ -4754,7 +4754,7 @@ dependencies = [ "kvdb-rocksdb 0.1.4 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", @@ -4778,7 +4778,7 @@ dependencies = [ "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4807,7 +4807,7 @@ dependencies = [ name = "substrate-consensus-aura-primitives" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", "substrate-application-crypto 2.0.0", @@ -4828,7 +4828,7 @@ dependencies = [ "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "pdqselect 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4861,7 +4861,7 @@ dependencies = [ name = "substrate-consensus-babe-primitives" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4879,7 +4879,7 @@ dependencies = [ "futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -4895,7 +4895,7 @@ version = "2.0.0" dependencies = [ "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "srml-timestamp 2.0.0", "substrate-client 2.0.0", @@ -4923,7 +4923,7 @@ dependencies = [ "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rhododendron 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4946,7 +4946,7 @@ dependencies = [ "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", @@ -4980,7 +4980,7 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libsecp256k1 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.40.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -5009,7 +5009,7 @@ dependencies = [ "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5036,7 +5036,7 @@ dependencies = [ name = "substrate-finality-grandpa-primitives" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -5048,7 +5048,7 @@ dependencies = [ name = "substrate-inherents" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", @@ -5100,7 +5100,7 @@ dependencies = [ "linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "quickcheck 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5141,7 +5141,7 @@ dependencies = [ "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -5213,10 +5213,10 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5243,7 +5243,7 @@ dependencies = [ "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -5274,7 +5274,7 @@ dependencies = [ "jsonrpc-derive 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5340,7 +5340,7 @@ dependencies = [ "node-primitives 2.0.0", "node-runtime 2.0.0", "parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5409,7 +5409,7 @@ version = "2.0.0" dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-primitives 2.0.0", ] @@ -5422,7 +5422,7 @@ dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-panic-handler 2.0.0", @@ -5459,7 +5459,7 @@ version = "2.0.0" dependencies = [ "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", "substrate-client-db 2.0.0", @@ -5477,7 +5477,7 @@ dependencies = [ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -5509,7 +5509,7 @@ dependencies = [ name = "substrate-test-runtime-client" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-primitives 2.0.0", "substrate-test-client 2.0.0", @@ -5525,7 +5525,7 @@ dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -5540,7 +5540,7 @@ dependencies = [ "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", @@ -5559,7 +5559,7 @@ dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", "substrate-primitives 2.0.0", "trie-bench 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5977,7 +5977,7 @@ name = "transaction-factory" version = "0.0.1" dependencies = [ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-cli 2.0.0", "substrate-client 2.0.0", @@ -5995,7 +5995,7 @@ dependencies = [ "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "trie-standardmap 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6712,9 +6712,9 @@ dependencies = [ "checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" "checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" -"checksum impl-codec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "78c441b3d2b5e24b407161e76d482b7bbd29b5da357707839ac40d95152f031f" +"checksum impl-codec 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3fa0086251524c50fd53b32e7b05eb6d79e2f97221eaf0c53c0ca9c3096f21d3" "checksum impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5158079de9d4158e0ce1de3ae0bd7be03904efc40b3d7dd8b8c301cbf6b52b56" -"checksum impl-serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d26be4b97d738552ea423f76c4f681012ff06c3fa36fa968656b3679f60b4a1" +"checksum impl-serde 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bbb1ea6188aca47a0eaeeb330d8a82f16cd500f30b897062d23922568727333a" "checksum impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0df44cb13008e863c3d80788d5f4cb0f94d09b31bb0190a8ecc05151b2ac8a" "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" "checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" @@ -6817,8 +6817,8 @@ dependencies = [ "checksum parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" "checksum parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "045b3c7af871285146300da35b1932bb6e4639b66c7c98e85d06a32cbc4e8fa7" "checksum parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df3a17dc27848fd99e4f87eb0f8c9baba6ede0a6d555400c850ca45254ef4ce3" -"checksum parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "65582b5c02128a4b0fa60fb3e070216e9c84be3e4a8f1b74bc37e15a25e58daf" -"checksum parity-scale-codec-derive 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a81f3cd93ed368a8e41c4e79538e99ca6e8f536096de23e3a0bc3e782093ce28" +"checksum parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "001fbbb956d8593f321c7a784f64d16b2c99b2657823976eea729006ad2c3668" +"checksum parity-scale-codec-derive 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42af752f59119656fa3cb31e8852ed24e895b968c0bdb41847da7f0cea6d155f" "checksum parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" "checksum parity-util-mem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2005637ccf93dbb60c85081ccaaf3f945f573da48dcc79f27f9646caa3ec1dc" "checksum parity-wasm 0.40.2 (registry+https://github.com/rust-lang/crates.io-index)" = "49d1e33551976be5345d2ecbfe995830719746c7f0902f0880a13d40e215f851" @@ -6844,7 +6844,7 @@ dependencies = [ "checksum pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c1d2cfa5a714db3b5f24f0915e74fcdf91d09d496ba61329705dda7774d2af" "checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" "checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427" -"checksum primitive-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e44400d651ca5276415dc8e00541c5c9d03844f1f0a87ad28f0a8fadcb2300bc" +"checksum primitive-types 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "83ef7b3b965c0eadcb6838f34f827e1dfb2939bdd5ebd43f9647e009b12b0371" "checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" "checksum proc-macro-hack 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "982a35d1194084ba319d65c4a68d24ca28f5fdb5b8bc20899e4eef8641ea5178" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" diff --git a/core/primitives/Cargo.toml b/core/primitives/Cargo.toml index f05907e3f2..b94fa39bd0 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -11,7 +11,7 @@ rustc-hex = { version = "2.0", default-features = false } serde = { version = "1.0", optional = true, features = ["derive"] } twox-hash = { version = "1.2.0", optional = true } byteorder = { version = "1.3.1", default-features = false } -primitive-types = { version = "0.5.0", default-features = false, features = ["codec"] } +primitive-types = { version = "0.5.1", default-features = false, features = ["codec"] } impl-serde = { version = "0.1", optional = true } log = { version = "0.4", optional = true } wasmi = { version = "0.5.0", optional = true } diff --git a/core/sr-primitives/Cargo.toml b/core/sr-primitives/Cargo.toml index db1819c3e6..271ed2dccc 100644 --- a/core/sr-primitives/Cargo.toml +++ b/core/sr-primitives/Cargo.toml @@ -20,7 +20,7 @@ impl-trait-for-tuples = "0.1.1" [dev-dependencies] serde_json = "1.0" -primitive-types = "0.5.0" +primitive-types = "0.5.1" rand = "0.7.2" [features] diff --git a/core/sr-primitives/src/generic/unchecked_extrinsic.rs b/core/sr-primitives/src/generic/unchecked_extrinsic.rs index 48614946d6..c5ee76e21c 100644 --- a/core/sr-primitives/src/generic/unchecked_extrinsic.rs +++ b/core/sr-primitives/src/generic/unchecked_extrinsic.rs @@ -21,7 +21,7 @@ use std::fmt; use rstd::prelude::*; use runtime_io::blake2_256; -use codec::{Decode, Encode, Input, Error}; +use codec::{Decode, Encode, EncodeLike, Input, Error}; use crate::{ traits::{self, Member, MaybeDisplay, SignedExtension, Checkable, Extrinsic}, generic::CheckedExtrinsic, transaction_validity::{TransactionValidityError, InvalidTransaction}, @@ -185,6 +185,12 @@ impl Encode for SignedPayload where } } +impl EncodeLike for SignedPayload +where + Call: Encode, + Extra: SignedExtension, +{} + impl Decode for UncheckedExtrinsic where @@ -240,6 +246,15 @@ where } } +impl EncodeLike + for UncheckedExtrinsic +where + Address: Encode, + Signature: Encode, + Call: Encode, + Extra: SignedExtension, +{} + #[cfg(feature = "std")] impl serde::Serialize for UncheckedExtrinsic diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 87bf313ac4..7163d2c736 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -85,7 +85,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 168, - impl_version: 168, + impl_version: 169, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/assets/src/lib.rs b/srml/assets/src/lib.rs index bde5f7d538..b143085232 100644 --- a/srml/assets/src/lib.rs +++ b/srml/assets/src/lib.rs @@ -159,7 +159,7 @@ decl_module! { let id = Self::next_asset_id(); >::mutate(|id| *id += One::one()); - >::insert((id, origin.clone()), total); + >::insert((id, &origin), total); >::insert(id, total); Self::deposit_event(RawEvent::Issued(id, origin, total)); @@ -186,7 +186,7 @@ decl_module! { /// Destroy any assets of `id` owned by `origin`. fn destroy(origin, #[compact] id: T::AssetId) { let origin = ensure_signed(origin)?; - let balance = >::take((id, origin.clone())); + let balance = >::take((id, &origin)); ensure!(!balance.is_zero(), "origin balance should be non-zero"); >::mutate(id, |total_supply| *total_supply -= balance); diff --git a/srml/aura/src/lib.rs b/srml/aura/src/lib.rs index 65d1508810..834d6b0a14 100644 --- a/srml/aura/src/lib.rs +++ b/srml/aura/src/lib.rs @@ -177,7 +177,7 @@ impl Module { fn initialize_authorities(authorities: &[T::AuthorityId]) { if !authorities.is_empty() { assert!(>::get().is_empty(), "Authorities are already initialized!"); - >::put_ref(authorities); + >::put(authorities); } } } diff --git a/srml/authority-discovery/src/lib.rs b/srml/authority-discovery/src/lib.rs index 4f759ba38a..c8857630fb 100644 --- a/srml/authority-discovery/src/lib.rs +++ b/srml/authority-discovery/src/lib.rs @@ -29,13 +29,13 @@ #![cfg_attr(not(feature = "std"), no_std)] use app_crypto::RuntimeAppPublic; -use codec::{Decode, Encode}; +use codec::FullCodec; use rstd::prelude::*; use support::{decl_module, decl_storage}; /// The module's config trait. pub trait Trait: system::Trait + session::Trait { - type AuthorityId: RuntimeAppPublic + Default + Decode + Encode + PartialEq; + type AuthorityId: RuntimeAppPublic + Default + FullCodec + PartialEq; } decl_storage! { @@ -102,7 +102,7 @@ impl Module { fn initialize_keys(keys: &[T::AuthorityId]) { if !keys.is_empty() { assert!(Keys::::get().is_empty(), "Keys are already initialized!"); - Keys::::put_ref(keys); + Keys::::put(keys); } } } diff --git a/srml/babe/src/lib.rs b/srml/babe/src/lib.rs index aa0165f9f8..a410eccda8 100644 --- a/srml/babe/src/lib.rs +++ b/srml/babe/src/lib.rs @@ -358,7 +358,7 @@ impl Module { } else { // move onto the next segment and update the index. let segment_idx = segment_idx + 1; - ::insert(&segment_idx, vec![*vrf_output].as_ref()); + ::insert(&segment_idx, &vec![*vrf_output]); ::put(&segment_idx); } } @@ -438,7 +438,7 @@ impl Module { fn initialize_authorities(authorities: &[(AuthorityId, BabeAuthorityWeight)]) { if !authorities.is_empty() { assert!(Authorities::get().is_empty(), "Authorities are already initialized!"); - Authorities::put_ref(authorities); + Authorities::put(authorities); } } } diff --git a/srml/collective/src/lib.rs b/srml/collective/src/lib.rs index f4e5ef50f0..4a157569c0 100644 --- a/srml/collective/src/lib.rs +++ b/srml/collective/src/lib.rs @@ -281,7 +281,7 @@ impl, I: Instance> ChangeMembers for Module { } ); } - >::put_ref(new); + >::put(new); } } @@ -289,7 +289,7 @@ impl, I: Instance> InitializeMembers for Module fn initialize_members(members: &[T::AccountId]) { if !members.is_empty() { assert!(>::get().is_empty(), "Members are already initialized!"); - >::put_ref(members); + >::put(members); } } } diff --git a/srml/contracts/src/wasm/code_cache.rs b/srml/contracts/src/wasm/code_cache.rs index 80fb3e18f6..e6702d29cf 100644 --- a/srml/contracts/src/wasm/code_cache.rs +++ b/srml/contracts/src/wasm/code_cache.rs @@ -98,7 +98,7 @@ pub fn load( let original_code = >::get(code_hash).ok_or_else(|| "pristine code is not found")?; prefab_module = prepare::prepare_contract::(&original_code, schedule)?; - >::insert(code_hash, prefab_module.clone()); + >::insert(&code_hash, &prefab_module); } Ok(prefab_module) } diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index 2c6187e582..b93f6f893a 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -24,7 +24,7 @@ use sr_primitives::{ traits::{Zero, Bounded, CheckedMul, CheckedDiv, EnsureOrigin, Hash, Dispatchable}, weights::SimpleDispatchInfo, }; -use codec::{Encode, Decode, Input, Output, Error}; +use codec::{Ref, Encode, Decode, Input, Output, Error}; use support::{ decl_module, decl_storage, decl_event, ensure, Parameter, @@ -377,10 +377,10 @@ decl_module! { let index = Self::public_prop_count(); PublicPropCount::put(index + 1); - >::insert(index, (value, vec![who.clone()])); + >::insert(index, (value, &[&who][..])); - let new_prop = (index, (*proposal).clone(), who); - >::append_or_put([new_prop].into_iter()); + let new_prop = (index, proposal, who); + >::append_or_put(&[Ref::from(&new_prop)][..]); Self::deposit_event(RawEvent::Proposed(index, value)); } @@ -609,7 +609,7 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedNormal(500_000)] pub fn delegate(origin, to: T::AccountId, conviction: Conviction) { let who = ensure_signed(origin)?; - >::insert(who.clone(), (to.clone(), conviction)); + >::insert(&who, (&to, conviction)); // Currency is locked indefinitely as long as it's delegated. T::Currency::extend_lock( DEMOCRACY_ID, @@ -788,10 +788,10 @@ impl Module { /// Actually enact a vote, if legit. fn do_vote(who: T::AccountId, ref_index: ReferendumIndex, vote: Vote) -> Result { ensure!(Self::is_active_referendum(ref_index), "vote given for invalid referendum."); - if !>::exists(&(ref_index, who.clone())) { - >::append_or_insert(ref_index, [who.clone()].into_iter()); + if !>::exists((ref_index, &who)) { + >::append_or_insert(ref_index, &[&who][..]); } - >::insert(&(ref_index, who), vote); + >::insert((ref_index, &who), vote); Ok(()) } @@ -929,7 +929,7 @@ impl Module { } else { >::append_or_insert( now + info.delay, - [Some((info.proposal, index))].into_iter() + &[Some((info.proposal, index))][..] ); } } else { diff --git a/srml/elections-phragmen/src/lib.rs b/srml/elections-phragmen/src/lib.rs index 42bec61fe1..b7cf1a4013 100644 --- a/srml/elections-phragmen/src/lib.rs +++ b/srml/elections-phragmen/src/lib.rs @@ -539,7 +539,7 @@ impl Module { // sort and save the members. new_members.sort(); - >::put(new_members.clone()); + >::put(&new_members); // save the runners as-is >::put(runners_up); diff --git a/srml/elections/src/lib.rs b/srml/elections/src/lib.rs index 1c4e012b5b..2a683879f8 100644 --- a/srml/elections/src/lib.rs +++ b/srml/elections/src/lib.rs @@ -816,7 +816,7 @@ impl Module { if set_len + 1 == VOTER_SET_SIZE { NextVoterSet::put(next + 1); } - >::append_or_insert(next, [Some(who.clone())].into_iter()) + >::append_or_insert(next, &[Some(who.clone())][..]) } } @@ -862,7 +862,7 @@ impl Module { // initialize leaderboard. let leaderboard_size = empty_seats + T::CarryCount::get() as usize; - >::put(vec![(Zero::zero(), T::AccountId::default()); leaderboard_size]); + >::put(vec![(BalanceOf::::zero(), T::AccountId::default()); leaderboard_size]); Self::deposit_event(RawEvent::TallyStarted(empty_seats as u32)); } @@ -1027,7 +1027,7 @@ impl Module { .chunks(APPROVAL_SET_SIZE) .enumerate() .for_each(|(index, slice)| >::insert( - (who.clone(), index as SetIndex), slice.to_vec()) + (&who, index as SetIndex), slice) ); } diff --git a/srml/grandpa/src/lib.rs b/srml/grandpa/src/lib.rs index 599dc0886f..610bd18fb3 100644 --- a/srml/grandpa/src/lib.rs +++ b/srml/grandpa/src/lib.rs @@ -333,7 +333,7 @@ impl Module { fn initialize_authorities(authorities: &[(AuthorityId, AuthorityWeight)]) { if !authorities.is_empty() { assert!(Authorities::get().is_empty(), "Authorities are already initialized!"); - Authorities::put_ref(authorities); + Authorities::put(authorities); } } } diff --git a/srml/im-online/src/lib.rs b/srml/im-online/src/lib.rs index 1a09349701..84c95fee47 100644 --- a/srml/im-online/src/lib.rs +++ b/srml/im-online/src/lib.rs @@ -418,7 +418,7 @@ impl Module { fn initialize_keys(keys: &[T::AuthorityId]) { if !keys.is_empty() { assert!(Keys::::get().is_empty(), "Keys are already initialized!"); - Keys::::put_ref(keys); + Keys::::put(keys); } } } diff --git a/srml/scored-pool/src/lib.rs b/srml/scored-pool/src/lib.rs index dabe9e8123..4d92caa559 100644 --- a/srml/scored-pool/src/lib.rs +++ b/srml/scored-pool/src/lib.rs @@ -88,7 +88,7 @@ mod mock; #[cfg(test)] mod tests; -use codec::{Encode, Decode}; +use codec::FullCodec; use rstd::prelude::*; use support::{ StorageValue, StorageMap, decl_module, decl_storage, decl_event, ensure, @@ -117,7 +117,7 @@ pub trait Trait: system::Trait { type Currency: Currency + ReservableCurrency; /// The score attributed to a member or candidate. - type Score: SimpleArithmetic + Clone + Copy + Default + Encode + Decode + MaybeSerializeDebug; + type Score: SimpleArithmetic + Clone + Copy + Default + FullCodec + MaybeSerializeDebug; /// The overarching event type. type Event: From> + Into<::Event>; diff --git a/srml/session/src/lib.rs b/srml/session/src/lib.rs index 992d24d6b6..208be4664a 100644 --- a/srml/session/src/lib.rs +++ b/srml/session/src/lib.rs @@ -640,15 +640,15 @@ impl Module { } fn key_owner(id: KeyTypeId, key_data: &[u8]) -> Option { - >::get(DEDUP_KEY_PREFIX, &(id, key_data.to_vec())) + >::get(DEDUP_KEY_PREFIX, (id, key_data)) } fn put_key_owner(id: KeyTypeId, key_data: &[u8], v: &T::ValidatorId) { - >::insert(DEDUP_KEY_PREFIX, &(id, key_data.to_vec()), v) + >::insert(DEDUP_KEY_PREFIX, (id, key_data), v) } fn clear_key_owner(id: KeyTypeId, key_data: &[u8]) { - >::remove(DEDUP_KEY_PREFIX, &(id, key_data.to_vec())); + >::remove(DEDUP_KEY_PREFIX, (id, key_data)); } } diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index e82188a463..0a2f37ccc4 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -722,7 +722,7 @@ decl_module! { // You're auto-bonded forever, here. We might improve this by only bonding when // you actually validate/nominate and remove once you unbond __everything__. - >::insert(&stash, controller.clone()); + >::insert(&stash, &controller); >::insert(&stash, payee); let stash_balance = T::Currency::free_balance(&stash); @@ -1339,7 +1339,7 @@ impl Module { if exposure.total < slot_stake { slot_stake = exposure.total; } - >::insert(c.clone(), exposure.clone()); + >::insert(&c, exposure.clone()); } // Update slot stake. diff --git a/srml/support/Cargo.toml b/srml/support/Cargo.toml index 731c6b1c45..2acf9f5fe3 100644 --- a/srml/support/Cargo.toml +++ b/srml/support/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] serde = { version = "1.0", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.0.5", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.0.6", default-features = false, features = ["derive"] } srml-metadata = { path = "../metadata", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index 83f62d97fc..76fff30bd3 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -338,7 +338,7 @@ fn decl_store_extra_genesis( < #name<#struct_trait #instance> as #scrate::storage::StorageValue<#typ> - >::put(&v); + >::put::<#typ>(v); }} }, DeclStorageTypeInfosKind::Map { key_type, is_linked, .. } => { @@ -363,7 +363,7 @@ fn decl_store_extra_genesis( < #name<#struct_trait #instance> as #scrate::storage::#map<#key_type, #typ> - >::insert(&k, &v); + >::insert::<#key_type, #typ>(k, v); }); }} }, @@ -384,7 +384,7 @@ fn decl_store_extra_genesis( < #name<#struct_trait #instance> as #scrate::storage::StorageDoubleMap<#key1_type, #key2_type, #typ> - >::insert(&k1, &k2, &v); + >::insert::<#key1_type, #key2_type, #typ>(k1, k2, v); }); }} }, @@ -927,11 +927,11 @@ fn impl_store_fns( quote!{ #( #[ #attrs ] )* - pub fn #get_fn>(key: K) -> #value_type { + pub fn #get_fn>(key: K) -> #value_type { < #name<#struct_trait #instance> as #scrate::storage::#map<#key_type, #typ> - >::get(key.borrow()) + >::get(key) } } } @@ -946,12 +946,10 @@ fn impl_store_fns( }; quote!{ - pub fn #get_fn(k1: &KArg1, k2: &KArg2) -> #value_type + pub fn #get_fn(k1: KArg1, k2: KArg2) -> #value_type where - #key1_type: #scrate::rstd::borrow::Borrow, - #key2_type: #scrate::rstd::borrow::Borrow, - KArg1: ?Sized + #scrate::codec::Encode, - KArg2: ?Sized + #scrate::codec::Encode, + KArg1: #scrate::codec::EncodeLike<#key1_type>, + KArg2: #scrate::codec::EncodeLike<#key2_type>, { < #name<#struct_trait #instance> as diff --git a/srml/support/src/dispatch.rs b/srml/support/src/dispatch.rs index b7b142ea19..67cd3e44bf 100644 --- a/srml/support/src/dispatch.rs +++ b/srml/support/src/dispatch.rs @@ -20,7 +20,7 @@ pub use crate::rstd::{result, prelude::{Vec, Clone, Eq, PartialEq}, marker}; #[cfg(feature = "std")] pub use std::fmt; -pub use crate::codec::{Codec, Decode, Encode, Input, Output, HasCompact, EncodeAsRef}; +pub use crate::codec::{Codec, EncodeLike, Decode, Encode, Input, Output, HasCompact, EncodeAsRef}; pub use srml_metadata::{ FunctionMetadata, DecodeDifferent, DecodeDifferentArray, FunctionArgumentMetadata, ModuleConstantMetadata, DefaultByte, DefaultByteGetter, @@ -49,16 +49,16 @@ pub trait Callable { pub type CallableCallFor = >::Call; #[cfg(feature = "std")] -pub trait Parameter: Codec + Clone + Eq + fmt::Debug {} +pub trait Parameter: Codec + EncodeLike + Clone + Eq + fmt::Debug {} #[cfg(feature = "std")] -impl Parameter for T where T: Codec + Clone + Eq + fmt::Debug {} +impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} #[cfg(not(feature = "std"))] -pub trait Parameter: Codec + Clone + Eq {} +pub trait Parameter: Codec + EncodeLike + Clone + Eq {} #[cfg(not(feature = "std"))] -impl Parameter for T where T: Codec + Clone + Eq {} +impl Parameter for T where T: Codec + EncodeLike + Clone + Eq {} /// Declares a `Module` struct and a `Call` enum, which implements the dispatch logic. /// diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index 711f4cbcfd..b88d86761c 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -235,7 +235,7 @@ pub use serde::{Serialize, Deserialize}; #[cfg(test)] mod tests { use super::*; - use codec::Codec; + use codec::{Codec, EncodeLike}; use runtime_io::with_externalities; use primitives::Blake2Hasher; pub use srml_metadata::{ @@ -245,7 +245,7 @@ mod tests { pub use rstd::marker::PhantomData; pub trait Trait { - type BlockNumber: Codec + Default; + type BlockNumber: Codec + EncodeLike + Default; type Origin; } diff --git a/srml/support/src/storage/child.rs b/srml/support/src/storage/child.rs index 6000dd2f17..1d6ee7a6f1 100644 --- a/srml/support/src/storage/child.rs +++ b/srml/support/src/storage/child.rs @@ -21,7 +21,8 @@ //! avoid collision from a resistant hash function (which unique implies)). // NOTE: could replace unhashed by having only one kind of storage (root being null storage key (storage_key can become Option<&[u8]>). -use super::{Codec, Encode, Decode, Vec}; +use crate::rstd::prelude::*; +use codec::{Codec, Encode, Decode}; /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. pub fn get(storage_key: &[u8], key: &[u8]) -> Option { diff --git a/srml/support/src/storage/generator/double_map.rs b/srml/support/src/storage/generator/double_map.rs index 3282c2074f..cac8dbd034 100644 --- a/srml/support/src/storage/generator/double_map.rs +++ b/srml/support/src/storage/generator/double_map.rs @@ -16,7 +16,7 @@ use rstd::prelude::*; use rstd::borrow::Borrow; -use codec::{Codec, Encode, EncodeAppend}; +use codec::{Ref, FullCodec, FullEncode, Encode, EncodeLike, EncodeAppend}; use crate::{storage::{self, unhashed}, hash::StorageHasher}; /// Generator for `StorageDoubleMap` used by `decl_storage`. @@ -39,7 +39,7 @@ use crate::{storage::{self, unhashed}, hash::StorageHasher}; /// If the key2s are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as /// `blake2_256` must be used for Hasher2. Otherwise, other items in storage with the same first /// key can be compromised. -pub trait StorageDoubleMap { +pub trait StorageDoubleMap { /// The type that get/take returns. type Query; @@ -59,10 +59,9 @@ pub trait StorageDoubleMap { fn from_query_to_optional_value(v: Self::Query) -> Option; /// Generate the first part of the key used in top storage. - fn storage_double_map_final_key1(k1: &KArg1) -> ::Output + fn storage_double_map_final_key1(k1: KArg1) -> ::Output where - KArg1: ?Sized + Encode, - K1: Borrow, + KArg1: EncodeLike, { let mut final_key1 = Self::key1_prefix().to_vec(); k1.encode_to(&mut final_key1); @@ -70,12 +69,10 @@ pub trait StorageDoubleMap { } /// Generate the full key used in top storage. - fn storage_double_map_final_key(k1: &KArg1, k2: &KArg2) -> Vec + fn storage_double_map_final_key(k1: KArg1, k2: KArg2) -> Vec where - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - K1: Borrow, - K2: Borrow, + KArg1: EncodeLike, + KArg2: EncodeLike, { let mut final_key = Self::storage_double_map_final_key1(k1).as_ref().to_vec(); final_key.extend_from_slice(k2.using_encoded(Self::Hasher2::hash).as_ref()); @@ -85,39 +82,33 @@ pub trait StorageDoubleMap { impl storage::StorageDoubleMap for G where - K1: Encode, - K2: Encode, - V: Codec, + K1: FullEncode, + K2: FullEncode, + V: FullCodec, G: StorageDoubleMap, { type Query = G::Query; - fn exists(k1: &KArg1, k2: &KArg2) -> bool + fn exists(k1: KArg1, k2: KArg2) -> bool where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, + KArg1: EncodeLike, + KArg2: EncodeLike, { unhashed::exists(&Self::storage_double_map_final_key(k1, k2)) } - fn get(k1: &KArg1, k2: &KArg2) -> Self::Query + fn get(k1: KArg1, k2: KArg2) -> Self::Query where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, + KArg1: EncodeLike, + KArg2: EncodeLike, { G::from_optional_value_to_query(unhashed::get(&Self::storage_double_map_final_key(k1, k2))) } - fn take(k1: &KArg1, k2: &KArg2) -> Self::Query + fn take(k1: KArg1, k2: KArg2) -> Self::Query where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, + KArg1: EncodeLike, + KArg2: EncodeLike, { let final_key = Self::storage_double_map_final_key(k1, k2); @@ -125,62 +116,57 @@ where G::from_optional_value_to_query(value) } - fn insert(k1: &KArg1, k2: &KArg2, val: &VArg) + fn insert(k1: KArg1, k2: KArg2, val: VArg) where - K1: Borrow, - K2: Borrow, - V: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - VArg: ?Sized + Encode, + KArg1: EncodeLike, + KArg2: EncodeLike, + VArg: EncodeLike, { unhashed::put(&Self::storage_double_map_final_key(k1, k2), &val.borrow()) } - fn remove(k1: &KArg1, k2: &KArg2) + fn remove(k1: KArg1, k2: KArg2) where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, + KArg1: EncodeLike, + KArg2: EncodeLike, { unhashed::kill(&Self::storage_double_map_final_key(k1, k2)) } - fn remove_prefix(k1: &KArg1) where KArg1: ?Sized + Encode, K1: Borrow { + fn remove_prefix(k1: KArg1) where KArg1: EncodeLike { unhashed::kill_prefix(Self::storage_double_map_final_key1(k1).as_ref()) } - fn mutate(k1: &KArg1, k2: &KArg2, f: F) -> R + fn mutate(k1: KArg1, k2: KArg2, f: F) -> R where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, + KArg1: EncodeLike, + KArg2: EncodeLike, F: FnOnce(&mut Self::Query) -> R, { - let mut val = G::get(k1, k2); + let final_key = Self::storage_double_map_final_key(k1, k2); + let mut val = G::from_optional_value_to_query(unhashed::get(final_key.as_ref())); let ret = f(&mut val); match G::from_query_to_optional_value(val) { - Some(ref val) => G::insert(k1, k2, val), - None => G::remove(k1, k2), + Some(ref val) => unhashed::put(final_key.as_ref(), val), + None => unhashed::kill(final_key.as_ref()), } ret } - fn append( - k1: &KArg1, - k2: &KArg2, - items: &[I], + fn append( + k1: KArg1, + k2: KArg2, + items: Items, ) -> Result<(), &'static str> where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - I: codec::Encode, - V: EncodeAppend, + KArg1: EncodeLike, + KArg2: EncodeLike, + Item: Encode, + EncodeLikeItem: EncodeLike, + V: EncodeAppend, + Items: IntoIterator, + Items::IntoIter: ExactSizeIterator { let final_key = Self::storage_double_map_final_key(k1, k2); @@ -192,7 +178,7 @@ where } }); - let new_val = V::append( + let new_val = V::append_or_new( encoded_value, items, ).map_err(|_| "Could not append given item")?; @@ -200,4 +186,22 @@ where Ok(()) } + + fn append_or_insert( + k1: KArg1, + k2: KArg2, + items: Items, + ) + where + KArg1: EncodeLike, + KArg2: EncodeLike, + Item: Encode, + EncodeLikeItem: EncodeLike, + V: EncodeAppend, + Items: IntoIterator + Clone + EncodeLike, + Items::IntoIter: ExactSizeIterator + { + Self::append(Ref::from(&k1), Ref::from(&k2), items.clone()) + .unwrap_or_else(|_| Self::insert(k1, k2, items)); + } } diff --git a/srml/support/src/storage/generator/linked_map.rs b/srml/support/src/storage/generator/linked_map.rs index d2476de587..6643a37f4f 100644 --- a/srml/support/src/storage/generator/linked_map.rs +++ b/srml/support/src/storage/generator/linked_map.rs @@ -14,12 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use codec::{Codec, Encode, Decode}; +use codec::{FullCodec, Encode, Decode, EncodeLike, Ref}; use crate::{storage::{self, unhashed}, hash::StorageHasher, traits::Len}; -use rstd::{ - borrow::Borrow, - marker::PhantomData, -}; +use rstd::marker::PhantomData; /// Generator for `StorageLinkedMap` used by `decl_storage`. /// @@ -43,7 +40,7 @@ use rstd::{ /// /// If the keys are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as /// `blake2_256` must be used. Otherwise, other values in storage can be compromised. -pub trait StorageLinkedMap { +pub trait StorageLinkedMap { /// The type that get/take returns. type Query; @@ -65,10 +62,10 @@ pub trait StorageLinkedMap { /// Generate the full key used in top storage. fn storage_linked_map_final_key(key: KeyArg) -> ::Output where - KeyArg: Borrow, + KeyArg: EncodeLike, { let mut final_key = Self::prefix().to_vec(); - key.borrow().encode_to(&mut final_key); + key.encode_to(&mut final_key); Self::Hasher::hash(&final_key) } @@ -96,13 +93,29 @@ impl Default for Linkage { } } +// Encode like a linkage. +#[derive(Encode)] +struct EncodeLikeLinkage, NKey: EncodeLike, Key: Encode> { + // Previous element key in storage (None for the first element) + previous: Option, + // Next element key in storage (None for the last element) + next: Option, + // The key of the linkage this type encode to + phantom: core::marker::PhantomData, +} + /// A key-value pair iterator for enumerable map. -pub struct Enumerator> { +pub struct Enumerator> { next: Option, _phantom: PhantomData<(G, V)>, } -impl> Iterator for Enumerator { +impl Iterator for Enumerator +where + K: FullCodec, + V: FullCodec, + G: StorageLinkedMap, +{ type Item = (K, V); fn next(&mut self) -> Option { @@ -123,7 +136,12 @@ impl> Iterator for Enumerator>(linkage: Linkage) { +fn remove_linkage(linkage: Linkage) +where + K: FullCodec, + V: FullCodec, + G: StorageLinkedMap, +{ let next_key = linkage.next.as_ref() .map(G::storage_linked_map_final_key) .map(|x| x.as_ref().to_vec()); @@ -140,7 +158,7 @@ fn remove_linkage>(linkage: Linkag unhashed::put(prev_key.as_ref(), &res); } else { // we were first so let's update the head - write_head::<_, _, G>(linkage.next.as_ref()); + write_head::<_, _, _, G>(linkage.next.as_ref()); } if let Some(next_key) = next_key { // Update previous of next element @@ -155,9 +173,9 @@ fn remove_linkage>(linkage: Linkag /// Read the contained data and it's linkage. fn read_with_linkage(key: &[u8]) -> Option<(V, Linkage)> where - K: Codec, - V: Codec, - G: StorageLinkedMap + K: FullCodec, + V: FullCodec, + G: StorageLinkedMap, { unhashed::get(key) } @@ -165,11 +183,12 @@ where /// Generate linkage for newly inserted element. /// /// Takes care of updating head and previous head's pointer. -fn new_head_linkage(key: &K) -> Linkage +fn new_head_linkage(key: KeyArg) -> Linkage where - K: Codec, - V: Codec, - G: StorageLinkedMap + KeyArg: EncodeLike, + K: FullCodec, + V: FullCodec, + G: StorageLinkedMap, { if let Some(head) = read_head::<_, _, G>() { // update previous head predecessor @@ -179,20 +198,22 @@ where .expect("head is set when first element is inserted and unset when last element is removed; if head is Some then it points to existing key; qed"); - unhashed::put(head_key.as_ref(), &(data, Linkage { + let new_linkage = EncodeLikeLinkage::<_, _, K> { + previous: Some(Ref::from(&key)), next: linkage.next.as_ref(), - previous: Some(key), - })); + phantom: Default::default(), + }; + unhashed::put(head_key.as_ref(), &(data, new_linkage)); } // update to current head - write_head::<_, _, G>(Some(key)); + write_head::<_, _, _, G>(Some(key)); // return linkage with pointer to previous head let mut linkage = Linkage::default(); linkage.next = Some(head); linkage } else { // we are first - update the head and produce empty linkage - write_head::<_, _, G>(Some(key)); + write_head::<_, _, _, G>(Some(key)); Linkage::default() } } @@ -200,9 +221,9 @@ where /// Read current head pointer. fn read_head() -> Option where - K: Codec, - V: Codec, - G: StorageLinkedMap + K: FullCodec, + V: FullCodec, + G: StorageLinkedMap, { unhashed::get(G::storage_linked_map_final_head_key().as_ref()) } @@ -210,35 +231,41 @@ where /// Overwrite current head pointer. /// /// If `None` is given head is removed from storage. -fn write_head(head: Option<&K>) +fn write_head(head: Option) where - K: Codec, - V: Codec, - G: StorageLinkedMap + KeyArg: EncodeLike, + K: FullCodec, + V: FullCodec, + G: StorageLinkedMap, { - match head { + match head.as_ref() { Some(head) => unhashed::put(G::storage_linked_map_final_head_key().as_ref(), head), None => unhashed::kill(G::storage_linked_map_final_head_key().as_ref()), } } -impl> storage::StorageLinkedMap for G { +impl storage::StorageLinkedMap for G +where + K: FullCodec, + V: FullCodec, + G: StorageLinkedMap, +{ type Query = G::Query; type Enumerator = Enumerator; - fn exists>(key: KeyArg) -> bool { + fn exists>(key: KeyArg) -> bool { unhashed::exists(Self::storage_linked_map_final_key(key).as_ref()) } - fn get>(key: KeyArg) -> Self::Query { + fn get>(key: KeyArg) -> Self::Query { let val = unhashed::get(Self::storage_linked_map_final_key(key).as_ref()); G::from_optional_value_to_query(val) } - fn swap, KeyArg2: Borrow>(key1: KeyArg1, key2: KeyArg2) { - let final_key1 = Self::storage_linked_map_final_key(key1.borrow()); - let final_key2 = Self::storage_linked_map_final_key(key2.borrow()); + fn swap, KeyArg2: EncodeLike>(key1: KeyArg1, key2: KeyArg2) { + let final_key1 = Self::storage_linked_map_final_key(Ref::from(&key1)); + let final_key2 = Self::storage_linked_map_final_key(Ref::from(&key2)); let full_value_1 = read_with_linkage::<_, _, G>(final_key1.as_ref()); let full_value_2 = read_with_linkage::<_, _, G>(final_key2.as_ref()); @@ -251,13 +278,13 @@ impl> storage::StorageLinkedMap { Self::remove(key1); - let linkage = new_head_linkage::<_, _, G>(key2.borrow()); + let linkage = new_head_linkage::<_, _, _, G>(key2); unhashed::put(final_key2.as_ref(), &(value, linkage)); } // Remove key and insert the new one. (None, Some((value, _linkage))) => { Self::remove(key2); - let linkage = new_head_linkage::<_, _, G>(key1.borrow()); + let linkage = new_head_linkage::<_, _, _, G>(key1); unhashed::put(final_key1.as_ref(), &(value, linkage)); } // No-op. @@ -265,37 +292,23 @@ impl> storage::StorageLinkedMap, ValArg: Borrow>(key: KeyArg, val: ValArg) { - let final_key = Self::storage_linked_map_final_key(key.borrow()); - let linkage = match read_with_linkage::<_, _, G>(final_key.as_ref()) { - // overwrite but reuse existing linkage - Some((_data, linkage)) => linkage, - // create new linkage - None => new_head_linkage::<_, _, G>(key.borrow()), - }; - unhashed::put(final_key.as_ref(), &(val.borrow(), linkage)) - } - - fn insert_ref, ValArg: ?Sized + Encode>(key: KeyArg, val: &ValArg) - where - V: AsRef - { - let final_key = Self::storage_linked_map_final_key(key.borrow()); + fn insert, ValArg: EncodeLike>(key: KeyArg, val: ValArg) { + let final_key = Self::storage_linked_map_final_key(Ref::from(&key)); let linkage = match read_with_linkage::<_, _, G>(final_key.as_ref()) { // overwrite but reuse existing linkage Some((_data, linkage)) => linkage, // create new linkage - None => new_head_linkage::<_, _, G>(key.borrow()), + None => new_head_linkage::<_, _, _, G>(key), }; - unhashed::put(final_key.as_ref(), &(&val, &linkage)) + unhashed::put(final_key.as_ref(), &(val, linkage)) } - fn remove>(key: KeyArg) { + fn remove>(key: KeyArg) { G::take(key); } - fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R { - let final_key = Self::storage_linked_map_final_key(key.borrow()); + fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R { + let final_key = Self::storage_linked_map_final_key(Ref::from(&key)); let (mut val, _linkage) = read_with_linkage::<_, _, G>(final_key.as_ref()) .map(|(data, linkage)| (G::from_optional_value_to_query(Some(data)), Some(linkage))) @@ -303,13 +316,13 @@ impl> storage::StorageLinkedMap G::insert(key.borrow(), val), - None => G::remove(key.borrow()), + Some(ref val) => G::insert(key, val), + None => G::remove(key), } ret } - fn take>(key: KeyArg) -> Self::Query { + fn take>(key: KeyArg) -> Self::Query { let final_key = Self::storage_linked_map_final_key(key); let full_value: Option<(V, Linkage)> = unhashed::take(final_key.as_ref()); @@ -333,7 +346,7 @@ impl> storage::StorageLinkedMap() } - fn decode_len>(key: KeyArg) -> Result + fn decode_len>(key: KeyArg) -> Result where V: codec::DecodeLength + Len { let key = Self::storage_linked_map_final_key(key); diff --git a/srml/support/src/storage/generator/map.rs b/srml/support/src/storage/generator/map.rs index cc060cf1ec..3c3edac28a 100644 --- a/srml/support/src/storage/generator/map.rs +++ b/srml/support/src/storage/generator/map.rs @@ -17,7 +17,7 @@ #[cfg(not(feature = "std"))] use rstd::prelude::*; use rstd::borrow::Borrow; -use codec::{Codec, Encode}; +use codec::{FullCodec, FullEncode, Encode, EncodeLike, Ref, EncodeAppend}; use crate::{storage::{self, unhashed}, hash::StorageHasher, traits::Len}; /// Generator for `StorageMap` used by `decl_storage`. @@ -31,7 +31,7 @@ use crate::{storage::{self, unhashed}, hash::StorageHasher, traits::Len}; /// /// If the keys are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as /// `blake2_256` must be used. Otherwise, other values in storage can be compromised. -pub trait StorageMap { +pub trait StorageMap { /// The type that get/take returns. type Query; @@ -50,7 +50,7 @@ pub trait StorageMap { /// Generate the full key used in top storage. fn storage_map_final_key(key: KeyArg) -> ::Output where - KeyArg: Borrow, + KeyArg: EncodeLike, { let mut final_key = Self::prefix().to_vec(); key.borrow().encode_to(&mut final_key); @@ -58,14 +58,14 @@ pub trait StorageMap { } } -impl> storage::StorageMap for G { +impl> storage::StorageMap for G { type Query = G::Query; - fn hashed_key_for>(key: KeyArg) -> Vec { + fn hashed_key_for>(key: KeyArg) -> Vec { Self::storage_map_final_key(key).as_ref().to_vec() } - fn swap, KeyArg2: Borrow>(key1: KeyArg1, key2: KeyArg2) { + fn swap, KeyArg2: EncodeLike>(key1: KeyArg1, key2: KeyArg2) { let k1 = Self::storage_map_final_key(key1); let k2 = Self::storage_map_final_key(key2); @@ -82,52 +82,48 @@ impl> storage::StorageMap for G { } } - fn exists>(key: KeyArg) -> bool { + fn exists>(key: KeyArg) -> bool { unhashed::exists(Self::storage_map_final_key(key).as_ref()) } - fn get>(key: KeyArg) -> Self::Query { + fn get>(key: KeyArg) -> Self::Query { G::from_optional_value_to_query(unhashed::get(Self::storage_map_final_key(key).as_ref())) } - fn insert, ValArg: Borrow>(key: KeyArg, val: ValArg) { + fn insert, ValArg: EncodeLike>(key: KeyArg, val: ValArg) { unhashed::put(Self::storage_map_final_key(key).as_ref(), &val.borrow()) } - fn insert_ref, ValArg: ?Sized + Encode>(key: KeyArg, val: &ValArg) - where V: AsRef - { - val.using_encoded(|b| unhashed::put_raw(Self::storage_map_final_key(key).as_ref(), b)) - } - - fn remove>(key: KeyArg) { + fn remove>(key: KeyArg) { unhashed::kill(Self::storage_map_final_key(key).as_ref()) } - fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R { - let mut val = G::get(key.borrow()); + fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R { + let final_key = Self::storage_map_final_key(key); + let mut val = G::from_optional_value_to_query(unhashed::get(final_key.as_ref())); let ret = f(&mut val); match G::from_query_to_optional_value(val) { - Some(ref val) => G::insert(key, val), - None => G::remove(key), + Some(ref val) => unhashed::put(final_key.as_ref(), &val.borrow()), + None => unhashed::kill(final_key.as_ref()), } ret } - fn take>(key: KeyArg) -> Self::Query { + fn take>(key: KeyArg) -> Self::Query { let key = Self::storage_map_final_key(key); let value = unhashed::take(key.as_ref()); G::from_optional_value_to_query(value) } - fn append<'a, I, R, KeyArg>(key: KeyArg, items: R) -> Result<(), &'static str> + fn append(key: KeyArg, items: Items) -> Result<(), &'static str> where - KeyArg: Borrow, - I: 'a + codec::Encode, - V: codec::EncodeAppend, - R: IntoIterator, - R::IntoIter: ExactSizeIterator, + KeyArg: EncodeLike, + Item: Encode, + EncodeLikeItem: EncodeLike, + V: EncodeAppend, + Items: IntoIterator, + Items::IntoIter: ExactSizeIterator, { let key = Self::storage_map_final_key(key); let encoded_value = unhashed::get_raw(key.as_ref()) @@ -138,7 +134,7 @@ impl> storage::StorageMap for G { } }); - let new_val = V::append( + let new_val = V::append_or_new( encoded_value, items, ).map_err(|_| "Could not append given item")?; @@ -146,19 +142,20 @@ impl> storage::StorageMap for G { Ok(()) } - fn append_or_insert<'a, I, R, KeyArg>(key: KeyArg, items: R) + fn append_or_insert(key: KeyArg, items: Items) where - KeyArg: Borrow, - I: 'a + codec::Encode + Clone, - V: codec::EncodeAppend + crate::rstd::iter::FromIterator, - R: IntoIterator + Clone, - R::IntoIter: ExactSizeIterator, + KeyArg: EncodeLike, + Item: Encode, + EncodeLikeItem: EncodeLike, + V: EncodeAppend, + Items: IntoIterator + Clone + EncodeLike, + Items::IntoIter: ExactSizeIterator, { - Self::append(key.borrow(), items.clone()) - .unwrap_or_else(|_| Self::insert(key, &items.into_iter().cloned().collect())); + Self::append(Ref::from(&key), items.clone()) + .unwrap_or_else(|_| Self::insert(key, items)); } - fn decode_len>(key: KeyArg) -> Result + fn decode_len>(key: KeyArg) -> Result where V: codec::DecodeLength + Len { let key = Self::storage_map_final_key(key); diff --git a/srml/support/src/storage/generator/value.rs b/srml/support/src/storage/generator/value.rs index c595d85290..8423503dde 100644 --- a/srml/support/src/storage/generator/value.rs +++ b/srml/support/src/storage/generator/value.rs @@ -16,8 +16,7 @@ #[cfg(not(feature = "std"))] use rstd::prelude::*; -use rstd::{borrow::Borrow, iter::FromIterator}; -use codec::{Codec, Encode}; +use codec::{FullCodec, Encode, EncodeAppend, EncodeLike}; use crate::{storage::{self, unhashed}, hash::{Twox128, StorageHasher}, traits::Len}; /// Generator for `StorageValue` used by `decl_storage`. @@ -26,7 +25,7 @@ use crate::{storage::{self, unhashed}, hash::{Twox128, StorageHasher}, traits::L /// ```nocompile /// Twox128(unhashed_key) /// ``` -pub trait StorageValue { +pub trait StorageValue { /// The type that get/take returns. type Query; @@ -45,7 +44,7 @@ pub trait StorageValue { } } -impl> storage::StorageValue for G { +impl> storage::StorageValue for G { type Query = G::Query; fn hashed_key() -> [u8; 16] { @@ -61,12 +60,8 @@ impl> storage::StorageValue for G { G::from_optional_value_to_query(value) } - fn put>(val: Arg) { - unhashed::put(&Self::storage_value_final_key(), val.borrow()) - } - - fn put_ref(val: &Arg) where T: AsRef { - val.using_encoded(|b| unhashed::put_raw(&Self::storage_value_final_key(), b)) + fn put>(val: Arg) { + unhashed::put(&Self::storage_value_final_key(), &val) } fn kill() { @@ -96,12 +91,13 @@ impl> storage::StorageValue for G { /// Append the given items to the value in the storage. /// /// `T` is required to implement `codec::EncodeAppend`. - fn append<'a, I, R>(items: R) -> Result<(), &'static str> + fn append(items: Items) -> Result<(), &'static str> where - I: 'a + codec::Encode, - T: codec::EncodeAppend, - R: IntoIterator, - R::IntoIter: ExactSizeIterator, + Item: Encode, + EncodeLikeItem: EncodeLike, + T: EncodeAppend, + Items: IntoIterator, + Items::IntoIter: ExactSizeIterator, { let key = Self::storage_value_final_key(); let encoded_value = unhashed::get_raw(&key) @@ -112,7 +108,7 @@ impl> storage::StorageValue for G { } }); - let new_val = T::append( + let new_val = T::append_or_new( encoded_value, items, ).map_err(|_| "Could not append given item")?; @@ -124,15 +120,14 @@ impl> storage::StorageValue for G { /// old (presumably corrupt) value is replaced with the given `items`. /// /// `T` is required to implement `codec::EncodeAppend`. - fn append_or_put<'a, I, R>(items: R) - where - I: 'a + codec::Encode + Clone, - T: codec::EncodeAppend + FromIterator, - R: IntoIterator + Clone, - R::IntoIter: ExactSizeIterator, + fn append_or_put(items: Items) where + Item: Encode, + EncodeLikeItem: EncodeLike, + T: EncodeAppend, + Items: IntoIterator + Clone + EncodeLike, + Items::IntoIter: ExactSizeIterator { - Self::append(items.clone()) - .unwrap_or_else(|_| Self::put(&items.into_iter().cloned().collect())); + Self::append(items.clone()).unwrap_or_else(|_| Self::put(items)); } /// Read the length of the value in a fast way, without decoding the entire value. diff --git a/srml/support/src/storage/mod.rs b/srml/support/src/storage/mod.rs index 3e3c889cde..648009b470 100644 --- a/srml/support/src/storage/mod.rs +++ b/srml/support/src/storage/mod.rs @@ -16,9 +16,8 @@ //! Stuff to do with the runtime's storage. -use crate::rstd::prelude::*; -use crate::rstd::{borrow::Borrow, iter::FromIterator}; -use codec::{Codec, Encode, Decode, EncodeAppend}; +use rstd::prelude::*; +use codec::{FullCodec, FullEncode, Encode, EncodeAppend, EncodeLike}; use crate::traits::Len; #[macro_use] @@ -29,7 +28,7 @@ pub mod child; pub mod generator; /// A trait for working with macro-generated storage values under the substrate storage API. -pub trait StorageValue { +pub trait StorageValue { /// The type that get/take return. type Query; @@ -43,11 +42,7 @@ pub trait StorageValue { fn get() -> Self::Query; /// Store a value under this key into the provided storage instance. - fn put>(val: Arg); - - /// Store a value under this key into the provided storage instance; this can take any reference - /// type that derefs to `T` (and has `Encode` implemented). - fn put_ref(val: &Arg) where T: AsRef; + fn put>(val: Arg); /// Mutate the value fn mutate R>(f: F) -> R; @@ -61,11 +56,13 @@ pub trait StorageValue { /// Append the given item to the value in the storage. /// /// `T` is required to implement `codec::EncodeAppend`. - fn append<'a, I, R>(items: R) -> Result<(), &'static str> where - I: 'a + Encode, - T: EncodeAppend, - R: IntoIterator, - R::IntoIter: ExactSizeIterator; + fn append(items: Items) -> Result<(), &'static str> + where + Item: Encode, + EncodeLikeItem: EncodeLike, + T: EncodeAppend, + Items: IntoIterator, + Items::IntoIter: ExactSizeIterator; /// Append the given items to the value in the storage. /// @@ -78,11 +75,13 @@ pub trait StorageValue { /// /// use with care; if your use-case is not _exactly_ as what this function is doing, /// you should use append and sensibly handle failure within the runtime code if it happens. - fn append_or_put<'a, I, R>(items: R) where - I: 'a + Encode + Clone, - T: EncodeAppend + FromIterator, - R: IntoIterator + Clone, - R::IntoIter: ExactSizeIterator; + fn append_or_put(items: Items) where + Item: Encode, + EncodeLikeItem: EncodeLike, + T: EncodeAppend, + Items: IntoIterator + Clone + EncodeLike, + Items::IntoIter: ExactSizeIterator; + /// Read the length of the value in a fast way, without decoding the entire value. /// @@ -92,60 +91,58 @@ pub trait StorageValue { } /// A strongly-typed map in storage. -pub trait StorageMap { +pub trait StorageMap { /// The type that get/take return. type Query; /// Get the storage key used to fetch a value corresponding to a specific key. - fn hashed_key_for>(key: KeyArg) -> Vec; + fn hashed_key_for>(key: KeyArg) -> Vec; /// Does the value (explicitly) exist in storage? - fn exists>(key: KeyArg) -> bool; + fn exists>(key: KeyArg) -> bool; /// Load the value associated with the given key from the map. - fn get>(key: KeyArg) -> Self::Query; + fn get>(key: KeyArg) -> Self::Query; /// Swap the values of two keys. - fn swap, KeyArg2: Borrow>(key1: KeyArg1, key2: KeyArg2); + fn swap, KeyArg2: EncodeLike>(key1: KeyArg1, key2: KeyArg2); /// Store a value to be associated with the given key from the map. - fn insert, ValArg: Borrow>(key: KeyArg, val: ValArg); - - /// Store a value under this key into the provided storage instance; this can take any reference - /// type that derefs to `T` (and has `Encode` implemented). - fn insert_ref, ValArg: ?Sized + Encode>(key: KeyArg, val: &ValArg) where V: AsRef; + fn insert, ValArg: EncodeLike>(key: KeyArg, val: ValArg); /// Remove the value under a key. - fn remove>(key: KeyArg); + fn remove>(key: KeyArg); /// Mutate the value under a key. - fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R; + fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R; /// Take the value under a key. - fn take>(key: KeyArg) -> Self::Query; + fn take>(key: KeyArg) -> Self::Query; /// Append the given items to the value in the storage. /// /// `V` is required to implement `codec::EncodeAppend`. - fn append<'a, I, R, KeyArg>(key: KeyArg, items: R) -> Result<(), &'static str> + fn append(key: KeyArg, items: Items) -> Result<(), &'static str> where - KeyArg: Borrow, - I: 'a + codec::Encode, - V: codec::EncodeAppend, - R: IntoIterator + Clone, - R::IntoIter: ExactSizeIterator; + KeyArg: EncodeLike, + Item: Encode, + EncodeLikeItem: EncodeLike, + V: EncodeAppend, + Items: IntoIterator, + Items::IntoIter: ExactSizeIterator; /// Safely append the given items to the value in the storage. If a codec error occurs, then the /// old (presumably corrupt) value is replaced with the given `items`. /// - /// `T` is required to implement `codec::EncodeAppend`. - fn append_or_insert<'a, I, R, KeyArg>(key: KeyArg, items: R) + /// `V` is required to implement `codec::EncodeAppend`. + fn append_or_insert(key: KeyArg, items: Items) where - KeyArg: Borrow, - I: 'a + codec::Encode + Clone, - V: codec::EncodeAppend + crate::rstd::iter::FromIterator, - R: IntoIterator + Clone, - R::IntoIter: ExactSizeIterator; + KeyArg: EncodeLike, + Item: Encode, + EncodeLikeItem: EncodeLike, + V: EncodeAppend, + Items: IntoIterator + Clone + EncodeLike, + Items::IntoIter: ExactSizeIterator; /// Read the length of the value in a fast way, without decoding the entire value. /// @@ -154,14 +151,14 @@ pub trait StorageMap { /// Note that `0` is returned as the default value if no encoded value exists at the given key. /// Therefore, this function cannot be used as a sign of _existence_. use the `::exists()` /// function for this purpose. - fn decode_len>(key: KeyArg) -> Result + fn decode_len>(key: KeyArg) -> Result where V: codec::DecodeLength + Len; } /// A strongly-typed linked map in storage. /// /// Similar to `StorageMap` but allows to enumerate other elements and doesn't implement append. -pub trait StorageLinkedMap { +pub trait StorageLinkedMap { /// The type that get/take return. type Query; @@ -169,29 +166,25 @@ pub trait StorageLinkedMap { type Enumerator: Iterator; /// Does the value (explicitly) exist in storage? - fn exists>(key: KeyArg) -> bool; + fn exists>(key: KeyArg) -> bool; /// Load the value associated with the given key from the map. - fn get>(key: KeyArg) -> Self::Query; + fn get>(key: KeyArg) -> Self::Query; /// Swap the values of two keys. - fn swap, KeyArg2: Borrow>(key1: KeyArg1, key2: KeyArg2); + fn swap, KeyArg2: EncodeLike>(key1: KeyArg1, key2: KeyArg2); /// Store a value to be associated with the given key from the map. - fn insert, ValArg: Borrow>(key: KeyArg, val: ValArg); - - /// Store a value under this key into the provided storage instance; this can take any reference - /// type that derefs to `T` (and has `Encode` implemented). - fn insert_ref, ValArg: ?Sized + Encode>(key: KeyArg, val: &ValArg) where V: AsRef; + fn insert, ValArg: EncodeLike>(key: KeyArg, val: ValArg); /// Remove the value under a key. - fn remove>(key: KeyArg); + fn remove>(key: KeyArg); /// Mutate the value under a key. - fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R; + fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R; /// Take the value under a key. - fn take>(key: KeyArg) -> Self::Query; + fn take>(key: KeyArg) -> Self::Query; /// Return current head element. fn head() -> Option; @@ -206,7 +199,7 @@ pub trait StorageLinkedMap { /// Note that `0` is returned as the default value if no encoded value exists at the given key. /// Therefore, this function cannot be used as a sign of _existence_. use the `::exists()` /// function for this purpose. - fn decode_len>(key: KeyArg) -> Result + fn decode_len>(key: KeyArg) -> Result where V: codec::DecodeLength + Len; } @@ -214,67 +207,69 @@ pub trait StorageLinkedMap { /// /// It provides an important ability to efficiently remove all entries /// that have a common first key. -pub trait StorageDoubleMap { +pub trait StorageDoubleMap { /// The type that get/take returns. type Query; - fn exists(k1: &KArg1, k2: &KArg2) -> bool + fn exists(k1: KArg1, k2: KArg2) -> bool where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode; + KArg1: EncodeLike, + KArg2: EncodeLike; - fn get(k1: &KArg1, k2: &KArg2) -> Self::Query + fn get(k1: KArg1, k2: KArg2) -> Self::Query where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode; + KArg1: EncodeLike, + KArg2: EncodeLike; - fn take(k1: &KArg1, k2: &KArg2) -> Self::Query + fn take(k1: KArg1, k2: KArg2) -> Self::Query where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode; + KArg1: EncodeLike, + KArg2: EncodeLike; - fn insert(k1: &KArg1, k2: &KArg2, val: &VArg) + fn insert(k1: KArg1, k2: KArg2, val: VArg) where - K1: Borrow, - K2: Borrow, - V: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - VArg: ?Sized + Encode; - - fn remove(k1: &KArg1, k2: &KArg2) + KArg1: EncodeLike, + KArg2: EncodeLike, + VArg: EncodeLike; + + fn remove(k1: KArg1, k2: KArg2) where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode; + KArg1: EncodeLike, + KArg2: EncodeLike; - fn remove_prefix(k1: &KArg1) where KArg1: ?Sized + Encode, K1: Borrow; + fn remove_prefix(k1: KArg1) where KArg1: ?Sized + EncodeLike; - fn mutate(k1: &KArg1, k2: &KArg2, f: F) -> R + fn mutate(k1: KArg1, k2: KArg2, f: F) -> R where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, + KArg1: EncodeLike, + KArg2: EncodeLike, F: FnOnce(&mut Self::Query) -> R; - fn append( - k1: &KArg1, - k2: &KArg2, - items: &[I], + fn append( + k1: KArg1, + k2: KArg2, + items: Items, ) -> Result<(), &'static str> where - K1: Borrow, - K2: Borrow, - KArg1: ?Sized + Encode, - KArg2: ?Sized + Encode, - I: codec::Encode, - V: EncodeAppend; + KArg1: EncodeLike, + KArg2: EncodeLike, + Item: Encode, + EncodeLikeItem: EncodeLike, + V: EncodeAppend, + Items: IntoIterator, + Items::IntoIter: ExactSizeIterator; + + fn append_or_insert( + k1: KArg1, + k2: KArg2, + items: Items, + ) + where + KArg1: EncodeLike, + KArg2: EncodeLike, + Item: Encode, + EncodeLikeItem: EncodeLike, + V: EncodeAppend, + Items: IntoIterator + Clone + EncodeLike, + Items::IntoIter: ExactSizeIterator; } diff --git a/srml/support/src/storage/storage_items.rs b/srml/support/src/storage/storage_items.rs index d93152bb9a..67d301dad9 100644 --- a/srml/support/src/storage/storage_items.rs +++ b/srml/support/src/storage/storage_items.rs @@ -256,6 +256,7 @@ mod tests { use crate::metadata::*; use crate::metadata::StorageHasher; use crate::rstd::marker::PhantomData; + use crate::codec::{Encode, Decode, EncodeLike}; storage_items! { Value: b"a" => u32; @@ -286,7 +287,7 @@ mod tests { } pub trait Trait { - type Origin: crate::codec::Encode + crate::codec::Decode + ::std::default::Default; + type Origin: Encode + Decode + EncodeLike + std::default::Default; type BlockNumber; } @@ -839,13 +840,17 @@ mod test_append_and_len { #[test] fn append_or_put_works() { with_externalities(&mut TestExternalities::default(), || { - let _ = MapVec::append_or_insert(1, [1, 2, 3].iter()); - let _ = MapVec::append_or_insert(1, [4, 5].iter()); + let _ = MapVec::append_or_insert(1, &[1, 2, 3][..]); + let _ = MapVec::append_or_insert(1, &[4, 5][..]); assert_eq!(MapVec::get(1), vec![1, 2, 3, 4, 5]); - let _ = JustVec::append_or_put([1, 2, 3].iter()); - let _ = JustVec::append_or_put([4, 5].iter()); + let _ = JustVec::append_or_put(&[1, 2, 3][..]); + let _ = JustVec::append_or_put(&[4, 5][..]); assert_eq!(JustVec::get(), vec![1, 2, 3, 4, 5]); + + let _ = OptionVec::append_or_put(&[1, 2, 3][..]); + let _ = OptionVec::append_or_put(&[4, 5][..]); + assert_eq!(OptionVec::get(), Some(vec![1, 2, 3, 4, 5])); }); } diff --git a/srml/support/src/storage/unhashed.rs b/srml/support/src/storage/unhashed.rs index d3cf346ace..6397fd39fc 100644 --- a/srml/support/src/storage/unhashed.rs +++ b/srml/support/src/storage/unhashed.rs @@ -16,7 +16,8 @@ //! Operation on unhashed runtime storage. -use super::{Encode, Decode, Vec}; +use rstd::prelude::*; +use codec::{Encode, Decode}; /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. pub fn get(key: &[u8]) -> Option { diff --git a/srml/support/src/traits.rs b/srml/support/src/traits.rs index 655df596d0..88e6159365 100644 --- a/srml/support/src/traits.rs +++ b/srml/support/src/traits.rs @@ -19,7 +19,7 @@ //! NOTE: If you're looking for `parameter_types`, it has moved in to the top-level module. use rstd::{prelude::*, result, marker::PhantomData, ops::Div}; -use codec::{Codec, Encode, Decode}; +use codec::{FullCodec, Codec, Encode, Decode}; use primitives::u32_trait::Value as U32; use sr_primitives::{ ConsensusEngineId, @@ -254,7 +254,7 @@ pub enum SignedImbalance>{ impl< P: Imbalance, N: Imbalance, - B: SimpleArithmetic + Codec + Copy + MaybeSerializeDebug + Default, + B: SimpleArithmetic + FullCodec + Copy + MaybeSerializeDebug + Default, > SignedImbalance { pub fn zero() -> Self { SignedImbalance::Positive(P::zero()) @@ -317,7 +317,7 @@ impl< /// Abstraction over a fungible assets system. pub trait Currency { /// The balance of an account. - type Balance: SimpleArithmetic + Codec + Copy + MaybeSerializeDebug + Default; + type Balance: SimpleArithmetic + FullCodec + Copy + MaybeSerializeDebug + Default; /// The opaque token type for an imbalance. This is returned by unbalanced operations /// and must be dealt with. It may be dropped but cannot be cloned. @@ -615,7 +615,7 @@ bitmask! { } pub trait Time { - type Moment: SimpleArithmetic + Codec + Clone + Default + Copy; + type Moment: SimpleArithmetic + FullCodec + Clone + Default + Copy; fn now() -> Self::Moment; } diff --git a/srml/support/test/tests/final_keys.rs b/srml/support/test/tests/final_keys.rs index fdd41b04fe..04b243ae7c 100644 --- a/srml/support/test/tests/final_keys.rs +++ b/srml/support/test/tests/final_keys.rs @@ -20,11 +20,11 @@ use codec::Encode; use support::{StorageDoubleMap, StorageLinkedMap, StorageMap, StorageValue}; mod no_instance { - use codec::{Encode, Decode}; + use codec::{Encode, Decode, EncodeLike}; pub trait Trait { type Origin; - type BlockNumber: Encode + Decode + Default + Clone; + type BlockNumber: Encode + Decode + EncodeLike + Default + Clone; } support::decl_module! { diff --git a/srml/support/test/tests/genesisconfig.rs b/srml/support/test/tests/genesisconfig.rs index 9d03d204dc..e945c774c0 100644 --- a/srml/support/test/tests/genesisconfig.rs +++ b/srml/support/test/tests/genesisconfig.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . pub trait Trait { - type BlockNumber: codec::Codec + Default; + type BlockNumber: codec::Codec + codec::EncodeLike + Default; type Origin; } diff --git a/srml/support/test/tests/instance.rs b/srml/support/test/tests/instance.rs index 0662689379..da4e73e710 100644 --- a/srml/support/test/tests/instance.rs +++ b/srml/support/test/tests/instance.rs @@ -45,7 +45,7 @@ mod module1 { type Event: From> + Into<::Event>; type Origin: From>; type SomeParameter: Get; - type GenericType: Default + Clone + codec::Codec; + type GenericType: Default + Clone + codec::Codec + codec::EncodeLike; } support::decl_module! { @@ -314,10 +314,10 @@ fn storage_instance_independance() { module2::Map::::insert(0, 0); module2::Map::::insert(0, 0); module2::Map::::insert(0, 0); - module2::LinkedMap::::insert(0, vec![]); - module2::LinkedMap::::insert(0, vec![]); - module2::LinkedMap::::insert(0, vec![]); - module2::LinkedMap::::insert(0, vec![]); + module2::LinkedMap::::insert::<_, Vec>(0, vec![]); + module2::LinkedMap::::insert::<_, Vec>(0, vec![]); + module2::LinkedMap::::insert::<_, Vec>(0, vec![]); + module2::LinkedMap::::insert::<_, Vec>(0, vec![]); module2::DoubleMap::::insert(&0, &0, &0); module2::DoubleMap::::insert(&0, &0, &0); module2::DoubleMap::::insert(&0, &0, &0); @@ -377,7 +377,7 @@ fn storage_with_instance_basic_operation() { assert_eq!(LinkedMap::get(key), vec![]); assert_eq!(LinkedMap::exists(key), false); assert_eq!(LinkedMap::enumerate().count(), 1); - LinkedMap::insert_ref(key, &vec![1]); + LinkedMap::insert(key, &vec![1]); assert_eq!(LinkedMap::enumerate().count(), 2); let key1 = 1; diff --git a/srml/support/test/tests/system.rs b/srml/support/test/tests/system.rs index 344a2bec73..1040b26cc6 100644 --- a/srml/support/test/tests/system.rs +++ b/srml/support/test/tests/system.rs @@ -1,12 +1,12 @@ -use support::codec::{Encode, Decode}; +use support::codec::{Encode, Decode, EncodeLike}; pub trait Trait: 'static + Eq + Clone { type Origin: Into, Self::Origin>> + From>; - type BlockNumber: Decode + Encode + Clone + Default; + type BlockNumber: Decode + Encode + EncodeLike + Clone + Default; type Hash; - type AccountId: Encode + Decode; + type AccountId: Encode + EncodeLike + Decode; type Event: From; } -- GitLab From 094cca7b7726ef407cd82e65efe4ab42fff33801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20R=2E=20Bald=C3=A9?= Date: Tue, 1 Oct 2019 23:10:37 +0100 Subject: [PATCH 168/275] Remove unused imports (#3737) --- core/consensus/babe/src/tests.rs | 2 +- srml/authority-discovery/src/lib.rs | 1 - srml/generic-asset/src/lib.rs | 2 +- srml/scored-pool/src/lib.rs | 2 +- srml/staking/src/mock.rs | 5 ----- srml/support/src/storage/storage_items.rs | 4 ++-- 6 files changed, 5 insertions(+), 11 deletions(-) diff --git a/core/consensus/babe/src/tests.rs b/core/consensus/babe/src/tests.rs index 85c3101e5e..32ad826cb1 100644 --- a/core/consensus/babe/src/tests.rs +++ b/core/consensus/babe/src/tests.rs @@ -30,7 +30,7 @@ use consensus_common::import_queue::{ use network::test::*; use network::test::{Block as TestBlock, PeersClient}; use network::config::BoxFinalityProofRequestBuilder; -use sr_primitives::{generic::DigestItem, traits::{Block as BlockT, DigestFor, NumberFor}}; +use sr_primitives::{generic::DigestItem, traits::{Block as BlockT, DigestFor}}; use network::config::ProtocolConfig; use tokio::runtime::current_thread; use client::BlockchainEvents; diff --git a/srml/authority-discovery/src/lib.rs b/srml/authority-discovery/src/lib.rs index c8857630fb..2ec9e98835 100644 --- a/srml/authority-discovery/src/lib.rs +++ b/srml/authority-discovery/src/lib.rs @@ -138,7 +138,6 @@ mod tests { use primitives::testing::KeyStore; use primitives::{crypto::key_types, sr25519, traits::BareCryptoStore, H256}; use runtime_io::{with_externalities, TestExternalities}; - use sr_primitives::generic::UncheckedExtrinsic; use sr_primitives::testing::{Header, UintAuthorityId}; use sr_primitives::traits::{ConvertInto, IdentityLookup, OpaqueKeys}; use sr_primitives::Perbill; diff --git a/srml/generic-asset/src/lib.rs b/srml/generic-asset/src/lib.rs index 1f4c395d8d..6791ee5785 100644 --- a/srml/generic-asset/src/lib.rs +++ b/srml/generic-asset/src/lib.rs @@ -166,7 +166,7 @@ use support::{ Currency, ExistenceRequirement, Imbalance, LockIdentifier, LockableCurrency, ReservableCurrency, SignedImbalance, UpdateBalanceOutcome, WithdrawReason, WithdrawReasons, }, - Parameter, StorageDoubleMap, StorageMap, StorageValue, + Parameter, StorageMap, }; use system::{ensure_signed, ensure_root}; diff --git a/srml/scored-pool/src/lib.rs b/srml/scored-pool/src/lib.rs index 4d92caa559..4739e165d1 100644 --- a/srml/scored-pool/src/lib.rs +++ b/srml/scored-pool/src/lib.rs @@ -91,7 +91,7 @@ mod tests; use codec::FullCodec; use rstd::prelude::*; use support::{ - StorageValue, StorageMap, decl_module, decl_storage, decl_event, ensure, + StorageValue, decl_module, decl_storage, decl_event, ensure, traits::{ChangeMembers, InitializeMembers, Currency, Get, ReservableCurrency}, }; use system::{self, ensure_root, ensure_signed}; diff --git a/srml/staking/src/mock.rs b/srml/staking/src/mock.rs index 8263e159c1..d8d3656142 100644 --- a/srml/staking/src/mock.rs +++ b/srml/staking/src/mock.rs @@ -394,11 +394,6 @@ pub fn check_nominator_exposure(stash: u64) { ); } -pub fn assert_total_expo(stash: u64, val: u64) { - let expo = Staking::stakers(&stash); - assert_eq!(expo.total, val, "total exposure mismatch {:?} != {:?}", expo.total, val); -} - pub fn assert_is_stash(acc: u64) { assert!(Staking::bonded(&acc).is_some(), "Not a stash."); } diff --git a/srml/support/src/storage/storage_items.rs b/srml/support/src/storage/storage_items.rs index 67d301dad9..24a7f3984a 100644 --- a/srml/support/src/storage/storage_items.rs +++ b/srml/support/src/storage/storage_items.rs @@ -19,7 +19,7 @@ //! This crate exports a macro `storage_items!` and traits describing behavior of generated //! structs. //! -//! Three kinds of data types are currently supported: +//! Two kinds of data types are currently supported: //! - values //! - maps //! @@ -758,7 +758,7 @@ mod test3 { #[cfg(test)] #[allow(dead_code)] mod test_append_and_len { - use crate::storage::{StorageMap, StorageValue}; + use crate::storage::{StorageValue}; use runtime_io::{with_externalities, TestExternalities}; use codec::{Encode, Decode}; -- GitLab From 223554e547fe802d566815cacf3acf6ce0e7fb78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 2 Oct 2019 10:03:18 +0200 Subject: [PATCH 169/275] Move offchain worker http helpers to `sr-primitives`. (#3733) * Move offchain helpers to sr-primitives. * Add some docs and fix tests. * Refresh cargo.lock * Bump runtime. * Don't run offchain http example. --- Cargo.lock | 2 +- core/sr-io/Cargo.toml | 3 -- core/sr-io/src/lib.rs | 2 - core/sr-primitives/Cargo.toml | 3 +- core/sr-primitives/src/lib.rs | 8 +-- .../src/offchain/http.rs | 49 +++++++++++++++---- .../src/offchain/mod.rs | 0 7 files changed, 47 insertions(+), 20 deletions(-) rename core/{sr-io => sr-primitives}/src/offchain/http.rs (89%) rename core/{sr-io => sr-primitives}/src/offchain/mod.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index af05d52d2e..9b7c07e28d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3854,7 +3854,6 @@ dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", - "substrate-offchain 2.0.0", "substrate-primitives 2.0.0", "substrate-state-machine 2.0.0", "substrate-trie 2.0.0", @@ -3878,6 +3877,7 @@ dependencies = [ "sr-io 2.0.0", "sr-std 2.0.0", "substrate-application-crypto 2.0.0", + "substrate-offchain 2.0.0", "substrate-primitives 2.0.0", ] diff --git a/core/sr-io/Cargo.toml b/core/sr-io/Cargo.toml index 08a526f4e6..2200014e9c 100644 --- a/core/sr-io/Cargo.toml +++ b/core/sr-io/Cargo.toml @@ -19,9 +19,6 @@ environmental = { version = "1.0.1", optional = true } substrate-state-machine = { path = "../state-machine", optional = true } trie = { package = "substrate-trie", path = "../trie", optional = true } -[dev-dependencies] -substrate-offchain = { path = "../offchain" } - [features] default = ["std"] std = [ diff --git a/core/sr-io/src/lib.rs b/core/sr-io/src/lib.rs index 06114c02a3..4b00a84231 100644 --- a/core/sr-io/src/lib.rs +++ b/core/sr-io/src/lib.rs @@ -45,8 +45,6 @@ pub enum EcdsaVerifyError { BadSignature, } -pub mod offchain; - /// Converts a public trait definition into a private trait and set of public functions /// that assume the trait is implemented for `()` for ease of calling. macro_rules! export_api { diff --git a/core/sr-primitives/Cargo.toml b/core/sr-primitives/Cargo.toml index 271ed2dccc..ff12fa6143 100644 --- a/core/sr-primitives/Cargo.toml +++ b/core/sr-primitives/Cargo.toml @@ -19,9 +19,10 @@ rand = { version = "0.7.0", optional = true } impl-trait-for-tuples = "0.1.1" [dev-dependencies] -serde_json = "1.0" primitive-types = "0.5.1" rand = "0.7.2" +serde_json = "1.0" +substrate-offchain = { path = "../offchain" } [features] default = ["std"] diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index ddb935867e..1e26a3d423 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -44,13 +44,13 @@ use codec::{Encode, Decode}; #[cfg(feature = "std")] pub mod testing; -pub mod weights; -pub mod traits; pub mod curve; - pub mod generic; -pub mod transaction_validity; +pub mod offchain; pub mod sr_arithmetic; +pub mod traits; +pub mod transaction_validity; +pub mod weights; /// Re-export these since they're only "kind of" generic. pub use generic::{DigestItem, Digest}; diff --git a/core/sr-io/src/offchain/http.rs b/core/sr-primitives/src/offchain/http.rs similarity index 89% rename from core/sr-io/src/offchain/http.rs rename to core/sr-primitives/src/offchain/http.rs index 7aab309f13..6df18da83e 100644 --- a/core/sr-io/src/offchain/http.rs +++ b/core/sr-primitives/src/offchain/http.rs @@ -14,7 +14,38 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! A non-std set of HTTP types. +//! A high-level helpers for making HTTP requests from Offchain Workers. +//! +//! `sr-io` crate exposes a low level methods to make and control HTTP requests +//! available only for Offchain Workers. Those might be hard to use +//! and usually that level of control is not really necessary. +//! This module aims to provide high-level wrappers for those APIs +//! to simplify making HTTP requests. +//! +//! +//! Example: +//! ```rust,no_run +//! use sr_primitives::offchain::http::Request; +//! +//! // initiate a GET request to localhost:1234 +//! let request: Request = Request::get("http://localhost:1234"); +//! let pending = request +//! .add_header("X-Auth", "hunter2") +//! .send() +//! .unwrap(); +//! +//! // wait for the response indefinitely +//! let mut response = pending.wait().unwrap(); +//! +//! // then check the headers +//! let mut headers = response.headers().into_iter(); +//! assert_eq!(headers.current(), None); +//! +//! // and collect the body +//! let body = response.body(); +//! assert_eq!(body.clone().collect::>(), b"1234".to_vec()); +//! assert_eq!(body.error(), &None); +//! ``` use rstd::str; use rstd::prelude::Vec; @@ -192,11 +223,11 @@ impl<'a, I: AsRef<[u8]>, T: IntoIterator> Request<'a, T> { let meta = &[]; // start an http request. - let id = crate::http_request_start(self.method.as_ref(), self.url, meta).map_err(|_| HttpError::IoError)?; + let id = runtime_io::http_request_start(self.method.as_ref(), self.url, meta).map_err(|_| HttpError::IoError)?; // add custom headers for header in &self.headers { - crate::http_request_add_header( + runtime_io::http_request_add_header( id, header.name(), header.value(), @@ -205,11 +236,11 @@ impl<'a, I: AsRef<[u8]>, T: IntoIterator> Request<'a, T> { // write body for chunk in self.body { - crate::http_request_write_body(id, chunk.as_ref(), self.deadline)?; + runtime_io::http_request_write_body(id, chunk.as_ref(), self.deadline)?; } // finalise the request - crate::http_request_write_body(id, &[], self.deadline)?; + runtime_io::http_request_write_body(id, &[], self.deadline)?; Ok(PendingRequest { id, @@ -276,7 +307,7 @@ impl PendingRequest { deadline: impl Into> ) -> Vec> { let ids = requests.iter().map(|r| r.id).collect::>(); - let statuses = crate::http_response_wait(&ids, deadline.into()); + let statuses = runtime_io::http_response_wait(&ids, deadline.into()); statuses .into_iter() @@ -314,7 +345,7 @@ impl Response { /// Retrieve the headers for this response. pub fn headers(&mut self) -> &Headers { if self.headers.is_none() { - self.headers = Some(Headers { raw: crate::http_response_headers(self.id) }); + self.headers = Some(Headers { raw: runtime_io::http_response_headers(self.id) }); } self.headers.as_ref().expect("Headers were just set; qed") } @@ -393,7 +424,7 @@ impl Iterator for ResponseBody { } if self.filled_up_to.is_none() { - let result = crate::http_response_read_body(self.id, &mut self.buffer, self.deadline); + let result = runtime_io::http_response_read_body(self.id, &mut self.buffer, self.deadline); match result { Err(e) => { self.error = Some(e); @@ -481,7 +512,7 @@ impl<'a> HeadersIterator<'a> { #[cfg(test)] mod tests { use super::*; - use crate::{TestExternalities, with_externalities}; + use runtime_io::{TestExternalities, with_externalities}; use substrate_offchain::testing; #[test] diff --git a/core/sr-io/src/offchain/mod.rs b/core/sr-primitives/src/offchain/mod.rs similarity index 100% rename from core/sr-io/src/offchain/mod.rs rename to core/sr-primitives/src/offchain/mod.rs -- GitLab From 27a86ed7156ad1a606669106db286f6223532ce9 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 2 Oct 2019 12:36:50 +0200 Subject: [PATCH 170/275] Fix quantization from OnDilution in treasury (#3736) * fix * bump version * remove println --- node/runtime/src/lib.rs | 2 +- srml/treasury/src/lib.rs | 74 +++++++++++++++++++--------------------- 2 files changed, 37 insertions(+), 39 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 7163d2c736..f4f71e37f3 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -84,7 +84,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 168, + spec_version: 169, impl_version: 169, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/treasury/src/lib.rs b/srml/treasury/src/lib.rs index 0fd561fca0..db8b0f34c9 100644 --- a/srml/treasury/src/lib.rs +++ b/srml/treasury/src/lib.rs @@ -75,9 +75,9 @@ use support::traits::{ Currency, ExistenceRequirement, Get, Imbalance, OnDilution, OnUnbalanced, ReservableCurrency, WithdrawReason }; -use sr_primitives::{Permill, ModuleId}; +use sr_primitives::{Permill, Perbill, ModuleId}; use sr_primitives::traits::{ - Zero, EnsureOrigin, StaticLookup, CheckedSub, CheckedMul, AccountIdConversion + Zero, EnsureOrigin, StaticLookup, AccountIdConversion, CheckedSub }; use sr_primitives::weights::SimpleDispatchInfo; use codec::{Encode, Decode}; @@ -343,10 +343,9 @@ impl OnDilution> for Module { if !minted.is_zero() && !portion.is_zero() { let total_issuance = T::Currency::total_issuance(); if let Some(funding) = total_issuance.checked_sub(&portion) { - let funding = funding / portion; - if let Some(funding) = funding.checked_mul(&minted) { - Self::on_unbalanced(T::Currency::issue(funding)); - } + let increase_ratio = Perbill::from_rational_approximation(minted, portion); + let funding = increase_ratio * funding; + Self::on_unbalanced(T::Currency::issue(funding)); } } } @@ -359,7 +358,11 @@ mod tests { use runtime_io::with_externalities; use support::{assert_noop, assert_ok, impl_outer_origin, parameter_types}; use primitives::{H256, Blake2Hasher}; - use sr_primitives::{Perbill, traits::{BlakeTwo256, OnFinalize, IdentityLookup}, testing::Header}; + use sr_primitives::{ + traits::{BlakeTwo256, OnFinalize, IdentityLookup}, + testing::Header, + assert_eq_error_rate, + }; impl_outer_origin! { pub enum Origin for Test {} @@ -460,6 +463,32 @@ mod tests { }); } + #[test] + fn minting_works_2() { + let tests = [(1, 10), (1, 20), (40, 130), (2, 66), (2, 67), (2, 100), (2, 101), (2, 134)]; + for &(minted, portion) in &tests { + with_externalities(&mut new_test_ext(), || { + let init_total_issuance = Balances::total_issuance(); + Treasury::on_dilution(minted, portion); + + assert_eq!( + Treasury::pot(), + (((init_total_issuance - portion) * minted) as f32 / portion as f32) + .round() as u64 + ); + + // Assert: + // portion / init_total_issuance + // == (portion + minted) / (init_total_issuance + Treasury::pot() + minted), + assert_eq_error_rate!( + portion * 1_000 / init_total_issuance, + (portion + minted) * 1_000 / (init_total_issuance + Treasury::pot() + minted), + 2, + ); + }); + } + } + #[test] fn spend_proposal_takes_min_deposit() { with_externalities(&mut new_test_ext(), || { @@ -577,37 +606,6 @@ mod tests { }); } - #[test] - // Note: This test demonstrates that `on_dilution` does not increase the pot with good resolution - // with large amounts of the network staked. https://github.com/paritytech/substrate/issues/2579 - // A fix to 2579 should include a change of this test. - fn on_dilution_quantization_effects() { - with_externalities(&mut new_test_ext(), || { - // minted = 1% of total issuance for all cases - assert_eq!(Balances::total_issuance(), 200); - - Treasury::on_dilution(2, 66); // portion = 33% of total issuance - assert_eq!(Treasury::pot(), 4); // should increase by 4 (200 - 66) / 66 * 2 - Balances::make_free_balance_be(&Treasury::account_id(), 0); - - Treasury::on_dilution(2, 67); // portion = 33+eps% of total issuance - assert_eq!(Treasury::pot(), 2); // should increase by 2 (200 - 67) / 67 * 2 - Balances::make_free_balance_be(&Treasury::account_id(), 0); - - Treasury::on_dilution(2, 100); // portion = 50% of total issuance - assert_eq!(Treasury::pot(), 2); // should increase by 2 (200 - 100) / 100 * 2 - Balances::make_free_balance_be(&Treasury::account_id(), 0); - - // If any more than 50% of the network is staked (i.e. (2 * portion) > total_issuance) - // then the pot will not increase. - Treasury::on_dilution(2, 101); // portion = 50+eps% of total issuance - assert_eq!(Treasury::pot(), 0); // should increase by 0 (200 - 101) / 101 * 2 - - Treasury::on_dilution(2, 134); // portion = 67% of total issuance - assert_eq!(Treasury::pot(), 0); // should increase by 0 (200 - 134) / 134 * 2 - }); - } - #[test] fn pot_underflow_should_not_diminish() { with_externalities(&mut new_test_ext(), || { -- GitLab From 7010ec7716e0edf97d61a29bd0c337648b3a57ae Mon Sep 17 00:00:00 2001 From: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> Date: Wed, 2 Oct 2019 09:51:49 -0400 Subject: [PATCH 171/275] BABE refactoring: split out verification (#3658) * Refactor parts of BABE verification into separate module * Fix silly compiler error * Move more of the verification code to verification.rs * Remove some unused imports * Fix line width * fix testsuite compile error * Fix compile errors in tests * Move authorship-related code to its own files * fix compile errors in tests * Respond to review comments by @rphmeier * improve docs * fix compile error * Add missing doc comment --- core/consensus/babe/src/authorship.rs | 214 +++++++++++ core/consensus/babe/src/lib.rs | 457 ++---------------------- core/consensus/babe/src/tests.rs | 6 +- core/consensus/babe/src/verification.rs | 232 ++++++++++++ 4 files changed, 482 insertions(+), 427 deletions(-) create mode 100644 core/consensus/babe/src/authorship.rs create mode 100644 core/consensus/babe/src/verification.rs diff --git a/core/consensus/babe/src/authorship.rs b/core/consensus/babe/src/authorship.rs new file mode 100644 index 0000000000..93405ff777 --- /dev/null +++ b/core/consensus/babe/src/authorship.rs @@ -0,0 +1,214 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! BABE authority selection and slot claiming. + +use merlin::Transcript; +use babe_primitives::{AuthorityId, BabeAuthorityWeight, BABE_ENGINE_ID, BABE_VRF_PREFIX}; +use babe_primitives::{Epoch, SlotNumber, AuthorityPair, BabePreDigest, BabeConfiguration}; +use primitives::{U256, blake2_256}; +use codec::Encode; +use schnorrkel::vrf::VRFInOut; +use primitives::Pair; +use keystore::KeyStorePtr; + +/// Calculates the primary selection threshold for a given authority, taking +/// into account `c` (`1 - c` represents the probability of a slot being empty). +pub(super) fn calculate_primary_threshold( + c: (u64, u64), + authorities: &[(AuthorityId, BabeAuthorityWeight)], + authority_index: usize, +) -> u128 { + use num_bigint::BigUint; + use num_rational::BigRational; + use num_traits::{cast::ToPrimitive, identities::One}; + + let c = c.0 as f64 / c.1 as f64; + + let theta = + authorities[authority_index].1 as f64 / + authorities.iter().map(|(_, weight)| weight).sum::() as f64; + + let calc = || { + let p = BigRational::from_float(1f64 - (1f64 - c).powf(theta))?; + let numer = p.numer().to_biguint()?; + let denom = p.denom().to_biguint()?; + ((BigUint::one() << 128) * numer / denom).to_u128() + }; + + calc().unwrap_or(u128::max_value()) +} + +/// Returns true if the given VRF output is lower than the given threshold, +/// false otherwise. +pub(super) fn check_primary_threshold(inout: &VRFInOut, threshold: u128) -> bool { + u128::from_le_bytes(inout.make_bytes::<[u8; 16]>(BABE_VRF_PREFIX)) < threshold +} + +/// Get the expected secondary author for the given slot and with given +/// authorities. This should always assign the slot to some authority unless the +/// authorities list is empty. +pub(super) fn secondary_slot_author( + slot_number: u64, + authorities: &[(AuthorityId, BabeAuthorityWeight)], + randomness: [u8; 32], +) -> Option<&AuthorityId> { + if authorities.is_empty() { + return None; + } + + let rand = U256::from((randomness, slot_number).using_encoded(blake2_256)); + + let authorities_len = U256::from(authorities.len()); + let idx = rand % authorities_len; + + let expected_author = authorities.get(idx.as_u32() as usize) + .expect("authorities not empty; index constrained to list length; \ + this is a valid index; qed"); + + Some(&expected_author.0) +} + +#[allow(deprecated)] +pub(super) fn make_transcript( + randomness: &[u8], + slot_number: u64, + epoch: u64, +) -> Transcript { + let mut transcript = Transcript::new(&BABE_ENGINE_ID); + transcript.commit_bytes(b"slot number", &slot_number.to_le_bytes()); + transcript.commit_bytes(b"current epoch", &epoch.to_le_bytes()); + transcript.commit_bytes(b"chain randomness", randomness); + transcript +} + + +/// Claim a secondary slot if it is our turn to propose, returning the +/// pre-digest to use when authoring the block, or `None` if it is not our turn +/// to propose. +fn claim_secondary_slot( + slot_number: SlotNumber, + authorities: &[(AuthorityId, BabeAuthorityWeight)], + keystore: &KeyStorePtr, + randomness: [u8; 32], +) -> Option<(BabePreDigest, AuthorityPair)> { + if authorities.is_empty() { + return None; + } + + let expected_author = super::authorship::secondary_slot_author( + slot_number, + authorities, + randomness, + )?; + + let keystore = keystore.read(); + + for (pair, authority_index) in authorities.iter() + .enumerate() + .flat_map(|(i, a)| { + keystore.key_pair::(&a.0).ok().map(|kp| (kp, i)) + }) + { + if pair.public() == *expected_author { + let pre_digest = BabePreDigest::Secondary { + slot_number, + authority_index: authority_index as u32, + }; + + return Some((pre_digest, pair)); + } + } + + None +} + +/// Tries to claim the given slot number. This method starts by trying to claim +/// a primary VRF based slot. If we are not able to claim it, then if we have +/// secondary slots enabled for the given epoch, we will fallback to trying to +/// claim a secondary slot. +pub(super) fn claim_slot( + slot_number: SlotNumber, + epoch: &Epoch, + config: &BabeConfiguration, + keystore: &KeyStorePtr, +) -> Option<(BabePreDigest, AuthorityPair)> { + claim_primary_slot(slot_number, epoch, config.c, keystore) + .or_else(|| { + if config.secondary_slots { + claim_secondary_slot( + slot_number, + &epoch.authorities, + keystore, + epoch.randomness, + ) + } else { + None + } + }) +} + +fn get_keypair(q: &AuthorityPair) -> &schnorrkel::Keypair { + use primitives::crypto::IsWrappedBy; + primitives::sr25519::Pair::from_ref(q).as_ref() +} + +/// Claim a primary slot if it is our turn. Returns `None` if it is not our turn. +/// This hashes the slot number, epoch, genesis hash, and chain randomness into +/// the VRF. If the VRF produces a value less than `threshold`, it is our turn, +/// so it returns `Some(_)`. Otherwise, it returns `None`. +fn claim_primary_slot( + slot_number: SlotNumber, + epoch: &Epoch, + c: (u64, u64), + keystore: &KeyStorePtr, +) -> Option<(BabePreDigest, AuthorityPair)> { + let Epoch { authorities, randomness, epoch_index, .. } = epoch; + let keystore = keystore.read(); + + for (pair, authority_index) in authorities.iter() + .enumerate() + .flat_map(|(i, a)| { + keystore.key_pair::(&a.0).ok().map(|kp| (kp, i)) + }) + { + let transcript = super::authorship::make_transcript(randomness, slot_number, *epoch_index); + + // Compute the threshold we will use. + // + // We already checked that authorities contains `key.public()`, so it can't + // be empty. Therefore, this division in `calculate_threshold` is safe. + let threshold = super::authorship::calculate_primary_threshold(c, authorities, authority_index); + + let pre_digest = get_keypair(&pair) + .vrf_sign_after_check(transcript, |inout| super::authorship::check_primary_threshold(inout, threshold)) + .map(|s| { + BabePreDigest::Primary { + slot_number, + vrf_output: s.0.to_output(), + vrf_proof: s.1, + authority_index: authority_index as u32, + } + }); + + // early exit on first successful claim + if let Some(pre_digest) = pre_digest { + return Some((pre_digest, pair)); + } + } + + None +} diff --git a/core/consensus/babe/src/lib.rs b/core/consensus/babe/src/lib.rs index 800caf9d2b..bd2830d4e7 100644 --- a/core/consensus/babe/src/lib.rs +++ b/core/consensus/babe/src/lib.rs @@ -72,22 +72,14 @@ use sr_primitives::traits::{ Zero, }; use keystore::KeyStorePtr; -use codec::Encode; use parking_lot::Mutex; -use primitives::{blake2_256, Blake2Hasher, H256, Pair, Public, U256}; -use merlin::Transcript; +use primitives::{Blake2Hasher, H256, Pair}; use inherents::{InherentDataProviders, InherentData}; use substrate_telemetry::{ telemetry, CONSENSUS_TRACE, CONSENSUS_DEBUG, }; -use schnorrkel::{ - keys::Keypair, - vrf::{ - VRFProof, VRFInOut, VRFOutput, - }, -}; use consensus_common::{ self, BlockImport, Environment, Proposer, BlockCheckParams, ForkChoiceStrategy, BlockImportParams, BlockOrigin, Error as ConsensusError, @@ -107,12 +99,12 @@ use client::{ use slots::{CheckedHeader, check_equivocation}; use futures::prelude::*; use log::{warn, debug, info, trace}; - use slots::{SlotWorker, SlotData, SlotInfo, SlotCompatible}; use epoch_changes::descendent_query; - mod aux_schema; +mod verification; mod epoch_changes; +mod authorship; #[cfg(test)] mod tests; pub use babe_primitives::{ @@ -351,7 +343,7 @@ impl slots::SimpleSlotWorker for BabeWorker Option { debug!(target: "babe", "Attempting to claim slot {}", slot_number); - let s = claim_slot( + let s = authorship::claim_slot( slot_number, epoch_data, &*self.config, @@ -434,8 +426,7 @@ impl SlotWorker for BabeWorker where /// Extract the BABE pre digest from the given header. Pre-runtime digests are /// mandatory, the function will return `Err` if none is found. -fn find_pre_digest(header: &B::Header) -> Result - where DigestItemFor: CompatibleDigestItem, +fn find_pre_digest(header: &H) -> Result { // genesis block doesn't contain a pre digest so let's generate a // dummy one to not break any invariants in the rest of the code @@ -477,221 +468,6 @@ fn find_next_epoch_digest(header: &B::Header) Ok(epoch_digest) } -struct VerificationParams<'a, B: 'a + BlockT> { - /// the header being verified. - header: B::Header, - /// the pre-digest of the header being verified. this is optional - if prior - /// verification code had to read it, it can be included here to avoid duplicate - /// work. - pre_digest: Option, - /// the slot number of the current time. - slot_now: SlotNumber, - /// epoch descriptor of the epoch this block _should_ be under, if it's valid. - epoch: &'a Epoch, - /// genesis config of this BABE chain. - config: &'a Config, -} - -struct VerifiedHeaderInfo { - pre_digest: DigestItemFor, - seal: DigestItemFor, -} - -/// Check a header has been signed by the right key. If the slot is too far in -/// the future, an error will be returned. If successful, returns the pre-header -/// and the digest item containing the seal. -/// -/// The seal must be the last digest. Otherwise, the whole header is considered -/// unsigned. This is required for security and must not be changed. -/// -/// This digest item will always return `Some` when used with `as_babe_pre_digest`. -/// -/// The given header can either be from a primary or secondary slot assignment, -/// with each having different validation logic. -fn check_header( - params: VerificationParams, - client: &C, -) -> Result>, String> where - DigestItemFor: CompatibleDigestItem, -{ - let VerificationParams { - mut header, - pre_digest, - slot_now, - epoch, - config, - } = params; - - let authorities = &epoch.authorities; - let pre_digest = pre_digest.map(Ok).unwrap_or_else(|| find_pre_digest::(&header))?; - - trace!(target: "babe", "Checking header"); - let seal = match header.digest_mut().pop() { - Some(x) => x, - None => return Err(babe_err!("Header {:?} is unsealed", header.hash())), - }; - - let sig = seal.as_babe_seal().ok_or_else(|| { - babe_err!("Header {:?} has a bad seal", header.hash()) - })?; - - // the pre-hash of the header doesn't include the seal - // and that's what we sign - let pre_hash = header.hash(); - - if pre_digest.slot_number() > slot_now { - header.digest_mut().push(seal); - return Ok(CheckedHeader::Deferred(header, pre_digest.slot_number())); - } - - if pre_digest.authority_index() > authorities.len() as u32 { - return Err(babe_err!("Slot author not found")); - } - - match &pre_digest { - BabePreDigest::Primary { vrf_output, vrf_proof, authority_index, slot_number } => { - debug!(target: "babe", "Verifying Primary block"); - - let digest = (vrf_output, vrf_proof, *authority_index, *slot_number); - - check_primary_header::( - pre_hash, - digest, - sig, - &epoch, - config.c, - )?; - }, - BabePreDigest::Secondary { authority_index, slot_number } if config.secondary_slots => { - debug!(target: "babe", "Verifying Secondary block"); - - let digest = (*authority_index, *slot_number); - - check_secondary_header::( - pre_hash, - digest, - sig, - &epoch, - )?; - }, - _ => { - return Err(babe_err!("Secondary slot assignments are disabled for the current epoch.")); - } - } - - let author = &authorities[pre_digest.authority_index() as usize].0; - - // the header is valid but let's check if there was something else already - // proposed at the same slot by the given author - if let Some(equivocation_proof) = check_equivocation( - client, - slot_now, - pre_digest.slot_number(), - &header, - author, - ).map_err(|e| e.to_string())? { - babe_info!( - "Slot author {:?} is equivocating at slot {} with headers {:?} and {:?}", - author, - pre_digest.slot_number(), - equivocation_proof.fst_header().hash(), - equivocation_proof.snd_header().hash() - ); - } - - let info = VerifiedHeaderInfo { - pre_digest: CompatibleDigestItem::babe_pre_digest(pre_digest), - seal, - }; - Ok(CheckedHeader::Checked(header, info)) -} - -/// Check a primary slot proposal header. We validate that the given header is -/// properly signed by the expected authority, and that the contained VRF proof -/// is valid. Additionally, the weight of this block must increase compared to -/// its parent since it is a primary block. -fn check_primary_header( - pre_hash: B::Hash, - pre_digest: (&VRFOutput, &VRFProof, AuthorityIndex, SlotNumber), - signature: AuthoritySignature, - epoch: &Epoch, - c: (u64, u64), -) -> Result<(), String> - where DigestItemFor: CompatibleDigestItem, -{ - let (vrf_output, vrf_proof, authority_index, slot_number) = pre_digest; - - let author = &epoch.authorities[authority_index as usize].0; - - if AuthorityPair::verify(&signature, pre_hash, &author) { - let (inout, _) = { - let transcript = make_transcript( - &epoch.randomness, - slot_number, - epoch.epoch_index, - ); - - schnorrkel::PublicKey::from_bytes(author.as_slice()).and_then(|p| { - p.vrf_verify(transcript, vrf_output, vrf_proof) - }).map_err(|s| { - babe_err!("VRF verification failed: {:?}", s) - })? - }; - - let threshold = calculate_primary_threshold( - c, - &epoch.authorities, - authority_index as usize, - ); - - if !check_primary_threshold(&inout, threshold) { - return Err(babe_err!("VRF verification of block by author {:?} failed: \ - threshold {} exceeded", author, threshold)); - } - - Ok(()) - } else { - Err(babe_err!("Bad signature on {:?}", pre_hash)) - } -} - -/// Check a secondary slot proposal header. We validate that the given header is -/// properly signed by the expected authority, which we have a deterministic way -/// of computing. Additionally, the weight of this block must stay the same -/// compared to its parent since it is a secondary block. -fn check_secondary_header( - pre_hash: B::Hash, - pre_digest: (AuthorityIndex, SlotNumber), - signature: AuthoritySignature, - epoch: &Epoch, -) -> Result<(), String> { - let (authority_index, slot_number) = pre_digest; - - // check the signature is valid under the expected authority and - // chain state. - let expected_author = secondary_slot_author( - slot_number, - &epoch.authorities, - epoch.randomness, - ).ok_or_else(|| "No secondary author expected.".to_string())?; - - let author = &epoch.authorities[authority_index as usize].0; - - if expected_author != author { - let msg = format!("Invalid author: Expected secondary author: {:?}, got: {:?}.", - expected_author, - author, - ); - - return Err(msg); - } - - if AuthorityPair::verify(&signature, pre_hash.as_ref(), author) { - Ok(()) - } else { - Err(format!("Bad signature on {:?}", pre_hash)) - } -} #[derive(Default, Clone)] struct TimeSource(Arc, Vec<(Instant, u64)>)>>); @@ -717,7 +493,6 @@ pub struct BabeLink { epoch_changes: SharedEpochChanges, config: Config, } - /// A verifier for Babe blocks. pub struct BabeVerifier { client: Arc>, @@ -838,7 +613,7 @@ impl Verifier for BabeVerifier(&header)?; + let pre_digest = find_pre_digest::(&header)?; let epoch = { let epoch_changes = self.epoch_changes.lock(); epoch_changes.epoch_for_child_of( @@ -854,22 +629,41 @@ impl Verifier for BabeVerifier(v_params, &self.api)?; - match checked_header { + match verification::check_header::(v_params)? { CheckedHeader::Checked(pre_header, verified_info) => { let babe_pre_digest = verified_info.pre_digest.as_babe_pre_digest() .expect("check_header always returns a pre-digest digest item; qed"); let slot_number = babe_pre_digest.slot_number(); + let author = verified_info.author; + + // the header is valid but let's check if there was something else already + // proposed at the same slot by the given author + if let Some(equivocation_proof) = check_equivocation( + &*self.api, + slot_now, + babe_pre_digest.slot_number(), + &header, + &author, + ).map_err(|e| e.to_string())? { + info!( + "Slot author {:?} is equivocating at slot {} with headers {:?} and {:?}", + author, + babe_pre_digest.slot_number(), + equivocation_proof.fst_header().hash(), + equivocation_proof.snd_header().hash(), + ); + } + // if the body is passed through, we need to use the runtime // to check that the internally-set timestamp in the inherents // actually matches the slot set in the seal. @@ -939,193 +733,6 @@ fn register_babe_inherent_data_provider( } } -fn get_keypair(q: &AuthorityPair) -> &Keypair { - use primitives::crypto::IsWrappedBy; - primitives::sr25519::Pair::from_ref(q).as_ref() -} - -#[allow(deprecated)] -fn make_transcript( - randomness: &[u8], - slot_number: u64, - epoch: u64, -) -> Transcript { - let mut transcript = Transcript::new(&BABE_ENGINE_ID); - transcript.commit_bytes(b"slot number", &slot_number.to_le_bytes()); - transcript.commit_bytes(b"current epoch", &epoch.to_le_bytes()); - transcript.commit_bytes(b"chain randomness", randomness); - transcript -} - -/// Returns true if the given VRF output is lower than the given threshold, -/// false otherwise. -fn check_primary_threshold(inout: &VRFInOut, threshold: u128) -> bool { - u128::from_le_bytes(inout.make_bytes::<[u8; 16]>(BABE_VRF_PREFIX)) < threshold -} - -/// Calculates the primary selection threshold for a given authority, taking -/// into account `c` (`1 - c` represents the probability of a slot being empty). -fn calculate_primary_threshold( - c: (u64, u64), - authorities: &[(AuthorityId, BabeAuthorityWeight)], - authority_index: usize, -) -> u128 { - use num_bigint::BigUint; - use num_rational::BigRational; - use num_traits::{cast::ToPrimitive, identities::One}; - - let c = c.0 as f64 / c.1 as f64; - - let theta = - authorities[authority_index].1 as f64 / - authorities.iter().map(|(_, weight)| weight).sum::() as f64; - - let calc = || { - let p = BigRational::from_float(1f64 - (1f64 - c).powf(theta))?; - let numer = p.numer().to_biguint()?; - let denom = p.denom().to_biguint()?; - ((BigUint::one() << 128) * numer / denom).to_u128() - }; - - calc().unwrap_or(u128::max_value()) -} - -/// Tries to claim the given slot number. This method starts by trying to claim -/// a primary VRF based slot. If we are not able to claim it, then if we have -/// secondary slots enabled for the given epoch, we will fallback to trying to -/// claim a secondary slot. -fn claim_slot( - slot_number: SlotNumber, - epoch: &Epoch, - config: &BabeConfiguration, - keystore: &KeyStorePtr, -) -> Option<(BabePreDigest, AuthorityPair)> { - claim_primary_slot(slot_number, epoch, config.c, keystore) - .or_else(|| { - if config.secondary_slots { - claim_secondary_slot( - slot_number, - &epoch.authorities, - keystore, - epoch.randomness, - ) - } else { - None - } - }) -} - -/// Claim a primary slot if it is our turn. Returns `None` if it is not our turn. -/// This hashes the slot number, epoch, genesis hash, and chain randomness into -/// the VRF. If the VRF produces a value less than `threshold`, it is our turn, -/// so it returns `Some(_)`. Otherwise, it returns `None`. -fn claim_primary_slot( - slot_number: SlotNumber, - epoch: &Epoch, - c: (u64, u64), - keystore: &KeyStorePtr, -) -> Option<(BabePreDigest, AuthorityPair)> { - let Epoch { authorities, randomness, epoch_index, .. } = epoch; - let keystore = keystore.read(); - - for (pair, authority_index) in authorities.iter() - .enumerate() - .flat_map(|(i, a)| { - keystore.key_pair::(&a.0).ok().map(|kp| (kp, i)) - }) - { - let transcript = make_transcript(randomness, slot_number, *epoch_index); - - // Compute the threshold we will use. - // - // We already checked that authorities contains `key.public()`, so it can't - // be empty. Therefore, this division in `calculate_threshold` is safe. - let threshold = calculate_primary_threshold(c, authorities, authority_index); - - let pre_digest = get_keypair(&pair) - .vrf_sign_after_check(transcript, |inout| check_primary_threshold(inout, threshold)) - .map(|s| { - BabePreDigest::Primary { - slot_number, - vrf_output: s.0.to_output(), - vrf_proof: s.1, - authority_index: authority_index as u32, - } - }); - - // early exit on first successful claim - if let Some(pre_digest) = pre_digest { - return Some((pre_digest, pair)); - } - } - - None -} - -/// Get the expected secondary author for the given slot and with given -/// authorities. This should always assign the slot to some authority unless the -/// authorities list is empty. -fn secondary_slot_author( - slot_number: u64, - authorities: &[(AuthorityId, BabeAuthorityWeight)], - randomness: [u8; 32], -) -> Option<&AuthorityId> { - if authorities.is_empty() { - return None; - } - - let rand = U256::from((randomness, slot_number).using_encoded(blake2_256)); - - let authorities_len = U256::from(authorities.len()); - let idx = rand % authorities_len; - - let expected_author = authorities.get(idx.as_u32() as usize) - .expect("authorities not empty; index constrained to list length; \ - this is a valid index; qed"); - - Some(&expected_author.0) -} - -/// Claim a secondary slot if it is our turn to propose, returning the -/// pre-digest to use when authoring the block, or `None` if it is not our turn -/// to propose. -fn claim_secondary_slot( - slot_number: SlotNumber, - authorities: &[(AuthorityId, BabeAuthorityWeight)], - keystore: &KeyStorePtr, - randomness: [u8; 32], -) -> Option<(BabePreDigest, AuthorityPair)> { - if authorities.is_empty() { - return None; - } - - let expected_author = secondary_slot_author( - slot_number, - authorities, - randomness, - )?; - - let keystore = keystore.read(); - - for (pair, authority_index) in authorities.iter() - .enumerate() - .flat_map(|(i, a)| { - keystore.key_pair::(&a.0).ok().map(|kp| (kp, i)) - }) - { - if pair.public() == *expected_author { - let pre_digest = BabePreDigest::Secondary { - slot_number, - authority_index: authority_index as u32, - }; - - return Some((pre_digest, pair)); - } - } - - None -} - /// A block-import handler for BABE. /// /// This scans each imported block for epoch change signals. The signals are @@ -1200,7 +807,7 @@ impl BlockImport for BabeBlockImport return Err(ConsensusError::ClientImport(e.to_string()).into()), } - let pre_digest = find_pre_digest::(&block.header) + let pre_digest = find_pre_digest::(&block.header) .expect("valid babe headers must contain a predigest; \ header has been already verified; qed"); let slot_number = pre_digest.slot_number(); @@ -1222,7 +829,7 @@ impl BlockImport for BabeBlockImport(&parent_header) + let parent_slot = find_pre_digest::(&parent_header) .map(|d| d.slot_number()) .expect("parent is non-genesis; valid BABE headers contain a pre-digest; \ header has already been verified; qed"); @@ -1475,7 +1082,7 @@ pub mod test_helpers { |slot| link.config.genesis_epoch(slot), ).unwrap().unwrap(); - super::claim_slot( + authorship::claim_slot( slot_number, epoch.as_ref(), &link.config, diff --git a/core/consensus/babe/src/tests.rs b/core/consensus/babe/src/tests.rs index 32ad826cb1..adfe0f03af 100644 --- a/core/consensus/babe/src/tests.rs +++ b/core/consensus/babe/src/tests.rs @@ -20,6 +20,7 @@ // https://github.com/paritytech/substrate/issues/2532 #![allow(deprecated)] use super::*; +use authorship::claim_slot; use babe_primitives::{AuthorityPair, SlotNumber}; use client::block_builder::BlockBuilder; @@ -80,7 +81,7 @@ impl Environment for DummyFactory { -> Result { - let parent_slot = crate::find_pre_digest::(parent_header) + let parent_slot = crate::find_pre_digest(parent_header) .expect("parent header has a pre-digest") .slot_number(); @@ -97,6 +98,7 @@ impl DummyProposer { fn propose_with(&mut self, pre_digests: DigestFor) -> future::Ready> { + use codec::Encode; let block_builder = self.factory.client.new_block_at( &BlockId::Hash(self.parent_hash), pre_digests, @@ -106,7 +108,7 @@ impl DummyProposer { Err(e) => return future::ready(Err(e)), }; - let this_slot = crate::find_pre_digest::(block.header()) + let this_slot = crate::find_pre_digest(block.header()) .expect("baked block has valid pre-digest") .slot_number(); diff --git a/core/consensus/babe/src/verification.rs b/core/consensus/babe/src/verification.rs new file mode 100644 index 0000000000..05d6102450 --- /dev/null +++ b/core/consensus/babe/src/verification.rs @@ -0,0 +1,232 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Verification for BABE headers. +use schnorrkel::vrf::{VRFOutput, VRFProof}; +use sr_primitives::{traits::Header, traits::DigestItemFor}; +use primitives::{Pair, Public}; +use babe_primitives::{Epoch, BabePreDigest, CompatibleDigestItem, AuthorityId}; +use babe_primitives::{AuthoritySignature, SlotNumber, AuthorityIndex, AuthorityPair}; +use slots::CheckedHeader; +use log::{debug, trace}; +use super::{find_pre_digest, BlockT}; +use super::authorship::{make_transcript, calculate_primary_threshold, check_primary_threshold, secondary_slot_author}; + +/// BABE verification parameters +pub(super) struct VerificationParams<'a, B: 'a + BlockT> { + /// the header being verified. + pub(super) header: B::Header, + /// the pre-digest of the header being verified. this is optional - if prior + /// verification code had to read it, it can be included here to avoid duplicate + /// work. + pub(super) pre_digest: Option, + /// the slot number of the current time. + pub(super) slot_now: SlotNumber, + /// epoch descriptor of the epoch this block _should_ be under, if it's valid. + pub(super) epoch: &'a Epoch, + /// genesis config of this BABE chain. + pub(super) config: &'a super::Config, +} + +macro_rules! babe_err { + ($($i: expr),+) => { + { + debug!(target: "babe", $($i),+); + format!($($i),+) + } + }; +} + +/// Check a header has been signed by the right key. If the slot is too far in +/// the future, an error will be returned. If successful, returns the pre-header +/// and the digest item containing the seal. +/// +/// The seal must be the last digest. Otherwise, the whole header is considered +/// unsigned. This is required for security and must not be changed. +/// +/// This digest item will always return `Some` when used with `as_babe_pre_digest`. +/// +/// The given header can either be from a primary or secondary slot assignment, +/// with each having different validation logic. +pub(super) fn check_header( + params: VerificationParams, +) -> Result>, String> where + DigestItemFor: CompatibleDigestItem, +{ + let VerificationParams { + mut header, + pre_digest, + slot_now, + epoch, + config, + } = params; + + let authorities = &epoch.authorities; + let pre_digest = pre_digest.map(Ok).unwrap_or_else(|| find_pre_digest::(&header))?; + + trace!(target: "babe", "Checking header"); + let seal = match header.digest_mut().pop() { + Some(x) => x, + None => return Err(babe_err!("Header {:?} is unsealed", header.hash())), + }; + + let sig = seal.as_babe_seal().ok_or_else(|| { + babe_err!("Header {:?} has a bad seal", header.hash()) + })?; + + // the pre-hash of the header doesn't include the seal + // and that's what we sign + let pre_hash = header.hash(); + + if pre_digest.slot_number() > slot_now { + header.digest_mut().push(seal); + return Ok(CheckedHeader::Deferred(header, pre_digest.slot_number())); + } + + let author = match authorities.get(pre_digest.authority_index() as usize) { + Some(author) => author.0.clone(), + None => return Err(babe_err!("Slot author not found")), + }; + + match &pre_digest { + BabePreDigest::Primary { vrf_output, vrf_proof, authority_index, slot_number } => { + debug!(target: "babe", "Verifying Primary block"); + + let digest = (vrf_output, vrf_proof, *authority_index, *slot_number); + + check_primary_header::( + pre_hash, + digest, + sig, + &epoch, + config.c, + )?; + }, + BabePreDigest::Secondary { authority_index, slot_number } if config.secondary_slots => { + debug!(target: "babe", "Verifying Secondary block"); + + let digest = (*authority_index, *slot_number); + + check_secondary_header::( + pre_hash, + digest, + sig, + &epoch, + )?; + }, + _ => { + return Err(babe_err!("Secondary slot assignments are disabled for the current epoch.")); + } + } + + let info = VerifiedHeaderInfo { + pre_digest: CompatibleDigestItem::babe_pre_digest(pre_digest), + seal, + author, + }; + Ok(CheckedHeader::Checked(header, info)) +} + +pub(super) struct VerifiedHeaderInfo { + pub(super) pre_digest: DigestItemFor, + pub(super) seal: DigestItemFor, + pub(super) author: AuthorityId, +} + +/// Check a primary slot proposal header. We validate that the given header is +/// properly signed by the expected authority, and that the contained VRF proof +/// is valid. Additionally, the weight of this block must increase compared to +/// its parent since it is a primary block. +fn check_primary_header( + pre_hash: B::Hash, + pre_digest: (&VRFOutput, &VRFProof, AuthorityIndex, SlotNumber), + signature: AuthoritySignature, + epoch: &Epoch, + c: (u64, u64), +) -> Result<(), String> { + let (vrf_output, vrf_proof, authority_index, slot_number) = pre_digest; + + let author = &epoch.authorities[authority_index as usize].0; + + if AuthorityPair::verify(&signature, pre_hash, &author) { + let (inout, _) = { + let transcript = make_transcript( + &epoch.randomness, + slot_number, + epoch.epoch_index, + ); + + schnorrkel::PublicKey::from_bytes(author.as_slice()).and_then(|p| { + p.vrf_verify(transcript, vrf_output, vrf_proof) + }).map_err(|s| { + babe_err!("VRF verification failed: {:?}", s) + })? + }; + + let threshold = calculate_primary_threshold( + c, + &epoch.authorities, + authority_index as usize, + ); + + if !check_primary_threshold(&inout, threshold) { + return Err(babe_err!("VRF verification of block by author {:?} failed: \ + threshold {} exceeded", author, threshold)); + } + + Ok(()) + } else { + Err(babe_err!("Bad signature on {:?}", pre_hash)) + } +} + +/// Check a secondary slot proposal header. We validate that the given header is +/// properly signed by the expected authority, which we have a deterministic way +/// of computing. Additionally, the weight of this block must stay the same +/// compared to its parent since it is a secondary block. +fn check_secondary_header( + pre_hash: B::Hash, + pre_digest: (AuthorityIndex, SlotNumber), + signature: AuthoritySignature, + epoch: &Epoch, +) -> Result<(), String> { + let (authority_index, slot_number) = pre_digest; + + // check the signature is valid under the expected authority and + // chain state. + let expected_author = secondary_slot_author( + slot_number, + &epoch.authorities, + epoch.randomness, + ).ok_or_else(|| "No secondary author expected.".to_string())?; + + let author = &epoch.authorities[authority_index as usize].0; + + if expected_author != author { + let msg = format!("Invalid author: Expected secondary author: {:?}, got: {:?}.", + expected_author, + author, + ); + + return Err(msg); + } + + if AuthorityPair::verify(&signature, pre_hash.as_ref(), author) { + Ok(()) + } else { + Err(format!("Bad signature on {:?}", pre_hash)) + } +} -- GitLab From d7be2906dc0535e8d9f4537fc2b5c664dff6e2fb Mon Sep 17 00:00:00 2001 From: Marcio Diaz Date: Wed, 2 Oct 2019 20:30:43 +0200 Subject: [PATCH 172/275] Optimize tree route to sync faster (#3665) * Introduce HeaderMetadata and use it for tree_route. Add lowest_common_ancestor. * Add tests. --- Cargo.lock | 15 ++ Cargo.toml | 1 + core/cli/Cargo.toml | 1 + core/cli/src/informant.rs | 17 +- core/client/Cargo.toml | 2 + core/client/db/Cargo.toml | 1 + core/client/db/src/lib.rs | 230 ++++++++++++------- core/client/db/src/light.rs | 129 ++++++++--- core/client/header-metadata/Cargo.toml | 10 + core/client/header-metadata/src/lib.rs | 281 +++++++++++++++++++++++ core/client/src/blockchain.rs | 120 +--------- core/client/src/client.rs | 53 +++-- core/client/src/in_mem.rs | 26 ++- core/client/src/light/blockchain.rs | 33 ++- core/consensus/babe/Cargo.toml | 1 + core/consensus/babe/src/epoch_changes.rs | 3 +- core/consensus/babe/src/lib.rs | 12 +- core/finality-grandpa/Cargo.toml | 1 + core/finality-grandpa/src/environment.rs | 6 +- core/network/Cargo.toml | 3 +- core/network/src/chain.rs | 12 +- core/test-runtime/client/src/lib.rs | 2 +- 22 files changed, 678 insertions(+), 281 deletions(-) create mode 100644 core/client/header-metadata/Cargo.toml create mode 100644 core/client/header-metadata/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 9b7c07e28d..91c602167c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4698,6 +4698,7 @@ dependencies = [ "sr-primitives 2.0.0", "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-client 2.0.0", + "substrate-header-metadata 2.0.0", "substrate-keyring 2.0.0", "substrate-network 2.0.0", "substrate-panic-handler 2.0.0", @@ -4732,6 +4733,7 @@ dependencies = [ "sr-version 2.0.0", "substrate-consensus-common 2.0.0", "substrate-executor 2.0.0", + "substrate-header-metadata 2.0.0", "substrate-inherents 2.0.0", "substrate-keyring 2.0.0", "substrate-panic-handler 2.0.0", @@ -4760,6 +4762,7 @@ dependencies = [ "substrate-client 2.0.0", "substrate-consensus-common 2.0.0", "substrate-executor 2.0.0", + "substrate-header-metadata 2.0.0", "substrate-keyring 2.0.0", "substrate-primitives 2.0.0", "substrate-state-db 2.0.0", @@ -4845,6 +4848,7 @@ dependencies = [ "substrate-consensus-slots 2.0.0", "substrate-consensus-uncles 2.0.0", "substrate-executor 2.0.0", + "substrate-header-metadata 2.0.0", "substrate-inherents 2.0.0", "substrate-keyring 2.0.0", "substrate-keystore 2.0.0", @@ -5019,6 +5023,7 @@ dependencies = [ "substrate-consensus-babe-primitives 2.0.0", "substrate-consensus-common 2.0.0", "substrate-finality-grandpa-primitives 2.0.0", + "substrate-header-metadata 2.0.0", "substrate-inherents 2.0.0", "substrate-keyring 2.0.0", "substrate-keystore 2.0.0", @@ -5044,6 +5049,15 @@ dependencies = [ "substrate-client 2.0.0", ] +[[package]] +name = "substrate-header-metadata" +version = "2.0.0" +dependencies = [ + "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 2.0.0", +] + [[package]] name = "substrate-inherents" version = "2.0.0" @@ -5114,6 +5128,7 @@ dependencies = [ "substrate-client 2.0.0", "substrate-consensus-babe-primitives 2.0.0", "substrate-consensus-common 2.0.0", + "substrate-header-metadata 2.0.0", "substrate-keyring 2.0.0", "substrate-peerset 2.0.0", "substrate-primitives 2.0.0", diff --git a/Cargo.toml b/Cargo.toml index 75f86e7761..c1bac20a7c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ members = [ "core/cli", "core/client", "core/client/db", + "core/client/header-metadata", "core/consensus/aura", "core/consensus/babe", "core/consensus/common", diff --git a/core/cli/Cargo.toml b/core/cli/Cargo.toml index b33c48fbd1..ba20d11699 100644 --- a/core/cli/Cargo.toml +++ b/core/cli/Cargo.toml @@ -24,6 +24,7 @@ exit-future = "0.1" serde_json = "1.0" panic-handler = { package = "substrate-panic-handler", path = "../../core/panic-handler" } client = { package = "substrate-client", path = "../../core/client" } +header-metadata = { package = "substrate-header-metadata", path = "../../core/client/header-metadata" } network = { package = "substrate-network", path = "../../core/network" } sr-primitives = { path = "../../core/sr-primitives" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } diff --git a/core/cli/src/informant.rs b/core/cli/src/informant.rs index a5fe52c09a..9d7f04b8f6 100644 --- a/core/cli/src/informant.rs +++ b/core/cli/src/informant.rs @@ -20,7 +20,7 @@ use client::BlockchainEvents; use futures::{Future, Stream}; use futures03::{StreamExt as _, TryStreamExt as _}; use log::{info, warn}; -use sr_primitives::{generic::BlockId, traits::Header}; +use sr_primitives::traits::Header; use service::AbstractService; mod display; @@ -47,19 +47,18 @@ pub fn build(service: &impl AbstractService) -> impl Future info!( + match maybe_ancestor { + Ok(ref ancestor) if ancestor.hash != *last_hash => info!( "Reorg from #{},{} to #{},{}, common ancestor #{},{}", last_num, last_hash, n.header.number(), n.hash, - t.common_block().number, t.common_block().hash, + ancestor.number, ancestor.hash, ), Ok(_) => {}, Err(e) => warn!("Error computing tree route: {}", e), diff --git a/core/client/Cargo.toml b/core/client/Cargo.toml index 7fcd291f50..58de8233bb 100644 --- a/core/client/Cargo.toml +++ b/core/client/Cargo.toml @@ -27,6 +27,7 @@ runtime-version = { package = "sr-version", path = "../sr-version", default-feat rstd = { package = "sr-std", path = "../sr-std", default-features = false } inherents = { package = "substrate-inherents", path = "../inherents", default-features = false } sr-api-macros = { path = "../sr-api-macros" } +header-metadata = { package = "substrate-header-metadata", path = "header-metadata", optional = true } [dev-dependencies] env_logger = "0.6" @@ -45,6 +46,7 @@ std = [ "sr-primitives/std", "runtime-version/std", "hash-db/std", + "header-metadata", "consensus", "parking_lot", "derive_more", diff --git a/core/client/db/Cargo.toml b/core/client/db/Cargo.toml index 89a1dcc0cb..594bda744c 100644 --- a/core/client/db/Cargo.toml +++ b/core/client/db/Cargo.toml @@ -22,6 +22,7 @@ executor = { package = "substrate-executor", path = "../../executor" } state_db = { package = "substrate-state-db", path = "../../state-db" } trie = { package = "substrate-trie", path = "../../trie" } consensus_common = { package = "substrate-consensus-common", path = "../../consensus/common" } +header_metadata = { package = "substrate-header-metadata", path = "../header-metadata" } [dev-dependencies] substrate-keyring = { path = "../../keyring" } diff --git a/core/client/db/src/lib.rs b/core/client/db/src/lib.rs index 728858e2d6..126622364a 100644 --- a/core/client/db/src/lib.rs +++ b/core/client/db/src/lib.rs @@ -42,6 +42,7 @@ use client::backend::NewBlockState; use client::blockchain::{well_known_cache_keys, HeaderBackend}; use client::{ForkBlocks, ExecutionStrategies}; use client::backend::{StorageCollection, ChildStorageCollection}; +use client::error::Result as ClientResult; use codec::{Decode, Encode}; use hash_db::{Hasher, Prefix}; use kvdb::{KeyValueDB, DBTransaction}; @@ -61,10 +62,11 @@ use state_machine::{ DBValue, ChangesTrieTransaction, ChangesTrieCacheAction, ChangesTrieBuildCache, backend::Backend as StateBackend, }; -use crate::utils::{Meta, db_err, meta_keys, read_db, block_id_to_lookup_key, read_meta}; +use crate::utils::{Meta, db_err, meta_keys, read_db, read_meta}; use client::leaves::{LeafSet, FinalizationDisplaced}; use client::children; use state_db::StateDb; +use header_metadata::{CachedHeaderMetadata, HeaderMetadata, HeaderMetadataCache}; use crate::storage_cache::{CachingState, SharedCache, new_shared_cache}; use log::{trace, debug, warn}; pub use state_db::PruningMode; @@ -271,16 +273,18 @@ pub struct BlockchainDb { db: Arc, meta: Arc, Block::Hash>>>, leaves: RwLock>>, + header_metadata_cache: HeaderMetadataCache, } impl BlockchainDb { - fn new(db: Arc) -> Result { + fn new(db: Arc) -> ClientResult { let meta = read_meta::(&*db, columns::META, columns::HEADER)?; let leaves = LeafSet::read_from_db(&*db, columns::META, meta_keys::LEAF_PREFIX)?; Ok(BlockchainDb { db, leaves: RwLock::new(leaves), meta: Arc::new(RwLock::new(meta)), + header_metadata_cache: HeaderMetadataCache::default(), }) } @@ -310,7 +314,7 @@ impl BlockchainDb { } impl client::blockchain::HeaderBackend for BlockchainDb { - fn header(&self, id: BlockId) -> Result, client::error::Error> { + fn header(&self, id: BlockId) -> ClientResult> { utils::read_header(&*self.db, columns::KEY_LOOKUP, columns::HEADER, id) } @@ -325,7 +329,7 @@ impl client::blockchain::HeaderBackend for BlockchainDb) -> Result { + fn status(&self, id: BlockId) -> ClientResult { let exists = match id { BlockId::Hash(_) => read_db( &*self.db, @@ -341,16 +345,11 @@ impl client::blockchain::HeaderBackend for BlockchainDb Result>, client::error::Error> { - if let Some(lookup_key) = block_id_to_lookup_key::(&*self.db, columns::KEY_LOOKUP, BlockId::Hash(hash))? { - let number = utils::lookup_key_to_number(&lookup_key)?; - Ok(Some(number)) - } else { - Ok(None) - } + fn number(&self, hash: Block::Hash) -> ClientResult>> { + Ok(self.header_metadata(hash).ok().map(|header_metadata| header_metadata.number)) } - fn hash(&self, number: NumberFor) -> Result, client::error::Error> { + fn hash(&self, number: NumberFor) -> ClientResult> { self.header(BlockId::Number(number)).and_then(|maybe_header| match maybe_header { Some(header) => Ok(Some(header.hash().clone())), None => Ok(None), @@ -359,7 +358,7 @@ impl client::blockchain::HeaderBackend for BlockchainDb client::blockchain::Backend for BlockchainDb { - fn body(&self, id: BlockId) -> Result>, client::error::Error> { + fn body(&self, id: BlockId) -> ClientResult>> { match read_db(&*self.db, columns::KEY_LOOKUP, columns::BODY, id)? { Some(body) => match Decode::decode(&mut &body[..]) { Ok(body) => Ok(Some(body)), @@ -371,7 +370,7 @@ impl client::blockchain::Backend for BlockchainDb { } } - fn justification(&self, id: BlockId) -> Result, client::error::Error> { + fn justification(&self, id: BlockId) -> ClientResult> { match read_db(&*self.db, columns::KEY_LOOKUP, columns::JUSTIFICATION, id)? { Some(justification) => match Decode::decode(&mut &justification[..]) { Ok(justification) => Ok(Some(justification)), @@ -383,7 +382,7 @@ impl client::blockchain::Backend for BlockchainDb { } } - fn last_finalized(&self) -> Result { + fn last_finalized(&self) -> ClientResult { Ok(self.meta.read().finalized_hash.clone()) } @@ -391,11 +390,11 @@ impl client::blockchain::Backend for BlockchainDb { None } - fn leaves(&self) -> Result, client::error::Error> { + fn leaves(&self) -> ClientResult> { Ok(self.leaves.read().hashes()) } - fn children(&self, parent_hash: Block::Hash) -> Result, client::error::Error> { + fn children(&self, parent_hash: Block::Hash) -> ClientResult> { children::read_children(&*self.db, columns::META, meta_keys::CHILDREN_PREFIX, parent_hash) } } @@ -406,6 +405,31 @@ impl client::blockchain::ProvideCache for BlockchainDb HeaderMetadata for BlockchainDb { + type Error = client::error::Error; + + fn header_metadata(&self, hash: Block::Hash) -> Result, Self::Error> { + self.header_metadata_cache.header_metadata(hash).or_else(|_| { + self.header(BlockId::hash(hash))?.map(|header| { + let header_metadata = CachedHeaderMetadata::from(&header); + self.header_metadata_cache.insert_header_metadata( + header_metadata.hash, + header_metadata.clone(), + ); + header_metadata + }).ok_or(client::error::Error::UnknownBlock("header not found in db".to_owned())) + }) + } + + fn insert_header_metadata(&self, hash: Block::Hash, metadata: CachedHeaderMetadata) { + self.header_metadata_cache.insert_header_metadata(hash, metadata) + } + + fn remove_header_metadata(&self, hash: Block::Hash) { + self.header_metadata_cache.remove_header_metadata(hash); + } +} + /// Database transaction pub struct BlockImportOperation { old_state: CachingState, Block>, @@ -437,7 +461,7 @@ where Block: BlockT, { type State = CachingState, Block>; - fn state(&self) -> Result, client::error::Error> { + fn state(&self) -> ClientResult> { Ok(Some(&self.old_state)) } @@ -447,7 +471,7 @@ where Block: BlockT, body: Option>, justification: Option, leaf_state: NewBlockState, - ) -> Result<(), client::error::Error> { + ) -> ClientResult<()> { assert!(self.pending_block.is_none(), "Only one block per operation is allowed"); self.pending_block = Some(PendingBlock { header, @@ -462,7 +486,7 @@ where Block: BlockT, // Currently cache isn't implemented on full nodes. } - fn update_db_storage(&mut self, update: PrefixedMemoryDB) -> Result<(), client::error::Error> { + fn update_db_storage(&mut self, update: PrefixedMemoryDB) -> ClientResult<()> { self.db_updates = update; Ok(()) } @@ -471,7 +495,7 @@ where Block: BlockT, &mut self, top: StorageOverlay, children: ChildrenStorageOverlay - ) -> Result { + ) -> ClientResult { if top.iter().any(|(k, _)| well_known_keys::is_child_storage_key(k)) { return Err(client::error::Error::GenesisInvalid.into()); @@ -499,13 +523,13 @@ where Block: BlockT, fn update_changes_trie( &mut self, update: ChangesTrieTransaction>, - ) -> Result<(), client::error::Error> { + ) -> ClientResult<()> { self.changes_trie_updates = update.0; self.changes_trie_cache_update = Some(update.1); Ok(()) } - fn insert_aux(&mut self, ops: I) -> Result<(), client::error::Error> + fn insert_aux(&mut self, ops: I) -> ClientResult<()> where I: IntoIterator, Option>)> { self.aux_ops.append(&mut ops.into_iter().collect()); @@ -516,18 +540,18 @@ where Block: BlockT, &mut self, update: StorageCollection, child_update: ChildStorageCollection, - ) -> Result<(), client::error::Error> { + ) -> ClientResult<()> { self.storage_updates = update; self.child_storage_updates = child_update; Ok(()) } - fn mark_finalized(&mut self, block: BlockId, justification: Option) -> Result<(), client::error::Error> { + fn mark_finalized(&mut self, block: BlockId, justification: Option) -> ClientResult<()> { self.finalized_blocks.push((block, justification)); Ok(()) } - fn mark_head(&mut self, block: BlockId) -> Result<(), client::error::Error> { + fn mark_head(&mut self, block: BlockId) -> ClientResult<()> { assert!(self.set_head.is_none(), "Only one set head per operation is allowed"); self.set_head = Some(block); Ok(()) @@ -751,11 +775,11 @@ impl> Backend { /// Create a new instance of database backend. /// /// The pruning window is how old a block must be before the state is pruned. - pub fn new(config: DatabaseSettings, canonicalization_delay: u64) -> client::error::Result { + pub fn new(config: DatabaseSettings, canonicalization_delay: u64) -> ClientResult { Self::new_inner(config, canonicalization_delay) } - fn new_inner(config: DatabaseSettings, canonicalization_delay: u64) -> Result { + fn new_inner(config: DatabaseSettings, canonicalization_delay: u64) -> ClientResult { #[cfg(feature = "kvdb-rocksdb")] let db = crate::utils::open_database(&config, columns::META, "full")?; #[cfg(not(feature = "kvdb-rocksdb"))] @@ -795,7 +819,7 @@ impl> Backend { db: Arc, canonicalization_delay: u64, config: &DatabaseSettings - ) -> Result { + ) -> ClientResult { let is_archive_pruning = config.pruning.is_archive(); let blockchain = BlockchainDb::new(db.clone())?; let meta = blockchain.meta.clone(); @@ -881,7 +905,7 @@ impl> Backend { /// /// Currently changes tries configuration is set up once (at genesis) and could not /// be changed. Thus, we'll actually read value once and then just use cached value. - fn changes_trie_config(&self, block: Block::Hash) -> Result, client::error::Error> { + fn changes_trie_config(&self, block: Block::Hash) -> ClientResult> { let mut cached_changes_trie_config = self.changes_trie_config.lock(); match cached_changes_trie_config.clone() { Some(cached_changes_trie_config) => Ok(cached_changes_trie_config), @@ -904,7 +928,12 @@ impl> Backend { /// In the case where the new best block is a block to be imported, `route_to` /// should be the parent of `best_to`. In the case where we set an existing block /// to be best, `route_to` should equal to `best_to`. - fn set_head_with_transaction(&self, transaction: &mut DBTransaction, route_to: Block::Hash, best_to: (NumberFor, Block::Hash)) -> Result<(Vec, Vec), client::error::Error> { + fn set_head_with_transaction( + &self, + transaction: &mut DBTransaction, + route_to: Block::Hash, + best_to: (NumberFor, Block::Hash), + ) -> ClientResult<(Vec, Vec)> { let mut enacted = Vec::default(); let mut retracted = Vec::default(); @@ -912,12 +941,10 @@ impl> Backend { // cannot find tree route with empty DB. if meta.best_hash != Default::default() { - let tree_route = ::client::blockchain::tree_route( - |id| self.blockchain.header(id)?.ok_or_else( - || client::error::Error::UnknownBlock(format!("{:?}", id)) - ), - BlockId::Hash(meta.best_hash), - BlockId::Hash(route_to), + let tree_route = header_metadata::tree_route( + &self.blockchain, + meta.best_hash, + route_to, )?; // uncanonicalize: check safety violations and ensure the numbers no longer @@ -968,7 +995,7 @@ impl> Backend { &self, header: &Block::Header, last_finalized: Option, - ) -> Result<(), client::error::Error> { + ) -> ClientResult<()> { let last_finalized = last_finalized.unwrap_or_else(|| self.blockchain.meta.read().finalized_hash); if *header.parent_hash() != last_finalized { return Err(::client::error::Error::NonSequentialFinalization( @@ -986,7 +1013,7 @@ impl> Backend { last_finalized: Option, justification: Option, finalization_displaced: &mut Option>>, - ) -> Result<(Block::Hash, ::Number, bool, bool), client::error::Error> { + ) -> ClientResult<(Block::Hash, ::Number, bool, bool)> { // TODO: ensure best chain contains this block. let number = *header.number(); self.ensure_sequential_finalization(header, last_finalized)?; @@ -1014,7 +1041,7 @@ impl> Backend { hash: Block::Hash, number: NumberFor, ) - -> Result<(), client::error::Error> + -> ClientResult<()> { let number_u64 = number.saturated_into::(); if number_u64 > self.canonicalization_delay { @@ -1042,7 +1069,7 @@ impl> Backend { } fn try_commit_operation(&self, mut operation: BlockImportOperation) - -> Result<(), client::error::Error> + -> ClientResult<()> { let mut transaction = DBTransaction::new(); let mut finalization_displaced_leaves = None; @@ -1088,6 +1115,12 @@ impl> Backend { hash, )?; + let header_metadata = CachedHeaderMetadata::from(&pending_block.header); + self.blockchain.insert_header_metadata( + header_metadata.hash, + header_metadata, + ); + transaction.put(columns::HEADER, &lookup_key, &pending_block.header.encode()); if let Some(body) = pending_block.body { transaction.put(columns::BODY, &lookup_key, &body.encode()); @@ -1231,7 +1264,7 @@ impl> Backend { f_header: &Block::Header, f_hash: Block::Hash, displaced: &mut Option>> - ) -> Result<(), client::error::Error> where + ) -> ClientResult<()> where Block: BlockT, { let f_num = f_header.number().clone(); @@ -1284,7 +1317,7 @@ impl client::backend::AuxStore for Backend where Block: BlockT, D: IntoIterator, - >(&self, insert: I, delete: D) -> client::error::Result<()> { + >(&self, insert: I, delete: D) -> ClientResult<()> { let mut transaction = DBTransaction::new(); for (k, v) in insert { transaction.put(columns::AUX, k, v); @@ -1296,7 +1329,7 @@ impl client::backend::AuxStore for Backend where Block: BlockT Result>, client::error::Error> { + fn get_aux(&self, key: &[u8]) -> ClientResult>> { Ok(self.storage.db.get(columns::AUX, key).map(|r| r.map(|v| v.to_vec())).map_err(db_err)?) } } @@ -1308,7 +1341,7 @@ impl client::backend::Backend for Backend whe type ChangesTrieStorage = DbChangesTrieStorage; type OffchainStorage = offchain::LocalStorage; - fn begin_operation(&self) -> Result { + fn begin_operation(&self) -> ClientResult { let old_state = self.state_at(BlockId::Hash(Default::default()))?; Ok(BlockImportOperation { pending_block: None, @@ -1324,13 +1357,17 @@ impl client::backend::Backend for Backend whe }) } - fn begin_state_operation(&self, operation: &mut Self::BlockImportOperation, block: BlockId) -> Result<(), client::error::Error> { + fn begin_state_operation( + &self, + operation: &mut Self::BlockImportOperation, + block: BlockId, + ) -> ClientResult<()> { operation.old_state = self.state_at(block)?; Ok(()) } fn commit_operation(&self, operation: Self::BlockImportOperation) - -> Result<(), client::error::Error> + -> ClientResult<()> { match self.try_commit_operation(operation) { Ok(_) => { @@ -1345,7 +1382,7 @@ impl client::backend::Backend for Backend whe } fn finalize_block(&self, block: BlockId, justification: Option) - -> Result<(), client::error::Error> + -> ClientResult<()> { let mut transaction = DBTransaction::new(); let hash = self.blockchain.expect_block_hash_from_id(&block)?; @@ -1385,7 +1422,7 @@ impl client::backend::Backend for Backend whe Some(self.offchain_storage.clone()) } - fn revert(&self, n: NumberFor) -> Result, client::error::Error> { + fn revert(&self, n: NumberFor) -> ClientResult> { let mut best = self.blockchain.info().best_number; let finalized = self.blockchain.info().finalized_number; let revertible = best - finalized; @@ -1430,7 +1467,7 @@ impl client::backend::Backend for Backend whe Some(used) } - fn state_at(&self, block: BlockId) -> Result { + fn state_at(&self, block: BlockId) -> ClientResult { use client::blockchain::HeaderBackend as BcHeaderBackend; // special case for genesis initialization @@ -1466,7 +1503,7 @@ impl client::backend::Backend for Backend whe !self.storage.state_db.is_pruned(hash, number.saturated_into::()) } - fn destroy_state(&self, state: Self::State) -> Result<(), client::error::Error> { + fn destroy_state(&self, state: Self::State) -> ClientResult<()> { if let Some(hash) = state.cache.parent_hash.clone() { let is_best = || self.blockchain.meta.read().best_hash == hash; state.release().sync_cache(&[], &[], vec![], vec![], None, None, is_best); @@ -1493,6 +1530,8 @@ mod tests { use sr_primitives::testing::{Header, Block as RawBlock, ExtrinsicWrapper}; use sr_primitives::traits::{Hash, BlakeTwo256}; use state_machine::{TrieMut, TrieDBMut, ChangesTrieRootsStorage, ChangesTrieStorage}; + use header_metadata::{lowest_common_ancestor, tree_route}; + use test_client; type Block = RawBlock>; @@ -1521,7 +1560,6 @@ mod tests { extrinsics_root: H256, ) -> H256 { use sr_primitives::testing::Digest; - let (changes_root, changes_trie_update) = prepare_changes(changes); let digest = Digest { logs: vec![ @@ -2077,11 +2115,7 @@ mod tests { let b2 = insert_header(&backend, 2, b1, Vec::new(), Default::default()); { - let tree_route = ::client::blockchain::tree_route( - |id| blockchain.header(id)?.ok_or_else(|| client::error::Error::UnknownBlock(format!("{:?}", id))), - BlockId::Hash(a3), - BlockId::Hash(b2) - ).unwrap(); + let tree_route = tree_route(blockchain, a3, b2).unwrap(); assert_eq!(tree_route.common_block().hash, block0); assert_eq!(tree_route.retracted().iter().map(|r| r.hash).collect::>(), vec![a3, a2, a1]); @@ -2089,11 +2123,7 @@ mod tests { } { - let tree_route = ::client::blockchain::tree_route( - |id| blockchain.header(id)?.ok_or_else(|| client::error::Error::UnknownBlock(format!("{:?}", id))), - BlockId::Hash(a1), - BlockId::Hash(a3), - ).unwrap(); + let tree_route = tree_route(blockchain, a1, a3).unwrap(); assert_eq!(tree_route.common_block().hash, a1); assert!(tree_route.retracted().is_empty()); @@ -2101,11 +2131,7 @@ mod tests { } { - let tree_route = ::client::blockchain::tree_route( - |id| blockchain.header(id)?.ok_or_else(|| client::error::Error::UnknownBlock(format!("{:?}", id))), - BlockId::Hash(a3), - BlockId::Hash(a1), - ).unwrap(); + let tree_route = tree_route(blockchain, a3, a1).unwrap(); assert_eq!(tree_route.common_block().hash, a1); assert_eq!(tree_route.retracted().iter().map(|r| r.hash).collect::>(), vec![a3, a2]); @@ -2113,11 +2139,7 @@ mod tests { } { - let tree_route = ::client::blockchain::tree_route( - |id| blockchain.header(id)?.ok_or_else(|| client::error::Error::UnknownBlock(format!("{:?}", id))), - BlockId::Hash(a2), - BlockId::Hash(a2), - ).unwrap(); + let tree_route = tree_route(blockchain, a2, a2).unwrap(); assert_eq!(tree_route.common_block().hash, a2); assert!(tree_route.retracted().is_empty()); @@ -2134,11 +2156,7 @@ mod tests { let block1 = insert_header(&backend, 1, block0, Vec::new(), Default::default()); { - let tree_route = ::client::blockchain::tree_route( - |id| blockchain.header(id)?.ok_or_else(|| client::error::Error::UnknownBlock(format!("{:?}", id))), - BlockId::Hash(block0), - BlockId::Hash(block1), - ).unwrap(); + let tree_route = tree_route(blockchain, block0, block1).unwrap(); assert_eq!(tree_route.common_block().hash, block0); assert!(tree_route.retracted().is_empty()); @@ -2146,6 +2164,64 @@ mod tests { } } + #[test] + fn lowest_common_ancestor_works() { + let backend = Backend::::new_test(1000, 100); + let blockchain = backend.blockchain(); + let block0 = insert_header(&backend, 0, Default::default(), Vec::new(), Default::default()); + + // fork from genesis: 3 prong. + let a1 = insert_header(&backend, 1, block0, Vec::new(), Default::default()); + let a2 = insert_header(&backend, 2, a1, Vec::new(), Default::default()); + let a3 = insert_header(&backend, 3, a2, Vec::new(), Default::default()); + + // fork from genesis: 2 prong. + let b1 = insert_header(&backend, 1, block0, Vec::new(), H256::from([1; 32])); + let b2 = insert_header(&backend, 2, b1, Vec::new(), Default::default()); + + { + let lca = lowest_common_ancestor(blockchain, a3, b2).unwrap(); + + assert_eq!(lca.hash, block0); + assert_eq!(lca.number, 0); + } + + { + let lca = lowest_common_ancestor(blockchain, a1, a3).unwrap(); + + assert_eq!(lca.hash, a1); + assert_eq!(lca.number, 1); + } + + { + let lca = lowest_common_ancestor(blockchain, a3, a1).unwrap(); + + assert_eq!(lca.hash, a1); + assert_eq!(lca.number, 1); + } + + { + let lca = lowest_common_ancestor(blockchain, a2, a3).unwrap(); + + assert_eq!(lca.hash, a2); + assert_eq!(lca.number, 2); + } + + { + let lca = lowest_common_ancestor(blockchain, a2, a1).unwrap(); + + assert_eq!(lca.hash, a1); + assert_eq!(lca.number, 1); + } + + { + let lca = lowest_common_ancestor(blockchain, a2, a2).unwrap(); + + assert_eq!(lca.hash, a2); + assert_eq!(lca.number, 2); + } + } + #[test] fn test_leaves_with_complex_block_tree() { let backend: Arc> = Arc::new(Backend::new_test(20, 20)); diff --git a/core/client/db/src/light.rs b/core/client/db/src/light.rs index 07f805495c..111b8e0deb 100644 --- a/core/client/db/src/light.rs +++ b/core/client/db/src/light.rs @@ -35,6 +35,7 @@ use codec::{Decode, Encode}; use primitives::Blake2Hasher; use sr_primitives::generic::{DigestItem, BlockId}; use sr_primitives::traits::{Block as BlockT, Header as HeaderT, Zero, One, NumberFor}; +use header_metadata::{CachedHeaderMetadata, HeaderMetadata, HeaderMetadataCache}; use crate::cache::{DbCacheSync, DbCache, ComplexBlockId, EntryType as CacheEntryType}; use crate::utils::{self, meta_keys, Meta, db_err, read_db, block_id_to_lookup_key, read_meta}; use crate::DatabaseSettings; @@ -60,6 +61,7 @@ pub struct LightStorage { db: Arc, meta: RwLock, Block::Hash>>, cache: Arc>, + header_metadata_cache: HeaderMetadataCache, } impl LightStorage @@ -109,6 +111,7 @@ impl LightStorage db, meta: RwLock::new(meta), cache: Arc::new(DbCacheSync(RwLock::new(cache))), + header_metadata_cache: HeaderMetadataCache::default(), }) } @@ -192,6 +195,31 @@ impl BlockchainHeaderBackend for LightStorage } } +impl HeaderMetadata for LightStorage { + type Error = ClientError; + + fn header_metadata(&self, hash: Block::Hash) -> Result, Self::Error> { + self.header_metadata_cache.header_metadata(hash).or_else(|_| { + self.header(BlockId::hash(hash))?.map(|header| { + let header_metadata = CachedHeaderMetadata::from(&header); + self.header_metadata_cache.insert_header_metadata( + header_metadata.hash, + header_metadata.clone(), + ); + header_metadata + }).ok_or(ClientError::UnknownBlock("header not found in db".to_owned())) + }) + } + + fn insert_header_metadata(&self, hash: Block::Hash, metadata: CachedHeaderMetadata) { + self.header_metadata_cache.insert_header_metadata(hash, metadata) + } + + fn remove_header_metadata(&self, hash: Block::Hash) { + self.header_metadata_cache.remove_header_metadata(hash); + } +} + impl LightStorage { // Get block changes trie root, if available. fn changes_trie_root(&self, block: BlockId) -> ClientResult> { @@ -208,17 +236,18 @@ impl LightStorage { /// In the case where the new best block is a block to be imported, `route_to` /// should be the parent of `best_to`. In the case where we set an existing block /// to be best, `route_to` should equal to `best_to`. - fn set_head_with_transaction(&self, transaction: &mut DBTransaction, route_to: Block::Hash, best_to: (NumberFor, Block::Hash)) -> Result<(), client::error::Error> { + fn set_head_with_transaction( + &self, + transaction: &mut DBTransaction, + route_to: Block::Hash, + best_to: (NumberFor, Block::Hash), + ) -> ClientResult<()> { let lookup_key = utils::number_and_hash_to_lookup_key(best_to.0, &best_to.1)?; // handle reorg. let meta = self.meta.read(); if meta.best_hash != Default::default() { - let tree_route = ::client::blockchain::tree_route( - |id| self.header(id)?.ok_or_else(|| client::error::Error::UnknownBlock(format!("{:?}", id))), - BlockId::Hash(meta.best_hash), - BlockId::Hash(route_to), - )?; + let tree_route = header_metadata::tree_route(self, meta.best_hash, route_to)?; // update block number to hash lookup entries. for retracted in tree_route.retracted() { @@ -418,6 +447,12 @@ impl LightBlockchainStorage for LightStorage )?; transaction.put(columns::HEADER, &lookup_key, &header.encode()); + let header_metadata = CachedHeaderMetadata::from(&header); + self.header_metadata_cache.insert_header_metadata( + header.hash().clone(), + header_metadata, + ); + let is_genesis = number.is_zero(); if is_genesis { self.cache.0.write().set_genesis_hash(hash); @@ -537,6 +572,7 @@ pub(crate) mod tests { use client::cht; use sr_primitives::generic::DigestItem; use sr_primitives::testing::{H256 as Hash, Header, Block as RawBlock, ExtrinsicWrapper}; + use header_metadata::{lowest_common_ancestor, tree_route}; use super::*; type Block = RawBlock>; @@ -781,11 +817,7 @@ pub(crate) mod tests { let b2 = insert_block(&db, HashMap::new(), || default_header(&b1, 2)); { - let tree_route = ::client::blockchain::tree_route( - |id| db.header(id)?.ok_or_else(|| client::error::Error::UnknownBlock(format!("{:?}", id))), - BlockId::Hash(a3), - BlockId::Hash(b2) - ).unwrap(); + let tree_route = tree_route(&db, a3, b2).unwrap(); assert_eq!(tree_route.common_block().hash, block0); assert_eq!(tree_route.retracted().iter().map(|r| r.hash).collect::>(), vec![a3, a2, a1]); @@ -793,11 +825,7 @@ pub(crate) mod tests { } { - let tree_route = ::client::blockchain::tree_route( - |id| db.header(id)?.ok_or_else(|| client::error::Error::UnknownBlock(format!("{:?}", id))), - BlockId::Hash(a1), - BlockId::Hash(a3), - ).unwrap(); + let tree_route = tree_route(&db, a1, a3).unwrap(); assert_eq!(tree_route.common_block().hash, a1); assert!(tree_route.retracted().is_empty()); @@ -805,11 +833,7 @@ pub(crate) mod tests { } { - let tree_route = ::client::blockchain::tree_route( - |id| db.header(id)?.ok_or_else(|| client::error::Error::UnknownBlock(format!("{:?}", id))), - BlockId::Hash(a3), - BlockId::Hash(a1), - ).unwrap(); + let tree_route = tree_route(&db, a3, a1).unwrap(); assert_eq!(tree_route.common_block().hash, a1); assert_eq!(tree_route.retracted().iter().map(|r| r.hash).collect::>(), vec![a3, a2]); @@ -817,11 +841,7 @@ pub(crate) mod tests { } { - let tree_route = ::client::blockchain::tree_route( - |id| db.header(id)?.ok_or_else(|| client::error::Error::UnknownBlock(format!("{:?}", id))), - BlockId::Hash(a2), - BlockId::Hash(a2), - ).unwrap(); + let tree_route = tree_route(&db, a2, a2).unwrap(); assert_eq!(tree_route.common_block().hash, a2); assert!(tree_route.retracted().is_empty()); @@ -829,6 +849,63 @@ pub(crate) mod tests { } } + #[test] + fn lowest_common_ancestor_works() { + let db = LightStorage::new_test(); + let block0 = insert_block(&db, HashMap::new(), || default_header(&Default::default(), 0)); + + // fork from genesis: 3 prong. + let a1 = insert_block(&db, HashMap::new(), || default_header(&block0, 1)); + let a2 = insert_block(&db, HashMap::new(), || default_header(&a1, 2)); + let a3 = insert_block(&db, HashMap::new(), || default_header(&a2, 3)); + + // fork from genesis: 2 prong. + let b1 = insert_block(&db, HashMap::new(), || header_with_extrinsics_root(&block0, 1, Hash::from([1; 32]))); + let b2 = insert_block(&db, HashMap::new(), || default_header(&b1, 2)); + + { + let lca = lowest_common_ancestor(&db, a3, b2).unwrap(); + + assert_eq!(lca.hash, block0); + assert_eq!(lca.number, 0); + } + + { + let lca = lowest_common_ancestor(&db, a1, a3).unwrap(); + + assert_eq!(lca.hash, a1); + assert_eq!(lca.number, 1); + } + + { + let lca = lowest_common_ancestor(&db, a3, a1).unwrap(); + + assert_eq!(lca.hash, a1); + assert_eq!(lca.number, 1); + } + + { + let lca = lowest_common_ancestor(&db, a2, a3).unwrap(); + + assert_eq!(lca.hash, a2); + assert_eq!(lca.number, 2); + } + + { + let lca = lowest_common_ancestor(&db, a2, a1).unwrap(); + + assert_eq!(lca.hash, a1); + assert_eq!(lca.number, 1); + } + + { + let lca = lowest_common_ancestor(&db, a2, a2).unwrap(); + + assert_eq!(lca.hash, a2); + assert_eq!(lca.number, 2); + } + } + #[test] fn authorities_are_cached() { let db = LightStorage::new_test(); diff --git a/core/client/header-metadata/Cargo.toml b/core/client/header-metadata/Cargo.toml new file mode 100644 index 0000000000..43fcebb25b --- /dev/null +++ b/core/client/header-metadata/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "substrate-header-metadata" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +lru-cache = { version = "0.1.2" } +parking_lot = { version = "0.9.0" } +sr-primitives = { path = "../../sr-primitives" } diff --git a/core/client/header-metadata/src/lib.rs b/core/client/header-metadata/src/lib.rs new file mode 100644 index 0000000000..cce45f264e --- /dev/null +++ b/core/client/header-metadata/src/lib.rs @@ -0,0 +1,281 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Implements tree backend, cached header metadata and algorithms +//! to compute routes efficiently over the tree of headers. + +use sr_primitives::traits::{Block as BlockT, NumberFor, Header}; +use parking_lot::RwLock; +use lru_cache::LruCache; + +/// Set to the expected max difference between `best` and `finalized` blocks at sync. +const LRU_CACHE_SIZE: usize = 5_000; + +/// Get lowest common ancestor between two blocks in the tree. +/// +/// This implementation is efficient because our trees have very few and +/// small branches, and because of our current query pattern: +/// lca(best, final), lca(best + 1, final), lca(best + 2, final), etc. +/// The first call is O(h) but the others are O(1). +pub fn lowest_common_ancestor>( + backend: &T, + id_one: Block::Hash, + id_two: Block::Hash, +) -> Result, T::Error> { + let mut header_one = backend.header_metadata(id_one)?; + let mut header_two = backend.header_metadata(id_two)?; + + let mut orig_header_one = header_one.clone(); + let mut orig_header_two = header_two.clone(); + + // We move through ancestor links as much as possible, since ancestor >= parent. + + while header_one.number > header_two.number { + let ancestor_one = backend.header_metadata(header_one.ancestor)?; + + if ancestor_one.number >= header_two.number { + header_one = ancestor_one; + } else { + break + } + } + + while header_one.number < header_two.number { + let ancestor_two = backend.header_metadata(header_two.ancestor)?; + + if ancestor_two.number >= header_one.number { + header_two = ancestor_two; + } else { + break + } + } + + // Then we move the remaining path using parent links. + + while header_one.hash != header_two.hash { + if header_one.number > header_two.number { + header_one = backend.header_metadata(header_one.parent)?; + } else { + header_two = backend.header_metadata(header_two.parent)?; + } + } + + // Update cached ancestor links. + + if orig_header_one.number > header_one.number { + orig_header_one.ancestor = header_one.hash; + backend.insert_header_metadata(orig_header_one.hash, orig_header_one); + } + + if orig_header_two.number > header_one.number { + orig_header_two.ancestor = header_one.hash; + backend.insert_header_metadata(orig_header_two.hash, orig_header_two); + } + + Ok(HashAndNumber { + hash: header_one.hash, + number: header_one.number, + }) +} + +/// Compute a tree-route between two blocks. See tree-route docs for more details. +pub fn tree_route>( + backend: &T, + from: Block::Hash, + to: Block::Hash, +) -> Result, T::Error> { + let mut from = backend.header_metadata(from)?; + let mut to = backend.header_metadata(to)?; + + let mut from_branch = Vec::new(); + let mut to_branch = Vec::new(); + + while to.number > from.number { + to_branch.push(HashAndNumber { + number: to.number, + hash: to.hash, + }); + + to = backend.header_metadata(to.parent)?; + } + + while from.number > to.number { + from_branch.push(HashAndNumber { + number: from.number, + hash: from.hash, + }); + from = backend.header_metadata(from.parent)?; + } + + // numbers are equal now. walk backwards until the block is the same + + while to != from { + to_branch.push(HashAndNumber { + number: to.number, + hash: to.hash, + }); + to = backend.header_metadata(to.parent)?; + + from_branch.push(HashAndNumber { + number: from.number, + hash: from.hash, + }); + from = backend.header_metadata(from.parent)?; + } + + // add the pivot block. and append the reversed to-branch (note that it's reverse order originals) + let pivot = from_branch.len(); + from_branch.push(HashAndNumber { + number: to.number, + hash: to.hash, + }); + from_branch.extend(to_branch.into_iter().rev()); + + Ok(TreeRoute { + route: from_branch, + pivot, + }) +} + +/// Hash and number of a block. +#[derive(Debug)] +pub struct HashAndNumber { + /// The number of the block. + pub number: NumberFor, + /// The hash of the block. + pub hash: Block::Hash, +} + +/// A tree-route from one block to another in the chain. +/// +/// All blocks prior to the pivot in the deque is the reverse-order unique ancestry +/// of the first block, the block at the pivot index is the common ancestor, +/// and all blocks after the pivot is the ancestry of the second block, in +/// order. +/// +/// The ancestry sets will include the given blocks, and thus the tree-route is +/// never empty. +/// +/// ```text +/// Tree route from R1 to E2. Retracted is [R1, R2, R3], Common is C, enacted [E1, E2] +/// <- R3 <- R2 <- R1 +/// / +/// C +/// \-> E1 -> E2 +/// ``` +/// +/// ```text +/// Tree route from C to E2. Retracted empty. Common is C, enacted [E1, E2] +/// C -> E1 -> E2 +/// ``` +#[derive(Debug)] +pub struct TreeRoute { + route: Vec>, + pivot: usize, +} + +impl TreeRoute { + /// Get a slice of all retracted blocks in reverse order (towards common ancestor) + pub fn retracted(&self) -> &[HashAndNumber] { + &self.route[..self.pivot] + } + + /// Get the common ancestor block. This might be one of the two blocks of the + /// route. + pub fn common_block(&self) -> &HashAndNumber { + self.route.get(self.pivot).expect("tree-routes are computed between blocks; \ + which are included in the route; \ + thus it is never empty; qed") + } + + /// Get a slice of enacted blocks (descendents of the common ancestor) + pub fn enacted(&self) -> &[HashAndNumber] { + &self.route[self.pivot + 1 ..] + } +} + +/// Handles header metadata: hash, number, parent hash, etc. +pub trait HeaderMetadata { + /// Error used in case the header metadata is not found. + type Error; + + fn header_metadata(&self, hash: Block::Hash) -> Result, Self::Error>; + fn insert_header_metadata(&self, hash: Block::Hash, header_metadata: CachedHeaderMetadata); + fn remove_header_metadata(&self, hash: Block::Hash); +} + +/// Caches header metadata in an in-memory LRU cache. +pub struct HeaderMetadataCache { + cache: RwLock>>, +} + +impl HeaderMetadataCache { + /// Creates a new LRU header metadata cache with `capacity`. + pub fn new(capacity: usize) -> Self { + HeaderMetadataCache { + cache: RwLock::new(LruCache::new(capacity)), + } + } +} + +impl Default for HeaderMetadataCache { + fn default() -> Self { + HeaderMetadataCache { + cache: RwLock::new(LruCache::new(LRU_CACHE_SIZE)), + } + } +} + +impl HeaderMetadata for HeaderMetadataCache { + type Error = String; + + fn header_metadata(&self, hash: Block::Hash) -> Result, Self::Error> { + self.cache.write().get_mut(&hash).cloned() + .ok_or("header metadata not found in cache".to_owned()) + } + + fn insert_header_metadata(&self, hash: Block::Hash, metadata: CachedHeaderMetadata) { + self.cache.write().insert(hash, metadata); + } + + fn remove_header_metadata(&self, hash: Block::Hash) { + self.cache.write().remove(&hash); + } +} + +/// Cached header metadata. Used to efficiently traverse the tree. +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct CachedHeaderMetadata { + /// Hash of the header. + pub hash: Block::Hash, + /// Block number. + pub number: NumberFor, + /// Hash of parent header. + pub parent: Block::Hash, + /// Hash of an ancestor header. Used to jump through the tree. + ancestor: Block::Hash, +} + +impl From<&Block::Header> for CachedHeaderMetadata { + fn from(header: &Block::Header) -> Self { + CachedHeaderMetadata { + hash: header.hash().clone(), + number: header.number().clone(), + parent: header.parent_hash().clone(), + ancestor: header.parent_hash().clone(), + } + } +} diff --git a/core/client/src/blockchain.rs b/core/client/src/blockchain.rs index 7cf510faf9..73b7c138d0 100644 --- a/core/client/src/blockchain.rs +++ b/core/client/src/blockchain.rs @@ -24,6 +24,8 @@ use sr_primitives::Justification; use log::warn; use parking_lot::Mutex; +use header_metadata::HeaderMetadata; + use crate::error::{Error, Result}; /// Blockchain database header backend. Does not perform any validation. @@ -74,7 +76,7 @@ pub trait HeaderBackend: Send + Sync { } /// Blockchain database backend. Does not perform any validation. -pub trait Backend: HeaderBackend { +pub trait Backend: HeaderBackend + HeaderMetadata { /// Get block body. Returns `None` if block is not found. fn body(&self, id: BlockId) -> Result::Extrinsic>>>; /// Get block justification. Returns `None` if justification does not exist. @@ -257,122 +259,6 @@ pub enum BlockStatus { Unknown, } -/// An entry in a tree route. -#[derive(Debug)] -pub struct RouteEntry { - /// The number of the block. - pub number: ::Number, - /// The hash of the block. - pub hash: Block::Hash, -} - -/// A tree-route from one block to another in the chain. -/// -/// All blocks prior to the pivot in the deque is the reverse-order unique ancestry -/// of the first block, the block at the pivot index is the common ancestor, -/// and all blocks after the pivot is the ancestry of the second block, in -/// order. -/// -/// The ancestry sets will include the given blocks, and thus the tree-route is -/// never empty. -/// -/// ```text -/// Tree route from R1 to E2. Retracted is [R1, R2, R3], Common is C, enacted [E1, E2] -/// <- R3 <- R2 <- R1 -/// / -/// C -/// \-> E1 -> E2 -/// ``` -/// -/// ```text -/// Tree route from C to E2. Retracted empty. Common is C, enacted [E1, E2] -/// C -> E1 -> E2 -/// ``` -#[derive(Debug)] -pub struct TreeRoute { - route: Vec>, - pivot: usize, -} - -impl TreeRoute { - /// Get a slice of all retracted blocks in reverse order (towards common ancestor) - pub fn retracted(&self) -> &[RouteEntry] { - &self.route[..self.pivot] - } - - /// Get the common ancestor block. This might be one of the two blocks of the - /// route. - pub fn common_block(&self) -> &RouteEntry { - self.route.get(self.pivot).expect("tree-routes are computed between blocks; \ - which are included in the route; \ - thus it is never empty; qed") - } - - /// Get a slice of enacted blocks (descendents of the common ancestor) - pub fn enacted(&self) -> &[RouteEntry] { - &self.route[self.pivot + 1 ..] - } -} - -/// Compute a tree-route between two blocks. See tree-route docs for more details. -pub fn tree_route) -> Result<::Header>>( - load_header: F, - from: BlockId, - to: BlockId, -) -> Result> { - let mut from = load_header(from)?; - let mut to = load_header(to)?; - - let mut from_branch = Vec::new(); - let mut to_branch = Vec::new(); - - while to.number() > from.number() { - to_branch.push(RouteEntry { - number: to.number().clone(), - hash: to.hash(), - }); - - to = load_header(BlockId::Hash(*to.parent_hash()))?; - } - - while from.number() > to.number() { - from_branch.push(RouteEntry { - number: from.number().clone(), - hash: from.hash(), - }); - from = load_header(BlockId::Hash(*from.parent_hash()))?; - } - - // numbers are equal now. walk backwards until the block is the same - - while to != from { - to_branch.push(RouteEntry { - number: to.number().clone(), - hash: to.hash(), - }); - to = load_header(BlockId::Hash(*to.parent_hash()))?; - - from_branch.push(RouteEntry { - number: from.number().clone(), - hash: from.hash(), - }); - from = load_header(BlockId::Hash(*from.parent_hash()))?; - } - - // add the pivot block. and append the reversed to-branch (note that it's reverse order originalls) - let pivot = from_branch.len(); - from_branch.push(RouteEntry { - number: to.number().clone(), - hash: to.hash(), - }); - from_branch.extend(to_branch.into_iter().rev()); - - Ok(TreeRoute { - route: from_branch, - pivot, - }) -} - /// A list of all well known keys in the blockchain cache. pub mod well_known_cache_keys { /// The type representing cache keys. diff --git a/core/client/src/client.rs b/core/client/src/client.rs index 595aa0e9c7..aff099233a 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -51,6 +51,7 @@ use consensus::{ ImportResult, BlockOrigin, ForkChoiceStrategy, SelectChain, self, }; +use header_metadata::{HeaderMetadata, CachedHeaderMetadata}; use crate::{ runtime_api::{ @@ -966,10 +967,10 @@ impl Client where }; let retracted = if is_new_best { - let route_from_best = crate::blockchain::tree_route( - |id| self.header(&id)?.ok_or_else(|| Error::UnknownBlock(format!("{:?}", id))), - BlockId::Hash(info.best_hash), - BlockId::Hash(parent_hash), + let route_from_best = header_metadata::tree_route( + self.backend.blockchain(), + info.best_hash, + parent_hash, )?; route_from_best.retracted().iter().rev().map(|e| e.hash.clone()).collect() } else { @@ -1100,11 +1101,7 @@ impl Client where return Ok(()); } - let route_from_finalized = crate::blockchain::tree_route( - |id| self.header(&id)?.ok_or_else(|| Error::UnknownBlock(format!("{:?}", id))), - BlockId::Hash(last_finalized), - BlockId::Hash(block), - )?; + let route_from_finalized = header_metadata::tree_route(self.backend.blockchain(), last_finalized, block)?; if let Some(retracted) = route_from_finalized.retracted().get(0) { warn!("Safety violation: attempted to revert finalized block {:?} which is not in the \ @@ -1113,11 +1110,7 @@ impl Client where return Err(error::Error::NotInFinalizedChain); } - let route_from_best = crate::blockchain::tree_route( - |id| self.header(&id)?.ok_or_else(|| Error::UnknownBlock(format!("{:?}", id))), - BlockId::Hash(best_block), - BlockId::Hash(block), - )?; + let route_from_best = header_metadata::tree_route(self.backend.blockchain(), best_block, block)?; // if the block is not a direct ancestor of the current best chain, // then some other block is the common ancestor. @@ -1321,6 +1314,26 @@ impl Client where } } +impl HeaderMetadata for Client where + B: backend::Backend, + E: CallExecutor, + Block: BlockT, +{ + type Error = error::Error; + + fn header_metadata(&self, hash: Block::Hash) -> Result, Self::Error> { + self.backend.blockchain().header_metadata(hash) + } + + fn insert_header_metadata(&self, hash: Block::Hash, metadata: CachedHeaderMetadata) { + self.backend.blockchain().insert_header_metadata(hash, metadata) + } + + fn remove_header_metadata(&self, hash: Block::Hash) { + self.backend.blockchain().remove_header_metadata(hash) + } +} + impl ProvideUncles for Client where B: backend::Backend, E: CallExecutor, @@ -1798,7 +1811,7 @@ where /// Utility methods for the client. pub mod utils { use super::*; - use crate::{blockchain, error}; + use crate::error; use primitives::H256; use std::borrow::Borrow; @@ -1812,7 +1825,7 @@ pub mod utils { client: &'a T, current: Option<(H, H)>, ) -> impl Fn(&H256, &H256) -> Result + 'a - where T: ChainHeaderBackend, + where T: ChainHeaderBackend + HeaderMetadata, { move |base, hash| { if base == hash { return Ok(false); } @@ -1831,13 +1844,9 @@ pub mod utils { } } - let tree_route = blockchain::tree_route( - |id| client.header(id)?.ok_or_else(|| Error::UnknownBlock(format!("{:?}", id))), - BlockId::Hash(*hash), - BlockId::Hash(*base), - )?; + let ancestor = header_metadata::lowest_common_ancestor(client, *hash, *base)?; - Ok(tree_route.common_block().hash == *base) + Ok(ancestor.hash == *base) } } } diff --git a/core/client/src/in_mem.rs b/core/client/src/in_mem.rs index debfbbd6c7..99dc1b6263 100644 --- a/core/client/src/in_mem.rs +++ b/core/client/src/in_mem.rs @@ -27,12 +27,15 @@ use state_machine::backend::{Backend as StateBackend, InMemory}; use state_machine::{self, InMemoryChangesTrieStorage, ChangesTrieAnchorBlockId, ChangesTrieTransaction}; use hash_db::{Hasher, Prefix}; use trie::MemoryDB; +use header_metadata::{CachedHeaderMetadata, HeaderMetadata}; use crate::error; use crate::backend::{self, NewBlockState, StorageCollection, ChildStorageCollection}; use crate::light; use crate::leaves::LeafSet; -use crate::blockchain::{self, BlockStatus, HeaderBackend, well_known_cache_keys::Id as CacheKeyId}; +use crate::blockchain::{ + self, BlockStatus, HeaderBackend, well_known_cache_keys::Id as CacheKeyId +}; struct PendingBlock { block: StoredBlock, @@ -221,11 +224,7 @@ impl Blockchain { if &best_hash == header.parent_hash() { None } else { - let route = crate::blockchain::tree_route( - |id| self.header(id)?.ok_or_else(|| error::Error::UnknownBlock(format!("{:?}", id))), - BlockId::Hash(best_hash), - BlockId::Hash(*header.parent_hash()), - )?; + let route = header_metadata::tree_route(self, best_hash, *header.parent_hash())?; Some(route) } }; @@ -320,6 +319,21 @@ impl HeaderBackend for Blockchain { } } +impl HeaderMetadata for Blockchain { + type Error = error::Error; + + fn header_metadata(&self, hash: Block::Hash) -> Result, Self::Error> { + self.header(BlockId::hash(hash))?.map(|header| CachedHeaderMetadata::from(&header)) + .ok_or(error::Error::UnknownBlock("header not found".to_owned())) + } + + fn insert_header_metadata(&self, _hash: Block::Hash, _metadata: CachedHeaderMetadata) { + // No need to implement. + } + fn remove_header_metadata(&self, _hash: Block::Hash) { + // No need to implement. + } +} impl blockchain::Backend for Blockchain { fn body(&self, id: BlockId) -> error::Result::Extrinsic>>> { diff --git a/core/client/src/light/blockchain.rs b/core/client/src/light/blockchain.rs index 8fef351b7c..202f94cd74 100644 --- a/core/client/src/light/blockchain.rs +++ b/core/client/src/light/blockchain.rs @@ -23,18 +23,20 @@ use std::{sync::Arc, collections::HashMap}; use sr_primitives::{Justification, generic::BlockId}; use sr_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero}; +use header_metadata::{HeaderMetadata, CachedHeaderMetadata}; + use crate::backend::{AuxStore, NewBlockState}; use crate::blockchain::{ Backend as BlockchainBackend, BlockStatus, Cache as BlockchainCache, HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo, ProvideCache, - well_known_cache_keys, + well_known_cache_keys }; use crate::cht; use crate::error::{Error as ClientError, Result as ClientResult}; use crate::light::fetcher::{Fetcher, RemoteHeaderRequest}; /// Light client blockchain storage. -pub trait Storage: AuxStore + BlockchainHeaderBackend { +pub trait Storage: AuxStore + BlockchainHeaderBackend + HeaderMetadata { /// Store new header. Should refuse to revert any finalized blocks. /// /// Takes new authorities, the leaf state of the new block, and @@ -140,6 +142,22 @@ impl BlockchainHeaderBackend for Blockchain where Block: Blo } } +impl HeaderMetadata for Blockchain where Block: BlockT, S: Storage { + type Error = ClientError; + + fn header_metadata(&self, hash: Block::Hash) -> Result, Self::Error> { + self.storage.header_metadata(hash) + } + + fn insert_header_metadata(&self, hash: Block::Hash, metadata: CachedHeaderMetadata) { + self.storage.insert_header_metadata(hash, metadata) + } + + fn remove_header_metadata(&self, hash: Block::Hash) { + self.storage.remove_header_metadata(hash) + } +} + impl BlockchainBackend for Blockchain where Block: BlockT, S: Storage { fn body(&self, _id: BlockId) -> ClientResult>> { Err(ClientError::NotAvailableOnLightClient) @@ -281,6 +299,17 @@ pub mod tests { } } + impl HeaderMetadata for DummyStorage { + type Error = ClientError; + + fn header_metadata(&self, hash: Hash) -> Result, Self::Error> { + self.header(BlockId::hash(hash))?.map(|header| CachedHeaderMetadata::from(&header)) + .ok_or(ClientError::UnknownBlock("header not found".to_owned())) + } + fn insert_header_metadata(&self, _hash: Hash, _metadata: CachedHeaderMetadata) {} + fn remove_header_metadata(&self, _hash: Hash) {} + } + impl AuxStore for DummyStorage { fn insert_aux< 'a, diff --git a/core/consensus/babe/Cargo.toml b/core/consensus/babe/Cargo.toml index a6d1833b29..b268a6f41b 100644 --- a/core/consensus/babe/Cargo.toml +++ b/core/consensus/babe/Cargo.toml @@ -21,6 +21,7 @@ substrate-telemetry = { path = "../../telemetry" } keystore = { package = "substrate-keystore", path = "../../keystore" } srml-babe = { path = "../../../srml/babe" } client = { package = "substrate-client", path = "../../client" } +header-metadata = { package = "substrate-header-metadata", path = "../../client/header-metadata" } consensus-common = { package = "substrate-consensus-common", path = "../common" } uncles = { package = "substrate-consensus-uncles", path = "../uncles" } slots = { package = "substrate-consensus-slots", path = "../slots" } diff --git a/core/consensus/babe/src/epoch_changes.rs b/core/consensus/babe/src/epoch_changes.rs index 0dbad245e6..311271ae15 100644 --- a/core/consensus/babe/src/epoch_changes.rs +++ b/core/consensus/babe/src/epoch_changes.rs @@ -28,6 +28,7 @@ use codec::{Encode, Decode}; use client::error::Error as ClientError; use client::utils as client_utils; use client::blockchain::HeaderBackend; +use header_metadata::HeaderMetadata; use primitives::H256; use std::ops::Add; @@ -62,7 +63,7 @@ pub(crate) struct HeaderBackendDescendentBuilder(H, std::marker::Phant // https://github.com/paritytech/substrate/issues/3624 impl<'a, H, Block> IsDescendentOfBuilder for HeaderBackendDescendentBuilder<&'a H, Block> where - H: HeaderBackend, + H: HeaderBackend + HeaderMetadata, Block: BlockT, { type Error = ClientError; diff --git a/core/consensus/babe/src/lib.rs b/core/consensus/babe/src/lib.rs index bd2830d4e7..d2a16bedb8 100644 --- a/core/consensus/babe/src/lib.rs +++ b/core/consensus/babe/src/lib.rs @@ -93,7 +93,7 @@ use consensus_common::import_queue::{Verifier, BasicQueue, CacheKeyId}; use client::{ block_builder::api::BlockBuilder as BlockBuilderApi, blockchain::{self, HeaderBackend, ProvideCache}, BlockchainEvents, CallExecutor, Client, - error::Result as ClientResult, backend::{AuxStore, Backend}, + error::Result as ClientResult, error::Error as ClientError, backend::{AuxStore, Backend}, ProvideUncles, }; use slots::{CheckedHeader, check_equivocation}; @@ -101,6 +101,8 @@ use futures::prelude::*; use log::{warn, debug, info, trace}; use slots::{SlotWorker, SlotData, SlotInfo, SlotCompatible}; use epoch_changes::descendent_query; +use header_metadata::HeaderMetadata; + mod aux_schema; mod verification; mod epoch_changes; @@ -223,7 +225,7 @@ pub fn start_babe(BabeParams { > where B: BlockT, C: ProvideRuntimeApi + ProvideCache + ProvideUncles + BlockchainEvents - + HeaderBackend + Send + Sync + 'static, + + HeaderBackend + HeaderMetadata + Send + Sync + 'static, C::Api: BabeApi, SC: SelectChain + 'static, E: Environment + Send + Sync, @@ -296,7 +298,7 @@ struct BabeWorker { impl slots::SimpleSlotWorker for BabeWorker where B: BlockT, - C: ProvideRuntimeApi + ProvideCache + HeaderBackend, + C: ProvideRuntimeApi + ProvideCache + HeaderBackend + HeaderMetadata, C::Api: BabeApi, E: Environment, E::Proposer: Proposer, @@ -408,7 +410,7 @@ impl slots::SimpleSlotWorker for BabeWorker SlotWorker for BabeWorker where B: BlockT, - C: ProvideRuntimeApi + ProvideCache + HeaderBackend + Send + Sync, + C: ProvideRuntimeApi + ProvideCache + HeaderBackend + HeaderMetadata + Send + Sync, C::Api: BabeApi, E: Environment + Send + Sync, E::Proposer: Proposer, @@ -1071,7 +1073,7 @@ pub mod test_helpers { link: &BabeLink, ) -> Option where B: BlockT, - C: ProvideRuntimeApi + ProvideCache + HeaderBackend, + C: ProvideRuntimeApi + ProvideCache + HeaderBackend + HeaderMetadata, C::Api: BabeApi, { let epoch = link.epoch_changes.lock().epoch_for_child_of( diff --git a/core/finality-grandpa/Cargo.toml b/core/finality-grandpa/Cargo.toml index f2e1dd490b..4e835e14f8 100644 --- a/core/finality-grandpa/Cargo.toml +++ b/core/finality-grandpa/Cargo.toml @@ -21,6 +21,7 @@ substrate-telemetry = { path = "../telemetry" } keystore = { package = "substrate-keystore", path = "../keystore" } serde_json = "1.0" client = { package = "substrate-client", path = "../client" } +header-metadata = { package = "substrate-header-metadata", path = "../client/header-metadata" } inherents = { package = "substrate-inherents", path = "../../core/inherents" } network = { package = "substrate-network", path = "../network" } srml-finality-tracker = { path = "../../srml/finality-tracker" } diff --git a/core/finality-grandpa/src/environment.rs b/core/finality-grandpa/src/environment.rs index 5e3abb3ac7..70e45848be 100644 --- a/core/finality-grandpa/src/environment.rs +++ b/core/finality-grandpa/src/environment.rs @@ -498,11 +498,7 @@ pub(crate) fn ancestry, E, RA>( { if base == block { return Err(GrandpaError::NotDescendent) } - let tree_route_res = ::client::blockchain::tree_route( - |id| client.header(&id)?.ok_or(client::error::Error::UnknownBlock(format!("{:?}", id))), - BlockId::Hash(block), - BlockId::Hash(base), - ); + let tree_route_res = header_metadata::tree_route(client, block, base); let tree_route = match tree_route_res { Ok(tree_route) => tree_route, diff --git a/core/network/Cargo.toml b/core/network/Cargo.toml index 9a0a4fc678..e8d84e1c6f 100644 --- a/core/network/Cargo.toml +++ b/core/network/Cargo.toml @@ -19,13 +19,14 @@ futures03 = { package = "futures-preview", version = "0.3.0-alpha.18", features futures-timer = "0.3" linked-hash-map = "0.5" linked_hash_set = "0.1.3" -lru-cache = "0.1.1" +lru-cache = "0.1.2" rustc-hex = "2.0" rand = "0.6" libp2p = { version = "0.12.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] } fork-tree = { path = "../../core/utils/fork-tree" } consensus = { package = "substrate-consensus-common", path = "../../core/consensus/common" } client = { package = "substrate-client", path = "../../core/client" } +header_metadata = { package = "substrate-header-metadata", path = "../../core/client/header-metadata" } sr-primitives = { path = "../../core/sr-primitives" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } diff --git a/core/network/src/chain.rs b/core/network/src/chain.rs index d23068179f..1a1f649cae 100644 --- a/core/network/src/chain.rs +++ b/core/network/src/chain.rs @@ -153,14 +153,8 @@ impl Client for SubstrateClient where return Ok(false); } - let tree_route = ::client::blockchain::tree_route( - |id| self.header(&id)?.ok_or_else(|| - client::error::Error::UnknownBlock(format!("{:?}", id)) - ), - BlockId::Hash(*block), - BlockId::Hash(*base), - )?; - - Ok(tree_route.common_block().hash == *base) + let ancestor = header_metadata::lowest_common_ancestor(self, *block, *base)?; + + Ok(ancestor.hash == *base) } } diff --git a/core/test-runtime/client/src/lib.rs b/core/test-runtime/client/src/lib.rs index d2cf704fdf..722aa0b2b4 100644 --- a/core/test-runtime/client/src/lib.rs +++ b/core/test-runtime/client/src/lib.rs @@ -78,7 +78,7 @@ pub type LightExecutor = client::light::call_executor::GenesisCallExecutor< client::LocalCallExecutor< client::light::backend::Backend< client_db::light::LightStorage, - Blake2Hasher + Blake2Hasher, >, NativeExecutor > -- GitLab From 0cfe7438b6cf2a2a3cb1f4ba98a83a17d3fe866c Mon Sep 17 00:00:00 2001 From: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> Date: Wed, 2 Oct 2019 15:23:59 -0400 Subject: [PATCH 173/275] =?UTF-8?q?Upgrade=20dependencies=20whenever=20?= =?UTF-8?q?=E2=80=9Ceasy=E2=80=9D=20(#3556)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update all dependencies * Upgrade dependencies whenever “easy” “easy” means that there are no major changes required. * Fix build and bump paste dependency to 0.1.6 * Remove dead code * Re-add = dependency for futures-preview * Add missing std features for runtime-io * Remove git dependencies as updated versions have been published to crates.io * try to debug bug * For sr-io, "std" should imply "no_oom" and "no_panic_handler". Otherwise, rustc complains (correctly) about duplicate lang items. * Add missing "runtime-io/std" features * Fix compilation errors * Prevent duplicate lang items Rust does not allow duplicate lang items. When compiled without the `std` feature, `sr-io` defines two lang items. Therefore, `sr-io` compiled without `feature = "std"` must not be linked with `std`. However, `pwasm-utils` and `wasmi-validation` both bring in `std` unless compiled with `default-features = "false"`. This caused a duplicate lang item error. Building both with `default-features = "false"` prevents this error. When building with `feature = "std"`, they should both be built with the `std` feature, so this feature needs to be explicitly depended on. * Bump `impl_version` * Make tests pass Three tests used 1 less gas than they had previously. * Try to un-break build * Add a Cargo.lock file * Revert offchain code * Revert "Revert offchain code" This reverts commit d216d08cc6ca0344614669c1d24cde3aa5c0d4e2. * Don’t try to send a body with a GET request without adding a Transfer-Encoding or Content-Length header. This has always been wrong, but hyperium/hyper#1925 hid the bug until hyper was upgraded to 0.12.35. * Change some more GET requests to POST requests * Fix excess line width and remove an `extern crate` * Delete commented-out extern crate Co-Authored-By: Sergei Pepyakin * Fix regression in Cargo.toml files dev-dependencies need `default-features = false`, too. * Bump parity-wasm dependency * Bump `futures-preview` * Apply suggestions from code review Co-Authored-By: Bastian Köcher * Update Cargo.lock files * Apply suggestions from code review Co-Authored-By: Bastian Köcher * Update core/service/src/chain_ops.rs Co-Authored-By: Sergei Pepyakin --- CONTRIBUTING.adoc | 2 +- Cargo.lock | 1783 +++--- Cargo.toml | 6 +- SECURITY.md | 6 +- core/application-crypto/Cargo.toml | 2 +- core/authority-discovery/Cargo.toml | 20 +- core/basic-authorship/Cargo.toml | 4 +- core/chain-spec/Cargo.toml | 2 +- core/chain-spec/derive/Cargo.toml | 5 +- core/chain-spec/derive/src/impls.rs | 1 - core/chain-spec/src/lib.rs | 1 - core/cli/Cargo.toml | 38 +- core/cli/src/params.rs | 2 +- core/client/Cargo.toml | 18 +- core/client/db/Cargo.toml | 8 +- core/client/src/genesis.rs | 2 +- core/consensus/aura/Cargo.toml | 12 +- core/consensus/babe/Cargo.toml | 24 +- core/consensus/babe/primitives/Cargo.toml | 2 +- core/consensus/common/Cargo.toml | 8 +- core/consensus/pow/Cargo.toml | 4 +- core/consensus/rhd/Cargo.toml | 10 +- core/consensus/slots/Cargo.toml | 6 +- core/consensus/uncles/Cargo.toml | 2 +- core/executor/Cargo.toml | 20 +- core/executor/runtime-test/Cargo.toml | 2 +- core/executor/src/allocator.rs | 2 +- core/executor/src/wasm_executor.rs | 7 +- core/finality-grandpa/Cargo.toml | 18 +- core/finality-grandpa/primitives/Cargo.toml | 2 +- core/keyring/Cargo.toml | 2 +- core/keystore/Cargo.toml | 10 +- core/network/Cargo.toml | 52 +- core/network/src/protocol/sync.rs | 1 - core/network/src/test/sync.rs | 1 - core/offchain/Cargo.toml | 18 +- core/offchain/src/api/http.rs | 30 +- core/panic-handler/Cargo.toml | 4 +- core/peerset/Cargo.toml | 10 +- core/phragmen/Cargo.toml | 2 +- core/primitives/Cargo.toml | 45 +- core/primitives/src/crypto.rs | 3 +- core/primitives/src/ed25519.rs | 6 +- core/rpc-servers/Cargo.toml | 4 +- core/rpc/Cargo.toml | 16 +- core/rpc/api/Cargo.toml | 10 +- core/rpc/primitives/Cargo.toml | 2 +- core/serializer/Cargo.toml | 4 +- core/service/Cargo.toml | 26 +- core/service/src/chain_ops.rs | 4 +- core/service/src/lib.rs | 2 +- core/service/test/Cargo.toml | 14 +- core/sr-api-macros/Cargo.toml | 14 +- core/sr-io/Cargo.toml | 10 +- core/sr-io/without_std.rs | 1 - core/sr-primitives/Cargo.toml | 16 +- core/sr-sandbox/Cargo.toml | 6 +- core/sr-version/Cargo.toml | 6 +- core/sr-version/src/lib.rs | 7 +- core/state-db/Cargo.toml | 4 +- core/state-machine/Cargo.toml | 8 +- core/telemetry/Cargo.toml | 22 +- core/test-client/Cargo.toml | 2 +- core/test-runtime/Cargo.toml | 6 +- core/transaction-pool/Cargo.toml | 6 +- core/transaction-pool/graph/Cargo.toml | 10 +- core/trie/Cargo.toml | 12 +- core/utils/wasm-builder/Cargo.toml | 2 +- core/wasm-interface/Cargo.toml | 2 +- node-template/Cargo.toml | 14 +- node-template/runtime/Cargo.toml | 4 +- node/cli/Cargo.toml | 22 +- node/executor/Cargo.toml | 2 +- node/primitives/Cargo.toml | 2 +- node/rpc-client/Cargo.toml | 8 +- node/rpc/Cargo.toml | 8 +- node/runtime/Cargo.toml | 2 +- node/runtime/src/lib.rs | 4 +- node/testing/Cargo.toml | 2 +- srml/assets/Cargo.toml | 3 +- srml/aura/Cargo.toml | 4 +- srml/authority-discovery/Cargo.toml | 2 +- srml/authorship/Cargo.toml | 2 +- srml/babe/Cargo.toml | 6 +- srml/babe/src/lib.rs | 2 +- srml/balances/Cargo.toml | 6 +- srml/collective/Cargo.toml | 8 +- srml/contracts/Cargo.toml | 14 +- srml/democracy/Cargo.toml | 6 +- srml/elections-phragmen/Cargo.toml | 4 +- srml/elections/Cargo.toml | 8 +- srml/example/Cargo.toml | 2 +- srml/executive/Cargo.toml | 4 +- srml/finality-tracker/Cargo.toml | 4 +- srml/generic-asset/Cargo.toml | 2 +- srml/grandpa/Cargo.toml | 2 +- srml/im-online/Cargo.toml | 2 +- srml/indices/Cargo.toml | 6 +- srml/membership/Cargo.toml | 2 +- srml/metadata/Cargo.toml | 2 +- srml/offences/Cargo.toml | 4 +- srml/scored-pool/Cargo.toml | 2 +- srml/session/Cargo.toml | 11 +- srml/staking/Cargo.toml | 4 +- srml/staking/reward-curve/Cargo.toml | 4 +- srml/staking/reward-curve/src/log.rs | 2 +- srml/sudo/Cargo.toml | 2 +- srml/support/Cargo.toml | 10 +- srml/support/procedural/Cargo.toml | 4 +- .../procedural/src/storage/transformation.rs | 4 +- srml/support/procedural/tools/Cargo.toml | 6 +- .../procedural/tools/derive/Cargo.toml | 2 +- srml/support/test/Cargo.toml | 4 +- srml/system/Cargo.toml | 8 +- srml/timestamp/Cargo.toml | 4 +- srml/treasury/Cargo.toml | 2 +- subkey/Cargo.toml | 12 +- subkey/src/vanity.rs | 2 +- test-utils/chain-spec-builder/Cargo.lock | 5198 ----------------- test-utils/chain-spec-builder/Cargo.toml | 2 +- test-utils/transaction-factory/Cargo.toml | 2 +- 121 files changed, 1306 insertions(+), 6561 deletions(-) delete mode 100644 test-utils/chain-spec-builder/Cargo.lock diff --git a/CONTRIBUTING.adoc b/CONTRIBUTING.adoc index 9b39b11b00..1de4820a11 100644 --- a/CONTRIBUTING.adoc +++ b/CONTRIBUTING.adoc @@ -47,7 +47,7 @@ When reviewing a pull request, the end-goal is to suggest useful changes to the === Updating Polkadot as well -If your PR changes the external APIs or interfaces used by Polkadot, **a corresponding PR on Polkadot must** be submitted as well. If you tagged the PR with `breaksapi` or `breaksconsensus` this is most certainly the case, in all other cases check for it by running step 1. +If your PR changes the external APIs or interfaces used by Polkadot, **a corresponding PR on Polkadot must** be submitted as well. If you tagged the PR with `breaksapi` or `breaksconsensus` this is most certainly the case, in all other cases check for it by running step 1. To update a corresponding Polkadot PR: diff --git a/Cargo.lock b/Cargo.lock index 91c602167c..9d80227547 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,7 +2,7 @@ # It is not intended for manual editing. [[package]] name = "adler32" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -13,7 +13,7 @@ dependencies = [ "aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -23,7 +23,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -32,13 +32,13 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ahash" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "const-random 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -46,7 +46,7 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -54,12 +54,12 @@ dependencies = [ [[package]] name = "aio-limited" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -70,7 +70,15 @@ name = "ansi_term" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -116,7 +124,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -129,24 +137,24 @@ name = "atty" version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "autocfg" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "backtrace" -version = "0.3.33" +version = "0.3.38" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -154,8 +162,8 @@ name = "backtrace-sys" version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -169,7 +177,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "safemem 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -185,25 +193,25 @@ name = "bindgen" version = "0.47.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "cexpr 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "clang-sys 0.26.4 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "bitflags" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -218,13 +226,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "blake2" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -233,7 +241,7 @@ version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -274,15 +282,15 @@ dependencies = [ [[package]] name = "bs58" -version = "0.2.2" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bstr" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -298,7 +306,7 @@ dependencies = [ [[package]] name = "bumpalo" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -332,7 +340,7 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -341,7 +349,7 @@ name = "c2-chacha" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -352,13 +360,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cargo_metadata" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -369,10 +376,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cc" -version = "1.0.38" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -385,7 +393,7 @@ dependencies = [ [[package]] name = "cfg-if" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -400,10 +408,10 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", @@ -415,7 +423,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -426,10 +434,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -439,7 +447,7 @@ name = "clear_on_drop" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -447,15 +455,15 @@ name = "cloudabi" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cmake" -version = "0.1.40" +version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -464,7 +472,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "const-random-macro 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -472,13 +480,13 @@ name = "const-random-macro" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro-hack 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "constant_time_eq" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -487,7 +495,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -500,7 +508,7 @@ name = "crc32fast" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -514,16 +522,16 @@ dependencies = [ "criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -547,15 +555,6 @@ dependencies = [ "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "crossbeam-deque" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "crossbeam-deque" version = "0.7.1" @@ -571,9 +570,9 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -591,8 +590,8 @@ name = "crossbeam-utils" version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -605,7 +604,7 @@ name = "crypto-mac" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -623,7 +622,7 @@ name = "csv" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bstr 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -640,11 +639,11 @@ dependencies = [ [[package]] name = "ctor" -version = "0.1.9" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -653,7 +652,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -662,7 +661,7 @@ version = "3.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -676,14 +675,14 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "1.2.1" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -691,28 +690,17 @@ name = "data-encoding" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "derive_more" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "derive_more" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -750,13 +738,24 @@ name = "doc-comment" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ed25519-dalek" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ed25519-dalek" version = "1.0.0-pre.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "curve25519-dalek 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -764,7 +763,7 @@ dependencies = [ [[package]] name = "either" -version = "1.5.2" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -781,15 +780,15 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", - "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "environmental" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -805,7 +804,7 @@ name = "error-chain" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -814,7 +813,7 @@ name = "exit-future" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -823,7 +822,7 @@ name = "failure" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -834,7 +833,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -848,7 +847,7 @@ name = "fdlimit" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -856,9 +855,9 @@ name = "finality-grandpa" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "hashmap_core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -870,7 +869,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -883,15 +882,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "flate2" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide_c_api 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -925,10 +924,10 @@ name = "fs-swap" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -936,8 +935,8 @@ name = "fs2" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -950,7 +949,7 @@ name = "fuchsia-zircon" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -961,21 +960,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-channel-preview" -version = "0.3.0-alpha.18" +version = "0.3.0-alpha.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-core-preview" -version = "0.3.0-alpha.18" +version = "0.3.0-alpha.19" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -983,65 +982,63 @@ name = "futures-cpupool" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-executor-preview" -version = "0.3.0-alpha.18" +version = "0.3.0-alpha.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-io-preview" -version = "0.3.0-alpha.18" +version = "0.3.0-alpha.19" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-preview" -version = "0.3.0-alpha.18" +version = "0.3.0-alpha.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-channel-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-executor-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-executor-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-io-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-sink-preview" -version = "0.3.0-alpha.18" +version = "0.3.0-alpha.19" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures-core-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "futures-timer" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-util-preview" -version = "0.3.0-alpha.18" +version = "0.3.0-alpha.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-channel-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-io-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1076,7 +1073,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "c_linked_list 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "get_if_addrs-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1086,16 +1083,17 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "getrandom" -version = "0.1.6" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1113,11 +1111,11 @@ name = "globset" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "bstr 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1128,10 +1126,10 @@ dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1164,8 +1162,8 @@ name = "hashbrown" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ahash 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", - "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ahash 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1178,7 +1176,7 @@ name = "heapsize" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1196,19 +1194,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "hex-literal" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hex-literal-impl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal-impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "hex-literal-impl" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro-hack 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1252,7 +1250,7 @@ dependencies = [ [[package]] name = "http" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1266,8 +1264,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1278,7 +1276,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "humantime" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1304,19 +1302,19 @@ dependencies = [ [[package]] name = "hyper" -version = "0.12.33" +version = "0.12.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1324,9 +1322,9 @@ dependencies = [ "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1337,8 +1335,8 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1371,15 +1369,6 @@ dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "impl-serde" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "impl-serde" version = "0.2.1" @@ -1390,17 +1379,17 @@ dependencies = [ [[package]] name = "impl-trait-for-tuples" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "indexmap" -version = "1.0.2" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1418,7 +1407,7 @@ name = "iovec" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1432,7 +1421,7 @@ name = "itertools" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1440,12 +1429,22 @@ name = "itoa" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "jobserver" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "js-sys" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "wasm-bindgen 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1454,11 +1453,11 @@ version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1471,10 +1470,10 @@ name = "jsonrpc-core" version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1494,7 +1493,7 @@ dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1502,13 +1501,13 @@ name = "jsonrpc-http-server" version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-server-utils 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 2.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1517,7 +1516,7 @@ version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1530,12 +1529,12 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 2.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1545,7 +1544,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-server-utils 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ws 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1602,10 +1601,10 @@ dependencies = [ "fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rocksdb 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1616,11 +1615,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lazy_static" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "lazycell" @@ -1629,7 +1625,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.60" +version = "0.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1637,8 +1633,8 @@ name = "libloading" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1647,8 +1643,8 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core-derive 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-deflate 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1685,20 +1681,20 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "asn1_der 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bs58 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "multistream-select 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1720,7 +1716,7 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1728,8 +1724,8 @@ name = "libp2p-deflate" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "flate2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1739,9 +1735,9 @@ name = "libp2p-dns" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-dns-unofficial 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1750,14 +1746,14 @@ name = "libp2p-floodsub" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bs58 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "cuckoofilter 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-swarm 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1769,12 +1765,12 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-swarm 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1790,21 +1786,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-swarm 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "uint 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uint 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1817,17 +1813,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "dns-parser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-swarm 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-udp 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1839,9 +1835,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1854,12 +1850,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "curve25519-dalek 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", "snow 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1874,10 +1870,10 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-swarm 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1890,7 +1886,7 @@ name = "libp2p-plaintext" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1900,11 +1896,11 @@ name = "libp2p-ratelimit" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aio-limited 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "aio-limited 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1917,14 +1913,14 @@ dependencies = [ "aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", "rw-stream-sink 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1932,9 +1928,9 @@ dependencies = [ "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-futures 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-futures 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1942,7 +1938,7 @@ name = "libp2p-swarm" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1956,11 +1952,11 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "get_if_addrs 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "ipnet 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1971,9 +1967,9 @@ name = "libp2p-uds" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1982,13 +1978,13 @@ name = "libp2p-wasm-ext" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-futures 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-futures 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1997,9 +1993,9 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rw-stream-sink 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "soketto 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2014,9 +2010,9 @@ name = "libp2p-yamux" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "yamux 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2027,9 +2023,9 @@ version = "5.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bindgen 0.47.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2063,9 +2059,9 @@ name = "libz-sys" version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2112,15 +2108,15 @@ name = "log" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "log" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2137,7 +2133,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2151,7 +2147,7 @@ name = "memchr" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2179,7 +2175,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "merlin" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2196,32 +2192,12 @@ dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "miniz-sys" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "miniz_oxide" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "miniz_oxide_c_api" -version = "0.2.3" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2233,8 +2209,8 @@ dependencies = [ "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2247,7 +2223,7 @@ version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2258,7 +2234,7 @@ version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2284,8 +2260,8 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2304,13 +2280,13 @@ name = "native-tls" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.10.24 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.48 (registry+https://github.com/rust-lang/crates.io-index)", - "schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)", + "schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2321,9 +2297,9 @@ name = "net2" version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2331,10 +2307,10 @@ name = "nix" version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2343,17 +2319,17 @@ name = "node-cli" version = "2.0.0" dependencies = [ "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "node-executor 2.0.0", "node-primitives 2.0.0", "node-rpc 2.0.0", "node-runtime 2.0.0", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -2419,7 +2395,7 @@ dependencies = [ "substrate-test-client 2.0.0", "substrate-trie 2.0.0", "trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2441,12 +2417,12 @@ name = "node-rpc" version = "2.0.0" dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core-client 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-derive 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", "node-runtime 2.0.0", "node-testing 2.0.0", @@ -2465,10 +2441,10 @@ name = "node-rpc-client" version = "2.0.0" dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core-client 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", "substrate-rpc 2.0.0", ] @@ -2525,10 +2501,10 @@ name = "node-template" version = "2.0.0" dependencies = [ "ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "node-template-runtime 2.0.0", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2604,7 +2580,7 @@ dependencies = [ "substrate-keyring 2.0.0", "substrate-primitives 2.0.0", "substrate-test-client 2.0.0", - "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2614,7 +2590,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "nohash-hasher" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2631,7 +2607,7 @@ name = "num-bigint" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2641,7 +2617,7 @@ name = "num-integer" version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2650,7 +2626,7 @@ name = "num-rational" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2661,7 +2637,7 @@ name = "num-traits" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2669,7 +2645,7 @@ name = "num_cpus" version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2689,9 +2665,14 @@ dependencies = [ "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "once_cell" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "opaque-debug" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2699,12 +2680,12 @@ name = "openssl" version = "0.10.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.48 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2714,13 +2695,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "openssl-sys" -version = "0.9.48" +version = "0.9.49" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2729,15 +2710,7 @@ name = "output_vt100" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "owning_ref" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2759,7 +2732,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bs58 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2775,7 +2748,7 @@ name = "parity-multihash" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "blake2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2804,7 +2777,7 @@ dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2817,24 +2790,15 @@ name = "parity-util-mem" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parity-wasm" -version = "0.40.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "parking_lot" -version = "0.5.5" +version = "0.40.3" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "parking_lot" @@ -2874,27 +2838,16 @@ dependencies = [ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "parking_lot_core" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "parking_lot_core" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2902,11 +2855,11 @@ name = "parking_lot_core" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2914,14 +2867,14 @@ name = "parking_lot_core" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2929,33 +2882,33 @@ name = "parking_lot_core" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "paste" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "paste-impl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", + "paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "paste-impl" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro-hack 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3002,7 +2955,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "pkg-config" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -3016,7 +2969,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ctor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "ctor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3029,7 +2982,7 @@ dependencies = [ "fixed-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "impl-codec 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "impl-serde 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "uint 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uint 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3042,12 +2995,12 @@ dependencies = [ [[package]] name = "proc-macro-hack" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3060,7 +3013,7 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3084,7 +3037,7 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "multimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3102,7 +3055,7 @@ dependencies = [ "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3116,7 +3069,7 @@ dependencies = [ [[package]] name = "protobuf" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -3125,8 +3078,8 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.40.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.40.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3141,13 +3094,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "quickcheck" -version = "0.8.5" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3163,7 +3116,7 @@ name = "quote" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3171,7 +3124,7 @@ name = "rand" version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3181,10 +3134,10 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3194,9 +3147,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3204,8 +3157,8 @@ name = "rand" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3214,7 +3167,7 @@ dependencies = [ "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3222,8 +3175,8 @@ name = "rand" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3234,7 +3187,7 @@ name = "rand_chacha" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3265,7 +3218,7 @@ name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3297,9 +3250,9 @@ name = "rand_jitter" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3309,10 +3262,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3320,7 +3273,7 @@ name = "rand_pcg" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3343,23 +3296,23 @@ dependencies = [ [[package]] name = "rayon" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rayon-core" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3383,14 +3336,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "regex" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3403,18 +3355,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.10" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ucd-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "remove_dir_all" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3423,8 +3372,8 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3433,12 +3382,12 @@ name = "ring" version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3446,23 +3395,22 @@ name = "rocksdb" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "librocksdb-sys 5.18.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rpassword" -version = "3.0.2" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-demangle" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -3484,7 +3432,7 @@ version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", "sct 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3496,7 +3444,7 @@ name = "rustversion" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3507,7 +3455,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3526,7 +3474,7 @@ dependencies = [ [[package]] name = "safemem" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -3539,11 +3487,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3551,14 +3499,14 @@ name = "schnorrkel" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "curve25519-dalek 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "merlin 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "merlin 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3588,7 +3536,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3632,17 +3580,17 @@ name = "serde" version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" -version = "1.0.97" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3663,7 +3611,7 @@ dependencies = [ "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3691,7 +3639,7 @@ dependencies = [ "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3703,7 +3651,7 @@ dependencies = [ "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3744,7 +3692,7 @@ name = "slog-json" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3757,7 +3705,7 @@ version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3768,7 +3716,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3790,7 +3738,7 @@ dependencies = [ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "static_slice 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3800,11 +3748,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3819,7 +3767,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "spin" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -3840,15 +3788,15 @@ dependencies = [ "substrate-primitives 2.0.0", "substrate-state-machine 2.0.0", "substrate-test-runtime-client 2.0.0", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", - "trybuild 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", + "trybuild 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "sr-io" version = "2.0.0" dependencies = [ - "environmental 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "environmental 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "libsecp256k1 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3864,12 +3812,12 @@ dependencies = [ name = "sr-primitives" version = "2.0.0" dependencies = [ - "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "primitive-types 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3890,7 +3838,7 @@ dependencies = [ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", "substrate-primitives 2.0.0", - "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3914,7 +3862,7 @@ dependencies = [ name = "sr-version" version = "2.0.0" dependencies = [ - "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -3939,7 +3887,7 @@ dependencies = [ name = "srml-aura" version = "2.0.0" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3978,7 +3926,7 @@ dependencies = [ name = "srml-authorship" version = "0.1.0" dependencies = [ - "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -3993,8 +3941,8 @@ dependencies = [ name = "srml-babe" version = "2.0.0" dependencies = [ - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4033,7 +3981,7 @@ dependencies = [ name = "srml-collective" version = "2.0.0" dependencies = [ - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4052,9 +4000,9 @@ version = "2.0.0" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.40.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.40.3 (registry+https://github.com/rust-lang/crates.io-index)", "pwasm-utils 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4066,7 +4014,7 @@ dependencies = [ "srml-system 2.0.0", "srml-timestamp 2.0.0", "substrate-primitives 2.0.0", - "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "wasmi-validation 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4090,7 +4038,7 @@ dependencies = [ name = "srml-elections" version = "2.0.0" dependencies = [ - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4107,7 +4055,7 @@ dependencies = [ name = "srml-elections-phragmen" version = "2.0.0" dependencies = [ - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4139,7 +4087,7 @@ dependencies = [ name = "srml-executive" version = "2.0.0" dependencies = [ - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4156,7 +4104,7 @@ dependencies = [ name = "srml-finality-tracker" version = "2.0.0" dependencies = [ - "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4294,8 +4242,8 @@ dependencies = [ name = "srml-session" version = "2.0.0" dependencies = [ - "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4339,7 +4287,7 @@ name = "srml-staking-reward-curve" version = "2.0.0" dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4364,10 +4312,10 @@ name = "srml-support" version = "2.0.0" dependencies = [ "bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "once_cell 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4388,7 +4336,7 @@ dependencies = [ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "sr-api-macros 2.0.0", "srml-support-procedural-tools 2.0.0", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4399,7 +4347,7 @@ dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "srml-support-procedural-tools-derive 2.0.0", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4408,7 +4356,7 @@ version = "2.0.0" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4422,7 +4370,7 @@ dependencies = [ "srml-support 2.0.0", "substrate-inherents 2.0.0", "substrate-primitives 2.0.0", - "trybuild 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "trybuild 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4430,7 +4378,7 @@ name = "srml-system" version = "2.0.0" dependencies = [ "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4446,7 +4394,7 @@ dependencies = [ name = "srml-timestamp" version = "2.0.0" dependencies = [ - "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4490,7 +4438,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "stream-cipher" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4526,7 +4474,7 @@ dependencies = [ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4542,7 +4490,7 @@ dependencies = [ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4551,11 +4499,11 @@ version = "2.0.0" dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", "node-runtime 2.0.0", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "srml-balances 2.0.0", @@ -4570,7 +4518,7 @@ name = "substrate" version = "2.0.0" dependencies = [ "ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "node-cli 2.0.0", "vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4593,10 +4541,10 @@ name = "substrate-authority-discovery" version = "2.0.0" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4627,8 +4575,8 @@ dependencies = [ name = "substrate-basic-authorship" version = "2.0.0" dependencies = [ - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", @@ -4655,7 +4603,7 @@ dependencies = [ name = "substrate-chain-spec" version = "2.0.0" dependencies = [ - "impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -4670,7 +4618,7 @@ name = "substrate-chain-spec-derive" version = "2.0.0" dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4679,21 +4627,21 @@ dependencies = [ name = "substrate-cli" version = "2.0.0" dependencies = [ - "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "names 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rpassword 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rpassword 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4715,16 +4663,16 @@ dependencies = [ name = "substrate-client" version = "2.0.0" dependencies = [ - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", "kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-api-macros 2.0.0", @@ -4755,7 +4703,7 @@ dependencies = [ "kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", "kvdb-rocksdb 0.1.4 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -4777,10 +4725,10 @@ version = "2.0.0" dependencies = [ "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", @@ -4823,18 +4771,18 @@ version = "2.0.0" dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "fork-tree 2.0.0", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "merlin 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "merlin 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "pdqselect 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -4878,11 +4826,11 @@ dependencies = [ name = "substrate-consensus-common" version = "2.0.0" dependencies = [ - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -4897,8 +4845,8 @@ dependencies = [ name = "substrate-consensus-pow" version = "2.0.0" dependencies = [ - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "srml-timestamp 2.0.0", @@ -4923,10 +4871,10 @@ dependencies = [ name = "substrate-consensus-rhd" version = "2.0.0" dependencies = [ - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rhododendron 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4947,9 +4895,9 @@ dependencies = [ name = "substrate-consensus-slots" version = "2.0.0" dependencies = [ - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -4965,7 +4913,7 @@ dependencies = [ name = "substrate-consensus-uncles" version = "2.0.0" dependencies = [ - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "srml-authorship 0.1.0", "substrate-client 2.0.0", @@ -4979,13 +4927,13 @@ name = "substrate-executor" version = "2.0.0" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libsecp256k1 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.40.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.40.3 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-version 2.0.0", @@ -4999,7 +4947,7 @@ dependencies = [ "substrate-trie 2.0.0", "substrate-wasm-interface 2.0.0", "tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5010,12 +4958,12 @@ dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "finality-grandpa 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "fork-tree 2.0.0", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "srml-finality-tracker 2.0.0", @@ -5072,7 +5020,7 @@ dependencies = [ name = "substrate-keyring" version = "2.0.0" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "strum 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "strum_macros 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5086,11 +5034,11 @@ dependencies = [ "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-application-crypto 2.0.0", "substrate-primitives 2.0.0", - "subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5098,26 +5046,26 @@ dependencies = [ name = "substrate-network" version = "2.0.0" dependencies = [ - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "fork-tree 2.0.0", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quickcheck 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "quickcheck 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5140,7 +5088,7 @@ dependencies = [ "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5150,12 +5098,12 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5183,20 +5131,20 @@ dependencies = [ name = "substrate-panic-handler" version = "2.0.0" dependencies = [ - "backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "substrate-peerset" version = "2.0.0" dependencies = [ - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5219,21 +5167,21 @@ dependencies = [ "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ed25519-dalek 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "hash256-std-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "primitive-types 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5242,9 +5190,9 @@ dependencies = [ "substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-serializer 2.0.0", "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "twox-hash 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "twox-hash 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5252,12 +5200,12 @@ name = "substrate-rpc" version = "2.0.0" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5282,13 +5230,13 @@ dependencies = [ name = "substrate-rpc-api" version = "2.0.0" dependencies = [ - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core-client 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-derive 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5315,7 +5263,7 @@ dependencies = [ "jsonrpc-http-server 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-ws-server 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -5345,12 +5293,12 @@ dependencies = [ name = "substrate-service" version = "2.0.0" dependencies = [ - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "node-executor 2.0.0", "node-primitives 2.0.0", "node-runtime 2.0.0", @@ -5383,7 +5331,7 @@ dependencies = [ "substrate-telemetry 2.0.0", "substrate-test-runtime-client 2.0.0", "substrate-transaction-pool 2.0.0", - "sysinfo 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sysinfo 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)", "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5395,9 +5343,9 @@ version = "2.0.0" dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", "substrate-consensus-common 2.0.0", @@ -5423,7 +5371,7 @@ name = "substrate-state-db" version = "2.0.0" dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-primitives 2.0.0", @@ -5434,8 +5382,8 @@ name = "substrate-state-machine" version = "2.0.0" dependencies = [ "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5452,13 +5400,13 @@ name = "substrate-telemetry" version = "2.0.0" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "slog-async 2.3.0 (git+https://github.com/paritytech/slog-async)", @@ -5472,7 +5420,7 @@ dependencies = [ name = "substrate-test-client" version = "2.0.0" dependencies = [ - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -5489,8 +5437,8 @@ dependencies = [ name = "substrate-test-runtime" version = "2.0.0" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5536,10 +5484,10 @@ name = "substrate-transaction-graph" version = "2.0.0" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5552,9 +5500,9 @@ dependencies = [ name = "substrate-transaction-pool" version = "2.0.0" dependencies = [ - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -5571,7 +5519,7 @@ version = "2.0.0" dependencies = [ "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5588,7 +5536,7 @@ name = "substrate-wasm-builder" version = "1.0.7" dependencies = [ "build-helper 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cargo_metadata 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo_metadata 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5618,12 +5566,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "subtle" -version = "2.1.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "syn" -version = "0.15.42" +version = "0.15.44" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5636,7 +5584,7 @@ name = "syn" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5648,20 +5596,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "sysinfo" -version = "0.9.0" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5688,12 +5636,12 @@ name = "tempfile" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5701,7 +5649,7 @@ name = "termcolor" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5709,7 +5657,7 @@ name = "textwrap" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5717,7 +5665,7 @@ name = "thread_local" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5725,9 +5673,9 @@ name = "time" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5767,7 +5715,7 @@ version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5775,12 +5723,12 @@ dependencies = [ "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-sync 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-udp 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5790,8 +5738,8 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5800,7 +5748,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5809,7 +5757,7 @@ name = "tokio-current-thread" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5818,9 +5766,9 @@ name = "tokio-dns-unofficial" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5830,7 +5778,7 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5838,9 +5786,9 @@ name = "tokio-fs" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5849,22 +5797,22 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-reactor" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5877,7 +5825,7 @@ version = "0.10.0-alpha.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5890,7 +5838,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5899,25 +5847,25 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-threadpool" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5928,7 +5876,7 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5938,23 +5886,23 @@ name = "tokio-tls" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-udp" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5963,15 +5911,15 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5991,7 +5939,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "transaction-factory" version = "0.0.1" dependencies = [ - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-cli 2.0.0", @@ -6024,7 +5972,7 @@ dependencies = [ "elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "hashbrown 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6052,11 +6000,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "trybuild" -version = "1.0.9" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6070,15 +6018,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "twox-hash" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6091,14 +6039,9 @@ name = "typenum" version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "ucd-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "uint" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6116,7 +6059,7 @@ dependencies = [ [[package]] name = "unicase" -version = "2.4.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6145,7 +6088,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "unicode-width" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -6192,11 +6135,6 @@ dependencies = [ "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "utf8-ranges" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "vcpkg" version = "0.2.7" @@ -6212,8 +6150,8 @@ name = "vergen" version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6229,22 +6167,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wabt" -version = "0.7.4" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", - "wabt-sys 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "wabt-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wabt-sys" -version = "0.5.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "cmake 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6254,7 +6192,7 @@ version = "2.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6263,81 +6201,89 @@ name = "want" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "wasi" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "wasm-bindgen" -version = "0.2.48" +version = "0.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "wasm-bindgen-macro 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.48" +version = "0.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bumpalo 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-futures" -version = "0.3.25" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.48" +version = "0.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro-support 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro-support 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.48" +version = "0.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-backend 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.48" +version = "0.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wasm-bindgen-webidl" -version = "0.2.48" +version = "0.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-backend 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6346,12 +6292,12 @@ name = "wasm-timer" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", "send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6359,11 +6305,11 @@ name = "wasmi" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.40.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.40.3 (registry+https://github.com/rust-lang/crates.io-index)", "wasmi-validation 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6372,19 +6318,19 @@ name = "wasmi-validation" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "parity-wasm 0.40.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.40.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "web-sys" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", "sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-webidl 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-webidl 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6411,17 +6357,17 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6442,7 +6388,7 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6452,7 +6398,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6474,7 +6420,7 @@ name = "winapi-util" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6484,10 +6430,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wincolor" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6499,7 +6445,7 @@ dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6523,7 +6469,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "curve25519-dalek 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6543,9 +6489,9 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "nohash-hasher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "nohash-hasher 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6558,29 +6504,35 @@ name = "zeroize" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "zeroize_derive 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize_derive 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "zeroize" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "zeroize_derive" -version = "0.9.0" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [metadata] -"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" +"checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" "checksum aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2e5b0458ea3beae0d1d8c0f3946564f8e10f90646cf78c06b4351052058d1ee" "checksum aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d" "checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100" -"checksum ahash 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "e96e12a0287c75063711e04484e9b140d4a59ec074d3fe5f0b1cc90e0e992665" -"checksum aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36b7aa1ccb7d7ea3f437cf025a2ab1c47cc6c1bc9fc84918ff449def12f5e282" -"checksum aio-limited 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f10b352bc3fc08ae24dc5d2d3ddcac153678533986122dc283d747b12071000" +"checksum ahash 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b58aeefd9396419a4f4f2b9778f2d832a11851b55010e231c5390cf2b1c416b4" +"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" +"checksum aio-limited 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c4dddf55b0b2da9acb7512f21c0a4f1c0871522ec4ab7fb919d0da807d1e32b3" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" "checksum app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e73a24bad9bd6a94d6395382a6c69fe071708ae4409f763c5475e14ee896313d" "checksum arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "bc4662175ead9cd84451d5c35070517777949a2ed84551764129cedb88384841" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" @@ -6589,26 +6541,26 @@ dependencies = [ "checksum asn1_der_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e7f92edafad155aff997fa5b727c6429b91e996b5a5d62a2b0adbae1306b5fe" "checksum assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7deb0a829ca7bcfaf5da70b073a8d128619259a7be8216a355e23f00763059e5" "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" -"checksum autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "22130e92352b948e7e82a49cdb0aa94f2211761117f29e052dd397c1ac33542b" -"checksum backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)" = "88fb679bc9af8fa639198790a77f52d345fe13656c08b43afa9424c206b731c6" +"checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875" +"checksum backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)" = "690a62be8920ccf773ee00ef0968649b0e724cda8bd5b12286302b4ae955fdf5" "checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b" "checksum base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" "checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" "checksum bindgen 0.47.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df683a55b54b41d5ea8ebfaebb5aa7e6b84e3f3006a78f010dadc9ca88469260" -"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" +"checksum bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a606a02debe2813760609f57a64a2ffd27d9fdf5b2f133eaca0b248dd92cdd2" "checksum bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5da9b3d9f6f585199287a473f4f8dfab6566cf827d15c00c219f53c645687ead" "checksum bitvec 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9633b74910e1870f50f5af189b08487195cdb83c0e27a71d6f64d5e09dd0538b" -"checksum blake2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91721a6330935673395a0607df4d49a9cb90ae12d259f1b3e0a3f6e1d486872e" +"checksum blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" "checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" "checksum block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1339a1042f5d9f295737ad4d9a6ab6bf81c84a933dba110b9200cd6d1448b814" "checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" "checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" "checksum block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4dc3af3ee2e12f3e5d224e5e1e3d73668abbeb69e566d361f7d5563a4fdf09" -"checksum bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0de79cfb98e7aa9988188784d8664b4b5dad6eaaa0863b91d9a4ed871d4f7a42" -"checksum bstr 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e0a692f1c740e7e821ca71a22cf99b9b2322dfa94d10f71443befb1797b3946a" +"checksum bs58 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c95ee6bba9d950218b6cc910cf62bc9e0a171d0f4537e3627b0f54d08549b188" +"checksum bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6c2c5b58ab920a4f5aeaaca34b4488074e8cc7596af94e6f8c6ff247c60245" "checksum build-helper 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bdce191bf3fa4995ce948c8c83b4640a1745457a149e73c6db75b4ffe36aad5f" -"checksum bumpalo 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2cd43d82f27d68911e6ee11ee791fb248f138f5d69424dc02e098d4f152b0b05" +"checksum bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad807f2fc2bf185eeb98ff3a901bd46dc5ad58163d0fa4577ba0d25674d71708" "checksum byte-slice-cast 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7cbcbf18128ec71d8d4a0d054461ec59fff5b75b7d10a4c9b7c7cb1a379c3e77" "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" @@ -6617,27 +6569,26 @@ dependencies = [ "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" "checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" "checksum c_linked_list 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" -"checksum cargo_metadata 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e904f164f39cae0c3a4f2713eb97a47ba64676a071e99a69ddfef4994694d2c" +"checksum cargo_metadata 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "700b3731fd7d357223d0000f4dbf1808401b694609035c3c411fbc0cd375c426" "checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" -"checksum cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "ce400c638d48ee0e9ab75aef7997609ec57367ccfe1463f21bf53c3eca67bf46" +"checksum cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc9a35e1f4290eb9e5fc54ba6cf40671ed2a2514c3eeb2b2a908dda2ea5a1be" "checksum cexpr 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7fa24eb00d5ffab90eaeaf1092ac85c04c64aaf358ea6f84505b8116d24c6af" -"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" -"checksum chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "77d81f58b7301084de3b958691458a53c3f7e0b1d702f77e550b6a88e3a88abe" +"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +"checksum chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e8493056968583b0193c1bb04d6f7684586f3726992d6c573261941a895dbd68" "checksum clang-sys 0.26.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ef0c1bcf2e99c649104bd7a7012d8f8802684400e03db0ec0af48583c6fa0e4" "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" "checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum cmake 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "2ca4386c8954b76a8415b63959337d940d724b336cabd3afe189c2b51a7e1ff0" +"checksum cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62" "checksum const-random 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7b641a8c9867e341f3295564203b1c250eb8ce6cb6126e007941f78c4d2ed7fe" "checksum const-random-macro 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c750ec12b83377637110d5a57f5ae08e895b06c4b16e2bdbf1a94ef717428c59" -"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" +"checksum constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120" "checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" "checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" "checksum criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0363053954f3e679645fc443321ca128b7b950a6fe288cf5f9335cc22ee58394" "checksum criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76f9212ddf2f4a9eb2d401635190600656a1f88a932ef53d06e7fa4c7e02fb8e" "checksum crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa" -"checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13" "checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71" "checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9" "checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" @@ -6647,24 +6598,24 @@ dependencies = [ "checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" "checksum csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d" "checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c" -"checksum ctor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3b4c17619643c1252b5f690084b82639dd7fac141c57c8e77a00e0148132092c" +"checksum ctor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8ce37ad4184ab2ce004c33bf6379185d3b1c95801cab51026bd271bf68eedc" "checksum ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "022cd691704491df67d25d006fe8eca083098253c4d43516c2206479c58c6736" "checksum ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7dfd2d8b4c82121dfdff120f818e09fc4380b0b7e17a742081a89b94853e87f" "checksum cuckoofilter 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd43f7cfaffe0a386636a10baea2ee05cc50df3b77bea4a456c9572a939bf1f" -"checksum curve25519-dalek 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5d4b820e8711c211745880150f5fac78ab07d6e3851d8ce9f5a02cedc199174c" +"checksum curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8b7dcd30ba50cdf88b55b033456138b7c0ac4afdc436d82e1b79f370f24cc66d" "checksum data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97" -"checksum derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6d944ac6003ed268757ef1ee686753b57efc5fcf0ebe7b64c9fc81e7e32ff839" "checksum derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a141330240c921ec6d074a3e188a7c7ef95668bb95e7d44fa0e5778ec2a7afe" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" "checksum digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e5b29bf156f3f4b3c4f610a25ff69370616ae6e0657d416de22645483e72af0a" "checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" "checksum dns-parser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea" "checksum doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "923dea538cea0aa3025e8685b20d6ee21ef99c4f77e954a30febbaac5ec73a97" +"checksum ed25519-dalek 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d07e8b8a8386c3b89a7a4b329fdfa4cb545de2545e9e2ebbc3dd3929253e426" "checksum ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81956bcf7ef761fb4e1d88de3fa181358a0d26cbcb9755b587a08f9119824b86" -"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b" +"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" "checksum elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "073be79b6538296faf81c631872676600616073817dd9a440c477ad09b408983" "checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" -"checksum environmental 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c7464757b80de8930c91c9afe77ddce501826bf9d134a87db2c67d9dc177e2c" +"checksum environmental 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "34f8467a0284de039e6bd0e25c14519538462ba5beb548bb1f03e645097837a8" "checksum erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3beee4bc16478a1b26f2e80ad819a52d24745e292f521a63c16eea5f74b7eb60" "checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9" "checksum exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d8013f441e38e31c670e7f34ec8f1d5d3a2bd9d303c1ff83976ca886005e8f48" @@ -6675,7 +6626,7 @@ dependencies = [ "checksum finality-grandpa 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9681c1f75941ea47584573dd2bc10558b2067d460612945887e00744e43393be" "checksum fixed-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "516877b7b9a1cc2d0293cbce23cd6203f0edbfd4090e6ca4489fecb5aa73050e" "checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" -"checksum flate2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "550934ad4808d5d39365e5d61727309bf18b3b02c6c56b729cb92e7dd84bc3d8" +"checksum flate2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ad3c5233c9a940c8719031b423d7e6c16af66e031cb0420b0896f5245bf181d3" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" @@ -6684,22 +6635,22 @@ dependencies = [ "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "45dc39533a6cae6da2b56da48edae506bb767ec07370f86f70fc062e9d435869" -"checksum futures-channel-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "f477fd0292c4a4ae77044454e7f2b413207942ad405f759bb0b4698b7ace5b12" -"checksum futures-core-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "4a2f26f774b81b3847dcda0c81bd4b6313acfb4f69e5a0390c7cb12c058953e9" +"checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" +"checksum futures-channel-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "d5e5f4df964fa9c1c2f8bddeb5c3611631cacd93baf810fc8bb2fb4b495c263a" +"checksum futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "b35b6263fb1ef523c3056565fa67b1d16f0a8604ff12b11b08c25f28a734c60a" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" -"checksum futures-executor-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "80705612926df8a1bc05f0057e77460e29318801f988bf7d803a734cf54e7528" -"checksum futures-io-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "ee7de0c1c9ed23f9457b0437fec7663ce64d9cc3c906597e714e529377b5ddd1" -"checksum futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "efa8f90c4fb2328e381f8adfd4255b4a2b696f77d1c63a3dee6700b564c4e4b5" -"checksum futures-sink-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "e9b65a2481863d1b78e094a07e9c0eed458cc7dc6e72b22b7138b8a67d924859" -"checksum futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f9eb554aa23143abc64ec4d0016f038caf53bb7cbc3d91490835c54edc96550" -"checksum futures-util-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "7df53daff1e98cc024bf2720f3ceb0414d96fbb0a94f3cad3a5c3bf3be1d261c" +"checksum futures-executor-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "75236e88bd9fe88e5e8bfcd175b665d0528fe03ca4c5207fabc028c8f9d93e98" +"checksum futures-io-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "f4914ae450db1921a56c91bde97a27846287d062087d4a652efc09bb3a01ebda" +"checksum futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "3b1dce2a0267ada5c6ff75a8ba864b4e679a9e2aa44262af7a3b5516d530d76e" +"checksum futures-sink-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "86f148ef6b69f75bb610d4f9a2336d4fc88c4b5b67129d1a340dd0fd362efeec" +"checksum futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "878f1d2fc31355fa02ed2372e741b0c17e58373341e6a122569b4623a14a7d33" +"checksum futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "5ce968633c17e5f97936bd2797b6e38fb56cf16a7422319f7ec2e30d3c470e8d" "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" "checksum generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fceb69994e330afed50c93524be68c42fa898c2d9fd4ee8da03bd7363acd26f2" "checksum get_if_addrs 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "abddb55a898d32925f3148bd281174a68eeb68bbfd9a5938a57b18f506ee4ef7" "checksum get_if_addrs-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d04f9fb746cf36b191c00f3ede8bde9c8e64f9f4b05ae2694a9ccf5e3f5ab48" -"checksum getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e65cce4e5084b14874c4e7097f38cab54f47ee554f9194673456ea379dcc4c55" +"checksum getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" "checksum globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2" @@ -6712,33 +6663,33 @@ dependencies = [ "checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" -"checksum hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c3da68162fdd2147e66682e78e729bd77f93b4c99656db058c5782d8c6b6225a" -"checksum hex-literal-impl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06095d08c7c05760f11a071b3e1d4c5b723761c01bd8d7201c30a9536668a612" +"checksum hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0" +"checksum hex-literal-impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d4c5c844e2fee0bf673d54c2c177f1713b3d2af2ff6e666b49cb7572e6cf42d" "checksum hmac 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a13f4163aa0c5ca1be584aace0e2212b2e41be5478218d4f657f5f778b2ae2a" "checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" "checksum hmac-drbg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4fe727d41d2eec0a6574d887914347e5ff96a3b87177817e2a9820c5c87fecc2" "checksum hmac-drbg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" -"checksum http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "eed324f0f0daf6ec10c474f150505af2c143f251722bf9dbd1261bd1f2ee2c1a" +"checksum http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "372bcb56f939e449117fb0869c2e8fd8753a8223d92a172c6e808cf123a5b6e4" "checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" -"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" +"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" "checksum hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273" -"checksum hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)" = "7cb44cbce9d8ee4fb36e4c0ad7b794ac44ebaad924b9c8291a63215bb44c2c8f" +"checksum hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)" = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6" "checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" "checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" "checksum impl-codec 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3fa0086251524c50fd53b32e7b05eb6d79e2f97221eaf0c53c0ca9c3096f21d3" -"checksum impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5158079de9d4158e0ce1de3ae0bd7be03904efc40b3d7dd8b8c301cbf6b52b56" "checksum impl-serde 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bbb1ea6188aca47a0eaeeb330d8a82f16cd500f30b897062d23922568727333a" -"checksum impl-trait-for-tuples 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0df44cb13008e863c3d80788d5f4cb0f94d09b31bb0190a8ecc05151b2ac8a" -"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" +"checksum impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6947b372790f8948f439bb6aaa6baabdf80be1a207a477ff072f83fb793e428f" +"checksum indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a61202fbe46c4a951e9404a720a0180bcf3212c750d735cb5c4ba4dc551299f3" "checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" "checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum ipnet 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e61c2da0d0f700c77d2d313dbf4f93e41d235fa12c6681fee06621036df4c2af" "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" -"checksum js-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)" = "da3ea71161651a4cd97d999b2da139109c537b15ab33abc8ae4ead38deac8a03" +"checksum jobserver 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b1d42ef453b30b7387e113da1c83ab1605d90c5b4e0eb8e96d016ed3b8c160" +"checksum js-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)" = "2cc9a97d7cec30128fd8b28a7c1f9df1c001ceb9b441e2b755e24130a6b43c79" "checksum jsonrpc-client-transports 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dbf2466adbf6d5b4e618857f22be40b1e1cc6ed79d72751324358f6b539b06d" "checksum jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91d767c183a7e58618a609499d359ce3820700b3ebb4823a18c343b4a2a41a0d" "checksum jsonrpc-core-client 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "161dc223549fa6fe4a4eda675de2d1d3cff5a7164e5c031cdf1e22c734700f8b" @@ -6754,9 +6705,9 @@ dependencies = [ "checksum kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" "checksum kvdb-rocksdb 0.1.4 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" -"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" +"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" -"checksum libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb" +"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" "checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" "checksum libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4183fb4be621d97baebbbe0c499d6ae337e9e6ec955f9fa3cb29e55547dfacdb" "checksum libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a7ebd9d597299512e096cc1bd58e955c03ef28f33214a33b9c7e4ace109ff41" @@ -6789,7 +6740,7 @@ dependencies = [ "checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff" "checksum lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c275b6ad54070ac2d665eef9197db647b32239c9d244bfb6f041a766d00da5b3" +"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" "checksum lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" "checksum malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "35adee9ed962cf7d07d62cb58bc45029f3227f5b5b86246caa8632f06c187bc3" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" @@ -6797,11 +6748,9 @@ dependencies = [ "checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f" "checksum memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ef49315991403ba5fa225a70399df5e115f57b274cb0b1b4bcd6e734fa5bd783" "checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" -"checksum merlin 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "66448a173ad394ef5ebf734efa724f3644dcffda083b1e89979da4461ddac079" +"checksum merlin 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "de2d16d3b15fec5943d1144f861f61f279d165fdd60998ca262913b9bf1c8adb" "checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" -"checksum miniz-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9e3ae51cea1576ceba0dde3d484d30e6e5b86dee0b2d412fe3a16a15c98202" -"checksum miniz_oxide 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c061edee74a88eb35d876ce88b94d77a0448a201de111c244b70d047f5820516" -"checksum miniz_oxide_c_api 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6c675792957b0d19933816c4e1d56663c341dd9bfa31cb2140ff2267c1d8ecf4" +"checksum miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7108aff85b876d06f22503dcce091e29f76733b2bfdd91eebce81f5e68203a10" "checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23" "checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" @@ -6813,7 +6762,7 @@ dependencies = [ "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" -"checksum nohash-hasher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d138afcce92d219ccb6eb53d9b1e8a96ac0d633cfd3c53cd9856d96d1741bb8" +"checksum nohash-hasher 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4e657a6ec97f9a3ba46f6f7034ea6db9fcd5b71d25ef1074b7bc03da49be0e8e" "checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" "checksum num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9c3f34cdd24f334cb265d9bf8bfa8a241920d026916785747a92f0e55541a1a" "checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" @@ -6822,12 +6771,12 @@ dependencies = [ "checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" "checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c" "checksum once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37" -"checksum opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "93f5bb2e8e8dec81642920ccff6b61f1eb94fa3020c5a325c9851ff604152409" +"checksum once_cell 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d584f08c2d717d5c23a6414fc2822b71c651560713e54fa7eace675f758a355e" +"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" "checksum openssl 0.10.24 (registry+https://github.com/rust-lang/crates.io-index)" = "8152bb5a9b5b721538462336e3bef9a539f892715e5037fda0f984577311af15" "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-sys 0.9.48 (registry+https://github.com/rust-lang/crates.io-index)" = "b5ba300217253bcc5dc68bed23d782affa45000193866e025329aa8a7a9f05b8" +"checksum openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)" = "f4fad9e54bd23bd4cbbe48fdc08a1b8091707ac869ef8508edea2fec77dcc884" "checksum output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9" -"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" "checksum parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" "checksum parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "045b3c7af871285146300da35b1932bb6e4639b66c7c98e85d06a32cbc4e8fa7" @@ -6836,19 +6785,17 @@ dependencies = [ "checksum parity-scale-codec-derive 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42af752f59119656fa3cb31e8852ed24e895b968c0bdb41847da7f0cea6d155f" "checksum parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" "checksum parity-util-mem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2005637ccf93dbb60c85081ccaaf3f945f573da48dcc79f27f9646caa3ec1dc" -"checksum parity-wasm 0.40.2 (registry+https://github.com/rust-lang/crates.io-index)" = "49d1e33551976be5345d2ecbfe995830719746c7f0902f0880a13d40e215f851" -"checksum parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4d05f1349491390b1730afba60bb20d55761bef489a954546b58b4b34e1e2ac" +"checksum parity-wasm 0.40.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1e39faaa292a687ea15120b1ac31899b13586446521df6c149e46f1584671e0f" "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" "checksum parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7" "checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" -"checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa" "checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" "checksum parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c" "checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" -"checksum paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4a4a1c555c6505821f9d58b8779d0f630a6b7e4e1be24ba718610acf01fa79" -"checksum paste-impl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "26e796e623b8b257215f27e6c80a5478856cae305f5b59810ff9acdaa34570e6" +"checksum paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "423a519e1c6e828f1e73b720f9d9ed2fa643dce8a7737fb43235ce0b41eeaa49" +"checksum paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5" "checksum pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" "checksum pdqselect 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ec91767ecc0a0bbe558ce8c9da33c068066c57ecc8bb8477ef8c1ad3ef77c27" "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" @@ -6856,23 +6803,23 @@ dependencies = [ "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" "checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" "checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" -"checksum pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c1d2cfa5a714db3b5f24f0915e74fcdf91d09d496ba61329705dda7774d2af" +"checksum pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "72d5370d90f49f70bd033c3d75e87fc529fbfff9d6f7cccef07d6170079d91ea" "checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" "checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427" "checksum primitive-types 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "83ef7b3b965c0eadcb6838f34f827e1dfb2939bdd5ebd43f9647e009b12b0371" "checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" -"checksum proc-macro-hack 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "982a35d1194084ba319d65c4a68d24ca28f5fdb5b8bc20899e4eef8641ea5178" +"checksum proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "114cdf1f426eb7f550f01af5f53a33c0946156f6814aec939b3bd77e844f9a9d" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -"checksum proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e98a83a9f9b331f54b924e68a66acb1bb35cb01fb0a23645139967abefb697e8" +"checksum proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afdc77cc74ec70ed262262942ebb7dac3d479e9e5cfa2da1841c0806f6cdabcc" "checksum prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96d14b1c185652833d24aaad41c5832b0be5616a590227c1fbff57c616754b23" "checksum prost-build 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb788126ea840817128183f8f603dce02cb7aea25c2a0b764359d8e20010702e" "checksum prost-derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e7dc378b94ac374644181a2247cebf59a6ec1c88b49ac77f3a94b86b79d0e11" "checksum prost-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1de482a366941c8d56d19b650fac09ca08508f2a696119ee7513ad590c8bac6f" -"checksum protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8aefcec9f142b524d98fc81d07827743be89dd6586a1ba6ab21fa66a500b3fa5" +"checksum protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40361836defdd5871ff7e84096c6f6444af7fc157f8ef1789f54f147687caa20" "checksum pwasm-utils 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d473123ba135028544926f7aa6f34058d8bc6f120c4fcd3777f84af724280b3" "checksum quick-error 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb6ccf8db7bbcb9c2eae558db5ab4f3da1c2a87e4e597ed394726bc8ea6ca1d" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" -"checksum quickcheck 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9c35d9c36a562f37eca96e79f66d5fd56eefbc22560dacc4a864cabd2d277456" +"checksum quickcheck 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5ca504a2fdaa08d3517f442fbbba91ac24d1ec4c51ea68688a038765e3b2662" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" @@ -6893,20 +6840,20 @@ dependencies = [ "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" "checksum rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "03b418169fb9c46533f326efd6eed2576699c44ca92d3052a066214a8d828929" -"checksum rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4b0186e22767d5b9738a05eab7c6ac90b15db17e5b5f9bd87976dd7d89a10a4" -"checksum rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe0df8435ac0c397d467b6cad6d25543d06e8a019ef3f6af3c384597515bd2" +"checksum rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83a27732a533a1be0a0035a111fe76db89ad312f6f0347004c220c57f209a123" +"checksum rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98dcf634205083b17d0861252431eb2acbfb698ab7478a2d20de07954f47ec7b" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" "checksum ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d813022b2e00774a48eaf43caaa3c20b45f040ba8cbf398e2e8911a06668dbe6" -"checksum regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b23da8dfd98a84bd7e08700190a5d9f7d2d38abd4369dd1dae651bc40bfd2cc" +"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" "checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9" -"checksum regex-syntax 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5485bf1523a9ed51c4964273f22f63f24e31632adb5dad134f488f86a3875c" +"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" "checksum rhododendron 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "36542aafc2429a4c010fafa079a20dee953b663cb2427f51d86cf1d436846b4d" "checksum ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)" = "426bc186e3e95cac1e4a4be125a4aca7e84c2d616ffc02244eef36e2a60a093c" "checksum rocksdb 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1651697fefd273bfb4fd69466cc2a9d20de557a0213b97233b22b5e95924b5e" -"checksum rpassword 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c34fa7bcae7fca3c8471e8417088bbc3ad9af8066b0ecf4f3c0d98a0d772716e" -"checksum rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f4dccf6f4891ebcc0c39f9b6eb1a83b9bf5d747cb439ec6fba4f3b977038af" +"checksum rpassword 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f072d931f11a96546efd97642e1e75e807345aced86b947f9239102f262d0fcd" +"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" "checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum rustls 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f271e3552cd835fa28c541c34a7e8fdd8cdff09d77fe4eb8f6c42e87a11b096e" @@ -6914,9 +6861,9 @@ dependencies = [ "checksum rw-stream-sink 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9cbe61c20455d3015b2bb7be39e1872310283b8e5a52f5b242b0ac7581fe78" "checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" "checksum safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347" -"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" +"checksum safemem 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d2b08423011dae9a5ca23f07cf57dac3857f5c885d352b76f6d95f4aea9434d0" "checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" -"checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339" +"checksum schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021" "checksum schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "eacd8381b3c37840c9c9f40472af529e49975bdcbc24f83c31059fd6539023d3" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" @@ -6928,7 +6875,7 @@ dependencies = [ "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0eddf2e8f50ced781f288c19f18621fa72a3779e3cb58dbf23b07469b0abeb4" "checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd" -"checksum serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)" = "c22a0820adfe2f257b098714323563dd06426502abbbce4f51b72ef544c5027f" +"checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e" "checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704" "checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68" "checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" @@ -6946,11 +6893,11 @@ dependencies = [ "checksum snow 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5a64f02fd208ef15bd2d1a65861df4707e416151e1272d02c8faafad1c138100" "checksum soketto 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bceb1a3a15232d013d9a3b7cac9e5ce8e2313f348f01d4bc1097e5e53aa07095" "checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" -"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55" +"checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5" "checksum static_slice 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "92a7e0c5e3dfb52e8fbe0e63a1b947bbb17b4036408b151353c4491374931362" -"checksum stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8861bc80f649f5b4c9bd38b696ae9af74499d479dbfb327f0607de6b326a36bc" +"checksum stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8131256a5896cabcf5eb04f4d6dacbe1aefda854b0d9896e09cb58829ec5638c" "checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "checksum structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "16c2cdbf9cc375f15d1b4141bc48aeef444806655cd0e904207edc8d68d86ed7" @@ -6960,11 +6907,11 @@ dependencies = [ "checksum substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3be511be555a3633e71739a79e4ddff6a6aaa6579fa6114182a51d72c3eb93c5" "checksum substrate-wasm-builder-runner 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af21b27fad38b212c1919f700cb0def33c88cde14d22e0d1b17d4521f4eb8b40" "checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" -"checksum subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "01dca13cf6c3b179864ab3292bd794e757618d35a7766b7c46050c614ba00829" -"checksum syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)" = "eadc09306ca51a40555dd6fc2b415538e9e18bc9f870e47b1a524a79fe2dcf5e" +"checksum subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab3af2eb31c42e8f0ccf43548232556c42737e01a96db6e1777b0be108e79799" +"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" "checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf" "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" -"checksum sysinfo 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c3e2cab189e59f72710e3dd5e1e0d5be0f6c5c999c326f2fdcdf3bf4483ec9fd" +"checksum sysinfo 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d5bd3b813d94552a8033c650691645f8dd5a63d614dddd62428a95d3931ef7b6" "checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" "checksum target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" @@ -6984,14 +6931,14 @@ dependencies = [ "checksum tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f27ee0e6db01c5f0b2973824547ce7e637b2ed79b891a9677b0de9bd532b6ac" "checksum tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af" "checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" -"checksum tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6af16bfac7e112bea8b0442542161bfc41cbfa4466b580bdda7d18cb88b911ce" +"checksum tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "c56391be9805bc80163151c0b9e5164ee64f4b0200962c346fea12773158f22d" "checksum tokio-rustls 0.10.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3e5cebc3ca33110e460c4d2e7c5e863b159fadcbf125449d896720695b2af709" "checksum tokio-sync 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2162248ff317e2bc713b261f242b69dbb838b85248ed20bb21df56d60ea4cae7" "checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" -"checksum tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "90ca01319dea1e376a001e8dc192d42ebde6dd532532a5bad988ac37db365b19" +"checksum tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2bd2c6a3885302581f4401c82af70d792bb9df1700e7437b0aeb4ada94d5388c" "checksum tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e" "checksum tokio-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "354b8cd83825b3c20217a9dc174d6a0c67441a2fae5c41bcb1ea6679f6ae0f7c" -"checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92" +"checksum tokio-udp 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f02298505547f73e60f568359ef0d016d5acd6e830ab9bc7c4a5b3403440121b" "checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" "checksum toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724" "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" @@ -7000,63 +6947,63 @@ dependencies = [ "checksum trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0b779f7c1c8fe9276365d9d5be5c4b5adeacf545117bb3f64c974305789c5c0b" "checksum trie-standardmap 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3161ba520ab28cd8e6b68e1126f1009f6e335339d1a73b978139011703264c8" "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" -"checksum trybuild 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f2e8e773ac21d176ee05243456b9f1a942cd1a586dab188ced05b8e8d58dc635" +"checksum trybuild 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "9fc69705e261edf3b9a87012b2353a49f49c0465186b5ab96e95f6983d6984aa" "checksum twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d261e83e727c8e2dbb75dacac67c36e35db36a958ee504f2164fc052434e1" -"checksum twox-hash 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7834480552ffc48e1930ceddd701f47d2234319d80b7bcbbe2fe7202933c101" +"checksum twox-hash 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" "checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" -"checksum ucd-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa9b3b49edd3468c0e6565d85783f51af95212b6fa3986a5500954f00b460874" -"checksum uint 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5375d2c574f89adad4108ad525c93e39669853a602560bf5ed4ca9943b10799" +"checksum uint 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8f0f47ed099f0db671ce82c66548c5de012e3c0cba3963514d1db15c7588701" "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" -"checksum unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a84e5511b2a947f3ae965dcb29b13b7b1691b6e7332cf5dbc1744138d5acb7f6" +"checksum unicase 2.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2e2e6bd1e59e56598518beb94fd6db628ded570326f0a98c679a304bd9f00150" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" "checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9" -"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" +"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2c64cdf40b4a9645534a943668681bcb219faf51874d4b65d2e0abda1b10a2ab" "checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" -"checksum utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d50aa7650df78abf942826607c62468ce18d9019673d4a2ebe1865dbb96ffde" "checksum vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "33dd455d0f96e90a75803cfeb7f948768c08d70a6de9a8d2362461935698bf95" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6aba5e34f93dc7051dfad05b98a18e9156f27e7b431fe1d2398cb6061c0a1dba" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "74e463a508e390cc7447e70f640fbf44ad52e1bd095314ace1fdf99516d32add" -"checksum wabt-sys 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a6265b25719e82598d104b3717375e37661d41753e2c84cde3f51050c7ed7e3c" +"checksum wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3c5c5c1286c6e578416982609f47594265f9d489f9b836157d403ad605a46693" +"checksum wabt-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "af5d153dc96aad7dc13ab90835b892c69867948112d95299e522d370c4e13a08" "checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" "checksum want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" -"checksum wasm-bindgen 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "4de97fa1806bb1a99904216f6ac5e0c050dc4f8c676dc98775047c38e5c01b55" -"checksum wasm-bindgen-backend 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "5d82c170ef9f5b2c63ad4460dfcee93f3ec04a9a36a4cc20bc973c39e59ab8e3" -"checksum wasm-bindgen-futures 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)" = "73c25810ee684c909488c214f55abcbc560beb62146d352b9588519e73c2fed9" -"checksum wasm-bindgen-macro 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f07d50f74bf7a738304f6b8157f4a581e1512cd9e9cdb5baad8c31bbe8ffd81d" -"checksum wasm-bindgen-macro-support 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "95cf8fe77e45ba5f91bc8f3da0c3aa5d464b3d8ed85d84f4d4c7cc106436b1d7" -"checksum wasm-bindgen-shared 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "d9c2d4d4756b2e46d3a5422e06277d02e4d3e1d62d138b76a4c681e925743623" -"checksum wasm-bindgen-webidl 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "24e47859b4eba3d3b9a5c2c299f9d6f8d0b613671315f6f0c5c7f835e524b36a" +"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" +"checksum wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "cd34c5ba0d228317ce388e87724633c57edca3e7531feb4e25e35aaa07a656af" +"checksum wasm-bindgen-backend 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "927196b315c23eed2748442ba675a4c54a1a079d90d9bdc5ad16ce31cf90b15b" +"checksum wasm-bindgen-futures 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)" = "83420b37346c311b9ed822af41ec2e82839bfe99867ec6c54e2da43b7538771c" +"checksum wasm-bindgen-macro 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "92c2442bf04d89792816650820c3fb407af8da987a9f10028d5317f5b04c2b4a" +"checksum wasm-bindgen-macro-support 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "9c075d27b7991c68ca0f77fe628c3513e64f8c477d422b859e03f28751b46fc5" +"checksum wasm-bindgen-shared 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "83d61fe986a7af038dd8b5ec660e5849cbd9f38e7492b9404cc48b2b4df731d1" +"checksum wasm-bindgen-webidl 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "9b979afb0535fe4749906a674082db1211de8aef466331d43232f63accb7c07c" "checksum wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3d6101df9a5987df809216bdda7289f52b58128e6b6a6546e9ee3e6b632b4921" "checksum wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f31d26deb2d9a37e6cfed420edce3ed604eab49735ba89035e13c98f9a528313" "checksum wasmi-validation 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6bc0356e3df56e639fc7f7d8a99741915531e27ed735d911ed83d7e1339c8188" -"checksum web-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)" = "86d515d2f713d3a6ab198031d2181b7540f8e319e4637ec2d4a41a208335ef29" +"checksum web-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)" = "c84440699cd02ca23bed6f045ffb1497bc18a3c2628bd13e2093186faaaacf6b" "checksum webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4f7e1cd7900a3a6b65a3e8780c51a3e6b59c0e2c55c6dc69578c288d69f7d082" "checksum webpki-roots 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c10fa4212003ba19a564f25cd8ab572c6791f99a03cc219c13ed35ccab00de0e" "checksum websocket 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b255b190f412e45000c35be7fe9b48b39a2ac5eb90d093d421694e5dae8b335c" "checksum weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164" "checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" +"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" +"checksum wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96f5016b18804d24db43cebf3c77269e7569b8954a8464501c216cc5e070eaa9" "checksum ws 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a6f5bb86663ff4d1639408410f50bf6050367a8525d644d49a6894cd618a631" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ee1585dc1484373cbc1cee7aafda26634665cf449436fd6e24bfd1fad230538" "checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" "checksum yamux 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "01bd67889938c48f0049fc60a77341039e6c3eaf16cb7693e6ead7c0ba701295" +"checksum zeroize 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4090487fa66630f7b166fba2bbb525e247a5449f41c468cc1d98f8ae6ac03120" "checksum zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "45af6a010d13e4cf5b54c94ba5a2b2eba5596b9e46bf5875612d332a1f2b3f86" -"checksum zeroize_derive 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afd1469e4bbca3b96606d26ba6e9bd6d3aed3b1299c82b92ec94377d22d78dbc" +"checksum zeroize_derive 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "080616bd0e31f36095288bb0acdf1f78ef02c2fa15527d7e993f2a6c7591643e" diff --git a/Cargo.toml b/Cargo.toml index c1bac20a7c..a345b880da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,11 +11,11 @@ edition = "2018" [dependencies] cli = { package = "node-cli", path = "node/cli" } -futures = "0.1" -ctrlc = { version = "3.0", features = ["termination"] } +futures = "0.1.29" +ctrlc = { version = "3.1.3", features = ["termination"] } [build-dependencies] -vergen = "3" +vergen = "3.0.4" [workspace] members = [ diff --git a/SECURITY.md b/SECURITY.md index c5a3f35fdd..b850e5462e 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,7 +4,7 @@ Parity Technologies is committed to resolving security vulnerabilities in our so ## Reporting a Vulnerability -Security vulnerabilities in Parity software should be reported by email to security@parity.io. If you think your report might be eligible for the Parity Bug Bounty Program, your email should be send to bugbounty@parity.io. +Security vulnerabilities in Parity software should be reported by email to security@parity.io. If you think your report might be eligible for the Parity Bug Bounty Program, your email should be send to bugbounty@parity.io. Your report should include the following: @@ -19,7 +19,7 @@ Try to include as much information in your report as you can, including a descri You'll receive a response to your email within two business days indicating the next steps in handling your report. We encourage finders to use encrypted communication channels to protect the confidentiality of vulnerability reports. You can encrypt your report using our public key. This key is [on MIT's key server](https://pgp.mit.edu/pks/lookup?op=get&search=0x5D0F03018D07DE73) server and reproduced below. -After the initial reply to your report, our team will endeavor to keep you informed of the progress being made towards a fix. These updates will be sent at least every five business days. +After the initial reply to your report, our team will endeavor to keep you informed of the progress being made towards a fix. These updates will be sent at least every five business days. Thank you for taking the time to responsibly disclose any vulnerabilities you find. @@ -36,7 +36,7 @@ Responsible investigation and reporting includes, but isn't limited to, the foll ## Bug Bounty Program -Our Bug Bounty Program allows us to recognise and reward members of the Parity community for helping us find and address significant bugs, in accordance with the terms of the Parity Bug Bounty Program. A detailed description on eligibility, rewards, legal information and terms & conditions for contributors can be found on [our website](https://paritytech.io/bug-bounty.html). +Our Bug Bounty Program allows us to recognise and reward members of the Parity community for helping us find and address significant bugs, in accordance with the terms of the Parity Bug Bounty Program. A detailed description on eligibility, rewards, legal information and terms & conditions for contributors can be found on [our website](https://paritytech.io/bug-bounty.html). diff --git a/core/application-crypto/Cargo.toml b/core/application-crypto/Cargo.toml index 4e4f896f29..3a48446696 100644 --- a/core/application-crypto/Cargo.toml +++ b/core/application-crypto/Cargo.toml @@ -8,7 +8,7 @@ description = "Provides facilities for generating application specific crypto wr [dependencies] primitives = { package = "substrate-primitives", path = "../primitives", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -serde = { version = "1.0", optional = true, features = ["derive"] } +serde = { version = "1.0.101", optional = true, features = ["derive"] } rstd = { package = "sr-std", path = "../sr-std", default-features = false } runtime-io = { package = "sr-io", path = "../sr-io", default-features = false } diff --git a/core/authority-discovery/Cargo.toml b/core/authority-discovery/Cargo.toml index f544854b5b..a74549eb45 100644 --- a/core/authority-discovery/Cargo.toml +++ b/core/authority-discovery/Cargo.toml @@ -6,26 +6,26 @@ edition = "2018" build = "build.rs" [build-dependencies] -prost-build = "0.5" +prost-build = "0.5.0" [dependencies] authority-discovery-primitives = { package = "substrate-authority-discovery-primitives", path = "./primitives" } -bytes = "0.4" +bytes = "0.4.12" client = { package = "substrate-client", path = "../../core/client" } codec = { package = "parity-scale-codec", default-features = false, version = "1.0.3" } -derive_more = "0.14.0" -futures = "0.1" +derive_more = "0.15.0" +futures = "0.1.29" libp2p = { version = "0.12.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] } -log = "0.4" +log = "0.4.8" network = { package = "substrate-network", path = "../../core/network" } primitives = { package = "substrate-primitives", path = "../primitives" } -prost = "0.5" -serde_json = "1.0" +prost = "0.5.0" +serde_json = "1.0.40" sr-primitives = { path = "../../core/sr-primitives" } -tokio-timer = "0.2" +tokio-timer = "0.2.11" [dev-dependencies] -parking_lot = { version = "0.9.0" } +parking_lot = "0.9.0" peerset = { package = "substrate-peerset", path = "../../core/peerset" } test-client = { package = "substrate-test-runtime-client", path = "../../core/test-runtime/client" } -tokio = { version = "0.1"} +tokio = "0.1.22" diff --git a/core/basic-authorship/Cargo.toml b/core/basic-authorship/Cargo.toml index a819592601..0a98c151d6 100644 --- a/core/basic-authorship/Cargo.toml +++ b/core/basic-authorship/Cargo.toml @@ -5,8 +5,8 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -log = "0.4" -futures-preview = "0.3.0-alpha.18" +log = "0.4.8" +futures-preview = "0.3.0-alpha.19" codec = { package = "parity-scale-codec", version = "1.0.0" } sr-primitives = { path = "../../core/sr-primitives" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } diff --git a/core/chain-spec/Cargo.toml b/core/chain-spec/Cargo.toml index d3111b094d..bff5999ef4 100644 --- a/core/chain-spec/Cargo.toml +++ b/core/chain-spec/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] chain-spec-derive = { package = "substrate-chain-spec-derive", path = "./derive" } -impl-trait-for-tuples = "0.1.1" +impl-trait-for-tuples = "0.1.2" network = { package = "substrate-network", path = "../../core/network" } primitives = { package = "substrate-primitives", path = "../primitives" } serde = { version = "1.0.101", features = ["derive"] } diff --git a/core/chain-spec/derive/Cargo.toml b/core/chain-spec/derive/Cargo.toml index fab6cd5d1d..2e42ca0cf3 100644 --- a/core/chain-spec/derive/Cargo.toml +++ b/core/chain-spec/derive/Cargo.toml @@ -8,10 +8,9 @@ edition = "2018" proc-macro = true [dependencies] -proc-macro-crate = "0.1.3" -proc-macro2 = "1.0.1" +proc-macro-crate = "0.1.4" +proc-macro2 = "1.0.4" quote = "1.0.2" syn = "1.0.5" [dev-dependencies] - diff --git a/core/chain-spec/derive/src/impls.rs b/core/chain-spec/derive/src/impls.rs index fe6e963286..cdc27aef0b 100644 --- a/core/chain-spec/derive/src/impls.rs +++ b/core/chain-spec/derive/src/impls.rs @@ -188,4 +188,3 @@ fn generate_fork_to_base( }) } } - diff --git a/core/chain-spec/src/lib.rs b/core/chain-spec/src/lib.rs index 88184b9706..705be998b7 100644 --- a/core/chain-spec/src/lib.rs +++ b/core/chain-spec/src/lib.rs @@ -121,4 +121,3 @@ use sr_primitives::BuildStorage; /// A set of traits for the runtime genesis config. pub trait RuntimeGenesis: Serialize + DeserializeOwned + BuildStorage {} impl RuntimeGenesis for T {} - diff --git a/core/cli/Cargo.toml b/core/cli/Cargo.toml index ba20d11699..e3b33746d5 100644 --- a/core/cli/Cargo.toml +++ b/core/cli/Cargo.toml @@ -6,22 +6,22 @@ description = "Substrate CLI interface." edition = "2018" [dependencies] -clap = "~2.32" -derive_more = "0.14.0" -env_logger = "0.6" -log = "0.4" -atty = "0.2" -regex = "1" -time = "0.1" -ansi_term = "0.11" -lazy_static = "1.3" -app_dirs = "1.2" -tokio = "0.1.7" -futures = "0.1.17" -futures03 = { package = "futures-preview", version = "0.3.0-alpha.18", features = ["compat"] } -fdlimit = "0.1" -exit-future = "0.1" -serde_json = "1.0" +clap = "~2.32.0" +derive_more = "0.15.0" +env_logger = "0.6.2" +log = "0.4.8" +atty = "0.2.13" +regex = "1.3.1" +time = "0.1.42" +ansi_term = "0.12.1" +lazy_static = "1.4.0" +app_dirs = "1.2.1" +tokio = "0.1.22" +futures = "0.1.29" +futures03 = { package = "futures-preview", version = "=0.3.0-alpha.19", features = ["compat"] } +fdlimit = "0.1.1" +exit-future = "0.1.4" +serde_json = "1.0.40" panic-handler = { package = "substrate-panic-handler", path = "../../core/panic-handler" } client = { package = "substrate-client", path = "../../core/client" } header-metadata = { package = "substrate-header-metadata", path = "../../core/client/header-metadata" } @@ -33,8 +33,8 @@ state-machine = { package = "substrate-state-machine", path = "../../core/state- substrate-telemetry = { path = "../../core/telemetry" } keyring = { package = "substrate-keyring", path = "../keyring" } names = "0.11.0" -structopt = "0.2" -rpassword = "3.0" +structopt = "0.2.0" +rpassword = "4.0.1" [dev-dependencies] -tempdir = "0.3" +tempdir = "0.3.7" diff --git a/core/cli/src/params.rs b/core/cli/src/params.rs index f95ff40eea..6656e1653f 100644 --- a/core/cli/src/params.rs +++ b/core/cli/src/params.rs @@ -17,7 +17,7 @@ use crate::traits::{AugmentClap, GetLogFilter}; use std::path::PathBuf; -use structopt::{StructOpt, clap::{arg_enum, _clap_count_exprs, App, AppSettings, SubCommand, Arg}}; +use structopt::{StructOpt, clap::{arg_enum, App, AppSettings, _clap_count_exprs, SubCommand, Arg}}; use client; pub use crate::execution_strategy::ExecutionStrategy; diff --git a/core/client/Cargo.toml b/core/client/Cargo.toml index 58de8233bb..8852988cb1 100644 --- a/core/client/Cargo.toml +++ b/core/client/Cargo.toml @@ -5,13 +5,13 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -derive_more = { version = "0.14.0", optional = true } -fnv = { version = "1.0", optional = true } -log = { version = "0.4", optional = true } +derive_more = { version = "0.15.0", optional = true } +fnv = { version = "1.0.6", optional = true } +log = { version = "0.4.8", optional = true } parking_lot = { version = "0.9.0", optional = true } -hex = { package = "hex-literal", version = "0.2", optional = true } -futures = { version = "0.1", optional = true } -futures03 = { package = "futures-preview", version = "0.3.0-alpha.18", features = ["compat"], optional = true } +hex-literal = { version = "0.2.1", optional = true } +futures = { version = "0.1.29", optional = true } +futures03 = { package = "futures-preview", version = "0.3.0-alpha.19", features = ["compat"], optional = true } consensus = { package = "substrate-consensus-common", path = "../consensus/common", optional = true } executor = { package = "substrate-executor", path = "../executor", optional = true } state-machine = { package = "substrate-state-machine", path = "../state-machine", optional = true } @@ -30,8 +30,8 @@ sr-api-macros = { path = "../sr-api-macros" } header-metadata = { package = "substrate-header-metadata", path = "header-metadata", optional = true } [dev-dependencies] -env_logger = "0.6" -tempfile = "3.1" +env_logger = "0.6.2" +tempfile = "3.1.0" test-client = { package = "substrate-test-runtime-client", path = "../test-runtime/client" } kvdb-memorydb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" } panic-handler = { package = "substrate-panic-handler", path = "../panic-handler" } @@ -52,7 +52,7 @@ std = [ "derive_more", "fnv", "log", - "hex", + "hex-literal", "futures", "futures03", "executor", diff --git a/core/client/db/Cargo.toml b/core/client/db/Cargo.toml index 594bda744c..891255cb77 100644 --- a/core/client/db/Cargo.toml +++ b/core/client/db/Cargo.toml @@ -6,13 +6,13 @@ edition = "2018" [dependencies] parking_lot = "0.9.0" -log = "0.4" +log = "0.4.8" kvdb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" } # FIXME replace with release as soon as our rocksdb changes are released upstream https://github.com/paritytech/parity-common/issues/88 kvdb-rocksdb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d", optional = true } kvdb-memorydb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" } -linked-hash-map = "0.5" -hash-db = { version = "0.15.2" } +linked-hash-map = "0.5.2" +hash-db = "0.15.2" primitives = { package = "substrate-primitives", path = "../../primitives" } sr-primitives = { path = "../../sr-primitives" } client = { package = "substrate-client", path = "../../client" } @@ -27,7 +27,7 @@ header_metadata = { package = "substrate-header-metadata", path = "../header-met [dev-dependencies] substrate-keyring = { path = "../../keyring" } test-client = { package = "substrate-test-runtime-client", path = "../../test-runtime/client" } -env_logger = { version = "0.6" } +env_logger = "0.6.2" [features] default = [] diff --git a/core/client/src/genesis.rs b/core/client/src/genesis.rs index 796d1417f2..0c0d49f8ea 100644 --- a/core/client/src/genesis.rs +++ b/core/client/src/genesis.rs @@ -54,7 +54,7 @@ mod tests { AccountKeyring, Sr25519Keyring, }; use primitives::{Blake2Hasher, map, offchain::NeverOffchainExt}; - use hex::*; + use hex_literal::*; native_executor_instance!( Executor, diff --git a/core/consensus/aura/Cargo.toml b/core/consensus/aura/Cargo.toml index 724b720f4f..b63987ecb7 100644 --- a/core/consensus/aura/Cargo.toml +++ b/core/consensus/aura/Cargo.toml @@ -21,11 +21,11 @@ substrate-telemetry = { path = "../../telemetry" } keystore = { package = "substrate-keystore", path = "../../keystore" } consensus_common = { package = "substrate-consensus-common", path = "../common" } sr-primitives = { path = "../../sr-primitives" } -futures-preview = { version = "0.3.0-alpha.18", features = ["compat"] } +futures-preview = { version = "0.3.0-alpha.19", features = ["compat"] } futures01 = { package = "futures", version = "0.1" } -futures-timer = "0.3" +futures-timer = "0.4.0" parking_lot = "0.9.0" -log = "0.4" +log = "0.4.8" derive_more = "0.15.0" [dev-dependencies] @@ -34,6 +34,6 @@ substrate-executor = { path = "../../executor" } network = { package = "substrate-network", path = "../../network", features = ["test-helpers"]} service = { package = "substrate-service", path = "../../service" } test-client = { package = "substrate-test-runtime-client", path = "../../test-runtime/client" } -tokio = "0.1.7" -env_logger = "0.6" -tempfile = "3.1" +tokio = "0.1.22" +env_logger = "0.6.2" +tempfile = "3.1.0" diff --git a/core/consensus/babe/Cargo.toml b/core/consensus/babe/Cargo.toml index b268a6f41b..e225c2503a 100644 --- a/core/consensus/babe/Cargo.toml +++ b/core/consensus/babe/Cargo.toml @@ -10,9 +10,9 @@ codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive babe_primitives = { package = "substrate-consensus-babe-primitives", path = "primitives" } primitives = { package = "substrate-primitives", path = "../../primitives" } app-crypto = { package = "substrate-application-crypto", path = "../../application-crypto" } -num-bigint = "0.2" -num-rational = "0.2" -num-traits = "0.2" +num-bigint = "0.2.3" +num-rational = "0.2.2" +num-traits = "0.2.8" runtime-support = { package = "srml-support", path = "../../../srml/support" } runtime-version = { package = "sr-version", path = "../../sr-version" } runtime-io = { package = "sr-io", path = "../../sr-io" } @@ -27,14 +27,14 @@ uncles = { package = "substrate-consensus-uncles", path = "../uncles" } slots = { package = "substrate-consensus-slots", path = "../slots" } sr-primitives = { path = "../../sr-primitives" } fork-tree = { path = "../../utils/fork-tree" } -futures-preview = { version = "0.3.0-alpha.18", features = ["compat"] } +futures-preview = { version = "0.3.0-alpha.19", features = ["compat"] } futures01 = { package = "futures", version = "0.1" } -futures-timer = "0.3" +futures-timer = "0.4.0" parking_lot = "0.9.0" -log = "0.4.6" -schnorrkel = { version = "0.8.4", features = ["preaudit_deprecated"] } -rand = "0.6.5" -merlin = "1.0.3" +log = "0.4.8" +schnorrkel = { version = "0.8.5", features = ["preaudit_deprecated"] } +rand = "0.7.2" +merlin = "1.2.1" pdqselect = "0.1.0" [dev-dependencies] @@ -43,9 +43,9 @@ substrate-executor = { path = "../../executor" } network = { package = "substrate-network", path = "../../network", features = ["test-helpers"]} service = { package = "substrate-service", path = "../../service" } test-client = { package = "substrate-test-runtime-client", path = "../../test-runtime/client" } -tokio = "0.1.18" -env_logger = "0.6.1" -tempfile = "3.1" +tokio = "0.1.22" +env_logger = "0.6.2" +tempfile = "3.1.0" [features] test-helpers = [] diff --git a/core/consensus/babe/primitives/Cargo.toml b/core/consensus/babe/primitives/Cargo.toml index 5f7fbe4fd8..79e817d081 100644 --- a/core/consensus/babe/primitives/Cargo.toml +++ b/core/consensus/babe/primitives/Cargo.toml @@ -11,7 +11,7 @@ rstd = { package = "sr-std", path = "../../../sr-std", default-features = false sr-primitives = { path = "../../../sr-primitives", default-features = false } app-crypto = { package = "substrate-application-crypto", path = "../../../application-crypto", default-features = false } slots = { package = "substrate-consensus-slots", path = "../../slots", optional = true } -schnorrkel = { version = "0.8.4", features = ["preaudit_deprecated"], optional = true } +schnorrkel = { version = "0.8.5", features = ["preaudit_deprecated"], optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } [features] diff --git a/core/consensus/common/Cargo.toml b/core/consensus/common/Cargo.toml index e75c4c695e..73a74c7ced 100644 --- a/core/consensus/common/Cargo.toml +++ b/core/consensus/common/Cargo.toml @@ -6,13 +6,13 @@ description = "Common utilities for substrate consensus" edition = "2018" [dependencies] -derive_more = "0.14.0" +derive_more = "0.15.0" libp2p = { version = "0.12.0", default-features = false } -log = "0.4" +log = "0.4.8" primitives = { package = "substrate-primitives", path= "../../primitives" } inherents = { package = "substrate-inherents", path = "../../inherents" } -futures-preview = "0.3.0-alpha.18" -futures-timer = "0.3" +futures-preview = "0.3.0-alpha.19" +futures-timer = "0.4.0" rstd = { package = "sr-std", path = "../../sr-std" } runtime_version = { package = "sr-version", path = "../../sr-version" } sr-primitives = { path = "../../sr-primitives" } diff --git a/core/consensus/pow/Cargo.toml b/core/consensus/pow/Cargo.toml index f5bb3a4ea8..54dd58c467 100644 --- a/core/consensus/pow/Cargo.toml +++ b/core/consensus/pow/Cargo.toml @@ -14,5 +14,5 @@ srml-timestamp = { path = "../../../srml/timestamp" } inherents = { package = "substrate-inherents", path = "../../inherents" } pow-primitives = { package = "substrate-consensus-pow-primitives", path = "primitives" } consensus-common = { package = "substrate-consensus-common", path = "../common" } -log = "0.4" -futures-preview = { version = "0.3.0-alpha.18", features = ["compat"] } +log = "0.4.8" +futures-preview = { version = "0.3.0-alpha.19", features = ["compat"] } diff --git a/core/consensus/rhd/Cargo.toml b/core/consensus/rhd/Cargo.toml index 801605c3f6..48d0840b55 100644 --- a/core/consensus/rhd/Cargo.toml +++ b/core/consensus/rhd/Cargo.toml @@ -6,8 +6,8 @@ description = "Rhododendron Round-Based consensus-algorithm for substrate" edition = "2018" [dependencies] -derive_more = "0.14.0" -futures = "0.1.17" +derive_more = "0.15.0" +futures = "0.1.29" codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../primitives" } consensus = { package = "substrate-consensus-common", path = "../common" } @@ -18,11 +18,11 @@ srml-system = { path = "../../../srml/system" } sr-primitives = { path = "../../sr-primitives" } runtime_version = { package = "sr-version", path = "../../sr-version" } runtime_io = { package = "sr-io", path = "../../sr-io" } -tokio = "0.1.7" +tokio = "0.1.22" parking_lot = "0.9.0" -log = "0.4" +log = "0.4.8" rhododendron = { version = "0.7.0", features = ["codec"] } -exit-future = "0.1" +exit-future = "0.1.4" [dev-dependencies] keyring = { package = "substrate-keyring", path = "../../keyring" } diff --git a/core/consensus/slots/Cargo.toml b/core/consensus/slots/Cargo.toml index 03c62c7245..4074242502 100644 --- a/core/consensus/slots/Cargo.toml +++ b/core/consensus/slots/Cargo.toml @@ -14,10 +14,10 @@ sr-primitives = { path = "../../sr-primitives" } substrate-telemetry = { path = "../../telemetry" } consensus_common = { package = "substrate-consensus-common", path = "../common" } inherents = { package = "substrate-inherents", path = "../../inherents" } -futures-preview = "0.3.0-alpha.18" -futures-timer = "0.3" +futures-preview = "0.3.0-alpha.19" +futures-timer = "0.4.0" parking_lot = "0.9.0" -log = "0.4" +log = "0.4.8" [dev-dependencies] test-client = { package = "substrate-test-runtime-client", path = "../../test-runtime/client" } diff --git a/core/consensus/uncles/Cargo.toml b/core/consensus/uncles/Cargo.toml index 98b8adee8b..4820324870 100644 --- a/core/consensus/uncles/Cargo.toml +++ b/core/consensus/uncles/Cargo.toml @@ -12,4 +12,4 @@ sr-primitives = { path = "../../sr-primitives" } srml-authorship = { path = "../../../srml/authorship" } consensus_common = { package = "substrate-consensus-common", path = "../common" } inherents = { package = "substrate-inherents", path = "../../inherents" } -log = "0.4" +log = "0.4.8" diff --git a/core/executor/Cargo.toml b/core/executor/Cargo.toml index dade16a935..1f53cd4099 100644 --- a/core/executor/Cargo.toml +++ b/core/executor/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -derive_more = "0.14.0" +derive_more = "0.15.0" codec = { package = "parity-scale-codec", version = "1.0.0" } runtime_io = { package = "sr-io", path = "../sr-io" } primitives = { package = "substrate-primitives", path = "../primitives" } @@ -13,19 +13,19 @@ trie = { package = "substrate-trie", path = "../trie" } serializer = { package = "substrate-serializer", path = "../serializer" } runtime_version = { package = "sr-version", path = "../sr-version" } panic-handler = { package = "substrate-panic-handler", path = "../panic-handler" } +wasmi = "0.5.1" +parity-wasm = "0.40.3" +lazy_static = "1.4.0" wasm-interface = { package = "substrate-wasm-interface", path = "../wasm-interface" } -wasmi = "0.5.0" -parity-wasm = "0.40.1" -lazy_static = "1.3" parking_lot = "0.9.0" -log = "0.4" -libsecp256k1 = "0.3" -tiny-keccak = "1.4.2" +log = "0.4.8" +libsecp256k1 = "0.3.0" +tiny-keccak = "1.5.0" [dev-dependencies] -assert_matches = "1.1" -wabt = "~0.7.4" -hex-literal = "0.2.0" +assert_matches = "1.3.0" +wabt = "0.9.2" +hex-literal = "0.2.1" runtime-test = { package = "substrate-runtime-test", path = "runtime-test" } substrate-client = { path = "../client" } substrate-offchain = { path = "../offchain/" } diff --git a/core/executor/runtime-test/Cargo.toml b/core/executor/runtime-test/Cargo.toml index 2d4e58b8d4..153c5c9a1f 100644 --- a/core/executor/runtime-test/Cargo.toml +++ b/core/executor/runtime-test/Cargo.toml @@ -17,4 +17,4 @@ wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1. [features] default = [ "std" ] -std = [] +std = ["runtime_io/std", "sandbox/std", "rstd/std"] diff --git a/core/executor/src/allocator.rs b/core/executor/src/allocator.rs index 403cf92e20..523499db71 100644 --- a/core/executor/src/allocator.rs +++ b/core/executor/src/allocator.rs @@ -155,7 +155,7 @@ impl FreeingBumpHeapAllocator { /// Deallocates the space which was allocated for a pointer. /// - /// # Arguments + /// # Arguments /// /// - `mem` - a slice representing the linear memory on which this allocator operates. /// - `ptr` - pointer to the allocated chunk diff --git a/core/executor/src/wasm_executor.rs b/core/executor/src/wasm_executor.rs index afdbe57640..6ded0adad6 100644 --- a/core/executor/src/wasm_executor.rs +++ b/core/executor/src/wasm_executor.rs @@ -27,16 +27,15 @@ use wasmi::{ Module, ModuleInstance, MemoryInstance, MemoryRef, TableRef, ImportsBuilder, ModuleRef, memory_units::Pages, RuntimeValue::{I32, I64, self}, }; -use crate::error::{Error, Result}; +use super::{sandbox, allocator, error::{Error, Result}}; use codec::{Encode, Decode}; use primitives::{ blake2_128, blake2_256, twox_64, twox_128, twox_256, ed25519, sr25519, Pair, crypto::KeyTypeId, offchain, sandbox as sandbox_primitives, Blake2Hasher, traits::Externalities, }; -use trie::{TrieConfiguration, trie_types::Layout}; -use crate::sandbox; -use crate::allocator; +use trie::TrieConfiguration; +use trie::trie_types::Layout; use log::trace; use wasm_interface::{ FunctionContext, HostFunctions, Pointer, WordSize, Sandbox, MemoryId, PointerType, diff --git a/core/finality-grandpa/Cargo.toml b/core/finality-grandpa/Cargo.toml index 4e835e14f8..0a42ff4531 100644 --- a/core/finality-grandpa/Cargo.toml +++ b/core/finality-grandpa/Cargo.toml @@ -6,20 +6,20 @@ edition = "2018" [dependencies] fork-tree = { path = "../../core/utils/fork-tree" } -futures = "0.1" -futures03 = { package = "futures-preview", version = "0.3.0-alpha.18", features = ["compat"] } -log = "0.4" +futures = "0.1.29" +futures03 = { package = "futures-preview", version = "0.3.0-alpha.19", features = ["compat"] } +log = "0.4.8" parking_lot = "0.9.0" -tokio-executor = "0.1.7" +tokio-executor = "0.1.8" tokio-timer = "0.2.11" -rand = "0.6" +rand = "0.7.2" codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } sr-primitives = { path = "../sr-primitives" } consensus_common = { package = "substrate-consensus-common", path = "../consensus/common" } primitives = { package = "substrate-primitives", path = "../primitives" } substrate-telemetry = { path = "../telemetry" } keystore = { package = "substrate-keystore", path = "../keystore" } -serde_json = "1.0" +serde_json = "1.0.40" client = { package = "substrate-client", path = "../client" } header-metadata = { package = "substrate-header-metadata", path = "../client/header-metadata" } inherents = { package = "substrate-inherents", path = "../../core/inherents" } @@ -34,6 +34,6 @@ network = { package = "substrate-network", path = "../network", features = ["tes keyring = { package = "substrate-keyring", path = "../keyring" } test-client = { package = "substrate-test-runtime-client", path = "../test-runtime/client"} babe_primitives = { package = "substrate-consensus-babe-primitives", path = "../consensus/babe/primitives" } -env_logger = "0.6" -tokio = "0.1.17" -tempfile = "3.1" +env_logger = "0.6.2" +tokio = "0.1.22" +tempfile = "3.1.0" diff --git a/core/finality-grandpa/primitives/Cargo.toml b/core/finality-grandpa/primitives/Cargo.toml index ecbaf2e1ec..02439d4150 100644 --- a/core/finality-grandpa/primitives/Cargo.toml +++ b/core/finality-grandpa/primitives/Cargo.toml @@ -10,7 +10,7 @@ app-crypto = { package = "substrate-application-crypto", path = "../../applicati codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } sr-primitives = { path = "../../sr-primitives", default-features = false } rstd = { package = "sr-std", path = "../../sr-std", default-features = false } -serde = { version = "1.0", optional = true, features = ["derive"] } +serde = { version = "1.0.101", optional = true, features = ["derive"] } [features] default = ["std"] diff --git a/core/keyring/Cargo.toml b/core/keyring/Cargo.toml index 1a58dc133e..0147689985 100644 --- a/core/keyring/Cargo.toml +++ b/core/keyring/Cargo.toml @@ -7,6 +7,6 @@ edition = "2018" [dependencies] primitives = { package = "substrate-primitives", path = "../primitives" } sr-primitives = { path = "../sr-primitives" } -lazy_static = { version = "1.0" } +lazy_static = "1.4.0" strum = "0.15.0" strum_macros = "0.15.0" diff --git a/core/keystore/Cargo.toml b/core/keystore/Cargo.toml index c56b9ba67d..ff5696ab37 100644 --- a/core/keystore/Cargo.toml +++ b/core/keystore/Cargo.toml @@ -8,11 +8,11 @@ edition = "2018" derive_more = "0.15.0" primitives = { package = "substrate-primitives", path = "../primitives" } app-crypto = { package = "substrate-application-crypto", path = "../application-crypto" } -hex = "0.3" -rand = "0.6" -serde_json = "1.0" -subtle = "2.0" +hex = "0.3.2" +rand = "0.7.2" +serde_json = "1.0.40" +subtle = "2.1.1" parking_lot = "0.9.0" [dev-dependencies] -tempdir = "0.3" +tempdir = "0.3.7" diff --git a/core/network/Cargo.toml b/core/network/Cargo.toml index e8d84e1c6f..453fbbeee3 100644 --- a/core/network/Cargo.toml +++ b/core/network/Cargo.toml @@ -7,21 +7,21 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -bytes = "0.4" -derive_more = "0.14.0" -either = "1.5.2" -log = "0.4" +bytes = "0.4.12" +derive_more = "0.15.0" +either = "1.5.3" +log = "0.4.8" parking_lot = "0.9.0" -bitflags = "1.0" -fnv = "1.0" -futures = "0.1.17" -futures03 = { package = "futures-preview", version = "0.3.0-alpha.18", features = ["compat"] } -futures-timer = "0.3" -linked-hash-map = "0.5" +bitflags = "1.2.0" +fnv = "1.0.6" +futures = "0.1.29" +futures03 = { package = "futures-preview", version = "0.3.0-alpha.19", features = ["compat"] } +futures-timer = "0.4.0" +linked-hash-map = "0.5.2" linked_hash_set = "0.1.3" lru-cache = "0.1.2" -rustc-hex = "2.0" -rand = "0.6" +rustc-hex = "2.0.1" +rand = "0.7.2" libp2p = { version = "0.12.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] } fork-tree = { path = "../../core/utils/fork-tree" } consensus = { package = "substrate-consensus-common", path = "../../core/consensus/common" } @@ -31,31 +31,31 @@ sr-primitives = { path = "../../core/sr-primitives" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } peerset = { package = "substrate-peerset", path = "../../core/peerset" } -serde = { version = "1.0.70", features = ["derive"] } -serde_json = "1.0.24" -slog = { version = "^2", features = ["nested-values"] } +serde = { version = "1.0.101", features = ["derive"] } +serde_json = "1.0.40" +slog = { version = "2.5.2", features = ["nested-values"] } slog_derive = "0.1.1" -smallvec = "0.6" -tokio-io = "0.1" -tokio = { version = "0.1.11", optional = true } -unsigned-varint = { version = "0.2.1", features = ["codec"] } +smallvec = "0.6.10" +tokio-io = "0.1.12" +tokio = { version = "0.1.22", optional = true } +unsigned-varint = { version = "0.2.2", features = ["codec"] } keyring = { package = "substrate-keyring", path = "../../core/keyring", optional = true } test_client = { package = "substrate-test-client", path = "../../core/test-client", optional = true } test-client = { package = "substrate-test-runtime-client", path = "../../core/test-runtime/client", optional = true } erased-serde = "0.3.9" -void = "1.0" -zeroize = "0.9.0" +void = "1.0.2" +zeroize = "0.10.1" babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../consensus/babe/primitives" } [dev-dependencies] -env_logger = { version = "0.6" } +env_logger = "0.6.2" keyring = { package = "substrate-keyring", path = "../../core/keyring" } -quickcheck = "0.8.5" -rand = "0.6.5" +quickcheck = "0.9.0" +rand = "0.7.2" test-client = { package = "substrate-test-runtime-client", path = "../../core/test-runtime/client" } test_runtime = { package = "substrate-test-runtime", path = "../../core/test-runtime" } -tempdir = "0.3" -tokio = "0.1.11" +tempdir = "0.3.7" +tokio = "0.1.22" [features] default = [] diff --git a/core/network/src/protocol/sync.rs b/core/network/src/protocol/sync.rs index 39927792be..9f9db92289 100644 --- a/core/network/src/protocol/sync.rs +++ b/core/network/src/protocol/sync.rs @@ -1325,4 +1325,3 @@ fn explicit_sync_request( } None } - diff --git a/core/network/src/test/sync.rs b/core/network/src/test/sync.rs index 3d8e57cad0..b5b137a31a 100644 --- a/core/network/src/test/sync.rs +++ b/core/network/src/test/sync.rs @@ -581,4 +581,3 @@ fn can_sync_explicit_forks() { Ok(Async::Ready(())) })).unwrap(); } - diff --git a/core/offchain/Cargo.toml b/core/offchain/Cargo.toml index 867f80f6d2..8f342ee602 100644 --- a/core/offchain/Cargo.toml +++ b/core/offchain/Cargo.toml @@ -7,30 +7,30 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -bytes = "0.4" +bytes = "0.4.12" client = { package = "substrate-client", path = "../../core/client" } -fnv = "1.0" +fnv = "1.0.6" futures01 = { package = "futures", version = "0.1" } -futures-preview = "0.3.0-alpha.18" -futures-timer = "0.3" -hyper = "0.12.33" +futures-preview = "0.3.0-alpha.19" +futures-timer = "0.4.0" +hyper = "0.12.35" hyper-tls = "0.3.2" -log = "0.4" +log = "0.4.8" offchain-primitives = { package = "substrate-offchain-primitives", path = "./primitives" } codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } parking_lot = "0.9.0" primitives = { package = "substrate-primitives", path = "../../core/primitives" } -rand = "0.7" +rand = "0.7.2" sr-primitives = { path = "../../core/sr-primitives" } transaction_pool = { package = "substrate-transaction-pool", path = "../../core/transaction-pool" } network = { package = "substrate-network", path = "../../core/network" } keystore = { package = "substrate-keystore", path = "../keystore" } [dev-dependencies] -env_logger = "0.6" +env_logger = "0.6.2" client-db = { package = "substrate-client-db", path = "../../core/client/db/", default-features = true } test-client = { package = "substrate-test-runtime-client", path = "../../core/test-runtime/client" } -tokio = "0.1" +tokio = "0.1.22" [features] default = [] diff --git a/core/offchain/src/api/http.rs b/core/offchain/src/api/http.rs index 9ea666862c..6744a42f95 100644 --- a/core/offchain/src/api/http.rs +++ b/core/offchain/src/api/http.rs @@ -759,7 +759,7 @@ mod tests { let (mut api, addr) = build_api_server!(); - let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); api.request_write_body(id, &[], Some(deadline)).unwrap(); match api.response_wait(&[id], Some(deadline))[0] { @@ -805,13 +805,13 @@ mod tests { Ok(_) => panic!() }; - let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); match api.request_add_header(id, "Foo", "\0") { Err(()) => {} Ok(_) => panic!() }; - let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); api.request_add_header(id, "Foo", "Bar").unwrap(); api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); match api.request_add_header(id, "Foo2", "Bar") { @@ -848,7 +848,7 @@ mod tests { _ => panic!() }; - let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); api.request_write_body(id, &[], None).unwrap(); @@ -857,7 +857,7 @@ mod tests { _ => panic!() }; - let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); api.request_write_body(id, &[], None).unwrap(); @@ -866,7 +866,7 @@ mod tests { _ => panic!() }; - let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); api.response_wait(&[id], None); match api.request_write_body(id, &[], None) { @@ -874,7 +874,7 @@ mod tests { _ => panic!() }; - let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); api.request_write_body(id, &[1, 2, 3, 4], None).unwrap(); api.response_wait(&[id], None); match api.request_write_body(id, &[1, 2, 3, 4], None) { @@ -882,7 +882,7 @@ mod tests { _ => panic!() }; - let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); api.response_headers(id); match api.request_write_body(id, &[1, 2, 3, 4], None) { Err(HttpError::Invalid) => {} @@ -896,14 +896,14 @@ mod tests { _ => panic!() }; - let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); api.response_read_body(id, &mut [], None).unwrap(); match api.request_write_body(id, &[1, 2, 3, 4], None) { Err(HttpError::Invalid) => {} _ => panic!() }; - let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); api.response_read_body(id, &mut [], None).unwrap(); match api.request_write_body(id, &[], None) { Err(HttpError::Invalid) => {} @@ -916,10 +916,10 @@ mod tests { let (mut api, addr) = build_api_server!(); assert!(api.response_headers(HttpRequestId(0xdead)).is_empty()); - let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); assert!(api.response_headers(id).is_empty()); - let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); api.request_write_body(id, &[], None).unwrap(); while api.response_headers(id).is_empty() { std::thread::sleep(std::time::Duration::from_millis(100)); @@ -939,10 +939,10 @@ mod tests { fn response_header_invalid_call() { let (mut api, addr) = build_api_server!(); - let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); assert!(api.response_headers(id).is_empty()); - let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); api.request_add_header(id, "Foo", "Bar").unwrap(); assert!(api.response_headers(id).is_empty()); @@ -983,7 +983,7 @@ mod tests { let (mut api, addr) = build_api_server!(); for _ in 0..50 { - let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); + let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); for _ in 0..250 { match rand::random::() % 6 { diff --git a/core/panic-handler/Cargo.toml b/core/panic-handler/Cargo.toml index 054bd643ac..9724b92919 100644 --- a/core/panic-handler/Cargo.toml +++ b/core/panic-handler/Cargo.toml @@ -6,5 +6,5 @@ description = "Substrate panic handler." edition = "2018" [dependencies] -backtrace = "0.3" -log = "0.4" +backtrace = "0.3.38" +log = "0.4.8" diff --git a/core/peerset/Cargo.toml b/core/peerset/Cargo.toml index c2c92b8b1a..b11e59c770 100644 --- a/core/peerset/Cargo.toml +++ b/core/peerset/Cargo.toml @@ -8,12 +8,12 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -futures-preview = "0.3.0-alpha.18" +futures-preview = "0.3.0-alpha.19" libp2p = { version = "0.12.0", default-features = false } -linked-hash-map = "0.5" -log = "0.4" +linked-hash-map = "0.5.2" +log = "0.4.8" lru-cache = "0.1.2" -serde_json = "1.0.24" +serde_json = "1.0.40" [dev-dependencies] -rand = "0.6" +rand = "0.7.2" diff --git a/core/phragmen/Cargo.toml b/core/phragmen/Cargo.toml index 52f061b862..e10be1d92d 100644 --- a/core/phragmen/Cargo.toml +++ b/core/phragmen/Cargo.toml @@ -11,7 +11,7 @@ rstd = { package = "sr-std", path = "../sr-std", default-features = false } [dev-dependencies] runtime-io ={ package = "sr-io", path = "../sr-io" } support = { package = "srml-support", path = "../../srml/support" } -rand = "0.7.0" +rand = "0.7.2" [features] default = ["std"] diff --git a/core/primitives/Cargo.toml b/core/primitives/Cargo.toml index b94fa39bd0..461a8fe7e3 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -7,37 +7,37 @@ edition = "2018" [dependencies] rstd = { package = "sr-std", path = "../sr-std", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -rustc-hex = { version = "2.0", default-features = false } -serde = { version = "1.0", optional = true, features = ["derive"] } -twox-hash = { version = "1.2.0", optional = true } -byteorder = { version = "1.3.1", default-features = false } +rustc-hex = { version = "2.0.1", default-features = false } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +twox-hash = { version = "1.5.0", optional = true } +byteorder = { version = "1.3.2", default-features = false } primitive-types = { version = "0.5.1", default-features = false, features = ["codec"] } -impl-serde = { version = "0.1", optional = true } -log = { version = "0.4", optional = true } -wasmi = { version = "0.5.0", optional = true } +impl-serde = { version = "0.2.1", optional = true } +log = { version = "0.4.8", optional = true } +wasmi = { version = "0.5.1", optional = true } hash-db = { version = "0.15.2", default-features = false } hash256-std-hasher = { version = "0.15.2", default-features = false } -ed25519-dalek = { version = "1.0.0-pre.1", optional = true } -base58 = { version = "0.1", optional = true } +ed25519-dalek = { version = "0.9.1", optional = true } +base58 = { version = "0.1.0", optional = true } blake2-rfc = { version = "0.2.18", optional = true } -schnorrkel = { version = "0.8.4", features = ["preaudit_deprecated"], optional = true } -rand = { version = "0.6", optional = true } -sha2 = { version = "0.8", optional = true } +schnorrkel = { version = "0.8.5", features = ["preaudit_deprecated"], optional = true } +rand = { version = "0.7.2", optional = true } +sha2 = { version = "0.8.0", optional = true } substrate-bip39 = { version = "0.3.1", optional = true } -tiny-bip39 = { version = "0.6.1", optional = true } -hex = { version = "0.3", optional = true } -regex = { version = "1.1", optional = true } -num-traits = { version = "0.2", default-features = false } -zeroize = { version = "0.9.2", default-features = false } -lazy_static = { version = "1.3", optional = true } +tiny-bip39 = { version = "0.6.2", optional = true } +hex = { version = "0.3.2", optional = true } +regex = { version = "1.3.1", optional = true } +num-traits = { version = "0.2.8", default-features = false } +zeroize = "0.10.1" +lazy_static = { version = "1.4.0", optional = true } parking_lot = { version = "0.9.0", optional = true } [dev-dependencies] substrate-serializer = { path = "../serializer" } -pretty_assertions = "0.6" -hex-literal = "0.2" -rand = "0.6" -criterion = "0.2" +pretty_assertions = "0.6.1" +hex-literal = "0.2.1" +rand = "0.7.2" +criterion = "0.2.11" [[bench]] name = "benches" @@ -79,5 +79,4 @@ std = [ "schnorrkel", "regex", "num-traits/std", - "zeroize/std" ] diff --git a/core/primitives/src/crypto.rs b/core/primitives/src/crypto.rs index e2838315d1..8a336783b7 100644 --- a/core/primitives/src/crypto.rs +++ b/core/primitives/src/crypto.rs @@ -587,9 +587,8 @@ pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static { /// This is only for ephemeral keys really, since you won't have access to the secret key /// for storage. If you want a persistent key pair, use `generate_with_phrase` instead. fn generate() -> (Self, Self::Seed) { - let mut csprng: OsRng = OsRng::new().expect("OS random generator works; qed"); let mut seed = Self::Seed::default(); - csprng.fill_bytes(seed.as_mut()); + OsRng.fill_bytes(seed.as_mut()); (Self::from_seed(&seed), seed) } diff --git a/core/primitives/src/ed25519.rs b/core/primitives/src/ed25519.rs index 810e86767d..c40499a3a1 100644 --- a/core/primitives/src/ed25519.rs +++ b/core/primitives/src/ed25519.rs @@ -397,7 +397,7 @@ impl TraitPair for Pair { fn from_seed_slice(seed_slice: &[u8]) -> Result { let secret = ed25519_dalek::SecretKey::from_bytes(seed_slice) .map_err(|_| SecretStringError::InvalidSeedLength)?; - let public = ed25519_dalek::PublicKey::from(&secret); + let public = ed25519_dalek::PublicKey::from(secret.expand::()); Ok(Pair(ed25519_dalek::Keypair { secret, public })) } @@ -434,7 +434,7 @@ impl TraitPair for Pair { /// Sign a message. fn sign(&self, message: &[u8]) -> Signature { - let r = self.0.sign(message).to_bytes(); + let r = self.0.sign::(message).to_bytes(); Signature::from_raw(r) } @@ -458,7 +458,7 @@ impl TraitPair for Pair { Err(_) => return false }; - match public_key.verify(message.as_ref(), &sig) { + match public_key.verify::(message.as_ref(), &sig) { Ok(_) => true, _ => false, } diff --git a/core/rpc-servers/Cargo.toml b/core/rpc-servers/Cargo.toml index f5c5da0339..27601d8cc1 100644 --- a/core/rpc-servers/Cargo.toml +++ b/core/rpc-servers/Cargo.toml @@ -7,8 +7,8 @@ edition = "2018" [dependencies] jsonrpc-core = "13.2.0" pubsub = { package = "jsonrpc-pubsub", version = "13.2.0" } -log = "0.4" -serde = "1.0" +log = "0.4.8" +serde = "1.0.101" serde_json = "1.0" sr-primitives = { path = "../sr-primitives" } diff --git a/core/rpc/Cargo.toml b/core/rpc/Cargo.toml index 215cf02a8c..5178fc56d8 100644 --- a/core/rpc/Cargo.toml +++ b/core/rpc/Cargo.toml @@ -8,13 +8,13 @@ edition = "2018" api = { package = "substrate-rpc-api", path = "./api" } client = { package = "substrate-client", path = "../client" } codec = { package = "parity-scale-codec", version = "1.0.0" } -futures03 = { package = "futures-preview", version = "0.3.0-alpha.18", features = ["compat"] } +futures03 = { package = "futures-preview", version = "0.3.0-alpha.19", features = ["compat"] } jsonrpc-pubsub = "13.1.0" -log = "0.4" +log = "0.4.8" primitives = { package = "substrate-primitives", path = "../primitives" } rpc = { package = "jsonrpc-core", version = "13.0.0" } runtime_version = { package = "sr-version", path = "../sr-version" } -serde_json = "1.0" +serde_json = "1.0.40" session = { package = "substrate-session", path = "../session" } sr-primitives = { path = "../sr-primitives" } rpc-primitives = { package = "substrate-rpc-primitives", path = "primitives" } @@ -22,13 +22,13 @@ state_machine = { package = "substrate-state-machine", path = "../state-machine" substrate-executor = { path = "../executor" } substrate-keystore = { path = "../keystore" } transaction_pool = { package = "substrate-transaction-pool", path = "../transaction-pool" } -hash-db = { version = "0.15.0", default-features = false } +hash-db = { version = "0.15.2", default-features = false } [dev-dependencies] -assert_matches = "1.1" -futures = "0.1.17" +assert_matches = "1.3.0" +futures = "0.1.29" network = { package = "substrate-network", path = "../network" } -rustc-hex = "2.0" +rustc-hex = "2.0.1" sr-io = { path = "../sr-io" } test-client = { package = "substrate-test-runtime-client", path = "../test-runtime/client" } -tokio = "0.1.17" +tokio = "0.1.22" diff --git a/core/rpc/api/Cargo.toml b/core/rpc/api/Cargo.toml index e4114147d6..b2614dbced 100644 --- a/core/rpc/api/Cargo.toml +++ b/core/rpc/api/Cargo.toml @@ -6,17 +6,17 @@ edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0" } -derive_more = "0.14.0" -futures03 = { package = "futures-preview", version = "0.3.0-alpha.18", features = ["compat"] } +derive_more = "0.15.0" +futures03 = { package = "futures-preview", version = "0.3.0-alpha.19", features = ["compat"] } jsonrpc-core = "13.2.0" jsonrpc-core-client = "13.2.0" jsonrpc-derive = "13.2.0" jsonrpc-pubsub = "13.2.0" -log = "0.4" +log = "0.4.8" parking_lot = "0.9.0" primitives = { package = "substrate-primitives", path = "../../primitives" } runtime_version = { package = "sr-version", path = "../../sr-version" } -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" +serde = { version = "1.0.101", features = ["derive"] } +serde_json = "1.0.40" txpool = { package = "substrate-transaction-graph", path = "../../transaction-pool/graph" } rpc-primitives = { package = "substrate-rpc-primitives", path = "../../rpc/primitives" } diff --git a/core/rpc/primitives/Cargo.toml b/core/rpc/primitives/Cargo.toml index fab94a86ba..4044428112 100644 --- a/core/rpc/primitives/Cargo.toml +++ b/core/rpc/primitives/Cargo.toml @@ -5,5 +5,5 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", features = ["derive"] } +serde = { version = "1.0.101", features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../primitives" } diff --git a/core/serializer/Cargo.toml b/core/serializer/Cargo.toml index ae320e4277..b6dfa3f470 100644 --- a/core/serializer/Cargo.toml +++ b/core/serializer/Cargo.toml @@ -5,5 +5,5 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = "1.0" -serde_json = "1.0" +serde = "1.0.101" +serde_json = "1.0.40" diff --git a/core/service/Cargo.toml b/core/service/Cargo.toml index e0982c58ae..5d8abee116 100644 --- a/core/service/Cargo.toml +++ b/core/service/Cargo.toml @@ -5,20 +5,20 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -derive_more = "0.14.0" -futures = "0.1.17" -futures03 = { package = "futures-preview", version = "0.3.0-alpha.18", features = ["compat"] } +derive_more = "0.15.0" +futures = "0.1.29" +futures03 = { package = "futures-preview", version = "0.3.0-alpha.19", features = ["compat"] } parking_lot = "0.9.0" -lazy_static = "1.0" -log = "0.4" -slog = {version = "^2", features = ["nested-values"]} -tokio-executor = "0.1.7" -tokio-timer = "0.2" -exit-future = "0.1" -serde = { version = "1.0" } -serde_json = "1.0" -sysinfo = "0.9.0" -target_info = "0.1" +lazy_static = "1.4.0" +log = "0.4.8" +slog = { version = "2.5.2", features = ["nested-values"] } +tokio-executor = "0.1.8" +tokio-timer = "0.2.11" +exit-future = "0.1.4" +serde = "1.0.101" +serde_json = "1.0.40" +sysinfo = "0.9.5" +target_info = "0.1.0" keystore = { package = "substrate-keystore", path = "../../core/keystore" } sr-io = { path = "../../core/sr-io" } sr-primitives = { path = "../../core/sr-primitives" } diff --git a/core/service/src/chain_ops.rs b/core/service/src/chain_ops.rs index f82dac1913..0858534482 100644 --- a/core/service/src/chain_ops.rs +++ b/core/service/src/chain_ops.rs @@ -21,6 +21,7 @@ use chain_spec::{ChainSpec, RuntimeGenesis, Extension}; /// Defines the logic for an operation exporting blocks within a range. #[macro_export] +/// Export blocks macro_rules! export_blocks { ($client:ident, $exit:ident, $output:ident, $from:ident, $to:ident, $json:ident) => {{ let mut block = $from; @@ -77,6 +78,7 @@ macro_rules! export_blocks { /// Defines the logic for an operation importing blocks from some known import. #[macro_export] +/// Import blocks macro_rules! import_blocks { ($block:ty, $client:ident, $queue:ident, $exit:ident, $input:ident) => {{ use consensus_common::import_queue::{IncomingBlock, Link, BlockImportError, BlockImportResult}; @@ -120,7 +122,7 @@ macro_rules! import_blocks { } let (exit_send, exit_recv) = std::sync::mpsc::channel(); - ::std::thread::spawn(move || { + std::thread::spawn(move || { let _ = $exit.wait(); let _ = exit_send.send(()); }); diff --git a/core/service/src/lib.rs b/core/service/src/lib.rs index afe5bad8f5..fccf04d8a1 100644 --- a/core/service/src/lib.rs +++ b/core/service/src/lib.rs @@ -629,7 +629,7 @@ impl Future for // Polling all the `to_poll` futures. while let Some(pos) = self.to_poll.iter_mut().position(|t| t.poll().map(|t| t.is_ready()).unwrap_or(true)) { - self.to_poll.remove(pos); + let _ = self.to_poll.remove(pos); } // The service future never ends. diff --git a/core/service/test/Cargo.toml b/core/service/test/Cargo.toml index 459e079c85..b4651da7a7 100644 --- a/core/service/test/Cargo.toml +++ b/core/service/test/Cargo.toml @@ -5,13 +5,13 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -tempdir = "0.3" -tokio = "0.1.7" -futures = "0.1" -futures03 = { package = "futures-preview", version = "=0.3.0-alpha.18", features = ["compat"] } -log = "0.4" -env_logger = "0.6" -fdlimit = "0.1" +tempdir = "0.3.7" +tokio = "0.1.22" +futures = "0.1.29" +log = "0.4.8" +env_logger = "0.6.2" +fdlimit = "0.1.1" +futures03 = { package = "futures-preview", version = "=0.3.0-alpha.19", features = ["compat"] } service = { package = "substrate-service", path = "../../../core/service" } network = { package = "substrate-network", path = "../../../core/network" } consensus = { package = "substrate-consensus-common", path = "../../../core/consensus/common" } diff --git a/core/sr-api-macros/Cargo.toml b/core/sr-api-macros/Cargo.toml index c025ad800e..6f02e30409 100644 --- a/core/sr-api-macros/Cargo.toml +++ b/core/sr-api-macros/Cargo.toml @@ -9,10 +9,10 @@ proc-macro = true [dependencies] quote = "0.6.12" -syn = { version = "^0.15.30", features = [ "full", "fold", "extra-traits", "visit" ] } -proc-macro2 = "0.4" -blake2-rfc = "0.2" -proc-macro-crate = "0.1.3" +syn = { version = "0.15.44", features = [ "full", "fold", "extra-traits", "visit" ] } +proc-macro2 = "0.4.27" +blake2-rfc = "0.2.18" +proc-macro-crate = "0.1.4" [dev-dependencies] client = { package = "substrate-client", path = "../client" } @@ -21,11 +21,11 @@ state_machine = { package = "substrate-state-machine", path = "../state-machine" sr-primitives = { path = "../sr-primitives" } sr-version = { path = "../sr-version" } primitives = { package = "substrate-primitives", path = "../primitives" } -criterion = "0.2" +criterion = "0.2.11" consensus_common = { package = "substrate-consensus-common", path = "../consensus/common" } codec = { package = "parity-scale-codec", version = "1.0.0" } -trybuild = "1.0" -rustversion = "0.1" +trybuild = "1.0.14" +rustversion = "0.1.4" [[bench]] name = "bench" diff --git a/core/sr-io/Cargo.toml b/core/sr-io/Cargo.toml index 2200014e9c..65b080b86d 100644 --- a/core/sr-io/Cargo.toml +++ b/core/sr-io/Cargo.toml @@ -6,16 +6,16 @@ build = "build.rs" edition = "2018" [build-dependencies] -rustc_version = "0.2" +rustc_version = "0.2.3" [dependencies] rstd = { package = "sr-std", path = "../sr-std", default-features = false } primitives = { package = "substrate-primitives", path = "../primitives", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } hash-db = { version = "0.15.2", default-features = false } -libsecp256k1 = { version = "0.3", optional = true } -tiny-keccak = { version = "1.4.2", optional = true } -environmental = { version = "1.0.1", optional = true } +libsecp256k1 = { version = "0.3.0", optional = true } +tiny-keccak = { version = "1.5.0", optional = true } +environmental = { version = "1.0.2", optional = true } substrate-state-machine = { path = "../state-machine", optional = true } trie = { package = "substrate-trie", path = "../trie", optional = true } @@ -30,7 +30,7 @@ std = [ "environmental", "substrate-state-machine", "libsecp256k1", - "tiny-keccak" + "tiny-keccak", ] nightly = [] strict = [] diff --git a/core/sr-io/without_std.rs b/core/sr-io/without_std.rs index 95087b0c48..90ec5a9ee4 100644 --- a/core/sr-io/without_std.rs +++ b/core/sr-io/without_std.rs @@ -1191,4 +1191,3 @@ unsafe fn from_raw_parts(ptr: *mut u8, len: u32) -> Option> { } impl Api for () {} - diff --git a/core/sr-primitives/Cargo.toml b/core/sr-primitives/Cargo.toml index ff12fa6143..fc8b744d37 100644 --- a/core/sr-primitives/Cargo.toml +++ b/core/sr-primitives/Cargo.toml @@ -5,23 +5,23 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -num-traits = { version = "0.2", default-features = false } -integer-sqrt = { version = "0.1.2" } -serde = { version = "1.0", optional = true, features = ["derive"] } +num-traits = { version = "0.2.8", default-features = false } +integer-sqrt = "0.1.2" +serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../primitives", default-features = false } app-crypto = { package = "substrate-application-crypto", path = "../application-crypto", default-features = false } rstd = { package = "sr-std", path = "../sr-std", default-features = false } runtime_io = { package = "sr-io", path = "../sr-io", default-features = false } -log = { version = "0.4", optional = true } -paste = { version = "0.1"} -rand = { version = "0.7.0", optional = true } -impl-trait-for-tuples = "0.1.1" +log = { version = "0.4.8", optional = true } +paste = "0.1.6" +rand = { version = "0.7.2", optional = true } +impl-trait-for-tuples = "0.1.2" [dev-dependencies] +serde_json = "1.0.40" primitive-types = "0.5.1" rand = "0.7.2" -serde_json = "1.0" substrate-offchain = { path = "../offchain" } [features] diff --git a/core/sr-sandbox/Cargo.toml b/core/sr-sandbox/Cargo.toml index 2185ab4adc..87b4e742a0 100755 --- a/core/sr-sandbox/Cargo.toml +++ b/core/sr-sandbox/Cargo.toml @@ -6,7 +6,7 @@ build = "build.rs" edition = "2018" [build-dependencies] -rustc_version = "0.2" +rustc_version = "0.2.3" [dependencies] wasmi = { version = "0.5.1", optional = true } @@ -15,8 +15,8 @@ rstd = { package = "sr-std", path = "../sr-std", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } [dev-dependencies] -wabt = "~0.7.4" -assert_matches = "1.1" +wabt = "0.9.2" +assert_matches = "1.3.0" [features] default = ["std"] diff --git a/core/sr-version/Cargo.toml b/core/sr-version/Cargo.toml index a83d1f6415..fcae97b4d2 100644 --- a/core/sr-version/Cargo.toml +++ b/core/sr-version/Cargo.toml @@ -5,9 +5,9 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -impl-serde = { version = "0.1", optional = true } -serde = { version = "1.0", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +impl-serde = { version = "0.2.1", optional = true } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.0.5", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../sr-std", default-features = false } sr-primitives = { path = "../sr-primitives", default-features = false } diff --git a/core/sr-version/src/lib.rs b/core/sr-version/src/lib.rs index f787d8dd7e..ca98f3c221 100644 --- a/core/sr-version/src/lib.rs +++ b/core/sr-version/src/lib.rs @@ -188,10 +188,10 @@ mod apis_serialize { seq.end() } - pub fn serialize_bytesref(apis: &&super::ApiId, ser: S) -> Result where + pub fn serialize_bytesref(&apis: &&super::ApiId, ser: S) -> Result where S: Serializer, { - bytes::serialize(*apis, ser) + bytes::serialize(apis, ser) } #[derive(Deserialize)] @@ -228,9 +228,8 @@ mod apis_serialize { pub fn deserialize_bytes<'de, D>(d: D) -> Result where D: de::Deserializer<'de> { - let bytes = bytes::deserialize_check_len(d, bytes::ExpectedLen::Exact(8))?; let mut arr = [0; 8]; - arr.copy_from_slice(&bytes); + bytes::deserialize_check_len(d, bytes::ExpectedLen::Exact(&mut arr[..]))?; Ok(arr) } } diff --git a/core/state-db/Cargo.toml b/core/state-db/Cargo.toml index 332751c927..86298ae909 100644 --- a/core/state-db/Cargo.toml +++ b/core/state-db/Cargo.toml @@ -6,9 +6,9 @@ edition = "2018" [dependencies] parking_lot = "0.9.0" -log = "0.4" +log = "0.4.8" primitives = { package = "substrate-primitives", path = "../../core/primitives" } codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } [dev-dependencies] -env_logger = "0.6" +env_logger = "0.6.2" diff --git a/core/state-machine/Cargo.toml b/core/state-machine/Cargo.toml index d9fb592bab..914fa04db8 100644 --- a/core/state-machine/Cargo.toml +++ b/core/state-machine/Cargo.toml @@ -6,7 +6,7 @@ description = "Substrate State Machine" edition = "2018" [dependencies] -log = "0.4" +log = "0.4.8" parking_lot = "0.9.0" hash-db = "0.15.2" trie-db = "0.15.2" @@ -15,11 +15,11 @@ trie = { package = "substrate-trie", path = "../trie" } primitives = { package = "substrate-primitives", path = "../primitives" } panic-handler = { package = "substrate-panic-handler", path = "../panic-handler" } codec = { package = "parity-scale-codec", version = "1.0.0" } -num-traits = "0.2" -rand = "0.7.1" +num-traits = "0.2.8" +rand = "0.7.2" [dev-dependencies] -hex-literal = "0.2.0" +hex-literal = "0.2.1" [features] default = [] diff --git a/core/telemetry/Cargo.toml b/core/telemetry/Cargo.toml index 2dcb394f0e..90150ad749 100644 --- a/core/telemetry/Cargo.toml +++ b/core/telemetry/Cargo.toml @@ -6,20 +6,20 @@ description = "Telemetry utils" edition = "2018" [dependencies] -bytes = "0.4" +bytes = "0.4.12" parking_lot = "0.9.0" futures01 = { package = "futures", version = "0.1" } -futures-preview = { version = "0.3.0-alpha.18", features = ["compat"] } -futures-timer = "0.3" +futures-preview = { version = "0.3.0-alpha.19", features = ["compat"] } +futures-timer = "0.4.0" libp2p = { version = "0.12.0", default-features = false, features = ["libp2p-websocket"] } -log = "0.4" -rand = "0.6" -serde = { version = "1.0.81", features = ["derive"] } -slog = { version = "^2", features = ["nested-values"] } +log = "0.4.8" +rand = "0.7.2" +serde = { version = "1.0.101", features = ["derive"] } +slog = { version = "2.5.2", features = ["nested-values"] } # TODO: we're using slog-async just to be able to clone records; See https://github.com/slog-rs/slog/issues/221, # https://github.com/paritytech/substrate/issues/2823 and https://github.com/paritytech/substrate/issues/3260 slog-async = { git = "https://github.com/paritytech/slog-async", features = ["nested-values"] } -slog-json = { version = "^2", features = ["nested-values"] } -slog-scope = "^4" -tokio-io = "0.1" -void = "1.0" +slog-json = { version = "2.3.0", features = ["nested-values"] } +slog-scope = "4.1.2" +tokio-io = "0.1.12" +void = "1.0.2" diff --git a/core/test-client/Cargo.toml b/core/test-client/Cargo.toml index 1281bd07d0..de13b34d69 100644 --- a/core/test-client/Cargo.toml +++ b/core/test-client/Cargo.toml @@ -9,7 +9,7 @@ client = { package = "substrate-client", path = "../client" } client-db = { package = "substrate-client-db", path = "../client/db", features = ["test-helpers"] } consensus = { package = "substrate-consensus-common", path = "../consensus/common" } executor = { package = "substrate-executor", path = "../executor" } -futures-preview = "0.3.0-alpha.18" +futures-preview = "0.3.0-alpha.19" hash-db = "0.15.2" keyring = { package = "substrate-keyring", path = "../keyring" } codec = { package = "parity-scale-codec", version = "1.0.0" } diff --git a/core/test-runtime/Cargo.toml b/core/test-runtime/Cargo.toml index 2f66d4471f..313db0fd07 100644 --- a/core/test-runtime/Cargo.toml +++ b/core/test-runtime/Cargo.toml @@ -6,8 +6,8 @@ edition = "2018" build = "build.rs" [dependencies] -log = { version = "0.4", optional = true } -serde = { version = "1.0", optional = true, features = ["derive"] } +log = { version = "0.4.8", optional = true } +serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } keyring = { package = "substrate-keyring", path = "../keyring", optional = true } substrate-client = { path = "../client", default-features = false } @@ -27,7 +27,7 @@ trie-db = { version = "0.15.2", default-features = false } memory-db = { version = "0.15.2", default-features = false } offchain-primitives = { package = "substrate-offchain-primitives", path = "../offchain/primitives", default-features = false} executive = { package = "srml-executive", path = "../../srml/executive", default-features = false } -cfg-if = "0.1.6" +cfg-if = "0.1.10" srml-babe = { path = "../../srml/babe", default-features = false } srml-timestamp = { path = "../../srml/timestamp", default-features = false } srml-system = { path = "../../srml/system", default-features = false } diff --git a/core/transaction-pool/Cargo.toml b/core/transaction-pool/Cargo.toml index e55070f06e..33ec9e9ece 100644 --- a/core/transaction-pool/Cargo.toml +++ b/core/transaction-pool/Cargo.toml @@ -5,9 +5,9 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -derive_more = "0.14.0" -futures-preview = "=0.3.0-alpha.18" -log = "0.4" +derive_more = "0.15.0" +log = "0.4.8" +futures-preview = "0.3.0-alpha.19" codec = { package = "parity-scale-codec", version = "1.0.0" } parking_lot = "0.9.0" sr-primitives = { path = "../sr-primitives" } diff --git a/core/transaction-pool/graph/Cargo.toml b/core/transaction-pool/graph/Cargo.toml index 2e15e2ac25..d99291476e 100644 --- a/core/transaction-pool/graph/Cargo.toml +++ b/core/transaction-pool/graph/Cargo.toml @@ -5,16 +5,16 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -derive_more = "0.14.0" -futures-preview = "0.3.0-alpha.18" -log = "0.4" +derive_more = "0.15.0" +futures-preview = "0.3.0-alpha.19" +log = "0.4.8" parking_lot = "0.9.0" -serde = { version = "1.0", features = ["derive"] } +serde = { version = "1.0.101", features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../primitives" } sr-primitives = { path = "../../sr-primitives" } [dev-dependencies] assert_matches = "1.3.0" -env_logger = "0.6.1" +env_logger = "0.6.2" codec = { package = "parity-scale-codec", version = "1.0.0" } test_runtime = { package = "substrate-test-runtime", path = "../../test-runtime" } diff --git a/core/trie/Cargo.toml b/core/trie/Cargo.toml index 16849d9715..50498a17ba 100644 --- a/core/trie/Cargo.toml +++ b/core/trie/Cargo.toml @@ -3,7 +3,7 @@ name = "substrate-trie" version = "2.0.0" authors = ["Parity Technologies "] description = "Patricia trie stuff using a parity-scale-codec node format" -repository = "https://github.com/paritytech/parity-common" +repository = "https://github.com/paritytech/substrate" license = "GPL-3.0" edition = "2018" @@ -21,11 +21,11 @@ memory-db = { version = "0.15.2", default-features = false } primitives = { package = "substrate-primitives", path = "../primitives", default-features = false } [dev-dependencies] -trie-bench = { version = "0.16.2" } -trie-standardmap = { version = "0.15.2" } -keccak-hasher = { version = "0.15.2" } -criterion = "0.2" -hex-literal = "0.2.0" +trie-bench = "0.16.2" +trie-standardmap = "0.15.2" +keccak-hasher = "0.15.2" +criterion = "0.2.11" +hex-literal = "0.2.1" [features] default = ["std"] diff --git a/core/utils/wasm-builder/Cargo.toml b/core/utils/wasm-builder/Cargo.toml index b74877a5d4..bbcfe2ff52 100644 --- a/core/utils/wasm-builder/Cargo.toml +++ b/core/utils/wasm-builder/Cargo.toml @@ -10,7 +10,7 @@ license = "GPL-3.0" [dependencies] build-helper = "0.1.1" -cargo_metadata = "0.8" +cargo_metadata = "0.8.2" tempfile = "3.1.0" toml = "0.5.3" walkdir = "2.2.9" diff --git a/core/wasm-interface/Cargo.toml b/core/wasm-interface/Cargo.toml index c388b32930..b8169031d0 100644 --- a/core/wasm-interface/Cargo.toml +++ b/core/wasm-interface/Cargo.toml @@ -5,4 +5,4 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -wasmi = "0.5.0" +wasmi = "0.5.1" diff --git a/node-template/Cargo.toml b/node-template/Cargo.toml index 93b1abe79a..2aa305486c 100644 --- a/node-template/Cargo.toml +++ b/node-template/Cargo.toml @@ -10,12 +10,12 @@ name = "node-template" path = "src/main.rs" [dependencies] -derive_more = "0.14.0" -futures = "0.1" -ctrlc = { version = "3.0", features = ["termination"] } -log = "0.4" -tokio = "0.1" -exit-future = "0.1" +derive_more = "0.15.0" +futures = "0.1.29" +ctrlc = { version = "3.1.3", features = ["termination"] } +log = "0.4.8" +tokio = "0.1.22" +exit-future = "0.1.4" parking_lot = "0.9.0" codec = { package = "parity-scale-codec", version = "1.0.0" } trie-root = "0.15.2" @@ -36,4 +36,4 @@ basic-authorship = { package = "substrate-basic-authorship", path = "../core/bas node-template-runtime = { path = "runtime" } [build-dependencies] -vergen = "3" +vergen = "3.0.4" diff --git a/node-template/runtime/Cargo.toml b/node-template/runtime/Cargo.toml index 44545d5780..18948d503c 100644 --- a/node-template/runtime/Cargo.toml +++ b/node-template/runtime/Cargo.toml @@ -5,8 +5,8 @@ authors = ["Anonymous"] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true, features = ["derive"] } -safe-mix = { version = "1.0", default-features = false } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default_features = false } runtime-io = { package = "sr-io", path = "../../core/sr-io", default_features = false } diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index 86c7200560..ca3ec92630 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -7,10 +7,10 @@ build = "build.rs" edition = "2018" [dependencies] -log = "0.4" -tokio = "0.1.7" -futures = "0.1" -exit-future = "0.1" +log = "0.4.8" +tokio = "0.1.22" +futures = "0.1.29" +exit-future = "0.1.4" jsonrpc-core = "13.2.0" cli = { package = "substrate-cli", path = "../../core/cli" } codec = { package = "parity-scale-codec", version = "1.0.0" } @@ -21,7 +21,7 @@ inherents = { package = "substrate-inherents", path = "../../core/inherents" } node-runtime = { path = "../runtime" } node-rpc = { path = "../rpc" } node-primitives = { path = "../primitives" } -hex-literal = "0.2" +hex-literal = "0.2.1" substrate-rpc = { package = "substrate-rpc", path = "../../core/rpc" } substrate-basic-authorship = { path = "../../core/basic-authorship" } substrate-service = { path = "../../core/service" } @@ -35,12 +35,12 @@ grandpa_primitives = { package = "substrate-finality-grandpa-primitives", path = sr-primitives = { path = "../../core/sr-primitives" } node-executor = { path = "../executor" } substrate-telemetry = { package = "substrate-telemetry", path = "../../core/telemetry" } -structopt = "0.2" +structopt = "0.2.0" transaction-factory = { path = "../../test-utils/transaction-factory" } keyring = { package = "substrate-keyring", path = "../../core/keyring" } indices = { package = "srml-indices", path = "../../srml/indices" } timestamp = { package = "srml-timestamp", path = "../../srml/timestamp", default-features = false } -rand = "0.6" +rand = "0.7.2" finality_tracker = { package = "srml-finality-tracker", path = "../../srml/finality-tracker", default-features = false } contracts = { package = "srml-contracts", path = "../../srml/contracts" } system = { package = "srml-system", path = "../../srml/system" } @@ -49,7 +49,7 @@ support = { package = "srml-support", path = "../../srml/support", default-featu im_online = { package = "srml-im-online", path = "../../srml/im-online", default-features = false } sr-authority-discovery = { package = "srml-authority-discovery", path = "../../srml/authority-discovery", default-features = false } authority-discovery = { package = "substrate-authority-discovery", path = "../../core/authority-discovery"} -serde = { version = "1.0", features = [ "derive" ] } +serde = { version = "1.0.101", features = [ "derive" ] } client_db = { package = "substrate-client-db", path = "../../core/client/db", features = ["kvdb-rocksdb"] } offchain = { package = "substrate-offchain", path = "../../core/offchain" } @@ -58,9 +58,9 @@ keystore = { package = "substrate-keystore", path = "../../core/keystore" } babe = { package = "substrate-consensus-babe", path = "../../core/consensus/babe", features = ["test-helpers"] } consensus-common = { package = "substrate-consensus-common", path = "../../core/consensus/common" } service-test = { package = "substrate-service-test", path = "../../core/service/test" } -futures03 = { package = "futures-preview", version = "0.3.0-alpha.18" } -tempfile = "3.1" +futures03 = { package = "futures-preview", version = "0.3.0-alpha.19" } +tempfile = "3.1.0" [build-dependencies] cli = { package = "substrate-cli", path = "../../core/cli" } -structopt = "0.2" +structopt = "0.2.0" diff --git a/node/executor/Cargo.toml b/node/executor/Cargo.toml index a9ff25890e..63f1c8c0f4 100644 --- a/node/executor/Cargo.toml +++ b/node/executor/Cargo.toml @@ -29,7 +29,7 @@ treasury = { package = "srml-treasury", path = "../../srml/treasury" } contracts = { package = "srml-contracts", path = "../../srml/contracts" } grandpa = { package = "srml-grandpa", path = "../../srml/grandpa" } indices = { package = "srml-indices", path = "../../srml/indices" } -wabt = "~0.7.4" +wabt = "0.9.2" [features] benchmarks = [] diff --git a/node/primitives/Cargo.toml b/node/primitives/Cargo.toml index 248713a888..266720b024 100644 --- a/node/primitives/Cargo.toml +++ b/node/primitives/Cargo.toml @@ -9,7 +9,7 @@ client = { package = "substrate-client", path = "../../core/client", default-fea codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -serde = { version = "1.0", optional = true, features = ["derive"] } +serde = { version = "1.0.101", optional = true, features = ["derive"] } sr-primitives = { path = "../../core/sr-primitives", default-features = false } [dev-dependencies] diff --git a/node/rpc-client/Cargo.toml b/node/rpc-client/Cargo.toml index b98df224df..7dca144886 100644 --- a/node/rpc-client/Cargo.toml +++ b/node/rpc-client/Cargo.toml @@ -5,10 +5,10 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -env_logger = "0.6" -futures = "0.1.26" -hyper = "0.12" +env_logger = "0.6.2" +futures = "0.1.29" +hyper = "0.12.35" jsonrpc-core-client = { version = "13.1.0", features = ["http", "ws"] } -log = "0.4" +log = "0.4.8" node-primitives = { path = "../primitives" } substrate-rpc = { path = "../../core/rpc", version = "2.0.0" } diff --git a/node/rpc/Cargo.toml b/node/rpc/Cargo.toml index c2cee10b3a..6bec6adb6f 100644 --- a/node/rpc/Cargo.toml +++ b/node/rpc/Cargo.toml @@ -11,10 +11,10 @@ jsonrpc-core-client = "13.2.0" jsonrpc-derive = "13.2.0" jsonrpc-pubsub = "13.2.0" keyring = { package = "substrate-keyring", path = "../../core/keyring" } -log = "0.4" +log = "0.4.8" node-primitives = { path = "../primitives" } codec = { package = "parity-scale-codec", version = "1.0.0" } -serde = { version = "1.0", features = ["derive"] } +serde = { version = "1.0.101", features = ["derive"] } sr-primitives = { path = "../../core/sr-primitives" } substrate-primitives = { path = "../../core/primitives" } rpc-primitives = { package = "substrate-rpc-primitives", path = "../../core/rpc/primitives" } @@ -23,5 +23,5 @@ transaction_pool = { package = "substrate-transaction-pool", path = "../../core/ [dev-dependencies] node-testing = { path = "../testing" } node-runtime = { path = "../runtime" } -env_logger = "0.6" -futures03 = { package = "futures-preview", version = "=0.3.0-alpha.18" } +env_logger = "0.6.2" +futures03 = { package = "futures-preview", version = "=0.3.0-alpha.19" } diff --git a/node/runtime/Cargo.toml b/node/runtime/Cargo.toml index 8b1f775cea..9b794130e7 100644 --- a/node/runtime/Cargo.toml +++ b/node/runtime/Cargo.toml @@ -10,7 +10,7 @@ codec = { package = "parity-scale-codec", version = "1.0.0", default-features = integer-sqrt = { version = "0.1.2" } rustc-hex = { version = "2.0", optional = true } safe-mix = { version = "1.0", default-features = false } -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } authority-discovery-primitives = { package = "substrate-authority-discovery-primitives", path = "../../core/authority-discovery/primitives", default-features = false } babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../core/consensus/babe/primitives", default-features = false } diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index f4f71e37f3..82ffe5390f 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -84,8 +84,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 169, - impl_version: 169, + spec_version: 170, + impl_version: 170, apis: RUNTIME_API_VERSIONS, }; diff --git a/node/testing/Cargo.toml b/node/testing/Cargo.toml index 7f473d1be9..e622e35d4a 100644 --- a/node/testing/Cargo.toml +++ b/node/testing/Cargo.toml @@ -27,4 +27,4 @@ system = { package = "srml-system", path = "../../srml/system" } test-client = { package = "substrate-test-client", path = "../../core/test-client" } timestamp = { package = "srml-timestamp", path = "../../srml/timestamp" } treasury = { package = "srml-treasury", path = "../../srml/treasury" } -wabt = "~0.7.4" +wabt = "0.9.2" diff --git a/srml/assets/Cargo.toml b/srml/assets/Cargo.toml index ea5973254e..5f22ab3ba3 100644 --- a/srml/assets/Cargo.toml +++ b/srml/assets/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } # Needed for various traits. In our case, `OnFinalize`. sr-primitives = { path = "../../core/sr-primitives", default-features = false } @@ -27,4 +27,5 @@ std = [ "sr-primitives/std", "support/std", "system/std", + "runtime-io/std", ] diff --git a/srml/aura/Cargo.toml b/srml/aura/Cargo.toml index d7d6f8c9cf..f1c37b7c08 100644 --- a/srml/aura/Cargo.toml +++ b/srml/aura/Cargo.toml @@ -10,7 +10,7 @@ codec = { package = "parity-scale-codec", version = "1.0.0", default-features = inherents = { package = "substrate-inherents", path = "../../core/inherents", default-features = false } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } session = { package = "srml-session", path = "../session", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } @@ -20,7 +20,7 @@ system = { package = "srml-system", path = "../system", default-features = false timestamp = { package = "srml-timestamp", path = "../timestamp", default-features = false } [dev-dependencies] -lazy_static = "1.0" +lazy_static = "1.4.0" parking_lot = "0.9.0" [features] diff --git a/srml/authority-discovery/Cargo.toml b/srml/authority-discovery/Cargo.toml index e9647984ed..3968ab52ae 100644 --- a/srml/authority-discovery/Cargo.toml +++ b/srml/authority-discovery/Cargo.toml @@ -9,8 +9,8 @@ app-crypto = { package = "substrate-application-crypto", path = "../../core/appl codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } +serde = { version = "1.0.101", optional = true } runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } -serde = { version = "1.0", optional = true } session = { package = "srml-session", path = "../session", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } diff --git a/srml/authorship/Cargo.toml b/srml/authorship/Cargo.toml index 03c7fb9d07..e860be2f64 100644 --- a/srml/authorship/Cargo.toml +++ b/srml/authorship/Cargo.toml @@ -14,7 +14,7 @@ sr-primitives = { path = "../../core/sr-primitives", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } -impl-trait-for-tuples = "0.1.1" +impl-trait-for-tuples = "0.1.2" [features] default = ["std"] diff --git a/srml/babe/Cargo.toml b/srml/babe/Cargo.toml index 1cce838685..dc82906650 100644 --- a/srml/babe/Cargo.toml +++ b/srml/babe/Cargo.toml @@ -5,9 +5,9 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -hex-literal = "0.2" +hex-literal = "0.2.1" codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.93", optional = true } +serde = { version = "1.0.101", optional = true } inherents = { package = "substrate-inherents", path = "../../core/inherents", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } @@ -20,7 +20,7 @@ babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../ runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } [dev-dependencies] -lazy_static = "1.3.0" +lazy_static = "1.4.0" parking_lot = "0.9.0" sr-version = { path = "../../core/sr-version", default-features = false } primitives = { package = "substrate-primitives", path = "../../core/primitives" } diff --git a/srml/babe/src/lib.rs b/srml/babe/src/lib.rs index a410eccda8..330ec89ba5 100644 --- a/srml/babe/src/lib.rs +++ b/srml/babe/src/lib.rs @@ -391,7 +391,7 @@ impl Module { debug_assert_ne!(GenesisSlot::get(), 0); // deposit a log because this is the first block in epoch #0 - // we use the same values as genesis because we haven't collected any + // we use the same values as genesis because we haven't collected any // randomness yet. let next = NextEpochDescriptor { authorities: Self::authorities(), diff --git a/srml/balances/Cargo.toml b/srml/balances/Cargo.toml index ca885de678..d2b6e00d98 100644 --- a/srml/balances/Cargo.toml +++ b/srml/balances/Cargo.toml @@ -5,8 +5,8 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } -safe-mix = { version = "1.0", default-features = false} +serde = { version = "1.0.101", optional = true } +safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } substrate-keyring = { path = "../../core/keyring", optional = true } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } @@ -15,7 +15,7 @@ support = { package = "srml-support", path = "../support", default-features = fa system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] -runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } [features] diff --git a/srml/collective/Cargo.toml b/srml/collective/Cargo.toml index dce2920a12..347a289b57 100644 --- a/srml/collective/Cargo.toml +++ b/srml/collective/Cargo.toml @@ -5,18 +5,18 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } -safe-mix = { version = "1.0", default-features = false} +serde = { version = "1.0.101", optional = true } +safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] -hex-literal = "0.2.0" +hex-literal = "0.2.1" balances = { package = "srml-balances", path = "../balances" } [features] diff --git a/srml/contracts/Cargo.toml b/srml/contracts/Cargo.toml index 646dcd8b5b..f076f5feda 100644 --- a/srml/contracts/Cargo.toml +++ b/srml/contracts/Cargo.toml @@ -5,11 +5,11 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true, features = ["derive"] } +serde = { version = "1.0.101", optional = true, features = ["derive"] } pwasm-utils = { version = "0.11.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -parity-wasm = { version = "0.40", default-features = false } -wasmi-validation = { version = "0.2", default-features = false } +parity-wasm = { version = "0.40.3", default-features = false } +wasmi-validation = { version = "0.2.0", default-features = false } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } @@ -19,12 +19,12 @@ support = { package = "srml-support", path = "../support", default-features = fa system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] -wabt = "~0.7.4" -assert_matches = "1.1" -hex-literal = "0.2.0" +wabt = "0.9.2" +assert_matches = "1.3.0" +hex-literal = "0.2.1" balances = { package = "srml-balances", path = "../balances" } +hex = "0.3.2" timestamp = { package = "srml-timestamp", path = "../timestamp" } -hex = "0.3" [features] default = ["std"] diff --git a/srml/democracy/Cargo.toml b/srml/democracy/Cargo.toml index 22f091e4d3..761e56ceda 100644 --- a/srml/democracy/Cargo.toml +++ b/srml/democracy/Cargo.toml @@ -5,11 +5,11 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true, features = ["derive"] } -safe-mix = { version = "1.0", default-features = false} +serde = { version = "1.0.101", optional = true, features = ["derive"] } +safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } diff --git a/srml/elections-phragmen/Cargo.toml b/srml/elections-phragmen/Cargo.toml index 0faa429d75..02898fc754 100644 --- a/srml/elections-phragmen/Cargo.toml +++ b/srml/elections-phragmen/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } @@ -16,7 +16,7 @@ system = { package = "srml-system", path = "../system", default-features = false rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } [dev-dependencies] -hex-literal = "0.2.0" +hex-literal = "0.2.1" balances = { package = "srml-balances", path = "../balances" } [features] diff --git a/srml/elections/Cargo.toml b/srml/elections/Cargo.toml index d479906737..88d147ac08 100644 --- a/srml/elections/Cargo.toml +++ b/srml/elections/Cargo.toml @@ -5,18 +5,18 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } -safe-mix = { version = "1.0", default-features = false} +serde = { version = "1.0.101", optional = true } +safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] -hex-literal = "0.2.0" +hex-literal = "0.2.1" balances = { package = "srml-balances", path = "../balances" } [features] diff --git a/srml/example/Cargo.toml b/srml/example/Cargo.toml index 30addfa727..695e0602fb 100644 --- a/srml/example/Cargo.toml +++ b/srml/example/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } diff --git a/srml/executive/Cargo.toml b/srml/executive/Cargo.toml index c937855148..a87eed40b7 100644 --- a/srml/executive/Cargo.toml +++ b/srml/executive/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } @@ -14,7 +14,7 @@ support = { package = "srml-support", path = "../support", default-features = fa system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] -hex-literal = "0.2.0" +hex-literal = "0.2.1" primitives = { package = "substrate-primitives", path = "../../core/primitives" } srml-indices = { path = "../indices" } balances = { package = "srml-balances", path = "../balances" } diff --git a/srml/finality-tracker/Cargo.toml b/srml/finality-tracker/Cargo.toml index 6e9cf12f74..7e3439e0fe 100644 --- a/srml/finality-tracker/Cargo.toml +++ b/srml/finality-tracker/Cargo.toml @@ -5,14 +5,14 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", default-features = false, features = ["derive"] } +serde = { version = "1.0.101", default-features = false, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } inherents = { package = "substrate-inherents", path = "../../core/inherents", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } srml-system = { path = "../system", default-features = false } -impl-trait-for-tuples = "0.1.1" +impl-trait-for-tuples = "0.1.2" [dev-dependencies] primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } diff --git a/srml/generic-asset/Cargo.toml b/srml/generic-asset/Cargo.toml index cfe170dd7d..49a9db4c0e 100644 --- a/srml/generic-asset/Cargo.toml +++ b/srml/generic-asset/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Centrality Developers "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } diff --git a/srml/grandpa/Cargo.toml b/srml/grandpa/Cargo.toml index 344139db20..4b494cfeff 100644 --- a/srml/grandpa/Cargo.toml +++ b/srml/grandpa/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true, features = ["derive"] } +serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } substrate-finality-grandpa-primitives = { path = "../../core/finality-grandpa/primitives", default-features = false } diff --git a/srml/im-online/Cargo.toml b/srml/im-online/Cargo.toml index 9dc44f38ba..b62cc2a8f9 100644 --- a/srml/im-online/Cargo.toml +++ b/srml/im-online/Cargo.toml @@ -9,7 +9,7 @@ app-crypto = { package = "substrate-application-crypto", path = "../../core/appl codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package="substrate-primitives", path = "../../core/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } session = { package = "srml-session", path = "../session", default-features = false } runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } diff --git a/srml/indices/Cargo.toml b/srml/indices/Cargo.toml index 31fea3cd01..b8b560c3f9 100644 --- a/srml/indices/Cargo.toml +++ b/srml/indices/Cargo.toml @@ -5,8 +5,8 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } -safe-mix = { version = "1.0", default-features = false} +serde = { version = "1.0.101", optional = true } +safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } substrate-keyring = { path = "../../core/keyring", optional = true } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } @@ -17,7 +17,7 @@ support = { package = "srml-support", path = "../support", default-features = fa system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] -ref_thread_local = "0.0" +ref_thread_local = "0.0.0" [features] default = ["std"] diff --git a/srml/membership/Cargo.toml b/srml/membership/Cargo.toml index 3e822ff8ac..a8cb730555 100644 --- a/srml/membership/Cargo.toml +++ b/srml/membership/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } diff --git a/srml/metadata/Cargo.toml b/srml/metadata/Cargo.toml index 9fc9c6e46d..e9381f68bb 100644 --- a/srml/metadata/Cargo.toml +++ b/srml/metadata/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -serde = { version = "1.0", optional = true, features = ["derive"] } +serde = { version = "1.0.101", optional = true, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } diff --git a/srml/offences/Cargo.toml b/srml/offences/Cargo.toml index 39ca0f785e..90a3396d11 100644 --- a/srml/offences/Cargo.toml +++ b/srml/offences/Cargo.toml @@ -8,14 +8,14 @@ edition = "2018" balances = { package = "srml-balances", path = "../balances", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } sr-primitives = { path = "../../core/sr-primitives", default-features = false } sr-staking-primitives = { path = "../../core/sr-staking-primitives", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } [dev-dependencies] -runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io" } substrate-primitives = { path = "../../core/primitives" } [features] diff --git a/srml/scored-pool/Cargo.toml b/srml/scored-pool/Cargo.toml index 77d614fc7e..e65f71a10d 100644 --- a/srml/scored-pool/Cargo.toml +++ b/srml/scored-pool/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } diff --git a/srml/session/Cargo.toml b/srml/session/Cargo.toml index cd58095815..b114755ad9 100644 --- a/srml/session/Cargo.toml +++ b/srml/session/Cargo.toml @@ -5,8 +5,8 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } -safe-mix = { version = "1.0", default-features = false} +serde = { version = "1.0.101", optional = true } +safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } @@ -16,12 +16,12 @@ system = { package = "srml-system", path = "../system", default-features = false timestamp = { package = "srml-timestamp", path = "../timestamp", default-features = false } substrate-trie = { path = "../../core/trie", default-features = false, optional = true } runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false } -impl-trait-for-tuples = "0.1.1" +impl-trait-for-tuples = "0.1.2" [dev-dependencies] primitives = { package = "substrate-primitives", path = "../../core/primitives" } app-crypto = { package = "substrate-application-crypto", path = "../../core/application-crypto" } -lazy_static = "1.0" +lazy_static = "1.4.0" [features] default = ["std", "historical"] @@ -35,5 +35,6 @@ std = [ "sr-primitives/std", "sr-staking-primitives/std", "timestamp/std", - "substrate-trie/std" + "substrate-trie/std", + "runtime-io/std", ] diff --git a/srml/staking/Cargo.toml b/srml/staking/Cargo.toml index 3700d84c09..67f3ab41d6 100644 --- a/srml/staking/Cargo.toml +++ b/srml/staking/Cargo.toml @@ -5,8 +5,8 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } -safe-mix = { version = "1.0", default-features = false} +serde = { version = "1.0.101", optional = true } +safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } substrate-keyring = { path = "../../core/keyring", optional = true } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } diff --git a/srml/staking/reward-curve/Cargo.toml b/srml/staking/reward-curve/Cargo.toml index 19deeae72e..4fb0ab1672 100644 --- a/srml/staking/reward-curve/Cargo.toml +++ b/srml/staking/reward-curve/Cargo.toml @@ -10,8 +10,8 @@ proc-macro = true [dependencies] syn = { version = "1.0", features = [ "full", "visit" ] } quote = "1.0" -proc-macro2 = "1.0" -proc-macro-crate = "0.1.3" +proc-macro2 = "1.0.4" +proc-macro-crate = "0.1.4" [dev-dependencies] sr-primitives = { path = "../../../core/sr-primitives" } diff --git a/srml/staking/reward-curve/src/log.rs b/srml/staking/reward-curve/src/log.rs index 1079591a6c..1a25dbb986 100644 --- a/srml/staking/reward-curve/src/log.rs +++ b/srml/staking/reward-curve/src/log.rs @@ -28,7 +28,7 @@ pub fn log2(p: u32, q: u32) -> u32 { if k == 0 { (_2_div_ln_2 as u128 * (y_num as u128).pow(1) / (y_den as u128).pow(1)) .try_into().unwrap() - } else { + } else { let mut res = _2_div_ln_2 as u128 * (y_num as u128).pow(3) / (y_den as u128).pow(3); for _ in 1..k { res = res * (y_num as u128).pow(2) / (y_den as u128).pow(2); diff --git a/srml/sudo/Cargo.toml b/srml/sudo/Cargo.toml index 6dad983d06..152f32ab89 100644 --- a/srml/sudo/Cargo.toml +++ b/srml/sudo/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } diff --git a/srml/support/Cargo.toml b/srml/support/Cargo.toml index 2acf9f5fe3..79a3beb6dc 100644 --- a/srml/support/Cargo.toml +++ b/srml/support/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true, features = ["derive"] } +serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.6", default-features = false, features = ["derive"] } srml-metadata = { path = "../metadata", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } @@ -14,10 +14,10 @@ sr-primitives = { path = "../../core/sr-primitives", default-features = false } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } inherents = { package = "substrate-inherents", path = "../../core/inherents", default-features = false } srml-support-procedural = { package = "srml-support-procedural", path = "./procedural" } -paste = "0.1" -once_cell = { version = "0.1.6", default-features = false, optional = true } -bitmask = { version = "0.5", default-features = false } -impl-trait-for-tuples = "0.1.1" +paste = "0.1.6" +once_cell = { version = "0.2.4", default-features = false, optional = true } +bitmask = { version = "0.5.0", default-features = false } +impl-trait-for-tuples = "0.1.2" [dev-dependencies] pretty_assertions = "0.6.1" diff --git a/srml/support/procedural/Cargo.toml b/srml/support/procedural/Cargo.toml index cb719583e2..91b4ca5074 100644 --- a/srml/support/procedural/Cargo.toml +++ b/srml/support/procedural/Cargo.toml @@ -12,5 +12,5 @@ srml-support-procedural-tools = { package = "srml-support-procedural-tools", pat sr-api-macros = { path = "../../../core/sr-api-macros" } proc-macro2 = "0.4.27" -quote = { version = "0.6.12" } -syn = { version = "0.15.32", features = ["full"] } +quote = "0.6.12" +syn = { version = "0.15.44", features = ["full"] } diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index 76fff30bd3..c6a3a1f668 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -1087,7 +1087,9 @@ fn store_functions_to_metadata ( #[cfg(feature = "std")] #[allow(non_upper_case_globals)] - static #cache_name: #scrate::once_cell::sync::OnceCell<#scrate::rstd::vec::Vec> = #scrate::once_cell::sync::OnceCell::INIT; + static #cache_name: #scrate::once_cell::sync::OnceCell< + #scrate::rstd::vec::Vec + > = #scrate::once_cell::sync::OnceCell::new(); #[cfg(feature = "std")] impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::metadata::DefaultByte diff --git a/srml/support/procedural/tools/Cargo.toml b/srml/support/procedural/tools/Cargo.toml index 037636a2a0..62c55a703f 100644 --- a/srml/support/procedural/tools/Cargo.toml +++ b/srml/support/procedural/tools/Cargo.toml @@ -7,6 +7,6 @@ edition = "2018" [dependencies] srml-support-procedural-tools-derive = { package = "srml-support-procedural-tools-derive", path = "./derive" } proc-macro2 = "0.4.27" -quote = { version = "0.6.12" } -syn = { version = "0.15.30", features = ["full"] } -proc-macro-crate = "0.1.3" +quote = "0.6.12" +syn = { version = "0.15.44", features = ["full"] } +proc-macro-crate = "0.1.4" diff --git a/srml/support/procedural/tools/derive/Cargo.toml b/srml/support/procedural/tools/derive/Cargo.toml index 2f7f35ff4a..54bfaba838 100644 --- a/srml/support/procedural/tools/derive/Cargo.toml +++ b/srml/support/procedural/tools/derive/Cargo.toml @@ -10,4 +10,4 @@ proc-macro = true [dependencies] proc-macro2 = "0.4.27" quote = { version = "0.6.12", features = ["proc-macro"] } -syn = { version = "0.15.30", features = ["proc-macro" ,"full", "extra-traits", "parsing"] } +syn = { version = "0.15.44", features = ["proc-macro" ,"full", "extra-traits", "parsing"] } diff --git a/srml/support/test/Cargo.toml b/srml/support/test/Cargo.toml index b0b21fb6a3..bb1b3749e9 100644 --- a/srml/support/test/Cargo.toml +++ b/srml/support/test/Cargo.toml @@ -5,13 +5,13 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", default-features = false, features = ["derive"] } +serde = { version = "1.0.101", default-features = false, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } runtime-io ={ package = "sr-io", path = "../../../core/sr-io", default-features = false } support = { package = "srml-support", version = "2", path = "../", default-features = false } inherents = { package = "substrate-inherents", path = "../../../core/inherents", default-features = false } primitives = { package = "substrate-primitives", path = "../../../core/primitives", default-features = false } -trybuild = "1" +trybuild = "1.0.14" pretty_assertions = "0.6.1" [features] diff --git a/srml/system/Cargo.toml b/srml/system/Cargo.toml index 344e59dd49..a9ce6b3f8c 100644 --- a/srml/system/Cargo.toml +++ b/srml/system/Cargo.toml @@ -5,8 +5,8 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true, features = ["derive"] } -safe-mix = { version = "1.0", default-features = false} +serde = { version = "1.0.101", optional = true, features = ["derive"] } +safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } @@ -14,10 +14,10 @@ runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = f sr-primitives = { path = "../../core/sr-primitives", default-features = false } sr-version = { path = "../../core/sr-version", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } -impl-trait-for-tuples = "0.1.1" +impl-trait-for-tuples = "0.1.2" [dev-dependencies] -criterion = "0.2" +criterion = "0.2.11" [features] default = ["std"] diff --git a/srml/timestamp/Cargo.toml b/srml/timestamp/Cargo.toml index 6a30ad69d0..939fb72566 100644 --- a/srml/timestamp/Cargo.toml +++ b/srml/timestamp/Cargo.toml @@ -5,14 +5,14 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } inherents = { package = "substrate-inherents", path = "../../core/inherents", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } -impl-trait-for-tuples = "0.1.1" +impl-trait-for-tuples = "0.1.2" [dev-dependencies] runtime-io ={ package = "sr-io", path = "../../core/sr-io" } diff --git a/srml/treasury/Cargo.toml b/srml/treasury/Cargo.toml index 55ea6aef95..f19fa2c218 100644 --- a/srml/treasury/Cargo.toml +++ b/srml/treasury/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true, features = ["derive"] } +serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } diff --git a/subkey/Cargo.toml b/subkey/Cargo.toml index 9e7112a029..1b1a697d0f 100644 --- a/subkey/Cargo.toml +++ b/subkey/Cargo.toml @@ -9,13 +9,13 @@ primitives = { package = "substrate-primitives", version = "*", path = "../core node-runtime = { version = "*", path = "../node/runtime" } node-primitives = { version = "*", path = "../node/primitives" } sr-primitives = { version = "*", path = "../core/sr-primitives" } -rand = "0.6" -clap = { version = "~2.32", features = ["yaml"] } -tiny-bip39 = "0.6.0" -rustc-hex = "2.0" +rand = "0.7.2" +clap = { version = "~2.32.0", features = ["yaml"] } +tiny-bip39 = "0.6.2" +rustc-hex = "2.0.1" substrate-bip39 = "0.3.1" -hex = "0.3" -hex-literal = "0.2" +hex = "0.3.2" +hex-literal = "0.2.1" codec = { package = "parity-scale-codec", version = "1.0.0" } system = { package = "srml-system", path = "../srml/system" } balances = { package = "srml-balances", path = "../srml/balances" } diff --git a/subkey/src/vanity.rs b/subkey/src/vanity.rs index ea30f7413e..b612bc470f 100644 --- a/subkey/src/vanity.rs +++ b/subkey/src/vanity.rs @@ -76,7 +76,7 @@ pub(super) fn generate_key(desired: &str) -> Result, &str> loop { if done % 100000 == 0 { - OsRng::new().unwrap().fill_bytes(seed.as_mut()); + OsRng.fill_bytes(seed.as_mut()); } else { next_seed(seed.as_mut()); } diff --git a/test-utils/chain-spec-builder/Cargo.lock b/test-utils/chain-spec-builder/Cargo.lock deleted file mode 100644 index afa92a46f8..0000000000 --- a/test-utils/chain-spec-builder/Cargo.lock +++ /dev/null @@ -1,5198 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "aes" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "aes-ctr" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "aes-soft" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "aesni" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "aho-corasick" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "aio-limited" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ansi_term" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "app_dirs" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "arrayref" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "arrayvec" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "asn1_der" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "asn1_der_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "asn1_der_derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "atty" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "autocfg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "backtrace" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "backtrace-sys" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "base-x" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "base58" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "base64" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "base64" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bigint" -version = "4.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bindgen" -version = "0.47.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cexpr 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "clang-sys 0.26.4 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bitflags" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bitmask" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "blake2" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "blake2-rfc" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "block-buffer" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "block-buffer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "block-buffer" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "block-cipher-trait" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "block-modes" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "block-padding" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bs58" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bstr" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bumpalo" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "byte-tools" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "byteorder" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "byteorder" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bytes" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "c_linked_list" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "cc" -version = "1.0.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cexpr" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cfg-if" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "chain-spec-builder" -version = "0.1.0" -dependencies = [ - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "node-cli 1.0.0", - "substrate-primitives 1.0.0", - "substrate-service 1.0.0", -] - -[[package]] -name = "chrono" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "clang-sys" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "clap" -version = "2.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "clear_on_drop" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "constant_time_eq" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "core-foundation" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "core-foundation-sys" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "crossbeam" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-channel" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-deque" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-deque" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-deque" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-queue" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-utils" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-utils" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crunchy" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "crypto-mac" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crypto-mac" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crypto-mac" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ctr" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cuckoofilter" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "curve25519-dalek" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "data-encoding" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "derive_more" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "digest" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "digest" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "digest" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "discard" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "dns-parser" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ed25519-dalek" -version = "1.0.0-pre.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "curve25519-dalek 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "either" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "elastic-array" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "env_logger" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "environmental" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "erased-serde" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "error-chain" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "exit-future" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "failure" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "failure_derive" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "fdlimit" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "finality-grandpa" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "hashmap_core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec-derive 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fixed-hash" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fnv" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "fork-tree" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fs-swap" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "futures" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "futures-cpupool" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "gcc" -version = "0.3.55" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "generic-array" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "generic-array" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "generic-array" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "get_if_addrs" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "c_linked_list 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "get_if_addrs-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "get_if_addrs-sys" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "glob" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "globset" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "bstr 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "h2" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hash-db" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "hash256-std-hasher" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hashbrown" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hashmap_core" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "heapsize" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "heck" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hex" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "hex-literal" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "hex-literal-impl 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hex-literal" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "hex-literal-impl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hex-literal-impl" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hex-literal-impl" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro-hack 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hmac" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crypto-mac 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hmac" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crypto-mac 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hmac" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hmac-drbg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "http" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "httparse" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "humantime" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hyper" -version = "0.10.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hyper" -version = "0.12.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "h2 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "idna" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "impl-codec" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "impl-serde" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "indexmap" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "integer-sqrt" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "interleaved-ordered" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "iovec" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "itoa" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "js-sys" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "wasm-bindgen 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "jsonrpc-core" -version = "10.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "jsonrpc-derive" -version = "10.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "jsonrpc-http-server" -version = "10.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "hyper 0.12.28 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "jsonrpc-pubsub" -version = "10.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "jsonrpc-core 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "jsonrpc-server-utils" -version = "10.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "globset 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "jsonrpc-ws-server" -version = "10.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-ws 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "keccak" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "kvdb" -version = "0.1.0" -source = "git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d#b0317f649ab2c665b7987b8475878fc4d2e1f81d" -dependencies = [ - "elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", -] - -[[package]] -name = "kvdb-rocksdb" -version = "0.1.4" -source = "git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d#b0317f649ab2c665b7987b8475878fc4d2e1f81d" -dependencies = [ - "elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rocksdb 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "language-tags" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "lazy_static" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "lazycell" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "libc" -version = "0.2.54" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "libloading" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core-derive 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-dns 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-floodsub 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-identify 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-kad 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-mdns 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-mplex 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-noise 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-ping 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-plaintext 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-ratelimit 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-secio 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-tcp 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-uds 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-websocket 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-yamux 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multihash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "stdweb 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-core" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "asn1_der 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "multistream-select 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multihash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rw-stream-sink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "secp256k1 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-core-derive" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-dns" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-dns-unofficial 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-floodsub" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "cuckoofilter 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-identify" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-kad" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "bigint 4.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multihash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-mdns" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "dns-parser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-mplex" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-noise" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "curve25519-dalek 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", - "snow 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-ping" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-plaintext" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-ratelimit" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aio-limited 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-secio" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "asn1_der 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rw-stream-sink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "secp256k1 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-futures 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-tcp" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "get_if_addrs 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tk-listen 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-uds" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-websocket" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rw-stream-sink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "stdweb 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "websocket 0.22.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libp2p-yamux" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "yamux 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "librocksdb-sys" -version = "5.18.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bindgen 0.47.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libsecp256k1" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac-drbg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "linked-hash-map" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "linked_hash_set" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "lock_api" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "log" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "log" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "lru-cache" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "matches" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "memchr" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "memoffset" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "memory-db" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hashmap_core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "memory_units" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "merlin" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "mime" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "mio" -version = "0.6.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "mio-extras" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "mio-uds" -version = "0.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "miow" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "multistream-select" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "names" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "native-tls" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.10.22 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.46 (registry+https://github.com/rust-lang/crates.io-index)", - "schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "net2" -version = "0.2.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "node-cli" -version = "1.0.0" -dependencies = [ - "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "node-executor 1.0.0", - "node-primitives 1.0.0", - "node-runtime 1.0.0", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-basic-authorship 1.0.0", - "substrate-cli 1.0.0", - "substrate-client 1.0.0", - "substrate-consensus-aura 1.1.0", - "substrate-finality-grandpa 1.0.0", - "substrate-inherents 1.0.0", - "substrate-keystore 1.0.0", - "substrate-network 0.1.0", - "substrate-primitives 1.0.0", - "substrate-service 1.0.0", - "substrate-telemetry 1.0.0", - "substrate-transaction-pool 1.0.0", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "node-executor" -version = "1.0.0" -dependencies = [ - "node-primitives 1.0.0", - "node-runtime 1.0.0", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "substrate-executor 1.0.0", - "substrate-primitives 1.0.0", - "substrate-state-machine 1.0.0", - "substrate-trie 1.0.0", - "trie-root 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "node-primitives" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "node-runtime" -version = "1.0.0" -dependencies = [ - "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "node-primitives 1.0.0", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "sr-version 1.0.0", - "srml-aura 1.0.0", - "srml-balances 1.0.0", - "srml-consensus 1.0.0", - "srml-contract 1.0.0", - "srml-council 1.0.0", - "srml-democracy 1.0.0", - "srml-executive 1.0.0", - "srml-finality-tracker 1.0.0", - "srml-grandpa 1.0.0", - "srml-indices 1.0.0", - "srml-session 1.0.0", - "srml-staking 1.0.0", - "srml-sudo 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "srml-timestamp 1.0.0", - "srml-treasury 1.0.0", - "substrate-client 1.0.0", - "substrate-consensus-aura-primitives 1.0.0", - "substrate-consensus-authorities 1.0.0", - "substrate-keyring 1.0.0", - "substrate-offchain-primitives 0.1.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "nodrop" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "nohash-hasher" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "nom" -version = "4.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-integer" -version = "0.1.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-traits" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "num_cpus" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "numtoa" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "ole32-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "once_cell" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "opaque-debug" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "openssl" -version = "0.10.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.46 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "openssl-probe" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "openssl-sys" -version = "0.9.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "owning_ref" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "owning_ref" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-bytes" -version = "0.1.0" -source = "git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d#b0317f649ab2c665b7987b8475878fc4d2e1f81d" - -[[package]] -name = "parity-codec" -version = "3.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec-derive 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-codec-derive" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro-crate 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-crypto" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aes 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "block-modes 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", - "ripemd160 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "scrypt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-multiaddr" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multihash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-multihash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "blake2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-wasm" -version = "0.31.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-ws" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parking_lot" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parking_lot" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parking_lot" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parking_lot_core" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parking_lot_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parking_lot_core" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "paste" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "paste-impl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "paste-impl" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro-hack 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "pbkdf2" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crypto-mac 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "pbkdf2" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "percent-encoding" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "pkg-config" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "primitive-types" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fixed-hash 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "uint 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "proc-macro-crate" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "proc-macro-hack" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "proc-macro-hack" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "proc-macro-hack-impl" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "proc-macro2" -version = "0.4.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "protobuf" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "pwasm-utils" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "quick-error" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "quick-error" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "quote" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_core" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_xorshift" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rayon" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rayon-core" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "redox_syscall" -version = "0.1.54" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "redox_termios" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "regex" -version = "1.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "regex-syntax" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "remove_dir_all" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ring" -version = "0.14.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ripemd160" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rocksdb" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "librocksdb-sys 5.18.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "rustc-hex" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rw-stream-sink" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ryu" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "safe-mix" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "safemem" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "schannel" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "schnorrkel" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "curve25519-dalek 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "merlin 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "scopeguard" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "scrypt" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "pbkdf2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "secp256k1" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "security-framework" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "security-framework-sys" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "send_wrapper" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "serde" -version = "1.0.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "serde_derive 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "serde_derive" -version = "1.0.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "serde_json" -version = "1.0.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sha-1" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sha1" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "sha2" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sha2" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", - "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sha2" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sha3" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "shell32-sys" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slab" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "slog" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slog-async" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slog-json" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slog-scope" -version = "4.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slog_derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "smallvec" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "snow" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "static_slice 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sourcefile" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "spin" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "sr-api-macros" -version = "1.0.0" -dependencies = [ - "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-crate 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sr-io" -version = "1.0.0" -dependencies = [ - "environmental 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 1.0.0", - "substrate-primitives 1.0.0", - "substrate-state-machine 1.0.0", - "substrate-trie 1.0.0", - "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sr-primitives" -version = "1.0.0" -dependencies = [ - "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-std 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "sr-sandbox" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 1.0.0", - "substrate-primitives 1.0.0", - "wasmi 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sr-std" -version = "1.0.0" -dependencies = [ - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sr-version" -version = "1.0.0" -dependencies = [ - "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", -] - -[[package]] -name = "srml-aura" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-session 1.0.0", - "srml-staking 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "srml-timestamp 1.0.0", - "substrate-inherents 1.0.0", -] - -[[package]] -name = "srml-balances" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "substrate-keyring 1.0.0", -] - -[[package]] -name = "srml-consensus" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "substrate-inherents 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "srml-contract" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", - "pwasm-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "sr-sandbox 1.0.0", - "sr-std 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "srml-timestamp 1.0.0", - "substrate-primitives 1.0.0", - "wasmi-validation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "srml-council" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-democracy 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "srml-democracy" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", -] - -[[package]] -name = "srml-executive" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", -] - -[[package]] -name = "srml-finality-tracker" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "substrate-inherents 1.0.0", -] - -[[package]] -name = "srml-grandpa" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-consensus 1.0.0", - "srml-finality-tracker 1.0.0", - "srml-session 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "substrate-finality-grandpa-primitives 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "srml-indices" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "substrate-keyring 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "srml-metadata" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "srml-session" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-consensus 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "srml-timestamp 1.0.0", -] - -[[package]] -name = "srml-staking" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-consensus 1.0.0", - "srml-session 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "substrate-keyring 1.0.0", -] - -[[package]] -name = "srml-sudo" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-support 1.0.0", - "srml-support-procedural 1.0.0", - "srml-system 1.0.0", -] - -[[package]] -name = "srml-support" -version = "1.0.0" -dependencies = [ - "bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-metadata 1.0.0", - "srml-support-procedural 1.0.0", - "substrate-inherents 1.0.0", -] - -[[package]] -name = "srml-support-procedural" -version = "1.0.0" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api-macros 1.0.0", - "srml-support-procedural-tools 1.0.0", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "srml-support-procedural-tools" -version = "1.0.0" -dependencies = [ - "proc-macro-crate 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "srml-support-procedural-tools-derive 1.0.0", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "srml-support-procedural-tools-derive" -version = "1.0.0" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "srml-system" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-support 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "srml-timestamp" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", - "substrate-inherents 1.0.0", -] - -[[package]] -name = "srml-treasury" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "srml-balances 1.0.0", - "srml-support 1.0.0", - "srml-system 1.0.0", -] - -[[package]] -name = "stable_deref_trait" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "static_assertions" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "static_slice" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "stdweb" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "discard 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "stdweb-derive 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "stdweb-internal-macros 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "stdweb-internal-runtime 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "stdweb-derive" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "stdweb-internal-macros" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "base-x 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "stdweb-internal-runtime" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "stream-cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "string" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "strsim" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "structopt" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt-derive 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "structopt-derive" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "strum" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "strum_macros" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-basic-authorship" -version = "1.0.0" -dependencies = [ - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "substrate-client 1.0.0", - "substrate-consensus-aura-primitives 1.0.0", - "substrate-consensus-common 1.0.0", - "substrate-inherents 1.0.0", - "substrate-primitives 1.0.0", - "substrate-telemetry 1.0.0", - "substrate-transaction-pool 1.0.0", -] - -[[package]] -name = "substrate-bip39" -version = "0.2.1" -source = "git+https://github.com/paritytech/substrate-bip39#44307fda4ea17fe97aeb93af317fbc8f6ed34193" -dependencies = [ - "hmac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "schnorrkel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-cli" -version = "1.0.0" -dependencies = [ - "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "names 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-client 1.0.0", - "substrate-keyring 1.0.0", - "substrate-network 0.1.0", - "substrate-panic-handler 1.0.0", - "substrate-primitives 1.0.0", - "substrate-service 1.0.0", - "substrate-state-machine 1.0.0", - "substrate-telemetry 1.0.0", - "sysinfo 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-client" -version = "1.0.0" -dependencies = [ - "derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api-macros 1.0.0", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "sr-version 1.0.0", - "substrate-consensus-common 1.0.0", - "substrate-executor 1.0.0", - "substrate-inherents 1.0.0", - "substrate-keyring 1.0.0", - "substrate-primitives 1.0.0", - "substrate-state-machine 1.0.0", - "substrate-telemetry 1.0.0", - "substrate-trie 1.0.0", -] - -[[package]] -name = "substrate-client-db" -version = "1.0.0" -dependencies = [ - "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", - "kvdb-rocksdb 0.1.4 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "substrate-client 1.0.0", - "substrate-consensus-common 1.0.0", - "substrate-executor 1.0.0", - "substrate-primitives 1.0.0", - "substrate-state-db 1.0.0", - "substrate-state-machine 1.0.0", - "substrate-trie 1.0.0", -] - -[[package]] -name = "substrate-consensus-aura" -version = "1.1.0" -dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "sr-version 1.0.0", - "srml-aura 1.0.0", - "srml-consensus 1.0.0", - "srml-support 1.0.0", - "substrate-client 1.0.0", - "substrate-consensus-aura-primitives 1.0.0", - "substrate-consensus-authorities 1.0.0", - "substrate-consensus-common 1.0.0", - "substrate-consensus-slots 1.1.0", - "substrate-inherents 1.0.0", - "substrate-primitives 1.0.0", - "substrate-telemetry 1.0.0", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-consensus-aura-primitives" -version = "1.0.0" -dependencies = [ - "sr-primitives 1.0.0", - "substrate-client 1.0.0", -] - -[[package]] -name = "substrate-consensus-authorities" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "sr-version 1.0.0", - "srml-support 1.0.0", - "substrate-client 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "substrate-consensus-common" -version = "1.0.0" -dependencies = [ - "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-version 1.0.0", - "substrate-inherents 1.0.0", - "substrate-primitives 1.0.0", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-consensus-slots" -version = "1.1.0" -dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "substrate-client 1.0.0", - "substrate-consensus-common 1.0.0", - "substrate-inherents 1.0.0", - "substrate-primitives 1.0.0", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-executor" -version = "1.0.0" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-version 1.0.0", - "substrate-panic-handler 1.0.0", - "substrate-primitives 1.0.0", - "substrate-serializer 1.0.0", - "substrate-state-machine 1.0.0", - "substrate-trie 1.0.0", - "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-finality-grandpa" -version = "1.0.0" -dependencies = [ - "finality-grandpa 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "fork-tree 1.0.0", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "srml-finality-tracker 1.0.0", - "substrate-client 1.0.0", - "substrate-consensus-common 1.0.0", - "substrate-finality-grandpa-primitives 1.0.0", - "substrate-inherents 1.0.0", - "substrate-network 0.1.0", - "substrate-primitives 1.0.0", - "substrate-service 1.0.0", - "substrate-telemetry 1.0.0", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-finality-grandpa-primitives" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", - "substrate-client 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "substrate-inherents" -version = "1.0.0" -dependencies = [ - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-std 1.0.0", -] - -[[package]] -name = "substrate-keyring" -version = "1.0.0" -dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "strum 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", - "strum_macros 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "substrate-keystore" -version = "1.0.0" -dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-crypto 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-primitives 1.0.0", - "subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-network" -version = "0.1.0" -dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "fork-tree 1.0.0", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "substrate-client 1.0.0", - "substrate-consensus-common 1.0.0", - "substrate-network-libp2p 1.0.0", - "substrate-peerset 1.0.0", - "substrate-primitives 1.0.0", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-network-libp2p" -version = "1.0.0" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "slog_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-peerset 1.0.0", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-offchain" -version = "0.1.0" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "substrate-client 1.0.0", - "substrate-consensus-common 1.0.0", - "substrate-inherents 1.0.0", - "substrate-offchain-primitives 0.1.0", - "substrate-primitives 1.0.0", - "substrate-transaction-pool 1.0.0", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-offchain-primitives" -version = "0.1.0" -dependencies = [ - "sr-primitives 1.0.0", - "substrate-client 1.0.0", -] - -[[package]] -name = "substrate-panic-handler" -version = "1.0.0" -dependencies = [ - "backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-peerset" -version = "1.0.0" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-primitives" -version = "1.0.0" -dependencies = [ - "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hash256-std-hasher 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "schnorrkel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 1.0.0", - "substrate-bip39 0.2.1 (git+https://github.com/paritytech/substrate-bip39)", - "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "twox-hash 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-rpc" -version = "1.0.0" -dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "sr-version 1.0.0", - "substrate-client 1.0.0", - "substrate-executor 1.0.0", - "substrate-network 0.1.0", - "substrate-primitives 1.0.0", - "substrate-state-machine 1.0.0", - "substrate-transaction-pool 1.0.0", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-rpc-servers" -version = "1.0.0" -dependencies = [ - "jsonrpc-http-server 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-ws-server 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "substrate-rpc 1.0.0", -] - -[[package]] -name = "substrate-serializer" -version = "1.0.0" -dependencies = [ - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-service" -version = "1.0.0" -dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 1.0.0", - "sr-primitives 1.0.0", - "substrate-client 1.0.0", - "substrate-client-db 1.0.0", - "substrate-consensus-common 1.0.0", - "substrate-executor 1.0.0", - "substrate-inherents 1.0.0", - "substrate-keystore 1.0.0", - "substrate-network 0.1.0", - "substrate-offchain 0.1.0", - "substrate-primitives 1.0.0", - "substrate-rpc-servers 1.0.0", - "substrate-telemetry 1.0.0", - "substrate-transaction-pool 1.0.0", - "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-state-db" -version = "1.0.0" -dependencies = [ - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "substrate-state-machine" -version = "1.0.0" -dependencies = [ - "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-panic-handler 1.0.0", - "substrate-primitives 1.0.0", - "substrate-trie 1.0.0", - "trie-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-root 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-telemetry" -version = "1.0.0" -dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-scope 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "ws 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-transaction-graph" -version = "1.0.0" -dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "substrate-primitives 1.0.0", -] - -[[package]] -name = "substrate-transaction-pool" -version = "1.0.0" -dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 1.0.0", - "substrate-client 1.0.0", - "substrate-primitives 1.0.0", - "substrate-transaction-graph 1.0.0", -] - -[[package]] -name = "substrate-trie" -version = "1.0.0" -dependencies = [ - "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "memory-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 1.0.0", - "substrate-primitives 1.0.0", - "trie-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-root 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "subtle" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "subtle" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "syn" -version = "0.15.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "synstructure" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sysinfo" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "take_mut" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "target_info" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "tempfile" -version = "3.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "termcolor" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "termion" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "textwrap" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "thread_local" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "time" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tiny-bip39" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tiny-keccak" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tk-listen" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-sync 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-trace-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-codec" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-current-thread" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-dns-unofficial" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-executor" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-fs" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-io" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-reactor" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-sync 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-sync" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-tcp" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-threadpool" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-timer" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-tls" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-trace-core" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-udp" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-uds" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "toml" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "traitobject" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "trie-db" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hashmap_core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "trie-root" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "try-lock" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "twofish" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "twox-hash" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "typeable" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "typenum" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "ucd-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "uint" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "unicase" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "unicase" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "unicode-normalization" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "unicode-segmentation" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "unicode-width" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "unicode-xid" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "unsigned-varint" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "untrusted" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "url" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "utf8-ranges" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "vcpkg" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "vec_map" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "version_check" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "want" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "wasm-bindgen-macro 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bumpalo 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro-support 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.43" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "wasm-bindgen-webidl" -version = "0.2.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "weedle 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasmi" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi-validation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasmi-validation" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "web-sys" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", - "sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-webidl 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "websocket" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "weedle" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "which" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi-util" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "wincolor" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ws" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.10.22 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "x25519-dalek" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "curve25519-dalek 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "xdg" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "yaml-rust" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "yamux" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "nohash-hasher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "zeroize" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum aes 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "54eb1d8fe354e5fc611daf4f2ea97dd45a765f4f1e4512306ec183ae2e8f20c9" -"checksum aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2e5b0458ea3beae0d1d8c0f3946564f8e10f90646cf78c06b4351052058d1ee" -"checksum aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d" -"checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100" -"checksum aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e6f484ae0c99fec2e858eb6134949117399f222608d84cadb3f58c1f97c2364c" -"checksum aio-limited 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f10b352bc3fc08ae24dc5d2d3ddcac153678533986122dc283d747b12071000" -"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -"checksum app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e73a24bad9bd6a94d6395382a6c69fe071708ae4409f763c5475e14ee896313d" -"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" -"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" -"checksum asn1_der 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9893d63fc3b1c44231e667da6836a33f27d8b6b3bdc82f83da5dfd579d1b6528" -"checksum asn1_der_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e7f92edafad155aff997fa5b727c6429b91e996b5a5d62a2b0adbae1306b5fe" -"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" -"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" -"checksum backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f106c02a3604afcdc0df5d36cc47b44b55917dbaf3d808f71c163a0ddba64637" -"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6" -"checksum base-x 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d55aa264e822dbafa12db4d54767aff17c6ba55ea2d8559b3e17392c7d000e5d" -"checksum base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" -"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" -"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" -"checksum bigint 4.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ebecac13b3c745150d7b6c3ea7572d372f09d627c2077e893bf26c5c7f70d282" -"checksum bindgen 0.47.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df683a55b54b41d5ea8ebfaebb5aa7e6b84e3f3006a78f010dadc9ca88469260" -"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" -"checksum bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5da9b3d9f6f585199287a473f4f8dfab6566cf827d15c00c219f53c645687ead" -"checksum blake2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91721a6330935673395a0607df4d49a9cb90ae12d259f1b3e0a3f6e1d486872e" -"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" -"checksum block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1339a1042f5d9f295737ad4d9a6ab6bf81c84a933dba110b9200cd6d1448b814" -"checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" -"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -"checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" -"checksum block-modes 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "31aa8410095e39fdb732909fb5730a48d5bd7c2e3cd76bd1b07b3dbea130c529" -"checksum block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4dc3af3ee2e12f3e5d224e5e1e3d73668abbeb69e566d361f7d5563a4fdf09" -"checksum bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0de79cfb98e7aa9988188784d8664b4b5dad6eaaa0863b91d9a4ed871d4f7a42" -"checksum bstr 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6c8203ca06c502958719dae5f653a79e0cc6ba808ed02beffbf27d09610f2143" -"checksum bumpalo 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4639720be048090544634e0402490838995ccdc9d2fe648f528f30d3c33ae71f" -"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" -"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" -"checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" -"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" -"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -"checksum c_linked_list 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" -"checksum cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "389803e36973d242e7fecb092b2de44a3d35ac62524b3b9339e51d577d668e02" -"checksum cexpr 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7fa24eb00d5ffab90eaeaf1092ac85c04c64aaf358ea6f84505b8116d24c6af" -"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" -"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" -"checksum clang-sys 0.26.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ef0c1bcf2e99c649104bd7a7012d8f8802684400e03db0ec0af48583c6fa0e4" -"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" -"checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" -"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" -"checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" -"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" -"checksum crossbeam 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad4c7ea749d9fb09e23c5cb17e3b70650860553a0e2744e38446b1803bf7db94" -"checksum crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f0ed1a4de2235cabda8558ff5840bffb97fcb64c97827f354a451307df5f72b" -"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" -"checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13" -"checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71" -"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" -"checksum crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04c9e3102cc2d69cd681412141b390abd55a362afc1540965dad0ad4d34280b4" -"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" -"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" -"checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" -"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" -"checksum crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" -"checksum crypto-mac 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "779015233ac67d65098614aec748ac1c756ab6677fa2e14cf8b37c08dfed1198" -"checksum crypto-mac 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7afa06d05a046c7a47c3a849907ec303504608c927f4e85f7bfff22b7180d971" -"checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" -"checksum ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "022cd691704491df67d25d006fe8eca083098253c4d43516c2206479c58c6736" -"checksum cuckoofilter 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd43f7cfaffe0a386636a10baea2ee05cc50df3b77bea4a456c9572a939bf1f" -"checksum curve25519-dalek 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "750226d75fc2f5a8daec6e7477624e258674023eb73d8d647f63b943ca182a4a" -"checksum data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97" -"checksum derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fbe9f11be34f800b3ecaaed0ec9ec2e015d1d0ba0c8644c1310f73d6e8994615" -"checksum digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e5b29bf156f3f4b3c4f610a25ff69370616ae6e0657d416de22645483e72af0a" -"checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" -"checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c" -"checksum discard 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" -"checksum dns-parser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea" -"checksum ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81956bcf7ef761fb4e1d88de3fa181358a0d26cbcb9755b587a08f9119824b86" -"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b" -"checksum elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "073be79b6538296faf81c631872676600616073817dd9a440c477ad09b408983" -"checksum env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b61fa891024a945da30a9581546e8cfaf5602c7b3f4c137a2805cf388f92075a" -"checksum environmental 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c7464757b80de8930c91c9afe77ddce501826bf9d134a87db2c67d9dc177e2c" -"checksum erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3beee4bc16478a1b26f2e80ad819a52d24745e292f521a63c16eea5f74b7eb60" -"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" -"checksum exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d8013f441e38e31c670e7f34ec8f1d5d3a2bd9d303c1ff83976ca886005e8f48" -"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" -"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" -"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" -"checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" -"checksum finality-grandpa 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5cdd9ef7c48777665dacc9657c272778121d4d09848100bcc2bd9c773c6cf837" -"checksum fixed-hash 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d1a683d1234507e4f3bf2736eeddf0de1dc65996dc0164d57eba0a74bcf29489" -"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" -"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -"checksum fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "921d332c89b3b61a826de38c61ee5b6e02c56806cade1b0e5d81bd71f57a71bb" -"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "62941eff9507c8177d448bd83a44d9b9760856e184081d8cd79ba9f03dd24981" -"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" -"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" -"checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592" -"checksum generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fceb69994e330afed50c93524be68c42fa898c2d9fd4ee8da03bd7363acd26f2" -"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" -"checksum get_if_addrs 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "abddb55a898d32925f3148bd281174a68eeb68bbfd9a5938a57b18f506ee4ef7" -"checksum get_if_addrs-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d04f9fb746cf36b191c00f3ede8bde9c8e64f9f4b05ae2694a9ccf5e3f5ab48" -"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" -"checksum globset 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef4feaabe24a0a658fd9cf4a9acf6ed284f045c77df0f49020ba3245cfb7b454" -"checksum h2 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "85ab6286db06040ddefb71641b50017c06874614001a134b423783e2db2920bd" -"checksum hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ba7fb417e5c470acdd61068c79767d0e65962e70836cf6c9dfd2409f06345ce0" -"checksum hash256-std-hasher 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f8b2027c19ec91eb304999abae7307d225cf93be42af53b0039f76e98ed5af86" -"checksum hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da" -"checksum hashmap_core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8e04cb7a5051270ef3fa79f8c7604d581ecfa73d520e74f554e45541c4b5881a" -"checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" -"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" -"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" -"checksum hex-literal 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ddc2928beef125e519d69ae1baa8c37ea2e0d3848545217f6db0179c5eb1d639" -"checksum hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c3da68162fdd2147e66682e78e729bd77f93b4c99656db058c5782d8c6b6225a" -"checksum hex-literal-impl 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "520870c3213943eb8d7803e80180d12a6c7ceb4ae74602544529d1643dc4ddda" -"checksum hex-literal-impl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06095d08c7c05760f11a071b3e1d4c5b723761c01bd8d7201c30a9536668a612" -"checksum hmac 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a13f4163aa0c5ca1be584aace0e2212b2e41be5478218d4f657f5f778b2ae2a" -"checksum hmac 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "733e1b3ac906631ca01ebb577e9bb0f5e37a454032b9036b5eaea4013ed6f99a" -"checksum hmac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f127a908633569f208325f86f71255d3363c79721d7f9fe31cd5569908819771" -"checksum hmac-drbg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4fe727d41d2eec0a6574d887914347e5ff96a3b87177817e2a9820c5c87fecc2" -"checksum http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "eed324f0f0daf6ec10c474f150505af2c143f251722bf9dbd1261bd1f2ee2c1a" -"checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83" -"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" -"checksum hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273" -"checksum hyper 0.12.28 (registry+https://github.com/rust-lang/crates.io-index)" = "e8e4606fed1c162e3a63d408c07584429f49a4f34c7176cb6cbee60e78f2372c" -"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" -"checksum impl-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2050d823639fbeae26b2b5ba09aca8907793117324858070ade0673c49f793b" -"checksum impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5158079de9d4158e0ce1de3ae0bd7be03904efc40b3d7dd8b8c301cbf6b52b56" -"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" -"checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" -"checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" -"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" -"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" -"checksum js-sys 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "e9c0d432259f651d765d888e30164c096ddbae13c89e56dd1d02a719e020efa8" -"checksum jsonrpc-core 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dc15eef5f8b6bef5ac5f7440a957ff95d036e2f98706947741bfc93d1976db4c" -"checksum jsonrpc-derive 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c2dae61ca8a3b047fb11309b00661bc56837085bd07e46f907b9c562c0b03e68" -"checksum jsonrpc-http-server 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "11d2a00824306155b8ef57fe957f31b8cd8ad24262f15cf911d84dcf9a3f206d" -"checksum jsonrpc-pubsub 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37fce55133ee264d0ab42bd862efcd45ae1d062cda599f4cc12ccc4be3195f2a" -"checksum jsonrpc-server-utils 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c9527f01ef25f251d64082cbefc0c6d6f367349afe6848ef908a674e06b2bdd3" -"checksum jsonrpc-ws-server 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3889012aa638a2f18eb1a879f46fc8b34e7e1423cbff3247cd1531de0d51084b" -"checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" -"checksum kvdb-rocksdb 0.1.4 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" -"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" -"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" -"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" -"checksum libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "c6785aa7dd976f5fbf3b71cfd9cd49d7f783c1ff565a858d71031c6c313aa5c6" -"checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2" -"checksum libp2p 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0231edab431064b30b7749484a39735eb36492cef4658c372c9059e58c3003aa" -"checksum libp2p-core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d1a3bad2ed26297112847678683dd221473a0d44297250b61f004e1b35e72493" -"checksum libp2p-core-derive 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f765f103b680cbed910b02bfdbdcfce5b1142899c93e51acb960bf59b6f81b1" -"checksum libp2p-dns 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b129d20cc8cbb6ce5da8361045649c024659173e246c5dfbf20ae06071c046a" -"checksum libp2p-floodsub 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "70d68816b8435d6788399416eb2f0a6974fb1d15c4be5c30141f87c8e81746df" -"checksum libp2p-identify 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "718ca645a065fd70855ca6042a7df686c24cd21add750c37a82c811fbd1e5c43" -"checksum libp2p-kad 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bbe27c623a6a720efd5d704347838972062f89149a9c3cd149748da60bdcd3e0" -"checksum libp2p-mdns 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c9bc1a5d85f4812cae6367b49a432763fe28997bac7c530dc55b70ec18a78aa7" -"checksum libp2p-mplex 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe5a858342a1cc89464474f7edc4bae1da649b9c823a3e04d9fb494493601746" -"checksum libp2p-noise 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc6b5185c50a52a12e7bbe2ee7799059e24de4e52ab25edbfd26c8ab8515d317" -"checksum libp2p-ping 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7905c1431ad115bee83405770629a27d6f17153ad02ec9670a7347998ef20e22" -"checksum libp2p-plaintext 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc17626763ded57da8fed73187c2d9f6ebb89d30838673c430315bf560c7e4db" -"checksum libp2p-ratelimit 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2409d08b809ab1a74269597f7da2829d117cc11b9ed3343af33fc20831619726" -"checksum libp2p-secio 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "258cdc6742945c8f6402997bbbf36733588e2db18e5a0014da6d46e3ccfb92cf" -"checksum libp2p-tcp 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1b5691e2ba2720d42bd1e93d6b90239fa9235c1956ef6a5f1dd499a7ae2767be" -"checksum libp2p-uds 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ab0b9ca050105fd94229c48911c0c84aef4d6b86a53d1b6df81d938354e47e" -"checksum libp2p-websocket 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "81692c3141a9aefd84f4faffdc93985af3858ef82ed7fe8185e6b27437b36183" -"checksum libp2p-yamux 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6ff51a5b2056bacee1c9f2ed8455cdf3c5c619261ddb4efc783119130aaf52" -"checksum librocksdb-sys 5.18.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d19778314deaa7048f2ea7d07b8aa12e1c227acebe975a37eeab6d2f8c74e41b" -"checksum libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "688e8d65e495567c2c35ea0001b26b9debf0b4ea11f8cccc954233b75fc3428a" -"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" -"checksum linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7c91c4c7bbeb4f2f7c4e5be11e6a05bd6830bc37249c47ce1ad86ad453ff9c" -"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" -"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" -"checksum lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" -"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" -"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" -"checksum memory-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7623b01a4f1b7acb7cf8e3f678f05e15e6ae26cb0b738dfeb5cc186fd6b82ef4" -"checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" -"checksum merlin 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8c39467de91b004f5b9c06fac5bbc8e7d28309a205ee66905166b70804a71fea" -"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" -"checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" -"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" -"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" -"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -"checksum multistream-select 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f989d40aab0ed0d83c1cdb4856b5790e980b96548d1a921f280e985eb049f38d" -"checksum names 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef320dab323286b50fb5cdda23f61c796a72a89998ab565ca32525c5c556f2da" -"checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" -"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" -"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" -"checksum nohash-hasher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d138afcce92d219ccb6eb53d9b1e8a96ac0d633cfd3c53cd9856d96d1741bb8" -"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" -"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" -"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" -"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba" -"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" -"checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c" -"checksum once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37" -"checksum opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "93f5bb2e8e8dec81642920ccff6b61f1eb94fa3020c5a325c9851ff604152409" -"checksum openssl 0.10.22 (registry+https://github.com/rust-lang/crates.io-index)" = "a51f452b82d622fc8dd973d7266e9055ac64af25b957d9ced3989142dc61cb6b" -"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-sys 0.9.46 (registry+https://github.com/rust-lang/crates.io-index)" = "05636e06b4f8762d4b81d24a351f3966f38bd25ccbcfd235606c91fdb82cc60f" -"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" -"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" -"checksum parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" -"checksum parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dcb43c05fb71c03b4ea7327bf15694da1e0f23f19d5b1e95bab6c6d74097e336" -"checksum parity-codec-derive 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "00a486fd383382ddcb2de928364b1f82571c1e48274fc43b7667a4738ee4056c" -"checksum parity-crypto 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1b9c063d87e1507cb3807493c8d21859ef23b5414b39f81c53f0ba267d64c1" -"checksum parity-multiaddr 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18a130a727008cfcd1068a28439fe939897ccad28664422aeca65b384d6de6d0" -"checksum parity-multihash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05d6a68e07ab34a9e87bd8dd4936f6bb5be21e4f6dbcdbaf04d8e854eba0af01" -"checksum parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "511379a8194230c2395d2f5fa627a5a7e108a9f976656ce723ae68fca4097bfc" -"checksum parity-ws 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2fec5048fba72a2e01baeb0d08089db79aead4b57e2443df172fb1840075a233" -"checksum parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4d05f1349491390b1730afba60bb20d55761bef489a954546b58b4b34e1e2ac" -"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" -"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" -"checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa" -"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" -"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" -"checksum paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4a4a1c555c6505821f9d58b8779d0f630a6b7e4e1be24ba718610acf01fa79" -"checksum paste-impl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "26e796e623b8b257215f27e6c80a5478856cae305f5b59810ff9acdaa34570e6" -"checksum pbkdf2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0c09cddfbfc98de7f76931acf44460972edb4023eb14d0c6d4018800e552d8e0" -"checksum pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" -"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" -"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" -"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" -"checksum primitive-types 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "99d5a5fe9d93ddb394e2fb3fc49d0e31acb475fd45a30eeb8f3e76b767ecb7e1" -"checksum proc-macro-crate 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4c6cf4e5b00300d151dfffae39f529dfa5188f42eeb14201229aa420d6aad10c" -"checksum proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c725b36c99df7af7bf9324e9c999b9e37d92c8f8caf106d82e1d7953218d2d8" -"checksum proc-macro-hack 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0c1dd4172a1e1f96f709341418f49b11ea6c2d95d53dca08c0f74cbd332d9cf3" -"checksum proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b753ad9ed99dd8efeaa7d2fb8453c8f6bc3e54b97966d35f1bc77ca6865254a" -"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -"checksum protobuf 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc7badf647ae2fa27ba51c218e347386c88cc604fcfe71f2aba0ad017f3f2b75" -"checksum pwasm-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "efb0dcbddbb600f47a7098d33762a00552c671992171637f5bb310b37fe1f0e4" -"checksum quick-error 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb6ccf8db7bbcb9c2eae558db5ab4f3da1c2a87e4e597ed394726bc8ea6ca1d" -"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" -"checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" -"checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" -"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" -"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" -"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -"checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -"checksum rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "373814f27745b2686b350dd261bfd24576a6fb0e2c5919b3a2b6005f820b0473" -"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" -"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -"checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252" -"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8f0a0bcab2fd7d1d7c54fa9eae6f43eddeb9ce2e7352f8518a814a4f65d60c58" -"checksum regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dcfd8681eebe297b81d98498869d4aae052137651ad7b96822f09ceb690d0a96" -"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" -"checksum ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)" = "426bc186e3e95cac1e4a4be125a4aca7e84c2d616ffc02244eef36e2a60a093c" -"checksum ripemd160 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad5112e0dbbb87577bfbc56c42450235e3012ce336e29c5befd7807bd626da4a" -"checksum rocksdb 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1651697fefd273bfb4fd69466cc2a9d20de557a0213b97233b22b5e95924b5e" -"checksum rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ccc78bfd5acd7bf3e89cffcf899e5cb1a52d6fafa8dec2739ad70c9577a57288" -"checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8" -"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum rw-stream-sink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d548a40fe17c3a77d54b82457b79fcc9b8a288d509ca20fbf5aa1dac386d22d6" -"checksum ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "b96a9549dc8d48f2c283938303c4b5a77aa29bfbc5b54b084fb1630408899a8f" -"checksum safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347" -"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" -"checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339" -"checksum schnorrkel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b5eff518f9bed3d803a0d002af0ab96339b0ebbedde3bec98a684986134b7a39" -"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum scrypt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8570c5e2fa69cb29d492fd4e9974b6b5facb5a888e1c6da630d4a3cd7ebfef4a" -"checksum secp256k1 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfaccd3a23619349e0878d9a241f34b1982343cdf67367058cd7d078d326b63e" -"checksum security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eee63d0f4a9ec776eeb30e220f0bc1e092c3ad744b2a379e3993070364d3adc2" -"checksum security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9636f8989cbf61385ae4824b98c1aaa54c994d7d8b41f11c601ed799f0549a56" -"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0eddf2e8f50ced781f288c19f18621fa72a3779e3cb58dbf23b07469b0abeb4" -"checksum serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)" = "a72e9b96fa45ce22a4bc23da3858dfccfd60acd28a25bcd328a98fdd6bea43fd" -"checksum serde_derive 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)" = "101b495b109a3e3ca8c4cbe44cf62391527cdfb6ba15821c5ce80bcd5ea23f9f" -"checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d" -"checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68" -"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" -"checksum sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d963c78ce367df26d7ea8b8cc655c651b42e8a1e584e869c1e17dae3ccb116a" -"checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0" -"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" -"checksum sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf" -"checksum shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ee04b46101f57121c9da2b151988283b6beb79b34f5bb29a58ee48cb695122c" -"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" -"checksum slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e1a2eec401952cd7b12a84ea120e2d57281329940c3f93c2bf04f462539508e" -"checksum slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e544d16c6b230d84c866662fe55e31aacfca6ae71e6fc49ae9a311cb379bfc2f" -"checksum slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddc0d2aff1f8f325ef660d9a0eb6e6dcd20b30b3f581a5897f58bf42d061c37a" -"checksum slog-scope 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "60c04b4726fa04595ccf2c2dad7bcd15474242c4c5e109a8a376e8a2c9b1539a" -"checksum slog_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eff3b513cf2e0d1a60e1aba152dc72bedc5b05585722bb3cebd7bcb1e31b98f" -"checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" -"checksum snow 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5a64f02fd208ef15bd2d1a65861df4707e416151e1272d02c8faafad1c138100" -"checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" -"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55" -"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" -"checksum static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5" -"checksum static_slice 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "92a7e0c5e3dfb52e8fbe0e63a1b947bbb17b4036408b151353c4491374931362" -"checksum stdweb 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)" = "c34362bb10ac1a9439674795cc0e1bdcb0c46444c8fd4874ef39a01d9a8a8f24" -"checksum stdweb-derive 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e21ebd9179de08f2300a65454268a17ea3de204627458588c84319c4def3930" -"checksum stdweb-internal-macros 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e68f7d08b76979a43e93fe043b66d2626e35d41d68b0b85519202c6dd8ac59fa" -"checksum stdweb-internal-runtime 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d52317523542cc0af5b7e31017ad0f7d1e78da50455e38d5657cd17754f617da" -"checksum stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8861bc80f649f5b4c9bd38b696ae9af74499d479dbfb327f0607de6b326a36bc" -"checksum string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b639411d0b9c738748b5397d5ceba08e648f4f1992231aa859af1a017f31f60b" -"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" -"checksum structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "3d0760c312538987d363c36c42339b55f5ee176ea8808bbe4543d484a291c8d1" -"checksum structopt-derive 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "528aeb7351d042e6ffbc2a6fb76a86f9b622fdf7c25932798e7a82cb03bc94c6" -"checksum strum 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1810e25f576e7ffce1ff5243b37066da5ded0310b3274c20baaeccb1145b2806" -"checksum strum_macros 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "572a2f4e53dd4c3483fd79e5cc10ddd773a3acb1169bbfe8762365e107110579" -"checksum substrate-bip39 0.2.1 (git+https://github.com/paritytech/substrate-bip39)" = "" -"checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" -"checksum subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "01dca13cf6c3b179864ab3292bd794e757618d35a7766b7c46050c614ba00829" -"checksum syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)" = "a1393e4a97a19c01e900df2aec855a29f71cf02c402e2f443b8d2747c25c5dbe" -"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" -"checksum sysinfo 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d88e417391431019773011a31a6c967538da388782b7711f2f6fafd9e601e55" -"checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" -"checksum target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" -"checksum tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b86c784c88d98c801132806dadd3819ed29d8600836c4088e855cdf3e178ed8a" -"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" -"checksum termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dde0593aeb8d47accea5392b39350015b5eccb12c0d98044d856983d89548dea" -"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" -"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" -"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" -"checksum tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c5676413eaeb1ea35300a0224416f57abc3bd251657e0fafc12c47ff98c060" -"checksum tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e9175261fbdb60781fcd388a4d6cc7e14764a2b629a7ad94abb439aed223a44f" -"checksum tk-listen 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5462b0f968c0457efe38fcd2df7e487096b992419e4f5337b06775a614bbda4b" -"checksum tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "cec6c34409089be085de9403ba2010b80e36938c9ca992c4f67f407bb13db0b1" -"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" -"checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" -"checksum tokio-dns-unofficial 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "82c65483db54eb91b4ef3a9389a3364558590faf30ce473141707c0e16fda975" -"checksum tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "83ea44c6c0773cc034771693711c35c677b4b5a4b21b9e7071704c54de7d555e" -"checksum tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af" -"checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" -"checksum tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6af16bfac7e112bea8b0442542161bfc41cbfa4466b580bdda7d18cb88b911ce" -"checksum tokio-sync 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5b2f843ffdf8d6e1f90bddd48da43f99ab071660cd92b7ec560ef3cdfd7a409a" -"checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" -"checksum tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72558af20be886ea124595ea0f806dd5703b8958e4705429dd58b3d8231f72f2" -"checksum tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2910970404ba6fa78c5539126a9ae2045d62e3713041e447f695f41405a120c6" -"checksum tokio-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "354b8cd83825b3c20217a9dc174d6a0c67441a2fae5c41bcb1ea6679f6ae0f7c" -"checksum tokio-trace-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "350c9edade9830dc185ae48ba45667a445ab59f6167ef6d0254ec9d2430d9dd3" -"checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92" -"checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" -"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" -"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" -"checksum trie-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1ba73747fd3a64ab531274c04cb588dfa9d30d972d62990831e63fbce2cfec59" -"checksum trie-root 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfa2e20c4f1418ac2e71ddc418e35e1b56e34022e2146209ffdbf1b2de8b1bd9" -"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" -"checksum twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d261e83e727c8e2dbb75dacac67c36e35db36a958ee504f2164fc052434e1" -"checksum twox-hash 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "09871da9f15424236082e0b220fd404a4eb6bebc7205c67653701229234ac64c" -"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" -"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" -"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" -"checksum uint 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91bb295c2c53c54742a6b8acb705114f6dfdf3c42becdb146a662cb77fcc0d02" -"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" -"checksum unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a84e5511b2a947f3ae965dcb29b13b7b1691b6e7332cf5dbc1744138d5acb7f6" -"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -"checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" -"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" -"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" -"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" -"checksum unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2c64cdf40b4a9645534a943668681bcb219faf51874d4b65d2e0abda1b10a2ab" -"checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" -"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" -"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" -"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" -"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" -"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" -"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3" -"checksum wasm-bindgen 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "546e4ab1bf7f9a3532d21472efd72d01a23f55abd885c60b165f393394dbad95" -"checksum wasm-bindgen-backend 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "7b84bedebfd6ae3522cce59dec6b52ee6c53ceeaae8541668c15b9f42df8ecab" -"checksum wasm-bindgen-futures 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "c6fc76797785881eac82f72e9b676032a737dea717103878100dbf6106d8d2cb" -"checksum wasm-bindgen-macro 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "f2a033fc6bfd5e486a488b0e19d7d1bb29e667ebb91db85f698381a8aa831786" -"checksum wasm-bindgen-macro-support 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "fba68375ef8f095c4a169c093c95ed2e1b5e44f7872f3bcbcafe2c51b4a80480" -"checksum wasm-bindgen-shared 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "321949f4d7f7bf7a49dccd464bdc46581b180f761d9505e4943926d50b2a4a64" -"checksum wasm-bindgen-webidl 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "b8c2c2b45b827f96657beea954a5430d37da4cf477d2874595f5f0a6ad027980" -"checksum wasmi 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aebbaef470840d157a5c47c8c49f024da7b1b80e90ff729ca982b2b80447e78b" -"checksum wasmi-validation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab380192444b3e8522ae79c0a1976e42a82920916ccdfbce3def89f456ea33f3" -"checksum web-sys 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "47ad2ecfe3793a87a0aa49562ad6f01cb3af3c870213283bc60032ec8dd7e62a" -"checksum websocket 0.22.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0adcd2a64c5746c9702b354a1b992802b0c363df1dfa324a74cb7aebe10e0cbf" -"checksum weedle 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26a4c67f132386d965390b8a734d5d10adbcd30eb5cc74bd9229af8b83f10044" -"checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" -"checksum ws 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)" = "329d3e6dd450a9c5c73024e1047f0be7e24121a68484eb0b5368977bee3cf8c3" -"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -"checksum x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ee1585dc1484373cbc1cee7aafda26634665cf449436fd6e24bfd1fad230538" -"checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" -"checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" -"checksum yamux 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "01bd67889938c48f0049fc60a77341039e6c3eaf16cb7693e6ead7c0ba701295" -"checksum zeroize 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8ddfeb6eee2fb3b262ef6e0898a52b7563bb8e0d5955a313b3cf2f808246ea14" diff --git a/test-utils/chain-spec-builder/Cargo.toml b/test-utils/chain-spec-builder/Cargo.toml index 1e048a91cd..0bd9b2c55c 100644 --- a/test-utils/chain-spec-builder/Cargo.toml +++ b/test-utils/chain-spec-builder/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -clap = { version = "~2.32", features = ["yaml"] } +clap = { version = "~2.32.0", features = ["yaml"] } node-cli = { path = "../../node/cli" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } substrate-service = { path = "../../core/service" } diff --git a/test-utils/transaction-factory/Cargo.toml b/test-utils/transaction-factory/Cargo.toml index f3c392c3d6..e53972eec6 100644 --- a/test-utils/transaction-factory/Cargo.toml +++ b/test-utils/transaction-factory/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" cli = { package = "substrate-cli", path = "../../core/cli" } client = { package = "substrate-client", path = "../../core/client" } consensus_common = { package = "substrate-consensus-common", path = "../../core/consensus/common" } -log = "0.4" +log = "0.4.8" codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } -- GitLab From f04d7de11ac6c10b572edadd3b2e3d2ba30ff594 Mon Sep 17 00:00:00 2001 From: Yash Garg Date: Thu, 3 Oct 2019 06:43:59 +0530 Subject: [PATCH 174/275] Update README.adoc (#3744) * Update README.adoc * Update README.adoc Co-Authored-By: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update README.adoc Co-Authored-By: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update README.adoc Co-Authored-By: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update README.adoc Co-Authored-By: joe petrowski <25483142+joepetrowski@users.noreply.github.com> --- README.adoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.adoc b/README.adoc index 39b0912b7d..810d07c612 100644 --- a/README.adoc +++ b/README.adoc @@ -20,13 +20,13 @@ See also https://www.parity.io/what-is-substrate/. Substrate is still an early stage project, and while it has already been used as the basis of major projects like Polkadot, using it is still a significant undertaking. In particular, you should have a good knowledge of blockchain concepts and basic cryptography. Terminology like header, block, client, hash, transaction and signature should be familiar. At present you will need a working knowledge of Rust to be able to do anything interesting (though eventually, we aim for this not to be the case). -Substrate is designed to be used in one of three ways: +Substrate is designed for use in one of three ways: -1. Trivial: By running the Substrate binary `substrate` and configuring it with a genesis block that includes the current demonstration runtime. In this case, you just build Substrate, configure a JSON file and launch your own blockchain. This affords you the least amount of customisability, primarily allowing you to change the genesis parameters of the various included runtime modules such as balances, staking, block-period, fees and governance. +**1. Trivial**: By running the Substrate binary `substrate` and configuring it with a genesis block that includes the current demonstration runtime. In this case, you just build Substrate, configure a JSON file, and launch your own blockchain. This affords you the least amount of customizability, primarily allowing you to change the genesis parameters of the various included runtime modules such as balances, staking, block-period, fees, and governance. -2. Modular: By hacking together modules from the Substrate Runtime Module Library into a new runtime and possibly altering or reconfiguring the Substrate client's block authoring logic. This affords you a very large amount of freedom over your own blockchain's logic, letting you change datatypes, add or remove modules and, crucially, add your own modules. Much can be changed without touching the block-authoring logic (since it is generic). If this is the case, then the existing Substrate binary can be used for block authoring and syncing. If the block authoring logic needs to be tweaked, then a new altered block-authoring binary must be built as a separate project and used by validators. This is how the Polkadot relay chain is built and should suffice for almost all circumstances in the near to mid-term. +**2. Modular**: By hacking together modules from the Substrate Runtime Module Library (SRML) into a new runtime and possibly altering or reconfiguring the Substrate client's block authoring logic. This affords you a very large amount of freedom over your blockchain's logic, letting you change datatypes, add or remove modules, and crucially, add your own modules. Much can be changed without touching the block authoring logic (since it is generic). If this is the case, then the existing Substrate binary can be used for block authoring and syncing. If the block authoring logic needs to be tweaked, then a new, altered block authoring binary must be built as a separate project and used by validators. This is how the Polkadot relay chain is built and should suffice for almost all circumstances in the near to mid-term. -3. Generic: The entire Substrate Runtime Module Library can be ignored and the entire runtime designed and implemented from scratch. If desired, this can be done in a language other than Rust, providing it can target WebAssembly. If the runtime can be made to be compatible with the existing client's block authoring logic, then you can simply construct a new genesis block from your Wasm blob and launch your chain with the existing Rust-based Substrate client. If not, then you'll need to alter the client's block authoring logic accordingly. This is probably a useless option for most projects right now, but provides complete flexibility allowing for a long-term far-reaching upgrade path for the Substrate paradigm. +**3. Generic**: The entire SRML can be ignored and the entire runtime designed and implemented from scratch. If desired, this can be done in a language other than Rust, provided it can target WebAssembly. If the runtime can be made compatible with the existing client's block authoring logic, then you can simply construct a new genesis block from your Wasm blob and launch your chain with the existing Rust-based Substrate client. If not, then you'll need to alter the client's block authoring logic accordingly. This is probably a useless option for most projects right now, but provides complete flexibility allowing for a long-term, far-reaching upgrade path for the Substrate paradigm. === The Basics of Substrate -- GitLab From 8492a268cacb13b0e51d7fa8551a1c662882390a Mon Sep 17 00:00:00 2001 From: Xiliang Chen Date: Thu, 3 Oct 2019 14:16:07 +1300 Subject: [PATCH 175/275] Minor fixes (#3751) * fix warning * use compact for balance type * bump version --- node/runtime/src/lib.rs | 2 +- srml/elections-phragmen/src/lib.rs | 2 +- srml/elections/src/lib.rs | 4 ++-- srml/scored-pool/src/lib.rs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 82ffe5390f..190385d6bc 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -85,7 +85,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 170, - impl_version: 170, + impl_version: 171, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/elections-phragmen/src/lib.rs b/srml/elections-phragmen/src/lib.rs index b7cf1a4013..58c0f11340 100644 --- a/srml/elections-phragmen/src/lib.rs +++ b/srml/elections-phragmen/src/lib.rs @@ -181,7 +181,7 @@ decl_module! { /// Writes: O(V) given `V` votes. V is bounded by 16. /// # #[weight = SimpleDispatchInfo::FixedNormal(100_000)] - fn vote(origin, votes: Vec, value: BalanceOf) { + fn vote(origin, votes: Vec, #[compact] value: BalanceOf) { let who = ensure_signed(origin)?; let candidates_count = >::decode_len().unwrap_or(0) as usize; diff --git a/srml/elections/src/lib.rs b/srml/elections/src/lib.rs index 2a683879f8..8c90090349 100644 --- a/srml/elections/src/lib.rs +++ b/srml/elections/src/lib.rs @@ -344,7 +344,7 @@ decl_module! { votes: Vec, #[compact] index: VoteIndex, hint: SetIndex, - value: BalanceOf + #[compact] value: BalanceOf ) -> Result { let who = ensure_signed(origin)?; Self::do_set_approvals(who, votes, index, hint, value) @@ -361,7 +361,7 @@ decl_module! { votes: Vec, #[compact] index: VoteIndex, hint: SetIndex, - value: BalanceOf + #[compact] value: BalanceOf ) -> Result { let who = Self::proxy(ensure_signed(origin)?).ok_or("not a proxy")?; Self::do_set_approvals(who, votes, index, hint, value) diff --git a/srml/scored-pool/src/lib.rs b/srml/scored-pool/src/lib.rs index 4739e165d1..609f17b457 100644 --- a/srml/scored-pool/src/lib.rs +++ b/srml/scored-pool/src/lib.rs @@ -91,7 +91,7 @@ mod tests; use codec::FullCodec; use rstd::prelude::*; use support::{ - StorageValue, decl_module, decl_storage, decl_event, ensure, + decl_module, decl_storage, decl_event, ensure, traits::{ChangeMembers, InitializeMembers, Currency, Get, ReservableCurrency}, }; use system::{self, ensure_root, ensure_signed}; -- GitLab From ddd7368b73e7d47cff8b51776ad4c0bc4fb007c9 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Thu, 3 Oct 2019 11:02:20 +0800 Subject: [PATCH 176/275] Cumulative fixes to make working with consensus-pow easier (#3617) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * consensus-pow: add difficulty data to auxiliary * Timestamp api * Implement FinalityProofProvider for () * Add DifficultyApi * Remove assumption that Difficulty is u128 * Use a separate trait for add instead of hard-code it as Saturating * Some convenience functions to work with PowVerifier * Try to fix mining unstability * Fix generic resolution * Unused best_header variable * Fix hash calculation * Remove artificial sleep * Tweak proposer waiting time * Revert sleep removal The reason why it was there is because when mine_loop returns, it means an error happened. In that case, we'd better sleep for a moment before trying again, because immediately trying would most likely just fail. * Pass sync oracle to mining So that it does not mine when major syncing * Expose build time as a parameter Instead of hardcode it as previously 100ms. * Update lock file * Fix compile * Support skipping check_inherents for ancient blocks For PoW, older blocks are secured by the work, and can mostly be considered to be finalized. Thus we can save both code complexity and validation time by skipping checking inherents for them. * Move difficulty fetch function out of loop To make things faster * Remove seed from mining Each engine can use its own Rng source. * Better comments * Add TotalDifficulty definition for U256 and u128 * Update core/consensus/pow/src/lib.rs Co-Authored-By: André Silva * Rename TotalDifficulty::add -> increment * Use SelectChain to fetch the best header/hash * Update lock file --- Cargo.lock | 1 + core/consensus/pow/primitives/Cargo.toml | 2 + core/consensus/pow/primitives/src/lib.rs | 45 +++++-- core/consensus/pow/src/lib.rs | 164 +++++++++++++++++------ core/network/src/chain.rs | 6 + 5 files changed, 168 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9d80227547..7043341751 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4861,6 +4861,7 @@ dependencies = [ name = "substrate-consensus-pow-primitives" version = "2.0.0" dependencies = [ + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", "substrate-client 2.0.0", diff --git a/core/consensus/pow/primitives/Cargo.toml b/core/consensus/pow/primitives/Cargo.toml index a7e0d284b0..021e4c80a7 100644 --- a/core/consensus/pow/primitives/Cargo.toml +++ b/core/consensus/pow/primitives/Cargo.toml @@ -10,6 +10,7 @@ substrate-client = { path = "../../../client", default-features = false } rstd = { package = "sr-std", path = "../../../sr-std", default-features = false } sr-primitives = { path = "../../../sr-primitives", default-features = false } primitives = { package = "substrate-primitives", path = "../../../primitives", default-features = false } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } [features] default = ["std"] @@ -18,4 +19,5 @@ std = [ "substrate-client/std", "sr-primitives/std", "primitives/std", + "codec/std", ] diff --git a/core/consensus/pow/primitives/src/lib.rs b/core/consensus/pow/primitives/src/lib.rs index 807a7b2df2..2079b1cbe7 100644 --- a/core/consensus/pow/primitives/src/lib.rs +++ b/core/consensus/pow/primitives/src/lib.rs @@ -20,17 +20,46 @@ use rstd::vec::Vec; use sr_primitives::ConsensusEngineId; +use codec::Decode; +use substrate_client::decl_runtime_apis; /// The `ConsensusEngineId` of PoW. pub const POW_ENGINE_ID: ConsensusEngineId = [b'p', b'o', b'w', b'_']; -/// Type of difficulty. -/// -/// For runtime designed for Substrate, it's always possible to fit its total -/// difficulty range under `u128::max_value()` because it can be freely scaled -/// up or scaled down. Very few PoW chains use difficulty values -/// larger than `u128::max_value()`. -pub type Difficulty = u128; - /// Type of seal. pub type Seal = Vec; + +/// Define methods that total difficulty should implement. +pub trait TotalDifficulty { + fn increment(&mut self, other: Self); +} + +impl TotalDifficulty for primitives::U256 { + fn increment(&mut self, other: Self) { + let ret = self.saturating_add(other); + *self = ret; + } +} + +impl TotalDifficulty for u128 { + fn increment(&mut self, other: Self) { + let ret = self.saturating_add(other); + *self = ret; + } +} + +decl_runtime_apis! { + /// API necessary for timestamp-based difficulty adjustment algorithms. + pub trait TimestampApi { + /// Return the timestamp in the current block. + fn timestamp() -> Moment; + } + + /// API for those chains that put their difficulty adjustment algorithm directly + /// onto runtime. Note that while putting difficulty adjustment algorithm to + /// runtime is safe, putting the PoW algorithm on runtime is not. + pub trait DifficultyApi { + /// Return the target difficulty of the next block. + fn difficulty() -> Difficulty; + } +} diff --git a/core/consensus/pow/src/lib.rs b/core/consensus/pow/src/lib.rs index 8bc0d3593a..7f282e2052 100644 --- a/core/consensus/pow/src/lib.rs +++ b/core/consensus/pow/src/lib.rs @@ -41,12 +41,12 @@ use sr_primitives::Justification; use sr_primitives::generic::{BlockId, Digest, DigestItem}; use sr_primitives::traits::{Block as BlockT, Header as HeaderT, ProvideRuntimeApi}; use srml_timestamp::{TimestampInherentData, InherentError as TIError}; -use pow_primitives::{Difficulty, Seal, POW_ENGINE_ID}; +use pow_primitives::{Seal, TotalDifficulty, POW_ENGINE_ID}; use primitives::H256; use inherents::{InherentDataProviders, InherentData}; use consensus_common::{ - BlockImportParams, BlockOrigin, ForkChoiceStrategy, - Environment, Proposer, + BlockImportParams, BlockOrigin, ForkChoiceStrategy, SyncOracle, Environment, Proposer, + SelectChain, }; use consensus_common::import_queue::{BoxBlockImport, BasicQueue, Verifier}; use codec::{Encode, Decode}; @@ -63,59 +63,78 @@ fn aux_key(hash: &H256) -> Vec { /// Auxiliary storage data for PoW. #[derive(Encode, Decode, Clone, Debug, Default)] -pub struct PowAux { - /// Total difficulty. +pub struct PowAux { + /// Difficulty of the current block. + pub difficulty: Difficulty, + /// Total difficulty up to current block. pub total_difficulty: Difficulty, } -impl PowAux { +impl PowAux where + Difficulty: Decode + Default, +{ /// Read the auxiliary from client. pub fn read(client: &C, hash: &H256) -> Result { let key = aux_key(hash); match client.get_aux(&key).map_err(|e| format!("{:?}", e))? { - Some(bytes) => PowAux::decode(&mut &bytes[..]).map_err(|e| format!("{:?}", e)), - None => Ok(PowAux::default()), + Some(bytes) => Self::decode(&mut &bytes[..]) + .map_err(|e| format!("{:?}", e)), + None => Ok(Self::default()), } } } /// Algorithm used for proof of work. pub trait PowAlgorithm { + /// Difficulty for the algorithm. + type Difficulty: TotalDifficulty + Default + Encode + Decode + Ord + Clone + Copy; + /// Get the next block's difficulty. - fn difficulty(&self, parent: &BlockId) -> Result; + fn difficulty(&self, parent: &BlockId) -> Result; /// Verify proof of work against the given difficulty. fn verify( &self, parent: &BlockId, pre_hash: &H256, seal: &Seal, - difficulty: Difficulty, + difficulty: Self::Difficulty, ) -> Result; /// Mine a seal that satisfy the given difficulty. fn mine( &self, parent: &BlockId, pre_hash: &H256, - seed: &H256, - difficulty: Difficulty, + difficulty: Self::Difficulty, round: u32, ) -> Result, String>; } /// A verifier for PoW blocks. -pub struct PowVerifier { +pub struct PowVerifier, C, S, Algorithm> { client: Arc, algorithm: Algorithm, inherent_data_providers: inherents::InherentDataProviders, + select_chain: Option, + check_inherents_after: <::Header as HeaderT>::Number, } -impl PowVerifier { - fn check_header>( +impl, C, S, Algorithm> PowVerifier { + pub fn new( + client: Arc, + algorithm: Algorithm, + check_inherents_after: <::Header as HeaderT>::Number, + select_chain: Option, + inherent_data_providers: inherents::InherentDataProviders, + ) -> Self { + Self { client, algorithm, inherent_data_providers, select_chain, check_inherents_after } + } + + fn check_header( &self, mut header: B::Header, parent_block_id: BlockId, - ) -> Result<(B::Header, Difficulty, DigestItem), String> where + ) -> Result<(B::Header, Algorithm::Difficulty, DigestItem), String> where Algorithm: PowAlgorithm, { let hash = header.hash(); @@ -146,7 +165,7 @@ impl PowVerifier { Ok((header, difficulty, seal)) } - fn check_inherents>( + fn check_inherents( &self, block: B, block_id: BlockId, @@ -157,6 +176,10 @@ impl PowVerifier { { const MAX_TIMESTAMP_DRIFT_SECS: u64 = 60; + if *block.header().number() < self.check_inherents_after { + return Ok(()) + } + let inherent_res = self.client.runtime_api().check_inherents( &block_id, block, @@ -183,9 +206,10 @@ impl PowVerifier { } } -impl, C, Algorithm> Verifier for PowVerifier where +impl, C, S, Algorithm> Verifier for PowVerifier where C: ProvideRuntimeApi + Send + Sync + HeaderBackend + AuxStore + ProvideCache + BlockOf, C::Api: BlockBuilderApi, + S: SelectChain, Algorithm: PowAlgorithm + Send + Sync, { fn verify( @@ -199,17 +223,23 @@ impl, C, Algorithm> Verifier for PowVerifier select_chain.best_chain() + .map_err(|e| format!("Fetch best chain failed via select chain: {:?}", e))? + .hash(), + None => self.client.info().best_hash, + }; let hash = header.hash(); let parent_hash = *header.parent_hash(); let best_aux = PowAux::read(self.client.as_ref(), &best_hash)?; let mut aux = PowAux::read(self.client.as_ref(), &parent_hash)?; - let (checked_header, difficulty, seal) = self.check_header::( + let (checked_header, difficulty, seal) = self.check_header( header, BlockId::Hash(parent_hash), )?; - aux.total_difficulty = aux.total_difficulty.saturating_add(difficulty); + aux.difficulty = difficulty; + aux.total_difficulty.increment(difficulty); if let Some(inner_body) = body.take() { let block = B::new(checked_header.clone(), inner_body); @@ -241,7 +271,7 @@ impl, C, Algorithm> Verifier for PowVerifier Result<(), consensus_common::Error> { if !inherent_data_providers.has_provider(&srml_timestamp::INHERENT_IDENTIFIER) { @@ -258,10 +288,12 @@ fn register_pow_inherent_data_provider( pub type PowImportQueue = BasicQueue; /// Import queue for PoW engine. -pub fn import_queue( +pub fn import_queue( block_import: BoxBlockImport, client: Arc, algorithm: Algorithm, + check_inherents_after: <::Header as HeaderT>::Number, + select_chain: Option, inherent_data_providers: InherentDataProviders, ) -> Result, consensus_common::Error> where B: BlockT, @@ -269,14 +301,17 @@ pub fn import_queue( C: Send + Sync + AuxStore + 'static, C::Api: BlockBuilderApi, Algorithm: PowAlgorithm + Send + Sync + 'static, + S: SelectChain + 'static, { register_pow_inherent_data_provider(&inherent_data_providers)?; - let verifier = PowVerifier { - client: client.clone(), + let verifier = PowVerifier::new( + client.clone(), algorithm, + check_inherents_after, + select_chain, inherent_data_providers, - }; + ); Ok(BasicQueue::new( verifier, @@ -296,19 +331,24 @@ pub fn import_queue( /// information, or just be a graffiti. `round` is for number of rounds the /// CPU miner runs each time. This parameter should be tweaked so that each /// mining round is within sub-second time. -pub fn start_mine, C, Algorithm, E>( +pub fn start_mine, C, Algorithm, E, SO, S>( mut block_import: BoxBlockImport, client: Arc, algorithm: Algorithm, mut env: E, preruntime: Option>, round: u32, + mut sync_oracle: SO, + build_time: std::time::Duration, + select_chain: Option, inherent_data_providers: inherents::InherentDataProviders, ) where C: HeaderBackend + AuxStore + 'static, Algorithm: PowAlgorithm + Send + Sync + 'static, E: Environment + Send + Sync + 'static, E::Error: std::fmt::Debug, + SO: SyncOracle + Send + Sync + 'static, + S: SelectChain + 'static, { if let Err(_) = register_pow_inherent_data_provider(&inherent_data_providers) { warn!("Registering inherent data provider for timestamp failed"); @@ -323,6 +363,9 @@ pub fn start_mine, C, Algorithm, E>( &mut env, preruntime.as_ref(), round, + &mut sync_oracle, + build_time.clone(), + select_chain.as_ref(), &inherent_data_providers ) { Ok(()) => (), @@ -331,31 +374,52 @@ pub fn start_mine, C, Algorithm, E>( e ), } - std::thread::sleep(std::time::Duration::new(1, 0)); } }); } -fn mine_loop, C, Algorithm, E>( +fn mine_loop, C, Algorithm, E, SO, S>( block_import: &mut BoxBlockImport, client: &C, algorithm: &Algorithm, env: &mut E, preruntime: Option<&Vec>, round: u32, + sync_oracle: &mut SO, + build_time: std::time::Duration, + select_chain: Option<&S>, inherent_data_providers: &inherents::InherentDataProviders, ) -> Result<(), String> where C: HeaderBackend + AuxStore, Algorithm: PowAlgorithm, E: Environment, E::Error: std::fmt::Debug, + SO: SyncOracle, + S: SelectChain, { 'outer: loop { - let best_hash = client.info().best_hash; - let best_header = client.header(BlockId::Hash(best_hash)) - .map_err(|e| format!("Fetching best header failed: {:?}", e))? - .ok_or("Best header does not exist")?; + if sync_oracle.is_major_syncing() { + debug!(target: "pow", "Skipping proposal due to sync."); + std::thread::sleep(std::time::Duration::new(1, 0)); + continue 'outer + } + + let (best_hash, best_header) = match select_chain { + Some(select_chain) => { + let header = select_chain.best_chain() + .map_err(|e| format!("Fetching best header failed using select chain: {:?}", e))?; + let hash = header.hash(); + (hash, header) + }, + None => { + let hash = client.info().best_hash; + let header = client.header(BlockId::Hash(hash)) + .map_err(|e| format!("Fetching best header failed: {:?}", e))? + .ok_or("Best header does not exist")?; + (hash, header) + }, + }; let mut aux = PowAux::read(client, &best_hash)?; let mut proposer = env.init(&best_header).map_err(|e| format!("{:?}", e))?; @@ -368,21 +432,19 @@ fn mine_loop, C, Algorithm, E>( let block = futures::executor::block_on(proposer.propose( inherent_data, inherent_digest, - std::time::Duration::new(0, 0) + build_time.clone(), )).map_err(|e| format!("Block proposing error: {:?}", e))?; let (header, body) = block.deconstruct(); - let seed = H256::random(); let (difficulty, seal) = { - loop { - let difficulty = algorithm.difficulty( - &BlockId::Hash(best_hash), - )?; + let difficulty = algorithm.difficulty( + &BlockId::Hash(best_hash), + )?; + loop { let seal = algorithm.mine( &BlockId::Hash(best_hash), &header.hash(), - &seed, difficulty, round, )?; @@ -397,10 +459,28 @@ fn mine_loop, C, Algorithm, E>( } }; - aux.total_difficulty = aux.total_difficulty.saturating_add(difficulty); - let hash = header.hash(); + aux.difficulty = difficulty; + aux.total_difficulty.increment(difficulty); + let hash = { + let mut header = header.clone(); + header.digest_mut().push(DigestItem::Seal(POW_ENGINE_ID, seal.clone())); + header.hash() + }; let key = aux_key(&hash); + let best_hash = match select_chain { + Some(select_chain) => select_chain.best_chain() + .map_err(|e| format!("Fetch best hash failed via select chain: {:?}", e))? + .hash(), + None => client.info().best_hash, + }; + let best_aux = PowAux::::read(client, &best_hash)?; + + // if the best block has changed in the meantime drop our proposal + if best_aux.total_difficulty > aux.total_difficulty { + continue 'outer + } + let import_block = BlockImportParams { origin: BlockOrigin::Own, header, diff --git a/core/network/src/chain.rs b/core/network/src/chain.rs index 1a1f649cae..f68942fd96 100644 --- a/core/network/src/chain.rs +++ b/core/network/src/chain.rs @@ -83,6 +83,12 @@ pub trait FinalityProofProvider: Send + Sync { fn prove_finality(&self, for_block: Block::Hash, request: &[u8]) -> Result>, Error>; } +impl FinalityProofProvider for () { + fn prove_finality(&self, _for_block: Block::Hash, _request: &[u8]) -> Result>, Error> { + Ok(None) + } +} + impl Client for SubstrateClient where B: client::backend::Backend + Send + Sync + 'static, E: CallExecutor + Send + Sync + 'static, -- GitLab From 73104d3ae1ec061c4efd981a83cdd09104ba159f Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Thu, 3 Oct 2019 12:37:37 +0200 Subject: [PATCH 177/275] Split off TypeId so as not to pull in sr-io (#3740) * Add type-id * Builds with std now. * Fix for cargo * Remove unneeded stuff * Move TypeId. --- core/primitives/src/lib.rs | 5 +++++ core/sr-primitives/src/lib.rs | 4 ++-- core/sr-primitives/src/traits.rs | 8 +------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/core/primitives/src/lib.rs b/core/primitives/src/lib.rs index 8086c9832a..310f0133ef 100644 --- a/core/primitives/src/lib.rs +++ b/core/primitives/src/lib.rs @@ -219,3 +219,8 @@ impl codec::Decode for NeverNativeValue { } } +/// Provide a simple 4 byte identifier for a type. +pub trait TypeId { + /// Simple 4 byte identifier. + const TYPE_ID: [u8; 4]; +} diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index 1e26a3d423..bdcbfb0b46 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -56,7 +56,7 @@ pub mod weights; pub use generic::{DigestItem, Digest}; /// Re-export this since it's part of the API of this crate. -pub use primitives::crypto::{key_types, KeyTypeId, CryptoType}; +pub use primitives::{TypeId, crypto::{key_types, KeyTypeId, CryptoType}}; pub use app_crypto::RuntimeAppPublic; /// Re-export arithmetic stuff. @@ -82,7 +82,7 @@ use traits::{Verify, Lazy}; #[derive(Clone, Copy, Eq, PartialEq, Encode, Decode)] pub struct ModuleId(pub [u8; 8]); -impl traits::TypeId for ModuleId { +impl TypeId for ModuleId { const TYPE_ID: [u8; 4] = *b"modl"; } diff --git a/core/sr-primitives/src/traits.rs b/core/sr-primitives/src/traits.rs index de200bdf55..10c2e80658 100644 --- a/core/sr-primitives/src/traits.rs +++ b/core/sr-primitives/src/traits.rs @@ -23,7 +23,7 @@ use runtime_io; use std::fmt::{Debug, Display}; #[cfg(feature = "std")] use serde::{Serialize, Deserialize, de::DeserializeOwned}; -use primitives::{self, Hasher, Blake2Hasher}; +use primitives::{self, Hasher, Blake2Hasher, TypeId}; use crate::codec::{Codec, Encode, Decode, HasCompact}; use crate::transaction_validity::{ ValidTransaction, TransactionValidity, TransactionValidityError, UnknownTransaction, @@ -1123,12 +1123,6 @@ pub trait AccountIdConversion: Sized { fn try_from_sub_account(x: &AccountId) -> Option<(Self, S)>; } -/// Provide a simple 4 byte identifier for a type. -pub trait TypeId { - /// Simple 4 byte identifier. - const TYPE_ID: [u8; 4]; -} - /// Format is TYPE_ID ++ encode(parachain ID) ++ 00.... where 00... is indefinite trailing zeroes to /// fill AccountId. impl AccountIdConversion for Id { -- GitLab From f17d023bbe179f15678ac9989f471c9b18917e17 Mon Sep 17 00:00:00 2001 From: Joshy Orndorff Date: Thu, 3 Oct 2019 23:12:06 -0800 Subject: [PATCH 178/275] Grammar (#3754) --- core/consensus/pow/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/consensus/pow/src/lib.rs b/core/consensus/pow/src/lib.rs index 7f282e2052..766c1c63e0 100644 --- a/core/consensus/pow/src/lib.rs +++ b/core/consensus/pow/src/lib.rs @@ -100,7 +100,7 @@ pub trait PowAlgorithm { seal: &Seal, difficulty: Self::Difficulty, ) -> Result; - /// Mine a seal that satisfy the given difficulty. + /// Mine a seal that satisfies the given difficulty. fn mine( &self, parent: &BlockId, -- GitLab From 3dedd246c62255ba6f9b777ecba318dfc2078d85 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Fri, 4 Oct 2019 14:56:41 +0200 Subject: [PATCH 179/275] Decouple BABE from session (#3760) --- core/test-runtime/src/lib.rs | 4 + node-template/runtime/src/lib.rs | 1 + node/runtime/src/lib.rs | 3 +- srml/babe/src/lib.rs | 171 +++++++++++++++++++++---------- srml/babe/src/mock.rs | 1 + 5 files changed, 125 insertions(+), 55 deletions(-) diff --git a/core/test-runtime/src/lib.rs b/core/test-runtime/src/lib.rs index ff9826acae..e75cb69149 100644 --- a/core/test-runtime/src/lib.rs +++ b/core/test-runtime/src/lib.rs @@ -405,6 +405,10 @@ parameter_types! { impl srml_babe::Trait for Runtime { type EpochDuration = EpochDuration; type ExpectedBlockTime = ExpectedBlockTime; + // there is no actual runtime in this test-runtime, so testing crates + // are manually adding the digests. normally in this situation you'd use + // srml_babe::SameAuthoritiesForever. + type EpochChangeTrigger = srml_babe::ExternalTrigger; } /// Adds one to the given input and returns the final result. diff --git a/node-template/runtime/src/lib.rs b/node-template/runtime/src/lib.rs index 6b2b335d68..216cb0edc2 100644 --- a/node-template/runtime/src/lib.rs +++ b/node-template/runtime/src/lib.rs @@ -189,6 +189,7 @@ parameter_types! { impl babe::Trait for Runtime { type EpochDuration = EpochDuration; type ExpectedBlockTime = ExpectedBlockTime; + type EpochChangeTrigger = babe::SameAuthoritiesForever; } impl grandpa::Trait for Runtime { diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 190385d6bc..490c2f300f 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -84,7 +84,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 170, + spec_version: 171, impl_version: 171, apis: RUNTIME_API_VERSIONS, }; @@ -142,6 +142,7 @@ parameter_types! { impl babe::Trait for Runtime { type EpochDuration = EpochDuration; type ExpectedBlockTime = ExpectedBlockTime; + type EpochChangeTrigger = babe::ExternalTrigger; } impl indices::Trait for Runtime { diff --git a/srml/babe/src/lib.rs b/srml/babe/src/lib.rs index 330ec89ba5..e69877d783 100644 --- a/srml/babe/src/lib.rs +++ b/srml/babe/src/lib.rs @@ -122,8 +122,52 @@ impl ProvideInherentData for InherentDataProvider { } pub trait Trait: timestamp::Trait { + /// The amount of time, in slots, that each epoch should last. type EpochDuration: Get; + + /// The expected average block time at which BABE should be creating + /// blocks. Since BABE is probabilistic it is not trivial to figure out + /// what the expected average block time should be based on the slot + /// duration and the security parameter `c` (where `1 - c` represents + /// the probability of a slot being empty). type ExpectedBlockTime: Get; + + /// BABE requires some logic to be triggered on every block to query for whether an epoch + /// has ended and to perform the transition to the next epoch. + /// + /// Typically, the `ExternalTrigger` type should be used. An internal trigger should only be used + /// when no other module is responsible for changing authority set. + type EpochChangeTrigger: EpochChangeTrigger; +} + +/// Trigger an epoch change, if any should take place. +pub trait EpochChangeTrigger { + /// Trigger an epoch change, if any should take place. This should be called + /// during every block, after initialization is done. + fn trigger(now: T::BlockNumber); +} + +/// A type signifying to BABE that an external trigger +/// for epoch changes (e.g. srml-session) is used. +pub struct ExternalTrigger; + +impl EpochChangeTrigger for ExternalTrigger { + fn trigger(_: T::BlockNumber) { } // nothing - trigger is external. +} + +/// A type signifying to BABE that it should perform epoch changes +/// with an internal trigger, recycling the same authorities forever. +pub struct SameAuthoritiesForever; + +impl EpochChangeTrigger for SameAuthoritiesForever { + fn trigger(now: T::BlockNumber) { + if >::should_epoch_change(now) { + let authorities = >::authorities(); + let next_authorities = authorities.clone(); + + >::enact_epoch_change(authorities, next_authorities); + } + } } /// The length of the BABE randomness @@ -203,8 +247,8 @@ decl_module! { const ExpectedBlockTime: T::Moment = T::ExpectedBlockTime::get(); /// Initialization - fn on_initialize() { - Self::do_initialize(); + fn on_initialize(now: T::BlockNumber) { + Self::do_initialize(now); } /// Block finalization @@ -263,21 +307,10 @@ impl session::ShouldEndSession for Module { // it might be (and it is in current implementation) that session module is calling // should_end_session() from it's own on_initialize() handler // => because session on_initialize() is called earlier than ours, let's ensure - // that we have synced with digest before checking if session should be ended - Self::do_initialize(); + // that we have synced with digest before checking if session should be ended. + Self::do_initialize(now); - // The session has technically ended during the passage of time - // between this block and the last, but we have to "end" the session now, - // since there is no earlier possible block we could have done it. - // - // The exception is for block 1: the genesis has slot 0, so we treat - // epoch 0 as having started at the slot of block 1. We want to use - // the same randomness and validator set as signalled in the genesis, - // so we don't rotate the session. - now != sr_primitives::traits::One::one() && { - let diff = CurrentSlot::get().saturating_sub(Self::current_epoch_start()); - diff >= T::EpochDuration::get() - } + Self::should_epoch_change(now) } } @@ -336,6 +369,69 @@ impl Module { ::MinimumPeriod::get().saturating_mul(2.into()) } + /// Determine whether an epoch change should take place at this block. + /// Assumes that initialization has already taken place. + pub fn should_epoch_change(now: T::BlockNumber) -> bool { + // The epoch has technically ended during the passage of time + // between this block and the last, but we have to "end" the epoch now, + // since there is no earlier possible block we could have done it. + // + // The exception is for block 1: the genesis has slot 0, so we treat + // epoch 0 as having started at the slot of block 1. We want to use + // the same randomness and validator set as signalled in the genesis, + // so we don't rotate the epoch. + now != sr_primitives::traits::One::one() && { + let diff = CurrentSlot::get().saturating_sub(Self::current_epoch_start()); + diff >= T::EpochDuration::get() + } + } + + /// DANGEROUS: Enact an epoch change. Should be done on every block where `should_epoch_change` has returned `true`, + /// and the caller is the only caller of this function. + /// + /// Typically, this is not handled directly by the user, but by higher-level validator-set manager logic like + /// `srml-session`. + pub fn enact_epoch_change( + authorities: Vec<(AuthorityId, BabeAuthorityWeight)>, + next_authorities: Vec<(AuthorityId, BabeAuthorityWeight)>, + ) { + // PRECONDITION: caller has done initialization and is guaranteed + // by the session module to be called before this. + #[cfg(debug_assertions)] + { + assert!(Self::initialized().is_some()) + } + + // Update epoch index + let epoch_index = EpochIndex::get() + .checked_add(1) + .expect("epoch indices will never reach 2^64 before the death of the universe; qed"); + + EpochIndex::put(epoch_index); + Authorities::put(authorities); + + // Update epoch randomness. + let next_epoch_index = epoch_index + .checked_add(1) + .expect("epoch indices will never reach 2^64 before the death of the universe; qed"); + + // Returns randomness for the current epoch and computes the *next* + // epoch randomness. + let randomness = Self::randomness_change_epoch(next_epoch_index); + Randomness::put(randomness); + + // After we update the current epoch, we signal the *next* epoch change + // so that nodes can track changes. + let next_randomness = NextRandomness::get(); + + let next = NextEpochDescriptor { + authorities: next_authorities, + randomness: next_randomness, + }; + + Self::deposit_consensus(ConsensusLog::NextEpochData(next)) + } + // finds the start slot of the current epoch. only guaranteed to // give correct results after `do_initialize` of the first block // in the chain (as its result is based off of `GenesisSlot`). @@ -363,7 +459,7 @@ impl Module { } } - fn do_initialize() { + fn do_initialize(now: T::BlockNumber) { // since do_initialize can be called twice (if session module is present) // => let's ensure that we only modify the storage once per block let initialized = Self::initialized().is_some(); @@ -414,6 +510,9 @@ impl Module { }); Initialized::put(maybe_vrf); + + // enact epoch change, if necessary. + T::EpochChangeTrigger::trigger::(now) } /// Call this function exactly once when an epoch changes, to update the @@ -460,51 +559,15 @@ impl session::OneSessionHandler for Module { fn on_new_session<'a, I: 'a>(_changed: bool, validators: I, queued_validators: I) where I: Iterator { - // PRECONDITION: `should_end_session` has done initialization and is guaranteed - // by the session module to be called before this. - #[cfg(debug_assertions)] - { - assert!(Self::initialized().is_some()) - } - - // Update epoch index - let epoch_index = EpochIndex::get() - .checked_add(1) - .expect("epoch indices will never reach 2^64 before the death of the universe; qed"); - - EpochIndex::put(epoch_index); - - // Update authorities. let authorities = validators.map(|(_account, k)| { (k, 1) }).collect::>(); - Authorities::put(authorities); - - // Update epoch randomness. - let next_epoch_index = epoch_index - .checked_add(1) - .expect("epoch indices will never reach 2^64 before the death of the universe; qed"); - - // Returns randomness for the current epoch and computes the *next* - // epoch randomness. - let randomness = Self::randomness_change_epoch(next_epoch_index); - Randomness::put(randomness); - - // After we update the current epoch, we signal the *next* epoch change - // so that nodes can track changes. let next_authorities = queued_validators.map(|(_account, k)| { (k, 1) }).collect::>(); - let next_randomness = NextRandomness::get(); - - let next = NextEpochDescriptor { - authorities: next_authorities, - randomness: next_randomness, - }; - - Self::deposit_consensus(ConsensusLog::NextEpochData(next)) + Self::enact_epoch_change(authorities, next_authorities) } fn on_disabled(i: usize) { diff --git a/srml/babe/src/mock.rs b/srml/babe/src/mock.rs index 741f08fc08..acc08c7a3b 100644 --- a/srml/babe/src/mock.rs +++ b/srml/babe/src/mock.rs @@ -98,6 +98,7 @@ impl timestamp::Trait for Test { impl Trait for Test { type EpochDuration = EpochDuration; type ExpectedBlockTime = ExpectedBlockTime; + type EpochChangeTrigger = crate::ExternalTrigger; } pub fn new_test_ext(authorities: Vec) -> runtime_io::TestExternalities { -- GitLab From c0d293236a574f1297c59de1f8d53f06c8eb605e Mon Sep 17 00:00:00 2001 From: kaichao Date: Sat, 5 Oct 2019 01:00:18 +0800 Subject: [PATCH 180/275] Enable opt-in google analytics for RustDocs. (#3762) --- .gitlab-ci.yml | 2 +- rustdoc-header.html | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 rustdoc-header.html diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 60a75d5db4..a6ef113044 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -288,7 +288,7 @@ build-rust-doc-release: <<: *build-only script: - rm -f ./crate-docs/index.html # use it as an indicator if the job succeeds - - BUILD_DUMMY_WASM_BINARY=1 time cargo +nightly doc --release --all --verbose + - BUILD_DUMMY_WASM_BINARY=1 time RUSTDOCFLAGS="--html-in-header $(pwd)/rustdoc-header.html" cargo +nightly doc --release --all --verbose - cp -R ./target/doc ./crate-docs - echo "" > ./crate-docs/index.html - sccache -s diff --git a/rustdoc-header.html b/rustdoc-header.html new file mode 100644 index 0000000000..a679d5e299 --- /dev/null +++ b/rustdoc-header.html @@ -0,0 +1,10 @@ + + + + -- GitLab From 1774f6131e1ee1ffea7cd5e8127cc4ec3d237e8a Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Fri, 4 Oct 2019 19:13:54 +0200 Subject: [PATCH 181/275] Utility module for doing stuff like batch calls (#3759) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Implement and test batch * Add files. * Remove comments. * Update srml/utility/src/lib.rs Co-Authored-By: Bastian Köcher * Fixes --- Cargo.lock | 16 ++++ Cargo.toml | 1 + node/runtime/Cargo.toml | 2 + node/runtime/src/lib.rs | 6 ++ srml/assets/src/lib.rs | 9 ++- srml/utility/Cargo.toml | 30 +++++++ srml/utility/src/lib.rs | 173 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 233 insertions(+), 4 deletions(-) create mode 100644 srml/utility/Cargo.toml create mode 100644 srml/utility/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 7043341751..ca1270929f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2486,6 +2486,7 @@ dependencies = [ "srml-system 2.0.0", "srml-timestamp 2.0.0", "srml-treasury 2.0.0", + "srml-utility 2.0.0", "substrate-authority-discovery-primitives 2.0.0", "substrate-client 2.0.0", "substrate-consensus-babe-primitives 2.0.0", @@ -4421,6 +4422,21 @@ dependencies = [ "substrate-primitives 2.0.0", ] +[[package]] +name = "srml-utility" +version = "2.0.0" +dependencies = [ + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 2.0.0", + "sr-primitives 2.0.0", + "sr-std 2.0.0", + "srml-balances 2.0.0", + "srml-support 2.0.0", + "srml-system 2.0.0", + "substrate-primitives 2.0.0", +] + [[package]] name = "stable_deref_trait" version = "1.1.1" diff --git a/Cargo.toml b/Cargo.toml index a345b880da..71ba1c17f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -103,6 +103,7 @@ members = [ "srml/system", "srml/timestamp", "srml/treasury", + "srml/utility", "node/cli", "node/executor", "node/primitives", diff --git a/node/runtime/Cargo.toml b/node/runtime/Cargo.toml index 9b794130e7..f256575086 100644 --- a/node/runtime/Cargo.toml +++ b/node/runtime/Cargo.toml @@ -48,6 +48,7 @@ support = { package = "srml-support", path = "../../srml/support", default-featu system = { package = "srml-system", path = "../../srml/system", default-features = false } timestamp = { package = "srml-timestamp", path = "../../srml/timestamp", default-features = false } treasury = { package = "srml-treasury", path = "../../srml/treasury", default-features = false } +utility = { package = "srml-utility", path = "../../srml/utility", default-features = false } [build-dependencies] wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.2", path = "../../core/utils/wasm-builder-runner" } @@ -92,5 +93,6 @@ std = [ "system/std", "timestamp/std", "treasury/std", + "utility/std", "version/std", ] diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 490c2f300f..b06ba19ee5 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -134,6 +134,11 @@ impl system::Trait for Runtime { type Version = Version; } +impl utility::Trait for Runtime { + type Event = Event; + type Call = Call; +} + parameter_types! { pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS; pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; @@ -492,6 +497,7 @@ construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic { System: system::{Module, Call, Storage, Config, Event}, + Utility: utility::{Module, Call, Event}, Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)}, Timestamp: timestamp::{Module, Call, Storage, Inherent}, Authorship: authorship::{Module, Call, Storage, Inherent}, diff --git a/srml/assets/src/lib.rs b/srml/assets/src/lib.rs index b143085232..2a4245176a 100644 --- a/srml/assets/src/lib.rs +++ b/srml/assets/src/lib.rs @@ -196,10 +196,11 @@ decl_module! { } decl_event!( - pub enum Event - where ::AccountId, - ::Balance, - ::AssetId { + pub enum Event where + ::AccountId, + ::Balance, + ::AssetId, + { /// Some assets were issued. Issued(AssetId, AccountId, Balance), /// Some assets were transferred. diff --git a/srml/utility/Cargo.toml b/srml/utility/Cargo.toml new file mode 100644 index 0000000000..d46ed62a55 --- /dev/null +++ b/srml/utility/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "srml-utility" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +serde = { version = "1.0", optional = true } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } +system = { package = "srml-system", path = "../system", default-features = false } +sr-primitives = { path = "../../core/sr-primitives", default-features = false } +rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } +runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false } + +[dev-dependencies] +primitives = { package = "substrate-primitives", path = "../../core/primitives" } +balances = { package = "srml-balances", path = "../balances" } + +[features] +default = ["std"] +std = [ + "serde", + "codec/std", + "sr-primitives/std", + "support/std", + "system/std", + "runtime-io/std", + "rstd/std" +] diff --git a/srml/utility/src/lib.rs b/srml/utility/src/lib.rs new file mode 100644 index 0000000000..9fe34ee2d0 --- /dev/null +++ b/srml/utility/src/lib.rs @@ -0,0 +1,173 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! # Utility Module +//! A module full of useful helpers for practical chain management. + +// Ensure we're `no_std` when compiling for Wasm. +#![cfg_attr(not(feature = "std"), no_std)] + +use rstd::prelude::*; +use support::{decl_module, decl_event, Parameter}; +use system::ensure_root; +use sr_primitives::{ + traits::{Dispatchable, DispatchResult}, weights::SimpleDispatchInfo +}; + +/// Configuration trait. +pub trait Trait: system::Trait { + /// The overarching event type. + type Event: From> + Into<::Event>; + + /// The overarching call type. + type Call: Parameter + Dispatchable; +} + +pub type DispatchResultOf = DispatchResult<<::Call as Dispatchable>::Error>; + +decl_event!( + /// Events type. + pub enum Event where + DispatchResult = DispatchResultOf, + { + BatchExecuted(Vec), + } +); + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + /// Deposit one of this module's events by using the default implementation. + fn deposit_event() = default; + + /// Send a batch of dispatch calls (only root). + #[weight = SimpleDispatchInfo::FreeOperational] + fn batch(origin, calls: Vec<::Call>) { + ensure_root(origin)?; + let results = calls.into_iter() + .map(|call| call.dispatch(system::RawOrigin::Root.into())) + .collect::>(); + Self::deposit_event(RawEvent::BatchExecuted(results)); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use support::{assert_ok, assert_noop, impl_outer_origin, parameter_types, impl_outer_dispatch}; + use runtime_io::with_externalities; + use primitives::{H256, Blake2Hasher}; + use sr_primitives::{ + Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header + }; + + impl_outer_origin! { + pub enum Origin for Test {} + } + + impl_outer_dispatch! { + pub enum Call for Test where origin: Origin { + balances::Balances, + utility::Utility, + } + } + + // For testing the module, we construct most of a mock runtime. This means + // first constructing a configuration type (`Test`) which `impl`s each of the + // configuration traits of modules we want to use. + #[derive(Clone, Eq, PartialEq)] + pub struct Test; + parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + } + impl system::Trait for Test { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Call = Call; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type WeightMultiplierUpdate = (); + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + } + parameter_types! { + pub const ExistentialDeposit: u64 = 0; + pub const TransferFee: u64 = 0; + pub const CreationFee: u64 = 0; + pub const TransactionBaseFee: u64 = 0; + pub const TransactionByteFee: u64 = 0; + } + impl balances::Trait for Test { + type Balance = u64; + type OnFreeBalanceZero = (); + type OnNewAccount = (); + type Event = (); + type TransactionPayment = (); + type TransferPayment = (); + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type TransferFee = TransferFee; + type CreationFee = CreationFee; + type TransactionBaseFee = TransactionBaseFee; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = (); + } + impl Trait for Test { + type Event = (); + type Call = Call; + } + type Balances = balances::Module; + type Utility = Module; + + fn new_test_ext() -> runtime_io::TestExternalities { + let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + balances::GenesisConfig:: { + balances: vec![(1, 10), (2, 0)], + vesting: vec![], + }.assimilate_storage(&mut t).unwrap(); + t.into() + } + + #[test] + fn batch_works() { + with_externalities(&mut new_test_ext(), || { + assert_eq!(Balances::free_balance(1), 10); + assert_eq!(Balances::free_balance(2), 0); + assert_noop!(Utility::batch(Origin::signed(1), vec![ + Call::Balances(balances::Call::force_transfer(1, 2, 5)), + Call::Balances(balances::Call::force_transfer(1, 2, 5)) + ]), "RequireRootOrigin"); + assert_ok!(Utility::batch(Origin::ROOT, vec![ + Call::Balances(balances::Call::force_transfer(1, 2, 5)), + Call::Balances(balances::Call::force_transfer(1, 2, 5)) + ])); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::free_balance(2), 10); + }); + } +} -- GitLab From b4cd2485d5070cdb6c4f9c2bdbc31be0f9fff65c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Fri, 4 Oct 2019 18:51:08 +0100 Subject: [PATCH 182/275] babe: ancient epoch tree pruning (#3746) * babe: prune epoch tree when importing a new epoch change * fork-tree: fix tree pruning * babe: actually prune epoch change fork tree * Fix typos * babe: add test for epoch tree pruning * fork-tree: fix pruning of stale forks --- core/consensus/babe/src/epoch_changes.rs | 38 ++++-- core/consensus/babe/src/lib.rs | 78 ++++++----- core/consensus/babe/src/tests.rs | 161 +++++++++++++++++++++++ core/utils/fork-tree/src/lib.rs | 88 +++++++------ 4 files changed, 280 insertions(+), 85 deletions(-) diff --git a/core/consensus/babe/src/epoch_changes.rs b/core/consensus/babe/src/epoch_changes.rs index 311271ae15..09a14d2864 100644 --- a/core/consensus/babe/src/epoch_changes.rs +++ b/core/consensus/babe/src/epoch_changes.rs @@ -190,23 +190,35 @@ impl EpochChanges where EpochChanges { inner: ForkTree::new() } } - /// Prune out finalized epochs, except for the ancestor of the finalized block. + /// Prune out finalized epochs, except for the ancestor of the finalized + /// block. The given slot should be the slot number at which the finalized + /// block was authored. pub fn prune_finalized>( &mut self, descendent_of_builder: D, - _hash: &Hash, - _number: Number, + hash: &Hash, + number: Number, + slot: SlotNumber, ) -> Result<(), fork_tree::Error> { - let _is_descendent_of = descendent_of_builder + let is_descendent_of = descendent_of_builder .build_is_descendent_of(None); - // TODO: - // https://github.com/paritytech/substrate/issues/3651 - // + let predicate = |epoch: &PersistedEpoch| match *epoch { + PersistedEpoch::Genesis(_, ref epoch_1) => + slot >= epoch_1.end_slot(), + PersistedEpoch::Regular(ref epoch_n) => + slot >= epoch_n.end_slot(), + }; + // prune any epochs which could not be _live_ as of the children of the - // finalized block. - // i.e. re-root the fork tree to the oldest ancestor of (hash, number) - // where epoch.end_slot() >= slot(hash) + // finalized block, i.e. re-root the fork tree to the oldest ancestor of + // (hash, number) where epoch.end_slot() >= finalized_slot + self.inner.prune( + hash, + &number, + &is_descendent_of, + &predicate, + )?; Ok(()) } @@ -300,6 +312,12 @@ impl EpochChanges where Err(e) => Err(e), } } + + /// Return the inner fork tree, useful for testing purposes. + #[cfg(test)] + pub fn tree(&self) -> &ForkTree { + &self.inner + } } /// Type alias to produce the epoch-changes tree from a block type. diff --git a/core/consensus/babe/src/lib.rs b/core/consensus/babe/src/lib.rs index d2a16bedb8..b4f376b50d 100644 --- a/core/consensus/babe/src/lib.rs +++ b/core/consensus/babe/src/lib.rs @@ -254,24 +254,6 @@ pub fn start_babe(BabeParams { &inherent_data_providers, )?; - let epoch_changes = babe_link.epoch_changes.clone(); - let pruning_task = client.finality_notification_stream() - .for_each(move |notification| { - // TODO: supply is-descendent-of and maybe write to disk _now_ - // as opposed to waiting for the next epoch? - let res = epoch_changes.lock().prune_finalized( - descendent_query(&*client), - ¬ification.hash, - *notification.header.number(), - ); - - if let Err(e) = res { - babe_err!("Could not prune expired epoch changes: {:?}", e); - } - - future::ready(()) - }); - babe_info!("Starting BABE Authorship worker"); let slot_worker = slots::start_slot_worker( config.0, @@ -280,9 +262,9 @@ pub fn start_babe(BabeParams { sync_oracle, inherent_data_providers, babe_link.time_source, - ).map(|_| ()); + ); - Ok(future::select(slot_worker, pruning_task).map(|_| Ok::<(), ()>(())).compat()) + Ok(slot_worker.map(|_| Ok::<(), ()>(())).compat()) } struct BabeWorker { @@ -889,6 +871,8 @@ impl BlockImport for BabeBlockImport BlockImport for BabeBlockImport(&finalized_header) + .expect("finalized header must be valid; \ + valid blocks have a pre-digest; qed") + .slot_number() + }; + epoch_changes.prune_finalized( + descendent_query(&*self.client), + &info.finalized_hash, + info.finalized_number, + finalized_slot, + ).map_err(|e| ConsensusError::ClientImport(format!("{:?}", e)))?; + + epoch_changes.import( + descendent_query(&*self.client), + hash, + number, + *block.header.parent_hash(), + next_epoch, + ).map_err(|e| ConsensusError::ClientImport(format!("{:?}", e)))?; + + Ok(()) + }; - if let Err(e) = res { - let err = ConsensusError::ClientImport(format!("{:?}", e)); + if let Err(e) = prune_and_import() { babe_err!("Failed to launch next epoch: {:?}", e); *epoch_changes = old_epoch_changes.expect("set `Some` above and not taken; qed"); - return Err(err); + return Err(e); } crate::aux_schema::write_epoch_changes::( @@ -935,10 +946,7 @@ impl BlockImport for BabeBlockImport b, Err(e) => return future::ready(Err(e)), @@ -597,3 +598,163 @@ fn importing_block_one_sets_genesis_epoch() { ).unwrap().unwrap().into_inner(); assert_eq!(epoch_for_second_block, genesis_epoch); } + +#[test] +fn importing_epoch_change_block_prunes_tree() { + use client::backend::Finalizer; + + let mut net = BabeTestNet::new(1); + + let peer = net.peer(0); + let data = peer.data.as_ref().expect("babe link set up during initialization"); + + let client = peer.client().as_full().expect("Only full clients are used in tests").clone(); + let mut block_import = data.block_import.lock().take().expect("import set up during init"); + let epoch_changes = data.link.epoch_changes.clone(); + + // This is just boilerplate code for proposing and importing a valid BABE + // block that's built on top of the given parent. The proposer takes care + // of producing epoch change digests according to the epoch duration (which + // is set to 6 slots in the test runtime). + let mut propose_and_import_block = |parent_header| { + let mut environ = DummyFactory { + client: client.clone(), + config: data.link.config.clone(), + epoch_changes: data.link.epoch_changes.clone(), + mutator: Arc::new(|_, _| ()), + }; + + let mut proposer = environ.init(&parent_header).unwrap(); + let parent_pre_digest = find_pre_digest::(&parent_header).unwrap(); + + let pre_digest = sr_primitives::generic::Digest { + logs: vec![ + Item::babe_pre_digest( + BabePreDigest::Secondary { + authority_index: 0, + slot_number: parent_pre_digest.slot_number() + 1, + }, + ), + ], + }; + + let mut block = futures::executor::block_on(proposer.propose_with(pre_digest)).unwrap(); + + let seal = { + // sign the pre-sealed hash of the block and then + // add it to a digest item. + let pair = AuthorityPair::from_seed(&[1; 32]); + let pre_hash = block.header.hash(); + let signature = pair.sign(pre_hash.as_ref()); + Item::babe_seal(signature) + }; + + let post_hash = { + block.header.digest_mut().push(seal.clone()); + let h = block.header.hash(); + block.header.digest_mut().pop(); + h + }; + + let next_epoch_digest = + find_next_epoch_digest::(&block.header).unwrap(); + + let import_result = block_import.import_block( + BlockImportParams { + origin: BlockOrigin::Own, + header: block.header, + justification: None, + post_digests: vec![seal], + body: Some(block.extrinsics), + finalized: false, + auxiliary: Vec::new(), + fork_choice: ForkChoiceStrategy::LongestChain, + }, + Default::default(), + ).unwrap(); + + match import_result { + ImportResult::Imported(_) => {}, + _ => panic!("expected block to be imported"), + } + + (post_hash, next_epoch_digest) + }; + + let mut propose_and_import_blocks = |parent_id, n| { + let mut hashes = Vec::new(); + let mut parent_header = client.header(&parent_id).unwrap().unwrap(); + + for _ in 0..n { + let (block_hash, _) = propose_and_import_block(parent_header); + hashes.push(block_hash); + parent_header = client.header(&BlockId::Hash(block_hash)).unwrap().unwrap(); + } + + hashes + }; + + // This is the block tree that we're going to use in this test. Each node + // represents an epoch change block, the epoch duration is 6 slots. + // + // *---- F (#7) + // / *------ G (#19) - H (#25) + // / / + // A (#1) - B (#7) - C (#13) - D (#19) - E (#25) + // \ + // *------ I (#25) + + // Create and import the canon chain and keep track of fork blocks (A, C, D) + // from the diagram above. + let canon_hashes = propose_and_import_blocks(BlockId::Number(0), 30); + + // Create the forks + let fork_1 = propose_and_import_blocks(BlockId::Hash(canon_hashes[0]), 10); + let fork_2 = propose_and_import_blocks(BlockId::Hash(canon_hashes[12]), 15); + let fork_3 = propose_and_import_blocks(BlockId::Hash(canon_hashes[18]), 10); + + // We should be tracking a total of 9 epochs in the fork tree + assert_eq!( + epoch_changes.lock().tree().iter().count(), + 9, + ); + + // And only one root + assert_eq!( + epoch_changes.lock().tree().roots().count(), + 1, + ); + + // We finalize block #13 from the canon chain, so on the next epoch + // change the tree should be pruned, to not contain F (#7). + client.finalize_block(BlockId::Hash(canon_hashes[12]), None, false).unwrap(); + propose_and_import_blocks(BlockId::Hash(client.info().chain.best_hash), 7); + + // at this point no hashes from the first fork must exist on the tree + assert!( + !epoch_changes.lock().tree().iter().map(|(h, _, _)| h).any(|h| fork_1.contains(h)), + ); + + // but the epoch changes from the other forks must still exist + assert!( + epoch_changes.lock().tree().iter().map(|(h, _, _)| h).any(|h| fork_2.contains(h)) + ); + + assert!( + epoch_changes.lock().tree().iter().map(|(h, _, _)| h).any(|h| fork_3.contains(h)), + ); + + // finalizing block #25 from the canon chain should prune out the second fork + client.finalize_block(BlockId::Hash(canon_hashes[24]), None, false).unwrap(); + propose_and_import_blocks(BlockId::Hash(client.info().chain.best_hash), 8); + + // at this point no hashes from the second fork must exist on the tree + assert!( + !epoch_changes.lock().tree().iter().map(|(h, _, _)| h).any(|h| fork_2.contains(h)), + ); + + // while epoch changes from the last fork should still exist + assert!( + epoch_changes.lock().tree().iter().map(|(h, _, _)| h).any(|h| fork_3.contains(h)), + ); +} diff --git a/core/utils/fork-tree/src/lib.rs b/core/utils/fork-tree/src/lib.rs index 4299918755..b0258a9ca2 100644 --- a/core/utils/fork-tree/src/lib.rs +++ b/core/utils/fork-tree/src/lib.rs @@ -86,55 +86,45 @@ impl ForkTree where N: Ord + Clone, V: Clone, { - /// Prune all nodes that are not descendents of `hash` according to - /// `is_descendent_of`. The given function `is_descendent_of` should return - /// `true` if the second hash (target) is a descendent of the first hash - /// (base). After pruning the tree it should have one or zero roots. The - /// number and order of calls to `is_descendent_of` is unspecified and - /// subject to change. - pub fn prune( + /// Prune the tree, removing all non-canonical nodes. We find the node in the + /// tree that is the deepest ancestor of the given hash and that passes the + /// given predicate. If such a node exists, we re-root the tree to this + /// node. Otherwise the tree remains unchanged. The given function + /// `is_descendent_of` should return `true` if the second hash (target) is a + /// descendent of the first hash (base). + pub fn prune( &mut self, hash: &H, - number: N, - is_descendent_of: &F + number: &N, + is_descendent_of: &F, + predicate: &P, ) -> Result<(), Error> where E: std::error::Error, - F: Fn(&H, &H) -> Result + F: Fn(&H, &H) -> Result, + P: Fn(&V) -> bool, { - let mut new_root = None; - for node in self.node_iter() { - // if the node has a lower number than the one being finalized then - // we only keep if it has no children and the finalized block is a - // descendent of this node - if node.number < number { - if !node.children.is_empty() || !is_descendent_of(&node.hash, hash)? { - continue; - } - } - - // if the node has the same number as the finalized block then it - // must have the same hash - if node.number == number && node.hash != *hash { - continue; - } + let new_root = self.find_node_where( + hash, + number, + is_descendent_of, + predicate, + )?; - // if the node has a higher number then we keep it if it is a - // descendent of the finalized block - if node.number > number && !is_descendent_of(hash, &node.hash)? { - continue; - } + if let Some(root) = new_root { + let mut root = root.clone(); - new_root = Some(node); - break; - } + // we found the deepest ancestor of the finalized block, so we prune + // out any children that don't include the finalized block. + root.children.retain(|node| { + node.number == *number && node.hash == *hash || + node.number < *number && is_descendent_of(&node.hash, hash).unwrap_or(false) + }); - if let Some(root) = new_root { - self.roots = vec![root.clone()]; + self.roots = vec![root]; } Ok(()) } - } impl ForkTree where @@ -1203,18 +1193,36 @@ mod test { tree.prune( &"C", - 3, + &3, &is_descendent_of, + &|_| true, + ).unwrap(); + + assert_eq!( + tree.roots.iter().map(|node| node.hash).collect::>(), + vec!["B"], + ); + + assert_eq!( + tree.iter().map(|(hash, _, _)| *hash).collect::>(), + vec!["B", "C", "D", "E"], + ); + + tree.prune( + &"E", + &5, + &is_descendent_of, + &|_| true, ).unwrap(); assert_eq!( tree.roots.iter().map(|node| node.hash).collect::>(), - vec!["C"], + vec!["D"], ); assert_eq!( tree.iter().map(|(hash, _, _)| *hash).collect::>(), - vec!["C", "D", "E"], + vec!["D", "E"], ); } -- GitLab From fdac986a38db63bbaa413a0e211b98f55a185158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Fri, 4 Oct 2019 19:55:03 +0100 Subject: [PATCH 183/275] babe: small compilation fix (#3764) * babe: fix type on find_pre_digest call * fork-tree: optimize prune * babe: fix test compilation --- core/consensus/babe/src/lib.rs | 2 +- core/consensus/babe/src/tests.rs | 2 +- core/utils/fork-tree/src/lib.rs | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/core/consensus/babe/src/lib.rs b/core/consensus/babe/src/lib.rs index b4f376b50d..683425e815 100644 --- a/core/consensus/babe/src/lib.rs +++ b/core/consensus/babe/src/lib.rs @@ -896,7 +896,7 @@ impl BlockImport for BabeBlockImport(&finalized_header) + find_pre_digest::(&finalized_header) .expect("finalized header must be valid; \ valid blocks have a pre-digest; qed") .slot_number() diff --git a/core/consensus/babe/src/tests.rs b/core/consensus/babe/src/tests.rs index f06cc6f46c..46c038b187 100644 --- a/core/consensus/babe/src/tests.rs +++ b/core/consensus/babe/src/tests.rs @@ -625,7 +625,7 @@ fn importing_epoch_change_block_prunes_tree() { }; let mut proposer = environ.init(&parent_header).unwrap(); - let parent_pre_digest = find_pre_digest::(&parent_header).unwrap(); + let parent_pre_digest = find_pre_digest(&parent_header).unwrap(); let pre_digest = sr_primitives::generic::Digest { logs: vec![ diff --git a/core/utils/fork-tree/src/lib.rs b/core/utils/fork-tree/src/lib.rs index b0258a9ca2..f192ee5478 100644 --- a/core/utils/fork-tree/src/lib.rs +++ b/core/utils/fork-tree/src/lib.rs @@ -115,10 +115,11 @@ impl ForkTree where // we found the deepest ancestor of the finalized block, so we prune // out any children that don't include the finalized block. - root.children.retain(|node| { + let children = std::mem::replace(&mut root.children, Vec::new()); + root.children = children.into_iter().filter(|node| { node.number == *number && node.hash == *hash || node.number < *number && is_descendent_of(&node.hash, hash).unwrap_or(false) - }); + }).take(1).collect(); self.roots = vec![root]; } -- GitLab From 062748f2b932a00947d1b9b2ae85f6dcbbce03e1 Mon Sep 17 00:00:00 2001 From: kaichao Date: Sat, 5 Oct 2019 03:30:50 +0800 Subject: [PATCH 184/275] Fix RustDoc generation. (#3763) * Attemp to fix it. * Move env to the begining. --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a6ef113044..769ee60d1e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -288,7 +288,7 @@ build-rust-doc-release: <<: *build-only script: - rm -f ./crate-docs/index.html # use it as an indicator if the job succeeds - - BUILD_DUMMY_WASM_BINARY=1 time RUSTDOCFLAGS="--html-in-header $(pwd)/rustdoc-header.html" cargo +nightly doc --release --all --verbose + - BUILD_DUMMY_WASM_BINARY=1 RUSTDOCFLAGS="--html-in-header $(pwd)/rustdoc-header.html" time cargo +nightly doc --release --all --verbose - cp -R ./target/doc ./crate-docs - echo "" > ./crate-docs/index.html - sccache -s -- GitLab From 4d40591c69260ff78adc5525d2fddfcc60c28c14 Mon Sep 17 00:00:00 2001 From: Marcio Diaz Date: Sat, 5 Oct 2019 10:43:19 +0200 Subject: [PATCH 185/275] Use header metadata in babe verify. (#3756) * Use header_metadata in verify. * Log hash in header_metadata error. * Fix naming, error. --- core/client/db/src/lib.rs | 4 ++-- core/client/db/src/light.rs | 2 +- core/client/src/in_mem.rs | 2 +- core/consensus/babe/src/lib.rs | 7 +++---- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/core/client/db/src/lib.rs b/core/client/db/src/lib.rs index 126622364a..7cc6ef54a0 100644 --- a/core/client/db/src/lib.rs +++ b/core/client/db/src/lib.rs @@ -42,7 +42,7 @@ use client::backend::NewBlockState; use client::blockchain::{well_known_cache_keys, HeaderBackend}; use client::{ForkBlocks, ExecutionStrategies}; use client::backend::{StorageCollection, ChildStorageCollection}; -use client::error::Result as ClientResult; +use client::error::{Result as ClientResult, Error as ClientError}; use codec::{Decode, Encode}; use hash_db::{Hasher, Prefix}; use kvdb::{KeyValueDB, DBTransaction}; @@ -417,7 +417,7 @@ impl HeaderMetadata for BlockchainDb { header_metadata.clone(), ); header_metadata - }).ok_or(client::error::Error::UnknownBlock("header not found in db".to_owned())) + }).ok_or(ClientError::UnknownBlock(format!("header not found in db: {}", hash))) }) } diff --git a/core/client/db/src/light.rs b/core/client/db/src/light.rs index 111b8e0deb..19fc7fde35 100644 --- a/core/client/db/src/light.rs +++ b/core/client/db/src/light.rs @@ -207,7 +207,7 @@ impl HeaderMetadata for LightStorage { header_metadata.clone(), ); header_metadata - }).ok_or(ClientError::UnknownBlock("header not found in db".to_owned())) + }).ok_or(ClientError::UnknownBlock(format!("header not found in db: {}", hash))) }) } diff --git a/core/client/src/in_mem.rs b/core/client/src/in_mem.rs index 99dc1b6263..5c35400d77 100644 --- a/core/client/src/in_mem.rs +++ b/core/client/src/in_mem.rs @@ -324,7 +324,7 @@ impl HeaderMetadata for Blockchain { fn header_metadata(&self, hash: Block::Hash) -> Result, Self::Error> { self.header(BlockId::hash(hash))?.map(|header| CachedHeaderMetadata::from(&header)) - .ok_or(error::Error::UnknownBlock("header not found".to_owned())) + .ok_or(error::Error::UnknownBlock(format!("header not found: {}", hash))) } fn insert_header_metadata(&self, _hash: Block::Hash, _metadata: CachedHeaderMetadata) { diff --git a/core/consensus/babe/src/lib.rs b/core/consensus/babe/src/lib.rs index 683425e815..000c14269f 100644 --- a/core/consensus/babe/src/lib.rs +++ b/core/consensus/babe/src/lib.rs @@ -593,9 +593,8 @@ impl Verifier for BabeVerifier(&header)?; let epoch = { @@ -603,7 +602,7 @@ impl Verifier for BabeVerifier Date: Sat, 5 Oct 2019 09:44:07 +0100 Subject: [PATCH 186/275] babe: prune the epoch tree on startup (#3768) --- core/consensus/babe/src/lib.rs | 69 ++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/core/consensus/babe/src/lib.rs b/core/consensus/babe/src/lib.rs index 000c14269f..4f69c176ce 100644 --- a/core/consensus/babe/src/lib.rs +++ b/core/consensus/babe/src/lib.rs @@ -112,7 +112,7 @@ mod tests; pub use babe_primitives::{ AuthorityId, AuthorityPair, AuthoritySignature, Epoch, NextEpochDescriptor, }; -pub use epoch_changes::{EpochChanges, SharedEpochChanges}; +pub use epoch_changes::{EpochChanges, EpochChangesFor, SharedEpochChanges}; macro_rules! babe_err { ($($i: expr),+) => { @@ -889,24 +889,10 @@ impl BlockImport for BabeBlockImport(&finalized_header) - .expect("finalized header must be valid; \ - valid blocks have a pre-digest; qed") - .slot_number() - }; - - epoch_changes.prune_finalized( - descendent_query(&*self.client), - &info.finalized_hash, - info.finalized_number, - finalized_slot, - ).map_err(|e| ConsensusError::ClientImport(format!("{:?}", e)))?; + prune_finalized( + &self.client, + &mut epoch_changes, + )?; epoch_changes.import( descendent_query(&*self.client), @@ -989,6 +975,40 @@ impl BlockImport for BabeBlockImport( + client: &Client, + epoch_changes: &mut EpochChangesFor, +) -> Result<(), ConsensusError> where + Block: BlockT, + E: CallExecutor + Send + Sync, + B: Backend, + RA: Send + Sync, +{ + let info = client.info().chain; + + let finalized_slot = { + let finalized_header = client.header(&BlockId::Hash(info.finalized_hash)) + .map_err(|e| ConsensusError::ClientImport(format!("{:?}", e)))? + .expect("best finalized hash was given by client; \ + finalized headers must exist in db; qed"); + + find_pre_digest::(&finalized_header) + .expect("finalized header must be valid; \ + valid blocks have a pre-digest; qed") + .slot_number() + }; + + epoch_changes.prune_finalized( + descendent_query(&*client), + &info.finalized_hash, + info.finalized_number, + finalized_slot, + ).map_err(|e| ConsensusError::ClientImport(format!("{:?}", e)))?; + + Ok(()) +} + /// Produce a BABE block-import object to be used later on in the construction of /// an import-queue. /// @@ -1001,7 +1021,8 @@ pub fn block_import, I, RA, PRA>( api: Arc, ) -> ClientResult<(BabeBlockImport, BabeLink)> where B: Backend, - E: CallExecutor, + E: CallExecutor + Send + Sync, + RA: Send + Sync, { let epoch_changes = aux_schema::load_epoch_changes(&*client)?; let link = BabeLink { @@ -1010,6 +1031,14 @@ pub fn block_import, I, RA, PRA>( config: config.clone(), }; + // NOTE: this isn't entirely necessary, but since we didn't use to prune the + // epoch tree it is useful as a migration, so that nodes prune long trees on + // startup rather than waiting until importing the next epoch change block. + prune_finalized( + &client, + &mut epoch_changes.lock(), + )?; + let import = BabeBlockImport::new( client, api, -- GitLab From 179bdd3170d992d2dca33054c41181119032ba98 Mon Sep 17 00:00:00 2001 From: Micheal Waltz Date: Sat, 5 Oct 2019 11:04:22 +0000 Subject: [PATCH 187/275] Fix docker builds #3731 (#3767) --- Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 0271db8d14..1ebc7b04aa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,13 +5,15 @@ FROM phusion/baseimage:0.10.2 as builder LABEL maintainer="chevdor@gmail.com" LABEL description="This is the build stage for Substrate. Here we create the binary." +ENV DEBIAN_FRONTEND=noninteractive + ARG PROFILE=release WORKDIR /substrate COPY . /substrate RUN apt-get update && \ - apt-get dist-upgrade -y && \ + apt-get dist-upgrade -y -o Dpkg::Options::="--force-confold" && \ apt-get install -y cmake pkg-config libssl-dev git clang RUN curl https://sh.rustup.rs -sSf | sh -s -- -y && \ -- GitLab From aba25769f23dc1bbfeb18b4326cb67234076bd7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sat, 5 Oct 2019 13:06:38 +0200 Subject: [PATCH 188/275] srml-utility: Store errors as `DispatchError` to make the decodable (#3766) --- node/runtime/src/lib.rs | 6 +++--- srml/utility/src/lib.rs | 17 ++++++----------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index b06ba19ee5..7495190464 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -84,8 +84,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 171, - impl_version: 171, + spec_version: 172, + impl_version: 172, apis: RUNTIME_API_VERSIONS, }; @@ -497,7 +497,7 @@ construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic { System: system::{Module, Call, Storage, Config, Event}, - Utility: utility::{Module, Call, Event}, + Utility: utility::{Module, Call, Event}, Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)}, Timestamp: timestamp::{Module, Call, Storage, Inherent}, Authorship: authorship::{Module, Call, Storage, Inherent}, diff --git a/srml/utility/src/lib.rs b/srml/utility/src/lib.rs index 9fe34ee2d0..c0b1954da9 100644 --- a/srml/utility/src/lib.rs +++ b/srml/utility/src/lib.rs @@ -23,27 +23,21 @@ use rstd::prelude::*; use support::{decl_module, decl_event, Parameter}; use system::ensure_root; -use sr_primitives::{ - traits::{Dispatchable, DispatchResult}, weights::SimpleDispatchInfo -}; +use sr_primitives::{traits::Dispatchable, weights::SimpleDispatchInfo, DispatchError}; /// Configuration trait. pub trait Trait: system::Trait { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From + Into<::Event>; /// The overarching call type. type Call: Parameter + Dispatchable; } -pub type DispatchResultOf = DispatchResult<<::Call as Dispatchable>::Error>; - decl_event!( /// Events type. - pub enum Event where - DispatchResult = DispatchResultOf, - { - BatchExecuted(Vec), + pub enum Event { + BatchExecuted(Vec>), } ); @@ -58,8 +52,9 @@ decl_module! { ensure_root(origin)?; let results = calls.into_iter() .map(|call| call.dispatch(system::RawOrigin::Root.into())) + .map(|res| res.map_err(Into::into)) .collect::>(); - Self::deposit_event(RawEvent::BatchExecuted(results)); + Self::deposit_event(Event::BatchExecuted(results)); } } } -- GitLab From f860828600c278769c0ea36909b14ef47d4c2107 Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Sun, 6 Oct 2019 22:44:32 +0900 Subject: [PATCH 189/275] Make the purge-chain prompt a little nicer (#3772) --- core/cli/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/cli/src/lib.rs b/core/cli/src/lib.rs index 7d5593f2cd..2e7619116c 100644 --- a/core/cli/src/lib.rs +++ b/core/cli/src/lib.rs @@ -423,7 +423,7 @@ impl<'a> ParseAndPreparePurge<'a> { let db_path = config.database_path; if !self.params.yes { - print!("Are you sure to remove {:?}? (y/n)", &db_path); + print!("Are you sure to remove {:?}? [y/N]: ", &db_path); stdout().flush().expect("failed to flush stdout"); let mut input = String::new(); -- GitLab From b942db7efe14a3465bc0917befdf771de8cd0fab Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 7 Oct 2019 09:00:15 +0300 Subject: [PATCH 190/275] Fix state RPC subscriptions on light node (#3626) * fetch all keys at once in light RPC subscriptions * restore lost fil --- Cargo.lock | 1 + core/rpc/Cargo.toml | 1 + core/rpc/api/src/subscriptions.rs | 7 +- core/rpc/src/state/mod.rs | 119 +----- core/rpc/src/state/state_full.rs | 142 ++++++- core/rpc/src/state/state_light.rs | 651 ++++++++++++++++++++++++++---- 6 files changed, 714 insertions(+), 207 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca1270929f..170ed9e2f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5224,6 +5224,7 @@ dependencies = [ "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", diff --git a/core/rpc/Cargo.toml b/core/rpc/Cargo.toml index 5178fc56d8..e6f0db1c9c 100644 --- a/core/rpc/Cargo.toml +++ b/core/rpc/Cargo.toml @@ -23,6 +23,7 @@ substrate-executor = { path = "../executor" } substrate-keystore = { path = "../keystore" } transaction_pool = { package = "substrate-transaction-pool", path = "../transaction-pool" } hash-db = { version = "0.15.2", default-features = false } +parking_lot = { version = "0.9.0" } [dev-dependencies] assert_matches = "1.3.0" diff --git a/core/rpc/api/src/subscriptions.rs b/core/rpc/api/src/subscriptions.rs index bff184cade..a1e486138f 100644 --- a/core/rpc/api/src/subscriptions.rs +++ b/core/rpc/api/src/subscriptions.rs @@ -74,13 +74,14 @@ impl Subscriptions { /// Second parameter is a function that converts Subscriber sink into a future. /// This future will be driven to completion by the underlying event loop /// or will be cancelled in case #cancel is invoked. - pub fn add(&self, subscriber: Subscriber, into_future: G) where + pub fn add(&self, subscriber: Subscriber, into_future: G) -> SubscriptionId where G: FnOnce(Sink) -> R, R: future::IntoFuture, F: future::Future + Send + 'static, { let id = self.next_id.next_id(); - if let Ok(sink) = subscriber.assign_id(id.into()) { + let subscription_id: SubscriptionId = id.into(); + if let Ok(sink) = subscriber.assign_id(subscription_id.clone()) { let (tx, rx) = oneshot::channel(); let future = into_future(sink) .into_future() @@ -92,6 +93,8 @@ impl Subscriptions { error!("Failed to spawn RPC subscription task"); } } + + subscription_id } /// Cancel subscription. diff --git a/core/rpc/src/state/mod.rs b/core/rpc/src/state/mod.rs index 390f95ab41..b922601b0a 100644 --- a/core/rpc/src/state/mod.rs +++ b/core/rpc/src/state/mod.rs @@ -23,27 +23,24 @@ mod state_light; mod tests; use std::sync::Arc; -use futures03::{future, StreamExt as _, TryStreamExt as _}; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; -use log::warn; use rpc::{ Result as RpcResult, - futures::{stream, Future, Sink, Stream}, + futures::Future, }; use api::Subscriptions; use client::{ - BlockchainEvents, Client, CallExecutor, + Client, CallExecutor, runtime_api::Metadata, light::{blockchain::RemoteBlockchain, fetcher::Fetcher}, }; use primitives::{ Blake2Hasher, Bytes, H256, - storage::{well_known_keys, StorageKey, StorageData, StorageChangeSet}, + storage::{StorageKey, StorageData, StorageChangeSet}, }; use runtime_version::RuntimeVersion; use sr_primitives::{ - generic::BlockId, traits::{Block as BlockT, ProvideRuntimeApi}, }; @@ -59,12 +56,6 @@ pub trait StateBackend: Send + Sync + 'static E: client::CallExecutor + Send + Sync + 'static, RA: Send + Sync + 'static, { - /// Get client reference. - fn client(&self) -> &Arc>; - - /// Get subscriptions reference. - fn subscriptions(&self) -> &Subscriptions; - /// Call runtime method at given block. fn call( &self, @@ -161,123 +152,29 @@ pub trait StateBackend: Send + Sync + 'static &self, _meta: crate::metadata::Metadata, subscriber: Subscriber, - ) { - let stream = match self.client().storage_changes_notification_stream( - Some(&[StorageKey(well_known_keys::CODE.to_vec())]), - None, - ) { - Ok(stream) => stream, - Err(err) => { - let _ = subscriber.reject(Error::from(client_err(err)).into()); - return; - } - }; - - self.subscriptions().add(subscriber, |sink| { - let version = self.runtime_version(None.into()) - .map_err(Into::into) - .wait(); - - let client = self.client().clone(); - let mut previous_version = version.clone(); - - let stream = stream - .filter_map(move |_| { - let info = client.info(); - let version = client - .runtime_version_at(&BlockId::hash(info.chain.best_hash)) - .map_err(client_err) - .map_err(Into::into); - if previous_version != version { - previous_version = version.clone(); - future::ready(Some(Ok::<_, ()>(version))) - } else { - future::ready(None) - } - }) - .compat(); - - sink - .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) - .send_all( - stream::iter_result(vec![Ok(version)]) - .chain(stream) - ) - // we ignore the resulting Stream (if the first stream is over we are unsubscribed) - .map(|_| ()) - }); - } + ); /// Unsubscribe from runtime version subscription fn unsubscribe_runtime_version( &self, _meta: Option, id: SubscriptionId, - ) -> RpcResult { - Ok(self.subscriptions().cancel(id)) - } + ) -> RpcResult; /// New storage subscription fn subscribe_storage( &self, _meta: crate::metadata::Metadata, subscriber: Subscriber>, - keys: Option> - ) { - let keys = Into::>>::into(keys); - let stream = match self.client().storage_changes_notification_stream( - keys.as_ref().map(|x| &**x), - None - ) { - Ok(stream) => stream, - Err(err) => { - let _ = subscriber.reject(client_err(err).into()); - return; - }, - }; - - // initial values - let initial = stream::iter_result(keys - .map(|keys| { - let block = self.client().info().chain.best_hash; - let changes = keys - .into_iter() - .map(|key| self.storage(Some(block.clone()).into(), key.clone()) - .map(|val| (key.clone(), val)) - .wait() - .unwrap_or_else(|_| (key, None)) - ) - .collect(); - vec![Ok(Ok(StorageChangeSet { block, changes }))] - }).unwrap_or_default()); - - self.subscriptions().add(subscriber, |sink| { - let stream = stream - .map(|(block, changes)| Ok::<_, ()>(Ok(StorageChangeSet { - block, - changes: changes.iter() - .filter_map(|(o_sk, k, v)| if o_sk.is_none() { - Some((k.clone(),v.cloned())) - } else { None }).collect(), - }))) - .compat(); - - sink - .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) - .send_all(initial.chain(stream)) - // we ignore the resulting Stream (if the first stream is over we are unsubscribed) - .map(|_| ()) - }) - } + keys: Option>, + ); /// Unsubscribe from storage subscription fn unsubscribe_storage( &self, _meta: Option, id: SubscriptionId, - ) -> RpcResult { - Ok(self.subscriptions().cancel(id)) - } + ) -> RpcResult; } /// Create new state API that works on full node. diff --git a/core/rpc/src/state/state_full.rs b/core/rpc/src/state/state_full.rs index 8b3dcd3d69..6f0472163f 100644 --- a/core/rpc/src/state/state_full.rs +++ b/core/rpc/src/state/state_full.rs @@ -19,16 +19,22 @@ use std::collections::{BTreeMap, HashMap}; use std::sync::Arc; use std::ops::Range; -use rpc::futures::future::result; +use futures03::{future, StreamExt as _, TryStreamExt as _}; +use log::warn; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use rpc::{ + Result as RpcResult, + futures::{stream, Future, Sink, Stream, future::result}, +}; use api::Subscriptions; use client::{ - Client, CallExecutor, runtime_api::Metadata, + Client, CallExecutor, BlockchainEvents, runtime_api::Metadata, backend::Backend, error::Result as ClientResult, }; use primitives::{ H256, Blake2Hasher, Bytes, offchain::NeverOffchainExt, - storage::{StorageKey, StorageData, StorageChangeSet}, + storage::{well_known_keys, StorageKey, StorageData, StorageChangeSet}, }; use runtime_version::RuntimeVersion; use state_machine::ExecutionStrategy; @@ -53,6 +59,7 @@ struct QueryStorageRange { pub filtered_range: Option>, } +/// State API backend for full nodes. pub struct FullState { client: Arc>, subscriptions: Subscriptions, @@ -64,7 +71,7 @@ impl FullState B: Backend + Send + Sync + 'static, E: CallExecutor + Send + Sync + 'static + Clone, { - /// + /// Create new state API backend for full nodes. pub fn new(client: Arc>, subscriptions: Subscriptions) -> Self { Self { client, subscriptions } } @@ -225,14 +232,6 @@ impl StateBackend for FullState: ProvideRuntimeApi, as ProvideRuntimeApi>::Api: Metadata, { - fn client(&self) -> &Arc> { - &self.client - } - - fn subscriptions(&self) -> &Subscriptions { - &self.subscriptions - } - fn call( &self, block: Option, @@ -352,6 +351,125 @@ impl StateBackend for FullState, + ) { + let stream = match self.client.storage_changes_notification_stream( + Some(&[StorageKey(well_known_keys::CODE.to_vec())]), + None, + ) { + Ok(stream) => stream, + Err(err) => { + let _ = subscriber.reject(Error::from(client_err(err)).into()); + return; + } + }; + + self.subscriptions.add(subscriber, |sink| { + let version = self.runtime_version(None.into()) + .map_err(Into::into) + .wait(); + + let client = self.client.clone(); + let mut previous_version = version.clone(); + + let stream = stream + .filter_map(move |_| { + let info = client.info(); + let version = client + .runtime_version_at(&BlockId::hash(info.chain.best_hash)) + .map_err(client_err) + .map_err(Into::into); + if previous_version != version { + previous_version = version.clone(); + future::ready(Some(Ok::<_, ()>(version))) + } else { + future::ready(None) + } + }) + .compat(); + + sink + .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) + .send_all( + stream::iter_result(vec![Ok(version)]) + .chain(stream) + ) + // we ignore the resulting Stream (if the first stream is over we are unsubscribed) + .map(|_| ()) + }); + } + + fn unsubscribe_runtime_version( + &self, + _meta: Option, + id: SubscriptionId, + ) -> RpcResult { + Ok(self.subscriptions.cancel(id)) + } + + fn subscribe_storage( + &self, + _meta: crate::metadata::Metadata, + subscriber: Subscriber>, + keys: Option>, + ) { + let keys = Into::>>::into(keys); + let stream = match self.client.storage_changes_notification_stream( + keys.as_ref().map(|x| &**x), + None + ) { + Ok(stream) => stream, + Err(err) => { + let _ = subscriber.reject(client_err(err).into()); + return; + }, + }; + + // initial values + let initial = stream::iter_result(keys + .map(|keys| { + let block = self.client.info().chain.best_hash; + let changes = keys + .into_iter() + .map(|key| self.storage(Some(block.clone()).into(), key.clone()) + .map(|val| (key.clone(), val)) + .wait() + .unwrap_or_else(|_| (key, None)) + ) + .collect(); + vec![Ok(Ok(StorageChangeSet { block, changes }))] + }).unwrap_or_default()); + + self.subscriptions.add(subscriber, |sink| { + let stream = stream + .map(|(block, changes)| Ok::<_, ()>(Ok(StorageChangeSet { + block, + changes: changes.iter() + .filter_map(|(o_sk, k, v)| if o_sk.is_none() { + Some((k.clone(),v.cloned())) + } else { None }).collect(), + }))) + .compat(); + + sink + .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) + .send_all(initial.chain(stream)) + // we ignore the resulting Stream (if the first stream is over we are unsubscribed) + .map(|_| ()) + }); + } + + fn unsubscribe_storage( + &self, + _meta: Option, + id: SubscriptionId, + ) -> RpcResult { + Ok(self.subscriptions.cancel(id)) + } } /// Splits passed range into two subranges where: diff --git a/core/rpc/src/state/state_light.rs b/core/rpc/src/state/state_light.rs index 456992db66..3d0c7979e3 100644 --- a/core/rpc/src/state/state_light.rs +++ b/core/rpc/src/state/state_light.rs @@ -16,19 +16,31 @@ //! State API backend for light nodes. -use std::sync::Arc; +use std::{ + sync::Arc, + collections::{HashSet, HashMap, hash_map::Entry}, +}; use codec::Decode; -use futures03::{future::{ready, Either}, FutureExt, TryFutureExt}; +use futures03::{ + future::{ready, Either}, + channel::oneshot::{channel, Sender}, + FutureExt, TryFutureExt, + StreamExt as _, TryStreamExt as _, +}; use hash_db::Hasher; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use log::warn; +use parking_lot::Mutex; use rpc::{ Result as RpcResult, + futures::Sink, futures::future::{result, Future}, + futures::stream::Stream, }; use api::Subscriptions; use client::{ - Client, CallExecutor, backend::Backend, + BlockchainEvents, Client, CallExecutor, backend::Backend, error::Error as ClientError, light::{ blockchain::{future_header, RemoteBlockchain}, @@ -42,18 +54,89 @@ use primitives::{ use runtime_version::RuntimeVersion; use sr_primitives::{ generic::BlockId, - traits::{Block as BlockT, Header as HeaderT}, + traits::Block as BlockT, }; use super::{StateBackend, error::{FutureResult, Error}, client_err}; +/// Storage data map of storage keys => (optional) storage value. +type StorageMap = HashMap>; + +/// State API backend for light nodes. pub struct LightState, B, E, RA> { client: Arc>, subscriptions: Subscriptions, + version_subscriptions: SimpleSubscriptions, + storage_subscriptions: Arc>>, remote_blockchain: Arc>, fetcher: Arc, } +/// Shared requests container. +trait SharedRequests: Clone + Send + Sync { + /// Tries to listen for already issued request, or issues request. + /// + /// Returns true if requests has been issued. + fn listen_request( + &self, + block: Hash, + sender: Sender>, + ) -> bool; + + /// Returns (and forgets) all listeners for given request. + fn on_response_received(&self, block: Hash) -> Vec>>; +} + +/// Storage subscriptions data. +struct StorageSubscriptions { + /// Active storage requests. + active_requests: HashMap>>>, + /// Map of subscription => keys that this subscription watch for. + keys_by_subscription: HashMap>, + /// Map of key => set of subscriptions that watch this key. + subscriptions_by_key: HashMap>, +} + +impl SharedRequests for Arc>> { + fn listen_request( + &self, + block: Block::Hash, + sender: Sender>, + ) -> bool { + let mut subscriptions = self.lock(); + let active_requests_at = subscriptions.active_requests.entry(block).or_default(); + active_requests_at.push(sender); + active_requests_at.len() == 1 + } + + fn on_response_received(&self, block: Block::Hash) -> Vec>> { + self.lock().active_requests.remove(&block).unwrap_or_default() + } +} + +/// Simple, maybe shared, subscription data that shares per block requests. +type SimpleSubscriptions = Arc>>>>>; + +impl SharedRequests for SimpleSubscriptions where + Hash: Send + Eq + std::hash::Hash, + V: Send, +{ + fn listen_request( + &self, + block: Hash, + sender: Sender>, + ) -> bool { + let mut subscriptions = self.lock(); + let active_requests_at = subscriptions.entry(block).or_default(); + active_requests_at.push(sender); + active_requests_at.len() == 1 + } + + fn on_response_received(&self, block: Hash) -> Vec>> { + self.lock().remove(&block).unwrap_or_default() + } +} + impl + 'static, B, E, RA> LightState where Block: BlockT, @@ -61,39 +144,31 @@ impl + 'static, B, E, RA> LightState + Send + Sync + 'static + Clone, RA: Send + Sync + 'static, { - /// + /// Create new state API backend for light nodes. pub fn new( client: Arc>, subscriptions: Subscriptions, remote_blockchain: Arc>, fetcher: Arc, ) -> Self { - Self { client, subscriptions, remote_blockchain, fetcher, } + Self { + client, + subscriptions, + version_subscriptions: Arc::new(Mutex::new(HashMap::new())), + storage_subscriptions: Arc::new(Mutex::new(StorageSubscriptions { + active_requests: HashMap::new(), + keys_by_subscription: HashMap::new(), + subscriptions_by_key: HashMap::new(), + })), + remote_blockchain, + fetcher, + } } /// Returns given block hash or best block hash if None is passed. fn block_or_best(&self, hash: Option) -> Block::Hash { hash.unwrap_or_else(|| self.client.info().chain.best_hash) } - - /// Resolve header by hash. - fn resolve_header( - &self, - block: Option, - ) -> impl std::future::Future> { - let block = self.block_or_best(block); - let maybe_header = future_header( - &*self.remote_blockchain, - &*self.fetcher, - BlockId::Hash(block), - ); - - maybe_header.then(move |result| - ready(result.and_then(|maybe_header| - maybe_header.ok_or(ClientError::UnknownBlock(format!("{}", block))) - ).map_err(client_err)), - ) - } } impl StateBackend for LightState @@ -104,34 +179,19 @@ impl StateBackend for LightState + 'static { - fn client(&self) -> &Arc> { - &self.client - } - - fn subscriptions(&self) -> &Subscriptions { - &self.subscriptions - } - fn call( &self, block: Option, method: String, call_data: Bytes, ) -> FutureResult { - let fetcher = self.fetcher.clone(); - let call_result = self.resolve_header(block) - .then(move |result| match result { - Ok(header) => Either::Left(fetcher.remote_call(RemoteCallRequest { - block: header.hash(), - header, - method, - call_data: call_data.0, - retry_count: Default::default(), - }).then(|result| ready(result.map(Bytes).map_err(client_err)))), - Err(error) => Either::Right(ready(Err(error))), - }); - - Box::new(call_result.boxed().compat()) + Box::new(call( + &*self.remote_blockchain, + self.fetcher.clone(), + self.block_or_best(block), + method, + call_data, + ).boxed().compat()) } fn storage_keys( @@ -147,26 +207,15 @@ impl StateBackend for LightState, key: StorageKey, ) -> FutureResult> { - let fetcher = self.fetcher.clone(); - let storage = self.resolve_header(block) - .then(move |result| match result { - Ok(header) => Either::Left(fetcher.remote_read(RemoteReadRequest { - block: header.hash(), - header, - keys: vec![key.0.clone()], - retry_count: Default::default(), - }).then(move |result| ready(result - .map(|mut data| data - .remove(&key.0) - .expect("successful result has entry for all keys; qed") - .map(StorageData) - ) - .map_err(client_err) - ))), - Err(error) => Either::Right(ready(Err(error))), - }); - - Box::new(storage.boxed().compat()) + Box::new(storage( + &*self.remote_blockchain, + self.fetcher.clone(), + self.block_or_best(block), + vec![key.0.clone()], + ).boxed().compat().map(move |mut values| values + .remove(&key) + .expect("successful request has entries for all requested keys; qed") + )) } fn storage_hash( @@ -197,11 +246,12 @@ impl StateBackend for LightState FutureResult> { + let block = self.block_or_best(block); let fetcher = self.fetcher.clone(); - let child_storage = self.resolve_header(block) + let child_storage = resolve_header(&*self.remote_blockchain, &*self.fetcher, block) .then(move |result| match result { Ok(header) => Either::Left(fetcher.remote_read_child(RemoteReadChildRequest { - block: header.hash(), + block, header, storage_key: child_storage_key.0, keys: vec![key.0.clone()], @@ -247,12 +297,11 @@ impl StateBackend for LightState) -> FutureResult { - let version = self.call(block, "Core_version".into(), Bytes(Vec::new())) - .and_then(|version| Decode::decode(&mut &version.0[..]) - .map_err(|_| client_err(ClientError::VersionInvalid)) - ); - - Box::new(version) + Box::new(runtime_version( + &*self.remote_blockchain, + self.fetcher.clone(), + self.block_or_best(block), + ).boxed().compat()) } fn query_storage( @@ -267,31 +316,469 @@ impl StateBackend for LightState>, - _keys: Option> + subscriber: Subscriber>, + keys: Option> ) { + let keys = match keys { + Some(keys) => keys, + None => { + warn!("Cannot subscribe to all keys on light client. Subscription rejected."); + return; + } + }; + + let keys = keys.iter().cloned().collect::>(); + let keys_to_check = keys.iter().map(|k| k.0.clone()).collect::>(); + let subscription_id = self.subscriptions.add(subscriber, move |sink| { + let fetcher = self.fetcher.clone(); + let remote_blockchain = self.remote_blockchain.clone(); + let storage_subscriptions = self.storage_subscriptions.clone(); + let initial_block = self.block_or_best(None); + let initial_keys = keys_to_check.iter().cloned().collect::>(); + + let changes_stream = subscription_stream::( + storage_subscriptions.clone(), + self.client + .import_notification_stream() + .map(|notification| Ok::<_, ()>(notification.hash)) + .compat(), + display_error(storage( + &*remote_blockchain, + fetcher.clone(), + initial_block, + initial_keys, + ).map(move |r| r.map(|r| (initial_block, r)))), + move |block| { + // there'll be single request per block for all active subscriptions + // with all subscribed keys + let keys = storage_subscriptions + .lock() + .subscriptions_by_key + .keys() + .map(|k| k.0.clone()) + .collect(); + + storage( + &*remote_blockchain, + fetcher.clone(), + block, + keys, + ) + }, + move |block, old_value, new_value| { + // let's only select keys which are valid for this subscription + let new_value = new_value + .iter() + .filter(|(k, _)| keys_to_check.contains(&k.0)) + .map(|(k, v)| (k.clone(), v.clone())) + .collect::>(); + let value_differs = old_value + .as_ref() + .map(|old_value| **old_value != new_value) + .unwrap_or(true); + match value_differs { + true => Some(StorageChangeSet { + block, + changes: new_value + .iter() + .map(|(k, v)| (k.clone(), v.clone())) + .collect(), + }), + false => None, + } + } + ); + + sink + .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) + .send_all(changes_stream.map(|changes| Ok(changes))) + // we ignore the resulting Stream (if the first stream is over we are unsubscribed) + .map(|_| ()) + }); + + // remember keys associated with this subscription + let mut storage_subscriptions = self.storage_subscriptions.lock(); + storage_subscriptions.keys_by_subscription.insert(subscription_id.clone(), keys.clone()); + for key in keys { + storage_subscriptions + .subscriptions_by_key + .entry(key) + .or_default() + .insert(subscription_id.clone()); + } } fn unsubscribe_storage( &self, _meta: Option, - _id: SubscriptionId, + id: SubscriptionId, ) -> RpcResult { - Ok(false) + if !self.subscriptions.cancel(id.clone()) { + return Ok(false); + } + + // forget subscription keys + let mut storage_subscriptions = self.storage_subscriptions.lock(); + let keys = storage_subscriptions.keys_by_subscription.remove(&id); + for key in keys.into_iter().flat_map(|keys| keys.into_iter()) { + match storage_subscriptions.subscriptions_by_key.entry(key) { + Entry::Vacant(_) => unreachable!("every key from keys_by_subscription has\ + corresponding entry in subscriptions_by_key; qed"), + Entry::Occupied(mut entry) => { + entry.get_mut().remove(&id); + if entry.get().is_empty() { + entry.remove(); + } + } + } + } + + Ok(true) } fn subscribe_runtime_version( &self, _meta: crate::metadata::Metadata, - _subscriber: Subscriber, + subscriber: Subscriber, ) { + self.subscriptions.add(subscriber, move |sink| { + let fetcher = self.fetcher.clone(); + let remote_blockchain = self.remote_blockchain.clone(); + let version_subscriptions = self.version_subscriptions.clone(); + let initial_block = self.block_or_best(None); + + let versions_stream = subscription_stream::( + version_subscriptions, + self.client + .import_notification_stream() + .map(|notification| Ok::<_, ()>(notification.hash)) + .compat(), + display_error(runtime_version( + &*remote_blockchain, + fetcher.clone(), + initial_block, + ).map(move |r| r.map(|r| (initial_block, r)))), + move |block| runtime_version( + &*remote_blockchain, + fetcher.clone(), + block, + ), + |_, old_version, new_version| { + let version_differs = old_version + .as_ref() + .map(|old_version| *old_version != new_version) + .unwrap_or(true); + match version_differs { + true => Some(new_version.clone()), + false => None, + } + } + ); + + sink + .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) + .send_all(versions_stream.map(|version| Ok(version))) + // we ignore the resulting Stream (if the first stream is over we are unsubscribed) + .map(|_| ()) + }); } fn unsubscribe_runtime_version( &self, _meta: Option, - _id: SubscriptionId, + id: SubscriptionId, ) -> RpcResult { - Ok(false) + Ok(self.subscriptions.cancel(id)) + } +} + +/// Resolve header by hash. +fn resolve_header>( + remote_blockchain: &dyn RemoteBlockchain, + fetcher: &F, + block: Block::Hash, +) -> impl std::future::Future> { + let maybe_header = future_header( + remote_blockchain, + fetcher, + BlockId::Hash(block), + ); + + maybe_header.then(move |result| + ready(result.and_then(|maybe_header| + maybe_header.ok_or(ClientError::UnknownBlock(format!("{}", block))) + ).map_err(client_err)), + ) +} + +/// Call runtime method at given block +fn call>( + remote_blockchain: &dyn RemoteBlockchain, + fetcher: Arc, + block: Block::Hash, + method: String, + call_data: Bytes, +) -> impl std::future::Future> { + resolve_header(remote_blockchain, &*fetcher, block) + .then(move |result| match result { + Ok(header) => Either::Left(fetcher.remote_call(RemoteCallRequest { + block, + header, + method, + call_data: call_data.0, + retry_count: Default::default(), + }).then(|result| ready(result.map(Bytes).map_err(client_err)))), + Err(error) => Either::Right(ready(Err(error))), + }) +} + +/// Get runtime version at given block. +fn runtime_version>( + remote_blockchain: &dyn RemoteBlockchain, + fetcher: Arc, + block: Block::Hash, +) -> impl std::future::Future> { + call( + remote_blockchain, + fetcher, + block, + "Core_version".into(), + Bytes(Vec::new()), + ) + .then(|version| ready(version.and_then(|version| + Decode::decode(&mut &version.0[..]).map_err(|_| client_err(ClientError::VersionInvalid)) + ))) +} + +/// Get storage value at given key at given block. +fn storage>( + remote_blockchain: &dyn RemoteBlockchain, + fetcher: Arc, + block: Block::Hash, + keys: Vec>, +) -> impl std::future::Future>, Error>> { + resolve_header(remote_blockchain, &*fetcher, block) + .then(move |result| match result { + Ok(header) => Either::Left(fetcher.remote_read(RemoteReadRequest { + block, + header, + keys, + retry_count: Default::default(), + }).then(|result| ready(result + .map(|result| result + .into_iter() + .map(|(key, value)| (StorageKey(key), value.map(StorageData))) + .collect() + ).map_err(client_err) + ))), + Err(error) => Either::Right(ready(Err(error))), + }) +} + +/// Returns subscription stream that issues request on every imported block and +/// if value has changed from previous block, emits (stream) item. +fn subscription_stream< + Block, + Requests, + FutureBlocksStream, + V, N, + InitialRequestFuture, + IssueRequest, IssueRequestFuture, + CompareValues, +>( + shared_requests: Requests, + future_blocks_stream: FutureBlocksStream, + initial_request: InitialRequestFuture, + issue_request: IssueRequest, + compare_values: CompareValues, +) -> impl Stream where + Block: BlockT, + Requests: 'static + SharedRequests, + FutureBlocksStream: Stream, + V: Send + 'static + Clone, + InitialRequestFuture: std::future::Future> + Send + 'static, + IssueRequest: 'static + Fn(Block::Hash) -> IssueRequestFuture, + IssueRequestFuture: std::future::Future> + Send + 'static, + CompareValues: Fn(Block::Hash, Option<&V>, &V) -> Option, +{ + // we need to send initial value first, then we'll only be sending if value has changed + let previous_value = Arc::new(Mutex::new(None)); + + // prepare 'stream' of initial values + let initial_value_stream = ignore_error(initial_request) + .boxed() + .compat() + .into_stream(); + + // prepare stream of future values + // + // we do not want to stop stream if single request fails + // (the warning should have been already issued by the request issuer) + let future_values_stream = future_blocks_stream + .and_then(move |block| ignore_error(maybe_share_remote_request::( + shared_requests.clone(), + block, + &issue_request, + ).map(move |r| r.map(|v| (block, v)))).boxed().compat()); + + // now let's return changed values for selected blocks + initial_value_stream + .chain(future_values_stream) + .filter_map(move |block_and_new_value| block_and_new_value.and_then(|(block, new_value)| { + let mut previous_value = previous_value.lock(); + compare_values(block, previous_value.as_ref(), &new_value) + .map(|notification_value| { + *previous_value = Some(new_value); + notification_value + }) + })) + .map_err(|_| ()) +} + +/// Request some data from remote node, probably reusing response from already +/// (in-progress) existing request. +fn maybe_share_remote_request( + shared_requests: Requests, + block: Block::Hash, + issue_request: &IssueRequest, +) -> impl std::future::Future> where + V: Clone, + Requests: SharedRequests, + IssueRequest: Fn(Block::Hash) -> IssueRequestFuture, + IssueRequestFuture: std::future::Future>, +{ + let (sender, receiver) = channel(); + let need_issue_request = shared_requests.listen_request(block, sender); + + // if that isn't the first request - just listen for existing request' response + if !need_issue_request { + return Either::Right(receiver.then(|r| ready(r.unwrap_or(Err(()))))); + } + + // that is the first request - issue remote request + notify all listeners on + // completion + Either::Left( + display_error(issue_request(block)) + .then(move |remote_result| { + let listeners = shared_requests.on_response_received(block); + // skip first element, because this future is the first element + for receiver in listeners.into_iter().skip(1) { + if let Err(_) = receiver.send(remote_result.clone()) { + // we don't care if receiver has been dropped already + } + } + + ready(remote_result) + }) + ) +} + +/// Convert successful future result into Ok(result) and error into Err(()), +/// displaying warning. +fn display_error(future: F) -> impl std::future::Future> where + F: std::future::Future> +{ + future.then(|result| ready(match result { + Ok(result) => Ok(result), + Err(err) => { + warn!("Remote request for subscription data has failed with: {:?}", err); + Err(()) + }, + })) +} + +/// Convert successful future result into Ok(Some(result)) and error into Ok(None), +/// displaying warning. +fn ignore_error(future: F) -> impl std::future::Future, ()>> where + F: std::future::Future> +{ + future.then(|result| ready(match result { + Ok(result) => Ok(Some(result)), + Err(()) => Ok(None), + })) +} + +#[cfg(test)] +mod tests { + use rpc::futures::stream::futures_ordered; + use test_client::runtime::Block; + use super::*; + + #[test] + fn subscription_stream_works() { + let stream = subscription_stream::( + SimpleSubscriptions::default(), + futures_ordered(vec![result(Ok(H256::from([2; 32]))), result(Ok(H256::from([3; 32])))]), + ready(Ok((H256::from([1; 32]), 100))), + |block| match block[0] { + 2 => ready(Ok(100)), + 3 => ready(Ok(200)), + _ => unreachable!("should not issue additional requests"), + }, + |_, old_value, new_value| match old_value == Some(new_value) { + true => None, + false => Some(new_value.clone()), + } + ); + + assert_eq!( + stream.collect().wait(), + Ok(vec![100, 200]) + ); + } + + #[test] + fn subscription_stream_ignores_failed_requests() { + let stream = subscription_stream::( + SimpleSubscriptions::default(), + futures_ordered(vec![result(Ok(H256::from([2; 32]))), result(Ok(H256::from([3; 32])))]), + ready(Ok((H256::from([1; 32]), 100))), + |block| match block[0] { + 2 => ready(Err(client_err(ClientError::NotAvailableOnLightClient))), + 3 => ready(Ok(200)), + _ => unreachable!("should not issue additional requests"), + }, + |_, old_value, new_value| match old_value == Some(new_value) { + true => None, + false => Some(new_value.clone()), + } + ); + + assert_eq!( + stream.collect().wait(), + Ok(vec![100, 200]) + ); + } + + #[test] + fn maybe_share_remote_request_shares_request() { + type UnreachableFuture = futures03::future::Ready>; + + let shared_requests = SimpleSubscriptions::default(); + + // let's 'issue' requests for B1 + shared_requests.lock().insert( + H256::from([1; 32]), + vec![channel().0], + ); + + // make sure that no additional requests are issued when we're asking for B1 + let _ = maybe_share_remote_request::( + shared_requests.clone(), + H256::from([1; 32]), + &|_| unreachable!("no duplicate requests issued"), + ); + + // make sure that additional requests is issued when we're asking for B2 + let request_issued = Arc::new(Mutex::new(false)); + let _ = maybe_share_remote_request::( + shared_requests.clone(), + H256::from([2; 32]), + &|_| { + *request_issued.lock() = true; + ready(Ok(Default::default())) + }, + ); + assert!(*request_issued.lock()); } } -- GitLab From 6b8e5431fe39916119f7dafc44a956f8fada824a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20=C5=A0kvorc?= Date: Mon, 7 Oct 2019 09:34:10 +0200 Subject: [PATCH 191/275] Alternative sysvar setup for Windows (#3761) * Alternative sysvar setup for Windows The command line setup did not work for me. This adds instructions and images on how to do it through the UI. * Modified instructions to use Powershell, removed images from PR. --- README.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.adoc b/README.adoc index 810d07c612..f5d7f95713 100644 --- a/README.adoc +++ b/README.adoc @@ -246,7 +246,7 @@ If you are trying to set up Substrate on Windows, you should do the following: .\bootstrap-vcpkg.bat .\vcpkg.exe install openssl:x64-windows-static -7. After, you need to add OpenSSL to your System Variables: +7. After, you need to add OpenSSL to your System Variables. Note that in order for the following commands to work, you need to use Windows Powershell: $env:OPENSSL_DIR = 'C:\Tools\vcpkg\installed\x64-windows-static' $env:OPENSSL_STATIC = 'Yes' -- GitLab From 1c7e65fa3618f81880940fbfb779285b646a1617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Mon, 7 Oct 2019 14:28:28 +0100 Subject: [PATCH 192/275] client: fix comparison of CachedHeaderMetadata in tree_route (#3776) * client: fix comparison of CachedHeaderMetadata in tree_route * client: add regression test for tree_route --- core/client/db/src/lib.rs | 34 ++++++++++++++++++++++++++ core/client/header-metadata/src/lib.rs | 4 +-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/core/client/db/src/lib.rs b/core/client/db/src/lib.rs index 7cc6ef54a0..7061e9d29a 100644 --- a/core/client/db/src/lib.rs +++ b/core/client/db/src/lib.rs @@ -2222,6 +2222,40 @@ mod tests { } } + #[test] + fn test_tree_route_regression() { + // NOTE: this is a test for a regression introduced in #3665, the result + // of tree_route would be erroneously computed, since it was taking into + // account the `ancestor` in `CachedHeaderMetadata` for the comparison. + // in this test we simulate the same behavior with the side-effect + // triggering the issue being eviction of a previously fetched record + // from the cache, therefore this test is dependent on the LRU cache + // size for header metadata, which is currently set to 5000 elements. + let backend = Backend::::new_test(10000, 10000); + let blockchain = backend.blockchain(); + + let genesis = insert_header(&backend, 0, Default::default(), Vec::new(), Default::default()); + + let block100 = (1..=100).fold(genesis, |parent, n| { + insert_header(&backend, n, parent, Vec::new(), Default::default()) + }); + + let block7000 = (101..=7000).fold(block100, |parent, n| { + insert_header(&backend, n, parent, Vec::new(), Default::default()) + }); + + // This will cause the ancestor of `block100` to be set to `genesis` as a side-effect. + lowest_common_ancestor(blockchain, genesis, block100).unwrap(); + + // While traversing the tree we will have to do 6900 calls to + // `header_metadata`, which will make sure we will exhaust our cache + // which only takes 5000 elements. In particular, the `CachedHeaderMetadata` struct for + // block #100 will be evicted and will get a new value (with ancestor set to its parent). + let tree_route = tree_route(blockchain, block100, block7000).unwrap(); + + assert!(tree_route.retracted().is_empty()); + } + #[test] fn test_leaves_with_complex_block_tree() { let backend: Arc> = Arc::new(Backend::new_test(20, 20)); diff --git a/core/client/header-metadata/src/lib.rs b/core/client/header-metadata/src/lib.rs index cce45f264e..a8c3886020 100644 --- a/core/client/header-metadata/src/lib.rs +++ b/core/client/header-metadata/src/lib.rs @@ -122,7 +122,7 @@ pub fn tree_route>( // numbers are equal now. walk backwards until the block is the same - while to != from { + while to.hash != from.hash { to_branch.push(HashAndNumber { number: to.number, hash: to.hash, @@ -257,7 +257,7 @@ impl HeaderMetadata for HeaderMetadataCache { } /// Cached header metadata. Used to efficiently traverse the tree. -#[derive(Debug, Clone, Eq, PartialEq)] +#[derive(Debug, Clone)] pub struct CachedHeaderMetadata { /// Hash of the header. pub hash: Block::Hash, -- GitLab From c5e0897d45727ba545ac2152c3a3caf6a675be7a Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Tue, 8 Oct 2019 09:23:27 +0200 Subject: [PATCH 193/275] Example of how to inspect arguments in weight calculation (#3753) * document how to make a custom weight calculator * Simpler explanation and implementation. * remove unneeded where --- srml/example/src/lib.rs | 62 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/srml/example/src/lib.rs b/srml/example/src/lib.rs index fe16fb7d6e..ef8eead7ba 100644 --- a/srml/example/src/lib.rs +++ b/srml/example/src/lib.rs @@ -258,13 +258,51 @@ use support::{dispatch::Result, decl_module, decl_storage, decl_event}; use system::{ensure_signed, ensure_root}; use codec::{Encode, Decode}; use sr_primitives::{ - traits::{SignedExtension, Bounded}, weights::{SimpleDispatchInfo, DispatchInfo}, + traits::{SignedExtension, Bounded, SaturatedConversion}, + weights::{SimpleDispatchInfo, DispatchInfo, DispatchClass, ClassifyDispatch, WeighData, Weight}, transaction_validity::{ ValidTransaction, TransactionValidityError, InvalidTransaction, TransactionValidity, }, }; -/// Our module's configuration trait. All our types and consts go in here. If the +// A custom weight calculator tailored for the dispatch call `set_dummy()`. This actually examines +// the arguments and makes a decision based upon them. +// +// The `WeightData` trait has access to the arguments of the dispatch that it wants to assign a +// weight to. Nonetheless, the trait itself can not make any assumptions about what that type +// generic type of the arguments, `T`, is. Based on our needs, we could replace `T` with a more +// concrete type while implementing the trait. The `decl_module!` expects whatever implements +// `WeighData` to replace `T` with a tuple of the dispatch arguments. This is exactly how we will +// craft the implementation below. +// +// The rules of `WeightForSetDummy` is as follows: +// - The final weight of each dispatch is calculated as the argument of the call multiplied by the +// parameter given to the `WeightForSetDummy`'s constructor. +// - assigns a dispatch class `operational` if the argument of the call is more than 1000. +struct WeightForSetDummy(BalanceOf); + +impl WeighData<(&BalanceOf,)> for WeightForSetDummy +{ + fn weigh_data(&self, target: (&BalanceOf,)) -> Weight { + let multiplier = self.0; + (*target.0 * multiplier).saturated_into::() + } +} + +impl ClassifyDispatch<(&BalanceOf,)> for WeightForSetDummy { + fn classify_dispatch(&self, target: (&BalanceOf,)) -> DispatchClass { + if *target.0 > >::from(1000u32) { + DispatchClass::Operational + } else { + DispatchClass::Normal + } + } +} + +/// A type alias for the balance type from this module's point of view. +type BalanceOf = ::Balance; + +/// Our module's configuration trait. All our types and constants go in here. If the /// module is dependent on specific other modules, then their configuration traits /// should be added to our implied traits list. /// @@ -454,6 +492,7 @@ decl_module! { // without worrying about gameability or attack scenarios. // If you not specify `Result` explicitly as return value, it will be added automatically // for you and `Ok(())` will be returned. + #[weight = WeightForSetDummy::(>::from(100u32))] fn set_dummy(origin, #[compact] new_value: T::Balance) { ensure_root(origin)?; // Put the new value into storage. @@ -600,7 +639,10 @@ mod tests { // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sr_primitives::{ - Perbill, traits::{BlakeTwo256, OnInitialize, OnFinalize, IdentityLookup}, testing::Header + Perbill, + traits::{BlakeTwo256, OnInitialize, OnFinalize, IdentityLookup}, + weights::GetDispatchInfo, + testing::Header }; impl_outer_origin! { @@ -726,4 +768,18 @@ mod tests { ); }) } + + #[test] + fn weights_work() { + // must have a default weight. + let default_call = >::accumulate_dummy(10); + let info = default_call.get_dispatch_info(); + // aka. `let info = as GetDispatchInfo>::get_dispatch_info(&default_call);` + assert_eq!(info.weight, 10_000); + + // must have a custom weight of `100 * arg = 2000` + let custom_call = >::set_dummy(20); + let info = custom_call.get_dispatch_info(); + assert_eq!(info.weight, 2000); + } } -- GitLab From ac11c330a95827211e1999781b5f691e72387c9e Mon Sep 17 00:00:00 2001 From: Xiliang Chen Date: Tue, 8 Oct 2019 22:30:16 +1300 Subject: [PATCH 194/275] expose module errors into metadata (#3752) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * expose module errors into metadata * it checks * Tests for error metadata * Apply suggestions from code review Co-Authored-By: Bastian Köcher * remove inherent errors from metadata * bump version * Apply suggestions from code review Co-Authored-By: Bastian Köcher * Update srml/support/src/error.rs Co-Authored-By: Bastian Köcher --- srml/metadata/src/lib.rs | 34 ++++++++++++++++++++++----- srml/support/src/dispatch.rs | 10 +++++++- srml/support/src/error.rs | 20 ++++++++++++++-- srml/support/src/metadata.rs | 39 ++++++++++++++++++++++++++++--- srml/support/test/tests/system.rs | 3 +++ 5 files changed, 94 insertions(+), 12 deletions(-) diff --git a/srml/metadata/src/lib.rs b/srml/metadata/src/lib.rs index bf7c379000..244d117564 100644 --- a/srml/metadata/src/lib.rs +++ b/srml/metadata/src/lib.rs @@ -179,7 +179,7 @@ pub struct OuterEventMetadata { >, } -/// All the metadata about a event. +/// All the metadata about an event. #[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] pub struct EventMetadata { @@ -209,6 +209,25 @@ pub struct ModuleConstantMetadata { pub documentation: DecodeDifferentArray<&'static str, StringBuf>, } +/// All the metadata about a module error. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub struct ErrorMetadata { + pub name: DecodeDifferentStr, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about errors in a module. +pub trait ModuleErrorMetadata { + fn metadata() -> &'static [ErrorMetadata]; +} + +impl ModuleErrorMetadata for &'static str { + fn metadata() -> &'static [ErrorMetadata] { + &[] + } +} + /// A technical trait to store lazy initiated vec value as static dyn pointer. pub trait DefaultByte: Send + Sync { fn default_byte(&self) -> Vec; @@ -326,8 +345,10 @@ pub enum RuntimeMetadata { V5(RuntimeMetadataDeprecated), /// Version 6 for runtime metadata. No longer used. V6(RuntimeMetadataDeprecated), - /// Version 7 for runtime metadata. - V7(RuntimeMetadataV7), + /// Version 7 for runtime metadata. No longer used. + V7(RuntimeMetadataDeprecated), + /// Version 8 for runtime metadata. + V8(RuntimeMetadataV8), } /// Enum that should fail. @@ -351,12 +372,12 @@ impl Decode for RuntimeMetadataDeprecated { /// The metadata of a runtime. #[derive(Eq, Encode, PartialEq)] #[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] -pub struct RuntimeMetadataV7 { +pub struct RuntimeMetadataV8 { pub modules: DecodeDifferentArray, } /// The latest version of the metadata. -pub type RuntimeMetadataLastVersion = RuntimeMetadataV7; +pub type RuntimeMetadataLastVersion = RuntimeMetadataV8; /// All metadata about an runtime module. #[derive(Clone, PartialEq, Eq, Encode)] @@ -367,6 +388,7 @@ pub struct ModuleMetadata { pub calls: ODFnA, pub event: ODFnA, pub constants: DFnA, + pub errors: DFnA, } type ODFnA = Option>; @@ -380,6 +402,6 @@ impl Into for RuntimeMetadataPrefixed { impl Into for RuntimeMetadataLastVersion { fn into(self) -> RuntimeMetadataPrefixed { - RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V7(self)) + RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V8(self)) } } diff --git a/srml/support/src/dispatch.rs b/srml/support/src/dispatch.rs index 67cd3e44bf..fd24c257ae 100644 --- a/srml/support/src/dispatch.rs +++ b/srml/support/src/dispatch.rs @@ -23,7 +23,7 @@ pub use std::fmt; pub use crate::codec::{Codec, EncodeLike, Decode, Encode, Input, Output, HasCompact, EncodeAsRef}; pub use srml_metadata::{ FunctionMetadata, DecodeDifferent, DecodeDifferentArray, FunctionArgumentMetadata, - ModuleConstantMetadata, DefaultByte, DefaultByteGetter, + ModuleConstantMetadata, DefaultByte, DefaultByteGetter, ModuleErrorMetadata, ErrorMetadata }; pub use sr_primitives::{ weights::{ @@ -1298,6 +1298,14 @@ macro_rules! decl_module { { $( $other_where_bounds )* } $( $constants )* } + + impl<$trait_instance: $trait_name $(, $instance: $instantiable)?> $crate::dispatch::ModuleErrorMetadata + for $mod_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )* + { + fn metadata() -> &'static [$crate::dispatch::ErrorMetadata] { + <$error_type as $crate::dispatch::ModuleErrorMetadata>::metadata() + } + } } } diff --git a/srml/support/src/error.rs b/srml/support/src/error.rs index 2f9d9379bf..848bd126d2 100644 --- a/srml/support/src/error.rs +++ b/srml/support/src/error.rs @@ -18,6 +18,7 @@ #[doc(hidden)] pub use sr_primitives::traits::LookupError; +pub use srml_metadata::{ModuleErrorMetadata, ErrorMetadata, DecodeDifferent}; /// Declare an error type for a runtime module. /// @@ -49,7 +50,7 @@ macro_rules! decl_error { $(#[$attr:meta])* pub enum $error:ident { $( - $( #[$variant_attr:meta] )* + $( #[doc = $doc_attr:tt] )* $name:ident ),* $(,)? @@ -62,7 +63,7 @@ macro_rules! decl_error { Other(&'static str), CannotLookup, $( - $(#[$variant_attr])* + $( #[doc = $doc_attr] )* $name ),* } @@ -115,6 +116,21 @@ macro_rules! decl_error { $crate::dispatch::DispatchError::new(None, self.as_u8(), Some(self.as_str())) } } + + impl $crate::error::ModuleErrorMetadata for $error { + fn metadata() -> &'static [$crate::error::ErrorMetadata] { + &[ + $( + $crate::error::ErrorMetadata { + name: $crate::error::DecodeDifferent::Encode(stringify!($name)), + documentation: $crate::error::DecodeDifferent::Encode(&[ + $( $doc_attr ),* + ]), + } + ),* + ] + } + } }; (@GENERATE_AS_U8 $self:ident diff --git a/srml/support/src/metadata.rs b/srml/support/src/metadata.rs index 7ae5f7d193..a223a14f9e 100644 --- a/srml/support/src/metadata.rs +++ b/srml/support/src/metadata.rs @@ -17,7 +17,7 @@ pub use srml_metadata::{ DecodeDifferent, FnEncode, RuntimeMetadata, ModuleMetadata, RuntimeMetadataLastVersion, DefaultByteGetter, RuntimeMetadataPrefixed, StorageEntryMetadata, StorageMetadata, - StorageEntryType, StorageEntryModifier, DefaultByte, StorageHasher + StorageEntryType, StorageEntryModifier, DefaultByte, StorageHasher, ModuleErrorMetadata }; /// Implements the metadata support for the given runtime and all its modules. @@ -96,6 +96,11 @@ macro_rules! __runtime_modules_to_metadata { $crate::metadata::FnEncode( $mod::$module::<$runtime $(, $mod::$instance )?>::module_constants_metadata ) + ), + errors: $crate::metadata::DecodeDifferent::Encode( + $crate::metadata::FnEncode( + <$mod::$module::<$runtime $(, $mod::$instance )?> as $crate::metadata::ModuleErrorMetadata>::metadata + ) ) }; $( $rest )* @@ -227,6 +232,7 @@ mod tests { use srml_metadata::{ EventMetadata, StorageEntryModifier, StorageEntryType, FunctionMetadata, StorageEntryMetadata, ModuleMetadata, RuntimeMetadataPrefixed, DefaultByte, ModuleConstantMetadata, DefaultByteGetter, + ErrorMetadata, }; use codec::{Encode, Decode}; use crate::traits::Get; @@ -278,7 +284,7 @@ mod tests { } mod event_module { - use crate::dispatch::Result; + use crate::dispatch::DispatchResult; pub trait Trait { type Origin; @@ -296,7 +302,19 @@ mod tests { decl_module! { pub struct Module for enum Call where origin: T::Origin { - fn aux_0(_origin) -> Result { unreachable!() } + type Error = Error; + + fn aux_0(_origin) -> DispatchResult { unreachable!() } + } + } + + crate::decl_error! { + pub enum Error { + /// Some user input error + UserInputError, + /// Something bad happened + /// this could be due to many reasons + BadThingHappened, } } } @@ -447,6 +465,7 @@ mod tests { } ]) ), + errors: DecodeDifferent::Encode(FnEncode(|| &[])), }, ModuleMetadata { name: DecodeDifferent::Encode("Module"), @@ -469,6 +488,19 @@ mod tests { ]) )), constants: DecodeDifferent::Encode(FnEncode(|| &[])), + errors: DecodeDifferent::Encode(FnEncode(|| &[ + ErrorMetadata { + name: DecodeDifferent::Encode("UserInputError"), + documentation: DecodeDifferent::Encode(&[" Some user input error"]), + }, + ErrorMetadata { + name: DecodeDifferent::Encode("BadThingHappened"), + documentation: DecodeDifferent::Encode(&[ + " Something bad happened", + " this could be due to many reasons", + ]), + }, + ])), }, ModuleMetadata { name: DecodeDifferent::Encode("Module2"), @@ -505,6 +537,7 @@ mod tests { ]) )), constants: DecodeDifferent::Encode(FnEncode(|| &[])), + errors: DecodeDifferent::Encode(FnEncode(|| &[])), }, ]) }; diff --git a/srml/support/test/tests/system.rs b/srml/support/test/tests/system.rs index 1040b26cc6..f1a427060a 100644 --- a/srml/support/test/tests/system.rs +++ b/srml/support/test/tests/system.rs @@ -29,7 +29,10 @@ support::decl_event!( support::decl_error! { pub enum Error { + /// Test error documentation TestError, + /// Error documentation + /// with multiple lines AnotherError } } -- GitLab From 607d7e833edd4db346e4aa14983a9af3f92d2756 Mon Sep 17 00:00:00 2001 From: Jim Posen Date: Tue, 8 Oct 2019 12:57:12 +0200 Subject: [PATCH 195/275] Refactor NativeExecutor to support multiple Wasm execution methods (#3677) * executor: Move definitions of externals out of wasm_executor module. * executor: Create WasmRuntime trait. This will be used to decouple the runtime cache from wasmi execution. * executor: Remove WasmExecutor and move methods to wasmi_execution. These will now be crate-internal functions and there is no need for the struct. * executor: Set default default_heap_pages in NativeExecutor. * cli: CLI configuration for Wasm execution method. * executor: Remove wasmi-specific code from wasm_runtime. * Respond to review comments. --- core/cli/src/lib.rs | 3 + core/cli/src/params.rs | 43 +- core/client/src/genesis.rs | 2 +- core/client/src/lib.rs | 4 +- core/client/src/light/call_executor.rs | 12 +- core/client/src/light/fetcher.rs | 40 +- core/executor/src/error.rs | 15 + .../{wasm_executor.rs => host_interface.rs} | 803 +--------------- core/executor/src/lib.rs | 8 +- core/executor/src/native_executor.rs | 111 +-- core/executor/src/sandbox.rs | 37 +- core/executor/src/wasm_runtime.rs | 173 ++++ core/executor/src/wasm_runtimes_cache.rs | 353 ------- core/executor/src/wasmi_execution.rs | 902 ++++++++++++++++++ core/service/src/builder.rs | 10 +- core/service/src/config.rs | 4 + core/service/test/src/lib.rs | 1 + core/sr-api-macros/tests/runtime_calls.rs | 2 +- core/test-client/src/lib.rs | 12 +- core/test-runtime/client/src/lib.rs | 4 +- core/test-runtime/src/system.rs | 51 +- node/executor/src/lib.rs | 6 +- 22 files changed, 1359 insertions(+), 1237 deletions(-) rename core/executor/src/{wasm_executor.rs => host_interface.rs} (61%) create mode 100644 core/executor/src/wasm_runtime.rs delete mode 100644 core/executor/src/wasm_runtimes_cache.rs create mode 100644 core/executor/src/wasmi_execution.rs diff --git a/core/cli/src/lib.rs b/core/cli/src/lib.rs index 2e7619116c..d4bb4f6f0d 100644 --- a/core/cli/src/lib.rs +++ b/core/cli/src/lib.rs @@ -380,6 +380,7 @@ impl<'a> ParseAndPrepareImport<'a> { Exit: IntoExit { let mut config = create_config_with_db_path(spec_factory, &self.params.shared_params, self.version)?; + config.wasm_method = self.params.wasm_method.into(); config.execution_strategies = ExecutionStrategies { importing: self.params.execution.into(), other: self.params.execution.into(), @@ -692,6 +693,8 @@ where service::Roles::FULL }; + config.wasm_method = cli.wasm_method.into(); + let exec = cli.execution_strategies; let exec_all_or = |strat: params::ExecutionStrategy| exec.execution.unwrap_or(strat).into(); config.execution_strategies = ExecutionStrategies { diff --git a/core/cli/src/params.rs b/core/cli/src/params.rs index 6656e1653f..b453c7dabd 100644 --- a/core/cli/src/params.rs +++ b/core/cli/src/params.rs @@ -18,7 +18,6 @@ use crate::traits::{AugmentClap, GetLogFilter}; use std::path::PathBuf; use structopt::{StructOpt, clap::{arg_enum, App, AppSettings, _clap_count_exprs, SubCommand, Arg}}; -use client; pub use crate::execution_strategy::ExecutionStrategy; @@ -44,6 +43,24 @@ impl Into for ExecutionStrategy { } } +arg_enum! { + /// How to execute Wasm runtime code + #[allow(missing_docs)] + #[derive(Debug, Clone)] + pub enum WasmExecutionMethod { + // Uses an interpreter. + Interpreted, + } +} + +impl Into for WasmExecutionMethod { + fn into(self) -> service::config::WasmExecutionMethod { + match self { + WasmExecutionMethod::Interpreted => service::config::WasmExecutionMethod::Interpreted, + } + } +} + arg_enum! { /// Whether off-chain workers are enabled. #[allow(missing_docs)] @@ -404,6 +421,18 @@ pub struct RunCmd { )] pub offchain_worker: OffchainWorkerEnabled, + /// Method for executing Wasm runtime code. + #[structopt( + long = "wasm-execution", + value_name = "METHOD", + raw( + possible_values = "&WasmExecutionMethod::variants()", + case_insensitive = "true", + default_value = r#""Interpreted""# + ) + )] + pub wasm_method: WasmExecutionMethod, + #[allow(missing_docs)] #[structopt(flatten)] pub execution_strategies: ExecutionStrategies, @@ -651,6 +680,18 @@ pub struct ImportBlocksCmd { #[structopt(flatten)] pub shared_params: SharedParams, + /// Method for executing Wasm runtime code. + #[structopt( + long = "wasm-execution", + value_name = "METHOD", + raw( + possible_values = "&WasmExecutionMethod::variants()", + case_insensitive = "true", + default_value = r#""Interpreted""# + ) + )] + pub wasm_method: WasmExecutionMethod, + /// The means of execution used when calling into the runtime while importing blocks. #[structopt( long = "execution", diff --git a/core/client/src/genesis.rs b/core/client/src/genesis.rs index 0c0d49f8ea..51e0536613 100644 --- a/core/client/src/genesis.rs +++ b/core/client/src/genesis.rs @@ -63,7 +63,7 @@ mod tests { ); fn executor() -> executor::NativeExecutor { - executor::NativeExecutor::new(None) + executor::NativeExecutor::new(executor::WasmExecutionMethod::Interpreted, None) } fn construct_block( diff --git a/core/client/src/lib.rs b/core/client/src/lib.rs index 70c9b75926..5a2cb746f3 100644 --- a/core/client/src/lib.rs +++ b/core/client/src/lib.rs @@ -49,7 +49,7 @@ //! use substrate_client::{Client, in_mem::Backend, LocalCallExecutor}; //! use primitives::Blake2Hasher; //! use sr_primitives::{StorageOverlay, ChildrenStorageOverlay}; -//! use executor::NativeExecutor; +//! use executor::{NativeExecutor, WasmExecutionMethod}; //! //! // In this example, we're using the `Block` and `RuntimeApi` types from the //! // `substrate-test-runtime-client` crate. These types are automatically generated when @@ -62,7 +62,7 @@ //! backend.clone(), //! LocalCallExecutor::new( //! backend.clone(), -//! NativeExecutor::::new(None), +//! NativeExecutor::::new(WasmExecutionMethod::Interpreted, None), //! None, //! ), //! // This parameter provides the storage for the chain genesis. diff --git a/core/client/src/light/call_executor.rs b/core/client/src/light/call_executor.rs index ec182cca11..d969c39a5a 100644 --- a/core/client/src/light/call_executor.rs +++ b/core/client/src/light/call_executor.rs @@ -304,7 +304,7 @@ mod tests { use consensus::BlockOrigin; use primitives::offchain::NeverOffchainExt; use test_client::{self, runtime::{Header, Digest, Block}, ClientExt, TestClient}; - use executor::NativeExecutor; + use executor::{NativeExecutor, WasmExecutionMethod}; use crate::backend::{Backend, NewBlockState}; use crate::in_mem::Backend as InMemBackend; use super::*; @@ -399,6 +399,10 @@ mod tests { } } + fn local_executor() -> NativeExecutor { + NativeExecutor::new(WasmExecutionMethod::Interpreted, None) + } + #[test] fn execution_proof_is_generated_and_checked() { fn execute(remote_client: &TestClient, at: u64, method: &'static str) -> (Vec, Vec) { @@ -413,8 +417,7 @@ mod tests { ).unwrap(); // check remote execution proof locally - let local_executor = NativeExecutor::::new(None); - let local_result = check_execution_proof(&local_executor, &RemoteCallRequest { + let local_result = check_execution_proof(&local_executor(), &RemoteCallRequest { block: test_client::runtime::Hash::default(), header: remote_header, method: method.into(), @@ -437,9 +440,8 @@ mod tests { ).unwrap(); // check remote execution proof locally - let local_executor = NativeExecutor::::new(None); let execution_result = check_execution_proof_with_make_header( - &local_executor, + &local_executor(), &RemoteCallRequest { block: test_client::runtime::Hash::default(), header: remote_header, diff --git a/core/client/src/light/fetcher.rs b/core/client/src/light/fetcher.rs index 3c4387209a..51e1ed3b81 100644 --- a/core/client/src/light/fetcher.rs +++ b/core/client/src/light/fetcher.rs @@ -503,7 +503,7 @@ pub mod tests { use parking_lot::Mutex; use codec::Decode; use crate::client::tests::prepare_client_with_key_changes; - use executor::{self, NativeExecutor}; + use executor::{NativeExecutor, WasmExecutionMethod}; use crate::error::Error as ClientError; use test_client::{ self, ClientExt, blockchain::HeaderBackend, AccountKeyring, @@ -563,12 +563,16 @@ pub mod tests { } type TestChecker = LightDataChecker< - executor::NativeExecutor, + NativeExecutor, Blake2Hasher, Block, DummyStorage, >; + fn local_executor() -> NativeExecutor { + NativeExecutor::new(WasmExecutionMethod::Interpreted, None) + } + fn prepare_for_read_proof_check() -> (TestChecker, Header, Vec>, u32) { // prepare remote client let remote_client = test_client::new(); @@ -596,8 +600,10 @@ pub mod tests { None, crate::backend::NewBlockState::Final, ).unwrap(); - let local_executor = NativeExecutor::::new(None); - let local_checker = LightDataChecker::new(Arc::new(DummyBlockchain::new(DummyStorage::new())), local_executor); + let local_checker = LightDataChecker::new( + Arc::new(DummyBlockchain::new(DummyStorage::new())), + local_executor() + ); (local_checker, remote_block_header, remote_read_proof, heap_pages) } @@ -636,8 +642,10 @@ pub mod tests { None, crate::backend::NewBlockState::Final, ).unwrap(); - let local_executor = NativeExecutor::::new(None); - let local_checker = LightDataChecker::new(Arc::new(DummyBlockchain::new(DummyStorage::new())), local_executor); + let local_checker = LightDataChecker::new( + Arc::new(DummyBlockchain::new(DummyStorage::new())), + local_executor(), + ); (local_checker, remote_block_header, remote_read_proof, child_value) } @@ -662,8 +670,10 @@ pub mod tests { if insert_cht { local_storage.insert_cht_root(1, local_cht_root); } - let local_executor = NativeExecutor::::new(None); - let local_checker = LightDataChecker::new(Arc::new(DummyBlockchain::new(DummyStorage::new())), local_executor); + let local_checker = LightDataChecker::new( + Arc::new(DummyBlockchain::new(DummyStorage::new())), + local_executor(), + ); (local_checker, local_cht_root, remote_block_header, remote_header_proof) } @@ -744,7 +754,7 @@ pub mod tests { let (remote_client, local_roots, test_cases) = prepare_client_with_key_changes(); let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(DummyStorage::new())), - NativeExecutor::::new(None) + local_executor(), ); let local_checker = &local_checker as &dyn FetchChecker; let max = remote_client.info().chain.best_number; @@ -813,7 +823,7 @@ pub mod tests { local_storage.changes_tries_cht_roots.insert(0, local_cht_root); let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(local_storage)), - NativeExecutor::::new(None) + local_executor(), ); // check proof on local client @@ -842,7 +852,7 @@ pub mod tests { let (remote_client, local_roots, test_cases) = prepare_client_with_key_changes(); let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(DummyStorage::new())), - NativeExecutor::::new(None) + local_executor(), ); let local_checker = &local_checker as &dyn FetchChecker; let max = remote_client.info().chain.best_number; @@ -924,7 +934,7 @@ pub mod tests { // fails when changes trie CHT is missing from the local db let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(DummyStorage::new())), - NativeExecutor::::new(None) + local_executor(), ); assert!(local_checker.check_changes_tries_proof(4, &remote_proof.roots, remote_proof.roots_proof.clone()).is_err()); @@ -934,7 +944,7 @@ pub mod tests { local_storage.changes_tries_cht_roots.insert(0, local_cht_root); let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(local_storage)), - NativeExecutor::::new(None) + local_executor(), ); assert!(local_checker.check_changes_tries_proof(4, &remote_proof.roots, vec![]).is_err()); } @@ -948,7 +958,7 @@ pub mod tests { let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(DummyStorage::new())), - NativeExecutor::::new(None) + local_executor(), ); let body_request = RemoteBodyRequest { @@ -971,7 +981,7 @@ pub mod tests { let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(DummyStorage::new())), - NativeExecutor::::new(None) + local_executor(), ); let body_request = RemoteBodyRequest { diff --git a/core/executor/src/error.rs b/core/executor/src/error.rs index c5148241ee..6b3c45ee49 100644 --- a/core/executor/src/error.rs +++ b/core/executor/src/error.rs @@ -98,3 +98,18 @@ impl From for Error { Error::Other(err) } } + +/// Type for errors occurring during Wasm runtime construction. +#[derive(Debug, derive_more::Display)] +pub enum WasmError { + /// Code could not be read from the state. + CodeNotFound, + /// Failure to reinitialize runtime instance from snapshot. + ApplySnapshotFailed, + /// Wasm code failed validation. + InvalidModule, + /// Wasm code could not be deserialized. + CantDeserializeWasm, + /// Instantiation error. + Instantiation(Error), +} diff --git a/core/executor/src/wasm_executor.rs b/core/executor/src/host_interface.rs similarity index 61% rename from core/executor/src/wasm_executor.rs rename to core/executor/src/host_interface.rs index 6ded0adad6..7c99415f6c 100644 --- a/core/executor/src/wasm_executor.rs +++ b/core/executor/src/host_interface.rs @@ -14,33 +14,20 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Wasm interface module. +//! Definition and implementation of the Substrate Wasm host interface. //! -//! This module defines and implements the wasm part of Substrate Host Interface and provides -//! an interface for calling into the wasm runtime. +//! These are the host functions callable from within the Substrate runtime. -use std::{convert::TryFrom, str, panic}; -use tiny_keccak; -use secp256k1; +use crate::error::{Error, Result}; -use wasmi::{ - Module, ModuleInstance, MemoryInstance, MemoryRef, TableRef, ImportsBuilder, ModuleRef, - memory_units::Pages, RuntimeValue::{I32, I64, self}, -}; -use super::{sandbox, allocator, error::{Error, Result}}; -use codec::{Encode, Decode}; +use codec::Encode; +use std::{convert::TryFrom, str, panic}; use primitives::{ - blake2_128, blake2_256, twox_64, twox_128, twox_256, ed25519, sr25519, Pair, crypto::KeyTypeId, - offchain, sandbox as sandbox_primitives, Blake2Hasher, - traits::Externalities, -}; -use trie::TrieConfiguration; -use trie::trie_types::Layout; -use log::trace; -use wasm_interface::{ - FunctionContext, HostFunctions, Pointer, WordSize, Sandbox, MemoryId, PointerType, - Result as WResult, + blake2_128, blake2_256, twox_64, twox_128, twox_256, ed25519, sr25519, Blake2Hasher, Pair, + crypto::KeyTypeId, offchain, }; +use trie::{TrieConfiguration, trie_types::Layout}; +use wasm_interface::{FunctionContext, Pointer, PointerType, Result as WResult, WordSize}; #[cfg(feature="wasm-extern-trace")] macro_rules! debug_trace { @@ -52,317 +39,7 @@ macro_rules! debug_trace { ( $( $x:tt )* ) => () } -struct FunctionExecutor { - sandbox_store: sandbox::Store, - heap: allocator::FreeingBumpHeapAllocator, - memory: MemoryRef, - table: Option, -} - -impl FunctionExecutor { - fn new(m: MemoryRef, heap_base: u32, t: Option) -> Result { - Ok(FunctionExecutor { - sandbox_store: sandbox::Store::new(), - heap: allocator::FreeingBumpHeapAllocator::new(heap_base), - memory: m, - table: t, - }) - } -} - -impl sandbox::SandboxCapabilities for FunctionExecutor { - type SupervisorFuncRef = wasmi::FuncRef; - - fn store(&self) -> &sandbox::Store { - &self.sandbox_store - } - fn store_mut(&mut self) -> &mut sandbox::Store { - &mut self.sandbox_store - } - fn allocate(&mut self, len: WordSize) -> Result> { - let heap = &mut self.heap; - self.memory.with_direct_access_mut(|mem| { - heap.allocate(mem, len) - }) - } - fn deallocate(&mut self, ptr: Pointer) -> Result<()> { - let heap = &mut self.heap; - self.memory.with_direct_access_mut(|mem| { - heap.deallocate(mem, ptr) - }) - } - fn write_memory(&mut self, ptr: Pointer, data: &[u8]) -> Result<()> { - self.memory.set(ptr.into(), data).map_err(Into::into) - } - fn read_memory(&self, ptr: Pointer, len: WordSize) -> Result> { - self.memory.get(ptr.into(), len as usize).map_err(Into::into) - } - - fn invoke( - &mut self, - dispatch_thunk: &Self::SupervisorFuncRef, - invoke_args_ptr: Pointer, - invoke_args_len: WordSize, - state: u32, - func_idx: sandbox::SupervisorFuncIndex, - ) -> Result - { - let result = wasmi::FuncInstance::invoke( - dispatch_thunk, - &[ - RuntimeValue::I32(u32::from(invoke_args_ptr) as i32), - RuntimeValue::I32(invoke_args_len as i32), - RuntimeValue::I32(state as i32), - RuntimeValue::I32(usize::from(func_idx) as i32), - ], - self, - ); - match result { - Ok(Some(RuntimeValue::I64(val))) => Ok(val), - Ok(_) => return Err("Supervisor function returned unexpected result!".into()), - Err(err) => Err(Error::Trap(err)), - } - } -} - -impl FunctionContext for FunctionExecutor { - fn read_memory_into(&self, address: Pointer, dest: &mut [u8]) -> WResult<()> { - self.memory.get_into(address.into(), dest).map_err(|e| format!("{:?}", e)) - } - - fn write_memory(&mut self, address: Pointer, data: &[u8]) -> WResult<()> { - self.memory.set(address.into(), data).map_err(|e| format!("{:?}", e)) - } - - fn allocate_memory(&mut self, size: WordSize) -> WResult> { - let heap = &mut self.heap; - self.memory.with_direct_access_mut(|mem| { - heap.allocate(mem, size).map_err(|e| format!("{:?}", e)) - }) - } - - fn deallocate_memory(&mut self, ptr: Pointer) -> WResult<()> { - let heap = &mut self.heap; - self.memory.with_direct_access_mut(|mem| { - heap.deallocate(mem, ptr).map_err(|e| format!("{:?}", e)) - }) - } - - fn sandbox(&mut self) -> &mut dyn Sandbox { - self - } -} - -impl Sandbox for FunctionExecutor { - fn memory_get( - &self, - memory_id: MemoryId, - offset: WordSize, - buf_ptr: Pointer, - buf_len: WordSize, - ) -> WResult { - let sandboxed_memory = self.sandbox_store.memory(memory_id).map_err(|e| format!("{:?}", e))?; - - match MemoryInstance::transfer( - &sandboxed_memory, - offset as usize, - &self.memory, - buf_ptr.into(), - buf_len as usize, - ) { - Ok(()) => Ok(sandbox_primitives::ERR_OK), - Err(_) => Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS), - } - } - - fn memory_set( - &mut self, - memory_id: MemoryId, - offset: WordSize, - val_ptr: Pointer, - val_len: WordSize, - ) -> WResult { - let sandboxed_memory = self.sandbox_store.memory(memory_id).map_err(|e| format!("{:?}", e))?; - - match MemoryInstance::transfer( - &self.memory, - val_ptr.into(), - &sandboxed_memory, - offset as usize, - val_len as usize, - ) { - Ok(()) => Ok(sandbox_primitives::ERR_OK), - Err(_) => Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS), - } - } - - fn memory_teardown(&mut self, memory_id: MemoryId) -> WResult<()> { - self.sandbox_store.memory_teardown(memory_id).map_err(|e| format!("{:?}", e)) - } - - fn memory_new( - &mut self, - initial: u32, - maximum: u32, - ) -> WResult { - self.sandbox_store.new_memory(initial, maximum).map_err(|e| format!("{:?}", e)) - } - - fn invoke( - &mut self, - instance_id: u32, - export_name: &str, - args: &[u8], - return_val: Pointer, - return_val_len: WordSize, - state: u32, - ) -> WResult { - trace!(target: "sr-sandbox", "invoke, instance_idx={}", instance_id); - - // Deserialize arguments and convert them into wasmi types. - let args = Vec::::decode(&mut &args[..]) - .map_err(|_| "Can't decode serialized arguments for the invocation")? - .into_iter() - .map(Into::into) - .collect::>(); - - let instance = self.sandbox_store.instance(instance_id).map_err(|e| format!("{:?}", e))?; - let result = instance.invoke(export_name, &args, self, state); - - match result { - Ok(None) => Ok(sandbox_primitives::ERR_OK), - Ok(Some(val)) => { - // Serialize return value and write it back into the memory. - sandbox_primitives::ReturnValue::Value(val.into()).using_encoded(|val| { - if val.len() > return_val_len as usize { - Err("Return value buffer is too small")?; - } - self.write_memory(return_val, val).map_err(|_| "Return value buffer is OOB")?; - Ok(sandbox_primitives::ERR_OK) - }) - } - Err(_) => Ok(sandbox_primitives::ERR_EXECUTION), - } - } - - fn instance_teardown(&mut self, instance_id: u32) -> WResult<()> { - self.sandbox_store.instance_teardown(instance_id).map_err(|e| format!("{:?}", e)) - } - - fn instance_new( - &mut self, - dispatch_thunk_id: u32, - wasm: &[u8], - raw_env_def: &[u8], - state: u32, - ) -> WResult { - // Extract a dispatch thunk from instance's table by the specified index. - let dispatch_thunk = { - let table = self.table.as_ref() - .ok_or_else(|| "Runtime doesn't have a table; sandbox is unavailable")?; - table.get(dispatch_thunk_id) - .map_err(|_| "dispatch_thunk_idx is out of the table bounds")? - .ok_or_else(|| "dispatch_thunk_idx points on an empty table entry")? - .clone() - }; - - let instance_idx_or_err_code = - match sandbox::instantiate(self, dispatch_thunk, wasm, raw_env_def, state) { - Ok(instance_idx) => instance_idx, - Err(sandbox::InstantiationError::StartTrapped) => - sandbox_primitives::ERR_EXECUTION, - Err(_) => sandbox_primitives::ERR_MODULE, - }; - - Ok(instance_idx_or_err_code as u32) - } -} - -trait WritePrimitive { - fn write_primitive(&mut self, ptr: Pointer, t: T) -> WResult<()>; -} - -impl WritePrimitive for &mut dyn FunctionContext { - fn write_primitive(&mut self, ptr: Pointer, t: u32) -> WResult<()> { - let r = t.to_le_bytes(); - self.write_memory(ptr.cast(), &r) - } -} - -trait ReadPrimitive { - fn read_primitive(&self, offset: Pointer) -> WResult; -} - -impl ReadPrimitive for &mut dyn FunctionContext { - fn read_primitive(&self, ptr: Pointer) -> WResult { - let mut r = [0u8; 4]; - self.read_memory_into(ptr.cast(), &mut r)?; - Ok(u32::from_le_bytes(r)) - } -} - -fn deadline_to_timestamp(deadline: u64) -> Option { - if deadline == 0 { - None - } else { - Some(offchain::Timestamp::from_unix_millis(deadline)) - } -} - -impl FunctionExecutor { - fn resolver() -> &'static dyn wasmi::ModuleImportResolver { - struct Resolver; - impl wasmi::ModuleImportResolver for Resolver { - fn resolve_func(&self, name: &str, signature: &wasmi::Signature) - -> std::result::Result - { - let signature = wasm_interface::Signature::from(signature); - - if let Some((index, func)) = SubstrateExternals::functions().iter() - .enumerate() - .find(|f| name == f.1.name()) - { - if signature == func.signature() { - Ok(wasmi::FuncInstance::alloc_host(signature.into(), index)) - } else { - Err(wasmi::Error::Instantiation( - format!( - "Invalid signature for function `{}` expected `{:?}`, got `{:?}`", - func.name(), - signature, - func.signature(), - ) - )) - } - } else { - Err(wasmi::Error::Instantiation( - format!("Export {} not found", name), - )) - } - } - } - &Resolver - } -} - -impl wasmi::Externals for FunctionExecutor { - fn invoke_index(&mut self, index: usize, args: wasmi::RuntimeArgs) - -> std::result::Result, wasmi::Trap> - { - let mut args = args.as_ref().iter().copied().map(Into::into); - let function = SubstrateExternals::functions().get(index).ok_or_else(|| - Error::from( - format!("Could not find host function with index: {}", index), - ) - )?; - - function.execute(self, &mut args) - .map_err(Error::FunctionExecution) - .map_err(wasmi::Trap::from) - .map(|v| v.map(Into::into)) - } -} -struct SubstrateExternals; +pub struct SubstrateExternals; impl_wasm_host_interface! { impl SubstrateExternals where context { @@ -1400,6 +1077,29 @@ impl_wasm_host_interface! { } } +trait WritePrimitive { + fn write_primitive(&mut self, ptr: Pointer, t: T) -> WResult<()>; +} + +impl WritePrimitive for &mut dyn FunctionContext { + fn write_primitive(&mut self, ptr: Pointer, t: u32) -> WResult<()> { + let r = t.to_le_bytes(); + self.write_memory(ptr.cast(), &r) + } +} + +trait ReadPrimitive { + fn read_primitive(&self, offset: Pointer) -> WResult; +} + +impl ReadPrimitive for &mut dyn FunctionContext { + fn read_primitive(&self, ptr: Pointer) -> WResult { + let mut r = [0u8; 4]; + self.read_memory_into(ptr.cast(), &mut r)?; + Ok(u32::from_le_bytes(r)) + } +} + /// Execute closure that access external storage. /// /// All panics that happen within closure are captured and transformed into @@ -1419,438 +1119,11 @@ fn with_external_storage(f: F) -> std::result::Result .map_err(|err| format!("{}", err)) } -/// Wasm rust executor for contracts. -/// -/// Executes the provided code in a sandboxed wasm runtime. -#[derive(Debug, Clone)] -pub struct WasmExecutor; - -impl WasmExecutor { - /// Create a new instance. - pub fn new() -> Self { - WasmExecutor - } - - /// Call a given method in the given code. - /// - /// Signature of this method needs to be `(I32, I32) -> I64`. - /// - /// This should be used for tests only. - pub fn call>( - &self, - ext: &mut E, - heap_pages: usize, - code: &[u8], - method: &str, - data: &[u8], - ) -> Result> { - let module = wasmi::Module::from_buffer(code)?; - let module = Self::instantiate_module(heap_pages, &module)?; - - self.call_in_wasm_module(ext, &module, method, data) - } - - /// Call a given method with a custom signature in the given code. - /// - /// This should be used for tests only. - pub fn call_with_custom_signature< - E: Externalities, - F: FnOnce(&mut dyn FnMut(&[u8]) -> Result) -> Result>, - FR: FnOnce(Option, &MemoryRef) -> Result>, - R, - >( - &self, - ext: &mut E, - heap_pages: usize, - code: &[u8], - method: &str, - create_parameters: F, - filter_result: FR, - ) -> Result { - let module = wasmi::Module::from_buffer(code)?; - let module = Self::instantiate_module(heap_pages, &module)?; - - self.call_in_wasm_module_with_custom_signature( - ext, - &module, - method, - create_parameters, - filter_result, - ) - } - - fn get_mem_instance(module: &ModuleRef) -> Result { - Ok(module - .export_by_name("memory") - .ok_or_else(|| Error::InvalidMemoryReference)? - .as_memory() - .ok_or_else(|| Error::InvalidMemoryReference)? - .clone()) - } - - /// Find the global named `__heap_base` in the given wasm module instance and - /// tries to get its value. - fn get_heap_base(module: &ModuleRef) -> Result { - let heap_base_val = module - .export_by_name("__heap_base") - .ok_or_else(|| Error::HeapBaseNotFoundOrInvalid)? - .as_global() - .ok_or_else(|| Error::HeapBaseNotFoundOrInvalid)? - .get(); - - match heap_base_val { - wasmi::RuntimeValue::I32(v) => Ok(v as u32), - _ => Err(Error::HeapBaseNotFoundOrInvalid), - } - } - - /// Call a given method in the given wasm-module runtime. - pub fn call_in_wasm_module>( - &self, - ext: &mut E, - module_instance: &ModuleRef, - method: &str, - data: &[u8], - ) -> Result> { - self.call_in_wasm_module_with_custom_signature( - ext, - module_instance, - method, - |alloc| { - let offset = alloc(data)?; - Ok(vec![I32(offset as i32), I32(data.len() as i32)]) - }, - |res, memory| { - if let Some(I64(r)) = res { - let offset = r as u32; - let length = (r as u64 >> 32) as usize; - memory.get(offset, length).map_err(|_| Error::Runtime).map(Some) - } else { - Ok(None) - } - } - ) - } - - /// Call a given method in the given wasm-module runtime. - fn call_in_wasm_module_with_custom_signature< - E: Externalities, - F: FnOnce(&mut dyn FnMut(&[u8]) -> Result) -> Result>, - FR: FnOnce(Option, &MemoryRef) -> Result>, - R, - >( - &self, - ext: &mut E, - module_instance: &ModuleRef, - method: &str, - create_parameters: F, - filter_result: FR, - ) -> Result { - // extract a reference to a linear memory, optional reference to a table - // and then initialize FunctionExecutor. - let memory = Self::get_mem_instance(module_instance)?; - let table: Option = module_instance - .export_by_name("__indirect_function_table") - .and_then(|e| e.as_table().cloned()); - let heap_base = Self::get_heap_base(module_instance)?; - - let mut fec = FunctionExecutor::new( - memory.clone(), - heap_base, - table, - )?; - - let parameters = create_parameters(&mut |data: &[u8]| { - let offset = fec.allocate_memory(data.len() as u32)?; - fec.write_memory(offset, data).map(|_| offset.into()).map_err(Into::into) - })?; - - let result = runtime_io::with_externalities( - ext, - || module_instance.invoke_export(method, ¶meters, &mut fec), - ); - - match result { - Ok(val) => match filter_result(val, &memory)? { - Some(val) => Ok(val), - None => Err(Error::InvalidReturn), - }, - Err(e) => { - trace!( - target: "wasm-executor", - "Failed to execute code with {} pages", - memory.current_size().0 - ); - Err(e.into()) - }, - } - } - - /// Prepare module instance - pub fn instantiate_module( - heap_pages: usize, - module: &Module, - ) -> Result { - // start module instantiation. Don't run 'start' function yet. - let intermediate_instance = ModuleInstance::new( - module, - &ImportsBuilder::new() - .with_resolver("env", FunctionExecutor::resolver()) - )?; - - // Verify that the module has the heap base global variable. - let _ = Self::get_heap_base(intermediate_instance.not_started_instance())?; - - // Extract a reference to a linear memory. - let memory = Self::get_mem_instance(intermediate_instance.not_started_instance())?; - memory.grow(Pages(heap_pages)).map_err(|_| Error::Runtime)?; - - if intermediate_instance.has_start() { - // Runtime is not allowed to have the `start` function. - Err(Error::RuntimeHasStartFn) - } else { - Ok(intermediate_instance.assert_no_start()) - } +fn deadline_to_timestamp(deadline: u64) -> Option { + if deadline == 0 { + None + } else { + Some(offchain::Timestamp::from_unix_millis(deadline)) } } - -#[cfg(test)] -mod tests { - use super::*; - - use codec::Encode; - - use state_machine::TestExternalities as CoreTestExternalities; - use hex_literal::hex; - use primitives::map; - use runtime_test::WASM_BINARY; - use substrate_offchain::testing; - - type TestExternalities = CoreTestExternalities; - - #[test] - fn returning_should_work() { - let mut ext = TestExternalities::default(); - let test_code = WASM_BINARY; - - let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_empty_return", &[]).unwrap(); - assert_eq!(output, vec![0u8; 0]); - } - - #[test] - fn panicking_should_work() { - let mut ext = TestExternalities::default(); - let test_code = WASM_BINARY; - - let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_panic", &[]); - assert!(output.is_err()); - - let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_conditional_panic", &[]); - assert_eq!(output.unwrap(), vec![0u8; 0]); - - let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_conditional_panic", &[2]); - assert!(output.is_err()); - } - - #[test] - fn storage_should_work() { - let mut ext = TestExternalities::default(); - ext.set_storage(b"foo".to_vec(), b"bar".to_vec()); - let test_code = WASM_BINARY; - - let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_data_in", b"Hello world").unwrap(); - - assert_eq!(output, b"all ok!".to_vec()); - - let expected = TestExternalities::new((map![ - b"input".to_vec() => b"Hello world".to_vec(), - b"foo".to_vec() => b"bar".to_vec(), - b"baz".to_vec() => b"bar".to_vec() - ], map![])); - assert_eq!(ext, expected); - } - - #[test] - fn clear_prefix_should_work() { - let mut ext = TestExternalities::default(); - ext.set_storage(b"aaa".to_vec(), b"1".to_vec()); - ext.set_storage(b"aab".to_vec(), b"2".to_vec()); - ext.set_storage(b"aba".to_vec(), b"3".to_vec()); - ext.set_storage(b"abb".to_vec(), b"4".to_vec()); - ext.set_storage(b"bbb".to_vec(), b"5".to_vec()); - let test_code = WASM_BINARY; - - // This will clear all entries which prefix is "ab". - let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_clear_prefix", b"ab").unwrap(); - - assert_eq!(output, b"all ok!".to_vec()); - - let expected = TestExternalities::new((map![ - b"aaa".to_vec() => b"1".to_vec(), - b"aab".to_vec() => b"2".to_vec(), - b"bbb".to_vec() => b"5".to_vec() - ], map![])); - assert_eq!(expected, ext); - } - - #[test] - fn blake2_256_should_work() { - let mut ext = TestExternalities::default(); - let test_code = WASM_BINARY; - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_blake2_256", &[]).unwrap(), - blake2_256(&b""[..]).encode() - ); - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_blake2_256", b"Hello world!").unwrap(), - blake2_256(&b"Hello world!"[..]).encode() - ); - } - - #[test] - fn blake2_128_should_work() { - let mut ext = TestExternalities::default(); - let test_code = WASM_BINARY; - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_blake2_128", &[]).unwrap(), - blake2_128(&b""[..]).encode() - ); - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_blake2_128", b"Hello world!").unwrap(), - blake2_128(&b"Hello world!"[..]).encode() - ); - } - - #[test] - fn twox_256_should_work() { - let mut ext = TestExternalities::default(); - let test_code = WASM_BINARY; - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_twox_256", &[]).unwrap(), - hex!("99e9d85137db46ef4bbea33613baafd56f963c64b1f3685a4eb4abd67ff6203a"), - ); - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_twox_256", b"Hello world!").unwrap(), - hex!("b27dfd7f223f177f2a13647b533599af0c07f68bda23d96d059da2b451a35a74"), - ); - } - - #[test] - fn twox_128_should_work() { - let mut ext = TestExternalities::default(); - let test_code = WASM_BINARY; - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_twox_128", &[]).unwrap(), - hex!("99e9d85137db46ef4bbea33613baafd5") - ); - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_twox_128", b"Hello world!").unwrap(), - hex!("b27dfd7f223f177f2a13647b533599af") - ); - } - - #[test] - fn ed25519_verify_should_work() { - let mut ext = TestExternalities::::default(); - let test_code = WASM_BINARY; - let key = ed25519::Pair::from_seed(&blake2_256(b"test")); - let sig = key.sign(b"all ok!"); - let mut calldata = vec![]; - calldata.extend_from_slice(key.public().as_ref()); - calldata.extend_from_slice(sig.as_ref()); - - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_ed25519_verify", &calldata).unwrap(), - vec![1] - ); - - let other_sig = key.sign(b"all is not ok!"); - let mut calldata = vec![]; - calldata.extend_from_slice(key.public().as_ref()); - calldata.extend_from_slice(other_sig.as_ref()); - - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_ed25519_verify", &calldata).unwrap(), - vec![0] - ); - } - - #[test] - fn sr25519_verify_should_work() { - let mut ext = TestExternalities::::default(); - let test_code = WASM_BINARY; - let key = sr25519::Pair::from_seed(&blake2_256(b"test")); - let sig = key.sign(b"all ok!"); - let mut calldata = vec![]; - calldata.extend_from_slice(key.public().as_ref()); - calldata.extend_from_slice(sig.as_ref()); - - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sr25519_verify", &calldata).unwrap(), - vec![1] - ); - - let other_sig = key.sign(b"all is not ok!"); - let mut calldata = vec![]; - calldata.extend_from_slice(key.public().as_ref()); - calldata.extend_from_slice(other_sig.as_ref()); - - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sr25519_verify", &calldata).unwrap(), - vec![0] - ); - } - - #[test] - fn ordered_trie_root_should_work() { - let mut ext = TestExternalities::::default(); - let trie_input = vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()]; - let test_code = WASM_BINARY; - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_ordered_trie_root", &[]).unwrap(), - Layout::::ordered_trie_root(trie_input.iter()).as_fixed_bytes().encode() - ); - } - - #[test] - fn offchain_local_storage_should_work() { - use substrate_client::backend::OffchainStorage; - - let mut ext = TestExternalities::::default(); - let (offchain, state) = testing::TestOffchainExt::new(); - ext.set_offchain_externalities(offchain); - let test_code = WASM_BINARY; - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_offchain_local_storage", &[]).unwrap(), - vec![0] - ); - assert_eq!(state.read().persistent_storage.get(b"", b"test"), Some(vec![])); - } - - #[test] - fn offchain_http_should_work() { - let mut ext = TestExternalities::::default(); - let (offchain, state) = testing::TestOffchainExt::new(); - ext.set_offchain_externalities(offchain); - state.write().expect_request( - 0, - testing::PendingRequest { - method: "POST".into(), - uri: "http://localhost:12345".into(), - body: vec![1, 2, 3, 4], - headers: vec![("X-Auth".to_owned(), "test".to_owned())], - sent: true, - response: Some(vec![1, 2, 3]), - response_headers: vec![("X-Auth".to_owned(), "hello".to_owned())], - ..Default::default() - }, - ); - - let test_code = WASM_BINARY; - assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_offchain_http", &[]).unwrap(), - vec![0] - ); - } -} diff --git a/core/executor/src/lib.rs b/core/executor/src/lib.rs index b5c5027951..8b833c9b08 100644 --- a/core/executor/src/lib.rs +++ b/core/executor/src/lib.rs @@ -31,24 +31,24 @@ #[macro_use] mod wasm_utils; -mod wasm_executor; +mod wasmi_execution; #[macro_use] mod native_executor; mod sandbox; mod allocator; -mod wasm_runtimes_cache; +mod host_interface; +mod wasm_runtime; pub mod error; pub use wasmi; -pub use wasm_executor::WasmExecutor; pub use native_executor::{with_native_environment, NativeExecutor, NativeExecutionDispatch}; -pub use wasm_runtimes_cache::RuntimesCache; pub use runtime_version::{RuntimeVersion, NativeVersion}; pub use codec::Codec; #[doc(hidden)] pub use primitives::{Blake2Hasher, traits::Externalities}; #[doc(hidden)] pub use wasm_interface; +pub use wasm_runtime::WasmExecutionMethod; /// Provides runtime information. pub trait RuntimeInfo { diff --git a/core/executor/src/native_executor.rs b/core/executor/src/native_executor.rs index cdf0be7f76..5f4e91b16d 100644 --- a/core/executor/src/native_executor.rs +++ b/core/executor/src/native_executor.rs @@ -16,19 +16,20 @@ use std::{result, cell::RefCell, panic::UnwindSafe}; use crate::error::{Error, Result}; -use crate::wasm_executor::WasmExecutor; +use crate::wasm_runtime::{RuntimesCache, WasmExecutionMethod, WasmRuntime}; +use crate::RuntimeInfo; use runtime_version::{NativeVersion, RuntimeVersion}; use codec::{Decode, Encode}; -use crate::RuntimeInfo; use primitives::{Blake2Hasher, NativeOrEncoded, traits::{CodeExecutor, Externalities}}; use log::{trace, warn}; -use crate::RuntimesCache; - thread_local! { static RUNTIMES_CACHE: RefCell = RefCell::new(RuntimesCache::new()); } +/// Default num of pages for the heap +const DEFAULT_HEAP_PAGES: u64 = 1024; + fn safe_call(f: F) -> Result where F: UnwindSafe + FnOnce() -> U { @@ -65,31 +66,52 @@ pub trait NativeExecutionDispatch: Send + Sync { pub struct NativeExecutor { /// Dummy field to avoid the compiler complaining about us not using `D`. _dummy: ::std::marker::PhantomData, - /// The fallback executor in case native isn't available. - fallback: WasmExecutor, + /// Method used to execute fallback Wasm code. + fallback_method: WasmExecutionMethod, /// Native runtime version info. native_version: NativeVersion, /// The number of 64KB pages to allocate for Wasm execution. - default_heap_pages: Option, + default_heap_pages: u64, } impl NativeExecutor { /// Create new instance. - pub fn new(default_heap_pages: Option) -> Self { + /// + /// # Parameters + /// + /// `fallback_method` - Method used to execute fallback Wasm code. + /// + /// `default_heap_pages` - Number of 64KB pages to allocate for Wasm execution. + /// Defaults to `DEFAULT_HEAP_PAGES` if `None` is provided. + pub fn new(fallback_method: WasmExecutionMethod, default_heap_pages: Option) -> Self { NativeExecutor { _dummy: Default::default(), - fallback: WasmExecutor::new(), + fallback_method, native_version: D::native_version(), - default_heap_pages: default_heap_pages, + default_heap_pages: default_heap_pages.unwrap_or(DEFAULT_HEAP_PAGES), } } + + fn with_runtime( + &self, + ext: &mut E, + f: impl for <'a> FnOnce(&'a mut dyn WasmRuntime, &'a mut E) -> Result + ) -> Result + where E: Externalities + { + RUNTIMES_CACHE.with(|cache| { + let mut cache = cache.borrow_mut(); + let runtime = cache.fetch_runtime(ext, self.fallback_method, self.default_heap_pages)?; + f(runtime, ext) + }) + } } impl Clone for NativeExecutor { fn clone(&self) -> Self { NativeExecutor { _dummy: Default::default(), - fallback: self.fallback.clone(), + fallback_method: self.fallback_method, native_version: D::native_version(), default_heap_pages: self.default_heap_pages, } @@ -105,17 +127,13 @@ impl RuntimeInfo for NativeExecutor { &self, ext: &mut E, ) -> Option { - RUNTIMES_CACHE.with(|cache| { - let cache = &mut cache.borrow_mut(); - - match cache.fetch_runtime(&self.fallback, ext, self.default_heap_pages) { - Ok(runtime) => runtime.version(), - Err(e) => { - warn!(target: "executor", "Failed to fetch runtime: {:?}", e); - None - } + match self.with_runtime(ext, |runtime, _ext| Ok(runtime.version())) { + Ok(version) => version, + Err(e) => { + warn!(target: "executor", "Failed to fetch runtime: {:?}", e); + None } - }) + } } } @@ -135,15 +153,9 @@ impl CodeExecutor for NativeExecutor, ) -> (Result>, bool){ - RUNTIMES_CACHE.with(|cache| { - let cache = &mut cache.borrow_mut(); - let cached_runtime = match cache.fetch_runtime( - &self.fallback, ext, self.default_heap_pages, - ) { - Ok(cached_runtime) => cached_runtime, - Err(e) => return (Err(e), false), - }; - let onchain_version = cached_runtime.version(); + let mut used_native = false; + let result = self.with_runtime(ext, |runtime, ext| { + let onchain_version = runtime.version(); match ( use_native, onchain_version @@ -160,25 +172,9 @@ impl CodeExecutor for NativeExecutor".into(), |v| format!("{}", v)) ); - ( - cached_runtime.with(|module| - self.fallback - .call_in_wasm_module(ext, module, method, data) - .map(NativeOrEncoded::Encoded) - ), - false - ) - } - (false, _, _) => { - ( - cached_runtime.with(|module| - self.fallback - .call_in_wasm_module(ext, module, method, data) - .map(NativeOrEncoded::Encoded) - ), - false - ) + runtime.call(ext, method, data).map(NativeOrEncoded::Encoded) } + (false, _, _) => runtime.call(ext, method, data).map(NativeOrEncoded::Encoded), (true, true, Some(call)) => { trace!( target: "executor", @@ -188,11 +184,13 @@ impl CodeExecutor for NativeExecutor".into(), |v| format!("{}", v)) ); - ( - with_native_environment(ext, move || (call)()) - .and_then(|r| r.map(NativeOrEncoded::Native).map_err(|s| Error::ApiError(s.to_string()))), - true - ) + + used_native = true; + with_native_environment(ext, move || (call)()) + .and_then(|r| r + .map(NativeOrEncoded::Native) + .map_err(|s| Error::ApiError(s.to_string())) + ) } _ => { trace!( @@ -201,10 +199,13 @@ impl CodeExecutor for NativeExecutor".into(), |v| format!("{}", v)) ); - (D::dispatch(ext, method, data).map(NativeOrEncoded::Encoded), true) + + used_native = true; + D::dispatch(ext, method, data).map(NativeOrEncoded::Encoded) } } - }) + }); + (result, used_native) } } diff --git a/core/executor/src/sandbox.rs b/core/executor/src/sandbox.rs index f09c246679..de49cc9f7c 100644 --- a/core/executor/src/sandbox.rs +++ b/core/executor/src/sandbox.rs @@ -586,14 +586,27 @@ impl Store { #[cfg(test)] mod tests { use super::*; - use primitives::{Blake2Hasher}; - use crate::wasm_executor::WasmExecutor; + use primitives::{Blake2Hasher, traits::Externalities}; + use crate::wasm_runtime::WasmRuntime; + use crate::wasmi_execution; use state_machine::TestExternalities as CoreTestExternalities; use wabt; use runtime_test::WASM_BINARY; type TestExternalities = CoreTestExternalities; + fn call_wasm>( + ext: &mut E, + heap_pages: u64, + code: &[u8], + method: &str, + data: &[u8], + ) -> Result> { + let mut instance = wasmi_execution::create_instance(ext, code, heap_pages) + .map_err(|err| err.to_string())?; + instance.call(ext, method, data) + } + #[test] fn sandbox_should_work() { let mut ext = TestExternalities::::default(); @@ -621,7 +634,7 @@ mod tests { "#).unwrap(); assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox", &code).unwrap(), + call_wasm(&mut ext, 8, &test_code[..], "test_sandbox", &code).unwrap(), vec![1], ); } @@ -642,7 +655,7 @@ mod tests { "#).unwrap(); assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox", &code).unwrap(), + call_wasm(&mut ext, 8, &test_code[..], "test_sandbox", &code).unwrap(), vec![0], ); } @@ -662,7 +675,7 @@ mod tests { ) "#).unwrap(); - let res = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_exhaust_heap", &code); + let res = call_wasm(&mut ext, 8, &test_code[..], "test_exhaust_heap", &code); assert_eq!(res.is_err(), true); if let Err(err) = res { assert_eq!( @@ -708,7 +721,7 @@ mod tests { "#).unwrap(); assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox", &code).unwrap(), + call_wasm(&mut ext, 8, &test_code[..], "test_sandbox", &code).unwrap(), vec![1], ); } @@ -742,7 +755,7 @@ mod tests { "#).unwrap(); assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox_args", &code).unwrap(), + call_wasm(&mut ext, 8, &test_code[..], "test_sandbox_args", &code).unwrap(), vec![1], ); } @@ -764,7 +777,7 @@ mod tests { "#).unwrap(); assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox_return_val", &code).unwrap(), + call_wasm(&mut ext, 8, &test_code[..], "test_sandbox_return_val", &code).unwrap(), vec![1], ); } @@ -784,7 +797,7 @@ mod tests { "#).unwrap(); assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", &code).unwrap(), + call_wasm(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", &code).unwrap(), vec![1], ); } @@ -798,7 +811,7 @@ mod tests { let code = &[0, 0, 0, 0, 1, 0, 0, 0]; assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", code).unwrap(), + call_wasm(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", code).unwrap(), vec![1], ); } @@ -821,7 +834,7 @@ mod tests { "#).unwrap(); assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", &code).unwrap(), + call_wasm(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", &code).unwrap(), vec![0], ); } @@ -845,7 +858,7 @@ mod tests { "#).unwrap(); assert_eq!( - WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", &code).unwrap(), + call_wasm(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", &code).unwrap(), vec![2], ); } diff --git a/core/executor/src/wasm_runtime.rs b/core/executor/src/wasm_runtime.rs new file mode 100644 index 0000000000..27b65d6551 --- /dev/null +++ b/core/executor/src/wasm_runtime.rs @@ -0,0 +1,173 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Traits and accessor functions for calling into the Substrate Wasm runtime. +//! +//! The primary means of accessing the runtimes is through a cache which saves the reusable +//! components of the runtime that are expensive to initialize. + +use crate::error::{Error, WasmError}; +use crate::wasmi_execution; +use log::{trace, warn}; +use codec::Decode; +use primitives::{storage::well_known_keys, Blake2Hasher, traits::Externalities}; +use runtime_version::RuntimeVersion; +use std::{collections::hash_map::{Entry, HashMap}}; + +/// The Substrate Wasm runtime. +pub trait WasmRuntime { + /// Attempt to update the number of heap pages available during execution. + /// + /// Returns false if the update cannot be applied. The function is guaranteed to return true if + /// the heap pages would not change from its current value. + fn update_heap_pages(&mut self, heap_pages: u64) -> bool; + + /// Call a method in the Substrate runtime by name. Returns the encoded result on success. + fn call(&mut self, ext: &mut dyn Externalities, method: &str, data: &[u8]) + -> Result, Error>; + + /// Returns the version of this runtime. + /// + /// Returns `None` if the runtime doesn't provide the information or there was an error + /// while fetching it. + fn version(&self) -> Option; +} + +/// Specification of different methods of executing the runtime Wasm code. +#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)] +pub enum WasmExecutionMethod { + /// Uses the Wasmi interpreter. + Interpreted, +} + +/// Cache for the runtimes. +/// +/// When an instance is requested for the first time it is added to this cache. Metadata is kept +/// with the instance so that it can be efficiently reinitialized. +/// +/// When using the Wasmi interpreter execution method, the metadata includes the initial memory and +/// values of mutable globals. Follow-up requests to fetch a runtime return this one instance with +/// the memory reset to the initial memory. So, one runtime instance is reused for every fetch +/// request. +/// +/// For now the cache grows indefinitely, but that should be fine for now since runtimes can only be +/// upgraded rarely and there are no other ways to make the node to execute some other runtime. +pub struct RuntimesCache { + /// A cache of runtime instances along with metadata, ready to be reused. + /// + /// Instances are keyed by the Wasm execution method and the hash of their code. + instances: HashMap<(WasmExecutionMethod, [u8; 32]), Result, WasmError>>, +} + +impl RuntimesCache { + /// Creates a new instance of a runtimes cache. + pub fn new() -> RuntimesCache { + RuntimesCache { + instances: HashMap::new(), + } + } + + /// Fetches an instance of the runtime. + /// + /// On first use we create a new runtime instance, save it to the cache + /// and persist its initial memory. + /// + /// Each subsequent request will return this instance, with its memory restored + /// to the persisted initial memory. Thus, we reuse one single runtime instance + /// for every `fetch_runtime` invocation. + /// + /// # Parameters + /// + /// `ext` - Externalities to use for the runtime. This is used for setting + /// up an initial runtime instance. The parameter is only needed for calling + /// into the Wasm module to find out the `Core_version`. + /// + /// `default_heap_pages` - Number of 64KB pages to allocate for Wasm execution. + /// + /// # Return value + /// + /// If no error occurred a tuple `(wasmi::ModuleRef, Option)` is + /// returned. `RuntimeVersion` is contained if the call to `Core_version` returned + /// a version. + /// + /// In case of failure one of two errors can be returned: + /// + /// `Err::InvalidCode` is returned for runtime code issues. + /// + /// `Error::InvalidMemoryReference` is returned if no memory export with the + /// identifier `memory` can be found in the runtime. + pub fn fetch_runtime>( + &mut self, + ext: &mut E, + wasm_method: WasmExecutionMethod, + default_heap_pages: u64, + ) -> Result<&mut (dyn WasmRuntime + 'static), Error> { + let code_hash = ext + .original_storage_hash(well_known_keys::CODE) + .ok_or(Error::InvalidCode("`CODE` not found in storage.".into()))?; + + let heap_pages = ext + .storage(well_known_keys::HEAP_PAGES) + .and_then(|pages| u64::decode(&mut &pages[..]).ok()) + .unwrap_or(default_heap_pages); + + let result = match self.instances.entry((wasm_method, code_hash.into())) { + Entry::Occupied(o) => { + let result = o.into_mut(); + if let Ok(ref mut cached_runtime) = result { + if !cached_runtime.update_heap_pages(heap_pages) { + trace!( + target: "runtimes_cache", + "heap_pages were changed. Reinstantiating the instance" + ); + *result = create_wasm_runtime(ext, wasm_method, heap_pages); + if let Err(ref err) = result { + warn!(target: "runtimes_cache", "cannot create a runtime: {:?}", err); + } + } + } + result + }, + Entry::Vacant(v) => { + trace!(target: "runtimes_cache", "no instance found in cache, creating now."); + let result = create_wasm_runtime(ext, wasm_method, heap_pages); + if let Err(ref err) = result { + warn!(target: "runtimes_cache", "cannot create a runtime: {:?}", err); + } + v.insert(result) + } + }; + + result.as_mut() + .map(|runtime| runtime.as_mut()) + .map_err(|ref e| Error::InvalidCode(format!("{:?}", e))) + } +} + +fn create_wasm_runtime>( + ext: &mut E, + wasm_method: WasmExecutionMethod, + heap_pages: u64, +) -> Result, WasmError> { + let code = ext + .original_storage(well_known_keys::CODE) + .ok_or(WasmError::CodeNotFound)?; + match wasm_method { + WasmExecutionMethod::Interpreted => + wasmi_execution::create_instance(ext, &code, heap_pages) + .map(|runtime| -> Box { Box::new(runtime) }), + } +} diff --git a/core/executor/src/wasm_runtimes_cache.rs b/core/executor/src/wasm_runtimes_cache.rs deleted file mode 100644 index a615660777..0000000000 --- a/core/executor/src/wasm_runtimes_cache.rs +++ /dev/null @@ -1,353 +0,0 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Implements a cache for pre-created Wasm runtime module instances. - -use crate::error::Error; -use crate::wasm_executor::WasmExecutor; -use log::{trace, warn}; -use codec::Decode; -use parity_wasm::elements::{deserialize_buffer, DataSegment, Instruction, Module as RawModule}; -use primitives::{storage::well_known_keys, Blake2Hasher, traits::Externalities}; -use runtime_version::RuntimeVersion; -use std::{collections::hash_map::{Entry, HashMap}, mem, rc::Rc}; -use wasmi::{Module as WasmModule, ModuleRef as WasmModuleInstanceRef, RuntimeValue}; - -#[derive(Debug)] -enum CacheError { - CodeNotFound, - ApplySnapshotFailed, - InvalidModule, - CantDeserializeWasm, - Instantiation(Error), -} - -/// A runtime along with its version and initial state snapshot. -#[derive(Clone)] -pub struct CachedRuntime { - /// A wasm module instance. - instance: WasmModuleInstanceRef, - /// Runtime version according to `Core_version`. - /// - /// Can be `None` if the runtime doesn't expose this function. - version: Option, - /// The snapshot of the instance's state taken just after the instantiation. - state_snapshot: StateSnapshot, -} - -impl CachedRuntime { - /// Perform an operation with the clean version of the runtime wasm instance. - pub fn with(&self, f: F) -> R - where - F: FnOnce(&WasmModuleInstanceRef) -> R, - { - self.state_snapshot.apply(&self.instance).expect( - "applying the snapshot can only fail if the passed instance is different - from the one that was used for creation of the snapshot; - we use the snapshot that is directly associated with the instance; - thus the snapshot was created using the instance; - qed", - ); - f(&self.instance) - } - - /// Returns the version of this cached runtime. - /// - /// Returns `None` if the runtime doesn't provide the information or there was an error - /// while fetching it. - pub fn version(&self) -> Option { - self.version.clone() - } -} - -/// A state snapshot of an instance taken just after instantiation. -/// -/// It is used for restoring the state of the module after execution. -#[derive(Clone)] -struct StateSnapshot { - /// The offset and the content of the memory segments that should be used to restore the snapshot - data_segments: Vec<(u32, Vec)>, - /// The list of all global mutable variables of the module in their sequential order. - global_mut_values: Vec, - heap_pages: u64, -} - -impl StateSnapshot { - // Returns `None` if instance is not valid. - fn take( - module_instance: &WasmModuleInstanceRef, - data_segments: Vec, - heap_pages: u64, - ) -> Option { - let prepared_segments = data_segments - .into_iter() - .map(|mut segment| { - // Just replace contents of the segment since the segments will be discarded later - // anyway. - let contents = mem::replace(segment.value_mut(), vec![]); - - let init_expr = match segment.offset() { - Some(offset) => offset.code(), - // Return if the segment is passive - None => return None - }; - - // [op, End] - if init_expr.len() != 2 { - return None; - } - let offset = match init_expr[0] { - Instruction::I32Const(v) => v as u32, - Instruction::GetGlobal(idx) => { - let global_val = module_instance.globals().get(idx as usize)?.get(); - match global_val { - RuntimeValue::I32(v) => v as u32, - _ => return None, - } - } - _ => return None, - }; - - Some((offset, contents)) - }) - .collect::>>()?; - - // Collect all values of mutable globals. - let global_mut_values = module_instance - .globals() - .iter() - .filter(|g| g.is_mutable()) - .map(|g| g.get()) - .collect(); - - Some(Self { - data_segments: prepared_segments, - global_mut_values, - heap_pages, - }) - } - - /// Reset the runtime instance to the initial version by restoring - /// the preserved memory and globals. - /// - /// Returns `Err` if applying the snapshot is failed. - fn apply(&self, instance: &WasmModuleInstanceRef) -> Result<(), CacheError> { - let memory = instance - .export_by_name("memory") - .ok_or(CacheError::ApplySnapshotFailed)? - .as_memory() - .cloned() - .ok_or(CacheError::ApplySnapshotFailed)?; - - // First, erase the memory and copy the data segments into it. - memory - .erase() - .map_err(|_| CacheError::ApplySnapshotFailed)?; - for (offset, contents) in &self.data_segments { - memory - .set(*offset, contents) - .map_err(|_| CacheError::ApplySnapshotFailed)?; - } - - // Second, restore the values of mutable globals. - for (global_ref, global_val) in instance - .globals() - .iter() - .filter(|g| g.is_mutable()) - .zip(self.global_mut_values.iter()) - { - // the instance should be the same as used for preserving and - // we iterate the same way it as we do it for preserving values that means that the - // types should be the same and all the values are mutable. So no error is expected/ - global_ref - .set(*global_val) - .map_err(|_| CacheError::ApplySnapshotFailed)?; - } - Ok(()) - } -} - -/// Default num of pages for the heap -const DEFAULT_HEAP_PAGES: u64 = 1024; - -/// Cache for the runtimes. -/// -/// When an instance is requested for the first time it is added to this -/// cache. Furthermore its initial memory and values of mutable globals are preserved here. Follow-up -/// requests to fetch a runtime return this one instance with the memory -/// reset to the initial memory. So, one runtime instance is reused for -/// every fetch request. -/// -/// For now the cache grows indefinitely, but that should be fine for now since runtimes can only be -/// upgraded rarely and there are no other ways to make the node to execute some other runtime. -pub struct RuntimesCache { - /// A cache of runtime instances along with metadata, ready to be reused. - /// - /// Instances are keyed by the hash of their code. - instances: HashMap<[u8; 32], Result, CacheError>>, -} - -impl RuntimesCache { - /// Creates a new instance of a runtimes cache. - pub fn new() -> RuntimesCache { - RuntimesCache { - instances: HashMap::new(), - } - } - - /// Fetches an instance of the runtime. - /// - /// On first use we create a new runtime instance, save it to the cache - /// and persist its initial memory. - /// - /// Each subsequent request will return this instance, with its memory restored - /// to the persisted initial memory. Thus, we reuse one single runtime instance - /// for every `fetch_runtime` invocation. - /// - /// # Parameters - /// - /// `wasm_executor`- Rust wasm executor. Executes the provided code in a - /// sandboxed Wasm runtime. - /// - /// `ext` - Externalities to use for the runtime. This is used for setting - /// up an initial runtime instance. The parameter is only needed for calling - /// into the Wasm module to find out the `Core_version`. - /// - /// `default_heap_pages` - Number of 64KB pages to allocate for Wasm execution. - /// Defaults to `DEFAULT_HEAP_PAGES` if `None` is provided. - /// - /// # Return value - /// - /// If no error occurred a tuple `(wasmi::ModuleRef, Option)` is - /// returned. `RuntimeVersion` is contained if the call to `Core_version` returned - /// a version. - /// - /// In case of failure one of two errors can be returned: - /// - /// `Err::InvalidCode` is returned for runtime code issues. - /// - /// `Error::InvalidMemoryReference` is returned if no memory export with the - /// identifier `memory` can be found in the runtime. - pub fn fetch_runtime>( - &mut self, - wasm_executor: &WasmExecutor, - ext: &mut E, - default_heap_pages: Option, - ) -> Result, Error> { - let code_hash = ext - .original_storage_hash(well_known_keys::CODE) - .ok_or(Error::InvalidCode("`CODE` not found in storage.".into()))?; - - let heap_pages = ext - .storage(well_known_keys::HEAP_PAGES) - .and_then(|pages| u64::decode(&mut &pages[..]).ok()) - .or(default_heap_pages) - .unwrap_or(DEFAULT_HEAP_PAGES); - - // This is direct result from fighting with borrowck. - let handle_result = - |cached_result: &Result, CacheError>| match *cached_result { - Err(ref e) => Err(Error::InvalidCode(format!("{:?}", e))), - Ok(ref cached_runtime) => Ok(Rc::clone(cached_runtime)), - }; - - match self.instances.entry(code_hash.into()) { - Entry::Occupied(mut o) => { - let result = o.get_mut(); - if let Ok(ref cached_runtime) = result { - if cached_runtime.state_snapshot.heap_pages != heap_pages { - trace!( - target: "runtimes_cache", - "heap_pages were changed. Reinstantiating the instance" - ); - *result = Self::create_wasm_instance(wasm_executor, ext, heap_pages); - if let Err(ref err) = result { - warn!(target: "runtimes_cache", "cannot create a runtime: {:?}", err); - } - } - } - handle_result(result) - }, - Entry::Vacant(v) => { - trace!(target: "runtimes_cache", "no instance found in cache, creating now."); - let result = Self::create_wasm_instance( - wasm_executor, - ext, - heap_pages, - ); - if let Err(ref err) = result { - warn!(target: "runtimes_cache", "cannot create a runtime: {:?}", err); - } - handle_result(v.insert(result)) - } - } - } - - fn create_wasm_instance>( - wasm_executor: &WasmExecutor, - ext: &mut E, - heap_pages: u64, - ) -> Result, CacheError> { - let code = ext - .original_storage(well_known_keys::CODE) - .ok_or(CacheError::CodeNotFound)?; - let module = WasmModule::from_buffer(&code).map_err(|_| CacheError::InvalidModule)?; - - // Extract the data segments from the wasm code. - // - // A return of this error actually indicates that there is a problem in logic, since - // we just loaded and validated the `module` above. - let data_segments = extract_data_segments(&code)?; - - // Instantiate this module. - let instance = WasmExecutor::instantiate_module(heap_pages as usize, &module) - .map_err(CacheError::Instantiation)?; - - // Take state snapshot before executing anything. - let state_snapshot = StateSnapshot::take(&instance, data_segments, heap_pages) - .expect( - "`take` returns `Err` if the module is not valid; - we already loaded module above, thus the `Module` is proven to be valid at this point; - qed - ", - ); - - let version = wasm_executor - .call_in_wasm_module(ext, &instance, "Core_version", &[]) - .ok() - .and_then(|v| RuntimeVersion::decode(&mut v.as_slice()).ok()); - Ok(Rc::new(CachedRuntime { - instance, - version, - state_snapshot, - })) - } -} - -/// Extract the data segments from the given wasm code. -/// -/// Returns `Err` if the given wasm code cannot be deserialized. -fn extract_data_segments(wasm_code: &[u8]) -> Result, CacheError> { - let raw_module: RawModule = deserialize_buffer(wasm_code) - .map_err(|_| CacheError::CantDeserializeWasm)?; - - let segments = raw_module - .data_section() - .map(|ds| ds.entries()) - .unwrap_or(&[]) - .to_vec(); - Ok(segments) -} diff --git a/core/executor/src/wasmi_execution.rs b/core/executor/src/wasmi_execution.rs new file mode 100644 index 0000000000..e228372bd3 --- /dev/null +++ b/core/executor/src/wasmi_execution.rs @@ -0,0 +1,902 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Implementation of a Wasm runtime using the Wasmi interpreter. + +use std::{str, mem}; +use wasmi::{ + Module, ModuleInstance, MemoryInstance, MemoryRef, TableRef, ImportsBuilder, ModuleRef, + memory_units::Pages, RuntimeValue::{I32, I64, self}, +}; +use crate::error::{Error, WasmError}; +use codec::{Encode, Decode}; +use primitives::{sandbox as sandbox_primitives, Blake2Hasher, traits::Externalities}; +use crate::host_interface::SubstrateExternals; +use crate::sandbox; +use crate::allocator; +use crate::wasm_runtime::WasmRuntime; +use log::trace; +use parity_wasm::elements::{deserialize_buffer, DataSegment, Instruction, Module as RawModule}; +use runtime_version::RuntimeVersion; +use wasm_interface::{ + FunctionContext, HostFunctions, Pointer, WordSize, Sandbox, MemoryId, Result as WResult, +}; + +struct FunctionExecutor { + sandbox_store: sandbox::Store, + heap: allocator::FreeingBumpHeapAllocator, + memory: MemoryRef, + table: Option, +} + +impl FunctionExecutor { + fn new(m: MemoryRef, heap_base: u32, t: Option) -> Result { + Ok(FunctionExecutor { + sandbox_store: sandbox::Store::new(), + heap: allocator::FreeingBumpHeapAllocator::new(heap_base), + memory: m, + table: t, + }) + } +} + +impl sandbox::SandboxCapabilities for FunctionExecutor { + type SupervisorFuncRef = wasmi::FuncRef; + + fn store(&self) -> &sandbox::Store { + &self.sandbox_store + } + fn store_mut(&mut self) -> &mut sandbox::Store { + &mut self.sandbox_store + } + fn allocate(&mut self, len: WordSize) -> Result, Error> { + let heap = &mut self.heap; + self.memory.with_direct_access_mut(|mem| { + heap.allocate(mem, len) + }) + } + fn deallocate(&mut self, ptr: Pointer) -> Result<(), Error> { + let heap = &mut self.heap; + self.memory.with_direct_access_mut(|mem| { + heap.deallocate(mem, ptr) + }) + } + fn write_memory(&mut self, ptr: Pointer, data: &[u8]) -> Result<(), Error> { + self.memory.set(ptr.into(), data).map_err(Into::into) + } + fn read_memory(&self, ptr: Pointer, len: WordSize) -> Result, Error> { + self.memory.get(ptr.into(), len as usize).map_err(Into::into) + } + + fn invoke( + &mut self, + dispatch_thunk: &Self::SupervisorFuncRef, + invoke_args_ptr: Pointer, + invoke_args_len: WordSize, + state: u32, + func_idx: sandbox::SupervisorFuncIndex, + ) -> Result + { + let result = wasmi::FuncInstance::invoke( + dispatch_thunk, + &[ + RuntimeValue::I32(u32::from(invoke_args_ptr) as i32), + RuntimeValue::I32(invoke_args_len as i32), + RuntimeValue::I32(state as i32), + RuntimeValue::I32(usize::from(func_idx) as i32), + ], + self, + ); + match result { + Ok(Some(RuntimeValue::I64(val))) => Ok(val), + Ok(_) => return Err("Supervisor function returned unexpected result!".into()), + Err(err) => Err(Error::Trap(err)), + } + } +} + +impl FunctionContext for FunctionExecutor { + fn read_memory_into(&self, address: Pointer, dest: &mut [u8]) -> WResult<()> { + self.memory.get_into(address.into(), dest).map_err(|e| format!("{:?}", e)) + } + + fn write_memory(&mut self, address: Pointer, data: &[u8]) -> WResult<()> { + self.memory.set(address.into(), data).map_err(|e| format!("{:?}", e)) + } + + fn allocate_memory(&mut self, size: WordSize) -> WResult> { + let heap = &mut self.heap; + self.memory.with_direct_access_mut(|mem| { + heap.allocate(mem, size).map_err(|e| format!("{:?}", e)) + }) + } + + fn deallocate_memory(&mut self, ptr: Pointer) -> WResult<()> { + let heap = &mut self.heap; + self.memory.with_direct_access_mut(|mem| { + heap.deallocate(mem, ptr).map_err(|e| format!("{:?}", e)) + }) + } + + fn sandbox(&mut self) -> &mut dyn Sandbox { + self + } +} + +impl Sandbox for FunctionExecutor { + fn memory_get( + &self, + memory_id: MemoryId, + offset: WordSize, + buf_ptr: Pointer, + buf_len: WordSize, + ) -> WResult { + let sandboxed_memory = self.sandbox_store.memory(memory_id).map_err(|e| format!("{:?}", e))?; + + match MemoryInstance::transfer( + &sandboxed_memory, + offset as usize, + &self.memory, + buf_ptr.into(), + buf_len as usize, + ) { + Ok(()) => Ok(sandbox_primitives::ERR_OK), + Err(_) => Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS), + } + } + + fn memory_set( + &mut self, + memory_id: MemoryId, + offset: WordSize, + val_ptr: Pointer, + val_len: WordSize, + ) -> WResult { + let sandboxed_memory = self.sandbox_store.memory(memory_id).map_err(|e| format!("{:?}", e))?; + + match MemoryInstance::transfer( + &self.memory, + val_ptr.into(), + &sandboxed_memory, + offset as usize, + val_len as usize, + ) { + Ok(()) => Ok(sandbox_primitives::ERR_OK), + Err(_) => Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS), + } + } + + fn memory_teardown(&mut self, memory_id: MemoryId) -> WResult<()> { + self.sandbox_store.memory_teardown(memory_id).map_err(|e| format!("{:?}", e)) + } + + fn memory_new( + &mut self, + initial: u32, + maximum: u32, + ) -> WResult { + self.sandbox_store.new_memory(initial, maximum).map_err(|e| format!("{:?}", e)) + } + + fn invoke( + &mut self, + instance_id: u32, + export_name: &str, + args: &[u8], + return_val: Pointer, + return_val_len: WordSize, + state: u32, + ) -> WResult { + trace!(target: "sr-sandbox", "invoke, instance_idx={}", instance_id); + + // Deserialize arguments and convert them into wasmi types. + let args = Vec::::decode(&mut &args[..]) + .map_err(|_| "Can't decode serialized arguments for the invocation")? + .into_iter() + .map(Into::into) + .collect::>(); + + let instance = self.sandbox_store.instance(instance_id).map_err(|e| format!("{:?}", e))?; + let result = instance.invoke(export_name, &args, self, state); + + match result { + Ok(None) => Ok(sandbox_primitives::ERR_OK), + Ok(Some(val)) => { + // Serialize return value and write it back into the memory. + sandbox_primitives::ReturnValue::Value(val.into()).using_encoded(|val| { + if val.len() > return_val_len as usize { + Err("Return value buffer is too small")?; + } + self.write_memory(return_val, val).map_err(|_| "Return value buffer is OOB")?; + Ok(sandbox_primitives::ERR_OK) + }) + } + Err(_) => Ok(sandbox_primitives::ERR_EXECUTION), + } + } + + fn instance_teardown(&mut self, instance_id: u32) -> WResult<()> { + self.sandbox_store.instance_teardown(instance_id).map_err(|e| format!("{:?}", e)) + } + + fn instance_new( + &mut self, + dispatch_thunk_id: u32, + wasm: &[u8], + raw_env_def: &[u8], + state: u32, + ) -> WResult { + // Extract a dispatch thunk from instance's table by the specified index. + let dispatch_thunk = { + let table = self.table.as_ref() + .ok_or_else(|| "Runtime doesn't have a table; sandbox is unavailable")?; + table.get(dispatch_thunk_id) + .map_err(|_| "dispatch_thunk_idx is out of the table bounds")? + .ok_or_else(|| "dispatch_thunk_idx points on an empty table entry")? + .clone() + }; + + let instance_idx_or_err_code = + match sandbox::instantiate(self, dispatch_thunk, wasm, raw_env_def, state) { + Ok(instance_idx) => instance_idx, + Err(sandbox::InstantiationError::StartTrapped) => + sandbox_primitives::ERR_EXECUTION, + Err(_) => sandbox_primitives::ERR_MODULE, + }; + + Ok(instance_idx_or_err_code as u32) + } +} + +impl FunctionExecutor { + fn resolver() -> &'static dyn wasmi::ModuleImportResolver { + struct Resolver; + impl wasmi::ModuleImportResolver for Resolver { + fn resolve_func(&self, name: &str, signature: &wasmi::Signature) + -> std::result::Result + { + let signature = wasm_interface::Signature::from(signature); + + if let Some((index, func)) = SubstrateExternals::functions().iter() + .enumerate() + .find(|f| name == f.1.name()) + { + if signature == func.signature() { + Ok(wasmi::FuncInstance::alloc_host(signature.into(), index)) + } else { + Err(wasmi::Error::Instantiation( + format!( + "Invalid signature for function `{}` expected `{:?}`, got `{:?}`", + func.name(), + signature, + func.signature(), + ) + )) + } + } else { + Err(wasmi::Error::Instantiation( + format!("Export {} not found", name), + )) + } + } + } + &Resolver + } +} + +impl wasmi::Externals for FunctionExecutor { + fn invoke_index(&mut self, index: usize, args: wasmi::RuntimeArgs) + -> Result, wasmi::Trap> + { + let mut args = args.as_ref().iter().copied().map(Into::into); + let function = SubstrateExternals::functions().get(index).ok_or_else(|| + Error::from( + format!("Could not find host function with index: {}", index), + ) + )?; + + function.execute(self, &mut args) + .map_err(Error::FunctionExecution) + .map_err(wasmi::Trap::from) + .map(|v| v.map(Into::into)) + } +} + +fn get_mem_instance(module: &ModuleRef) -> Result { + Ok(module + .export_by_name("memory") + .ok_or_else(|| Error::InvalidMemoryReference)? + .as_memory() + .ok_or_else(|| Error::InvalidMemoryReference)? + .clone()) +} + +/// Find the global named `__heap_base` in the given wasm module instance and +/// tries to get its value. +fn get_heap_base(module: &ModuleRef) -> Result { + let heap_base_val = module + .export_by_name("__heap_base") + .ok_or_else(|| Error::HeapBaseNotFoundOrInvalid)? + .as_global() + .ok_or_else(|| Error::HeapBaseNotFoundOrInvalid)? + .get(); + + match heap_base_val { + wasmi::RuntimeValue::I32(v) => Ok(v as u32), + _ => Err(Error::HeapBaseNotFoundOrInvalid), + } +} + +/// Call a given method in the given wasm-module runtime. +fn call_in_wasm_module( + ext: &mut dyn Externalities, + module_instance: &ModuleRef, + method: &str, + data: &[u8], +) -> Result, Error> { + call_in_wasm_module_with_custom_signature( + ext, + module_instance, + method, + |alloc| { + let offset = alloc(data)?; + Ok(vec![I32(offset as i32), I32(data.len() as i32)]) + }, + |res, memory| { + if let Some(I64(r)) = res { + let offset = r as u32; + let length = (r as u64 >> 32) as usize; + memory.get(offset, length).map_err(|_| Error::Runtime).map(Some) + } else { + Ok(None) + } + } + ) +} + +/// Call a given method in the given wasm-module runtime. +fn call_in_wasm_module_with_custom_signature< + F: FnOnce(&mut dyn FnMut(&[u8]) -> Result) -> Result, Error>, + FR: FnOnce(Option, &MemoryRef) -> Result, Error>, + R, +>( + ext: &mut dyn Externalities, + module_instance: &ModuleRef, + method: &str, + create_parameters: F, + filter_result: FR, +) -> Result { + // extract a reference to a linear memory, optional reference to a table + // and then initialize FunctionExecutor. + let memory = get_mem_instance(module_instance)?; + let table: Option = module_instance + .export_by_name("__indirect_function_table") + .and_then(|e| e.as_table().cloned()); + let heap_base = get_heap_base(module_instance)?; + + let mut fec = FunctionExecutor::new( + memory.clone(), + heap_base, + table, + )?; + + let parameters = create_parameters(&mut |data: &[u8]| { + let offset = fec.allocate_memory(data.len() as u32)?; + fec.write_memory(offset, data).map(|_| offset.into()).map_err(Into::into) + })?; + + let result = runtime_io::with_externalities( + ext, + || module_instance.invoke_export(method, ¶meters, &mut fec), + ); + + match result { + Ok(val) => match filter_result(val, &memory)? { + Some(val) => Ok(val), + None => Err(Error::InvalidReturn), + }, + Err(e) => { + trace!( + target: "wasm-executor", + "Failed to execute code with {} pages", + memory.current_size().0 + ); + Err(e.into()) + }, + } +} + +/// Prepare module instance +fn instantiate_module( + heap_pages: usize, + module: &Module, +) -> Result { + // start module instantiation. Don't run 'start' function yet. + let intermediate_instance = ModuleInstance::new( + module, + &ImportsBuilder::new() + .with_resolver("env", FunctionExecutor::resolver()) + )?; + + // Verify that the module has the heap base global variable. + let _ = get_heap_base(intermediate_instance.not_started_instance())?; + + // Extract a reference to a linear memory. + let memory = get_mem_instance(intermediate_instance.not_started_instance())?; + memory.grow(Pages(heap_pages)).map_err(|_| Error::Runtime)?; + + if intermediate_instance.has_start() { + // Runtime is not allowed to have the `start` function. + Err(Error::RuntimeHasStartFn) + } else { + Ok(intermediate_instance.assert_no_start()) + } +} + +/// A state snapshot of an instance taken just after instantiation. +/// +/// It is used for restoring the state of the module after execution. +#[derive(Clone)] +struct StateSnapshot { + /// The offset and the content of the memory segments that should be used to restore the snapshot + data_segments: Vec<(u32, Vec)>, + /// The list of all global mutable variables of the module in their sequential order. + global_mut_values: Vec, + heap_pages: u64, +} + +impl StateSnapshot { + // Returns `None` if instance is not valid. + fn take( + module_instance: &ModuleRef, + data_segments: Vec, + heap_pages: u64, + ) -> Option { + let prepared_segments = data_segments + .into_iter() + .map(|mut segment| { + // Just replace contents of the segment since the segments will be discarded later + // anyway. + let contents = mem::replace(segment.value_mut(), vec![]); + + let init_expr = match segment.offset() { + Some(offset) => offset.code(), + // Return if the segment is passive + None => return None + }; + + // [op, End] + if init_expr.len() != 2 { + return None; + } + let offset = match init_expr[0] { + Instruction::I32Const(v) => v as u32, + Instruction::GetGlobal(idx) => { + let global_val = module_instance.globals().get(idx as usize)?.get(); + match global_val { + RuntimeValue::I32(v) => v as u32, + _ => return None, + } + } + _ => return None, + }; + + Some((offset, contents)) + }) + .collect::>>()?; + + // Collect all values of mutable globals. + let global_mut_values = module_instance + .globals() + .iter() + .filter(|g| g.is_mutable()) + .map(|g| g.get()) + .collect(); + + Some(Self { + data_segments: prepared_segments, + global_mut_values, + heap_pages, + }) + } + + /// Reset the runtime instance to the initial version by restoring + /// the preserved memory and globals. + /// + /// Returns `Err` if applying the snapshot is failed. + fn apply(&self, instance: &ModuleRef) -> Result<(), WasmError> { + let memory = instance + .export_by_name("memory") + .ok_or(WasmError::ApplySnapshotFailed)? + .as_memory() + .cloned() + .ok_or(WasmError::ApplySnapshotFailed)?; + + // First, erase the memory and copy the data segments into it. + memory + .erase() + .map_err(|_| WasmError::ApplySnapshotFailed)?; + for (offset, contents) in &self.data_segments { + memory + .set(*offset, contents) + .map_err(|_| WasmError::ApplySnapshotFailed)?; + } + + // Second, restore the values of mutable globals. + for (global_ref, global_val) in instance + .globals() + .iter() + .filter(|g| g.is_mutable()) + .zip(self.global_mut_values.iter()) + { + // the instance should be the same as used for preserving and + // we iterate the same way it as we do it for preserving values that means that the + // types should be the same and all the values are mutable. So no error is expected/ + global_ref + .set(*global_val) + .map_err(|_| WasmError::ApplySnapshotFailed)?; + } + Ok(()) + } +} + +/// A runtime along with its version and initial state snapshot. +#[derive(Clone)] +pub struct WasmiRuntime { + /// A wasm module instance. + instance: ModuleRef, + /// Runtime version according to `Core_version`. + /// + /// Can be `None` if the runtime doesn't expose this function. + version: Option, + /// The snapshot of the instance's state taken just after the instantiation. + state_snapshot: StateSnapshot, +} + +impl WasmiRuntime { + /// Perform an operation with the clean version of the runtime wasm instance. + fn with(&self, f: F) -> R + where + F: FnOnce(&ModuleRef) -> R, + { + self.state_snapshot.apply(&self.instance).expect( + "applying the snapshot can only fail if the passed instance is different + from the one that was used for creation of the snapshot; + we use the snapshot that is directly associated with the instance; + thus the snapshot was created using the instance; + qed", + ); + f(&self.instance) + } +} + +impl WasmRuntime for WasmiRuntime { + fn update_heap_pages(&mut self, heap_pages: u64) -> bool { + self.state_snapshot.heap_pages == heap_pages + } + + fn call(&mut self, ext: &mut dyn Externalities, method: &str, data: &[u8]) + -> Result, Error> + { + self.with(|module| { + call_in_wasm_module(ext, module, method, data) + }) + } + + fn version(&self) -> Option { + self.version.clone() + } +} + +pub fn create_instance>(ext: &mut E, code: &[u8], heap_pages: u64) + -> Result +{ + let module = Module::from_buffer(&code).map_err(|_| WasmError::InvalidModule)?; + + // Extract the data segments from the wasm code. + // + // A return of this error actually indicates that there is a problem in logic, since + // we just loaded and validated the `module` above. + let data_segments = extract_data_segments(&code)?; + + // Instantiate this module. + let instance = instantiate_module(heap_pages as usize, &module) + .map_err(WasmError::Instantiation)?; + + // Take state snapshot before executing anything. + let state_snapshot = StateSnapshot::take(&instance, data_segments, heap_pages) + .expect( + "`take` returns `Err` if the module is not valid; + we already loaded module above, thus the `Module` is proven to be valid at this point; + qed + ", + ); + + let version = call_in_wasm_module(ext, &instance, "Core_version", &[]) + .ok() + .and_then(|v| RuntimeVersion::decode(&mut v.as_slice()).ok()); + Ok(WasmiRuntime { + instance, + version, + state_snapshot, + }) +} + +/// Extract the data segments from the given wasm code. +/// +/// Returns `Err` if the given wasm code cannot be deserialized. +fn extract_data_segments(wasm_code: &[u8]) -> Result, WasmError> { + let raw_module: RawModule = deserialize_buffer(wasm_code) + .map_err(|_| WasmError::CantDeserializeWasm)?; + + let segments = raw_module + .data_section() + .map(|ds| ds.entries()) + .unwrap_or(&[]) + .to_vec(); + Ok(segments) +} + +#[cfg(test)] +mod tests { + use super::*; + + use state_machine::TestExternalities as CoreTestExternalities; + use hex_literal::hex; + use primitives::{blake2_128, blake2_256, ed25519, sr25519, map, Pair}; + use runtime_test::WASM_BINARY; + use substrate_offchain::testing; + use trie::{TrieConfiguration, trie_types::Layout}; + + type TestExternalities = CoreTestExternalities; + + fn call>( + ext: &mut E, + heap_pages: u64, + code: &[u8], + method: &str, + data: &[u8], + ) -> Result, Error> { + let mut instance = create_instance(ext, code, heap_pages) + .map_err(|err| err.to_string())?; + instance.call(ext, method, data) + } + + #[test] + fn returning_should_work() { + let mut ext = TestExternalities::default(); + let test_code = WASM_BINARY; + + let output = call(&mut ext, 8, &test_code[..], "test_empty_return", &[]).unwrap(); + assert_eq!(output, vec![0u8; 0]); + } + + #[test] + fn panicking_should_work() { + let mut ext = TestExternalities::default(); + let test_code = WASM_BINARY; + + let output = call(&mut ext, 8, &test_code[..], "test_panic", &[]); + assert!(output.is_err()); + + let output = call(&mut ext, 8, &test_code[..], "test_conditional_panic", &[]); + assert_eq!(output.unwrap(), vec![0u8; 0]); + + let output = call(&mut ext, 8, &test_code[..], "test_conditional_panic", &[2]); + assert!(output.is_err()); + } + + #[test] + fn storage_should_work() { + let mut ext = TestExternalities::default(); + ext.set_storage(b"foo".to_vec(), b"bar".to_vec()); + let test_code = WASM_BINARY; + + let output = call(&mut ext, 8, &test_code[..], "test_data_in", b"Hello world").unwrap(); + + assert_eq!(output, b"all ok!".to_vec()); + + let expected = TestExternalities::new((map![ + b"input".to_vec() => b"Hello world".to_vec(), + b"foo".to_vec() => b"bar".to_vec(), + b"baz".to_vec() => b"bar".to_vec() + ], map![])); + assert_eq!(ext, expected); + } + + #[test] + fn clear_prefix_should_work() { + let mut ext = TestExternalities::default(); + ext.set_storage(b"aaa".to_vec(), b"1".to_vec()); + ext.set_storage(b"aab".to_vec(), b"2".to_vec()); + ext.set_storage(b"aba".to_vec(), b"3".to_vec()); + ext.set_storage(b"abb".to_vec(), b"4".to_vec()); + ext.set_storage(b"bbb".to_vec(), b"5".to_vec()); + let test_code = WASM_BINARY; + + // This will clear all entries which prefix is "ab". + let output = call(&mut ext, 8, &test_code[..], "test_clear_prefix", b"ab").unwrap(); + + assert_eq!(output, b"all ok!".to_vec()); + + let expected = TestExternalities::new((map![ + b"aaa".to_vec() => b"1".to_vec(), + b"aab".to_vec() => b"2".to_vec(), + b"bbb".to_vec() => b"5".to_vec() + ], map![])); + assert_eq!(expected, ext); + } + + #[test] + fn blake2_256_should_work() { + let mut ext = TestExternalities::default(); + let test_code = WASM_BINARY; + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_blake2_256", &[]).unwrap(), + blake2_256(&b""[..]).encode() + ); + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_blake2_256", b"Hello world!").unwrap(), + blake2_256(&b"Hello world!"[..]).encode() + ); + } + + #[test] + fn blake2_128_should_work() { + let mut ext = TestExternalities::default(); + let test_code = WASM_BINARY; + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_blake2_128", &[]).unwrap(), + blake2_128(&b""[..]).encode() + ); + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_blake2_128", b"Hello world!").unwrap(), + blake2_128(&b"Hello world!"[..]).encode() + ); + } + + #[test] + fn twox_256_should_work() { + let mut ext = TestExternalities::default(); + let test_code = WASM_BINARY; + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_twox_256", &[]).unwrap(), + hex!("99e9d85137db46ef4bbea33613baafd56f963c64b1f3685a4eb4abd67ff6203a"), + ); + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_twox_256", b"Hello world!").unwrap(), + hex!("b27dfd7f223f177f2a13647b533599af0c07f68bda23d96d059da2b451a35a74"), + ); + } + + #[test] + fn twox_128_should_work() { + let mut ext = TestExternalities::default(); + let test_code = WASM_BINARY; + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_twox_128", &[]).unwrap(), + hex!("99e9d85137db46ef4bbea33613baafd5") + ); + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_twox_128", b"Hello world!").unwrap(), + hex!("b27dfd7f223f177f2a13647b533599af") + ); + } + + #[test] + fn ed25519_verify_should_work() { + let mut ext = TestExternalities::::default(); + let test_code = WASM_BINARY; + let key = ed25519::Pair::from_seed(&blake2_256(b"test")); + let sig = key.sign(b"all ok!"); + let mut calldata = vec![]; + calldata.extend_from_slice(key.public().as_ref()); + calldata.extend_from_slice(sig.as_ref()); + + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_ed25519_verify", &calldata).unwrap(), + vec![1] + ); + + let other_sig = key.sign(b"all is not ok!"); + let mut calldata = vec![]; + calldata.extend_from_slice(key.public().as_ref()); + calldata.extend_from_slice(other_sig.as_ref()); + + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_ed25519_verify", &calldata).unwrap(), + vec![0] + ); + } + + #[test] + fn sr25519_verify_should_work() { + let mut ext = TestExternalities::::default(); + let test_code = WASM_BINARY; + let key = sr25519::Pair::from_seed(&blake2_256(b"test")); + let sig = key.sign(b"all ok!"); + let mut calldata = vec![]; + calldata.extend_from_slice(key.public().as_ref()); + calldata.extend_from_slice(sig.as_ref()); + + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_sr25519_verify", &calldata).unwrap(), + vec![1] + ); + + let other_sig = key.sign(b"all is not ok!"); + let mut calldata = vec![]; + calldata.extend_from_slice(key.public().as_ref()); + calldata.extend_from_slice(other_sig.as_ref()); + + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_sr25519_verify", &calldata).unwrap(), + vec![0] + ); + } + + #[test] + fn ordered_trie_root_should_work() { + let mut ext = TestExternalities::::default(); + let trie_input = vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()]; + let test_code = WASM_BINARY; + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_ordered_trie_root", &[]).unwrap(), + Layout::::ordered_trie_root(trie_input.iter()).as_fixed_bytes().encode() + ); + } + + #[test] + fn offchain_local_storage_should_work() { + use substrate_client::backend::OffchainStorage; + + let mut ext = TestExternalities::::default(); + let (offchain, state) = testing::TestOffchainExt::new(); + ext.set_offchain_externalities(offchain); + let test_code = WASM_BINARY; + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_offchain_local_storage", &[]).unwrap(), + vec![0] + ); + assert_eq!(state.read().persistent_storage.get(b"", b"test"), Some(vec![])); + } + + #[test] + fn offchain_http_should_work() { + let mut ext = TestExternalities::::default(); + let (offchain, state) = testing::TestOffchainExt::new(); + ext.set_offchain_externalities(offchain); + state.write().expect_request( + 0, + testing::PendingRequest { + method: "POST".into(), + uri: "http://localhost:12345".into(), + body: vec![1, 2, 3, 4], + headers: vec![("X-Auth".to_owned(), "test".to_owned())], + sent: true, + response: Some(vec![1, 2, 3]), + response_headers: vec![("X-Auth".to_owned(), "hello".to_owned())], + ..Default::default() + }, + ); + + let test_code = WASM_BINARY; + assert_eq!( + call(&mut ext, 8, &test_code[..], "test_offchain_http", &[]).unwrap(), + vec![0] + ); + } +} diff --git a/core/service/src/builder.rs b/core/service/src/builder.rs index f0860de1c1..e4b02150bf 100644 --- a/core/service/src/builder.rs +++ b/core/service/src/builder.rs @@ -167,7 +167,10 @@ where TGen: RuntimeGenesis, TCSExt: Extension { pruning: config.pruning.clone(), }; - let executor = NativeExecutor::::new(config.default_heap_pages); + let executor = NativeExecutor::::new( + config.wasm_method, + config.default_heap_pages, + ); let fork_blocks = config.chain_spec .extensions() @@ -239,7 +242,10 @@ where TGen: RuntimeGenesis, TCSExt: Extension { pruning: config.pruning.clone(), }; - let executor = NativeExecutor::::new(config.default_heap_pages); + let executor = NativeExecutor::::new( + config.wasm_method, + config.default_heap_pages, + ); let db_storage = client_db::light::LightStorage::new(db_settings)?; let light_blockchain = client::light::new_light_blockchain(db_storage); diff --git a/core/service/src/config.rs b/core/service/src/config.rs index c4690e53f7..a1ba83753f 100644 --- a/core/service/src/config.rs +++ b/core/service/src/config.rs @@ -19,6 +19,7 @@ pub use client::ExecutionStrategies; pub use client_db::PruningMode; pub use network::config::{ExtTransport, NetworkConfiguration, Roles}; +pub use substrate_executor::WasmExecutionMethod; use std::{path::PathBuf, net::SocketAddr}; use transaction_pool; @@ -60,6 +61,8 @@ pub struct Configuration { pub custom: C, /// Node name. pub name: String, + /// Wasm execution method. + pub wasm_method: WasmExecutionMethod, /// Execution strategies. pub execution_strategies: ExecutionStrategies, /// RPC over HTTP binding address. `None` if disabled. @@ -116,6 +119,7 @@ impl Configuration where state_cache_child_ratio: Default::default(), custom: Default::default(), pruning: PruningMode::default(), + wasm_method: WasmExecutionMethod::Interpreted, execution_strategies: Default::default(), rpc_http: None, rpc_ws: None, diff --git a/core/service/test/src/lib.rs b/core/service/test/src/lib.rs index 2d064f965b..806996576f 100644 --- a/core/service/test/src/lib.rs +++ b/core/service/test/src/lib.rs @@ -178,6 +178,7 @@ fn node_config ( chain_spec: (*spec).clone(), custom: Default::default(), name: format!("Node {}", index), + wasm_method: service::config::WasmExecutionMethod::Interpreted, execution_strategies: Default::default(), rpc_http: None, rpc_ws: None, diff --git a/core/sr-api-macros/tests/runtime_calls.rs b/core/sr-api-macros/tests/runtime_calls.rs index f33a9e257a..ce6300bc41 100644 --- a/core/sr-api-macros/tests/runtime_calls.rs +++ b/core/sr-api-macros/tests/runtime_calls.rs @@ -186,7 +186,7 @@ fn record_proof_works() { // Use the proof backend to execute `execute_block`. let mut overlay = Default::default(); - let executor = NativeExecutor::::new(None); + let executor = NativeExecutor::::new(WasmExecutionMethod::Interpreted, None); execution_proof_check_on_trie_backend( &backend, &mut overlay, diff --git a/core/test-client/src/lib.rs b/core/test-client/src/lib.rs index a2baf11be2..dbe4431456 100644 --- a/core/test-client/src/lib.rs +++ b/core/test-client/src/lib.rs @@ -24,7 +24,7 @@ pub use client::{ExecutionStrategies, blockchain, backend, self}; pub use client_db::{Backend, self}; pub use client_ext::ClientExt; pub use consensus; -pub use executor::{NativeExecutor, self}; +pub use executor::{NativeExecutor, WasmExecutionMethod, self}; pub use keyring::{ AccountKeyring, ed25519::Keyring as Ed25519Keyring, @@ -198,7 +198,7 @@ impl TestClientBuilder } impl TestClientBuilder< - client::LocalCallExecutor>, + client::LocalCallExecutor>, Backend, G, > { @@ -209,18 +209,20 @@ impl TestClientBuilder< ) -> ( client::Client< Backend, - client::LocalCallExecutor>, + client::LocalCallExecutor>, Block, RuntimeApi >, client::LongestChain, ) where - I: Into>>, + I: Into>>, E: executor::NativeExecutionDispatch, Backend: client::backend::Backend, Block: BlockT::Out>, { - let executor = executor.into().unwrap_or_else(|| executor::NativeExecutor::new(None)); + let executor = executor.into().unwrap_or_else(|| + NativeExecutor::new(WasmExecutionMethod::Interpreted, None) + ); let executor = LocalCallExecutor::new(self.backend.clone(), executor, self.keystore.take()); self.build_with_executor(executor) diff --git a/core/test-runtime/client/src/lib.rs b/core/test-runtime/client/src/lib.rs index 722aa0b2b4..affbae62c2 100644 --- a/core/test-runtime/client/src/lib.rs +++ b/core/test-runtime/client/src/lib.rs @@ -39,7 +39,7 @@ pub mod prelude { // Client structs pub use super::{ TestClient, TestClientBuilder, Backend, LightBackend, - Executor, LightExecutor, LocalExecutor, NativeExecutor, + Executor, LightExecutor, LocalExecutor, NativeExecutor, WasmExecutionMethod, }; // Keyring pub use super::{AccountKeyring, Sr25519Keyring}; @@ -261,7 +261,7 @@ pub fn new_light() -> ( let storage = client_db::light::LightStorage::new_test(); let blockchain = Arc::new(client::light::blockchain::Blockchain::new(storage)); let backend = Arc::new(LightBackend::new(blockchain.clone())); - let executor = NativeExecutor::new(None); + let executor = NativeExecutor::new(WasmExecutionMethod::Interpreted, None); let local_call_executor = client::LocalCallExecutor::new(backend.clone(), executor, None); let call_executor = LightExecutor::new( backend.clone(), diff --git a/core/test-runtime/src/system.rs b/core/test-runtime/src/system.rs index e61e72f3a0..12a656cf31 100644 --- a/core/test-runtime/src/system.rs +++ b/core/test-runtime/src/system.rs @@ -322,8 +322,19 @@ mod tests { use runtime_io::{with_externalities, TestExternalities}; use substrate_test_runtime_client::{AccountKeyring, Sr25519Keyring}; use crate::{Header, Transfer, WASM_BINARY}; - use primitives::{Blake2Hasher, map}; - use substrate_executor::WasmExecutor; + use primitives::{Blake2Hasher, NeverNativeValue, map, traits::CodeExecutor}; + use substrate_executor::{NativeExecutor, WasmExecutionMethod, native_executor_instance}; + + // Declare an instance of the native executor dispatch for the test runtime. + native_executor_instance!( + NativeDispatch, + crate::api::dispatch, + crate::native_version + ); + + fn executor() -> NativeExecutor { + NativeExecutor::new(WasmExecutionMethod::Interpreted, None) + } fn new_test_ext() -> TestExternalities { let authorities = vec![ @@ -331,13 +342,19 @@ mod tests { Sr25519Keyring::Bob.to_raw_public(), Sr25519Keyring::Charlie.to_raw_public() ]; - TestExternalities::new((map![ - twox_128(b"latest").to_vec() => vec![69u8; 32], - twox_128(b"sys:auth").to_vec() => authorities.encode(), - blake2_256(&AccountKeyring::Alice.to_raw_public().to_keyed_vec(b"balance:")).to_vec() => { - vec![111u8, 0, 0, 0, 0, 0, 0, 0] - } - ], map![])) + TestExternalities::new_with_code( + WASM_BINARY, + ( + map![ + twox_128(b"latest").to_vec() => vec![69u8; 32], + twox_128(b"sys:auth").to_vec() => authorities.encode(), + blake2_256(&AccountKeyring::Alice.to_raw_public().to_keyed_vec(b"balance:")).to_vec() => { + vec![111u8, 0, 0, 0, 0, 0, 0, 0] + } + ], + map![], + ) + ) } fn block_import_works(block_executor: F) where F: Fn(Block, &mut TestExternalities) { @@ -370,7 +387,13 @@ mod tests { #[test] fn block_import_works_wasm() { block_import_works(|b, ext| { - WasmExecutor::new().call(ext, 8, &WASM_BINARY, "Core_execute_block", &b.encode()).unwrap(); + executor().call::<_, NeverNativeValue, fn() -> _>( + ext, + "Core_execute_block", + &b.encode(), + false, + None, + ).0.unwrap(); }) } @@ -458,7 +481,13 @@ mod tests { #[test] fn block_import_with_transaction_works_wasm() { block_import_with_transaction_works(|b, ext| { - WasmExecutor::new().call(ext, 8, &WASM_BINARY, "Core_execute_block", &b.encode()).unwrap(); + executor().call::<_, NeverNativeValue, fn() -> _>( + ext, + "Core_execute_block", + &b.encode(), + false, + None, + ).0.unwrap(); }) } } diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index 864b51d6c7..38656b7bd4 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -22,7 +22,6 @@ #[cfg(feature = "benchmarks")] extern crate test; pub use substrate_executor::NativeExecutor; -pub use substrate_executor::RuntimesCache; use substrate_executor::native_executor_instance; // Declare an instance of the native executor named `Executor`. Include the wasm binary as the @@ -53,6 +52,7 @@ mod tests { transaction_validity::InvalidTransaction, weights::{WeightMultiplier, GetDispatchInfo}, }; use contracts::ContractAddressFor; + use substrate_executor::{NativeExecutor, WasmExecutionMethod}; use system::{EventRecord, Phase}; use node_runtime::{ Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances, BuildStorage, @@ -117,8 +117,8 @@ mod tests { Header::new(n, Default::default(), Default::default(), [69; 32].into(), Default::default()) } - fn executor() -> ::substrate_executor::NativeExecutor { - substrate_executor::NativeExecutor::new(None) + fn executor() -> NativeExecutor { + NativeExecutor::new(WasmExecutionMethod::Interpreted, None) } fn set_heap_pages>(ext: &mut E, heap_pages: u64) { -- GitLab From 348d27bfb0fa56555c92c79ddc40f5849bb90b7d Mon Sep 17 00:00:00 2001 From: Weiliang Li Date: Wed, 9 Oct 2019 00:16:24 +0900 Subject: [PATCH 196/275] gossip: save sender for kept messages (#3738) --- core/network/src/protocol/consensus_gossip.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/core/network/src/protocol/consensus_gossip.rs b/core/network/src/protocol/consensus_gossip.rs index d916e9aace..e23df7e1a5 100644 --- a/core/network/src/protocol/consensus_gossip.rs +++ b/core/network/src/protocol/consensus_gossip.rs @@ -89,6 +89,7 @@ struct MessageEntry { message_hash: B::Hash, topic: B::Hash, message: ConsensusMessage, + sender: Option, } /// Consensus message destination. @@ -322,12 +323,14 @@ impl ConsensusGossip { message_hash: B::Hash, topic: B::Hash, message: ConsensusMessage, + sender: Option, ) { if self.known_messages.insert(message_hash.clone(), ()).is_none() { self.messages.push(MessageEntry { message_hash, topic, message, + sender, }); } } @@ -343,7 +346,7 @@ impl ConsensusGossip { message: ConsensusMessage, ) { let message_hash = HashFor::::hash(&message.data[..]); - self.register_message_hashed(message_hash, topic, message); + self.register_message_hashed(message_hash, topic, message, None); } /// Call when a peer has been disconnected to stop tracking gossip status. @@ -429,7 +432,7 @@ impl ConsensusGossip { { tx.unbounded_send(TopicNotification { message: entry.message.data.clone(), - sender: None, + sender: entry.sender.clone(), }) .expect("receiver known to be live; qed"); } @@ -498,7 +501,7 @@ impl ConsensusGossip { } } if keep { - self.register_message_hashed(message_hash, topic, message); + self.register_message_hashed(message_hash, topic, message, Some(who.clone())); } } else { trace!(target:"gossip", "Ignored statement from unregistered peer {}", who); @@ -553,7 +556,7 @@ impl ConsensusGossip { force: bool, ) { let message_hash = HashFor::::hash(&message.data); - self.register_message_hashed(message_hash, topic, message.clone()); + self.register_message_hashed(message_hash, topic, message.clone(), None); let intent = if force { MessageIntent::ForcedBroadcast } else { MessageIntent::Broadcast }; propagate(protocol, iter::once((&message_hash, &topic, &message)), intent, &mut self.peers, &self.validators); } @@ -618,6 +621,7 @@ mod tests { message_hash: $hash, topic: $topic, message: ConsensusMessage { data: $m, engine_id: [0, 0, 0, 0]}, + sender: None, }); } } -- GitLab From f3a830d3e37d78a869c78c037cc2ac6f0c4e5ddd Mon Sep 17 00:00:00 2001 From: Ashley Date: Wed, 9 Oct 2019 04:31:39 +1300 Subject: [PATCH 197/275] Split off System random functions into a new Randomness module (#3699) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * split off system randomness functions into a new module * bump spec and impl version * Move randomness to bottom of construct_runtime calls, move initialization into on_initialize * Update srml/randomness/Cargo.toml Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update srml/randomness/src/lib.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update srml/randomness/src/lib.rs Co-Authored-By: Bastian Köcher * Update srml/randomness/Cargo.toml Co-Authored-By: Bastian Köcher * Improve system example * Update Cargo.lock * Fix randomness example * Get rid of the stored index * Add tests * Add a random test * Improve docs * Fix executive test :^) * Add a utility function to tests * Update srml/randomness/Cargo.toml Co-Authored-By: Gavin Wood * Update srml/randomness/src/lib.rs Co-Authored-By: Bastian Köcher * Update srml/randomness/src/lib.rs Co-Authored-By: Bastian Köcher * Change interpretation of block numbers * rename crate * refactor randomess module usage * change random material len to a const * Update srml/randomness-collective-flip/src/lib.rs Co-Authored-By: Bastian Köcher * Update srml/randomness-collective-flip/src/lib.rs Co-Authored-By: Bastian Köcher --- Cargo.lock | 17 ++ Cargo.toml | 1 + node-template/runtime/Cargo.toml | 2 + node-template/runtime/src/lib.rs | 3 +- node/runtime/Cargo.toml | 2 + node/runtime/src/lib.rs | 7 +- srml/contracts/Cargo.toml | 3 + srml/contracts/src/exec.rs | 2 +- srml/executive/src/lib.rs | 2 +- srml/randomness-collective-flip/Cargo.toml | 28 ++ srml/randomness-collective-flip/src/lib.rs | 289 +++++++++++++++++++++ srml/system/src/lib.rs | 77 +----- 12 files changed, 352 insertions(+), 81 deletions(-) create mode 100644 srml/randomness-collective-flip/Cargo.toml create mode 100644 srml/randomness-collective-flip/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 170ed9e2f1..d63806fee4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2478,6 +2478,7 @@ dependencies = [ "srml-indices 2.0.0", "srml-membership 2.0.0", "srml-offences 1.0.0", + "srml-randomness-collective-flip 2.0.0", "srml-session 2.0.0", "srml-staking 2.0.0", "srml-staking-reward-curve 2.0.0", @@ -2544,6 +2545,7 @@ dependencies = [ "srml-executive 2.0.0", "srml-grandpa 2.0.0", "srml-indices 2.0.0", + "srml-randomness-collective-flip 2.0.0", "srml-sudo 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", @@ -4011,6 +4013,7 @@ dependencies = [ "sr-sandbox 2.0.0", "sr-std 2.0.0", "srml-balances 2.0.0", + "srml-randomness-collective-flip 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", @@ -4224,6 +4227,20 @@ dependencies = [ "substrate-primitives 2.0.0", ] +[[package]] +name = "srml-randomness-collective-flip" +version = "2.0.0" +dependencies = [ + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 2.0.0", + "sr-primitives 2.0.0", + "sr-std 2.0.0", + "srml-support 2.0.0", + "srml-system 2.0.0", + "substrate-primitives 2.0.0", +] + [[package]] name = "srml-scored-pool" version = "1.0.0" diff --git a/Cargo.toml b/Cargo.toml index 71ba1c17f1..62993397fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -95,6 +95,7 @@ members = [ "srml/membership", "srml/metadata", "srml/offences", + "srml/randomness-collective-flip", "srml/scored-pool", "srml/session", "srml/staking", diff --git a/node-template/runtime/Cargo.toml b/node-template/runtime/Cargo.toml index 18948d503c..76821b6dfd 100644 --- a/node-template/runtime/Cargo.toml +++ b/node-template/runtime/Cargo.toml @@ -20,6 +20,7 @@ babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../ executive = { package = "srml-executive", path = "../../srml/executive", default_features = false } indices = { package = "srml-indices", path = "../../srml/indices", default_features = false } grandpa = { package = "srml-grandpa", path = "../../srml/grandpa", default-features = false } +randomness-collective-flip = { package = "srml-randomness-collective-flip", path = "../../srml/randomness-collective-flip", default_features = false } system = { package = "srml-system", path = "../../srml/system", default_features = false } timestamp = { package = "srml-timestamp", path = "../../srml/timestamp", default_features = false } sudo = { package = "srml-sudo", path = "../../srml/sudo", default_features = false } @@ -46,6 +47,7 @@ std = [ "grandpa/std", "primitives/std", "sr-primitives/std", + "randomness-collective-flip/std", "system/std", "timestamp/std", "sudo/std", diff --git a/node-template/runtime/src/lib.rs b/node-template/runtime/src/lib.rs index 216cb0edc2..ba328c6e37 100644 --- a/node-template/runtime/src/lib.rs +++ b/node-template/runtime/src/lib.rs @@ -272,6 +272,7 @@ construct_runtime!( Sudo: sudo, // Used for the module template in `./template.rs` TemplateModule: template::{Module, Call, Storage, Event}, + RandomnessCollectiveFlip: randomness_collective_flip::{Module, Call, Storage}, } ); @@ -340,7 +341,7 @@ impl_runtime_apis! { } fn random_seed() -> ::Hash { - System::random_seed() + RandomnessCollectiveFlip::random_seed() } } diff --git a/node/runtime/Cargo.toml b/node/runtime/Cargo.toml index f256575086..a47d652100 100644 --- a/node/runtime/Cargo.toml +++ b/node/runtime/Cargo.toml @@ -40,6 +40,7 @@ im-online = { package = "srml-im-online", path = "../../srml/im-online", default indices = { package = "srml-indices", path = "../../srml/indices", default-features = false } membership = { package = "srml-membership", path = "../../srml/membership", default-features = false } offences = { package = "srml-offences", path = "../../srml/offences", default-features = false } +randomness-collective-flip = { package = "srml-randomness-collective-flip", path = "../../srml/randomness-collective-flip", default-features = false } session = { package = "srml-session", path = "../../srml/session", default-features = false, features = ["historical"] } staking = { package = "srml-staking", path = "../../srml/staking", default-features = false } srml-staking-reward-curve = { path = "../../srml/staking/reward-curve"} @@ -78,6 +79,7 @@ std = [ "offchain-primitives/std", "offences/std", "primitives/std", + "randomness-collective-flip/std", "rstd/std", "rustc-hex", "safe-mix/std", diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 7495190464..ebe7b134e0 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -84,8 +84,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 172, - impl_version: 172, + spec_version: 173, + impl_version: 173, apis: RUNTIME_API_VERSIONS, }; @@ -518,6 +518,7 @@ construct_runtime!( ImOnline: im_online::{Module, Call, Storage, Event, ValidateUnsigned, Config}, AuthorityDiscovery: authority_discovery::{Module, Call, Config}, Offences: offences::{Module, Call, Storage, Event}, + RandomnessCollectiveFlip: randomness_collective_flip::{Module, Call, Storage}, } ); @@ -589,7 +590,7 @@ impl_runtime_apis! { } fn random_seed() -> ::Hash { - System::random_seed() + RandomnessCollectiveFlip::random_seed() } } diff --git a/srml/contracts/Cargo.toml b/srml/contracts/Cargo.toml index f076f5feda..aad45df860 100644 --- a/srml/contracts/Cargo.toml +++ b/srml/contracts/Cargo.toml @@ -17,6 +17,8 @@ rstd = { package = "sr-std", path = "../../core/sr-std", default-features = fals sandbox = { package = "sr-sandbox", path = "../../core/sr-sandbox", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } +randomness-collective-flip = { package = "srml-randomness-collective-flip", path = "../randomness-collective-flip", default-features = false } +timestamp = { package = "srml-timestamp", path = "../timestamp", default-features = false } [dev-dependencies] wabt = "0.9.2" @@ -33,6 +35,7 @@ std = [ "codec/std", "primitives/std", "sr-primitives/std", + "randomness-collective-flip/std", "runtime-io/std", "rstd/std", "sandbox/std", diff --git a/srml/contracts/src/exec.rs b/srml/contracts/src/exec.rs index 94343c5fb9..e4c5539cec 100644 --- a/srml/contracts/src/exec.rs +++ b/srml/contracts/src/exec.rs @@ -753,7 +753,7 @@ where } fn random(&self, subject: &[u8]) -> SeedOf { - system::Module::::random(subject) + randomness_collective_flip::Module::::random(subject) } fn now(&self) -> &MomentOf { diff --git a/srml/executive/src/lib.rs b/srml/executive/src/lib.rs index ad9cb7bf80..ee11ffadf4 100644 --- a/srml/executive/src/lib.rs +++ b/srml/executive/src/lib.rs @@ -451,7 +451,7 @@ mod tests { header: Header { parent_hash: [69u8; 32].into(), number: 1, - state_root: hex!("3e51b47b6cc8449eece93eee4b01f03b00a0ca7981c0b6c0447b6e0d50ca886d").into(), + state_root: hex!("a6378d7fdd31029d13718d54bdff10a370e75cc624aaf94a90e7e7d4a24e0bcc").into(), extrinsics_root: hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(), digest: Digest { logs: vec![], }, }, diff --git a/srml/randomness-collective-flip/Cargo.toml b/srml/randomness-collective-flip/Cargo.toml new file mode 100644 index 0000000000..5be9aad50f --- /dev/null +++ b/srml/randomness-collective-flip/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "srml-randomness-collective-flip" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +safe-mix = { version = "1.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +sr-primitives = { path = "../../core/sr-primitives", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } +system = { package = "srml-system", path = "../system", default-features = false } +rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } + +[dev-dependencies] +primitives = { package = "substrate-primitives", path = "../../core/primitives" } +runtime-io = { package = "sr-io", path = "../../core/sr-io" } + +[features] +default = ["std"] +std = [ + "safe-mix/std", + "system/std", + "codec/std", + "support/std", + "sr-primitives/std", + "rstd/std", +] diff --git a/srml/randomness-collective-flip/src/lib.rs b/srml/randomness-collective-flip/src/lib.rs new file mode 100644 index 0000000000..39dcf15ab4 --- /dev/null +++ b/srml/randomness-collective-flip/src/lib.rs @@ -0,0 +1,289 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! # Randomness Module +//! +//! The Randomness Collective Flip module provides a [`random`](./struct.Module.html#method.random) +//! function that generates low-influence random values based on the block hashes from the previous +//! `81` blocks. Low-influence randomness can be useful when defending against relatively weak +//! adversaries. +//! +//! ## Public Functions +//! +//! See the [`Module`](./struct.Module.html) struct for details of publicly available functions. +//! +//! ## Usage +//! +//! ### Prerequisites +//! +//! Import the Randomness Collective Flip module and derive your module's configuration trait from +//! the system trait. +//! +//! ### Example - Get random seed for the current block +//! +//! ``` +//! use support::{decl_module, dispatch::Result}; +//! +//! pub trait Trait: system::Trait {} +//! +//! decl_module! { +//! pub struct Module for enum Call where origin: T::Origin { +//! pub fn random_module_example(origin) -> Result { +//! let _random_seed = >::random_seed(); +//! Ok(()) +//! } +//! } +//! } +//! # fn main() { } +//! ``` + +#![cfg_attr(not(feature = "std"), no_std)] + +use rstd::{prelude::*, convert::TryInto}; +use sr_primitives::traits::Hash; +use support::{decl_module, decl_storage}; +use safe_mix::TripletMix; +use codec::Encode; +use system::Trait; + +const RANDOM_MATERIAL_LEN: u32 = 81; + +fn block_number_to_index(block_number: T::BlockNumber) -> usize { + // on_initialize is called on the first block after genesis + let index = (block_number - 1.into()) % RANDOM_MATERIAL_LEN.into(); + index.try_into().ok().expect("Something % 81 is always smaller than usize; qed") +} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + fn on_initialize(block_number: T::BlockNumber) { + let parent_hash = >::parent_hash(); + + >::mutate(|ref mut values| if values.len() < RANDOM_MATERIAL_LEN as usize { + values.push(parent_hash) + } else { + let index = block_number_to_index::(block_number); + values[index] = parent_hash; + }); + } + } +} + +decl_storage! { + trait Store for Module as RandomnessCollectiveFlip { + /// Series of block headers from the last 81 blocks that acts as random seed material. This + /// is arranged as a ring buffer with `block_number % 81` being the index into the `Vec` of + /// the oldest hash. + RandomMaterial get(random_material): Vec; + } +} + +impl Module { + /// Get the basic random seed. + /// + /// In general you won't want to use this, but rather `Self::random` which allows you to give a + /// subject for the random result and whose value will be independently low-influence random + /// from any other such seeds. + pub fn random_seed() -> T::Hash { + Self::random(&[][..]) + } + + /// Get a low-influence "random" value. + /// + /// Being a deterministic block chain, real randomness is difficult to come by. This gives you + /// something that approximates it. `subject` is a context identifier and allows you to get a + /// different result to other callers of this function; use it like + /// `random(&b"my context"[..])`. This is initially implemented through a low-influence + /// "triplet mix" convolution of previous block hash values. In the future it will be generated + /// from a secure verifiable random function (VRF). + /// + /// ### Security Notes + /// + /// This randomness uses a low-influence function, drawing upon the block hashes from the + /// previous 81 blocks. Its result for any given subject will be known far in advance by anyone + /// observing the chain. Any block producer has significant influence over their block hashes + /// bounded only by their computational resources. Our low-influence function reduces the actual + /// block producer's influence over the randomness, but increases the influence of small + /// colluding groups of recent block producers. + /// + /// Some BABE blocks have VRF outputs where the block producer has exactly one bit of influence, + /// either they make the block or they do not make the block and thus someone else makes the + /// next block. Yet, this randomness is not fresh in all BABE blocks. + /// + /// If that is an insufficient security guarantee then two things can be used to improve this + /// randomness: + /// + /// - Name, in advance, the block number whose random value will be used; ensure your module + /// retains a buffer of previous random values for its subject and then index into these in + /// order to obviate the ability of your user to look up the parent hash and choose when to + /// transact based upon it. + /// - Require your user to first commit to an additional value by first posting its hash. + /// Require them to reveal the value to determine the final result, hashing it with the + /// output of this random function. This reduces the ability of a cabal of block producers + /// from conspiring against individuals. + /// + /// WARNING: Hashing the result of this function will remove any low-influence properties it has + /// and mean that all bits of the resulting value are entirely manipulatable by the author of + /// the parent block, who can determine the value of `parent_hash`. + pub fn random(subject: &[u8]) -> T::Hash { + let block_number = >::block_number(); + let index = block_number_to_index::(block_number); + + let hash_series = >::get(); + if !hash_series.is_empty() { + // Always the case after block 1 is initialised. + hash_series.iter() + .cycle() + .skip(index) + .take(RANDOM_MATERIAL_LEN as usize) + .enumerate() + .map(|(i, h)| (i as i8, subject, h).using_encoded(T::Hashing::hash)) + .triplet_mix() + } else { + T::Hash::default() + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use primitives::{H256, Blake2Hasher}; + use sr_primitives::{Perbill, traits::{BlakeTwo256, OnInitialize, Header as _, IdentityLookup}, testing::Header}; + use support::{impl_outer_origin, parameter_types}; + use runtime_io::with_externalities; + + #[derive(Clone, PartialEq, Eq)] + pub struct Test; + + impl_outer_origin! { + pub enum Origin for Test {} + } + + parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + } + + impl system::Trait for Test { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = (); + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type WeightMultiplierUpdate = (); + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type AvailableBlockRatio = AvailableBlockRatio; + type MaximumBlockLength = MaximumBlockLength; + type Version = (); + } + + type System = system::Module; + type Randomness = Module; + + fn new_test_ext() -> runtime_io::TestExternalities { + let t = system::GenesisConfig::default().build_storage::().unwrap(); + t.into() + } + + #[test] + fn test_block_number_to_index() { + for i in 1 .. 1000 { + assert_eq!((i - 1) as usize % 81, block_number_to_index::(i)); + } + } + + fn setup_blocks(blocks: u64) { + let mut parent_hash = System::parent_hash(); + + for i in 1 .. (blocks + 1) { + System::initialize(&i, &parent_hash, &Default::default(), &Default::default()); + Randomness::on_initialize(i); + + let header = System::finalize(); + parent_hash = header.hash(); + System::set_block_number(*header.number()); + } + } + + #[test] + fn test_random_material_parital() { + with_externalities(&mut new_test_ext(), || { + let genesis_hash = System::parent_hash(); + + setup_blocks(38); + + let random_material = Randomness::random_material(); + + assert_eq!(random_material.len(), 38); + assert_eq!(random_material[0], genesis_hash); + }); + } + + #[test] + fn test_random_material_filled() { + with_externalities(&mut new_test_ext(), || { + let genesis_hash = System::parent_hash(); + + setup_blocks(81); + + let random_material = Randomness::random_material(); + + assert_eq!(random_material.len(), 81); + assert_ne!(random_material[0], random_material[1]); + assert_eq!(random_material[0], genesis_hash); + }); + } + + #[test] + fn test_random_material_filled_twice() { + with_externalities(&mut new_test_ext(), || { + let genesis_hash = System::parent_hash(); + + setup_blocks(162); + + let random_material = Randomness::random_material(); + + assert_eq!(random_material.len(), 81); + assert_ne!(random_material[0], random_material[1]); + assert_ne!(random_material[0], genesis_hash); + }); + } + + #[test] + fn test_random() { + with_externalities(&mut new_test_ext(), || { + setup_blocks(162); + + assert_eq!(System::block_number(), 162); + assert_eq!(Randomness::random_seed(), Randomness::random_seed()); + assert_ne!(Randomness::random(b"random_1"), Randomness::random(b"random_2")); + + let random = Randomness::random_seed(); + + assert_ne!(random, H256::zero()); + assert!(!Randomness::random_material().contains(&random)); + }); + } +} diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index 5a1115b90d..79782d5af4 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -65,7 +65,7 @@ //! //! Import the System module and derive your module's configuration trait from the system trait. //! -//! ### Example - Get random seed and extrinsic count for the current block +//! ### Example - Get extrinsic count and parent hash for the current block //! //! ``` //! use support::{decl_module, dispatch::Result}; @@ -77,8 +77,8 @@ //! pub struct Module for enum Call where origin: T::Origin { //! pub fn system_module_example(origin) -> Result { //! let _sender = ensure_signed(origin)?; -//! let _random_seed = >::random_seed(); //! let _extrinsic_count = >::extrinsic_count(); +//! let _parent_hash = >::parent_hash(); //! Ok(()) //! } //! } @@ -114,7 +114,6 @@ use support::{ decl_module, decl_event, decl_storage, decl_error, storage, Parameter, traits::{Contains, Get}, }; -use safe_mix::TripletMix; use codec::{Encode, Decode}; #[cfg(any(feature = "std", test))] @@ -389,9 +388,6 @@ decl_storage! { pub BlockHash get(block_hash) build(|_| vec![(T::BlockNumber::zero(), hash69())]): map T::BlockNumber => T::Hash; /// Extrinsics data for the current block (maps an extrinsic's index to its data). ExtrinsicData get(extrinsic_data): map u32 => Vec; - /// Series of block headers from the last 81 blocks that acts as random seed material. This is arranged as a - /// ring buffer with the `i8` prefix being the index into the `Vec` of the oldest hash. - RandomMaterial get(random_material): (i8, Vec); /// The current block number being processed. Set by `execute_block`. Number get(block_number) build(|_| 1.into()): T::BlockNumber; /// Hash of the previous block. @@ -641,12 +637,6 @@ impl Module { >::put(parent_hash); >::insert(*number - One::one(), parent_hash); >::put(txs_root); - >::mutate(|&mut(ref mut index, ref mut values)| if values.len() < 81 { - values.push(parent_hash.clone()) - } else { - values[*index as usize] = parent_hash.clone(); - *index = (*index + 1) % 81; - }); >::kill(); EventCount::kill(); >::remove_prefix(&()); @@ -736,69 +726,6 @@ impl Module { /// Return the chain's current runtime version. pub fn runtime_version() -> RuntimeVersion { T::Version::get() } - /// Get the basic random seed. - /// - /// In general you won't want to use this, but rather `Self::random` which - /// allows you to give a subject for the random result and whose value will - /// be independently low-influence random from any other such seeds. - pub fn random_seed() -> T::Hash { - Self::random(&[][..]) - } - - /// Get a low-influence "random" value. - /// - /// Being a deterministic block chain, real randomness is difficult to come - /// by. This gives you something that approximates it. `subject` is a - /// context identifier and allows you to get a different result to other - /// callers of this function; use it like `random(&b"my context"[..])`. - /// - /// This is initially implemented through a low-influence "triplet mix" - /// convolution of previous block hash values. In the future it will be - /// generated from a secure verifiable random function (VRF). - /// - /// ### Security Notes - /// - /// This randomness uses a low-influence function, drawing upon the block - /// hashes from the previous 81 blocks. Its result for any given subject - /// will be known in advance by the block producer of this block (and, - /// indeed, anyone who knows the block's `parent_hash`). However, it is - /// mostly impossible for the producer of this block *alone* to influence - /// the value of this hash. A sizable minority of dishonest and coordinating - /// block producers would be required in order to affect this value. If that - /// is an insufficient security guarantee then two things can be used to - /// improve this randomness: - /// - /// - Name, in advance, the block number whose random value will be used; - /// ensure your module retains a buffer of previous random values for its - /// subject and then index into these in order to obviate the ability of - /// your user to look up the parent hash and choose when to transact based - /// upon it. - /// - Require your user to first commit to an additional value by first - /// posting its hash. Require them to reveal the value to determine the - /// final result, hashing it with the output of this random function. This - /// reduces the ability of a cabal of block producers from conspiring - /// against individuals. - /// - /// WARNING: Hashing the result of this function will remove any - /// low-influnce properties it has and mean that all bits of the resulting - /// value are entirely manipulatable by the author of the parent block, who - /// can determine the value of `parent_hash`. - pub fn random(subject: &[u8]) -> T::Hash { - let (index, hash_series) = >::get(); - if hash_series.len() > 0 { - // Always the case after block 1 is initialised. - hash_series.iter() - .cycle() - .skip(index as usize) - .take(81) - .enumerate() - .map(|(i, h)| (i as i8, subject, h).using_encoded(T::Hashing::hash)) - .triplet_mix() - } else { - T::Hash::default() - } - } - /// Increment a particular account's nonce by 1. pub fn inc_account_nonce(who: &T::AccountId) { >::insert(who, Self::account_nonce(who) + T::Index::one()); -- GitLab From 82bd785c9c3f64eed744e4602fac5eb4a96a2c9b Mon Sep 17 00:00:00 2001 From: Demi Obenour <48690212+DemiMarie-parity@users.noreply.github.com> Date: Tue, 8 Oct 2019 15:09:05 -0400 Subject: [PATCH 198/275] Update dependencies, respecting semver (#3784) --- Cargo.lock | 154 +++++++++++++++++++++++++++-------------------------- 1 file changed, 78 insertions(+), 76 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d63806fee4..ba762f1393 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,7 +38,7 @@ dependencies = [ [[package]] name = "ahash" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "const-random 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -366,7 +366,7 @@ dependencies = [ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -532,7 +532,7 @@ dependencies = [ "rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -751,13 +751,14 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "1.0.0-pre.1" +version = "1.0.0-pre.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -890,7 +891,7 @@ dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "miniz_oxide 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1159,10 +1160,10 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ahash 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "ahash 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1382,7 +1383,7 @@ name = "impl-trait-for-tuples" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1459,7 +1460,7 @@ dependencies = [ "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "websocket 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1474,7 +1475,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1683,7 +1684,7 @@ dependencies = [ "asn1_der 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "bs58 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ed25519-dalek 1.0.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1703,7 +1704,7 @@ dependencies = [ "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1774,7 +1775,7 @@ dependencies = [ "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1801,7 +1802,7 @@ dependencies = [ "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "uint 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1841,7 +1842,7 @@ dependencies = [ "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2043,7 +2044,7 @@ dependencies = [ [[package]] name = "libsecp256k1" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2051,6 +2052,7 @@ dependencies = [ "hmac-drbg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2164,7 +2166,7 @@ version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hashbrown 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hashbrown 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2194,7 +2196,7 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2264,7 +2266,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2283,9 +2285,9 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.10.24 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.10.25 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.50 (registry+https://github.com/rust-lang/crates.io-index)", "schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2680,7 +2682,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "openssl" -version = "0.10.24" +version = "0.10.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2688,7 +2690,7 @@ dependencies = [ "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.50 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2698,7 +2700,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "openssl-sys" -version = "0.9.49" +version = "0.9.50" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2742,7 +2744,7 @@ dependencies = [ "parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2757,7 +2759,7 @@ dependencies = [ "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2909,7 +2911,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3001,7 +3003,7 @@ name = "proc-macro-hack" version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3016,7 +3018,7 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3119,7 +3121,7 @@ name = "quote" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3447,7 +3449,7 @@ name = "rustversion" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3591,14 +3593,14 @@ name = "serde_derive" version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3698,7 +3700,7 @@ dependencies = [ "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3792,7 +3794,7 @@ dependencies = [ "substrate-state-machine 2.0.0", "substrate-test-runtime-client 2.0.0", "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", - "trybuild 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", + "trybuild 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3801,7 +3803,7 @@ version = "2.0.0" dependencies = [ "environmental 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libsecp256k1 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libsecp256k1 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", @@ -3824,7 +3826,7 @@ dependencies = [ "primitive-types 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-std 2.0.0", "substrate-application-crypto 2.0.0", @@ -4305,7 +4307,7 @@ name = "srml-staking-reward-curve" version = "2.0.0" dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4388,7 +4390,7 @@ dependencies = [ "srml-support 2.0.0", "substrate-inherents 2.0.0", "substrate-primitives 2.0.0", - "trybuild 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", + "trybuild 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4582,7 +4584,7 @@ dependencies = [ "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "prost-build 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-authority-discovery-primitives 2.0.0", "substrate-client 2.0.0", @@ -4638,7 +4640,7 @@ version = "2.0.0" dependencies = [ "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-chain-spec-derive 2.0.0", "substrate-network 2.0.0", @@ -4651,7 +4653,7 @@ name = "substrate-chain-spec-derive" version = "2.0.0" dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4675,7 +4677,7 @@ dependencies = [ "names 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rpassword 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-client 2.0.0", @@ -4964,7 +4966,7 @@ dependencies = [ "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libsecp256k1 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libsecp256k1 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.40.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4998,7 +5000,7 @@ dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "srml-finality-tracker 2.0.0", "substrate-client 2.0.0", @@ -5069,7 +5071,7 @@ dependencies = [ "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-application-crypto 2.0.0", "substrate-primitives 2.0.0", "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5102,7 +5104,7 @@ dependencies = [ "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "slog_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5120,7 +5122,7 @@ dependencies = [ "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5179,7 +5181,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5243,7 +5245,7 @@ dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-version 2.0.0", @@ -5275,7 +5277,7 @@ dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "sr-version 2.0.0", "substrate-primitives 2.0.0", "substrate-rpc-primitives 2.0.0", @@ -5300,7 +5302,7 @@ dependencies = [ "jsonrpc-ws-server 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", ] @@ -5321,7 +5323,7 @@ name = "substrate-serializer" version = "2.0.0" dependencies = [ "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5341,7 +5343,7 @@ dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -5619,7 +5621,7 @@ name = "syn" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5741,7 +5743,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6006,7 +6008,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hashbrown 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hashbrown 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6035,13 +6037,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "trybuild" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6138,7 +6140,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "unsigned-varint" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6207,7 +6209,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "wabt-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6263,7 +6265,7 @@ dependencies = [ "bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-shared 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6295,7 +6297,7 @@ name = "wasm-bindgen-macro-support" version = "0.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-backend 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6315,7 +6317,7 @@ dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-backend 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6563,7 +6565,7 @@ dependencies = [ "checksum aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2e5b0458ea3beae0d1d8c0f3946564f8e10f90646cf78c06b4351052058d1ee" "checksum aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d" "checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100" -"checksum ahash 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b58aeefd9396419a4f4f2b9778f2d832a11851b55010e231c5390cf2b1c416b4" +"checksum ahash 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)" = "b35dfc96a657c1842b4eb73180b65e37152d4b94d0eb5cb51708aee7826950b4" "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" "checksum aio-limited 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c4dddf55b0b2da9acb7512f21c0a4f1c0871522ec4ab7fb919d0da807d1e32b3" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" @@ -6646,7 +6648,7 @@ dependencies = [ "checksum dns-parser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea" "checksum doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "923dea538cea0aa3025e8685b20d6ee21ef99c4f77e954a30febbaac5ec73a97" "checksum ed25519-dalek 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d07e8b8a8386c3b89a7a4b329fdfa4cb545de2545e9e2ebbc3dd3929253e426" -"checksum ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81956bcf7ef761fb4e1d88de3fa181358a0d26cbcb9755b587a08f9119824b86" +"checksum ed25519-dalek 1.0.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)" = "845aaacc16f01178f33349e7c992ecd0cee095aa5e577f0f4dee35971bd36455" "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" "checksum elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "073be79b6538296faf81c631872676600616073817dd9a440c477ad09b408983" "checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" @@ -6693,7 +6695,7 @@ dependencies = [ "checksum hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" "checksum hash256-std-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" "checksum hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da" -"checksum hashbrown 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2bcea5b597dd98e6d1f1ec171744cc5dee1a30d1c23c5b98e3cf9d4fbdf8a526" +"checksum hashbrown 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6587d09be37fb98a11cb08b9000a3f592451c1b1b613ca69d949160e313a430a" "checksum hashmap_core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "2d6852e5a86250521973b0c1d39677166d8a9c0047c908d7e04f1aa04177973c" "checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" @@ -6767,7 +6769,7 @@ dependencies = [ "checksum libp2p-yamux 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a37bed07c8ee0ceeecdfb90d703aa6b1cec99a69b4157e5f7f2c03acacbfca15" "checksum librocksdb-sys 5.18.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d19778314deaa7048f2ea7d07b8aa12e1c227acebe975a37eeab6d2f8c74e41b" "checksum libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "688e8d65e495567c2c35ea0001b26b9debf0b4ea11f8cccc954233b75fc3428a" -"checksum libsecp256k1 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf0a4113e7b18b72b9b65d5b35335d99865ef059034426e4b85ad63adddf996" +"checksum libsecp256k1 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "63cc09b49bf0cc55885982347b174ad89855e97a12284d2c9dcc6da2e20c28f5" "checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" "checksum linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7c91c4c7bbeb4f2f7c4e5be11e6a05bd6830bc37249c47ce1ad86ad453ff9c" @@ -6785,7 +6787,7 @@ dependencies = [ "checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" "checksum merlin 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "de2d16d3b15fec5943d1144f861f61f279d165fdd60998ca262913b9bf1c8adb" "checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" -"checksum miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7108aff85b876d06f22503dcce091e29f76733b2bfdd91eebce81f5e68203a10" +"checksum miniz_oxide 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "304f66c19be2afa56530fa7c39796192eef38618da8d19df725ad7c6d6b2aaae" "checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23" "checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" @@ -6808,9 +6810,9 @@ dependencies = [ "checksum once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37" "checksum once_cell 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d584f08c2d717d5c23a6414fc2822b71c651560713e54fa7eace675f758a355e" "checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" -"checksum openssl 0.10.24 (registry+https://github.com/rust-lang/crates.io-index)" = "8152bb5a9b5b721538462336e3bef9a539f892715e5037fda0f984577311af15" +"checksum openssl 0.10.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2f372b2b53ce10fb823a337aaa674e3a7d072b957c6264d0f4ff0bd86e657449" "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)" = "f4fad9e54bd23bd4cbbe48fdc08a1b8091707ac869ef8508edea2fec77dcc884" +"checksum openssl-sys 0.9.50 (registry+https://github.com/rust-lang/crates.io-index)" = "2c42dcccb832556b5926bc9ae61e8775f2a61e725ab07ab3d1e7fcf8ae62c3b6" "checksum output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9" "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" "checksum parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" @@ -6845,7 +6847,7 @@ dependencies = [ "checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" "checksum proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "114cdf1f426eb7f550f01af5f53a33c0946156f6814aec939b3bd77e844f9a9d" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -"checksum proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afdc77cc74ec70ed262262942ebb7dac3d479e9e5cfa2da1841c0806f6cdabcc" +"checksum proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "90cf5f418035b98e655e9cdb225047638296b862b42411c4e45bb88d700f7fc0" "checksum prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96d14b1c185652833d24aaad41c5832b0be5616a590227c1fbff57c616754b23" "checksum prost-build 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb788126ea840817128183f8f603dce02cb7aea25c2a0b764359d8e20010702e" "checksum prost-derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e7dc378b94ac374644181a2247cebf59a6ec1c88b49ac77f3a94b86b79d0e11" @@ -6911,7 +6913,7 @@ dependencies = [ "checksum send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0eddf2e8f50ced781f288c19f18621fa72a3779e3cb58dbf23b07469b0abeb4" "checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd" "checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e" -"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704" +"checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2" "checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68" "checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" "checksum sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d963c78ce367df26d7ea8b8cc655c651b42e8a1e584e869c1e17dae3ccb116a" @@ -6982,7 +6984,7 @@ dependencies = [ "checksum trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0b779f7c1c8fe9276365d9d5be5c4b5adeacf545117bb3f64c974305789c5c0b" "checksum trie-standardmap 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3161ba520ab28cd8e6b68e1126f1009f6e335339d1a73b978139011703264c8" "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" -"checksum trybuild 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "9fc69705e261edf3b9a87012b2353a49f49c0465186b5ab96e95f6983d6984aa" +"checksum trybuild 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "10d8f366221c5a5ff8a62faa005e186fdce758949d34a9140b64a062951bae68" "checksum twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d261e83e727c8e2dbb75dacac67c36e35db36a958ee504f2164fc052434e1" "checksum twox-hash 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" @@ -6996,7 +6998,7 @@ dependencies = [ "checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" -"checksum unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2c64cdf40b4a9645534a943668681bcb219faf51874d4b65d2e0abda1b10a2ab" +"checksum unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f0023a96687fe169081e8adce3f65e3874426b7886e9234d490af2dc077959" "checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" -- GitLab From bebe88a64c7199fcbcfdfae0ba6eb72e9e797b8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Tue, 8 Oct 2019 20:56:22 +0100 Subject: [PATCH 199/275] babe: verify slots are strictly increasing (#3785) * babe: re-use code to propose and import test block * babe: add failing test for slot validation * babe: verify slot numbers are strictly increasing --- core/consensus/babe/src/lib.rs | 39 ++++-- core/consensus/babe/src/tests.rs | 220 +++++++++++++++++-------------- 2 files changed, 144 insertions(+), 115 deletions(-) diff --git a/core/consensus/babe/src/lib.rs b/core/consensus/babe/src/lib.rs index 4f69c176ce..0eacf1407e 100644 --- a/core/consensus/babe/src/lib.rs +++ b/core/consensus/babe/src/lib.rs @@ -795,6 +795,31 @@ impl BlockImport for BabeBlockImport(&parent_header) + .map(|d| d.slot_number()) + .expect("parent is non-genesis; valid BABE headers contain a pre-digest; \ + header has already been verified; qed"); + + // make sure that slot number is strictly increasing + if slot_number <= parent_slot { + return Err( + ConsensusError::ClientImport(babe_err!( + "Slot number must increase: parent slot: {}, this slot: {}", + parent_slot, + slot_number + )) + ); + } + let mut epoch_changes = self.epoch_changes.lock(); // check if there's any epoch change expected to happen at this slot. @@ -803,20 +828,6 @@ impl BlockImport for BabeBlockImport(&parent_header) - .map(|d| d.slot_number()) - .expect("parent is non-genesis; valid BABE headers contain a pre-digest; \ - header has already been verified; qed"); - let parent_weight = if *parent_header.number() == Zero::zero() { 0 } else { diff --git a/core/consensus/babe/src/tests.rs b/core/consensus/babe/src/tests.rs index 46c038b187..e6883977a0 100644 --- a/core/consensus/babe/src/tests.rs +++ b/core/consensus/babe/src/tests.rs @@ -525,35 +525,33 @@ fn can_author_block() { } } -#[test] -fn importing_block_one_sets_genesis_epoch() { - let mut net = BabeTestNet::new(1); - - let peer = net.peer(0); - let data = peer.data.as_ref().expect("babe link set up during initialization"); - let client = peer.client().as_full().expect("Only full clients are used in tests").clone(); - - let mut environ = DummyFactory { - client: client.clone(), - config: data.link.config.clone(), - epoch_changes: data.link.epoch_changes.clone(), - mutator: Arc::new(|_, _| ()), - }; - - let genesis_header = client.header(&BlockId::Number(0)).unwrap().unwrap(); - - let mut proposer = environ.init(&genesis_header).unwrap(); - let babe_claim = Item::babe_pre_digest(babe_primitives::BabePreDigest::Secondary { - authority_index: 0, - slot_number: 999, +// Propose and import a new BABE block on top of the given parent. +fn propose_and_import_block( + parent: &TestHeader, + slot_number: Option, + proposer_factory: &mut DummyFactory, + block_import: &mut BoxBlockImport, +) -> H256 { + let mut proposer = proposer_factory.init(parent).unwrap(); + + let slot_number = slot_number.unwrap_or_else(|| { + let parent_pre_digest = find_pre_digest(parent).unwrap(); + parent_pre_digest.slot_number() + 1 }); - let pre_digest = sr_primitives::generic::Digest { logs: vec![babe_claim] }; - let genesis_epoch = data.link.config.genesis_epoch(999); + let pre_digest = sr_primitives::generic::Digest { + logs: vec![ + Item::babe_pre_digest( + BabePreDigest::Secondary { + authority_index: 0, + slot_number, + }, + ), + ], + }; let mut block = futures::executor::block_on(proposer.propose_with(pre_digest)).unwrap(); - // seal by alice. let seal = { // sign the pre-sealed hash of the block and then // add it to a digest item. @@ -569,18 +567,14 @@ fn importing_block_one_sets_genesis_epoch() { block.header.digest_mut().pop(); h }; - assert_eq!(*block.header.number(), 1); - let (header, body) = block.deconstruct(); - let post_digests = vec![seal]; - let mut block_import = data.block_import.lock().take().expect("import set up during init"); - block_import.import_block( + let import_result = block_import.import_block( BlockImportParams { origin: BlockOrigin::Own, - header, + header: block.header, justification: None, - post_digests, - body: Some(body), + post_digests: vec![seal], + body: Some(block.extrinsics), finalized: false, auxiliary: Vec::new(), fork_choice: ForkChoiceStrategy::LongestChain, @@ -588,14 +582,51 @@ fn importing_block_one_sets_genesis_epoch() { Default::default(), ).unwrap(); + match import_result { + ImportResult::Imported(_) => {}, + _ => panic!("expected block to be imported"), + } + + post_hash +} + +#[test] +fn importing_block_one_sets_genesis_epoch() { + let mut net = BabeTestNet::new(1); + + let peer = net.peer(0); + let data = peer.data.as_ref().expect("babe link set up during initialization"); + let client = peer.client().as_full().expect("Only full clients are used in tests").clone(); + + let mut proposer_factory = DummyFactory { + client: client.clone(), + config: data.link.config.clone(), + epoch_changes: data.link.epoch_changes.clone(), + mutator: Arc::new(|_, _| ()), + }; + + let mut block_import = data.block_import.lock().take().expect("import set up during init"); + + let genesis_header = client.header(&BlockId::Number(0)).unwrap().unwrap(); + + let block_hash = propose_and_import_block( + &genesis_header, + Some(999), + &mut proposer_factory, + &mut block_import, + ); + + let genesis_epoch = data.link.config.genesis_epoch(999); + let epoch_changes = data.link.epoch_changes.lock(); let epoch_for_second_block = epoch_changes.epoch_for_child_of( descendent_query(&*client), - &post_hash, + &block_hash, 1, 1000, |slot| data.link.config.genesis_epoch(slot), ).unwrap().unwrap().into_inner(); + assert_eq!(epoch_for_second_block, genesis_epoch); } @@ -612,81 +643,28 @@ fn importing_epoch_change_block_prunes_tree() { let mut block_import = data.block_import.lock().take().expect("import set up during init"); let epoch_changes = data.link.epoch_changes.clone(); - // This is just boilerplate code for proposing and importing a valid BABE - // block that's built on top of the given parent. The proposer takes care - // of producing epoch change digests according to the epoch duration (which - // is set to 6 slots in the test runtime). - let mut propose_and_import_block = |parent_header| { - let mut environ = DummyFactory { - client: client.clone(), - config: data.link.config.clone(), - epoch_changes: data.link.epoch_changes.clone(), - mutator: Arc::new(|_, _| ()), - }; - - let mut proposer = environ.init(&parent_header).unwrap(); - let parent_pre_digest = find_pre_digest(&parent_header).unwrap(); - - let pre_digest = sr_primitives::generic::Digest { - logs: vec![ - Item::babe_pre_digest( - BabePreDigest::Secondary { - authority_index: 0, - slot_number: parent_pre_digest.slot_number() + 1, - }, - ), - ], - }; - - let mut block = futures::executor::block_on(proposer.propose_with(pre_digest)).unwrap(); - - let seal = { - // sign the pre-sealed hash of the block and then - // add it to a digest item. - let pair = AuthorityPair::from_seed(&[1; 32]); - let pre_hash = block.header.hash(); - let signature = pair.sign(pre_hash.as_ref()); - Item::babe_seal(signature) - }; - - let post_hash = { - block.header.digest_mut().push(seal.clone()); - let h = block.header.hash(); - block.header.digest_mut().pop(); - h - }; - - let next_epoch_digest = - find_next_epoch_digest::(&block.header).unwrap(); - - let import_result = block_import.import_block( - BlockImportParams { - origin: BlockOrigin::Own, - header: block.header, - justification: None, - post_digests: vec![seal], - body: Some(block.extrinsics), - finalized: false, - auxiliary: Vec::new(), - fork_choice: ForkChoiceStrategy::LongestChain, - }, - Default::default(), - ).unwrap(); - - match import_result { - ImportResult::Imported(_) => {}, - _ => panic!("expected block to be imported"), - } - - (post_hash, next_epoch_digest) + let mut proposer_factory = DummyFactory { + client: client.clone(), + config: data.link.config.clone(), + epoch_changes: data.link.epoch_changes.clone(), + mutator: Arc::new(|_, _| ()), }; + // This is just boilerplate code for proposing and importing n valid BABE + // blocks that are built on top of the given parent. The proposer takes care + // of producing epoch change digests according to the epoch duration (which + // is set to 6 slots in the test runtime). let mut propose_and_import_blocks = |parent_id, n| { let mut hashes = Vec::new(); let mut parent_header = client.header(&parent_id).unwrap().unwrap(); for _ in 0..n { - let (block_hash, _) = propose_and_import_block(parent_header); + let block_hash = propose_and_import_block( + &parent_header, + None, + &mut proposer_factory, + &mut block_import, + ); hashes.push(block_hash); parent_header = client.header(&BlockId::Hash(block_hash)).unwrap().unwrap(); } @@ -758,3 +736,43 @@ fn importing_epoch_change_block_prunes_tree() { epoch_changes.lock().tree().iter().map(|(h, _, _)| h).any(|h| fork_3.contains(h)), ); } + +#[test] +#[should_panic] +fn verify_slots_are_strictly_increasing() { + let mut net = BabeTestNet::new(1); + + let peer = net.peer(0); + let data = peer.data.as_ref().expect("babe link set up during initialization"); + + let client = peer.client().as_full().expect("Only full clients are used in tests").clone(); + let mut block_import = data.block_import.lock().take().expect("import set up during init"); + + let mut proposer_factory = DummyFactory { + client: client.clone(), + config: data.link.config.clone(), + epoch_changes: data.link.epoch_changes.clone(), + mutator: Arc::new(|_, _| ()), + }; + + let genesis_header = client.header(&BlockId::Number(0)).unwrap().unwrap(); + + // we should have no issue importing this block + let b1 = propose_and_import_block( + &genesis_header, + Some(999), + &mut proposer_factory, + &mut block_import, + ); + + let b1 = client.header(&BlockId::Hash(b1)).unwrap().unwrap(); + + // we should fail to import this block since the slot number didn't increase. + // we will panic due to the `PanickingBlockImport` defined above. + propose_and_import_block( + &b1, + Some(999), + &mut proposer_factory, + &mut block_import, + ); +} -- GitLab From 79c776afa2d4893efabfc19da7b0786c88090569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 9 Oct 2019 15:50:30 +0200 Subject: [PATCH 200/275] Move `Externalities` into its own crate (#3775) * Move `Externalities` into `substrate-externalities` - `Externalities` now support generic extensions - Split of `primtives-storage` for storage primitive types * Move the externalities scoping into `substrate-externalities` * Fix compilation * Review feedback * Adds macro for declaring extensions * Fix benchmarks * Introduce `ExtensionStore` trait * Last review comments * Implement it for `ExtensionStore` --- Cargo.lock | 27 ++- Cargo.toml | 1 + core/application-crypto/src/ed25519.rs | 9 +- core/application-crypto/src/sr25519.rs | 9 +- core/client/db/src/lib.rs | 5 +- core/client/src/call_executor.rs | 41 ++-- core/client/src/client.rs | 52 +++-- core/client/src/genesis.rs | 14 +- core/client/src/light/call_executor.rs | 70 ++++--- core/client/src/light/fetcher.rs | 7 +- core/client/src/light/mod.rs | 4 +- core/executor/Cargo.toml | 1 + core/executor/src/lib.rs | 4 +- core/executor/src/native_executor.rs | 22 +-- core/executor/src/sandbox.rs | 24 +-- core/executor/src/wasm_runtime.rs | 10 +- core/executor/src/wasmi_execution.rs | 34 ++-- core/externalities/Cargo.toml | 12 ++ core/externalities/src/extensions.rs | 127 ++++++++++++ core/externalities/src/lib.rs | 139 +++++++++++++ core/externalities/src/scope_limited.rs | 37 ++++ core/finality-grandpa/src/finality_proof.rs | 4 +- core/primitives/Cargo.toml | 6 +- core/primitives/src/child_storage_key.rs | 68 ------- core/primitives/src/lib.rs | 5 +- core/primitives/src/offchain.rs | 114 +---------- core/primitives/src/testing.rs | 7 +- core/primitives/src/traits.rs | 126 +----------- core/primitives/storage/Cargo.toml | 15 ++ .../{src/storage.rs => storage/src/lib.rs} | 78 ++++++-- core/rpc/src/author/tests.rs | 8 +- core/rpc/src/state/state_full.rs | 10 +- core/sr-io/Cargo.toml | 4 +- core/sr-io/src/lib.rs | 7 +- core/sr-io/with_std.rs | 90 ++++----- core/sr-primitives/Cargo.toml | 2 + core/sr-primitives/src/lib.rs | 3 + core/sr-primitives/src/offchain/http.rs | 12 +- core/state-machine/Cargo.toml | 1 + core/state-machine/src/basic.rs | 61 +++--- core/state-machine/src/ext.rs | 169 +++++++++------- core/state-machine/src/lib.rs | 184 ++++++++++-------- core/state-machine/src/overlayed_changes.rs | 10 +- core/state-machine/src/proving_backend.rs | 2 +- core/state-machine/src/testing.rs | 84 ++++---- core/test-runtime/src/system.rs | 29 +-- node-template/runtime/src/template.rs | 14 +- node/executor/src/lib.rs | 27 ++- srml/assets/src/lib.rs | 26 +-- srml/aura/src/mock.rs | 4 +- srml/aura/src/tests.rs | 4 +- srml/authority-discovery/src/lib.rs | 26 +-- srml/authorship/src/lib.rs | 19 +- srml/babe/src/mock.rs | 2 +- srml/babe/src/tests.rs | 13 +- srml/balances/src/mock.rs | 4 +- srml/balances/src/tests.rs | 90 ++++----- srml/collective/src/lib.rs | 28 +-- srml/contracts/src/exec.rs | 60 +++--- srml/contracts/src/tests.rs | 55 +++--- srml/council/src/lib.rs | 1 - srml/democracy/src/lib.rs | 79 ++++---- srml/elections-phragmen/src/lib.rs | 86 ++++---- srml/elections/src/mock.rs | 12 +- srml/elections/src/tests.rs | 114 +++++------ srml/example/src/lib.rs | 15 +- srml/executive/src/lib.rs | 26 +-- srml/finality-tracker/src/lib.rs | 15 +- srml/generic-asset/src/mock.rs | 6 +- srml/generic-asset/src/tests.rs | 92 ++++----- srml/grandpa/src/mock.rs | 4 +- srml/grandpa/src/tests.rs | 16 +- srml/im-online/src/mock.rs | 4 +- srml/im-online/src/tests.rs | 17 +- srml/indices/src/mock.rs | 4 +- srml/indices/src/tests.rs | 10 +- srml/membership/src/lib.rs | 18 +- srml/offences/src/mock.rs | 4 +- srml/offences/src/tests.rs | 16 +- srml/randomness-collective-flip/src/lib.rs | 18 +- srml/scored-pool/src/mock.rs | 4 +- srml/scored-pool/src/tests.rs | 35 ++-- srml/session/src/historical.rs | 13 +- srml/session/src/lib.rs | 28 ++- srml/staking/src/mock.rs | 6 +- srml/staking/src/tests.rs | 92 +++++---- srml/support/src/lib.rs | 23 ++- srml/support/src/storage/storage_items.rs | 16 +- srml/support/test/Cargo.toml | 2 + srml/support/test/tests/instance.rs | 14 +- srml/system/benches/bench.rs | 11 +- srml/system/src/lib.rs | 36 ++-- srml/timestamp/src/lib.rs | 13 +- srml/treasury/src/lib.rs | 40 ++-- srml/utility/src/lib.rs | 10 +- 95 files changed, 1600 insertions(+), 1420 deletions(-) create mode 100644 core/externalities/Cargo.toml create mode 100644 core/externalities/src/extensions.rs create mode 100644 core/externalities/src/lib.rs create mode 100644 core/externalities/src/scope_limited.rs delete mode 100644 core/primitives/src/child_storage_key.rs create mode 100644 core/primitives/storage/Cargo.toml rename core/primitives/{src/storage.rs => storage/src/lib.rs} (62%) diff --git a/Cargo.lock b/Cargo.lock index ba762f1393..a1f3ba2983 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3801,12 +3801,12 @@ dependencies = [ name = "sr-io" version = "2.0.0" dependencies = [ - "environmental 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "libsecp256k1 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", + "substrate-externalities 2.0.0", "substrate-primitives 2.0.0", "substrate-state-machine 2.0.0", "substrate-trie 2.0.0", @@ -3830,6 +3830,7 @@ dependencies = [ "sr-io 2.0.0", "sr-std 2.0.0", "substrate-application-crypto 2.0.0", + "substrate-externalities 2.0.0", "substrate-offchain 2.0.0", "substrate-primitives 2.0.0", ] @@ -4387,6 +4388,7 @@ dependencies = [ "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", + "sr-primitives 2.0.0", "srml-support 2.0.0", "substrate-inherents 2.0.0", "substrate-primitives 2.0.0", @@ -4974,6 +4976,7 @@ dependencies = [ "sr-io 2.0.0", "sr-version 2.0.0", "substrate-client 2.0.0", + "substrate-externalities 2.0.0", "substrate-offchain 2.0.0", "substrate-panic-handler 2.0.0", "substrate-primitives 2.0.0", @@ -4987,6 +4990,16 @@ dependencies = [ "wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "substrate-externalities" +version = "2.0.0" +dependencies = [ + "environmental 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-std 2.0.0", + "substrate-primitives-storage 2.0.0", +] + [[package]] name = "substrate-finality-grandpa" version = "2.0.0" @@ -5224,6 +5237,8 @@ dependencies = [ "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", "substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-externalities 2.0.0", + "substrate-primitives-storage 2.0.0", "substrate-serializer 2.0.0", "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "twox-hash 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5231,6 +5246,15 @@ dependencies = [ "zeroize 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "substrate-primitives-storage" +version = "2.0.0" +dependencies = [ + "impl-serde 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-std 2.0.0", +] + [[package]] name = "substrate-rpc" version = "2.0.0" @@ -5425,6 +5449,7 @@ dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-externalities 2.0.0", "substrate-panic-handler 2.0.0", "substrate-primitives 2.0.0", "substrate-trie 2.0.0", diff --git a/Cargo.toml b/Cargo.toml index 62993397fd..7e34a0bd6c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,7 @@ members = [ "core/consensus/pow", "core/executor", "core/executor/runtime-test", + "core/externalities", "core/finality-grandpa", "core/finality-grandpa/primitives", "core/inherents", diff --git a/core/application-crypto/src/ed25519.rs b/core/application-crypto/src/ed25519.rs index d5c4fd7bad..b0113718b5 100644 --- a/core/application-crypto/src/ed25519.rs +++ b/core/application-crypto/src/ed25519.rs @@ -53,14 +53,7 @@ impl RuntimePublic for Public { #[cfg(test)] mod tests { use sr_primitives::{generic::BlockId, traits::ProvideRuntimeApi}; - use primitives::{ - testing::{ - KeyStore, - ED25519, - }, - crypto::Pair, - traits::BareCryptoStore as _, - }; + use primitives::{testing::{KeyStore, ED25519}, crypto::Pair}; use test_client::{ TestClientBuilder, DefaultTestClientBuilderExt, TestClientBuilderExt, runtime::{TestAPI, app_crypto::ed25519::{AppPair, AppPublic}}, diff --git a/core/application-crypto/src/sr25519.rs b/core/application-crypto/src/sr25519.rs index 93565a628f..40f6c6b22e 100644 --- a/core/application-crypto/src/sr25519.rs +++ b/core/application-crypto/src/sr25519.rs @@ -53,14 +53,7 @@ impl RuntimePublic for Public { #[cfg(test)] mod tests { use sr_primitives::{generic::BlockId, traits::ProvideRuntimeApi}; - use primitives::{ - testing::{ - KeyStore, - SR25519, - }, - crypto::Pair, - traits::BareCryptoStore as _, - }; + use primitives::{testing::{KeyStore, SR25519}, crypto::Pair}; use test_client::{ TestClientBuilder, DefaultTestClientBuilderExt, TestClientBuilderExt, runtime::{TestAPI, app_crypto::sr25519::{AppPair, AppPublic}}, diff --git a/core/client/db/src/lib.rs b/core/client/db/src/lib.rs index 7061e9d29a..1f7fa604a4 100644 --- a/core/client/db/src/lib.rs +++ b/core/client/db/src/lib.rs @@ -224,7 +224,7 @@ pub fn new_client( > where Block: BlockT, - E: CodeExecutor + RuntimeInfo, + E: CodeExecutor + RuntimeInfo, S: BuildStorage, { let backend = Arc::new(Backend::new(settings, CANONICALIZATION_DELAY)?); @@ -456,8 +456,7 @@ impl BlockImportOperation { } impl client::backend::BlockImportOperation -for BlockImportOperation -where Block: BlockT, + for BlockImportOperation where Block: BlockT, { type State = CachingState, Block>; diff --git a/core/client/src/call_executor.rs b/core/client/src/call_executor.rs index ebb882709d..05a2a8eba1 100644 --- a/core/client/src/call_executor.rs +++ b/core/client/src/call_executor.rs @@ -26,8 +26,8 @@ use state_machine::{ use executor::{RuntimeVersion, RuntimeInfo, NativeVersion}; use hash_db::Hasher; use primitives::{ - offchain::{self, NeverOffchainExt}, H256, Blake2Hasher, NativeOrEncoded, NeverNativeValue, - traits::CodeExecutor, + offchain::OffchainExt, H256, Blake2Hasher, NativeOrEncoded, NeverNativeValue, + traits::{CodeExecutor, KeystoreExt}, }; use crate::runtime_api::{ProofRecorder, InitializeBlock}; @@ -47,15 +47,13 @@ where /// Execute a call to a contract on top of state in a block of given hash. /// /// No changes are made. - fn call< - O: offchain::Externalities, - >( + fn call( &self, id: &BlockId, method: &str, call_data: &[u8], strategy: ExecutionStrategy, - side_effects_handler: Option<&mut O>, + side_effects_handler: Option, ) -> Result, error::Error>; /// Execute a contextual call on top of state in a block of a given hash. @@ -65,7 +63,6 @@ where /// of the execution context. fn contextual_call< 'a, - O: offchain::Externalities, IB: Fn() -> error::Result<()>, EM: Fn( Result, Self::Error>, @@ -83,7 +80,7 @@ where initialize_block: InitializeBlock<'a, B>, execution_manager: ExecutionManager, native_call: Option, - side_effects_handler: Option<&mut O>, + side_effects_handler: Option, proof_recorder: &Option>>>, enable_keystore: bool, ) -> error::Result> where ExecutionManager: Clone; @@ -97,11 +94,10 @@ where /// /// No changes are made. fn call_at_state< - O: offchain::Externalities, S: state_machine::Backend, F: FnOnce( Result, Self::Error>, - Result, Self::Error> + Result, Self::Error>, ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, NC: FnOnce() -> result::Result + UnwindSafe, @@ -112,7 +108,7 @@ where call_data: &[u8], manager: ExecutionManager, native_call: Option, - side_effects_handler: Option<&mut O>, + side_effects_handler: Option, ) -> Result< ( NativeOrEncoded, @@ -191,18 +187,18 @@ impl Clone for LocalCallExecutor where E: Clone { impl CallExecutor for LocalCallExecutor where B: backend::Backend, - E: CodeExecutor + RuntimeInfo, + E: CodeExecutor + RuntimeInfo, Block: BlockT, { type Error = E::Error; - fn call( + fn call( &self, id: &BlockId, method: &str, call_data: &[u8], strategy: ExecutionStrategy, - side_effects_handler: Option<&mut O>, + side_effects_handler: Option, ) -> error::Result> { let mut changes = OverlayedChanges::default(); let state = self.backend.state_at(*id)?; @@ -214,7 +210,7 @@ where &self.executor, method, call_data, - self.keystore.clone(), + self.keystore.clone().map(KeystoreExt), ).execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>( strategy.get_manager(), false, @@ -227,7 +223,6 @@ where fn contextual_call< 'a, - O: offchain::Externalities, IB: Fn() -> error::Result<()>, EM: Fn( Result, Self::Error>, @@ -245,7 +240,7 @@ where initialize_block: InitializeBlock<'a, Block>, execution_manager: ExecutionManager, native_call: Option, - side_effects_handler: Option<&mut O>, + side_effects_handler: Option, recorder: &Option>>>, enable_keystore: bool, ) -> Result, error::Error> where ExecutionManager: Clone { @@ -259,7 +254,7 @@ where } let keystore = if enable_keystore { - self.keystore.clone() + self.keystore.clone().map(KeystoreExt) } else { None }; @@ -326,7 +321,6 @@ where &mut overlay, &state, self.backend.changes_trie_storage(), - NeverOffchainExt::new(), None, ); let version = self.executor.runtime_version(&mut ext); @@ -335,11 +329,10 @@ where } fn call_at_state< - O: offchain::Externalities, S: state_machine::Backend, F: FnOnce( Result, Self::Error>, - Result, Self::Error> + Result, Self::Error>, ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, NC: FnOnce() -> result::Result + UnwindSafe, @@ -350,7 +343,7 @@ where call_data: &[u8], manager: ExecutionManager, native_call: Option, - side_effects_handler: Option<&mut O>, + side_effects_handler: Option, ) -> error::Result<( NativeOrEncoded, (S::Transaction, ::Out), @@ -364,7 +357,7 @@ where &self.executor, method, call_data, - self.keystore.clone(), + self.keystore.clone().map(KeystoreExt), ).execute_using_consensus_failure_handler( manager, true, @@ -391,7 +384,7 @@ where &self.executor, method, call_data, - self.keystore.clone(), + self.keystore.clone().map(KeystoreExt), ) .map_err(Into::into) } diff --git a/core/client/src/client.rs b/core/client/src/client.rs index aff099233a..34334b1388 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -28,7 +28,7 @@ use hash_db::{Hasher, Prefix}; use primitives::{ Blake2Hasher, H256, ChangesTrieConfiguration, convert_hash, NeverNativeValue, ExecutionContext, NativeOrEncoded, storage::{StorageKey, StorageData, well_known_keys}, - offchain::{NeverOffchainExt, self}, traits::CodeExecutor, + offchain::{OffchainExt, self}, traits::CodeExecutor, }; use substrate_telemetry::{telemetry, SUBSTRATE_INFO}; use sr_primitives::{ @@ -248,7 +248,7 @@ pub fn new_in_mem( Block, RA >> where - E: CodeExecutor + RuntimeInfo, + E: CodeExecutor + RuntimeInfo, S: BuildStorage, Block: BlockT, { @@ -264,7 +264,7 @@ pub fn new_with_backend( keystore: Option, ) -> error::Result, Block, RA>> where - E: CodeExecutor + RuntimeInfo, + E: CodeExecutor + RuntimeInfo, S: BuildStorage, Block: BlockT, B: backend::LocalBackend @@ -1058,18 +1058,27 @@ impl Client where }), } }; - let (_, storage_update, changes_update) = self.executor.call_at_state::<_, _, _, NeverNativeValue, fn() -> _>( - transaction_state, - &mut overlay, - "Core_execute_block", - &::new(import_headers.pre().clone(), body.unwrap_or_default()).encode(), - match origin { - BlockOrigin::NetworkInitialSync => get_execution_manager(self.execution_strategies().syncing), - _ => get_execution_manager(self.execution_strategies().importing), - }, - None, - NeverOffchainExt::new(), - )?; + + let encoded_block = ::new( + import_headers.pre().clone(), + body.unwrap_or_default(), + ).encode(); + + let (_, storage_update, changes_update) = self.executor + .call_at_state::<_, _, NeverNativeValue, fn() -> _>( + transaction_state, + &mut overlay, + "Core_execute_block", + &encoded_block, + match origin { + BlockOrigin::NetworkInitialSync => get_execution_manager( + self.execution_strategies().syncing, + ), + _ => get_execution_manager(self.execution_strategies().importing), + }, + None, + None, + )?; overlay.commit_prospective(); @@ -1460,12 +1469,13 @@ impl CallRuntimeAt for Client where }; let capabilities = context.capabilities(); - let mut offchain_extensions = match context { - ExecutionContext::OffchainCall(ext) => ext.map(|x| x.0), - _ => None, - }.map(|ext| offchain::LimitedExternalities::new(capabilities, ext)); + let offchain_extensions = if let ExecutionContext::OffchainCall(Some(ext)) = context { + Some(OffchainExt::new(offchain::LimitedExternalities::new(capabilities, ext.0))) + } else { + None + }; - self.executor.contextual_call::<_, _, fn(_,_) -> _,_,_>( + self.executor.contextual_call::<_, fn(_,_) -> _,_,_>( || core_api.initialize_block(at, &self.prepare_environment_block(at)?), at, function, @@ -1474,7 +1484,7 @@ impl CallRuntimeAt for Client where initialize_block, manager, native_call, - offchain_extensions.as_mut(), + offchain_extensions, recorder, capabilities.has(offchain::Capability::Keystore), ) diff --git a/core/client/src/genesis.rs b/core/client/src/genesis.rs index 51e0536613..031b2dc0ad 100644 --- a/core/client/src/genesis.rs +++ b/core/client/src/genesis.rs @@ -53,7 +53,7 @@ mod tests { runtime::{Hash, Transfer, Block, BlockNumber, Header, Digest}, AccountKeyring, Sr25519Keyring, }; - use primitives::{Blake2Hasher, map, offchain::NeverOffchainExt}; + use primitives::{Blake2Hasher, map}; use hex_literal::*; native_executor_instance!( @@ -93,7 +93,7 @@ mod tests { StateMachine::new( backend, Some(&InMemoryChangesTrieStorage::<_, u64>::new()), - NeverOffchainExt::new(), + None, &mut overlay, &executor(), "Core_initialize_block", @@ -107,7 +107,7 @@ mod tests { StateMachine::new( backend, Some(&InMemoryChangesTrieStorage::<_, u64>::new()), - NeverOffchainExt::new(), + None, &mut overlay, &executor(), "BlockBuilder_apply_extrinsic", @@ -121,7 +121,7 @@ mod tests { let (ret_data, _, _) = StateMachine::new( backend, Some(&InMemoryChangesTrieStorage::<_, u64>::new()), - NeverOffchainExt::new(), + None, &mut overlay, &executor(), "BlockBuilder_finalize_block", @@ -169,7 +169,7 @@ mod tests { let _ = StateMachine::new( &backend, Some(&InMemoryChangesTrieStorage::<_, u64>::new()), - NeverOffchainExt::new(), + None, &mut overlay, &executor(), "Core_execute_block", @@ -199,7 +199,7 @@ mod tests { let _ = StateMachine::new( &backend, Some(&InMemoryChangesTrieStorage::<_, u64>::new()), - NeverOffchainExt::new(), + None, &mut overlay, &executor(), "Core_execute_block", @@ -229,7 +229,7 @@ mod tests { let r = StateMachine::new( &backend, Some(&InMemoryChangesTrieStorage::<_, u64>::new()), - NeverOffchainExt::new(), + None, &mut overlay, &executor(), "Core_execute_block", diff --git a/core/client/src/light/call_executor.rs b/core/client/src/light/call_executor.rs index d969c39a5a..65776bcfe0 100644 --- a/core/client/src/light/call_executor.rs +++ b/core/client/src/light/call_executor.rs @@ -23,11 +23,12 @@ use std::{ use codec::{Encode, Decode}; use primitives::{ - offchain, H256, Blake2Hasher, convert_hash, NativeOrEncoded, + offchain::OffchainExt, H256, Blake2Hasher, convert_hash, NativeOrEncoded, traits::CodeExecutor, }; -use sr_primitives::generic::BlockId; -use sr_primitives::traits::{One, Block as BlockT, Header as HeaderT, NumberFor}; +use sr_primitives::{ + generic::BlockId, traits::{One, Block as BlockT, Header as HeaderT, NumberFor}, +}; use state_machine::{ self, Backend as StateBackend, OverlayedChanges, ExecutionStrategy, create_proof_check_backend, execution_proof_check_on_trie_backend, ExecutionManager, ChangesTrieTransaction, @@ -74,15 +75,13 @@ impl CallExecutor for { type Error = ClientError; - fn call< - O: offchain::Externalities, - >( + fn call( &self, id: &BlockId, method: &str, call_data: &[u8], strategy: ExecutionStrategy, - side_effects_handler: Option<&mut O>, + side_effects_handler: Option, ) -> ClientResult> { match self.backend.is_local_state_available(id) { true => self.local.call(id, method, call_data, strategy, side_effects_handler), @@ -92,7 +91,6 @@ impl CallExecutor for fn contextual_call< 'a, - O: offchain::Externalities, IB: Fn() -> ClientResult<()>, EM: Fn( Result, Self::Error>, @@ -110,7 +108,7 @@ impl CallExecutor for initialize_block: InitializeBlock<'a, Block>, _manager: ExecutionManager, native_call: Option, - side_effects_handler: Option<&mut O>, + side_effects_handler: Option, recorder: &Option>>>, enable_keystore: bool, ) -> ClientResult> where ExecutionManager: Clone { @@ -119,7 +117,6 @@ impl CallExecutor for match self.backend.is_local_state_available(at) { true => CallExecutor::contextual_call::< - _, _, fn( Result, Local::Error>, @@ -153,7 +150,6 @@ impl CallExecutor for } fn call_at_state< - O: offchain::Externalities, S: StateBackend, FF: FnOnce( Result, Self::Error>, @@ -168,7 +164,7 @@ impl CallExecutor for _call_data: &[u8], _manager: ExecutionManager, _native_call: Option, - _side_effects_handler: Option<&mut O>, + _side_effects_handler: Option, ) -> ClientResult<( NativeOrEncoded, (S::Transaction, ::Out), @@ -242,11 +238,10 @@ pub fn check_execution_proof( ) -> ClientResult> where Header: HeaderT, - E: CodeExecutor, - H: Hasher, - H::Out: Ord + 'static, + E: CodeExecutor, + H: Hasher, { - check_execution_proof_with_make_header( + check_execution_proof_with_make_header::( executor, request, remote_proof, @@ -268,9 +263,8 @@ fn check_execution_proof_with_make_header ClientResult> where Header: HeaderT, - E: CodeExecutor, - H: Hasher, - H::Out: Ord + 'static, + E: CodeExecutor, + H: Hasher, { let local_state_root = request.header.state_root(); let root: H::Out = convert_hash(&local_state_root); @@ -301,33 +295,32 @@ fn check_execution_proof_with_make_header for DummyCallExecutor { type Error = ClientError; - fn call( + fn call( &self, _id: &BlockId, _method: &str, _call_data: &[u8], _strategy: ExecutionStrategy, - _side_effects_handler: Option<&mut O>, + _side_effects_handler: Option, ) -> Result, ClientError> { Ok(vec![42]) } fn contextual_call< 'a, - O: offchain::Externalities, IB: Fn() -> ClientResult<()>, EM: Fn( Result, Self::Error>, @@ -345,7 +338,7 @@ mod tests { _initialize_block: InitializeBlock<'a, Block>, _execution_manager: ExecutionManager, _native_call: Option, - _side_effects_handler: Option<&mut O>, + _side_effects_handler: Option, _proof_recorder: &Option>>>, _enable_keystore: bool, ) -> ClientResult> where ExecutionManager: Clone { @@ -357,7 +350,6 @@ mod tests { } fn call_at_state< - O: offchain::Externalities, S: state_machine::Backend, F: FnOnce( Result, Self::Error>, @@ -372,7 +364,7 @@ mod tests { _call_data: &[u8], _manager: ExecutionManager, _native_call: Option, - _side_effects_handler: Option<&mut O>, + _side_effects_handler: Option, ) -> Result< ( NativeOrEncoded, @@ -417,13 +409,17 @@ mod tests { ).unwrap(); // check remote execution proof locally - let local_result = check_execution_proof(&local_executor(), &RemoteCallRequest { - block: test_client::runtime::Hash::default(), - header: remote_header, - method: method.into(), - call_data: vec![], - retry_count: None, - }, remote_execution_proof).unwrap(); + let local_result = check_execution_proof::<_, _, Blake2Hasher>( + &local_executor(), + &RemoteCallRequest { + block: test_client::runtime::Hash::default(), + header: remote_header, + method: method.into(), + call_data: vec![], + retry_count: None, + }, + remote_execution_proof, + ).unwrap(); (remote_result, local_result) } @@ -440,7 +436,7 @@ mod tests { ).unwrap(); // check remote execution proof locally - let execution_result = check_execution_proof_with_make_header( + let execution_result = check_execution_proof_with_make_header::<_, _, Blake2Hasher, _>( &local_executor(), &RemoteCallRequest { block: test_client::runtime::Hash::default(), @@ -518,7 +514,7 @@ mod tests { "test_method", &[], ExecutionStrategy::NativeElseWasm, - NeverOffchainExt::new(), + None, ).unwrap(), vec![42], ); @@ -528,7 +524,7 @@ mod tests { "test_method", &[], ExecutionStrategy::NativeElseWasm, - NeverOffchainExt::new(), + None, ); match call_on_unavailable { diff --git a/core/client/src/light/fetcher.rs b/core/client/src/light/fetcher.rs index 51e1ed3b81..dbf6d41c38 100644 --- a/core/client/src/light/fetcher.rs +++ b/core/client/src/light/fetcher.rs @@ -23,7 +23,7 @@ use std::future::Future; use hash_db::{HashDB, Hasher, EMPTY_PREFIX}; use codec::{Decode, Encode}; -use primitives::{ChangesTrieConfiguration, convert_hash, traits::CodeExecutor}; +use primitives::{ChangesTrieConfiguration, convert_hash, traits::CodeExecutor, H256}; use sr_primitives::traits::{ Block as BlockT, Header as HeaderT, Hash, HashFor, NumberFor, SimpleArithmetic, CheckedConversion, Zero, @@ -370,9 +370,8 @@ impl> LightDataChecker { impl FetchChecker for LightDataChecker where Block: BlockT, - E: CodeExecutor, - H: Hasher, - H::Out: Ord + 'static, + E: CodeExecutor, + H: Hasher, S: BlockchainStorage, { fn check_header_proof( diff --git a/core/client/src/light/mod.rs b/core/client/src/light/mod.rs index c9d2e6040b..d06a9ae9dd 100644 --- a/core/client/src/light/mod.rs +++ b/core/client/src/light/mod.rs @@ -63,7 +63,7 @@ pub fn new_light( B: BlockT, S: BlockchainStorage + 'static, GS: BuildStorage, - E: CodeExecutor + RuntimeInfo, + E: CodeExecutor + RuntimeInfo, { let local_executor = LocalCallExecutor::new(backend.clone(), code_executor, None); let executor = GenesisCallExecutor::new(backend.clone(), local_executor); @@ -76,7 +76,7 @@ pub fn new_fetch_checker>( executor: E, ) -> LightDataChecker where - E: CodeExecutor, + E: CodeExecutor, { LightDataChecker::new(blockchain, executor) } diff --git a/core/executor/Cargo.toml b/core/executor/Cargo.toml index 1f53cd4099..cf3ea4ff7a 100644 --- a/core/executor/Cargo.toml +++ b/core/executor/Cargo.toml @@ -17,6 +17,7 @@ wasmi = "0.5.1" parity-wasm = "0.40.3" lazy_static = "1.4.0" wasm-interface = { package = "substrate-wasm-interface", path = "../wasm-interface" } +externalities = { package = "substrate-externalities", path = "../externalities" } parking_lot = "0.9.0" log = "0.4.8" libsecp256k1 = "0.3.0" diff --git a/core/executor/src/lib.rs b/core/executor/src/lib.rs index 8b833c9b08..ccc78afdb4 100644 --- a/core/executor/src/lib.rs +++ b/core/executor/src/lib.rs @@ -45,7 +45,7 @@ pub use native_executor::{with_native_environment, NativeExecutor, NativeExecuti pub use runtime_version::{RuntimeVersion, NativeVersion}; pub use codec::Codec; #[doc(hidden)] -pub use primitives::{Blake2Hasher, traits::Externalities}; +pub use primitives::traits::Externalities; #[doc(hidden)] pub use wasm_interface; pub use wasm_runtime::WasmExecutionMethod; @@ -56,7 +56,7 @@ pub trait RuntimeInfo { fn native_version(&self) -> &NativeVersion; /// Extract RuntimeVersion of given :code block - fn runtime_version> ( + fn runtime_version ( &self, ext: &mut E, ) -> Option; diff --git a/core/executor/src/native_executor.rs b/core/executor/src/native_executor.rs index 5f4e91b16d..7323703ed9 100644 --- a/core/executor/src/native_executor.rs +++ b/core/executor/src/native_executor.rs @@ -20,7 +20,7 @@ use crate::wasm_runtime::{RuntimesCache, WasmExecutionMethod, WasmRuntime}; use crate::RuntimeInfo; use runtime_version::{NativeVersion, RuntimeVersion}; use codec::{Decode, Encode}; -use primitives::{Blake2Hasher, NativeOrEncoded, traits::{CodeExecutor, Externalities}}; +use primitives::{NativeOrEncoded, traits::{CodeExecutor, Externalities}}; use log::{trace, warn}; thread_local! { @@ -41,10 +41,10 @@ fn safe_call(f: F) -> Result /// Set up the externalities and safe calling environment to execute calls to a native runtime. /// /// If the inner closure panics, it will be caught and return an error. -pub fn with_native_environment(ext: &mut dyn Externalities, f: F) -> Result +pub fn with_native_environment(ext: &mut dyn Externalities, f: F) -> Result where F: UnwindSafe + FnOnce() -> U { - runtime_io::with_externalities(ext, move || safe_call(f)) + externalities::set_and_run_with_externalities(ext, move || safe_call(f)) } /// Delegate for dispatching a CodeExecutor call. @@ -54,7 +54,7 @@ pub trait NativeExecutionDispatch: Send + Sync { /// Dispatch a method in the runtime. /// /// If the method with the specified name doesn't exist then `Err` is returned. - fn dispatch(ext: &mut dyn Externalities, method: &str, data: &[u8]) -> Result>; + fn dispatch(ext: &mut dyn Externalities, method: &str, data: &[u8]) -> Result>; /// Provide native runtime version. fn native_version() -> NativeVersion; @@ -95,10 +95,8 @@ impl NativeExecutor { fn with_runtime( &self, ext: &mut E, - f: impl for <'a> FnOnce(&'a mut dyn WasmRuntime, &'a mut E) -> Result - ) -> Result - where E: Externalities - { + f: impl for <'a> FnOnce(&'a mut dyn WasmRuntime, &'a mut E) -> Result, + ) -> Result where E: Externalities { RUNTIMES_CACHE.with(|cache| { let mut cache = cache.borrow_mut(); let runtime = cache.fetch_runtime(ext, self.fallback_method, self.default_heap_pages)?; @@ -123,7 +121,7 @@ impl RuntimeInfo for NativeExecutor { &self.native_version } - fn runtime_version>( + fn runtime_version( &self, ext: &mut E, ) -> Option { @@ -137,12 +135,12 @@ impl RuntimeInfo for NativeExecutor { } } -impl CodeExecutor for NativeExecutor { +impl CodeExecutor for NativeExecutor { type Error = Error; fn call < - E: Externalities, + E: Externalities, R:Decode + Encode + PartialEq, NC: FnOnce() -> result::Result + UnwindSafe >( @@ -220,7 +218,7 @@ macro_rules! native_executor_instance { (IMPL $name:ident, $dispatcher:path, $version:path) => { impl $crate::NativeExecutionDispatch for $name { fn dispatch( - ext: &mut $crate::Externalities<$crate::Blake2Hasher>, + ext: &mut $crate::Externalities, method: &str, data: &[u8] ) -> $crate::error::Result> { diff --git a/core/executor/src/sandbox.rs b/core/executor/src/sandbox.rs index de49cc9f7c..3a213ccdf0 100644 --- a/core/executor/src/sandbox.rs +++ b/core/executor/src/sandbox.rs @@ -593,9 +593,9 @@ mod tests { use wabt; use runtime_test::WASM_BINARY; - type TestExternalities = CoreTestExternalities; + type TestExternalities = CoreTestExternalities; - fn call_wasm>( + fn call_wasm( ext: &mut E, heap_pages: u64, code: &[u8], @@ -609,7 +609,7 @@ mod tests { #[test] fn sandbox_should_work() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -641,7 +641,7 @@ mod tests { #[test] fn sandbox_trap() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -662,7 +662,7 @@ mod tests { #[test] fn sandbox_should_trap_when_heap_exhausted() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -690,7 +690,7 @@ mod tests { #[test] fn start_called() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -728,7 +728,7 @@ mod tests { #[test] fn invoke_args() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -762,7 +762,7 @@ mod tests { #[test] fn return_val() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -784,7 +784,7 @@ mod tests { #[test] fn unlinkable_module() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -804,7 +804,7 @@ mod tests { #[test] fn corrupted_module() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); let test_code = WASM_BINARY; // Corrupted wasm file @@ -818,7 +818,7 @@ mod tests { #[test] fn start_fn_ok() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -841,7 +841,7 @@ mod tests { #[test] fn start_fn_traps() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" diff --git a/core/executor/src/wasm_runtime.rs b/core/executor/src/wasm_runtime.rs index 27b65d6551..d88ae7b9ed 100644 --- a/core/executor/src/wasm_runtime.rs +++ b/core/executor/src/wasm_runtime.rs @@ -23,7 +23,7 @@ use crate::error::{Error, WasmError}; use crate::wasmi_execution; use log::{trace, warn}; use codec::Decode; -use primitives::{storage::well_known_keys, Blake2Hasher, traits::Externalities}; +use primitives::{storage::well_known_keys, traits::Externalities}; use runtime_version::RuntimeVersion; use std::{collections::hash_map::{Entry, HashMap}}; @@ -36,8 +36,8 @@ pub trait WasmRuntime { fn update_heap_pages(&mut self, heap_pages: u64) -> bool; /// Call a method in the Substrate runtime by name. Returns the encoded result on success. - fn call(&mut self, ext: &mut dyn Externalities, method: &str, data: &[u8]) - -> Result, Error>; + fn call(&mut self, ext: &mut dyn Externalities, method: &str, data: &[u8]) + -> Result, Error>; /// Returns the version of this runtime. /// @@ -109,7 +109,7 @@ impl RuntimesCache { /// /// `Error::InvalidMemoryReference` is returned if no memory export with the /// identifier `memory` can be found in the runtime. - pub fn fetch_runtime>( + pub fn fetch_runtime( &mut self, ext: &mut E, wasm_method: WasmExecutionMethod, @@ -157,7 +157,7 @@ impl RuntimesCache { } } -fn create_wasm_runtime>( +fn create_wasm_runtime( ext: &mut E, wasm_method: WasmExecutionMethod, heap_pages: u64, diff --git a/core/executor/src/wasmi_execution.rs b/core/executor/src/wasmi_execution.rs index e228372bd3..0719ff4d40 100644 --- a/core/executor/src/wasmi_execution.rs +++ b/core/executor/src/wasmi_execution.rs @@ -23,7 +23,7 @@ use wasmi::{ }; use crate::error::{Error, WasmError}; use codec::{Encode, Decode}; -use primitives::{sandbox as sandbox_primitives, Blake2Hasher, traits::Externalities}; +use primitives::{sandbox as sandbox_primitives, traits::Externalities}; use crate::host_interface::SubstrateExternals; use crate::sandbox; use crate::allocator; @@ -342,7 +342,7 @@ fn get_heap_base(module: &ModuleRef) -> Result { /// Call a given method in the given wasm-module runtime. fn call_in_wasm_module( - ext: &mut dyn Externalities, + ext: &mut dyn Externalities, module_instance: &ModuleRef, method: &str, data: &[u8], @@ -373,7 +373,7 @@ fn call_in_wasm_module_with_custom_signature< FR: FnOnce(Option, &MemoryRef) -> Result, Error>, R, >( - ext: &mut dyn Externalities, + ext: &mut dyn Externalities, module_instance: &ModuleRef, method: &str, create_parameters: F, @@ -398,7 +398,7 @@ fn call_in_wasm_module_with_custom_signature< fec.write_memory(offset, data).map(|_| offset.into()).map_err(Into::into) })?; - let result = runtime_io::with_externalities( + let result = externalities::set_and_run_with_externalities( ext, || module_instance.invoke_export(method, ¶meters, &mut fec), ); @@ -588,7 +588,7 @@ impl WasmRuntime for WasmiRuntime { self.state_snapshot.heap_pages == heap_pages } - fn call(&mut self, ext: &mut dyn Externalities, method: &str, data: &[u8]) + fn call(&mut self, ext: &mut dyn Externalities, method: &str, data: &[u8]) -> Result, Error> { self.with(|module| { @@ -601,7 +601,7 @@ impl WasmRuntime for WasmiRuntime { } } -pub fn create_instance>(ext: &mut E, code: &[u8], heap_pages: u64) +pub fn create_instance(ext: &mut E, code: &[u8], heap_pages: u64) -> Result { let module = Module::from_buffer(&code).map_err(|_| WasmError::InvalidModule)?; @@ -656,14 +656,16 @@ mod tests { use state_machine::TestExternalities as CoreTestExternalities; use hex_literal::hex; - use primitives::{blake2_128, blake2_256, ed25519, sr25519, map, Pair}; + use primitives::{ + Blake2Hasher, blake2_128, blake2_256, ed25519, sr25519, map, Pair, offchain::OffchainExt, + }; use runtime_test::WASM_BINARY; use substrate_offchain::testing; use trie::{TrieConfiguration, trie_types::Layout}; - type TestExternalities = CoreTestExternalities; + type TestExternalities = CoreTestExternalities; - fn call>( + fn call( ext: &mut E, heap_pages: u64, code: &[u8], @@ -798,7 +800,7 @@ mod tests { #[test] fn ed25519_verify_should_work() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); let test_code = WASM_BINARY; let key = ed25519::Pair::from_seed(&blake2_256(b"test")); let sig = key.sign(b"all ok!"); @@ -824,7 +826,7 @@ mod tests { #[test] fn sr25519_verify_should_work() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); let test_code = WASM_BINARY; let key = sr25519::Pair::from_seed(&blake2_256(b"test")); let sig = key.sign(b"all ok!"); @@ -850,7 +852,7 @@ mod tests { #[test] fn ordered_trie_root_should_work() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); let trie_input = vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()]; let test_code = WASM_BINARY; assert_eq!( @@ -863,9 +865,9 @@ mod tests { fn offchain_local_storage_should_work() { use substrate_client::backend::OffchainStorage; - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); let (offchain, state) = testing::TestOffchainExt::new(); - ext.set_offchain_externalities(offchain); + ext.register_extension(OffchainExt::new(offchain)); let test_code = WASM_BINARY; assert_eq!( call(&mut ext, 8, &test_code[..], "test_offchain_local_storage", &[]).unwrap(), @@ -876,9 +878,9 @@ mod tests { #[test] fn offchain_http_should_work() { - let mut ext = TestExternalities::::default(); + let mut ext = TestExternalities::default(); let (offchain, state) = testing::TestOffchainExt::new(); - ext.set_offchain_externalities(offchain); + ext.register_extension(OffchainExt::new(offchain)); state.write().expect_request( 0, testing::PendingRequest { diff --git a/core/externalities/Cargo.toml b/core/externalities/Cargo.toml new file mode 100644 index 0000000000..97ece5439a --- /dev/null +++ b/core/externalities/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "substrate-externalities" +version = "2.0.0" +license = "GPL-3.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +primitive-types = { version = "0.5.1", features = ["codec"] } +primitives-storage = { package = "substrate-primitives-storage", path = "../primitives/storage" } +rstd = { package = "sr-std", path = "../sr-std" } +environmental = { version = "1.0.2" } diff --git a/core/externalities/src/extensions.rs b/core/externalities/src/extensions.rs new file mode 100644 index 0000000000..c7d7bc4853 --- /dev/null +++ b/core/externalities/src/extensions.rs @@ -0,0 +1,127 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Externalities extensions storage. +//! +//! Externalities support to register a wide variety custom extensions. The [`Extensions`] provides +//! some convenience functionality to store and retrieve these extensions. +//! +//! It is required that each extension implements the [`Extension`] trait. + +use std::{collections::HashMap, any::{Any, TypeId}, ops::DerefMut}; + +/// Marker trait for types that should be registered as [`Externalities`](crate::Externalities) extension. +/// +/// As extensions are stored as `Box`, this trait should give more confidence that the correct +/// type is registered and requested. +pub trait Extension: Sized {} + +/// Macro for declaring an extension that usable with [`Extensions`]. +/// +/// The extension will be an unit wrapper struct that implements [`Extension`], `Deref` and +/// `DerefMut`. The wrapped type is given by the user. +/// +/// # Example +/// ``` +/// # use substrate_externalities::decl_extension; +/// decl_extension! { +/// /// Some test extension +/// struct TestExt(String); +/// } +/// ``` +#[macro_export] +macro_rules! decl_extension { + ( + $( #[ $attr:meta ] )* + $vis:vis struct $ext_name:ident ($inner:ty); + ) => { + $( #[ $attr ] )* + $vis struct $ext_name (pub $inner); + + impl $crate::Extension for $ext_name {} + + impl std::ops::Deref for $ext_name { + type Target = $inner; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } + + impl std::ops::DerefMut for $ext_name { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + } +} + +/// Something that provides access to the [`Extensions`] store. +/// +/// This is a super trait of the [`Externalities`](crate::Externalities). +pub trait ExtensionStore { + /// Tries to find a registered extension by the given `type_id` and returns it as a `&mut dyn Any`. + /// + /// It is advised to use [`ExternalitiesExt::extension`](crate::ExternalitiesExt::extension) + /// instead of this function to get type system support and automatic type downcasting. + fn extension_by_type_id(&mut self, type_id: TypeId) -> Option<&mut dyn Any>; +} + +/// Stores extensions that should be made available through the externalities. +#[derive(Default)] +pub struct Extensions { + extensions: HashMap>, +} + +impl Extensions { + /// Create new instance of `Self`. + pub fn new() -> Self { + Self::default() + } + + /// Register the given extension. + pub fn register(&mut self, ext: E) { + self.extensions.insert(ext.type_id(), Box::new(ext)); + } + + /// Return a mutable reference to the requested extension. + pub fn get_mut(&mut self, ext_type_id: TypeId) -> Option<&mut dyn Any> { + self.extensions.get_mut(&ext_type_id).map(DerefMut::deref_mut) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + struct DummyExt(u32); + impl Extension for DummyExt {} + + struct DummyExt2(u32); + impl Extension for DummyExt2 {} + + #[test] + fn register_and_retrieve_extension() { + let mut exts = Extensions::new(); + exts.register(DummyExt(1)); + exts.register(DummyExt2(2)); + + let ext = exts.get_mut(TypeId::of::()).expect("Extension is registered"); + let ext_ty = ext.downcast_mut::().expect("Downcasting works"); + + assert_eq!(ext_ty.0, 1); + } +} diff --git a/core/externalities/src/lib.rs b/core/externalities/src/lib.rs new file mode 100644 index 0000000000..ecd5f7a7a7 --- /dev/null +++ b/core/externalities/src/lib.rs @@ -0,0 +1,139 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Substrate externalities abstraction +//! +//! The externalities mainly provide access to storage and to registered extensions. Extensions +//! are for example the keystore or the offchain externalities. These externalities are used to +//! access the node from the runtime via the runtime interfaces. +//! +//! This crate exposes the main [`Externalities`] trait. + +use primitive_types::H256; + +use std::any::{Any, TypeId}; + +use primitives_storage::ChildStorageKey; + +pub use scope_limited::{set_and_run_with_externalities, with_externalities}; +pub use extensions::{Extension, Extensions, ExtensionStore}; + +mod extensions; +mod scope_limited; + +/// The Substrate externalities. +/// +/// Provides access to the storage and to other registered extensions. +pub trait Externalities: ExtensionStore { + /// Read runtime storage. + fn storage(&self, key: &[u8]) -> Option>; + + /// Get storage value hash. This may be optimized for large values. + fn storage_hash(&self, key: &[u8]) -> Option; + + /// Get child storage value hash. This may be optimized for large values. + fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option; + + /// Read original runtime storage, ignoring any overlayed changes. + fn original_storage(&self, key: &[u8]) -> Option>; + + /// Read original runtime child storage, ignoring any overlayed changes. + fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option>; + + /// Get original storage value hash, ignoring any overlayed changes. + /// This may be optimized for large values. + fn original_storage_hash(&self, key: &[u8]) -> Option; + + /// Get original child storage value hash, ignoring any overlayed changes. + /// This may be optimized for large values. + fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option; + + /// Read child runtime storage. + fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option>; + + /// Set storage entry `key` of current contract being called (effective immediately). + fn set_storage(&mut self, key: Vec, value: Vec) { + self.place_storage(key, Some(value)); + } + + /// Set child storage entry `key` of current contract being called (effective immediately). + fn set_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Vec) { + self.place_child_storage(storage_key, key, Some(value)) + } + + /// Clear a storage entry (`key`) of current contract being called (effective immediately). + fn clear_storage(&mut self, key: &[u8]) { + self.place_storage(key.to_vec(), None); + } + + /// Clear a child storage entry (`key`) of current contract being called (effective immediately). + fn clear_child_storage(&mut self, storage_key: ChildStorageKey, key: &[u8]) { + self.place_child_storage(storage_key, key.to_vec(), None) + } + + /// Whether a storage entry exists. + fn exists_storage(&self, key: &[u8]) -> bool { + self.storage(key).is_some() + } + + /// Whether a child storage entry exists. + fn exists_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> bool { + self.child_storage(storage_key, key).is_some() + } + + /// Clear an entire child storage. + fn kill_child_storage(&mut self, storage_key: ChildStorageKey); + + /// Clear storage entries which keys are start with the given prefix. + fn clear_prefix(&mut self, prefix: &[u8]); + + /// Clear child storage entries which keys are start with the given prefix. + fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]); + + /// Set or clear a storage entry (`key`) of current contract being called (effective immediately). + fn place_storage(&mut self, key: Vec, value: Option>); + + /// Set or clear a child storage entry. Return whether the operation succeeds. + fn place_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Option>); + + /// Get the identity of the chain. + fn chain_id(&self) -> u64; + + /// Get the trie root of the current storage map. This will also update all child storage keys + /// in the top-level storage map. + fn storage_root(&mut self) -> H256; + + /// Get the trie root of a child storage map. This will also update the value of the child + /// storage keys in the top-level storage map. + /// If the storage root equals the default hash as defined by the trie, the key in the top-level + /// storage map will be removed. + fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec; + + /// Get the change trie root of the current storage overlay at a block with given parent. + fn storage_changes_root(&mut self, parent: H256) -> Result, ()>; +} + +/// Extension for the [`Externalities`] trait. +pub trait ExternalitiesExt { + /// Tries to find a registered extension and returns a mutable reference. + fn extension(&mut self) -> Option<&mut T>; +} + +impl ExternalitiesExt for T { + fn extension(&mut self) -> Option<&mut A> { + self.extension_by_type_id(TypeId::of::()).and_then(Any::downcast_mut) + } +} diff --git a/core/externalities/src/scope_limited.rs b/core/externalities/src/scope_limited.rs new file mode 100644 index 0000000000..ae185449be --- /dev/null +++ b/core/externalities/src/scope_limited.rs @@ -0,0 +1,37 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Stores the externalities in an `environmental` value to make it scope limited available. + +use crate::Externalities; + +environmental::environmental!(ext: trait Externalities); + +/// Set the given externalities while executing the given closure. To get access to the externalities +/// while executing the given closure [`with_externalities`] grants access to them. The externalities +/// are only set for the same thread this function was called from. +pub fn set_and_run_with_externalities(ext: &mut dyn Externalities, f: F) -> R + where F: FnOnce() -> R +{ + ext::using(ext, f) +} + +/// Execute the given closure with the currently set externalities. +/// +/// Returns `None` if no externalities are set or `Some(_)` with the result of the closure. +pub fn with_externalities R, R>(f: F) -> Option { + ext::with(f) +} diff --git a/core/finality-grandpa/src/finality_proof.rs b/core/finality-grandpa/src/finality_proof.rs index bae6c8ebc0..da5732f2f6 100644 --- a/core/finality-grandpa/src/finality_proof.rs +++ b/core/finality-grandpa/src/finality_proof.rs @@ -48,7 +48,7 @@ use sr_primitives::{ Justification, generic::BlockId, traits::{NumberFor, Block as BlockT, Header as HeaderT, One}, }; -use primitives::{H256, Blake2Hasher, offchain::NeverOffchainExt}; +use primitives::{H256, Blake2Hasher}; use substrate_telemetry::{telemetry, CONSENSUS_INFO}; use fg_primitives::AuthorityId; @@ -78,7 +78,7 @@ impl, RA> AuthoritySetForFinalityProver fo "GrandpaApi_grandpa_authorities", &[], ExecutionStrategy::NativeElseWasm, - NeverOffchainExt::new(), + None, ).and_then(|call_result| Decode::decode(&mut &call_result[..]) .map_err(|err| ClientError::CallResultDecode( "failed to decode GRANDPA authorities set proof".into(), err diff --git a/core/primitives/Cargo.toml b/core/primitives/Cargo.toml index 461a8fe7e3..a527f16c1c 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -31,6 +31,8 @@ num-traits = { version = "0.2.8", default-features = false } zeroize = "0.10.1" lazy_static = { version = "1.4.0", optional = true } parking_lot = { version = "0.9.0", optional = true } +externalities = { package = "substrate-externalities", path = "../externalities", optional = true } +primitives-storage = { package = "substrate-primitives-storage", path = "storage", default-features = false } [dev-dependencies] substrate-serializer = { path = "../serializer" } @@ -52,7 +54,7 @@ std = [ "log", "wasmi", "lazy_static", - "parking_lot", + "parking_lot", "primitive-types/std", "primitive-types/serde", "primitive-types/byteorder", @@ -79,4 +81,6 @@ std = [ "schnorrkel", "regex", "num-traits/std", + "externalities", + "primitives-storage/std", ] diff --git a/core/primitives/src/child_storage_key.rs b/core/primitives/src/child_storage_key.rs deleted file mode 100644 index eba34c1ef9..0000000000 --- a/core/primitives/src/child_storage_key.rs +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Provides a wrapper around a child storage key. - -use crate::storage::well_known_keys::is_child_trie_key_valid; -use rstd::{borrow::Cow, vec::Vec}; - -/// A wrapper around a child storage key. -/// -/// This wrapper ensures that the child storage key is correct and properly used. It is -/// impossible to create an instance of this struct without providing a correct `storage_key`. -pub struct ChildStorageKey<'a> { - storage_key: Cow<'a, [u8]>, -} - -impl<'a> ChildStorageKey<'a> { - fn new(storage_key: Cow<'a, [u8]>) -> Option { - if is_child_trie_key_valid(&storage_key) { - Some(ChildStorageKey { storage_key }) - } else { - None - } - } - - /// Create a new `ChildStorageKey` from a vector. - /// - /// `storage_key` need to start with `:child_storage:default:` - /// See `is_child_trie_key_valid` for more details. - pub fn from_vec(key: Vec) -> Option { - Self::new(Cow::Owned(key)) - } - - /// Create a new `ChildStorageKey` from a slice. - /// - /// `storage_key` need to start with `:child_storage:default:` - /// See `is_child_trie_key_valid` for more details. - pub fn from_slice(key: &'a [u8]) -> Option { - Self::new(Cow::Borrowed(key)) - } - - /// Get access to the byte representation of the storage key. - /// - /// This key is guaranteed to be correct. - pub fn as_ref(&self) -> &[u8] { - &*self.storage_key - } - - /// Destruct this instance into an owned vector that represents the storage key. - /// - /// This key is guaranteed to be correct. - pub fn into_owned(self) -> Vec { - self.storage_key.into_owned() - } -} diff --git a/core/primitives/src/lib.rs b/core/primitives/src/lib.rs index 310f0133ef..b1ce6e2f97 100644 --- a/core/primitives/src/lib.rs +++ b/core/primitives/src/lib.rs @@ -54,16 +54,15 @@ pub mod crypto; pub mod u32_trait; -pub mod child_storage_key; pub mod ed25519; pub mod sr25519; pub mod hash; mod hasher; pub mod offchain; pub mod sandbox; -pub mod storage; pub mod uint; mod changes_trie; +#[cfg(feature = "std")] pub mod traits; pub mod testing; @@ -81,6 +80,8 @@ pub use hash_db::Hasher; // pub use self::hasher::blake::BlakeHasher; pub use self::hasher::blake2::Blake2Hasher; +pub use primitives_storage as storage; + /// Context for executing a call into the runtime. pub enum ExecutionContext { /// Context for general importing (including own blocks). diff --git a/core/primitives/src/offchain.rs b/core/primitives/src/offchain.rs index 6403a20dbd..84fee530f6 100644 --- a/core/primitives/src/offchain.rs +++ b/core/primitives/src/offchain.rs @@ -17,8 +17,7 @@ //! Offchain workers types use codec::{Encode, Decode}; -use rstd::prelude::{Vec, Box}; -use rstd::convert::TryFrom; +use rstd::{prelude::{Vec, Box}, convert::TryFrom}; pub use crate::crypto::KeyTypeId; @@ -663,110 +662,17 @@ impl Externalities for LimitedExternalities { } } -/// An implementation of offchain extensions that should never be triggered. -pub enum NeverOffchainExt {} - -impl NeverOffchainExt { - /// Create new offchain extensions. - pub fn new<'a>() -> Option<&'a mut Self> { - None - } +#[cfg(feature = "std")] +externalities::decl_extension! { + /// The offchain extension that will be registered at the Substrate externalities. + pub struct OffchainExt(Box); } -impl Externalities for NeverOffchainExt { - fn is_validator(&self) -> bool { - unreachable!() - } - - fn submit_transaction(&mut self, _extrinsic: Vec) -> Result<(), ()> { - unreachable!() - } - - fn network_state( - &self, - ) -> Result { - unreachable!() - } - - fn timestamp(&mut self) -> Timestamp { - unreachable!() - } - - fn sleep_until(&mut self, _deadline: Timestamp) { - unreachable!() - } - - fn random_seed(&mut self) -> [u8; 32] { - unreachable!() - } - - fn local_storage_set(&mut self, _kind: StorageKind, _key: &[u8], _value: &[u8]) { - unreachable!() - } - - fn local_storage_compare_and_set( - &mut self, - _kind: StorageKind, - _key: &[u8], - _old_value: Option<&[u8]>, - _new_value: &[u8], - ) -> bool { - unreachable!() - } - - fn local_storage_get(&mut self, _kind: StorageKind, _key: &[u8]) -> Option> { - unreachable!() - } - - fn http_request_start( - &mut self, - _method: &str, - _uri: &str, - _meta: &[u8] - ) -> Result { - unreachable!() - } - - fn http_request_add_header( - &mut self, - _request_id: HttpRequestId, - _name: &str, - _value: &str - ) -> Result<(), ()> { - unreachable!() - } - - fn http_request_write_body( - &mut self, - _request_id: HttpRequestId, - _chunk: &[u8], - _deadline: Option - ) -> Result<(), HttpError> { - unreachable!() - } - - fn http_response_wait( - &mut self, - _ids: &[HttpRequestId], - _deadline: Option - ) -> Vec { - unreachable!() - } - - fn http_response_headers( - &mut self, - _request_id: HttpRequestId - ) -> Vec<(Vec, Vec)> { - unreachable!() - } - - fn http_response_read_body( - &mut self, - _request_id: HttpRequestId, - _buffer: &mut [u8], - _deadline: Option - ) -> Result { - unreachable!() +#[cfg(feature = "std")] +impl OffchainExt { + /// Create a new instance of `Self`. + pub fn new(offchain: O) -> Self { + Self(Box::new(offchain)) } } diff --git a/core/primitives/src/testing.rs b/core/primitives/src/testing.rs index ccfc36af73..7fdefd8fe0 100644 --- a/core/primitives/src/testing.rs +++ b/core/primitives/src/testing.rs @@ -18,8 +18,7 @@ #[cfg(feature = "std")] use crate::{ed25519, sr25519, crypto::{Public, Pair}}; -use crate::crypto::KeyTypeId; // No idea why this import had to move from - // the previous line, but now the compiler is happy +use crate::crypto::KeyTypeId; /// Key type for generic Ed25519 key. pub const ED25519: KeyTypeId = KeyTypeId(*b"ed25"); @@ -37,7 +36,7 @@ pub struct KeyStore { #[cfg(feature = "std")] impl KeyStore { /// Creates a new instance of `Self`. - pub fn new() -> std::sync::Arc> { + pub fn new() -> crate::traits::BareCryptoStorePtr { std::sync::Arc::new(parking_lot::RwLock::new(Self::default())) } } @@ -133,7 +132,7 @@ impl crate::traits::BareCryptoStore for KeyStore { #[cfg(test)] mod tests { use super::*; - use crate::{sr25519, traits::BareCryptoStore}; + use crate::sr25519; use crate::testing::{ED25519, SR25519}; diff --git a/core/primitives/src/traits.rs b/core/primitives/src/traits.rs index b173d8512c..1ef665032e 100644 --- a/core/primitives/src/traits.rs +++ b/core/primitives/src/traits.rs @@ -16,15 +16,13 @@ //! Shareable Substrate traits. -#[cfg(feature = "std")] -use crate::{crypto::KeyTypeId, ed25519, sr25519, child_storage_key::ChildStorageKey}; -#[cfg(feature = "std")] +use crate::{crypto::KeyTypeId, ed25519, sr25519}; + use std::{fmt::{Debug, Display}, panic::UnwindSafe}; -#[cfg(feature = "std")] -use hash_db::Hasher; + +pub use externalities::{Externalities, ExternalitiesExt}; /// Something that generates, stores and provides access to keys. -#[cfg(feature = "std")] pub trait BareCryptoStore: Send + Sync { /// Returns all sr25519 public keys for the given key type. fn sr25519_public_keys(&self, id: KeyTypeId) -> Vec; @@ -70,128 +68,22 @@ pub trait BareCryptoStore: Send + Sync { } /// A pointer to the key store. -#[cfg(feature = "std")] pub type BareCryptoStorePtr = std::sync::Arc>; -/// Externalities: pinned to specific active address. -#[cfg(feature = "std")] -pub trait Externalities { - /// Read runtime storage. - fn storage(&self, key: &[u8]) -> Option>; - - /// Get storage value hash. This may be optimized for large values. - fn storage_hash(&self, key: &[u8]) -> Option { - self.storage(key).map(|v| H::hash(&v)) - } - - /// Get child storage value hash. This may be optimized for large values. - fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { - self.child_storage(storage_key, key).map(|v| H::hash(&v)) - } - - /// Read original runtime storage, ignoring any overlayed changes. - fn original_storage(&self, key: &[u8]) -> Option>; - - /// Read original runtime child storage, ignoring any overlayed changes. - fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option>; - - /// Get original storage value hash, ignoring any overlayed changes. - /// This may be optimized for large values. - fn original_storage_hash(&self, key: &[u8]) -> Option { - self.original_storage(key).map(|v| H::hash(&v)) - } - - /// Get original child storage value hash, ignoring any overlayed changes. - /// This may be optimized for large values. - fn original_child_storage_hash( - &self, - storage_key: ChildStorageKey, - key: &[u8], - ) -> Option { - self.original_child_storage(storage_key, key).map(|v| H::hash(&v)) - } - - /// Read child runtime storage. - fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option>; - - /// Set storage entry `key` of current contract being called (effective immediately). - fn set_storage(&mut self, key: Vec, value: Vec) { - self.place_storage(key, Some(value)); - } - - /// Set child storage entry `key` of current contract being called (effective immediately). - fn set_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Vec) { - self.place_child_storage(storage_key, key, Some(value)) - } - - /// Clear a storage entry (`key`) of current contract being called (effective immediately). - fn clear_storage(&mut self, key: &[u8]) { - self.place_storage(key.to_vec(), None); - } - - /// Clear a child storage entry (`key`) of current contract being called (effective immediately). - fn clear_child_storage(&mut self, storage_key: ChildStorageKey, key: &[u8]) { - self.place_child_storage(storage_key, key.to_vec(), None) - } - - /// Whether a storage entry exists. - fn exists_storage(&self, key: &[u8]) -> bool { - self.storage(key).is_some() - } - - /// Whether a child storage entry exists. - fn exists_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> bool { - self.child_storage(storage_key, key).is_some() - } - - /// Clear an entire child storage. - fn kill_child_storage(&mut self, storage_key: ChildStorageKey); - - /// Clear storage entries which keys are start with the given prefix. - fn clear_prefix(&mut self, prefix: &[u8]); - - /// Clear child storage entries which keys are start with the given prefix. - fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]); - - /// Set or clear a storage entry (`key`) of current contract being called (effective immediately). - fn place_storage(&mut self, key: Vec, value: Option>); - - /// Set or clear a child storage entry. Return whether the operation succeeds. - fn place_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Option>); - - /// Get the identity of the chain. - fn chain_id(&self) -> u64; - - /// Get the trie root of the current storage map. This will also update all child storage keys - /// in the top-level storage map. - fn storage_root(&mut self) -> H::Out where H::Out: Ord; - - /// Get the trie root of a child storage map. This will also update the value of the child - /// storage keys in the top-level storage map. - /// If the storage root equals the default hash as defined by the trie, the key in the top-level - /// storage map will be removed. - fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec; - - /// Get the change trie root of the current storage overlay at a block with given parent. - fn storage_changes_root(&mut self, parent: H::Out) -> Result, ()> where H::Out: Ord; - - /// Returns offchain externalities extension if present. - fn offchain(&mut self) -> Option<&mut dyn crate::offchain::Externalities>; - - /// Returns the keystore. - fn keystore(&self) -> Option; +externalities::decl_extension! { + /// The keystore extension to register/retrieve from the externalities. + pub struct KeystoreExt(BareCryptoStorePtr); } /// Code execution engine. -#[cfg(feature = "std")] -pub trait CodeExecutor: Sized + Send + Sync { +pub trait CodeExecutor: Sized + Send + Sync { /// Externalities error type. type Error: Display + Debug + Send + 'static; /// Call a given method in the runtime. Returns a tuple of the result (either the output data /// or an execution error) together with a `bool`, which is true if native execution was used. fn call< - E: Externalities, + E: Externalities, R: codec::Codec + PartialEq, NC: FnOnce() -> Result + UnwindSafe, >( diff --git a/core/primitives/storage/Cargo.toml b/core/primitives/storage/Cargo.toml new file mode 100644 index 0000000000..5b1ed37d6a --- /dev/null +++ b/core/primitives/storage/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "substrate-primitives-storage" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" +description = "Storage related primitives" + +[dependencies] +rstd = { package = "sr-std", path = "../../sr-std", default-features = false } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +impl-serde = { version = "0.2.1", optional = true } + +[features] +default = [ "std" ] +std = [ "rstd/std", "serde", "impl-serde" ] diff --git a/core/primitives/src/storage.rs b/core/primitives/storage/src/lib.rs similarity index 62% rename from core/primitives/src/storage.rs rename to core/primitives/storage/src/lib.rs index 14c49bfaa9..334779ed5f 100644 --- a/core/primitives/src/storage.rs +++ b/core/primitives/storage/src/lib.rs @@ -14,23 +14,30 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Contract execution data. +//! Primitive types for storage related stuff. + +#![cfg_attr(not(feature = "std"), no_std)] #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; -#[cfg(feature = "std")] -use crate::bytes; -use rstd::vec::Vec; -/// Contract storage key. +use rstd::{vec::Vec, borrow::Cow}; + +/// Storage key. #[derive(PartialEq, Eq)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Hash, PartialOrd, Ord, Clone))] -pub struct StorageKey(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec); +pub struct StorageKey( + #[cfg_attr(feature = "std", serde(with="impl_serde::serialize"))] + pub Vec, +); -/// Contract storage entry data. +/// Storage data associated to a [`StorageKey`]. #[derive(PartialEq, Eq)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Hash, PartialOrd, Ord, Clone))] -pub struct StorageData(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec); +pub struct StorageData( + #[cfg_attr(feature = "std", serde(with="impl_serde::serialize"))] + pub Vec, +); /// Storage change set #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, PartialEq, Eq))] @@ -39,15 +46,11 @@ pub struct StorageChangeSet { /// Block hash pub block: Hash, /// A list of changes - pub changes: Vec<( - StorageKey, - Option, - )>, + pub changes: Vec<(StorageKey, Option)>, } /// List of all well known keys and prefixes in storage. pub mod well_known_keys { - /// Wasm code of the runtime. /// /// Stored as a raw byte vector. Required by substrate. @@ -94,3 +97,52 @@ pub mod well_known_keys { has_right_prefix } } + +/// A wrapper around a child storage key. +/// +/// This wrapper ensures that the child storage key is correct and properly used. It is +/// impossible to create an instance of this struct without providing a correct `storage_key`. +pub struct ChildStorageKey<'a> { + storage_key: Cow<'a, [u8]>, +} + +impl<'a> ChildStorageKey<'a> { + /// Create new instance of `Self`. + fn new(storage_key: Cow<'a, [u8]>) -> Option { + if well_known_keys::is_child_trie_key_valid(&storage_key) { + Some(ChildStorageKey { storage_key }) + } else { + None + } + } + + /// Create a new `ChildStorageKey` from a vector. + /// + /// `storage_key` need to start with `:child_storage:default:` + /// See `is_child_trie_key_valid` for more details. + pub fn from_vec(key: Vec) -> Option { + Self::new(Cow::Owned(key)) + } + + /// Create a new `ChildStorageKey` from a slice. + /// + /// `storage_key` need to start with `:child_storage:default:` + /// See `is_child_trie_key_valid` for more details. + pub fn from_slice(key: &'a [u8]) -> Option { + Self::new(Cow::Borrowed(key)) + } + + /// Get access to the byte representation of the storage key. + /// + /// This key is guaranteed to be correct. + pub fn as_ref(&self) -> &[u8] { + &*self.storage_key + } + + /// Destruct this instance into an owned vector that represents the storage key. + /// + /// This key is guaranteed to be correct. + pub fn into_owned(self) -> Vec { + self.storage_key.into_owned() + } +} diff --git a/core/rpc/src/author/tests.rs b/core/rpc/src/author/tests.rs index 57d3929d92..202dab4940 100644 --- a/core/rpc/src/author/tests.rs +++ b/core/rpc/src/author/tests.rs @@ -24,8 +24,8 @@ use transaction_pool::{ FullChainApi, }; use primitives::{ - H256, blake2_256, hexdisplay::HexDisplay, traits::BareCryptoStore, - testing::{ED25519, SR25519, KeyStore}, ed25519, crypto::Pair + H256, blake2_256, hexdisplay::HexDisplay, testing::{ED25519, SR25519, KeyStore}, ed25519, + crypto::Pair, }; use test_client::{ self, AccountKeyring, runtime::{Extrinsic, Transfer, SessionKeys}, DefaultTestClientBuilderExt, @@ -212,7 +212,9 @@ fn should_insert_key() { fn should_rotate_keys() { let runtime = runtime::Runtime::new().unwrap(); let keystore = KeyStore::new(); - let client = Arc::new(test_client::TestClientBuilder::new().set_keystore(keystore.clone()).build()); + let client = Arc::new( + test_client::TestClientBuilder::new().set_keystore(keystore.clone()).build(), + ); let p = Author { client: client.clone(), pool: Arc::new(Pool::new(Default::default(), FullChainApi::new(client))), diff --git a/core/rpc/src/state/state_full.rs b/core/rpc/src/state/state_full.rs index 6f0472163f..cd05093c3a 100644 --- a/core/rpc/src/state/state_full.rs +++ b/core/rpc/src/state/state_full.rs @@ -33,8 +33,7 @@ use client::{ backend::Backend, error::Result as ClientResult, }; use primitives::{ - H256, Blake2Hasher, Bytes, offchain::NeverOffchainExt, - storage::{well_known_keys, StorageKey, StorageData, StorageChangeSet}, + H256, Blake2Hasher, Bytes, storage::{well_known_keys, StorageKey, StorageData, StorageChangeSet}, }; use runtime_version::RuntimeVersion; use state_machine::ExecutionStrategy; @@ -240,13 +239,16 @@ impl StateBackend for FullState FutureResult { Box::new(result( self.block_or_best(block) - .and_then(|block| self.client.executor() + .and_then(|block| + self + .client + .executor() .call( &BlockId::Hash(block), &method, &*call_data, ExecutionStrategy::NativeElseWasm, - NeverOffchainExt::new(), + None, ) .map(Into::into)) .map_err(client_err))) diff --git a/core/sr-io/Cargo.toml b/core/sr-io/Cargo.toml index 65b080b86d..e2b681b75b 100644 --- a/core/sr-io/Cargo.toml +++ b/core/sr-io/Cargo.toml @@ -15,9 +15,9 @@ codec = { package = "parity-scale-codec", version = "1.0.0", default-features = hash-db = { version = "0.15.2", default-features = false } libsecp256k1 = { version = "0.3.0", optional = true } tiny-keccak = { version = "1.5.0", optional = true } -environmental = { version = "1.0.2", optional = true } substrate-state-machine = { path = "../state-machine", optional = true } trie = { package = "substrate-trie", path = "../trie", optional = true } +externalities = { package = "substrate-externalities", path = "../externalities", optional = true } [features] default = ["std"] @@ -27,10 +27,10 @@ std = [ "rstd/std", "hash-db/std", "trie", - "environmental", "substrate-state-machine", "libsecp256k1", "tiny-keccak", + "externalities", ] nightly = [] strict = [] diff --git a/core/sr-io/src/lib.rs b/core/sr-io/src/lib.rs index 4b00a84231..24f964c7b5 100644 --- a/core/sr-io/src/lib.rs +++ b/core/sr-io/src/lib.rs @@ -368,13 +368,10 @@ mod imp { } #[cfg(feature = "std")] -pub use self::imp::{ - StorageOverlay, ChildrenStorageOverlay, with_storage, - with_externalities -}; +pub use self::imp::{StorageOverlay, ChildrenStorageOverlay, with_storage}; #[cfg(not(feature = "std"))] pub use self::imp::ext::*; /// Type alias for Externalities implementation used in tests. #[cfg(feature = "std")] -pub type TestExternalities = self::imp::TestExternalities; +pub type TestExternalities = self::imp::TestExternalities; diff --git a/core/sr-io/with_std.rs b/core/sr-io/with_std.rs index 919f4a913a..e431ae1f6e 100644 --- a/core/sr-io/with_std.rs +++ b/core/sr-io/with_std.rs @@ -16,19 +16,18 @@ use primitives::{ blake2_128, blake2_256, twox_128, twox_256, twox_64, ed25519, Blake2Hasher, sr25519, Pair, H256, - traits::Externalities, child_storage_key::ChildStorageKey, hexdisplay::HexDisplay, offchain, - Hasher, + traits::KeystoreExt, storage::ChildStorageKey, hexdisplay::HexDisplay, Hasher, + offchain::{self, OffchainExt}, }; // Switch to this after PoC-3 // pub use primitives::BlakeHasher; pub use substrate_state_machine::{BasicExternalities, TestExternalities}; -use environmental::environmental; use trie::{TrieConfiguration, trie_types::Layout}; use std::{collections::HashMap, convert::TryFrom}; -environmental!(ext: trait Externalities); +use externalities::{with_externalities, set_and_run_with_externalities, ExternalitiesExt}; /// Additional bounds for `Hasher` trait for with_std. pub trait HasherBounds {} @@ -48,12 +47,12 @@ fn child_storage_key_or_panic(storage_key: &[u8]) -> ChildStorageKey { impl StorageApi for () { fn storage(key: &[u8]) -> Option> { - ext::with(|ext| ext.storage(key).map(|s| s.to_vec())) + with_externalities(|ext| ext.storage(key).map(|s| s.to_vec())) .expect("storage cannot be called outside of an Externalities-provided environment.") } fn read_storage(key: &[u8], value_out: &mut [u8], value_offset: usize) -> Option { - ext::with(|ext| ext.storage(key).map(|value| { + with_externalities(|ext| ext.storage(key).map(|value| { let data = &value[value_offset.min(value.len())..]; let written = std::cmp::min(data.len(), value_out.len()); value_out[..written].copy_from_slice(&data[..written]); @@ -62,7 +61,7 @@ impl StorageApi for () { } fn child_storage(storage_key: &[u8], key: &[u8]) -> Option> { - ext::with(|ext| { + with_externalities(|ext| { let storage_key = child_storage_key_or_panic(storage_key); ext.child_storage(storage_key, key).map(|s| s.to_vec()) }) @@ -70,7 +69,7 @@ impl StorageApi for () { } fn set_storage(key: &[u8], value: &[u8]) { - ext::with(|ext| + with_externalities(|ext| ext.set_storage(key.to_vec(), value.to_vec()) ); } @@ -81,7 +80,7 @@ impl StorageApi for () { value_out: &mut [u8], value_offset: usize, ) -> Option { - ext::with(|ext| { + with_externalities(|ext| { let storage_key = child_storage_key_or_panic(storage_key); ext.child_storage(storage_key, key) .map(|value| { @@ -95,73 +94,71 @@ impl StorageApi for () { } fn set_child_storage(storage_key: &[u8], key: &[u8], value: &[u8]) { - ext::with(|ext| { + with_externalities(|ext| { let storage_key = child_storage_key_or_panic(storage_key); ext.set_child_storage(storage_key, key.to_vec(), value.to_vec()) }); } fn clear_storage(key: &[u8]) { - ext::with(|ext| + with_externalities(|ext| ext.clear_storage(key) ); } fn clear_child_storage(storage_key: &[u8], key: &[u8]) { - ext::with(|ext| { + with_externalities(|ext| { let storage_key = child_storage_key_or_panic(storage_key); ext.clear_child_storage(storage_key, key) }); } fn kill_child_storage(storage_key: &[u8]) { - ext::with(|ext| { + with_externalities(|ext| { let storage_key = child_storage_key_or_panic(storage_key); ext.kill_child_storage(storage_key) }); } fn exists_storage(key: &[u8]) -> bool { - ext::with(|ext| + with_externalities(|ext| ext.exists_storage(key) ).unwrap_or(false) } fn exists_child_storage(storage_key: &[u8], key: &[u8]) -> bool { - ext::with(|ext| { + with_externalities(|ext| { let storage_key = child_storage_key_or_panic(storage_key); ext.exists_child_storage(storage_key, key) }).unwrap_or(false) } fn clear_prefix(prefix: &[u8]) { - ext::with(|ext| - ext.clear_prefix(prefix) - ); + with_externalities(|ext| ext.clear_prefix(prefix)); } fn clear_child_prefix(storage_key: &[u8], prefix: &[u8]) { - ext::with(|ext| { + with_externalities(|ext| { let storage_key = child_storage_key_or_panic(storage_key); ext.clear_child_prefix(storage_key, prefix) }); } fn storage_root() -> [u8; 32] { - ext::with(|ext| + with_externalities(|ext| ext.storage_root() ).unwrap_or(H256::zero()).into() } fn child_storage_root(storage_key: &[u8]) -> Vec { - ext::with(|ext| { + with_externalities(|ext| { let storage_key = child_storage_key_or_panic(storage_key); ext.child_storage_root(storage_key) }).expect("child_storage_root cannot be called outside of an Externalities-provided environment.") } fn storage_changes_root(parent_hash: [u8; 32]) -> Option<[u8; 32]> { - ext::with(|ext| + with_externalities(|ext| ext.storage_changes_root(parent_hash.into()).map(|h| h.map(|h| h.into())) ).unwrap_or(Ok(None)).expect("Invalid parent hash passed to storage_changes_root") } @@ -177,7 +174,7 @@ impl StorageApi for () { impl OtherApi for () { fn chain_id() -> u64 { - ext::with(|ext| + with_externalities(|ext| ext.chain_id() ).unwrap_or(0) } @@ -199,8 +196,8 @@ impl OtherApi for () { impl CryptoApi for () { fn ed25519_public_keys(id: KeyTypeId) -> Vec { - ext::with(|ext| { - ext.keystore() + with_externalities(|ext| { + ext.extension::() .expect("No `keystore` associated for the current context!") .read() .ed25519_public_keys(id) @@ -208,8 +205,8 @@ impl CryptoApi for () { } fn ed25519_generate(id: KeyTypeId, seed: Option<&str>) -> ed25519::Public { - ext::with(|ext| { - ext.keystore() + with_externalities(|ext| { + ext.extension::() .expect("No `keystore` associated for the current context!") .write() .ed25519_generate_new(id, seed) @@ -224,8 +221,8 @@ impl CryptoApi for () { ) -> Option { let pub_key = ed25519::Public::try_from(pubkey.as_ref()).ok()?; - ext::with(|ext| { - ext.keystore() + with_externalities(|ext| { + ext.extension::() .expect("No `keystore` associated for the current context!") .read() .ed25519_key_pair(id, &pub_key) @@ -238,8 +235,8 @@ impl CryptoApi for () { } fn sr25519_public_keys(id: KeyTypeId) -> Vec { - ext::with(|ext| { - ext.keystore() + with_externalities(|ext| { + ext.extension::() .expect("No `keystore` associated for the current context!") .read() .sr25519_public_keys(id) @@ -247,8 +244,8 @@ impl CryptoApi for () { } fn sr25519_generate(id: KeyTypeId, seed: Option<&str>) -> sr25519::Public { - ext::with(|ext| { - ext.keystore() + with_externalities(|ext| { + ext.extension::() .expect("No `keystore` associated for the current context!") .write() .sr25519_generate_new(id, seed) @@ -263,8 +260,8 @@ impl CryptoApi for () { ) -> Option { let pub_key = sr25519::Public::try_from(pubkey.as_ref()).ok()?; - ext::with(|ext| { - ext.keystore() + with_externalities(|ext| { + ext.extension::() .expect("No `keystore` associated for the current context!") .read() .sr25519_key_pair(id, &pub_key) @@ -316,9 +313,9 @@ impl HashingApi for () { } fn with_offchain(f: impl FnOnce(&mut dyn offchain::Externalities) -> R, msg: &'static str) -> R { - ext::with(|ext| ext - .offchain() - .map(|ext| f(ext)) + with_externalities(|ext| ext + .extension::() + .map(|ext| f(&mut **ext)) .expect(msg) ).expect("offchain-worker functions cannot be called outside of an Externalities-provided environment.") } @@ -443,13 +440,6 @@ impl OffchainApi for () { impl Api for () {} -/// Execute the given closure with global function available whose functionality routes into the -/// externalities `ext`. Forwards the value that the closure returns. -// NOTE: need a concrete hasher here due to limitations of the `environmental!` macro, otherwise a type param would have been fine I think. -pub fn with_externalities R>(ext: &mut dyn Externalities, f: F) -> R { - ext::using(ext, f) -} - /// A set of key value pairs for storage. pub type StorageOverlay = HashMap, Vec>; @@ -467,7 +457,7 @@ pub fn with_storage R>( rstd::mem::swap(&mut alt_storage, storage); let mut ext = BasicExternalities::new(alt_storage.0, alt_storage.1); - let r = ext::using(&mut ext, f); + let r = set_and_run_with_externalities(&mut ext, f); *storage = ext.into_storages(); @@ -482,7 +472,7 @@ mod std_tests { #[test] fn storage_works() { let mut t = BasicExternalities::default(); - assert!(with_externalities(&mut t, || { + assert!(set_and_run_with_externalities(&mut t, || { assert_eq!(storage(b"hello"), None); set_storage(b"hello", b"world"); assert_eq!(storage(b"hello"), Some(b"world".to_vec())); @@ -493,7 +483,7 @@ mod std_tests { t = BasicExternalities::new(map![b"foo".to_vec() => b"bar".to_vec()], map![]); - assert!(!with_externalities(&mut t, || { + assert!(!set_and_run_with_externalities(&mut t, || { assert_eq!(storage(b"hello"), None); assert_eq!(storage(b"foo"), Some(b"bar".to_vec())); false @@ -506,7 +496,7 @@ mod std_tests { b":test".to_vec() => b"\x0b\0\0\0Hello world".to_vec() ], map![]); - with_externalities(&mut t, || { + set_and_run_with_externalities(&mut t, || { let mut v = [0u8; 4]; assert!(read_storage(b":test", &mut v[..], 0).unwrap() >= 4); assert_eq!(v, [11u8, 0, 0, 0]); @@ -525,7 +515,7 @@ mod std_tests { b":abdd".to_vec() => b"\x0b\0\0\0Hello world".to_vec() ], map![]); - with_externalities(&mut t, || { + set_and_run_with_externalities(&mut t, || { clear_prefix(b":abc"); assert!(storage(b":a").is_some()); diff --git a/core/sr-primitives/Cargo.toml b/core/sr-primitives/Cargo.toml index fc8b744d37..ab81df2b53 100644 --- a/core/sr-primitives/Cargo.toml +++ b/core/sr-primitives/Cargo.toml @@ -16,6 +16,7 @@ runtime_io = { package = "sr-io", path = "../sr-io", default-features = false } log = { version = "0.4.8", optional = true } paste = "0.1.6" rand = { version = "0.7.2", optional = true } +externalities = { package = "substrate-externalities", path = "../externalities", optional = true } impl-trait-for-tuples = "0.1.2" [dev-dependencies] @@ -36,4 +37,5 @@ std = [ "primitives/std", "app-crypto/std", "rand", + "externalities", ] diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index bdcbfb0b46..36d785f9a6 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -67,6 +67,9 @@ pub use sr_arithmetic::{ /// Re-export 128 bit helpers from sr_arithmetic pub use sr_arithmetic::helpers_128bit; +#[cfg(feature = "std")] +pub use externalities::set_and_run_with_externalities; + /// An abstraction over justification for a block's validity under a consensus algorithm. /// /// Essentially a finality proof. The exact formulation will vary between consensus diff --git a/core/sr-primitives/src/offchain/http.rs b/core/sr-primitives/src/offchain/http.rs index 6df18da83e..2d84f175d1 100644 --- a/core/sr-primitives/src/offchain/http.rs +++ b/core/sr-primitives/src/offchain/http.rs @@ -512,16 +512,18 @@ impl<'a> HeadersIterator<'a> { #[cfg(test)] mod tests { use super::*; - use runtime_io::{TestExternalities, with_externalities}; + use crate::set_and_run_with_externalities; + use runtime_io::TestExternalities; use substrate_offchain::testing; + use primitives::offchain::OffchainExt; #[test] fn should_send_a_basic_request_and_get_response() { let (offchain, state) = testing::TestOffchainExt::new(); let mut t = TestExternalities::default(); - t.set_offchain_externalities(offchain); + t.register_extension(OffchainExt::new(offchain)); - with_externalities(&mut t, || { + set_and_run_with_externalities(&mut t, || { let request: Request = Request::get("http://localhost:1234"); let pending = request .add_header("X-Auth", "hunter2") @@ -560,9 +562,9 @@ mod tests { fn should_send_a_post_request() { let (offchain, state) = testing::TestOffchainExt::new(); let mut t = TestExternalities::default(); - t.set_offchain_externalities(offchain); + t.register_extension(OffchainExt::new(offchain)); - with_externalities(&mut t, || { + set_and_run_with_externalities(&mut t, || { let pending = Request::default() .method(Method::Post) .url("http://localhost:1234") diff --git a/core/state-machine/Cargo.toml b/core/state-machine/Cargo.toml index 914fa04db8..7cd8601a3b 100644 --- a/core/state-machine/Cargo.toml +++ b/core/state-machine/Cargo.toml @@ -17,6 +17,7 @@ panic-handler = { package = "substrate-panic-handler", path = "../panic-handler" codec = { package = "parity-scale-codec", version = "1.0.0" } num-traits = "0.2.8" rand = "0.7.2" +externalities = { package = "substrate-externalities", path = "../externalities" } [dev-dependencies] hex-literal = "0.2.1" diff --git a/core/state-machine/src/basic.rs b/core/state-machine/src/basic.rs index e45af45c9f..c2d1a0e395 100644 --- a/core/state-machine/src/basic.rs +++ b/core/state-machine/src/basic.rs @@ -16,15 +16,14 @@ //! Basic implementation for Externalities. -use std::collections::HashMap; -use std::iter::FromIterator; +use std::{collections::HashMap, any::{TypeId, Any}, iter::FromIterator}; use crate::backend::{Backend, InMemory}; use hash_db::Hasher; use trie::{TrieConfiguration, default_child_trie_root}; use trie::trie_types::Layout; use primitives::{ - storage::well_known_keys::is_child_storage_key, child_storage_key::ChildStorageKey, offchain, - traits::Externalities, + storage::{well_known_keys::is_child_storage_key, ChildStorageKey}, + traits::Externalities, Blake2Hasher, hash::H256, }; use log::warn; @@ -88,21 +87,37 @@ impl From, Vec>> for BasicExternalities { } } -impl Externalities for BasicExternalities where H::Out: Ord { +impl Externalities for BasicExternalities { fn storage(&self, key: &[u8]) -> Option> { self.top.get(key).cloned() } + fn storage_hash(&self, key: &[u8]) -> Option { + self.storage(key).map(|v| Blake2Hasher::hash(&v)) + } + fn original_storage(&self, key: &[u8]) -> Option> { - Externalities::::storage(self, key) + self.storage(key) + } + + fn original_storage_hash(&self, key: &[u8]) -> Option { + self.storage_hash(key) } fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { self.children.get(storage_key.as_ref()).and_then(|child| child.get(key)).cloned() } + fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { + self.child_storage(storage_key, key).map(|v| Blake2Hasher::hash(&v)) + } + + fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { + self.child_storage_hash(storage_key, key) + } + fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { - Externalities::::child_storage(self, storage_key, key) + Externalities::child_storage(self, storage_key, key) } fn place_storage(&mut self, key: Vec, maybe_value: Option>) { @@ -155,16 +170,15 @@ impl Externalities for BasicExternalities where H::Out: Ord { fn chain_id(&self) -> u64 { 42 } - fn storage_root(&mut self) -> H::Out { + fn storage_root(&mut self) -> H256 { let mut top = self.top.clone(); let keys: Vec<_> = self.children.keys().map(|k| k.to_vec()).collect(); // Single child trie implementation currently allows using the same child // empty root for all child trie. Using null storage key until multiple // type of child trie support. - let empty_hash = default_child_trie_root::>(&[]); + let empty_hash = default_child_trie_root::>(&[]); for storage_key in keys { - let child_root = Externalities::::child_storage_root( - self, + let child_root = self.child_storage_root( ChildStorageKey::from_slice(storage_key.as_slice()) .expect("Map only feed by valid keys; qed"), ); @@ -175,30 +189,27 @@ impl Externalities for BasicExternalities where H::Out: Ord { } } - Layout::::trie_root(self.top.clone()) + Layout::::trie_root(self.top.clone()) } fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { if let Some(child) = self.children.get(storage_key.as_ref()) { let delta = child.clone().into_iter().map(|(k, v)| (k, Some(v))); - InMemory::::default().child_storage_root(storage_key.as_ref(), delta).0 + InMemory::::default().child_storage_root(storage_key.as_ref(), delta).0 } else { - default_child_trie_root::>(storage_key.as_ref()) + default_child_trie_root::>(storage_key.as_ref()) } } - fn storage_changes_root(&mut self, _parent: H::Out) -> Result, ()> { + fn storage_changes_root(&mut self, _parent: H256) -> Result, ()> { Ok(None) } +} - fn offchain(&mut self) -> Option<&mut dyn offchain::Externalities> { - warn!("Call to non-existent offchain externalities set."); - None - } - - fn keystore(&self) -> Option { - warn!("Call to non-existent keystore."); +impl externalities::ExtensionStore for BasicExternalities { + fn extension_by_type_id(&mut self, _: TypeId) -> Option<&mut dyn Any> { + warn!("Extensions are not supported by `BasicExternalities`."); None } } @@ -206,14 +217,13 @@ impl Externalities for BasicExternalities where H::Out: Ord { #[cfg(test)] mod tests { use super::*; - use primitives::{Blake2Hasher, H256, map}; + use primitives::{H256, map}; use primitives::storage::well_known_keys::CODE; use hex_literal::hex; #[test] fn commit_should_work() { let mut ext = BasicExternalities::default(); - let ext = &mut ext as &mut dyn Externalities; ext.set_storage(b"doe".to_vec(), b"reindeer".to_vec()); ext.set_storage(b"dog".to_vec(), b"puppy".to_vec()); ext.set_storage(b"dogglesworth".to_vec(), b"cat".to_vec()); @@ -225,7 +235,6 @@ mod tests { #[test] fn set_and_retrieve_code() { let mut ext = BasicExternalities::default(); - let ext = &mut ext as &mut dyn Externalities; let code = vec![1, 2, 3]; ext.set_storage(CODE.to_vec(), code.clone()); @@ -246,8 +255,6 @@ mod tests { ] ); - let ext = &mut ext as &mut dyn Externalities; - let child = || ChildStorageKey::from_vec(child_storage.clone()).unwrap(); assert_eq!(ext.child_storage(child(), b"doe"), Some(b"reindeer".to_vec())); diff --git a/core/state-machine/src/ext.rs b/core/state-machine/src/ext.rs index c4a2bd7f63..3433aee92c 100644 --- a/core/state-machine/src/ext.rs +++ b/core/state-machine/src/ext.rs @@ -16,22 +16,24 @@ //! Concrete externalities implementation. -use std::{error, fmt, cmp::Ord}; -use log::{warn, trace}; use crate::{ backend::Backend, OverlayedChanges, changes_trie::{ Storage as ChangesTrieStorage, CacheAction as ChangesTrieCacheAction, build_changes_trie, }, }; + use hash_db::Hasher; use primitives::{ - offchain, storage::well_known_keys::is_child_storage_key, - traits::{BareCryptoStorePtr, Externalities}, child_storage_key::ChildStorageKey, - hexdisplay::HexDisplay, + storage::{ChildStorageKey, well_known_keys::is_child_storage_key}, + traits::Externalities, hexdisplay::HexDisplay, hash::H256, }; -use trie::{MemoryDB, default_child_trie_root}; -use trie::trie_types::Layout; +use trie::{trie_types::Layout, MemoryDB, default_child_trie_root}; +use externalities::Extensions; + +use std::{error, fmt, any::{Any, TypeId}}; + +use log::{warn, trace}; const EXT_NOT_ALLOWED_TO_FAIL: &str = "Externalities not allowed to fail within runtime"; @@ -65,11 +67,7 @@ impl error::Error for Error { } /// Wraps a read-only backend, call executor, and current overlayed changes. -pub struct Ext<'a, H, N, B, T, O> -where - H: Hasher, - B: 'a + Backend, -{ +pub struct Ext<'a, H, N, B, T> where H: Hasher, B: 'a + Backend { /// The overlayed changes to write to. overlay: &'a mut OverlayedChanges, /// The storage backend to read from. @@ -86,25 +84,19 @@ where /// `storage_changes_root` is called matters + we need to remember additional /// data at this moment (block number). changes_trie_transaction: Option<(MemoryDB, H::Out, ChangesTrieCacheAction)>, - /// Additional externalities for offchain workers. - /// - /// If None, some methods from the trait might not be supported. - offchain_externalities: Option<&'a mut O>, - /// The keystore that manages the keys of the node. - keystore: Option, /// Pseudo-unique id used for tracing. pub id: u16, /// Dummy usage of N arg. - _phantom: ::std::marker::PhantomData, + _phantom: std::marker::PhantomData, + /// Extensions registered with this instance. + extensions: Option<&'a mut Extensions>, } -impl<'a, H, N, B, T, O> Ext<'a, H, N, B, T, O> +impl<'a, H, N, B, T> Ext<'a, H, N, B, T> where - H: Hasher, + H: Hasher, B: 'a + Backend, T: 'a + ChangesTrieStorage, - O: 'a + offchain::Externalities, - H::Out: Ord + 'static, N: crate::changes_trie::BlockNumber, { /// Create a new `Ext` from overlayed changes and read-only backend @@ -112,8 +104,7 @@ where overlay: &'a mut OverlayedChanges, backend: &'a B, changes_trie_storage: Option<&'a T>, - offchain_externalities: Option<&'a mut O>, - keystore: Option, + extensions: Option<&'a mut Extensions>, ) -> Self { Ext { overlay, @@ -121,21 +112,25 @@ where storage_transaction: None, changes_trie_storage, changes_trie_transaction: None, - offchain_externalities, - keystore, id: rand::random(), _phantom: Default::default(), + extensions, } } /// Get the transaction necessary to update the backend. - pub fn transaction(mut self) -> ((B::Transaction, H::Out), Option>) { + pub fn transaction(&mut self) -> ( + (B::Transaction, H256), + Option>, + ) { let _ = self.storage_root(); let (storage_transaction, changes_trie_transaction) = ( self.storage_transaction + .take() .expect("storage_transaction always set after calling storage root; qed"), self.changes_trie_transaction + .take() .map(|(tx, _, cache)| (tx, cache)), ); @@ -151,16 +146,14 @@ where fn mark_dirty(&mut self) { self.storage_transaction = None; } - } #[cfg(test)] -impl<'a, H, N, B, T, O> Ext<'a, H, N, B, T, O> +impl<'a, H, N, B, T> Ext<'a, H, N, B, T> where - H: Hasher, + H: Hasher, B: 'a + Backend, T: 'a + ChangesTrieStorage, - O: 'a + offchain::Externalities, N: crate::changes_trie::BlockNumber, { pub fn storage_pairs(&self) -> Vec<(Vec, Vec)> { @@ -177,13 +170,12 @@ where } } -impl<'a, B, T, H, N, O> Externalities for Ext<'a, H, N, B, T, O> -where H: Hasher, +impl<'a, H, B, T, N> Externalities for Ext<'a, H, N, B, T> +where + H: Hasher, B: 'a + Backend, T: 'a + ChangesTrieStorage, - H::Out: Ord + 'static, N: crate::changes_trie::BlockNumber, - O: 'a + offchain::Externalities, { fn storage(&self, key: &[u8]) -> Option> { let _guard = panic_handler::AbortGuard::force_abort(); @@ -197,10 +189,14 @@ where H: Hasher, result } - fn storage_hash(&self, key: &[u8]) -> Option { + fn storage_hash(&self, key: &[u8]) -> Option { let _guard = panic_handler::AbortGuard::force_abort(); - let result = self.overlay.storage(key).map(|x| x.map(|x| H::hash(x))).unwrap_or_else(|| - self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL)); + let result = self.overlay + .storage(key) + .map(|x| x.map(|x| H::hash(x))) + .unwrap_or_else(|| + self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL) + ); trace!(target: "state-trace", "{:04x}: Hash {}={:?}", self.id, HexDisplay::from(&key), @@ -220,7 +216,7 @@ where H: Hasher, result } - fn original_storage_hash(&self, key: &[u8]) -> Option { + fn original_storage_hash(&self, key: &[u8]) -> Option { let _guard = panic_handler::AbortGuard::force_abort(); let result = self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL); trace!(target: "state-trace", "{:04x}: GetOriginalHash {}={:?}", @@ -233,33 +229,48 @@ where H: Hasher, fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { let _guard = panic_handler::AbortGuard::force_abort(); - let result = self.overlay.child_storage(storage_key.as_ref(), key).map(|x| x.map(|x| x.to_vec())).unwrap_or_else(|| - self.backend.child_storage(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL)); + let result = self.overlay + .child_storage(storage_key.as_ref(), key) + .map(|x| x.map(|x| x.to_vec())) + .unwrap_or_else(|| + self.backend.child_storage(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL) + ); + trace!(target: "state-trace", "{:04x}: GetChild({}) {}={:?}", self.id, HexDisplay::from(&storage_key.as_ref()), HexDisplay::from(&key), result.as_ref().map(HexDisplay::from) ); + result } - fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { + fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { let _guard = panic_handler::AbortGuard::force_abort(); - let result = self.overlay.child_storage(storage_key.as_ref(), key).map(|x| x.map(|x| H::hash(x))).unwrap_or_else(|| - self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL)); + let result = self.overlay + .child_storage(storage_key.as_ref(), key) + .map(|x| x.map(|x| H::hash(x))) + .unwrap_or_else(|| + self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL) + ); + trace!(target: "state-trace", "{:04x}: ChildHash({}) {}={:?}", self.id, HexDisplay::from(&storage_key.as_ref()), HexDisplay::from(&key), result, ); + result } fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { let _guard = panic_handler::AbortGuard::force_abort(); - let result = self.backend.child_storage(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL); + let result = self.backend + .child_storage(storage_key.as_ref(), key) + .expect(EXT_NOT_ALLOWED_TO_FAIL); + trace!(target: "state-trace", "{:04x}: ChildOriginal({}) {}={:?}", self.id, HexDisplay::from(&storage_key.as_ref()), @@ -269,9 +280,12 @@ where H: Hasher, result } - fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { + fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { let _guard = panic_handler::AbortGuard::force_abort(); - let result = self.backend.child_storage_hash(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL); + let result = self.backend + .child_storage_hash(storage_key.as_ref(), key) + .expect(EXT_NOT_ALLOWED_TO_FAIL); + trace!(target: "state-trace", "{}: ChildHashOriginal({}) {}={:?}", self.id, HexDisplay::from(&storage_key.as_ref()), @@ -287,6 +301,7 @@ where H: Hasher, Some(x) => x.is_some(), _ => self.backend.exists_storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL), }; + trace!(target: "state-trace", "{:04x}: Exists {}={:?}", self.id, HexDisplay::from(&key), @@ -301,8 +316,11 @@ where H: Hasher, let result = match self.overlay.child_storage(storage_key.as_ref(), key) { Some(x) => x.is_some(), - _ => self.backend.exists_child_storage(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL), + _ => self.backend + .exists_child_storage(storage_key.as_ref(), key) + .expect(EXT_NOT_ALLOWED_TO_FAIL), }; + trace!(target: "state-trace", "{:04x}: ChildExists({}) {}={:?}", self.id, HexDisplay::from(&storage_key.as_ref()), @@ -328,7 +346,12 @@ where H: Hasher, self.overlay.set_storage(key, value); } - fn place_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Option>) { + fn place_child_storage( + &mut self, + storage_key: ChildStorageKey, + key: Vec, + value: Option>, + ) { trace!(target: "state-trace", "{:04x}: PutChild({}) {}={:?}", self.id, HexDisplay::from(&storage_key.as_ref()), @@ -392,7 +415,7 @@ where H: Hasher, 42 } - fn storage_root(&mut self) -> H::Out { + fn storage_root(&mut self) -> H256 { let _guard = panic_handler::AbortGuard::force_abort(); if let Some((_, ref root)) = self.storage_transaction { trace!(target: "state-trace", "{:04x}: Root (cached) {}", @@ -465,7 +488,7 @@ where H: Hasher, } } - fn storage_changes_root(&mut self, parent_hash: H::Out) -> Result, ()> { + fn storage_changes_root(&mut self, parent_hash: H256) -> Result, ()> { let _guard = panic_handler::AbortGuard::force_abort(); self.changes_trie_transaction = build_changes_trie::<_, T, H, N>( self.backend, @@ -481,32 +504,36 @@ where H: Hasher, ); result } +} - fn offchain(&mut self) -> Option<&mut dyn offchain::Externalities> { - self.offchain_externalities.as_mut().map(|x| &mut **x as _) - } - - fn keystore(&self) -> Option { - self.keystore.clone() +impl<'a, H, B, T, N> externalities::ExtensionStore for Ext<'a, H, N, B, T> +where + H: Hasher, + B: 'a + Backend, + T: 'a + ChangesTrieStorage, + N: crate::changes_trie::BlockNumber, +{ + fn extension_by_type_id(&mut self, type_id: TypeId) -> Option<&mut dyn Any> { + self.extensions.as_mut().and_then(|exts| exts.get_mut(type_id)) } - } #[cfg(test)] mod tests { + use super::*; use hex_literal::hex; use codec::Encode; - use primitives::{Blake2Hasher}; - use primitives::storage::well_known_keys::EXTRINSIC_INDEX; - use crate::backend::InMemory; - use crate::changes_trie::{Configuration as ChangesTrieConfiguration, - InMemoryStorage as InMemoryChangesTrieStorage}; - use crate::overlayed_changes::OverlayedValue; - use super::*; + use primitives::{Blake2Hasher, storage::well_known_keys::EXTRINSIC_INDEX}; + use crate::{ + changes_trie::{ + Configuration as ChangesTrieConfiguration, + InMemoryStorage as InMemoryChangesTrieStorage, + }, backend::InMemory, overlayed_changes::OverlayedValue, + }; type TestBackend = InMemory; type TestChangesTrieStorage = InMemoryChangesTrieStorage; - type TestExt<'a> = Ext<'a, Blake2Hasher, u64, TestBackend, TestChangesTrieStorage, crate::NeverOffchainExt>; + type TestExt<'a> = Ext<'a, Blake2Hasher, u64, TestBackend, TestChangesTrieStorage>; fn prepare_overlay_with_changes() -> OverlayedChanges { OverlayedChanges { @@ -532,7 +559,7 @@ mod tests { fn storage_changes_root_is_none_when_storage_is_not_provided() { let mut overlay = prepare_overlay_with_changes(); let backend = TestBackend::default(); - let mut ext = TestExt::new(&mut overlay, &backend, None, None, None); + let mut ext = TestExt::new(&mut overlay, &backend, None, None); assert_eq!(ext.storage_changes_root(Default::default()).unwrap(), None); } @@ -542,7 +569,7 @@ mod tests { overlay.changes_trie_config = None; let storage = TestChangesTrieStorage::with_blocks(vec![(100, Default::default())]); let backend = TestBackend::default(); - let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None, None); + let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None); assert_eq!(ext.storage_changes_root(Default::default()).unwrap(), None); } @@ -551,7 +578,7 @@ mod tests { let mut overlay = prepare_overlay_with_changes(); let storage = TestChangesTrieStorage::with_blocks(vec![(99, Default::default())]); let backend = TestBackend::default(); - let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None, None); + let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None); assert_eq!( ext.storage_changes_root(Default::default()).unwrap(), Some(hex!("bb0c2ef6e1d36d5490f9766cfcc7dfe2a6ca804504c3bb206053890d6dd02376").into()), @@ -564,7 +591,7 @@ mod tests { overlay.prospective.top.get_mut(&vec![1]).unwrap().value = None; let storage = TestChangesTrieStorage::with_blocks(vec![(99, Default::default())]); let backend = TestBackend::default(); - let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None, None); + let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None); assert_eq!( ext.storage_changes_root(Default::default()).unwrap(), Some(hex!("96f5aae4690e7302737b6f9b7f8567d5bbb9eac1c315f80101235a92d9ec27f4").into()), diff --git a/core/state-machine/src/lib.rs b/core/state-machine/src/lib.rs index 5220b4b31d..c3092367f0 100644 --- a/core/state-machine/src/lib.rs +++ b/core/state-machine/src/lib.rs @@ -18,18 +18,16 @@ #![warn(missing_docs)] -use std::{ - fmt, result, collections::HashMap, - marker::PhantomData, panic::UnwindSafe, -}; +use std::{fmt, result, collections::HashMap, panic::UnwindSafe, marker::PhantomData}; use log::{warn, trace}; use hash_db::Hasher; use codec::{Decode, Encode}; use primitives::{ - storage::well_known_keys, NativeOrEncoded, NeverNativeValue, offchain::{self, NeverOffchainExt}, - traits::{BareCryptoStorePtr, CodeExecutor}, - hexdisplay::HexDisplay, + storage::well_known_keys, NativeOrEncoded, NeverNativeValue, offchain::OffchainExt, + traits::{KeystoreExt, CodeExecutor}, hexdisplay::HexDisplay, hash::H256, }; +use overlayed_changes::OverlayedChangeSet; +use externalities::Extensions; pub mod backend; mod changes_trie; @@ -42,9 +40,7 @@ mod proving_backend; mod trie_backend; mod trie_backend_essence; -use overlayed_changes::OverlayedChangeSet; -pub use trie::{TrieMut, DBValue, MemoryDB}; -pub use trie::trie_types::{Layout, TrieDBMut}; +pub use trie::{trie_types::{Layout, TrieDBMut}, TrieMut, DBValue, MemoryDB}; pub use testing::TestExternalities; pub use basic::BasicExternalities; pub use ext::Ext; @@ -167,48 +163,54 @@ fn always_untrusted_wasm() -> ExecutionManager { - backend: B, - changes_trie_storage: Option<&'a T>, - offchain_ext: Option<&'a mut O>, - overlay: &'a mut OverlayedChanges, +pub struct StateMachine<'a, B, H, N, T, Exec> where H: Hasher, B: Backend { + backend: &'a B, exec: &'a Exec, method: &'a str, call_data: &'a [u8], - keystore: Option, - _hasher: PhantomData<(H, N)>, + overlay: &'a mut OverlayedChanges, + extensions: Extensions, + changes_trie_storage: Option<&'a T>, + _marker: PhantomData<(H, N)>, } -impl<'a, B, H, N, T, O, Exec> StateMachine<'a, B, H, N, T, O, Exec> where - H: Hasher, - Exec: CodeExecutor, +impl<'a, B, H, N, T, Exec> StateMachine<'a, B, H, N, T, Exec> where + H: Hasher, + Exec: CodeExecutor, B: Backend, T: ChangesTrieStorage, - O: offchain::Externalities, - H::Out: Ord + 'static, N: crate::changes_trie::BlockNumber, { /// Creates new substrate state machine. pub fn new( - backend: B, + backend: &'a B, changes_trie_storage: Option<&'a T>, - offchain_ext: Option<&'a mut O>, + offchain_ext: Option, overlay: &'a mut OverlayedChanges, exec: &'a Exec, method: &'a str, call_data: &'a [u8], - keystore: Option, + keystore: Option, ) -> Self { + let mut extensions = Extensions::new(); + + if let Some(keystore) = keystore { + extensions.register(keystore); + } + + if let Some(offchain) = offchain_ext { + extensions.register(offchain); + } + Self { backend, - changes_trie_storage, - offchain_ext, - overlay, exec, method, call_data, - keystore, - _hasher: PhantomData, + extensions, + overlay, + changes_trie_storage, + _marker: PhantomData, } } @@ -220,10 +222,10 @@ impl<'a, B, H, N, T, O, Exec> StateMachine<'a, B, H, N, T, O, Exec> where /// /// Note: changes to code will be in place if this call is made again. For running partial /// blocks (e.g. a transaction at a time), ensure a different method is used. - pub fn execute( - &mut self, - strategy: ExecutionStrategy, - ) -> Result<(Vec, (B::Transaction, H::Out), Option>), Box> { + pub fn execute(&mut self, strategy: ExecutionStrategy) -> Result< + (Vec, (B::Transaction, H::Out), Option>), + Box, + > { // We are not giving a native call and thus we are sure that the result can never be a native // value. self.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>( @@ -252,38 +254,44 @@ impl<'a, B, H, N, T, O, Exec> StateMachine<'a, B, H, N, T, O, Exec> where R: Decode + Encode + PartialEq, NC: FnOnce() -> result::Result + UnwindSafe, { - let mut externalities = ext::Ext::new( + let mut ext = Ext::new( self.overlay, - &self.backend, - self.changes_trie_storage, - self.offchain_ext.as_mut().map(|x| &mut **x), - self.keystore.clone(), + self.backend, + self.changes_trie_storage.clone(), + Some(&mut self.extensions), ); - let id = externalities.id; - trace!(target: "state-trace", "{:04x}: Call {} at {:?}. Input={:?}", + + let id = ext.id; + trace!( + target: "state-trace", "{:04x}: Call {} at {:?}. Input={:?}", id, self.method, self.backend, HexDisplay::from(&self.call_data), ); + let (result, was_native) = self.exec.call( - &mut externalities, + &mut ext, self.method, self.call_data, use_native, native_call, ); + let (storage_delta, changes_delta) = if compute_tx { - let (storage_delta, changes_delta) = externalities.transaction(); + let (storage_delta, changes_delta) = ext.transaction(); (Some(storage_delta), changes_delta) } else { (None, None) }; - trace!(target: "state-trace", "{:04x}: Return. Native={:?}, Result={:?}", + + trace!( + target: "state-trace", "{:04x}: Return. Native={:?}, Result={:?}", id, was_native, result, ); + (result, was_native, storage_delta, changes_delta) } @@ -293,12 +301,16 @@ impl<'a, B, H, N, T, O, Exec> StateMachine<'a, B, H, N, T, O, Exec> where mut native_call: Option, orig_prospective: OverlayedChangeSet, on_consensus_failure: Handler, - ) -> (CallResult, Option<(B::Transaction, H::Out)>, Option>) where + ) -> ( + CallResult, + Option<(B::Transaction, H::Out)>, + Option>, + ) where R: Decode + Encode + PartialEq, NC: FnOnce() -> result::Result + UnwindSafe, Handler: FnOnce( CallResult, - CallResult + CallResult, ) -> CallResult { let (result, was_native, storage_delta, changes_delta) = self.execute_aux( @@ -317,7 +329,8 @@ impl<'a, B, H, N, T, O, Exec> StateMachine<'a, B, H, N, T, O, Exec> where if (result.is_ok() && wasm_result.is_ok() && result.as_ref().ok() == wasm_result.as_ref().ok()) - || result.is_err() && wasm_result.is_err() { + || result.is_err() && wasm_result.is_err() + { (result, storage_delta, changes_delta) } else { (on_consensus_failure(wasm_result, result), wasm_storage_delta, wasm_changes_delta) @@ -332,7 +345,11 @@ impl<'a, B, H, N, T, O, Exec> StateMachine<'a, B, H, N, T, O, Exec> where compute_tx: bool, mut native_call: Option, orig_prospective: OverlayedChangeSet, - ) -> (CallResult, Option<(B::Transaction, H::Out)>, Option>) where + ) -> ( + CallResult, + Option<(B::Transaction, H::Out)>, + Option>, + ) where R: Decode + Encode + PartialEq, NC: FnOnce() -> result::Result + UnwindSafe, { @@ -431,7 +448,7 @@ impl<'a, B, H, N, T, O, Exec> StateMachine<'a, B, H, N, T, O, Exec> where }; if result.is_ok() { - init_overlay(self.overlay, true, &self.backend)?; + init_overlay(self.overlay, true, self.backend)?; } result.map_err(|e| Box::new(e) as _) @@ -445,13 +462,12 @@ pub fn prove_execution( exec: &Exec, method: &str, call_data: &[u8], - keystore: Option, + keystore: Option, ) -> Result<(Vec, Vec>), Box> where B: Backend, - H: Hasher, - Exec: CodeExecutor, - H::Out: Ord + 'static, + H: Hasher, + Exec: CodeExecutor, { let trie_backend = backend.as_trie_backend() .ok_or_else(|| Box::new(ExecutionError::UnableToGenerateProof) as Box)?; @@ -473,17 +489,16 @@ pub fn prove_execution_on_trie_backend( exec: &Exec, method: &str, call_data: &[u8], - keystore: Option, + keystore: Option, ) -> Result<(Vec, Vec>), Box> where S: trie_backend_essence::TrieBackendStorage, - H: Hasher, - Exec: CodeExecutor, - H::Out: Ord + 'static, + H: Hasher, + Exec: CodeExecutor, { let proving_backend = proving_backend::ProvingBackend::new(trie_backend); - let mut sm = StateMachine::<_, H, _, InMemoryChangesTrieStorage, _, Exec>::new( - proving_backend, None, NeverOffchainExt::new(), overlay, exec, method, call_data, keystore, + let mut sm = StateMachine::<_, H, _, InMemoryChangesTrieStorage, Exec>::new( + &proving_backend, None, None, overlay, exec, method, call_data, keystore, ); let (result, _, _) = sm.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>( @@ -503,11 +518,11 @@ pub fn execution_proof_check( exec: &Exec, method: &str, call_data: &[u8], - keystore: Option, + keystore: Option, ) -> Result, Box> where - H: Hasher, - Exec: CodeExecutor, + H: Hasher, + Exec: CodeExecutor, H::Out: Ord + 'static, { let trie_backend = create_proof_check_backend::(root.into(), proof)?; @@ -521,15 +536,14 @@ pub fn execution_proof_check_on_trie_backend( exec: &Exec, method: &str, call_data: &[u8], - keystore: Option, + keystore: Option, ) -> Result, Box> where - H: Hasher, - Exec: CodeExecutor, - H::Out: Ord + 'static, + H: Hasher, + Exec: CodeExecutor, { - let mut sm = StateMachine::<_, H, _, InMemoryChangesTrieStorage, _, Exec>::new( - trie_backend, None, NeverOffchainExt::new(), overlay, exec, method, call_data, keystore, + let mut sm = StateMachine::<_, H, _, InMemoryChangesTrieStorage, Exec>::new( + trie_backend, None, None, overlay, exec, method, call_data, keystore, ); sm.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>( @@ -546,7 +560,7 @@ pub fn prove_read( ) -> Result>, Box> where B: Backend, - H: Hasher, + H: Hasher, H::Out: Ord, I: IntoIterator, I::Item: AsRef<[u8]>, @@ -741,7 +755,7 @@ mod tests { InMemoryStorage as InMemoryChangesTrieStorage, Configuration as ChangesTrieConfig, }; - use primitives::{Blake2Hasher, map, traits::Externalities, child_storage_key::ChildStorageKey}; + use primitives::{Blake2Hasher, map, traits::Externalities, storage::ChildStorageKey}; struct DummyCodeExecutor { change_changes_trie_config: bool, @@ -750,10 +764,14 @@ mod tests { fallback_succeeds: bool, } - impl CodeExecutor for DummyCodeExecutor { + impl CodeExecutor for DummyCodeExecutor { type Error = u8; - fn call, R: Encode + Decode + PartialEq, NC: FnOnce() -> result::Result>( + fn call< + E: Externalities, + R: Encode + Decode + PartialEq, + NC: FnOnce() -> result::Result, + >( &self, ext: &mut E, _method: &str, @@ -800,9 +818,9 @@ mod tests { let changes_trie_storage = InMemoryChangesTrieStorage::::new(); let mut state_machine = StateMachine::new( - backend, + &backend, Some(&changes_trie_storage), - NeverOffchainExt::new(), + None, &mut overlayed_changes, &DummyCodeExecutor { change_changes_trie_config: false, @@ -829,9 +847,9 @@ mod tests { let changes_trie_storage = InMemoryChangesTrieStorage::::new(); let mut state_machine = StateMachine::new( - backend, + &backend, Some(&changes_trie_storage), - NeverOffchainExt::new(), + None, &mut overlayed_changes, &DummyCodeExecutor { change_changes_trie_config: false, @@ -855,9 +873,9 @@ mod tests { let changes_trie_storage = InMemoryChangesTrieStorage::::new(); let mut state_machine = StateMachine::new( - backend, + &backend, Some(&changes_trie_storage), - NeverOffchainExt::new(), + None, &mut overlayed_changes, &DummyCodeExecutor { change_changes_trie_config: false, @@ -948,7 +966,6 @@ mod tests { &mut overlay, backend, Some(&changes_trie_storage), - NeverOffchainExt::new(), None, ); ext.clear_prefix(b"ab"); @@ -979,7 +996,6 @@ mod tests { &mut overlay, backend, Some(&changes_trie_storage), - NeverOffchainExt::new(), None, ); @@ -1067,9 +1083,9 @@ mod tests { let changes_trie_storage = InMemoryChangesTrieStorage::::new(); let mut state_machine = StateMachine::new( - backend, + &backend, Some(&changes_trie_storage), - NeverOffchainExt::new(), + None, &mut overlayed_changes, &DummyCodeExecutor { change_changes_trie_config: true, @@ -1092,9 +1108,9 @@ mod tests { let changes_trie_storage = InMemoryChangesTrieStorage::::new(); let mut state_machine = StateMachine::new( - backend, + &backend, Some(&changes_trie_storage), - NeverOffchainExt::new(), + None, &mut overlayed_changes, &DummyCodeExecutor { change_changes_trie_config: true, diff --git a/core/state-machine/src/overlayed_changes.rs b/core/state-machine/src/overlayed_changes.rs index a4952ddf73..53a66dc49e 100644 --- a/core/state-machine/src/overlayed_changes.rs +++ b/core/state-machine/src/overlayed_changes.rs @@ -420,7 +420,6 @@ mod tests { &mut overlay, &backend, Some(&changes_trie_storage), - crate::NeverOffchainExt::new(), None, ); const ROOT: [u8; 32] = hex!("39245109cef3758c2eed2ccba8d9b370a917850af3824bc8348d505df2c298fa"); @@ -432,9 +431,12 @@ mod tests { fn changes_trie_configuration_is_saved() { let mut overlay = OverlayedChanges::default(); assert!(overlay.changes_trie_config.is_none()); - assert_eq!(overlay.set_changes_trie_config(ChangesTrieConfig { - digest_interval: 4, digest_levels: 1, - }), true); + assert_eq!( + overlay.set_changes_trie_config( + ChangesTrieConfig { digest_interval: 4, digest_levels: 1, }, + ), + true, + ); assert!(overlay.changes_trie_config.is_some()); } diff --git a/core/state-machine/src/proving_backend.rs b/core/state-machine/src/proving_backend.rs index 3908f62eaa..c6c4ef1ec8 100644 --- a/core/state-machine/src/proving_backend.rs +++ b/core/state-machine/src/proving_backend.rs @@ -250,7 +250,7 @@ mod tests { use crate::backend::{InMemory}; use crate::trie_backend::tests::test_trie; use super::*; - use primitives::{Blake2Hasher, child_storage_key::ChildStorageKey}; + use primitives::{Blake2Hasher, storage::ChildStorageKey}; fn test_proving<'a>( trie_backend: &'a TrieBackend,Blake2Hasher>, diff --git a/core/state-machine/src/testing.rs b/core/state-machine/src/testing.rs index 160f7d2a47..ea63eac021 100644 --- a/core/state-machine/src/testing.rs +++ b/core/state-machine/src/testing.rs @@ -16,7 +16,7 @@ //! Test implementation for Externalities. -use std::collections::{HashMap}; +use std::{collections::HashMap, any::{Any, TypeId}}; use hash_db::Hasher; use crate::{ backend::{InMemory, Backend}, OverlayedChanges, @@ -26,25 +26,28 @@ use crate::{ }, }; use primitives::{ - storage::well_known_keys::{CHANGES_TRIE_CONFIG, CODE, HEAP_PAGES, is_child_storage_key}, - traits::{BareCryptoStorePtr, Externalities}, offchain, child_storage_key::ChildStorageKey, + storage::{ + ChildStorageKey, + well_known_keys::{CHANGES_TRIE_CONFIG, CODE, HEAP_PAGES, is_child_storage_key} + }, + traits::Externalities, hash::H256, Blake2Hasher, }; use codec::Encode; +use externalities::{Extensions, Extension}; const EXT_NOT_ALLOWED_TO_FAIL: &str = "Externalities not allowed to fail within runtime"; type StorageTuple = (HashMap, Vec>, HashMap, HashMap, Vec>>); /// Simple HashMap-based Externalities impl. -pub struct TestExternalities { +pub struct TestExternalities=Blake2Hasher, N: ChangesTrieBlockNumber=u64> { overlay: OverlayedChanges, backend: InMemory, changes_trie_storage: ChangesTrieInMemoryStorage, - offchain: Option>, - keystore: Option, + extensions: Extensions, } -impl TestExternalities { +impl, N: ChangesTrieBlockNumber> TestExternalities { /// Create a new instance of `TestExternalities` with storage. pub fn new(storage: StorageTuple) -> Self { Self::new_with_code(&[], storage) @@ -75,8 +78,7 @@ impl TestExternalities { overlay, changes_trie_storage: ChangesTrieInMemoryStorage::new(), backend: backend.into(), - offchain: None, - keystore: None, + extensions: Default::default(), } } @@ -85,14 +87,9 @@ impl TestExternalities { self.backend = self.backend.update(vec![(None, k, Some(v))]); } - /// Set offchain externaltiies. - pub fn set_offchain_externalities(&mut self, offchain: impl offchain::Externalities + 'static) { - self.offchain = Some(Box::new(offchain)); - } - - /// Set keystore. - pub fn set_keystore(&mut self, keystore: BareCryptoStorePtr) { - self.keystore = Some(keystore); + /// Registers the given extension for this instance. + pub fn register_extension(&mut self, ext: E) { + self.extensions.register(ext); } /// Get mutable reference to changes trie storage. @@ -118,13 +115,13 @@ impl TestExternalities { } } -impl std::fmt::Debug for TestExternalities { +impl, N: ChangesTrieBlockNumber> std::fmt::Debug for TestExternalities { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(f, "overlay: {:?}\nbackend: {:?}", self.overlay, self.backend.pairs()) } } -impl PartialEq for TestExternalities { +impl, N: ChangesTrieBlockNumber> PartialEq for TestExternalities { /// This doesn't test if they are in the same state, only if they contains the /// same data at this state fn eq(&self, other: &TestExternalities) -> bool { @@ -132,30 +129,37 @@ impl PartialEq for TestExternalities } } -impl Default for TestExternalities { +impl, N: ChangesTrieBlockNumber> Default for TestExternalities { fn default() -> Self { Self::new(Default::default()) } } -impl From for TestExternalities { +impl, N: ChangesTrieBlockNumber> From for TestExternalities { fn from(storage: StorageTuple) -> Self { Self::new(storage) } } -impl Externalities for TestExternalities where - H: Hasher, +impl Externalities for TestExternalities where + H: Hasher, N: ChangesTrieBlockNumber, - H::Out: Ord + 'static, { fn storage(&self, key: &[u8]) -> Option> { self.overlay.storage(key).map(|x| x.map(|x| x.to_vec())).unwrap_or_else(|| self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL)) } + fn storage_hash(&self, key: &[u8]) -> Option { + self.storage(key).map(|v| H::hash(&v)) + } + fn original_storage(&self, key: &[u8]) -> Option> { self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL) } + fn original_storage_hash(&self, key: &[u8]) -> Option { + self.storage_hash(key) + } + fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { self.overlay .child_storage(storage_key.as_ref(), key) @@ -166,6 +170,10 @@ impl Externalities for TestExternalities where ) } + fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { + self.child_storage(storage_key, key).map(|v| H::hash(&v)) + } + fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { self.backend .child_storage(storage_key.as_ref(), key) @@ -173,6 +181,10 @@ impl Externalities for TestExternalities where .expect(EXT_NOT_ALLOWED_TO_FAIL) } + fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { + self.child_storage_hash(storage_key, key) + } + fn place_storage(&mut self, key: Vec, maybe_value: Option>) { if is_child_storage_key(&key) { panic!("Refuse to directly set child storage key"); @@ -185,7 +197,7 @@ impl Externalities for TestExternalities where &mut self, storage_key: ChildStorageKey, key: Vec, - value: Option> + value: Option>, ) { self.overlay.set_child_storage(storage_key.into_owned(), key, value); } @@ -215,7 +227,6 @@ impl Externalities for TestExternalities where } fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]) { - self.overlay.clear_child_prefix(storage_key.as_ref(), prefix); let backend = &self.backend; @@ -227,8 +238,7 @@ impl Externalities for TestExternalities where fn chain_id(&self) -> u64 { 42 } - fn storage_root(&mut self) -> H::Out { - + fn storage_root(&mut self) -> H256 { let child_storage_keys = self.overlay.prospective.children.keys() .chain(self.overlay.committed.children.keys()); @@ -246,7 +256,6 @@ impl Externalities for TestExternalities where let delta = self.overlay.committed.top.iter().map(|(k, v)| (k.clone(), v.value.clone())) .chain(self.overlay.prospective.top.iter().map(|(k, v)| (k.clone(), v.value.clone()))); self.backend.full_storage_root(delta, child_delta_iter).0 - } fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { @@ -270,7 +279,7 @@ impl Externalities for TestExternalities where root } - fn storage_changes_root(&mut self, parent: H::Out) -> Result, ()> { + fn storage_changes_root(&mut self, parent: H256) -> Result, ()> { Ok(build_changes_trie::<_, _, H, N>( &self.backend, Some(&self.changes_trie_storage), @@ -278,15 +287,14 @@ impl Externalities for TestExternalities where parent, )?.map(|(_, root, _)| root)) } +} - fn offchain(&mut self) -> Option<&mut dyn offchain::Externalities> { - self.offchain - .as_mut() - .map(|x| &mut **x as _) - } - - fn keystore(&self) -> Option { - self.keystore.clone() +impl externalities::ExtensionStore for TestExternalities where + H: Hasher, + N: ChangesTrieBlockNumber, +{ + fn extension_by_type_id(&mut self, type_id: TypeId) -> Option<&mut dyn Any> { + self.extensions.get_mut(type_id) } } diff --git a/core/test-runtime/src/system.rs b/core/test-runtime/src/system.rs index 12a656cf31..81bca2fad3 100644 --- a/core/test-runtime/src/system.rs +++ b/core/test-runtime/src/system.rs @@ -319,10 +319,11 @@ fn info_expect_equal_hash(given: &Hash, expected: &Hash) { mod tests { use super::*; - use runtime_io::{with_externalities, TestExternalities}; + use runtime_io::TestExternalities; use substrate_test_runtime_client::{AccountKeyring, Sr25519Keyring}; + use sr_primitives::set_and_run_with_externalities; use crate::{Header, Transfer, WASM_BINARY}; - use primitives::{Blake2Hasher, NeverNativeValue, map, traits::CodeExecutor}; + use primitives::{NeverNativeValue, map, traits::CodeExecutor}; use substrate_executor::{NativeExecutor, WasmExecutionMethod, native_executor_instance}; // Declare an instance of the native executor dispatch for the test runtime. @@ -336,7 +337,7 @@ mod tests { NativeExecutor::new(WasmExecutionMethod::Interpreted, None) } - fn new_test_ext() -> TestExternalities { + fn new_test_ext() -> TestExternalities { let authorities = vec![ Sr25519Keyring::Alice.to_raw_public(), Sr25519Keyring::Bob.to_raw_public(), @@ -357,7 +358,7 @@ mod tests { ) } - fn block_import_works(block_executor: F) where F: Fn(Block, &mut TestExternalities) { + fn block_import_works(block_executor: F) where F: Fn(Block, &mut TestExternalities) { let h = Header { parent_hash: [69u8; 32].into(), number: 1, @@ -370,7 +371,7 @@ mod tests { extrinsics: vec![], }; - with_externalities(&mut new_test_ext(), || polish_block(&mut b)); + set_and_run_with_externalities(&mut new_test_ext(), || polish_block(&mut b)); block_executor(b, &mut new_test_ext()); } @@ -378,7 +379,7 @@ mod tests { #[test] fn block_import_works_native() { block_import_works(|b, ext| { - with_externalities(ext, || { + set_and_run_with_externalities(ext, || { execute_block(b); }); }); @@ -397,7 +398,9 @@ mod tests { }) } - fn block_import_with_transaction_works(block_executor: F) where F: Fn(Block, &mut TestExternalities) { + fn block_import_with_transaction_works(block_executor: F) + where F: Fn(Block, &mut TestExternalities) + { let mut b1 = Block { header: Header { parent_hash: [69u8; 32].into(), @@ -417,7 +420,7 @@ mod tests { }; let mut dummy_ext = new_test_ext(); - with_externalities(&mut dummy_ext, || polish_block(&mut b1)); + set_and_run_with_externalities(&mut dummy_ext, || polish_block(&mut b1)); let mut b2 = Block { header: Header { @@ -443,26 +446,26 @@ mod tests { ], }; - with_externalities(&mut dummy_ext, || polish_block(&mut b2)); + set_and_run_with_externalities(&mut dummy_ext, || polish_block(&mut b2)); drop(dummy_ext); let mut t = new_test_ext(); - with_externalities(&mut t, || { + set_and_run_with_externalities(&mut t, || { assert_eq!(balance_of(AccountKeyring::Alice.into()), 111); assert_eq!(balance_of(AccountKeyring::Bob.into()), 0); }); block_executor(b1, &mut t); - with_externalities(&mut t, || { + set_and_run_with_externalities(&mut t, || { assert_eq!(balance_of(AccountKeyring::Alice.into()), 42); assert_eq!(balance_of(AccountKeyring::Bob.into()), 69); }); block_executor(b2, &mut t); - with_externalities(&mut t, || { + set_and_run_with_externalities(&mut t, || { assert_eq!(balance_of(AccountKeyring::Alice.into()), 0); assert_eq!(balance_of(AccountKeyring::Bob.into()), 42); assert_eq!(balance_of(AccountKeyring::Charlie.into()), 69); @@ -472,7 +475,7 @@ mod tests { #[test] fn block_import_with_transaction_works_native() { block_import_with_transaction_works(|b, ext| { - with_externalities(ext, || { + set_and_run_with_externalities(ext, || { execute_block(b); }); }); diff --git a/node-template/runtime/src/template.rs b/node-template/runtime/src/template.rs index 5a4225e63a..0266890dd8 100644 --- a/node-template/runtime/src/template.rs +++ b/node-template/runtime/src/template.rs @@ -69,12 +69,12 @@ decl_event!( mod tests { use super::*; - use runtime_io::with_externalities; - use primitives::{H256, Blake2Hasher}; + use primitives::H256; use support::{impl_outer_origin, assert_ok, parameter_types}; - use sr_primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; - use sr_primitives::weights::Weight; - use sr_primitives::Perbill; + use sr_primitives::{ + set_and_run_with_externalities, traits::{BlakeTwo256, IdentityLookup}, testing::Header, + weights::Weight, Perbill, + }; impl_outer_origin! { pub enum Origin for Test {} @@ -116,13 +116,13 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { system::GenesisConfig::default().build_storage::().unwrap().into() } #[test] fn it_works_for_default_value() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // Just a dummy test for the dummy funtion `do_something` // calling the `do_something` function with a value 42 assert_ok!(TemplateModule::do_something(Origin::signed(1), 42)); diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index 38656b7bd4..40c1e08f9b 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -36,7 +36,6 @@ native_executor_instance!( mod tests { use super::Executor; use {balances, contracts, indices, system, timestamp}; - use runtime_io; use codec::{Encode, Decode, Joiner}; use runtime_support::{ Hashable, StorageValue, StorageMap, traits::Currency, @@ -121,7 +120,7 @@ mod tests { NativeExecutor::new(WasmExecutionMethod::Interpreted, None) } - fn set_heap_pages>(ext: &mut E, heap_pages: u64) { + fn set_heap_pages(ext: &mut E, heap_pages: u64) { ext.place_storage(well_known_keys::HEAP_PAGES.to_vec(), Some(heap_pages.encode())); } @@ -227,7 +226,7 @@ mod tests { ).0; assert!(r.is_ok()); - runtime_io::with_externalities(&mut t, || { + sr_primitives::set_and_run_with_externalities(&mut t, || { assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); @@ -263,7 +262,7 @@ mod tests { ).0; assert!(r.is_ok()); - runtime_io::with_externalities(&mut t, || { + sr_primitives::set_and_run_with_externalities(&mut t, || { assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); @@ -434,7 +433,7 @@ mod tests { None, ).0.unwrap(); - runtime_io::with_externalities(&mut t, || { + sr_primitives::set_and_run_with_externalities(&mut t, || { assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); assert_eq!(Balances::total_balance(&bob()), 169 * DOLLARS); let events = vec![ @@ -469,7 +468,7 @@ mod tests { None, ).0.unwrap(); - runtime_io::with_externalities(&mut t, || { + sr_primitives::set_and_run_with_externalities(&mut t, || { // NOTE: fees differ slightly in tests that execute more than one block due to the // weight update. Hence, using `assert_eq_error_rate`. assert_eq_error_rate!( @@ -541,7 +540,7 @@ mod tests { None, ).0.unwrap(); - runtime_io::with_externalities(&mut t, || { + sr_primitives::set_and_run_with_externalities(&mut t, || { assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); assert_eq!(Balances::total_balance(&bob()), 169 * DOLLARS); }); @@ -554,7 +553,7 @@ mod tests { None, ).0.unwrap(); - runtime_io::with_externalities(&mut t, || { + sr_primitives::set_and_run_with_externalities(&mut t, || { assert_eq_error_rate!( Balances::total_balance(&alice()), 32 * DOLLARS - 2 * transfer_fee(&xt()), @@ -716,7 +715,7 @@ mod tests { None, ).0.unwrap(); - runtime_io::with_externalities(&mut t, || { + sr_primitives::set_and_run_with_externalities(&mut t, || { // Verify that the contract constructor worked well and code of TRANSFER contract is actually deployed. assert_eq!( &contracts::ContractInfoOf::::get(addr) @@ -837,7 +836,7 @@ mod tests { .expect("Extrinsic could be applied") .expect("Extrinsic did not fail"); - runtime_io::with_externalities(&mut t, || { + sr_primitives::set_and_run_with_externalities(&mut t, || { assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - 1 * transfer_fee(&xt())); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); @@ -896,7 +895,7 @@ mod tests { let mut prev_multiplier = WeightMultiplier::default(); - runtime_io::with_externalities(&mut t, || { + sr_primitives::set_and_run_with_externalities(&mut t, || { assert_eq!(System::next_weight_multiplier(), prev_multiplier); }); @@ -948,7 +947,7 @@ mod tests { ).0.unwrap(); // weight multiplier is increased for next block. - runtime_io::with_externalities(&mut t, || { + sr_primitives::set_and_run_with_externalities(&mut t, || { let fm = System::next_weight_multiplier(); println!("After a big block: {:?} -> {:?}", prev_multiplier, fm); assert!(fm > prev_multiplier); @@ -965,7 +964,7 @@ mod tests { ).0.unwrap(); // weight multiplier is increased for next block. - runtime_io::with_externalities(&mut t, || { + sr_primitives::set_and_run_with_externalities(&mut t, || { let fm = System::next_weight_multiplier(); println!("After a small block: {:?} -> {:?}", prev_multiplier, fm); assert!(fm < prev_multiplier); @@ -1019,7 +1018,7 @@ mod tests { ).0; assert!(r.is_ok()); - runtime_io::with_externalities(&mut t, || { + sr_primitives::set_and_run_with_externalities(&mut t, || { assert_eq!(Balances::total_balance(&bob()), (10 + 69) * DOLLARS); // Components deducted from alice's balances: // - Weight fee diff --git a/srml/assets/src/lib.rs b/srml/assets/src/lib.rs index 2a4245176a..e7f258483f 100644 --- a/srml/assets/src/lib.rs +++ b/srml/assets/src/lib.rs @@ -240,12 +240,14 @@ impl Module { mod tests { use super::*; - use runtime_io::with_externalities; use support::{impl_outer_origin, assert_ok, assert_noop, parameter_types}; - use primitives::{H256, Blake2Hasher}; + use primitives::H256; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. - use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; + use sr_primitives::{ + Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header, + set_and_run_with_externalities, + }; impl_outer_origin! { pub enum Origin for Test {} @@ -289,13 +291,13 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { system::GenesisConfig::default().build_storage::().unwrap().into() } #[test] fn issuing_asset_units_to_issuer_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); }); @@ -303,7 +305,7 @@ mod tests { #[test] fn querying_total_supply_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50)); @@ -320,7 +322,7 @@ mod tests { #[test] fn transferring_amount_above_available_balance_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50)); @@ -331,7 +333,7 @@ mod tests { #[test] fn transferring_amount_less_than_available_balance_should_not_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50)); @@ -345,7 +347,7 @@ mod tests { #[test] fn transferring_less_than_one_unit_should_not_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 0), "transfer amount should be non-zero"); @@ -354,7 +356,7 @@ mod tests { #[test] fn transferring_more_units_than_total_supply_should_not_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 101), "origin account balance must be greater than or equal to the transfer amount"); @@ -363,7 +365,7 @@ mod tests { #[test] fn destroying_asset_balance_with_positive_balance_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); assert_ok!(Assets::destroy(Origin::signed(1), 0)); @@ -372,7 +374,7 @@ mod tests { #[test] fn destroying_asset_balance_with_zero_balance_should_not_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 2), 0); assert_noop!(Assets::destroy(Origin::signed(2), 0), "origin balance should be non-zero"); diff --git a/srml/aura/src/mock.rs b/srml/aura/src/mock.rs index 6dc8953e88..7ebfd2a533 100644 --- a/srml/aura/src/mock.rs +++ b/srml/aura/src/mock.rs @@ -26,7 +26,7 @@ use sr_primitives::{ }; use support::{impl_outer_origin, parameter_types}; use runtime_io; -use primitives::{H256, Blake2Hasher}; +use primitives::H256; impl_outer_origin!{ pub enum Origin for Test {} @@ -73,7 +73,7 @@ impl Trait for Test { type AuthorityId = AuthorityId; } -pub fn new_test_ext(authorities: Vec) -> runtime_io::TestExternalities { +pub fn new_test_ext(authorities: Vec) -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); GenesisConfig::{ authorities: authorities.into_iter().map(|a| UintAuthorityId(a).to_public_key()).collect(), diff --git a/srml/aura/src/tests.rs b/srml/aura/src/tests.rs index a90eddf18f..0537fc8b64 100644 --- a/srml/aura/src/tests.rs +++ b/srml/aura/src/tests.rs @@ -18,12 +18,12 @@ #![cfg(test)] -use runtime_io::with_externalities; +use sr_primitives::set_and_run_with_externalities; use crate::mock::{Aura, new_test_ext}; #[test] fn initial_values() { - with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { + set_and_run_with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { assert_eq!(Aura::last(), 0u64); assert_eq!(Aura::authorities().len(), 4); }); diff --git a/srml/authority-discovery/src/lib.rs b/srml/authority-discovery/src/lib.rs index 2ec9e98835..38d587ba05 100644 --- a/srml/authority-discovery/src/lib.rs +++ b/srml/authority-discovery/src/lib.rs @@ -135,12 +135,12 @@ impl session::OneSessionHandler for Module { mod tests { use super::*; use app_crypto::Pair; - use primitives::testing::KeyStore; - use primitives::{crypto::key_types, sr25519, traits::BareCryptoStore, H256}; - use runtime_io::{with_externalities, TestExternalities}; - use sr_primitives::testing::{Header, UintAuthorityId}; - use sr_primitives::traits::{ConvertInto, IdentityLookup, OpaqueKeys}; - use sr_primitives::Perbill; + use primitives::{testing::KeyStore, crypto::key_types, sr25519, H256, traits::KeystoreExt}; + use runtime_io::TestExternalities; + use sr_primitives::{ + testing::{Header, UintAuthorityId}, traits::{ConvertInto, IdentityLookup, OpaqueKeys}, + Perbill, set_and_run_with_externalities, + }; use support::{impl_outer_origin, parameter_types}; type AuthorityDiscovery = Module; @@ -261,9 +261,9 @@ mod tests { // Create externalities. let mut externalities = TestExternalities::new(t); - externalities.set_keystore(key_store); + externalities.register_extension(KeystoreExt(key_store)); - with_externalities(&mut externalities, || { + set_and_run_with_externalities(&mut externalities, || { assert_eq!( authority_id, AuthorityDiscovery::authority_id().expect("Retrieving public key.") @@ -298,9 +298,9 @@ mod tests { // Create externalities. let mut externalities = TestExternalities::new(t); - externalities.set_keystore(key_store); + externalities.register_extension(KeystoreExt(key_store)); - with_externalities(&mut externalities, || { + set_and_run_with_externalities(&mut externalities, || { assert_eq!(None, AuthorityDiscovery::authority_id()); }); } @@ -335,9 +335,9 @@ mod tests { // Create externalities. let mut externalities = TestExternalities::new(t); - externalities.set_keystore(key_store); + externalities.register_extension(KeystoreExt(key_store)); - with_externalities(&mut externalities, || { + set_and_run_with_externalities(&mut externalities, || { let payload = String::from("test payload").into_bytes(); let (sig, authority_id) = AuthorityDiscovery::sign(&payload).expect("signature"); @@ -350,7 +350,7 @@ mod tests { assert!(!AuthorityDiscovery::verify( &String::from("other payload").into_bytes(), sig, - authority_id + authority_id, )) }); } diff --git a/srml/authorship/src/lib.rs b/srml/authorship/src/lib.rs index 490774c734..0033e53221 100644 --- a/srml/authorship/src/lib.rs +++ b/srml/authorship/src/lib.rs @@ -412,12 +412,11 @@ impl ProvideInherent for Module { #[cfg(test)] mod tests { use super::*; - use runtime_io::with_externalities; - use primitives::{H256, Blake2Hasher}; - use sr_primitives::traits::{BlakeTwo256, IdentityLookup}; - use sr_primitives::testing::Header; - use sr_primitives::generic::DigestItem; - use sr_primitives::Perbill; + use primitives::H256; + use sr_primitives::{ + set_and_run_with_externalities, traits::{BlakeTwo256, IdentityLookup}, testing::Header, + generic::DigestItem, Perbill, + }; use support::{parameter_types, impl_outer_origin, ConsensusEngineId}; impl_outer_origin!{ @@ -535,7 +534,7 @@ mod tests { ) } - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { let t = system::GenesisConfig::default().build_storage::().unwrap(); t.into() } @@ -543,7 +542,7 @@ mod tests { #[test] fn prune_old_uncles_works() { use UncleEntryItem::*; - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let hash = Default::default(); let author = Default::default(); let uncles = vec![ @@ -562,7 +561,7 @@ mod tests { #[test] fn rejects_bad_uncles() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let author_a = 69; struct CanonChain { @@ -675,7 +674,7 @@ mod tests { #[test] fn sets_author_lazily() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let author = 42; let mut header = seal_header( create_header(1, Default::default(), [1; 32].into()), diff --git a/srml/babe/src/mock.rs b/srml/babe/src/mock.rs index acc08c7a3b..582299f11c 100644 --- a/srml/babe/src/mock.rs +++ b/srml/babe/src/mock.rs @@ -101,7 +101,7 @@ impl Trait for Test { type EpochChangeTrigger = crate::ExternalTrigger; } -pub fn new_test_ext(authorities: Vec) -> runtime_io::TestExternalities { +pub fn new_test_ext(authorities: Vec) -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); GenesisConfig { authorities: authorities.into_iter().map(|a| (UintAuthorityId(a).to_public_key(), 1)).collect(), diff --git a/srml/babe/src/tests.rs b/srml/babe/src/tests.rs index ef449485b7..0a165b3854 100644 --- a/srml/babe/src/tests.rs +++ b/srml/babe/src/tests.rs @@ -17,9 +17,10 @@ //! Consensus extension module tests for BABE consensus. use super::*; -use runtime_io::with_externalities; use mock::{new_test_ext, Babe, Test}; -use sr_primitives::{traits::OnFinalize, testing::{Digest, DigestItem}}; +use sr_primitives::{ + set_and_run_with_externalities, traits::OnFinalize, testing::{Digest, DigestItem}, +}; use session::ShouldEndSession; const EMPTY_RANDOMNESS: [u8; 32] = [ @@ -53,14 +54,14 @@ fn empty_randomness_is_correct() { #[test] fn initial_values() { - with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { + set_and_run_with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { assert_eq!(Babe::authorities().len(), 4) }) } #[test] fn check_module() { - with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { + set_and_run_with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { assert!(!Babe::should_end_session(0), "Genesis does not change sessions"); assert!(!Babe::should_end_session(200000), "BABE does not include the block number in epoch calculations"); @@ -71,7 +72,7 @@ type System = system::Module; #[test] fn first_block_epoch_zero_start() { - with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { + set_and_run_with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { let genesis_slot = 100; let first_vrf = [1; 32]; let pre_digest = make_pre_digest( @@ -119,7 +120,7 @@ fn first_block_epoch_zero_start() { #[test] fn authority_index() { - with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { + set_and_run_with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { assert_eq!( Babe::find_author((&[(BABE_ENGINE_ID, &[][..])]).into_iter().cloned()), None, "Trivially invalid authorities are ignored") diff --git a/srml/balances/src/mock.rs b/srml/balances/src/mock.rs index 12a49fc90d..a909795178 100644 --- a/srml/balances/src/mock.rs +++ b/srml/balances/src/mock.rs @@ -20,7 +20,7 @@ use sr_primitives::{Perbill, traits::{Convert, IdentityLookup}, testing::Header, weights::{DispatchInfo, Weight}}; -use primitives::{H256, Blake2Hasher}; +use primitives::H256; use runtime_io; use support::{impl_outer_origin, parameter_types}; use support::traits::Get; @@ -179,7 +179,7 @@ impl ExtBuilder { TRANSACTION_BYTE_FEE.with(|v| *v.borrow_mut() = self.transaction_byte_fee); WEIGHT_TO_FEE.with(|v| *v.borrow_mut() = self.weight_to_fee); } - pub fn build(self) -> runtime_io::TestExternalities { + pub fn build(self) -> runtime_io::TestExternalities { self.set_associated_consts(); let mut t = system::GenesisConfig::default().build_storage::().unwrap(); GenesisConfig:: { diff --git a/srml/balances/src/tests.rs b/srml/balances/src/tests.rs index 8e9f6acdd8..b4745c2253 100644 --- a/srml/balances/src/tests.rs +++ b/srml/balances/src/tests.rs @@ -20,7 +20,7 @@ use super::*; use mock::{Balances, ExtBuilder, Runtime, System, info_from_weight, CALL}; -use runtime_io::with_externalities; +use sr_primitives::set_and_run_with_externalities; use support::{ assert_noop, assert_ok, assert_err, traits::{LockableCurrency, LockIdentifier, WithdrawReason, WithdrawReasons, @@ -34,7 +34,7 @@ const ID_3: LockIdentifier = *b"3 "; #[test] fn basic_locking_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { assert_eq!(Balances::free_balance(&1), 10); Balances::set_lock(ID_1, &1, 9, u64::max_value(), WithdrawReasons::all()); assert_noop!( @@ -46,7 +46,7 @@ fn basic_locking_should_work() { #[test] fn partial_locking_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { Balances::set_lock(ID_1, &1, 5, u64::max_value(), WithdrawReasons::all()); assert_ok!(>::transfer(&1, &2, 1)); }); @@ -54,7 +54,7 @@ fn partial_locking_should_work() { #[test] fn lock_removal_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { Balances::set_lock(ID_1, &1, u64::max_value(), u64::max_value(), WithdrawReasons::all()); Balances::remove_lock(ID_1, &1); assert_ok!(>::transfer(&1, &2, 1)); @@ -63,7 +63,7 @@ fn lock_removal_should_work() { #[test] fn lock_replacement_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { Balances::set_lock(ID_1, &1, u64::max_value(), u64::max_value(), WithdrawReasons::all()); Balances::set_lock(ID_1, &1, 5, u64::max_value(), WithdrawReasons::all()); assert_ok!(>::transfer(&1, &2, 1)); @@ -72,7 +72,7 @@ fn lock_replacement_should_work() { #[test] fn double_locking_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { Balances::set_lock(ID_1, &1, 5, u64::max_value(), WithdrawReasons::all()); Balances::set_lock(ID_2, &1, 5, u64::max_value(), WithdrawReasons::all()); assert_ok!(>::transfer(&1, &2, 1)); @@ -81,7 +81,7 @@ fn double_locking_should_work() { #[test] fn combination_locking_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { Balances::set_lock(ID_1, &1, u64::max_value(), 0, WithdrawReasons::none()); Balances::set_lock(ID_2, &1, 0, u64::max_value(), WithdrawReasons::none()); Balances::set_lock(ID_3, &1, 0, 0, WithdrawReasons::all()); @@ -91,7 +91,7 @@ fn combination_locking_should_work() { #[test] fn lock_value_extension_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { Balances::set_lock(ID_1, &1, 5, u64::max_value(), WithdrawReasons::all()); assert_noop!( >::transfer(&1, &2, 6), @@ -112,7 +112,7 @@ fn lock_value_extension_should_work() { #[test] fn lock_reasons_should_work() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default() .existential_deposit(1) .monied(true).transaction_fees(0, 1, 0) @@ -163,7 +163,7 @@ fn lock_reasons_should_work() { #[test] fn lock_block_number_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { Balances::set_lock(ID_1, &1, 10, 2, WithdrawReasons::all()); assert_noop!( >::transfer(&1, &2, 1), @@ -177,7 +177,7 @@ fn lock_block_number_should_work() { #[test] fn lock_block_number_extension_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { Balances::set_lock(ID_1, &1, 10, 2, WithdrawReasons::all()); assert_noop!( >::transfer(&1, &2, 6), @@ -199,7 +199,7 @@ fn lock_block_number_extension_should_work() { #[test] fn lock_reasons_extension_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { Balances::set_lock(ID_1, &1, 10, 10, WithdrawReason::Transfer.into()); assert_noop!( >::transfer(&1, &2, 6), @@ -220,7 +220,7 @@ fn lock_reasons_extension_should_work() { #[test] fn default_indexing_on_new_accounts_should_not_work2() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default() .existential_deposit(10) .creation_fee(50) @@ -242,7 +242,7 @@ fn default_indexing_on_new_accounts_should_not_work2() { #[test] fn reserved_balance_should_prevent_reclaim_count() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default() .existential_deposit(256 * 1) .monied(true) @@ -281,7 +281,7 @@ fn reserved_balance_should_prevent_reclaim_count() { #[test] fn reward_should_work() { - with_externalities(&mut ExtBuilder::default().monied(true).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().monied(true).build(), || { assert_eq!(Balances::total_balance(&1), 10); assert_ok!(Balances::deposit_into_existing(&1, 10).map(drop)); assert_eq!(Balances::total_balance(&1), 20); @@ -291,7 +291,7 @@ fn reward_should_work() { #[test] fn dust_account_removal_should_work() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default() .existential_deposit(100) .monied(true) @@ -311,7 +311,7 @@ fn dust_account_removal_should_work() { #[test] fn dust_account_removal_should_work2() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default() .existential_deposit(100) .creation_fee(50) @@ -332,7 +332,7 @@ fn dust_account_removal_should_work2() { #[test] fn balance_works() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let _ = Balances::deposit_creating(&1, 42); assert_eq!(Balances::free_balance(&1), 42); assert_eq!(Balances::reserved_balance(&1), 0); @@ -345,7 +345,7 @@ fn balance_works() { #[test] fn balance_transfer_works() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::transfer(Some(1).into(), 2, 69)); assert_eq!(Balances::total_balance(&1), 42); @@ -355,7 +355,7 @@ fn balance_transfer_works() { #[test] fn force_transfer_works() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let _ = Balances::deposit_creating(&1, 111); assert_noop!( Balances::force_transfer(Some(2).into(), 1, 2, 69), @@ -369,7 +369,7 @@ fn force_transfer_works() { #[test] fn reserving_balance_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let _ = Balances::deposit_creating(&1, 111); assert_eq!(Balances::total_balance(&1), 111); @@ -386,7 +386,7 @@ fn reserving_balance_should_work() { #[test] fn balance_transfer_when_reserved_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 69)); assert_noop!( @@ -398,7 +398,7 @@ fn balance_transfer_when_reserved_should_not_work() { #[test] fn deducting_balance_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 69)); assert_eq!(Balances::free_balance(&1), 42); @@ -407,7 +407,7 @@ fn deducting_balance_should_work() { #[test] fn refunding_balance_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let _ = Balances::deposit_creating(&1, 42); Balances::set_reserved_balance(&1, 69); Balances::unreserve(&1, 69); @@ -418,7 +418,7 @@ fn refunding_balance_should_work() { #[test] fn slashing_balance_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 69)); assert!(Balances::slash(&1, 69).1.is_zero()); @@ -430,7 +430,7 @@ fn slashing_balance_should_work() { #[test] fn slashing_incomplete_balance_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let _ = Balances::deposit_creating(&1, 42); assert_ok!(Balances::reserve(&1, 21)); assert_eq!(Balances::slash(&1, 69).1, 27); @@ -442,7 +442,7 @@ fn slashing_incomplete_balance_should_work() { #[test] fn unreserving_balance_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 111)); Balances::unreserve(&1, 42); @@ -453,7 +453,7 @@ fn unreserving_balance_should_work() { #[test] fn slashing_reserved_balance_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 111)); assert_eq!(Balances::slash_reserved(&1, 42).1, 0); @@ -465,7 +465,7 @@ fn slashing_reserved_balance_should_work() { #[test] fn slashing_incomplete_reserved_balance_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 42)); assert_eq!(Balances::slash_reserved(&1, 69).1, 27); @@ -477,7 +477,7 @@ fn slashing_incomplete_reserved_balance_should_work() { #[test] fn transferring_reserved_balance_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let _ = Balances::deposit_creating(&1, 110); let _ = Balances::deposit_creating(&2, 1); assert_ok!(Balances::reserve(&1, 110)); @@ -491,7 +491,7 @@ fn transferring_reserved_balance_should_work() { #[test] fn transferring_reserved_balance_to_nonexistent_should_fail() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 111)); assert_noop!(Balances::repatriate_reserved(&1, &2, 42), "beneficiary account must pre-exist"); @@ -500,7 +500,7 @@ fn transferring_reserved_balance_to_nonexistent_should_fail() { #[test] fn transferring_incomplete_reserved_balance_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let _ = Balances::deposit_creating(&1, 110); let _ = Balances::deposit_creating(&2, 1); assert_ok!(Balances::reserve(&1, 41)); @@ -514,7 +514,7 @@ fn transferring_incomplete_reserved_balance_should_work() { #[test] fn transferring_too_high_value_should_not_panic() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { >::insert(1, u64::max_value()); >::insert(2, 1); @@ -530,7 +530,7 @@ fn transferring_too_high_value_should_not_panic() { #[test] fn account_create_on_free_too_low_with_other() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(100).build(), || { let _ = Balances::deposit_creating(&1, 100); @@ -547,7 +547,7 @@ fn account_create_on_free_too_low_with_other() { #[test] fn account_create_on_free_too_low() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(100).build(), || { // No-op. @@ -560,7 +560,7 @@ fn account_create_on_free_too_low() { #[test] fn account_removal_on_free_too_low() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(100).build(), || { assert_eq!(>::get(), 0); @@ -590,7 +590,7 @@ fn account_removal_on_free_too_low() { #[test] fn transfer_overflow_isnt_exploitable() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().creation_fee(50).build(), || { // Craft a value that will overflow if summed with `creation_fee`. @@ -606,7 +606,7 @@ fn transfer_overflow_isnt_exploitable() { #[test] fn check_vesting_status() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default() .existential_deposit(256) .monied(true) @@ -669,7 +669,7 @@ fn check_vesting_status() { #[test] fn unvested_balance_should_not_transfer() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default() .existential_deposit(10) .monied(true) @@ -691,7 +691,7 @@ fn unvested_balance_should_not_transfer() { #[test] fn vested_balance_should_transfer() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default() .existential_deposit(10) .monied(true) @@ -710,7 +710,7 @@ fn vested_balance_should_transfer() { #[test] fn extra_balance_should_transfer() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default() .existential_deposit(10) .monied(true) @@ -740,7 +740,7 @@ fn extra_balance_should_transfer() { #[test] fn liquid_funds_should_transfer_with_delayed_vesting() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default() .existential_deposit(256) .monied(true) @@ -770,7 +770,7 @@ fn liquid_funds_should_transfer_with_delayed_vesting() { #[test] fn signed_extension_take_fees_work() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default() .existential_deposit(10) .transaction_fees(10, 1, 5) @@ -788,7 +788,7 @@ fn signed_extension_take_fees_work() { #[test] fn signed_extension_take_fees_is_bounded() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default() .existential_deposit(1000) .transaction_fees(0, 0, 1) @@ -810,7 +810,7 @@ fn signed_extension_take_fees_is_bounded() { #[test] fn burn_must_work() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default() .monied(true) .build(), diff --git a/srml/collective/src/lib.rs b/srml/collective/src/lib.rs index 4a157569c0..7ae352266a 100644 --- a/srml/collective/src/lib.rs +++ b/srml/collective/src/lib.rs @@ -382,10 +382,10 @@ mod tests { use support::{Hashable, assert_ok, assert_noop, parameter_types}; use system::{EventRecord, Phase}; use hex_literal::hex; - use runtime_io::with_externalities; - use primitives::{H256, Blake2Hasher}; + use primitives::H256; use sr_primitives::{ - Perbill, traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, testing::Header, BuildStorage + set_and_run_with_externalities, Perbill, + traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, testing::Header, BuildStorage, }; use crate as collective; @@ -439,7 +439,7 @@ mod tests { } ); - fn make_ext() -> runtime_io::TestExternalities { + fn make_ext() -> runtime_io::TestExternalities { GenesisConfig { collective_Instance1: Some(collective::GenesisConfig { members: vec![1, 2, 3], @@ -451,7 +451,7 @@ mod tests { #[test] fn motions_basic_environment_works() { - with_externalities(&mut make_ext(), || { + set_and_run_with_externalities(&mut make_ext(), || { System::set_block_number(1); assert_eq!(Collective::members(), vec![1, 2, 3]); assert_eq!(Collective::proposals(), Vec::::new()); @@ -464,7 +464,7 @@ mod tests { #[test] fn removal_of_old_voters_votes_works() { - with_externalities(&mut make_ext(), || { + set_and_run_with_externalities(&mut make_ext(), || { System::set_block_number(1); let proposal = make_proposal(42); let hash = BlakeTwo256::hash_of(&proposal); @@ -498,7 +498,7 @@ mod tests { #[test] fn removal_of_old_voters_votes_works_with_set_members() { - with_externalities(&mut make_ext(), || { + set_and_run_with_externalities(&mut make_ext(), || { System::set_block_number(1); let proposal = make_proposal(42); let hash = BlakeTwo256::hash_of(&proposal); @@ -532,7 +532,7 @@ mod tests { #[test] fn propose_works() { - with_externalities(&mut make_ext(), || { + set_and_run_with_externalities(&mut make_ext(), || { System::set_block_number(1); let proposal = make_proposal(42); let hash = proposal.blake2_256().into(); @@ -561,7 +561,7 @@ mod tests { #[test] fn motions_ignoring_non_collective_proposals_works() { - with_externalities(&mut make_ext(), || { + set_and_run_with_externalities(&mut make_ext(), || { System::set_block_number(1); let proposal = make_proposal(42); assert_noop!( @@ -573,7 +573,7 @@ mod tests { #[test] fn motions_ignoring_non_collective_votes_works() { - with_externalities(&mut make_ext(), || { + set_and_run_with_externalities(&mut make_ext(), || { System::set_block_number(1); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); @@ -584,7 +584,7 @@ mod tests { #[test] fn motions_ignoring_bad_index_collective_vote_works() { - with_externalities(&mut make_ext(), || { + set_and_run_with_externalities(&mut make_ext(), || { System::set_block_number(3); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); @@ -595,7 +595,7 @@ mod tests { #[test] fn motions_revoting_works() { - with_externalities(&mut make_ext(), || { + set_and_run_with_externalities(&mut make_ext(), || { System::set_block_number(1); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); @@ -640,7 +640,7 @@ mod tests { #[test] fn motions_disapproval_works() { - with_externalities(&mut make_ext(), || { + set_and_run_with_externalities(&mut make_ext(), || { System::set_block_number(1); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); @@ -683,7 +683,7 @@ mod tests { #[test] fn motions_approval_works() { - with_externalities(&mut make_ext(), || { + set_and_run_with_externalities(&mut make_ext(), || { System::set_block_number(1); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); diff --git a/srml/contracts/src/exec.rs b/srml/contracts/src/exec.rs index e4c5539cec..0cb0ee2679 100644 --- a/srml/contracts/src/exec.rs +++ b/srml/contracts/src/exec.rs @@ -803,16 +803,12 @@ mod tests { BalanceOf, ExecFeeToken, ExecutionContext, Ext, Loader, TransferFeeKind, TransferFeeToken, Vm, ExecResult, RawEvent, DeferredAction, }; - use crate::account_db::AccountDb; - use crate::exec::{ExecReturnValue, ExecError, STATUS_SUCCESS}; - use crate::gas::GasMeter; - use crate::tests::{ExtBuilder, Test}; - use crate::{CodeHash, Config}; - use runtime_io::with_externalities; - use std::cell::RefCell; - use std::rc::Rc; - use std::collections::HashMap; - use std::marker::PhantomData; + use crate::{ + account_db::AccountDb, gas::GasMeter, tests::{ExtBuilder, Test}, + exec::{ExecReturnValue, ExecError, STATUS_SUCCESS}, CodeHash, Config, + }; + use sr_primitives::set_and_run_with_externalities; + use std::{cell::RefCell, rc::Rc, collections::HashMap, marker::PhantomData}; use assert_matches::assert_matches; const ALICE: u64 = 1; @@ -937,7 +933,7 @@ mod tests { exec_success() }); - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); ctx.overlay.instantiate_contract(&BOB, exec_ch).unwrap(); @@ -957,7 +953,7 @@ mod tests { let dest = BOB; // This test verifies that base fee for call is taken. - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let vm = MockVm::new(); let loader = MockLoader::empty(); let cfg = Config::preload(); @@ -975,7 +971,7 @@ mod tests { }); // This test verifies that base fee for instantiation is taken. - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let mut loader = MockLoader::empty(); let code = loader.insert(|_| exec_success()); @@ -1005,7 +1001,7 @@ mod tests { let vm = MockVm::new(); let loader = MockLoader::empty(); - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); ctx.overlay.set_balance(&origin, 100); @@ -1037,7 +1033,7 @@ mod tests { |_| Ok(ExecReturnValue { status: 1, data: Vec::new() }) ); - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap(); @@ -1065,7 +1061,7 @@ mod tests { // This test sends 50 units of currency to a non-existent account. // This should lead to creation of a new account thus // a fee should be charged. - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(15).build(), || { let vm = MockVm::new(); @@ -1094,7 +1090,7 @@ mod tests { // This one is similar to the previous one but transfer to an existing account. // In this test we expect that a regular transfer fee is charged. - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(15).build(), || { let vm = MockVm::new(); @@ -1123,7 +1119,7 @@ mod tests { // This test sends 50 units of currency as an endownment to a newly // instantiated contract. - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(15).build(), || { let mut loader = MockLoader::empty(); @@ -1164,7 +1160,7 @@ mod tests { let vm = MockVm::new(); let loader = MockLoader::empty(); - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); ctx.overlay.set_balance(&origin, 0); @@ -1198,7 +1194,7 @@ mod tests { |_| Ok(ExecReturnValue { status: STATUS_SUCCESS, data: vec![1, 2, 3, 4] }) ); - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap(); @@ -1229,7 +1225,7 @@ mod tests { |_| Ok(ExecReturnValue { status: 1, data: vec![1, 2, 3, 4] }) ); - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap(); @@ -1257,7 +1253,7 @@ mod tests { }); // This one tests passing the input data into a contract via call. - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); ctx.overlay.instantiate_contract(&BOB, input_data_ch).unwrap(); @@ -1282,7 +1278,7 @@ mod tests { }); // This one tests passing the input data into a contract via instantiate. - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); @@ -1326,7 +1322,7 @@ mod tests { exec_success() }); - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); ctx.overlay.instantiate_contract(&BOB, recurse_ch).unwrap(); @@ -1370,7 +1366,7 @@ mod tests { exec_success() }); - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); @@ -1412,7 +1408,7 @@ mod tests { exec_success() }); - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); ctx.overlay.instantiate_contract(&BOB, bob_ch).unwrap(); @@ -1436,7 +1432,7 @@ mod tests { let mut loader = MockLoader::empty(); let dummy_ch = loader.insert(|_| exec_success()); - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(15).build(), || { let cfg = Config::preload(); @@ -1464,7 +1460,7 @@ mod tests { |_| Ok(ExecReturnValue { status: STATUS_SUCCESS, data: vec![80, 65, 83, 83] }) ); - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(15).build(), || { let cfg = Config::preload(); @@ -1507,7 +1503,7 @@ mod tests { |_| Ok(ExecReturnValue { status: 1, data: vec![70, 65, 73, 76] }) ); - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(15).build(), || { let cfg = Config::preload(); @@ -1555,7 +1551,7 @@ mod tests { } }); - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(15).build(), || { let cfg = Config::preload(); @@ -1617,7 +1613,7 @@ mod tests { } }); - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(15).build(), || { let cfg = Config::preload(); @@ -1653,7 +1649,7 @@ mod tests { exec_success() }); - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); diff --git a/srml/contracts/src/tests.rs b/srml/contracts/src/tests.rs index f2ef8a275d..a92d11e4d4 100644 --- a/srml/contracts/src/tests.rs +++ b/srml/contracts/src/tests.rs @@ -19,21 +19,18 @@ #![allow(unused)] -use crate::account_db::{AccountDb, DirectAccountDb, OverlayAccountDb}; use crate::{ BalanceOf, ComputeDispatchFee, ContractAddressFor, ContractInfo, ContractInfoOf, GenesisConfig, Module, RawAliveContractInfo, RawEvent, Trait, TrieId, TrieIdFromParentCounter, Schedule, - TrieIdGenerator, CheckBlockGasLimit, + TrieIdGenerator, CheckBlockGasLimit, account_db::{AccountDb, DirectAccountDb, OverlayAccountDb}, }; use assert_matches::assert_matches; use hex_literal::*; use codec::{Decode, Encode, KeyedVec}; -use runtime_io; -use runtime_io::with_externalities; use sr_primitives::{ Perbill, BuildStorage, transaction_validity::{InvalidTransaction, ValidTransaction}, traits::{BlakeTwo256, Hash, IdentityLookup, SignedExtension}, - weights::{DispatchInfo, DispatchClass}, + weights::{DispatchInfo, DispatchClass}, set_and_run_with_externalities, testing::{Digest, DigestItem, Header, UintAuthorityId, H256}, }; use support::{ @@ -41,7 +38,7 @@ use support::{ storage::child, StorageMap, StorageValue, traits::{Currency, Get}, }; use std::{cell::RefCell, sync::atomic::{AtomicUsize, Ordering}}; -use primitives::{storage::well_known_keys, Blake2Hasher}; +use primitives::storage::well_known_keys; use system::{self, EventRecord, Phase}; mod contract { @@ -275,7 +272,7 @@ impl ExtBuilder { INSTANTIATION_FEE.with(|v| *v.borrow_mut() = self.instantiation_fee); BLOCK_GAS_LIMIT.with(|v| *v.borrow_mut() = self.block_gas_limit); } - pub fn build(self) -> runtime_io::TestExternalities { + pub fn build(self) -> runtime_io::TestExternalities { self.set_associated_consts(); let mut t = system::GenesisConfig::default().build_storage::().unwrap(); balances::GenesisConfig:: { @@ -307,7 +304,7 @@ fn compile_module(wabt_module: &str) // Then we check that the all unused gas is refunded. #[test] fn refunds_unused_gas() { - with_externalities(&mut ExtBuilder::default().gas_price(2).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().gas_price(2).build(), || { Balances::deposit_creating(&ALICE, 100_000_000); assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, Vec::new())); @@ -319,7 +316,7 @@ fn refunds_unused_gas() { #[test] fn account_removal_removes_storage() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(100).build(), || { let trie_id1 = ::TrieIdGenerator::trie_id(&1); @@ -419,7 +416,7 @@ const CODE_RETURN_FROM_START_FN: &str = r#" fn instantiate_and_call_and_deposit_event() { let (wasm, code_hash) = compile_module::(CODE_RETURN_FROM_START_FN).unwrap(); - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(100).build(), || { Balances::deposit_creating(&ALICE, 1_000_000); @@ -502,7 +499,7 @@ fn dispatch_call() { let (wasm, code_hash) = compile_module::(CODE_DISPATCH_CALL).unwrap(); - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(50).build(), || { Balances::deposit_creating(&ALICE, 1_000_000); @@ -623,7 +620,7 @@ fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { let (wasm, code_hash) = compile_module::(CODE_DISPATCH_CALL_THEN_TRAP).unwrap(); - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(50).build(), || { Balances::deposit_creating(&ALICE, 1_000_000); @@ -826,7 +823,7 @@ fn test_set_rent_code_and_hash() { let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(50).build(), || { Balances::deposit_creating(&ALICE, 1_000_000); @@ -855,7 +852,7 @@ fn storage_size() { let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); // Storage size - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(50).build(), || { // Create @@ -885,7 +882,7 @@ fn storage_size() { fn deduct_blocks() { let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(50).build(), || { // Create @@ -982,7 +979,7 @@ fn claim_surcharge_malus() { fn claim_surcharge(blocks: u64, trigger_call: impl Fn() -> bool, removes: bool) { let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(50).build(), || { // Create @@ -1018,7 +1015,7 @@ fn removals(trigger_call: impl Fn() -> bool) { let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); // Balance reached and superior to subsistence threshold - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(50).build(), || { // Create @@ -1057,7 +1054,7 @@ fn removals(trigger_call: impl Fn() -> bool) { ); // Allowance exceeded - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(50).build(), || { // Create @@ -1095,7 +1092,7 @@ fn removals(trigger_call: impl Fn() -> bool) { ); // Balance reached and inferior to subsistence threshold - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(50).build(), || { // Create @@ -1142,7 +1139,7 @@ fn call_removed_contract() { let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); // Balance reached and superior to subsistence threshold - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(50).build(), || { // Create @@ -1230,7 +1227,7 @@ const CODE_CHECK_DEFAULT_RENT_ALLOWANCE: &str = r#" fn default_rent_allowance_on_instantiate() { let (wasm, code_hash) = compile_module::(CODE_CHECK_DEFAULT_RENT_ALLOWANCE).unwrap(); - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(50).build(), || { // Create @@ -1347,7 +1344,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: let (restoration_wasm, restoration_code_hash) = compile_module::(CODE_RESTORATION).unwrap(); - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(50).build(), || { Balances::deposit_creating(&ALICE, 1_000_000); @@ -1533,7 +1530,7 @@ const CODE_STORAGE_SIZE: &str = r#" fn storage_max_value_limit() { let (wasm, code_hash) = compile_module::(CODE_STORAGE_SIZE).unwrap(); - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(50).build(), || { // Create @@ -1900,7 +1897,7 @@ fn deploy_and_call_other_contract() { let (callee_wasm, callee_code_hash) = compile_module::(CODE_RETURN_WITH_DATA).unwrap(); let (caller_wasm, caller_code_hash) = compile_module::(CODE_CALLER_CONTRACT).unwrap(); - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(50).build(), || { // Create @@ -2031,7 +2028,7 @@ const CODE_SELF_DESTRUCT: &str = r#" #[test] fn self_destruct_by_draining_balance() { let (wasm, code_hash) = compile_module::(CODE_SELF_DESTRUCT).unwrap(); - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(50).build(), || { Balances::deposit_creating(&ALICE, 1_000_000); @@ -2070,7 +2067,7 @@ fn self_destruct_by_draining_balance() { #[test] fn cannot_self_destruct_while_live() { let (wasm, code_hash) = compile_module::(CODE_SELF_DESTRUCT).unwrap(); - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(50).build(), || { Balances::deposit_creating(&ALICE, 1_000_000); @@ -2272,7 +2269,7 @@ fn destroy_contract_and_transfer_funds() { let (callee_wasm, callee_code_hash) = compile_module::(CODE_SELF_DESTRUCT).unwrap(); let (caller_wasm, caller_code_hash) = compile_module::(CODE_DESTROY_AND_TRANSFER).unwrap(); - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(50).build(), || { // Create @@ -2371,7 +2368,7 @@ const CODE_SELF_DESTRUCTING_CONSTRUCTOR: &str = r#" #[test] fn cannot_self_destruct_in_constructor() { let (wasm, code_hash) = compile_module::(CODE_SELF_DESTRUCTING_CONSTRUCTOR).unwrap(); - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().existential_deposit(50).build(), || { Balances::deposit_creating(&ALICE, 1_000_000); @@ -2395,7 +2392,7 @@ fn cannot_self_destruct_in_constructor() { #[test] fn check_block_gas_limit_works() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().block_gas_limit(50).build(), || { let info = DispatchInfo { weight: 100, class: DispatchClass::Normal }; diff --git a/srml/council/src/lib.rs b/srml/council/src/lib.rs index aa27bcde21..e65cf9ace1 100644 --- a/srml/council/src/lib.rs +++ b/srml/council/src/lib.rs @@ -38,7 +38,6 @@ impl OnMembersChanged for () { mod tests { // These re-exports are here for a reason, edit with care pub use super::*; - pub use runtime_io::with_externalities; use support::{impl_outer_origin, impl_outer_event, impl_outer_dispatch, parameter_types}; use support::traits::Get; pub use primitives::{H256, Blake2Hasher, u32_trait::{_1, _2, _3, _4}}; diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index b93f6f893a..477e6818c9 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -971,14 +971,15 @@ impl OnFreeBalanceZero for Module { #[cfg(test)] mod tests { use super::*; - use runtime_io::with_externalities; use support::{ impl_outer_origin, impl_outer_dispatch, assert_noop, assert_ok, parameter_types, traits::Contains }; - use primitives::{H256, Blake2Hasher}; - use sr_primitives::{traits::{BlakeTwo256, IdentityLookup, Bounded}, testing::Header}; - use sr_primitives::Perbill; + use primitives::H256; + use sr_primitives::{ + set_and_run_with_externalities, traits::{BlakeTwo256, IdentityLookup, Bounded}, + testing::Header, Perbill, + }; use balances::BalanceLock; use system::EnsureSignedBy; @@ -1084,7 +1085,7 @@ mod tests { type CooloffPeriod = CooloffPeriod; } - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); balances::GenesisConfig::{ balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], @@ -1100,7 +1101,7 @@ mod tests { #[test] fn params_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_eq!(Democracy::referendum_count(), 0); assert_eq!(Balances::free_balance(&42), 0); assert_eq!(Balances::total_issuance(), 210); @@ -1132,7 +1133,7 @@ mod tests { #[test] fn external_and_public_interleaving_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(0); assert_ok!(Democracy::external_propose( Origin::signed(2), @@ -1245,7 +1246,7 @@ mod tests { #[test] fn emergency_cancel_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(0); let r = Democracy::inject_referendum( 2, @@ -1274,7 +1275,7 @@ mod tests { #[test] fn veto_external_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(0); assert_ok!(Democracy::external_propose( Origin::signed(2), @@ -1334,7 +1335,7 @@ mod tests { #[test] fn external_referendum_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(0); assert_noop!(Democracy::external_propose( Origin::signed(1), @@ -1363,7 +1364,7 @@ mod tests { #[test] fn external_majority_referendum_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(0); assert_noop!(Democracy::external_propose_majority( Origin::signed(1), @@ -1388,7 +1389,7 @@ mod tests { #[test] fn external_default_referendum_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(0); assert_noop!(Democracy::external_propose_default( Origin::signed(3), @@ -1413,7 +1414,7 @@ mod tests { #[test] fn fast_track_referendum_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(0); let h = BlakeTwo256::hash_of(&set_balance_proposal(2)); assert_noop!(Democracy::fast_track(Origin::signed(5), h, 3, 2), "no proposal made"); @@ -1437,7 +1438,7 @@ mod tests { #[test] fn fast_track_referendum_fails_when_no_simple_majority() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(0); let h = BlakeTwo256::hash_of(&set_balance_proposal(2)); assert_ok!(Democracy::external_propose( @@ -1453,7 +1454,7 @@ mod tests { #[test] fn locked_for_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(1); assert_ok!(propose_set_balance(1, 2, 2)); assert_ok!(propose_set_balance(1, 4, 4)); @@ -1466,7 +1467,7 @@ mod tests { #[test] fn single_proposal_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); assert!(Democracy::referendum_info(0).is_none()); @@ -1513,7 +1514,7 @@ mod tests { #[test] fn cancel_queued_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1537,7 +1538,7 @@ mod tests { #[test] fn proxy_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_eq!(Democracy::proxy(10), None); assert_ok!(Democracy::set_proxy(Origin::signed(1), 10)); assert_eq!(Democracy::proxy(10), Some(1)); @@ -1567,7 +1568,7 @@ mod tests { #[test] fn single_proposal_should_work_with_proxy() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1587,7 +1588,7 @@ mod tests { #[test] fn single_proposal_should_work_with_delegation() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1612,7 +1613,7 @@ mod tests { #[test] fn single_proposal_should_work_with_cyclic_delegation() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1639,7 +1640,7 @@ mod tests { #[test] /// If transactor already voted, delegated vote is overwriten. fn single_proposal_should_work_with_vote_and_delegation() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1665,7 +1666,7 @@ mod tests { #[test] fn single_proposal_should_work_with_undelegation() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1694,7 +1695,7 @@ mod tests { #[test] /// If transactor voted, delegated vote is overwriten. fn single_proposal_should_work_with_delegation_and_vote() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1725,7 +1726,7 @@ mod tests { #[test] fn deposit_for_proposals_should_be_taken() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(1); assert_ok!(propose_set_balance(1, 2, 5)); assert_ok!(Democracy::second(Origin::signed(2), 0)); @@ -1740,7 +1741,7 @@ mod tests { #[test] fn deposit_for_proposals_should_be_returned() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(1); assert_ok!(propose_set_balance(1, 2, 5)); assert_ok!(Democracy::second(Origin::signed(2), 0)); @@ -1756,7 +1757,7 @@ mod tests { #[test] fn proposal_with_deposit_below_minimum_should_not_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(1); assert_noop!(propose_set_balance(1, 2, 0), "value too low"); }); @@ -1764,7 +1765,7 @@ mod tests { #[test] fn poor_proposer_should_not_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(1); assert_noop!(propose_set_balance(1, 2, 11), "proposer\'s balance too low"); }); @@ -1772,7 +1773,7 @@ mod tests { #[test] fn poor_seconder_should_not_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(1); assert_ok!(propose_set_balance(2, 2, 11)); assert_noop!(Democracy::second(Origin::signed(1), 0), "seconder\'s balance too low"); @@ -1781,7 +1782,7 @@ mod tests { #[test] fn runners_up_should_come_after() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 2)); assert_ok!(propose_set_balance(1, 4, 4)); @@ -1797,7 +1798,7 @@ mod tests { #[test] fn simple_passing_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(1); let r = Democracy::inject_referendum( 1, @@ -1820,7 +1821,7 @@ mod tests { #[test] fn cancel_referendum_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(1); let r = Democracy::inject_referendum( 1, @@ -1840,7 +1841,7 @@ mod tests { #[test] fn simple_failing_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(1); let r = Democracy::inject_referendum( 1, @@ -1863,7 +1864,7 @@ mod tests { #[test] fn controversial_voting_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(1); let r = Democracy::inject_referendum( 1, @@ -1889,7 +1890,7 @@ mod tests { #[test] fn delayed_enactment_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(1); let r = Democracy::inject_referendum( 1, @@ -1917,7 +1918,7 @@ mod tests { #[test] fn controversial_low_turnout_voting_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(1); let r = Democracy::inject_referendum( 1, @@ -1939,7 +1940,7 @@ mod tests { #[test] fn passing_low_turnout_voting_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_eq!(Balances::free_balance(&42), 0); assert_eq!(Balances::total_issuance(), 210); @@ -1965,7 +1966,7 @@ mod tests { #[test] fn lock_voting_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(0); let r = Democracy::inject_referendum( 1, @@ -2025,7 +2026,7 @@ mod tests { #[test] fn lock_voting_should_work_with_delegation() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(1); let r = Democracy::inject_referendum( 1, diff --git a/srml/elections-phragmen/src/lib.rs b/srml/elections-phragmen/src/lib.rs index 58c0f11340..1405536267 100644 --- a/srml/elections-phragmen/src/lib.rs +++ b/srml/elections-phragmen/src/lib.rs @@ -591,10 +591,10 @@ mod tests { use super::*; use std::cell::RefCell; use srml_support::{assert_ok, assert_noop, parameter_types, assert_eq_uvec}; - use runtime_io::with_externalities; - use primitives::{H256, Blake2Hasher}; - use sr_primitives::{Perbill, testing::Header, BuildStorage, - traits::{BlakeTwo256, IdentityLookup, Block as BlockT} + use primitives::H256; + use sr_primitives::{ + Perbill, testing::Header, BuildStorage, + traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, set_and_run_with_externalities }; use crate as elections; @@ -730,7 +730,7 @@ mod tests { self.desired_runners_up = count; self } - pub fn build(self) -> runtime_io::TestExternalities { + pub fn build(self) -> runtime_io::TestExternalities { VOTING_BOND.with(|v| *v.borrow_mut() = self.voter_bond); GenesisConfig { balances: Some(balances::GenesisConfig::{ @@ -770,7 +770,7 @@ mod tests { #[test] fn params_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(1); assert_eq!(Elections::desired_members(), 2); assert_eq!(Elections::term_duration(), 5); @@ -790,7 +790,7 @@ mod tests { #[test] fn simple_candidate_submission_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_eq!(Elections::candidates(), Vec::::new()); assert!(Elections::is_candidate(&1).is_err()); assert!(Elections::is_candidate(&2).is_err()); @@ -817,7 +817,7 @@ mod tests { #[test] fn simple_candidate_submission_with_no_votes_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_eq!(Elections::candidates(), Vec::::new()); assert_ok!(Elections::submit_candidacy(Origin::signed(1))); @@ -844,7 +844,7 @@ mod tests { #[test] fn dupe_candidate_submission_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_eq!(Elections::candidates(), Vec::::new()); assert_ok!(Elections::submit_candidacy(Origin::signed(1))); assert_eq!(Elections::candidates(), vec![1]); @@ -858,7 +858,7 @@ mod tests { #[test] fn member_candidacy_submission_should_not_work() { // critically important to make sure that outgoing candidates and losers are not mixed up. - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); @@ -878,7 +878,7 @@ mod tests { #[test] fn poor_candidate_submission_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_eq!(Elections::candidates(), Vec::::new()); assert_noop!( Elections::submit_candidacy(Origin::signed(7)), @@ -889,7 +889,7 @@ mod tests { #[test] fn simple_voting_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_eq!(Elections::candidates(), Vec::::new()); assert_eq!(balances(&2), (20, 0)); @@ -903,7 +903,7 @@ mod tests { #[test] fn can_vote_with_custom_stake() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_eq!(Elections::candidates(), Vec::::new()); assert_eq!(balances(&2), (20, 0)); @@ -917,7 +917,7 @@ mod tests { #[test] fn can_update_votes_and_stake() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_eq!(balances(&2), (20, 0)); assert_ok!(Elections::submit_candidacy(Origin::signed(5))); @@ -938,7 +938,7 @@ mod tests { #[test] fn cannot_vote_for_no_candidate() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_noop!( Elections::vote(Origin::signed(2), vec![], 20), "cannot vote when no candidates or members exist" @@ -949,7 +949,7 @@ mod tests { #[test] fn can_vote_for_old_members_even_when_no_new_candidates() { // let allowed_votes = candidates_count as usize + Self::members().len() - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -967,7 +967,7 @@ mod tests { #[test] fn cannot_vote_for_more_than_candidates() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -980,7 +980,7 @@ mod tests { #[test] fn cannot_vote_for_less_than_ed() { - with_externalities(&mut ExtBuilder::default().voter_bond(8).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().voter_bond(8).build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -993,7 +993,7 @@ mod tests { #[test] fn can_vote_for_more_than_total_balance_but_moot() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1006,7 +1006,7 @@ mod tests { #[test] fn remove_voter_should_work() { - with_externalities(&mut ExtBuilder::default().voter_bond(8).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().voter_bond(8).build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); @@ -1031,14 +1031,14 @@ mod tests { #[test] fn non_voter_remove_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_noop!(Elections::remove_voter(Origin::signed(3)), "must be a voter"); }); } #[test] fn dupe_remove_should_fail() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); @@ -1051,7 +1051,7 @@ mod tests { #[test] fn removed_voter_should_not_be_counted() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1071,7 +1071,7 @@ mod tests { #[test] fn reporter_must_be_voter() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_noop!( Elections::report_defunct_voter(Origin::signed(1), 2), "reporter must be a voter", @@ -1081,7 +1081,7 @@ mod tests { #[test] fn can_detect_defunct_voter() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1116,7 +1116,7 @@ mod tests { #[test] fn report_voter_should_work_and_earn_reward() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1148,8 +1148,8 @@ mod tests { #[test] fn report_voter_should_slash_when_bad_report() { - with_externalities(&mut ExtBuilder::default().build(), || { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1180,7 +1180,7 @@ mod tests { #[test] fn simple_voting_rounds_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1215,7 +1215,7 @@ mod tests { #[test] fn defunct_voter_will_be_counted() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); // This guy's vote is pointless for this round. @@ -1243,7 +1243,7 @@ mod tests { #[test] fn only_desired_seats_are_chosen() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1264,7 +1264,7 @@ mod tests { #[test] fn phragmen_should_not_self_vote() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1279,7 +1279,7 @@ mod tests { #[test] fn runners_up_should_be_kept() { - with_externalities(&mut ExtBuilder::default().desired_runners_up(2).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().desired_runners_up(2).build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1306,7 +1306,7 @@ mod tests { #[test] fn runners_up_should_be_next_candidates() { - with_externalities(&mut ExtBuilder::default().desired_runners_up(2).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().desired_runners_up(2).build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1333,7 +1333,7 @@ mod tests { #[test] fn runners_up_lose_bond_once_outgoing() { - with_externalities(&mut ExtBuilder::default().desired_runners_up(1).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().desired_runners_up(1).build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(2))); @@ -1364,7 +1364,7 @@ mod tests { #[test] fn current_members_are_always_implicitly_next_candidate() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1400,7 +1400,7 @@ mod tests { fn election_state_is_uninterrupted() { // what I mean by uninterrupted: // given no input or stimulants the same members are re-elected. - with_externalities(&mut ExtBuilder::default().desired_runners_up(2).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().desired_runners_up(2).build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1433,7 +1433,7 @@ mod tests { #[test] fn remove_members_triggers_election() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1459,7 +1459,7 @@ mod tests { #[test] fn seats_should_be_released_when_no_vote() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1493,7 +1493,7 @@ mod tests { #[test] fn outgoing_will_get_the_bond_back() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_eq!(balances(&5), (50, 0)); assert_ok!(Elections::submit_candidacy(Origin::signed(5))); @@ -1519,7 +1519,7 @@ mod tests { #[test] fn losers_will_lose_the_bond() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1542,7 +1542,7 @@ mod tests { #[test] fn incoming_outgoing_are_reported() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(5))); @@ -1587,7 +1587,7 @@ mod tests { #[test] fn invalid_votes_are_moot() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); diff --git a/srml/elections/src/mock.rs b/srml/elections/src/mock.rs index 161da35e6a..b9e548e1ed 100644 --- a/srml/elections/src/mock.rs +++ b/srml/elections/src/mock.rs @@ -23,11 +23,9 @@ use support::{ StorageValue, StorageMap, parameter_types, assert_ok, traits::{Get, ChangeMembers, Currency} }; -use runtime_io::with_externalities; -use primitives::{H256, Blake2Hasher}; +use primitives::H256; use sr_primitives::{ - Perbill, BuildStorage, - testing::Header, + Perbill, BuildStorage, set_and_run_with_externalities, testing::Header, traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, }; use crate as elections; @@ -213,7 +211,7 @@ impl ExtBuilder { self.desired_seats = seats; self } - pub fn build(self) -> runtime_io::TestExternalities { + pub fn build(self) -> runtime_io::TestExternalities { VOTER_BOND.with(|v| *v.borrow_mut() = self.voter_bond); VOTING_FEE.with(|v| *v.borrow_mut() = self.voting_fee); PRESENT_SLASH_PER_VOTER.with(|v| *v.borrow_mut() = self.bad_presentation_punishment); @@ -283,9 +281,9 @@ pub(crate) fn locks(who: &u64) -> Vec { Balances::locks(who).iter().map(|l| l.amount).collect::>() } -pub(crate) fn new_test_ext_with_candidate_holes() -> runtime_io::TestExternalities { +pub(crate) fn new_test_ext_with_candidate_holes() -> runtime_io::TestExternalities { let mut t = ExtBuilder::default().build(); - with_externalities(&mut t, || { + set_and_run_with_externalities(&mut t, || { >::put(vec![0, 0, 1]); elections::CandidateCount::put(1); >::insert(1, (0, 2)); diff --git a/srml/elections/src/tests.rs b/srml/elections/src/tests.rs index c6f4f9a0b3..149e534a2f 100644 --- a/srml/elections/src/tests.rs +++ b/srml/elections/src/tests.rs @@ -22,11 +22,11 @@ use crate::mock::*; use crate::*; use support::{assert_ok, assert_err, assert_noop}; -use runtime_io::with_externalities; +use sr_primitives::set_and_run_with_externalities; #[test] fn params_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(1); assert_eq!(Elections::next_vote_from(1), 4); assert_eq!(Elections::next_vote_from(4), 4); @@ -53,7 +53,7 @@ fn params_should_work() { #[test] fn chunking_bool_to_flag_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_eq!(Elections::bool_to_flag(vec![]), vec![]); assert_eq!(Elections::bool_to_flag(vec![false]), vec![0]); assert_eq!(Elections::bool_to_flag(vec![true]), vec![1]); @@ -98,7 +98,7 @@ fn chunking_bool_to_flag_should_work() { #[test] fn chunking_voter_set_growth_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); // create 65. 64 (set0) + 1 (set1) @@ -122,7 +122,7 @@ fn chunking_voter_set_growth_should_work() { #[test] fn chunking_voter_set_reclaim_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); (1..=129).for_each(|i| vote(i, 0)); @@ -159,7 +159,7 @@ fn chunking_voter_set_reclaim_should_work() { #[test] fn chunking_approvals_set_growth_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { // create candidates and voters. (1..=250).for_each(|i| create_candidate(i, (i-1) as u32)); (1..=250).for_each(|i| vote(i, i as usize)); @@ -221,7 +221,7 @@ fn chunking_approvals_set_growth_should_work() { #[test] fn chunking_cell_status_works() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); (1..=63).for_each(|i| vote(i, 0)); @@ -240,7 +240,7 @@ fn chunking_cell_status_works() { #[test] fn chunking_voter_index_does_not_take_holes_into_account() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); // create 65. 64 (set0) + 1 (set1) @@ -265,7 +265,7 @@ fn chunking_voter_index_does_not_take_holes_into_account() { #[test] fn chunking_approval_storage_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); @@ -285,7 +285,7 @@ fn chunking_approval_storage_should_work() { #[test] fn voting_initial_set_approvals_ignores_voter_index() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); // Last argument is essentially irrelevant. You might get or miss a tip. @@ -299,7 +299,7 @@ fn voting_initial_set_approvals_ignores_voter_index() { } #[test] fn voting_bad_approval_index_slashes_voters_and_bond_reduces_stake() { - with_externalities(&mut ExtBuilder::default().voting_fee(5).voter_bond(2).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().voting_fee(5).voter_bond(2).build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); (1..=63).for_each(|i| vote(i, 0)); @@ -329,7 +329,7 @@ fn voting_bad_approval_index_slashes_voters_and_bond_reduces_stake() { #[test] fn voting_subsequent_set_approvals_checks_voter_index() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::set_approvals(Origin::signed(3), vec![], 0, 0, 30)); @@ -353,7 +353,7 @@ fn voting_subsequent_set_approvals_checks_voter_index() { #[test] fn voting_cannot_lock_less_than_limit() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_noop!( @@ -366,7 +366,7 @@ fn voting_cannot_lock_less_than_limit() { #[test] fn voting_locking_more_than_total_balance_is_moot() { - with_externalities(&mut ExtBuilder::default().voter_bond(2).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().voter_bond(2).build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_eq!(balances(&3), (30, 0)); @@ -382,7 +382,7 @@ fn voting_locking_more_than_total_balance_is_moot() { #[test] fn voting_locking_stake_and_reserving_bond_works() { - with_externalities(&mut ExtBuilder::default().voter_bond(2).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().voter_bond(2).build(), || { assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); assert_eq!(balances(&2), (20, 0)); @@ -408,7 +408,7 @@ fn voting_locking_stake_and_reserving_bond_works() { #[test] fn voting_without_any_candidate_count_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(1); assert_eq!(Elections::candidates().len(), 0); @@ -422,7 +422,7 @@ fn voting_without_any_candidate_count_should_not_work() { #[test] fn voting_setting_an_approval_vote_count_more_than_candidate_count_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(1); assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); @@ -437,7 +437,7 @@ fn voting_setting_an_approval_vote_count_more_than_candidate_count_should_not_wo #[test] fn voting_resubmitting_approvals_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(1); assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); @@ -456,7 +456,7 @@ fn voting_resubmitting_approvals_should_work() { #[test] fn voting_retracting_voter_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(1); assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); @@ -501,7 +501,7 @@ fn voting_retracting_voter_should_work() { #[test] fn voting_invalid_retraction_index_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(1); assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); @@ -514,7 +514,7 @@ fn voting_invalid_retraction_index_should_not_work() { #[test] fn voting_overflow_retraction_index_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(1); assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); @@ -525,7 +525,7 @@ fn voting_overflow_retraction_index_should_not_work() { #[test] fn voting_non_voter_retraction_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(1); assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); @@ -536,7 +536,7 @@ fn voting_non_voter_retraction_should_not_work() { #[test] fn retracting_inactive_voter_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); @@ -570,7 +570,7 @@ fn retracting_inactive_voter_should_work() { #[test] fn retracting_inactive_voter_with_other_candidates_in_slots_should_work() { - with_externalities(&mut ExtBuilder::default().voter_bond(2).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().voter_bond(2).build(), || { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); @@ -605,7 +605,7 @@ fn retracting_inactive_voter_with_other_candidates_in_slots_should_work() { #[test] fn retracting_inactive_voter_with_bad_reporter_index_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); @@ -634,7 +634,7 @@ fn retracting_inactive_voter_with_bad_reporter_index_should_not_work() { #[test] fn retracting_inactive_voter_with_bad_target_index_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); @@ -663,7 +663,7 @@ fn retracting_inactive_voter_with_bad_target_index_should_not_work() { #[test] fn retracting_active_voter_should_slash_reporter() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); @@ -711,7 +711,7 @@ fn retracting_active_voter_should_slash_reporter() { #[test] fn retracting_inactive_voter_by_nonvoter_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); @@ -740,7 +740,7 @@ fn retracting_inactive_voter_by_nonvoter_should_not_work() { #[test] fn candidacy_simple_candidate_submission_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(1); assert_eq!(Elections::candidates(), Vec::::new()); assert_eq!(Elections::candidate_reg_info(1), None); @@ -768,7 +768,7 @@ fn candidacy_simple_candidate_submission_should_work() { fn candidacy_submission_using_free_slot_should_work() { let mut t = new_test_ext_with_candidate_holes(); - with_externalities(&mut t, || { + set_and_run_with_externalities(&mut t, || { System::set_block_number(1); assert_eq!(Elections::candidates(), vec![0, 0, 1]); @@ -784,7 +784,7 @@ fn candidacy_submission_using_free_slot_should_work() { fn candidacy_submission_using_alternative_free_slot_should_work() { let mut t = new_test_ext_with_candidate_holes(); - with_externalities(&mut t, || { + set_and_run_with_externalities(&mut t, || { System::set_block_number(1); assert_eq!(Elections::candidates(), vec![0, 0, 1]); @@ -800,7 +800,7 @@ fn candidacy_submission_using_alternative_free_slot_should_work() { fn candidacy_submission_not_using_free_slot_should_not_work() { let mut t = new_test_ext_with_candidate_holes(); - with_externalities(&mut t, || { + set_and_run_with_externalities(&mut t, || { System::set_block_number(1); assert_noop!( Elections::submit_candidacy(Origin::signed(4), 3), @@ -811,7 +811,7 @@ fn candidacy_submission_not_using_free_slot_should_not_work() { #[test] fn candidacy_bad_candidate_slot_submission_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(1); assert_eq!(Elections::candidates(), Vec::::new()); assert_noop!( @@ -823,7 +823,7 @@ fn candidacy_bad_candidate_slot_submission_should_not_work() { #[test] fn candidacy_non_free_candidate_slot_submission_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(1); assert_eq!(Elections::candidates(), Vec::::new()); assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); @@ -837,7 +837,7 @@ fn candidacy_non_free_candidate_slot_submission_should_not_work() { #[test] fn candidacy_dupe_candidate_submission_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(1); assert_eq!(Elections::candidates(), Vec::::new()); assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); @@ -851,7 +851,7 @@ fn candidacy_dupe_candidate_submission_should_not_work() { #[test] fn candidacy_poor_candidate_submission_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(1); assert_eq!(Elections::candidates(), Vec::::new()); assert_noop!( @@ -863,7 +863,7 @@ fn candidacy_poor_candidate_submission_should_not_work() { #[test] fn election_voting_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(1); assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); @@ -892,7 +892,7 @@ fn election_voting_should_work() { #[test] fn election_proxy_voting_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(1); assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); @@ -933,7 +933,7 @@ fn election_proxy_voting_should_work() { #[test] fn election_simple_tally_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(4); assert!(!Elections::presentation_active()); @@ -972,7 +972,7 @@ fn election_simple_tally_should_work() { #[test] fn election_seats_should_be_released() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); @@ -1006,7 +1006,7 @@ fn election_seats_should_be_released() { #[test] fn election_presentations_with_zero_staked_deposit_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); @@ -1022,7 +1022,7 @@ fn election_presentations_with_zero_staked_deposit_should_not_work() { #[test] fn election_double_presentations_should_be_punished() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert!(Balances::can_slash(&4, 10)); System::set_block_number(4); @@ -1045,7 +1045,7 @@ fn election_double_presentations_should_be_punished() { #[test] fn election_presenting_for_double_election_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(4); assert_eq!(Elections::submit_candidacy(Origin::signed(2), 0), Ok(())); assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); @@ -1072,7 +1072,7 @@ fn election_presenting_for_double_election_should_not_work() { #[test] fn election_presenting_loser_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0, 60)); @@ -1105,7 +1105,7 @@ fn election_presenting_loser_should_not_work() { #[test] fn election_presenting_loser_first_should_not_matter() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0, 60)); @@ -1137,7 +1137,7 @@ fn election_presenting_loser_first_should_not_matter() { #[test] fn election_present_outside_of_presentation_period_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(4); assert!(!Elections::presentation_active()); assert_noop!( @@ -1149,7 +1149,7 @@ fn election_present_outside_of_presentation_period_should_not_work() { #[test] fn election_present_with_invalid_vote_index_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); @@ -1165,7 +1165,7 @@ fn election_present_with_invalid_vote_index_should_not_work() { #[test] fn election_present_when_presenter_is_poor_should_not_work() { let test_present = |p| { - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .voting_fee(5) .voter_bond(2) .bad_presentation_punishment(p) @@ -1199,7 +1199,7 @@ fn election_present_when_presenter_is_poor_should_not_work() { #[test] fn election_invalid_present_tally_should_slash() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(4); assert!(!Elections::presentation_active()); assert_eq!(Balances::total_balance(&4), 40); @@ -1219,7 +1219,7 @@ fn election_invalid_present_tally_should_slash() { #[test] fn election_runners_up_should_be_kept() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(4); assert!(!Elections::presentation_active()); @@ -1280,7 +1280,7 @@ fn election_runners_up_should_be_kept() { #[test] fn election_second_tally_should_use_runners_up() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0, 60)); @@ -1335,7 +1335,7 @@ fn election_second_tally_should_use_runners_up() { #[test] fn election_loser_candidates_bond_gets_slashed() { - with_externalities(&mut ExtBuilder::default().desired_seats(1).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().desired_seats(1).build(), || { System::set_block_number(4); assert!(!Elections::presentation_active()); @@ -1374,7 +1374,7 @@ fn election_loser_candidates_bond_gets_slashed() { #[test] fn pot_accumulating_weight_and_decaying_should_work() { - with_externalities(&mut ExtBuilder::default().balance_factor(10).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().balance_factor(10).build(), || { System::set_block_number(4); assert!(!Elections::presentation_active()); @@ -1502,7 +1502,7 @@ fn pot_accumulating_weight_and_decaying_should_work() { #[test] fn pot_winning_resets_accumulated_pot() { - with_externalities(&mut ExtBuilder::default().balance_factor(10).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().balance_factor(10).build(), || { System::set_block_number(4); assert!(!Elections::presentation_active()); @@ -1564,7 +1564,7 @@ fn pot_winning_resets_accumulated_pot() { #[test] fn pot_resubmitting_approvals_stores_pot() { - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .voter_bond(0) .voting_fee(0) .balance_factor(10) @@ -1629,7 +1629,7 @@ fn pot_resubmitting_approvals_stores_pot() { #[test] fn pot_get_offset_should_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_eq!(Elections::get_offset(100, 0), 0); assert_eq!(Elections::get_offset(100, 1), 96); assert_eq!(Elections::get_offset(100, 2), 96 + 93); @@ -1653,7 +1653,7 @@ fn pot_get_offset_should_work() { #[test] fn pot_get_offset_with_zero_decay() { - with_externalities(&mut ExtBuilder::default().decay_ratio(0).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().decay_ratio(0).build(), || { assert_eq!(Elections::get_offset(100, 0), 0); assert_eq!(Elections::get_offset(100, 1), 0); assert_eq!(Elections::get_offset(100, 2), 0); diff --git a/srml/example/src/lib.rs b/srml/example/src/lib.rs index ef8eead7ba..08adf9efa7 100644 --- a/srml/example/src/lib.rs +++ b/srml/example/src/lib.rs @@ -634,15 +634,12 @@ mod tests { use super::*; use support::{assert_ok, impl_outer_origin, parameter_types}; - use runtime_io::with_externalities; - use primitives::{H256, Blake2Hasher}; + use primitives::H256; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sr_primitives::{ - Perbill, + set_and_run_with_externalities, Perbill, weights::GetDispatchInfo, testing::Header, traits::{BlakeTwo256, OnInitialize, OnFinalize, IdentityLookup}, - weights::GetDispatchInfo, - testing::Header }; impl_outer_origin! { @@ -707,7 +704,7 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); // We use default for brevity, but you can configure as desired if needed. balances::GenesisConfig::::default().assimilate_storage(&mut t).unwrap(); @@ -722,7 +719,7 @@ mod tests { #[test] fn it_works_for_optional_value() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // Check that GenesisBuilder works properly. assert_eq!(Example::dummy(), Some(42)); @@ -743,7 +740,7 @@ mod tests { #[test] fn it_works_for_default_value() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_eq!(Example::foo(), 24); assert_ok!(Example::accumulate_foo(Origin::signed(1), 1)); assert_eq!(Example::foo(), 25); @@ -752,7 +749,7 @@ mod tests { #[test] fn signed_ext_watch_dummy_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let call = >::set_dummy(10); let info = DispatchInfo::default(); diff --git a/srml/executive/src/lib.rs b/srml/executive/src/lib.rs index ee11ffadf4..f1509f1760 100644 --- a/srml/executive/src/lib.rs +++ b/srml/executive/src/lib.rs @@ -293,12 +293,12 @@ where #[cfg(test)] mod tests { use super::*; - use runtime_io::with_externalities; - use primitives::{H256, Blake2Hasher}; + use primitives::H256; use sr_primitives::{ generic::Era, Perbill, DispatchError, weights::Weight, testing::{Digest, Header, Block}, traits::{Bounded, Header as HeaderT, BlakeTwo256, IdentityLookup, ConvertInto}, transaction_validity::{InvalidTransaction, UnknownTransaction}, ApplyError, + set_and_run_with_externalities, }; use support::{ impl_outer_event, impl_outer_origin, parameter_types, impl_outer_dispatch, @@ -419,8 +419,8 @@ mod tests { }.assimilate_storage(&mut t).unwrap(); let xt = sr_primitives::testing::TestXt(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(2, 69))); let weight = xt.get_dispatch_info().weight as u64; - let mut t = runtime_io::TestExternalities::::new(t); - with_externalities(&mut t, || { + let mut t = runtime_io::TestExternalities::new(t); + set_and_run_with_externalities(&mut t, || { Executive::initialize_block(&Header::new( 1, H256::default(), @@ -435,7 +435,7 @@ mod tests { }); } - fn new_test_ext(balance_factor: u64) -> runtime_io::TestExternalities { + fn new_test_ext(balance_factor: u64) -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); balances::GenesisConfig:: { balances: vec![(1, 111 * balance_factor)], @@ -446,7 +446,7 @@ mod tests { #[test] fn block_import_works() { - with_externalities(&mut new_test_ext(1), || { + set_and_run_with_externalities(&mut new_test_ext(1), || { Executive::execute_block(Block { header: Header { parent_hash: [69u8; 32].into(), @@ -463,7 +463,7 @@ mod tests { #[test] #[should_panic] fn block_import_of_bad_state_root_fails() { - with_externalities(&mut new_test_ext(1), || { + set_and_run_with_externalities(&mut new_test_ext(1), || { Executive::execute_block(Block { header: Header { parent_hash: [69u8; 32].into(), @@ -480,7 +480,7 @@ mod tests { #[test] #[should_panic] fn block_import_of_bad_extrinsic_root_fails() { - with_externalities(&mut new_test_ext(1), || { + set_and_run_with_externalities(&mut new_test_ext(1), || { Executive::execute_block(Block { header: Header { parent_hash: [69u8; 32].into(), @@ -499,7 +499,7 @@ mod tests { let mut t = new_test_ext(1); // bad nonce check! let xt = sr_primitives::testing::TestXt(sign_extra(1, 30, 0), Call::Balances(BalancesCall::transfer(33, 69))); - with_externalities(&mut t, || { + set_and_run_with_externalities(&mut t, || { Executive::initialize_block(&Header::new( 1, H256::default(), @@ -521,7 +521,7 @@ mod tests { let encoded_len = encoded.len() as Weight; let limit = AvailableBlockRatio::get() * MaximumBlockWeight::get(); let num_to_exhaust_block = limit / encoded_len; - with_externalities(&mut t, || { + set_and_run_with_externalities(&mut t, || { Executive::initialize_block(&Header::new( 1, H256::default(), @@ -557,7 +557,7 @@ mod tests { let x2 = sr_primitives::testing::TestXt(sign_extra(1, 2, 0), Call::Balances(BalancesCall::transfer(33, 0))); let len = xt.clone().encode().len() as u32; let mut t = new_test_ext(1); - with_externalities(&mut t, || { + set_and_run_with_externalities(&mut t, || { assert_eq!(>::all_extrinsics_weight(), 0); assert_eq!(>::all_extrinsics_weight(), 0); @@ -581,7 +581,7 @@ mod tests { let xt = sr_primitives::testing::TestXt(None, Call::Balances(BalancesCall::set_balance(33, 69, 69))); let mut t = new_test_ext(1); - with_externalities(&mut t, || { + set_and_run_with_externalities(&mut t, || { assert_eq!(Executive::validate_transaction(xt.clone()), Ok(Default::default())); assert_eq!( Executive::apply_extrinsic(xt), @@ -599,7 +599,7 @@ mod tests { let id: LockIdentifier = *b"0 "; let execute_with_lock = |lock: WithdrawReasons| { let mut t = new_test_ext(1); - with_externalities(&mut t, || { + set_and_run_with_externalities(&mut t, || { as LockableCurrency>::set_lock( id, &1, diff --git a/srml/finality-tracker/src/lib.rs b/srml/finality-tracker/src/lib.rs index 1bf9754b0a..f00762fcdf 100644 --- a/srml/finality-tracker/src/lib.rs +++ b/srml/finality-tracker/src/lib.rs @@ -247,11 +247,12 @@ impl ProvideInherent for Module { mod tests { use super::*; - use runtime_io::{with_externalities, TestExternalities}; + use runtime_io::TestExternalities; use primitives::H256; - use sr_primitives::traits::{BlakeTwo256, IdentityLookup, OnFinalize, Header as HeaderT}; - use sr_primitives::testing::Header; - use sr_primitives::Perbill; + use sr_primitives::{ + set_and_run_with_externalities, testing::Header, Perbill, + traits::{BlakeTwo256, IdentityLookup, OnFinalize, Header as HeaderT}, + }; use support::{assert_ok, impl_outer_origin, parameter_types}; use srml_system as system; use std::cell::RefCell; @@ -321,7 +322,7 @@ mod tests { #[test] fn median_works() { let t = system::GenesisConfig::default().build_storage::().unwrap(); - with_externalities(&mut TestExternalities::new(t), || { + set_and_run_with_externalities(&mut TestExternalities::new(t), || { FinalityTracker::update_hint(Some(500)); assert_eq!(FinalityTracker::median(), 250); assert!(NOTIFICATIONS.with(|n| n.borrow().is_empty())); @@ -331,7 +332,7 @@ mod tests { #[test] fn notifies_when_stalled() { let t = system::GenesisConfig::default().build_storage::().unwrap(); - with_externalities(&mut TestExternalities::new(t), || { + set_and_run_with_externalities(&mut TestExternalities::new(t), || { let mut parent_hash = System::parent_hash(); for i in 2..106 { System::initialize(&i, &parent_hash, &Default::default(), &Default::default()); @@ -350,7 +351,7 @@ mod tests { #[test] fn recent_notifications_prevent_stalling() { let t = system::GenesisConfig::default().build_storage::().unwrap(); - with_externalities(&mut TestExternalities::new(t), || { + set_and_run_with_externalities(&mut TestExternalities::new(t), || { let mut parent_hash = System::parent_hash(); for i in 2..106 { System::initialize(&i, &parent_hash, &Default::default(), &Default::default()); diff --git a/srml/generic-asset/src/mock.rs b/srml/generic-asset/src/mock.rs index 7e47de0b36..c0f9f154b8 100644 --- a/srml/generic-asset/src/mock.rs +++ b/srml/generic-asset/src/mock.rs @@ -25,7 +25,7 @@ use sr_primitives::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, }; -use primitives::{Blake2Hasher, H256}; +use primitives::H256; use support::{parameter_types, impl_outer_event, impl_outer_origin}; use super::*; @@ -118,7 +118,7 @@ impl ExtBuilder { } // builds genesis config - pub fn build(self) -> runtime_io::TestExternalities { + pub fn build(self) -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); GenesisConfig:: { @@ -137,7 +137,7 @@ impl ExtBuilder { // This function basically just builds a genesis storage key/value store according to // our desired mockup. -pub fn new_test_ext() -> runtime_io::TestExternalities { +pub fn new_test_ext() -> runtime_io::TestExternalities { system::GenesisConfig::default() .build_storage::() .unwrap() diff --git a/srml/generic-asset/src/tests.rs b/srml/generic-asset/src/tests.rs index 685e553c1c..90e5775828 100644 --- a/srml/generic-asset/src/tests.rs +++ b/srml/generic-asset/src/tests.rs @@ -22,14 +22,14 @@ use super::*; use crate::mock::{new_test_ext, ExtBuilder, GenericAsset, Origin, System, Test, TestEvent}; -use runtime_io::with_externalities; +use sr_primitives::set_and_run_with_externalities; use support::{assert_noop, assert_ok}; #[test] fn issuing_asset_units_to_issuer_should_work() { let balance = 100; - with_externalities(&mut ExtBuilder::default().free_balance((16000, 1, 100)).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((16000, 1, 100)).build(), || { let default_permission = PermissionLatest { update: Owner::Address(1), mint: Owner::Address(1), @@ -51,7 +51,7 @@ fn issuing_asset_units_to_issuer_should_work() { #[test] fn issuing_with_next_asset_id_overflow_should_not_work() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), || { NextAssetId::::put(u32::max_value()); @@ -79,7 +79,7 @@ fn issuing_with_next_asset_id_overflow_should_not_work() { fn querying_total_supply_should_work() { let asset_id = 1000; - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), || { let default_permission = PermissionLatest { @@ -127,7 +127,7 @@ fn querying_total_supply_should_work() { fn transferring_amount_should_work() { let asset_id = 1000; let free_balance = 100; - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), || { let default_permission = PermissionLatest { @@ -168,7 +168,7 @@ fn transferring_amount_should_work() { #[test] fn transferring_amount_should_fail_when_transferring_more_than_free_balance() { let asset_id = 1000; - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), || { let default_permission = PermissionLatest { @@ -195,7 +195,7 @@ fn transferring_amount_should_fail_when_transferring_more_than_free_balance() { fn transferring_less_than_one_unit_should_not_work() { let asset_id = 1000; - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), || { let default_permission = PermissionLatest { @@ -233,7 +233,7 @@ fn self_transfer_should_fail() { let asset_id = 1000; let balance = 100; - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), || { let default_permission = PermissionLatest { @@ -259,7 +259,7 @@ fn self_transfer_should_fail() { #[test] fn transferring_more_units_than_total_supply_should_not_work() { let asset_id = 1000; - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), || { let default_permission = PermissionLatest { @@ -286,7 +286,7 @@ fn transferring_more_units_than_total_supply_should_not_work() { // Ensures it uses fake money for staking asset id. #[test] fn staking_asset_id_should_return_0() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_eq!(GenericAsset::staking_asset_id(), 16000); }); } @@ -294,7 +294,7 @@ fn staking_asset_id_should_return_0() { // Ensures it uses fake money for spending asset id. #[test] fn spending_asset_id_should_return_10() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_eq!(GenericAsset::spending_asset_id(), 16001); }); } @@ -305,7 +305,7 @@ fn spending_asset_id_should_return_10() { // -Â total_balance should return 0 #[test] fn total_balance_should_be_zero() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_eq!(GenericAsset::total_balance(&0, &0), 0); }); } @@ -323,7 +323,7 @@ fn total_balance_should_be_equal_to_account_balance() { mint: Owner::Address(1), burn: Owner::Address(1), }; - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), || { assert_ok!(GenericAsset::create( @@ -348,7 +348,7 @@ fn total_balance_should_be_equal_to_account_balance() { // -Â free_balance should return 50. #[test] fn free_balance_should_only_return_account_free_balance() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 50)).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 50)).build(), || { GenericAsset::set_reserved_balance(&1, &0, 70); assert_eq!(GenericAsset::free_balance(&1, &0), 50); }); @@ -363,7 +363,7 @@ fn free_balance_should_only_return_account_free_balance() { // -Â total_balance should equals to account balance + free balance. #[test] fn total_balance_should_be_equal_to_sum_of_account_balance_and_free_balance() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 50)).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 50)).build(), || { GenericAsset::set_reserved_balance(&1, &0, 70); assert_eq!(GenericAsset::total_balance(&1, &0), 120); }); @@ -378,7 +378,7 @@ fn total_balance_should_be_equal_to_sum_of_account_balance_and_free_balance() { // - reserved_balance should return 70. #[test] fn reserved_balance_should_only_return_account_reserved_balance() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 50)).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 50)).build(), || { GenericAsset::set_reserved_balance(&1, &0, 70); assert_eq!(GenericAsset::reserved_balance(&1, &0), 70); }); @@ -394,7 +394,7 @@ fn reserved_balance_should_only_return_account_reserved_balance() { // - reserved_balance = amount #[test] fn set_reserved_balance_should_add_balance_as_reserved() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { GenericAsset::set_reserved_balance(&1, &0, 50); assert_eq!(GenericAsset::reserved_balance(&1, &0), 50); }); @@ -410,7 +410,7 @@ fn set_reserved_balance_should_add_balance_as_reserved() { // - New free_balance should replace older free_balance. #[test] fn set_free_balance_should_add_amount_as_free_balance() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { GenericAsset::set_free_balance(&1, &0, 50); assert_eq!(GenericAsset::free_balance(&1, &0), 50); }); @@ -429,7 +429,7 @@ fn set_free_balance_should_add_amount_as_free_balance() { // - new reserved_balance = original free balance + reserved amount #[test] fn reserve_should_moves_amount_from_balance_to_reserved_balance() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { assert_ok!(GenericAsset::reserve(&1, &0, 70)); assert_eq!(GenericAsset::free_balance(&1, &0), 30); assert_eq!(GenericAsset::reserved_balance(&1, &0), 70); @@ -448,7 +448,7 @@ fn reserve_should_moves_amount_from_balance_to_reserved_balance() { // - Should throw an error. #[test] fn reserve_should_not_moves_amount_from_balance_to_reserved_balance() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { assert_noop!(GenericAsset::reserve(&1, &0, 120), "not enough free funds"); assert_eq!(GenericAsset::free_balance(&1, &0), 100); assert_eq!(GenericAsset::reserved_balance(&1, &0), 0); @@ -466,7 +466,7 @@ fn reserve_should_not_moves_amount_from_balance_to_reserved_balance() { // - unreserved should return 20. #[test] fn unreserve_should_return_substratced_value_from_unreserved_amount_by_actual_acount_balance() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::unreserve(&1, &0, 120), 20); }); @@ -483,7 +483,7 @@ fn unreserve_should_return_substratced_value_from_unreserved_amount_by_actual_ac // - unreserved should return None. #[test] fn unreserve_should_return_none() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::unreserve(&1, &0, 50), 0); }); @@ -500,7 +500,7 @@ fn unreserve_should_return_none() { // - free_balance should be 200. #[test] fn unreserve_should_increase_free_balance_by_reserved_balance() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { GenericAsset::set_reserved_balance(&1, &0, 100); GenericAsset::unreserve(&1, &0, 120); assert_eq!(GenericAsset::free_balance(&1, &0), 200); @@ -518,7 +518,7 @@ fn unreserve_should_increase_free_balance_by_reserved_balance() { // - reserved_balance should be 0. #[test] fn unreserve_should_deduct_reserved_balance_by_reserved_amount() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { GenericAsset::set_free_balance(&1, &0, 100); GenericAsset::unreserve(&1, &0, 120); assert_eq!(GenericAsset::reserved_balance(&1, &0), 0); @@ -536,7 +536,7 @@ fn unreserve_should_deduct_reserved_balance_by_reserved_amount() { // - slash should return None. #[test] fn slash_should_return_slash_reserved_amount() { - with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::slash(&1, &0, 70), None); }); @@ -550,7 +550,7 @@ fn slash_should_return_slash_reserved_amount() { // - Should return slashed_reserved - reserved_balance. #[test] fn slash_reserved_should_deducts_up_to_amount_from_reserved_balance() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::slash_reserved(&1, &0, 150), Some(50)); }); @@ -564,7 +564,7 @@ fn slash_reserved_should_deducts_up_to_amount_from_reserved_balance() { // - Should return None. #[test] fn slash_reserved_should_return_none() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::slash_reserved(&1, &0, 100), None); }); @@ -579,7 +579,7 @@ fn slash_reserved_should_return_none() { // - Should not return None. #[test] fn repatriate_reserved_return_amount_substracted_by_slash_amount() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::repatriate_reserved(&1, &0, &1, 130), 30); }); @@ -594,7 +594,7 @@ fn repatriate_reserved_return_amount_substracted_by_slash_amount() { // - Should return None. #[test] fn repatriate_reserved_return_none() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::repatriate_reserved(&1, &0, &1, 90), 0); }); @@ -608,7 +608,7 @@ fn repatriate_reserved_return_none() { // - Should create a new reserved asset. #[test] fn create_reserved_should_create_a_default_account_with_the_balance_given() { - with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { let default_permission = PermissionLatest { update: Owner::Address(1), mint: Owner::Address(1), @@ -643,7 +643,7 @@ fn create_reserved_should_create_a_default_account_with_the_balance_given() { // - Should throw a permission error #[test] fn mint_should_throw_permission_error() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { let origin = 1; let asset_id = 4; let to_account = 2; @@ -666,7 +666,7 @@ fn mint_should_throw_permission_error() { // - Should not change `origins` free_balance. #[test] fn mint_should_increase_asset() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), || { let origin = 1; @@ -707,7 +707,7 @@ fn mint_should_increase_asset() { // - Should throw a permission error. #[test] fn burn_should_throw_permission_error() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), || { let origin = 1; @@ -733,7 +733,7 @@ fn burn_should_throw_permission_error() { // - Should not change `origin`'s free_balance. #[test] fn burn_should_burn_an_asset() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), || { let origin = 1; @@ -779,7 +779,7 @@ fn burn_should_burn_an_asset() { // - The account origin should have burn, mint and update permissions. #[test] fn check_permission_should_return_correct_permission() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), || { let origin = 1; @@ -825,7 +825,7 @@ fn check_permission_should_return_correct_permission() { // - The account origin should not have burn, mint and update permissions. #[test] fn check_permission_should_return_false_for_no_permission() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), || { let origin = 1; @@ -871,7 +871,7 @@ fn check_permission_should_return_false_for_no_permission() { // - The account origin should have update and mint permissions. #[test] fn update_permission_should_change_permission() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), || { let origin = 1; @@ -923,7 +923,7 @@ fn update_permission_should_change_permission() { // - Should throw an error stating "Origin does not have enough permission to update permissions." #[test] fn update_permission_should_throw_error_when_lack_of_permissions() { - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), || { let origin = 1; @@ -974,7 +974,7 @@ fn update_permission_should_throw_error_when_lack_of_permissions() { // - Permissions must have burn, mint and updatePermission for the given asset_id. #[test] fn create_asset_works_with_given_asset_id_and_from_account() { - with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { let origin = 1; let from_account: Option<::AccountId> = Some(1); @@ -1011,7 +1011,7 @@ fn create_asset_works_with_given_asset_id_and_from_account() { // - `create_asset` should not work. #[test] fn create_asset_with_non_reserved_asset_id_should_not_work() { - with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { let origin = 1; let from_account: Option<::AccountId> = Some(1); @@ -1045,7 +1045,7 @@ fn create_asset_with_non_reserved_asset_id_should_not_work() { // - `create_asset` should not work. #[test] fn create_asset_with_a_taken_asset_id_should_not_work() { - with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { let origin = 1; let from_account: Option<::AccountId> = Some(1); @@ -1090,7 +1090,7 @@ fn create_asset_with_a_taken_asset_id_should_not_work() { // - Should create a reserved token. #[test] fn create_asset_should_create_a_reserved_asset_when_from_account_is_none() { - with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { let origin = 1; let from_account: Option<::AccountId> = None; @@ -1133,7 +1133,7 @@ fn create_asset_should_create_a_reserved_asset_when_from_account_is_none() { // - Should not create a `reserved_asset`. #[test] fn create_asset_should_create_a_user_asset() { - with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { let origin = 1; let from_account: Option<::AccountId> = None; @@ -1180,7 +1180,7 @@ fn update_permission_should_raise_event() { burn: Owner::Address(origin), }; - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default() .next_asset_id(asset_id) .free_balance((staking_asset_id, origin, initial_balance)) @@ -1223,7 +1223,7 @@ fn mint_should_raise_event() { let to = 2; let amount = 100; - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default() .next_asset_id(asset_id) .free_balance((staking_asset_id, origin, initial_balance)) @@ -1262,7 +1262,7 @@ fn burn_should_raise_event() { }; let amount = 100; - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default() .next_asset_id(asset_id) .free_balance((staking_asset_id, origin, initial_balance)) diff --git a/srml/grandpa/src/mock.rs b/srml/grandpa/src/mock.rs index af2fedf42f..8d585e4b46 100644 --- a/srml/grandpa/src/mock.rs +++ b/srml/grandpa/src/mock.rs @@ -21,7 +21,7 @@ use sr_primitives::{Perbill, DigestItem, traits::IdentityLookup, testing::{Header, UintAuthorityId}}; use runtime_io; use support::{impl_outer_origin, impl_outer_event, parameter_types}; -use primitives::{H256, Blake2Hasher}; +use primitives::H256; use codec::{Encode, Decode}; use crate::{AuthorityId, GenesisConfig, Trait, Module, ConsensusLog}; use substrate_finality_grandpa_primitives::GRANDPA_ENGINE_ID; @@ -82,7 +82,7 @@ pub fn to_authorities(vec: Vec<(u64, u64)>) -> Vec<(AuthorityId, u64)> { .collect() } -pub fn new_test_ext(authorities: Vec<(u64, u64)>) -> runtime_io::TestExternalities { +pub fn new_test_ext(authorities: Vec<(u64, u64)>) -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); GenesisConfig { authorities: to_authorities(authorities), diff --git a/srml/grandpa/src/tests.rs b/srml/grandpa/src/tests.rs index 41229a5136..aec75d274c 100644 --- a/srml/grandpa/src/tests.rs +++ b/srml/grandpa/src/tests.rs @@ -18,9 +18,7 @@ #![cfg(test)] -use sr_primitives::testing::Digest; -use sr_primitives::traits::{Header, OnFinalize}; -use runtime_io::with_externalities; +use sr_primitives::{set_and_run_with_externalities, testing::Digest, traits::{Header, OnFinalize}}; use crate::mock::*; use system::{EventRecord, Phase}; use codec::{Decode, Encode}; @@ -29,7 +27,7 @@ use super::*; #[test] fn authorities_change_logged() { - with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + set_and_run_with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { System::initialize(&1, &Default::default(), &Default::default(), &Default::default()); Grandpa::schedule_change(to_authorities(vec![(4, 1), (5, 1), (6, 1)]), 0, None).unwrap(); @@ -57,7 +55,7 @@ fn authorities_change_logged() { #[test] fn authorities_change_logged_after_delay() { - with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + set_and_run_with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { System::initialize(&1, &Default::default(), &Default::default(), &Default::default()); Grandpa::schedule_change(to_authorities(vec![(4, 1), (5, 1), (6, 1)]), 1, None).unwrap(); Grandpa::on_finalize(1); @@ -90,7 +88,7 @@ fn authorities_change_logged_after_delay() { #[test] fn cannot_schedule_change_when_one_pending() { - with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + set_and_run_with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { System::initialize(&1, &Default::default(), &Default::default(), &Default::default()); Grandpa::schedule_change(to_authorities(vec![(4, 1), (5, 1), (6, 1)]), 1, None).unwrap(); assert!(>::exists()); @@ -133,7 +131,7 @@ fn new_decodes_from_old() { #[test] fn dispatch_forced_change() { - with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + set_and_run_with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { System::initialize(&1, &Default::default(), &Default::default(), &Default::default()); Grandpa::schedule_change( to_authorities(vec![(4, 1), (5, 1), (6, 1)]), @@ -205,7 +203,7 @@ fn dispatch_forced_change() { #[test] fn schedule_pause_only_when_live() { - with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + set_and_run_with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { // we schedule a pause at block 1 with delay of 1 System::initialize(&1, &Default::default(), &Default::default(), &Default::default()); Grandpa::schedule_pause(1).unwrap(); @@ -240,7 +238,7 @@ fn schedule_pause_only_when_live() { #[test] fn schedule_resume_only_when_paused() { - with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + set_and_run_with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { System::initialize(&1, &Default::default(), &Default::default(), &Default::default()); // the set is currently live, resuming it is an error diff --git a/srml/im-online/src/mock.rs b/srml/im-online/src/mock.rs index a7b669ddb8..c2869136dc 100644 --- a/srml/im-online/src/mock.rs +++ b/srml/im-online/src/mock.rs @@ -25,7 +25,7 @@ use sr_primitives::Perbill; use sr_staking_primitives::{SessionIndex, offence::ReportOffence}; use sr_primitives::testing::{Header, UintAuthorityId, TestXt}; use sr_primitives::traits::{IdentityLookup, BlakeTwo256, ConvertInto}; -use primitives::{H256, Blake2Hasher}; +use primitives::H256; use support::{impl_outer_origin, impl_outer_dispatch, parameter_types}; use {runtime_io, system}; @@ -85,7 +85,7 @@ impl ReportOffence for OffenceHandler { } } -pub fn new_test_ext() -> runtime_io::TestExternalities { +pub fn new_test_ext() -> runtime_io::TestExternalities { let t = system::GenesisConfig::default().build_storage::().unwrap(); t.into() } diff --git a/srml/im-online/src/tests.rs b/srml/im-online/src/tests.rs index c6405c34fa..d57b9f59cb 100644 --- a/srml/im-online/src/tests.rs +++ b/srml/im-online/src/tests.rs @@ -21,10 +21,9 @@ use super::*; use crate::mock::*; use offchain::testing::TestOffchainExt; -use primitives::offchain::OpaquePeerId; -use runtime_io::with_externalities; +use primitives::offchain::{OpaquePeerId, OffchainExt}; use support::{dispatch, assert_noop}; -use sr_primitives::testing::UintAuthorityId; +use sr_primitives::{set_and_run_with_externalities, testing::UintAuthorityId}; #[test] @@ -49,7 +48,7 @@ fn test_unresponsiveness_slash_fraction() { #[test] fn should_report_offline_validators() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // given let block = 1; System::set_block_number(block); @@ -125,7 +124,7 @@ fn heartbeat( #[test] fn should_mark_online_validator_when_heartbeat_is_received() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { advance_session(); // given VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 3, 4, 5, 6])); @@ -160,7 +159,7 @@ fn should_mark_online_validator_when_heartbeat_is_received() { #[test] fn late_heartbeat_should_fail() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { advance_session(); // given VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 4, 4, 5, 6])); @@ -181,9 +180,9 @@ fn late_heartbeat_should_fail() { fn should_generate_heartbeats() { let mut ext = new_test_ext(); let (offchain, state) = TestOffchainExt::new(); - ext.set_offchain_externalities(offchain); + ext.register_extension(OffchainExt::new(offchain)); - with_externalities(&mut ext, || { + set_and_run_with_externalities(&mut ext, || { // given let block = 1; System::set_block_number(block); @@ -219,7 +218,7 @@ fn should_generate_heartbeats() { #[test] fn should_cleanup_received_heartbeats_on_session_end() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { advance_session(); VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 3])); diff --git a/srml/indices/src/mock.rs b/srml/indices/src/mock.rs index 65a0193b5a..59d84279a9 100644 --- a/srml/indices/src/mock.rs +++ b/srml/indices/src/mock.rs @@ -22,7 +22,7 @@ use std::collections::HashSet; use ref_thread_local::{ref_thread_local, RefThreadLocal}; use sr_primitives::testing::Header; use sr_primitives::Perbill; -use primitives::{H256, Blake2Hasher}; +use primitives::H256; use support::{impl_outer_origin, parameter_types}; use {runtime_io, system}; use crate::{GenesisConfig, Module, Trait, IsDeadAccount, OnNewAccount, ResolveHint}; @@ -96,7 +96,7 @@ impl Trait for Runtime { type Event = (); } -pub fn new_test_ext() -> runtime_io::TestExternalities { +pub fn new_test_ext() -> runtime_io::TestExternalities { { let mut h = ALIVE.borrow_mut(); h.clear(); diff --git a/srml/indices/src/tests.rs b/srml/indices/src/tests.rs index 7b60e30527..4b8f1822b4 100644 --- a/srml/indices/src/tests.rs +++ b/srml/indices/src/tests.rs @@ -20,11 +20,11 @@ use super::*; use crate::mock::{Indices, new_test_ext, make_account, kill_account, TestIsDeadAccount}; -use runtime_io::with_externalities; +use sr_primitives::set_and_run_with_externalities; #[test] fn indexing_lookup_should_work() { - with_externalities( + set_and_run_with_externalities( &mut new_test_ext(), || { assert_eq!(Indices::lookup_index(0), Some(1)); @@ -38,7 +38,7 @@ fn indexing_lookup_should_work() { #[test] fn default_indexing_on_new_accounts_should_work() { - with_externalities( + set_and_run_with_externalities( &mut new_test_ext(), || { assert_eq!(Indices::lookup_index(4), None); @@ -50,7 +50,7 @@ fn default_indexing_on_new_accounts_should_work() { #[test] fn reclaim_indexing_on_new_accounts_should_work() { - with_externalities( + set_and_run_with_externalities( &mut new_test_ext(), || { assert_eq!(Indices::lookup_index(1), Some(2)); @@ -66,7 +66,7 @@ fn reclaim_indexing_on_new_accounts_should_work() { #[test] fn alive_account_should_prevent_reclaim() { - with_externalities( + set_and_run_with_externalities( &mut new_test_ext(), || { assert!(!TestIsDeadAccount::is_dead_account(&2)); diff --git a/srml/membership/src/lib.rs b/srml/membership/src/lib.rs index 87e9268bd9..1a6ca82986 100644 --- a/srml/membership/src/lib.rs +++ b/srml/membership/src/lib.rs @@ -193,12 +193,12 @@ mod tests { use std::cell::RefCell; use support::{assert_ok, assert_noop, impl_outer_origin, parameter_types}; - use runtime_io::with_externalities; - use primitives::{H256, Blake2Hasher}; + use primitives::H256; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried. use sr_primitives::{ - Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header + Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header, + set_and_run_with_externalities, }; use system::EnsureSignedBy; @@ -281,7 +281,7 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); // We use default for brevity, but you can configure as desired if needed. GenesisConfig::{ @@ -293,7 +293,7 @@ mod tests { #[test] fn query_membership_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_eq!(Membership::members(), vec![10, 20, 30]); assert_eq!(MEMBERS.with(|m| m.borrow().clone()), vec![10, 20, 30]); }); @@ -301,7 +301,7 @@ mod tests { #[test] fn add_member_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_noop!(Membership::add_member(Origin::signed(5), 15), "bad origin"); assert_noop!(Membership::add_member(Origin::signed(1), 10), "already a member"); assert_ok!(Membership::add_member(Origin::signed(1), 15)); @@ -312,7 +312,7 @@ mod tests { #[test] fn remove_member_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_noop!(Membership::remove_member(Origin::signed(5), 20), "bad origin"); assert_noop!(Membership::remove_member(Origin::signed(2), 15), "not a member"); assert_ok!(Membership::remove_member(Origin::signed(2), 20)); @@ -323,7 +323,7 @@ mod tests { #[test] fn swap_member_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_noop!(Membership::swap_member(Origin::signed(5), 10, 25), "bad origin"); assert_noop!(Membership::swap_member(Origin::signed(3), 15, 25), "not a member"); assert_noop!(Membership::swap_member(Origin::signed(3), 10, 30), "already a member"); @@ -337,7 +337,7 @@ mod tests { #[test] fn reset_members_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_noop!(Membership::reset_members(Origin::signed(1), vec![20, 40, 30]), "bad origin"); assert_ok!(Membership::reset_members(Origin::signed(4), vec![20, 40, 30])); assert_eq!(Membership::members(), vec![20, 30, 40]); diff --git a/srml/offences/src/mock.rs b/srml/offences/src/mock.rs index e7280c34e9..01891ce32b 100644 --- a/srml/offences/src/mock.rs +++ b/srml/offences/src/mock.rs @@ -28,7 +28,7 @@ use sr_staking_primitives::{ }; use sr_primitives::testing::Header; use sr_primitives::traits::{IdentityLookup, BlakeTwo256}; -use substrate_primitives::{H256, Blake2Hasher}; +use substrate_primitives::H256; use support::{impl_outer_origin, impl_outer_event, parameter_types, StorageMap, StorageDoubleMap}; use {runtime_io, system}; @@ -103,7 +103,7 @@ impl_outer_event! { } } -pub fn new_test_ext() -> runtime_io::TestExternalities { +pub fn new_test_ext() -> runtime_io::TestExternalities { let t = system::GenesisConfig::default().build_storage::().unwrap(); t.into() } diff --git a/srml/offences/src/tests.rs b/srml/offences/src/tests.rs index 17f933b8e8..7604533ba5 100644 --- a/srml/offences/src/tests.rs +++ b/srml/offences/src/tests.rs @@ -24,11 +24,11 @@ use crate::mock::{ offence_reports, }; use system::{EventRecord, Phase}; -use runtime_io::with_externalities; +use sr_primitives::set_and_run_with_externalities; #[test] fn should_report_an_authority_and_trigger_on_offence() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); @@ -51,7 +51,7 @@ fn should_report_an_authority_and_trigger_on_offence() { #[test] fn should_calculate_the_fraction_correctly() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); @@ -83,7 +83,7 @@ fn should_calculate_the_fraction_correctly() { #[test] fn should_not_report_the_same_authority_twice_in_the_same_slot() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); @@ -113,7 +113,7 @@ fn should_not_report_the_same_authority_twice_in_the_same_slot() { #[test] fn should_report_in_different_time_slot() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); @@ -143,7 +143,7 @@ fn should_report_in_different_time_slot() { #[test] fn should_deposit_event() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); @@ -171,7 +171,7 @@ fn should_deposit_event() { #[test] fn doesnt_deposit_event_for_dups() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); @@ -208,7 +208,7 @@ fn doesnt_deposit_event_for_dups() { fn should_properly_count_offences() { // We report two different authorities for the same issue. Ultimately, the 1st authority // should have `count` equal 2 and the count of the 2nd one should be equal to 1. - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); diff --git a/srml/randomness-collective-flip/src/lib.rs b/srml/randomness-collective-flip/src/lib.rs index 39dcf15ab4..e5110c5d21 100644 --- a/srml/randomness-collective-flip/src/lib.rs +++ b/srml/randomness-collective-flip/src/lib.rs @@ -161,10 +161,12 @@ impl Module { #[cfg(test)] mod tests { use super::*; - use primitives::{H256, Blake2Hasher}; - use sr_primitives::{Perbill, traits::{BlakeTwo256, OnInitialize, Header as _, IdentityLookup}, testing::Header}; + use primitives::H256; + use sr_primitives::{ + Perbill, traits::{BlakeTwo256, OnInitialize, Header as _, IdentityLookup}, testing::Header, + set_and_run_with_externalities, + }; use support::{impl_outer_origin, parameter_types}; - use runtime_io::with_externalities; #[derive(Clone, PartialEq, Eq)] pub struct Test; @@ -202,7 +204,7 @@ mod tests { type System = system::Module; type Randomness = Module; - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { let t = system::GenesisConfig::default().build_storage::().unwrap(); t.into() } @@ -229,7 +231,7 @@ mod tests { #[test] fn test_random_material_parital() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let genesis_hash = System::parent_hash(); setup_blocks(38); @@ -243,7 +245,7 @@ mod tests { #[test] fn test_random_material_filled() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let genesis_hash = System::parent_hash(); setup_blocks(81); @@ -258,7 +260,7 @@ mod tests { #[test] fn test_random_material_filled_twice() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let genesis_hash = System::parent_hash(); setup_blocks(162); @@ -273,7 +275,7 @@ mod tests { #[test] fn test_random() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { setup_blocks(162); assert_eq!(System::block_number(), 162); diff --git a/srml/scored-pool/src/mock.rs b/srml/scored-pool/src/mock.rs index fd14abd617..92a16bf25d 100644 --- a/srml/scored-pool/src/mock.rs +++ b/srml/scored-pool/src/mock.rs @@ -20,7 +20,7 @@ use super::*; use std::cell::RefCell; use support::{impl_outer_origin, parameter_types}; -use primitives::{H256, Blake2Hasher}; +use primitives::H256; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried. use sr_primitives::{ @@ -132,7 +132,7 @@ impl Trait for Test { // This function basically just builds a genesis storage key/value store according to // our desired mockup. -pub fn new_test_ext() -> runtime_io::TestExternalities { +pub fn new_test_ext() -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); // We use default for brevity, but you can configure as desired if needed. balances::GenesisConfig:: { diff --git a/srml/scored-pool/src/tests.rs b/srml/scored-pool/src/tests.rs index 740e707ce0..cd3efb0ceb 100644 --- a/srml/scored-pool/src/tests.rs +++ b/srml/scored-pool/src/tests.rs @@ -20,8 +20,7 @@ use super::*; use mock::*; use support::{assert_ok, assert_noop}; -use runtime_io::with_externalities; -use sr_primitives::traits::OnInitialize; +use sr_primitives::{set_and_run_with_externalities, traits::OnInitialize}; type ScoredPool = Module; type System = system::Module; @@ -32,7 +31,7 @@ const INDEX_ERR: &str = "index does not match requested account"; #[test] fn query_membership_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_eq!(ScoredPool::members(), vec![20, 40]); assert_eq!(Balances::reserved_balance(&31), CandidateDeposit::get()); assert_eq!(Balances::reserved_balance(&40), CandidateDeposit::get()); @@ -42,7 +41,7 @@ fn query_membership_works() { #[test] fn submit_candidacy_must_not_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_noop!( ScoredPool::submit_candidacy(Origin::signed(99)), "balance too low to submit candidacy" @@ -56,7 +55,7 @@ fn submit_candidacy_must_not_work() { #[test] fn submit_candidacy_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // given let who = 15; @@ -71,7 +70,7 @@ fn submit_candidacy_works() { #[test] fn scoring_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // given let who = 15; let score = 99; @@ -89,7 +88,7 @@ fn scoring_works() { #[test] fn scoring_same_element_with_same_score_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // given let who = 31; let index = find_in_pool(who).expect("entity must be in pool") as u32; @@ -109,7 +108,7 @@ fn scoring_same_element_with_same_score_works() { #[test] fn kicking_works_only_for_authorized() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let who = 40; let index = find_in_pool(who).expect("entity must be in pool") as u32; assert_noop!(ScoredPool::kick(Origin::signed(99), who, index), "bad origin"); @@ -118,7 +117,7 @@ fn kicking_works_only_for_authorized() { #[test] fn kicking_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // given let who = 40; assert_eq!(Balances::reserved_balance(&who), CandidateDeposit::get()); @@ -138,7 +137,7 @@ fn kicking_works() { #[test] fn unscored_entities_must_not_be_used_for_filling_members() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // given // we submit a candidacy, score will be `None` assert_ok!(ScoredPool::submit_candidacy(Origin::signed(15))); @@ -163,7 +162,7 @@ fn unscored_entities_must_not_be_used_for_filling_members() { #[test] fn refreshing_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // given let who = 15; assert_ok!(ScoredPool::submit_candidacy(Origin::signed(who))); @@ -181,7 +180,7 @@ fn refreshing_works() { #[test] fn refreshing_happens_every_period() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // given System::set_block_number(1); assert_ok!(ScoredPool::submit_candidacy(Origin::signed(15))); @@ -201,7 +200,7 @@ fn refreshing_happens_every_period() { #[test] fn withdraw_candidacy_must_only_work_for_members() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let who = 77; let index = 0; assert_noop!( ScoredPool::withdraw_candidacy(Origin::signed(who), index), INDEX_ERR); @@ -210,7 +209,7 @@ fn withdraw_candidacy_must_only_work_for_members() { #[test] fn oob_index_should_abort() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let who = 40; let oob_index = ScoredPool::pool().len() as u32; assert_noop!(ScoredPool::withdraw_candidacy(Origin::signed(who), oob_index), OOB_ERR); @@ -221,7 +220,7 @@ fn oob_index_should_abort() { #[test] fn index_mismatches_should_abort() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let who = 40; let index = 3; assert_noop!(ScoredPool::withdraw_candidacy(Origin::signed(who), index), INDEX_ERR); @@ -232,7 +231,7 @@ fn index_mismatches_should_abort() { #[test] fn withdraw_unscored_candidacy_must_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // given let who = 5; @@ -247,7 +246,7 @@ fn withdraw_unscored_candidacy_must_work() { #[test] fn withdraw_scored_candidacy_must_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // given let who = 40; assert_eq!(Balances::reserved_balance(&who), CandidateDeposit::get()); @@ -265,7 +264,7 @@ fn withdraw_scored_candidacy_must_work() { #[test] fn candidacy_resubmitting_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // given let who = 15; diff --git a/srml/session/src/historical.rs b/srml/session/src/historical.rs index 24821a0393..af9447eb7e 100644 --- a/srml/session/src/historical.rs +++ b/srml/session/src/historical.rs @@ -312,9 +312,10 @@ impl> support::traits::KeyOwnerProofSystem<(KeyTypeId, #[cfg(test)] mod tests { use super::*; - use runtime_io::with_externalities; - use primitives::{Blake2Hasher, crypto::key_types::DUMMY}; - use sr_primitives::{traits::OnInitialize, testing::UintAuthorityId}; + use primitives::crypto::key_types::DUMMY; + use sr_primitives::{ + traits::OnInitialize, testing::UintAuthorityId, set_and_run_with_externalities, + }; use crate::mock::{ NEXT_VALIDATORS, force_new_session, set_next_validators, Test, System, Session, @@ -323,7 +324,7 @@ mod tests { type Historical = Module; - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); crate::GenesisConfig:: { keys: NEXT_VALIDATORS.with(|l| @@ -335,7 +336,7 @@ mod tests { #[test] fn generated_proof_is_good() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { set_next_validators(vec![1, 2]); force_new_session(); @@ -376,7 +377,7 @@ mod tests { #[test] fn prune_up_to_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { for i in 1..101u64 { set_next_validators(vec![i]); force_new_session(); diff --git a/srml/session/src/lib.rs b/srml/session/src/lib.rs index 208be4664a..df311f5081 100644 --- a/srml/session/src/lib.rs +++ b/srml/session/src/lib.rs @@ -680,11 +680,9 @@ impl> FindAuthor mod tests { use super::*; use support::assert_ok; - use runtime_io::with_externalities; - use primitives::{Blake2Hasher, crypto::key_types::DUMMY}; + use primitives::crypto::key_types::DUMMY; use sr_primitives::{ - traits::OnInitialize, - testing::UintAuthorityId, + traits::OnInitialize, set_and_run_with_externalities, testing::UintAuthorityId, }; use mock::{ NEXT_VALIDATORS, SESSION_CHANGED, TEST_SESSION_CHANGED, authorities, force_new_session, @@ -692,7 +690,7 @@ mod tests { reset_before_session_end_called, before_session_end_called, }; - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); GenesisConfig:: { keys: NEXT_VALIDATORS.with(|l| @@ -710,7 +708,7 @@ mod tests { #[test] fn simple_setup_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_eq!(authorities(), vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]); assert_eq!(Session::validators(), vec![1, 2, 3]); }); @@ -718,7 +716,7 @@ mod tests { #[test] fn put_get_keys() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { Session::put_keys(&10, &UintAuthorityId(10).into()); assert_eq!(Session::load_keys(&10), Some(UintAuthorityId(10).into())); }) @@ -727,7 +725,7 @@ mod tests { #[test] fn keys_cleared_on_kill() { let mut ext = new_test_ext(); - with_externalities(&mut ext, || { + set_and_run_with_externalities(&mut ext, || { assert_eq!(Session::validators(), vec![1, 2, 3]); assert_eq!(Session::load_keys(&1), Some(UintAuthorityId(1).into())); @@ -744,7 +742,7 @@ mod tests { fn authorities_should_track_validators() { reset_before_session_end_called(); - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { set_next_validators(vec![1, 2]); force_new_session(); initialize_block(1); @@ -795,7 +793,7 @@ mod tests { #[test] fn should_work_with_early_exit() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { set_session_length(10); initialize_block(1); @@ -818,7 +816,7 @@ mod tests { #[test] fn session_change_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // Block 1: No change initialize_block(1); assert_eq!(authorities(), vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]); @@ -848,7 +846,7 @@ mod tests { #[test] fn duplicates_are_not_allowed() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::set_block_number(1); Session::on_initialize(1); assert!(Session::set_keys(Origin::signed(4), UintAuthorityId(1).into(), vec![]).is_err()); @@ -863,7 +861,7 @@ mod tests { fn session_changed_flag_works() { reset_before_session_end_called(); - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { TEST_SESSION_CHANGED.with(|l| *l.borrow_mut() = true); force_new_session(); @@ -952,7 +950,7 @@ mod tests { #[test] fn session_keys_generate_output_works_as_set_keys_input() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let new_keys = mock::MockSessionKeys::generate(None); assert_ok!( Session::set_keys( @@ -966,7 +964,7 @@ mod tests { #[test] fn return_true_if_more_than_third_is_disabled() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { set_next_validators(vec![1, 2, 3, 4, 5, 6, 7]); force_new_session(); initialize_block(1); diff --git a/srml/staking/src/mock.rs b/srml/staking/src/mock.rs index d8d3656142..9055d7db87 100644 --- a/srml/staking/src/mock.rs +++ b/srml/staking/src/mock.rs @@ -22,7 +22,7 @@ use sr_primitives::curve::PiecewiseLinear; use sr_primitives::traits::{IdentityLookup, Convert, OpaqueKeys, OnInitialize, SaturatedConversion}; use sr_primitives::testing::{Header, UintAuthorityId}; use sr_staking_primitives::SessionIndex; -use primitives::{H256, Blake2Hasher}; +use primitives::H256; use runtime_io; use support::{assert_ok, impl_outer_origin, parameter_types, StorageLinkedMap}; use support::traits::{Currency, Get, FindAuthor}; @@ -274,7 +274,7 @@ impl ExtBuilder { pub fn set_associated_consts(&self) { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); } - pub fn build(self) -> runtime_io::TestExternalities { + pub fn build(self) -> runtime_io::TestExternalities { self.set_associated_consts(); let mut storage = system::GenesisConfig::default().build_storage::().unwrap(); let balance_factor = if self.existential_deposit > 0 { @@ -341,7 +341,7 @@ impl ExtBuilder { }.assimilate_storage(&mut storage); let mut ext = storage.into(); - runtime_io::with_externalities(&mut ext, || { + sr_primitives::set_and_run_with_externalities(&mut ext, || { let validators = Session::validators(); SESSION.with(|x| *x.borrow_mut() = (validators.clone(), HashSet::new()) diff --git a/srml/staking/src/tests.rs b/srml/staking/src/tests.rs index 6b51fb9b3f..48218f9eb7 100644 --- a/srml/staking/src/tests.rs +++ b/srml/staking/src/tests.rs @@ -18,16 +18,14 @@ use super::*; use mock::*; -use runtime_io::with_externalities; -use sr_primitives::{assert_eq_error_rate, traits::OnInitialize}; +use sr_primitives::{assert_eq_error_rate, traits::OnInitialize, set_and_run_with_externalities}; use sr_staking_primitives::offence::{OffenceDetails, OnOffenceHandler}; -use support::{assert_ok, assert_noop, assert_eq_uvec}; -use support::traits::{Currency, ReservableCurrency}; +use support::{assert_ok, assert_noop, assert_eq_uvec, traits::{Currency, ReservableCurrency}}; #[test] fn basic_setup_works() { // Verifies initial conditions of mock - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .build(), || { // Account 11 is stashed and locked, and account 10 is the controller @@ -109,7 +107,7 @@ fn basic_setup_works() { #[test] fn change_controller_works() { - with_externalities(&mut ExtBuilder::default().build(), + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_eq!(Staking::bonded(&11), Some(10)); @@ -136,7 +134,7 @@ fn rewards_should_work() { // * rewards get recorded per session // * rewards get paid per Era // * Check that nominators are also rewarded - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .nominate(false) .build(), || { @@ -217,7 +215,7 @@ fn multi_era_reward_should_work() { // Should check that: // The value of current_session_reward is set at the end of each era, based on // slot_stake and session_reward. - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .nominate(false) .build(), || { @@ -260,7 +258,7 @@ fn staking_should_work() { // * new validators can be added to the default set // * new ones will be chosen per era // * either one can unlock the stash and back-down from being a validator via `chill`ing. - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .nominate(false) .fair(false) // to give 20 more staked value .build(), @@ -322,7 +320,7 @@ fn staking_should_work() { #[test] fn less_than_needed_candidates_works() { - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .minimum_validator_count(1) .validator_count(4) .nominate(false) @@ -349,7 +347,7 @@ fn less_than_needed_candidates_works() { #[test] fn no_candidate_emergency_condition() { - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .minimum_validator_count(10) .validator_count(15) .num_validators(4) @@ -415,7 +413,7 @@ fn nominating_and_rewards_should_work() { // 10 with stake 400.0 20 with stake 600.0 30 with stake 0 // 4 has load 0.0005555555555555556 and supported // 10 with stake 600.0 20 with stake 400.0 40 with stake 0.0 - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .nominate(false) .validator_pool(true) .build(), @@ -599,7 +597,7 @@ fn nominators_also_get_slashed() { // 10 - is the controller of 11 // 11 - is the stash. // 2 - is the nominator of 20, 10 - with_externalities(&mut ExtBuilder::default().nominate(false).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().nominate(false).build(), || { assert_eq!(Staking::validator_count(), 2); // Set payee to controller @@ -659,7 +657,7 @@ fn double_staking_should_fail() { // * an account already bonded as stash cannot be be stashed again. // * an account already bonded as stash cannot nominate. // * an account already bonded as controller can nominate. - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .build(), || { let arbitrary_value = 5; @@ -684,7 +682,7 @@ fn double_staking_should_fail() { fn double_controlling_should_fail() { // should test (in the same order): // * an account already bonded as controller CANNOT be reused as the controller of another account. - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .build(), || { let arbitrary_value = 5; @@ -703,7 +701,7 @@ fn double_controlling_should_fail() { #[test] fn session_and_eras_work() { - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .build(), || { assert_eq!(Staking::current_era(), 0); @@ -747,7 +745,7 @@ fn session_and_eras_work() { #[test] fn forcing_new_era_works() { - with_externalities(&mut ExtBuilder::default().build(),|| { + set_and_run_with_externalities(&mut ExtBuilder::default().build(),|| { // normal flow of session. assert_eq!(Staking::current_era(), 0); start_session(0); @@ -786,7 +784,7 @@ fn forcing_new_era_works() { #[test] fn cannot_transfer_staked_balance() { // Tests that a stash account cannot transfer funds - with_externalities(&mut ExtBuilder::default().nominate(false).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().nominate(false).build(), || { // Confirm account 11 is stashed assert_eq!(Staking::bonded(&11), Some(10)); // Confirm account 11 has some free balance @@ -811,7 +809,7 @@ fn cannot_transfer_staked_balance_2() { // Tests that a stash account cannot transfer funds // Same test as above but with 20, and more accurate. // 21 has 2000 free balance but 1000 at stake - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .nominate(false) .fair(true) .build(), @@ -834,7 +832,7 @@ fn cannot_transfer_staked_balance_2() { #[test] fn cannot_reserve_staked_balance() { // Checks that a bonded account cannot reserve balance from free balance - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { // Confirm account 11 is stashed assert_eq!(Staking::bonded(&11), Some(10)); // Confirm account 11 has some free balance @@ -854,7 +852,7 @@ fn cannot_reserve_staked_balance() { #[test] fn reward_destination_works() { // Rewards go to the correct destination as determined in Payee - with_externalities(&mut ExtBuilder::default().nominate(false).build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().nominate(false).build(), || { // Check that account 11 is a validator assert!(Staking::current_elected().contains(&11)); // Check the balance of the validator account @@ -946,7 +944,7 @@ fn validator_payment_prefs_work() { // Test that validator preferences are correctly honored // Note: unstake threshold is being directly tested in slashing tests. // This test will focus on validator payment. - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .build(), || { // Initial config @@ -998,7 +996,7 @@ fn bond_extra_works() { // Tests that extra `free_balance` in the stash can be added to stake // NOTE: this tests only verifies `StakingLedger` for correct updates // See `bond_extra_and_withdraw_unbonded_works` for more details and updates on `Exposure`. - with_externalities(&mut ExtBuilder::default().build(), + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { // Check that account 10 is a validator assert!(>::exists(11)); @@ -1044,7 +1042,7 @@ fn bond_extra_and_withdraw_unbonded_works() { // * It can add extra funds to the bonded account. // * it can unbond a portion of its funds from the stash account. // * Once the unbonding period is done, it can actually take the funds out of the stash. - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .nominate(false) .build(), || { @@ -1131,7 +1129,7 @@ fn bond_extra_and_withdraw_unbonded_works() { #[test] fn too_many_unbond_calls_should_not_work() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { // locked at era 0 until 3 for _ in 0..MAX_UNLOCKING_CHUNKS-1 { assert_ok!(Staking::unbond(Origin::signed(10), 1)); @@ -1160,7 +1158,7 @@ fn too_many_unbond_calls_should_not_work() { fn slot_stake_is_least_staked_validator_and_exposure_defines_maximum_punishment() { // Test that slot_stake is determined by the least staked validator // Test that slot_stake is the maximum punishment that can happen to a validator - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .nominate(false) .fair(false) .build(), @@ -1213,7 +1211,7 @@ fn slot_stake_is_least_staked_validator_and_exposure_defines_maximum_punishment( fn on_free_balance_zero_stash_removes_validator() { // Tests that validator storage items are cleaned up when stash is empty // Tests that storage items are untouched when controller is empty - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .existential_deposit(10) .build(), || { @@ -1266,7 +1264,7 @@ fn on_free_balance_zero_stash_removes_validator() { fn on_free_balance_zero_stash_removes_nominator() { // Tests that nominator storage items are cleaned up when stash is empty // Tests that storage items are untouched when controller is empty - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .existential_deposit(10) .build(), || { @@ -1322,7 +1320,7 @@ fn on_free_balance_zero_stash_removes_nominator() { #[test] fn switching_roles() { // Test that it should be possible to switch between roles (nominator, validator, idle) with minimal overhead. - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .nominate(false) .build(), || { @@ -1391,7 +1389,7 @@ fn switching_roles() { #[test] fn wrong_vote_is_null() { - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .nominate(false) .validator_pool(true) .build(), @@ -1419,7 +1417,7 @@ fn wrong_vote_is_null() { fn bond_with_no_staked_value() { // Behavior when someone bonds with no staked value. // Particularly when she votes and the candidate is elected. - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .validator_count(3) .existential_deposit(5) .nominate(false) @@ -1467,7 +1465,7 @@ fn bond_with_no_staked_value() { fn bond_with_little_staked_value_bounded_by_slot_stake() { // Behavior when someone bonds with little staked value. // Particularly when she votes and the candidate is elected. - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .validator_count(3) .nominate(false) .minimum_validator_count(1) @@ -1517,7 +1515,7 @@ fn bond_with_little_staked_value_bounded_by_slot_stake() { #[cfg(feature = "equalize")] #[test] fn phragmen_linear_worse_case_equalize() { - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .nominate(false) .validator_pool(true) .fair(true) @@ -1562,7 +1560,7 @@ fn phragmen_linear_worse_case_equalize() { #[test] fn new_era_elects_correct_number_of_validators() { - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .nominate(true) .validator_pool(true) .fair(true) @@ -1583,7 +1581,7 @@ fn new_era_elects_correct_number_of_validators() { #[test] fn phragmen_should_not_overflow_validators() { - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .nominate(false) .build(), || { @@ -1609,7 +1607,7 @@ fn phragmen_should_not_overflow_validators() { #[test] fn phragmen_should_not_overflow_nominators() { - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .nominate(false) .build(), || { @@ -1634,7 +1632,7 @@ fn phragmen_should_not_overflow_nominators() { #[test] fn phragmen_should_not_overflow_ultimate() { - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .nominate(false) .build(), || { @@ -1656,7 +1654,7 @@ fn phragmen_should_not_overflow_ultimate() { #[test] fn reward_validator_slashing_validator_doesnt_overflow() { - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .build(), || { let stake = u32::max_value() as u64 * 2; @@ -1689,7 +1687,7 @@ fn reward_validator_slashing_validator_doesnt_overflow() { #[test] fn reward_from_authorship_event_handler_works() { - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .build(), || { use authorship::EventHandler; @@ -1716,7 +1714,7 @@ fn reward_from_authorship_event_handler_works() { #[test] fn add_reward_points_fns_works() { - with_externalities(&mut ExtBuilder::default() + set_and_run_with_externalities(&mut ExtBuilder::default() .build(), || { let validators = >::current_elected(); @@ -1744,7 +1742,7 @@ fn add_reward_points_fns_works() { #[test] fn unbonded_balance_is_not_slashable() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { // total amount staked is slashable. assert_eq!(Staking::slashable_balance_of(&11), 1000); @@ -1759,7 +1757,7 @@ fn unbonded_balance_is_not_slashable() { fn era_is_always_same_length() { // This ensures that the sessions is always of the same length if there is no forcing no // session changes. - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { start_era(1); assert_eq!(Staking::current_era_start_session_index(), SessionsPerEra::get()); @@ -1779,7 +1777,7 @@ fn era_is_always_same_length() { #[test] fn offence_forces_new_era() { - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { Staking::on_offence( &[OffenceDetails { offender: ( @@ -1799,7 +1797,7 @@ fn offence_forces_new_era() { fn slashing_performed_according_exposure() { // This test checks that slashing is performed according the exposure (or more precisely, // historical exposure), not the current balance. - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_eq!(Staking::stakers(&11).own, 1000); // Handle an offence with a historical exposure. @@ -1827,7 +1825,7 @@ fn slashing_performed_according_exposure() { fn reporters_receive_their_slice() { // This test verifies that the reporters of the offence receive their slice from the slashed // amount. - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { // The reporters' reward is calculated from the total exposure. #[cfg(feature = "equalize")] let initial_balance = 1250; @@ -1857,7 +1855,7 @@ fn reporters_receive_their_slice() { #[test] fn invulnerables_are_not_slashed() { // For invulnerable validators no slashing is performed. - with_externalities( + set_and_run_with_externalities( &mut ExtBuilder::default().invulnerables(vec![11]).build(), || { #[cfg(feature = "equalize")] @@ -1894,7 +1892,7 @@ fn invulnerables_are_not_slashed() { #[test] fn dont_slash_if_fraction_is_zero() { // Don't slash if the fraction is zero. - with_externalities(&mut ExtBuilder::default().build(), || { + set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { assert_eq!(Balances::free_balance(&11), 1000); Staking::on_offence( diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index b88d86761c..675e5b6ea8 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -236,13 +236,12 @@ pub use serde::{Serialize, Deserialize}; mod tests { use super::*; use codec::{Codec, EncodeLike}; - use runtime_io::with_externalities; - use primitives::Blake2Hasher; - pub use srml_metadata::{ + use sr_primitives::set_and_run_with_externalities; + use srml_metadata::{ DecodeDifferent, StorageEntryMetadata, StorageMetadata, StorageEntryType, - StorageEntryModifier, DefaultByte, DefaultByteGetter, StorageHasher + StorageEntryModifier, DefaultByteGetter, StorageHasher, }; - pub use rstd::marker::PhantomData; + use rstd::marker::PhantomData; pub trait Trait { type BlockNumber: Codec + EncodeLike + Default; @@ -281,7 +280,7 @@ mod tests { type Origin = u32; } - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { GenesisConfig::default().build_storage().unwrap().into() } @@ -289,7 +288,7 @@ mod tests { #[test] fn linked_map_issue_3318() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { OptionLinkedMap::insert(1, 1); assert_eq!(OptionLinkedMap::get(1), Some(1)); OptionLinkedMap::insert(1, 2); @@ -299,7 +298,7 @@ mod tests { #[test] fn linked_map_swap_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { OptionLinkedMap::insert(0, 0); OptionLinkedMap::insert(1, 1); OptionLinkedMap::insert(2, 2); @@ -328,7 +327,7 @@ mod tests { #[test] fn linked_map_basic_insert_remove_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // initialized during genesis assert_eq!(Map::get(&15u32), 42u64); @@ -354,7 +353,7 @@ mod tests { #[test] fn linked_map_enumeration_and_head_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_eq!(Map::head(), Some(15)); assert_eq!(Map::enumerate().collect::>(), vec![(15, 42)]); // insert / remove @@ -406,7 +405,7 @@ mod tests { #[test] fn double_map_basic_insert_remove_remove_prefix_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { type DoubleMap = DataDM; // initialized during genesis assert_eq!(DoubleMap::get(&15u32, &16u32), 42u64); @@ -446,7 +445,7 @@ mod tests { #[test] fn double_map_append_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { type DoubleMap = AppendableDM; let key1 = 17u32; diff --git a/srml/support/src/storage/storage_items.rs b/srml/support/src/storage/storage_items.rs index 24a7f3984a..4f8f194795 100644 --- a/srml/support/src/storage/storage_items.rs +++ b/srml/support/src/storage/storage_items.rs @@ -758,8 +758,8 @@ mod test3 { #[cfg(test)] #[allow(dead_code)] mod test_append_and_len { - use crate::storage::{StorageValue}; - use runtime_io::{with_externalities, TestExternalities}; + use runtime_io::TestExternalities; + use sr_primitives::set_and_run_with_externalities; use codec::{Encode, Decode}; pub trait Trait { @@ -801,7 +801,7 @@ mod test_append_and_len { #[test] fn default_for_option() { - with_externalities(&mut TestExternalities::default(), || { + set_and_run_with_externalities(&mut TestExternalities::default(), || { assert_eq!(OptionVec::get(), None); assert_eq!(JustVec::get(), vec![]); }); @@ -809,7 +809,7 @@ mod test_append_and_len { #[test] fn append_works() { - with_externalities(&mut TestExternalities::default(), || { + set_and_run_with_externalities(&mut TestExternalities::default(), || { let _ = MapVec::append(1, [1, 2, 3].iter()); let _ = MapVec::append(1, [4, 5].iter()); assert_eq!(MapVec::get(1), vec![1, 2, 3, 4, 5]); @@ -822,7 +822,7 @@ mod test_append_and_len { #[test] fn append_works_for_default() { - with_externalities(&mut TestExternalities::default(), || { + set_and_run_with_externalities(&mut TestExternalities::default(), || { assert_eq!(JustVecWithDefault::get(), vec![6, 9]); let _ = JustVecWithDefault::append([1].iter()); assert_eq!(JustVecWithDefault::get(), vec![6, 9, 1]); @@ -839,7 +839,7 @@ mod test_append_and_len { #[test] fn append_or_put_works() { - with_externalities(&mut TestExternalities::default(), || { + set_and_run_with_externalities(&mut TestExternalities::default(), || { let _ = MapVec::append_or_insert(1, &[1, 2, 3][..]); let _ = MapVec::append_or_insert(1, &[4, 5][..]); assert_eq!(MapVec::get(1), vec![1, 2, 3, 4, 5]); @@ -856,7 +856,7 @@ mod test_append_and_len { #[test] fn len_works() { - with_externalities(&mut TestExternalities::default(), || { + set_and_run_with_externalities(&mut TestExternalities::default(), || { JustVec::put(&vec![1, 2, 3, 4]); OptionVec::put(&vec![1, 2, 3, 4, 5]); MapVec::insert(1, &vec![1, 2, 3, 4, 5, 6]); @@ -871,7 +871,7 @@ mod test_append_and_len { #[test] fn len_works_for_default() { - with_externalities(&mut TestExternalities::default(), || { + set_and_run_with_externalities(&mut TestExternalities::default(), || { // vec assert_eq!(JustVec::get(), vec![]); assert_eq!(JustVec::decode_len(), Ok(0)); diff --git a/srml/support/test/Cargo.toml b/srml/support/test/Cargo.toml index bb1b3749e9..f40fef9ead 100644 --- a/srml/support/test/Cargo.toml +++ b/srml/support/test/Cargo.toml @@ -10,6 +10,7 @@ codec = { package = "parity-scale-codec", version = "1.0.0", default-features = runtime-io ={ package = "sr-io", path = "../../../core/sr-io", default-features = false } support = { package = "srml-support", version = "2", path = "../", default-features = false } inherents = { package = "substrate-inherents", path = "../../../core/inherents", default-features = false } +sr-primitives = { package = "sr-primitives", path = "../../../core/sr-primitives", default-features = false } primitives = { package = "substrate-primitives", path = "../../../core/primitives", default-features = false } trybuild = "1.0.14" pretty_assertions = "0.6.1" @@ -23,4 +24,5 @@ std = [ "support/std", "inherents/std", "primitives/std", + "sr-primitives/std", ] diff --git a/srml/support/test/tests/instance.rs b/srml/support/test/tests/instance.rs index da4e73e710..c7a2d25eed 100644 --- a/srml/support/test/tests/instance.rs +++ b/srml/support/test/tests/instance.rs @@ -15,20 +15,22 @@ // along with Substrate. If not, see . #![recursion_limit="128"] -use runtime_io::with_externalities; +use sr_primitives::{ + generic, BuildStorage, traits::{BlakeTwo256, Block as _, Verify}, + set_and_run_with_externalities, +}; use support::{ Parameter, traits::Get, parameter_types, - sr_primitives::{generic, BuildStorage, traits::{BlakeTwo256, Block as _, Verify}}, metadata::{ DecodeDifferent, StorageMetadata, StorageEntryModifier, StorageEntryType, DefaultByteGetter, - StorageEntryMetadata, StorageHasher + StorageEntryMetadata, StorageHasher, }, StorageValue, StorageMap, StorageLinkedMap, StorageDoubleMap, }; use inherents::{ ProvideInherent, InherentData, InherentIdentifier, RuntimeString, MakeFatalError }; -use primitives::{H256, sr25519, Blake2Hasher}; +use primitives::{H256, sr25519}; mod system; @@ -275,7 +277,7 @@ pub type Header = generic::Header; pub type Block = generic::Block; pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; -fn new_test_ext() -> runtime_io::TestExternalities { +fn new_test_ext() -> runtime_io::TestExternalities { GenesisConfig{ module1_Instance1: Some(module1::GenesisConfig { value: 3, @@ -329,7 +331,7 @@ fn storage_instance_independance() { #[test] fn storage_with_instance_basic_operation() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { type Value = module2::Value; type Map = module2::Map; type LinkedMap = module2::LinkedMap; diff --git a/srml/system/benches/bench.rs b/srml/system/benches/bench.rs index b24e52f457..89e9af9525 100644 --- a/srml/system/benches/bench.rs +++ b/srml/system/benches/bench.rs @@ -17,9 +17,10 @@ use criterion::{Criterion, criterion_group, criterion_main, black_box}; use srml_system as system; use support::{decl_module, decl_event, impl_outer_origin, impl_outer_event}; -use runtime_io::with_externalities; -use primitives::{H256, Blake2Hasher}; -use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; +use primitives::H256; +use sr_primitives::{ + set_and_run_with_externalities, Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header, +}; mod module { use super::*; @@ -82,13 +83,13 @@ impl module::Trait for Runtime { type Event = Event; } -fn new_test_ext() -> runtime_io::TestExternalities { +fn new_test_ext() -> runtime_io::TestExternalities { system::GenesisConfig::default().build_storage::().unwrap().into() } fn deposit_events(n: usize) { let mut t = new_test_ext(); - with_externalities(&mut t, || { + set_and_run_with_externalities(&mut t, || { for _ in 0..n { module::Module::::deposit_event( module::Event::Complex(vec![1, 2, 3], 2, 3, 899) diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index 79782d5af4..065b23bda1 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -120,7 +120,7 @@ use codec::{Encode, Decode}; use runtime_io::TestExternalities; #[cfg(any(feature = "std", test))] -use primitives::{ChangesTrieConfiguration, Blake2Hasher}; +use primitives::ChangesTrieConfiguration; pub mod offchain; @@ -695,7 +695,7 @@ impl Module { /// Get the basic externalities for this module, useful for tests. #[cfg(any(feature = "std", test))] - pub fn externalities() -> TestExternalities { + pub fn externalities() -> TestExternalities { TestExternalities::new((map![ >::hashed_key_for(T::BlockNumber::zero()) => [69u8; 32].encode(), >::hashed_key().to_vec() => T::BlockNumber::one().encode(), @@ -1090,9 +1090,11 @@ impl Lookup for ChainContext { #[cfg(test)] mod tests { use super::*; - use runtime_io::with_externalities; use primitives::H256; - use sr_primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header, DispatchError}; + use sr_primitives::{ + traits::{BlakeTwo256, IdentityLookup}, testing::Header, DispatchError, + set_and_run_with_externalities, + }; use support::{impl_outer_origin, parameter_types}; impl_outer_origin! { @@ -1141,7 +1143,7 @@ mod tests { const CALL: &::Call = &(); - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { GenesisConfig::default().build_storage::().unwrap().into() } @@ -1162,7 +1164,7 @@ mod tests { #[test] fn deposit_event_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { System::initialize(&1, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); System::note_finished_extrinsics(); System::deposit_event(1u16); @@ -1199,7 +1201,7 @@ mod tests { #[test] fn deposit_event_topics() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { const BLOCK_NUMBER: u64 = 1; System::initialize(&BLOCK_NUMBER, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); @@ -1259,7 +1261,7 @@ mod tests { #[test] fn prunes_block_hash_mappings() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // simulate import of 15 blocks for n in 1..=15 { System::initialize( @@ -1292,7 +1294,7 @@ mod tests { #[test] fn signed_ext_check_nonce_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { >::insert(1, 1); let info = DispatchInfo::default(); let len = 0_usize; @@ -1310,7 +1312,7 @@ mod tests { #[test] fn signed_ext_check_weight_works_normal_tx() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let normal_limit = normal_weight_limit(); let small = DispatchInfo { weight: 100, ..Default::default() }; let medium = DispatchInfo { @@ -1337,7 +1339,7 @@ mod tests { #[test] fn signed_ext_check_weight_fee_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let free = DispatchInfo { weight: 0, ..Default::default() }; let len = 0_usize; @@ -1350,7 +1352,7 @@ mod tests { #[test] fn signed_ext_check_weight_max_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let max = DispatchInfo { weight: Weight::max_value(), ..Default::default() }; let len = 0_usize; let normal_limit = normal_weight_limit(); @@ -1364,7 +1366,7 @@ mod tests { #[test] fn signed_ext_check_weight_works_operational_tx() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let normal = DispatchInfo { weight: 100, ..Default::default() }; let op = DispatchInfo { weight: 100, class: DispatchClass::Operational }; let len = 0_usize; @@ -1387,7 +1389,7 @@ mod tests { #[test] fn signed_ext_check_weight_priority_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal }; let op = DispatchInfo { weight: 100, class: DispatchClass::Operational }; let len = 0_usize; @@ -1408,7 +1410,7 @@ mod tests { #[test] fn signed_ext_check_weight_block_size_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let normal = DispatchInfo::default(); let normal_limit = normal_weight_limit() as usize; let reset_check_weight = |tx, s, f| { @@ -1432,7 +1434,7 @@ mod tests { #[test] fn signed_ext_check_era_should_work() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // future assert_eq!( CheckEra::::from(Era::mortal(4, 2)).additional_signed().err().unwrap(), @@ -1448,7 +1450,7 @@ mod tests { #[test] fn signed_ext_check_era_should_change_longevity() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal }; let len = 0_usize; let ext = ( diff --git a/srml/timestamp/src/lib.rs b/srml/timestamp/src/lib.rs index 4af0de8bd1..8ed3aa8dc0 100644 --- a/srml/timestamp/src/lib.rs +++ b/srml/timestamp/src/lib.rs @@ -322,9 +322,12 @@ mod tests { use super::*; use support::{impl_outer_origin, assert_ok, parameter_types}; - use runtime_io::{with_externalities, TestExternalities}; + use runtime_io::TestExternalities; use primitives::H256; - use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; + use sr_primitives::{ + Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header, + set_and_run_with_externalities, + }; impl_outer_origin! { pub enum Origin for Test {} @@ -369,7 +372,7 @@ mod tests { #[test] fn timestamp_works() { let t = system::GenesisConfig::default().build_storage::().unwrap(); - with_externalities(&mut TestExternalities::new(t), || { + set_and_run_with_externalities(&mut TestExternalities::new(t), || { Timestamp::set_timestamp(42); assert_ok!(Timestamp::dispatch(Call::set(69), Origin::NONE)); assert_eq!(Timestamp::now(), 69); @@ -380,7 +383,7 @@ mod tests { #[should_panic(expected = "Timestamp must be updated only once in the block")] fn double_timestamp_should_fail() { let t = system::GenesisConfig::default().build_storage::().unwrap(); - with_externalities(&mut TestExternalities::new(t), || { + set_and_run_with_externalities(&mut TestExternalities::new(t), || { Timestamp::set_timestamp(42); assert_ok!(Timestamp::dispatch(Call::set(69), Origin::NONE)); let _ = Timestamp::dispatch(Call::set(70), Origin::NONE); @@ -391,7 +394,7 @@ mod tests { #[should_panic(expected = "Timestamp must increment by at least between sequential blocks")] fn block_period_minimum_enforced() { let t = system::GenesisConfig::default().build_storage::().unwrap(); - with_externalities(&mut TestExternalities::new(t), || { + set_and_run_with_externalities(&mut TestExternalities::new(t), || { Timestamp::set_timestamp(42); let _ = Timestamp::dispatch(Call::set(46), Origin::NONE); }); diff --git a/srml/treasury/src/lib.rs b/srml/treasury/src/lib.rs index db8b0f34c9..8ccc260fa7 100644 --- a/srml/treasury/src/lib.rs +++ b/srml/treasury/src/lib.rs @@ -355,13 +355,11 @@ impl OnDilution> for Module { mod tests { use super::*; - use runtime_io::with_externalities; use support::{assert_noop, assert_ok, impl_outer_origin, parameter_types}; - use primitives::{H256, Blake2Hasher}; + use primitives::H256; use sr_primitives::{ - traits::{BlakeTwo256, OnFinalize, IdentityLookup}, - testing::Header, - assert_eq_error_rate, + traits::{BlakeTwo256, OnFinalize, IdentityLookup}, set_and_run_with_externalities, + testing::Header, assert_eq_error_rate, }; impl_outer_origin! { @@ -437,7 +435,7 @@ mod tests { type Balances = balances::Module; type Treasury = Module; - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); balances::GenesisConfig::{ balances: vec![(0, 100), (1, 99), (2, 1)], @@ -448,7 +446,7 @@ mod tests { #[test] fn genesis_config_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_eq!(Treasury::pot(), 0); assert_eq!(Treasury::proposal_count(), 0); }); @@ -456,7 +454,7 @@ mod tests { #[test] fn minting_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { // Check that accumulate works when we have Some value in Dummy already. Treasury::on_dilution(100, 100); assert_eq!(Treasury::pot(), 100); @@ -467,7 +465,7 @@ mod tests { fn minting_works_2() { let tests = [(1, 10), (1, 20), (40, 130), (2, 66), (2, 67), (2, 100), (2, 101), (2, 134)]; for &(minted, portion) in &tests { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let init_total_issuance = Balances::total_issuance(); Treasury::on_dilution(minted, portion); @@ -491,7 +489,7 @@ mod tests { #[test] fn spend_proposal_takes_min_deposit() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_ok!(Treasury::propose_spend(Origin::signed(0), 1, 3)); assert_eq!(Balances::free_balance(&0), 99); assert_eq!(Balances::reserved_balance(&0), 1); @@ -500,7 +498,7 @@ mod tests { #[test] fn spend_proposal_takes_proportional_deposit() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); assert_eq!(Balances::free_balance(&0), 95); assert_eq!(Balances::reserved_balance(&0), 5); @@ -509,14 +507,14 @@ mod tests { #[test] fn spend_proposal_fails_when_proposer_poor() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_noop!(Treasury::propose_spend(Origin::signed(2), 100, 3), "Proposer's balance too low"); }); } #[test] fn accepted_spend_proposal_ignored_outside_spend_period() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { Treasury::on_dilution(100, 100); assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); @@ -530,7 +528,7 @@ mod tests { #[test] fn unused_pot_should_diminish() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { let init_total_issuance = Balances::total_issuance(); Treasury::on_dilution(100, 100); assert_eq!(Balances::total_issuance(), init_total_issuance + 100); @@ -543,7 +541,7 @@ mod tests { #[test] fn rejected_spend_proposal_ignored_on_spend_period() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { Treasury::on_dilution(100, 100); assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); @@ -557,7 +555,7 @@ mod tests { #[test] fn reject_already_rejected_spend_proposal_fails() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { Treasury::on_dilution(100, 100); assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); @@ -568,21 +566,21 @@ mod tests { #[test] fn reject_non_existant_spend_proposal_fails() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_noop!(Treasury::reject_proposal(Origin::ROOT, 0), "No proposal at that index"); }); } #[test] fn accept_non_existant_spend_proposal_fails() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_noop!(Treasury::approve_proposal(Origin::ROOT, 0), "No proposal at that index"); }); } #[test] fn accept_already_rejected_spend_proposal_fails() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { Treasury::on_dilution(100, 100); assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); @@ -593,7 +591,7 @@ mod tests { #[test] fn accepted_spend_proposal_enacted_on_spend_period() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { Treasury::on_dilution(100, 100); assert_eq!(Treasury::pot(), 100); @@ -608,7 +606,7 @@ mod tests { #[test] fn pot_underflow_should_not_diminish() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { Treasury::on_dilution(100, 100); assert_ok!(Treasury::propose_spend(Origin::signed(0), 150, 3)); diff --git a/srml/utility/src/lib.rs b/srml/utility/src/lib.rs index c0b1954da9..a9009a3a7e 100644 --- a/srml/utility/src/lib.rs +++ b/srml/utility/src/lib.rs @@ -64,10 +64,10 @@ mod tests { use super::*; use support::{assert_ok, assert_noop, impl_outer_origin, parameter_types, impl_outer_dispatch}; - use runtime_io::with_externalities; - use primitives::{H256, Blake2Hasher}; + use primitives::H256; use sr_primitives::{ - Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header + Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header, + set_and_run_with_externalities, }; impl_outer_origin! { @@ -139,7 +139,7 @@ mod tests { type Balances = balances::Module; type Utility = Module; - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); balances::GenesisConfig:: { balances: vec![(1, 10), (2, 0)], @@ -150,7 +150,7 @@ mod tests { #[test] fn batch_works() { - with_externalities(&mut new_test_ext(), || { + set_and_run_with_externalities(&mut new_test_ext(), || { assert_eq!(Balances::free_balance(1), 10); assert_eq!(Balances::free_balance(2), 0); assert_noop!(Utility::batch(Origin::signed(1), vec![ -- GitLab From e44bd4415de36b661a3e17f7f98aaf466d270f79 Mon Sep 17 00:00:00 2001 From: Demi Obenour <48690212+DemiMarie-parity@users.noreply.github.com> Date: Wed, 9 Oct 2019 12:29:28 -0400 Subject: [PATCH 201/275] Bump dependencies (#3787) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update dependencies, respecting semver * Bump dependencies * Don’t patch tiny-bip39 dependency --- Cargo.lock | 78 +++++++++++++++----------- core/authority-discovery/Cargo.toml | 2 +- core/chain-spec/Cargo.toml | 2 +- core/cli/Cargo.toml | 4 +- core/client/Cargo.toml | 2 +- core/client/db/Cargo.toml | 2 +- core/consensus/aura/Cargo.toml | 2 +- core/consensus/babe/Cargo.toml | 2 +- core/finality-grandpa/Cargo.toml | 4 +- core/keystore/Cargo.toml | 2 +- core/network/Cargo.toml | 4 +- core/offchain/Cargo.toml | 2 +- core/peerset/Cargo.toml | 2 +- core/rpc-servers/Cargo.toml | 2 +- core/rpc/Cargo.toml | 2 +- core/rpc/api/Cargo.toml | 2 +- core/serializer/Cargo.toml | 2 +- core/service/Cargo.toml | 2 +- core/service/test/Cargo.toml | 2 +- core/sr-primitives/Cargo.toml | 2 +- core/state-db/Cargo.toml | 2 +- core/transaction-pool/graph/Cargo.toml | 2 +- node/rpc-client/Cargo.toml | 2 +- node/rpc/Cargo.toml | 2 +- srml/utility/Cargo.toml | 2 +- 25 files changed, 72 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a1f3ba2983..8a1ead4978 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -104,10 +104,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "arrayvec" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -240,7 +240,7 @@ name = "blake2-rfc" version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -341,7 +341,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -569,7 +569,7 @@ name = "crossbeam-epoch" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -787,6 +787,18 @@ dependencies = [ "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "env_logger" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "environmental" version = "1.0.2" @@ -1055,7 +1067,7 @@ name = "generic-array" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1313,7 +1325,7 @@ dependencies = [ "http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1405,11 +1417,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "iovec" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1785,7 +1796,7 @@ name = "libp2p-kad" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2209,7 +2220,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2235,7 +2246,7 @@ name = "mio-uds" version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2418,7 +2429,7 @@ dependencies = [ name = "node-rpc" version = "2.0.0" dependencies = [ - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core-client 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2442,7 +2453,7 @@ dependencies = [ name = "node-rpc-client" version = "2.0.0" dependencies = [ - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core-client 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2590,7 +2601,7 @@ dependencies = [ [[package]] name = "nodrop" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2767,7 +2778,7 @@ name = "parity-scale-codec" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "bitvec 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "byte-slice-cast 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec-derive 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4669,7 +4680,7 @@ dependencies = [ "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4701,7 +4712,7 @@ name = "substrate-client" version = "2.0.0" dependencies = [ "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4734,7 +4745,7 @@ dependencies = [ name = "substrate-client-db" version = "2.0.0" dependencies = [ - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", "kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", @@ -4761,7 +4772,7 @@ name = "substrate-consensus-aura" version = "2.0.0" dependencies = [ "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4806,7 +4817,7 @@ dependencies = [ name = "substrate-consensus-babe" version = "2.0.0" dependencies = [ - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "fork-tree 2.0.0", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5004,7 +5015,7 @@ dependencies = [ name = "substrate-finality-grandpa" version = "2.0.0" dependencies = [ - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "finality-grandpa 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "fork-tree 2.0.0", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5099,7 +5110,7 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "fork-tree 2.0.0", @@ -5145,7 +5156,7 @@ name = "substrate-offchain" version = "2.0.0" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5402,7 +5413,7 @@ dependencies = [ name = "substrate-service-test" version = "2.0.0" dependencies = [ - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5431,7 +5442,7 @@ dependencies = [ name = "substrate-state-db" version = "2.0.0" dependencies = [ - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5547,7 +5558,7 @@ version = "2.0.0" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5888,7 +5899,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5910,7 +5921,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5974,7 +5985,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6598,7 +6609,7 @@ dependencies = [ "checksum app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e73a24bad9bd6a94d6395382a6c69fe071708ae4409f763c5475e14ee896313d" "checksum arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "bc4662175ead9cd84451d5c35070517777949a2ed84551764129cedb88384841" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" -"checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba" +"checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" "checksum asn1_der 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bea40e881533b1fe23afca9cd1c1ca022219a10fce604099ecfc96bfa26eaf1a" "checksum asn1_der_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e7f92edafad155aff997fa5b727c6429b91e996b5a5d62a2b0adbae1306b5fe" "checksum assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7deb0a829ca7bcfaf5da70b073a8d128619259a7be8216a355e23f00763059e5" @@ -6677,6 +6688,7 @@ dependencies = [ "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" "checksum elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "073be79b6538296faf81c631872676600616073817dd9a440c477ad09b408983" "checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" +"checksum env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "39ecdb7dd54465526f0a56d666e3b2dd5f3a218665a030b6e4ad9e70fa95d8fa" "checksum environmental 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "34f8467a0284de039e6bd0e25c14519538462ba5beb548bb1f03e645097837a8" "checksum erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3beee4bc16478a1b26f2e80ad819a52d24745e292f521a63c16eea5f74b7eb60" "checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9" @@ -6746,7 +6758,7 @@ dependencies = [ "checksum indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a61202fbe46c4a951e9404a720a0180bcf3212c750d735cb5c4ba4dc551299f3" "checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" "checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" -"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" +"checksum iovec 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c9636900aa73ffed13cdbb199f17cd955670bb300927c8d25b517dfa136b6567" "checksum ipnet 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e61c2da0d0f700c77d2d313dbf4f93e41d235fa12c6681fee06621036df4c2af" "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" @@ -6823,7 +6835,7 @@ dependencies = [ "checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" -"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" +"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" "checksum nohash-hasher 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4e657a6ec97f9a3ba46f6f7034ea6db9fcd5b71d25ef1074b7bc03da49be0e8e" "checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" "checksum num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9c3f34cdd24f334cb265d9bf8bfa8a241920d026916785747a92f0e55541a1a" diff --git a/core/authority-discovery/Cargo.toml b/core/authority-discovery/Cargo.toml index a74549eb45..7283e07f89 100644 --- a/core/authority-discovery/Cargo.toml +++ b/core/authority-discovery/Cargo.toml @@ -20,7 +20,7 @@ log = "0.4.8" network = { package = "substrate-network", path = "../../core/network" } primitives = { package = "substrate-primitives", path = "../primitives" } prost = "0.5.0" -serde_json = "1.0.40" +serde_json = "1.0.41" sr-primitives = { path = "../../core/sr-primitives" } tokio-timer = "0.2.11" diff --git a/core/chain-spec/Cargo.toml b/core/chain-spec/Cargo.toml index bff5999ef4..1a3c56affb 100644 --- a/core/chain-spec/Cargo.toml +++ b/core/chain-spec/Cargo.toml @@ -10,7 +10,7 @@ impl-trait-for-tuples = "0.1.2" network = { package = "substrate-network", path = "../../core/network" } primitives = { package = "substrate-primitives", path = "../primitives" } serde = { version = "1.0.101", features = ["derive"] } -serde_json = "1.0.40" +serde_json = "1.0.41" sr-primitives = { path = "../../core/sr-primitives" } tel = { package = "substrate-telemetry", path = "../../core/telemetry" } diff --git a/core/cli/Cargo.toml b/core/cli/Cargo.toml index e3b33746d5..b1cb1d57ca 100644 --- a/core/cli/Cargo.toml +++ b/core/cli/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" [dependencies] clap = "~2.32.0" derive_more = "0.15.0" -env_logger = "0.6.2" +env_logger = "0.7.0" log = "0.4.8" atty = "0.2.13" regex = "1.3.1" @@ -21,7 +21,7 @@ futures = "0.1.29" futures03 = { package = "futures-preview", version = "=0.3.0-alpha.19", features = ["compat"] } fdlimit = "0.1.1" exit-future = "0.1.4" -serde_json = "1.0.40" +serde_json = "1.0.41" panic-handler = { package = "substrate-panic-handler", path = "../../core/panic-handler" } client = { package = "substrate-client", path = "../../core/client" } header-metadata = { package = "substrate-header-metadata", path = "../../core/client/header-metadata" } diff --git a/core/client/Cargo.toml b/core/client/Cargo.toml index 8852988cb1..5a0afd2d6f 100644 --- a/core/client/Cargo.toml +++ b/core/client/Cargo.toml @@ -30,7 +30,7 @@ sr-api-macros = { path = "../sr-api-macros" } header-metadata = { package = "substrate-header-metadata", path = "header-metadata", optional = true } [dev-dependencies] -env_logger = "0.6.2" +env_logger = "0.7.0" tempfile = "3.1.0" test-client = { package = "substrate-test-runtime-client", path = "../test-runtime/client" } kvdb-memorydb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" } diff --git a/core/client/db/Cargo.toml b/core/client/db/Cargo.toml index 891255cb77..7d88c39d7f 100644 --- a/core/client/db/Cargo.toml +++ b/core/client/db/Cargo.toml @@ -27,7 +27,7 @@ header_metadata = { package = "substrate-header-metadata", path = "../header-met [dev-dependencies] substrate-keyring = { path = "../../keyring" } test-client = { package = "substrate-test-runtime-client", path = "../../test-runtime/client" } -env_logger = "0.6.2" +env_logger = "0.7.0" [features] default = [] diff --git a/core/consensus/aura/Cargo.toml b/core/consensus/aura/Cargo.toml index b63987ecb7..a09d510950 100644 --- a/core/consensus/aura/Cargo.toml +++ b/core/consensus/aura/Cargo.toml @@ -35,5 +35,5 @@ network = { package = "substrate-network", path = "../../network", features = [" service = { package = "substrate-service", path = "../../service" } test-client = { package = "substrate-test-runtime-client", path = "../../test-runtime/client" } tokio = "0.1.22" -env_logger = "0.6.2" +env_logger = "0.7.0" tempfile = "3.1.0" diff --git a/core/consensus/babe/Cargo.toml b/core/consensus/babe/Cargo.toml index e225c2503a..b1c2c31f7d 100644 --- a/core/consensus/babe/Cargo.toml +++ b/core/consensus/babe/Cargo.toml @@ -44,7 +44,7 @@ network = { package = "substrate-network", path = "../../network", features = [" service = { package = "substrate-service", path = "../../service" } test-client = { package = "substrate-test-runtime-client", path = "../../test-runtime/client" } tokio = "0.1.22" -env_logger = "0.6.2" +env_logger = "0.7.0" tempfile = "3.1.0" [features] diff --git a/core/finality-grandpa/Cargo.toml b/core/finality-grandpa/Cargo.toml index 0a42ff4531..84178c8a78 100644 --- a/core/finality-grandpa/Cargo.toml +++ b/core/finality-grandpa/Cargo.toml @@ -19,7 +19,7 @@ consensus_common = { package = "substrate-consensus-common", path = "../consensu primitives = { package = "substrate-primitives", path = "../primitives" } substrate-telemetry = { path = "../telemetry" } keystore = { package = "substrate-keystore", path = "../keystore" } -serde_json = "1.0.40" +serde_json = "1.0.41" client = { package = "substrate-client", path = "../client" } header-metadata = { package = "substrate-header-metadata", path = "../client/header-metadata" } inherents = { package = "substrate-inherents", path = "../../core/inherents" } @@ -34,6 +34,6 @@ network = { package = "substrate-network", path = "../network", features = ["tes keyring = { package = "substrate-keyring", path = "../keyring" } test-client = { package = "substrate-test-runtime-client", path = "../test-runtime/client"} babe_primitives = { package = "substrate-consensus-babe-primitives", path = "../consensus/babe/primitives" } -env_logger = "0.6.2" +env_logger = "0.7.0" tokio = "0.1.22" tempfile = "3.1.0" diff --git a/core/keystore/Cargo.toml b/core/keystore/Cargo.toml index ff5696ab37..cc491337cf 100644 --- a/core/keystore/Cargo.toml +++ b/core/keystore/Cargo.toml @@ -10,7 +10,7 @@ primitives = { package = "substrate-primitives", path = "../primitives" } app-crypto = { package = "substrate-application-crypto", path = "../application-crypto" } hex = "0.3.2" rand = "0.7.2" -serde_json = "1.0.40" +serde_json = "1.0.41" subtle = "2.1.1" parking_lot = "0.9.0" diff --git a/core/network/Cargo.toml b/core/network/Cargo.toml index 453fbbeee3..016ddb8010 100644 --- a/core/network/Cargo.toml +++ b/core/network/Cargo.toml @@ -32,7 +32,7 @@ primitives = { package = "substrate-primitives", path = "../../core/primitives" codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } peerset = { package = "substrate-peerset", path = "../../core/peerset" } serde = { version = "1.0.101", features = ["derive"] } -serde_json = "1.0.40" +serde_json = "1.0.41" slog = { version = "2.5.2", features = ["nested-values"] } slog_derive = "0.1.1" smallvec = "0.6.10" @@ -48,7 +48,7 @@ zeroize = "0.10.1" babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../consensus/babe/primitives" } [dev-dependencies] -env_logger = "0.6.2" +env_logger = "0.7.0" keyring = { package = "substrate-keyring", path = "../../core/keyring" } quickcheck = "0.9.0" rand = "0.7.2" diff --git a/core/offchain/Cargo.toml b/core/offchain/Cargo.toml index 8f342ee602..ca9b27eee2 100644 --- a/core/offchain/Cargo.toml +++ b/core/offchain/Cargo.toml @@ -27,7 +27,7 @@ network = { package = "substrate-network", path = "../../core/network" } keystore = { package = "substrate-keystore", path = "../keystore" } [dev-dependencies] -env_logger = "0.6.2" +env_logger = "0.7.0" client-db = { package = "substrate-client-db", path = "../../core/client/db/", default-features = true } test-client = { package = "substrate-test-runtime-client", path = "../../core/test-runtime/client" } tokio = "0.1.22" diff --git a/core/peerset/Cargo.toml b/core/peerset/Cargo.toml index b11e59c770..96b721b41c 100644 --- a/core/peerset/Cargo.toml +++ b/core/peerset/Cargo.toml @@ -13,7 +13,7 @@ libp2p = { version = "0.12.0", default-features = false } linked-hash-map = "0.5.2" log = "0.4.8" lru-cache = "0.1.2" -serde_json = "1.0.40" +serde_json = "1.0.41" [dev-dependencies] rand = "0.7.2" diff --git a/core/rpc-servers/Cargo.toml b/core/rpc-servers/Cargo.toml index 27601d8cc1..80e16bc5ae 100644 --- a/core/rpc-servers/Cargo.toml +++ b/core/rpc-servers/Cargo.toml @@ -9,7 +9,7 @@ jsonrpc-core = "13.2.0" pubsub = { package = "jsonrpc-pubsub", version = "13.2.0" } log = "0.4.8" serde = "1.0.101" -serde_json = "1.0" +serde_json = "1.0.41" sr-primitives = { path = "../sr-primitives" } [target.'cfg(not(target_os = "unknown"))'.dependencies] diff --git a/core/rpc/Cargo.toml b/core/rpc/Cargo.toml index e6f0db1c9c..85998feb1b 100644 --- a/core/rpc/Cargo.toml +++ b/core/rpc/Cargo.toml @@ -14,7 +14,7 @@ log = "0.4.8" primitives = { package = "substrate-primitives", path = "../primitives" } rpc = { package = "jsonrpc-core", version = "13.0.0" } runtime_version = { package = "sr-version", path = "../sr-version" } -serde_json = "1.0.40" +serde_json = "1.0.41" session = { package = "substrate-session", path = "../session" } sr-primitives = { path = "../sr-primitives" } rpc-primitives = { package = "substrate-rpc-primitives", path = "primitives" } diff --git a/core/rpc/api/Cargo.toml b/core/rpc/api/Cargo.toml index b2614dbced..bccafc2a85 100644 --- a/core/rpc/api/Cargo.toml +++ b/core/rpc/api/Cargo.toml @@ -17,6 +17,6 @@ parking_lot = "0.9.0" primitives = { package = "substrate-primitives", path = "../../primitives" } runtime_version = { package = "sr-version", path = "../../sr-version" } serde = { version = "1.0.101", features = ["derive"] } -serde_json = "1.0.40" +serde_json = "1.0.41" txpool = { package = "substrate-transaction-graph", path = "../../transaction-pool/graph" } rpc-primitives = { package = "substrate-rpc-primitives", path = "../../rpc/primitives" } diff --git a/core/serializer/Cargo.toml b/core/serializer/Cargo.toml index b6dfa3f470..4e0e706e2f 100644 --- a/core/serializer/Cargo.toml +++ b/core/serializer/Cargo.toml @@ -6,4 +6,4 @@ edition = "2018" [dependencies] serde = "1.0.101" -serde_json = "1.0.40" +serde_json = "1.0.41" diff --git a/core/service/Cargo.toml b/core/service/Cargo.toml index 5d8abee116..5f5f132233 100644 --- a/core/service/Cargo.toml +++ b/core/service/Cargo.toml @@ -16,7 +16,7 @@ tokio-executor = "0.1.8" tokio-timer = "0.2.11" exit-future = "0.1.4" serde = "1.0.101" -serde_json = "1.0.40" +serde_json = "1.0.41" sysinfo = "0.9.5" target_info = "0.1.0" keystore = { package = "substrate-keystore", path = "../../core/keystore" } diff --git a/core/service/test/Cargo.toml b/core/service/test/Cargo.toml index b4651da7a7..872d63415f 100644 --- a/core/service/test/Cargo.toml +++ b/core/service/test/Cargo.toml @@ -9,7 +9,7 @@ tempdir = "0.3.7" tokio = "0.1.22" futures = "0.1.29" log = "0.4.8" -env_logger = "0.6.2" +env_logger = "0.7.0" fdlimit = "0.1.1" futures03 = { package = "futures-preview", version = "=0.3.0-alpha.19", features = ["compat"] } service = { package = "substrate-service", path = "../../../core/service" } diff --git a/core/sr-primitives/Cargo.toml b/core/sr-primitives/Cargo.toml index ab81df2b53..1074e509a6 100644 --- a/core/sr-primitives/Cargo.toml +++ b/core/sr-primitives/Cargo.toml @@ -20,7 +20,7 @@ externalities = { package = "substrate-externalities", path = "../externalities" impl-trait-for-tuples = "0.1.2" [dev-dependencies] -serde_json = "1.0.40" +serde_json = "1.0.41" primitive-types = "0.5.1" rand = "0.7.2" substrate-offchain = { path = "../offchain" } diff --git a/core/state-db/Cargo.toml b/core/state-db/Cargo.toml index 86298ae909..d271a0e179 100644 --- a/core/state-db/Cargo.toml +++ b/core/state-db/Cargo.toml @@ -11,4 +11,4 @@ primitives = { package = "substrate-primitives", path = "../../core/primitives" codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } [dev-dependencies] -env_logger = "0.6.2" +env_logger = "0.7.0" diff --git a/core/transaction-pool/graph/Cargo.toml b/core/transaction-pool/graph/Cargo.toml index d99291476e..fa0d6f14b6 100644 --- a/core/transaction-pool/graph/Cargo.toml +++ b/core/transaction-pool/graph/Cargo.toml @@ -15,6 +15,6 @@ sr-primitives = { path = "../../sr-primitives" } [dev-dependencies] assert_matches = "1.3.0" -env_logger = "0.6.2" +env_logger = "0.7.0" codec = { package = "parity-scale-codec", version = "1.0.0" } test_runtime = { package = "substrate-test-runtime", path = "../../test-runtime" } diff --git a/node/rpc-client/Cargo.toml b/node/rpc-client/Cargo.toml index 7dca144886..e377f89359 100644 --- a/node/rpc-client/Cargo.toml +++ b/node/rpc-client/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -env_logger = "0.6.2" +env_logger = "0.7.0" futures = "0.1.29" hyper = "0.12.35" jsonrpc-core-client = { version = "13.1.0", features = ["http", "ws"] } diff --git a/node/rpc/Cargo.toml b/node/rpc/Cargo.toml index 6bec6adb6f..6985d94e54 100644 --- a/node/rpc/Cargo.toml +++ b/node/rpc/Cargo.toml @@ -23,5 +23,5 @@ transaction_pool = { package = "substrate-transaction-pool", path = "../../core/ [dev-dependencies] node-testing = { path = "../testing" } node-runtime = { path = "../runtime" } -env_logger = "0.6.2" +env_logger = "0.7.0" futures03 = { package = "futures-preview", version = "=0.3.0-alpha.19" } diff --git a/srml/utility/Cargo.toml b/srml/utility/Cargo.toml index d46ed62a55..5e92bcf88a 100644 --- a/srml/utility/Cargo.toml +++ b/srml/utility/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true } +serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } -- GitLab From 66042f1cc737f4eb5ca8d05db9d981c3e4bd3693 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Thu, 10 Oct 2019 09:52:08 +0200 Subject: [PATCH 202/275] Multi-limb arithmetic for runtime (#3743) * First working version of all operations. * New and improved version of everything. * Minor cleanup. * Fix build * Finalize nignum * Some final works on refactors and tests. * fix build * Some review comments * Bench, better try into and nits * mutify the API * rename to big_uint * unmutify. * Remove resize * Apply suggestions from code review * Update core/sr-primitives/src/sr_arithmetic.rs Co-Authored-By: thiolliere * BEtter proof * Fix panic doc. * Bump. --- core/phragmen/src/lib.rs | 12 +- core/sr-primitives/Cargo.toml | 1 + core/sr-primitives/src/lib.rs | 10 +- core/sr-primitives/src/sr_arithmetic.rs | 1199 +++++++++++++++++++---- node/runtime/src/lib.rs | 4 +- 5 files changed, 1015 insertions(+), 211 deletions(-) diff --git a/core/phragmen/src/lib.rs b/core/phragmen/src/lib.rs index 5295d0f422..e15a857b5f 100644 --- a/core/phragmen/src/lib.rs +++ b/core/phragmen/src/lib.rs @@ -34,8 +34,8 @@ #![cfg_attr(not(feature = "std"), no_std)] use rstd::{prelude::*, collections::btree_map::BTreeMap}; -use sr_primitives::{helpers_128bit::multiply_by_rational_best_effort, Perbill, Rational128}; -use sr_primitives::traits::{Zero, Convert, Member, SimpleArithmetic, Saturating}; +use sr_primitives::{helpers_128bit::multiply_by_rational, Perbill, Rational128}; +use sr_primitives::traits::{Zero, Convert, Member, SimpleArithmetic, Saturating, Bounded}; mod mock; mod tests; @@ -253,11 +253,11 @@ pub fn elect( for e in &n.edges { let c = &mut candidates[e.candidate_index]; if !c.elected && !c.approval_stake.is_zero() { - let temp_n = multiply_by_rational_best_effort( + let temp_n = multiply_by_rational( n.load.n(), n.budget, c.approval_stake, - ); + ).unwrap_or(Bounded::max_value()); let temp_d = n.load.d(); let temp = Rational128::from(temp_n, temp_d); c.score = c.score.lazy_saturating_add(temp); @@ -303,11 +303,11 @@ pub fn elect( if e.load.d() == n.load.d() { // return e.load / n.load. let desired_scale: u128 = Perbill::accuracy().into(); - multiply_by_rational_best_effort( + multiply_by_rational( desired_scale, e.load.n(), n.load.n(), - ) + ).unwrap_or(Bounded::max_value()) } else { // defensive only. Both edge and nominator loads are built from // scores, hence MUST have the same denominator. diff --git a/core/sr-primitives/Cargo.toml b/core/sr-primitives/Cargo.toml index 1074e509a6..2ffe8a010d 100644 --- a/core/sr-primitives/Cargo.toml +++ b/core/sr-primitives/Cargo.toml @@ -26,6 +26,7 @@ rand = "0.7.2" substrate-offchain = { path = "../offchain" } [features] +bench = [] default = ["std"] std = [ "num-traits/std", diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index 36d785f9a6..3c75bae849 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -19,6 +19,10 @@ #![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] +// to allow benchmarking +#![cfg_attr(feature = "bench", feature(test))] +#[cfg(feature = "bench")] extern crate test; + #[doc(hidden)] pub use codec; #[cfg(feature = "std")] @@ -59,13 +63,15 @@ pub use generic::{DigestItem, Digest}; pub use primitives::{TypeId, crypto::{key_types, KeyTypeId, CryptoType}}; pub use app_crypto::RuntimeAppPublic; -/// Re-export arithmetic stuff. +/// Re-export top-level arithmetic stuff. pub use sr_arithmetic::{ Perquintill, Perbill, Permill, Percent, Rational128, Fixed64 }; -/// Re-export 128 bit helpers from sr_arithmetic +/// Re-export 128 bit helpers. pub use sr_arithmetic::helpers_128bit; +/// Re-export big_uint stiff. +pub use sr_arithmetic::biguint; #[cfg(feature = "std")] pub use externalities::set_and_run_with_externalities; diff --git a/core/sr-primitives/src/sr_arithmetic.rs b/core/sr-primitives/src/sr_arithmetic.rs index 20a7f51c1f..043a383a33 100644 --- a/core/sr-primitives/src/sr_arithmetic.rs +++ b/core/sr-primitives/src/sr_arithmetic.rs @@ -20,9 +20,8 @@ use crate::serde::{Serialize, Deserialize}; use rstd::{ - ops, prelude::*, - convert::{TryInto, TryFrom}, - cmp::Ordering, + ops, cmp::Ordering, prelude::*, + convert::{TryFrom, TryInto}, }; use codec::{Encode, Decode}; use crate::traits::{ @@ -669,16 +668,930 @@ impl CheckedAdd for Fixed64 { } } +/// Infinite precision unsigned integer for substrate runtime. +pub mod biguint { + use super::Zero; + use rstd::{cmp::Ordering, ops, prelude::*, cell::RefCell, convert::TryFrom}; + + // A sensible value for this would be half of the dword size of the host machine. Since the + // runtime is compiled to 32bit webassembly, using 32 and 64 for single and double respectively + // should yield the most performance. TODO #3745 we could benchmark this and verify. + /// Representation of a single limb. + pub type Single = u32; + /// Representation of two limbs. + pub type Double = u64; + /// Difference in the number of bits of [`Single`] and [`Double`]. + const SHIFT: usize = 32; + /// short form of _Base_. Analogous to the value 10 in base-10 decimal numbers. + const B: Double = Single::max_value() as Double + 1; + + /// Splits a [`Double`] limb number into a tuple of two [`Single`] limb numbers. + pub fn split(a: Double) -> (Single, Single) { + let al = a as Single; + let ah = (a >> SHIFT) as Single; + (ah, al) + } + + /// Assumed as a given primitive. + /// + /// Multiplication of two singles, which at most yields 1 double. + pub fn mul_single(a: Single, b: Single) -> Double { + let a: Double = a.into(); + let b: Double = b.into(); + let r = a * b; + r + } + + /// Assumed as a given primitive. + /// + /// Addition of two singles, which at most takes a single limb of result and a carry, + /// returned as a tuple respectively. + pub fn add_single(a: Single, b: Single) -> (Single, Single) { + let a: Double = a.into(); + let b: Double = b.into(); + let q = a + b; + let (carry, r) = split(q); + (r, carry) + } + + /// Assumed as a given primitive. + /// + /// Division of double by a single limb. Always returns a double limb of quotient and a single + /// limb of remainder. + fn div_single(a: Double, b: Single) -> (Double, Single) { + let b: Double = b.into(); + let q = a / b; + let r = a % b; + // both conversions are trivially safe. + (q, r as Single) + } + + /// Simple wrapper around an infinitely large integer, represented as limbs of [`Single`]. + #[derive(Clone, Default)] + pub struct BigUint { + /// digits (limbs) of this number (sorted as msb -> lsd). + pub(crate) digits: Vec, + } + + impl BigUint { + /// Create a new instance with `size` limbs. This prevents any number with zero limbs to be + /// created. + /// + /// The behavior of the type is undefined with zero limbs. + pub fn with_capacity(size: usize) -> Self { + Self { digits: vec![0; size.max(1)] } + } + + /// Raw constructor from custom limbs. If `limbs` is empty, `Zero::zero()` implementation is + /// used. + pub fn from_limbs(limbs: &[Single]) -> Self { + if limbs.len() > 0 { + Self { digits: limbs.to_vec() } + } else { + Zero::zero() + } + } + + /// Number of limbs. + pub fn len(&self) -> usize { self.digits.len() } + + /// A naive getter for limb at `index`. Note that the order is lsb -> msb. + /// + /// #### Panics + /// + /// This panics if index is out of range. + pub fn get(&self, index: usize) -> Single { + self.digits[self.len() - 1 - index] + } + + /// A naive getter for limb at `index`. Note that the order is lsb -> msb. + pub fn checked_get(&self, index: usize) -> Option { + if let Some(i) = self.len().checked_sub(1) { + if let Some(j) = i.checked_sub(index) { + return self.digits.get(j).cloned(); + } + } + return None; + } + + /// A naive setter for limb at `index`. Note that the order is lsb -> msb. + /// + /// #### Panics + /// + /// This panics if index is out of range. + pub fn set(&mut self, index: usize, value: Single) { + let len = self.digits.len(); + self.digits[len - 1 - index] = value; + } + + /// returns the least significant limb of the number. + /// + /// #### Panics + /// + /// While the constructor of the type prevents this, this can panic if `self` has no digits. + pub fn lsb(&self) -> Single { + self.digits[self.len() - 1] + } + + /// returns the most significant limb of the number. + /// + /// #### Panics + /// + /// While the constructor of the type prevents this, this can panic if `self` has no digits. + pub fn msb(&self) -> Single { + self.digits[0] + } + + /// Strips zeros from the left side of `self`, if any. + pub fn lstrip(&mut self) { + // by definition, a big-int number should never have leading zero limbs. This function + // has the ability to cause this. There is nothing to do if the number already has 1 + // limb only. call it a day and return. + if self.len().is_zero() { return; } + let mut index = 0; + for elem in self.digits.iter() { + if *elem != 0 { break } else { index += 1 } + } + if index > 0 { + self.digits = self.digits[index..].to_vec() + } + } + + /// Zero-pad `self` from left to reach `size` limbs. Will not make any difference if `self` + /// is already bigger than `size` limbs. + pub fn lpad(&mut self, size: usize) { + let n = self.len(); + if n >= size { return; } + let pad = size - n; + let mut new_digits = (0..pad).map(|_| 0).collect::>(); + new_digits.extend(self.digits.iter()); + self.digits = new_digits; + } + + /// Adds `self` with `other`. self and other do not have to have any particular size. Given + /// that the `n = max{size(self), size(other)}`, it will produce a number with `n + 1` + /// limbs. + /// + /// This function does not strip the output and returns the original allocated `n + 1` + /// limbs. The caller may strip the output if desired. + /// + /// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4. + pub fn add(self, other: &Self) -> Self { + let n = self.len().max(other.len()); + let mut k: Double = 0; + let mut w = Self::with_capacity(n + 1); + + for j in 0..n { + let u = Double::from(self.checked_get(j).unwrap_or(0)); + let v = Double::from(other.checked_get(j).unwrap_or(0)); + let s = u + v + k; + w.set(j, (s % B) as Single); + k = s / B; + } + // k is always 0 or 1. + w.set(n, k as Single); + w + } + + /// Subtracts `other` from `self`. self and other do not have to have any particular size. + /// Given that the `n = max{size(self), size(other)}`, it will produce a number of size `n`. + /// + /// If `other` is bigger than `self`, `Err(B - borrow)` is returned. + /// + /// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4. + pub fn sub(self, other: &Self) -> Result { + let n = self.len().max(other.len()); + let mut k = 0; + let mut w = Self::with_capacity(n); + for j in 0..n { + let s = { + let u = Double::from(self.checked_get(j).unwrap_or(0)); + let v = Double::from(other.checked_get(j).unwrap_or(0)); + let mut needs_borrow = false; + let mut t = 0; + + if let Some(v) = u.checked_sub(v) { + if let Some(v2) = v.checked_sub(k) { + t = v2 % B; + k = 0; + } else { + needs_borrow = true; + } + } else { + needs_borrow = true; + } + if needs_borrow { + t = u + B - v - k; + k = 1; + } + t + }; + // PROOF: t either comes from `v2 % B`, or from `u + B - v - k`. The former is + // trivial. The latter will not overflow this branch will only happen if the sum of + // `u - v - k` part has been negative, hence `u + B - v - k < b`. + w.set(j, s as Single); + } + + if k.is_zero() { + Ok(w) + } else { + Err(w) + } + } + + /// Multiplies n-limb number `self` with m-limb number `other`. + /// + /// The resulting number will always have `n + m` limbs. + /// + /// This function does not strip the output and returns the original allocated `n + m` + /// limbs. The caller may strip the output if desired. + /// + /// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4. + pub fn mul(self, other: &Self) -> Self { + let n = self.len(); + let m = other.len(); + let mut w = Self::with_capacity(m + n); + + for j in 0..n { + if self.get(j) == 0 { + // Note: `with_capacity` allocates with 0. Explicitly set j + m to zero if + // otherwise. + continue; + } + + let mut k = 0; + for i in 0..m { + // PROOF: (B−1) × (B−1) + (B−1) + (B−1) = B^2 −1 < B^2. addition is safe. + let t = + mul_single(self.get(j), other.get(i)) + + Double::from(w.get(i + j)) + + Double::from(k); + w.set(i + j, (t % B) as Single); + // PROOF: (B^2 - 1) / B < B. conversion is safe. + k = (t / B) as Single; + } + w.set(j + m, k); + } + w + } + + /// Divides `self` by a single limb `other`. This can be used in cases where the original + /// division cannot work due to the divisor (`other`) being just one limb. + /// + /// Invariant: `other` cannot be zero. + pub fn div_unit(self, mut other: Single) -> Self { + other = other.max(1); + let n = self.len(); + let mut out = Self::with_capacity(n); + let mut r: Single = 0; + // PROOF: (B-1) * B + (B-1) still fits in double + let with_r = |x: Double, r: Single| { r as Double * B + x }; + for d in (0..=n-1).rev() { + let (q, rr) = div_single(with_r(self.get(d).into(), r), other) ; + out.set(d, q as Single); + r = rr; + } + out + } + + /// Divides an `n + m` limb self by a `n` limb `other`. The result is a `m + 1` limb + /// quotient and a `n` limb remainder, if enabled by passing `true` in `rem` argument, both + /// in the form of an option's `Ok`. + /// + /// - requires `other` to be stripped and have no leading zeros. + /// - requires `self` to be stripped and have no leading zeros. + /// - requires `other` to have at least two limbs. + /// - requires `self` to have a greater length compared to `other`. + /// + /// All arguments are examined without being stripped for the above conditions. If any of + /// the above fails, `None` is returned.` + /// + /// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4. + pub fn div(self, other: &Self, rem: bool) -> Option<(Self, Self)> { + if other.len() <= 1 + || other.msb() == 0 + || self.msb() == 0 + || self.len() <= other.len() + { + return None + } + let n = other.len(); + let m = self.len() - n; + + let mut q = Self::with_capacity(m + 1); + let mut r = Self::with_capacity(n); + + debug_assert!(other.msb() != 0); + + // PROOF: 0 <= normalizer_bits < SHIFT 0 <= normalizer < B. all conversions are + // safe. + let normalizer_bits = other.msb().leading_zeros() as Single; + let normalizer = (2 as Single).pow(normalizer_bits as u32) as Single; + + // step D1. + let mut self_norm = self.mul(&Self::from(normalizer)); + let mut other_norm = other.clone().mul(&Self::from(normalizer)); + + // defensive only; the mul implementation should always create this. + self_norm.lpad(n + m + 1); + other_norm.lstrip(); + + // step D2. + for j in (0..=m).rev() { + // step D3.0 Find an estimate of q[j], named qhat. + let (qhat, rhat) = { + // PROOF: this always fits into `Double`. In the context of Single = u8, and + // Double = u16, think of 255 * 256 + 255 which is just u16::max_value(). + let dividend = + Double::from(self_norm.get(j + n)) + * B + + Double::from(self_norm.get(j + n - 1)); + let divisor = other_norm.get(n - 1); + div_single(dividend, divisor.into()) + }; + + // D3.1 test qhat + // replace qhat and rhat with RefCells. This helps share state with the closure + let qhat = RefCell::new(qhat); + let rhat = RefCell::new(rhat as Double); + + let test = || { + // decrease qhat if it is bigger than the base (B) + let qhat_local = *qhat.borrow(); + let rhat_local = *rhat.borrow(); + let predicate_1 = qhat_local >= B; + let predicate_2 = { + let lhs = qhat_local * other_norm.get(n - 2) as Double; + let rhs = B * rhat_local + self_norm.get(j + n - 2) as Double; + lhs > rhs + }; + if predicate_1 || predicate_2 { + *qhat.borrow_mut() -= 1; + *rhat.borrow_mut() += other_norm.get(n - 1) as Double; + true + } else { + false + } + }; + + test(); + while (*rhat.borrow() as Double) < B { + if !test() { break; } + } + + let qhat = qhat.into_inner(); + // we don't need rhat anymore. just let it go out of scope when it does. + + // step D4 + let lhs = Self { digits: (j..=j+n).rev().map(|d| self_norm.get(d)).collect() }; + let rhs = other_norm.clone().mul(&Self::from(qhat)); + + let maybe_sub = lhs.sub(&rhs); + let mut negative = false; + let sub = match maybe_sub { + Ok(t) => t, + Err(t) => { negative = true; t } + }; + (j..=j+n).for_each(|d| { self_norm.set(d, sub.get(d - j)); }); + + // step D5 + // PROOF: the `test()` specifically decreases qhat until it is below `B`. conversion + // is safe. + q.set(j, qhat as Single); + + // step D6: add back if negative happened. + if negative { + q.set(j, q.get(j) - 1); + let u = Self { digits: (j..=j+n).rev().map(|d| self_norm.get(d)).collect() }; + let r = other_norm.clone().add(&u); + (j..=j+n).rev().for_each(|d| { self_norm.set(d, r.get(d - j)); }) + } + } + + // if requested, calculate remainder. + if rem { + // undo the normalization. + if normalizer_bits > 0 { + let s = SHIFT as u32; + let nb = normalizer_bits; + for d in 0..n-1 { + let v = self_norm.get(d) >> nb + | self_norm.get(d + 1).overflowing_shl(s - nb).0; + r.set(d, v); + } + r.set(n - 1, self_norm.get(n - 1) >> normalizer_bits); + } else { + r = self_norm; + } + } + + Some((q, r)) + } + } + + #[cfg(feature = "std")] + impl rstd::fmt::Debug for BigUint { + fn fmt(&self, f: &mut rstd::fmt::Formatter<'_>) -> rstd::fmt::Result { + write!( + f, + "BigUint {{ {:?} ({:?})}}", + self.digits, + u128::try_from(self.clone()).unwrap_or_else(|_| 0), + ) + } + } + + impl PartialEq for BigUint { + fn eq(&self, other: &Self) -> bool { + // sadly, we have to reallocate here as strip mutably uses self. + let mut lhs = self.clone(); + let mut rhs = other.clone(); + lhs.lstrip(); + rhs.lstrip(); + lhs.digits.eq(&rhs.digits) + } + } + + impl Eq for BigUint {} + + impl Ord for BigUint { + fn cmp(&self, other: &Self) -> Ordering { + let lhs_first = self.digits.iter().position(|&e| e != 0); + let rhs_first = other.digits.iter().position(|&e| e != 0); + + match (lhs_first, rhs_first) { + // edge cases that should not happen. This basically means that one or both were + // zero. + (None, None) => Ordering::Equal, + (Some(_), None) => Ordering::Greater, + (None, Some(_)) => Ordering::Less, + (Some(lhs_idx), Some(rhs_idx)) => { + let lhs = &self.digits[lhs_idx..]; + let rhs = &other.digits[rhs_idx..]; + let len_cmp = lhs.len().cmp(&rhs.len()); + match len_cmp { + Ordering::Equal => lhs.cmp(rhs), + _ => len_cmp, + } + } + } + } + } + + impl PartialOrd for BigUint { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } + } + + impl ops::Add for BigUint { + type Output = Self; + fn add(self, rhs: Self) -> Self::Output { + self.add(&rhs) + } + } + + impl ops::Sub for BigUint { + type Output = Self; + fn sub(self, rhs: Self) -> Self::Output { + self.sub(&rhs).unwrap_or_else(|e| e) + } + } + + impl ops::Mul for BigUint { + type Output = Self; + fn mul(self, rhs: Self) -> Self::Output { + self.mul(&rhs) + } + } + + impl Zero for BigUint { + fn zero() -> Self { + Self { digits: vec![Zero::zero()] } + } + + fn is_zero(&self) -> bool { + self.digits.iter().all(|d| d.is_zero()) + } + } + + macro_rules! impl_try_from_number_for { + ($([$type:ty, $len:expr]),+) => { + $( + impl TryFrom for $type { + type Error = &'static str; + fn try_from(mut value: BigUint) -> Result<$type, Self::Error> { + value.lstrip(); + let error_message = concat!("cannot fit a number into ", stringify!($type)); + if value.len() * SHIFT > $len { + Err(error_message) + } else { + let mut acc: $type = Zero::zero(); + for (i, d) in value.digits.iter().rev().cloned().enumerate() { + let d: $type = d.into(); + acc += d << (SHIFT * i); + } + Ok(acc) + } + } + } + )* + }; + } + // can only be implemented for sizes bigger than two limb. + impl_try_from_number_for!([u128, 128], [u64, 64]); + + macro_rules! impl_from_for_smaller_than_word { + ($($type:ty),+) => { + $(impl From<$type> for BigUint { + fn from(a: $type) -> Self { + Self { digits: vec! [a.into()] } + } + })* + } + } + impl_from_for_smaller_than_word!(u8, u16, Single); + + impl From for BigUint { + fn from(a: Double) -> Self { + let (ah, al) = split(a); + Self { digits: vec![ah, al] } + } + } + + #[cfg(test)] + pub mod tests_biguint { + use super::*; + use rand::Rng; + #[cfg(feature = "bench")] + use test::Bencher; + + // TODO move into a proper fuzzer #3745 + const FUZZ_COUNT: usize = 100_000; + + pub fn random_big_uint(size: usize) -> BigUint { + let mut rng = rand::thread_rng(); + let digits = (0..size).map(|_| rng.gen_range(0, Single::max_value())).collect(); + BigUint { digits } + } + + fn run_with_data_set( + count: usize, + limbs_ub_1: usize, + limbs_ub_2: usize, + exact: bool, + assertion: F, + ) where + F: Fn(BigUint, BigUint) -> () + { + let mut rng = rand::thread_rng(); + for _ in 0..count { + let digits_len_1 = if exact { limbs_ub_1 } else { rng.gen_range(1, limbs_ub_1) }; + let digits_len_2 = if exact { limbs_ub_2 } else { rng.gen_range(1, limbs_ub_2) }; + + let u = random_big_uint(digits_len_1); + let v = random_big_uint(digits_len_2); + assertion(u, v); + } + } + + fn with_limbs(n: usize) -> BigUint { + BigUint { digits: vec![1; n] } + } + + #[test] + fn split_works() { + let a = SHIFT / 2; + let b = SHIFT * 3 / 2; + let num: Double = 1 << a | 1 << b; + // example when `Single = u8` + // assert_eq!(num, 0b_0001_0000_0001_0000) + assert_eq!(split(num), (1 << a, 1 << a)); + } + + #[test] + fn strip_works() { + let mut a = BigUint::from_limbs(&[0, 1, 0]); + a.lstrip(); + assert_eq!(a, BigUint { digits: vec![1, 0] }); + + let mut a = BigUint::from_limbs(&[0, 0, 1]); + a.lstrip(); + assert_eq!(a, BigUint { digits: vec![1] }); + + let mut a = BigUint::from_limbs(&[0, 0]); + a.lstrip(); + assert_eq!(a, BigUint { digits: vec![0] }); + + let mut a = BigUint::from_limbs(&[0, 0, 0]); + a.lstrip(); + assert_eq!(a, BigUint { digits: vec![0] }); + } + + #[test] + fn lpad_works() { + let mut a = BigUint::from_limbs(&[0, 1, 0]); + a.lpad(2); + assert_eq!(a.digits, vec![0, 1, 0]); + + let mut a = BigUint::from_limbs(&[0, 1, 0]); + a.lpad(3); + assert_eq!(a.digits, vec![0, 1, 0]); + + let mut a = BigUint::from_limbs(&[0, 1, 0]); + a.lpad(4); + assert_eq!(a.digits, vec![0, 0, 1, 0]); + } + + #[test] + fn equality_works() { + assert_eq!( + BigUint { digits: vec![1, 2, 3] } == BigUint { digits: vec![1, 2, 3] }, + true, + ); + assert_eq!( + BigUint { digits: vec![3, 2, 3] } == BigUint { digits: vec![1, 2, 3] }, + false, + ); + assert_eq!( + BigUint { digits: vec![0, 1, 2, 3] } == BigUint { digits: vec![1, 2, 3] }, + true, + ); + } + + #[test] + fn ordering_works() { + assert!(BigUint { digits: vec![0] } < BigUint { digits: vec![1] }); + assert!(BigUint { digits: vec![0] } == BigUint { digits: vec![0] }); + assert!(BigUint { digits: vec![] } == BigUint { digits: vec![0] }); + assert!(BigUint { digits: vec![] } == BigUint { digits: vec![] }); + assert!(BigUint { digits: vec![] } < BigUint { digits: vec![1] }); + + assert!(BigUint { digits: vec![1, 2, 3] } == BigUint { digits: vec![1, 2, 3] }); + assert!(BigUint { digits: vec![0, 1, 2, 3] } == BigUint { digits: vec![1, 2, 3] }); + + assert!(BigUint { digits: vec![1, 2, 4] } > BigUint { digits: vec![1, 2, 3] }); + assert!(BigUint { digits: vec![0, 1, 2, 4] } > BigUint { digits: vec![1, 2, 3] }); + assert!(BigUint { digits: vec![1, 2, 1, 0] } > BigUint { digits: vec![1, 2, 3] }); + + assert!(BigUint { digits: vec![0, 1, 2, 1] } < BigUint { digits: vec![1, 2, 3] }); + } + + #[test] + fn basic_random_ord_eq_works() { + type S = u128; + run_with_data_set(FUZZ_COUNT, 4, 4, false, |u, v| { + let ue = S::try_from(u.clone()).unwrap(); + let ve = S::try_from(v.clone()).unwrap(); + assert_eq!(u.cmp(&v), ue.cmp(&ve)); + assert_eq!(u.eq(&v), ue.eq(&ve)); + }) + } + + #[test] + fn can_try_build_numbers_from_types() { + use rstd::convert::TryFrom; + assert_eq!(u64::try_from(with_limbs(1)).unwrap(), 1); + assert_eq!(u64::try_from(with_limbs(2)).unwrap(), u32::max_value() as u64 + 2); + assert_eq!( + u64::try_from(with_limbs(3)).unwrap_err(), + "cannot fit a number into u64", + ); + assert_eq!( + u128::try_from(with_limbs(3)).unwrap(), + u32::max_value() as u128 + u64::max_value() as u128 + 3 + ); + } + + #[test] + fn zero_works() { + assert_eq!(BigUint::zero(), BigUint { digits: vec![0] }); + assert_eq!(BigUint { digits: vec![0, 1, 0] }.is_zero(), false); + assert_eq!(BigUint { digits: vec![0, 0, 0] }.is_zero(), true); + + let a = BigUint::zero(); + let b = BigUint::zero(); + let c = a * b; + assert_eq!(c.digits, vec![0, 0]); + } + + #[test] + fn basic_random_add_works() { + type S = u128; + run_with_data_set(FUZZ_COUNT, 3, 3, false, |u, v| { + let expected = S::try_from(u.clone()).unwrap() + S::try_from(v.clone()).unwrap(); + let t = u.clone().add(&v); + assert_eq!( + S::try_from(t.clone()).unwrap(), expected, + "{:?} + {:?} ===> {:?} != {:?}", u, v, t, expected, + ); + }) + } + + #[test] + fn sub_negative_works() { + assert_eq!( + BigUint::from(10 as Single).sub(&BigUint::from(5 as Single)).unwrap(), + BigUint::from(5 as Single) + ); + assert_eq!( + BigUint::from(10 as Single).sub(&BigUint::from(10 as Single)).unwrap(), + BigUint::from(0 as Single) + ); + assert_eq!( + BigUint::from(10 as Single).sub(&BigUint::from(13 as Single)).unwrap_err(), + BigUint::from((B - 3) as Single), + ); + } + + #[test] + fn basic_random_sub_works() { + type S = u128; + run_with_data_set(FUZZ_COUNT, 4, 4, false, |u, v| { + let expected = S::try_from(u.clone()).unwrap() + .checked_sub(S::try_from(v.clone()).unwrap()); + let t = u.clone().sub(&v); + if expected.is_none() { + assert!(t.is_err()) + } else { + let t = t.unwrap(); + let expected = expected.unwrap(); + assert_eq!( + S::try_from(t.clone()).unwrap(), expected, + "{:?} - {:?} ===> {:?} != {:?}", u, v, t, expected, + ); + } + }) + } + + #[test] + fn basic_random_mul_works() { + type S = u128; + run_with_data_set(FUZZ_COUNT, 2, 2, false, |u, v| { + let expected = S::try_from(u.clone()).unwrap() * S::try_from(v.clone()).unwrap(); + let t = u.clone().mul(&v); + assert_eq!( + S::try_from(t.clone()).unwrap(), expected, + "{:?} * {:?} ===> {:?} != {:?}", u, v, t, expected, + ); + }) + } + + #[test] + fn mul_always_appends_one_digit() { + let a = BigUint::from(10 as Single); + let b = BigUint::from(4 as Single); + assert_eq!(a.len(), 1); + assert_eq!(b.len(), 1); + + let n = a.mul(&b); + + assert_eq!(n.len(), 2); + assert_eq!(n.digits, vec![0, 40]); + } + + #[test] + fn div_conditions_work() { + let a = BigUint { digits: vec![2] }; + let b = BigUint { digits: vec![1, 2] }; + let c = BigUint { digits: vec![1, 1, 2] }; + let d = BigUint { digits: vec![0, 2] }; + let e = BigUint { digits: vec![0, 1, 1, 2] }; + + assert!(a.clone().div(&b, true).is_none()); + assert!(c.clone().div(&a, true).is_none()); + assert!(c.clone().div(&d, true).is_none()); + assert!(e.clone().div(&a, true).is_none()); + + assert!(c.clone().div(&b, true).is_some()); + } + + #[test] + fn div_unit_works() { + let a = BigUint { digits: vec![100] }; + let b = BigUint { digits: vec![1, 100] }; + + assert_eq!(a.clone().div_unit(1), a); + assert_eq!(a.clone().div_unit(0), a); + assert_eq!(a.clone().div_unit(2), BigUint::from(50 as Single)); + assert_eq!(a.clone().div_unit(7), BigUint::from(14 as Single)); + + assert_eq!(b.clone().div_unit(1), b); + assert_eq!(b.clone().div_unit(0), b); + assert_eq!(b.clone().div_unit(2), BigUint::from(((B + 100) / 2) as Single)); + assert_eq!(b.clone().div_unit(7), BigUint::from(((B + 100) / 7) as Single)); + + } + + #[test] + fn basic_random_div_works() { + type S = u128; + run_with_data_set(FUZZ_COUNT, 4, 4, false, |u, v| { + let ue = S::try_from(u.clone()).unwrap(); + let ve = S::try_from(v.clone()).unwrap(); + let (q, r) = (ue / ve, ue % ve); + if let Some((qq, rr)) = u.clone().div(&v, true) { + assert_eq!( + S::try_from(qq.clone()).unwrap(), q, + "{:?} / {:?} ===> {:?} != {:?}", u, v, qq, q, + ); + assert_eq!( + S::try_from(rr.clone()).unwrap(), r, + "{:?} % {:?} ===> {:?} != {:?}", u, v, rr, r, + ); + } else if v.len() == 1 { + let qq = u.clone().div_unit(ve as Single); + assert_eq!( + S::try_from(qq.clone()).unwrap(), q, + "[single] {:?} / {:?} ===> {:?} != {:?}", u, v, qq, q, + ); + } else { + if v.msb() == 0 || v.msb() == 0 || u.len() <= v.len() {} // nada + else { panic!("div returned none for an unexpected reason"); } + } + }) + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_addition_2_digit(bencher: &mut Bencher) { + let a = random_big_uint(2); + let b = random_big_uint(2); + bencher.iter(|| { + let _ = a.clone().add(&b); + }); + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_addition_4_digit(bencher: &mut Bencher) { + let a = random_big_uint(4); + let b = random_big_uint(4); + bencher.iter(|| { + let _ = a.clone().add(&b); + }); + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_subtraction_2_digit(bencher: &mut Bencher) { + let a = random_big_uint(2); + let b = random_big_uint(2); + bencher.iter(|| { + let _ = a.clone().sub(&b); + }); + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_subtraction_4_digit(bencher: &mut Bencher) { + let a = random_big_uint(4); + let b = random_big_uint(4); + bencher.iter(|| { + let _ = a.clone().sub(&b); + }); + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_multiplication_2_digit(bencher: &mut Bencher) { + let a = random_big_uint(2); + let b = random_big_uint(2); + bencher.iter(|| { + let _ = a.clone().mul(&b); + }); + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_multiplication_4_digit(bencher: &mut Bencher) { + let a = random_big_uint(4); + let b = random_big_uint(4); + bencher.iter(|| { + let _ = a.clone().mul(&b); + }); + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_division_4_digit(bencher: &mut Bencher) { + let a = random_big_uint(4); + let b = random_big_uint(2); + bencher.iter(|| { + let _ = a.clone().div(&b, true); + }); + } + } +} + /// Some helper functions to work with 128bit numbers. Note that the functionality provided here is /// only sensible to use with 128bit numbers because for smaller sizes, you can always rely on /// assumptions of a bigger type (u128) being available, or simply create a per-thing and use the /// multiplication implementation provided there. pub mod helpers_128bit { - use super::Perquintill; + use crate::biguint; use crate::traits::Zero; - use rstd::cmp::{min, max}; - - const ERROR: &'static str = "can not accurately multiply by rational in this type"; + use rstd::{cmp::{min, max}, convert::TryInto}; /// Helper gcd function used in Rational128 implementation. pub fn gcd(a: u128, b: u128) -> u128 { @@ -695,18 +1608,31 @@ pub mod helpers_128bit { } } + /// split a u128 into two u64 limbs + pub fn split(a: u128) -> (u64, u64) { + let al = a as u64; + let ah = (a >> 64) as u64; + (ah, al) + } + + /// Convert a u128 to a u32 based biguint. + pub fn to_big_uint(x: u128) -> biguint::BigUint { + let (xh, xl) = split(x); + let (xhh, xhl) = biguint::split(xh); + let (xlh, xll) = biguint::split(xl); + let mut n = biguint::BigUint::from_limbs(&[xhh, xhl, xlh, xll]); + n.lstrip(); + n + } + /// Safely and accurately compute `a * b / c`. The approach is: /// - Simply try `a * b / c`. - /// - Else, swap the operations (divide first) if `a > c` (division is possible) and `b <= c` - /// (overflow cannot happen) - /// - At any point, given an overflow or accuracy loss, return an Error. + /// - Else, convert them both into big numbers and re-try. `Err` is returned if the result + /// cannot be safely casted back to u128. /// /// Invariant: c must be greater than or equal to 1. - /// This might not return Ok even if `b < c`. pub fn multiply_by_rational(a: u128, b: u128, c: u128) -> Result { if a.is_zero() || b.is_zero() { return Ok(Zero::zero()); } - - // invariant: C cannot be zero. let c = c.max(1); // a and b are interchangeable by definition in this function. It always helps to assume the @@ -719,69 +1645,31 @@ pub mod helpers_128bit { if let Some(x) = a.checked_mul(b) { // This is the safest way to go. Try it. Ok(x / c) - } else if a > c { - // if it can be safely swapped and it is a fraction, then swap. - let q = a / c; - let r = a % c; - let r_additional = multiply_by_rational(r, b, c)?; - - let q_part = q.checked_mul(b) - .ok_or(ERROR)?; - let result = q_part.checked_add(r_additional) - .ok_or(ERROR)?; - Ok(result) } else { - Err(ERROR) - } - } - - /// Performs [`multiply_by_rational`]. In case of failure, if `b < c` it tries to approximate - /// the ratio into a perquintillion and return a lossy result. Otherwise, a best effort approach - /// of shifting both b and c is performed until multiply_by_rational can work. - /// - /// This function can very well be lossy and as the name suggests, perform a best effort in the - /// scope of u128 numbers. In case `b > c` and overflow happens, `a` is returned. - /// - /// c must be greater than or equal to 1. - pub fn multiply_by_rational_best_effort(a: u128, b: u128, c: u128) -> u128 { - if a.is_zero() || b.is_zero() { return Zero::zero(); } - let c = c.max(1); - - // unwrap the loop once. This favours performance over readability. - multiply_by_rational(a, b, c).unwrap_or_else(|_| { - if b <= c { - let per_thing = Perquintill::from_rational_approximation(b, c); - per_thing * a + let a_num = to_big_uint(a); + let b_num = to_big_uint(b); + let c_num = to_big_uint(c); + + let mut ab = a_num * b_num; + ab.lstrip(); + let mut q = if c_num.len() == 1 { + // PROOF: if `c_num.len() == 1` then `c` fits in one limb. + ab.div_unit(c as biguint::Single) } else { - let mut shift = 1; - let mut shifted_b = b.checked_shr(shift).unwrap_or(0); - let mut shifted_c = c.checked_shr(shift).unwrap_or(0); - - loop { - if shifted_b.is_zero() || shifted_c.is_zero() { - break a - } - match multiply_by_rational(a, shifted_b, shifted_c) { - Ok(r) => break r, - Err(_) => { - shift = shift + 1; - // by the time we reach here, b >= 1 && c >= 1. Before panic, they have - // to be zero which is prevented to happen by the break. - shifted_b = b.checked_shr(shift) - .expect( - "b >= 1 && c >= 1; break prevents them from ever being zero; \ - panic can only happen after either is zero; qed" - ); - shifted_c = c.checked_shr(shift) - .expect( - "b >= 1 && c >= 1; break prevents them from ever being zero; \ - panic can only happen after either is zero; qed" - ); - } - } - } - } - }) + // PROOF: both `ab` and `c` cannot have leading zero limbs; if length of `c` is 1, + // the previous branch would handle. Also, if ab for sure has a bigger size than + // c, because `a.checked_mul(b)` has failed, hence ab must be at least one limb + // bigger than c. In this case, returning zero is defensive-only and div should + // always return Some. + let (mut q, r) = ab.div(&c_num, true).unwrap_or((Zero::zero(), Zero::zero())); + let r: u128 = r.try_into() + .expect("reminder of div by c is always less than c; qed"); + if r > (c / 2) { q = q.add(&to_big_uint(1)); } + q + }; + q.lstrip(); + q.try_into().map_err(|_| "result cannot fit in u128") + } } } @@ -829,13 +1717,7 @@ impl Rational128 { if den == self.1 { Ok(self) } else { - if den > self.1 { - let n = helpers_128bit::multiply_by_rational(self.0, den, self.1)?; - Ok(Self(n, den)) - } else { - let div = self.1 / den; - Ok(Self(self.0 / div.max(1), den)) - } + helpers_128bit::multiply_by_rational(self.0, den, self.1).map(|n| Self(n, den)) } } @@ -872,9 +1754,9 @@ impl Rational128 { /// /// Overflow might happen during any of the steps. Error is returned in such cases. pub fn checked_add(self, other: Self) -> Result { - let lcm = self.lcm(&other)?; - let self_scaled = self.to_den(lcm)?; - let other_scaled = other.to_den(lcm)?; + let lcm = self.lcm(&other).map_err(|_| "failed to scale to denominator")?; + let self_scaled = self.to_den(lcm).map_err(|_| "failed to scale to denominator")?; + let other_scaled = other.to_den(lcm).map_err(|_| "failed to scale to denominator")?; let n = self_scaled.0.checked_add(other_scaled.0) .ok_or("overflow while adding numerators")?; Ok(Self(n, self_scaled.1)) @@ -884,9 +1766,9 @@ impl Rational128 { /// /// Overflow might happen during any of the steps. None is returned in such cases. pub fn checked_sub(self, other: Self) -> Result { - let lcm = self.lcm(&other)?; - let self_scaled = self.to_den(lcm)?; - let other_scaled = other.to_den(lcm)?; + let lcm = self.lcm(&other).map_err(|_| "failed to scale to denominator")?; + let self_scaled = self.to_den(lcm).map_err(|_| "failed to scale to denominator")?; + let other_scaled = other.to_den(lcm).map_err(|_| "failed to scale to denominator")?; let n = self_scaled.0.checked_sub(other_scaled.0) .ok_or("overflow while subtracting numerators")?; @@ -900,7 +1782,6 @@ impl PartialOrd for Rational128 { } } -/// Note that this implementation can very well be lossy. TODO #3670 impl Ord for Rational128 { fn cmp(&self, other: &Self) -> Ordering { // handle some edge cases. @@ -911,49 +1792,31 @@ impl Ord for Rational128 { } else if other.1.is_zero() { Ordering::Less } else { - // general lossy case - let saturated_lcm = helpers_128bit::multiply_by_rational_best_effort( - self.1, - other.1, - helpers_128bit::gcd(self.1, other.1) - ); - let self_scaled = self.to_den(saturated_lcm) - .unwrap_or(Self(Bounded::max_value(), self.1)); - let other_scaled = other.to_den(saturated_lcm) - .unwrap_or(Self(Bounded::max_value(), other.1)); - self_scaled.n().cmp(&other_scaled.n()) + // Don't even compute gcd. + let self_n = helpers_128bit::to_big_uint(self.0) * helpers_128bit::to_big_uint(other.1); + let other_n = helpers_128bit::to_big_uint(other.0) * helpers_128bit::to_big_uint(self.1); + self_n.cmp(&other_n) } } } -/// Note that this implementation can very well be lossy. TODO #3670 impl PartialEq for Rational128 { fn eq(&self, other: &Self) -> bool { // handle some edge cases. if self.1 == other.1 { self.0.eq(&other.0) } else { - // general lossy case - let saturated_lcm = helpers_128bit::multiply_by_rational_best_effort( - self.1, - other.1, - helpers_128bit::gcd(self.1, other.1) - ); - let self_scaled = self.to_den(saturated_lcm) - .unwrap_or(Self(Bounded::max_value(), self.1)); - let other_scaled = other.to_den(saturated_lcm) - .unwrap_or(Self(Bounded::max_value(), other.1)); - self_scaled.n().eq(&other_scaled.n()) + let self_n = helpers_128bit::to_big_uint(self.0) * helpers_128bit::to_big_uint(other.1); + let other_n = helpers_128bit::to_big_uint(other.0) * helpers_128bit::to_big_uint(self.1); + self_n.eq(&other_n) } } } - #[cfg(test)] mod test_rational128 { use super::*; use super::helpers_128bit::*; - use crate::assert_eq_error_rate; use rand::Rng; const MAX128: u128 = u128::max_value(); @@ -1004,7 +1867,7 @@ mod test_rational128 { assert_eq!(r(4, 10).to_den(5), Ok(r(2, 5))); // up and down with large numbers - assert_eq!(r(MAX128 - 10, MAX128).to_den(10), Ok(r(9, 10))); + assert_eq!(r(MAX128 - 10, MAX128).to_den(10), Ok(r(10, 10))); assert_eq!(r(MAX128 / 2, MAX128).to_den(10), Ok(r(5, 10))); // large to perbill. This is very well needed for phragmen. @@ -1033,7 +1896,7 @@ mod test_rational128 { // large numbers assert_eq!( r(1_000_000_000, MAX128).lcm(&r(7_000_000_000, MAX128-1)), - Err("can not accurately multiply by rational in this type"), + Err("result cannot fit in u128"), ); assert_eq!( r(1_000_000_000, MAX64).lcm(&r(7_000_000_000, MAX64-1)), @@ -1052,7 +1915,7 @@ mod test_rational128 { // errors assert_eq!( r(1, MAX128).checked_add(r(1, MAX128-1)), - Err("can not accurately multiply by rational in this type"), + Err("failed to scale to denominator"), ); assert_eq!( r(7, MAX128).checked_add(r(MAX128, MAX128)), @@ -1073,7 +1936,7 @@ mod test_rational128 { // errors assert_eq!( r(2, MAX128).checked_sub(r(1, MAX128-1)), - Err("can not accurately multiply by rational in this type"), + Err("failed to scale to denominator"), ); assert_eq!( r(7, MAX128).checked_sub(r(MAX128, MAX128)), @@ -1105,7 +1968,6 @@ mod test_rational128 { assert_eq!(multiply_by_rational(7, 20, 30).unwrap(), 7 * 2 / 3); assert_eq!(multiply_by_rational(20, 7, 30).unwrap(), 7 * 2 / 3); - // computed with swap assert_eq!( // MAX128 % 3 == 0 multiply_by_rational(MAX128, 2, 3).unwrap(), @@ -1136,7 +1998,6 @@ mod test_rational128 { 2 * MAX64 - 3, ); - assert_eq!( multiply_by_rational(MAX64 + 100, MAX64_2, MAX64_2 / 2).unwrap(), (MAX64 + 100) * 2, @@ -1146,9 +2007,14 @@ mod test_rational128 { (MAX64 + 100) * 2, ); - // fails to compute. have to use the greedy, lossy version here - assert!(multiply_by_rational(2u128.pow(66) - 1, 2u128.pow(65) - 1, 2u128.pow(65)).is_err()); - assert!(multiply_by_rational(1_000_000_000, MAX128 / 8, MAX128 / 2).is_err()); + assert_eq!( + multiply_by_rational(2u128.pow(66) - 1, 2u128.pow(65) - 1, 2u128.pow(65)).unwrap(), + 73786976294838206461, + ); + assert_eq!( + multiply_by_rational(1_000_000_000, MAX128 / 8, MAX128 / 2).unwrap(), + 250000000, + ); } #[test] @@ -1163,40 +2029,6 @@ mod test_rational128 { ); } - #[test] - fn multiply_by_rational_best_effort_works() { - assert_eq_error_rate!( - multiply_by_rational_best_effort(MAX64 + 100, MAX64_2, MAX64_2 / 2), - (MAX64 + 100) * 2, - 10, - ); - assert_eq_error_rate!( - multiply_by_rational_best_effort(MAX64 + 100, MAX64_2 * 100, MAX64_2 * 100 / 2), - (MAX64 + 100) * 2, - 10, - ); - assert_eq_error_rate!( - multiply_by_rational_best_effort(2u128.pow(66) - 1, 2u128.pow(65) - 1, 2u128.pow(65)), - mul_div(2u128.pow(66) - 1, 2u128.pow(65) - 1, 2u128.pow(65)), - 10, - ); - assert_eq_error_rate!( - multiply_by_rational_best_effort(1_000_000_000, MAX128 / 8, MAX128 / 2), - 1_000_000_000 / 4, - 10, - ); - - assert_eq!( - multiply_by_rational_best_effort(MAX128, MAX128 - 1, MAX128), - MAX128, - ); - - assert_eq!( - multiply_by_rational_best_effort(MAX64, MAX128 / 2, MAX128), - MAX64 / 2, - ); - } - fn do_fuzz_multiply_by_rational( iters: usize, bits: u32, @@ -1242,42 +2074,8 @@ mod test_rational128 { ); } - #[test] - fn fuzz_multiply_by_rational_best_effort_32() { - let f = |a, b, c| multiply_by_rational_best_effort(a, b, c); - println!("\nInvariant: b < c"); - do_fuzz_multiply_by_rational(1_000_000, 32, 0, false, true, f); - println!("every possibility"); - do_fuzz_multiply_by_rational(1_000_000, 32, 0, false, false, f); - } - - #[test] - fn fuzz_multiply_by_rational_best_effort_64() { - let f = |a, b, c| multiply_by_rational_best_effort(a, b, c); - println!("\nInvariant: b < c"); - do_fuzz_multiply_by_rational(1_000_000, 64, 0, false, true, f); - println!("every possibility"); - do_fuzz_multiply_by_rational(1_000_000, 64, 0, false, false, f); - } - - #[test] - fn fuzz_multiply_by_rational_best_effort_96() { - let f = |a, b, c| multiply_by_rational_best_effort(a, b, c); - // println!("\nInvariant: b < c"); - // do_fuzz_multiply_by_rational(1_000_000, 96, 0, false, true, f); - println!("every possibility"); - // do_fuzz_multiply_by_rational(1_000_000, 96, 0, false, false, f); - do_fuzz_multiply_by_rational(10, 96, 0, true, false, f); - } - - #[test] - fn fuzz_multiply_by_rational_best_effort_128() { - let f = |a, b, c| multiply_by_rational_best_effort(a, b, c); - println!("\nInvariant: b < c"); - do_fuzz_multiply_by_rational(1_000_000, 127, 0, false, true, f); - println!("every possibility"); - do_fuzz_multiply_by_rational(1_000_000, 127, 0, false, false, f); - } + // TODO $# move into a proper fuzzer #3745 + const FUZZ_COUNT: usize = 100_000; #[test] fn fuzz_multiply_by_rational_32() { @@ -1286,40 +2084,39 @@ mod test_rational128 { // returning `Err` is fine. let f = |a, b, c| multiply_by_rational(a, b, c).unwrap_or(mul_div(a, b, c)); println!("\nInvariant: b < c"); - do_fuzz_multiply_by_rational(1_000_000, 32, 0, false, true, f); + do_fuzz_multiply_by_rational(FUZZ_COUNT, 32, 0, false, true, f); println!("every possibility"); - do_fuzz_multiply_by_rational(1_000_000, 32, 0, false, false, f); + do_fuzz_multiply_by_rational(FUZZ_COUNT, 32, 0, false, false, f); } #[test] fn fuzz_multiply_by_rational_64() { let f = |a, b, c| multiply_by_rational(a, b, c).unwrap_or(mul_div(a, b, c)); println!("\nInvariant: b < c"); - do_fuzz_multiply_by_rational(1_000_000, 64, 0, false, true, f); + do_fuzz_multiply_by_rational(FUZZ_COUNT, 64, 0, false, true, f); println!("every possibility"); - do_fuzz_multiply_by_rational(1_000_000, 64, 0, false, false, f); + do_fuzz_multiply_by_rational(FUZZ_COUNT, 64, 0, false, false, f); } #[test] fn fuzz_multiply_by_rational_96() { let f = |a, b, c| multiply_by_rational(a, b, c).unwrap_or(mul_div(a, b, c)); println!("\nInvariant: b < c"); - do_fuzz_multiply_by_rational(1_000_000, 96, 0, false, true, f); + do_fuzz_multiply_by_rational(FUZZ_COUNT, 96, 0, false, true, f); println!("every possibility"); - do_fuzz_multiply_by_rational(1_000_000, 96, 0, false, false, f); + do_fuzz_multiply_by_rational(FUZZ_COUNT, 96, 0, false, false, f); } #[test] fn fuzz_multiply_by_rational_128() { let f = |a, b, c| multiply_by_rational(a, b, c).unwrap_or(mul_div(a, b, c)); println!("\nInvariant: b < c"); - do_fuzz_multiply_by_rational(1_000_000, 127, 0, false, true, f); + do_fuzz_multiply_by_rational(FUZZ_COUNT, 127, 0, false, true, f); println!("every possibility"); - do_fuzz_multiply_by_rational(1_000_000, 127, 0, false, false, f); + do_fuzz_multiply_by_rational(FUZZ_COUNT, 127, 0, false, false, f); } } - #[cfg(test)] mod tests_fixed64 { use super::*; diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index ebe7b134e0..c132e2d430 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -84,8 +84,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 173, - impl_version: 173, + spec_version: 174, + impl_version: 174, apis: RUNTIME_API_VERSIONS, }; -- GitLab From f922df62fa7db34f8731514133f0b120259cabbc Mon Sep 17 00:00:00 2001 From: Xiliang Chen Date: Thu, 10 Oct 2019 23:41:42 +1300 Subject: [PATCH 203/275] Decouple randomness-collective-flip (#3792) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Abstract Randomness trait * bump version * fix doc test * simpify code a bit * Apply suggestions from code review Co-Authored-By: Bastian Köcher Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * fix tests --- node-template/runtime/src/lib.rs | 2 +- node/runtime/src/lib.rs | 5 +-- srml/contracts/Cargo.toml | 4 +-- srml/contracts/src/exec.rs | 4 +-- srml/contracts/src/lib.rs | 5 +-- srml/contracts/src/tests.rs | 2 ++ srml/randomness-collective-flip/src/lib.rs | 37 ++++++++-------------- srml/support/src/traits.rs | 20 ++++++++++++ 8 files changed, 46 insertions(+), 33 deletions(-) diff --git a/node-template/runtime/src/lib.rs b/node-template/runtime/src/lib.rs index ba328c6e37..0e9b8050f0 100644 --- a/node-template/runtime/src/lib.rs +++ b/node-template/runtime/src/lib.rs @@ -33,7 +33,7 @@ pub use sr_primitives::BuildStorage; pub use timestamp::Call as TimestampCall; pub use balances::Call as BalancesCall; pub use sr_primitives::{Permill, Perbill}; -pub use support::{StorageValue, construct_runtime, parameter_types}; +pub use support::{StorageValue, construct_runtime, parameter_types, traits::Randomness}; /// An index to a block. pub type BlockNumber = u32; diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index c132e2d430..6ecce4c481 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -22,7 +22,7 @@ use rstd::prelude::*; use support::{ - construct_runtime, parameter_types, traits::{SplitTwoWays, Currency} + construct_runtime, parameter_types, traits::{SplitTwoWays, Currency, Randomness} }; use primitives::u32_trait::{_1, _2, _3, _4}; use node_primitives::{ @@ -85,7 +85,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 174, - impl_version: 174, + impl_version: 175, apis: RUNTIME_API_VERSIONS, }; @@ -398,6 +398,7 @@ parameter_types! { impl contracts::Trait for Runtime { type Currency = Balances; type Time = Timestamp; + type Randomness = RandomnessCollectiveFlip; type Call = Call; type Event = Event; type DetermineContractAddress = contracts::SimpleAddressDeterminator; diff --git a/srml/contracts/Cargo.toml b/srml/contracts/Cargo.toml index aad45df860..365566cfb5 100644 --- a/srml/contracts/Cargo.toml +++ b/srml/contracts/Cargo.toml @@ -17,8 +17,6 @@ rstd = { package = "sr-std", path = "../../core/sr-std", default-features = fals sandbox = { package = "sr-sandbox", path = "../../core/sr-sandbox", default-features = false } support = { package = "srml-support", path = "../support", default-features = false } system = { package = "srml-system", path = "../system", default-features = false } -randomness-collective-flip = { package = "srml-randomness-collective-flip", path = "../randomness-collective-flip", default-features = false } -timestamp = { package = "srml-timestamp", path = "../timestamp", default-features = false } [dev-dependencies] wabt = "0.9.2" @@ -27,6 +25,7 @@ hex-literal = "0.2.1" balances = { package = "srml-balances", path = "../balances" } hex = "0.3.2" timestamp = { package = "srml-timestamp", path = "../timestamp" } +randomness-collective-flip = { package = "srml-randomness-collective-flip", path = "../randomness-collective-flip" } [features] default = ["std"] @@ -35,7 +34,6 @@ std = [ "codec/std", "primitives/std", "sr-primitives/std", - "randomness-collective-flip/std", "runtime-io/std", "rstd/std", "sandbox/std", diff --git a/srml/contracts/src/exec.rs b/srml/contracts/src/exec.rs index 0cb0ee2679..a2dd3c1f3d 100644 --- a/srml/contracts/src/exec.rs +++ b/srml/contracts/src/exec.rs @@ -22,7 +22,7 @@ use crate::rent; use rstd::prelude::*; use sr_primitives::traits::{Bounded, CheckedAdd, CheckedSub, Zero}; -use support::traits::{WithdrawReason, Currency, Time}; +use support::traits::{WithdrawReason, Currency, Time, Randomness}; pub type AccountIdOf = ::AccountId; pub type CallOf = ::Call; @@ -753,7 +753,7 @@ where } fn random(&self, subject: &[u8]) -> SeedOf { - randomness_collective_flip::Module::::random(subject) + T::Randomness::random(subject) } fn now(&self) -> &MomentOf { diff --git a/srml/contracts/src/lib.rs b/srml/contracts/src/lib.rs index 918d0838c4..678fc65d76 100644 --- a/srml/contracts/src/lib.rs +++ b/srml/contracts/src/lib.rs @@ -122,9 +122,9 @@ use sr_primitives::{ use support::dispatch::{Result, Dispatchable}; use support::{ Parameter, decl_module, decl_event, decl_storage, storage::child, - parameter_types, + parameter_types, IsSubType }; -use support::{traits::{OnFreeBalanceZero, OnUnbalanced, Currency, Get, Time}, IsSubType}; +use support::traits::{OnFreeBalanceZero, OnUnbalanced, Currency, Get, Time, Randomness}; use system::{ensure_signed, RawOrigin, ensure_root}; use primitives::storage::well_known_keys::CHILD_STORAGE_KEY_PREFIX; @@ -335,6 +335,7 @@ parameter_types! { pub trait Trait: system::Trait { type Currency: Currency; type Time: Time; + type Randomness: Randomness; /// The outer call dispatch type. type Call: Parameter + Dispatchable::Origin> + IsSubType, Self>; diff --git a/srml/contracts/src/tests.rs b/srml/contracts/src/tests.rs index a92d11e4d4..9d02419b17 100644 --- a/srml/contracts/src/tests.rs +++ b/srml/contracts/src/tests.rs @@ -159,6 +159,7 @@ parameter_types! { impl Trait for Test { type Currency = Balances; type Time = Timestamp; + type Randomness = Randomness; type Call = Call; type DetermineContractAddress = DummyContractAddressFor; type Event = MetaEvent; @@ -187,6 +188,7 @@ type Balances = balances::Module; type Timestamp = timestamp::Module; type Contract = Module; type System = system::Module; +type Randomness = randomness_collective_flip::Module; pub struct DummyContractAddressFor; impl ContractAddressFor for DummyContractAddressFor { diff --git a/srml/randomness-collective-flip/src/lib.rs b/srml/randomness-collective-flip/src/lib.rs index e5110c5d21..4ad0095fdf 100644 --- a/srml/randomness-collective-flip/src/lib.rs +++ b/srml/randomness-collective-flip/src/lib.rs @@ -35,7 +35,7 @@ //! ### Example - Get random seed for the current block //! //! ``` -//! use support::{decl_module, dispatch::Result}; +//! use support::{decl_module, dispatch::Result, traits::Randomness}; //! //! pub trait Trait: system::Trait {} //! @@ -54,7 +54,7 @@ use rstd::{prelude::*, convert::TryInto}; use sr_primitives::traits::Hash; -use support::{decl_module, decl_storage}; +use support::{decl_module, decl_storage, traits::Randomness}; use safe_mix::TripletMix; use codec::Encode; use system::Trait; @@ -91,16 +91,7 @@ decl_storage! { } } -impl Module { - /// Get the basic random seed. - /// - /// In general you won't want to use this, but rather `Self::random` which allows you to give a - /// subject for the random result and whose value will be independently low-influence random - /// from any other such seeds. - pub fn random_seed() -> T::Hash { - Self::random(&[][..]) - } - +impl Randomness for Module { /// Get a low-influence "random" value. /// /// Being a deterministic block chain, real randomness is difficult to come by. This gives you @@ -138,7 +129,7 @@ impl Module { /// WARNING: Hashing the result of this function will remove any low-influence properties it has /// and mean that all bits of the resulting value are entirely manipulatable by the author of /// the parent block, who can determine the value of `parent_hash`. - pub fn random(subject: &[u8]) -> T::Hash { + fn random(subject: &[u8]) -> T::Hash { let block_number = >::block_number(); let index = block_number_to_index::(block_number); @@ -166,7 +157,7 @@ mod tests { Perbill, traits::{BlakeTwo256, OnInitialize, Header as _, IdentityLookup}, testing::Header, set_and_run_with_externalities, }; - use support::{impl_outer_origin, parameter_types}; + use support::{impl_outer_origin, parameter_types, traits::Randomness}; #[derive(Clone, PartialEq, Eq)] pub struct Test; @@ -202,7 +193,7 @@ mod tests { } type System = system::Module; - type Randomness = Module; + type CollectiveFlip = Module; fn new_test_ext() -> runtime_io::TestExternalities { let t = system::GenesisConfig::default().build_storage::().unwrap(); @@ -221,7 +212,7 @@ mod tests { for i in 1 .. (blocks + 1) { System::initialize(&i, &parent_hash, &Default::default(), &Default::default()); - Randomness::on_initialize(i); + CollectiveFlip::on_initialize(i); let header = System::finalize(); parent_hash = header.hash(); @@ -236,7 +227,7 @@ mod tests { setup_blocks(38); - let random_material = Randomness::random_material(); + let random_material = CollectiveFlip::random_material(); assert_eq!(random_material.len(), 38); assert_eq!(random_material[0], genesis_hash); @@ -250,7 +241,7 @@ mod tests { setup_blocks(81); - let random_material = Randomness::random_material(); + let random_material = CollectiveFlip::random_material(); assert_eq!(random_material.len(), 81); assert_ne!(random_material[0], random_material[1]); @@ -265,7 +256,7 @@ mod tests { setup_blocks(162); - let random_material = Randomness::random_material(); + let random_material = CollectiveFlip::random_material(); assert_eq!(random_material.len(), 81); assert_ne!(random_material[0], random_material[1]); @@ -279,13 +270,13 @@ mod tests { setup_blocks(162); assert_eq!(System::block_number(), 162); - assert_eq!(Randomness::random_seed(), Randomness::random_seed()); - assert_ne!(Randomness::random(b"random_1"), Randomness::random(b"random_2")); + assert_eq!(CollectiveFlip::random_seed(), CollectiveFlip::random_seed()); + assert_ne!(CollectiveFlip::random(b"random_1"), CollectiveFlip::random(b"random_2")); - let random = Randomness::random_seed(); + let random = CollectiveFlip::random_seed(); assert_ne!(random, H256::zero()); - assert!(!Randomness::random_material().contains(&random)); + assert!(!CollectiveFlip::random_material().contains(&random)); }); } } diff --git a/srml/support/src/traits.rs b/srml/support/src/traits.rs index 88e6159365..694e6ec4b0 100644 --- a/srml/support/src/traits.rs +++ b/srml/support/src/traits.rs @@ -717,3 +717,23 @@ pub trait InitializeMembers { impl InitializeMembers for () { fn initialize_members(_: &[T]) {} } + +// A trait that is able to provide randomness. +pub trait Randomness { + /// Get a "random" value + /// + /// Being a deterministic blockchain, real randomness is difficult to come by. This gives you + /// something that approximates it. `subject` is a context identifier and allows you to get a + /// different result to other callers of this function; use it like + /// `random(&b"my context"[..])`. + fn random(subject: &[u8]) -> Output; + + /// Get the basic random seed. + /// + /// In general you won't want to use this, but rather `Self::random` which allows you to give a + /// subject for the random result and whose value will be independently low-influence random + /// from any other such seeds. + fn random_seed() -> Output { + Self::random(&[][..]) + } +} -- GitLab From 7adfd837565f870882cb9726e546dc9df6804885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 10 Oct 2019 15:01:30 +0200 Subject: [PATCH 204/275] Add `execute_with` to `TestExternalities` (#3793) This function executes the given closure in a context where the test externalities are set. This makes the srml tests easier to write, as the test externalities need to be created anyway. --- Cargo.lock | 1 - core/sr-primitives/Cargo.toml | 2 - core/sr-primitives/src/lib.rs | 3 - core/sr-primitives/src/offchain/http.rs | 5 +- core/state-machine/src/testing.rs | 7 + core/test-runtime/src/system.rs | 25 +- node-template/runtime/src/template.rs | 5 +- node/executor/src/lib.rs | 24 +- srml/assets/src/lib.rs | 21 +- srml/aura/src/tests.rs | 3 +- srml/authority-discovery/src/lib.rs | 8 +- srml/authorship/src/lib.rs | 9 +- srml/babe/src/tests.rs | 12 +- srml/balances/src/tests.rs | 374 ++--- srml/collective/src/lib.rs | 44 +- srml/contracts/src/exec.rs | 409 +++-- srml/contracts/src/tests.rs | 1727 ++++++++++---------- srml/democracy/src/lib.rs | 73 +- srml/elections-phragmen/src/lib.rs | 78 +- srml/elections/src/mock.rs | 5 +- srml/elections/src/tests.rs | 271 +-- srml/example/src/lib.rs | 8 +- srml/executive/src/lib.rs | 19 +- srml/finality-tracker/src/lib.rs | 8 +- srml/generic-asset/src/tests.rs | 803 +++++---- srml/grandpa/src/tests.rs | 14 +- srml/im-online/src/tests.rs | 13 +- srml/indices/src/tests.rs | 65 +- srml/membership/src/lib.rs | 15 +- srml/offences/src/tests.rs | 15 +- srml/randomness-collective-flip/src/lib.rs | 9 +- srml/scored-pool/src/tests.rs | 34 +- srml/session/src/historical.rs | 8 +- srml/session/src/lib.rs | 25 +- srml/staking/src/mock.rs | 4 +- srml/staking/src/tests.rs | 1012 ++++++------ srml/support/src/lib.rs | 17 +- srml/support/src/storage/storage_items.rs | 13 +- srml/support/test/tests/instance.rs | 7 +- srml/system/benches/bench.rs | 6 +- srml/system/src/lib.rs | 36 +- srml/timestamp/src/lib.rs | 11 +- srml/treasury/src/lib.rs | 33 +- srml/utility/src/lib.rs | 7 +- 44 files changed, 2506 insertions(+), 2782 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a1ead4978..6e7dea9d1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3841,7 +3841,6 @@ dependencies = [ "sr-io 2.0.0", "sr-std 2.0.0", "substrate-application-crypto 2.0.0", - "substrate-externalities 2.0.0", "substrate-offchain 2.0.0", "substrate-primitives 2.0.0", ] diff --git a/core/sr-primitives/Cargo.toml b/core/sr-primitives/Cargo.toml index 2ffe8a010d..ac6e8685e2 100644 --- a/core/sr-primitives/Cargo.toml +++ b/core/sr-primitives/Cargo.toml @@ -16,7 +16,6 @@ runtime_io = { package = "sr-io", path = "../sr-io", default-features = false } log = { version = "0.4.8", optional = true } paste = "0.1.6" rand = { version = "0.7.2", optional = true } -externalities = { package = "substrate-externalities", path = "../externalities", optional = true } impl-trait-for-tuples = "0.1.2" [dev-dependencies] @@ -38,5 +37,4 @@ std = [ "primitives/std", "app-crypto/std", "rand", - "externalities", ] diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index 3c75bae849..7032560d0f 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -73,9 +73,6 @@ pub use sr_arithmetic::helpers_128bit; /// Re-export big_uint stiff. pub use sr_arithmetic::biguint; -#[cfg(feature = "std")] -pub use externalities::set_and_run_with_externalities; - /// An abstraction over justification for a block's validity under a consensus algorithm. /// /// Essentially a finality proof. The exact formulation will vary between consensus diff --git a/core/sr-primitives/src/offchain/http.rs b/core/sr-primitives/src/offchain/http.rs index 2d84f175d1..b68cf28365 100644 --- a/core/sr-primitives/src/offchain/http.rs +++ b/core/sr-primitives/src/offchain/http.rs @@ -512,7 +512,6 @@ impl<'a> HeadersIterator<'a> { #[cfg(test)] mod tests { use super::*; - use crate::set_and_run_with_externalities; use runtime_io::TestExternalities; use substrate_offchain::testing; use primitives::offchain::OffchainExt; @@ -523,7 +522,7 @@ mod tests { let mut t = TestExternalities::default(); t.register_extension(OffchainExt::new(offchain)); - set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { let request: Request = Request::get("http://localhost:1234"); let pending = request .add_header("X-Auth", "hunter2") @@ -564,7 +563,7 @@ mod tests { let mut t = TestExternalities::default(); t.register_extension(OffchainExt::new(offchain)); - set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { let pending = Request::default() .method(Method::Post) .url("http://localhost:1234") diff --git a/core/state-machine/src/testing.rs b/core/state-machine/src/testing.rs index ea63eac021..ca89921ff0 100644 --- a/core/state-machine/src/testing.rs +++ b/core/state-machine/src/testing.rs @@ -113,6 +113,13 @@ impl, N: ChangesTrieBlockNumber> TestExternalities { self.backend.update(top.chain(children).collect()) } + + /// Execute the given closure while `self` is set as externalities. + /// + /// Returns the result of the given closure. + pub fn execute_with(&mut self, execute: impl FnOnce() -> R) -> R { + externalities::set_and_run_with_externalities(self, execute) + } } impl, N: ChangesTrieBlockNumber> std::fmt::Debug for TestExternalities { diff --git a/core/test-runtime/src/system.rs b/core/test-runtime/src/system.rs index 81bca2fad3..f3359aa1ba 100644 --- a/core/test-runtime/src/system.rs +++ b/core/test-runtime/src/system.rs @@ -321,7 +321,6 @@ mod tests { use runtime_io::TestExternalities; use substrate_test_runtime_client::{AccountKeyring, Sr25519Keyring}; - use sr_primitives::set_and_run_with_externalities; use crate::{Header, Transfer, WASM_BINARY}; use primitives::{NeverNativeValue, map, traits::CodeExecutor}; use substrate_executor::{NativeExecutor, WasmExecutionMethod, native_executor_instance}; @@ -371,18 +370,14 @@ mod tests { extrinsics: vec![], }; - set_and_run_with_externalities(&mut new_test_ext(), || polish_block(&mut b)); + new_test_ext().execute_with(|| polish_block(&mut b)); block_executor(b, &mut new_test_ext()); } #[test] fn block_import_works_native() { - block_import_works(|b, ext| { - set_and_run_with_externalities(ext, || { - execute_block(b); - }); - }); + block_import_works(|b, ext| ext.execute_with(|| execute_block(b))); } #[test] @@ -420,7 +415,7 @@ mod tests { }; let mut dummy_ext = new_test_ext(); - set_and_run_with_externalities(&mut dummy_ext, || polish_block(&mut b1)); + dummy_ext.execute_with(|| polish_block(&mut b1)); let mut b2 = Block { header: Header { @@ -446,26 +441,26 @@ mod tests { ], }; - set_and_run_with_externalities(&mut dummy_ext, || polish_block(&mut b2)); + dummy_ext.execute_with(|| polish_block(&mut b2)); drop(dummy_ext); let mut t = new_test_ext(); - set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { assert_eq!(balance_of(AccountKeyring::Alice.into()), 111); assert_eq!(balance_of(AccountKeyring::Bob.into()), 0); }); block_executor(b1, &mut t); - set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { assert_eq!(balance_of(AccountKeyring::Alice.into()), 42); assert_eq!(balance_of(AccountKeyring::Bob.into()), 69); }); block_executor(b2, &mut t); - set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { assert_eq!(balance_of(AccountKeyring::Alice.into()), 0); assert_eq!(balance_of(AccountKeyring::Bob.into()), 42); assert_eq!(balance_of(AccountKeyring::Charlie.into()), 69); @@ -474,11 +469,7 @@ mod tests { #[test] fn block_import_with_transaction_works_native() { - block_import_with_transaction_works(|b, ext| { - set_and_run_with_externalities(ext, || { - execute_block(b); - }); - }); + block_import_with_transaction_works(|b, ext| ext.execute_with(|| execute_block(b))); } #[test] diff --git a/node-template/runtime/src/template.rs b/node-template/runtime/src/template.rs index 0266890dd8..eb4398787d 100644 --- a/node-template/runtime/src/template.rs +++ b/node-template/runtime/src/template.rs @@ -72,8 +72,7 @@ mod tests { use primitives::H256; use support::{impl_outer_origin, assert_ok, parameter_types}; use sr_primitives::{ - set_and_run_with_externalities, traits::{BlakeTwo256, IdentityLookup}, testing::Header, - weights::Weight, Perbill, + traits::{BlakeTwo256, IdentityLookup}, testing::Header, weights::Weight, Perbill, }; impl_outer_origin! { @@ -122,7 +121,7 @@ mod tests { #[test] fn it_works_for_default_value() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // Just a dummy test for the dummy funtion `do_something` // calling the `do_something` function with a value 42 assert_ok!(TemplateModule::do_something(Origin::signed(1), 42)); diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index 40c1e08f9b..2c2ad479f5 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -226,7 +226,7 @@ mod tests { ).0; assert!(r.is_ok()); - sr_primitives::set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); @@ -262,7 +262,7 @@ mod tests { ).0; assert!(r.is_ok()); - sr_primitives::set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); @@ -433,7 +433,7 @@ mod tests { None, ).0.unwrap(); - sr_primitives::set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); assert_eq!(Balances::total_balance(&bob()), 169 * DOLLARS); let events = vec![ @@ -468,7 +468,7 @@ mod tests { None, ).0.unwrap(); - sr_primitives::set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { // NOTE: fees differ slightly in tests that execute more than one block due to the // weight update. Hence, using `assert_eq_error_rate`. assert_eq_error_rate!( @@ -540,7 +540,7 @@ mod tests { None, ).0.unwrap(); - sr_primitives::set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); assert_eq!(Balances::total_balance(&bob()), 169 * DOLLARS); }); @@ -553,7 +553,7 @@ mod tests { None, ).0.unwrap(); - sr_primitives::set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { assert_eq_error_rate!( Balances::total_balance(&alice()), 32 * DOLLARS - 2 * transfer_fee(&xt()), @@ -715,7 +715,7 @@ mod tests { None, ).0.unwrap(); - sr_primitives::set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { // Verify that the contract constructor worked well and code of TRANSFER contract is actually deployed. assert_eq!( &contracts::ContractInfoOf::::get(addr) @@ -836,7 +836,7 @@ mod tests { .expect("Extrinsic could be applied") .expect("Extrinsic did not fail"); - sr_primitives::set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - 1 * transfer_fee(&xt())); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); @@ -895,7 +895,7 @@ mod tests { let mut prev_multiplier = WeightMultiplier::default(); - sr_primitives::set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { assert_eq!(System::next_weight_multiplier(), prev_multiplier); }); @@ -947,7 +947,7 @@ mod tests { ).0.unwrap(); // weight multiplier is increased for next block. - sr_primitives::set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { let fm = System::next_weight_multiplier(); println!("After a big block: {:?} -> {:?}", prev_multiplier, fm); assert!(fm > prev_multiplier); @@ -964,7 +964,7 @@ mod tests { ).0.unwrap(); // weight multiplier is increased for next block. - sr_primitives::set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { let fm = System::next_weight_multiplier(); println!("After a small block: {:?} -> {:?}", prev_multiplier, fm); assert!(fm < prev_multiplier); @@ -1018,7 +1018,7 @@ mod tests { ).0; assert!(r.is_ok()); - sr_primitives::set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { assert_eq!(Balances::total_balance(&bob()), (10 + 69) * DOLLARS); // Components deducted from alice's balances: // - Weight fee diff --git a/srml/assets/src/lib.rs b/srml/assets/src/lib.rs index e7f258483f..de95caf88f 100644 --- a/srml/assets/src/lib.rs +++ b/srml/assets/src/lib.rs @@ -244,10 +244,7 @@ mod tests { use primitives::H256; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. - use sr_primitives::{ - Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header, - set_and_run_with_externalities, - }; + use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; impl_outer_origin! { pub enum Origin for Test {} @@ -297,7 +294,7 @@ mod tests { #[test] fn issuing_asset_units_to_issuer_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); }); @@ -305,7 +302,7 @@ mod tests { #[test] fn querying_total_supply_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50)); @@ -322,7 +319,7 @@ mod tests { #[test] fn transferring_amount_above_available_balance_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50)); @@ -333,7 +330,7 @@ mod tests { #[test] fn transferring_amount_less_than_available_balance_should_not_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50)); @@ -347,7 +344,7 @@ mod tests { #[test] fn transferring_less_than_one_unit_should_not_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 0), "transfer amount should be non-zero"); @@ -356,7 +353,7 @@ mod tests { #[test] fn transferring_more_units_than_total_supply_should_not_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 101), "origin account balance must be greater than or equal to the transfer amount"); @@ -365,7 +362,7 @@ mod tests { #[test] fn destroying_asset_balance_with_positive_balance_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); assert_ok!(Assets::destroy(Origin::signed(1), 0)); @@ -374,7 +371,7 @@ mod tests { #[test] fn destroying_asset_balance_with_zero_balance_should_not_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 2), 0); assert_noop!(Assets::destroy(Origin::signed(2), 0), "origin balance should be non-zero"); diff --git a/srml/aura/src/tests.rs b/srml/aura/src/tests.rs index 0537fc8b64..a90ec3a861 100644 --- a/srml/aura/src/tests.rs +++ b/srml/aura/src/tests.rs @@ -18,12 +18,11 @@ #![cfg(test)] -use sr_primitives::set_and_run_with_externalities; use crate::mock::{Aura, new_test_ext}; #[test] fn initial_values() { - set_and_run_with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { + new_test_ext(vec![0, 1, 2, 3]).execute_with(|| { assert_eq!(Aura::last(), 0u64); assert_eq!(Aura::authorities().len(), 4); }); diff --git a/srml/authority-discovery/src/lib.rs b/srml/authority-discovery/src/lib.rs index 38d587ba05..177e11c4c0 100644 --- a/srml/authority-discovery/src/lib.rs +++ b/srml/authority-discovery/src/lib.rs @@ -139,7 +139,7 @@ mod tests { use runtime_io::TestExternalities; use sr_primitives::{ testing::{Header, UintAuthorityId}, traits::{ConvertInto, IdentityLookup, OpaqueKeys}, - Perbill, set_and_run_with_externalities, + Perbill, }; use support::{impl_outer_origin, parameter_types}; @@ -263,7 +263,7 @@ mod tests { let mut externalities = TestExternalities::new(t); externalities.register_extension(KeystoreExt(key_store)); - set_and_run_with_externalities(&mut externalities, || { + externalities.execute_with(|| { assert_eq!( authority_id, AuthorityDiscovery::authority_id().expect("Retrieving public key.") @@ -300,7 +300,7 @@ mod tests { let mut externalities = TestExternalities::new(t); externalities.register_extension(KeystoreExt(key_store)); - set_and_run_with_externalities(&mut externalities, || { + externalities.execute_with(|| { assert_eq!(None, AuthorityDiscovery::authority_id()); }); } @@ -337,7 +337,7 @@ mod tests { let mut externalities = TestExternalities::new(t); externalities.register_extension(KeystoreExt(key_store)); - set_and_run_with_externalities(&mut externalities, || { + externalities.execute_with(|| { let payload = String::from("test payload").into_bytes(); let (sig, authority_id) = AuthorityDiscovery::sign(&payload).expect("signature"); diff --git a/srml/authorship/src/lib.rs b/srml/authorship/src/lib.rs index 0033e53221..dcd1985664 100644 --- a/srml/authorship/src/lib.rs +++ b/srml/authorship/src/lib.rs @@ -414,8 +414,7 @@ mod tests { use super::*; use primitives::H256; use sr_primitives::{ - set_and_run_with_externalities, traits::{BlakeTwo256, IdentityLookup}, testing::Header, - generic::DigestItem, Perbill, + traits::{BlakeTwo256, IdentityLookup}, testing::Header, generic::DigestItem, Perbill, }; use support::{parameter_types, impl_outer_origin, ConsensusEngineId}; @@ -542,7 +541,7 @@ mod tests { #[test] fn prune_old_uncles_works() { use UncleEntryItem::*; - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let hash = Default::default(); let author = Default::default(); let uncles = vec![ @@ -561,7 +560,7 @@ mod tests { #[test] fn rejects_bad_uncles() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let author_a = 69; struct CanonChain { @@ -674,7 +673,7 @@ mod tests { #[test] fn sets_author_lazily() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let author = 42; let mut header = seal_header( create_header(1, Default::default(), [1; 32].into()), diff --git a/srml/babe/src/tests.rs b/srml/babe/src/tests.rs index 0a165b3854..f860375de4 100644 --- a/srml/babe/src/tests.rs +++ b/srml/babe/src/tests.rs @@ -18,9 +18,7 @@ use super::*; use mock::{new_test_ext, Babe, Test}; -use sr_primitives::{ - set_and_run_with_externalities, traits::OnFinalize, testing::{Digest, DigestItem}, -}; +use sr_primitives::{traits::OnFinalize, testing::{Digest, DigestItem}}; use session::ShouldEndSession; const EMPTY_RANDOMNESS: [u8; 32] = [ @@ -54,14 +52,14 @@ fn empty_randomness_is_correct() { #[test] fn initial_values() { - set_and_run_with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { + new_test_ext(vec![0, 1, 2, 3]).execute_with(|| { assert_eq!(Babe::authorities().len(), 4) }) } #[test] fn check_module() { - set_and_run_with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { + new_test_ext(vec![0, 1, 2, 3]).execute_with(|| { assert!(!Babe::should_end_session(0), "Genesis does not change sessions"); assert!(!Babe::should_end_session(200000), "BABE does not include the block number in epoch calculations"); @@ -72,7 +70,7 @@ type System = system::Module; #[test] fn first_block_epoch_zero_start() { - set_and_run_with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { + new_test_ext(vec![0, 1, 2, 3]).execute_with(|| { let genesis_slot = 100; let first_vrf = [1; 32]; let pre_digest = make_pre_digest( @@ -120,7 +118,7 @@ fn first_block_epoch_zero_start() { #[test] fn authority_index() { - set_and_run_with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { + new_test_ext(vec![0, 1, 2, 3]).execute_with(|| { assert_eq!( Babe::find_author((&[(BABE_ENGINE_ID, &[][..])]).into_iter().cloned()), None, "Trivially invalid authorities are ignored") diff --git a/srml/balances/src/tests.rs b/srml/balances/src/tests.rs index b4745c2253..3e7cb9a133 100644 --- a/srml/balances/src/tests.rs +++ b/srml/balances/src/tests.rs @@ -20,7 +20,6 @@ use super::*; use mock::{Balances, ExtBuilder, Runtime, System, info_from_weight, CALL}; -use sr_primitives::set_and_run_with_externalities; use support::{ assert_noop, assert_ok, assert_err, traits::{LockableCurrency, LockIdentifier, WithdrawReason, WithdrawReasons, @@ -34,7 +33,7 @@ const ID_3: LockIdentifier = *b"3 "; #[test] fn basic_locking_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { assert_eq!(Balances::free_balance(&1), 10); Balances::set_lock(ID_1, &1, 9, u64::max_value(), WithdrawReasons::all()); assert_noop!( @@ -46,7 +45,7 @@ fn basic_locking_should_work() { #[test] fn partial_locking_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { Balances::set_lock(ID_1, &1, 5, u64::max_value(), WithdrawReasons::all()); assert_ok!(>::transfer(&1, &2, 1)); }); @@ -54,7 +53,7 @@ fn partial_locking_should_work() { #[test] fn lock_removal_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { Balances::set_lock(ID_1, &1, u64::max_value(), u64::max_value(), WithdrawReasons::all()); Balances::remove_lock(ID_1, &1); assert_ok!(>::transfer(&1, &2, 1)); @@ -63,7 +62,7 @@ fn lock_removal_should_work() { #[test] fn lock_replacement_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { Balances::set_lock(ID_1, &1, u64::max_value(), u64::max_value(), WithdrawReasons::all()); Balances::set_lock(ID_1, &1, 5, u64::max_value(), WithdrawReasons::all()); assert_ok!(>::transfer(&1, &2, 1)); @@ -72,7 +71,7 @@ fn lock_replacement_should_work() { #[test] fn double_locking_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { Balances::set_lock(ID_1, &1, 5, u64::max_value(), WithdrawReasons::all()); Balances::set_lock(ID_2, &1, 5, u64::max_value(), WithdrawReasons::all()); assert_ok!(>::transfer(&1, &2, 1)); @@ -81,7 +80,7 @@ fn double_locking_should_work() { #[test] fn combination_locking_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { Balances::set_lock(ID_1, &1, u64::max_value(), 0, WithdrawReasons::none()); Balances::set_lock(ID_2, &1, 0, u64::max_value(), WithdrawReasons::none()); Balances::set_lock(ID_3, &1, 0, 0, WithdrawReasons::all()); @@ -91,7 +90,7 @@ fn combination_locking_should_work() { #[test] fn lock_value_extension_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { Balances::set_lock(ID_1, &1, 5, u64::max_value(), WithdrawReasons::all()); assert_noop!( >::transfer(&1, &2, 6), @@ -112,12 +111,12 @@ fn lock_value_extension_should_work() { #[test] fn lock_reasons_should_work() { - set_and_run_with_externalities( - &mut ExtBuilder::default() - .existential_deposit(1) - .monied(true).transaction_fees(0, 1, 0) - .build(), - || { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .transaction_fees(0, 1, 0) + .build() + .execute_with(|| { Balances::set_lock(ID_1, &1, 10, u64::max_value(), WithdrawReason::Transfer.into()); assert_noop!( >::transfer(&1, &2, 1), @@ -157,13 +156,12 @@ fn lock_reasons_should_work() { info_from_weight(1), 0, ).is_err()); - } - ); + }); } #[test] fn lock_block_number_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { Balances::set_lock(ID_1, &1, 10, 2, WithdrawReasons::all()); assert_noop!( >::transfer(&1, &2, 1), @@ -177,7 +175,7 @@ fn lock_block_number_should_work() { #[test] fn lock_block_number_extension_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { Balances::set_lock(ID_1, &1, 10, 2, WithdrawReasons::all()); assert_noop!( >::transfer(&1, &2, 6), @@ -199,7 +197,7 @@ fn lock_block_number_extension_should_work() { #[test] fn lock_reasons_extension_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).build(), || { + ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { Balances::set_lock(ID_1, &1, 10, 10, WithdrawReason::Transfer.into()); assert_noop!( >::transfer(&1, &2, 6), @@ -220,14 +218,12 @@ fn lock_reasons_extension_should_work() { #[test] fn default_indexing_on_new_accounts_should_not_work2() { - set_and_run_with_externalities( - &mut ExtBuilder::default() - .existential_deposit(10) - .creation_fee(50) - .monied(true) - .build(), - || { - + ExtBuilder::default() + .existential_deposit(10) + .creation_fee(50) + .monied(true) + .build() + .execute_with(|| { assert_eq!(Balances::is_dead_account(&5), true); // account 5 should not exist // ext_deposit is 10, value is 9, not satisfies for ext_deposit assert_noop!( @@ -236,18 +232,16 @@ fn default_indexing_on_new_accounts_should_not_work2() { ); assert_eq!(Balances::is_dead_account(&5), true); // account 5 should not exist assert_eq!(Balances::free_balance(&1), 100); - }, - ); + }); } #[test] fn reserved_balance_should_prevent_reclaim_count() { - set_and_run_with_externalities( - &mut ExtBuilder::default() - .existential_deposit(256 * 1) - .monied(true) - .build(), - || { + ExtBuilder::default() + .existential_deposit(256 * 1) + .monied(true) + .build() + .execute_with(|| { System::inc_account_nonce(&2); assert_eq!(Balances::is_dead_account(&2), false); assert_eq!(Balances::is_dead_account(&5), true); @@ -274,14 +268,13 @@ fn reserved_balance_should_prevent_reclaim_count() { assert_ok!(Balances::transfer(Some(4).into(), 6, 256 * 1 + 0x69)); assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69); assert_eq!(Balances::is_dead_account(&6), false); - }, - ); + }); } #[test] fn reward_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().monied(true).build(), || { + ExtBuilder::default().monied(true).build().execute_with(|| { assert_eq!(Balances::total_balance(&1), 10); assert_ok!(Balances::deposit_into_existing(&1, 10).map(drop)); assert_eq!(Balances::total_balance(&1), 20); @@ -291,12 +284,11 @@ fn reward_should_work() { #[test] fn dust_account_removal_should_work() { - set_and_run_with_externalities( - &mut ExtBuilder::default() - .existential_deposit(100) - .monied(true) - .build(), - || { + ExtBuilder::default() + .existential_deposit(100) + .monied(true) + .build() + .execute_with(|| { System::inc_account_nonce(&2); assert_eq!(System::account_nonce(&2), 1); assert_eq!(Balances::total_balance(&2), 2000); @@ -305,19 +297,17 @@ fn dust_account_removal_should_work() { assert_eq!(Balances::total_balance(&2), 0); assert_eq!(Balances::total_balance(&5), 1901); assert_eq!(System::account_nonce(&2), 0); - }, - ); + }); } #[test] fn dust_account_removal_should_work2() { - set_and_run_with_externalities( - &mut ExtBuilder::default() - .existential_deposit(100) - .creation_fee(50) - .monied(true) - .build(), - || { + ExtBuilder::default() + .existential_deposit(100) + .creation_fee(50) + .monied(true) + .build() + .execute_with(|| { System::inc_account_nonce(&2); assert_eq!(System::account_nonce(&2), 1); assert_eq!(Balances::total_balance(&2), 2000); @@ -326,13 +316,12 @@ fn dust_account_removal_should_work2() { assert_eq!(Balances::total_balance(&2), 0); assert_eq!(Balances::total_balance(&5), 1851); assert_eq!(System::account_nonce(&2), 0); - }, - ); + }); } #[test] fn balance_works() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 42); assert_eq!(Balances::free_balance(&1), 42); assert_eq!(Balances::reserved_balance(&1), 0); @@ -345,7 +334,7 @@ fn balance_works() { #[test] fn balance_transfer_works() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::transfer(Some(1).into(), 2, 69)); assert_eq!(Balances::total_balance(&1), 42); @@ -355,7 +344,7 @@ fn balance_transfer_works() { #[test] fn force_transfer_works() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); assert_noop!( Balances::force_transfer(Some(2).into(), 1, 2, 69), @@ -369,7 +358,7 @@ fn force_transfer_works() { #[test] fn reserving_balance_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); assert_eq!(Balances::total_balance(&1), 111); @@ -386,7 +375,7 @@ fn reserving_balance_should_work() { #[test] fn balance_transfer_when_reserved_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 69)); assert_noop!( @@ -398,7 +387,7 @@ fn balance_transfer_when_reserved_should_not_work() { #[test] fn deducting_balance_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 69)); assert_eq!(Balances::free_balance(&1), 42); @@ -407,7 +396,7 @@ fn deducting_balance_should_work() { #[test] fn refunding_balance_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 42); Balances::set_reserved_balance(&1, 69); Balances::unreserve(&1, 69); @@ -418,7 +407,7 @@ fn refunding_balance_should_work() { #[test] fn slashing_balance_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 69)); assert!(Balances::slash(&1, 69).1.is_zero()); @@ -430,7 +419,7 @@ fn slashing_balance_should_work() { #[test] fn slashing_incomplete_balance_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 42); assert_ok!(Balances::reserve(&1, 21)); assert_eq!(Balances::slash(&1, 69).1, 27); @@ -442,7 +431,7 @@ fn slashing_incomplete_balance_should_work() { #[test] fn unreserving_balance_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 111)); Balances::unreserve(&1, 42); @@ -453,7 +442,7 @@ fn unreserving_balance_should_work() { #[test] fn slashing_reserved_balance_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 111)); assert_eq!(Balances::slash_reserved(&1, 42).1, 0); @@ -465,7 +454,7 @@ fn slashing_reserved_balance_should_work() { #[test] fn slashing_incomplete_reserved_balance_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 42)); assert_eq!(Balances::slash_reserved(&1, 69).1, 27); @@ -477,7 +466,7 @@ fn slashing_incomplete_reserved_balance_should_work() { #[test] fn transferring_reserved_balance_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 110); let _ = Balances::deposit_creating(&2, 1); assert_ok!(Balances::reserve(&1, 110)); @@ -491,7 +480,7 @@ fn transferring_reserved_balance_should_work() { #[test] fn transferring_reserved_balance_to_nonexistent_should_fail() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 111)); assert_noop!(Balances::repatriate_reserved(&1, &2, 42), "beneficiary account must pre-exist"); @@ -500,7 +489,7 @@ fn transferring_reserved_balance_to_nonexistent_should_fail() { #[test] fn transferring_incomplete_reserved_balance_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 110); let _ = Balances::deposit_creating(&2, 1); assert_ok!(Balances::reserve(&1, 41)); @@ -514,7 +503,7 @@ fn transferring_incomplete_reserved_balance_should_work() { #[test] fn transferring_too_high_value_should_not_panic() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { >::insert(1, u64::max_value()); >::insert(2, 1); @@ -530,89 +519,76 @@ fn transferring_too_high_value_should_not_panic() { #[test] fn account_create_on_free_too_low_with_other() { - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(100).build(), - || { - let _ = Balances::deposit_creating(&1, 100); - assert_eq!(>::get(), 100); + ExtBuilder::default().existential_deposit(100).build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 100); + assert_eq!(>::get(), 100); - // No-op. - let _ = Balances::deposit_creating(&2, 50); - assert_eq!(Balances::free_balance(&2), 0); - assert_eq!(>::get(), 100); - } - ) + // No-op. + let _ = Balances::deposit_creating(&2, 50); + assert_eq!(Balances::free_balance(&2), 0); + assert_eq!(>::get(), 100); + }) } #[test] fn account_create_on_free_too_low() { - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(100).build(), - || { - // No-op. - let _ = Balances::deposit_creating(&2, 50); - assert_eq!(Balances::free_balance(&2), 0); - assert_eq!(>::get(), 0); - } - ) + ExtBuilder::default().existential_deposit(100).build().execute_with(|| { + // No-op. + let _ = Balances::deposit_creating(&2, 50); + assert_eq!(Balances::free_balance(&2), 0); + assert_eq!(>::get(), 0); + }) } #[test] fn account_removal_on_free_too_low() { - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(100).build(), - || { - assert_eq!(>::get(), 0); + ExtBuilder::default().existential_deposit(100).build().execute_with(|| { + assert_eq!(>::get(), 0); - // Setup two accounts with free balance above the existential threshold. - let _ = Balances::deposit_creating(&1, 110); - let _ = Balances::deposit_creating(&2, 110); + // Setup two accounts with free balance above the existential threshold. + let _ = Balances::deposit_creating(&1, 110); + let _ = Balances::deposit_creating(&2, 110); - assert_eq!(Balances::free_balance(&1), 110); - assert_eq!(Balances::free_balance(&2), 110); - assert_eq!(>::get(), 220); + assert_eq!(Balances::free_balance(&1), 110); + assert_eq!(Balances::free_balance(&2), 110); + assert_eq!(>::get(), 220); - // Transfer funds from account 1 of such amount that after this transfer - // the balance of account 1 will be below the existential threshold. - // This should lead to the removal of all balance of this account. - assert_ok!(Balances::transfer(Some(1).into(), 2, 20)); + // Transfer funds from account 1 of such amount that after this transfer + // the balance of account 1 will be below the existential threshold. + // This should lead to the removal of all balance of this account. + assert_ok!(Balances::transfer(Some(1).into(), 2, 20)); - // Verify free balance removal of account 1. - assert_eq!(Balances::free_balance(&1), 0); - assert_eq!(Balances::free_balance(&2), 130); + // Verify free balance removal of account 1. + assert_eq!(Balances::free_balance(&1), 0); + assert_eq!(Balances::free_balance(&2), 130); - // Verify that TotalIssuance tracks balance removal when free balance is too low. - assert_eq!(>::get(), 130); - }, - ); + // Verify that TotalIssuance tracks balance removal when free balance is too low. + assert_eq!(>::get(), 130); + }); } #[test] fn transfer_overflow_isnt_exploitable() { - set_and_run_with_externalities( - &mut ExtBuilder::default().creation_fee(50).build(), - || { - // Craft a value that will overflow if summed with `creation_fee`. - let evil_value = u64::max_value() - 49; - - assert_err!( - Balances::transfer(Some(1).into(), 5, evil_value), - "got overflow after adding a fee to value", - ); - } - ); + ExtBuilder::default().creation_fee(50).build().execute_with(|| { + // Craft a value that will overflow if summed with `creation_fee`. + let evil_value = u64::max_value() - 49; + + assert_err!( + Balances::transfer(Some(1).into(), 5, evil_value), + "got overflow after adding a fee to value", + ); + }); } #[test] fn check_vesting_status() { - set_and_run_with_externalities( - &mut ExtBuilder::default() - .existential_deposit(256) - .monied(true) - .vesting(true) - .build(), - || { + ExtBuilder::default() + .existential_deposit(256) + .monied(true) + .vesting(true) + .build() + .execute_with(|| { assert_eq!(System::block_number(), 1); let user1_free_balance = Balances::free_balance(&1); let user2_free_balance = Balances::free_balance(&2); @@ -663,19 +639,17 @@ fn check_vesting_status() { assert_eq!(Balances::vesting_balance(&2), 0); // Account 2 has fully vested by block 30 assert_eq!(Balances::vesting_balance(&12), 0); // Account 2 has fully vested by block 30 - } - ); + }); } #[test] fn unvested_balance_should_not_transfer() { - set_and_run_with_externalities( - &mut ExtBuilder::default() - .existential_deposit(10) - .monied(true) - .vesting(true) - .build(), - || { + ExtBuilder::default() + .existential_deposit(10) + .monied(true) + .vesting(true) + .build() + .execute_with(|| { assert_eq!(System::block_number(), 1); let user1_free_balance = Balances::free_balance(&1); assert_eq!(user1_free_balance, 100); // Account 1 has free balance @@ -685,38 +659,34 @@ fn unvested_balance_should_not_transfer() { Balances::transfer(Some(1).into(), 2, 56), "vesting balance too high to send value", ); // Account 1 cannot send more than vested amount - } - ); + }); } #[test] fn vested_balance_should_transfer() { - set_and_run_with_externalities( - &mut ExtBuilder::default() - .existential_deposit(10) - .monied(true) - .vesting(true) - .build(), - || { + ExtBuilder::default() + .existential_deposit(10) + .monied(true) + .vesting(true) + .build() + .execute_with(|| { assert_eq!(System::block_number(), 1); let user1_free_balance = Balances::free_balance(&1); assert_eq!(user1_free_balance, 100); // Account 1 has free balance // Account 1 has only 5 units vested at block 1 (plus 50 unvested) assert_eq!(Balances::vesting_balance(&1), 45); assert_ok!(Balances::transfer(Some(1).into(), 2, 55)); - } - ); + }); } #[test] fn extra_balance_should_transfer() { - set_and_run_with_externalities( - &mut ExtBuilder::default() - .existential_deposit(10) - .monied(true) - .vesting(true) - .build(), - || { + ExtBuilder::default() + .existential_deposit(10) + .monied(true) + .vesting(true) + .build() + .execute_with(|| { assert_eq!(System::block_number(), 1); assert_ok!(Balances::transfer(Some(3).into(), 1, 100)); assert_ok!(Balances::transfer(Some(3).into(), 2, 100)); @@ -734,19 +704,17 @@ fn extra_balance_should_transfer() { // Account 2 has no units vested at block 1, but gained 100 assert_eq!(Balances::vesting_balance(&2), 200); assert_ok!(Balances::transfer(Some(2).into(), 3, 100)); // Account 2 can send extra units gained - } - ); + }); } #[test] fn liquid_funds_should_transfer_with_delayed_vesting() { - set_and_run_with_externalities( - &mut ExtBuilder::default() - .existential_deposit(256) - .monied(true) - .vesting(true) - .build(), - || { + ExtBuilder::default() + .existential_deposit(256) + .monied(true) + .vesting(true) + .build() + .execute_with(|| { assert_eq!(System::block_number(), 1); let user12_free_balance = Balances::free_balance(&12); @@ -764,62 +732,64 @@ fn liquid_funds_should_transfer_with_delayed_vesting() { // Account 12 can still send liquid funds assert_ok!(Balances::transfer(Some(12).into(), 3, 256 * 5)); - } - ); + }); } #[test] fn signed_extension_take_fees_work() { - set_and_run_with_externalities( - &mut ExtBuilder::default() - .existential_deposit(10) - .transaction_fees(10, 1, 5) - .monied(true) - .build(), - || { + ExtBuilder::default() + .existential_deposit(10) + .transaction_fees(10, 1, 5) + .monied(true) + .build() + .execute_with(|| { let len = 10; - assert!(TakeFees::::from(0).pre_dispatch(&1, CALL, info_from_weight(5), len).is_ok()); + assert!( + TakeFees::::from(0) + .pre_dispatch(&1, CALL, info_from_weight(5), len) + .is_ok() + ); assert_eq!(Balances::free_balance(&1), 100 - 20 - 25); - assert!(TakeFees::::from(5 /* tipped */).pre_dispatch(&1, CALL, info_from_weight(3), len).is_ok()); + assert!( + TakeFees::::from(5 /* tipped */) + .pre_dispatch(&1, CALL, info_from_weight(3), len) + .is_ok() + ); assert_eq!(Balances::free_balance(&1), 100 - 20 - 25 - 20 - 5 - 15); - } - ); + }); } #[test] fn signed_extension_take_fees_is_bounded() { - set_and_run_with_externalities( - &mut ExtBuilder::default() - .existential_deposit(1000) - .transaction_fees(0, 0, 1) - .monied(true) - .build(), - || { + ExtBuilder::default() + .existential_deposit(1000) + .transaction_fees(0, 0, 1) + .monied(true) + .build() + .execute_with(|| { use sr_primitives::weights::Weight; // maximum weight possible - assert!(TakeFees::::from(0).pre_dispatch(&1, CALL, info_from_weight(Weight::max_value()), 10).is_ok()); + assert!( + TakeFees::::from(0) + .pre_dispatch(&1, CALL, info_from_weight(Weight::max_value()), 10) + .is_ok() + ); // fee will be proportional to what is the actual maximum weight in the runtime. assert_eq!( Balances::free_balance(&1), (10000 - ::MaximumBlockWeight::get()) as u64 ); - } - ); + }); } #[test] fn burn_must_work() { - set_and_run_with_externalities( - &mut ExtBuilder::default() - .monied(true) - .build(), - || { - let init_total_issuance = Balances::total_issuance(); - let imbalance = Balances::burn(10); - assert_eq!(Balances::total_issuance(), init_total_issuance - 10); - drop(imbalance); - assert_eq!(Balances::total_issuance(), init_total_issuance); - } - ); + ExtBuilder::default().monied(true).build().execute_with(|| { + let init_total_issuance = Balances::total_issuance(); + let imbalance = Balances::burn(10); + assert_eq!(Balances::total_issuance(), init_total_issuance - 10); + drop(imbalance); + assert_eq!(Balances::total_issuance(), init_total_issuance); + }); } diff --git a/srml/collective/src/lib.rs b/srml/collective/src/lib.rs index 7ae352266a..2de6243dd6 100644 --- a/srml/collective/src/lib.rs +++ b/srml/collective/src/lib.rs @@ -384,8 +384,8 @@ mod tests { use hex_literal::hex; use primitives::H256; use sr_primitives::{ - set_and_run_with_externalities, Perbill, - traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, testing::Header, BuildStorage, + Perbill, traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, testing::Header, + BuildStorage, }; use crate as collective; @@ -451,7 +451,7 @@ mod tests { #[test] fn motions_basic_environment_works() { - set_and_run_with_externalities(&mut make_ext(), || { + make_ext().execute_with(|| { System::set_block_number(1); assert_eq!(Collective::members(), vec![1, 2, 3]); assert_eq!(Collective::proposals(), Vec::::new()); @@ -464,7 +464,7 @@ mod tests { #[test] fn removal_of_old_voters_votes_works() { - set_and_run_with_externalities(&mut make_ext(), || { + make_ext().execute_with(|| { System::set_block_number(1); let proposal = make_proposal(42); let hash = BlakeTwo256::hash_of(&proposal); @@ -498,7 +498,7 @@ mod tests { #[test] fn removal_of_old_voters_votes_works_with_set_members() { - set_and_run_with_externalities(&mut make_ext(), || { + make_ext().execute_with(|| { System::set_block_number(1); let proposal = make_proposal(42); let hash = BlakeTwo256::hash_of(&proposal); @@ -532,7 +532,7 @@ mod tests { #[test] fn propose_works() { - set_and_run_with_externalities(&mut make_ext(), || { + make_ext().execute_with(|| { System::set_block_number(1); let proposal = make_proposal(42); let hash = proposal.blake2_256().into(); @@ -561,7 +561,7 @@ mod tests { #[test] fn motions_ignoring_non_collective_proposals_works() { - set_and_run_with_externalities(&mut make_ext(), || { + make_ext().execute_with(|| { System::set_block_number(1); let proposal = make_proposal(42); assert_noop!( @@ -573,29 +573,35 @@ mod tests { #[test] fn motions_ignoring_non_collective_votes_works() { - set_and_run_with_externalities(&mut make_ext(), || { + make_ext().execute_with(|| { System::set_block_number(1); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); - assert_noop!(Collective::vote(Origin::signed(42), hash.clone(), 0, true), "voter not a member"); + assert_noop!( + Collective::vote(Origin::signed(42), hash.clone(), 0, true), + "voter not a member", + ); }); } #[test] fn motions_ignoring_bad_index_collective_vote_works() { - set_and_run_with_externalities(&mut make_ext(), || { + make_ext().execute_with(|| { System::set_block_number(3); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); - assert_noop!(Collective::vote(Origin::signed(2), hash.clone(), 1, true), "mismatched index"); + assert_noop!( + Collective::vote(Origin::signed(2), hash.clone(), 1, true), + "mismatched index", + ); }); } #[test] fn motions_revoting_works() { - set_and_run_with_externalities(&mut make_ext(), || { + make_ext().execute_with(|| { System::set_block_number(1); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); @@ -604,13 +610,19 @@ mod tests { Collective::voting(&hash), Some(Votes { index: 0, threshold: 2, ayes: vec![1], nays: vec![] }) ); - assert_noop!(Collective::vote(Origin::signed(1), hash.clone(), 0, true), "duplicate vote ignored"); + assert_noop!( + Collective::vote(Origin::signed(1), hash.clone(), 0, true), + "duplicate vote ignored", + ); assert_ok!(Collective::vote(Origin::signed(1), hash.clone(), 0, false)); assert_eq!( Collective::voting(&hash), Some(Votes { index: 0, threshold: 2, ayes: vec![], nays: vec![1] }) ); - assert_noop!(Collective::vote(Origin::signed(1), hash.clone(), 0, false), "duplicate vote ignored"); + assert_noop!( + Collective::vote(Origin::signed(1), hash.clone(), 0, false), + "duplicate vote ignored", + ); assert_eq!(System::events(), vec![ EventRecord { @@ -640,7 +652,7 @@ mod tests { #[test] fn motions_disapproval_works() { - set_and_run_with_externalities(&mut make_ext(), || { + make_ext().execute_with(|| { System::set_block_number(1); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); @@ -683,7 +695,7 @@ mod tests { #[test] fn motions_approval_works() { - set_and_run_with_externalities(&mut make_ext(), || { + make_ext().execute_with(|| { System::set_block_number(1); let proposal = make_proposal(42); let hash: H256 = proposal.blake2_256().into(); diff --git a/srml/contracts/src/exec.rs b/srml/contracts/src/exec.rs index a2dd3c1f3d..f85797378f 100644 --- a/srml/contracts/src/exec.rs +++ b/srml/contracts/src/exec.rs @@ -807,7 +807,6 @@ mod tests { account_db::AccountDb, gas::GasMeter, tests::{ExtBuilder, Test}, exec::{ExecReturnValue, ExecError, STATUS_SUCCESS}, CodeHash, Config, }; - use sr_primitives::set_and_run_with_externalities; use std::{cell::RefCell, rc::Rc, collections::HashMap, marker::PhantomData}; use assert_matches::assert_matches; @@ -933,7 +932,7 @@ mod tests { exec_success() }); - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); ctx.overlay.instantiate_contract(&BOB, exec_ch).unwrap(); @@ -953,7 +952,7 @@ mod tests { let dest = BOB; // This test verifies that base fee for call is taken. - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let vm = MockVm::new(); let loader = MockLoader::empty(); let cfg = Config::preload(); @@ -971,7 +970,7 @@ mod tests { }); // This test verifies that base fee for instantiation is taken. - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let mut loader = MockLoader::empty(); let code = loader.insert(|_| exec_success()); @@ -1001,7 +1000,7 @@ mod tests { let vm = MockVm::new(); let loader = MockLoader::empty(); - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); ctx.overlay.set_balance(&origin, 100); @@ -1033,7 +1032,7 @@ mod tests { |_| Ok(ExecReturnValue { status: 1, data: Vec::new() }) ); - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap(); @@ -1061,93 +1060,84 @@ mod tests { // This test sends 50 units of currency to a non-existent account. // This should lead to creation of a new account thus // a fee should be charged. - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(15).build(), - || { - let vm = MockVm::new(); - let loader = MockLoader::empty(); - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.set_balance(&origin, 100); - ctx.overlay.set_balance(&dest, 0); - - let mut gas_meter = GasMeter::::with_limit(1000, 1); - - let result = ctx.call(dest, 50, &mut gas_meter, vec![]); - assert_matches!(result, Ok(_)); - - let mut toks = gas_meter.tokens().iter(); - match_tokens!( - toks, - ExecFeeToken::Call, - TransferFeeToken { - kind: TransferFeeKind::AccountCreate, - gas_price: 1u64 - }, - ); - }, - ); + ExtBuilder::default().existential_deposit(15).build().execute_with(|| { + let vm = MockVm::new(); + let loader = MockLoader::empty(); + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); + ctx.overlay.set_balance(&origin, 100); + ctx.overlay.set_balance(&dest, 0); + + let mut gas_meter = GasMeter::::with_limit(1000, 1); + + let result = ctx.call(dest, 50, &mut gas_meter, vec![]); + assert_matches!(result, Ok(_)); + + let mut toks = gas_meter.tokens().iter(); + match_tokens!( + toks, + ExecFeeToken::Call, + TransferFeeToken { + kind: TransferFeeKind::AccountCreate, + gas_price: 1u64 + }, + ); + }); // This one is similar to the previous one but transfer to an existing account. // In this test we expect that a regular transfer fee is charged. - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(15).build(), - || { - let vm = MockVm::new(); - let loader = MockLoader::empty(); - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.set_balance(&origin, 100); - ctx.overlay.set_balance(&dest, 15); - - let mut gas_meter = GasMeter::::with_limit(1000, 1); - - let result = ctx.call(dest, 50, &mut gas_meter, vec![]); - assert_matches!(result, Ok(_)); - - let mut toks = gas_meter.tokens().iter(); - match_tokens!( - toks, - ExecFeeToken::Call, - TransferFeeToken { - kind: TransferFeeKind::Transfer, - gas_price: 1u64 - }, - ); - }, - ); + ExtBuilder::default().existential_deposit(15).build().execute_with(|| { + let vm = MockVm::new(); + let loader = MockLoader::empty(); + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); + ctx.overlay.set_balance(&origin, 100); + ctx.overlay.set_balance(&dest, 15); + + let mut gas_meter = GasMeter::::with_limit(1000, 1); + + let result = ctx.call(dest, 50, &mut gas_meter, vec![]); + assert_matches!(result, Ok(_)); + + let mut toks = gas_meter.tokens().iter(); + match_tokens!( + toks, + ExecFeeToken::Call, + TransferFeeToken { + kind: TransferFeeKind::Transfer, + gas_price: 1u64 + }, + ); + }); // This test sends 50 units of currency as an endownment to a newly // instantiated contract. - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(15).build(), - || { - let mut loader = MockLoader::empty(); - let code = loader.insert(|_| exec_success()); - - let vm = MockVm::new(); - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - - ctx.overlay.set_balance(&origin, 100); - ctx.overlay.set_balance(&dest, 15); - - let mut gas_meter = GasMeter::::with_limit(1000, 1); - - let result = ctx.instantiate(50, &mut gas_meter, &code, vec![]); - assert_matches!(result, Ok(_)); - - let mut toks = gas_meter.tokens().iter(); - match_tokens!( - toks, - ExecFeeToken::Instantiate, - TransferFeeToken { - kind: TransferFeeKind::ContractInstantiate, - gas_price: 1u64 - }, - ); - }, - ); + ExtBuilder::default().existential_deposit(15).build().execute_with(|| { + let mut loader = MockLoader::empty(); + let code = loader.insert(|_| exec_success()); + + let vm = MockVm::new(); + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); + + ctx.overlay.set_balance(&origin, 100); + ctx.overlay.set_balance(&dest, 15); + + let mut gas_meter = GasMeter::::with_limit(1000, 1); + + let result = ctx.instantiate(50, &mut gas_meter, &code, vec![]); + assert_matches!(result, Ok(_)); + + let mut toks = gas_meter.tokens().iter(); + match_tokens!( + toks, + ExecFeeToken::Instantiate, + TransferFeeToken { + kind: TransferFeeKind::ContractInstantiate, + gas_price: 1u64 + }, + ); + }); } #[test] @@ -1160,7 +1150,7 @@ mod tests { let vm = MockVm::new(); let loader = MockLoader::empty(); - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); ctx.overlay.set_balance(&origin, 0); @@ -1194,7 +1184,7 @@ mod tests { |_| Ok(ExecReturnValue { status: STATUS_SUCCESS, data: vec![1, 2, 3, 4] }) ); - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap(); @@ -1225,7 +1215,7 @@ mod tests { |_| Ok(ExecReturnValue { status: 1, data: vec![1, 2, 3, 4] }) ); - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap(); @@ -1253,7 +1243,7 @@ mod tests { }); // This one tests passing the input data into a contract via call. - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); ctx.overlay.instantiate_contract(&BOB, input_data_ch).unwrap(); @@ -1278,7 +1268,7 @@ mod tests { }); // This one tests passing the input data into a contract via instantiate. - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); @@ -1322,7 +1312,7 @@ mod tests { exec_success() }); - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); ctx.overlay.instantiate_contract(&BOB, recurse_ch).unwrap(); @@ -1366,7 +1356,7 @@ mod tests { exec_success() }); - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); @@ -1408,7 +1398,7 @@ mod tests { exec_success() }); - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); ctx.overlay.instantiate_contract(&BOB, bob_ch).unwrap(); @@ -1432,23 +1422,20 @@ mod tests { let mut loader = MockLoader::empty(); let dummy_ch = loader.insert(|_| exec_success()); - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(15).build(), - || { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + ExtBuilder::default().existential_deposit(15).build().execute_with(|| { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - assert_matches!( - ctx.instantiate( - 0, // <- zero endowment - &mut GasMeter::::with_limit(10000, 1), - &dummy_ch, - vec![], - ), - Err(_) - ); - } - ); + assert_matches!( + ctx.instantiate( + 0, // <- zero endowment + &mut GasMeter::::with_limit(10000, 1), + &dummy_ch, + vec![], + ), + Err(_) + ); + }); } #[test] @@ -1460,38 +1447,35 @@ mod tests { |_| Ok(ExecReturnValue { status: STATUS_SUCCESS, data: vec![80, 65, 83, 83] }) ); - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(15).build(), - || { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.set_balance(&ALICE, 1000); - - let instantiated_contract_address = assert_matches!( - ctx.instantiate( - 100, - &mut GasMeter::::with_limit(10000, 1), - &dummy_ch, - vec![], - ), - Ok((address, ref output)) if output.data == vec![80, 65, 83, 83] => address - ); + ExtBuilder::default().existential_deposit(15).build().execute_with(|| { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + ctx.overlay.set_balance(&ALICE, 1000); - // Check that the newly created account has the expected code hash and - // there are instantiation event. - assert_eq!(ctx.overlay.get_code_hash(&instantiated_contract_address).unwrap(), dummy_ch); - assert_eq!(&ctx.events(), &[ - DeferredAction::DepositEvent { - event: RawEvent::Transfer(ALICE, instantiated_contract_address, 100), - topics: Vec::new(), - }, - DeferredAction::DepositEvent { - event: RawEvent::Instantiated(ALICE, instantiated_contract_address), - topics: Vec::new(), - } - ]); - } - ); + let instantiated_contract_address = assert_matches!( + ctx.instantiate( + 100, + &mut GasMeter::::with_limit(10000, 1), + &dummy_ch, + vec![], + ), + Ok((address, ref output)) if output.data == vec![80, 65, 83, 83] => address + ); + + // Check that the newly created account has the expected code hash and + // there are instantiation event. + assert_eq!(ctx.overlay.get_code_hash(&instantiated_contract_address).unwrap(), dummy_ch); + assert_eq!(&ctx.events(), &[ + DeferredAction::DepositEvent { + event: RawEvent::Transfer(ALICE, instantiated_contract_address, 100), + topics: Vec::new(), + }, + DeferredAction::DepositEvent { + event: RawEvent::Instantiated(ALICE, instantiated_contract_address), + topics: Vec::new(), + } + ]); + }); } #[test] @@ -1503,28 +1487,25 @@ mod tests { |_| Ok(ExecReturnValue { status: 1, data: vec![70, 65, 73, 76] }) ); - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(15).build(), - || { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.set_balance(&ALICE, 1000); - - let instantiated_contract_address = assert_matches!( - ctx.instantiate( - 100, - &mut GasMeter::::with_limit(10000, 1), - &dummy_ch, - vec![], - ), - Ok((address, ref output)) if output.data == vec![70, 65, 73, 76] => address - ); + ExtBuilder::default().existential_deposit(15).build().execute_with(|| { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + ctx.overlay.set_balance(&ALICE, 1000); - // Check that the account has not been created. - assert!(ctx.overlay.get_code_hash(&instantiated_contract_address).is_none()); - assert!(ctx.events().is_empty()); - } - ); + let instantiated_contract_address = assert_matches!( + ctx.instantiate( + 100, + &mut GasMeter::::with_limit(10000, 1), + &dummy_ch, + vec![], + ), + Ok((address, ref output)) if output.data == vec![70, 65, 73, 76] => address + ); + + // Check that the account has not been created. + assert!(ctx.overlay.get_code_hash(&instantiated_contract_address).is_none()); + assert!(ctx.events().is_empty()); + }); } #[test] @@ -1551,40 +1532,37 @@ mod tests { } }); - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(15).build(), - || { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.set_balance(&ALICE, 1000); - ctx.overlay.instantiate_contract(&BOB, instantiator_ch).unwrap(); + ExtBuilder::default().existential_deposit(15).build().execute_with(|| { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + ctx.overlay.set_balance(&ALICE, 1000); + ctx.overlay.instantiate_contract(&BOB, instantiator_ch).unwrap(); - assert_matches!( - ctx.call(BOB, 20, &mut GasMeter::::with_limit(1000, 1), vec![]), - Ok(_) - ); + assert_matches!( + ctx.call(BOB, 20, &mut GasMeter::::with_limit(1000, 1), vec![]), + Ok(_) + ); - let instantiated_contract_address = instantiated_contract_address.borrow().as_ref().unwrap().clone(); - - // Check that the newly created account has the expected code hash and - // there are instantiation event. - assert_eq!(ctx.overlay.get_code_hash(&instantiated_contract_address).unwrap(), dummy_ch); - assert_eq!(&ctx.events(), &[ - DeferredAction::DepositEvent { - event: RawEvent::Transfer(ALICE, BOB, 20), - topics: Vec::new(), - }, - DeferredAction::DepositEvent { - event: RawEvent::Transfer(BOB, instantiated_contract_address, 15), - topics: Vec::new(), - }, - DeferredAction::DepositEvent { - event: RawEvent::Instantiated(BOB, instantiated_contract_address), - topics: Vec::new(), - }, - ]); - } - ); + let instantiated_contract_address = instantiated_contract_address.borrow().as_ref().unwrap().clone(); + + // Check that the newly created account has the expected code hash and + // there are instantiation event. + assert_eq!(ctx.overlay.get_code_hash(&instantiated_contract_address).unwrap(), dummy_ch); + assert_eq!(&ctx.events(), &[ + DeferredAction::DepositEvent { + event: RawEvent::Transfer(ALICE, BOB, 20), + topics: Vec::new(), + }, + DeferredAction::DepositEvent { + event: RawEvent::Transfer(BOB, instantiated_contract_address, 15), + topics: Vec::new(), + }, + DeferredAction::DepositEvent { + event: RawEvent::Instantiated(BOB, instantiated_contract_address), + topics: Vec::new(), + }, + ]); + }); } #[test] @@ -1613,29 +1591,26 @@ mod tests { } }); - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(15).build(), - || { - let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.set_balance(&ALICE, 1000); - ctx.overlay.instantiate_contract(&BOB, instantiator_ch).unwrap(); + ExtBuilder::default().existential_deposit(15).build().execute_with(|| { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + ctx.overlay.set_balance(&ALICE, 1000); + ctx.overlay.instantiate_contract(&BOB, instantiator_ch).unwrap(); - assert_matches!( - ctx.call(BOB, 20, &mut GasMeter::::with_limit(1000, 1), vec![]), - Ok(_) - ); + assert_matches!( + ctx.call(BOB, 20, &mut GasMeter::::with_limit(1000, 1), vec![]), + Ok(_) + ); - // The contract wasn't instantiated so we don't expect to see an instantiation - // event here. - assert_eq!(&ctx.events(), &[ - DeferredAction::DepositEvent { - event: RawEvent::Transfer(ALICE, BOB, 20), - topics: Vec::new(), - }, - ]); - } - ); + // The contract wasn't instantiated so we don't expect to see an instantiation + // event here. + assert_eq!(&ctx.events(), &[ + DeferredAction::DepositEvent { + event: RawEvent::Transfer(ALICE, BOB, 20), + topics: Vec::new(), + }, + ]); + }); } #[test] @@ -1649,7 +1624,7 @@ mod tests { exec_success() }); - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); diff --git a/srml/contracts/src/tests.rs b/srml/contracts/src/tests.rs index 9d02419b17..d6de2ce3bd 100644 --- a/srml/contracts/src/tests.rs +++ b/srml/contracts/src/tests.rs @@ -30,7 +30,7 @@ use codec::{Decode, Encode, KeyedVec}; use sr_primitives::{ Perbill, BuildStorage, transaction_validity::{InvalidTransaction, ValidTransaction}, traits::{BlakeTwo256, Hash, IdentityLookup, SignedExtension}, - weights::{DispatchInfo, DispatchClass}, set_and_run_with_externalities, + weights::{DispatchInfo, DispatchClass}, testing::{Digest, DigestItem, Header, UintAuthorityId, H256}, }; use support::{ @@ -306,7 +306,7 @@ fn compile_module(wabt_module: &str) // Then we check that the all unused gas is refunded. #[test] fn refunds_unused_gas() { - set_and_run_with_externalities(&mut ExtBuilder::default().gas_price(2).build(), || { + ExtBuilder::default().gas_price(2).build().execute_with(|| { Balances::deposit_creating(&ALICE, 100_000_000); assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, Vec::new())); @@ -318,70 +318,67 @@ fn refunds_unused_gas() { #[test] fn account_removal_removes_storage() { - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(100).build(), - || { - let trie_id1 = ::TrieIdGenerator::trie_id(&1); - let trie_id2 = ::TrieIdGenerator::trie_id(&2); - let key1 = &[1; 32]; - let key2 = &[2; 32]; - - // Set up two accounts with free balance above the existential threshold. - { - Balances::deposit_creating(&1, 110); - ContractInfoOf::::insert(1, &ContractInfo::Alive(RawAliveContractInfo { - trie_id: trie_id1.clone(), - storage_size: ::StorageSizeOffset::get(), - deduct_block: System::block_number(), - code_hash: H256::repeat_byte(1), - rent_allowance: 40, - last_write: None, - })); - - let mut overlay = OverlayAccountDb::::new(&DirectAccountDb); - overlay.set_storage(&1, key1.clone(), Some(b"1".to_vec())); - overlay.set_storage(&1, key2.clone(), Some(b"2".to_vec())); - DirectAccountDb.commit(overlay.into_change_set()); - - Balances::deposit_creating(&2, 110); - ContractInfoOf::::insert(2, &ContractInfo::Alive(RawAliveContractInfo { - trie_id: trie_id2.clone(), - storage_size: ::StorageSizeOffset::get(), - deduct_block: System::block_number(), - code_hash: H256::repeat_byte(2), - rent_allowance: 40, - last_write: None, - })); - - let mut overlay = OverlayAccountDb::::new(&DirectAccountDb); - overlay.set_storage(&2, key1.clone(), Some(b"3".to_vec())); - overlay.set_storage(&2, key2.clone(), Some(b"4".to_vec())); - DirectAccountDb.commit(overlay.into_change_set()); - } + ExtBuilder::default().existential_deposit(100).build().execute_with(|| { + let trie_id1 = ::TrieIdGenerator::trie_id(&1); + let trie_id2 = ::TrieIdGenerator::trie_id(&2); + let key1 = &[1; 32]; + let key2 = &[2; 32]; + + // Set up two accounts with free balance above the existential threshold. + { + Balances::deposit_creating(&1, 110); + ContractInfoOf::::insert(1, &ContractInfo::Alive(RawAliveContractInfo { + trie_id: trie_id1.clone(), + storage_size: ::StorageSizeOffset::get(), + deduct_block: System::block_number(), + code_hash: H256::repeat_byte(1), + rent_allowance: 40, + last_write: None, + })); + + let mut overlay = OverlayAccountDb::::new(&DirectAccountDb); + overlay.set_storage(&1, key1.clone(), Some(b"1".to_vec())); + overlay.set_storage(&1, key2.clone(), Some(b"2".to_vec())); + DirectAccountDb.commit(overlay.into_change_set()); + + Balances::deposit_creating(&2, 110); + ContractInfoOf::::insert(2, &ContractInfo::Alive(RawAliveContractInfo { + trie_id: trie_id2.clone(), + storage_size: ::StorageSizeOffset::get(), + deduct_block: System::block_number(), + code_hash: H256::repeat_byte(2), + rent_allowance: 40, + last_write: None, + })); + + let mut overlay = OverlayAccountDb::::new(&DirectAccountDb); + overlay.set_storage(&2, key1.clone(), Some(b"3".to_vec())); + overlay.set_storage(&2, key2.clone(), Some(b"4".to_vec())); + DirectAccountDb.commit(overlay.into_change_set()); + } - // Transfer funds from account 1 of such amount that after this transfer - // the balance of account 1 will be below the existential threshold. - // - // This should lead to the removal of all storage associated with this account. - assert_ok!(Balances::transfer(Origin::signed(1), 2, 20)); - - // Verify that all entries from account 1 is removed, while - // entries from account 2 is in place. - { - assert!(>::get_storage(&DirectAccountDb, &1, Some(&trie_id1), key1).is_none()); - assert!(>::get_storage(&DirectAccountDb, &1, Some(&trie_id1), key2).is_none()); - - assert_eq!( - >::get_storage(&DirectAccountDb, &2, Some(&trie_id2), key1), - Some(b"3".to_vec()) - ); - assert_eq!( - >::get_storage(&DirectAccountDb, &2, Some(&trie_id2), key2), - Some(b"4".to_vec()) - ); - } - }, - ); + // Transfer funds from account 1 of such amount that after this transfer + // the balance of account 1 will be below the existential threshold. + // + // This should lead to the removal of all storage associated with this account. + assert_ok!(Balances::transfer(Origin::signed(1), 2, 20)); + + // Verify that all entries from account 1 is removed, while + // entries from account 2 is in place. + { + assert!(>::get_storage(&DirectAccountDb, &1, Some(&trie_id1), key1).is_none()); + assert!(>::get_storage(&DirectAccountDb, &1, Some(&trie_id1), key2).is_none()); + + assert_eq!( + >::get_storage(&DirectAccountDb, &2, Some(&trie_id2), key1), + Some(b"3".to_vec()) + ); + assert_eq!( + >::get_storage(&DirectAccountDb, &2, Some(&trie_id2), key2), + Some(b"4".to_vec()) + ); + } + }); } const CODE_RETURN_FROM_START_FN: &str = r#" @@ -418,61 +415,58 @@ const CODE_RETURN_FROM_START_FN: &str = r#" fn instantiate_and_call_and_deposit_event() { let (wasm, code_hash) = compile_module::(CODE_RETURN_FROM_START_FN).unwrap(); - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(100).build(), - || { - Balances::deposit_creating(&ALICE, 1_000_000); - - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - - // Check at the end to get hash on error easily - let creation = Contract::instantiate( - Origin::signed(ALICE), - 100, - 100_000, - code_hash.into(), - vec![], - ); + ExtBuilder::default().existential_deposit(100).build().execute_with(|| { + Balances::deposit_creating(&ALICE, 1_000_000); + + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + + // Check at the end to get hash on error easily + let creation = Contract::instantiate( + Origin::signed(ALICE), + 100, + 100_000, + code_hash.into(), + vec![], + ); + + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances( + balances::RawEvent::NewAccount(BOB, 100) + ), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Transfer(ALICE, BOB, 100)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Contract(BOB, vec![1, 2, 3, 4])), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Instantiated(ALICE, BOB)), + topics: vec![], + } + ]); - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances( - balances::RawEvent::NewAccount(BOB, 100) - ), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Transfer(ALICE, BOB, 100)), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Contract(BOB, vec![1, 2, 3, 4])), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Instantiated(ALICE, BOB)), - topics: vec![], - } - ]); - - assert_ok!(creation); - assert!(ContractInfoOf::::exists(BOB)); - }, - ); + assert_ok!(creation); + assert!(ContractInfoOf::::exists(BOB)); + }); } const CODE_DISPATCH_CALL: &str = r#" @@ -501,98 +495,95 @@ fn dispatch_call() { let (wasm, code_hash) = compile_module::(CODE_DISPATCH_CALL).unwrap(); - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(50).build(), - || { - Balances::deposit_creating(&ALICE, 1_000_000); - - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - - // Let's keep this assert even though it's redundant. If you ever need to update the - // wasm source this test will fail and will show you the actual hash. - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - ]); - - assert_ok!(Contract::instantiate( - Origin::signed(ALICE), - 100, - 100_000, - code_hash.into(), - vec![], - )); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::call( - Origin::signed(ALICE), - BOB, // newly created account - 0, - 100_000, - vec![], - )); - - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances( - balances::RawEvent::NewAccount(BOB, 100) - ), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Transfer(ALICE, BOB, 100)), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Instantiated(ALICE, BOB)), - topics: vec![], - }, - - // Dispatching the call. - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances( - balances::RawEvent::NewAccount(CHARLIE, 50) - ), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances( - balances::RawEvent::Transfer(BOB, CHARLIE, 50, 0) - ), - topics: vec![], - }, - - // Event emited as a result of dispatch. - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Dispatched(BOB, true)), - topics: vec![], - } - ]); - }, - ); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + + // Let's keep this assert even though it's redundant. If you ever need to update the + // wasm source this test will fail and will show you the actual hash. + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), + topics: vec![], + }, + ]); + + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 100, + 100_000, + code_hash.into(), + vec![], + )); + + assert_ok!(Contract::call( + Origin::signed(ALICE), + BOB, // newly created account + 0, + 100_000, + vec![], + )); + + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances( + balances::RawEvent::NewAccount(BOB, 100) + ), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Transfer(ALICE, BOB, 100)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Instantiated(ALICE, BOB)), + topics: vec![], + }, + + // Dispatching the call. + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances( + balances::RawEvent::NewAccount(CHARLIE, 50) + ), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances( + balances::RawEvent::Transfer(BOB, CHARLIE, 50, 0) + ), + topics: vec![], + }, + + // Event emited as a result of dispatch. + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Dispatched(BOB, true)), + topics: vec![], + } + ]); + }); } const CODE_DISPATCH_CALL_THEN_TRAP: &str = r#" @@ -622,80 +613,77 @@ fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { let (wasm, code_hash) = compile_module::(CODE_DISPATCH_CALL_THEN_TRAP).unwrap(); - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(50).build(), - || { - Balances::deposit_creating(&ALICE, 1_000_000); - - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - - // Let's keep this assert even though it's redundant. If you ever need to update the - // wasm source this test will fail and will show you the actual hash. - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - ]); - - assert_ok!(Contract::instantiate( + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + Balances::deposit_creating(&ALICE, 1_000_000); + + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + + // Let's keep this assert even though it's redundant. If you ever need to update the + // wasm source this test will fail and will show you the actual hash. + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), + topics: vec![], + }, + ]); + + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 100, + 100_000, + code_hash.into(), + vec![], + )); + + // Call the newly instantiated contract. The contract is expected to dispatch a call + // and then trap. + assert_err!( + Contract::call( Origin::signed(ALICE), - 100, + BOB, // newly created account + 0, 100_000, - code_hash.into(), vec![], - )); - - // Call the newly instantiated contract. The contract is expected to dispatch a call - // and then trap. - assert_err!( - Contract::call( - Origin::signed(ALICE), - BOB, // newly created account - 0, - 100_000, - vec![], + ), + "during execution" + ); + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances( + balances::RawEvent::NewAccount(BOB, 100) ), - "during execution" - ); - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances( - balances::RawEvent::NewAccount(BOB, 100) - ), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Transfer(ALICE, BOB, 100)), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Instantiated(ALICE, BOB)), - topics: vec![], - }, - // ABSENCE of events which would be caused by dispatched Balances::transfer call - ]); - }, - ); + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Transfer(ALICE, BOB, 100)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Instantiated(ALICE, BOB)), + topics: vec![], + }, + // ABSENCE of events which would be caused by dispatched Balances::transfer call + ]); + }); } const CODE_SET_RENT: &str = r#" @@ -825,28 +813,25 @@ fn test_set_rent_code_and_hash() { let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(50).build(), - || { - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - - // If you ever need to update the wasm source this test will fail - // and will show you the actual hash. - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - ]); - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + + // If you ever need to update the wasm source this test will fail + // and will show you the actual hash. + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), + topics: vec![], + }, + ]); + }); } #[test] @@ -854,92 +839,86 @@ fn storage_size() { let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); // Storage size - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(50).build(), - || { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::instantiate( - Origin::signed(ALICE), - 30_000, - 100_000, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.storage_size, ::StorageSizeOffset::get() + 4); - - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::set_storage_4_byte())); - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.storage_size, ::StorageSizeOffset::get() + 4 + 4); - - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::remove_storage_4_byte())); - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.storage_size, ::StorageSizeOffset::get() + 4); - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 30_000, + 100_000, code_hash.into(), + ::Balance::from(1_000u32).encode() // rent allowance + )); + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.storage_size, ::StorageSizeOffset::get() + 4); + + assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::set_storage_4_byte())); + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.storage_size, ::StorageSizeOffset::get() + 4 + 4); + + assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::remove_storage_4_byte())); + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.storage_size, ::StorageSizeOffset::get() + 4); + }); } #[test] fn deduct_blocks() { let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(50).build(), - || { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::instantiate( - Origin::signed(ALICE), - 30_000, - 100_000, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - - // Check creation - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, 1_000); - - // Advance 4 blocks - System::initialize(&5, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Trigger rent through call - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); - - // Check result - let rent = (8 + 4 - 3) // storage size = size_offset + deploy_set_storage - deposit_offset - * 4 // rent byte price - * 4; // blocks to rent - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, 1_000 - rent); - assert_eq!(bob_contract.deduct_block, 5); - assert_eq!(Balances::free_balance(BOB), 30_000 - rent); - - // Advance 7 blocks more - System::initialize(&12, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Trigger rent through call - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); - - // Check result - let rent_2 = (8 + 4 - 2) // storage size = size_offset + deploy_set_storage - deposit_offset - * 4 // rent byte price - * 7; // blocks to rent - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, 1_000 - rent - rent_2); - assert_eq!(bob_contract.deduct_block, 12); - assert_eq!(Balances::free_balance(BOB), 30_000 - rent - rent_2); - - // Second call on same block should have no effect on rent - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); - - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, 1_000 - rent - rent_2); - assert_eq!(bob_contract.deduct_block, 12); - assert_eq!(Balances::free_balance(BOB), 30_000 - rent - rent_2); - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 30_000, + 100_000, code_hash.into(), + ::Balance::from(1_000u32).encode() // rent allowance + )); + + // Check creation + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, 1_000); + + // Advance 4 blocks + System::initialize(&5, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Trigger rent through call + assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); + + // Check result + let rent = (8 + 4 - 3) // storage size = size_offset + deploy_set_storage - deposit_offset + * 4 // rent byte price + * 4; // blocks to rent + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, 1_000 - rent); + assert_eq!(bob_contract.deduct_block, 5); + assert_eq!(Balances::free_balance(BOB), 30_000 - rent); + + // Advance 7 blocks more + System::initialize(&12, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Trigger rent through call + assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); + + // Check result + let rent_2 = (8 + 4 - 2) // storage size = size_offset + deploy_set_storage - deposit_offset + * 4 // rent byte price + * 7; // blocks to rent + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, 1_000 - rent - rent_2); + assert_eq!(bob_contract.deduct_block, 12); + assert_eq!(Balances::free_balance(BOB), 30_000 - rent - rent_2); + + // Second call on same block should have no effect on rent + assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); + + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, 1_000 - rent - rent_2); + assert_eq!(bob_contract.deduct_block, 12); + assert_eq!(Balances::free_balance(BOB), 30_000 - rent - rent_2); + }); } #[test] @@ -981,32 +960,29 @@ fn claim_surcharge_malus() { fn claim_surcharge(blocks: u64, trigger_call: impl Fn() -> bool, removes: bool) { let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(50).build(), - || { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::instantiate( - Origin::signed(ALICE), - 100, - 100_000, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 100, + 100_000, code_hash.into(), + ::Balance::from(1_000u32).encode() // rent allowance + )); - // Advance blocks - System::initialize(&blocks, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + // Advance blocks + System::initialize(&blocks, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - // Trigger rent through call - assert!(trigger_call()); + // Trigger rent through call + assert!(trigger_call()); - if removes { - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - } else { - assert!(ContractInfoOf::::get(BOB).unwrap().get_alive().is_some()); - } + if removes { + assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); + } else { + assert!(ContractInfoOf::::get(BOB).unwrap().get_alive().is_some()); } - ); + }); } /// Test for all kind of removals for the given trigger: @@ -1017,123 +993,114 @@ fn removals(trigger_call: impl Fn() -> bool) { let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); // Balance reached and superior to subsistence threshold - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(50).build(), - || { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); - assert_ok!(Contract::instantiate( - Origin::signed(ALICE), - 100, - 100_000, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - - let subsistence_threshold = 50 /*existential_deposit*/ + 16 /*tombstone_deposit*/; - - // Trigger rent must have no effect - assert!(trigger_call()); - assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); - assert_eq!(Balances::free_balance(&BOB), 100); - - // Advance blocks - System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Trigger rent through call - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - assert_eq!(Balances::free_balance(&BOB), subsistence_threshold); - - // Advance blocks - System::initialize(&20, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Trigger rent must have no effect - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - assert_eq!(Balances::free_balance(&BOB), subsistence_threshold); - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 100, + 100_000, code_hash.into(), + ::Balance::from(1_000u32).encode() // rent allowance + )); + + let subsistence_threshold = 50 /*existential_deposit*/ + 16 /*tombstone_deposit*/; + + // Trigger rent must have no effect + assert!(trigger_call()); + assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); + assert_eq!(Balances::free_balance(&BOB), 100); + + // Advance blocks + System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Trigger rent through call + assert!(trigger_call()); + assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); + assert_eq!(Balances::free_balance(&BOB), subsistence_threshold); + + // Advance blocks + System::initialize(&20, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Trigger rent must have no effect + assert!(trigger_call()); + assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); + assert_eq!(Balances::free_balance(&BOB), subsistence_threshold); + }); // Allowance exceeded - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(50).build(), - || { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); - assert_ok!(Contract::instantiate( - Origin::signed(ALICE), - 1_000, - 100_000, code_hash.into(), - ::Balance::from(100u32).encode() // rent allowance - )); - - // Trigger rent must have no effect - assert!(trigger_call()); - assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 100); - assert_eq!(Balances::free_balance(&BOB), 1_000); - - // Advance blocks - System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Trigger rent through call - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - // Balance should be initial balance - initial rent_allowance - assert_eq!(Balances::free_balance(&BOB), 900); - - // Advance blocks - System::initialize(&20, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Trigger rent must have no effect - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - assert_eq!(Balances::free_balance(&BOB), 900); - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 1_000, + 100_000, code_hash.into(), + ::Balance::from(100u32).encode() // rent allowance + )); + + // Trigger rent must have no effect + assert!(trigger_call()); + assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 100); + assert_eq!(Balances::free_balance(&BOB), 1_000); + + // Advance blocks + System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Trigger rent through call + assert!(trigger_call()); + assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); + // Balance should be initial balance - initial rent_allowance + assert_eq!(Balances::free_balance(&BOB), 900); + + // Advance blocks + System::initialize(&20, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Trigger rent must have no effect + assert!(trigger_call()); + assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); + assert_eq!(Balances::free_balance(&BOB), 900); + }); // Balance reached and inferior to subsistence threshold - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(50).build(), - || { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); - assert_ok!(Contract::instantiate( - Origin::signed(ALICE), - 50+Balances::minimum_balance(), - 100_000, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - - // Trigger rent must have no effect - assert!(trigger_call()); - assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); - assert_eq!(Balances::free_balance(&BOB), 50 + Balances::minimum_balance()); - - // Transfer funds - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::transfer())); - assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); - assert_eq!(Balances::free_balance(&BOB), Balances::minimum_balance()); - - // Advance blocks - System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Trigger rent through call - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).is_none()); - assert_eq!(Balances::free_balance(&BOB), Balances::minimum_balance()); - - // Advance blocks - System::initialize(&20, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Trigger rent must have no effect - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).is_none()); - assert_eq!(Balances::free_balance(&BOB), Balances::minimum_balance()); - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 50+Balances::minimum_balance(), + 100_000, code_hash.into(), + ::Balance::from(1_000u32).encode() // rent allowance + )); + + // Trigger rent must have no effect + assert!(trigger_call()); + assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); + assert_eq!(Balances::free_balance(&BOB), 50 + Balances::minimum_balance()); + + // Transfer funds + assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::transfer())); + assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); + assert_eq!(Balances::free_balance(&BOB), Balances::minimum_balance()); + + // Advance blocks + System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Trigger rent through call + assert!(trigger_call()); + assert!(ContractInfoOf::::get(BOB).is_none()); + assert_eq!(Balances::free_balance(&BOB), Balances::minimum_balance()); + + // Advance blocks + System::initialize(&20, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Trigger rent must have no effect + assert!(trigger_call()); + assert!(ContractInfoOf::::get(BOB).is_none()); + assert_eq!(Balances::free_balance(&BOB), Balances::minimum_balance()); + }); } #[test] @@ -1141,38 +1108,35 @@ fn call_removed_contract() { let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); // Balance reached and superior to subsistence threshold - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(50).build(), - || { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); - assert_ok!(Contract::instantiate( - Origin::signed(ALICE), - 100, - 100_000, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - - // Calling contract should succeed. - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); - - // Advance blocks - System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Calling contract should remove contract and fail. - assert_err!( - Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()), - "contract has been evicted" - ); - - // Subsequent contract calls should also fail. - assert_err!( - Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()), - "contract has been evicted" - ); - } - ) + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 100, + 100_000, code_hash.into(), + ::Balance::from(1_000u32).encode() // rent allowance + )); + + // Calling contract should succeed. + assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); + + // Advance blocks + System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Calling contract should remove contract and fail. + assert_err!( + Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()), + "contract has been evicted" + ); + + // Subsequent contract calls should also fail. + assert_err!( + Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()), + "contract has been evicted" + ); + }) } const CODE_CHECK_DEFAULT_RENT_ALLOWANCE: &str = r#" @@ -1229,35 +1193,32 @@ const CODE_CHECK_DEFAULT_RENT_ALLOWANCE: &str = r#" fn default_rent_allowance_on_instantiate() { let (wasm, code_hash) = compile_module::(CODE_CHECK_DEFAULT_RENT_ALLOWANCE).unwrap(); - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(50).build(), - || { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::instantiate( - Origin::signed(ALICE), - 30_000, - 100_000, - code_hash.into(), - vec![], - )); - - // Check creation - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, >::max_value()); - - // Advance blocks - System::initialize(&5, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Trigger rent through call - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); - - // Check contract is still alive - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive(); - assert!(bob_contract.is_some()) - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 30_000, + 100_000, + code_hash.into(), + vec![], + )); + + // Check creation + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, >::max_value()); + + // Advance blocks + System::initialize(&5, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Trigger rent through call + assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); + + // Check contract is still alive + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive(); + assert!(bob_contract.is_some()) + }); } const CODE_RESTORATION: &str = r#" @@ -1346,122 +1307,119 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: let (restoration_wasm, restoration_code_hash) = compile_module::(CODE_RESTORATION).unwrap(); - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(50).build(), - || { - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, restoration_wasm)); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, set_rent_wasm)); - - // If you ever need to update the wasm source this test will fail - // and will show you the actual hash. - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(restoration_code_hash.into())), - topics: vec![], - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(set_rent_code_hash.into())), - topics: vec![], - }, - ]); - - // Create an account with address `BOB` with code `CODE_SET_RENT`. - // The input parameter sets the rent allowance to 0. - assert_ok!(Contract::instantiate( + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, restoration_wasm)); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, set_rent_wasm)); + + // If you ever need to update the wasm source this test will fail + // and will show you the actual hash. + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::CodeStored(restoration_code_hash.into())), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::CodeStored(set_rent_code_hash.into())), + topics: vec![], + }, + ]); + + // Create an account with address `BOB` with code `CODE_SET_RENT`. + // The input parameter sets the rent allowance to 0. + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 30_000, + 100_000, + set_rent_code_hash.into(), + ::Balance::from(0u32).encode() + )); + + // Check if `BOB` was created successfully and that the rent allowance is + // set to 0. + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, 0); + + if test_different_storage { + assert_ok!(Contract::call( Origin::signed(ALICE), - 30_000, - 100_000, - set_rent_code_hash.into(), - ::Balance::from(0u32).encode() - )); - - // Check if `BOB` was created successfully and that the rent allowance is - // set to 0. - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, 0); - - if test_different_storage { - assert_ok!(Contract::call( - Origin::signed(ALICE), - BOB, 0, 100_000, - call::set_storage_4_byte()) - ); - } - - // Advance 4 blocks, to the 5th. - System::initialize(&5, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - - // Call `BOB`, which makes it pay rent. Since the rent allowance is set to 0 - // we expect that it will get removed leaving tombstone. - assert_err!( - Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()), - "contract has been evicted" + BOB, 0, 100_000, + call::set_storage_4_byte()) ); - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - - /// Create another account with the address `DJANGO` with `CODE_RESTORATION`. - /// - /// Note that we can't use `ALICE` for creating `DJANGO` so we create yet another - /// account `CHARLIE` and create `DJANGO` with it. - Balances::deposit_creating(&CHARLIE, 1_000_000); - assert_ok!(Contract::instantiate( - Origin::signed(CHARLIE), - 30_000, - 100_000, - restoration_code_hash.into(), - ::Balance::from(0u32).encode() - )); - - // Before performing a call to `DJANGO` save its original trie id. - let django_trie_id = ContractInfoOf::::get(DJANGO).unwrap() - .get_alive().unwrap().trie_id; + } - if !test_restore_to_with_dirty_storage { - // Advance 1 block, to the 6th. - System::initialize(&6, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); - } + // Advance 4 blocks, to the 5th. + System::initialize(&5, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + + // Call `BOB`, which makes it pay rent. Since the rent allowance is set to 0 + // we expect that it will get removed leaving tombstone. + assert_err!( + Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()), + "contract has been evicted" + ); + assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); + + /// Create another account with the address `DJANGO` with `CODE_RESTORATION`. + /// + /// Note that we can't use `ALICE` for creating `DJANGO` so we create yet another + /// account `CHARLIE` and create `DJANGO` with it. + Balances::deposit_creating(&CHARLIE, 1_000_000); + assert_ok!(Contract::instantiate( + Origin::signed(CHARLIE), + 30_000, + 100_000, + restoration_code_hash.into(), + ::Balance::from(0u32).encode() + )); + + // Before performing a call to `DJANGO` save its original trie id. + let django_trie_id = ContractInfoOf::::get(DJANGO).unwrap() + .get_alive().unwrap().trie_id; + + if !test_restore_to_with_dirty_storage { + // Advance 1 block, to the 6th. + System::initialize(&6, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + } - // Perform a call to `DJANGO`. This should either perform restoration successfully or - // fail depending on the test parameters. - assert_ok!(Contract::call( - Origin::signed(ALICE), - DJANGO, - 0, - 100_000, - vec![], - )); - - if test_different_storage || test_restore_to_with_dirty_storage { - // Parametrization of the test imply restoration failure. Check that `DJANGO` aka - // restoration contract is still in place and also that `BOB` doesn't exist. - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - let django_contract = ContractInfoOf::::get(DJANGO).unwrap() - .get_alive().unwrap(); - assert_eq!(django_contract.storage_size, 16); - assert_eq!(django_contract.trie_id, django_trie_id); - assert_eq!(django_contract.deduct_block, System::block_number()); - } else { - // Here we expect that the restoration is succeeded. Check that the restoration - // contract `DJANGO` ceased to exist and that `BOB` returned back. - println!("{:?}", ContractInfoOf::::get(BOB)); - let bob_contract = ContractInfoOf::::get(BOB).unwrap() - .get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, 50); - assert_eq!(bob_contract.storage_size, 12); - assert_eq!(bob_contract.trie_id, django_trie_id); - assert_eq!(bob_contract.deduct_block, System::block_number()); - assert!(ContractInfoOf::::get(DJANGO).is_none()); - } + // Perform a call to `DJANGO`. This should either perform restoration successfully or + // fail depending on the test parameters. + assert_ok!(Contract::call( + Origin::signed(ALICE), + DJANGO, + 0, + 100_000, + vec![], + )); + + if test_different_storage || test_restore_to_with_dirty_storage { + // Parametrization of the test imply restoration failure. Check that `DJANGO` aka + // restoration contract is still in place and also that `BOB` doesn't exist. + assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); + let django_contract = ContractInfoOf::::get(DJANGO).unwrap() + .get_alive().unwrap(); + assert_eq!(django_contract.storage_size, 16); + assert_eq!(django_contract.trie_id, django_trie_id); + assert_eq!(django_contract.deduct_block, System::block_number()); + } else { + // Here we expect that the restoration is succeeded. Check that the restoration + // contract `DJANGO` ceased to exist and that `BOB` returned back. + println!("{:?}", ContractInfoOf::::get(BOB)); + let bob_contract = ContractInfoOf::::get(BOB).unwrap() + .get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, 50); + assert_eq!(bob_contract.storage_size, 12); + assert_eq!(bob_contract.trie_id, django_trie_id); + assert_eq!(bob_contract.deduct_block, System::block_number()); + assert!(ContractInfoOf::::get(DJANGO).is_none()); } - ); + }); } const CODE_STORAGE_SIZE: &str = r#" @@ -1532,46 +1490,43 @@ const CODE_STORAGE_SIZE: &str = r#" fn storage_max_value_limit() { let (wasm, code_hash) = compile_module::(CODE_STORAGE_SIZE).unwrap(); - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(50).build(), - || { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::instantiate( - Origin::signed(ALICE), - 30_000, - 100_000, - code_hash.into(), - vec![], - )); - - // Check creation - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, >::max_value()); - - // Call contract with allowed storage value. - assert_ok!(Contract::call( + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 30_000, + 100_000, + code_hash.into(), + vec![], + )); + + // Check creation + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, >::max_value()); + + // Call contract with allowed storage value. + assert_ok!(Contract::call( + Origin::signed(ALICE), + BOB, + 0, + 100_000, + Encode::encode(&self::MaxValueSize::get()), + )); + + // Call contract with too large a storage value. + assert_err!( + Contract::call( Origin::signed(ALICE), BOB, 0, 100_000, - Encode::encode(&self::MaxValueSize::get()), - )); - - // Call contract with too large a storage value. - assert_err!( - Contract::call( - Origin::signed(ALICE), - BOB, - 0, - 100_000, - Encode::encode(&(self::MaxValueSize::get() + 1)), - ), - "during execution" - ); - } - ); + Encode::encode(&(self::MaxValueSize::get() + 1)), + ), + "during execution" + ); + }); } const CODE_RETURN_WITH_DATA: &str = r#" @@ -1899,33 +1854,30 @@ fn deploy_and_call_other_contract() { let (callee_wasm, callee_code_hash) = compile_module::(CODE_RETURN_WITH_DATA).unwrap(); let (caller_wasm, caller_code_hash) = compile_module::(CODE_CALLER_CONTRACT).unwrap(); - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(50).build(), - || { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, callee_wasm)); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, caller_wasm)); - - assert_ok!(Contract::instantiate( - Origin::signed(ALICE), - 100_000, - 100_000, - caller_code_hash.into(), - vec![], - )); - - // Call BOB contract, which attempts to instantiate and call the callee contract and - // makes various assertions on the results from those calls. - assert_ok!(Contract::call( - Origin::signed(ALICE), - BOB, - 0, - 200_000, - callee_code_hash.as_ref().to_vec(), - )); - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, callee_wasm)); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, caller_wasm)); + + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 100_000, + 100_000, + caller_code_hash.into(), + vec![], + )); + + // Call BOB contract, which attempts to instantiate and call the callee contract and + // makes various assertions on the results from those calls. + assert_ok!(Contract::call( + Origin::signed(ALICE), + BOB, + 0, + 200_000, + callee_code_hash.as_ref().to_vec(), + )); + }); } const CODE_SELF_DESTRUCT: &str = r#" @@ -2030,86 +1982,80 @@ const CODE_SELF_DESTRUCT: &str = r#" #[test] fn self_destruct_by_draining_balance() { let (wasm, code_hash) = compile_module::(CODE_SELF_DESTRUCT).unwrap(); - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(50).build(), - || { - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - - // Instantiate the BOB contract. - assert_ok!(Contract::instantiate( - Origin::signed(ALICE), - 100_000, - 100_000, - code_hash.into(), - vec![], - )); - - // Check that the BOB contract has been instantiated. - assert_matches!( - ContractInfoOf::::get(BOB), - Some(ContractInfo::Alive(_)) - ); - - // Call BOB with no input data, forcing it to self-destruct. - assert_ok!(Contract::call( - Origin::signed(ALICE), - BOB, - 0, - 100_000, - vec![], - )); - - // Check that BOB is now dead. - assert!(ContractInfoOf::::get(BOB).is_none()); - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + + // Instantiate the BOB contract. + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 100_000, + 100_000, + code_hash.into(), + vec![], + )); + + // Check that the BOB contract has been instantiated. + assert_matches!( + ContractInfoOf::::get(BOB), + Some(ContractInfo::Alive(_)) + ); + + // Call BOB with no input data, forcing it to self-destruct. + assert_ok!(Contract::call( + Origin::signed(ALICE), + BOB, + 0, + 100_000, + vec![], + )); + + // Check that BOB is now dead. + assert!(ContractInfoOf::::get(BOB).is_none()); + }); } #[test] fn cannot_self_destruct_while_live() { let (wasm, code_hash) = compile_module::(CODE_SELF_DESTRUCT).unwrap(); - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(50).build(), - || { - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - - // Instantiate the BOB contract. - assert_ok!(Contract::instantiate( + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + + // Instantiate the BOB contract. + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 100_000, + 100_000, + code_hash.into(), + vec![], + )); + + // Check that the BOB contract has been instantiated. + assert_matches!( + ContractInfoOf::::get(BOB), + Some(ContractInfo::Alive(_)) + ); + + // Call BOB with input data, forcing it make a recursive call to itself to + // self-destruct, resulting in a trap. + assert_err!( + Contract::call( Origin::signed(ALICE), + BOB, + 0, 100_000, - 100_000, - code_hash.into(), - vec![], - )); - - // Check that the BOB contract has been instantiated. - assert_matches!( - ContractInfoOf::::get(BOB), - Some(ContractInfo::Alive(_)) - ); - - // Call BOB with input data, forcing it make a recursive call to itself to - // self-destruct, resulting in a trap. - assert_err!( - Contract::call( - Origin::signed(ALICE), - BOB, - 0, - 100_000, - vec![0], - ), - "during execution" - ); - - // Check that BOB is still alive. - assert_matches!( - ContractInfoOf::::get(BOB), - Some(ContractInfo::Alive(_)) - ); - } - ); + vec![0], + ), + "during execution" + ); + + // Check that BOB is still alive. + assert_matches!( + ContractInfoOf::::get(BOB), + Some(ContractInfo::Alive(_)) + ); + }); } const CODE_DESTROY_AND_TRANSFER: &str = r#" @@ -2271,43 +2217,40 @@ fn destroy_contract_and_transfer_funds() { let (callee_wasm, callee_code_hash) = compile_module::(CODE_SELF_DESTRUCT).unwrap(); let (caller_wasm, caller_code_hash) = compile_module::(CODE_DESTROY_AND_TRANSFER).unwrap(); - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(50).build(), - || { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, callee_wasm)); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, caller_wasm)); - - // This deploys the BOB contract, which in turn deploys the CHARLIE contract during - // construction. - assert_ok!(Contract::instantiate( - Origin::signed(ALICE), - 200_000, - 100_000, - caller_code_hash.into(), - callee_code_hash.as_ref().to_vec(), - )); - - // Check that the CHARLIE contract has been instantiated. - assert_matches!( - ContractInfoOf::::get(CHARLIE), - Some(ContractInfo::Alive(_)) - ); - - // Call BOB, which calls CHARLIE, forcing CHARLIE to self-destruct. - assert_ok!(Contract::call( - Origin::signed(ALICE), - BOB, - 0, - 100_000, - CHARLIE.encode(), - )); - - // Check that CHARLIE has moved on to the great beyond (ie. died). - assert!(ContractInfoOf::::get(CHARLIE).is_none()); - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + // Create + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, callee_wasm)); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, caller_wasm)); + + // This deploys the BOB contract, which in turn deploys the CHARLIE contract during + // construction. + assert_ok!(Contract::instantiate( + Origin::signed(ALICE), + 200_000, + 100_000, + caller_code_hash.into(), + callee_code_hash.as_ref().to_vec(), + )); + + // Check that the CHARLIE contract has been instantiated. + assert_matches!( + ContractInfoOf::::get(CHARLIE), + Some(ContractInfo::Alive(_)) + ); + + // Call BOB, which calls CHARLIE, forcing CHARLIE to self-destruct. + assert_ok!(Contract::call( + Origin::signed(ALICE), + BOB, + 0, + 100_000, + CHARLIE.encode(), + )); + + // Check that CHARLIE has moved on to the great beyond (ie. died). + assert!(ContractInfoOf::::get(CHARLIE).is_none()); + }); } const CODE_SELF_DESTRUCTING_CONSTRUCTOR: &str = r#" @@ -2370,43 +2313,37 @@ const CODE_SELF_DESTRUCTING_CONSTRUCTOR: &str = r#" #[test] fn cannot_self_destruct_in_constructor() { let (wasm, code_hash) = compile_module::(CODE_SELF_DESTRUCTING_CONSTRUCTOR).unwrap(); - set_and_run_with_externalities( - &mut ExtBuilder::default().existential_deposit(50).build(), - || { - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - - // Fail to instantiate the BOB contract since its final balance is below existential - // deposit. - assert_err!( - Contract::instantiate( - Origin::signed(ALICE), - 100_000, - 100_000, - code_hash.into(), - vec![], - ), - "insufficient remaining balance" - ); - } - ); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + + // Fail to instantiate the BOB contract since its final balance is below existential + // deposit. + assert_err!( + Contract::instantiate( + Origin::signed(ALICE), + 100_000, + 100_000, + code_hash.into(), + vec![], + ), + "insufficient remaining balance" + ); + }); } #[test] fn check_block_gas_limit_works() { - set_and_run_with_externalities( - &mut ExtBuilder::default().block_gas_limit(50).build(), - || { - let info = DispatchInfo { weight: 100, class: DispatchClass::Normal }; - let check = CheckBlockGasLimit::(Default::default()); - let call: Call = crate::Call::put_code(1000, vec![]).into(); + ExtBuilder::default().block_gas_limit(50).build().execute_with(|| { + let info = DispatchInfo { weight: 100, class: DispatchClass::Normal }; + let check = CheckBlockGasLimit::(Default::default()); + let call: Call = crate::Call::put_code(1000, vec![]).into(); - assert_eq!( - check.validate(&0, &call, info, 0), InvalidTransaction::ExhaustsResources.into(), - ); + assert_eq!( + check.validate(&0, &call, info, 0), InvalidTransaction::ExhaustsResources.into(), + ); - let call: Call = crate::Call::update_schedule(Default::default()).into(); - assert_eq!(check.validate(&0, &call, info, 0), Ok(Default::default())); - } - ); + let call: Call = crate::Call::update_schedule(Default::default()).into(); + assert_eq!(check.validate(&0, &call, info, 0), Ok(Default::default())); + }); } diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index 477e6818c9..2af301df1c 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -976,10 +976,7 @@ mod tests { traits::Contains }; use primitives::H256; - use sr_primitives::{ - set_and_run_with_externalities, traits::{BlakeTwo256, IdentityLookup, Bounded}, - testing::Header, Perbill, - }; + use sr_primitives::{traits::{BlakeTwo256, IdentityLookup, Bounded}, testing::Header, Perbill}; use balances::BalanceLock; use system::EnsureSignedBy; @@ -1101,7 +1098,7 @@ mod tests { #[test] fn params_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(Democracy::referendum_count(), 0); assert_eq!(Balances::free_balance(&42), 0); assert_eq!(Balances::total_issuance(), 210); @@ -1133,7 +1130,7 @@ mod tests { #[test] fn external_and_public_interleaving_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(Democracy::external_propose( Origin::signed(2), @@ -1246,7 +1243,7 @@ mod tests { #[test] fn emergency_cancel_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); let r = Democracy::inject_referendum( 2, @@ -1275,7 +1272,7 @@ mod tests { #[test] fn veto_external_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(Democracy::external_propose( Origin::signed(2), @@ -1335,7 +1332,7 @@ mod tests { #[test] fn external_referendum_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_noop!(Democracy::external_propose( Origin::signed(1), @@ -1364,7 +1361,7 @@ mod tests { #[test] fn external_majority_referendum_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_noop!(Democracy::external_propose_majority( Origin::signed(1), @@ -1389,7 +1386,7 @@ mod tests { #[test] fn external_default_referendum_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_noop!(Democracy::external_propose_default( Origin::signed(3), @@ -1414,7 +1411,7 @@ mod tests { #[test] fn fast_track_referendum_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); let h = BlakeTwo256::hash_of(&set_balance_proposal(2)); assert_noop!(Democracy::fast_track(Origin::signed(5), h, 3, 2), "no proposal made"); @@ -1438,7 +1435,7 @@ mod tests { #[test] fn fast_track_referendum_fails_when_no_simple_majority() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); let h = BlakeTwo256::hash_of(&set_balance_proposal(2)); assert_ok!(Democracy::external_propose( @@ -1454,7 +1451,7 @@ mod tests { #[test] fn locked_for_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); assert_ok!(propose_set_balance(1, 2, 2)); assert_ok!(propose_set_balance(1, 4, 4)); @@ -1467,7 +1464,7 @@ mod tests { #[test] fn single_proposal_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); assert!(Democracy::referendum_info(0).is_none()); @@ -1514,7 +1511,7 @@ mod tests { #[test] fn cancel_queued_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1538,7 +1535,7 @@ mod tests { #[test] fn proxy_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(Democracy::proxy(10), None); assert_ok!(Democracy::set_proxy(Origin::signed(1), 10)); assert_eq!(Democracy::proxy(10), Some(1)); @@ -1568,7 +1565,7 @@ mod tests { #[test] fn single_proposal_should_work_with_proxy() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1588,7 +1585,7 @@ mod tests { #[test] fn single_proposal_should_work_with_delegation() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1613,7 +1610,7 @@ mod tests { #[test] fn single_proposal_should_work_with_cyclic_delegation() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1640,7 +1637,7 @@ mod tests { #[test] /// If transactor already voted, delegated vote is overwriten. fn single_proposal_should_work_with_vote_and_delegation() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1666,7 +1663,7 @@ mod tests { #[test] fn single_proposal_should_work_with_undelegation() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1695,7 +1692,7 @@ mod tests { #[test] /// If transactor voted, delegated vote is overwriten. fn single_proposal_should_work_with_delegation_and_vote() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 1)); @@ -1726,7 +1723,7 @@ mod tests { #[test] fn deposit_for_proposals_should_be_taken() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); assert_ok!(propose_set_balance(1, 2, 5)); assert_ok!(Democracy::second(Origin::signed(2), 0)); @@ -1741,7 +1738,7 @@ mod tests { #[test] fn deposit_for_proposals_should_be_returned() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); assert_ok!(propose_set_balance(1, 2, 5)); assert_ok!(Democracy::second(Origin::signed(2), 0)); @@ -1757,7 +1754,7 @@ mod tests { #[test] fn proposal_with_deposit_below_minimum_should_not_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); assert_noop!(propose_set_balance(1, 2, 0), "value too low"); }); @@ -1765,7 +1762,7 @@ mod tests { #[test] fn poor_proposer_should_not_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); assert_noop!(propose_set_balance(1, 2, 11), "proposer\'s balance too low"); }); @@ -1773,7 +1770,7 @@ mod tests { #[test] fn poor_seconder_should_not_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); assert_ok!(propose_set_balance(2, 2, 11)); assert_noop!(Democracy::second(Origin::signed(1), 0), "seconder\'s balance too low"); @@ -1782,7 +1779,7 @@ mod tests { #[test] fn runners_up_should_come_after() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(propose_set_balance(1, 2, 2)); assert_ok!(propose_set_balance(1, 4, 4)); @@ -1798,7 +1795,7 @@ mod tests { #[test] fn simple_passing_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( 1, @@ -1821,7 +1818,7 @@ mod tests { #[test] fn cancel_referendum_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( 1, @@ -1841,7 +1838,7 @@ mod tests { #[test] fn simple_failing_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( 1, @@ -1864,7 +1861,7 @@ mod tests { #[test] fn controversial_voting_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( 1, @@ -1890,7 +1887,7 @@ mod tests { #[test] fn delayed_enactment_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( 1, @@ -1918,7 +1915,7 @@ mod tests { #[test] fn controversial_low_turnout_voting_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( 1, @@ -1940,7 +1937,7 @@ mod tests { #[test] fn passing_low_turnout_voting_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(Balances::free_balance(&42), 0); assert_eq!(Balances::total_issuance(), 210); @@ -1966,7 +1963,7 @@ mod tests { #[test] fn lock_voting_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(0); let r = Democracy::inject_referendum( 1, @@ -2026,7 +2023,7 @@ mod tests { #[test] fn lock_voting_should_work_with_delegation() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( 1, diff --git a/srml/elections-phragmen/src/lib.rs b/srml/elections-phragmen/src/lib.rs index 1405536267..6ec79a537c 100644 --- a/srml/elections-phragmen/src/lib.rs +++ b/srml/elections-phragmen/src/lib.rs @@ -594,7 +594,7 @@ mod tests { use primitives::H256; use sr_primitives::{ Perbill, testing::Header, BuildStorage, - traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, set_and_run_with_externalities + traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, }; use crate as elections; @@ -770,7 +770,7 @@ mod tests { #[test] fn params_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_eq!(Elections::desired_members(), 2); assert_eq!(Elections::term_duration(), 5); @@ -790,7 +790,7 @@ mod tests { #[test] fn simple_candidate_submission_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(Elections::candidates(), Vec::::new()); assert!(Elections::is_candidate(&1).is_err()); assert!(Elections::is_candidate(&2).is_err()); @@ -817,7 +817,7 @@ mod tests { #[test] fn simple_candidate_submission_with_no_votes_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(Elections::candidates(), Vec::::new()); assert_ok!(Elections::submit_candidacy(Origin::signed(1))); @@ -844,7 +844,7 @@ mod tests { #[test] fn dupe_candidate_submission_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(Elections::candidates(), Vec::::new()); assert_ok!(Elections::submit_candidacy(Origin::signed(1))); assert_eq!(Elections::candidates(), vec![1]); @@ -858,7 +858,7 @@ mod tests { #[test] fn member_candidacy_submission_should_not_work() { // critically important to make sure that outgoing candidates and losers are not mixed up. - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); @@ -878,7 +878,7 @@ mod tests { #[test] fn poor_candidate_submission_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(Elections::candidates(), Vec::::new()); assert_noop!( Elections::submit_candidacy(Origin::signed(7)), @@ -889,7 +889,7 @@ mod tests { #[test] fn simple_voting_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(Elections::candidates(), Vec::::new()); assert_eq!(balances(&2), (20, 0)); @@ -903,7 +903,7 @@ mod tests { #[test] fn can_vote_with_custom_stake() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(Elections::candidates(), Vec::::new()); assert_eq!(balances(&2), (20, 0)); @@ -917,7 +917,7 @@ mod tests { #[test] fn can_update_votes_and_stake() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(balances(&2), (20, 0)); assert_ok!(Elections::submit_candidacy(Origin::signed(5))); @@ -938,7 +938,7 @@ mod tests { #[test] fn cannot_vote_for_no_candidate() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_noop!( Elections::vote(Origin::signed(2), vec![], 20), "cannot vote when no candidates or members exist" @@ -949,7 +949,7 @@ mod tests { #[test] fn can_vote_for_old_members_even_when_no_new_candidates() { // let allowed_votes = candidates_count as usize + Self::members().len() - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -967,7 +967,7 @@ mod tests { #[test] fn cannot_vote_for_more_than_candidates() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -980,7 +980,7 @@ mod tests { #[test] fn cannot_vote_for_less_than_ed() { - set_and_run_with_externalities(&mut ExtBuilder::default().voter_bond(8).build(), || { + ExtBuilder::default().voter_bond(8).build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -993,7 +993,7 @@ mod tests { #[test] fn can_vote_for_more_than_total_balance_but_moot() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1006,7 +1006,7 @@ mod tests { #[test] fn remove_voter_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().voter_bond(8).build(), || { + ExtBuilder::default().voter_bond(8).build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); @@ -1031,14 +1031,14 @@ mod tests { #[test] fn non_voter_remove_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_noop!(Elections::remove_voter(Origin::signed(3)), "must be a voter"); }); } #[test] fn dupe_remove_should_fail() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); @@ -1051,7 +1051,7 @@ mod tests { #[test] fn removed_voter_should_not_be_counted() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1071,7 +1071,7 @@ mod tests { #[test] fn reporter_must_be_voter() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_noop!( Elections::report_defunct_voter(Origin::signed(1), 2), "reporter must be a voter", @@ -1081,7 +1081,7 @@ mod tests { #[test] fn can_detect_defunct_voter() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1116,7 +1116,7 @@ mod tests { #[test] fn report_voter_should_work_and_earn_reward() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1148,8 +1148,7 @@ mod tests { #[test] fn report_voter_should_slash_when_bad_report() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1174,13 +1173,12 @@ mod tests { assert_eq!(balances(&4), (35, 5)); assert_eq!(balances(&5), (45, 3)); }); - }); } #[test] fn simple_voting_rounds_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1215,7 +1213,7 @@ mod tests { #[test] fn defunct_voter_will_be_counted() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); // This guy's vote is pointless for this round. @@ -1243,7 +1241,7 @@ mod tests { #[test] fn only_desired_seats_are_chosen() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1264,7 +1262,7 @@ mod tests { #[test] fn phragmen_should_not_self_vote() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1279,7 +1277,7 @@ mod tests { #[test] fn runners_up_should_be_kept() { - set_and_run_with_externalities(&mut ExtBuilder::default().desired_runners_up(2).build(), || { + ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1306,7 +1304,7 @@ mod tests { #[test] fn runners_up_should_be_next_candidates() { - set_and_run_with_externalities(&mut ExtBuilder::default().desired_runners_up(2).build(), || { + ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1333,7 +1331,7 @@ mod tests { #[test] fn runners_up_lose_bond_once_outgoing() { - set_and_run_with_externalities(&mut ExtBuilder::default().desired_runners_up(1).build(), || { + ExtBuilder::default().desired_runners_up(1).build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(2))); @@ -1364,7 +1362,7 @@ mod tests { #[test] fn current_members_are_always_implicitly_next_candidate() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1400,7 +1398,7 @@ mod tests { fn election_state_is_uninterrupted() { // what I mean by uninterrupted: // given no input or stimulants the same members are re-elected. - set_and_run_with_externalities(&mut ExtBuilder::default().desired_runners_up(2).build(), || { + ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1433,7 +1431,7 @@ mod tests { #[test] fn remove_members_triggers_election() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1459,7 +1457,7 @@ mod tests { #[test] fn seats_should_be_released_when_no_vote() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1493,7 +1491,7 @@ mod tests { #[test] fn outgoing_will_get_the_bond_back() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(balances(&5), (50, 0)); assert_ok!(Elections::submit_candidacy(Origin::signed(5))); @@ -1519,7 +1517,7 @@ mod tests { #[test] fn losers_will_lose_the_bond() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); @@ -1542,7 +1540,7 @@ mod tests { #[test] fn incoming_outgoing_are_reported() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(5))); @@ -1587,7 +1585,7 @@ mod tests { #[test] fn invalid_votes_are_moot() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(4))); assert_ok!(Elections::submit_candidacy(Origin::signed(3))); diff --git a/srml/elections/src/mock.rs b/srml/elections/src/mock.rs index b9e548e1ed..d48a0fd3fd 100644 --- a/srml/elections/src/mock.rs +++ b/srml/elections/src/mock.rs @@ -25,8 +25,7 @@ use support::{ }; use primitives::H256; use sr_primitives::{ - Perbill, BuildStorage, set_and_run_with_externalities, testing::Header, - traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, + Perbill, BuildStorage, testing::Header, traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, }; use crate as elections; @@ -283,7 +282,7 @@ pub(crate) fn locks(who: &u64) -> Vec { pub(crate) fn new_test_ext_with_candidate_holes() -> runtime_io::TestExternalities { let mut t = ExtBuilder::default().build(); - set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { >::put(vec![0, 0, 1]); elections::CandidateCount::put(1); >::insert(1, (0, 2)); diff --git a/srml/elections/src/tests.rs b/srml/elections/src/tests.rs index 149e534a2f..c9bb054ab2 100644 --- a/srml/elections/src/tests.rs +++ b/srml/elections/src/tests.rs @@ -22,11 +22,10 @@ use crate::mock::*; use crate::*; use support::{assert_ok, assert_err, assert_noop}; -use sr_primitives::set_and_run_with_externalities; #[test] fn params_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_eq!(Elections::next_vote_from(1), 4); assert_eq!(Elections::next_vote_from(4), 4); @@ -53,7 +52,7 @@ fn params_should_work() { #[test] fn chunking_bool_to_flag_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(Elections::bool_to_flag(vec![]), vec![]); assert_eq!(Elections::bool_to_flag(vec![false]), vec![0]); assert_eq!(Elections::bool_to_flag(vec![true]), vec![1]); @@ -98,7 +97,7 @@ fn chunking_bool_to_flag_should_work() { #[test] fn chunking_voter_set_growth_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); // create 65. 64 (set0) + 1 (set1) @@ -122,7 +121,7 @@ fn chunking_voter_set_growth_should_work() { #[test] fn chunking_voter_set_reclaim_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); (1..=129).for_each(|i| vote(i, 0)); @@ -159,7 +158,7 @@ fn chunking_voter_set_reclaim_should_work() { #[test] fn chunking_approvals_set_growth_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { // create candidates and voters. (1..=250).for_each(|i| create_candidate(i, (i-1) as u32)); (1..=250).for_each(|i| vote(i, i as usize)); @@ -221,7 +220,7 @@ fn chunking_approvals_set_growth_should_work() { #[test] fn chunking_cell_status_works() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); (1..=63).for_each(|i| vote(i, 0)); @@ -240,7 +239,7 @@ fn chunking_cell_status_works() { #[test] fn chunking_voter_index_does_not_take_holes_into_account() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); // create 65. 64 (set0) + 1 (set1) @@ -265,7 +264,7 @@ fn chunking_voter_index_does_not_take_holes_into_account() { #[test] fn chunking_approval_storage_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); @@ -285,7 +284,7 @@ fn chunking_approval_storage_should_work() { #[test] fn voting_initial_set_approvals_ignores_voter_index() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); // Last argument is essentially irrelevant. You might get or miss a tip. @@ -299,7 +298,7 @@ fn voting_initial_set_approvals_ignores_voter_index() { } #[test] fn voting_bad_approval_index_slashes_voters_and_bond_reduces_stake() { - set_and_run_with_externalities(&mut ExtBuilder::default().voting_fee(5).voter_bond(2).build(), || { + ExtBuilder::default().voting_fee(5).voter_bond(2).build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); (1..=63).for_each(|i| vote(i, 0)); @@ -329,7 +328,7 @@ fn voting_bad_approval_index_slashes_voters_and_bond_reduces_stake() { #[test] fn voting_subsequent_set_approvals_checks_voter_index() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::set_approvals(Origin::signed(3), vec![], 0, 0, 30)); @@ -353,7 +352,7 @@ fn voting_subsequent_set_approvals_checks_voter_index() { #[test] fn voting_cannot_lock_less_than_limit() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_noop!( @@ -366,7 +365,7 @@ fn voting_cannot_lock_less_than_limit() { #[test] fn voting_locking_more_than_total_balance_is_moot() { - set_and_run_with_externalities(&mut ExtBuilder::default().voter_bond(2).build(), || { + ExtBuilder::default().voter_bond(2).build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_eq!(balances(&3), (30, 0)); @@ -382,7 +381,7 @@ fn voting_locking_more_than_total_balance_is_moot() { #[test] fn voting_locking_stake_and_reserving_bond_works() { - set_and_run_with_externalities(&mut ExtBuilder::default().voter_bond(2).build(), || { + ExtBuilder::default().voter_bond(2).build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); assert_eq!(balances(&2), (20, 0)); @@ -408,7 +407,7 @@ fn voting_locking_stake_and_reserving_bond_works() { #[test] fn voting_without_any_candidate_count_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_eq!(Elections::candidates().len(), 0); @@ -422,7 +421,7 @@ fn voting_without_any_candidate_count_should_not_work() { #[test] fn voting_setting_an_approval_vote_count_more_than_candidate_count_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); @@ -437,7 +436,7 @@ fn voting_setting_an_approval_vote_count_more_than_candidate_count_should_not_wo #[test] fn voting_resubmitting_approvals_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); @@ -456,7 +455,7 @@ fn voting_resubmitting_approvals_should_work() { #[test] fn voting_retracting_voter_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); @@ -501,7 +500,7 @@ fn voting_retracting_voter_should_work() { #[test] fn voting_invalid_retraction_index_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); @@ -514,7 +513,7 @@ fn voting_invalid_retraction_index_should_not_work() { #[test] fn voting_overflow_retraction_index_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); @@ -525,7 +524,7 @@ fn voting_overflow_retraction_index_should_not_work() { #[test] fn voting_non_voter_retraction_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); @@ -536,7 +535,7 @@ fn voting_non_voter_retraction_should_not_work() { #[test] fn retracting_inactive_voter_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); @@ -570,7 +569,7 @@ fn retracting_inactive_voter_should_work() { #[test] fn retracting_inactive_voter_with_other_candidates_in_slots_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().voter_bond(2).build(), || { + ExtBuilder::default().voter_bond(2).build().execute_with(|| { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); @@ -605,7 +604,7 @@ fn retracting_inactive_voter_with_other_candidates_in_slots_should_work() { #[test] fn retracting_inactive_voter_with_bad_reporter_index_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); @@ -634,7 +633,7 @@ fn retracting_inactive_voter_with_bad_reporter_index_should_not_work() { #[test] fn retracting_inactive_voter_with_bad_target_index_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); @@ -663,7 +662,7 @@ fn retracting_inactive_voter_with_bad_target_index_should_not_work() { #[test] fn retracting_active_voter_should_slash_reporter() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); @@ -711,7 +710,7 @@ fn retracting_active_voter_should_slash_reporter() { #[test] fn retracting_inactive_voter_by_nonvoter_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); @@ -740,7 +739,7 @@ fn retracting_inactive_voter_by_nonvoter_should_not_work() { #[test] fn candidacy_simple_candidate_submission_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_eq!(Elections::candidates(), Vec::::new()); assert_eq!(Elections::candidate_reg_info(1), None); @@ -768,7 +767,7 @@ fn candidacy_simple_candidate_submission_should_work() { fn candidacy_submission_using_free_slot_should_work() { let mut t = new_test_ext_with_candidate_holes(); - set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { System::set_block_number(1); assert_eq!(Elections::candidates(), vec![0, 0, 1]); @@ -784,7 +783,7 @@ fn candidacy_submission_using_free_slot_should_work() { fn candidacy_submission_using_alternative_free_slot_should_work() { let mut t = new_test_ext_with_candidate_holes(); - set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { System::set_block_number(1); assert_eq!(Elections::candidates(), vec![0, 0, 1]); @@ -800,7 +799,7 @@ fn candidacy_submission_using_alternative_free_slot_should_work() { fn candidacy_submission_not_using_free_slot_should_not_work() { let mut t = new_test_ext_with_candidate_holes(); - set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { System::set_block_number(1); assert_noop!( Elections::submit_candidacy(Origin::signed(4), 3), @@ -811,7 +810,7 @@ fn candidacy_submission_not_using_free_slot_should_not_work() { #[test] fn candidacy_bad_candidate_slot_submission_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_eq!(Elections::candidates(), Vec::::new()); assert_noop!( @@ -823,7 +822,7 @@ fn candidacy_bad_candidate_slot_submission_should_not_work() { #[test] fn candidacy_non_free_candidate_slot_submission_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_eq!(Elections::candidates(), Vec::::new()); assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); @@ -837,7 +836,7 @@ fn candidacy_non_free_candidate_slot_submission_should_not_work() { #[test] fn candidacy_dupe_candidate_submission_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_eq!(Elections::candidates(), Vec::::new()); assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); @@ -851,7 +850,7 @@ fn candidacy_dupe_candidate_submission_should_not_work() { #[test] fn candidacy_poor_candidate_submission_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_eq!(Elections::candidates(), Vec::::new()); assert_noop!( @@ -863,7 +862,7 @@ fn candidacy_poor_candidate_submission_should_not_work() { #[test] fn election_voting_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); @@ -892,7 +891,7 @@ fn election_voting_should_work() { #[test] fn election_proxy_voting_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); @@ -933,7 +932,7 @@ fn election_proxy_voting_should_work() { #[test] fn election_simple_tally_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(4); assert!(!Elections::presentation_active()); @@ -972,7 +971,7 @@ fn election_simple_tally_should_work() { #[test] fn election_seats_should_be_released() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); @@ -1006,7 +1005,7 @@ fn election_seats_should_be_released() { #[test] fn election_presentations_with_zero_staked_deposit_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); @@ -1022,7 +1021,7 @@ fn election_presentations_with_zero_staked_deposit_should_not_work() { #[test] fn election_double_presentations_should_be_punished() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert!(Balances::can_slash(&4, 10)); System::set_block_number(4); @@ -1045,7 +1044,7 @@ fn election_double_presentations_should_be_punished() { #[test] fn election_presenting_for_double_election_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(4); assert_eq!(Elections::submit_candidacy(Origin::signed(2), 0), Ok(())); assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); @@ -1072,7 +1071,7 @@ fn election_presenting_for_double_election_should_not_work() { #[test] fn election_presenting_loser_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0, 60)); @@ -1105,7 +1104,7 @@ fn election_presenting_loser_should_not_work() { #[test] fn election_presenting_loser_first_should_not_matter() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0, 60)); @@ -1137,7 +1136,7 @@ fn election_presenting_loser_first_should_not_matter() { #[test] fn election_present_outside_of_presentation_period_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(4); assert!(!Elections::presentation_active()); assert_noop!( @@ -1149,7 +1148,7 @@ fn election_present_outside_of_presentation_period_should_not_work() { #[test] fn election_present_with_invalid_vote_index_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); @@ -1165,33 +1164,35 @@ fn election_present_with_invalid_vote_index_should_not_work() { #[test] fn election_present_when_presenter_is_poor_should_not_work() { let test_present = |p| { - set_and_run_with_externalities(&mut ExtBuilder::default() + ExtBuilder::default() .voting_fee(5) .voter_bond(2) .bad_presentation_punishment(p) - .build(), - || { - System::set_block_number(4); - let _ = Balances::make_free_balance_be(&1, 15); - assert!(!Elections::presentation_active()); - - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); // -3 - assert_eq!(Balances::free_balance(&1), 12); - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 15)); // -2 -5 - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_eq!(Balances::free_balance(&1), 5); - assert_eq!(Balances::reserved_balance(&1), 5); - if p > 5 { - assert_noop!(Elections::present_winner( - Origin::signed(1), 1, 10, 0), - "presenter must have sufficient slashable funds" - ); - } else { - assert_ok!(Elections::present_winner(Origin::signed(1), 1, 10, 0)); - } - }); + .build() + .execute_with(|| { + System::set_block_number(4); + let _ = Balances::make_free_balance_be(&1, 15); + assert!(!Elections::presentation_active()); + + // -3 + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); + assert_eq!(Balances::free_balance(&1), 12); + // -2 -5 + assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 15)); + assert_ok!(Elections::end_block(System::block_number())); + + System::set_block_number(6); + assert_eq!(Balances::free_balance(&1), 5); + assert_eq!(Balances::reserved_balance(&1), 5); + if p > 5 { + assert_noop!(Elections::present_winner( + Origin::signed(1), 1, 10, 0), + "presenter must have sufficient slashable funds" + ); + } else { + assert_ok!(Elections::present_winner(Origin::signed(1), 1, 10, 0)); + } + }); }; test_present(4); test_present(6); @@ -1199,7 +1200,7 @@ fn election_present_when_presenter_is_poor_should_not_work() { #[test] fn election_invalid_present_tally_should_slash() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(4); assert!(!Elections::presentation_active()); assert_eq!(Balances::total_balance(&4), 40); @@ -1219,7 +1220,7 @@ fn election_invalid_present_tally_should_slash() { #[test] fn election_runners_up_should_be_kept() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(4); assert!(!Elections::presentation_active()); @@ -1280,7 +1281,7 @@ fn election_runners_up_should_be_kept() { #[test] fn election_second_tally_should_use_runners_up() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0, 60)); @@ -1335,7 +1336,7 @@ fn election_second_tally_should_use_runners_up() { #[test] fn election_loser_candidates_bond_gets_slashed() { - set_and_run_with_externalities(&mut ExtBuilder::default().desired_seats(1).build(), || { + ExtBuilder::default().desired_seats(1).build().execute_with(|| { System::set_block_number(4); assert!(!Elections::presentation_active()); @@ -1374,7 +1375,7 @@ fn election_loser_candidates_bond_gets_slashed() { #[test] fn pot_accumulating_weight_and_decaying_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().balance_factor(10).build(), || { + ExtBuilder::default().balance_factor(10).build().execute_with(|| { System::set_block_number(4); assert!(!Elections::presentation_active()); @@ -1502,7 +1503,7 @@ fn pot_accumulating_weight_and_decaying_should_work() { #[test] fn pot_winning_resets_accumulated_pot() { - set_and_run_with_externalities(&mut ExtBuilder::default().balance_factor(10).build(), || { + ExtBuilder::default().balance_factor(10).build().execute_with(|| { System::set_block_number(4); assert!(!Elections::presentation_active()); @@ -1564,72 +1565,88 @@ fn pot_winning_resets_accumulated_pot() { #[test] fn pot_resubmitting_approvals_stores_pot() { - set_and_run_with_externalities(&mut ExtBuilder::default() + ExtBuilder::default() .voter_bond(0) .voting_fee(0) .balance_factor(10) - .build(), - || { System::set_block_number(4); - assert!(!Elections::presentation_active()); + .build() + .execute_with(|| { + System::set_block_number(4); + assert!(!Elections::presentation_active()); - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 2)); + assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(1), 2)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 0, 0, 600)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 0, 1, 500)); - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![false, false, true], 0, 2, 100)); + assert_ok!( + Elections::set_approvals(Origin::signed(6), vec![true, false, false], 0, 0, 600), + ); + assert_ok!( + Elections::set_approvals(Origin::signed(5), vec![false, true, false], 0, 1, 500), + ); + assert_ok!( + Elections::set_approvals(Origin::signed(1), vec![false, false, true], 0, 2, 100), + ); - assert_ok!(Elections::end_block(System::block_number())); + assert_ok!(Elections::end_block(System::block_number())); - System::set_block_number(6); - assert!(Elections::presentation_active()); + System::set_block_number(6); + assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100, 0), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100, 1), (500, 5), (600, 6)])); - assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 0), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100, 0), Ok(())); + assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100, 1), (500, 5), (600, 6)])); + assert_ok!(Elections::end_block(System::block_number())); - assert_eq!(Elections::members(), vec![(6, 11), (5, 11)]); + assert_eq!(Elections::members(), vec![(6, 11), (5, 11)]); - System::set_block_number(12); - assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); - assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true, false, false], 1, 0, 600)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true, false], 1, 1, 500)); - // give 1 some new high balance - let _ = Balances::make_free_balance_be(&1, 997); - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![false, false, true], 1, 2, 1000)); - assert_eq!(Elections::voter_info(1).unwrap(), - VoterInfo { - stake: 1000, // 997 + 3 which is candidacy bond. - pot: Elections::get_offset(100, 1), - last_active: 1, - last_win: 1, - } - ); - assert_ok!(Elections::end_block(System::block_number())); + System::set_block_number(12); + assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); + assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); + assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); + assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); + assert_ok!( + Elections::set_approvals(Origin::signed(6), vec![true, false, false], 1, 0, 600), + ); + assert_ok!( + Elections::set_approvals(Origin::signed(5), vec![false, true, false], 1, 1, 500), + ); + // give 1 some new high balance + let _ = Balances::make_free_balance_be(&1, 997); + assert_ok!( + Elections::set_approvals(Origin::signed(1), vec![false, false, true], 1, 2, 1000), + ); + assert_eq!(Elections::voter_info(1).unwrap(), + VoterInfo { + stake: 1000, // 997 + 3 which is candidacy bond. + pot: Elections::get_offset(100, 1), + last_active: 1, + last_win: 1, + } + ); + assert_ok!(Elections::end_block(System::block_number())); - assert_eq!(Elections::members(), vec![(6, 11), (5, 11)]); + assert_eq!(Elections::members(), vec![(6, 11), (5, 11)]); - System::set_block_number(14); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 1), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 1), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(1), 1, 1000 + 96 /* pot */, 1), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (500, 5), (600, 6), (1096, 1)])); - assert_ok!(Elections::end_block(System::block_number())); + System::set_block_number(14); + assert!(Elections::presentation_active()); + assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 1), Ok(())); + assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 1), Ok(())); + assert_eq!( + Elections::present_winner(Origin::signed(1), 1, 1000 + 96 /* pot */, 1), + Ok(()), + ); + assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (500, 5), (600, 6), (1096, 1)])); + assert_ok!(Elections::end_block(System::block_number())); - assert_eq!(Elections::members(), vec![(1, 19), (6, 19)]); - }) + assert_eq!(Elections::members(), vec![(1, 19), (6, 19)]); + }) } #[test] fn pot_get_offset_should_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(Elections::get_offset(100, 0), 0); assert_eq!(Elections::get_offset(100, 1), 96); assert_eq!(Elections::get_offset(100, 2), 96 + 93); @@ -1653,7 +1670,7 @@ fn pot_get_offset_should_work() { #[test] fn pot_get_offset_with_zero_decay() { - set_and_run_with_externalities(&mut ExtBuilder::default().decay_ratio(0).build(), || { + ExtBuilder::default().decay_ratio(0).build().execute_with(|| { assert_eq!(Elections::get_offset(100, 0), 0); assert_eq!(Elections::get_offset(100, 1), 0); assert_eq!(Elections::get_offset(100, 2), 0); diff --git a/srml/example/src/lib.rs b/srml/example/src/lib.rs index 08adf9efa7..0766468efa 100644 --- a/srml/example/src/lib.rs +++ b/srml/example/src/lib.rs @@ -638,7 +638,7 @@ mod tests { // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sr_primitives::{ - set_and_run_with_externalities, Perbill, weights::GetDispatchInfo, testing::Header, + Perbill, weights::GetDispatchInfo, testing::Header, traits::{BlakeTwo256, OnInitialize, OnFinalize, IdentityLookup}, }; @@ -719,7 +719,7 @@ mod tests { #[test] fn it_works_for_optional_value() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // Check that GenesisBuilder works properly. assert_eq!(Example::dummy(), Some(42)); @@ -740,7 +740,7 @@ mod tests { #[test] fn it_works_for_default_value() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(Example::foo(), 24); assert_ok!(Example::accumulate_foo(Origin::signed(1), 1)); assert_eq!(Example::foo(), 25); @@ -749,7 +749,7 @@ mod tests { #[test] fn signed_ext_watch_dummy_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let call = >::set_dummy(10); let info = DispatchInfo::default(); diff --git a/srml/executive/src/lib.rs b/srml/executive/src/lib.rs index f1509f1760..23c645f6ef 100644 --- a/srml/executive/src/lib.rs +++ b/srml/executive/src/lib.rs @@ -298,7 +298,6 @@ mod tests { generic::Era, Perbill, DispatchError, weights::Weight, testing::{Digest, Header, Block}, traits::{Bounded, Header as HeaderT, BlakeTwo256, IdentityLookup, ConvertInto}, transaction_validity::{InvalidTransaction, UnknownTransaction}, ApplyError, - set_and_run_with_externalities, }; use support::{ impl_outer_event, impl_outer_origin, parameter_types, impl_outer_dispatch, @@ -420,7 +419,7 @@ mod tests { let xt = sr_primitives::testing::TestXt(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(2, 69))); let weight = xt.get_dispatch_info().weight as u64; let mut t = runtime_io::TestExternalities::new(t); - set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { Executive::initialize_block(&Header::new( 1, H256::default(), @@ -446,7 +445,7 @@ mod tests { #[test] fn block_import_works() { - set_and_run_with_externalities(&mut new_test_ext(1), || { + new_test_ext(1).execute_with(|| { Executive::execute_block(Block { header: Header { parent_hash: [69u8; 32].into(), @@ -463,7 +462,7 @@ mod tests { #[test] #[should_panic] fn block_import_of_bad_state_root_fails() { - set_and_run_with_externalities(&mut new_test_ext(1), || { + new_test_ext(1).execute_with(|| { Executive::execute_block(Block { header: Header { parent_hash: [69u8; 32].into(), @@ -480,7 +479,7 @@ mod tests { #[test] #[should_panic] fn block_import_of_bad_extrinsic_root_fails() { - set_and_run_with_externalities(&mut new_test_ext(1), || { + new_test_ext(1).execute_with(|| { Executive::execute_block(Block { header: Header { parent_hash: [69u8; 32].into(), @@ -499,7 +498,7 @@ mod tests { let mut t = new_test_ext(1); // bad nonce check! let xt = sr_primitives::testing::TestXt(sign_extra(1, 30, 0), Call::Balances(BalancesCall::transfer(33, 69))); - set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { Executive::initialize_block(&Header::new( 1, H256::default(), @@ -521,7 +520,7 @@ mod tests { let encoded_len = encoded.len() as Weight; let limit = AvailableBlockRatio::get() * MaximumBlockWeight::get(); let num_to_exhaust_block = limit / encoded_len; - set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { Executive::initialize_block(&Header::new( 1, H256::default(), @@ -557,7 +556,7 @@ mod tests { let x2 = sr_primitives::testing::TestXt(sign_extra(1, 2, 0), Call::Balances(BalancesCall::transfer(33, 0))); let len = xt.clone().encode().len() as u32; let mut t = new_test_ext(1); - set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { assert_eq!(>::all_extrinsics_weight(), 0); assert_eq!(>::all_extrinsics_weight(), 0); @@ -581,7 +580,7 @@ mod tests { let xt = sr_primitives::testing::TestXt(None, Call::Balances(BalancesCall::set_balance(33, 69, 69))); let mut t = new_test_ext(1); - set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { assert_eq!(Executive::validate_transaction(xt.clone()), Ok(Default::default())); assert_eq!( Executive::apply_extrinsic(xt), @@ -599,7 +598,7 @@ mod tests { let id: LockIdentifier = *b"0 "; let execute_with_lock = |lock: WithdrawReasons| { let mut t = new_test_ext(1); - set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { as LockableCurrency>::set_lock( id, &1, diff --git a/srml/finality-tracker/src/lib.rs b/srml/finality-tracker/src/lib.rs index f00762fcdf..ba893c42d0 100644 --- a/srml/finality-tracker/src/lib.rs +++ b/srml/finality-tracker/src/lib.rs @@ -250,7 +250,7 @@ mod tests { use runtime_io::TestExternalities; use primitives::H256; use sr_primitives::{ - set_and_run_with_externalities, testing::Header, Perbill, + testing::Header, Perbill, traits::{BlakeTwo256, IdentityLookup, OnFinalize, Header as HeaderT}, }; use support::{assert_ok, impl_outer_origin, parameter_types}; @@ -322,7 +322,7 @@ mod tests { #[test] fn median_works() { let t = system::GenesisConfig::default().build_storage::().unwrap(); - set_and_run_with_externalities(&mut TestExternalities::new(t), || { + TestExternalities::new(t).execute_with(|| { FinalityTracker::update_hint(Some(500)); assert_eq!(FinalityTracker::median(), 250); assert!(NOTIFICATIONS.with(|n| n.borrow().is_empty())); @@ -332,7 +332,7 @@ mod tests { #[test] fn notifies_when_stalled() { let t = system::GenesisConfig::default().build_storage::().unwrap(); - set_and_run_with_externalities(&mut TestExternalities::new(t), || { + TestExternalities::new(t).execute_with(|| { let mut parent_hash = System::parent_hash(); for i in 2..106 { System::initialize(&i, &parent_hash, &Default::default(), &Default::default()); @@ -351,7 +351,7 @@ mod tests { #[test] fn recent_notifications_prevent_stalling() { let t = system::GenesisConfig::default().build_storage::().unwrap(); - set_and_run_with_externalities(&mut TestExternalities::new(t), || { + TestExternalities::new(t).execute_with(|| { let mut parent_hash = System::parent_hash(); for i in 2..106 { System::initialize(&i, &parent_hash, &Default::default(), &Default::default()); diff --git a/srml/generic-asset/src/tests.rs b/srml/generic-asset/src/tests.rs index 90e5775828..165936d021 100644 --- a/srml/generic-asset/src/tests.rs +++ b/srml/generic-asset/src/tests.rs @@ -22,14 +22,13 @@ use super::*; use crate::mock::{new_test_ext, ExtBuilder, GenericAsset, Origin, System, Test, TestEvent}; -use sr_primitives::set_and_run_with_externalities; use support::{assert_noop, assert_ok}; #[test] fn issuing_asset_units_to_issuer_should_work() { let balance = 100; - set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((16000, 1, 100)).build(), || { + ExtBuilder::default().free_balance((16000, 1, 100)).build().execute_with(|| { let default_permission = PermissionLatest { update: Owner::Address(1), mint: Owner::Address(1), @@ -51,61 +50,55 @@ fn issuing_asset_units_to_issuer_should_work() { #[test] fn issuing_with_next_asset_id_overflow_should_not_work() { - set_and_run_with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - NextAssetId::::put(u32::max_value()); - let default_permission = PermissionLatest { - update: Owner::Address(1), - mint: Owner::Address(1), - burn: Owner::Address(1), - }; - assert_noop!( - GenericAsset::create( - Origin::signed(1), - AssetOptions { - initial_issuance: 1, - permissions: default_permission - } - ), - "No new assets id available." - ); - assert_eq!(GenericAsset::next_asset_id(), u32::max_value()); - }, - ); + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + NextAssetId::::put(u32::max_value()); + let default_permission = PermissionLatest { + update: Owner::Address(1), + mint: Owner::Address(1), + burn: Owner::Address(1), + }; + assert_noop!( + GenericAsset::create( + Origin::signed(1), + AssetOptions { + initial_issuance: 1, + permissions: default_permission + } + ), + "No new assets id available." + ); + assert_eq!(GenericAsset::next_asset_id(), u32::max_value()); + }); } #[test] fn querying_total_supply_should_work() { let asset_id = 1000; - set_and_run_with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let default_permission = PermissionLatest { - update: Owner::Address(1), - mint: Owner::Address(1), - burn: Owner::Address(1), - }; - assert_ok!(GenericAsset::create( - Origin::signed(1), - AssetOptions { - initial_issuance: 100, - permissions: default_permission - } - )); - assert_eq!(GenericAsset::free_balance(&asset_id, &1), 100); - assert_ok!(GenericAsset::transfer(Origin::signed(1), asset_id, 2, 50)); - assert_eq!(GenericAsset::free_balance(&asset_id, &1), 50); - assert_eq!(GenericAsset::free_balance(&asset_id, &2), 50); - assert_ok!(GenericAsset::transfer(Origin::signed(2), asset_id, 3, 31)); - assert_eq!(GenericAsset::free_balance(&asset_id, &1), 50); - assert_eq!(GenericAsset::free_balance(&asset_id, &2), 19); - assert_eq!(GenericAsset::free_balance(&asset_id, &3), 31); - assert_ok!(GenericAsset::transfer(Origin::signed(1), asset_id, 1, 1)); - assert_eq!(GenericAsset::free_balance(&asset_id, &1), 50); - }, - ); + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let default_permission = PermissionLatest { + update: Owner::Address(1), + mint: Owner::Address(1), + burn: Owner::Address(1), + }; + assert_ok!(GenericAsset::create( + Origin::signed(1), + AssetOptions { + initial_issuance: 100, + permissions: default_permission + } + )); + assert_eq!(GenericAsset::free_balance(&asset_id, &1), 100); + assert_ok!(GenericAsset::transfer(Origin::signed(1), asset_id, 2, 50)); + assert_eq!(GenericAsset::free_balance(&asset_id, &1), 50); + assert_eq!(GenericAsset::free_balance(&asset_id, &2), 50); + assert_ok!(GenericAsset::transfer(Origin::signed(2), asset_id, 3, 31)); + assert_eq!(GenericAsset::free_balance(&asset_id, &1), 50); + assert_eq!(GenericAsset::free_balance(&asset_id, &2), 19); + assert_eq!(GenericAsset::free_balance(&asset_id, &3), 31); + assert_ok!(GenericAsset::transfer(Origin::signed(1), asset_id, 1, 1)); + assert_eq!(GenericAsset::free_balance(&asset_id, &1), 50); + }); } // Given @@ -127,27 +120,24 @@ fn querying_total_supply_should_work() { fn transferring_amount_should_work() { let asset_id = 1000; let free_balance = 100; - set_and_run_with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let default_permission = PermissionLatest { - update: Owner::Address(1), - mint: Owner::Address(1), - burn: Owner::Address(1), - }; - assert_ok!(GenericAsset::create( - Origin::signed(1), - AssetOptions { - initial_issuance: free_balance, - permissions: default_permission - } - )); - assert_eq!(GenericAsset::free_balance(&asset_id, &1), free_balance); - assert_ok!(GenericAsset::transfer(Origin::signed(1), asset_id, 2, 40)); - assert_eq!(GenericAsset::free_balance(&asset_id, &1), 60); - assert_eq!(GenericAsset::free_balance(&asset_id, &2), 40); - }, - ); + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let default_permission = PermissionLatest { + update: Owner::Address(1), + mint: Owner::Address(1), + burn: Owner::Address(1), + }; + assert_ok!(GenericAsset::create( + Origin::signed(1), + AssetOptions { + initial_issuance: free_balance, + permissions: default_permission + } + )); + assert_eq!(GenericAsset::free_balance(&asset_id, &1), free_balance); + assert_ok!(GenericAsset::transfer(Origin::signed(1), asset_id, 2, 40)); + assert_eq!(GenericAsset::free_balance(&asset_id, &1), 60); + assert_eq!(GenericAsset::free_balance(&asset_id, &2), 40); + }); } // Given @@ -168,55 +158,49 @@ fn transferring_amount_should_work() { #[test] fn transferring_amount_should_fail_when_transferring_more_than_free_balance() { let asset_id = 1000; - set_and_run_with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let default_permission = PermissionLatest { - update: Owner::Address(1), - mint: Owner::Address(1), - burn: Owner::Address(1), - }; - assert_ok!(GenericAsset::create( - Origin::signed(1), - AssetOptions { - initial_issuance: 100, - permissions: default_permission - } - )); - assert_noop!( - GenericAsset::transfer(Origin::signed(1), asset_id, 2, 2000), - "balance too low to send amount" - ); - }, - ); + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let default_permission = PermissionLatest { + update: Owner::Address(1), + mint: Owner::Address(1), + burn: Owner::Address(1), + }; + assert_ok!(GenericAsset::create( + Origin::signed(1), + AssetOptions { + initial_issuance: 100, + permissions: default_permission + } + )); + assert_noop!( + GenericAsset::transfer(Origin::signed(1), asset_id, 2, 2000), + "balance too low to send amount" + ); + }); } #[test] fn transferring_less_than_one_unit_should_not_work() { let asset_id = 1000; - set_and_run_with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let default_permission = PermissionLatest { - update: Owner::Address(1), - mint: Owner::Address(1), - burn: Owner::Address(1), - }; - assert_ok!(GenericAsset::create( - Origin::signed(1), - AssetOptions { - initial_issuance: 100, - permissions: default_permission - } - )); - assert_eq!(GenericAsset::free_balance(&asset_id, &1), 100); - assert_noop!( - GenericAsset::transfer(Origin::signed(1), asset_id, 2, 0), - "cannot transfer zero amount" - ); - }, - ); + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let default_permission = PermissionLatest { + update: Owner::Address(1), + mint: Owner::Address(1), + burn: Owner::Address(1), + }; + assert_ok!(GenericAsset::create( + Origin::signed(1), + AssetOptions { + initial_issuance: 100, + permissions: default_permission + } + )); + assert_eq!(GenericAsset::free_balance(&asset_id, &1), 100); + assert_noop!( + GenericAsset::transfer(Origin::signed(1), asset_id, 2, 0), + "cannot transfer zero amount" + ); + }); } // Given @@ -233,60 +217,54 @@ fn self_transfer_should_fail() { let asset_id = 1000; let balance = 100; - set_and_run_with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let default_permission = PermissionLatest { - update: Owner::Address(1), - mint: Owner::Address(1), - burn: Owner::Address(1), - }; - assert_ok!(GenericAsset::create( - Origin::signed(1), - AssetOptions { - initial_issuance: balance, - permissions: default_permission - } - )); + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let default_permission = PermissionLatest { + update: Owner::Address(1), + mint: Owner::Address(1), + burn: Owner::Address(1), + }; + assert_ok!(GenericAsset::create( + Origin::signed(1), + AssetOptions { + initial_issuance: balance, + permissions: default_permission + } + )); - let initial_free_balance = GenericAsset::free_balance(&asset_id, &1); - assert_ok!(GenericAsset::transfer(Origin::signed(1), asset_id, 1, 10)); - assert_eq!(GenericAsset::free_balance(&asset_id, &1), initial_free_balance); - }, - ); + let initial_free_balance = GenericAsset::free_balance(&asset_id, &1); + assert_ok!(GenericAsset::transfer(Origin::signed(1), asset_id, 1, 10)); + assert_eq!(GenericAsset::free_balance(&asset_id, &1), initial_free_balance); + }); } #[test] fn transferring_more_units_than_total_supply_should_not_work() { let asset_id = 1000; - set_and_run_with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let default_permission = PermissionLatest { - update: Owner::Address(1), - mint: Owner::Address(1), - burn: Owner::Address(1), - }; - assert_ok!(GenericAsset::create( - Origin::signed(1), - AssetOptions { - initial_issuance: 100, - permissions: default_permission - } - )); - assert_eq!(GenericAsset::free_balance(&asset_id, &1), 100); - assert_noop!( - GenericAsset::transfer(Origin::signed(1), asset_id, 2, 101), - "balance too low to send amount" - ); - }, - ); + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let default_permission = PermissionLatest { + update: Owner::Address(1), + mint: Owner::Address(1), + burn: Owner::Address(1), + }; + assert_ok!(GenericAsset::create( + Origin::signed(1), + AssetOptions { + initial_issuance: 100, + permissions: default_permission + } + )); + assert_eq!(GenericAsset::free_balance(&asset_id, &1), 100); + assert_noop!( + GenericAsset::transfer(Origin::signed(1), asset_id, 2, 101), + "balance too low to send amount" + ); + }); } // Ensures it uses fake money for staking asset id. #[test] fn staking_asset_id_should_return_0() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(GenericAsset::staking_asset_id(), 16000); }); } @@ -294,7 +272,7 @@ fn staking_asset_id_should_return_0() { // Ensures it uses fake money for spending asset id. #[test] fn spending_asset_id_should_return_10() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(GenericAsset::spending_asset_id(), 16001); }); } @@ -305,7 +283,7 @@ fn spending_asset_id_should_return_10() { // -Â total_balance should return 0 #[test] fn total_balance_should_be_zero() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(GenericAsset::total_balance(&0, &0), 0); }); } @@ -323,19 +301,16 @@ fn total_balance_should_be_equal_to_account_balance() { mint: Owner::Address(1), burn: Owner::Address(1), }; - set_and_run_with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - assert_ok!(GenericAsset::create( - Origin::signed(1), - AssetOptions { - initial_issuance: 100, - permissions: default_permission - } - )); - assert_eq!(GenericAsset::total_balance(&1000, &1), 100); - }, - ); + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + assert_ok!(GenericAsset::create( + Origin::signed(1), + AssetOptions { + initial_issuance: 100, + permissions: default_permission + } + )); + assert_eq!(GenericAsset::total_balance(&1000, &1), 100); + }); } // Given @@ -348,7 +323,7 @@ fn total_balance_should_be_equal_to_account_balance() { // -Â free_balance should return 50. #[test] fn free_balance_should_only_return_account_free_balance() { - set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 50)).build(), || { + ExtBuilder::default().free_balance((1, 0, 50)).build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 70); assert_eq!(GenericAsset::free_balance(&1, &0), 50); }); @@ -363,7 +338,7 @@ fn free_balance_should_only_return_account_free_balance() { // -Â total_balance should equals to account balance + free balance. #[test] fn total_balance_should_be_equal_to_sum_of_account_balance_and_free_balance() { - set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 50)).build(), || { + ExtBuilder::default().free_balance((1, 0, 50)).build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 70); assert_eq!(GenericAsset::total_balance(&1, &0), 120); }); @@ -378,7 +353,7 @@ fn total_balance_should_be_equal_to_sum_of_account_balance_and_free_balance() { // - reserved_balance should return 70. #[test] fn reserved_balance_should_only_return_account_reserved_balance() { - set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 50)).build(), || { + ExtBuilder::default().free_balance((1, 0, 50)).build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 70); assert_eq!(GenericAsset::reserved_balance(&1, &0), 70); }); @@ -394,7 +369,7 @@ fn reserved_balance_should_only_return_account_reserved_balance() { // - reserved_balance = amount #[test] fn set_reserved_balance_should_add_balance_as_reserved() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 50); assert_eq!(GenericAsset::reserved_balance(&1, &0), 50); }); @@ -410,7 +385,7 @@ fn set_reserved_balance_should_add_balance_as_reserved() { // - New free_balance should replace older free_balance. #[test] fn set_free_balance_should_add_amount_as_free_balance() { - set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + ExtBuilder::default().free_balance((1, 0, 100)).build().execute_with(|| { GenericAsset::set_free_balance(&1, &0, 50); assert_eq!(GenericAsset::free_balance(&1, &0), 50); }); @@ -429,7 +404,7 @@ fn set_free_balance_should_add_amount_as_free_balance() { // - new reserved_balance = original free balance + reserved amount #[test] fn reserve_should_moves_amount_from_balance_to_reserved_balance() { - set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + ExtBuilder::default().free_balance((1, 0, 100)).build().execute_with(|| { assert_ok!(GenericAsset::reserve(&1, &0, 70)); assert_eq!(GenericAsset::free_balance(&1, &0), 30); assert_eq!(GenericAsset::reserved_balance(&1, &0), 70); @@ -448,7 +423,7 @@ fn reserve_should_moves_amount_from_balance_to_reserved_balance() { // - Should throw an error. #[test] fn reserve_should_not_moves_amount_from_balance_to_reserved_balance() { - set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + ExtBuilder::default().free_balance((1, 0, 100)).build().execute_with(|| { assert_noop!(GenericAsset::reserve(&1, &0, 120), "not enough free funds"); assert_eq!(GenericAsset::free_balance(&1, &0), 100); assert_eq!(GenericAsset::reserved_balance(&1, &0), 0); @@ -466,7 +441,7 @@ fn reserve_should_not_moves_amount_from_balance_to_reserved_balance() { // - unreserved should return 20. #[test] fn unreserve_should_return_substratced_value_from_unreserved_amount_by_actual_acount_balance() { - set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + ExtBuilder::default().free_balance((1, 0, 100)).build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::unreserve(&1, &0, 120), 20); }); @@ -483,7 +458,7 @@ fn unreserve_should_return_substratced_value_from_unreserved_amount_by_actual_ac // - unreserved should return None. #[test] fn unreserve_should_return_none() { - set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + ExtBuilder::default().free_balance((1, 0, 100)).build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::unreserve(&1, &0, 50), 0); }); @@ -500,7 +475,7 @@ fn unreserve_should_return_none() { // - free_balance should be 200. #[test] fn unreserve_should_increase_free_balance_by_reserved_balance() { - set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + ExtBuilder::default().free_balance((1, 0, 100)).build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 100); GenericAsset::unreserve(&1, &0, 120); assert_eq!(GenericAsset::free_balance(&1, &0), 200); @@ -518,7 +493,7 @@ fn unreserve_should_increase_free_balance_by_reserved_balance() { // - reserved_balance should be 0. #[test] fn unreserve_should_deduct_reserved_balance_by_reserved_amount() { - set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + ExtBuilder::default().free_balance((1, 0, 100)).build().execute_with(|| { GenericAsset::set_free_balance(&1, &0, 100); GenericAsset::unreserve(&1, &0, 120); assert_eq!(GenericAsset::reserved_balance(&1, &0), 0); @@ -536,7 +511,7 @@ fn unreserve_should_deduct_reserved_balance_by_reserved_amount() { // - slash should return None. #[test] fn slash_should_return_slash_reserved_amount() { - set_and_run_with_externalities(&mut ExtBuilder::default().free_balance((1, 0, 100)).build(), || { + ExtBuilder::default().free_balance((1, 0, 100)).build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::slash(&1, &0, 70), None); }); @@ -550,7 +525,7 @@ fn slash_should_return_slash_reserved_amount() { // - Should return slashed_reserved - reserved_balance. #[test] fn slash_reserved_should_deducts_up_to_amount_from_reserved_balance() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::slash_reserved(&1, &0, 150), Some(50)); }); @@ -564,7 +539,7 @@ fn slash_reserved_should_deducts_up_to_amount_from_reserved_balance() { // - Should return None. #[test] fn slash_reserved_should_return_none() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::slash_reserved(&1, &0, 100), None); }); @@ -579,7 +554,7 @@ fn slash_reserved_should_return_none() { // - Should not return None. #[test] fn repatriate_reserved_return_amount_substracted_by_slash_amount() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::repatriate_reserved(&1, &0, &1, 130), 30); }); @@ -594,7 +569,7 @@ fn repatriate_reserved_return_amount_substracted_by_slash_amount() { // - Should return None. #[test] fn repatriate_reserved_return_none() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::repatriate_reserved(&1, &0, &1, 90), 0); }); @@ -608,7 +583,7 @@ fn repatriate_reserved_return_none() { // - Should create a new reserved asset. #[test] fn create_reserved_should_create_a_default_account_with_the_balance_given() { - set_and_run_with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { + ExtBuilder::default().next_asset_id(10).build().execute_with(|| { let default_permission = PermissionLatest { update: Owner::Address(1), mint: Owner::Address(1), @@ -643,7 +618,7 @@ fn create_reserved_should_create_a_default_account_with_the_balance_given() { // - Should throw a permission error #[test] fn mint_should_throw_permission_error() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { let origin = 1; let asset_id = 4; let to_account = 2; @@ -666,36 +641,33 @@ fn mint_should_throw_permission_error() { // - Should not change `origins` free_balance. #[test] fn mint_should_increase_asset() { - set_and_run_with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let origin = 1; - let asset_id = 1000; - let to_account = 2; - let amount = 500; - let initial_issuance = 100; - - let default_permission = PermissionLatest { - update: Owner::Address(origin), - mint: Owner::Address(origin), - burn: Owner::Address(origin), - }; + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let origin = 1; + let asset_id = 1000; + let to_account = 2; + let amount = 500; + let initial_issuance = 100; - assert_ok!(GenericAsset::create( - Origin::signed(origin), - AssetOptions { - initial_issuance: initial_issuance, - permissions: default_permission - } - )); + let default_permission = PermissionLatest { + update: Owner::Address(origin), + mint: Owner::Address(origin), + burn: Owner::Address(origin), + }; - assert_ok!(GenericAsset::mint(Origin::signed(origin), asset_id, to_account, amount)); - assert_eq!(GenericAsset::free_balance(&asset_id, &to_account), amount); + assert_ok!(GenericAsset::create( + Origin::signed(origin), + AssetOptions { + initial_issuance: initial_issuance, + permissions: default_permission + } + )); - // Origin's free_balance should not change. - assert_eq!(GenericAsset::free_balance(&asset_id, &origin), initial_issuance); - }, - ); + assert_ok!(GenericAsset::mint(Origin::signed(origin), asset_id, to_account, amount)); + assert_eq!(GenericAsset::free_balance(&asset_id, &to_account), amount); + + // Origin's free_balance should not change. + assert_eq!(GenericAsset::free_balance(&asset_id, &origin), initial_issuance); + }); } // Given @@ -707,20 +679,17 @@ fn mint_should_increase_asset() { // - Should throw a permission error. #[test] fn burn_should_throw_permission_error() { - set_and_run_with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let origin = 1; - let asset_id = 4; - let to_account = 2; - let amount = 10; - - assert_noop!( - GenericAsset::burn(Origin::signed(origin), asset_id, to_account, amount), - "The origin does not have permission to burn an asset." - ); - }, - ); + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let origin = 1; + let asset_id = 4; + let to_account = 2; + let amount = 10; + + assert_noop!( + GenericAsset::burn(Origin::signed(origin), asset_id, to_account, amount), + "The origin does not have permission to burn an asset." + ); + }); } // Given @@ -733,41 +702,38 @@ fn burn_should_throw_permission_error() { // - Should not change `origin`'s free_balance. #[test] fn burn_should_burn_an_asset() { - set_and_run_with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let origin = 1; - let asset_id = 1000; - let to_account = 2; - let amount = 1000; - let initial_issuance = 100; - let burn_amount = 400; - let expected_amount = 600; - - let default_permission = PermissionLatest { - update: Owner::Address(origin), - mint: Owner::Address(origin), - burn: Owner::Address(origin), - }; + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let origin = 1; + let asset_id = 1000; + let to_account = 2; + let amount = 1000; + let initial_issuance = 100; + let burn_amount = 400; + let expected_amount = 600; - assert_ok!(GenericAsset::create( - Origin::signed(origin), - AssetOptions { - initial_issuance: initial_issuance, - permissions: default_permission - } - )); - assert_ok!(GenericAsset::mint(Origin::signed(origin), asset_id, to_account, amount)); + let default_permission = PermissionLatest { + update: Owner::Address(origin), + mint: Owner::Address(origin), + burn: Owner::Address(origin), + }; - assert_ok!(GenericAsset::burn( - Origin::signed(origin), - asset_id, - to_account, - burn_amount - )); - assert_eq!(GenericAsset::free_balance(&asset_id, &to_account), expected_amount); - }, - ); + assert_ok!(GenericAsset::create( + Origin::signed(origin), + AssetOptions { + initial_issuance: initial_issuance, + permissions: default_permission + } + )); + assert_ok!(GenericAsset::mint(Origin::signed(origin), asset_id, to_account, amount)); + + assert_ok!(GenericAsset::burn( + Origin::signed(origin), + asset_id, + to_account, + burn_amount + )); + assert_eq!(GenericAsset::free_balance(&asset_id, &to_account), expected_amount); + }); } // Given @@ -779,41 +745,29 @@ fn burn_should_burn_an_asset() { // - The account origin should have burn, mint and update permissions. #[test] fn check_permission_should_return_correct_permission() { - set_and_run_with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let origin = 1; - let asset_id = 1000; - let initial_issuance = 100; - - let default_permission = PermissionLatest { - update: Owner::Address(origin), - mint: Owner::Address(origin), - burn: Owner::Address(origin), - }; + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let origin = 1; + let asset_id = 1000; + let initial_issuance = 100; - assert_ok!(GenericAsset::create( - Origin::signed(origin), - AssetOptions { - initial_issuance: initial_issuance, - permissions: default_permission - } - )); + let default_permission = PermissionLatest { + update: Owner::Address(origin), + mint: Owner::Address(origin), + burn: Owner::Address(origin), + }; - assert_eq!( - GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Burn), - true - ); - assert_eq!( - GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Mint), - true - ); - assert_eq!( - GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Update), - true - ); - }, - ); + assert_ok!(GenericAsset::create( + Origin::signed(origin), + AssetOptions { + initial_issuance: initial_issuance, + permissions: default_permission + }, + )); + + assert!(GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Burn)); + assert!(GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Mint)); + assert!(GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Update)); + }); } // Given @@ -825,41 +779,29 @@ fn check_permission_should_return_correct_permission() { // - The account origin should not have burn, mint and update permissions. #[test] fn check_permission_should_return_false_for_no_permission() { - set_and_run_with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let origin = 1; - let asset_id = 1000; - let initial_issuance = 100; - - let default_permission = PermissionLatest { - update: Owner::None, - mint: Owner::None, - burn: Owner::None, - }; + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let origin = 1; + let asset_id = 1000; + let initial_issuance = 100; - assert_ok!(GenericAsset::create( - Origin::signed(origin), - AssetOptions { - initial_issuance: initial_issuance, - permissions: default_permission - } - )); + let default_permission = PermissionLatest { + update: Owner::None, + mint: Owner::None, + burn: Owner::None, + }; - assert_eq!( - GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Burn), - false - ); - assert_eq!( - GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Mint), - false - ); - assert_eq!( - GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Update), - false - ); - }, - ); + assert_ok!(GenericAsset::create( + Origin::signed(origin), + AssetOptions { + initial_issuance: initial_issuance, + permissions: default_permission + } + )); + + assert!(!GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Burn)); + assert!(!GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Mint)); + assert!(!GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Update)); + }); } // Given @@ -871,48 +813,39 @@ fn check_permission_should_return_false_for_no_permission() { // - The account origin should have update and mint permissions. #[test] fn update_permission_should_change_permission() { - set_and_run_with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let origin = 1; - let asset_id = 1000; - let initial_issuance = 100; - - let default_permission = PermissionLatest { - update: Owner::Address(origin), - mint: Owner::None, - burn: Owner::None, - }; - - let new_permission = PermissionLatest { - update: Owner::Address(origin), - mint: Owner::Address(origin), - burn: Owner::None, - }; + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let origin = 1; + let asset_id = 1000; + let initial_issuance = 100; - assert_ok!(GenericAsset::create( - Origin::signed(origin), - AssetOptions { - initial_issuance: initial_issuance, - permissions: default_permission - } - )); + let default_permission = PermissionLatest { + update: Owner::Address(origin), + mint: Owner::None, + burn: Owner::None, + }; - assert_ok!(GenericAsset::update_permission( - Origin::signed(origin), - asset_id, - new_permission - )); - assert_eq!( - GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Mint), - true - ); - assert_eq!( - GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Burn), - false - ); - }, - ); + let new_permission = PermissionLatest { + update: Owner::Address(origin), + mint: Owner::Address(origin), + burn: Owner::None, + }; + + assert_ok!(GenericAsset::create( + Origin::signed(origin), + AssetOptions { + initial_issuance: initial_issuance, + permissions: default_permission + } + )); + + assert_ok!(GenericAsset::update_permission( + Origin::signed(origin), + asset_id, + new_permission, + )); + assert!(GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Mint)); + assert!(!GenericAsset::check_permission(&asset_id, &origin, &PermissionType::Burn)); + }); } // Given @@ -923,41 +856,38 @@ fn update_permission_should_change_permission() { // - Should throw an error stating "Origin does not have enough permission to update permissions." #[test] fn update_permission_should_throw_error_when_lack_of_permissions() { - set_and_run_with_externalities( - &mut ExtBuilder::default().free_balance((16000, 1, 100000)).build(), - || { - let origin = 1; - let asset_id = 1000; - let initial_issuance = 100; - - let default_permission = PermissionLatest { - update: Owner::None, - mint: Owner::None, - burn: Owner::None, - }; - - let new_permission = PermissionLatest { - update: Owner::Address(origin), - mint: Owner::Address(origin), - burn: Owner::None, - }; - - let expected_error_message = "Origin does not have enough permission to update permissions."; + ExtBuilder::default().free_balance((16000, 1, 100000)).build().execute_with(|| { + let origin = 1; + let asset_id = 1000; + let initial_issuance = 100; - assert_ok!(GenericAsset::create( - Origin::signed(origin), - AssetOptions { - initial_issuance: initial_issuance, - permissions: default_permission - } - )); + let default_permission = PermissionLatest { + update: Owner::None, + mint: Owner::None, + burn: Owner::None, + }; - assert_noop!( - GenericAsset::update_permission(Origin::signed(origin), asset_id, new_permission), - expected_error_message - ); - }, - ); + let new_permission = PermissionLatest { + update: Owner::Address(origin), + mint: Owner::Address(origin), + burn: Owner::None, + }; + + let expected_error_message = "Origin does not have enough permission to update permissions."; + + assert_ok!(GenericAsset::create( + Origin::signed(origin), + AssetOptions { + initial_issuance: initial_issuance, + permissions: default_permission + }, + )); + + assert_noop!( + GenericAsset::update_permission(Origin::signed(origin), asset_id, new_permission), + expected_error_message, + ); + }); } // Given @@ -974,7 +904,7 @@ fn update_permission_should_throw_error_when_lack_of_permissions() { // - Permissions must have burn, mint and updatePermission for the given asset_id. #[test] fn create_asset_works_with_given_asset_id_and_from_account() { - set_and_run_with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { + ExtBuilder::default().next_asset_id(10).build().execute_with(|| { let origin = 1; let from_account: Option<::AccountId> = Some(1); @@ -1011,7 +941,7 @@ fn create_asset_works_with_given_asset_id_and_from_account() { // - `create_asset` should not work. #[test] fn create_asset_with_non_reserved_asset_id_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { + ExtBuilder::default().next_asset_id(10).build().execute_with(|| { let origin = 1; let from_account: Option<::AccountId> = Some(1); @@ -1045,7 +975,7 @@ fn create_asset_with_non_reserved_asset_id_should_not_work() { // - `create_asset` should not work. #[test] fn create_asset_with_a_taken_asset_id_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { + ExtBuilder::default().next_asset_id(10).build().execute_with(|| { let origin = 1; let from_account: Option<::AccountId> = Some(1); @@ -1090,7 +1020,7 @@ fn create_asset_with_a_taken_asset_id_should_not_work() { // - Should create a reserved token. #[test] fn create_asset_should_create_a_reserved_asset_when_from_account_is_none() { - set_and_run_with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { + ExtBuilder::default().next_asset_id(10).build().execute_with(|| { let origin = 1; let from_account: Option<::AccountId> = None; @@ -1133,7 +1063,7 @@ fn create_asset_should_create_a_reserved_asset_when_from_account_is_none() { // - Should not create a `reserved_asset`. #[test] fn create_asset_should_create_a_user_asset() { - set_and_run_with_externalities(&mut ExtBuilder::default().next_asset_id(10).build(), || { + ExtBuilder::default().next_asset_id(10).build().execute_with(|| { let origin = 1; let from_account: Option<::AccountId> = None; @@ -1180,12 +1110,11 @@ fn update_permission_should_raise_event() { burn: Owner::Address(origin), }; - set_and_run_with_externalities( - &mut ExtBuilder::default() - .next_asset_id(asset_id) - .free_balance((staking_asset_id, origin, initial_balance)) - .build(), - || { + ExtBuilder::default() + .next_asset_id(asset_id) + .free_balance((staking_asset_id, origin, initial_balance)) + .build() + .execute_with(|| { assert_ok!(GenericAsset::create( Origin::signed(origin), AssetOptions { @@ -1201,9 +1130,11 @@ fn update_permission_should_raise_event() { permissions.clone() )); + let expected_event = TestEvent::generic_asset( + RawEvent::PermissionUpdated(asset_id, permissions.clone()), + ); // Assert - assert!(System::events().iter().any(|record| record.event - == TestEvent::generic_asset(RawEvent::PermissionUpdated(asset_id, permissions.clone())))); + assert!(System::events().iter().any(|record| record.event == expected_event)); }, ); } @@ -1223,27 +1154,26 @@ fn mint_should_raise_event() { let to = 2; let amount = 100; - set_and_run_with_externalities( - &mut ExtBuilder::default() - .next_asset_id(asset_id) - .free_balance((staking_asset_id, origin, initial_balance)) - .build(), - || { + ExtBuilder::default() + .next_asset_id(asset_id) + .free_balance((staking_asset_id, origin, initial_balance)) + .build() + .execute_with(|| { assert_ok!(GenericAsset::create( Origin::signed(origin), AssetOptions { initial_issuance: 0, permissions: permissions.clone(), - } + }, )); // Act assert_ok!(GenericAsset::mint(Origin::signed(origin), asset_id, to, amount)); + let expected_event = TestEvent::generic_asset(RawEvent::Minted(asset_id, to, amount)); + // Assert - assert!(System::events() - .iter() - .any(|record| record.event == TestEvent::generic_asset(RawEvent::Minted(asset_id, to, amount)))); + assert!(System::events().iter().any(|record| record.event == expected_event)); }, ); } @@ -1262,27 +1192,26 @@ fn burn_should_raise_event() { }; let amount = 100; - set_and_run_with_externalities( - &mut ExtBuilder::default() - .next_asset_id(asset_id) - .free_balance((staking_asset_id, origin, initial_balance)) - .build(), - || { + ExtBuilder::default() + .next_asset_id(asset_id) + .free_balance((staking_asset_id, origin, initial_balance)) + .build() + .execute_with(|| { assert_ok!(GenericAsset::create( Origin::signed(origin), AssetOptions { initial_issuance: amount, permissions: permissions.clone(), - } + }, )); // Act assert_ok!(GenericAsset::burn(Origin::signed(origin), asset_id, origin, amount)); + let expected_event = TestEvent::generic_asset(RawEvent::Burned(asset_id, origin, amount)); + // Assert - assert!(System::events() - .iter() - .any(|record| record.event == TestEvent::generic_asset(RawEvent::Burned(asset_id, origin, amount)))); + assert!(System::events().iter().any(|record| record.event == expected_event)); }, ); } diff --git a/srml/grandpa/src/tests.rs b/srml/grandpa/src/tests.rs index aec75d274c..2efeb4b5bf 100644 --- a/srml/grandpa/src/tests.rs +++ b/srml/grandpa/src/tests.rs @@ -18,7 +18,7 @@ #![cfg(test)] -use sr_primitives::{set_and_run_with_externalities, testing::Digest, traits::{Header, OnFinalize}}; +use sr_primitives::{testing::Digest, traits::{Header, OnFinalize}}; use crate::mock::*; use system::{EventRecord, Phase}; use codec::{Decode, Encode}; @@ -27,7 +27,7 @@ use super::*; #[test] fn authorities_change_logged() { - set_and_run_with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + new_test_ext(vec![(1, 1), (2, 1), (3, 1)]).execute_with(|| { System::initialize(&1, &Default::default(), &Default::default(), &Default::default()); Grandpa::schedule_change(to_authorities(vec![(4, 1), (5, 1), (6, 1)]), 0, None).unwrap(); @@ -55,7 +55,7 @@ fn authorities_change_logged() { #[test] fn authorities_change_logged_after_delay() { - set_and_run_with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + new_test_ext(vec![(1, 1), (2, 1), (3, 1)]).execute_with(|| { System::initialize(&1, &Default::default(), &Default::default(), &Default::default()); Grandpa::schedule_change(to_authorities(vec![(4, 1), (5, 1), (6, 1)]), 1, None).unwrap(); Grandpa::on_finalize(1); @@ -88,7 +88,7 @@ fn authorities_change_logged_after_delay() { #[test] fn cannot_schedule_change_when_one_pending() { - set_and_run_with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + new_test_ext(vec![(1, 1), (2, 1), (3, 1)]).execute_with(|| { System::initialize(&1, &Default::default(), &Default::default(), &Default::default()); Grandpa::schedule_change(to_authorities(vec![(4, 1), (5, 1), (6, 1)]), 1, None).unwrap(); assert!(>::exists()); @@ -131,7 +131,7 @@ fn new_decodes_from_old() { #[test] fn dispatch_forced_change() { - set_and_run_with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + new_test_ext(vec![(1, 1), (2, 1), (3, 1)]).execute_with(|| { System::initialize(&1, &Default::default(), &Default::default(), &Default::default()); Grandpa::schedule_change( to_authorities(vec![(4, 1), (5, 1), (6, 1)]), @@ -203,7 +203,7 @@ fn dispatch_forced_change() { #[test] fn schedule_pause_only_when_live() { - set_and_run_with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + new_test_ext(vec![(1, 1), (2, 1), (3, 1)]).execute_with(|| { // we schedule a pause at block 1 with delay of 1 System::initialize(&1, &Default::default(), &Default::default(), &Default::default()); Grandpa::schedule_pause(1).unwrap(); @@ -238,7 +238,7 @@ fn schedule_pause_only_when_live() { #[test] fn schedule_resume_only_when_paused() { - set_and_run_with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + new_test_ext(vec![(1, 1), (2, 1), (3, 1)]).execute_with(|| { System::initialize(&1, &Default::default(), &Default::default(), &Default::default()); // the set is currently live, resuming it is an error diff --git a/srml/im-online/src/tests.rs b/srml/im-online/src/tests.rs index d57b9f59cb..652d751281 100644 --- a/srml/im-online/src/tests.rs +++ b/srml/im-online/src/tests.rs @@ -23,8 +23,7 @@ use crate::mock::*; use offchain::testing::TestOffchainExt; use primitives::offchain::{OpaquePeerId, OffchainExt}; use support::{dispatch, assert_noop}; -use sr_primitives::{set_and_run_with_externalities, testing::UintAuthorityId}; - +use sr_primitives::testing::UintAuthorityId; #[test] fn test_unresponsiveness_slash_fraction() { @@ -48,7 +47,7 @@ fn test_unresponsiveness_slash_fraction() { #[test] fn should_report_offline_validators() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let block = 1; System::set_block_number(block); @@ -124,7 +123,7 @@ fn heartbeat( #[test] fn should_mark_online_validator_when_heartbeat_is_received() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { advance_session(); // given VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 3, 4, 5, 6])); @@ -159,7 +158,7 @@ fn should_mark_online_validator_when_heartbeat_is_received() { #[test] fn late_heartbeat_should_fail() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { advance_session(); // given VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 4, 4, 5, 6])); @@ -182,7 +181,7 @@ fn should_generate_heartbeats() { let (offchain, state) = TestOffchainExt::new(); ext.register_extension(OffchainExt::new(offchain)); - set_and_run_with_externalities(&mut ext, || { + ext.execute_with(|| { // given let block = 1; System::set_block_number(block); @@ -218,7 +217,7 @@ fn should_generate_heartbeats() { #[test] fn should_cleanup_received_heartbeats_on_session_end() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { advance_session(); VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 3])); diff --git a/srml/indices/src/tests.rs b/srml/indices/src/tests.rs index 4b8f1822b4..3bcf015713 100644 --- a/srml/indices/src/tests.rs +++ b/srml/indices/src/tests.rs @@ -20,61 +20,48 @@ use super::*; use crate::mock::{Indices, new_test_ext, make_account, kill_account, TestIsDeadAccount}; -use sr_primitives::set_and_run_with_externalities; #[test] fn indexing_lookup_should_work() { - set_and_run_with_externalities( - &mut new_test_ext(), - || { - assert_eq!(Indices::lookup_index(0), Some(1)); - assert_eq!(Indices::lookup_index(1), Some(2)); - assert_eq!(Indices::lookup_index(2), Some(3)); - assert_eq!(Indices::lookup_index(3), Some(4)); - assert_eq!(Indices::lookup_index(4), None); - }, - ); + new_test_ext().execute_with(|| { + assert_eq!(Indices::lookup_index(0), Some(1)); + assert_eq!(Indices::lookup_index(1), Some(2)); + assert_eq!(Indices::lookup_index(2), Some(3)); + assert_eq!(Indices::lookup_index(3), Some(4)); + assert_eq!(Indices::lookup_index(4), None); + }); } #[test] fn default_indexing_on_new_accounts_should_work() { - set_and_run_with_externalities( - &mut new_test_ext(), - || { - assert_eq!(Indices::lookup_index(4), None); - make_account(5); - assert_eq!(Indices::lookup_index(4), Some(5)); - }, - ); + new_test_ext().execute_with(|| { + assert_eq!(Indices::lookup_index(4), None); + make_account(5); + assert_eq!(Indices::lookup_index(4), Some(5)); + }); } #[test] fn reclaim_indexing_on_new_accounts_should_work() { - set_and_run_with_externalities( - &mut new_test_ext(), - || { - assert_eq!(Indices::lookup_index(1), Some(2)); - assert_eq!(Indices::lookup_index(4), None); + new_test_ext().execute_with(|| { + assert_eq!(Indices::lookup_index(1), Some(2)); + assert_eq!(Indices::lookup_index(4), None); - kill_account(2); // index 1 no longer locked to id 2 + kill_account(2); // index 1 no longer locked to id 2 - make_account(1 + 256); // id 257 takes index 1. - assert_eq!(Indices::lookup_index(1), Some(257)); - }, - ); + make_account(1 + 256); // id 257 takes index 1. + assert_eq!(Indices::lookup_index(1), Some(257)); + }); } #[test] fn alive_account_should_prevent_reclaim() { - set_and_run_with_externalities( - &mut new_test_ext(), - || { - assert!(!TestIsDeadAccount::is_dead_account(&2)); - assert_eq!(Indices::lookup_index(1), Some(2)); - assert_eq!(Indices::lookup_index(4), None); + new_test_ext().execute_with(|| { + assert!(!TestIsDeadAccount::is_dead_account(&2)); + assert_eq!(Indices::lookup_index(1), Some(2)); + assert_eq!(Indices::lookup_index(4), None); - make_account(1 + 256); // id 257 takes index 1. - assert_eq!(Indices::lookup_index(4), Some(257)); - }, - ); + make_account(1 + 256); // id 257 takes index 1. + assert_eq!(Indices::lookup_index(4), Some(257)); + }); } diff --git a/srml/membership/src/lib.rs b/srml/membership/src/lib.rs index 1a6ca82986..0cd3b0af66 100644 --- a/srml/membership/src/lib.rs +++ b/srml/membership/src/lib.rs @@ -196,10 +196,7 @@ mod tests { use primitives::H256; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried. - use sr_primitives::{ - Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header, - set_and_run_with_externalities, - }; + use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; use system::EnsureSignedBy; impl_outer_origin! { @@ -293,7 +290,7 @@ mod tests { #[test] fn query_membership_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(Membership::members(), vec![10, 20, 30]); assert_eq!(MEMBERS.with(|m| m.borrow().clone()), vec![10, 20, 30]); }); @@ -301,7 +298,7 @@ mod tests { #[test] fn add_member_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_noop!(Membership::add_member(Origin::signed(5), 15), "bad origin"); assert_noop!(Membership::add_member(Origin::signed(1), 10), "already a member"); assert_ok!(Membership::add_member(Origin::signed(1), 15)); @@ -312,7 +309,7 @@ mod tests { #[test] fn remove_member_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_noop!(Membership::remove_member(Origin::signed(5), 20), "bad origin"); assert_noop!(Membership::remove_member(Origin::signed(2), 15), "not a member"); assert_ok!(Membership::remove_member(Origin::signed(2), 20)); @@ -323,7 +320,7 @@ mod tests { #[test] fn swap_member_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_noop!(Membership::swap_member(Origin::signed(5), 10, 25), "bad origin"); assert_noop!(Membership::swap_member(Origin::signed(3), 15, 25), "not a member"); assert_noop!(Membership::swap_member(Origin::signed(3), 10, 30), "already a member"); @@ -337,7 +334,7 @@ mod tests { #[test] fn reset_members_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_noop!(Membership::reset_members(Origin::signed(1), vec![20, 40, 30]), "bad origin"); assert_ok!(Membership::reset_members(Origin::signed(4), vec![20, 40, 30])); assert_eq!(Membership::members(), vec![20, 30, 40]); diff --git a/srml/offences/src/tests.rs b/srml/offences/src/tests.rs index 7604533ba5..28e655d16b 100644 --- a/srml/offences/src/tests.rs +++ b/srml/offences/src/tests.rs @@ -24,11 +24,10 @@ use crate::mock::{ offence_reports, }; use system::{EventRecord, Phase}; -use sr_primitives::set_and_run_with_externalities; #[test] fn should_report_an_authority_and_trigger_on_offence() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); @@ -51,7 +50,7 @@ fn should_report_an_authority_and_trigger_on_offence() { #[test] fn should_calculate_the_fraction_correctly() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); @@ -83,7 +82,7 @@ fn should_calculate_the_fraction_correctly() { #[test] fn should_not_report_the_same_authority_twice_in_the_same_slot() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); @@ -113,7 +112,7 @@ fn should_not_report_the_same_authority_twice_in_the_same_slot() { #[test] fn should_report_in_different_time_slot() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); @@ -143,7 +142,7 @@ fn should_report_in_different_time_slot() { #[test] fn should_deposit_event() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); @@ -171,7 +170,7 @@ fn should_deposit_event() { #[test] fn doesnt_deposit_event_for_dups() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); @@ -208,7 +207,7 @@ fn doesnt_deposit_event_for_dups() { fn should_properly_count_offences() { // We report two different authorities for the same issue. Ultimately, the 1st authority // should have `count` equal 2 and the count of the 2nd one should be equal to 1. - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let time_slot = 42; assert_eq!(offence_reports(KIND, time_slot), vec![]); diff --git a/srml/randomness-collective-flip/src/lib.rs b/srml/randomness-collective-flip/src/lib.rs index 4ad0095fdf..8dedf6f570 100644 --- a/srml/randomness-collective-flip/src/lib.rs +++ b/srml/randomness-collective-flip/src/lib.rs @@ -155,7 +155,6 @@ mod tests { use primitives::H256; use sr_primitives::{ Perbill, traits::{BlakeTwo256, OnInitialize, Header as _, IdentityLookup}, testing::Header, - set_and_run_with_externalities, }; use support::{impl_outer_origin, parameter_types, traits::Randomness}; @@ -222,7 +221,7 @@ mod tests { #[test] fn test_random_material_parital() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let genesis_hash = System::parent_hash(); setup_blocks(38); @@ -236,7 +235,7 @@ mod tests { #[test] fn test_random_material_filled() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let genesis_hash = System::parent_hash(); setup_blocks(81); @@ -251,7 +250,7 @@ mod tests { #[test] fn test_random_material_filled_twice() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let genesis_hash = System::parent_hash(); setup_blocks(162); @@ -266,7 +265,7 @@ mod tests { #[test] fn test_random() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { setup_blocks(162); assert_eq!(System::block_number(), 162); diff --git a/srml/scored-pool/src/tests.rs b/srml/scored-pool/src/tests.rs index cd3efb0ceb..2f47b5da6f 100644 --- a/srml/scored-pool/src/tests.rs +++ b/srml/scored-pool/src/tests.rs @@ -20,7 +20,7 @@ use super::*; use mock::*; use support::{assert_ok, assert_noop}; -use sr_primitives::{set_and_run_with_externalities, traits::OnInitialize}; +use sr_primitives::traits::OnInitialize; type ScoredPool = Module; type System = system::Module; @@ -31,7 +31,7 @@ const INDEX_ERR: &str = "index does not match requested account"; #[test] fn query_membership_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(ScoredPool::members(), vec![20, 40]); assert_eq!(Balances::reserved_balance(&31), CandidateDeposit::get()); assert_eq!(Balances::reserved_balance(&40), CandidateDeposit::get()); @@ -41,7 +41,7 @@ fn query_membership_works() { #[test] fn submit_candidacy_must_not_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_noop!( ScoredPool::submit_candidacy(Origin::signed(99)), "balance too low to submit candidacy" @@ -55,7 +55,7 @@ fn submit_candidacy_must_not_work() { #[test] fn submit_candidacy_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let who = 15; @@ -70,7 +70,7 @@ fn submit_candidacy_works() { #[test] fn scoring_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let who = 15; let score = 99; @@ -88,7 +88,7 @@ fn scoring_works() { #[test] fn scoring_same_element_with_same_score_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let who = 31; let index = find_in_pool(who).expect("entity must be in pool") as u32; @@ -108,7 +108,7 @@ fn scoring_same_element_with_same_score_works() { #[test] fn kicking_works_only_for_authorized() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let who = 40; let index = find_in_pool(who).expect("entity must be in pool") as u32; assert_noop!(ScoredPool::kick(Origin::signed(99), who, index), "bad origin"); @@ -117,7 +117,7 @@ fn kicking_works_only_for_authorized() { #[test] fn kicking_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let who = 40; assert_eq!(Balances::reserved_balance(&who), CandidateDeposit::get()); @@ -137,7 +137,7 @@ fn kicking_works() { #[test] fn unscored_entities_must_not_be_used_for_filling_members() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given // we submit a candidacy, score will be `None` assert_ok!(ScoredPool::submit_candidacy(Origin::signed(15))); @@ -162,7 +162,7 @@ fn unscored_entities_must_not_be_used_for_filling_members() { #[test] fn refreshing_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let who = 15; assert_ok!(ScoredPool::submit_candidacy(Origin::signed(who))); @@ -180,7 +180,7 @@ fn refreshing_works() { #[test] fn refreshing_happens_every_period() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given System::set_block_number(1); assert_ok!(ScoredPool::submit_candidacy(Origin::signed(15))); @@ -200,7 +200,7 @@ fn refreshing_happens_every_period() { #[test] fn withdraw_candidacy_must_only_work_for_members() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let who = 77; let index = 0; assert_noop!( ScoredPool::withdraw_candidacy(Origin::signed(who), index), INDEX_ERR); @@ -209,7 +209,7 @@ fn withdraw_candidacy_must_only_work_for_members() { #[test] fn oob_index_should_abort() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let who = 40; let oob_index = ScoredPool::pool().len() as u32; assert_noop!(ScoredPool::withdraw_candidacy(Origin::signed(who), oob_index), OOB_ERR); @@ -220,7 +220,7 @@ fn oob_index_should_abort() { #[test] fn index_mismatches_should_abort() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let who = 40; let index = 3; assert_noop!(ScoredPool::withdraw_candidacy(Origin::signed(who), index), INDEX_ERR); @@ -231,7 +231,7 @@ fn index_mismatches_should_abort() { #[test] fn withdraw_unscored_candidacy_must_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let who = 5; @@ -246,7 +246,7 @@ fn withdraw_unscored_candidacy_must_work() { #[test] fn withdraw_scored_candidacy_must_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let who = 40; assert_eq!(Balances::reserved_balance(&who), CandidateDeposit::get()); @@ -264,7 +264,7 @@ fn withdraw_scored_candidacy_must_work() { #[test] fn candidacy_resubmitting_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // given let who = 15; diff --git a/srml/session/src/historical.rs b/srml/session/src/historical.rs index af9447eb7e..08e4a6ce31 100644 --- a/srml/session/src/historical.rs +++ b/srml/session/src/historical.rs @@ -313,9 +313,7 @@ impl> support::traits::KeyOwnerProofSystem<(KeyTypeId, mod tests { use super::*; use primitives::crypto::key_types::DUMMY; - use sr_primitives::{ - traits::OnInitialize, testing::UintAuthorityId, set_and_run_with_externalities, - }; + use sr_primitives::{traits::OnInitialize, testing::UintAuthorityId}; use crate::mock::{ NEXT_VALIDATORS, force_new_session, set_next_validators, Test, System, Session, @@ -336,7 +334,7 @@ mod tests { #[test] fn generated_proof_is_good() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { set_next_validators(vec![1, 2]); force_new_session(); @@ -377,7 +375,7 @@ mod tests { #[test] fn prune_up_to_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { for i in 1..101u64 { set_next_validators(vec![i]); force_new_session(); diff --git a/srml/session/src/lib.rs b/srml/session/src/lib.rs index df311f5081..bb14b0d8f4 100644 --- a/srml/session/src/lib.rs +++ b/srml/session/src/lib.rs @@ -681,9 +681,7 @@ mod tests { use super::*; use support::assert_ok; use primitives::crypto::key_types::DUMMY; - use sr_primitives::{ - traits::OnInitialize, set_and_run_with_externalities, testing::UintAuthorityId, - }; + use sr_primitives::{traits::OnInitialize, testing::UintAuthorityId}; use mock::{ NEXT_VALIDATORS, SESSION_CHANGED, TEST_SESSION_CHANGED, authorities, force_new_session, set_next_validators, set_session_length, session_changed, Test, Origin, System, Session, @@ -708,7 +706,7 @@ mod tests { #[test] fn simple_setup_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(authorities(), vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]); assert_eq!(Session::validators(), vec![1, 2, 3]); }); @@ -716,7 +714,7 @@ mod tests { #[test] fn put_get_keys() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { Session::put_keys(&10, &UintAuthorityId(10).into()); assert_eq!(Session::load_keys(&10), Some(UintAuthorityId(10).into())); }) @@ -725,7 +723,7 @@ mod tests { #[test] fn keys_cleared_on_kill() { let mut ext = new_test_ext(); - set_and_run_with_externalities(&mut ext, || { + ext.execute_with(|| { assert_eq!(Session::validators(), vec![1, 2, 3]); assert_eq!(Session::load_keys(&1), Some(UintAuthorityId(1).into())); @@ -742,7 +740,7 @@ mod tests { fn authorities_should_track_validators() { reset_before_session_end_called(); - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { set_next_validators(vec![1, 2]); force_new_session(); initialize_block(1); @@ -793,7 +791,7 @@ mod tests { #[test] fn should_work_with_early_exit() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { set_session_length(10); initialize_block(1); @@ -816,7 +814,7 @@ mod tests { #[test] fn session_change_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // Block 1: No change initialize_block(1); assert_eq!(authorities(), vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]); @@ -846,7 +844,7 @@ mod tests { #[test] fn duplicates_are_not_allowed() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::set_block_number(1); Session::on_initialize(1); assert!(Session::set_keys(Origin::signed(4), UintAuthorityId(1).into(), vec![]).is_err()); @@ -861,7 +859,7 @@ mod tests { fn session_changed_flag_works() { reset_before_session_end_called(); - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { TEST_SESSION_CHANGED.with(|l| *l.borrow_mut() = true); force_new_session(); @@ -950,7 +948,7 @@ mod tests { #[test] fn session_keys_generate_output_works_as_set_keys_input() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let new_keys = mock::MockSessionKeys::generate(None); assert_ok!( Session::set_keys( @@ -964,7 +962,7 @@ mod tests { #[test] fn return_true_if_more_than_third_is_disabled() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { set_next_validators(vec![1, 2, 3, 4, 5, 6, 7]); force_new_session(); initialize_block(1); @@ -977,6 +975,5 @@ mod tests { assert_eq!(Session::disable_index(2), true); assert_eq!(Session::disable_index(3), true); }); - } } diff --git a/srml/staking/src/mock.rs b/srml/staking/src/mock.rs index 9055d7db87..43bd00e3e0 100644 --- a/srml/staking/src/mock.rs +++ b/srml/staking/src/mock.rs @@ -340,8 +340,8 @@ impl ExtBuilder { keys: validators.iter().map(|x| (*x, UintAuthorityId(*x))).collect(), }.assimilate_storage(&mut storage); - let mut ext = storage.into(); - sr_primitives::set_and_run_with_externalities(&mut ext, || { + let mut ext = runtime_io::TestExternalities::from(storage); + ext.execute_with(|| { let validators = Session::validators(); SESSION.with(|x| *x.borrow_mut() = (validators.clone(), HashSet::new()) diff --git a/srml/staking/src/tests.rs b/srml/staking/src/tests.rs index 48218f9eb7..ca462b640b 100644 --- a/srml/staking/src/tests.rs +++ b/srml/staking/src/tests.rs @@ -18,16 +18,14 @@ use super::*; use mock::*; -use sr_primitives::{assert_eq_error_rate, traits::OnInitialize, set_and_run_with_externalities}; +use sr_primitives::{assert_eq_error_rate, traits::OnInitialize}; use sr_staking_primitives::offence::{OffenceDetails, OnOffenceHandler}; use support::{assert_ok, assert_noop, assert_eq_uvec, traits::{Currency, ReservableCurrency}}; #[test] fn basic_setup_works() { // Verifies initial conditions of mock - set_and_run_with_externalities(&mut ExtBuilder::default() - .build(), - || { + ExtBuilder::default().build().execute_with(|| { // Account 11 is stashed and locked, and account 10 is the controller assert_eq!(Staking::bonded(&11), Some(10)); // Account 21 is stashed and locked, and account 20 is the controller @@ -107,8 +105,7 @@ fn basic_setup_works() { #[test] fn change_controller_works() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), - || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(Staking::bonded(&11), Some(10)); assert!(>::enumerate().map(|(c, _)| c).collect::>().contains(&11)); @@ -134,10 +131,7 @@ fn rewards_should_work() { // * rewards get recorded per session // * rewards get paid per Era // * Check that nominators are also rewarded - set_and_run_with_externalities(&mut ExtBuilder::default() - .nominate(false) - .build(), - || { + ExtBuilder::default().nominate(false).build().execute_with(|| { // Init some balances let _ = Balances::make_free_balance_be(&2, 500); @@ -215,10 +209,7 @@ fn multi_era_reward_should_work() { // Should check that: // The value of current_session_reward is set at the end of each era, based on // slot_stake and session_reward. - set_and_run_with_externalities(&mut ExtBuilder::default() - .nominate(false) - .build(), - || { + ExtBuilder::default().nominate(false).build().execute_with(|| { let init_balance_10 = Balances::total_balance(&10); // Set payee to controller @@ -258,122 +249,122 @@ fn staking_should_work() { // * new validators can be added to the default set // * new ones will be chosen per era // * either one can unlock the stash and back-down from being a validator via `chill`ing. - set_and_run_with_externalities(&mut ExtBuilder::default() + ExtBuilder::default() .nominate(false) .fair(false) // to give 20 more staked value - .build(), - || { - Timestamp::set_timestamp(1); // Initialize time. + .build() + .execute_with(|| { + Timestamp::set_timestamp(1); // Initialize time. - // remember + compare this along with the test. - assert_eq_uvec!(validator_controllers(), vec![20, 10]); + // remember + compare this along with the test. + assert_eq_uvec!(validator_controllers(), vec![20, 10]); - // put some money in account that we'll use. - for i in 1..5 { let _ = Balances::make_free_balance_be(&i, 2000); } + // put some money in account that we'll use. + for i in 1..5 { let _ = Balances::make_free_balance_be(&i, 2000); } - // --- Block 1: - start_session(1); - // add a new candidate for being a validator. account 3 controlled by 4. - assert_ok!(Staking::bond(Origin::signed(3), 4, 1500, RewardDestination::Controller)); - assert_ok!(Staking::validate(Origin::signed(4), ValidatorPrefs::default())); + // --- Block 1: + start_session(1); + // add a new candidate for being a validator. account 3 controlled by 4. + assert_ok!(Staking::bond(Origin::signed(3), 4, 1500, RewardDestination::Controller)); + assert_ok!(Staking::validate(Origin::signed(4), ValidatorPrefs::default())); - // No effects will be seen so far. - assert_eq_uvec!(validator_controllers(), vec![20, 10]); + // No effects will be seen so far. + assert_eq_uvec!(validator_controllers(), vec![20, 10]); - // --- Block 2: - start_session(2); + // --- Block 2: + start_session(2); - // No effects will be seen so far. Era has not been yet triggered. - assert_eq_uvec!(validator_controllers(), vec![20, 10]); + // No effects will be seen so far. Era has not been yet triggered. + assert_eq_uvec!(validator_controllers(), vec![20, 10]); - // --- Block 3: the validators will now be queued. - start_session(3); - assert_eq!(Staking::current_era(), 1); + // --- Block 3: the validators will now be queued. + start_session(3); + assert_eq!(Staking::current_era(), 1); - // --- Block 4: the validators will now be changed. - start_session(4); + // --- Block 4: the validators will now be changed. + start_session(4); - assert_eq_uvec!(validator_controllers(), vec![20, 4]); - // --- Block 4: Unstake 4 as a validator, freeing up the balance stashed in 3 - // 4 will chill - Staking::chill(Origin::signed(4)).unwrap(); + assert_eq_uvec!(validator_controllers(), vec![20, 4]); + // --- Block 4: Unstake 4 as a validator, freeing up the balance stashed in 3 + // 4 will chill + Staking::chill(Origin::signed(4)).unwrap(); - // --- Block 5: nothing. 4 is still there. - start_session(5); - assert_eq_uvec!(validator_controllers(), vec![20, 4]); + // --- Block 5: nothing. 4 is still there. + start_session(5); + assert_eq_uvec!(validator_controllers(), vec![20, 4]); - // --- Block 6: 4 will not be a validator. - start_session(7); - assert_eq_uvec!(validator_controllers(), vec![20, 10]); + // --- Block 6: 4 will not be a validator. + start_session(7); + assert_eq_uvec!(validator_controllers(), vec![20, 10]); - // Note: the stashed value of 4 is still lock - assert_eq!( - Staking::ledger(&4), - Some(StakingLedger { stash: 3, total: 1500, active: 1500, unlocking: vec![] }) - ); - // e.g. it cannot spend more than 500 that it has free from the total 2000 - assert_noop!(Balances::reserve(&3, 501), "account liquidity restrictions prevent withdrawal"); - assert_ok!(Balances::reserve(&3, 409)); - }); + // Note: the stashed value of 4 is still lock + assert_eq!( + Staking::ledger(&4), + Some(StakingLedger { stash: 3, total: 1500, active: 1500, unlocking: vec![] }) + ); + // e.g. it cannot spend more than 500 that it has free from the total 2000 + assert_noop!(Balances::reserve(&3, 501), "account liquidity restrictions prevent withdrawal"); + assert_ok!(Balances::reserve(&3, 409)); + }); } #[test] fn less_than_needed_candidates_works() { - set_and_run_with_externalities(&mut ExtBuilder::default() + ExtBuilder::default() .minimum_validator_count(1) .validator_count(4) .nominate(false) .num_validators(3) - .build(), - || { - assert_eq!(Staking::validator_count(), 4); - assert_eq!(Staking::minimum_validator_count(), 1); - assert_eq_uvec!(validator_controllers(), vec![30, 20, 10]); - - start_era(1); - - // Previous set is selected. NO election algorithm is even executed. - assert_eq_uvec!(validator_controllers(), vec![30, 20, 10]); - - // But the exposure is updated in a simple way. No external votes exists. This is purely self-vote. - assert_eq!(Staking::stakers(10).others.len(), 0); - assert_eq!(Staking::stakers(20).others.len(), 0); - assert_eq!(Staking::stakers(30).others.len(), 0); - check_exposure_all(); - check_nominator_all(); - }); + .build() + .execute_with(|| { + assert_eq!(Staking::validator_count(), 4); + assert_eq!(Staking::minimum_validator_count(), 1); + assert_eq_uvec!(validator_controllers(), vec![30, 20, 10]); + + start_era(1); + + // Previous set is selected. NO election algorithm is even executed. + assert_eq_uvec!(validator_controllers(), vec![30, 20, 10]); + + // But the exposure is updated in a simple way. No external votes exists. + // This is purely self-vote. + assert_eq!(Staking::stakers(10).others.len(), 0); + assert_eq!(Staking::stakers(20).others.len(), 0); + assert_eq!(Staking::stakers(30).others.len(), 0); + check_exposure_all(); + check_nominator_all(); + }); } #[test] fn no_candidate_emergency_condition() { - set_and_run_with_externalities(&mut ExtBuilder::default() + ExtBuilder::default() .minimum_validator_count(10) .validator_count(15) .num_validators(4) .validator_pool(true) .nominate(false) - .build(), - || { - - // initial validators - assert_eq_uvec!(validator_controllers(), vec![10, 20, 30, 40]); + .build() + .execute_with(|| { + // initial validators + assert_eq_uvec!(validator_controllers(), vec![10, 20, 30, 40]); - // set the minimum validator count. - ::MinimumValidatorCount::put(10); - ::ValidatorCount::put(15); - assert_eq!(Staking::validator_count(), 15); + // set the minimum validator count. + ::MinimumValidatorCount::put(10); + ::ValidatorCount::put(15); + assert_eq!(Staking::validator_count(), 15); - let _ = Staking::chill(Origin::signed(10)); + let _ = Staking::chill(Origin::signed(10)); - // trigger era - System::set_block_number(1); - Session::on_initialize(System::block_number()); + // trigger era + System::set_block_number(1); + Session::on_initialize(System::block_number()); - // Previous ones are elected. chill is invalidates. TODO: #2494 - assert_eq_uvec!(validator_controllers(), vec![10, 20, 30, 40]); - assert_eq!(Staking::current_elected().len(), 0); - }); + // Previous ones are elected. chill is invalidates. TODO: #2494 + assert_eq_uvec!(validator_controllers(), vec![10, 20, 30, 40]); + assert_eq!(Staking::current_elected().len(), 0); + }); } #[test] @@ -413,181 +404,181 @@ fn nominating_and_rewards_should_work() { // 10 with stake 400.0 20 with stake 600.0 30 with stake 0 // 4 has load 0.0005555555555555556 and supported // 10 with stake 600.0 20 with stake 400.0 40 with stake 0.0 - set_and_run_with_externalities(&mut ExtBuilder::default() + ExtBuilder::default() .nominate(false) .validator_pool(true) - .build(), - || { - // initial validators -- everyone is actually even. - assert_eq_uvec!(validator_controllers(), vec![40, 30]); - - // Set payee to controller - assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller)); - assert_ok!(Staking::set_payee(Origin::signed(20), RewardDestination::Controller)); - assert_ok!(Staking::set_payee(Origin::signed(30), RewardDestination::Controller)); - assert_ok!(Staking::set_payee(Origin::signed(40), RewardDestination::Controller)); - - // give the man some money - let initial_balance = 1000; - for i in [1, 2, 3, 4, 5, 10, 11, 20, 21].iter() { - let _ = Balances::make_free_balance_be(i, initial_balance); - } - - // bond two account pairs and state interest in nomination. - // 2 will nominate for 10, 20, 30 - assert_ok!(Staking::bond(Origin::signed(1), 2, 1000, RewardDestination::Controller)); - assert_ok!(Staking::nominate(Origin::signed(2), vec![11, 21, 31])); - // 4 will nominate for 10, 20, 40 - assert_ok!(Staking::bond(Origin::signed(3), 4, 1000, RewardDestination::Controller)); - assert_ok!(Staking::nominate(Origin::signed(4), vec![11, 21, 41])); - - // the total reward for era 0 - let total_payout_0 = current_total_payout_for_duration(3000); - assert!(total_payout_0 > 100); // Test is meaningfull if reward something - >::reward_by_ids(vec![(41, 1)]); - >::reward_by_ids(vec![(31, 1)]); - >::reward_by_ids(vec![(21, 10)]); // must be no-op - >::reward_by_ids(vec![(11, 10)]); // must be no-op - - start_era(1); - - // 10 and 20 have more votes, they will be chosen by phragmen. - assert_eq_uvec!(validator_controllers(), vec![20, 10]); - - // OLD validators must have already received some rewards. - assert_eq!(Balances::total_balance(&40), 1 + total_payout_0 / 2); - assert_eq!(Balances::total_balance(&30), 1 + total_payout_0 / 2); - - // ------ check the staked value of all parties. - - if cfg!(feature = "equalize") { - // total expo of 10, with 1200 coming from nominators (externals), according to phragmen. - assert_eq!(Staking::stakers(11).own, 1000); - assert_eq_error_rate!(Staking::stakers(11).total, 1000 + 1000, 2); - // 2 and 4 supported 10, each with stake 600, according to phragmen. - assert_eq!( - Staking::stakers(11).others.iter().map(|e| e.value).collect::>>(), - vec![600, 400] - ); - assert_eq!( - Staking::stakers(11).others.iter().map(|e| e.who).collect::>(), - vec![3, 1] - ); - // total expo of 20, with 500 coming from nominators (externals), according to phragmen. - assert_eq!(Staking::stakers(21).own, 1000); - assert_eq_error_rate!(Staking::stakers(21).total, 1000 + 1000, 2); - // 2 and 4 supported 20, each with stake 250, according to phragmen. - assert_eq!( - Staking::stakers(21).others.iter().map(|e| e.value).collect::>>(), - vec![400, 600] - ); - assert_eq!( - Staking::stakers(21).others.iter().map(|e| e.who).collect::>(), - vec![3, 1] - ); - } else { - // total expo of 10, with 1200 coming from nominators (externals), according to phragmen. - assert_eq!(Staking::stakers(11).own, 1000); - assert_eq!(Staking::stakers(11).total, 1000 + 800); - // 2 and 4 supported 10, each with stake 600, according to phragmen. - assert_eq!( - Staking::stakers(11).others.iter().map(|e| e.value).collect::>>(), - vec![400, 400] - ); - assert_eq!( - Staking::stakers(11).others.iter().map(|e| e.who).collect::>(), - vec![3, 1] - ); - // total expo of 20, with 500 coming from nominators (externals), according to phragmen. - assert_eq!(Staking::stakers(21).own, 1000); - assert_eq_error_rate!(Staking::stakers(21).total, 1000 + 1200, 2); - // 2 and 4 supported 20, each with stake 250, according to phragmen. - assert_eq!( - Staking::stakers(21).others.iter().map(|e| e.value).collect::>>(), - vec![600, 600] - ); - assert_eq!( - Staking::stakers(21).others.iter().map(|e| e.who).collect::>(), - vec![3, 1] - ); - } - - // They are not chosen anymore - assert_eq!(Staking::stakers(31).total, 0); - assert_eq!(Staking::stakers(41).total, 0); - - // the total reward for era 1 - let total_payout_1 = current_total_payout_for_duration(3000); - assert!(total_payout_1 > 100); // Test is meaningfull if reward something - >::reward_by_ids(vec![(41, 10)]); // must be no-op - >::reward_by_ids(vec![(31, 10)]); // must be no-op - >::reward_by_ids(vec![(21, 2)]); - >::reward_by_ids(vec![(11, 1)]); - - start_era(2); - - // nothing else will happen, era ends and rewards are paid again, - // it is expected that nominators will also be paid. See below - - let payout_for_10 = total_payout_1 / 3; - let payout_for_20 = 2 * total_payout_1 / 3; - if cfg!(feature = "equalize") { - // Nominator 2: has [400 / 2000 ~ 1 / 5 from 10] + [600 / 2000 ~ 3 / 10 from 20]'s reward. - assert_eq_error_rate!( - Balances::total_balance(&2), - initial_balance + payout_for_10 / 5 + payout_for_20 * 3 / 10, - 2, - ); - // Nominator 4: has [400 / 2000 ~ 1 / 5 from 20] + [600 / 2000 ~ 3 / 10 from 10]'s reward. - assert_eq_error_rate!( - Balances::total_balance(&4), - initial_balance + payout_for_20 / 5 + payout_for_10 * 3 / 10, - 2, - ); - - // Validator 10: got 1000 / 2000 external stake. - assert_eq_error_rate!( - Balances::total_balance(&10), - initial_balance + payout_for_10 / 2, - 1, - ); - // Validator 20: got 1000 / 2000 external stake. - assert_eq_error_rate!( - Balances::total_balance(&20), - initial_balance + payout_for_20 / 2, - 1, - ); - } else { - // Nominator 2: has [400/1800 ~ 2/9 from 10] + [600/2200 ~ 3/11 from 20]'s reward. ==> 2/9 + 3/11 - assert_eq_error_rate!( - Balances::total_balance(&2), - initial_balance + (2 * payout_for_10 / 9 + 3 * payout_for_20 / 11), - 1, - ); - // Nominator 4: has [400/1800 ~ 2/9 from 10] + [600/2200 ~ 3/11 from 20]'s reward. ==> 2/9 + 3/11 - assert_eq_error_rate!( - Balances::total_balance(&4), - initial_balance + (2 * payout_for_10 / 9 + 3 * payout_for_20 / 11), - 1, - ); - - // Validator 10: got 800 / 1800 external stake => 8/18 =? 4/9 => Validator's share = 5/9 - assert_eq_error_rate!( - Balances::total_balance(&10), - initial_balance + 5 * payout_for_10 / 9, - 1, - ); - // Validator 20: got 1200 / 2200 external stake => 12/22 =? 6/11 => Validator's share = 5/11 - assert_eq_error_rate!( - Balances::total_balance(&20), - initial_balance + 5 * payout_for_20 / 11, - 1, - ); - } - - check_exposure_all(); - check_nominator_all(); - }); + .build() + .execute_with(|| { + // initial validators -- everyone is actually even. + assert_eq_uvec!(validator_controllers(), vec![40, 30]); + + // Set payee to controller + assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller)); + assert_ok!(Staking::set_payee(Origin::signed(20), RewardDestination::Controller)); + assert_ok!(Staking::set_payee(Origin::signed(30), RewardDestination::Controller)); + assert_ok!(Staking::set_payee(Origin::signed(40), RewardDestination::Controller)); + + // give the man some money + let initial_balance = 1000; + for i in [1, 2, 3, 4, 5, 10, 11, 20, 21].iter() { + let _ = Balances::make_free_balance_be(i, initial_balance); + } + + // bond two account pairs and state interest in nomination. + // 2 will nominate for 10, 20, 30 + assert_ok!(Staking::bond(Origin::signed(1), 2, 1000, RewardDestination::Controller)); + assert_ok!(Staking::nominate(Origin::signed(2), vec![11, 21, 31])); + // 4 will nominate for 10, 20, 40 + assert_ok!(Staking::bond(Origin::signed(3), 4, 1000, RewardDestination::Controller)); + assert_ok!(Staking::nominate(Origin::signed(4), vec![11, 21, 41])); + + // the total reward for era 0 + let total_payout_0 = current_total_payout_for_duration(3000); + assert!(total_payout_0 > 100); // Test is meaningfull if reward something + >::reward_by_ids(vec![(41, 1)]); + >::reward_by_ids(vec![(31, 1)]); + >::reward_by_ids(vec![(21, 10)]); // must be no-op + >::reward_by_ids(vec![(11, 10)]); // must be no-op + + start_era(1); + + // 10 and 20 have more votes, they will be chosen by phragmen. + assert_eq_uvec!(validator_controllers(), vec![20, 10]); + + // OLD validators must have already received some rewards. + assert_eq!(Balances::total_balance(&40), 1 + total_payout_0 / 2); + assert_eq!(Balances::total_balance(&30), 1 + total_payout_0 / 2); + + // ------ check the staked value of all parties. + + if cfg!(feature = "equalize") { + // total expo of 10, with 1200 coming from nominators (externals), according to phragmen. + assert_eq!(Staking::stakers(11).own, 1000); + assert_eq_error_rate!(Staking::stakers(11).total, 1000 + 1000, 2); + // 2 and 4 supported 10, each with stake 600, according to phragmen. + assert_eq!( + Staking::stakers(11).others.iter().map(|e| e.value).collect::>>(), + vec![600, 400] + ); + assert_eq!( + Staking::stakers(11).others.iter().map(|e| e.who).collect::>(), + vec![3, 1] + ); + // total expo of 20, with 500 coming from nominators (externals), according to phragmen. + assert_eq!(Staking::stakers(21).own, 1000); + assert_eq_error_rate!(Staking::stakers(21).total, 1000 + 1000, 2); + // 2 and 4 supported 20, each with stake 250, according to phragmen. + assert_eq!( + Staking::stakers(21).others.iter().map(|e| e.value).collect::>>(), + vec![400, 600] + ); + assert_eq!( + Staking::stakers(21).others.iter().map(|e| e.who).collect::>(), + vec![3, 1] + ); + } else { + // total expo of 10, with 1200 coming from nominators (externals), according to phragmen. + assert_eq!(Staking::stakers(11).own, 1000); + assert_eq!(Staking::stakers(11).total, 1000 + 800); + // 2 and 4 supported 10, each with stake 600, according to phragmen. + assert_eq!( + Staking::stakers(11).others.iter().map(|e| e.value).collect::>>(), + vec![400, 400] + ); + assert_eq!( + Staking::stakers(11).others.iter().map(|e| e.who).collect::>(), + vec![3, 1] + ); + // total expo of 20, with 500 coming from nominators (externals), according to phragmen. + assert_eq!(Staking::stakers(21).own, 1000); + assert_eq_error_rate!(Staking::stakers(21).total, 1000 + 1200, 2); + // 2 and 4 supported 20, each with stake 250, according to phragmen. + assert_eq!( + Staking::stakers(21).others.iter().map(|e| e.value).collect::>>(), + vec![600, 600] + ); + assert_eq!( + Staking::stakers(21).others.iter().map(|e| e.who).collect::>(), + vec![3, 1] + ); + } + + // They are not chosen anymore + assert_eq!(Staking::stakers(31).total, 0); + assert_eq!(Staking::stakers(41).total, 0); + + // the total reward for era 1 + let total_payout_1 = current_total_payout_for_duration(3000); + assert!(total_payout_1 > 100); // Test is meaningfull if reward something + >::reward_by_ids(vec![(41, 10)]); // must be no-op + >::reward_by_ids(vec![(31, 10)]); // must be no-op + >::reward_by_ids(vec![(21, 2)]); + >::reward_by_ids(vec![(11, 1)]); + + start_era(2); + + // nothing else will happen, era ends and rewards are paid again, + // it is expected that nominators will also be paid. See below + + let payout_for_10 = total_payout_1 / 3; + let payout_for_20 = 2 * total_payout_1 / 3; + if cfg!(feature = "equalize") { + // Nominator 2: has [400 / 2000 ~ 1 / 5 from 10] + [600 / 2000 ~ 3 / 10 from 20]'s reward. + assert_eq_error_rate!( + Balances::total_balance(&2), + initial_balance + payout_for_10 / 5 + payout_for_20 * 3 / 10, + 2, + ); + // Nominator 4: has [400 / 2000 ~ 1 / 5 from 20] + [600 / 2000 ~ 3 / 10 from 10]'s reward. + assert_eq_error_rate!( + Balances::total_balance(&4), + initial_balance + payout_for_20 / 5 + payout_for_10 * 3 / 10, + 2, + ); + + // Validator 10: got 1000 / 2000 external stake. + assert_eq_error_rate!( + Balances::total_balance(&10), + initial_balance + payout_for_10 / 2, + 1, + ); + // Validator 20: got 1000 / 2000 external stake. + assert_eq_error_rate!( + Balances::total_balance(&20), + initial_balance + payout_for_20 / 2, + 1, + ); + } else { + // Nominator 2: has [400/1800 ~ 2/9 from 10] + [600/2200 ~ 3/11 from 20]'s reward. ==> 2/9 + 3/11 + assert_eq_error_rate!( + Balances::total_balance(&2), + initial_balance + (2 * payout_for_10 / 9 + 3 * payout_for_20 / 11), + 1, + ); + // Nominator 4: has [400/1800 ~ 2/9 from 10] + [600/2200 ~ 3/11 from 20]'s reward. ==> 2/9 + 3/11 + assert_eq_error_rate!( + Balances::total_balance(&4), + initial_balance + (2 * payout_for_10 / 9 + 3 * payout_for_20 / 11), + 1, + ); + + // Validator 10: got 800 / 1800 external stake => 8/18 =? 4/9 => Validator's share = 5/9 + assert_eq_error_rate!( + Balances::total_balance(&10), + initial_balance + 5 * payout_for_10 / 9, + 1, + ); + // Validator 20: got 1200 / 2200 external stake => 12/22 =? 6/11 => Validator's share = 5/11 + assert_eq_error_rate!( + Balances::total_balance(&20), + initial_balance + 5 * payout_for_20 / 11, + 1, + ); + } + + check_exposure_all(); + check_nominator_all(); + }); } #[test] @@ -597,7 +588,7 @@ fn nominators_also_get_slashed() { // 10 - is the controller of 11 // 11 - is the stash. // 2 - is the nominator of 20, 10 - set_and_run_with_externalities(&mut ExtBuilder::default().nominate(false).build(), || { + ExtBuilder::default().nominate(false).build().execute_with(|| { assert_eq!(Staking::validator_count(), 2); // Set payee to controller @@ -657,53 +648,49 @@ fn double_staking_should_fail() { // * an account already bonded as stash cannot be be stashed again. // * an account already bonded as stash cannot nominate. // * an account already bonded as controller can nominate. - set_and_run_with_externalities(&mut ExtBuilder::default() - .build(), - || { - let arbitrary_value = 5; - // 2 = controller, 1 stashed => ok - assert_ok!( - Staking::bond(Origin::signed(1), 2, arbitrary_value, - RewardDestination::default()) - ); - // 4 = not used so far, 1 stashed => not allowed. - assert_noop!( - Staking::bond(Origin::signed(1), 4, arbitrary_value, - RewardDestination::default()), "stash already bonded" - ); - // 1 = stashed => attempting to nominate should fail. - assert_noop!(Staking::nominate(Origin::signed(1), vec![1]), "not a controller"); - // 2 = controller => nominating should work. - assert_ok!(Staking::nominate(Origin::signed(2), vec![1])); - }); + ExtBuilder::default().build().execute_with(|| { + let arbitrary_value = 5; + // 2 = controller, 1 stashed => ok + assert_ok!( + Staking::bond(Origin::signed(1), 2, arbitrary_value, + RewardDestination::default()) + ); + // 4 = not used so far, 1 stashed => not allowed. + assert_noop!( + Staking::bond(Origin::signed(1), 4, arbitrary_value, + RewardDestination::default()), "stash already bonded" + ); + // 1 = stashed => attempting to nominate should fail. + assert_noop!(Staking::nominate(Origin::signed(1), vec![1]), "not a controller"); + // 2 = controller => nominating should work. + assert_ok!(Staking::nominate(Origin::signed(2), vec![1])); + }); } #[test] fn double_controlling_should_fail() { // should test (in the same order): // * an account already bonded as controller CANNOT be reused as the controller of another account. - set_and_run_with_externalities(&mut ExtBuilder::default() - .build(), - || { - let arbitrary_value = 5; - // 2 = controller, 1 stashed => ok - assert_ok!( - Staking::bond(Origin::signed(1), 2, arbitrary_value, - RewardDestination::default()) - ); - // 2 = controller, 3 stashed (Note that 2 is reused.) => no-op - assert_noop!( - Staking::bond(Origin::signed(3), 2, arbitrary_value, RewardDestination::default()), - "controller already paired" - ); - }); + ExtBuilder::default().build().execute_with(|| { + let arbitrary_value = 5; + // 2 = controller, 1 stashed => ok + assert_ok!(Staking::bond( + Origin::signed(1), + 2, + arbitrary_value, + RewardDestination::default(), + )); + // 2 = controller, 3 stashed (Note that 2 is reused.) => no-op + assert_noop!( + Staking::bond(Origin::signed(3), 2, arbitrary_value, RewardDestination::default()), + "controller already paired", + ); + }); } #[test] fn session_and_eras_work() { - set_and_run_with_externalities(&mut ExtBuilder::default() - .build(), - || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(Staking::current_era(), 0); // Block 1: No change. @@ -745,7 +732,7 @@ fn session_and_eras_work() { #[test] fn forcing_new_era_works() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(),|| { + ExtBuilder::default().build().execute_with(|| { // normal flow of session. assert_eq!(Staking::current_era(), 0); start_session(0); @@ -784,7 +771,7 @@ fn forcing_new_era_works() { #[test] fn cannot_transfer_staked_balance() { // Tests that a stash account cannot transfer funds - set_and_run_with_externalities(&mut ExtBuilder::default().nominate(false).build(), || { + ExtBuilder::default().nominate(false).build().execute_with(|| { // Confirm account 11 is stashed assert_eq!(Staking::bonded(&11), Some(10)); // Confirm account 11 has some free balance @@ -809,11 +796,7 @@ fn cannot_transfer_staked_balance_2() { // Tests that a stash account cannot transfer funds // Same test as above but with 20, and more accurate. // 21 has 2000 free balance but 1000 at stake - set_and_run_with_externalities(&mut ExtBuilder::default() - .nominate(false) - .fair(true) - .build(), - || { + ExtBuilder::default().nominate(false).fair(true).build().execute_with(|| { // Confirm account 21 is stashed assert_eq!(Staking::bonded(&21), Some(20)); // Confirm account 21 has some free balance @@ -832,7 +815,7 @@ fn cannot_transfer_staked_balance_2() { #[test] fn cannot_reserve_staked_balance() { // Checks that a bonded account cannot reserve balance from free balance - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { // Confirm account 11 is stashed assert_eq!(Staking::bonded(&11), Some(10)); // Confirm account 11 has some free balance @@ -852,7 +835,7 @@ fn cannot_reserve_staked_balance() { #[test] fn reward_destination_works() { // Rewards go to the correct destination as determined in Payee - set_and_run_with_externalities(&mut ExtBuilder::default().nominate(false).build(), || { + ExtBuilder::default().nominate(false).build().execute_with(|| { // Check that account 11 is a validator assert!(Staking::current_elected().contains(&11)); // Check the balance of the validator account @@ -944,9 +927,7 @@ fn validator_payment_prefs_work() { // Test that validator preferences are correctly honored // Note: unstake threshold is being directly tested in slashing tests. // This test will focus on validator payment. - set_and_run_with_externalities(&mut ExtBuilder::default() - .build(), - || { + ExtBuilder::default().build().execute_with(|| { // Initial config let validator_cut = 5; let stash_initial_balance = Balances::total_balance(&11); @@ -996,8 +977,7 @@ fn bond_extra_works() { // Tests that extra `free_balance` in the stash can be added to stake // NOTE: this tests only verifies `StakingLedger` for correct updates // See `bond_extra_and_withdraw_unbonded_works` for more details and updates on `Exposure`. - set_and_run_with_externalities(&mut ExtBuilder::default().build(), - || { + ExtBuilder::default().build().execute_with(|| { // Check that account 10 is a validator assert!(>::exists(11)); // Check that account 10 is bonded to account 11 @@ -1042,10 +1022,7 @@ fn bond_extra_and_withdraw_unbonded_works() { // * It can add extra funds to the bonded account. // * it can unbond a portion of its funds from the stash account. // * Once the unbonding period is done, it can actually take the funds out of the stash. - set_and_run_with_externalities(&mut ExtBuilder::default() - .nominate(false) - .build(), - || { + ExtBuilder::default().nominate(false).build().execute_with(|| { // Set payee to controller. avoids confusion assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller)); @@ -1129,7 +1106,7 @@ fn bond_extra_and_withdraw_unbonded_works() { #[test] fn too_many_unbond_calls_should_not_work() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { // locked at era 0 until 3 for _ in 0..MAX_UNLOCKING_CHUNKS-1 { assert_ok!(Staking::unbond(Origin::signed(10), 1)); @@ -1158,11 +1135,7 @@ fn too_many_unbond_calls_should_not_work() { fn slot_stake_is_least_staked_validator_and_exposure_defines_maximum_punishment() { // Test that slot_stake is determined by the least staked validator // Test that slot_stake is the maximum punishment that can happen to a validator - set_and_run_with_externalities(&mut ExtBuilder::default() - .nominate(false) - .fair(false) - .build(), - || { + ExtBuilder::default().nominate(false).fair(false).build().execute_with(|| { // Confirm validator count is 2 assert_eq!(Staking::validator_count(), 2); // Confirm account 10 and 20 are validators @@ -1211,10 +1184,7 @@ fn slot_stake_is_least_staked_validator_and_exposure_defines_maximum_punishment( fn on_free_balance_zero_stash_removes_validator() { // Tests that validator storage items are cleaned up when stash is empty // Tests that storage items are untouched when controller is empty - set_and_run_with_externalities(&mut ExtBuilder::default() - .existential_deposit(10) - .build(), - || { + ExtBuilder::default().existential_deposit(10).build().execute_with(|| { // Check the balance of the validator account assert_eq!(Balances::free_balance(&10), 256); // Check the balance of the stash account @@ -1264,10 +1234,7 @@ fn on_free_balance_zero_stash_removes_validator() { fn on_free_balance_zero_stash_removes_nominator() { // Tests that nominator storage items are cleaned up when stash is empty // Tests that storage items are untouched when controller is empty - set_and_run_with_externalities(&mut ExtBuilder::default() - .existential_deposit(10) - .build(), - || { + ExtBuilder::default().existential_deposit(10).build().execute_with(|| { // Make 10 a nominator assert_ok!(Staking::nominate(Origin::signed(10), vec![20])); // Check that account 10 is a nominator @@ -1320,10 +1287,7 @@ fn on_free_balance_zero_stash_removes_nominator() { #[test] fn switching_roles() { // Test that it should be possible to switch between roles (nominator, validator, idle) with minimal overhead. - set_and_run_with_externalities(&mut ExtBuilder::default() - .nominate(false) - .build(), - || { + ExtBuilder::default().nominate(false).build().execute_with(|| { Timestamp::set_timestamp(1); // Initialize time. // Reset reward destination @@ -1389,11 +1353,7 @@ fn switching_roles() { #[test] fn wrong_vote_is_null() { - set_and_run_with_externalities(&mut ExtBuilder::default() - .nominate(false) - .validator_pool(true) - .build(), - || { + ExtBuilder::default().nominate(false).validator_pool(true).build().execute_with(|| { assert_eq_uvec!(validator_controllers(), vec![40, 30]); // put some money in account that we'll use. @@ -1417,174 +1377,173 @@ fn wrong_vote_is_null() { fn bond_with_no_staked_value() { // Behavior when someone bonds with no staked value. // Particularly when she votes and the candidate is elected. - set_and_run_with_externalities(&mut ExtBuilder::default() - .validator_count(3) - .existential_deposit(5) - .nominate(false) - .minimum_validator_count(1) - .build(), || { - // Can't bond with 1 - assert_noop!( - Staking::bond(Origin::signed(1), 2, 1, RewardDestination::Controller), - "can not bond with value less than minimum balance" - ); - // bonded with absolute minimum value possible. - assert_ok!(Staking::bond(Origin::signed(1), 2, 5, RewardDestination::Controller)); - assert_eq!(Balances::locks(&1)[0].amount, 5); + ExtBuilder::default() + .validator_count(3) + .existential_deposit(5) + .nominate(false) + .minimum_validator_count(1) + .build() + .execute_with(|| { + // Can't bond with 1 + assert_noop!( + Staking::bond(Origin::signed(1), 2, 1, RewardDestination::Controller), + "can not bond with value less than minimum balance", + ); + // bonded with absolute minimum value possible. + assert_ok!(Staking::bond(Origin::signed(1), 2, 5, RewardDestination::Controller)); + assert_eq!(Balances::locks(&1)[0].amount, 5); - // unbonding even 1 will cause all to be unbonded. - assert_ok!(Staking::unbond(Origin::signed(2), 1)); - assert_eq!( - Staking::ledger(2), - Some(StakingLedger { - stash: 1, - active: 0, - total: 5, - unlocking: vec![UnlockChunk {value: 5, era: 3}] - }) - ); + // unbonding even 1 will cause all to be unbonded. + assert_ok!(Staking::unbond(Origin::signed(2), 1)); + assert_eq!( + Staking::ledger(2), + Some(StakingLedger { + stash: 1, + active: 0, + total: 5, + unlocking: vec![UnlockChunk {value: 5, era: 3}] + }) + ); - start_era(1); - start_era(2); + start_era(1); + start_era(2); - // not yet removed. - assert_ok!(Staking::withdraw_unbonded(Origin::signed(2))); - assert!(Staking::ledger(2).is_some()); - assert_eq!(Balances::locks(&1)[0].amount, 5); + // not yet removed. + assert_ok!(Staking::withdraw_unbonded(Origin::signed(2))); + assert!(Staking::ledger(2).is_some()); + assert_eq!(Balances::locks(&1)[0].amount, 5); - start_era(3); + start_era(3); - // poof. Account 1 is removed from the staking system. - assert_ok!(Staking::withdraw_unbonded(Origin::signed(2))); - assert!(Staking::ledger(2).is_none()); - assert_eq!(Balances::locks(&1).len(), 0); - }); + // poof. Account 1 is removed from the staking system. + assert_ok!(Staking::withdraw_unbonded(Origin::signed(2))); + assert!(Staking::ledger(2).is_none()); + assert_eq!(Balances::locks(&1).len(), 0); + }); } #[test] fn bond_with_little_staked_value_bounded_by_slot_stake() { // Behavior when someone bonds with little staked value. // Particularly when she votes and the candidate is elected. - set_and_run_with_externalities(&mut ExtBuilder::default() + ExtBuilder::default() .validator_count(3) .nominate(false) .minimum_validator_count(1) - .build(), - || { - - // setup - assert_ok!(Staking::chill(Origin::signed(30))); - assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller)); - let init_balance_2 = Balances::free_balance(&2); - let init_balance_10 = Balances::free_balance(&10); - - // Stingy validator. - assert_ok!(Staking::bond(Origin::signed(1), 2, 1, RewardDestination::Controller)); - assert_ok!(Staking::validate(Origin::signed(2), ValidatorPrefs::default())); - - let total_payout_0 = current_total_payout_for_duration(3000); - assert!(total_payout_0 > 100); // Test is meaningfull if reward something - reward_all_elected(); - start_era(1); - - // 2 is elected. - // and fucks up the slot stake. - assert_eq_uvec!(validator_controllers(), vec![20, 10, 2]); - assert_eq!(Staking::slot_stake(), 1); - - // Old ones are rewarded. - assert_eq!(Balances::free_balance(&10), init_balance_10 + total_payout_0 / 3); - // no rewards paid to 2. This was initial election. - assert_eq!(Balances::free_balance(&2), init_balance_2); - - let total_payout_1 = current_total_payout_for_duration(3000); - assert!(total_payout_1 > 100); // Test is meaningfull if reward something - reward_all_elected(); - start_era(2); - - assert_eq_uvec!(validator_controllers(), vec![20, 10, 2]); - assert_eq!(Staking::slot_stake(), 1); - - assert_eq!(Balances::free_balance(&2), init_balance_2 + total_payout_1 / 3); - assert_eq!(Balances::free_balance(&10), init_balance_10 + total_payout_0 / 3 + total_payout_1 / 3); - check_exposure_all(); - check_nominator_all(); - }); + .build() + .execute_with(|| { + // setup + assert_ok!(Staking::chill(Origin::signed(30))); + assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller)); + let init_balance_2 = Balances::free_balance(&2); + let init_balance_10 = Balances::free_balance(&10); + + // Stingy validator. + assert_ok!(Staking::bond(Origin::signed(1), 2, 1, RewardDestination::Controller)); + assert_ok!(Staking::validate(Origin::signed(2), ValidatorPrefs::default())); + + let total_payout_0 = current_total_payout_for_duration(3000); + assert!(total_payout_0 > 100); // Test is meaningfull if reward something + reward_all_elected(); + start_era(1); + + // 2 is elected. + // and fucks up the slot stake. + assert_eq_uvec!(validator_controllers(), vec![20, 10, 2]); + assert_eq!(Staking::slot_stake(), 1); + + // Old ones are rewarded. + assert_eq!(Balances::free_balance(&10), init_balance_10 + total_payout_0 / 3); + // no rewards paid to 2. This was initial election. + assert_eq!(Balances::free_balance(&2), init_balance_2); + + let total_payout_1 = current_total_payout_for_duration(3000); + assert!(total_payout_1 > 100); // Test is meaningfull if reward something + reward_all_elected(); + start_era(2); + + assert_eq_uvec!(validator_controllers(), vec![20, 10, 2]); + assert_eq!(Staking::slot_stake(), 1); + + assert_eq!(Balances::free_balance(&2), init_balance_2 + total_payout_1 / 3); + assert_eq!( + Balances::free_balance(&10), + init_balance_10 + total_payout_0 / 3 + total_payout_1 / 3, + ); + check_exposure_all(); + check_nominator_all(); + }); } #[cfg(feature = "equalize")] #[test] fn phragmen_linear_worse_case_equalize() { - set_and_run_with_externalities(&mut ExtBuilder::default() + ExtBuilder::default() .nominate(false) .validator_pool(true) .fair(true) - .build(), - || { - - bond_validator(50, 1000); - bond_validator(60, 1000); - bond_validator(70, 1000); - - bond_nominator(2, 2000, vec![11]); - bond_nominator(4, 1000, vec![11, 21]); - bond_nominator(6, 1000, vec![21, 31]); - bond_nominator(8, 1000, vec![31, 41]); - bond_nominator(110, 1000, vec![41, 51]); - bond_nominator(120, 1000, vec![51, 61]); - bond_nominator(130, 1000, vec![61, 71]); - - for i in &[10, 20, 30, 40, 50, 60, 70] { - assert_ok!(Staking::set_payee(Origin::signed(*i), RewardDestination::Controller)); - } - - assert_eq_uvec!(validator_controllers(), vec![40, 30]); - assert_ok!(Staking::set_validator_count(Origin::ROOT, 7)); - - start_era(1); - - assert_eq_uvec!(validator_controllers(), vec![10, 60, 40, 20, 50, 30, 70]); - - assert_eq_error_rate!(Staking::stakers(11).total, 3000, 2); - assert_eq_error_rate!(Staking::stakers(21).total, 2255, 2); - assert_eq_error_rate!(Staking::stakers(31).total, 2255, 2); - assert_eq_error_rate!(Staking::stakers(41).total, 1925, 2); - assert_eq_error_rate!(Staking::stakers(51).total, 1870, 2); - assert_eq_error_rate!(Staking::stakers(61).total, 1890, 2); - assert_eq_error_rate!(Staking::stakers(71).total, 1800, 2); - - check_exposure_all(); - check_nominator_all(); - }) + .build() + .execute_with(|| { + bond_validator(50, 1000); + bond_validator(60, 1000); + bond_validator(70, 1000); + + bond_nominator(2, 2000, vec![11]); + bond_nominator(4, 1000, vec![11, 21]); + bond_nominator(6, 1000, vec![21, 31]); + bond_nominator(8, 1000, vec![31, 41]); + bond_nominator(110, 1000, vec![41, 51]); + bond_nominator(120, 1000, vec![51, 61]); + bond_nominator(130, 1000, vec![61, 71]); + + for i in &[10, 20, 30, 40, 50, 60, 70] { + assert_ok!(Staking::set_payee(Origin::signed(*i), RewardDestination::Controller)); + } + + assert_eq_uvec!(validator_controllers(), vec![40, 30]); + assert_ok!(Staking::set_validator_count(Origin::ROOT, 7)); + + start_era(1); + + assert_eq_uvec!(validator_controllers(), vec![10, 60, 40, 20, 50, 30, 70]); + + assert_eq_error_rate!(Staking::stakers(11).total, 3000, 2); + assert_eq_error_rate!(Staking::stakers(21).total, 2255, 2); + assert_eq_error_rate!(Staking::stakers(31).total, 2255, 2); + assert_eq_error_rate!(Staking::stakers(41).total, 1925, 2); + assert_eq_error_rate!(Staking::stakers(51).total, 1870, 2); + assert_eq_error_rate!(Staking::stakers(61).total, 1890, 2); + assert_eq_error_rate!(Staking::stakers(71).total, 1800, 2); + + check_exposure_all(); + check_nominator_all(); + }) } #[test] fn new_era_elects_correct_number_of_validators() { - set_and_run_with_externalities(&mut ExtBuilder::default() + ExtBuilder::default() .nominate(true) .validator_pool(true) .fair(true) .validator_count(1) - .build(), - || { - assert_eq!(Staking::validator_count(), 1); - assert_eq!(validator_controllers().len(), 1); - - System::set_block_number(1); - Session::on_initialize(System::block_number()); - - assert_eq!(validator_controllers().len(), 1); - check_exposure_all(); - check_nominator_all(); - }) + .build() + .execute_with(|| { + assert_eq!(Staking::validator_count(), 1); + assert_eq!(validator_controllers().len(), 1); + + System::set_block_number(1); + Session::on_initialize(System::block_number()); + + assert_eq!(validator_controllers().len(), 1); + check_exposure_all(); + check_nominator_all(); + }) } #[test] fn phragmen_should_not_overflow_validators() { - set_and_run_with_externalities(&mut ExtBuilder::default() - .nominate(false) - .build(), - || { + ExtBuilder::default().nominate(false).build().execute_with(|| { let _ = Staking::chill(Origin::signed(10)); let _ = Staking::chill(Origin::signed(20)); @@ -1607,10 +1566,7 @@ fn phragmen_should_not_overflow_validators() { #[test] fn phragmen_should_not_overflow_nominators() { - set_and_run_with_externalities(&mut ExtBuilder::default() - .nominate(false) - .build(), - || { + ExtBuilder::default().nominate(false).build().execute_with(|| { let _ = Staking::chill(Origin::signed(10)); let _ = Staking::chill(Origin::signed(20)); @@ -1632,10 +1588,7 @@ fn phragmen_should_not_overflow_nominators() { #[test] fn phragmen_should_not_overflow_ultimate() { - set_and_run_with_externalities(&mut ExtBuilder::default() - .nominate(false) - .build(), - || { + ExtBuilder::default().nominate(false).build().execute_with(|| { bond_validator(2, u64::max_value()); bond_validator(4, u64::max_value()); @@ -1654,9 +1607,7 @@ fn phragmen_should_not_overflow_ultimate() { #[test] fn reward_validator_slashing_validator_doesnt_overflow() { - set_and_run_with_externalities(&mut ExtBuilder::default() - .build(), - || { + ExtBuilder::default().build().execute_with(|| { let stake = u32::max_value() as u64 * 2; let reward_slash = u32::max_value() as u64 * 2; @@ -1687,9 +1638,7 @@ fn reward_validator_slashing_validator_doesnt_overflow() { #[test] fn reward_from_authorship_event_handler_works() { - set_and_run_with_externalities(&mut ExtBuilder::default() - .build(), - || { + ExtBuilder::default().build().execute_with(|| { use authorship::EventHandler; assert_eq!(>::author(), 11); @@ -1714,9 +1663,7 @@ fn reward_from_authorship_event_handler_works() { #[test] fn add_reward_points_fns_works() { - set_and_run_with_externalities(&mut ExtBuilder::default() - .build(), - || { + ExtBuilder::default().build().execute_with(|| { let validators = >::current_elected(); // Not mandatory but must be coherent with rewards assert_eq!(validators, vec![21, 11]); @@ -1742,7 +1689,7 @@ fn add_reward_points_fns_works() { #[test] fn unbonded_balance_is_not_slashable() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { // total amount staked is slashable. assert_eq!(Staking::slashable_balance_of(&11), 1000); @@ -1757,7 +1704,7 @@ fn unbonded_balance_is_not_slashable() { fn era_is_always_same_length() { // This ensures that the sessions is always of the same length if there is no forcing no // session changes. - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { start_era(1); assert_eq!(Staking::current_era_start_session_index(), SessionsPerEra::get()); @@ -1777,7 +1724,7 @@ fn era_is_always_same_length() { #[test] fn offence_forces_new_era() { - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { Staking::on_offence( &[OffenceDetails { offender: ( @@ -1797,7 +1744,7 @@ fn offence_forces_new_era() { fn slashing_performed_according_exposure() { // This test checks that slashing is performed according the exposure (or more precisely, // historical exposure), not the current balance. - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(Staking::stakers(&11).own, 1000); // Handle an offence with a historical exposure. @@ -1825,7 +1772,7 @@ fn slashing_performed_according_exposure() { fn reporters_receive_their_slice() { // This test verifies that the reporters of the offence receive their slice from the slashed // amount. - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { // The reporters' reward is calculated from the total exposure. #[cfg(feature = "equalize")] let initial_balance = 1250; @@ -1855,44 +1802,41 @@ fn reporters_receive_their_slice() { #[test] fn invulnerables_are_not_slashed() { // For invulnerable validators no slashing is performed. - set_and_run_with_externalities( - &mut ExtBuilder::default().invulnerables(vec![11]).build(), - || { - #[cfg(feature = "equalize")] - let initial_balance = 1250; - #[cfg(not(feature = "equalize"))] - let initial_balance = 1375; - - assert_eq!(Balances::free_balance(&11), 1000); - assert_eq!(Balances::free_balance(&21), 2000); - assert_eq!(Staking::stakers(&21).total, initial_balance); - - Staking::on_offence( - &[ - OffenceDetails { - offender: (11, Staking::stakers(&11)), - reporters: vec![], - }, - OffenceDetails { - offender: (21, Staking::stakers(&21)), - reporters: vec![], - }, - ], - &[Perbill::from_percent(50), Perbill::from_percent(20)], - ); + ExtBuilder::default().invulnerables(vec![11]).build().execute_with(|| { + #[cfg(feature = "equalize")] + let initial_balance = 1250; + #[cfg(not(feature = "equalize"))] + let initial_balance = 1375; + + assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(&21), 2000); + assert_eq!(Staking::stakers(&21).total, initial_balance); + + Staking::on_offence( + &[ + OffenceDetails { + offender: (11, Staking::stakers(&11)), + reporters: vec![], + }, + OffenceDetails { + offender: (21, Staking::stakers(&21)), + reporters: vec![], + }, + ], + &[Perbill::from_percent(50), Perbill::from_percent(20)], + ); - // The validator 11 hasn't been slashed, but 21 has been. - assert_eq!(Balances::free_balance(&11), 1000); - // 2000 - (0.2 * initial_balance) - assert_eq!(Balances::free_balance(&21), 2000 - (2 * initial_balance / 10)); - }, - ); + // The validator 11 hasn't been slashed, but 21 has been. + assert_eq!(Balances::free_balance(&11), 1000); + // 2000 - (0.2 * initial_balance) + assert_eq!(Balances::free_balance(&21), 2000 - (2 * initial_balance / 10)); + }); } #[test] fn dont_slash_if_fraction_is_zero() { // Don't slash if the fraction is zero. - set_and_run_with_externalities(&mut ExtBuilder::default().build(), || { + ExtBuilder::default().build().execute_with(|| { assert_eq!(Balances::free_balance(&11), 1000); Staking::on_offence( diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index 675e5b6ea8..96360b6c4e 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -173,10 +173,10 @@ macro_rules! assert_err { #[macro_export] #[cfg(feature = "std")] macro_rules! assert_ok { - ( $x:expr ) => { + ( $x:expr $(,)? ) => { assert_eq!($x, Ok(())); }; - ( $x:expr, $y:expr ) => { + ( $x:expr, $y:expr $(,)? ) => { assert_eq!($x, Ok($y)); } } @@ -236,7 +236,6 @@ pub use serde::{Serialize, Deserialize}; mod tests { use super::*; use codec::{Codec, EncodeLike}; - use sr_primitives::set_and_run_with_externalities; use srml_metadata::{ DecodeDifferent, StorageEntryMetadata, StorageMetadata, StorageEntryType, StorageEntryModifier, DefaultByteGetter, StorageHasher, @@ -288,7 +287,7 @@ mod tests { #[test] fn linked_map_issue_3318() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { OptionLinkedMap::insert(1, 1); assert_eq!(OptionLinkedMap::get(1), Some(1)); OptionLinkedMap::insert(1, 2); @@ -298,7 +297,7 @@ mod tests { #[test] fn linked_map_swap_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { OptionLinkedMap::insert(0, 0); OptionLinkedMap::insert(1, 1); OptionLinkedMap::insert(2, 2); @@ -327,7 +326,7 @@ mod tests { #[test] fn linked_map_basic_insert_remove_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // initialized during genesis assert_eq!(Map::get(&15u32), 42u64); @@ -353,7 +352,7 @@ mod tests { #[test] fn linked_map_enumeration_and_head_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(Map::head(), Some(15)); assert_eq!(Map::enumerate().collect::>(), vec![(15, 42)]); // insert / remove @@ -405,7 +404,7 @@ mod tests { #[test] fn double_map_basic_insert_remove_remove_prefix_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { type DoubleMap = DataDM; // initialized during genesis assert_eq!(DoubleMap::get(&15u32, &16u32), 42u64); @@ -445,7 +444,7 @@ mod tests { #[test] fn double_map_append_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { type DoubleMap = AppendableDM; let key1 = 17u32; diff --git a/srml/support/src/storage/storage_items.rs b/srml/support/src/storage/storage_items.rs index 4f8f194795..1854d703c0 100644 --- a/srml/support/src/storage/storage_items.rs +++ b/srml/support/src/storage/storage_items.rs @@ -759,7 +759,6 @@ mod test3 { #[allow(dead_code)] mod test_append_and_len { use runtime_io::TestExternalities; - use sr_primitives::set_and_run_with_externalities; use codec::{Encode, Decode}; pub trait Trait { @@ -801,7 +800,7 @@ mod test_append_and_len { #[test] fn default_for_option() { - set_and_run_with_externalities(&mut TestExternalities::default(), || { + TestExternalities::default().execute_with(|| { assert_eq!(OptionVec::get(), None); assert_eq!(JustVec::get(), vec![]); }); @@ -809,7 +808,7 @@ mod test_append_and_len { #[test] fn append_works() { - set_and_run_with_externalities(&mut TestExternalities::default(), || { + TestExternalities::default().execute_with(|| { let _ = MapVec::append(1, [1, 2, 3].iter()); let _ = MapVec::append(1, [4, 5].iter()); assert_eq!(MapVec::get(1), vec![1, 2, 3, 4, 5]); @@ -822,7 +821,7 @@ mod test_append_and_len { #[test] fn append_works_for_default() { - set_and_run_with_externalities(&mut TestExternalities::default(), || { + TestExternalities::default().execute_with(|| { assert_eq!(JustVecWithDefault::get(), vec![6, 9]); let _ = JustVecWithDefault::append([1].iter()); assert_eq!(JustVecWithDefault::get(), vec![6, 9, 1]); @@ -839,7 +838,7 @@ mod test_append_and_len { #[test] fn append_or_put_works() { - set_and_run_with_externalities(&mut TestExternalities::default(), || { + TestExternalities::default().execute_with(|| { let _ = MapVec::append_or_insert(1, &[1, 2, 3][..]); let _ = MapVec::append_or_insert(1, &[4, 5][..]); assert_eq!(MapVec::get(1), vec![1, 2, 3, 4, 5]); @@ -856,7 +855,7 @@ mod test_append_and_len { #[test] fn len_works() { - set_and_run_with_externalities(&mut TestExternalities::default(), || { + TestExternalities::default().execute_with(|| { JustVec::put(&vec![1, 2, 3, 4]); OptionVec::put(&vec![1, 2, 3, 4, 5]); MapVec::insert(1, &vec![1, 2, 3, 4, 5, 6]); @@ -871,7 +870,7 @@ mod test_append_and_len { #[test] fn len_works_for_default() { - set_and_run_with_externalities(&mut TestExternalities::default(), || { + TestExternalities::default().execute_with(|| { // vec assert_eq!(JustVec::get(), vec![]); assert_eq!(JustVec::decode_len(), Ok(0)); diff --git a/srml/support/test/tests/instance.rs b/srml/support/test/tests/instance.rs index c7a2d25eed..a8465adfd7 100644 --- a/srml/support/test/tests/instance.rs +++ b/srml/support/test/tests/instance.rs @@ -15,10 +15,7 @@ // along with Substrate. If not, see . #![recursion_limit="128"] -use sr_primitives::{ - generic, BuildStorage, traits::{BlakeTwo256, Block as _, Verify}, - set_and_run_with_externalities, -}; +use sr_primitives::{generic, BuildStorage, traits::{BlakeTwo256, Block as _, Verify}}; use support::{ Parameter, traits::Get, parameter_types, metadata::{ @@ -331,7 +328,7 @@ fn storage_instance_independance() { #[test] fn storage_with_instance_basic_operation() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { type Value = module2::Value; type Map = module2::Map; type LinkedMap = module2::LinkedMap; diff --git a/srml/system/benches/bench.rs b/srml/system/benches/bench.rs index 89e9af9525..1b18b55fd2 100644 --- a/srml/system/benches/bench.rs +++ b/srml/system/benches/bench.rs @@ -18,9 +18,7 @@ use criterion::{Criterion, criterion_group, criterion_main, black_box}; use srml_system as system; use support::{decl_module, decl_event, impl_outer_origin, impl_outer_event}; use primitives::H256; -use sr_primitives::{ - set_and_run_with_externalities, Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header, -}; +use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; mod module { use super::*; @@ -89,7 +87,7 @@ fn new_test_ext() -> runtime_io::TestExternalities { fn deposit_events(n: usize) { let mut t = new_test_ext(); - set_and_run_with_externalities(&mut t, || { + t.execute_with(|| { for _ in 0..n { module::Module::::deposit_event( module::Event::Complex(vec![1, 2, 3], 2, 3, 899) diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index 065b23bda1..7c90f21240 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -1091,10 +1091,7 @@ impl Lookup for ChainContext { mod tests { use super::*; use primitives::H256; - use sr_primitives::{ - traits::{BlakeTwo256, IdentityLookup}, testing::Header, DispatchError, - set_and_run_with_externalities, - }; + use sr_primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header, DispatchError}; use support::{impl_outer_origin, parameter_types}; impl_outer_origin! { @@ -1164,7 +1161,7 @@ mod tests { #[test] fn deposit_event_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { System::initialize(&1, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); System::note_finished_extrinsics(); System::deposit_event(1u16); @@ -1201,10 +1198,15 @@ mod tests { #[test] fn deposit_event_topics() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { const BLOCK_NUMBER: u64 = 1; - System::initialize(&BLOCK_NUMBER, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); + System::initialize( + &BLOCK_NUMBER, + &[0u8; 32].into(), + &[0u8; 32].into(), + &Default::default(), + ); System::note_finished_extrinsics(); let topics = vec![ @@ -1261,7 +1263,7 @@ mod tests { #[test] fn prunes_block_hash_mappings() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // simulate import of 15 blocks for n in 1..=15 { System::initialize( @@ -1294,7 +1296,7 @@ mod tests { #[test] fn signed_ext_check_nonce_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { >::insert(1, 1); let info = DispatchInfo::default(); let len = 0_usize; @@ -1312,7 +1314,7 @@ mod tests { #[test] fn signed_ext_check_weight_works_normal_tx() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let normal_limit = normal_weight_limit(); let small = DispatchInfo { weight: 100, ..Default::default() }; let medium = DispatchInfo { @@ -1339,7 +1341,7 @@ mod tests { #[test] fn signed_ext_check_weight_fee_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let free = DispatchInfo { weight: 0, ..Default::default() }; let len = 0_usize; @@ -1352,7 +1354,7 @@ mod tests { #[test] fn signed_ext_check_weight_max_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let max = DispatchInfo { weight: Weight::max_value(), ..Default::default() }; let len = 0_usize; let normal_limit = normal_weight_limit(); @@ -1366,7 +1368,7 @@ mod tests { #[test] fn signed_ext_check_weight_works_operational_tx() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let normal = DispatchInfo { weight: 100, ..Default::default() }; let op = DispatchInfo { weight: 100, class: DispatchClass::Operational }; let len = 0_usize; @@ -1389,7 +1391,7 @@ mod tests { #[test] fn signed_ext_check_weight_priority_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal }; let op = DispatchInfo { weight: 100, class: DispatchClass::Operational }; let len = 0_usize; @@ -1410,7 +1412,7 @@ mod tests { #[test] fn signed_ext_check_weight_block_size_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let normal = DispatchInfo::default(); let normal_limit = normal_weight_limit() as usize; let reset_check_weight = |tx, s, f| { @@ -1434,7 +1436,7 @@ mod tests { #[test] fn signed_ext_check_era_should_work() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // future assert_eq!( CheckEra::::from(Era::mortal(4, 2)).additional_signed().err().unwrap(), @@ -1450,7 +1452,7 @@ mod tests { #[test] fn signed_ext_check_era_should_change_longevity() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal }; let len = 0_usize; let ext = ( diff --git a/srml/timestamp/src/lib.rs b/srml/timestamp/src/lib.rs index 8ed3aa8dc0..cdacb8a391 100644 --- a/srml/timestamp/src/lib.rs +++ b/srml/timestamp/src/lib.rs @@ -324,10 +324,7 @@ mod tests { use support::{impl_outer_origin, assert_ok, parameter_types}; use runtime_io::TestExternalities; use primitives::H256; - use sr_primitives::{ - Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header, - set_and_run_with_externalities, - }; + use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; impl_outer_origin! { pub enum Origin for Test {} @@ -372,7 +369,7 @@ mod tests { #[test] fn timestamp_works() { let t = system::GenesisConfig::default().build_storage::().unwrap(); - set_and_run_with_externalities(&mut TestExternalities::new(t), || { + TestExternalities::new(t).execute_with(|| { Timestamp::set_timestamp(42); assert_ok!(Timestamp::dispatch(Call::set(69), Origin::NONE)); assert_eq!(Timestamp::now(), 69); @@ -383,7 +380,7 @@ mod tests { #[should_panic(expected = "Timestamp must be updated only once in the block")] fn double_timestamp_should_fail() { let t = system::GenesisConfig::default().build_storage::().unwrap(); - set_and_run_with_externalities(&mut TestExternalities::new(t), || { + TestExternalities::new(t).execute_with(|| { Timestamp::set_timestamp(42); assert_ok!(Timestamp::dispatch(Call::set(69), Origin::NONE)); let _ = Timestamp::dispatch(Call::set(70), Origin::NONE); @@ -394,7 +391,7 @@ mod tests { #[should_panic(expected = "Timestamp must increment by at least between sequential blocks")] fn block_period_minimum_enforced() { let t = system::GenesisConfig::default().build_storage::().unwrap(); - set_and_run_with_externalities(&mut TestExternalities::new(t), || { + TestExternalities::new(t).execute_with(|| { Timestamp::set_timestamp(42); let _ = Timestamp::dispatch(Call::set(46), Origin::NONE); }); diff --git a/srml/treasury/src/lib.rs b/srml/treasury/src/lib.rs index 8ccc260fa7..d5b3e6e55f 100644 --- a/srml/treasury/src/lib.rs +++ b/srml/treasury/src/lib.rs @@ -358,8 +358,7 @@ mod tests { use support::{assert_noop, assert_ok, impl_outer_origin, parameter_types}; use primitives::H256; use sr_primitives::{ - traits::{BlakeTwo256, OnFinalize, IdentityLookup}, set_and_run_with_externalities, - testing::Header, assert_eq_error_rate, + traits::{BlakeTwo256, OnFinalize, IdentityLookup}, testing::Header, assert_eq_error_rate, }; impl_outer_origin! { @@ -446,7 +445,7 @@ mod tests { #[test] fn genesis_config_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(Treasury::pot(), 0); assert_eq!(Treasury::proposal_count(), 0); }); @@ -454,7 +453,7 @@ mod tests { #[test] fn minting_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { // Check that accumulate works when we have Some value in Dummy already. Treasury::on_dilution(100, 100); assert_eq!(Treasury::pot(), 100); @@ -465,7 +464,7 @@ mod tests { fn minting_works_2() { let tests = [(1, 10), (1, 20), (40, 130), (2, 66), (2, 67), (2, 100), (2, 101), (2, 134)]; for &(minted, portion) in &tests { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let init_total_issuance = Balances::total_issuance(); Treasury::on_dilution(minted, portion); @@ -489,7 +488,7 @@ mod tests { #[test] fn spend_proposal_takes_min_deposit() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_ok!(Treasury::propose_spend(Origin::signed(0), 1, 3)); assert_eq!(Balances::free_balance(&0), 99); assert_eq!(Balances::reserved_balance(&0), 1); @@ -498,7 +497,7 @@ mod tests { #[test] fn spend_proposal_takes_proportional_deposit() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); assert_eq!(Balances::free_balance(&0), 95); assert_eq!(Balances::reserved_balance(&0), 5); @@ -507,14 +506,14 @@ mod tests { #[test] fn spend_proposal_fails_when_proposer_poor() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_noop!(Treasury::propose_spend(Origin::signed(2), 100, 3), "Proposer's balance too low"); }); } #[test] fn accepted_spend_proposal_ignored_outside_spend_period() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { Treasury::on_dilution(100, 100); assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); @@ -528,7 +527,7 @@ mod tests { #[test] fn unused_pot_should_diminish() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { let init_total_issuance = Balances::total_issuance(); Treasury::on_dilution(100, 100); assert_eq!(Balances::total_issuance(), init_total_issuance + 100); @@ -541,7 +540,7 @@ mod tests { #[test] fn rejected_spend_proposal_ignored_on_spend_period() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { Treasury::on_dilution(100, 100); assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); @@ -555,7 +554,7 @@ mod tests { #[test] fn reject_already_rejected_spend_proposal_fails() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { Treasury::on_dilution(100, 100); assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); @@ -566,21 +565,21 @@ mod tests { #[test] fn reject_non_existant_spend_proposal_fails() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_noop!(Treasury::reject_proposal(Origin::ROOT, 0), "No proposal at that index"); }); } #[test] fn accept_non_existant_spend_proposal_fails() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_noop!(Treasury::approve_proposal(Origin::ROOT, 0), "No proposal at that index"); }); } #[test] fn accept_already_rejected_spend_proposal_fails() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { Treasury::on_dilution(100, 100); assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); @@ -591,7 +590,7 @@ mod tests { #[test] fn accepted_spend_proposal_enacted_on_spend_period() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { Treasury::on_dilution(100, 100); assert_eq!(Treasury::pot(), 100); @@ -606,7 +605,7 @@ mod tests { #[test] fn pot_underflow_should_not_diminish() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { Treasury::on_dilution(100, 100); assert_ok!(Treasury::propose_spend(Origin::signed(0), 150, 3)); diff --git a/srml/utility/src/lib.rs b/srml/utility/src/lib.rs index a9009a3a7e..52675d24fc 100644 --- a/srml/utility/src/lib.rs +++ b/srml/utility/src/lib.rs @@ -65,10 +65,7 @@ mod tests { use support::{assert_ok, assert_noop, impl_outer_origin, parameter_types, impl_outer_dispatch}; use primitives::H256; - use sr_primitives::{ - Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header, - set_and_run_with_externalities, - }; + use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; impl_outer_origin! { pub enum Origin for Test {} @@ -150,7 +147,7 @@ mod tests { #[test] fn batch_works() { - set_and_run_with_externalities(&mut new_test_ext(), || { + new_test_ext().execute_with(|| { assert_eq!(Balances::free_balance(1), 10); assert_eq!(Balances::free_balance(2), 0); assert_noop!(Utility::batch(Origin::signed(1), vec![ -- GitLab From ce03f373c88e28f7d23df64f8d4e2f3588c6ca3f Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Fri, 11 Oct 2019 13:59:26 +0200 Subject: [PATCH 205/275] Fix semantics of ExistenceRequirement::KeepAlive. (#3796) * Fix semantics of ExistenceRequirement::KeepAlive. * Bump runtime version --- node/runtime/src/lib.rs | 2 +- srml/balances/src/lib.rs | 11 +++++++++-- srml/balances/src/tests.rs | 36 ++++++++++++++++++++++++++++++++++++ srml/support/src/traits.rs | 3 +++ 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 6ecce4c481..70b1b8f16a 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -84,7 +84,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 174, + spec_version: 175, impl_version: 175, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/balances/src/lib.rs b/srml/balances/src/lib.rs index 03e32e1ddf..b75c7a96de 100644 --- a/srml/balances/src/lib.rs +++ b/srml/balances/src/lib.rs @@ -947,8 +947,15 @@ where reason: WithdrawReason, liveness: ExistenceRequirement, ) -> result::Result { - if let Some(new_balance) = Self::free_balance(who).checked_sub(&value) { - if liveness == ExistenceRequirement::KeepAlive && new_balance < T::ExistentialDeposit::get() { + let old_balance = Self::free_balance(who); + if let Some(new_balance) = old_balance.checked_sub(&value) { + // if we need to keep the account alive... + if liveness == ExistenceRequirement::KeepAlive + // ...and it would be dead afterwards... + && new_balance < T::ExistentialDeposit::get() + // ...yet is was alive before + && old_balance >= T::ExistentialDeposit::get() + { return Err("payment would kill account") } Self::ensure_can_withdraw(who, value, reason, new_balance)?; diff --git a/srml/balances/src/tests.rs b/srml/balances/src/tests.rs index 3e7cb9a133..0b119d3ae6 100644 --- a/srml/balances/src/tests.rs +++ b/srml/balances/src/tests.rs @@ -25,6 +25,7 @@ use support::{ traits::{LockableCurrency, LockIdentifier, WithdrawReason, WithdrawReasons, Currency, ReservableCurrency} }; +use sr_primitives::weights::DispatchClass; use system::RawOrigin; const ID_1: LockIdentifier = *b"1 "; @@ -783,6 +784,41 @@ fn signed_extension_take_fees_is_bounded() { }); } +#[test] +fn signed_extension_allows_free_transactions() { + ExtBuilder::default() + .transaction_fees(100, 1, 1) + .monied(false) + .build() + .execute_with(|| { + // 1 ain't have a penny. + assert_eq!(Balances::free_balance(&1), 0); + + // like a FreeOperational + let operational_transaction = DispatchInfo { + weight: 0, + class: DispatchClass::Operational + }; + let len = 100; + assert!( + TakeFees::::from(0) + .validate(&1, CALL, operational_transaction , len) + .is_ok() + ); + + // like a FreeNormal + let free_transaction = DispatchInfo { + weight: 0, + class: DispatchClass::Normal + }; + assert!( + TakeFees::::from(0) + .validate(&1, CALL, free_transaction , len) + .is_err() + ); + }); +} + #[test] fn burn_must_work() { ExtBuilder::default().monied(true).build().execute_with(|| { diff --git a/srml/support/src/traits.rs b/srml/support/src/traits.rs index 694e6ec4b0..cd11b56612 100644 --- a/srml/support/src/traits.rs +++ b/srml/support/src/traits.rs @@ -156,6 +156,9 @@ impl OnUnbalanced for () { #[derive(Copy, Clone, Eq, PartialEq)] pub enum ExistenceRequirement { /// Operation must not result in the account going out of existence. + /// + /// Note this implies that if the account never existed in the first place, then the operation + /// may legitimately leave the account unchanged and still non-existent. KeepAlive, /// Operation may result in account going out of existence. AllowDeath, -- GitLab From 0cd9bbfb721b5f0f31982f681bdf1e77612ecc79 Mon Sep 17 00:00:00 2001 From: Caio Date: Fri, 11 Oct 2019 20:16:51 -0300 Subject: [PATCH 206/275] Fix Typo (#3805) The `chain::error::FutureResult` doc is currently referring to the wrong structure --- core/rpc/api/src/chain/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/rpc/api/src/chain/error.rs b/core/rpc/api/src/chain/error.rs index eccb7f4f1b..454c0887ab 100644 --- a/core/rpc/api/src/chain/error.rs +++ b/core/rpc/api/src/chain/error.rs @@ -23,7 +23,7 @@ use jsonrpc_core as rpc; /// Chain RPC Result type. pub type Result = std::result::Result; -/// State RPC future Result type. +/// Chain RPC future Result type. pub type FutureResult = Box + Send>; /// Chain RPC errors. -- GitLab From 3704e29d8df0d1aca0d2f766bbc79c2d69ae4bee Mon Sep 17 00:00:00 2001 From: yjh Date: Sat, 12 Oct 2019 17:32:29 +0800 Subject: [PATCH 207/275] fix comments (#3808) Signed-off-by: yjhmelody <465402634@qq.com> --- core/sr-primitives/src/traits.rs | 2 +- srml/system/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/sr-primitives/src/traits.rs b/core/sr-primitives/src/traits.rs index 10c2e80658..f94a71d38a 100644 --- a/core/sr-primitives/src/traits.rs +++ b/core/sr-primitives/src/traits.rs @@ -611,7 +611,7 @@ pub trait IsMember { } /// Something which fulfills the abstract idea of a Substrate header. It has types for a `Number`, -/// a `Hash` and a `Digest`. It provides access to an `extrinsics_root`, `state_root` and +/// a `Hash` and a `Hashing`. It provides access to an `extrinsics_root`, `state_root` and /// `parent_hash`, as well as a `digest` and a block `number`. /// /// You can also create a `new` one from those fields. diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index 7c90f21240..71c99af3b3 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -48,7 +48,7 @@ //! //! - [`CheckWeight`]: Checks the weight and length of the block and ensure that it does not //! exceed the limits. -//! - ['CheckNonce']: Checks the nonce of the transaction. Contains a single payload of type +//! - [`CheckNonce`]: Checks the nonce of the transaction. Contains a single payload of type //! `T::Index`. //! - [`CheckEra`]: Checks the era of the transaction. Contains a single payload of type `Era`. //! - [`CheckGenesis`]: Checks the provided genesis hash of the transaction. Must be a part of the -- GitLab From e9db00f87b643c8506e70d0fdce3bae58026e469 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Sat, 12 Oct 2019 16:12:03 +0100 Subject: [PATCH 208/275] node: re-use testnet genesis spec for staging testnet (#3802) --- node/cli/src/chain_spec.rs | 113 ++++++++----------------------------- 1 file changed, 25 insertions(+), 88 deletions(-) diff --git a/node/cli/src/chain_spec.rs b/node/cli/src/chain_spec.rs index 905e867436..d81591290e 100644 --- a/node/cli/src/chain_spec.rs +++ b/node/cli/src/chain_spec.rs @@ -117,83 +117,19 @@ fn staging_testnet_config_genesis() -> GenesisConfig { )]; // generated with secret: subkey inspect "$secret"/fir - let endowed_accounts: Vec = vec![ + let root_key: AccountId = hex![ // 5Ff3iXP75ruzroPWRP2FYBHWnmGGBSb63857BgnzCoXNxfPo - hex!["9ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809"].unchecked_into(), - ]; + "9ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809" + ].unchecked_into(); - const ENDOWMENT: Balance = 10_000_000 * DOLLARS; - const STASH: Balance = 100 * DOLLARS; + let endowed_accounts: Vec = vec![root_key.clone()]; - GenesisConfig { - system: Some(SystemConfig { - code: WASM_BINARY.to_vec(), - changes_trie_config: Default::default(), - }), - balances: Some(BalancesConfig { - balances: endowed_accounts.iter().cloned() - .map(|k| (k, ENDOWMENT)) - .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) - .collect(), - vesting: vec![], - }), - indices: Some(IndicesConfig { - ids: endowed_accounts.iter().cloned() - .chain(initial_authorities.iter().map(|x| x.0.clone())) - .collect::>(), - }), - session: Some(SessionConfig { - keys: initial_authorities.iter().map(|x| { - (x.0.clone(), session_keys(x.2.clone(), x.3.clone(), x.4.clone())) - }).collect::>(), - }), - staking: Some(StakingConfig { - current_era: 0, - validator_count: 7, - minimum_validator_count: 4, - stakers: initial_authorities.iter().map(|x| { - (x.0.clone(), x.1.clone(), STASH, StakerStatus::Validator) - }).collect(), - invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(), - slash_reward_fraction: Perbill::from_percent(10), - .. Default::default() - }), - democracy: Some(DemocracyConfig::default()), - collective_Instance1: Some(CouncilConfig { - members: vec![], - phantom: Default::default(), - }), - collective_Instance2: Some(TechnicalCommitteeConfig { - members: vec![], - phantom: Default::default(), - }), - elections: Some(ElectionsConfig { - members: vec![], - presentation_duration: 1 * DAYS, - term_duration: 28 * DAYS, - desired_seats: 0, - }), - contracts: Some(ContractsConfig { - current_schedule: Default::default(), - gas_price: 1 * MILLICENTS, - }), - sudo: Some(SudoConfig { - key: endowed_accounts[0].clone(), - }), - babe: Some(BabeConfig { - authorities: vec![], - }), - im_online: Some(ImOnlineConfig { - keys: vec![], - }), - authority_discovery: Some(AuthorityDiscoveryConfig{ - keys: vec![], - }), - grandpa: Some(GrandpaConfig { - authorities: vec![], - }), - membership_Instance1: Some(Default::default()), - } + testnet_genesis( + initial_authorities, + root_key, + Some(endowed_accounts), + false, + ) } /// Staging testnet config. @@ -257,20 +193,23 @@ pub fn testnet_genesis( const ENDOWMENT: Balance = 10_000_000 * DOLLARS; const STASH: Balance = 100 * DOLLARS; - let desired_seats = (endowed_accounts.len() / 2 - initial_authorities.len()) as u32; - GenesisConfig { system: Some(SystemConfig { code: WASM_BINARY.to_vec(), changes_trie_config: Default::default(), }), - indices: Some(IndicesConfig { - ids: endowed_accounts.clone(), - }), balances: Some(BalancesConfig { - balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(), + balances: endowed_accounts.iter().cloned() + .map(|k| (k, ENDOWMENT)) + .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) + .collect(), vesting: vec![], }), + indices: Some(IndicesConfig { + ids: endowed_accounts.iter().cloned() + .chain(initial_authorities.iter().map(|x| x.0.clone())) + .collect::>(), + }), session: Some(SessionConfig { keys: initial_authorities.iter().map(|x| { (x.0.clone(), session_keys(x.2.clone(), x.3.clone(), x.4.clone())) @@ -278,8 +217,8 @@ pub fn testnet_genesis( }), staking: Some(StakingConfig { current_era: 0, - minimum_validator_count: 1, - validator_count: 2, + validator_count: initial_authorities.len() as u32 * 2, + minimum_validator_count: initial_authorities.len() as u32, stakers: initial_authorities.iter().map(|x| { (x.0.clone(), x.1.clone(), STASH, StakerStatus::Validator) }).collect(), @@ -297,12 +236,10 @@ pub fn testnet_genesis( phantom: Default::default(), }), elections: Some(ElectionsConfig { - members: endowed_accounts.iter() - .filter(|&endowed| initial_authorities.iter().find(|&(_, controller, ..)| controller == endowed).is_none()) - .map(|a| (a.clone(), 1000000)).collect(), - presentation_duration: 10, - term_duration: 1000000, - desired_seats: desired_seats, + members: vec![], + presentation_duration: 1 * DAYS, + term_duration: 28 * DAYS, + desired_seats: 0, }), contracts: Some(ContractsConfig { current_schedule: contracts::Schedule { -- GitLab From 02622d9c048e1cfbd24e5d13676ab8f48c0b84a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Sat, 12 Oct 2019 18:31:49 +0100 Subject: [PATCH 209/275] deps: update clap and structopt (#3809) --- Cargo.lock | 60 +++++++----- core/cli/Cargo.toml | 4 +- core/cli/src/execution_strategy.rs | 2 +- core/cli/src/params.rs | 112 +++++++++-------------- node/cli/Cargo.toml | 4 +- node/cli/src/lib.rs | 8 +- scripts/node-template-release/Cargo.toml | 2 +- subkey/Cargo.toml | 2 +- test-utils/chain-spec-builder/Cargo.toml | 2 +- 9 files changed, 92 insertions(+), 104 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6e7dea9d1d..5a17eaed31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -197,7 +197,7 @@ dependencies = [ "cexpr 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "clang-sys 0.26.4 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -400,7 +400,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "chain-spec-builder" version = "2.0.0" dependencies = [ - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "node-cli 2.0.0", "substrate-primitives 2.0.0", "substrate-service 2.0.0", @@ -429,14 +429,14 @@ dependencies = [ [[package]] name = "clap" -version = "2.32.0" +version = "2.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -518,7 +518,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2355,7 +2355,7 @@ dependencies = [ "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", - "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-authority-discovery 2.0.0", "substrate-basic-authorship 2.0.0", "substrate-chain-spec 2.0.0", @@ -3009,6 +3009,16 @@ dependencies = [ "toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "proc-macro-error" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "proc-macro-hack" version = "0.5.10" @@ -4501,27 +4511,28 @@ dependencies = [ [[package]] name = "strsim" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "structopt" -version = "0.2.18" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt-derive 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "structopt-derive" -version = "0.2.18" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-error 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4544,7 +4555,7 @@ dependencies = [ name = "subkey" version = "2.0.0" dependencies = [ - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", @@ -4677,7 +4688,7 @@ dependencies = [ "ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4691,7 +4702,7 @@ dependencies = [ "rpassword 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", - "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-client 2.0.0", "substrate-header-metadata 2.0.0", "substrate-keyring 2.0.0", @@ -5726,7 +5737,7 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6648,7 +6659,7 @@ dependencies = [ "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e8493056968583b0193c1bb04d6f7684586f3726992d6c573261941a895dbd68" "checksum clang-sys 0.26.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ef0c1bcf2e99c649104bd7a7012d8f8802684400e03db0ec0af48583c6fa0e4" -"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" +"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62" @@ -6881,6 +6892,7 @@ dependencies = [ "checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427" "checksum primitive-types 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "83ef7b3b965c0eadcb6838f34f827e1dfb2939bdd5ebd43f9647e009b12b0371" "checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" +"checksum proc-macro-error 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aeccfe4d5d8ea175d5f0e4a2ad0637e0f4121d63bd99d356fb1f39ab2e7c6097" "checksum proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "114cdf1f426eb7f550f01af5f53a33c0946156f6814aec939b3bd77e844f9a9d" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "90cf5f418035b98e655e9cdb225047638296b862b42411c4e45bb88d700f7fc0" @@ -6972,9 +6984,9 @@ dependencies = [ "checksum static_slice 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "92a7e0c5e3dfb52e8fbe0e63a1b947bbb17b4036408b151353c4491374931362" "checksum stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8131256a5896cabcf5eb04f4d6dacbe1aefda854b0d9896e09cb58829ec5638c" "checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" -"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" -"checksum structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "16c2cdbf9cc375f15d1b4141bc48aeef444806655cd0e904207edc8d68d86ed7" -"checksum structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107" +"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +"checksum structopt 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4f66a4c0ddf7aee4677995697366de0749b0139057342eccbb609b12d0affc" +"checksum structopt-derive 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8fe0c13e476b4e21ff7f5c4ace3818b6d7bdc16897c31c73862471bc1663acae" "checksum strum 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d1c33039533f051704951680f1adfd468fd37ac46816ded0d9ee068e60f05f" "checksum strum_macros 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "47cd23f5c7dee395a00fa20135e2ec0fffcdfa151c56182966d7a3261343432e" "checksum substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3be511be555a3633e71739a79e4ddff6a6aaa6579fa6114182a51d72c3eb93c5" @@ -6990,7 +7002,7 @@ dependencies = [ "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" -"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" +"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c5676413eaeb1ea35300a0224416f57abc3bd251657e0fafc12c47ff98c060" diff --git a/core/cli/Cargo.toml b/core/cli/Cargo.toml index b1cb1d57ca..a2723484ad 100644 --- a/core/cli/Cargo.toml +++ b/core/cli/Cargo.toml @@ -6,7 +6,7 @@ description = "Substrate CLI interface." edition = "2018" [dependencies] -clap = "~2.32.0" +clap = "2.33.0" derive_more = "0.15.0" env_logger = "0.7.0" log = "0.4.8" @@ -33,7 +33,7 @@ state-machine = { package = "substrate-state-machine", path = "../../core/state- substrate-telemetry = { path = "../../core/telemetry" } keyring = { package = "substrate-keyring", path = "../keyring" } names = "0.11.0" -structopt = "0.2.0" +structopt = "0.3.3" rpassword = "4.0.1" [dev-dependencies] diff --git a/core/cli/src/execution_strategy.rs b/core/cli/src/execution_strategy.rs index bd3030906e..93236227e5 100644 --- a/core/cli/src/execution_strategy.rs +++ b/core/cli/src/execution_strategy.rs @@ -16,7 +16,7 @@ #![allow(missing_docs)] -use structopt::clap::{arg_enum, _clap_count_exprs}; +use structopt::clap::arg_enum; arg_enum! { /// How to execute blocks diff --git a/core/cli/src/params.rs b/core/cli/src/params.rs index b453c7dabd..b949b336de 100644 --- a/core/cli/src/params.rs +++ b/core/cli/src/params.rs @@ -17,7 +17,7 @@ use crate::traits::{AugmentClap, GetLogFilter}; use std::path::PathBuf; -use structopt::{StructOpt, clap::{arg_enum, App, AppSettings, _clap_count_exprs, SubCommand, Arg}}; +use structopt::{StructOpt, clap::{arg_enum, App, AppSettings, SubCommand, Arg}}; pub use crate::execution_strategy::ExecutionStrategy; @@ -205,11 +205,9 @@ pub struct NodeKeyParams { #[structopt( long = "node-key-type", value_name = "TYPE", - raw( - possible_values = "&NodeKeyType::variants()", - case_insensitive = "true", - default_value = r#""Ed25519""# - ) + possible_values = &NodeKeyType::variants(), + case_insensitive = true, + default_value = "Ed25519" )] pub node_key_type: NodeKeyType, @@ -248,11 +246,9 @@ pub struct ExecutionStrategies { #[structopt( long = "execution-syncing", value_name = "STRATEGY", - raw( - possible_values = "&ExecutionStrategy::variants()", - case_insensitive = "true", - default_value = r#""NativeElseWasm""# - ) + possible_values = &ExecutionStrategy::variants(), + case_insensitive = true, + default_value = "NativeElseWasm" )] pub execution_syncing: ExecutionStrategy, @@ -260,11 +256,9 @@ pub struct ExecutionStrategies { #[structopt( long = "execution-import-block", value_name = "STRATEGY", - raw( - possible_values = "&ExecutionStrategy::variants()", - case_insensitive = "true", - default_value = r#""NativeElseWasm""# - ) + possible_values = &ExecutionStrategy::variants(), + case_insensitive = true, + default_value = "NativeElseWasm" )] pub execution_import_block: ExecutionStrategy, @@ -272,11 +266,9 @@ pub struct ExecutionStrategies { #[structopt( long = "execution-block-construction", value_name = "STRATEGY", - raw( - possible_values = "&ExecutionStrategy::variants()", - case_insensitive = "true", - default_value = r#""Wasm""# - ) + possible_values = &ExecutionStrategy::variants(), + case_insensitive = true, + default_value = "Wasm" )] pub execution_block_construction: ExecutionStrategy, @@ -284,11 +276,9 @@ pub struct ExecutionStrategies { #[structopt( long = "execution-offchain-worker", value_name = "STRATEGY", - raw( - possible_values = "&ExecutionStrategy::variants()", - case_insensitive = "true", - default_value = r#""Native""# - ) + possible_values = &ExecutionStrategy::variants(), + case_insensitive = true, + default_value = "Native" )] pub execution_offchain_worker: ExecutionStrategy, @@ -296,11 +286,9 @@ pub struct ExecutionStrategies { #[structopt( long = "execution-other", value_name = "STRATEGY", - raw( - possible_values = "&ExecutionStrategy::variants()", - case_insensitive = "true", - default_value = r#""Native""# - ) + possible_values = &ExecutionStrategy::variants(), + case_insensitive = true, + default_value = "Native" )] pub execution_other: ExecutionStrategy, @@ -308,17 +296,15 @@ pub struct ExecutionStrategies { #[structopt( long = "execution", value_name = "STRATEGY", - raw( - possible_values = "&ExecutionStrategy::variants()", - case_insensitive = "true", - conflicts_with_all = "&[ - \"execution_other\", - \"execution_offchain_worker\", - \"execution_block_construction\", - \"execution_import_block\", - \"execution_syncing\", - ]" - ) + possible_values = &ExecutionStrategy::variants(), + case_insensitive = true, + conflicts_with_all = &[ + "execution-other", + "execution-offchain-worker", + "execution-block-construction", + "execution-import-block", + "execution-syncing", + ] )] pub execution: Option, } @@ -377,7 +363,7 @@ pub struct RunCmd { /// allow localhost, https://polkadot.js.org and /// https://substrate-ui.parity.io origins. When running in --dev mode the /// default is to allow all origins. - #[structopt(long = "rpc-cors", value_name = "ORIGINS", parse(try_from_str = "parse_cors"))] + #[structopt(long = "rpc-cors", value_name = "ORIGINS", parse(try_from_str = parse_cors))] pub rpc_cors: Option, /// Specify the pruning mode, a number of blocks to keep or 'archive'. @@ -404,7 +390,7 @@ pub struct RunCmd { /// telemetry endpoints. Verbosity levels range from 0-9, with 0 denoting /// the least verbosity. If no verbosity level is specified the default is /// 0. - #[structopt(long = "telemetry-url", value_name = "URL VERBOSITY", parse(try_from_str = "parse_telemetry_endpoints"))] + #[structopt(long = "telemetry-url", value_name = "URL VERBOSITY", parse(try_from_str = parse_telemetry_endpoints))] pub telemetry_endpoints: Vec<(String, u8)>, /// Should execute offchain workers on every block. @@ -413,11 +399,9 @@ pub struct RunCmd { #[structopt( long = "offchain-worker", value_name = "ENABLED", - raw( - possible_values = "&OffchainWorkerEnabled::variants()", - case_insensitive = "true", - default_value = r#""WhenValidating""# - ) + possible_values = &OffchainWorkerEnabled::variants(), + case_insensitive = true, + default_value = "WhenValidating" )] pub offchain_worker: OffchainWorkerEnabled, @@ -425,11 +409,9 @@ pub struct RunCmd { #[structopt( long = "wasm-execution", value_name = "METHOD", - raw( - possible_values = "&WasmExecutionMethod::variants()", - case_insensitive = "true", - default_value = r#""Interpreted""# - ) + possible_values = &WasmExecutionMethod::variants(), + case_insensitive = true, + default_value = "Interpreted" )] pub wasm_method: WasmExecutionMethod, @@ -464,14 +446,14 @@ pub struct RunCmd { /// Use interactive shell for entering the password used by the keystore. #[structopt( long = "password-interactive", - raw(conflicts_with_all = "&[ \"password\", \"password_filename\" ]") + conflicts_with_all = &[ "password", "password-filename" ] )] pub password_interactive: bool, /// Password used by the keystore. #[structopt( long = "password", - raw(conflicts_with_all = "&[ \"password_interactive\", \"password_filename\" ]") + conflicts_with_all = &[ "password-interactive", "password-filename" ] )] pub password: Option, @@ -480,7 +462,7 @@ pub struct RunCmd { long = "password-filename", value_name = "PATH", parse(from_os_str), - raw(conflicts_with_all = "&[ \"password_interactive\", \"password\" ]") + conflicts_with_all = &[ "password-interactive", "password" ] )] pub password_filename: Option } @@ -684,11 +666,9 @@ pub struct ImportBlocksCmd { #[structopt( long = "wasm-execution", value_name = "METHOD", - raw( - possible_values = "&WasmExecutionMethod::variants()", - case_insensitive = "true", - default_value = r#""Interpreted""# - ) + possible_values = &WasmExecutionMethod::variants(), + case_insensitive = true, + default_value = "Interpreted" )] pub wasm_method: WasmExecutionMethod, @@ -696,11 +676,9 @@ pub struct ImportBlocksCmd { #[structopt( long = "execution", value_name = "STRATEGY", - raw( - possible_values = "&ExecutionStrategy::variants()", - case_insensitive = "true", - default_value = r#""NativeElseWasm""# - ) + possible_values = &ExecutionStrategy::variants(), + case_insensitive = true, + default_value = "NativeElseWasm" )] pub execution: ExecutionStrategy, } diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index ca3ec92630..0ddd7b49ff 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -35,7 +35,7 @@ grandpa_primitives = { package = "substrate-finality-grandpa-primitives", path = sr-primitives = { path = "../../core/sr-primitives" } node-executor = { path = "../executor" } substrate-telemetry = { package = "substrate-telemetry", path = "../../core/telemetry" } -structopt = "0.2.0" +structopt = "0.3.3" transaction-factory = { path = "../../test-utils/transaction-factory" } keyring = { package = "substrate-keyring", path = "../../core/keyring" } indices = { package = "srml-indices", path = "../../srml/indices" } @@ -63,4 +63,4 @@ tempfile = "3.1.0" [build-dependencies] cli = { package = "substrate-cli", path = "../../core/cli" } -structopt = "0.2.0" +structopt = "0.3.3" diff --git a/node/cli/src/lib.rs b/node/cli/src/lib.rs index a4deed37c1..7eb3bb89c3 100644 --- a/node/cli/src/lib.rs +++ b/node/cli/src/lib.rs @@ -108,11 +108,9 @@ pub struct FactoryCmd { #[structopt( long = "execution", value_name = "STRATEGY", - raw( - possible_values = "&ExecutionStrategyParam::variants()", - case_insensitive = "true", - default_value = r#""NativeElseWasm""# - ) + possible_values = &ExecutionStrategyParam::variants(), + case_insensitive = true, + default_value = "NativeElseWasm" )] pub execution: ExecutionStrategyParam, } diff --git a/scripts/node-template-release/Cargo.toml b/scripts/node-template-release/Cargo.toml index 34aadc971f..8a43435b20 100644 --- a/scripts/node-template-release/Cargo.toml +++ b/scripts/node-template-release/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" toml = "0.4" tar = "0.4" glob = "0.2" -structopt = "0.2" +structopt = "0.3" tempfile = "3" fs_extra = "1" git2 = "0.8" diff --git a/subkey/Cargo.toml b/subkey/Cargo.toml index 1b1a697d0f..d901b59d0b 100644 --- a/subkey/Cargo.toml +++ b/subkey/Cargo.toml @@ -10,7 +10,7 @@ node-runtime = { version = "*", path = "../node/runtime" } node-primitives = { version = "*", path = "../node/primitives" } sr-primitives = { version = "*", path = "../core/sr-primitives" } rand = "0.7.2" -clap = { version = "~2.32.0", features = ["yaml"] } +clap = { version = "2.33.0", features = ["yaml"] } tiny-bip39 = "0.6.2" rustc-hex = "2.0.1" substrate-bip39 = "0.3.1" diff --git a/test-utils/chain-spec-builder/Cargo.toml b/test-utils/chain-spec-builder/Cargo.toml index 0bd9b2c55c..478e230505 100644 --- a/test-utils/chain-spec-builder/Cargo.toml +++ b/test-utils/chain-spec-builder/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -clap = { version = "~2.32.0", features = ["yaml"] } +clap = { version = "2.33.0", features = ["yaml"] } node-cli = { path = "../../node/cli" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } substrate-service = { path = "../../core/service" } -- GitLab From 64192122e3ce9d059bb15ab3e674aa6ddf670cc8 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Sun, 13 Oct 2019 17:22:53 +0200 Subject: [PATCH 210/275] Update tests.rs (#3814) --- srml/staking/src/tests.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/srml/staking/src/tests.rs b/srml/staking/src/tests.rs index ca462b640b..2cb7981154 100644 --- a/srml/staking/src/tests.rs +++ b/srml/staking/src/tests.rs @@ -218,7 +218,6 @@ fn multi_era_reward_should_work() { // Compute now as other parameter won't change let total_payout_0 = current_total_payout_for_duration(3000); assert!(total_payout_0 > 10); // Test is meaningfull if reward something - dbg!(>::slot_stake()); >::reward_by_ids(vec![(11, 1)]); start_session(0); -- GitLab From e2ce9bfeeb149ff927032164d87b2f39e7da3be9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 14 Oct 2019 20:20:07 +0200 Subject: [PATCH 211/275] Provide macro for exporting functions from wasm (#3801) The macro generates the functions with the signature we expect for wasm functions. This macro is useful for tests where we need to call into wasm. Parameter passing is done by SCALE encoding the input and output parameters. --- core/executor/runtime-test/src/lib.rs | 185 ++++++++++++++------------ core/executor/src/sandbox.rs | 36 ++--- core/executor/src/wasmi_execution.rs | 115 ++++++++++------ core/primitives/src/lib.rs | 4 + core/primitives/src/testing.rs | 116 +++++++++++++++- 5 files changed, 312 insertions(+), 144 deletions(-) diff --git a/core/executor/runtime-test/src/lib.rs b/core/executor/runtime-test/src/lib.rs index 35f3191ffd..61eca8dd4e 100644 --- a/core/executor/runtime-test/src/lib.rs +++ b/core/executor/runtime-test/src/lib.rs @@ -5,48 +5,23 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -use rstd::{vec::Vec, slice, vec}; +#[cfg(not(feature = "std"))] +use rstd::{vec::Vec, vec}; +#[cfg(not(feature = "std"))] use runtime_io::{ set_storage, storage, clear_prefix, blake2_128, blake2_256, twox_128, twox_256, ed25519_verify, sr25519_verify, }; +#[cfg(not(feature = "std"))] use sr_primitives::{print, traits::{BlakeTwo256, Hash}}; +#[cfg(not(feature = "std"))] use primitives::{ed25519, sr25519}; -macro_rules! impl_stubs { - ( $( $new_name:ident => $invoke:expr, )* ) => { - $( - impl_stubs!(@METHOD $new_name => $invoke); - )* - }; - ( @METHOD $new_name:ident => $invoke:expr ) => { - #[no_mangle] - pub fn $new_name(input_data: *mut u8, input_len: usize) -> u64 { - let input: &[u8] = if input_len == 0 { - &[0u8; 0] - } else { - unsafe { - slice::from_raw_parts(input_data, input_len) - } - }; - - let output: Vec = $invoke(input); - let res = output.as_ptr() as u64 + ((output.len() as u64) << 32); - - // Leak the output vector to avoid it being freed. - // This is fine in a WASM context since the heap - // will be discarded after the call. - rstd::mem::forget(output); - res - } - }; -} - -impl_stubs!( - test_data_in => |input| { +primitives::wasm_export_functions! { + fn test_data_in(input: Vec) -> Vec { print("set_storage"); - set_storage(b"input", input); + set_storage(b"input", &input); print("storage"); let foo = storage(b"foo").unwrap(); @@ -56,25 +31,44 @@ impl_stubs!( print("finished!"); b"all ok!".to_vec() - }, - test_clear_prefix => |input| { - clear_prefix(input); + } + + fn test_clear_prefix(input: Vec) -> Vec { + clear_prefix(&input); b"all ok!".to_vec() - }, - test_empty_return => |_| Vec::new(), - test_exhaust_heap => |_| Vec::with_capacity(16777216), - test_panic => |_| panic!("test panic"), - test_conditional_panic => |input: &[u8]| { + } + + fn test_empty_return() {} + + fn test_exhaust_heap() -> Vec { Vec::with_capacity(16777216) } + + fn test_panic() { panic!("test panic") } + + fn test_conditional_panic(input: Vec) -> Vec { if input.len() > 0 { panic!("test panic") } - input.to_vec() - }, - test_blake2_256 => |input| blake2_256(input).to_vec(), - test_blake2_128 => |input| blake2_128(input).to_vec(), - test_twox_256 => |input| twox_256(input).to_vec(), - test_twox_128 => |input| twox_128(input).to_vec(), - test_ed25519_verify => |input: &[u8]| { + + input + } + + fn test_blake2_256(input: Vec) -> Vec { + blake2_256(&input).to_vec() + } + + fn test_blake2_128(input: Vec) -> Vec { + blake2_128(&input).to_vec() + } + + fn test_twox_256(input: Vec) -> Vec { + twox_256(&input).to_vec() + } + + fn test_twox_128(input: Vec) -> Vec { + twox_128(&input).to_vec() + } + + fn test_ed25519_verify(input: Vec) -> bool { let mut pubkey = [0; 32]; let mut sig = [0; 64]; @@ -82,9 +76,10 @@ impl_stubs!( sig.copy_from_slice(&input[32..96]); let msg = b"all ok!"; - [ed25519_verify(&ed25519::Signature(sig), &msg[..], &ed25519::Public(pubkey)) as u8].to_vec() - }, - test_sr25519_verify => |input: &[u8]| { + ed25519_verify(&ed25519::Signature(sig), &msg[..], &ed25519::Public(pubkey)) + } + + fn test_sr25519_verify(input: Vec) -> bool { let mut pubkey = [0; 32]; let mut sig = [0; 64]; @@ -92,9 +87,10 @@ impl_stubs!( sig.copy_from_slice(&input[32..96]); let msg = b"all ok!"; - [sr25519_verify(&sr25519::Signature(sig), &msg[..], &sr25519::Public(pubkey)) as u8].to_vec() - }, - test_ordered_trie_root => |_| { + sr25519_verify(&sr25519::Signature(sig), &msg[..], &sr25519::Public(pubkey)) + } + + fn test_ordered_trie_root() -> Vec { BlakeTwo256::ordered_trie_root( vec![ b"zero"[..].into(), @@ -102,24 +98,25 @@ impl_stubs!( b"two"[..].into(), ], ).as_ref().to_vec() - }, - test_sandbox => |code: &[u8]| { - let ok = execute_sandboxed(code, &[]).is_ok(); - [ok as u8].to_vec() - }, - test_sandbox_args => |code: &[u8]| { - let ok = execute_sandboxed( - code, + } + + fn test_sandbox(code: Vec) -> bool { + execute_sandboxed(&code, &[]).is_ok() + } + + fn test_sandbox_args(code: Vec) -> bool { + execute_sandboxed( + &code, &[ sandbox::TypedValue::I32(0x12345678), sandbox::TypedValue::I64(0x1234567887654321), - ] - ).is_ok(); - [ok as u8].to_vec() - }, - test_sandbox_return_val => |code: &[u8]| { + ], + ).is_ok() + } + + fn test_sandbox_return_val(code: Vec) -> bool { let ok = match execute_sandboxed( - code, + &code, &[ sandbox::TypedValue::I32(0x1336), ] @@ -127,41 +124,43 @@ impl_stubs!( Ok(sandbox::ReturnValue::Value(sandbox::TypedValue::I32(0x1337))) => true, _ => false, }; - [ok as u8].to_vec() - }, - test_sandbox_instantiate => |code: &[u8]| { + + ok + } + + fn test_sandbox_instantiate(code: Vec) -> u8 { let env_builder = sandbox::EnvironmentDefinitionBuilder::new(); - let code = match sandbox::Instance::new(code, &env_builder, &mut ()) { + let code = match sandbox::Instance::new(&code, &env_builder, &mut ()) { Ok(_) => 0, Err(sandbox::Error::Module) => 1, Err(sandbox::Error::Execution) => 2, Err(sandbox::Error::OutOfBounds) => 3, }; - [code].to_vec() - }, - test_offchain_local_storage => |_| { + + code + } + + fn test_offchain_local_storage() -> bool { let kind = primitives::offchain::StorageKind::PERSISTENT; assert_eq!(runtime_io::local_storage_get(kind, b"test"), None); runtime_io::local_storage_set(kind, b"test", b"asd"); assert_eq!(runtime_io::local_storage_get(kind, b"test"), Some(b"asd".to_vec())); let res = runtime_io::local_storage_compare_and_set(kind, b"test", Some(b"asd"), b""); - assert_eq!(res, true); assert_eq!(runtime_io::local_storage_get(kind, b"test"), Some(b"".to_vec())); + res + } - [0].to_vec() - }, - test_offchain_local_storage_with_none => |_| { + fn test_offchain_local_storage_with_none() { let kind = primitives::offchain::StorageKind::PERSISTENT; assert_eq!(runtime_io::local_storage_get(kind, b"test"), None); let res = runtime_io::local_storage_compare_and_set(kind, b"test", None, b"value"); assert_eq!(res, true); assert_eq!(runtime_io::local_storage_get(kind, b"test"), Some(b"value".to_vec())); + } - [0].to_vec() - }, - test_offchain_http => |_| { + fn test_offchain_http() -> bool { use primitives::offchain::HttpRequestStatus; let run = || -> Option<()> { let id = runtime_io::http_request_start("POST", "http://localhost:12345", &[]).ok()?; @@ -182,16 +181,23 @@ impl_stubs!( Some(()) }; - [if run().is_some() { 0 } else { 1 }].to_vec() - }, -); + run().is_some() + } + } -fn execute_sandboxed(code: &[u8], args: &[sandbox::TypedValue]) -> Result { +#[cfg(not(feature = "std"))] +fn execute_sandboxed( + code: &[u8], + args: &[sandbox::TypedValue], +) -> Result { struct State { counter: u32, } - fn env_assert(_e: &mut State, args: &[sandbox::TypedValue]) -> Result { + fn env_assert( + _e: &mut State, + args: &[sandbox::TypedValue], + ) -> Result { if args.len() != 1 { return Err(sandbox::HostError); } @@ -202,7 +208,10 @@ fn execute_sandboxed(code: &[u8], args: &[sandbox::TypedValue]) -> Result Result { + fn env_inc_counter( + e: &mut State, + args: &[sandbox::TypedValue], + ) -> Result { if args.len() != 1 { return Err(sandbox::HostError); } diff --git a/core/executor/src/sandbox.rs b/core/executor/src/sandbox.rs index 3a213ccdf0..c4122274a9 100644 --- a/core/executor/src/sandbox.rs +++ b/core/executor/src/sandbox.rs @@ -631,11 +631,11 @@ mod tests { call $assert ) ) - "#).unwrap(); + "#).unwrap().encode(); assert_eq!( call_wasm(&mut ext, 8, &test_code[..], "test_sandbox", &code).unwrap(), - vec![1], + true.encode(), ); } @@ -673,7 +673,7 @@ mod tests { call $assert ) ) - "#).unwrap(); + "#).unwrap().encode(); let res = call_wasm(&mut ext, 8, &test_code[..], "test_exhaust_heap", &code); assert_eq!(res.is_err(), true); @@ -718,11 +718,11 @@ mod tests { call $assert ) ) - "#).unwrap(); + "#).unwrap().encode(); assert_eq!( call_wasm(&mut ext, 8, &test_code[..], "test_sandbox", &code).unwrap(), - vec![1], + true.encode(), ); } @@ -752,11 +752,11 @@ mod tests { ) ) ) - "#).unwrap(); + "#).unwrap().encode(); assert_eq!( call_wasm(&mut ext, 8, &test_code[..], "test_sandbox_args", &code).unwrap(), - vec![1], + true.encode(), ); } @@ -774,11 +774,11 @@ mod tests { ) ) ) - "#).unwrap(); + "#).unwrap().encode(); assert_eq!( call_wasm(&mut ext, 8, &test_code[..], "test_sandbox_return_val", &code).unwrap(), - vec![1], + true.encode(), ); } @@ -794,11 +794,11 @@ mod tests { (func (export "call") ) ) - "#).unwrap(); + "#).unwrap().encode(); assert_eq!( call_wasm(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", &code).unwrap(), - vec![1], + 1u8.encode(), ); } @@ -808,11 +808,11 @@ mod tests { let test_code = WASM_BINARY; // Corrupted wasm file - let code = &[0, 0, 0, 0, 1, 0, 0, 0]; + let code = vec![0u8, 0, 0, 0, 1, 0, 0, 0].encode(); assert_eq!( - call_wasm(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", code).unwrap(), - vec![1], + call_wasm(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", &code).unwrap(), + 1u8.encode(), ); } @@ -831,11 +831,11 @@ mod tests { (start $start) ) - "#).unwrap(); + "#).unwrap().encode(); assert_eq!( call_wasm(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", &code).unwrap(), - vec![0], + 0u8.encode(), ); } @@ -855,11 +855,11 @@ mod tests { (start $start) ) - "#).unwrap(); + "#).unwrap().encode(); assert_eq!( call_wasm(&mut ext, 8, &test_code[..], "test_sandbox_instantiate", &code).unwrap(), - vec![2], + 2u8.encode(), ); } } diff --git a/core/executor/src/wasmi_execution.rs b/core/executor/src/wasmi_execution.rs index 0719ff4d40..ba7738a993 100644 --- a/core/executor/src/wasmi_execution.rs +++ b/core/executor/src/wasmi_execution.rs @@ -662,6 +662,7 @@ mod tests { use runtime_test::WASM_BINARY; use substrate_offchain::testing; use trie::{TrieConfiguration, trie_types::Layout}; + use codec::{Encode, Decode}; type TestExternalities = CoreTestExternalities; @@ -694,10 +695,10 @@ mod tests { let output = call(&mut ext, 8, &test_code[..], "test_panic", &[]); assert!(output.is_err()); - let output = call(&mut ext, 8, &test_code[..], "test_conditional_panic", &[]); - assert_eq!(output.unwrap(), vec![0u8; 0]); + let output = call(&mut ext, 8, &test_code[..], "test_conditional_panic", &[0]); + assert_eq!(Decode::decode(&mut &output.unwrap()[..]), Ok(Vec::::new())); - let output = call(&mut ext, 8, &test_code[..], "test_conditional_panic", &[2]); + let output = call(&mut ext, 8, &test_code[..], "test_conditional_panic", &vec![2].encode()); assert!(output.is_err()); } @@ -707,9 +708,15 @@ mod tests { ext.set_storage(b"foo".to_vec(), b"bar".to_vec()); let test_code = WASM_BINARY; - let output = call(&mut ext, 8, &test_code[..], "test_data_in", b"Hello world").unwrap(); + let output = call( + &mut ext, + 8, + &test_code[..], + "test_data_in", + &b"Hello world".to_vec().encode(), + ).unwrap(); - assert_eq!(output, b"all ok!".to_vec()); + assert_eq!(output, b"all ok!".to_vec().encode()); let expected = TestExternalities::new((map![ b"input".to_vec() => b"Hello world".to_vec(), @@ -730,9 +737,15 @@ mod tests { let test_code = WASM_BINARY; // This will clear all entries which prefix is "ab". - let output = call(&mut ext, 8, &test_code[..], "test_clear_prefix", b"ab").unwrap(); + let output = call( + &mut ext, + 8, + &test_code[..], + "test_clear_prefix", + &b"ab".to_vec().encode(), + ).unwrap(); - assert_eq!(output, b"all ok!".to_vec()); + assert_eq!(output, b"all ok!".to_vec().encode()); let expected = TestExternalities::new((map![ b"aaa".to_vec() => b"1".to_vec(), @@ -747,12 +760,18 @@ mod tests { let mut ext = TestExternalities::default(); let test_code = WASM_BINARY; assert_eq!( - call(&mut ext, 8, &test_code[..], "test_blake2_256", &[]).unwrap(), - blake2_256(&b""[..]).encode() + call(&mut ext, 8, &test_code[..], "test_blake2_256", &[0]).unwrap(), + blake2_256(&b""[..]).to_vec().encode(), ); assert_eq!( - call(&mut ext, 8, &test_code[..], "test_blake2_256", b"Hello world!").unwrap(), - blake2_256(&b"Hello world!"[..]).encode() + call( + &mut ext, + 8, + &test_code[..], + "test_blake2_256", + &b"Hello world!".to_vec().encode(), + ).unwrap(), + blake2_256(&b"Hello world!"[..]).to_vec().encode(), ); } @@ -761,12 +780,18 @@ mod tests { let mut ext = TestExternalities::default(); let test_code = WASM_BINARY; assert_eq!( - call(&mut ext, 8, &test_code[..], "test_blake2_128", &[]).unwrap(), - blake2_128(&b""[..]).encode() + call(&mut ext, 8, &test_code[..], "test_blake2_128", &[0]).unwrap(), + blake2_128(&b""[..]).to_vec().encode(), ); assert_eq!( - call(&mut ext, 8, &test_code[..], "test_blake2_128", b"Hello world!").unwrap(), - blake2_128(&b"Hello world!"[..]).encode() + call( + &mut ext, + 8, + &test_code[..], + "test_blake2_128", + &b"Hello world!".to_vec().encode(), + ).unwrap(), + blake2_128(&b"Hello world!"[..]).to_vec().encode(), ); } @@ -775,12 +800,22 @@ mod tests { let mut ext = TestExternalities::default(); let test_code = WASM_BINARY; assert_eq!( - call(&mut ext, 8, &test_code[..], "test_twox_256", &[]).unwrap(), - hex!("99e9d85137db46ef4bbea33613baafd56f963c64b1f3685a4eb4abd67ff6203a"), + call(&mut ext, 8, &test_code[..], "test_twox_256", &[0]).unwrap(), + hex!( + "99e9d85137db46ef4bbea33613baafd56f963c64b1f3685a4eb4abd67ff6203a" + ).to_vec().encode(), ); assert_eq!( - call(&mut ext, 8, &test_code[..], "test_twox_256", b"Hello world!").unwrap(), - hex!("b27dfd7f223f177f2a13647b533599af0c07f68bda23d96d059da2b451a35a74"), + call( + &mut ext, + 8, + &test_code[..], + "test_twox_256", + &b"Hello world!".to_vec().encode(), + ).unwrap(), + hex!( + "b27dfd7f223f177f2a13647b533599af0c07f68bda23d96d059da2b451a35a74" + ).to_vec().encode(), ); } @@ -789,12 +824,18 @@ mod tests { let mut ext = TestExternalities::default(); let test_code = WASM_BINARY; assert_eq!( - call(&mut ext, 8, &test_code[..], "test_twox_128", &[]).unwrap(), - hex!("99e9d85137db46ef4bbea33613baafd5") + call(&mut ext, 8, &test_code[..], "test_twox_128", &[0]).unwrap(), + hex!("99e9d85137db46ef4bbea33613baafd5").to_vec().encode(), ); assert_eq!( - call(&mut ext, 8, &test_code[..], "test_twox_128", b"Hello world!").unwrap(), - hex!("b27dfd7f223f177f2a13647b533599af") + call( + &mut ext, + 8, + &test_code[..], + "test_twox_128", + &b"Hello world!".to_vec().encode(), + ).unwrap(), + hex!("b27dfd7f223f177f2a13647b533599af").to_vec().encode(), ); } @@ -809,8 +850,8 @@ mod tests { calldata.extend_from_slice(sig.as_ref()); assert_eq!( - call(&mut ext, 8, &test_code[..], "test_ed25519_verify", &calldata).unwrap(), - vec![1] + call(&mut ext, 8, &test_code[..], "test_ed25519_verify", &calldata.encode()).unwrap(), + true.encode(), ); let other_sig = key.sign(b"all is not ok!"); @@ -819,8 +860,8 @@ mod tests { calldata.extend_from_slice(other_sig.as_ref()); assert_eq!( - call(&mut ext, 8, &test_code[..], "test_ed25519_verify", &calldata).unwrap(), - vec![0] + call(&mut ext, 8, &test_code[..], "test_ed25519_verify", &calldata.encode()).unwrap(), + false.encode(), ); } @@ -835,8 +876,8 @@ mod tests { calldata.extend_from_slice(sig.as_ref()); assert_eq!( - call(&mut ext, 8, &test_code[..], "test_sr25519_verify", &calldata).unwrap(), - vec![1] + call(&mut ext, 8, &test_code[..], "test_sr25519_verify", &calldata.encode()).unwrap(), + true.encode(), ); let other_sig = key.sign(b"all is not ok!"); @@ -845,8 +886,8 @@ mod tests { calldata.extend_from_slice(other_sig.as_ref()); assert_eq!( - call(&mut ext, 8, &test_code[..], "test_sr25519_verify", &calldata).unwrap(), - vec![0] + call(&mut ext, 8, &test_code[..], "test_sr25519_verify", &calldata.encode()).unwrap(), + false.encode(), ); } @@ -856,8 +897,8 @@ mod tests { let trie_input = vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()]; let test_code = WASM_BINARY; assert_eq!( - call(&mut ext, 8, &test_code[..], "test_ordered_trie_root", &[]).unwrap(), - Layout::::ordered_trie_root(trie_input.iter()).as_fixed_bytes().encode() + call(&mut ext, 8, &test_code[..], "test_ordered_trie_root", &[0]).unwrap(), + Layout::::ordered_trie_root(trie_input.iter()).as_bytes().encode(), ); } @@ -870,8 +911,8 @@ mod tests { ext.register_extension(OffchainExt::new(offchain)); let test_code = WASM_BINARY; assert_eq!( - call(&mut ext, 8, &test_code[..], "test_offchain_local_storage", &[]).unwrap(), - vec![0] + call(&mut ext, 8, &test_code[..], "test_offchain_local_storage", &[0]).unwrap(), + true.encode(), ); assert_eq!(state.read().persistent_storage.get(b"", b"test"), Some(vec![])); } @@ -897,8 +938,8 @@ mod tests { let test_code = WASM_BINARY; assert_eq!( - call(&mut ext, 8, &test_code[..], "test_offchain_http", &[]).unwrap(), - vec![0] + call(&mut ext, 8, &test_code[..], "test_offchain_http", &[0]).unwrap(), + true.encode(), ); } } diff --git a/core/primitives/src/lib.rs b/core/primitives/src/lib.rs index b1ce6e2f97..c2d23050f9 100644 --- a/core/primitives/src/lib.rs +++ b/core/primitives/src/lib.rs @@ -39,6 +39,7 @@ use std::borrow::Cow; use serde::{Serialize, Deserialize}; #[cfg(feature = "std")] pub use serde;// << for macro +#[doc(hidden)] pub use codec::{Encode, Decode};// << for macro #[cfg(feature = "std")] @@ -82,6 +83,9 @@ pub use self::hasher::blake2::Blake2Hasher; pub use primitives_storage as storage; +#[doc(hidden)] +pub use rstd; + /// Context for executing a call into the runtime. pub enum ExecutionContext { /// Context for general importing (including own blocks). diff --git a/core/primitives/src/testing.rs b/core/primitives/src/testing.rs index 7fdefd8fe0..92a09ff044 100644 --- a/core/primitives/src/testing.rs +++ b/core/primitives/src/testing.rs @@ -129,13 +129,127 @@ impl crate::traits::BareCryptoStore for KeyStore { } } +/// Macro for exporting functions from wasm in with the expected signature for using it with the +/// wasm executor. This is useful for tests where you need to call a function in wasm. +/// +/// The input parameters are expected to be SCALE encoded and will be automatically decoded for you. +/// The output value is also SCALE encoded when returned back to the host. +/// +/// The functions are feature-gated with `#[cfg(not(feature = "std"))]`, so they are only available +/// from within wasm. +/// +/// # Example +/// +/// ``` +/// # use substrate_primitives::wasm_export_functions; +/// +/// wasm_export_functions! { +/// fn test_in_wasm(value: bool, another_value: Vec) -> bool { +/// value && another_value.is_empty() +/// } +/// +/// fn without_return_value() { +/// // do something +/// } +/// } +/// ``` +#[macro_export] +macro_rules! wasm_export_functions { + ( + $( + fn $name:ident ( + $( $arg_name:ident: $arg_ty:ty ),* $(,)? + ) $( -> $ret_ty:ty )? { $( $fn_impl:tt )* } + )* + ) => { + $( + $crate::wasm_export_functions! { + @IMPL + fn $name ( + $( $arg_name: $arg_ty ),* + ) $( -> $ret_ty )? { $( $fn_impl )* } + } + )* + }; + (@IMPL + fn $name:ident ( + $( $arg_name:ident: $arg_ty:ty ),* + ) { $( $fn_impl:tt )* } + ) => { + #[no_mangle] + #[allow(unreachable_code)] + #[cfg(not(feature = "std"))] + pub fn $name(input_data: *mut u8, input_len: usize) -> u64 { + let input: &[u8] = if input_len == 0 { + &[0u8; 0] + } else { + unsafe { + $crate::rstd::slice::from_raw_parts(input_data, input_len) + } + }; + + { + let ($( $arg_name ),*) : ($( $arg_ty ),*) = $crate::Decode::decode( + &mut &input[..], + ).expect("Input data is correctly encoded"); + + $( $fn_impl )* + } + + // We need to return *something* + let output = Vec::::new(); + let res = output.as_ptr() as u64 + ((output.len() as u64) << 32); + + // Leak the output vector to avoid it being freed. + // This is fine in a WASM context since the heap + // will be discarded after the call. + $crate::rstd::mem::forget(output); + res + } + }; + (@IMPL + fn $name:ident ( + $( $arg_name:ident: $arg_ty:ty ),* + ) $( -> $ret_ty:ty )? { $( $fn_impl:tt )* } + ) => { + #[no_mangle] + #[allow(unreachable_code)] + #[cfg(not(feature = "std"))] + pub fn $name(input_data: *mut u8, input_len: usize) -> u64 { + let input: &[u8] = if input_len == 0 { + &[0u8; 0] + } else { + unsafe { + $crate::rstd::slice::from_raw_parts(input_data, input_len) + } + }; + + let output $( : $ret_ty )? = { + let ($( $arg_name ),*) : ($( $arg_ty ),*) = $crate::Decode::decode( + &mut &input[..], + ).expect("Input data is correctly encoded"); + + $( $fn_impl )* + }; + + let output = $crate::Encode::encode(&output); + let res = output.as_ptr() as u64 + ((output.len() as u64) << 32); + + // Leak the output vector to avoid it being freed. + // This is fine in a WASM context since the heap + // will be discarded after the call. + $crate::rstd::mem::forget(output); + res + } + }; +} + #[cfg(test)] mod tests { use super::*; use crate::sr25519; use crate::testing::{ED25519, SR25519}; - #[test] fn store_key_and_extract() { let store = KeyStore::new(); -- GitLab From 1ae7a901d9b2a7f4fefc7b5f5846c2d13ef6d8c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Tue, 15 Oct 2019 01:19:01 +0100 Subject: [PATCH 212/275] grandpa: fix until imported logging arg order (#3818) --- core/finality-grandpa/src/until_imported.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/finality-grandpa/src/until_imported.rs b/core/finality-grandpa/src/until_imported.rs index b8568c1f85..119ecf95c5 100644 --- a/core/finality-grandpa/src/until_imported.rs +++ b/core/finality-grandpa/src/until_imported.rs @@ -175,9 +175,9 @@ impl Stream for UntilImported target: "afg", "Waiting to import block {} before {} {} messages can be imported. \ Possible fork?", - self.identifier, block_hash, v.len(), + self.identifier, ); *last_log = next_log; -- GitLab From 67b73c468e44839c5809245703d067dc75940076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 15 Oct 2019 11:16:10 +0200 Subject: [PATCH 213/275] Fix asynchronous transaction rejections. (#3817) * Fix handling transaction pool errors. * Add test. * Review suggestions. --- core/rpc/api/src/subscriptions.rs | 7 +++ core/rpc/src/author/mod.rs | 71 +++++++++++++------------ core/rpc/src/author/tests.rs | 34 ++++++++++-- core/transaction-pool/graph/src/pool.rs | 2 +- 4 files changed, 73 insertions(+), 41 deletions(-) diff --git a/core/rpc/api/src/subscriptions.rs b/core/rpc/api/src/subscriptions.rs index a1e486138f..d5ca74fa60 100644 --- a/core/rpc/api/src/subscriptions.rs +++ b/core/rpc/api/src/subscriptions.rs @@ -69,6 +69,13 @@ impl Subscriptions { } } + /// Borrows the internal task executor. + /// + /// This can be used to spawn additional tasks on the underyling event loop. + pub fn executor(&self) -> &TaskExecutor { + &self.executor + } + /// Creates new subscription for given subscriber. /// /// Second parameter is a function that converts Subscriber sink into a future. diff --git a/core/rpc/src/author/mod.rs b/core/rpc/src/author/mod.rs index 9a978f22f7..82122dcf3d 100644 --- a/core/rpc/src/author/mod.rs +++ b/core/rpc/src/author/mod.rs @@ -26,10 +26,9 @@ use log::warn; use client::{self, Client}; use rpc::futures::{ Sink, Future, - stream::Stream as _, future::result, }; -use futures03::{StreamExt as _, compat::Compat}; +use futures03::{StreamExt as _, compat::Compat, future::ready}; use api::Subscriptions; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use codec::{Encode, Decode}; @@ -162,42 +161,44 @@ impl AuthorApi, BlockHash

> for Author whe let best_block_hash = self.client.info().chain.best_hash; let dxt = <

::Block as traits::Block>::Extrinsic::decode(&mut &xt[..]) .map_err(error::Error::from)?; - Ok(self.pool - .submit_and_watch(&generic::BlockId::hash(best_block_hash), dxt) - .boxed() - .compat() - .map_err(|e| e.into_pool_error() - .map(error::Error::from) - .unwrap_or_else(|e| error::Error::Verification(Box::new(e)).into()) - )) + Ok( + self.pool + .submit_and_watch(&generic::BlockId::hash(best_block_hash), dxt) + .map_err(|e| e.into_pool_error() + .map(error::Error::from) + .unwrap_or_else(|e| error::Error::Verification(Box::new(e)).into()) + ) + ) }; - let future_watcher = match submit() { - Ok(future_watcher) => future_watcher, - Err(err) => { - // reject the subscriber (ignore errors - we don't care if subscriber is no longer there). - let _ = subscriber.reject(err.into()); - return; - }, - }; - - // make 'future' watcher be a future with output = stream of watcher events - let future_watcher = future_watcher - .map_err(|err| { warn!("Failed to submit extrinsic: {}", err); }) - .map(|watcher| Compat::new(watcher.into_stream().map(|v| Ok::<_, ()>(Ok(v))))); - - // convert a 'future' watcher into the stream with single element = stream of watcher events - let watcher_stream = future_watcher.into_stream(); - - // and now flatten the 'watcher_stream' so that we'll have the stream with watcher events - let watcher_stream = watcher_stream.flatten(); + let subscriptions = self.subscriptions.clone(); + let future = ready(submit()) + .and_then(|res| res) + // convert the watcher into a `Stream` + .map(|res| res.map(|watcher| watcher.into_stream().map(|v| Ok::<_, ()>(Ok(v))))) + // now handle the import result, + // start a new subscrition + .map(move |result| match result { + Ok(watcher) => { + subscriptions.add(subscriber, move |sink| { + sink + .sink_map_err(|_| unimplemented!()) + .send_all(Compat::new(watcher)) + .map(|_| ()) + }); + }, + Err(err) => { + warn!("Failed to submit extrinsic: {}", err); + // reject the subscriber (ignore errors - we don't care if subscriber is no longer there). + let _ = subscriber.reject(err.into()); + }, + }); - self.subscriptions.add(subscriber, move |sink| { - sink - .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) - .send_all(watcher_stream) - .map(|_| ()) - }); + let res = self.subscriptions.executor() + .execute(Box::new(Compat::new(future.map(|_| Ok(()))))); + if res.is_err() { + warn!("Error spawning subscription RPC task."); + } } fn unwatch_extrinsic(&self, _metadata: Option, id: SubscriptionId) -> Result { diff --git a/core/rpc/src/author/tests.rs b/core/rpc/src/author/tests.rs index 202dab4940..e8ba4c132a 100644 --- a/core/rpc/src/author/tests.rs +++ b/core/rpc/src/author/tests.rs @@ -19,18 +19,19 @@ use super::*; use std::sync::Arc; use assert_matches::assert_matches; use codec::Encode; -use transaction_pool::{ - txpool::Pool, - FullChainApi, -}; use primitives::{ H256, blake2_256, hexdisplay::HexDisplay, testing::{ED25519, SR25519, KeyStore}, ed25519, crypto::Pair, }; +use rpc::futures::Stream as _; use test_client::{ self, AccountKeyring, runtime::{Extrinsic, Transfer, SessionKeys}, DefaultTestClientBuilderExt, TestClientBuilderExt, }; +use transaction_pool::{ + txpool::Pool, + FullChainApi, +}; use tokio::runtime; fn uxt(sender: AccountKeyring, nonce: u64) -> Extrinsic { @@ -102,7 +103,7 @@ fn should_watch_extrinsic() { subscriptions: Subscriptions::new(Arc::new(runtime.executor())), keystore: keystore.clone(), }; - let (subscriber, id_rx, data) = ::jsonrpc_pubsub::typed::Subscriber::new_test("test"); + let (subscriber, id_rx, data) = jsonrpc_pubsub::typed::Subscriber::new_test("test"); // when p.watch_extrinsic(Default::default(), subscriber, uxt(AccountKeyring::Alice, 0).encode().into()); @@ -132,6 +133,29 @@ fn should_watch_extrinsic() { ); } +#[test] +fn should_return_watch_validation_error() { + //given + let mut runtime = runtime::Runtime::new().unwrap(); + let client = Arc::new(test_client::new()); + let pool = Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone()))); + let keystore = KeyStore::new(); + let p = Author { + client, + pool: pool.clone(), + subscriptions: Subscriptions::new(Arc::new(runtime.executor())), + keystore: keystore.clone(), + }; + let (subscriber, id_rx, _data) = jsonrpc_pubsub::typed::Subscriber::new_test("test"); + + // when + p.watch_extrinsic(Default::default(), subscriber, uxt(AccountKeyring::Alice, 179).encode().into()); + + // then + let res = runtime.block_on(id_rx).unwrap(); + assert!(res.is_err(), "Expected the transaction to be rejected as invalid."); +} + #[test] fn should_return_pending_extrinsics() { let runtime = runtime::Runtime::new().unwrap(); diff --git a/core/transaction-pool/graph/src/pool.rs b/core/transaction-pool/graph/src/pool.rs index 53b2a62cbe..621aeabda8 100644 --- a/core/transaction-pool/graph/src/pool.rs +++ b/core/transaction-pool/graph/src/pool.rs @@ -66,7 +66,7 @@ pub trait ChainApi: Send + Sync { /// Error type. type Error: From + error::IntoPoolError; /// Validate transaction future. - type ValidationFuture: Future> + Send; + type ValidationFuture: Future> + Send + Unpin; /// Verify extrinsic at given block. fn validate_transaction( -- GitLab From 9b8bfd72126be453cda302caff28a6c99adee14c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Tue, 15 Oct 2019 15:07:56 +0100 Subject: [PATCH 214/275] chain spec builder: add generate mode for authority keys (#3811) * core: use trait object for genesis constructor * chain-spec-builder: use structopt * chain-spec-builder: add new command to generate authority keys * chain-spec-builder: use ? in main * chain-spec-builder: fix stored and printed suri from seed * chain-spec-builder: add comment about created keystore folders * chain-spec-builder: simplify file write --- Cargo.lock | 6 +- core/chain-spec/src/chain_spec.rs | 11 +- test-utils/chain-spec-builder/Cargo.toml | 6 +- test-utils/chain-spec-builder/src/cli.yml | 24 -- test-utils/chain-spec-builder/src/main.rs | 258 ++++++++++++++++++++-- 5 files changed, 249 insertions(+), 56 deletions(-) delete mode 100644 test-utils/chain-spec-builder/src/cli.yml diff --git a/Cargo.lock b/Cargo.lock index 5a17eaed31..b8dade5e24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -400,10 +400,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "chain-spec-builder" version = "2.0.0" dependencies = [ - "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "node-cli 2.0.0", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-keystore 2.0.0", "substrate-primitives 2.0.0", - "substrate-service 2.0.0", ] [[package]] diff --git a/core/chain-spec/src/chain_spec.rs b/core/chain-spec/src/chain_spec.rs index b4c57f1e03..8d72effc7b 100644 --- a/core/chain-spec/src/chain_spec.rs +++ b/core/chain-spec/src/chain_spec.rs @@ -20,6 +20,7 @@ use std::borrow::Cow; use std::collections::HashMap; use std::fs::File; use std::path::PathBuf; +use std::rc::Rc; use serde::{Serialize, Deserialize}; use primitives::storage::{StorageKey, StorageData}; use sr_primitives::{BuildStorage, StorageOverlay, ChildrenStorageOverlay}; @@ -31,7 +32,7 @@ use tel::TelemetryEndpoints; enum GenesisSource { File(PathBuf), Binary(Cow<'static, [u8]>), - Factory(fn() -> G), + Factory(Rc G>), } impl Clone for GenesisSource { @@ -39,7 +40,7 @@ impl Clone for GenesisSource { match *self { GenesisSource::File(ref path) => GenesisSource::File(path.clone()), GenesisSource::Binary(ref d) => GenesisSource::Binary(d.clone()), - GenesisSource::Factory(f) => GenesisSource::Factory(f), + GenesisSource::Factory(ref f) => GenesisSource::Factory(f.clone()), } } } @@ -187,10 +188,10 @@ impl ChainSpec { } /// Create hardcoded spec. - pub fn from_genesis( + pub fn from_genesis G + 'static>( name: &str, id: &str, - constructor: fn() -> G, + constructor: F, boot_nodes: Vec, telemetry_endpoints: Option, protocol_id: Option<&str>, @@ -211,7 +212,7 @@ impl ChainSpec { ChainSpec { spec, - genesis: GenesisSource::Factory(constructor), + genesis: GenesisSource::Factory(Rc::new(constructor)), } } } diff --git a/test-utils/chain-spec-builder/Cargo.toml b/test-utils/chain-spec-builder/Cargo.toml index 478e230505..324d33cbf0 100644 --- a/test-utils/chain-spec-builder/Cargo.toml +++ b/test-utils/chain-spec-builder/Cargo.toml @@ -5,7 +5,9 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -clap = { version = "2.33.0", features = ["yaml"] } +ansi_term = "0.12.1" +keystore = { package = "substrate-keystore", path = "../../core/keystore" } node-cli = { path = "../../node/cli" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } -substrate-service = { path = "../../core/service" } +rand = "0.7.2" +structopt = "0.3.3" diff --git a/test-utils/chain-spec-builder/src/cli.yml b/test-utils/chain-spec-builder/src/cli.yml deleted file mode 100644 index f4b1cb7e2e..0000000000 --- a/test-utils/chain-spec-builder/src/cli.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: chain-spec-builder -author: "azban " -about: Utility for creating chain specs primarily for testing -args: -- initial_authority_seed: - short: a - value_name: INITIAL_AUTHORITY_SEED - help: Initial authority seed - takes_value: true - multiple: true - required: true -- endowed_account_seed: - short: e - value_name: ENDOWED_ACCOUNT_SEED - help: Endowed account seed - takes_value: true - multiple: true - required: true -- sudo_key_seed: - short: u - value_name: SUDO_KEY_SEED - help: Sudo key seed - takes_value: true - required: true diff --git a/test-utils/chain-spec-builder/src/main.rs b/test-utils/chain-spec-builder/src/main.rs index 8f59c73493..22c5253b06 100644 --- a/test-utils/chain-spec-builder/src/main.rs +++ b/test-utils/chain-spec-builder/src/main.rs @@ -1,49 +1,261 @@ -use clap::{App, load_yaml}; +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use std::{fs, path::{Path, PathBuf}}; + +use ansi_term::Style; +use rand::{Rng, distributions::Alphanumeric, rngs::OsRng}; +use structopt::StructOpt; + +use keystore::{Store as Keystore}; use node_cli::chain_spec::{self, AccountId}; -use substrate_service::chain_ops::build_spec; +use primitives::{crypto::{Public, Ss58Codec}, traits::BareCryptoStore}; -fn genesis_constructor() -> chain_spec::GenesisConfig { - let yaml = load_yaml!("./cli.yml"); - let matches = App::from_yaml(yaml).get_matches(); - let authorities = matches.values_of("initial_authority_seed") - .unwrap() - .map(chain_spec::get_authority_keys_from_seed) - .collect(); +/// A utility to easily create a testnet chain spec definition with a given set +/// of authorities and endowed accounts and/or generate random accounts. +#[derive(StructOpt)] +#[structopt(rename_all = "kebab-case")] +enum ChainSpecBuilder { + /// Create a new chain spec with the given authorities, endowed and sudo + /// accounts. + New { + /// Authority key seed. + #[structopt(long, short, required = true)] + authority_seeds: Vec, + /// Endowed account address (SS58 format). + #[structopt(long, short)] + endowed_accounts: Vec, + /// Sudo account address (SS58 format). + #[structopt(long, short)] + sudo_account: String, + /// The path where the chain spec should be saved. + #[structopt(long, short, default_value = "./chain_spec.json")] + chain_spec_path: PathBuf, + }, + /// Create a new chain spec with the given number of authorities and endowed + /// accounts. Random keys will be generated as required. + Generate { + /// The number of authorities. + #[structopt(long, short)] + authorities: usize, + /// The number of endowed accounts. + #[structopt(long, short, default_value = "0")] + endowed: usize, + /// The path where the chain spec should be saved. + #[structopt(long, short, default_value = "./chain_spec.json")] + chain_spec_path: PathBuf, + /// Path to use when saving generated keystores for each authority. + /// + /// At this path, a new folder will be created for each authority's + /// keystore named `auth-$i` where `i` is the authority index, i.e. + /// `auth-0`, `auth-1`, etc. + #[structopt(long, short)] + keystore_path: Option, + }, +} - let endowed_accounts = matches.values_of("endowed_account_seed") - .unwrap() - .map(chain_spec::get_from_seed::) - .collect(); +impl ChainSpecBuilder { + /// Returns the path where the chain spec should be saved. + fn chain_spec_path(&self) -> &Path { + match self { + ChainSpecBuilder::New { chain_spec_path, .. } => + chain_spec_path.as_path(), + ChainSpecBuilder::Generate { chain_spec_path, .. } => + chain_spec_path.as_path(), + } + } +} - let sudo_key_seed = matches.value_of("sudo_key_seed").unwrap(); - let sudo_key = chain_spec::get_from_seed::(sudo_key_seed); +fn genesis_constructor( + authority_seeds: &[String], + endowed_accounts: &[AccountId], + sudo_account: &AccountId, +) -> chain_spec::GenesisConfig { + let authorities = authority_seeds + .iter() + .map(AsRef::as_ref) + .map(chain_spec::get_authority_keys_from_seed) + .collect::>(); let enable_println = true; chain_spec::testnet_genesis( authorities, - sudo_key.into(), - Some(endowed_accounts), + sudo_account.clone(), + Some(endowed_accounts.to_vec()), enable_println, ) } -fn generate_chain_spec() -> String { +fn generate_chain_spec( + authority_seeds: Vec, + endowed_accounts: Vec, + sudo_account: String, +) -> Result { + let parse_account = |address: &String| { + AccountId::from_string(address) + .map_err(|err| format!("Failed to parse account address: {:?}", err)) + }; + + let endowed_accounts = endowed_accounts + .iter() + .map(parse_account) + .collect::, String>>()?; + + let sudo_account = parse_account(&sudo_account)?; + let chain_spec = chain_spec::ChainSpec::from_genesis( "Custom", "custom", - genesis_constructor, + move || genesis_constructor(&authority_seeds, &endowed_accounts, &sudo_account), vec![], None, None, None, Default::default(), ); - build_spec(chain_spec, false).unwrap() + + chain_spec.to_json(false).map_err(|err| err.to_string()) +} + +fn generate_authority_keys_and_store( + seeds: &[String], + keystore_path: &Path, +) -> Result<(), String> { + for (n, seed) in seeds.into_iter().enumerate() { + let keystore = Keystore::open( + keystore_path.join(format!("auth-{}", n)), + None, + ).map_err(|err| err.to_string())?; + + let (_, _, grandpa, babe, im_online) = + chain_spec::get_authority_keys_from_seed(seed); + + let insert_key = |key_type, public| { + keystore.write().insert_unknown( + key_type, + &format!("//{}", seed), + public, + ).map_err(|_| format!("Failed to insert key: {}", grandpa)) + }; + + insert_key( + primitives::crypto::key_types::BABE, + babe.as_slice(), + )?; + + insert_key( + primitives::crypto::key_types::GRANDPA, + grandpa.as_slice(), + )?; + + insert_key( + primitives::crypto::key_types::IM_ONLINE, + im_online.as_slice(), + )?; + } + + Ok(()) +} + +fn print_seeds( + authority_seeds: &[String], + endowed_seeds: &[String], + sudo_seed: &str, +) { + let header = Style::new().bold().underline(); + let entry = Style::new().bold(); + + println!("{}", header.paint("Authority seeds")); + + for (n, seed) in authority_seeds.iter().enumerate() { + println!("{} //{}", + entry.paint(format!("auth-{}:", n)), + seed, + ); + } + + println!(); + + if !endowed_seeds.is_empty() { + println!("{}", header.paint("Endowed seeds")); + for (n, seed) in endowed_seeds.iter().enumerate() { + println!("{} //{}", + entry.paint(format!("endowed-{}:", n)), + seed, + ); + } + + println!(); + } + + println!("{}", header.paint("Sudo seed")); + println!("//{}", sudo_seed); } -fn main() { - let json = generate_chain_spec(); - println!("{}", json); +fn main() -> Result<(), String> { + let builder = ChainSpecBuilder::from_args(); + let chain_spec_path = builder.chain_spec_path().to_path_buf(); + + let (authority_seeds, endowed_accounts, sudo_account) = match builder { + ChainSpecBuilder::Generate { authorities, endowed, keystore_path, .. } => { + let authorities = authorities.max(1); + let rand_str = || -> String { + OsRng.sample_iter(&Alphanumeric) + .take(32) + .collect() + }; + + let authority_seeds = (0..authorities).map(|_| rand_str()).collect::>(); + let endowed_seeds = (0..endowed).map(|_| rand_str()).collect::>(); + let sudo_seed = rand_str(); + + print_seeds( + &authority_seeds, + &endowed_seeds, + &sudo_seed, + ); + + if let Some(keystore_path) = keystore_path { + generate_authority_keys_and_store( + &authority_seeds, + &keystore_path, + )?; + } + + let endowed_accounts = endowed_seeds.iter().map(|seed| { + chain_spec::get_from_seed::(seed) + .to_ss58check() + }).collect(); + + let sudo_account = chain_spec::get_from_seed::(&sudo_seed) + .to_ss58check(); + + (authority_seeds, endowed_accounts, sudo_account) + }, + ChainSpecBuilder::New { authority_seeds, endowed_accounts, sudo_account, .. } => { + (authority_seeds, endowed_accounts, sudo_account) + }, + }; + + let json = generate_chain_spec( + authority_seeds, + endowed_accounts, + sudo_account, + )?; + + fs::write(chain_spec_path, json).map_err(|err| err.to_string()) } -- GitLab From a1d8124152d21c88085bd0c1ada709e2560e193a Mon Sep 17 00:00:00 2001 From: Demi Obenour <48690212+DemiMarie-parity@users.noreply.github.com> Date: Tue, 15 Oct 2019 12:33:34 -0400 Subject: [PATCH 215/275] Bump dependencies, respecting semver (#3812) --- Cargo.lock | 146 +++++++++++++++++++++++++++++------------------------ 1 file changed, 79 insertions(+), 67 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8dade5e24..f83f550fdc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -112,19 +112,19 @@ dependencies = [ [[package]] name = "asn1_der" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "asn1_der_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "asn1_der_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "asn1_der_derive" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -341,7 +341,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -627,7 +627,7 @@ dependencies = [ "bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -747,7 +747,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -758,7 +758,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -834,22 +834,22 @@ dependencies = [ [[package]] name = "failure" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "failure_derive" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1327,7 +1327,7 @@ dependencies = [ "http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1419,7 +1419,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "iovec" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1427,7 +1427,7 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1466,7 +1466,7 @@ name = "jsonrpc-client-transports" version = "13.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1686,7 +1686,7 @@ dependencies = [ "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1694,11 +1694,11 @@ name = "libp2p-core" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "asn1_der 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "asn1_der 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "bs58 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "ed25519-dalek 1.0.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1720,7 +1720,7 @@ dependencies = [ "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1790,7 +1790,7 @@ dependencies = [ "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1817,7 +1817,7 @@ dependencies = [ "uint 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1839,7 +1839,7 @@ dependencies = [ "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-udp 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1892,7 +1892,7 @@ dependencies = [ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1957,7 +1957,7 @@ dependencies = [ "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1968,7 +1968,7 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "get_if_addrs 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ipnet 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ipnet 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2222,7 +2222,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2248,7 +2248,7 @@ name = "mio-uds" version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "iovec 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2300,7 +2300,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.10.25 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.50 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.51 (registry+https://github.com/rust-lang/crates.io-index)", "schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2703,7 +2703,7 @@ dependencies = [ "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.50 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.51 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2713,7 +2713,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "openssl-sys" -version = "0.9.50" +version = "0.9.51" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3079,7 +3079,7 @@ name = "prost-derive" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3489,7 +3489,7 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -3528,7 +3528,7 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "merlin 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3627,7 +3627,7 @@ version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3759,8 +3759,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3817,7 +3817,7 @@ dependencies = [ "substrate-state-machine 2.0.0", "substrate-test-runtime-client 2.0.0", "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", - "trybuild 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", + "trybuild 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4414,7 +4414,7 @@ dependencies = [ "srml-support 2.0.0", "substrate-inherents 2.0.0", "substrate-primitives 2.0.0", - "trybuild 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", + "trybuild 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5685,6 +5685,17 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "synstructure" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "sysinfo" version = "0.9.5" @@ -5768,7 +5779,7 @@ name = "tiny-bip39" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5809,7 +5820,7 @@ dependencies = [ "tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-sync 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5901,7 +5912,7 @@ dependencies = [ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-sync 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5911,7 +5922,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5919,7 +5930,7 @@ dependencies = [ [[package]] name = "tokio-sync" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5933,7 +5944,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5997,7 +6008,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6085,7 +6096,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "trybuild" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6237,7 +6248,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6362,7 +6373,7 @@ name = "wasm-bindgen-webidl" version = "0.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6374,7 +6385,7 @@ dependencies = [ [[package]] name = "wasm-timer" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6411,7 +6422,7 @@ name = "web-sys" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "js-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", "sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6472,7 +6483,7 @@ name = "which" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6622,8 +6633,8 @@ dependencies = [ "checksum arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "bc4662175ead9cd84451d5c35070517777949a2ed84551764129cedb88384841" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" "checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" -"checksum asn1_der 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bea40e881533b1fe23afca9cd1c1ca022219a10fce604099ecfc96bfa26eaf1a" -"checksum asn1_der_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e7f92edafad155aff997fa5b727c6429b91e996b5a5d62a2b0adbae1306b5fe" +"checksum asn1_der 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6fce6b6a0ffdafebd82c87e79e3f40e8d2c523e5fea5566ff6b90509bf98d638" +"checksum asn1_der_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d0864d84b8e07b145449be9a8537db86bf9de5ce03b913214694643b4743502" "checksum assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7deb0a829ca7bcfaf5da70b073a8d128619259a7be8216a355e23f00763059e5" "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" "checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875" @@ -6705,8 +6716,8 @@ dependencies = [ "checksum erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3beee4bc16478a1b26f2e80ad819a52d24745e292f521a63c16eea5f74b7eb60" "checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9" "checksum exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d8013f441e38e31c670e7f34ec8f1d5d3a2bd9d303c1ff83976ca886005e8f48" -"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" -"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" +"checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" +"checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" "checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" "checksum finality-grandpa 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9681c1f75941ea47584573dd2bc10558b2067d460612945887e00744e43393be" @@ -6770,8 +6781,8 @@ dependencies = [ "checksum indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a61202fbe46c4a951e9404a720a0180bcf3212c750d735cb5c4ba4dc551299f3" "checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" "checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" -"checksum iovec 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c9636900aa73ffed13cdbb199f17cd955670bb300927c8d25b517dfa136b6567" -"checksum ipnet 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e61c2da0d0f700c77d2d313dbf4f93e41d235fa12c6681fee06621036df4c2af" +"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +"checksum ipnet 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc15ac2e0886d62ba078989ef6920ab23997ab0b04ca5687f1a9a7484296a48" "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum jobserver 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b1d42ef453b30b7387e113da1c83ab1605d90c5b4e0eb8e96d016ed3b8c160" @@ -6861,7 +6872,7 @@ dependencies = [ "checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" "checksum openssl 0.10.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2f372b2b53ce10fb823a337aaa674e3a7d072b957c6264d0f4ff0bd86e657449" "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-sys 0.9.50 (registry+https://github.com/rust-lang/crates.io-index)" = "2c42dcccb832556b5926bc9ae61e8775f2a61e725ab07ab3d1e7fcf8ae62c3b6" +"checksum openssl-sys 0.9.51 (registry+https://github.com/rust-lang/crates.io-index)" = "ba24190c8f0805d3bd2ce028f439fe5af1d55882bbe6261bed1dbc93b50dd6b1" "checksum output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9" "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" "checksum parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" @@ -6946,7 +6957,7 @@ dependencies = [ "checksum rustls 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f271e3552cd835fa28c541c34a7e8fdd8cdff09d77fe4eb8f6c42e87a11b096e" "checksum rustversion 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b48139cfc215c6cc70d43c6c555a59e723c3b5adb26a4cfa09f815a5ae5871e8" "checksum rw-stream-sink 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9cbe61c20455d3015b2bb7be39e1872310283b8e5a52f5b242b0ac7581fe78" -"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" +"checksum ryu 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "19d2271fa48eaf61e53cc88b4ad9adcbafa2d512c531e7fadb6dc11a4d3656c5" "checksum safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347" "checksum safemem 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d2b08423011dae9a5ca23f07cf57dac3857f5c885d352b76f6d95f4aea9434d0" "checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" @@ -6998,6 +7009,7 @@ dependencies = [ "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" "checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf" "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" +"checksum synstructure 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f085a5855930c0441ca1288cf044ea4aecf4f43a91668abdb870b4ba546a203" "checksum sysinfo 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d5bd3b813d94552a8033c650691645f8dd5a63d614dddd62428a95d3931ef7b6" "checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" "checksum target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" @@ -7020,7 +7032,7 @@ dependencies = [ "checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" "checksum tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "c56391be9805bc80163151c0b9e5164ee64f4b0200962c346fea12773158f22d" "checksum tokio-rustls 0.10.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3e5cebc3ca33110e460c4d2e7c5e863b159fadcbf125449d896720695b2af709" -"checksum tokio-sync 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2162248ff317e2bc713b261f242b69dbb838b85248ed20bb21df56d60ea4cae7" +"checksum tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d06554cce1ae4a50f42fba8023918afa931413aded705b560e29600ccf7c6d76" "checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" "checksum tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2bd2c6a3885302581f4401c82af70d792bb9df1700e7437b0aeb4ada94d5388c" "checksum tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e" @@ -7034,7 +7046,7 @@ dependencies = [ "checksum trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0b779f7c1c8fe9276365d9d5be5c4b5adeacf545117bb3f64c974305789c5c0b" "checksum trie-standardmap 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3161ba520ab28cd8e6b68e1126f1009f6e335339d1a73b978139011703264c8" "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" -"checksum trybuild 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "10d8f366221c5a5ff8a62faa005e186fdce758949d34a9140b64a062951bae68" +"checksum trybuild 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "e6851bf8351876984fbab8a2391de6378947b898410d8714edd12164d2137127" "checksum twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d261e83e727c8e2dbb75dacac67c36e35db36a958ee504f2164fc052434e1" "checksum twox-hash 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" @@ -7069,7 +7081,7 @@ dependencies = [ "checksum wasm-bindgen-macro-support 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "9c075d27b7991c68ca0f77fe628c3513e64f8c477d422b859e03f28751b46fc5" "checksum wasm-bindgen-shared 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "83d61fe986a7af038dd8b5ec660e5849cbd9f38e7492b9404cc48b2b4df731d1" "checksum wasm-bindgen-webidl 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "9b979afb0535fe4749906a674082db1211de8aef466331d43232f63accb7c07c" -"checksum wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3d6101df9a5987df809216bdda7289f52b58128e6b6a6546e9ee3e6b632b4921" +"checksum wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "aa3e01d234bb71760e685cfafa5e2c96f8ad877c161a721646356651069e26ac" "checksum wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f31d26deb2d9a37e6cfed420edce3ed604eab49735ba89035e13c98f9a528313" "checksum wasmi-validation 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6bc0356e3df56e639fc7f7d8a99741915531e27ed735d911ed83d7e1339c8188" "checksum web-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)" = "c84440699cd02ca23bed6f045ffb1497bc18a3c2628bd13e2093186faaaacf6b" -- GitLab From ba43ca16ee4c9eb45f6eec04ebf50f38b6dd6db7 Mon Sep 17 00:00:00 2001 From: Fabio Tudone Date: Wed, 16 Oct 2019 11:02:12 +0300 Subject: [PATCH 216/275] Fix #1536: do not require to construct a block for encoding it (#3813) * Fix #1536: do not require to construct a block for encoding it * Bump `impl_version` * Improve `Block::encode_from` signature and rustdoc (from review by @bkchr) --- core/client/src/client.rs | 8 ++++---- core/sr-primitives/src/generic/block.rs | 3 +++ core/sr-primitives/src/testing.rs | 3 +++ core/sr-primitives/src/traits.rs | 2 ++ node/runtime/src/lib.rs | 2 +- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/core/client/src/client.rs b/core/client/src/client.rs index 34334b1388..796520cb7f 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -1059,10 +1059,10 @@ impl Client where } }; - let encoded_block = ::new( - import_headers.pre().clone(), - body.unwrap_or_default(), - ).encode(); + let encoded_block = ::encode_from( + import_headers.pre(), + &body.unwrap_or_default() + ); let (_, storage_update, changes_update) = self.executor .call_at_state::<_, _, NeverNativeValue, fn() -> _>( diff --git a/core/sr-primitives/src/generic/block.rs b/core/sr-primitives/src/generic/block.rs index 736ad0cbbb..29fcaab572 100644 --- a/core/sr-primitives/src/generic/block.rs +++ b/core/sr-primitives/src/generic/block.rs @@ -93,6 +93,9 @@ where fn new(header: Self::Header, extrinsics: Vec) -> Self { Block { header, extrinsics } } + fn encode_from(header: &Self::Header, extrinsics: &[Self::Extrinsic]) -> Vec { + (header, extrinsics).encode() + } } /// Abstraction over a substrate block and justification. diff --git a/core/sr-primitives/src/testing.rs b/core/sr-primitives/src/testing.rs index 5391735576..b790347118 100644 --- a/core/sr-primitives/src/testing.rs +++ b/core/sr-primitives/src/testing.rs @@ -259,6 +259,9 @@ impl) -> Self { Block { header, extrinsics } } + fn encode_from(header: &Self::Header, extrinsics: &[Self::Extrinsic]) -> Vec { + (header, extrinsics).encode() + } } impl<'a, Xt> Deserialize<'a> for Block where Block: Decode { diff --git a/core/sr-primitives/src/traits.rs b/core/sr-primitives/src/traits.rs index f94a71d38a..a589f5f389 100644 --- a/core/sr-primitives/src/traits.rs +++ b/core/sr-primitives/src/traits.rs @@ -687,6 +687,8 @@ pub trait Block: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebugButNotDes fn hash(&self) -> Self::Hash { <::Hashing as Hash>::hash_of(self.header()) } + /// Create an encoded block from the given `header` and `extrinsics` without requiring to create an instance. + fn encode_from(header: &Self::Header, extrinsics: &[Self::Extrinsic]) -> Vec; } /// Something that acts like an `Extrinsic`. diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 70b1b8f16a..d8fc9a1a57 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -85,7 +85,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 175, - impl_version: 175, + impl_version: 176, apis: RUNTIME_API_VERSIONS, }; -- GitLab From 297956d124b3fed191876e3f902de9a2a89c84ba Mon Sep 17 00:00:00 2001 From: Ashley Date: Wed, 16 Oct 2019 10:59:25 +0100 Subject: [PATCH 217/275] WIP: Node role RPC call (#3719) * Add a Node Role RPC call * Formatting * Fix tests * Change tests to use NodeRole::Authority so I don't forget to update the test * Improve role checking * return a vec instead * fix tests --- core/rpc/api/src/system/helpers.rs | 25 +++++++++++++++++++------ core/rpc/api/src/system/mod.rs | 6 +++++- core/rpc/src/system/mod.rs | 10 +++++++++- core/rpc/src/system/tests.rs | 11 +++++++++++ core/service/src/lib.rs | 19 ++++++++++++++++++- 5 files changed, 62 insertions(+), 9 deletions(-) diff --git a/core/rpc/api/src/system/helpers.rs b/core/rpc/api/src/system/helpers.rs index 00e2ba9f40..10319d57b6 100644 --- a/core/rpc/api/src/system/helpers.rs +++ b/core/rpc/api/src/system/helpers.rs @@ -50,6 +50,14 @@ pub struct Health { pub should_have_peers: bool, } +impl fmt::Display for Health { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "{} peers ({})", self.peers, if self.is_syncing { + "syncing" + } else { "idle" }) + } +} + /// Network Peer information #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -66,12 +74,17 @@ pub struct PeerInfo { pub best_number: Number, } -impl fmt::Display for Health { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "{} peers ({})", self.peers, if self.is_syncing { - "syncing" - } else { "idle" }) - } +/// The role the node is running as +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum NodeRole { + /// The node is a full node + Full, + /// The node is a light client + LightClient, + /// The node is an authority + Authority, + /// An unknown role with a bit number + UnknownRole(u8) } #[cfg(test)] diff --git a/core/rpc/api/src/system/mod.rs b/core/rpc/api/src/system/mod.rs index b5eacc5d61..f59fd84c7c 100644 --- a/core/rpc/api/src/system/mod.rs +++ b/core/rpc/api/src/system/mod.rs @@ -24,7 +24,7 @@ use jsonrpc_derive::rpc; use self::error::Result; -pub use self::helpers::{Properties, SystemInfo, Health, PeerInfo}; +pub use self::helpers::{Properties, SystemInfo, Health, PeerInfo, NodeRole}; pub use self::gen_client::Client as SystemClient; /// Substrate system RPC API @@ -64,4 +64,8 @@ pub trait SystemApi { // TODO: make this stable and move structs https://github.com/paritytech/substrate/issues/1890 #[rpc(name = "system_networkState", returns = "jsonrpc_core::Value")] fn system_network_state(&self) -> Receiver; + + /// Returns the roles the node is running as. + #[rpc(name = "system_nodeRoles", returns = "Vec")] + fn system_node_roles(&self) -> Receiver>; } diff --git a/core/rpc/src/system/mod.rs b/core/rpc/src/system/mod.rs index 8eeff6758b..8907151d9a 100644 --- a/core/rpc/src/system/mod.rs +++ b/core/rpc/src/system/mod.rs @@ -25,7 +25,7 @@ use sr_primitives::traits::{self, Header as HeaderT}; use self::error::Result; pub use api::system::*; -pub use self::helpers::{Properties, SystemInfo, Health, PeerInfo}; +pub use self::helpers::{Properties, SystemInfo, Health, PeerInfo, NodeRole}; pub use self::gen_client::Client as SystemClient; /// System API implementation @@ -42,6 +42,8 @@ pub enum Request { Peers(oneshot::Sender::Number>>>), /// Must return the state of the network. NetworkState(oneshot::Sender), + /// Must return the node role. + NodeRoles(oneshot::Sender>) } impl System { @@ -94,4 +96,10 @@ impl SystemApi::Number> for Sy let _ = self.send_back.unbounded_send(Request::NetworkState(tx)); Receiver(Compat::new(rx)) } + + fn system_node_roles(&self) -> Receiver> { + let (tx, rx) = oneshot::channel(); + let _ = self.send_back.unbounded_send(Request::NodeRoles(tx)); + Receiver(Compat::new(rx)) + } } diff --git a/core/rpc/src/system/tests.rs b/core/rpc/src/system/tests.rs index 5b271af9ac..1c532be372 100644 --- a/core/rpc/src/system/tests.rs +++ b/core/rpc/src/system/tests.rs @@ -79,6 +79,9 @@ fn api>>(sync: T) -> System { average_upload_per_sec: 0, peerset: serde_json::Value::Null, }).unwrap()); + }, + Request::NodeRoles(sender) => { + let _ = sender.send(vec![NodeRole::Authority]); } }; @@ -221,3 +224,11 @@ fn system_network_state() { } ); } + +#[test] +fn system_node_roles() { + assert_eq!( + wait_receiver(api(None).system_node_roles()), + vec![NodeRole::Authority] + ); +} \ No newline at end of file diff --git a/core/service/src/lib.rs b/core/service/src/lib.rs index fccf04d8a1..5dd9ea8270 100644 --- a/core/service/src/lib.rs +++ b/core/service/src/lib.rs @@ -368,6 +368,7 @@ macro_rules! new_impl { let _ = to_spawn_tx.unbounded_send(Box::new(build_network_future( + $config.roles, network_mut, client.clone(), network_status_sinks.clone(), @@ -662,6 +663,7 @@ fn build_network_future< S: network::specialization::NetworkSpecialization, H: network::ExHashT > ( + roles: Roles, mut network: network::NetworkWorker, client: Arc, status_sinks: Arc, NetworkState)>>>>, @@ -669,7 +671,7 @@ fn build_network_future< should_have_peers: bool, dht_event_tx: Option>, ) -> impl Future { - // Compatibility shim while we're transitionning to stable Futures. + // Compatibility shim while we're transitioning to stable Futures. // See https://github.com/paritytech/substrate/issues/3099 let mut rpc_rx = futures03::compat::Compat::new(rpc_rx.map(|v| Ok::<_, ()>(v))); @@ -725,6 +727,21 @@ fn build_network_future< let _ = sender.send(network_state); } } + rpc::system::Request::NodeRoles(sender) => { + use rpc::system::NodeRole; + + let node_roles = (0 .. 8) + .filter(|&bit_number| (roles.bits() >> bit_number) & 1 == 1) + .map(|bit_number| match Roles::from_bits(1 << bit_number) { + Some(Roles::AUTHORITY) => NodeRole::Authority, + Some(Roles::LIGHT) => NodeRole::LightClient, + Some(Roles::FULL) => NodeRole::Full, + _ => NodeRole::UnknownRole(bit_number), + }) + .collect(); + + let _ = sender.send(node_roles); + } }; } -- GitLab From ead7e0efda5f216ba13992ea6832ac4b70772204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 16 Oct 2019 12:40:35 +0200 Subject: [PATCH 218/275] Move srml RPC extensions to separate crates (#3791) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Move srml-system RPC out. * Fix tests for system-rpc module. * Contracts RPC moved. * Fix rpc test. * Clean up. * Update lockfile. * Bump runtime version. * Update srml/contracts/rpc/runtime-api/src/lib.rs Co-Authored-By: Bastian Köcher * Bump impl version. --- Cargo.lock | 75 ++++++++++++---- Cargo.toml | 1 + core/rpc/src/state/tests.rs | 2 +- core/test-runtime/Cargo.toml | 2 + core/test-runtime/src/lib.rs | 12 +++ core/test-runtime/src/system.rs | 19 ++-- node/primitives/Cargo.toml | 8 -- node/primitives/src/lib.rs | 45 ---------- node/rpc/Cargo.toml | 17 +--- node/rpc/src/lib.rs | 25 ++---- node/runtime/Cargo.toml | 4 + node/runtime/src/lib.rs | 12 +-- srml/contracts/rpc/Cargo.toml | 17 ++++ srml/contracts/rpc/runtime-api/Cargo.toml | 20 +++++ srml/contracts/rpc/runtime-api/src/lib.rs | 64 +++++++++++++ .../contracts/rpc/src/lib.rs | 41 +++++---- srml/system/rpc/Cargo.toml | 23 +++++ srml/system/rpc/runtime-api/Cargo.toml | 16 ++++ srml/system/rpc/runtime-api/src/lib.rs | 34 +++++++ .../accounts.rs => srml/system/rpc/src/lib.rs | 89 ++++++++++--------- 20 files changed, 344 insertions(+), 182 deletions(-) create mode 100644 srml/contracts/rpc/Cargo.toml create mode 100644 srml/contracts/rpc/runtime-api/Cargo.toml create mode 100644 srml/contracts/rpc/runtime-api/src/lib.rs rename node/rpc/src/contracts.rs => srml/contracts/rpc/src/lib.rs (74%) create mode 100644 srml/system/rpc/Cargo.toml create mode 100644 srml/system/rpc/runtime-api/Cargo.toml create mode 100644 srml/system/rpc/runtime-api/src/lib.rs rename node/rpc/src/accounts.rs => srml/system/rpc/src/lib.rs (64%) diff --git a/Cargo.lock b/Cargo.lock index f83f550fdc..b42da79f88 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2417,12 +2417,8 @@ dependencies = [ name = "node-primitives" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-client 2.0.0", "substrate-primitives 2.0.0", "substrate-serializer 2.0.0", ] @@ -2431,23 +2427,12 @@ dependencies = [ name = "node-rpc" version = "2.0.0" dependencies = [ - "env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", - "node-runtime 2.0.0", - "node-testing 2.0.0", - "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", + "srml-contracts-rpc 2.0.0", + "srml-system-rpc 2.0.0", "substrate-client 2.0.0", - "substrate-keyring 2.0.0", - "substrate-primitives 2.0.0", - "substrate-rpc-primitives 2.0.0", "substrate-transaction-pool 2.0.0", ] @@ -2484,6 +2469,7 @@ dependencies = [ "srml-balances 2.0.0", "srml-collective 2.0.0", "srml-contracts 2.0.0", + "srml-contracts-rpc-runtime-api 2.0.0", "srml-democracy 2.0.0", "srml-elections 2.0.0", "srml-executive 2.0.0", @@ -2500,6 +2486,7 @@ dependencies = [ "srml-sudo 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", + "srml-system-rpc-runtime-api 2.0.0", "srml-timestamp 2.0.0", "srml-treasury 2.0.0", "srml-utility 2.0.0", @@ -4047,6 +4034,31 @@ dependencies = [ "wasmi-validation 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "srml-contracts-rpc" +version = "2.0.0" +dependencies = [ + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 2.0.0", + "srml-contracts-rpc-runtime-api 2.0.0", + "substrate-client 2.0.0", + "substrate-rpc-primitives 2.0.0", +] + +[[package]] +name = "srml-contracts-rpc-runtime-api" +version = "2.0.0" +dependencies = [ + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-std 2.0.0", + "substrate-client 2.0.0", +] + [[package]] name = "srml-democracy" version = "2.0.0" @@ -4434,6 +4446,34 @@ dependencies = [ "substrate-primitives 2.0.0", ] +[[package]] +name = "srml-system-rpc" +version = "2.0.0" +dependencies = [ + "env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 2.0.0", + "srml-system-rpc-runtime-api 2.0.0", + "substrate-client 2.0.0", + "substrate-primitives 2.0.0", + "substrate-test-runtime-client 2.0.0", + "substrate-transaction-pool 2.0.0", +] + +[[package]] +name = "srml-system-rpc-runtime-api" +version = "2.0.0" +dependencies = [ + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-client 2.0.0", +] + [[package]] name = "srml-timestamp" version = "2.0.0" @@ -5535,6 +5575,7 @@ dependencies = [ "srml-executive 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", + "srml-system-rpc-runtime-api 2.0.0", "srml-timestamp 2.0.0", "substrate-application-crypto 2.0.0", "substrate-client 2.0.0", diff --git a/Cargo.toml b/Cargo.toml index 7e34a0bd6c..6508e2b41e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -103,6 +103,7 @@ members = [ "srml/staking/reward-curve", "srml/sudo", "srml/system", + "srml/system/rpc", "srml/timestamp", "srml/treasury", "srml/utility", diff --git a/core/rpc/src/state/tests.rs b/core/rpc/src/state/tests.rs index ba1aac4cc3..3790b3ea11 100644 --- a/core/rpc/src/state/tests.rs +++ b/core/rpc/src/state/tests.rs @@ -282,7 +282,7 @@ fn should_return_runtime_version() { \"specVersion\":1,\"implVersion\":1,\"apis\":[[\"0xdf6acb689907609b\",2],\ [\"0x37e397fc7c91f5e4\",1],[\"0xd2bc9897eed08f15\",1],[\"0x40fe3ad401f8959a\",3],\ [\"0xc6e9a76309f39b09\",1],[\"0xdd718d5cc53262d4\",1],[\"0xcbca25e39f142387\",1],\ - [\"0xf78b278be53f454c\",1],[\"0xab3c0572291feb8b\",1]]}"; + [\"0xf78b278be53f454c\",1],[\"0xab3c0572291feb8b\",1],[\"0xbc9d89904f5b923f\",1]]}"; let runtime_version = api.runtime_version(None.into()).wait().unwrap(); let serialized = serde_json::to_string(&runtime_version).unwrap(); diff --git a/core/test-runtime/Cargo.toml b/core/test-runtime/Cargo.toml index 313db0fd07..fec9128ef5 100644 --- a/core/test-runtime/Cargo.toml +++ b/core/test-runtime/Cargo.toml @@ -31,6 +31,7 @@ cfg-if = "0.1.10" srml-babe = { path = "../../srml/babe", default-features = false } srml-timestamp = { path = "../../srml/timestamp", default-features = false } srml-system = { path = "../../srml/system", default-features = false } +srml-system-rpc-runtime-api = { path = "../../srml/system/rpc/runtime-api", default-features = false } [dev-dependencies] substrate-executor = { path = "../executor" } @@ -68,6 +69,7 @@ std = [ "srml-babe/std", "srml-timestamp/std", "srml-system/std", + "srml-system-rpc-runtime-api/std", "app-crypto/std", "session/std", ] diff --git a/core/test-runtime/src/lib.rs b/core/test-runtime/src/lib.rs index e75cb69149..fddee22be2 100644 --- a/core/test-runtime/src/lib.rs +++ b/core/test-runtime/src/lib.rs @@ -648,6 +648,12 @@ cfg_if! { SessionKeys::generate(None) } } + + impl srml_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(_account: AccountId) -> Index { + 0 + } + } } } else { impl_runtime_apis! { @@ -858,6 +864,12 @@ cfg_if! { SessionKeys::generate(None) } } + + impl srml_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(_account: AccountId) -> Index { + 0 + } + } } } } diff --git a/core/test-runtime/src/system.rs b/core/test-runtime/src/system.rs index f3359aa1ba..d06bef5923 100644 --- a/core/test-runtime/src/system.rs +++ b/core/test-runtime/src/system.rs @@ -18,7 +18,7 @@ //! and depositing logs. use rstd::prelude::*; -use runtime_io::{storage_root, storage_changes_root, twox_128, blake2_256}; +use runtime_io::{storage_root, storage_changes_root, blake2_256}; use runtime_support::storage::{self, StorageValue, StorageMap}; use runtime_support::storage_items; use sr_primitives::{ @@ -170,22 +170,14 @@ pub fn validate_transaction(utx: Extrinsic) -> TransactionValidity { return InvalidTransaction::Future.into(); } - let hash = |from: &AccountId, nonce: u64| { - twox_128(&nonce.to_keyed_vec(&from.encode())).to_vec() - }; + let encode = |from: &AccountId, nonce: u64| (from, nonce).encode(); let requires = if tx.nonce != expected_nonce && tx.nonce > 0 { - let mut deps = Vec::new(); - deps.push(hash(&tx.from, tx.nonce - 1)); - deps + vec![encode(&tx.from, tx.nonce - 1)] } else { - Vec::new() + vec![] }; - let provides = { - let mut p = Vec::new(); - p.push(hash(&tx.from, tx.nonce)); - p - }; + let provides = vec![encode(&tx.from, tx.nonce)]; Ok(ValidTransaction { priority: tx.amount, @@ -324,6 +316,7 @@ mod tests { use crate::{Header, Transfer, WASM_BINARY}; use primitives::{NeverNativeValue, map, traits::CodeExecutor}; use substrate_executor::{NativeExecutor, WasmExecutionMethod, native_executor_instance}; + use runtime_io::twox_128; // Declare an instance of the native executor dispatch for the test runtime. native_executor_instance!( diff --git a/node/primitives/Cargo.toml b/node/primitives/Cargo.toml index 266720b024..25725449a3 100644 --- a/node/primitives/Cargo.toml +++ b/node/primitives/Cargo.toml @@ -5,11 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -client = { package = "substrate-client", path = "../../core/client", default-features = false } -codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } -rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } -serde = { version = "1.0.101", optional = true, features = ["derive"] } sr-primitives = { path = "../../core/sr-primitives", default-features = false } [dev-dependencies] @@ -19,10 +15,6 @@ pretty_assertions = "0.6.1" [features] default = ["std"] std = [ - "client/std", - "codec/std", "primitives/std", - "rstd/std", - "serde", "sr-primitives/std", ] diff --git a/node/primitives/src/lib.rs b/node/primitives/src/lib.rs index 907b78a017..b8abdd7421 100644 --- a/node/primitives/src/lib.rs +++ b/node/primitives/src/lib.rs @@ -20,15 +20,10 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::prelude::*; use sr_primitives::{ generic, traits::{Verify, BlakeTwo256}, OpaqueExtrinsic, AnySignature }; -#[cfg(feature = "std")] -use serde::{Serialize, Deserialize}; -use codec::{Encode, Decode}; - /// An index to a block. pub type BlockNumber = u32; @@ -72,43 +67,3 @@ pub type BlockId = generic::BlockId; /// Opaque, encoded, unchecked extrinsic. pub type UncheckedExtrinsic = OpaqueExtrinsic; -/// A result of execution of a contract. -#[derive(Eq, PartialEq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] -pub enum ContractExecResult { - /// The contract returned successfully. - /// - /// There is a status code and, optionally, some data returned by the contract. - Success { - /// Status code returned by the contract. - status: u8, - /// Output data returned by the contract. - /// - /// Can be empty. - data: Vec, - }, - /// The contract execution either trapped or returned an error. - Error, -} - -client::decl_runtime_apis! { - /// The API to query account account nonce (aka index). - pub trait AccountNonceApi { - /// Get current account nonce of given `AccountId`. - fn account_nonce(account: AccountId) -> Index; - } - - /// The API to interact with contracts without using executive. - pub trait ContractsApi { - /// Perform a call from a specified account to a given contract. - /// - /// See the contracts' `call` dispatchable function for more details. - fn call( - origin: AccountId, - dest: AccountId, - value: Balance, - gas_limit: u64, - input_data: Vec, - ) -> ContractExecResult; - } -} diff --git a/node/rpc/Cargo.toml b/node/rpc/Cargo.toml index 6985d94e54..5d2ca81e0f 100644 --- a/node/rpc/Cargo.toml +++ b/node/rpc/Cargo.toml @@ -7,21 +7,8 @@ edition = "2018" [dependencies] client = { package = "substrate-client", path = "../../core/client" } jsonrpc-core = "13.2.0" -jsonrpc-core-client = "13.2.0" -jsonrpc-derive = "13.2.0" -jsonrpc-pubsub = "13.2.0" -keyring = { package = "substrate-keyring", path = "../../core/keyring" } -log = "0.4.8" node-primitives = { path = "../primitives" } -codec = { package = "parity-scale-codec", version = "1.0.0" } -serde = { version = "1.0.101", features = ["derive"] } sr-primitives = { path = "../../core/sr-primitives" } -substrate-primitives = { path = "../../core/primitives" } -rpc-primitives = { package = "substrate-rpc-primitives", path = "../../core/rpc/primitives" } +srml-contracts-rpc = { path = "../../srml/contracts/rpc/" } +srml-system-rpc = { path = "../../srml/system/rpc/" } transaction_pool = { package = "substrate-transaction-pool", path = "../../core/transaction-pool" } - -[dev-dependencies] -node-testing = { path = "../testing" } -node-runtime = { path = "../runtime" } -env_logger = "0.7.0" -futures03 = { package = "futures-preview", version = "=0.3.0-alpha.19" } diff --git a/node/rpc/src/lib.rs b/node/rpc/src/lib.rs index 43f723f796..398d458e63 100644 --- a/node/rpc/src/lib.rs +++ b/node/rpc/src/lib.rs @@ -25,43 +25,32 @@ //! The RPCs available in this crate however can make some assumptions //! about how the runtime is constructed and what `SRML` modules //! are part of it. Therefore all node-runtime-specific RPCs can -//! be placed here. +//! be placed here or imported from corresponding `SRML` RPC definitions. #![warn(missing_docs)] use std::sync::Arc; -use node_primitives::{Block, AccountNonceApi, ContractsApi}; +use node_primitives::{Block, AccountId, Index, Balance}; use sr_primitives::traits::ProvideRuntimeApi; use transaction_pool::txpool::{ChainApi, Pool}; -pub mod accounts; -pub mod contracts; - -mod constants { - /// A status code indicating an error happened while trying to call into the runtime. - /// - /// This typically means that the runtime trapped. - pub const RUNTIME_ERROR: i64 = 1; -} - /// Instantiate all RPC extensions. pub fn create(client: Arc, pool: Arc>) -> jsonrpc_core::IoHandler where C: ProvideRuntimeApi, C: client::blockchain::HeaderBackend, C: Send + Sync + 'static, - C::Api: AccountNonceApi + ContractsApi, + C::Api: srml_system_rpc::AccountNonceApi, + C::Api: srml_contracts_rpc::ContractsRuntimeApi, P: ChainApi + Sync + Send + 'static, M: jsonrpc_core::Metadata + Default, { - use self::{ - accounts::{Accounts, AccountsApi}, - contracts::{Contracts, ContractsApi}, - }; + use srml_system_rpc::{System, SystemApi}; + use srml_contracts_rpc::{Contracts, ContractsApi}; let mut io = jsonrpc_core::IoHandler::default(); io.extend_with( - AccountsApi::to_delegate(Accounts::new(client.clone(), pool)) + SystemApi::to_delegate(System::new(client.clone(), pool)) ); io.extend_with( ContractsApi::to_delegate(Contracts::new(client)) diff --git a/node/runtime/Cargo.toml b/node/runtime/Cargo.toml index a47d652100..f9818c096e 100644 --- a/node/runtime/Cargo.toml +++ b/node/runtime/Cargo.toml @@ -31,6 +31,7 @@ babe = { package = "srml-babe", path = "../../srml/babe", default-features = fal balances = { package = "srml-balances", path = "../../srml/balances", default-features = false } collective = { package = "srml-collective", path = "../../srml/collective", default-features = false } contracts = { package = "srml-contracts", path = "../../srml/contracts", default-features = false } +contracts-rpc-runtime-api = { package = "srml-contracts-rpc-runtime-api", path = "../../srml/contracts/rpc/runtime-api/", default-features = false } democracy = { package = "srml-democracy", path = "../../srml/democracy", default-features = false } elections = { package = "srml-elections", path = "../../srml/elections", default-features = false } executive = { package = "srml-executive", path = "../../srml/executive", default-features = false } @@ -47,6 +48,7 @@ srml-staking-reward-curve = { path = "../../srml/staking/reward-curve"} sudo = { package = "srml-sudo", path = "../../srml/sudo", default-features = false } support = { package = "srml-support", path = "../../srml/support", default-features = false } system = { package = "srml-system", path = "../../srml/system", default-features = false } +system-rpc-runtime-api = { package = "srml-system-rpc-runtime-api", path = "../../srml/system/rpc/runtime-api/", default-features = false } timestamp = { package = "srml-timestamp", path = "../../srml/timestamp", default-features = false } treasury = { package = "srml-treasury", path = "../../srml/treasury", default-features = false } utility = { package = "srml-utility", path = "../../srml/utility", default-features = false } @@ -67,6 +69,7 @@ std = [ "codec/std", "collective/std", "contracts/std", + "contracts-rpc-runtime-api/std", "democracy/std", "elections/std", "executive/std", @@ -93,6 +96,7 @@ std = [ "sudo/std", "support/std", "system/std", + "system-rpc-runtime-api/std", "timestamp/std", "treasury/std", "utility/std", diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index d8fc9a1a57..fd31969efa 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -27,7 +27,7 @@ use support::{ use primitives::u32_trait::{_1, _2, _3, _4}; use node_primitives::{ AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, - Moment, Signature, ContractExecResult, + Moment, Signature, }; use babe_primitives::{AuthorityId as BabeId, AuthoritySignature as BabeSignature}; use grandpa::fg_primitives; @@ -84,7 +84,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 175, + spec_version: 176, impl_version: 176, apis: RUNTIME_API_VERSIONS, }; @@ -660,20 +660,22 @@ impl_runtime_apis! { } } - impl node_primitives::AccountNonceApi for Runtime { + impl system_rpc_runtime_api::AccountNonceApi for Runtime { fn account_nonce(account: AccountId) -> Index { System::account_nonce(account) } } - impl node_primitives::ContractsApi for Runtime { + impl contracts_rpc_runtime_api::ContractsApi for Runtime { fn call( origin: AccountId, dest: AccountId, value: Balance, gas_limit: u64, input_data: Vec, - ) -> ContractExecResult { + ) -> contracts_rpc_runtime_api::ContractExecResult { + use contracts_rpc_runtime_api::ContractExecResult; + let exec_result = Contracts::bare_call( origin, dest.into(), diff --git a/srml/contracts/rpc/Cargo.toml b/srml/contracts/rpc/Cargo.toml new file mode 100644 index 0000000000..8ebb714e20 --- /dev/null +++ b/srml/contracts/rpc/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "srml-contracts-rpc" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +client = { package = "substrate-client", path = "../../../core/client" } +codec = { package = "parity-scale-codec", version = "1.0.0" } +jsonrpc-core = "13.2.0" +jsonrpc-core-client = "13.2.0" +jsonrpc-derive = "13.2.0" +rpc-primitives = { package = "substrate-rpc-primitives", path = "../../../core/rpc/primitives" } +serde = { version = "1.0.101", features = ["derive"] } +sr-primitives = { path = "../../../core/sr-primitives" } +srml-contracts-rpc-runtime-api = { path = "./runtime-api" } + diff --git a/srml/contracts/rpc/runtime-api/Cargo.toml b/srml/contracts/rpc/runtime-api/Cargo.toml new file mode 100644 index 0000000000..fce82aed2a --- /dev/null +++ b/srml/contracts/rpc/runtime-api/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "srml-contracts-rpc-runtime-api" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +client = { package = "substrate-client", path = "../../../../core/client", default-features = false } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +rstd = { package = "sr-std", path = "../../../../core/sr-std", default-features = false } +serde = { version = "1.0.101", optional = true, features = ["derive"] } + +[features] +default = ["std"] +std = [ + "client/std", + "codec/std", + "rstd/std", + "serde", +] diff --git a/srml/contracts/rpc/runtime-api/src/lib.rs b/srml/contracts/rpc/runtime-api/src/lib.rs new file mode 100644 index 0000000000..a5b56888ce --- /dev/null +++ b/srml/contracts/rpc/runtime-api/src/lib.rs @@ -0,0 +1,64 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Runtime API definition required by Contracts RPC extensions. +//! +//! This API should be imported and implemented by the runtime, +//! of a node that wants to use the custom RPC extension +//! adding Contracts access methods. + +#![cfg_attr(not(feature = "std"), no_std)] + +use rstd::vec::Vec; +use codec::{Encode, Decode, Codec}; + +/// A result of execution of a contract. +#[derive(Eq, PartialEq, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug, serde::Serialize, serde::Deserialize))] +pub enum ContractExecResult { + /// The contract returned successfully. + /// + /// There is a status code and, optionally, some data returned by the contract. + Success { + /// Status code returned by the contract. + status: u8, + /// Output data returned by the contract. + /// + /// Can be empty. + data: Vec, + }, + /// The contract execution either trapped or returned an error. + Error, +} + +client::decl_runtime_apis! { + /// The API to interact with contracts without using executive. + pub trait ContractsApi where + AccountId: Codec, + Balance: Codec, + { + /// Perform a call from a specified account to a given contract. + /// + /// See the contracts' `call` dispatchable function for more details. + fn call( + origin: AccountId, + dest: AccountId, + value: Balance, + gas_limit: u64, + input_data: Vec, + ) -> ContractExecResult; + } +} diff --git a/node/rpc/src/contracts.rs b/srml/contracts/rpc/src/lib.rs similarity index 74% rename from node/rpc/src/contracts.rs rename to srml/contracts/rpc/src/lib.rs index 3da2478dab..7e17aaaf17 100644 --- a/node/rpc/src/contracts.rs +++ b/srml/contracts/rpc/src/lib.rs @@ -20,22 +20,23 @@ use std::sync::Arc; use serde::{Serialize, Deserialize}; use client::blockchain::HeaderBackend; +use codec::Codec; use jsonrpc_core::{Error, ErrorCode, Result}; use jsonrpc_derive::rpc; -use node_primitives::{ - AccountId, Balance, Block, BlockId, ContractExecResult, ContractsApi as ContractsRuntimeApi, -}; -use sr_primitives::traits::{ - self, - Block as BlockT, +use sr_primitives::{ + generic::BlockId, + traits::{Block as BlockT, ProvideRuntimeApi}, }; use rpc_primitives::number; +pub use srml_contracts_rpc_runtime_api::{ContractExecResult, ContractsApi as ContractsRuntimeApi}; +pub use self::gen_client::Client as ContractsClient; + /// A struct that encodes RPC parameters required for a call to a smart-contract. #[derive(Serialize, Deserialize)] #[serde(rename_all="camelCase")] #[serde(deny_unknown_fields)] -pub struct CallRequest { +pub struct CallRequest { origin: AccountId, dest: AccountId, value: Balance, @@ -45,7 +46,7 @@ pub struct CallRequest { /// Contracts RPC methods. #[rpc] -pub trait ContractsApi { +pub trait ContractsApi { /// Executes a call to a contract. /// /// This call is performed locally without submitting any transactions. Thus executing this @@ -55,33 +56,39 @@ pub trait ContractsApi { #[rpc(name = "contracts_call")] fn call( &self, - call_request: CallRequest, + call_request: CallRequest, at: Option, ) -> Result; } /// An implementation of contract specific RPC methods. -pub struct Contracts { +pub struct Contracts { client: Arc, + _marker: std::marker::PhantomData, } -impl Contracts { +impl Contracts { /// Create new `Contracts` with the given reference to the client. pub fn new(client: Arc) -> Self { - Contracts { client } + Contracts { client, _marker: Default::default() } } } -impl ContractsApi<::Hash> for Contracts +const RUNTIME_ERROR: i64 = 1; + +impl ContractsApi<::Hash, AccountId, Balance> for Contracts where + Block: BlockT, C: Send + Sync + 'static, - C: traits::ProvideRuntimeApi, + C: ProvideRuntimeApi, C: HeaderBackend, - C::Api: ContractsRuntimeApi, + C::Api: ContractsRuntimeApi, + AccountId: Codec, + Balance: Codec, { fn call( &self, - call_request: CallRequest, + call_request: CallRequest, at: Option<::Hash>, ) -> Result { let api = self.client.runtime_api(); @@ -106,7 +113,7 @@ where let exec_result = api .call(&at, origin, dest, value, gas_limit, input_data) .map_err(|e| Error { - code: ErrorCode::ServerError(crate::constants::RUNTIME_ERROR), + code: ErrorCode::ServerError(RUNTIME_ERROR), message: "Runtime trapped while executing a contract.".into(), data: Some(format!("{:?}", e).into()), })?; diff --git a/srml/system/rpc/Cargo.toml b/srml/system/rpc/Cargo.toml new file mode 100644 index 0000000000..04856a817f --- /dev/null +++ b/srml/system/rpc/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "srml-system-rpc" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +client = { package = "substrate-client", path = "../../../core/client" } +codec = { package = "parity-scale-codec", version = "1.0.0" } +jsonrpc-core = "13.2.0" +jsonrpc-core-client = "13.2.0" +jsonrpc-derive = "13.2.0" +log = "0.4.8" +serde = { version = "1.0.101", features = ["derive"] } +sr-primitives = { path = "../../../core/sr-primitives" } +srml-system-rpc-runtime-api = { path = "./runtime-api" } +substrate-primitives = { path = "../../../core/primitives" } +transaction_pool = { package = "substrate-transaction-pool", path = "../../../core/transaction-pool" } + +[dev-dependencies] +test-client = { package = "substrate-test-runtime-client", path = "../../../core/test-runtime/client" } +env_logger = "0.7.0" +futures03 = { package = "futures-preview", version = "=0.3.0-alpha.19" } diff --git a/srml/system/rpc/runtime-api/Cargo.toml b/srml/system/rpc/runtime-api/Cargo.toml new file mode 100644 index 0000000000..fc525d8fce --- /dev/null +++ b/srml/system/rpc/runtime-api/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "srml-system-rpc-runtime-api" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +client = { package = "substrate-client", path = "../../../../core/client", default-features = false } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } + +[features] +default = ["std"] +std = [ + "client/std", + "codec/std", +] diff --git a/srml/system/rpc/runtime-api/src/lib.rs b/srml/system/rpc/runtime-api/src/lib.rs new file mode 100644 index 0000000000..45af0241e0 --- /dev/null +++ b/srml/system/rpc/runtime-api/src/lib.rs @@ -0,0 +1,34 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Runtime API definition required by System RPC extensions. +//! +//! This API should be imported and implemented by the runtime, +//! of a node that wants to use the custom RPC extension +//! adding System access methods. + +#![cfg_attr(not(feature = "std"), no_std)] + +client::decl_runtime_apis! { + /// The API to query account nonce (aka transaction index). + pub trait AccountNonceApi where + AccountId: codec::Codec, + Index: codec::Codec, + { + /// Get current account nonce of given `AccountId`. + fn account_nonce(account: AccountId) -> Index; + } +} diff --git a/node/rpc/src/accounts.rs b/srml/system/rpc/src/lib.rs similarity index 64% rename from node/rpc/src/accounts.rs rename to srml/system/rpc/src/lib.rs index 6c8e60736a..c6c0a658fb 100644 --- a/node/rpc/src/accounts.rs +++ b/srml/system/rpc/src/lib.rs @@ -14,58 +14,66 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Node-specific RPC methods for Accounts. +//! System SRML specific RPC methods. use std::sync::Arc; +use codec::{self, Codec, Encode}; use client::blockchain::HeaderBackend; use jsonrpc_core::{Result, Error, ErrorCode}; use jsonrpc_derive::rpc; -use node_primitives::{ - AccountId, Index, AccountNonceApi, Block, BlockId, +use sr_primitives::{ + generic::BlockId, + traits, }; -use codec::Encode; -use sr_primitives::traits; use substrate_primitives::hexdisplay::HexDisplay; use transaction_pool::txpool::{self, Pool}; -pub use self::gen_client::Client as AccountsClient; +pub use srml_system_rpc_runtime_api::AccountNonceApi; +pub use self::gen_client::Client as SystemClient; -/// Accounts RPC methods. +/// System RPC methods. #[rpc] -pub trait AccountsApi { +pub trait SystemApi { /// Returns the next valid index (aka nonce) for given account. /// /// This method takes into consideration all pending transactions /// currently in the pool and if no transactions are found in the pool /// it fallbacks to query the index from the runtime (aka. state nonce). - #[rpc(name = "account_nextIndex")] + #[rpc(name = "system_accountNextIndex", alias("account_nextIndex"))] fn nonce(&self, account: AccountId) -> Result; } -/// An implementation of Accounts specific RPC methods. -pub struct Accounts { +const RUNTIME_ERROR: i64 = 1; + +/// An implementation of System-specific RPC methods. +pub struct System { client: Arc, pool: Arc>, + _marker: std::marker::PhantomData, } -impl Accounts { - /// Create new `Accounts` given client and transaction pool. +impl System { + /// Create new `System` given client and transaction pool. pub fn new(client: Arc, pool: Arc>) -> Self { - Accounts { + System { client, - pool + pool, + _marker: Default::default(), } } } -impl AccountsApi for Accounts +impl SystemApi for System where C: traits::ProvideRuntimeApi, C: HeaderBackend, C: Send + Sync + 'static, - C::Api: AccountNonceApi, + C::Api: AccountNonceApi, P: txpool::ChainApi + Sync + Send + 'static, + Block: traits::Block, + AccountId: Clone + std::fmt::Display + Codec, + Index: Clone + std::fmt::Display + Codec + traits::SimpleArithmetic, { fn nonce(&self, account: AccountId) -> Result { let api = self.client.runtime_api(); @@ -73,7 +81,7 @@ where let at = BlockId::hash(best); let nonce = api.account_nonce(&at, account.clone()).map_err(|e| Error { - code: ErrorCode::ServerError(crate::constants::RUNTIME_ERROR), + code: ErrorCode::ServerError(RUNTIME_ERROR), message: "Unable to query nonce.".into(), data: Some(format!("{:?}", e).into()), })?; @@ -85,12 +93,12 @@ where // Since extrinsics are opaque to us, we look for them using // `provides` tag. And increment the nonce if we find a transaction // that matches the current one. - let mut current_nonce = nonce; - let mut current_tag = (account.clone(), nonce).encode(); + let mut current_nonce = nonce.clone(); + let mut current_tag = (account.clone(), nonce.clone()).encode(); for tx in self.pool.ready() { log::debug!( target: "rpc", - "Current nonce to {:?}, checking {} vs {:?}", + "Current nonce to {}, checking {} vs {:?}", current_nonce, HexDisplay::from(¤t_tag), tx.provides.iter().map(|x| format!("{}", HexDisplay::from(x))).collect::>(), @@ -98,8 +106,8 @@ where // since transactions in `ready()` need to be ordered by nonce // it's fine to continue with current iterator. if tx.provides.get(0) == Some(¤t_tag) { - current_nonce += 1; - current_tag = (account.clone(), current_nonce).encode(); + current_nonce += traits::One::one(); + current_tag = (account.clone(), current_nonce.clone()).encode(); } } @@ -112,42 +120,37 @@ mod tests { use super::*; use futures03::executor::block_on; - use node_runtime::{CheckedExtrinsic, Call, TimestampCall}; - use codec::Decode; - use node_testing::{ - client::{ClientExt, TestClientBuilder, TestClientBuilderExt}, - keyring::{self, alice, signed_extra}, + use test_client::{ + runtime::Transfer, + AccountKeyring, }; - const VERSION: u32 = node_runtime::VERSION.spec_version; - #[test] fn should_return_next_nonce_for_some_account() { // given let _ = env_logger::try_init(); - let client = Arc::new(TestClientBuilder::new().build()); + let client = Arc::new(test_client::new()); let pool = Arc::new(Pool::new(Default::default(), transaction_pool::FullChainApi::new(client.clone()))); - let new_transaction = |extra| { - let ex = CheckedExtrinsic { - signed: Some((alice().into(), extra)), - function: Call::Timestamp(TimestampCall::set(5)), + let new_transaction = |nonce: u64| { + let t = Transfer { + from: AccountKeyring::Alice.into(), + to: AccountKeyring::Bob.into(), + amount: 5, + nonce, }; - let xt = keyring::sign(ex, VERSION, client.genesis_hash().into()); - // Convert to OpaqueExtrinsic - let encoded = xt.encode(); - node_primitives::UncheckedExtrinsic::decode(&mut &*encoded).unwrap() + t.into_signed_tx() }; // Populate the pool - let ext0 = new_transaction(signed_extra(0, 0)); + let ext0 = new_transaction(0); block_on(pool.submit_one(&BlockId::number(0), ext0)).unwrap(); - let ext1 = new_transaction(signed_extra(1, 0)); + let ext1 = new_transaction(1); block_on(pool.submit_one(&BlockId::number(0), ext1)).unwrap(); - let accounts = Accounts::new(client, pool); + let accounts = System::new(client, pool); // when - let nonce = accounts.nonce(alice().into()); + let nonce = accounts.nonce(AccountKeyring::Alice.into()); // then assert_eq!(nonce.unwrap(), 2); -- GitLab From e0f3fa3845654770f6d96dbaa2d3a76842ad44f3 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 16 Oct 2019 15:47:46 +0200 Subject: [PATCH 219/275] Refactor decl storage (#3765) * split implementation in multiple files: * transformation -> genesis_config/ getters.rs instance_trait.rs metadata.rs mod.rs store_trait.rs * mod.rs -> parser.rs * impl.rs -> storage_struct.rs * parser is isolated into parse module, it could be improved as well but this can be done in another PR * modules contains a defintion of decl_storage input which must be ok to work with. * implementation change: * T: Trait might be more often bound to 'static (anyway we only use static one and it is needed for metadata current implementation). * GenesisConfig no longer requires its fields to be Clone (possible since to EncodeLike feature) * builder for map storages must return precise type Vec<(key, value)> --- node/runtime/src/lib.rs | 4 +- srml/support/procedural/src/lib.rs | 2 +- .../src/storage/genesis_config/builder_def.rs | 111 ++ .../genesis_config/genesis_config_def.rs | 144 ++ .../src/storage/genesis_config/mod.rs | 203 +++ .../support/procedural/src/storage/getters.rs | 80 ++ srml/support/procedural/src/storage/impls.rs | 418 ------ .../procedural/src/storage/instance_trait.rs | 196 +++ .../procedural/src/storage/metadata.rs | 230 +++ srml/support/procedural/src/storage/mod.rs | 521 ++++--- srml/support/procedural/src/storage/parse.rs | 377 +++++ .../procedural/src/storage/storage_struct.rs | 220 +++ .../procedural/src/storage/store_trait.rs | 54 + .../procedural/src/storage/transformation.rs | 1264 ----------------- srml/support/procedural/tools/src/syn_ext.rs | 12 +- 15 files changed, 1978 insertions(+), 1858 deletions(-) create mode 100644 srml/support/procedural/src/storage/genesis_config/builder_def.rs create mode 100644 srml/support/procedural/src/storage/genesis_config/genesis_config_def.rs create mode 100644 srml/support/procedural/src/storage/genesis_config/mod.rs create mode 100644 srml/support/procedural/src/storage/getters.rs delete mode 100644 srml/support/procedural/src/storage/impls.rs create mode 100644 srml/support/procedural/src/storage/instance_trait.rs create mode 100644 srml/support/procedural/src/storage/metadata.rs create mode 100644 srml/support/procedural/src/storage/parse.rs create mode 100644 srml/support/procedural/src/storage/storage_struct.rs create mode 100644 srml/support/procedural/src/storage/store_trait.rs delete mode 100644 srml/support/procedural/src/storage/transformation.rs diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index fd31969efa..63fc856013 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -84,8 +84,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 176, - impl_version: 176, + spec_version: 177, + impl_version: 177, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/support/procedural/src/lib.rs b/srml/support/procedural/src/lib.rs index a9cfa8d30d..38d404712e 100644 --- a/srml/support/procedural/src/lib.rs +++ b/srml/support/procedural/src/lib.rs @@ -213,5 +213,5 @@ use proc_macro::TokenStream; /// #[proc_macro] pub fn decl_storage(input: TokenStream) -> TokenStream { - storage::transformation::decl_storage_impl(input) + storage::decl_storage_impl(input) } diff --git a/srml/support/procedural/src/storage/genesis_config/builder_def.rs b/srml/support/procedural/src/storage/genesis_config/builder_def.rs new file mode 100644 index 0000000000..60f094e9fe --- /dev/null +++ b/srml/support/procedural/src/storage/genesis_config/builder_def.rs @@ -0,0 +1,111 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Builder logic definition used to build genesis storage. + +use srml_support_procedural_tools::syn_ext as ext; +use proc_macro2::TokenStream; +use syn::spanned::Spanned; +use quote::{quote, quote_spanned}; +use super::super::{DeclStorageDefExt, StorageLineTypeDef}; + +/// Definition of builder blocks, each block insert some value in the storage. +/// They must be called inside externalities, and with `self` being the genesis config. +pub struct BuilderDef { + /// Contains: + /// * build block for storage with build attribute. + /// * build block for storage with config attribute and no build attribute. + /// * build block for extra genesis build expression. + pub blocks: Vec, + /// The build blocks requires generic traits. + pub is_generic: bool, +} + +impl BuilderDef { + pub fn from_def(scrate: &TokenStream, def: &DeclStorageDefExt) -> Self { + let mut blocks = Vec::new(); + let mut is_generic = false; + + for line in def.storage_lines.iter() { + let storage_struct = &line.storage_struct; + let storage_trait = &line.storage_trait; + let value_type = &line.value_type; + + // Contains the data to inset at genesis either from build or config. + let mut data = None; + + if let Some(builder) = &line.build { + is_generic |= ext::expr_contains_ident(&builder, &def.module_runtime_generic); + is_generic |= line.is_generic; + + data = Some(quote_spanned!(builder.span() => &(#builder)(&self))); + } else if let Some(config) = &line.config { + is_generic |= line.is_generic; + + data = Some(quote!(&self.#config;)); + }; + + if let Some(data) = data { + blocks.push(match &line.storage_type { + StorageLineTypeDef::Simple(_) => { + quote!{{ + let v: &#value_type = #data; + <#storage_struct as #scrate::#storage_trait>::put::<&#value_type>(v); + }} + }, + StorageLineTypeDef::Map(map) | StorageLineTypeDef::LinkedMap(map) => { + let key = &map.key; + quote!{{ + let data: &#scrate::rstd::vec::Vec<(#key, #value_type)> = #data; + data.iter().for_each(|(k, v)| { + <#storage_struct as #scrate::#storage_trait>::insert::< + &#key, &#value_type + >(k, v); + }); + }} + }, + StorageLineTypeDef::DoubleMap(map) => { + let key1 = &map.key1; + let key2 = &map.key2; + quote!{{ + let data: &#scrate::rstd::vec::Vec<(#key1, #key2, #value_type)> = #data; + data.iter().for_each(|(k1, k2, v)| { + <#storage_struct as #scrate::#storage_trait>::insert::< + &#key1, &#key2, &#value_type + >(k1, k2, v); + }); + }} + }, + }); + } + } + + if let Some(builder) = def.extra_genesis_build.as_ref() { + is_generic |= ext::expr_contains_ident(&builder, &def.module_runtime_generic); + + blocks.push(quote_spanned! { builder.span() => + let extra_genesis_builder: fn(&Self) = #builder; + extra_genesis_builder(&self); + }); + } + + + Self { + blocks, + is_generic, + } + } +} diff --git a/srml/support/procedural/src/storage/genesis_config/genesis_config_def.rs b/srml/support/procedural/src/storage/genesis_config/genesis_config_def.rs new file mode 100644 index 0000000000..f9d2f8abe8 --- /dev/null +++ b/srml/support/procedural/src/storage/genesis_config/genesis_config_def.rs @@ -0,0 +1,144 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Genesis config defintion. + +use srml_support_procedural_tools::syn_ext as ext; +use proc_macro2::TokenStream; +use syn::parse_quote; +use quote::quote; +use super::super::{DeclStorageDefExt, StorageLineTypeDef}; + +pub struct GenesisConfigFieldDef { + pub doc: Vec, + pub name: syn::Ident, + pub typ: syn::Type, + pub default: TokenStream, +} + +pub struct GenesisConfigDef { + pub is_generic: bool, + pub fields: Vec, + /// For example: `, I: Instance=DefaultInstance>`. + pub genesis_struct_decl: TokenStream, + /// For example: ``. + pub genesis_struct: TokenStream, + /// For example: `, I: Instance>`. + pub genesis_impl: TokenStream, + /// The where clause to use to constrain generics if genesis config is generic. + pub genesis_where_clause: Option, +} + +impl GenesisConfigDef { + pub fn from_def(def: &DeclStorageDefExt) -> Self { + let fields = Self::get_genesis_config_field_defs(def); + + let is_generic = fields.iter() + .any(|field| ext::type_contains_ident(&field.typ, &def.module_runtime_generic)); + + let ( + genesis_struct_decl, + genesis_impl, + genesis_struct, + genesis_where_clause + ) = if is_generic { + let runtime_generic = &def.module_runtime_generic; + let runtime_trait = &def.module_runtime_trait; + let optional_instance = &def.optional_instance; + let optional_instance_bound = &def.optional_instance_bound; + let optional_instance_bound_optional_default = &def.optional_instance_bound_optional_default; + let where_clause = &def.where_clause; + ( + quote!(<#runtime_generic: #runtime_trait, #optional_instance_bound_optional_default>), + quote!(<#runtime_generic: #runtime_trait, #optional_instance_bound>), + quote!(<#runtime_generic, #optional_instance>), + where_clause.clone(), + ) + } else { + (quote!(), quote!(), quote!(), None) + }; + + Self { + is_generic, + fields, + genesis_struct_decl, + genesis_struct, + genesis_impl, + genesis_where_clause, + } + } + + fn get_genesis_config_field_defs(def: &DeclStorageDefExt) -> Vec { + let mut config_field_defs = Vec::new(); + + for (config_field, line) in def.storage_lines.iter() + .filter_map(|line| line.config.as_ref().map(|config_field| (config_field.clone(), line))) + { + let value_type = &line.value_type; + + let typ = match &line.storage_type { + StorageLineTypeDef::Simple(_) => (*value_type).clone(), + StorageLineTypeDef::Map(map) | StorageLineTypeDef::LinkedMap(map) => { + let key = &map.key; + parse_quote!( Vec<(#key, #value_type)> ) + }, + StorageLineTypeDef::DoubleMap(map) => { + let key1 = &map.key1; + let key2 = &map.key2; + + parse_quote!( Vec<(#key1, #key2, #value_type)> ) + }, + }; + + let default = line.default_value.as_ref() + .map(|d| { + if line.is_option { + quote!( #d.unwrap_or_default() ) + } else { + quote!( #d ) + } + }) + .unwrap_or_else(|| quote!( Default::default() )); + + config_field_defs.push(GenesisConfigFieldDef { + doc: line.doc_attrs.clone(), + name: config_field, + typ, + default, + }); + } + + for line in &def.extra_genesis_config_lines { + let doc = line.attrs.iter() + .filter_map(|a| a.parse_meta().ok()) + .filter(|m| m.name() == "doc") + .collect(); + + let default = line.default.as_ref().map(|e| quote!( #e )) + .unwrap_or_else(|| quote!( Default::default() )); + + + config_field_defs.push(GenesisConfigFieldDef { + doc, + name: line.name.clone(), + typ: line.typ.clone(), + default, + }); + } + + config_field_defs + } +} diff --git a/srml/support/procedural/src/storage/genesis_config/mod.rs b/srml/support/procedural/src/storage/genesis_config/mod.rs new file mode 100644 index 0000000000..57de1e34a8 --- /dev/null +++ b/srml/support/procedural/src/storage/genesis_config/mod.rs @@ -0,0 +1,203 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Declaration of genesis config structure and implementation of build storage trait and +//! functions. + +use proc_macro2::{TokenStream, Span}; +use quote::quote; +use super::{DeclStorageDefExt, instance_trait::DEFAULT_INSTANTIABLE_TRAIT_NAME}; +use genesis_config_def::GenesisConfigDef; +use builder_def::BuilderDef; + +mod genesis_config_def; +mod builder_def; + +const DEFAULT_INSTANCE_NAME: &str = "__GeneratedInstance"; + +fn decl_genesis_config_and_impl_default( + scrate: &TokenStream, + genesis_config: &GenesisConfigDef, +) -> TokenStream { + let config_fields = genesis_config.fields.iter().map(|field| { + let (name, typ, doc) = (&field.name, &field.typ, &field.doc); + quote!( #( #[ #doc] )* pub #name: #typ, ) + }); + + let config_field_defaults = genesis_config.fields.iter().map(|field| { + let (name, default, doc) = (&field.name, &field.default, &field.doc); + quote!( #( #[ #doc] )* #name: #default, ) + }); + + let serde_bug_bound = if !genesis_config.fields.is_empty() { + let mut b_ser = String::new(); + let mut b_dser = String::new(); + + for typ in genesis_config.fields.iter().map(|c| &c.typ) { + let typ = quote!( #typ ); + b_ser.push_str(&format!("{} : {}::serde::Serialize, ", typ, scrate)); + b_dser.push_str(&format!("{} : {}::serde::de::DeserializeOwned, ", typ, scrate)); + } + + quote! { + #[serde(bound(serialize = #b_ser))] + #[serde(bound(deserialize = #b_dser))] + } + } else { + quote!() + }; + + let genesis_struct_decl = &genesis_config.genesis_struct_decl; + let genesis_struct = &genesis_config.genesis_struct; + let genesis_impl = &genesis_config.genesis_impl; + let genesis_where_clause = &genesis_config.genesis_where_clause; + + quote!( + #[derive(#scrate::Serialize, #scrate::Deserialize)] + #[cfg(feature = "std")] + #[serde(rename_all = "camelCase")] + #[serde(deny_unknown_fields)] + #serde_bug_bound + pub struct GenesisConfig#genesis_struct_decl #genesis_where_clause { + #( #config_fields )* + } + + #[cfg(feature = "std")] + impl#genesis_impl Default for GenesisConfig#genesis_struct #genesis_where_clause { + fn default() -> Self { + GenesisConfig { + #( #config_field_defaults )* + } + } + } + ) +} + +fn impl_build_storage( + scrate: &TokenStream, + def: &DeclStorageDefExt, + genesis_config: &GenesisConfigDef, + builders: &BuilderDef, +) -> TokenStream { + let runtime_generic = &def.module_runtime_generic; + let runtime_trait = &def.module_runtime_trait; + let optional_instance = &def.optional_instance; + let optional_instance_bound = &def.optional_instance_bound; + let where_clause = &def.where_clause; + + let inherent_instance = def.optional_instance.clone().unwrap_or_else(|| { + let name = syn::Ident::new(DEFAULT_INSTANCE_NAME, Span::call_site()); + quote!( #name ) + }); + let inherent_instance_bound = def.optional_instance_bound.clone().unwrap_or_else(|| { + let bound = syn::Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site()); + quote!( #inherent_instance: #bound ) + }); + + let build_storage_impl = quote!( + <#runtime_generic: #runtime_trait, #inherent_instance_bound> + ); + + let genesis_struct = &genesis_config.genesis_struct; + let genesis_impl = &genesis_config.genesis_impl; + let genesis_where_clause = &genesis_config.genesis_where_clause; + + let ( + fn_generic, + fn_traitinstance, + fn_where_clause + ) = if !genesis_config.is_generic && builders.is_generic { + ( + quote!( <#runtime_generic: #runtime_trait, #optional_instance_bound> ), + quote!( #runtime_generic, #optional_instance ), + Some(&def.where_clause), + ) + } else { + (quote!(), quote!(), None) + }; + + let builder_blocks = &builders.blocks; + + let build_storage_impl_trait = quote!( + #scrate::sr_primitives::BuildModuleGenesisStorage<#runtime_generic, #inherent_instance> + ); + + quote!{ + #[cfg(feature = "std")] + impl#genesis_impl GenesisConfig#genesis_struct #genesis_where_clause { + pub fn build_storage #fn_generic (self) -> std::result::Result< + ( + #scrate::sr_primitives::StorageOverlay, + #scrate::sr_primitives::ChildrenStorageOverlay, + ), + String + > #fn_where_clause { + let mut storage = (Default::default(), Default::default()); + self.assimilate_storage::<#fn_traitinstance>(&mut storage)?; + Ok(storage) + } + + /// Assimilate the storage for this module into pre-existing overlays. + pub fn assimilate_storage #fn_generic ( + self, + tuple_storage: &mut ( + #scrate::sr_primitives::StorageOverlay, + #scrate::sr_primitives::ChildrenStorageOverlay, + ), + ) -> std::result::Result<(), String> #fn_where_clause { + #scrate::with_storage(tuple_storage, || { + #( #builder_blocks )* + Ok(()) + }) + } + } + + #[cfg(feature = "std")] + impl#build_storage_impl #build_storage_impl_trait for GenesisConfig#genesis_struct + #where_clause + { + fn build_module_genesis_storage( + self, + storage: &mut ( + #scrate::sr_primitives::StorageOverlay, + #scrate::sr_primitives::ChildrenStorageOverlay, + ), + ) -> std::result::Result<(), String> { + self.assimilate_storage::<#fn_traitinstance> (storage) + } + } + } +} + +pub fn genesis_config_and_build_storage( + scrate: &TokenStream, + def: &DeclStorageDefExt, +) -> TokenStream { + let builders = BuilderDef::from_def(scrate, def); + if !builders.blocks.is_empty() { + let genesis_config = &GenesisConfigDef::from_def(def); + let decl_genesis_config_and_impl_default = + decl_genesis_config_and_impl_default(scrate, genesis_config); + let impl_build_storage = impl_build_storage(scrate, def, genesis_config, &builders); + + quote!{ + #decl_genesis_config_and_impl_default + #impl_build_storage + } + } else { + quote!() + } +} diff --git a/srml/support/procedural/src/storage/getters.rs b/srml/support/procedural/src/storage/getters.rs new file mode 100644 index 0000000000..f30e489eb5 --- /dev/null +++ b/srml/support/procedural/src/storage/getters.rs @@ -0,0 +1,80 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Implementation of getters on module structure. + +use proc_macro2::TokenStream; +use quote::quote; +use super::{DeclStorageDefExt, StorageLineTypeDef}; + +pub fn impl_getters(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStream { + let mut getters = TokenStream::new(); + + for (get_fn, line) in def.storage_lines.iter() + .filter_map(|line| line.getter.as_ref().map(|get_fn| (get_fn, line))) + { + let attrs = &line.doc_attrs; + + let storage_struct = &line.storage_struct; + let storage_trait = &line.storage_trait; + + let getter = match &line.storage_type { + StorageLineTypeDef::Simple(value) => { + quote!{ + #( #[ #attrs ] )* + pub fn #get_fn() -> #value { + <#storage_struct as #scrate::#storage_trait>::get() + } + } + }, + StorageLineTypeDef::Map(map) | StorageLineTypeDef::LinkedMap(map) => { + let key = &map.key; + let value = &map.value; + quote!{ + #( #[ #attrs ] )* + pub fn #get_fn>(key: K) -> #value { + <#storage_struct as #scrate::#storage_trait>::get(key) + } + } + }, + StorageLineTypeDef::DoubleMap(map) => { + let key1 = &map.key1; + let key2 = &map.key2; + let value = &map.value; + quote!{ + pub fn #get_fn(k1: KArg1, k2: KArg2) -> #value + where + KArg1: #scrate::codec::EncodeLike<#key1>, + KArg2: #scrate::codec::EncodeLike<#key2>, + { + <#storage_struct as #scrate::#storage_trait>::get(k1, k2) + } + } + }, + }; + getters.extend(getter); + } + + let module_struct = &def.module_struct; + let module_impl = &def.module_impl; + let where_clause = &def.where_clause; + + quote!( + impl#module_impl #module_struct #where_clause { + #getters + } + ) +} diff --git a/srml/support/procedural/src/storage/impls.rs b/srml/support/procedural/src/storage/impls.rs deleted file mode 100644 index ee6fa9a164..0000000000 --- a/srml/support/procedural/src/storage/impls.rs +++ /dev/null @@ -1,418 +0,0 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -use crate::storage::transformation::{DeclStorageTypeInfos, InstanceOpts}; - -use srml_support_procedural_tools::syn_ext as ext; -use proc_macro2::TokenStream as TokenStream2; -use syn::Ident; -use quote::quote; - -fn from_optional_value_to_query(is_option: bool, fielddefault: TokenStream2) -> TokenStream2 { - if !is_option { - // raw type case - quote!( v.unwrap_or_else(|| #fielddefault ) ) - } else { - // Option<> type case - quote!( v.or_else(|| #fielddefault ) ) - } -} - -fn from_query_to_optional_value(is_option: bool) -> TokenStream2 { - if !is_option { - // raw type case - quote!( Some(v) ) - } else { - // Option<> type case - quote!( v ) - } -} - -// prefix for consts in trait Instance -pub(crate) const PREFIX_FOR: &str = "PREFIX_FOR_"; -pub(crate) const HEAD_KEY_FOR: &str = "HEAD_KEY_FOR_"; - -pub(crate) struct Impls<'a, I: Iterator> { - pub scrate: &'a TokenStream2, - pub visibility: &'a syn::Visibility, - pub traitinstance: &'a syn::Ident, - pub traittype: &'a syn::TypeParamBound, - pub instance_opts: &'a InstanceOpts, - pub type_infos: DeclStorageTypeInfos<'a>, - pub fielddefault: TokenStream2, - pub prefix: String, - pub cratename: &'a syn::Ident, - pub name: &'a syn::Ident, - pub attrs: I, - pub where_clause: &'a Option, -} - -impl<'a, I: Iterator> Impls<'a, I> { - pub fn simple_value(self) -> TokenStream2 { - let Self { - scrate, - visibility, - traitinstance, - traittype, - instance_opts, - type_infos, - fielddefault, - prefix, - name, - attrs, - where_clause, - .. - } = self; - let DeclStorageTypeInfos { typ, value_type, is_option, .. } = type_infos; - - let from_optional_value_to_query = from_optional_value_to_query(is_option, fielddefault); - let from_query_to_optional_value = from_query_to_optional_value(is_option); - - let InstanceOpts { - equal_default_instance, - bound_instantiable, - instance, - .. - } = instance_opts; - - let final_prefix = if let Some(instance) = instance { - let const_name = Ident::new(&format!("{}{}", PREFIX_FOR, name.to_string()), proc_macro2::Span::call_site()); - quote!{ #instance::#const_name.as_bytes() } - } else { - quote!{ #prefix.as_bytes() } - }; - - let (struct_trait, impl_trait, trait_and_instance, where_clause) = if ext::type_contains_ident( - value_type, traitinstance - ) { - ( - quote!(#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance), - quote!(#traitinstance: #traittype, #instance #bound_instantiable), - quote!(#traitinstance, #instance), - where_clause.clone(), - ) - } else { - ( - quote!(#instance #bound_instantiable #equal_default_instance), - quote!(#instance #bound_instantiable), - quote!(#instance), - None, - ) - }; - - // generator for value - quote! { - #( #[ #attrs ] )* - #visibility struct #name<#struct_trait>( - #scrate::rstd::marker::PhantomData<(#trait_and_instance)> - ) #where_clause; - - impl<#impl_trait> #scrate::storage::generator::StorageValue<#typ> - for #name<#trait_and_instance> #where_clause - { - type Query = #value_type; - - fn unhashed_key() -> &'static [u8] { - #final_prefix - } - - fn from_optional_value_to_query(v: Option<#typ>) -> Self::Query { - #from_optional_value_to_query - } - - fn from_query_to_optional_value(v: Self::Query) -> Option<#typ> { - #from_query_to_optional_value - } - } - } - } - - pub fn map(self, hasher: TokenStream2, kty: &syn::Type) -> TokenStream2 { - let Self { - scrate, - visibility, - traitinstance, - traittype, - instance_opts, - type_infos, - fielddefault, - prefix, - name, - attrs, - where_clause, - .. - } = self; - let DeclStorageTypeInfos { typ, value_type, is_option, .. } = type_infos; - - let from_optional_value_to_query = from_optional_value_to_query(is_option, fielddefault); - let from_query_to_optional_value = from_query_to_optional_value(is_option); - - let InstanceOpts { - equal_default_instance, - bound_instantiable, - instance, - .. - } = instance_opts; - - let final_prefix = if let Some(instance) = instance { - let const_name = syn::Ident::new( - &format!("{}{}", PREFIX_FOR, name.to_string()), - proc_macro2::Span::call_site(), - ); - quote! { #instance::#const_name.as_bytes() } - } else { - quote! { #prefix.as_bytes() } - }; - - let trait_required = ext::type_contains_ident(value_type, traitinstance) - || ext::type_contains_ident(kty, traitinstance); - - let (struct_trait, impl_trait, trait_and_instance, where_clause) = if trait_required { - ( - quote!(#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance), - quote!(#traitinstance: #traittype, #instance #bound_instantiable), - quote!(#traitinstance, #instance), - where_clause.clone(), - ) - } else { - ( - quote!(#instance #bound_instantiable #equal_default_instance), - quote!(#instance #bound_instantiable), - quote!(#instance), - None, - ) - }; - - // generator for map - quote!{ - #( #[ #attrs ] )* - #visibility struct #name<#struct_trait>( - #scrate::rstd::marker::PhantomData<(#trait_and_instance)> - ) #where_clause; - - impl<#impl_trait> #scrate::storage::generator::StorageMap<#kty, #typ> - for #name<#trait_and_instance> #where_clause - { - type Query = #value_type; - type Hasher = #scrate::#hasher; - - fn prefix() -> &'static [u8] { - #final_prefix - } - - fn from_optional_value_to_query(v: Option<#typ>) -> Self::Query { - #from_optional_value_to_query - } - - fn from_query_to_optional_value(v: Self::Query) -> Option<#typ> { - #from_query_to_optional_value - } - } - } - } - - pub fn linked_map(self, hasher: TokenStream2, kty: &syn::Type) -> TokenStream2 { - let Self { - scrate, - visibility, - traitinstance, - traittype, - instance_opts, - type_infos, - fielddefault, - prefix, - name, - attrs, - where_clause, - .. - } = self; - - let InstanceOpts { - equal_default_instance, - bound_instantiable, - instance, - .. - } = instance_opts; - - let final_prefix = if let Some(instance) = instance { - let const_name = Ident::new( - &format!("{}{}", PREFIX_FOR, name.to_string()), proc_macro2::Span::call_site() - ); - quote!{ #instance::#const_name.as_bytes() } - } else { - quote!{ #prefix.as_bytes() } - }; - - // make sure to use different prefix for head and elements. - let head_key = if let Some(instance) = instance { - let const_name = Ident::new( - &format!("{}{}", HEAD_KEY_FOR, name.to_string()), proc_macro2::Span::call_site() - ); - quote!{ #instance::#const_name.as_bytes() } - } else { - let head_key = format!("head of {}", prefix); - quote!{ #head_key.as_bytes() } - }; - - let DeclStorageTypeInfos { typ, value_type, is_option, .. } = type_infos; - - let from_optional_value_to_query = from_optional_value_to_query(is_option, fielddefault); - let from_query_to_optional_value = from_query_to_optional_value(is_option); - - let trait_required = ext::type_contains_ident(value_type, traitinstance) - || ext::type_contains_ident(kty, traitinstance); - - let (struct_trait, impl_trait, trait_and_instance, where_clause) = if trait_required { - ( - quote!(#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance), - quote!(#traitinstance: #traittype, #instance #bound_instantiable), - quote!(#traitinstance, #instance), - where_clause.clone(), - ) - } else { - ( - quote!(#instance #bound_instantiable #equal_default_instance), - quote!(#instance #bound_instantiable), - quote!(#instance), - None, - ) - }; - - // generator for linked map - quote! { - #( #[ #attrs ] )* - #visibility struct #name<#struct_trait>( - #scrate::rstd::marker::PhantomData<(#trait_and_instance)> - ) #where_clause; - - impl<#impl_trait> #scrate::storage::generator::StorageLinkedMap<#kty, #typ> - for #name<#trait_and_instance> #where_clause - { - type Query = #value_type; - type Hasher = #scrate::#hasher; - - fn prefix() -> &'static [u8] { - #final_prefix - } - - fn head_key() -> &'static [u8] { - #head_key - } - - fn from_optional_value_to_query(v: Option<#typ>) -> Self::Query { - #from_optional_value_to_query - } - - fn from_query_to_optional_value(v: Self::Query) -> Option<#typ> { - #from_query_to_optional_value - } - } - } - } - - pub fn double_map( - self, - hasher: TokenStream2, - k1ty: &syn::Type, - k2ty: &syn::Type, - k2_hasher: TokenStream2, - ) -> TokenStream2 { - let Self { - scrate, - visibility, - traitinstance, - traittype, - type_infos, - fielddefault, - prefix, - name, - attrs, - instance_opts, - where_clause, - .. - } = self; - - let DeclStorageTypeInfos { typ, value_type, is_option, .. } = type_infos; - - let from_optional_value_to_query = from_optional_value_to_query(is_option, fielddefault); - let from_query_to_optional_value = from_query_to_optional_value(is_option); - - let InstanceOpts { - equal_default_instance, - bound_instantiable, - instance, - .. - } = instance_opts; - - let final_prefix = if let Some(instance) = instance { - let const_name = Ident::new( - &format!("{}{}", PREFIX_FOR, name.to_string()), proc_macro2::Span::call_site() - ); - quote!{ #instance::#const_name.as_bytes() } - } else { - quote!{ #prefix.as_bytes() } - }; - - let (struct_trait, impl_trait, trait_and_instance, where_clause) = if ext::type_contains_ident( - value_type, traitinstance - ) || ext::type_contains_ident(k1ty, traitinstance) || ext::type_contains_ident(k2ty, traitinstance) - { - ( - quote!(#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance), - quote!(#traitinstance: #traittype, #instance #bound_instantiable), - quote!(#traitinstance, #instance), - where_clause.clone(), - ) - } else { - ( - quote!(#instance #bound_instantiable #equal_default_instance), - quote!(#instance #bound_instantiable), - quote!(#instance), - None, - ) - }; - - // generator for double map - quote!{ - #( #[ #attrs ] )* - #visibility struct #name<#struct_trait> ( - #scrate::rstd::marker::PhantomData<(#trait_and_instance)> - ) #where_clause; - - impl<#impl_trait> #scrate::storage::generator::StorageDoubleMap<#k1ty, #k2ty, #typ> - for #name<#trait_and_instance> #where_clause - { - type Query = #value_type; - - type Hasher1 = #scrate::#hasher; - - type Hasher2 = #scrate::#k2_hasher; - - fn key1_prefix() -> &'static [u8] { - #final_prefix - } - - fn from_optional_value_to_query(v: Option<#typ>) -> Self::Query { - #from_optional_value_to_query - } - - fn from_query_to_optional_value(v: Self::Query) -> Option<#typ> { - #from_query_to_optional_value - } - } - } - } -} diff --git a/srml/support/procedural/src/storage/instance_trait.rs b/srml/support/procedural/src/storage/instance_trait.rs new file mode 100644 index 0000000000..fe81dfe0db --- /dev/null +++ b/srml/support/procedural/src/storage/instance_trait.rs @@ -0,0 +1,196 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Implementation of the trait instance and the instance structures implementing it. +//! (For not instantiable traits there is still the inherent instance implemented). + +use proc_macro2::{TokenStream, Span}; +use quote::quote; +use super::{DeclStorageDefExt, StorageLineTypeDef}; + +const NUMBER_OF_INSTANCE: usize = 16; +const INHERENT_INSTANCE_NAME: &str = "__InherentHiddenInstance"; +pub(crate) const DEFAULT_INSTANTIABLE_TRAIT_NAME: &str = "__GeneratedInstantiable"; + +// prefix for consts in trait Instance +pub(crate) const PREFIX_FOR: &str = "PREFIX_FOR_"; +pub(crate) const HEAD_KEY_FOR: &str = "HEAD_KEY_FOR_"; + +// Used to generate the const: +// `const $name: &'static str = $value_prefix ++ instance_prefix ++ $value_suffix` +struct InstanceConstDef { + name: syn::Ident, + value_prefix: String, + value_suffix: String, +} + +// Used to generate an instance implementation. +struct InstanceDef { + prefix: String, + instance_struct: syn::Ident, + doc: TokenStream, +} + +pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStream { + let mut impls = TokenStream::new(); + + let mut const_defs = vec![]; + + for line in def.storage_lines.iter() { + let storage_prefix = format!("{} {}", def.crate_name, line.name); + + let const_name = syn::Ident::new( + &format!("{}{}", PREFIX_FOR, line.name.to_string()), proc_macro2::Span::call_site() + ); + const_defs.push(InstanceConstDef { + name: const_name, + value_prefix: String::new(), + value_suffix: storage_prefix.clone(), + }); + + if let StorageLineTypeDef::LinkedMap(_) = line.storage_type { + let const_name = syn::Ident::new( + &format!("{}{}", HEAD_KEY_FOR, line.name.to_string()), proc_macro2::Span::call_site() + ); + const_defs.push(InstanceConstDef { + name: const_name, + value_prefix: "head of ".into(), + value_suffix: storage_prefix, + }); + } + } + + impls.extend(create_instance_trait(&const_defs, def)); + + // Implementation of instances. + if let Some(module_instance) = &def.module_instance { + let instance_defs = (0..NUMBER_OF_INSTANCE) + .map(|i| { + let name = format!("Instance{}", i); + InstanceDef { + instance_struct: syn::Ident::new(&name, proc_macro2::Span::call_site()), + prefix: name, + doc: quote!(#[doc=r"Module instance"]), + } + }) + .chain( + module_instance.instance_default.as_ref().map(|ident| InstanceDef { + prefix: String::new(), + instance_struct: ident.clone(), + doc: quote!(#[doc=r"Default module instance"]), + }) + ); + + for instance_def in instance_defs { + impls.extend(create_and_impl_instance_struct(scrate, &instance_def, &const_defs, def)); + } + } + + // The name of the inherently available instance. + let inherent_instance = syn::Ident::new(INHERENT_INSTANCE_NAME, Span::call_site()); + + // Implementation of inherent instance. + if let Some(default_instance) = def.module_instance.as_ref() + .and_then(|i| i.instance_default.as_ref()) + { + impls.extend(quote! { + #[doc(hidden)] + pub type #inherent_instance = #default_instance; + }); + } else { + let instance_def = InstanceDef { + prefix: String::new(), + instance_struct: inherent_instance, + doc: quote!(#[doc(hidden)]), + }; + impls.extend(create_and_impl_instance_struct(scrate, &instance_def, &const_defs, def)); + } + + impls +} + +fn create_instance_trait( + const_defs: &[InstanceConstDef], + def: &DeclStorageDefExt, +) -> TokenStream { + let instance_trait = def.module_instance.as_ref().map(|i| i.instance_trait.clone()) + .unwrap_or_else(|| syn::Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site())); + + let mut const_impls = TokenStream::new(); + for const_def in const_defs { + let const_name = &const_def.name; + const_impls.extend(quote! { + const #const_name: &'static str; + }); + } + + let optional_hide = if def.module_instance.is_some() { + quote!() + } else { + quote!(#[doc(hidden)]) + }; + + quote! { + /// Tag a type as an instance of a module. + /// + /// Defines storage prefixes, they must be unique. + #optional_hide + pub trait #instance_trait: 'static { + /// The prefix used by any storage entry of an instance. + const PREFIX: &'static str; + #const_impls + } + } +} + +fn create_and_impl_instance_struct( + scrate: &TokenStream, + instance_def: &InstanceDef, + const_defs: &[InstanceConstDef], + def: &DeclStorageDefExt, +) -> TokenStream { + let mut const_impls = TokenStream::new(); + + for const_def in const_defs { + let const_value = format!( + "{}{}{}", const_def.value_prefix, instance_def.prefix, const_def.value_suffix + ); + let const_name = &const_def.name; + + const_impls.extend(quote! { + const #const_name: &'static str = #const_value; + }); + } + + let instance_trait = def.module_instance.as_ref().map(|i| i.instance_trait.clone()) + .unwrap_or_else(|| syn::Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site())); + + let instance_struct = &instance_def.instance_struct; + let prefix = format!("{}{}", instance_def.prefix, def.crate_name.to_string()); + let doc = &instance_def.doc; + + quote! { + // Those trait are derived because of wrong bounds for generics + #[cfg_attr(feature = "std", derive(Debug))] + #[derive(Clone, Eq, PartialEq, #scrate::codec::Encode, #scrate::codec::Decode)] + #doc + pub struct #instance_struct; + impl #instance_trait for #instance_struct { + const PREFIX: &'static str = #prefix; + #const_impls + } + } +} diff --git a/srml/support/procedural/src/storage/metadata.rs b/srml/support/procedural/src/storage/metadata.rs new file mode 100644 index 0000000000..e280c7d8a2 --- /dev/null +++ b/srml/support/procedural/src/storage/metadata.rs @@ -0,0 +1,230 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Implementation of `storage_metadata` on module structure, used by construct_runtime. + +use srml_support_procedural_tools::clean_type_string; +use proc_macro2::TokenStream; +use quote::quote; +use super::{DeclStorageDefExt, StorageLineDefExt, StorageLineTypeDef}; + +fn storage_line_metadata_type(scrate: &TokenStream, line: &StorageLineDefExt) -> TokenStream { + let value_type = &line.value_type; + let value_type = clean_type_string("e!( #value_type ).to_string()); + match &line.storage_type { + StorageLineTypeDef::Simple(_) => { + quote!{ + #scrate::metadata::StorageEntryType::Plain( + #scrate::metadata::DecodeDifferent::Encode(#value_type), + ) + } + }, + StorageLineTypeDef::Map(map) => { + let hasher = map.hasher.into_metadata(); + let key = &map.key; + let key = clean_type_string("e!(#key).to_string()); + quote!{ + #scrate::metadata::StorageEntryType::Map { + hasher: #scrate::metadata::#hasher, + key: #scrate::metadata::DecodeDifferent::Encode(#key), + value: #scrate::metadata::DecodeDifferent::Encode(#value_type), + is_linked: false, + } + } + }, + StorageLineTypeDef::LinkedMap(map) => { + let hasher = map.hasher.into_metadata(); + let key = &map.key; + let key = clean_type_string("e!(#key).to_string()); + quote!{ + #scrate::metadata::StorageEntryType::Map { + hasher: #scrate::metadata::#hasher, + key: #scrate::metadata::DecodeDifferent::Encode(#key), + value: #scrate::metadata::DecodeDifferent::Encode(#value_type), + is_linked: true, + } + } + }, + StorageLineTypeDef::DoubleMap(map) => { + let hasher1 = map.hasher1.into_metadata(); + let hasher2 = map.hasher2.into_metadata(); + let key1 = &map.key1; + let key1 = clean_type_string("e!(#key1).to_string()); + let key2 = &map.key2; + let key2 = clean_type_string("e!(#key2).to_string()); + quote!{ + #scrate::metadata::StorageEntryType::DoubleMap { + hasher: #scrate::metadata::#hasher1, + key1: #scrate::metadata::DecodeDifferent::Encode(#key1), + key2: #scrate::metadata::DecodeDifferent::Encode(#key2), + value: #scrate::metadata::DecodeDifferent::Encode(#value_type), + key2_hasher: #scrate::metadata::#hasher2, + } + } + }, + } +} + +fn default_byte_getter( + scrate: &TokenStream, + line: &StorageLineDefExt, + def: &DeclStorageDefExt, +) -> (TokenStream, TokenStream) { + let default = line.default_value.as_ref().map(|d| quote!( #d )) + .unwrap_or_else(|| quote!( Default::default() )); + + let str_name = line.name.to_string(); + let struct_name = syn::Ident::new(&("__GetByteStruct".to_string() + &str_name), line.name.span()); + let cache_name = syn::Ident::new(&("__CACHE_GET_BYTE_STRUCT_".to_string() + &str_name), line.name.span()); + + let runtime_generic = &def.module_runtime_generic; + let runtime_trait = &def.module_runtime_trait; + let optional_instance_bound_optional_default = &def.optional_instance_bound_optional_default; + let optional_instance_bound = &def.optional_instance_bound; + let optional_instance = &def.optional_instance; + let optional_comma_instance = optional_instance.as_ref().map(|i| quote!(, #i)); + let where_clause = &def.where_clause; + + let query_type = &line.query_type; + + let struct_def = quote! { + #[doc(hidden)] + pub struct #struct_name< + #runtime_generic, #optional_instance_bound_optional_default + >(pub #scrate::rstd::marker::PhantomData<(#runtime_generic #optional_comma_instance)>); + + #[cfg(feature = "std")] + #[allow(non_upper_case_globals)] + static #cache_name: #scrate::once_cell::sync::OnceCell<#scrate::rstd::vec::Vec> = + #scrate::once_cell::sync::OnceCell::new(); + + #[cfg(feature = "std")] + impl<#runtime_generic: #runtime_trait, #optional_instance_bound> + #scrate::metadata::DefaultByte + for #struct_name<#runtime_generic, #optional_instance> + #where_clause + { + fn default_byte(&self) -> #scrate::rstd::vec::Vec { + use #scrate::codec::Encode; + #cache_name.get_or_init(|| { + let def_val: #query_type = #default; + <#query_type as Encode>::encode(&def_val) + }).clone() + } + } + + unsafe impl<#runtime_generic: #runtime_trait, #optional_instance_bound> Send + for #struct_name<#runtime_generic, #optional_instance> #where_clause {} + + unsafe impl<#runtime_generic: #runtime_trait, #optional_instance_bound> Sync + for #struct_name<#runtime_generic, #optional_instance> #where_clause {} + + #[cfg(not(feature = "std"))] + impl<#runtime_generic: #runtime_trait, #optional_instance_bound> + #scrate::metadata::DefaultByte + for #struct_name<#runtime_generic, #optional_instance> + #where_clause + { + fn default_byte(&self) -> #scrate::rstd::vec::Vec { + use #scrate::codec::Encode; + let def_val: #query_type = #default; + <#query_type as Encode>::encode(&def_val) + } + } + }; + let struct_instance = quote!( + #struct_name::<#runtime_generic, #optional_instance>(#scrate::rstd::marker::PhantomData) + ); + + (struct_def, struct_instance) +} + +pub fn impl_metadata(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStream { + let mut entries = TokenStream::new(); + let mut default_byte_getter_struct_defs = TokenStream::new(); + + for line in def.storage_lines.iter() { + let str_name = line.name.to_string(); + + let modifier = if line.is_option { + quote!(#scrate::metadata::StorageEntryModifier::Optional) + } else { + quote!(#scrate::metadata::StorageEntryModifier::Default) + }; + + let ty = storage_line_metadata_type(scrate, line); + + let ( + default_byte_getter_struct_def, + default_byte_getter_struct_instance, + ) = default_byte_getter(scrate, line, def); + + let mut docs = TokenStream::new(); + for attr in line.attrs.iter().filter_map(|v| v.parse_meta().ok()) { + if let syn::Meta::NameValue(meta) = attr { + if meta.ident == "doc" { + let lit = meta.lit; + docs.extend(quote!(#lit,)); + } + } + } + + let entry = quote! { + #scrate::metadata::StorageEntryMetadata { + name: #scrate::metadata::DecodeDifferent::Encode(#str_name), + modifier: #modifier, + ty: #ty, + default: #scrate::metadata::DecodeDifferent::Encode( + #scrate::metadata::DefaultByteGetter(&#default_byte_getter_struct_instance) + ), + documentation: #scrate::metadata::DecodeDifferent::Encode(&[ #docs ]), + }, + }; + + default_byte_getter_struct_defs.extend(default_byte_getter_struct_def); + entries.extend(entry); + } + + let prefix = if let Some(instance) = &def.module_instance { + let instance_generic = &instance.instance_generic; + quote!(#instance_generic::PREFIX) + } else { + let prefix = def.crate_name.to_string(); + quote!(#prefix) + }; + + let store_metadata = quote!( + #scrate::metadata::StorageMetadata { + prefix: #scrate::metadata::DecodeDifferent::Encode(#prefix), + entries: #scrate::metadata::DecodeDifferent::Encode(&[ #entries ][..]), + } + ); + + let module_struct = &def.module_struct; + let module_impl = &def.module_impl; + let where_clause = &def.where_clause; + + quote!( + #default_byte_getter_struct_defs + + impl#module_impl #module_struct #where_clause { + #[doc(hidden)] + pub fn storage_metadata() -> #scrate::metadata::StorageMetadata { + #store_metadata + } + } + ) +} diff --git a/srml/support/procedural/src/storage/mod.rs b/srml/support/procedural/src/storage/mod.rs index 4253206f44..9a6931d87e 100644 --- a/srml/support/procedural/src/storage/mod.rs +++ b/srml/support/procedural/src/storage/mod.rs @@ -14,191 +14,358 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] -//! `decl_storage` macro -// end::description[] +//! `decl_storage` input definition and expansion. + +mod storage_struct; +mod parse; +mod store_trait; +mod getters; +mod metadata; +mod instance_trait; +mod genesis_config; -use srml_support_procedural_tools::{ToTokens, Parse, syn_ext as ext}; -use syn::{Ident, Token}; -use proc_macro2::TokenStream as TokenStream2; use quote::quote; +use srml_support_procedural_tools::{ + generate_crate_access, generate_hidden_includes, syn_ext as ext +}; -mod impls; - -pub mod transformation; - -mod keyword { - syn::custom_keyword!(hiddencrate); - syn::custom_keyword!(add_extra_genesis); - syn::custom_keyword!(extra_genesis_skip_phantom_data_field); - syn::custom_keyword!(config); - syn::custom_keyword!(build); - syn::custom_keyword!(get); - syn::custom_keyword!(map); - syn::custom_keyword!(linked_map); - syn::custom_keyword!(double_map); - syn::custom_keyword!(blake2_256); - syn::custom_keyword!(blake2_128); - syn::custom_keyword!(twox_256); - syn::custom_keyword!(twox_128); - syn::custom_keyword!(twox_64_concat); - syn::custom_keyword!(hasher); +/// All informations contained in input of decl_storage +pub struct DeclStorageDef { + /// Name of the module used to import hidden imports. + hidden_crate: Option, + /// Visibility of store trait. + visibility: syn::Visibility, + /// Name of store trait: usually `Store`. + store_trait: syn::Ident, + /// Module name used by construct_runtime: usually `Module`. + module_name: syn::Ident, + /// Usually `T`. + module_runtime_generic: syn::Ident, + /// Usually `Trait` + module_runtime_trait: syn::Path, + /// For instantiable module: usually `I: Instance=DefaultInstance`. + module_instance: Option, + /// Where claused used to constrain T and I even more. + where_clause: Option, + /// The extra build function used to build storage at genesis. + extra_genesis_build: Option, + /// The extra genesis config fields. + extra_genesis_config_lines: Vec, + /// Definition of storages. + storage_lines: Vec, + /// Name of the crate, used for storage prefixes. + crate_name: syn::Ident, } -/// Parsing usage only -#[derive(Parse, ToTokens, Debug)] -struct StorageDefinition { - pub hidden_crate: ext::Opt, - pub visibility: syn::Visibility, - pub trait_token: Token![trait], - pub ident: Ident, - pub for_token: Token![for], - pub module_ident: Ident, - pub mod_lt_token: Token![<], - pub mod_param: syn::GenericParam, - pub mod_instance_param_token: Option, - pub mod_instance: Option, - pub mod_instantiable_token: Option, - pub mod_instantiable: Option, - pub mod_default_instance_token: Option, - pub mod_default_instance: Option, - pub mod_gt_token: Token![>], - pub as_token: Token![as], - pub crate_ident: Ident, - pub where_clause: Option, - pub content: ext::Braces>, - pub extra_genesis: ext::Opt, +impl syn::parse::Parse for DeclStorageDef { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + parse::parse(input) + } } -#[derive(Parse, ToTokens, Debug)] -struct SpecificHiddenCrate { - pub keyword: keyword::hiddencrate, - pub ident: ext::Parens, +/// Extended version of `DeclStorageDef` with useful precomputed value. +pub struct DeclStorageDefExt { + /// Name of the module used to import hidden imports. + hidden_crate: Option, + /// Visibility of store trait. + visibility: syn::Visibility, + /// Name of store trait: usually `Store`. + store_trait: syn::Ident, + /// Module name used by construct_runtime: usually `Module`. + #[allow(unused)] + module_name: syn::Ident, + /// Usually `T`. + module_runtime_generic: syn::Ident, + /// Usually `Trait`. + module_runtime_trait: syn::Path, + /// For instantiable module: usually `I: Instance=DefaultInstance`. + module_instance: Option, + /// Where claused used to constrain T and I even more. + where_clause: Option, + /// The extra build function used to build storage at genesis. + extra_genesis_build: Option, + /// The extra genesis config fields. + extra_genesis_config_lines: Vec, + /// Definition of storages. + storage_lines: Vec, + /// Name of the crate, used for storage prefixes. + crate_name: syn::Ident, + /// Full struct expansion: `Module`. + module_struct: proc_macro2::TokenStream, + /// Impl block for module: ``. + module_impl: proc_macro2::TokenStream, + /// For instantiable: `I`. + optional_instance: Option, + /// For instantiable: `I: Instance`. + optional_instance_bound: Option, + /// For instantiable: `I: Instance = DefaultInstance`. + optional_instance_bound_optional_default: Option, } -#[derive(Parse, ToTokens, Debug)] -struct AddExtraGenesis { - pub extragenesis_keyword: keyword::add_extra_genesis, - pub content: ext::Braces, -} +impl From for DeclStorageDefExt { + fn from(mut def: DeclStorageDef) -> Self { + let storage_lines = def.storage_lines.drain(..).collect::>(); + let storage_lines = storage_lines.into_iter() + .map(|line| StorageLineDefExt::from_def(line, &def)) + .collect(); + + let ( + optional_instance, + optional_instance_bound, + optional_instance_bound_optional_default, + ) = if let Some(instance) = def.module_instance.as_ref() { + let instance_generic = &instance.instance_generic; + let instance_trait= &instance.instance_trait; + let optional_equal_instance_default = instance.instance_default.as_ref() + .map(|d| quote!( = #d )); + ( + Some(quote!(#instance_generic)), + Some(quote!(#instance_generic: #instance_trait)), + Some(quote!(#instance_generic: #instance_trait #optional_equal_instance_default)), + ) + } else { + (None, None, None) + }; + + let module_runtime_generic = &def.module_runtime_generic; + let module_runtime_trait = &def.module_runtime_trait; + let module_name = &def.module_name; -#[derive(Parse, ToTokens, Debug)] -struct AddExtraGenesisContent { - pub lines: ext::Punctuated, + let module_struct = quote!( + #module_name<#module_runtime_generic, #optional_instance> + ); + + let module_impl = quote!( + <#module_runtime_generic: #module_runtime_trait + 'static, #optional_instance_bound> + ); + + Self { + hidden_crate: def.hidden_crate, + visibility: def.visibility, + store_trait: def.store_trait, + module_name: def.module_name, + module_runtime_generic: def.module_runtime_generic, + module_runtime_trait: def.module_runtime_trait, + module_instance: def.module_instance, + where_clause: def.where_clause, + extra_genesis_build: def.extra_genesis_build, + extra_genesis_config_lines: def.extra_genesis_config_lines, + crate_name: def.crate_name, + storage_lines, + module_struct, + module_impl, + optional_instance, + optional_instance_bound, + optional_instance_bound_optional_default, + } + } } -#[derive(Parse, ToTokens, Debug)] -enum AddExtraGenesisLineEnum { - AddExtraGenesisLine(AddExtraGenesisLine), - AddExtraGenesisBuild(DeclStorageBuild), +/// Usually `I: Instance=DefaultInstance`. +pub struct ModuleInstanceDef { + /// Usually: `I`. + instance_generic: syn::Ident, + /// Usually: `Instance`. + instance_trait: syn::Ident, + /// Usually: `DefaultInstance`. + instance_default: Option, } -#[derive(Parse, ToTokens, Debug)] -struct AddExtraGenesisLine { - pub attrs: ext::OuterAttributes, - pub config_keyword: keyword::config, - pub extra_field: ext::Parens, - pub coldot_token: Token![:], - pub extra_type: syn::Type, - pub default_value: ext::Opt, +pub struct StorageLineDef { + attrs: Vec, + /// Visibility of the storage struct. + visibility: syn::Visibility, + name: syn::Ident, + /// The name of getter function to be implemented on Module struct. + getter: Option, + /// The name of the field to be used in genesis config if any. + config: Option, + /// The build function of the storage if any. + build: Option, + /// Default value of genesis config field and also for storage when no value available. + default_value: Option, + storage_type: StorageLineTypeDef, } -#[derive(Parse, ToTokens, Debug)] -struct DeclStorageLine { - // attrs (main use case is doc) - pub attrs: ext::OuterAttributes, - // visibility (no need to make optional - pub visibility: syn::Visibility, - // name - pub name: Ident, - pub getter: ext::Opt, - pub config: ext::Opt, - pub build: ext::Opt, - pub coldot_token: Token![:], - pub storage_type: DeclStorageType, - pub default_value: ext::Opt, +pub struct StorageLineDefExt { + #[allow(unused)] + attrs: Vec, + /// Visibility of the storage struct. + visibility: syn::Visibility, + name: syn::Ident, + /// The name of getter function to be implemented on Module struct. + getter: Option, + /// The name of the field to be used in genesis config if any. + config: Option, + /// The build function of the storage if any. + build: Option, + /// Default value of genesis config field and also for storage when no value available. + default_value: Option, + storage_type: StorageLineTypeDef, + doc_attrs: Vec, + /// Either the type stored in storage or wrapped in an Option. + query_type: syn::Type, + /// The type stored in storage. + value_type: syn::Type, + /// Full struct, for example: `StorageName`. + storage_struct: proc_macro2::TokenStream, + /// If storage is generic over runtime then `T`. + optional_storage_runtime_comma: Option, + /// If storage is generic over runtime then `T: Trait`. + optional_storage_runtime_bound_comma: Option, + /// The where clause to use to constrain generics if storage is generic over runtime. + optional_storage_where_clause: Option, + /// Full trait, for example: `storage::StorageMap`. + storage_trait: proc_macro2::TokenStream, + /// Full trait, for example: `storage::generator::StorageMap`. + storage_generator_trait: proc_macro2::TokenStream, + /// Weither the storage is generic. + is_generic: bool, + /// Weither the storage value is an option. + is_option: bool, } +impl StorageLineDefExt { + fn from_def(storage_def: StorageLineDef, def: &DeclStorageDef) -> Self { + let is_generic = match &storage_def.storage_type { + StorageLineTypeDef::Simple(value) => { + ext::type_contains_ident(&value, &def.module_runtime_generic) + }, + StorageLineTypeDef::Map(map) => { + ext::type_contains_ident(&map.key, &def.module_runtime_generic) + || ext::type_contains_ident(&map.value, &def.module_runtime_generic) + } + StorageLineTypeDef::LinkedMap(map) => { + ext::type_contains_ident(&map.key, &def.module_runtime_generic) + || ext::type_contains_ident(&map.value, &def.module_runtime_generic) + } + StorageLineTypeDef::DoubleMap(map) => { + ext::type_contains_ident(&map.key1, &def.module_runtime_generic) + || ext::type_contains_ident(&map.key2, &def.module_runtime_generic) + || ext::type_contains_ident(&map.value, &def.module_runtime_generic) + } + }; -#[derive(Parse, ToTokens, Debug)] -struct DeclStorageGetter { - pub getter_keyword: keyword::get, - pub getfn: ext::Parens, -} + let query_type = match &storage_def.storage_type { + StorageLineTypeDef::Simple(value) => value.clone(), + StorageLineTypeDef::Map(map) => map.value.clone(), + StorageLineTypeDef::LinkedMap(map) => map.value.clone(), + StorageLineTypeDef::DoubleMap(map) => map.value.clone(), + }; + let is_option = ext::extract_type_option(&query_type).is_some(); + let value_type = ext::extract_type_option(&query_type).unwrap_or(query_type.clone()); -#[derive(Parse, ToTokens, Debug)] -struct DeclStorageConfig { - pub config_keyword: keyword::config, - pub expr: ext::Parens>, -} + let module_runtime_generic = &def.module_runtime_generic; + let module_runtime_trait = &def.module_runtime_trait; + let optional_storage_runtime_comma = if is_generic { + Some(quote!( #module_runtime_generic, )) + } else { + None + }; + let optional_storage_runtime_bound_comma = if is_generic { + Some(quote!( #module_runtime_generic: #module_runtime_trait, )) + } else { + None + }; -#[derive(Parse, ToTokens, Debug)] -struct DeclStorageBuild { - pub build_keyword: keyword::build, - pub expr: ext::Parens, -} + let storage_name = &storage_def.name; + let optional_instance_generic = def.module_instance.as_ref().map(|i| { + let instance_generic = &i.instance_generic; + quote!( #instance_generic ) + }); + let storage_struct = quote!( + #storage_name<#optional_storage_runtime_comma #optional_instance_generic> + ); -#[derive(Parse, ToTokens, Debug)] -enum DeclStorageType { - Map(DeclStorageMap), - LinkedMap(DeclStorageLinkedMap), - DoubleMap(DeclStorageDoubleMap), - Simple(syn::Type), + let optional_storage_where_clause = if is_generic { + def.where_clause.as_ref().map(|w| quote!( #w )) + } else { + None + }; + + let storage_trait_trunkated = match &storage_def.storage_type { + StorageLineTypeDef::Simple(_) => { + quote!( StorageValue<#value_type> ) + }, + StorageLineTypeDef::Map(map) => { + let key = &map.key; + quote!( StorageMap<#key, #value_type> ) + }, + StorageLineTypeDef::LinkedMap(map) => { + let key = &map.key; + quote!( StorageLinkedMap<#key, #value_type> ) + }, + StorageLineTypeDef::DoubleMap(map) => { + let key1 = &map.key1; + let key2 = &map.key2; + quote!( StorageDoubleMap<#key1, #key2, #value_type> ) + }, + }; + + let storage_trait = quote!( storage::#storage_trait_trunkated ); + let storage_generator_trait = quote!( storage::generator::#storage_trait_trunkated ); + + let doc_attrs = storage_def.attrs.iter() + .filter_map(|a| a.parse_meta().ok()) + .filter(|m| m.name() == "doc") + .collect(); + + Self { + attrs: storage_def.attrs, + visibility: storage_def.visibility, + name: storage_def.name, + getter: storage_def.getter, + config: storage_def.config, + build: storage_def.build, + default_value: storage_def.default_value, + storage_type: storage_def.storage_type, + doc_attrs, + query_type, + value_type, + storage_struct, + optional_storage_runtime_comma, + optional_storage_runtime_bound_comma, + optional_storage_where_clause, + storage_trait, + storage_generator_trait, + is_generic, + is_option, + } + } } -#[derive(Parse, ToTokens, Debug)] -struct DeclStorageMap { - pub map_keyword: keyword::map, - pub hasher: ext::Opt, - pub key: syn::Type, - pub ass_keyword: Token![=>], - pub value: syn::Type, +pub enum StorageLineTypeDef { + Map(MapDef), + LinkedMap(MapDef), + DoubleMap(DoubleMapDef), + Simple(syn::Type), } -#[derive(Parse, ToTokens, Debug)] -struct DeclStorageLinkedMap { - pub map_keyword: keyword::linked_map, - pub hasher: ext::Opt, +pub struct MapDef { + pub hasher: HasherKind, pub key: syn::Type, - pub ass_keyword: Token![=>], + /// This is the query value not the inner value used in storage trait implementation. pub value: syn::Type, } -#[derive(Parse, ToTokens, Debug)] -struct DeclStorageDoubleMap { - pub map_keyword: keyword::double_map, - pub hasher: ext::Opt, +pub struct DoubleMapDef { + pub hasher1: HasherKind, + pub hasher2: HasherKind, pub key1: syn::Type, - pub comma_keyword: Token![,], - pub key2_hasher: Hasher, - pub key2: ext::Parens, - pub ass_keyword: Token![=>], + pub key2: syn::Type, + /// This is the query value not the inner value used in storage trait implementation. pub value: syn::Type, } -#[derive(Parse, ToTokens, Debug)] -enum Hasher { - Blake2_256(keyword::blake2_256), - Blake2_128(keyword::blake2_128), - Twox256(keyword::twox_256), - Twox128(keyword::twox_128), - Twox64Concat(keyword::twox_64_concat), -} - -#[derive(Parse, ToTokens, Debug)] -struct DeclStorageDefault { - pub equal_token: Token![=], - pub expr: syn::Expr, -} - -#[derive(Parse, ToTokens, Debug)] -struct SetHasher { - pub hasher_keyword: keyword::hasher, - pub inner: ext::Parens, +pub struct ExtraGenesisLineDef { + attrs: Vec, + name: syn::Ident, + typ: syn::Type, + default: Option, } #[derive(Debug, Clone)] -enum HasherKind { +pub enum HasherKind { Blake2_256, Blake2_128, Twox256, @@ -206,26 +373,8 @@ enum HasherKind { Twox64Concat, } -impl From<&SetHasher> for HasherKind { - fn from(set_hasher: &SetHasher) -> Self { - (&set_hasher.inner.content).into() - } -} - -impl From<&Hasher> for HasherKind { - fn from(hasher: &Hasher) -> Self { - match hasher { - Hasher::Blake2_256(_) => HasherKind::Blake2_256, - Hasher::Blake2_128(_) => HasherKind::Blake2_128, - Hasher::Twox256(_) => HasherKind::Twox256, - Hasher::Twox128(_) => HasherKind::Twox128, - Hasher::Twox64Concat(_) => HasherKind::Twox64Concat, - } - } -} - impl HasherKind { - fn into_storage_hasher_struct(&self) -> TokenStream2 { + fn to_storage_hasher_struct(&self) -> proc_macro2::TokenStream { match self { HasherKind::Blake2_256 => quote!( Blake2_256 ), HasherKind::Blake2_128 => quote!( Blake2_128 ), @@ -235,7 +384,7 @@ impl HasherKind { } } - fn into_metadata(&self) -> TokenStream2 { + fn into_metadata(&self) -> proc_macro2::TokenStream { match self { HasherKind::Blake2_256 => quote!( StorageHasher::Blake2_256 ), HasherKind::Blake2_128 => quote!( StorageHasher::Blake2_128 ), @@ -245,3 +394,39 @@ impl HasherKind { } } } + +/// Full implementation of decl_storage. +pub fn decl_storage_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let def = syn::parse_macro_input!(input as DeclStorageDef); + let def_ext = DeclStorageDefExt::from(def); + + let hidden_crate_name = def_ext.hidden_crate.as_ref().map(|i| i.to_string()) + .unwrap_or_else(|| "decl_storage".to_string()); + + let scrate = generate_crate_access(&hidden_crate_name, "srml-support"); + let scrate_decl = generate_hidden_includes(&hidden_crate_name, "srml-support"); + + let store_trait = store_trait::decl_and_impl(&def_ext); + let getters = getters::impl_getters(&scrate, &def_ext); + let metadata = metadata::impl_metadata(&scrate, &def_ext); + let instance_trait = instance_trait::decl_and_impl(&scrate, &def_ext); + let genesis_config = genesis_config::genesis_config_and_build_storage(&scrate, &def_ext); + let storage_struct = storage_struct::decl_and_impl(&scrate, &def_ext); + + quote!( + use #scrate::{ + StorageValue as _, + StorageMap as _, + StorageLinkedMap as _, + StorageDoubleMap as _ + }; + + #scrate_decl + #store_trait + #getters + #metadata + #instance_trait + #genesis_config + #storage_struct + ).into() +} diff --git a/srml/support/procedural/src/storage/parse.rs b/srml/support/procedural/src/storage/parse.rs new file mode 100644 index 0000000000..8464077ca2 --- /dev/null +++ b/srml/support/procedural/src/storage/parse.rs @@ -0,0 +1,377 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Parsing of decl_storage input. + +use srml_support_procedural_tools::{ToTokens, Parse, syn_ext as ext}; +use syn::{Ident, Token}; + +mod keyword { + syn::custom_keyword!(hiddencrate); + syn::custom_keyword!(add_extra_genesis); + syn::custom_keyword!(extra_genesis_skip_phantom_data_field); + syn::custom_keyword!(config); + syn::custom_keyword!(build); + syn::custom_keyword!(get); + syn::custom_keyword!(map); + syn::custom_keyword!(linked_map); + syn::custom_keyword!(double_map); + syn::custom_keyword!(blake2_256); + syn::custom_keyword!(blake2_128); + syn::custom_keyword!(twox_256); + syn::custom_keyword!(twox_128); + syn::custom_keyword!(twox_64_concat); + syn::custom_keyword!(hasher); +} + +/// Parsing usage only +#[derive(Parse, ToTokens, Debug)] +struct StorageDefinition { + pub hidden_crate: ext::Opt, + pub visibility: syn::Visibility, + pub trait_token: Token![trait], + pub ident: Ident, + pub for_token: Token![for], + pub module_ident: Ident, + pub mod_lt_token: Token![<], + pub mod_param_generic: syn::Ident, + pub mod_param_bound_token: Option, + pub mod_param_bound: syn::Path, + pub mod_instance_param_token: Option, + pub mod_instance: Option, + pub mod_instantiable_token: Option, + pub mod_instantiable: Option, + pub mod_default_instance_token: Option, + pub mod_default_instance: Option, + pub mod_gt_token: Token![>], + pub as_token: Token![as], + pub crate_ident: Ident, + pub where_clause: Option, + pub content: ext::Braces>, + pub extra_genesis: ext::Opt, +} + +#[derive(Parse, ToTokens, Debug)] +struct SpecificHiddenCrate { + pub keyword: keyword::hiddencrate, + pub ident: ext::Parens, +} + +#[derive(Parse, ToTokens, Debug)] +struct AddExtraGenesis { + pub extragenesis_keyword: keyword::add_extra_genesis, + pub content: ext::Braces, +} + +#[derive(Parse, ToTokens, Debug)] +struct AddExtraGenesisContent { + pub lines: ext::Punctuated, +} + +#[derive(Parse, ToTokens, Debug)] +enum AddExtraGenesisLineEnum { + AddExtraGenesisLine(AddExtraGenesisLine), + AddExtraGenesisBuild(DeclStorageBuild), +} + +#[derive(Parse, ToTokens, Debug)] +struct AddExtraGenesisLine { + pub attrs: ext::OuterAttributes, + pub config_keyword: keyword::config, + pub extra_field: ext::Parens, + pub coldot_token: Token![:], + pub extra_type: syn::Type, + pub default_value: ext::Opt, +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageLine { + // attrs (main use case is doc) + pub attrs: ext::OuterAttributes, + // visibility (no need to make optional + pub visibility: syn::Visibility, + // name + pub name: Ident, + pub getter: ext::Opt, + pub config: ext::Opt, + pub build: ext::Opt, + pub coldot_token: Token![:], + pub storage_type: DeclStorageType, + pub default_value: ext::Opt, +} + + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageGetter { + pub getter_keyword: keyword::get, + pub getfn: ext::Parens, +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageConfig { + pub config_keyword: keyword::config, + pub expr: ext::Parens>, +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageBuild { + pub build_keyword: keyword::build, + pub expr: ext::Parens, +} + +#[derive(Parse, ToTokens, Debug)] +enum DeclStorageType { + Map(DeclStorageMap), + LinkedMap(DeclStorageLinkedMap), + DoubleMap(DeclStorageDoubleMap), + Simple(syn::Type), +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageMap { + pub map_keyword: keyword::map, + pub hasher: ext::Opt, + pub key: syn::Type, + pub ass_keyword: Token![=>], + pub value: syn::Type, +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageLinkedMap { + pub map_keyword: keyword::linked_map, + pub hasher: ext::Opt, + pub key: syn::Type, + pub ass_keyword: Token![=>], + pub value: syn::Type, +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageDoubleMap { + pub map_keyword: keyword::double_map, + pub hasher: ext::Opt, + pub key1: syn::Type, + pub comma_keyword: Token![,], + pub key2_hasher: Hasher, + pub key2: ext::Parens, + pub ass_keyword: Token![=>], + pub value: syn::Type, +} + +#[derive(Parse, ToTokens, Debug)] +enum Hasher { + Blake2_256(keyword::blake2_256), + Blake2_128(keyword::blake2_128), + Twox256(keyword::twox_256), + Twox128(keyword::twox_128), + Twox64Concat(keyword::twox_64_concat), +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageDefault { + pub equal_token: Token![=], + pub expr: syn::Expr, +} + +#[derive(Parse, ToTokens, Debug)] +struct SetHasher { + pub hasher_keyword: keyword::hasher, + pub inner: ext::Parens, +} + +impl From for super::HasherKind { + fn from(set_hasher: SetHasher) -> Self { + set_hasher.inner.content.into() + } +} + +impl From for super::HasherKind { + fn from(hasher: Hasher) -> Self { + match hasher { + Hasher::Blake2_256(_) => super::HasherKind::Blake2_256, + Hasher::Blake2_128(_) => super::HasherKind::Blake2_128, + Hasher::Twox256(_) => super::HasherKind::Twox256, + Hasher::Twox128(_) => super::HasherKind::Twox128, + Hasher::Twox64Concat(_) => super::HasherKind::Twox64Concat, + } + } +} + +fn get_module_instance( + instance: Option, + instantiable: Option, + default_instance: Option, +) -> syn::Result> { + let right_syntax = "Should be $Instance: $Instantiable = $DefaultInstance"; + + match (instance, instantiable, default_instance) { + (Some(instance), Some(instantiable), default_instance) => { + Ok(Some(super::ModuleInstanceDef { + instance_generic: instance, + instance_trait: instantiable, + instance_default: default_instance, + })) + }, + (None, None, None) => Ok(None), + (Some(instance), None, _) => Err( + syn::Error::new( + instance.span(), + format!( + "Expect instantiable trait bound for instance: {}. {}", + instance, + right_syntax, + ) + ) + ), + (None, Some(instantiable), _) => Err( + syn::Error::new( + instantiable.span(), + format!( + "Expect instance generic for bound instantiable: {}. {}", + instantiable, + right_syntax, + ) + ) + ), + (None, _, Some(default_instance)) => Err( + syn::Error::new( + default_instance.span(), + format!( + "Expect instance generic for default instance: {}. {}", + default_instance, + right_syntax, + ) + ) + ), + } +} + +pub fn parse(input: syn::parse::ParseStream) -> syn::Result { + use syn::parse::Parse; + use syn::spanned::Spanned; + + let def = StorageDefinition::parse(input)?; + + let module_instance = get_module_instance( + def.mod_instance, + def.mod_instantiable, + def.mod_default_instance, + )?; + + let mut extra_genesis_config_lines = vec![]; + let mut extra_genesis_build = None; + + for line in def.extra_genesis.inner.into_iter() + .flat_map(|o| o.content.content.lines.inner.into_iter()) + { + match line { + AddExtraGenesisLineEnum::AddExtraGenesisLine(def) => { + extra_genesis_config_lines.push(super::ExtraGenesisLineDef{ + attrs: def.attrs.inner, + name: def.extra_field.content, + typ: def.extra_type, + default: def.default_value.inner.map(|o| o.expr), + }); + } + AddExtraGenesisLineEnum::AddExtraGenesisBuild(def) => { + if extra_genesis_build.is_some() { + return Err(syn::Error::new( + def.span(), + "Only one build expression allowed for extra genesis" + )) + } + + extra_genesis_build = Some(def.expr.content); + } + } + } + + let mut storage_lines = vec![]; + + for line in def.content.content.inner.into_iter() { + let getter = line.getter.inner.map(|o| o.getfn.content); + let config = if let Some(config) = line.config.inner { + if let Some(ident) = config.expr.content { + Some(ident) + } else if let Some(ident) = getter.clone() { + Some(ident) + } else { + return Err(syn::Error::new( + config.span(), + "Invalid storage definiton, couldn't find config identifier: storage must either have a get \ + identifier `get(ident)` or a defined config identifier `config(ident)`" + )) + } + } else { + None + }; + + let storage_type = match line.storage_type { + DeclStorageType::Map(map) => super::StorageLineTypeDef::Map( + super::MapDef { + hasher: map.hasher.inner.map(Into::into) + .unwrap_or(super::HasherKind::Blake2_256), + key: map.key, + value: map.value, + } + ), + DeclStorageType::LinkedMap(map) => super::StorageLineTypeDef::LinkedMap( + super::MapDef { + hasher: map.hasher.inner.map(Into::into) + .unwrap_or(super::HasherKind::Blake2_256), + key: map.key, + value: map.value, + } + ), + DeclStorageType::DoubleMap(map) => super::StorageLineTypeDef::DoubleMap( + super::DoubleMapDef { + hasher1: map.hasher.inner.map(Into::into) + .unwrap_or(super::HasherKind::Blake2_256), + hasher2: map.key2_hasher.into(), + key1: map.key1, + key2: map.key2.content, + value: map.value, + } + ), + DeclStorageType::Simple(expr) => super::StorageLineTypeDef::Simple(expr), + }; + + storage_lines.push(super::StorageLineDef { + attrs: line.attrs.inner, + visibility: line.visibility, + name: line.name, + getter, + config, + build: line.build.inner.map(|o| o.expr.content), + default_value: line.default_value.inner.map(|o| o.expr), + storage_type, + }) + } + + Ok(super::DeclStorageDef { + hidden_crate: def.hidden_crate.inner.map(|i| i.ident.content), + visibility: def.visibility, + module_name: def.module_ident, + store_trait: def.ident, + module_runtime_generic: def.mod_param_generic, + module_runtime_trait: def.mod_param_bound, + where_clause: def.where_clause, + crate_name: def.crate_ident, + module_instance, + extra_genesis_build, + extra_genesis_config_lines, + storage_lines, + }) +} diff --git a/srml/support/procedural/src/storage/storage_struct.rs b/srml/support/procedural/src/storage/storage_struct.rs new file mode 100644 index 0000000000..e195fb53e8 --- /dev/null +++ b/srml/support/procedural/src/storage/storage_struct.rs @@ -0,0 +1,220 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Implementation of storage structures and implementation of storage traits on them. + +use proc_macro2::TokenStream; +use quote::quote; +use super::{ + DeclStorageDefExt, StorageLineTypeDef, + instance_trait::{PREFIX_FOR, HEAD_KEY_FOR}, +}; + +fn from_optional_value_to_query(is_option: bool, default: &Option) -> TokenStream { + let default = default.as_ref().map(|d| quote!( #d )) + .unwrap_or_else(|| quote!( Default::default() )); + + if !is_option { + // raw type case + quote!( v.unwrap_or_else(|| #default ) ) + } else { + // Option<> type case + quote!( v.or_else(|| #default ) ) + } +} + +fn from_query_to_optional_value(is_option: bool) -> TokenStream { + if !is_option { + // raw type case + quote!( Some(v) ) + } else { + // Option<> type case + quote!( v ) + } +} + +pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStream { + let mut impls = TokenStream::new(); + + for line in &def.storage_lines { + + // Propagate doc attributes. + let attrs = &line.doc_attrs; + + let visibility = &line.visibility; + let optional_storage_runtime_comma = &line.optional_storage_runtime_comma; + let optional_storage_runtime_bound_comma = &line.optional_storage_runtime_bound_comma; + let optional_storage_where_clause = &line.optional_storage_where_clause; + let optional_instance_bound_optional_default = &def.optional_instance_bound_optional_default; + let optional_instance_bound = &def.optional_instance_bound; + let optional_instance = &def.optional_instance; + let name = &line.name; + + let struct_decl = quote!( + #( #[ #attrs ] )* + #visibility struct #name< + #optional_storage_runtime_bound_comma #optional_instance_bound_optional_default + >( + #scrate::rstd::marker::PhantomData< + (#optional_storage_runtime_comma #optional_instance) + > + ) #optional_storage_where_clause; + ); + + let from_query_to_optional_value = from_query_to_optional_value(line.is_option); + let from_optional_value_to_query = + from_optional_value_to_query(line.is_option, &line.default_value); + + let final_prefix = if let Some(instance) = def.module_instance.as_ref() { + let instance = &instance.instance_generic; + let const_name = syn::Ident::new( + &format!("{}{}", PREFIX_FOR, line.name.to_string()), proc_macro2::Span::call_site() + ); + quote!( #instance::#const_name.as_bytes() ) + } else { + let prefix = format!("{} {}", def.crate_name, line.name); + quote!( #prefix.as_bytes() ) + }; + + + let storage_generator_trait = &line.storage_generator_trait; + let storage_struct = &line.storage_struct; + let impl_trait = quote!( #optional_storage_runtime_bound_comma #optional_instance_bound ); + let value_type = &line.value_type; + let query_type = &line.query_type; + + let struct_impl = match &line.storage_type { + StorageLineTypeDef::Simple(_) => { + quote!( + impl<#impl_trait> #scrate::#storage_generator_trait for #storage_struct + #optional_storage_where_clause + { + type Query = #query_type; + + fn unhashed_key() -> &'static [u8] { + #final_prefix + } + + fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query { + #from_optional_value_to_query + } + + fn from_query_to_optional_value(v: Self::Query) -> Option<#value_type> { + #from_query_to_optional_value + } + } + ) + }, + StorageLineTypeDef::Map(map) => { + let hasher = map.hasher.to_storage_hasher_struct(); + quote!( + impl<#impl_trait> #scrate::#storage_generator_trait for #storage_struct + #optional_storage_where_clause + { + type Query = #query_type; + type Hasher = #scrate::#hasher; + + fn prefix() -> &'static [u8] { + #final_prefix + } + + fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query { + #from_optional_value_to_query + } + + fn from_query_to_optional_value(v: Self::Query) -> Option<#value_type> { + #from_query_to_optional_value + } + } + ) + }, + StorageLineTypeDef::LinkedMap(map) => { + let hasher = map.hasher.to_storage_hasher_struct(); + + // make sure to use different prefix for head and elements. + let head_key = if let Some(instance) = def.module_instance.as_ref() { + let instance = &instance.instance_generic; + let const_name = syn::Ident::new( + &format!("{}{}", HEAD_KEY_FOR, line.name.to_string()), proc_macro2::Span::call_site() + ); + quote!( #instance::#const_name.as_bytes() ) + } else { + let prefix = format!("head of {} {}", def.crate_name, line.name); + quote!( #prefix.as_bytes() ) + }; + + quote!( + impl<#impl_trait> #scrate::#storage_generator_trait for #storage_struct + #optional_storage_where_clause + { + type Query = #query_type; + type Hasher = #scrate::#hasher; + + fn prefix() -> &'static [u8] { + #final_prefix + } + + fn head_key() -> &'static [u8] { + #head_key + } + + fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query { + #from_optional_value_to_query + } + + fn from_query_to_optional_value(v: Self::Query) -> Option<#value_type> { + #from_query_to_optional_value + } + } + ) + }, + StorageLineTypeDef::DoubleMap(map) => { + let hasher1 = map.hasher1.to_storage_hasher_struct(); + let hasher2 = map.hasher2.to_storage_hasher_struct(); + quote!( + impl<#impl_trait> #scrate::#storage_generator_trait for #storage_struct + #optional_storage_where_clause + { + type Query = #query_type; + + type Hasher1 = #scrate::#hasher1; + + type Hasher2 = #scrate::#hasher2; + + fn key1_prefix() -> &'static [u8] { + #final_prefix + } + + fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query { + #from_optional_value_to_query + } + + fn from_query_to_optional_value(v: Self::Query) -> Option<#value_type> { + #from_query_to_optional_value + } + } + ) + } + }; + + impls.extend(quote!( + #struct_decl + #struct_impl + )) + } + + impls +} diff --git a/srml/support/procedural/src/storage/store_trait.rs b/srml/support/procedural/src/storage/store_trait.rs new file mode 100644 index 0000000000..4c9d96b6bb --- /dev/null +++ b/srml/support/procedural/src/storage/store_trait.rs @@ -0,0 +1,54 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Declaration of store trait and implementation on module structure. + +use proc_macro2::TokenStream; +use quote::quote; +use super::DeclStorageDefExt; + +pub fn decl_and_impl(def: &DeclStorageDefExt) -> TokenStream { + let decl_store_items = def.storage_lines.iter() + .map(|sline| &sline.name) + .fold(TokenStream::new(), |mut items, name| { + items.extend(quote!(type #name;)); + items + }); + + let impl_store_items = def.storage_lines.iter() + .fold(TokenStream::new(), |mut items, line| { + let name = &line.name; + let storage_struct = &line.storage_struct; + + items.extend(quote!(type #name = #storage_struct;)); + items + }); + + let visibility = &def.visibility; + let store_trait = &def.store_trait; + let module_struct = &def.module_struct; + let module_impl = &def.module_impl; + let where_clause = &def.where_clause; + + quote!( + #visibility trait #store_trait { + #decl_store_items + } + impl#module_impl #store_trait for #module_struct #where_clause { + #impl_store_items + } + ) +} diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs deleted file mode 100644 index c6a3a1f668..0000000000 --- a/srml/support/procedural/src/storage/transformation.rs +++ /dev/null @@ -1,1264 +0,0 @@ -// Copyright 2017-2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! `decl_storage` macro transformation - -use srml_support_procedural_tools::syn_ext as ext; -use srml_support_procedural_tools::{ - generate_crate_access, generate_hidden_includes, clean_type_string -}; - -use proc_macro::TokenStream; -use proc_macro2::{TokenStream as TokenStream2, Span}; - -use syn::{ - Ident, - GenericParam, - WhereClause, - spanned::Spanned, - parse::{ - Error, - Result, - }, - parse_macro_input, -}; -use quote::{quote, quote_spanned}; - -use super::*; - -const NUMBER_OF_INSTANCE: usize = 16; -const DEFAULT_INSTANTIABLE_TRAIT_NAME: &str = "__GeneratedInstantiable"; -const DEFAULT_INSTANCE_NAME: &str = "__GeneratedInstance"; -const INHERENT_INSTANCE_NAME: &str = "__InherentHiddenInstance"; - -// try macro but returning tokenized error -macro_rules! try_tok(( $expre : expr ) => { - match $expre { - Ok(r) => r, - Err (err) => { - return err.to_compile_error().into() - } - } -}); - -pub fn decl_storage_impl(input: TokenStream) -> TokenStream { - let def = parse_macro_input!(input as StorageDefinition); - - let StorageDefinition { - hidden_crate, - visibility, - ident: storetype, - module_ident, - mod_param: strait, - mod_instance, - mod_instantiable, - mod_default_instance, - crate_ident: cratename, - content: ext::Braces { content: storage_lines, ..}, - extra_genesis, - where_clause, - .. - } = def; - - let instance_opts = match get_instance_opts( - mod_instance, - mod_instantiable, - mod_default_instance - ) { - Ok(opts) => opts, - Err(err) => return err.to_compile_error().into(), - }; - - let hidden_crate_name = hidden_crate.inner.map(|rc| rc.ident.content).map(|i| i.to_string()) - .unwrap_or_else(|| "decl_storage".to_string()); - let scrate = generate_crate_access(&hidden_crate_name, "srml-support"); - let scrate_decl = generate_hidden_includes( - &hidden_crate_name, - "srml-support", - ); - - let ( - traitinstance, - traittypes, - ) = if let GenericParam::Type(syn::TypeParam {ident, bounds, ..}) = strait { - (ident, bounds) - } else { - return try_tok!(Err(Error::new(strait.span(), "Missing declare store generic params"))); - }; - - let traittype = if let Some(traittype) = traittypes.first() { - traittype.into_value() - } else { - return try_tok!(Err(Error::new(traittypes.span(), "Trait bound expected"))); - }; - - let extra_genesis = try_tok!(decl_store_extra_genesis( - &scrate, - &traitinstance, - &traittype, - &instance_opts, - &storage_lines, - &extra_genesis.inner, - &where_clause, - )); - let decl_storage_items = decl_storage_items( - &scrate, - &traitinstance, - &traittype, - &instance_opts, - &cratename, - &storage_lines, - &where_clause, - ).unwrap_or_else(|err| err.to_compile_error()); - - let decl_store_items = decl_store_items( - &storage_lines, - ); - let impl_store_items = impl_store_items( - &traitinstance, - &instance_opts.instance, - &storage_lines, - ); - let impl_store_fns = impl_store_fns( - &scrate, - &traitinstance, - &instance_opts.instance, - &storage_lines, - ); - let (store_default_struct, store_metadata) = store_functions_to_metadata( - &scrate, - &traitinstance, - &traittype, - &instance_opts, - &storage_lines, - &where_clause, - &cratename, - ); - - let InstanceOpts { - instance, - bound_instantiable, - .. - } = instance_opts; - - let expanded = quote! { - use #scrate::{ - StorageValue as _, - StorageMap as _, - StorageLinkedMap as _, - StorageDoubleMap as _ - }; - - #scrate_decl - #decl_storage_items - #visibility trait #storetype { - #decl_store_items - } - #store_default_struct - impl<#traitinstance: #traittype, #instance #bound_instantiable> #storetype - for #module_ident<#traitinstance, #instance> #where_clause - { - #impl_store_items - } - impl<#traitinstance: 'static + #traittype, #instance #bound_instantiable> - #module_ident<#traitinstance, #instance> #where_clause - { - #impl_store_fns - #[doc(hidden)] - pub fn storage_metadata() -> #scrate::metadata::StorageMetadata { - #store_metadata - } - } - - #extra_genesis - }; - - expanded.into() -} - -fn decl_store_extra_genesis( - scrate: &TokenStream2, - traitinstance: &Ident, - traittype: &syn::TypeParamBound, - instance_opts: &InstanceOpts, - storage_lines: &ext::Punctuated, - extra_genesis: &Option, - where_clause: &Option, -) -> Result { - - let InstanceOpts { - equal_default_instance, - bound_instantiable, - instance, - .. - } = instance_opts; - - let mut is_trait_needed = false; - let mut serde_complete_bound = Vec::new(); - let mut config_field = TokenStream2::new(); - let mut config_field_default = TokenStream2::new(); - let mut builders = TokenStream2::new(); - let mut assimilate_require_generic = instance.is_some(); - let mut builders_clone_bound = Vec::new(); - - for sline in storage_lines.inner.iter() { - let DeclStorageLine { - attrs, - name, - getter, - config, - build, - storage_type, - default_value, - .. - } = sline; - - let type_infos = get_type_infos(storage_type); - - let opt_build = build - .inner - .as_ref() - .map(|b| { - assimilate_require_generic |= ext::expr_contains_ident(&b.expr.content, traitinstance); - &b.expr.content - }) - .map(|b| quote!( #b )); - - // need build line - let builder = if let Some(ref config) = config.inner { - let ident = if let Some(ident) = config.expr.content.as_ref() { - quote!( #ident ) - } else if let Some(ref getter) = getter.inner { - let ident = &getter.getfn.content; - quote!( #ident ) - } else { - return Err( - Error::new_spanned( - name, - "Invalid storage definiton, couldn't find config identifier: storage must either have a get identifier \ - `get(ident)` or a defined config identifier `config(ident)`" - ) - ); - }; - - if ext::type_contains_ident(type_infos.value_type, traitinstance) { - is_trait_needed = true; - } - - if opt_build.is_none() { - builders_clone_bound.push(type_infos.value_type.clone()); - } - - let value_type = &type_infos.value_type; - serde_complete_bound.push(quote!( #value_type )); - match type_infos.kind { - DeclStorageTypeInfosKind::Map { key_type, .. } => { - serde_complete_bound.push(quote!( #key_type )); - is_trait_needed = is_trait_needed - || ext::type_contains_ident(key_type, traitinstance); - - if opt_build.is_none() { - builders_clone_bound.push(key_type.clone()); - } - }, - DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, .. } => { - serde_complete_bound.push(quote!( #key1_type )); - serde_complete_bound.push(quote!( #key2_type )); - is_trait_needed = is_trait_needed - || ext::type_contains_ident(key1_type, traitinstance) - || ext::type_contains_ident(key2_type, traitinstance); - if opt_build.is_none() { - builders_clone_bound.push(key1_type.clone()); - builders_clone_bound.push(key2_type.clone()); - } - }, - _ => {}, - } - - if type_infos.is_option { - serde_complete_bound.push(type_infos.typ.clone()); - } - - // Propagate doc attributes. - let attrs = attrs.inner.iter().filter_map(|a| a.parse_meta().ok()).filter(|m| m.name() == "doc"); - - let storage_type = type_infos.typ.clone(); - config_field.extend(match type_infos.kind { - DeclStorageTypeInfosKind::Simple => { - quote!( #( #[ #attrs ] )* pub #ident: #storage_type, ) - }, - DeclStorageTypeInfosKind::Map {key_type, .. } => { - quote!( #( #[ #attrs ] )* pub #ident: Vec<(#key_type, #storage_type)>, ) - }, - DeclStorageTypeInfosKind::DoubleMap {key1_type, key2_type, .. } => { - quote!( #( #[ #attrs ] )* pub #ident: Vec<(#key1_type, #key2_type, #storage_type)>, ) - }, - }); - - let fielddefault = default_value.inner.as_ref().map(|d| &d.expr).map(|d| - if type_infos.is_option { - quote!( #d.unwrap_or_default() ) - } else { - quote!( #d ) - }).unwrap_or_else(|| quote!( Default::default() )); - - config_field_default.extend(quote!( #ident: #fielddefault, )); - - opt_build.or_else(|| Some(quote!( (|config: &Self| config.#ident.clone()) ))) - } else { - opt_build - }; - - let typ = type_infos.typ; - if let Some(builder) = builder { - builders.extend(match type_infos.kind { - DeclStorageTypeInfosKind::Simple => { - let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) { - assimilate_require_generic = true; - quote!(#traitinstance,) - } else { - quote!() - }; - - quote!{{ - let v = (#builder)(&self); - < - #name<#struct_trait #instance> as - #scrate::storage::StorageValue<#typ> - >::put::<#typ>(v); - }} - }, - DeclStorageTypeInfosKind::Map { key_type, is_linked, .. } => { - let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) - || ext::type_contains_ident(key_type, traitinstance) - { - assimilate_require_generic = true; - quote!(#traitinstance,) - } else { - quote!() - }; - - let map = if is_linked { - quote! { StorageLinkedMap } - } else { - quote! { StorageMap } - }; - - quote!{{ - let data = (#builder)(&self); - data.into_iter().for_each(|(k, v)| { - < - #name<#struct_trait #instance> as - #scrate::storage::#map<#key_type, #typ> - >::insert::<#key_type, #typ>(k, v); - }); - }} - }, - DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, .. } => { - let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) - || ext::type_contains_ident(key1_type, traitinstance) - || ext::type_contains_ident(key2_type, traitinstance) - { - assimilate_require_generic = true; - quote!(#traitinstance,) - } else { - quote!() - }; - - quote!{{ - let data = (#builder)(&self); - data.into_iter().for_each(|(k1, k2, v)| { - < - #name<#struct_trait #instance> as - #scrate::storage::StorageDoubleMap<#key1_type, #key2_type, #typ> - >::insert::<#key1_type, #key2_type, #typ>(k1, k2, v); - }); - }} - }, - }); - } - } - - let mut has_scall = false; - let mut scall = quote!{ let scall: fn(&Self) = |_| {}; scall }; - let mut genesis_extrafields = TokenStream2::new(); - let mut genesis_extrafields_default = TokenStream2::new(); - - // extra genesis - if let Some(eg) = extra_genesis { - for ex_content in eg.content.content.lines.inner.iter() { - match ex_content { - AddExtraGenesisLineEnum::AddExtraGenesisLine(AddExtraGenesisLine { - attrs, - extra_field, - extra_type, - default_value, - .. - }) => { - if ext::type_contains_ident(&extra_type, traitinstance) { - is_trait_needed = true; - } - - serde_complete_bound.push(quote!( #extra_type )); - - let extrafield = &extra_field.content; - genesis_extrafields.extend(quote!{ - #attrs pub #extrafield: #extra_type, - }); - let extra_default = default_value.inner.as_ref().map(|d| &d.expr).map(|e| quote!{ #e }) - .unwrap_or_else(|| quote!( Default::default() )); - genesis_extrafields_default.extend(quote!{ - #extrafield: #extra_default, - }); - }, - AddExtraGenesisLineEnum::AddExtraGenesisBuild(DeclStorageBuild{ expr, .. }) => { - if has_scall { - return Err(Error::new(expr.span(), "Only one build expression allowed for extra genesis")); - } - assimilate_require_generic |= ext::expr_contains_ident(&expr.content, traitinstance); - let content = &expr.content; - scall = quote_spanned! { expr.span() => - let scall: fn(&Self) = #content; scall - }; - has_scall = true; - }, - } - } - } - - let serde_bug_bound = if !serde_complete_bound.is_empty() { - let mut b_ser = String::new(); - let mut b_dser = String::new(); - - serde_complete_bound.into_iter().for_each(|bound| { - let stype = quote!(#bound); - b_ser.push_str(&format!("{} : {}::serde::Serialize, ", stype, scrate)); - b_dser.push_str(&format!("{} : {}::serde::de::DeserializeOwned, ", stype, scrate)); - }); - - quote! { - #[serde(bound(serialize = #b_ser))] - #[serde(bound(deserialize = #b_dser))] - } - } else { - quote!() - }; - - let is_extra_genesis_needed = has_scall - || !config_field.is_empty() - || !genesis_extrafields.is_empty() - || !builders.is_empty(); - if is_extra_genesis_needed { - let (inherent_instance, inherent_bound_instantiable) = if instance.is_some() { - (instance.clone(), bound_instantiable.clone()) - } else { - let instantiable = Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site()); - ( - Some(Ident::new(DEFAULT_INSTANCE_NAME, Span::call_site())), - quote!(: #instantiable), - ) - }; - - let (fparam_struct, fparam_impl, sparam, build_storage_impl) = if is_trait_needed { - ( - quote!(<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>), - quote!(<#traitinstance: #traittype, #instance #bound_instantiable>), - quote!(<#traitinstance, #instance>), - quote!(<#traitinstance: #traittype, #inherent_instance #inherent_bound_instantiable>), - ) - } else { - // do not even need type parameter - ( - quote!(), - quote!(), - quote!(), - quote!(<#traitinstance: #traittype, #inherent_instance #inherent_bound_instantiable>), - ) - }; - - let (fn_generic, fn_traitinstance) = if !is_trait_needed && assimilate_require_generic { - ( - quote!( <#traitinstance: #traittype, #instance #bound_instantiable> ), - quote!( #traitinstance, #instance ) - ) - } else { - (quote!(), quote!()) - }; - - let impl_trait = quote!(BuildModuleGenesisStorage<#traitinstance, #inherent_instance>); - - let extend_where_clause = |to_extend: &mut WhereClause| { - if let Some(where_clause) = where_clause { - to_extend.predicates.extend(where_clause.predicates.iter().cloned()); - } - }; - - let mut genesis_where_clause: WhereClause = syn::parse_quote!( - where #( #builders_clone_bound: Clone ),* - ); - let mut fn_where_clause = genesis_where_clause.clone(); - - - let mut build_storage_where_clause = genesis_where_clause.clone(); - extend_where_clause(&mut build_storage_where_clause); - - if is_trait_needed { - extend_where_clause(&mut genesis_where_clause); - } else if assimilate_require_generic { - extend_where_clause(&mut fn_where_clause); - } - - let res = quote!{ - #[derive(#scrate::Serialize, #scrate::Deserialize)] - #[cfg(feature = "std")] - #[serde(rename_all = "camelCase")] - #[serde(deny_unknown_fields)] - #serde_bug_bound - pub struct GenesisConfig#fparam_struct #genesis_where_clause { - #config_field - #genesis_extrafields - } - - #[cfg(feature = "std")] - impl#fparam_impl Default for GenesisConfig#sparam #genesis_where_clause { - fn default() -> Self { - GenesisConfig { - #config_field_default - #genesis_extrafields_default - } - } - } - - #[cfg(feature = "std")] - impl#fparam_impl GenesisConfig#sparam #genesis_where_clause { - pub fn build_storage #fn_generic (self) -> std::result::Result< - ( - #scrate::sr_primitives::StorageOverlay, - #scrate::sr_primitives::ChildrenStorageOverlay, - ), - String - > #fn_where_clause { - let mut storage = (Default::default(), Default::default()); - self.assimilate_storage::<#fn_traitinstance>(&mut storage)?; - Ok(storage) - } - - /// Assimilate the storage for this module into pre-existing overlays. - pub fn assimilate_storage #fn_generic ( - self, - tuple_storage: &mut ( - #scrate::sr_primitives::StorageOverlay, - #scrate::sr_primitives::ChildrenStorageOverlay, - ), - ) -> std::result::Result<(), String> #fn_where_clause { - #scrate::with_storage(tuple_storage, || { - #builders - - #scall(&self); - - Ok(()) - }) - } - } - - #[cfg(feature = "std")] - impl#build_storage_impl #scrate::sr_primitives::#impl_trait - for GenesisConfig#sparam #build_storage_where_clause - { - fn build_module_genesis_storage( - self, - storage: &mut ( - #scrate::sr_primitives::StorageOverlay, - #scrate::sr_primitives::ChildrenStorageOverlay, - ), - ) -> std::result::Result<(), String> { - self.assimilate_storage::<#fn_traitinstance> (storage) - } - } - }; - - Ok(res) - } else { - Ok(quote!()) - } -} - -fn create_and_impl_instance( - instance_prefix: &str, - ident: &Ident, - doc: &TokenStream2, - const_names: &[(Ident, String, String)], - scrate: &TokenStream2, - instantiable: &Ident, - cratename: &Ident, -) -> TokenStream2 { - let mut const_impls = TokenStream2::new(); - - for (const_name, const_value_prefix, const_value_suffix) in const_names { - let const_value = format!("{}{}{}", const_value_prefix, instance_prefix, const_value_suffix); - const_impls.extend(quote! { - const #const_name: &'static str = #const_value; - }); - } - - let prefix = format!("{}{}", instance_prefix, cratename.to_string()); - - quote! { - // Those trait are derived because of wrong bounds for generics - #[cfg_attr(feature = "std", derive(Debug))] - #[derive(Clone, Eq, PartialEq, #scrate::codec::Encode, #scrate::codec::Decode)] - #doc - pub struct #ident; - impl #instantiable for #ident { - const PREFIX: &'static str = #prefix; - #const_impls - } - } -} - -fn decl_storage_items( - scrate: &TokenStream2, - traitinstance: &Ident, - traittype: &syn::TypeParamBound, - instance_opts: &InstanceOpts, - cratename: &Ident, - storage_lines: &ext::Punctuated, - where_clause: &Option, -) -> syn::Result { - let mut impls = TokenStream2::new(); - - let InstanceOpts { - instance, - default_instance, - instantiable, - .. - } = instance_opts; - - let build_prefix = |cratename, name| format!("{} {}", cratename, name); - - // Build Instantiable trait - let mut const_names = vec![]; - - for sline in storage_lines.inner.iter() { - let DeclStorageLine { - storage_type, - name, - .. - } = sline; - - let prefix = build_prefix(cratename, name); - - let type_infos = get_type_infos(storage_type); - - let const_name = syn::Ident::new( - &format!("{}{}", impls::PREFIX_FOR, name.to_string()), proc_macro2::Span::call_site() - ); - const_names.push((const_name, String::new(), prefix.clone())); - - if let DeclStorageTypeInfosKind::Map { is_linked: true, .. } = type_infos.kind { - let const_name = syn::Ident::new( - &format!("{}{}", impls::HEAD_KEY_FOR, name.to_string()), proc_macro2::Span::call_site() - ); - const_names.push((const_name, "head of ".into(), prefix)); - } - } - - let instantiable = instantiable - .clone() - .unwrap_or_else(|| Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site())); - - // Declare Instance trait - { - let mut const_impls = TokenStream2::new(); - for (const_name, ..) in &const_names { - const_impls.extend(quote! { - const #const_name: &'static str; - }); - } - - let hide = if instance.is_some() { - quote!() - } else { - quote!(#[doc(hidden)]) - }; - - impls.extend(quote! { - /// Tag a type as an instance of a module. - /// - /// Defines storage prefixes, they must be unique. - #hide - pub trait #instantiable: 'static { - /// The prefix used by any storage entry of an instance. - const PREFIX: &'static str; - #const_impls - } - }); - } - - if instance.is_some() { - let instances = (0..NUMBER_OF_INSTANCE) - .map(|i| { - let name = format!("Instance{}", i); - let ident = Ident::new(&name, proc_macro2::Span::call_site()); - (name, ident, quote! {#[doc=r"Module instance"]}) - }) - .chain( - default_instance - .clone() - .map(|ident| - (String::new(), ident, quote! {#[doc=r"Default module instance"]}) - ) - ); - - // Impl Instance trait for instances - for (instance_prefix, ident, doc) in instances { - impls.extend( - create_and_impl_instance( - &instance_prefix, &ident, &doc, &const_names, scrate, &instantiable, cratename - ) - ); - } - } - - // The name of the inherently available instance. - let inherent_instance = Ident::new(INHERENT_INSTANCE_NAME, Span::call_site()); - - if default_instance.is_some() { - impls.extend(quote! { - #[doc(hidden)] - pub type #inherent_instance = #default_instance; - }); - } else { - impls.extend( - create_and_impl_instance( - "", - &inherent_instance, - "e!(#[doc(hidden)]), - &const_names, - scrate, - &instantiable, - cratename, - ) - ); - } - - for sline in storage_lines.inner.iter() { - let DeclStorageLine { - attrs, - name, - storage_type, - default_value, - visibility, - .. - } = sline; - - let type_infos = get_type_infos(storage_type); - - if type_infos.is_option && default_value.inner.is_some() { - return Err(syn::Error::new_spanned( - default_value, - "Default values for Option types are not supported" - )); - } - - let fielddefault = default_value.inner - .as_ref() - .map(|d| &d.expr) - .map(|d| quote!( #d )) - .unwrap_or_else(|| quote!{ Default::default() }); - let kind = type_infos.kind.clone(); - // Propagate doc attributes. - let attrs = attrs.inner.iter().filter_map(|a| a.parse_meta().ok()).filter(|m| m.name() == "doc"); - - let i = impls::Impls { - scrate, - visibility, - cratename, - traitinstance, - traittype, - instance_opts, - type_infos, - fielddefault, - prefix: build_prefix(cratename, name), - name, - attrs, - where_clause, - }; - - let implementation = match kind { - DeclStorageTypeInfosKind::Simple => { - i.simple_value() - }, - DeclStorageTypeInfosKind::Map { key_type, is_linked: false, hasher } => { - i.map(hasher.into_storage_hasher_struct(), key_type) - }, - DeclStorageTypeInfosKind::Map { key_type, is_linked: true, hasher } => { - i.linked_map(hasher.into_storage_hasher_struct(), key_type) - }, - DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, key2_hasher, hasher } => { - i.double_map(hasher.into_storage_hasher_struct(), key1_type, key2_type, key2_hasher.into_storage_hasher_struct()) - }, - }; - impls.extend(implementation) - } - - Ok(impls) -} - -fn decl_store_items(storage_lines: &ext::Punctuated) -> TokenStream2 { - storage_lines.inner.iter().map(|sline| &sline.name) - .fold(TokenStream2::new(), |mut items, name| { - items.extend(quote!(type #name;)); - items - }) -} - -fn impl_store_items( - traitinstance: &Ident, - instance: &Option, - storage_lines: &ext::Punctuated, -) -> TokenStream2 { - storage_lines.inner - .iter() - .fold(TokenStream2::new(), |mut items, line| { - let name = &line.name; - let type_infos = get_type_infos(&line.storage_type); - let requires_trait = match type_infos.kind { - DeclStorageTypeInfosKind::Simple => { - ext::type_contains_ident(&type_infos.value_type, traitinstance) - }, - DeclStorageTypeInfosKind::Map { key_type, .. } => { - ext::type_contains_ident(&type_infos.value_type, traitinstance) - || ext::type_contains_ident(key_type, traitinstance) - } - DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, .. } => { - ext::type_contains_ident(&type_infos.value_type, traitinstance) - || ext::type_contains_ident(key1_type, traitinstance) - || ext::type_contains_ident(key2_type, traitinstance) - } - }; - - let struct_trait = if requires_trait { - quote!(#traitinstance,) - } else { - quote!() - }; - - items.extend( - quote!( - type #name = #name<#struct_trait #instance>; - ) - ); - items - }) -} - -fn impl_store_fns( - scrate: &TokenStream2, - traitinstance: &Ident, - instance: &Option, - storage_lines: &ext::Punctuated, -) -> TokenStream2 { - let mut items = TokenStream2::new(); - for sline in storage_lines.inner.iter() { - let DeclStorageLine { - attrs, - name, - getter, - storage_type, - .. - } = sline; - - if let Some(getter) = getter.inner.as_ref() { - let get_fn = &getter.getfn.content; - - let type_infos = get_type_infos(storage_type); - let value_type = type_infos.value_type; - - // Propagate doc attributes. - let attrs = attrs.inner.iter().filter_map(|a| a.parse_meta().ok()).filter(|m| m.name() == "doc"); - - let typ = type_infos.typ; - let item = match type_infos.kind { - DeclStorageTypeInfosKind::Simple => { - let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) { - quote!(#traitinstance,) - } else { - quote!() - }; - - quote!{ - #( #[ #attrs ] )* - pub fn #get_fn() -> #value_type { - < - #name<#struct_trait #instance> as - #scrate::storage::StorageValue<#typ> - >::get() - } - } - }, - DeclStorageTypeInfosKind::Map { key_type, is_linked, .. } => { - let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) - || ext::type_contains_ident(key_type, traitinstance) - { - quote!(#traitinstance,) - } else { - quote!() - }; - - let map = if is_linked { - quote! { StorageLinkedMap } - } else { - quote! { StorageMap } - }; - - quote!{ - #( #[ #attrs ] )* - pub fn #get_fn>(key: K) -> #value_type { - < - #name<#struct_trait #instance> as - #scrate::storage::#map<#key_type, #typ> - >::get(key) - } - } - } - DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, .. } => { - let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) - || ext::type_contains_ident(key1_type, traitinstance) - || ext::type_contains_ident(key2_type, traitinstance) - { - quote!(#traitinstance,) - } else { - quote!() - }; - - quote!{ - pub fn #get_fn(k1: KArg1, k2: KArg2) -> #value_type - where - KArg1: #scrate::codec::EncodeLike<#key1_type>, - KArg2: #scrate::codec::EncodeLike<#key2_type>, - { - < - #name<#struct_trait #instance> as - #scrate::storage::StorageDoubleMap<#key1_type, #key2_type, #typ> - >::get(k1, k2) - } - } - } - }; - items.extend(item); - } - } - items -} - -fn store_functions_to_metadata ( - scrate: &TokenStream2, - traitinstance: &Ident, - traittype: &syn::TypeParamBound, - instance_opts: &InstanceOpts, - storage_lines: &ext::Punctuated, - where_clause: &Option, - cratename: &Ident, -) -> (TokenStream2, TokenStream2) { - let InstanceOpts { - comma_instance, - equal_default_instance, - bound_instantiable, - instance, - .. - } = instance_opts; - - let mut items = TokenStream2::new(); - let mut default_getter_struct_def = TokenStream2::new(); - for sline in storage_lines.inner.iter() { - let DeclStorageLine { - attrs, - name, - storage_type, - default_value, - .. - } = sline; - - let type_infos = get_type_infos(storage_type); - let value_type = type_infos.value_type; - - let typ = type_infos.typ; - let styp = clean_type_string(&typ.to_string()); - let stype = match type_infos.kind { - DeclStorageTypeInfosKind::Simple => { - quote!{ - #scrate::metadata::StorageEntryType::Plain( - #scrate::metadata::DecodeDifferent::Encode(#styp), - ) - } - }, - DeclStorageTypeInfosKind::Map { key_type, is_linked, hasher } => { - let hasher = hasher.into_metadata(); - let kty = clean_type_string("e!(#key_type).to_string()); - quote!{ - #scrate::metadata::StorageEntryType::Map { - hasher: #scrate::metadata::#hasher, - key: #scrate::metadata::DecodeDifferent::Encode(#kty), - value: #scrate::metadata::DecodeDifferent::Encode(#styp), - is_linked: #is_linked, - } - } - }, - DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, key2_hasher, hasher } => { - let hasher = hasher.into_metadata(); - let k1ty = clean_type_string("e!(#key1_type).to_string()); - let k2ty = clean_type_string("e!(#key2_type).to_string()); - let k2_hasher = key2_hasher.into_metadata(); - quote!{ - #scrate::metadata::StorageEntryType::DoubleMap { - hasher: #scrate::metadata::#hasher, - key1: #scrate::metadata::DecodeDifferent::Encode(#k1ty), - key2: #scrate::metadata::DecodeDifferent::Encode(#k2ty), - value: #scrate::metadata::DecodeDifferent::Encode(#styp), - key2_hasher: #scrate::metadata::#k2_hasher, - } - } - }, - }; - let modifier = if type_infos.is_option { - quote!{ - #scrate::metadata::StorageEntryModifier::Optional - } - } else { - quote!{ - #scrate::metadata::StorageEntryModifier::Default - } - }; - let default = default_value.inner.as_ref().map(|d| &d.expr) - .map(|d| { - quote!( #d ) - }) - .unwrap_or_else(|| quote!( Default::default() )); - let mut docs = TokenStream2::new(); - for attr in attrs.inner.iter().filter_map(|v| v.parse_meta().ok()) { - if let syn::Meta::NameValue(syn::MetaNameValue{ - ref ident, - ref lit, - .. - }) = attr { - if ident == "doc" { - docs.extend(quote!(#lit,)); - } - } - } - let str_name = name.to_string(); - let struct_name = proc_macro2::Ident::new(&("__GetByteStruct".to_string() + &str_name), name.span()); - let cache_name = proc_macro2::Ident::new(&("__CACHE_GET_BYTE_STRUCT_".to_string() + &str_name), name.span()); - - let item = quote! { - #scrate::metadata::StorageEntryMetadata { - name: #scrate::metadata::DecodeDifferent::Encode(#str_name), - modifier: #modifier, - ty: #stype, - default: #scrate::metadata::DecodeDifferent::Encode( - #scrate::metadata::DefaultByteGetter( - &#struct_name::<#traitinstance, #instance>(#scrate::rstd::marker::PhantomData) - ) - ), - documentation: #scrate::metadata::DecodeDifferent::Encode(&[ #docs ]), - }, - }; - items.extend(item); - - let def_get = quote! { - #[doc(hidden)] - pub struct #struct_name< - #traitinstance, #instance #bound_instantiable #equal_default_instance - >(pub #scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>); - - #[cfg(feature = "std")] - #[allow(non_upper_case_globals)] - static #cache_name: #scrate::once_cell::sync::OnceCell< - #scrate::rstd::vec::Vec - > = #scrate::once_cell::sync::OnceCell::new(); - - #[cfg(feature = "std")] - impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::metadata::DefaultByte - for #struct_name<#traitinstance, #instance> #where_clause - { - fn default_byte(&self) -> #scrate::rstd::vec::Vec { - use #scrate::codec::Encode; - #cache_name.get_or_init(|| { - let def_val: #value_type = #default; - <#value_type as Encode>::encode(&def_val) - }).clone() - } - } - - unsafe impl<#traitinstance: #traittype, #instance #bound_instantiable> Send - for #struct_name<#traitinstance, #instance> #where_clause {} - - unsafe impl<#traitinstance: #traittype, #instance #bound_instantiable> Sync - for #struct_name<#traitinstance, #instance> #where_clause {} - - #[cfg(not(feature = "std"))] - impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::metadata::DefaultByte - for #struct_name<#traitinstance, #instance> #where_clause - { - fn default_byte(&self) -> #scrate::rstd::vec::Vec { - use #scrate::codec::Encode; - let def_val: #value_type = #default; - <#value_type as Encode>::encode(&def_val) - } - } - }; - - default_getter_struct_def.extend(def_get); - } - - let prefix = cratename.to_string(); - let prefix = instance.as_ref().map_or_else(|| quote!(#prefix), |i| quote!(#i::PREFIX)); - - (default_getter_struct_def, quote!{ - #scrate::metadata::StorageMetadata { - prefix: #scrate::metadata::DecodeDifferent::Encode(#prefix), - entries: #scrate::metadata::DecodeDifferent::Encode(&[ #items ][..]), - } - }) -} - - -#[derive(Debug, Clone)] -pub(crate) struct DeclStorageTypeInfos<'a> { - pub is_option: bool, - pub typ: TokenStream2, - pub value_type: &'a syn::Type, - kind: DeclStorageTypeInfosKind<'a>, -} - -#[derive(Debug, Clone)] -enum DeclStorageTypeInfosKind<'a> { - Simple, - Map { - hasher: HasherKind, - key_type: &'a syn::Type, - is_linked: bool, - }, - DoubleMap { - hasher: HasherKind, - key1_type: &'a syn::Type, - key2_type: &'a syn::Type, - key2_hasher: HasherKind, - } -} - -fn get_type_infos(storage_type: &DeclStorageType) -> DeclStorageTypeInfos { - let (value_type, kind) = match storage_type { - DeclStorageType::Simple(ref st) => (st, DeclStorageTypeInfosKind::Simple), - DeclStorageType::Map(ref map) => (&map.value, DeclStorageTypeInfosKind::Map { - hasher: map.hasher.inner.as_ref().map(|h| h.into()).unwrap_or(HasherKind::Blake2_256), - key_type: &map.key, - is_linked: false, - }), - DeclStorageType::LinkedMap(ref map) => (&map.value, DeclStorageTypeInfosKind::Map { - hasher: map.hasher.inner.as_ref().map(|h| h.into()).unwrap_or(HasherKind::Blake2_256), - key_type: &map.key, - is_linked: true, - }), - DeclStorageType::DoubleMap(ref map) => (&map.value, DeclStorageTypeInfosKind::DoubleMap { - hasher: map.hasher.inner.as_ref().map(|h| h.into()).unwrap_or(HasherKind::Blake2_256), - key1_type: &map.key1, - key2_type: &map.key2.content, - key2_hasher: (&map.key2_hasher).into(), - }), - }; - - let extracted_type = ext::extract_type_option(value_type); - let is_option = extracted_type.is_some(); - let typ = extracted_type.unwrap_or(quote!( #value_type )); - - DeclStorageTypeInfos { - is_option, - typ, - value_type, - kind, - } - -} - -#[derive(Default)] -pub(crate) struct InstanceOpts { - pub instance: Option, - pub default_instance: Option, - pub instantiable: Option, - pub comma_instance: TokenStream2, - pub equal_default_instance: TokenStream2, - pub bound_instantiable: TokenStream2, -} - -fn get_instance_opts( - instance: Option, - instantiable: Option, - default_instance: Option, -) -> Result { - let right_syntax = "Should be $Instance: $Instantiable = $DefaultInstance"; - - match (instance, instantiable, default_instance) { - (Some(instance), Some(instantiable), default_instance) => { - let (equal_default_instance, default_instance) = if let Some(def) = default_instance { - (quote!{= #def}, Some(def)) - } else { - (quote!(), None) - }; - - Ok(InstanceOpts { - comma_instance: quote!{, #instance}, - equal_default_instance, - bound_instantiable: quote!{: #instantiable}, - instance: Some(instance), - default_instance, - instantiable: Some(instantiable), - }) - }, - (None, None, None) => Ok(Default::default()), - (Some(instance), None, _) => Err( - Error::new( - instance.span(), - format!( - "Expect instantiable trait bound for instance: {}. {}", - instance, - right_syntax, - ) - ) - ), - (None, Some(instantiable), _) => Err( - Error::new( - instantiable.span(), - format!( - "Expect instance generic for bound instantiable: {}. {}", - instantiable, - right_syntax, - ) - ) - ), - (None, _, Some(default_instance)) => Err( - Error::new( - default_instance.span(), - format!( - "Expect instance generic for default instance: {}. {}", - default_instance, - right_syntax, - ) - ) - ), - } -} diff --git a/srml/support/procedural/tools/src/syn_ext.rs b/srml/support/procedural/tools/src/syn_ext.rs index 1033ebcce2..1658a6b4ae 100644 --- a/srml/support/procedural/tools/src/syn_ext.rs +++ b/srml/support/procedural/tools/src/syn_ext.rs @@ -184,13 +184,15 @@ impl ToTokens for Opt

{ } } -pub fn extract_type_option(typ: &syn::Type) -> Option { +pub fn extract_type_option(typ: &syn::Type) -> Option { if let syn::Type::Path(ref path) = typ { let v = path.path.segments.last()?; if v.value().ident == "Option" { - if let syn::PathArguments::AngleBracketed(ref a) = v.value().arguments { - let args = &a.args; - return Some(quote!{ #args }) + // Option has only one type argument in angle bracket. + if let syn::PathArguments::AngleBracketed(a) = &v.value().arguments { + if let syn::GenericArgument::Type(typ) = a.args.last()?.value() { + return Some(typ.clone()) + } } } } @@ -253,4 +255,4 @@ pub fn expr_contains_ident(expr: &syn::Expr, ident: &Ident) -> bool { visit::visit_expr(&mut visit, expr); visit.result -} \ No newline at end of file +} -- GitLab From 0cd7260ef8025ec770a24ee374f3a27fe5b1ebf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 16 Oct 2019 21:00:31 +0200 Subject: [PATCH 220/275] Make `wasmi_execution` public to use it from tests (#3829) * Make `wasmi_execution` public to use it from tests * Make `WasmRuntime` accessible as well * Add `call_in_wasm` instead of making stuff public * Use `WasmRuntime` * Move test * More feedback --- core/executor/src/error.rs | 6 ++++ core/executor/src/lib.rs | 48 +++++++++++++++++++++++++++++++ core/executor/src/wasm_runtime.rs | 20 +++++++++---- 3 files changed, 69 insertions(+), 5 deletions(-) diff --git a/core/executor/src/error.rs b/core/executor/src/error.rs index 6b3c45ee49..e1221bea54 100644 --- a/core/executor/src/error.rs +++ b/core/executor/src/error.rs @@ -99,6 +99,12 @@ impl From for Error { } } +impl From for Error { + fn from(err: WasmError) -> Error { + Error::Other(err.to_string()) + } +} + /// Type for errors occurring during Wasm runtime construction. #[derive(Debug, derive_more::Display)] pub enum WasmError { diff --git a/core/executor/src/lib.rs b/core/executor/src/lib.rs index ccc78afdb4..582ebbca34 100644 --- a/core/executor/src/lib.rs +++ b/core/executor/src/lib.rs @@ -50,6 +50,33 @@ pub use primitives::traits::Externalities; pub use wasm_interface; pub use wasm_runtime::WasmExecutionMethod; +/// Call the given `function` in the given wasm `code`. +/// +/// The signature of `function` needs to follow the default Substrate function signature. +/// +/// - `call_data`: Will be given as input parameters to `function` +/// - `execution_method`: The execution method to use. +/// - `ext`: The externalities that should be set while executing the wasm function. +/// - `heap_pages`: The number of heap pages to allocate. +/// +/// Returns the `Vec` that contains the return value of the function. +pub fn call_in_wasm( + function: &str, + call_data: &[u8], + execution_method: WasmExecutionMethod, + ext: &mut E, + code: &[u8], + heap_pages: u64, +) -> error::Result> { + let mut instance = wasm_runtime::create_wasm_runtime_with_code( + ext, + execution_method, + heap_pages, + code, + )?; + instance.call(ext, function, call_data) +} + /// Provides runtime information. pub trait RuntimeInfo { /// Native runtime information. @@ -61,3 +88,24 @@ pub trait RuntimeInfo { ext: &mut E, ) -> Option; } + +#[cfg(test)] +mod tests { + use super::*; + use runtime_test::WASM_BINARY; + use runtime_io::TestExternalities; + + #[test] + fn call_in_interpreted_wasm_works() { + let mut ext = TestExternalities::default(); + let res = call_in_wasm( + "test_empty_return", + &[], + WasmExecutionMethod::Interpreted, + &mut ext, + &WASM_BINARY, + 8, + ).unwrap(); + assert_eq!(res, vec![0u8; 0]); + } +} diff --git a/core/executor/src/wasm_runtime.rs b/core/executor/src/wasm_runtime.rs index d88ae7b9ed..8d2291fe04 100644 --- a/core/executor/src/wasm_runtime.rs +++ b/core/executor/src/wasm_runtime.rs @@ -157,17 +157,27 @@ impl RuntimesCache { } } -fn create_wasm_runtime( +/// Create a wasm runtime with the given `code`. +pub fn create_wasm_runtime_with_code( ext: &mut E, wasm_method: WasmExecutionMethod, heap_pages: u64, + code: &[u8], ) -> Result, WasmError> { - let code = ext - .original_storage(well_known_keys::CODE) - .ok_or(WasmError::CodeNotFound)?; match wasm_method { WasmExecutionMethod::Interpreted => - wasmi_execution::create_instance(ext, &code, heap_pages) + wasmi_execution::create_instance(ext, code, heap_pages) .map(|runtime| -> Box { Box::new(runtime) }), } } + +fn create_wasm_runtime( + ext: &mut E, + wasm_method: WasmExecutionMethod, + heap_pages: u64, +) -> Result, WasmError> { + let code = ext + .original_storage(well_known_keys::CODE) + .ok_or(WasmError::CodeNotFound)?; + create_wasm_runtime_with_code(ext, wasm_method, heap_pages, &code) +} -- GitLab From 0b2606e91e823bd12f3aa0f1b32f65cf2d918bb9 Mon Sep 17 00:00:00 2001 From: Ashley Date: Thu, 17 Oct 2019 11:34:03 +0100 Subject: [PATCH 221/275] Add error types to BABE and PoW (#3827) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add an error type to Babe * Add an error type to PoW * Simplify error enum variant names * Update core/consensus/babe/src/lib.rs Co-Authored-By: Bastian Köcher * Add missing newline * Split up DataProvider into CreateInherents and CheckInherents --- Cargo.lock | 2 + core/consensus/babe/Cargo.toml | 1 + core/consensus/babe/src/lib.rs | 145 ++++++++++++++++-------- core/consensus/babe/src/tests.rs | 6 +- core/consensus/babe/src/verification.rs | 45 +++----- core/consensus/pow/Cargo.toml | 1 + core/consensus/pow/src/lib.rs | 97 +++++++++++----- 7 files changed, 191 insertions(+), 106 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b42da79f88..1fd3c18534 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4869,6 +4869,7 @@ dependencies = [ name = "substrate-consensus-babe" version = "2.0.0" dependencies = [ + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "fork-tree 2.0.0", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4945,6 +4946,7 @@ dependencies = [ name = "substrate-consensus-pow" version = "2.0.0" dependencies = [ + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/core/consensus/babe/Cargo.toml b/core/consensus/babe/Cargo.toml index b1c2c31f7d..30b7c1f8d6 100644 --- a/core/consensus/babe/Cargo.toml +++ b/core/consensus/babe/Cargo.toml @@ -36,6 +36,7 @@ schnorrkel = { version = "0.8.5", features = ["preaudit_deprecated"] } rand = "0.7.2" merlin = "1.2.1" pdqselect = "0.1.0" +derive_more = "0.15.0" [dev-dependencies] keyring = { package = "substrate-keyring", path = "../../keyring" } diff --git a/core/consensus/babe/src/lib.rs b/core/consensus/babe/src/lib.rs index 0eacf1407e..287b26a300 100644 --- a/core/consensus/babe/src/lib.rs +++ b/core/consensus/babe/src/lib.rs @@ -66,7 +66,7 @@ use consensus_common::ImportResult; use consensus_common::import_queue::{ BoxJustificationImport, BoxFinalityProofImport, }; -use sr_primitives::{generic::{BlockId, OpaqueDigestItemId}, Justification}; +use sr_primitives::{generic::{BlockId, OpaqueDigestItemId}, Justification, RuntimeString}; use sr_primitives::traits::{ Block as BlockT, Header, DigestItemFor, ProvideRuntimeApi, Zero, @@ -102,6 +102,7 @@ use log::{warn, debug, info, trace}; use slots::{SlotWorker, SlotData, SlotInfo, SlotCompatible}; use epoch_changes::descendent_query; use header_metadata::HeaderMetadata; +use schnorrkel::SignatureError; mod aux_schema; mod verification; @@ -114,13 +115,71 @@ pub use babe_primitives::{ }; pub use epoch_changes::{EpochChanges, EpochChangesFor, SharedEpochChanges}; -macro_rules! babe_err { - ($($i: expr),+) => { - { - debug!(target: "babe", $($i),+); - format!($($i),+) - } - }; + +#[derive(derive_more::Display, Debug)] +enum Error { + #[display(fmt = "Multiple BABE pre-runtime digests, rejecting!")] + MultiplePreRuntimeDigests, + #[display(fmt = "No BABE pre-runtime digest found")] + NoPreRuntimeDigest, + #[display(fmt = "Multiple BABE epoch change digests, rejecting!")] + MultipleEpochChangeDigests, + #[display(fmt = "Could not extract timestamp and slot: {:?}", _0)] + Extraction(consensus_common::Error), + #[display(fmt = "Could not fetch epoch at {:?}", _0)] + FetchEpoch(B::Hash), + #[display(fmt = "Header {:?} rejected: too far in the future", _0)] + TooFarInFuture(B::Hash), + #[display(fmt = "Parent ({}) of {} unavailable. Cannot import", _0, _1)] + ParentUnavailable(B::Hash, B::Hash), + #[display(fmt = "Slot number must increase: parent slot: {}, this slot: {}", _0, _1)] + SlotNumberMustIncrease(u64, u64), + #[display(fmt = "Header {:?} has a bad seal", _0)] + HeaderBadSeal(B::Hash), + #[display(fmt = "Header {:?} is unsealed", _0)] + HeaderUnsealed(B::Hash), + #[display(fmt = "Slot author not found")] + SlotAuthorNotFound, + #[display(fmt = "Secondary slot assignments are disabled for the current epoch.")] + SecondarySlotAssignmentsDisabled, + #[display(fmt = "Bad signature on {:?}", _0)] + BadSignature(B::Hash), + #[display(fmt = "Invalid author: Expected secondary author: {:?}, got: {:?}.", _0, _1)] + InvalidAuthor(AuthorityId, AuthorityId), + #[display(fmt = "No secondary author expected.")] + NoSecondaryAuthorExpected, + #[display(fmt = "VRF verification of block by author {:?} failed: threshold {} exceeded", _0, _1)] + VRFVerificationOfBlockFailed(AuthorityId, u128), + #[display(fmt = "VRF verification failed: {:?}", _0)] + VRFVerificationFailed(SignatureError), + #[display(fmt = "Could not fetch parent header: {:?}", _0)] + FetchParentHeader(client::error::Error), + #[display(fmt = "Expected epoch change to happen at {:?}, s{}", _0, _1)] + ExpectedEpochChange(B::Hash, u64), + #[display(fmt = "Could not look up epoch: {:?}", _0)] + CouldNotLookUpEpoch(Box>), + #[display(fmt = "Block {} is not valid under any epoch.", _0)] + BlockNotValid(B::Hash), + #[display(fmt = "Unexpected epoch change")] + UnexpectedEpochChange, + #[display(fmt = "Parent block of {} has no associated weight", _0)] + ParentBlockNoAssociatedWeight(B::Hash), + #[display(fmt = "Checking inherents failed: {}", _0)] + CheckInherents(String), + Client(client::error::Error), + Runtime(RuntimeString), + ForkTree(Box>), +} + +impl std::convert::From> for String { + fn from(error: Error) -> String { + error.to_string() + } +} + +fn babe_err(error: Error) -> Error { + debug!(target: "babe", "{}", error); + error } macro_rules! babe_info { @@ -385,7 +444,7 @@ impl slots::SimpleSlotWorker for BabeWorker Result { self.env.init(block).map_err(|e| { - consensus_common::Error::ClientImport(format!("{:?}", e)).into() + consensus_common::Error::ClientImport(format!("{:?}", e)) }) } } @@ -410,7 +469,7 @@ impl SlotWorker for BabeWorker where /// Extract the BABE pre digest from the given header. Pre-runtime digests are /// mandatory, the function will return `Err` if none is found. -fn find_pre_digest(header: &H) -> Result +fn find_pre_digest(header: &B::Header) -> Result> { // genesis block doesn't contain a pre digest so let's generate a // dummy one to not break any invariants in the rest of the code @@ -425,17 +484,17 @@ fn find_pre_digest(header: &H) -> Result for log in header.digest().logs() { trace!(target: "babe", "Checking log {:?}, looking for pre runtime digest", log); match (log.as_babe_pre_digest(), pre_digest.is_some()) { - (Some(_), true) => Err(babe_err!("Multiple BABE pre-runtime digests, rejecting!"))?, + (Some(_), true) => return Err(babe_err(Error::MultiplePreRuntimeDigests)), (None, _) => trace!(target: "babe", "Ignoring digest not meant for us"), (s, false) => pre_digest = s, } } - pre_digest.ok_or_else(|| babe_err!("No BABE pre-runtime digest found")) + pre_digest.ok_or_else(|| babe_err(Error::NoPreRuntimeDigest)) } /// Extract the BABE epoch change digest from the given header, if it exists. fn find_next_epoch_digest(header: &B::Header) - -> Result, String> + -> Result, Error> where DigestItemFor: CompatibleDigestItem, { let mut epoch_digest: Option<_> = None; @@ -443,7 +502,7 @@ fn find_next_epoch_digest(header: &B::Header) trace!(target: "babe", "Checking log {:?}, looking for epoch change digest.", log); let log = log.try_to::(OpaqueDigestItemId::Consensus(&BABE_ENGINE_ID)); match (log, epoch_digest.is_some()) { - (Some(ConsensusLog::NextEpochData(_)), true) => Err(babe_err!("Multiple BABE epoch change digests, rejecting!"))?, + (Some(ConsensusLog::NextEpochData(_)), true) => return Err(babe_err(Error::MultipleEpochChangeDigests)), (Some(ConsensusLog::NextEpochData(epoch)), false) => epoch_digest = Some(epoch), _ => trace!(target: "babe", "Ignoring digest not meant for us"), } @@ -493,20 +552,20 @@ impl BabeVerifier { block: Block, block_id: BlockId, inherent_data: InherentData, - ) -> Result<(), String> + ) -> Result<(), Error> where PRA: ProvideRuntimeApi, PRA::Api: BlockBuilderApi { let inherent_res = self.api.runtime_api().check_inherents( &block_id, block, inherent_data, - ).map_err(|e| format!("{:?}", e))?; + ).map_err(Error::Client)?; if !inherent_res.ok() { inherent_res .into_errors() .try_for_each(|(i, e)| { - Err(self.inherent_data_providers.error_to_string(&i, &e)) + Err(Error::CheckInherents(self.inherent_data_providers.error_to_string(&i, &e))) }) } else { Ok(()) @@ -585,18 +644,18 @@ impl Verifier for BabeVerifier::Runtime)?; let (_, slot_now, _) = self.time_source.extract_timestamp_and_slot(&inherent_data) - .map_err(|e| format!("Could not extract timestamp and slot: {:?}", e))?; + .map_err(Error::::Extraction)?; let hash = header.hash(); let parent_hash = *header.parent_hash(); let parent_header_metadata = self.client.header_metadata(parent_hash) - .map_err(|e| format!("Could not fetch parent header: {:?}", e))?; + .map_err(Error::::FetchParentHeader)?; - let pre_digest = find_pre_digest::(&header)?; + let pre_digest = find_pre_digest::(&header)?; let epoch = { let epoch_changes = self.epoch_changes.lock(); epoch_changes.epoch_for_child_of( @@ -606,8 +665,8 @@ impl Verifier for BabeVerifier::ForkTree(Box::new(e)))? + .ok_or_else(|| Error::::FetchEpoch(parent_hash))? }; // We add one to the current slot to allow for some small drift. @@ -691,7 +750,7 @@ impl Verifier for BabeVerifier ?hash, "a" => ?a, "b" => ?b ); - Err(format!("Header {:?} rejected: too far in the future", hash)) + Err(Error::::TooFarInFuture(hash).into()) } } } @@ -787,10 +846,10 @@ impl BlockImport for BabeBlockImport return Ok(ImportResult::AlreadyInChain), Ok(blockchain::BlockStatus::Unknown) => {}, - Err(e) => return Err(ConsensusError::ClientImport(e.to_string()).into()), + Err(e) => return Err(ConsensusError::ClientImport(e.to_string())), } - let pre_digest = find_pre_digest::(&block.header) + let pre_digest = find_pre_digest::(&block.header) .expect("valid babe headers must contain a predigest; \ header has been already verified; qed"); let slot_number = pre_digest.slot_number(); @@ -798,13 +857,11 @@ impl BlockImport for BabeBlockImport::ParentUnavailable(parent_hash, hash) + ).into()))?; - let parent_slot = find_pre_digest::(&parent_header) + let parent_slot = find_pre_digest::(&parent_header) .map(|d| d.slot_number()) .expect("parent is non-genesis; valid BABE headers contain a pre-digest; \ header has already been verified; qed"); @@ -812,11 +869,9 @@ impl BlockImport for BabeBlockImport::SlotNumberMustIncrease(parent_slot, slot_number) + ).into()) ); } @@ -834,7 +889,7 @@ impl BlockImport for BabeBlockImport::ParentBlockNoAssociatedWeight(hash)).into() ))? }; @@ -846,10 +901,10 @@ impl BlockImport for BabeBlockImport| ConsensusError::ChainLookup( - babe_err!("Could not look up epoch: {:?}", e) + babe_err(Error::::CouldNotLookUpEpoch(Box::new(e))).into() ))? .ok_or_else(|| ConsensusError::ClientImport( - babe_err!("Block {} is not valid under any epoch.", hash) + babe_err(Error::::BlockNotValid(hash)).into() ))?; let first_in_epoch = parent_slot < epoch.as_ref().start_slot; @@ -860,7 +915,7 @@ impl BlockImport for BabeBlockImport(&block.header) - .map_err(|e| ConsensusError::from(ConsensusError::ClientImport(e.to_string())))?; + .map_err(|e| ConsensusError::ClientImport(e.to_string()))?; match (first_in_epoch, next_epoch_digest.is_some()) { (true, true) => {}, @@ -868,12 +923,12 @@ impl BlockImport for BabeBlockImport { return Err( ConsensusError::ClientImport( - babe_err!("Expected epoch change to happen at {:?}, s{}", hash, slot_number), + babe_err(Error::::ExpectedEpochChange(hash, slot_number)).into(), ) ); }, (false, true) => { - return Err(ConsensusError::ClientImport("Unexpected epoch change".into())); + return Err(ConsensusError::ClientImport(Error::::UnexpectedEpochChange.into())); }, } @@ -917,7 +972,7 @@ impl BlockImport for BabeBlockImport( .expect("best finalized hash was given by client; \ finalized headers must exist in db; qed"); - find_pre_digest::(&finalized_header) + find_pre_digest::(&finalized_header) .expect("finalized header must be valid; \ valid blocks have a pre-digest; qed") .slot_number() diff --git a/core/consensus/babe/src/tests.rs b/core/consensus/babe/src/tests.rs index e6883977a0..2e236f190b 100644 --- a/core/consensus/babe/src/tests.rs +++ b/core/consensus/babe/src/tests.rs @@ -81,7 +81,7 @@ impl Environment for DummyFactory { -> Result { - let parent_slot = crate::find_pre_digest(parent_header) + let parent_slot = crate::find_pre_digest::(parent_header) .expect("parent header has a pre-digest") .slot_number(); @@ -109,7 +109,7 @@ impl DummyProposer { Err(e) => return future::ready(Err(e)), }; - let this_slot = crate::find_pre_digest(block.header()) + let this_slot = crate::find_pre_digest::(block.header()) .expect("baked block has valid pre-digest") .slot_number(); @@ -535,7 +535,7 @@ fn propose_and_import_block( let mut proposer = proposer_factory.init(parent).unwrap(); let slot_number = slot_number.unwrap_or_else(|| { - let parent_pre_digest = find_pre_digest(parent).unwrap(); + let parent_pre_digest = find_pre_digest::(parent).unwrap(); parent_pre_digest.slot_number() + 1 }); diff --git a/core/consensus/babe/src/verification.rs b/core/consensus/babe/src/verification.rs index 05d6102450..36e34dfb95 100644 --- a/core/consensus/babe/src/verification.rs +++ b/core/consensus/babe/src/verification.rs @@ -22,7 +22,7 @@ use babe_primitives::{Epoch, BabePreDigest, CompatibleDigestItem, AuthorityId}; use babe_primitives::{AuthoritySignature, SlotNumber, AuthorityIndex, AuthorityPair}; use slots::CheckedHeader; use log::{debug, trace}; -use super::{find_pre_digest, BlockT}; +use super::{find_pre_digest, babe_err, BlockT, Error}; use super::authorship::{make_transcript, calculate_primary_threshold, check_primary_threshold, secondary_slot_author}; /// BABE verification parameters @@ -41,15 +41,6 @@ pub(super) struct VerificationParams<'a, B: 'a + BlockT> { pub(super) config: &'a super::Config, } -macro_rules! babe_err { - ($($i: expr),+) => { - { - debug!(target: "babe", $($i),+); - format!($($i),+) - } - }; -} - /// Check a header has been signed by the right key. If the slot is too far in /// the future, an error will be returned. If successful, returns the pre-header /// and the digest item containing the seal. @@ -63,7 +54,7 @@ macro_rules! babe_err { /// with each having different validation logic. pub(super) fn check_header( params: VerificationParams, -) -> Result>, String> where +) -> Result>, Error> where DigestItemFor: CompatibleDigestItem, { let VerificationParams { @@ -75,16 +66,16 @@ pub(super) fn check_header( } = params; let authorities = &epoch.authorities; - let pre_digest = pre_digest.map(Ok).unwrap_or_else(|| find_pre_digest::(&header))?; + let pre_digest = pre_digest.map(Ok).unwrap_or_else(|| find_pre_digest::(&header))?; trace!(target: "babe", "Checking header"); let seal = match header.digest_mut().pop() { Some(x) => x, - None => return Err(babe_err!("Header {:?} is unsealed", header.hash())), + None => return Err(babe_err(Error::HeaderUnsealed(header.hash()))), }; let sig = seal.as_babe_seal().ok_or_else(|| { - babe_err!("Header {:?} has a bad seal", header.hash()) + babe_err(Error::HeaderBadSeal(header.hash())) })?; // the pre-hash of the header doesn't include the seal @@ -98,7 +89,7 @@ pub(super) fn check_header( let author = match authorities.get(pre_digest.authority_index() as usize) { Some(author) => author.0.clone(), - None => return Err(babe_err!("Slot author not found")), + None => return Err(babe_err(Error::SlotAuthorNotFound)), }; match &pre_digest { @@ -128,7 +119,7 @@ pub(super) fn check_header( )?; }, _ => { - return Err(babe_err!("Secondary slot assignments are disabled for the current epoch.")); + return Err(babe_err(Error::SecondarySlotAssignmentsDisabled)); } } @@ -156,7 +147,7 @@ fn check_primary_header( signature: AuthoritySignature, epoch: &Epoch, c: (u64, u64), -) -> Result<(), String> { +) -> Result<(), Error> { let (vrf_output, vrf_proof, authority_index, slot_number) = pre_digest; let author = &epoch.authorities[authority_index as usize].0; @@ -172,7 +163,7 @@ fn check_primary_header( schnorrkel::PublicKey::from_bytes(author.as_slice()).and_then(|p| { p.vrf_verify(transcript, vrf_output, vrf_proof) }).map_err(|s| { - babe_err!("VRF verification failed: {:?}", s) + babe_err(Error::VRFVerificationFailed(s)) })? }; @@ -183,13 +174,12 @@ fn check_primary_header( ); if !check_primary_threshold(&inout, threshold) { - return Err(babe_err!("VRF verification of block by author {:?} failed: \ - threshold {} exceeded", author, threshold)); + return Err(babe_err(Error::VRFVerificationOfBlockFailed(author.clone(), threshold))); } Ok(()) } else { - Err(babe_err!("Bad signature on {:?}", pre_hash)) + Err(babe_err(Error::BadSignature(pre_hash))) } } @@ -202,7 +192,7 @@ fn check_secondary_header( pre_digest: (AuthorityIndex, SlotNumber), signature: AuthoritySignature, epoch: &Epoch, -) -> Result<(), String> { +) -> Result<(), Error> { let (authority_index, slot_number) = pre_digest; // check the signature is valid under the expected authority and @@ -211,22 +201,17 @@ fn check_secondary_header( slot_number, &epoch.authorities, epoch.randomness, - ).ok_or_else(|| "No secondary author expected.".to_string())?; + ).ok_or_else(|| Error::NoSecondaryAuthorExpected)?; let author = &epoch.authorities[authority_index as usize].0; if expected_author != author { - let msg = format!("Invalid author: Expected secondary author: {:?}, got: {:?}.", - expected_author, - author, - ); - - return Err(msg); + return Err(Error::InvalidAuthor(expected_author.clone(), author.clone())); } if AuthorityPair::verify(&signature, pre_hash.as_ref(), author) { Ok(()) } else { - Err(format!("Bad signature on {:?}", pre_hash)) + Err(Error::BadSignature(pre_hash)) } } diff --git a/core/consensus/pow/Cargo.toml b/core/consensus/pow/Cargo.toml index 54dd58c467..86efcbb95d 100644 --- a/core/consensus/pow/Cargo.toml +++ b/core/consensus/pow/Cargo.toml @@ -16,3 +16,4 @@ pow-primitives = { package = "substrate-consensus-pow-primitives", path = "primi consensus-common = { package = "substrate-consensus-common", path = "../common" } log = "0.4.8" futures-preview = { version = "0.3.0-alpha.19", features = ["compat"] } +derive_more = "0.15.0" diff --git a/core/consensus/pow/src/lib.rs b/core/consensus/pow/src/lib.rs index 766c1c63e0..040eb01d9c 100644 --- a/core/consensus/pow/src/lib.rs +++ b/core/consensus/pow/src/lib.rs @@ -37,7 +37,7 @@ use client::{ block_builder::api::BlockBuilder as BlockBuilderApi, backend::AuxStore, well_known_cache_keys::Id as CacheKeyId, }; -use sr_primitives::Justification; +use sr_primitives::{Justification, RuntimeString}; use sr_primitives::generic::{BlockId, Digest, DigestItem}; use sr_primitives::traits::{Block as BlockT, Header as HeaderT, ProvideRuntimeApi}; use srml_timestamp::{TimestampInherentData, InherentError as TIError}; @@ -46,12 +46,50 @@ use primitives::H256; use inherents::{InherentDataProviders, InherentData}; use consensus_common::{ BlockImportParams, BlockOrigin, ForkChoiceStrategy, SyncOracle, Environment, Proposer, - SelectChain, + SelectChain, Error as ConsensusError }; use consensus_common::import_queue::{BoxBlockImport, BasicQueue, Verifier}; use codec::{Encode, Decode}; use log::*; +#[derive(derive_more::Display, Debug)] +pub enum Error { + #[display(fmt = "Header uses the wrong engine {:?}", _0)] + WrongEngine([u8; 4]), + #[display(fmt = "Header {:?} is unsealed", _0)] + HeaderUnsealed(B::Hash), + #[display(fmt = "PoW validation error: invalid seal")] + InvalidSeal, + #[display(fmt = "Rejecting block too far in future")] + TooFarInFuture, + #[display(fmt = "Fetching best header failed using select chain: {:?}", _0)] + BestHeaderSelectChain(ConsensusError), + #[display(fmt = "Fetching best header failed: {:?}", _0)] + BestHeader(client::error::Error), + #[display(fmt = "Best header does not exist")] + NoBestHeader, + #[display(fmt = "Block proposing error: {:?}", _0)] + BlockProposingError(String), + #[display(fmt = "Fetch best hash failed via select chain: {:?}", _0)] + BestHashSelectChain(ConsensusError), + #[display(fmt = "Error with block built on {:?}: {:?}", _0, _1)] + BlockBuiltError(B::Hash, ConsensusError), + #[display(fmt = "Creating inherents failed: {}", _0)] + CreateInherents(RuntimeString), + #[display(fmt = "Checking inherents failed: {}", _0)] + CheckInherents(String), + Client(client::error::Error), + Codec(codec::Error), + Environment(String), + Runtime(RuntimeString) +} + +impl std::convert::From> for String { + fn from(error: Error) -> String { + error.to_string() + } +} + /// Auxiliary storage prefix for PoW engine. pub const POW_AUX_PREFIX: [u8; 4] = *b"PoW:"; @@ -74,12 +112,12 @@ impl PowAux where Difficulty: Decode + Default, { /// Read the auxiliary from client. - pub fn read(client: &C, hash: &H256) -> Result { + pub fn read(client: &C, hash: &H256) -> Result> { let key = aux_key(hash); - match client.get_aux(&key).map_err(|e| format!("{:?}", e))? { + match client.get_aux(&key).map_err(Error::Client)? { Some(bytes) => Self::decode(&mut &bytes[..]) - .map_err(|e| format!("{:?}", e)), + .map_err(Error::Codec), None => Ok(Self::default()), } } @@ -91,7 +129,7 @@ pub trait PowAlgorithm { type Difficulty: TotalDifficulty + Default + Encode + Decode + Ord + Clone + Copy; /// Get the next block's difficulty. - fn difficulty(&self, parent: &BlockId) -> Result; + fn difficulty(&self, parent: &BlockId) -> Result>; /// Verify proof of work against the given difficulty. fn verify( &self, @@ -99,7 +137,7 @@ pub trait PowAlgorithm { pre_hash: &H256, seal: &Seal, difficulty: Self::Difficulty, - ) -> Result; + ) -> Result>; /// Mine a seal that satisfies the given difficulty. fn mine( &self, @@ -107,7 +145,7 @@ pub trait PowAlgorithm { pre_hash: &H256, difficulty: Self::Difficulty, round: u32, - ) -> Result, String>; + ) -> Result, Error>; } /// A verifier for PoW blocks. @@ -134,7 +172,7 @@ impl, C, S, Algorithm> PowVerifier { &self, mut header: B::Header, parent_block_id: BlockId, - ) -> Result<(B::Header, Algorithm::Difficulty, DigestItem), String> where + ) -> Result<(B::Header, Algorithm::Difficulty, DigestItem), Error> where Algorithm: PowAlgorithm, { let hash = header.hash(); @@ -144,10 +182,10 @@ impl, C, S, Algorithm> PowVerifier { if id == POW_ENGINE_ID { (DigestItem::Seal(id, seal.clone()), seal) } else { - return Err(format!("Header uses the wrong engine {:?}", id)) + return Err(Error::WrongEngine(id)) } }, - _ => return Err(format!("Header {:?} is unsealed", hash)), + _ => return Err(Error::HeaderUnsealed(hash)), }; let pre_hash = header.hash(); @@ -159,7 +197,7 @@ impl, C, S, Algorithm> PowVerifier { &inner_seal, difficulty, )? { - return Err("PoW validation error: invalid seal".into()); + return Err(Error::InvalidSeal); } Ok((header, difficulty, seal)) @@ -171,7 +209,7 @@ impl, C, S, Algorithm> PowVerifier { block_id: BlockId, inherent_data: InherentData, timestamp_now: u64, - ) -> Result<(), String> where + ) -> Result<(), Error> where C: ProvideRuntimeApi, C::Api: BlockBuilderApi { const MAX_TIMESTAMP_DRIFT_SECS: u64 = 60; @@ -184,7 +222,7 @@ impl, C, S, Algorithm> PowVerifier { &block_id, block, inherent_data, - ).map_err(|e| format!("{:?}", e))?; + ).map_err(Error::Client)?; if !inherent_res.ok() { inherent_res @@ -192,13 +230,15 @@ impl, C, S, Algorithm> PowVerifier { .try_for_each(|(i, e)| match TIError::try_from(&i, &e) { Some(TIError::ValidAtTimestamp(timestamp)) => { if timestamp > timestamp_now + MAX_TIMESTAMP_DRIFT_SECS { - return Err("Rejecting block too far in future".into()); + return Err(Error::TooFarInFuture); } Ok(()) }, - Some(TIError::Other(e)) => Err(e.into()), - None => Err(self.inherent_data_providers.error_to_string(&i, &e)), + Some(TIError::Other(e)) => Err(Error::Runtime(e)), + None => Err(Error::CheckInherents( + self.inherent_data_providers.error_to_string(&i, &e) + )), }) } else { Ok(()) @@ -231,8 +271,8 @@ impl, C, S, Algorithm> Verifier for PowVerifier(self.client.as_ref(), &best_hash)?; + let mut aux = PowAux::read::<_, B>(self.client.as_ref(), &parent_hash)?; let (checked_header, difficulty, seal) = self.check_header( header, @@ -390,7 +430,7 @@ fn mine_loop, C, Algorithm, E, SO, S>( build_time: std::time::Duration, select_chain: Option<&S>, inherent_data_providers: &inherents::InherentDataProviders, -) -> Result<(), String> where +) -> Result<(), Error> where C: HeaderBackend + AuxStore, Algorithm: PowAlgorithm, E: Environment, @@ -408,23 +448,24 @@ fn mine_loop, C, Algorithm, E, SO, S>( let (best_hash, best_header) = match select_chain { Some(select_chain) => { let header = select_chain.best_chain() - .map_err(|e| format!("Fetching best header failed using select chain: {:?}", e))?; + .map_err(Error::BestHeaderSelectChain)?; let hash = header.hash(); (hash, header) }, None => { let hash = client.info().best_hash; let header = client.header(BlockId::Hash(hash)) - .map_err(|e| format!("Fetching best header failed: {:?}", e))? - .ok_or("Best header does not exist")?; + .map_err(Error::BestHeader)? + .ok_or(Error::NoBestHeader)?; (hash, header) }, }; let mut aux = PowAux::read(client, &best_hash)?; - let mut proposer = env.init(&best_header).map_err(|e| format!("{:?}", e))?; + let mut proposer = env.init(&best_header) + .map_err(|e| Error::Environment(format!("{:?}", e)))?; let inherent_data = inherent_data_providers - .create_inherent_data().map_err(String::from)?; + .create_inherent_data().map_err(Error::CreateInherents)?; let mut inherent_digest = Digest::default(); if let Some(preruntime) = &preruntime { inherent_digest.push(DigestItem::PreRuntime(POW_ENGINE_ID, preruntime.to_vec())); @@ -433,7 +474,7 @@ fn mine_loop, C, Algorithm, E, SO, S>( inherent_data, inherent_digest, build_time.clone(), - )).map_err(|e| format!("Block proposing error: {:?}", e))?; + )).map_err(|e| Error::BlockProposingError(format!("{:?}", e)))?; let (header, body) = block.deconstruct(); let (difficulty, seal) = { @@ -470,7 +511,7 @@ fn mine_loop, C, Algorithm, E, SO, S>( let key = aux_key(&hash); let best_hash = match select_chain { Some(select_chain) => select_chain.best_chain() - .map_err(|e| format!("Fetch best hash failed via select chain: {:?}", e))? + .map_err(Error::BestHashSelectChain)? .hash(), None => client.info().best_hash, }; @@ -493,6 +534,6 @@ fn mine_loop, C, Algorithm, E, SO, S>( }; block_import.import_block(import_block, HashMap::default()) - .map_err(|e| format!("Error with block built on {:?}: {:?}", best_hash, e))?; + .map_err(|e| Error::BlockBuiltError(best_hash, e))?; } } -- GitLab From 165e7c93ae0593a93634139e4a74371bb35cfaac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 17 Oct 2019 12:54:28 +0200 Subject: [PATCH 222/275] Make `VersionInfo` derive `Clone` (#3839) --- core/cli/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/core/cli/src/lib.rs b/core/cli/src/lib.rs index d4bb4f6f0d..c5af33b738 100644 --- a/core/cli/src/lib.rs +++ b/core/cli/src/lib.rs @@ -79,6 +79,7 @@ const NODE_KEY_SECP256K1_FILE: &str = "secret"; const NODE_KEY_ED25519_FILE: &str = "secret_ed25519"; /// Executable version. Used to pass version information from the root crate. +#[derive(Clone)] pub struct VersionInfo { /// Implementaiton name. pub name: &'static str, -- GitLab From df1582beef2d47109a0adcb14376420b1a99e157 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Thu, 17 Oct 2019 14:21:32 +0200 Subject: [PATCH 223/275] refactor: Transaction-Payment module (#3816) * Initial draft that compiles * Extract payment stuff from balances * Extract multiplier update stuff from system * Some fixes. * Update len-fee as well * some review comments. * Remove todo * bump --- Cargo.lock | 22 + Cargo.toml | 1 + core/sr-primitives/src/sr_arithmetic.rs | 39 +- core/sr-primitives/src/weights.rs | 76 ---- core/test-runtime/src/lib.rs | 1 - node-template/runtime/Cargo.toml | 2 + node-template/runtime/src/lib.rs | 22 +- node-template/runtime/src/template.rs | 1 - node/cli/Cargo.toml | 1 + node/cli/src/factory_impl.rs | 2 +- node/cli/src/service.rs | 4 +- node/executor/Cargo.toml | 1 + node/executor/src/lib.rs | 81 ++-- node/runtime/Cargo.toml | 2 + node/runtime/src/constants.rs | 8 +- node/runtime/src/impls.rs | 169 +++++--- node/runtime/src/lib.rs | 26 +- node/testing/Cargo.toml | 1 + node/testing/src/keyring.rs | 2 +- srml/assets/src/lib.rs | 1 - srml/aura/src/mock.rs | 1 - srml/authority-discovery/src/lib.rs | 1 - srml/authorship/src/lib.rs | 1 - srml/babe/src/mock.rs | 1 - srml/balances/Cargo.toml | 1 + srml/balances/src/lib.rs | 141 +------ srml/balances/src/mock.rs | 56 +-- srml/balances/src/tests.rs | 99 +---- srml/collective/src/lib.rs | 1 - srml/contracts/src/lib.rs | 2 +- srml/contracts/src/tests.rs | 7 - srml/council/src/lib.rs | 7 - srml/democracy/src/lib.rs | 7 - srml/elections-phragmen/src/lib.rs | 7 - srml/elections/src/mock.rs | 7 - srml/example/src/lib.rs | 7 - srml/executive/Cargo.toml | 1 + srml/executive/src/lib.rs | 20 +- srml/finality-tracker/src/lib.rs | 1 - srml/generic-asset/src/lib.rs | 1 - srml/generic-asset/src/mock.rs | 1 - srml/grandpa/src/mock.rs | 1 - srml/im-online/src/mock.rs | 1 - srml/indices/src/mock.rs | 1 - srml/membership/src/lib.rs | 1 - srml/offences/src/mock.rs | 1 - srml/randomness-collective-flip/src/lib.rs | 1 - srml/scored-pool/src/mock.rs | 7 - srml/session/src/mock.rs | 1 - srml/staking/src/mock.rs | 7 - srml/system/benches/bench.rs | 1 - srml/system/src/lib.rs | 28 +- srml/timestamp/src/lib.rs | 1 - srml/transaction-payment/Cargo.toml | 27 ++ srml/transaction-payment/src/lib.rs | 455 +++++++++++++++++++++ srml/treasury/src/lib.rs | 7 - srml/utility/src/lib.rs | 7 - subkey/Cargo.toml | 1 + subkey/src/main.rs | 2 +- 59 files changed, 785 insertions(+), 597 deletions(-) create mode 100644 srml/transaction-payment/Cargo.toml create mode 100644 srml/transaction-payment/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 1fd3c18534..c1aec02c00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2357,6 +2357,7 @@ dependencies = [ "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", + "srml-transaction-payment 2.0.0", "structopt 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-authority-discovery 2.0.0", "substrate-basic-authorship 2.0.0", @@ -2403,6 +2404,7 @@ dependencies = [ "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", + "srml-transaction-payment 2.0.0", "srml-treasury 2.0.0", "substrate-executor 2.0.0", "substrate-primitives 2.0.0", @@ -2488,6 +2490,7 @@ dependencies = [ "srml-system 2.0.0", "srml-system-rpc-runtime-api 2.0.0", "srml-timestamp 2.0.0", + "srml-transaction-payment 2.0.0", "srml-treasury 2.0.0", "srml-utility 2.0.0", "substrate-authority-discovery-primitives 2.0.0", @@ -2552,6 +2555,7 @@ dependencies = [ "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", + "srml-transaction-payment 2.0.0", "substrate-client 2.0.0", "substrate-consensus-babe-primitives 2.0.0", "substrate-offchain-primitives 2.0.0", @@ -2579,6 +2583,7 @@ dependencies = [ "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", + "srml-transaction-payment 2.0.0", "srml-treasury 2.0.0", "substrate-client 2.0.0", "substrate-executor 2.0.0", @@ -3988,6 +3993,7 @@ dependencies = [ "sr-std 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", + "srml-transaction-payment 2.0.0", "substrate-keyring 2.0.0", "substrate-primitives 2.0.0", ] @@ -4138,6 +4144,7 @@ dependencies = [ "srml-indices 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", + "srml-transaction-payment 2.0.0", "substrate-primitives 2.0.0", ] @@ -4490,6 +4497,20 @@ dependencies = [ "substrate-primitives 2.0.0", ] +[[package]] +name = "srml-transaction-payment" +version = "2.0.0" +dependencies = [ + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 2.0.0", + "sr-primitives 2.0.0", + "sr-std 2.0.0", + "srml-balances 2.0.0", + "srml-support 2.0.0", + "srml-system 2.0.0", + "substrate-primitives 2.0.0", +] + [[package]] name = "srml-treasury" version = "2.0.0" @@ -4608,6 +4629,7 @@ dependencies = [ "sr-primitives 2.0.0", "srml-balances 2.0.0", "srml-system 2.0.0", + "srml-transaction-payment 2.0.0", "substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-primitives 2.0.0", "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 6508e2b41e..5b012be0e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,6 +106,7 @@ members = [ "srml/system/rpc", "srml/timestamp", "srml/treasury", + "srml/transaction-payment", "srml/utility", "node/cli", "node/executor", diff --git a/core/sr-primitives/src/sr_arithmetic.rs b/core/sr-primitives/src/sr_arithmetic.rs index 043a383a33..5f5b5dc1e5 100644 --- a/core/sr-primitives/src/sr_arithmetic.rs +++ b/core/sr-primitives/src/sr_arithmetic.rs @@ -543,7 +543,6 @@ implement_per_thing!( /// An unsigned fixed point number. Can hold any value in the range [-9_223_372_036, 9_223_372_036] /// with fixed point accuracy of one billion. -#[cfg_attr(feature = "std", derive(Debug))] #[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct Fixed64(i64); @@ -668,6 +667,13 @@ impl CheckedAdd for Fixed64 { } } +#[cfg(feature = "std")] +impl rstd::fmt::Debug for Fixed64 { + fn fmt(&self, f: &mut rstd::fmt::Formatter<'_>) -> rstd::fmt::Result { + write!(f, "Fixed64({},{})", self.0 / DIV, (self.0 % DIV) / 1000) + } +} + /// Infinite precision unsigned integer for substrate runtime. pub mod biguint { use super::Zero; @@ -981,8 +987,6 @@ pub mod biguint { let mut q = Self::with_capacity(m + 1); let mut r = Self::with_capacity(n); - debug_assert!(other.msb() != 0); - // PROOF: 0 <= normalizer_bits < SHIFT 0 <= normalizer < B. all conversions are // safe. let normalizer_bits = other.msb().leading_zeros() as Single; @@ -2136,6 +2140,35 @@ mod tests_fixed64 { assert_eq!(max(), Fixed64::from_natural(9_223_372_037)); } + #[test] + fn fixed_64_growth_decrease_curve() { + let test_set = vec![0u32, 1, 10, 1000, 1_000_000_000]; + + // negative (1/2) + let mut fm = Fixed64::from_rational(-1, 2); + test_set.clone().into_iter().for_each(|i| { + assert_eq!(fm.saturated_multiply_accumulate(i) as i32, i as i32 - i as i32 / 2); + }); + + // unit (1) multiplier + fm = Fixed64::from_parts(0); + test_set.clone().into_iter().for_each(|i| { + assert_eq!(fm.saturated_multiply_accumulate(i), i); + }); + + // i.5 multiplier + fm = Fixed64::from_rational(1, 2); + test_set.clone().into_iter().for_each(|i| { + assert_eq!(fm.saturated_multiply_accumulate(i), i * 3 / 2); + }); + + // dual multiplier + fm = Fixed64::from_rational(1, 1); + test_set.clone().into_iter().for_each(|i| { + assert_eq!(fm.saturated_multiply_accumulate(i), i * 2); + }); + } + macro_rules! saturating_mul_acc_test { ($num_type:tt) => { assert_eq!( diff --git a/core/sr-primitives/src/weights.rs b/core/sr-primitives/src/weights.rs index 28f1b2fe0c..2ffd4ee391 100644 --- a/core/sr-primitives/src/weights.rs +++ b/core/sr-primitives/src/weights.rs @@ -23,9 +23,6 @@ //! Note that the decl_module macro _cannot_ enforce this and will simply fail if an invalid struct //! (something that does not implement `Weighable`) is passed in. -use crate::{Fixed64, traits::Saturating}; -use crate::codec::{Encode, Decode}; - pub use crate::transaction_validity::TransactionPriority; use crate::traits::Bounded; @@ -167,76 +164,3 @@ impl Default for SimpleDispatchInfo { SimpleDispatchInfo::FixedNormal(10_000) } } - -/// Representation of a weight multiplier. This represents how a fee value can be computed from a -/// weighted transaction. -/// -/// This is basically a wrapper for the `Fixed64` type a slightly tailored multiplication to u32 -/// in the form of the `apply_to` method. -#[cfg_attr(feature = "std", derive(Debug))] -#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct WeightMultiplier(Fixed64); - -impl WeightMultiplier { - /// Apply the inner Fixed64 as a weight multiplier to a weight value. - /// - /// This will perform a saturated `weight + weight * self.0`. - pub fn apply_to(&self, weight: Weight) -> Weight { - self.0.saturated_multiply_accumulate(weight) - } - - /// build self from raw parts per billion. - #[cfg(feature = "std")] - pub fn from_parts(parts: i64) -> Self { - Self(Fixed64::from_parts(parts)) - } - - /// build self from a fixed64 value. - pub fn from_fixed(f: Fixed64) -> Self { - Self(f) - } - - /// Approximate the fraction `n/d`. - pub fn from_rational(n: i64, d: u64) -> Self { - Self(Fixed64::from_rational(n, d)) - } -} - -impl Saturating for WeightMultiplier { - fn saturating_add(self, rhs: Self) -> Self { - Self(self.0.saturating_add(rhs.0)) - } - fn saturating_mul(self, rhs: Self) -> Self { - Self(self.0.saturating_mul(rhs.0)) - - } - fn saturating_sub(self, rhs: Self) -> Self { - Self(self.0.saturating_sub(rhs.0)) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn multiplier_apply_to_works() { - let test_set = vec![0, 1, 10, 1000, 1_000_000_000]; - - // negative (1/2) - let mut fm = WeightMultiplier::from_rational(-1, 2); - test_set.clone().into_iter().for_each(|i| { assert_eq!(fm.apply_to(i) as i32, i as i32 - i as i32 / 2); }); - - // unit (1) multiplier - fm = WeightMultiplier::from_parts(0); - test_set.clone().into_iter().for_each(|i| { assert_eq!(fm.apply_to(i), i); }); - - // i.5 multiplier - fm = WeightMultiplier::from_rational(1, 2); - test_set.clone().into_iter().for_each(|i| { assert_eq!(fm.apply_to(i), i * 3 / 2); }); - - // dual multiplier - fm = WeightMultiplier::from_rational(1, 1); - test_set.clone().into_iter().for_each(|i| { assert_eq!(fm.apply_to(i), i * 2); }); - } -} diff --git a/core/test-runtime/src/lib.rs b/core/test-runtime/src/lib.rs index fddee22be2..3cb89de56f 100644 --- a/core/test-runtime/src/lib.rs +++ b/core/test-runtime/src/lib.rs @@ -382,7 +382,6 @@ impl srml_system::Trait for Runtime { type Lookup = IdentityLookup; type Header = Header; type Event = Event; - type WeightMultiplierUpdate = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; diff --git a/node-template/runtime/Cargo.toml b/node-template/runtime/Cargo.toml index 76821b6dfd..96484c16ae 100644 --- a/node-template/runtime/Cargo.toml +++ b/node-template/runtime/Cargo.toml @@ -24,6 +24,7 @@ randomness-collective-flip = { package = "srml-randomness-collective-flip", path system = { package = "srml-system", path = "../../srml/system", default_features = false } timestamp = { package = "srml-timestamp", path = "../../srml/timestamp", default_features = false } sudo = { package = "srml-sudo", path = "../../srml/sudo", default_features = false } +transaction-payment = { package = "srml-transaction-payment", path = "../../srml/transaction-payment", default_features = false } sr-primitives = { path = "../../core/sr-primitives", default_features = false } client = { package = "substrate-client", path = "../../core/client", default_features = false } offchain-primitives = { package = "substrate-offchain-primitives", path = "../../core/offchain/primitives", default-features = false } @@ -51,6 +52,7 @@ std = [ "system/std", "timestamp/std", "sudo/std", + "transaction-payment/std", "version/std", "serde", "safe-mix/std", diff --git a/node-template/runtime/src/lib.rs b/node-template/runtime/src/lib.rs index 0e9b8050f0..da49ad4474 100644 --- a/node-template/runtime/src/lib.rs +++ b/node-template/runtime/src/lib.rs @@ -166,18 +166,17 @@ impl system::Trait for Runtime { type Header = generic::Header; /// The ubiquitous event type. type Event = Event; - /// Update weight (to fee) multiplier per-block. - type WeightMultiplierUpdate = (); /// The ubiquitous origin type. type Origin = Origin; /// Maximum number of block number to block hash mappings to keep (oldest pruned first). type BlockHashCount = BlockHashCount; - /// Maximum weight of each block. With a default weight system of 1byte == 1weight, 4mb is ok. + /// Maximum weight of each block. type MaximumBlockWeight = MaximumBlockWeight; /// Maximum size of all encoded transactions (in bytes) that are allowed in one block. type MaximumBlockLength = MaximumBlockLength; /// Portion of the block weight that is available to all normal transactions. type AvailableBlockRatio = AvailableBlockRatio; + /// Version of the runtime. type Version = Version; } @@ -223,8 +222,6 @@ parameter_types! { pub const ExistentialDeposit: u128 = 500; pub const TransferFee: u128 = 0; pub const CreationFee: u128 = 0; - pub const TransactionBaseFee: u128 = 0; - pub const TransactionByteFee: u128 = 1; } impl balances::Trait for Runtime { @@ -236,15 +233,25 @@ impl balances::Trait for Runtime { type OnNewAccount = Indices; /// The ubiquitous event type. type Event = Event; - type TransactionPayment = (); type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; +} + +parameter_types! { + pub const TransactionBaseFee: Balance = 0; + pub const TransactionByteFee: Balance = 1; +} + +impl transaction_payment::Trait for Runtime { + type Currency = balances::Module; + type OnTransactionPayment = (); type TransactionBaseFee = TransactionBaseFee; type TransactionByteFee = TransactionByteFee; type WeightToFee = ConvertInto; + type FeeMultiplierUpdate = (); } impl sudo::Trait for Runtime { @@ -269,6 +276,7 @@ construct_runtime!( Grandpa: grandpa::{Module, Call, Storage, Config, Event}, Indices: indices::{default, Config}, Balances: balances::{default, Error}, + TransactionPayment: transaction_payment::{Module, Storage}, Sudo: sudo, // Used for the module template in `./template.rs` TemplateModule: template::{Module, Call, Storage, Event}, @@ -293,7 +301,7 @@ pub type SignedExtra = ( system::CheckEra, system::CheckNonce, system::CheckWeight, - balances::TakeFees + transaction_payment::ChargeTransactionPayment ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; diff --git a/node-template/runtime/src/template.rs b/node-template/runtime/src/template.rs index eb4398787d..8c6c35edc4 100644 --- a/node-template/runtime/src/template.rs +++ b/node-template/runtime/src/template.rs @@ -100,7 +100,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index 0ddd7b49ff..5fa92360d6 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -45,6 +45,7 @@ finality_tracker = { package = "srml-finality-tracker", path = "../../srml/final contracts = { package = "srml-contracts", path = "../../srml/contracts" } system = { package = "srml-system", path = "../../srml/system" } balances = { package = "srml-balances", path = "../../srml/balances" } +transaction-payment = { package = "srml-transaction-payment", path = "../../srml/transaction-payment" } support = { package = "srml-support", path = "../../srml/support", default-features = false } im_online = { package = "srml-im-online", path = "../../srml/im-online", default-features = false } sr-authority-discovery = { package = "srml-authority-discovery", path = "../../srml/authority-discovery", default-features = false } diff --git a/node/cli/src/factory_impl.rs b/node/cli/src/factory_impl.rs index 827b8e308c..84c24f2af0 100644 --- a/node/cli/src/factory_impl.rs +++ b/node/cli/src/factory_impl.rs @@ -56,7 +56,7 @@ impl FactoryState { system::CheckEra::from(Era::mortal(256, phase)), system::CheckNonce::from(index), system::CheckWeight::new(), - balances::TakeFees::from(0), + transaction_payment::ChargeTransactionPayment::from(0), Default::default(), ) } diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index 7012a3d6ce..485cd325b0 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -528,14 +528,14 @@ mod tests { let check_era = system::CheckEra::from(Era::Immortal); let check_nonce = system::CheckNonce::from(index); let check_weight = system::CheckWeight::new(); - let take_fees = balances::TakeFees::from(0); + let payment = transaction_payment::ChargeTransactionPayment::from(0); let extra = ( check_version, check_genesis, check_era, check_nonce, check_weight, - take_fees, + payment, Default::default(), ); let raw_payload = SignedPayload::from_raw( diff --git a/node/executor/Cargo.toml b/node/executor/Cargo.toml index 63f1c8c0f4..1908443ca9 100644 --- a/node/executor/Cargo.toml +++ b/node/executor/Cargo.toml @@ -22,6 +22,7 @@ test-client = { package = "substrate-test-client", path = "../../core/test-clien sr-primitives = { path = "../../core/sr-primitives" } runtime_support = { package = "srml-support", path = "../../srml/support" } balances = { package = "srml-balances", path = "../../srml/balances" } +transaction-payment = { package = "srml-transaction-payment", path = "../../srml/transaction-payment" } session = { package = "srml-session", path = "../../srml/session" } system = { package = "srml-system", path = "../../srml/system" } timestamp = { package = "srml-timestamp", path = "../../srml/timestamp" } diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index 2c2ad479f5..3558987716 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -46,16 +46,16 @@ mod tests { traits::{CodeExecutor, Externalities}, storage::well_known_keys, }; use sr_primitives::{ - assert_eq_error_rate, + Fixed64, traits::{Header as HeaderT, Hash as HashT, Convert}, ApplyResult, - transaction_validity::InvalidTransaction, weights::{WeightMultiplier, GetDispatchInfo}, + transaction_validity::InvalidTransaction, weights::GetDispatchInfo, }; use contracts::ContractAddressFor; use substrate_executor::{NativeExecutor, WasmExecutionMethod}; use system::{EventRecord, Phase}; use node_runtime::{ Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances, BuildStorage, - System, Event, TransferFee, TransactionBaseFee, TransactionByteFee, + System, TransactionPayment, Event, TransferFee, TransactionBaseFee, TransactionByteFee, constants::currency::*, impls::WeightToFee, }; use node_primitives::{Balance, Hash, BlockNumber}; @@ -88,17 +88,15 @@ mod tests { } /// Default transfer fee - fn transfer_fee(extrinsic: &E) -> Balance { + fn transfer_fee(extrinsic: &E, fee_multiplier: Fixed64) -> Balance { let length_fee = TransactionBaseFee::get() + TransactionByteFee::get() * (extrinsic.encode().len() as Balance); let weight = default_transfer_call().get_dispatch_info().weight; - // NOTE: this is really hard to apply, since the multiplier of each block needs to be fetched - // before the block, while we compute this after the block. - // weight = >::next_weight_multiplier().apply_to(weight); - let weight_fee = ::WeightToFee::convert(weight); - length_fee + weight_fee + TransferFee::get() + let weight_fee = ::WeightToFee::convert(weight); + + fee_multiplier.saturated_multiply_accumulate(length_fee + weight_fee) + TransferFee::get() } fn default_transfer_call() -> balances::Call { @@ -217,6 +215,9 @@ mod tests { None, ).0; assert!(r.is_ok()); + + let fm = t.execute_with(TransactionPayment::next_fee_multiplier); + let r = executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, "BlockBuilder_apply_extrinsic", @@ -227,7 +228,7 @@ mod tests { assert!(r.is_ok()); t.execute_with(|| { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt(), fm)); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); } @@ -253,6 +254,9 @@ mod tests { None, ).0; assert!(r.is_ok()); + + let fm = t.execute_with(TransactionPayment::next_fee_multiplier); + let r = executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, "BlockBuilder_apply_extrinsic", @@ -263,7 +267,7 @@ mod tests { assert!(r.is_ok()); t.execute_with(|| { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt(), fm)); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); } @@ -425,6 +429,9 @@ mod tests { let (block1, block2) = blocks(); + let mut alice_last_known_balance: Balance = Default::default(); + let mut fm = t.execute_with(TransactionPayment::next_fee_multiplier); + executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, "Core_execute_block", @@ -434,8 +441,9 @@ mod tests { ).0.unwrap(); t.execute_with(|| { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt(), fm)); assert_eq!(Balances::total_balance(&bob()), 169 * DOLLARS); + alice_last_known_balance = Balances::total_balance(&alice()); let events = vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), @@ -460,6 +468,9 @@ mod tests { ]; assert_eq!(System::events(), events); }); + + fm = t.execute_with(TransactionPayment::next_fee_multiplier); + executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, "Core_execute_block", @@ -471,15 +482,13 @@ mod tests { t.execute_with(|| { // NOTE: fees differ slightly in tests that execute more than one block due to the // weight update. Hence, using `assert_eq_error_rate`. - assert_eq_error_rate!( + assert_eq!( Balances::total_balance(&alice()), - 32 * DOLLARS - 2 * transfer_fee(&xt()), - 10_000 + alice_last_known_balance - 10 * DOLLARS - transfer_fee(&xt(), fm), ); - assert_eq_error_rate!( + assert_eq!( Balances::total_balance(&bob()), - 179 * DOLLARS - transfer_fee(&xt()), - 10_000 + 179 * DOLLARS - transfer_fee(&xt(), fm), ); let events = vec![ EventRecord { @@ -532,6 +541,9 @@ mod tests { let (block1, block2) = blocks(); + let mut alice_last_known_balance: Balance = Default::default(); + let mut fm = t.execute_with(TransactionPayment::next_fee_multiplier); + executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, "Core_execute_block", @@ -541,10 +553,13 @@ mod tests { ).0.unwrap(); t.execute_with(|| { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt(), fm)); assert_eq!(Balances::total_balance(&bob()), 169 * DOLLARS); + alice_last_known_balance = Balances::total_balance(&alice()); }); + fm = t.execute_with(TransactionPayment::next_fee_multiplier); + executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, "Core_execute_block", @@ -554,15 +569,13 @@ mod tests { ).0.unwrap(); t.execute_with(|| { - assert_eq_error_rate!( + assert_eq!( Balances::total_balance(&alice()), - 32 * DOLLARS - 2 * transfer_fee(&xt()), - 10_000 + alice_last_known_balance - 10 * DOLLARS - transfer_fee(&xt(), fm), ); - assert_eq_error_rate!( + assert_eq!( Balances::total_balance(&bob()), - 179 * DOLLARS - 1 * transfer_fee(&xt()), - 10_000 + 179 * DOLLARS - 1 * transfer_fee(&xt(), fm), ); }); } @@ -824,6 +837,7 @@ mod tests { None, ).0; assert!(r.is_ok()); + let fm = t.execute_with(TransactionPayment::next_fee_multiplier); let r = executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, "BlockBuilder_apply_extrinsic", @@ -837,7 +851,7 @@ mod tests { .expect("Extrinsic did not fail"); t.execute_with(|| { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - 1 * transfer_fee(&xt())); + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - 1 * transfer_fee(&xt(), fm)); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); } @@ -890,13 +904,14 @@ mod tests { #[test] - fn weight_multiplier_increases_and_decreases_on_big_weight() { + fn fee_multiplier_increases_and_decreases_on_big_weight() { let mut t = new_test_ext(COMPACT_CODE, false); - let mut prev_multiplier = WeightMultiplier::default(); + // initial fee multiplier must be zero + let mut prev_multiplier = Fixed64::from_parts(0); t.execute_with(|| { - assert_eq!(System::next_weight_multiplier(), prev_multiplier); + assert_eq!(TransactionPayment::next_fee_multiplier(), prev_multiplier); }); let mut tt = new_test_ext(COMPACT_CODE, false); @@ -948,7 +963,7 @@ mod tests { // weight multiplier is increased for next block. t.execute_with(|| { - let fm = System::next_weight_multiplier(); + let fm = TransactionPayment::next_fee_multiplier(); println!("After a big block: {:?} -> {:?}", prev_multiplier, fm); assert!(fm > prev_multiplier); prev_multiplier = fm; @@ -965,7 +980,7 @@ mod tests { // weight multiplier is increased for next block. t.execute_with(|| { - let fm = System::next_weight_multiplier(); + let fm = TransactionPayment::next_fee_multiplier(); println!("After a small block: {:?} -> {:?}", prev_multiplier, fm); assert!(fm < prev_multiplier); }); @@ -978,7 +993,7 @@ mod tests { // weight of transfer call as of now: 1_000_000 // if weight of the cheapest weight would be 10^7, this would be 10^9, which is: // - 1 MILLICENTS in substrate node. - // - 1 milldot based on current polkadot runtime. + // - 1 milli-dot based on current polkadot runtime. // (this baed on assigning 0.1 CENT to the cheapest tx with `weight = 100`) let mut t = TestExternalities::::new_with_code(COMPACT_CODE, (map![ >::hashed_key_for(alice()) => { @@ -1052,6 +1067,7 @@ mod tests { fn block_weight_capacity_report() { // Just report how many transfer calls you could fit into a block. The number should at least // be a few hundred (250 at the time of writing but can change over time). Runs until panic. + use node_primitives::Index; // execution ext. let mut t = new_test_ext(COMPACT_CODE, false); @@ -1118,6 +1134,7 @@ mod tests { // Just report how big a block can get. Executes until panic. Should be ignored unless if // manually inspected. The number should at least be a few megabytes (5 at the time of // writing but can change over time). + use node_primitives::Index; // execution ext. let mut t = new_test_ext(COMPACT_CODE, false); diff --git a/node/runtime/Cargo.toml b/node/runtime/Cargo.toml index f9818c096e..af66c0432f 100644 --- a/node/runtime/Cargo.toml +++ b/node/runtime/Cargo.toml @@ -52,6 +52,7 @@ system-rpc-runtime-api = { package = "srml-system-rpc-runtime-api", path = "../. timestamp = { package = "srml-timestamp", path = "../../srml/timestamp", default-features = false } treasury = { package = "srml-treasury", path = "../../srml/treasury", default-features = false } utility = { package = "srml-utility", path = "../../srml/utility", default-features = false } +transaction-payment = { package = "srml-transaction-payment", path = "../../srml/transaction-payment", default-features = false } [build-dependencies] wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.2", path = "../../core/utils/wasm-builder-runner" } @@ -100,5 +101,6 @@ std = [ "timestamp/std", "treasury/std", "utility/std", + "transaction-payment/std", "version/std", ] diff --git a/node/runtime/src/constants.rs b/node/runtime/src/constants.rs index 79d3dbd8eb..ca57bdc8ba 100644 --- a/node/runtime/src/constants.rs +++ b/node/runtime/src/constants.rs @@ -67,10 +67,10 @@ pub mod time { pub const DAYS: BlockNumber = HOURS * 24; } -// CRITICAL NOTE: The system module maintains two constants: a _maximum_ block weight and a -// _ratio_ of it yielding the portion which is accessible to normal transactions (reserving the rest -// for operational ones). `TARGET_BLOCK_FULLNESS` is entirely independent and the system module is -// not aware of if, nor should it care about it. This constant simply denotes on which ratio of the +// CRITICAL NOTE: The system module maintains two constants: a _maximum_ block weight and a _ratio_ +// of it yielding the portion which is accessible to normal transactions (reserving the rest for +// operational ones). `TARGET_BLOCK_FULLNESS` is entirely independent and the system module is not +// aware of if, nor should it care about it. This constant simply denotes on which ratio of the // _maximum_ block weight we tweak the fees. It does NOT care about the type of the dispatch. // // For the system to be configured in a sane way, `TARGET_BLOCK_FULLNESS` should always be less than diff --git a/node/runtime/src/impls.rs b/node/runtime/src/impls.rs index 2e1fcc8826..2193845020 100644 --- a/node/runtime/src/impls.rs +++ b/node/runtime/src/impls.rs @@ -17,7 +17,7 @@ //! Some configurable implementations as associated type for the substrate runtime. use node_primitives::Balance; -use sr_primitives::weights::{Weight, WeightMultiplier}; +use sr_primitives::weights::Weight; use sr_primitives::traits::{Convert, Saturating}; use sr_primitives::Fixed64; use support::traits::{OnUnbalanced, Currency}; @@ -82,10 +82,10 @@ impl Convert for WeightToFee { /// next_weight = weight * (1 + (v . diff) + (v . diff)^2 / 2) /// /// https://research.web3.foundation/en/latest/polkadot/Token%20Economics/#relay-chain-transaction-fees -pub struct WeightMultiplierUpdateHandler; +pub struct FeeMultiplierUpdateHandler; -impl Convert<(Weight, WeightMultiplier), WeightMultiplier> for WeightMultiplierUpdateHandler { - fn convert(previous_state: (Weight, WeightMultiplier)) -> WeightMultiplier { +impl Convert<(Weight, Fixed64), Fixed64> for FeeMultiplierUpdateHandler { + fn convert(previous_state: (Weight, Fixed64)) -> Fixed64 { let (block_weight, multiplier) = previous_state; let max_weight = MaximumBlockWeight::get(); let target_weight = (TARGET_BLOCK_FULLNESS * max_weight) as u128; @@ -113,17 +113,17 @@ impl Convert<(Weight, WeightMultiplier), WeightMultiplier> for WeightMultiplierU // Note: this is merely bounded by how big the multiplier and the inner value can go, // not by any economical reasoning. let excess = first_term.saturating_add(second_term); - multiplier.saturating_add(WeightMultiplier::from_fixed(excess)) + multiplier.saturating_add(excess) } else { - // first_term > second_term + // Proof: first_term > second_term. Safe subtraction. let negative = first_term - second_term; - multiplier.saturating_sub(WeightMultiplier::from_fixed(negative)) + multiplier.saturating_sub(negative) // despite the fact that apply_to saturates weight (final fee cannot go below 0) // it is crucially important to stop here and don't further reduce the weight fee // multiplier. While at -1, it means that the network is so un-congested that all // transactions have no weight fee. We stop here and only increase if the network // became more busy. - .max(WeightMultiplier::from_rational(-1, 1)) + .max(Fixed64::from_rational(-1, 1)) } } } @@ -132,7 +132,6 @@ impl Convert<(Weight, WeightMultiplier), WeightMultiplier> for WeightMultiplierU mod tests { use super::*; use sr_primitives::weights::Weight; - use sr_primitives::Perbill; use crate::{MaximumBlockWeight, AvailableBlockRatio, Runtime}; use crate::constants::currency::*; @@ -145,8 +144,7 @@ mod tests { } // poc reference implementation. - #[allow(dead_code)] - fn weight_multiplier_update(block_weight: Weight) -> Perbill { + fn fee_multiplier_update(block_weight: Weight, previous: Fixed64) -> Fixed64 { let block_weight = block_weight as f32; let v: f32 = 0.00004; @@ -157,53 +155,84 @@ mod tests { // Current saturation in terms of weight let s = block_weight; - let fm = 1.0 + (v * (s/m - ss/m)) + (v.powi(2) * (s/m - ss/m).powi(2)) / 2.0; - // return a per-bill-like value. - let fm = if fm >= 1.0 { fm - 1.0 } else { 1.0 - fm }; - Perbill::from_parts((fm * 1_000_000_000_f32) as u32) + let fm = (v * (s/m - ss/m)) + (v.powi(2) * (s/m - ss/m).powi(2)) / 2.0; + let addition_fm = Fixed64::from_parts((fm * 1_000_000_000_f32) as i64); + previous.saturating_add(addition_fm) } - fn wm(parts: i64) -> WeightMultiplier { - WeightMultiplier::from_parts(parts) + fn fm(parts: i64) -> Fixed64 { + Fixed64::from_parts(parts) + } + + #[test] + fn fee_multiplier_update_poc_works() { + let fm = Fixed64::from_rational(0, 1); + let test_set = vec![ + // TODO: this has a rounding error and fails. + // (0, fm.clone()), + (100, fm.clone()), + (target(), fm.clone()), + (max() / 2, fm.clone()), + (max(), fm.clone()), + ]; + test_set.into_iter().for_each(|(w, fm)| { + assert_eq!( + fee_multiplier_update(w, fm), + FeeMultiplierUpdateHandler::convert((w, fm)), + "failed for weight {} and prev fm {:?}", + w, + fm, + ); + }) } #[test] fn empty_chain_simulation() { // just a few txs per_block. let block_weight = 1000; - let mut wm = WeightMultiplier::default(); + let mut fm = Fixed64::default(); let mut iterations: u64 = 0; loop { - let next = WeightMultiplierUpdateHandler::convert((block_weight, wm)); - wm = next; - if wm == WeightMultiplier::from_rational(-1, 1) { break; } + let next = FeeMultiplierUpdateHandler::convert((block_weight, fm)); + fm = next; + if fm == Fixed64::from_rational(-1, 1) { break; } iterations += 1; } - println!("iteration {}, new wm = {:?}. Weight fee is now zero", iterations, wm); + println!("iteration {}, new fm = {:?}. Weight fee is now zero", iterations, fm); } #[test] #[ignore] fn congested_chain_simulation() { // `cargo test congested_chain_simulation -- --nocapture` to get some insight. + // almost full. The entire quota of normal transactions is taken. let block_weight = AvailableBlockRatio::get() * max(); - let tx_weight = 1000; - let mut wm = WeightMultiplier::default(); + + // default minimum substrate weight + let tx_weight = 10_000u32; + + // initial value of system + let mut fm = Fixed64::default(); + assert_eq!(fm, Fixed64::from_parts(0)); + let mut iterations: u64 = 0; loop { - let next = WeightMultiplierUpdateHandler::convert((block_weight, wm)); - if wm == next { break; } - wm = next; + let next = FeeMultiplierUpdateHandler::convert((block_weight, fm)); + if fm == next { break; } + fm = next; iterations += 1; - let fee = ::WeightToFee::convert(wm.apply_to(tx_weight)); + let fee = ::WeightToFee::convert(tx_weight); + let adjusted_fee = fm.saturated_multiply_accumulate(fee); println!( - "iteration {}, new wm = {:?}. Fee at this point is: {} millicents, {} cents, {} dollars", + "iteration {}, new fm = {:?}. Fee at this point is: \ + {} units, {} millicents, {} cents, {} dollars", iterations, - wm, - fee / MILLICENTS, - fee / CENTS, - fee / DOLLARS + fm, + adjusted_fee, + adjusted_fee / MILLICENTS, + adjusted_fee / CENTS, + adjusted_fee / DOLLARS ); } } @@ -212,65 +241,65 @@ mod tests { fn stateless_weight_mul() { // Light block. Fee is reduced a little. assert_eq!( - WeightMultiplierUpdateHandler::convert((target() / 4, WeightMultiplier::default())), - wm(-7500) + FeeMultiplierUpdateHandler::convert((target() / 4, Fixed64::default())), + fm(-7500) ); // a bit more. Fee is decreased less, meaning that the fee increases as the block grows. assert_eq!( - WeightMultiplierUpdateHandler::convert((target() / 2, WeightMultiplier::default())), - wm(-5000) + FeeMultiplierUpdateHandler::convert((target() / 2, Fixed64::default())), + fm(-5000) ); // ideal. Original fee. No changes. assert_eq!( - WeightMultiplierUpdateHandler::convert((target(), WeightMultiplier::default())), - wm(0) + FeeMultiplierUpdateHandler::convert((target(), Fixed64::default())), + fm(0) ); // // More than ideal. Fee is increased. assert_eq!( - WeightMultiplierUpdateHandler::convert(((target() * 2), WeightMultiplier::default())), - wm(10000) + FeeMultiplierUpdateHandler::convert(((target() * 2), Fixed64::default())), + fm(10000) ); } #[test] fn stateful_weight_mul_grow_to_infinity() { assert_eq!( - WeightMultiplierUpdateHandler::convert((target() * 2, WeightMultiplier::default())), - wm(10000) + FeeMultiplierUpdateHandler::convert((target() * 2, Fixed64::default())), + fm(10000) ); assert_eq!( - WeightMultiplierUpdateHandler::convert((target() * 2, wm(10000))), - wm(20000) + FeeMultiplierUpdateHandler::convert((target() * 2, fm(10000))), + fm(20000) ); assert_eq!( - WeightMultiplierUpdateHandler::convert((target() * 2, wm(20000))), - wm(30000) + FeeMultiplierUpdateHandler::convert((target() * 2, fm(20000))), + fm(30000) ); // ... assert_eq!( - WeightMultiplierUpdateHandler::convert((target() * 2, wm(1_000_000_000))), - wm(1_000_000_000 + 10000) + FeeMultiplierUpdateHandler::convert((target() * 2, fm(1_000_000_000))), + fm(1_000_000_000 + 10000) ); } #[test] fn stateful_weight_mil_collapse_to_minus_one() { assert_eq!( - WeightMultiplierUpdateHandler::convert((0, WeightMultiplier::default())), - wm(-10000) + FeeMultiplierUpdateHandler::convert((0, Fixed64::default())), + fm(-10000) ); assert_eq!( - WeightMultiplierUpdateHandler::convert((0, wm(-10000))), - wm(-20000) + FeeMultiplierUpdateHandler::convert((0, fm(-10000))), + fm(-20000) ); assert_eq!( - WeightMultiplierUpdateHandler::convert((0, wm(-20000))), - wm(-30000) + FeeMultiplierUpdateHandler::convert((0, fm(-20000))), + fm(-30000) ); // ... assert_eq!( - WeightMultiplierUpdateHandler::convert((0, wm(1_000_000_000 * -1))), - wm(-1_000_000_000) + FeeMultiplierUpdateHandler::convert((0, fm(1_000_000_000 * -1))), + fm(-1_000_000_000) ); } @@ -278,20 +307,30 @@ mod tests { fn weight_to_fee_should_not_overflow_on_large_weights() { let kb = 1024 as Weight; let mb = kb * kb; - let max_fm = WeightMultiplier::from_fixed(Fixed64::from_natural(i64::max_value())); - - vec![0, 1, 10, 1000, kb, 10 * kb, 100 * kb, mb, 10 * mb, Weight::max_value() / 2, Weight::max_value()] - .into_iter() - .for_each(|i| { - WeightMultiplierUpdateHandler::convert((i, WeightMultiplier::default())); - }); + let max_fm = Fixed64::from_natural(i64::max_value()); + + vec![ + 0, + 1, + 10, + 1000, + kb, + 10 * kb, + 100 * kb, + mb, + 10 * mb, + Weight::max_value() / 2, + Weight::max_value() + ].into_iter().for_each(|i| { + FeeMultiplierUpdateHandler::convert((i, Fixed64::default())); + }); // Some values that are all above the target and will cause an increase. let t = target(); vec![t + 100, t * 2, t * 4] .into_iter() .for_each(|i| { - let fm = WeightMultiplierUpdateHandler::convert(( + let fm = FeeMultiplierUpdateHandler::convert(( i, max_fm )); diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 63fc856013..fdf0bfdc14 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -65,7 +65,7 @@ pub use staking::StakerStatus; /// Implementations of some helper traits passed into runtime modules as associated types. pub mod impls; -use impls::{CurrencyToVoteHandler, WeightMultiplierUpdateHandler, Author, WeightToFee}; +use impls::{CurrencyToVoteHandler, FeeMultiplierUpdateHandler, Author, WeightToFee}; /// Constant values used within the runtime. pub mod constants; @@ -84,8 +84,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 177, - impl_version: 177, + spec_version: 178, + impl_version: 178, apis: RUNTIME_API_VERSIONS, }; @@ -125,7 +125,6 @@ impl system::Trait for Runtime { type AccountId = AccountId; type Lookup = Indices; type Header = generic::Header; - type WeightMultiplierUpdate = WeightMultiplierUpdateHandler; type Event = Event; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -161,8 +160,6 @@ parameter_types! { pub const ExistentialDeposit: Balance = 1 * DOLLARS; pub const TransferFee: Balance = 1 * CENTS; pub const CreationFee: Balance = 1 * CENTS; - pub const TransactionBaseFee: Balance = 1 * CENTS; - pub const TransactionByteFee: Balance = 10 * MILLICENTS; } impl balances::Trait for Runtime { @@ -170,15 +167,25 @@ impl balances::Trait for Runtime { type OnFreeBalanceZero = ((Staking, Contracts), Session); type OnNewAccount = Indices; type Event = Event; - type TransactionPayment = DealWithFees; type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; +} + +parameter_types! { + pub const TransactionBaseFee: Balance = 1 * CENTS; + pub const TransactionByteFee: Balance = 10 * MILLICENTS; +} + +impl transaction_payment::Trait for Runtime { + type Currency = Balances; + type OnTransactionPayment = DealWithFees; type TransactionBaseFee = TransactionBaseFee; type TransactionByteFee = TransactionByteFee; type WeightToFee = WeightToFee; + type FeeMultiplierUpdate = FeeMultiplierUpdateHandler; } parameter_types! { @@ -480,7 +487,7 @@ impl system::offchain::CreateTransaction for Runtim system::CheckEra::::from(generic::Era::mortal(period, current_block)), system::CheckNonce::::from(index), system::CheckWeight::::new(), - balances::TakeFees::::from(tip), + transaction_payment::ChargeTransactionPayment::::from(tip), Default::default(), ); let raw_payload = SignedPayload::new(call, extra).ok()?; @@ -504,6 +511,7 @@ construct_runtime!( Authorship: authorship::{Module, Call, Storage, Inherent}, Indices: indices, Balances: balances::{default, Error}, + TransactionPayment: transaction_payment::{Module, Storage}, Staking: staking::{default, OfflineWorker}, Session: session::{Module, Call, Storage, Event, Config}, Democracy: democracy::{Module, Call, Storage, Config, Event}, @@ -540,7 +548,7 @@ pub type SignedExtra = ( system::CheckEra, system::CheckNonce, system::CheckWeight, - balances::TakeFees, + transaction_payment::ChargeTransactionPayment, contracts::CheckBlockGasLimit, ); /// Unchecked extrinsic type as expected by this runtime. diff --git a/node/testing/Cargo.toml b/node/testing/Cargo.toml index e622e35d4a..8a4c08ed11 100644 --- a/node/testing/Cargo.toml +++ b/node/testing/Cargo.toml @@ -27,4 +27,5 @@ system = { package = "srml-system", path = "../../srml/system" } test-client = { package = "substrate-test-client", path = "../../core/test-client" } timestamp = { package = "srml-timestamp", path = "../../srml/timestamp" } treasury = { package = "srml-treasury", path = "../../srml/treasury" } +transaction-payment = { package = "srml-transaction-payment", path = "../../srml/transaction-payment" } wabt = "0.9.2" diff --git a/node/testing/src/keyring.rs b/node/testing/src/keyring.rs index 0c6eb478cc..853ca0ef6d 100644 --- a/node/testing/src/keyring.rs +++ b/node/testing/src/keyring.rs @@ -72,7 +72,7 @@ pub fn signed_extra(nonce: Index, extra_fee: Balance) -> SignedExtra { system::CheckEra::from(Era::mortal(256, 0)), system::CheckNonce::from(nonce), system::CheckWeight::new(), - balances::TakeFees::from(extra_fee), + transaction_payment::ChargeTransactionPayment::from(extra_fee), Default::default(), ) } diff --git a/srml/assets/src/lib.rs b/srml/assets/src/lib.rs index de95caf88f..37845c3a14 100644 --- a/srml/assets/src/lib.rs +++ b/srml/assets/src/lib.rs @@ -271,7 +271,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/aura/src/mock.rs b/srml/aura/src/mock.rs index 7ebfd2a533..5c55e8bdd5 100644 --- a/srml/aura/src/mock.rs +++ b/srml/aura/src/mock.rs @@ -54,7 +54,6 @@ impl system::Trait for Test { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/authority-discovery/src/lib.rs b/srml/authority-discovery/src/lib.rs index 177e11c4c0..2c923103a8 100644 --- a/srml/authority-discovery/src/lib.rs +++ b/srml/authority-discovery/src/lib.rs @@ -204,7 +204,6 @@ mod tests { type AccountId = AuthorityId; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/authorship/src/lib.rs b/srml/authorship/src/lib.rs index dcd1985664..b42104a26b 100644 --- a/srml/authorship/src/lib.rs +++ b/srml/authorship/src/lib.rs @@ -442,7 +442,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/babe/src/mock.rs b/srml/babe/src/mock.rs index 582299f11c..5a6b80a2a6 100644 --- a/srml/babe/src/mock.rs +++ b/srml/babe/src/mock.rs @@ -62,7 +62,6 @@ impl system::Trait for Test { type AccountId = DummyValidatorId; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/balances/Cargo.toml b/srml/balances/Cargo.toml index d2b6e00d98..f7f6041c6b 100644 --- a/srml/balances/Cargo.toml +++ b/srml/balances/Cargo.toml @@ -17,6 +17,7 @@ system = { package = "srml-system", path = "../system", default-features = false [dev-dependencies] runtime-io = { package = "sr-io", path = "../../core/sr-io" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } +transaction-payment = { package = "srml-transaction-payment", path = "../transaction-payment" } [features] default = ["std"] diff --git a/srml/balances/src/lib.rs b/srml/balances/src/lib.rs index b75c7a96de..4f8edc5428 100644 --- a/srml/balances/src/lib.rs +++ b/srml/balances/src/lib.rs @@ -86,17 +86,6 @@ //! //! - `vesting_balance` - Get the amount that is currently being vested and cannot be transferred out of this account. //! -//! ### Signed Extensions -//! -//! The balances module defines the following extensions: -//! -//! - [`TakeFees`]: Consumes fees proportional to the length and weight of the transaction. -//! Additionally, it can contain a single encoded payload as a `tip`. The inclusion priority -//! is increased proportional to the tip. -//! -//! Lookup the runtime aggregator file (e.g. `node/runtime`) to see the full list of signed -//! extensions included in a chain. -//! //! ## Usage //! //! The following examples show how to use the Balances module in your custom module. @@ -171,15 +160,11 @@ use support::{ dispatch::Result, }; use sr_primitives::{ - transaction_validity::{ - TransactionPriority, ValidTransaction, InvalidTransaction, TransactionValidityError, - TransactionValidity, - }, traits::{ Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub, MaybeSerializeDebug, - Saturating, Bounded, SignedExtension, SaturatedConversion, Convert, + Saturating, Bounded, }, - weights::{DispatchInfo, SimpleDispatchInfo, Weight}, + weights::SimpleDispatchInfo, }; use system::{IsDeadAccount, OnNewAccount, ensure_signed, ensure_root}; @@ -210,15 +195,6 @@ pub trait Subtrait: system::Trait { /// The fee required to create an account. type CreationFee: Get; - - /// The fee to be paid for making a transaction; the base. - type TransactionBaseFee: Get; - - /// The fee to be paid for making a transaction; the per-byte portion. - type TransactionByteFee: Get; - - /// Convert a weight value into a deductible fee based on the currency type. - type WeightToFee: Convert; } pub trait Trait: system::Trait { @@ -235,9 +211,6 @@ pub trait Trait: system::Trait { /// Handler for when a new account is created. type OnNewAccount: OnNewAccount; - /// Handler for the unbalanced reduction when taking transaction fees. - type TransactionPayment: OnUnbalanced>; - /// Handler for the unbalanced reduction when taking fees associated with balance /// transfer (which may also include account creation). type TransferPayment: OnUnbalanced>; @@ -256,15 +229,6 @@ pub trait Trait: system::Trait { /// The fee required to create an account. type CreationFee: Get; - - /// The fee to be paid for making a transaction; the base. - type TransactionBaseFee: Get; - - /// The fee to be paid for making a transaction; the per-byte portion. - type TransactionByteFee: Get; - - /// Convert a weight value into a deductible fee based on the currency type. - type WeightToFee: Convert; } impl, I: Instance> Subtrait for T { @@ -274,9 +238,6 @@ impl, I: Instance> Subtrait for T { type ExistentialDeposit = T::ExistentialDeposit; type TransferFee = T::TransferFee; type CreationFee = T::CreationFee; - type TransactionBaseFee = T::TransactionBaseFee; - type TransactionByteFee = T::TransactionByteFee; - type WeightToFee = T::WeightToFee; } decl_event!( @@ -414,12 +375,6 @@ decl_module! { /// The fee required to create an account. const CreationFee: T::Balance = T::CreationFee::get(); - /// The fee to be paid for making a transaction; the base. - const TransactionBaseFee: T::Balance = T::TransactionBaseFee::get(); - - /// The fee to be paid for making a transaction; the per-byte portion. - const TransactionByteFee: T::Balance = T::TransactionByteFee::get(); - fn deposit_event() = default; /// Transfer some liquid free balance to another account. @@ -776,7 +731,7 @@ mod imbalances { // This works as long as `increase_total_issuance_by` doesn't use the Imbalance // types (basically for charging fees). // This should eventually be refactored so that the three type items that do -// depend on the Imbalance type (TransactionPayment, TransferPayment, DustRemoval) +// depend on the Imbalance type (TransferPayment, DustRemoval) // are placed in their own SRML module. struct ElevatedTrait, I: Instance>(T, I); impl, I: Instance> Clone for ElevatedTrait { @@ -796,7 +751,6 @@ impl, I: Instance> system::Trait for ElevatedTrait { type AccountId = T::AccountId; type Lookup = T::Lookup; type Header = T::Header; - type WeightMultiplierUpdate = T::WeightMultiplierUpdate; type Event = (); type BlockHashCount = T::BlockHashCount; type MaximumBlockWeight = T::MaximumBlockWeight; @@ -809,15 +763,11 @@ impl, I: Instance> Trait for ElevatedTrait { type OnFreeBalanceZero = T::OnFreeBalanceZero; type OnNewAccount = T::OnNewAccount; type Event = (); - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = T::ExistentialDeposit; type TransferFee = T::TransferFee; type CreationFee = T::CreationFee; - type TransactionBaseFee = T::TransactionBaseFee; - type TransactionByteFee = T::TransactionByteFee; - type WeightToFee = T::WeightToFee; } impl, I: Instance> Currency for Module @@ -1194,91 +1144,6 @@ where } } -/// Require the transactor pay for themselves and maybe include a tip to gain additional priority -/// in the queue. -#[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct TakeFees, I: Instance = DefaultInstance>(#[codec(compact)] T::Balance); - -impl, I: Instance> TakeFees { - /// utility constructor. Used only in client/factory code. - pub fn from(fee: T::Balance) -> Self { - Self(fee) - } - - /// Compute the final fee value for a particular transaction. - /// - /// The final fee is composed of: - /// - _length-fee_: This is the amount paid merely to pay for size of the transaction. - /// - _weight-fee_: This amount is computed based on the weight of the transaction. Unlike - /// size-fee, this is not input dependent and reflects the _complexity_ of the execution - /// and the time it consumes. - /// - (optional) _tip_: if included in the transaction, it will be added on top. Only signed - /// transactions can have a tip. - fn compute_fee(len: usize, info: DispatchInfo, tip: T::Balance) -> T::Balance { - let len_fee = if info.pay_length_fee() { - let len = T::Balance::from(len as u32); - let base = T::TransactionBaseFee::get(); - let per_byte = T::TransactionByteFee::get(); - base.saturating_add(per_byte.saturating_mul(len)) - } else { - Zero::zero() - }; - - let weight_fee = { - // cap the weight to the maximum defined in runtime, otherwise it will be the `Bounded` - // maximum of its data type, which is not desired. - let capped_weight = info.weight.min(::MaximumBlockWeight::get()); - let weight_update = >::next_weight_multiplier(); - let adjusted_weight = weight_update.apply_to(capped_weight); - T::WeightToFee::convert(adjusted_weight) - }; - - len_fee.saturating_add(weight_fee).saturating_add(tip) - } -} - -#[cfg(feature = "std")] -impl, I: Instance> rstd::fmt::Debug for TakeFees { - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { - self.0.fmt(f) - } -} - -impl, I: Instance + Clone + Eq> SignedExtension for TakeFees { - type AccountId = T::AccountId; - type Call = T::Call; - type AdditionalSigned = (); - type Pre = (); - fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } - - fn validate( - &self, - who: &Self::AccountId, - _call: &Self::Call, - info: DispatchInfo, - len: usize, - ) -> TransactionValidity { - // pay any fees. - let fee = Self::compute_fee(len, info, self.0); - let imbalance = match >::withdraw( - who, - fee, - WithdrawReason::TransactionPayment, - ExistenceRequirement::KeepAlive, - ) { - Ok(imbalance) => imbalance, - Err(_) => return InvalidTransaction::Payment.into(), - }; - T::TransactionPayment::on_unbalanced(imbalance); - - let mut r = ValidTransaction::default(); - // NOTE: we probably want to maximize the _fee (of any type) per weight unit_ here, which - // will be a bit more than setting the priority to tip. For now, this is enough. - r.priority = fee.saturated_into::(); - Ok(r) - } -} - impl, I: Instance> IsDeadAccount for Module where T::Balance: MaybeSerializeDebug diff --git a/srml/balances/src/mock.rs b/srml/balances/src/mock.rs index a909795178..600d0e6fb7 100644 --- a/srml/balances/src/mock.rs +++ b/srml/balances/src/mock.rs @@ -18,7 +18,7 @@ #![cfg(test)] -use sr_primitives::{Perbill, traits::{Convert, IdentityLookup}, testing::Header, +use sr_primitives::{Perbill, traits::{ConvertInto, IdentityLookup}, testing::Header, weights::{DispatchInfo, Weight}}; use primitives::H256; use runtime_io; @@ -35,10 +35,6 @@ thread_local! { static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); static TRANSFER_FEE: RefCell = RefCell::new(0); static CREATION_FEE: RefCell = RefCell::new(0); - static TRANSACTION_BASE_FEE: RefCell = RefCell::new(0); - static TRANSACTION_BYTE_FEE: RefCell = RefCell::new(1); - static TRANSACTION_WEIGHT_FEE: RefCell = RefCell::new(1); - static WEIGHT_TO_FEE: RefCell = RefCell::new(1); } pub struct ExistentialDeposit; @@ -56,23 +52,6 @@ impl Get for CreationFee { fn get() -> u64 { CREATION_FEE.with(|v| *v.borrow()) } } -pub struct TransactionBaseFee; -impl Get for TransactionBaseFee { - fn get() -> u64 { TRANSACTION_BASE_FEE.with(|v| *v.borrow()) } -} - -pub struct TransactionByteFee; -impl Get for TransactionByteFee { - fn get() -> u64 { TRANSACTION_BYTE_FEE.with(|v| *v.borrow()) } -} - -pub struct WeightToFee(u64); -impl Convert for WeightToFee { - fn convert(t: Weight) -> u64 { - WEIGHT_TO_FEE.with(|v| *v.borrow() * (t as u64)) - } -} - // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Runtime; @@ -92,7 +71,6 @@ impl system::Trait for Runtime { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -100,26 +78,31 @@ impl system::Trait for Runtime { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); } +parameter_types! { + pub const TransactionBaseFee: u64 = 0; + pub const TransactionByteFee: u64 = 1; +} +impl transaction_payment::Trait for Runtime { + type Currency = Module; + type OnTransactionPayment = (); + type TransactionBaseFee = TransactionBaseFee; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = ConvertInto; + type FeeMultiplierUpdate = (); +} impl Trait for Runtime { type Balance = u64; type OnFreeBalanceZero = (); type OnNewAccount = (); type Event = (); - type TransactionPayment = (); type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = WeightToFee; } pub struct ExtBuilder { - transaction_base_fee: u64, - transaction_byte_fee: u64, - weight_to_fee: u64, existential_deposit: u64, transfer_fee: u64, creation_fee: u64, @@ -129,9 +112,6 @@ pub struct ExtBuilder { impl Default for ExtBuilder { fn default() -> Self { Self { - transaction_base_fee: 0, - transaction_byte_fee: 0, - weight_to_fee: 0, existential_deposit: 0, transfer_fee: 0, creation_fee: 0, @@ -141,12 +121,6 @@ impl Default for ExtBuilder { } } impl ExtBuilder { - pub fn transaction_fees(mut self, base_fee: u64, byte_fee: u64, weight_fee: u64) -> Self { - self.transaction_base_fee = base_fee; - self.transaction_byte_fee = byte_fee; - self.weight_to_fee = weight_fee; - self - } pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { self.existential_deposit = existential_deposit; self @@ -175,9 +149,6 @@ impl ExtBuilder { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); TRANSFER_FEE.with(|v| *v.borrow_mut() = self.transfer_fee); CREATION_FEE.with(|v| *v.borrow_mut() = self.creation_fee); - TRANSACTION_BASE_FEE.with(|v| *v.borrow_mut() = self.transaction_base_fee); - TRANSACTION_BYTE_FEE.with(|v| *v.borrow_mut() = self.transaction_byte_fee); - WEIGHT_TO_FEE.with(|v| *v.borrow_mut() = self.weight_to_fee); } pub fn build(self) -> runtime_io::TestExternalities { self.set_associated_consts(); @@ -211,7 +182,6 @@ impl ExtBuilder { pub type System = system::Module; pub type Balances = Module; - pub const CALL: &::Call = &(); /// create a transaction info struct from weight. Handy to avoid building the whole struct. diff --git a/srml/balances/src/tests.rs b/srml/balances/src/tests.rs index 0b119d3ae6..839ac67991 100644 --- a/srml/balances/src/tests.rs +++ b/srml/balances/src/tests.rs @@ -20,12 +20,13 @@ use super::*; use mock::{Balances, ExtBuilder, Runtime, System, info_from_weight, CALL}; +use sr_primitives::traits::SignedExtension; use support::{ assert_noop, assert_ok, assert_err, traits::{LockableCurrency, LockIdentifier, WithdrawReason, WithdrawReasons, Currency, ReservableCurrency} }; -use sr_primitives::weights::DispatchClass; +use transaction_payment::ChargeTransactionPayment; use system::RawOrigin; const ID_1: LockIdentifier = *b"1 "; @@ -115,7 +116,6 @@ fn lock_reasons_should_work() { ExtBuilder::default() .existential_deposit(1) .monied(true) - .transaction_fees(0, 1, 0) .build() .execute_with(|| { Balances::set_lock(ID_1, &1, 10, u64::max_value(), WithdrawReason::Transfer.into()); @@ -125,8 +125,8 @@ fn lock_reasons_should_work() { ); assert_ok!(>::reserve(&1, 1)); // NOTE: this causes a fee payment. - assert!( as SignedExtension>::pre_dispatch( - TakeFees::from(1), + assert!( as SignedExtension>::pre_dispatch( + ChargeTransactionPayment::from(1), &1, CALL, info_from_weight(1), @@ -139,8 +139,8 @@ fn lock_reasons_should_work() { >::reserve(&1, 1), "account liquidity restrictions prevent withdrawal" ); - assert!( as SignedExtension>::pre_dispatch( - TakeFees::from(1), + assert!( as SignedExtension>::pre_dispatch( + ChargeTransactionPayment::from(1), &1, CALL, info_from_weight(1), @@ -150,8 +150,8 @@ fn lock_reasons_should_work() { Balances::set_lock(ID_1, &1, 10, u64::max_value(), WithdrawReason::TransactionPayment.into()); assert_ok!(>::transfer(&1, &2, 1)); assert_ok!(>::reserve(&1, 1)); - assert!( as SignedExtension>::pre_dispatch( - TakeFees::from(1), + assert!( as SignedExtension>::pre_dispatch( + ChargeTransactionPayment::from(1), &1, CALL, info_from_weight(1), @@ -736,89 +736,6 @@ fn liquid_funds_should_transfer_with_delayed_vesting() { }); } -#[test] -fn signed_extension_take_fees_work() { - ExtBuilder::default() - .existential_deposit(10) - .transaction_fees(10, 1, 5) - .monied(true) - .build() - .execute_with(|| { - let len = 10; - assert!( - TakeFees::::from(0) - .pre_dispatch(&1, CALL, info_from_weight(5), len) - .is_ok() - ); - assert_eq!(Balances::free_balance(&1), 100 - 20 - 25); - assert!( - TakeFees::::from(5 /* tipped */) - .pre_dispatch(&1, CALL, info_from_weight(3), len) - .is_ok() - ); - assert_eq!(Balances::free_balance(&1), 100 - 20 - 25 - 20 - 5 - 15); - }); -} - -#[test] -fn signed_extension_take_fees_is_bounded() { - ExtBuilder::default() - .existential_deposit(1000) - .transaction_fees(0, 0, 1) - .monied(true) - .build() - .execute_with(|| { - use sr_primitives::weights::Weight; - - // maximum weight possible - assert!( - TakeFees::::from(0) - .pre_dispatch(&1, CALL, info_from_weight(Weight::max_value()), 10) - .is_ok() - ); - // fee will be proportional to what is the actual maximum weight in the runtime. - assert_eq!( - Balances::free_balance(&1), - (10000 - ::MaximumBlockWeight::get()) as u64 - ); - }); -} - -#[test] -fn signed_extension_allows_free_transactions() { - ExtBuilder::default() - .transaction_fees(100, 1, 1) - .monied(false) - .build() - .execute_with(|| { - // 1 ain't have a penny. - assert_eq!(Balances::free_balance(&1), 0); - - // like a FreeOperational - let operational_transaction = DispatchInfo { - weight: 0, - class: DispatchClass::Operational - }; - let len = 100; - assert!( - TakeFees::::from(0) - .validate(&1, CALL, operational_transaction , len) - .is_ok() - ); - - // like a FreeNormal - let free_transaction = DispatchInfo { - weight: 0, - class: DispatchClass::Normal - }; - assert!( - TakeFees::::from(0) - .validate(&1, CALL, free_transaction , len) - .is_err() - ); - }); -} - #[test] fn burn_must_work() { ExtBuilder::default().monied(true).build().execute_with(|| { diff --git a/srml/collective/src/lib.rs b/srml/collective/src/lib.rs index 2de6243dd6..edfc4bf46f 100644 --- a/srml/collective/src/lib.rs +++ b/srml/collective/src/lib.rs @@ -406,7 +406,6 @@ mod tests { type Lookup = IdentityLookup; type Header = Header; type Event = Event; - type WeightMultiplierUpdate = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; diff --git a/srml/contracts/src/lib.rs b/srml/contracts/src/lib.rs index 678fc65d76..3d8a455ad7 100644 --- a/srml/contracts/src/lib.rs +++ b/srml/contracts/src/lib.rs @@ -442,7 +442,7 @@ where } /// The default dispatch fee computor computes the fee in the same way that -/// the implementation of `TakeFees` for the Balances module does. Note that this only takes a fixed +/// the implementation of `ChargeTransactionPayment` for the Balances module does. Note that this only takes a fixed /// fee based on size. Unlike the balances module, weight-fee is applied. pub struct DefaultDispatchFeeComputor(PhantomData); impl ComputeDispatchFee<::Call, BalanceOf> for DefaultDispatchFeeComputor { diff --git a/srml/contracts/src/tests.rs b/srml/contracts/src/tests.rs index d6de2ce3bd..d3b52c334b 100644 --- a/srml/contracts/src/tests.rs +++ b/srml/contracts/src/tests.rs @@ -96,8 +96,6 @@ parameter_types! { pub const BlockHashCount: u64 = 250; pub const MaximumBlockWeight: u32 = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; - pub const BalancesTransactionBaseFee: u64 = 0; - pub const BalancesTransactionByteFee: u64 = 0; pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl system::Trait for Test { @@ -110,7 +108,6 @@ impl system::Trait for Test { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = MetaEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -123,15 +120,11 @@ impl balances::Trait for Test { type OnFreeBalanceZero = Contract; type OnNewAccount = (); type Event = MetaEvent; - type TransactionPayment = (); type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = BalancesTransactionBaseFee; - type TransactionByteFee = BalancesTransactionByteFee; - type WeightToFee = (); } parameter_types! { pub const MinimumPeriod: u64 = 1; diff --git a/srml/council/src/lib.rs b/srml/council/src/lib.rs index e65cf9ace1..195202c873 100644 --- a/srml/council/src/lib.rs +++ b/srml/council/src/lib.rs @@ -114,7 +114,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = Event; type Error = Error; type BlockHashCount = BlockHashCount; @@ -127,24 +126,18 @@ mod tests { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 1; - pub const TransactionByteFee: u64 = 0; } impl balances::Trait for Test { type Balance = u64; type OnNewAccount = (); type OnFreeBalanceZero = (); type Event = Event; - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type Error = Error; type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = (); } parameter_types! { pub const LaunchPeriod: u64 = 1; diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index 2af301df1c..b7e7dac6f9 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -1015,7 +1015,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -1027,23 +1026,17 @@ mod tests { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 0; - pub const TransactionByteFee: u64 = 0; } impl balances::Trait for Test { type Balance = u64; type OnFreeBalanceZero = (); type OnNewAccount = (); type Event = (); - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = (); } parameter_types! { pub const LaunchPeriod: u64 = 2; diff --git a/srml/elections-phragmen/src/lib.rs b/srml/elections-phragmen/src/lib.rs index 6ec79a537c..fdc88ce9e0 100644 --- a/srml/elections-phragmen/src/lib.rs +++ b/srml/elections-phragmen/src/lib.rs @@ -616,7 +616,6 @@ mod tests { type Lookup = IdentityLookup; type Header = Header; type Event = Event; - type WeightMultiplierUpdate = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; @@ -628,8 +627,6 @@ mod tests { pub const ExistentialDeposit: u64 = 1; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 0; - pub const TransactionByteFee: u64 = 0; } impl balances::Trait for Test { @@ -637,15 +634,11 @@ mod tests { type OnNewAccount = (); type OnFreeBalanceZero = (); type Event = Event; - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = (); } parameter_types! { diff --git a/srml/elections/src/mock.rs b/srml/elections/src/mock.rs index d48a0fd3fd..77b13d74a1 100644 --- a/srml/elections/src/mock.rs +++ b/srml/elections/src/mock.rs @@ -47,7 +47,6 @@ impl system::Trait for Test { type Lookup = IdentityLookup; type Header = Header; type Event = Event; - type WeightMultiplierUpdate = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; @@ -59,23 +58,17 @@ parameter_types! { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 0; - pub const TransactionByteFee: u64 = 0; } impl balances::Trait for Test { type Balance = u64; type OnNewAccount = (); type OnFreeBalanceZero = (); type Event = Event; - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = (); } parameter_types! { diff --git a/srml/example/src/lib.rs b/srml/example/src/lib.rs index 0766468efa..a6a075d8cb 100644 --- a/srml/example/src/lib.rs +++ b/srml/example/src/lib.rs @@ -667,7 +667,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -679,23 +678,17 @@ mod tests { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 0; - pub const TransactionByteFee: u64 = 0; } impl balances::Trait for Test { type Balance = u64; type OnFreeBalanceZero = (); type OnNewAccount = (); type Event = (); - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = (); } impl Trait for Test { type Event = (); diff --git a/srml/executive/Cargo.toml b/srml/executive/Cargo.toml index a87eed40b7..92191a7aac 100644 --- a/srml/executive/Cargo.toml +++ b/srml/executive/Cargo.toml @@ -18,6 +18,7 @@ hex-literal = "0.2.1" primitives = { package = "substrate-primitives", path = "../../core/primitives" } srml-indices = { path = "../indices" } balances = { package = "srml-balances", path = "../balances" } +transaction-payment = { package = "srml-transaction-payment", path = "../transaction-payment" } [features] default = ["std"] diff --git a/srml/executive/src/lib.rs b/srml/executive/src/lib.rs index 23c645f6ef..401f07d206 100644 --- a/srml/executive/src/lib.rs +++ b/srml/executive/src/lib.rs @@ -347,7 +347,6 @@ mod tests { type Header = Header; type Event = MetaEvent; type BlockHashCount = BlockHashCount; - type WeightMultiplierUpdate = (); type MaximumBlockWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; @@ -357,23 +356,30 @@ mod tests { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 10; - pub const TransactionByteFee: u64 = 0; } impl balances::Trait for Runtime { type Balance = u64; type OnFreeBalanceZero = (); type OnNewAccount = (); type Event = MetaEvent; - type TransactionPayment = (); type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; + } + + parameter_types! { + pub const TransactionBaseFee: u64 = 10; + pub const TransactionByteFee: u64 = 0; + } + impl transaction_payment::Trait for Runtime { + type Currency = Balances; + type OnTransactionPayment = (); type TransactionBaseFee = TransactionBaseFee; type TransactionByteFee = TransactionByteFee; type WeightToFee = ConvertInto; + type FeeMultiplierUpdate = (); } impl ValidateUnsigned for Runtime { @@ -391,7 +397,7 @@ mod tests { system::CheckEra, system::CheckNonce, system::CheckWeight, - balances::TakeFees + transaction_payment::ChargeTransactionPayment ); type TestXt = sr_primitives::testing::TestXt; type Executive = super::Executive, system::ChainContext, Runtime, ()>; @@ -401,7 +407,7 @@ mod tests { system::CheckEra::from(Era::Immortal), system::CheckNonce::from(nonce), system::CheckWeight::new(), - balances::TakeFees::from(fee) + transaction_payment::ChargeTransactionPayment::from(fee) ) } @@ -450,7 +456,7 @@ mod tests { header: Header { parent_hash: [69u8; 32].into(), number: 1, - state_root: hex!("a6378d7fdd31029d13718d54bdff10a370e75cc624aaf94a90e7e7d4a24e0bcc").into(), + state_root: hex!("f0d1d66255c2e5b40580eb8b93ddbe732491478487f85e358e1d167d369e398e").into(), extrinsics_root: hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(), digest: Digest { logs: vec![], }, }, diff --git a/srml/finality-tracker/src/lib.rs b/srml/finality-tracker/src/lib.rs index ba893c42d0..1106a17a58 100644 --- a/srml/finality-tracker/src/lib.rs +++ b/srml/finality-tracker/src/lib.rs @@ -298,7 +298,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/generic-asset/src/lib.rs b/srml/generic-asset/src/lib.rs index 6791ee5785..ca49e2f1cd 100644 --- a/srml/generic-asset/src/lib.rs +++ b/srml/generic-asset/src/lib.rs @@ -1056,7 +1056,6 @@ impl system::Trait for ElevatedTrait { type MaximumBlockWeight = T::MaximumBlockWeight; type MaximumBlockLength = T::MaximumBlockLength; type AvailableBlockRatio = T::AvailableBlockRatio; - type WeightMultiplierUpdate = (); type BlockHashCount = T::BlockHashCount; type Version = T::Version; } diff --git a/srml/generic-asset/src/mock.rs b/srml/generic-asset/src/mock.rs index c0f9f154b8..57b13760fa 100644 --- a/srml/generic-asset/src/mock.rs +++ b/srml/generic-asset/src/mock.rs @@ -56,7 +56,6 @@ impl system::Trait for Test { type Lookup = IdentityLookup; type Header = Header; type Event = TestEvent; - type WeightMultiplierUpdate = (); type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; diff --git a/srml/grandpa/src/mock.rs b/srml/grandpa/src/mock.rs index 8d585e4b46..fcacbade20 100644 --- a/srml/grandpa/src/mock.rs +++ b/srml/grandpa/src/mock.rs @@ -57,7 +57,6 @@ impl system::Trait for Test { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = TestEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/im-online/src/mock.rs b/srml/im-online/src/mock.rs index c2869136dc..e50e7779e9 100644 --- a/srml/im-online/src/mock.rs +++ b/srml/im-online/src/mock.rs @@ -111,7 +111,6 @@ impl system::Trait for Runtime { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/indices/src/mock.rs b/srml/indices/src/mock.rs index 59d84279a9..427fd87c47 100644 --- a/srml/indices/src/mock.rs +++ b/srml/indices/src/mock.rs @@ -81,7 +81,6 @@ impl system::Trait for Runtime { type AccountId = u64; type Lookup = Indices; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/membership/src/lib.rs b/srml/membership/src/lib.rs index 0cd3b0af66..5d2001b32d 100644 --- a/srml/membership/src/lib.rs +++ b/srml/membership/src/lib.rs @@ -224,7 +224,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/offences/src/mock.rs b/srml/offences/src/mock.rs index 01891ce32b..f9c7939081 100644 --- a/srml/offences/src/mock.rs +++ b/srml/offences/src/mock.rs @@ -78,7 +78,6 @@ impl system::Trait for Runtime { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = TestEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/randomness-collective-flip/src/lib.rs b/srml/randomness-collective-flip/src/lib.rs index 8dedf6f570..f6261b6a03 100644 --- a/srml/randomness-collective-flip/src/lib.rs +++ b/srml/randomness-collective-flip/src/lib.rs @@ -182,7 +182,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/scored-pool/src/mock.rs b/srml/scored-pool/src/mock.rs index 92a16bf25d..394f486a8b 100644 --- a/srml/scored-pool/src/mock.rs +++ b/srml/scored-pool/src/mock.rs @@ -52,8 +52,6 @@ parameter_types! { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 0; - pub const TransactionByteFee: u64 = 0; } impl system::Trait for Test { @@ -66,7 +64,6 @@ impl system::Trait for Test { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -80,15 +77,11 @@ impl balances::Trait for Test { type OnFreeBalanceZero = (); type OnNewAccount = (); type Event = (); - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = (); } thread_local! { diff --git a/srml/session/src/mock.rs b/srml/session/src/mock.rs index 736d3fa4da..d680fdc96b 100644 --- a/srml/session/src/mock.rs +++ b/srml/session/src/mock.rs @@ -168,7 +168,6 @@ impl system::Trait for Test { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/staking/src/mock.rs b/srml/staking/src/mock.rs index 43bd00e3e0..41a2ad4802 100644 --- a/srml/staking/src/mock.rs +++ b/srml/staking/src/mock.rs @@ -118,7 +118,6 @@ impl system::Trait for Test { type AccountId = AccountId; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -129,23 +128,17 @@ impl system::Trait for Test { parameter_types! { pub const TransferFee: Balance = 0; pub const CreationFee: Balance = 0; - pub const TransactionBaseFee: u64 = 0; - pub const TransactionByteFee: u64 = 0; } impl balances::Trait for Test { type Balance = Balance; type OnFreeBalanceZero = Staking; type OnNewAccount = (); type Event = (); - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = (); } parameter_types! { pub const Period: BlockNumber = 1; diff --git a/srml/system/benches/bench.rs b/srml/system/benches/bench.rs index 1b18b55fd2..6da02cf9c8 100644 --- a/srml/system/benches/bench.rs +++ b/srml/system/benches/bench.rs @@ -68,7 +68,6 @@ impl system::Trait for Runtime { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = Event; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index 71c99af3b3..caa6d573b0 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -97,13 +97,13 @@ use rstd::marker::PhantomData; use sr_version::RuntimeVersion; use sr_primitives::{ generic::{self, Era}, Perbill, ApplyError, ApplyOutcome, DispatchError, - weights::{Weight, DispatchInfo, DispatchClass, WeightMultiplier, SimpleDispatchInfo}, + weights::{Weight, DispatchInfo, DispatchClass, SimpleDispatchInfo}, transaction_validity::{ ValidTransaction, TransactionPriority, TransactionLongevity, TransactionValidityError, InvalidTransaction, TransactionValidity, }, traits::{ - self, CheckEqual, SimpleArithmetic, Zero, SignedExtension, Convert, Lookup, LookupError, + self, CheckEqual, SimpleArithmetic, Zero, SignedExtension, Lookup, LookupError, SimpleBitOps, Hash, Member, MaybeDisplay, EnsureOrigin, SaturatedConversion, MaybeSerializeDebugButNotDeserialize, MaybeSerializeDebug, StaticLookup, One, Bounded, }, @@ -188,14 +188,6 @@ pub trait Trait: 'static + Eq + Clone { /// (e.g. Indices module) may provide more functional/efficient alternatives. type Lookup: StaticLookup; - /// Handler for updating the weight multiplier at the end of each block. - /// - /// It receives the current block's weight as input and returns the next weight multiplier for next - /// block. - /// - /// Note that passing `()` will keep the value constant. - type WeightMultiplierUpdate: Convert<(Weight, WeightMultiplier), WeightMultiplier>; - /// The block header. type Header: Parameter + traits::Header< Number = Self::BlockNumber, @@ -381,9 +373,6 @@ decl_storage! { AllExtrinsicsWeight: Option; /// Total length (in bytes) for all extrinsics put together, for the current block. AllExtrinsicsLen: Option; - /// The next weight multiplier. This should be updated at the end of each block based on the - /// saturation level (weight). - pub NextWeightMultiplier get(next_weight_multiplier): WeightMultiplier = Default::default(); /// Map of block numbers to block hashes. pub BlockHash get(block_hash) build(|_| vec![(T::BlockNumber::zero(), hash69())]): map T::BlockNumber => T::Hash; /// Extrinsics data for the current block (maps an extrinsic's index to its data). @@ -612,17 +601,6 @@ impl Module { AllExtrinsicsLen::get().unwrap_or_default() } - /// Update the next weight multiplier. - /// - /// This should be called at then end of each block, before `all_extrinsics_weight` is cleared. - pub fn update_weight_multiplier() { - // update the multiplier based on block weight. - let current_weight = Self::all_extrinsics_weight(); - NextWeightMultiplier::mutate(|fm| { - *fm = T::WeightMultiplierUpdate::convert((current_weight, *fm)) - }); - } - /// Start the execution of a particular block. pub fn initialize( number: &T::BlockNumber, @@ -645,7 +623,6 @@ impl Module { /// Remove temporary "environment" entries in storage. pub fn finalize() -> T::Header { ExtrinsicCount::kill(); - Self::update_weight_multiplier(); AllExtrinsicsWeight::kill(); AllExtrinsicsLen::kill(); @@ -1118,7 +1095,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = u16; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/timestamp/src/lib.rs b/srml/timestamp/src/lib.rs index cdacb8a391..35546575c5 100644 --- a/srml/timestamp/src/lib.rs +++ b/srml/timestamp/src/lib.rs @@ -348,7 +348,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/transaction-payment/Cargo.toml b/srml/transaction-payment/Cargo.toml new file mode 100644 index 0000000000..7f8eddab19 --- /dev/null +++ b/srml/transaction-payment/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "srml-transaction-payment" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } +sr-primitives = { path = "../../core/sr-primitives", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } +system = { package = "srml-system", path = "../system", default-features = false } + +[dev-dependencies] +runtime-io = { package = "sr-io", path = "../../core/sr-io" } +primitives = { package = "substrate-primitives", path = "../../core/primitives" } +balances = { package = "srml-balances", path = "../balances" } + +[features] +default = ["std"] +std = [ + "codec/std", + "rstd/std", + "sr-primitives/std", + "support/std", + "system/std", +] diff --git a/srml/transaction-payment/src/lib.rs b/srml/transaction-payment/src/lib.rs new file mode 100644 index 0000000000..f2e815fcd4 --- /dev/null +++ b/srml/transaction-payment/src/lib.rs @@ -0,0 +1,455 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! # Transaction Payment Module +//! +//! This module provides the basic logic needed to pay the absolute minimum amount needed for a +//! transaction to be included. This includes: +//! - _weight fee_: A fee proportional to amount of weight a transaction consumes. +//! - _length fee_: A fee proportional to the encoded length of the transaction. +//! - _tip_: An optional tip. Tip increases the priority of the transaction, giving it a higher +//! chance to be included by the transaction queue. +//! +//! Additionally, this module allows one to configure: +//! - The mapping between one unit of weight to one unit of fee via [`WeightToFee`]. +//! - A means of updating the fee for the next block, via defining a multiplier, based on the +//! final state of the chain at the end of the previous block. This can be configured via +//! [`FeeMultiplierUpdate`] + +#![cfg_attr(not(feature = "std"), no_std)] + +use rstd::prelude::*; +use codec::{Encode, Decode}; +use support::{ + decl_storage, decl_module, + traits::{Currency, Get, OnUnbalanced, ExistenceRequirement, WithdrawReason}, +}; +use sr_primitives::{ + Fixed64, + transaction_validity::{ + TransactionPriority, ValidTransaction, InvalidTransaction, TransactionValidityError, + TransactionValidity, + }, + traits::{Zero, Saturating, SignedExtension, SaturatedConversion, Convert}, + weights::{Weight, DispatchInfo}, +}; + +type Multiplier = Fixed64; +type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; +type NegativeImbalanceOf = + <::Currency as Currency<::AccountId>>::NegativeImbalance; + +pub trait Trait: system::Trait { + /// The currency type in which fees will be paid. + type Currency: Currency; + + /// Handler for the unbalanced reduction when taking transaction fees. + type OnTransactionPayment: OnUnbalanced>; + + /// The fee to be paid for making a transaction; the base. + type TransactionBaseFee: Get>; + + /// The fee to be paid for making a transaction; the per-byte portion. + type TransactionByteFee: Get>; + + /// Convert a weight value into a deductible fee based on the currency type. + type WeightToFee: Convert>; + + /// Update the multiplier of the next block, based on the previous block's weight. + // TODO: maybe this does not need previous weight and can just read it + type FeeMultiplierUpdate: Convert<(Weight, Multiplier), Multiplier>; +} + +decl_storage! { + trait Store for Module as Balances { + NextFeeMultiplier get(next_fee_multiplier): Multiplier = Multiplier::from_parts(0); + } +} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + /// The fee to be paid for making a transaction; the base. + const TransactionBaseFee: BalanceOf = T::TransactionBaseFee::get(); + + /// The fee to be paid for making a transaction; the per-byte portion. + const TransactionByteFee: BalanceOf = T::TransactionByteFee::get(); + + fn on_finalize() { + let current_weight = >::all_extrinsics_weight(); + NextFeeMultiplier::mutate(|fm| { + *fm = T::FeeMultiplierUpdate::convert((current_weight, *fm)) + }); + } + } +} + +impl Module {} + +/// Require the transactor pay for themselves and maybe include a tip to gain additional priority +/// in the queue. +#[derive(Encode, Decode, Clone, Eq, PartialEq)] +pub struct ChargeTransactionPayment(#[codec(compact)] BalanceOf); + +impl ChargeTransactionPayment { + /// utility constructor. Used only in client/factory code. + pub fn from(fee: BalanceOf) -> Self { + Self(fee) + } + + /// Compute the final fee value for a particular transaction. + /// + /// The final fee is composed of: + /// - _length-fee_: This is the amount paid merely to pay for size of the transaction. + /// - _weight-fee_: This amount is computed based on the weight of the transaction. Unlike + /// size-fee, this is not input dependent and reflects the _complexity_ of the execution + /// and the time it consumes. + /// - (optional) _tip_: if included in the transaction, it will be added on top. Only signed + /// transactions can have a tip. + fn compute_fee(len: usize, info: DispatchInfo, tip: BalanceOf) -> BalanceOf { + let len_fee = if info.pay_length_fee() { + let len = >::from(len as u32); + let base = T::TransactionBaseFee::get(); + let per_byte = T::TransactionByteFee::get(); + base.saturating_add(per_byte.saturating_mul(len)) + } else { + Zero::zero() + }; + + let weight_fee = { + // cap the weight to the maximum defined in runtime, otherwise it will be the `Bounded` + // maximum of its data type, which is not desired. + let capped_weight = info.weight.min(::MaximumBlockWeight::get()); + T::WeightToFee::convert(capped_weight) + }; + + // everything except for tip + let basic_fee = len_fee.saturating_add(weight_fee); + let fee_update = NextFeeMultiplier::get(); + let adjusted_fee = fee_update.saturated_multiply_accumulate(basic_fee); + + adjusted_fee.saturating_add(tip) + } +} + +#[cfg(feature = "std")] +impl rstd::fmt::Debug for ChargeTransactionPayment { + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + write!(f, "ChargeTransactionPayment<{:?}>", self.0) + } +} + +impl SignedExtension for ChargeTransactionPayment + where BalanceOf: Send + Sync +{ + type AccountId = T::AccountId; + type Call = T::Call; + type AdditionalSigned = (); + type Pre = (); + fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } + + fn validate( + &self, + who: &Self::AccountId, + _call: &Self::Call, + info: DispatchInfo, + len: usize, + ) -> TransactionValidity { + // pay any fees. + let fee = Self::compute_fee(len, info, self.0); + let imbalance = match T::Currency::withdraw( + who, + fee, + WithdrawReason::TransactionPayment, + ExistenceRequirement::KeepAlive, + ) { + Ok(imbalance) => imbalance, + Err(_) => return InvalidTransaction::Payment.into(), + }; + T::OnTransactionPayment::on_unbalanced(imbalance); + + let mut r = ValidTransaction::default(); + // NOTE: we probably want to maximize the _fee (of any type) per weight unit_ here, which + // will be a bit more than setting the priority to tip. For now, this is enough. + r.priority = fee.saturated_into::(); + Ok(r) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use support::{parameter_types, impl_outer_origin}; + use primitives::H256; + use sr_primitives::{ + Perbill, + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, + weights::DispatchClass, + }; + use rstd::cell::RefCell; + + const CALL: &::Call = &(); + + #[derive(Clone, PartialEq, Eq, Debug)] + pub struct Runtime; + + impl_outer_origin!{ + pub enum Origin for Runtime {} + } + + parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + } + + impl system::Trait for Runtime { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = (); + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + } + + parameter_types! { + pub const TransferFee: u64 = 0; + pub const CreationFee: u64 = 0; + pub const ExistentialDeposit: u64 = 0; + } + + impl balances::Trait for Runtime { + type Balance = u64; + type OnFreeBalanceZero = (); + type OnNewAccount = (); + type Event = (); + type TransferPayment = (); + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type TransferFee = TransferFee; + type CreationFee = CreationFee; + } + + thread_local! { + static TRANSACTION_BASE_FEE: RefCell = RefCell::new(0); + static TRANSACTION_BYTE_FEE: RefCell = RefCell::new(1); + static WEIGHT_TO_FEE: RefCell = RefCell::new(1); + } + + pub struct TransactionBaseFee; + impl Get for TransactionBaseFee { + fn get() -> u64 { TRANSACTION_BASE_FEE.with(|v| *v.borrow()) } + } + + pub struct TransactionByteFee; + impl Get for TransactionByteFee { + fn get() -> u64 { TRANSACTION_BYTE_FEE.with(|v| *v.borrow()) } + } + + pub struct WeightToFee(u64); + impl Convert for WeightToFee { + fn convert(t: Weight) -> u64 { + WEIGHT_TO_FEE.with(|v| *v.borrow() * (t as u64)) + } + } + + impl Trait for Runtime { + type Currency = balances::Module; + type OnTransactionPayment = (); + type TransactionBaseFee = TransactionBaseFee; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = WeightToFee; + type FeeMultiplierUpdate = (); + } + + type Balances = balances::Module; + + pub struct ExtBuilder { + balance_factor: u64, + base_fee: u64, + byte_fee: u64, + weight_to_fee: u64 + } + + impl Default for ExtBuilder { + fn default() -> Self { + Self { + balance_factor: 1, + base_fee: 0, + byte_fee: 1, + weight_to_fee: 1, + } + } + } + + impl ExtBuilder { + pub fn fees(mut self, base: u64, byte: u64, weight: u64) -> Self { + self.base_fee = base; + self.byte_fee = byte; + self.weight_to_fee = weight; + self + } + pub fn balance_factor(mut self, factor: u64) -> Self { + self.balance_factor = factor; + self + } + fn set_constants(&self) { + TRANSACTION_BASE_FEE.with(|v| *v.borrow_mut() = self.base_fee); + TRANSACTION_BYTE_FEE.with(|v| *v.borrow_mut() = self.byte_fee); + WEIGHT_TO_FEE.with(|v| *v.borrow_mut() = self.weight_to_fee); + } + pub fn build(self) -> runtime_io::TestExternalities { + self.set_constants(); + let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + balances::GenesisConfig:: { + balances: vec![ + (1, 10 * self.balance_factor), + (2, 20 * self.balance_factor), + (3, 30 * self.balance_factor), + (4, 40 * self.balance_factor), + (5, 50 * self.balance_factor), + (6, 60 * self.balance_factor) + ], + vesting: vec![], + }.assimilate_storage(&mut t).unwrap(); + t.into() + } + } + + /// create a transaction info struct from weight. Handy to avoid building the whole struct. + pub fn info_from_weight(w: Weight) -> DispatchInfo { + DispatchInfo { weight: w, ..Default::default() } + } + + #[test] + fn signed_extension_transaction_payment_work() { + ExtBuilder::default() + .balance_factor(10) // 100 + .fees(5, 1, 1) // 5 fixed, 1 per byte, 1 per weight + .build() + .execute_with(|| + { + let len = 10; + assert!( + ChargeTransactionPayment::::from(0) + .pre_dispatch(&1, CALL, info_from_weight(5), len) + .is_ok() + ); + assert_eq!(Balances::free_balance(&1), 100 - 5 - 5 - 10); + + assert!( + ChargeTransactionPayment::::from(5 /* tipped */) + .pre_dispatch(&2, CALL, info_from_weight(3), len) + .is_ok() + ); + assert_eq!(Balances::free_balance(&2), 200 - 5 - 10 - 3 - 5); + }); + } + + #[test] + fn signed_extension_transaction_payment_is_bounded() { + ExtBuilder::default() + .balance_factor(1000) + .fees(0, 0, 1) + .build() + .execute_with(|| + { + use sr_primitives::weights::Weight; + + // maximum weight possible + assert!( + ChargeTransactionPayment::::from(0) + .pre_dispatch(&1, CALL, info_from_weight(Weight::max_value()), 10) + .is_ok() + ); + // fee will be proportional to what is the actual maximum weight in the runtime. + assert_eq!( + Balances::free_balance(&1), + (10000 - ::MaximumBlockWeight::get()) as u64 + ); + }); + } + + #[test] + fn signed_extension_allows_free_transactions() { + ExtBuilder::default() + .fees(100, 1, 1) + .balance_factor(0) + .build() + .execute_with(|| + { + // 1 ain't have a penny. + assert_eq!(Balances::free_balance(&1), 0); + + // like a FreeOperational + let operational_transaction = DispatchInfo { + weight: 0, + class: DispatchClass::Operational + }; + let len = 100; + assert!( + ChargeTransactionPayment::::from(0) + .validate(&1, CALL, operational_transaction , len) + .is_ok() + ); + + // like a FreeNormal + let free_transaction = DispatchInfo { + weight: 0, + class: DispatchClass::Normal + }; + assert!( + ChargeTransactionPayment::::from(0) + .validate(&1, CALL, free_transaction , len) + .is_err() + ); + }); + } + + #[test] + fn signed_ext_length_fee_is_also_updated_per_congestion() { + ExtBuilder::default() + .fees(5, 1, 1) + .balance_factor(10) + .build() + .execute_with(|| + { + // all fees should be x1.5 + NextFeeMultiplier::put(Fixed64::from_rational(1, 2)); + let len = 10; + + assert!( + ChargeTransactionPayment::::from(10) // tipped + .pre_dispatch(&1, CALL, info_from_weight(3), len) + .is_ok() + ); + assert_eq!(Balances::free_balance(&1), 100 - 10 - (5 + 10 + 3) * 3 / 2); + }) + } +} + + diff --git a/srml/treasury/src/lib.rs b/srml/treasury/src/lib.rs index d5b3e6e55f..936e4bd93d 100644 --- a/srml/treasury/src/lib.rs +++ b/srml/treasury/src/lib.rs @@ -383,7 +383,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -395,23 +394,17 @@ mod tests { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 0; - pub const TransactionByteFee: u64 = 0; } impl balances::Trait for Test { type Balance = u64; type OnNewAccount = (); type OnFreeBalanceZero = (); type Event = (); - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = (); } parameter_types! { pub const ProposalBond: Permill = Permill::from_percent(5); diff --git a/srml/utility/src/lib.rs b/srml/utility/src/lib.rs index 52675d24fc..d69e260ff9 100644 --- a/srml/utility/src/lib.rs +++ b/srml/utility/src/lib.rs @@ -99,7 +99,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -111,23 +110,17 @@ mod tests { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 0; - pub const TransactionByteFee: u64 = 0; } impl balances::Trait for Test { type Balance = u64; type OnFreeBalanceZero = (); type OnNewAccount = (); type Event = (); - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = (); } impl Trait for Test { type Event = (); diff --git a/subkey/Cargo.toml b/subkey/Cargo.toml index d901b59d0b..e1c3ef64d2 100644 --- a/subkey/Cargo.toml +++ b/subkey/Cargo.toml @@ -19,6 +19,7 @@ hex-literal = "0.2.1" codec = { package = "parity-scale-codec", version = "1.0.0" } system = { package = "srml-system", path = "../srml/system" } balances = { package = "srml-balances", path = "../srml/balances" } +transaction-payment = { package = "srml-transaction-payment", path = "../srml/transaction-payment" } [features] bench = [] diff --git a/subkey/src/main.rs b/subkey/src/main.rs index 973502b3d6..2596513ab2 100644 --- a/subkey/src/main.rs +++ b/subkey/src/main.rs @@ -363,7 +363,7 @@ fn create_extrinsic( system::CheckEra::::from(Era::Immortal), system::CheckNonce::::from(i), system::CheckWeight::::new(), - balances::TakeFees::::from(f), + transaction_payment::ChargeTransactionPayment::::from(f), Default::default(), ) }; -- GitLab From d0e68bf17e84102d50daa29365e8af4a2fc42cbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 17 Oct 2019 23:35:41 +0200 Subject: [PATCH 224/275] Don't panic when we try to register 2 global loggers (#3840) --- core/cli/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/cli/src/lib.rs b/core/cli/src/lib.rs index c5af33b738..e891f90dc2 100644 --- a/core/cli/src/lib.rs +++ b/core/cli/src/lib.rs @@ -919,7 +919,9 @@ fn init_logger(pattern: &str) { writeln!(buf, "{}", output) }); - builder.init(); + if builder.try_init().is_err() { + info!("Not registering Substrate logger, as there is already a global logger registered!"); + } } fn kill_color(s: &str) -> String { -- GitLab From 734f1c3d066ba0c700d19aee5feb79869aae4228 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Fri, 18 Oct 2019 00:25:18 +0100 Subject: [PATCH 225/275] grandpa: don't expire next round messages (#3845) * grandpa: don't expire next round messages * grandpa: fix test * grandpa: first round in set is 1 * grandpa: fix test * grandpa: update doc --- .../src/communication/gossip.rs | 81 ++++++++++++++----- .../src/communication/tests.rs | 4 +- 2 files changed, 62 insertions(+), 23 deletions(-) diff --git a/core/finality-grandpa/src/communication/gossip.rs b/core/finality-grandpa/src/communication/gossip.rs index 831be7ad14..1f9d78c867 100644 --- a/core/finality-grandpa/src/communication/gossip.rs +++ b/core/finality-grandpa/src/communication/gossip.rs @@ -132,7 +132,7 @@ struct View { impl Default for View { fn default() -> Self { View { - round: Round(0), + round: Round(1), set_id: SetId(0), last_commit: None, } @@ -144,7 +144,7 @@ impl View { fn update_set(&mut self, set_id: SetId) { if set_id != self.set_id { self.set_id = set_id; - self.round = Round(0); + self.round = Round(1); } } @@ -194,21 +194,30 @@ impl KeepTopics { fn new() -> Self { KeepTopics { current_set: SetId(0), - rounds: VecDeque::with_capacity(KEEP_RECENT_ROUNDS + 1), + rounds: VecDeque::with_capacity(KEEP_RECENT_ROUNDS + 2), reverse_map: HashMap::new(), } } fn push(&mut self, round: Round, set_id: SetId) { self.current_set = std::cmp::max(self.current_set, set_id); - self.rounds.push_back((round, set_id)); - // the 1 is for the current round. - while self.rounds.len() > KEEP_RECENT_ROUNDS + 1 { + // under normal operation the given round is already tracked (since we + // track one round ahead). if we skip rounds (with a catch up) the given + // round topic might not be tracked yet. + if !self.rounds.contains(&(round, set_id)) { + self.rounds.push_back((round, set_id)); + } + + // we also accept messages for the next round + self.rounds.push_back((Round(round.0.saturating_add(1)), set_id)); + + // the 2 is for the current and next round. + while self.rounds.len() > KEEP_RECENT_ROUNDS + 2 { let _ = self.rounds.pop_front(); } - let mut map = HashMap::with_capacity(KEEP_RECENT_ROUNDS + 2); + let mut map = HashMap::with_capacity(KEEP_RECENT_ROUNDS + 3); map.insert(super::global_topic::(self.current_set.0), (None, self.current_set)); for &(round, set) in &self.rounds { @@ -554,7 +563,7 @@ impl Inner { { let local_view = match self.local_view { ref mut x @ None => x.get_or_insert(View { - round: Round(0), + round: Round(1), set_id, last_commit: None, }), @@ -566,7 +575,7 @@ impl Inner { }; local_view.update_set(set_id); - self.live_topics.push(Round(0), set_id); + self.live_topics.push(Round(1), set_id); self.authorities = authorities; } self.multicast_neighbor_packet() @@ -1466,11 +1475,11 @@ mod tests { let peer = PeerId::random(); val.note_set(SetId(set_id), vec![auth.clone()], |_, _| {}); - val.note_round(Round(0), |_, _| {}); + val.note_round(Round(1), |_, _| {}); let inner = val.inner.read(); let unknown_voter = inner.validate_round_message(&peer, &VoteOrPrecommitMessage { - round: Round(0), + round: Round(1), set_id: SetId(set_id), message: SignedMessage:: { message: grandpa::Message::Prevote(grandpa::Prevote { @@ -1483,7 +1492,7 @@ mod tests { }); let bad_sig = inner.validate_round_message(&peer, &VoteOrPrecommitMessage { - round: Round(0), + round: Round(1), set_id: SetId(set_id), message: SignedMessage:: { message: grandpa::Message::Prevote(grandpa::Prevote { @@ -1512,7 +1521,7 @@ mod tests { let peer = PeerId::random(); val.note_set(SetId(set_id), vec![auth.clone()], |_, _| {}); - val.note_round(Round(0), |_, _| {}); + val.note_round(Round(1), |_, _| {}); let validate_catch_up = || { let mut inner = val.inner.write(); @@ -1548,19 +1557,19 @@ mod tests { #[test] fn unanswerable_catch_up_requests_discarded() { - // create voter set state with round 1 completed + // create voter set state with round 2 completed let set_state: SharedVoterSetState = { let mut completed_rounds = voter_set_state().read().completed_rounds(); completed_rounds.push(environment::CompletedRound { - number: 1, + number: 2, state: grandpa::round::State::genesis(Default::default()), base: Default::default(), votes: Default::default(), }); let mut current_rounds = environment::CurrentRounds::new(); - current_rounds.insert(2, environment::HasVoted::No); + current_rounds.insert(3, environment::HasVoted::No); let set_state = environment::VoterSetState::::Live { completed_rounds, @@ -1581,7 +1590,7 @@ mod tests { let peer = PeerId::random(); val.note_set(SetId(set_id), vec![auth.clone()], |_, _| {}); - val.note_round(Round(2), |_, _| {}); + val.note_round(Round(3), |_, _| {}); // add the peer making the request to the validator, // otherwise it is discarded @@ -1597,7 +1606,7 @@ mod tests { &set_state, ); - // we're at round 2, a catch up request for round 10 is out of scope + // we're at round 3, a catch up request for round 10 is out of scope assert!(res.0.is_none()); assert_eq!(res.1, Action::Discard(cost::OUT_OF_SCOPE_MESSAGE)); @@ -1605,16 +1614,16 @@ mod tests { &peer, CatchUpRequestMessage { set_id: SetId(set_id), - round: Round(1), + round: Round(2), }, &set_state, ); - // a catch up request for round 1 should be answered successfully + // a catch up request for round 2 should be answered successfully match res.0.unwrap() { GossipMessage::CatchUp(catch_up) => { assert_eq!(catch_up.set_id, SetId(set_id)); - assert_eq!(catch_up.message.round_number, 1); + assert_eq!(catch_up.message.round_number, 2); assert_eq!(res.1, Action::Discard(cost::CATCH_UP_REPLY)); }, @@ -1849,4 +1858,34 @@ mod tests { _ => panic!("expected catch up message"), } } + + #[test] + fn doesnt_expire_next_round_messages() { + // NOTE: this is a regression test + let (val, _) = GossipValidator::::new( + config(), + voter_set_state(), + true, + ); + + // the validator starts at set id 1. + val.note_set(SetId(1), Vec::new(), |_, _| {}); + + // we are at round 10 + val.note_round(Round(9), |_, _| {}); + val.note_round(Round(10), |_, _| {}); + + let mut is_expired = val.message_expired(); + + // we accept messages from rounds 9, 10 and 11 + // therefore neither of those should be considered expired + for round in &[9, 10, 11] { + assert!( + !is_expired( + crate::communication::round_topic::(*round, 1), + &[], + ) + ) + } + } } diff --git a/core/finality-grandpa/src/communication/tests.rs b/core/finality-grandpa/src/communication/tests.rs index 6215e30b80..14e54511fb 100644 --- a/core/finality-grandpa/src/communication/tests.rs +++ b/core/finality-grandpa/src/communication/tests.rs @@ -217,7 +217,7 @@ fn good_commit_leads_to_relay() { let public = make_ids(&private[..]); let voter_set = Arc::new(public.iter().cloned().collect::>()); - let round = 0; + let round = 1; let set_id = 1; let commit = { @@ -332,7 +332,7 @@ fn bad_commit_leads_to_report() { let public = make_ids(&private[..]); let voter_set = Arc::new(public.iter().cloned().collect::>()); - let round = 0; + let round = 1; let set_id = 1; let commit = { -- GitLab From 48a5aaa921088ac8457a8c0510cedf88bace0ba2 Mon Sep 17 00:00:00 2001 From: kwingram25 Date: Fri, 18 Oct 2019 09:28:48 +0200 Subject: [PATCH 226/275] Use Bytes for contract rpc input_data (#3841) * Use Bytes for contract input_data * Update srml/contracts/rpc/src/lib.rs --- Cargo.lock | 1 + srml/contracts/rpc/Cargo.toml | 2 +- srml/contracts/rpc/src/lib.rs | 5 +++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c1aec02c00..bba0fc2f6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4052,6 +4052,7 @@ dependencies = [ "sr-primitives 2.0.0", "srml-contracts-rpc-runtime-api 2.0.0", "substrate-client 2.0.0", + "substrate-primitives 2.0.0", "substrate-rpc-primitives 2.0.0", ] diff --git a/srml/contracts/rpc/Cargo.toml b/srml/contracts/rpc/Cargo.toml index 8ebb714e20..90bf34bec1 100644 --- a/srml/contracts/rpc/Cargo.toml +++ b/srml/contracts/rpc/Cargo.toml @@ -10,8 +10,8 @@ codec = { package = "parity-scale-codec", version = "1.0.0" } jsonrpc-core = "13.2.0" jsonrpc-core-client = "13.2.0" jsonrpc-derive = "13.2.0" +primitives = { package = "substrate-primitives", path = "../../../core/primitives" } rpc-primitives = { package = "substrate-rpc-primitives", path = "../../../core/rpc/primitives" } serde = { version = "1.0.101", features = ["derive"] } sr-primitives = { path = "../../../core/sr-primitives" } srml-contracts-rpc-runtime-api = { path = "./runtime-api" } - diff --git a/srml/contracts/rpc/src/lib.rs b/srml/contracts/rpc/src/lib.rs index 7e17aaaf17..ba50bd12f0 100644 --- a/srml/contracts/rpc/src/lib.rs +++ b/srml/contracts/rpc/src/lib.rs @@ -23,6 +23,7 @@ use client::blockchain::HeaderBackend; use codec::Codec; use jsonrpc_core::{Error, ErrorCode, Result}; use jsonrpc_derive::rpc; +use primitives::Bytes; use sr_primitives::{ generic::BlockId, traits::{Block as BlockT, ProvideRuntimeApi}, @@ -41,7 +42,7 @@ pub struct CallRequest { dest: AccountId, value: Balance, gas_limit: number::NumberOrHex, - input_data: Vec, + input_data: Bytes, } /// Contracts RPC methods. @@ -111,7 +112,7 @@ where })?; let exec_result = api - .call(&at, origin, dest, value, gas_limit, input_data) + .call(&at, origin, dest, value, gas_limit, input_data.to_vec()) .map_err(|e| Error { code: ErrorCode::ServerError(RUNTIME_ERROR), message: "Runtime trapped while executing a contract.".into(), -- GitLab From c2761470f79b2cd18727c223e1b9e9456b393496 Mon Sep 17 00:00:00 2001 From: cheme Date: Fri, 18 Oct 2019 09:52:25 +0200 Subject: [PATCH 227/275] Code redundancy between ext implementation and testing. (#3830) * fix child_storage_hash * extract common implementation for ext and testing * cleaning impl. * replace ExtBasisMut by actual Ext * remove extbasis. * Update tests to use Ext from test externalities. * use Ext constructor for getting ext from TestExternalities. * Add missing extensions from ext. * fix wasmi test * Fix merge error. --- core/executor/src/lib.rs | 1 + core/executor/src/sandbox.rs | 10 ++ core/executor/src/wasmi_execution.rs | 70 ++++++---- core/state-machine/src/ext.rs | 28 ++-- core/state-machine/src/testing.rs | 176 +++---------------------- core/state-machine/src/trie_backend.rs | 2 +- core/test-runtime/src/system.rs | 6 +- node/executor/src/lib.rs | 89 ++++++++----- 8 files changed, 151 insertions(+), 231 deletions(-) diff --git a/core/executor/src/lib.rs b/core/executor/src/lib.rs index 582ebbca34..ac98388cd7 100644 --- a/core/executor/src/lib.rs +++ b/core/executor/src/lib.rs @@ -98,6 +98,7 @@ mod tests { #[test] fn call_in_interpreted_wasm_works() { let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let res = call_in_wasm( "test_empty_return", &[], diff --git a/core/executor/src/sandbox.rs b/core/executor/src/sandbox.rs index c4122274a9..e1e9e0db95 100644 --- a/core/executor/src/sandbox.rs +++ b/core/executor/src/sandbox.rs @@ -610,6 +610,7 @@ mod tests { #[test] fn sandbox_should_work() { let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -642,6 +643,7 @@ mod tests { #[test] fn sandbox_trap() { let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -663,6 +665,7 @@ mod tests { #[test] fn sandbox_should_trap_when_heap_exhausted() { let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -691,6 +694,7 @@ mod tests { #[test] fn start_called() { let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -729,6 +733,7 @@ mod tests { #[test] fn invoke_args() { let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -763,6 +768,7 @@ mod tests { #[test] fn return_val() { let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -785,6 +791,7 @@ mod tests { #[test] fn unlinkable_module() { let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -805,6 +812,7 @@ mod tests { #[test] fn corrupted_module() { let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; // Corrupted wasm file @@ -819,6 +827,7 @@ mod tests { #[test] fn start_fn_ok() { let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" @@ -842,6 +851,7 @@ mod tests { #[test] fn start_fn_traps() { let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" diff --git a/core/executor/src/wasmi_execution.rs b/core/executor/src/wasmi_execution.rs index ba7738a993..2b832b4906 100644 --- a/core/executor/src/wasmi_execution.rs +++ b/core/executor/src/wasmi_execution.rs @@ -681,6 +681,7 @@ mod tests { #[test] fn returning_should_work() { let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let output = call(&mut ext, 8, &test_code[..], "test_empty_return", &[]).unwrap(); @@ -690,6 +691,7 @@ mod tests { #[test] fn panicking_should_work() { let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let output = call(&mut ext, 8, &test_code[..], "test_panic", &[]); @@ -705,18 +707,22 @@ mod tests { #[test] fn storage_should_work() { let mut ext = TestExternalities::default(); - ext.set_storage(b"foo".to_vec(), b"bar".to_vec()); - let test_code = WASM_BINARY; - let output = call( - &mut ext, - 8, - &test_code[..], - "test_data_in", - &b"Hello world".to_vec().encode(), - ).unwrap(); + { + let mut ext = ext.ext(); + ext.set_storage(b"foo".to_vec(), b"bar".to_vec()); + let test_code = WASM_BINARY; + + let output = call( + &mut ext, + 8, + &test_code[..], + "test_data_in", + &b"Hello world".to_vec().encode(), + ).unwrap(); - assert_eq!(output, b"all ok!".to_vec().encode()); + assert_eq!(output, b"all ok!".to_vec().encode()); + } let expected = TestExternalities::new((map![ b"input".to_vec() => b"Hello world".to_vec(), @@ -729,23 +735,26 @@ mod tests { #[test] fn clear_prefix_should_work() { let mut ext = TestExternalities::default(); - ext.set_storage(b"aaa".to_vec(), b"1".to_vec()); - ext.set_storage(b"aab".to_vec(), b"2".to_vec()); - ext.set_storage(b"aba".to_vec(), b"3".to_vec()); - ext.set_storage(b"abb".to_vec(), b"4".to_vec()); - ext.set_storage(b"bbb".to_vec(), b"5".to_vec()); - let test_code = WASM_BINARY; - - // This will clear all entries which prefix is "ab". - let output = call( - &mut ext, - 8, - &test_code[..], - "test_clear_prefix", - &b"ab".to_vec().encode(), - ).unwrap(); + { + let mut ext = ext.ext(); + ext.set_storage(b"aaa".to_vec(), b"1".to_vec()); + ext.set_storage(b"aab".to_vec(), b"2".to_vec()); + ext.set_storage(b"aba".to_vec(), b"3".to_vec()); + ext.set_storage(b"abb".to_vec(), b"4".to_vec()); + ext.set_storage(b"bbb".to_vec(), b"5".to_vec()); + let test_code = WASM_BINARY; + + // This will clear all entries which prefix is "ab". + let output = call( + &mut ext, + 8, + &test_code[..], + "test_clear_prefix", + &b"ab".to_vec().encode(), + ).unwrap(); - assert_eq!(output, b"all ok!".to_vec().encode()); + assert_eq!(output, b"all ok!".to_vec().encode()); + } let expected = TestExternalities::new((map![ b"aaa".to_vec() => b"1".to_vec(), @@ -758,6 +767,7 @@ mod tests { #[test] fn blake2_256_should_work() { let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; assert_eq!( call(&mut ext, 8, &test_code[..], "test_blake2_256", &[0]).unwrap(), @@ -778,6 +788,7 @@ mod tests { #[test] fn blake2_128_should_work() { let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; assert_eq!( call(&mut ext, 8, &test_code[..], "test_blake2_128", &[0]).unwrap(), @@ -798,6 +809,7 @@ mod tests { #[test] fn twox_256_should_work() { let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; assert_eq!( call(&mut ext, 8, &test_code[..], "test_twox_256", &[0]).unwrap(), @@ -822,6 +834,7 @@ mod tests { #[test] fn twox_128_should_work() { let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; assert_eq!( call(&mut ext, 8, &test_code[..], "test_twox_128", &[0]).unwrap(), @@ -842,6 +855,7 @@ mod tests { #[test] fn ed25519_verify_should_work() { let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let key = ed25519::Pair::from_seed(&blake2_256(b"test")); let sig = key.sign(b"all ok!"); @@ -868,6 +882,7 @@ mod tests { #[test] fn sr25519_verify_should_work() { let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let test_code = WASM_BINARY; let key = sr25519::Pair::from_seed(&blake2_256(b"test")); let sig = key.sign(b"all ok!"); @@ -894,6 +909,7 @@ mod tests { #[test] fn ordered_trie_root_should_work() { let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); let trie_input = vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()]; let test_code = WASM_BINARY; assert_eq!( @@ -910,6 +926,7 @@ mod tests { let (offchain, state) = testing::TestOffchainExt::new(); ext.register_extension(OffchainExt::new(offchain)); let test_code = WASM_BINARY; + let mut ext = ext.ext(); assert_eq!( call(&mut ext, 8, &test_code[..], "test_offchain_local_storage", &[0]).unwrap(), true.encode(), @@ -937,6 +954,7 @@ mod tests { ); let test_code = WASM_BINARY; + let mut ext = ext.ext(); assert_eq!( call(&mut ext, 8, &test_code[..], "test_offchain_http", &[0]).unwrap(), true.encode(), diff --git a/core/state-machine/src/ext.rs b/core/state-machine/src/ext.rs index 3433aee92c..0e93302a95 100644 --- a/core/state-machine/src/ext.rs +++ b/core/state-machine/src/ext.rs @@ -32,7 +32,6 @@ use trie::{trie_types::Layout, MemoryDB, default_child_trie_root}; use externalities::Extensions; use std::{error, fmt, any::{Any, TypeId}}; - use log::{warn, trace}; const EXT_NOT_ALLOWED_TO_FAIL: &str = "Externalities not allowed to fail within runtime"; @@ -99,6 +98,7 @@ where T: 'a + ChangesTrieStorage, N: crate::changes_trie::BlockNumber, { + /// Create a new `Ext` from overlayed changes and read-only backend pub fn new( overlay: &'a mut OverlayedChanges, @@ -467,16 +467,22 @@ where } else { let storage_key = storage_key.as_ref(); - let delta = self.overlay.committed.children.get(storage_key) - .into_iter() - .flat_map(|map| map.iter().map(|(k, v)| (k.clone(), v.value.clone()))) - .chain(self.overlay.prospective.children.get(storage_key) - .into_iter() - .flat_map(|map| map.clone().into_iter().map(|(k, v)| (k.clone(), v.value.clone())))); - - let root = self.backend.child_storage_root(storage_key, delta).0; - - self.overlay.set_storage(storage_key.to_vec(), Some(root.to_vec())); + let (root, is_empty, _) = { + let delta = self.overlay.committed.children.get(storage_key) + .into_iter() + .flat_map(|map| map.clone().into_iter().map(|(k, v)| (k, v.value))) + .chain(self.overlay.prospective.children.get(storage_key) + .into_iter() + .flat_map(|map| map.clone().into_iter().map(|(k, v)| (k, v.value)))); + + self.backend.child_storage_root(storage_key, delta) + }; + + if is_empty { + self.overlay.set_storage(storage_key.into(), None); + } else { + self.overlay.set_storage(storage_key.into(), Some(root.clone())); + } trace!(target: "state-trace", "{:04x}: ChildRoot({}) {}", self.id, diff --git a/core/state-machine/src/testing.rs b/core/state-machine/src/testing.rs index ca89921ff0..16ff62020b 100644 --- a/core/state-machine/src/testing.rs +++ b/core/state-machine/src/testing.rs @@ -21,22 +21,20 @@ use hash_db::Hasher; use crate::{ backend::{InMemory, Backend}, OverlayedChanges, changes_trie::{ - build_changes_trie, InMemoryStorage as ChangesTrieInMemoryStorage, + InMemoryStorage as ChangesTrieInMemoryStorage, BlockNumber as ChangesTrieBlockNumber, }, + ext::Ext, }; use primitives::{ storage::{ - ChildStorageKey, well_known_keys::{CHANGES_TRIE_CONFIG, CODE, HEAP_PAGES, is_child_storage_key} }, - traits::Externalities, hash::H256, Blake2Hasher, + hash::H256, Blake2Hasher, }; use codec::Encode; use externalities::{Extensions, Extension}; -const EXT_NOT_ALLOWED_TO_FAIL: &str = "Externalities not allowed to fail within runtime"; - type StorageTuple = (HashMap, Vec>, HashMap, HashMap, Vec>>); /// Simple HashMap-based Externalities impl. @@ -48,6 +46,17 @@ pub struct TestExternalities=Blake2Hasher, N: ChangesTrieBlo } impl, N: ChangesTrieBlockNumber> TestExternalities { + + /// Get externalities implementation. + pub fn ext(&mut self) -> Ext, ChangesTrieInMemoryStorage> { + Ext::new( + &mut self.overlay, + &self.backend, + Some(&self.changes_trie_storage), + Some(&mut self.extensions), + ) + } + /// Create a new instance of `TestExternalities` with storage. pub fn new(storage: StorageTuple) -> Self { Self::new_with_code(&[], storage) @@ -118,7 +127,8 @@ impl, N: ChangesTrieBlockNumber> TestExternalities { /// /// Returns the result of the given closure. pub fn execute_with(&mut self, execute: impl FnOnce() -> R) -> R { - externalities::set_and_run_with_externalities(self, execute) + let mut ext = self.ext(); + externalities::set_and_run_with_externalities(&mut ext, execute) } } @@ -146,156 +156,6 @@ impl, N: ChangesTrieBlockNumber> From for Test } } -impl Externalities for TestExternalities where - H: Hasher, - N: ChangesTrieBlockNumber, -{ - fn storage(&self, key: &[u8]) -> Option> { - self.overlay.storage(key).map(|x| x.map(|x| x.to_vec())).unwrap_or_else(|| - self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL)) - } - - fn storage_hash(&self, key: &[u8]) -> Option { - self.storage(key).map(|v| H::hash(&v)) - } - - fn original_storage(&self, key: &[u8]) -> Option> { - self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL) - } - - fn original_storage_hash(&self, key: &[u8]) -> Option { - self.storage_hash(key) - } - - fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { - self.overlay - .child_storage(storage_key.as_ref(), key) - .map(|x| x.map(|x| x.to_vec())) - .unwrap_or_else(|| self.backend - .child_storage(storage_key.as_ref(), key) - .expect(EXT_NOT_ALLOWED_TO_FAIL) - ) - } - - fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { - self.child_storage(storage_key, key).map(|v| H::hash(&v)) - } - - fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { - self.backend - .child_storage(storage_key.as_ref(), key) - .map(|x| x.map(|x| x.to_vec())) - .expect(EXT_NOT_ALLOWED_TO_FAIL) - } - - fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { - self.child_storage_hash(storage_key, key) - } - - fn place_storage(&mut self, key: Vec, maybe_value: Option>) { - if is_child_storage_key(&key) { - panic!("Refuse to directly set child storage key"); - } - - self.overlay.set_storage(key, maybe_value); - } - - fn place_child_storage( - &mut self, - storage_key: ChildStorageKey, - key: Vec, - value: Option>, - ) { - self.overlay.set_child_storage(storage_key.into_owned(), key, value); - } - - fn kill_child_storage(&mut self, storage_key: ChildStorageKey) { - let backend = &self.backend; - let overlay = &mut self.overlay; - - overlay.clear_child_storage(storage_key.as_ref()); - backend.for_keys_in_child_storage(storage_key.as_ref(), |key| { - overlay.set_child_storage(storage_key.as_ref().to_vec(), key.to_vec(), None); - }); - } - - fn clear_prefix(&mut self, prefix: &[u8]) { - if is_child_storage_key(prefix) { - panic!("Refuse to directly clear prefix that is part of child storage key"); - } - - self.overlay.clear_prefix(prefix); - - let backend = &self.backend; - let overlay = &mut self.overlay; - backend.for_keys_with_prefix(prefix, |key| { - overlay.set_storage(key.to_vec(), None); - }); - } - - fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]) { - self.overlay.clear_child_prefix(storage_key.as_ref(), prefix); - - let backend = &self.backend; - let overlay = &mut self.overlay; - backend.for_child_keys_with_prefix(storage_key.as_ref(), prefix, |key| { - overlay.set_child_storage(storage_key.as_ref().to_vec(), key.to_vec(), None); - }); - } - - fn chain_id(&self) -> u64 { 42 } - - fn storage_root(&mut self) -> H256 { - let child_storage_keys = - self.overlay.prospective.children.keys() - .chain(self.overlay.committed.children.keys()); - - let child_delta_iter = child_storage_keys.map(|storage_key| - (storage_key.clone(), self.overlay.committed.children.get(storage_key) - .into_iter() - .flat_map(|map| map.iter().map(|(k, v)| (k.clone(), v.value.clone()))) - .chain(self.overlay.prospective.children.get(storage_key) - .into_iter() - .flat_map(|map| map.iter().map(|(k, v)| (k.clone(), v.value.clone())))))); - - - // compute and memoize - let delta = self.overlay.committed.top.iter().map(|(k, v)| (k.clone(), v.value.clone())) - .chain(self.overlay.prospective.top.iter().map(|(k, v)| (k.clone(), v.value.clone()))); - self.backend.full_storage_root(delta, child_delta_iter).0 - } - - fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { - let storage_key = storage_key.as_ref(); - - let (root, is_empty, _) = { - let delta = self.overlay.committed.children.get(storage_key) - .into_iter() - .flat_map(|map| map.clone().into_iter().map(|(k, v)| (k, v.value))) - .chain(self.overlay.prospective.children.get(storage_key) - .into_iter() - .flat_map(|map| map.clone().into_iter().map(|(k, v)| (k, v.value)))); - - self.backend.child_storage_root(storage_key, delta) - }; - if is_empty { - self.overlay.set_storage(storage_key.into(), None); - } else { - self.overlay.set_storage(storage_key.into(), Some(root.clone())); - } - root - } - - fn storage_changes_root(&mut self, parent: H256) -> Result, ()> { - Ok(build_changes_trie::<_, _, H, N>( - &self.backend, - Some(&self.changes_trie_storage), - &self.overlay, - parent, - )?.map(|(_, root, _)| root)) - } -} - impl externalities::ExtensionStore for TestExternalities where H: Hasher, N: ChangesTrieBlockNumber, @@ -308,12 +168,13 @@ impl externalities::ExtensionStore for TestExternalities where #[cfg(test)] mod tests { use super::*; - use primitives::{Blake2Hasher, H256}; + use primitives::traits::Externalities; use hex_literal::hex; #[test] fn commit_should_work() { let mut ext = TestExternalities::::default(); + let mut ext = ext.ext(); ext.set_storage(b"doe".to_vec(), b"reindeer".to_vec()); ext.set_storage(b"dog".to_vec(), b"puppy".to_vec()); ext.set_storage(b"dogglesworth".to_vec(), b"cat".to_vec()); @@ -324,6 +185,7 @@ mod tests { #[test] fn set_and_retrieve_code() { let mut ext = TestExternalities::::default(); + let mut ext = ext.ext(); let code = vec![1, 2, 3]; ext.set_storage(CODE.to_vec(), code.clone()); diff --git a/core/state-machine/src/trie_backend.rs b/core/state-machine/src/trie_backend.rs index ce5773c0b7..432ccf3e75 100644 --- a/core/state-machine/src/trie_backend.rs +++ b/core/state-machine/src/trie_backend.rs @@ -168,7 +168,7 @@ impl, H: Hasher> Backend for TrieBackend where let mut write_overlay = S::Overlay::default(); let mut root = match self.storage(storage_key) { - Ok(value) => value.unwrap_or(default_child_trie_root::>(storage_key)), + Ok(value) => value.unwrap_or(default_root.clone()), Err(e) => { warn!(target: "trie", "Failed to read child storage root: {}", e); default_root.clone() diff --git a/core/test-runtime/src/system.rs b/core/test-runtime/src/system.rs index d06bef5923..fc4de0ce4b 100644 --- a/core/test-runtime/src/system.rs +++ b/core/test-runtime/src/system.rs @@ -376,8 +376,9 @@ mod tests { #[test] fn block_import_works_wasm() { block_import_works(|b, ext| { + let mut ext = ext.ext(); executor().call::<_, NeverNativeValue, fn() -> _>( - ext, + &mut ext, "Core_execute_block", &b.encode(), false, @@ -468,8 +469,9 @@ mod tests { #[test] fn block_import_with_transaction_works_wasm() { block_import_with_transaction_works(|b, ext| { + let mut ext = ext.ext(); executor().call::<_, NeverNativeValue, fn() -> _>( - ext, + &mut ext, "Core_execute_block", &b.encode(), false, diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index 3558987716..3c97b3cd11 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -34,6 +34,7 @@ native_executor_instance!( #[cfg(test)] mod tests { + use substrate_executor::error::Result; use super::Executor; use {balances, contracts, indices, system, timestamp}; use codec::{Encode, Decode, Joiner}; @@ -122,6 +123,26 @@ mod tests { ext.place_storage(well_known_keys::HEAP_PAGES.to_vec(), Some(heap_pages.encode())); } + fn executor_call< + R:Decode + Encode + PartialEq, + NC: FnOnce() -> std::result::Result + std::panic::UnwindSafe + >( + t: &mut TestExternalities, + method: &str, + data: &[u8], + use_native: bool, + native_call: Option, + ) -> (Result>, bool) { + let mut t = t.ext(); + executor().call::<_, R, NC>( + &mut t, + method, + data, + use_native, + native_call, + ) + } + #[test] fn panic_execution_with_foreign_code_gives_error() { let mut t = TestExternalities::::new_with_code(BLOATY_CODE, (map![ @@ -139,7 +160,7 @@ mod tests { } ], map![])); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + let r = executor_call:: _>( &mut t, "Core_initialize_block", &vec![].and(&from_block_number(1u32)), @@ -147,7 +168,7 @@ mod tests { None, ).0; assert!(r.is_ok()); - let v = executor().call::<_, NeverNativeValue, fn() -> _>( + let v = executor_call:: _>( &mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), @@ -175,7 +196,7 @@ mod tests { } ], map![])); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + let r = executor_call:: _>( &mut t, "Core_initialize_block", &vec![].and(&from_block_number(1u32)), @@ -183,7 +204,7 @@ mod tests { None, ).0; assert!(r.is_ok()); - let v = executor().call::<_, NeverNativeValue, fn() -> _>( + let v = executor_call:: _>( &mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), @@ -207,7 +228,7 @@ mod tests { >::hashed_key_for(0) => vec![0u8; 32] ], map![])); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + let r = executor_call:: _>( &mut t, "Core_initialize_block", &vec![].and(&from_block_number(1u32)), @@ -218,7 +239,7 @@ mod tests { let fm = t.execute_with(TransactionPayment::next_fee_multiplier); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + let r = executor_call:: _>( &mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), @@ -246,7 +267,7 @@ mod tests { >::hashed_key_for(0) => vec![0u8; 32] ], map![])); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + let r = executor_call:: _>( &mut t, "Core_initialize_block", &vec![].and(&from_block_number(1u32)), @@ -257,7 +278,7 @@ mod tests { let fm = t.execute_with(TransactionPayment::next_fee_multiplier); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + let r = executor_call:: _>( &mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), @@ -307,7 +328,7 @@ mod tests { }; // execute the block to get the real header. - executor().call::<_, NeverNativeValue, fn() -> _>( + executor_call:: _>( env, "Core_initialize_block", &header.encode(), @@ -316,7 +337,7 @@ mod tests { ).0.unwrap(); for i in extrinsics.iter() { - executor().call::<_, NeverNativeValue, fn() -> _>( + executor_call:: _>( env, "BlockBuilder_apply_extrinsic", &i.encode(), @@ -325,7 +346,7 @@ mod tests { ).0.unwrap(); } - let header = match executor().call::<_, NeverNativeValue, fn() -> _>( + let header = match executor_call:: _>( env, "BlockBuilder_finalize_block", &[0u8;0], @@ -432,7 +453,7 @@ mod tests { let mut alice_last_known_balance: Balance = Default::default(); let mut fm = t.execute_with(TransactionPayment::next_fee_multiplier); - executor().call::<_, NeverNativeValue, fn() -> _>( + executor_call:: _>( &mut t, "Core_execute_block", &block1.0, @@ -471,7 +492,7 @@ mod tests { fm = t.execute_with(TransactionPayment::next_fee_multiplier); - executor().call::<_, NeverNativeValue, fn() -> _>( + executor_call:: _>( &mut t, "Core_execute_block", &block2.0, @@ -544,7 +565,7 @@ mod tests { let mut alice_last_known_balance: Balance = Default::default(); let mut fm = t.execute_with(TransactionPayment::next_fee_multiplier); - executor().call::<_, NeverNativeValue, fn() -> _>( + executor_call:: _>( &mut t, "Core_execute_block", &block1.0, @@ -560,7 +581,7 @@ mod tests { fm = t.execute_with(TransactionPayment::next_fee_multiplier); - executor().call::<_, NeverNativeValue, fn() -> _>( + executor_call:: _>( &mut t, "Core_execute_block", &block2.0, @@ -720,7 +741,7 @@ mod tests { let mut t = new_test_ext(COMPACT_CODE, false); - executor().call::<_, NeverNativeValue, fn() -> _>( + executor_call:: _>( &mut t, "Core_execute_block", &b.0, @@ -744,9 +765,9 @@ mod tests { fn wasm_big_block_import_fails() { let mut t = new_test_ext(COMPACT_CODE, false); - set_heap_pages(&mut t, 4); + set_heap_pages(&mut t.ext(), 4); - let result = executor().call::<_, NeverNativeValue, fn() -> _>( + let result = executor_call:: _>( &mut t, "Core_execute_block", &block_with_size(42, 0, 120_000).0, @@ -760,7 +781,7 @@ mod tests { fn native_big_block_import_succeeds() { let mut t = new_test_ext(COMPACT_CODE, false); - executor().call::<_, NeverNativeValue, fn() -> _>( + executor_call:: _>( &mut t, "Core_execute_block", &block_with_size(42, 0, 120_000).0, @@ -774,7 +795,7 @@ mod tests { let mut t = new_test_ext(COMPACT_CODE, false); assert!( - executor().call::<_, NeverNativeValue, fn() -> _>( + executor_call:: _>( &mut t, "Core_execute_block", &block_with_size(42, 0, 120_000).0, @@ -797,7 +818,7 @@ mod tests { >::hashed_key_for(0) => vec![0u8; 32] ], map![])); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + let r = executor_call:: _>( &mut t, "Core_initialize_block", &vec![].and(&from_block_number(1u32)), @@ -805,7 +826,7 @@ mod tests { None, ).0; assert!(r.is_ok()); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + let r = executor_call:: _>( &mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), @@ -829,7 +850,7 @@ mod tests { >::hashed_key_for(0) => vec![0u8; 32] ], map![])); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + let r = executor_call:: _>( &mut t, "Core_initialize_block", &vec![].and(&from_block_number(1u32)), @@ -838,7 +859,7 @@ mod tests { ).0; assert!(r.is_ok()); let fm = t.execute_with(TransactionPayment::next_fee_multiplier); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + let r = executor_call:: _>( &mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), @@ -863,7 +884,7 @@ mod tests { let block = Block::decode(&mut &block_data[..]).unwrap(); let mut t = new_test_ext(COMPACT_CODE, true); - executor().call::<_, NeverNativeValue, fn() -> _>( + executor_call:: _>( &mut t, "Core_execute_block", &block.encode(), @@ -871,7 +892,7 @@ mod tests { None, ).0.unwrap(); - assert!(t.storage_changes_root(GENESIS_HASH.into()).unwrap().is_some()); + assert!(t.ext().storage_changes_root(GENESIS_HASH.into()).unwrap().is_some()); } #[test] @@ -879,7 +900,7 @@ mod tests { let block1 = changes_trie_block(); let mut t = new_test_ext(COMPACT_CODE, true); - executor().call::<_, NeverNativeValue, fn() -> _>( + executor_call:: _>( &mut t, "Core_execute_block", &block1.0, @@ -887,7 +908,7 @@ mod tests { None, ).0.unwrap(); - assert!(t.storage_changes_root(GENESIS_HASH.into()).unwrap().is_some()); + assert!(t.ext().storage_changes_root(GENESIS_HASH.into()).unwrap().is_some()); } #[test] @@ -953,7 +974,7 @@ mod tests { println!("++ Block 1 size: {} / Block 2 size {}", block1.0.encode().len(), block2.0.encode().len()); // execute a big block. - executor().call::<_, NeverNativeValue, fn() -> _>( + executor_call:: _>( &mut t, "Core_execute_block", &block1.0, @@ -970,7 +991,7 @@ mod tests { }); // execute a big block. - executor().call::<_, NeverNativeValue, fn() -> _>( + executor_call:: _>( &mut t, "Core_execute_block", &block2.0, @@ -1015,7 +1036,7 @@ mod tests { function: Call::Balances(default_transfer_call()), }); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + let r = executor_call:: _>( &mut t, "Core_initialize_block", &vec![].and(&from_block_number(1u32)), @@ -1024,7 +1045,7 @@ mod tests { ).0; assert!(r.is_ok()); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + let r = executor_call:: _>( &mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt.clone()), @@ -1109,7 +1130,7 @@ mod tests { len / 1024 / 1024, ); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + let r = executor_call:: _>( &mut t, "Core_execute_block", &block.0, @@ -1173,7 +1194,7 @@ mod tests { len / 1024 / 1024, ); - let r = executor().call::<_, NeverNativeValue, fn() -> _>( + let r = executor_call:: _>( &mut t, "Core_execute_block", &block.0, -- GitLab From 71c7b680790e634327b0c826c058a7ac30509aa9 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Fri, 18 Oct 2019 12:41:57 +0200 Subject: [PATCH 228/275] Update CONTRIBUTING.adoc (#3842) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update CONTRIBUTING.adoc * fix typos * Update CONTRIBUTING.adoc Co-Authored-By: André Silva --- CONTRIBUTING.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.adoc b/CONTRIBUTING.adoc index 1de4820a11..817e1d7489 100644 --- a/CONTRIBUTING.adoc +++ b/CONTRIBUTING.adoc @@ -26,6 +26,7 @@ Merging pull requests once CI is successful: - it is an urgent fix with no large change to logic, then it may be merged after a non-author contributor has approved the review once CI is complete. . Once a PR is ready for review please add the https://github.com/paritytech/substrate/pulls?q=is%3Apr+is%3Aopen+label%3AA0-pleasereview[`pleasereview`] label. Generally PRs should sit with this label for 48 hours in order to garner feedback. It may be merged before if all relevant parties had a look at it. +. If the first review is not an approval, swap `A0-pleasereview` to any label `[A3, A7]` to indicate that the PR has received some feedback, but needs further work. For example. https://github.com/paritytech/substrate/labels/A3-inprogress[`A3-inprogress`] is a general indicator that the PR is work in progress and https://github.com/paritytech/substrate/labels/A4-gotissues[`A4-gotissues`] means that it has significant problems that need fixing. Once the work is done, change the label back to `A0-pleasereview`. You might end up swapping a few times back and forth to climb up the A label group. Once a PR is https://github.com/paritytech/substrate/labels/A8-looksgood[`A8-looksgood`], it is ready to merge. . PRs that break the external API must be tagged with https://github.com/paritytech/substrate/labels/B2-breaksapi[`breaksapi`], when it changes the SRML or consensus of running system with https://github.com/paritytech/substrate/labels/B3-breaksconsensus[`breaksconsensus`] . No PR should be merged until all reviews' comments are addressed. -- GitLab From a2071c47c7f923407cc4ea0091db9eb3b5a42fbe Mon Sep 17 00:00:00 2001 From: Xiliang Chen Date: Fri, 18 Oct 2019 23:58:05 +1300 Subject: [PATCH 229/275] remove unused file (#3851) --- srml/council/src/lib.rs | 279 ---------------------------------------- 1 file changed, 279 deletions(-) delete mode 100644 srml/council/src/lib.rs diff --git a/srml/council/src/lib.rs b/srml/council/src/lib.rs deleted file mode 100644 index 195202c873..0000000000 --- a/srml/council/src/lib.rs +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright 2017-2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Council system: Handles the voting in and maintenance of council members. - -#![cfg_attr(not(feature = "std"), no_std)] -#![recursion_limit="128"] - -pub mod motions; -pub mod seats; - -pub use crate::seats::{Trait, Module, RawEvent, Event, VoteIndex}; - -/// Trait for type that can handle incremental changes to a set of account IDs. -pub trait OnMembersChanged { - /// A number of members `new` just joined the set and replaced some `old` ones. - fn on_members_changed(new: &[AccountId], old: &[AccountId]); -} - -impl OnMembersChanged for () { - fn on_members_changed(_new: &[T], _old: &[T]) {} -} - -#[cfg(test)] -mod tests { - // These re-exports are here for a reason, edit with care - pub use super::*; - use support::{impl_outer_origin, impl_outer_event, impl_outer_dispatch, parameter_types}; - use support::traits::Get; - pub use primitives::{H256, Blake2Hasher, u32_trait::{_1, _2, _3, _4}}; - pub use sr_primitives::traits::{BlakeTwo256, IdentityLookup}; - pub use sr_primitives::testing::{Digest, DigestItem, Header}; - pub use sr_primitives::Perbill; - pub use {seats, motions}; - use std::cell::RefCell; - - impl_outer_origin! { - pub enum Origin for Test { - motions - } - } - - impl_outer_event! { - pub enum Event for Test { - balances, democracy, seats, motions, - } - } - - impl_outer_dispatch! { - pub enum Call for Test where origin: Origin { - type Error = Error; - - balances::Balances, - democracy::Democracy, - } - } - - thread_local! { - static VOTER_BOND: RefCell = RefCell::new(0); - static VOTING_FEE: RefCell = RefCell::new(0); - static PRESENT_SLASH_PER_VOTER: RefCell = RefCell::new(0); - static DECAY_RATIO: RefCell = RefCell::new(0); - } - - pub struct VotingBond; - impl Get for VotingBond { - fn get() -> u64 { VOTER_BOND.with(|v| *v.borrow()) } - } - - pub struct VotingFee; - impl Get for VotingFee { - fn get() -> u64 { VOTING_FEE.with(|v| *v.borrow()) } - } - - pub struct PresentSlashPerVoter; - impl Get for PresentSlashPerVoter { - fn get() -> u64 { PRESENT_SLASH_PER_VOTER.with(|v| *v.borrow()) } - } - - pub struct DecayRatio; - impl Get for DecayRatio { - fn get() -> u32 { DECAY_RATIO.with(|v| *v.borrow()) } - } - - // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. - #[derive(Clone, Eq, PartialEq, Debug)] - pub struct Test; - parameter_types! { - pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); - } - impl system::Trait for Test { - type Origin = Origin; - type Index = u64; - type BlockNumber = u64; - type Call = (); - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; - type Header = Header; - type Event = Event; - type Error = Error; - type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; - type Version = (); - } - parameter_types! { - pub const ExistentialDeposit: u64 = 0; - pub const TransferFee: u64 = 0; - pub const CreationFee: u64 = 0; - } - impl balances::Trait for Test { - type Balance = u64; - type OnNewAccount = (); - type OnFreeBalanceZero = (); - type Event = Event; - type TransferPayment = (); - type DustRemoval = (); - type Error = Error; - type ExistentialDeposit = ExistentialDeposit; - type TransferFee = TransferFee; - type CreationFee = CreationFee; - } - parameter_types! { - pub const LaunchPeriod: u64 = 1; - pub const VotingPeriod: u64 = 3; - pub const MinimumDeposit: u64 = 1; - pub const EnactmentPeriod: u64 = 0; - pub const CooloffPeriod: u64 = 2; - } - impl democracy::Trait for Test { - type Proposal = Call; - type Event = Event; - type Currency = balances::Module; - type EnactmentPeriod = EnactmentPeriod; - type LaunchPeriod = LaunchPeriod; - type EmergencyVotingPeriod = VotingPeriod; - type VotingPeriod = VotingPeriod; - type MinimumDeposit = MinimumDeposit; - type ExternalOrigin = motions::EnsureProportionAtLeast<_1, _2, u64>; - type ExternalMajorityOrigin = motions::EnsureProportionAtLeast<_2, _3, u64>; - type EmergencyOrigin = motions::EnsureProportionAtLeast<_1, _1, u64>; - type CancellationOrigin = motions::EnsureProportionAtLeast<_2, _3, u64>; - type VetoOrigin = motions::EnsureMember; - type CooloffPeriod = CooloffPeriod; - } - parameter_types! { - pub const CandidacyBond: u64 = 3; - pub const CarryCount: u32 = 2; - pub const InactiveGracePeriod: u32 = 1; - pub const CouncilVotingPeriod: u64 = 4; - } - impl seats::Trait for Test { - type Event = Event; - type BadPresentation = (); - type BadReaper = (); - type BadVoterIndex = (); - type LoserCandidate = (); - type OnMembersChanged = CouncilMotions; - type CandidacyBond = CandidacyBond; - type VotingBond = VotingBond; - type VotingFee = VotingFee; - type PresentSlashPerVoter = PresentSlashPerVoter; - type CarryCount = CarryCount; - type InactiveGracePeriod = InactiveGracePeriod; - type CouncilVotingPeriod = CouncilVotingPeriod; - type DecayRatio = DecayRatio; - } - impl motions::Trait for Test { - type Origin = Origin; - type Proposal = Call; - type Event = Event; - } - - pub struct ExtBuilder { - balance_factor: u64, - decay_ratio: u32, - voting_fee: u64, - voter_bond: u64, - bad_presentation_punishment: u64, - with_council: bool, - } - - impl Default for ExtBuilder { - fn default() -> Self { - Self { - balance_factor: 1, - decay_ratio: 24, - voting_fee: 0, - voter_bond: 0, - bad_presentation_punishment: 1, - with_council: false, - } - } - } - - impl ExtBuilder { - pub fn with_council(mut self, council: bool) -> Self { - self.with_council = council; - self - } - pub fn balance_factor(mut self, factor: u64) -> Self { - self.balance_factor = factor; - self - } - pub fn decay_ratio(mut self, ratio: u32) -> Self { - self.decay_ratio = ratio; - self - } - pub fn voting_fee(mut self, fee: u64) -> Self { - self.voting_fee = fee; - self - } - pub fn bad_presentation_punishment(mut self, fee: u64) -> Self { - self.bad_presentation_punishment = fee; - self - } - pub fn voter_bond(mut self, fee: u64) -> Self { - self.voter_bond = fee; - self - } - pub fn set_associated_consts(&self) { - VOTER_BOND.with(|v| *v.borrow_mut() = self.voter_bond); - VOTING_FEE.with(|v| *v.borrow_mut() = self.voting_fee); - PRESENT_SLASH_PER_VOTER.with(|v| *v.borrow_mut() = self.bad_presentation_punishment); - DECAY_RATIO.with(|v| *v.borrow_mut() = self.decay_ratio); - } - pub fn build(self) -> runtime_io::TestExternalities { - self.set_associated_consts(); - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); - balances::GenesisConfig::{ - balances: vec![ - (1, 10 * self.balance_factor), - (2, 20 * self.balance_factor), - (3, 30 * self.balance_factor), - (4, 40 * self.balance_factor), - (5, 50 * self.balance_factor), - (6, 60 * self.balance_factor) - ], - vesting: vec![], - }.assimilate_storage(&mut t).unwrap(); - seats::GenesisConfig:: { - active_council: if self.with_council { vec![ - (1, 10), - (2, 10), - (3, 10) - ] } else { vec![] }, - desired_seats: 2, - presentation_duration: 2, - term_duration: 5, - }.assimilate_storage(&mut t).unwrap(); - runtime_io::TestExternalities::new(t) - } - } - - pub type System = system::Module; - pub type Balances = balances::Module; - pub type Democracy = democracy::Module; - pub type Council = seats::Module; - pub type CouncilMotions = motions::Module; -} -- GitLab From 5e406b1c18babf2dd102f7f587b7959b277b6496 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Fri, 18 Oct 2019 19:58:31 +0900 Subject: [PATCH 230/275] Switch node template to use AuRa (#3790) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Stuck on service * Make service compile * Remove Grandpa dependency * Update node-template/runtime/Cargo.toml Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Fix build * Update crypto import * Update node-template/src/service.rs Co-Authored-By: André Silva * Update node-template/src/service.rs Co-Authored-By: André Silva * Update node-template/src/service.rs Co-Authored-By: André Silva * Update node-template/src/service.rs Co-Authored-By: André Silva * Update node-template/runtime/src/lib.rs Co-Authored-By: André Silva * Fix macro dependency * Trying to add grandpa back * Update node-template/src/chain_spec.rs Co-Authored-By: André Silva * Update node-template/src/chain_spec.rs Co-Authored-By: André Silva * Update node-template/src/chain_spec.rs Co-Authored-By: André Silva * Update node-template/src/service.rs Co-Authored-By: André Silva * Update node-template/src/service.rs Co-Authored-By: André Silva * Unused import * Use grandpa block import --- Cargo.lock | 8 ++-- node-template/Cargo.toml | 4 +- node-template/README.md | 14 ++++-- node-template/runtime/Cargo.toml | 12 ++--- node-template/runtime/src/lib.rs | 73 +++++++++---------------------- node-template/src/chain_spec.rs | 22 +++++----- node-template/src/cli.rs | 1 + node-template/src/service.rs | 75 ++++++++++++-------------------- 8 files changed, 83 insertions(+), 126 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bba0fc2f6f..8cf8b42bd4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2519,8 +2519,8 @@ dependencies = [ "substrate-basic-authorship 2.0.0", "substrate-cli 2.0.0", "substrate-client 2.0.0", - "substrate-consensus-babe 2.0.0", - "substrate-consensus-babe-primitives 2.0.0", + "substrate-consensus-aura 2.0.0", + "substrate-consensus-aura-primitives 2.0.0", "substrate-executor 2.0.0", "substrate-finality-grandpa 2.0.0", "substrate-finality-grandpa-primitives 2.0.0", @@ -2545,7 +2545,7 @@ dependencies = [ "sr-primitives 2.0.0", "sr-std 2.0.0", "sr-version 2.0.0", - "srml-babe 2.0.0", + "srml-aura 2.0.0", "srml-balances 2.0.0", "srml-executive 2.0.0", "srml-grandpa 2.0.0", @@ -2557,7 +2557,7 @@ dependencies = [ "srml-timestamp 2.0.0", "srml-transaction-payment 2.0.0", "substrate-client 2.0.0", - "substrate-consensus-babe-primitives 2.0.0", + "substrate-consensus-aura-primitives 2.0.0", "substrate-offchain-primitives 2.0.0", "substrate-primitives 2.0.0", "substrate-session 2.0.0", diff --git a/node-template/Cargo.toml b/node-template/Cargo.toml index 2aa305486c..2c01655dc2 100644 --- a/node-template/Cargo.toml +++ b/node-template/Cargo.toml @@ -27,8 +27,8 @@ substrate-service = { path = "../core/service" } inherents = { package = "substrate-inherents", path = "../core/inherents" } transaction-pool = { package = "substrate-transaction-pool", path = "../core/transaction-pool" } network = { package = "substrate-network", path = "../core/network" } -babe = { package = "substrate-consensus-babe", path = "../core/consensus/babe" } -babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../core/consensus/babe/primitives" } +aura = { package = "substrate-consensus-aura", path = "../core/consensus/aura" } +aura-primitives = { package = "substrate-consensus-aura-primitives", path = "../core/consensus/aura/primitives" } grandpa = { package = "substrate-finality-grandpa", path = "../core/finality-grandpa" } grandpa-primitives = { package = "substrate-finality-grandpa-primitives", path = "../core/finality-grandpa/primitives" } substrate-client = { path = "../core/client" } diff --git a/node-template/README.md b/node-template/README.md index 5a59652c1b..c411dbeef5 100644 --- a/node-template/README.md +++ b/node-template/README.md @@ -10,7 +10,7 @@ Install Rust: curl https://sh.rustup.rs -sSf | sh ``` -Install required tools: +Initialize your Wasm Build environment: ```bash ./scripts/init.sh @@ -19,17 +19,23 @@ Install required tools: Build Wasm and native code: ```bash -cargo build +cargo build --release ``` ## Run ### Single node development chain -You can start a development chain with: +Purge any existing developer chain state: ```bash -cargo run -- --dev +./target/release/node-template purge-chain --dev +``` + +Start a development chain with: + +```bash +./target/release/node-template --dev ``` Detailed logs may be shown by running the node with the following environment variables set: `RUST_LOG=debug RUST_BACKTRACE=1 cargo run -- --dev`. diff --git a/node-template/runtime/Cargo.toml b/node-template/runtime/Cargo.toml index 96484c16ae..df9dd9c77f 100644 --- a/node-template/runtime/Cargo.toml +++ b/node-template/runtime/Cargo.toml @@ -15,11 +15,11 @@ support = { package = "srml-support", path = "../../srml/support", default_featu primitives = { package = "substrate-primitives", path = "../../core/primitives", default_features = false } substrate-session = { path = "../../core/session", default-features = false } balances = { package = "srml-balances", path = "../../srml/balances", default_features = false } -babe = { package = "srml-babe", path = "../../srml/babe", default-features = false } -babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../core/consensus/babe/primitives", default-features = false } +aura = { package = "srml-aura", path = "../../srml/aura", default_features = false } +aura-primitives = { package = "substrate-consensus-aura-primitives", path = "../../core/consensus/aura/primitives", default_features = false } +grandpa = { package = "srml-grandpa", path = "../../srml/grandpa", default_features = false } executive = { package = "srml-executive", path = "../../srml/executive", default_features = false } indices = { package = "srml-indices", path = "../../srml/indices", default_features = false } -grandpa = { package = "srml-grandpa", path = "../../srml/grandpa", default-features = false } randomness-collective-flip = { package = "srml-randomness-collective-flip", path = "../../srml/randomness-collective-flip", default_features = false } system = { package = "srml-system", path = "../../srml/system", default_features = false } timestamp = { package = "srml-timestamp", path = "../../srml/timestamp", default_features = false } @@ -41,11 +41,11 @@ std = [ "runtime-io/std", "support/std", "balances/std", - "babe/std", - "babe-primitives/std", + "aura/std", + "aura-primitives/std", + 'grandpa/std', "executive/std", "indices/std", - "grandpa/std", "primitives/std", "sr-primitives/std", "randomness-collective-flip/std", diff --git a/node-template/runtime/src/lib.rs b/node-template/runtime/src/lib.rs index da49ad4474..acc5143ffe 100644 --- a/node-template/runtime/src/lib.rs +++ b/node-template/runtime/src/lib.rs @@ -16,13 +16,13 @@ use sr_primitives::{ }; use sr_primitives::traits::{NumberFor, BlakeTwo256, Block as BlockT, StaticLookup, Verify, ConvertInto}; use sr_primitives::weights::Weight; -use babe::{AuthorityId as BabeId}; -use grandpa::{AuthorityId as GrandpaId, AuthorityWeight as GrandpaWeight}; -use grandpa::fg_primitives; use client::{ block_builder::api::{CheckInherentsResult, InherentData, self as block_builder_api}, runtime_api as client_api, impl_runtime_apis }; +use aura_primitives::sr25519::AuthorityId as AuraId; +use grandpa::{AuthorityId as GrandpaId, AuthorityWeight as GrandpaWeight}; +use grandpa::fg_primitives; use version::RuntimeVersion; #[cfg(feature = "std")] use version::NativeVersion; @@ -80,14 +80,12 @@ pub mod opaque { /// Opaque block identifier type. pub type BlockId = generic::BlockId; - pub type SessionHandlers = (Grandpa, Babe); - impl_opaque_keys! { pub struct SessionKeys { + #[id(key_types::AURA)] + pub aura: AuraId, #[id(key_types::GRANDPA)] pub grandpa: GrandpaId, - #[id(key_types::BABE)] - pub babe: BabeId, } } } @@ -102,20 +100,6 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { apis: RUNTIME_API_VERSIONS, }; -/// Constants for Babe. - -/// Since BABE is probabilistic this is the average expected block time that -/// we are targetting. Blocks will be produced at a minimum duration defined -/// by `SLOT_DURATION`, but some slots will not be allocated to any -/// authority and hence no block will be produced. We expect to have this -/// block time on average following the defined slot duration and the value -/// of `c` configured for BABE (where `1 - c` represents the probability of -/// a slot being empty). -/// This value is only used indirectly to define the unit constants below -/// that are expressed in blocks. The rest of the code should use -/// `SLOT_DURATION` instead (like the timestamp module for calculating the -/// minimum period). -/// pub const MILLISECS_PER_BLOCK: u64 = 6000; pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; @@ -180,15 +164,8 @@ impl system::Trait for Runtime { type Version = Version; } -parameter_types! { - pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64; - pub const ExpectedBlockTime: u64 = MILLISECS_PER_BLOCK; -} - -impl babe::Trait for Runtime { - type EpochDuration = EpochDuration; - type ExpectedBlockTime = ExpectedBlockTime; - type EpochChangeTrigger = babe::SameAuthoritiesForever; +impl aura::Trait for Runtime { + type AuthorityId = AuraId; } impl grandpa::Trait for Runtime { @@ -214,7 +191,7 @@ parameter_types! { impl timestamp::Trait for Runtime { /// A timestamp: milliseconds since the unix epoch. type Moment = u64; - type OnTimestampSet = Babe; + type OnTimestampSet = Aura; type MinimumPeriod = MinimumPeriod; } @@ -272,7 +249,7 @@ construct_runtime!( { System: system::{Module, Call, Storage, Config, Event}, Timestamp: timestamp::{Module, Call, Storage, Inherent}, - Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)}, + Aura: aura::{Module, Config, Inherent(Timestamp)}, Grandpa: grandpa::{Module, Call, Storage, Config, Event}, Indices: indices::{default, Config}, Balances: balances::{default, Error}, @@ -365,27 +342,13 @@ impl_runtime_apis! { } } - impl fg_primitives::GrandpaApi for Runtime { - fn grandpa_authorities() -> Vec<(GrandpaId, GrandpaWeight)> { - Grandpa::grandpa_authorities() + impl aura_primitives::AuraApi for Runtime { + fn slot_duration() -> u64 { + Aura::slot_duration() } - } - - impl babe_primitives::BabeApi for Runtime { - fn configuration() -> babe_primitives::BabeConfiguration { - // The choice of `c` parameter (where `1 - c` represents the - // probability of a slot being empty), is done in accordance to the - // slot duration and expected target block time, for safely - // resisting network delays of maximum two seconds. - // - babe_primitives::BabeConfiguration { - slot_duration: Babe::slot_duration(), - epoch_length: EpochDuration::get(), - c: PRIMARY_PROBABILITY, - genesis_authorities: Babe::authorities(), - randomness: Babe::randomness(), - secondary_slots: true, - } + + fn authorities() -> Vec { + Aura::authorities() } } @@ -395,4 +358,10 @@ impl_runtime_apis! { opaque::SessionKeys::generate(seed) } } + + impl fg_primitives::GrandpaApi for Runtime { + fn grandpa_authorities() -> Vec<(GrandpaId, GrandpaWeight)> { + Grandpa::grandpa_authorities() + } + } } diff --git a/node-template/src/chain_spec.rs b/node-template/src/chain_spec.rs index 9fdc6ee2ca..2996f5414a 100644 --- a/node-template/src/chain_spec.rs +++ b/node-template/src/chain_spec.rs @@ -1,9 +1,9 @@ use primitives::{Pair, Public}; use node_template_runtime::{ - AccountId, BabeConfig, BalancesConfig, GenesisConfig, GrandpaConfig, + AccountId, AuraConfig, BalancesConfig, GenesisConfig, GrandpaConfig, SudoConfig, IndicesConfig, SystemConfig, WASM_BINARY, }; -use babe_primitives::{AuthorityId as BabeId}; +use aura_primitives::sr25519::{AuthorityId as AuraId}; use grandpa_primitives::{AuthorityId as GrandpaId}; use substrate_service; @@ -31,13 +31,11 @@ pub fn get_from_seed(seed: &str) -> ::Pu .public() } -/// Helper function to generate stash, controller and session key from seed -pub fn get_authority_keys_from_seed(seed: &str) -> (AccountId, AccountId, GrandpaId, BabeId) { +/// Helper function to generate an authority key for Aura +pub fn get_authority_keys_from_seed(s: &str) -> (AuraId, GrandpaId) { ( - get_from_seed::(&format!("{}//stash", seed)), - get_from_seed::(seed), - get_from_seed::(seed), - get_from_seed::(seed), + get_from_seed::(s), + get_from_seed::(s), ) } @@ -106,7 +104,7 @@ impl Alternative { } } -fn testnet_genesis(initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId)>, +fn testnet_genesis(initial_authorities: Vec<(AuraId, GrandpaId)>, root_key: AccountId, endowed_accounts: Vec, _enable_println: bool) -> GenesisConfig { @@ -125,11 +123,11 @@ fn testnet_genesis(initial_authorities: Vec<(AccountId, AccountId, GrandpaId, Ba sudo: Some(SudoConfig { key: root_key, }), - babe: Some(BabeConfig { - authorities: initial_authorities.iter().map(|x| (x.3.clone(), 1)).collect(), + aura: Some(AuraConfig { + authorities: initial_authorities.iter().map(|x| (x.0.clone())).collect(), }), grandpa: Some(GrandpaConfig { - authorities: initial_authorities.iter().map(|x| (x.2.clone(), 1)).collect(), + authorities: initial_authorities.iter().map(|x| (x.1.clone(), 1)).collect(), }), } } diff --git a/node-template/src/cli.rs b/node-template/src/cli.rs index 6a0b0dd706..f0b429e0fa 100644 --- a/node-template/src/cli.rs +++ b/node-template/src/cli.rs @@ -5,6 +5,7 @@ use tokio::runtime::Runtime; pub use substrate_cli::{VersionInfo, IntoExit, error}; use substrate_cli::{informant, parse_and_prepare, ParseAndPrepare, NoCustom}; use substrate_service::{AbstractService, Roles as ServiceRoles, Configuration}; +use aura_primitives::sr25519::{AuthorityPair as AuraPair}; use crate::chain_spec; use log::info; diff --git a/node-template/src/service.rs b/node-template/src/service.rs index 24b22082c5..64a453e298 100644 --- a/node-template/src/service.rs +++ b/node-template/src/service.rs @@ -3,16 +3,16 @@ use std::sync::Arc; use std::time::Duration; use substrate_client::LongestChain; -use babe; -use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; use futures::prelude::*; use node_template_runtime::{self, GenesisConfig, opaque::Block, RuntimeApi}; use substrate_service::{error::{Error as ServiceError}, AbstractService, Configuration, ServiceBuilder}; use transaction_pool::{self, txpool::{Pool as TransactionPool}}; use inherents::InherentDataProviders; -use network::construct_simple_protocol; +use network::{construct_simple_protocol}; use substrate_executor::native_executor_instance; pub use substrate_executor::NativeExecutor; +use aura_primitives::sr25519::{AuthorityPair as AuraPair}; +use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; // Our native executor instance. native_executor_instance!( @@ -44,33 +44,26 @@ macro_rules! new_full_start { .with_transaction_pool(|config, client| Ok(transaction_pool::txpool::Pool::new(config, transaction_pool::FullChainApi::new(client))) )? - .with_import_queue(|_config, client, mut select_chain, _transaction_pool| { + .with_import_queue(|_config, client, mut select_chain, transaction_pool| { let select_chain = select_chain.take() .ok_or_else(|| substrate_service::Error::SelectChainRequired)?; + let (grandpa_block_import, grandpa_link) = grandpa::block_import::<_, _, _, node_template_runtime::RuntimeApi, _, _>( client.clone(), &*client, select_chain )?; - let justification_import = grandpa_block_import.clone(); - - let (babe_block_import, babe_link) = babe::block_import( - babe::Config::get_or_compute(&*client)?, - grandpa_block_import, - client.clone(), - client.clone(), - )?; - let import_queue = babe::import_queue( - babe_link.clone(), - babe_block_import.clone(), - Some(Box::new(justification_import)), + let import_queue = aura::import_queue::<_, _, AuraPair, _>( + aura::SlotDuration::get_or_compute(&*client)?, + Box::new(grandpa_block_import.clone()), + Some(Box::new(grandpa_block_import.clone())), None, - client.clone(), client, inherent_data_providers.clone(), + Some(transaction_pool), )?; - import_setup = Some((babe_block_import, grandpa_link, babe_link)); + import_setup = Some((grandpa_block_import, grandpa_link)); Ok(import_queue) })?; @@ -83,24 +76,23 @@ macro_rules! new_full_start { pub fn new_full(config: Configuration) -> Result { - let is_authority = config.roles.is_authority(); + let force_authoring = config.force_authoring; let name = config.name.clone(); let disable_grandpa = config.disable_grandpa; - let force_authoring = config.force_authoring; let (builder, mut import_setup, inherent_data_providers) = new_full_start!(config); + let (block_import, grandpa_link) = + import_setup.take() + .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); + let service = builder.with_network_protocol(|_| Ok(NodeProtocol::new()))? .with_finality_proof_provider(|client, backend| Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, client)) as _) )? .build()?; - let (block_import, grandpa_link, babe_link) = - import_setup.take() - .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); - if is_authority { let proposer = basic_authorship::ProposerFactory { client: service.client(), @@ -111,22 +103,21 @@ pub fn new_full(config: Configuration( + aura::SlotDuration::get_or_compute(&*client)?, client, select_chain, - env: proposer, block_import, - sync_oracle: service.network(), - inherent_data_providers: inherent_data_providers.clone(), + proposer, + service.network(), + inherent_data_providers.clone(), force_authoring, - babe_link, - }; + service.keystore(), + )?; - let babe = babe::start_babe(babe_config)?; - let select = babe.select(service.on_exit()).then(|_| Ok(())); + let select = aura.select(service.on_exit()).then(|_| Ok(())); - // the BABE authoring task is considered infallible, i.e. if it + // the AURA authoring task is considered essential, i.e. if it // fails we take down the service with it. service.spawn_essential_task(select); } @@ -196,26 +187,18 @@ pub fn new_light(config: Configuration( client.clone(), backend, Arc::new(fetch_checker), client.clone() )?; - let finality_proof_import = grandpa_block_import.clone(); let finality_proof_request_builder = finality_proof_import.create_finality_proof_request_builder(); - let (babe_block_import, babe_link) = babe::block_import( - babe::Config::get_or_compute(&*client)?, - grandpa_block_import, - client.clone(), - client.clone(), - )?; - - let import_queue = babe::import_queue( - babe_link.clone(), - babe_block_import, + let import_queue = aura::import_queue::<_, _, AuraPair, ()>( + aura::SlotDuration::get_or_compute(&*client)?, + Box::new(grandpa_block_import), None, Some(Box::new(finality_proof_import)), - client.clone(), client, inherent_data_providers.clone(), + None, )?; Ok((import_queue, finality_proof_request_builder)) -- GitLab From fb26c5605ff5a9fc2675e1cef4694ac53a9d86e9 Mon Sep 17 00:00:00 2001 From: h4x3rotab Date: Fri, 18 Oct 2019 21:00:45 +0800 Subject: [PATCH 231/275] Fix typo (#3853) In `core/client/src/client.rs`: "innacurate" -> "inaccurate" --- core/client/src/client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/client/src/client.rs b/core/client/src/client.rs index 796520cb7f..d853d851c5 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -1125,7 +1125,7 @@ impl Client where // then some other block is the common ancestor. if route_from_best.common_block().hash != block { // NOTE: we're setting the finalized block as best block, this might - // be slightly innacurate since we might have a "better" block + // be slightly inaccurate since we might have a "better" block // further along this chain, but since best chain selection logic is // pluggable we cannot make a better choice here. usages that need // an accurate "best" block need to go through `SelectChain` -- GitLab From 6949b8e2862ed18f4f8d6be3f44d77e1e7097c98 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 18 Oct 2019 16:01:14 +0200 Subject: [PATCH 232/275] core/finality-grandpa: Minor refactorings (#3825) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * core/finality-grandpa: Improve code comments * core/finality-grandpa: Rename VoteOrPrecommit to PrevoteOrPrecommit According to the Grandpa paper [1]: > A vote is a block hash, together with some metadata such as round number and the type of vote, such as prevote or precommit, all signed with a voter’s private key. To reduce confusion this patch makes the code consistent with the research paper. [1] https://github.com/w3f/consensus/blob/master/pdf/grandpa.pdf * core/finality-grandpa: Add comment for NetworkStream concept * core/finality-grandpa: Improve round_communication doc comment * core/finality-grandpa: Rename PrevoteOrPrecommit to Vote * core/finality-grandpa: Represent NetworkStream state machine as enum * core/finality-grandpa: Improve KeepTopics comment --- core/finality-grandpa/primitives/src/lib.rs | 2 +- .../src/communication/gossip.rs | 24 ++++--- .../finality-grandpa/src/communication/mod.rs | 64 +++++++++++++------ 3 files changed, 59 insertions(+), 31 deletions(-) diff --git a/core/finality-grandpa/primitives/src/lib.rs b/core/finality-grandpa/primitives/src/lib.rs index 384319a298..a439953899 100644 --- a/core/finality-grandpa/primitives/src/lib.rs +++ b/core/finality-grandpa/primitives/src/lib.rs @@ -52,7 +52,7 @@ pub type AuthorityWeight = u64; /// The index of an authority. pub type AuthorityIndex = u64; -/// The identifier of a GRANDPA set. +/// The monotonic identifier of a GRANDPA set of authorities. pub type SetId = u64; /// The round indicator. diff --git a/core/finality-grandpa/src/communication/gossip.rs b/core/finality-grandpa/src/communication/gossip.rs index 1f9d78c867..24402c8a02 100644 --- a/core/finality-grandpa/src/communication/gossip.rs +++ b/core/finality-grandpa/src/communication/gossip.rs @@ -183,7 +183,13 @@ impl View { const KEEP_RECENT_ROUNDS: usize = 3; -/// Tracks topics we keep messages for. +/// Tracks gossip topics that we are keeping messages for. We keep topics of: +/// +/// - the last `KEEP_RECENT_ROUNDS` complete GRANDPA rounds, +/// +/// - the topic for the current and next round, +/// +/// - and a global topic for commit and catch-up messages. struct KeepTopics { current_set: SetId, rounds: VecDeque<(Round, SetId)>, @@ -256,7 +262,7 @@ fn neighbor_topics(view: &View>) -> Vec { #[derive(Debug, Encode, Decode)] pub(super) enum GossipMessage { /// Grandpa message with round and set info. - VoteOrPrecommit(VoteOrPrecommitMessage), + Vote(VoteMessage), /// Grandpa commit message with round and set info. Commit(FullCommitMessage), /// A neighbor packet. Not repropagated. @@ -273,9 +279,9 @@ impl From>> for GossipMessage { +pub(super) struct VoteMessage { /// The round this message is from. pub(super) round: Round, /// The voter set ID this message is from. @@ -612,7 +618,7 @@ impl Inner { cost::PAST_REJECTION } - fn validate_round_message(&self, who: &PeerId, full: &VoteOrPrecommitMessage) + fn validate_round_message(&self, who: &PeerId, full: &VoteMessage) -> Action { match self.consider_vote(full.round, full.set_id) { @@ -1003,7 +1009,7 @@ impl GossipValidator { let action = { match GossipMessage::::decode(&mut data) { - Ok(GossipMessage::VoteOrPrecommit(ref message)) + Ok(GossipMessage::Vote(ref message)) => self.inner.write().validate_round_message(who, message), Ok(GossipMessage::Commit(ref message)) => self.inner.write().validate_commit_message(who, message), Ok(GossipMessage::Neighbor(update)) => { @@ -1163,7 +1169,7 @@ impl network_gossip::Validator for GossipValidator Ok(GossipMessage::Neighbor(_)) => false, Ok(GossipMessage::CatchUpRequest(_)) => false, Ok(GossipMessage::CatchUp(_)) => false, - Ok(GossipMessage::VoteOrPrecommit(_)) => false, // should not be the case. + Ok(GossipMessage::Vote(_)) => false, // should not be the case. } }) } @@ -1478,7 +1484,7 @@ mod tests { val.note_round(Round(1), |_, _| {}); let inner = val.inner.read(); - let unknown_voter = inner.validate_round_message(&peer, &VoteOrPrecommitMessage { + let unknown_voter = inner.validate_round_message(&peer, &VoteMessage { round: Round(1), set_id: SetId(set_id), message: SignedMessage:: { @@ -1491,7 +1497,7 @@ mod tests { } }); - let bad_sig = inner.validate_round_message(&peer, &VoteOrPrecommitMessage { + let bad_sig = inner.validate_round_message(&peer, &VoteMessage { round: Round(1), set_id: SetId(set_id), message: SignedMessage:: { diff --git a/core/finality-grandpa/src/communication/mod.rs b/core/finality-grandpa/src/communication/mod.rs index 652c33c026..ba7bdce336 100644 --- a/core/finality-grandpa/src/communication/mod.rs +++ b/core/finality-grandpa/src/communication/mod.rs @@ -48,7 +48,7 @@ use crate::{ }; use crate::environment::HasVoted; use gossip::{ - GossipMessage, FullCatchUpMessage, FullCommitMessage, VoteOrPrecommitMessage, GossipValidator + GossipMessage, FullCatchUpMessage, FullCommitMessage, VoteMessage, GossipValidator }; use fg_primitives::{ AuthorityPair, AuthorityId, AuthoritySignature, SetId as SetIdNumber, RoundNumber, @@ -148,12 +148,21 @@ impl Network for Arc> where type In = NetworkStream; fn messages_for(&self, topic: B::Hash) -> Self::In { + // Given that one can only communicate with the Substrate network via the `NetworkService` via message-passing, + // and given that methods on the network consensus gossip are not exposed but only reachable by passing a + // closure into `with_gossip` on the `NetworkService` this function needs to make use of the `NetworkStream` + // construction. + // + // We create a oneshot channel and pass the sender within a closure to the network. At some point in the future + // the network passes the message channel back through the oneshot channel. But the consumer of this function + // expects a stream, not a stream within a oneshot. This complexity is abstracted within `NetworkStream`, + // waiting for the oneshot to resolve and from there on acting like a normal message channel. let (tx, rx) = oneshot::channel(); self.with_gossip(move |gossip, _| { let inner_rx = gossip.messages_for(GRANDPA_ENGINE_ID, topic); let _ = tx.send(inner_rx); }); - NetworkStream { outer: rx, inner: None } + NetworkStream::PollingOneshot(rx) } fn register_validator(&self, validator: Arc>) { @@ -202,10 +211,18 @@ impl Network for Arc> where } } -/// A stream used by NetworkBridge in its implementation of Network. -pub struct NetworkStream { - inner: Option>, - outer: oneshot::Receiver> +/// A stream used by NetworkBridge in its implementation of Network. Given a oneshot that eventually returns a channel +/// which eventually returns messages, instead of: +/// +/// 1. polling the oneshot until it returns a message channel +/// +/// 2. polling the message channel for messages +/// +/// `NetworkStream` combines the two steps into one, requiring a consumer to only poll `NetworkStream` to retrieve +/// messages directly. +pub enum NetworkStream { + PollingOneshot(oneshot::Receiver>), + PollingTopicNotifications(mpsc::UnboundedReceiver), } impl Stream for NetworkStream { @@ -213,17 +230,21 @@ impl Stream for NetworkStream { type Error = (); fn poll(&mut self) -> Poll, Self::Error> { - if let Some(ref mut inner) = self.inner { - return inner.poll(); - } - match self.outer.poll() { - Ok(futures::Async::Ready(mut inner)) => { - let poll_result = inner.poll(); - self.inner = Some(inner); - poll_result + match self { + NetworkStream::PollingOneshot(oneshot) => { + match oneshot.poll() { + Ok(futures::Async::Ready(mut stream)) => { + let poll_result = stream.poll(); + *self = NetworkStream::PollingTopicNotifications(stream); + poll_result + }, + Ok(futures::Async::NotReady) => Ok(futures::Async::NotReady), + Err(_) => Err(()) + } + }, + NetworkStream::PollingTopicNotifications(stream) => { + stream.poll() }, - Ok(futures::Async::NotReady) => Ok(futures::Async::NotReady), - Err(_) => Err(()) } } } @@ -275,8 +296,8 @@ impl> NetworkBridge { validator.note_round(Round(round.number), |_, _| {}); for signed in round.votes.iter() { - let message = gossip::GossipMessage::VoteOrPrecommit( - gossip::VoteOrPrecommitMessage:: { + let message = gossip::GossipMessage::Vote( + gossip::VoteMessage:: { message: signed.clone(), round: Round(round.number), set_id: SetId(set_id), @@ -341,7 +362,8 @@ impl> NetworkBridge { ); } - /// Get the round messages for a round in the current set ID. These are signature-checked. + /// Get a stream of signature-checked round messages from the network as well as a sink for round messages to the + /// network all within the current set. pub(crate) fn round_communication( &self, round: Round, @@ -379,7 +401,7 @@ impl> NetworkBridge { }) .and_then(move |msg| { match msg { - GossipMessage::VoteOrPrecommit(msg) => { + GossipMessage::Vote(msg) => { // check signature. if !voters.contains_key(&msg.message.id) { debug!(target: "afg", "Skipping message from unknown voter {}", msg.message.id); @@ -707,7 +729,7 @@ impl> Sink for OutgoingMessages id: local_id.clone(), }; - let message = GossipMessage::VoteOrPrecommit(VoteOrPrecommitMessage:: { + let message = GossipMessage::Vote(VoteMessage:: { message: signed.clone(), round: Round(self.round), set_id: SetId(self.set_id), -- GitLab From ac21a1b5804c350a995ece904440b0947d8a1f85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 18 Oct 2019 16:05:23 +0200 Subject: [PATCH 233/275] Don't make `ServiceBuilder` require to have a finality proof provider (#3831) specified --- core/service/src/builder.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/service/src/builder.rs b/core/service/src/builder.rs index e4b02150bf..6a286bf19d 100644 --- a/core/service/src/builder.rs +++ b/core/service/src/builder.rs @@ -149,7 +149,7 @@ where TGen: RuntimeGenesis, TCSExt: Extension { (), (), BoxFinalityProofRequestBuilder, - (), + Arc>, (), (), (), @@ -224,7 +224,7 @@ where TGen: RuntimeGenesis, TCSExt: Extension { (), (), BoxFinalityProofRequestBuilder, - (), + Arc>, (), (), (), -- GitLab From f5ea01efb14b6dcaa1a5e7aeef3c1341921c0538 Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Fri, 18 Oct 2019 16:44:40 +0200 Subject: [PATCH 234/275] Persist block announcements (#3826) * Persist block announcements * Renamed sync requests to fork targets * Fixed pruning detection condition --- core/network/src/protocol.rs | 11 +- core/network/src/protocol/sync.rs | 207 +++++++++++++----------------- core/network/src/test/mod.rs | 2 + core/network/src/test/sync.rs | 11 ++ 4 files changed, 104 insertions(+), 127 deletions(-) diff --git a/core/network/src/protocol.rs b/core/network/src/protocol.rs index dc9e6688e7..2e036cf118 100644 --- a/core/network/src/protocol.rs +++ b/core/network/src/protocol.rs @@ -1121,18 +1121,13 @@ impl, H: ExHashT> Protocol { }; match self.sync.on_block_announce(who.clone(), hash, &announce, is_their_best) { - sync::OnBlockAnnounce::Request(peer, req) => { - self.send_message(peer, GenericMessage::BlockRequest(req)); - return CustomMessageOutcome::None - } sync::OnBlockAnnounce::Nothing => { - // try_import is only true when we have all data required to import block + // `on_block_announce` returns `OnBlockAnnounce::ImportHeader` + // when we have all data required to import the block // in the BlockAnnounce message. This is only when: // 1) we're on light client; // AND - // - EITHER 2.1) announced block is stale; - // - OR 2.2) announced block is NEW and we normally only want to download this single block (i.e. - // there are no ascendants of this block scheduled for retrieval) + // 2) parent block is already imported and not pruned. return CustomMessageOutcome::None } sync::OnBlockAnnounce::ImportHeader => () // We proceed with the import. diff --git a/core/network/src/protocol/sync.rs b/core/network/src/protocol/sync.rs index 9f9db92289..bd8a9fe27f 100644 --- a/core/network/src/protocol/sync.rs +++ b/core/network/src/protocol/sync.rs @@ -69,9 +69,6 @@ const MAJOR_SYNC_BLOCKS: u8 = 5; /// Number of recently announced blocks to track for each peer. const ANNOUNCE_HISTORY_SIZE: usize = 64; -/// Max number of blocks to download for unknown forks. -const MAX_UNKNOWN_FORK_DOWNLOAD_LEN: u32 = 32; - /// Reputation change when a peer sent us a status message that led to a /// database read error. const BLOCKCHAIN_STATUS_READ_ERROR_REPUTATION_CHANGE: i32 = -(1 << 16); @@ -125,8 +122,8 @@ pub struct ChainSync { best_importing_number: NumberFor, /// Finality proof handler. request_builder: Option>, - /// Explicit sync requests. - sync_requests: HashMap>, + /// Fork sync targets. + fork_targets: HashMap>, /// A flag that caches idle state with no pending requests. is_idle: bool, /// A type to check incoming block announcements. @@ -160,8 +157,9 @@ pub struct PeerInfo { pub best_number: NumberFor } -struct SyncRequest { +struct ForkTarget { number: NumberFor, + parent_hash: Option, peers: HashSet, } @@ -242,13 +240,11 @@ pub enum OnBlockData { /// Result of [`ChainSync::on_block_announce`]. #[derive(Debug, Clone, PartialEq, Eq)] -pub enum OnBlockAnnounce { +pub enum OnBlockAnnounce { /// The announcement does not require further handling. Nothing, /// The announcement header should be imported. ImportHeader, - /// Another block request to the given peer is necessary. - Request(PeerId, BlockRequest) } /// Result of [`ChainSync::on_block_justification`]. @@ -307,7 +303,7 @@ impl ChainSync { queue_blocks: Default::default(), best_importing_number: Zero::zero(), request_builder, - sync_requests: Default::default(), + fork_targets: Default::default(), is_idle: false, block_announce_validator, } @@ -462,7 +458,7 @@ impl ChainSync { // The implementation is similar to on_block_announce with unknown parent hash. pub fn set_sync_fork_request(&mut self, peers: Vec, hash: &B::Hash, number: NumberFor) { if peers.is_empty() { - if let Some(_) = self.sync_requests.remove(hash) { + if let Some(_) = self.fork_targets.remove(hash) { debug!(target: "sync", "Cleared sync request for block {:?} with {:?}", hash, peers); } return; @@ -494,11 +490,12 @@ impl ChainSync { } } - self.sync_requests + self.fork_targets .entry(hash.clone()) - .or_insert_with(|| SyncRequest { + .or_insert_with(|| ForkTarget { number, peers: Default::default(), + parent_hash: None, }) .peers.extend(peers); } @@ -562,17 +559,30 @@ impl ChainSync { } let blocks = &mut self.blocks; let attrs = &self.required_block_attributes; - let sync_requests = &self.sync_requests; + let fork_targets = &self.fork_targets; let mut have_requests = false; let last_finalized = self.client.info().chain.finalized_number; let best_queued = self.best_queued_number; + let client = &self.client; + let queue = &self.queue_blocks; let iter = self.peers.iter_mut().filter_map(move |(id, peer)| { if !peer.state.is_available() { trace!(target: "sync", "Peer {} is busy", id); return None } - if let Some((hash, req)) = explicit_sync_request(id, sync_requests, best_queued, last_finalized, attrs) { - trace!(target: "sync", "Downloading explicitly requested block {:?} from {}", hash, id); + if let Some((hash, req)) = fork_sync_request( + id, + fork_targets, + best_queued, + last_finalized, + attrs, + |hash| if queue.contains(hash) { + BlockStatus::Queued + } else { + client.block_status(&BlockId::Hash(*hash)).unwrap_or(BlockStatus::Unknown) + }, + ) { + trace!(target: "sync", "Downloading fork {:?} from {}", hash, id); peer.state = PeerSyncState::DownloadingStale(hash); have_requests = true; Some((id.clone(), req)) @@ -665,6 +675,26 @@ impl ChainSync { peer.state = PeerSyncState::AncestorSearch(next_num, next_state); return Ok(OnBlockData::Request(who, ancestry_request::(next_num))) } else { + // Ancestry search is complete. Check if peer is on a stale fork unknown to us and + // add it to sync targets if necessary. + trace!(target: "sync", "Ancestry search complete. Ours={} ({}), Theirs={} ({}), Common={}", + self.best_queued_hash, + self.best_queued_number, + peer.best_hash, + peer.best_number, + peer.common_number + ); + if peer.common_number < peer.best_number && peer.best_number < self.best_queued_number { + trace!(target: "sync", "Added fork target {} for {}" , peer.best_hash, who); + self.fork_targets + .entry(peer.best_hash.clone()) + .or_insert_with(|| ForkTarget { + number: peer.best_number, + parent_hash: None, + peers: Default::default(), + }) + .peers.insert(who); + } peer.state = PeerSyncState::Available; Vec::new() } @@ -922,14 +952,14 @@ impl ChainSync { self.best_queued_number = number; self.best_queued_hash = *hash; } - if let Some(_) = self.sync_requests.remove(&hash) { - trace!(target: "sync", "Completed explicit sync request {:?}", hash); + if let Some(_) = self.fork_targets.remove(&hash) { + trace!(target: "sync", "Completed fork sync {:?}", hash); } // Update common blocks for (n, peer) in self.peers.iter_mut() { if let PeerSyncState::AncestorSearch(_, _) = peer.state { - // Abort search. - peer.state = PeerSyncState::Available; + // Wait for ancestry search to complete first. + continue; } let new_common_number = if peer.best_number >= number { number @@ -952,12 +982,12 @@ impl ChainSync { /// Call when a node announces a new block. /// - /// If true is returned, then the caller MUST try to import passed + /// If `OnBlockAnnounce::ImportHeader` is returned, then the caller MUST try to import passed /// header (call `on_block_data`). The network request isn't sent /// in this case. Both hash and header is passed as an optimization /// to avoid rehashing the header. pub fn on_block_announce(&mut self, who: PeerId, hash: B::Hash, announce: &BlockAnnounce, is_best: bool) - -> OnBlockAnnounce + -> OnBlockAnnounce { let header = &announce.header; let number = *header.number(); @@ -1001,6 +1031,9 @@ impl ChainSync { // known block case if known || self.is_already_downloading(&hash) { trace!(target: "sync", "Known block announce from {}: {}", who, hash); + if let Some(target) = self.fork_targets.get_mut(&hash) { + target.peers.insert(who); + } return OnBlockAnnounce::Nothing } @@ -1009,79 +1042,42 @@ impl ChainSync { match self.block_announce_validator.validate(&header, assoc_data) { Ok(Validation::Success) => (), Ok(Validation::Failure) => { - debug!(target: "sync", "block announcement validation of block {} from {} failed", hash, who); + debug!(target: "sync", "Block announcement validation of block {} from {} failed", hash, who); return OnBlockAnnounce::Nothing } Err(e) => { - error!(target: "sync", "block announcement validation errored: {}", e); + error!(target: "sync", "Block announcement validation errored: {}", e); return OnBlockAnnounce::Nothing } } - // stale block case - let requires_additional_data = !self.role.is_light(); - if number <= self.best_queued_number { - if !(known_parent || self.is_already_downloading(header.parent_hash())) { - let block_status = self.client.block_status(&BlockId::Number(*header.number())) - .unwrap_or(BlockStatus::Unknown); - if block_status == BlockStatus::InChainPruned { - trace!( - target: "sync", - "Ignored unknown ancient block announced from {}: {} {:?}", who, hash, header - ); - return OnBlockAnnounce::Nothing - } - trace!( - target: "sync", - "Considering new unknown stale block announced from {}: {} {:?}", who, hash, header - ); - if let Some(request) = self.download_unknown_stale(&who, &hash) { - if requires_additional_data { - return OnBlockAnnounce::Request(who, request) - } else { - return OnBlockAnnounce::ImportHeader - } - } else { - return OnBlockAnnounce::Nothing - } - } else { - if ancient_parent { - trace!(target: "sync", "Ignored ancient stale block announced from {}: {} {:?}", who, hash, header); - return OnBlockAnnounce::Nothing - } - if let Some(request) = self.download_stale(&who, &hash) { - if requires_additional_data { - return OnBlockAnnounce::Request(who, request) - } else { - return OnBlockAnnounce::ImportHeader - } - } else { - return OnBlockAnnounce::Nothing - } - } - } - if ancient_parent { trace!(target: "sync", "Ignored ancient block announced from {}: {} {:?}", who, hash, header); return OnBlockAnnounce::Nothing } - trace!(target: "sync", "Considering new block announced from {}: {} {:?}", who, hash, header); - - let (range, request) = match self.select_new_blocks(who.clone()) { - Some((range, request)) => (range, request), - None => return OnBlockAnnounce::Nothing - }; - - let is_required_data_available = !requires_additional_data - && range.end - range.start == One::one() - && range.start == *header.number(); + let requires_additional_data = !self.role.is_light() || !known_parent; + if !requires_additional_data { + trace!(target: "sync", "Importing new header announced from {}: {} {:?}", who, hash, header); + return OnBlockAnnounce::ImportHeader + } - if !is_required_data_available { - return OnBlockAnnounce::Request(who, request) + if number <= self.best_queued_number { + trace!( + target: "sync", + "Added sync target for block announced from {}: {} {:?}", who, hash, header + ); + self.fork_targets + .entry(hash.clone()) + .or_insert_with(|| ForkTarget { + number, + parent_hash: Some(header.parent_hash().clone()), + peers: Default::default(), + }) + .peers.insert(who); } - OnBlockAnnounce::ImportHeader + OnBlockAnnounce::Nothing } /// Call when a peer has disconnected. @@ -1117,40 +1113,6 @@ impl ChainSync { }) } - /// Download old block with known parent. - fn download_stale(&mut self, who: &PeerId, hash: &B::Hash) -> Option> { - let peer = self.peers.get_mut(who)?; - if !peer.state.is_available() { - return None - } - peer.state = PeerSyncState::DownloadingStale(*hash); - Some(message::generic::BlockRequest { - id: 0, - fields: self.required_block_attributes.clone(), - from: message::FromBlock::Hash(*hash), - to: None, - direction: message::Direction::Ascending, - max: Some(1), - }) - } - - /// Download old block with unknown parent. - fn download_unknown_stale(&mut self, who: &PeerId, hash: &B::Hash) -> Option> { - let peer = self.peers.get_mut(who)?; - if !peer.state.is_available() { - return None - } - peer.state = PeerSyncState::DownloadingStale(*hash); - Some(message::generic::BlockRequest { - id: 0, - fields: self.required_block_attributes.clone(), - from: message::FromBlock::Hash(*hash), - to: None, - direction: message::Direction::Descending, - max: Some(MAX_UNKNOWN_FORK_DOWNLOAD_LEN), - }) - } - /// Select a range of new blocks to download from the given peer. fn select_new_blocks(&mut self, who: PeerId) -> Option<(Range>, BlockRequest)> { // when there are too many blocks in the queue => do not try to download new blocks @@ -1298,28 +1260,35 @@ fn peer_block_request( } } -/// Get pending explicit sync request for a peer. -fn explicit_sync_request( +/// Get pending fork sync targets for a peer. +fn fork_sync_request( id: &PeerId, - requests: &HashMap>, + targets: &HashMap>, best_num: NumberFor, finalized: NumberFor, attributes: &message::BlockAttributes, + check_block: impl Fn(&B::Hash) -> BlockStatus, ) -> Option<(B::Hash, BlockRequest)> { - for (hash, r) in requests { + for (hash, r) in targets { if !r.peers.contains(id) { continue } if r.number <= best_num { trace!(target: "sync", "Downloading requested fork {:?} from {}", hash, id); + let parent_status = r.parent_hash.as_ref().map_or(BlockStatus::Unknown, check_block); + let mut count = (r.number - finalized).saturated_into::(); // up to the last finalized block + if parent_status != BlockStatus::Unknown { + // request only single block + count = 1; + } return Some((hash.clone(), message::generic::BlockRequest { id: 0, fields: attributes.clone(), from: message::FromBlock::Hash(hash.clone()), to: None, direction: message::Direction::Descending, - max: Some((r.number - finalized).saturated_into::()), // up to the last finalized block + max: Some(count), })) } } diff --git a/core/network/src/test/mod.rs b/core/network/src/test/mod.rs index 2c87ba1ac8..92e747280b 100644 --- a/core/network/src/test/mod.rs +++ b/core/network/src/test/mod.rs @@ -704,7 +704,9 @@ pub trait TestNetFactory: Sized { fn poll(&mut self) { self.mut_peers(|peers| { for peer in peers { + trace!(target: "sync", "-- Polling {}", peer.id()); peer.network.poll().unwrap(); + trace!(target: "sync", "-- Polling complete {}", peer.id()); // We poll `imported_blocks_stream`. while let Ok(Async::Ready(Some(notification))) = peer.imported_blocks_stream.poll() { diff --git a/core/network/src/test/sync.rs b/core/network/src/test/sync.rs index b5b137a31a..b1b2b9d407 100644 --- a/core/network/src/test/sync.rs +++ b/core/network/src/test/sync.rs @@ -457,6 +457,17 @@ fn can_sync_small_non_best_forks() { } Ok(Async::Ready(())) })).unwrap(); + net.block_until_sync(&mut runtime); + + let another_fork = net.peer(0).push_blocks_at(BlockId::Number(35), 2, true); + net.peer(0).announce_block(another_fork, Vec::new()); + runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> { + net.poll(); + if net.peer(1).client().header(&BlockId::Hash(another_fork)).unwrap().is_none() { + return Ok(Async::NotReady) + } + Ok(Async::Ready(())) + })).unwrap(); } #[test] -- GitLab From 5ad7a68fc7dc518b75734514d71dbaa64af74438 Mon Sep 17 00:00:00 2001 From: Ximin Luo Date: Fri, 18 Oct 2019 16:15:05 +0100 Subject: [PATCH 235/275] Make build work with rustc 1.37 stable and RUSTC_BOOTSTRAP=1 (#3844) * Make build work with rustc 1.37 stable and RUSTC_BOOTSTRAP=1 * Bump versions to run CI --- core/sr-std/without_std.rs | 1 - core/utils/wasm-builder/src/prerequisites.rs | 7 ++++++- node/runtime/src/lib.rs | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/core/sr-std/without_std.rs b/core/sr-std/without_std.rs index ed9eea6c31..134cc25c94 100755 --- a/core/sr-std/without_std.rs +++ b/core/sr-std/without_std.rs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -#[cfg(feature = "nightly")] #[doc(hidden)] pub extern crate alloc; diff --git a/core/utils/wasm-builder/src/prerequisites.rs b/core/utils/wasm-builder/src/prerequisites.rs index eeac6df33e..0c41dff6c8 100644 --- a/core/utils/wasm-builder/src/prerequisites.rs +++ b/core/utils/wasm-builder/src/prerequisites.rs @@ -16,6 +16,7 @@ use std::{process::{Command, Stdio}, fs}; +use std::env; use tempfile::tempdir; /// Checks that all prerequisites are installed. @@ -23,7 +24,7 @@ use tempfile::tempdir; /// # Returns /// Returns `None` if everything was found and `Some(ERR_MSG)` if something could not be found. pub fn check() -> Option<&'static str> { - if !check_nightly_installed() { + if !rustc_stable_forced_to_nightly() && !check_nightly_installed(){ return Some("Rust nightly not installed, please install it!") } @@ -39,6 +40,10 @@ pub fn check() -> Option<&'static str> { check_wasm_toolchain_installed() } +fn rustc_stable_forced_to_nightly() -> bool { + env::var("RUSTC_BOOTSTRAP") == Ok("1".to_string()) +} + fn check_nightly_installed() -> bool { let command = crate::get_nightly_cargo(); command.is_nightly() diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index fdf0bfdc14..ac801fd39e 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -84,8 +84,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 178, - impl_version: 178, + spec_version: 179, + impl_version: 179, apis: RUNTIME_API_VERSIONS, }; -- GitLab From c96f11a68ba8856ee97fbbc9e29bf667dd5fb0b8 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 18 Oct 2019 18:32:13 +0300 Subject: [PATCH 236/275] Support block revert operation in blockchain cache (#3401) * support block revert operation in cache * #[cfg(test)] -> fn unused_sink() * swap conditions * post-merge fix --- core/client/db/src/cache/list_cache.rs | 141 ++++++++++++++++++++++- core/client/db/src/cache/list_storage.rs | 8 ++ core/client/db/src/cache/mod.rs | 21 ++++ core/client/db/src/lib.rs | 6 + 4 files changed, 175 insertions(+), 1 deletion(-) diff --git a/core/client/db/src/cache/list_cache.rs b/core/client/db/src/cache/list_cache.rs index 9095b80fb6..7a4fcc448e 100644 --- a/core/client/db/src/cache/list_cache.rs +++ b/core/client/db/src/cache/list_cache.rs @@ -39,7 +39,7 @@ //! Finalized entry E1 is pruned when block B is finalized so that: //! EntryAt(B.number - prune_depth).points_to(E1) -use std::collections::BTreeSet; +use std::collections::{BTreeSet, BTreeMap}; use log::warn; @@ -89,6 +89,9 @@ pub enum CommitOperation { /// - new entry is finalized AND/OR /// - some forks are destroyed BlockFinalized(ComplexBlockId, Option>, BTreeSet), + /// When best block is reverted - contains the forks that have to be updated + /// (they're either destroyed, or their best entry is updated to earlier block). + BlockReverted(BTreeMap>>), } /// Single fork of list-based cache. @@ -333,6 +336,44 @@ impl> ListCache Ok(Some(operation)) } + /// When block is reverted. + pub fn on_block_revert>( + &self, + tx: &mut Tx, + reverted_block: &ComplexBlockId, + ) -> ClientResult> { + // can't revert finalized blocks + debug_assert!(self.best_finalized_block.number < reverted_block.number); + + // iterate all unfinalized forks and truncate/destroy if required + let mut updated = BTreeMap::new(); + for (index, fork) in self.unfinalized.iter().enumerate() { + // we only need to truncate fork if its head is ancestor of truncated block + if fork.head.valid_from.number < reverted_block.number { + continue; + } + + // we only need to truncate fork if its head is connected to truncated block + if !chain::is_connected_to_block(&self.storage, reverted_block, &fork.head.valid_from)? { + continue; + } + + let updated_fork = fork.truncate( + &self.storage, + tx, + reverted_block.number, + self.best_finalized_block.number, + )?; + updated.insert(index, updated_fork); + } + + // schedule commit operation and update meta + let operation = CommitOperation::BlockReverted(updated); + tx.update_meta(self.best_finalized_entry.as_ref(), &self.unfinalized, &operation); + + Ok(operation) + } + /// When transaction is committed. pub fn on_transaction_commit(&mut self, op: CommitOperation) { match op { @@ -366,6 +407,14 @@ impl> ListCache self.unfinalized.remove(*fork_index); } }, + CommitOperation::BlockReverted(forks) => { + for (fork_index, updated_fork) in forks.into_iter().rev() { + match updated_fork { + Some(updated_fork) => self.unfinalized[fork_index] = updated_fork, + None => { self.unfinalized.remove(fork_index); }, + } + } + }, } } @@ -533,6 +582,43 @@ impl Fork { best_finalized_block, ) } + + /// Truncate fork by deleting all entries that are descendants of given block. + pub fn truncate, Tx: StorageTransaction>( + &self, + storage: &S, + tx: &mut Tx, + reverting_block: NumberFor, + best_finalized_block: NumberFor, + ) -> ClientResult>> { + let mut current = self.head.valid_from.clone(); + loop { + // read pointer to previous entry + let entry = storage.require_entry(¤t)?; + + // truncation stops when we have reached the ancestor of truncated block + if current.number < reverting_block { + // if we have reached finalized block => destroy fork + if chain::is_finalized_block(storage, ¤t, best_finalized_block)? { + return Ok(None); + } + + // else fork needs to be updated + return Ok(Some(Fork { + best_block: None, + head: entry.into_entry(current), + })); + } + + tx.remove_storage_entry(¤t); + + // truncation also stops when there are no more entries in the list + current = match entry.prev_valid_from { + Some(prev_valid_from) => prev_valid_from, + None => return Ok(None), + }; + } + } } /// Destroy fork by deleting all unfinalized entries. @@ -1400,4 +1486,57 @@ pub mod tests { do_test(PruningStrategy::ByDepth(10)); do_test(PruningStrategy::NeverPrune) } + + #[test] + fn revert_block_works() { + // 1 -> (2) -> 3 -> 4 -> 5 + // \ + // -> 5'' + // \ + // -> (3') -> 4' -> 5' + let mut cache = ListCache::new( + DummyStorage::new() + .with_meta(Some(correct_id(1)), vec![correct_id(5), fork_id(1, 2, 5), fork_id(2, 4, 5)]) + .with_id(1, correct_id(1).hash) + .with_entry(correct_id(1), StorageEntry { prev_valid_from: None, value: 1 }) + .with_entry(correct_id(3), StorageEntry { prev_valid_from: Some(correct_id(1)), value: 3 }) + .with_entry(correct_id(4), StorageEntry { prev_valid_from: Some(correct_id(3)), value: 4 }) + .with_entry(correct_id(5), StorageEntry { prev_valid_from: Some(correct_id(4)), value: 5 }) + .with_entry(fork_id(1, 2, 4), StorageEntry { prev_valid_from: Some(correct_id(1)), value: 14 }) + .with_entry(fork_id(1, 2, 5), StorageEntry { prev_valid_from: Some(fork_id(1, 2, 4)), value: 15 }) + .with_entry(fork_id(2, 4, 5), StorageEntry { prev_valid_from: Some(correct_id(4)), value: 25 }) + .with_header(test_header(1)) + .with_header(test_header(2)) + .with_header(test_header(3)) + .with_header(test_header(4)) + .with_header(test_header(5)) + .with_header(fork_header(1, 2, 3)) + .with_header(fork_header(1, 2, 4)) + .with_header(fork_header(1, 2, 5)) + .with_header(fork_header(2, 4, 5)), + PruningStrategy::ByDepth(1024), correct_id(1) + ); + + // when 5 is reverted: entry 5 is truncated + let op = cache.on_block_revert(&mut DummyTransaction::new(), &correct_id(5)).unwrap(); + assert_eq!(op, CommitOperation::BlockReverted(vec![ + (0, Some(Fork { best_block: None, head: Entry { valid_from: correct_id(4), value: 4 } })), + ].into_iter().collect())); + cache.on_transaction_commit(op); + + // when 3 is reverted: entries 4+5' are truncated + let op = cache.on_block_revert(&mut DummyTransaction::new(), &correct_id(3)).unwrap(); + assert_eq!(op, CommitOperation::BlockReverted(vec![ + (0, None), + (2, None), + ].into_iter().collect())); + cache.on_transaction_commit(op); + + // when 2 is reverted: entries 4'+5' are truncated + let op = cache.on_block_revert(&mut DummyTransaction::new(), &correct_id(2)).unwrap(); + assert_eq!(op, CommitOperation::BlockReverted(vec![ + (0, None), + ].into_iter().collect())); + cache.on_transaction_commit(op); + } } diff --git a/core/client/db/src/cache/list_storage.rs b/core/client/db/src/cache/list_storage.rs index a7bfc4dd58..4fd9ecaced 100644 --- a/core/client/db/src/cache/list_storage.rs +++ b/core/client/db/src/cache/list_storage.rs @@ -227,6 +227,14 @@ mod meta { unfinalized.remove(*fork_index); } }, + CommitOperation::BlockReverted(ref forks) => { + for (fork_index, updated_fork) in forks.iter().rev() { + match updated_fork { + Some(updated_fork) => unfinalized[*fork_index] = &updated_fork.head().valid_from, + None => { unfinalized.remove(*fork_index); }, + } + } + }, } (finalized, unfinalized).encode() diff --git a/core/client/db/src/cache/mod.rs b/core/client/db/src/cache/mod.rs index 6f7d1bf47d..bfc496dd2f 100644 --- a/core/client/db/src/cache/mod.rs +++ b/core/client/db/src/cache/mod.rs @@ -268,6 +268,27 @@ impl<'a, Block: BlockT> DbCacheTransaction<'a, Block> { Ok(self) } + + /// When block is reverted. + pub fn on_block_revert( + mut self, + reverted_block: &ComplexBlockId, + ) -> ClientResult { + for (name, cache) in self.cache.cache_at.iter() { + let op = cache.on_block_revert( + &mut self::list_storage::DbStorageTransaction::new( + cache.storage(), + &mut self.tx + ), + reverted_block, + )?; + + assert!(!self.cache_at_op.contains_key(name)); + self.cache_at_op.insert(name.to_owned(), op); + } + + Ok(self) + } } /// Synchronous implementation of database-backed blockchain data cache. diff --git a/core/client/db/src/lib.rs b/core/client/db/src/lib.rs index 1f7fa604a4..0f765506a3 100644 --- a/core/client/db/src/lib.rs +++ b/core/client/db/src/lib.rs @@ -1518,6 +1518,12 @@ impl client::backend::Backend for Backend whe impl client::backend::LocalBackend for Backend where Block: BlockT {} +/// TODO: remove me in #3201 +pub fn unused_sink(cache_tx: crate::cache::DbCacheTransaction) { + cache_tx.on_block_revert(&crate::cache::ComplexBlockId::new(Default::default(), 0.into())).unwrap(); + unimplemented!() +} + #[cfg(test)] mod tests { use hash_db::{HashDB, EMPTY_PREFIX}; -- GitLab From 4f25b470dd682e7820e95322de35b914de6f65c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Fri, 18 Oct 2019 18:07:41 +0100 Subject: [PATCH 237/275] grandpa: pluggable voting rules (#3673) * grandpa: support pluggable custom voting rules * grandpa: add docs to grandpa voting rule * grandpa: make voting rule mandatory * grandpa: add test for voting rule * node: add GRANDPA voting rule * grandpa: pass backend to VotingRule * core: fix docs in SelectChain::finality_target * grandpa: implement 3/4 of unfinalized chain restriction as voting rule * grandpa: rename AlwaysBehindBestBlock voting rule * grandpa: fix tests * grandpa: remove useless test * grandpa: extend environemnt voting rule test * grandpa: add proofs to unreachable statements * grandpa: fix typo * grandpa: fix docs --- core/consensus/common/src/select_chain.rs | 5 +- core/finality-grandpa/src/environment.rs | 85 ++++--- core/finality-grandpa/src/lib.rs | 35 ++- core/finality-grandpa/src/tests.rs | 142 ++++++++++-- core/finality-grandpa/src/voting_rule.rs | 270 ++++++++++++++++++++++ node-template/src/service.rs | 1 + node/cli/src/service.rs | 1 + 7 files changed, 471 insertions(+), 68 deletions(-) create mode 100644 core/finality-grandpa/src/voting_rule.rs diff --git a/core/consensus/common/src/select_chain.rs b/core/consensus/common/src/select_chain.rs index cae28656a1..e696db6b87 100644 --- a/core/consensus/common/src/select_chain.rs +++ b/core/consensus/common/src/select_chain.rs @@ -42,8 +42,9 @@ pub trait SelectChain: Sync + Send + Clone { /// best chain to author new blocks upon and probably finalize. fn best_chain(&self) -> Result<::Header, Error>; - /// Get the best ancestor of `target_hash` that we should attempt - /// to finalize next. + /// Get the best descendent of `target_hash` that we should attempt to + /// finalize next, if any. It is valid to return the given `target_hash` + /// itself if no better descendent exists. fn finality_target( &self, target_hash: ::Hash, diff --git a/core/finality-grandpa/src/environment.rs b/core/finality-grandpa/src/environment.rs index 70e45848be..ee146c4608 100644 --- a/core/finality-grandpa/src/environment.rs +++ b/core/finality-grandpa/src/environment.rs @@ -52,6 +52,7 @@ use crate::authorities::{AuthoritySet, SharedAuthoritySet}; use crate::consensus_changes::SharedConsensusChanges; use crate::justification::GrandpaJustification; use crate::until_imported::UntilVoteTargetImported; +use crate::voting_rule::VotingRule; use fg_primitives::{AuthorityId, AuthoritySignature, SetId, RoundNumber}; type HistoricalVotes = grandpa::HistoricalVotes< @@ -368,7 +369,7 @@ impl SharedVoterSetState { } /// The environment we run GRANDPA in. -pub(crate) struct Environment, RA, SC> { +pub(crate) struct Environment, RA, SC, VR> { pub(crate) inner: Arc>, pub(crate) select_chain: SC, pub(crate) voters: Arc>, @@ -378,9 +379,10 @@ pub(crate) struct Environment, RA, SC> { pub(crate) network: crate::communication::NetworkBridge, pub(crate) set_id: SetId, pub(crate) voter_set_state: SharedVoterSetState, + pub(crate) voting_rule: VR, } -impl, RA, SC> Environment { +impl, RA, SC, VR> Environment { /// Updates the voter set state using the given closure. The write lock is /// held during evaluation of the closure and the environment's voter set /// state is set to its result if successful. @@ -396,16 +398,18 @@ impl, RA, SC> Environment, B, E, N, RA, SC> +impl, B, E, N, RA, SC, VR> grandpa::Chain> -for Environment +for Environment where Block: 'static, B: Backend + 'static, - E: CallExecutor + 'static, + E: CallExecutor + Send + Sync + 'static, N: Network + 'static, N::In: 'static, SC: SelectChain + 'static, + VR: VotingRule>, + RA: Send + Sync, NumberFor: BlockNumberOps, { fn ancestry(&self, base: Block::Hash, block: Block::Hash) -> Result, GrandpaError> { @@ -429,7 +433,7 @@ where debug!(target: "afg", "Finding best chain containing block {:?} with number limit {:?}", block, limit); match self.select_chain.finality_target(block, None) { - Ok(Some(mut best_hash)) => { + Ok(Some(best_hash)) => { let base_header = self.inner.header(&BlockId::Hash(block)).ok()? .expect("Header known to exist after `best_containing` call; qed"); @@ -445,35 +449,51 @@ where } } - let mut best_header = self.inner.header(&BlockId::Hash(best_hash)).ok()? + let best_header = self.inner.header(&BlockId::Hash(best_hash)).ok()? .expect("Header known to exist after `best_containing` call; qed"); - // we target a vote towards 3/4 of the unfinalized chain (rounding up) - let target = { - let two = NumberFor::::one() + One::one(); - let three = two + One::one(); - let four = three + One::one(); - - let diff = *best_header.number() - *base_header.number(); - let diff = ((diff * three) + two) / four; + // check if our vote is currently being limited due to a pending change + let limit = limit.filter(|limit| limit < best_header.number()); + let target; + + let target_header = if let Some(target_number) = limit { + let mut target_header = best_header.clone(); + + // walk backwards until we find the target block + loop { + if *target_header.number() < target_number { + unreachable!( + "we are traversing backwards from a known block; \ + blocks are stored contiguously; \ + qed" + ); + } + + if *target_header.number() == target_number { + break; + } + + target_header = self.inner.header(&BlockId::Hash(*target_header.parent_hash())).ok()? + .expect("Header known to exist after `best_containing` call; qed"); + } - *base_header.number() + diff + target = target_header; + &target + } else { + // otherwise just use the given best as the target + &best_header }; - // unless our vote is currently being limited due to a pending change - let target = limit.map(|limit| limit.min(target)).unwrap_or(target); - - // walk backwards until we find the target block - loop { - if *best_header.number() < target { unreachable!(); } - if *best_header.number() == target { - return Some((best_hash, *best_header.number())); - } - - best_hash = *best_header.parent_hash(); - best_header = self.inner.header(&BlockId::Hash(best_hash)).ok()? - .expect("Header known to exist after `best_containing` call; qed"); - } + // restrict vote according to the given voting rule, if the + // voting rule doesn't restrict the vote then we keep the + // previous target. + // + // note that we pass the original `best_header`, i.e. before the + // authority set limit filter, which can be considered a + // mandatory/implicit voting rule. + self.voting_rule + .restrict_vote(&*self.inner, &base_header, &best_header, target_header) + .or(Some((target_header.hash(), *target_header.number()))) }, Ok(None) => { debug!(target: "afg", "Encountered error finding best chain containing {:?}: couldn't find target block", block); @@ -519,9 +539,9 @@ pub(crate) fn ancestry, E, RA>( Ok(tree_route.retracted().iter().skip(1).map(|e| e.hash).collect()) } -impl, N, RA, SC> +impl, N, RA, SC, VR> voter::Environment> -for Environment +for Environment where Block: 'static, B: Backend + 'static, @@ -530,6 +550,7 @@ where N::In: 'static + Send, RA: 'static + Send + Sync, SC: SelectChain + 'static, + VR: VotingRule>, NumberFor: BlockNumberOps, { type Timer = Box + Send>; diff --git a/core/finality-grandpa/src/lib.rs b/core/finality-grandpa/src/lib.rs index e4b71acbec..3841084d11 100644 --- a/core/finality-grandpa/src/lib.rs +++ b/core/finality-grandpa/src/lib.rs @@ -92,11 +92,15 @@ mod justification; mod light_import; mod observer; mod until_imported; +mod voting_rule; pub use communication::Network; pub use finality_proof::FinalityProofProvider; pub use light_import::light_block_import; pub use observer::run_grandpa_observer; +pub use voting_rule::{ + BeforeBestBlock, ThreeQuartersOfTheUnfinalizedChain, VotingRule, VotingRulesBuilder +}; use aux_schema::PersistentData; use environment::{Environment, VoterSetState}; @@ -466,7 +470,7 @@ fn register_finality_tracker_inherent_data_provider, N, RA, SC, X> { +pub struct GrandpaParams, N, RA, SC, VR, X> { /// Configuration for the GRANDPA service. pub config: Config, /// A link to the block import worker. @@ -479,12 +483,14 @@ pub struct GrandpaParams, N, RA, SC, X> { pub on_exit: X, /// If supplied, can be used to hook on telemetry connection established events. pub telemetry_on_connect: Option>, + /// A voting rule used to potentially restrict target votes. + pub voting_rule: VR, } /// Run a GRANDPA voter as a task. Provide configuration and a link to a /// block import worker that has already been instantiated with `block_import`. -pub fn run_grandpa_voter, N, RA, SC, X>( - grandpa_params: GrandpaParams, +pub fn run_grandpa_voter, N, RA, SC, VR, X>( + grandpa_params: GrandpaParams, ) -> client::error::Result + Send + 'static> where Block::Hash: Ord, B: Backend + 'static, @@ -492,6 +498,7 @@ pub fn run_grandpa_voter, N, RA, SC, X>( N: Network + Send + Sync + 'static, N::In: Send + 'static, SC: SelectChain + 'static, + VR: VotingRule> + Clone + 'static, NumberFor: BlockNumberOps, DigestFor: Encode, RA: Send + Sync + 'static, @@ -504,6 +511,7 @@ pub fn run_grandpa_voter, N, RA, SC, X>( inherent_data_providers, on_exit, telemetry_on_connect, + voting_rule, } = grandpa_params; let LinkHalf { @@ -556,8 +564,9 @@ pub fn run_grandpa_voter, N, RA, SC, X>( config, network, select_chain, + voting_rule, persistent_data, - voter_commands_rx + voter_commands_rx, ); let voter_work = voter_work @@ -578,13 +587,13 @@ pub fn run_grandpa_voter, N, RA, SC, X>( /// Future that powers the voter. #[must_use] -struct VoterWork, RA, SC> { +struct VoterWork, RA, SC, VR> { voter: Box>> + Send>, - env: Arc>, + env: Arc>, voter_commands_rx: mpsc::UnboundedReceiver>>, } -impl VoterWork +impl VoterWork where Block: BlockT, N: Network + Sync, @@ -594,12 +603,14 @@ where E: CallExecutor + Send + Sync + 'static, B: Backend + 'static, SC: SelectChain + 'static, + VR: VotingRule> + Clone + 'static, { fn new( client: Arc>, config: Config, network: NetworkBridge, select_chain: SC, + voting_rule: VR, persistent_data: PersistentData, voter_commands_rx: mpsc::UnboundedReceiver>>, ) -> Self { @@ -608,6 +619,7 @@ where let env = Arc::new(Environment { inner: client, select_chain, + voting_rule, voters: Arc::new(voters), config, network, @@ -731,6 +743,7 @@ where authority_set: self.env.authority_set.clone(), consensus_changes: self.env.consensus_changes.clone(), network: self.env.network.clone(), + voting_rule: self.env.voting_rule.clone(), }); self.rebuild_voter(); @@ -755,7 +768,7 @@ where } } -impl Future for VoterWork +impl Future for VoterWork where Block: BlockT, N: Network + Sync, @@ -765,6 +778,7 @@ where E: CallExecutor + Send + Sync + 'static, B: Backend + 'static, SC: SelectChain + 'static, + VR: VotingRule> + Clone + 'static, { type Item = (); type Error = Error; @@ -809,8 +823,8 @@ where } #[deprecated(since = "1.1", note = "Please switch to run_grandpa_voter.")] -pub fn run_grandpa, N, RA, SC, X>( - grandpa_params: GrandpaParams, +pub fn run_grandpa, N, RA, SC, VR, X>( + grandpa_params: GrandpaParams, ) -> ::client::error::Result + Send + 'static> where Block::Hash: Ord, B: Backend + 'static, @@ -821,6 +835,7 @@ pub fn run_grandpa, N, RA, SC, X>( NumberFor: BlockNumberOps, DigestFor: Encode, RA: Send + Sync + 'static, + VR: VotingRule> + Clone + 'static, X: Future + Clone + Send + 'static, { run_grandpa_voter(grandpa_params) diff --git a/core/finality-grandpa/src/tests.rs b/core/finality-grandpa/src/tests.rs index 1957ab5c4f..7f4a0d053a 100644 --- a/core/finality-grandpa/src/tests.rs +++ b/core/finality-grandpa/src/tests.rs @@ -385,6 +385,7 @@ fn run_to_completion_with( inherent_data_providers: InherentDataProviders::new(), on_exit: Exit, telemetry_on_connect: None, + voting_rule: (), }; let voter = run_grandpa_voter(grandpa_params).expect("all in order with client and network"); @@ -516,6 +517,7 @@ fn finalize_3_voters_1_full_observer() { inherent_data_providers: InherentDataProviders::new(), on_exit: Exit, telemetry_on_connect: None, + voting_rule: (), }; let voter = run_grandpa_voter(grandpa_params).expect("all in order with client and network"); @@ -676,6 +678,7 @@ fn transition_3_voters_twice_1_full_observer() { inherent_data_providers: InherentDataProviders::new(), on_exit: Exit, telemetry_on_connect: None, + voting_rule: (), }; let voter = run_grandpa_voter(grandpa_params).expect("all in order with client and network"); @@ -861,30 +864,6 @@ fn finalizes_multiple_pending_changes_in_order() { run_to_completion(&mut runtime, 30, net.clone(), all_peers); } -#[test] -fn doesnt_vote_on_the_tip_of_the_chain() { - let mut runtime = current_thread::Runtime::new().unwrap(); - let peers_a = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; - let voters = make_ids(peers_a); - let api = TestApi::new(voters); - let mut net = GrandpaTestNet::new(api, 3); - - // add 100 blocks - net.peer(0).push_blocks(100, false); - net.block_until_sync(&mut runtime); - - for i in 0..3 { - assert_eq!(net.peer(i).client().info().chain.best_number, 100, - "Peer #{} failed to sync", i); - } - - let net = Arc::new(Mutex::new(net)); - let highest = run_to_completion(&mut runtime, 75, net.clone(), peers_a); - - // the highest block to be finalized will be 3/4 deep in the unfinalized chain - assert_eq!(highest, 75); -} - #[test] fn force_change_to_new_set() { let _ = env_logger::try_init(); @@ -1122,6 +1101,7 @@ fn voter_persists_its_votes() { inherent_data_providers: InherentDataProviders::new(), on_exit: Exit, telemetry_on_connect: None, + voting_rule: VotingRulesBuilder::default().build(), }; let voter = run_grandpa_voter(grandpa_params) @@ -1452,6 +1432,7 @@ fn voter_catches_up_to_latest_round_when_behind() { inherent_data_providers: InherentDataProviders::new(), on_exit: Exit, telemetry_on_connect: None, + voting_rule: (), }; Box::new(run_grandpa_voter(grandpa_params).expect("all in order with client and network")) @@ -1533,3 +1514,116 @@ fn voter_catches_up_to_latest_round_when_behind() { let drive_to_completion = futures::future::poll_fn(|| { net.lock().poll(); Ok(Async::NotReady) }); let _ = runtime.block_on(test.select(drive_to_completion).map_err(|_| ())).unwrap(); } + +#[test] +fn grandpa_environment_respects_voting_rules() { + use grandpa::Chain; + use network::test::TestClient; + + let peers = &[Ed25519Keyring::Alice]; + let voters = make_ids(peers); + + let mut net = GrandpaTestNet::new(TestApi::new(voters), 1); + let peer = net.peer(0); + let network_service = peer.network_service().clone(); + let link = peer.data.lock().take().unwrap(); + + // create a voter environment with a given voting rule + let environment = |voting_rule: Box>| { + let PersistentData { + ref authority_set, + ref consensus_changes, + ref set_state, + .. + } = link.persistent_data; + + let config = Config { + gossip_duration: TEST_GOSSIP_DURATION, + justification_period: 32, + keystore: None, + name: None, + }; + + let (network, _) = NetworkBridge::new( + network_service.clone(), + config.clone(), + set_state.clone(), + Exit, + true, + ); + + Environment { + authority_set: authority_set.clone(), + config: config.clone(), + consensus_changes: consensus_changes.clone(), + inner: link.client.clone(), + select_chain: link.select_chain.clone(), + set_id: authority_set.set_id(), + voter_set_state: set_state.clone(), + voters: Arc::new(authority_set.current_authorities()), + network, + voting_rule, + } + }; + + // add 20 blocks + peer.push_blocks(20, false); + + // create an environment with no voting rule restrictions + let unrestricted_env = environment(Box::new(())); + + // another with 3/4 unfinalized chain voting rule restriction + let three_quarters_env = environment(Box::new( + voting_rule::ThreeQuartersOfTheUnfinalizedChain + )); + + // and another restricted with the default voting rules: i.e. 3/4 rule and + // always below best block + let default_env = environment(Box::new( + VotingRulesBuilder::default().build() + )); + + // the unrestricted environment should just return the best block + assert_eq!( + unrestricted_env.best_chain_containing( + peer.client().info().chain.finalized_hash + ).unwrap().1, + 20, + ); + + // both the other environments should return block 15, which is 3/4 of the + // way in the unfinalized chain + assert_eq!( + three_quarters_env.best_chain_containing( + peer.client().info().chain.finalized_hash + ).unwrap().1, + 15, + ); + + assert_eq!( + default_env.best_chain_containing( + peer.client().info().chain.finalized_hash + ).unwrap().1, + 15, + ); + + // we finalize block 19 with block 20 being the best block + peer.client().finalize_block(BlockId::Number(19), None, false).unwrap(); + + // the 3/4 environment should propose block 20 for voting + assert_eq!( + three_quarters_env.best_chain_containing( + peer.client().info().chain.finalized_hash + ).unwrap().1, + 20, + ); + + // while the default environment will always still make sure we don't vote + // on the best block + assert_eq!( + default_env.best_chain_containing( + peer.client().info().chain.finalized_hash + ).unwrap().1, + 19, + ); +} diff --git a/core/finality-grandpa/src/voting_rule.rs b/core/finality-grandpa/src/voting_rule.rs new file mode 100644 index 0000000000..355fa0cd2d --- /dev/null +++ b/core/finality-grandpa/src/voting_rule.rs @@ -0,0 +1,270 @@ +// Copyright 2018-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Handling custom voting rules for GRANDPA. +//! +//! This exposes the `VotingRule` trait used to implement arbitrary voting +//! restrictions that are taken into account by the GRANDPA environment when +//! selecting a finality target to vote on. + +use std::sync::Arc; + +use client::blockchain::HeaderBackend; +use sr_primitives::generic::BlockId; +use sr_primitives::traits::{Block as BlockT, Header, NumberFor, One, Zero}; + +/// A trait for custom voting rules in GRANDPA. +pub trait VotingRule: Send + Sync where + Block: BlockT, + B: HeaderBackend, +{ + /// Restrict the given `current_target` vote, returning the block hash and + /// number of the block to vote on, and `None` in case the vote should not + /// be restricted. `base` is the block that we're basing our votes on in + /// order to pick our target (e.g. last round estimate), and `best_target` + /// is the initial best vote target before any vote rules were applied. When + /// applying multiple `VotingRule`s both `base` and `best_target` should + /// remain unchanged. + /// + /// The contract of this interface requires that when restricting a vote, the + /// returned value **must** be an ancestor of the given `current_target`, + /// this also means that a variant must be maintained throughout the + /// execution of voting rules wherein `current_target <= best_target`. + fn restrict_vote( + &self, + backend: &B, + base: &Block::Header, + best_target: &Block::Header, + current_target: &Block::Header, + ) -> Option<(Block::Hash, NumberFor)>; +} + +impl VotingRule for () where + Block: BlockT, + B: HeaderBackend, +{ + fn restrict_vote( + &self, + _backend: &B, + _base: &Block::Header, + _best_target: &Block::Header, + _current_target: &Block::Header, + ) -> Option<(Block::Hash, NumberFor)> { + None + } +} + +/// A custom voting rule that guarantees that our vote is always behind the best +/// block, in the best case exactly one block behind it. +#[derive(Clone)] +pub struct BeforeBestBlock; +impl VotingRule for BeforeBestBlock where + Block: BlockT, + B: HeaderBackend, +{ + fn restrict_vote( + &self, + _backend: &B, + _base: &Block::Header, + best_target: &Block::Header, + current_target: &Block::Header, + ) -> Option<(Block::Hash, NumberFor)> { + if current_target.number().is_zero() { + return None; + } + + if current_target.number() == best_target.number() { + return Some(( + current_target.parent_hash().clone(), + *current_target.number() - One::one(), + )); + } + + None + } +} + +/// A custom voting rule that limits votes towards 3/4 of the unfinalized chain, +/// using the given `base` and `best_target` to figure where the 3/4 target +/// should fall. +pub struct ThreeQuartersOfTheUnfinalizedChain; + +impl VotingRule for ThreeQuartersOfTheUnfinalizedChain where + Block: BlockT, + B: HeaderBackend, +{ + fn restrict_vote( + &self, + backend: &B, + base: &Block::Header, + best_target: &Block::Header, + current_target: &Block::Header, + ) -> Option<(Block::Hash, NumberFor)> { + // target a vote towards 3/4 of the unfinalized chain (rounding up) + let target_number = { + let two = NumberFor::::one() + One::one(); + let three = two + One::one(); + let four = three + One::one(); + + let diff = *best_target.number() - *base.number(); + let diff = ((diff * three) + two) / four; + + *base.number() + diff + }; + + // our current target is already lower than this rule would restrict + if target_number >= *current_target.number() { + return None; + } + + let mut target_header = current_target.clone(); + let mut target_hash = current_target.hash(); + + // walk backwards until we find the target block + loop { + if *target_header.number() < target_number { + unreachable!( + "we are traversing backwards from a known block; \ + blocks are stored contiguously; \ + qed" + ); + } + if *target_header.number() == target_number { + return Some((target_hash, target_number)); + } + + target_hash = *target_header.parent_hash(); + target_header = backend.header(BlockId::Hash(target_hash)).ok()? + .expect("Header known to exist due to the existence of one of its descendents; qed"); + } + } +} + +struct VotingRules { + rules: Arc>>>, +} + +impl Clone for VotingRules { + fn clone(&self) -> Self { + VotingRules { + rules: self.rules.clone(), + } + } +} + +impl VotingRule for VotingRules where + Block: BlockT, + B: HeaderBackend, +{ + fn restrict_vote( + &self, + backend: &B, + base: &Block::Header, + best_target: &Block::Header, + current_target: &Block::Header, + ) -> Option<(Block::Hash, NumberFor)> { + let restricted_target = self.rules.iter().fold( + current_target.clone(), + |current_target, rule| { + rule.restrict_vote( + backend, + base, + best_target, + ¤t_target, + ) + .and_then(|(hash, _)| backend.header(BlockId::Hash(hash)).ok()) + .and_then(std::convert::identity) + .unwrap_or(current_target) + }, + ); + + let restricted_hash = restricted_target.hash(); + + if restricted_hash != current_target.hash() { + Some((restricted_hash, *restricted_target.number())) + } else { + None + } + } +} + +/// A builder of a composite voting rule that applies a set of rules to +/// progressively restrict the vote. +pub struct VotingRulesBuilder { + rules: Vec>>, +} + +impl Default for VotingRulesBuilder where + Block: BlockT, + B: HeaderBackend, +{ + fn default() -> Self { + VotingRulesBuilder::new() + .add(BeforeBestBlock) + .add(ThreeQuartersOfTheUnfinalizedChain) + } +} + +impl VotingRulesBuilder where + Block: BlockT, + B: HeaderBackend, +{ + /// Return a new voting rule builder using the given backend. + pub fn new() -> Self { + VotingRulesBuilder { + rules: Vec::new(), + } + } + + /// Add a new voting rule to the builder. + pub fn add(mut self, rule: R) -> Self where + R: VotingRule + 'static, + { + self.rules.push(Box::new(rule)); + self + } + + /// Add all given voting rules to the builder. + pub fn add_all(mut self, rules: I) -> Self where + I: IntoIterator>>, + { + self.rules.extend(rules); + self + } + + /// Return a new `VotingRule` that applies all of the previously added + /// voting rules in-order. + pub fn build(self) -> impl VotingRule + Clone { + VotingRules { + rules: Arc::new(self.rules), + } + } +} + +impl VotingRule for Box> where + Block: BlockT, + B: HeaderBackend, +{ + fn restrict_vote( + &self, + backend: &B, + base: &Block::Header, + best_target: &Block::Header, + current_target: &Block::Header, + ) -> Option<(Block::Hash, NumberFor)> { + (**self).restrict_vote(backend, base, best_target, current_target) + } +} diff --git a/node-template/src/service.rs b/node-template/src/service.rs index 64a453e298..7934355812 100644 --- a/node-template/src/service.rs +++ b/node-template/src/service.rs @@ -149,6 +149,7 @@ pub fn new_full(config: Configuration Date: Sat, 19 Oct 2019 08:36:43 +0100 Subject: [PATCH 238/275] Move sr-arithmetic to a new crate and add in a fuzzer (#3799) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Split up sr_arithmetic.rs * Add some basic fuzzing * Add more tests * Add printing to fuzzing * Clean things up * Remove arbitrary * Remove comments * More cleaning, fix small error that was causing a panic * Add rational128 * Remove old random tests * introduce panic * fuzzing should panic properly * Bit of cleanup * Add a test uncovered via fuzzing that fails! * Few small changes * Move sr-arithmetic to its own crate * Fix fuzzing * Got rid of fuzzer Cargo.lock * Added no_std * re-export assert_eq_error_rate * bump impl and spec version * re add convert into * Add an ignore to the test * Enabled benchmarking * Reindent * Clean up biguint fuzzer * Clean up biguint more * shuffle sr-primitives/traits about * Remove unused dependencies * Apply clippy suggestions * upgrade primitive-types versions * Run tests against num-bigint * Get rid of allocation in assert_biguints_eq * Add an optimisation to multiply_by_rational * rename parts_per_x -> per_things * Change fuzzer cargo.toml * Remove allocation from BigUint PartialEq impl * Remove accidental indentation * Renmove Lazy and Convert traits * Copy assert_eq_error_rate macro back to sr-primitives * Add documentation to fuzzers * fix sr-primitives assert_eq_error_rate * add cfg(test) * Update core/sr-arithmetic/src/traits.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update core/sr-arithmetic/src/traits.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update core/sr-arithmetic/fuzzer/src/biguint.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Allow rounding up in rational128 * Make changes to biguint.rs * Update core/sr-arithmetic/src/traits.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Final touches * Convert to num_bigint::BigUint to compare * remove unused mut * more small changes * shuffle sr-primitives trait imports * more code review * move assert_eq_error_rate to lib.rs * Update core/sr-arithmetic/fuzzer/src/biguint.rs Co-Authored-By: Bastian Köcher * Get rid of S * Simplify rational128 honggfuzz link * Insignificantly change rational128 fuzzing code * Slightly tidy up some of the arithmetic logic * Get rid of sr_arithmetic again(?) and fix sr-primitives/weights * Apply updates to sr_arithmetic.rs to crate --- Cargo.lock | 78 +- Cargo.toml | 2 + core/sr-arithmetic/Cargo.toml | 26 + core/sr-arithmetic/fuzzer/.gitignore | 2 + core/sr-arithmetic/fuzzer/Cargo.toml | 20 + core/sr-arithmetic/fuzzer/src/biguint.rs | 181 ++ core/sr-arithmetic/fuzzer/src/rational128.rs | 77 + core/sr-arithmetic/src/biguint.rs | 809 +++++++ core/sr-arithmetic/src/fixed64.rs | 233 ++ core/sr-arithmetic/src/helpers_128bit.rs | 112 + core/sr-arithmetic/src/lib.rs | 48 + core/sr-arithmetic/src/per_things.rs | 519 +++++ core/sr-arithmetic/src/rational128.rs | 384 +++ core/sr-arithmetic/src/traits.rs | 143 ++ core/sr-primitives/Cargo.toml | 6 +- core/sr-primitives/src/lib.rs | 9 +- core/sr-primitives/src/sr_arithmetic.rs | 2203 ------------------ core/sr-primitives/src/traits.rs | 126 +- core/sr-primitives/src/weights.rs | 2 +- node/runtime/src/lib.rs | 2 +- 20 files changed, 2643 insertions(+), 2339 deletions(-) create mode 100644 core/sr-arithmetic/Cargo.toml create mode 100644 core/sr-arithmetic/fuzzer/.gitignore create mode 100644 core/sr-arithmetic/fuzzer/Cargo.toml create mode 100644 core/sr-arithmetic/fuzzer/src/biguint.rs create mode 100644 core/sr-arithmetic/fuzzer/src/rational128.rs create mode 100644 core/sr-arithmetic/src/biguint.rs create mode 100644 core/sr-arithmetic/src/fixed64.rs create mode 100644 core/sr-arithmetic/src/helpers_128bit.rs create mode 100644 core/sr-arithmetic/src/lib.rs create mode 100644 core/sr-arithmetic/src/per_things.rs create mode 100644 core/sr-arithmetic/src/rational128.rs create mode 100644 core/sr-arithmetic/src/traits.rs delete mode 100644 core/sr-primitives/src/sr_arithmetic.rs diff --git a/Cargo.lock b/Cargo.lock index 8cf8b42bd4..82a5ab2229 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -92,6 +92,11 @@ dependencies = [ "xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "arbitrary" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "arc-swap" version = "0.3.11" @@ -890,6 +895,17 @@ dependencies = [ "static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "fixed-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fixedbitset" version = "0.1.9" @@ -1263,6 +1279,16 @@ dependencies = [ "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "honggfuzz" +version = "0.5.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arbitrary 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "http" version = "0.1.18" @@ -2165,6 +2191,15 @@ dependencies = [ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "memmap" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "memoffset" version = "0.5.1" @@ -2995,6 +3030,16 @@ dependencies = [ "uint 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "primitive-types" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fixed-hash 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-codec 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "uint 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "proc-macro-crate" version = "0.1.4" @@ -3812,6 +3857,30 @@ dependencies = [ "trybuild 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sr-arithmetic" +version = "2.0.0" +dependencies = [ + "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-std 2.0.0", +] + +[[package]] +name = "sr-arithmetic-fuzzer" +version = "2.0.0" +dependencies = [ + "honggfuzz 0.5.45 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-arithmetic 2.0.0", +] + [[package]] name = "sr-io" version = "2.0.0" @@ -3833,15 +3902,13 @@ name = "sr-primitives" version = "2.0.0" dependencies = [ "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-arithmetic 2.0.0", "sr-io 2.0.0", "sr-std 2.0.0", "substrate-application-crypto 2.0.0", @@ -6696,6 +6763,7 @@ dependencies = [ "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" "checksum app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e73a24bad9bd6a94d6395382a6c69fe071708ae4409f763c5475e14ee896313d" +"checksum arbitrary 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "64cf76cb6e2222ed0ea86b2b0ee2f71c96ec6edd5af42e84d59160e91b836ec4" "checksum arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "bc4662175ead9cd84451d5c35070517777949a2ed84551764129cedb88384841" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" "checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" @@ -6788,6 +6856,7 @@ dependencies = [ "checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" "checksum finality-grandpa 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9681c1f75941ea47584573dd2bc10558b2067d460612945887e00744e43393be" "checksum fixed-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "516877b7b9a1cc2d0293cbce23cd6203f0edbfd4090e6ca4489fecb5aa73050e" +"checksum fixed-hash 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6357b15872f8126e4ea7cf79d579473f132ccd2de239494ad1bf4aa892faea68" "checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" "checksum flate2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ad3c5233c9a940c8719031b423d7e6c16af66e031cb0420b0896f5245bf181d3" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" @@ -6832,6 +6901,7 @@ dependencies = [ "checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" "checksum hmac-drbg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4fe727d41d2eec0a6574d887914347e5ff96a3b87177817e2a9820c5c87fecc2" "checksum hmac-drbg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" +"checksum honggfuzz 0.5.45 (registry+https://github.com/rust-lang/crates.io-index)" = "24c27b4aa3049d6d10d8e33d52c9d03ca9aec18f8a449b246f8c4a5b0c10fb34" "checksum http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "372bcb56f939e449117fb0869c2e8fd8753a8223d92a172c6e808cf123a5b6e4" "checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" @@ -6908,6 +6978,7 @@ dependencies = [ "checksum malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "35adee9ed962cf7d07d62cb58bc45029f3227f5b5b86246caa8632f06c187bc3" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" +"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" "checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f" "checksum memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ef49315991403ba5fa225a70399df5e115f57b274cb0b1b4bcd6e734fa5bd783" "checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" @@ -6970,6 +7041,7 @@ dependencies = [ "checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" "checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427" "checksum primitive-types 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "83ef7b3b965c0eadcb6838f34f827e1dfb2939bdd5ebd43f9647e009b12b0371" +"checksum primitive-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97b5a08dda18910f056e5c2060c034e77cab18e0bd7d895e44f03207af4c71d5" "checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" "checksum proc-macro-error 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aeccfe4d5d8ea175d5f0e4a2ad0637e0f4121d63bd99d356fb1f39ab2e7c6097" "checksum proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "114cdf1f426eb7f550f01af5f53a33c0946156f6814aec939b3bd77e844f9a9d" diff --git a/Cargo.toml b/Cargo.toml index 5b012be0e9..9d01fabc1e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,6 +53,8 @@ members = [ "core/service/test", "core/session", "core/sr-api-macros", + "core/sr-arithmetic", + "core/sr-arithmetic/fuzzer", "core/sr-io", "core/sr-primitives", "core/sr-staking-primitives", diff --git a/core/sr-arithmetic/Cargo.toml b/core/sr-arithmetic/Cargo.toml new file mode 100644 index 0000000000..d98404db94 --- /dev/null +++ b/core/sr-arithmetic/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "sr-arithmetic" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +num-traits = { version = "0.2.8", default-features = false } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +rstd = { package = "sr-std", path = "../sr-std", default-features = false } +integer-sqrt = "0.1.2" + +[dev-dependencies] +primitive-types = "0.6.0" +rand = "0.7.2" + +[features] +bench = [] +default = ["std"] +std = [ + "serde", + "num-traits/std", + "rstd/std", + "codec/std", +] diff --git a/core/sr-arithmetic/fuzzer/.gitignore b/core/sr-arithmetic/fuzzer/.gitignore new file mode 100644 index 0000000000..3ebcb104d4 --- /dev/null +++ b/core/sr-arithmetic/fuzzer/.gitignore @@ -0,0 +1,2 @@ +hfuzz_target +hfuzz_workspace diff --git a/core/sr-arithmetic/fuzzer/Cargo.toml b/core/sr-arithmetic/fuzzer/Cargo.toml new file mode 100644 index 0000000000..8838e60436 --- /dev/null +++ b/core/sr-arithmetic/fuzzer/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "sr-arithmetic-fuzzer" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +sr-arithmetic = { path = ".." } +honggfuzz = "0.5" +primitive-types = "0.6" +num-bigint = "0.2" +num-traits = "0.2" + +[[bin]] +name = "biguint" +path = "src/biguint.rs" + +[[bin]] +name = "rational128" +path = "src/rational128.rs" diff --git a/core/sr-arithmetic/fuzzer/src/biguint.rs b/core/sr-arithmetic/fuzzer/src/biguint.rs new file mode 100644 index 0000000000..bd270a97ca --- /dev/null +++ b/core/sr-arithmetic/fuzzer/src/biguint.rs @@ -0,0 +1,181 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! # Running +//! Running this fuzzer can be done with `cargo hfuzz run biguint`. `honggfuzz` CLI options can +//! be used by setting `HFUZZ_RUN_ARGS`, such as `-n 4` to use 4 threads. +//! +//! # Debugging a panic +//! Once a panic is found, it can be debugged with +//! `cargo hfuzz run-debug biguint hfuzz_workspace/biguint/*.fuzz`. +//! +//! # More infomation +//! More information about `honggfuzz` can be found +//! [here](https://docs.rs/honggfuzz/). + +use honggfuzz::fuzz; +use sr_arithmetic::biguint::{BigUint, Single}; +use std::convert::TryFrom; + +fn main() { + loop { + fuzz!(|data: (Vec, Vec, bool)| { + let (mut digits_u, mut digits_v, return_remainder) = data; + + let mut u = BigUint::from_limbs(&digits_u); + let mut v = BigUint::from_limbs(&digits_v); + + u.lstrip(); + v.lstrip(); + + let ue = u128::try_from(u.clone()); + let ve = u128::try_from(v.clone()); + + digits_u.reverse(); + digits_v.reverse(); + + let num_u = num_bigint::BigUint::new(digits_u.clone()); + let num_v = num_bigint::BigUint::new(digits_v.clone()); + + if check_digit_lengths(&u, &v, 4) { + assert_eq!(u.cmp(&v), ue.cmp(&ve)); + assert_eq!(u.eq(&v), ue.eq(&ve)); + } + + if check_digit_lengths(&u, &v, 3) { + let expected = ue.unwrap() + ve.unwrap(); + let t = u.clone().add(&v); + assert_eq!( + u128::try_from(t.clone()).unwrap(), expected, + "{:?} + {:?} ===> {:?} != {:?}", u, v, t, expected, + ); + } + + if check_digit_lengths(&u, &v, 4) { + let expected = ue.unwrap().checked_sub(ve.unwrap()); + let t = u.clone().sub(&v); + if expected.is_none() { + assert!(t.is_err()) + } else { + let t = t.unwrap(); + let expected = expected.unwrap(); + assert_eq!( + u128::try_from(t.clone()).unwrap(), expected, + "{:?} - {:?} ===> {:?} != {:?}", u, v, t, expected, + ); + } + } + + if check_digit_lengths(&u, &v, 2) { + let expected = ue.unwrap() * ve.unwrap(); + let t = u.clone().mul(&v); + assert_eq!( + u128::try_from(t.clone()).unwrap(), expected, + "{:?} * {:?} ===> {:?} != {:?}", u, v, t, expected, + ); + } + + if check_digit_lengths(&u, &v, 4) { + let (ue, ve) = (ue.unwrap(), ve.unwrap()); + if ve == 0 { + return; + } + let (q, r) = (ue / ve, ue % ve); + if let Some((qq, rr)) = u.clone().div(&v, true) { + assert_eq!( + u128::try_from(qq.clone()).unwrap(), q, + "{:?} / {:?} ===> {:?} != {:?}", u, v, qq, q, + ); + assert_eq!( + u128::try_from(rr.clone()).unwrap(), r, + "{:?} % {:?} ===> {:?} != {:?}", u, v, rr, r, + ); + } else if v.len() == 1 { + let qq = u.clone().div_unit(ve as Single); + assert_eq!( + u128::try_from(qq.clone()).unwrap(), q, + "[single] {:?} / {:?} ===> {:?} != {:?}", u, v, qq, q, + ); + } else if v.msb() != 0 && u.msb() != 0 && u.len() > v.len() { + panic!("div returned none for an unexpected reason"); + } + } + + // Test against num_bigint + + // Equality + + assert_eq!(u.cmp(&v), num_u.cmp(&num_v)); + + // Addition + + let w = u.clone().add(&v); + let num_w = num_u.clone() + &num_v; + + assert_biguints_eq(&w, &num_w); + + // Subtraction + + if let Ok(w) = u.clone().sub(&v) { + let num_w = num_u.clone() - &num_v; + + assert_biguints_eq(&w, &num_w); + } + + // Multiplication + + let w = u.clone().mul(&v); + let num_w = num_u.clone() * &num_v; + + assert_biguints_eq(&w, &num_w); + + // Division + + if v.len() == 1 && v.get(0) != 0 { + let w = u.clone().div_unit(v.get(0)); + let num_w = num_u.clone() / &num_v; + assert_biguints_eq(&w, &num_w); + } else if u.len() > v.len() && v.len() > 0 { + let num_remainder = num_u.clone() % num_v.clone(); + + let (w, remainder) = u.clone().div(&v, return_remainder).unwrap(); + let num_w = num_u.clone() / &num_v; + + assert_biguints_eq(&w, &num_w); + + if return_remainder { + assert_biguints_eq(&remainder, &num_remainder); + } + } + }); + } +} + +fn check_digit_lengths(u: &BigUint, v: &BigUint, max_limbs: usize) -> bool { + 1 <= u.len() && u.len() <= max_limbs && 1 <= v.len() && v.len() <= max_limbs +} + +fn assert_biguints_eq(a: &BigUint, b: &num_bigint::BigUint) { + let mut a = a.clone(); + a.lstrip(); + + // `num_bigint::BigUint` doesn't expose it's internals, so we need to convert into that to + // compare. + let limbs = (0 .. a.len()).map(|i| a.get(i)).collect(); + let num_a = num_bigint::BigUint::new(limbs); + + assert!(&num_a == b, "\narithmetic: {:?}\nnum-bigint: {:?}", a, b); +} diff --git a/core/sr-arithmetic/fuzzer/src/rational128.rs b/core/sr-arithmetic/fuzzer/src/rational128.rs new file mode 100644 index 0000000000..b2a00d7545 --- /dev/null +++ b/core/sr-arithmetic/fuzzer/src/rational128.rs @@ -0,0 +1,77 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! # Running +//! Running this fuzzer can be done with `cargo hfuzz run rational128`. `honggfuzz` CLI options can +//! be used by setting `HFUZZ_RUN_ARGS`, such as `-n 4` to use 4 threads. +//! +//! # Debugging a panic +//! Once a panic is found, it can be debugged with +//! `cargo hfuzz run-debug rational128 hfuzz_workspace/rational128/*.fuzz`. +//! +//! # More infomation +//! More information about `honggfuzz` can be found +//! [here](https://docs.rs/honggfuzz/). + +use honggfuzz::fuzz; +use sr_arithmetic::{helpers_128bit::multiply_by_rational, traits::Zero}; + +fn main() { + loop { + fuzz!(|data: ([u8; 16], [u8; 16], [u8; 16])| { + let (a_bytes, b_bytes, c_bytes) = data; + let (a, b, c) = ( + u128::from_be_bytes(a_bytes), + u128::from_be_bytes(b_bytes), + u128::from_be_bytes(c_bytes), + ); + + println!("++ Equation: {} * {} / {}", a, b, c); + + // The point of this fuzzing is to make sure that `multiply_by_rational` is 100% + // accurate as long as the value fits in a u128. + if let Ok(result) = multiply_by_rational(a, b, c) { + let truth = mul_div(a, b, c); + + if result != truth && result != truth + 1 { + println!("++ Expected {}", truth); + println!("+++++++ Got {}", result); + panic!(); + } + } + }) + } +} + +fn mul_div(a: u128, b: u128, c: u128) -> u128 { + use primitive_types::U256; + if a.is_zero() { + return Zero::zero(); + } + let c = c.max(1); + + // e for extended + let ae: U256 = a.into(); + let be: U256 = b.into(); + let ce: U256 = c.into(); + + let r = ae * be / ce; + if r > u128::max_value().into() { + a + } else { + r.as_u128() + } +} diff --git a/core/sr-arithmetic/src/biguint.rs b/core/sr-arithmetic/src/biguint.rs new file mode 100644 index 0000000000..d90ad4862b --- /dev/null +++ b/core/sr-arithmetic/src/biguint.rs @@ -0,0 +1,809 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Infinite precision unsigned integer for substrate runtime. + +use num_traits::Zero; +use rstd::{cmp::Ordering, ops, prelude::*, cell::RefCell, convert::TryFrom}; + +// A sensible value for this would be half of the dword size of the host machine. Since the +// runtime is compiled to 32bit webassembly, using 32 and 64 for single and double respectively +// should yield the most performance. TODO #3745 we could benchmark this and verify. +/// Representation of a single limb. +pub type Single = u32; +/// Representation of two limbs. +pub type Double = u64; +/// Difference in the number of bits of [`Single`] and [`Double`]. +const SHIFT: usize = 32; +/// short form of _Base_. Analogous to the value 10 in base-10 decimal numbers. +const B: Double = Single::max_value() as Double + 1; + +/// Splits a [`Double`] limb number into a tuple of two [`Single`] limb numbers. +pub fn split(a: Double) -> (Single, Single) { + let al = a as Single; + let ah = (a >> SHIFT) as Single; + (ah, al) +} + +/// Assumed as a given primitive. +/// +/// Multiplication of two singles, which at most yields 1 double. +pub fn mul_single(a: Single, b: Single) -> Double { + let a: Double = a.into(); + let b: Double = b.into(); + a * b +} + +/// Assumed as a given primitive. +/// +/// Addition of two singles, which at most takes a single limb of result and a carry, +/// returned as a tuple respectively. +pub fn add_single(a: Single, b: Single) -> (Single, Single) { + let a: Double = a.into(); + let b: Double = b.into(); + let q = a + b; + let (carry, r) = split(q); + (r, carry) +} + +/// Assumed as a given primitive. +/// +/// Division of double by a single limb. Always returns a double limb of quotient and a single +/// limb of remainder. +fn div_single(a: Double, b: Single) -> (Double, Single) { + let b: Double = b.into(); + let q = a / b; + let r = a % b; + // both conversions are trivially safe. + (q, r as Single) +} + +/// Simple wrapper around an infinitely large integer, represented as limbs of [`Single`]. +#[derive(Clone, Default)] +pub struct BigUint { + /// digits (limbs) of this number (sorted as msb -> lsd). + pub(crate) digits: Vec, +} + +impl BigUint { + /// Create a new instance with `size` limbs. This prevents any number with zero limbs to be + /// created. + /// + /// The behavior of the type is undefined with zero limbs. + pub fn with_capacity(size: usize) -> Self { + Self { digits: vec![0; size.max(1)] } + } + + /// Raw constructor from custom limbs. If `limbs` is empty, `Zero::zero()` implementation is + /// used. + pub fn from_limbs(limbs: &[Single]) -> Self { + if !limbs.is_empty() { + Self { digits: limbs.to_vec() } + } else { + Zero::zero() + } + } + + /// Number of limbs. + pub fn len(&self) -> usize { self.digits.len() } + + /// A naive getter for limb at `index`. Note that the order is lsb -> msb. + /// + /// #### Panics + /// + /// This panics if index is out of range. + pub fn get(&self, index: usize) -> Single { + self.digits[self.len() - 1 - index] + } + + /// A naive getter for limb at `index`. Note that the order is lsb -> msb. + pub fn checked_get(&self, index: usize) -> Option { + let i = self.len().checked_sub(1)?; + let j = i.checked_sub(index)?; + self.digits.get(j).cloned() + } + + /// A naive setter for limb at `index`. Note that the order is lsb -> msb. + /// + /// #### Panics + /// + /// This panics if index is out of range. + pub fn set(&mut self, index: usize, value: Single) { + let len = self.digits.len(); + self.digits[len - 1 - index] = value; + } + + /// returns the least significant limb of the number. + /// + /// #### Panics + /// + /// While the constructor of the type prevents this, this can panic if `self` has no digits. + pub fn lsb(&self) -> Single { + self.digits[self.len() - 1] + } + + /// returns the most significant limb of the number. + /// + /// #### Panics + /// + /// While the constructor of the type prevents this, this can panic if `self` has no digits. + pub fn msb(&self) -> Single { + self.digits[0] + } + + /// Strips zeros from the left side (the most significant limbs) of `self`, if any. + pub fn lstrip(&mut self) { + // by definition, a big-int number should never have leading zero limbs. This function + // has the ability to cause this. There is nothing to do if the number already has 1 + // limb only. call it a day and return. + if self.len().is_zero() { return; } + let index = self.digits.iter().position(|&elem| elem != 0).unwrap_or(0); + + if index > 0 { + self.digits = self.digits[index..].to_vec() + } + } + + /// Zero-pad `self` from left to reach `size` limbs. Will not make any difference if `self` + /// is already bigger than `size` limbs. + pub fn lpad(&mut self, size: usize) { + let n = self.len(); + if n >= size { return; } + let pad = size - n; + let mut new_digits = (0..pad).map(|_| 0).collect::>(); + new_digits.extend(self.digits.iter()); + self.digits = new_digits; + } + + /// Adds `self` with `other`. self and other do not have to have any particular size. Given + /// that the `n = max{size(self), size(other)}`, it will produce a number with `n + 1` + /// limbs. + /// + /// This function does not strip the output and returns the original allocated `n + 1` + /// limbs. The caller may strip the output if desired. + /// + /// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4. + pub fn add(self, other: &Self) -> Self { + let n = self.len().max(other.len()); + let mut k: Double = 0; + let mut w = Self::with_capacity(n + 1); + + for j in 0..n { + let u = Double::from(self.checked_get(j).unwrap_or(0)); + let v = Double::from(other.checked_get(j).unwrap_or(0)); + let s = u + v + k; + w.set(j, (s % B) as Single); + k = s / B; + } + // k is always 0 or 1. + w.set(n, k as Single); + w + } + + /// Subtracts `other` from `self`. self and other do not have to have any particular size. + /// Given that the `n = max{size(self), size(other)}`, it will produce a number of size `n`. + /// + /// If `other` is bigger than `self`, `Err(B - borrow)` is returned. + /// + /// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4. + pub fn sub(self, other: &Self) -> Result { + let n = self.len().max(other.len()); + let mut k = 0; + let mut w = Self::with_capacity(n); + for j in 0..n { + let s = { + let u = Double::from(self.checked_get(j).unwrap_or(0)); + let v = Double::from(other.checked_get(j).unwrap_or(0)); + let mut needs_borrow = false; + let mut t = 0; + + if let Some(v) = u.checked_sub(v) { + if let Some(v2) = v.checked_sub(k) { + t = v2 % B; + k = 0; + } else { + needs_borrow = true; + } + } else { + needs_borrow = true; + } + if needs_borrow { + t = u + B - v - k; + k = 1; + } + t + }; + // PROOF: t either comes from `v2 % B`, or from `u + B - v - k`. The former is + // trivial. The latter will not overflow this branch will only happen if the sum of + // `u - v - k` part has been negative, hence `u + B - v - k < b`. + w.set(j, s as Single); + } + + if k.is_zero() { + Ok(w) + } else { + Err(w) + } + } + + /// Multiplies n-limb number `self` with m-limb number `other`. + /// + /// The resulting number will always have `n + m` limbs. + /// + /// This function does not strip the output and returns the original allocated `n + m` + /// limbs. The caller may strip the output if desired. + /// + /// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4. + pub fn mul(self, other: &Self) -> Self { + let n = self.len(); + let m = other.len(); + let mut w = Self::with_capacity(m + n); + + for j in 0..n { + if self.get(j) == 0 { + // Note: `with_capacity` allocates with 0. Explicitly set j + m to zero if + // otherwise. + continue; + } + + let mut k = 0; + for i in 0..m { + // PROOF: (B−1) × (B−1) + (B−1) + (B−1) = B^2 −1 < B^2. addition is safe. + let t = + mul_single(self.get(j), other.get(i)) + + Double::from(w.get(i + j)) + + Double::from(k); + w.set(i + j, (t % B) as Single); + // PROOF: (B^2 - 1) / B < B. conversion is safe. + k = (t / B) as Single; + } + w.set(j + m, k); + } + w + } + + /// Divides `self` by a single limb `other`. This can be used in cases where the original + /// division cannot work due to the divisor (`other`) being just one limb. + /// + /// Invariant: `other` cannot be zero. + pub fn div_unit(self, mut other: Single) -> Self { + other = other.max(1); + let n = self.len(); + let mut out = Self::with_capacity(n); + let mut r: Single = 0; + // PROOF: (B-1) * B + (B-1) still fits in double + let with_r = |x: Double, r: Single| { Double::from(r) * B + x }; + for d in (0..n).rev() { + let (q, rr) = div_single(with_r(self.get(d).into(), r), other) ; + out.set(d, q as Single); + r = rr; + } + out + } + + /// Divides an `n + m` limb self by a `n` limb `other`. The result is a `m + 1` limb + /// quotient and a `n` limb remainder, if enabled by passing `true` in `rem` argument, both + /// in the form of an option's `Ok`. + /// + /// - requires `other` to be stripped and have no leading zeros. + /// - requires `self` to be stripped and have no leading zeros. + /// - requires `other` to have at least two limbs. + /// - requires `self` to have a greater length compared to `other`. + /// + /// All arguments are examined without being stripped for the above conditions. If any of + /// the above fails, `None` is returned.` + /// + /// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4. + pub fn div(self, other: &Self, rem: bool) -> Option<(Self, Self)> { + if other.len() <= 1 + || other.msb() == 0 + || self.msb() == 0 + || self.len() <= other.len() + { + return None + } + let n = other.len(); + let m = self.len() - n; + + let mut q = Self::with_capacity(m + 1); + let mut r = Self::with_capacity(n); + + // PROOF: 0 <= normalizer_bits < SHIFT 0 <= normalizer < B. all conversions are + // safe. + let normalizer_bits = other.msb().leading_zeros() as Single; + let normalizer = (2 as Single).pow(normalizer_bits as u32) as Single; + + // step D1. + let mut self_norm = self.mul(&Self::from(normalizer)); + let mut other_norm = other.clone().mul(&Self::from(normalizer)); + + // defensive only; the mul implementation should always create this. + self_norm.lpad(n + m + 1); + other_norm.lstrip(); + + // step D2. + for j in (0..=m).rev() { + // step D3.0 Find an estimate of q[j], named qhat. + let (qhat, rhat) = { + // PROOF: this always fits into `Double`. In the context of Single = u8, and + // Double = u16, think of 255 * 256 + 255 which is just u16::max_value(). + let dividend = + Double::from(self_norm.get(j + n)) + * B + + Double::from(self_norm.get(j + n - 1)); + let divisor = other_norm.get(n - 1); + div_single(dividend, divisor) + }; + + // D3.1 test qhat + // replace qhat and rhat with RefCells. This helps share state with the closure + let qhat = RefCell::new(qhat); + let rhat = RefCell::new(Double::from(rhat)); + + let test = || { + // decrease qhat if it is bigger than the base (B) + let qhat_local = *qhat.borrow(); + let rhat_local = *rhat.borrow(); + let predicate_1 = qhat_local >= B; + let predicate_2 = { + let lhs = qhat_local * Double::from(other_norm.get(n - 2)); + let rhs = B * rhat_local + Double::from(self_norm.get(j + n - 2)); + lhs > rhs + }; + if predicate_1 || predicate_2 { + *qhat.borrow_mut() -= 1; + *rhat.borrow_mut() += Double::from(other_norm.get(n - 1)); + true + } else { + false + } + }; + + test(); + while (*rhat.borrow() as Double) < B { + if !test() { break; } + } + + let qhat = qhat.into_inner(); + // we don't need rhat anymore. just let it go out of scope when it does. + + // step D4 + let lhs = Self { digits: (j..=j+n).rev().map(|d| self_norm.get(d)).collect() }; + let rhs = other_norm.clone().mul(&Self::from(qhat)); + + let maybe_sub = lhs.sub(&rhs); + let mut negative = false; + let sub = match maybe_sub { + Ok(t) => t, + Err(t) => { negative = true; t } + }; + (j..=j+n).for_each(|d| { self_norm.set(d, sub.get(d - j)); }); + + // step D5 + // PROOF: the `test()` specifically decreases qhat until it is below `B`. conversion + // is safe. + q.set(j, qhat as Single); + + // step D6: add back if negative happened. + if negative { + q.set(j, q.get(j) - 1); + let u = Self { digits: (j..=j+n).rev().map(|d| self_norm.get(d)).collect() }; + let r = other_norm.clone().add(&u); + (j..=j+n).rev().for_each(|d| { self_norm.set(d, r.get(d - j)); }) + } + } + + // if requested, calculate remainder. + if rem { + // undo the normalization. + if normalizer_bits > 0 { + let s = SHIFT as u32; + let nb = normalizer_bits; + for d in 0..n-1 { + let v = self_norm.get(d) >> nb + | self_norm.get(d + 1).overflowing_shl(s - nb).0; + r.set(d, v); + } + r.set(n - 1, self_norm.get(n - 1) >> normalizer_bits); + } else { + r = self_norm; + } + } + + Some((q, r)) + } +} + +#[cfg(feature = "std")] +impl rstd::fmt::Debug for BigUint { + fn fmt(&self, f: &mut rstd::fmt::Formatter<'_>) -> rstd::fmt::Result { + write!( + f, + "BigUint {{ {:?} ({:?})}}", + self.digits, + u128::try_from(self.clone()).unwrap_or(0), + ) + } +} + +impl PartialEq for BigUint { + fn eq(&self, other: &Self) -> bool { + self.cmp(other) == Ordering::Equal + } +} + +impl Eq for BigUint {} + +impl Ord for BigUint { + fn cmp(&self, other: &Self) -> Ordering { + let lhs_first = self.digits.iter().position(|&e| e != 0); + let rhs_first = other.digits.iter().position(|&e| e != 0); + + match (lhs_first, rhs_first) { + // edge cases that should not happen. This basically means that one or both were + // zero. + (None, None) => Ordering::Equal, + (Some(_), None) => Ordering::Greater, + (None, Some(_)) => Ordering::Less, + (Some(lhs_idx), Some(rhs_idx)) => { + let lhs = &self.digits[lhs_idx..]; + let rhs = &other.digits[rhs_idx..]; + let len_cmp = lhs.len().cmp(&rhs.len()); + match len_cmp { + Ordering::Equal => lhs.cmp(rhs), + _ => len_cmp, + } + } + } + } +} + +impl PartialOrd for BigUint { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl ops::Add for BigUint { + type Output = Self; + fn add(self, rhs: Self) -> Self::Output { + self.add(&rhs) + } +} + +impl ops::Sub for BigUint { + type Output = Self; + fn sub(self, rhs: Self) -> Self::Output { + self.sub(&rhs).unwrap_or_else(|e| e) + } +} + +impl ops::Mul for BigUint { + type Output = Self; + fn mul(self, rhs: Self) -> Self::Output { + self.mul(&rhs) + } +} + +impl Zero for BigUint { + fn zero() -> Self { + Self { digits: vec![Zero::zero()] } + } + + fn is_zero(&self) -> bool { + self.digits.iter().all(|d| d.is_zero()) + } +} + +macro_rules! impl_try_from_number_for { + ($([$type:ty, $len:expr]),+) => { + $( + impl TryFrom for $type { + type Error = &'static str; + fn try_from(mut value: BigUint) -> Result<$type, Self::Error> { + value.lstrip(); + let error_message = concat!("cannot fit a number into ", stringify!($type)); + if value.len() * SHIFT > $len { + Err(error_message) + } else { + let mut acc: $type = Zero::zero(); + for (i, d) in value.digits.iter().rev().cloned().enumerate() { + let d: $type = d.into(); + acc += d << (SHIFT * i); + } + Ok(acc) + } + } + } + )* + }; +} +// can only be implemented for sizes bigger than two limb. +impl_try_from_number_for!([u128, 128], [u64, 64]); + +macro_rules! impl_from_for_smaller_than_word { + ($($type:ty),+) => { + $(impl From<$type> for BigUint { + fn from(a: $type) -> Self { + Self { digits: vec! [a.into()] } + } + })* + } +} +impl_from_for_smaller_than_word!(u8, u16, Single); + +impl From for BigUint { + fn from(a: Double) -> Self { + let (ah, al) = split(a); + Self { digits: vec![ah, al] } + } +} + +#[cfg(test)] +pub mod tests { + use super::*; + #[cfg(feature = "bench")] + use test::Bencher; + + fn with_limbs(n: usize) -> BigUint { + BigUint { digits: vec![1; n] } + } + + #[test] + fn split_works() { + let a = SHIFT / 2; + let b = SHIFT * 3 / 2; + let num: Double = 1 << a | 1 << b; + // example when `Single = u8` + // assert_eq!(num, 0b_0001_0000_0001_0000) + assert_eq!(split(num), (1 << a, 1 << a)); + } + + #[test] + fn strip_works() { + let mut a = BigUint::from_limbs(&[0, 1, 0]); + a.lstrip(); + assert_eq!(a, BigUint { digits: vec![1, 0] }); + + let mut a = BigUint::from_limbs(&[0, 0, 1]); + a.lstrip(); + assert_eq!(a, BigUint { digits: vec![1] }); + + let mut a = BigUint::from_limbs(&[0, 0]); + a.lstrip(); + assert_eq!(a, BigUint { digits: vec![0] }); + + let mut a = BigUint::from_limbs(&[0, 0, 0]); + a.lstrip(); + assert_eq!(a, BigUint { digits: vec![0] }); + } + + #[test] + fn lpad_works() { + let mut a = BigUint::from_limbs(&[0, 1, 0]); + a.lpad(2); + assert_eq!(a.digits, vec![0, 1, 0]); + + let mut a = BigUint::from_limbs(&[0, 1, 0]); + a.lpad(3); + assert_eq!(a.digits, vec![0, 1, 0]); + + let mut a = BigUint::from_limbs(&[0, 1, 0]); + a.lpad(4); + assert_eq!(a.digits, vec![0, 0, 1, 0]); + } + + #[test] + fn equality_works() { + assert_eq!( + BigUint { digits: vec![1, 2, 3] } == BigUint { digits: vec![1, 2, 3] }, + true, + ); + assert_eq!( + BigUint { digits: vec![3, 2, 3] } == BigUint { digits: vec![1, 2, 3] }, + false, + ); + assert_eq!( + BigUint { digits: vec![0, 1, 2, 3] } == BigUint { digits: vec![1, 2, 3] }, + true, + ); + } + + #[test] + fn ordering_works() { + assert!(BigUint { digits: vec![0] } < BigUint { digits: vec![1] }); + assert!(BigUint { digits: vec![0] } == BigUint { digits: vec![0] }); + assert!(BigUint { digits: vec![] } == BigUint { digits: vec![0] }); + assert!(BigUint { digits: vec![] } == BigUint { digits: vec![] }); + assert!(BigUint { digits: vec![] } < BigUint { digits: vec![1] }); + + assert!(BigUint { digits: vec![1, 2, 3] } == BigUint { digits: vec![1, 2, 3] }); + assert!(BigUint { digits: vec![0, 1, 2, 3] } == BigUint { digits: vec![1, 2, 3] }); + + assert!(BigUint { digits: vec![1, 2, 4] } > BigUint { digits: vec![1, 2, 3] }); + assert!(BigUint { digits: vec![0, 1, 2, 4] } > BigUint { digits: vec![1, 2, 3] }); + assert!(BigUint { digits: vec![1, 2, 1, 0] } > BigUint { digits: vec![1, 2, 3] }); + + assert!(BigUint { digits: vec![0, 1, 2, 1] } < BigUint { digits: vec![1, 2, 3] }); + } + + #[test] + fn can_try_build_numbers_from_types() { + use rstd::convert::TryFrom; + assert_eq!(u64::try_from(with_limbs(1)).unwrap(), 1); + assert_eq!(u64::try_from(with_limbs(2)).unwrap(), u32::max_value() as u64 + 2); + assert_eq!( + u64::try_from(with_limbs(3)).unwrap_err(), + "cannot fit a number into u64", + ); + assert_eq!( + u128::try_from(with_limbs(3)).unwrap(), + u32::max_value() as u128 + u64::max_value() as u128 + 3 + ); + } + + #[test] + fn zero_works() { + assert_eq!(BigUint::zero(), BigUint { digits: vec![0] }); + assert_eq!(BigUint { digits: vec![0, 1, 0] }.is_zero(), false); + assert_eq!(BigUint { digits: vec![0, 0, 0] }.is_zero(), true); + + let a = BigUint::zero(); + let b = BigUint::zero(); + let c = a * b; + assert_eq!(c.digits, vec![0, 0]); + } + + #[test] + fn sub_negative_works() { + assert_eq!( + BigUint::from(10 as Single).sub(&BigUint::from(5 as Single)).unwrap(), + BigUint::from(5 as Single) + ); + assert_eq!( + BigUint::from(10 as Single).sub(&BigUint::from(10 as Single)).unwrap(), + BigUint::from(0 as Single) + ); + assert_eq!( + BigUint::from(10 as Single).sub(&BigUint::from(13 as Single)).unwrap_err(), + BigUint::from((B - 3) as Single), + ); + } + + #[test] + fn mul_always_appends_one_digit() { + let a = BigUint::from(10 as Single); + let b = BigUint::from(4 as Single); + assert_eq!(a.len(), 1); + assert_eq!(b.len(), 1); + + let n = a.mul(&b); + + assert_eq!(n.len(), 2); + assert_eq!(n.digits, vec![0, 40]); + } + + #[test] + fn div_conditions_work() { + let a = BigUint { digits: vec![2] }; + let b = BigUint { digits: vec![1, 2] }; + let c = BigUint { digits: vec![1, 1, 2] }; + let d = BigUint { digits: vec![0, 2] }; + let e = BigUint { digits: vec![0, 1, 1, 2] }; + + assert!(a.clone().div(&b, true).is_none()); + assert!(c.clone().div(&a, true).is_none()); + assert!(c.clone().div(&d, true).is_none()); + assert!(e.clone().div(&a, true).is_none()); + + assert!(c.clone().div(&b, true).is_some()); + } + + #[test] + fn div_unit_works() { + let a = BigUint { digits: vec![100] }; + let b = BigUint { digits: vec![1, 100] }; + + assert_eq!(a.clone().div_unit(1), a); + assert_eq!(a.clone().div_unit(0), a); + assert_eq!(a.clone().div_unit(2), BigUint::from(50 as Single)); + assert_eq!(a.clone().div_unit(7), BigUint::from(14 as Single)); + + assert_eq!(b.clone().div_unit(1), b); + assert_eq!(b.clone().div_unit(0), b); + assert_eq!(b.clone().div_unit(2), BigUint::from(((B + 100) / 2) as Single)); + assert_eq!(b.clone().div_unit(7), BigUint::from(((B + 100) / 7) as Single)); + + } + + #[cfg(feature = "bench")] + fn random_big_uint(size: usize) -> BigUint { + use rand::Rng; + let mut rng = rand::thread_rng(); + let digits = (0..size).map(|_| rng.gen_range(0, Single::max_value())).collect(); + BigUint { digits } + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_addition_2_digit(bencher: &mut Bencher) { + let a = random_big_uint(2); + let b = random_big_uint(2); + bencher.iter(|| { + let _ = a.clone().add(&b); + }); + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_addition_4_digit(bencher: &mut Bencher) { + let a = random_big_uint(4); + let b = random_big_uint(4); + bencher.iter(|| { + let _ = a.clone().add(&b); + }); + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_subtraction_2_digit(bencher: &mut Bencher) { + let a = random_big_uint(2); + let b = random_big_uint(2); + bencher.iter(|| { + let _ = a.clone().sub(&b); + }); + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_subtraction_4_digit(bencher: &mut Bencher) { + let a = random_big_uint(4); + let b = random_big_uint(4); + bencher.iter(|| { + let _ = a.clone().sub(&b); + }); + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_multiplication_2_digit(bencher: &mut Bencher) { + let a = random_big_uint(2); + let b = random_big_uint(2); + bencher.iter(|| { + let _ = a.clone().mul(&b); + }); + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_multiplication_4_digit(bencher: &mut Bencher) { + let a = random_big_uint(4); + let b = random_big_uint(4); + bencher.iter(|| { + let _ = a.clone().mul(&b); + }); + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_division_4_digit(bencher: &mut Bencher) { + let a = random_big_uint(4); + let b = random_big_uint(2); + bencher.iter(|| { + let _ = a.clone().div(&b, true); + }); + } +} diff --git a/core/sr-arithmetic/src/fixed64.rs b/core/sr-arithmetic/src/fixed64.rs new file mode 100644 index 0000000000..7dfc8414d2 --- /dev/null +++ b/core/sr-arithmetic/src/fixed64.rs @@ -0,0 +1,233 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use rstd::{ + ops, prelude::*, + convert::{TryFrom, TryInto}, +}; +use codec::{Encode, Decode}; +use crate::{ + Perbill, + traits::{ + SaturatedConversion, CheckedSub, CheckedAdd, Bounded, UniqueSaturatedInto, Saturating + } +}; + +/// An unsigned fixed point number. Can hold any value in the range [-9_223_372_036, 9_223_372_036] +/// with fixed point accuracy of one billion. +#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct Fixed64(i64); + +/// The accuracy of the `Fixed64` type. +const DIV: i64 = 1_000_000_000; + +impl Fixed64 { + /// creates self from a natural number. + /// + /// Note that this might be lossy. + pub fn from_natural(int: i64) -> Self { + Self(int.saturating_mul(DIV)) + } + + /// Return the accuracy of the type. Given that this function returns the value `X`, it means + /// that an instance composed of `X` parts (`Fixed64::from_parts(X)`) is equal to `1`. + pub fn accuracy() -> i64 { + DIV + } + + /// Raw constructor. Equal to `parts / 1_000_000_000`. + pub fn from_parts(parts: i64) -> Self { + Self(parts) + } + + /// creates self from a rational number. Equal to `n/d`. + /// + /// Note that this might be lossy. + pub fn from_rational(n: i64, d: u64) -> Self { + Self( + (i128::from(n).saturating_mul(i128::from(DIV)) / i128::from(d).max(1)) + .try_into() + .unwrap_or_else(|_| Bounded::max_value()) + ) + } + + /// Performs a saturated multiply and accumulate by unsigned number. + /// + /// Returns a saturated `int + (self * int)`. + pub fn saturated_multiply_accumulate(self, int: N) -> N + where + N: TryFrom + From + UniqueSaturatedInto + Bounded + Clone + Saturating + + ops::Rem + ops::Div + ops::Mul + + ops::Add, + { + let div = DIV as u64; + let positive = self.0 > 0; + // safe to convert as absolute value. + let parts = self.0.checked_abs().map(|v| v as u64).unwrap_or(i64::max_value() as u64 + 1); + + + // will always fit. + let natural_parts = parts / div; + // might saturate. + let natural_parts: N = natural_parts.saturated_into(); + // fractional parts can always fit into u32. + let perbill_parts = (parts % div) as u32; + + let n = int.clone().saturating_mul(natural_parts); + let p = Perbill::from_parts(perbill_parts) * int.clone(); + + // everything that needs to be either added or subtracted from the original weight. + let excess = n.saturating_add(p); + + if positive { + int.saturating_add(excess) + } else { + int.saturating_sub(excess) + } + } +} + +impl Saturating for Fixed64 { + fn saturating_add(self, rhs: Self) -> Self { + Self(self.0.saturating_add(rhs.0)) + } + fn saturating_mul(self, rhs: Self) -> Self { + Self(self.0.saturating_mul(rhs.0) / DIV) + } + fn saturating_sub(self, rhs: Self) -> Self { + Self(self.0.saturating_sub(rhs.0)) + } +} + +/// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait +/// for safe addition. +impl ops::Add for Fixed64 { + type Output = Self; + + fn add(self, rhs: Self) -> Self::Output { + Self(self.0 + rhs.0) + } +} + +/// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait +/// for safe subtraction. +impl ops::Sub for Fixed64 { + type Output = Self; + + fn sub(self, rhs: Self) -> Self::Output { + Self(self.0 - rhs.0) + } +} + +impl CheckedSub for Fixed64 { + fn checked_sub(&self, rhs: &Self) -> Option { + self.0.checked_sub(rhs.0).map(Self) + } +} + +impl CheckedAdd for Fixed64 { + fn checked_add(&self, rhs: &Self) -> Option { + self.0.checked_add(rhs.0).map(Self) + } +} + +#[cfg(feature = "std")] +impl rstd::fmt::Debug for Fixed64 { + fn fmt(&self, f: &mut rstd::fmt::Formatter<'_>) -> rstd::fmt::Result { + write!(f, "Fixed64({},{})", self.0 / DIV, (self.0 % DIV) / 1000) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn max() -> Fixed64 { + Fixed64::from_parts(i64::max_value()) + } + + #[test] + fn fixed64_semantics() { + assert_eq!(Fixed64::from_rational(5, 2).0, 5 * 1_000_000_000 / 2); + assert_eq!(Fixed64::from_rational(5, 2), Fixed64::from_rational(10, 4)); + assert_eq!(Fixed64::from_rational(5, 0), Fixed64::from_rational(5, 1)); + + // biggest value that can be created. + assert_ne!(max(), Fixed64::from_natural(9_223_372_036)); + assert_eq!(max(), Fixed64::from_natural(9_223_372_037)); + } + + #[test] + fn fixed_64_growth_decrease_curve() { + let test_set = vec![0u32, 1, 10, 1000, 1_000_000_000]; + + // negative (1/2) + let mut fm = Fixed64::from_rational(-1, 2); + test_set.clone().into_iter().for_each(|i| { + assert_eq!(fm.saturated_multiply_accumulate(i) as i32, i as i32 - i as i32 / 2); + }); + + // unit (1) multiplier + fm = Fixed64::from_parts(0); + test_set.clone().into_iter().for_each(|i| { + assert_eq!(fm.saturated_multiply_accumulate(i), i); + }); + + // i.5 multiplier + fm = Fixed64::from_rational(1, 2); + test_set.clone().into_iter().for_each(|i| { + assert_eq!(fm.saturated_multiply_accumulate(i), i * 3 / 2); + }); + + // dual multiplier + fm = Fixed64::from_rational(1, 1); + test_set.clone().into_iter().for_each(|i| { + assert_eq!(fm.saturated_multiply_accumulate(i), i * 2); + }); + } + + macro_rules! saturating_mul_acc_test { + ($num_type:tt) => { + assert_eq!( + Fixed64::from_rational(100, 1).saturated_multiply_accumulate(10 as $num_type), + 1010, + ); + assert_eq!( + Fixed64::from_rational(100, 2).saturated_multiply_accumulate(10 as $num_type), + 510, + ); + assert_eq!( + Fixed64::from_rational(100, 3).saturated_multiply_accumulate(0 as $num_type), + 0, + ); + assert_eq!( + Fixed64::from_rational(5, 1).saturated_multiply_accumulate($num_type::max_value()), + $num_type::max_value() + ); + assert_eq!( + max().saturated_multiply_accumulate($num_type::max_value()), + $num_type::max_value() + ); + } + } + + #[test] + fn fixed64_multiply_accumulate_works() { + saturating_mul_acc_test!(u32); + saturating_mul_acc_test!(u64); + saturating_mul_acc_test!(u128); + } +} diff --git a/core/sr-arithmetic/src/helpers_128bit.rs b/core/sr-arithmetic/src/helpers_128bit.rs new file mode 100644 index 0000000000..10cc94ae77 --- /dev/null +++ b/core/sr-arithmetic/src/helpers_128bit.rs @@ -0,0 +1,112 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Some helper functions to work with 128bit numbers. Note that the functionality provided here is +//! only sensible to use with 128bit numbers because for smaller sizes, you can always rely on +//! assumptions of a bigger type (u128) being available, or simply create a per-thing and use the +//! multiplication implementation provided there. + +use crate::biguint; +use num_traits::Zero; +use rstd::{cmp::{min, max}, convert::TryInto, mem}; + +/// Helper gcd function used in Rational128 implementation. +pub fn gcd(a: u128, b: u128) -> u128 { + match ((a, b), (a & 1, b & 1)) { + ((x, y), _) if x == y => y, + ((0, x), _) | ((x, 0), _) => x, + ((x, y), (0, 1)) | ((y, x), (1, 0)) => gcd(x >> 1, y), + ((x, y), (0, 0)) => gcd(x >> 1, y >> 1) << 1, + ((x, y), (1, 1)) => { + let (x, y) = (min(x, y), max(x, y)); + gcd((y - x) >> 1, x) + }, + _ => unreachable!(), + } +} + +/// split a u128 into two u64 limbs +pub fn split(a: u128) -> (u64, u64) { + let al = a as u64; + let ah = (a >> 64) as u64; + (ah, al) +} + +/// Convert a u128 to a u32 based biguint. +pub fn to_big_uint(x: u128) -> biguint::BigUint { + let (xh, xl) = split(x); + let (xhh, xhl) = biguint::split(xh); + let (xlh, xll) = biguint::split(xl); + let mut n = biguint::BigUint::from_limbs(&[xhh, xhl, xlh, xll]); + n.lstrip(); + n +} + +/// Safely and accurately compute `a * b / c`. The approach is: +/// - Simply try `a * b / c`. +/// - Else, convert them both into big numbers and re-try. `Err` is returned if the result +/// cannot be safely casted back to u128. +/// +/// Invariant: c must be greater than or equal to 1. +pub fn multiply_by_rational(mut a: u128, mut b: u128, mut c: u128) -> Result { + if a.is_zero() || b.is_zero() { return Ok(Zero::zero()); } + c = c.max(1); + + // a and b are interchangeable by definition in this function. It always helps to assume the + // bigger of which is being multiplied by a `0 < b/c < 1`. Hence, a should be the bigger and + // b the smaller one. + if b > a { + mem::swap(&mut a, &mut b); + } + + // Attempt to perform the division first + if a % c == 0 { + a /= c; + c = 1; + } else if b % c == 0 { + b /= c; + c = 1; + } + + if let Some(x) = a.checked_mul(b) { + // This is the safest way to go. Try it. + Ok(x / c) + } else { + let a_num = to_big_uint(a); + let b_num = to_big_uint(b); + let c_num = to_big_uint(c); + + let mut ab = a_num * b_num; + ab.lstrip(); + let mut q = if c_num.len() == 1 { + // PROOF: if `c_num.len() == 1` then `c` fits in one limb. + ab.div_unit(c as biguint::Single) + } else { + // PROOF: both `ab` and `c` cannot have leading zero limbs; if length of `c` is 1, + // the previous branch would handle. Also, if ab for sure has a bigger size than + // c, because `a.checked_mul(b)` has failed, hence ab must be at least one limb + // bigger than c. In this case, returning zero is defensive-only and div should + // always return Some. + let (mut q, r) = ab.div(&c_num, true).unwrap_or((Zero::zero(), Zero::zero())); + let r: u128 = r.try_into() + .expect("reminder of div by c is always less than c; qed"); + if r > (c / 2) { q = q.add(&to_big_uint(1)); } + q + }; + q.lstrip(); + q.try_into().map_err(|_| "result cannot fit in u128") + } +} diff --git a/core/sr-arithmetic/src/lib.rs b/core/sr-arithmetic/src/lib.rs new file mode 100644 index 0000000000..847ca9e797 --- /dev/null +++ b/core/sr-arithmetic/src/lib.rs @@ -0,0 +1,48 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Minimal fixed point arithmetic primitives and types for runtime. + +#![cfg_attr(not(feature = "std"), no_std)] + +// to allow benchmarking +#![cfg_attr(feature = "bench", feature(test))] +#[cfg(feature = "bench")] extern crate test; + +/// Copied from `sr-primitives` and documented there. +#[cfg(test)] +macro_rules! assert_eq_error_rate { + ($x:expr, $y:expr, $error:expr $(,)?) => { + assert!( + ($x) >= (($y) - ($error)) && ($x) <= (($y) + ($error)), + "{:?} != {:?} (with error rate {:?})", + $x, + $y, + $error, + ); + }; +} + +pub mod biguint; +pub mod helpers_128bit; +pub mod traits; +mod per_things; +mod fixed64; +mod rational128; + +pub use fixed64::Fixed64; +pub use per_things::{Percent, Permill, Perbill, Perquintill}; +pub use rational128::Rational128; diff --git a/core/sr-arithmetic/src/per_things.rs b/core/sr-arithmetic/src/per_things.rs new file mode 100644 index 0000000000..afd8100a84 --- /dev/null +++ b/core/sr-arithmetic/src/per_things.rs @@ -0,0 +1,519 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize}; + +use rstd::{ops, prelude::*, convert::TryInto}; +use codec::{Encode, Decode, CompactAs}; +use crate::traits::{SaturatedConversion, UniqueSaturatedInto, Saturating}; + +macro_rules! implement_per_thing { + ($name:ident, $test_mod:ident, [$($test_units:tt),+], $max:tt, $type:ty, $upper_type:ty, $title:expr $(,)?) => { + /// A fixed point representation of a number between in the range [0, 1]. + /// + #[doc = $title] + #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Ord, PartialOrd))] + #[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, CompactAs)] + pub struct $name($type); + + impl $name { + /// Nothing. + pub fn zero() -> Self { Self(0) } + + /// `true` if this is nothing. + pub fn is_zero(&self) -> bool { self.0 == 0 } + + /// Everything. + pub fn one() -> Self { Self($max) } + + /// Consume self and deconstruct into a raw numeric type. + pub fn deconstruct(self) -> $type { self.0 } + + /// Return the scale at which this per-thing is working. + pub const fn accuracy() -> $type { $max } + + /// From an explicitly defined number of parts per maximum of the type. + /// + /// This can be called at compile time. + pub const fn from_parts(parts: $type) -> Self { + Self([parts, $max][(parts > $max) as usize]) + } + + /// Converts from a percent. Equal to `x / 100`. + /// + /// This can be created at compile time. + pub const fn from_percent(x: $type) -> Self { + Self([x, 100][(x > 100) as usize] * ($max / 100)) + } + + /// Return the product of multiplication of this value by itself. + pub fn square(self) -> Self { + // both can be safely casted and multiplied. + let p: $upper_type = self.0 as $upper_type * self.0 as $upper_type; + let q: $upper_type = <$upper_type>::from($max) * <$upper_type>::from($max); + Self::from_rational_approximation(p, q) + } + + /// Converts a fraction into `Permill`. + #[cfg(feature = "std")] + pub fn from_fraction(x: f64) -> Self { Self((x * ($max as f64)) as $type) } + + /// Approximate the fraction `p/q` into a per-thing fraction. This will never overflow. + /// + /// The computation of this approximation is performed in the generic type `N`. Given + /// `M` as the data type that can hold the maximum value of this per-thing (e.g. u32 for + /// perbill), this can only work if `N == M` or `N: From + TryInto`. + pub fn from_rational_approximation(p: N, q: N) -> Self + where N: Clone + Ord + From<$type> + TryInto<$type> + ops::Div + { + // q cannot be zero. + let q = q.max((1 as $type).into()); + // p should not be bigger than q. + let p = p.min(q.clone()); + + let factor = (q.clone() / $max.into()).max((1 as $type).into()); + + // q cannot overflow: (q / (q/$max)) < 2 * $max. p < q hence p also cannot overflow. + // this implies that $type must be able to fit 2 * $max. + let q_reduce: $type = (q / factor.clone()) + .try_into() + .map_err(|_| "Failed to convert") + .expect( + "q / (q/$max) < (2 * $max). Macro prevents any type being created that \ + does not satisfy this; qed" + ); + let p_reduce: $type = (p / factor.clone()) + .try_into() + .map_err(|_| "Failed to convert") + .expect( + "q / (q/$max) < (2 * $max). Macro prevents any type being created that \ + does not satisfy this; qed" + ); + + // `p_reduced` and `q_reduced` are withing $type. Mul by another $max will always + // fit in $upper_type. This is guaranteed by the macro tests. + let part = + p_reduce as $upper_type + * <$upper_type>::from($max) + / q_reduce as $upper_type; + + $name(part as $type) + } + } + + impl Saturating for $name { + fn saturating_add(self, rhs: Self) -> Self { + // defensive-only: since `$max * 2 < $type::max_value()`, this can never overflow. + Self::from_parts(self.0.saturating_add(rhs.0)) + } + fn saturating_sub(self, rhs: Self) -> Self { + Self::from_parts(self.0.saturating_sub(rhs.0)) + } + fn saturating_mul(self, rhs: Self) -> Self { + let a = self.0 as $upper_type; + let b = rhs.0 as $upper_type; + let m = <$upper_type>::from($max); + let parts = a * b / m; + // This will always fit into $type. + Self::from_parts(parts as $type) + } + } + + impl ops::Div for $name { + type Output = Self; + + fn div(self, rhs: Self) -> Self::Output { + let p = self.0; + let q = rhs.0; + Self::from_rational_approximation(p, q) + } + } + + /// Overflow-prune multiplication. + /// + /// tailored to be used with a balance type. + impl ops::Mul for $name + where + N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem + + ops::Div + ops::Mul + ops::Add, + { + type Output = N; + fn mul(self, b: N) -> Self::Output { + let maximum: N = $max.into(); + let upper_max: $upper_type = $max.into(); + let part: N = self.0.into(); + + let rem_multiplied_divided = { + let rem = b.clone().rem(maximum.clone()); + + // `rem_sized` is inferior to $max, thus it fits into $type. This is assured by + // a test. + let rem_sized = rem.saturated_into::<$type>(); + + // `self` and `rem_sized` are inferior to $max, thus the product is less than + // $max^2 and fits into $upper_type. This is assured by a test. + let rem_multiplied_upper = rem_sized as $upper_type * self.0 as $upper_type; + + // `rem_multiplied_upper` is less than $max^2 therefore divided by $max it fits + // in $type. remember that $type always fits $max. + let mut rem_multiplied_divided_sized = + (rem_multiplied_upper / upper_max) as $type; + // fix a tiny rounding error + if rem_multiplied_upper % upper_max > upper_max / 2 { + rem_multiplied_divided_sized += 1; + } + + // `rem_multiplied_divided_sized` is inferior to b, thus it can be converted + // back to N type + rem_multiplied_divided_sized.into() + }; + + (b / maximum) * part + rem_multiplied_divided + } + } + + #[cfg(test)] + mod $test_mod { + use codec::{Encode, Decode}; + use super::{$name, Saturating}; + use crate::traits::Zero; + + + #[test] + fn macro_expanded_correctly() { + // needed for the `from_percent` to work. + assert!($max >= 100); + assert!($max % 100 == 0); + + // needed for `from_rational_approximation` + assert!(2 * $max < <$type>::max_value()); + assert!(<$upper_type>::from($max) < <$upper_type>::max_value()); + + // for something like percent they can be the same. + assert!((<$type>::max_value() as $upper_type) <= <$upper_type>::max_value()); + assert!(<$upper_type>::from($max).checked_mul($max.into()).is_some()); + } + + #[derive(Encode, Decode, PartialEq, Eq, Debug)] + struct WithCompact { + data: T, + } + + #[test] + fn has_compact() { + let data = WithCompact { data: $name(1) }; + let encoded = data.encode(); + assert_eq!(data, WithCompact::<$name>::decode(&mut &encoded[..]).unwrap()); + } + + #[test] + fn compact_encoding() { + let tests = [ + // assume all per_things have the size u8 at least. + (0 as $type, 1usize), + (1 as $type, 1usize), + (63, 1), + (64, 2), + (65, 2), + (<$type>::max_value(), <$type>::max_value().encode().len() + 1) + ]; + for &(n, l) in &tests { + let compact: codec::Compact<$name> = $name(n).into(); + let encoded = compact.encode(); + assert_eq!(encoded.len(), l); + let decoded = >::decode(&mut & encoded[..]) + .unwrap(); + let per_thingy: $name = decoded.into(); + assert_eq!(per_thingy, $name(n)); + } + } + + #[test] + fn per_thing_api_works() { + // some really basic stuff + assert_eq!($name::zero(), $name::from_parts(Zero::zero())); + assert_eq!($name::one(), $name::from_parts($max)); + assert_eq!($name::accuracy(), $max); + assert_eq!($name::from_percent(0), $name::from_parts(Zero::zero())); + assert_eq!($name::from_percent(10), $name::from_parts($max / 10)); + assert_eq!($name::from_percent(100), $name::from_parts($max)); + } + + macro_rules! per_thing_mul_test { + ($num_type:tt) => { + // multiplication from all sort of from_percent + assert_eq!( + $name::from_percent(100) * $num_type::max_value(), + $num_type::max_value() + ); + assert_eq_error_rate!( + $name::from_percent(99) * $num_type::max_value(), + ((Into::::into($num_type::max_value()) * 99u32) / 100u32).as_u128() as $num_type, + 1, + ); + assert_eq!( + $name::from_percent(50) * $num_type::max_value(), + $num_type::max_value() / 2, + ); + assert_eq_error_rate!( + $name::from_percent(1) * $num_type::max_value(), + $num_type::max_value() / 100, + 1, + ); + assert_eq!($name::from_percent(0) * $num_type::max_value(), 0); + + // // multiplication with bounds + assert_eq!($name::one() * $num_type::max_value(), $num_type::max_value()); + assert_eq!($name::zero() * $num_type::max_value(), 0); + } + } + + #[test] + fn per_thing_mul_works() { + use primitive_types::U256; + + // accuracy test + assert_eq!($name::from_rational_approximation(1 as $type, 3) * 30 as $type, 10); + + $(per_thing_mul_test!($test_units);)* + } + + #[test] + fn per_thing_mul_rounds_to_nearest_number() { + assert_eq!($name::from_percent(33) * 10u64, 3); + assert_eq!($name::from_percent(34) * 10u64, 3); + assert_eq!($name::from_percent(35) * 10u64, 3); + assert_eq!($name::from_percent(36) * 10u64, 4); + assert_eq!($name::from_percent(36) * 10u64, 4); + } + + #[test] + fn per_thing_multiplication_with_large_number() { + use primitive_types::U256; + let max_minus_one = $max - 1; + assert_eq_error_rate!( + $name::from_parts(max_minus_one) * std::u128::MAX, + ((Into::::into(std::u128::MAX) * max_minus_one) / $max).as_u128(), + 1, + ); + } + + macro_rules! per_thing_from_rationale_approx_test { + ($num_type:tt) => { + // within accuracy boundary + assert_eq!( + $name::from_rational_approximation(1 as $num_type, 0), + $name::one(), + ); + assert_eq!( + $name::from_rational_approximation(1 as $num_type, 1), + $name::one(), + ); + assert_eq_error_rate!( + $name::from_rational_approximation(1 as $num_type, 3).0, + $name::from_parts($max / 3).0, + 2 + ); + assert_eq!( + $name::from_rational_approximation(1 as $num_type, 10), + $name::from_percent(10), + ); + assert_eq!( + $name::from_rational_approximation(1 as $num_type, 4), + $name::from_percent(25), + ); + assert_eq!( + $name::from_rational_approximation(1 as $num_type, 4), + $name::from_rational_approximation(2 as $num_type, 8), + ); + // no accurate anymore but won't overflow. + assert_eq!( + $name::from_rational_approximation( + $num_type::max_value() - 1, + $num_type::max_value() + ), + $name::one(), + ); + assert_eq_error_rate!( + $name::from_rational_approximation( + $num_type::max_value() / 3, + $num_type::max_value() + ).0, + $name::from_parts($max / 3).0, + 2 + ); + assert_eq!( + $name::from_rational_approximation(1, $num_type::max_value()), + $name::zero(), + ); + }; + } + + #[test] + fn per_thing_from_rationale_approx_works() { + // This is just to make sure something like Percent which _might_ get built from a + // u8 does not overflow in the context of this test. + let max_value = <$upper_type>::from($max); + // almost at the edge + assert_eq!( + $name::from_rational_approximation($max - 1, $max + 1), + $name::from_parts($max - 2), + ); + assert_eq!( + $name::from_rational_approximation(1, $max-1), + $name::from_parts(1), + ); + assert_eq!( + $name::from_rational_approximation(1, $max), + $name::from_parts(1), + ); + assert_eq!( + $name::from_rational_approximation(2, 2 * $max - 1), + $name::from_parts(1), + ); + assert_eq!( + $name::from_rational_approximation(1, $max+1), + $name::zero(), + ); + assert_eq!( + $name::from_rational_approximation(3 * max_value / 2, 3 * max_value), + $name::from_percent(50), + ); + $(per_thing_from_rationale_approx_test!($test_units);)* + } + + #[test] + fn per_things_mul_operates_in_output_type() { + // assert_eq!($name::from_percent(50) * 100u32, 50u32); + assert_eq!($name::from_percent(50) * 100u64, 50u64); + assert_eq!($name::from_percent(50) * 100u128, 50u128); + } + + #[test] + fn per_thing_saturating_op_works() { + assert_eq!( + $name::from_percent(50).saturating_add($name::from_percent(40)), + $name::from_percent(90) + ); + assert_eq!( + $name::from_percent(50).saturating_add($name::from_percent(50)), + $name::from_percent(100) + ); + assert_eq!( + $name::from_percent(60).saturating_add($name::from_percent(50)), + $name::from_percent(100) + ); + + assert_eq!( + $name::from_percent(60).saturating_sub($name::from_percent(50)), + $name::from_percent(10) + ); + assert_eq!( + $name::from_percent(60).saturating_sub($name::from_percent(60)), + $name::from_percent(0) + ); + assert_eq!( + $name::from_percent(60).saturating_sub($name::from_percent(70)), + $name::from_percent(0) + ); + + assert_eq!( + $name::from_percent(50).saturating_mul($name::from_percent(50)), + $name::from_percent(25) + ); + assert_eq!( + $name::from_percent(20).saturating_mul($name::from_percent(20)), + $name::from_percent(4) + ); + assert_eq!( + $name::from_percent(10).saturating_mul($name::from_percent(10)), + $name::from_percent(1) + ); + } + + #[test] + fn per_thing_square_works() { + assert_eq!($name::from_percent(100).square(), $name::from_percent(100)); + assert_eq!($name::from_percent(50).square(), $name::from_percent(25)); + assert_eq!($name::from_percent(10).square(), $name::from_percent(1)); + assert_eq!( + $name::from_percent(2).square(), + $name::from_parts((4 * <$upper_type>::from($max) / 100 / 100) as $type) + ); + } + + #[test] + fn per_things_div_works() { + // normal + assert_eq!($name::from_percent(10) / $name::from_percent(20), + $name::from_percent(50) + ); + assert_eq!($name::from_percent(10) / $name::from_percent(10), + $name::from_percent(100) + ); + assert_eq!($name::from_percent(10) / $name::from_percent(0), + $name::from_percent(100) + ); + + // will not overflow + assert_eq!($name::from_percent(10) / $name::from_percent(5), + $name::from_percent(100) + ); + assert_eq!($name::from_percent(100) / $name::from_percent(50), + $name::from_percent(100) + ); + } + } + }; +} + +implement_per_thing!( + Percent, + test_per_cent, + [u32, u64, u128], + 100u8, + u8, + u16, + "_Percent_", +); +implement_per_thing!( + Permill, + test_permill, + [u32, u64, u128], + 1_000_000u32, + u32, + u64, + "_Parts per Million_", +); +implement_per_thing!( + Perbill, + test_perbill, + [u32, u64, u128], + 1_000_000_000u32, + u32, + u64, + "_Parts per Billion_", +); +implement_per_thing!( + Perquintill, + test_perquintill, + [u64, u128], + 1_000_000_000_000_000_000u64, + u64, + u128, + "_Parts per Quintillion_", +); diff --git a/core/sr-arithmetic/src/rational128.rs b/core/sr-arithmetic/src/rational128.rs new file mode 100644 index 0000000000..706d6a5eba --- /dev/null +++ b/core/sr-arithmetic/src/rational128.rs @@ -0,0 +1,384 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use rstd::{cmp::Ordering, prelude::*}; +use crate::helpers_128bit; +use num_traits::Zero; + +/// A wrapper for any rational number with a 128 bit numerator and denominator. +#[derive(Clone, Copy, Default, Eq)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct Rational128(u128, u128); + +impl Rational128 { + /// Nothing. + pub fn zero() -> Self { + Self(0, 1) + } + + /// If it is zero or not + pub fn is_zero(&self) -> bool { + self.0.is_zero() + } + + /// Build from a raw `n/d`. + pub fn from(n: u128, d: u128) -> Self { + Self(n, d.max(1)) + } + + /// Build from a raw `n/d`. This could lead to / 0 if not properly handled. + pub fn from_unchecked(n: u128, d: u128) -> Self { + Self(n, d) + } + + /// Return the numerator. + pub fn n(&self) -> u128 { + self.0 + } + + /// Return the denominator. + pub fn d(&self) -> u128 { + self.1 + } + + /// Convert `self` to a similar rational number where denominator is the given `den`. + // + /// This only returns if the result is accurate. `Err` is returned if the result cannot be + /// accurately calculated. + pub fn to_den(self, den: u128) -> Result { + if den == self.1 { + Ok(self) + } else { + helpers_128bit::multiply_by_rational(self.0, den, self.1).map(|n| Self(n, den)) + } + } + + /// Get the least common divisor of `self` and `other`. + /// + /// This only returns if the result is accurate. `Err` is returned if the result cannot be + /// accurately calculated. + pub fn lcm(&self, other: &Self) -> Result { + // this should be tested better: two large numbers that are almost the same. + if self.1 == other.1 { return Ok(self.1) } + let g = helpers_128bit::gcd(self.1, other.1); + helpers_128bit::multiply_by_rational(self.1 , other.1, g) + } + + /// A saturating add that assumes `self` and `other` have the same denominator. + pub fn lazy_saturating_add(self, other: Self) -> Self { + if other.is_zero() { + self + } else { + Self(self.0.saturating_add(other.0) ,self.1) + } + } + + /// A saturating subtraction that assumes `self` and `other` have the same denominator. + pub fn lazy_saturating_sub(self, other: Self) -> Self { + if other.is_zero() { + self + } else { + Self(self.0.saturating_sub(other.0) ,self.1) + } + } + + /// Addition. Simply tries to unify the denominators and add the numerators. + /// + /// Overflow might happen during any of the steps. Error is returned in such cases. + pub fn checked_add(self, other: Self) -> Result { + let lcm = self.lcm(&other).map_err(|_| "failed to scale to denominator")?; + let self_scaled = self.to_den(lcm).map_err(|_| "failed to scale to denominator")?; + let other_scaled = other.to_den(lcm).map_err(|_| "failed to scale to denominator")?; + let n = self_scaled.0.checked_add(other_scaled.0) + .ok_or("overflow while adding numerators")?; + Ok(Self(n, self_scaled.1)) + } + + /// Subtraction. Simply tries to unify the denominators and subtract the numerators. + /// + /// Overflow might happen during any of the steps. None is returned in such cases. + pub fn checked_sub(self, other: Self) -> Result { + let lcm = self.lcm(&other).map_err(|_| "failed to scale to denominator")?; + let self_scaled = self.to_den(lcm).map_err(|_| "failed to scale to denominator")?; + let other_scaled = other.to_den(lcm).map_err(|_| "failed to scale to denominator")?; + + let n = self_scaled.0.checked_sub(other_scaled.0) + .ok_or("overflow while subtracting numerators")?; + Ok(Self(n, self_scaled.1)) + } +} + +impl PartialOrd for Rational128 { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Rational128 { + fn cmp(&self, other: &Self) -> Ordering { + // handle some edge cases. + if self.1 == other.1 { + self.0.cmp(&other.0) + } else if self.1.is_zero() { + Ordering::Greater + } else if other.1.is_zero() { + Ordering::Less + } else { + // Don't even compute gcd. + let self_n = helpers_128bit::to_big_uint(self.0) * helpers_128bit::to_big_uint(other.1); + let other_n = helpers_128bit::to_big_uint(other.0) * helpers_128bit::to_big_uint(self.1); + self_n.cmp(&other_n) + } + } +} + +impl PartialEq for Rational128 { + fn eq(&self, other: &Self) -> bool { + // handle some edge cases. + if self.1 == other.1 { + self.0.eq(&other.0) + } else { + let self_n = helpers_128bit::to_big_uint(self.0) * helpers_128bit::to_big_uint(other.1); + let other_n = helpers_128bit::to_big_uint(other.0) * helpers_128bit::to_big_uint(self.1); + self_n.eq(&other_n) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use super::helpers_128bit::*; + + const MAX128: u128 = u128::max_value(); + const MAX64: u128 = u64::max_value() as u128; + const MAX64_2: u128 = 2 * u64::max_value() as u128; + + fn r(p: u128, q: u128) -> Rational128 { + Rational128(p, q) + } + + fn mul_div(a: u128, b: u128, c: u128) -> u128 { + use primitive_types::U256; + if a.is_zero() { return Zero::zero(); } + let c = c.max(1); + + // e for extended + let ae: U256 = a.into(); + let be: U256 = b.into(); + let ce: U256 = c.into(); + + let r = ae * be / ce; + if r > u128::max_value().into() { + a + } else { + r.as_u128() + } + } + + #[test] + fn truth_value_function_works() { + assert_eq!( + mul_div(2u128.pow(100), 8, 4), + 2u128.pow(101) + ); + assert_eq!( + mul_div(2u128.pow(100), 4, 8), + 2u128.pow(99) + ); + + // and it returns a if result cannot fit + assert_eq!(mul_div(MAX128 - 10, 2, 1), MAX128 - 10); + } + + #[test] + fn to_denom_works() { + // simple up and down + assert_eq!(r(1, 5).to_den(10), Ok(r(2, 10))); + assert_eq!(r(4, 10).to_den(5), Ok(r(2, 5))); + + // up and down with large numbers + assert_eq!(r(MAX128 - 10, MAX128).to_den(10), Ok(r(10, 10))); + assert_eq!(r(MAX128 / 2, MAX128).to_den(10), Ok(r(5, 10))); + + // large to perbill. This is very well needed for phragmen. + assert_eq!( + r(MAX128 / 2, MAX128).to_den(1000_000_000), + Ok(r(500_000_000, 1000_000_000)) + ); + + // large to large + assert_eq!(r(MAX128 / 2, MAX128).to_den(MAX128/2), Ok(r(MAX128/4, MAX128/2))); + } + + #[test] + fn gdc_works() { + assert_eq!(gcd(10, 5), 5); + assert_eq!(gcd(7, 22), 1); + } + + #[test] + fn lcm_works() { + // simple stuff + assert_eq!(r(3, 10).lcm(&r(4, 15)).unwrap(), 30); + assert_eq!(r(5, 30).lcm(&r(1, 7)).unwrap(), 210); + assert_eq!(r(5, 30).lcm(&r(1, 10)).unwrap(), 30); + + // large numbers + assert_eq!( + r(1_000_000_000, MAX128).lcm(&r(7_000_000_000, MAX128-1)), + Err("result cannot fit in u128"), + ); + assert_eq!( + r(1_000_000_000, MAX64).lcm(&r(7_000_000_000, MAX64-1)), + Ok(340282366920938463408034375210639556610), + ); + assert!(340282366920938463408034375210639556610 < MAX128); + assert!(340282366920938463408034375210639556610 == MAX64 * (MAX64 - 1)); + } + + #[test] + fn add_works() { + // works + assert_eq!(r(3, 10).checked_add(r(1, 10)).unwrap(), r(2, 5)); + assert_eq!(r(3, 10).checked_add(r(3, 7)).unwrap(), r(51, 70)); + + // errors + assert_eq!( + r(1, MAX128).checked_add(r(1, MAX128-1)), + Err("failed to scale to denominator"), + ); + assert_eq!( + r(7, MAX128).checked_add(r(MAX128, MAX128)), + Err("overflow while adding numerators"), + ); + assert_eq!( + r(MAX128, MAX128).checked_add(r(MAX128, MAX128)), + Err("overflow while adding numerators"), + ); + } + + #[test] + fn sub_works() { + // works + assert_eq!(r(3, 10).checked_sub(r(1, 10)).unwrap(), r(1, 5)); + assert_eq!(r(6, 10).checked_sub(r(3, 7)).unwrap(), r(12, 70)); + + // errors + assert_eq!( + r(2, MAX128).checked_sub(r(1, MAX128-1)), + Err("failed to scale to denominator"), + ); + assert_eq!( + r(7, MAX128).checked_sub(r(MAX128, MAX128)), + Err("overflow while subtracting numerators"), + ); + assert_eq!( + r(1, 10).checked_sub(r(2,10)), + Err("overflow while subtracting numerators"), + ); + } + + #[test] + fn ordering_and_eq_works() { + assert!(r(1, 2) > r(1, 3)); + assert!(r(1, 2) > r(2, 6)); + + assert!(r(1, 2) < r(6, 6)); + assert!(r(2, 1) > r(2, 6)); + + assert!(r(5, 10) == r(1, 2)); + assert!(r(1, 2) == r(1, 2)); + + assert!(r(1, 1490000000000200000) > r(1, 1490000000000200001)); + } + + #[test] + fn multiply_by_rational_works() { + assert_eq!(multiply_by_rational(7, 2, 3).unwrap(), 7 * 2 / 3); + assert_eq!(multiply_by_rational(7, 20, 30).unwrap(), 7 * 2 / 3); + assert_eq!(multiply_by_rational(20, 7, 30).unwrap(), 7 * 2 / 3); + + assert_eq!( + // MAX128 % 3 == 0 + multiply_by_rational(MAX128, 2, 3).unwrap(), + MAX128 / 3 * 2, + ); + assert_eq!( + // MAX128 % 7 == 3 + multiply_by_rational(MAX128, 5, 7).unwrap(), + (MAX128 / 7 * 5) + (3 * 5 / 7), + ); + assert_eq!( + // MAX128 % 7 == 3 + multiply_by_rational(MAX128, 11 , 13).unwrap(), + (MAX128 / 13 * 11) + (8 * 11 / 13), + ); + assert_eq!( + // MAX128 % 1000 == 455 + multiply_by_rational(MAX128, 555, 1000).unwrap(), + (MAX128 / 1000 * 555) + (455 * 555 / 1000), + ); + + assert_eq!( + multiply_by_rational(2 * MAX64 - 1, MAX64, MAX64).unwrap(), + 2 * MAX64 - 1, + ); + assert_eq!( + multiply_by_rational(2 * MAX64 - 1, MAX64 - 1, MAX64).unwrap(), + 2 * MAX64 - 3, + ); + + assert_eq!( + multiply_by_rational(MAX64 + 100, MAX64_2, MAX64_2 / 2).unwrap(), + (MAX64 + 100) * 2, + ); + assert_eq!( + multiply_by_rational(MAX64 + 100, MAX64_2 / 100, MAX64_2 / 200).unwrap(), + (MAX64 + 100) * 2, + ); + + assert_eq!( + multiply_by_rational(2u128.pow(66) - 1, 2u128.pow(65) - 1, 2u128.pow(65)).unwrap(), + 73786976294838206461, + ); + assert_eq!( + multiply_by_rational(1_000_000_000, MAX128 / 8, MAX128 / 2).unwrap(), + 250000000, + ); + } + + #[test] + fn multiply_by_rational_a_b_are_interchangeable() { + assert_eq!( + multiply_by_rational(10, MAX128, MAX128 / 2), + Ok(20), + ); + assert_eq!( + multiply_by_rational(MAX128, 10, MAX128 / 2), + Ok(20), + ); + } + + #[test] + #[ignore] + fn multiply_by_rational_fuzzed_equation() { + assert_eq!( + multiply_by_rational(154742576605164960401588224, 9223376310179529214, 549756068598), + Ok(2596149632101417846585204209223679) + ); + } +} diff --git a/core/sr-arithmetic/src/traits.rs b/core/sr-arithmetic/src/traits.rs new file mode 100644 index 0000000000..d02425066f --- /dev/null +++ b/core/sr-arithmetic/src/traits.rs @@ -0,0 +1,143 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Primitives for the runtime modules. + +use rstd::{self, convert::{TryFrom, TryInto}}; +use codec::HasCompact; +pub use integer_sqrt::IntegerSquareRoot; +pub use num_traits::{ + Zero, One, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, + CheckedShl, CheckedShr +}; +use rstd::ops::{ + Add, Sub, Mul, Div, Rem, AddAssign, SubAssign, MulAssign, DivAssign, + RemAssign, Shl, Shr +}; + +/// A meta trait for arithmetic. +/// +/// Arithmetic types do all the usual stuff you'd expect numbers to do. They are guaranteed to +/// be able to represent at least `u32` values without loss, hence the trait implies `From` +/// and smaller ints. All other conversions are fallible. +pub trait SimpleArithmetic: + Zero + One + IntegerSquareRoot + + From + From + From + TryInto + TryInto + TryInto + + TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + + UniqueSaturatedInto + UniqueSaturatedInto + UniqueSaturatedInto + + UniqueSaturatedFrom + UniqueSaturatedInto + UniqueSaturatedFrom + UniqueSaturatedInto + + Add + AddAssign + + Sub + SubAssign + + Mul + MulAssign + + Div + DivAssign + + Rem + RemAssign + + Shl + Shr + + CheckedShl + CheckedShr + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv + + Saturating + PartialOrd + Ord + Bounded + + HasCompact + Sized +{} +impl + From + From + TryInto + TryInto + TryInto + + TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + + UniqueSaturatedInto + UniqueSaturatedInto + UniqueSaturatedInto + + UniqueSaturatedFrom + UniqueSaturatedInto + UniqueSaturatedFrom + + UniqueSaturatedInto + UniqueSaturatedFrom + UniqueSaturatedInto + + Add + AddAssign + + Sub + SubAssign + + Mul + MulAssign + + Div + DivAssign + + Rem + RemAssign + + Shl + Shr + + CheckedShl + CheckedShr + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv + + Saturating + PartialOrd + Ord + Bounded + + HasCompact + Sized +> SimpleArithmetic for T {} + +/// Just like `From` except that if the source value is too big to fit into the destination type +/// then it'll saturate the destination. +pub trait UniqueSaturatedFrom: Sized { + /// Convert from a value of `T` into an equivalent instance of `Self`. + fn unique_saturated_from(t: T) -> Self; +} + +/// Just like `Into` except that if the source value is too big to fit into the destination type +/// then it'll saturate the destination. +pub trait UniqueSaturatedInto: Sized { + /// Consume self to return an equivalent value of `T`. + fn unique_saturated_into(self) -> T; +} + +impl + Bounded + Sized> UniqueSaturatedFrom for S { + fn unique_saturated_from(t: T) -> Self { + S::try_from(t).unwrap_or_else(|_| Bounded::max_value()) + } +} + +impl + Sized> UniqueSaturatedInto for S { + fn unique_saturated_into(self) -> T { + self.try_into().unwrap_or_else(|_| Bounded::max_value()) + } +} + +/// Simple trait to use checked mul and max value to give a saturated mul operation over +/// supported types. +pub trait Saturating { + /// Saturated addition - if the product can't fit in the type then just use max-value. + fn saturating_add(self, o: Self) -> Self; + + /// Saturated subtraction - if the product can't fit in the type then just use max-value. + fn saturating_sub(self, o: Self) -> Self; + + /// Saturated multiply - if the product can't fit in the type then just use max-value. + fn saturating_mul(self, o: Self) -> Self; +} + +impl Saturating for T { + fn saturating_add(self, o: Self) -> Self { + ::saturating_add(self, o) + } + fn saturating_sub(self, o: Self) -> Self { + ::saturating_sub(self, o) + } + fn saturating_mul(self, o: Self) -> Self { + self.checked_mul(&o).unwrap_or_else(Bounded::max_value) + } +} + +/// Convenience type to work around the highly unergonomic syntax needed +/// to invoke the functions of overloaded generic traits, in this case +/// `SaturatedFrom` and `SaturatedInto`. +pub trait SaturatedConversion { + /// Convert from a value of `T` into an equivalent instance of `Self`. + /// + /// This just uses `UniqueSaturatedFrom` internally but with this + /// variant you can provide the destination type using turbofish syntax + /// in case Rust happens not to assume the correct type. + fn saturated_from(t: T) -> Self where Self: UniqueSaturatedFrom { + >::unique_saturated_from(t) + } + + /// Consume self to return an equivalent value of `T`. + /// + /// This just uses `UniqueSaturatedInto` internally but with this + /// variant you can provide the destination type using turbofish syntax + /// in case Rust happens not to assume the correct type. + fn saturated_into(self) -> T where Self: UniqueSaturatedInto { + >::unique_saturated_into(self) + } +} +impl SaturatedConversion for T {} diff --git a/core/sr-primitives/Cargo.toml b/core/sr-primitives/Cargo.toml index ac6e8685e2..249b89acee 100644 --- a/core/sr-primitives/Cargo.toml +++ b/core/sr-primitives/Cargo.toml @@ -5,12 +5,11 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -num-traits = { version = "0.2.8", default-features = false } -integer-sqrt = "0.1.2" serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../primitives", default-features = false } app-crypto = { package = "substrate-application-crypto", path = "../application-crypto", default-features = false } +arithmetic = { package = "sr-arithmetic", path = "../sr-arithmetic", default-features = false } rstd = { package = "sr-std", path = "../sr-std", default-features = false } runtime_io = { package = "sr-io", path = "../sr-io", default-features = false } log = { version = "0.4.8", optional = true } @@ -20,7 +19,6 @@ impl-trait-for-tuples = "0.1.2" [dev-dependencies] serde_json = "1.0.41" -primitive-types = "0.5.1" rand = "0.7.2" substrate-offchain = { path = "../offchain" } @@ -28,7 +26,6 @@ substrate-offchain = { path = "../offchain" } bench = [] default = ["std"] std = [ - "num-traits/std", "serde", "log", "rstd/std", @@ -36,5 +33,6 @@ std = [ "codec/std", "primitives/std", "app-crypto/std", + "arithmetic/std", "rand", ] diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index 7032560d0f..590b6fedd7 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -51,7 +51,6 @@ pub mod testing; pub mod curve; pub mod generic; pub mod offchain; -pub mod sr_arithmetic; pub mod traits; pub mod transaction_validity; pub mod weights; @@ -64,14 +63,14 @@ pub use primitives::{TypeId, crypto::{key_types, KeyTypeId, CryptoType}}; pub use app_crypto::RuntimeAppPublic; /// Re-export top-level arithmetic stuff. -pub use sr_arithmetic::{ +pub use arithmetic::{ Perquintill, Perbill, Permill, Percent, Rational128, Fixed64 }; /// Re-export 128 bit helpers. -pub use sr_arithmetic::helpers_128bit; -/// Re-export big_uint stiff. -pub use sr_arithmetic::biguint; +pub use arithmetic::helpers_128bit; +/// Re-export big_uint stuff. +pub use arithmetic::biguint; /// An abstraction over justification for a block's validity under a consensus algorithm. /// diff --git a/core/sr-primitives/src/sr_arithmetic.rs b/core/sr-primitives/src/sr_arithmetic.rs deleted file mode 100644 index 5f5b5dc1e5..0000000000 --- a/core/sr-primitives/src/sr_arithmetic.rs +++ /dev/null @@ -1,2203 +0,0 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Minimal fixed point arithmetic primitives and types for runtime. - -#[cfg(feature = "std")] -use crate::serde::{Serialize, Deserialize}; - -use rstd::{ - ops, cmp::Ordering, prelude::*, - convert::{TryFrom, TryInto}, -}; -use codec::{Encode, Decode}; -use crate::traits::{ - SaturatedConversion, CheckedSub, CheckedAdd, Bounded, UniqueSaturatedInto, Saturating, Zero, -}; - -macro_rules! implement_per_thing { - ($name:ident, $test_mod:ident, [$($test_units:tt),+], $max:tt, $type:ty, $upper_type:ty, $title:expr $(,)?) => { - /// A fixed point representation of a number between in the range [0, 1]. - /// - #[doc = $title] - #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Ord, PartialOrd))] - #[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq)] - pub struct $name($type); - - impl $name { - /// Nothing. - pub fn zero() -> Self { Self(0) } - - /// `true` if this is nothing. - pub fn is_zero(&self) -> bool { self.0 == 0 } - - /// Everything. - pub fn one() -> Self { Self($max) } - - /// Consume self and deconstruct into a raw numeric type. - pub fn deconstruct(self) -> $type { self.0 } - - /// Return the scale at which this per-thing is working. - pub const fn accuracy() -> $type { $max } - - /// From an explicitly defined number of parts per maximum of the type. - /// - /// This can be called at compile time. - pub const fn from_parts(parts: $type) -> Self { - Self([parts, $max][(parts > $max) as usize]) - } - - /// Converts from a percent. Equal to `x / 100`. - /// - /// This can be created at compile time. - pub const fn from_percent(x: $type) -> Self { - Self([x, 100][(x > 100) as usize] * ($max / 100)) - } - - /// Return the product of multiplication of this value by itself. - pub fn square(self) -> Self { - // both can be safely casted and multiplied. - let p: $upper_type = self.0 as $upper_type * self.0 as $upper_type; - let q: $upper_type = $max as $upper_type * $max as $upper_type; - Self::from_rational_approximation(p, q) - } - - /// Converts a fraction into `Permill`. - #[cfg(feature = "std")] - pub fn from_fraction(x: f64) -> Self { Self((x * ($max as f64)) as $type) } - - /// Approximate the fraction `p/q` into a per-thing fraction. This will never overflow. - /// - /// The computation of this approximation is performed in the generic type `N`. Given - /// `M` as the data type that can hold the maximum value of this per-thing (e.g. u32 for - /// perbill), this can only work if `N == M` or `N: From + TryInto`. - pub fn from_rational_approximation(p: N, q: N) -> Self - where N: Clone + Ord + From<$type> + TryInto<$type> + ops::Div - { - // q cannot be zero. - let q = q.max((1 as $type).into()); - // p should not be bigger than q. - let p = p.min(q.clone()); - - let factor = (q.clone() / $max.into()).max((1 as $type).into()); - - // q cannot overflow: (q / (q/$max)) < 2 * $max. p < q hence p also cannot overflow. - // this implies that $type must be able to fit 2 * $max. - let q_reduce: $type = (q / factor.clone()) - .try_into() - .map_err(|_| "Failed to convert") - .expect( - "q / (q/$max) < (2 * $max). Macro prevents any type being created that \ - does not satisfy this; qed" - ); - let p_reduce: $type = (p / factor.clone()) - .try_into() - .map_err(|_| "Failed to convert") - .expect( - "q / (q/$max) < (2 * $max). Macro prevents any type being created that \ - does not satisfy this; qed" - ); - - // `p_reduced` and `q_reduced` are withing $type. Mul by another $max will always - // fit in $upper_type. This is guaranteed by the macro tests. - let part = - p_reduce as $upper_type - * ($max as $upper_type) - / q_reduce as $upper_type; - - $name(part as $type) - } - } - - impl Saturating for $name { - fn saturating_add(self, rhs: Self) -> Self { - // defensive-only: since `$max * 2 < $type::max_value()`, this can never overflow. - Self::from_parts(self.0.saturating_add(rhs.0)) - } - fn saturating_sub(self, rhs: Self) -> Self { - Self::from_parts(self.0.saturating_sub(rhs.0)) - } - fn saturating_mul(self, rhs: Self) -> Self { - let a = self.0 as $upper_type; - let b = rhs.0 as $upper_type; - let m = $max as $upper_type; - let parts = a * b / m; - // This will always fit into $type. - Self::from_parts(parts as $type) - } - } - - impl ops::Div for $name { - type Output = Self; - - fn div(self, rhs: Self) -> Self::Output { - let p = self.0; - let q = rhs.0; - Self::from_rational_approximation(p, q) - } - } - - /// Overflow-prune multiplication. - /// - /// tailored to be used with a balance type. - impl ops::Mul for $name - where - N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem - + ops::Div + ops::Mul + ops::Add, - { - type Output = N; - fn mul(self, b: N) -> Self::Output { - let maximum: N = $max.into(); - let upper_max: $upper_type = $max.into(); - let part: N = self.0.into(); - - let rem_multiplied_divided = { - let rem = b.clone().rem(maximum.clone()); - - // `rem_sized` is inferior to $max, thus it fits into $type. This is assured by - // a test. - let rem_sized = rem.saturated_into::<$type>(); - - // `self` and `rem_sized` are inferior to $max, thus the product is less than - // $max^2 and fits into $upper_type. This is assured by a test. - let rem_multiplied_upper = rem_sized as $upper_type * self.0 as $upper_type; - - // `rem_multiplied_upper` is less than $max^2 therefore divided by $max it fits - // in $type. remember that $type always fits $max. - let mut rem_multiplied_divided_sized = - (rem_multiplied_upper / upper_max) as $type; - // fix a tiny rounding error - if rem_multiplied_upper % upper_max > upper_max / 2 { - rem_multiplied_divided_sized += 1; - } - - // `rem_multiplied_divided_sized` is inferior to b, thus it can be converted - // back to N type - rem_multiplied_divided_sized.into() - }; - - (b / maximum) * part + rem_multiplied_divided - } - } - - impl codec::CompactAs for $name { - type As = $type; - fn encode_as(&self) -> &$type { - &self.0 - } - fn decode_from(x: $type) -> Self { - Self(x) - } - } - - impl From> for $name { - fn from(x: codec::Compact<$name>) -> Self { - x.0 - } - } - - #[cfg(test)] - mod $test_mod { - use codec::{Encode, Decode}; - use super::{$name, Saturating}; - use crate::{assert_eq_error_rate, traits::Zero}; - - - #[test] - fn macro_expanded_correctly() { - // needed for the `from_percent` to work. - assert!($max >= 100); - assert!($max % 100 == 0); - - // needed for `from_rational_approximation` - assert!(2 * $max < <$type>::max_value()); - assert!(($max as $upper_type) < <$upper_type>::max_value()); - - // for something like percent they can be the same. - assert!((<$type>::max_value() as $upper_type) <= <$upper_type>::max_value()); - assert!(($max as $upper_type).checked_mul($max.into()).is_some()); - } - - #[derive(Encode, Decode, PartialEq, Eq, Debug)] - struct WithCompact { - data: T, - } - - #[test] - fn has_compact() { - let data = WithCompact { data: $name(1) }; - let encoded = data.encode(); - assert_eq!(data, WithCompact::<$name>::decode(&mut &encoded[..]).unwrap()); - } - - #[test] - fn compact_encoding() { - let tests = [ - // assume all per_things have the size u8 at least. - (0 as $type, 1usize), - (1 as $type, 1usize), - (63, 1), - (64, 2), - (65, 2), - (<$type>::max_value(), <$type>::max_value().encode().len() + 1) - ]; - for &(n, l) in &tests { - let compact: crate::codec::Compact<$name> = $name(n).into(); - let encoded = compact.encode(); - assert_eq!(encoded.len(), l); - let decoded = >::decode(&mut & encoded[..]) - .unwrap(); - let per_thingy: $name = decoded.into(); - assert_eq!(per_thingy, $name(n)); - } - } - - #[test] - fn per_thing_api_works() { - // some really basic stuff - assert_eq!($name::zero(), $name::from_parts(Zero::zero())); - assert_eq!($name::one(), $name::from_parts($max)); - assert_eq!($name::accuracy(), $max); - assert_eq!($name::from_percent(0), $name::from_parts(Zero::zero())); - assert_eq!($name::from_percent(10), $name::from_parts($max / 10)); - assert_eq!($name::from_percent(100), $name::from_parts($max)); - } - - macro_rules! per_thing_mul_test { - ($num_type:tt) => { - // multiplication from all sort of from_percent - assert_eq!( - $name::from_percent(100) * $num_type::max_value(), - $num_type::max_value() - ); - assert_eq_error_rate!( - $name::from_percent(99) * $num_type::max_value(), - ((Into::::into($num_type::max_value()) * 99u32) / 100u32).as_u128() as $num_type, - 1, - ); - assert_eq!( - $name::from_percent(50) * $num_type::max_value(), - $num_type::max_value() / 2, - ); - assert_eq_error_rate!( - $name::from_percent(1) * $num_type::max_value(), - $num_type::max_value() / 100, - 1, - ); - assert_eq!($name::from_percent(0) * $num_type::max_value(), 0); - - // // multiplication with bounds - assert_eq!($name::one() * $num_type::max_value(), $num_type::max_value()); - assert_eq!($name::zero() * $num_type::max_value(), 0); - } - } - - #[test] - fn per_thing_mul_works() { - use primitive_types::U256; - - // accuracy test - assert_eq!($name::from_rational_approximation(1 as $type, 3) * 30 as $type, 10); - - $(per_thing_mul_test!($test_units);)* - } - - #[test] - fn per_thing_mul_rounds_to_nearest_number() { - assert_eq!($name::from_percent(33) * 10u64, 3); - assert_eq!($name::from_percent(34) * 10u64, 3); - assert_eq!($name::from_percent(35) * 10u64, 3); - assert_eq!($name::from_percent(36) * 10u64, 4); - assert_eq!($name::from_percent(36) * 10u64, 4); - } - - #[test] - fn per_thing_multiplication_with_large_number() { - use primitive_types::U256; - let max_minus_one = $max - 1; - assert_eq_error_rate!( - $name::from_parts(max_minus_one) * std::u128::MAX, - ((Into::::into(std::u128::MAX) * max_minus_one) / $max).as_u128(), - 1, - ); - } - - macro_rules! per_thing_from_rationale_approx_test { - ($num_type:tt) => { - // within accuracy boundary - assert_eq!( - $name::from_rational_approximation(1 as $num_type, 0), - $name::one(), - ); - assert_eq!( - $name::from_rational_approximation(1 as $num_type, 1), - $name::one(), - ); - assert_eq_error_rate!( - $name::from_rational_approximation(1 as $num_type, 3).0, - $name::from_parts($max / 3).0, - 2 - ); - assert_eq!( - $name::from_rational_approximation(1 as $num_type, 10), - $name::from_percent(10), - ); - assert_eq!( - $name::from_rational_approximation(1 as $num_type, 4), - $name::from_percent(25), - ); - assert_eq!( - $name::from_rational_approximation(1 as $num_type, 4), - $name::from_rational_approximation(2 as $num_type, 8), - ); - // no accurate anymore but won't overflow. - assert_eq!( - $name::from_rational_approximation( - $num_type::max_value() - 1, - $num_type::max_value() - ), - $name::one(), - ); - assert_eq_error_rate!( - $name::from_rational_approximation( - $num_type::max_value() / 3, - $num_type::max_value() - ).0, - $name::from_parts($max / 3).0, - 2 - ); - assert_eq!( - $name::from_rational_approximation(1, $num_type::max_value()), - $name::zero(), - ); - }; - } - - #[test] - fn per_thing_from_rationale_approx_works() { - // This is just to make sure something like Percent which _might_ get built from a - // u8 does not overflow in the context of this test. - let max_value = $max as $upper_type; - // almost at the edge - assert_eq!( - $name::from_rational_approximation($max - 1, $max + 1), - $name::from_parts($max - 2), - ); - assert_eq!( - $name::from_rational_approximation(1, $max-1), - $name::from_parts(1), - ); - assert_eq!( - $name::from_rational_approximation(1, $max), - $name::from_parts(1), - ); - assert_eq!( - $name::from_rational_approximation(2, 2 * $max - 1), - $name::from_parts(1), - ); - assert_eq!( - $name::from_rational_approximation(1, $max+1), - $name::zero(), - ); - assert_eq!( - $name::from_rational_approximation(3 * max_value / 2, 3 * max_value), - $name::from_percent(50), - ); - $(per_thing_from_rationale_approx_test!($test_units);)* - } - - #[test] - fn per_things_mul_operates_in_output_type() { - // assert_eq!($name::from_percent(50) * 100u32, 50u32); - assert_eq!($name::from_percent(50) * 100u64, 50u64); - assert_eq!($name::from_percent(50) * 100u128, 50u128); - } - - #[test] - fn per_thing_saturating_op_works() { - assert_eq!( - $name::from_percent(50).saturating_add($name::from_percent(40)), - $name::from_percent(90) - ); - assert_eq!( - $name::from_percent(50).saturating_add($name::from_percent(50)), - $name::from_percent(100) - ); - assert_eq!( - $name::from_percent(60).saturating_add($name::from_percent(50)), - $name::from_percent(100) - ); - - assert_eq!( - $name::from_percent(60).saturating_sub($name::from_percent(50)), - $name::from_percent(10) - ); - assert_eq!( - $name::from_percent(60).saturating_sub($name::from_percent(60)), - $name::from_percent(0) - ); - assert_eq!( - $name::from_percent(60).saturating_sub($name::from_percent(70)), - $name::from_percent(0) - ); - - assert_eq!( - $name::from_percent(50).saturating_mul($name::from_percent(50)), - $name::from_percent(25) - ); - assert_eq!( - $name::from_percent(20).saturating_mul($name::from_percent(20)), - $name::from_percent(4) - ); - assert_eq!( - $name::from_percent(10).saturating_mul($name::from_percent(10)), - $name::from_percent(1) - ); - } - - #[test] - fn per_thing_square_works() { - assert_eq!($name::from_percent(100).square(), $name::from_percent(100)); - assert_eq!($name::from_percent(50).square(), $name::from_percent(25)); - assert_eq!($name::from_percent(10).square(), $name::from_percent(1)); - assert_eq!( - $name::from_percent(2).square(), - $name::from_parts((4 * ($max as $upper_type) / 100 / 100) as $type) - ); - } - - #[test] - fn per_things_div_works() { - // normal - assert_eq!($name::from_percent(10) / $name::from_percent(20), - $name::from_percent(50) - ); - assert_eq!($name::from_percent(10) / $name::from_percent(10), - $name::from_percent(100) - ); - assert_eq!($name::from_percent(10) / $name::from_percent(0), - $name::from_percent(100) - ); - - // will not overflow - assert_eq!($name::from_percent(10) / $name::from_percent(5), - $name::from_percent(100) - ); - assert_eq!($name::from_percent(100) / $name::from_percent(50), - $name::from_percent(100) - ); - } - } - }; -} - -implement_per_thing!( - Percent, - test_per_cent, - [u32, u64, u128], - 100u8, - u8, - u16, - "_Percent_", -); -implement_per_thing!( - Permill, - test_permill, - [u32, u64, u128], - 1_000_000u32, - u32, - u64, - "_Parts per Million_", -); -implement_per_thing!( - Perbill, - test_perbill, - [u32, u64, u128], - 1_000_000_000u32, - u32, - u64, - "_Parts per Billion_", -); -implement_per_thing!( - Perquintill, - test_perquintill, - [u64, u128], - 1_000_000_000_000_000_000u64, - u64, - u128, - "_Parts per Quintillion_", -); - -/// An unsigned fixed point number. Can hold any value in the range [-9_223_372_036, 9_223_372_036] -/// with fixed point accuracy of one billion. -#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct Fixed64(i64); - -/// The accuracy of the `Fixed64` type. -const DIV: i64 = 1_000_000_000; - -impl Fixed64 { - /// creates self from a natural number. - /// - /// Note that this might be lossy. - pub fn from_natural(int: i64) -> Self { - Self(int.saturating_mul(DIV)) - } - - /// Return the accuracy of the type. Given that this function returns the value `X`, it means - /// that an instance composed of `X` parts (`Fixed64::from_parts(X)`) is equal to `1`. - pub fn accuracy() -> i64 { - DIV - } - - /// Raw constructor. Equal to `parts / 1_000_000_000`. - pub fn from_parts(parts: i64) -> Self { - Self(parts) - } - - /// creates self from a rational number. Equal to `n/d`. - /// - /// Note that this might be lossy. - pub fn from_rational(n: i64, d: u64) -> Self { - Self( - ((n as i128).saturating_mul(DIV as i128) / (d as i128).max(1)) - .try_into() - .unwrap_or(Bounded::max_value()) - ) - } - - /// Performs a saturated multiply and accumulate by unsigned number. - /// - /// Returns a saturated `int + (self * int)`. - pub fn saturated_multiply_accumulate(&self, int: N) -> N - where - N: TryFrom + From + UniqueSaturatedInto + Bounded + Clone + Saturating + - ops::Rem + ops::Div + ops::Mul + - ops::Add, - { - let div = DIV as u64; - let positive = self.0 > 0; - // safe to convert as absolute value. - let parts = self.0.checked_abs().map(|v| v as u64).unwrap_or(i64::max_value() as u64 + 1); - - - // will always fit. - let natural_parts = parts / div; - // might saturate. - let natural_parts: N = natural_parts.saturated_into(); - // fractional parts can always fit into u32. - let perbill_parts = (parts % div) as u32; - - let n = int.clone().saturating_mul(natural_parts); - let p = Perbill::from_parts(perbill_parts) * int.clone(); - - // everything that needs to be either added or subtracted from the original weight. - let excess = n.saturating_add(p); - - if positive { - int.saturating_add(excess) - } else { - int.saturating_sub(excess) - } - } -} - -impl Saturating for Fixed64 { - fn saturating_add(self, rhs: Self) -> Self { - Self(self.0.saturating_add(rhs.0)) - } - fn saturating_mul(self, rhs: Self) -> Self { - Self(self.0.saturating_mul(rhs.0) / DIV) - } - fn saturating_sub(self, rhs: Self) -> Self { - Self(self.0.saturating_sub(rhs.0)) - } -} - -/// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait -/// for safe addition. -impl ops::Add for Fixed64 { - type Output = Self; - - fn add(self, rhs: Self) -> Self::Output { - Self(self.0 + rhs.0) - } -} - -/// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait -/// for safe subtraction. -impl ops::Sub for Fixed64 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self::Output { - Self(self.0 - rhs.0) - } -} - -impl CheckedSub for Fixed64 { - fn checked_sub(&self, rhs: &Self) -> Option { - if let Some(v) = self.0.checked_sub(rhs.0) { - Some(Self(v)) - } else { - None - } - } -} - -impl CheckedAdd for Fixed64 { - fn checked_add(&self, rhs: &Self) -> Option { - if let Some(v) = self.0.checked_add(rhs.0) { - Some(Self(v)) - } else { - None - } - } -} - -#[cfg(feature = "std")] -impl rstd::fmt::Debug for Fixed64 { - fn fmt(&self, f: &mut rstd::fmt::Formatter<'_>) -> rstd::fmt::Result { - write!(f, "Fixed64({},{})", self.0 / DIV, (self.0 % DIV) / 1000) - } -} - -/// Infinite precision unsigned integer for substrate runtime. -pub mod biguint { - use super::Zero; - use rstd::{cmp::Ordering, ops, prelude::*, cell::RefCell, convert::TryFrom}; - - // A sensible value for this would be half of the dword size of the host machine. Since the - // runtime is compiled to 32bit webassembly, using 32 and 64 for single and double respectively - // should yield the most performance. TODO #3745 we could benchmark this and verify. - /// Representation of a single limb. - pub type Single = u32; - /// Representation of two limbs. - pub type Double = u64; - /// Difference in the number of bits of [`Single`] and [`Double`]. - const SHIFT: usize = 32; - /// short form of _Base_. Analogous to the value 10 in base-10 decimal numbers. - const B: Double = Single::max_value() as Double + 1; - - /// Splits a [`Double`] limb number into a tuple of two [`Single`] limb numbers. - pub fn split(a: Double) -> (Single, Single) { - let al = a as Single; - let ah = (a >> SHIFT) as Single; - (ah, al) - } - - /// Assumed as a given primitive. - /// - /// Multiplication of two singles, which at most yields 1 double. - pub fn mul_single(a: Single, b: Single) -> Double { - let a: Double = a.into(); - let b: Double = b.into(); - let r = a * b; - r - } - - /// Assumed as a given primitive. - /// - /// Addition of two singles, which at most takes a single limb of result and a carry, - /// returned as a tuple respectively. - pub fn add_single(a: Single, b: Single) -> (Single, Single) { - let a: Double = a.into(); - let b: Double = b.into(); - let q = a + b; - let (carry, r) = split(q); - (r, carry) - } - - /// Assumed as a given primitive. - /// - /// Division of double by a single limb. Always returns a double limb of quotient and a single - /// limb of remainder. - fn div_single(a: Double, b: Single) -> (Double, Single) { - let b: Double = b.into(); - let q = a / b; - let r = a % b; - // both conversions are trivially safe. - (q, r as Single) - } - - /// Simple wrapper around an infinitely large integer, represented as limbs of [`Single`]. - #[derive(Clone, Default)] - pub struct BigUint { - /// digits (limbs) of this number (sorted as msb -> lsd). - pub(crate) digits: Vec, - } - - impl BigUint { - /// Create a new instance with `size` limbs. This prevents any number with zero limbs to be - /// created. - /// - /// The behavior of the type is undefined with zero limbs. - pub fn with_capacity(size: usize) -> Self { - Self { digits: vec![0; size.max(1)] } - } - - /// Raw constructor from custom limbs. If `limbs` is empty, `Zero::zero()` implementation is - /// used. - pub fn from_limbs(limbs: &[Single]) -> Self { - if limbs.len() > 0 { - Self { digits: limbs.to_vec() } - } else { - Zero::zero() - } - } - - /// Number of limbs. - pub fn len(&self) -> usize { self.digits.len() } - - /// A naive getter for limb at `index`. Note that the order is lsb -> msb. - /// - /// #### Panics - /// - /// This panics if index is out of range. - pub fn get(&self, index: usize) -> Single { - self.digits[self.len() - 1 - index] - } - - /// A naive getter for limb at `index`. Note that the order is lsb -> msb. - pub fn checked_get(&self, index: usize) -> Option { - if let Some(i) = self.len().checked_sub(1) { - if let Some(j) = i.checked_sub(index) { - return self.digits.get(j).cloned(); - } - } - return None; - } - - /// A naive setter for limb at `index`. Note that the order is lsb -> msb. - /// - /// #### Panics - /// - /// This panics if index is out of range. - pub fn set(&mut self, index: usize, value: Single) { - let len = self.digits.len(); - self.digits[len - 1 - index] = value; - } - - /// returns the least significant limb of the number. - /// - /// #### Panics - /// - /// While the constructor of the type prevents this, this can panic if `self` has no digits. - pub fn lsb(&self) -> Single { - self.digits[self.len() - 1] - } - - /// returns the most significant limb of the number. - /// - /// #### Panics - /// - /// While the constructor of the type prevents this, this can panic if `self` has no digits. - pub fn msb(&self) -> Single { - self.digits[0] - } - - /// Strips zeros from the left side of `self`, if any. - pub fn lstrip(&mut self) { - // by definition, a big-int number should never have leading zero limbs. This function - // has the ability to cause this. There is nothing to do if the number already has 1 - // limb only. call it a day and return. - if self.len().is_zero() { return; } - let mut index = 0; - for elem in self.digits.iter() { - if *elem != 0 { break } else { index += 1 } - } - if index > 0 { - self.digits = self.digits[index..].to_vec() - } - } - - /// Zero-pad `self` from left to reach `size` limbs. Will not make any difference if `self` - /// is already bigger than `size` limbs. - pub fn lpad(&mut self, size: usize) { - let n = self.len(); - if n >= size { return; } - let pad = size - n; - let mut new_digits = (0..pad).map(|_| 0).collect::>(); - new_digits.extend(self.digits.iter()); - self.digits = new_digits; - } - - /// Adds `self` with `other`. self and other do not have to have any particular size. Given - /// that the `n = max{size(self), size(other)}`, it will produce a number with `n + 1` - /// limbs. - /// - /// This function does not strip the output and returns the original allocated `n + 1` - /// limbs. The caller may strip the output if desired. - /// - /// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4. - pub fn add(self, other: &Self) -> Self { - let n = self.len().max(other.len()); - let mut k: Double = 0; - let mut w = Self::with_capacity(n + 1); - - for j in 0..n { - let u = Double::from(self.checked_get(j).unwrap_or(0)); - let v = Double::from(other.checked_get(j).unwrap_or(0)); - let s = u + v + k; - w.set(j, (s % B) as Single); - k = s / B; - } - // k is always 0 or 1. - w.set(n, k as Single); - w - } - - /// Subtracts `other` from `self`. self and other do not have to have any particular size. - /// Given that the `n = max{size(self), size(other)}`, it will produce a number of size `n`. - /// - /// If `other` is bigger than `self`, `Err(B - borrow)` is returned. - /// - /// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4. - pub fn sub(self, other: &Self) -> Result { - let n = self.len().max(other.len()); - let mut k = 0; - let mut w = Self::with_capacity(n); - for j in 0..n { - let s = { - let u = Double::from(self.checked_get(j).unwrap_or(0)); - let v = Double::from(other.checked_get(j).unwrap_or(0)); - let mut needs_borrow = false; - let mut t = 0; - - if let Some(v) = u.checked_sub(v) { - if let Some(v2) = v.checked_sub(k) { - t = v2 % B; - k = 0; - } else { - needs_borrow = true; - } - } else { - needs_borrow = true; - } - if needs_borrow { - t = u + B - v - k; - k = 1; - } - t - }; - // PROOF: t either comes from `v2 % B`, or from `u + B - v - k`. The former is - // trivial. The latter will not overflow this branch will only happen if the sum of - // `u - v - k` part has been negative, hence `u + B - v - k < b`. - w.set(j, s as Single); - } - - if k.is_zero() { - Ok(w) - } else { - Err(w) - } - } - - /// Multiplies n-limb number `self` with m-limb number `other`. - /// - /// The resulting number will always have `n + m` limbs. - /// - /// This function does not strip the output and returns the original allocated `n + m` - /// limbs. The caller may strip the output if desired. - /// - /// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4. - pub fn mul(self, other: &Self) -> Self { - let n = self.len(); - let m = other.len(); - let mut w = Self::with_capacity(m + n); - - for j in 0..n { - if self.get(j) == 0 { - // Note: `with_capacity` allocates with 0. Explicitly set j + m to zero if - // otherwise. - continue; - } - - let mut k = 0; - for i in 0..m { - // PROOF: (B−1) × (B−1) + (B−1) + (B−1) = B^2 −1 < B^2. addition is safe. - let t = - mul_single(self.get(j), other.get(i)) - + Double::from(w.get(i + j)) - + Double::from(k); - w.set(i + j, (t % B) as Single); - // PROOF: (B^2 - 1) / B < B. conversion is safe. - k = (t / B) as Single; - } - w.set(j + m, k); - } - w - } - - /// Divides `self` by a single limb `other`. This can be used in cases where the original - /// division cannot work due to the divisor (`other`) being just one limb. - /// - /// Invariant: `other` cannot be zero. - pub fn div_unit(self, mut other: Single) -> Self { - other = other.max(1); - let n = self.len(); - let mut out = Self::with_capacity(n); - let mut r: Single = 0; - // PROOF: (B-1) * B + (B-1) still fits in double - let with_r = |x: Double, r: Single| { r as Double * B + x }; - for d in (0..=n-1).rev() { - let (q, rr) = div_single(with_r(self.get(d).into(), r), other) ; - out.set(d, q as Single); - r = rr; - } - out - } - - /// Divides an `n + m` limb self by a `n` limb `other`. The result is a `m + 1` limb - /// quotient and a `n` limb remainder, if enabled by passing `true` in `rem` argument, both - /// in the form of an option's `Ok`. - /// - /// - requires `other` to be stripped and have no leading zeros. - /// - requires `self` to be stripped and have no leading zeros. - /// - requires `other` to have at least two limbs. - /// - requires `self` to have a greater length compared to `other`. - /// - /// All arguments are examined without being stripped for the above conditions. If any of - /// the above fails, `None` is returned.` - /// - /// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4. - pub fn div(self, other: &Self, rem: bool) -> Option<(Self, Self)> { - if other.len() <= 1 - || other.msb() == 0 - || self.msb() == 0 - || self.len() <= other.len() - { - return None - } - let n = other.len(); - let m = self.len() - n; - - let mut q = Self::with_capacity(m + 1); - let mut r = Self::with_capacity(n); - - // PROOF: 0 <= normalizer_bits < SHIFT 0 <= normalizer < B. all conversions are - // safe. - let normalizer_bits = other.msb().leading_zeros() as Single; - let normalizer = (2 as Single).pow(normalizer_bits as u32) as Single; - - // step D1. - let mut self_norm = self.mul(&Self::from(normalizer)); - let mut other_norm = other.clone().mul(&Self::from(normalizer)); - - // defensive only; the mul implementation should always create this. - self_norm.lpad(n + m + 1); - other_norm.lstrip(); - - // step D2. - for j in (0..=m).rev() { - // step D3.0 Find an estimate of q[j], named qhat. - let (qhat, rhat) = { - // PROOF: this always fits into `Double`. In the context of Single = u8, and - // Double = u16, think of 255 * 256 + 255 which is just u16::max_value(). - let dividend = - Double::from(self_norm.get(j + n)) - * B - + Double::from(self_norm.get(j + n - 1)); - let divisor = other_norm.get(n - 1); - div_single(dividend, divisor.into()) - }; - - // D3.1 test qhat - // replace qhat and rhat with RefCells. This helps share state with the closure - let qhat = RefCell::new(qhat); - let rhat = RefCell::new(rhat as Double); - - let test = || { - // decrease qhat if it is bigger than the base (B) - let qhat_local = *qhat.borrow(); - let rhat_local = *rhat.borrow(); - let predicate_1 = qhat_local >= B; - let predicate_2 = { - let lhs = qhat_local * other_norm.get(n - 2) as Double; - let rhs = B * rhat_local + self_norm.get(j + n - 2) as Double; - lhs > rhs - }; - if predicate_1 || predicate_2 { - *qhat.borrow_mut() -= 1; - *rhat.borrow_mut() += other_norm.get(n - 1) as Double; - true - } else { - false - } - }; - - test(); - while (*rhat.borrow() as Double) < B { - if !test() { break; } - } - - let qhat = qhat.into_inner(); - // we don't need rhat anymore. just let it go out of scope when it does. - - // step D4 - let lhs = Self { digits: (j..=j+n).rev().map(|d| self_norm.get(d)).collect() }; - let rhs = other_norm.clone().mul(&Self::from(qhat)); - - let maybe_sub = lhs.sub(&rhs); - let mut negative = false; - let sub = match maybe_sub { - Ok(t) => t, - Err(t) => { negative = true; t } - }; - (j..=j+n).for_each(|d| { self_norm.set(d, sub.get(d - j)); }); - - // step D5 - // PROOF: the `test()` specifically decreases qhat until it is below `B`. conversion - // is safe. - q.set(j, qhat as Single); - - // step D6: add back if negative happened. - if negative { - q.set(j, q.get(j) - 1); - let u = Self { digits: (j..=j+n).rev().map(|d| self_norm.get(d)).collect() }; - let r = other_norm.clone().add(&u); - (j..=j+n).rev().for_each(|d| { self_norm.set(d, r.get(d - j)); }) - } - } - - // if requested, calculate remainder. - if rem { - // undo the normalization. - if normalizer_bits > 0 { - let s = SHIFT as u32; - let nb = normalizer_bits; - for d in 0..n-1 { - let v = self_norm.get(d) >> nb - | self_norm.get(d + 1).overflowing_shl(s - nb).0; - r.set(d, v); - } - r.set(n - 1, self_norm.get(n - 1) >> normalizer_bits); - } else { - r = self_norm; - } - } - - Some((q, r)) - } - } - - #[cfg(feature = "std")] - impl rstd::fmt::Debug for BigUint { - fn fmt(&self, f: &mut rstd::fmt::Formatter<'_>) -> rstd::fmt::Result { - write!( - f, - "BigUint {{ {:?} ({:?})}}", - self.digits, - u128::try_from(self.clone()).unwrap_or_else(|_| 0), - ) - } - } - - impl PartialEq for BigUint { - fn eq(&self, other: &Self) -> bool { - // sadly, we have to reallocate here as strip mutably uses self. - let mut lhs = self.clone(); - let mut rhs = other.clone(); - lhs.lstrip(); - rhs.lstrip(); - lhs.digits.eq(&rhs.digits) - } - } - - impl Eq for BigUint {} - - impl Ord for BigUint { - fn cmp(&self, other: &Self) -> Ordering { - let lhs_first = self.digits.iter().position(|&e| e != 0); - let rhs_first = other.digits.iter().position(|&e| e != 0); - - match (lhs_first, rhs_first) { - // edge cases that should not happen. This basically means that one or both were - // zero. - (None, None) => Ordering::Equal, - (Some(_), None) => Ordering::Greater, - (None, Some(_)) => Ordering::Less, - (Some(lhs_idx), Some(rhs_idx)) => { - let lhs = &self.digits[lhs_idx..]; - let rhs = &other.digits[rhs_idx..]; - let len_cmp = lhs.len().cmp(&rhs.len()); - match len_cmp { - Ordering::Equal => lhs.cmp(rhs), - _ => len_cmp, - } - } - } - } - } - - impl PartialOrd for BigUint { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } - } - - impl ops::Add for BigUint { - type Output = Self; - fn add(self, rhs: Self) -> Self::Output { - self.add(&rhs) - } - } - - impl ops::Sub for BigUint { - type Output = Self; - fn sub(self, rhs: Self) -> Self::Output { - self.sub(&rhs).unwrap_or_else(|e| e) - } - } - - impl ops::Mul for BigUint { - type Output = Self; - fn mul(self, rhs: Self) -> Self::Output { - self.mul(&rhs) - } - } - - impl Zero for BigUint { - fn zero() -> Self { - Self { digits: vec![Zero::zero()] } - } - - fn is_zero(&self) -> bool { - self.digits.iter().all(|d| d.is_zero()) - } - } - - macro_rules! impl_try_from_number_for { - ($([$type:ty, $len:expr]),+) => { - $( - impl TryFrom for $type { - type Error = &'static str; - fn try_from(mut value: BigUint) -> Result<$type, Self::Error> { - value.lstrip(); - let error_message = concat!("cannot fit a number into ", stringify!($type)); - if value.len() * SHIFT > $len { - Err(error_message) - } else { - let mut acc: $type = Zero::zero(); - for (i, d) in value.digits.iter().rev().cloned().enumerate() { - let d: $type = d.into(); - acc += d << (SHIFT * i); - } - Ok(acc) - } - } - } - )* - }; - } - // can only be implemented for sizes bigger than two limb. - impl_try_from_number_for!([u128, 128], [u64, 64]); - - macro_rules! impl_from_for_smaller_than_word { - ($($type:ty),+) => { - $(impl From<$type> for BigUint { - fn from(a: $type) -> Self { - Self { digits: vec! [a.into()] } - } - })* - } - } - impl_from_for_smaller_than_word!(u8, u16, Single); - - impl From for BigUint { - fn from(a: Double) -> Self { - let (ah, al) = split(a); - Self { digits: vec![ah, al] } - } - } - - #[cfg(test)] - pub mod tests_biguint { - use super::*; - use rand::Rng; - #[cfg(feature = "bench")] - use test::Bencher; - - // TODO move into a proper fuzzer #3745 - const FUZZ_COUNT: usize = 100_000; - - pub fn random_big_uint(size: usize) -> BigUint { - let mut rng = rand::thread_rng(); - let digits = (0..size).map(|_| rng.gen_range(0, Single::max_value())).collect(); - BigUint { digits } - } - - fn run_with_data_set( - count: usize, - limbs_ub_1: usize, - limbs_ub_2: usize, - exact: bool, - assertion: F, - ) where - F: Fn(BigUint, BigUint) -> () - { - let mut rng = rand::thread_rng(); - for _ in 0..count { - let digits_len_1 = if exact { limbs_ub_1 } else { rng.gen_range(1, limbs_ub_1) }; - let digits_len_2 = if exact { limbs_ub_2 } else { rng.gen_range(1, limbs_ub_2) }; - - let u = random_big_uint(digits_len_1); - let v = random_big_uint(digits_len_2); - assertion(u, v); - } - } - - fn with_limbs(n: usize) -> BigUint { - BigUint { digits: vec![1; n] } - } - - #[test] - fn split_works() { - let a = SHIFT / 2; - let b = SHIFT * 3 / 2; - let num: Double = 1 << a | 1 << b; - // example when `Single = u8` - // assert_eq!(num, 0b_0001_0000_0001_0000) - assert_eq!(split(num), (1 << a, 1 << a)); - } - - #[test] - fn strip_works() { - let mut a = BigUint::from_limbs(&[0, 1, 0]); - a.lstrip(); - assert_eq!(a, BigUint { digits: vec![1, 0] }); - - let mut a = BigUint::from_limbs(&[0, 0, 1]); - a.lstrip(); - assert_eq!(a, BigUint { digits: vec![1] }); - - let mut a = BigUint::from_limbs(&[0, 0]); - a.lstrip(); - assert_eq!(a, BigUint { digits: vec![0] }); - - let mut a = BigUint::from_limbs(&[0, 0, 0]); - a.lstrip(); - assert_eq!(a, BigUint { digits: vec![0] }); - } - - #[test] - fn lpad_works() { - let mut a = BigUint::from_limbs(&[0, 1, 0]); - a.lpad(2); - assert_eq!(a.digits, vec![0, 1, 0]); - - let mut a = BigUint::from_limbs(&[0, 1, 0]); - a.lpad(3); - assert_eq!(a.digits, vec![0, 1, 0]); - - let mut a = BigUint::from_limbs(&[0, 1, 0]); - a.lpad(4); - assert_eq!(a.digits, vec![0, 0, 1, 0]); - } - - #[test] - fn equality_works() { - assert_eq!( - BigUint { digits: vec![1, 2, 3] } == BigUint { digits: vec![1, 2, 3] }, - true, - ); - assert_eq!( - BigUint { digits: vec![3, 2, 3] } == BigUint { digits: vec![1, 2, 3] }, - false, - ); - assert_eq!( - BigUint { digits: vec![0, 1, 2, 3] } == BigUint { digits: vec![1, 2, 3] }, - true, - ); - } - - #[test] - fn ordering_works() { - assert!(BigUint { digits: vec![0] } < BigUint { digits: vec![1] }); - assert!(BigUint { digits: vec![0] } == BigUint { digits: vec![0] }); - assert!(BigUint { digits: vec![] } == BigUint { digits: vec![0] }); - assert!(BigUint { digits: vec![] } == BigUint { digits: vec![] }); - assert!(BigUint { digits: vec![] } < BigUint { digits: vec![1] }); - - assert!(BigUint { digits: vec![1, 2, 3] } == BigUint { digits: vec![1, 2, 3] }); - assert!(BigUint { digits: vec![0, 1, 2, 3] } == BigUint { digits: vec![1, 2, 3] }); - - assert!(BigUint { digits: vec![1, 2, 4] } > BigUint { digits: vec![1, 2, 3] }); - assert!(BigUint { digits: vec![0, 1, 2, 4] } > BigUint { digits: vec![1, 2, 3] }); - assert!(BigUint { digits: vec![1, 2, 1, 0] } > BigUint { digits: vec![1, 2, 3] }); - - assert!(BigUint { digits: vec![0, 1, 2, 1] } < BigUint { digits: vec![1, 2, 3] }); - } - - #[test] - fn basic_random_ord_eq_works() { - type S = u128; - run_with_data_set(FUZZ_COUNT, 4, 4, false, |u, v| { - let ue = S::try_from(u.clone()).unwrap(); - let ve = S::try_from(v.clone()).unwrap(); - assert_eq!(u.cmp(&v), ue.cmp(&ve)); - assert_eq!(u.eq(&v), ue.eq(&ve)); - }) - } - - #[test] - fn can_try_build_numbers_from_types() { - use rstd::convert::TryFrom; - assert_eq!(u64::try_from(with_limbs(1)).unwrap(), 1); - assert_eq!(u64::try_from(with_limbs(2)).unwrap(), u32::max_value() as u64 + 2); - assert_eq!( - u64::try_from(with_limbs(3)).unwrap_err(), - "cannot fit a number into u64", - ); - assert_eq!( - u128::try_from(with_limbs(3)).unwrap(), - u32::max_value() as u128 + u64::max_value() as u128 + 3 - ); - } - - #[test] - fn zero_works() { - assert_eq!(BigUint::zero(), BigUint { digits: vec![0] }); - assert_eq!(BigUint { digits: vec![0, 1, 0] }.is_zero(), false); - assert_eq!(BigUint { digits: vec![0, 0, 0] }.is_zero(), true); - - let a = BigUint::zero(); - let b = BigUint::zero(); - let c = a * b; - assert_eq!(c.digits, vec![0, 0]); - } - - #[test] - fn basic_random_add_works() { - type S = u128; - run_with_data_set(FUZZ_COUNT, 3, 3, false, |u, v| { - let expected = S::try_from(u.clone()).unwrap() + S::try_from(v.clone()).unwrap(); - let t = u.clone().add(&v); - assert_eq!( - S::try_from(t.clone()).unwrap(), expected, - "{:?} + {:?} ===> {:?} != {:?}", u, v, t, expected, - ); - }) - } - - #[test] - fn sub_negative_works() { - assert_eq!( - BigUint::from(10 as Single).sub(&BigUint::from(5 as Single)).unwrap(), - BigUint::from(5 as Single) - ); - assert_eq!( - BigUint::from(10 as Single).sub(&BigUint::from(10 as Single)).unwrap(), - BigUint::from(0 as Single) - ); - assert_eq!( - BigUint::from(10 as Single).sub(&BigUint::from(13 as Single)).unwrap_err(), - BigUint::from((B - 3) as Single), - ); - } - - #[test] - fn basic_random_sub_works() { - type S = u128; - run_with_data_set(FUZZ_COUNT, 4, 4, false, |u, v| { - let expected = S::try_from(u.clone()).unwrap() - .checked_sub(S::try_from(v.clone()).unwrap()); - let t = u.clone().sub(&v); - if expected.is_none() { - assert!(t.is_err()) - } else { - let t = t.unwrap(); - let expected = expected.unwrap(); - assert_eq!( - S::try_from(t.clone()).unwrap(), expected, - "{:?} - {:?} ===> {:?} != {:?}", u, v, t, expected, - ); - } - }) - } - - #[test] - fn basic_random_mul_works() { - type S = u128; - run_with_data_set(FUZZ_COUNT, 2, 2, false, |u, v| { - let expected = S::try_from(u.clone()).unwrap() * S::try_from(v.clone()).unwrap(); - let t = u.clone().mul(&v); - assert_eq!( - S::try_from(t.clone()).unwrap(), expected, - "{:?} * {:?} ===> {:?} != {:?}", u, v, t, expected, - ); - }) - } - - #[test] - fn mul_always_appends_one_digit() { - let a = BigUint::from(10 as Single); - let b = BigUint::from(4 as Single); - assert_eq!(a.len(), 1); - assert_eq!(b.len(), 1); - - let n = a.mul(&b); - - assert_eq!(n.len(), 2); - assert_eq!(n.digits, vec![0, 40]); - } - - #[test] - fn div_conditions_work() { - let a = BigUint { digits: vec![2] }; - let b = BigUint { digits: vec![1, 2] }; - let c = BigUint { digits: vec![1, 1, 2] }; - let d = BigUint { digits: vec![0, 2] }; - let e = BigUint { digits: vec![0, 1, 1, 2] }; - - assert!(a.clone().div(&b, true).is_none()); - assert!(c.clone().div(&a, true).is_none()); - assert!(c.clone().div(&d, true).is_none()); - assert!(e.clone().div(&a, true).is_none()); - - assert!(c.clone().div(&b, true).is_some()); - } - - #[test] - fn div_unit_works() { - let a = BigUint { digits: vec![100] }; - let b = BigUint { digits: vec![1, 100] }; - - assert_eq!(a.clone().div_unit(1), a); - assert_eq!(a.clone().div_unit(0), a); - assert_eq!(a.clone().div_unit(2), BigUint::from(50 as Single)); - assert_eq!(a.clone().div_unit(7), BigUint::from(14 as Single)); - - assert_eq!(b.clone().div_unit(1), b); - assert_eq!(b.clone().div_unit(0), b); - assert_eq!(b.clone().div_unit(2), BigUint::from(((B + 100) / 2) as Single)); - assert_eq!(b.clone().div_unit(7), BigUint::from(((B + 100) / 7) as Single)); - - } - - #[test] - fn basic_random_div_works() { - type S = u128; - run_with_data_set(FUZZ_COUNT, 4, 4, false, |u, v| { - let ue = S::try_from(u.clone()).unwrap(); - let ve = S::try_from(v.clone()).unwrap(); - let (q, r) = (ue / ve, ue % ve); - if let Some((qq, rr)) = u.clone().div(&v, true) { - assert_eq!( - S::try_from(qq.clone()).unwrap(), q, - "{:?} / {:?} ===> {:?} != {:?}", u, v, qq, q, - ); - assert_eq!( - S::try_from(rr.clone()).unwrap(), r, - "{:?} % {:?} ===> {:?} != {:?}", u, v, rr, r, - ); - } else if v.len() == 1 { - let qq = u.clone().div_unit(ve as Single); - assert_eq!( - S::try_from(qq.clone()).unwrap(), q, - "[single] {:?} / {:?} ===> {:?} != {:?}", u, v, qq, q, - ); - } else { - if v.msb() == 0 || v.msb() == 0 || u.len() <= v.len() {} // nada - else { panic!("div returned none for an unexpected reason"); } - } - }) - } - - #[cfg(feature = "bench")] - #[bench] - fn bench_addition_2_digit(bencher: &mut Bencher) { - let a = random_big_uint(2); - let b = random_big_uint(2); - bencher.iter(|| { - let _ = a.clone().add(&b); - }); - } - - #[cfg(feature = "bench")] - #[bench] - fn bench_addition_4_digit(bencher: &mut Bencher) { - let a = random_big_uint(4); - let b = random_big_uint(4); - bencher.iter(|| { - let _ = a.clone().add(&b); - }); - } - - #[cfg(feature = "bench")] - #[bench] - fn bench_subtraction_2_digit(bencher: &mut Bencher) { - let a = random_big_uint(2); - let b = random_big_uint(2); - bencher.iter(|| { - let _ = a.clone().sub(&b); - }); - } - - #[cfg(feature = "bench")] - #[bench] - fn bench_subtraction_4_digit(bencher: &mut Bencher) { - let a = random_big_uint(4); - let b = random_big_uint(4); - bencher.iter(|| { - let _ = a.clone().sub(&b); - }); - } - - #[cfg(feature = "bench")] - #[bench] - fn bench_multiplication_2_digit(bencher: &mut Bencher) { - let a = random_big_uint(2); - let b = random_big_uint(2); - bencher.iter(|| { - let _ = a.clone().mul(&b); - }); - } - - #[cfg(feature = "bench")] - #[bench] - fn bench_multiplication_4_digit(bencher: &mut Bencher) { - let a = random_big_uint(4); - let b = random_big_uint(4); - bencher.iter(|| { - let _ = a.clone().mul(&b); - }); - } - - #[cfg(feature = "bench")] - #[bench] - fn bench_division_4_digit(bencher: &mut Bencher) { - let a = random_big_uint(4); - let b = random_big_uint(2); - bencher.iter(|| { - let _ = a.clone().div(&b, true); - }); - } - } -} - -/// Some helper functions to work with 128bit numbers. Note that the functionality provided here is -/// only sensible to use with 128bit numbers because for smaller sizes, you can always rely on -/// assumptions of a bigger type (u128) being available, or simply create a per-thing and use the -/// multiplication implementation provided there. -pub mod helpers_128bit { - use crate::biguint; - use crate::traits::Zero; - use rstd::{cmp::{min, max}, convert::TryInto}; - - /// Helper gcd function used in Rational128 implementation. - pub fn gcd(a: u128, b: u128) -> u128 { - match ((a, b), (a & 1, b & 1)) { - ((x, y), _) if x == y => y, - ((0, x), _) | ((x, 0), _) => x, - ((x, y), (0, 1)) | ((y, x), (1, 0)) => gcd(x >> 1, y), - ((x, y), (0, 0)) => gcd(x >> 1, y >> 1) << 1, - ((x, y), (1, 1)) => { - let (x, y) = (min(x, y), max(x, y)); - gcd((y - x) >> 1, x) - }, - _ => unreachable!(), - } - } - - /// split a u128 into two u64 limbs - pub fn split(a: u128) -> (u64, u64) { - let al = a as u64; - let ah = (a >> 64) as u64; - (ah, al) - } - - /// Convert a u128 to a u32 based biguint. - pub fn to_big_uint(x: u128) -> biguint::BigUint { - let (xh, xl) = split(x); - let (xhh, xhl) = biguint::split(xh); - let (xlh, xll) = biguint::split(xl); - let mut n = biguint::BigUint::from_limbs(&[xhh, xhl, xlh, xll]); - n.lstrip(); - n - } - - /// Safely and accurately compute `a * b / c`. The approach is: - /// - Simply try `a * b / c`. - /// - Else, convert them both into big numbers and re-try. `Err` is returned if the result - /// cannot be safely casted back to u128. - /// - /// Invariant: c must be greater than or equal to 1. - pub fn multiply_by_rational(a: u128, b: u128, c: u128) -> Result { - if a.is_zero() || b.is_zero() { return Ok(Zero::zero()); } - let c = c.max(1); - - // a and b are interchangeable by definition in this function. It always helps to assume the - // bigger of which is being multiplied by a `0 < b/c < 1`. Hence, a should be the bigger and - // b the smaller one. - let t = a; - let a = a.max(b); - let b = t.min(b); - - if let Some(x) = a.checked_mul(b) { - // This is the safest way to go. Try it. - Ok(x / c) - } else { - let a_num = to_big_uint(a); - let b_num = to_big_uint(b); - let c_num = to_big_uint(c); - - let mut ab = a_num * b_num; - ab.lstrip(); - let mut q = if c_num.len() == 1 { - // PROOF: if `c_num.len() == 1` then `c` fits in one limb. - ab.div_unit(c as biguint::Single) - } else { - // PROOF: both `ab` and `c` cannot have leading zero limbs; if length of `c` is 1, - // the previous branch would handle. Also, if ab for sure has a bigger size than - // c, because `a.checked_mul(b)` has failed, hence ab must be at least one limb - // bigger than c. In this case, returning zero is defensive-only and div should - // always return Some. - let (mut q, r) = ab.div(&c_num, true).unwrap_or((Zero::zero(), Zero::zero())); - let r: u128 = r.try_into() - .expect("reminder of div by c is always less than c; qed"); - if r > (c / 2) { q = q.add(&to_big_uint(1)); } - q - }; - q.lstrip(); - q.try_into().map_err(|_| "result cannot fit in u128") - } - } -} - -/// A wrapper for any rational number with a 128 bit numerator and denominator. -#[derive(Clone, Copy, Default, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] -pub struct Rational128(u128, u128); - -impl Rational128 { - /// Nothing. - pub fn zero() -> Self { - Self(0, 1) - } - - /// If it is zero or not - pub fn is_zero(&self) -> bool { - self.0.is_zero() - } - - /// Build from a raw `n/d`. - pub fn from(n: u128, d: u128) -> Self { - Self(n, d.max(1)) - } - - /// Build from a raw `n/d`. This could lead to / 0 if not properly handled. - pub fn from_unchecked(n: u128, d: u128) -> Self { - Self(n, d) - } - - /// Return the numerator. - pub fn n(&self) -> u128 { - self.0 - } - - /// Return the denominator. - pub fn d(&self) -> u128 { - self.1 - } - - /// Convert `self` to a similar rational number where denominator is the given `den`. - // - /// This only returns if the result is accurate. `Err` is returned if the result cannot be - /// accurately calculated. - pub fn to_den(self, den: u128) -> Result { - if den == self.1 { - Ok(self) - } else { - helpers_128bit::multiply_by_rational(self.0, den, self.1).map(|n| Self(n, den)) - } - } - - /// Get the least common divisor of `self` and `other`. - /// - /// This only returns if the result is accurate. `Err` is returned if the result cannot be - /// accurately calculated. - pub fn lcm(&self, other: &Self) -> Result { - // this should be tested better: two large numbers that are almost the same. - if self.1 == other.1 { return Ok(self.1) } - let g = helpers_128bit::gcd(self.1, other.1); - helpers_128bit::multiply_by_rational(self.1 , other.1, g) - } - - /// A saturating add that assumes `self` and `other` have the same denominator. - pub fn lazy_saturating_add(self, other: Self) -> Self { - if other.is_zero() { - self - } else { - Self(self.0.saturating_add(other.0) ,self.1) - } - } - - /// A saturating subtraction that assumes `self` and `other` have the same denominator. - pub fn lazy_saturating_sub(self, other: Self) -> Self { - if other.is_zero() { - self - } else { - Self(self.0.saturating_sub(other.0) ,self.1) - } - } - - /// Addition. Simply tries to unify the denominators and add the numerators. - /// - /// Overflow might happen during any of the steps. Error is returned in such cases. - pub fn checked_add(self, other: Self) -> Result { - let lcm = self.lcm(&other).map_err(|_| "failed to scale to denominator")?; - let self_scaled = self.to_den(lcm).map_err(|_| "failed to scale to denominator")?; - let other_scaled = other.to_den(lcm).map_err(|_| "failed to scale to denominator")?; - let n = self_scaled.0.checked_add(other_scaled.0) - .ok_or("overflow while adding numerators")?; - Ok(Self(n, self_scaled.1)) - } - - /// Subtraction. Simply tries to unify the denominators and subtract the numerators. - /// - /// Overflow might happen during any of the steps. None is returned in such cases. - pub fn checked_sub(self, other: Self) -> Result { - let lcm = self.lcm(&other).map_err(|_| "failed to scale to denominator")?; - let self_scaled = self.to_den(lcm).map_err(|_| "failed to scale to denominator")?; - let other_scaled = other.to_den(lcm).map_err(|_| "failed to scale to denominator")?; - - let n = self_scaled.0.checked_sub(other_scaled.0) - .ok_or("overflow while subtracting numerators")?; - Ok(Self(n, self_scaled.1)) - } -} - -impl PartialOrd for Rational128 { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for Rational128 { - fn cmp(&self, other: &Self) -> Ordering { - // handle some edge cases. - if self.1 == other.1 { - self.0.cmp(&other.0) - } else if self.1.is_zero() { - Ordering::Greater - } else if other.1.is_zero() { - Ordering::Less - } else { - // Don't even compute gcd. - let self_n = helpers_128bit::to_big_uint(self.0) * helpers_128bit::to_big_uint(other.1); - let other_n = helpers_128bit::to_big_uint(other.0) * helpers_128bit::to_big_uint(self.1); - self_n.cmp(&other_n) - } - } -} - -impl PartialEq for Rational128 { - fn eq(&self, other: &Self) -> bool { - // handle some edge cases. - if self.1 == other.1 { - self.0.eq(&other.0) - } else { - let self_n = helpers_128bit::to_big_uint(self.0) * helpers_128bit::to_big_uint(other.1); - let other_n = helpers_128bit::to_big_uint(other.0) * helpers_128bit::to_big_uint(self.1); - self_n.eq(&other_n) - } - } -} - -#[cfg(test)] -mod test_rational128 { - use super::*; - use super::helpers_128bit::*; - use rand::Rng; - - const MAX128: u128 = u128::max_value(); - const MAX64: u128 = u64::max_value() as u128; - const MAX64_2: u128 = 2 * u64::max_value() as u128; - - fn r(p: u128, q: u128) -> Rational128 { - Rational128(p, q) - } - - fn mul_div(a: u128, b: u128, c: u128) -> u128 { - use primitive_types::U256; - if a.is_zero() { return Zero::zero(); } - let c = c.max(1); - - // e for extended - let ae: U256 = a.into(); - let be: U256 = b.into(); - let ce: U256 = c.into(); - - let r = ae * be / ce; - if r > u128::max_value().into() { - a - } else { - r.as_u128() - } - } - - #[test] - fn truth_value_function_works() { - assert_eq!( - mul_div(2u128.pow(100), 8, 4), - 2u128.pow(101) - ); - assert_eq!( - mul_div(2u128.pow(100), 4, 8), - 2u128.pow(99) - ); - - // and it returns a if result cannot fit - assert_eq!(mul_div(MAX128 - 10, 2, 1), MAX128 - 10); - } - - #[test] - fn to_denom_works() { - // simple up and down - assert_eq!(r(1, 5).to_den(10), Ok(r(2, 10))); - assert_eq!(r(4, 10).to_den(5), Ok(r(2, 5))); - - // up and down with large numbers - assert_eq!(r(MAX128 - 10, MAX128).to_den(10), Ok(r(10, 10))); - assert_eq!(r(MAX128 / 2, MAX128).to_den(10), Ok(r(5, 10))); - - // large to perbill. This is very well needed for phragmen. - assert_eq!( - r(MAX128 / 2, MAX128).to_den(1000_000_000), - Ok(r(500_000_000, 1000_000_000)) - ); - - // large to large - assert_eq!(r(MAX128 / 2, MAX128).to_den(MAX128/2), Ok(r(MAX128/4, MAX128/2))); - } - - #[test] - fn gdc_works() { - assert_eq!(gcd(10, 5), 5); - assert_eq!(gcd(7, 22), 1); - } - - #[test] - fn lcm_works() { - // simple stuff - assert_eq!(r(3, 10).lcm(&r(4, 15)).unwrap(), 30); - assert_eq!(r(5, 30).lcm(&r(1, 7)).unwrap(), 210); - assert_eq!(r(5, 30).lcm(&r(1, 10)).unwrap(), 30); - - // large numbers - assert_eq!( - r(1_000_000_000, MAX128).lcm(&r(7_000_000_000, MAX128-1)), - Err("result cannot fit in u128"), - ); - assert_eq!( - r(1_000_000_000, MAX64).lcm(&r(7_000_000_000, MAX64-1)), - Ok(340282366920938463408034375210639556610), - ); - assert!(340282366920938463408034375210639556610 < MAX128); - assert!(340282366920938463408034375210639556610 == MAX64 * (MAX64 - 1)); - } - - #[test] - fn add_works() { - // works - assert_eq!(r(3, 10).checked_add(r(1, 10)).unwrap(), r(2, 5)); - assert_eq!(r(3, 10).checked_add(r(3, 7)).unwrap(), r(51, 70)); - - // errors - assert_eq!( - r(1, MAX128).checked_add(r(1, MAX128-1)), - Err("failed to scale to denominator"), - ); - assert_eq!( - r(7, MAX128).checked_add(r(MAX128, MAX128)), - Err("overflow while adding numerators"), - ); - assert_eq!( - r(MAX128, MAX128).checked_add(r(MAX128, MAX128)), - Err("overflow while adding numerators"), - ); - } - - #[test] - fn sub_works() { - // works - assert_eq!(r(3, 10).checked_sub(r(1, 10)).unwrap(), r(1, 5)); - assert_eq!(r(6, 10).checked_sub(r(3, 7)).unwrap(), r(12, 70)); - - // errors - assert_eq!( - r(2, MAX128).checked_sub(r(1, MAX128-1)), - Err("failed to scale to denominator"), - ); - assert_eq!( - r(7, MAX128).checked_sub(r(MAX128, MAX128)), - Err("overflow while subtracting numerators"), - ); - assert_eq!( - r(1, 10).checked_sub(r(2,10)), - Err("overflow while subtracting numerators"), - ); - } - - #[test] - fn ordering_and_eq_works() { - assert!(r(1, 2) > r(1, 3)); - assert!(r(1, 2) > r(2, 6)); - - assert!(r(1, 2) < r(6, 6)); - assert!(r(2, 1) > r(2, 6)); - - assert!(r(5, 10) == r(1, 2)); - assert!(r(1, 2) == r(1, 2)); - - assert!(r(1, 1490000000000200000) > r(1, 1490000000000200001)); - } - - #[test] - fn multiply_by_rational_works() { - assert_eq!(multiply_by_rational(7, 2, 3).unwrap(), 7 * 2 / 3); - assert_eq!(multiply_by_rational(7, 20, 30).unwrap(), 7 * 2 / 3); - assert_eq!(multiply_by_rational(20, 7, 30).unwrap(), 7 * 2 / 3); - - assert_eq!( - // MAX128 % 3 == 0 - multiply_by_rational(MAX128, 2, 3).unwrap(), - MAX128 / 3 * 2, - ); - assert_eq!( - // MAX128 % 7 == 3 - multiply_by_rational(MAX128, 5, 7).unwrap(), - (MAX128 / 7 * 5) + (3 * 5 / 7), - ); - assert_eq!( - // MAX128 % 7 == 3 - multiply_by_rational(MAX128, 11 , 13).unwrap(), - (MAX128 / 13 * 11) + (8 * 11 / 13), - ); - assert_eq!( - // MAX128 % 1000 == 455 - multiply_by_rational(MAX128, 555, 1000).unwrap(), - (MAX128 / 1000 * 555) + (455 * 555 / 1000), - ); - - assert_eq!( - multiply_by_rational(2 * MAX64 - 1, MAX64, MAX64).unwrap(), - 2 * MAX64 - 1, - ); - assert_eq!( - multiply_by_rational(2 * MAX64 - 1, MAX64 - 1, MAX64).unwrap(), - 2 * MAX64 - 3, - ); - - assert_eq!( - multiply_by_rational(MAX64 + 100, MAX64_2, MAX64_2 / 2).unwrap(), - (MAX64 + 100) * 2, - ); - assert_eq!( - multiply_by_rational(MAX64 + 100, MAX64_2 / 100, MAX64_2 / 200).unwrap(), - (MAX64 + 100) * 2, - ); - - assert_eq!( - multiply_by_rational(2u128.pow(66) - 1, 2u128.pow(65) - 1, 2u128.pow(65)).unwrap(), - 73786976294838206461, - ); - assert_eq!( - multiply_by_rational(1_000_000_000, MAX128 / 8, MAX128 / 2).unwrap(), - 250000000, - ); - } - - #[test] - fn multiply_by_rational_a_b_are_interchangeable() { - assert_eq!( - multiply_by_rational(10, MAX128, MAX128 / 2), - Ok(20), - ); - assert_eq!( - multiply_by_rational(MAX128, 10, MAX128 / 2), - Ok(20), - ); - } - - fn do_fuzz_multiply_by_rational( - iters: usize, - bits: u32, - maximum_error: u128, - do_print: bool, - bounded: bool, - mul_fn: F, - ) where F: Fn(u128, u128, u128) -> u128 { - let mut rng = rand::thread_rng(); - let mut average_diff = 0.0; - let upper_bound = 2u128.pow(bits); - - for _ in 0..iters { - let a = rng.gen_range(0u128, upper_bound); - let c = rng.gen_range(0u128, upper_bound); - let b = rng.gen_range( - 0u128, - if bounded { c } else { upper_bound } - ); - - let a: u128 = a.into(); - let b: u128 = b.into(); - let c: u128 = c.into(); - - let truth = mul_div(a, b, c); - let result = mul_fn(a, b, c); - let diff = truth.max(result) - truth.min(result); - let loss_ratio = diff as f64 / truth as f64; - average_diff += loss_ratio; - - if do_print && diff > maximum_error { - println!("++ Computed with more loss than expected: {} * {} / {}", a, b, c); - println!("++ Expected {}", truth); - println!("+++++++ Got {}", result); - } - } - - // print report - println!( - "## Fuzzed with {} numbers. Average error was {}", - iters, - average_diff / (iters as f64), - ); - } - - // TODO $# move into a proper fuzzer #3745 - const FUZZ_COUNT: usize = 100_000; - - #[test] - fn fuzz_multiply_by_rational_32() { - // if Err just return the truth value. We don't care about such cases. The point of this - // fuzzing is to make sure: if `multiply_by_rational` returns `Ok`, it must be 100% accurate - // returning `Err` is fine. - let f = |a, b, c| multiply_by_rational(a, b, c).unwrap_or(mul_div(a, b, c)); - println!("\nInvariant: b < c"); - do_fuzz_multiply_by_rational(FUZZ_COUNT, 32, 0, false, true, f); - println!("every possibility"); - do_fuzz_multiply_by_rational(FUZZ_COUNT, 32, 0, false, false, f); - } - - #[test] - fn fuzz_multiply_by_rational_64() { - let f = |a, b, c| multiply_by_rational(a, b, c).unwrap_or(mul_div(a, b, c)); - println!("\nInvariant: b < c"); - do_fuzz_multiply_by_rational(FUZZ_COUNT, 64, 0, false, true, f); - println!("every possibility"); - do_fuzz_multiply_by_rational(FUZZ_COUNT, 64, 0, false, false, f); - } - - #[test] - fn fuzz_multiply_by_rational_96() { - let f = |a, b, c| multiply_by_rational(a, b, c).unwrap_or(mul_div(a, b, c)); - println!("\nInvariant: b < c"); - do_fuzz_multiply_by_rational(FUZZ_COUNT, 96, 0, false, true, f); - println!("every possibility"); - do_fuzz_multiply_by_rational(FUZZ_COUNT, 96, 0, false, false, f); - } - - #[test] - fn fuzz_multiply_by_rational_128() { - let f = |a, b, c| multiply_by_rational(a, b, c).unwrap_or(mul_div(a, b, c)); - println!("\nInvariant: b < c"); - do_fuzz_multiply_by_rational(FUZZ_COUNT, 127, 0, false, true, f); - println!("every possibility"); - do_fuzz_multiply_by_rational(FUZZ_COUNT, 127, 0, false, false, f); - } -} - -#[cfg(test)] -mod tests_fixed64 { - use super::*; - - fn max() -> Fixed64 { - Fixed64::from_parts(i64::max_value()) - } - - #[test] - fn fixed64_semantics() { - assert_eq!(Fixed64::from_rational(5, 2).0, 5 * 1_000_000_000 / 2); - assert_eq!(Fixed64::from_rational(5, 2), Fixed64::from_rational(10, 4)); - assert_eq!(Fixed64::from_rational(5, 0), Fixed64::from_rational(5, 1)); - - // biggest value that can be created. - assert_ne!(max(), Fixed64::from_natural(9_223_372_036)); - assert_eq!(max(), Fixed64::from_natural(9_223_372_037)); - } - - #[test] - fn fixed_64_growth_decrease_curve() { - let test_set = vec![0u32, 1, 10, 1000, 1_000_000_000]; - - // negative (1/2) - let mut fm = Fixed64::from_rational(-1, 2); - test_set.clone().into_iter().for_each(|i| { - assert_eq!(fm.saturated_multiply_accumulate(i) as i32, i as i32 - i as i32 / 2); - }); - - // unit (1) multiplier - fm = Fixed64::from_parts(0); - test_set.clone().into_iter().for_each(|i| { - assert_eq!(fm.saturated_multiply_accumulate(i), i); - }); - - // i.5 multiplier - fm = Fixed64::from_rational(1, 2); - test_set.clone().into_iter().for_each(|i| { - assert_eq!(fm.saturated_multiply_accumulate(i), i * 3 / 2); - }); - - // dual multiplier - fm = Fixed64::from_rational(1, 1); - test_set.clone().into_iter().for_each(|i| { - assert_eq!(fm.saturated_multiply_accumulate(i), i * 2); - }); - } - - macro_rules! saturating_mul_acc_test { - ($num_type:tt) => { - assert_eq!( - Fixed64::from_rational(100, 1).saturated_multiply_accumulate(10 as $num_type), - 1010, - ); - assert_eq!( - Fixed64::from_rational(100, 2).saturated_multiply_accumulate(10 as $num_type), - 510, - ); - assert_eq!( - Fixed64::from_rational(100, 3).saturated_multiply_accumulate(0 as $num_type), - 0, - ); - assert_eq!( - Fixed64::from_rational(5, 1).saturated_multiply_accumulate($num_type::max_value()), - $num_type::max_value() - ); - assert_eq!( - max().saturated_multiply_accumulate($num_type::max_value()), - $num_type::max_value() - ); - } - } - - #[test] - fn fixed64_multiply_accumulate_works() { - saturating_mul_acc_test!(u32); - saturating_mul_acc_test!(u64); - saturating_mul_acc_test!(u128); - } -} diff --git a/core/sr-primitives/src/traits.rs b/core/sr-primitives/src/traits.rs index a589f5f389..a384c95e19 100644 --- a/core/sr-primitives/src/traits.rs +++ b/core/sr-primitives/src/traits.rs @@ -24,20 +24,16 @@ use std::fmt::{Debug, Display}; #[cfg(feature = "std")] use serde::{Serialize, Deserialize, de::DeserializeOwned}; use primitives::{self, Hasher, Blake2Hasher, TypeId}; -use crate::codec::{Codec, Encode, Decode, HasCompact}; +use crate::codec::{Codec, Encode, Decode}; use crate::transaction_validity::{ ValidTransaction, TransactionValidity, TransactionValidityError, UnknownTransaction, }; use crate::generic::{Digest, DigestItem}; use crate::weights::DispatchInfo; -pub use integer_sqrt::IntegerSquareRoot; -pub use num_traits::{ +pub use arithmetic::traits::{ + SimpleArithmetic, UniqueSaturatedInto, UniqueSaturatedFrom, Saturating, SaturatedConversion, Zero, One, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, - CheckedShl, CheckedShr -}; -use rstd::ops::{ - Add, Sub, Mul, Div, Rem, AddAssign, SubAssign, MulAssign, DivAssign, - RemAssign, Shl, Shr + CheckedShl, CheckedShr, IntegerSquareRoot }; use app_crypto::AppKey; use impl_trait_for_tuples::impl_for_tuples; @@ -198,120 +194,6 @@ impl> Convert for ConvertInto { fn convert(a: A) -> B { a.into() } } -/// A meta trait for arithmetic. -/// -/// Arithmetic types do all the usual stuff you'd expect numbers to do. They are guaranteed to -/// be able to represent at least `u32` values without loss, hence the trait implies `From` -/// and smaller ints. All other conversions are fallible. -pub trait SimpleArithmetic: - Zero + One + IntegerSquareRoot + - From + From + From + TryInto + TryInto + TryInto + - TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + - UniqueSaturatedInto + UniqueSaturatedInto + UniqueSaturatedInto + - UniqueSaturatedFrom + UniqueSaturatedInto + UniqueSaturatedFrom + UniqueSaturatedInto + - Add + AddAssign + - Sub + SubAssign + - Mul + MulAssign + - Div + DivAssign + - Rem + RemAssign + - Shl + Shr + - CheckedShl + CheckedShr + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv + - Saturating + PartialOrd + Ord + Bounded + - HasCompact + Sized -{} -impl + From + From + TryInto + TryInto + TryInto + - TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + - UniqueSaturatedInto + UniqueSaturatedInto + UniqueSaturatedInto + - UniqueSaturatedFrom + UniqueSaturatedInto + UniqueSaturatedFrom + - UniqueSaturatedInto + UniqueSaturatedFrom + UniqueSaturatedInto + - Add + AddAssign + - Sub + SubAssign + - Mul + MulAssign + - Div + DivAssign + - Rem + RemAssign + - Shl + Shr + - CheckedShl + CheckedShr + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv + - Saturating + PartialOrd + Ord + Bounded + - HasCompact + Sized -> SimpleArithmetic for T {} - -/// Just like `From` except that if the source value is too big to fit into the destination type -/// then it'll saturate the destination. -pub trait UniqueSaturatedFrom: Sized { - /// Convert from a value of `T` into an equivalent instance of `Self`. - fn unique_saturated_from(t: T) -> Self; -} - -/// Just like `Into` except that if the source value is too big to fit into the destination type -/// then it'll saturate the destination. -pub trait UniqueSaturatedInto: Sized { - /// Consume self to return an equivalent value of `T`. - fn unique_saturated_into(self) -> T; -} - -impl + Bounded + Sized> UniqueSaturatedFrom for S { - fn unique_saturated_from(t: T) -> Self { - S::try_from(t).unwrap_or_else(|_| Bounded::max_value()) - } -} - -impl + Sized> UniqueSaturatedInto for S { - fn unique_saturated_into(self) -> T { - self.try_into().unwrap_or_else(|_| Bounded::max_value()) - } -} - -/// Simple trait to use checked mul and max value to give a saturated mul operation over -/// supported types. -pub trait Saturating { - /// Saturated addition - if the product can't fit in the type then just use max-value. - fn saturating_add(self, o: Self) -> Self; - - /// Saturated subtraction - if the product can't fit in the type then just use max-value. - fn saturating_sub(self, o: Self) -> Self; - - /// Saturated multiply - if the product can't fit in the type then just use max-value. - fn saturating_mul(self, o: Self) -> Self; -} - -impl Saturating for T { - fn saturating_add(self, o: Self) -> Self { - ::saturating_add(self, o) - } - fn saturating_sub(self, o: Self) -> Self { - ::saturating_sub(self, o) - } - fn saturating_mul(self, o: Self) -> Self { - self.checked_mul(&o).unwrap_or_else(Bounded::max_value) - } -} - -/// Convenience type to work around the highly unergonomic syntax needed -/// to invoke the functions of overloaded generic traits, in this case -/// `SaturatedFrom` and `SaturatedInto`. -pub trait SaturatedConversion { - /// Convert from a value of `T` into an equivalent instance of `Self`. - /// - /// This just uses `UniqueSaturatedFrom` internally but with this - /// variant you can provide the destination type using turbofish syntax - /// in case Rust happens not to assume the correct type. - fn saturated_from(t: T) -> Self where Self: UniqueSaturatedFrom { - >::unique_saturated_from(t) - } - - /// Consume self to return an equivalent value of `T`. - /// - /// This just uses `UniqueSaturatedInto` internally but with this - /// variant you can provide the destination type using turbofish syntax - /// in case Rust happens not to assume the correct type. - fn saturated_into(self) -> T where Self: UniqueSaturatedInto { - >::unique_saturated_into(self) - } -} -impl SaturatedConversion for T {} - /// Convenience type to work around the highly unergonomic syntax needed /// to invoke the functions of overloaded generic traits, in this case /// `TryFrom` and `TryInto`. diff --git a/core/sr-primitives/src/weights.rs b/core/sr-primitives/src/weights.rs index 2ffd4ee391..b1cce0f77f 100644 --- a/core/sr-primitives/src/weights.rs +++ b/core/sr-primitives/src/weights.rs @@ -24,7 +24,7 @@ //! (something that does not implement `Weighable`) is passed in. pub use crate::transaction_validity::TransactionPriority; -use crate::traits::Bounded; +use arithmetic::traits::Bounded; /// Numeric range of a transaction weight. pub type Weight = u32; diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index ac801fd39e..69f812ce32 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -85,7 +85,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 179, - impl_version: 179, + impl_version: 180, apis: RUNTIME_API_VERSIONS, }; -- GitLab From e479a512f104e77747a2bb3e98f57ebc59faad8d Mon Sep 17 00:00:00 2001 From: Andrew Dirksen Date: Sat, 19 Oct 2019 01:38:19 -0700 Subject: [PATCH 239/275] Change manual dependency on wasm-gc executable to an automatic cargo dependency. (#3854) Improves user experience. --- Cargo.lock | 21 ++++++++++++++++++++ Dockerfile | 1 - README.adoc | 13 ++++-------- core/utils/wasm-builder/Cargo.toml | 1 + core/utils/wasm-builder/README.md | 1 - core/utils/wasm-builder/src/lib.rs | 1 - core/utils/wasm-builder/src/prerequisites.rs | 13 +----------- core/utils/wasm-builder/src/wasm_project.rs | 13 +++--------- node-template/scripts/init.sh | 4 ---- scripts/init.sh | 4 ---- 10 files changed, 30 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 82a5ab2229..d9bfc40409 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2840,6 +2840,14 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parity-wasm" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parity-wasm" version = "0.40.3" @@ -5759,6 +5767,7 @@ dependencies = [ "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-gc-api 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6516,6 +6525,16 @@ dependencies = [ "weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "wasm-gc-api" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "wasm-timer" version = "0.1.3" @@ -7019,6 +7038,7 @@ dependencies = [ "checksum parity-scale-codec-derive 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42af752f59119656fa3cb31e8852ed24e895b968c0bdb41847da7f0cea6d155f" "checksum parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" "checksum parity-util-mem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2005637ccf93dbb60c85081ccaaf3f945f573da48dcc79f27f9646caa3ec1dc" +"checksum parity-wasm 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ad52817c4d343339b3bc2e26861bd21478eda0b7509acf83505727000512ac" "checksum parity-wasm 0.40.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1e39faaa292a687ea15120b1ac31899b13586446521df6c149e46f1584671e0f" "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" @@ -7219,6 +7239,7 @@ dependencies = [ "checksum wasm-bindgen-macro-support 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "9c075d27b7991c68ca0f77fe628c3513e64f8c477d422b859e03f28751b46fc5" "checksum wasm-bindgen-shared 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "83d61fe986a7af038dd8b5ec660e5849cbd9f38e7492b9404cc48b2b4df731d1" "checksum wasm-bindgen-webidl 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "9b979afb0535fe4749906a674082db1211de8aef466331d43232f63accb7c07c" +"checksum wasm-gc-api 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c32691b6c7e6c14e7f8fd55361a9088b507aa49620fcd06c09b3a1082186b9" "checksum wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "aa3e01d234bb71760e685cfafa5e2c96f8ad877c161a721646356651069e26ac" "checksum wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f31d26deb2d9a37e6cfed420edce3ed604eab49735ba89035e13c98f9a528313" "checksum wasmi-validation 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6bc0356e3df56e639fc7f7d8a99741915531e27ed735d911ed83d7e1339c8188" diff --git a/Dockerfile b/Dockerfile index 1ebc7b04aa..7cba85c544 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,6 @@ RUN curl https://sh.rustup.rs -sSf | sh -s -- -y && \ export PATH="$PATH:$HOME/.cargo/bin" && \ rustup toolchain install nightly && \ rustup target add wasm32-unknown-unknown --toolchain nightly && \ - cargo install --git https://github.com/alexcrichton/wasm-gc && \ rustup default nightly && \ rustup default stable && \ cargo build "--$PROFILE" diff --git a/README.adoc b/README.adoc index f5d7f95713..6563340cc6 100644 --- a/README.adoc +++ b/README.adoc @@ -184,7 +184,6 @@ curl https://sh.rustup.rs -sSf | sh rustup update nightly rustup target add wasm32-unknown-unknown --toolchain nightly rustup update stable -cargo install --git https://github.com/alexcrichton/wasm-gc ---- You will also need to install the following packages: @@ -231,13 +230,9 @@ If you are trying to set up Substrate on Windows, you should do the following: rustup update stable rustup target add wasm32-unknown-unknown --toolchain nightly -4. Next, you install wasm-gc, which is used to slim down Wasm files: +4. Then, you need to install LLVM: https://releases.llvm.org/download.html - cargo install --git https://github.com/alexcrichton/wasm-gc --force - -5. Then, you need to install LLVM: https://releases.llvm.org/download.html - -6. Next, you need to install OpenSSL, which we will do with `vcpkg`: +5. Next, you need to install OpenSSL, which we will do with `vcpkg`: mkdir \Tools cd \Tools @@ -246,14 +241,14 @@ If you are trying to set up Substrate on Windows, you should do the following: .\bootstrap-vcpkg.bat .\vcpkg.exe install openssl:x64-windows-static -7. After, you need to add OpenSSL to your System Variables. Note that in order for the following commands to work, you need to use Windows Powershell: +6. After, you need to add OpenSSL to your System Variables. Note that in order for the following commands to work, you need to use Windows Powershell: $env:OPENSSL_DIR = 'C:\Tools\vcpkg\installed\x64-windows-static' $env:OPENSSL_STATIC = 'Yes' [System.Environment]::SetEnvironmentVariable('OPENSSL_DIR', $env:OPENSSL_DIR, [System.EnvironmentVariableTarget]::User) [System.Environment]::SetEnvironmentVariable('OPENSSL_STATIC', $env:OPENSSL_STATIC, [System.EnvironmentVariableTarget]::User) -8. Finally, you need to install `cmake`: https://cmake.org/download/ +7. Finally, you need to install `cmake`: https://cmake.org/download/ ==== Shared Steps diff --git a/core/utils/wasm-builder/Cargo.toml b/core/utils/wasm-builder/Cargo.toml index bbcfe2ff52..7fcdd6c4e1 100644 --- a/core/utils/wasm-builder/Cargo.toml +++ b/core/utils/wasm-builder/Cargo.toml @@ -15,3 +15,4 @@ tempfile = "3.1.0" toml = "0.5.3" walkdir = "2.2.9" fs2 = "0.4.3" +wasm-gc-api = "0.1.11" diff --git a/core/utils/wasm-builder/README.md b/core/utils/wasm-builder/README.md index 0f3d933a2f..b15d2ebfab 100644 --- a/core/utils/wasm-builder/README.md +++ b/core/utils/wasm-builder/README.md @@ -57,7 +57,6 @@ be `NODE_RUNTIME`. WASM builder requires the following prerequisities for building the WASM binary: - rust nightly + `wasm32-unknown-unknown` toolchain -- wasm-gc License: GPL-3.0 diff --git a/core/utils/wasm-builder/src/lib.rs b/core/utils/wasm-builder/src/lib.rs index 6f7687f446..b97559c076 100644 --- a/core/utils/wasm-builder/src/lib.rs +++ b/core/utils/wasm-builder/src/lib.rs @@ -75,7 +75,6 @@ //! WASM builder requires the following prerequisities for building the WASM binary: //! //! - rust nightly + `wasm32-unknown-unknown` toolchain -//! - wasm-gc //! use std::{env, fs, path::PathBuf, process::{Command, Stdio, self}}; diff --git a/core/utils/wasm-builder/src/prerequisites.rs b/core/utils/wasm-builder/src/prerequisites.rs index 0c41dff6c8..73e356f0c2 100644 --- a/core/utils/wasm-builder/src/prerequisites.rs +++ b/core/utils/wasm-builder/src/prerequisites.rs @@ -14,9 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use std::{process::{Command, Stdio}, fs}; - -use std::env; +use std::{env, fs}; use tempfile::tempdir; /// Checks that all prerequisites are installed. @@ -28,15 +26,6 @@ pub fn check() -> Option<&'static str> { return Some("Rust nightly not installed, please install it!") } - if Command::new("wasm-gc") - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .status() - .map(|s| !s.success()).unwrap_or(true) - { - return Some("`wasm-gc` not installed, please install it!") - } - check_wasm_toolchain_installed() } diff --git a/core/utils/wasm-builder/src/wasm_project.rs b/core/utils/wasm-builder/src/wasm_project.rs index afe6faa070..1651642ee0 100644 --- a/core/utils/wasm-builder/src/wasm_project.rs +++ b/core/utils/wasm-builder/src/wasm_project.rs @@ -16,7 +16,7 @@ use crate::write_file_if_changed; -use std::{fs, path::{Path, PathBuf}, borrow::ToOwned, process::{Command, self}, env}; +use std::{fs, path::{Path, PathBuf}, borrow::ToOwned, process, env}; use toml::value::Table; @@ -352,15 +352,8 @@ fn compact_wasm_file( .join(format!("{}.wasm", wasm_binary)); let wasm_compact_file = project.join(format!("{}.compact.wasm", wasm_binary)); - let res = Command::new("wasm-gc") - .arg(&wasm_file) - .arg(&wasm_compact_file) - .status() - .map(|s| s.success()); - - if !res.unwrap_or(false) { - panic!("Failed to compact generated WASM binary."); - } + wasm_gc::garbage_collect_file(&wasm_file, &wasm_compact_file) + .expect("Failed to compact generated WASM binary."); (WasmBinary(wasm_compact_file), WasmBinaryBloaty(wasm_file)) } diff --git a/node-template/scripts/init.sh b/node-template/scripts/init.sh index cf5ecf9792..1405a41ef3 100755 --- a/node-template/scripts/init.sh +++ b/node-template/scripts/init.sh @@ -10,7 +10,3 @@ if [ -z $CI_PROJECT_NAME ] ; then fi rustup target add wasm32-unknown-unknown --toolchain nightly - -# Install wasm-gc. It's useful for stripping slimming down wasm binaries. -command -v wasm-gc || \ - cargo +nightly install --git https://github.com/alexcrichton/wasm-gc --force diff --git a/scripts/init.sh b/scripts/init.sh index cf5ecf9792..1405a41ef3 100755 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -10,7 +10,3 @@ if [ -z $CI_PROJECT_NAME ] ; then fi rustup target add wasm32-unknown-unknown --toolchain nightly - -# Install wasm-gc. It's useful for stripping slimming down wasm binaries. -command -v wasm-gc || \ - cargo +nightly install --git https://github.com/alexcrichton/wasm-gc --force -- GitLab From 5fde6d0882bd9943da28df6d40dc78714672dcca Mon Sep 17 00:00:00 2001 From: Caio Date: Sat, 19 Oct 2019 08:01:51 -0300 Subject: [PATCH 240/275] It's Clippy time (#3806) Fix some Clippy issues --- core/client/db/src/cache/mod.rs | 2 +- core/consensus/babe/primitives/src/digest.rs | 2 +- core/consensus/babe/src/aux_schema.rs | 2 +- core/consensus/slots/src/aux_schema.rs | 2 +- core/consensus/slots/src/lib.rs | 11 +++++------ core/finality-grandpa/src/lib.rs | 2 +- core/primitives/src/ed25519.rs | 8 +------- core/primitives/src/sr25519.rs | 8 +------- core/rpc-servers/src/lib.rs | 2 +- core/service/src/chain_ops.rs | 4 ++-- srml/support/src/hash.rs | 2 +- srml/support/src/traits.rs | 2 +- srml/system/src/lib.rs | 2 +- 13 files changed, 18 insertions(+), 31 deletions(-) diff --git a/core/client/db/src/cache/mod.rs b/core/client/db/src/cache/mod.rs index bfc496dd2f..9aaea57b0c 100644 --- a/core/client/db/src/cache/mod.rs +++ b/core/client/db/src/cache/mod.rs @@ -207,7 +207,7 @@ impl<'a, Block: BlockT> DbCacheTransaction<'a, Block> { // prepare list of caches that are not update // (we might still need to do some cache maintenance in this case) let missed_caches = self.cache.cache_at.keys() - .filter(|cache| !data_at.contains_key(cache.clone())) + .filter(|cache| !data_at.contains_key(*cache)) .cloned() .collect::>(); diff --git a/core/consensus/babe/primitives/src/digest.rs b/core/consensus/babe/primitives/src/digest.rs index 3f275ecdb6..ff62ae29c5 100644 --- a/core/consensus/babe/primitives/src/digest.rs +++ b/core/consensus/babe/primitives/src/digest.rs @@ -91,7 +91,7 @@ impl BabePreDigest { } /// The prefix used by BABE for its VRF keys. -pub const BABE_VRF_PREFIX: &'static [u8] = b"substrate-babe-vrf"; +pub const BABE_VRF_PREFIX: &[u8] = b"substrate-babe-vrf"; /// A raw version of `BabePreDigest`, usable on `no_std`. #[derive(Copy, Clone, Encode, Decode)] diff --git a/core/consensus/babe/src/aux_schema.rs b/core/consensus/babe/src/aux_schema.rs index 67f61050fa..6290d5cf31 100644 --- a/core/consensus/babe/src/aux_schema.rs +++ b/core/consensus/babe/src/aux_schema.rs @@ -38,7 +38,7 @@ fn load_decode(backend: &B, key: &[u8]) -> ClientResult> T: Decode, { let corrupt = |e: codec::Error| { - ClientError::Backend(format!("BABE DB is corrupted. Decode error: {}", e.what())).into() + ClientError::Backend(format!("BABE DB is corrupted. Decode error: {}", e.what())) }; match backend.get_aux(key)? { None => Ok(None), diff --git a/core/consensus/slots/src/aux_schema.rs b/core/consensus/slots/src/aux_schema.rs index 1d54cb5c2e..186288c174 100644 --- a/core/consensus/slots/src/aux_schema.rs +++ b/core/consensus/slots/src/aux_schema.rs @@ -38,7 +38,7 @@ fn load_decode(backend: &C, key: &[u8]) -> ClientResult> None => Ok(None), Some(t) => T::decode(&mut &t[..]) .map_err( - |e| ClientError::Backend(format!("Slots DB is corrupted. Decode error: {}", e.what())).into(), + |e| ClientError::Backend(format!("Slots DB is corrupted. Decode error: {}", e.what())), ) .map(Some) } diff --git a/core/consensus/slots/src/lib.rs b/core/consensus/slots/src/lib.rs index fd86a0f277..e33d00d255 100644 --- a/core/consensus/slots/src/lib.rs +++ b/core/consensus/slots/src/lib.rs @@ -189,9 +189,9 @@ pub trait SimpleSlotWorker { logs, }, remaining_duration, - ).map_err(|e| consensus_common::Error::ClientImport(format!("{:?}", e)).into()), + ).map_err(|e| consensus_common::Error::ClientImport(format!("{:?}", e))), Delay::new(remaining_duration) - .map_err(|err| consensus_common::Error::FaultyTimer(err).into()) + .map_err(consensus_common::Error::FaultyTimer) ).map(|v| match v { futures::future::Either::Left((b, _)) => b.map(|b| (b, claim)), futures::future::Either::Right((Ok(_), _)) => @@ -220,9 +220,9 @@ pub trait SimpleSlotWorker { } let (header, body) = block.deconstruct(); - let header_num = header.number().clone(); + let header_num = *header.number(); let header_hash = header.hash(); - let parent_hash = header.parent_hash().clone(); + let parent_hash = *header.parent_hash(); let block_import_params = block_import_params_maker( header, @@ -401,9 +401,8 @@ impl SlotDuration { .map_err(|_| { client::error::Error::Backend({ error!(target: "slots", "slot duration kept in invalid format"); - format!("slot duration kept in invalid format") + "slot duration kept in invalid format".to_string() }) - .into() }), None => { use sr_primitives::traits::Zero; diff --git a/core/finality-grandpa/src/lib.rs b/core/finality-grandpa/src/lib.rs index 3841084d11..9d1e3f563f 100644 --- a/core/finality-grandpa/src/lib.rs +++ b/core/finality-grandpa/src/lib.rs @@ -822,7 +822,7 @@ where } } -#[deprecated(since = "1.1", note = "Please switch to run_grandpa_voter.")] +#[deprecated(since = "1.1.0", note = "Please switch to run_grandpa_voter.")] pub fn run_grandpa, N, RA, SC, VR, X>( grandpa_params: GrandpaParams, ) -> ::client::error::Result + Send + 'static> where diff --git a/core/primitives/src/ed25519.rs b/core/primitives/src/ed25519.rs index c40499a3a1..b674a150c4 100644 --- a/core/primitives/src/ed25519.rs +++ b/core/primitives/src/ed25519.rs @@ -41,6 +41,7 @@ use crate::{crypto::{Public as TraitPublic, UncheckedFrom, CryptoType, Derive}}; type Seed = [u8; 32]; /// A public key. +#[cfg_attr(feature = "std", derive(Hash))] #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default)] pub struct Public(pub [u8; 32]); @@ -152,13 +153,6 @@ impl<'de> Deserialize<'de> for Public { } } -#[cfg(feature = "std")] -impl std::hash::Hash for Public { - fn hash(&self, state: &mut H) { - self.0.hash(state); - } -} - /// A signature (a 512-bit value). #[derive(Encode, Decode)] pub struct Signature(pub [u8; 64]); diff --git a/core/primitives/src/sr25519.rs b/core/primitives/src/sr25519.rs index 0e573f49ce..ed8bb72c9e 100644 --- a/core/primitives/src/sr25519.rs +++ b/core/primitives/src/sr25519.rs @@ -47,6 +47,7 @@ use schnorrkel::keys::{MINI_SECRET_KEY_LENGTH, SECRET_KEY_LENGTH}; const SIGNING_CTX: &[u8] = b"substrate"; /// An Schnorrkel/Ristretto x25519 ("sr25519") public key. +#[cfg_attr(feature = "std", derive(Hash))] #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default)] pub struct Public(pub [u8; 32]); @@ -151,13 +152,6 @@ impl<'de> Deserialize<'de> for Public { } } -#[cfg(feature = "std")] -impl std::hash::Hash for Public { - fn hash(&self, state: &mut H) { - self.0.hash(state); - } -} - /// An Schnorrkel/Ristretto x25519 ("sr25519") signature. /// /// Instead of importing it for the local module, alias it to be available as a public type diff --git a/core/rpc-servers/src/lib.rs b/core/rpc-servers/src/lib.rs index a23b4a0899..3f408f6684 100644 --- a/core/rpc-servers/src/lib.rs +++ b/core/rpc-servers/src/lib.rs @@ -16,7 +16,7 @@ //! Substrate RPC servers. -#[warn(missing_docs)] +#![warn(missing_docs)] use std::io; use jsonrpc_core::IoHandlerExtension; diff --git a/core/service/src/chain_ops.rs b/core/service/src/chain_ops.rs index 0858534482..e6d7df33c2 100644 --- a/core/service/src/chain_ops.rs +++ b/core/service/src/chain_ops.rs @@ -46,7 +46,7 @@ macro_rules! export_blocks { let last_: u64 = last.saturated_into::(); let block_: u64 = block.saturated_into::(); let len: u64 = last_ - block_ + 1; - $output.write(&len.encode())?; + $output.write_all(&len.encode())?; } loop { @@ -59,7 +59,7 @@ macro_rules! export_blocks { serde_json::to_writer(&mut $output, &block) .map_err(|e| format!("Error writing JSON: {}", e))?; } else { - $output.write(&block.encode())?; + $output.write_all(&block.encode())?; } }, None => break, diff --git a/srml/support/src/hash.rs b/srml/support/src/hash.rs index 3775ebc26b..cbd78f6032 100644 --- a/srml/support/src/hash.rs +++ b/srml/support/src/hash.rs @@ -59,7 +59,7 @@ impl StorageHasher for Twox64Concat { type Output = Vec; fn hash(x: &[u8]) -> Vec { twox_64(x) - .into_iter() + .iter() .chain(x.into_iter()) .cloned() .collect::>() diff --git a/srml/support/src/traits.rs b/srml/support/src/traits.rs index cd11b56612..05f3cd070c 100644 --- a/srml/support/src/traits.rs +++ b/srml/support/src/traits.rs @@ -148,7 +148,7 @@ pub trait OnUnbalanced { fn on_unbalanced(amount: Imbalance); } -impl OnUnbalanced for () { +impl OnUnbalanced for () { fn on_unbalanced(amount: Imbalance) { drop(amount); } } diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index caa6d573b0..76cbe7cbab 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -567,7 +567,7 @@ impl Module { // We perform early return if we've reached the maximum capacity of the event list, // so `Events` seems to be corrupted. Also, this has happened after the start of execution // (since the event list is cleared at the block initialization). - if >::append([event].into_iter()).is_err() { + if >::append([event].iter()).is_err() { // The most sensible thing to do here is to just ignore this event and wait until the // new block. return; -- GitLab From d1cd01c74e8d5550396cb654f9a3f1b641efdf4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sun, 20 Oct 2019 13:02:21 +0200 Subject: [PATCH 241/275] Clean up the wasm-builder and release 1.0.8 (#3858) --- Cargo.lock | 2 +- core/executor/runtime-test/build.rs | 2 +- core/test-runtime/build.rs | 2 +- core/utils/wasm-builder/Cargo.toml | 2 +- core/utils/wasm-builder/src/lib.rs | 23 +++++++++++--------- core/utils/wasm-builder/src/prerequisites.rs | 12 ++++------ node-template/runtime/build.rs | 2 +- node/runtime/build.rs | 2 +- 8 files changed, 23 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d9bfc40409..aab1866999 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5759,7 +5759,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" -version = "1.0.7" +version = "1.0.8" dependencies = [ "build-helper 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/core/executor/runtime-test/build.rs b/core/executor/runtime-test/build.rs index 136dc79398..68e5205f0c 100644 --- a/core/executor/runtime-test/build.rs +++ b/core/executor/runtime-test/build.rs @@ -21,7 +21,7 @@ fn main() { "wasm_binary.rs", WasmBuilderSource::CratesOrPath { path: "../../utils/wasm-builder", - version: "1.0.7", + version: "1.0.8", }, // This instructs LLD to export __heap_base as a global variable, which is used by the // external memory allocator. diff --git a/core/test-runtime/build.rs b/core/test-runtime/build.rs index 2e2d1fc93e..200cd6d42c 100644 --- a/core/test-runtime/build.rs +++ b/core/test-runtime/build.rs @@ -21,7 +21,7 @@ fn main() { "wasm_binary.rs", WasmBuilderSource::CratesOrPath { path: "../utils/wasm-builder", - version: "1.0.7", + version: "1.0.8", }, // Note that we set the stack-size to 1MB explicitly even though it is set // to this value by default. This is because some of our tests (`restoration_of_globals`) diff --git a/core/utils/wasm-builder/Cargo.toml b/core/utils/wasm-builder/Cargo.toml index 7fcdd6c4e1..e9d38f2bd2 100644 --- a/core/utils/wasm-builder/Cargo.toml +++ b/core/utils/wasm-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-wasm-builder" -version = "1.0.7" +version = "1.0.8" authors = ["Parity Technologies "] description = "Utility for building WASM binaries" edition = "2018" diff --git a/core/utils/wasm-builder/src/lib.rs b/core/utils/wasm-builder/src/lib.rs index b97559c076..93e1700792 100644 --- a/core/utils/wasm-builder/src/lib.rs +++ b/core/utils/wasm-builder/src/lib.rs @@ -205,9 +205,7 @@ impl CargoCommand { } fn args(&mut self, args: &[&str]) -> &mut Self { - for arg in args { - self.arg(arg); - } + args.into_iter().for_each(|a| { self.arg(a); }); self } @@ -227,12 +225,17 @@ impl CargoCommand { /// Check if the supplied cargo command is a nightly version fn is_nightly(&self) -> bool { - self.command() - .arg("--version") - .output() - .map_err(|_| ()) - .and_then(|o| String::from_utf8(o.stdout).map_err(|_| ())) - .unwrap_or_default() - .contains("-nightly") + // `RUSTC_BOOTSTRAP` tells a stable compiler to behave like a nightly. So, when this env + // variable is set, we can assume that whatever rust compiler we have, it is a nightly compiler. + // For "more" information, see: + // https://github.com/rust-lang/rust/blob/fa0f7d0080d8e7e9eb20aa9cbf8013f96c81287f/src/libsyntax/feature_gate/check.rs#L891 + env::var("RUSTC_BOOTSTRAP").is_ok() || + self.command() + .arg("--version") + .output() + .map_err(|_| ()) + .and_then(|o| String::from_utf8(o.stdout).map_err(|_| ())) + .unwrap_or_default() + .contains("-nightly") } } diff --git a/core/utils/wasm-builder/src/prerequisites.rs b/core/utils/wasm-builder/src/prerequisites.rs index 73e356f0c2..3a7f8387dc 100644 --- a/core/utils/wasm-builder/src/prerequisites.rs +++ b/core/utils/wasm-builder/src/prerequisites.rs @@ -14,7 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use std::{env, fs}; +use std::fs; + use tempfile::tempdir; /// Checks that all prerequisites are installed. @@ -22,20 +23,15 @@ use tempfile::tempdir; /// # Returns /// Returns `None` if everything was found and `Some(ERR_MSG)` if something could not be found. pub fn check() -> Option<&'static str> { - if !rustc_stable_forced_to_nightly() && !check_nightly_installed(){ + if !check_nightly_installed(){ return Some("Rust nightly not installed, please install it!") } check_wasm_toolchain_installed() } -fn rustc_stable_forced_to_nightly() -> bool { - env::var("RUSTC_BOOTSTRAP") == Ok("1".to_string()) -} - fn check_nightly_installed() -> bool { - let command = crate::get_nightly_cargo(); - command.is_nightly() + crate::get_nightly_cargo().is_nightly() } fn check_wasm_toolchain_installed() -> Option<&'static str> { diff --git a/node-template/runtime/build.rs b/node-template/runtime/build.rs index ddbeefa112..c5e798c6ef 100644 --- a/node-template/runtime/build.rs +++ b/node-template/runtime/build.rs @@ -19,7 +19,7 @@ use wasm_builder_runner::{build_current_project_with_rustflags, WasmBuilderSourc fn main() { build_current_project_with_rustflags( "wasm_binary.rs", - WasmBuilderSource::Crates("1.0.7"), + WasmBuilderSource::Crates("1.0.8"), // This instructs LLD to export __heap_base as a global variable, which is used by the // external memory allocator. "-Clink-arg=--export=__heap_base", diff --git a/node/runtime/build.rs b/node/runtime/build.rs index 7311fb90ce..f5c2f98a75 100644 --- a/node/runtime/build.rs +++ b/node/runtime/build.rs @@ -21,7 +21,7 @@ fn main() { "wasm_binary.rs", WasmBuilderSource::CratesOrPath { path: "../../core/utils/wasm-builder", - version: "1.0.7", + version: "1.0.8", }, // This instructs LLD to export __heap_base as a global variable, which is used by the // external memory allocator. -- GitLab From c497fcb150002be1b34cc90d31d196e9766cd37a Mon Sep 17 00:00:00 2001 From: Ashley Date: Mon, 21 Oct 2019 07:46:23 +0100 Subject: [PATCH 242/275] Change Contracts::DefaultMaxDepth from 1024 to 32 (#3855) * Change DefaultMaxDepth from 1024 to 32 * bump impl and spec version --- node/runtime/src/lib.rs | 2 +- srml/contracts/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 69f812ce32..d11897845b 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -84,7 +84,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 179, + spec_version: 180, impl_version: 180, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/contracts/src/lib.rs b/srml/contracts/src/lib.rs index 3d8a455ad7..e52d059992 100644 --- a/srml/contracts/src/lib.rs +++ b/srml/contracts/src/lib.rs @@ -325,7 +325,7 @@ parameter_types! { /// A reasonable default value for [`Trait::InstantiateBaseFee`]. pub const DefaultInstantiateBaseFee: u32 = 1000; /// A reasonable default value for [`Trait::MaxDepth`]. - pub const DefaultMaxDepth: u32 = 1024; + pub const DefaultMaxDepth: u32 = 32; /// A reasonable default value for [`Trait::MaxValueSize`]. pub const DefaultMaxValueSize: u32 = 16_384; /// A reasonable default value for [`Trait::BlockGasLimit`]. -- GitLab From b7627c4cf8e109dfc80095c5c58f4cf082b56e4d Mon Sep 17 00:00:00 2001 From: CrocdileChan <1576710154@qq.com> Date: Mon, 21 Oct 2019 15:25:50 +0800 Subject: [PATCH 243/275] use ThreadPool to execute spawn_worker(fn) (#3836) * use ThreadPool to spawn_worker() * use ThreadPool to implement spawn_worker(fn) * use ThreadPool to implement spawn_worker(f) * update [dependencies] threadpool and num_cpus version * rm 'extern crate num_cpus' * cargo.lock update * merge the newest cargo.lock * Update Cargo.lock * use Mutex to wrap OffchainWorkers.thread_pool * format use crate * use parking_lot::Mutex instead of std::sync::Mutex --- Cargo.lock | 11 +++++++++++ core/offchain/Cargo.toml | 2 ++ core/offchain/src/lib.rs | 29 ++++++++++++++++------------- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aab1866999..2e30793e47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5316,6 +5316,7 @@ dependencies = [ "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5328,6 +5329,7 @@ dependencies = [ "substrate-primitives 2.0.0", "substrate-test-runtime-client 2.0.0", "substrate-transaction-pool 2.0.0", + "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5906,6 +5908,14 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "threadpool" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "time" version = "0.1.42" @@ -7176,6 +7186,7 @@ dependencies = [ "checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" +"checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c5676413eaeb1ea35300a0224416f57abc3bd251657e0fafc12c47ff98c060" "checksum tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d8a021c69bb74a44ccedb824a046447e2c84a01df9e5c20779750acb38e11b2" diff --git a/core/offchain/Cargo.toml b/core/offchain/Cargo.toml index ca9b27eee2..678d943c59 100644 --- a/core/offchain/Cargo.toml +++ b/core/offchain/Cargo.toml @@ -16,6 +16,8 @@ futures-timer = "0.4.0" hyper = "0.12.35" hyper-tls = "0.3.2" log = "0.4.8" +threadpool = "1.7" +num_cpus = "1.10" offchain-primitives = { package = "substrate-offchain-primitives", path = "./primitives" } codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } parking_lot = "0.9.0" diff --git a/core/offchain/src/lib.rs b/core/offchain/src/lib.rs index 79c6df04ea..a335ca5380 100644 --- a/core/offchain/src/lib.rs +++ b/core/offchain/src/lib.rs @@ -39,6 +39,8 @@ use std::{ sync::Arc, }; +use parking_lot::Mutex; +use threadpool::ThreadPool; use client::runtime_api::ApiExt; use futures::future::Future; use log::{debug, warn}; @@ -58,6 +60,7 @@ pub struct OffchainWorkers { client: Arc, db: Storage, _block: PhantomData, + thread_pool: Mutex, } impl OffchainWorkers { @@ -67,6 +70,7 @@ impl OffchainWorkers OffchainWorkers< debug!("Spawning offchain workers at {:?}", at); let number = *number; let client = self.client.clone(); - spawn_worker(move || { + self.spawn_worker(move || { let runtime = client.runtime_api(); let api = Box::new(api); debug!("Running offchain workers at {:?}", at); @@ -134,19 +138,18 @@ impl OffchainWorkers< futures::future::Either::Right(futures::future::ready(())) } } -} -/// Spawns a new offchain worker. -/// -/// We spawn offchain workers for each block in a separate thread, -/// since they can run for a significant amount of time -/// in a blocking fashion and we don't want to block the runtime. -/// -/// Note that we should avoid that if we switch to future-based runtime in the future, -/// alternatively: -/// TODO [ToDr] (#1458) we can consider using a thread pool instead. -fn spawn_worker(f: impl FnOnce() -> () + Send + 'static) { - std::thread::spawn(f); + /// Spawns a new offchain worker. + /// + /// We spawn offchain workers for each block in a separate thread, + /// since they can run for a significant amount of time + /// in a blocking fashion and we don't want to block the runtime. + /// + /// Note that we should avoid that if we switch to future-based runtime in the future, + /// alternatively: + fn spawn_worker(&self, f: impl FnOnce() -> () + Send + 'static) { + self.thread_pool.lock().execute(f); + } } #[cfg(test)] -- GitLab From 44a9482bdac1ebbb5c820530b25eb4554739bf84 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Mon, 21 Oct 2019 23:40:22 +0300 Subject: [PATCH 244/275] Use uniform quotes (#3867) --- node-template/runtime/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node-template/runtime/Cargo.toml b/node-template/runtime/Cargo.toml index df9dd9c77f..5ebf3af6cf 100644 --- a/node-template/runtime/Cargo.toml +++ b/node-template/runtime/Cargo.toml @@ -43,7 +43,7 @@ std = [ "balances/std", "aura/std", "aura-primitives/std", - 'grandpa/std', + "grandpa/std", "executive/std", "indices/std", "primitives/std", -- GitLab From 271f4cfd523061abfd3ec7724fb1064caecc939d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 22 Oct 2019 03:09:39 +0200 Subject: [PATCH 245/275] Fix deserialization of `Bytes` (#3866) * Update impl-serde to patch RPC. * Add test. * Fix long line. --- Cargo.lock | 12 ++++++------ core/rpc/src/state/tests.rs | 8 ++++++++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2e30793e47..d77ba65cbd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1412,7 +1412,7 @@ dependencies = [ [[package]] name = "impl-serde" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3034,7 +3034,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fixed-hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "impl-codec 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-serde 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "uint 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3957,7 +3957,7 @@ dependencies = [ name = "sr-version" version = "2.0.0" dependencies = [ - "impl-serde 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", @@ -5386,7 +5386,7 @@ dependencies = [ "hash256-std-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-serde 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5415,7 +5415,7 @@ dependencies = [ name = "substrate-primitives-storage" version = "2.0.0" dependencies = [ - "impl-serde 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", ] @@ -6941,7 +6941,7 @@ dependencies = [ "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" "checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" "checksum impl-codec 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3fa0086251524c50fd53b32e7b05eb6d79e2f97221eaf0c53c0ca9c3096f21d3" -"checksum impl-serde 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bbb1ea6188aca47a0eaeeb330d8a82f16cd500f30b897062d23922568727333a" +"checksum impl-serde 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a263dc95daa6c3788c8f7133d86dc2ad89ec5a0c56167f9e3441c5f7f33358c4" "checksum impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6947b372790f8948f439bb6aaa6baabdf80be1a207a477ff072f83fb793e428f" "checksum indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a61202fbe46c4a951e9404a720a0180bcf3212c750d735cb5c4ba4dc551299f3" "checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" diff --git a/core/rpc/src/state/tests.rs b/core/rpc/src/state/tests.rs index 3790b3ea11..5dfa234337 100644 --- a/core/rpc/src/state/tests.rs +++ b/core/rpc/src/state/tests.rs @@ -313,3 +313,11 @@ fn should_notify_on_runtime_version_initially() { // no more notifications on this channel assert_eq!(core.block_on(next.into_future()).unwrap().0, None); } + +#[test] +fn should_deserialize_storage_key() { + let k = "\"0x7f864e18e3dd8b58386310d2fe0919eef27c6e558564b7f67f22d99d20f587b\""; + let k: StorageKey = serde_json::from_str(k).unwrap(); + + assert_eq!(k.0.len(), 32); +} -- GitLab From 0b972942392db1042ae67300f37f4accaa8304cf Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Tue, 22 Oct 2019 03:53:58 -0400 Subject: [PATCH 246/275] Explicitly declare decl_storage! getters as functions (#3870) * parse decl_storage getters with fn keyword * test for get in decl_storage * update all decl_storage! getters * bump version * adjust missed doc line --- node-template/runtime/src/template.rs | 4 +-- node/runtime/src/lib.rs | 4 +-- srml/assets/src/lib.rs | 2 +- srml/aura/src/lib.rs | 4 +-- srml/authority-discovery/src/lib.rs | 2 +- srml/babe/src/lib.rs | 12 +++---- srml/balances/src/lib.rs | 10 +++--- srml/collective/src/lib.rs | 10 +++--- srml/contracts/src/lib.rs | 6 ++-- srml/democracy/src/lib.rs | 24 ++++++------- srml/elections-phragmen/src/lib.rs | 18 +++++----- srml/elections/src/lib.rs | 32 ++++++++--------- srml/example/src/lib.rs | 10 +++--- srml/finality-tracker/src/lib.rs | 8 ++--- srml/generic-asset/src/lib.rs | 12 +++---- srml/grandpa/src/lib.rs | 12 +++---- srml/im-online/src/lib.rs | 6 ++-- srml/indices/src/lib.rs | 4 +-- srml/membership/src/lib.rs | 2 +- srml/offences/src/lib.rs | 2 +- srml/randomness-collective-flip/src/lib.rs | 2 +- srml/scored-pool/src/lib.rs | 8 ++--- srml/session/src/historical.rs | 4 +-- srml/session/src/lib.rs | 8 ++--- srml/staking/src/lib.rs | 36 ++++++++++---------- srml/sudo/src/lib.rs | 2 +- srml/support/procedural/src/lib.rs | 6 ++-- srml/support/procedural/src/storage/parse.rs | 15 +++++--- srml/support/src/lib.rs | 16 +++++++-- srml/support/src/storage/storage_items.rs | 32 ++++++++--------- srml/support/test/tests/final_keys.rs | 8 ++--- srml/support/test/tests/issue2219.rs | 14 ++++---- srml/system/src/lib.rs | 20 +++++------ srml/timestamp/src/lib.rs | 2 +- srml/transaction-payment/src/lib.rs | 2 +- srml/treasury/src/lib.rs | 6 ++-- 36 files changed, 190 insertions(+), 175 deletions(-) diff --git a/node-template/runtime/src/template.rs b/node-template/runtime/src/template.rs index 8c6c35edc4..db7bd24b0e 100644 --- a/node-template/runtime/src/template.rs +++ b/node-template/runtime/src/template.rs @@ -24,8 +24,8 @@ decl_storage! { trait Store for Module as TemplateModule { // Just a dummy storage item. // Here we are declaring a StorageValue, `Something` as a Option - // `get(something)` is the default getter which returns either the stored `u32` or `None` if nothing stored - Something get(something): Option; + // `get(fn something)` is the default getter which returns either the stored `u32` or `None` if nothing stored + Something get(fn something): Option; } } diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index d11897845b..75e1c9eefd 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -84,8 +84,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 180, - impl_version: 180, + spec_version: 181, + impl_version: 181, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/assets/src/lib.rs b/srml/assets/src/lib.rs index 37845c3a14..528428000e 100644 --- a/srml/assets/src/lib.rs +++ b/srml/assets/src/lib.rs @@ -215,7 +215,7 @@ decl_storage! { /// The number of units of assets held by any given account. Balances: map (T::AssetId, T::AccountId) => T::Balance; /// The next asset identifier up for grabs. - NextAssetId get(next_asset_id): T::AssetId; + NextAssetId get(fn next_asset_id): T::AssetId; /// The total unit supply of an asset. TotalSupply: map T::AssetId => T::Balance; } diff --git a/srml/aura/src/lib.rs b/srml/aura/src/lib.rs index 834d6b0a14..f9034c7ca0 100644 --- a/srml/aura/src/lib.rs +++ b/srml/aura/src/lib.rs @@ -148,10 +148,10 @@ pub trait Trait: timestamp::Trait { decl_storage! { trait Store for Module as Aura { /// The last timestamp. - LastTimestamp get(last) build(|_| 0.into()): T::Moment; + LastTimestamp get(fn last) build(|_| 0.into()): T::Moment; /// The current authorities - pub Authorities get(authorities): Vec; + pub Authorities get(fn authorities): Vec; } add_extra_genesis { config(authorities): Vec; diff --git a/srml/authority-discovery/src/lib.rs b/srml/authority-discovery/src/lib.rs index 2c923103a8..c82d580fd9 100644 --- a/srml/authority-discovery/src/lib.rs +++ b/srml/authority-discovery/src/lib.rs @@ -41,7 +41,7 @@ pub trait Trait: system::Trait + session::Trait { decl_storage! { trait Store for Module as AuthorityDiscovery { /// The current set of keys that may issue a heartbeat. - Keys get(keys): Vec; + Keys get(fn keys): Vec; } add_extra_genesis { config(keys): Vec; diff --git a/srml/babe/src/lib.rs b/srml/babe/src/lib.rs index e69877d783..ee2d66fbe6 100644 --- a/srml/babe/src/lib.rs +++ b/srml/babe/src/lib.rs @@ -180,17 +180,17 @@ type MaybeVrf = Option<[u8; 32 /* VRF_OUTPUT_LENGTH */]>; decl_storage! { trait Store for Module as Babe { /// Current epoch index. - pub EpochIndex get(epoch_index): u64; + pub EpochIndex get(fn epoch_index): u64; /// Current epoch authorities. - pub Authorities get(authorities): Vec<(AuthorityId, BabeAuthorityWeight)>; + pub Authorities get(fn authorities): Vec<(AuthorityId, BabeAuthorityWeight)>; /// The slot at which the first epoch actually started. This is 0 /// until the first block of the chain. - pub GenesisSlot get(genesis_slot): u64; + pub GenesisSlot get(fn genesis_slot): u64; /// Current slot number. - pub CurrentSlot get(current_slot): u64; + pub CurrentSlot get(fn current_slot): u64; /// The epoch randomness for the *current* epoch. /// @@ -205,7 +205,7 @@ decl_storage! { // NOTE: the following fields don't use the constants to define the // array size because the metadata API currently doesn't resolve the // variable to its underlying value. - pub Randomness get(randomness): [u8; 32 /* RANDOMNESS_LENGTH */]; + pub Randomness get(fn randomness): [u8; 32 /* RANDOMNESS_LENGTH */]; /// Next epoch randomness. NextRandomness: [u8; 32 /* RANDOMNESS_LENGTH */]; @@ -224,7 +224,7 @@ decl_storage! { /// Temporary value (cleared at block finalization) which is `Some` /// if per-block initialization has already been called for current block. - Initialized get(initialized): Option; + Initialized get(fn initialized): Option; } add_extra_genesis { config(authorities): Vec<(AuthorityId, BabeAuthorityWeight)>; diff --git a/srml/balances/src/lib.rs b/srml/balances/src/lib.rs index 4f8edc5428..b0b0a60efa 100644 --- a/srml/balances/src/lib.rs +++ b/srml/balances/src/lib.rs @@ -295,12 +295,12 @@ pub struct BalanceLock { decl_storage! { trait Store for Module, I: Instance=DefaultInstance> as Balances { /// The total units issued in the system. - pub TotalIssuance get(total_issuance) build(|config: &GenesisConfig| { + pub TotalIssuance get(fn total_issuance) build(|config: &GenesisConfig| { config.balances.iter().fold(Zero::zero(), |acc: T::Balance, &(_, n)| acc + n) }): T::Balance; /// Information regarding the vesting of a given account. - pub Vesting get(vesting) build(|config: &GenesisConfig| { + pub Vesting get(fn vesting) build(|config: &GenesisConfig| { // Generate initial vesting configuration // * who - Account which we are generating vesting configuration for // * begin - Block when the account will start to vest @@ -337,7 +337,7 @@ decl_storage! { /// /// `system::AccountNonce` is also deleted if `ReservedBalance` is also zero (it also gets /// collapsed to zero if it ever becomes less than `ExistentialDeposit`. - pub FreeBalance get(free_balance) + pub FreeBalance get(fn free_balance) build(|config: &GenesisConfig| config.balances.clone()): map T::AccountId => T::Balance; @@ -352,10 +352,10 @@ decl_storage! { /// /// `system::AccountNonce` is also deleted if `FreeBalance` is also zero (it also gets /// collapsed to zero if it ever becomes less than `ExistentialDeposit`.) - pub ReservedBalance get(reserved_balance): map T::AccountId => T::Balance; + pub ReservedBalance get(fn reserved_balance): map T::AccountId => T::Balance; /// Any liquidity locks on some account balances. - pub Locks get(locks): map T::AccountId => Vec>; + pub Locks get(fn locks): map T::AccountId => Vec>; } add_extra_genesis { config(balances): Vec<(T::AccountId, T::Balance)>; diff --git a/srml/collective/src/lib.rs b/srml/collective/src/lib.rs index edfc4bf46f..a965230246 100644 --- a/srml/collective/src/lib.rs +++ b/srml/collective/src/lib.rs @@ -86,15 +86,15 @@ pub struct Votes { decl_storage! { trait Store for Module, I: Instance=DefaultInstance> as Collective { /// The hashes of the active proposals. - pub Proposals get(proposals): Vec; + pub Proposals get(fn proposals): Vec; /// Actual proposal for a given hash, if it's current. - pub ProposalOf get(proposal_of): map T::Hash => Option<>::Proposal>; + pub ProposalOf get(fn proposal_of): map T::Hash => Option<>::Proposal>; /// Votes on a given proposal, if it is ongoing. - pub Voting get(voting): map T::Hash => Option>; + pub Voting get(fn voting): map T::Hash => Option>; /// Proposals so far. - pub ProposalCount get(proposal_count): u32; + pub ProposalCount get(fn proposal_count): u32; /// The current members of the collective. This is stored sorted (just by value). - pub Members get(members): Vec; + pub Members get(fn members): Vec; } add_extra_genesis { config(phantom): rstd::marker::PhantomData; diff --git a/srml/contracts/src/lib.rs b/srml/contracts/src/lib.rs index e52d059992..b3c8c9b764 100644 --- a/srml/contracts/src/lib.rs +++ b/srml/contracts/src/lib.rs @@ -838,9 +838,9 @@ decl_event! { decl_storage! { trait Store for Module as Contract { /// Gas spent so far in this block. - GasSpent get(gas_spent): Gas; + GasSpent get(fn gas_spent): Gas; /// Current cost schedule for contracts. - CurrentSchedule get(current_schedule) config(): Schedule = Schedule::default(); + CurrentSchedule get(fn current_schedule) config(): Schedule = Schedule::default(); /// A mapping from an original code hash to the original code, untouched by instrumentation. pub PristineCode: map CodeHash => Option>; /// A mapping between an original code hash and instrumented wasm code, ready for execution. @@ -850,7 +850,7 @@ decl_storage! { /// The code associated with a given account. pub ContractInfoOf: map T::AccountId => Option>; /// The price of one unit of gas. - GasPrice get(gas_price) config(): BalanceOf = 1.into(); + GasPrice get(fn gas_price) config(): BalanceOf = 1.into(); } } diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index b7e7dac6f9..af145828ab 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -259,38 +259,38 @@ impl ReferendumInfo as Democracy { /// The number of (public) proposals that have been made so far. - pub PublicPropCount get(public_prop_count) build(|_| 0 as PropIndex) : PropIndex; + pub PublicPropCount get(fn public_prop_count) build(|_| 0 as PropIndex) : PropIndex; /// The public proposals. Unsorted. - pub PublicProps get(public_props): Vec<(PropIndex, T::Proposal, T::AccountId)>; + pub PublicProps get(fn public_props): Vec<(PropIndex, T::Proposal, T::AccountId)>; /// Those who have locked a deposit. - pub DepositOf get(deposit_of): map PropIndex => Option<(BalanceOf, Vec)>; + pub DepositOf get(fn deposit_of): map PropIndex => Option<(BalanceOf, Vec)>; /// The next free referendum index, aka the number of referenda started so far. - pub ReferendumCount get(referendum_count) build(|_| 0 as ReferendumIndex): ReferendumIndex; + pub ReferendumCount get(fn referendum_count) build(|_| 0 as ReferendumIndex): ReferendumIndex; /// The next referendum index that should be tallied. - pub NextTally get(next_tally) build(|_| 0 as ReferendumIndex): ReferendumIndex; + pub NextTally get(fn next_tally) build(|_| 0 as ReferendumIndex): ReferendumIndex; /// Information concerning any given referendum. - pub ReferendumInfoOf get(referendum_info): + pub ReferendumInfoOf get(fn referendum_info): map ReferendumIndex => Option<(ReferendumInfo)>; /// Queue of successful referenda to be dispatched. - pub DispatchQueue get(dispatch_queue): + pub DispatchQueue get(fn dispatch_queue): map T::BlockNumber => Vec>; /// Get the voters for the current proposal. - pub VotersFor get(voters_for): map ReferendumIndex => Vec; + pub VotersFor get(fn voters_for): map ReferendumIndex => Vec; /// Get the vote in a given referendum of a particular voter. The result is meaningful only /// if `voters_for` includes the voter when called with the referendum (you'll get the /// default `Vote` value otherwise). If you don't want to check `voters_for`, then you can /// also check for simple existence with `VoteOf::exists` first. - pub VoteOf get(vote_of): map (ReferendumIndex, T::AccountId) => Vote; + pub VoteOf get(fn vote_of): map (ReferendumIndex, T::AccountId) => Vote; /// Who is able to vote for whom. Value is the fund-holding account, key is the /// vote-transaction-sending account. - pub Proxy get(proxy): map T::AccountId => Option; + pub Proxy get(fn proxy): map T::AccountId => Option; /// Get the account (and lock periods) to which another account is delegating vote. - pub Delegations get(delegations): linked_map T::AccountId => (T::AccountId, Conviction); + pub Delegations get(fn delegations): linked_map T::AccountId => (T::AccountId, Conviction); /// True if the last referendum tabled was submitted externally. False if it was a public /// proposal. @@ -304,7 +304,7 @@ decl_storage! { /// A record of who vetoed what. Maps proposal hash to a possible existent block number /// (until when it may not be resubmitted) and who vetoed it. - pub Blacklist get(blacklist): map T::Hash => Option<(T::BlockNumber, Vec)>; + pub Blacklist get(fn blacklist): map T::Hash => Option<(T::BlockNumber, Vec)>; /// Record of all proposals that have been subject to emergency cancellation. pub Cancellations: map T::Hash => bool; diff --git a/srml/elections-phragmen/src/lib.rs b/srml/elections-phragmen/src/lib.rs index fdc88ce9e0..781d506bd6 100644 --- a/srml/elections-phragmen/src/lib.rs +++ b/srml/elections-phragmen/src/lib.rs @@ -132,29 +132,29 @@ decl_storage! { trait Store for Module as PhragmenElection { // ---- parameters /// Number of members to elect. - pub DesiredMembers get(desired_members) config(): u32; + pub DesiredMembers get(fn desired_members) config(): u32; /// Number of runners_up to keep. - pub DesiredRunnersUp get(desired_runners_up) config(): u32; + pub DesiredRunnersUp get(fn desired_runners_up) config(): u32; /// How long each seat is kept. This defines the next block number at which an election /// round will happen. - pub TermDuration get(term_duration) config(): T::BlockNumber; + pub TermDuration get(fn term_duration) config(): T::BlockNumber; // ---- State /// The current elected membership. Sorted based on account id. - pub Members get(members) config(): Vec; + pub Members get(fn members) config(): Vec; /// The current runners_up. Sorted based on low to high merit (worse to best runner). - pub RunnersUp get(runners_up): Vec; + pub RunnersUp get(fn runners_up): Vec; /// The total number of vote rounds that have happened, excluding the upcoming one. - pub ElectionRounds get(election_rounds): u32 = Zero::zero(); + pub ElectionRounds get(fn election_rounds): u32 = Zero::zero(); /// Votes of a particular voter, with the round index of the votes. - pub VotesOf get(votes_of): linked_map T::AccountId => Vec; + pub VotesOf get(fn votes_of): linked_map T::AccountId => Vec; /// Locked stake of a voter. - pub StakeOf get(stake_of): map T::AccountId => BalanceOf; + pub StakeOf get(fn stake_of): map T::AccountId => BalanceOf; /// The present candidate list. Sorted based on account id. A current member can never enter /// this vector and is always implicitly assumed to be a candidate. - pub Candidates get(candidates): Vec; + pub Candidates get(fn candidates): Vec; } } diff --git a/srml/elections/src/lib.rs b/srml/elections/src/lib.rs index 8c90090349..439be7e76c 100644 --- a/srml/elections/src/lib.rs +++ b/srml/elections/src/lib.rs @@ -213,11 +213,11 @@ decl_storage! { // ---- parameters /// How long to give each top candidate to present themselves after the vote ends. - pub PresentationDuration get(presentation_duration) config(): T::BlockNumber; + pub PresentationDuration get(fn presentation_duration) config(): T::BlockNumber; /// How long each position is active for. - pub TermDuration get(term_duration) config(): T::BlockNumber; + pub TermDuration get(fn term_duration) config(): T::BlockNumber; /// Number of accounts that should constitute the collective. - pub DesiredSeats get(desired_seats) config(): u32; + pub DesiredSeats get(fn desired_seats) config(): u32; // ---- permanent state (always relevant, changes only at the finalization of voting) @@ -225,9 +225,9 @@ decl_storage! { /// executive matters. The block number (second element in the tuple) is the block that /// their position is active until (calculated by the sum of the block number when the /// member was elected and their term duration). - pub Members get(members) config(): Vec<(T::AccountId, T::BlockNumber)>; + pub Members get(fn members) config(): Vec<(T::AccountId, T::BlockNumber)>; /// The total number of vote rounds that have happened or are in progress. - pub VoteCount get(vote_index): VoteIndex; + pub VoteCount get(fn vote_index): VoteIndex; // ---- persistent state (always relevant, changes constantly) @@ -235,35 +235,35 @@ decl_storage! { // bit-wise manner. In order to get a human-readable representation (`Vec`), use // [`all_approvals_of`]. Furthermore, each vector of scalars is chunked with the cap of // `APPROVAL_SET_SIZE`. - pub ApprovalsOf get(approvals_of): map (T::AccountId, SetIndex) => Vec; + pub ApprovalsOf get(fn approvals_of): map (T::AccountId, SetIndex) => Vec; /// The vote index and list slot that the candidate `who` was registered or `None` if they /// are not currently registered. - pub RegisterInfoOf get(candidate_reg_info): map T::AccountId => Option<(VoteIndex, u32)>; + pub RegisterInfoOf get(fn candidate_reg_info): map T::AccountId => Option<(VoteIndex, u32)>; /// Basic information about a voter. - pub VoterInfoOf get(voter_info): map T::AccountId => Option>>; + pub VoterInfoOf get(fn voter_info): map T::AccountId => Option>>; /// The present voter list (chunked and capped at [`VOTER_SET_SIZE`]). - pub Voters get(voters): map SetIndex => Vec>; + pub Voters get(fn voters): map SetIndex => Vec>; /// the next free set to store a voter in. This will keep growing. - pub NextVoterSet get(next_nonfull_voter_set): SetIndex = 0; + pub NextVoterSet get(fn next_nonfull_voter_set): SetIndex = 0; /// Current number of Voters. - pub VoterCount get(voter_count): SetIndex = 0; + pub VoterCount get(fn voter_count): SetIndex = 0; /// The present candidate list. - pub Candidates get(candidates): Vec; // has holes + pub Candidates get(fn candidates): Vec; // has holes /// Current number of active candidates - pub CandidateCount get(candidate_count): u32; + pub CandidateCount get(fn candidate_count): u32; // ---- temporary state (only relevant during finalization/presentation) /// The accounts holding the seats that will become free on the next tally. - pub NextFinalize get(next_finalize): Option<(T::BlockNumber, u32, Vec)>; + pub NextFinalize get(fn next_finalize): Option<(T::BlockNumber, u32, Vec)>; /// Get the leaderboard if we're in the presentation phase. The first element is the weight /// of each entry; It may be the direct summed approval stakes, or a weighted version of it. /// Sorted from low to high. - pub Leaderboard get(leaderboard): Option, T::AccountId)> >; + pub Leaderboard get(fn leaderboard): Option, T::AccountId)> >; /// Who is able to vote for whom. Value is the fund-holding account, key is the /// vote-transaction-sending account. - pub Proxy get(proxy): map T::AccountId => Option; + pub Proxy get(fn proxy): map T::AccountId => Option; } } diff --git a/srml/example/src/lib.rs b/srml/example/src/lib.rs index a6a075d8cb..bc85241456 100644 --- a/srml/example/src/lib.rs +++ b/srml/example/src/lib.rs @@ -318,7 +318,7 @@ decl_storage! { // keep things around between blocks. trait Store for Module as Example { // Any storage declarations of the form: - // `pub? Name get(getter_name)? [config()|config(myname)] [build(|_| {...})] : (= )?;` + // `pub? Name get(fn getter_name)? [config()|config(myname)] [build(|_| {...})] : (= )?;` // where `` is either: // - `Type` (a basic value item); or // - `map KeyType => ValueType` (a map item). @@ -331,7 +331,7 @@ decl_storage! { // - `Foo::put(1); Foo::get()` returns `1`; // - `Foo::kill(); Foo::get()` returns `0` (u32::default()). // e.g. Foo: u32; - // e.g. pub Bar get(bar): map T::AccountId => Vec<(T::Balance, u64)>; + // e.g. pub Bar get(fn bar): map T::AccountId => Vec<(T::Balance, u64)>; // // For basic value items, you'll get a type which implements // `support::StorageValue`. For map items, you'll get a type which @@ -340,13 +340,13 @@ decl_storage! { // If they have a getter (`get(getter_name)`), then your module will come // equipped with `fn getter_name() -> Type` for basic value items or // `fn getter_name(key: KeyType) -> ValueType` for map items. - Dummy get(dummy) config(): Option; + Dummy get(fn dummy) config(): Option; // A map that has enumerable entries. - Bar get(bar) config(): linked_map T::AccountId => T::Balance; + Bar get(fn bar) config(): linked_map T::AccountId => T::Balance; // this one uses the default, we'll demonstrate the usage of 'mutate' API. - Foo get(foo) config(): T::Balance; + Foo get(fn foo) config(): T::Balance; } } diff --git a/srml/finality-tracker/src/lib.rs b/srml/finality-tracker/src/lib.rs index 1106a17a58..5e973cd432 100644 --- a/srml/finality-tracker/src/lib.rs +++ b/srml/finality-tracker/src/lib.rs @@ -96,17 +96,17 @@ pub trait Trait: SystemTrait { decl_storage! { trait Store for Module as Timestamp { /// Recent hints. - RecentHints get(recent_hints) build(|_| vec![T::BlockNumber::zero()]): Vec; + RecentHints get(fn recent_hints) build(|_| vec![T::BlockNumber::zero()]): Vec; /// Ordered recent hints. - OrderedHints get(ordered_hints) build(|_| vec![T::BlockNumber::zero()]): Vec; + OrderedHints get(fn ordered_hints) build(|_| vec![T::BlockNumber::zero()]): Vec; /// The median. - Median get(median) build(|_| T::BlockNumber::zero()): T::BlockNumber; + Median get(fn median) build(|_| T::BlockNumber::zero()): T::BlockNumber; /// Final hint to apply in the block. `None` means "same as parent". Update: Option; // when initialized through config this is set in the beginning. - Initialized get(initialized) build(|_| false): bool; + Initialized get(fn initialized) build(|_| false): bool; } } diff --git a/srml/generic-asset/src/lib.rs b/srml/generic-asset/src/lib.rs index ca49e2f1cd..12e9d2cbf6 100644 --- a/srml/generic-asset/src/lib.rs +++ b/srml/generic-asset/src/lib.rs @@ -447,7 +447,7 @@ pub struct BalanceLock { decl_storage! { trait Store for Module as GenericAsset { /// Total issuance of a given asset. - pub TotalIssuance get(total_issuance) build(|config: &GenesisConfig| { + pub TotalIssuance get(fn total_issuance) build(|config: &GenesisConfig| { let issuance = config.initial_balance * (config.endowed_accounts.len() as u32).into(); config.assets.iter().map(|id| (id.clone(), issuance)).collect::>() }): map T::AssetId => T::Balance; @@ -459,19 +459,19 @@ decl_storage! { pub ReservedBalance: double_map T::AssetId, twox_128(T::AccountId) => T::Balance; /// Next available ID for user-created asset. - pub NextAssetId get(next_asset_id) config(): T::AssetId; + pub NextAssetId get(fn next_asset_id) config(): T::AssetId; /// Permission options for a given asset. - pub Permissions get(get_permission): map T::AssetId => PermissionVersions; + pub Permissions get(fn get_permission): map T::AssetId => PermissionVersions; /// Any liquidity locks on some account balances. - pub Locks get(locks): map T::AccountId => Vec>; + pub Locks get(fn locks): map T::AccountId => Vec>; /// The identity of the asset which is the one that is designated for the chain's staking system. - pub StakingAssetId get(staking_asset_id) config(): T::AssetId; + pub StakingAssetId get(fn staking_asset_id) config(): T::AssetId; /// The identity of the asset which is the one that is designated for paying the chain's transaction fee. - pub SpendingAssetId get(spending_asset_id) config(): T::AssetId; + pub SpendingAssetId get(fn spending_asset_id) config(): T::AssetId; } add_extra_genesis { config(assets): Vec; diff --git a/srml/grandpa/src/lib.rs b/srml/grandpa/src/lib.rs index 610bd18fb3..0fc0df382a 100644 --- a/srml/grandpa/src/lib.rs +++ b/srml/grandpa/src/lib.rs @@ -138,26 +138,26 @@ decl_event!( decl_storage! { trait Store for Module as GrandpaFinality { /// The current authority set. - Authorities get(authorities): Vec<(AuthorityId, AuthorityWeight)>; + Authorities get(fn authorities): Vec<(AuthorityId, AuthorityWeight)>; /// State of the current authority set. - State get(state): StoredState = StoredState::Live; + State get(fn state): StoredState = StoredState::Live; /// Pending change: (signaled at, scheduled change). PendingChange: Option>; /// next block number where we can force a change. - NextForced get(next_forced): Option; + NextForced get(fn next_forced): Option; /// `true` if we are currently stalled. - Stalled get(stalled): Option<(T::BlockNumber, T::BlockNumber)>; + Stalled get(fn stalled): Option<(T::BlockNumber, T::BlockNumber)>; /// The number of changes (both in terms of keys and underlying economic responsibilities) /// in the "set" of Grandpa validators from genesis. - CurrentSetId get(current_set_id) build(|_| fg_primitives::SetId::default()): SetId; + CurrentSetId get(fn current_set_id) build(|_| fg_primitives::SetId::default()): SetId; /// A mapping from grandpa set ID to the index of the *most recent* session for which its members were responsible. - SetIdSession get(session_for_set): map SetId => Option; + SetIdSession get(fn session_for_set): map SetId => Option; } add_extra_genesis { config(authorities): Vec<(AuthorityId, AuthorityWeight)>; diff --git a/srml/im-online/src/lib.rs b/srml/im-online/src/lib.rs index 84c95fee47..1a75cebd2e 100644 --- a/srml/im-online/src/lib.rs +++ b/srml/im-online/src/lib.rs @@ -221,14 +221,14 @@ decl_event!( decl_storage! { trait Store for Module as ImOnline { /// The block number when we should gossip. - GossipAt get(gossip_at): T::BlockNumber; + GossipAt get(fn gossip_at): T::BlockNumber; /// The current set of keys that may issue a heartbeat. - Keys get(keys): Vec; + Keys get(fn keys): Vec; /// For each session index we keep a mapping of `AuthorityId` /// to `offchain::OpaqueNetworkState`. - ReceivedHeartbeats get(received_heartbeats): double_map SessionIndex, + ReceivedHeartbeats get(fn received_heartbeats): double_map SessionIndex, blake2_256(AuthIndex) => Vec; } add_extra_genesis { diff --git a/srml/indices/src/lib.rs b/srml/indices/src/lib.rs index be5016c40e..31aa57276b 100644 --- a/srml/indices/src/lib.rs +++ b/srml/indices/src/lib.rs @@ -93,12 +93,12 @@ decl_event!( decl_storage! { trait Store for Module as Indices { /// The next free enumeration set. - pub NextEnumSet get(next_enum_set) build(|config: &GenesisConfig| { + pub NextEnumSet get(fn next_enum_set) build(|config: &GenesisConfig| { (config.ids.len() as u32 / ENUM_SET_SIZE).into() }): T::AccountIndex; /// The enumeration sets. - pub EnumSet get(enum_set) build(|config: &GenesisConfig| { + pub EnumSet get(fn enum_set) build(|config: &GenesisConfig| { (0..((config.ids.len() as u32) + ENUM_SET_SIZE - 1) / ENUM_SET_SIZE) .map(|i| ( i.into(), diff --git a/srml/membership/src/lib.rs b/srml/membership/src/lib.rs index 5d2001b32d..6cd2a914e6 100644 --- a/srml/membership/src/lib.rs +++ b/srml/membership/src/lib.rs @@ -57,7 +57,7 @@ pub trait Trait: system::Trait { decl_storage! { trait Store for Module, I: Instance=DefaultInstance> as Membership { /// The current membership, stored as an ordered Vec. - Members get(members): Vec; + Members get(fn members): Vec; } add_extra_genesis { config(members): Vec; diff --git a/srml/offences/src/lib.rs b/srml/offences/src/lib.rs index 801b8b5fca..a6cf4d7956 100644 --- a/srml/offences/src/lib.rs +++ b/srml/offences/src/lib.rs @@ -59,7 +59,7 @@ pub trait Trait: system::Trait { decl_storage! { trait Store for Module as Offences { /// The primary structure that holds all offence records keyed by report identifiers. - Reports get(reports): map ReportIdOf => Option>; + Reports get(fn reports): map ReportIdOf => Option>; /// A vector of reports of the same kind that happened at the same time slot. ConcurrentReportsIndex: double_map Kind, blake2_256(OpaqueTimeSlot) => Vec>; diff --git a/srml/randomness-collective-flip/src/lib.rs b/srml/randomness-collective-flip/src/lib.rs index f6261b6a03..3644b8898c 100644 --- a/srml/randomness-collective-flip/src/lib.rs +++ b/srml/randomness-collective-flip/src/lib.rs @@ -87,7 +87,7 @@ decl_storage! { /// Series of block headers from the last 81 blocks that acts as random seed material. This /// is arranged as a ring buffer with `block_number % 81` being the index into the `Vec` of /// the oldest hash. - RandomMaterial get(random_material): Vec; + RandomMaterial get(fn random_material): Vec; } } diff --git a/srml/scored-pool/src/lib.rs b/srml/scored-pool/src/lib.rs index 609f17b457..fa18d899e2 100644 --- a/srml/scored-pool/src/lib.rs +++ b/srml/scored-pool/src/lib.rs @@ -154,20 +154,20 @@ decl_storage! { trait Store for Module, I: Instance=DefaultInstance> as ScoredPool { /// The current pool of candidates, stored as an ordered Vec /// (ordered descending by score, `None` last, highest first). - Pool get(pool) config(): PoolT; + Pool get(fn pool) config(): PoolT; /// A Map of the candidates. The information in this Map is redundant /// to the information in the `Pool`. But the Map enables us to easily /// check if a candidate is already in the pool, without having to /// iterate over the entire pool (the `Pool` is not sorted by /// `T::AccountId`, but by `T::Score` instead). - CandidateExists get(candidate_exists): map T::AccountId => bool; + CandidateExists get(fn candidate_exists): map T::AccountId => bool; /// The current membership, stored as an ordered Vec. - Members get(members): Vec; + Members get(fn members): Vec; /// Size of the `Members` set. - MemberCount get(member_count) config(): u32; + MemberCount get(fn member_count) config(): u32; } add_extra_genesis { config(members): Vec; diff --git a/srml/session/src/historical.rs b/srml/session/src/historical.rs index 08e4a6ce31..d3fbc67b95 100644 --- a/srml/session/src/historical.rs +++ b/srml/session/src/historical.rs @@ -56,9 +56,9 @@ pub trait Trait: super::Trait { decl_storage! { trait Store for Module as Session { /// Mapping from historical session indices to session-data root hash and validator count. - HistoricalSessions get(historical_root): map SessionIndex => Option<(T::Hash, ValidatorCount)>; + HistoricalSessions get(fn historical_root): map SessionIndex => Option<(T::Hash, ValidatorCount)>; /// Queued full identifications for queued sessions whose validators have become obsolete. - CachedObsolete get(cached_obsolete): map SessionIndex + CachedObsolete get(fn cached_obsolete): map SessionIndex => Option>; /// The range of historical sessions we store. [first, last) StoredRange: Option<(SessionIndex, SessionIndex)>; diff --git a/srml/session/src/lib.rs b/srml/session/src/lib.rs index bb14b0d8f4..76cc6d0663 100644 --- a/srml/session/src/lib.rs +++ b/srml/session/src/lib.rs @@ -349,10 +349,10 @@ const DEDUP_KEY_PREFIX: &[u8] = b":session:keys"; decl_storage! { trait Store for Module as Session { /// The current set of validators. - Validators get(validators): Vec; + Validators get(fn validators): Vec; /// Current index of the session. - CurrentIndex get(current_index): SessionIndex; + CurrentIndex get(fn current_index): SessionIndex; /// True if the underlying economic identities or weighting behind the validators /// has changed in the queued validator set. @@ -360,12 +360,12 @@ decl_storage! { /// The queued keys for the next session. When the next session begins, these keys /// will be used to determine the validator's session keys. - QueuedKeys get(queued_keys): Vec<(T::ValidatorId, T::Keys)>; + QueuedKeys get(fn queued_keys): Vec<(T::ValidatorId, T::Keys)>; /// Indices of disabled validators. /// /// The set is cleared when `on_session_ending` returns a new set of identities. - DisabledValidators get(disabled_validators): Vec; + DisabledValidators get(fn disabled_validators): Vec; /// The next session keys for a validator. /// diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index 0a2f37ccc4..013aed2729 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -551,72 +551,72 @@ decl_storage! { trait Store for Module as Staking { /// The ideal number of staking participants. - pub ValidatorCount get(validator_count) config(): u32; + pub ValidatorCount get(fn validator_count) config(): u32; /// Minimum number of staking participants before emergency conditions are imposed. - pub MinimumValidatorCount get(minimum_validator_count) config(): + pub MinimumValidatorCount get(fn minimum_validator_count) config(): u32 = DEFAULT_MINIMUM_VALIDATOR_COUNT; /// Any validators that may never be slashed or forcibly kicked. It's a Vec since they're /// easy to initialize and the performance hit is minimal (we expect no more than four /// invulnerables) and restricted to testnets. - pub Invulnerables get(invulnerables) config(): Vec; + pub Invulnerables get(fn invulnerables) config(): Vec; /// Map from all locked "stash" accounts to the controller account. - pub Bonded get(bonded): map T::AccountId => Option; + pub Bonded get(fn bonded): map T::AccountId => Option; /// Map from all (unlocked) "controller" accounts to the info regarding the staking. - pub Ledger get(ledger): + pub Ledger get(fn ledger): map T::AccountId => Option>>; /// Where the reward payment should be made. Keyed by stash. - pub Payee get(payee): map T::AccountId => RewardDestination; + pub Payee get(fn payee): map T::AccountId => RewardDestination; /// The map from (wannabe) validator stash key to the preferences of that validator. - pub Validators get(validators): linked_map T::AccountId => ValidatorPrefs>; + pub Validators get(fn validators): linked_map T::AccountId => ValidatorPrefs>; /// The map from nominator stash key to the set of stash keys of all validators to nominate. - pub Nominators get(nominators): linked_map T::AccountId => Vec; + pub Nominators get(fn nominators): linked_map T::AccountId => Vec; /// Nominators for a particular account that is in action right now. You can't iterate /// through validators here, but you can find them in the Session module. /// /// This is keyed by the stash account. - pub Stakers get(stakers): map T::AccountId => Exposure>; + pub Stakers get(fn stakers): map T::AccountId => Exposure>; /// The currently elected validator set keyed by stash account ID. - pub CurrentElected get(current_elected): Vec; + pub CurrentElected get(fn current_elected): Vec; /// The current era index. - pub CurrentEra get(current_era) config(): EraIndex; + pub CurrentEra get(fn current_era) config(): EraIndex; /// The start of the current era. - pub CurrentEraStart get(current_era_start): MomentOf; + pub CurrentEraStart get(fn current_era_start): MomentOf; /// The session index at which the current era started. - pub CurrentEraStartSessionIndex get(current_era_start_session_index): SessionIndex; + pub CurrentEraStartSessionIndex get(fn current_era_start_session_index): SessionIndex; /// Rewards for the current era. Using indices of current elected set. - CurrentEraPointsEarned get(current_era_reward): EraPoints; + CurrentEraPointsEarned get(fn current_era_reward): EraPoints; /// The amount of balance actively at stake for each validator slot, currently. /// /// This is used to derive rewards and punishments. - pub SlotStake get(slot_stake) build(|config: &GenesisConfig| { + pub SlotStake get(fn slot_stake) build(|config: &GenesisConfig| { config.stakers.iter().map(|&(_, _, value, _)| value).min().unwrap_or_default() }): BalanceOf; /// True if the next session change will be a new era regardless of index. - pub ForceEra get(force_era) config(): Forcing; + pub ForceEra get(fn force_era) config(): Forcing; /// The percentage of the slash that is distributed to reporters. /// /// The rest of the slashed value is handled by the `Slash`. - pub SlashRewardFraction get(slash_reward_fraction) config(): Perbill; + pub SlashRewardFraction get(fn slash_reward_fraction) config(): Perbill; /// A mapping from still-bonded eras to the first session index of that era. BondedEras: Vec<(EraIndex, SessionIndex)>; /// All slashes that have occurred in a given era. - EraSlashJournal get(era_slash_journal): + EraSlashJournal get(fn era_slash_journal): map EraIndex => Vec>>; } add_extra_genesis { diff --git a/srml/sudo/src/lib.rs b/srml/sudo/src/lib.rs index c4e13eefe2..7801384abc 100644 --- a/srml/sudo/src/lib.rs +++ b/srml/sudo/src/lib.rs @@ -200,6 +200,6 @@ decl_event!( decl_storage! { trait Store for Module as Sudo { /// The `AccountId` of the sudo key. - Key get(key) config(): T::AccountId; + Key get(fn key) config(): T::AccountId; } } diff --git a/srml/support/procedural/src/lib.rs b/srml/support/procedural/src/lib.rs index 38d404712e..792f739f1c 100644 --- a/srml/support/procedural/src/lib.rs +++ b/srml/support/procedural/src/lib.rs @@ -33,7 +33,7 @@ use proc_macro::TokenStream; /// ```nocompile /// decl_storage! { /// trait Store for Module as Example { -/// Foo get(foo) config(): u32=12; +/// Foo get(fn foo) config(): u32=12; /// Bar: map u32 => u32; /// pub Zed build(|config| vec![(0, 0)]): linked_map u32 => u32; /// } @@ -120,11 +120,11 @@ use proc_macro::TokenStream; /// /// Basic storage can be extended as such: /// -/// `#vis #name get(#getter) config(#field_name) build(#closure): #type = #default;` +/// `#vis #name get(fn #getter) config(#field_name) build(#closure): #type = #default;` /// /// * `#vis`: Set the visibility of the structure. `pub` or nothing. /// * `#name`: Name of the storage item, used as a prefix in storage. -/// * [optional] `get(#getter)`: Implements the function #getter to `Module`. +/// * [optional] `get(fn #getter)`: Implements the function #getter to `Module`. /// * [optional] `config(#field_name)`: `field_name` is optional if get is set. /// Will include the item in `GenesisConfig`. /// * [optional] `build(#closure)`: Closure called with storage overlays. diff --git a/srml/support/procedural/src/storage/parse.rs b/srml/support/procedural/src/storage/parse.rs index 8464077ca2..53da5ae33e 100644 --- a/srml/support/procedural/src/storage/parse.rs +++ b/srml/support/procedural/src/storage/parse.rs @@ -113,11 +113,16 @@ struct DeclStorageLine { pub default_value: ext::Opt, } +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageGetterBody { + fn_keyword: Option, + ident: Ident, +} #[derive(Parse, ToTokens, Debug)] struct DeclStorageGetter { pub getter_keyword: keyword::get, - pub getfn: ext::Parens, + pub getfn: ext::Parens, } #[derive(Parse, ToTokens, Debug)] @@ -301,17 +306,17 @@ pub fn parse(input: syn::parse::ParseStream) -> syn::Result as Example { - pub Data get(data) build(|_| vec![(15u32, 42u64)]): linked_map hasher(twox_64_concat) u32 => u64; + pub Data get(fn data) build(|_| vec![(15u32, 42u64)]): linked_map hasher(twox_64_concat) u32 => u64; pub OptionLinkedMap: linked_map u32 => Option; - pub GenericData get(generic_data): linked_map hasher(twox_128) T::BlockNumber => T::BlockNumber; - pub GenericData2 get(generic_data2): linked_map T::BlockNumber => Option; + pub GenericData get(fn generic_data): linked_map hasher(twox_128) T::BlockNumber => T::BlockNumber; + pub GenericData2 get(fn generic_data2): linked_map T::BlockNumber => Option; + pub GetterNoFnKeyword get(no_fn): Option; pub DataDM config(test_config) build(|_| vec![(15u32, 16u32, 42u64)]): double_map hasher(twox_64_concat) u32, blake2_256(u32) => u64; @@ -516,6 +517,15 @@ mod tests { ), documentation: DecodeDifferent::Encode(&[]), }, + StorageEntryMetadata { + name: DecodeDifferent::Encode("GetterNoFnKeyword"), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::Plain(DecodeDifferent::Encode("u32")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructGetterNoFnKeyword(PhantomData::)) + ), + documentation: DecodeDifferent::Encode(&[]), + }, StorageEntryMetadata { name: DecodeDifferent::Encode("DataDM"), modifier: StorageEntryModifier::Default, diff --git a/srml/support/src/storage/storage_items.rs b/srml/support/src/storage/storage_items.rs index 1854d703c0..1edf9c03db 100644 --- a/srml/support/src/storage/storage_items.rs +++ b/srml/support/src/storage/storage_items.rs @@ -307,15 +307,15 @@ mod tests { // getters: pub / $default // we need at least one type which uses T, otherwise GenesisConfig will complain. - GETU32 get(u32_getter): T::Origin; - pub PUBGETU32 get(pub_u32_getter) build(|config: &GenesisConfig| config.u32_getter_with_config): u32; - GETU32WITHCONFIG get(u32_getter_with_config) config(): u32; - pub PUBGETU32WITHCONFIG get(pub_u32_getter_with_config) config(): u32; - GETU32MYDEF get(u32_getter_mydef): Option; - pub PUBGETU32MYDEF get(pub_u32_getter_mydef) config(): u32 = 3; - GETU32WITHCONFIGMYDEF get(u32_getter_with_config_mydef) config(): u32 = 2; - pub PUBGETU32WITHCONFIGMYDEF get(pub_u32_getter_with_config_mydef) config(): u32 = 1; - PUBGETU32WITHCONFIGMYDEFOPT get(pub_u32_getter_with_config_mydef_opt) config(): Option; + GETU32 get(fn u32_getter): T::Origin; + pub PUBGETU32 get(fn pub_u32_getter) build(|config: &GenesisConfig| config.u32_getter_with_config): u32; + GETU32WITHCONFIG get(fn u32_getter_with_config) config(): u32; + pub PUBGETU32WITHCONFIG get(fn pub_u32_getter_with_config) config(): u32; + GETU32MYDEF get(fn u32_getter_mydef): Option; + pub PUBGETU32MYDEF get(fn pub_u32_getter_mydef) config(): u32 = 3; + GETU32WITHCONFIGMYDEF get(fn u32_getter_with_config_mydef) config(): u32 = 2; + pub PUBGETU32WITHCONFIGMYDEF get(fn pub_u32_getter_with_config_mydef) config(): u32 = 1; + PUBGETU32WITHCONFIGMYDEFOPT get(fn pub_u32_getter_with_config_mydef_opt) config(): Option; // map non-getters: pub / $default MAPU32 : map u32 => Option; @@ -324,17 +324,17 @@ mod tests { pub PUBMAPU32MYDEF : map u32 => Option; // map getters: pub / $default - GETMAPU32 get(map_u32_getter): map u32 => String; - pub PUBGETMAPU32 get(pub_map_u32_getter): map u32 => String; + GETMAPU32 get(fn map_u32_getter): map u32 => String; + pub PUBGETMAPU32 get(fn pub_map_u32_getter): map u32 => String; - GETMAPU32MYDEF get(map_u32_getter_mydef): map u32 => String = "map".into(); - pub PUBGETMAPU32MYDEF get(pub_map_u32_getter_mydef): map u32 => String = "pubmap".into(); + GETMAPU32MYDEF get(fn map_u32_getter_mydef): map u32 => String = "map".into(); + pub PUBGETMAPU32MYDEF get(fn pub_map_u32_getter_mydef): map u32 => String = "pubmap".into(); // linked map LINKEDMAPU32 : linked_map u32 => Option; pub PUBLINKEDMAPU32MYDEF : linked_map u32 => Option; - GETLINKEDMAPU32 get(linked_map_u32_getter): linked_map u32 => String; - pub PUBGETLINKEDMAPU32MYDEF get(pub_linked_map_u32_getter_mydef): linked_map u32 => String = "pubmap".into(); + GETLINKEDMAPU32 get(fn linked_map_u32_getter): linked_map u32 => String; + pub PUBGETLINKEDMAPU32MYDEF get(fn pub_linked_map_u32_getter_mydef): linked_map u32 => String = "pubmap".into(); COMPLEXTYPE1: ::std::vec::Vec<::Origin>; COMPLEXTYPE2: (Vec)>>, u32); @@ -741,7 +741,7 @@ mod test3 { } crate::decl_storage! { trait Store for Module as Test { - Foo get(foo) config(initial_foo): u32; + Foo get(fn foo) config(initial_foo): u32; } } diff --git a/srml/support/test/tests/final_keys.rs b/srml/support/test/tests/final_keys.rs index 04b243ae7c..44a6b540a7 100644 --- a/srml/support/test/tests/final_keys.rs +++ b/srml/support/test/tests/final_keys.rs @@ -44,8 +44,8 @@ mod no_instance { pub DoubleMap: double_map u32, blake2_256(u32) => u32; pub DoubleMap2: double_map hasher(twox_128) u32, blake2_128(u32) => u32; - pub TestGenericValue get(test_generic_value) config(): Option; - pub TestGenericDoubleMap get(foo2) config(test_generic_double_map): + pub TestGenericValue get(fn test_generic_value) config(): Option; + pub TestGenericDoubleMap get(fn foo2) config(test_generic_double_map): double_map u32, blake2_256(T::BlockNumber) => Option; } } @@ -74,8 +74,8 @@ mod instance { pub DoubleMap: double_map u32, blake2_256(u32) => u32; pub DoubleMap2: double_map hasher(twox_128) u32, blake2_128(u32) => u32; - pub TestGenericValue get(test_generic_value) config(): Option; - pub TestGenericDoubleMap get(foo2) config(test_generic_double_map): + pub TestGenericValue get(fn test_generic_value) config(): Option; + pub TestGenericDoubleMap get(fn foo2) config(test_generic_double_map): double_map u32, blake2_256(T::BlockNumber) => Option; } add_extra_genesis { diff --git a/srml/support/test/tests/issue2219.rs b/srml/support/test/tests/issue2219.rs index 28bd9463ff..72e0bc8caf 100644 --- a/srml/support/test/tests/issue2219.rs +++ b/srml/support/test/tests/issue2219.rs @@ -102,7 +102,7 @@ mod module { support::decl_storage! { trait Store for Module as Actors { /// requirements to enter and maintain status in roles - pub Parameters get(parameters) build(|config: &GenesisConfig| { + pub Parameters get(fn parameters) build(|config: &GenesisConfig| { if config.enable_storage_role { let storage_params: RoleParameters = Default::default(); vec![(Role::Storage, storage_params)] @@ -112,7 +112,7 @@ mod module { }): map Role => Option>; /// the roles members can enter into - pub AvailableRoles get(available_roles) build(|config: &GenesisConfig| { + pub AvailableRoles get(fn available_roles) build(|config: &GenesisConfig| { if config.enable_storage_role { vec![(Role::Storage)] } else { @@ -121,13 +121,13 @@ mod module { }): Vec; /// Actors list - pub ActorAccountIds get(actor_account_ids) : Vec; + pub ActorAccountIds get(fn actor_account_ids) : Vec; /// actor accounts associated with a role - pub AccountIdsByRole get(account_ids_by_role) : map Role => Vec; + pub AccountIdsByRole get(fn account_ids_by_role) : map Role => Vec; /// tokens locked until given block number - pub Bondage get(bondage) : map T::AccountId => T::BlockNumber; + pub Bondage get(fn bondage) : map T::AccountId => T::BlockNumber; /// First step before enter a role is registering intent with a new account/key. /// This is done by sending a role_entry_request() from the new account. @@ -135,10 +135,10 @@ mod module { /// The account making the request will be bonded and must have /// sufficient balance to cover the minimum stake for the role. /// Bonding only occurs after successful entry into a role. - pub RoleEntryRequests get(role_entry_requests) : Requests; + pub RoleEntryRequests get(fn role_entry_requests) : Requests; /// Entry request expires after this number of blocks - pub RequestLifeTime get(request_life_time) config(request_life_time) : u64 = 0; + pub RequestLifeTime get(fn request_life_time) config(request_life_time) : u64 = 0; } add_extra_genesis { config(enable_storage_role): bool; diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index 76cbe7cbab..ed9dee2373 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -366,7 +366,7 @@ type EventIndex = u32; decl_storage! { trait Store for Module as System { /// Extrinsics nonce for accounts. - pub AccountNonce get(account_nonce): map T::AccountId => T::Index; + pub AccountNonce get(fn account_nonce): map T::AccountId => T::Index; /// Total extrinsics count for the current block. ExtrinsicCount: Option; /// Total weight for all extrinsics put together, for the current block. @@ -374,21 +374,21 @@ decl_storage! { /// Total length (in bytes) for all extrinsics put together, for the current block. AllExtrinsicsLen: Option; /// Map of block numbers to block hashes. - pub BlockHash get(block_hash) build(|_| vec![(T::BlockNumber::zero(), hash69())]): map T::BlockNumber => T::Hash; + pub BlockHash get(fn block_hash) build(|_| vec![(T::BlockNumber::zero(), hash69())]): map T::BlockNumber => T::Hash; /// Extrinsics data for the current block (maps an extrinsic's index to its data). - ExtrinsicData get(extrinsic_data): map u32 => Vec; + ExtrinsicData get(fn extrinsic_data): map u32 => Vec; /// The current block number being processed. Set by `execute_block`. - Number get(block_number) build(|_| 1.into()): T::BlockNumber; + Number get(fn block_number) build(|_| 1.into()): T::BlockNumber; /// Hash of the previous block. - ParentHash get(parent_hash) build(|_| hash69()): T::Hash; + ParentHash get(fn parent_hash) build(|_| hash69()): T::Hash; /// Extrinsics root of the current block, also part of the block header. - ExtrinsicsRoot get(extrinsics_root): T::Hash; + ExtrinsicsRoot get(fn extrinsics_root): T::Hash; /// Digest of the current block, also part of the block header. - Digest get(digest): DigestOf; + Digest get(fn digest): DigestOf; /// Events deposited for the current block. - Events get(events): Vec>; + Events get(fn events): Vec>; /// The number of events in the `Events` list. - EventCount get(event_count): EventIndex; + EventCount get(fn event_count): EventIndex; // TODO: https://github.com/paritytech/substrate/issues/2553 // Possibly, we can improve it by using something like: @@ -408,7 +408,7 @@ decl_storage! { /// The value has the type `(T::BlockNumber, EventIndex)` because if we used only just /// the `EventIndex` then in case if the topic has the same contents on the next block /// no notification will be triggered thus the event might be lost. - EventTopics get(event_topics): double_map hasher(blake2_256) (), blake2_256(T::Hash) + EventTopics get(fn event_topics): double_map hasher(blake2_256) (), blake2_256(T::Hash) => Vec<(T::BlockNumber, EventIndex)>; } add_extra_genesis { diff --git a/srml/timestamp/src/lib.rs b/srml/timestamp/src/lib.rs index 35546575c5..a48190da9a 100644 --- a/srml/timestamp/src/lib.rs +++ b/srml/timestamp/src/lib.rs @@ -244,7 +244,7 @@ decl_module! { decl_storage! { trait Store for Module as Timestamp { /// Current time for the current block. - pub Now get(now) build(|_| 0.into()): T::Moment; + pub Now get(fn now) build(|_| 0.into()): T::Moment; /// Did the timestamp get updated in this block? DidUpdate: bool; diff --git a/srml/transaction-payment/src/lib.rs b/srml/transaction-payment/src/lib.rs index f2e815fcd4..b662f55689 100644 --- a/srml/transaction-payment/src/lib.rs +++ b/srml/transaction-payment/src/lib.rs @@ -76,7 +76,7 @@ pub trait Trait: system::Trait { decl_storage! { trait Store for Module as Balances { - NextFeeMultiplier get(next_fee_multiplier): Multiplier = Multiplier::from_parts(0); + NextFeeMultiplier get(fn next_fee_multiplier): Multiplier = Multiplier::from_parts(0); } } diff --git a/srml/treasury/src/lib.rs b/srml/treasury/src/lib.rs index 936e4bd93d..67ee456139 100644 --- a/srml/treasury/src/lib.rs +++ b/srml/treasury/src/lib.rs @@ -225,13 +225,13 @@ pub struct Proposal { decl_storage! { trait Store for Module as Treasury { /// Number of proposals that have been made. - ProposalCount get(proposal_count): ProposalIndex; + ProposalCount get(fn proposal_count): ProposalIndex; /// Proposals that have been made. - Proposals get(proposals): map ProposalIndex => Option>>; + Proposals get(fn proposals): map ProposalIndex => Option>>; /// Proposal indices that have been approved but not yet awarded. - Approvals get(approvals): Vec; + Approvals get(fn approvals): Vec; } } -- GitLab From a0e47d13b570eeab3b7c7747569bec032627dcf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 22 Oct 2019 10:29:44 +0200 Subject: [PATCH 247/275] Improve logging for offchain transaction submission. (#3871) --- core/offchain/src/api.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/offchain/src/api.rs b/core/offchain/src/api.rs index d17a892d97..d4301d22ed 100644 --- a/core/offchain/src/api.rs +++ b/core/offchain/src/api.rs @@ -317,12 +317,12 @@ impl AsyncApi { }, }; - info!("Submitting to the pool: {:?} (isSigned: {:?})", xt, xt.is_signed()); + info!("Submitting transaction to the pool: {:?} (isSigned: {:?})", xt, xt.is_signed()); future::Either::Right(self.transaction_pool .submit_one(&self.at, xt.clone()) .map(|result| match result { Ok(hash) => { debug!("[{:?}] Offchain transaction added to the pool.", hash); }, - Err(e) => { debug!("Couldn't submit transaction: {:?}", e); }, + Err(e) => { warn!("Couldn't submit offchain transaction: {:?}", e); }, })) } } -- GitLab From 2e1d8310f58d6abc12e0f9ed223acbc560d6fb3a Mon Sep 17 00:00:00 2001 From: yjh Date: Tue, 22 Oct 2019 17:37:52 +0800 Subject: [PATCH 248/275] refactor map macro for more general use (#3850) * refactor map macro for more general use Signed-off-by: yjhmelody <465402634@qq.com> * use $(,)? Signed-off-by: yjhmelody <465402634@qq.com> * Update core/primitives/src/lib.rs Co-Authored-By: thiolliere * Update core/primitives/src/lib.rs Co-Authored-By: thiolliere --- core/primitives/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/primitives/src/lib.rs b/core/primitives/src/lib.rs index c2d23050f9..0a1f80aaa9 100644 --- a/core/primitives/src/lib.rs +++ b/core/primitives/src/lib.rs @@ -26,9 +26,9 @@ /// Can be used to create a `HashMap`. #[macro_export] macro_rules! map { - ($( $name:expr => $value:expr ),*) => ( + ($( $name:expr => $value:expr ),* $(,)? ) => ( vec![ $( ( $name, $value ) ),* ].into_iter().collect() - ) + ); } use rstd::prelude::*; -- GitLab From a61c0eb891a4942d0fa96333aa57472940fb181b Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Tue, 22 Oct 2019 13:02:20 +0300 Subject: [PATCH 249/275] fix ambiguity about start in doc (#3864) --- core/sr-sandbox/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/sr-sandbox/src/lib.rs b/core/sr-sandbox/src/lib.rs index e814a51ace..b04524b241 100755 --- a/core/sr-sandbox/src/lib.rs +++ b/core/sr-sandbox/src/lib.rs @@ -171,7 +171,7 @@ pub struct Instance { impl Instance { /// Instantiate a module with the given [`EnvironmentDefinitionBuilder`]. It will - /// run the `start` function with the given `state`. + /// run the `start` function (if it is present in the module) with the given `state`. /// /// Returns `Err(Error::Module)` if this module can't be instantiated with the given /// environment. If execution of `start` function generated a trap, then `Err(Error::Execution)` will -- GitLab From 27f741e11c2ccb3bd78852d5c3445a7055f48c5c Mon Sep 17 00:00:00 2001 From: Ashley Date: Tue, 22 Oct 2019 12:24:58 +0100 Subject: [PATCH 250/275] Remove sr-arithmetic/fuzzer from workspace to fix windows builds (#3872) * Remove sr-arithmetic/fuzzer from workspace to fix windows builds * Remove sr-arithmetic/fuzzer from check_runtime.sh --- Cargo.lock | 38 --- Cargo.toml | 1 - core/sr-arithmetic/fuzzer/Cargo.lock | 465 +++++++++++++++++++++++++++ core/sr-arithmetic/fuzzer/Cargo.toml | 2 + scripts/gitlab/check_runtime.sh | 2 +- 5 files changed, 468 insertions(+), 40 deletions(-) create mode 100644 core/sr-arithmetic/fuzzer/Cargo.lock diff --git a/Cargo.lock b/Cargo.lock index d77ba65cbd..6df1104377 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -92,11 +92,6 @@ dependencies = [ "xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "arbitrary" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "arc-swap" version = "0.3.11" @@ -1279,16 +1274,6 @@ dependencies = [ "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "honggfuzz" -version = "0.5.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arbitrary 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "http" version = "0.1.18" @@ -2191,15 +2176,6 @@ dependencies = [ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "memmap" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "memoffset" version = "0.5.1" @@ -3878,17 +3854,6 @@ dependencies = [ "sr-std 2.0.0", ] -[[package]] -name = "sr-arithmetic-fuzzer" -version = "2.0.0" -dependencies = [ - "honggfuzz 0.5.45 (registry+https://github.com/rust-lang/crates.io-index)", - "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-arithmetic 2.0.0", -] - [[package]] name = "sr-io" version = "2.0.0" @@ -6792,7 +6757,6 @@ dependencies = [ "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" "checksum app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e73a24bad9bd6a94d6395382a6c69fe071708ae4409f763c5475e14ee896313d" -"checksum arbitrary 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "64cf76cb6e2222ed0ea86b2b0ee2f71c96ec6edd5af42e84d59160e91b836ec4" "checksum arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "bc4662175ead9cd84451d5c35070517777949a2ed84551764129cedb88384841" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" "checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" @@ -6930,7 +6894,6 @@ dependencies = [ "checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" "checksum hmac-drbg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4fe727d41d2eec0a6574d887914347e5ff96a3b87177817e2a9820c5c87fecc2" "checksum hmac-drbg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" -"checksum honggfuzz 0.5.45 (registry+https://github.com/rust-lang/crates.io-index)" = "24c27b4aa3049d6d10d8e33d52c9d03ca9aec18f8a449b246f8c4a5b0c10fb34" "checksum http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "372bcb56f939e449117fb0869c2e8fd8753a8223d92a172c6e808cf123a5b6e4" "checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" @@ -7007,7 +6970,6 @@ dependencies = [ "checksum malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "35adee9ed962cf7d07d62cb58bc45029f3227f5b5b86246caa8632f06c187bc3" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" -"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" "checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f" "checksum memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ef49315991403ba5fa225a70399df5e115f57b274cb0b1b4bcd6e734fa5bd783" "checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" diff --git a/Cargo.toml b/Cargo.toml index 9d01fabc1e..8d3d04c4d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,7 +54,6 @@ members = [ "core/session", "core/sr-api-macros", "core/sr-arithmetic", - "core/sr-arithmetic/fuzzer", "core/sr-io", "core/sr-primitives", "core/sr-staking-primitives", diff --git a/core/sr-arithmetic/fuzzer/Cargo.lock b/core/sr-arithmetic/fuzzer/Cargo.lock new file mode 100644 index 0000000000..f6ce6f1d47 --- /dev/null +++ b/core/sr-arithmetic/fuzzer/Cargo.lock @@ -0,0 +1,465 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "arbitrary" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "arrayvec" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "autocfg" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bitvec" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "byte-slice-cast" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "byteorder" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "c2-chacha" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "fixed-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "getrandom" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "honggfuzz" +version = "0.5.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arbitrary 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "impl-codec" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "integer-sqrt" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.65" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memmap" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "num-bigint" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-integer" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parity-scale-codec" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "bitvec 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-slice-cast 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec-derive 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "primitive-types" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fixed-hash 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-codec 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "uint 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro2" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_chacha" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc-hex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_derive" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sr-arithmetic" +version = "2.0.0" +dependencies = [ + "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-std 2.0.0", +] + +[[package]] +name = "sr-arithmetic-fuzzer" +version = "2.0.0" +dependencies = [ + "honggfuzz 0.5.45 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-arithmetic 2.0.0", +] + +[[package]] +name = "sr-std" +version = "2.0.0" +dependencies = [ + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "static_assertions" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "syn" +version = "0.15.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "toml" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "uint" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "wasi" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum arbitrary 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "64cf76cb6e2222ed0ea86b2b0ee2f71c96ec6edd5af42e84d59160e91b836ec4" +"checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" +"checksum bitvec 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9633b74910e1870f50f5af189b08487195cdb83c0e27a71d6f64d5e09dd0538b" +"checksum byte-slice-cast 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7cbcbf18128ec71d8d4a0d054461ec59fff5b75b7d10a4c9b7c7cb1a379c3e77" +"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" +"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" +"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +"checksum crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +"checksum fixed-hash 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6357b15872f8126e4ea7cf79d579473f132ccd2de239494ad1bf4aa892faea68" +"checksum getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571" +"checksum honggfuzz 0.5.45 (registry+https://github.com/rust-lang/crates.io-index)" = "24c27b4aa3049d6d10d8e33d52c9d03ca9aec18f8a449b246f8c4a5b0c10fb34" +"checksum impl-codec 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3fa0086251524c50fd53b32e7b05eb6d79e2f97221eaf0c53c0ca9c3096f21d3" +"checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" +"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +"checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8" +"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" +"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" +"checksum num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9c3f34cdd24f334cb265d9bf8bfa8a241920d026916785747a92f0e55541a1a" +"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" +"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" +"checksum parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "001fbbb956d8593f321c7a784f64d16b2c99b2657823976eea729006ad2c3668" +"checksum parity-scale-codec-derive 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42af752f59119656fa3cb31e8852ed24e895b968c0bdb41847da7f0cea6d155f" +"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" +"checksum primitive-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97b5a08dda18910f056e5c2060c034e77cab18e0bd7d895e44f03207af4c71d5" +"checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" +"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +"checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" +"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" +"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" +"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" +"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +"checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8" +"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +"checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd" +"checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e" +"checksum static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5" +"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf" +"checksum toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724" +"checksum uint 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8f0f47ed099f0db671ce82c66548c5de012e3c0cba3963514d1db15c7588701" +"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" +"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/core/sr-arithmetic/fuzzer/Cargo.toml b/core/sr-arithmetic/fuzzer/Cargo.toml index 8838e60436..482905c435 100644 --- a/core/sr-arithmetic/fuzzer/Cargo.toml +++ b/core/sr-arithmetic/fuzzer/Cargo.toml @@ -11,6 +11,8 @@ primitive-types = "0.6" num-bigint = "0.2" num-traits = "0.2" +[workspace] + [[bin]] name = "biguint" path = "src/biguint.rs" diff --git a/scripts/gitlab/check_runtime.sh b/scripts/gitlab/check_runtime.sh index 725c5077c5..cd988718d0 100755 --- a/scripts/gitlab/check_runtime.sh +++ b/scripts/gitlab/check_runtime.sh @@ -32,7 +32,7 @@ github_label () { # check if the wasm sources changed if ! git diff --name-only origin/master...${CI_COMMIT_SHA} \ - | grep -q -e '^node/src/runtime' -e '^srml/' -e '^core/sr-' + | grep -q -e '^node/src/runtime' -e '^srml/' -e '^core/sr-' | grep -v -e '^core/sr-arithmetic/fuzzer' then cat <<-EOT -- GitLab From a31c01b398d958ccf0a24d8c1c11fb073df66212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 22 Oct 2019 14:13:44 +0200 Subject: [PATCH 251/275] Runtime logging. (#3821) * Implement Printable for tuples. * Add debugging function. * Add debug 1. * Implement for everything. * RuntimeDebug derive. * Introduce RuntimeDebug. * Add some dummy logging. * Replace RuntimeDebug with Debug. * Revert "Replace RuntimeDebug with Debug." This reverts commit bc47070a8cb30241b2b590b2fa29fd195088162f. * Working on Debug for all. * Fix bounds. * Add debug utils. * Implement runtime logging. * Add some docs and clean up. * Clean up derives. * Fix custom derive impl. * Bump runtime. * Fix long lines. * Fix doc test. * Use CARGO_CFG_STD. * Revert "Use CARGO_CFG_STD." This reverts commit ea429566de18ed0fa052571b359eb9826a64a9f4. * Use parse_macro_input * Update lockfile. * Apply review suggestions. * Remove stray re-export. * Add no-std impl. * Update lockfile. --- Cargo.lock | 15 ++ core/application-crypto/src/lib.rs | 16 +- core/application-crypto/src/traits.rs | 30 +-- .../authority-discovery/primitives/src/lib.rs | 9 +- core/consensus/babe/primitives/src/digest.rs | 3 +- core/consensus/babe/primitives/src/lib.rs | 8 +- core/executor/src/host_interface.rs | 16 ++ core/finality-grandpa/primitives/src/lib.rs | 10 +- core/phragmen/src/lib.rs | 15 +- core/primitives/Cargo.toml | 6 +- core/primitives/debug-derive/Cargo.toml | 19 ++ core/primitives/debug-derive/src/impls.rs | 217 ++++++++++++++++++ core/primitives/debug-derive/src/lib.rs | 44 ++++ core/primitives/debug-derive/tests/tests.rs | 63 +++++ core/primitives/src/crypto.rs | 4 +- core/primitives/src/ed25519.rs | 22 +- core/primitives/src/hexdisplay.rs | 8 +- core/primitives/src/lib.rs | 65 +++++- core/primitives/src/offchain.rs | 29 +-- core/primitives/src/sandbox.rs | 12 +- core/primitives/src/sr25519.rs | 25 +- core/primitives/storage/Cargo.toml | 1 + core/primitives/storage/src/lib.rs | 12 +- core/sr-arithmetic/Cargo.toml | 12 +- core/sr-arithmetic/src/biguint.rs | 8 +- core/sr-arithmetic/src/fixed64.rs | 9 +- core/sr-arithmetic/src/per_things.rs | 9 +- core/sr-arithmetic/src/rational128.rs | 4 +- core/sr-io/Cargo.toml | 6 +- core/sr-io/src/lib.rs | 15 ++ core/sr-io/with_std.rs | 16 ++ core/sr-io/without_std.rs | 24 ++ core/sr-primitives/Cargo.toml | 12 +- core/sr-primitives/src/curve.rs | 3 +- core/sr-primitives/src/generic/block.rs | 13 +- .../src/generic/checked_extrinsic.rs | 3 +- core/sr-primitives/src/generic/digest.rs | 11 +- core/sr-primitives/src/generic/era.rs | 4 +- core/sr-primitives/src/generic/header.rs | 26 +-- .../src/generic/unchecked_extrinsic.rs | 5 +- core/sr-primitives/src/lib.rs | 34 +-- core/sr-primitives/src/offchain/http.rs | 24 +- core/sr-primitives/src/traits.rs | 83 ++++--- .../sr-primitives/src/transaction_validity.rs | 16 +- core/sr-primitives/src/weights.rs | 11 +- core/sr-sandbox/src/lib.rs | 2 +- core/sr-staking-primitives/src/offence.rs | 3 +- core/sr-std/without_std.rs | 1 + core/sr-version/src/lib.rs | 6 +- core/test-runtime/src/lib.rs | 10 +- core/trie/src/node_header.rs | 2 +- node/primitives/src/lib.rs | 1 - node/runtime/src/lib.rs | 2 +- srml/authorship/src/lib.rs | 4 +- srml/balances/src/lib.rs | 23 +- srml/collective/src/lib.rs | 7 +- srml/contracts/rpc/runtime-api/Cargo.toml | 2 + srml/contracts/rpc/runtime-api/src/lib.rs | 5 +- srml/contracts/src/exec.rs | 5 +- srml/contracts/src/lib.rs | 36 +-- srml/democracy/src/lib.rs | 10 +- srml/democracy/src/vote_threshold.rs | 4 +- srml/elections/src/lib.rs | 11 +- srml/example/src/lib.rs | 3 +- srml/generic-asset/src/lib.rs | 38 ++- srml/im-online/src/lib.rs | 31 ++- srml/indices/src/address.rs | 4 +- srml/metadata/src/lib.rs | 87 ++++--- srml/scored-pool/src/lib.rs | 10 +- srml/staking/src/lib.rs | 29 +-- srml/support/Cargo.toml | 1 + .../procedural/src/storage/instance_trait.rs | 8 +- srml/support/src/debug.rs | 209 +++++++++++++++++ srml/support/src/dispatch.rs | 29 +-- srml/support/src/error.rs | 3 +- srml/support/src/event.rs | 25 +- srml/support/src/lib.rs | 7 +- srml/support/src/origin.rs | 4 +- srml/support/src/runtime.rs | 3 +- srml/support/src/traits.rs | 8 +- srml/support/test/tests/instance.rs | 6 +- srml/support/test/tests/system.rs | 3 +- srml/system/src/lib.rs | 82 ++++--- srml/timestamp/src/lib.rs | 4 +- srml/transaction-payment/src/lib.rs | 6 +- srml/treasury/src/lib.rs | 4 +- 86 files changed, 1266 insertions(+), 469 deletions(-) create mode 100644 core/primitives/debug-derive/Cargo.toml create mode 100644 core/primitives/debug-derive/src/impls.rs create mode 100644 core/primitives/debug-derive/src/lib.rs create mode 100644 core/primitives/debug-derive/tests/tests.rs create mode 100644 srml/support/src/debug.rs diff --git a/Cargo.lock b/Cargo.lock index 6df1104377..0ad4317dd9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3852,6 +3852,7 @@ dependencies = [ "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", + "substrate-debug-derive 2.0.0", ] [[package]] @@ -3860,6 +3861,7 @@ version = "2.0.0" dependencies = [ "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "libsecp256k1 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", @@ -4102,6 +4104,7 @@ version = "2.0.0" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 2.0.0", "sr-std 2.0.0", "substrate-client 2.0.0", ] @@ -4416,6 +4419,7 @@ version = "2.0.0" dependencies = [ "bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5088,6 +5092,15 @@ dependencies = [ "substrate-primitives 2.0.0", ] +[[package]] +name = "substrate-debug-derive" +version = "2.0.0" +dependencies = [ + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "substrate-executor" version = "2.0.0" @@ -5367,6 +5380,7 @@ dependencies = [ "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", "substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-debug-derive 2.0.0", "substrate-externalities 2.0.0", "substrate-primitives-storage 2.0.0", "substrate-serializer 2.0.0", @@ -5383,6 +5397,7 @@ dependencies = [ "impl-serde 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", + "substrate-debug-derive 2.0.0", ] [[package]] diff --git a/core/application-crypto/src/lib.rs b/core/application-crypto/src/lib.rs index e3366a461a..16eda53238 100644 --- a/core/application-crypto/src/lib.rs +++ b/core/application-crypto/src/lib.rs @@ -21,7 +21,7 @@ #![cfg_attr(not(feature = "std"), no_std)] #[doc(hidden)] -pub use primitives::{self, crypto::{CryptoType, Public, Derive, IsWrappedBy, Wraps}}; +pub use primitives::{self, crypto::{CryptoType, Public, Derive, IsWrappedBy, Wraps}, RuntimeDebug}; #[doc(hidden)] #[cfg(feature = "std")] pub use primitives::crypto::{SecretStringError, DeriveJunction, Ss58Codec, Pair}; @@ -139,10 +139,12 @@ macro_rules! app_crypto { $crate::wrap!{ /// A generic `AppPublic` wrapper type over $public crypto; this has no specific App. #[derive( - Clone, Default, Eq, PartialEq, Ord, PartialOrd, $crate::codec::Encode, + Clone, Default, Eq, PartialEq, Ord, PartialOrd, + $crate::codec::Encode, $crate::codec::Decode, + $crate::RuntimeDebug, )] - #[cfg_attr(feature = "std", derive(Debug, Hash))] + #[cfg_attr(feature = "std", derive(Hash))] pub struct Public($public); } @@ -239,8 +241,12 @@ macro_rules! app_crypto { $crate::wrap! { /// A generic `AppPublic` wrapper type over $public crypto; this has no specific App. - #[derive(Clone, Default, Eq, PartialEq, $crate::codec::Encode, $crate::codec::Decode)] - #[cfg_attr(feature = "std", derive(Debug, Hash))] + #[derive(Clone, Default, Eq, PartialEq, + $crate::codec::Encode, + $crate::codec::Decode, + $crate::RuntimeDebug, + )] + #[cfg_attr(feature = "std", derive(Hash))] pub struct Signature($sig); } diff --git a/core/application-crypto/src/traits.rs b/core/application-crypto/src/traits.rs index aad076bd90..49d3a44aee 100644 --- a/core/application-crypto/src/traits.rs +++ b/core/application-crypto/src/traits.rs @@ -14,10 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use primitives::crypto::{KeyTypeId, CryptoType, IsWrappedBy, Public}; #[cfg(feature = "std")] use primitives::crypto::Pair; + use codec::Codec; +use primitives::crypto::{KeyTypeId, CryptoType, IsWrappedBy, Public}; +use rstd::fmt::Debug; /// An application-specific key. pub trait AppKey: 'static + Send + Sync + Sized + CryptoType + Clone { @@ -38,23 +40,25 @@ pub trait AppKey: 'static + Send + Sync + Sized + CryptoType + Clone { const ID: KeyTypeId; } -/// Type which implements Debug and Hash in std, not when no-std (std variant). +/// Type which implements Hash in std, not when no-std (std variant). #[cfg(feature = "std")] -pub trait MaybeDebugHash: std::fmt::Debug + std::hash::Hash {} +pub trait MaybeHash: std::hash::Hash {} #[cfg(feature = "std")] -impl MaybeDebugHash for T {} +impl MaybeHash for T {} -/// Type which implements Debug and Hash in std, not when no-std (no-std variant). +/// Type which implements Hash in std, not when no-std (no-std variant). #[cfg(not(feature = "std"))] -pub trait MaybeDebugHash {} +pub trait MaybeHash {} #[cfg(not(feature = "std"))] -impl MaybeDebugHash for T {} +impl MaybeHash for T {} /// A application's public key. -pub trait AppPublic: AppKey + Public + Ord + PartialOrd + Eq + PartialEq + MaybeDebugHash + codec::Codec { +pub trait AppPublic: + AppKey + Public + Ord + PartialOrd + Eq + PartialEq + Debug + MaybeHash + codec::Codec +{ /// The wrapped type which is just a plain instance of `Public`. type Generic: - IsWrappedBy + Public + Ord + PartialOrd + Eq + PartialEq + MaybeDebugHash + codec::Codec; + IsWrappedBy + Public + Ord + PartialOrd + Eq + PartialEq + Debug + MaybeHash + codec::Codec; } /// A application's key pair. @@ -65,15 +69,15 @@ pub trait AppPair: AppKey + Pair::Public> { } /// A application's signature. -pub trait AppSignature: AppKey + Eq + PartialEq + MaybeDebugHash { +pub trait AppSignature: AppKey + Eq + PartialEq + Debug + MaybeHash { /// The wrapped type which is just a plain instance of `Signature`. - type Generic: IsWrappedBy + Eq + PartialEq + MaybeDebugHash; + type Generic: IsWrappedBy + Eq + PartialEq + Debug + MaybeHash; } /// A runtime interface for a public key. pub trait RuntimePublic: Sized { /// The signature that will be generated when signing with the corresponding private key. - type Signature: Codec + MaybeDebugHash + Eq + PartialEq + Clone; + type Signature: Codec + Debug + MaybeHash + Eq + PartialEq + Clone; /// Returns all public keys for the given key type in the keystore. fn all(key_type: KeyTypeId) -> crate::Vec; @@ -101,7 +105,7 @@ pub trait RuntimeAppPublic: Sized { const ID: KeyTypeId; /// The signature that will be generated when signing with the corresponding private key. - type Signature: Codec + MaybeDebugHash + Eq + PartialEq + Clone; + type Signature: Codec + Debug + MaybeHash + Eq + PartialEq + Clone; /// Returns all public keys for this application in the keystore. fn all() -> crate::Vec; diff --git a/core/authority-discovery/primitives/src/lib.rs b/core/authority-discovery/primitives/src/lib.rs index 13da4de020..7c56dc6ca4 100644 --- a/core/authority-discovery/primitives/src/lib.rs +++ b/core/authority-discovery/primitives/src/lib.rs @@ -20,12 +20,13 @@ use client::decl_runtime_apis; use rstd::vec::Vec; +use sr_primitives::RuntimeDebug; -#[derive(codec::Encode, codec::Decode, Eq, PartialEq, Clone)] -#[cfg_attr(feature = "std", derive(Debug, Hash))] +#[derive(codec::Encode, codec::Decode, Eq, PartialEq, Clone, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Hash))] pub struct Signature(pub Vec); -#[derive(codec::Encode, codec::Decode, Eq, PartialEq, Clone)] -#[cfg_attr(feature = "std", derive(Debug, Hash))] +#[derive(codec::Encode, codec::Decode, Eq, PartialEq, Clone, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Hash))] pub struct AuthorityId(pub Vec); decl_runtime_apis! { diff --git a/core/consensus/babe/primitives/src/digest.rs b/core/consensus/babe/primitives/src/digest.rs index ff62ae29c5..95dd247810 100644 --- a/core/consensus/babe/primitives/src/digest.rs +++ b/core/consensus/babe/primitives/src/digest.rs @@ -195,8 +195,7 @@ impl Decode for BabePreDigest { /// Information about the next epoch. This is broadcast in the first block /// of the epoch. -#[derive(Decode, Encode, Default, PartialEq, Eq, Clone)] -#[cfg_attr(any(feature = "std", test), derive(Debug))] +#[derive(Decode, Encode, Default, PartialEq, Eq, Clone, sr_primitives::RuntimeDebug)] pub struct NextEpochDescriptor { /// The authorities. pub authorities: Vec<(AuthorityId, BabeAuthorityWeight)>, diff --git a/core/consensus/babe/primitives/src/lib.rs b/core/consensus/babe/primitives/src/lib.rs index 1293b7c8ba..c464e797d8 100644 --- a/core/consensus/babe/primitives/src/lib.rs +++ b/core/consensus/babe/primitives/src/lib.rs @@ -23,7 +23,7 @@ mod digest; use codec::{Encode, Decode}; use rstd::vec::Vec; -use sr_primitives::ConsensusEngineId; +use sr_primitives::{ConsensusEngineId, RuntimeDebug}; use substrate_client::decl_runtime_apis; #[cfg(feature = "std")] @@ -79,8 +79,7 @@ pub type BabeAuthorityWeight = u64; pub type BabeBlockWeight = u32; /// BABE epoch information -#[derive(Decode, Encode, Default, PartialEq, Eq, Clone)] -#[cfg_attr(any(feature = "std", test), derive(Debug))] +#[derive(Decode, Encode, Default, PartialEq, Eq, Clone, RuntimeDebug)] pub struct Epoch { /// The epoch index pub epoch_index: u64, @@ -127,8 +126,7 @@ pub enum ConsensusLog { } /// Configuration data used by the BABE consensus engine. -#[derive(Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(any(feature = "std", test), derive(Debug))] +#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)] pub struct BabeConfiguration { /// The slot duration in milliseconds for BABE. Currently, only /// the value provided by this type at genesis will be used. diff --git a/core/executor/src/host_interface.rs b/core/executor/src/host_interface.rs index 7c99415f6c..e6386ff1ac 100644 --- a/core/executor/src/host_interface.rs +++ b/core/executor/src/host_interface.rs @@ -151,6 +151,22 @@ impl_wasm_host_interface! { Ok(()) } + ext_log( + level: u32, + target_data: Pointer, + target_len: WordSize, + message_data: Pointer, + message_len: WordSize, + ) { + let target = context.read_memory(target_data, target_len) + .map_err(|_| "Invalid attempt to determine target in ext_log")?; + let message = context.read_memory(message_data, message_len) + .map_err(|_| "Invalid attempt to determine message in ext_log")?; + + runtime_io::log(level.into(), &target, &message); + Ok(()) + } + ext_set_storage( key_data: Pointer, key_len: WordSize, diff --git a/core/finality-grandpa/primitives/src/lib.rs b/core/finality-grandpa/primitives/src/lib.rs index a439953899..27139bbeef 100644 --- a/core/finality-grandpa/primitives/src/lib.rs +++ b/core/finality-grandpa/primitives/src/lib.rs @@ -24,7 +24,7 @@ extern crate alloc; #[cfg(feature = "std")] use serde::Serialize; use codec::{Encode, Decode, Codec}; -use sr_primitives::ConsensusEngineId; +use sr_primitives::{ConsensusEngineId, RuntimeDebug}; use client::decl_runtime_apis; use rstd::vec::Vec; @@ -59,8 +59,8 @@ pub type SetId = u64; pub type RoundNumber = u64; /// A scheduled change of authority set. -#[cfg_attr(feature = "std", derive(Debug, Serialize))] -#[derive(Clone, Eq, PartialEq, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Serialize))] +#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] pub struct ScheduledChange { /// The new authorities after the change, along with their respective weights. pub next_authorities: Vec<(AuthorityId, AuthorityWeight)>, @@ -69,8 +69,8 @@ pub struct ScheduledChange { } /// An consensus log item for GRANDPA. -#[cfg_attr(feature = "std", derive(Serialize, Debug))] -#[derive(Decode, Encode, PartialEq, Eq, Clone)] +#[cfg_attr(feature = "std", derive(Serialize))] +#[derive(Decode, Encode, PartialEq, Eq, Clone, RuntimeDebug)] pub enum ConsensusLog { /// Schedule an authority set change. /// diff --git a/core/phragmen/src/lib.rs b/core/phragmen/src/lib.rs index e15a857b5f..7377bac2f8 100644 --- a/core/phragmen/src/lib.rs +++ b/core/phragmen/src/lib.rs @@ -34,6 +34,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use rstd::{prelude::*, collections::btree_map::BTreeMap}; +use sr_primitives::RuntimeDebug; use sr_primitives::{helpers_128bit::multiply_by_rational, Perbill, Rational128}; use sr_primitives::traits::{Zero, Convert, Member, SimpleArithmetic, Saturating, Bounded}; @@ -54,8 +55,7 @@ pub type ExtendedBalance = u128; const DEN: u128 = u128::max_value(); /// A candidate entity for phragmen election. -#[derive(Clone, Default)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Default, RuntimeDebug)] pub struct Candidate { /// Identifier. pub who: AccountId, @@ -68,8 +68,7 @@ pub struct Candidate { } /// A voter entity. -#[derive(Clone, Default)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Default, RuntimeDebug)] pub struct Voter { /// Identifier. who: AccountId, @@ -82,8 +81,7 @@ pub struct Voter { } /// A candidate being backed by a voter. -#[derive(Clone, Default)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Default, RuntimeDebug)] pub struct Edge { /// Identifier. who: AccountId, @@ -100,7 +98,7 @@ pub type PhragmenAssignment = (AccountId, Perbill); pub type PhragmenStakedAssignment = (AccountId, ExtendedBalance); /// Final result of the phragmen election. -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(RuntimeDebug)] pub struct PhragmenResult { /// Just winners zipped with their approval stake. Note that the approval stake is merely the /// sub of their received stake and could be used for very basic sorting and approval voting. @@ -117,8 +115,7 @@ pub struct PhragmenResult { /// /// This, at the current version, resembles the `Exposure` defined in the staking SRML module, yet /// they do not necessarily have to be the same. -#[derive(Default)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Default, RuntimeDebug)] pub struct Support { /// The amount of support as the effect of self-vote. pub own: ExtendedBalance, diff --git a/core/primitives/Cargo.toml b/core/primitives/Cargo.toml index a527f16c1c..557ce55b88 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -8,12 +8,12 @@ edition = "2018" rstd = { package = "sr-std", path = "../sr-std", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rustc-hex = { version = "2.0.1", default-features = false } +log = { version = "0.4.8", default-features = false } serde = { version = "1.0.101", optional = true, features = ["derive"] } twox-hash = { version = "1.5.0", optional = true } byteorder = { version = "1.3.2", default-features = false } primitive-types = { version = "0.5.1", default-features = false, features = ["codec"] } impl-serde = { version = "0.2.1", optional = true } -log = { version = "0.4.8", optional = true } wasmi = { version = "0.5.1", optional = true } hash-db = { version = "0.15.2", default-features = false } hash256-std-hasher = { version = "0.15.2", default-features = false } @@ -31,6 +31,7 @@ num-traits = { version = "0.2.8", default-features = false } zeroize = "0.10.1" lazy_static = { version = "1.4.0", optional = true } parking_lot = { version = "0.9.0", optional = true } +substrate-debug-derive = { version = "2.0.0", path = "./debug-derive" } externalities = { package = "substrate-externalities", path = "../externalities", optional = true } primitives-storage = { package = "substrate-primitives-storage", path = "storage", default-features = false } @@ -51,7 +52,7 @@ bench = false [features] default = ["std"] std = [ - "log", + "log/std", "wasmi", "lazy_static", "parking_lot", @@ -81,6 +82,7 @@ std = [ "schnorrkel", "regex", "num-traits/std", + "substrate-debug-derive/std", "externalities", "primitives-storage/std", ] diff --git a/core/primitives/debug-derive/Cargo.toml b/core/primitives/debug-derive/Cargo.toml new file mode 100644 index 0000000000..9c7b7aa1ba --- /dev/null +++ b/core/primitives/debug-derive/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "substrate-debug-derive" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[lib] +proc-macro = true + +[dependencies] +quote = "1.0.2" +syn = "1.0.5" +proc-macro2 = "1.0" + +[features] +std = [] + +[dev-dependencies] + diff --git a/core/primitives/debug-derive/src/impls.rs b/core/primitives/debug-derive/src/impls.rs new file mode 100644 index 0000000000..decceca044 --- /dev/null +++ b/core/primitives/debug-derive/src/impls.rs @@ -0,0 +1,217 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use quote::quote; +use proc_macro2::TokenStream; +use syn::{Data, DeriveInput, parse_quote}; + +pub fn debug_derive(ast: DeriveInput) -> proc_macro::TokenStream { + let name_str = ast.ident.to_string(); + let implementation = implementation::derive(&name_str, &ast.data); + let name = &ast.ident; + let mut generics = ast.generics.clone(); + let (impl_generics, ty_generics, where_clause) = { + let wh = generics.make_where_clause(); + for t in ast.generics.type_params() { + let name = &t.ident; + wh.predicates.push(parse_quote!{ #name : core::fmt::Debug }); + } + generics.split_for_impl() + }; + let gen = quote!{ + impl #impl_generics core::fmt::Debug for #name #ty_generics #where_clause { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + #implementation + } + } + }; + + gen.into() +} + +#[cfg(not(feature = "std"))] +mod implementation { + use super::*; + + /// Derive the inner implementation of `Debug::fmt` function. + /// + /// Non-std environment. We do nothing to prevent bloating the size of runtime. + /// Implement `Printable` if you need to print the details. + pub fn derive(_name_str: &str, _data: &Data) -> TokenStream { + quote! { + fmt.write_str("") + } + } +} + +#[cfg(feature = "std")] +mod implementation { + use super::*; + use proc_macro2::Span; + use syn::{Ident, Index, token::SelfValue}; + + /// Derive the inner implementation of `Debug::fmt` function. + pub fn derive(name_str: &str, data: &Data) -> TokenStream { + match *data { + Data::Struct(ref s) => derive_struct(&name_str, &s.fields), + Data::Union(ref u) => derive_fields(&name_str, Fields::new(u.fields.named.iter(), None)), + Data::Enum(ref e) => derive_enum(&name_str, &e), + } + } + + enum Fields { + Indexed { + indices: Vec, + }, + Unnamed { + vars: Vec, + }, + Named { + names: Vec, + this: Option, + }, + } + + impl Fields { + fn new<'a>(fields: impl Iterator, this: Option) -> Self { + let mut indices = vec![]; + let mut names = vec![]; + + for (i, f) in fields.enumerate() { + if let Some(ident) = f.ident.clone() { + names.push(ident); + } else { + indices.push(Index::from(i)); + } + } + + if names.is_empty() { + Self::Indexed { + indices, + } + } else { + Self::Named { + names, + this, + } + } + } + } + + fn derive_fields<'a>( + name_str: &str, + fields: Fields, + ) -> TokenStream { + match fields { + Fields::Named { names, this } => { + let names_str: Vec<_> = names.iter() + .map(|x| x.to_string()) + .collect(); + + let fields = match this { + None => quote! { #( .field(#names_str, #names) )* }, + Some(this) => quote! { #( .field(#names_str, &#this.#names) )* }, + }; + + quote! { + fmt.debug_struct(#name_str) + #fields + .finish() + } + + }, + Fields::Indexed { indices } => { + quote! { + fmt.debug_tuple(#name_str) + #( .field(&self.#indices) )* + .finish() + } + }, + Fields::Unnamed { vars } => { + quote! { + fmt.debug_tuple(#name_str) + #( .field(#vars) )* + .finish() + } + }, + } + } + + fn derive_enum( + name: &str, + e: &syn::DataEnum, + ) -> TokenStream { + let v = e.variants + .iter() + .map(|v| { + let name = format!("{}::{}", name, v.ident); + let ident = &v.ident; + match v.fields { + syn::Fields::Named(ref f) => { + let names: Vec<_> = f.named.iter().flat_map(|f| f.ident.clone()).collect(); + let fields_impl = derive_fields(&name, Fields::Named { + names: names.clone(), + this: None, + }); + (ident, (quote!{ { #( ref #names ),* } }, fields_impl)) + }, + syn::Fields::Unnamed(ref f) => { + let names = f.unnamed.iter() + .enumerate() + .map(|(id, _)| Ident::new(&format!("a{}", id), Span::call_site())) + .collect::>(); + let fields_impl = derive_fields(&name, Fields::Unnamed { vars: names.clone() }); + (ident, (quote! { ( #( ref #names ),* ) }, fields_impl)) + }, + syn::Fields::Unit => { + let fields_impl = derive_fields(&name, Fields::Indexed { indices: vec![] }); + (ident, (quote! { }, fields_impl)) + }, + } + }); + + type Vecs = (Vec, Vec); + let (variants, others): Vecs<_, _> = v.unzip(); + let (match_fields, variants_impl): Vecs<_, _> = others.into_iter().unzip(); + + quote! { + match self { + #( Self::#variants #match_fields => #variants_impl, )* + _ => Ok(()), + } + } + } + + fn derive_struct( + name_str: &str, + fields: &syn::Fields, + ) -> TokenStream { + match *fields { + syn::Fields::Named(ref f) => derive_fields( + name_str, + Fields::new(f.named.iter(), Some(syn::Token!(self)(Span::call_site()))), + ), + syn::Fields::Unnamed(ref f) => derive_fields( + name_str, + Fields::new(f.unnamed.iter(), None), + ), + syn::Fields::Unit => derive_fields( + name_str, + Fields::Indexed { indices: vec![] }, + ), + } + } +} diff --git a/core/primitives/debug-derive/src/lib.rs b/core/primitives/debug-derive/src/lib.rs new file mode 100644 index 0000000000..5e6cf6098b --- /dev/null +++ b/core/primitives/debug-derive/src/lib.rs @@ -0,0 +1,44 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Macros to derive runtime debug implementation. +//! +//! This custom derive implements a `core::fmt::Debug` trait, +//! but in case the `std` feature is enabled the implementation +//! will actually print out the structure as regular `derive(Debug)` +//! would do. If `std` is disabled the implementation will be empty. +//! +//! This behaviour is useful to prevent bloating the runtime WASM +//! blob from unneeded code. +//! +//! ```rust +//! #[derive(substrate_debug_derive::RuntimeDebug)] +//! struct MyStruct; +//! +//! assert_eq!(format!("{:?}", MyStruct), "MyStruct"); +//! ``` + +extern crate proc_macro; + +mod impls; + +use proc_macro::TokenStream; + +#[proc_macro_derive(RuntimeDebug)] +pub fn debug_derive(input: TokenStream) -> TokenStream { + impls::debug_derive(syn::parse_macro_input!(input)) +} + diff --git a/core/primitives/debug-derive/tests/tests.rs b/core/primitives/debug-derive/tests/tests.rs new file mode 100644 index 0000000000..63ad6a3e8d --- /dev/null +++ b/core/primitives/debug-derive/tests/tests.rs @@ -0,0 +1,63 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use substrate_debug_derive::RuntimeDebug; + +#[derive(RuntimeDebug)] +struct Unnamed(u64, String); + +#[derive(RuntimeDebug)] +struct Named { + a: u64, + b: String, +} + +#[derive(RuntimeDebug)] +enum EnumLongName { + A, + B(A, String), + VariantLongName { + a: A, + b: String, + }, +} + + +#[test] +fn should_display_proper_debug() { + use self::EnumLongName as Enum; + + assert_eq!( + format!("{:?}", Unnamed(1, "abc".into())), + "Unnamed(1, \"abc\")" + ); + assert_eq!( + format!("{:?}", Named { a: 1, b: "abc".into() }), + "Named { a: 1, b: \"abc\" }" + ); + assert_eq!( + format!("{:?}", Enum::::A), + "EnumLongName::A" + ); + assert_eq!( + format!("{:?}", Enum::B(1, "abc".into())), + "EnumLongName::B(1, \"abc\")" + ); + assert_eq!( + format!("{:?}", Enum::VariantLongName { a: 1, b: "abc".into() }), + "EnumLongName::VariantLongName { a: 1, b: \"abc\" }" + ); +} diff --git a/core/primitives/src/crypto.rs b/core/primitives/src/crypto.rs index 8a336783b7..588f3bc6e2 100644 --- a/core/primitives/src/crypto.rs +++ b/core/primitives/src/crypto.rs @@ -43,7 +43,7 @@ pub const DEV_PHRASE: &str = "bottom drive obey lake curtain smoke basket hold r pub const DEV_ADDRESS: &str = "5DfhGyQdFobKM8NsWvEeAKk5EQQgYe9AydgJ7rMB6E1EqRzV"; /// The infallible type. -#[derive(Debug)] +#[derive(crate::RuntimeDebug)] pub enum Infallible {} /// The length of the junction identifier. Note that this is also referred to as the @@ -743,7 +743,7 @@ pub trait CryptoType { /// Values whose first character is `_` are reserved for private use and won't conflict with any /// public modules. #[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(crate::RuntimeDebug)] pub struct KeyTypeId(pub [u8; 4]); impl From for KeyTypeId { diff --git a/core/primitives/src/ed25519.rs b/core/primitives/src/ed25519.rs index b674a150c4..ff3b21e160 100644 --- a/core/primitives/src/ed25519.rs +++ b/core/primitives/src/ed25519.rs @@ -130,12 +130,17 @@ impl std::fmt::Display for Public { } } -#[cfg(feature = "std")] -impl std::fmt::Debug for Public { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl rstd::fmt::Debug for Public { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { let s = self.to_ss58check(); write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8]) } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } } #[cfg(feature = "std")] @@ -223,11 +228,16 @@ impl AsMut<[u8]> for Signature { } } -#[cfg(feature = "std")] -impl std::fmt::Debug for Signature { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl rstd::fmt::Debug for Signature { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0)) } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } } #[cfg(feature = "std")] diff --git a/core/primitives/src/hexdisplay.rs b/core/primitives/src/hexdisplay.rs index 87be587a7d..6765ce517e 100644 --- a/core/primitives/src/hexdisplay.rs +++ b/core/primitives/src/hexdisplay.rs @@ -24,8 +24,8 @@ impl<'a> HexDisplay<'a> { pub fn from(d: &'a R) -> Self { HexDisplay(d.as_bytes_ref()) } } -impl<'a> ::core::fmt::Display for HexDisplay<'a> { - fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> { +impl<'a> rstd::fmt::Display for HexDisplay<'a> { + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> Result<(), rstd::fmt::Error> { if self.0.len() < 1027 { for byte in self.0 { f.write_fmt(format_args!("{:02x}", byte))?; @@ -43,8 +43,8 @@ impl<'a> ::core::fmt::Display for HexDisplay<'a> { } } -impl<'a> core::fmt::Debug for HexDisplay<'a> { - fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> { +impl<'a> rstd::fmt::Debug for HexDisplay<'a> { + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> Result<(), rstd::fmt::Error> { for byte in self.0 { f.write_fmt(format_args!("{:02x}", byte))?; } diff --git a/core/primitives/src/lib.rs b/core/primitives/src/lib.rs index 0a1f80aaa9..48d3d998fa 100644 --- a/core/primitives/src/lib.rs +++ b/core/primitives/src/lib.rs @@ -42,6 +42,8 @@ pub use serde;// << for macro #[doc(hidden)] pub use codec::{Encode, Decode};// << for macro +pub use substrate_debug_derive::RuntimeDebug; + #[cfg(feature = "std")] pub use impl_serde::serialize as bytes; @@ -116,8 +118,8 @@ impl ExecutionContext { } /// Hex-serialized shim for `Vec`. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Hash, PartialOrd, Ord))] +#[derive(PartialEq, Eq, Clone, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Hash, PartialOrd, Ord))] pub struct Bytes(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec); impl From> for Bytes { @@ -162,8 +164,8 @@ pub enum NativeOrEncoded { } #[cfg(feature = "std")] -impl ::std::fmt::Debug for NativeOrEncoded { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { +impl rstd::fmt::Debug for NativeOrEncoded { + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { hexdisplay::HexDisplay::from(&self.as_encoded().as_ref()).fmt(f) } } @@ -229,3 +231,58 @@ pub trait TypeId { /// Simple 4 byte identifier. const TYPE_ID: [u8; 4]; } + +/// A log level matching the one from `log` crate. +/// +/// Used internally by `runtime_io::log` method. +#[repr(u32)] +pub enum LogLevel { + /// `Error` log level. + Error = 1, + /// `Warn` log level. + Warn = 2, + /// `Info` log level. + Info = 3, + /// `Debug` log level. + Debug = 4, + /// `Trace` log level. + Trace = 5, +} + +impl From for LogLevel { + fn from(val: u32) -> Self { + match val { + x if x == LogLevel::Warn as u32 => LogLevel::Warn, + x if x == LogLevel::Info as u32 => LogLevel::Info, + x if x == LogLevel::Debug as u32 => LogLevel::Debug, + x if x == LogLevel::Trace as u32 => LogLevel::Trace, + _ => LogLevel::Error, + } + } +} + +impl From for LogLevel { + fn from(l: log::Level) -> Self { + use log::Level::*; + match l { + Error => Self::Error, + Warn => Self::Warn, + Info => Self::Info, + Debug => Self::Debug, + Trace => Self::Trace, + } + } +} + +impl From for log::Level { + fn from(l: LogLevel) -> Self { + use self::LogLevel::*; + match l { + Error => Self::Error, + Warn => Self::Warn, + Info => Self::Info, + Debug => Self::Debug, + Trace => Self::Trace, + } + } +} diff --git a/core/primitives/src/offchain.rs b/core/primitives/src/offchain.rs index 84fee530f6..27bd29a00d 100644 --- a/core/primitives/src/offchain.rs +++ b/core/primitives/src/offchain.rs @@ -18,12 +18,12 @@ use codec::{Encode, Decode}; use rstd::{prelude::{Vec, Box}, convert::TryFrom}; +use crate::RuntimeDebug; pub use crate::crypto::KeyTypeId; /// A type of supported crypto. -#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, RuntimeDebug)] #[repr(C)] pub enum StorageKind { /// Persistent storage is non-revertible and not fork-aware. It means that any value @@ -59,8 +59,8 @@ impl From for u32 { } /// Opaque type for offchain http requests. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "std", derive(Debug, Hash))] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Hash))] pub struct HttpRequestId(pub u16); impl From for u32 { @@ -70,8 +70,7 @@ impl From for u32 { } /// An error enum returned by some http methods. -#[derive(Clone, Copy, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug)] #[repr(C)] pub enum HttpError { /// The requested action couldn't been completed within a deadline. @@ -102,8 +101,7 @@ impl From for u32 { } /// Status of the HTTP request -#[derive(Clone, Copy, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug)] pub enum HttpRequestStatus { /// Deadline was reached while we waited for this request to finish. /// @@ -149,8 +147,7 @@ impl TryFrom for HttpRequestStatus { /// A blob to hold information about the local node's network state /// without committing to its format. -#[derive(Clone, Eq, PartialEq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] pub struct OpaqueNetworkState { /// PeerId of the local node. pub peer_id: OpaquePeerId, @@ -159,8 +156,7 @@ pub struct OpaqueNetworkState { } /// Simple blob to hold a `PeerId` without committing to its format. -#[derive(Default, Clone, Eq, PartialEq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Default, Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] pub struct OpaquePeerId(pub Vec); impl OpaquePeerId { @@ -171,8 +167,7 @@ impl OpaquePeerId { } /// Simple blob to hold a `Multiaddr` without committing to its format. -#[derive(Clone, Eq, PartialEq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] pub struct OpaqueMultiaddr(pub Vec); impl OpaqueMultiaddr { @@ -183,13 +178,11 @@ impl OpaqueMultiaddr { } /// Opaque timestamp type -#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Default)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Default, RuntimeDebug)] pub struct Timestamp(u64); /// Duration type -#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Default)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Default, RuntimeDebug)] pub struct Duration(u64); impl Duration { diff --git a/core/primitives/src/sandbox.rs b/core/primitives/src/sandbox.rs index e47a30ca5b..dd91ad6a1f 100644 --- a/core/primitives/src/sandbox.rs +++ b/core/primitives/src/sandbox.rs @@ -21,12 +21,12 @@ use rstd::vec::Vec; /// Error error that can be returned from host function. #[derive(Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(crate::RuntimeDebug)] pub struct HostError; /// Representation of a typed wasm value. #[derive(Clone, Copy, PartialEq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(crate::RuntimeDebug)] pub enum TypedValue { /// Value of 32-bit signed or unsigned integer. #[codec(index = "1")] @@ -86,7 +86,7 @@ impl From for ::wasmi::RuntimeValue { /// /// Basically a `TypedValue` plus `Unit`, for functions which return nothing. #[derive(Clone, Copy, PartialEq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(crate::RuntimeDebug)] pub enum ReturnValue { /// For returning nothing. Unit, @@ -119,7 +119,7 @@ fn return_value_encoded_max_size() { /// Describes an entity to define or import into the environment. #[derive(Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(crate::RuntimeDebug)] pub enum ExternEntity { /// Function that is specified by an index in a default table of /// a module that creates the sandbox. @@ -137,7 +137,7 @@ pub enum ExternEntity { /// Each entry has a two-level name and description of an entity /// being defined. #[derive(Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(crate::RuntimeDebug)] pub struct Entry { /// Module name of which corresponding entity being defined. pub module_name: Vec, @@ -149,7 +149,7 @@ pub struct Entry { /// Definition of runtime that could be used by sandboxed code. #[derive(Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(crate::RuntimeDebug)] pub struct EnvironmentDefinition { /// Vector of all entries in the environment definition. pub entries: Vec, diff --git a/core/primitives/src/sr25519.rs b/core/primitives/src/sr25519.rs index ed8bb72c9e..f2160b88b7 100644 --- a/core/primitives/src/sr25519.rs +++ b/core/primitives/src/sr25519.rs @@ -129,12 +129,20 @@ impl std::fmt::Display for Public { } } -#[cfg(feature = "std")] -impl std::fmt::Debug for Public { - fn fmt(&self, f: &mut std::fmt::Formatter) -> ::std::fmt::Result { +#[cfg(not(feature = "std"))] +use core as std; + +impl rstd::fmt::Debug for Public { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { let s = self.to_ss58check(); write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8]) } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } } #[cfg(feature = "std")] @@ -231,11 +239,16 @@ impl From for Signature { } } -#[cfg(feature = "std")] -impl std::fmt::Debug for Signature { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { +impl rstd::fmt::Debug for Signature { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0)) } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } } #[cfg(feature = "std")] diff --git a/core/primitives/storage/Cargo.toml b/core/primitives/storage/Cargo.toml index 5b1ed37d6a..7bb2b95623 100644 --- a/core/primitives/storage/Cargo.toml +++ b/core/primitives/storage/Cargo.toml @@ -9,6 +9,7 @@ description = "Storage related primitives" rstd = { package = "sr-std", path = "../../sr-std", default-features = false } serde = { version = "1.0.101", optional = true, features = ["derive"] } impl-serde = { version = "0.2.1", optional = true } +substrate-debug-derive = { version = "2.0.0", path = "../debug-derive" } [features] default = [ "std" ] diff --git a/core/primitives/storage/src/lib.rs b/core/primitives/storage/src/lib.rs index 334779ed5f..dcdc223994 100644 --- a/core/primitives/storage/src/lib.rs +++ b/core/primitives/storage/src/lib.rs @@ -20,27 +20,29 @@ #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; +use substrate_debug_derive::RuntimeDebug; use rstd::{vec::Vec, borrow::Cow}; /// Storage key. -#[derive(PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Hash, PartialOrd, Ord, Clone))] +#[derive(PartialEq, Eq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Hash, PartialOrd, Ord, Clone))] pub struct StorageKey( #[cfg_attr(feature = "std", serde(with="impl_serde::serialize"))] pub Vec, ); /// Storage data associated to a [`StorageKey`]. -#[derive(PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Hash, PartialOrd, Ord, Clone))] +#[derive(PartialEq, Eq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Hash, PartialOrd, Ord, Clone))] pub struct StorageData( #[cfg_attr(feature = "std", serde(with="impl_serde::serialize"))] pub Vec, ); /// Storage change set -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, PartialEq, Eq))] +#[derive(RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, PartialEq, Eq))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] pub struct StorageChangeSet { /// Block hash diff --git a/core/sr-arithmetic/Cargo.toml b/core/sr-arithmetic/Cargo.toml index d98404db94..3962daf493 100644 --- a/core/sr-arithmetic/Cargo.toml +++ b/core/sr-arithmetic/Cargo.toml @@ -5,11 +5,12 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -num-traits = { version = "0.2.8", default-features = false } -serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -rstd = { package = "sr-std", path = "../sr-std", default-features = false } integer-sqrt = "0.1.2" +num-traits = { version = "0.2.8", default-features = false } +rstd = { package = "sr-std", path = "../sr-std", default-features = false } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +substrate-debug-derive = { path = "../primitives/debug-derive", default-features = false } [dev-dependencies] primitive-types = "0.6.0" @@ -19,8 +20,9 @@ rand = "0.7.2" bench = [] default = ["std"] std = [ - "serde", + "codec/std", "num-traits/std", "rstd/std", - "codec/std", + "serde", + "substrate-debug-derive/std", ] diff --git a/core/sr-arithmetic/src/biguint.rs b/core/sr-arithmetic/src/biguint.rs index d90ad4862b..b7d93c2f0d 100644 --- a/core/sr-arithmetic/src/biguint.rs +++ b/core/sr-arithmetic/src/biguint.rs @@ -427,8 +427,8 @@ impl BigUint { } } -#[cfg(feature = "std")] impl rstd::fmt::Debug for BigUint { + #[cfg(feature = "std")] fn fmt(&self, f: &mut rstd::fmt::Formatter<'_>) -> rstd::fmt::Result { write!( f, @@ -437,6 +437,12 @@ impl rstd::fmt::Debug for BigUint { u128::try_from(self.clone()).unwrap_or(0), ) } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter<'_>) -> rstd::fmt::Result { + Ok(()) + } + } impl PartialEq for BigUint { diff --git a/core/sr-arithmetic/src/fixed64.rs b/core/sr-arithmetic/src/fixed64.rs index 7dfc8414d2..3bac75898e 100644 --- a/core/sr-arithmetic/src/fixed64.rs +++ b/core/sr-arithmetic/src/fixed64.rs @@ -144,11 +144,16 @@ impl CheckedAdd for Fixed64 { } } -#[cfg(feature = "std")] impl rstd::fmt::Debug for Fixed64 { - fn fmt(&self, f: &mut rstd::fmt::Formatter<'_>) -> rstd::fmt::Result { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { write!(f, "Fixed64({},{})", self.0 / DIV, (self.0 % DIV) / 1000) } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } } #[cfg(test)] diff --git a/core/sr-arithmetic/src/per_things.rs b/core/sr-arithmetic/src/per_things.rs index afd8100a84..2dd1e62d0b 100644 --- a/core/sr-arithmetic/src/per_things.rs +++ b/core/sr-arithmetic/src/per_things.rs @@ -20,14 +20,15 @@ use serde::{Serialize, Deserialize}; use rstd::{ops, prelude::*, convert::TryInto}; use codec::{Encode, Decode, CompactAs}; use crate::traits::{SaturatedConversion, UniqueSaturatedInto, Saturating}; +use substrate_debug_derive::RuntimeDebug; macro_rules! implement_per_thing { ($name:ident, $test_mod:ident, [$($test_units:tt),+], $max:tt, $type:ty, $upper_type:ty, $title:expr $(,)?) => { /// A fixed point representation of a number between in the range [0, 1]. /// #[doc = $title] - #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Ord, PartialOrd))] - #[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, CompactAs)] + #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Ord, PartialOrd))] + #[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, RuntimeDebug, CompactAs)] pub struct $name($type); impl $name { @@ -189,7 +190,7 @@ macro_rules! implement_per_thing { #[cfg(test)] mod $test_mod { use codec::{Encode, Decode}; - use super::{$name, Saturating}; + use super::{$name, Saturating, RuntimeDebug}; use crate::traits::Zero; @@ -208,7 +209,7 @@ macro_rules! implement_per_thing { assert!(<$upper_type>::from($max).checked_mul($max.into()).is_some()); } - #[derive(Encode, Decode, PartialEq, Eq, Debug)] + #[derive(Encode, Decode, PartialEq, Eq, RuntimeDebug)] struct WithCompact { data: T, } diff --git a/core/sr-arithmetic/src/rational128.rs b/core/sr-arithmetic/src/rational128.rs index 706d6a5eba..3247321199 100644 --- a/core/sr-arithmetic/src/rational128.rs +++ b/core/sr-arithmetic/src/rational128.rs @@ -17,10 +17,10 @@ use rstd::{cmp::Ordering, prelude::*}; use crate::helpers_128bit; use num_traits::Zero; +use substrate_debug_derive::RuntimeDebug; /// A wrapper for any rational number with a 128 bit numerator and denominator. -#[derive(Clone, Copy, Default, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Copy, Default, Eq, RuntimeDebug)] pub struct Rational128(u128, u128); impl Rational128 { diff --git a/core/sr-io/Cargo.toml b/core/sr-io/Cargo.toml index e2b681b75b..4d140d289d 100644 --- a/core/sr-io/Cargo.toml +++ b/core/sr-io/Cargo.toml @@ -9,15 +9,16 @@ edition = "2018" rustc_version = "0.2.3" [dependencies] -rstd = { package = "sr-std", path = "../sr-std", default-features = false } -primitives = { package = "substrate-primitives", path = "../primitives", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } hash-db = { version = "0.15.2", default-features = false } +primitives = { package = "substrate-primitives", path = "../primitives", default-features = false } +rstd = { package = "sr-std", path = "../sr-std", default-features = false } libsecp256k1 = { version = "0.3.0", optional = true } tiny-keccak = { version = "1.5.0", optional = true } substrate-state-machine = { path = "../state-machine", optional = true } trie = { package = "substrate-trie", path = "../trie", optional = true } externalities = { package = "substrate-externalities", path = "../externalities", optional = true } +log = { version = "0.4.8", optional = true } [features] default = ["std"] @@ -31,6 +32,7 @@ std = [ "libsecp256k1", "tiny-keccak", "externalities", + "log", ] nightly = [] strict = [] diff --git a/core/sr-io/src/lib.rs b/core/sr-io/src/lib.rs index 24f964c7b5..b0274286dc 100644 --- a/core/sr-io/src/lib.rs +++ b/core/sr-io/src/lib.rs @@ -33,6 +33,7 @@ use primitives::{ offchain::{ Timestamp, HttpRequestId, HttpRequestStatus, HttpError, StorageKind, OpaqueNetworkState, }, + LogLevel, }; /// Error verifying ECDSA signature @@ -158,6 +159,20 @@ export_api! { fn print_utf8(utf8: &[u8]); /// Print any `u8` slice as hex. fn print_hex(data: &[u8]); + + /// Request to print a log message (stderr) on the host. + /// + /// Note that this will be only displayed if the host + /// is enabed to display log messages with given + /// level and target. + /// + /// Instead of using directly, prefer setting up `RuntimeLogger` + /// and using `log` macros. + fn log( + level: LogLevel, + target: &[u8], + message: &[u8] + ); } } diff --git a/core/sr-io/with_std.rs b/core/sr-io/with_std.rs index e431ae1f6e..de40115cbe 100644 --- a/core/sr-io/with_std.rs +++ b/core/sr-io/with_std.rs @@ -192,6 +192,22 @@ impl OtherApi for () { fn print_hex(data: &[u8]) { println!("{}", HexDisplay::from(&data)); } + + fn log( + level: LogLevel, + target: &[u8], + message: &[u8], + ) { + let target = std::str::from_utf8(target).unwrap_or("invalid utf8"); + let msg = std::str::from_utf8(message).unwrap_or("invalid utf8"); + + log::log!( + target: target, + log::Level::from(level), + "{}", + msg, + ) + } } impl CryptoApi for () { diff --git a/core/sr-io/without_std.rs b/core/sr-io/without_std.rs index 90ec5a9ee4..789098185e 100644 --- a/core/sr-io/without_std.rs +++ b/core/sr-io/without_std.rs @@ -160,6 +160,14 @@ pub mod ext { fn ext_print_hex(data: *const u8, len: u32); /// Print a number fn ext_print_num(value: u64); + /// Print a log line if logging for given level and target is enabled. + fn ext_log( + level: u32, + target_data: *const u8, + target_len: u32, + message_data: *const u8, + message_len: u32, + ); /// Set value for key in storage. fn ext_set_storage(key_data: *const u8, key_len: u32, value_data: *const u8, value_len: u32); @@ -780,6 +788,22 @@ impl OtherApi for () { ext_print_hex.get()(data.as_ptr(), data.len() as u32); } } + + fn log( + level: LogLevel, + target: &[u8], + message: &[u8] + ) { + unsafe { + ext_log.get()( + level as u32, + target.as_ptr(), + target.len() as u32, + message.as_ptr(), + message.len() as u32, + ) + } + } } impl HashingApi for () { diff --git a/core/sr-primitives/Cargo.toml b/core/sr-primitives/Cargo.toml index 249b89acee..d330301426 100644 --- a/core/sr-primitives/Cargo.toml +++ b/core/sr-primitives/Cargo.toml @@ -26,13 +26,13 @@ substrate-offchain = { path = "../offchain" } bench = [] default = ["std"] std = [ - "serde", - "log", - "rstd/std", - "runtime_io/std", - "codec/std", - "primitives/std", "app-crypto/std", "arithmetic/std", + "codec/std", + "log", + "primitives/std", "rand", + "rstd/std", + "runtime_io/std", + "serde", ] diff --git a/core/sr-primitives/src/curve.rs b/core/sr-primitives/src/curve.rs index dc6316bd47..6f25af3e10 100644 --- a/core/sr-primitives/src/curve.rs +++ b/core/sr-primitives/src/curve.rs @@ -20,8 +20,7 @@ use crate::{Perbill, traits::{SimpleArithmetic, SaturatedConversion}}; use core::ops::Sub; /// Piecewise Linear function in [0, 1] -> [0, 1]. -#[cfg_attr(feature = "std", derive(Debug))] -#[derive(PartialEq, Eq)] +#[derive(PartialEq, Eq, primitives::RuntimeDebug)] pub struct PiecewiseLinear<'a> { /// Array of points. Must be in order from the lowest abscissas to the highest. pub points: &'a [(Perbill, Perbill)] diff --git a/core/sr-primitives/src/generic/block.rs b/core/sr-primitives/src/generic/block.rs index 29fcaab572..3383e25760 100644 --- a/core/sr-primitives/src/generic/block.rs +++ b/core/sr-primitives/src/generic/block.rs @@ -23,13 +23,14 @@ use std::fmt; use serde::{Deserialize, Serialize}; use rstd::prelude::*; +use primitives::RuntimeDebug; use crate::codec::{Codec, Encode, Decode}; use crate::traits::{self, Member, Block as BlockT, Header as HeaderT, MaybeSerialize}; use crate::Justification; /// Something to identify a block. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Debug, Serialize))] +#[derive(PartialEq, Eq, Clone, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] #[cfg_attr(feature = "std", serde(deny_unknown_fields))] pub enum BlockId { @@ -61,8 +62,8 @@ impl fmt::Display for BlockId { } /// Abstraction over a substrate block. -#[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] #[cfg_attr(feature = "std", serde(deny_unknown_fields))] pub struct Block { @@ -99,8 +100,8 @@ where } /// Abstraction over a substrate block and justification. -#[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] #[cfg_attr(feature = "std", serde(deny_unknown_fields))] pub struct SignedBlock { diff --git a/core/sr-primitives/src/generic/checked_extrinsic.rs b/core/sr-primitives/src/generic/checked_extrinsic.rs index e8d41325c4..1e030ea1d8 100644 --- a/core/sr-primitives/src/generic/checked_extrinsic.rs +++ b/core/sr-primitives/src/generic/checked_extrinsic.rs @@ -26,8 +26,7 @@ use crate::transaction_validity::TransactionValidity; /// Definition of something that the external world might want to say; its /// existence implies that it has been checked and is good, particularly with /// regards to the signature. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Clone, primitives::RuntimeDebug)] pub struct CheckedExtrinsic { /// Who this purports to be from and the number of extrinsics have come before /// from the same signer, if anyone (note this is not a signature). diff --git a/core/sr-primitives/src/generic/digest.rs b/core/sr-primitives/src/generic/digest.rs index d2974444e2..83f2c6f174 100644 --- a/core/sr-primitives/src/generic/digest.rs +++ b/core/sr-primitives/src/generic/digest.rs @@ -23,10 +23,11 @@ use rstd::prelude::*; use crate::ConsensusEngineId; use crate::codec::{Decode, Encode, Input, Error}; +use primitives::RuntimeDebug; /// Generic header digest. -#[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct Digest { /// A list of logs in the digest. pub logs: Vec>, @@ -72,8 +73,7 @@ impl Digest { /// Digest item that is able to encode/decode 'system' digest items and /// provide opaque access to other items. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Clone, RuntimeDebug)] pub enum DigestItem { /// System digest item that contains the root of changes trie at given /// block. It is created for every block iff runtime supports changes @@ -123,8 +123,7 @@ impl<'a, Hash: Decode> serde::Deserialize<'a> for DigestItem { /// A 'referencing view' for digest item. Does not own its contents. Used by /// final runtime implementations for encoding/decoding its log items. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Clone, RuntimeDebug)] pub enum DigestItemRef<'a, Hash: 'a> { /// Reference to `DigestItem::ChangesTrieRoot`. ChangesTrieRoot(&'a Hash), diff --git a/core/sr-primitives/src/generic/era.rs b/core/sr-primitives/src/generic/era.rs index 7308a8adc5..305951b1ee 100644 --- a/core/sr-primitives/src/generic/era.rs +++ b/core/sr-primitives/src/generic/era.rs @@ -28,8 +28,8 @@ pub type Period = u64; pub type Phase = u64; /// An era to describe the longevity of a transaction. -#[derive(PartialEq, Eq, Clone, Copy)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] +#[derive(PartialEq, Eq, Clone, Copy, primitives::RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum Era { /// The transaction is valid forever. The genesis hash must be present in the signed content. Immortal, diff --git a/core/sr-primitives/src/generic/header.rs b/core/sr-primitives/src/generic/header.rs index e9a8405fe2..75994749c5 100644 --- a/core/sr-primitives/src/generic/header.rs +++ b/core/sr-primitives/src/generic/header.rs @@ -18,20 +18,21 @@ #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; -#[cfg(feature = "std")] -use log::debug; use crate::codec::{Decode, Encode, Codec, Input, Output, HasCompact, EncodeAsRef, Error}; use crate::traits::{ - self, Member, SimpleArithmetic, SimpleBitOps, MaybeDisplay, Hash as HashT, MaybeSerializeDebug, - MaybeSerializeDebugButNotDeserialize + self, Member, SimpleArithmetic, SimpleBitOps, Hash as HashT, + MaybeSerializeDeserialize, MaybeSerialize, MaybeDisplay, }; use crate::generic::Digest; use primitives::U256; -use core::convert::TryFrom; +use rstd::{ + convert::TryFrom, + fmt::Debug, +}; /// Abstraction over a block header for a substrate chain. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[derive(PartialEq, Eq, Clone, primitives::RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] #[cfg_attr(feature = "std", serde(deny_unknown_fields))] pub struct Header + TryFrom, Hash: HashT> { @@ -103,11 +104,11 @@ impl codec::EncodeLike for Header where {} impl traits::Header for Header where - Number: Member + MaybeSerializeDebug + rstd::hash::Hash + MaybeDisplay + + Number: Member + MaybeSerializeDeserialize + Debug + rstd::hash::Hash + MaybeDisplay + SimpleArithmetic + Codec + Copy + Into + TryFrom, Hash: HashT, Hash::Output: Default + rstd::hash::Hash + Copy + Member + - MaybeSerializeDebugButNotDeserialize + MaybeDisplay + SimpleBitOps + Codec, + MaybeSerialize + Debug + MaybeDisplay + SimpleBitOps + Codec, { type Number = Number; type Hash = ::Output; @@ -127,15 +128,12 @@ impl traits::Header for Header where fn digest(&self) -> &Digest { &self.digest } - #[cfg(feature = "std")] fn digest_mut(&mut self) -> &mut Digest { - debug!(target: "header", "Retrieving mutable reference to digest"); + #[cfg(feature = "std")] + log::debug!(target: "header", "Retrieving mutable reference to digest"); &mut self.digest } - #[cfg(not(feature = "std"))] - fn digest_mut(&mut self) -> &mut Digest { &mut self.digest } - fn new( number: Self::Number, extrinsics_root: Self::Hash, diff --git a/core/sr-primitives/src/generic/unchecked_extrinsic.rs b/core/sr-primitives/src/generic/unchecked_extrinsic.rs index c5ee76e21c..d50314f33b 100644 --- a/core/sr-primitives/src/generic/unchecked_extrinsic.rs +++ b/core/sr-primitives/src/generic/unchecked_extrinsic.rs @@ -16,10 +16,8 @@ //! Generic implementation of an unchecked (pre-verification) extrinsic. -#[cfg(feature = "std")] -use std::fmt; - use rstd::prelude::*; +use rstd::fmt; use runtime_io::blake2_256; use codec::{Decode, Encode, EncodeLike, Input, Error}; use crate::{ @@ -264,7 +262,6 @@ impl s } } -#[cfg(feature = "std")] impl fmt::Debug for UncheckedExtrinsic where diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index 590b6fedd7..ea295fbea6 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -62,6 +62,9 @@ pub use generic::{DigestItem, Digest}; pub use primitives::{TypeId, crypto::{key_types, KeyTypeId, CryptoType}}; pub use app_crypto::RuntimeAppPublic; +/// Re-export `RuntimeDebug`, to avoid dependency clutter. +pub use primitives::RuntimeDebug; + /// Re-export top-level arithmetic stuff. pub use arithmetic::{ Perquintill, Perbill, Permill, Percent, @@ -166,8 +169,7 @@ impl BuildStorage for (StorageOverlay, ChildrenStorageOverlay) { pub type ConsensusEngineId = [u8; 4]; /// Signature verify that can work with any known signature types.. -#[derive(Eq, PartialEq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Eq, PartialEq, Clone, Encode, Decode, RuntimeDebug)] pub enum MultiSignature { /// An Ed25519 signature. Ed25519(ed25519::Signature), @@ -194,8 +196,8 @@ impl Default for MultiSignature { } /// Public key for any known crypto algorithm. -#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum MultiSigner { /// An Ed25519 identity. Ed25519(ed25519::Public), @@ -260,8 +262,8 @@ impl Verify for MultiSignature { } /// Signature verify that can work with any known signature types.. -#[derive(Eq, PartialEq, Clone, Default, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[derive(Eq, PartialEq, Clone, Default, Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct AnySignature(H512); impl Verify for AnySignature { @@ -289,8 +291,8 @@ impl From for AnySignature { } } -#[derive(Eq, PartialEq, Clone, Copy, Decode, Encode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize))] +#[derive(Eq, PartialEq, Clone, Copy, Decode, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize))] /// Reason why an extrinsic couldn't be applied (i.e. invalid extrinsic). pub enum ApplyError { /// General error to do with the permissions of the sender. @@ -341,8 +343,8 @@ impl From for ApplyOutcome { /// Result from attempt to apply an extrinsic. pub type ApplyResult = Result; -#[derive(Eq, PartialEq, Clone, Copy, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize))] +#[derive(Eq, PartialEq, Clone, Copy, Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize))] /// Reason why a dispatch call failed pub struct DispatchError { /// Module index, matching the metadata module index @@ -564,13 +566,19 @@ macro_rules! assert_eq_error_rate { #[derive(PartialEq, Eq, Clone, Default, Encode, Decode)] pub struct OpaqueExtrinsic(pub Vec); -#[cfg(feature = "std")] -impl std::fmt::Debug for OpaqueExtrinsic { - fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { +impl rstd::fmt::Debug for OpaqueExtrinsic { + #[cfg(feature = "std")] + fn fmt(&self, fmt: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { write!(fmt, "{}", primitives::hexdisplay::HexDisplay::from(&self.0)) } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _fmt: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } } + #[cfg(feature = "std")] impl ::serde::Serialize for OpaqueExtrinsic { fn serialize(&self, seq: S) -> Result where S: ::serde::Serializer { diff --git a/core/sr-primitives/src/offchain/http.rs b/core/sr-primitives/src/offchain/http.rs index b68cf28365..77e514d653 100644 --- a/core/sr-primitives/src/offchain/http.rs +++ b/core/sr-primitives/src/offchain/http.rs @@ -51,6 +51,7 @@ use rstd::str; use rstd::prelude::Vec; #[cfg(not(feature = "std"))] use rstd::prelude::vec; +use primitives::RuntimeDebug; use primitives::offchain::{ Timestamp, HttpRequestId as RequestId, @@ -59,8 +60,7 @@ use primitives::offchain::{ }; /// Request method (HTTP verb) -#[derive(Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, PartialEq, Eq, RuntimeDebug)] pub enum Method { /// GET request Get, @@ -93,8 +93,7 @@ mod header { use super::*; /// A header type. - #[derive(Clone, PartialEq, Eq)] - #[cfg_attr(feature = "std", derive(Debug))] + #[derive(Clone, PartialEq, Eq, RuntimeDebug)] pub struct Header { name: Vec, value: Vec, @@ -128,8 +127,7 @@ mod header { } /// An HTTP request builder. -#[derive(Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, PartialEq, Eq, RuntimeDebug)] pub struct Request<'a, T = Vec<&'static [u8]>> { /// Request method pub method: Method, @@ -249,8 +247,7 @@ impl<'a, I: AsRef<[u8]>, T: IntoIterator> Request<'a, T> { } /// A request error -#[derive(Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, PartialEq, Eq, RuntimeDebug)] pub enum Error { /// Deadline has been reached. DeadlineReached, @@ -261,8 +258,7 @@ pub enum Error { } /// A struct representing an uncompleted http request. -#[derive(PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, RuntimeDebug)] pub struct PendingRequest { /// Request ID pub id: RequestId, @@ -323,7 +319,7 @@ impl PendingRequest { } /// A HTTP response. -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(RuntimeDebug)] pub struct Response { /// Request id pub id: RequestId, @@ -452,8 +448,7 @@ impl Iterator for ResponseBody { } /// A collection of Headers in the response. -#[derive(Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, PartialEq, Eq, RuntimeDebug)] pub struct Headers { /// Raw headers pub raw: Vec<(Vec, Vec)>, @@ -483,8 +478,7 @@ impl Headers { } /// A custom iterator traversing all the headers. -#[derive(Clone)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, RuntimeDebug)] pub struct HeadersIterator<'a> { collection: &'a [(Vec, Vec)], index: Option, diff --git a/core/sr-primitives/src/traits.rs b/core/sr-primitives/src/traits.rs index a384c95e19..0497f094d2 100644 --- a/core/sr-primitives/src/traits.rs +++ b/core/sr-primitives/src/traits.rs @@ -17,10 +17,10 @@ //! Primitives for the runtime modules. use rstd::prelude::*; -use rstd::{self, result, marker::PhantomData, convert::{TryFrom, TryInto}}; +use rstd::{self, result, marker::PhantomData, convert::{TryFrom, TryInto}, fmt::Debug}; use runtime_io; #[cfg(feature = "std")] -use std::fmt::{Debug, Display}; +use std::fmt::Display; #[cfg(feature = "std")] use serde::{Serialize, Deserialize, de::DeserializeOwned}; use primitives::{self, Hasher, Blake2Hasher, TypeId}; @@ -147,7 +147,7 @@ pub trait Lookup { /// context. pub trait StaticLookup { /// Type to lookup from. - type Source: Codec + Clone + PartialEq + MaybeDebug; + type Source: Codec + Clone + PartialEq + Debug; /// Type to lookup into. type Target; /// Attempt a lookup. @@ -159,7 +159,7 @@ pub trait StaticLookup { /// A lookup implementation returning the input value. #[derive(Default)] pub struct IdentityLookup(PhantomData); -impl StaticLookup for IdentityLookup { +impl StaticLookup for IdentityLookup { type Source = T; type Target = T; fn lookup(x: T) -> Result { Ok(x) } @@ -323,10 +323,10 @@ pub trait OffchainWorker { /// Abstraction around hashing // Stupid bug in the Rust compiler believes derived // traits must be fulfilled by all type parameters. -pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq { +pub trait Hash: 'static + MaybeSerializeDeserialize + Debug + Clone + Eq + PartialEq { /// The hash type produced. - type Output: Member + MaybeSerializeDebug + rstd::hash::Hash + AsRef<[u8]> + AsMut<[u8]> + Copy - + Default + Encode + Decode; + type Output: Member + MaybeSerializeDeserialize + Debug + rstd::hash::Hash + + AsRef<[u8]> + AsMut<[u8]> + Copy + Default + Encode + Decode; /// The associated hash_db Hasher type. type Hasher: Hasher; @@ -353,8 +353,8 @@ pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq { } /// Blake2-256 Hash implementation. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[derive(PartialEq, Eq, Clone, primitives::RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct BlakeTwo256; impl Hash for BlakeTwo256 { @@ -410,7 +410,7 @@ impl CheckEqual for primitives::H256 { } } -impl CheckEqual for super::generic::DigestItem where H: Encode { +impl CheckEqual for super::generic::DigestItem where H: Encode { #[cfg(feature = "std")] fn check_equal(&self, other: &Self) { if self != other { @@ -447,23 +447,17 @@ macro_rules! impl_maybe_marker { } impl_maybe_marker!( - /// A type that implements Debug when in std environment. - MaybeDebug: Debug; - /// A type that implements Display when in std environment. MaybeDisplay: Display; /// A type that implements Hash when in std environment. - MaybeHash: ::rstd::hash::Hash; + MaybeHash: rstd::hash::Hash; /// A type that implements Serialize when in std environment. MaybeSerialize: Serialize; /// A type that implements Serialize, DeserializeOwned and Debug when in std environment. - MaybeSerializeDebug: Debug, DeserializeOwned, Serialize; - - /// A type that implements Serialize and Debug when in std environment. - MaybeSerializeDebugButNotDeserialize: Debug, Serialize + MaybeSerializeDeserialize: DeserializeOwned, Serialize ); /// A type that provides a randomness beacon. @@ -483,8 +477,8 @@ pub trait RandomnessBeacon { } /// A type that can be used in runtime structures. -pub trait Member: Send + Sync + Sized + MaybeDebug + Eq + PartialEq + Clone + 'static {} -impl Member for T {} +pub trait Member: Send + Sync + Sized + Debug + Eq + PartialEq + Clone + 'static {} +impl Member for T {} /// Determine if a `MemberId` is a valid member. pub trait IsMember { @@ -497,11 +491,13 @@ pub trait IsMember { /// `parent_hash`, as well as a `digest` and a block `number`. /// /// You can also create a `new` one from those fields. -pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebugButNotDeserialize + 'static { +pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug + 'static { /// Header number. - type Number: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec; + type Number: Member + MaybeSerializeDeserialize + Debug + rstd::hash::Hash + + Copy + MaybeDisplay + SimpleArithmetic + Codec; /// Header hash type - type Hash: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>; + type Hash: Member + MaybeSerializeDeserialize + Debug + rstd::hash::Hash + + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>; /// Hashing algorithm type Hashing: Hash; @@ -549,13 +545,14 @@ pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebugButNotDe /// `Extrinsic` piece of information as well as a `Header`. /// /// You can get an iterator over each of the `extrinsics` and retrieve the `header`. -pub trait Block: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebugButNotDeserialize + 'static { +pub trait Block: Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug + 'static { /// Type of extrinsics. type Extrinsic: Member + Codec + Extrinsic + MaybeSerialize; /// Header type. type Header: Header; /// Block hash type. - type Hash: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>; + type Hash: Member + MaybeSerializeDeserialize + Debug + rstd::hash::Hash + + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>; /// Returns a reference to the header. fn header(&self) -> &Self::Header; @@ -661,7 +658,7 @@ pub trait Dispatchable { /// Means by which a transaction may be extended. This type embodies both the data and the logic /// that should be additionally associated with the transaction. It should be plain old data. -pub trait SignedExtension: Codec + MaybeDebug + Sync + Send + Clone + Eq + PartialEq { +pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq { /// The type which encodes the sender identity. type AccountId; @@ -1080,8 +1077,13 @@ macro_rules! impl_opaque_keys { )* } ) => { - #[derive(Default, Clone, PartialEq, Eq, $crate::codec::Encode, $crate::codec::Decode)] - #[cfg_attr(feature = "std", derive(Debug, $crate::serde::Serialize, $crate::serde::Deserialize))] + #[derive( + Default, Clone, PartialEq, Eq, + $crate::codec::Encode, + $crate::codec::Decode, + $crate::RuntimeDebug + )] + #[cfg_attr(feature = "std", derive($crate::serde::Serialize, $crate::serde::Deserialize))] pub struct $name { $( pub $field: $type, @@ -1131,7 +1133,25 @@ pub trait Printable { impl Printable for u8 { fn print(&self) { - u64::from(*self).print() + (*self as u64).print() + } +} + +impl Printable for u32 { + fn print(&self) { + (*self as u64).print() + } +} + +impl Printable for usize { + fn print(&self) { + (*self as u64).print() + } +} + +impl Printable for u64 { + fn print(&self) { + runtime_io::print_num(*self); } } @@ -1147,9 +1167,10 @@ impl Printable for &str { } } -impl Printable for u64 { +#[impl_for_tuples(1, 12)] +impl Printable for Tuple { fn print(&self) { - runtime_io::print_num(*self); + for_tuples!( #( Tuple.print(); )* ) } } diff --git a/core/sr-primitives/src/transaction_validity.rs b/core/sr-primitives/src/transaction_validity.rs index eb6cf3bdbb..3e765215b9 100644 --- a/core/sr-primitives/src/transaction_validity.rs +++ b/core/sr-primitives/src/transaction_validity.rs @@ -18,6 +18,7 @@ use rstd::prelude::*; use crate::codec::{Encode, Decode}; +use crate::RuntimeDebug; /// Priority for a transaction. Additive. Higher is better. pub type TransactionPriority = u64; @@ -30,8 +31,8 @@ pub type TransactionLongevity = u64; pub type TransactionTag = Vec; /// An invalid transaction validity. -#[derive(Clone, PartialEq, Eq, Encode, Decode, Copy)] -#[cfg_attr(feature = "std", derive(Debug, serde::Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, Decode, Copy, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(serde::Serialize))] pub enum InvalidTransaction { /// The call of the transaction is not expected. Call, @@ -81,8 +82,8 @@ impl From for &'static str { } /// An unknown transaction validity. -#[derive(Clone, PartialEq, Eq, Encode, Decode, Copy)] -#[cfg_attr(feature = "std", derive(Debug, serde::Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, Decode, Copy, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(serde::Serialize))] pub enum UnknownTransaction { /// Could not lookup some information that is required to validate the transaction. CannotLookup, @@ -105,8 +106,8 @@ impl From for &'static str { } /// Errors that can occur while checking the validity of a transaction. -#[derive(Clone, PartialEq, Eq, Encode, Decode, Copy)] -#[cfg_attr(feature = "std", derive(Debug, serde::Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, Decode, Copy, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(serde::Serialize))] pub enum TransactionValidityError { /// The transaction is invalid. Invalid(InvalidTransaction), @@ -173,8 +174,7 @@ impl Into for UnknownTransaction { } /// Information concerning a valid transaction. -#[derive(Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)] pub struct ValidTransaction { /// Priority of the transaction. /// diff --git a/core/sr-primitives/src/weights.rs b/core/sr-primitives/src/weights.rs index b1cce0f77f..b245f90247 100644 --- a/core/sr-primitives/src/weights.rs +++ b/core/sr-primitives/src/weights.rs @@ -23,16 +23,17 @@ //! Note that the decl_module macro _cannot_ enforce this and will simply fail if an invalid struct //! (something that does not implement `Weighable`) is passed in. -pub use crate::transaction_validity::TransactionPriority; use arithmetic::traits::Bounded; +use crate::RuntimeDebug; + +pub use crate::transaction_validity::TransactionPriority; /// Numeric range of a transaction weight. pub type Weight = u32; /// A generalized group of dispatch types. This is only distinguishing normal, user-triggered transactions /// (`Normal`) and anything beyond which serves a higher purpose to the system (`Operational`). -#[cfg_attr(feature = "std", derive(Debug))] -#[derive(PartialEq, Eq, Clone, Copy)] +#[derive(PartialEq, Eq, Clone, Copy, RuntimeDebug)] pub enum DispatchClass { /// A normal dispatch. Normal, @@ -61,8 +62,8 @@ impl From for DispatchClass { } /// A bundle of static information collected from the `#[weight = $x]` attributes. -#[cfg_attr(feature = "std", derive(PartialEq, Eq, Debug))] -#[derive(Clone, Copy, Default)] +#[cfg_attr(feature = "std", derive(PartialEq, Eq))] +#[derive(Clone, Copy, Default, RuntimeDebug)] pub struct DispatchInfo { /// Weight of this transaction. pub weight: Weight, diff --git a/core/sr-sandbox/src/lib.rs b/core/sr-sandbox/src/lib.rs index b04524b241..c9f9135661 100755 --- a/core/sr-sandbox/src/lib.rs +++ b/core/sr-sandbox/src/lib.rs @@ -51,7 +51,7 @@ mod imp { } /// Error that can occur while using this crate. -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(primitives::RuntimeDebug)] pub enum Error { /// Module is not valid, couldn't be instantiated. Module, diff --git a/core/sr-staking-primitives/src/offence.rs b/core/sr-staking-primitives/src/offence.rs index c076103c18..db51f75df1 100644 --- a/core/sr-staking-primitives/src/offence.rs +++ b/core/sr-staking-primitives/src/offence.rs @@ -131,8 +131,7 @@ impl OnOffenceHandler for () { } /// A details about an offending authority for a particular kind of offence. -#[derive(Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, PartialEq, Eq, Encode, Decode, sr_primitives::RuntimeDebug)] pub struct OffenceDetails { /// The offending authority id pub offender: Offender, diff --git a/core/sr-std/without_std.rs b/core/sr-std/without_std.rs index 134cc25c94..9762c74367 100755 --- a/core/sr-std/without_std.rs +++ b/core/sr-std/without_std.rs @@ -53,6 +53,7 @@ pub use core::clone; pub use core::cmp; pub use core::convert; pub use core::default; +pub use core::fmt; pub use core::hash; pub use core::intrinsics; pub use core::iter; diff --git a/core/sr-version/src/lib.rs b/core/sr-version/src/lib.rs index ca98f3c221..24c54a739a 100644 --- a/core/sr-version/src/lib.rs +++ b/core/sr-version/src/lib.rs @@ -62,8 +62,8 @@ macro_rules! create_apis_vec { /// This triplet have different semantics and mis-interpretation could cause problems. /// In particular: bug fixes should result in an increment of `spec_version` and possibly `authoring_version`, /// absolutely not `impl_version` since they change the semantics of the runtime. -#[derive(Clone, PartialEq, Eq, Encode, Default)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize, Decode))] +#[derive(Clone, PartialEq, Eq, Encode, Default, sr_primitives::RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Decode))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] pub struct RuntimeVersion { /// Identifies the different Substrate runtimes. There'll be at least polkadot and node. @@ -147,7 +147,7 @@ impl RuntimeVersion { } #[cfg(feature = "std")] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Debug)] pub struct NativeVersion { /// Basic runtime version info. pub runtime_version: RuntimeVersion, diff --git a/core/test-runtime/src/lib.rs b/core/test-runtime/src/lib.rs index 3cb89de56f..45d86f891c 100644 --- a/core/test-runtime/src/lib.rs +++ b/core/test-runtime/src/lib.rs @@ -28,6 +28,7 @@ use codec::{Encode, Decode, Input, Error}; use primitives::{ Blake2Hasher, OpaqueMetadata, + RuntimeDebug, testing::{ ED25519, SR25519, @@ -93,8 +94,7 @@ pub fn native_version() -> NativeVersion { } /// Calls in transactions. -#[derive(Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)] pub struct Transfer { pub from: AccountId, pub to: AccountId, @@ -113,8 +113,7 @@ impl Transfer { } /// Extrinsic for test-runtime. -#[derive(Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)] pub enum Extrinsic { AuthoritiesChange(Vec), Transfer(Transfer, AccountSignature), @@ -353,8 +352,7 @@ impl_outer_origin!{ pub enum Origin for Runtime where system = srml_system {} } -#[derive(Clone, Encode, Decode, Eq, PartialEq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug)] pub struct Event; impl From for Event { diff --git a/core/trie/src/node_header.rs b/core/trie/src/node_header.rs index 50d3d87250..616273e574 100644 --- a/core/trie/src/node_header.rs +++ b/core/trie/src/node_header.rs @@ -22,7 +22,7 @@ use rstd::iter::once; /// A node header #[derive(Copy, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(primitives::RuntimeDebug)] pub(crate) enum NodeHeader { Null, Branch(bool, usize), diff --git a/node/primitives/src/lib.rs b/node/primitives/src/lib.rs index b8abdd7421..431ba17c00 100644 --- a/node/primitives/src/lib.rs +++ b/node/primitives/src/lib.rs @@ -66,4 +66,3 @@ pub type BlockId = generic::BlockId; /// Opaque, encoded, unchecked extrinsic. pub type UncheckedExtrinsic = OpaqueExtrinsic; - diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 75e1c9eefd..472dec02b8 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -85,7 +85,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 181, - impl_version: 181, + impl_version: 182, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/authorship/src/lib.rs b/srml/authorship/src/lib.rs index b42104a26b..173af5f729 100644 --- a/srml/authorship/src/lib.rs +++ b/srml/authorship/src/lib.rs @@ -195,8 +195,8 @@ where } } -#[derive(Encode, Decode)] -#[cfg_attr(any(feature = "std", test), derive(PartialEq, Debug))] +#[derive(Encode, Decode, sr_primitives::RuntimeDebug)] +#[cfg_attr(any(feature = "std", test), derive(PartialEq))] enum UncleEntryItem { InclusionHeight(BlockNumber), Uncle(Hash, Option), diff --git a/srml/balances/src/lib.rs b/srml/balances/src/lib.rs index b0b0a60efa..3c354da508 100644 --- a/srml/balances/src/lib.rs +++ b/srml/balances/src/lib.rs @@ -148,7 +148,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use rstd::prelude::*; -use rstd::{cmp, result, mem}; +use rstd::{cmp, result, mem, fmt::Debug}; use codec::{Codec, Encode, Decode}; use support::{ StorageValue, Parameter, decl_event, decl_storage, decl_module, @@ -160,8 +160,9 @@ use support::{ dispatch::Result, }; use sr_primitives::{ + RuntimeDebug, traits::{ - Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub, MaybeSerializeDebug, + Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub, MaybeSerializeDeserialize, Saturating, Bounded, }, weights::SimpleDispatchInfo, @@ -176,7 +177,7 @@ pub use self::imbalances::{PositiveImbalance, NegativeImbalance}; pub trait Subtrait: system::Trait { /// The balance of an account. type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + - MaybeSerializeDebug + From; + MaybeSerializeDeserialize + Debug + From; /// A function that is invoked when the free-balance has fallen below the existential deposit and /// has been reduced to zero. @@ -200,7 +201,7 @@ pub trait Subtrait: system::Trait { pub trait Trait: system::Trait { /// The balance of an account. type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + - MaybeSerializeDebug + From; + MaybeSerializeDeserialize + Debug + From; /// A function that is invoked when the free-balance has fallen below the existential deposit and /// has been reduced to zero. @@ -255,8 +256,7 @@ decl_event!( ); /// Struct to encode the vesting schedule of an individual account. -#[derive(Encode, Decode, Copy, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, RuntimeDebug)] pub struct VestingSchedule { /// Locked amount at genesis. pub locked: Balance, @@ -283,8 +283,7 @@ impl Ves } } -#[derive(Encode, Decode, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] pub struct BalanceLock { pub id: LockIdentifier, pub amount: Balance, @@ -772,7 +771,7 @@ impl, I: Instance> Trait for ElevatedTrait { impl, I: Instance> Currency for Module where - T::Balance: MaybeSerializeDebug + T::Balance: MaybeSerializeDeserialize + Debug { type Balance = T::Balance; type PositiveImbalance = PositiveImbalance; @@ -1009,7 +1008,7 @@ where impl, I: Instance> ReservableCurrency for Module where - T::Balance: MaybeSerializeDebug + T::Balance: MaybeSerializeDeserialize + Debug { fn can_reserve(who: &T::AccountId, value: Self::Balance) -> bool { Self::free_balance(who) @@ -1072,7 +1071,7 @@ where impl, I: Instance> LockableCurrency for Module where - T::Balance: MaybeSerializeDebug + T::Balance: MaybeSerializeDeserialize + Debug { type Moment = T::BlockNumber; @@ -1146,7 +1145,7 @@ where impl, I: Instance> IsDeadAccount for Module where - T::Balance: MaybeSerializeDebug + T::Balance: MaybeSerializeDeserialize + Debug { fn is_dead_account(who: &T::AccountId) -> bool { Self::total_balance(who).is_zero() diff --git a/srml/collective/src/lib.rs b/srml/collective/src/lib.rs index a965230246..37c1482f9b 100644 --- a/srml/collective/src/lib.rs +++ b/srml/collective/src/lib.rs @@ -25,6 +25,7 @@ use rstd::{prelude::*, result}; use primitives::u32_trait::Value as U32; +use sr_primitives::RuntimeDebug; use sr_primitives::traits::{Hash, EnsureOrigin}; use sr_primitives::weights::SimpleDispatchInfo; use support::{ @@ -55,8 +56,7 @@ pub trait Trait: system::Trait { } /// Origin for the collective module. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Clone, RuntimeDebug)] pub enum RawOrigin { /// It has been condoned by a given number of members of the collective from a given total. Members(MemberCount, MemberCount), @@ -69,8 +69,7 @@ pub enum RawOrigin { /// Origin for the collective module. pub type Origin = RawOrigin<::AccountId, I>; -#[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] /// Info for keeping track of a motion being voted on. pub struct Votes { /// The proposal's unique index. diff --git a/srml/contracts/rpc/runtime-api/Cargo.toml b/srml/contracts/rpc/runtime-api/Cargo.toml index fce82aed2a..2a36ed2c96 100644 --- a/srml/contracts/rpc/runtime-api/Cargo.toml +++ b/srml/contracts/rpc/runtime-api/Cargo.toml @@ -9,6 +9,7 @@ client = { package = "substrate-client", path = "../../../../core/client", defau codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", path = "../../../../core/sr-std", default-features = false } serde = { version = "1.0.101", optional = true, features = ["derive"] } +sr-primitives = { path = "../../../../core/sr-primitives", default-features = false } [features] default = ["std"] @@ -17,4 +18,5 @@ std = [ "codec/std", "rstd/std", "serde", + "sr-primitives/std", ] diff --git a/srml/contracts/rpc/runtime-api/src/lib.rs b/srml/contracts/rpc/runtime-api/src/lib.rs index a5b56888ce..7f01b8bdfa 100644 --- a/srml/contracts/rpc/runtime-api/src/lib.rs +++ b/srml/contracts/rpc/runtime-api/src/lib.rs @@ -24,10 +24,11 @@ use rstd::vec::Vec; use codec::{Encode, Decode, Codec}; +use sr_primitives::RuntimeDebug; /// A result of execution of a contract. -#[derive(Eq, PartialEq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, serde::Serialize, serde::Deserialize))] +#[derive(Eq, PartialEq, Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub enum ContractExecResult { /// The contract returned successfully. /// diff --git a/srml/contracts/src/exec.rs b/srml/contracts/src/exec.rs index f85797378f..af79c6c818 100644 --- a/srml/contracts/src/exec.rs +++ b/srml/contracts/src/exec.rs @@ -60,7 +60,7 @@ impl ExecReturnValue { /// VM-specific errors during execution (eg. division by 0, OOB access, failure to satisfy some /// precondition of a system call, etc.) or errors with the orchestration (eg. out-of-gas errors, a /// non-existent destination contract, etc.). -#[cfg_attr(test, derive(Debug))] +#[cfg_attr(test, derive(sr_primitives::RuntimeDebug))] pub struct ExecError { pub reason: &'static str, /// This is an allocated buffer that may be reused. The buffer must be cleared explicitly @@ -231,7 +231,8 @@ impl Token for ExecFeeToken { } } -#[cfg_attr(any(feature = "std", test), derive(Debug, PartialEq, Eq, Clone))] +#[cfg_attr(any(feature = "std", test), derive(PartialEq, Eq, Clone))] +#[derive(sr_primitives::RuntimeDebug)] pub enum DeferredAction { DepositEvent { /// A list of topics this event will be deposited with. diff --git a/srml/contracts/src/lib.rs b/srml/contracts/src/lib.rs index b3c8c9b764..4346211ab6 100644 --- a/srml/contracts/src/lib.rs +++ b/srml/contracts/src/lib.rs @@ -109,15 +109,16 @@ pub use crate::exec::{ExecResult, ExecReturnValue, ExecError, StatusCode}; #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; use primitives::crypto::UncheckedFrom; -use rstd::{prelude::*, marker::PhantomData}; +use rstd::{prelude::*, marker::PhantomData, fmt::Debug}; use codec::{Codec, Encode, Decode}; use runtime_io::blake2_256; use sr_primitives::{ - traits::{Hash, StaticLookup, Zero, MaybeSerializeDebug, Member, SignedExtension}, + traits::{Hash, StaticLookup, Zero, MaybeSerializeDeserialize, Member, SignedExtension}, weights::DispatchInfo, transaction_validity::{ ValidTransaction, InvalidTransaction, TransactionValidity, TransactionValidityError, }, + RuntimeDebug, }; use support::dispatch::{Result, Dispatchable}; use support::{ @@ -143,8 +144,7 @@ pub trait ComputeDispatchFee { /// Information for managing an acocunt and its sub trie abstraction. /// This is the required info to cache for an account -#[derive(Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, RuntimeDebug)] pub enum ContractInfo { Alive(AliveContractInfo), Tombstone(TombstoneContractInfo), @@ -207,9 +207,7 @@ pub type AliveContractInfo = /// Information for managing an account and its sub trie abstraction. /// This is the required info to cache for an account. -// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. -#[derive(Encode, Decode, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] pub struct RawAliveContractInfo { /// Unique ID for the subtree encoded as a bytes vector. pub trie_id: TrieId, @@ -228,15 +226,14 @@ pub struct RawAliveContractInfo { pub type TombstoneContractInfo = RawTombstoneContractInfo<::Hash, ::Hashing>; -// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. -#[derive(Encode, Decode, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, PartialEq, Eq, RuntimeDebug)] pub struct RawTombstoneContractInfo(H, PhantomData); impl RawTombstoneContractInfo where - H: Member + MaybeSerializeDebug + AsRef<[u8]> + AsMut<[u8]> + Copy + Default + rstd::hash::Hash - + Codec, + H: Member + MaybeSerializeDeserialize+ Debug + + AsRef<[u8]> + AsMut<[u8]> + Copy + Default + + rstd::hash::Hash + Codec, Hasher: Hash, { fn new(storage_root: &[u8], code_hash: H) -> Self { @@ -891,8 +888,8 @@ impl Config { } /// Definition of the cost schedule and other parameterizations for wasm vm. -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -#[derive(Clone, Encode, Decode, PartialEq, Eq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug)] pub struct Schedule { /// Version of the schedule. pub version: u32, @@ -988,9 +985,14 @@ impl Default for CheckBlockGasLimit { } } -#[cfg(feature = "std")] -impl std::fmt::Debug for CheckBlockGasLimit { - fn fmt(&self, _: &mut std::fmt::Formatter) -> std::fmt::Result { +impl rstd::fmt::Debug for CheckBlockGasLimit { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + write!(f, "CheckBlockGasLimit") + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { Ok(()) } } diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index af145828ab..f1f10a7319 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -21,6 +21,7 @@ use rstd::prelude::*; use rstd::{result, convert::TryFrom}; use sr_primitives::{ + RuntimeDebug, traits::{Zero, Bounded, CheckedMul, CheckedDiv, EnsureOrigin, Hash, Dispatchable}, weights::SimpleDispatchInfo, }; @@ -48,8 +49,7 @@ pub type PropIndex = u32; pub type ReferendumIndex = u32; /// A value denoting the strength of conviction of a vote. -#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug)] pub enum Conviction { /// 0.1x votes, unlocked. None, @@ -148,8 +148,7 @@ impl Bounded for Conviction { const MAX_RECURSION_LIMIT: u32 = 16; /// A number of lock periods, plus a vote, one way or the other. -#[derive(Copy, Clone, Eq, PartialEq, Default)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Copy, Clone, Eq, PartialEq, Default, RuntimeDebug)] pub struct Vote { pub aye: bool, pub conviction: Conviction, @@ -231,8 +230,7 @@ pub trait Trait: system::Trait + Sized { } /// Info regarding an ongoing referendum. -#[derive(Encode, Decode, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] pub struct ReferendumInfo { /// When voting on this referendum will end. end: BlockNumber, diff --git a/srml/democracy/src/vote_threshold.rs b/srml/democracy/src/vote_threshold.rs index d304c36f32..61e7e65359 100644 --- a/srml/democracy/src/vote_threshold.rs +++ b/srml/democracy/src/vote_threshold.rs @@ -23,8 +23,8 @@ use sr_primitives::traits::{Zero, IntegerSquareRoot}; use rstd::ops::{Add, Mul, Div, Rem}; /// A means of determining if a vote is past pass threshold. -#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] +#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, sr_primitives::RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum VoteThreshold { /// A supermajority of approvals is needed to pass this vote. SuperMajorityApprove, diff --git a/srml/elections/src/lib.rs b/srml/elections/src/lib.rs index 439be7e76c..87e29f3b14 100644 --- a/srml/elections/src/lib.rs +++ b/srml/elections/src/lib.rs @@ -25,7 +25,10 @@ use rstd::prelude::*; use sr_primitives::{ - print, traits::{Zero, One, StaticLookup, Bounded, Saturating}, weights::SimpleDispatchInfo, + RuntimeDebug, + print, + traits::{Zero, One, StaticLookup, Bounded, Saturating}, + weights::SimpleDispatchInfo, }; use support::{ dispatch::Result, decl_storage, decl_event, ensure, decl_module, @@ -98,8 +101,7 @@ mod tests; // entries before they increase the capacity. /// The activity status of a voter. -#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, Default)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, Default, RuntimeDebug)] pub struct VoterInfo { /// Last VoteIndex in which this voter assigned (or initialized) approvals. last_active: VoteIndex, @@ -114,8 +116,7 @@ pub struct VoterInfo { } /// Used to demonstrate the status of a particular index in the global voter list. -#[derive(PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, RuntimeDebug)] pub enum CellStatus { /// Any out of bound index. Means a push a must happen to the chunk pointed by `NextVoterSet`. /// Voting fee is applied in case a new chunk is created. diff --git a/srml/example/src/lib.rs b/srml/example/src/lib.rs index bc85241456..c9d9d93cc7 100644 --- a/srml/example/src/lib.rs +++ b/srml/example/src/lib.rs @@ -584,10 +584,9 @@ impl Module { #[derive(Encode, Decode, Clone, Eq, PartialEq)] pub struct WatchDummy(PhantomData); -#[cfg(feature = "std")] impl rstd::fmt::Debug for WatchDummy { fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { - write!(f, "WatchDummy") + write!(f, "WatchDummy") } } diff --git a/srml/generic-asset/src/lib.rs b/srml/generic-asset/src/lib.rs index 12e9d2cbf6..fdbb57f56f 100644 --- a/srml/generic-asset/src/lib.rs +++ b/srml/generic-asset/src/lib.rs @@ -153,12 +153,13 @@ use codec::{Decode, Encode, HasCompact, Input, Output, Error}; +use sr_primitives::RuntimeDebug; use sr_primitives::traits::{ - CheckedAdd, CheckedSub, MaybeSerializeDebug, Member, One, Saturating, SimpleArithmetic, Zero, Bounded + CheckedAdd, CheckedSub, MaybeSerializeDeserialize, Member, One, Saturating, SimpleArithmetic, Zero, Bounded }; use rstd::prelude::*; -use rstd::{cmp, result}; +use rstd::{cmp, result, fmt::Debug}; use support::dispatch::Result; use support::{ decl_event, decl_module, decl_storage, ensure, @@ -181,7 +182,8 @@ pub trait Trait: system::Trait { + SimpleArithmetic + Default + Copy - + MaybeSerializeDebug; + + MaybeSerializeDeserialize + + Debug; type AssetId: Parameter + Member + SimpleArithmetic + Default + Copy; type Event: From> + Into<::Event>; } @@ -192,7 +194,8 @@ pub trait Subtrait: system::Trait { + SimpleArithmetic + Default + Copy - + MaybeSerializeDebug; + + MaybeSerializeDeserialize + + Debug; type AssetId: Parameter + Member + SimpleArithmetic + Default + Copy; } @@ -202,8 +205,7 @@ impl Subtrait for T { } /// Asset creation options. -#[cfg_attr(feature = "std", derive(Debug))] -#[derive(Clone, Encode, Decode, PartialEq, Eq)] +#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug)] pub struct AssetOptions { /// Initial issuance of this asset. All deposit to the creater of the asset. #[codec(compact)] @@ -213,8 +215,7 @@ pub struct AssetOptions { } /// Owner of an asset. -#[cfg_attr(feature = "std", derive(Debug))] -#[derive(Clone, Encode, Decode, PartialEq, Eq)] +#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug)] pub enum Owner { /// No owner. None, @@ -229,8 +230,7 @@ impl Default for Owner { } /// Asset permissions -#[cfg_attr(feature = "std", derive(Debug))] -#[derive(Clone, Encode, Decode, PartialEq, Eq)] +#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug)] pub struct PermissionsV1 { /// Who have permission to update asset permission pub update: Owner, @@ -240,16 +240,14 @@ pub struct PermissionsV1 { pub burn: Owner, } -#[cfg_attr(feature = "std", derive(Debug))] -#[derive(Clone, Encode, Decode, PartialEq, Eq)] +#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug)] #[repr(u8)] enum PermissionVersionNumber { V1 = 0, } /// Versioned asset permission -#[cfg_attr(feature = "std", derive(Debug))] -#[derive(Clone, PartialEq, Eq)] +#[derive(Clone, PartialEq, Eq, RuntimeDebug)] pub enum PermissionVersions { V1(PermissionsV1), } @@ -435,8 +433,7 @@ decl_module! { } } -#[derive(Encode, Decode, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] pub struct BalanceLock { pub id: LockIdentifier, pub amount: Balance, @@ -1065,8 +1062,7 @@ impl Trait for ElevatedTrait { type Event = (); } -#[derive(Encode, Decode, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] pub struct AssetCurrency(rstd::marker::PhantomData, rstd::marker::PhantomData); impl Currency for AssetCurrency @@ -1200,7 +1196,9 @@ where Self::free_balance(who) .checked_sub(&value) .map_or(false, |new_balance| - >::ensure_can_withdraw(&U::asset_id(), who, value, WithdrawReason::Reserve, new_balance).is_ok() + >::ensure_can_withdraw( + &U::asset_id(), who, value, WithdrawReason::Reserve, new_balance + ).is_ok() ) } @@ -1254,7 +1252,7 @@ impl AssetIdProvider for SpendingAssetIdProvider { impl LockableCurrency for AssetCurrency> where T: Trait, - T::Balance: MaybeSerializeDebug, + T::Balance: MaybeSerializeDeserialize + Debug, { type Moment = T::BlockNumber; diff --git a/srml/im-online/src/lib.rs b/srml/im-online/src/lib.rs index 1a75cebd2e..202507bef9 100644 --- a/srml/im-online/src/lib.rs +++ b/srml/im-online/src/lib.rs @@ -76,6 +76,7 @@ use primitives::offchain::{OpaqueNetworkState, StorageKind}; use rstd::prelude::*; use session::historical::IdentificationTuple; use sr_primitives::{ + RuntimeDebug, traits::{Convert, Member, Printable, Saturating}, Perbill, transaction_validity::{ TransactionValidity, TransactionLongevity, ValidTransaction, InvalidTransaction, @@ -86,7 +87,7 @@ use sr_staking_primitives::{ offence::{ReportOffence, Offence, Kind}, }; use support::{ - decl_module, decl_event, decl_storage, print, ensure, Parameter + decl_module, decl_event, decl_storage, print, ensure, Parameter, debug }; use system::ensure_none; use system::offchain::SubmitUnsignedTransaction; @@ -146,15 +147,14 @@ const DB_KEY: &[u8] = b"srml/im-online-worker-status"; /// finishing it. With every execution of the off-chain worker we check /// if we need to recover and resume gossipping or if there is already /// another off-chain worker in the process of gossipping. -#[derive(Encode, Decode, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] struct WorkerStatus { done: bool, gossipping_at: BlockNumber, } /// Error which may occur while executing the off-chain code. -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(RuntimeDebug)] enum OffchainErr { DecodeWorkerStatus, FailedSigning, @@ -176,8 +176,7 @@ impl Printable for OffchainErr { pub type AuthIndex = u32; /// Heartbeat which is sent/received. -#[derive(Encode, Decode, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] pub struct Heartbeat where BlockNumber: PartialEq + Eq + Decode + Encode, { @@ -280,6 +279,8 @@ decl_module! { // Runs after every block. fn offchain_worker(now: T::BlockNumber) { + debug::RuntimeLogger::init(); + // Only send messages if we are a potential validator. if runtime_io::is_validator() { Self::offchain(now); @@ -319,6 +320,14 @@ impl Module { Ok(_) => {}, Err(err) => print(err), } + } else { + debug::native::trace!( + target: "imonline", + "Skipping gossip at: {:?} >= {:?} || {:?}", + next_gossip, + now, + if not_yet_gossipped { "not gossipped" } else { "gossipped" } + ); } } @@ -346,6 +355,13 @@ impl Module { let signature = key.sign(&heartbeat_data.encode()).ok_or(OffchainErr::FailedSigning)?; let call = Call::heartbeat(heartbeat_data, signature); + + debug::info!( + target: "imonline", + "[index: {:?}] Reporting im-online at block: {:?}", + authority_index, + block_number + ); T::SubmitTransaction::submit_unsigned(call) .map_err(|_| OffchainErr::SubmitTransaction)?; @@ -538,7 +554,8 @@ impl support::unsigned::ValidateUnsigned for Module { } /// An offence that is filed if a validator didn't send a heartbeat message. -#[cfg_attr(feature = "std", derive(Clone, Debug, PartialEq, Eq))] +#[derive(RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Clone, PartialEq, Eq))] pub struct UnresponsivenessOffence { /// The current session index in which we report the unresponsive validators. /// diff --git a/srml/indices/src/address.rs b/srml/indices/src/address.rs index caef4728fb..21ee654cf2 100644 --- a/srml/indices/src/address.rs +++ b/srml/indices/src/address.rs @@ -24,8 +24,8 @@ use codec::{Encode, Decode, Input, Output, Error}; /// An indices-aware address, which can be either a direct `AccountId` or /// an index. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Debug, Hash))] +#[derive(PartialEq, Eq, Clone, sr_primitives::RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Hash))] pub enum Address where AccountId: Member, AccountIndex: Member, diff --git a/srml/metadata/src/lib.rs b/srml/metadata/src/lib.rs index 244d117564..d85a6837fc 100644 --- a/srml/metadata/src/lib.rs +++ b/srml/metadata/src/lib.rs @@ -28,6 +28,7 @@ use serde::Serialize; use codec::{Decode, Input, Error}; use codec::{Encode, Output}; use rstd::vec::Vec; +use primitives::RuntimeDebug; #[cfg(feature = "std")] type StringBuf = String; @@ -84,13 +85,12 @@ impl Eq for DecodeDifferent where B: Encode + Eq + PartialEq + 'static, O: Encode + Eq + PartialEq + 'static {} -#[cfg(feature = "std")] -impl std::fmt::Debug for DecodeDifferent +impl rstd::fmt::Debug for DecodeDifferent where - B: std::fmt::Debug + Eq + 'static, - O: std::fmt::Debug + Eq + 'static, + B: rstd::fmt::Debug + Eq + 'static, + O: rstd::fmt::Debug + Eq + 'static, { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { match self { DecodeDifferent::Encode(b) => b.fmt(f), DecodeDifferent::Decoded(o) => o.fmt(f), @@ -114,14 +114,11 @@ impl serde::Serialize for DecodeDifferent pub type DecodeDifferentArray = DecodeDifferent<&'static [B], Vec>; -#[cfg(feature = "std")] -type DecodeDifferentStr = DecodeDifferent<&'static str, StringBuf>; -#[cfg(not(feature = "std"))] type DecodeDifferentStr = DecodeDifferent<&'static str, StringBuf>; /// All the metadata about a function. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct FunctionMetadata { pub name: DecodeDifferentStr, pub arguments: DecodeDifferentArray, @@ -129,8 +126,8 @@ pub struct FunctionMetadata { } /// All the metadata about a function argument. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct FunctionArgumentMetadata { pub name: DecodeDifferentStr, pub ty: DecodeDifferentStr, @@ -154,9 +151,8 @@ impl PartialEq for FnEncode { } } -#[cfg(feature = "std")] -impl std::fmt::Debug for FnEncode { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl rstd::fmt::Debug for FnEncode { + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { self.0().fmt(f) } } @@ -169,8 +165,8 @@ impl serde::Serialize for FnEncode { } /// All the metadata about an outer event. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct OuterEventMetadata { pub name: DecodeDifferentStr, pub events: DecodeDifferentArray< @@ -180,8 +176,8 @@ pub struct OuterEventMetadata { } /// All the metadata about an event. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct EventMetadata { pub name: DecodeDifferentStr, pub arguments: DecodeDifferentArray<&'static str, StringBuf>, @@ -189,8 +185,8 @@ pub struct EventMetadata { } /// All the metadata about one storage entry. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct StorageEntryMetadata { pub name: DecodeDifferentStr, pub modifier: StorageEntryModifier, @@ -200,8 +196,8 @@ pub struct StorageEntryMetadata { } /// All the metadata about one module constant. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct ModuleConstantMetadata { pub name: DecodeDifferentStr, pub ty: DecodeDifferentStr, @@ -210,8 +206,8 @@ pub struct ModuleConstantMetadata { } /// All the metadata about a module error. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct ErrorMetadata { pub name: DecodeDifferentStr, pub documentation: DecodeDifferentArray<&'static str, StringBuf>, @@ -265,16 +261,15 @@ impl serde::Serialize for DefaultByteGetter { } } -#[cfg(feature = "std")] -impl std::fmt::Debug for DefaultByteGetter { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl rstd::fmt::Debug for DefaultByteGetter { + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { self.0.default_byte().fmt(f) } } /// Hasher used by storage maps -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub enum StorageHasher { Blake2_128, Blake2_256, @@ -284,8 +279,8 @@ pub enum StorageHasher { } /// A storage entry type. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub enum StorageEntryType { Plain(DecodeDifferentStr), Map { @@ -304,32 +299,32 @@ pub enum StorageEntryType { } /// A storage entry modifier. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub enum StorageEntryModifier { Optional, Default, } /// All metadata of the storage. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct StorageMetadata { /// The common prefix used by all storage entries. pub prefix: DecodeDifferent<&'static str, StringBuf>, pub entries: DecodeDifferent<&'static [StorageEntryMetadata], Vec>, } -#[derive(Eq, Encode, PartialEq)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] /// Metadata prefixed by a u32 for reserved usage pub struct RuntimeMetadataPrefixed(pub u32, pub RuntimeMetadata); /// The metadata of a runtime. /// The version ID encoded/decoded through /// the enum nature of `RuntimeMetadata`. -#[derive(Eq, Encode, PartialEq)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub enum RuntimeMetadata { /// Unused; enum filler. V0(RuntimeMetadataDeprecated), @@ -352,8 +347,8 @@ pub enum RuntimeMetadata { } /// Enum that should fail. -#[derive(Eq, PartialEq)] -#[cfg_attr(feature = "std", derive(Debug, Serialize))] +#[derive(Eq, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize))] pub enum RuntimeMetadataDeprecated { } impl Encode for RuntimeMetadataDeprecated { @@ -370,8 +365,8 @@ impl Decode for RuntimeMetadataDeprecated { } /// The metadata of a runtime. -#[derive(Eq, Encode, PartialEq)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct RuntimeMetadataV8 { pub modules: DecodeDifferentArray, } @@ -380,8 +375,8 @@ pub struct RuntimeMetadataV8 { pub type RuntimeMetadataLastVersion = RuntimeMetadataV8; /// All metadata about an runtime module. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] pub struct ModuleMetadata { pub name: DecodeDifferentStr, pub storage: Option, StorageMetadata>>, diff --git a/srml/scored-pool/src/lib.rs b/srml/scored-pool/src/lib.rs index fa18d899e2..5fde1e9c45 100644 --- a/srml/scored-pool/src/lib.rs +++ b/srml/scored-pool/src/lib.rs @@ -89,14 +89,17 @@ mod mock; mod tests; use codec::FullCodec; -use rstd::prelude::*; +use rstd::{ + fmt::Debug, + prelude::*, +}; use support::{ decl_module, decl_storage, decl_event, ensure, traits::{ChangeMembers, InitializeMembers, Currency, Get, ReservableCurrency}, }; use system::{self, ensure_root, ensure_signed}; use sr_primitives::{ - traits::{EnsureOrigin, SimpleArithmetic, MaybeSerializeDebug, Zero, StaticLookup}, + traits::{EnsureOrigin, SimpleArithmetic, MaybeSerializeDeserialize, Zero, StaticLookup}, }; type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; @@ -117,7 +120,8 @@ pub trait Trait: system::Trait { type Currency: Currency + ReservableCurrency; /// The score attributed to a member or candidate. - type Score: SimpleArithmetic + Clone + Copy + Default + FullCodec + MaybeSerializeDebug; + type Score: + SimpleArithmetic + Clone + Copy + Default + FullCodec + MaybeSerializeDeserialize + Debug; /// The overarching event type. type Event: From> + Into<::Event>; diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index 013aed2729..e7d7c073a1 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -263,6 +263,7 @@ use support::{ use session::{historical::OnSessionEnding, SelectInitialValidators}; use sr_primitives::{ Perbill, + RuntimeDebug, curve::PiecewiseLinear, weights::SimpleDispatchInfo, traits::{ @@ -313,7 +314,8 @@ impl EraPoints { } /// Indicates the initial status of the staker. -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[derive(RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum StakerStatus { /// Chilling. Idle, @@ -324,8 +326,7 @@ pub enum StakerStatus { } /// A destination account for payment. -#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, RuntimeDebug)] pub enum RewardDestination { /// Pay into the stash account, increasing the amount at stake accordingly. Staked, @@ -342,8 +343,7 @@ impl Default for RewardDestination { } /// Preference of what happens on a slash event. -#[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] pub struct ValidatorPrefs { /// Reward that validator takes up-front; only the rest is split between themselves and /// nominators. @@ -360,8 +360,7 @@ impl Default for ValidatorPrefs { } /// Just a Balance/BlockNumber tuple to encode when a chunk of funds will be unlocked. -#[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] pub struct UnlockChunk { /// Amount of funds to be unlocked. #[codec(compact)] @@ -372,8 +371,7 @@ pub struct UnlockChunk { } /// The ledger of a (bonded) stash. -#[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] pub struct StakingLedger { /// The stash account whose balance is actually locked and at stake. pub stash: AccountId, @@ -411,8 +409,7 @@ impl< } /// The amount of exposure (to slashing) than an individual nominator has. -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, RuntimeDebug)] pub struct IndividualExposure { /// The stash account of the nominator in question. who: AccountId, @@ -422,8 +419,7 @@ pub struct IndividualExposure { } /// A snapshot of the stake backing a single validator in the system. -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, RuntimeDebug)] pub struct Exposure { /// The total balance backing this validator. #[codec(compact)] @@ -436,8 +432,7 @@ pub struct Exposure { } /// A slashing event occurred, slashing a validator for a given amount of balance. -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, RuntimeDebug)] pub struct SlashJournalEntry { who: AccountId, amount: Balance, @@ -532,8 +527,8 @@ pub trait Trait: system::Trait { } /// Mode of era-forcing. -#[derive(Copy, Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[derive(Copy, Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum Forcing { /// Not forcing anything - just let whatever happen. NotForcing, diff --git a/srml/support/Cargo.toml b/srml/support/Cargo.toml index 79a3beb6dc..2b8c4cb9f9 100644 --- a/srml/support/Cargo.toml +++ b/srml/support/Cargo.toml @@ -5,6 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] +log = "0.4" serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.6", default-features = false, features = ["derive"] } srml-metadata = { path = "../metadata", default-features = false } diff --git a/srml/support/procedural/src/storage/instance_trait.rs b/srml/support/procedural/src/storage/instance_trait.rs index fe81dfe0db..1a7add89a4 100644 --- a/srml/support/procedural/src/storage/instance_trait.rs +++ b/srml/support/procedural/src/storage/instance_trait.rs @@ -184,8 +184,12 @@ fn create_and_impl_instance_struct( quote! { // Those trait are derived because of wrong bounds for generics - #[cfg_attr(feature = "std", derive(Debug))] - #[derive(Clone, Eq, PartialEq, #scrate::codec::Encode, #scrate::codec::Decode)] + #[derive( + Clone, Eq, PartialEq, + #scrate::codec::Encode, + #scrate::codec::Decode, + #scrate::RuntimeDebug, + )] #doc pub struct #instance_struct; impl #instance_trait for #instance_struct { diff --git a/srml/support/src/debug.rs b/srml/support/src/debug.rs new file mode 100644 index 0000000000..1c4e463bf1 --- /dev/null +++ b/srml/support/src/debug.rs @@ -0,0 +1,209 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Runtime debugging and logging utilities. +//! +//! This module contains macros and functions that will allow +//! you to print logs out of the runtime code. +//! +//! First and foremost be aware that adding regular logging code to +//! your runtime will have a negative effect on the performance +//! and size of the blob. Luckily there are some ways to mitigate +//! this that are described below. +//! +//! First component to utilize debug-printing and loggin is actually +//! located in `primitives` crate: `primitives::RuntimeDebug`. +//! This custom-derive generates `core::fmt::Debug` implementation, +//! just like regular `derive(Debug)`, however it does not generate +//! any code when the code is compiled to WASM. This means that +//! you can safely sprinkle `RuntimeDebug` in your runtime codebase, +//! without affecting the size. This also allows you to print/log +//! both when the code is running natively or in WASM, but note +//! that WASM debug formatting of structs will be empty. +//! +//! ```rust,no_run +//! use srml_support::debug; +//! +//! #[derive(primitives::RuntimeDebug)] +//! struct MyStruct { +//! a: u64, +//! } +//! +//! // First initialize the logger. +//! // +//! // This is only required when you want the logs to be printed +//! // also during non-native run. +//! // Note that enabling the logger has performance impact on +//! // WASM runtime execution and should be used sparingly. +//! debug::RuntimeLogger::init(); +//! +//! let x = MyStruct { a: 5 }; +//! // will log an info line `"My struct: MyStruct{a:5}"` when running +//! // natively, but will only print `"My struct: "` when running WASM. +//! debug::info!("My struct: {:?}", x); +//! +//! // same output here, although this will print to stdout +//! // (and without log format) +//! debug::print!("My struct: {:?}", x); +//! ``` +//! +//! If you want to avoid extra overhead in WASM, but still be able +//! to print / log when the code is executed natively you can use +//! macros coming from `native` sub-module. This module enables +//! logs conditionally and strips out logs in WASM. +//! +//! ```rust,no_run +//! use srml_support::debug::native; +//! +//! #[derive(primitives::RuntimeDebug)] +//! struct MyStruct { +//! a: u64, +//! } +//! +//! // We don't initialize the logger, since +//! // we are not printing anything out in WASM. +//! // debug::RuntimeLogger::init(); +//! +//! let x = MyStruct { a: 5 }; +//! +//! // Displays an info log when running natively, nothing when WASM. +//! native::info!("My struct: {:?}", x); +//! +//! // same output to stdout, no overhead on WASM. +//! native::print!("My struct: {:?}", x); +//! ``` + +use rstd::vec::Vec; +use rstd::fmt::{self, Debug}; + +pub use log::{info, debug, error, trace, warn}; +pub use crate::runtime_print as print; + +/// Native-only logging. +/// +/// Using any functions from this module will have any effect +/// only if the runtime is running natively (i.e. not via WASM) +#[cfg(feature = "std")] +pub mod native { + pub use super::{info, debug, error, trace, warn, print}; +} + +/// Native-only logging. +/// +/// Using any functions from this module will have any effect +/// only if the runtime is running natively (i.e. not via WASM) +#[cfg(not(feature = "std"))] +pub mod native { + #[macro_export] + macro_rules! noop { + ($($arg:tt)+) => {} + } + pub use noop as info; + pub use noop as debug; + pub use noop as error; + pub use noop as trace; + pub use noop as warn; + pub use noop as print; +} + +/// Print out a formatted message. +#[macro_export] +macro_rules! runtime_print { + ($($arg:tt)+) => { + use core::fmt::Write; + let mut w = $crate::debug::Writer::default(); + let _ = core::write!(&mut w, $($arg)+); + w.print(); + } +} + +/// Print out the debuggable type. +pub fn debug(data: &impl Debug) { + runtime_print!("{:?}", data); +} + +/// A target for `core::write!` macro - constructs a string in memory. +#[derive(Default)] +pub struct Writer(Vec); + +impl fmt::Write for Writer { + fn write_str(&mut self, s: &str) -> fmt::Result { + self.0.extend(s.as_bytes()); + Ok(()) + } +} + +impl Writer { + /// Print the content of this `Writer` out. + pub fn print(&self) { + runtime_io::print_utf8(&self.0) + } +} + +/// Runtime logger implementation - `log` crate backend. +/// +/// The logger should be initialized if you want to display +/// logs inside the runtime that is not necessarily running natively. +/// +/// When runtime is executed natively any log statements are displayed +/// even if this logger is NOT initialized. +/// +/// Note that even though the logs are not displayed in WASM, they +/// may still affect the size and performance of the generated runtime. +/// To lower the footprint make sure to only use macros from `native` +/// sub-module. +pub struct RuntimeLogger; + +impl RuntimeLogger { + /// Initialize the logger. + /// + /// This is a no-op when running natively (`std`). + #[cfg(feature = "std")] + pub fn init() {} + + /// Initialize the logger. + /// + /// This is a no-op when running natively (`std`). + #[cfg(not(feature = "std"))] + pub fn init() { + static LOGGER: RuntimeLogger = RuntimeLogger;; + let _ = log::set_logger(&LOGGER); + } +} + +impl log::Log for RuntimeLogger { + fn enabled(&self, _metadata: &log::Metadata) -> bool { + // to avoid calling to host twice, we pass everything + // and let the host decide what to print. + // If someone is initializing the logger they should + // know what they are doing. + true + } + + fn log(&self, record: &log::Record) { + use fmt::Write; + let mut w = Writer::default(); + let _ = core::write!(&mut w, "{}", record.args()); + + runtime_io::log( + record.level().into(), + record.target().as_bytes(), + &w.0, + ); + } + + fn flush(&self) {} +} diff --git a/srml/support/src/dispatch.rs b/srml/support/src/dispatch.rs index fd24c257ae..df86f43611 100644 --- a/srml/support/src/dispatch.rs +++ b/srml/support/src/dispatch.rs @@ -17,9 +17,7 @@ //! Dispatch system. Contains a macro for defining runtime modules and //! generating values representing lazy module function calls. -pub use crate::rstd::{result, prelude::{Vec, Clone, Eq, PartialEq}, marker}; -#[cfg(feature = "std")] -pub use std::fmt; +pub use crate::rstd::{result, fmt, prelude::{Vec, Clone, Eq, PartialEq}, marker}; pub use crate::codec::{Codec, EncodeLike, Decode, Encode, Input, Output, HasCompact, EncodeAsRef}; pub use srml_metadata::{ FunctionMetadata, DecodeDifferent, DecodeDifferentArray, FunctionArgumentMetadata, @@ -29,7 +27,9 @@ pub use sr_primitives::{ weights::{ SimpleDispatchInfo, GetDispatchInfo, DispatchInfo, WeighData, ClassifyDispatch, TransactionPriority - }, traits::{Dispatchable, DispatchResult, ModuleDispatchError}, DispatchError + }, + traits::{Dispatchable, DispatchResult, ModuleDispatchError}, + DispatchError, }; /// A type that cannot be instantiated. @@ -48,18 +48,9 @@ pub trait Callable { // https://github.com/rust-lang/rust/issues/51331 pub type CallableCallFor = >::Call; -#[cfg(feature = "std")] pub trait Parameter: Codec + EncodeLike + Clone + Eq + fmt::Debug {} - -#[cfg(feature = "std")] impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} -#[cfg(not(feature = "std"))] -pub trait Parameter: Codec + EncodeLike + Clone + Eq {} - -#[cfg(not(feature = "std"))] -impl Parameter for T where T: Codec + EncodeLike + Clone + Eq {} - /// Declares a `Module` struct and a `Call` enum, which implements the dispatch logic. /// /// ## Declaration @@ -1071,8 +1062,7 @@ macro_rules! decl_module { $crate::__check_reserved_fn_name! { $( $fn_name )* } // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. - #[derive(Clone, Copy, PartialEq, Eq)] - #[cfg_attr(feature = "std", derive(Debug))] + #[derive(Clone, Copy, PartialEq, Eq, $crate::RuntimeDebug)] pub struct $mod_type< $trait_instance: $trait_name $(, $instance: $instantiable $( = $module_default_instance)?)? @@ -1223,7 +1213,6 @@ macro_rules! decl_module { for $call_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )* {} - #[cfg(feature = "std")] impl<$trait_instance: $trait_name $(, $instance: $instantiable)?> $crate::dispatch::fmt::Debug for $call_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )* { @@ -1325,8 +1314,12 @@ macro_rules! impl_outer_dispatch { } ) => { $(#[$attr])* - #[derive(Clone, PartialEq, Eq, $crate::codec::Encode, $crate::codec::Decode)] - #[cfg_attr(feature = "std", derive(Debug))] + #[derive( + Clone, PartialEq, Eq, + $crate::codec::Encode, + $crate::codec::Decode, + $crate::RuntimeDebug, + )] pub enum $call_type { $( $camelcase ( $crate::dispatch::CallableCallFor<$camelcase, $runtime> ) diff --git a/srml/support/src/error.rs b/srml/support/src/error.rs index 848bd126d2..9aa13713da 100644 --- a/srml/support/src/error.rs +++ b/srml/support/src/error.rs @@ -56,8 +56,7 @@ macro_rules! decl_error { $(,)? } ) => { - #[derive(Clone, PartialEq, Eq)] - #[cfg_attr(feature = "std", derive(Debug))] + #[derive(Clone, PartialEq, Eq, $crate::RuntimeDebug)] $(#[$attr])* pub enum $error { Other(&'static str), diff --git a/srml/support/src/event.rs b/srml/support/src/event.rs index eb5cc20635..3411c93922 100644 --- a/srml/support/src/event.rs +++ b/srml/support/src/event.rs @@ -121,8 +121,12 @@ macro_rules! decl_event { } ) => { // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. - #[derive(Clone, PartialEq, Eq, $crate::codec::Encode, $crate::codec::Decode)] - #[cfg_attr(feature = "std", derive(Debug))] + #[derive( + Clone, PartialEq, Eq, + $crate::codec::Encode, + $crate::codec::Decode, + $crate::RuntimeDebug, + )] /// Events for this module. /// $(#[$attr])* @@ -260,9 +264,12 @@ macro_rules! __decl_generic_event { /// [`Trait`]: trait.Trait.html pub type Event<$event_generic_param $(, $instance $( = $event_default_instance)? )?> = RawEvent<$( $generic_type ),* $(, $instance)? >; - // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. - #[derive(Clone, PartialEq, Eq, $crate::codec::Encode, $crate::codec::Decode)] - #[cfg_attr(feature = "std", derive(Debug))] + #[derive( + Clone, PartialEq, Eq, + $crate::codec::Encode, + $crate::codec::Decode, + $crate::RuntimeDebug, + )] /// Events for this module. /// $(#[$attr])* @@ -452,8 +459,12 @@ macro_rules! impl_outer_event { $( $module_name:ident::Event $( <$generic_param:ident> )? $( { $generic_instance:ident } )?, )*; ) => { $crate::paste::item! { - #[derive(Clone, PartialEq, Eq, $crate::codec::Encode, $crate::codec::Decode)] - #[cfg_attr(feature = "std", derive(Debug))] + #[derive( + Clone, PartialEq, Eq, + $crate::codec::Encode, + $crate::codec::Decode, + $crate::RuntimeDebug, + )] $(#[$attr])* #[allow(non_camel_case_types)] pub enum $name { diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index 728749d657..2a9f66bd52 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -40,7 +40,11 @@ pub use paste; pub use runtime_io::with_storage; #[doc(hidden)] pub use runtime_io::storage_root; +#[doc(hidden)] +pub use sr_primitives::RuntimeDebug; +#[macro_use] +pub mod debug; #[macro_use] pub mod dispatch; #[macro_use] @@ -224,8 +228,7 @@ macro_rules! __assert_eq_uvec { /// The void type - it cannot exist. // Oh rust, you crack me up... -#[derive(Clone, Eq, PartialEq)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(Clone, Eq, PartialEq, RuntimeDebug)] pub enum Void {} #[cfg(feature = "std")] diff --git a/srml/support/src/origin.rs b/srml/support/src/origin.rs index f3fec6e3ae..6da9bc1385 100644 --- a/srml/support/src/origin.rs +++ b/srml/support/src/origin.rs @@ -151,9 +151,7 @@ macro_rules! impl_outer_origin { $( $module:ident $( < $generic:ident > )? $( { $generic_instance:ident } )? ,)* ) => { $crate::paste::item! { - // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. - #[derive(Clone, PartialEq, Eq)] - #[cfg_attr(feature = "std", derive(Debug))] + #[derive(Clone, PartialEq, Eq, $crate::RuntimeDebug)] $(#[$attr])* #[allow(non_camel_case_types)] pub enum $name { diff --git a/srml/support/src/runtime.rs b/srml/support/src/runtime.rs index 491252ce70..52bf48baa5 100644 --- a/srml/support/src/runtime.rs +++ b/srml/support/src/runtime.rs @@ -191,8 +191,7 @@ macro_rules! construct_runtime { )* }; ) => { - #[derive(Clone, Copy, PartialEq, Eq)] - #[cfg_attr(feature = "std", derive(Debug))] + #[derive(Clone, Copy, PartialEq, Eq, $crate::RuntimeDebug)] pub struct $runtime; impl $crate::sr_primitives::traits::GetNodeBlockType for $runtime { type NodeBlock = $node_block; diff --git a/srml/support/src/traits.rs b/srml/support/src/traits.rs index 05f3cd070c..c58d60ffc9 100644 --- a/srml/support/src/traits.rs +++ b/srml/support/src/traits.rs @@ -18,12 +18,12 @@ //! //! NOTE: If you're looking for `parameter_types`, it has moved in to the top-level module. -use rstd::{prelude::*, result, marker::PhantomData, ops::Div}; +use rstd::{prelude::*, result, marker::PhantomData, ops::Div, fmt::Debug}; use codec::{FullCodec, Codec, Encode, Decode}; use primitives::u32_trait::Value as U32; use sr_primitives::{ ConsensusEngineId, - traits::{MaybeSerializeDebug, SimpleArithmetic, Saturating}, + traits::{MaybeSerializeDeserialize, SimpleArithmetic, Saturating}, }; /// Anything that can have a `::len()` method. @@ -257,7 +257,7 @@ pub enum SignedImbalance>{ impl< P: Imbalance, N: Imbalance, - B: SimpleArithmetic + FullCodec + Copy + MaybeSerializeDebug + Default, + B: SimpleArithmetic + FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default, > SignedImbalance { pub fn zero() -> Self { SignedImbalance::Positive(P::zero()) @@ -320,7 +320,7 @@ impl< /// Abstraction over a fungible assets system. pub trait Currency { /// The balance of an account. - type Balance: SimpleArithmetic + FullCodec + Copy + MaybeSerializeDebug + Default; + type Balance: SimpleArithmetic + FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default; /// The opaque token type for an imbalance. This is returned by unbalanced operations /// and must be dealt with. It may be dropped but cannot be cloned. diff --git a/srml/support/test/tests/instance.rs b/srml/support/test/tests/instance.rs index a8465adfd7..dd05cb1d8c 100644 --- a/srml/support/test/tests/instance.rs +++ b/srml/support/test/tests/instance.rs @@ -87,8 +87,7 @@ mod module1 { } } - #[derive(PartialEq, Eq, Clone)] - #[cfg_attr(feature = "std", derive(Debug))] + #[derive(PartialEq, Eq, Clone, sr_primitives::RuntimeDebug)] pub enum Origin, I> where T::BlockNumber: From { Members(u32), _Phantom(std::marker::PhantomData<(T, I)>), @@ -150,8 +149,7 @@ mod module2 { } } - #[derive(PartialEq, Eq, Clone)] - #[cfg_attr(feature = "std", derive(Debug))] + #[derive(PartialEq, Eq, Clone, sr_primitives::RuntimeDebug)] pub enum Origin, I=DefaultInstance> { Members(u32), _Phantom(std::marker::PhantomData<(T, I)>), diff --git a/srml/support/test/tests/system.rs b/srml/support/test/tests/system.rs index f1a427060a..2996724f62 100644 --- a/srml/support/test/tests/system.rs +++ b/srml/support/test/tests/system.rs @@ -38,8 +38,7 @@ support::decl_error! { } /// Origin for the system module. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Clone, sr_primitives::RuntimeDebug)] pub enum RawOrigin { Root, Signed(AccountId), diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index ed9dee2373..c9dcca53cb 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -94,8 +94,10 @@ use rstd::prelude::*; #[cfg(any(feature = "std", test))] use rstd::map; use rstd::marker::PhantomData; +use rstd::fmt::Debug; use sr_version::RuntimeVersion; use sr_primitives::{ + RuntimeDebug, generic::{self, Era}, Perbill, ApplyError, ApplyOutcome, DispatchError, weights::{Weight, DispatchInfo, DispatchClass, SimpleDispatchInfo}, transaction_validity::{ @@ -105,7 +107,7 @@ use sr_primitives::{ traits::{ self, CheckEqual, SimpleArithmetic, Zero, SignedExtension, Lookup, LookupError, SimpleBitOps, Hash, Member, MaybeDisplay, EnsureOrigin, SaturatedConversion, - MaybeSerializeDebugButNotDeserialize, MaybeSerializeDebug, StaticLookup, One, Bounded, + MaybeSerialize, MaybeSerializeDeserialize, StaticLookup, One, Bounded, }, }; @@ -158,28 +160,28 @@ pub trait Trait: 'static + Eq + Clone { type Origin: Into, Self::Origin>> + From>; /// The aggregated `Call` type. - type Call; + type Call: Debug; /// Account index (aka nonce) type. This stores the number of previous transactions associated with a sender /// account. type Index: - Parameter + Member + MaybeSerializeDebugButNotDeserialize + Default + MaybeDisplay + SimpleArithmetic + Copy; + Parameter + Member + MaybeSerialize + Debug + Default + MaybeDisplay + SimpleArithmetic + Copy; /// The block number type used by the runtime. type BlockNumber: - Parameter + Member + MaybeSerializeDebug + MaybeDisplay + SimpleArithmetic + Default + Bounded + Copy - + rstd::hash::Hash; + Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + SimpleArithmetic + + Default + Bounded + Copy + rstd::hash::Hash; /// The output of the `Hashing` function. type Hash: - Parameter + Member + MaybeSerializeDebug + MaybeDisplay + SimpleBitOps + Default + Copy + CheckEqual - + rstd::hash::Hash + AsRef<[u8]> + AsMut<[u8]>; + Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + SimpleBitOps + + Default + Copy + CheckEqual + rstd::hash::Hash + AsRef<[u8]> + AsMut<[u8]>; /// The hashing system (algorithm) being used in the runtime (e.g. Blake2). type Hashing: Hash; /// The user account identifier type for the runtime. - type AccountId: Parameter + Member + MaybeSerializeDebug + MaybeDisplay + Ord + Default; + type AccountId: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + Ord + Default; /// Converting trait to take a source type and convert to `AccountId`. /// @@ -195,7 +197,7 @@ pub trait Trait: 'static + Eq + Clone { >; /// The aggregated event type of the runtime. - type Event: Parameter + Member + From; + type Event: Parameter + Member + From + Debug; /// Maximum number of block number to block hash mappings to keep (oldest pruned first). type BlockHashCount: Get; @@ -280,8 +282,8 @@ decl_module! { } /// A phase of a block's execution. -#[derive(Encode, Decode)] -#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone, Debug))] +#[derive(Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone))] pub enum Phase { /// Applying an extrinsic. ApplyExtrinsic(u32), @@ -290,8 +292,8 @@ pub enum Phase { } /// Record of an event happening. -#[derive(Encode, Decode)] -#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone, Debug))] +#[derive(Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone))] pub struct EventRecord { /// The phase of the block it happened in. pub phase: Phase, @@ -323,8 +325,7 @@ decl_error! { } /// Origin for the System module. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Debug))] +#[derive(PartialEq, Eq, Clone, RuntimeDebug)] pub enum RawOrigin { /// The system itself ordained this dispatch to happen: this is the highest privilege level. Root, @@ -855,10 +856,15 @@ impl SignedExtension for CheckWeight { } } -#[cfg(feature = "std")] -impl rstd::fmt::Debug for CheckWeight { +impl Debug for CheckWeight { + #[cfg(feature = "std")] fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { - write!(f, "CheckWeight") + write!(f, "CheckWeight") + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) } } @@ -873,11 +879,16 @@ impl CheckNonce { } } -#[cfg(feature = "std")] -impl rstd::fmt::Debug for CheckNonce { +impl Debug for CheckNonce { + #[cfg(feature = "std")] fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { self.0.fmt(f) } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } } impl SignedExtension for CheckNonce { @@ -951,11 +962,16 @@ impl CheckEra { } } -#[cfg(feature = "std")] -impl rstd::fmt::Debug for CheckEra { +impl Debug for CheckEra { + #[cfg(feature = "std")] fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { self.0.fmt(f) } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } } impl SignedExtension for CheckEra { @@ -994,9 +1010,14 @@ impl SignedExtension for CheckEra { #[derive(Encode, Decode, Clone, Eq, PartialEq)] pub struct CheckGenesis(rstd::marker::PhantomData); -#[cfg(feature = "std")] -impl rstd::fmt::Debug for CheckGenesis { - fn fmt(&self, _f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { +impl Debug for CheckGenesis { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + write!(f, "CheckGenesis") + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { Ok(()) } } @@ -1023,9 +1044,14 @@ impl SignedExtension for CheckGenesis { #[derive(Encode, Decode, Clone, Eq, PartialEq)] pub struct CheckVersion(rstd::marker::PhantomData); -#[cfg(feature = "std")] -impl rstd::fmt::Debug for CheckVersion { - fn fmt(&self, _f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { +impl Debug for CheckVersion { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + write!(f, "CheckVersion") + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { Ok(()) } } diff --git a/srml/timestamp/src/lib.rs b/srml/timestamp/src/lib.rs index a48190da9a..2ab751088e 100644 --- a/srml/timestamp/src/lib.rs +++ b/srml/timestamp/src/lib.rs @@ -111,8 +111,8 @@ pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"timstap0"; pub type InherentType = u64; /// Errors that can occur while checking the timestamp inherent. -#[derive(Encode)] -#[cfg_attr(feature = "std", derive(Debug, Decode))] +#[derive(Encode, sr_primitives::RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode))] pub enum InherentError { /// The timestamp is valid in the future. /// This is a non-fatal-error and will not stop checking the inherents. diff --git a/srml/transaction-payment/src/lib.rs b/srml/transaction-payment/src/lib.rs index b662f55689..ab120322f6 100644 --- a/srml/transaction-payment/src/lib.rs +++ b/srml/transaction-payment/src/lib.rs @@ -145,11 +145,15 @@ impl ChargeTransactionPayment { } } -#[cfg(feature = "std")] impl rstd::fmt::Debug for ChargeTransactionPayment { + #[cfg(feature = "std")] fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { write!(f, "ChargeTransactionPayment<{:?}>", self.0) } + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } } impl SignedExtension for ChargeTransactionPayment diff --git a/srml/treasury/src/lib.rs b/srml/treasury/src/lib.rs index 67ee456139..08e2f729ab 100644 --- a/srml/treasury/src/lib.rs +++ b/srml/treasury/src/lib.rs @@ -213,8 +213,8 @@ decl_module! { } /// A spending proposal. -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -#[derive(Encode, Decode, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +#[derive(Encode, Decode, Clone, PartialEq, Eq, sr_primitives::RuntimeDebug)] pub struct Proposal { proposer: AccountId, value: Balance, -- GitLab From 3d84e941c3c59a6f2f3e2328a2e45e0f4a24e537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Tue, 22 Oct 2019 14:51:59 +0100 Subject: [PATCH 252/275] cli: disable pruning on validators (#3835) --- core/cli/src/lib.rs | 29 ++++++++++++++++++++++------- core/cli/src/params.rs | 14 ++++++++++++-- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/core/cli/src/lib.rs b/core/cli/src/lib.rs index e891f90dc2..e588c5e8f1 100644 --- a/core/cli/src/lib.rs +++ b/core/cli/src/lib.rs @@ -675,13 +675,6 @@ where config.database_path = db_path(&base_path, config.chain_spec.id()); config.database_cache_size = cli.database_cache_size; config.state_cache_size = cli.state_cache_size; - config.pruning = match cli.pruning { - Some(ref s) if s == "archive" => PruningMode::ArchiveAll, - None => PruningMode::default(), - Some(s) => PruningMode::keep_blocks(s.parse() - .map_err(|_| error::Error::Input("Invalid pruning mode specified".to_string()))? - ), - }; let is_dev = cli.shared_params.dev; @@ -694,6 +687,28 @@ where service::Roles::FULL }; + // by default we disable pruning if the node is an authority (i.e. + // `ArchiveAll`), otherwise we keep state for the last 256 blocks. if the + // node is an authority and pruning is enabled explicitly, then we error + // unless `unsafe_pruning` is set. + config.pruning = match cli.pruning { + Some(ref s) if s == "archive" => PruningMode::ArchiveAll, + None if role == service::Roles::AUTHORITY => PruningMode::ArchiveAll, + None => PruningMode::default(), + Some(s) => { + if role == service::Roles::AUTHORITY && !cli.unsafe_pruning { + return Err(error::Error::Input( + "Validators should run with state pruning disabled (i.e. archive). \ + You can ignore this check with `--unsafe-pruning`.".to_string() + )); + } + + PruningMode::keep_blocks(s.parse() + .map_err(|_| error::Error::Input("Invalid pruning mode specified".to_string()))? + ) + }, + }; + config.wasm_method = cli.wasm_method.into(); let exec = cli.execution_strategies; diff --git a/core/cli/src/params.rs b/core/cli/src/params.rs index b949b336de..e75defec1d 100644 --- a/core/cli/src/params.rs +++ b/core/cli/src/params.rs @@ -366,12 +366,22 @@ pub struct RunCmd { #[structopt(long = "rpc-cors", value_name = "ORIGINS", parse(try_from_str = parse_cors))] pub rpc_cors: Option, - /// Specify the pruning mode, a number of blocks to keep or 'archive'. + /// Specify the state pruning mode, a number of blocks to keep or 'archive'. /// - /// Default is 256. + /// Default is to keep all block states if the node is running as a + /// validator (i.e. 'archive'), otherwise state is only kept for the last + /// 256 blocks. #[structopt(long = "pruning", value_name = "PRUNING_MODE")] pub pruning: Option, + /// Force start with unsafe pruning settings. + /// + /// When running as a validator it is highly recommended to disable state + /// pruning (i.e. 'archive') which is the default. The node will refuse to + /// start as a validator if pruning is enabled unless this option is set. + #[structopt(long = "unsafe-pruning")] + pub unsafe_pruning: bool, + /// The human-readable name for this node. /// /// The node name will be reported to the telemetry server, if enabled. -- GitLab From d1e6f1b39a0d87fc52e7df7dde7f9f04ecfe7d02 Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Tue, 22 Oct 2019 15:52:38 +0200 Subject: [PATCH 253/275] Fail on pruning mode change (#3882) --- core/state-db/src/lib.rs | 67 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/core/state-db/src/lib.rs b/core/state-db/src/lib.rs index 81772e554b..e561d9ce96 100644 --- a/core/state-db/src/lib.rs +++ b/core/state-db/src/lib.rs @@ -41,6 +41,11 @@ use noncanonical::NonCanonicalOverlay; use pruning::RefWindow; use log::trace; +const PRUNING_MODE: &[u8] = b"mode"; +const PRUNING_MODE_ARCHIVE: &[u8] = b"archive"; +const PRUNING_MODE_ARCHIVE_CANON: &[u8] = b"archive_canonical"; +const PRUNING_MODE_CONSTRAINED: &[u8] = b"constrained"; + /// Database value type. pub type DBValue = Vec; @@ -77,6 +82,8 @@ pub enum Error { InvalidBlockNumber, /// Trying to insert block with unknown parent. InvalidParent, + /// Invalid pruning mode specified. Contains expected mode. + InvalidPruningMode(String), } /// Pinning error type. @@ -99,6 +106,7 @@ impl fmt::Debug for Error { Error::InvalidBlock => write!(f, "Trying to canonicalize invalid block"), Error::InvalidBlockNumber => write!(f, "Trying to insert block with invalid number"), Error::InvalidParent => write!(f, "Trying to insert block with unknown parent"), + Error::InvalidPruningMode(e) => write!(f, "Expected pruning mode: {}", e), } } } @@ -159,6 +167,14 @@ impl PruningMode { } } + /// Is this an archive (either ArchiveAll or ArchiveCanonical) pruning mode? + pub fn id(&self) -> &[u8] { + match self { + PruningMode::ArchiveAll => PRUNING_MODE_ARCHIVE, + PruningMode::ArchiveCanonical => PRUNING_MODE_ARCHIVE_CANON, + PruningMode::Constrained(_) => PRUNING_MODE_CONSTRAINED, + } + } } impl Default for PruningMode { @@ -183,6 +199,10 @@ struct StateDbSync { impl StateDbSync { pub fn new(mode: PruningMode, db: &D) -> Result, Error> { trace!(target: "state-db", "StateDb settings: {:?}", mode); + + // Check that settings match + Self::check_meta(&mode, db)?; + let non_canonical: NonCanonicalOverlay = NonCanonicalOverlay::new(db)?; let pruning: Option> = match mode { PruningMode::Constrained(Constraints { @@ -192,6 +212,7 @@ impl StateDbSync { PruningMode::Constrained(_) => Some(RefWindow::new(db)?), PruningMode::ArchiveAll | PruningMode::ArchiveCanonical => None, }; + Ok(StateDbSync { mode, non_canonical, @@ -200,18 +221,41 @@ impl StateDbSync { }) } + fn check_meta(mode: &PruningMode, db: &D) -> Result<(), Error> { + let db_mode = db.get_meta(&to_meta_key(PRUNING_MODE, &())).map_err(Error::Db)?; + trace!(target: "state-db", + "DB pruning mode: {:?}", + db_mode.as_ref().map(|v| std::str::from_utf8(&v)) + ); + match &db_mode { + Some(v) if v.as_slice() == mode.id() => Ok(()), + Some(v) => Err(Error::InvalidPruningMode(String::from_utf8_lossy(v).into())), + None => Ok(()), + } + } + pub fn insert_block(&mut self, hash: &BlockHash, number: u64, parent_hash: &BlockHash, mut changeset: ChangeSet) -> Result, Error> { + let mut meta = ChangeSet::default(); + if number == 0 { + // Save pruning mode when writing first block. + meta.inserted.push((to_meta_key(PRUNING_MODE, &()), self.mode.id().into())); + } + match self.mode { PruningMode::ArchiveAll => { changeset.deleted.clear(); // write changes immediately Ok(CommitSet { data: changeset, - meta: Default::default(), + meta: meta, }) }, PruningMode::Constrained(_) | PruningMode::ArchiveCanonical => { - self.non_canonical.insert(hash, number, parent_hash, changeset) + let commit = self.non_canonical.insert(hash, number, parent_hash, changeset); + commit.map(|mut c| { + c.meta.inserted.extend(meta.inserted); + c + }) } } } @@ -544,4 +588,23 @@ mod tests { assert!(sdb.is_pruned(&H256::from_low_u64_be(22), 2)); assert!(db.data_eq(&make_db(&[1, 21, 3, 921, 922, 93, 94]))); } + + #[test] + fn detects_incompatible_mode() { + let mut db = make_db(&[]); + let state_db = StateDb::new(PruningMode::ArchiveAll, &db).unwrap(); + db.commit( + &state_db + .insert_block::( + &H256::from_low_u64_be(0), + 0, + &H256::from_low_u64_be(0), + make_changeset(&[], &[]), + ) + .unwrap(), + ); + let new_mode = PruningMode::Constrained(Constraints { max_blocks: Some(2), max_mem: None }); + let state_db: Result, _> = StateDb::new(new_mode, &db); + assert!(state_db.is_err()); + } } -- GitLab From b9d66637857017356983dd021c1d200898561eb7 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Tue, 22 Oct 2019 16:53:20 +0300 Subject: [PATCH 254/275] Dry out author rpc tests (#3878) --- core/rpc/src/author/tests.rs | 149 ++++++++++++++--------------------- 1 file changed, 60 insertions(+), 89 deletions(-) diff --git a/core/rpc/src/author/tests.rs b/core/rpc/src/author/tests.rs index e8ba4c132a..5ae044ff49 100644 --- a/core/rpc/src/author/tests.rs +++ b/core/rpc/src/author/tests.rs @@ -20,13 +20,13 @@ use std::sync::Arc; use assert_matches::assert_matches; use codec::Encode; use primitives::{ - H256, blake2_256, hexdisplay::HexDisplay, testing::{ED25519, SR25519, KeyStore}, ed25519, + H256, blake2_256, hexdisplay::HexDisplay, testing::{ED25519, SR25519, KeyStore}, traits::BareCryptoStorePtr, ed25519, crypto::Pair, }; use rpc::futures::Stream as _; use test_client::{ - self, AccountKeyring, runtime::{Extrinsic, Transfer, SessionKeys}, DefaultTestClientBuilderExt, - TestClientBuilderExt, + self, AccountKeyring, runtime::{Extrinsic, Transfer, SessionKeys, RuntimeApi, Block}, DefaultTestClientBuilderExt, + TestClientBuilderExt, Backend, Client, Executor }; use transaction_pool::{ txpool::Pool, @@ -44,17 +44,41 @@ fn uxt(sender: AccountKeyring, nonce: u64) -> Extrinsic { tx.into_signed_tx() } +struct TestSetup { + pub runtime: runtime::Runtime, + pub client: Arc>, + pub keystore: BareCryptoStorePtr, + pub pool: Arc, Block>>>, +} + +impl Default for TestSetup { + fn default() -> Self { + let keystore = KeyStore::new(); + let client = Arc::new(test_client::TestClientBuilder::new().set_keystore(keystore.clone()).build()); + let pool = Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone()))); + TestSetup { + runtime: runtime::Runtime::new().expect("Failed to create runtime in test setup"), + client, + keystore, + pool, + } + } +} + +impl TestSetup { + fn author(&self) -> Author, Block>, RuntimeApi> { + Author { + client: self.client.clone(), + pool: self.pool.clone(), + subscriptions: Subscriptions::new(Arc::new(self.runtime.executor())), + keystore: self.keystore.clone(), + } + } +} + #[test] fn submit_transaction_should_not_cause_error() { - let runtime = runtime::Runtime::new().unwrap(); - let client = Arc::new(test_client::new()); - let keystore = KeyStore::new(); - let p = Author { - client: client.clone(), - pool: Arc::new(Pool::new(Default::default(), FullChainApi::new(client))), - subscriptions: Subscriptions::new(Arc::new(runtime.executor())), - keystore: keystore.clone(), - }; + let p = TestSetup::default().author(); let xt = uxt(AccountKeyring::Alice, 1).encode(); let h: H256 = blake2_256(&xt).into(); @@ -69,15 +93,7 @@ fn submit_transaction_should_not_cause_error() { #[test] fn submit_rich_transaction_should_not_cause_error() { - let runtime = runtime::Runtime::new().unwrap(); - let client = Arc::new(test_client::new()); - let keystore = KeyStore::new(); - let p = Author { - client: client.clone(), - pool: Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone()))), - subscriptions: Subscriptions::new(Arc::new(runtime.executor())), - keystore: keystore.clone(), - }; + let p = TestSetup::default().author(); let xt = uxt(AccountKeyring::Alice, 0).encode(); let h: H256 = blake2_256(&xt).into(); @@ -93,23 +109,16 @@ fn submit_rich_transaction_should_not_cause_error() { #[test] fn should_watch_extrinsic() { //given - let mut runtime = runtime::Runtime::new().unwrap(); - let client = Arc::new(test_client::new()); - let pool = Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone()))); - let keystore = KeyStore::new(); - let p = Author { - client, - pool: pool.clone(), - subscriptions: Subscriptions::new(Arc::new(runtime.executor())), - keystore: keystore.clone(), - }; + let mut setup = TestSetup::default(); + let p = setup.author(); + let (subscriber, id_rx, data) = jsonrpc_pubsub::typed::Subscriber::new_test("test"); // when p.watch_extrinsic(Default::default(), subscriber, uxt(AccountKeyring::Alice, 0).encode().into()); // then - assert_eq!(runtime.block_on(id_rx), Ok(Ok(1.into()))); + assert_eq!(setup.runtime.block_on(id_rx), Ok(Ok(1.into()))); // check notifications let replacement = { let tx = Transfer { @@ -121,14 +130,14 @@ fn should_watch_extrinsic() { tx.into_signed_tx() }; AuthorApi::submit_extrinsic(&p, replacement.encode().into()).wait().unwrap(); - let (res, data) = runtime.block_on(data.into_future()).unwrap(); + let (res, data) = setup.runtime.block_on(data.into_future()).unwrap(); assert_eq!( res, Some(r#"{"jsonrpc":"2.0","method":"test","params":{"result":"ready","subscription":1}}"#.into()) ); let h = blake2_256(&replacement.encode()); assert_eq!( - runtime.block_on(data.into_future()).unwrap().0, + setup.runtime.block_on(data.into_future()).unwrap().0, Some(format!(r#"{{"jsonrpc":"2.0","method":"test","params":{{"result":{{"usurped":"0x{}"}},"subscription":1}}}}"#, HexDisplay::from(&h))) ); } @@ -136,38 +145,23 @@ fn should_watch_extrinsic() { #[test] fn should_return_watch_validation_error() { //given - let mut runtime = runtime::Runtime::new().unwrap(); - let client = Arc::new(test_client::new()); - let pool = Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone()))); - let keystore = KeyStore::new(); - let p = Author { - client, - pool: pool.clone(), - subscriptions: Subscriptions::new(Arc::new(runtime.executor())), - keystore: keystore.clone(), - }; + let mut setup = TestSetup::default(); + let p = setup.author(); + let (subscriber, id_rx, _data) = jsonrpc_pubsub::typed::Subscriber::new_test("test"); // when p.watch_extrinsic(Default::default(), subscriber, uxt(AccountKeyring::Alice, 179).encode().into()); // then - let res = runtime.block_on(id_rx).unwrap(); + let res = setup.runtime.block_on(id_rx).unwrap(); assert!(res.is_err(), "Expected the transaction to be rejected as invalid."); } #[test] fn should_return_pending_extrinsics() { - let runtime = runtime::Runtime::new().unwrap(); - let client = Arc::new(test_client::new()); - let pool = Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone()))); - let keystore = KeyStore::new(); - let p = Author { - client, - pool: pool.clone(), - subscriptions: Subscriptions::new(Arc::new(runtime.executor())), - keystore: keystore.clone(), - }; + let p = TestSetup::default().author(); + let ex = uxt(AccountKeyring::Alice, 0); AuthorApi::submit_extrinsic(&p, ex.encode().into()).wait().unwrap(); assert_matches!( @@ -178,23 +172,16 @@ fn should_return_pending_extrinsics() { #[test] fn should_remove_extrinsics() { - let runtime = runtime::Runtime::new().unwrap(); - let client = Arc::new(test_client::new()); - let pool = Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone()))); - let keystore = KeyStore::new(); - let p = Author { - client, - pool: pool.clone(), - subscriptions: Subscriptions::new(Arc::new(runtime.executor())), - keystore: keystore.clone(), - }; + let setup = TestSetup::default(); + let p = setup.author(); + let ex1 = uxt(AccountKeyring::Alice, 0); p.submit_extrinsic(ex1.encode().into()).wait().unwrap(); let ex2 = uxt(AccountKeyring::Alice, 1); p.submit_extrinsic(ex2.encode().into()).wait().unwrap(); let ex3 = uxt(AccountKeyring::Bob, 0); let hash3 = p.submit_extrinsic(ex3.encode().into()).wait().unwrap(); - assert_eq!(pool.status().ready, 3); + assert_eq!(setup.pool.status().ready, 3); // now remove all 3 let removed = p.remove_extrinsic(vec![ @@ -208,15 +195,8 @@ fn should_remove_extrinsics() { #[test] fn should_insert_key() { - let runtime = runtime::Runtime::new().unwrap(); - let client = Arc::new(test_client::new()); - let keystore = KeyStore::new(); - let p = Author { - client: client.clone(), - pool: Arc::new(Pool::new(Default::default(), FullChainApi::new(client))), - subscriptions: Subscriptions::new(Arc::new(runtime.executor())), - keystore: keystore.clone(), - }; + let setup = TestSetup::default(); + let p = setup.author(); let suri = "//Alice"; let key_pair = ed25519::Pair::from_string(suri, None).expect("Generates keypair"); @@ -226,7 +206,7 @@ fn should_insert_key() { key_pair.public().0.to_vec().into(), ).expect("Insert key"); - let store_key_pair = keystore.read() + let store_key_pair = setup.keystore.read() .ed25519_key_pair(ED25519, &key_pair.public()).expect("Key exists in store"); assert_eq!(key_pair.public(), store_key_pair.public()); @@ -234,29 +214,20 @@ fn should_insert_key() { #[test] fn should_rotate_keys() { - let runtime = runtime::Runtime::new().unwrap(); - let keystore = KeyStore::new(); - let client = Arc::new( - test_client::TestClientBuilder::new().set_keystore(keystore.clone()).build(), - ); - let p = Author { - client: client.clone(), - pool: Arc::new(Pool::new(Default::default(), FullChainApi::new(client))), - subscriptions: Subscriptions::new(Arc::new(runtime.executor())), - keystore: keystore.clone(), - }; + let setup = TestSetup::default(); + let p = setup.author(); let new_public_keys = p.rotate_keys().expect("Rotates the keys"); let session_keys = SessionKeys::decode(&mut &new_public_keys[..]) .expect("SessionKeys decode successfully"); - let ed25519_key_pair = keystore.read().ed25519_key_pair( + let ed25519_key_pair = setup.keystore.read().ed25519_key_pair( ED25519, &session_keys.ed25519.clone().into(), ).expect("ed25519 key exists in store"); - let sr25519_key_pair = keystore.read().sr25519_key_pair( + let sr25519_key_pair = setup.keystore.read().sr25519_key_pair( SR25519, &session_keys.sr25519.clone().into(), ).expect("sr25519 key exists in store"); -- GitLab From 653456962f43bb6872ffcc2917e652b5e0f980db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 22 Oct 2019 18:54:52 +0200 Subject: [PATCH 255/275] Support disabling the addition of the default bootnode (#3888) --- core/cli/src/lib.rs | 2 +- core/cli/src/params.rs | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/core/cli/src/lib.rs b/core/cli/src/lib.rs index e588c5e8f1..51363445dc 100644 --- a/core/cli/src/lib.rs +++ b/core/cli/src/lib.rs @@ -803,7 +803,7 @@ where G: RuntimeGenesis, E: ChainSpecExtension, { - if spec.boot_nodes().is_empty() { + if spec.boot_nodes().is_empty() && !cli.disable_default_bootnode { let base_path = base_path(&cli.shared_params, version); let storage_path = network_path(&base_path, spec.id()); let node_key = node_key_config(cli.node_key_params, &Some(storage_path))?; diff --git a/core/cli/src/params.rs b/core/cli/src/params.rs index e75defec1d..ae1c856622 100644 --- a/core/cli/src/params.rs +++ b/core/cli/src/params.rs @@ -614,6 +614,13 @@ pub struct BuildSpecCmd { #[structopt(long = "raw")] pub raw: bool, + /// Disable adding the default bootnode to the specification. + /// + /// By default the `/ip4/127.0.0.1/tcp/30333/p2p/NODE_PEER_ID` bootnode is added to the + /// specification when no bootnode exists. + #[structopt(long = "disable-default-bootnode")] + pub disable_default_bootnode: bool, + #[allow(missing_docs)] #[structopt(flatten)] pub shared_params: SharedParams, @@ -763,7 +770,7 @@ impl StructOpt for CoreParams where ) ).subcommand( BuildSpecCmd::augment_clap(SubCommand::with_name("build-spec")) - .about("Build a spec.json file, outputing to stdout.") + .about("Build a spec.json file, outputting to stdout.") ) .subcommand( ExportBlocksCmd::augment_clap(SubCommand::with_name("export-blocks")) -- GitLab From d00d3137246bdb7d63fb6ef206957c539685322b Mon Sep 17 00:00:00 2001 From: Weiliang Li Date: Wed, 23 Oct 2019 15:23:47 +0900 Subject: [PATCH 256/275] gossip: futures 03 Receiver (#3832) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * gossip: futures 03 receiver * fix gossip test * use tokio 01 * add comment * Update core/finality-grandpa/src/communication/mod.rs Co-Authored-By: Bastian Köcher * fix format * rename * remove tokio 01 runtime * minor fix * make stable happy --- .../finality-grandpa/src/communication/mod.rs | 30 ++++++++++++------- core/network/src/protocol/consensus_gossip.rs | 30 +++++++++---------- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/core/finality-grandpa/src/communication/mod.rs b/core/finality-grandpa/src/communication/mod.rs index ba7bdce336..f2a4dee21e 100644 --- a/core/finality-grandpa/src/communication/mod.rs +++ b/core/finality-grandpa/src/communication/mod.rs @@ -31,6 +31,7 @@ use std::sync::Arc; use futures::prelude::*; use futures::sync::{oneshot, mpsc}; +use futures03::stream::{StreamExt, TryStreamExt}; use grandpa::Message::{Prevote, Precommit, PrimaryPropose}; use grandpa::{voter, voter_set::VoterSet}; use log::{debug, trace}; @@ -100,7 +101,7 @@ mod benefit { /// Intended to be a lightweight handle such as an `Arc`. pub trait Network: Clone + Send + 'static { /// A stream of input messages for a topic. - type In: Stream; + type In: Stream; /// Get a stream of messages for a specific gossip topic. fn messages_for(&self, topic: Block::Hash) -> Self::In; @@ -145,7 +146,9 @@ impl Network for Arc> where S: network::specialization::NetworkSpecialization, H: network::ExHashT, { - type In = NetworkStream; + type In = NetworkStream< + Box + Send + 'static>, + >; fn messages_for(&self, topic: B::Hash) -> Self::In { // Given that one can only communicate with the Substrate network via the `NetworkService` via message-passing, @@ -159,7 +162,11 @@ impl Network for Arc> where // waiting for the oneshot to resolve and from there on acting like a normal message channel. let (tx, rx) = oneshot::channel(); self.with_gossip(move |gossip, _| { - let inner_rx = gossip.messages_for(GRANDPA_ENGINE_ID, topic); + let inner_rx: Box + Send> = Box::new(gossip + .messages_for(GRANDPA_ENGINE_ID, topic) + .map(|x| Ok(x)) + .compat() + ); let _ = tx.send(inner_rx); }); NetworkStream::PollingOneshot(rx) @@ -220,13 +227,16 @@ impl Network for Arc> where /// /// `NetworkStream` combines the two steps into one, requiring a consumer to only poll `NetworkStream` to retrieve /// messages directly. -pub enum NetworkStream { - PollingOneshot(oneshot::Receiver>), - PollingTopicNotifications(mpsc::UnboundedReceiver), +pub enum NetworkStream { + PollingOneshot(oneshot::Receiver), + PollingTopicNotifications(R), } -impl Stream for NetworkStream { - type Item = network_gossip::TopicNotification; +impl Stream for NetworkStream +where + R: Stream, +{ + type Item = R::Item; type Error = (); fn poll(&mut self) -> Poll, Self::Error> { @@ -266,11 +276,11 @@ impl> NetworkBridge { service: N, config: crate::Config, set_state: crate::environment::SharedVoterSetState, - on_exit: impl Future + Clone + Send + 'static, + on_exit: impl Future + Clone + Send + 'static, catch_up_enabled: bool, ) -> ( Self, - impl futures::Future + Send + 'static, + impl Future + Send + 'static, ) { let (validator, report_stream) = GossipValidator::new( diff --git a/core/network/src/protocol/consensus_gossip.rs b/core/network/src/protocol/consensus_gossip.rs index e23df7e1a5..f3d4e536a7 100644 --- a/core/network/src/protocol/consensus_gossip.rs +++ b/core/network/src/protocol/consensus_gossip.rs @@ -48,7 +48,7 @@ use std::sync::Arc; use std::iter; use std::time; use log::{trace, debug}; -use futures::sync::mpsc; +use futures03::channel::mpsc; use lru_cache::LruCache; use libp2p::PeerId; use sr_primitives::traits::{Block as BlockT, Hash, HashFor}; @@ -608,7 +608,7 @@ impl Validator for DiscardAll { #[cfg(test)] mod tests { use sr_primitives::testing::{H256, Block as RawBlock, ExtrinsicWrapper}; - use futures::Stream; + use futures03::executor::block_on_stream; use super::*; @@ -670,7 +670,7 @@ mod tests { let m2 = vec![4, 5, 6]; push_msg!(consensus, prev_hash, m1_hash, m1); - push_msg!(consensus, best_hash, m2_hash, m2.clone()); + push_msg!(consensus, best_hash, m2_hash, m2); consensus.known_messages.insert(m1_hash, ()); consensus.known_messages.insert(m2_hash, ()); @@ -692,8 +692,6 @@ mod tests { #[test] fn message_stream_include_those_sent_before_asking_for_stream() { - use futures::Stream; - let mut consensus = ConsensusGossip::::new(); consensus.register_validator_internal([0, 0, 0, 0], Arc::new(AllowAll)); @@ -701,9 +699,9 @@ mod tests { let topic = HashFor::::hash(&[1,2,3]); consensus.register_message(topic, message.clone()); - let stream = consensus.messages_for([0, 0, 0, 0], topic); + let mut stream = block_on_stream(consensus.messages_for([0, 0, 0, 0], topic)); - assert_eq!(stream.wait().next(), Some(Ok(TopicNotification { message: message.data, sender: None }))); + assert_eq!(stream.next(), Some(TopicNotification { message: message.data, sender: None })); } #[test] @@ -725,16 +723,17 @@ mod tests { let mut consensus = ConsensusGossip::::new(); consensus.register_validator_internal([0, 0, 0, 0], Arc::new(AllowAll)); - let message = ConsensusMessage { data: vec![4, 5, 6], engine_id: [0, 0, 0, 0] }; - let topic = HashFor::::hash(&[1,2,3]); + let data = vec![4, 5, 6]; + let message = ConsensusMessage { data: data.clone(), engine_id: [0, 0, 0, 0] }; + let topic = HashFor::::hash(&[1, 2, 3]); consensus.register_message(topic, message.clone()); - let stream1 = consensus.messages_for([0, 0, 0, 0], topic); - let stream2 = consensus.messages_for([0, 0, 0, 0], topic); + let mut stream1 = block_on_stream(consensus.messages_for([0, 0, 0, 0], topic)); + let mut stream2 = block_on_stream(consensus.messages_for([0, 0, 0, 0], topic)); - assert_eq!(stream1.wait().next(), Some(Ok(TopicNotification { message: message.data.clone(), sender: None }))); - assert_eq!(stream2.wait().next(), Some(Ok(TopicNotification { message: message.data, sender: None }))); + assert_eq!(stream1.next(), Some(TopicNotification { message: data.clone(), sender: None })); + assert_eq!(stream2.next(), Some(TopicNotification { message: data, sender: None })); } #[test] @@ -749,9 +748,10 @@ mod tests { consensus.register_message(topic, msg_a); consensus.register_message(topic, msg_b); - let mut stream = consensus.messages_for([0, 0, 0, 0], topic).wait(); + let mut stream = block_on_stream(consensus.messages_for([0, 0, 0, 0], topic)); + + assert_eq!(stream.next(), Some(TopicNotification { message: vec![1, 2, 3], sender: None })); - assert_eq!(stream.next(), Some(Ok(TopicNotification { message: vec![1, 2, 3], sender: None }))); let _ = consensus.live_message_sinks.remove(&([0, 0, 0, 0], topic)); assert_eq!(stream.next(), None); } -- GitLab From c4e78a3332a872ceafdf2810a9b0e576672a26f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 23 Oct 2019 09:37:41 +0200 Subject: [PATCH 257/275] Fix srml assets compilation with `std` feature (#3892) --- srml/assets/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/srml/assets/Cargo.toml b/srml/assets/Cargo.toml index 5f22ab3ba3..052a3045b2 100644 --- a/srml/assets/Cargo.toml +++ b/srml/assets/Cargo.toml @@ -27,5 +27,4 @@ std = [ "sr-primitives/std", "support/std", "system/std", - "runtime-io/std", ] -- GitLab From 395cb2d00bf0b091292a937e258e818b88601bb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 23 Oct 2019 10:28:44 +0200 Subject: [PATCH 258/275] Wasm-builder-runner unset `CARGO_TARGET_DIR` and release 1.0.4 (#3893) * Wasm-builder-runner unset `CARGO_TARGET_DIR` and release 1.0.4 `CARGO_TARGET_DIR` needs to be unset or otherwise cargo deadlocks, because cargo always holds an exclusive lock on target dir. * Commit missing version up * Lock file --- Cargo.lock | 14 +++++++------- core/executor/runtime-test/Cargo.toml | 2 +- core/test-runtime/Cargo.toml | 2 +- core/utils/wasm-builder-runner/Cargo.toml | 2 +- core/utils/wasm-builder-runner/src/lib.rs | 7 ++++++- node-template/runtime/Cargo.toml | 2 +- node/runtime/Cargo.toml | 2 +- 7 files changed, 18 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0ad4317dd9..f12014a220 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2511,7 +2511,7 @@ dependencies = [ "substrate-offchain-primitives 2.0.0", "substrate-primitives 2.0.0", "substrate-session 2.0.0", - "substrate-wasm-builder-runner 1.0.3", + "substrate-wasm-builder-runner 1.0.4", ] [[package]] @@ -2572,7 +2572,7 @@ dependencies = [ "substrate-offchain-primitives 2.0.0", "substrate-primitives 2.0.0", "substrate-session 2.0.0", - "substrate-wasm-builder-runner 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-wasm-builder-runner 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5484,7 +5484,7 @@ dependencies = [ "sr-sandbox 2.0.0", "sr-std 2.0.0", "substrate-primitives 2.0.0", - "substrate-wasm-builder-runner 1.0.3", + "substrate-wasm-builder-runner 1.0.4", ] [[package]] @@ -5672,7 +5672,7 @@ dependencies = [ "substrate-state-machine 2.0.0", "substrate-test-runtime-client 2.0.0", "substrate-trie 2.0.0", - "substrate-wasm-builder-runner 1.0.3", + "substrate-wasm-builder-runner 1.0.4", "trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5754,11 +5754,11 @@ dependencies = [ [[package]] name = "substrate-wasm-builder-runner" -version = "1.0.3" +version = "1.0.4" [[package]] name = "substrate-wasm-builder-runner" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -7148,7 +7148,7 @@ dependencies = [ "checksum strum 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d1c33039533f051704951680f1adfd468fd37ac46816ded0d9ee068e60f05f" "checksum strum_macros 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "47cd23f5c7dee395a00fa20135e2ec0fffcdfa151c56182966d7a3261343432e" "checksum substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3be511be555a3633e71739a79e4ddff6a6aaa6579fa6114182a51d72c3eb93c5" -"checksum substrate-wasm-builder-runner 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af21b27fad38b212c1919f700cb0def33c88cde14d22e0d1b17d4521f4eb8b40" +"checksum substrate-wasm-builder-runner 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bd48273fe9d7f92c1f7d6c1c537bb01c8068f925b47ad2cd8367e11dc32f8550" "checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" "checksum subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab3af2eb31c42e8f0ccf43548232556c42737e01a96db6e1777b0be108e79799" "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" diff --git a/core/executor/runtime-test/Cargo.toml b/core/executor/runtime-test/Cargo.toml index 153c5c9a1f..72041218bf 100644 --- a/core/executor/runtime-test/Cargo.toml +++ b/core/executor/runtime-test/Cargo.toml @@ -13,7 +13,7 @@ primitives = { package = "substrate-primitives", path = "../../primitives", def sr-primitives = { package = "sr-primitives", path = "../../sr-primitives", default-features = false } [build-dependencies] -wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.2", path = "../../utils/wasm-builder-runner" } +wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.4", path = "../../utils/wasm-builder-runner" } [features] default = [ "std" ] diff --git a/core/test-runtime/Cargo.toml b/core/test-runtime/Cargo.toml index fec9128ef5..4e7c3f8bca 100644 --- a/core/test-runtime/Cargo.toml +++ b/core/test-runtime/Cargo.toml @@ -39,7 +39,7 @@ substrate-test-runtime-client = { path = "./client" } state_machine = { package = "substrate-state-machine", path = "../state-machine" } [build-dependencies] -wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.2", path = "../utils/wasm-builder-runner" } +wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.4", path = "../utils/wasm-builder-runner" } [features] default = [ diff --git a/core/utils/wasm-builder-runner/Cargo.toml b/core/utils/wasm-builder-runner/Cargo.toml index 71cdbd2835..ab8a539054 100644 --- a/core/utils/wasm-builder-runner/Cargo.toml +++ b/core/utils/wasm-builder-runner/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-wasm-builder-runner" -version = "1.0.3" +version = "1.0.4" authors = ["Parity Technologies "] description = "Runner for substrate-wasm-builder" edition = "2018" diff --git a/core/utils/wasm-builder-runner/src/lib.rs b/core/utils/wasm-builder-runner/src/lib.rs index 1fee4a4fd7..1739c5eff2 100644 --- a/core/utils/wasm-builder-runner/src/lib.rs +++ b/core/utils/wasm-builder-runner/src/lib.rs @@ -227,6 +227,11 @@ fn run_project(project_folder: &Path) { cmd.arg("--release"); } + // Unset the `CARGO_TARGET_DIR` to prevent a cargo deadlock (cargo locks a target dir exclusive). + // The runner project is created in `CARGO_TARGET_DIR` and executing it will create a sub target + // directory inside of `CARGO_TARGET_DIR`. + cmd.env_remove("CARGO_TARGET_DIR"); + if !cmd.status().map(|s| s.success()).unwrap_or(false) { // Don't spam the output with backtraces when a build failed! process::exit(1); @@ -255,7 +260,7 @@ fn check_provide_dummy_wasm_binary() -> bool { fn provide_dummy_wasm_binary(file_path: &Path) { fs::write( file_path, - "pub const WASM_BINARY: &[u8] = &[]; pub const WASM_BINARY_BLOATY: &[u8] = &[];" + "pub const WASM_BINARY: &[u8] = &[]; pub const WASM_BINARY_BLOATY: &[u8] = &[];", ).expect("Writing dummy WASM binary should not fail"); } diff --git a/node-template/runtime/Cargo.toml b/node-template/runtime/Cargo.toml index 5ebf3af6cf..ff2e3eb2b1 100644 --- a/node-template/runtime/Cargo.toml +++ b/node-template/runtime/Cargo.toml @@ -30,7 +30,7 @@ client = { package = "substrate-client", path = "../../core/client", default_fea offchain-primitives = { package = "substrate-offchain-primitives", path = "../../core/offchain/primitives", default-features = false } [build-dependencies] -wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.2" } +wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.4" } [features] default = ["std"] diff --git a/node/runtime/Cargo.toml b/node/runtime/Cargo.toml index af66c0432f..d65112da24 100644 --- a/node/runtime/Cargo.toml +++ b/node/runtime/Cargo.toml @@ -55,7 +55,7 @@ utility = { package = "srml-utility", path = "../../srml/utility", default-featu transaction-payment = { package = "srml-transaction-payment", path = "../../srml/transaction-payment", default-features = false } [build-dependencies] -wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.2", path = "../../core/utils/wasm-builder-runner" } +wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.4", path = "../../core/utils/wasm-builder-runner" } [features] default = ["std"] -- GitLab From acf86cd4b0ad4c45dbba57c2ae323531d5b71264 Mon Sep 17 00:00:00 2001 From: Ashley Date: Wed, 23 Oct 2019 11:02:30 +0100 Subject: [PATCH 259/275] Add an OnUnbalanced hook for contract rent payments (#3857) * Add RentPayment trait to runtime * clarify check * improve proof * Clarify further * Simplify RentPayment::on_unbalance calling and get rid of NonZeroRentHook --- node/runtime/src/lib.rs | 3 ++- srml/contracts/src/lib.rs | 3 +++ srml/contracts/src/rent.rs | 6 ++++-- srml/contracts/src/tests.rs | 1 + 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 472dec02b8..1544ee9a4a 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -85,7 +85,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 181, - impl_version: 182, + impl_version: 183, apis: RUNTIME_API_VERSIONS, }; @@ -412,6 +412,7 @@ impl contracts::Trait for Runtime { type ComputeDispatchFee = contracts::DefaultDispatchFeeComputor; type TrieIdGenerator = contracts::TrieIdFromParentCounter; type GasPayment = (); + type RentPayment = (); type SignedClaimHandicap = contracts::DefaultSignedClaimHandicap; type TombstoneDeposit = TombstoneDeposit; type StorageSizeOffset = contracts::DefaultStorageSizeOffset; diff --git a/srml/contracts/src/lib.rs b/srml/contracts/src/lib.rs index 4346211ab6..8eaef951ba 100644 --- a/srml/contracts/src/lib.rs +++ b/srml/contracts/src/lib.rs @@ -355,6 +355,9 @@ pub trait Trait: system::Trait { /// Handler for the unbalanced reduction when making a gas payment. type GasPayment: OnUnbalanced>; + /// Handler for rent payments. + type RentPayment: OnUnbalanced>; + /// Number of block delay an extrinsic claim surcharge has. /// /// When claim surcharge is called by an extrinsic the rent is checked diff --git a/srml/contracts/src/rent.rs b/srml/contracts/src/rent.rs index 776f804ee7..ecc5f61031 100644 --- a/srml/contracts/src/rent.rs +++ b/srml/contracts/src/rent.rs @@ -17,7 +17,7 @@ use crate::{BalanceOf, ContractInfo, ContractInfoOf, TombstoneContractInfo, Trait, AliveContractInfo}; use sr_primitives::traits::{Bounded, CheckedDiv, CheckedMul, Saturating, Zero, SaturatedConversion}; -use support::traits::{Currency, ExistenceRequirement, Get, WithdrawReason}; +use support::traits::{Currency, ExistenceRequirement, Get, WithdrawReason, OnUnbalanced}; use support::StorageMap; #[derive(PartialEq, Eq, Copy, Clone)] @@ -126,7 +126,7 @@ fn try_evict_or_and_pay_rent( if can_withdraw_rent && (insufficient_rent || pay_rent) { // Collect dues. - let _ = T::Currency::withdraw( + let imbalance = T::Currency::withdraw( account, dues_limited, WithdrawReason::Fee, @@ -137,6 +137,8 @@ fn try_evict_or_and_pay_rent( dues_limited < rent_budget < balance - subsistence < balance - existential_deposit; qed", ); + + T::RentPayment::on_unbalanced(imbalance); } if insufficient_rent || !can_withdraw_rent { diff --git a/srml/contracts/src/tests.rs b/srml/contracts/src/tests.rs index d3b52c334b..7a13a66de2 100644 --- a/srml/contracts/src/tests.rs +++ b/srml/contracts/src/tests.rs @@ -159,6 +159,7 @@ impl Trait for Test { type ComputeDispatchFee = DummyComputeDispatchFee; type TrieIdGenerator = DummyTrieIdGenerator; type GasPayment = (); + type RentPayment = (); type SignedClaimHandicap = SignedClaimHandicap; type TombstoneDeposit = TombstoneDeposit; type StorageSizeOffset = StorageSizeOffset; -- GitLab From a2ef57b517103ed119f1fa5781cafc44b6210bf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 23 Oct 2019 17:17:12 +0200 Subject: [PATCH 260/275] Throw an error if a bootnode is registered with two different peer ids (#3891) * Throw an error if a bootnode is registered with two different peer ids * Rename error * Fix compilation :( * Review feedback --- core/cli/src/lib.rs | 14 ++++++++------ core/network/src/error.rs | 29 +++++++++++++++++++++++++++- core/network/src/service.rs | 38 ++++++++++++++++++++++++++----------- node-template/src/cli.rs | 6 +++--- node-template/src/main.rs | 7 ++----- node/cli/src/lib.rs | 6 +++--- node/src/main.rs | 7 ++----- 7 files changed, 73 insertions(+), 34 deletions(-) diff --git a/core/cli/src/lib.rs b/core/cli/src/lib.rs index 51363445dc..3b4953312a 100644 --- a/core/cli/src/lib.rs +++ b/core/cli/src/lib.rs @@ -269,22 +269,24 @@ pub struct ParseAndPrepareRun<'a, RP> { impl<'a, RP> ParseAndPrepareRun<'a, RP> { /// Runs the command and runs the main client. - pub fn run( + pub fn run( self, spec_factory: S, exit: Exit, run_service: RS, ) -> error::Result<()> - where S: FnOnce(&str) -> Result>, String>, + where + S: FnOnce(&str) -> Result>, String>, + E: Into, RP: StructOpt + Clone, C: Default, G: RuntimeGenesis, - E: ChainSpecExtension, + CE: ChainSpecExtension, Exit: IntoExit, - RS: FnOnce(Exit, RunCmd, RP, Configuration) -> Result<(), String> + RS: FnOnce(Exit, RunCmd, RP, Configuration) -> Result<(), E> { let config = create_run_node_config( - self.params.left.clone(), spec_factory, self.impl_name, self.version + self.params.left.clone(), spec_factory, self.impl_name, self.version, )?; run_service(exit, self.params.left, self.params.right, config).map_err(Into::into) @@ -633,7 +635,7 @@ fn fill_config_keystore_password( } fn create_run_node_config( - cli: RunCmd, spec_factory: S, impl_name: &'static str, version: &VersionInfo + cli: RunCmd, spec_factory: S, impl_name: &'static str, version: &VersionInfo, ) -> error::Result> where C: Default, diff --git a/core/network/src/error.rs b/core/network/src/error.rs index 95a1dc5abe..c3f89e43c1 100644 --- a/core/network/src/error.rs +++ b/core/network/src/error.rs @@ -18,16 +18,42 @@ use client; +use libp2p::{PeerId, Multiaddr}; + +use std::fmt; + /// Result type alias for the network. pub type Result = std::result::Result; /// Error type for the network. -#[derive(Debug, derive_more::Display, derive_more::From)] +#[derive(derive_more::Display, derive_more::From)] pub enum Error { /// Io error Io(std::io::Error), /// Client error Client(client::error::Error), + /// The same bootnode (based on address) is registered with two different peer ids. + #[display( + fmt = "The same bootnode (`{}`) is registered with two different peer ids: `{}` and `{}`", + address, + first_id, + second_id, + )] + DuplicateBootnode { + /// The address of the bootnode. + address: Multiaddr, + /// The first peer id that was found for the bootnode. + first_id: PeerId, + /// The second peer id that was found for the bootnode. + second_id: PeerId, + }, +} + +// Make `Debug` use the `Display` implementation. +impl fmt::Debug for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self, f) + } } impl std::error::Error for Error { @@ -35,6 +61,7 @@ impl std::error::Error for Error { match self { Error::Io(ref err) => Some(err), Error::Client(ref err) => Some(err), + Error::DuplicateBootnode { .. } => None, } } } diff --git a/core/network/src/service.rs b/core/network/src/service.rs index 5e8d41340c..1c44826062 100644 --- a/core/network/src/service.rs +++ b/core/network/src/service.rs @@ -52,14 +52,11 @@ use crate::protocol::specialization::NetworkSpecialization; use crate::protocol::sync::SyncState; /// Minimum Requirements for a Hash within Networking -pub trait ExHashT: - ::std::hash::Hash + Eq + ::std::fmt::Debug + Clone + Send + Sync + 'static -{ -} +pub trait ExHashT: std::hash::Hash + Eq + std::fmt::Debug + Clone + Send + Sync + 'static {} + impl ExHashT for T where - T: ::std::hash::Hash + Eq + ::std::fmt::Debug + Clone + Send + Sync + 'static -{ -} + T: std::hash::Hash + Eq + std::fmt::Debug + Clone + Send + Sync + 'static +{} /// Transaction pool interface pub trait TransactionPool: Send + Sync { @@ -152,6 +149,23 @@ impl, H: ExHashT> NetworkWorker } } + // Check for duplicate bootnodes. + known_addresses.iter() + .try_for_each(|(peer_id, addr)| + if let Some(other) = known_addresses + .iter() + .find(|o| o.1 == *addr && o.0 != *peer_id) + { + Err(Error::DuplicateBootnode { + address: addr.clone(), + first_id: peer_id.clone(), + second_id: other.0.clone(), + }) + } else { + Ok(()) + } + )?; + // Initialize the reserved peers. for reserved in params.network_config.reserved_nodes.iter() { if let Ok((peer_id, addr)) = parse_str_addr(reserved) { @@ -553,8 +567,9 @@ impl, H: ExHashT> NetworkServic } } -impl, H: ExHashT> - ::consensus::SyncOracle for NetworkService { +impl, H: ExHashT> consensus::SyncOracle + for NetworkService +{ fn is_major_syncing(&mut self) -> bool { NetworkService::is_major_syncing(self) } @@ -564,8 +579,9 @@ impl, H: ExHashT> } } -impl<'a, B: BlockT + 'static, S: NetworkSpecialization, H: ExHashT> - ::consensus::SyncOracle for &'a NetworkService { +impl<'a, B: BlockT + 'static, S: NetworkSpecialization, H: ExHashT> consensus::SyncOracle + for &'a NetworkService +{ fn is_major_syncing(&mut self) -> bool { NetworkService::is_major_syncing(self) } diff --git a/node-template/src/cli.rs b/node-template/src/cli.rs index f0b429e0fa..15c1a0486f 100644 --- a/node-template/src/cli.rs +++ b/node-template/src/cli.rs @@ -29,15 +29,15 @@ pub fn run(args: I, exit: E, version: VersionInfo) -> error::Result<()> match config.roles { ServiceRoles::LIGHT => run_until_exit( runtime, - service::new_light(config).map_err(|e| format!("{:?}", e))?, + service::new_light(config)?, exit ), _ => run_until_exit( runtime, - service::new_full(config).map_err(|e| format!("{:?}", e))?, + service::new_full(config)?, exit ), - }.map_err(|e| format!("{:?}", e)) + } }), ParseAndPrepare::BuildSpec(cmd) => cmd.run(load_spec), ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder(|config: Config<_>| diff --git a/node-template/src/main.rs b/node-template/src/main.rs index 024efcc7db..1f286a2237 100644 --- a/node-template/src/main.rs +++ b/node-template/src/main.rs @@ -10,7 +10,7 @@ mod cli; pub use substrate_cli::{VersionInfo, IntoExit, error}; -fn main() { +fn main() -> Result<(), cli::error::Error> { let version = VersionInfo { name: "Substrate Node", commit: env!("VERGEN_SHA_SHORT"), @@ -21,8 +21,5 @@ fn main() { support_url: "support.anonymous.an", }; - if let Err(e) = cli::run(::std::env::args(), cli::Exit, version) { - eprintln!("Fatal error: {}\n\n{:?}", e, e); - std::process::exit(1) - } + cli::run(std::env::args(), cli::Exit, version) } diff --git a/node/cli/src/lib.rs b/node/cli/src/lib.rs index 7eb3bb89c3..d339952ca8 100644 --- a/node/cli/src/lib.rs +++ b/node/cli/src/lib.rs @@ -172,15 +172,15 @@ pub fn run(args: I, exit: E, version: cli::VersionInfo) -> error::Resul match config.roles { ServiceRoles::LIGHT => run_until_exit( runtime, - service::new_light(config).map_err(|e| format!("{:?}", e))?, + service::new_light(config)?, exit ), _ => run_until_exit( runtime, - service::new_full(config).map_err(|e| format!("{:?}", e))?, + service::new_full(config)?, exit ), - }.map_err(|e| format!("{:?}", e)) + } }), ParseAndPrepare::BuildSpec(cmd) => cmd.run(load_spec), ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder(|config: Config<_, _>| diff --git a/node/src/main.rs b/node/src/main.rs index ca4a6b4c60..9f76cf638c 100644 --- a/node/src/main.rs +++ b/node/src/main.rs @@ -43,7 +43,7 @@ impl cli::IntoExit for Exit { } } -fn main() { +fn main() -> Result<(), cli::error::Error> { let version = VersionInfo { name: "Substrate Node", commit: env!("VERGEN_SHA_SHORT"), @@ -54,8 +54,5 @@ fn main() { support_url: "https://github.com/paritytech/substrate/issues/new", }; - if let Err(e) = cli::run(::std::env::args(), Exit, version) { - eprintln!("Fatal error: {}\n\n{:?}", e, e); - std::process::exit(1) - } + cli::run(std::env::args(), Exit, version) } -- GitLab From 772e0ee2d745a0e502cb71be58dc5775b5e53a74 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Wed, 23 Oct 2019 22:04:42 +0200 Subject: [PATCH 261/275] Fix phragmen election to wasm (#3898) * Fix phragmen-election compile to wasm * Fix chain_spec stuff * Fix panic with no term duration --- Cargo.lock | 2 +- node/cli/src/chain_spec.rs | 8 ++--- node/primitives/src/lib.rs | 5 +-- node/runtime/Cargo.toml | 4 +-- node/runtime/src/lib.rs | 34 +++++-------------- node/testing/src/genesis.rs | 2 +- srml/elections-phragmen/src/lib.rs | 53 +++++++++++++++++++++++++++--- 7 files changed, 66 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f12014a220..96c7bfa1e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2484,7 +2484,7 @@ dependencies = [ "srml-contracts 2.0.0", "srml-contracts-rpc-runtime-api 2.0.0", "srml-democracy 2.0.0", - "srml-elections 2.0.0", + "srml-elections-phragmen 2.0.0", "srml-executive 2.0.0", "srml-finality-tracker 2.0.0", "srml-grandpa 2.0.0", diff --git a/node/cli/src/chain_spec.rs b/node/cli/src/chain_spec.rs index d81591290e..bc9f1e615f 100644 --- a/node/cli/src/chain_spec.rs +++ b/node/cli/src/chain_spec.rs @@ -235,11 +235,11 @@ pub fn testnet_genesis( members: vec![], phantom: Default::default(), }), - elections: Some(ElectionsConfig { - members: vec![], - presentation_duration: 1 * DAYS, + elections_phragmen: Some(ElectionsConfig { + members: endowed_accounts.iter().take(2).cloned().collect(), term_duration: 28 * DAYS, - desired_seats: 0, + desired_members: 4, + desired_runners_up: 1, }), contracts: Some(ContractsConfig { current_schedule: contracts::Schedule { diff --git a/node/primitives/src/lib.rs b/node/primitives/src/lib.rs index 431ba17c00..6b128db4f3 100644 --- a/node/primitives/src/lib.rs +++ b/node/primitives/src/lib.rs @@ -60,9 +60,6 @@ pub type DigestItem = generic::DigestItem; /// Header type. pub type Header = generic::Header; /// Block type. -pub type Block = generic::Block; +pub type Block = generic::Block; /// Block ID. pub type BlockId = generic::BlockId; - -/// Opaque, encoded, unchecked extrinsic. -pub type UncheckedExtrinsic = OpaqueExtrinsic; diff --git a/node/runtime/Cargo.toml b/node/runtime/Cargo.toml index d65112da24..252a7767ea 100644 --- a/node/runtime/Cargo.toml +++ b/node/runtime/Cargo.toml @@ -33,7 +33,7 @@ collective = { package = "srml-collective", path = "../../srml/collective", defa contracts = { package = "srml-contracts", path = "../../srml/contracts", default-features = false } contracts-rpc-runtime-api = { package = "srml-contracts-rpc-runtime-api", path = "../../srml/contracts/rpc/runtime-api/", default-features = false } democracy = { package = "srml-democracy", path = "../../srml/democracy", default-features = false } -elections = { package = "srml-elections", path = "../../srml/elections", default-features = false } +elections-phragmen = { package = "srml-elections-phragmen", path = "../../srml/elections-phragmen", default-features = false } executive = { package = "srml-executive", path = "../../srml/executive", default-features = false } finality-tracker = { package = "srml-finality-tracker", path = "../../srml/finality-tracker", default-features = false } grandpa = { package = "srml-grandpa", path = "../../srml/grandpa", default-features = false } @@ -72,7 +72,7 @@ std = [ "contracts/std", "contracts-rpc-runtime-api/std", "democracy/std", - "elections/std", + "elections-phragmen/std", "executive/std", "finality-tracker/std", "grandpa/std", diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 1544ee9a4a..a198877552 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -45,7 +45,6 @@ use sr_primitives::traits::{ self, BlakeTwo256, Block as BlockT, NumberFor, StaticLookup, SaturatedConversion, }; use version::RuntimeVersion; -use elections::VoteIndex; #[cfg(any(feature = "std", test))] use version::NativeVersion; use primitives::OpaqueMetadata; @@ -84,8 +83,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 181, - impl_version: 183, + spec_version: 182, + impl_version: 182, apis: RUNTIME_API_VERSIONS, }; @@ -324,33 +323,18 @@ impl collective::Trait for Runtime { parameter_types! { pub const CandidacyBond: Balance = 10 * DOLLARS; pub const VotingBond: Balance = 1 * DOLLARS; - pub const VotingFee: Balance = 2 * DOLLARS; - pub const MinimumVotingLock: Balance = 1 * DOLLARS; - pub const PresentSlashPerVoter: Balance = 1 * CENTS; - pub const CarryCount: u32 = 6; - // one additional vote should go by before an inactive voter can be reaped. - pub const InactiveGracePeriod: VoteIndex = 1; - pub const ElectionsVotingPeriod: BlockNumber = 2 * DAYS; - pub const DecayRatio: u32 = 0; } -impl elections::Trait for Runtime { +impl elections_phragmen::Trait for Runtime { type Event = Event; type Currency = Balances; - type BadPresentation = (); - type BadReaper = (); - type BadVoterIndex = (); - type LoserCandidate = (); - type ChangeMembers = Council; + type CurrencyToVote = CurrencyToVoteHandler; type CandidacyBond = CandidacyBond; type VotingBond = VotingBond; - type VotingFee = VotingFee; - type MinimumVotingLock = MinimumVotingLock; - type PresentSlashPerVoter = PresentSlashPerVoter; - type CarryCount = CarryCount; - type InactiveGracePeriod = InactiveGracePeriod; - type VotingPeriod = ElectionsVotingPeriod; - type DecayRatio = DecayRatio; + type LoserCandidate = (); + type BadReport = (); + type KickedMember = (); + type ChangeMembers = Council; } type TechnicalCollective = collective::Instance2; @@ -518,7 +502,7 @@ construct_runtime!( Democracy: democracy::{Module, Call, Storage, Config, Event}, Council: collective::::{Module, Call, Storage, Origin, Event, Config}, TechnicalCommittee: collective::::{Module, Call, Storage, Origin, Event, Config}, - Elections: elections::{Module, Call, Storage, Event, Config}, + Elections: elections_phragmen::{Module, Call, Storage, Event, Config}, TechnicalMembership: membership::::{Module, Call, Storage, Event, Config}, FinalityTracker: finality_tracker::{Module, Call, Inherent}, Grandpa: grandpa::{Module, Call, Storage, Config, Event}, diff --git a/node/testing/src/genesis.rs b/node/testing/src/genesis.rs index 35ff93d1a6..a9f55d86e3 100644 --- a/node/testing/src/genesis.rs +++ b/node/testing/src/genesis.rs @@ -94,7 +94,7 @@ pub fn config(support_changes_trie: bool, code: Option<&[u8]>) -> GenesisConfig collective_Instance1: Some(Default::default()), collective_Instance2: Some(Default::default()), membership_Instance1: Some(Default::default()), - elections: Some(Default::default()), + elections_phragmen: Some(Default::default()), sudo: Some(Default::default()), } } diff --git a/srml/elections-phragmen/src/lib.rs b/srml/elections-phragmen/src/lib.rs index 781d506bd6..f56c5a4ec3 100644 --- a/srml/elections-phragmen/src/lib.rs +++ b/srml/elections-phragmen/src/lib.rs @@ -76,6 +76,7 @@ #![cfg_attr(not(feature = "std"), no_std)] +use rstd::prelude::*; use sr_primitives::{print, traits::{Zero, StaticLookup, Bounded, Convert}}; use sr_primitives::weights::SimpleDispatchInfo; use srml_support::{ @@ -136,7 +137,8 @@ decl_storage! { /// Number of runners_up to keep. pub DesiredRunnersUp get(fn desired_runners_up) config(): u32; /// How long each seat is kept. This defines the next block number at which an election - /// round will happen. + /// round will happen. If set to zero, no elections are ever triggered and the module will + /// be in passive mode. In that case only a member set defined in at genesis can exist. pub TermDuration get(fn term_duration) config(): T::BlockNumber; // ---- State @@ -470,8 +472,10 @@ impl Module { /// Runs phragmen election and cleans all the previous candidate state. The voter state is NOT /// cleaned and voters must themselves submit a transaction to retract. fn end_block(block_number: T::BlockNumber) -> dispatch::Result { - if (block_number % Self::term_duration()).is_zero() { - Self::do_phragmen(); + if !Self::term_duration().is_zero() { + if (block_number % Self::term_duration()).is_zero() { + Self::do_phragmen(); + } } Ok(()) } @@ -701,7 +705,9 @@ mod tests { pub struct ExtBuilder { balance_factor: u64, voter_bond: u64, + term_duration: u64, desired_runners_up: u32, + members: Vec, } impl Default for ExtBuilder { @@ -710,6 +716,8 @@ mod tests { balance_factor: 1, voter_bond: 2, desired_runners_up: 0, + term_duration: 5, + members: vec![], } } } @@ -723,6 +731,14 @@ mod tests { self.desired_runners_up = count; self } + pub fn term_duration(mut self, duration: u64) -> Self { + self.term_duration = duration; + self + } + pub fn members(mut self, members: Vec) -> Self { + self.members = members; + self + } pub fn build(self) -> runtime_io::TestExternalities { VOTING_BOND.with(|v| *v.borrow_mut() = self.voter_bond); GenesisConfig { @@ -738,10 +754,10 @@ mod tests { vesting: vec![], }), elections: Some(elections::GenesisConfig::{ - members: vec![], + members: self.members, desired_members: 2, desired_runners_up: self.desired_runners_up, - term_duration: 5, + term_duration: self.term_duration, }), }.build_storage().unwrap().into() } @@ -781,6 +797,33 @@ mod tests { }); } + #[test] + fn passive_module_should_work() { + ExtBuilder::default() + .term_duration(0) + .members(vec![1, 2, 3]) + .build() + .execute_with(|| + { + System::set_block_number(1); + assert_eq!(Elections::term_duration(), 0); + assert_eq!(Elections::desired_members(), 2); + assert_eq!(Elections::election_rounds(), 0); + + assert_eq!(Elections::members(), vec![1, 2, 3]); + assert_eq!(Elections::runners_up(), vec![]); + + assert_eq!(Elections::candidates(), vec![]); + assert_eq!(all_voters(), vec![]); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members(), vec![1, 2, 3]); + assert_eq!(Elections::runners_up(), vec![]); + }); + } + #[test] fn simple_candidate_submission_should_work() { ExtBuilder::default().build().execute_with(|| { -- GitLab From 5c6ce3f1d6f460cba6bc1952a6ae6567144d2237 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 23 Oct 2019 22:05:05 +0200 Subject: [PATCH 262/275] Remove support for secp256k1 for network keys (#3897) --- core/cli/src/lib.rs | 34 +--------------------------------- core/cli/src/params.rs | 12 ------------ core/network/Cargo.toml | 2 +- core/network/src/config.rs | 28 ++++------------------------ core/network/src/lib.rs | 4 +--- core/network/src/service.rs | 5 +---- 6 files changed, 8 insertions(+), 77 deletions(-) diff --git a/core/cli/src/lib.rs b/core/cli/src/lib.rs index 3b4953312a..b49f686ae6 100644 --- a/core/cli/src/lib.rs +++ b/core/cli/src/lib.rs @@ -68,11 +68,6 @@ use substrate_telemetry::TelemetryEndpoints; /// The maximum number of characters for a node name. const NODE_NAME_MAX_LENGTH: usize = 32; -/// The file name of the node's Secp256k1 secret key inside the chain-specific -/// network config directory, if neither `--node-key` nor `--node-key-file` -/// is specified in combination with `--node-key-type=secp256k1`. -const NODE_KEY_SECP256K1_FILE: &str = "secret"; - /// The file name of the node's Ed25519 secret key inside the chain-specific /// network config directory, if neither `--node-key` nor `--node-key-file` /// is specified in combination with `--node-key-type=ed25519`. @@ -494,14 +489,6 @@ where P: AsRef { match params.node_key_type { - NodeKeyType::Secp256k1 => - params.node_key.as_ref().map(parse_secp256k1_secret).unwrap_or_else(|| - Ok(params.node_key_file - .or_else(|| net_config_file(net_config_dir, NODE_KEY_SECP256K1_FILE)) - .map(network::config::Secret::File) - .unwrap_or(network::config::Secret::New))) - .map(NodeKeyConfig::Secp256k1), - NodeKeyType::Ed25519 => params.node_key.as_ref().map(parse_ed25519_secret).unwrap_or_else(|| Ok(params.node_key_file @@ -524,14 +511,6 @@ fn invalid_node_key(e: impl std::fmt::Display) -> error::Error { error::Error::Input(format!("Invalid node key: {}", e)) } -/// Parse a Secp256k1 secret key from a hex string into a `network::Secret`. -fn parse_secp256k1_secret(hex: &String) -> error::Result { - H256::from_str(hex).map_err(invalid_node_key).and_then(|bytes| - network::config::identity::secp256k1::SecretKey::from_bytes(bytes) - .map(network::config::Secret::Input) - .map_err(invalid_node_key)) -} - /// Parse a Ed25519 secret key from a hex string into a `network::Secret`. fn parse_ed25519_secret(hex: &String) -> error::Result { H256::from_str(&hex).map_err(invalid_node_key).and_then(|bytes| @@ -952,7 +931,7 @@ fn kill_color(s: &str) -> String { mod tests { use super::*; use tempdir::TempDir; - use network::config::identity::{secp256k1, ed25519}; + use network::config::identity::ed25519; #[test] fn tests_node_name_good() { @@ -975,7 +954,6 @@ mod tests { NodeKeyType::variants().into_iter().try_for_each(|t| { let node_key_type = NodeKeyType::from_str(t).unwrap(); let sk = match node_key_type { - NodeKeyType::Secp256k1 => secp256k1::SecretKey::generate().to_bytes().to_vec(), NodeKeyType::Ed25519 => ed25519::SecretKey::generate().as_ref().to_vec() }; let params = NodeKeyParams { @@ -984,9 +962,6 @@ mod tests { node_key_file: None }; node_key_config(params, &net_config_dir).and_then(|c| match c { - NodeKeyConfig::Secp256k1(network::config::Secret::Input(ref ski)) - if node_key_type == NodeKeyType::Secp256k1 && - &sk[..] == ski.to_bytes() => Ok(()), NodeKeyConfig::Ed25519(network::config::Secret::Input(ref ski)) if node_key_type == NodeKeyType::Ed25519 && &sk[..] == ski.as_ref() => Ok(()), @@ -1012,8 +987,6 @@ mod tests { node_key_file: Some(file.clone()) }; node_key_config(params, &net_config_dir).and_then(|c| match c { - NodeKeyConfig::Secp256k1(network::config::Secret::File(ref f)) - if node_key_type == NodeKeyType::Secp256k1 && f == &file => Ok(()), NodeKeyConfig::Ed25519(network::config::Secret::File(ref f)) if node_key_type == NodeKeyType::Ed25519 && f == &file => Ok(()), _ => Err(error::Error::Input("Unexpected node key config".into())) @@ -1046,8 +1019,6 @@ mod tests { let typ = params.node_key_type; node_key_config::(params, &None) .and_then(|c| match c { - NodeKeyConfig::Secp256k1(network::config::Secret::New) - if typ == NodeKeyType::Secp256k1 => Ok(()), NodeKeyConfig::Ed25519(network::config::Secret::New) if typ == NodeKeyType::Ed25519 => Ok(()), _ => Err(error::Error::Input("Unexpected node key config".into())) @@ -1061,9 +1032,6 @@ mod tests { let typ = params.node_key_type; node_key_config(params, &Some(net_config_dir.clone())) .and_then(move |c| match c { - NodeKeyConfig::Secp256k1(network::config::Secret::File(ref f)) - if typ == NodeKeyType::Secp256k1 && - f == &dir.join(NODE_KEY_SECP256K1_FILE) => Ok(()), NodeKeyConfig::Ed25519(network::config::Secret::File(ref f)) if typ == NodeKeyType::Ed25519 && f == &dir.join(NODE_KEY_ED25519_FILE) => Ok(()), diff --git a/core/cli/src/params.rs b/core/cli/src/params.rs index ae1c856622..4480736066 100644 --- a/core/cli/src/params.rs +++ b/core/cli/src/params.rs @@ -150,7 +150,6 @@ arg_enum! { #[allow(missing_docs)] #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum NodeKeyType { - Secp256k1, Ed25519 } } @@ -164,10 +163,6 @@ pub struct NodeKeyParams { /// The value is a string that is parsed according to the choice of /// `--node-key-type` as follows: /// - /// `secp256k1`: - /// The value is parsed as a hex-encoded Secp256k1 32 bytes secret key, - /// i.e. 64 hex characters. - /// /// `ed25519`: /// The value is parsed as a hex-encoded Ed25519 32 bytes secret key, /// i.e. 64 hex characters. @@ -198,10 +193,6 @@ pub struct NodeKeyParams { /// /// The node's secret key determines the corresponding public key and hence the /// node's peer ID in the context of libp2p. - /// - /// NOTE: The current default key type is `secp256k1` for a transition period only - /// but will eventually change to `ed25519` in a future release. To continue using - /// `secp256k1` keys, use `--node-key-type=secp256k1`. #[structopt( long = "node-key-type", value_name = "TYPE", @@ -216,9 +207,6 @@ pub struct NodeKeyParams { /// The contents of the file are parsed according to the choice of `--node-key-type` /// as follows: /// - /// `secp256k1`: - /// The file must contain an unencoded 32 bytes Secp256k1 secret key. - /// /// `ed25519`: /// The file must contain an unencoded 32 bytes Ed25519 secret key. /// diff --git a/core/network/Cargo.toml b/core/network/Cargo.toml index 016ddb8010..71e7d95bfa 100644 --- a/core/network/Cargo.toml +++ b/core/network/Cargo.toml @@ -22,7 +22,7 @@ linked_hash_set = "0.1.3" lru-cache = "0.1.2" rustc-hex = "2.0.1" rand = "0.7.2" -libp2p = { version = "0.12.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] } +libp2p = { version = "0.12.0", default-features = false, features = ["libp2p-websocket"] } fork-tree = { path = "../../core/utils/fork-tree" } consensus = { package = "substrate-consensus-common", path = "../../core/consensus/common" } client = { package = "substrate-client", path = "../../core/client" } diff --git a/core/network/src/config.rs b/core/network/src/config.rs index 0582fcb300..445d4427bd 100644 --- a/core/network/src/config.rs +++ b/core/network/src/config.rs @@ -29,7 +29,7 @@ use bitflags::bitflags; use consensus::{block_validation::BlockAnnounceValidator, import_queue::ImportQueue}; use sr_primitives::traits::{Block as BlockT}; use std::sync::Arc; -use libp2p::identity::{Keypair, secp256k1, ed25519}; +use libp2p::identity::{Keypair, ed25519}; use libp2p::wasm_ext; use libp2p::{PeerId, Multiaddr, multiaddr}; use std::error::Error; @@ -364,15 +364,10 @@ impl NonReservedPeerMode { /// the evaluation of the node key configuration. #[derive(Clone)] pub enum NodeKeyConfig { - /// A Secp256k1 secret key configuration. - Secp256k1(Secret), /// A Ed25519 secret key configuration. Ed25519(Secret) } -/// The options for obtaining a Secp256k1 secret key. -pub type Secp256k1Secret = Secret; - /// The options for obtaining a Ed25519 secret key. pub type Ed25519Secret = Secret; @@ -385,7 +380,6 @@ pub enum Secret { /// it is created with a newly generated secret key `K`. The format /// of the file is determined by `K`: /// - /// * `secp256k1::SecretKey`: An unencoded 32 bytes Secp256k1 secret key. /// * `ed25519::SecretKey`: An unencoded 32 bytes Ed25519 secret key. File(PathBuf), /// Always generate a new secret key `K`. @@ -406,20 +400,6 @@ impl NodeKeyConfig { pub fn into_keypair(self) -> io::Result { use NodeKeyConfig::*; match self { - Secp256k1(Secret::New) => - Ok(Keypair::generate_secp256k1()), - - Secp256k1(Secret::Input(k)) => - Ok(Keypair::Secp256k1(k.into())), - - Secp256k1(Secret::File(f)) => - get_secret(f, - |mut b| secp256k1::SecretKey::from_bytes(&mut b), - secp256k1::SecretKey::generate, - |b| b.to_bytes().to_vec()) - .map(secp256k1::Keypair::from) - .map(Keypair::Secp256k1), - Ed25519(Secret::New) => Ok(Keypair::generate_ed25519()), @@ -526,9 +506,9 @@ mod tests { #[test] fn test_secret_input() { - let sk = secp256k1::SecretKey::generate(); - let kp1 = NodeKeyConfig::Secp256k1(Secret::Input(sk.clone())).into_keypair().unwrap(); - let kp2 = NodeKeyConfig::Secp256k1(Secret::Input(sk)).into_keypair().unwrap(); + let sk = ed25519::SecretKey::generate(); + let kp1 = NodeKeyConfig::Ed25519(Secret::Input(sk.clone())).into_keypair().unwrap(); + let kp2 = NodeKeyConfig::Ed25519(Secret::Input(sk)).into_keypair().unwrap(); assert!(secret_bytes(&kp1) == secret_bytes(&kp2)); } diff --git a/core/network/src/lib.rs b/core/network/src/lib.rs index 7e9fd51a41..d0977d90c9 100644 --- a/core/network/src/lib.rs +++ b/core/network/src/lib.rs @@ -24,9 +24,7 @@ //! # Node identities and addresses //! //! In a decentralized network, each node possesses a network private key and a network public key. -//! In Substrate, the keys are based on the ed25519 curve. As of the writing of this documentation, -//! the secp256k1 curve can also be used, but is deprecated. Our local node's keypair must be -//! passed as part of the network configuration. +//! In Substrate, the keys are based on the ed25519 curve. //! //! From a node's public key, we can derive its *identity*. In Substrate and libp2p, a node's //! identity is represented with the [`PeerId`] struct. All network communications between nodes on diff --git a/core/network/src/service.rs b/core/network/src/service.rs index 1c44826062..48ad51bde3 100644 --- a/core/network/src/service.rs +++ b/core/network/src/service.rs @@ -42,7 +42,7 @@ use sr_primitives::{traits::{Block as BlockT, NumberFor}, ConsensusEngineId}; use crate::{behaviour::{Behaviour, BehaviourOut}, config::{parse_str_addr, parse_addr}}; use crate::{NetworkState, NetworkStateNotConnectedPeer, NetworkStatePeer}; -use crate::{transport, config::NodeKeyConfig, config::NonReservedPeerMode}; +use crate::{transport, config::NonReservedPeerMode}; use crate::config::{Params, TransportConfig}; use crate::error::Error; use crate::protocol::{self, Protocol, Context, CustomMessageOutcome, PeerInfo}; @@ -185,9 +185,6 @@ impl, H: ExHashT> NetworkWorker }; // Private and public keys configuration. - if let NodeKeyConfig::Secp256k1(_) = params.network_config.node_key { - warn!(target: "sub-libp2p", "Secp256k1 keys are deprecated in favour of ed25519"); - } let local_identity = params.network_config.node_key.clone().into_keypair()?; let local_public = local_identity.public(); let local_peer_id = local_public.clone().into_peer_id(); -- GitLab From eda5fe5cf0f8e56d90f8cd913ffcb118362df559 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 23 Oct 2019 22:05:24 +0200 Subject: [PATCH 263/275] Split the telemetry net status report in two (#3887) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Split the telemetry net status report in two * Update core/service/src/lib.rs Co-Authored-By: Bastian Köcher * Remove clone() * Move code to status_sinks.rs instead * Add basic usage for status_sinks * Update core/service/src/status_sinks.rs Co-Authored-By: Bastian Köcher --- Cargo.lock | 1 + core/cli/src/informant.rs | 13 +-- core/service/Cargo.toml | 1 + core/service/src/builder.rs | 1 + core/service/src/lib.rs | 48 +++++----- core/service/src/status_sinks.rs | 149 +++++++++++++++++++++++++++++++ 6 files changed, 188 insertions(+), 25 deletions(-) create mode 100644 core/service/src/status_sinks.rs diff --git a/Cargo.lock b/Cargo.lock index 96c7bfa1e6..a87da6586c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5539,6 +5539,7 @@ dependencies = [ "substrate-transaction-pool 2.0.0", "sysinfo 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)", "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/core/cli/src/informant.rs b/core/cli/src/informant.rs index 9d7f04b8f6..f7c23ba479 100644 --- a/core/cli/src/informant.rs +++ b/core/cli/src/informant.rs @@ -22,6 +22,7 @@ use futures03::{StreamExt as _, TryStreamExt as _}; use log::{info, warn}; use sr_primitives::traits::Header; use service::AbstractService; +use std::time::Duration; mod display; @@ -31,11 +32,13 @@ pub fn build(service: &impl AbstractService) -> impl Future { select_chain: Option, network: Arc, /// Sinks to propagate network status updates. - network_status_sinks: Arc>>>, + /// For each element, every time the `Interval` fires we push an element on the sender. + network_status_sinks: Arc>>, transaction_pool: Arc, /// A future that resolves when the service has exited, this is useful to /// make sure any internally spawned futures stop when the service does. @@ -210,7 +211,7 @@ macro_rules! new_impl { let has_bootnodes = !network_params.network_config.boot_nodes.is_empty(); let network_mut = network::NetworkWorker::new(network_params)?; let network = network_mut.service().clone(); - let network_status_sinks = Arc::new(Mutex::new(Vec::new())); + let network_status_sinks = Arc::new(Mutex::new(status_sinks::StatusSinks::new())); let offchain_storage = backend.offchain_storage(); let offchain_workers = match ($config.offchain_worker, offchain_storage) { @@ -296,9 +297,9 @@ macro_rules! new_impl { let client_ = client.clone(); let mut sys = System::new(); let self_pid = get_current_pid().ok(); - let (netstat_tx, netstat_rx) = mpsc::unbounded::<(NetworkStatus<_>, NetworkState)>(); - network_status_sinks.lock().push(netstat_tx); - let tel_task = netstat_rx.for_each(move |(net_status, network_state)| { + let (state_tx, state_rx) = mpsc::unbounded::<(NetworkStatus<_>, NetworkState)>(); + network_status_sinks.lock().push(std::time::Duration::from_millis(5000), state_tx); + let tel_task = state_rx.for_each(move |(net_status, _)| { let info = client_.info(); let best_number = info.chain.best_number.saturated_into::(); let best_hash = info.chain.best_hash; @@ -325,7 +326,6 @@ macro_rules! new_impl { telemetry!( SUBSTRATE_INFO; "system.interval"; - "network_state" => network_state, "peers" => num_peers, "height" => best_number, "best" => ?best_hash, @@ -343,6 +343,19 @@ macro_rules! new_impl { }).select(exit.clone()).then(|_| Ok(())); let _ = to_spawn_tx.unbounded_send(Box::new(tel_task)); + // Periodically send the network state to the telemetry. + let (netstat_tx, netstat_rx) = mpsc::unbounded::<(NetworkStatus<_>, NetworkState)>(); + network_status_sinks.lock().push(std::time::Duration::from_secs(30), netstat_tx); + let tel_task_2 = netstat_rx.for_each(move |(_, network_state)| { + telemetry!( + SUBSTRATE_INFO; + "system.network_state"; + "state" => network_state, + ); + Ok(()) + }).select(exit.clone()).then(|_| Ok(())); + let _ = to_spawn_tx.unbounded_send(Box::new(tel_task_2)); + // RPC let (system_rpc_tx, system_rpc_rx) = futures03::channel::mpsc::unbounded(); let gen_handler = || { @@ -507,7 +520,7 @@ pub trait AbstractService: 'static + Future + fn network(&self) -> Arc>; /// Returns a receiver that periodically receives a status of the network. - fn network_status(&self) -> mpsc::UnboundedReceiver<(NetworkStatus, NetworkState)>; + fn network_status(&self, interval: Duration) -> mpsc::UnboundedReceiver<(NetworkStatus, NetworkState)>; /// Get shared transaction pool instance. fn transaction_pool(&self) -> Arc>; @@ -590,9 +603,9 @@ where self.network.clone() } - fn network_status(&self) -> mpsc::UnboundedReceiver<(NetworkStatus, NetworkState)> { + fn network_status(&self, interval: Duration) -> mpsc::UnboundedReceiver<(NetworkStatus, NetworkState)> { let (sink, stream) = mpsc::unbounded(); - self.network_status_sinks.lock().push(sink); + self.network_status_sinks.lock().push(interval, sink); stream } @@ -666,7 +679,7 @@ fn build_network_future< roles: Roles, mut network: network::NetworkWorker, client: Arc, - status_sinks: Arc, NetworkState)>>>>, + status_sinks: Arc, NetworkState)>>>, rpc_rx: futures03::channel::mpsc::UnboundedReceiver>, should_have_peers: bool, dht_event_tx: Option>, @@ -675,10 +688,6 @@ fn build_network_future< // See https://github.com/paritytech/substrate/issues/3099 let mut rpc_rx = futures03::compat::Compat::new(rpc_rx.map(|v| Ok::<_, ()>(v))); - // Interval at which we send status updates on the status stream. - const STATUS_INTERVAL: Duration = Duration::from_millis(5000); - let mut status_interval = tokio_timer::Interval::new_interval(STATUS_INTERVAL); - let mut imported_blocks_stream = client.import_notification_stream().fuse() .map(|v| Ok::<_, ()>(v)).compat(); let mut finality_notification_stream = client.finality_notification_stream().fuse() @@ -746,7 +755,7 @@ fn build_network_future< } // Interval report for the external API. - while let Ok(Async::Ready(_)) = status_interval.poll() { + status_sinks.lock().poll(|| { let status = NetworkStatus { sync_state: network.sync_state(), best_seen_block: network.best_seen_block(), @@ -757,9 +766,8 @@ fn build_network_future< average_upload_per_sec: network.average_upload_per_sec(), }; let state = network.network_state(); - - status_sinks.lock().retain(|sink| sink.unbounded_send((status.clone(), state.clone())).is_ok()); - } + (status, state) + }); // Main network polling. while let Ok(Async::Ready(Some(Event::Dht(event)))) = network.poll().map_err(|err| { diff --git a/core/service/src/status_sinks.rs b/core/service/src/status_sinks.rs new file mode 100644 index 0000000000..079ecf6353 --- /dev/null +++ b/core/service/src/status_sinks.rs @@ -0,0 +1,149 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use futures::prelude::*; +use futures::sync::mpsc; +use futures::stream::futures_unordered::FuturesUnordered; +use std::time::{Duration, Instant}; +use tokio_timer::Delay; + +/// Holds a list of `UnboundedSender`s, each associated with a certain time period. Every time the +/// period elapses, we push an element on the sender. +/// +/// Senders are removed only when they are closed. +pub struct StatusSinks { + entries: FuturesUnordered>, +} + +struct YieldAfter { + delay: tokio_timer::Delay, + interval: Duration, + sender: Option>, +} + +impl StatusSinks { + /// Builds a new empty collection. + pub fn new() -> StatusSinks { + StatusSinks { + entries: FuturesUnordered::new(), + } + } + + /// Adds a sender to the collection. + /// + /// The `interval` is the time period between two pushes on the sender. + pub fn push(&mut self, interval: Duration, sender: mpsc::UnboundedSender) { + self.entries.push(YieldAfter { + delay: Delay::new(Instant::now() + interval), + interval, + sender: Some(sender), + }) + } + + /// Processes all the senders. If any sender is ready, calls the `status_grab` function and + /// pushes what it returns to the sender. + /// + /// This function doesn't return anything, but it should be treated as if it implicitly + /// returns `Ok(Async::NotReady)`. In particular, it should be called again when the task + /// is waken up. + /// + /// # Panic + /// + /// Panics if not called within the context of a task. + pub fn poll(&mut self, mut status_grab: impl FnMut() -> T) { + loop { + match self.entries.poll() { + Ok(Async::Ready(Some((sender, interval)))) => { + let status = status_grab(); + if sender.unbounded_send(status).is_ok() { + self.entries.push(YieldAfter { + // Note that since there's a small delay between the moment a task is + // waken up and the moment it is polled, the period is actually not + // `interval` but `interval + `. We ignore this problem in + // practice. + delay: Delay::new(Instant::now() + interval), + interval, + sender: Some(sender), + }); + } + } + Err(()) | + Ok(Async::Ready(None)) | + Ok(Async::NotReady) => break, + } + } + } +} + +impl Future for YieldAfter { + type Item = (mpsc::UnboundedSender, Duration); + type Error = (); + + fn poll(&mut self) -> Poll { + match self.delay.poll() { + Ok(Async::NotReady) => Ok(Async::NotReady), + Ok(Async::Ready(())) => { + let sender = self.sender.take() + .expect("sender is always Some unless the future is finished; qed"); + Ok(Async::Ready((sender, self.interval))) + }, + Err(_) => Err(()), + } + } +} + +#[cfg(test)] +mod tests { + use super::StatusSinks; + use futures::prelude::*; + use futures::sync::mpsc; + use std::time::Duration; + + #[test] + fn basic_usage() { + let mut status_sinks = StatusSinks::new(); + + let (tx1, rx1) = mpsc::unbounded(); + status_sinks.push(Duration::from_millis(200), tx1); + + let (tx2, rx2) = mpsc::unbounded(); + status_sinks.push(Duration::from_millis(500), tx2); + + let mut runtime = tokio::runtime::Runtime::new().unwrap(); + + let mut val_order = 5; + runtime.spawn(futures::future::poll_fn(move || { + status_sinks.poll(|| { val_order += 1; val_order }); + Ok(Async::NotReady) + })); + + let done = rx1 + .into_future() + .and_then(|(item, rest)| { + assert_eq!(item, Some(6)); + rest.into_future() + }) + .and_then(|(item, _)| { + assert_eq!(item, Some(7)); + rx2.into_future() + }) + .map(|(item, _)| { + assert_eq!(item, Some(8)); + }); + + runtime.block_on(done).unwrap(); + } +} -- GitLab From e17836bb4cd5b1203416a980f28c0422c1491022 Mon Sep 17 00:00:00 2001 From: Ryan Bell Date: Thu, 24 Oct 2019 00:29:58 -0700 Subject: [PATCH 264/275] Update README.adoc (#3900) --- README.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.adoc b/README.adoc index 6563340cc6..bb23958bce 100644 --- a/README.adoc +++ b/README.adoc @@ -418,7 +418,7 @@ curl -H 'Content-Type: application/json' --data '{ "jsonrpc":"2.0", "method":"au === Viewing documentation for Substrate packages You can generate documentation for a Substrate Rust package and have it automatically open in your web browser using https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html#using-rustdoc-with-cargo[rustdoc with Cargo], -(of the The Rustdoc Book), by running the the following command: +(of the The Rustdoc Book), by running the following command: ``` cargo doc --package --open -- GitLab From a1226ebdae46ebd27f36f439b633bc809614bd30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Thu, 24 Oct 2019 09:14:32 +0100 Subject: [PATCH 265/275] node: spawn grandpa voter as essential task (#3899) * node: spawn grandpa voter as essential task * node: stop babe authoring task on exit * node: remove unnecessary future boxing * Apply suggestions from code review --- node-template/src/service.rs | 8 ++++---- node/cli/src/service.rs | 9 ++++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/node-template/src/service.rs b/node-template/src/service.rs index 7934355812..c46928c10e 100644 --- a/node-template/src/service.rs +++ b/node-template/src/service.rs @@ -115,11 +115,11 @@ pub fn new_full(config: Configuration(config: Configuration { // start the lightweight GRANDPA observer - service.spawn_task(Box::new(grandpa::run_grandpa_observer( + service.spawn_task(grandpa::run_grandpa_observer( grandpa_config, grandpa_link, service.network(), service.on_exit(), - )?)); + )?); }, (true, false) => { // start the full GRANDPA voter diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index 983908c07d..0f4a098f3d 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -175,6 +175,7 @@ macro_rules! new_full { service.network(), dht_event_rx, ); + service.spawn_task(authority_discovery); } @@ -189,12 +190,12 @@ macro_rules! new_full { match (is_authority, disable_grandpa) { (false, false) => { // start the lightweight GRANDPA observer - service.spawn_task(Box::new(grandpa::run_grandpa_observer( + service.spawn_task(grandpa::run_grandpa_observer( config, grandpa_link, service.network(), service.on_exit(), - )?)); + )?); }, (true, false) => { // start the full GRANDPA voter @@ -207,7 +208,9 @@ macro_rules! new_full { telemetry_on_connect: Some(service.telemetry_on_connect_stream()), voting_rule: grandpa::VotingRulesBuilder::default().build(), }; - service.spawn_task(Box::new(grandpa::run_grandpa_voter(grandpa_config)?)); + // the GRANDPA voter task is considered infallible, i.e. + // if it fails we take down the service with it. + service.spawn_essential_task(grandpa::run_grandpa_voter(grandpa_config)?); }, (_, true) => { grandpa::setup_disabled_grandpa( -- GitLab From cc0b1d08d6e0e7e9690947f484c9a1e2265bf05d Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Thu, 24 Oct 2019 10:59:09 +0200 Subject: [PATCH 266/275] Add SECP256k1/ECDSA support for transaction signing (#3861) * Add SECP256k1/ECDSA support for transaction signing. * Refactoring and fixes * Fix for contracts * Avoid breaking runtime host function * Build fixes, make subkey work more generaically. * Fix tests * Dedpulicate a bit of code, remove unneeded code, docs * Bump runtime version * Fix a test and clean up some code. * Derivation can derive seed. * Whitespace * Bump runtime again. * Update core/primitives/src/crypto.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update core/primitives/src/ecdsa.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Fix AppVerify --- Cargo.lock | 2 + core/application-crypto/src/lib.rs | 13 +- core/application-crypto/src/traits.rs | 1 + core/executor/src/host_interface.rs | 82 ++- core/keyring/src/ed25519.rs | 15 + core/keyring/src/sr25519.rs | 15 + core/primitives/Cargo.toml | 4 + core/primitives/src/crypto.rs | 286 +++++--- core/primitives/src/ecdsa.rs | 608 ++++++++++++++++++ core/primitives/src/ed25519.rs | 20 +- core/primitives/src/hexdisplay.rs | 2 +- core/primitives/src/lib.rs | 1 + core/primitives/src/sr25519.rs | 53 +- core/sr-io/src/lib.rs | 9 +- core/sr-io/with_std.rs | 10 + core/sr-io/without_std.rs | 24 + .../src/generic/unchecked_extrinsic.rs | 22 +- core/sr-primitives/src/lib.rs | 60 +- core/sr-primitives/src/traits.rs | 73 ++- node/cli/src/chain_spec.rs | 67 +- node/cli/src/factory_impl.rs | 13 +- node/cli/src/service.rs | 17 +- node/primitives/src/lib.rs | 9 +- node/runtime/src/lib.rs | 59 +- node/testing/src/keyring.rs | 6 +- srml/system/src/offchain.rs | 71 +- subkey/src/cli.yml | 5 + subkey/src/main.rs | 146 +++-- subkey/src/vanity.rs | 6 +- test-utils/chain-spec-builder/src/main.rs | 6 +- 30 files changed, 1286 insertions(+), 419 deletions(-) create mode 100644 core/primitives/src/ecdsa.rs diff --git a/Cargo.lock b/Cargo.lock index a87da6586c..14f8c87c1a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5366,6 +5366,7 @@ dependencies = [ "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "impl-serde 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libsecp256k1 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5385,6 +5386,7 @@ dependencies = [ "substrate-primitives-storage 2.0.0", "substrate-serializer 2.0.0", "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "twox-hash 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmi 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/core/application-crypto/src/lib.rs b/core/application-crypto/src/lib.rs index 16eda53238..b4ada5425b 100644 --- a/core/application-crypto/src/lib.rs +++ b/core/application-crypto/src/lib.rs @@ -88,22 +88,13 @@ macro_rules! app_crypto { } fn derive< Iter: Iterator - >(&self, path: Iter) -> Result { - self.0.derive(path).map(Self) + >(&self, path: Iter, seed: Option) -> Result<(Self, Option), Self::DeriveError> { + self.0.derive(path, seed).map(|x| (Self(x.0), x.1)) } fn from_seed(seed: &Self::Seed) -> Self { Self(<$pair>::from_seed(seed)) } fn from_seed_slice(seed: &[u8]) -> Result { <$pair>::from_seed_slice(seed).map(Self) } - fn from_standard_components< - I: Iterator - >( - seed: &str, - password: Option<&str>, - path: I, - ) -> Result { - <$pair>::from_standard_components::(seed, password, path).map(Self) - } fn sign(&self, msg: &[u8]) -> Self::Signature { Signature(self.0.sign(msg)) } diff --git a/core/application-crypto/src/traits.rs b/core/application-crypto/src/traits.rs index 49d3a44aee..66e6cd6579 100644 --- a/core/application-crypto/src/traits.rs +++ b/core/application-crypto/src/traits.rs @@ -126,3 +126,4 @@ pub trait RuntimeAppPublic: Sized { /// Verify that the given signature matches the given message using this public key. fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool; } + diff --git a/core/executor/src/host_interface.rs b/core/executor/src/host_interface.rs index e6386ff1ac..7d87d93333 100644 --- a/core/executor/src/host_interface.rs +++ b/core/executor/src/host_interface.rs @@ -41,6 +41,40 @@ macro_rules! debug_trace { pub struct SubstrateExternals; +enum RecoverResult { + Invalid(u32), + Valid(secp256k1::PublicKey), +} + +fn secp256k1_recover( + context: &mut dyn FunctionContext, + msg_data: Pointer, + sig_data: Pointer, +) -> WResult { + let mut sig = [0u8; 65]; + context.read_memory_into(sig_data, &mut sig[..]) + .map_err(|_| "Invalid attempt to get signature in ext_secp256k1_ecdsa_recover")?; + let rs = match secp256k1::Signature::parse_slice(&sig[0..64]) { + Ok(rs) => rs, + _ => return Ok(RecoverResult::Invalid(1)), + }; + + let recovery_id = if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as u8; + let v = match secp256k1::RecoveryId::parse(recovery_id) { + Ok(v) => v, + _ => return Ok(RecoverResult::Invalid(2)), + }; + + let mut msg = [0u8; 32]; + context.read_memory_into(msg_data, &mut msg[..]) + .map_err(|_| "Invalid attempt to get message in ext_secp256k1_ecdsa_recover")?; + + Ok(match secp256k1::recover(&secp256k1::Message::parse(&msg), &rs, &v) { + Ok(pubkey) => RecoverResult::Valid(pubkey), + Err(_) => RecoverResult::Invalid(3), + }) +} + impl_wasm_host_interface! { impl SubstrateExternals where context { ext_malloc(size: WordSize) -> Pointer { @@ -781,33 +815,29 @@ impl_wasm_host_interface! { sig_data: Pointer, pubkey_data: Pointer, ) -> u32 { - let mut sig = [0u8; 65]; - context.read_memory_into(sig_data, &mut sig[..]) - .map_err(|_| "Invalid attempt to get signature in ext_secp256k1_ecdsa_recover")?; - let rs = match secp256k1::Signature::parse_slice(&sig[0..64]) { - Ok(rs) => rs, - _ => return Ok(1), - }; - - let recovery_id = if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as u8; - let v = match secp256k1::RecoveryId::parse(recovery_id) { - Ok(v) => v, - _ => return Ok(2), - }; - - let mut msg = [0u8; 32]; - context.read_memory_into(msg_data, &mut msg[..]) - .map_err(|_| "Invalid attempt to get message in ext_secp256k1_ecdsa_recover")?; - - let pubkey = match secp256k1::recover(&secp256k1::Message::parse(&msg), &rs, &v) { - Ok(pk) => pk, - _ => return Ok(3), - }; - - context.write_memory(pubkey_data, &pubkey.serialize()[1..65]) - .map_err(|_| "Invalid attempt to set pubkey in ext_secp256k1_ecdsa_recover")?; + match secp256k1_recover(context, msg_data, sig_data)? { + RecoverResult::Invalid(c) => Ok(c), + RecoverResult::Valid(pubkey) => { + context.write_memory(pubkey_data, &pubkey.serialize()[1..65]) + .map_err(|_| "Invalid attempt to set pubkey in ext_secp256k1_ecdsa_recover")?; + Ok(0) + } + } + } - Ok(0) + ext_secp256k1_ecdsa_recover_compressed( + msg_data: Pointer, + sig_data: Pointer, + pubkey_data: Pointer, + ) -> u32 { + match secp256k1_recover(context, msg_data, sig_data)? { + RecoverResult::Invalid(c) => Ok(c), + RecoverResult::Valid(pubkey) => { + context.write_memory(pubkey_data, &pubkey.serialize_compressed()[..]) + .map_err(|_| "Invalid attempt to set pubkey in ext_secp256k1_ecdsa_recover")?; + Ok(0) + } + } } ext_is_validator() -> u32 { diff --git a/core/keyring/src/ed25519.rs b/core/keyring/src/ed25519.rs index 56bdb1ce8c..c1a357fc0e 100644 --- a/core/keyring/src/ed25519.rs +++ b/core/keyring/src/ed25519.rs @@ -20,6 +20,7 @@ use std::{collections::HashMap, ops::Deref}; use lazy_static::lazy_static; use primitives::{ed25519::{Pair, Public, Signature}, Pair as PairT, Public as PublicT, H256}; pub use primitives::ed25519; +use sr_primitives::AccountId32; /// Set of test accounts. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum_macros::Display, strum_macros::EnumIter)] @@ -39,6 +40,10 @@ impl Keyring { Self::iter().find(|&k| &Public::from(k) == who) } + pub fn from_account_id(who: &AccountId32) -> Option { + Self::iter().find(|&k| &k.to_account_id() == who) + } + pub fn from_raw_public(who: [u8; 32]) -> Option { Self::from_public(&Public::from_raw(who)) } @@ -59,6 +64,10 @@ impl Keyring { Public::from(self).to_raw_vec() } + pub fn to_account_id(self) -> AccountId32 { + self.to_raw_public().into() + } + pub fn sign(self, msg: &[u8]) -> Signature { Pair::from(self).sign(msg) } @@ -119,6 +128,12 @@ impl From for Public { } } +impl From for AccountId32 { + fn from(k: Keyring) -> Self { + k.to_account_id() + } +} + impl From for Pair { fn from(k: Keyring) -> Self { k.pair() diff --git a/core/keyring/src/sr25519.rs b/core/keyring/src/sr25519.rs index bb3aaa6b51..b37b2bdf9b 100644 --- a/core/keyring/src/sr25519.rs +++ b/core/keyring/src/sr25519.rs @@ -21,6 +21,7 @@ use std::ops::Deref; use lazy_static::lazy_static; use primitives::{sr25519::{Pair, Public, Signature}, Pair as PairT, Public as PublicT, H256}; pub use primitives::sr25519; +use sr_primitives::AccountId32; /// Set of test accounts. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum_macros::Display, strum_macros::EnumIter)] @@ -40,6 +41,10 @@ impl Keyring { Self::iter().find(|&k| &Public::from(k) == who) } + pub fn from_account_id(who: &AccountId32) -> Option { + Self::iter().find(|&k| &k.to_account_id() == who) + } + pub fn from_raw_public(who: [u8; 32]) -> Option { Self::from_public(&Public::from_raw(who)) } @@ -60,6 +65,10 @@ impl Keyring { Public::from(self).to_raw_vec() } + pub fn to_account_id(self) -> AccountId32 { + self.to_raw_public().into() + } + pub fn sign(self, msg: &[u8]) -> Signature { Pair::from(self).sign(msg) } @@ -114,6 +123,12 @@ lazy_static! { }; } +impl From for AccountId32 { + fn from(k: Keyring) -> Self { + k.to_account_id() + } +} + impl From for Public { fn from(k: Keyring) -> Self { (*PUBLIC_KEYS).get(&k).unwrap().clone() diff --git a/core/primitives/Cargo.toml b/core/primitives/Cargo.toml index 557ce55b88..bc8106de3a 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -31,6 +31,8 @@ num-traits = { version = "0.2.8", default-features = false } zeroize = "0.10.1" lazy_static = { version = "1.4.0", optional = true } parking_lot = { version = "0.9.0", optional = true } +libsecp256k1 = { version = "0.3.0", optional = true } +tiny-keccak = { version = "1.5.0", optional = true } substrate-debug-derive = { version = "2.0.0", path = "./debug-derive" } externalities = { package = "substrate-externalities", path = "../externalities", optional = true } primitives-storage = { package = "substrate-primitives-storage", path = "storage", default-features = false } @@ -82,6 +84,8 @@ std = [ "schnorrkel", "regex", "num-traits/std", + "libsecp256k1", + "tiny-keccak", "substrate-debug-derive/std", "externalities", "primitives-storage/std", diff --git a/core/primitives/src/crypto.rs b/core/primitives/src/crypto.rs index 588f3bc6e2..b7c70e6224 100644 --- a/core/primitives/src/crypto.rs +++ b/core/primitives/src/crypto.rs @@ -255,7 +255,7 @@ pub enum PublicError { /// Key that can be encoded to/from SS58. #[cfg(feature = "std")] -pub trait Ss58Codec: Sized { +pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default { /// Some if the string is a properly encoded SS58Check address. fn from_ss58check(s: &str) -> Result { Self::from_ss58check_with_version(s) @@ -269,7 +269,23 @@ pub trait Ss58Codec: Sized { }) } /// Some if the string is a properly encoded SS58Check address. - fn from_ss58check_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError>; + fn from_ss58check_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> { + let mut res = Self::default(); + let len = res.as_mut().len(); + let d = s.from_base58().map_err(|_| PublicError::BadBase58)?; // failure here would be invalid encoding. + if d.len() != len + 3 { + // Invalid length. + return Err(PublicError::BadLength); + } + let ver = d[0].try_into().map_err(|_: ()| PublicError::UnknownVersion)?; + + if d[len + 1..len + 3] != ss58hash(&d[0..len + 1]).as_bytes()[0..2] { + // Invalid checksum. + return Err(PublicError::InvalidChecksum); + } + res.as_mut().copy_from_slice(&d[1..len + 1]); + Ok((res, ver)) + } /// Some if the string is a properly encoded SS58Check address, optionally with /// a derivation path following. fn from_string(s: &str) -> Result { @@ -285,7 +301,13 @@ pub trait Ss58Codec: Sized { } /// Return the ss58-check string for this key. - fn to_ss58check_with_version(&self, version: Ss58AddressFormat) -> String; + fn to_ss58check_with_version(&self, version: Ss58AddressFormat) -> String { + let mut v = vec![version.into()]; + v.extend(self.as_ref()); + let r = ss58hash(&v); + v.extend(&r.as_bytes()[0..2]); + v.to_base58() + } /// Return the ss58-check string for this key. fn to_ss58check(&self) -> String { self.to_ss58check_with_version(*DEFAULT_VERSION.lock()) } /// Some if the string is a properly encoded SS58Check address, optionally with @@ -408,44 +430,28 @@ pub fn set_default_ss58_version(version: Ss58AddressFormat) { } #[cfg(feature = "std")] -impl + AsRef<[u8]> + Default + Derive> Ss58Codec for T { - fn from_ss58check_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> { - let mut res = T::default(); - let len = res.as_mut().len(); - let d = s.from_base58().map_err(|_| PublicError::BadBase58)?; // failure here would be invalid encoding. - if d.len() != len + 3 { - // Invalid length. - return Err(PublicError::BadLength); - } - let ver = d[0].try_into().map_err(|_: ()| PublicError::UnknownVersion)?; - - if d[len+1..len+3] != ss58hash(&d[0..len+1]).as_bytes()[0..2] { - // Invalid checksum. - return Err(PublicError::InvalidChecksum); - } - res.as_mut().copy_from_slice(&d[1..len+1]); - Ok((res, ver)) - } - - fn to_ss58check_with_version(&self, version: Ss58AddressFormat) -> String { - let mut v = vec![version.into()]; - v.extend(self.as_ref()); - let r = ss58hash(&v); - v.extend(&r.as_bytes()[0..2]); - v.to_base58() - } - +impl + AsRef<[u8]> + Default + Derive> Ss58Codec for T { fn from_string(s: &str) -> Result { - let re = Regex::new(r"^(?P[\w\d]+)?(?P(//?[^/]+)*)$") + let re = Regex::new(r"^(?P[\w\d ]+)?(?P(//?[^/]+)*)$") .expect("constructed from known-good static value; qed"); let cap = re.captures(s).ok_or(PublicError::InvalidFormat)?; let re_junction = Regex::new(r"/(/?[^/]+)") .expect("constructed from known-good static value; qed"); - let addr = Self::from_ss58check( - cap.name("ss58") - .map(|r| r.as_str()) - .unwrap_or(DEV_ADDRESS) - )?; + let s = cap.name("ss58") + .map(|r| r.as_str()) + .unwrap_or(DEV_ADDRESS); + let addr = if s.starts_with("0x") { + let d = hex::decode(&s[2..]).map_err(|_| PublicError::InvalidFormat)?; + let mut r = Self::default(); + if d.len() == r.as_ref().len() { + r.as_mut().copy_from_slice(&d); + r + } else { + Err(PublicError::BadLength)? + } + } else { + Self::from_ss58check(s)? + }; if cap["path"].is_empty() { Ok(addr) } else { @@ -457,7 +463,7 @@ impl + AsRef<[u8]> + Default + Derive> Ss58Codec for T { } fn from_string_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> { - let re = Regex::new(r"^(?P[\w\d]+)?(?P(//?[^/]+)*)$") + let re = Regex::new(r"^(?P[\w\d ]+)?(?P(//?[^/]+)*)$") .expect("constructed from known-good static value; qed"); let cap = re.captures(s).ok_or(PublicError::InvalidFormat)?; let re_junction = Regex::new(r"/(/?[^/]+)") @@ -495,6 +501,103 @@ pub trait Public: AsRef<[u8]> + AsMut<[u8]> + Default + Derive + CryptoType + Pa fn as_slice(&self) -> &[u8] { self.as_ref() } } +/// An opaque 32-byte cryptographic identifier. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Default, Encode, Decode)] +pub struct AccountId32([u8; 32]); + +impl UncheckedFrom for AccountId32 { + fn unchecked_from(h: crate::hash::H256) -> Self { + AccountId32(h.into()) + } +} + +#[cfg(feature = "std")] +impl Ss58Codec for AccountId32 {} + +impl AsRef<[u8]> for AccountId32 { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + +impl AsMut<[u8]> for AccountId32 { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.0[..] + } +} + +impl AsRef<[u8; 32]> for AccountId32 { + fn as_ref(&self) -> &[u8; 32] { + &self.0 + } +} + +impl AsMut<[u8; 32]> for AccountId32 { + fn as_mut(&mut self) -> &mut [u8; 32] { + &mut self.0 + } +} + +impl From<[u8; 32]> for AccountId32 { + fn from(x: [u8; 32]) -> AccountId32 { + AccountId32(x) + } +} + +impl<'a> rstd::convert::TryFrom<&'a [u8]> for AccountId32 { + type Error = (); + fn try_from(x: &'a [u8]) -> Result { + if x.len() == 32 { + let mut r = AccountId32::default(); + r.0.copy_from_slice(x); + Ok(r) + } else { + Err(()) + } + } +} + +impl From for [u8; 32] { + fn from(x: AccountId32) -> [u8; 32] { + x.0 + } +} + +#[cfg(feature = "std")] +impl std::fmt::Display for AccountId32 { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_ss58check()) + } +} + +impl rstd::fmt::Debug for AccountId32 { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + let s = self.to_ss58check(); + write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8]) + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + Ok(()) + } +} + +#[cfg(feature = "std")] +impl serde::Serialize for AccountId32 { + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + serializer.serialize_str(&self.to_ss58check()) + } +} + +#[cfg(feature = "std")] +impl<'de> serde::Deserialize<'de> for AccountId32 { + fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { + Ss58Codec::from_ss58check(&String::deserialize(deserializer)?) + .map_err(|e| serde::de::Error::custom(format!("{:?}", e))) + } +} + #[cfg(feature = "std")] pub use self::dummy::*; @@ -544,17 +647,10 @@ mod dummy { Ok(Default::default()) } fn derive< - Iter: Iterator - >(&self, _: Iter) -> Result { Ok(Self) } + Iter: Iterator, + >(&self, _: Iter, _: Option) -> Result<(Self, Option), Self::DeriveError> { Ok((Self, None)) } fn from_seed(_: &Self::Seed) -> Self { Self } fn from_seed_slice(_: &[u8]) -> Result { Ok(Self) } - fn from_standard_components< - I: Iterator - >( - _: &str, - _: Option<&str>, - _: I - ) -> Result { Ok(Self) } fn sign(&self, _: &[u8]) -> Self::Signature { Self } fn verify>(_: &Self::Signature, _: M, _: &Self::Public) -> bool { true } fn verify_weak, M: AsRef<[u8]>>(_: &[u8], _: M, _: P) -> bool { true } @@ -604,7 +700,10 @@ pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static { fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Self, Self::Seed), SecretStringError>; /// Derive a child key from a series of given junctions. - fn derive>(&self, path: Iter) -> Result; + fn derive>(&self, + path: Iter, + seed: Option, + ) -> Result<(Self, Option), Self::DeriveError>; /// Generate new key pair from the provided `seed`. /// @@ -619,11 +718,6 @@ pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static { /// by an attacker then they can also derive your key. fn from_seed_slice(seed: &[u8]) -> Result; - /// Construct a key from a phrase, password and path. - fn from_standard_components< - I: Iterator - >(phrase: &str, password: Option<&str>, path: I) -> Result; - /// Sign a message. fn sign(&self, message: &[u8]) -> Self::Signature; @@ -636,7 +730,9 @@ pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static { /// Get the public key. fn public(&self) -> Self::Public; - /// Interprets the string `s` in order to generate a key Pair. + /// Interprets the string `s` in order to generate a key Pair. Returns both the pair and an optional seed, in the + /// case that the pair can be expressed as a direct derivation from a seed (some cases, such as Sr25519 derivations + /// with path components, cannot). /// /// This takes a helper function to do the key generation from a phrase, password and /// junction iterator. @@ -662,31 +758,40 @@ pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static { /// be equivalent to no password at all. /// /// `None` is returned if no matches are found. - fn from_string(s: &str, password_override: Option<&str>) -> Result { - let hex_seed = if s.starts_with("0x") { - &s[2..] - } else { - s - }; - - if let Ok(d) = hex::decode(hex_seed) { - if let Ok(r) = Self::from_seed_slice(&d) { - return Ok(r) - } - } - - let re = Regex::new(r"^(?P\w+( \w+)*)?(?P(//?[^/]+)*)(///(?P.*))?$") + fn from_string_with_seed(s: &str, password_override: Option<&str>) -> Result<(Self, Option), SecretStringError> { + let re = Regex::new(r"^(?P[\d\w ]+)?(?P(//?[^/]+)*)(///(?P.*))?$") .expect("constructed from known-good static value; qed"); let cap = re.captures(s).ok_or(SecretStringError::InvalidFormat)?; + let re_junction = Regex::new(r"/(/?[^/]+)") .expect("constructed from known-good static value; qed"); let path = re_junction.captures_iter(&cap["path"]) .map(|f| DeriveJunction::from(&f[1])); - Self::from_standard_components( - cap.name("phrase").map(|r| r.as_str()).unwrap_or(DEV_PHRASE), - password_override.or_else(|| cap.name("password").map(|m| m.as_str())), - path, - ) + + let phrase = cap.name("phrase").map(|r| r.as_str()).unwrap_or(DEV_PHRASE); + let password = password_override.or_else(|| cap.name("password").map(|m| m.as_str())); + + let (root, seed) = if phrase.starts_with("0x") { + hex::decode(&phrase[2..]).ok() + .and_then(|seed_vec| { + let mut seed = Self::Seed::default(); + if seed.as_ref().len() == seed_vec.len() { + seed.as_mut().copy_from_slice(&seed_vec); + Some((Self::from_seed(&seed), seed)) + } else { + None + } + }) + .ok_or(SecretStringError::InvalidSeed)? + } else { + Self::from_phrase(phrase, password) + .map_err(|_| SecretStringError::InvalidPhrase)? + }; + root.derive(path, Some(seed)).map_err(|_| SecretStringError::InvalidPath) + } + + fn from_string(s: &str, password_override: Option<&str>) -> Result { + Self::from_string_with_seed(s, password_override).map(|x| x.0) } /// Return a vec filled with raw data. @@ -846,13 +951,13 @@ mod tests { } impl Pair for TestPair { type Public = TestPublic; - type Seed = [u8; 0]; + type Seed = [u8; 8]; type Signature = [u8; 0]; type DeriveError = (); - fn generate() -> (Self, ::Seed) { (TestPair::Generated, []) } + fn generate() -> (Self, ::Seed) { (TestPair::Generated, [0u8; 8]) } fn generate_with_phrase(_password: Option<&str>) -> (Self, String, ::Seed) { - (TestPair::GeneratedWithPhrase, "".into(), []) + (TestPair::GeneratedWithPhrase, "".into(), [0u8; 8]) } fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Self, ::Seed), SecretStringError> @@ -860,14 +965,20 @@ mod tests { Ok((TestPair::GeneratedFromPhrase { phrase: phrase.to_owned(), password: password.map(Into::into) - }, [])) + }, [0u8; 8])) } - fn derive>(&self, _path: Iter) - -> Result + fn derive>(&self, path_iter: Iter, _: Option<[u8; 8]>) + -> Result<(Self, Option<[u8; 8]>), Self::DeriveError> { - Err(()) + Ok((match self.clone() { + TestPair::Standard {phrase, password, path} => + TestPair::Standard { phrase, password, path: path.into_iter().chain(path_iter).collect() }, + TestPair::GeneratedFromPhrase {phrase, password} => + TestPair::Standard { phrase, password, path: path_iter.collect() }, + x => if path_iter.count() == 0 { x } else { return Err(()) }, + }, None)) } - fn from_seed(_seed: &::Seed) -> Self { TestPair::Seed(vec![]) } + fn from_seed(_seed: &::Seed) -> Self { TestPair::Seed(_seed.as_ref().to_owned()) } fn sign(&self, _message: &[u8]) -> Self::Signature { [] } fn verify>(_: &Self::Signature, _: M, _: &Self::Public) -> bool { true } fn verify_weak, M: AsRef<[u8]>>( @@ -876,17 +987,6 @@ mod tests { _pubkey: P ) -> bool { true } fn public(&self) -> Self::Public { TestPublic } - fn from_standard_components>( - phrase: &str, - password: Option<&str>, - path: I - ) -> Result { - Ok(TestPair::Standard { - phrase: phrase.to_owned(), - password: password.map(ToOwned::to_owned), - path: path.collect() - }) - } fn from_seed_slice(seed: &[u8]) -> Result { @@ -903,10 +1003,6 @@ mod tests { TestPair::from_string("0x0123456789abcdef", None), Ok(TestPair::Seed(hex!["0123456789abcdef"][..].to_owned())) ); - assert_eq!( - TestPair::from_string("0123456789abcdef", None), - Ok(TestPair::Seed(hex!["0123456789abcdef"][..].to_owned())) - ); } #[test] diff --git a/core/primitives/src/ecdsa.rs b/core/primitives/src/ecdsa.rs new file mode 100644 index 0000000000..abff460c91 --- /dev/null +++ b/core/primitives/src/ecdsa.rs @@ -0,0 +1,608 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +// tag::description[] +//! Simple ECDSA API. +// end::description[] + +use rstd::cmp::Ordering; +use codec::{Encode, Decode}; + +#[cfg(feature = "std")] +use std::convert::{TryFrom, TryInto}; +#[cfg(feature = "std")] +use substrate_bip39::seed_from_entropy; +#[cfg(feature = "std")] +use bip39::{Mnemonic, Language, MnemonicType}; +#[cfg(feature = "std")] +use crate::{hashing::blake2_256, crypto::{Pair as TraitPair, DeriveJunction, SecretStringError, Ss58Codec}}; +#[cfg(feature = "std")] +use serde::{de, Serializer, Serialize, Deserializer, Deserialize}; +use crate::crypto::{Public as TraitPublic, UncheckedFrom, CryptoType, Derive}; +#[cfg(feature = "std")] +use secp256k1::{PublicKey, SecretKey}; + +/// A secret seed (which is bytewise essentially equivalent to a SecretKey). +/// +/// We need it as a different type because `Seed` is expected to be AsRef<[u8]>. +#[cfg(feature = "std")] +type Seed = [u8; 32]; + +/// The ECDSA 33-byte compressed public key. +#[derive(Clone, Encode, Decode)] +pub struct Public(pub [u8; 33]); + +impl PartialOrd for Public { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Public { + fn cmp(&self, other: &Self) -> Ordering { + self.0[..].cmp(&other.0[..]) + } +} + +impl PartialEq for Public { + fn eq(&self, other: &Self) -> bool { + &self.0[..] == &other.0[..] + } +} + +impl Eq for Public {} + +impl Default for Public { + fn default() -> Self { + Public([0u8; 33]) + } +} + +/// A key pair. +#[cfg(feature = "std")] +#[derive(Clone)] +pub struct Pair { + public: PublicKey, + secret: SecretKey, +} + +impl AsRef<[u8; 33]> for Public { + fn as_ref(&self) -> &[u8; 33] { + &self.0 + } +} + +impl AsRef<[u8]> for Public { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + +impl AsMut<[u8]> for Public { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.0[..] + } +} + +impl rstd::convert::TryFrom<&[u8]> for Public { + type Error = (); + + fn try_from(data: &[u8]) -> Result { + if data.len() == 33 { + let mut inner = [0u8; 33]; + inner.copy_from_slice(data); + Ok(Public(inner)) + } else { + Err(()) + } + } +} + +impl From for [u8; 33] { + fn from(x: Public) -> Self { + x.0 + } +} + +#[cfg(feature = "std")] +impl From for Public { + fn from(x: Pair) -> Self { + x.public() + } +} + +impl UncheckedFrom<[u8; 33]> for Public { + fn unchecked_from(x: [u8; 33]) -> Self { + Public(x) + } +} + +#[cfg(feature = "std")] +impl std::fmt::Display for Public { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_ss58check()) + } +} + +#[cfg(feature = "std")] +impl std::fmt::Debug for Public { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + let s = self.to_ss58check(); + write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&&self.0[..]), &s[0..8]) + } +} + +#[cfg(feature = "std")] +impl Serialize for Public { + fn serialize(&self, serializer: S) -> Result where S: Serializer { + serializer.serialize_str(&self.to_ss58check()) + } +} + +#[cfg(feature = "std")] +impl<'de> Deserialize<'de> for Public { + fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { + Public::from_ss58check(&String::deserialize(deserializer)?) + .map_err(|e| de::Error::custom(format!("{:?}", e))) + } +} + +#[cfg(feature = "std")] +impl std::hash::Hash for Public { + fn hash(&self, state: &mut H) { + self.0.hash(state); + } +} + +/// A signature (a 512-bit value). +#[derive(Encode, Decode)] +pub struct Signature([u8; 65]); + +impl rstd::convert::TryFrom<&[u8]> for Signature { + type Error = (); + + fn try_from(data: &[u8]) -> Result { + if data.len() == 65 { + let mut inner = [0u8; 65]; + inner.copy_from_slice(data); + Ok(Signature(inner)) + } else { + Err(()) + } + } +} + +impl Clone for Signature { + fn clone(&self) -> Self { + let mut r = [0u8; 65]; + r.copy_from_slice(&self.0[..]); + Signature(r) + } +} + +impl Default for Signature { + fn default() -> Self { + Signature([0u8; 65]) + } +} + +impl PartialEq for Signature { + fn eq(&self, b: &Self) -> bool { + self.0[..] == b.0[..] + } +} + +impl Eq for Signature {} + +impl From for [u8; 65] { + fn from(v: Signature) -> [u8; 65] { + v.0 + } +} + +impl AsRef<[u8; 65]> for Signature { + fn as_ref(&self) -> &[u8; 65] { + &self.0 + } +} + +impl AsRef<[u8]> for Signature { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + +impl AsMut<[u8]> for Signature { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.0[..] + } +} + +#[cfg(feature = "std")] +impl std::fmt::Debug for Signature { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0)) + } +} + +#[cfg(feature = "std")] +impl std::hash::Hash for Signature { + fn hash(&self, state: &mut H) { + std::hash::Hash::hash(&self.0[..], state); + } +} + +impl Signature { + /// A new instance from the given 65-byte `data`. + /// + /// NOTE: No checking goes on to ensure this is a real signature. Only use it if + /// you are certain that the array actually is a signature. GIGO! + pub fn from_raw(data: [u8; 65]) -> Signature { + Signature(data) + } + + /// Recover the public key from this signature and a message. + #[cfg(feature = "std")] + pub fn recover>(&self, message: M) -> Option { + let message = secp256k1::Message::parse(&blake2_256(message.as_ref())); + let sig: (_, _) = self.try_into().ok()?; + secp256k1::recover(&message, &sig.0, &sig.1).ok() + .map(|recovered| Public(recovered.serialize_compressed())) + } +} + +#[cfg(feature = "std")] +impl From<(secp256k1::Signature, secp256k1::RecoveryId)> for Signature { + fn from(x: (secp256k1::Signature, secp256k1::RecoveryId)) -> Signature { + let mut r = Self::default(); + r.0[0..64].copy_from_slice(&x.0.serialize()[..]); + r.0[64] = x.1.serialize(); + r + } +} + +#[cfg(feature = "std")] +impl<'a> TryFrom<&'a Signature> for (secp256k1::Signature, secp256k1::RecoveryId) { + type Error = (); + fn try_from(x: &'a Signature) -> Result<(secp256k1::Signature, secp256k1::RecoveryId), Self::Error> { + Ok(( + secp256k1::Signature::parse_slice(&x.0[0..64]).expect("hardcoded to 64 bytes; qed"), + secp256k1::RecoveryId::parse(x.0[64]).map_err(|_| ())?, + )) + } +} + +/// An error type for SS58 decoding. +#[cfg(feature = "std")] +#[derive(Clone, Copy, Eq, PartialEq, Debug)] +pub enum PublicError { + /// Bad alphabet. + BadBase58, + /// Bad length. + BadLength, + /// Unknown version. + UnknownVersion, + /// Invalid checksum. + InvalidChecksum, +} + +impl Public { + /// A new instance from the given 33-byte `data`. + /// + /// NOTE: No checking goes on to ensure this is a real public key. Only use it if + /// you are certain that the array actually is a pubkey. GIGO! + pub fn from_raw(data: [u8; 33]) -> Self { + Public(data) + } + + /// Return a slice filled with raw data. + pub fn as_array_ref(&self) -> &[u8; 33] { + self.as_ref() + } +} + +impl TraitPublic for Public { + /// A new instance from the given slice that should be 33 bytes long. + /// + /// NOTE: No checking goes on to ensure this is a real public key. Only use it if + /// you are certain that the array actually is a pubkey. GIGO! + fn from_slice(data: &[u8]) -> Self { + let mut r = [0u8; 33]; + r.copy_from_slice(data); + Public(r) + } +} + +impl Derive for Public {} + +/// Derive a single hard junction. +#[cfg(feature = "std")] +fn derive_hard_junction(secret_seed: &Seed, cc: &[u8; 32]) -> Seed { + ("Secp256k1HDKD", secret_seed, cc).using_encoded(|data| { + let mut res = [0u8; 32]; + res.copy_from_slice(blake2_rfc::blake2b::blake2b(32, &[], data).as_bytes()); + res + }) +} + +/// An error when deriving a key. +#[cfg(feature = "std")] +pub enum DeriveError { + /// A soft key was found in the path (and is unsupported). + SoftKeyInPath, +} + +#[cfg(feature = "std")] +impl TraitPair for Pair { + type Public = Public; + type Seed = Seed; + type Signature = Signature; + type DeriveError = DeriveError; + + /// Generate new secure (random) key pair and provide the recovery phrase. + /// + /// You can recover the same key later with `from_phrase`. + fn generate_with_phrase(password: Option<&str>) -> (Pair, String, Seed) { + let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English); + let phrase = mnemonic.phrase(); + let (pair, seed) = Self::from_phrase(phrase, password) + .expect("All phrases generated by Mnemonic are valid; qed"); + ( + pair, + phrase.to_owned(), + seed, + ) + } + + /// Generate key pair from given recovery phrase and password. + fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Pair, Seed), SecretStringError> { + let big_seed = seed_from_entropy( + Mnemonic::from_phrase(phrase, Language::English) + .map_err(|_| SecretStringError::InvalidPhrase)?.entropy(), + password.unwrap_or(""), + ).map_err(|_| SecretStringError::InvalidSeed)?; + let mut seed = Seed::default(); + seed.copy_from_slice(&big_seed[0..32]); + Self::from_seed_slice(&big_seed[0..32]).map(|x| (x, seed)) + } + + /// Make a new key pair from secret seed material. + /// + /// You should never need to use this; generate(), generate_with_phrase + fn from_seed(seed: &Seed) -> Pair { + Self::from_seed_slice(&seed[..]).expect("seed has valid length; qed") + } + + /// Make a new key pair from secret seed material. The slice must be 32 bytes long or it + /// will return `None`. + /// + /// You should never need to use this; generate(), generate_with_phrase + fn from_seed_slice(seed_slice: &[u8]) -> Result { + let secret = SecretKey::parse_slice(seed_slice) + .map_err(|_| SecretStringError::InvalidSeedLength)?; + let public = PublicKey::from_secret_key(&secret); + Ok(Pair{ secret, public }) + } + + /// Derive a child key from a series of given junctions. + fn derive>(&self, + path: Iter, + _seed: Option + ) -> Result<(Pair, Option), DeriveError> { + let mut acc = self.secret.serialize(); + for j in path { + match j { + DeriveJunction::Soft(_cc) => return Err(DeriveError::SoftKeyInPath), + DeriveJunction::Hard(cc) => acc = derive_hard_junction(&acc, &cc), + } + } + Ok((Self::from_seed(&acc), Some(acc))) + } + + /// Get the public key. + fn public(&self) -> Public { + Public(self.public.serialize_compressed()) + } + + /// Sign a message. + fn sign(&self, message: &[u8]) -> Signature { + let message = secp256k1::Message::parse(&blake2_256(message)); + secp256k1::sign(&message, &self.secret).into() + } + + /// Verify a signature on a message. Returns true if the signature is good. + fn verify>(sig: &Self::Signature, message: M, pubkey: &Self::Public) -> bool { + let message = secp256k1::Message::parse(&blake2_256(message.as_ref())); + let sig: (_, _) = match sig.try_into() { Ok(x) => x, _ => return false }; + match secp256k1::recover(&message, &sig.0, &sig.1) { + Ok(actual) => &pubkey.0[..] == &actual.serialize_compressed()[..], + _ => false, + } + } + + /// Verify a signature on a message. Returns true if the signature is good. + /// + /// This doesn't use the type system to ensure that `sig` and `pubkey` are the correct + /// size. Use it only if you're coming from byte buffers and need the speed. + fn verify_weak, M: AsRef<[u8]>>(sig: &[u8], message: M, pubkey: P) -> bool { + let message = secp256k1::Message::parse(&blake2_256(message.as_ref())); + if sig.len() != 65 { return false } + let ri = match secp256k1::RecoveryId::parse(sig[64]) { Ok(x) => x, _ => return false }; + let sig = match secp256k1::Signature::parse_slice(&sig[0..64]) { Ok(x) => x, _ => return false }; + match secp256k1::recover(&message, &sig, &ri) { + Ok(actual) => pubkey.as_ref() == &actual.serialize_compressed()[..], + _ => false, + } + } + + /// Return a vec filled with raw data. + fn to_raw_vec(&self) -> Vec { + self.seed().to_vec() + } +} + +#[cfg(feature = "std")] +impl Pair { + /// Get the seed for this key. + pub fn seed(&self) -> Seed { + self.secret.serialize() + } + + /// Exactly as `from_string` except that if no matches are found then, the the first 32 + /// characters are taken (padded with spaces as necessary) and used as the MiniSecretKey. + pub fn from_legacy_string(s: &str, password_override: Option<&str>) -> Pair { + Self::from_string(s, password_override).unwrap_or_else(|_| { + let mut padded_seed: Seed = [' ' as u8; 32]; + let len = s.len().min(32); + padded_seed[..len].copy_from_slice(&s.as_bytes()[..len]); + Self::from_seed(&padded_seed) + }) + } +} + +impl CryptoType for Public { + #[cfg(feature="std")] + type Pair = Pair; +} + +impl CryptoType for Signature { + #[cfg(feature="std")] + type Pair = Pair; +} + +#[cfg(feature = "std")] +impl CryptoType for Pair { + type Pair = Pair; +} + +#[cfg(test)] +mod test { + use super::*; + use hex_literal::hex; + use crate::crypto::DEV_PHRASE; + + #[test] + fn default_phrase_should_be_used() { + assert_eq!( + Pair::from_string("//Alice///password", None).unwrap().public(), + Pair::from_string(&format!("{}//Alice", DEV_PHRASE), Some("password")).unwrap().public(), + ); + } + + #[test] + fn seed_and_derive_should_work() { + let seed = hex!("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"); + let pair = Pair::from_seed(&seed); + assert_eq!(pair.seed(), seed); + let path = vec![DeriveJunction::Hard([0u8; 32])]; + let derived = pair.derive(path.into_iter(), None).ok().unwrap(); + assert_eq!( + derived.0.seed(), + hex!("b8eefc4937200a8382d00050e050ced2d4ab72cc2ef1b061477afb51564fdd61") + ); + } + + #[test] + fn test_vector_should_work() { + let pair = Pair::from_seed( + &hex!("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60") + ); + let public = pair.public(); + assert_eq!(public, Public::from_raw( + hex!("028db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd91") + )); + let message = b""; + let signature = hex!("3dde91174bd9359027be59a428b8146513df80a2a3c7eda2194f64de04a69ab97b753169e94db6ffd50921a2668a48b94ca11e3d32c1ff19cfe88890aa7e8f3c00"); + let signature = Signature::from_raw(signature); + assert!(&pair.sign(&message[..]) == &signature); + assert!(Pair::verify(&signature, &message[..], &public)); + } + + #[test] + fn test_vector_by_string_should_work() { + let pair = Pair::from_string( + "0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60", + None + ).unwrap(); + let public = pair.public(); + assert_eq!(public, Public::from_raw( + hex!("028db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd91") + )); + let message = b""; + let signature = hex!("3dde91174bd9359027be59a428b8146513df80a2a3c7eda2194f64de04a69ab97b753169e94db6ffd50921a2668a48b94ca11e3d32c1ff19cfe88890aa7e8f3c00"); + let signature = Signature::from_raw(signature); + assert!(&pair.sign(&message[..]) == &signature); + assert!(Pair::verify(&signature, &message[..], &public)); + } + + #[test] + fn generated_pair_should_work() { + let (pair, _) = Pair::generate(); + let public = pair.public(); + let message = b"Something important"; + let signature = pair.sign(&message[..]); + assert!(Pair::verify(&signature, &message[..], &public)); + assert!(!Pair::verify(&signature, b"Something else", &public)); + } + + #[test] + fn seeded_pair_should_work() { + let pair = Pair::from_seed(b"12345678901234567890123456789012"); + let public = pair.public(); + assert_eq!(public, Public::from_raw( + hex!("035676109c54b9a16d271abeb4954316a40a32bcce023ac14c8e26e958aa68fba9") + )); + let message = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000200d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000"); + let signature = pair.sign(&message[..]); + println!("Correct signature: {:?}", signature); + assert!(Pair::verify(&signature, &message[..], &public)); + assert!(!Pair::verify(&signature, "Other message", &public)); + } + + #[test] + fn generate_with_phrase_recovery_possible() { + let (pair1, phrase, _) = Pair::generate_with_phrase(None); + let (pair2, _) = Pair::from_phrase(&phrase, None).unwrap(); + + assert_eq!(pair1.public(), pair2.public()); + } + + #[test] + fn generate_with_password_phrase_recovery_possible() { + let (pair1, phrase, _) = Pair::generate_with_phrase(Some("password")); + let (pair2, _) = Pair::from_phrase(&phrase, Some("password")).unwrap(); + + assert_eq!(pair1.public(), pair2.public()); + } + + #[test] + fn password_does_something() { + let (pair1, phrase, _) = Pair::generate_with_phrase(Some("password")); + let (pair2, _) = Pair::from_phrase(&phrase, None).unwrap(); + + assert_ne!(pair1.public(), pair2.public()); + } + + #[test] + fn ss58check_roundtrip_works() { + let pair = Pair::from_seed(b"12345678901234567890123456789012"); + let public = pair.public(); + let s = public.to_ss58check(); + println!("Correct: {}", s); + let cmp = Public::from_ss58check(&s).unwrap(); + assert_eq!(cmp, public); + } +} diff --git a/core/primitives/src/ed25519.rs b/core/primitives/src/ed25519.rs index ff3b21e160..8c3aa9f89d 100644 --- a/core/primitives/src/ed25519.rs +++ b/core/primitives/src/ed25519.rs @@ -406,7 +406,10 @@ impl TraitPair for Pair { } /// Derive a child key from a series of given junctions. - fn derive>(&self, path: Iter) -> Result { + fn derive>(&self, + path: Iter, + _seed: Option, + ) -> Result<(Pair, Option), DeriveError> { let mut acc = self.0.secret.to_bytes(); for j in path { match j { @@ -414,18 +417,7 @@ impl TraitPair for Pair { DeriveJunction::Hard(cc) => acc = derive_hard_junction(&acc, &cc), } } - Ok(Self::from_seed(&acc)) - } - - /// Generate a key from the phrase, password and derivation path. - fn from_standard_components>( - phrase: &str, - password: Option<&str>, - path: I - ) -> Result { - Self::from_phrase(phrase, password)?.0 - .derive(path) - .map_err(|_| SecretStringError::InvalidPath) + Ok((Self::from_seed(&acc), Some(acc))) } /// Get the public key. @@ -528,7 +520,7 @@ mod test { let pair = Pair::from_seed(&seed); assert_eq!(pair.seed(), &seed); let path = vec![DeriveJunction::Hard([0u8; 32])]; - let derived = pair.derive(path.into_iter()).ok().unwrap(); + let derived = pair.derive(path.into_iter(), None).ok().unwrap().0; assert_eq!( derived.seed(), &hex!("ede3354e133f9c8e337ddd6ee5415ed4b4ffe5fc7d21e933f4930a3730e5b21c") diff --git a/core/primitives/src/hexdisplay.rs b/core/primitives/src/hexdisplay.rs index 6765ce517e..2c8533e25b 100644 --- a/core/primitives/src/hexdisplay.rs +++ b/core/primitives/src/hexdisplay.rs @@ -80,7 +80,7 @@ macro_rules! impl_non_endians { impl_non_endians!([u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 8], [u8; 10], [u8; 12], [u8; 14], [u8; 16], [u8; 20], [u8; 24], [u8; 28], [u8; 32], [u8; 40], - [u8; 48], [u8; 56], [u8; 64], [u8; 80], [u8; 96], [u8; 112], [u8; 128]); + [u8; 48], [u8; 56], [u8; 64], [u8; 65], [u8; 80], [u8; 96], [u8; 112], [u8; 128]); /// Format into ASCII + # + hex, suitable for storage key preimages. pub fn ascii_format(asciish: &[u8]) -> String { diff --git a/core/primitives/src/lib.rs b/core/primitives/src/lib.rs index 48d3d998fa..d1b42766a0 100644 --- a/core/primitives/src/lib.rs +++ b/core/primitives/src/lib.rs @@ -59,6 +59,7 @@ pub mod u32_trait; pub mod ed25519; pub mod sr25519; +pub mod ecdsa; pub mod hash; mod hasher; pub mod offchain; diff --git a/core/primitives/src/sr25519.rs b/core/primitives/src/sr25519.rs index f2160b88b7..bb319b8221 100644 --- a/core/primitives/src/sr25519.rs +++ b/core/primitives/src/sr25519.rs @@ -388,8 +388,8 @@ impl AsRef for Pair { /// Derive a single hard junction. #[cfg(feature = "std")] -fn derive_hard_junction(secret: &SecretKey, cc: &[u8; CHAIN_CODE_LENGTH]) -> SecretKey { - secret.hard_derive_mini_secret_key(Some(ChainCode(cc.clone())), b"").0.expand(ExpansionMode::Ed25519) +fn derive_hard_junction(secret: &SecretKey, cc: &[u8; CHAIN_CODE_LENGTH]) -> MiniSecretKey { + secret.hard_derive_mini_secret_key(Some(ChainCode(cc.clone())), b"").0 } /// The raw secret seed, which can be used to recreate the `Pair`. @@ -444,17 +444,6 @@ impl TraitPair for Pair { } } - /// Generate a key from the phrase, password and derivation path. - fn from_standard_components>( - phrase: &str, - password: Option<&str>, - path: I - ) -> Result { - Self::from_phrase(phrase, password)?.0 - .derive(path) - .map_err(|_| SecretStringError::InvalidPath) - } - fn generate_with_phrase(password: Option<&str>) -> (Pair, String, Seed) { let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English); let phrase = mnemonic.phrase(); @@ -473,13 +462,27 @@ impl TraitPair for Pair { .map(|m| Self::from_entropy(m.entropy(), password)) } - fn derive>(&self, path: Iter) -> Result { + fn derive>(&self, + path: Iter, + seed: Option, + ) -> Result<(Pair, Option), Self::DeriveError> { + let seed = if let Some(s) = seed { + if let Ok(msk) = MiniSecretKey::from_bytes(&s) { + if msk.expand(ExpansionMode::Ed25519) == self.0.secret { + Some(msk) + } else { None } + } else { None } + } else { None }; let init = self.0.secret.clone(); - let result = path.fold(init, |acc, j| match j { - DeriveJunction::Soft(cc) => acc.derived_key_simple(ChainCode(cc), &[]).0, - DeriveJunction::Hard(cc) => derive_hard_junction(&acc, &cc), + let (result, seed) = path.fold((init, seed), |(acc, acc_seed), j| match (j, acc_seed) { + (DeriveJunction::Soft(cc), _) => + (acc.derived_key_simple(ChainCode(cc), &[]).0, None), + (DeriveJunction::Hard(cc), maybe_seed) => { + let seed = derive_hard_junction(&acc, &cc); + (seed.expand(ExpansionMode::Ed25519), maybe_seed.map(|_| seed)) + } }); - Ok(Self(result.into())) + Ok((Self(result.into()), seed.map(|s| MiniSecretKey::to_bytes(&s)))) } fn sign(&self, message: &[u8]) -> Signature { @@ -621,9 +624,9 @@ mod test { let pair = Pair::from_seed(&hex!( "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" )); - let derive_1 = pair.derive(Some(DeriveJunction::soft(1)).into_iter()).unwrap(); - let derive_1b = pair.derive(Some(DeriveJunction::soft(1)).into_iter()).unwrap(); - let derive_2 = pair.derive(Some(DeriveJunction::soft(2)).into_iter()).unwrap(); + let derive_1 = pair.derive(Some(DeriveJunction::soft(1)).into_iter(), None).unwrap().0; + let derive_1b = pair.derive(Some(DeriveJunction::soft(1)).into_iter(), None).unwrap().0; + let derive_2 = pair.derive(Some(DeriveJunction::soft(2)).into_iter(), None).unwrap().0; assert_eq!(derive_1.public(), derive_1b.public()); assert_ne!(derive_1.public(), derive_2.public()); } @@ -633,9 +636,9 @@ mod test { let pair = Pair::from_seed(&hex!( "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" )); - let derive_1 = pair.derive(Some(DeriveJunction::hard(1)).into_iter()).unwrap(); - let derive_1b = pair.derive(Some(DeriveJunction::hard(1)).into_iter()).unwrap(); - let derive_2 = pair.derive(Some(DeriveJunction::hard(2)).into_iter()).unwrap(); + let derive_1 = pair.derive(Some(DeriveJunction::hard(1)).into_iter(), None).unwrap().0; + let derive_1b = pair.derive(Some(DeriveJunction::hard(1)).into_iter(), None).unwrap().0; + let derive_2 = pair.derive(Some(DeriveJunction::hard(2)).into_iter(), None).unwrap().0; assert_eq!(derive_1.public(), derive_1b.public()); assert_ne!(derive_1.public(), derive_2.public()); } @@ -646,7 +649,7 @@ mod test { "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" )); let path = Some(DeriveJunction::soft(1)); - let pair_1 = pair.derive(path.clone().into_iter()).unwrap(); + let pair_1 = pair.derive(path.clone().into_iter(), None).unwrap().0; let public_1 = pair.public().derive(path.into_iter()).unwrap(); assert_eq!(pair_1.public(), public_1); } diff --git a/core/sr-io/src/lib.rs b/core/sr-io/src/lib.rs index b0274286dc..fe5e50b3ed 100644 --- a/core/sr-io/src/lib.rs +++ b/core/sr-io/src/lib.rs @@ -220,15 +220,20 @@ export_api! { /// Verify and recover a SECP256k1 ECDSA signature. /// - `sig` is passed in RSV format. V should be either 0/1 or 27/28. - /// - returns `Err` if the signature is bad, otherwise the 64-byte pubkey (doesn't include the 0x04 prefix). + /// - returns `Err` if the signature is bad, otherwise the 64-byte raw pubkey (doesn't include the 0x04 prefix). fn secp256k1_ecdsa_recover(sig: &[u8; 65], msg: &[u8; 32]) -> Result<[u8; 64], EcdsaVerifyError>; + + /// Verify and recover a SECP256k1 ECDSA signature. + /// - `sig` is passed in RSV format. V should be either 0/1 or 27/28. + /// - returns `Err` if the signature is bad, otherwise the 33-byte compressed pubkey. + fn secp256k1_ecdsa_recover_compressed(sig: &[u8; 65], msg: &[u8; 32]) -> Result<[u8; 33], EcdsaVerifyError>; } } export_api! { pub(crate) trait HashingApi { /// Conduct a 256-bit Keccak hash. - fn keccak_256(data: &[u8]) -> [u8; 32] ; + fn keccak_256(data: &[u8]) -> [u8; 32]; /// Conduct a 128-bit Blake2 hash. fn blake2_128(data: &[u8]) -> [u8; 16]; diff --git a/core/sr-io/with_std.rs b/core/sr-io/with_std.rs index de40115cbe..fdd32124c1 100644 --- a/core/sr-io/with_std.rs +++ b/core/sr-io/with_std.rs @@ -300,6 +300,16 @@ impl CryptoApi for () { res.copy_from_slice(&pubkey.serialize()[1..65]); Ok(res) } + + fn secp256k1_ecdsa_recover_compressed(sig: &[u8; 65], msg: &[u8; 32]) -> Result<[u8; 33], EcdsaVerifyError> { + let rs = secp256k1::Signature::parse_slice(&sig[0..64]) + .map_err(|_| EcdsaVerifyError::BadRS)?; + let v = secp256k1::RecoveryId::parse(if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as u8) + .map_err(|_| EcdsaVerifyError::BadV)?; + let pubkey = secp256k1::recover(&secp256k1::Message::parse(msg), &rs, &v) + .map_err(|_| EcdsaVerifyError::BadSignature)?; + Ok(pubkey.serialize_compressed()) + } } impl HashingApi for () { diff --git a/core/sr-io/without_std.rs b/core/sr-io/without_std.rs index 789098185e..c3f7d62031 100644 --- a/core/sr-io/without_std.rs +++ b/core/sr-io/without_std.rs @@ -394,12 +394,23 @@ pub mod ext { ) -> u32; /// Note: ext_secp256k1_ecdsa_recover returns 0 if the signature is correct, nonzero otherwise. + /// + /// pubkey_data must point to 64 bytes. fn ext_secp256k1_ecdsa_recover( msg_data: *const u8, sig_data: *const u8, pubkey_data: *mut u8, ) -> u32; + /// Note: ext_secp256k1_ecdsa_recover_compressed returns 0 if the signature is correct, nonzero otherwise. + /// + /// pubkey_data must point to 33 bytes. + fn ext_secp256k1_ecdsa_recover_compressed( + msg_data: *const u8, + sig_data: *const u8, + pubkey_data: *mut u8, + ) -> u32; + //================================ // Offchain-worker Context //================================ @@ -971,6 +982,19 @@ impl CryptoApi for () { _ => unreachable!("`ext_secp256k1_ecdsa_recover` only returns 0, 1, 2 or 3; qed"), } } + + fn secp256k1_ecdsa_recover_compressed(sig: &[u8; 65], msg: &[u8; 32]) -> Result<[u8; 33], EcdsaVerifyError> { + let mut pubkey = [0u8; 33]; + match unsafe { + ext_secp256k1_ecdsa_recover_compressed.get()(msg.as_ptr(), sig.as_ptr(), pubkey.as_mut_ptr()) + } { + 0 => Ok(pubkey), + 1 => Err(EcdsaVerifyError::BadRS), + 2 => Err(EcdsaVerifyError::BadV), + 3 => Err(EcdsaVerifyError::BadSignature), + _ => unreachable!("`ext_secp256k1_ecdsa_recover_compressed` only returns 0, 1, 2 or 3; qed"), + } + } } impl OffchainApi for () { diff --git a/core/sr-primitives/src/generic/unchecked_extrinsic.rs b/core/sr-primitives/src/generic/unchecked_extrinsic.rs index d50314f33b..4af8d9a95b 100644 --- a/core/sr-primitives/src/generic/unchecked_extrinsic.rs +++ b/core/sr-primitives/src/generic/unchecked_extrinsic.rs @@ -21,7 +21,7 @@ use rstd::fmt; use runtime_io::blake2_256; use codec::{Decode, Encode, EncodeLike, Input, Error}; use crate::{ - traits::{self, Member, MaybeDisplay, SignedExtension, Checkable, Extrinsic}, + traits::{self, Member, MaybeDisplay, SignedExtension, Checkable, Extrinsic, IdentifyAccount}, generic::CheckedExtrinsic, transaction_validity::{TransactionValidityError, InvalidTransaction}, }; @@ -98,7 +98,8 @@ for where Address: Member + MaybeDisplay, Call: Encode + Member, - Signature: Member + traits::Verify, + Signature: Member + traits::Verify, + ::Signer: IdentifyAccount, Extra: SignedExtension, AccountId: Member + MaybeDisplay, Lookup: traits::Lookup, @@ -284,17 +285,26 @@ mod tests { use super::*; use runtime_io::blake2_256; use crate::codec::{Encode, Decode}; - use crate::traits::{SignedExtension, IdentityLookup}; + use crate::traits::{SignedExtension, IdentifyAccount, IdentityLookup}; use serde::{Serialize, Deserialize}; type TestContext = IdentityLookup; + #[derive(Eq, PartialEq, Clone, Copy, Debug, Serialize, Deserialize, Encode, Decode)] + pub struct TestSigner(pub u64); + impl From for TestSigner { fn from(x: u64) -> Self { Self(x) } } + impl From for u64 { fn from(x: TestSigner) -> Self { x.0 } } + impl IdentifyAccount for TestSigner { + type AccountId = u64; + fn into_account(self) -> u64 { self.into() } + } + #[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize, Encode, Decode)] struct TestSig(u64, Vec); impl traits::Verify for TestSig { - type Signer = u64; - fn verify>(&self, mut msg: L, signer: &Self::Signer) -> bool { - *signer == self.0 && msg.get() == &self.1[..] + type Signer = TestSigner; + fn verify>(&self, mut msg: L, signer: &u64) -> bool { + signer == &self.0 && msg.get() == &self.1[..] } } diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index ea295fbea6..84f7bbcff6 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -42,7 +42,7 @@ pub use runtime_io::{StorageOverlay, ChildrenStorageOverlay}; use rstd::prelude::*; use rstd::convert::TryFrom; -use primitives::{crypto, ed25519, sr25519, hash::{H256, H512}}; +use primitives::{crypto, ed25519, sr25519, ecdsa, hash::{H256, H512}}; use codec::{Encode, Decode}; #[cfg(feature = "std")] @@ -59,7 +59,7 @@ pub mod weights; pub use generic::{DigestItem, Digest}; /// Re-export this since it's part of the API of this crate. -pub use primitives::{TypeId, crypto::{key_types, KeyTypeId, CryptoType}}; +pub use primitives::{TypeId, crypto::{key_types, KeyTypeId, CryptoType, AccountId32}}; pub use app_crypto::RuntimeAppPublic; /// Re-export `RuntimeDebug`, to avoid dependency clutter. @@ -117,6 +117,7 @@ macro_rules! create_runtime_str { #[cfg(feature = "std")] pub use serde::{Serialize, Deserialize, de::DeserializeOwned}; +use crate::traits::IdentifyAccount; /// Complex storage builder stuff. #[cfg(feature = "std")] @@ -175,6 +176,8 @@ pub enum MultiSignature { Ed25519(ed25519::Signature), /// An Sr25519 signature. Sr25519(sr25519::Signature), + /// An ECDSA/SECP256k1 signature. + Ecdsa(ecdsa::Signature), } impl From for MultiSignature { @@ -189,6 +192,12 @@ impl From for MultiSignature { } } +impl From for MultiSignature { + fn from(x: ecdsa::Signature) -> Self { + MultiSignature::Ecdsa(x) + } +} + impl Default for MultiSignature { fn default() -> Self { MultiSignature::Ed25519(Default::default()) @@ -203,6 +212,8 @@ pub enum MultiSigner { Ed25519(ed25519::Public), /// An Sr25519 identity. Sr25519(sr25519::Public), + /// An SECP256k1/ECDSA identity (actually, the Blake2 hash of the pub key). + Ecdsa(ecdsa::Public), } impl Default for MultiSigner { @@ -224,6 +235,18 @@ impl AsRef<[u8]> for MultiSigner { match *self { MultiSigner::Ed25519(ref who) => who.as_ref(), MultiSigner::Sr25519(ref who) => who.as_ref(), + MultiSigner::Ecdsa(ref who) => who.as_ref(), + } + } +} + +impl traits::IdentifyAccount for MultiSigner { + type AccountId = AccountId32; + fn into_account(self) -> AccountId32 { + match self { + MultiSigner::Ed25519(who) => <[u8; 32]>::from(who).into(), + MultiSigner::Sr25519(who) => <[u8; 32]>::from(who).into(), + MultiSigner::Ecdsa(who) => runtime_io::blake2_256(who.as_ref()).into(), } } } @@ -240,23 +263,37 @@ impl From for MultiSigner { } } - #[cfg(feature = "std")] +impl From for MultiSigner { + fn from(x: ecdsa::Public) -> Self { + MultiSigner::Ecdsa(x) + } +} + +#[cfg(feature = "std")] impl std::fmt::Display for MultiSigner { fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { match *self { MultiSigner::Ed25519(ref who) => write!(fmt, "ed25519: {}", who), MultiSigner::Sr25519(ref who) => write!(fmt, "sr25519: {}", who), + MultiSigner::Ecdsa(ref who) => write!(fmt, "ecdsa: {}", who), } } } impl Verify for MultiSignature { type Signer = MultiSigner; - fn verify>(&self, msg: L, signer: &Self::Signer) -> bool { + fn verify>(&self, mut msg: L, signer: &AccountId32) -> bool { + use primitives::crypto::Public; match (self, signer) { - (MultiSignature::Ed25519(ref sig), &MultiSigner::Ed25519(ref who)) => sig.verify(msg, who), - (MultiSignature::Sr25519(ref sig), &MultiSigner::Sr25519(ref who)) => sig.verify(msg, who), - _ => false, + (MultiSignature::Ed25519(ref sig), who) => sig.verify(msg, &ed25519::Public::from_slice(who.as_ref())), + (MultiSignature::Sr25519(ref sig), who) => sig.verify(msg, &sr25519::Public::from_slice(who.as_ref())), + (MultiSignature::Ecdsa(ref sig), who) => { + let m = runtime_io::blake2_256(msg.get()); + match runtime_io::secp256k1_ecdsa_recover_compressed(sig.as_ref(), &m) { + Ok(pubkey) => &runtime_io::blake2_256(pubkey.as_ref()) == >::as_ref(who), + _ => false, + } + } } } } @@ -269,12 +306,13 @@ pub struct AnySignature(H512); impl Verify for AnySignature { type Signer = sr25519::Public; fn verify>(&self, mut msg: L, signer: &sr25519::Public) -> bool { + use primitives::crypto::Public; + let msg = msg.get(); sr25519::Signature::try_from(self.0.as_fixed_bytes().as_ref()) - .map(|s| runtime_io::sr25519_verify(&s, msg.get(), &signer)) + .map(|s| s.verify(msg, signer)) .unwrap_or(false) || ed25519::Signature::try_from(self.0.as_fixed_bytes().as_ref()) - .and_then(|s| ed25519::Public::try_from(signer.0.as_ref()).map(|p| (s, p))) - .map(|(s, p)| runtime_io::ed25519_verify(&s, msg.get(), &p)) + .map(|s| s.verify(msg, &ed25519::Public::from_slice(signer.as_ref()))) .unwrap_or(false) } } @@ -398,7 +436,7 @@ impl From<&'static str> for DispatchError { /// Verify a signature on an encoded value in a lazy manner. This can be /// an optimization if the signature scheme has an "unsigned" escape hash. -pub fn verify_encoded_lazy(sig: &V, item: &T, signer: &V::Signer) -> bool { +pub fn verify_encoded_lazy(sig: &V, item: &T, signer: &::AccountId) -> bool { // The `Lazy` trait expresses something like `X: FnMut &'a T>`. // unfortunately this is a lifetime relationship that can't // be expressed without generic associated types, better unification of HRTBs in type position, diff --git a/core/sr-primitives/src/traits.rs b/core/sr-primitives/src/traits.rs index 0497f094d2..4586a84511 100644 --- a/core/sr-primitives/src/traits.rs +++ b/core/sr-primitives/src/traits.rs @@ -50,46 +50,84 @@ impl<'a> Lazy<[u8]> for &'a [u8] { fn get(&mut self) -> &[u8] { &**self } } +/// Some type that is able to be collapsed into an account ID. It is not possible to recreate the original value from +/// the account ID. +pub trait IdentifyAccount { + /// The account ID that this can be transformed into. + type AccountId; + /// Transform into an account. + fn into_account(self) -> Self::AccountId; +} + +impl IdentifyAccount for primitives::ed25519::Public { + type AccountId = Self; + fn into_account(self) -> Self { self } +} + +impl IdentifyAccount for primitives::sr25519::Public { + type AccountId = Self; + fn into_account(self) -> Self { self } +} + +impl IdentifyAccount for primitives::ecdsa::Public { + type AccountId = Self; + fn into_account(self) -> Self { self } +} + /// Means of signature verification. pub trait Verify { /// Type of the signer. - type Signer; + type Signer: IdentifyAccount; /// Verify a signature. Return `true` if signature is valid for the value. - fn verify>(&self, msg: L, signer: &Self::Signer) -> bool; + fn verify>(&self, msg: L, signer: &::AccountId) -> bool; } impl Verify for primitives::ed25519::Signature { type Signer = primitives::ed25519::Public; - fn verify>(&self, mut msg: L, signer: &Self::Signer) -> bool { + fn verify>(&self, mut msg: L, signer: &primitives::ed25519::Public) -> bool { runtime_io::ed25519_verify(self, msg.get(), signer) } } impl Verify for primitives::sr25519::Signature { type Signer = primitives::sr25519::Public; - fn verify>(&self, mut msg: L, signer: &Self::Signer) -> bool { + fn verify>(&self, mut msg: L, signer: &primitives::sr25519::Public) -> bool { runtime_io::sr25519_verify(self, msg.get(), signer) } } +impl Verify for primitives::ecdsa::Signature { + type Signer = primitives::ecdsa::Public; + fn verify>(&self, mut msg: L, signer: &primitives::ecdsa::Public) -> bool { + match runtime_io::secp256k1_ecdsa_recover_compressed(self.as_ref(), &runtime_io::blake2_256(msg.get())) { + Ok(pubkey) => >::as_ref(signer) == &pubkey[..], + _ => false, + } + } +} + /// Means of signature verification of an application key. pub trait AppVerify { /// Type of the signer. - type Signer; + type AccountId; /// Verify a signature. Return `true` if signature is valid for the value. - fn verify>(&self, msg: L, signer: &Self::Signer) -> bool; + fn verify>(&self, msg: L, signer: &Self::AccountId) -> bool; } impl< S: Verify::Public as app_crypto::AppPublic>::Generic> + From, T: app_crypto::Wraps + app_crypto::AppKey + app_crypto::AppSignature + AsRef + AsMut + From, -> AppVerify for T { - type Signer = ::Public; - fn verify>(&self, msg: L, signer: &Self::Signer) -> bool { +> AppVerify for T where + ::Signer: IdentifyAccount::Signer>, + <::Public as app_crypto::AppPublic>::Generic: + IdentifyAccount::Public as app_crypto::AppPublic>::Generic>, +{ + type AccountId = ::Public; + fn verify>(&self, msg: L, signer: &::Public) -> bool { use app_crypto::IsWrappedBy; let inner: &S = self.as_ref(); - let inner_pubkey = ::Generic::from_ref(&signer); + let inner_pubkey = <::Public as app_crypto::AppPublic>::Generic::from_ref(&signer); Verify::verify(inner, msg, inner_pubkey) } } @@ -1179,6 +1217,21 @@ mod tests { use super::AccountIdConversion; use crate::codec::{Encode, Decode, Input}; + mod t { + use primitives::crypto::KeyTypeId; + use app_crypto::{app_crypto, sr25519}; + app_crypto!(sr25519, KeyTypeId(*b"test")); + } + + #[test] + fn app_verify_works() { + use t::*; + use super::AppVerify; + + let s = Signature::default(); + let _ = s.verify(&[0u8; 100][..], &Public::default()); + } + #[derive(Encode, Decode, Default, PartialEq, Debug)] struct U32Value(u32); impl super::TypeId for U32Value { diff --git a/node/cli/src/chain_spec.rs b/node/cli/src/chain_spec.rs index bc9f1e615f..07f6946baf 100644 --- a/node/cli/src/chain_spec.rs +++ b/node/cli/src/chain_spec.rs @@ -17,7 +17,7 @@ //! Substrate chain configurations. use chain_spec::ChainSpecExtension; -use primitives::{Pair, Public, crypto::UncheckedInto}; +use primitives::{Pair, Public, crypto::UncheckedInto, sr25519}; use serde::{Serialize, Deserialize}; use node_runtime::{ AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig, DemocracyConfig, @@ -32,10 +32,13 @@ use substrate_telemetry::TelemetryEndpoints; use grandpa_primitives::{AuthorityId as GrandpaId}; use babe_primitives::{AuthorityId as BabeId}; use im_online::sr25519::{AuthorityId as ImOnlineId}; -use sr_primitives::Perbill; +use sr_primitives::{traits::Verify, Perbill}; -pub use node_primitives::{AccountId, Balance}; +pub use node_primitives::{AccountId, Balance, Signature}; pub use node_runtime::GenesisConfig; +use sr_primitives::traits::IdentifyAccount; + +type AccountPublic = ::Signer; const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; @@ -72,9 +75,9 @@ fn staging_testnet_config_genesis() -> GenesisConfig { let initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId, ImOnlineId)> = vec![( // 5Fbsd6WXDGiLTxunqeK5BATNiocfCqu9bS1yArVjCgeBLkVy - hex!["9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12"].unchecked_into(), + hex!["9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12"].into(), // 5EnCiV7wSHeNhjW3FSUwiJNkcc2SBkPLn5Nj93FmbLtBjQUq - hex!["781ead1e2fa9ccb74b44c19d29cb2a7a4b5be3972927ae98cd3877523976a276"].unchecked_into(), + hex!["781ead1e2fa9ccb74b44c19d29cb2a7a4b5be3972927ae98cd3877523976a276"].into(), // 5Fb9ayurnxnaXj56CjmyQLBiadfRCqUbL2VWNbbe1nZU6wiC hex!["9becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe9699332"].unchecked_into(), // 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8 @@ -83,9 +86,9 @@ fn staging_testnet_config_genesis() -> GenesisConfig { hex!["6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"].unchecked_into(), ),( // 5ERawXCzCWkjVq3xz1W5KGNtVx2VdefvZ62Bw1FEuZW4Vny2 - hex!["68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78"].unchecked_into(), + hex!["68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78"].into(), // 5Gc4vr42hH1uDZc93Nayk5G7i687bAQdHHc9unLuyeawHipF - hex!["c8dc79e36b29395413399edaec3e20fcca7205fb19776ed8ddb25d6f427ec40e"].unchecked_into(), + hex!["c8dc79e36b29395413399edaec3e20fcca7205fb19776ed8ddb25d6f427ec40e"].into(), // 5EockCXN6YkiNCDjpqqnbcqd4ad35nU4RmA1ikM4YeRN4WcE hex!["7932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f"].unchecked_into(), // 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ @@ -94,9 +97,9 @@ fn staging_testnet_config_genesis() -> GenesisConfig { hex!["482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e"].unchecked_into(), ),( // 5DyVtKWPidondEu8iHZgi6Ffv9yrJJ1NDNLom3X9cTDi98qp - hex!["547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65"].unchecked_into(), + hex!["547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65"].into(), // 5FeD54vGVNpFX3PndHPXJ2MDakc462vBCD5mgtWRnWYCpZU9 - hex!["9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526"].unchecked_into(), + hex!["9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526"].into(), // 5E1jLYfLdUQKrFrtqoKgFrRvxM3oQPMbf6DfcsrugZZ5Bn8d hex!["5633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440"].unchecked_into(), // 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH @@ -105,9 +108,9 @@ fn staging_testnet_config_genesis() -> GenesisConfig { hex!["482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a"].unchecked_into(), ),( // 5HYZnKWe5FVZQ33ZRJK1rG3WaLMztxWrrNDb1JRwaHHVWyP9 - hex!["f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663"].unchecked_into(), + hex!["f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663"].into(), // 5EPQdAQ39WQNLCRjWsCk5jErsCitHiY5ZmjfWzzbXDoAoYbn - hex!["66bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f"].unchecked_into(), + hex!["66bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f"].into(), // 5DMa31Hd5u1dwoRKgC4uvqyrdK45RHv3CpwvpUC1EzuwDit4 hex!["3919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef"].unchecked_into(), // 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x @@ -120,7 +123,7 @@ fn staging_testnet_config_genesis() -> GenesisConfig { let root_key: AccountId = hex![ // 5Ff3iXP75ruzroPWRP2FYBHWnmGGBSb63857BgnzCoXNxfPo "9ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809" - ].unchecked_into(); + ].into(); let endowed_accounts: Vec = vec![root_key.clone()]; @@ -154,12 +157,18 @@ pub fn get_from_seed(seed: &str) -> ::Pu .public() } +/// Helper function to generate an account ID from seed +pub fn get_account_id_from_seed(seed: &str) -> AccountId where + AccountPublic: From<::Public> +{ + AccountPublic::from(get_from_seed::(seed)).into_account() +} /// Helper function to generate stash, controller and session key from seed pub fn get_authority_keys_from_seed(seed: &str) -> (AccountId, AccountId, GrandpaId, BabeId, ImOnlineId) { ( - get_from_seed::(&format!("{}//stash", seed)), - get_from_seed::(seed), + get_account_id_from_seed::(&format!("{}//stash", seed)), + get_account_id_from_seed::(seed), get_from_seed::(seed), get_from_seed::(seed), get_from_seed::(seed), @@ -175,18 +184,18 @@ pub fn testnet_genesis( ) -> GenesisConfig { let endowed_accounts: Vec = endowed_accounts.unwrap_or_else(|| { vec![ - get_from_seed::("Alice"), - get_from_seed::("Bob"), - get_from_seed::("Charlie"), - get_from_seed::("Dave"), - get_from_seed::("Eve"), - get_from_seed::("Ferdie"), - get_from_seed::("Alice//stash"), - get_from_seed::("Bob//stash"), - get_from_seed::("Charlie//stash"), - get_from_seed::("Dave//stash"), - get_from_seed::("Eve//stash"), - get_from_seed::("Ferdie//stash"), + get_account_id_from_seed::("Alice"), + get_account_id_from_seed::("Bob"), + get_account_id_from_seed::("Charlie"), + get_account_id_from_seed::("Dave"), + get_account_id_from_seed::("Eve"), + get_account_id_from_seed::("Ferdie"), + get_account_id_from_seed::("Alice//stash"), + get_account_id_from_seed::("Bob//stash"), + get_account_id_from_seed::("Charlie//stash"), + get_account_id_from_seed::("Dave//stash"), + get_account_id_from_seed::("Eve//stash"), + get_account_id_from_seed::("Ferdie//stash"), ] }); @@ -272,7 +281,7 @@ fn development_config_genesis() -> GenesisConfig { vec![ get_authority_keys_from_seed("Alice"), ], - get_from_seed::("Alice"), + get_account_id_from_seed::("Alice"), None, true, ) @@ -298,7 +307,7 @@ fn local_testnet_genesis() -> GenesisConfig { get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Bob"), ], - get_from_seed::("Alice"), + get_account_id_from_seed::("Alice"), None, false, ) @@ -330,7 +339,7 @@ pub(crate) mod tests { vec![ get_authority_keys_from_seed("Alice"), ], - get_from_seed::("Alice"), + get_account_id_from_seed::("Alice"), None, false, ) diff --git a/node/cli/src/factory_impl.rs b/node/cli/src/factory_impl.rs index 84c24f2af0..48fb7b237f 100644 --- a/node/cli/src/factory_impl.rs +++ b/node/cli/src/factory_impl.rs @@ -25,16 +25,21 @@ use codec::{Encode, Decode}; use keyring::sr25519::Keyring; use node_runtime::{ Call, CheckedExtrinsic, UncheckedExtrinsic, SignedExtra, BalancesCall, ExistentialDeposit, - MinimumPeriod, + MinimumPeriod }; +use node_primitives::Signature; use primitives::{sr25519, crypto::Pair}; -use sr_primitives::{generic::Era, traits::{Block as BlockT, Header as HeaderT, SignedExtension}}; +use sr_primitives::{ + generic::Era, traits::{Block as BlockT, Header as HeaderT, SignedExtension, Verify, IdentifyAccount} +}; use transaction_factory::RuntimeAdapter; use transaction_factory::modes::Mode; use inherents::InherentData; use timestamp; use finality_tracker; +type AccountPublic = ::Signer; + pub struct FactoryState { block_no: N, @@ -167,7 +172,7 @@ impl RuntimeAdapter for FactoryState { } fn master_account_id() -> Self::AccountId { - Keyring::Alice.pair().public() + Keyring::Alice.to_account_id() } fn master_account_secret() -> Self::Secret { @@ -177,7 +182,7 @@ impl RuntimeAdapter for FactoryState { /// Generates a random `AccountId` from `seed`. fn gen_random_account_id(seed: &Self::Number) -> Self::AccountId { let pair: sr25519::Pair = sr25519::Pair::from_seed(&gen_seed_bytes(*seed)); - pair.public().into() + AccountPublic::from(pair.public()).into_account() } /// Generates a random `Secret` from `seed`. diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index 0f4a098f3d..03d31c4392 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -330,17 +330,15 @@ mod tests { use consensus_common::{ Environment, Proposer, BlockImportParams, BlockOrigin, ForkChoiceStrategy, BlockImport, }; - use node_primitives::{Block, DigestItem}; - use node_runtime::{BalancesCall, Call, UncheckedExtrinsic}; + use node_primitives::{Block, DigestItem, Signature}; + use node_runtime::{BalancesCall, Call, UncheckedExtrinsic, Address}; use node_runtime::constants::{currency::CENTS, time::SLOT_DURATION}; use codec::{Encode, Decode}; - use primitives::{ - crypto::Pair as CryptoPair, - sr25519::Public as AddressPublic, H256, - }; + use primitives::{crypto::Pair as CryptoPair, H256}; use sr_primitives::{ generic::{BlockId, Era, Digest, SignedPayload}, traits::Block as BlockT, + traits::Verify, OpaqueExtrinsic, }; use timestamp; @@ -348,6 +346,9 @@ mod tests { use keyring::AccountKeyring; use substrate_service::{AbstractService, Roles}; use crate::service::new_full; + use sr_primitives::traits::IdentifyAccount; + + type AccountPublic = ::Signer; #[cfg(feature = "rhd")] fn test_sync() { @@ -518,8 +519,8 @@ mod tests { }, |service, _| { let amount = 5 * CENTS; - let to = AddressPublic::from_raw(bob.public().0); - let from = AddressPublic::from_raw(charlie.public().0); + let to: Address = AccountPublic::from(bob.public()).into_account().into(); + let from: Address = AccountPublic::from(charlie.public()).into_account().into(); let genesis_hash = service.client().block_hash(0).unwrap().unwrap(); let best_block_id = BlockId::number(service.client().info().chain.best_number); let version = service.client().runtime_version_at(&best_block_id).unwrap().spec_version; diff --git a/node/primitives/src/lib.rs b/node/primitives/src/lib.rs index 6b128db4f3..b6a5ec0565 100644 --- a/node/primitives/src/lib.rs +++ b/node/primitives/src/lib.rs @@ -21,21 +21,20 @@ #![cfg_attr(not(feature = "std"), no_std)] use sr_primitives::{ - generic, traits::{Verify, BlakeTwo256}, OpaqueExtrinsic, AnySignature + generic, traits::{Verify, BlakeTwo256, IdentifyAccount}, OpaqueExtrinsic, MultiSignature }; /// An index to a block. pub type BlockNumber = u32; /// Alias to 512-bit hash when used in the context of a transaction signature on the chain. -pub type Signature = AnySignature; +pub type Signature = MultiSignature; /// Some way of identifying an account on the chain. We intentionally make it equivalent /// to the public key of our transaction signing scheme. -pub type AccountId = ::Signer; +pub type AccountId = <::Signer as IdentifyAccount>::AccountId; -/// The type for looking up accounts. We don't expect more than 4 billion of them, but you -/// never know... +/// The type for looking up accounts. We don't expect more than 4 billion of them. pub type AccountIndex = u32; /// Balance of an account. diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index a198877552..d7008dd893 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -42,7 +42,7 @@ use sr_primitives::curve::PiecewiseLinear; use sr_primitives::transaction_validity::TransactionValidity; use sr_primitives::weights::Weight; use sr_primitives::traits::{ - self, BlakeTwo256, Block as BlockT, NumberFor, StaticLookup, SaturatedConversion, + BlakeTwo256, Block as BlockT, NumberFor, StaticLookup, }; use version::RuntimeVersion; #[cfg(any(feature = "std", test))] @@ -83,8 +83,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 182, - impl_version: 182, + spec_version: 183, + impl_version: 183, apis: RUNTIME_API_VERSIONS, }; @@ -455,34 +455,6 @@ impl finality_tracker::Trait for Runtime { type ReportLatency = ReportLatency; } -impl system::offchain::CreateTransaction for Runtime { - type Signature = Signature; - - fn create_transaction>( - call: Call, - account: AccountId, - index: Index, - ) -> Option<(Call, ::SignaturePayload)> { - let period = 1 << 8; - let current_block = System::block_number().saturated_into::(); - let tip = 0; - let extra: SignedExtra = ( - system::CheckVersion::::new(), - system::CheckGenesis::::new(), - system::CheckEra::::from(generic::Era::mortal(period, current_block)), - system::CheckNonce::::from(index), - system::CheckWeight::::new(), - transaction_payment::ChargeTransactionPayment::::from(tip), - Default::default(), - ); - let raw_payload = SignedPayload::new(call, extra).ok()?; - let signature = F::sign(account.clone(), &raw_payload)?; - let address = Indices::unlookup(account); - let (call, extra, _) = raw_payload.deconstruct(); - Some((call, (address, signature, extra))) - } -} - construct_runtime!( pub enum Runtime where Block = Block, @@ -693,28 +665,3 @@ impl_runtime_apis! { } } } - -#[cfg(test)] -mod tests { - use super::*; - use sr_primitives::app_crypto::RuntimeAppPublic; - use system::offchain::SubmitSignedTransaction; - - fn is_submit_signed_transaction(_arg: T) where - T: SubmitSignedTransaction< - Runtime, - Call, - Extrinsic=UncheckedExtrinsic, - CreateTransaction=Runtime, - Signer=Signer, - >, - Signer: RuntimeAppPublic + From, - Signer::Signature: Into, - {} - - #[test] - fn validate_bounds() { - let x = SubmitTransaction::default(); - is_submit_signed_transaction(x); - } -} diff --git a/node/testing/src/keyring.rs b/node/testing/src/keyring.rs index 853ca0ef6d..ca44a53880 100644 --- a/node/testing/src/keyring.rs +++ b/node/testing/src/keyring.rs @@ -23,9 +23,7 @@ use sr_primitives::generic::Era; use codec::Encode; /// Alice's account id. -pub fn alice() -> AccountId { - AccountKeyring::Alice.into() -} +pub fn alice() -> AccountId { AccountKeyring::Alice.into() } /// Bob's account id. pub fn bob() -> AccountId { @@ -82,7 +80,7 @@ pub fn sign(xt: CheckedExtrinsic, version: u32, genesis_hash: [u8; 32]) -> Unche match xt.signed { Some((signed, extra)) => { let payload = (xt.function, extra.clone(), version, genesis_hash, genesis_hash); - let key = AccountKeyring::from_public(&signed).unwrap(); + let key = AccountKeyring::from_account_id(&signed).unwrap(); let signature = payload.using_encoded(|b| { if b.len() > 256 { key.sign(&sr_io::blake2_256(b)) diff --git a/srml/system/src/offchain.rs b/srml/system/src/offchain.rs index e234c74c08..468c88af39 100644 --- a/srml/system/src/offchain.rs +++ b/srml/system/src/offchain.rs @@ -21,71 +21,24 @@ use sr_primitives::app_crypto::RuntimeAppPublic; use sr_primitives::traits::Extrinsic as ExtrinsicT; /// A trait responsible for signing a payload using given account. -pub trait Signer { +pub trait Signer { /// Sign any encodable payload with given account and produce a signature. /// /// Returns `Some` if signing succeeded and `None` in case the `account` couldn't be used. - fn sign(account: Account, payload: &Payload) -> Option; + fn sign(public: Public, payload: &Payload) -> Option; } -impl Signer for AppPublic where - AppPublic: RuntimeAppPublic + From, +impl Signer for AppPublic where + AppPublic: RuntimeAppPublic + From, AppPublic::Signature: Into, { - fn sign(account: Account, raw_payload: &Payload) -> Option { + fn sign(public: Public, raw_payload: &Payload) -> Option { raw_payload.using_encoded(|payload| { - AppPublic::from(account).sign(&payload).map(Into::into) + AppPublic::from(public).sign(&payload).map(Into::into) }) } } -/// Creates runtime-specific signed transaction. -pub trait CreateTransaction { - type Signature; - - /// Attempt to create signed extrinsic data that encodes call from given account. - /// - /// Runtime implementation is free to construct the payload to sign and the signature - /// in any way it wants. - /// Returns `None` if signed extrinsic could not be created (either because signing failed - /// or because of any other runtime-specific reason). - fn create_transaction>( - call: Extrinsic::Call, - account: T::AccountId, - nonce: T::Index, - ) -> Option<(Extrinsic::Call, Extrinsic::SignaturePayload)>; -} - -/// A trait to sign and submit transactions in offchain calls. -pub trait SubmitSignedTransaction { - /// Unchecked extrinsic type. - type Extrinsic: ExtrinsicT + codec::Encode; - - /// A runtime-specific type to produce signed data for the extrinsic. - type CreateTransaction: CreateTransaction; - - /// A type used to sign transactions created using `CreateTransaction`. - type Signer: Signer< - T::AccountId, - >::Signature, - >; - - /// Sign given call and submit it to the transaction pool. - /// - /// Returns `Ok` if the transaction was submitted correctly - /// and `Err` if the key for given `id` was not found or the - /// transaction was rejected from the pool. - fn sign_and_submit(call: impl Into, id: T::AccountId) -> Result<(), ()> { - let call = call.into(); - let expected = >::account_nonce(&id); - let (call, signature_data) = Self::CreateTransaction - ::create_transaction::(call, id, expected) - .ok_or(())?; - let xt = Self::Extrinsic::new(call, Some(signature_data)).ok_or(())?; - runtime_io::submit_transaction(xt.encode()) - } -} - /// A trait to submit unsigned transactions in offchain calls. pub trait SubmitUnsignedTransaction { /// Unchecked extrinsic type. @@ -114,18 +67,6 @@ impl Default for TransactionSubmitter { } } -/// A blanket implementation to simplify creation of transaction signer & submitter in the runtime. -impl SubmitSignedTransaction for TransactionSubmitter where - T: crate::Trait, - C: CreateTransaction, - S: Signer>::Signature>, - E: ExtrinsicT + codec::Encode, -{ - type Extrinsic = E; - type CreateTransaction = C; - type Signer = S; -} - /// A blanket impl to use the same submitter for usigned transactions as well. impl SubmitUnsignedTransaction for TransactionSubmitter where T: crate::Trait, diff --git a/subkey/src/cli.yml b/subkey/src/cli.yml index aa6c6d4a57..5d8cd11b1e 100644 --- a/subkey/src/cli.yml +++ b/subkey/src/cli.yml @@ -12,6 +12,11 @@ args: long: sr25519 help: Use Schnorr/Ristretto x25519/BIP39 cryptography takes_value: false + - secp256k1: + short: k + long: secp256k1 + help: Use SECP256k1/ECDSA/BIP39 cryptography + takes_value: false - password: short: p long: password diff --git a/subkey/src/main.rs b/subkey/src/main.rs index 2596513ab2..1b537580f5 100644 --- a/subkey/src/main.rs +++ b/subkey/src/main.rs @@ -22,15 +22,15 @@ use bip39::{Language, Mnemonic, MnemonicType}; use clap::{load_yaml, App, ArgMatches}; use codec::{Decode, Encode}; use hex_literal::hex; -use node_primitives::{Balance, Hash, Index}; +use node_primitives::{Balance, Hash, Index, AccountId, Signature}; use node_runtime::{BalancesCall, Call, Runtime, SignedPayload, UncheckedExtrinsic, VERSION}; use primitives::{ crypto::{set_default_ss58_version, Ss58AddressFormat, Ss58Codec}, - ed25519, sr25519, Pair, Public, H256, hexdisplay::HexDisplay, + ed25519, sr25519, ecdsa, Pair, Public, H256, hexdisplay::HexDisplay, }; -use sr_primitives::generic::Era; +use sr_primitives::{traits::{IdentifyAccount, Verify}, generic::Era}; use std::{ - convert::TryInto, + convert::{TryInto, TryFrom}, io::{stdin, Read}, str::FromStr, }; @@ -43,8 +43,10 @@ trait Crypto: Sized { fn pair_from_suri(suri: &str, password: Option<&str>) -> Self::Pair { Self::Pair::from_string(suri, password).expect("Invalid phrase") } - fn ss58_from_pair(pair: &Self::Pair) -> String { - pair.public().to_ss58check() + fn ss58_from_pair(pair: &Self::Pair) -> String where + ::Public: PublicT, + { + pair.public().into_runtime().into_account().to_ss58check() } fn public_from_pair(pair: &Self::Pair) -> Self::Public { pair.public() @@ -58,28 +60,43 @@ trait Crypto: Sized { { if let Ok((pair, seed)) = Self::Pair::from_phrase(uri, password) { let public_key = Self::public_from_pair(&pair); - println!("Secret phrase `{}` is account:\n Secret seed: {}\n Public key (hex): {}\n Address (SS58): {}", + println!("Secret phrase `{}` is account:\n \ + Secret seed: {}\n \ + Public key (hex): {}\n \ + Account ID: {}\n \ + SS58 Address: {}", uri, format_seed::(seed), - format_public_key::(public_key), + format_public_key::(public_key.clone()), + format_account_id::(public_key), Self::ss58_from_pair(&pair) ); - } else if let Ok(pair) = Self::Pair::from_string(uri, password) { + } else if let Ok((pair, seed)) = Self::Pair::from_string_with_seed(uri, password) { let public_key = Self::public_from_pair(&pair); - println!( - "Secret Key URI `{}` is account:\n Public key (hex): {}\n Address (SS58): {}", + println!("Secret Key URI `{}` is account:\n \ + Secret seed: {}\n \ + Public key (hex): {}\n \ + Account ID: {}\n \ + SS58 Address: {}", uri, - format_public_key::(public_key), + if let Some(seed) = seed { format_seed::(seed) } else { "n/a".into() }, + format_public_key::(public_key.clone()), + format_account_id::(public_key), Self::ss58_from_pair(&pair) ); } else if let Ok((public_key, v)) = ::Public::from_string_with_version(uri) { let v = network_override.unwrap_or(v); - println!("Public Key URI `{}` is account:\n Network ID/version: {}\n Public key (hex): {}\n Address (SS58): {}", + println!("Public Key URI `{}` is account:\n \ + Network ID/version: {}\n \ + Public key (hex): {}\n \ + Account ID: {}\n \ + SS58 Address: {}", uri, String::from(v), format_public_key::(public_key.clone()), + format_account_id::(public_key.clone()), public_key.to_ss58check_with_version(v) ); } else { @@ -106,17 +123,37 @@ impl Crypto for Sr25519 { type Public = sr25519::Public; } +struct Ecdsa; + +impl Crypto for Ecdsa { + type Pair = ecdsa::Pair; + type Public = ecdsa::Public; +} + type SignatureOf = <::Pair as Pair>::Signature; type PublicOf = <::Pair as Pair>::Public; type SeedOf = <::Pair as Pair>::Seed; +type AccountPublic = ::Signer; -trait SignatureT: AsRef<[u8]> + AsMut<[u8]> + Default {} -trait PublicT: Sized + AsRef<[u8]> + Ss58Codec {} +trait SignatureT: AsRef<[u8]> + AsMut<[u8]> + Default { + /// Converts the signature into a runtime account signature, if possible. If not possible, bombs out. + fn into_runtime(self) -> Signature { + panic!("This cryptography isn't supported for this runtime.") + } +} +trait PublicT: Sized + AsRef<[u8]> + Ss58Codec { + /// Converts the public key into a runtime account public key, if possible. If not possible, bombs out. + fn into_runtime(self) -> AccountPublic { + panic!("This cryptography isn't supported for this runtime.") + } +} -impl SignatureT for sr25519::Signature {} -impl SignatureT for ed25519::Signature {} -impl PublicT for sr25519::Public {} -impl PublicT for ed25519::Public {} +impl SignatureT for sr25519::Signature { fn into_runtime(self) -> Signature { self.into() } } +impl SignatureT for ed25519::Signature { fn into_runtime(self) -> Signature { self.into() } } +impl SignatureT for ecdsa::Signature { fn into_runtime(self) -> Signature { self.into() } } +impl PublicT for sr25519::Public { fn into_runtime(self) -> AccountPublic { self.into() } } +impl PublicT for ed25519::Public { fn into_runtime(self) -> AccountPublic { self.into() } } +impl PublicT for ecdsa::Public { fn into_runtime(self) -> AccountPublic { self.into() } } fn main() { let yaml = load_yaml!("cli.yml"); @@ -125,10 +162,12 @@ fn main() { .get_matches(); if matches.is_present("ed25519") { - execute::(matches) - } else { - execute::(matches) + return execute::(matches) } + if matches.is_present("secp256k1") { + return execute::(matches) + } + return execute::(matches) } fn execute(matches: ArgMatches) @@ -165,7 +204,7 @@ where ("verify", Some(matches)) => { let should_decode = matches.is_present("hex"); let message = read_message_from_stdin(should_decode); - let is_valid_signature = do_verify::(matches, message, password); + let is_valid_signature = do_verify::(matches, message); if is_valid_signature { println!("Signature verifies correctly."); } else { @@ -182,20 +221,20 @@ where C::print_from_uri(&formated_seed, None, maybe_network); } ("transfer", Some(matches)) => { - let signer = read_pair::(matches.value_of("from"), password); + let signer = read_pair::(matches.value_of("from"), password); let index = read_required_parameter::(matches, "index"); let genesis_hash = read_genesis_hash(matches); - let to = read_public_key::(matches.value_of("to"), password); + let to: AccountId = read_account_id(matches.value_of("to")); let amount = read_required_parameter::(matches, "amount"); let function = Call::Balances(BalancesCall::transfer(to.into(), amount)); - let extrinsic = create_extrinsic(function, index, signer, genesis_hash); + let extrinsic = create_extrinsic::(function, index, signer, genesis_hash); print_extrinsic(extrinsic); } ("sign-transaction", Some(matches)) => { - let signer = read_pair::(matches.value_of("suri"), password); + let signer = read_pair::(matches.value_of("suri"), password); let index = read_required_parameter::(matches, "nonce"); let genesis_hash = read_genesis_hash(matches); @@ -205,7 +244,7 @@ where .and_then(|x| Decode::decode(&mut &x[..]).ok()) .unwrap(); - let extrinsic = create_extrinsic(function, index, signer, genesis_hash); + let extrinsic = create_extrinsic::(function, index, signer, genesis_hash); print_extrinsic(extrinsic); } @@ -236,13 +275,13 @@ where format_signature::(&signature) } -fn do_verify(matches: &ArgMatches, message: Vec, password: Option<&str>) -> bool +fn do_verify(matches: &ArgMatches, message: Vec) -> bool where SignatureOf: SignatureT, PublicOf: PublicT, { let signature = read_signature::(matches); - let pubkey = read_public_key::(matches.value_of("uri"), password); + let pubkey = read_public_key::(matches.value_of("uri")); <::Pair as Pair>::verify(&signature, &message, &pubkey) } @@ -305,9 +344,7 @@ where signature } -fn read_public_key(matched_uri: Option<&str>, password: Option<&str>) -> PublicOf -where - SignatureOf: SignatureT, +fn read_public_key(matched_uri: Option<&str>) -> PublicOf where PublicOf: PublicT, { let uri = matched_uri.expect("parameter is required; thus it can't be None; qed"); @@ -319,13 +356,28 @@ where if let Ok(pubkey_vec) = hex::decode(uri) { ::Public::from_slice(pubkey_vec.as_slice()) } else { - ::Pair::from_string(uri, password) + ::Public::from_string(uri) .ok() - .map(|p| p.public()) .expect("Invalid URI; expecting either a secret URI or a public URI.") } } +fn read_account_id(matched_uri: Option<&str>) -> AccountId { + let uri = matched_uri.expect("parameter is required; thus it can't be None; qed"); + let uri = if uri.starts_with("0x") { + &uri[2..] + } else { + uri + }; + if let Ok(data_vec) = hex::decode(uri) { + AccountId::try_from(data_vec.as_slice()) + .expect("Invalid hex length for account ID; should be 32 bytes") + } else { + AccountId::from_ss58check(uri).ok() + .expect("Invalid SS58-check address given for account ID.") + } +} + fn read_pair( matched_suri: Option<&str>, password: Option<&str>, @@ -350,12 +402,21 @@ fn format_public_key(public_key: PublicOf) -> String { format!("0x{}", HexDisplay::from(&public_key.as_ref())) } -fn create_extrinsic( +fn format_account_id(public_key: PublicOf) -> String where + PublicOf: PublicT, +{ + format!("0x{}", HexDisplay::from(&public_key.into_runtime().into_account().as_ref())) +} + +fn create_extrinsic( function: Call, index: Index, - signer: ::Pair, + signer: C::Pair, genesis_hash: H256, -) -> UncheckedExtrinsic { +) -> UncheckedExtrinsic where + PublicOf: PublicT, + SignatureOf: SignatureT, +{ let extra = |i: Index, f: Balance| { ( system::CheckVersion::::new(), @@ -380,13 +441,14 @@ fn create_extrinsic( (), ), ); - let signature = raw_payload.using_encoded(|payload| signer.sign(payload)); + let signature = raw_payload.using_encoded(|payload| signer.sign(payload)).into_runtime(); + let signer = signer.public().into_runtime(); let (function, extra, _) = raw_payload.deconstruct(); UncheckedExtrinsic::new_signed( function, - signer.public().into(), - signature.into(), + signer.into_account().into(), + signature, extra, ) } @@ -439,7 +501,7 @@ mod tests { let matches = App::from_yaml(yaml).get_matches_from(arg_vec); let matches = matches.subcommand().1.unwrap(); - assert!(do_verify::(matches, message, password)); + assert!(do_verify::(matches, message)); } #[test] diff --git a/subkey/src/vanity.rs b/subkey/src/vanity.rs index b612bc470f..835001a0aa 100644 --- a/subkey/src/vanity.rs +++ b/subkey/src/vanity.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use super::Crypto; +use super::{PublicOf, PublicT, Crypto}; use primitives::Pair; use rand::{rngs::OsRng, RngCore}; @@ -62,7 +62,9 @@ fn calculate_score(_desired: &str, key: &str) -> usize { 0 } -pub(super) fn generate_key(desired: &str) -> Result, &str> { +pub(super) fn generate_key(desired: &str) -> Result, &str> where + PublicOf: PublicT, +{ if desired.is_empty() { return Err("Pattern must not be empty"); } diff --git a/test-utils/chain-spec-builder/src/main.rs b/test-utils/chain-spec-builder/src/main.rs index 22c5253b06..8fdd282345 100644 --- a/test-utils/chain-spec-builder/src/main.rs +++ b/test-utils/chain-spec-builder/src/main.rs @@ -22,7 +22,7 @@ use structopt::StructOpt; use keystore::{Store as Keystore}; use node_cli::chain_spec::{self, AccountId}; -use primitives::{crypto::{Public, Ss58Codec}, traits::BareCryptoStore}; +use primitives::{sr25519, crypto::{Public, Ss58Codec}, traits::BareCryptoStore}; /// A utility to easily create a testnet chain spec definition with a given set /// of authorities and endowed accounts and/or generate random accounts. @@ -237,11 +237,11 @@ fn main() -> Result<(), String> { } let endowed_accounts = endowed_seeds.iter().map(|seed| { - chain_spec::get_from_seed::(seed) + chain_spec::get_account_id_from_seed::(seed) .to_ss58check() }).collect(); - let sudo_account = chain_spec::get_from_seed::(&sudo_seed) + let sudo_account = chain_spec::get_account_id_from_seed::(&sudo_seed) .to_ss58check(); (authority_seeds, endowed_accounts, sudo_account) -- GitLab From 7cc598c2d454606b8aabe4ca18c2b1bb5ad59fb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Thu, 24 Oct 2019 13:29:09 +0100 Subject: [PATCH 267/275] node-template: remove unnecessary on_exit guard (#3903) --- node-template/src/service.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/node-template/src/service.rs b/node-template/src/service.rs index c46928c10e..46c0124cb4 100644 --- a/node-template/src/service.rs +++ b/node-template/src/service.rs @@ -115,8 +115,6 @@ pub fn new_full(config: Configuration Date: Thu, 24 Oct 2019 15:03:52 +0200 Subject: [PATCH 268/275] Better Parameterisation for Fee system (#3823) * Better fee parameters * Fix build * Better runtime tests * Price to Weight ratio as type parameter (#3856) * Price to Weight ration as type parameter * Kian feedback * Some renames. * Fix executor tests * Getting Closer. * Phantom Data * Actually fix executor tests. * Fix tests. * Remove todo * Fix build --- Cargo.lock | 1 + core/sr-arithmetic/src/biguint.rs | 2 +- core/sr-arithmetic/src/fixed64.rs | 6 + node/executor/src/lib.rs | 11 +- node/runtime/Cargo.toml | 3 + node/runtime/src/constants.rs | 16 -- node/runtime/src/impls.rs | 322 +++++++++++++++------------- node/runtime/src/lib.rs | 12 +- srml/system/src/lib.rs | 27 ++- srml/transaction-payment/src/lib.rs | 6 +- 10 files changed, 217 insertions(+), 189 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 14f8c87c1a..c3c3e66c12 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2472,6 +2472,7 @@ dependencies = [ "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-staking-primitives 2.0.0", "sr-std 2.0.0", diff --git a/core/sr-arithmetic/src/biguint.rs b/core/sr-arithmetic/src/biguint.rs index b7d93c2f0d..c0836e09b3 100644 --- a/core/sr-arithmetic/src/biguint.rs +++ b/core/sr-arithmetic/src/biguint.rs @@ -21,7 +21,7 @@ use rstd::{cmp::Ordering, ops, prelude::*, cell::RefCell, convert::TryFrom}; // A sensible value for this would be half of the dword size of the host machine. Since the // runtime is compiled to 32bit webassembly, using 32 and 64 for single and double respectively -// should yield the most performance. TODO #3745 we could benchmark this and verify. +// should yield the most performance. /// Representation of a single limb. pub type Single = u32; /// Representation of two limbs. diff --git a/core/sr-arithmetic/src/fixed64.rs b/core/sr-arithmetic/src/fixed64.rs index 3bac75898e..bd58e36940 100644 --- a/core/sr-arithmetic/src/fixed64.rs +++ b/core/sr-arithmetic/src/fixed64.rs @@ -48,6 +48,12 @@ impl Fixed64 { DIV } + /// Consume self and return the inner value. + /// + /// This should only be used for testing. + #[cfg(any(feature = "std", test))] + pub fn into_inner(self) -> i64 { self.0 } + /// Raw constructor. Equal to `parts / 1_000_000_000`. pub fn from_parts(parts: i64) -> Self { Self(parts) diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index 3c97b3cd11..39727d1d55 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -38,9 +38,7 @@ mod tests { use super::Executor; use {balances, contracts, indices, system, timestamp}; use codec::{Encode, Decode, Joiner}; - use runtime_support::{ - Hashable, StorageValue, StorageMap, traits::Currency, - }; + use runtime_support::{Hashable, StorageValue, StorageMap, traits::Currency}; use state_machine::TestExternalities as CoreTestExternalities; use primitives::{ Blake2Hasher, NeverNativeValue, NativeOrEncoded, map, @@ -57,8 +55,9 @@ mod tests { use node_runtime::{ Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances, BuildStorage, System, TransactionPayment, Event, TransferFee, TransactionBaseFee, TransactionByteFee, - constants::currency::*, impls::WeightToFee, + WeightFeeCoefficient, constants::currency::*, }; + use node_runtime::impls::LinearWeightToFee; use node_primitives::{Balance, Hash, BlockNumber}; use node_testing::keyring::*; use wabt; @@ -501,8 +500,6 @@ mod tests { ).0.unwrap(); t.execute_with(|| { - // NOTE: fees differ slightly in tests that execute more than one block due to the - // weight update. Hence, using `assert_eq_error_rate`. assert_eq!( Balances::total_balance(&alice()), alice_last_known_balance - 10 * DOLLARS - transfer_fee(&xt(), fm), @@ -1069,7 +1066,7 @@ mod tests { balance_alice -= length_fee; let weight = default_transfer_call().get_dispatch_info().weight; - let weight_fee = WeightToFee::convert(weight); + let weight_fee = LinearWeightToFee::::convert(weight); // we know that weight to fee multiplier is effect-less in block 1. assert_eq!(weight_fee as Balance, MILLICENTS); diff --git a/node/runtime/Cargo.toml b/node/runtime/Cargo.toml index 252a7767ea..5a6a2b6772 100644 --- a/node/runtime/Cargo.toml +++ b/node/runtime/Cargo.toml @@ -57,6 +57,9 @@ transaction-payment = { package = "srml-transaction-payment", path = "../../srml [build-dependencies] wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.4", path = "../../core/utils/wasm-builder-runner" } +[dev-dependencies] +runtime_io = { package = "sr-io", path = "../../core/sr-io" } + [features] default = ["std"] std = [ diff --git a/node/runtime/src/constants.rs b/node/runtime/src/constants.rs index ca57bdc8ba..fba4c7ac79 100644 --- a/node/runtime/src/constants.rs +++ b/node/runtime/src/constants.rs @@ -66,19 +66,3 @@ pub mod time { pub const HOURS: BlockNumber = MINUTES * 60; pub const DAYS: BlockNumber = HOURS * 24; } - -// CRITICAL NOTE: The system module maintains two constants: a _maximum_ block weight and a _ratio_ -// of it yielding the portion which is accessible to normal transactions (reserving the rest for -// operational ones). `TARGET_BLOCK_FULLNESS` is entirely independent and the system module is not -// aware of if, nor should it care about it. This constant simply denotes on which ratio of the -// _maximum_ block weight we tweak the fees. It does NOT care about the type of the dispatch. -// -// For the system to be configured in a sane way, `TARGET_BLOCK_FULLNESS` should always be less than -// the ratio that `system` module uses to find normal transaction quota. -/// Fee-related. -pub mod fee { - pub use sr_primitives::Perbill; - - /// The block saturation level. Fees will be updates based on this value. - pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25); -} diff --git a/node/runtime/src/impls.rs b/node/runtime/src/impls.rs index 2193845020..2e9bd38c8f 100644 --- a/node/runtime/src/impls.rs +++ b/node/runtime/src/impls.rs @@ -19,10 +19,9 @@ use node_primitives::Balance; use sr_primitives::weights::Weight; use sr_primitives::traits::{Convert, Saturating}; -use sr_primitives::Fixed64; -use support::traits::{OnUnbalanced, Currency}; -use crate::{Balances, Authorship, MaximumBlockWeight, NegativeImbalance}; -use crate::constants::fee::TARGET_BLOCK_FULLNESS; +use sr_primitives::{Fixed64, Perbill}; +use support::traits::{OnUnbalanced, Currency, Get}; +use crate::{Balances, System, Authorship, MaximumBlockWeight, NegativeImbalance}; pub struct Author; impl OnUnbalanced for Author { @@ -47,48 +46,34 @@ impl Convert for CurrencyToVoteHandler { fn convert(x: u128) -> Balance { x * Self::factor() } } -/// Handles converting a weight scalar to a fee value, based on the scale and granularity of the -/// node's balance type. -/// -/// This should typically create a mapping between the following ranges: -/// - [0, system::MaximumBlockWeight] -/// - [Balance::min, Balance::max] -/// -/// Yet, it can be used for any other sort of change to weight-fee. Some examples being: -/// - Setting it to `0` will essentially disable the weight fee. -/// - Setting it to `1` will cause the literal `#[weight = x]` values to be charged. -/// -/// By default, substrate node will have a weight range of [0, 1_000_000_000]. -pub struct WeightToFee; -impl Convert for WeightToFee { - fn convert(x: Weight) -> Balance { +/// Convert from weight to balance via a simple coefficient multiplication +/// The associated type C encapsulates a constant in units of balance per weight +pub struct LinearWeightToFee(rstd::marker::PhantomData); + +impl> Convert for LinearWeightToFee { + fn convert(w: Weight) -> Balance { // substrate-node a weight of 10_000 (smallest non-zero weight) to be mapped to 10^7 units of // fees, hence: - Balance::from(x).saturating_mul(1_000) + let coefficient = C::get(); + Balance::from(w).saturating_mul(coefficient) } } -/// A struct that updates the weight multiplier based on the saturation level of the previous block. -/// This should typically be called once per-block. +/// Update the given multiplier based on the following formula /// -/// This assumes that weight is a numeric value in the u32 range. -/// -/// Given `TARGET_BLOCK_FULLNESS = 1/2`, a block saturation greater than 1/2 will cause the system -/// fees to slightly grow and the opposite for block saturations less than 1/2. -/// -/// Formula: -/// diff = (target_weight - current_block_weight) +/// diff = (target_weight - previous_block_weight) /// v = 0.00004 /// next_weight = weight * (1 + (v . diff) + (v . diff)^2 / 2) /// +/// Where `target_weight` must be given as the `Get` implementation of the `T` generic type. /// https://research.web3.foundation/en/latest/polkadot/Token%20Economics/#relay-chain-transaction-fees -pub struct FeeMultiplierUpdateHandler; +pub struct TargetedFeeAdjustment(rstd::marker::PhantomData); -impl Convert<(Weight, Fixed64), Fixed64> for FeeMultiplierUpdateHandler { - fn convert(previous_state: (Weight, Fixed64)) -> Fixed64 { - let (block_weight, multiplier) = previous_state; +impl> Convert for TargetedFeeAdjustment { + fn convert(multiplier: Fixed64) -> Fixed64 { + let block_weight = System::all_extrinsics_weight(); let max_weight = MaximumBlockWeight::get(); - let target_weight = (TARGET_BLOCK_FULLNESS * max_weight) as u128; + let target_weight = (T::get() * max_weight) as u128; let block_weight = block_weight as u128; // determines if the first_term is positive @@ -100,8 +85,8 @@ impl Convert<(Weight, Fixed64), Fixed64> for FeeMultiplierUpdateHandler { // 0.00004 = 4/100_000 = 40_000/10^9 let v = Fixed64::from_rational(4, 100_000); - // 0.00004^2 = 16/10^10 ~= 2/10^9. Taking the future /2 into account, then it is just 1 parts - // from a billionth. + // 0.00004^2 = 16/10^10 ~= 2/10^9. Taking the future /2 into account, then it is just 1 + // parts from a billionth. let v_squared_2 = Fixed64::from_rational(1, 1_000_000_000); let first_term = v.saturating_mul(diff); @@ -132,15 +117,16 @@ impl Convert<(Weight, Fixed64), Fixed64> for FeeMultiplierUpdateHandler { mod tests { use super::*; use sr_primitives::weights::Weight; + use sr_primitives::assert_eq_error_rate; use crate::{MaximumBlockWeight, AvailableBlockRatio, Runtime}; - use crate::constants::currency::*; + use crate::{constants::currency::*, TransactionPayment, TargetBlockFullness}; fn max() -> Weight { MaximumBlockWeight::get() } fn target() -> Weight { - TARGET_BLOCK_FULLNESS * max() + TargetBlockFullness::get() * max() } // poc reference implementation. @@ -155,50 +141,68 @@ mod tests { // Current saturation in terms of weight let s = block_weight; - let fm = (v * (s/m - ss/m)) + (v.powi(2) * (s/m - ss/m).powi(2)) / 2.0; - let addition_fm = Fixed64::from_parts((fm * 1_000_000_000_f32) as i64); + let fm = v * (s/m - ss/m) + v.powi(2) * (s/m - ss/m).powi(2) / 2.0; + let addition_fm = Fixed64::from_parts((fm * 1_000_000_000_f32).round() as i64); previous.saturating_add(addition_fm) } - fn fm(parts: i64) -> Fixed64 { + fn feemul(parts: i64) -> Fixed64 { Fixed64::from_parts(parts) } + fn run_with_system_weight(w: Weight, assertions: F) where F: Fn() -> () { + let mut t: runtime_io::TestExternalities = + system::GenesisConfig::default().build_storage::().unwrap().into(); + t.execute_with(|| { + System::set_block_limits(w, 0); + assertions() + }); + } + #[test] fn fee_multiplier_update_poc_works() { let fm = Fixed64::from_rational(0, 1); let test_set = vec![ - // TODO: this has a rounding error and fails. - // (0, fm.clone()), + (0, fm.clone()), (100, fm.clone()), (target(), fm.clone()), (max() / 2, fm.clone()), (max(), fm.clone()), ]; test_set.into_iter().for_each(|(w, fm)| { - assert_eq!( - fee_multiplier_update(w, fm), - FeeMultiplierUpdateHandler::convert((w, fm)), - "failed for weight {} and prev fm {:?}", - w, - fm, - ); + run_with_system_weight(w, || { + assert_eq_error_rate!( + fee_multiplier_update(w, fm).into_inner(), + TargetedFeeAdjustment::::convert(fm).into_inner(), + 5, + ); + }) }) } #[test] fn empty_chain_simulation() { // just a few txs per_block. - let block_weight = 1000; - let mut fm = Fixed64::default(); - let mut iterations: u64 = 0; - loop { - let next = FeeMultiplierUpdateHandler::convert((block_weight, fm)); - fm = next; - if fm == Fixed64::from_rational(-1, 1) { break; } - iterations += 1; - } - println!("iteration {}, new fm = {:?}. Weight fee is now zero", iterations, fm); + let block_weight = 0; + run_with_system_weight(block_weight, || { + let mut fm = Fixed64::default(); + let mut iterations: u64 = 0; + loop { + let next = TargetedFeeAdjustment::::convert(fm); + fm = next; + if fm == Fixed64::from_rational(-1, 1) { break; } + iterations += 1; + } + println!("iteration {}, new fm = {:?}. Weight fee is now zero", iterations, fm); + assert!(iterations > 50_000, "This assertion is just a warning; Don't panic. \ + Current substrate/polkadot node are configured with a _slow adjusting fee_ \ + mechanism. Hence, it is really unlikely that fees collapse to zero even on an \ + empty chain in less than at least of couple of thousands of empty blocks. But this \ + simulation indicates that fees collapsed to zero after {} almost-empty blocks. \ + Check it", + iterations, + ); + }) } #[test] @@ -207,100 +211,116 @@ mod tests { // `cargo test congested_chain_simulation -- --nocapture` to get some insight. // almost full. The entire quota of normal transactions is taken. - let block_weight = AvailableBlockRatio::get() * max(); - - // default minimum substrate weight - let tx_weight = 10_000u32; - - // initial value of system - let mut fm = Fixed64::default(); - assert_eq!(fm, Fixed64::from_parts(0)); - - let mut iterations: u64 = 0; - loop { - let next = FeeMultiplierUpdateHandler::convert((block_weight, fm)); - if fm == next { break; } - fm = next; - iterations += 1; - let fee = ::WeightToFee::convert(tx_weight); - let adjusted_fee = fm.saturated_multiply_accumulate(fee); - println!( - "iteration {}, new fm = {:?}. Fee at this point is: \ - {} units, {} millicents, {} cents, {} dollars", - iterations, - fm, - adjusted_fee, - adjusted_fee / MILLICENTS, - adjusted_fee / CENTS, - adjusted_fee / DOLLARS - ); - } + let block_weight = AvailableBlockRatio::get() * max() - 100; + + // Default substrate minimum. + let tx_weight = 10_000; + + run_with_system_weight(block_weight, || { + // initial value configured on module + let mut fm = Fixed64::default(); + assert_eq!(fm, TransactionPayment::next_fee_multiplier()); + + let mut iterations: u64 = 0; + loop { + let next = TargetedFeeAdjustment::::convert(fm); + // if no change, panic. This should never happen in this case. + if fm == next { panic!("The fee should ever increase"); } + fm = next; + iterations += 1; + let fee = ::WeightToFee::convert(tx_weight); + let adjusted_fee = fm.saturated_multiply_accumulate(fee); + println!( + "iteration {}, new fm = {:?}. Fee at this point is: {} units / {} millicents, \ + {} cents, {} dollars", + iterations, + fm, + adjusted_fee, + adjusted_fee / MILLICENTS, + adjusted_fee / CENTS, + adjusted_fee / DOLLARS, + ); + } + }); } #[test] fn stateless_weight_mul() { - // Light block. Fee is reduced a little. - assert_eq!( - FeeMultiplierUpdateHandler::convert((target() / 4, Fixed64::default())), - fm(-7500) - ); - // a bit more. Fee is decreased less, meaning that the fee increases as the block grows. - assert_eq!( - FeeMultiplierUpdateHandler::convert((target() / 2, Fixed64::default())), - fm(-5000) - ); - // ideal. Original fee. No changes. - assert_eq!( - FeeMultiplierUpdateHandler::convert((target(), Fixed64::default())), - fm(0) - ); - // // More than ideal. Fee is increased. - assert_eq!( - FeeMultiplierUpdateHandler::convert(((target() * 2), Fixed64::default())), - fm(10000) - ); + run_with_system_weight(target() / 4, || { + // Light block. Fee is reduced a little. + assert_eq!( + TargetedFeeAdjustment::::convert(Fixed64::default()), + feemul(-7500), + ); + }); + run_with_system_weight(target() / 2, || { + // a bit more. Fee is decreased less, meaning that the fee increases as the block grows. + assert_eq!( + TargetedFeeAdjustment::::convert(Fixed64::default()), + feemul(-5000), + ); + + }); + run_with_system_weight(target(), || { + // ideal. Original fee. No changes. + assert_eq!( + TargetedFeeAdjustment::::convert(Fixed64::default()), + feemul(0), + ); + }); + run_with_system_weight(target() * 2, || { + // // More than ideal. Fee is increased. + assert_eq!( + TargetedFeeAdjustment::::convert(Fixed64::default()), + feemul(10000), + ); + }); } #[test] fn stateful_weight_mul_grow_to_infinity() { - assert_eq!( - FeeMultiplierUpdateHandler::convert((target() * 2, Fixed64::default())), - fm(10000) - ); - assert_eq!( - FeeMultiplierUpdateHandler::convert((target() * 2, fm(10000))), - fm(20000) - ); - assert_eq!( - FeeMultiplierUpdateHandler::convert((target() * 2, fm(20000))), - fm(30000) - ); - // ... - assert_eq!( - FeeMultiplierUpdateHandler::convert((target() * 2, fm(1_000_000_000))), - fm(1_000_000_000 + 10000) - ); + run_with_system_weight(target() * 2, || { + assert_eq!( + TargetedFeeAdjustment::::convert(Fixed64::default()), + feemul(10000) + ); + assert_eq!( + TargetedFeeAdjustment::::convert(feemul(10000)), + feemul(20000) + ); + assert_eq!( + TargetedFeeAdjustment::::convert(feemul(20000)), + feemul(30000) + ); + // ... + assert_eq!( + TargetedFeeAdjustment::::convert(feemul(1_000_000_000)), + feemul(1_000_000_000 + 10000) + ); + }); } #[test] fn stateful_weight_mil_collapse_to_minus_one() { - assert_eq!( - FeeMultiplierUpdateHandler::convert((0, Fixed64::default())), - fm(-10000) - ); - assert_eq!( - FeeMultiplierUpdateHandler::convert((0, fm(-10000))), - fm(-20000) - ); - assert_eq!( - FeeMultiplierUpdateHandler::convert((0, fm(-20000))), - fm(-30000) - ); - // ... - assert_eq!( - FeeMultiplierUpdateHandler::convert((0, fm(1_000_000_000 * -1))), - fm(-1_000_000_000) - ); + run_with_system_weight(0, || { + assert_eq!( + TargetedFeeAdjustment::::convert(Fixed64::default()), + feemul(-10000) + ); + assert_eq!( + TargetedFeeAdjustment::::convert(feemul(-10000)), + feemul(-20000) + ); + assert_eq!( + TargetedFeeAdjustment::::convert(feemul(-20000)), + feemul(-30000) + ); + // ... + assert_eq!( + TargetedFeeAdjustment::::convert(feemul(1_000_000_000 * -1)), + feemul(-1_000_000_000) + ); + }) } #[test] @@ -309,6 +329,7 @@ mod tests { let mb = kb * kb; let max_fm = Fixed64::from_natural(i64::max_value()); + // check that for all values it can compute, correctly. vec![ 0, 1, @@ -322,7 +343,11 @@ mod tests { Weight::max_value() / 2, Weight::max_value() ].into_iter().for_each(|i| { - FeeMultiplierUpdateHandler::convert((i, Fixed64::default())); + run_with_system_weight(i, || { + let next = TargetedFeeAdjustment::::convert(Fixed64::default()); + let truth = fee_multiplier_update(i, Fixed64::default()); + assert_eq_error_rate!(truth.into_inner(), next.into_inner(), 5); + }); }); // Some values that are all above the target and will cause an increase. @@ -330,12 +355,11 @@ mod tests { vec![t + 100, t * 2, t * 4] .into_iter() .for_each(|i| { - let fm = FeeMultiplierUpdateHandler::convert(( - i, - max_fm - )); - // won't grow. The convert saturates everything. - assert_eq!(fm, max_fm); + run_with_system_weight(i, || { + let fm = TargetedFeeAdjustment::::convert(max_fm); + // won't grow. The convert saturates everything. + assert_eq!(fm, max_fm); + }) }); } } diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index d7008dd893..9097dd22a3 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -64,7 +64,7 @@ pub use staking::StakerStatus; /// Implementations of some helper traits passed into runtime modules as associated types. pub mod impls; -use impls::{CurrencyToVoteHandler, FeeMultiplierUpdateHandler, Author, WeightToFee}; +use impls::{CurrencyToVoteHandler, Author, LinearWeightToFee, TargetedFeeAdjustment}; /// Constant values used within the runtime. pub mod constants; @@ -109,9 +109,9 @@ pub type DealWithFees = SplitTwoWays< parameter_types! { pub const BlockHashCount: BlockNumber = 250; pub const MaximumBlockWeight: Weight = 1_000_000_000; - pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; pub const Version: RuntimeVersion = VERSION; + pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); } impl system::Trait for Runtime { @@ -176,6 +176,10 @@ impl balances::Trait for Runtime { parameter_types! { pub const TransactionBaseFee: Balance = 1 * CENTS; pub const TransactionByteFee: Balance = 10 * MILLICENTS; + // setting this to zero will disable the weight fee. + pub const WeightFeeCoefficient: Balance = 1_000; + // for a sane configuration, this should always be less than `AvailableBlockRatio`. + pub const TargetBlockFullness: Perbill = Perbill::from_percent(25); } impl transaction_payment::Trait for Runtime { @@ -183,8 +187,8 @@ impl transaction_payment::Trait for Runtime { type OnTransactionPayment = DealWithFees; type TransactionBaseFee = TransactionBaseFee; type TransactionByteFee = TransactionByteFee; - type WeightToFee = WeightToFee; - type FeeMultiplierUpdate = FeeMultiplierUpdateHandler; + type WeightToFee = LinearWeightToFee; + type FeeMultiplierUpdate = TargetedFeeAdjustment; } parameter_types! { diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index c9dcca53cb..87c38096ab 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -157,15 +157,17 @@ pub fn extrinsics_data_root(xts: Vec>) -> H::Output { pub trait Trait: 'static + Eq + Clone { /// The aggregated `Origin` type used by dispatchable calls. - type Origin: Into, Self::Origin>> + From>; + type Origin: + Into, Self::Origin>> + From>; /// The aggregated `Call` type. type Call: Debug; - /// Account index (aka nonce) type. This stores the number of previous transactions associated with a sender - /// account. + /// Account index (aka nonce) type. This stores the number of previous transactions associated + /// with a sender account. type Index: - Parameter + Member + MaybeSerialize + Debug + Default + MaybeDisplay + SimpleArithmetic + Copy; + Parameter + Member + MaybeSerialize + Debug + Default + MaybeDisplay + SimpleArithmetic + + Copy; /// The block number type used by the runtime. type BlockNumber: @@ -181,13 +183,15 @@ pub trait Trait: 'static + Eq + Clone { type Hashing: Hash; /// The user account identifier type for the runtime. - type AccountId: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + Ord + Default; + type AccountId: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + Ord + + Default; /// Converting trait to take a source type and convert to `AccountId`. /// - /// Used to define the type and conversion mechanism for referencing accounts in transactions. It's perfectly - /// reasonable for this to be an identity conversion (with the source type being `AccountId`), but other modules - /// (e.g. Indices module) may provide more functional/efficient alternatives. + /// Used to define the type and conversion mechanism for referencing accounts in transactions. + /// It's perfectly reasonable for this to be an identity conversion (with the source type being + /// `AccountId`), but other modules (e.g. Indices module) may provide more functional/efficient + /// alternatives. type Lookup: StaticLookup; /// The block header. @@ -701,6 +705,13 @@ impl Module { >::put(n); } + /// Set the current block weight. This should only be used in some integration tests. + #[cfg(any(feature = "std", test))] + pub fn set_block_limits(weight: Weight, len: usize) { + AllExtrinsicsWeight::put(weight); + AllExtrinsicsLen::put(len as u32); + } + /// Return the chain's current runtime version. pub fn runtime_version() -> RuntimeVersion { T::Version::get() } diff --git a/srml/transaction-payment/src/lib.rs b/srml/transaction-payment/src/lib.rs index ab120322f6..5ad5c650af 100644 --- a/srml/transaction-payment/src/lib.rs +++ b/srml/transaction-payment/src/lib.rs @@ -70,8 +70,7 @@ pub trait Trait: system::Trait { type WeightToFee: Convert>; /// Update the multiplier of the next block, based on the previous block's weight. - // TODO: maybe this does not need previous weight and can just read it - type FeeMultiplierUpdate: Convert<(Weight, Multiplier), Multiplier>; + type FeeMultiplierUpdate: Convert; } decl_storage! { @@ -89,9 +88,8 @@ decl_module! { const TransactionByteFee: BalanceOf = T::TransactionByteFee::get(); fn on_finalize() { - let current_weight = >::all_extrinsics_weight(); NextFeeMultiplier::mutate(|fm| { - *fm = T::FeeMultiplierUpdate::convert((current_weight, *fm)) + *fm = T::FeeMultiplierUpdate::convert(*fm) }); } } -- GitLab From 626699a992c5d30a482b235c7f952e3193ed3f25 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Thu, 24 Oct 2019 15:11:24 +0200 Subject: [PATCH 269/275] Bump transaction version (#3904) --- core/sr-primitives/src/generic/unchecked_extrinsic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/sr-primitives/src/generic/unchecked_extrinsic.rs b/core/sr-primitives/src/generic/unchecked_extrinsic.rs index 4af8d9a95b..c7bff1f4c8 100644 --- a/core/sr-primitives/src/generic/unchecked_extrinsic.rs +++ b/core/sr-primitives/src/generic/unchecked_extrinsic.rs @@ -25,7 +25,7 @@ use crate::{ generic::CheckedExtrinsic, transaction_validity::{TransactionValidityError, InvalidTransaction}, }; -const TRANSACTION_VERSION: u8 = 3; +const TRANSACTION_VERSION: u8 = 4; /// A extrinsic right from the external world. This is unchecked and so /// can contain a signature. -- GitLab From fa7864e7055b39bc57e4db306b29e09c01baffba Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 24 Oct 2019 15:11:38 +0200 Subject: [PATCH 270/275] Service builder clean-up (#3906) * Rename NewService to Service * Move new_impl! macro to builder module * Inline new_impl! * Minor cleanup * Inline the offchain_workers() function * Fix indentation level * Inline start_rpc * Remove RpcBuilder trait --- core/service/src/builder.rs | 632 ++++++++++++++++++++++-------------- core/service/src/lib.rs | 343 +------------------ node/cli/src/service.rs | 4 +- 3 files changed, 400 insertions(+), 579 deletions(-) diff --git a/core/service/src/builder.rs b/core/service/src/builder.rs index cf91d1b267..b2a6cc731a 100644 --- a/core/service/src/builder.rs +++ b/core/service/src/builder.rs @@ -14,9 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use crate::{NewService, NetworkStatus, NetworkState, error::{self, Error}, DEFAULT_PROTOCOL_ID}; +use crate::{Service, NetworkStatus, NetworkState, error::{self, Error}, DEFAULT_PROTOCOL_ID}; use crate::{SpawnTaskHandle, start_rpc_servers, build_network_future, TransactionPoolAdapter}; -use crate::TaskExecutor; use crate::status_sinks; use crate::config::Configuration; use client::{ @@ -33,13 +32,13 @@ use futures03::{ FutureExt as _, TryFutureExt as _, StreamExt as _, TryStreamExt as _, }; -use keystore::{Store as Keystore, KeyStorePtr}; +use keystore::{Store as Keystore}; use log::{info, warn}; use network::{FinalityProofProvider, OnDemand, NetworkService, NetworkStateInfo, DhtEvent}; use network::{config::BoxFinalityProofRequestBuilder, specialization::NetworkSpecialization}; use parking_lot::{Mutex, RwLock}; use primitives::{Blake2Hasher, H256, Hasher}; -use rpc::{self, system::SystemInfo}; +use rpc; use sr_primitives::generic::BlockId; use sr_primitives::traits::{ Block as BlockT, Extrinsic, ProvideRuntimeApi, NumberFor, One, Zero, Header, SaturatedConversion @@ -69,7 +68,7 @@ use transaction_pool::txpool::{self, ChainApi, Pool as TransactionPool}; /// generics is done when you call `build`. /// pub struct ServiceBuilder + TNetP, TExPool, TRpc, Backend> { config: Configuration, client: Arc, @@ -83,7 +82,7 @@ pub struct ServiceBuilder, rpc_extensions: TRpc, - rpc_builder: TRpcB, + remote_backend: Option>>, dht_event_tx: Option>, marker: PhantomData<(TBl, TRtApi)>, } @@ -134,7 +133,7 @@ type TLightCallExecutor = client::light::call_executor::GenesisC >, >; -impl ServiceBuilder<(), (), TCfg, TGen, TCSExt, (), (), (), (), (), (), (), (), (), (), ()> +impl ServiceBuilder<(), (), TCfg, TGen, TCSExt, (), (), (), (), (), (), (), (), (), ()> where TGen: RuntimeGenesis, TCSExt: Extension { /// Start the service builder with a configuration. pub fn new_full, TRtApi, TExecDisp: NativeExecutionDispatch>( @@ -154,7 +153,6 @@ where TGen: RuntimeGenesis, TCSExt: Extension { (), (), (), - FullRpcBuilder, TFullBackend, >, Error> { let keystore = Keystore::open(config.keystore_path.clone(), config.keystore_password.clone())?; @@ -190,8 +188,6 @@ where TGen: RuntimeGenesis, TCSExt: Extension { let client = Arc::new(client); - let rpc_builder = FullRpcBuilder { client: client.clone() }; - Ok(ServiceBuilder { config, client, @@ -205,7 +201,7 @@ where TGen: RuntimeGenesis, TCSExt: Extension { network_protocol: (), transaction_pool: Arc::new(()), rpc_extensions: Default::default(), - rpc_builder, + remote_backend: None, dht_event_tx: None, marker: PhantomData, }) @@ -229,7 +225,6 @@ where TGen: RuntimeGenesis, TCSExt: Extension { (), (), (), - LightRpcBuilder, TLightBackend, >, Error> { let keystore = Keystore::open(config.keystore_path.clone(), config.keystore_password.clone())?; @@ -259,11 +254,6 @@ where TGen: RuntimeGenesis, TCSExt: Extension { &config.chain_spec, executor, )?); - let rpc_builder = LightRpcBuilder { - client: client.clone(), - remote_blockchain, - fetcher: fetcher.clone(), - }; Ok(ServiceBuilder { config, @@ -278,16 +268,16 @@ where TGen: RuntimeGenesis, TCSExt: Extension { network_protocol: (), transaction_pool: Arc::new(()), rpc_extensions: Default::default(), - rpc_builder, + remote_backend: Some(remote_blockchain), dht_event_tx: None, marker: PhantomData, }) } } -impl +impl ServiceBuilder { + TNetP, TExPool, TRpc, Backend> { /// Returns a reference to the client that was stored in this builder. pub fn client(&self) -> &Arc { @@ -311,7 +301,7 @@ impl, &Arc ) -> Result, Error> ) -> Result, Error> { + TNetP, TExPool, TRpc, Backend>, Error> { let select_chain = select_chain_builder(&self.config, &self.backend)?; Ok(ServiceBuilder { @@ -327,7 +317,7 @@ impl, &Arc) -> Result ) -> Result, Error> { + TNetP, TExPool, TRpc, Backend>, Error> { self.with_opt_select_chain(|cfg, b| builder(cfg, b).map(Option::Some)) } @@ -348,7 +338,7 @@ impl, Arc, Option, Arc) -> Result ) -> Result, Error> + TNetP, TExPool, TRpc, Backend>, Error> where TSc: Clone { let import_queue = builder( &self.config, @@ -370,7 +360,7 @@ impl) -> Result ) -> Result, Error> { + UNetP, TExPool, TRpc, Backend>, Error> { let network_protocol = network_protocol_builder(&self.config)?; Ok(ServiceBuilder { @@ -397,7 +387,7 @@ impl, Error> { let finality_proof_provider = builder(self.client.clone(), self.backend.clone())?; @@ -440,7 +429,7 @@ impl, Error> { self.with_opt_finality_proof_provider(|client, backend| build(client, backend).map(Option::Some)) @@ -483,7 +471,7 @@ impl, ) -> Result<(UImpQu, Option), Error> ) -> Result, Error> + TNetP, TExPool, TRpc, Backend>, Error> where TSc: Clone, TFchr: Clone { let (import_queue, fprb) = builder( &self.config, @@ -507,7 +495,7 @@ impl, ) -> Result<(UImpQu, UFprb), Error> ) -> Result, Error> + TNetP, TExPool, TRpc, Backend>, Error> where TSc: Clone, TFchr: Clone { self.with_import_queue_and_opt_fprb(|cfg, cl, b, f, sc, tx| builder(cfg, cl, b, f, sc, tx) @@ -538,7 +526,7 @@ impl) -> Result ) -> Result, Error> { + TNetP, UExPool, TRpc, Backend>, Error> { let transaction_pool = transaction_pool_builder(self.config.transaction_pool.clone(), self.client.clone())?; Ok(ServiceBuilder { @@ -554,7 +542,7 @@ impl, Arc) -> URpc ) -> Result, Error> { + TNetP, TExPool, URpc, Backend>, Error> { let rpc_extensions = rpc_ext_builder(self.client.clone(), self.transaction_pool.clone()); Ok(ServiceBuilder { @@ -581,114 +569,36 @@ impl, - ) -> Result, Error> { - Ok(ServiceBuilder { - config: self.config, - client: self.client, - backend: self.backend, - keystore: self.keystore, - fetcher: self.fetcher, - select_chain: self.select_chain, - import_queue: self.import_queue, - finality_proof_request_builder: self.finality_proof_request_builder, - finality_proof_provider: self.finality_proof_provider, - network_protocol: self.network_protocol, - transaction_pool: self.transaction_pool, - rpc_extensions: self.rpc_extensions, - rpc_builder: self.rpc_builder, - dht_event_tx: Some(dht_event_tx), - marker: self.marker, - }) - } -} - -/// RPC handlers builder. -pub trait RpcBuilder { - /// Build chain RPC handler. - fn build_chain(&self, subscriptions: rpc::Subscriptions) -> rpc::chain::Chain; - /// Build state RPC handler. - fn build_state(&self, subscriptions: rpc::Subscriptions) -> rpc::state::State; -} - -/// RPC handlers builder for full nodes. -pub struct FullRpcBuilder { - client: Arc>, -} - -impl RpcBuilder, TFullCallExecutor, TRtApi> - for - FullRpcBuilder - where - TBl: BlockT, - TRtApi: 'static + Send + Sync, - TExecDisp: 'static + NativeExecutionDispatch, - TFullClient: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: runtime_api::Metadata, -{ - fn build_chain( - &self, - subscriptions: rpc::Subscriptions, - ) -> rpc::chain::Chain, TFullCallExecutor, TBl, TRtApi> { - rpc::chain::new_full(self.client.clone(), subscriptions) - } - - fn build_state( - &self, - subscriptions: rpc::Subscriptions, - ) -> rpc::state::State, TFullCallExecutor, TBl, TRtApi> { - rpc::state::new_full(self.client.clone(), subscriptions) - } -} - -/// RPC handlers builder for light nodes. -pub struct LightRpcBuilder, TRtApi, TExecDisp> { - client: Arc>, - remote_blockchain: Arc>, - fetcher: Arc>, -} - -impl RpcBuilder, TLightCallExecutor, TRtApi> - for - LightRpcBuilder - where - TBl: BlockT, - TRtApi: 'static + Send + Sync, - TExecDisp: 'static + NativeExecutionDispatch, -{ - fn build_chain( - &self, - subscriptions: rpc::Subscriptions, - ) -> rpc::chain::Chain, TLightCallExecutor, TBl, TRtApi> { - rpc::chain::new_light( - self.client.clone(), - subscriptions, - self.remote_blockchain.clone(), - self.fetcher.clone(), - ) - } - - fn build_state( - &self, - subscriptions: rpc::Subscriptions, - ) -> rpc::state::State, TLightCallExecutor, TBl, TRtApi> { - rpc::state::new_light( - self.client.clone(), - subscriptions, - self.remote_blockchain.clone(), - self.fetcher.clone(), - ) + /// Adds a dht event sender to builder to be used by the network to send dht events to the authority discovery + /// module. + pub fn with_dht_event_tx( + self, + dht_event_tx: mpsc::Sender, + ) -> Result, Error> { + Ok(ServiceBuilder { + config: self.config, + client: self.client, + backend: self.backend, + keystore: self.keystore, + fetcher: self.fetcher, + select_chain: self.select_chain, + import_queue: self.import_queue, + finality_proof_request_builder: self.finality_proof_request_builder, + finality_proof_provider: self.finality_proof_provider, + network_protocol: self.network_protocol, + transaction_pool: self.transaction_pool, + rpc_extensions: self.rpc_extensions, + remote_backend: self.remote_backend, + dht_event_tx: Some(dht_event_tx), + marker: self.marker, + }) } } @@ -736,10 +646,10 @@ pub trait ServiceBuilderRevert { impl< TBl, TRtApi, TCfg, TGen, TCSExt, TBackend, TExec, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, - TExPool, TRpc, TRpcB, Backend + TExPool, TRpc, Backend > ServiceBuilderImport for ServiceBuilder< TBl, TRtApi, TCfg, TGen, TCSExt, Client, - TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB, Backend + TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, Backend > where TBl: BlockT::Out>, TBackend: 'static + client::backend::Backend + Send, @@ -759,9 +669,9 @@ impl< } } -impl +impl ServiceBuilderExport for ServiceBuilder, - TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB, TBackend> + TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TBackend> where TBl: BlockT::Out>, TBackend: 'static + client::backend::Backend + Send, @@ -782,9 +692,9 @@ where } } -impl +impl ServiceBuilderRevert for ServiceBuilder, - TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TRpcB, TBackend> + TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TBackend> where TBl: BlockT::Out>, TBackend: 'static + client::backend::Backend + Send, @@ -801,7 +711,7 @@ where } } -impl +impl ServiceBuilder< TBl, TRtApi, @@ -817,7 +727,6 @@ ServiceBuilder< TNetP, TransactionPool, TRpc, - TRpcB, TBackend, > where Client: ProvideRuntimeApi, @@ -838,10 +747,9 @@ ServiceBuilder< TNetP: NetworkSpecialization, TExPoolApi: 'static + ChainApi::Hash>, TRpc: rpc::RpcExtension + Clone, - TRpcB: RpcBuilder, { /// Builds the service. - pub fn build(self) -> Result Result, TSc, @@ -858,7 +766,7 @@ ServiceBuilder< marker: _, mut config, client, - fetcher, + fetcher: on_demand, backend, keystore, select_chain, @@ -868,8 +776,8 @@ ServiceBuilder< network_protocol, transaction_pool, rpc_extensions, + remote_backend, dht_event_tx, - rpc_builder, } = self; session::generate_initial_session_keys( @@ -877,74 +785,344 @@ ServiceBuilder< config.dev_key_seed.clone().map(|s| vec![s]).unwrap_or_default() )?; - new_impl!( - TBl, - config, - move |_| -> Result<_, Error> { - Ok(( - client, - fetcher, - backend, - keystore, - select_chain, - import_queue, - finality_proof_request_builder, - finality_proof_provider, - network_protocol, - transaction_pool, - rpc_extensions, - dht_event_tx, - )) + let (signal, exit) = exit_future::signal(); + + // List of asynchronous tasks to spawn. We collect them, then spawn them all at once. + let (to_spawn_tx, to_spawn_rx) = + mpsc::unbounded:: + Send>>(); + + let import_queue = Box::new(import_queue); + let chain_info = client.info().chain; + + let version = config.full_version(); + info!("Highest known block at #{}", chain_info.best_number); + telemetry!( + SUBSTRATE_INFO; + "node.start"; + "height" => chain_info.best_number.saturated_into::(), + "best" => ?chain_info.best_hash + ); + + let transaction_pool_adapter = Arc::new(TransactionPoolAdapter { + imports_external_transactions: !config.roles.is_light(), + pool: transaction_pool.clone(), + client: client.clone(), + executor: Arc::new(SpawnTaskHandle { sender: to_spawn_tx.clone(), on_exit: exit.clone() }), + }); + + let protocol_id = { + let protocol_id_full = match config.chain_spec.protocol_id() { + Some(pid) => pid, + None => { + warn!("Using default protocol ID {:?} because none is configured in the \ + chain specs", DEFAULT_PROTOCOL_ID + ); + DEFAULT_PROTOCOL_ID + } + }.as_bytes(); + network::config::ProtocolId::from(protocol_id_full) + }; + + let block_announce_validator = + Box::new(consensus_common::block_validation::DefaultBlockAnnounceValidator::new(client.clone())); + + let network_params = network::config::Params { + roles: config.roles, + network_config: config.network.clone(), + chain: client.clone(), + finality_proof_provider, + finality_proof_request_builder, + on_demand: on_demand.clone(), + transaction_pool: transaction_pool_adapter.clone() as _, + import_queue, + protocol_id, + specialization: network_protocol, + block_announce_validator, + }; + + let has_bootnodes = !network_params.network_config.boot_nodes.is_empty(); + let network_mut = network::NetworkWorker::new(network_params)?; + let network = network_mut.service().clone(); + let network_status_sinks = Arc::new(Mutex::new(status_sinks::StatusSinks::new())); + + let offchain_storage = backend.offchain_storage(); + let offchain_workers = match (config.offchain_worker, offchain_storage) { + (true, Some(db)) => { + Some(Arc::new(offchain::OffchainWorkers::new(client.clone(), db))) + }, + (true, None) => { + log::warn!("Offchain workers disabled, due to lack of offchain storage support in backend."); + None }, - |h, c, tx, r| maintain_transaction_pool(h, c, tx, r), - |n, o, p, ns, v| offchain_workers(n, o, p, ns, v), - |c, ssb, si, te, tp, ext, ks| start_rpc(&rpc_builder, c, ssb, si, te, tp, ext, ks), + _ => None, + }; + + { + // block notifications + let txpool = Arc::downgrade(&transaction_pool); + let wclient = Arc::downgrade(&client); + let offchain = offchain_workers.as_ref().map(Arc::downgrade); + let to_spawn_tx_ = to_spawn_tx.clone(); + let network_state_info: Arc = network.clone(); + let is_validator = config.roles.is_authority(); + + let events = client.import_notification_stream() + .map(|v| Ok::<_, ()>(v)).compat() + .for_each(move |notification| { + let number = *notification.header.number(); + let txpool = txpool.upgrade(); + + if let (Some(txpool), Some(client)) = (txpool.as_ref(), wclient.upgrade()) { + let future = maintain_transaction_pool( + &BlockId::hash(notification.hash), + &client, + &*txpool, + ¬ification.retracted, + ).map_err(|e| warn!("Pool error processing new block: {:?}", e))?; + let _ = to_spawn_tx_.unbounded_send(future); + } + + let offchain = offchain.as_ref().and_then(|o| o.upgrade()); + if let (Some(txpool), Some(offchain)) = (txpool, offchain) { + let future = offchain.on_block_imported(&number, &txpool, network_state_info.clone(), is_validator) + .map(|()| Ok(())); + let _ = to_spawn_tx_.unbounded_send(Box::new(Compat::new(future))); + } + + Ok(()) + }) + .select(exit.clone()) + .then(|_| Ok(())); + let _ = to_spawn_tx.unbounded_send(Box::new(events)); + } + + { + // extrinsic notifications + let network = Arc::downgrade(&network); + let transaction_pool_ = transaction_pool.clone(); + let events = transaction_pool.import_notification_stream() + .map(|v| Ok::<_, ()>(v)).compat() + .for_each(move |_| { + if let Some(network) = network.upgrade() { + network.trigger_repropagate(); + } + let status = transaction_pool_.status(); + telemetry!(SUBSTRATE_INFO; "txpool.import"; + "ready" => status.ready, + "future" => status.future + ); + Ok(()) + }) + .select(exit.clone()) + .then(|_| Ok(())); + + let _ = to_spawn_tx.unbounded_send(Box::new(events)); + } + + // Periodically notify the telemetry. + let transaction_pool_ = transaction_pool.clone(); + let client_ = client.clone(); + let mut sys = System::new(); + let self_pid = get_current_pid().ok(); + let (state_tx, state_rx) = mpsc::unbounded::<(NetworkStatus<_>, NetworkState)>(); + network_status_sinks.lock().push(std::time::Duration::from_millis(5000), state_tx); + let tel_task = state_rx.for_each(move |(net_status, _)| { + let info = client_.info(); + let best_number = info.chain.best_number.saturated_into::(); + let best_hash = info.chain.best_hash; + let num_peers = net_status.num_connected_peers; + let txpool_status = transaction_pool_.status(); + let finalized_number: u64 = info.chain.finalized_number.saturated_into::(); + let bandwidth_download = net_status.average_download_per_sec; + let bandwidth_upload = net_status.average_upload_per_sec; + + let used_state_cache_size = match info.used_state_cache_size { + Some(size) => size, + None => 0, + }; + + // get cpu usage and memory usage of this process + let (cpu_usage, memory) = if let Some(self_pid) = self_pid { + if sys.refresh_process(self_pid) { + let proc = sys.get_process(self_pid) + .expect("Above refresh_process succeeds, this should be Some(), qed"); + (proc.cpu_usage(), proc.memory()) + } else { (0.0, 0) } + } else { (0.0, 0) }; + + telemetry!( + SUBSTRATE_INFO; + "system.interval"; + "peers" => num_peers, + "height" => best_number, + "best" => ?best_hash, + "txcount" => txpool_status.ready, + "cpu" => cpu_usage, + "memory" => memory, + "finalized_height" => finalized_number, + "finalized_hash" => ?info.chain.finalized_hash, + "bandwidth_download" => bandwidth_download, + "bandwidth_upload" => bandwidth_upload, + "used_state_cache_size" => used_state_cache_size, + ); + + Ok(()) + }).select(exit.clone()).then(|_| Ok(())); + let _ = to_spawn_tx.unbounded_send(Box::new(tel_task)); + + // Periodically send the network state to the telemetry. + let (netstat_tx, netstat_rx) = mpsc::unbounded::<(NetworkStatus<_>, NetworkState)>(); + network_status_sinks.lock().push(std::time::Duration::from_secs(30), netstat_tx); + let tel_task_2 = netstat_rx.for_each(move |(_, network_state)| { + telemetry!( + SUBSTRATE_INFO; + "system.network_state"; + "state" => network_state, + ); + Ok(()) + }).select(exit.clone()).then(|_| Ok(())); + let _ = to_spawn_tx.unbounded_send(Box::new(tel_task_2)); + + // RPC + let (system_rpc_tx, system_rpc_rx) = futures03::channel::mpsc::unbounded(); + let gen_handler = || { + use rpc::{chain, state, author, system}; + + let system_info = rpc::system::SystemInfo { + chain_name: config.chain_spec.name().into(), + impl_name: config.impl_name.into(), + impl_version: config.impl_version.into(), + properties: config.chain_spec.properties().clone(), + }; + + let subscriptions = rpc::Subscriptions::new(Arc::new(SpawnTaskHandle { + sender: to_spawn_tx.clone(), + on_exit: exit.clone() + })); + + let (chain, state) = if let (Some(remote_backend), Some(on_demand)) = + (remote_backend.as_ref(), on_demand.as_ref()) { + // Light clients + let chain = rpc::chain::new_light( + client.clone(), + subscriptions.clone(), + remote_backend.clone(), + on_demand.clone() + ); + let state = rpc::state::new_light( + client.clone(), + subscriptions.clone(), + remote_backend.clone(), + on_demand.clone() + ); + (chain, state) + + } else { + // Full nodes + let chain = rpc::chain::new_full(client.clone(), subscriptions.clone()); + let state = rpc::state::new_full(client.clone(), subscriptions.clone()); + (chain, state) + }; + + let author = rpc::author::Author::new( + client.clone(), + transaction_pool.clone(), + subscriptions, + keystore.clone(), + ); + let system = system::System::new(system_info, system_rpc_tx.clone()); + + rpc_servers::rpc_handler(( + state::StateApi::to_delegate(state), + chain::ChainApi::to_delegate(chain), + author::AuthorApi::to_delegate(author), + system::SystemApi::to_delegate(system), + rpc_extensions.clone(), + )) + }; + let rpc_handlers = gen_handler(); + let rpc = start_rpc_servers(&config, gen_handler)?; + + + let _ = to_spawn_tx.unbounded_send(Box::new(build_network_future( + config.roles, + network_mut, + client.clone(), + network_status_sinks.clone(), + system_rpc_rx, + has_bootnodes, + dht_event_tx, ) + .map_err(|_| ()) + .select(exit.clone()) + .then(|_| Ok(())))); + + let telemetry_connection_sinks: Arc>>> = Default::default(); + + // Telemetry + let telemetry = config.telemetry_endpoints.clone().map(|endpoints| { + let is_authority = config.roles.is_authority(); + let network_id = network.local_peer_id().to_base58(); + let name = config.name.clone(); + let impl_name = config.impl_name.to_owned(); + let version = version.clone(); + let chain_name = config.chain_spec.name().to_owned(); + let telemetry_connection_sinks_ = telemetry_connection_sinks.clone(); + let telemetry = tel::init_telemetry(tel::TelemetryConfig { + endpoints, + wasm_external_transport: config.telemetry_external_transport.take(), + }); + let future = telemetry.clone() + .map(|ev| Ok::<_, ()>(ev)) + .compat() + .for_each(move |event| { + // Safe-guard in case we add more events in the future. + let tel::TelemetryEvent::Connected = event; + + telemetry!(SUBSTRATE_INFO; "system.connected"; + "name" => name.clone(), + "implementation" => impl_name.clone(), + "version" => version.clone(), + "config" => "", + "chain" => chain_name.clone(), + "authority" => is_authority, + "network_id" => network_id.clone() + ); + + telemetry_connection_sinks_.lock().retain(|sink| { + sink.unbounded_send(()).is_ok() + }); + Ok(()) + }); + let _ = to_spawn_tx.unbounded_send(Box::new(future + .select(exit.clone()) + .then(|_| Ok(())))); + telemetry + }); + + Ok(Service { + client, + network, + network_status_sinks, + select_chain, + transaction_pool, + exit, + signal: Some(signal), + essential_failed: Arc::new(AtomicBool::new(false)), + to_spawn_tx, + to_spawn_rx, + to_poll: Vec::new(), + rpc_handlers, + _rpc: rpc, + _telemetry: telemetry, + _offchain_workers: offchain_workers, + _telemetry_on_connect_sinks: telemetry_connection_sinks.clone(), + keystore, + marker: PhantomData::, + }) } } -pub(crate) fn start_rpc( - rpc_builder: &RpcB, - client: Arc>, - system_send_back: futures03::channel::mpsc::UnboundedSender>, - rpc_system_info: SystemInfo, - task_executor: TaskExecutor, - transaction_pool: Arc>, - rpc_extensions: impl rpc::RpcExtension, - keystore: KeyStorePtr, -) -> rpc_servers::RpcHandler -where - Block: BlockT::Out>, - Backend: client::backend::Backend + 'static, - Client: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: - runtime_api::Metadata + session::SessionKeys, - Api: Send + Sync + 'static, - Executor: client::CallExecutor + Send + Sync + Clone + 'static, - PoolApi: txpool::ChainApi + 'static, - RpcB: RpcBuilder, -{ - use rpc::{chain, state, author, system}; - let subscriptions = rpc::Subscriptions::new(task_executor); - let chain = rpc_builder.build_chain(subscriptions.clone()); - let state = rpc_builder.build_state(subscriptions.clone()); - let author = rpc::author::Author::new( - client, - transaction_pool, - subscriptions, - keystore, - ); - let system = system::System::new(rpc_system_info, system_send_back); - - rpc_servers::rpc_handler(( - state::StateApi::to_delegate(state), - chain::ChainApi::to_delegate(chain), - author::AuthorApi::to_delegate(author), - system::SystemApi::to_delegate(system), - rpc_extensions, - )) -} - pub(crate) fn maintain_transaction_pool( id: &BlockId, client: &Arc>, @@ -997,32 +1175,6 @@ pub(crate) fn maintain_transaction_pool( }) } -pub(crate) fn offchain_workers( - number: &NumberFor, - offchain: &offchain::OffchainWorkers< - Client, - >::OffchainStorage, - Block - >, - pool: &Arc>, - network_state: &Arc, - is_validator: bool, -) -> error::Result + Send>> -where - Block: BlockT::Out>, - Backend: client::backend::Backend + 'static, - Api: 'static, - >::OffchainStorage: 'static, - Client: ProvideRuntimeApi + Send + Sync, - as ProvideRuntimeApi>::Api: offchain::OffchainWorkerApi, - Executor: client::CallExecutor + 'static, - PoolApi: txpool::ChainApi + 'static, -{ - let future = offchain.on_block_imported(number, pool, network_state.clone(), is_validator) - .map(|()| Ok(())); - Ok(Box::new(Compat::new(future))) -} - #[cfg(test)] mod tests { use super::*; diff --git a/core/service/src/lib.rs b/core/service/src/lib.rs index 334a001a48..3057b8ce4d 100644 --- a/core/service/src/lib.rs +++ b/core/service/src/lib.rs @@ -24,6 +24,7 @@ pub mod config; pub mod chain_ops; pub mod error; +mod builder; mod status_sinks; use std::io; @@ -71,7 +72,7 @@ pub use futures::future::Executor; const DEFAULT_PROTOCOL_ID: &str = "sup"; /// Substrate service. -pub struct NewService { +pub struct Service { client: Arc, select_chain: Option, network: Arc, @@ -129,338 +130,6 @@ impl Executor + Send>> for SpawnTaskHandle } } -macro_rules! new_impl { - ( - $block:ty, - $config:ident, - $build_components:expr, - $maintain_transaction_pool:expr, - $offchain_workers:expr, - $start_rpc:expr, - ) => {{ - let (signal, exit) = exit_future::signal(); - - // List of asynchronous tasks to spawn. We collect them, then spawn them all at once. - let (to_spawn_tx, to_spawn_rx) = - mpsc::unbounded:: + Send>>(); - - // Create all the components. - let ( - client, - on_demand, - backend, - keystore, - select_chain, - import_queue, - finality_proof_request_builder, - finality_proof_provider, - network_protocol, - transaction_pool, - rpc_extensions, - dht_event_tx, - ) = $build_components(&$config)?; - let import_queue = Box::new(import_queue); - let chain_info = client.info().chain; - - let version = $config.full_version(); - info!("Highest known block at #{}", chain_info.best_number); - telemetry!( - SUBSTRATE_INFO; - "node.start"; - "height" => chain_info.best_number.saturated_into::(), - "best" => ?chain_info.best_hash - ); - - let transaction_pool_adapter = Arc::new(TransactionPoolAdapter { - imports_external_transactions: !$config.roles.is_light(), - pool: transaction_pool.clone(), - client: client.clone(), - executor: Arc::new(SpawnTaskHandle { sender: to_spawn_tx.clone(), on_exit: exit.clone() }), - }); - - let protocol_id = { - let protocol_id_full = match $config.chain_spec.protocol_id() { - Some(pid) => pid, - None => { - warn!("Using default protocol ID {:?} because none is configured in the \ - chain specs", DEFAULT_PROTOCOL_ID - ); - DEFAULT_PROTOCOL_ID - } - }.as_bytes(); - network::config::ProtocolId::from(protocol_id_full) - }; - - let block_announce_validator = - Box::new(consensus_common::block_validation::DefaultBlockAnnounceValidator::new(client.clone())); - - let network_params = network::config::Params { - roles: $config.roles, - network_config: $config.network.clone(), - chain: client.clone(), - finality_proof_provider, - finality_proof_request_builder, - on_demand, - transaction_pool: transaction_pool_adapter.clone() as _, - import_queue, - protocol_id, - specialization: network_protocol, - block_announce_validator, - }; - - let has_bootnodes = !network_params.network_config.boot_nodes.is_empty(); - let network_mut = network::NetworkWorker::new(network_params)?; - let network = network_mut.service().clone(); - let network_status_sinks = Arc::new(Mutex::new(status_sinks::StatusSinks::new())); - - let offchain_storage = backend.offchain_storage(); - let offchain_workers = match ($config.offchain_worker, offchain_storage) { - (true, Some(db)) => { - Some(Arc::new(offchain::OffchainWorkers::new(client.clone(), db))) - }, - (true, None) => { - log::warn!("Offchain workers disabled, due to lack of offchain storage support in backend."); - None - }, - _ => None, - }; - - { - // block notifications - let txpool = Arc::downgrade(&transaction_pool); - let wclient = Arc::downgrade(&client); - let offchain = offchain_workers.as_ref().map(Arc::downgrade); - let to_spawn_tx_ = to_spawn_tx.clone(); - let network_state_info: Arc = network.clone(); - let is_validator = $config.roles.is_authority(); - - let events = client.import_notification_stream() - .map(|v| Ok::<_, ()>(v)).compat() - .for_each(move |notification| { - let number = *notification.header.number(); - let txpool = txpool.upgrade(); - - if let (Some(txpool), Some(client)) = (txpool.as_ref(), wclient.upgrade()) { - let future = $maintain_transaction_pool( - &BlockId::hash(notification.hash), - &client, - &*txpool, - ¬ification.retracted, - ).map_err(|e| warn!("Pool error processing new block: {:?}", e))?; - let _ = to_spawn_tx_.unbounded_send(future); - } - - let offchain = offchain.as_ref().and_then(|o| o.upgrade()); - if let (Some(txpool), Some(offchain)) = (txpool, offchain) { - let future = $offchain_workers( - &number, - &offchain, - &txpool, - &network_state_info, - is_validator, - ).map_err(|e| warn!("Offchain workers error processing new block: {:?}", e))?; - let _ = to_spawn_tx_.unbounded_send(future); - } - - Ok(()) - }) - .select(exit.clone()) - .then(|_| Ok(())); - let _ = to_spawn_tx.unbounded_send(Box::new(events)); - } - - { - // extrinsic notifications - let network = Arc::downgrade(&network); - let transaction_pool_ = transaction_pool.clone(); - let events = transaction_pool.import_notification_stream() - .map(|v| Ok::<_, ()>(v)).compat() - .for_each(move |_| { - if let Some(network) = network.upgrade() { - network.trigger_repropagate(); - } - let status = transaction_pool_.status(); - telemetry!(SUBSTRATE_INFO; "txpool.import"; - "ready" => status.ready, - "future" => status.future - ); - Ok(()) - }) - .select(exit.clone()) - .then(|_| Ok(())); - - let _ = to_spawn_tx.unbounded_send(Box::new(events)); - } - - // Periodically notify the telemetry. - let transaction_pool_ = transaction_pool.clone(); - let client_ = client.clone(); - let mut sys = System::new(); - let self_pid = get_current_pid().ok(); - let (state_tx, state_rx) = mpsc::unbounded::<(NetworkStatus<_>, NetworkState)>(); - network_status_sinks.lock().push(std::time::Duration::from_millis(5000), state_tx); - let tel_task = state_rx.for_each(move |(net_status, _)| { - let info = client_.info(); - let best_number = info.chain.best_number.saturated_into::(); - let best_hash = info.chain.best_hash; - let num_peers = net_status.num_connected_peers; - let txpool_status = transaction_pool_.status(); - let finalized_number: u64 = info.chain.finalized_number.saturated_into::(); - let bandwidth_download = net_status.average_download_per_sec; - let bandwidth_upload = net_status.average_upload_per_sec; - - let used_state_cache_size = match info.used_state_cache_size { - Some(size) => size, - None => 0, - }; - - // get cpu usage and memory usage of this process - let (cpu_usage, memory) = if let Some(self_pid) = self_pid { - if sys.refresh_process(self_pid) { - let proc = sys.get_process(self_pid) - .expect("Above refresh_process succeeds, this should be Some(), qed"); - (proc.cpu_usage(), proc.memory()) - } else { (0.0, 0) } - } else { (0.0, 0) }; - - telemetry!( - SUBSTRATE_INFO; - "system.interval"; - "peers" => num_peers, - "height" => best_number, - "best" => ?best_hash, - "txcount" => txpool_status.ready, - "cpu" => cpu_usage, - "memory" => memory, - "finalized_height" => finalized_number, - "finalized_hash" => ?info.chain.finalized_hash, - "bandwidth_download" => bandwidth_download, - "bandwidth_upload" => bandwidth_upload, - "used_state_cache_size" => used_state_cache_size, - ); - - Ok(()) - }).select(exit.clone()).then(|_| Ok(())); - let _ = to_spawn_tx.unbounded_send(Box::new(tel_task)); - - // Periodically send the network state to the telemetry. - let (netstat_tx, netstat_rx) = mpsc::unbounded::<(NetworkStatus<_>, NetworkState)>(); - network_status_sinks.lock().push(std::time::Duration::from_secs(30), netstat_tx); - let tel_task_2 = netstat_rx.for_each(move |(_, network_state)| { - telemetry!( - SUBSTRATE_INFO; - "system.network_state"; - "state" => network_state, - ); - Ok(()) - }).select(exit.clone()).then(|_| Ok(())); - let _ = to_spawn_tx.unbounded_send(Box::new(tel_task_2)); - - // RPC - let (system_rpc_tx, system_rpc_rx) = futures03::channel::mpsc::unbounded(); - let gen_handler = || { - let system_info = rpc::system::SystemInfo { - chain_name: $config.chain_spec.name().into(), - impl_name: $config.impl_name.into(), - impl_version: $config.impl_version.into(), - properties: $config.chain_spec.properties().clone(), - }; - $start_rpc( - client.clone(), - //light_components.clone(), - system_rpc_tx.clone(), - system_info.clone(), - Arc::new(SpawnTaskHandle { sender: to_spawn_tx.clone(), on_exit: exit.clone() }), - transaction_pool.clone(), - rpc_extensions.clone(), - keystore.clone(), - ) - }; - let rpc_handlers = gen_handler(); - let rpc = start_rpc_servers(&$config, gen_handler)?; - - - let _ = to_spawn_tx.unbounded_send(Box::new(build_network_future( - $config.roles, - network_mut, - client.clone(), - network_status_sinks.clone(), - system_rpc_rx, - has_bootnodes, - dht_event_tx, - ) - .map_err(|_| ()) - .select(exit.clone()) - .then(|_| Ok(())))); - - let telemetry_connection_sinks: Arc>>> = Default::default(); - - // Telemetry - let telemetry = $config.telemetry_endpoints.clone().map(|endpoints| { - let is_authority = $config.roles.is_authority(); - let network_id = network.local_peer_id().to_base58(); - let name = $config.name.clone(); - let impl_name = $config.impl_name.to_owned(); - let version = version.clone(); - let chain_name = $config.chain_spec.name().to_owned(); - let telemetry_connection_sinks_ = telemetry_connection_sinks.clone(); - let telemetry = tel::init_telemetry(tel::TelemetryConfig { - endpoints, - wasm_external_transport: $config.telemetry_external_transport.take(), - }); - let future = telemetry.clone() - .map(|ev| Ok::<_, ()>(ev)) - .compat() - .for_each(move |event| { - // Safe-guard in case we add more events in the future. - let tel::TelemetryEvent::Connected = event; - - telemetry!(SUBSTRATE_INFO; "system.connected"; - "name" => name.clone(), - "implementation" => impl_name.clone(), - "version" => version.clone(), - "config" => "", - "chain" => chain_name.clone(), - "authority" => is_authority, - "network_id" => network_id.clone() - ); - - telemetry_connection_sinks_.lock().retain(|sink| { - sink.unbounded_send(()).is_ok() - }); - Ok(()) - }); - let _ = to_spawn_tx.unbounded_send(Box::new(future - .select(exit.clone()) - .then(|_| Ok(())))); - telemetry - }); - - Ok(NewService { - client, - network, - network_status_sinks, - select_chain, - transaction_pool, - exit, - signal: Some(signal), - essential_failed: Arc::new(AtomicBool::new(false)), - to_spawn_tx, - to_spawn_rx, - to_poll: Vec::new(), - rpc_handlers, - _rpc: rpc, - _telemetry: telemetry, - _offchain_workers: offchain_workers, - _telemetry_on_connect_sinks: telemetry_connection_sinks.clone(), - keystore, - marker: PhantomData::<$block>, - }) - }} -} - -mod builder; - /// Abstraction over a Substrate service. pub trait AbstractService: 'static + Future + Executor + Send>> + Send { @@ -530,7 +199,7 @@ pub trait AbstractService: 'static + Future + } impl AbstractService for - NewService, TSc, NetworkStatus, + Service, TSc, NetworkStatus, NetworkService, TransactionPool, TOc> where TBl: BlockT, @@ -619,7 +288,7 @@ where } impl Future for - NewService + Service { type Item = (); type Error = Error; @@ -652,7 +321,7 @@ impl Future for } impl Executor + Send>> for - NewService + Service { fn execute( &self, @@ -819,7 +488,7 @@ pub struct NetworkStatus { } impl Drop for - NewService + Service { fn drop(&mut self) { debug!(target: "service", "Substrate service shutdown"); diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index 03d31c4392..78b978b72b 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -33,7 +33,7 @@ use transaction_pool::{self, txpool::{Pool as TransactionPool}}; use inherents::InherentDataProviders; use network::construct_simple_protocol; -use substrate_service::{NewService, NetworkStatus}; +use substrate_service::{Service, NetworkStatus}; use client::{Client, LocalCallExecutor}; use client_db::Backend; use sr_primitives::traits::Block as BlockT; @@ -248,7 +248,7 @@ pub type NodeConfiguration = Configuration(config: NodeConfiguration) -> Result< - NewService< + Service< ConcreteBlock, ConcreteClient, LongestChain, -- GitLab From 5bd69ac2c12f4160ee345200f367ed909df5aae1 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Thu, 24 Oct 2019 17:01:14 +0200 Subject: [PATCH 271/275] core/finality-grandpa: Request block sync from network after import timeout (#3800) * core/finality-grandpa: Pass Grandpa msg sender up to UntilImported * core/finality-grandpa: Track senders to maybe later request blocks * core/finality-grandpa: Make BlockStatus pub only within crate * core/finality-grandpa: Abstract NetworkBridge with BlockSyncRequester * core/finality-grandpa: Pass BlockSyncRequester to UntilImported * core/finality-grandpa: Track block number of pending within UntilImported * core/finality-grandpa: Request block sync on long wait * core/finality-grandpa: Adjust unit tests to previous changes * core/finality-grandpa: Fix line length * core/finality-grandpa: Add comment explaining in & out vote combination * core/finality-grandpa: Log after, not before, timeout expired The UntilImported component should log whenever waiting for a specific block to be imported surpassed a defined constant timeout. Without this patch the code would log whenever the current time was below the timeout. * core/finality-grandpa: Collect senders as HashSet for deduplication * Revert "core/finality-grandpa: Track senders to maybe later request blocks" This reverts commit 61ac9dd715612d5fdbf7b8f00b84e450f282ade0. * Revert "core/finality-grandpa: Pass Grandpa msg sender up to UntilImported" This reverts commit afdc9646a6c314f99a9d19242f1878f85980e70d. * core/network/sync: Ask for block from all peers if none provided When requesting an explicit fork sync, try to sync from all known peers, when no specific peers were provided. * core/network/sync: Request specific fork sync from peers ahead or on par When making an explicit fork sync request without specifying any peers, make sure to only request it from the locally known peers that are either ahead or on a par compared to the block number we are looking for. * grandpa: fix tests * grandpa: fix warnings * grandpa: add test for block sync request on until_imported * grandpa: rename Environment field inner to client * grandpa: fix minor nits * grandpa: minor nits in until_imported * grandpa: copy docs for set_sync_fork_request * grandpa: remove stale TODO on UntilImported --- .../finality-grandpa/src/communication/mod.rs | 27 ++- .../src/communication/tests.rs | 4 + core/finality-grandpa/src/environment.rs | 27 +-- core/finality-grandpa/src/lib.rs | 45 ++-- core/finality-grandpa/src/tests.rs | 2 +- core/finality-grandpa/src/until_imported.rs | 195 +++++++++++++++--- core/network/src/protocol/sync.rs | 24 ++- 7 files changed, 258 insertions(+), 66 deletions(-) diff --git a/core/finality-grandpa/src/communication/mod.rs b/core/finality-grandpa/src/communication/mod.rs index f2a4dee21e..6f43b1106a 100644 --- a/core/finality-grandpa/src/communication/mod.rs +++ b/core/finality-grandpa/src/communication/mod.rs @@ -39,7 +39,7 @@ use network::{consensus_gossip as network_gossip, NetworkService}; use network_gossip::ConsensusMessage; use codec::{Encode, Decode}; use primitives::Pair; -use sr_primitives::traits::{Block as BlockT, Hash as HashT, Header as HeaderT}; +use sr_primitives::traits::{Block as BlockT, Hash as HashT, Header as HeaderT, NumberFor}; use substrate_telemetry::{telemetry, CONSENSUS_DEBUG, CONSENSUS_INFO}; use tokio_executor::Executor; @@ -129,6 +129,14 @@ pub trait Network: Clone + Send + 'static { /// Inform peers that a block with given hash should be downloaded. fn announce(&self, block: Block::Hash, associated_data: Vec); + + /// Notifies the sync service to try and sync the given block from the given + /// peers. + /// + /// If the given vector of peers is empty then the underlying implementation + /// should make a best effort to fetch the block from any peers it is + /// connected to (NOTE: this assumption will change in the future #3629). + fn set_sync_fork_request(&self, peers: Vec, hash: Block::Hash, number: NumberFor); } /// Create a unique topic for a round and set-id combo. @@ -216,6 +224,10 @@ impl Network for Arc> where fn announce(&self, block: B::Hash, associated_data: Vec) { self.announce_block(block, associated_data) } + + fn set_sync_fork_request(&self, peers: Vec, hash: B::Hash, number: NumberFor) { + NetworkService::set_sync_fork_request(self, peers, hash, number) + } } /// A stream used by NetworkBridge in its implementation of Network. Given a oneshot that eventually returns a channel @@ -468,6 +480,9 @@ impl> NetworkBridge { format!("Failed to receive on unbounded receiver for round {}", round.0) )); + // Combine incoming votes from external GRANDPA nodes with outgoing + // votes from our own GRANDPA voter to have a single + // vote-import-pipeline. let incoming = incoming.select(out_rx); (incoming, outgoing) @@ -514,6 +529,16 @@ impl> NetworkBridge { (incoming, outgoing) } + + /// Notifies the sync service to try and sync the given block from the given + /// peers. + /// + /// If the given vector of peers is empty then the underlying implementation + /// should make a best effort to fetch the block from any peers it is + /// connected to (NOTE: this assumption will change in the future #3629). + pub(crate) fn set_sync_fork_request(&self, peers: Vec, hash: B::Hash, number: NumberFor) { + self.service.set_sync_fork_request(peers, hash, number) + } } fn incoming_global>( diff --git a/core/finality-grandpa/src/communication/tests.rs b/core/finality-grandpa/src/communication/tests.rs index 14e54511fb..7b91b2ef0a 100644 --- a/core/finality-grandpa/src/communication/tests.rs +++ b/core/finality-grandpa/src/communication/tests.rs @@ -25,6 +25,7 @@ use tokio::runtime::current_thread; use std::sync::Arc; use keyring::Ed25519Keyring; use codec::Encode; +use sr_primitives::traits::NumberFor; use crate::environment::SharedVoterSetState; use super::gossip::{self, GossipValidator}; @@ -91,6 +92,9 @@ impl super::Network for TestNetwork { fn announce(&self, block: Hash, _associated_data: Vec) { let _ = self.sender.unbounded_send(Event::Announce(block)); } + + /// Notify the sync service to try syncing the given chain. + fn set_sync_fork_request(&self, _peers: Vec, _hash: Hash, _number: NumberFor) {} } impl network_gossip::ValidatorContext for TestNetwork { diff --git a/core/finality-grandpa/src/environment.rs b/core/finality-grandpa/src/environment.rs index ee146c4608..149b00e80f 100644 --- a/core/finality-grandpa/src/environment.rs +++ b/core/finality-grandpa/src/environment.rs @@ -370,7 +370,7 @@ impl SharedVoterSetState { /// The environment we run GRANDPA in. pub(crate) struct Environment, RA, SC, VR> { - pub(crate) inner: Arc>, + pub(crate) client: Arc>, pub(crate) select_chain: SC, pub(crate) voters: Arc>, pub(crate) config: Config, @@ -413,7 +413,7 @@ where NumberFor: BlockNumberOps, { fn ancestry(&self, base: Block::Hash, block: Block::Hash) -> Result, GrandpaError> { - ancestry(&self.inner, base, block) + ancestry(&self.client, base, block) } fn best_chain_containing(&self, block: Block::Hash) -> Option<(Block::Hash, NumberFor)> { @@ -434,7 +434,7 @@ where match self.select_chain.finality_target(block, None) { Ok(Some(best_hash)) => { - let base_header = self.inner.header(&BlockId::Hash(block)).ok()? + let base_header = self.client.header(&BlockId::Hash(block)).ok()? .expect("Header known to exist after `best_containing` call; qed"); if let Some(limit) = limit { @@ -449,7 +449,7 @@ where } } - let best_header = self.inner.header(&BlockId::Hash(best_hash)).ok()? + let best_header = self.client.header(&BlockId::Hash(best_hash)).ok()? .expect("Header known to exist after `best_containing` call; qed"); // check if our vote is currently being limited due to a pending change @@ -473,7 +473,7 @@ where break; } - target_header = self.inner.header(&BlockId::Hash(*target_header.parent_hash())).ok()? + target_header = self.client.header(&BlockId::Hash(*target_header.parent_hash())).ok()? .expect("Header known to exist after `best_containing` call; qed"); } @@ -492,7 +492,7 @@ where // authority set limit filter, which can be considered a // mandatory/implicit voting rule. self.voting_rule - .restrict_vote(&*self.inner, &base_header, &best_header, target_header) + .restrict_vote(&*self.client, &base_header, &best_header, target_header) .or(Some((target_header.hash(), *target_header.number()))) }, Ok(None) => { @@ -601,8 +601,9 @@ where // schedule incoming messages from the network to be held until // corresponding blocks are imported. let incoming = Box::new(UntilVoteTargetImported::new( - self.inner.import_notification_stream(), - self.inner.clone(), + self.client.import_notification_stream(), + self.network.clone(), + self.client.clone(), incoming, "round", ).map_err(Into::into)); @@ -650,7 +651,7 @@ where current_rounds, }; - crate::aux_schema::write_voter_set_state(&*self.inner, &set_state)?; + crate::aux_schema::write_voter_set_state(&*self.client, &set_state)?; Ok(Some(set_state)) })?; @@ -691,7 +692,7 @@ where current_rounds, }; - crate::aux_schema::write_voter_set_state(&*self.inner, &set_state)?; + crate::aux_schema::write_voter_set_state(&*self.client, &set_state)?; Ok(Some(set_state)) })?; @@ -742,7 +743,7 @@ where current_rounds, }; - crate::aux_schema::write_voter_set_state(&*self.inner, &set_state)?; + crate::aux_schema::write_voter_set_state(&*self.client, &set_state)?; Ok(Some(set_state)) })?; @@ -800,7 +801,7 @@ where current_rounds, }; - crate::aux_schema::write_voter_set_state(&*self.inner, &set_state)?; + crate::aux_schema::write_voter_set_state(&*self.client, &set_state)?; Ok(Some(set_state)) })?; @@ -816,7 +817,7 @@ where commit: Commit, ) -> Result<(), Self::Error> { finalize_block( - &*self.inner, + &*self.client, &self.authority_set, &self.consensus_changes, Some(self.config.justification_period.into()), diff --git a/core/finality-grandpa/src/lib.rs b/core/finality-grandpa/src/lib.rs index 9d1e3f563f..63eddfd3f3 100644 --- a/core/finality-grandpa/src/lib.rs +++ b/core/finality-grandpa/src/lib.rs @@ -22,11 +22,11 @@ //! //! # Usage //! -//! First, create a block-import wrapper with the `block_import` function. -//! The GRANDPA worker needs to be linked together with this block import object, -//! so a `LinkHalf` is returned as well. All blocks imported (from network or consensus or otherwise) -//! must pass through this wrapper, otherwise consensus is likely to break in -//! unexpected ways. +//! First, create a block-import wrapper with the `block_import` function. The +//! GRANDPA worker needs to be linked together with this block import object, so +//! a `LinkHalf` is returned as well. All blocks imported (from network or +//! consensus or otherwise) must pass through this wrapper, otherwise consensus +//! is likely to break in unexpected ways. //! //! Next, use the `LinkHalf` and a local configuration to `run_grandpa_voter`. //! This requires a `Network` implementation. The returned future should be @@ -242,7 +242,7 @@ impl From for Error { } /// Something which can determine if a block is known. -pub trait BlockStatus { +pub(crate) trait BlockStatus { /// Return `Ok(Some(number))` or `Ok(None)` depending on whether the block /// is definitely known and has been imported. /// If an unexpected error occurs, return that. @@ -261,6 +261,26 @@ impl, RA> BlockStatus for Arc { + /// Notifies the sync service to try and sync the given block from the given + /// peers. + /// + /// If the given vector of peers is empty then the underlying implementation + /// should make a best effort to fetch the block from any peers it is + /// connected to (NOTE: this assumption will change in the future #3629). + fn set_sync_fork_request(&self, peers: Vec, hash: Block::Hash, number: NumberFor); +} + +impl BlockSyncRequester for NetworkBridge where + Block: BlockT, + N: communication::Network, +{ + fn set_sync_fork_request(&self, peers: Vec, hash: Block::Hash, number: NumberFor) { + NetworkBridge::set_sync_fork_request(self, peers, hash, number) + } +} + /// A new authority set along with the canonical block it changed at. #[derive(Debug)] pub(crate) struct NewAuthoritySet { @@ -429,6 +449,7 @@ fn global_communication, B, E, N, RA>( // block commit and catch up messages until relevant blocks are imported. let global_in = UntilGlobalMessageBlocksImported::new( client.import_notification_stream(), + network.clone(), client.clone(), global_in, "global", @@ -617,7 +638,7 @@ where let voters = persistent_data.authority_set.current_authorities(); let env = Arc::new(Environment { - inner: client, + client, select_chain, voting_rule, voters: Arc::new(voters), @@ -656,7 +677,7 @@ where "authority_id" => authority_id.to_string(), ); - let chain_info = self.env.inner.info(); + let chain_info = self.env.client.info(); telemetry!(CONSENSUS_INFO; "afg.authority_set"; "number" => ?chain_info.chain.finalized_number, "hash" => ?chain_info.chain.finalized_hash, @@ -680,7 +701,7 @@ where let global_comms = global_communication( self.env.set_id, &self.env.voters, - &self.env.inner, + &self.env.client, &self.env.network, &self.env.config.keystore, ); @@ -728,7 +749,7 @@ where (new.canon_hash, new.canon_number), ); - aux_schema::write_voter_set_state(&*self.env.inner, &set_state)?; + aux_schema::write_voter_set_state(&*self.env.client, &set_state)?; Ok(Some(set_state)) })?; @@ -737,7 +758,7 @@ where set_id: new.set_id, voter_set_state: self.env.voter_set_state.clone(), // Fields below are simply transferred and not updated. - inner: self.env.inner.clone(), + client: self.env.client.clone(), select_chain: self.env.select_chain.clone(), config: self.env.config.clone(), authority_set: self.env.authority_set.clone(), @@ -757,7 +778,7 @@ where let completed_rounds = voter_set_state.completed_rounds(); let set_state = VoterSetState::Paused { completed_rounds }; - aux_schema::write_voter_set_state(&*self.env.inner, &set_state)?; + aux_schema::write_voter_set_state(&*self.env.client, &set_state)?; Ok(Some(set_state)) })?; diff --git a/core/finality-grandpa/src/tests.rs b/core/finality-grandpa/src/tests.rs index 7f4a0d053a..8c0047e38b 100644 --- a/core/finality-grandpa/src/tests.rs +++ b/core/finality-grandpa/src/tests.rs @@ -1556,7 +1556,7 @@ fn grandpa_environment_respects_voting_rules() { authority_set: authority_set.clone(), config: config.clone(), consensus_changes: consensus_changes.clone(), - inner: link.client.clone(), + client: link.client.clone(), select_chain: link.select_chain.clone(), set_id: authority_set.set_id(), voter_set_state: set_state.clone(), diff --git a/core/finality-grandpa/src/until_imported.rs b/core/finality-grandpa/src/until_imported.rs index 119ecf95c5..5fca476a82 100644 --- a/core/finality-grandpa/src/until_imported.rs +++ b/core/finality-grandpa/src/until_imported.rs @@ -20,7 +20,13 @@ //! //! This is used for votes and commit messages currently. -use super::{BlockStatus, CommunicationIn, Error, SignedMessage}; +use super::{ + BlockStatus as BlockStatusT, + BlockSyncRequester as BlockSyncRequesterT, + CommunicationIn, + Error, + SignedMessage, +}; use log::{debug, warn}; use client::{BlockImportNotification, ImportNotifications}; @@ -54,8 +60,8 @@ pub(crate) trait BlockUntilImported: Sized { wait: Wait, ready: Ready, ) -> Result<(), Error> where - S: BlockStatus, - Wait: FnMut(Block::Hash, Self), + S: BlockStatusT, + Wait: FnMut(Block::Hash, NumberFor, Self), Ready: FnMut(Self::Blocked); /// called when the wait has completed. The canonical number is passed through @@ -64,23 +70,31 @@ pub(crate) trait BlockUntilImported: Sized { } /// Buffering imported messages until blocks with given hashes are imported. -pub(crate) struct UntilImported> { +pub(crate) struct UntilImported> { import_notifications: Fuse, Error = ()> + Send>>, - status_check: Status, + block_sync_requester: BlockSyncRequester, + status_check: BlockStatus, inner: Fuse, ready: VecDeque, check_pending: Interval, - pending: HashMap)>, + /// Mapping block hashes to their block number, the point in time it was + /// first encountered (Instant) and a list of GRANDPA messages referencing + /// the block hash. + pending: HashMap, Instant, Vec)>, identifier: &'static str, } -impl UntilImported - where Status: BlockStatus, M: BlockUntilImported +impl UntilImported where + Block: BlockT, + BlockStatus: BlockStatusT, + M: BlockUntilImported, + I: Stream, { /// Create a new `UntilImported` wrapper. pub(crate) fn new( import_notifications: ImportNotifications, - status_check: Status, + block_sync_requester: BlockSyncRequester, + status_check: BlockStatus, stream: I, identifier: &'static str, ) -> Self { @@ -98,6 +112,7 @@ impl UntilImported let stream = import_notifications.map::<_, fn(_) -> _>(|v| Ok::<_, ()>(v)).compat(); Box::new(stream) as Box + Send> }.fuse(), + block_sync_requester, status_check, inner: stream.fuse(), ready: VecDeque::new(), @@ -108,8 +123,10 @@ impl UntilImported } } -impl Stream for UntilImported where - Status: BlockStatus, +impl Stream for UntilImported where + Block: BlockT, + BStatus: BlockStatusT, + BSyncRequester: BlockSyncRequesterT, I: Stream, M: BlockUntilImported, { @@ -128,10 +145,10 @@ impl Stream for UntilImported M::schedule_wait( input, &self.status_check, - |target_hash, wait| pending + |target_hash, target_number, wait| pending .entry(target_hash) - .or_insert_with(|| (Instant::now(), Vec::new())) - .1 + .or_insert_with(|| (target_number, Instant::now(), Vec::new())) + .2 .push(wait), |ready_item| ready.push_back(ready_item), )?; @@ -146,7 +163,7 @@ impl Stream for UntilImported Ok(Async::Ready(None)) => return Ok(Async::Ready(None)), Ok(Async::Ready(Some(notification))) => { // new block imported. queue up all messages tied to that hash. - if let Some((_, messages)) = self.pending.remove(¬ification.hash) { + if let Some((_, _, messages)) = self.pending.remove(¬ification.hash) { let canon_number = notification.header.number().clone(); let ready_messages = messages.into_iter() .filter_map(|m| m.wait_completed(canon_number)); @@ -165,28 +182,38 @@ impl Stream for UntilImported if update_interval { let mut known_keys = Vec::new(); - for (&block_hash, &mut (ref mut last_log, ref v)) in &mut self.pending { + for (&block_hash, &mut (block_number, ref mut last_log, ref v)) in &mut self.pending { if let Some(number) = self.status_check.block_number(block_hash)? { known_keys.push((block_hash, number)); } else { let next_log = *last_log + LOG_PENDING_INTERVAL; - if Instant::now() <= next_log { + if Instant::now() >= next_log { debug!( target: "afg", "Waiting to import block {} before {} {} messages can be imported. \ + Requesting network sync service to retrieve block from. \ Possible fork?", block_hash, v.len(), self.identifier, ); + // NOTE: when sending an empty vec of peers the + // underlying should make a best effort to sync the + // block from any peers it knows about. + self.block_sync_requester.set_sync_fork_request( + vec![], + block_hash, + block_number, + ); + *last_log = next_log; } } } for (known_hash, canon_number) in known_keys { - if let Some((_, pending_messages)) = self.pending.remove(&known_hash) { + if let Some((_, _, pending_messages)) = self.pending.remove(&known_hash) { let ready_messages = pending_messages.into_iter() .filter_map(|m| m.wait_completed(canon_number)); @@ -220,14 +247,14 @@ fn warn_authority_wrong_target(hash: H, id: AuthorityId) impl BlockUntilImported for SignedMessage { type Blocked = Self; - fn schedule_wait( + fn schedule_wait( msg: Self::Blocked, - status_check: &S, + status_check: &BlockStatus, mut wait: Wait, mut ready: Ready, ) -> Result<(), Error> where - S: BlockStatus, - Wait: FnMut(Block::Hash, Self), + BlockStatus: BlockStatusT, + Wait: FnMut(Block::Hash, NumberFor, Self), Ready: FnMut(Self::Blocked), { let (&target_hash, target_number) = msg.target(); @@ -239,7 +266,7 @@ impl BlockUntilImported for SignedMessage { ready(msg); } } else { - wait(target_hash, msg) + wait(target_hash, target_number, msg) } Ok(()) @@ -259,7 +286,13 @@ impl BlockUntilImported for SignedMessage { /// Helper type definition for the stream which waits until vote targets for /// signed messages are imported. -pub(crate) type UntilVoteTargetImported = UntilImported>; +pub(crate) type UntilVoteTargetImported = UntilImported< + Block, + BlockStatus, + BlockSyncRequester, + I, + SignedMessage, +>; /// This blocks a global message import, i.e. a commit or catch up messages, /// until all blocks referenced in its votes are known. @@ -274,14 +307,14 @@ pub(crate) struct BlockGlobalMessage { impl BlockUntilImported for BlockGlobalMessage { type Blocked = CommunicationIn; - fn schedule_wait( + fn schedule_wait( input: Self::Blocked, - status_check: &S, + status_check: &BlockStatus, mut wait: Wait, mut ready: Ready, ) -> Result<(), Error> where - S: BlockStatus, - Wait: FnMut(Block::Hash, Self), + BlockStatus: BlockStatusT, + Wait: FnMut(Block::Hash, NumberFor, Self), Ready: FnMut(Self::Blocked), { use std::collections::hash_map::Entry; @@ -383,7 +416,7 @@ impl BlockUntilImported for BlockGlobalMessage { // if this is taking a long time. for (hash, is_known) in checked_hashes { if let KnownOrUnknown::Unknown(target_number) = is_known { - wait(hash, BlockGlobalMessage { + wait(hash, target_number, BlockGlobalMessage { inner: locked_global.clone(), target_number, }) @@ -425,9 +458,10 @@ impl BlockUntilImported for BlockGlobalMessage { /// A stream which gates off incoming global messages, i.e. commit and catch up /// messages, until all referenced block hashes have been imported. -pub(crate) type UntilGlobalMessageBlocksImported = UntilImported< +pub(crate) type UntilGlobalMessageBlocksImported = UntilImported< Block, - Status, + BlockStatus, + BlockSyncRequester, I, BlockGlobalMessage, >; @@ -485,12 +519,31 @@ mod tests { inner: Arc>>, } - impl BlockStatus for TestBlockStatus { + impl BlockStatusT for TestBlockStatus { fn block_number(&self, hash: Hash) -> Result, Error> { Ok(self.inner.lock().get(&hash).map(|x| x.clone())) } } + #[derive(Clone)] + struct TestBlockSyncRequester { + requests: Arc)>>>, + } + + impl Default for TestBlockSyncRequester { + fn default() -> Self { + TestBlockSyncRequester { + requests: Arc::new(Mutex::new(Vec::new())), + } + } + } + + impl BlockSyncRequesterT for TestBlockSyncRequester { + fn set_sync_fork_request(&self, _peers: Vec, hash: Hash, number: NumberFor) { + self.requests.lock().push((hash, number)); + } + } + fn make_header(number: u64) -> Header { Header::new( number, @@ -535,6 +588,7 @@ mod tests { let until_imported = UntilGlobalMessageBlocksImported::new( import_notifications, + TestBlockSyncRequester::default(), block_status, global_rx.map_err(|_| panic!("should never error")), "global", @@ -561,6 +615,7 @@ mod tests { let until_imported = UntilGlobalMessageBlocksImported::new( import_notifications, + TestBlockSyncRequester::default(), block_status, global_rx.map_err(|_| panic!("should never error")), "global", @@ -806,4 +861,80 @@ mod tests { unapply_catch_up(unknown_catch_up()), ); } + + #[test] + fn request_block_sync_for_needed_blocks() { + let (chain_state, import_notifications) = TestChainState::new(); + let block_status = chain_state.block_status(); + + let (global_tx, global_rx) = futures::sync::mpsc::unbounded(); + + let block_sync_requester = TestBlockSyncRequester::default(); + + let until_imported = UntilGlobalMessageBlocksImported::new( + import_notifications, + block_sync_requester.clone(), + block_status, + global_rx.map_err(|_| panic!("should never error")), + "global", + ); + + let h1 = make_header(5); + let h2 = make_header(6); + let h3 = make_header(7); + + // we create a commit message, with precommits for blocks 6 and 7 which + // we haven't imported. + let unknown_commit = CompactCommit:: { + target_hash: h1.hash(), + target_number: 5, + precommits: vec![ + Precommit { + target_hash: h2.hash(), + target_number: 6, + }, + Precommit { + target_hash: h3.hash(), + target_number: 7, + }, + ], + auth_data: Vec::new(), // not used + }; + + let unknown_commit = || voter::CommunicationIn::Commit( + 0, + unknown_commit.clone(), + voter::Callback::Blank, + ); + + // we send the commit message and spawn the until_imported stream + global_tx.unbounded_send(unknown_commit()).unwrap(); + + let mut runtime = Runtime::new().unwrap(); + runtime.spawn(until_imported.into_future().map(|_| ()).map_err(|_| ())); + + // assert that we will make sync requests + let assert = futures::future::poll_fn::<(), (), _>(|| { + let block_sync_requests = block_sync_requester.requests.lock(); + + // we request blocks targeted by the precommits that aren't imported + if block_sync_requests.contains(&(h2.hash(), *h2.number())) && + block_sync_requests.contains(&(h3.hash(), *h3.number())) + { + return Ok(Async::Ready(())); + } + + Ok(Async::NotReady) + }); + + // the `until_imported` stream doesn't request the blocks immediately, + // but it should request them after a small timeout + let timeout = Delay::new(Instant::now() + Duration::from_secs(60)); + let test = assert.select2(timeout).map(|res| match res { + Either::A(_) => {}, + Either::B(_) => panic!("timed out waiting for block sync request"), + }).map_err(|_| ()); + + runtime.block_on(test).unwrap(); + } } diff --git a/core/network/src/protocol/sync.rs b/core/network/src/protocol/sync.rs index bd8a9fe27f..4f08c942de 100644 --- a/core/network/src/protocol/sync.rs +++ b/core/network/src/protocol/sync.rs @@ -456,14 +456,24 @@ impl ChainSync { /// Request syncing for the given block from given set of peers. // The implementation is similar to on_block_announce with unknown parent hash. - pub fn set_sync_fork_request(&mut self, peers: Vec, hash: &B::Hash, number: NumberFor) { + pub fn set_sync_fork_request(&mut self, mut peers: Vec, hash: &B::Hash, number: NumberFor) { if peers.is_empty() { - if let Some(_) = self.fork_targets.remove(hash) { - debug!(target: "sync", "Cleared sync request for block {:?} with {:?}", hash, peers); - } - return; + debug!( + target: "sync", + "Explicit sync request for block {:?} with no peers specified. \ + Syncing from all connected peers {:?} instead.", + hash, peers, + ); + + peers = self.peers.iter() + // Only request blocks from peers who are ahead or on a par. + .filter(|(_, peer)| peer.best_number >= number) + .map(|(id, _)| id.clone()) + .collect(); + } else { + debug!(target: "sync", "Explicit sync request for block {:?} with {:?}", hash, peers); } - debug!(target: "sync", "Explicit sync request for block {:?} with {:?}", hash, peers); + if self.is_known(&hash) { debug!(target: "sync", "Refusing to sync known hash {:?}", hash); return; @@ -1074,7 +1084,7 @@ impl ChainSync { parent_hash: Some(header.parent_hash().clone()), peers: Default::default(), }) - .peers.insert(who); + .peers.insert(who); } OnBlockAnnounce::Nothing -- GitLab From 81618967efc309fbbdd8dec3e8c28b21027861d1 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Thu, 24 Oct 2019 17:26:26 +0200 Subject: [PATCH 272/275] Fix treasury kept and spend when emptied (#3880) * Now construct_runtime must include treasury config so account is created at genesis. * if it doesn't though it is ok, account will be created when the amount put is more than existential deposit. --- node/cli/src/chain_spec.rs | 1 + node/runtime/src/lib.rs | 6 +-- node/testing/src/genesis.rs | 1 + srml/treasury/src/lib.rs | 102 +++++++++++++++++++++++++++++++++--- 4 files changed, 99 insertions(+), 11 deletions(-) diff --git a/node/cli/src/chain_spec.rs b/node/cli/src/chain_spec.rs index 07f6946baf..721fdbaf99 100644 --- a/node/cli/src/chain_spec.rs +++ b/node/cli/src/chain_spec.rs @@ -273,6 +273,7 @@ pub fn testnet_genesis( authorities: vec![], }), membership_Instance1: Some(Default::default()), + treasury: Some(Default::default()), } } diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 9097dd22a3..c43777773d 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -83,8 +83,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 183, - impl_version: 183, + spec_version: 184, + impl_version: 184, apis: RUNTIME_API_VERSIONS, }; @@ -482,7 +482,7 @@ construct_runtime!( TechnicalMembership: membership::::{Module, Call, Storage, Event, Config}, FinalityTracker: finality_tracker::{Module, Call, Inherent}, Grandpa: grandpa::{Module, Call, Storage, Config, Event}, - Treasury: treasury::{Module, Call, Storage, Event}, + Treasury: treasury::{Module, Call, Storage, Config, Event}, Contracts: contracts, Sudo: sudo, ImOnline: im_online::{Module, Call, Storage, Event, ValidateUnsigned, Config}, diff --git a/node/testing/src/genesis.rs b/node/testing/src/genesis.rs index a9f55d86e3..5220d1774b 100644 --- a/node/testing/src/genesis.rs +++ b/node/testing/src/genesis.rs @@ -96,5 +96,6 @@ pub fn config(support_changes_trie: bool, code: Option<&[u8]>) -> GenesisConfig membership_Instance1: Some(Default::default()), elections_phragmen: Some(Default::default()), sudo: Some(Default::default()), + treasury: Some(Default::default()), } } diff --git a/srml/treasury/src/lib.rs b/srml/treasury/src/lib.rs index 08e2f729ab..48b56e438e 100644 --- a/srml/treasury/src/lib.rs +++ b/srml/treasury/src/lib.rs @@ -77,7 +77,7 @@ use support::traits::{ }; use sr_primitives::{Permill, Perbill, ModuleId}; use sr_primitives::traits::{ - Zero, EnsureOrigin, StaticLookup, AccountIdConversion, CheckedSub + Zero, EnsureOrigin, StaticLookup, AccountIdConversion, CheckedSub, Saturating }; use sr_primitives::weights::SimpleDispatchInfo; use codec::{Encode, Decode}; @@ -233,6 +233,15 @@ decl_storage! { /// Proposal indices that have been approved but not yet awarded. Approvals get(fn approvals): Vec; } + add_extra_genesis { + build(|_config| { + // Create Treasury account + let _ = T::Currency::make_free_balance_be( + &>::account_id(), + T::Currency::minimum_balance(), + ); + }); + } } decl_event!( @@ -311,6 +320,10 @@ impl Module { Self::deposit_event(RawEvent::Burnt(burn)) } + // Must never be an error, but better to be safe. + // proof: budget_remaining is account free balance minus ED; + // Thus we can't spend more than account free balance minus ED; + // Thus account is kept alive; qed; if let Err(problem) = T::Currency::settle( &Self::account_id(), imbalance, @@ -325,21 +338,32 @@ impl Module { Self::deposit_event(RawEvent::Rollover(budget_remaining)); } + /// Return the amount of money in the pot. + // The existential deposit is not part of the pot so treasury account never gets deleted. fn pot() -> BalanceOf { T::Currency::free_balance(&Self::account_id()) + // Must never be less than 0 but better be safe. + .saturating_sub(T::Currency::minimum_balance()) } } impl OnUnbalanced> for Module { fn on_unbalanced(amount: NegativeImbalanceOf) { - T::Currency::resolve_creating(&Self::account_id(), amount); + // Must resolve into existing but better to be safe. + let _ = T::Currency::resolve_creating(&Self::account_id(), amount); } } +/// Mint extra funds for the treasury to keep the ratio of portion to total_issuance equal +/// pre dilution and post-dilution. +/// +/// i.e. +/// ```nocompile +/// portion / total_issuance_before_dilution == +/// (portion + minted) / (total_issuance_before_dilution + minted_to_treasury + minted) +/// ``` impl OnDilution> for Module { fn on_dilution(minted: BalanceOf, portion: BalanceOf) { - // Mint extra funds for the treasury to keep the ratio of portion to total_issuance equal - // pre dilution and post-dilution. if !minted.is_zero() && !portion.is_zero() { let total_issuance = T::Currency::total_issuance(); if let Some(funding) = total_issuance.checked_sub(&portion) { @@ -391,7 +415,7 @@ mod tests { type Version = (); } parameter_types! { - pub const ExistentialDeposit: u64 = 0; + pub const ExistentialDeposit: u64 = 1; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; } @@ -430,9 +454,11 @@ mod tests { fn new_test_ext() -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); balances::GenesisConfig::{ - balances: vec![(0, 100), (1, 99), (2, 1)], + // Total issuance will be 200 with treasury account initialized at ED. + balances: vec![(0, 100), (1, 98), (2, 1)], vesting: vec![], }.assimilate_storage(&mut t).unwrap(); + GenesisConfig::default().assimilate_storage::(&mut t).unwrap(); t.into() } @@ -600,17 +626,77 @@ mod tests { fn pot_underflow_should_not_diminish() { new_test_ext().execute_with(|| { Treasury::on_dilution(100, 100); + assert_eq!(Treasury::pot(), 100); assert_ok!(Treasury::propose_spend(Origin::signed(0), 150, 3)); assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); >::on_finalize(2); + assert_eq!(Treasury::pot(), 100); // Pot hasn't changed + + Treasury::on_dilution(100, 100); + >::on_finalize(4); + assert_eq!(Balances::free_balance(&3), 150); // Fund has been spent + assert_eq!(Treasury::pot(), 75); // Pot has finally changed + }); + } + + // Treasury account doesn't get deleted if amount approved to spend is all its free balance. + // i.e. pot should not include existential deposit needed for account survival. + #[test] + fn treasury_account_doesnt_get_deleted() { + new_test_ext().execute_with(|| { + Treasury::on_dilution(100, 100); assert_eq!(Treasury::pot(), 100); + let treasury_balance = Balances::free_balance(&Treasury::account_id()); + + assert_ok!(Treasury::propose_spend(Origin::signed(0), treasury_balance, 3)); + assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); + + >::on_finalize(2); + assert_eq!(Treasury::pot(), 100); // Pot hasn't changed + + assert_ok!(Treasury::propose_spend(Origin::signed(0), Treasury::pot(), 3)); + assert_ok!(Treasury::approve_proposal(Origin::ROOT, 1)); + + >::on_finalize(4); + assert_eq!(Treasury::pot(), 0); // Pot is emptied + assert_eq!(Balances::free_balance(&Treasury::account_id()), 1); // but the account is still there + }); + } + + // In case treasury account is not existing then it works fine. + // This is usefull for chain that will just update runtime. + #[test] + fn inexisting_account_works() { + let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + balances::GenesisConfig::{ + balances: vec![(0, 100), (1, 99), (2, 1)], + vesting: vec![], + }.assimilate_storage(&mut t).unwrap(); + // Treasury genesis config is not build thus treasury account does not exist + let mut t: runtime_io::TestExternalities = t.into(); + + t.execute_with(|| { + assert_eq!(Balances::free_balance(&Treasury::account_id()), 0); // Account does not exist + assert_eq!(Treasury::pot(), 0); // Pot is empty + + assert_ok!(Treasury::propose_spend(Origin::signed(0), 99, 3)); + assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); + assert_ok!(Treasury::propose_spend(Origin::signed(0), 1, 3)); + assert_ok!(Treasury::approve_proposal(Origin::ROOT, 1)); + >::on_finalize(2); + assert_eq!(Treasury::pot(), 0); // Pot hasn't changed + assert_eq!(Balances::free_balance(&3), 0); // Balance of `3` hasn't changed Treasury::on_dilution(100, 100); + assert_eq!(Treasury::pot(), 99); // Pot now contains funds + assert_eq!(Balances::free_balance(&Treasury::account_id()), 100); // Account does exist + >::on_finalize(4); - assert_eq!(Balances::free_balance(&3), 150); - assert_eq!(Treasury::pot(), 75); + + assert_eq!(Treasury::pot(), 0); // Pot has changed + assert_eq!(Balances::free_balance(&3), 99); // Balance of `3` has changed }); } } -- GitLab From c6524464feb7c88d35e73e5e3a9f7fde90763d97 Mon Sep 17 00:00:00 2001 From: Joshy Orndorff Date: Fri, 25 Oct 2019 00:25:33 -0400 Subject: [PATCH 273/275] Change dependency name "node-template-runtime" -> "runtime" (#3910) --- node-template/Cargo.toml | 2 +- node-template/src/chain_spec.rs | 2 +- node-template/src/service.rs | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/node-template/Cargo.toml b/node-template/Cargo.toml index 2c01655dc2..bb61c2c2ca 100644 --- a/node-template/Cargo.toml +++ b/node-template/Cargo.toml @@ -33,7 +33,7 @@ grandpa = { package = "substrate-finality-grandpa", path = "../core/finality-gra grandpa-primitives = { package = "substrate-finality-grandpa-primitives", path = "../core/finality-grandpa/primitives" } substrate-client = { path = "../core/client" } basic-authorship = { package = "substrate-basic-authorship", path = "../core/basic-authorship" } -node-template-runtime = { path = "runtime" } +runtime = { package = "node-template-runtime", path = "runtime" } [build-dependencies] vergen = "3.0.4" diff --git a/node-template/src/chain_spec.rs b/node-template/src/chain_spec.rs index 2996f5414a..b8f7fef35e 100644 --- a/node-template/src/chain_spec.rs +++ b/node-template/src/chain_spec.rs @@ -1,5 +1,5 @@ use primitives::{Pair, Public}; -use node_template_runtime::{ +use runtime::{ AccountId, AuraConfig, BalancesConfig, GenesisConfig, GrandpaConfig, SudoConfig, IndicesConfig, SystemConfig, WASM_BINARY, }; diff --git a/node-template/src/service.rs b/node-template/src/service.rs index 46c0124cb4..203e311df9 100644 --- a/node-template/src/service.rs +++ b/node-template/src/service.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use std::time::Duration; use substrate_client::LongestChain; use futures::prelude::*; -use node_template_runtime::{self, GenesisConfig, opaque::Block, RuntimeApi}; +use runtime::{self, GenesisConfig, opaque::Block, RuntimeApi}; use substrate_service::{error::{Error as ServiceError}, AbstractService, Configuration, ServiceBuilder}; use transaction_pool::{self, txpool::{Pool as TransactionPool}}; use inherents::InherentDataProviders; @@ -17,8 +17,8 @@ use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; // Our native executor instance. native_executor_instance!( pub Executor, - node_template_runtime::api::dispatch, - node_template_runtime::native_version, + runtime::api::dispatch, + runtime::native_version, ); construct_simple_protocol! { @@ -36,7 +36,7 @@ macro_rules! new_full_start { let inherent_data_providers = inherents::InherentDataProviders::new(); let builder = substrate_service::ServiceBuilder::new_full::< - node_template_runtime::opaque::Block, node_template_runtime::RuntimeApi, crate::service::Executor + runtime::opaque::Block, runtime::RuntimeApi, crate::service::Executor >($config)? .with_select_chain(|_config, backend| { Ok(substrate_client::LongestChain::new(backend.clone())) @@ -49,7 +49,7 @@ macro_rules! new_full_start { .ok_or_else(|| substrate_service::Error::SelectChainRequired)?; let (grandpa_block_import, grandpa_link) = - grandpa::block_import::<_, _, _, node_template_runtime::RuntimeApi, _, _>( + grandpa::block_import::<_, _, _, runtime::RuntimeApi, _, _>( client.clone(), &*client, select_chain )?; -- GitLab From 4ff62401ccd29881b4120c90b7767e58b99f5ae8 Mon Sep 17 00:00:00 2001 From: Jim Posen Date: Fri, 25 Oct 2019 11:44:57 +0200 Subject: [PATCH 274/275] support: BuildStorage methods to take self reference (#3884) * support: BuildStorage methods to take self reference. There is no reason to consume the GenesisConfig when using it to initialize a new storage backend. Instead, build_storage and assimilate_storage now operator on self references. * Bump node runtime impl_version. --- core/chain-spec/src/chain_spec.rs | 8 +++---- core/sr-primitives/src/lib.rs | 24 +++++++++---------- node/runtime/src/lib.rs | 2 +- .../src/storage/genesis_config/builder_def.rs | 4 ++-- .../src/storage/genesis_config/mod.rs | 6 ++--- 5 files changed, 21 insertions(+), 23 deletions(-) diff --git a/core/chain-spec/src/chain_spec.rs b/core/chain-spec/src/chain_spec.rs index 8d72effc7b..0f69654b9e 100644 --- a/core/chain-spec/src/chain_spec.rs +++ b/core/chain-spec/src/chain_spec.rs @@ -71,7 +71,7 @@ impl GenesisSource { } impl<'a, G: RuntimeGenesis, E> BuildStorage for &'a ChainSpec { - fn build_storage(self) -> Result<(StorageOverlay, ChildrenStorageOverlay), String> { + fn build_storage(&self) -> Result<(StorageOverlay, ChildrenStorageOverlay), String> { match self.genesis.resolve()? { Genesis::Runtime(gc) => gc.build_storage(), Genesis::Raw(map, children_map) => Ok(( @@ -85,7 +85,7 @@ impl<'a, G: RuntimeGenesis, E> BuildStorage for &'a ChainSpec { } fn assimilate_storage( - self, + &self, _: &mut (StorageOverlay, ChildrenStorageOverlay) ) -> Result<(), String> { Err("`assimilate_storage` not implemented for `ChainSpec`.".into()) @@ -289,11 +289,11 @@ mod tests { impl BuildStorage for Genesis { fn assimilate_storage( - self, + &self, storage: &mut (StorageOverlay, ChildrenStorageOverlay), ) -> Result<(), String> { storage.0.extend( - self.0.into_iter().map(|(a, b)| (a.into_bytes(), b.into_bytes())) + self.0.iter().map(|(a, b)| (a.clone().into_bytes(), b.clone().into_bytes())) ); Ok(()) } diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index 84f7bbcff6..624e224ef1 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -123,14 +123,14 @@ use crate::traits::IdentifyAccount; #[cfg(feature = "std")] pub trait BuildStorage: Sized { /// Build the storage out of this builder. - fn build_storage(self) -> Result<(StorageOverlay, ChildrenStorageOverlay), String> { + fn build_storage(&self) -> Result<(StorageOverlay, ChildrenStorageOverlay), String> { let mut storage = (Default::default(), Default::default()); self.assimilate_storage(&mut storage)?; Ok(storage) } /// Assimilate the storage for this module into pre-existing overlays. fn assimilate_storage( - self, + &self, storage: &mut (StorageOverlay, ChildrenStorageOverlay), ) -> Result<(), String>; } @@ -140,26 +140,24 @@ pub trait BuildStorage: Sized { pub trait BuildModuleGenesisStorage: Sized { /// Create the module genesis storage into the given `storage` and `child_storage`. fn build_module_genesis_storage( - self, + &self, storage: &mut (StorageOverlay, ChildrenStorageOverlay), ) -> Result<(), String>; } #[cfg(feature = "std")] impl BuildStorage for (StorageOverlay, ChildrenStorageOverlay) { - fn build_storage(self) -> Result<(StorageOverlay, ChildrenStorageOverlay), String> { - Ok(self) - } fn assimilate_storage( - self, + &self, storage: &mut (StorageOverlay, ChildrenStorageOverlay), )-> Result<(), String> { - storage.0.extend(self.0); - for (k, other_map) in self.1.into_iter() { + storage.0.extend(self.0.iter().map(|(k, v)| (k.clone(), v.clone()))); + for (k, other_map) in self.1.iter() { + let k = k.clone(); if let Some(map) = storage.1.get_mut(&k) { - map.extend(other_map); + map.extend(other_map.iter().map(|(k, v)| (k.clone(), v.clone()))); } else { - storage.1.insert(k, other_map); + storage.1.insert(k, other_map.clone()); } } Ok(()) @@ -522,11 +520,11 @@ macro_rules! impl_outer_config { #[cfg(any(feature = "std", test))] impl $crate::BuildStorage for $main { fn assimilate_storage( - self, + &self, storage: &mut ($crate::StorageOverlay, $crate::ChildrenStorageOverlay), ) -> std::result::Result<(), String> { $( - if let Some(extra) = self.[< $snake $(_ $instance )? >] { + if let Some(ref extra) = self.[< $snake $(_ $instance )? >] { $crate::impl_outer_config! { @CALL_FN $concrete; diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index c43777773d..fefc1144ac 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -84,7 +84,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 184, - impl_version: 184, + impl_version: 185, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/support/procedural/src/storage/genesis_config/builder_def.rs b/srml/support/procedural/src/storage/genesis_config/builder_def.rs index 60f094e9fe..fc425e4a6d 100644 --- a/srml/support/procedural/src/storage/genesis_config/builder_def.rs +++ b/srml/support/procedural/src/storage/genesis_config/builder_def.rs @@ -51,7 +51,7 @@ impl BuilderDef { is_generic |= ext::expr_contains_ident(&builder, &def.module_runtime_generic); is_generic |= line.is_generic; - data = Some(quote_spanned!(builder.span() => &(#builder)(&self))); + data = Some(quote_spanned!(builder.span() => &(#builder)(self))); } else if let Some(config) = &line.config { is_generic |= line.is_generic; @@ -98,7 +98,7 @@ impl BuilderDef { blocks.push(quote_spanned! { builder.span() => let extra_genesis_builder: fn(&Self) = #builder; - extra_genesis_builder(&self); + extra_genesis_builder(self); }); } diff --git a/srml/support/procedural/src/storage/genesis_config/mod.rs b/srml/support/procedural/src/storage/genesis_config/mod.rs index 57de1e34a8..2d4d4af386 100644 --- a/srml/support/procedural/src/storage/genesis_config/mod.rs +++ b/srml/support/procedural/src/storage/genesis_config/mod.rs @@ -138,7 +138,7 @@ fn impl_build_storage( quote!{ #[cfg(feature = "std")] impl#genesis_impl GenesisConfig#genesis_struct #genesis_where_clause { - pub fn build_storage #fn_generic (self) -> std::result::Result< + pub fn build_storage #fn_generic (&self) -> std::result::Result< ( #scrate::sr_primitives::StorageOverlay, #scrate::sr_primitives::ChildrenStorageOverlay, @@ -152,7 +152,7 @@ fn impl_build_storage( /// Assimilate the storage for this module into pre-existing overlays. pub fn assimilate_storage #fn_generic ( - self, + &self, tuple_storage: &mut ( #scrate::sr_primitives::StorageOverlay, #scrate::sr_primitives::ChildrenStorageOverlay, @@ -170,7 +170,7 @@ fn impl_build_storage( #where_clause { fn build_module_genesis_storage( - self, + &self, storage: &mut ( #scrate::sr_primitives::StorageOverlay, #scrate::sr_primitives::ChildrenStorageOverlay, -- GitLab From 706defecb954ff45234fdb82e08a9e50eda76c82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 25 Oct 2019 12:24:58 +0200 Subject: [PATCH 275/275] Bring back `SubmitSignedTransaction` trait. (#3908) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Bring back SubmitSignedTransaction. * Fix long lines. * Add missing docs. * Update core/primitives/src/crypto.rs Co-Authored-By: Bastian Köcher * Update node/runtime/src/lib.rs Co-Authored-By: Bastian Köcher * Update core/primitives/src/crypto.rs Co-Authored-By: Bastian Köcher --- core/primitives/src/crypto.rs | 3 + core/sr-primitives/src/lib.rs | 21 +++++++ node/runtime/src/lib.rs | 53 +++++++++++++++++- srml/im-online/src/lib.rs | 12 ---- srml/system/src/offchain.rs | 102 ++++++++++++++++++++++++++++++++-- 5 files changed, 173 insertions(+), 18 deletions(-) diff --git a/core/primitives/src/crypto.rs b/core/primitives/src/crypto.rs index b7c70e6224..6e46793432 100644 --- a/core/primitives/src/crypto.rs +++ b/core/primitives/src/crypto.rs @@ -790,6 +790,9 @@ pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static { root.derive(path, Some(seed)).map_err(|_| SecretStringError::InvalidPath) } + /// Interprets the string `s` in order to generate a key pair. + /// + /// See [`from_string_with_seed`](Self::from_string_with_seed) for more extensive documentation. fn from_string(s: &str, password_override: Option<&str>) -> Result { Self::from_string_with_seed(s, password_override).map(|x| x.0) } diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index 624e224ef1..4341e3543a 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -255,18 +255,39 @@ impl From for MultiSigner { } } +impl TryFrom for ed25519::Public { + type Error = (); + fn try_from(m: MultiSigner) -> Result { + if let MultiSigner::Ed25519(x) = m { Ok(x) } else { Err(()) } + } +} + impl From for MultiSigner { fn from(x: sr25519::Public) -> Self { MultiSigner::Sr25519(x) } } +impl TryFrom for sr25519::Public { + type Error = (); + fn try_from(m: MultiSigner) -> Result { + if let MultiSigner::Sr25519(x) = m { Ok(x) } else { Err(()) } + } +} + impl From for MultiSigner { fn from(x: ecdsa::Public) -> Self { MultiSigner::Ecdsa(x) } } +impl TryFrom for ecdsa::Public { + type Error = (); + fn try_from(m: MultiSigner) -> Result { + if let MultiSigner::Ecdsa(x) = m { Ok(x) } else { Err(()) } + } +} + #[cfg(feature = "std")] impl std::fmt::Display for MultiSigner { fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index fefc1144ac..3b72ff40fa 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -42,7 +42,7 @@ use sr_primitives::curve::PiecewiseLinear; use sr_primitives::transaction_validity::TransactionValidity; use sr_primitives::weights::Weight; use sr_primitives::traits::{ - BlakeTwo256, Block as BlockT, NumberFor, StaticLookup, + self, BlakeTwo256, Block as BlockT, NumberFor, StaticLookup, SaturatedConversion, }; use version::RuntimeVersion; #[cfg(any(feature = "std", test))] @@ -459,6 +459,36 @@ impl finality_tracker::Trait for Runtime { type ReportLatency = ReportLatency; } +impl system::offchain::CreateTransaction for Runtime { + type Public = ::Signer; + type Signature = Signature; + + fn create_transaction>( + call: Call, + public: Self::Public, + account: AccountId, + index: Index, + ) -> Option<(Call, ::SignaturePayload)> { + let period = 1 << 8; + let current_block = System::block_number().saturated_into::(); + let tip = 0; + let extra: SignedExtra = ( + system::CheckVersion::::new(), + system::CheckGenesis::::new(), + system::CheckEra::::from(generic::Era::mortal(period, current_block)), + system::CheckNonce::::from(index), + system::CheckWeight::::new(), + transaction_payment::ChargeTransactionPayment::::from(tip), + Default::default(), + ); + let raw_payload = SignedPayload::new(call, extra).ok()?; + let signature = F::sign(public, &raw_payload)?; + let address = Indices::unlookup(account); + let (call, extra, _) = raw_payload.deconstruct(); + Some((call, (address, signature, extra))) + } +} + construct_runtime!( pub enum Runtime where Block = Block, @@ -669,3 +699,24 @@ impl_runtime_apis! { } } } +#[cfg(test)] +mod tests { + use super::*; + use system::offchain::SubmitSignedTransaction; + + fn is_submit_signed_transaction(_arg: T) where + T: SubmitSignedTransaction< + Runtime, + Call, + Extrinsic=UncheckedExtrinsic, + CreateTransaction=Runtime, + Signer=ImOnlineId, + >, + {} + + #[test] + fn validate_bounds() { + let x = SubmitTransaction::default(); + is_submit_signed_transaction(x); + } +} diff --git a/srml/im-online/src/lib.rs b/srml/im-online/src/lib.rs index 202507bef9..82b866d32b 100644 --- a/srml/im-online/src/lib.rs +++ b/srml/im-online/src/lib.rs @@ -96,12 +96,6 @@ pub mod sr25519 { mod app_sr25519 { use app_crypto::{app_crypto, key_types::IM_ONLINE, sr25519}; app_crypto!(sr25519, IM_ONLINE); - - impl From for sr_primitives::AnySignature { - fn from(sig: Signature) -> Self { - sr25519::Signature::from(sig).into() - } - } } /// An i'm online keypair using sr25519 as its crypto. @@ -119,12 +113,6 @@ pub mod ed25519 { mod app_ed25519 { use app_crypto::{app_crypto, key_types::IM_ONLINE, ed25519}; app_crypto!(ed25519, IM_ONLINE); - - impl From for sr_primitives::AnySignature { - fn from(sig: Signature) -> Self { - ed25519::Signature::from(sig).into() - } - } } /// An i'm online keypair using ed25519 as its crypto. diff --git a/srml/system/src/offchain.rs b/srml/system/src/offchain.rs index 468c88af39..11f7e234f7 100644 --- a/srml/system/src/offchain.rs +++ b/srml/system/src/offchain.rs @@ -17,8 +17,8 @@ //! Module helpers for offchain calls. use codec::Encode; -use sr_primitives::app_crypto::RuntimeAppPublic; -use sr_primitives::traits::Extrinsic as ExtrinsicT; +use sr_primitives::app_crypto::{self, RuntimeAppPublic}; +use sr_primitives::traits::{Extrinsic as ExtrinsicT, IdentifyAccount}; /// A trait responsible for signing a payload using given account. pub trait Signer { @@ -28,17 +28,96 @@ pub trait Signer { fn sign(public: Public, payload: &Payload) -> Option; } +/// A `Signer` implementation for any `AppPublic` type. +/// +/// This implementation additionaly supports conversion to/from multi-signature/multi-signer +/// wrappers. +/// If the wrapped crypto doesn't match `AppPublic`s crypto `None` is returned. impl Signer for AppPublic where - AppPublic: RuntimeAppPublic + From, - AppPublic::Signature: Into, + AppPublic: RuntimeAppPublic + + app_crypto::AppPublic + + From<::Generic>, + ::Signature: app_crypto::AppSignature, + Signature: From< + <::Signature as app_crypto::AppSignature>::Generic + >, + Public: rstd::convert::TryInto<::Generic> { fn sign(public: Public, raw_payload: &Payload) -> Option { raw_payload.using_encoded(|payload| { - AppPublic::from(public).sign(&payload).map(Into::into) + let public = public.try_into().ok()?; + AppPublic::from(public).sign(&payload) + .map( + <::Signature as app_crypto::AppSignature> + ::Generic::from + ) + .map(Signature::from) }) } } +/// Creates runtime-specific signed transaction. +pub trait CreateTransaction { + /// A `Public` key representing a particular `AccountId`. + type Public; + /// A `Signature` generated by the `Signer`. + type Signature; + + /// Attempt to create signed extrinsic data that encodes call from given account. + /// + /// Runtime implementation is free to construct the payload to sign and the signature + /// in any way it wants. + /// Returns `None` if signed extrinsic could not be created (either because signing failed + /// or because of any other runtime-specific reason). + fn create_transaction>( + call: Extrinsic::Call, + public: Self::Public, + account: T::AccountId, + nonce: T::Index, + ) -> Option<(Extrinsic::Call, Extrinsic::SignaturePayload)>; +} + +type PublicOf = < + >::CreateTransaction as CreateTransaction< + T, + >::Extrinsic, + > +>::Public; + +/// A trait to sign and submit transactions in offchain calls. +pub trait SubmitSignedTransaction +where + PublicOf: IdentifyAccount + Clone, +{ + /// Unchecked extrinsic type. + type Extrinsic: ExtrinsicT + codec::Encode; + + /// A runtime-specific type to produce signed data for the extrinsic. + type CreateTransaction: CreateTransaction; + + /// A type used to sign transactions created using `CreateTransaction`. + type Signer: Signer< + PublicOf, + >::Signature, + >; + + /// Sign given call and submit it to the transaction pool. + /// + /// Returns `Ok` if the transaction was submitted correctly + /// and `Err` if the key for given `id` was not found or the + /// transaction was rejected from the pool. + fn sign_and_submit(call: impl Into, public: PublicOf) -> Result<(), ()> { + let call = call.into(); + let id = public.clone().into_account(); + let expected = >::account_nonce(&id); + let (call, signature_data) = Self::CreateTransaction + ::create_transaction::(call, public, id, expected) + .ok_or(())?; + let xt = Self::Extrinsic::new(call, Some(signature_data)).ok_or(())?; + runtime_io::submit_transaction(xt.encode()) + } +} + /// A trait to submit unsigned transactions in offchain calls. pub trait SubmitUnsignedTransaction { /// Unchecked extrinsic type. @@ -67,6 +146,19 @@ impl Default for TransactionSubmitter { } } +/// A blanket implementation to simplify creation of transaction signer & submitter in the runtime. +impl SubmitSignedTransaction for TransactionSubmitter where + T: crate::Trait, + C: CreateTransaction, + S: Signer<>::Public, >::Signature>, + E: ExtrinsicT + codec::Encode, + >::Public: IdentifyAccount + Clone, +{ + type Extrinsic = E; + type CreateTransaction = C; + type Signer = S; +} + /// A blanket impl to use the same submitter for usigned transactions as well. impl SubmitUnsignedTransaction for TransactionSubmitter where T: crate::Trait, -- GitLab

(slot_num, &authorities) { - None => return Err("Slot Author not found".to_string()), + None => return Err(Error::SlotAuthorNotFound), Some(author) => author, }; @@ -386,7 +403,7 @@ fn check_header( slot_num, &header, expected_author, - ).map_err(|e| e.to_string())? { + ).map_err(Error::Client)? { info!( "Slot author is equivocating at slot {} with headers {:?} and {:?}", slot_num, @@ -397,7 +414,7 @@ fn check_header( Ok(CheckedHeader::Checked(header, (slot_num, seal))) } else { - Err(format!("Bad signature on {:?}", hash)) + Err(Error::BadSignature(hash)) } } } @@ -419,7 +436,7 @@ impl AuraVerifier block_id: BlockId, inherent_data: InherentData, timestamp_now: u64, - ) -> Result<(), String> + ) -> Result<(), Error> where C: ProvideRuntimeApi, C::Api: BlockBuilderApi { const MAX_TIMESTAMP_DRIFT_SECS: u64 = 60; @@ -428,7 +445,7 @@ impl AuraVerifier &block_id, block, inherent_data, - ).map_err(|e| format!("{:?}", e))?; + ).map_err(Error::Client)?; if !inherent_res.ok() { inherent_res @@ -438,7 +455,7 @@ impl AuraVerifier // halt import until timestamp is valid. // reject when too far ahead. if timestamp > timestamp_now + MAX_TIMESTAMP_DRIFT_SECS { - return Err("Rejecting block too far in future".into()); + return Err(Error::TooFarInFuture); } let diff = timestamp.saturating_sub(timestamp_now); @@ -453,8 +470,10 @@ impl AuraVerifier thread::sleep(Duration::from_secs(diff)); Ok(()) }, - Some(TIError::Other(e)) => Err(e.into()), - None => Err(self.inherent_data_providers.error_to_string(&i, &e)), + Some(TIError::Other(e)) => Err(Error::Runtime(e)), + None => Err(Error::DataProvider( + self.inherent_data_providers.error_to_string(&i, &e) + )), }) } else { Ok(()) @@ -497,7 +516,7 @@ impl Verifier for AuraVerifier where hash, &authorities[..], self.transaction_pool.as_ref().map(|x| &**x), - )?; + ).map_err(|e| e.to_string())?; match checked_header { CheckedHeader::Checked(pre_header, (slot_num, seal)) => { // if the body is passed through, we need to use the runtime @@ -518,7 +537,7 @@ impl Verifier for AuraVerifier where BlockId::Hash(parent_hash), inherent_data, timestamp_now, - )?; + ).map_err(|e| e.to_string())?; } let (_, inner_body) = block.deconstruct(); -- GitLab From aae1a9e23ac716785acb1762fad7123dd6eac375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Tue, 1 Oct 2019 07:44:33 +0100 Subject: [PATCH 162/275] srml: system: add kill_prefix (#3729) * srml: system: add kill_prefix * node: bump spec_version --- node/runtime/src/lib.rs | 4 ++-- srml/system/src/lib.rs | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index c731427033..b7bb26ee00 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -84,8 +84,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 166, - impl_version: 166, + spec_version: 167, + impl_version: 167, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index ecbfb598df..5a1115b90d 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -278,6 +278,13 @@ decl_module! { storage::unhashed::kill(&key); } } + + /// Kill all storage items with a key that starts with the given prefix. + #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + fn kill_prefix(origin, prefix: Key) { + ensure_root(origin)?; + storage::unhashed::kill_prefix(&prefix); + } } } -- GitLab From 55c9d1451d1f35e171d9990a22b613fa95f0e12c Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 1 Oct 2019 12:14:25 +0300 Subject: [PATCH 163/275] Prepare for asynchronous transaction validation in tx pool (#3650) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * async txpool API * Update core/rpc/src/author/mod.rs Co-Authored-By: Tomasz Drwięga * Update core/transaction-pool/graph/src/pool.rs Co-Authored-By: Tomasz Drwięga * Pool -> Pool + ValidatedPool * removed lost block_on when importing xt from network * fix grumbles * alias for future::Executor in rpc * removed executor from Author RPCs * Pool + SharedValidatedPool -> Pool * fix compilation after merge * another fix * another fix --- Cargo.lock | 3 + core/basic-authorship/src/basic_authorship.rs | 6 +- core/basic-authorship/src/lib.rs | 2 +- core/network/src/protocol.rs | 28 +- core/network/src/service.rs | 18 +- core/network/src/test/mod.rs | 8 +- core/offchain/src/api.rs | 19 +- core/offchain/src/lib.rs | 2 +- core/rpc/api/src/author/error.rs | 3 + core/rpc/api/src/author/mod.rs | 4 +- core/rpc/api/src/lib.rs | 2 +- core/rpc/api/src/subscriptions.rs | 7 +- core/rpc/src/author/mod.rs | 55 +- core/rpc/src/author/tests.rs | 35 +- core/service/src/builder.rs | 83 ++- core/service/src/lib.rs | 72 ++- core/service/test/Cargo.toml | 1 + core/service/test/src/lib.rs | 2 +- core/transaction-pool/Cargo.toml | 1 + core/transaction-pool/graph/src/lib.rs | 7 +- core/transaction-pool/graph/src/pool.rs | 610 ++++++++---------- .../graph/src/validated_pool.rs | 371 +++++++++++ core/transaction-pool/src/api.rs | 17 +- core/transaction-pool/src/lib.rs | 2 +- core/transaction-pool/src/tests.rs | 32 +- node-template/src/service.rs | 4 +- node/cli/src/service.rs | 7 +- node/rpc/Cargo.toml | 1 + node/rpc/src/accounts.rs | 7 +- 29 files changed, 912 insertions(+), 497 deletions(-) create mode 100644 core/transaction-pool/graph/src/validated_pool.rs diff --git a/Cargo.lock b/Cargo.lock index 27066afe3c..41e8e69013 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2441,6 +2441,7 @@ name = "node-rpc" version = "2.0.0" dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core-client 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-derive 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5380,6 +5381,7 @@ dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", @@ -5536,6 +5538,7 @@ name = "substrate-transaction-pool" version = "2.0.0" dependencies = [ "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/core/basic-authorship/src/basic_authorship.rs b/core/basic-authorship/src/basic_authorship.rs index 59b12ba1e4..7f8b343f65 100644 --- a/core/basic-authorship/src/basic_authorship.rs +++ b/core/basic-authorship/src/basic_authorship.rs @@ -247,10 +247,12 @@ mod tests { fn should_cease_building_block_when_deadline_is_reached() { // given let client = Arc::new(test_client::new()); - let chain_api = transaction_pool::ChainApi::new(client.clone()); + let chain_api = transaction_pool::FullChainApi::new(client.clone()); let txpool = Arc::new(TransactionPool::new(Default::default(), chain_api)); - txpool.submit_at(&BlockId::number(0), vec![extrinsic(0), extrinsic(1)], false).unwrap(); + futures::executor::block_on( + txpool.submit_at(&BlockId::number(0), vec![extrinsic(0), extrinsic(1)], false) + ).unwrap(); let mut proposer_factory = ProposerFactory { client: client.clone(), diff --git a/core/basic-authorship/src/lib.rs b/core/basic-authorship/src/lib.rs index 71c9e27922..7961e4fe9e 100644 --- a/core/basic-authorship/src/lib.rs +++ b/core/basic-authorship/src/lib.rs @@ -26,7 +26,7 @@ //! # use test_client::{self, runtime::{Extrinsic, Transfer}, AccountKeyring}; //! # use transaction_pool::txpool::{self, Pool as TransactionPool}; //! # let client = Arc::new(test_client::new()); -//! # let chain_api = transaction_pool::ChainApi::new(client.clone()); +//! # let chain_api = transaction_pool::FullChainApi::new(client.clone()); //! # let txpool = Arc::new(TransactionPool::new(Default::default(), chain_api)); //! // The first step is to create a `ProposerFactory`. //! let mut proposer_factory = ProposerFactory { diff --git a/core/network/src/protocol.rs b/core/network/src/protocol.rs index ef581a6e43..dc9e6688e7 100644 --- a/core/network/src/protocol.rs +++ b/core/network/src/protocol.rs @@ -963,6 +963,14 @@ impl, H: ExHashT> Protocol { who: PeerId, extrinsics: message::Transactions ) { + // sending extrinsic to light node is considered a bad behavior + if !self.config.roles.is_full() { + trace!(target: "sync", "Peer {} is trying to send extrinsic to the light node", who); + self.behaviour.disconnect_peer(&who); + self.peerset_handle.report_peer(who, i32::min_value()); + return; + } + // Accept extrinsics only when fully synced if self.sync.status().state != SyncState::Idle { trace!(target: "sync", "{} Ignoring extrinsics while syncing", who); @@ -971,12 +979,15 @@ impl, H: ExHashT> Protocol { trace!(target: "sync", "Received {} extrinsics from {}", extrinsics.len(), who); if let Some(ref mut peer) = self.context_data.peers.get_mut(&who) { for t in extrinsics { - if let Some(hash) = self.transaction_pool.import(&t) { - self.peerset_handle.report_peer(who.clone(), NEW_EXTRINSIC_REPUTATION_CHANGE); - peer.known_extrinsics.insert(hash); - } else { - trace!(target: "sync", "Extrinsic rejected"); - } + let hash = self.transaction_pool.hash_of(&t); + peer.known_extrinsics.insert(hash); + + self.transaction_pool.import( + self.peerset_handle.clone().into(), + who.clone(), + NEW_EXTRINSIC_REPUTATION_CHANGE, + t, + ); } } } @@ -995,6 +1006,11 @@ impl, H: ExHashT> Protocol { let extrinsics = self.transaction_pool.transactions(); let mut propagated_to = HashMap::new(); for (who, peer) in self.context_data.peers.iter_mut() { + // never send extrinsics to the light node + if !peer.info.roles.is_full() { + continue; + } + let (hashes, to_send): (Vec<_>, Vec<_>) = extrinsics .iter() .filter(|&(ref hash, _)| peer.known_extrinsics.insert(hash.clone())) diff --git a/core/network/src/service.rs b/core/network/src/service.rs index 2cf949116f..5e8d41340c 100644 --- a/core/network/src/service.rs +++ b/core/network/src/service.rs @@ -65,8 +65,18 @@ impl ExHashT for T where pub trait TransactionPool: Send + Sync { /// Get transactions from the pool that are ready to be propagated. fn transactions(&self) -> Vec<(H, B::Extrinsic)>; + /// Get hash of transaction. + fn hash_of(&self, transaction: &B::Extrinsic) -> H; /// Import a transaction into the pool. - fn import(&self, transaction: &B::Extrinsic) -> Option; + /// + /// Peer reputation is changed by reputation_change if transaction is accepted by the pool. + fn import( + &self, + report_handle: ReportHandle, + who: PeerId, + reputation_change: i32, + transaction: B::Extrinsic, + ); /// Notify the pool about transactions broadcast. fn on_broadcasted(&self, propagations: HashMap>); } @@ -77,6 +87,12 @@ pub struct ReportHandle { inner: PeersetHandle, // wraps it so we don't have to worry about breaking API. } +impl From for ReportHandle { + fn from(peerset_handle: PeersetHandle) -> Self { + ReportHandle { inner: peerset_handle } + } +} + impl ReportHandle { /// Report a given peer as either beneficial (+) or costly (-) according to the /// given scalar. diff --git a/core/network/src/test/mod.rs b/core/network/src/test/mod.rs index 920636810b..2c87ba1ac8 100644 --- a/core/network/src/test/mod.rs +++ b/core/network/src/test/mod.rs @@ -47,7 +47,7 @@ use consensus::Error as ConsensusError; use consensus::{BlockOrigin, ForkChoiceStrategy, BlockImportParams, BlockCheckParams, JustificationImport}; use futures::prelude::*; use futures03::{StreamExt as _, TryStreamExt as _}; -use crate::{NetworkWorker, NetworkService, config::ProtocolId}; +use crate::{NetworkWorker, NetworkService, ReportHandle, config::ProtocolId}; use crate::config::{NetworkConfiguration, TransportConfig, BoxFinalityProofRequestBuilder}; use libp2p::PeerId; use parking_lot::Mutex; @@ -400,10 +400,12 @@ impl TransactionPool for EmptyTransactionPool { Vec::new() } - fn import(&self, _transaction: &Extrinsic) -> Option { - None + fn hash_of(&self, _transaction: &Extrinsic) -> Hash { + Hash::default() } + fn import(&self, _report_handle: ReportHandle, _who: PeerId, _rep_change: i32, _transaction: Extrinsic) {} + fn on_broadcasted(&self, _: HashMap>) {} } diff --git a/core/offchain/src/api.rs b/core/offchain/src/api.rs index 62b73f28d6..d17a892d97 100644 --- a/core/offchain/src/api.rs +++ b/core/offchain/src/api.rs @@ -302,29 +302,28 @@ impl AsyncApi { match msg { ExtMessage::SubmitExtrinsic(ext) => self.submit_extrinsic(ext), } - future::ready(()) }); future::join(extrinsics, http) .map(|((), ())| ()) } - fn submit_extrinsic(&mut self, ext: Vec) { + fn submit_extrinsic(&mut self, ext: Vec) -> impl Future { let xt = match ::Extrinsic::decode(&mut &*ext) { Ok(xt) => xt, Err(e) => { warn!("Unable to decode extrinsic: {:?}: {}", ext, e.what()); - return + return future::Either::Left(future::ready(())) }, }; info!("Submitting to the pool: {:?} (isSigned: {:?})", xt, xt.is_signed()); - match self.transaction_pool.submit_one(&self.at, xt.clone()) { - Ok(hash) => debug!("[{:?}] Offchain transaction added to the pool.", hash), - Err(e) => { - debug!("Couldn't submit transaction: {:?}", e); - }, - } + future::Either::Right(self.transaction_pool + .submit_one(&self.at, xt.clone()) + .map(|result| match result { + Ok(hash) => { debug!("[{:?}] Offchain transaction added to the pool.", hash); }, + Err(e) => { debug!("Couldn't submit transaction: {:?}", e); }, + })) } } @@ -354,7 +353,7 @@ mod tests { let db = LocalStorage::new_test(); let client = Arc::new(test_client::new()); let pool = Arc::new( - Pool::new(Default::default(), transaction_pool::ChainApi::new(client.clone())) + Pool::new(Default::default(), transaction_pool::FullChainApi::new(client.clone())) ); let mock = Arc::new(MockNetworkStateInfo()); diff --git a/core/offchain/src/lib.rs b/core/offchain/src/lib.rs index 9b785ec8ba..79c6df04ea 100644 --- a/core/offchain/src/lib.rs +++ b/core/offchain/src/lib.rs @@ -171,7 +171,7 @@ mod tests { // given let _ = env_logger::try_init(); let client = Arc::new(test_client::new()); - let pool = Arc::new(Pool::new(Default::default(), transaction_pool::ChainApi::new(client.clone()))); + let pool = Arc::new(Pool::new(Default::default(), transaction_pool::FullChainApi::new(client.clone()))); let db = client_db::offchain::LocalStorage::new_test(); let network_state = Arc::new(MockNetworkStateInfo()); diff --git a/core/rpc/api/src/author/error.rs b/core/rpc/api/src/author/error.rs index 727b58bd21..8e4f887768 100644 --- a/core/rpc/api/src/author/error.rs +++ b/core/rpc/api/src/author/error.rs @@ -22,6 +22,9 @@ use jsonrpc_core as rpc; /// Author RPC Result type. pub type Result = std::result::Result; +/// Author RPC future Result type. +pub type FutureResult = Box + Send>; + /// Author RPC errors. #[derive(Debug, derive_more::Display, derive_more::From)] pub enum Error { diff --git a/core/rpc/api/src/author/mod.rs b/core/rpc/api/src/author/mod.rs index 5cde56995a..4ea96cb3c6 100644 --- a/core/rpc/api/src/author/mod.rs +++ b/core/rpc/api/src/author/mod.rs @@ -24,7 +24,7 @@ use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use primitives::{ Bytes }; -use self::error::Result; +use self::error::{FutureResult, Result}; use txpool::watcher::Status; pub use self::gen_client::Client as AuthorClient; @@ -37,7 +37,7 @@ pub trait AuthorApi { /// Submit hex-encoded extrinsic for inclusion in block. #[rpc(name = "author_submitExtrinsic")] - fn submit_extrinsic(&self, extrinsic: Bytes) -> Result; + fn submit_extrinsic(&self, extrinsic: Bytes) -> FutureResult; /// Insert a key into the keystore. #[rpc(name = "author_insertKey")] diff --git a/core/rpc/api/src/lib.rs b/core/rpc/api/src/lib.rs index 78fa58f14a..12db07633d 100644 --- a/core/rpc/api/src/lib.rs +++ b/core/rpc/api/src/lib.rs @@ -25,7 +25,7 @@ mod helpers; mod subscriptions; pub use jsonrpc_core::IoHandlerExtension as RpcExtension; -pub use subscriptions::Subscriptions; +pub use subscriptions::{Subscriptions, TaskExecutor}; pub use helpers::Receiver; pub mod author; diff --git a/core/rpc/api/src/subscriptions.rs b/core/rpc/api/src/subscriptions.rs index f284e0ef52..bff184cade 100644 --- a/core/rpc/api/src/subscriptions.rs +++ b/core/rpc/api/src/subscriptions.rs @@ -25,6 +25,9 @@ use jsonrpc_core::futures::{Future, future}; type Id = u64; +/// Alias for a an implementation of `futures::future::Executor`. +pub type TaskExecutor = Arc + Send>> + Send + Sync>; + /// Generate unique ids for subscriptions. #[derive(Clone, Debug)] pub struct IdProvider { @@ -53,12 +56,12 @@ impl IdProvider { pub struct Subscriptions { next_id: IdProvider, active_subscriptions: Arc>>>, - executor: Arc + Send>> + Send + Sync>, + executor: TaskExecutor, } impl Subscriptions { /// Creates new `Subscriptions` object. - pub fn new(executor: Arc + Send>> + Send + Sync>) -> Self { + pub fn new(executor: TaskExecutor) -> Self { Subscriptions { next_id: Default::default(), active_subscriptions: Default::default(), diff --git a/core/rpc/src/author/mod.rs b/core/rpc/src/author/mod.rs index 50b5e30d57..9a978f22f7 100644 --- a/core/rpc/src/author/mod.rs +++ b/core/rpc/src/author/mod.rs @@ -20,13 +20,18 @@ mod tests; use std::{sync::Arc, convert::TryInto}; +use futures03::future::{FutureExt, TryFutureExt}; +use log::warn; use client::{self, Client}; -use rpc::futures::{Sink, Future}; +use rpc::futures::{ + Sink, Future, + stream::Stream as _, + future::result, +}; use futures03::{StreamExt as _, compat::Compat}; use api::Subscriptions; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; -use log::warn; use codec::{Encode, Decode}; use primitives::{Bytes, Blake2Hasher, H256, traits::BareCryptoStorePtr}; use sr_primitives::{generic, traits::{self, ProvideRuntimeApi}}; @@ -44,7 +49,7 @@ use session::SessionKeys; /// Re-export the API for backward compatibility. pub use api::author::*; -use self::error::{Error, Result}; +use self::error::{Error, FutureResult, Result}; /// Authoring API pub struct Author where P: PoolChainApi + Sync + Send + 'static { @@ -108,15 +113,19 @@ impl AuthorApi, BlockHash